lkml.org 
[lkml]   [2022]   [Oct]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V5 04/26] mmc: core: Extend support for mmc regulators with a vqmmc2
    Date
    From: Ulf Hansson <ulf.hansson@linaro.org>

    Updates in V4:
    - Moved the voltage defines into this patch.

    Update in previous version:
    To allow an additional external regulator to be controlled by an mmc host
    driver, let's add support for a vqmmc2 regulator to the mmc core.

    For an SD UHS-II interface the vqmmc2 regulator may correspond to the so
    called vdd2 supply, as described by the SD spec. Initially, only 1.8V is
    needed, hence limit the new helper function, mmc_regulator_set_vqmmc2() to
    this too.

    Note that, to allow for flexibility mmc host drivers need to manage the
    enable/disable of the vqmmc2 regulator themselves, while the regulator is
    looked up through the common mmc_regulator_get_supply().

    Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
    ---
    drivers/mmc/core/regulator.c | 34 ++++++++++++++++++++++++++++++++++
    include/linux/mmc/host.h | 11 +++++++++++
    2 files changed, 45 insertions(+)

    diff --git a/drivers/mmc/core/regulator.c b/drivers/mmc/core/regulator.c
    index 609201a467ef..3c189682797c 100644
    --- a/drivers/mmc/core/regulator.c
    +++ b/drivers/mmc/core/regulator.c
    @@ -223,6 +223,33 @@ int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios)
    }
    EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc);

    +/**
    + * mmc_regulator_set_vqmmc2 - Set vqmmc2 as per the ios->vqmmc2_voltage
    + * @mmc: The mmc host to regulate
    + * @ios: The io bus settings
    + *
    + * Sets a new voltage level for the vqmmc2 regulator, which may correspond to
    + * the vdd2 regulator for an SD UHS-II interface. This function is expected to
    + * be called by mmc host drivers.
    + *
    + * Returns a negative error code on failure, zero if the voltage level was
    + * changed successfully or a positive value if the level didn't need to change.
    + */
    +int mmc_regulator_set_vqmmc2(struct mmc_host *mmc, struct mmc_ios *ios)
    +{
    + if (IS_ERR(mmc->supply.vqmmc2))
    + return -EINVAL;
    +
    + switch (ios->vqmmc2_voltage) {
    + case MMC_VQMMC2_VOLTAGE_180:
    + return mmc_regulator_set_voltage_if_supported(
    + mmc->supply.vqmmc2, 1700000, 1800000, 1950000);
    + default:
    + return -EINVAL;
    + }
    +}
    +EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc2);
    +
    #else

    static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
    @@ -249,6 +276,7 @@ int mmc_regulator_get_supply(struct mmc_host *mmc)

    mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc");
    mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc");
    + mmc->supply.vqmmc2 = devm_regulator_get_optional(dev, "vqmmc2");

    if (IS_ERR(mmc->supply.vmmc)) {
    if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER)
    @@ -268,6 +296,12 @@ int mmc_regulator_get_supply(struct mmc_host *mmc)
    dev_dbg(dev, "No vqmmc regulator found\n");
    }

    + if (IS_ERR(mmc->supply.vqmmc2)) {
    + if (PTR_ERR(mmc->supply.vqmmc2) == -EPROBE_DEFER)
    + return -EPROBE_DEFER;
    + dev_dbg(dev, "No vqmmc2 regulator found\n");
    + }
    +
    return 0;
    }
    EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);
    diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
    index 0b4122b26352..cc2cd502ae29 100644
    --- a/include/linux/mmc/host.h
    +++ b/include/linux/mmc/host.h
    @@ -71,6 +71,9 @@ struct mmc_ios {
    #define MMC_SIGNAL_VOLTAGE_180 1
    #define MMC_SIGNAL_VOLTAGE_120 2

    + unsigned char vqmmc2_voltage;
    +#define MMC_VQMMC2_VOLTAGE_180 0
    +
    unsigned char drv_type; /* driver type (A, B, C, D) */

    #define MMC_SET_DRIVER_TYPE_B 0
    @@ -321,6 +324,7 @@ struct mmc_pwrseq;
    struct mmc_supply {
    struct regulator *vmmc; /* Card power supply */
    struct regulator *vqmmc; /* Optional Vccq supply */
    + struct regulator *vqmmc2; /* Optional supply for phy */
    };

    struct mmc_ctx {
    @@ -600,6 +604,7 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
    struct regulator *supply,
    unsigned short vdd_bit);
    int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios);
    +int mmc_regulator_set_vqmmc2(struct mmc_host *mmc, struct mmc_ios *ios);
    #else
    static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
    struct regulator *supply,
    @@ -613,6 +618,12 @@ static inline int mmc_regulator_set_vqmmc(struct mmc_host *mmc,
    {
    return -EINVAL;
    }
    +
    +static inline int mmc_regulator_set_vqmmc2(struct mmc_host *mmc,
    + struct mmc_ios *ios)
    +{
    + return -EINVAL;
    +}
    #endif

    int mmc_regulator_get_supply(struct mmc_host *mmc);
    --
    2.25.1
    \
     
     \ /
      Last update: 2022-10-14 13:52    [W:5.571 / U:0.120 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site