s2mpa01.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. // SPDX-License-Identifier: GPL-2.0+
  2. //
  3. // Copyright (c) 2013 Samsung Electronics Co., Ltd
  4. // http://www.samsung.com
  5. #include <linux/bug.h>
  6. #include <linux/err.h>
  7. #include <linux/gpio.h>
  8. #include <linux/slab.h>
  9. #include <linux/module.h>
  10. #include <linux/of.h>
  11. #include <linux/regmap.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/regulator/driver.h>
  14. #include <linux/regulator/machine.h>
  15. #include <linux/regulator/of_regulator.h>
  16. #include <linux/mfd/samsung/core.h>
  17. #include <linux/mfd/samsung/s2mpa01.h>
  18. struct s2mpa01_info {
  19. int ramp_delay24;
  20. int ramp_delay3;
  21. int ramp_delay5;
  22. int ramp_delay16;
  23. int ramp_delay7;
  24. int ramp_delay8910;
  25. };
  26. static int get_ramp_delay(int ramp_delay)
  27. {
  28. unsigned char cnt = 0;
  29. ramp_delay /= 6250;
  30. while (true) {
  31. ramp_delay = ramp_delay >> 1;
  32. if (ramp_delay == 0)
  33. break;
  34. cnt++;
  35. }
  36. if (cnt > 3)
  37. cnt = 3;
  38. return cnt;
  39. }
  40. static int s2mpa01_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
  41. unsigned int old_selector,
  42. unsigned int new_selector)
  43. {
  44. struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev);
  45. unsigned int ramp_delay = 0;
  46. int old_volt, new_volt;
  47. switch (rdev_get_id(rdev)) {
  48. case S2MPA01_BUCK2:
  49. case S2MPA01_BUCK4:
  50. ramp_delay = s2mpa01->ramp_delay24;
  51. break;
  52. case S2MPA01_BUCK3:
  53. ramp_delay = s2mpa01->ramp_delay3;
  54. break;
  55. case S2MPA01_BUCK5:
  56. ramp_delay = s2mpa01->ramp_delay5;
  57. break;
  58. case S2MPA01_BUCK1:
  59. case S2MPA01_BUCK6:
  60. ramp_delay = s2mpa01->ramp_delay16;
  61. break;
  62. case S2MPA01_BUCK7:
  63. ramp_delay = s2mpa01->ramp_delay7;
  64. break;
  65. case S2MPA01_BUCK8:
  66. case S2MPA01_BUCK9:
  67. case S2MPA01_BUCK10:
  68. ramp_delay = s2mpa01->ramp_delay8910;
  69. break;
  70. }
  71. if (ramp_delay == 0)
  72. ramp_delay = rdev->desc->ramp_delay;
  73. old_volt = rdev->desc->min_uV + (rdev->desc->uV_step * old_selector);
  74. new_volt = rdev->desc->min_uV + (rdev->desc->uV_step * new_selector);
  75. return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay);
  76. }
  77. static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
  78. {
  79. struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev);
  80. unsigned int ramp_val, ramp_shift, ramp_reg = S2MPA01_REG_RAMP2;
  81. unsigned int ramp_enable = 1, enable_shift = 0;
  82. int ret;
  83. switch (rdev_get_id(rdev)) {
  84. case S2MPA01_BUCK1:
  85. enable_shift = S2MPA01_BUCK1_RAMP_EN_SHIFT;
  86. if (!ramp_delay) {
  87. ramp_enable = 0;
  88. break;
  89. }
  90. if (ramp_delay > s2mpa01->ramp_delay16)
  91. s2mpa01->ramp_delay16 = ramp_delay;
  92. else
  93. ramp_delay = s2mpa01->ramp_delay16;
  94. ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;
  95. break;
  96. case S2MPA01_BUCK2:
  97. enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT;
  98. if (!ramp_delay) {
  99. ramp_enable = 0;
  100. break;
  101. }
  102. if (ramp_delay > s2mpa01->ramp_delay24)
  103. s2mpa01->ramp_delay24 = ramp_delay;
  104. else
  105. ramp_delay = s2mpa01->ramp_delay24;
  106. ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT;
  107. ramp_reg = S2MPA01_REG_RAMP1;
  108. break;
  109. case S2MPA01_BUCK3:
  110. enable_shift = S2MPA01_BUCK3_RAMP_EN_SHIFT;
  111. if (!ramp_delay) {
  112. ramp_enable = 0;
  113. break;
  114. }
  115. s2mpa01->ramp_delay3 = ramp_delay;
  116. ramp_shift = S2MPA01_BUCK3_RAMP_SHIFT;
  117. ramp_reg = S2MPA01_REG_RAMP1;
  118. break;
  119. case S2MPA01_BUCK4:
  120. enable_shift = S2MPA01_BUCK4_RAMP_EN_SHIFT;
  121. if (!ramp_delay) {
  122. ramp_enable = 0;
  123. break;
  124. }
  125. if (ramp_delay > s2mpa01->ramp_delay24)
  126. s2mpa01->ramp_delay24 = ramp_delay;
  127. else
  128. ramp_delay = s2mpa01->ramp_delay24;
  129. ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT;
  130. ramp_reg = S2MPA01_REG_RAMP1;
  131. break;
  132. case S2MPA01_BUCK5:
  133. s2mpa01->ramp_delay5 = ramp_delay;
  134. ramp_shift = S2MPA01_BUCK5_RAMP_SHIFT;
  135. break;
  136. case S2MPA01_BUCK6:
  137. if (ramp_delay > s2mpa01->ramp_delay16)
  138. s2mpa01->ramp_delay16 = ramp_delay;
  139. else
  140. ramp_delay = s2mpa01->ramp_delay16;
  141. ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;
  142. break;
  143. case S2MPA01_BUCK7:
  144. s2mpa01->ramp_delay7 = ramp_delay;
  145. ramp_shift = S2MPA01_BUCK7_RAMP_SHIFT;
  146. break;
  147. case S2MPA01_BUCK8:
  148. case S2MPA01_BUCK9:
  149. case S2MPA01_BUCK10:
  150. if (ramp_delay > s2mpa01->ramp_delay8910)
  151. s2mpa01->ramp_delay8910 = ramp_delay;
  152. else
  153. ramp_delay = s2mpa01->ramp_delay8910;
  154. ramp_shift = S2MPA01_BUCK8910_RAMP_SHIFT;
  155. break;
  156. default:
  157. return 0;
  158. }
  159. if (!ramp_enable)
  160. goto ramp_disable;
  161. /* Ramp delay can be enabled/disabled only for buck[1234] */
  162. if (rdev_get_id(rdev) >= S2MPA01_BUCK1 &&
  163. rdev_get_id(rdev) <= S2MPA01_BUCK4) {
  164. ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,
  165. 1 << enable_shift, 1 << enable_shift);
  166. if (ret) {
  167. dev_err(&rdev->dev, "failed to enable ramp rate\n");
  168. return ret;
  169. }
  170. }
  171. ramp_val = get_ramp_delay(ramp_delay);
  172. return regmap_update_bits(rdev->regmap, ramp_reg, 0x3 << ramp_shift,
  173. ramp_val << ramp_shift);
  174. ramp_disable:
  175. return regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,
  176. 1 << enable_shift, 0);
  177. }
  178. static const struct regulator_ops s2mpa01_ldo_ops = {
  179. .list_voltage = regulator_list_voltage_linear,
  180. .map_voltage = regulator_map_voltage_linear,
  181. .is_enabled = regulator_is_enabled_regmap,
  182. .enable = regulator_enable_regmap,
  183. .disable = regulator_disable_regmap,
  184. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  185. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  186. .set_voltage_time_sel = regulator_set_voltage_time_sel,
  187. };
  188. static const struct regulator_ops s2mpa01_buck_ops = {
  189. .list_voltage = regulator_list_voltage_linear,
  190. .map_voltage = regulator_map_voltage_linear,
  191. .is_enabled = regulator_is_enabled_regmap,
  192. .enable = regulator_enable_regmap,
  193. .disable = regulator_disable_regmap,
  194. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  195. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  196. .set_voltage_time_sel = s2mpa01_regulator_set_voltage_time_sel,
  197. .set_ramp_delay = s2mpa01_set_ramp_delay,
  198. };
  199. #define regulator_desc_ldo(num, step) { \
  200. .name = "LDO"#num, \
  201. .of_match = of_match_ptr("LDO"#num), \
  202. .regulators_node = of_match_ptr("regulators"), \
  203. .id = S2MPA01_LDO##num, \
  204. .ops = &s2mpa01_ldo_ops, \
  205. .type = REGULATOR_VOLTAGE, \
  206. .owner = THIS_MODULE, \
  207. .min_uV = MIN_800_MV, \
  208. .uV_step = step, \
  209. .n_voltages = S2MPA01_LDO_N_VOLTAGES, \
  210. .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \
  211. .vsel_mask = S2MPA01_LDO_VSEL_MASK, \
  212. .enable_reg = S2MPA01_REG_L1CTRL + num - 1, \
  213. .enable_mask = S2MPA01_ENABLE_MASK \
  214. }
  215. #define regulator_desc_buck1_4(num) { \
  216. .name = "BUCK"#num, \
  217. .of_match = of_match_ptr("BUCK"#num), \
  218. .regulators_node = of_match_ptr("regulators"), \
  219. .id = S2MPA01_BUCK##num, \
  220. .ops = &s2mpa01_buck_ops, \
  221. .type = REGULATOR_VOLTAGE, \
  222. .owner = THIS_MODULE, \
  223. .min_uV = MIN_600_MV, \
  224. .uV_step = STEP_6_25_MV, \
  225. .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \
  226. .ramp_delay = S2MPA01_RAMP_DELAY, \
  227. .vsel_reg = S2MPA01_REG_B1CTRL2 + (num - 1) * 2, \
  228. .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \
  229. .enable_reg = S2MPA01_REG_B1CTRL1 + (num - 1) * 2, \
  230. .enable_mask = S2MPA01_ENABLE_MASK \
  231. }
  232. #define regulator_desc_buck5 { \
  233. .name = "BUCK5", \
  234. .of_match = of_match_ptr("BUCK5"), \
  235. .regulators_node = of_match_ptr("regulators"), \
  236. .id = S2MPA01_BUCK5, \
  237. .ops = &s2mpa01_buck_ops, \
  238. .type = REGULATOR_VOLTAGE, \
  239. .owner = THIS_MODULE, \
  240. .min_uV = MIN_800_MV, \
  241. .uV_step = STEP_6_25_MV, \
  242. .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \
  243. .ramp_delay = S2MPA01_RAMP_DELAY, \
  244. .vsel_reg = S2MPA01_REG_B5CTRL2, \
  245. .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \
  246. .enable_reg = S2MPA01_REG_B5CTRL1, \
  247. .enable_mask = S2MPA01_ENABLE_MASK \
  248. }
  249. #define regulator_desc_buck6_10(num, min, step) { \
  250. .name = "BUCK"#num, \
  251. .of_match = of_match_ptr("BUCK"#num), \
  252. .regulators_node = of_match_ptr("regulators"), \
  253. .id = S2MPA01_BUCK##num, \
  254. .ops = &s2mpa01_buck_ops, \
  255. .type = REGULATOR_VOLTAGE, \
  256. .owner = THIS_MODULE, \
  257. .min_uV = min, \
  258. .uV_step = step, \
  259. .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \
  260. .ramp_delay = S2MPA01_RAMP_DELAY, \
  261. .vsel_reg = S2MPA01_REG_B6CTRL2 + (num - 6) * 2, \
  262. .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \
  263. .enable_reg = S2MPA01_REG_B6CTRL1 + (num - 6) * 2, \
  264. .enable_mask = S2MPA01_ENABLE_MASK \
  265. }
  266. static const struct regulator_desc regulators[] = {
  267. regulator_desc_ldo(1, STEP_25_MV),
  268. regulator_desc_ldo(2, STEP_50_MV),
  269. regulator_desc_ldo(3, STEP_50_MV),
  270. regulator_desc_ldo(4, STEP_50_MV),
  271. regulator_desc_ldo(5, STEP_25_MV),
  272. regulator_desc_ldo(6, STEP_25_MV),
  273. regulator_desc_ldo(7, STEP_50_MV),
  274. regulator_desc_ldo(8, STEP_50_MV),
  275. regulator_desc_ldo(9, STEP_50_MV),
  276. regulator_desc_ldo(10, STEP_50_MV),
  277. regulator_desc_ldo(11, STEP_50_MV),
  278. regulator_desc_ldo(12, STEP_50_MV),
  279. regulator_desc_ldo(13, STEP_50_MV),
  280. regulator_desc_ldo(14, STEP_50_MV),
  281. regulator_desc_ldo(15, STEP_50_MV),
  282. regulator_desc_ldo(16, STEP_50_MV),
  283. regulator_desc_ldo(17, STEP_50_MV),
  284. regulator_desc_ldo(18, STEP_50_MV),
  285. regulator_desc_ldo(19, STEP_50_MV),
  286. regulator_desc_ldo(20, STEP_50_MV),
  287. regulator_desc_ldo(21, STEP_50_MV),
  288. regulator_desc_ldo(22, STEP_50_MV),
  289. regulator_desc_ldo(23, STEP_50_MV),
  290. regulator_desc_ldo(24, STEP_50_MV),
  291. regulator_desc_ldo(25, STEP_50_MV),
  292. regulator_desc_ldo(26, STEP_25_MV),
  293. regulator_desc_buck1_4(1),
  294. regulator_desc_buck1_4(2),
  295. regulator_desc_buck1_4(3),
  296. regulator_desc_buck1_4(4),
  297. regulator_desc_buck5,
  298. regulator_desc_buck6_10(6, MIN_600_MV, STEP_6_25_MV),
  299. regulator_desc_buck6_10(7, MIN_600_MV, STEP_6_25_MV),
  300. regulator_desc_buck6_10(8, MIN_800_MV, STEP_12_5_MV),
  301. regulator_desc_buck6_10(9, MIN_1500_MV, STEP_12_5_MV),
  302. regulator_desc_buck6_10(10, MIN_1000_MV, STEP_12_5_MV),
  303. };
  304. static int s2mpa01_pmic_probe(struct platform_device *pdev)
  305. {
  306. struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
  307. struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
  308. struct regulator_config config = { };
  309. struct s2mpa01_info *s2mpa01;
  310. int i;
  311. s2mpa01 = devm_kzalloc(&pdev->dev, sizeof(*s2mpa01), GFP_KERNEL);
  312. if (!s2mpa01)
  313. return -ENOMEM;
  314. config.dev = iodev->dev;
  315. config.regmap = iodev->regmap_pmic;
  316. config.driver_data = s2mpa01;
  317. for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) {
  318. struct regulator_dev *rdev;
  319. if (pdata)
  320. config.init_data = pdata->regulators[i].initdata;
  321. rdev = devm_regulator_register(&pdev->dev,
  322. &regulators[i], &config);
  323. if (IS_ERR(rdev)) {
  324. dev_err(&pdev->dev, "regulator init failed for %d\n",
  325. i);
  326. return PTR_ERR(rdev);
  327. }
  328. }
  329. return 0;
  330. }
  331. static const struct platform_device_id s2mpa01_pmic_id[] = {
  332. { "s2mpa01-pmic", 0},
  333. { },
  334. };
  335. MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id);
  336. static struct platform_driver s2mpa01_pmic_driver = {
  337. .driver = {
  338. .name = "s2mpa01-pmic",
  339. },
  340. .probe = s2mpa01_pmic_probe,
  341. .id_table = s2mpa01_pmic_id,
  342. };
  343. module_platform_driver(s2mpa01_pmic_driver);
  344. /* Module information */
  345. MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
  346. MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>");
  347. MODULE_DESCRIPTION("SAMSUNG S2MPA01 Regulator Driver");
  348. MODULE_LICENSE("GPL");