mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
mmc: core: Extend support for mmc regulators with a vqmmc2
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> Link: https://lore.kernel.org/r/20240913102836.6144-5-victorshihgli@gmail.com
This commit is contained in:
parent
153196d550
commit
a56ffd3a83
|
|
@ -226,6 +226,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)
|
||||
|
|
@ -252,6 +279,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)
|
||||
|
|
@ -275,6 +303,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);
|
||||
|
|
|
|||
|
|
@ -75,6 +75,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
|
||||
|
|
@ -308,6 +311,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 {
|
||||
|
|
@ -590,6 +594,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,
|
||||
|
|
@ -603,6 +608,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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user