提交 488aab3d 编写于 作者: L Lars Persson 提交者: Ulf Hansson

mmc: usdhi6rol0: add pinctrl to set pin drive strength

Some boards need different pin drive strength for the UHS mode. Add an
optional pinctrl setting with two pin states covering UHS speeds and
other speeds.
Signed-off-by: NLars Persson <larper@axis.com>
Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
上级 0cd59df9
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/mmc/sdio.h> #include <linux/mmc/sdio.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -198,6 +199,11 @@ struct usdhi6_host { ...@@ -198,6 +199,11 @@ struct usdhi6_host {
struct dma_chan *chan_rx; struct dma_chan *chan_rx;
struct dma_chan *chan_tx; struct dma_chan *chan_tx;
bool dma_active; bool dma_active;
/* Pin control */
struct pinctrl *pinctrl;
struct pinctrl_state *pins_default;
struct pinctrl_state *pins_uhs;
}; };
/* I/O primitives */ /* I/O primitives */
...@@ -1147,12 +1153,35 @@ static void usdhi6_enable_sdio_irq(struct mmc_host *mmc, int enable) ...@@ -1147,12 +1153,35 @@ static void usdhi6_enable_sdio_irq(struct mmc_host *mmc, int enable)
} }
} }
static int usdhi6_set_pinstates(struct usdhi6_host *host, int voltage)
{
if (IS_ERR(host->pins_uhs))
return 0;
switch (voltage) {
case MMC_SIGNAL_VOLTAGE_180:
case MMC_SIGNAL_VOLTAGE_120:
return pinctrl_select_state(host->pinctrl,
host->pins_uhs);
default:
return pinctrl_select_state(host->pinctrl,
host->pins_default);
}
}
static int usdhi6_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) static int usdhi6_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios)
{ {
int ret; int ret;
ret = mmc_regulator_set_vqmmc(mmc, ios); ret = mmc_regulator_set_vqmmc(mmc, ios);
if (ret < 0)
return ret;
ret = usdhi6_set_pinstates(mmc_priv(mmc), ios->signal_voltage);
if (ret)
dev_warn_once(mmc_dev(mmc),
"Failed to set pinstate err=%d\n", ret);
return ret; return ret;
} }
...@@ -1740,6 +1769,25 @@ static int usdhi6_probe(struct platform_device *pdev) ...@@ -1740,6 +1769,25 @@ static int usdhi6_probe(struct platform_device *pdev)
host->wait = USDHI6_WAIT_FOR_REQUEST; host->wait = USDHI6_WAIT_FOR_REQUEST;
host->timeout = msecs_to_jiffies(4000); host->timeout = msecs_to_jiffies(4000);
host->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(host->pinctrl)) {
ret = PTR_ERR(host->pinctrl);
goto e_free_mmc;
}
host->pins_uhs = pinctrl_lookup_state(host->pinctrl, "state_uhs");
if (!IS_ERR(host->pins_uhs)) {
host->pins_default = pinctrl_lookup_state(host->pinctrl,
PINCTRL_STATE_DEFAULT);
if (IS_ERR(host->pins_default)) {
dev_err(dev,
"UHS pinctrl requires a default pin state.\n");
ret = PTR_ERR(host->pins_default);
goto e_free_mmc;
}
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
host->base = devm_ioremap_resource(dev, res); host->base = devm_ioremap_resource(dev, res);
if (IS_ERR(host->base)) { if (IS_ERR(host->base)) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册