On Tue, 31 Jan 2023 at 22:02, Paul Cercueil <paul@xxxxxxxxxxxxxxx> wrote: > > Support enabling / disabling the vqmmc power supply if it was provided > by the firmware. > > Provide the .start_signal_voltage_switch callback to change the voltage > of the external vqmmc power supply. > > Signed-off-by: Paul Cercueil <paul@xxxxxxxxxxxxxxx> Applied for next, thanks! Kind regards Uffe > --- > drivers/mmc/host/jz4740_mmc.c | 38 ++++++++++++++++++++++++++++++++++- > 1 file changed, 37 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c > index eb8e9607b086..ccd2c3aed0f0 100644 > --- a/drivers/mmc/host/jz4740_mmc.c > +++ b/drivers/mmc/host/jz4740_mmc.c > @@ -21,6 +21,7 @@ > #include <linux/of_device.h> > #include <linux/pinctrl/consumer.h> > #include <linux/platform_device.h> > +#include <linux/regulator/consumer.h> > #include <linux/rwsem.h> > #include <linux/scatterlist.h> > > @@ -162,6 +163,8 @@ struct jz4740_mmc_host { > struct mmc_request *req; > struct mmc_command *cmd; > > + bool vqmmc_enabled; > + > unsigned long waiting; > > uint32_t cmdat; > @@ -943,6 +946,8 @@ static void jz4740_mmc_request(struct mmc_host *mmc, struct mmc_request *req) > static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > { > struct jz4740_mmc_host *host = mmc_priv(mmc); > + int ret; > + > if (ios->clock) > jz4740_mmc_set_clock_rate(host, ios->clock); > > @@ -955,12 +960,25 @@ static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > clk_prepare_enable(host->clk); > break; > case MMC_POWER_ON: > + if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { > + ret = regulator_enable(mmc->supply.vqmmc); > + if (ret) > + dev_err(&host->pdev->dev, "Failed to set vqmmc power!\n"); > + else > + host->vqmmc_enabled = true; > + } > break; > - default: > + case MMC_POWER_OFF: > if (!IS_ERR(mmc->supply.vmmc)) > mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); > + if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { > + regulator_disable(mmc->supply.vqmmc); > + host->vqmmc_enabled = false; > + } > clk_disable_unprepare(host->clk); > break; > + default: > + break; > } > > switch (ios->bus_width) { > @@ -986,6 +1004,23 @@ static void jz4740_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) > jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_SDIO, enable); > } > > +static int jz4740_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) > +{ > + int ret; > + > + /* vqmmc regulator is available */ > + if (!IS_ERR(mmc->supply.vqmmc)) { > + ret = mmc_regulator_set_vqmmc(mmc, ios); > + return ret < 0 ? ret : 0; > + } > + > + /* no vqmmc regulator, assume fixed regulator at 3/3.3V */ > + if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) > + return 0; > + > + return -EINVAL; > +} > + > static const struct mmc_host_ops jz4740_mmc_ops = { > .request = jz4740_mmc_request, > .pre_req = jz4740_mmc_pre_request, > @@ -994,6 +1029,7 @@ static const struct mmc_host_ops jz4740_mmc_ops = { > .get_ro = mmc_gpio_get_ro, > .get_cd = mmc_gpio_get_cd, > .enable_sdio_irq = jz4740_mmc_enable_sdio_irq, > + .start_signal_voltage_switch = jz4740_voltage_switch, > }; > > static inline struct jz4740_mmc_host * > -- > 2.39.1 >