mp886x.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // MP8867/MP8869 regulator driver
  4. //
  5. // Copyright (C) 2020 Synaptics Incorporated
  6. //
  7. // Author: Jisheng Zhang <[email protected]>
  8. #include <linux/gpio/consumer.h>
  9. #include <linux/i2c.h>
  10. #include <linux/module.h>
  11. #include <linux/of_device.h>
  12. #include <linux/regmap.h>
  13. #include <linux/regulator/driver.h>
  14. #include <linux/regulator/of_regulator.h>
  15. #define MP886X_VSEL 0x00
  16. #define MP886X_V_BOOT (1 << 7)
  17. #define MP886X_SYSCNTLREG1 0x01
  18. #define MP886X_MODE (1 << 0)
  19. #define MP886X_SLEW_SHIFT 3
  20. #define MP886X_SLEW_MASK (0x7 << MP886X_SLEW_SHIFT)
  21. #define MP886X_GO (1 << 6)
  22. #define MP886X_EN (1 << 7)
  23. #define MP8869_SYSCNTLREG2 0x02
  24. struct mp886x_cfg_info {
  25. const struct regulator_ops *rops;
  26. const unsigned int slew_rates[8];
  27. const int switch_freq[4];
  28. const u8 fs_reg;
  29. const u8 fs_shift;
  30. };
  31. struct mp886x_device_info {
  32. struct device *dev;
  33. struct regulator_desc desc;
  34. struct regulator_init_data *regulator;
  35. struct gpio_desc *en_gpio;
  36. const struct mp886x_cfg_info *ci;
  37. u32 r[2];
  38. unsigned int sel;
  39. };
  40. static void mp886x_set_switch_freq(struct mp886x_device_info *di,
  41. struct regmap *regmap,
  42. u32 freq)
  43. {
  44. const struct mp886x_cfg_info *ci = di->ci;
  45. int i;
  46. for (i = 0; i < ARRAY_SIZE(ci->switch_freq); i++) {
  47. if (freq == ci->switch_freq[i]) {
  48. regmap_update_bits(regmap, ci->fs_reg,
  49. 0x3 << ci->fs_shift, i << ci->fs_shift);
  50. return;
  51. }
  52. }
  53. dev_err(di->dev, "invalid frequency %d\n", freq);
  54. }
  55. static int mp886x_set_mode(struct regulator_dev *rdev, unsigned int mode)
  56. {
  57. switch (mode) {
  58. case REGULATOR_MODE_FAST:
  59. regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1,
  60. MP886X_MODE, MP886X_MODE);
  61. break;
  62. case REGULATOR_MODE_NORMAL:
  63. regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1,
  64. MP886X_MODE, 0);
  65. break;
  66. default:
  67. return -EINVAL;
  68. }
  69. return 0;
  70. }
  71. static unsigned int mp886x_get_mode(struct regulator_dev *rdev)
  72. {
  73. u32 val;
  74. int ret;
  75. ret = regmap_read(rdev->regmap, MP886X_SYSCNTLREG1, &val);
  76. if (ret < 0)
  77. return ret;
  78. if (val & MP886X_MODE)
  79. return REGULATOR_MODE_FAST;
  80. else
  81. return REGULATOR_MODE_NORMAL;
  82. }
  83. static int mp8869_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
  84. {
  85. int ret;
  86. ret = regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1,
  87. MP886X_GO, MP886X_GO);
  88. if (ret < 0)
  89. return ret;
  90. sel <<= ffs(rdev->desc->vsel_mask) - 1;
  91. return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
  92. MP886X_V_BOOT | rdev->desc->vsel_mask, sel);
  93. }
  94. static inline unsigned int mp8869_scale(unsigned int uv, u32 r1, u32 r2)
  95. {
  96. u32 tmp = uv * r1 / r2;
  97. return uv + tmp;
  98. }
  99. static int mp8869_get_voltage_sel(struct regulator_dev *rdev)
  100. {
  101. struct mp886x_device_info *di = rdev_get_drvdata(rdev);
  102. int ret, uv;
  103. unsigned int val;
  104. bool fbloop;
  105. ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
  106. if (ret)
  107. return ret;
  108. fbloop = val & MP886X_V_BOOT;
  109. if (fbloop) {
  110. uv = rdev->desc->min_uV;
  111. uv = mp8869_scale(uv, di->r[0], di->r[1]);
  112. return regulator_map_voltage_linear(rdev, uv, uv);
  113. }
  114. val &= rdev->desc->vsel_mask;
  115. val >>= ffs(rdev->desc->vsel_mask) - 1;
  116. return val;
  117. }
  118. static const struct regulator_ops mp8869_regulator_ops = {
  119. .set_voltage_sel = mp8869_set_voltage_sel,
  120. .get_voltage_sel = mp8869_get_voltage_sel,
  121. .set_voltage_time_sel = regulator_set_voltage_time_sel,
  122. .map_voltage = regulator_map_voltage_linear,
  123. .list_voltage = regulator_list_voltage_linear,
  124. .enable = regulator_enable_regmap,
  125. .disable = regulator_disable_regmap,
  126. .is_enabled = regulator_is_enabled_regmap,
  127. .set_mode = mp886x_set_mode,
  128. .get_mode = mp886x_get_mode,
  129. .set_ramp_delay = regulator_set_ramp_delay_regmap,
  130. };
  131. static const struct mp886x_cfg_info mp8869_ci = {
  132. .rops = &mp8869_regulator_ops,
  133. .slew_rates = {
  134. 40000,
  135. 30000,
  136. 20000,
  137. 10000,
  138. 5000,
  139. 2500,
  140. 1250,
  141. 625,
  142. },
  143. .switch_freq = {
  144. 500000,
  145. 750000,
  146. 1000000,
  147. 1250000,
  148. },
  149. .fs_reg = MP8869_SYSCNTLREG2,
  150. .fs_shift = 4,
  151. };
  152. static int mp8867_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
  153. {
  154. struct mp886x_device_info *di = rdev_get_drvdata(rdev);
  155. int ret, delta;
  156. ret = mp8869_set_voltage_sel(rdev, sel);
  157. if (ret < 0)
  158. return ret;
  159. delta = di->sel - sel;
  160. if (abs(delta) <= 5)
  161. ret = regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1,
  162. MP886X_GO, 0);
  163. di->sel = sel;
  164. return ret;
  165. }
  166. static int mp8867_get_voltage_sel(struct regulator_dev *rdev)
  167. {
  168. struct mp886x_device_info *di = rdev_get_drvdata(rdev);
  169. int ret, uv;
  170. unsigned int val;
  171. bool fbloop;
  172. ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
  173. if (ret)
  174. return ret;
  175. fbloop = val & MP886X_V_BOOT;
  176. val &= rdev->desc->vsel_mask;
  177. val >>= ffs(rdev->desc->vsel_mask) - 1;
  178. if (fbloop) {
  179. uv = regulator_list_voltage_linear(rdev, val);
  180. uv = mp8869_scale(uv, di->r[0], di->r[1]);
  181. return regulator_map_voltage_linear(rdev, uv, uv);
  182. }
  183. return val;
  184. }
  185. static const struct regulator_ops mp8867_regulator_ops = {
  186. .set_voltage_sel = mp8867_set_voltage_sel,
  187. .get_voltage_sel = mp8867_get_voltage_sel,
  188. .set_voltage_time_sel = regulator_set_voltage_time_sel,
  189. .map_voltage = regulator_map_voltage_linear,
  190. .list_voltage = regulator_list_voltage_linear,
  191. .enable = regulator_enable_regmap,
  192. .disable = regulator_disable_regmap,
  193. .is_enabled = regulator_is_enabled_regmap,
  194. .set_mode = mp886x_set_mode,
  195. .get_mode = mp886x_get_mode,
  196. .set_ramp_delay = regulator_set_ramp_delay_regmap,
  197. };
  198. static const struct mp886x_cfg_info mp8867_ci = {
  199. .rops = &mp8867_regulator_ops,
  200. .slew_rates = {
  201. 64000,
  202. 32000,
  203. 16000,
  204. 8000,
  205. 4000,
  206. 2000,
  207. 1000,
  208. 500,
  209. },
  210. .switch_freq = {
  211. 500000,
  212. 750000,
  213. 1000000,
  214. 1500000,
  215. },
  216. .fs_reg = MP886X_SYSCNTLREG1,
  217. .fs_shift = 1,
  218. };
  219. static int mp886x_regulator_register(struct mp886x_device_info *di,
  220. struct regulator_config *config)
  221. {
  222. struct regulator_desc *rdesc = &di->desc;
  223. struct regulator_dev *rdev;
  224. rdesc->name = "mp886x-reg";
  225. rdesc->supply_name = "vin";
  226. rdesc->ops = di->ci->rops;
  227. rdesc->type = REGULATOR_VOLTAGE;
  228. rdesc->n_voltages = 128;
  229. rdesc->enable_reg = MP886X_SYSCNTLREG1;
  230. rdesc->enable_mask = MP886X_EN;
  231. rdesc->min_uV = 600000;
  232. rdesc->uV_step = 10000;
  233. rdesc->vsel_reg = MP886X_VSEL;
  234. rdesc->vsel_mask = 0x3f;
  235. rdesc->ramp_reg = MP886X_SYSCNTLREG1;
  236. rdesc->ramp_mask = MP886X_SLEW_MASK;
  237. rdesc->ramp_delay_table = di->ci->slew_rates;
  238. rdesc->n_ramp_values = ARRAY_SIZE(di->ci->slew_rates);
  239. rdesc->owner = THIS_MODULE;
  240. rdev = devm_regulator_register(di->dev, &di->desc, config);
  241. if (IS_ERR(rdev))
  242. return PTR_ERR(rdev);
  243. di->sel = rdesc->ops->get_voltage_sel(rdev);
  244. return 0;
  245. }
  246. static const struct regmap_config mp886x_regmap_config = {
  247. .reg_bits = 8,
  248. .val_bits = 8,
  249. };
  250. static int mp886x_i2c_probe(struct i2c_client *client)
  251. {
  252. struct device *dev = &client->dev;
  253. struct device_node *np = dev->of_node;
  254. struct mp886x_device_info *di;
  255. struct regulator_config config = { };
  256. struct regmap *regmap;
  257. u32 freq;
  258. int ret;
  259. di = devm_kzalloc(dev, sizeof(struct mp886x_device_info), GFP_KERNEL);
  260. if (!di)
  261. return -ENOMEM;
  262. di->regulator = of_get_regulator_init_data(dev, np, &di->desc);
  263. if (!di->regulator) {
  264. dev_err(dev, "Platform data not found!\n");
  265. return -EINVAL;
  266. }
  267. ret = of_property_read_u32_array(np, "mps,fb-voltage-divider",
  268. di->r, 2);
  269. if (ret)
  270. return ret;
  271. di->en_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
  272. if (IS_ERR(di->en_gpio))
  273. return PTR_ERR(di->en_gpio);
  274. di->ci = of_device_get_match_data(dev);
  275. di->dev = dev;
  276. regmap = devm_regmap_init_i2c(client, &mp886x_regmap_config);
  277. if (IS_ERR(regmap)) {
  278. dev_err(dev, "Failed to allocate regmap!\n");
  279. return PTR_ERR(regmap);
  280. }
  281. i2c_set_clientdata(client, di);
  282. config.dev = di->dev;
  283. config.init_data = di->regulator;
  284. config.regmap = regmap;
  285. config.driver_data = di;
  286. config.of_node = np;
  287. if (!of_property_read_u32(np, "mps,switch-frequency-hz", &freq))
  288. mp886x_set_switch_freq(di, regmap, freq);
  289. ret = mp886x_regulator_register(di, &config);
  290. if (ret < 0)
  291. dev_err(dev, "Failed to register regulator!\n");
  292. return ret;
  293. }
  294. static const struct of_device_id mp886x_dt_ids[] = {
  295. {
  296. .compatible = "mps,mp8867",
  297. .data = &mp8867_ci
  298. },
  299. {
  300. .compatible = "mps,mp8869",
  301. .data = &mp8869_ci
  302. },
  303. { }
  304. };
  305. MODULE_DEVICE_TABLE(of, mp886x_dt_ids);
  306. static const struct i2c_device_id mp886x_id[] = {
  307. { "mp886x", },
  308. { },
  309. };
  310. MODULE_DEVICE_TABLE(i2c, mp886x_id);
  311. static struct i2c_driver mp886x_regulator_driver = {
  312. .driver = {
  313. .name = "mp886x-regulator",
  314. .of_match_table = of_match_ptr(mp886x_dt_ids),
  315. },
  316. .probe_new = mp886x_i2c_probe,
  317. .id_table = mp886x_id,
  318. };
  319. module_i2c_driver(mp886x_regulator_driver);
  320. MODULE_AUTHOR("Jisheng Zhang <[email protected]>");
  321. MODULE_DESCRIPTION("MP886x regulator driver");
  322. MODULE_LICENSE("GPL v2");