axp20x-regulator.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. /*
  2. * AXP20x regulators driver.
  3. *
  4. * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
  5. *
  6. * This file is subject to the terms and conditions of the GNU General
  7. * Public License. See the file "COPYING" in the main directory of this
  8. * archive for more details.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include <linux/err.h>
  16. #include <linux/init.h>
  17. #include <linux/module.h>
  18. #include <linux/of.h>
  19. #include <linux/of_device.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/regmap.h>
  22. #include <linux/mfd/axp20x.h>
  23. #include <linux/regulator/driver.h>
  24. #include <linux/regulator/of_regulator.h>
  25. #define AXP20X_IO_ENABLED 0x03
  26. #define AXP20X_IO_DISABLED 0x07
  27. #define AXP22X_IO_ENABLED 0x03
  28. #define AXP22X_IO_DISABLED 0x04
  29. #define AXP20X_WORKMODE_DCDC2_MASK BIT(2)
  30. #define AXP20X_WORKMODE_DCDC3_MASK BIT(1)
  31. #define AXP22X_WORKMODE_DCDCX_MASK(x) BIT(x)
  32. #define AXP20X_FREQ_DCDC_MASK 0x0f
  33. #define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
  34. _vmask, _ereg, _emask, _enable_val, _disable_val) \
  35. [_family##_##_id] = { \
  36. .name = (_match), \
  37. .supply_name = (_supply), \
  38. .of_match = of_match_ptr(_match), \
  39. .regulators_node = of_match_ptr("regulators"), \
  40. .type = REGULATOR_VOLTAGE, \
  41. .id = _family##_##_id, \
  42. .n_voltages = (((_max) - (_min)) / (_step) + 1), \
  43. .owner = THIS_MODULE, \
  44. .min_uV = (_min) * 1000, \
  45. .uV_step = (_step) * 1000, \
  46. .vsel_reg = (_vreg), \
  47. .vsel_mask = (_vmask), \
  48. .enable_reg = (_ereg), \
  49. .enable_mask = (_emask), \
  50. .enable_val = (_enable_val), \
  51. .disable_val = (_disable_val), \
  52. .ops = &axp20x_ops, \
  53. }
  54. #define AXP_DESC(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
  55. _vmask, _ereg, _emask) \
  56. [_family##_##_id] = { \
  57. .name = (_match), \
  58. .supply_name = (_supply), \
  59. .of_match = of_match_ptr(_match), \
  60. .regulators_node = of_match_ptr("regulators"), \
  61. .type = REGULATOR_VOLTAGE, \
  62. .id = _family##_##_id, \
  63. .n_voltages = (((_max) - (_min)) / (_step) + 1), \
  64. .owner = THIS_MODULE, \
  65. .min_uV = (_min) * 1000, \
  66. .uV_step = (_step) * 1000, \
  67. .vsel_reg = (_vreg), \
  68. .vsel_mask = (_vmask), \
  69. .enable_reg = (_ereg), \
  70. .enable_mask = (_emask), \
  71. .ops = &axp20x_ops, \
  72. }
  73. #define AXP_DESC_SW(_family, _id, _match, _supply, _ereg, _emask) \
  74. [_family##_##_id] = { \
  75. .name = (_match), \
  76. .supply_name = (_supply), \
  77. .of_match = of_match_ptr(_match), \
  78. .regulators_node = of_match_ptr("regulators"), \
  79. .type = REGULATOR_VOLTAGE, \
  80. .id = _family##_##_id, \
  81. .owner = THIS_MODULE, \
  82. .enable_reg = (_ereg), \
  83. .enable_mask = (_emask), \
  84. .ops = &axp20x_ops_sw, \
  85. }
  86. #define AXP_DESC_FIXED(_family, _id, _match, _supply, _volt) \
  87. [_family##_##_id] = { \
  88. .name = (_match), \
  89. .supply_name = (_supply), \
  90. .of_match = of_match_ptr(_match), \
  91. .regulators_node = of_match_ptr("regulators"), \
  92. .type = REGULATOR_VOLTAGE, \
  93. .id = _family##_##_id, \
  94. .n_voltages = 1, \
  95. .owner = THIS_MODULE, \
  96. .min_uV = (_volt) * 1000, \
  97. .ops = &axp20x_ops_fixed \
  98. }
  99. #define AXP_DESC_RANGES(_family, _id, _match, _supply, _ranges, _n_voltages, \
  100. _vreg, _vmask, _ereg, _emask) \
  101. [_family##_##_id] = { \
  102. .name = (_match), \
  103. .supply_name = (_supply), \
  104. .of_match = of_match_ptr(_match), \
  105. .regulators_node = of_match_ptr("regulators"), \
  106. .type = REGULATOR_VOLTAGE, \
  107. .id = _family##_##_id, \
  108. .n_voltages = (_n_voltages), \
  109. .owner = THIS_MODULE, \
  110. .vsel_reg = (_vreg), \
  111. .vsel_mask = (_vmask), \
  112. .enable_reg = (_ereg), \
  113. .enable_mask = (_emask), \
  114. .linear_ranges = (_ranges), \
  115. .n_linear_ranges = ARRAY_SIZE(_ranges), \
  116. .ops = &axp20x_ops_range, \
  117. }
  118. static struct regulator_ops axp20x_ops_fixed = {
  119. .list_voltage = regulator_list_voltage_linear,
  120. };
  121. static struct regulator_ops axp20x_ops_range = {
  122. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  123. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  124. .list_voltage = regulator_list_voltage_linear_range,
  125. .enable = regulator_enable_regmap,
  126. .disable = regulator_disable_regmap,
  127. .is_enabled = regulator_is_enabled_regmap,
  128. };
  129. static struct regulator_ops axp20x_ops = {
  130. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  131. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  132. .list_voltage = regulator_list_voltage_linear,
  133. .enable = regulator_enable_regmap,
  134. .disable = regulator_disable_regmap,
  135. .is_enabled = regulator_is_enabled_regmap,
  136. };
  137. static struct regulator_ops axp20x_ops_sw = {
  138. .enable = regulator_enable_regmap,
  139. .disable = regulator_disable_regmap,
  140. .is_enabled = regulator_is_enabled_regmap,
  141. };
  142. static const struct regulator_linear_range axp20x_ldo4_ranges[] = {
  143. REGULATOR_LINEAR_RANGE(1250000, 0x0, 0x0, 0),
  144. REGULATOR_LINEAR_RANGE(1300000, 0x1, 0x8, 100000),
  145. REGULATOR_LINEAR_RANGE(2500000, 0x9, 0xf, 100000),
  146. };
  147. static const struct regulator_desc axp20x_regulators[] = {
  148. AXP_DESC(AXP20X, DCDC2, "dcdc2", "vin2", 700, 2275, 25,
  149. AXP20X_DCDC2_V_OUT, 0x3f, AXP20X_PWR_OUT_CTRL, 0x10),
  150. AXP_DESC(AXP20X, DCDC3, "dcdc3", "vin3", 700, 3500, 25,
  151. AXP20X_DCDC3_V_OUT, 0x7f, AXP20X_PWR_OUT_CTRL, 0x02),
  152. AXP_DESC_FIXED(AXP20X, LDO1, "ldo1", "acin", 1300),
  153. AXP_DESC(AXP20X, LDO2, "ldo2", "ldo24in", 1800, 3300, 100,
  154. AXP20X_LDO24_V_OUT, 0xf0, AXP20X_PWR_OUT_CTRL, 0x04),
  155. AXP_DESC(AXP20X, LDO3, "ldo3", "ldo3in", 700, 3500, 25,
  156. AXP20X_LDO3_V_OUT, 0x7f, AXP20X_PWR_OUT_CTRL, 0x40),
  157. AXP_DESC_RANGES(AXP20X, LDO4, "ldo4", "ldo24in", axp20x_ldo4_ranges,
  158. 16, AXP20X_LDO24_V_OUT, 0x0f, AXP20X_PWR_OUT_CTRL,
  159. 0x08),
  160. AXP_DESC_IO(AXP20X, LDO5, "ldo5", "ldo5in", 1800, 3300, 100,
  161. AXP20X_LDO5_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07,
  162. AXP20X_IO_ENABLED, AXP20X_IO_DISABLED),
  163. };
  164. static const struct regulator_desc axp22x_regulators[] = {
  165. AXP_DESC(AXP22X, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
  166. AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(1)),
  167. AXP_DESC(AXP22X, DCDC2, "dcdc2", "vin2", 600, 1540, 20,
  168. AXP22X_DCDC2_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(2)),
  169. AXP_DESC(AXP22X, DCDC3, "dcdc3", "vin3", 600, 1860, 20,
  170. AXP22X_DCDC3_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)),
  171. AXP_DESC(AXP22X, DCDC4, "dcdc4", "vin4", 600, 1540, 20,
  172. AXP22X_DCDC4_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(4)),
  173. AXP_DESC(AXP22X, DCDC5, "dcdc5", "vin5", 1000, 2550, 50,
  174. AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(5)),
  175. /* secondary switchable output of DCDC1 */
  176. AXP_DESC_SW(AXP22X, DC1SW, "dc1sw", NULL, AXP22X_PWR_OUT_CTRL2,
  177. BIT(7)),
  178. /* LDO regulator internally chained to DCDC5 */
  179. AXP_DESC(AXP22X, DC5LDO, "dc5ldo", NULL, 700, 1400, 100,
  180. AXP22X_DC5LDO_V_OUT, 0x7, AXP22X_PWR_OUT_CTRL1, BIT(0)),
  181. AXP_DESC(AXP22X, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
  182. AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(6)),
  183. AXP_DESC(AXP22X, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
  184. AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)),
  185. AXP_DESC(AXP22X, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
  186. AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(7)),
  187. AXP_DESC(AXP22X, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
  188. AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(3)),
  189. AXP_DESC(AXP22X, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
  190. AXP22X_DLDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(4)),
  191. AXP_DESC(AXP22X, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
  192. AXP22X_DLDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
  193. AXP_DESC(AXP22X, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
  194. AXP22X_DLDO4_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(6)),
  195. AXP_DESC(AXP22X, ELDO1, "eldo1", "eldoin", 700, 3300, 100,
  196. AXP22X_ELDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(0)),
  197. AXP_DESC(AXP22X, ELDO2, "eldo2", "eldoin", 700, 3300, 100,
  198. AXP22X_ELDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(1)),
  199. AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100,
  200. AXP22X_ELDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(2)),
  201. AXP_DESC_IO(AXP22X, LDO_IO0, "ldo_io0", "ips", 1800, 3300, 100,
  202. AXP22X_LDO_IO0_V_OUT, 0x1f, AXP20X_GPIO0_CTRL, 0x07,
  203. AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
  204. AXP_DESC_IO(AXP22X, LDO_IO1, "ldo_io1", "ips", 1800, 3300, 100,
  205. AXP22X_LDO_IO1_V_OUT, 0x1f, AXP20X_GPIO1_CTRL, 0x07,
  206. AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
  207. AXP_DESC_FIXED(AXP22X, RTC_LDO, "rtc_ldo", "ips", 3000),
  208. };
  209. static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
  210. {
  211. struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
  212. u32 min, max, def, step;
  213. switch (axp20x->variant) {
  214. case AXP202_ID:
  215. case AXP209_ID:
  216. min = 750;
  217. max = 1875;
  218. def = 1500;
  219. step = 75;
  220. break;
  221. case AXP221_ID:
  222. case AXP223_ID:
  223. min = 1800;
  224. max = 4050;
  225. def = 3000;
  226. step = 150;
  227. break;
  228. default:
  229. dev_err(&pdev->dev,
  230. "Setting DCDC frequency for unsupported AXP variant\n");
  231. return -EINVAL;
  232. }
  233. if (dcdcfreq == 0)
  234. dcdcfreq = def;
  235. if (dcdcfreq < min) {
  236. dcdcfreq = min;
  237. dev_warn(&pdev->dev, "DCDC frequency too low. Set to %ukHz\n",
  238. min);
  239. }
  240. if (dcdcfreq > max) {
  241. dcdcfreq = max;
  242. dev_warn(&pdev->dev, "DCDC frequency too high. Set to %ukHz\n",
  243. max);
  244. }
  245. dcdcfreq = (dcdcfreq - min) / step;
  246. return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ,
  247. AXP20X_FREQ_DCDC_MASK, dcdcfreq);
  248. }
  249. static int axp20x_regulator_parse_dt(struct platform_device *pdev)
  250. {
  251. struct device_node *np, *regulators;
  252. int ret;
  253. u32 dcdcfreq = 0;
  254. np = of_node_get(pdev->dev.parent->of_node);
  255. if (!np)
  256. return 0;
  257. regulators = of_get_child_by_name(np, "regulators");
  258. if (!regulators) {
  259. dev_warn(&pdev->dev, "regulators node not found\n");
  260. } else {
  261. of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
  262. ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
  263. if (ret < 0) {
  264. dev_err(&pdev->dev, "Error setting dcdc frequency: %d\n", ret);
  265. return ret;
  266. }
  267. of_node_put(regulators);
  268. }
  269. return 0;
  270. }
  271. static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
  272. {
  273. struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
  274. unsigned int mask;
  275. switch (axp20x->variant) {
  276. case AXP202_ID:
  277. case AXP209_ID:
  278. if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3))
  279. return -EINVAL;
  280. mask = AXP20X_WORKMODE_DCDC2_MASK;
  281. if (id == AXP20X_DCDC3)
  282. mask = AXP20X_WORKMODE_DCDC3_MASK;
  283. workmode <<= ffs(mask) - 1;
  284. break;
  285. case AXP221_ID:
  286. case AXP223_ID:
  287. if (id < AXP22X_DCDC1 || id > AXP22X_DCDC5)
  288. return -EINVAL;
  289. mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP22X_DCDC1);
  290. workmode <<= id - AXP22X_DCDC1;
  291. break;
  292. default:
  293. /* should not happen */
  294. WARN_ON(1);
  295. return -EINVAL;
  296. }
  297. return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode);
  298. }
  299. static int axp20x_regulator_probe(struct platform_device *pdev)
  300. {
  301. struct regulator_dev *rdev;
  302. struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
  303. const struct regulator_desc *regulators;
  304. struct regulator_config config = {
  305. .dev = pdev->dev.parent,
  306. .regmap = axp20x->regmap,
  307. .driver_data = axp20x,
  308. };
  309. int ret, i, nregulators;
  310. u32 workmode;
  311. const char *axp22x_dc1_name = axp22x_regulators[AXP22X_DCDC1].name;
  312. const char *axp22x_dc5_name = axp22x_regulators[AXP22X_DCDC5].name;
  313. switch (axp20x->variant) {
  314. case AXP202_ID:
  315. case AXP209_ID:
  316. regulators = axp20x_regulators;
  317. nregulators = AXP20X_REG_ID_MAX;
  318. break;
  319. case AXP221_ID:
  320. case AXP223_ID:
  321. regulators = axp22x_regulators;
  322. nregulators = AXP22X_REG_ID_MAX;
  323. break;
  324. default:
  325. dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
  326. axp20x->variant);
  327. return -EINVAL;
  328. }
  329. /* This only sets the dcdc freq. Ignore any errors */
  330. axp20x_regulator_parse_dt(pdev);
  331. for (i = 0; i < nregulators; i++) {
  332. const struct regulator_desc *desc = &regulators[i];
  333. struct regulator_desc *new_desc;
  334. /*
  335. * Regulators DC1SW and DC5LDO are connected internally,
  336. * so we have to handle their supply names separately.
  337. *
  338. * We always register the regulators in proper sequence,
  339. * so the supply names are correctly read. See the last
  340. * part of this loop to see where we save the DT defined
  341. * name.
  342. */
  343. if (regulators == axp22x_regulators) {
  344. if (i == AXP22X_DC1SW) {
  345. new_desc = devm_kzalloc(&pdev->dev,
  346. sizeof(*desc),
  347. GFP_KERNEL);
  348. *new_desc = regulators[i];
  349. new_desc->supply_name = axp22x_dc1_name;
  350. desc = new_desc;
  351. } else if (i == AXP22X_DC5LDO) {
  352. new_desc = devm_kzalloc(&pdev->dev,
  353. sizeof(*desc),
  354. GFP_KERNEL);
  355. *new_desc = regulators[i];
  356. new_desc->supply_name = axp22x_dc5_name;
  357. desc = new_desc;
  358. }
  359. }
  360. rdev = devm_regulator_register(&pdev->dev, desc, &config);
  361. if (IS_ERR(rdev)) {
  362. dev_err(&pdev->dev, "Failed to register %s\n",
  363. regulators[i].name);
  364. return PTR_ERR(rdev);
  365. }
  366. ret = of_property_read_u32(rdev->dev.of_node,
  367. "x-powers,dcdc-workmode",
  368. &workmode);
  369. if (!ret) {
  370. if (axp20x_set_dcdc_workmode(rdev, i, workmode))
  371. dev_err(&pdev->dev, "Failed to set workmode on %s\n",
  372. rdev->desc->name);
  373. }
  374. /*
  375. * Save AXP22X DCDC1 / DCDC5 regulator names for later.
  376. */
  377. if (regulators == axp22x_regulators) {
  378. /* Can we use rdev->constraints->name instead? */
  379. if (i == AXP22X_DCDC1)
  380. of_property_read_string(rdev->dev.of_node,
  381. "regulator-name",
  382. &axp22x_dc1_name);
  383. else if (i == AXP22X_DCDC5)
  384. of_property_read_string(rdev->dev.of_node,
  385. "regulator-name",
  386. &axp22x_dc5_name);
  387. }
  388. }
  389. return 0;
  390. }
  391. static struct platform_driver axp20x_regulator_driver = {
  392. .probe = axp20x_regulator_probe,
  393. .driver = {
  394. .name = "axp20x-regulator",
  395. },
  396. };
  397. module_platform_driver(axp20x_regulator_driver);
  398. MODULE_LICENSE("GPL v2");
  399. MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
  400. MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC");
  401. MODULE_ALIAS("platform:axp20x-regulator");