diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2019-02-13 12:10:37 -0500 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2019-02-25 09:20:58 -0500 |
commit | de13d5a44e61366ab5b75c111449ca284b6e3f5d (patch) | |
tree | 363bc760602f0ea03bc2842a07ac97a9b9281d48 /drivers/mmc | |
parent | 643108630e486bcb6c2127ae6d526eb54705161f (diff) |
mmc: core: Move regulator helpers to separate file
The mmc regulator helper functions, are placed in the extensive core.c
file. In a step towards trying to create a better structure of files,
avoiding too many lines of code per file, let's move these helpers to a new
file, regulator.c.
Moreover, this within this context it makes sense to also drop the export
of mmc_vddrange_to_ocrmask(), but instead let's make it internal to the mmc
core.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/Makefile | 2 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 242 | ||||
-rw-r--r-- | drivers/mmc/core/core.h | 1 | ||||
-rw-r--r-- | drivers/mmc/core/regulator.c | 261 |
4 files changed, 263 insertions, 243 deletions
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index abba078f7f49..95ffe008ebdf 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile | |||
@@ -8,7 +8,7 @@ mmc_core-y := core.o bus.o host.o \ | |||
8 | mmc.o mmc_ops.o sd.o sd_ops.o \ | 8 | mmc.o mmc_ops.o sd.o sd_ops.o \ |
9 | sdio.o sdio_ops.o sdio_bus.o \ | 9 | sdio.o sdio_ops.o sdio_bus.o \ |
10 | sdio_cis.o sdio_io.o sdio_irq.o \ | 10 | sdio_cis.o sdio_io.o sdio_irq.o \ |
11 | slot-gpio.o | 11 | slot-gpio.o regulator.o |
12 | mmc_core-$(CONFIG_OF) += pwrseq.o | 12 | mmc_core-$(CONFIG_OF) += pwrseq.o |
13 | obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o | 13 | obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o |
14 | obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o | 14 | obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index de0f1a1f0a63..f796a6afb19b 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/leds.h> | 21 | #include <linux/leds.h> |
22 | #include <linux/scatterlist.h> | 22 | #include <linux/scatterlist.h> |
23 | #include <linux/log2.h> | 23 | #include <linux/log2.h> |
24 | #include <linux/regulator/consumer.h> | ||
25 | #include <linux/pm_runtime.h> | 24 | #include <linux/pm_runtime.h> |
26 | #include <linux/pm_wakeup.h> | 25 | #include <linux/pm_wakeup.h> |
27 | #include <linux/suspend.h> | 26 | #include <linux/suspend.h> |
@@ -1112,7 +1111,6 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) | |||
1112 | 1111 | ||
1113 | return mask; | 1112 | return mask; |
1114 | } | 1113 | } |
1115 | EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); | ||
1116 | 1114 | ||
1117 | #ifdef CONFIG_OF | 1115 | #ifdef CONFIG_OF |
1118 | 1116 | ||
@@ -1190,246 +1188,6 @@ struct device_node *mmc_of_find_child_device(struct mmc_host *host, | |||
1190 | return NULL; | 1188 | return NULL; |
1191 | } | 1189 | } |
1192 | 1190 | ||
1193 | #ifdef CONFIG_REGULATOR | ||
1194 | |||
1195 | /** | ||
1196 | * mmc_ocrbitnum_to_vdd - Convert a OCR bit number to its voltage | ||
1197 | * @vdd_bit: OCR bit number | ||
1198 | * @min_uV: minimum voltage value (mV) | ||
1199 | * @max_uV: maximum voltage value (mV) | ||
1200 | * | ||
1201 | * This function returns the voltage range according to the provided OCR | ||
1202 | * bit number. If conversion is not possible a negative errno value returned. | ||
1203 | */ | ||
1204 | static int mmc_ocrbitnum_to_vdd(int vdd_bit, int *min_uV, int *max_uV) | ||
1205 | { | ||
1206 | int tmp; | ||
1207 | |||
1208 | if (!vdd_bit) | ||
1209 | return -EINVAL; | ||
1210 | |||
1211 | /* | ||
1212 | * REVISIT mmc_vddrange_to_ocrmask() may have set some | ||
1213 | * bits this regulator doesn't quite support ... don't | ||
1214 | * be too picky, most cards and regulators are OK with | ||
1215 | * a 0.1V range goof (it's a small error percentage). | ||
1216 | */ | ||
1217 | tmp = vdd_bit - ilog2(MMC_VDD_165_195); | ||
1218 | if (tmp == 0) { | ||
1219 | *min_uV = 1650 * 1000; | ||
1220 | *max_uV = 1950 * 1000; | ||
1221 | } else { | ||
1222 | *min_uV = 1900 * 1000 + tmp * 100 * 1000; | ||
1223 | *max_uV = *min_uV + 100 * 1000; | ||
1224 | } | ||
1225 | |||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1229 | /** | ||
1230 | * mmc_regulator_get_ocrmask - return mask of supported voltages | ||
1231 | * @supply: regulator to use | ||
1232 | * | ||
1233 | * This returns either a negative errno, or a mask of voltages that | ||
1234 | * can be provided to MMC/SD/SDIO devices using the specified voltage | ||
1235 | * regulator. This would normally be called before registering the | ||
1236 | * MMC host adapter. | ||
1237 | */ | ||
1238 | int mmc_regulator_get_ocrmask(struct regulator *supply) | ||
1239 | { | ||
1240 | int result = 0; | ||
1241 | int count; | ||
1242 | int i; | ||
1243 | int vdd_uV; | ||
1244 | int vdd_mV; | ||
1245 | |||
1246 | count = regulator_count_voltages(supply); | ||
1247 | if (count < 0) | ||
1248 | return count; | ||
1249 | |||
1250 | for (i = 0; i < count; i++) { | ||
1251 | vdd_uV = regulator_list_voltage(supply, i); | ||
1252 | if (vdd_uV <= 0) | ||
1253 | continue; | ||
1254 | |||
1255 | vdd_mV = vdd_uV / 1000; | ||
1256 | result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV); | ||
1257 | } | ||
1258 | |||
1259 | if (!result) { | ||
1260 | vdd_uV = regulator_get_voltage(supply); | ||
1261 | if (vdd_uV <= 0) | ||
1262 | return vdd_uV; | ||
1263 | |||
1264 | vdd_mV = vdd_uV / 1000; | ||
1265 | result = mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV); | ||
1266 | } | ||
1267 | |||
1268 | return result; | ||
1269 | } | ||
1270 | EXPORT_SYMBOL_GPL(mmc_regulator_get_ocrmask); | ||
1271 | |||
1272 | /** | ||
1273 | * mmc_regulator_set_ocr - set regulator to match host->ios voltage | ||
1274 | * @mmc: the host to regulate | ||
1275 | * @supply: regulator to use | ||
1276 | * @vdd_bit: zero for power off, else a bit number (host->ios.vdd) | ||
1277 | * | ||
1278 | * Returns zero on success, else negative errno. | ||
1279 | * | ||
1280 | * MMC host drivers may use this to enable or disable a regulator using | ||
1281 | * a particular supply voltage. This would normally be called from the | ||
1282 | * set_ios() method. | ||
1283 | */ | ||
1284 | int mmc_regulator_set_ocr(struct mmc_host *mmc, | ||
1285 | struct regulator *supply, | ||
1286 | unsigned short vdd_bit) | ||
1287 | { | ||
1288 | int result = 0; | ||
1289 | int min_uV, max_uV; | ||
1290 | |||
1291 | if (vdd_bit) { | ||
1292 | mmc_ocrbitnum_to_vdd(vdd_bit, &min_uV, &max_uV); | ||
1293 | |||
1294 | result = regulator_set_voltage(supply, min_uV, max_uV); | ||
1295 | if (result == 0 && !mmc->regulator_enabled) { | ||
1296 | result = regulator_enable(supply); | ||
1297 | if (!result) | ||
1298 | mmc->regulator_enabled = true; | ||
1299 | } | ||
1300 | } else if (mmc->regulator_enabled) { | ||
1301 | result = regulator_disable(supply); | ||
1302 | if (result == 0) | ||
1303 | mmc->regulator_enabled = false; | ||
1304 | } | ||
1305 | |||
1306 | if (result) | ||
1307 | dev_err(mmc_dev(mmc), | ||
1308 | "could not set regulator OCR (%d)\n", result); | ||
1309 | return result; | ||
1310 | } | ||
1311 | EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr); | ||
1312 | |||
1313 | static int mmc_regulator_set_voltage_if_supported(struct regulator *regulator, | ||
1314 | int min_uV, int target_uV, | ||
1315 | int max_uV) | ||
1316 | { | ||
1317 | /* | ||
1318 | * Check if supported first to avoid errors since we may try several | ||
1319 | * signal levels during power up and don't want to show errors. | ||
1320 | */ | ||
1321 | if (!regulator_is_supported_voltage(regulator, min_uV, max_uV)) | ||
1322 | return -EINVAL; | ||
1323 | |||
1324 | return regulator_set_voltage_triplet(regulator, min_uV, target_uV, | ||
1325 | max_uV); | ||
1326 | } | ||
1327 | |||
1328 | /** | ||
1329 | * mmc_regulator_set_vqmmc - Set VQMMC as per the ios | ||
1330 | * | ||
1331 | * For 3.3V signaling, we try to match VQMMC to VMMC as closely as possible. | ||
1332 | * That will match the behavior of old boards where VQMMC and VMMC were supplied | ||
1333 | * by the same supply. The Bus Operating conditions for 3.3V signaling in the | ||
1334 | * SD card spec also define VQMMC in terms of VMMC. | ||
1335 | * If this is not possible we'll try the full 2.7-3.6V of the spec. | ||
1336 | * | ||
1337 | * For 1.2V and 1.8V signaling we'll try to get as close as possible to the | ||
1338 | * requested voltage. This is definitely a good idea for UHS where there's a | ||
1339 | * separate regulator on the card that's trying to make 1.8V and it's best if | ||
1340 | * we match. | ||
1341 | * | ||
1342 | * This function is expected to be used by a controller's | ||
1343 | * start_signal_voltage_switch() function. | ||
1344 | */ | ||
1345 | int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios) | ||
1346 | { | ||
1347 | struct device *dev = mmc_dev(mmc); | ||
1348 | int ret, volt, min_uV, max_uV; | ||
1349 | |||
1350 | /* If no vqmmc supply then we can't change the voltage */ | ||
1351 | if (IS_ERR(mmc->supply.vqmmc)) | ||
1352 | return -EINVAL; | ||
1353 | |||
1354 | switch (ios->signal_voltage) { | ||
1355 | case MMC_SIGNAL_VOLTAGE_120: | ||
1356 | return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, | ||
1357 | 1100000, 1200000, 1300000); | ||
1358 | case MMC_SIGNAL_VOLTAGE_180: | ||
1359 | return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, | ||
1360 | 1700000, 1800000, 1950000); | ||
1361 | case MMC_SIGNAL_VOLTAGE_330: | ||
1362 | ret = mmc_ocrbitnum_to_vdd(mmc->ios.vdd, &volt, &max_uV); | ||
1363 | if (ret < 0) | ||
1364 | return ret; | ||
1365 | |||
1366 | dev_dbg(dev, "%s: found vmmc voltage range of %d-%duV\n", | ||
1367 | __func__, volt, max_uV); | ||
1368 | |||
1369 | min_uV = max(volt - 300000, 2700000); | ||
1370 | max_uV = min(max_uV + 200000, 3600000); | ||
1371 | |||
1372 | /* | ||
1373 | * Due to a limitation in the current implementation of | ||
1374 | * regulator_set_voltage_triplet() which is taking the lowest | ||
1375 | * voltage possible if below the target, search for a suitable | ||
1376 | * voltage in two steps and try to stay close to vmmc | ||
1377 | * with a 0.3V tolerance at first. | ||
1378 | */ | ||
1379 | if (!mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, | ||
1380 | min_uV, volt, max_uV)) | ||
1381 | return 0; | ||
1382 | |||
1383 | return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, | ||
1384 | 2700000, volt, 3600000); | ||
1385 | default: | ||
1386 | return -EINVAL; | ||
1387 | } | ||
1388 | } | ||
1389 | EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc); | ||
1390 | |||
1391 | #endif /* CONFIG_REGULATOR */ | ||
1392 | |||
1393 | /** | ||
1394 | * mmc_regulator_get_supply - try to get VMMC and VQMMC regulators for a host | ||
1395 | * @mmc: the host to regulate | ||
1396 | * | ||
1397 | * Returns 0 or errno. errno should be handled, it is either a critical error | ||
1398 | * or -EPROBE_DEFER. 0 means no critical error but it does not mean all | ||
1399 | * regulators have been found because they all are optional. If you require | ||
1400 | * certain regulators, you need to check separately in your driver if they got | ||
1401 | * populated after calling this function. | ||
1402 | */ | ||
1403 | int mmc_regulator_get_supply(struct mmc_host *mmc) | ||
1404 | { | ||
1405 | struct device *dev = mmc_dev(mmc); | ||
1406 | int ret; | ||
1407 | |||
1408 | mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc"); | ||
1409 | mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc"); | ||
1410 | |||
1411 | if (IS_ERR(mmc->supply.vmmc)) { | ||
1412 | if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER) | ||
1413 | return -EPROBE_DEFER; | ||
1414 | dev_dbg(dev, "No vmmc regulator found\n"); | ||
1415 | } else { | ||
1416 | ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc); | ||
1417 | if (ret > 0) | ||
1418 | mmc->ocr_avail = ret; | ||
1419 | else | ||
1420 | dev_warn(dev, "Failed getting OCR mask: %d\n", ret); | ||
1421 | } | ||
1422 | |||
1423 | if (IS_ERR(mmc->supply.vqmmc)) { | ||
1424 | if (PTR_ERR(mmc->supply.vqmmc) == -EPROBE_DEFER) | ||
1425 | return -EPROBE_DEFER; | ||
1426 | dev_dbg(dev, "No vqmmc regulator found\n"); | ||
1427 | } | ||
1428 | |||
1429 | return 0; | ||
1430 | } | ||
1431 | EXPORT_SYMBOL_GPL(mmc_regulator_get_supply); | ||
1432 | |||
1433 | /* | 1191 | /* |
1434 | * Mask off any voltages we don't support and select | 1192 | * Mask off any voltages we don't support and select |
1435 | * the lowest voltage | 1193 | * the lowest voltage |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 8fb6bc37f808..b5083b13d594 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -59,6 +59,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr); | |||
59 | void mmc_power_off(struct mmc_host *host); | 59 | void mmc_power_off(struct mmc_host *host); |
60 | void mmc_power_cycle(struct mmc_host *host, u32 ocr); | 60 | void mmc_power_cycle(struct mmc_host *host, u32 ocr); |
61 | void mmc_set_initial_state(struct mmc_host *host); | 61 | void mmc_set_initial_state(struct mmc_host *host); |
62 | u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); | ||
62 | 63 | ||
63 | static inline void mmc_delay(unsigned int ms) | 64 | static inline void mmc_delay(unsigned int ms) |
64 | { | 65 | { |
diff --git a/drivers/mmc/core/regulator.c b/drivers/mmc/core/regulator.c new file mode 100644 index 000000000000..80f95f86ca0e --- /dev/null +++ b/drivers/mmc/core/regulator.c | |||
@@ -0,0 +1,261 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Helper functions for MMC regulators. | ||
4 | */ | ||
5 | |||
6 | #include <linux/device.h> | ||
7 | #include <linux/err.h> | ||
8 | #include <linux/log2.h> | ||
9 | #include <linux/regulator/consumer.h> | ||
10 | |||
11 | #include <linux/mmc/host.h> | ||
12 | |||
13 | #include "core.h" | ||
14 | #include "host.h" | ||
15 | |||
16 | #ifdef CONFIG_REGULATOR | ||
17 | |||
18 | /** | ||
19 | * mmc_ocrbitnum_to_vdd - Convert a OCR bit number to its voltage | ||
20 | * @vdd_bit: OCR bit number | ||
21 | * @min_uV: minimum voltage value (mV) | ||
22 | * @max_uV: maximum voltage value (mV) | ||
23 | * | ||
24 | * This function returns the voltage range according to the provided OCR | ||
25 | * bit number. If conversion is not possible a negative errno value returned. | ||
26 | */ | ||
27 | static int mmc_ocrbitnum_to_vdd(int vdd_bit, int *min_uV, int *max_uV) | ||
28 | { | ||
29 | int tmp; | ||
30 | |||
31 | if (!vdd_bit) | ||
32 | return -EINVAL; | ||
33 | |||
34 | /* | ||
35 | * REVISIT mmc_vddrange_to_ocrmask() may have set some | ||
36 | * bits this regulator doesn't quite support ... don't | ||
37 | * be too picky, most cards and regulators are OK with | ||
38 | * a 0.1V range goof (it's a small error percentage). | ||
39 | */ | ||
40 | tmp = vdd_bit - ilog2(MMC_VDD_165_195); | ||
41 | if (tmp == 0) { | ||
42 | *min_uV = 1650 * 1000; | ||
43 | *max_uV = 1950 * 1000; | ||
44 | } else { | ||
45 | *min_uV = 1900 * 1000 + tmp * 100 * 1000; | ||
46 | *max_uV = *min_uV + 100 * 1000; | ||
47 | } | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * mmc_regulator_get_ocrmask - return mask of supported voltages | ||
54 | * @supply: regulator to use | ||
55 | * | ||
56 | * This returns either a negative errno, or a mask of voltages that | ||
57 | * can be provided to MMC/SD/SDIO devices using the specified voltage | ||
58 | * regulator. This would normally be called before registering the | ||
59 | * MMC host adapter. | ||
60 | */ | ||
61 | int mmc_regulator_get_ocrmask(struct regulator *supply) | ||
62 | { | ||
63 | int result = 0; | ||
64 | int count; | ||
65 | int i; | ||
66 | int vdd_uV; | ||
67 | int vdd_mV; | ||
68 | |||
69 | count = regulator_count_voltages(supply); | ||
70 | if (count < 0) | ||
71 | return count; | ||
72 | |||
73 | for (i = 0; i < count; i++) { | ||
74 | vdd_uV = regulator_list_voltage(supply, i); | ||
75 | if (vdd_uV <= 0) | ||
76 | continue; | ||
77 | |||
78 | vdd_mV = vdd_uV / 1000; | ||
79 | result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV); | ||
80 | } | ||
81 | |||
82 | if (!result) { | ||
83 | vdd_uV = regulator_get_voltage(supply); | ||
84 | if (vdd_uV <= 0) | ||
85 | return vdd_uV; | ||
86 | |||
87 | vdd_mV = vdd_uV / 1000; | ||
88 | result = mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV); | ||
89 | } | ||
90 | |||
91 | return result; | ||
92 | } | ||
93 | EXPORT_SYMBOL_GPL(mmc_regulator_get_ocrmask); | ||
94 | |||
95 | /** | ||
96 | * mmc_regulator_set_ocr - set regulator to match host->ios voltage | ||
97 | * @mmc: the host to regulate | ||
98 | * @supply: regulator to use | ||
99 | * @vdd_bit: zero for power off, else a bit number (host->ios.vdd) | ||
100 | * | ||
101 | * Returns zero on success, else negative errno. | ||
102 | * | ||
103 | * MMC host drivers may use this to enable or disable a regulator using | ||
104 | * a particular supply voltage. This would normally be called from the | ||
105 | * set_ios() method. | ||
106 | */ | ||
107 | int mmc_regulator_set_ocr(struct mmc_host *mmc, | ||
108 | struct regulator *supply, | ||
109 | unsigned short vdd_bit) | ||
110 | { | ||
111 | int result = 0; | ||
112 | int min_uV, max_uV; | ||
113 | |||
114 | if (vdd_bit) { | ||
115 | mmc_ocrbitnum_to_vdd(vdd_bit, &min_uV, &max_uV); | ||
116 | |||
117 | result = regulator_set_voltage(supply, min_uV, max_uV); | ||
118 | if (result == 0 && !mmc->regulator_enabled) { | ||
119 | result = regulator_enable(supply); | ||
120 | if (!result) | ||
121 | mmc->regulator_enabled = true; | ||
122 | } | ||
123 | } else if (mmc->regulator_enabled) { | ||
124 | result = regulator_disable(supply); | ||
125 | if (result == 0) | ||
126 | mmc->regulator_enabled = false; | ||
127 | } | ||
128 | |||
129 | if (result) | ||
130 | dev_err(mmc_dev(mmc), | ||
131 | "could not set regulator OCR (%d)\n", result); | ||
132 | return result; | ||
133 | } | ||
134 | EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr); | ||
135 | |||
136 | static int mmc_regulator_set_voltage_if_supported(struct regulator *regulator, | ||
137 | int min_uV, int target_uV, | ||
138 | int max_uV) | ||
139 | { | ||
140 | /* | ||
141 | * Check if supported first to avoid errors since we may try several | ||
142 | * signal levels during power up and don't want to show errors. | ||
143 | */ | ||
144 | if (!regulator_is_supported_voltage(regulator, min_uV, max_uV)) | ||
145 | return -EINVAL; | ||
146 | |||
147 | return regulator_set_voltage_triplet(regulator, min_uV, target_uV, | ||
148 | max_uV); | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * mmc_regulator_set_vqmmc - Set VQMMC as per the ios | ||
153 | * | ||
154 | * For 3.3V signaling, we try to match VQMMC to VMMC as closely as possible. | ||
155 | * That will match the behavior of old boards where VQMMC and VMMC were supplied | ||
156 | * by the same supply. The Bus Operating conditions for 3.3V signaling in the | ||
157 | * SD card spec also define VQMMC in terms of VMMC. | ||
158 | * If this is not possible we'll try the full 2.7-3.6V of the spec. | ||
159 | * | ||
160 | * For 1.2V and 1.8V signaling we'll try to get as close as possible to the | ||
161 | * requested voltage. This is definitely a good idea for UHS where there's a | ||
162 | * separate regulator on the card that's trying to make 1.8V and it's best if | ||
163 | * we match. | ||
164 | * | ||
165 | * This function is expected to be used by a controller's | ||
166 | * start_signal_voltage_switch() function. | ||
167 | */ | ||
168 | int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios) | ||
169 | { | ||
170 | struct device *dev = mmc_dev(mmc); | ||
171 | int ret, volt, min_uV, max_uV; | ||
172 | |||
173 | /* If no vqmmc supply then we can't change the voltage */ | ||
174 | if (IS_ERR(mmc->supply.vqmmc)) | ||
175 | return -EINVAL; | ||
176 | |||
177 | switch (ios->signal_voltage) { | ||
178 | case MMC_SIGNAL_VOLTAGE_120: | ||
179 | return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, | ||
180 | 1100000, 1200000, 1300000); | ||
181 | case MMC_SIGNAL_VOLTAGE_180: | ||
182 | return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, | ||
183 | 1700000, 1800000, 1950000); | ||
184 | case MMC_SIGNAL_VOLTAGE_330: | ||
185 | ret = mmc_ocrbitnum_to_vdd(mmc->ios.vdd, &volt, &max_uV); | ||
186 | if (ret < 0) | ||
187 | return ret; | ||
188 | |||
189 | dev_dbg(dev, "%s: found vmmc voltage range of %d-%duV\n", | ||
190 | __func__, volt, max_uV); | ||
191 | |||
192 | min_uV = max(volt - 300000, 2700000); | ||
193 | max_uV = min(max_uV + 200000, 3600000); | ||
194 | |||
195 | /* | ||
196 | * Due to a limitation in the current implementation of | ||
197 | * regulator_set_voltage_triplet() which is taking the lowest | ||
198 | * voltage possible if below the target, search for a suitable | ||
199 | * voltage in two steps and try to stay close to vmmc | ||
200 | * with a 0.3V tolerance at first. | ||
201 | */ | ||
202 | if (!mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, | ||
203 | min_uV, volt, max_uV)) | ||
204 | return 0; | ||
205 | |||
206 | return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc, | ||
207 | 2700000, volt, 3600000); | ||
208 | default: | ||
209 | return -EINVAL; | ||
210 | } | ||
211 | } | ||
212 | EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc); | ||
213 | |||
214 | #else | ||
215 | |||
216 | static inline int mmc_regulator_get_ocrmask(struct regulator *supply) | ||
217 | { | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | #endif /* CONFIG_REGULATOR */ | ||
222 | |||
223 | /** | ||
224 | * mmc_regulator_get_supply - try to get VMMC and VQMMC regulators for a host | ||
225 | * @mmc: the host to regulate | ||
226 | * | ||
227 | * Returns 0 or errno. errno should be handled, it is either a critical error | ||
228 | * or -EPROBE_DEFER. 0 means no critical error but it does not mean all | ||
229 | * regulators have been found because they all are optional. If you require | ||
230 | * certain regulators, you need to check separately in your driver if they got | ||
231 | * populated after calling this function. | ||
232 | */ | ||
233 | int mmc_regulator_get_supply(struct mmc_host *mmc) | ||
234 | { | ||
235 | struct device *dev = mmc_dev(mmc); | ||
236 | int ret; | ||
237 | |||
238 | mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc"); | ||
239 | mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc"); | ||
240 | |||
241 | if (IS_ERR(mmc->supply.vmmc)) { | ||
242 | if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER) | ||
243 | return -EPROBE_DEFER; | ||
244 | dev_dbg(dev, "No vmmc regulator found\n"); | ||
245 | } else { | ||
246 | ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc); | ||
247 | if (ret > 0) | ||
248 | mmc->ocr_avail = ret; | ||
249 | else | ||
250 | dev_warn(dev, "Failed getting OCR mask: %d\n", ret); | ||
251 | } | ||
252 | |||
253 | if (IS_ERR(mmc->supply.vqmmc)) { | ||
254 | if (PTR_ERR(mmc->supply.vqmmc) == -EPROBE_DEFER) | ||
255 | return -EPROBE_DEFER; | ||
256 | dev_dbg(dev, "No vqmmc regulator found\n"); | ||
257 | } | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | EXPORT_SYMBOL_GPL(mmc_regulator_get_supply); | ||