[PATCH RFC 04/15] mmc: sunxi: Support vqmmc regulator

Ulf Hansson ulf.hansson at linaro.org
Fri Jan 29 03:40:12 PST 2016


On 21 January 2016 at 06:26, Chen-Yu Tsai <wens at csie.org> wrote:
> eMMC chips require 2 power supplies, vmmc for internal logic, and vqmmc
> for driving output buffers. vqmmc also controls signaling voltage. Most
> boards we've seen use the same regulator for both, nevertheless the 2
> have different usages, and should be set separately.
>
> This patch adds support for vqmmc regulator supply, including voltage
> switching. The MMC core can use this to try different signaling voltages
> for eMMC.
>
> Signed-off-by: Chen-Yu Tsai <wens at csie.org>

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sunxi-mmc.c | 31 +++++++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index 0495ae7da6d6..4bec87458317 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -28,6 +28,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/slab.h>
>  #include <linux/reset.h>
> +#include <linux/regulator/consumer.h>
>
>  #include <linux/of_address.h>
>  #include <linux/of_gpio.h>
> @@ -256,6 +257,9 @@ struct sunxi_mmc_host {
>         struct mmc_request *mrq;
>         struct mmc_request *manual_stop_mrq;
>         int             ferror;
> +
> +       /* vqmmc */
> +       bool            vqmmc_enabled;
>  };
>
>  static int sunxi_mmc_reset_host(struct sunxi_mmc_host *host)
> @@ -716,6 +720,16 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>                 if (host->ferror)
>                         return;
>
> +               if (!IS_ERR(mmc->supply.vqmmc)) {
> +                       host->ferror = regulator_enable(mmc->supply.vqmmc);
> +                       if (host->ferror) {
> +                               dev_err(mmc_dev(mmc),
> +                                       "failed to enable vqmmc\n");
> +                               return;
> +                       }
> +                       host->vqmmc_enabled = true;
> +               }
> +
>                 host->ferror = sunxi_mmc_init_host(mmc);
>                 if (host->ferror)
>                         return;
> @@ -727,6 +741,9 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>                 dev_dbg(mmc_dev(mmc), "power off!\n");
>                 sunxi_mmc_reset_host(host);
>                 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;
>                 break;
>         }
>
> @@ -758,6 +775,19 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>         }
>  }
>
> +static int sunxi_mmc_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios)
> +{
> +       /* vqmmc regulator is available */
> +       if (!IS_ERR(mmc->supply.vqmmc))
> +               return mmc_regulator_set_vqmmc(mmc, ios);
> +
> +       /* no vqmmc regulator, assume fixed regulator at 3/3.3V */
> +       if (mmc->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330)
> +               return 0;
> +
> +       return -EINVAL;
> +}
> +
>  static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
>  {
>         struct sunxi_mmc_host *host = mmc_priv(mmc);
> @@ -923,6 +953,7 @@ static struct mmc_host_ops sunxi_mmc_ops = {
>         .get_ro          = mmc_gpio_get_ro,
>         .get_cd          = mmc_gpio_get_cd,
>         .enable_sdio_irq = sunxi_mmc_enable_sdio_irq,
> +       .start_signal_voltage_switch = sunxi_mmc_volt_switch,
>         .hw_reset        = sunxi_mmc_hw_reset,
>         .card_busy       = sunxi_mmc_card_busy,
>  };
> --
> 2.7.0.rc3
>



More information about the linux-arm-kernel mailing list