mp886x.c 8.8 KB

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