qcom_smd-regulator.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /*
  2. * Copyright (c) 2015, Sony Mobile Communications AB.
  3. * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 and
  7. * only version 2 as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/module.h>
  15. #include <linux/of.h>
  16. #include <linux/of_device.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/regulator/driver.h>
  19. #include <linux/regulator/machine.h>
  20. #include <linux/regulator/of_regulator.h>
  21. #include <linux/soc/qcom/smd-rpm.h>
  22. struct qcom_rpm_reg {
  23. struct device *dev;
  24. struct qcom_smd_rpm *rpm;
  25. u32 type;
  26. u32 id;
  27. struct regulator_desc desc;
  28. int is_enabled;
  29. int uV;
  30. };
  31. struct rpm_regulator_req {
  32. __le32 key;
  33. __le32 nbytes;
  34. __le32 value;
  35. };
  36. #define RPM_KEY_SWEN 0x6e657773 /* "swen" */
  37. #define RPM_KEY_UV 0x00007675 /* "uv" */
  38. #define RPM_KEY_MA 0x0000616d /* "ma" */
  39. static int rpm_reg_write_active(struct qcom_rpm_reg *vreg,
  40. struct rpm_regulator_req *req,
  41. size_t size)
  42. {
  43. return qcom_rpm_smd_write(vreg->rpm,
  44. QCOM_SMD_RPM_ACTIVE_STATE,
  45. vreg->type,
  46. vreg->id,
  47. req, size);
  48. }
  49. static int rpm_reg_enable(struct regulator_dev *rdev)
  50. {
  51. struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
  52. struct rpm_regulator_req req;
  53. int ret;
  54. req.key = cpu_to_le32(RPM_KEY_SWEN);
  55. req.nbytes = cpu_to_le32(sizeof(u32));
  56. req.value = cpu_to_le32(1);
  57. ret = rpm_reg_write_active(vreg, &req, sizeof(req));
  58. if (!ret)
  59. vreg->is_enabled = 1;
  60. return ret;
  61. }
  62. static int rpm_reg_is_enabled(struct regulator_dev *rdev)
  63. {
  64. struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
  65. return vreg->is_enabled;
  66. }
  67. static int rpm_reg_disable(struct regulator_dev *rdev)
  68. {
  69. struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
  70. struct rpm_regulator_req req;
  71. int ret;
  72. req.key = cpu_to_le32(RPM_KEY_SWEN);
  73. req.nbytes = cpu_to_le32(sizeof(u32));
  74. req.value = 0;
  75. ret = rpm_reg_write_active(vreg, &req, sizeof(req));
  76. if (!ret)
  77. vreg->is_enabled = 0;
  78. return ret;
  79. }
  80. static int rpm_reg_get_voltage(struct regulator_dev *rdev)
  81. {
  82. struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
  83. return vreg->uV;
  84. }
  85. static int rpm_reg_set_voltage(struct regulator_dev *rdev,
  86. int min_uV,
  87. int max_uV,
  88. unsigned *selector)
  89. {
  90. struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
  91. struct rpm_regulator_req req;
  92. int ret = 0;
  93. req.key = cpu_to_le32(RPM_KEY_UV);
  94. req.nbytes = cpu_to_le32(sizeof(u32));
  95. req.value = cpu_to_le32(min_uV);
  96. ret = rpm_reg_write_active(vreg, &req, sizeof(req));
  97. if (!ret)
  98. vreg->uV = min_uV;
  99. return ret;
  100. }
  101. static int rpm_reg_set_load(struct regulator_dev *rdev, int load_uA)
  102. {
  103. struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
  104. struct rpm_regulator_req req;
  105. req.key = cpu_to_le32(RPM_KEY_MA);
  106. req.nbytes = cpu_to_le32(sizeof(u32));
  107. req.value = cpu_to_le32(load_uA / 1000);
  108. return rpm_reg_write_active(vreg, &req, sizeof(req));
  109. }
  110. static const struct regulator_ops rpm_smps_ldo_ops = {
  111. .enable = rpm_reg_enable,
  112. .disable = rpm_reg_disable,
  113. .is_enabled = rpm_reg_is_enabled,
  114. .get_voltage = rpm_reg_get_voltage,
  115. .set_voltage = rpm_reg_set_voltage,
  116. .set_load = rpm_reg_set_load,
  117. };
  118. static const struct regulator_ops rpm_switch_ops = {
  119. .enable = rpm_reg_enable,
  120. .disable = rpm_reg_disable,
  121. .is_enabled = rpm_reg_is_enabled,
  122. };
  123. static const struct regulator_desc pma8084_hfsmps = {
  124. .linear_ranges = (struct regulator_linear_range[]) {
  125. REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500),
  126. REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000),
  127. },
  128. .n_linear_ranges = 2,
  129. .n_voltages = 159,
  130. .ops = &rpm_smps_ldo_ops,
  131. };
  132. static const struct regulator_desc pma8084_ftsmps = {
  133. .linear_ranges = (struct regulator_linear_range[]) {
  134. REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000),
  135. REGULATOR_LINEAR_RANGE(700000, 185, 339, 10000),
  136. },
  137. .n_linear_ranges = 2,
  138. .n_voltages = 340,
  139. .ops = &rpm_smps_ldo_ops,
  140. };
  141. static const struct regulator_desc pma8084_pldo = {
  142. .linear_ranges = (struct regulator_linear_range[]) {
  143. REGULATOR_LINEAR_RANGE(750000, 0, 30, 25000),
  144. REGULATOR_LINEAR_RANGE(1500000, 31, 99, 50000),
  145. },
  146. .n_linear_ranges = 2,
  147. .n_voltages = 100,
  148. .ops = &rpm_smps_ldo_ops,
  149. };
  150. static const struct regulator_desc pma8084_nldo = {
  151. .linear_ranges = (struct regulator_linear_range[]) {
  152. REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
  153. },
  154. .n_linear_ranges = 1,
  155. .n_voltages = 64,
  156. .ops = &rpm_smps_ldo_ops,
  157. };
  158. static const struct regulator_desc pma8084_switch = {
  159. .ops = &rpm_switch_ops,
  160. };
  161. static const struct regulator_desc pm8x41_hfsmps = {
  162. .linear_ranges = (struct regulator_linear_range[]) {
  163. REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500),
  164. REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000),
  165. },
  166. .n_linear_ranges = 2,
  167. .n_voltages = 159,
  168. .ops = &rpm_smps_ldo_ops,
  169. };
  170. static const struct regulator_desc pm8841_ftsmps = {
  171. .linear_ranges = (struct regulator_linear_range[]) {
  172. REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000),
  173. REGULATOR_LINEAR_RANGE(700000, 185, 339, 10000),
  174. },
  175. .n_linear_ranges = 2,
  176. .n_voltages = 340,
  177. .ops = &rpm_smps_ldo_ops,
  178. };
  179. static const struct regulator_desc pm8941_boost = {
  180. .linear_ranges = (struct regulator_linear_range[]) {
  181. REGULATOR_LINEAR_RANGE(4000000, 0, 15, 100000),
  182. },
  183. .n_linear_ranges = 1,
  184. .n_voltages = 16,
  185. .ops = &rpm_smps_ldo_ops,
  186. };
  187. static const struct regulator_desc pm8941_pldo = {
  188. .linear_ranges = (struct regulator_linear_range[]) {
  189. REGULATOR_LINEAR_RANGE( 750000, 0, 30, 25000),
  190. REGULATOR_LINEAR_RANGE(1500000, 31, 99, 50000),
  191. },
  192. .n_linear_ranges = 2,
  193. .n_voltages = 100,
  194. .ops = &rpm_smps_ldo_ops,
  195. };
  196. static const struct regulator_desc pm8941_nldo = {
  197. .linear_ranges = (struct regulator_linear_range[]) {
  198. REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
  199. },
  200. .n_linear_ranges = 1,
  201. .n_voltages = 64,
  202. .ops = &rpm_smps_ldo_ops,
  203. };
  204. static const struct regulator_desc pm8941_lnldo = {
  205. .fixed_uV = 1740000,
  206. .n_voltages = 1,
  207. .ops = &rpm_smps_ldo_ops,
  208. };
  209. static const struct regulator_desc pm8941_switch = {
  210. .ops = &rpm_switch_ops,
  211. };
  212. static const struct regulator_desc pm8916_pldo = {
  213. .linear_ranges = (struct regulator_linear_range[]) {
  214. REGULATOR_LINEAR_RANGE(750000, 0, 208, 12500),
  215. },
  216. .n_linear_ranges = 1,
  217. .n_voltages = 209,
  218. .ops = &rpm_smps_ldo_ops,
  219. };
  220. static const struct regulator_desc pm8916_nldo = {
  221. .linear_ranges = (struct regulator_linear_range[]) {
  222. REGULATOR_LINEAR_RANGE(375000, 0, 93, 12500),
  223. },
  224. .n_linear_ranges = 1,
  225. .n_voltages = 94,
  226. .ops = &rpm_smps_ldo_ops,
  227. };
  228. static const struct regulator_desc pm8916_buck_lvo_smps = {
  229. .linear_ranges = (struct regulator_linear_range[]) {
  230. REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500),
  231. REGULATOR_LINEAR_RANGE(750000, 96, 127, 25000),
  232. },
  233. .n_linear_ranges = 2,
  234. .n_voltages = 128,
  235. .ops = &rpm_smps_ldo_ops,
  236. };
  237. static const struct regulator_desc pm8916_buck_hvo_smps = {
  238. .linear_ranges = (struct regulator_linear_range[]) {
  239. REGULATOR_LINEAR_RANGE(1550000, 0, 31, 25000),
  240. },
  241. .n_linear_ranges = 1,
  242. .n_voltages = 32,
  243. .ops = &rpm_smps_ldo_ops,
  244. };
  245. struct rpm_regulator_data {
  246. const char *name;
  247. u32 type;
  248. u32 id;
  249. const struct regulator_desc *desc;
  250. const char *supply;
  251. };
  252. static const struct rpm_regulator_data rpm_pm8841_regulators[] = {
  253. { "s1", QCOM_SMD_RPM_SMPB, 1, &pm8x41_hfsmps, "vdd_s1" },
  254. { "s2", QCOM_SMD_RPM_SMPB, 2, &pm8841_ftsmps, "vdd_s2" },
  255. { "s3", QCOM_SMD_RPM_SMPB, 3, &pm8x41_hfsmps, "vdd_s3" },
  256. { "s4", QCOM_SMD_RPM_SMPB, 4, &pm8841_ftsmps, "vdd_s4" },
  257. { "s5", QCOM_SMD_RPM_SMPB, 5, &pm8841_ftsmps, "vdd_s5" },
  258. { "s6", QCOM_SMD_RPM_SMPB, 6, &pm8841_ftsmps, "vdd_s6" },
  259. { "s7", QCOM_SMD_RPM_SMPB, 7, &pm8841_ftsmps, "vdd_s7" },
  260. { "s8", QCOM_SMD_RPM_SMPB, 8, &pm8841_ftsmps, "vdd_s8" },
  261. {}
  262. };
  263. static const struct rpm_regulator_data rpm_pm8916_regulators[] = {
  264. { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8916_buck_lvo_smps, "vdd_s1" },
  265. { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8916_buck_lvo_smps, "vdd_s2" },
  266. { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8916_buck_lvo_smps, "vdd_s3" },
  267. { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8916_buck_hvo_smps, "vdd_s4" },
  268. { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8916_nldo, "vdd_l1_l2_l3" },
  269. { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8916_nldo, "vdd_l1_l2_l3" },
  270. { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8916_nldo, "vdd_l1_l2_l3" },
  271. { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8916_pldo, "vdd_l4_l5_l6" },
  272. { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8916_pldo, "vdd_l4_l5_l6" },
  273. { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8916_pldo, "vdd_l4_l5_l6" },
  274. { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8916_pldo, "vdd_l7" },
  275. { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18" },
  276. { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18" },
  277. { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
  278. { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
  279. { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
  280. { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
  281. { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
  282. { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
  283. { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
  284. { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
  285. { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
  286. {}
  287. };
  288. static const struct rpm_regulator_data rpm_pm8941_regulators[] = {
  289. { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8x41_hfsmps, "vdd_s1" },
  290. { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8x41_hfsmps, "vdd_s2" },
  291. { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8x41_hfsmps, "vdd_s3" },
  292. { "s4", QCOM_SMD_RPM_BOOST, 1, &pm8941_boost },
  293. { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8941_nldo, "vdd_l1_l3" },
  294. { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8941_nldo, "vdd_l2_lvs1_2_3" },
  295. { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8941_nldo, "vdd_l1_l3" },
  296. { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8941_nldo, "vdd_l4_l11" },
  297. { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8941_lnldo, "vdd_l5_l7" },
  298. { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8941_pldo, "vdd_l6_l12_l14_l15" },
  299. { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8941_lnldo, "vdd_l5_l7" },
  300. { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8941_pldo, "vdd_l8_l16_l18_l19" },
  301. { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8941_pldo, "vdd_l9_l10_l17_l22" },
  302. { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8941_pldo, "vdd_l9_l10_l17_l22" },
  303. { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8941_nldo, "vdd_l4_l11" },
  304. { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8941_pldo, "vdd_l6_l12_l14_l15" },
  305. { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8941_pldo, "vdd_l13_l20_l23_l24" },
  306. { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8941_pldo, "vdd_l6_l12_l14_l15" },
  307. { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8941_pldo, "vdd_l6_l12_l14_l15" },
  308. { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8941_pldo, "vdd_l8_l16_l18_l19" },
  309. { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8941_pldo, "vdd_l9_l10_l17_l22" },
  310. { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8941_pldo, "vdd_l8_l16_l18_l19" },
  311. { "l19", QCOM_SMD_RPM_LDOA, 19, &pm8941_pldo, "vdd_l8_l16_l18_l19" },
  312. { "l20", QCOM_SMD_RPM_LDOA, 20, &pm8941_pldo, "vdd_l13_l20_l23_l24" },
  313. { "l21", QCOM_SMD_RPM_LDOA, 21, &pm8941_pldo, "vdd_l21" },
  314. { "l22", QCOM_SMD_RPM_LDOA, 22, &pm8941_pldo, "vdd_l9_l10_l17_l22" },
  315. { "l23", QCOM_SMD_RPM_LDOA, 23, &pm8941_pldo, "vdd_l13_l20_l23_l24" },
  316. { "l24", QCOM_SMD_RPM_LDOA, 24, &pm8941_pldo, "vdd_l13_l20_l23_l24" },
  317. { "lvs1", QCOM_SMD_RPM_VSA, 1, &pm8941_switch, "vdd_l2_lvs1_2_3" },
  318. { "lvs2", QCOM_SMD_RPM_VSA, 2, &pm8941_switch, "vdd_l2_lvs1_2_3" },
  319. { "lvs3", QCOM_SMD_RPM_VSA, 3, &pm8941_switch, "vdd_l2_lvs1_2_3" },
  320. { "5vs1", QCOM_SMD_RPM_VSA, 4, &pm8941_switch, "vin_5vs" },
  321. { "5vs2", QCOM_SMD_RPM_VSA, 5, &pm8941_switch, "vin_5vs" },
  322. {}
  323. };
  324. static const struct rpm_regulator_data rpm_pma8084_regulators[] = {
  325. { "s1", QCOM_SMD_RPM_SMPA, 1, &pma8084_ftsmps, "vdd_s1" },
  326. { "s2", QCOM_SMD_RPM_SMPA, 2, &pma8084_ftsmps, "vdd_s2" },
  327. { "s3", QCOM_SMD_RPM_SMPA, 3, &pma8084_hfsmps, "vdd_s3" },
  328. { "s4", QCOM_SMD_RPM_SMPA, 4, &pma8084_hfsmps, "vdd_s4" },
  329. { "s5", QCOM_SMD_RPM_SMPA, 5, &pma8084_hfsmps, "vdd_s5" },
  330. { "s6", QCOM_SMD_RPM_SMPA, 6, &pma8084_ftsmps, "vdd_s6" },
  331. { "s7", QCOM_SMD_RPM_SMPA, 7, &pma8084_ftsmps, "vdd_s7" },
  332. { "s8", QCOM_SMD_RPM_SMPA, 8, &pma8084_ftsmps, "vdd_s8" },
  333. { "s9", QCOM_SMD_RPM_SMPA, 9, &pma8084_ftsmps, "vdd_s9" },
  334. { "s10", QCOM_SMD_RPM_SMPA, 10, &pma8084_ftsmps, "vdd_s10" },
  335. { "s11", QCOM_SMD_RPM_SMPA, 11, &pma8084_ftsmps, "vdd_s11" },
  336. { "s12", QCOM_SMD_RPM_SMPA, 12, &pma8084_ftsmps, "vdd_s12" },
  337. { "l1", QCOM_SMD_RPM_LDOA, 1, &pma8084_nldo, "vdd_l1_l11" },
  338. { "l2", QCOM_SMD_RPM_LDOA, 2, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
  339. { "l3", QCOM_SMD_RPM_LDOA, 3, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
  340. { "l4", QCOM_SMD_RPM_LDOA, 4, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
  341. { "l5", QCOM_SMD_RPM_LDOA, 5, &pma8084_pldo, "vdd_l5_l7" },
  342. { "l6", QCOM_SMD_RPM_LDOA, 6, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
  343. { "l7", QCOM_SMD_RPM_LDOA, 7, &pma8084_pldo, "vdd_l5_l7" },
  344. { "l8", QCOM_SMD_RPM_LDOA, 8, &pma8084_pldo, "vdd_l8" },
  345. { "l9", QCOM_SMD_RPM_LDOA, 9, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
  346. { "l10", QCOM_SMD_RPM_LDOA, 10, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
  347. { "l11", QCOM_SMD_RPM_LDOA, 11, &pma8084_nldo, "vdd_l1_l11" },
  348. { "l12", QCOM_SMD_RPM_LDOA, 12, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
  349. { "l13", QCOM_SMD_RPM_LDOA, 13, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
  350. { "l14", QCOM_SMD_RPM_LDOA, 14, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
  351. { "l15", QCOM_SMD_RPM_LDOA, 15, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
  352. { "l16", QCOM_SMD_RPM_LDOA, 16, &pma8084_pldo, "vdd_l16_l25" },
  353. { "l17", QCOM_SMD_RPM_LDOA, 17, &pma8084_pldo, "vdd_l17" },
  354. { "l18", QCOM_SMD_RPM_LDOA, 18, &pma8084_pldo, "vdd_l18" },
  355. { "l19", QCOM_SMD_RPM_LDOA, 19, &pma8084_pldo, "vdd_l19" },
  356. { "l20", QCOM_SMD_RPM_LDOA, 20, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
  357. { "l21", QCOM_SMD_RPM_LDOA, 21, &pma8084_pldo, "vdd_l21" },
  358. { "l22", QCOM_SMD_RPM_LDOA, 22, &pma8084_pldo, "vdd_l22" },
  359. { "l23", QCOM_SMD_RPM_LDOA, 23, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
  360. { "l24", QCOM_SMD_RPM_LDOA, 24, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
  361. { "l25", QCOM_SMD_RPM_LDOA, 25, &pma8084_pldo, "vdd_l16_l25" },
  362. { "l26", QCOM_SMD_RPM_LDOA, 26, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
  363. { "l27", QCOM_SMD_RPM_LDOA, 27, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
  364. { "lvs1", QCOM_SMD_RPM_VSA, 1, &pma8084_switch },
  365. { "lvs2", QCOM_SMD_RPM_VSA, 2, &pma8084_switch },
  366. { "lvs3", QCOM_SMD_RPM_VSA, 3, &pma8084_switch },
  367. { "lvs4", QCOM_SMD_RPM_VSA, 4, &pma8084_switch },
  368. { "5vs1", QCOM_SMD_RPM_VSA, 5, &pma8084_switch },
  369. {}
  370. };
  371. static const struct of_device_id rpm_of_match[] = {
  372. { .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators },
  373. { .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators },
  374. { .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators },
  375. { .compatible = "qcom,rpm-pma8084-regulators", .data = &rpm_pma8084_regulators },
  376. {}
  377. };
  378. MODULE_DEVICE_TABLE(of, rpm_of_match);
  379. static int rpm_reg_probe(struct platform_device *pdev)
  380. {
  381. const struct rpm_regulator_data *reg;
  382. const struct of_device_id *match;
  383. struct regulator_config config = { };
  384. struct regulator_dev *rdev;
  385. struct qcom_rpm_reg *vreg;
  386. struct qcom_smd_rpm *rpm;
  387. rpm = dev_get_drvdata(pdev->dev.parent);
  388. if (!rpm) {
  389. dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
  390. return -ENODEV;
  391. }
  392. match = of_match_device(rpm_of_match, &pdev->dev);
  393. for (reg = match->data; reg->name; reg++) {
  394. vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
  395. if (!vreg)
  396. return -ENOMEM;
  397. vreg->dev = &pdev->dev;
  398. vreg->type = reg->type;
  399. vreg->id = reg->id;
  400. vreg->rpm = rpm;
  401. memcpy(&vreg->desc, reg->desc, sizeof(vreg->desc));
  402. vreg->desc.id = -1;
  403. vreg->desc.owner = THIS_MODULE;
  404. vreg->desc.type = REGULATOR_VOLTAGE;
  405. vreg->desc.name = reg->name;
  406. vreg->desc.supply_name = reg->supply;
  407. vreg->desc.of_match = reg->name;
  408. config.dev = &pdev->dev;
  409. config.driver_data = vreg;
  410. rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config);
  411. if (IS_ERR(rdev)) {
  412. dev_err(&pdev->dev, "failed to register %s\n", reg->name);
  413. return PTR_ERR(rdev);
  414. }
  415. }
  416. return 0;
  417. }
  418. static struct platform_driver rpm_reg_driver = {
  419. .probe = rpm_reg_probe,
  420. .driver = {
  421. .name = "qcom_rpm_smd_regulator",
  422. .of_match_table = rpm_of_match,
  423. },
  424. };
  425. static int __init rpm_reg_init(void)
  426. {
  427. return platform_driver_register(&rpm_reg_driver);
  428. }
  429. subsys_initcall(rpm_reg_init);
  430. static void __exit rpm_reg_exit(void)
  431. {
  432. platform_driver_unregister(&rpm_reg_driver);
  433. }
  434. module_exit(rpm_reg_exit)
  435. MODULE_DESCRIPTION("Qualcomm RPM regulator driver");
  436. MODULE_LICENSE("GPL v2");