lm363x-regulator.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * TI LM363X Regulator Driver
  3. *
  4. * Copyright 2015 Texas Instruments
  5. *
  6. * Author: Milo Kim <[email protected]>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/err.h>
  13. #include <linux/kernel.h>
  14. #include <linux/mfd/ti-lmu.h>
  15. #include <linux/mfd/ti-lmu-register.h>
  16. #include <linux/module.h>
  17. #include <linux/of.h>
  18. #include <linux/of_gpio.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/regulator/driver.h>
  21. #include <linux/regulator/of_regulator.h>
  22. #include <linux/slab.h>
  23. /* LM3631 */
  24. #define LM3631_BOOST_VSEL_MAX 0x25
  25. #define LM3631_LDO_VSEL_MAX 0x28
  26. #define LM3631_CONT_VSEL_MAX 0x03
  27. #define LM3631_VBOOST_MIN 4500000
  28. #define LM3631_VCONT_MIN 1800000
  29. #define LM3631_VLDO_MIN 4000000
  30. #define ENABLE_TIME_USEC 1000
  31. /* LM3632 */
  32. #define LM3632_BOOST_VSEL_MAX 0x26
  33. #define LM3632_LDO_VSEL_MAX 0x28
  34. #define LM3632_VBOOST_MIN 4500000
  35. #define LM3632_VLDO_MIN 4000000
  36. /* Common */
  37. #define LM363X_STEP_50mV 50000
  38. #define LM363X_STEP_500mV 500000
  39. static const int ldo_cont_enable_time[] = {
  40. 0, 2000, 5000, 10000, 20000, 50000, 100000, 200000,
  41. };
  42. static int lm363x_regulator_enable_time(struct regulator_dev *rdev)
  43. {
  44. enum lm363x_regulator_id id = rdev_get_id(rdev);
  45. u8 val, addr, mask;
  46. switch (id) {
  47. case LM3631_LDO_CONT:
  48. addr = LM3631_REG_ENTIME_VCONT;
  49. mask = LM3631_ENTIME_CONT_MASK;
  50. break;
  51. case LM3631_LDO_OREF:
  52. addr = LM3631_REG_ENTIME_VOREF;
  53. mask = LM3631_ENTIME_MASK;
  54. break;
  55. case LM3631_LDO_POS:
  56. addr = LM3631_REG_ENTIME_VPOS;
  57. mask = LM3631_ENTIME_MASK;
  58. break;
  59. case LM3631_LDO_NEG:
  60. addr = LM3631_REG_ENTIME_VNEG;
  61. mask = LM3631_ENTIME_MASK;
  62. break;
  63. default:
  64. return 0;
  65. }
  66. if (regmap_read(rdev->regmap, addr, (unsigned int *)&val))
  67. return -EINVAL;
  68. val = (val & mask) >> LM3631_ENTIME_SHIFT;
  69. if (id == LM3631_LDO_CONT)
  70. return ldo_cont_enable_time[val];
  71. else
  72. return ENABLE_TIME_USEC * val;
  73. }
  74. static struct regulator_ops lm363x_boost_voltage_table_ops = {
  75. .list_voltage = regulator_list_voltage_linear,
  76. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  77. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  78. };
  79. static struct regulator_ops lm363x_regulator_voltage_table_ops = {
  80. .list_voltage = regulator_list_voltage_linear,
  81. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  82. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  83. .enable = regulator_enable_regmap,
  84. .disable = regulator_disable_regmap,
  85. .is_enabled = regulator_is_enabled_regmap,
  86. .enable_time = lm363x_regulator_enable_time,
  87. };
  88. static const struct regulator_desc lm363x_regulator_desc[] = {
  89. /* LM3631 */
  90. {
  91. .name = "vboost",
  92. .of_match = "vboost",
  93. .id = LM3631_BOOST,
  94. .ops = &lm363x_boost_voltage_table_ops,
  95. .n_voltages = LM3631_BOOST_VSEL_MAX + 1,
  96. .min_uV = LM3631_VBOOST_MIN,
  97. .uV_step = LM363X_STEP_50mV,
  98. .type = REGULATOR_VOLTAGE,
  99. .owner = THIS_MODULE,
  100. .vsel_reg = LM3631_REG_VOUT_BOOST,
  101. .vsel_mask = LM3631_VOUT_MASK,
  102. },
  103. {
  104. .name = "ldo_cont",
  105. .of_match = "vcont",
  106. .id = LM3631_LDO_CONT,
  107. .ops = &lm363x_regulator_voltage_table_ops,
  108. .n_voltages = LM3631_CONT_VSEL_MAX + 1,
  109. .min_uV = LM3631_VCONT_MIN,
  110. .uV_step = LM363X_STEP_500mV,
  111. .type = REGULATOR_VOLTAGE,
  112. .owner = THIS_MODULE,
  113. .vsel_reg = LM3631_REG_VOUT_CONT,
  114. .vsel_mask = LM3631_VOUT_CONT_MASK,
  115. .enable_reg = LM3631_REG_LDO_CTRL2,
  116. .enable_mask = LM3631_EN_CONT_MASK,
  117. },
  118. {
  119. .name = "ldo_oref",
  120. .of_match = "voref",
  121. .id = LM3631_LDO_OREF,
  122. .ops = &lm363x_regulator_voltage_table_ops,
  123. .n_voltages = LM3631_LDO_VSEL_MAX + 1,
  124. .min_uV = LM3631_VLDO_MIN,
  125. .uV_step = LM363X_STEP_50mV,
  126. .type = REGULATOR_VOLTAGE,
  127. .owner = THIS_MODULE,
  128. .vsel_reg = LM3631_REG_VOUT_OREF,
  129. .vsel_mask = LM3631_VOUT_MASK,
  130. .enable_reg = LM3631_REG_LDO_CTRL1,
  131. .enable_mask = LM3631_EN_OREF_MASK,
  132. },
  133. {
  134. .name = "ldo_vpos",
  135. .of_match = "vpos",
  136. .id = LM3631_LDO_POS,
  137. .ops = &lm363x_regulator_voltage_table_ops,
  138. .n_voltages = LM3631_LDO_VSEL_MAX + 1,
  139. .min_uV = LM3631_VLDO_MIN,
  140. .uV_step = LM363X_STEP_50mV,
  141. .type = REGULATOR_VOLTAGE,
  142. .owner = THIS_MODULE,
  143. .vsel_reg = LM3631_REG_VOUT_POS,
  144. .vsel_mask = LM3631_VOUT_MASK,
  145. .enable_reg = LM3631_REG_LDO_CTRL1,
  146. .enable_mask = LM3631_EN_VPOS_MASK,
  147. },
  148. {
  149. .name = "ldo_vneg",
  150. .of_match = "vneg",
  151. .id = LM3631_LDO_NEG,
  152. .ops = &lm363x_regulator_voltage_table_ops,
  153. .n_voltages = LM3631_LDO_VSEL_MAX + 1,
  154. .min_uV = LM3631_VLDO_MIN,
  155. .uV_step = LM363X_STEP_50mV,
  156. .type = REGULATOR_VOLTAGE,
  157. .owner = THIS_MODULE,
  158. .vsel_reg = LM3631_REG_VOUT_NEG,
  159. .vsel_mask = LM3631_VOUT_MASK,
  160. .enable_reg = LM3631_REG_LDO_CTRL1,
  161. .enable_mask = LM3631_EN_VNEG_MASK,
  162. },
  163. /* LM3632 */
  164. {
  165. .name = "vboost",
  166. .of_match = "vboost",
  167. .id = LM3632_BOOST,
  168. .ops = &lm363x_boost_voltage_table_ops,
  169. .n_voltages = LM3632_BOOST_VSEL_MAX + 1,
  170. .min_uV = LM3632_VBOOST_MIN,
  171. .uV_step = LM363X_STEP_50mV,
  172. .type = REGULATOR_VOLTAGE,
  173. .owner = THIS_MODULE,
  174. .vsel_reg = LM3632_REG_VOUT_BOOST,
  175. .vsel_mask = LM3632_VOUT_MASK,
  176. },
  177. {
  178. .name = "ldo_vpos",
  179. .of_match = "vpos",
  180. .id = LM3632_LDO_POS,
  181. .ops = &lm363x_regulator_voltage_table_ops,
  182. .n_voltages = LM3632_LDO_VSEL_MAX + 1,
  183. .min_uV = LM3632_VLDO_MIN,
  184. .uV_step = LM363X_STEP_50mV,
  185. .type = REGULATOR_VOLTAGE,
  186. .owner = THIS_MODULE,
  187. .vsel_reg = LM3632_REG_VOUT_POS,
  188. .vsel_mask = LM3632_VOUT_MASK,
  189. .enable_reg = LM3632_REG_BIAS_CONFIG,
  190. .enable_mask = LM3632_EN_VPOS_MASK,
  191. },
  192. {
  193. .name = "ldo_vneg",
  194. .of_match = "vneg",
  195. .id = LM3632_LDO_NEG,
  196. .ops = &lm363x_regulator_voltage_table_ops,
  197. .n_voltages = LM3632_LDO_VSEL_MAX + 1,
  198. .min_uV = LM3632_VLDO_MIN,
  199. .uV_step = LM363X_STEP_50mV,
  200. .type = REGULATOR_VOLTAGE,
  201. .owner = THIS_MODULE,
  202. .vsel_reg = LM3632_REG_VOUT_NEG,
  203. .vsel_mask = LM3632_VOUT_MASK,
  204. .enable_reg = LM3632_REG_BIAS_CONFIG,
  205. .enable_mask = LM3632_EN_VNEG_MASK,
  206. },
  207. };
  208. static int lm363x_regulator_of_get_enable_gpio(struct device_node *np, int id)
  209. {
  210. /*
  211. * Check LCM_EN1/2_GPIO is configured.
  212. * Those pins are used for enabling VPOS/VNEG LDOs.
  213. */
  214. switch (id) {
  215. case LM3632_LDO_POS:
  216. return of_get_named_gpio(np, "ti,lcm-en1-gpio", 0);
  217. case LM3632_LDO_NEG:
  218. return of_get_named_gpio(np, "ti,lcm-en2-gpio", 0);
  219. default:
  220. return -EINVAL;
  221. }
  222. }
  223. static int lm363x_regulator_probe(struct platform_device *pdev)
  224. {
  225. struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent);
  226. struct regmap *regmap = lmu->regmap;
  227. struct regulator_config cfg = { };
  228. struct regulator_dev *rdev;
  229. struct device *dev = &pdev->dev;
  230. int id = pdev->id;
  231. int ret, ena_gpio;
  232. cfg.dev = dev;
  233. cfg.regmap = regmap;
  234. /*
  235. * LM3632 LDOs can be controlled by external pin.
  236. * Register update is required if the pin is used.
  237. */
  238. ena_gpio = lm363x_regulator_of_get_enable_gpio(dev->of_node, id);
  239. if (gpio_is_valid(ena_gpio)) {
  240. cfg.ena_gpio = ena_gpio;
  241. cfg.ena_gpio_flags = GPIOF_OUT_INIT_LOW;
  242. ret = regmap_update_bits(regmap, LM3632_REG_BIAS_CONFIG,
  243. LM3632_EXT_EN_MASK,
  244. LM3632_EXT_EN_MASK);
  245. if (ret) {
  246. dev_err(dev, "External pin err: %d\n", ret);
  247. return ret;
  248. }
  249. }
  250. rdev = devm_regulator_register(dev, &lm363x_regulator_desc[id], &cfg);
  251. if (IS_ERR(rdev)) {
  252. ret = PTR_ERR(rdev);
  253. dev_err(dev, "[%d] regulator register err: %d\n", id, ret);
  254. return ret;
  255. }
  256. return 0;
  257. }
  258. static struct platform_driver lm363x_regulator_driver = {
  259. .probe = lm363x_regulator_probe,
  260. .driver = {
  261. .name = "lm363x-regulator",
  262. },
  263. };
  264. module_platform_driver(lm363x_regulator_driver);
  265. MODULE_DESCRIPTION("TI LM363X Regulator Driver");
  266. MODULE_AUTHOR("Milo Kim");
  267. MODULE_LICENSE("GPL v2");
  268. MODULE_ALIAS("platform:lm363x-regulator");