bd71837-regulator.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2018 ROHM Semiconductors
  3. // bd71837-regulator.c ROHM BD71837MWV regulator driver
  4. #include <linux/delay.h>
  5. #include <linux/err.h>
  6. #include <linux/gpio.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/kernel.h>
  9. #include <linux/mfd/rohm-bd718x7.h>
  10. #include <linux/module.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/regulator/driver.h>
  13. #include <linux/regulator/machine.h>
  14. #include <linux/regulator/of_regulator.h>
  15. #include <linux/slab.h>
  16. struct bd71837_pmic {
  17. struct regulator_desc descs[BD71837_REGULATOR_CNT];
  18. struct bd71837 *mfd;
  19. struct platform_device *pdev;
  20. struct regulator_dev *rdev[BD71837_REGULATOR_CNT];
  21. };
  22. /*
  23. * BUCK1/2/3/4
  24. * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting
  25. * 00: 10.00mV/usec 10mV 1uS
  26. * 01: 5.00mV/usec 10mV 2uS
  27. * 10: 2.50mV/usec 10mV 4uS
  28. * 11: 1.25mV/usec 10mV 8uS
  29. */
  30. static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
  31. int ramp_delay)
  32. {
  33. struct bd71837_pmic *pmic = rdev_get_drvdata(rdev);
  34. struct bd71837 *mfd = pmic->mfd;
  35. int id = rdev->desc->id;
  36. unsigned int ramp_value = BUCK_RAMPRATE_10P00MV;
  37. dev_dbg(&pmic->pdev->dev, "Buck[%d] Set Ramp = %d\n", id + 1,
  38. ramp_delay);
  39. switch (ramp_delay) {
  40. case 1 ... 1250:
  41. ramp_value = BUCK_RAMPRATE_1P25MV;
  42. break;
  43. case 1251 ... 2500:
  44. ramp_value = BUCK_RAMPRATE_2P50MV;
  45. break;
  46. case 2501 ... 5000:
  47. ramp_value = BUCK_RAMPRATE_5P00MV;
  48. break;
  49. case 5001 ... 10000:
  50. ramp_value = BUCK_RAMPRATE_10P00MV;
  51. break;
  52. default:
  53. ramp_value = BUCK_RAMPRATE_10P00MV;
  54. dev_err(&pmic->pdev->dev,
  55. "%s: ramp_delay: %d not supported, setting 10000mV//us\n",
  56. rdev->desc->name, ramp_delay);
  57. }
  58. return regmap_update_bits(mfd->regmap, BD71837_REG_BUCK1_CTRL + id,
  59. BUCK_RAMPRATE_MASK, ramp_value << 6);
  60. }
  61. /* Bucks 1 to 4 support DVS. PWM mode is used when voltage is changed.
  62. * Bucks 5 to 8 and LDOs can use PFM and must be disabled when voltage
  63. * is changed. Hence we return -EBUSY for these if voltage is changed
  64. * when BUCK/LDO is enabled.
  65. */
  66. static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev,
  67. unsigned int sel)
  68. {
  69. if (regulator_is_enabled_regmap(rdev))
  70. return -EBUSY;
  71. return regulator_set_voltage_sel_regmap(rdev, sel);
  72. }
  73. static struct regulator_ops bd71837_ldo_regulator_ops = {
  74. .enable = regulator_enable_regmap,
  75. .disable = regulator_disable_regmap,
  76. .is_enabled = regulator_is_enabled_regmap,
  77. .list_voltage = regulator_list_voltage_linear_range,
  78. .set_voltage_sel = bd71837_set_voltage_sel_restricted,
  79. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  80. };
  81. static struct regulator_ops bd71837_ldo_regulator_nolinear_ops = {
  82. .enable = regulator_enable_regmap,
  83. .disable = regulator_disable_regmap,
  84. .is_enabled = regulator_is_enabled_regmap,
  85. .list_voltage = regulator_list_voltage_table,
  86. .set_voltage_sel = bd71837_set_voltage_sel_restricted,
  87. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  88. };
  89. static struct regulator_ops bd71837_buck_regulator_ops = {
  90. .enable = regulator_enable_regmap,
  91. .disable = regulator_disable_regmap,
  92. .is_enabled = regulator_is_enabled_regmap,
  93. .list_voltage = regulator_list_voltage_linear_range,
  94. .set_voltage_sel = bd71837_set_voltage_sel_restricted,
  95. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  96. .set_voltage_time_sel = regulator_set_voltage_time_sel,
  97. };
  98. static struct regulator_ops bd71837_buck_regulator_nolinear_ops = {
  99. .enable = regulator_enable_regmap,
  100. .disable = regulator_disable_regmap,
  101. .is_enabled = regulator_is_enabled_regmap,
  102. .list_voltage = regulator_list_voltage_table,
  103. .set_voltage_sel = bd71837_set_voltage_sel_restricted,
  104. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  105. .set_voltage_time_sel = regulator_set_voltage_time_sel,
  106. };
  107. static struct regulator_ops bd71837_buck1234_regulator_ops = {
  108. .enable = regulator_enable_regmap,
  109. .disable = regulator_disable_regmap,
  110. .is_enabled = regulator_is_enabled_regmap,
  111. .list_voltage = regulator_list_voltage_linear_range,
  112. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  113. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  114. .set_voltage_time_sel = regulator_set_voltage_time_sel,
  115. .set_ramp_delay = bd71837_buck1234_set_ramp_delay,
  116. };
  117. /*
  118. * BUCK1/2/3/4
  119. * 0.70 to 1.30V (10mV step)
  120. */
  121. static const struct regulator_linear_range bd71837_buck1234_voltage_ranges[] = {
  122. REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000),
  123. REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0),
  124. };
  125. /*
  126. * BUCK5
  127. * 0.9V to 1.35V ()
  128. */
  129. static const struct regulator_linear_range bd71837_buck5_voltage_ranges[] = {
  130. REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
  131. REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
  132. REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
  133. };
  134. /*
  135. * BUCK6
  136. * 3.0V to 3.3V (step 100mV)
  137. */
  138. static const struct regulator_linear_range bd71837_buck6_voltage_ranges[] = {
  139. REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
  140. };
  141. /*
  142. * BUCK7
  143. * 000 = 1.605V
  144. * 001 = 1.695V
  145. * 010 = 1.755V
  146. * 011 = 1.8V (Initial)
  147. * 100 = 1.845V
  148. * 101 = 1.905V
  149. * 110 = 1.95V
  150. * 111 = 1.995V
  151. */
  152. static const unsigned int buck_7_volts[] = {
  153. 1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000
  154. };
  155. /*
  156. * BUCK8
  157. * 0.8V to 1.40V (step 10mV)
  158. */
  159. static const struct regulator_linear_range bd71837_buck8_voltage_ranges[] = {
  160. REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000),
  161. REGULATOR_LINEAR_RANGE(1400000, 0x3D, 0x3F, 0),
  162. };
  163. /*
  164. * LDO1
  165. * 3.0 to 3.3V (100mV step)
  166. */
  167. static const struct regulator_linear_range bd71837_ldo1_voltage_ranges[] = {
  168. REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
  169. };
  170. /*
  171. * LDO2
  172. * 0.8 or 0.9V
  173. */
  174. static const unsigned int ldo_2_volts[] = {
  175. 900000, 800000
  176. };
  177. /*
  178. * LDO3
  179. * 1.8 to 3.3V (100mV step)
  180. */
  181. static const struct regulator_linear_range bd71837_ldo3_voltage_ranges[] = {
  182. REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
  183. };
  184. /*
  185. * LDO4
  186. * 0.9 to 1.8V (100mV step)
  187. */
  188. static const struct regulator_linear_range bd71837_ldo4_voltage_ranges[] = {
  189. REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
  190. REGULATOR_LINEAR_RANGE(1800000, 0x0A, 0x0F, 0),
  191. };
  192. /*
  193. * LDO5
  194. * 1.8 to 3.3V (100mV step)
  195. */
  196. static const struct regulator_linear_range bd71837_ldo5_voltage_ranges[] = {
  197. REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
  198. };
  199. /*
  200. * LDO6
  201. * 0.9 to 1.8V (100mV step)
  202. */
  203. static const struct regulator_linear_range bd71837_ldo6_voltage_ranges[] = {
  204. REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
  205. REGULATOR_LINEAR_RANGE(1800000, 0x0A, 0x0F, 0),
  206. };
  207. /*
  208. * LDO7
  209. * 1.8 to 3.3V (100mV step)
  210. */
  211. static const struct regulator_linear_range bd71837_ldo7_voltage_ranges[] = {
  212. REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
  213. };
  214. static const struct regulator_desc bd71837_regulators[] = {
  215. {
  216. .name = "buck1",
  217. .of_match = of_match_ptr("BUCK1"),
  218. .regulators_node = of_match_ptr("regulators"),
  219. .id = BD71837_BUCK1,
  220. .ops = &bd71837_buck1234_regulator_ops,
  221. .type = REGULATOR_VOLTAGE,
  222. .n_voltages = BD71837_BUCK1_VOLTAGE_NUM,
  223. .linear_ranges = bd71837_buck1234_voltage_ranges,
  224. .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
  225. .vsel_reg = BD71837_REG_BUCK1_VOLT_RUN,
  226. .vsel_mask = BUCK1_RUN_MASK,
  227. .enable_reg = BD71837_REG_BUCK1_CTRL,
  228. .enable_mask = BD71837_BUCK_EN,
  229. .owner = THIS_MODULE,
  230. },
  231. {
  232. .name = "buck2",
  233. .of_match = of_match_ptr("BUCK2"),
  234. .regulators_node = of_match_ptr("regulators"),
  235. .id = BD71837_BUCK2,
  236. .ops = &bd71837_buck1234_regulator_ops,
  237. .type = REGULATOR_VOLTAGE,
  238. .n_voltages = BD71837_BUCK2_VOLTAGE_NUM,
  239. .linear_ranges = bd71837_buck1234_voltage_ranges,
  240. .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
  241. .vsel_reg = BD71837_REG_BUCK2_VOLT_RUN,
  242. .vsel_mask = BUCK2_RUN_MASK,
  243. .enable_reg = BD71837_REG_BUCK2_CTRL,
  244. .enable_mask = BD71837_BUCK_EN,
  245. .owner = THIS_MODULE,
  246. },
  247. {
  248. .name = "buck3",
  249. .of_match = of_match_ptr("BUCK3"),
  250. .regulators_node = of_match_ptr("regulators"),
  251. .id = BD71837_BUCK3,
  252. .ops = &bd71837_buck1234_regulator_ops,
  253. .type = REGULATOR_VOLTAGE,
  254. .n_voltages = BD71837_BUCK3_VOLTAGE_NUM,
  255. .linear_ranges = bd71837_buck1234_voltage_ranges,
  256. .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
  257. .vsel_reg = BD71837_REG_BUCK3_VOLT_RUN,
  258. .vsel_mask = BUCK3_RUN_MASK,
  259. .enable_reg = BD71837_REG_BUCK3_CTRL,
  260. .enable_mask = BD71837_BUCK_EN,
  261. .owner = THIS_MODULE,
  262. },
  263. {
  264. .name = "buck4",
  265. .of_match = of_match_ptr("BUCK4"),
  266. .regulators_node = of_match_ptr("regulators"),
  267. .id = BD71837_BUCK4,
  268. .ops = &bd71837_buck1234_regulator_ops,
  269. .type = REGULATOR_VOLTAGE,
  270. .n_voltages = BD71837_BUCK4_VOLTAGE_NUM,
  271. .linear_ranges = bd71837_buck1234_voltage_ranges,
  272. .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
  273. .vsel_reg = BD71837_REG_BUCK4_VOLT_RUN,
  274. .vsel_mask = BUCK4_RUN_MASK,
  275. .enable_reg = BD71837_REG_BUCK4_CTRL,
  276. .enable_mask = BD71837_BUCK_EN,
  277. .owner = THIS_MODULE,
  278. },
  279. {
  280. .name = "buck5",
  281. .of_match = of_match_ptr("BUCK5"),
  282. .regulators_node = of_match_ptr("regulators"),
  283. .id = BD71837_BUCK5,
  284. .ops = &bd71837_buck_regulator_ops,
  285. .type = REGULATOR_VOLTAGE,
  286. .n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
  287. .linear_ranges = bd71837_buck5_voltage_ranges,
  288. .n_linear_ranges = ARRAY_SIZE(bd71837_buck5_voltage_ranges),
  289. .vsel_reg = BD71837_REG_BUCK5_VOLT,
  290. .vsel_mask = BUCK5_MASK,
  291. .enable_reg = BD71837_REG_BUCK5_CTRL,
  292. .enable_mask = BD71837_BUCK_EN,
  293. .owner = THIS_MODULE,
  294. },
  295. {
  296. .name = "buck6",
  297. .of_match = of_match_ptr("BUCK6"),
  298. .regulators_node = of_match_ptr("regulators"),
  299. .id = BD71837_BUCK6,
  300. .ops = &bd71837_buck_regulator_ops,
  301. .type = REGULATOR_VOLTAGE,
  302. .n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
  303. .linear_ranges = bd71837_buck6_voltage_ranges,
  304. .n_linear_ranges = ARRAY_SIZE(bd71837_buck6_voltage_ranges),
  305. .vsel_reg = BD71837_REG_BUCK6_VOLT,
  306. .vsel_mask = BUCK6_MASK,
  307. .enable_reg = BD71837_REG_BUCK6_CTRL,
  308. .enable_mask = BD71837_BUCK_EN,
  309. .owner = THIS_MODULE,
  310. },
  311. {
  312. .name = "buck7",
  313. .of_match = of_match_ptr("BUCK7"),
  314. .regulators_node = of_match_ptr("regulators"),
  315. .id = BD71837_BUCK7,
  316. .ops = &bd71837_buck_regulator_nolinear_ops,
  317. .type = REGULATOR_VOLTAGE,
  318. .volt_table = &buck_7_volts[0],
  319. .n_voltages = ARRAY_SIZE(buck_7_volts),
  320. .vsel_reg = BD71837_REG_BUCK7_VOLT,
  321. .vsel_mask = BUCK7_MASK,
  322. .enable_reg = BD71837_REG_BUCK7_CTRL,
  323. .enable_mask = BD71837_BUCK_EN,
  324. .owner = THIS_MODULE,
  325. },
  326. {
  327. .name = "buck8",
  328. .of_match = of_match_ptr("BUCK8"),
  329. .regulators_node = of_match_ptr("regulators"),
  330. .id = BD71837_BUCK8,
  331. .ops = &bd71837_buck_regulator_ops,
  332. .type = REGULATOR_VOLTAGE,
  333. .n_voltages = BD71837_BUCK8_VOLTAGE_NUM,
  334. .linear_ranges = bd71837_buck8_voltage_ranges,
  335. .n_linear_ranges = ARRAY_SIZE(bd71837_buck8_voltage_ranges),
  336. .vsel_reg = BD71837_REG_BUCK8_VOLT,
  337. .vsel_mask = BUCK8_MASK,
  338. .enable_reg = BD71837_REG_BUCK8_CTRL,
  339. .enable_mask = BD71837_BUCK_EN,
  340. .owner = THIS_MODULE,
  341. },
  342. {
  343. .name = "ldo1",
  344. .of_match = of_match_ptr("LDO1"),
  345. .regulators_node = of_match_ptr("regulators"),
  346. .id = BD71837_LDO1,
  347. .ops = &bd71837_ldo_regulator_ops,
  348. .type = REGULATOR_VOLTAGE,
  349. .n_voltages = BD71837_LDO1_VOLTAGE_NUM,
  350. .linear_ranges = bd71837_ldo1_voltage_ranges,
  351. .n_linear_ranges = ARRAY_SIZE(bd71837_ldo1_voltage_ranges),
  352. .vsel_reg = BD71837_REG_LDO1_VOLT,
  353. .vsel_mask = LDO1_MASK,
  354. .enable_reg = BD71837_REG_LDO1_VOLT,
  355. .enable_mask = BD71837_LDO_EN,
  356. .owner = THIS_MODULE,
  357. },
  358. {
  359. .name = "ldo2",
  360. .of_match = of_match_ptr("LDO2"),
  361. .regulators_node = of_match_ptr("regulators"),
  362. .id = BD71837_LDO2,
  363. .ops = &bd71837_ldo_regulator_nolinear_ops,
  364. .type = REGULATOR_VOLTAGE,
  365. .volt_table = &ldo_2_volts[0],
  366. .vsel_reg = BD71837_REG_LDO2_VOLT,
  367. .vsel_mask = LDO2_MASK,
  368. .n_voltages = ARRAY_SIZE(ldo_2_volts),
  369. .n_voltages = BD71837_LDO2_VOLTAGE_NUM,
  370. .enable_reg = BD71837_REG_LDO2_VOLT,
  371. .enable_mask = BD71837_LDO_EN,
  372. .owner = THIS_MODULE,
  373. },
  374. {
  375. .name = "ldo3",
  376. .of_match = of_match_ptr("LDO3"),
  377. .regulators_node = of_match_ptr("regulators"),
  378. .id = BD71837_LDO3,
  379. .ops = &bd71837_ldo_regulator_ops,
  380. .type = REGULATOR_VOLTAGE,
  381. .n_voltages = BD71837_LDO3_VOLTAGE_NUM,
  382. .linear_ranges = bd71837_ldo3_voltage_ranges,
  383. .n_linear_ranges = ARRAY_SIZE(bd71837_ldo3_voltage_ranges),
  384. .vsel_reg = BD71837_REG_LDO3_VOLT,
  385. .vsel_mask = LDO3_MASK,
  386. .enable_reg = BD71837_REG_LDO3_VOLT,
  387. .enable_mask = BD71837_LDO_EN,
  388. .owner = THIS_MODULE,
  389. },
  390. {
  391. .name = "ldo4",
  392. .of_match = of_match_ptr("LDO4"),
  393. .regulators_node = of_match_ptr("regulators"),
  394. .id = BD71837_LDO4,
  395. .ops = &bd71837_ldo_regulator_ops,
  396. .type = REGULATOR_VOLTAGE,
  397. .n_voltages = BD71837_LDO4_VOLTAGE_NUM,
  398. .linear_ranges = bd71837_ldo4_voltage_ranges,
  399. .n_linear_ranges = ARRAY_SIZE(bd71837_ldo4_voltage_ranges),
  400. .vsel_reg = BD71837_REG_LDO4_VOLT,
  401. .vsel_mask = LDO4_MASK,
  402. .enable_reg = BD71837_REG_LDO4_VOLT,
  403. .enable_mask = BD71837_LDO_EN,
  404. .owner = THIS_MODULE,
  405. },
  406. {
  407. .name = "ldo5",
  408. .of_match = of_match_ptr("LDO5"),
  409. .regulators_node = of_match_ptr("regulators"),
  410. .id = BD71837_LDO5,
  411. .ops = &bd71837_ldo_regulator_ops,
  412. .type = REGULATOR_VOLTAGE,
  413. .n_voltages = BD71837_LDO5_VOLTAGE_NUM,
  414. .linear_ranges = bd71837_ldo5_voltage_ranges,
  415. .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_voltage_ranges),
  416. /* LDO5 is supplied by buck6 */
  417. .supply_name = "buck6",
  418. .vsel_reg = BD71837_REG_LDO5_VOLT,
  419. .vsel_mask = LDO5_MASK,
  420. .enable_reg = BD71837_REG_LDO5_VOLT,
  421. .enable_mask = BD71837_LDO_EN,
  422. .owner = THIS_MODULE,
  423. },
  424. {
  425. .name = "ldo6",
  426. .of_match = of_match_ptr("LDO6"),
  427. .regulators_node = of_match_ptr("regulators"),
  428. .id = BD71837_LDO6,
  429. .ops = &bd71837_ldo_regulator_ops,
  430. .type = REGULATOR_VOLTAGE,
  431. .n_voltages = BD71837_LDO6_VOLTAGE_NUM,
  432. .linear_ranges = bd71837_ldo6_voltage_ranges,
  433. .n_linear_ranges = ARRAY_SIZE(bd71837_ldo6_voltage_ranges),
  434. /* LDO6 is supplied by buck7 */
  435. .supply_name = "buck7",
  436. .vsel_reg = BD71837_REG_LDO6_VOLT,
  437. .vsel_mask = LDO6_MASK,
  438. .enable_reg = BD71837_REG_LDO6_VOLT,
  439. .enable_mask = BD71837_LDO_EN,
  440. .owner = THIS_MODULE,
  441. },
  442. {
  443. .name = "ldo7",
  444. .of_match = of_match_ptr("LDO7"),
  445. .regulators_node = of_match_ptr("regulators"),
  446. .id = BD71837_LDO7,
  447. .ops = &bd71837_ldo_regulator_ops,
  448. .type = REGULATOR_VOLTAGE,
  449. .n_voltages = BD71837_LDO7_VOLTAGE_NUM,
  450. .linear_ranges = bd71837_ldo7_voltage_ranges,
  451. .n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_voltage_ranges),
  452. .vsel_reg = BD71837_REG_LDO7_VOLT,
  453. .vsel_mask = LDO7_MASK,
  454. .enable_reg = BD71837_REG_LDO7_VOLT,
  455. .enable_mask = BD71837_LDO_EN,
  456. .owner = THIS_MODULE,
  457. },
  458. };
  459. struct reg_init {
  460. unsigned int reg;
  461. unsigned int mask;
  462. };
  463. static int bd71837_probe(struct platform_device *pdev)
  464. {
  465. struct bd71837_pmic *pmic;
  466. struct regulator_config config = { 0 };
  467. struct reg_init pmic_regulator_inits[] = {
  468. {
  469. .reg = BD71837_REG_BUCK1_CTRL,
  470. .mask = BD71837_BUCK_SEL,
  471. }, {
  472. .reg = BD71837_REG_BUCK2_CTRL,
  473. .mask = BD71837_BUCK_SEL,
  474. }, {
  475. .reg = BD71837_REG_BUCK3_CTRL,
  476. .mask = BD71837_BUCK_SEL,
  477. }, {
  478. .reg = BD71837_REG_BUCK4_CTRL,
  479. .mask = BD71837_BUCK_SEL,
  480. }, {
  481. .reg = BD71837_REG_BUCK5_CTRL,
  482. .mask = BD71837_BUCK_SEL,
  483. }, {
  484. .reg = BD71837_REG_BUCK6_CTRL,
  485. .mask = BD71837_BUCK_SEL,
  486. }, {
  487. .reg = BD71837_REG_BUCK7_CTRL,
  488. .mask = BD71837_BUCK_SEL,
  489. }, {
  490. .reg = BD71837_REG_BUCK8_CTRL,
  491. .mask = BD71837_BUCK_SEL,
  492. }, {
  493. .reg = BD71837_REG_LDO1_VOLT,
  494. .mask = BD71837_LDO_SEL,
  495. }, {
  496. .reg = BD71837_REG_LDO2_VOLT,
  497. .mask = BD71837_LDO_SEL,
  498. }, {
  499. .reg = BD71837_REG_LDO3_VOLT,
  500. .mask = BD71837_LDO_SEL,
  501. }, {
  502. .reg = BD71837_REG_LDO4_VOLT,
  503. .mask = BD71837_LDO_SEL,
  504. }, {
  505. .reg = BD71837_REG_LDO5_VOLT,
  506. .mask = BD71837_LDO_SEL,
  507. }, {
  508. .reg = BD71837_REG_LDO6_VOLT,
  509. .mask = BD71837_LDO_SEL,
  510. }, {
  511. .reg = BD71837_REG_LDO7_VOLT,
  512. .mask = BD71837_LDO_SEL,
  513. }
  514. };
  515. int i, err;
  516. pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
  517. if (!pmic)
  518. return -ENOMEM;
  519. memcpy(pmic->descs, bd71837_regulators, sizeof(pmic->descs));
  520. pmic->pdev = pdev;
  521. pmic->mfd = dev_get_drvdata(pdev->dev.parent);
  522. if (!pmic->mfd) {
  523. dev_err(&pdev->dev, "No MFD driver data\n");
  524. err = -EINVAL;
  525. goto err;
  526. }
  527. platform_set_drvdata(pdev, pmic);
  528. /* Register LOCK release */
  529. err = regmap_update_bits(pmic->mfd->regmap, BD71837_REG_REGLOCK,
  530. (REGLOCK_PWRSEQ | REGLOCK_VREG), 0);
  531. if (err) {
  532. dev_err(&pmic->pdev->dev, "Failed to unlock PMIC (%d)\n", err);
  533. goto err;
  534. } else {
  535. dev_dbg(&pmic->pdev->dev, "Unlocked lock register 0x%x\n",
  536. BD71837_REG_REGLOCK);
  537. }
  538. /*
  539. * There is a HW quirk in BD71837. The shutdown sequence timings for
  540. * bucks/LDOs which are controlled via register interface are changed.
  541. * At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
  542. * beginning of shut-down sequence. As bucks 6 and 7 are parent
  543. * supplies for LDO5 and LDO6 - this causes LDO5/6 voltage
  544. * monitoring to errorneously detect under voltage and force PMIC to
  545. * emergency state instead of poweroff. In order to avoid this we
  546. * disable voltage monitoring for LDO5 and LDO6
  547. */
  548. err = regmap_update_bits(pmic->mfd->regmap, BD718XX_REG_MVRFLTMASK2,
  549. BD718XX_LDO5_VRMON80 | BD718XX_LDO6_VRMON80,
  550. BD718XX_LDO5_VRMON80 | BD718XX_LDO6_VRMON80);
  551. if (err) {
  552. dev_err(&pmic->pdev->dev,
  553. "Failed to disable voltage monitoring\n");
  554. goto err;
  555. }
  556. for (i = 0; i < ARRAY_SIZE(pmic_regulator_inits); i++) {
  557. struct regulator_desc *desc;
  558. struct regulator_dev *rdev;
  559. desc = &pmic->descs[i];
  560. config.dev = pdev->dev.parent;
  561. config.driver_data = pmic;
  562. config.regmap = pmic->mfd->regmap;
  563. rdev = devm_regulator_register(&pdev->dev, desc, &config);
  564. if (IS_ERR(rdev)) {
  565. dev_err(pmic->mfd->dev,
  566. "failed to register %s regulator\n",
  567. desc->name);
  568. err = PTR_ERR(rdev);
  569. goto err;
  570. }
  571. /* Regulator register gets the regulator constraints and
  572. * applies them (set_machine_constraints). This should have
  573. * turned the control register(s) to correct values and we
  574. * can now switch the control from PMIC state machine to the
  575. * register interface
  576. */
  577. err = regmap_update_bits(pmic->mfd->regmap,
  578. pmic_regulator_inits[i].reg,
  579. pmic_regulator_inits[i].mask,
  580. 0xFFFFFFFF);
  581. if (err) {
  582. dev_err(&pmic->pdev->dev,
  583. "Failed to write BUCK/LDO SEL bit for (%s)\n",
  584. desc->name);
  585. goto err;
  586. }
  587. pmic->rdev[i] = rdev;
  588. }
  589. err:
  590. return err;
  591. }
  592. static struct platform_driver bd71837_regulator = {
  593. .driver = {
  594. .name = "bd71837-pmic",
  595. },
  596. .probe = bd71837_probe,
  597. };
  598. module_platform_driver(bd71837_regulator);
  599. MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
  600. MODULE_DESCRIPTION("BD71837 voltage regulator driver");
  601. MODULE_LICENSE("GPL");