sc2731-regulator.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. //SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2017 Spreadtrum Communications Inc.
  4. */
  5. #include <linux/module.h>
  6. #include <linux/of.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/regmap.h>
  9. #include <linux/regulator/driver.h>
  10. #include <linux/regulator/of_regulator.h>
  11. /*
  12. * SC2731 regulator lock register
  13. */
  14. #define SC2731_PWR_WR_PROT 0xf0c
  15. #define SC2731_WR_UNLOCK_VALUE 0x6e7f
  16. /*
  17. * SC2731 enable register
  18. */
  19. #define SC2731_POWER_PD_SW 0xc28
  20. #define SC2731_LDO_CAMA0_PD 0xcfc
  21. #define SC2731_LDO_CAMA1_PD 0xd04
  22. #define SC2731_LDO_CAMMOT_PD 0xd0c
  23. #define SC2731_LDO_VLDO_PD 0xd6c
  24. #define SC2731_LDO_EMMCCORE_PD 0xd2c
  25. #define SC2731_LDO_SDCORE_PD 0xd74
  26. #define SC2731_LDO_SDIO_PD 0xd70
  27. #define SC2731_LDO_WIFIPA_PD 0xd4c
  28. #define SC2731_LDO_USB33_PD 0xd5c
  29. #define SC2731_LDO_CAMD0_PD 0xd7c
  30. #define SC2731_LDO_CAMD1_PD 0xd84
  31. #define SC2731_LDO_CON_PD 0xd8c
  32. #define SC2731_LDO_CAMIO_PD 0xd94
  33. #define SC2731_LDO_SRAM_PD 0xd78
  34. /*
  35. * SC2731 enable mask
  36. */
  37. #define SC2731_DCDC_CPU0_PD_MASK BIT(4)
  38. #define SC2731_DCDC_CPU1_PD_MASK BIT(3)
  39. #define SC2731_DCDC_RF_PD_MASK BIT(11)
  40. #define SC2731_LDO_CAMA0_PD_MASK BIT(0)
  41. #define SC2731_LDO_CAMA1_PD_MASK BIT(0)
  42. #define SC2731_LDO_CAMMOT_PD_MASK BIT(0)
  43. #define SC2731_LDO_VLDO_PD_MASK BIT(0)
  44. #define SC2731_LDO_EMMCCORE_PD_MASK BIT(0)
  45. #define SC2731_LDO_SDCORE_PD_MASK BIT(0)
  46. #define SC2731_LDO_SDIO_PD_MASK BIT(0)
  47. #define SC2731_LDO_WIFIPA_PD_MASK BIT(0)
  48. #define SC2731_LDO_USB33_PD_MASK BIT(0)
  49. #define SC2731_LDO_CAMD0_PD_MASK BIT(0)
  50. #define SC2731_LDO_CAMD1_PD_MASK BIT(0)
  51. #define SC2731_LDO_CON_PD_MASK BIT(0)
  52. #define SC2731_LDO_CAMIO_PD_MASK BIT(0)
  53. #define SC2731_LDO_SRAM_PD_MASK BIT(0)
  54. /*
  55. * SC2731 vsel register
  56. */
  57. #define SC2731_DCDC_CPU0_VOL 0xc54
  58. #define SC2731_DCDC_CPU1_VOL 0xc64
  59. #define SC2731_DCDC_RF_VOL 0xcb8
  60. #define SC2731_LDO_CAMA0_VOL 0xd00
  61. #define SC2731_LDO_CAMA1_VOL 0xd08
  62. #define SC2731_LDO_CAMMOT_VOL 0xd10
  63. #define SC2731_LDO_VLDO_VOL 0xd28
  64. #define SC2731_LDO_EMMCCORE_VOL 0xd30
  65. #define SC2731_LDO_SDCORE_VOL 0xd38
  66. #define SC2731_LDO_SDIO_VOL 0xd40
  67. #define SC2731_LDO_WIFIPA_VOL 0xd50
  68. #define SC2731_LDO_USB33_VOL 0xd60
  69. #define SC2731_LDO_CAMD0_VOL 0xd80
  70. #define SC2731_LDO_CAMD1_VOL 0xd88
  71. #define SC2731_LDO_CON_VOL 0xd90
  72. #define SC2731_LDO_CAMIO_VOL 0xd98
  73. #define SC2731_LDO_SRAM_VOL 0xdB0
  74. /*
  75. * SC2731 vsel register mask
  76. */
  77. #define SC2731_DCDC_CPU0_VOL_MASK GENMASK(8, 0)
  78. #define SC2731_DCDC_CPU1_VOL_MASK GENMASK(8, 0)
  79. #define SC2731_DCDC_RF_VOL_MASK GENMASK(8, 0)
  80. #define SC2731_LDO_CAMA0_VOL_MASK GENMASK(7, 0)
  81. #define SC2731_LDO_CAMA1_VOL_MASK GENMASK(7, 0)
  82. #define SC2731_LDO_CAMMOT_VOL_MASK GENMASK(7, 0)
  83. #define SC2731_LDO_VLDO_VOL_MASK GENMASK(7, 0)
  84. #define SC2731_LDO_EMMCCORE_VOL_MASK GENMASK(7, 0)
  85. #define SC2731_LDO_SDCORE_VOL_MASK GENMASK(7, 0)
  86. #define SC2731_LDO_SDIO_VOL_MASK GENMASK(7, 0)
  87. #define SC2731_LDO_WIFIPA_VOL_MASK GENMASK(7, 0)
  88. #define SC2731_LDO_USB33_VOL_MASK GENMASK(7, 0)
  89. #define SC2731_LDO_CAMD0_VOL_MASK GENMASK(6, 0)
  90. #define SC2731_LDO_CAMD1_VOL_MASK GENMASK(6, 0)
  91. #define SC2731_LDO_CON_VOL_MASK GENMASK(6, 0)
  92. #define SC2731_LDO_CAMIO_VOL_MASK GENMASK(6, 0)
  93. #define SC2731_LDO_SRAM_VOL_MASK GENMASK(6, 0)
  94. enum sc2731_regulator_id {
  95. SC2731_BUCK_CPU0,
  96. SC2731_BUCK_CPU1,
  97. SC2731_BUCK_RF,
  98. SC2731_LDO_CAMA0,
  99. SC2731_LDO_CAMA1,
  100. SC2731_LDO_CAMMOT,
  101. SC2731_LDO_VLDO,
  102. SC2731_LDO_EMMCCORE,
  103. SC2731_LDO_SDCORE,
  104. SC2731_LDO_SDIO,
  105. SC2731_LDO_WIFIPA,
  106. SC2731_LDO_USB33,
  107. SC2731_LDO_CAMD0,
  108. SC2731_LDO_CAMD1,
  109. SC2731_LDO_CON,
  110. SC2731_LDO_CAMIO,
  111. SC2731_LDO_SRAM,
  112. };
  113. static const struct regulator_ops sc2731_regu_linear_ops = {
  114. .enable = regulator_enable_regmap,
  115. .disable = regulator_disable_regmap,
  116. .is_enabled = regulator_is_enabled_regmap,
  117. .list_voltage = regulator_list_voltage_linear,
  118. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  119. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  120. };
  121. #define SC2731_REGU_LINEAR(_id, en_reg, en_mask, vreg, vmask, \
  122. vstep, vmin, vmax) { \
  123. .name = #_id, \
  124. .of_match = of_match_ptr(#_id), \
  125. .ops = &sc2731_regu_linear_ops, \
  126. .type = REGULATOR_VOLTAGE, \
  127. .id = SC2731_##_id, \
  128. .owner = THIS_MODULE, \
  129. .min_uV = vmin, \
  130. .n_voltages = ((vmax) - (vmin)) / (vstep) + 1, \
  131. .uV_step = vstep, \
  132. .enable_is_inverted = true, \
  133. .enable_val = 0, \
  134. .enable_reg = en_reg, \
  135. .enable_mask = en_mask, \
  136. .vsel_reg = vreg, \
  137. .vsel_mask = vmask, \
  138. }
  139. static const struct regulator_desc regulators[] = {
  140. SC2731_REGU_LINEAR(BUCK_CPU0, SC2731_POWER_PD_SW,
  141. SC2731_DCDC_CPU0_PD_MASK, SC2731_DCDC_CPU0_VOL,
  142. SC2731_DCDC_CPU0_VOL_MASK, 3125, 400000, 1996875),
  143. SC2731_REGU_LINEAR(BUCK_CPU1, SC2731_POWER_PD_SW,
  144. SC2731_DCDC_CPU1_PD_MASK, SC2731_DCDC_CPU1_VOL,
  145. SC2731_DCDC_CPU1_VOL_MASK, 3125, 400000, 1996875),
  146. SC2731_REGU_LINEAR(BUCK_RF, SC2731_POWER_PD_SW, SC2731_DCDC_RF_PD_MASK,
  147. SC2731_DCDC_RF_VOL, SC2731_DCDC_RF_VOL_MASK,
  148. 3125, 600000, 2196875),
  149. SC2731_REGU_LINEAR(LDO_CAMA0, SC2731_LDO_CAMA0_PD,
  150. SC2731_LDO_CAMA0_PD_MASK, SC2731_LDO_CAMA0_VOL,
  151. SC2731_LDO_CAMA0_VOL_MASK, 10000, 1200000, 3750000),
  152. SC2731_REGU_LINEAR(LDO_CAMA1, SC2731_LDO_CAMA1_PD,
  153. SC2731_LDO_CAMA1_PD_MASK, SC2731_LDO_CAMA1_VOL,
  154. SC2731_LDO_CAMA1_VOL_MASK, 10000, 1200000, 3750000),
  155. SC2731_REGU_LINEAR(LDO_CAMMOT, SC2731_LDO_CAMMOT_PD,
  156. SC2731_LDO_CAMMOT_PD_MASK, SC2731_LDO_CAMMOT_VOL,
  157. SC2731_LDO_CAMMOT_VOL_MASK, 10000, 1200000, 3750000),
  158. SC2731_REGU_LINEAR(LDO_VLDO, SC2731_LDO_VLDO_PD,
  159. SC2731_LDO_VLDO_PD_MASK, SC2731_LDO_VLDO_VOL,
  160. SC2731_LDO_VLDO_VOL_MASK, 10000, 1200000, 3750000),
  161. SC2731_REGU_LINEAR(LDO_EMMCCORE, SC2731_LDO_EMMCCORE_PD,
  162. SC2731_LDO_EMMCCORE_PD_MASK, SC2731_LDO_EMMCCORE_VOL,
  163. SC2731_LDO_EMMCCORE_VOL_MASK, 10000, 1200000,
  164. 3750000),
  165. SC2731_REGU_LINEAR(LDO_SDCORE, SC2731_LDO_SDCORE_PD,
  166. SC2731_LDO_SDCORE_PD_MASK, SC2731_LDO_SDCORE_VOL,
  167. SC2731_LDO_SDCORE_VOL_MASK, 10000, 1200000, 3750000),
  168. SC2731_REGU_LINEAR(LDO_SDIO, SC2731_LDO_SDIO_PD,
  169. SC2731_LDO_SDIO_PD_MASK, SC2731_LDO_SDIO_VOL,
  170. SC2731_LDO_SDIO_VOL_MASK, 10000, 1200000, 3750000),
  171. SC2731_REGU_LINEAR(LDO_WIFIPA, SC2731_LDO_WIFIPA_PD,
  172. SC2731_LDO_WIFIPA_PD_MASK, SC2731_LDO_WIFIPA_VOL,
  173. SC2731_LDO_WIFIPA_VOL_MASK, 10000, 1200000, 3750000),
  174. SC2731_REGU_LINEAR(LDO_USB33, SC2731_LDO_USB33_PD,
  175. SC2731_LDO_USB33_PD_MASK, SC2731_LDO_USB33_VOL,
  176. SC2731_LDO_USB33_VOL_MASK, 10000, 1200000, 3750000),
  177. SC2731_REGU_LINEAR(LDO_CAMD0, SC2731_LDO_CAMD0_PD,
  178. SC2731_LDO_CAMD0_PD_MASK, SC2731_LDO_CAMD0_VOL,
  179. SC2731_LDO_CAMD0_VOL_MASK, 6250, 1000000, 1793750),
  180. SC2731_REGU_LINEAR(LDO_CAMD1, SC2731_LDO_CAMD1_PD,
  181. SC2731_LDO_CAMD1_PD_MASK, SC2731_LDO_CAMD1_VOL,
  182. SC2731_LDO_CAMD1_VOL_MASK, 6250, 1000000, 1793750),
  183. SC2731_REGU_LINEAR(LDO_CON, SC2731_LDO_CON_PD,
  184. SC2731_LDO_CON_PD_MASK, SC2731_LDO_CON_VOL,
  185. SC2731_LDO_CON_VOL_MASK, 6250, 1000000, 1793750),
  186. SC2731_REGU_LINEAR(LDO_CAMIO, SC2731_LDO_CAMIO_PD,
  187. SC2731_LDO_CAMIO_PD_MASK, SC2731_LDO_CAMIO_VOL,
  188. SC2731_LDO_CAMIO_VOL_MASK, 6250, 1000000, 1793750),
  189. SC2731_REGU_LINEAR(LDO_SRAM, SC2731_LDO_SRAM_PD,
  190. SC2731_LDO_SRAM_PD_MASK, SC2731_LDO_SRAM_VOL,
  191. SC2731_LDO_SRAM_VOL_MASK, 6250, 1000000, 1793750),
  192. };
  193. static int sc2731_regulator_unlock(struct regmap *regmap)
  194. {
  195. return regmap_write(regmap, SC2731_PWR_WR_PROT,
  196. SC2731_WR_UNLOCK_VALUE);
  197. }
  198. static int sc2731_regulator_probe(struct platform_device *pdev)
  199. {
  200. int i, ret;
  201. struct regmap *regmap;
  202. struct regulator_config config = { };
  203. struct regulator_dev *rdev;
  204. regmap = dev_get_regmap(pdev->dev.parent, NULL);
  205. if (!regmap) {
  206. dev_err(&pdev->dev, "failed to get regmap.\n");
  207. return -ENODEV;
  208. }
  209. ret = sc2731_regulator_unlock(regmap);
  210. if (ret) {
  211. dev_err(&pdev->dev, "failed to release regulator lock\n");
  212. return ret;
  213. }
  214. config.dev = &pdev->dev;
  215. config.regmap = regmap;
  216. for (i = 0; i < ARRAY_SIZE(regulators); i++) {
  217. rdev = devm_regulator_register(&pdev->dev, &regulators[i],
  218. &config);
  219. if (IS_ERR(rdev)) {
  220. dev_err(&pdev->dev, "failed to register regulator %s\n",
  221. regulators[i].name);
  222. return PTR_ERR(rdev);
  223. }
  224. }
  225. return 0;
  226. }
  227. static struct platform_driver sc2731_regulator_driver = {
  228. .driver = {
  229. .name = "sc27xx-regulator",
  230. },
  231. .probe = sc2731_regulator_probe,
  232. };
  233. module_platform_driver(sc2731_regulator_driver);
  234. MODULE_AUTHOR("Chen Junhui <erick.chen@spreadtrum.com>");
  235. MODULE_DESCRIPTION("Spreadtrum SC2731 regulator driver");
  236. MODULE_LICENSE("GPL v2");