Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Lars Persson <larper@axis.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Lars Persson and committed by
Ulf Hansson
488aab3d 0cd59df9

+48
+48
drivers/mmc/host/usdhi6rol0.c
··· 22 22 #include <linux/mmc/sdio.h> 23 23 #include <linux/module.h> 24 24 #include <linux/pagemap.h> 25 + #include <linux/pinctrl/consumer.h> 25 26 #include <linux/platform_device.h> 26 27 #include <linux/scatterlist.h> 27 28 #include <linux/string.h> ··· 199 198 struct dma_chan *chan_rx; 200 199 struct dma_chan *chan_tx; 201 200 bool dma_active; 201 + 202 + /* Pin control */ 203 + struct pinctrl *pinctrl; 204 + struct pinctrl_state *pins_default; 205 + struct pinctrl_state *pins_uhs; 202 206 }; 203 207 204 208 /* I/O primitives */ ··· 1153 1147 } 1154 1148 } 1155 1149 1150 + static int usdhi6_set_pinstates(struct usdhi6_host *host, int voltage) 1151 + { 1152 + if (IS_ERR(host->pins_uhs)) 1153 + return 0; 1154 + 1155 + switch (voltage) { 1156 + case MMC_SIGNAL_VOLTAGE_180: 1157 + case MMC_SIGNAL_VOLTAGE_120: 1158 + return pinctrl_select_state(host->pinctrl, 1159 + host->pins_uhs); 1160 + 1161 + default: 1162 + return pinctrl_select_state(host->pinctrl, 1163 + host->pins_default); 1164 + } 1165 + } 1166 + 1156 1167 static int usdhi6_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) 1157 1168 { 1158 1169 int ret; 1159 1170 1160 1171 ret = mmc_regulator_set_vqmmc(mmc, ios); 1172 + if (ret < 0) 1173 + return ret; 1161 1174 1175 + ret = usdhi6_set_pinstates(mmc_priv(mmc), ios->signal_voltage); 1176 + if (ret) 1177 + dev_warn_once(mmc_dev(mmc), 1178 + "Failed to set pinstate err=%d\n", ret); 1162 1179 return ret; 1163 1180 } 1164 1181 ··· 1768 1739 host->mmc = mmc; 1769 1740 host->wait = USDHI6_WAIT_FOR_REQUEST; 1770 1741 host->timeout = msecs_to_jiffies(4000); 1742 + 1743 + host->pinctrl = devm_pinctrl_get(&pdev->dev); 1744 + if (IS_ERR(host->pinctrl)) { 1745 + ret = PTR_ERR(host->pinctrl); 1746 + goto e_free_mmc; 1747 + } 1748 + 1749 + host->pins_uhs = pinctrl_lookup_state(host->pinctrl, "state_uhs"); 1750 + if (!IS_ERR(host->pins_uhs)) { 1751 + host->pins_default = pinctrl_lookup_state(host->pinctrl, 1752 + PINCTRL_STATE_DEFAULT); 1753 + 1754 + if (IS_ERR(host->pins_default)) { 1755 + dev_err(dev, 1756 + "UHS pinctrl requires a default pin state.\n"); 1757 + ret = PTR_ERR(host->pins_default); 1758 + goto e_free_mmc; 1759 + } 1760 + } 1771 1761 1772 1762 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1773 1763 host->base = devm_ioremap_resource(dev, res);