s5m8767.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. /*
  2. * s5m8767.c
  3. *
  4. * Copyright (c) 2011 Samsung Electronics Co., Ltd
  5. * http://www.samsung.com
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2 of the License, or (at your
  10. * option) any later version.
  11. *
  12. */
  13. #include <linux/bug.h>
  14. #include <linux/err.h>
  15. #include <linux/gpio.h>
  16. #include <linux/slab.h>
  17. #include <linux/module.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/regulator/driver.h>
  20. #include <linux/regulator/machine.h>
  21. #include <linux/mfd/samsung/core.h>
  22. #include <linux/mfd/samsung/s5m8767.h>
  23. struct s5m8767_info {
  24. struct device *dev;
  25. struct sec_pmic_dev *iodev;
  26. int num_regulators;
  27. struct regulator_dev **rdev;
  28. struct sec_opmode_data *opmode;
  29. int ramp_delay;
  30. bool buck2_ramp;
  31. bool buck3_ramp;
  32. bool buck4_ramp;
  33. bool buck2_gpiodvs;
  34. bool buck3_gpiodvs;
  35. bool buck4_gpiodvs;
  36. u8 buck2_vol[8];
  37. u8 buck3_vol[8];
  38. u8 buck4_vol[8];
  39. int buck_gpios[3];
  40. int buck_ds[3];
  41. int buck_gpioindex;
  42. };
  43. struct sec_voltage_desc {
  44. int max;
  45. int min;
  46. int step;
  47. };
  48. static const struct sec_voltage_desc buck_voltage_val1 = {
  49. .max = 2225000,
  50. .min = 650000,
  51. .step = 6250,
  52. };
  53. static const struct sec_voltage_desc buck_voltage_val2 = {
  54. .max = 1600000,
  55. .min = 600000,
  56. .step = 6250,
  57. };
  58. static const struct sec_voltage_desc buck_voltage_val3 = {
  59. .max = 3000000,
  60. .min = 750000,
  61. .step = 12500,
  62. };
  63. static const struct sec_voltage_desc ldo_voltage_val1 = {
  64. .max = 3950000,
  65. .min = 800000,
  66. .step = 50000,
  67. };
  68. static const struct sec_voltage_desc ldo_voltage_val2 = {
  69. .max = 2375000,
  70. .min = 800000,
  71. .step = 25000,
  72. };
  73. static const struct sec_voltage_desc *reg_voltage_map[] = {
  74. [S5M8767_LDO1] = &ldo_voltage_val2,
  75. [S5M8767_LDO2] = &ldo_voltage_val2,
  76. [S5M8767_LDO3] = &ldo_voltage_val1,
  77. [S5M8767_LDO4] = &ldo_voltage_val1,
  78. [S5M8767_LDO5] = &ldo_voltage_val1,
  79. [S5M8767_LDO6] = &ldo_voltage_val2,
  80. [S5M8767_LDO7] = &ldo_voltage_val2,
  81. [S5M8767_LDO8] = &ldo_voltage_val2,
  82. [S5M8767_LDO9] = &ldo_voltage_val1,
  83. [S5M8767_LDO10] = &ldo_voltage_val1,
  84. [S5M8767_LDO11] = &ldo_voltage_val1,
  85. [S5M8767_LDO12] = &ldo_voltage_val1,
  86. [S5M8767_LDO13] = &ldo_voltage_val1,
  87. [S5M8767_LDO14] = &ldo_voltage_val1,
  88. [S5M8767_LDO15] = &ldo_voltage_val2,
  89. [S5M8767_LDO16] = &ldo_voltage_val1,
  90. [S5M8767_LDO17] = &ldo_voltage_val1,
  91. [S5M8767_LDO18] = &ldo_voltage_val1,
  92. [S5M8767_LDO19] = &ldo_voltage_val1,
  93. [S5M8767_LDO20] = &ldo_voltage_val1,
  94. [S5M8767_LDO21] = &ldo_voltage_val1,
  95. [S5M8767_LDO22] = &ldo_voltage_val1,
  96. [S5M8767_LDO23] = &ldo_voltage_val1,
  97. [S5M8767_LDO24] = &ldo_voltage_val1,
  98. [S5M8767_LDO25] = &ldo_voltage_val1,
  99. [S5M8767_LDO26] = &ldo_voltage_val1,
  100. [S5M8767_LDO27] = &ldo_voltage_val1,
  101. [S5M8767_LDO28] = &ldo_voltage_val1,
  102. [S5M8767_BUCK1] = &buck_voltage_val1,
  103. [S5M8767_BUCK2] = &buck_voltage_val2,
  104. [S5M8767_BUCK3] = &buck_voltage_val2,
  105. [S5M8767_BUCK4] = &buck_voltage_val2,
  106. [S5M8767_BUCK5] = &buck_voltage_val1,
  107. [S5M8767_BUCK6] = &buck_voltage_val1,
  108. [S5M8767_BUCK7] = NULL,
  109. [S5M8767_BUCK8] = NULL,
  110. [S5M8767_BUCK9] = &buck_voltage_val3,
  111. };
  112. static unsigned int s5m8767_opmode_reg[][4] = {
  113. /* {OFF, ON, LOWPOWER, SUSPEND} */
  114. /* LDO1 ... LDO28 */
  115. {0x0, 0x3, 0x2, 0x1}, /* LDO1 */
  116. {0x0, 0x3, 0x2, 0x1},
  117. {0x0, 0x3, 0x2, 0x1},
  118. {0x0, 0x0, 0x0, 0x0},
  119. {0x0, 0x3, 0x2, 0x1}, /* LDO5 */
  120. {0x0, 0x3, 0x2, 0x1},
  121. {0x0, 0x3, 0x2, 0x1},
  122. {0x0, 0x3, 0x2, 0x1},
  123. {0x0, 0x3, 0x2, 0x1},
  124. {0x0, 0x3, 0x2, 0x1}, /* LDO10 */
  125. {0x0, 0x3, 0x2, 0x1},
  126. {0x0, 0x3, 0x2, 0x1},
  127. {0x0, 0x3, 0x2, 0x1},
  128. {0x0, 0x3, 0x2, 0x1},
  129. {0x0, 0x3, 0x2, 0x1}, /* LDO15 */
  130. {0x0, 0x3, 0x2, 0x1},
  131. {0x0, 0x3, 0x2, 0x1},
  132. {0x0, 0x0, 0x0, 0x0},
  133. {0x0, 0x3, 0x2, 0x1},
  134. {0x0, 0x3, 0x2, 0x1}, /* LDO20 */
  135. {0x0, 0x3, 0x2, 0x1},
  136. {0x0, 0x3, 0x2, 0x1},
  137. {0x0, 0x0, 0x0, 0x0},
  138. {0x0, 0x3, 0x2, 0x1},
  139. {0x0, 0x3, 0x2, 0x1}, /* LDO25 */
  140. {0x0, 0x3, 0x2, 0x1},
  141. {0x0, 0x3, 0x2, 0x1},
  142. {0x0, 0x3, 0x2, 0x1}, /* LDO28 */
  143. /* BUCK1 ... BUCK9 */
  144. {0x0, 0x3, 0x1, 0x1}, /* BUCK1 */
  145. {0x0, 0x3, 0x1, 0x1},
  146. {0x0, 0x3, 0x1, 0x1},
  147. {0x0, 0x3, 0x1, 0x1},
  148. {0x0, 0x3, 0x2, 0x1}, /* BUCK5 */
  149. {0x0, 0x3, 0x1, 0x1},
  150. {0x0, 0x3, 0x1, 0x1},
  151. {0x0, 0x3, 0x1, 0x1},
  152. {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */
  153. };
  154. static int s5m8767_get_register(struct regulator_dev *rdev, int *reg,
  155. int *enable_ctrl)
  156. {
  157. int reg_id = rdev_get_id(rdev);
  158. unsigned int mode;
  159. struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
  160. switch (reg_id) {
  161. case S5M8767_LDO1 ... S5M8767_LDO2:
  162. *reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1);
  163. break;
  164. case S5M8767_LDO3 ... S5M8767_LDO28:
  165. *reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3);
  166. break;
  167. case S5M8767_BUCK1:
  168. *reg = S5M8767_REG_BUCK1CTRL1;
  169. break;
  170. case S5M8767_BUCK2 ... S5M8767_BUCK4:
  171. *reg = S5M8767_REG_BUCK2CTRL + (reg_id - S5M8767_BUCK2) * 9;
  172. break;
  173. case S5M8767_BUCK5:
  174. *reg = S5M8767_REG_BUCK5CTRL1;
  175. break;
  176. case S5M8767_BUCK6 ... S5M8767_BUCK9:
  177. *reg = S5M8767_REG_BUCK6CTRL1 + (reg_id - S5M8767_BUCK6) * 2;
  178. break;
  179. default:
  180. return -EINVAL;
  181. }
  182. mode = s5m8767->opmode[reg_id].mode;
  183. *enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT;
  184. return 0;
  185. }
  186. static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
  187. {
  188. struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
  189. int ret, reg;
  190. int mask = 0xc0, enable_ctrl;
  191. u8 val;
  192. ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
  193. if (ret == -EINVAL)
  194. return 1;
  195. else if (ret)
  196. return ret;
  197. ret = sec_reg_read(s5m8767->iodev, reg, &val);
  198. if (ret)
  199. return ret;
  200. return (val & mask) == enable_ctrl;
  201. }
  202. static int s5m8767_reg_enable(struct regulator_dev *rdev)
  203. {
  204. struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
  205. int ret, reg;
  206. int mask = 0xc0, enable_ctrl;
  207. ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
  208. if (ret)
  209. return ret;
  210. return sec_reg_update(s5m8767->iodev, reg, enable_ctrl, mask);
  211. }
  212. static int s5m8767_reg_disable(struct regulator_dev *rdev)
  213. {
  214. struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
  215. int ret, reg;
  216. int mask = 0xc0, enable_ctrl;
  217. ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
  218. if (ret)
  219. return ret;
  220. return sec_reg_update(s5m8767->iodev, reg, ~mask, mask);
  221. }
  222. static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg)
  223. {
  224. struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
  225. int reg_id = rdev_get_id(rdev);
  226. int reg;
  227. switch (reg_id) {
  228. case S5M8767_LDO1 ... S5M8767_LDO2:
  229. reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1);
  230. break;
  231. case S5M8767_LDO3 ... S5M8767_LDO28:
  232. reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3);
  233. break;
  234. case S5M8767_BUCK1:
  235. reg = S5M8767_REG_BUCK1CTRL2;
  236. break;
  237. case S5M8767_BUCK2:
  238. reg = S5M8767_REG_BUCK2DVS2;
  239. if (s5m8767->buck2_gpiodvs)
  240. reg += s5m8767->buck_gpioindex;
  241. break;
  242. case S5M8767_BUCK3:
  243. reg = S5M8767_REG_BUCK3DVS2;
  244. if (s5m8767->buck3_gpiodvs)
  245. reg += s5m8767->buck_gpioindex;
  246. break;
  247. case S5M8767_BUCK4:
  248. reg = S5M8767_REG_BUCK4DVS2;
  249. if (s5m8767->buck4_gpiodvs)
  250. reg += s5m8767->buck_gpioindex;
  251. break;
  252. case S5M8767_BUCK5:
  253. reg = S5M8767_REG_BUCK5CTRL2;
  254. break;
  255. case S5M8767_BUCK6 ... S5M8767_BUCK9:
  256. reg = S5M8767_REG_BUCK6CTRL2 + (reg_id - S5M8767_BUCK6) * 2;
  257. break;
  258. default:
  259. return -EINVAL;
  260. }
  261. *_reg = reg;
  262. return 0;
  263. }
  264. static int s5m8767_get_voltage_sel(struct regulator_dev *rdev)
  265. {
  266. struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
  267. int reg, mask, ret;
  268. int reg_id = rdev_get_id(rdev);
  269. u8 val;
  270. ret = s5m8767_get_voltage_register(rdev, &reg);
  271. if (ret)
  272. return ret;
  273. mask = (reg_id < S5M8767_BUCK1) ? 0x3f : 0xff;
  274. ret = sec_reg_read(s5m8767->iodev, reg, &val);
  275. if (ret)
  276. return ret;
  277. val &= mask;
  278. return val;
  279. }
  280. static int s5m8767_convert_voltage_to_sel(
  281. const struct sec_voltage_desc *desc,
  282. int min_vol, int max_vol)
  283. {
  284. int selector = 0;
  285. if (desc == NULL)
  286. return -EINVAL;
  287. if (max_vol < desc->min || min_vol > desc->max)
  288. return -EINVAL;
  289. if (min_vol < desc->min)
  290. min_vol = desc->min;
  291. selector = DIV_ROUND_UP(min_vol - desc->min, desc->step);
  292. if (desc->min + desc->step * selector > max_vol)
  293. return -EINVAL;
  294. return selector;
  295. }
  296. static inline int s5m8767_set_high(struct s5m8767_info *s5m8767)
  297. {
  298. int temp_index = s5m8767->buck_gpioindex;
  299. gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
  300. gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
  301. gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
  302. return 0;
  303. }
  304. static inline int s5m8767_set_low(struct s5m8767_info *s5m8767)
  305. {
  306. int temp_index = s5m8767->buck_gpioindex;
  307. gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
  308. gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
  309. gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
  310. return 0;
  311. }
  312. static int s5m8767_set_voltage_sel(struct regulator_dev *rdev,
  313. unsigned selector)
  314. {
  315. struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
  316. int reg_id = rdev_get_id(rdev);
  317. int reg, mask, ret = 0, old_index, index = 0;
  318. u8 *buck234_vol = NULL;
  319. switch (reg_id) {
  320. case S5M8767_LDO1 ... S5M8767_LDO28:
  321. mask = 0x3f;
  322. break;
  323. case S5M8767_BUCK1 ... S5M8767_BUCK6:
  324. mask = 0xff;
  325. if (reg_id == S5M8767_BUCK2 && s5m8767->buck2_gpiodvs)
  326. buck234_vol = &s5m8767->buck2_vol[0];
  327. else if (reg_id == S5M8767_BUCK3 && s5m8767->buck3_gpiodvs)
  328. buck234_vol = &s5m8767->buck3_vol[0];
  329. else if (reg_id == S5M8767_BUCK4 && s5m8767->buck4_gpiodvs)
  330. buck234_vol = &s5m8767->buck4_vol[0];
  331. break;
  332. case S5M8767_BUCK7 ... S5M8767_BUCK8:
  333. return -EINVAL;
  334. case S5M8767_BUCK9:
  335. mask = 0xff;
  336. break;
  337. default:
  338. return -EINVAL;
  339. }
  340. /* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */
  341. if (buck234_vol) {
  342. while (*buck234_vol != selector) {
  343. buck234_vol++;
  344. index++;
  345. }
  346. old_index = s5m8767->buck_gpioindex;
  347. s5m8767->buck_gpioindex = index;
  348. if (index > old_index)
  349. return s5m8767_set_high(s5m8767);
  350. else
  351. return s5m8767_set_low(s5m8767);
  352. } else {
  353. ret = s5m8767_get_voltage_register(rdev, &reg);
  354. if (ret)
  355. return ret;
  356. return sec_reg_update(s5m8767->iodev, reg, selector, mask);
  357. }
  358. }
  359. static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
  360. unsigned int old_sel,
  361. unsigned int new_sel)
  362. {
  363. struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
  364. const struct sec_voltage_desc *desc;
  365. int reg_id = rdev_get_id(rdev);
  366. desc = reg_voltage_map[reg_id];
  367. if ((old_sel < new_sel) && s5m8767->ramp_delay)
  368. return DIV_ROUND_UP(desc->step * (new_sel - old_sel),
  369. s5m8767->ramp_delay * 1000);
  370. return 0;
  371. }
  372. static struct regulator_ops s5m8767_ops = {
  373. .list_voltage = regulator_list_voltage_linear,
  374. .is_enabled = s5m8767_reg_is_enabled,
  375. .enable = s5m8767_reg_enable,
  376. .disable = s5m8767_reg_disable,
  377. .get_voltage_sel = s5m8767_get_voltage_sel,
  378. .set_voltage_sel = s5m8767_set_voltage_sel,
  379. .set_voltage_time_sel = s5m8767_set_voltage_time_sel,
  380. };
  381. static struct regulator_ops s5m8767_buck78_ops = {
  382. .is_enabled = s5m8767_reg_is_enabled,
  383. .enable = s5m8767_reg_enable,
  384. .disable = s5m8767_reg_disable,
  385. };
  386. #define s5m8767_regulator_desc(_name) { \
  387. .name = #_name, \
  388. .id = S5M8767_##_name, \
  389. .ops = &s5m8767_ops, \
  390. .type = REGULATOR_VOLTAGE, \
  391. .owner = THIS_MODULE, \
  392. }
  393. #define s5m8767_regulator_buck78_desc(_name) { \
  394. .name = #_name, \
  395. .id = S5M8767_##_name, \
  396. .ops = &s5m8767_buck78_ops, \
  397. .type = REGULATOR_VOLTAGE, \
  398. .owner = THIS_MODULE, \
  399. }
  400. static struct regulator_desc regulators[] = {
  401. s5m8767_regulator_desc(LDO1),
  402. s5m8767_regulator_desc(LDO2),
  403. s5m8767_regulator_desc(LDO3),
  404. s5m8767_regulator_desc(LDO4),
  405. s5m8767_regulator_desc(LDO5),
  406. s5m8767_regulator_desc(LDO6),
  407. s5m8767_regulator_desc(LDO7),
  408. s5m8767_regulator_desc(LDO8),
  409. s5m8767_regulator_desc(LDO9),
  410. s5m8767_regulator_desc(LDO10),
  411. s5m8767_regulator_desc(LDO11),
  412. s5m8767_regulator_desc(LDO12),
  413. s5m8767_regulator_desc(LDO13),
  414. s5m8767_regulator_desc(LDO14),
  415. s5m8767_regulator_desc(LDO15),
  416. s5m8767_regulator_desc(LDO16),
  417. s5m8767_regulator_desc(LDO17),
  418. s5m8767_regulator_desc(LDO18),
  419. s5m8767_regulator_desc(LDO19),
  420. s5m8767_regulator_desc(LDO20),
  421. s5m8767_regulator_desc(LDO21),
  422. s5m8767_regulator_desc(LDO22),
  423. s5m8767_regulator_desc(LDO23),
  424. s5m8767_regulator_desc(LDO24),
  425. s5m8767_regulator_desc(LDO25),
  426. s5m8767_regulator_desc(LDO26),
  427. s5m8767_regulator_desc(LDO27),
  428. s5m8767_regulator_desc(LDO28),
  429. s5m8767_regulator_desc(BUCK1),
  430. s5m8767_regulator_desc(BUCK2),
  431. s5m8767_regulator_desc(BUCK3),
  432. s5m8767_regulator_desc(BUCK4),
  433. s5m8767_regulator_desc(BUCK5),
  434. s5m8767_regulator_desc(BUCK6),
  435. s5m8767_regulator_buck78_desc(BUCK7),
  436. s5m8767_regulator_buck78_desc(BUCK8),
  437. s5m8767_regulator_desc(BUCK9),
  438. };
  439. static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
  440. {
  441. struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
  442. struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
  443. struct regulator_config config = { };
  444. struct regulator_dev **rdev;
  445. struct s5m8767_info *s5m8767;
  446. int i, ret, size, buck_init;
  447. if (!pdata) {
  448. dev_err(pdev->dev.parent, "Platform data not supplied\n");
  449. return -ENODEV;
  450. }
  451. if (pdata->buck2_gpiodvs) {
  452. if (pdata->buck3_gpiodvs || pdata->buck4_gpiodvs) {
  453. dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
  454. return -EINVAL;
  455. }
  456. }
  457. if (pdata->buck3_gpiodvs) {
  458. if (pdata->buck2_gpiodvs || pdata->buck4_gpiodvs) {
  459. dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
  460. return -EINVAL;
  461. }
  462. }
  463. if (pdata->buck4_gpiodvs) {
  464. if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs) {
  465. dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
  466. return -EINVAL;
  467. }
  468. }
  469. s5m8767 = devm_kzalloc(&pdev->dev, sizeof(struct s5m8767_info),
  470. GFP_KERNEL);
  471. if (!s5m8767)
  472. return -ENOMEM;
  473. size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2);
  474. s5m8767->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
  475. if (!s5m8767->rdev)
  476. return -ENOMEM;
  477. rdev = s5m8767->rdev;
  478. s5m8767->dev = &pdev->dev;
  479. s5m8767->iodev = iodev;
  480. s5m8767->num_regulators = S5M8767_REG_MAX - 2;
  481. platform_set_drvdata(pdev, s5m8767);
  482. s5m8767->buck_gpioindex = pdata->buck_default_idx;
  483. s5m8767->buck2_gpiodvs = pdata->buck2_gpiodvs;
  484. s5m8767->buck3_gpiodvs = pdata->buck3_gpiodvs;
  485. s5m8767->buck4_gpiodvs = pdata->buck4_gpiodvs;
  486. s5m8767->buck_gpios[0] = pdata->buck_gpios[0];
  487. s5m8767->buck_gpios[1] = pdata->buck_gpios[1];
  488. s5m8767->buck_gpios[2] = pdata->buck_gpios[2];
  489. s5m8767->buck_ds[0] = pdata->buck_ds[0];
  490. s5m8767->buck_ds[1] = pdata->buck_ds[1];
  491. s5m8767->buck_ds[2] = pdata->buck_ds[2];
  492. s5m8767->ramp_delay = pdata->buck_ramp_delay;
  493. s5m8767->buck2_ramp = pdata->buck2_ramp_enable;
  494. s5m8767->buck3_ramp = pdata->buck3_ramp_enable;
  495. s5m8767->buck4_ramp = pdata->buck4_ramp_enable;
  496. s5m8767->opmode = pdata->opmode;
  497. buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2,
  498. pdata->buck2_init,
  499. pdata->buck2_init +
  500. buck_voltage_val2.step);
  501. sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS2, buck_init);
  502. buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2,
  503. pdata->buck3_init,
  504. pdata->buck3_init +
  505. buck_voltage_val2.step);
  506. sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS2, buck_init);
  507. buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2,
  508. pdata->buck4_init,
  509. pdata->buck4_init +
  510. buck_voltage_val2.step);
  511. sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS2, buck_init);
  512. for (i = 0; i < 8; i++) {
  513. if (s5m8767->buck2_gpiodvs) {
  514. s5m8767->buck2_vol[i] =
  515. s5m8767_convert_voltage_to_sel(
  516. &buck_voltage_val2,
  517. pdata->buck2_voltage[i],
  518. pdata->buck2_voltage[i] +
  519. buck_voltage_val2.step);
  520. }
  521. if (s5m8767->buck3_gpiodvs) {
  522. s5m8767->buck3_vol[i] =
  523. s5m8767_convert_voltage_to_sel(
  524. &buck_voltage_val2,
  525. pdata->buck3_voltage[i],
  526. pdata->buck3_voltage[i] +
  527. buck_voltage_val2.step);
  528. }
  529. if (s5m8767->buck4_gpiodvs) {
  530. s5m8767->buck4_vol[i] =
  531. s5m8767_convert_voltage_to_sel(
  532. &buck_voltage_val2,
  533. pdata->buck4_voltage[i],
  534. pdata->buck4_voltage[i] +
  535. buck_voltage_val2.step);
  536. }
  537. }
  538. if (gpio_is_valid(pdata->buck_gpios[0]) &&
  539. gpio_is_valid(pdata->buck_gpios[1]) &&
  540. gpio_is_valid(pdata->buck_gpios[2])) {
  541. ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[0],
  542. "S5M8767 SET1");
  543. if (ret)
  544. return ret;
  545. ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[1],
  546. "S5M8767 SET2");
  547. if (ret)
  548. return ret;
  549. ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[2],
  550. "S5M8767 SET3");
  551. if (ret)
  552. return ret;
  553. /* SET1 GPIO */
  554. gpio_direction_output(pdata->buck_gpios[0],
  555. (s5m8767->buck_gpioindex >> 2) & 0x1);
  556. /* SET2 GPIO */
  557. gpio_direction_output(pdata->buck_gpios[1],
  558. (s5m8767->buck_gpioindex >> 1) & 0x1);
  559. /* SET3 GPIO */
  560. gpio_direction_output(pdata->buck_gpios[2],
  561. (s5m8767->buck_gpioindex >> 0) & 0x1);
  562. } else {
  563. dev_err(&pdev->dev, "GPIO NOT VALID\n");
  564. ret = -EINVAL;
  565. return ret;
  566. }
  567. ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[0], "S5M8767 DS2");
  568. if (ret)
  569. return ret;
  570. ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[1], "S5M8767 DS3");
  571. if (ret)
  572. return ret;
  573. ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[2], "S5M8767 DS4");
  574. if (ret)
  575. return ret;
  576. /* DS2 GPIO */
  577. gpio_direction_output(pdata->buck_ds[0], 0x0);
  578. /* DS3 GPIO */
  579. gpio_direction_output(pdata->buck_ds[1], 0x0);
  580. /* DS4 GPIO */
  581. gpio_direction_output(pdata->buck_ds[2], 0x0);
  582. if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs ||
  583. pdata->buck4_gpiodvs) {
  584. sec_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL,
  585. (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1),
  586. 1 << 1);
  587. sec_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL,
  588. (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1),
  589. 1 << 1);
  590. sec_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL,
  591. (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1),
  592. 1 << 1);
  593. }
  594. /* Initialize GPIO DVS registers */
  595. for (i = 0; i < 8; i++) {
  596. if (s5m8767->buck2_gpiodvs) {
  597. sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS1 + i,
  598. s5m8767->buck2_vol[i]);
  599. }
  600. if (s5m8767->buck3_gpiodvs) {
  601. sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS1 + i,
  602. s5m8767->buck3_vol[i]);
  603. }
  604. if (s5m8767->buck4_gpiodvs) {
  605. sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS1 + i,
  606. s5m8767->buck4_vol[i]);
  607. }
  608. }
  609. if (s5m8767->buck2_ramp)
  610. sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x08, 0x08);
  611. if (s5m8767->buck3_ramp)
  612. sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x04, 0x04);
  613. if (s5m8767->buck4_ramp)
  614. sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x02, 0x02);
  615. if (s5m8767->buck2_ramp || s5m8767->buck3_ramp
  616. || s5m8767->buck4_ramp) {
  617. switch (s5m8767->ramp_delay) {
  618. case 5:
  619. sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
  620. 0x40, 0xf0);
  621. break;
  622. case 10:
  623. sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
  624. 0x90, 0xf0);
  625. break;
  626. case 25:
  627. sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
  628. 0xd0, 0xf0);
  629. break;
  630. case 50:
  631. sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
  632. 0xe0, 0xf0);
  633. break;
  634. case 100:
  635. sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
  636. 0xf0, 0xf0);
  637. break;
  638. default:
  639. sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
  640. 0x90, 0xf0);
  641. }
  642. }
  643. for (i = 0; i < pdata->num_regulators; i++) {
  644. const struct sec_voltage_desc *desc;
  645. int id = pdata->regulators[i].id;
  646. desc = reg_voltage_map[id];
  647. if (desc) {
  648. regulators[id].n_voltages =
  649. (desc->max - desc->min) / desc->step + 1;
  650. regulators[id].min_uV = desc->min;
  651. regulators[id].uV_step = desc->step;
  652. }
  653. config.dev = s5m8767->dev;
  654. config.init_data = pdata->regulators[i].initdata;
  655. config.driver_data = s5m8767;
  656. rdev[i] = regulator_register(&regulators[id], &config);
  657. if (IS_ERR(rdev[i])) {
  658. ret = PTR_ERR(rdev[i]);
  659. dev_err(s5m8767->dev, "regulator init failed for %d\n",
  660. id);
  661. rdev[i] = NULL;
  662. goto err;
  663. }
  664. }
  665. return 0;
  666. err:
  667. for (i = 0; i < s5m8767->num_regulators; i++)
  668. if (rdev[i])
  669. regulator_unregister(rdev[i]);
  670. return ret;
  671. }
  672. static int __devexit s5m8767_pmic_remove(struct platform_device *pdev)
  673. {
  674. struct s5m8767_info *s5m8767 = platform_get_drvdata(pdev);
  675. struct regulator_dev **rdev = s5m8767->rdev;
  676. int i;
  677. for (i = 0; i < s5m8767->num_regulators; i++)
  678. if (rdev[i])
  679. regulator_unregister(rdev[i]);
  680. return 0;
  681. }
  682. static const struct platform_device_id s5m8767_pmic_id[] = {
  683. { "s5m8767-pmic", 0},
  684. { },
  685. };
  686. MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id);
  687. static struct platform_driver s5m8767_pmic_driver = {
  688. .driver = {
  689. .name = "s5m8767-pmic",
  690. .owner = THIS_MODULE,
  691. },
  692. .probe = s5m8767_pmic_probe,
  693. .remove = __devexit_p(s5m8767_pmic_remove),
  694. .id_table = s5m8767_pmic_id,
  695. };
  696. static int __init s5m8767_pmic_init(void)
  697. {
  698. return platform_driver_register(&s5m8767_pmic_driver);
  699. }
  700. subsys_initcall(s5m8767_pmic_init);
  701. static void __exit s5m8767_pmic_exit(void)
  702. {
  703. platform_driver_unregister(&s5m8767_pmic_driver);
  704. }
  705. module_exit(s5m8767_pmic_exit);
  706. /* Module information */
  707. MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
  708. MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver");
  709. MODULE_LICENSE("GPL");