bd70528-regulator.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2018 ROHM Semiconductors
  3. // bd70528-regulator.c ROHM BD70528MWV regulator driver
  4. #include <linux/delay.h>
  5. #include <linux/err.h>
  6. #include <linux/interrupt.h>
  7. #include <linux/kernel.h>
  8. #include <linux/mfd/rohm-bd70528.h>
  9. #include <linux/module.h>
  10. #include <linux/of.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/regmap.h>
  13. #include <linux/regulator/driver.h>
  14. #include <linux/regulator/machine.h>
  15. #include <linux/regulator/of_regulator.h>
  16. #include <linux/slab.h>
  17. #define BUCK_RAMPRATE_250MV 0
  18. #define BUCK_RAMPRATE_125MV 1
  19. #define BUCK_RAMP_MAX 250
  20. static const struct linear_range bd70528_buck1_volts[] = {
  21. REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 600000),
  22. REGULATOR_LINEAR_RANGE(2750000, 0x2, 0xf, 50000),
  23. };
  24. static const struct linear_range bd70528_buck2_volts[] = {
  25. REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 300000),
  26. REGULATOR_LINEAR_RANGE(1550000, 0x2, 0xd, 50000),
  27. REGULATOR_LINEAR_RANGE(3000000, 0xe, 0xf, 300000),
  28. };
  29. static const struct linear_range bd70528_buck3_volts[] = {
  30. REGULATOR_LINEAR_RANGE(800000, 0x00, 0xd, 50000),
  31. REGULATOR_LINEAR_RANGE(1800000, 0xe, 0xf, 0),
  32. };
  33. /* All LDOs have same voltage ranges */
  34. static const struct linear_range bd70528_ldo_volts[] = {
  35. REGULATOR_LINEAR_RANGE(1650000, 0x0, 0x07, 50000),
  36. REGULATOR_LINEAR_RANGE(2100000, 0x8, 0x0f, 100000),
  37. REGULATOR_LINEAR_RANGE(2850000, 0x10, 0x19, 50000),
  38. REGULATOR_LINEAR_RANGE(3300000, 0x19, 0x1f, 0),
  39. };
  40. /* Also both LEDs support same voltages */
  41. static const unsigned int led_volts[] = {
  42. 20000, 30000
  43. };
  44. static int bd70528_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
  45. {
  46. if (ramp_delay > 0 && ramp_delay <= BUCK_RAMP_MAX) {
  47. unsigned int ramp_value = BUCK_RAMPRATE_250MV;
  48. if (ramp_delay <= 125)
  49. ramp_value = BUCK_RAMPRATE_125MV;
  50. return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
  51. BD70528_MASK_BUCK_RAMP,
  52. ramp_value << BD70528_SIFT_BUCK_RAMP);
  53. }
  54. dev_err(&rdev->dev, "%s: ramp_delay: %d not supported\n",
  55. rdev->desc->name, ramp_delay);
  56. return -EINVAL;
  57. }
  58. static int bd70528_led_set_voltage_sel(struct regulator_dev *rdev,
  59. unsigned int sel)
  60. {
  61. int ret;
  62. ret = regulator_is_enabled_regmap(rdev);
  63. if (ret < 0)
  64. return ret;
  65. if (ret == 0)
  66. return regulator_set_voltage_sel_regmap(rdev, sel);
  67. dev_err(&rdev->dev,
  68. "LED voltage change not allowed when led is enabled\n");
  69. return -EBUSY;
  70. }
  71. static const struct regulator_ops bd70528_buck_ops = {
  72. .enable = regulator_enable_regmap,
  73. .disable = regulator_disable_regmap,
  74. .is_enabled = regulator_is_enabled_regmap,
  75. .list_voltage = regulator_list_voltage_linear_range,
  76. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  77. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  78. .set_voltage_time_sel = regulator_set_voltage_time_sel,
  79. .set_ramp_delay = bd70528_set_ramp_delay,
  80. };
  81. static const struct regulator_ops bd70528_ldo_ops = {
  82. .enable = regulator_enable_regmap,
  83. .disable = regulator_disable_regmap,
  84. .is_enabled = regulator_is_enabled_regmap,
  85. .list_voltage = regulator_list_voltage_linear_range,
  86. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  87. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  88. .set_voltage_time_sel = regulator_set_voltage_time_sel,
  89. };
  90. static const struct regulator_ops bd70528_led_ops = {
  91. .enable = regulator_enable_regmap,
  92. .disable = regulator_disable_regmap,
  93. .is_enabled = regulator_is_enabled_regmap,
  94. .list_voltage = regulator_list_voltage_table,
  95. .set_voltage_sel = bd70528_led_set_voltage_sel,
  96. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  97. };
  98. static const struct regulator_desc bd70528_desc[] = {
  99. {
  100. .name = "buck1",
  101. .of_match = of_match_ptr("BUCK1"),
  102. .regulators_node = of_match_ptr("regulators"),
  103. .id = BD70528_BUCK1,
  104. .ops = &bd70528_buck_ops,
  105. .type = REGULATOR_VOLTAGE,
  106. .linear_ranges = bd70528_buck1_volts,
  107. .n_linear_ranges = ARRAY_SIZE(bd70528_buck1_volts),
  108. .n_voltages = BD70528_BUCK_VOLTS,
  109. .enable_reg = BD70528_REG_BUCK1_EN,
  110. .enable_mask = BD70528_MASK_RUN_EN,
  111. .vsel_reg = BD70528_REG_BUCK1_VOLT,
  112. .vsel_mask = BD70528_MASK_BUCK_VOLT,
  113. .owner = THIS_MODULE,
  114. },
  115. {
  116. .name = "buck2",
  117. .of_match = of_match_ptr("BUCK2"),
  118. .regulators_node = of_match_ptr("regulators"),
  119. .id = BD70528_BUCK2,
  120. .ops = &bd70528_buck_ops,
  121. .type = REGULATOR_VOLTAGE,
  122. .linear_ranges = bd70528_buck2_volts,
  123. .n_linear_ranges = ARRAY_SIZE(bd70528_buck2_volts),
  124. .n_voltages = BD70528_BUCK_VOLTS,
  125. .enable_reg = BD70528_REG_BUCK2_EN,
  126. .enable_mask = BD70528_MASK_RUN_EN,
  127. .vsel_reg = BD70528_REG_BUCK2_VOLT,
  128. .vsel_mask = BD70528_MASK_BUCK_VOLT,
  129. .owner = THIS_MODULE,
  130. },
  131. {
  132. .name = "buck3",
  133. .of_match = of_match_ptr("BUCK3"),
  134. .regulators_node = of_match_ptr("regulators"),
  135. .id = BD70528_BUCK3,
  136. .ops = &bd70528_buck_ops,
  137. .type = REGULATOR_VOLTAGE,
  138. .linear_ranges = bd70528_buck3_volts,
  139. .n_linear_ranges = ARRAY_SIZE(bd70528_buck3_volts),
  140. .n_voltages = BD70528_BUCK_VOLTS,
  141. .enable_reg = BD70528_REG_BUCK3_EN,
  142. .enable_mask = BD70528_MASK_RUN_EN,
  143. .vsel_reg = BD70528_REG_BUCK3_VOLT,
  144. .vsel_mask = BD70528_MASK_BUCK_VOLT,
  145. .owner = THIS_MODULE,
  146. },
  147. {
  148. .name = "ldo1",
  149. .of_match = of_match_ptr("LDO1"),
  150. .regulators_node = of_match_ptr("regulators"),
  151. .id = BD70528_LDO1,
  152. .ops = &bd70528_ldo_ops,
  153. .type = REGULATOR_VOLTAGE,
  154. .linear_ranges = bd70528_ldo_volts,
  155. .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
  156. .n_voltages = BD70528_LDO_VOLTS,
  157. .enable_reg = BD70528_REG_LDO1_EN,
  158. .enable_mask = BD70528_MASK_RUN_EN,
  159. .vsel_reg = BD70528_REG_LDO1_VOLT,
  160. .vsel_mask = BD70528_MASK_LDO_VOLT,
  161. .owner = THIS_MODULE,
  162. },
  163. {
  164. .name = "ldo2",
  165. .of_match = of_match_ptr("LDO2"),
  166. .regulators_node = of_match_ptr("regulators"),
  167. .id = BD70528_LDO2,
  168. .ops = &bd70528_ldo_ops,
  169. .type = REGULATOR_VOLTAGE,
  170. .linear_ranges = bd70528_ldo_volts,
  171. .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
  172. .n_voltages = BD70528_LDO_VOLTS,
  173. .enable_reg = BD70528_REG_LDO2_EN,
  174. .enable_mask = BD70528_MASK_RUN_EN,
  175. .vsel_reg = BD70528_REG_LDO2_VOLT,
  176. .vsel_mask = BD70528_MASK_LDO_VOLT,
  177. .owner = THIS_MODULE,
  178. },
  179. {
  180. .name = "ldo3",
  181. .of_match = of_match_ptr("LDO3"),
  182. .regulators_node = of_match_ptr("regulators"),
  183. .id = BD70528_LDO3,
  184. .ops = &bd70528_ldo_ops,
  185. .type = REGULATOR_VOLTAGE,
  186. .linear_ranges = bd70528_ldo_volts,
  187. .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
  188. .n_voltages = BD70528_LDO_VOLTS,
  189. .enable_reg = BD70528_REG_LDO3_EN,
  190. .enable_mask = BD70528_MASK_RUN_EN,
  191. .vsel_reg = BD70528_REG_LDO3_VOLT,
  192. .vsel_mask = BD70528_MASK_LDO_VOLT,
  193. .owner = THIS_MODULE,
  194. },
  195. {
  196. .name = "ldo_led1",
  197. .of_match = of_match_ptr("LDO_LED1"),
  198. .regulators_node = of_match_ptr("regulators"),
  199. .id = BD70528_LED1,
  200. .ops = &bd70528_led_ops,
  201. .type = REGULATOR_VOLTAGE,
  202. .volt_table = &led_volts[0],
  203. .n_voltages = ARRAY_SIZE(led_volts),
  204. .enable_reg = BD70528_REG_LED_EN,
  205. .enable_mask = BD70528_MASK_LED1_EN,
  206. .vsel_reg = BD70528_REG_LED_VOLT,
  207. .vsel_mask = BD70528_MASK_LED1_VOLT,
  208. .owner = THIS_MODULE,
  209. },
  210. {
  211. .name = "ldo_led2",
  212. .of_match = of_match_ptr("LDO_LED2"),
  213. .regulators_node = of_match_ptr("regulators"),
  214. .id = BD70528_LED2,
  215. .ops = &bd70528_led_ops,
  216. .type = REGULATOR_VOLTAGE,
  217. .volt_table = &led_volts[0],
  218. .n_voltages = ARRAY_SIZE(led_volts),
  219. .enable_reg = BD70528_REG_LED_EN,
  220. .enable_mask = BD70528_MASK_LED2_EN,
  221. .vsel_reg = BD70528_REG_LED_VOLT,
  222. .vsel_mask = BD70528_MASK_LED2_VOLT,
  223. .owner = THIS_MODULE,
  224. },
  225. };
  226. static int bd70528_probe(struct platform_device *pdev)
  227. {
  228. struct rohm_regmap_dev *bd70528;
  229. int i;
  230. struct regulator_config config = {
  231. .dev = pdev->dev.parent,
  232. };
  233. bd70528 = dev_get_drvdata(pdev->dev.parent);
  234. if (!bd70528) {
  235. dev_err(&pdev->dev, "No MFD driver data\n");
  236. return -EINVAL;
  237. }
  238. config.regmap = bd70528->regmap;
  239. for (i = 0; i < ARRAY_SIZE(bd70528_desc); i++) {
  240. struct regulator_dev *rdev;
  241. rdev = devm_regulator_register(&pdev->dev, &bd70528_desc[i],
  242. &config);
  243. if (IS_ERR(rdev)) {
  244. dev_err(&pdev->dev,
  245. "failed to register %s regulator\n",
  246. bd70528_desc[i].name);
  247. return PTR_ERR(rdev);
  248. }
  249. }
  250. return 0;
  251. }
  252. static struct platform_driver bd70528_regulator = {
  253. .driver = {
  254. .name = "bd70528-pmic"
  255. },
  256. .probe = bd70528_probe,
  257. };
  258. module_platform_driver(bd70528_regulator);
  259. MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
  260. MODULE_DESCRIPTION("BD70528 voltage regulator driver");
  261. MODULE_LICENSE("GPL");
  262. MODULE_ALIAS("platform:bd70528-pmic");