bcm590xx-regulator.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Broadcom BCM590xx regulator driver
  4. *
  5. * Copyright 2014 Linaro Limited
  6. * Author: Matt Porter <mporter@linaro.org>
  7. */
  8. #include <linux/err.h>
  9. #include <linux/init.h>
  10. #include <linux/kernel.h>
  11. #include <linux/mfd/bcm590xx.h>
  12. #include <linux/module.h>
  13. #include <linux/of.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/regulator/driver.h>
  16. #include <linux/regulator/machine.h>
  17. #include <linux/regulator/of_regulator.h>
  18. #include <linux/slab.h>
  19. #define BCM590XX_REG_ENABLE BIT(7)
  20. #define BCM590XX_VBUS_ENABLE BIT(2)
  21. #define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3)
  22. #define BCM590XX_SR_VSEL_MASK GENMASK(5, 0)
  23. enum bcm590xx_reg_type {
  24. BCM590XX_REG_TYPE_LDO,
  25. BCM590XX_REG_TYPE_GPLDO,
  26. BCM590XX_REG_TYPE_SR,
  27. BCM590XX_REG_TYPE_VBUS
  28. };
  29. struct bcm590xx_reg_data {
  30. enum bcm590xx_reg_type type;
  31. enum bcm590xx_regmap_type regmap;
  32. const struct regulator_desc desc;
  33. };
  34. struct bcm590xx_reg {
  35. struct bcm590xx *mfd;
  36. unsigned int n_regulators;
  37. const struct bcm590xx_reg_data *regs;
  38. };
  39. static const struct regulator_ops bcm590xx_ops_ldo = {
  40. .is_enabled = regulator_is_enabled_regmap,
  41. .enable = regulator_enable_regmap,
  42. .disable = regulator_disable_regmap,
  43. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  44. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  45. .list_voltage = regulator_list_voltage_table,
  46. .map_voltage = regulator_map_voltage_iterate,
  47. };
  48. /*
  49. * LDO ops without voltage selection, used for MICLDO on BCM59054.
  50. * (These are currently the same as VBUS ops, but will be different
  51. * in the future once full PMMODE support is implemented.)
  52. */
  53. static const struct regulator_ops bcm590xx_ops_ldo_novolt = {
  54. .is_enabled = regulator_is_enabled_regmap,
  55. .enable = regulator_enable_regmap,
  56. .disable = regulator_disable_regmap,
  57. };
  58. static const struct regulator_ops bcm590xx_ops_dcdc = {
  59. .is_enabled = regulator_is_enabled_regmap,
  60. .enable = regulator_enable_regmap,
  61. .disable = regulator_disable_regmap,
  62. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  63. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  64. .list_voltage = regulator_list_voltage_linear_range,
  65. .map_voltage = regulator_map_voltage_linear_range,
  66. };
  67. static const struct regulator_ops bcm590xx_ops_vbus = {
  68. .is_enabled = regulator_is_enabled_regmap,
  69. .enable = regulator_enable_regmap,
  70. .disable = regulator_disable_regmap,
  71. };
  72. #define BCM590XX_REG_DESC(_model, _name, _name_lower) \
  73. .id = _model##_REG_##_name, \
  74. .name = #_name_lower, \
  75. .of_match = of_match_ptr(#_name_lower), \
  76. .regulators_node = of_match_ptr("regulators"), \
  77. .type = REGULATOR_VOLTAGE, \
  78. .owner = THIS_MODULE \
  79. #define BCM590XX_LDO_DESC(_model, _model_lower, _name, _name_lower, _table) \
  80. BCM590XX_REG_DESC(_model, _name, _name_lower), \
  81. .ops = &bcm590xx_ops_ldo, \
  82. .n_voltages = ARRAY_SIZE(_model_lower##_##_table), \
  83. .volt_table = _model_lower##_##_table, \
  84. .vsel_reg = _model##_##_name##CTRL, \
  85. .vsel_mask = BCM590XX_LDO_VSEL_MASK, \
  86. .enable_reg = _model##_##_name##PMCTRL1, \
  87. .enable_mask = BCM590XX_REG_ENABLE, \
  88. .enable_is_inverted = true
  89. #define BCM590XX_SR_DESC(_model, _model_lower, _name, _name_lower, _ranges) \
  90. BCM590XX_REG_DESC(_model, _name, _name_lower), \
  91. .ops = &bcm590xx_ops_dcdc, \
  92. .n_voltages = 64, \
  93. .linear_ranges = _model_lower##_##_ranges, \
  94. .n_linear_ranges = ARRAY_SIZE(_model_lower##_##_ranges), \
  95. .vsel_reg = _model##_##_name##VOUT1, \
  96. .vsel_mask = BCM590XX_SR_VSEL_MASK, \
  97. .enable_reg = _model##_##_name##PMCTRL1, \
  98. .enable_mask = BCM590XX_REG_ENABLE, \
  99. .enable_is_inverted = true
  100. #define BCM59056_REG_DESC(_name, _name_lower) \
  101. BCM590XX_REG_DESC(BCM59056, _name, _name_lower)
  102. #define BCM59056_LDO_DESC(_name, _name_lower, _table) \
  103. BCM590XX_LDO_DESC(BCM59056, bcm59056, _name, _name_lower, _table)
  104. #define BCM59056_SR_DESC(_name, _name_lower, _ranges) \
  105. BCM590XX_SR_DESC(BCM59056, bcm59056, _name, _name_lower, _ranges)
  106. #define BCM59054_REG_DESC(_name, _name_lower) \
  107. BCM590XX_REG_DESC(BCM59054, _name, _name_lower)
  108. #define BCM59054_LDO_DESC(_name, _name_lower, _table) \
  109. BCM590XX_LDO_DESC(BCM59054, bcm59054, _name, _name_lower, _table)
  110. #define BCM59054_SR_DESC(_name, _name_lower, _ranges) \
  111. BCM590XX_SR_DESC(BCM59054, bcm59054, _name, _name_lower, _ranges)
  112. /* BCM59056 data */
  113. /* I2C slave 0 registers */
  114. #define BCM59056_RFLDOPMCTRL1 0x60
  115. #define BCM59056_CAMLDO1PMCTRL1 0x62
  116. #define BCM59056_CAMLDO2PMCTRL1 0x64
  117. #define BCM59056_SIMLDO1PMCTRL1 0x66
  118. #define BCM59056_SIMLDO2PMCTRL1 0x68
  119. #define BCM59056_SDLDOPMCTRL1 0x6a
  120. #define BCM59056_SDXLDOPMCTRL1 0x6c
  121. #define BCM59056_MMCLDO1PMCTRL1 0x6e
  122. #define BCM59056_MMCLDO2PMCTRL1 0x70
  123. #define BCM59056_AUDLDOPMCTRL1 0x72
  124. #define BCM59056_MICLDOPMCTRL1 0x74
  125. #define BCM59056_USBLDOPMCTRL1 0x76
  126. #define BCM59056_VIBLDOPMCTRL1 0x78
  127. #define BCM59056_IOSR1PMCTRL1 0x7a
  128. #define BCM59056_IOSR2PMCTRL1 0x7c
  129. #define BCM59056_CSRPMCTRL1 0x7e
  130. #define BCM59056_SDSR1PMCTRL1 0x82
  131. #define BCM59056_SDSR2PMCTRL1 0x86
  132. #define BCM59056_MSRPMCTRL1 0x8a
  133. #define BCM59056_VSRPMCTRL1 0x8e
  134. #define BCM59056_RFLDOCTRL 0x96
  135. #define BCM59056_CAMLDO1CTRL 0x97
  136. #define BCM59056_CAMLDO2CTRL 0x98
  137. #define BCM59056_SIMLDO1CTRL 0x99
  138. #define BCM59056_SIMLDO2CTRL 0x9a
  139. #define BCM59056_SDLDOCTRL 0x9b
  140. #define BCM59056_SDXLDOCTRL 0x9c
  141. #define BCM59056_MMCLDO1CTRL 0x9d
  142. #define BCM59056_MMCLDO2CTRL 0x9e
  143. #define BCM59056_AUDLDOCTRL 0x9f
  144. #define BCM59056_MICLDOCTRL 0xa0
  145. #define BCM59056_USBLDOCTRL 0xa1
  146. #define BCM59056_VIBLDOCTRL 0xa2
  147. #define BCM59056_CSRVOUT1 0xc0
  148. #define BCM59056_IOSR1VOUT1 0xc3
  149. #define BCM59056_IOSR2VOUT1 0xc6
  150. #define BCM59056_MSRVOUT1 0xc9
  151. #define BCM59056_SDSR1VOUT1 0xcc
  152. #define BCM59056_SDSR2VOUT1 0xcf
  153. #define BCM59056_VSRVOUT1 0xd2
  154. /* I2C slave 1 registers */
  155. #define BCM59056_GPLDO5PMCTRL1 0x16
  156. #define BCM59056_GPLDO6PMCTRL1 0x18
  157. #define BCM59056_GPLDO1CTRL 0x1a
  158. #define BCM59056_GPLDO2CTRL 0x1b
  159. #define BCM59056_GPLDO3CTRL 0x1c
  160. #define BCM59056_GPLDO4CTRL 0x1d
  161. #define BCM59056_GPLDO5CTRL 0x1e
  162. #define BCM59056_GPLDO6CTRL 0x1f
  163. #define BCM59056_OTG_CTRL 0x40
  164. #define BCM59056_GPLDO1PMCTRL1 0x57
  165. #define BCM59056_GPLDO2PMCTRL1 0x59
  166. #define BCM59056_GPLDO3PMCTRL1 0x5b
  167. #define BCM59056_GPLDO4PMCTRL1 0x5d
  168. /*
  169. * RFLDO to VSR regulators are
  170. * accessed via I2C slave 0
  171. */
  172. /* LDO regulator IDs */
  173. #define BCM59056_REG_RFLDO 0
  174. #define BCM59056_REG_CAMLDO1 1
  175. #define BCM59056_REG_CAMLDO2 2
  176. #define BCM59056_REG_SIMLDO1 3
  177. #define BCM59056_REG_SIMLDO2 4
  178. #define BCM59056_REG_SDLDO 5
  179. #define BCM59056_REG_SDXLDO 6
  180. #define BCM59056_REG_MMCLDO1 7
  181. #define BCM59056_REG_MMCLDO2 8
  182. #define BCM59056_REG_AUDLDO 9
  183. #define BCM59056_REG_MICLDO 10
  184. #define BCM59056_REG_USBLDO 11
  185. #define BCM59056_REG_VIBLDO 12
  186. /* DCDC regulator IDs */
  187. #define BCM59056_REG_CSR 13
  188. #define BCM59056_REG_IOSR1 14
  189. #define BCM59056_REG_IOSR2 15
  190. #define BCM59056_REG_MSR 16
  191. #define BCM59056_REG_SDSR1 17
  192. #define BCM59056_REG_SDSR2 18
  193. #define BCM59056_REG_VSR 19
  194. /*
  195. * GPLDO1 to VBUS regulators are
  196. * accessed via I2C slave 1
  197. */
  198. #define BCM59056_REG_GPLDO1 20
  199. #define BCM59056_REG_GPLDO2 21
  200. #define BCM59056_REG_GPLDO3 22
  201. #define BCM59056_REG_GPLDO4 23
  202. #define BCM59056_REG_GPLDO5 24
  203. #define BCM59056_REG_GPLDO6 25
  204. #define BCM59056_REG_VBUS 26
  205. #define BCM59056_NUM_REGS 27
  206. /* LDO group A: supported voltages in microvolts */
  207. static const unsigned int bcm59056_ldo_a_table[] = {
  208. 1200000, 1800000, 2500000, 2700000, 2800000,
  209. 2900000, 3000000, 3300000,
  210. };
  211. /* LDO group C: supported voltages in microvolts */
  212. static const unsigned int bcm59056_ldo_c_table[] = {
  213. 3100000, 1800000, 2500000, 2700000, 2800000,
  214. 2900000, 3000000, 3300000,
  215. };
  216. /* DCDC group CSR: supported voltages in microvolts */
  217. static const struct linear_range bcm59056_dcdc_csr_ranges[] = {
  218. REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000),
  219. REGULATOR_LINEAR_RANGE(1360000, 51, 55, 20000),
  220. REGULATOR_LINEAR_RANGE(900000, 56, 63, 0),
  221. };
  222. /* DCDC group IOSR1: supported voltages in microvolts */
  223. static const struct linear_range bcm59056_dcdc_iosr1_ranges[] = {
  224. REGULATOR_LINEAR_RANGE(860000, 2, 51, 10000),
  225. REGULATOR_LINEAR_RANGE(1500000, 52, 52, 0),
  226. REGULATOR_LINEAR_RANGE(1800000, 53, 53, 0),
  227. REGULATOR_LINEAR_RANGE(900000, 54, 63, 0),
  228. };
  229. /* DCDC group SDSR1: supported voltages in microvolts */
  230. static const struct linear_range bcm59056_dcdc_sdsr1_ranges[] = {
  231. REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000),
  232. REGULATOR_LINEAR_RANGE(1340000, 51, 51, 0),
  233. REGULATOR_LINEAR_RANGE(900000, 52, 63, 0),
  234. };
  235. static const struct bcm590xx_reg_data bcm59056_regs[BCM59056_NUM_REGS] = {
  236. {
  237. .type = BCM590XX_REG_TYPE_LDO,
  238. .regmap = BCM590XX_REGMAP_PRI,
  239. .desc = {
  240. BCM59056_LDO_DESC(RFLDO, rfldo, ldo_a_table),
  241. },
  242. },
  243. {
  244. .type = BCM590XX_REG_TYPE_LDO,
  245. .regmap = BCM590XX_REGMAP_PRI,
  246. .desc = {
  247. BCM59056_LDO_DESC(CAMLDO1, camldo1, ldo_c_table),
  248. },
  249. },
  250. {
  251. .type = BCM590XX_REG_TYPE_LDO,
  252. .regmap = BCM590XX_REGMAP_PRI,
  253. .desc = {
  254. BCM59056_LDO_DESC(CAMLDO2, camldo2, ldo_c_table),
  255. },
  256. },
  257. {
  258. .type = BCM590XX_REG_TYPE_LDO,
  259. .regmap = BCM590XX_REGMAP_PRI,
  260. .desc = {
  261. BCM59056_LDO_DESC(SIMLDO1, simldo1, ldo_a_table),
  262. },
  263. },
  264. {
  265. .type = BCM590XX_REG_TYPE_LDO,
  266. .regmap = BCM590XX_REGMAP_PRI,
  267. .desc = {
  268. BCM59056_LDO_DESC(SIMLDO2, simldo2, ldo_a_table),
  269. },
  270. },
  271. {
  272. .type = BCM590XX_REG_TYPE_LDO,
  273. .regmap = BCM590XX_REGMAP_PRI,
  274. .desc = {
  275. BCM59056_LDO_DESC(SDLDO, sdldo, ldo_c_table),
  276. },
  277. },
  278. {
  279. .type = BCM590XX_REG_TYPE_LDO,
  280. .regmap = BCM590XX_REGMAP_PRI,
  281. .desc = {
  282. BCM59056_LDO_DESC(SDXLDO, sdxldo, ldo_a_table),
  283. },
  284. },
  285. {
  286. .type = BCM590XX_REG_TYPE_LDO,
  287. .regmap = BCM590XX_REGMAP_PRI,
  288. .desc = {
  289. BCM59056_LDO_DESC(MMCLDO1, mmcldo1, ldo_a_table),
  290. },
  291. },
  292. {
  293. .type = BCM590XX_REG_TYPE_LDO,
  294. .regmap = BCM590XX_REGMAP_PRI,
  295. .desc = {
  296. BCM59056_LDO_DESC(MMCLDO2, mmcldo2, ldo_a_table),
  297. },
  298. },
  299. {
  300. .type = BCM590XX_REG_TYPE_LDO,
  301. .regmap = BCM590XX_REGMAP_PRI,
  302. .desc = {
  303. BCM59056_LDO_DESC(AUDLDO, audldo, ldo_a_table),
  304. },
  305. },
  306. {
  307. .type = BCM590XX_REG_TYPE_LDO,
  308. .regmap = BCM590XX_REGMAP_PRI,
  309. .desc = {
  310. BCM59056_LDO_DESC(MICLDO, micldo, ldo_a_table),
  311. },
  312. },
  313. {
  314. .type = BCM590XX_REG_TYPE_LDO,
  315. .regmap = BCM590XX_REGMAP_PRI,
  316. .desc = {
  317. BCM59056_LDO_DESC(USBLDO, usbldo, ldo_a_table),
  318. },
  319. },
  320. {
  321. .type = BCM590XX_REG_TYPE_LDO,
  322. .regmap = BCM590XX_REGMAP_PRI,
  323. .desc = {
  324. BCM59056_LDO_DESC(VIBLDO, vibldo, ldo_c_table),
  325. },
  326. },
  327. {
  328. .type = BCM590XX_REG_TYPE_SR,
  329. .regmap = BCM590XX_REGMAP_PRI,
  330. .desc = {
  331. BCM59056_SR_DESC(CSR, csr, dcdc_csr_ranges),
  332. },
  333. },
  334. {
  335. .type = BCM590XX_REG_TYPE_SR,
  336. .regmap = BCM590XX_REGMAP_PRI,
  337. .desc = {
  338. BCM59056_SR_DESC(IOSR1, iosr1, dcdc_iosr1_ranges),
  339. },
  340. },
  341. {
  342. .type = BCM590XX_REG_TYPE_SR,
  343. .regmap = BCM590XX_REGMAP_PRI,
  344. .desc = {
  345. BCM59056_SR_DESC(IOSR2, iosr2, dcdc_iosr1_ranges),
  346. },
  347. },
  348. {
  349. .type = BCM590XX_REG_TYPE_SR,
  350. .regmap = BCM590XX_REGMAP_PRI,
  351. .desc = {
  352. BCM59056_SR_DESC(MSR, msr, dcdc_iosr1_ranges),
  353. },
  354. },
  355. {
  356. .type = BCM590XX_REG_TYPE_SR,
  357. .regmap = BCM590XX_REGMAP_PRI,
  358. .desc = {
  359. BCM59056_SR_DESC(SDSR1, sdsr1, dcdc_sdsr1_ranges),
  360. },
  361. },
  362. {
  363. .type = BCM590XX_REG_TYPE_SR,
  364. .regmap = BCM590XX_REGMAP_PRI,
  365. .desc = {
  366. BCM59056_SR_DESC(SDSR2, sdsr2, dcdc_iosr1_ranges),
  367. },
  368. },
  369. {
  370. .type = BCM590XX_REG_TYPE_SR,
  371. .regmap = BCM590XX_REGMAP_PRI,
  372. .desc = {
  373. BCM59056_SR_DESC(VSR, vsr, dcdc_iosr1_ranges),
  374. },
  375. },
  376. {
  377. .type = BCM590XX_REG_TYPE_GPLDO,
  378. .regmap = BCM590XX_REGMAP_SEC,
  379. .desc = {
  380. BCM59056_LDO_DESC(GPLDO1, gpldo1, ldo_a_table),
  381. },
  382. },
  383. {
  384. .type = BCM590XX_REG_TYPE_GPLDO,
  385. .regmap = BCM590XX_REGMAP_SEC,
  386. .desc = {
  387. BCM59056_LDO_DESC(GPLDO2, gpldo2, ldo_a_table),
  388. },
  389. },
  390. {
  391. .type = BCM590XX_REG_TYPE_GPLDO,
  392. .regmap = BCM590XX_REGMAP_SEC,
  393. .desc = {
  394. BCM59056_LDO_DESC(GPLDO3, gpldo3, ldo_a_table),
  395. },
  396. },
  397. {
  398. .type = BCM590XX_REG_TYPE_GPLDO,
  399. .regmap = BCM590XX_REGMAP_SEC,
  400. .desc = {
  401. BCM59056_LDO_DESC(GPLDO4, gpldo4, ldo_a_table),
  402. },
  403. },
  404. {
  405. .type = BCM590XX_REG_TYPE_GPLDO,
  406. .regmap = BCM590XX_REGMAP_SEC,
  407. .desc = {
  408. BCM59056_LDO_DESC(GPLDO5, gpldo5, ldo_a_table),
  409. },
  410. },
  411. {
  412. .type = BCM590XX_REG_TYPE_GPLDO,
  413. .regmap = BCM590XX_REGMAP_SEC,
  414. .desc = {
  415. BCM59056_LDO_DESC(GPLDO6, gpldo6, ldo_a_table),
  416. },
  417. },
  418. {
  419. .type = BCM590XX_REG_TYPE_VBUS,
  420. .regmap = BCM590XX_REGMAP_SEC,
  421. .desc = {
  422. BCM59056_REG_DESC(VBUS, vbus),
  423. .ops = &bcm590xx_ops_vbus,
  424. .n_voltages = 1,
  425. .fixed_uV = 5000000,
  426. .enable_reg = BCM59056_OTG_CTRL,
  427. .enable_mask = BCM590XX_VBUS_ENABLE,
  428. },
  429. },
  430. };
  431. /* BCM59054 data */
  432. /* I2C slave 0 registers */
  433. #define BCM59054_RFLDOPMCTRL1 0x60
  434. #define BCM59054_CAMLDO1PMCTRL1 0x62
  435. #define BCM59054_CAMLDO2PMCTRL1 0x64
  436. #define BCM59054_SIMLDO1PMCTRL1 0x66
  437. #define BCM59054_SIMLDO2PMCTRL1 0x68
  438. #define BCM59054_SDLDOPMCTRL1 0x6a
  439. #define BCM59054_SDXLDOPMCTRL1 0x6c
  440. #define BCM59054_MMCLDO1PMCTRL1 0x6e
  441. #define BCM59054_MMCLDO2PMCTRL1 0x70
  442. #define BCM59054_AUDLDOPMCTRL1 0x72
  443. #define BCM59054_MICLDOPMCTRL1 0x74
  444. #define BCM59054_USBLDOPMCTRL1 0x76
  445. #define BCM59054_VIBLDOPMCTRL1 0x78
  446. #define BCM59054_IOSR1PMCTRL1 0x7a
  447. #define BCM59054_IOSR2PMCTRL1 0x7c
  448. #define BCM59054_CSRPMCTRL1 0x7e
  449. #define BCM59054_SDSR1PMCTRL1 0x82
  450. #define BCM59054_SDSR2PMCTRL1 0x86
  451. #define BCM59054_MMSRPMCTRL1 0x8a
  452. #define BCM59054_VSRPMCTRL1 0x8e
  453. #define BCM59054_RFLDOCTRL 0x96
  454. #define BCM59054_CAMLDO1CTRL 0x97
  455. #define BCM59054_CAMLDO2CTRL 0x98
  456. #define BCM59054_SIMLDO1CTRL 0x99
  457. #define BCM59054_SIMLDO2CTRL 0x9a
  458. #define BCM59054_SDLDOCTRL 0x9b
  459. #define BCM59054_SDXLDOCTRL 0x9c
  460. #define BCM59054_MMCLDO1CTRL 0x9d
  461. #define BCM59054_MMCLDO2CTRL 0x9e
  462. #define BCM59054_AUDLDOCTRL 0x9f
  463. #define BCM59054_MICLDOCTRL 0xa0
  464. #define BCM59054_USBLDOCTRL 0xa1
  465. #define BCM59054_VIBLDOCTRL 0xa2
  466. #define BCM59054_CSRVOUT1 0xc0
  467. #define BCM59054_IOSR1VOUT1 0xc3
  468. #define BCM59054_IOSR2VOUT1 0xc6
  469. #define BCM59054_MMSRVOUT1 0xc9
  470. #define BCM59054_SDSR1VOUT1 0xcc
  471. #define BCM59054_SDSR2VOUT1 0xcf
  472. #define BCM59054_VSRVOUT1 0xd2
  473. /* I2C slave 1 registers */
  474. #define BCM59054_LVLDO1PMCTRL1 0x16
  475. #define BCM59054_LVLDO2PMCTRL1 0x18
  476. #define BCM59054_GPLDO1CTRL 0x1a
  477. #define BCM59054_GPLDO2CTRL 0x1b
  478. #define BCM59054_GPLDO3CTRL 0x1c
  479. #define BCM59054_TCXLDOCTRL 0x1d
  480. #define BCM59054_LVLDO1CTRL 0x1e
  481. #define BCM59054_LVLDO2CTRL 0x1f
  482. #define BCM59054_OTG_CTRL 0x40
  483. #define BCM59054_GPLDO1PMCTRL1 0x57
  484. #define BCM59054_GPLDO2PMCTRL1 0x59
  485. #define BCM59054_GPLDO3PMCTRL1 0x5b
  486. #define BCM59054_TCXLDOPMCTRL1 0x5d
  487. /*
  488. * RFLDO to VSR regulators are
  489. * accessed via I2C slave 0
  490. */
  491. /* LDO regulator IDs */
  492. #define BCM59054_REG_RFLDO 0
  493. #define BCM59054_REG_CAMLDO1 1
  494. #define BCM59054_REG_CAMLDO2 2
  495. #define BCM59054_REG_SIMLDO1 3
  496. #define BCM59054_REG_SIMLDO2 4
  497. #define BCM59054_REG_SDLDO 5
  498. #define BCM59054_REG_SDXLDO 6
  499. #define BCM59054_REG_MMCLDO1 7
  500. #define BCM59054_REG_MMCLDO2 8
  501. #define BCM59054_REG_AUDLDO 9
  502. #define BCM59054_REG_MICLDO 10
  503. #define BCM59054_REG_USBLDO 11
  504. #define BCM59054_REG_VIBLDO 12
  505. /* DCDC regulator IDs */
  506. #define BCM59054_REG_CSR 13
  507. #define BCM59054_REG_IOSR1 14
  508. #define BCM59054_REG_IOSR2 15
  509. #define BCM59054_REG_MMSR 16
  510. #define BCM59054_REG_SDSR1 17
  511. #define BCM59054_REG_SDSR2 18
  512. #define BCM59054_REG_VSR 19
  513. /*
  514. * GPLDO1 to VBUS regulators are
  515. * accessed via I2C slave 1
  516. */
  517. #define BCM59054_REG_GPLDO1 20
  518. #define BCM59054_REG_GPLDO2 21
  519. #define BCM59054_REG_GPLDO3 22
  520. #define BCM59054_REG_TCXLDO 23
  521. #define BCM59054_REG_LVLDO1 24
  522. #define BCM59054_REG_LVLDO2 25
  523. #define BCM59054_REG_VBUS 26
  524. #define BCM59054_NUM_REGS 27
  525. /* LDO group 1: supported voltages in microvolts */
  526. static const unsigned int bcm59054_ldo_1_table[] = {
  527. 1200000, 1800000, 2500000, 2700000, 2800000,
  528. 2900000, 3000000, 3300000,
  529. };
  530. /* LDO group 2: supported voltages in microvolts */
  531. static const unsigned int bcm59054_ldo_2_table[] = {
  532. 3100000, 1800000, 2500000, 2700000, 2800000,
  533. 2900000, 3000000, 3300000,
  534. };
  535. /* LDO group 3: supported voltages in microvolts */
  536. static const unsigned int bcm59054_ldo_3_table[] = {
  537. 1000000, 1107000, 1143000, 1214000, 1250000,
  538. 1464000, 1500000, 1786000,
  539. };
  540. /* DCDC group SR: supported voltages in microvolts */
  541. static const struct linear_range bcm59054_dcdc_sr_ranges[] = {
  542. REGULATOR_LINEAR_RANGE(0, 0, 1, 0),
  543. REGULATOR_LINEAR_RANGE(860000, 2, 60, 10000),
  544. REGULATOR_LINEAR_RANGE(1500000, 61, 61, 0),
  545. REGULATOR_LINEAR_RANGE(1800000, 62, 62, 0),
  546. REGULATOR_LINEAR_RANGE(900000, 63, 63, 0),
  547. };
  548. /* DCDC group VSR (BCM59054A1): supported voltages in microvolts */
  549. static const struct linear_range bcm59054_dcdc_vsr_a1_ranges[] = {
  550. REGULATOR_LINEAR_RANGE(0, 0, 1, 0),
  551. REGULATOR_LINEAR_RANGE(860000, 2, 59, 10000),
  552. REGULATOR_LINEAR_RANGE(1700000, 60, 60, 0),
  553. REGULATOR_LINEAR_RANGE(1500000, 61, 61, 0),
  554. REGULATOR_LINEAR_RANGE(1800000, 62, 62, 0),
  555. REGULATOR_LINEAR_RANGE(1600000, 63, 63, 0),
  556. };
  557. /* DCDC group CSR: supported voltages in microvolts */
  558. static const struct linear_range bcm59054_dcdc_csr_ranges[] = {
  559. REGULATOR_LINEAR_RANGE(700000, 0, 1, 100000),
  560. REGULATOR_LINEAR_RANGE(860000, 2, 60, 10000),
  561. REGULATOR_LINEAR_RANGE(900000, 61, 63, 0),
  562. };
  563. static const struct bcm590xx_reg_data bcm59054_regs[BCM59054_NUM_REGS] = {
  564. {
  565. .type = BCM590XX_REG_TYPE_LDO,
  566. .regmap = BCM590XX_REGMAP_PRI,
  567. .desc = {
  568. BCM59054_LDO_DESC(RFLDO, rfldo, ldo_1_table),
  569. },
  570. },
  571. {
  572. .type = BCM590XX_REG_TYPE_LDO,
  573. .regmap = BCM590XX_REGMAP_PRI,
  574. .desc = {
  575. BCM59054_LDO_DESC(CAMLDO1, camldo1, ldo_2_table),
  576. },
  577. },
  578. {
  579. .type = BCM590XX_REG_TYPE_LDO,
  580. .regmap = BCM590XX_REGMAP_PRI,
  581. .desc = {
  582. BCM59054_LDO_DESC(CAMLDO2, camldo2, ldo_2_table),
  583. },
  584. },
  585. {
  586. .type = BCM590XX_REG_TYPE_LDO,
  587. .regmap = BCM590XX_REGMAP_PRI,
  588. .desc = {
  589. BCM59054_LDO_DESC(SIMLDO1, simldo1, ldo_1_table),
  590. },
  591. },
  592. {
  593. .type = BCM590XX_REG_TYPE_LDO,
  594. .regmap = BCM590XX_REGMAP_PRI,
  595. .desc = {
  596. BCM59054_LDO_DESC(SIMLDO2, simldo2, ldo_1_table),
  597. },
  598. },
  599. {
  600. .type = BCM590XX_REG_TYPE_LDO,
  601. .regmap = BCM590XX_REGMAP_PRI,
  602. .desc = {
  603. BCM59054_LDO_DESC(SDLDO, sdldo, ldo_2_table),
  604. },
  605. },
  606. {
  607. .type = BCM590XX_REG_TYPE_LDO,
  608. .regmap = BCM590XX_REGMAP_PRI,
  609. .desc = {
  610. BCM59054_LDO_DESC(SDXLDO, sdxldo, ldo_1_table),
  611. },
  612. },
  613. {
  614. .type = BCM590XX_REG_TYPE_LDO,
  615. .regmap = BCM590XX_REGMAP_PRI,
  616. .desc = {
  617. BCM59054_LDO_DESC(MMCLDO1, mmcldo1, ldo_1_table),
  618. },
  619. },
  620. {
  621. .type = BCM590XX_REG_TYPE_LDO,
  622. .regmap = BCM590XX_REGMAP_PRI,
  623. .desc = {
  624. BCM59054_LDO_DESC(MMCLDO2, mmcldo2, ldo_1_table),
  625. },
  626. },
  627. {
  628. .type = BCM590XX_REG_TYPE_LDO,
  629. .regmap = BCM590XX_REGMAP_PRI,
  630. .desc = {
  631. BCM59054_LDO_DESC(AUDLDO, audldo, ldo_1_table),
  632. },
  633. },
  634. {
  635. .type = BCM590XX_REG_TYPE_LDO,
  636. .regmap = BCM590XX_REGMAP_PRI,
  637. .desc = {
  638. BCM59054_REG_DESC(MICLDO, micldo),
  639. .ops = &bcm590xx_ops_ldo_novolt,
  640. /* MICLDO is locked at 1.8V */
  641. .n_voltages = 1,
  642. .fixed_uV = 1800000,
  643. .enable_reg = BCM59054_MICLDOPMCTRL1,
  644. .enable_mask = BCM590XX_REG_ENABLE,
  645. .enable_is_inverted = true,
  646. },
  647. },
  648. {
  649. .type = BCM590XX_REG_TYPE_LDO,
  650. .regmap = BCM590XX_REGMAP_PRI,
  651. .desc = {
  652. BCM59054_LDO_DESC(USBLDO, usbldo, ldo_1_table),
  653. },
  654. },
  655. {
  656. .type = BCM590XX_REG_TYPE_LDO,
  657. .regmap = BCM590XX_REGMAP_PRI,
  658. .desc = {
  659. BCM59054_LDO_DESC(VIBLDO, vibldo, ldo_2_table),
  660. },
  661. },
  662. {
  663. .type = BCM590XX_REG_TYPE_SR,
  664. .regmap = BCM590XX_REGMAP_PRI,
  665. .desc = {
  666. BCM59054_SR_DESC(CSR, csr, dcdc_csr_ranges),
  667. },
  668. },
  669. {
  670. .type = BCM590XX_REG_TYPE_SR,
  671. .regmap = BCM590XX_REGMAP_PRI,
  672. .desc = {
  673. BCM59054_SR_DESC(IOSR1, iosr1, dcdc_sr_ranges),
  674. },
  675. },
  676. {
  677. .type = BCM590XX_REG_TYPE_SR,
  678. .regmap = BCM590XX_REGMAP_PRI,
  679. .desc = {
  680. BCM59054_SR_DESC(IOSR2, iosr2, dcdc_sr_ranges),
  681. },
  682. },
  683. {
  684. .type = BCM590XX_REG_TYPE_SR,
  685. .regmap = BCM590XX_REGMAP_PRI,
  686. .desc = {
  687. BCM59054_SR_DESC(MMSR, mmsr, dcdc_sr_ranges),
  688. },
  689. },
  690. {
  691. .type = BCM590XX_REG_TYPE_SR,
  692. .regmap = BCM590XX_REGMAP_PRI,
  693. .desc = {
  694. BCM59054_SR_DESC(SDSR1, sdsr1, dcdc_sr_ranges),
  695. },
  696. },
  697. {
  698. .type = BCM590XX_REG_TYPE_SR,
  699. .regmap = BCM590XX_REGMAP_PRI,
  700. .desc = {
  701. BCM59054_SR_DESC(SDSR2, sdsr2, dcdc_sr_ranges),
  702. },
  703. },
  704. {
  705. .type = BCM590XX_REG_TYPE_SR,
  706. .regmap = BCM590XX_REGMAP_PRI,
  707. .desc = {
  708. BCM59054_SR_DESC(VSR, vsr, dcdc_sr_ranges),
  709. },
  710. },
  711. {
  712. .type = BCM590XX_REG_TYPE_GPLDO,
  713. .regmap = BCM590XX_REGMAP_SEC,
  714. .desc = {
  715. BCM59054_LDO_DESC(GPLDO1, gpldo1, ldo_1_table),
  716. },
  717. },
  718. {
  719. .type = BCM590XX_REG_TYPE_GPLDO,
  720. .regmap = BCM590XX_REGMAP_SEC,
  721. .desc = {
  722. BCM59054_LDO_DESC(GPLDO2, gpldo2, ldo_1_table),
  723. },
  724. },
  725. {
  726. .type = BCM590XX_REG_TYPE_GPLDO,
  727. .regmap = BCM590XX_REGMAP_SEC,
  728. .desc = {
  729. BCM59054_LDO_DESC(GPLDO3, gpldo3, ldo_1_table),
  730. },
  731. },
  732. {
  733. .type = BCM590XX_REG_TYPE_GPLDO,
  734. .regmap = BCM590XX_REGMAP_SEC,
  735. .desc = {
  736. BCM59054_LDO_DESC(TCXLDO, tcxldo, ldo_1_table),
  737. },
  738. },
  739. {
  740. .type = BCM590XX_REG_TYPE_GPLDO,
  741. .regmap = BCM590XX_REGMAP_SEC,
  742. .desc = {
  743. BCM59054_LDO_DESC(LVLDO1, lvldo1, ldo_3_table),
  744. },
  745. },
  746. {
  747. .type = BCM590XX_REG_TYPE_GPLDO,
  748. .regmap = BCM590XX_REGMAP_SEC,
  749. .desc = {
  750. BCM59054_LDO_DESC(LVLDO2, lvldo2, ldo_3_table),
  751. },
  752. },
  753. {
  754. .type = BCM590XX_REG_TYPE_VBUS,
  755. .regmap = BCM590XX_REGMAP_SEC,
  756. .desc = {
  757. BCM59054_REG_DESC(VBUS, vbus),
  758. .ops = &bcm590xx_ops_vbus,
  759. .n_voltages = 1,
  760. .fixed_uV = 5000000,
  761. .enable_reg = BCM59054_OTG_CTRL,
  762. .enable_mask = BCM590XX_VBUS_ENABLE,
  763. },
  764. },
  765. };
  766. /*
  767. * BCM59054A1 regulators; same as previous revision, but with different
  768. * VSR voltage table.
  769. */
  770. static const struct bcm590xx_reg_data bcm59054_a1_regs[BCM59054_NUM_REGS] = {
  771. {
  772. .type = BCM590XX_REG_TYPE_LDO,
  773. .regmap = BCM590XX_REGMAP_PRI,
  774. .desc = {
  775. BCM59054_LDO_DESC(RFLDO, rfldo, ldo_1_table),
  776. },
  777. },
  778. {
  779. .type = BCM590XX_REG_TYPE_LDO,
  780. .regmap = BCM590XX_REGMAP_PRI,
  781. .desc = {
  782. BCM59054_LDO_DESC(CAMLDO1, camldo1, ldo_2_table),
  783. },
  784. },
  785. {
  786. .type = BCM590XX_REG_TYPE_LDO,
  787. .regmap = BCM590XX_REGMAP_PRI,
  788. .desc = {
  789. BCM59054_LDO_DESC(CAMLDO2, camldo2, ldo_2_table),
  790. },
  791. },
  792. {
  793. .type = BCM590XX_REG_TYPE_LDO,
  794. .regmap = BCM590XX_REGMAP_PRI,
  795. .desc = {
  796. BCM59054_LDO_DESC(SIMLDO1, simldo1, ldo_1_table),
  797. },
  798. },
  799. {
  800. .type = BCM590XX_REG_TYPE_LDO,
  801. .regmap = BCM590XX_REGMAP_PRI,
  802. .desc = {
  803. BCM59054_LDO_DESC(SIMLDO2, simldo2, ldo_1_table),
  804. },
  805. },
  806. {
  807. .type = BCM590XX_REG_TYPE_LDO,
  808. .regmap = BCM590XX_REGMAP_PRI,
  809. .desc = {
  810. BCM59054_LDO_DESC(SDLDO, sdldo, ldo_2_table),
  811. },
  812. },
  813. {
  814. .type = BCM590XX_REG_TYPE_LDO,
  815. .regmap = BCM590XX_REGMAP_PRI,
  816. .desc = {
  817. BCM59054_LDO_DESC(SDXLDO, sdxldo, ldo_1_table),
  818. },
  819. },
  820. {
  821. .type = BCM590XX_REG_TYPE_LDO,
  822. .regmap = BCM590XX_REGMAP_PRI,
  823. .desc = {
  824. BCM59054_LDO_DESC(MMCLDO1, mmcldo1, ldo_1_table),
  825. },
  826. },
  827. {
  828. .type = BCM590XX_REG_TYPE_LDO,
  829. .regmap = BCM590XX_REGMAP_PRI,
  830. .desc = {
  831. BCM59054_LDO_DESC(MMCLDO2, mmcldo2, ldo_1_table),
  832. },
  833. },
  834. {
  835. .type = BCM590XX_REG_TYPE_LDO,
  836. .regmap = BCM590XX_REGMAP_PRI,
  837. .desc = {
  838. BCM59054_LDO_DESC(AUDLDO, audldo, ldo_1_table),
  839. },
  840. },
  841. {
  842. .type = BCM590XX_REG_TYPE_LDO,
  843. .regmap = BCM590XX_REGMAP_PRI,
  844. .desc = {
  845. BCM59054_REG_DESC(MICLDO, micldo),
  846. .ops = &bcm590xx_ops_ldo_novolt,
  847. /* MICLDO is locked at 1.8V */
  848. .n_voltages = 1,
  849. .fixed_uV = 1800000,
  850. .enable_reg = BCM59054_MICLDOPMCTRL1,
  851. .enable_mask = BCM590XX_REG_ENABLE,
  852. .enable_is_inverted = true,
  853. },
  854. },
  855. {
  856. .type = BCM590XX_REG_TYPE_LDO,
  857. .regmap = BCM590XX_REGMAP_PRI,
  858. .desc = {
  859. BCM59054_LDO_DESC(USBLDO, usbldo, ldo_1_table),
  860. },
  861. },
  862. {
  863. .type = BCM590XX_REG_TYPE_LDO,
  864. .regmap = BCM590XX_REGMAP_PRI,
  865. .desc = {
  866. BCM59054_LDO_DESC(VIBLDO, vibldo, ldo_2_table),
  867. },
  868. },
  869. {
  870. .type = BCM590XX_REG_TYPE_SR,
  871. .regmap = BCM590XX_REGMAP_PRI,
  872. .desc = {
  873. BCM59054_SR_DESC(CSR, csr, dcdc_csr_ranges),
  874. },
  875. },
  876. {
  877. .type = BCM590XX_REG_TYPE_SR,
  878. .regmap = BCM590XX_REGMAP_PRI,
  879. .desc = {
  880. BCM59054_SR_DESC(IOSR1, iosr1, dcdc_sr_ranges),
  881. },
  882. },
  883. {
  884. .type = BCM590XX_REG_TYPE_SR,
  885. .regmap = BCM590XX_REGMAP_PRI,
  886. .desc = {
  887. BCM59054_SR_DESC(IOSR2, iosr2, dcdc_sr_ranges),
  888. },
  889. },
  890. {
  891. .type = BCM590XX_REG_TYPE_SR,
  892. .regmap = BCM590XX_REGMAP_PRI,
  893. .desc = {
  894. BCM59054_SR_DESC(MMSR, mmsr, dcdc_sr_ranges),
  895. },
  896. },
  897. {
  898. .type = BCM590XX_REG_TYPE_SR,
  899. .regmap = BCM590XX_REGMAP_PRI,
  900. .desc = {
  901. BCM59054_SR_DESC(SDSR1, sdsr1, dcdc_sr_ranges),
  902. },
  903. },
  904. {
  905. .type = BCM590XX_REG_TYPE_SR,
  906. .regmap = BCM590XX_REGMAP_PRI,
  907. .desc = {
  908. BCM59054_SR_DESC(SDSR2, sdsr2, dcdc_sr_ranges),
  909. },
  910. },
  911. {
  912. .type = BCM590XX_REG_TYPE_SR,
  913. .regmap = BCM590XX_REGMAP_PRI,
  914. .desc = {
  915. BCM59054_SR_DESC(VSR, vsr, dcdc_vsr_a1_ranges),
  916. },
  917. },
  918. {
  919. .type = BCM590XX_REG_TYPE_GPLDO,
  920. .regmap = BCM590XX_REGMAP_SEC,
  921. .desc = {
  922. BCM59054_LDO_DESC(GPLDO1, gpldo1, ldo_1_table),
  923. },
  924. },
  925. {
  926. .type = BCM590XX_REG_TYPE_GPLDO,
  927. .regmap = BCM590XX_REGMAP_SEC,
  928. .desc = {
  929. BCM59054_LDO_DESC(GPLDO2, gpldo2, ldo_1_table),
  930. },
  931. },
  932. {
  933. .type = BCM590XX_REG_TYPE_GPLDO,
  934. .regmap = BCM590XX_REGMAP_SEC,
  935. .desc = {
  936. BCM59054_LDO_DESC(GPLDO3, gpldo3, ldo_1_table),
  937. },
  938. },
  939. {
  940. .type = BCM590XX_REG_TYPE_GPLDO,
  941. .regmap = BCM590XX_REGMAP_SEC,
  942. .desc = {
  943. BCM59054_LDO_DESC(TCXLDO, tcxldo, ldo_1_table),
  944. },
  945. },
  946. {
  947. .type = BCM590XX_REG_TYPE_GPLDO,
  948. .regmap = BCM590XX_REGMAP_SEC,
  949. .desc = {
  950. BCM59054_LDO_DESC(LVLDO1, lvldo1, ldo_3_table),
  951. },
  952. },
  953. {
  954. .type = BCM590XX_REG_TYPE_GPLDO,
  955. .regmap = BCM590XX_REGMAP_SEC,
  956. .desc = {
  957. BCM59054_LDO_DESC(LVLDO2, lvldo2, ldo_3_table),
  958. },
  959. },
  960. {
  961. .type = BCM590XX_REG_TYPE_VBUS,
  962. .regmap = BCM590XX_REGMAP_SEC,
  963. .desc = {
  964. BCM59054_REG_DESC(VBUS, vbus),
  965. .ops = &bcm590xx_ops_vbus,
  966. .n_voltages = 1,
  967. .fixed_uV = 5000000,
  968. .enable_reg = BCM59054_OTG_CTRL,
  969. .enable_mask = BCM590XX_VBUS_ENABLE,
  970. },
  971. },
  972. };
  973. static int bcm590xx_probe(struct platform_device *pdev)
  974. {
  975. struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent);
  976. struct bcm590xx_reg *pmu;
  977. const struct bcm590xx_reg_data *info;
  978. struct regulator_config config = { };
  979. struct regulator_dev *rdev;
  980. unsigned int i;
  981. pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL);
  982. if (!pmu)
  983. return -ENOMEM;
  984. pmu->mfd = bcm590xx;
  985. switch (pmu->mfd->pmu_id) {
  986. case BCM590XX_PMUID_BCM59054:
  987. pmu->n_regulators = BCM59054_NUM_REGS;
  988. if (pmu->mfd->rev_analog == BCM59054_REV_ANALOG_A1)
  989. pmu->regs = bcm59054_a1_regs;
  990. else
  991. pmu->regs = bcm59054_regs;
  992. break;
  993. case BCM590XX_PMUID_BCM59056:
  994. pmu->n_regulators = BCM59056_NUM_REGS;
  995. pmu->regs = bcm59056_regs;
  996. break;
  997. default:
  998. dev_err(bcm590xx->dev,
  999. "unknown device type, could not initialize\n");
  1000. return -EINVAL;
  1001. }
  1002. platform_set_drvdata(pdev, pmu);
  1003. /* Register the regulators */
  1004. for (i = 0; i < pmu->n_regulators; i++) {
  1005. info = &pmu->regs[i];
  1006. config.dev = bcm590xx->dev;
  1007. config.driver_data = pmu;
  1008. switch (info->regmap) {
  1009. case BCM590XX_REGMAP_PRI:
  1010. config.regmap = bcm590xx->regmap_pri;
  1011. break;
  1012. case BCM590XX_REGMAP_SEC:
  1013. config.regmap = bcm590xx->regmap_sec;
  1014. break;
  1015. default:
  1016. dev_err(bcm590xx->dev,
  1017. "invalid regmap for %s regulator; this is a driver bug\n",
  1018. pdev->name);
  1019. return -EINVAL;
  1020. }
  1021. rdev = devm_regulator_register(&pdev->dev, &info->desc,
  1022. &config);
  1023. if (IS_ERR(rdev))
  1024. return dev_err_probe(bcm590xx->dev, PTR_ERR(rdev),
  1025. "failed to register %s regulator\n",
  1026. pdev->name);
  1027. }
  1028. return 0;
  1029. }
  1030. static struct platform_driver bcm590xx_regulator_driver = {
  1031. .driver = {
  1032. .name = "bcm590xx-vregs",
  1033. .probe_type = PROBE_PREFER_ASYNCHRONOUS,
  1034. },
  1035. .probe = bcm590xx_probe,
  1036. };
  1037. module_platform_driver(bcm590xx_regulator_driver);
  1038. MODULE_AUTHOR("Matt Porter <mporter@linaro.org>");
  1039. MODULE_DESCRIPTION("BCM590xx voltage regulator driver");
  1040. MODULE_LICENSE("GPL v2");
  1041. MODULE_ALIAS("platform:bcm590xx-vregs");