]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
mmc: mmci: Add support for setting pad type via pinctrl
authorPatrice Chotard <patrice.chotard@st.com>
Thu, 18 Jan 2018 14:34:20 +0000 (15:34 +0100)
committerUlf Hansson <ulf.hansson@linaro.org>
Thu, 18 Jan 2018 17:14:45 +0000 (18:14 +0100)
If variant hasn't the control bit to switch pads in opendrain mode,
we can achieve the same result by asking to the pinmux driver to
configure pins for us.

This patch make the mmci driver able to do this whenever needed.

Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.h

index c1123f644959711b42f8bb24b8683e2fccf057ee..f8a21f3c3b519777de7dbbd99d2365dcb7e8fb63 100644 (file)
@@ -1465,8 +1465,19 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                                ~MCI_ST_DATA2DIREN);
        }
 
-       if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN && variant->opendrain)
-               pwr |= variant->opendrain;
+       if (variant->opendrain) {
+               if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+                       pwr |= variant->opendrain;
+       } else {
+               /*
+                * If the variant cannot configure the pads by its own, then we
+                * expect the pinctrl to be able to do that for us
+                */
+               if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+                       pinctrl_select_state(host->pinctrl, host->pins_opendrain);
+               else
+                       pinctrl_select_state(host->pinctrl, host->pins_default);
+       }
 
        /*
         * If clock = 0 and the variant requires the MMCIPOWER to be used for
@@ -1610,6 +1621,32 @@ static int mmci_probe(struct amba_device *dev,
        host = mmc_priv(mmc);
        host->mmc = mmc;
 
+       /*
+        * Some variant (STM32) doesn't have opendrain bit, nevertheless
+        * pins can be set accordingly using pinctrl
+        */
+       if (!variant->opendrain) {
+               host->pinctrl = devm_pinctrl_get(&dev->dev);
+               if (IS_ERR(host->pinctrl)) {
+                       dev_err(&dev->dev, "failed to get pinctrl");
+                       goto host_free;
+               }
+
+               host->pins_default = pinctrl_lookup_state(host->pinctrl,
+                                                         PINCTRL_STATE_DEFAULT);
+               if (IS_ERR(host->pins_default)) {
+                       dev_err(mmc_dev(mmc), "Can't select default pins\n");
+                       goto host_free;
+               }
+
+               host->pins_opendrain = pinctrl_lookup_state(host->pinctrl,
+                                                           MMCI_PINCTRL_STATE_OPENDRAIN);
+               if (IS_ERR(host->pins_opendrain)) {
+                       dev_err(mmc_dev(mmc), "Can't select opendrain pins\n");
+                       goto host_free;
+               }
+       }
+
        host->hw_designer = amba_manf(dev);
        host->hw_revision = amba_rev(dev);
        dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
index 83160a9c4c773d1c9fcd13a194ae2020ff8ae365..f91cdf7f6dae766e7e76fd98626cb401f190cd61 100644 (file)
 
 #define NR_SG          128
 
+#define MMCI_PINCTRL_STATE_OPENDRAIN "opendrain"
+
 struct clk;
 struct variant_data;
 struct dma_chan;
@@ -227,6 +229,9 @@ struct mmci_host {
        bool                    vqmmc_enabled;
        struct mmci_platform_data *plat;
        struct variant_data     *variant;
+       struct pinctrl          *pinctrl;
+       struct pinctrl_state    *pins_default;
+       struct pinctrl_state    *pins_opendrain;
 
        u8                      hw_designer;
        u8                      hw_revision:4;