lp8788-ldo.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. /*
  2. * TI LP8788 MFD - ldo regulator driver
  3. *
  4. * Copyright 2012 Texas Instruments
  5. *
  6. * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
  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. */
  13. #include <linux/module.h>
  14. #include <linux/slab.h>
  15. #include <linux/err.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/regulator/driver.h>
  18. #include <linux/gpio.h>
  19. #include <linux/mfd/lp8788.h>
  20. /* register address */
  21. #define LP8788_EN_LDO_A 0x0D /* DLDO 1 ~ 8 */
  22. #define LP8788_EN_LDO_B 0x0E /* DLDO 9 ~ 12, ALDO 1 ~ 4 */
  23. #define LP8788_EN_LDO_C 0x0F /* ALDO 5 ~ 10 */
  24. #define LP8788_EN_SEL 0x10
  25. #define LP8788_DLDO1_VOUT 0x2E
  26. #define LP8788_DLDO2_VOUT 0x2F
  27. #define LP8788_DLDO3_VOUT 0x30
  28. #define LP8788_DLDO4_VOUT 0x31
  29. #define LP8788_DLDO5_VOUT 0x32
  30. #define LP8788_DLDO6_VOUT 0x33
  31. #define LP8788_DLDO7_VOUT 0x34
  32. #define LP8788_DLDO8_VOUT 0x35
  33. #define LP8788_DLDO9_VOUT 0x36
  34. #define LP8788_DLDO10_VOUT 0x37
  35. #define LP8788_DLDO11_VOUT 0x38
  36. #define LP8788_DLDO12_VOUT 0x39
  37. #define LP8788_ALDO1_VOUT 0x3A
  38. #define LP8788_ALDO2_VOUT 0x3B
  39. #define LP8788_ALDO3_VOUT 0x3C
  40. #define LP8788_ALDO4_VOUT 0x3D
  41. #define LP8788_ALDO5_VOUT 0x3E
  42. #define LP8788_ALDO6_VOUT 0x3F
  43. #define LP8788_ALDO7_VOUT 0x40
  44. #define LP8788_ALDO8_VOUT 0x41
  45. #define LP8788_ALDO9_VOUT 0x42
  46. #define LP8788_ALDO10_VOUT 0x43
  47. #define LP8788_DLDO1_TIMESTEP 0x44
  48. /* mask/shift bits */
  49. #define LP8788_EN_DLDO1_M BIT(0) /* Addr 0Dh ~ 0Fh */
  50. #define LP8788_EN_DLDO2_M BIT(1)
  51. #define LP8788_EN_DLDO3_M BIT(2)
  52. #define LP8788_EN_DLDO4_M BIT(3)
  53. #define LP8788_EN_DLDO5_M BIT(4)
  54. #define LP8788_EN_DLDO6_M BIT(5)
  55. #define LP8788_EN_DLDO7_M BIT(6)
  56. #define LP8788_EN_DLDO8_M BIT(7)
  57. #define LP8788_EN_DLDO9_M BIT(0)
  58. #define LP8788_EN_DLDO10_M BIT(1)
  59. #define LP8788_EN_DLDO11_M BIT(2)
  60. #define LP8788_EN_DLDO12_M BIT(3)
  61. #define LP8788_EN_ALDO1_M BIT(4)
  62. #define LP8788_EN_ALDO2_M BIT(5)
  63. #define LP8788_EN_ALDO3_M BIT(6)
  64. #define LP8788_EN_ALDO4_M BIT(7)
  65. #define LP8788_EN_ALDO5_M BIT(0)
  66. #define LP8788_EN_ALDO6_M BIT(1)
  67. #define LP8788_EN_ALDO7_M BIT(2)
  68. #define LP8788_EN_ALDO8_M BIT(3)
  69. #define LP8788_EN_ALDO9_M BIT(4)
  70. #define LP8788_EN_ALDO10_M BIT(5)
  71. #define LP8788_EN_SEL_DLDO911_M BIT(0) /* Addr 10h */
  72. #define LP8788_EN_SEL_DLDO7_M BIT(1)
  73. #define LP8788_EN_SEL_ALDO7_M BIT(2)
  74. #define LP8788_EN_SEL_ALDO5_M BIT(3)
  75. #define LP8788_EN_SEL_ALDO234_M BIT(4)
  76. #define LP8788_EN_SEL_ALDO1_M BIT(5)
  77. #define LP8788_VOUT_5BIT_M 0x1F /* Addr 2Eh ~ 43h */
  78. #define LP8788_VOUT_4BIT_M 0x0F
  79. #define LP8788_VOUT_3BIT_M 0x07
  80. #define LP8788_VOUT_1BIT_M 0x01
  81. #define LP8788_STARTUP_TIME_M 0xF8 /* Addr 44h ~ 59h */
  82. #define LP8788_STARTUP_TIME_S 3
  83. #define ENABLE_TIME_USEC 32
  84. #define ENABLE GPIOF_OUT_INIT_HIGH
  85. #define DISABLE GPIOF_OUT_INIT_LOW
  86. enum lp8788_enable_mode {
  87. REGISTER,
  88. EXTPIN,
  89. };
  90. enum lp8788_ldo_id {
  91. DLDO1,
  92. DLDO2,
  93. DLDO3,
  94. DLDO4,
  95. DLDO5,
  96. DLDO6,
  97. DLDO7,
  98. DLDO8,
  99. DLDO9,
  100. DLDO10,
  101. DLDO11,
  102. DLDO12,
  103. ALDO1,
  104. ALDO2,
  105. ALDO3,
  106. ALDO4,
  107. ALDO5,
  108. ALDO6,
  109. ALDO7,
  110. ALDO8,
  111. ALDO9,
  112. ALDO10,
  113. };
  114. struct lp8788_ldo {
  115. struct lp8788 *lp;
  116. struct regulator_desc *desc;
  117. struct regulator_dev *regulator;
  118. struct lp8788_ldo_enable_pin *en_pin;
  119. };
  120. /* DLDO 1, 2, 3, 9 voltage table */
  121. static const int lp8788_dldo1239_vtbl[] = {
  122. 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
  123. 2600000, 2700000, 2800000, 2900000, 3000000, 2850000, 2850000, 2850000,
  124. 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000,
  125. 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000,
  126. };
  127. /* DLDO 4 voltage table */
  128. static const int lp8788_dldo4_vtbl[] = { 1800000, 3000000 };
  129. /* DLDO 5, 7, 8 and ALDO 6 voltage table */
  130. static const int lp8788_dldo578_aldo6_vtbl[] = {
  131. 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
  132. 2600000, 2700000, 2800000, 2900000, 3000000, 3000000, 3000000, 3000000,
  133. };
  134. /* DLDO 6 voltage table */
  135. static const int lp8788_dldo6_vtbl[] = {
  136. 3000000, 3100000, 3200000, 3300000, 3400000, 3500000, 3600000, 3600000,
  137. };
  138. /* DLDO 10, 11 voltage table */
  139. static const int lp8788_dldo1011_vtbl[] = {
  140. 1100000, 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000,
  141. 1500000, 1500000, 1500000, 1500000, 1500000, 1500000, 1500000, 1500000,
  142. };
  143. /* ALDO 1 voltage table */
  144. static const int lp8788_aldo1_vtbl[] = { 1800000, 2850000 };
  145. /* ALDO 7 voltage table */
  146. static const int lp8788_aldo7_vtbl[] = {
  147. 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1800000,
  148. };
  149. static enum lp8788_ldo_id lp8788_dldo_id[] = {
  150. DLDO1,
  151. DLDO2,
  152. DLDO3,
  153. DLDO4,
  154. DLDO5,
  155. DLDO6,
  156. DLDO7,
  157. DLDO8,
  158. DLDO9,
  159. DLDO10,
  160. DLDO11,
  161. DLDO12,
  162. };
  163. static enum lp8788_ldo_id lp8788_aldo_id[] = {
  164. ALDO1,
  165. ALDO2,
  166. ALDO3,
  167. ALDO4,
  168. ALDO5,
  169. ALDO6,
  170. ALDO7,
  171. ALDO8,
  172. ALDO9,
  173. ALDO10,
  174. };
  175. /* DLDO 7, 9 and 11, ALDO 1 ~ 5 and 7
  176. : can be enabled either by external pin or by i2c register */
  177. static enum lp8788_enable_mode
  178. lp8788_get_ldo_enable_mode(struct lp8788_ldo *ldo, enum lp8788_ldo_id id)
  179. {
  180. int ret;
  181. u8 val, mask;
  182. ret = lp8788_read_byte(ldo->lp, LP8788_EN_SEL, &val);
  183. if (ret)
  184. return ret;
  185. switch (id) {
  186. case DLDO7:
  187. mask = LP8788_EN_SEL_DLDO7_M;
  188. break;
  189. case DLDO9:
  190. case DLDO11:
  191. mask = LP8788_EN_SEL_DLDO911_M;
  192. break;
  193. case ALDO1:
  194. mask = LP8788_EN_SEL_ALDO1_M;
  195. break;
  196. case ALDO2 ... ALDO4:
  197. mask = LP8788_EN_SEL_ALDO234_M;
  198. break;
  199. case ALDO5:
  200. mask = LP8788_EN_SEL_ALDO5_M;
  201. break;
  202. case ALDO7:
  203. mask = LP8788_EN_SEL_ALDO7_M;
  204. break;
  205. default:
  206. return REGISTER;
  207. }
  208. return val & mask ? EXTPIN : REGISTER;
  209. }
  210. static int lp8788_ldo_ctrl_by_extern_pin(struct lp8788_ldo *ldo, int pinstate)
  211. {
  212. struct lp8788_ldo_enable_pin *pin = ldo->en_pin;
  213. if (!pin)
  214. return -EINVAL;
  215. if (gpio_is_valid(pin->gpio))
  216. gpio_set_value(pin->gpio, pinstate);
  217. return 0;
  218. }
  219. static int lp8788_ldo_is_enabled_by_extern_pin(struct lp8788_ldo *ldo)
  220. {
  221. struct lp8788_ldo_enable_pin *pin = ldo->en_pin;
  222. if (!pin)
  223. return -EINVAL;
  224. return gpio_get_value(pin->gpio) ? 1 : 0;
  225. }
  226. static int lp8788_ldo_enable(struct regulator_dev *rdev)
  227. {
  228. struct lp8788_ldo *ldo = rdev_get_drvdata(rdev);
  229. enum lp8788_ldo_id id = rdev_get_id(rdev);
  230. enum lp8788_enable_mode mode = lp8788_get_ldo_enable_mode(ldo, id);
  231. switch (mode) {
  232. case EXTPIN:
  233. return lp8788_ldo_ctrl_by_extern_pin(ldo, ENABLE);
  234. case REGISTER:
  235. return regulator_enable_regmap(rdev);
  236. default:
  237. return -EINVAL;
  238. }
  239. }
  240. static int lp8788_ldo_disable(struct regulator_dev *rdev)
  241. {
  242. struct lp8788_ldo *ldo = rdev_get_drvdata(rdev);
  243. enum lp8788_ldo_id id = rdev_get_id(rdev);
  244. enum lp8788_enable_mode mode = lp8788_get_ldo_enable_mode(ldo, id);
  245. switch (mode) {
  246. case EXTPIN:
  247. return lp8788_ldo_ctrl_by_extern_pin(ldo, DISABLE);
  248. case REGISTER:
  249. return regulator_disable_regmap(rdev);
  250. default:
  251. return -EINVAL;
  252. }
  253. }
  254. static int lp8788_ldo_is_enabled(struct regulator_dev *rdev)
  255. {
  256. struct lp8788_ldo *ldo = rdev_get_drvdata(rdev);
  257. enum lp8788_ldo_id id = rdev_get_id(rdev);
  258. enum lp8788_enable_mode mode = lp8788_get_ldo_enable_mode(ldo, id);
  259. switch (mode) {
  260. case EXTPIN:
  261. return lp8788_ldo_is_enabled_by_extern_pin(ldo);
  262. case REGISTER:
  263. return regulator_is_enabled_regmap(rdev);
  264. default:
  265. return -EINVAL;
  266. }
  267. }
  268. static int lp8788_ldo_enable_time(struct regulator_dev *rdev)
  269. {
  270. struct lp8788_ldo *ldo = rdev_get_drvdata(rdev);
  271. enum lp8788_ldo_id id = rdev_get_id(rdev);
  272. u8 val, addr = LP8788_DLDO1_TIMESTEP + id;
  273. if (lp8788_read_byte(ldo->lp, addr, &val))
  274. return -EINVAL;
  275. val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S;
  276. return ENABLE_TIME_USEC * val;
  277. }
  278. static int lp8788_ldo_fixed_get_voltage(struct regulator_dev *rdev)
  279. {
  280. enum lp8788_ldo_id id = rdev_get_id(rdev);
  281. switch (id) {
  282. case ALDO2 ... ALDO5:
  283. return 2850000;
  284. case DLDO12:
  285. case ALDO8 ... ALDO9:
  286. return 2500000;
  287. case ALDO10:
  288. return 1100000;
  289. default:
  290. return -EINVAL;
  291. }
  292. }
  293. static struct regulator_ops lp8788_ldo_voltage_table_ops = {
  294. .list_voltage = regulator_list_voltage_table,
  295. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  296. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  297. .enable = lp8788_ldo_enable,
  298. .disable = lp8788_ldo_disable,
  299. .is_enabled = lp8788_ldo_is_enabled,
  300. .enable_time = lp8788_ldo_enable_time,
  301. };
  302. static struct regulator_ops lp8788_ldo_voltage_fixed_ops = {
  303. .get_voltage = lp8788_ldo_fixed_get_voltage,
  304. .enable = lp8788_ldo_enable,
  305. .disable = lp8788_ldo_disable,
  306. .is_enabled = lp8788_ldo_is_enabled,
  307. .enable_time = lp8788_ldo_enable_time,
  308. };
  309. static struct regulator_desc lp8788_dldo_desc[] = {
  310. {
  311. .name = "dldo1",
  312. .id = DLDO1,
  313. .ops = &lp8788_ldo_voltage_table_ops,
  314. .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
  315. .volt_table = lp8788_dldo1239_vtbl,
  316. .type = REGULATOR_VOLTAGE,
  317. .owner = THIS_MODULE,
  318. .vsel_reg = LP8788_DLDO1_VOUT,
  319. .vsel_mask = LP8788_VOUT_5BIT_M,
  320. .enable_reg = LP8788_EN_LDO_A,
  321. .enable_mask = LP8788_EN_DLDO1_M,
  322. },
  323. {
  324. .name = "dldo2",
  325. .id = DLDO2,
  326. .ops = &lp8788_ldo_voltage_table_ops,
  327. .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
  328. .volt_table = lp8788_dldo1239_vtbl,
  329. .type = REGULATOR_VOLTAGE,
  330. .owner = THIS_MODULE,
  331. .vsel_reg = LP8788_DLDO2_VOUT,
  332. .vsel_mask = LP8788_VOUT_5BIT_M,
  333. .enable_reg = LP8788_EN_LDO_A,
  334. .enable_mask = LP8788_EN_DLDO2_M,
  335. },
  336. {
  337. .name = "dldo3",
  338. .id = DLDO3,
  339. .ops = &lp8788_ldo_voltage_table_ops,
  340. .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
  341. .volt_table = lp8788_dldo1239_vtbl,
  342. .type = REGULATOR_VOLTAGE,
  343. .owner = THIS_MODULE,
  344. .vsel_reg = LP8788_DLDO3_VOUT,
  345. .vsel_mask = LP8788_VOUT_5BIT_M,
  346. .enable_reg = LP8788_EN_LDO_A,
  347. .enable_mask = LP8788_EN_DLDO3_M,
  348. },
  349. {
  350. .name = "dldo4",
  351. .id = DLDO4,
  352. .ops = &lp8788_ldo_voltage_table_ops,
  353. .n_voltages = ARRAY_SIZE(lp8788_dldo4_vtbl),
  354. .volt_table = lp8788_dldo4_vtbl,
  355. .type = REGULATOR_VOLTAGE,
  356. .owner = THIS_MODULE,
  357. .vsel_reg = LP8788_DLDO4_VOUT,
  358. .vsel_mask = LP8788_VOUT_1BIT_M,
  359. .enable_reg = LP8788_EN_LDO_A,
  360. .enable_mask = LP8788_EN_DLDO4_M,
  361. },
  362. {
  363. .name = "dldo5",
  364. .id = DLDO5,
  365. .ops = &lp8788_ldo_voltage_table_ops,
  366. .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
  367. .volt_table = lp8788_dldo578_aldo6_vtbl,
  368. .type = REGULATOR_VOLTAGE,
  369. .owner = THIS_MODULE,
  370. .vsel_reg = LP8788_DLDO5_VOUT,
  371. .vsel_mask = LP8788_VOUT_4BIT_M,
  372. .enable_reg = LP8788_EN_LDO_A,
  373. .enable_mask = LP8788_EN_DLDO5_M,
  374. },
  375. {
  376. .name = "dldo6",
  377. .id = DLDO6,
  378. .ops = &lp8788_ldo_voltage_table_ops,
  379. .n_voltages = ARRAY_SIZE(lp8788_dldo6_vtbl),
  380. .volt_table = lp8788_dldo6_vtbl,
  381. .type = REGULATOR_VOLTAGE,
  382. .owner = THIS_MODULE,
  383. .vsel_reg = LP8788_DLDO6_VOUT,
  384. .vsel_mask = LP8788_VOUT_3BIT_M,
  385. .enable_reg = LP8788_EN_LDO_A,
  386. .enable_mask = LP8788_EN_DLDO6_M,
  387. },
  388. {
  389. .name = "dldo7",
  390. .id = DLDO7,
  391. .ops = &lp8788_ldo_voltage_table_ops,
  392. .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
  393. .volt_table = lp8788_dldo578_aldo6_vtbl,
  394. .type = REGULATOR_VOLTAGE,
  395. .owner = THIS_MODULE,
  396. .vsel_reg = LP8788_DLDO7_VOUT,
  397. .vsel_mask = LP8788_VOUT_4BIT_M,
  398. .enable_reg = LP8788_EN_LDO_A,
  399. .enable_mask = LP8788_EN_DLDO7_M,
  400. },
  401. {
  402. .name = "dldo8",
  403. .id = DLDO8,
  404. .ops = &lp8788_ldo_voltage_table_ops,
  405. .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
  406. .volt_table = lp8788_dldo578_aldo6_vtbl,
  407. .type = REGULATOR_VOLTAGE,
  408. .owner = THIS_MODULE,
  409. .vsel_reg = LP8788_DLDO8_VOUT,
  410. .vsel_mask = LP8788_VOUT_4BIT_M,
  411. .enable_reg = LP8788_EN_LDO_A,
  412. .enable_mask = LP8788_EN_DLDO8_M,
  413. },
  414. {
  415. .name = "dldo9",
  416. .id = DLDO9,
  417. .ops = &lp8788_ldo_voltage_table_ops,
  418. .n_voltages = ARRAY_SIZE(lp8788_dldo1239_vtbl),
  419. .volt_table = lp8788_dldo1239_vtbl,
  420. .type = REGULATOR_VOLTAGE,
  421. .owner = THIS_MODULE,
  422. .vsel_reg = LP8788_DLDO9_VOUT,
  423. .vsel_mask = LP8788_VOUT_5BIT_M,
  424. .enable_reg = LP8788_EN_LDO_B,
  425. .enable_mask = LP8788_EN_DLDO9_M,
  426. },
  427. {
  428. .name = "dldo10",
  429. .id = DLDO10,
  430. .ops = &lp8788_ldo_voltage_table_ops,
  431. .n_voltages = ARRAY_SIZE(lp8788_dldo1011_vtbl),
  432. .volt_table = lp8788_dldo1011_vtbl,
  433. .type = REGULATOR_VOLTAGE,
  434. .owner = THIS_MODULE,
  435. .vsel_reg = LP8788_DLDO10_VOUT,
  436. .vsel_mask = LP8788_VOUT_4BIT_M,
  437. .enable_reg = LP8788_EN_LDO_B,
  438. .enable_mask = LP8788_EN_DLDO10_M,
  439. },
  440. {
  441. .name = "dldo11",
  442. .id = DLDO11,
  443. .ops = &lp8788_ldo_voltage_table_ops,
  444. .n_voltages = ARRAY_SIZE(lp8788_dldo1011_vtbl),
  445. .volt_table = lp8788_dldo1011_vtbl,
  446. .type = REGULATOR_VOLTAGE,
  447. .owner = THIS_MODULE,
  448. .vsel_reg = LP8788_DLDO11_VOUT,
  449. .vsel_mask = LP8788_VOUT_4BIT_M,
  450. .enable_reg = LP8788_EN_LDO_B,
  451. .enable_mask = LP8788_EN_DLDO11_M,
  452. },
  453. {
  454. .name = "dldo12",
  455. .id = DLDO12,
  456. .ops = &lp8788_ldo_voltage_fixed_ops,
  457. .n_voltages = 1,
  458. .type = REGULATOR_VOLTAGE,
  459. .owner = THIS_MODULE,
  460. .enable_reg = LP8788_EN_LDO_B,
  461. .enable_mask = LP8788_EN_DLDO12_M,
  462. },
  463. };
  464. static struct regulator_desc lp8788_aldo_desc[] = {
  465. {
  466. .name = "aldo1",
  467. .id = ALDO1,
  468. .ops = &lp8788_ldo_voltage_table_ops,
  469. .n_voltages = ARRAY_SIZE(lp8788_aldo1_vtbl),
  470. .volt_table = lp8788_aldo1_vtbl,
  471. .type = REGULATOR_VOLTAGE,
  472. .owner = THIS_MODULE,
  473. .vsel_reg = LP8788_ALDO1_VOUT,
  474. .vsel_mask = LP8788_VOUT_1BIT_M,
  475. .enable_reg = LP8788_EN_LDO_B,
  476. .enable_mask = LP8788_EN_ALDO1_M,
  477. },
  478. {
  479. .name = "aldo2",
  480. .id = ALDO2,
  481. .ops = &lp8788_ldo_voltage_fixed_ops,
  482. .n_voltages = 1,
  483. .type = REGULATOR_VOLTAGE,
  484. .owner = THIS_MODULE,
  485. .enable_reg = LP8788_EN_LDO_B,
  486. .enable_mask = LP8788_EN_ALDO2_M,
  487. },
  488. {
  489. .name = "aldo3",
  490. .id = ALDO3,
  491. .ops = &lp8788_ldo_voltage_fixed_ops,
  492. .n_voltages = 1,
  493. .type = REGULATOR_VOLTAGE,
  494. .owner = THIS_MODULE,
  495. .enable_reg = LP8788_EN_LDO_B,
  496. .enable_mask = LP8788_EN_ALDO3_M,
  497. },
  498. {
  499. .name = "aldo4",
  500. .id = ALDO4,
  501. .ops = &lp8788_ldo_voltage_fixed_ops,
  502. .n_voltages = 1,
  503. .type = REGULATOR_VOLTAGE,
  504. .owner = THIS_MODULE,
  505. .enable_reg = LP8788_EN_LDO_B,
  506. .enable_mask = LP8788_EN_ALDO4_M,
  507. },
  508. {
  509. .name = "aldo5",
  510. .id = ALDO5,
  511. .ops = &lp8788_ldo_voltage_fixed_ops,
  512. .n_voltages = 1,
  513. .type = REGULATOR_VOLTAGE,
  514. .owner = THIS_MODULE,
  515. .enable_reg = LP8788_EN_LDO_C,
  516. .enable_mask = LP8788_EN_ALDO5_M,
  517. },
  518. {
  519. .name = "aldo6",
  520. .id = ALDO6,
  521. .ops = &lp8788_ldo_voltage_table_ops,
  522. .n_voltages = ARRAY_SIZE(lp8788_dldo578_aldo6_vtbl),
  523. .volt_table = lp8788_dldo578_aldo6_vtbl,
  524. .type = REGULATOR_VOLTAGE,
  525. .owner = THIS_MODULE,
  526. .vsel_reg = LP8788_ALDO6_VOUT,
  527. .vsel_mask = LP8788_VOUT_4BIT_M,
  528. .enable_reg = LP8788_EN_LDO_C,
  529. .enable_mask = LP8788_EN_ALDO6_M,
  530. },
  531. {
  532. .name = "aldo7",
  533. .id = ALDO7,
  534. .ops = &lp8788_ldo_voltage_table_ops,
  535. .n_voltages = ARRAY_SIZE(lp8788_aldo7_vtbl),
  536. .volt_table = lp8788_aldo7_vtbl,
  537. .type = REGULATOR_VOLTAGE,
  538. .owner = THIS_MODULE,
  539. .vsel_reg = LP8788_ALDO7_VOUT,
  540. .vsel_mask = LP8788_VOUT_3BIT_M,
  541. .enable_reg = LP8788_EN_LDO_C,
  542. .enable_mask = LP8788_EN_ALDO7_M,
  543. },
  544. {
  545. .name = "aldo8",
  546. .id = ALDO8,
  547. .ops = &lp8788_ldo_voltage_fixed_ops,
  548. .n_voltages = 1,
  549. .type = REGULATOR_VOLTAGE,
  550. .owner = THIS_MODULE,
  551. .enable_reg = LP8788_EN_LDO_C,
  552. .enable_mask = LP8788_EN_ALDO8_M,
  553. },
  554. {
  555. .name = "aldo9",
  556. .id = ALDO9,
  557. .ops = &lp8788_ldo_voltage_fixed_ops,
  558. .n_voltages = 1,
  559. .type = REGULATOR_VOLTAGE,
  560. .owner = THIS_MODULE,
  561. .enable_reg = LP8788_EN_LDO_C,
  562. .enable_mask = LP8788_EN_ALDO9_M,
  563. },
  564. {
  565. .name = "aldo10",
  566. .id = ALDO10,
  567. .ops = &lp8788_ldo_voltage_fixed_ops,
  568. .n_voltages = 1,
  569. .type = REGULATOR_VOLTAGE,
  570. .owner = THIS_MODULE,
  571. .enable_reg = LP8788_EN_LDO_C,
  572. .enable_mask = LP8788_EN_ALDO10_M,
  573. },
  574. };
  575. static int lp8788_gpio_request_ldo_en(struct lp8788_ldo *ldo,
  576. enum lp8788_ext_ldo_en_id id)
  577. {
  578. struct device *dev = ldo->lp->dev;
  579. struct lp8788_ldo_enable_pin *pin = ldo->en_pin;
  580. int ret, gpio, pinstate;
  581. char *name[] = {
  582. [EN_ALDO1] = "LP8788_EN_ALDO1",
  583. [EN_ALDO234] = "LP8788_EN_ALDO234",
  584. [EN_ALDO5] = "LP8788_EN_ALDO5",
  585. [EN_ALDO7] = "LP8788_EN_ALDO7",
  586. [EN_DLDO7] = "LP8788_EN_DLDO7",
  587. [EN_DLDO911] = "LP8788_EN_DLDO911",
  588. };
  589. gpio = pin->gpio;
  590. if (!gpio_is_valid(gpio)) {
  591. dev_err(dev, "invalid gpio: %d\n", gpio);
  592. return -EINVAL;
  593. }
  594. pinstate = pin->init_state;
  595. ret = devm_gpio_request_one(dev, gpio, pinstate, name[id]);
  596. if (ret == -EBUSY) {
  597. dev_warn(dev, "gpio%d already used\n", gpio);
  598. return 0;
  599. }
  600. return ret;
  601. }
  602. static int lp8788_config_ldo_enable_mode(struct lp8788_ldo *ldo,
  603. enum lp8788_ldo_id id)
  604. {
  605. int ret;
  606. struct lp8788 *lp = ldo->lp;
  607. struct lp8788_platform_data *pdata = lp->pdata;
  608. enum lp8788_ext_ldo_en_id enable_id;
  609. u8 en_mask[] = {
  610. [EN_ALDO1] = LP8788_EN_SEL_ALDO1_M,
  611. [EN_ALDO234] = LP8788_EN_SEL_ALDO234_M,
  612. [EN_ALDO5] = LP8788_EN_SEL_ALDO5_M,
  613. [EN_ALDO7] = LP8788_EN_SEL_ALDO7_M,
  614. [EN_DLDO7] = LP8788_EN_SEL_DLDO7_M,
  615. [EN_DLDO911] = LP8788_EN_SEL_DLDO911_M,
  616. };
  617. switch (id) {
  618. case DLDO7:
  619. enable_id = EN_DLDO7;
  620. break;
  621. case DLDO9:
  622. case DLDO11:
  623. enable_id = EN_DLDO911;
  624. break;
  625. case ALDO1:
  626. enable_id = EN_ALDO1;
  627. break;
  628. case ALDO2 ... ALDO4:
  629. enable_id = EN_ALDO234;
  630. break;
  631. case ALDO5:
  632. enable_id = EN_ALDO5;
  633. break;
  634. case ALDO7:
  635. enable_id = EN_ALDO7;
  636. break;
  637. default:
  638. return 0;
  639. }
  640. /* if no platform data for ldo pin, then set default enable mode */
  641. if (!pdata || !pdata->ldo_pin || !pdata->ldo_pin[enable_id])
  642. goto set_default_ldo_enable_mode;
  643. ldo->en_pin = pdata->ldo_pin[enable_id];
  644. ret = lp8788_gpio_request_ldo_en(ldo, enable_id);
  645. if (ret)
  646. goto set_default_ldo_enable_mode;
  647. return ret;
  648. set_default_ldo_enable_mode:
  649. return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], 0);
  650. }
  651. static int lp8788_dldo_probe(struct platform_device *pdev)
  652. {
  653. struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
  654. int id = pdev->id;
  655. struct lp8788_ldo *ldo;
  656. struct regulator_config cfg = { };
  657. struct regulator_dev *rdev;
  658. int ret;
  659. ldo = devm_kzalloc(lp->dev, sizeof(struct lp8788_ldo), GFP_KERNEL);
  660. if (!ldo)
  661. return -ENOMEM;
  662. ldo->lp = lp;
  663. ret = lp8788_config_ldo_enable_mode(ldo, lp8788_dldo_id[id]);
  664. if (ret)
  665. return ret;
  666. cfg.dev = lp->dev;
  667. cfg.init_data = lp->pdata ? lp->pdata->dldo_data[id] : NULL;
  668. cfg.driver_data = ldo;
  669. cfg.regmap = lp->regmap;
  670. rdev = regulator_register(&lp8788_dldo_desc[id], &cfg);
  671. if (IS_ERR(rdev)) {
  672. ret = PTR_ERR(rdev);
  673. dev_err(lp->dev, "DLDO%d regulator register err = %d\n",
  674. id + 1, ret);
  675. return ret;
  676. }
  677. ldo->regulator = rdev;
  678. platform_set_drvdata(pdev, ldo);
  679. return 0;
  680. }
  681. static int lp8788_dldo_remove(struct platform_device *pdev)
  682. {
  683. struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
  684. platform_set_drvdata(pdev, NULL);
  685. regulator_unregister(ldo->regulator);
  686. return 0;
  687. }
  688. static struct platform_driver lp8788_dldo_driver = {
  689. .probe = lp8788_dldo_probe,
  690. .remove = lp8788_dldo_remove,
  691. .driver = {
  692. .name = LP8788_DEV_DLDO,
  693. .owner = THIS_MODULE,
  694. },
  695. };
  696. static int lp8788_aldo_probe(struct platform_device *pdev)
  697. {
  698. struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
  699. int id = pdev->id;
  700. struct lp8788_ldo *ldo;
  701. struct regulator_config cfg = { };
  702. struct regulator_dev *rdev;
  703. int ret;
  704. ldo = devm_kzalloc(lp->dev, sizeof(struct lp8788_ldo), GFP_KERNEL);
  705. if (!ldo)
  706. return -ENOMEM;
  707. ldo->lp = lp;
  708. ret = lp8788_config_ldo_enable_mode(ldo, lp8788_aldo_id[id]);
  709. if (ret)
  710. return ret;
  711. cfg.dev = lp->dev;
  712. cfg.init_data = lp->pdata ? lp->pdata->aldo_data[id] : NULL;
  713. cfg.driver_data = ldo;
  714. cfg.regmap = lp->regmap;
  715. rdev = regulator_register(&lp8788_aldo_desc[id], &cfg);
  716. if (IS_ERR(rdev)) {
  717. ret = PTR_ERR(rdev);
  718. dev_err(lp->dev, "ALDO%d regulator register err = %d\n",
  719. id + 1, ret);
  720. return ret;
  721. }
  722. ldo->regulator = rdev;
  723. platform_set_drvdata(pdev, ldo);
  724. return 0;
  725. }
  726. static int lp8788_aldo_remove(struct platform_device *pdev)
  727. {
  728. struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
  729. platform_set_drvdata(pdev, NULL);
  730. regulator_unregister(ldo->regulator);
  731. return 0;
  732. }
  733. static struct platform_driver lp8788_aldo_driver = {
  734. .probe = lp8788_aldo_probe,
  735. .remove = lp8788_aldo_remove,
  736. .driver = {
  737. .name = LP8788_DEV_ALDO,
  738. .owner = THIS_MODULE,
  739. },
  740. };
  741. static int __init lp8788_ldo_init(void)
  742. {
  743. int ret;
  744. ret = platform_driver_register(&lp8788_dldo_driver);
  745. if (ret)
  746. return ret;
  747. return platform_driver_register(&lp8788_aldo_driver);
  748. }
  749. subsys_initcall(lp8788_ldo_init);
  750. static void __exit lp8788_ldo_exit(void)
  751. {
  752. platform_driver_unregister(&lp8788_aldo_driver);
  753. platform_driver_unregister(&lp8788_dldo_driver);
  754. }
  755. module_exit(lp8788_ldo_exit);
  756. MODULE_DESCRIPTION("TI LP8788 LDO Driver");
  757. MODULE_AUTHOR("Milo Kim");
  758. MODULE_LICENSE("GPL");
  759. MODULE_ALIAS("platform:lp8788-dldo");
  760. MODULE_ALIAS("platform:lp8788-aldo");