rt5739.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Device driver for RT5739 regulator
  4. *
  5. * Copyright (C) 2023 Richtek Technology Corp.
  6. *
  7. * Author: ChiYuan Huang <cy_huang@richtek.com>
  8. */
  9. #include <linux/bits.h>
  10. #include <linux/gpio/consumer.h>
  11. #include <linux/i2c.h>
  12. #include <linux/kernel.h>
  13. #include <linux/mod_devicetable.h>
  14. #include <linux/property.h>
  15. #include <linux/regmap.h>
  16. #include <linux/regulator/driver.h>
  17. #include <linux/regulator/of_regulator.h>
  18. #define RT5739_AUTO_MODE 0
  19. #define RT5739_FPWM_MODE 1
  20. #define RT5739_REG_NSEL0 0x00
  21. #define RT5739_REG_NSEL1 0x01
  22. #define RT5739_REG_CNTL1 0x02
  23. #define RT5739_REG_ID1 0x03
  24. #define RT5739_REG_CNTL2 0x06
  25. #define RT5739_REG_CNTL4 0x08
  26. #define RT5739_VSEL_MASK GENMASK(7, 0)
  27. #define RT5739_MODEVSEL1_MASK BIT(1)
  28. #define RT5739_MODEVSEL0_MASK BIT(0)
  29. #define RT5739_VID_MASK GENMASK(7, 5)
  30. #define RT5739_DID_MASK GENMASK(3, 0)
  31. #define RT5739_ACTD_MASK BIT(7)
  32. #define RT5739_ENVSEL1_MASK BIT(1)
  33. #define RT5739_ENVSEL0_MASK BIT(0)
  34. #define RT5733_CHIPDIE_ID 0x1
  35. #define RT5733_VOLT_MINUV 270000
  36. #define RT5733_VOLT_MAXUV 1401250
  37. #define RT5733_VOLT_STPUV 6250
  38. #define RT5733_N_VOLTS 182
  39. #define RT5739_VOLT_MINUV 300000
  40. #define RT5739_VOLT_MAXUV 1300000
  41. #define RT5739_VOLT_STPUV 5000
  42. #define RT5739_N_VOLTS 201
  43. #define RT5739_I2CRDY_TIMEUS 1000
  44. static int rt5739_set_mode(struct regulator_dev *rdev, unsigned int mode)
  45. {
  46. const struct regulator_desc *desc = rdev->desc;
  47. struct regmap *regmap = rdev_get_regmap(rdev);
  48. unsigned int mask, val;
  49. if (desc->vsel_reg == RT5739_REG_NSEL0)
  50. mask = RT5739_MODEVSEL0_MASK;
  51. else
  52. mask = RT5739_MODEVSEL1_MASK;
  53. switch (mode) {
  54. case REGULATOR_MODE_FAST:
  55. val = mask;
  56. break;
  57. case REGULATOR_MODE_NORMAL:
  58. val = 0;
  59. break;
  60. default:
  61. return -EINVAL;
  62. }
  63. return regmap_update_bits(regmap, RT5739_REG_CNTL1, mask, val);
  64. }
  65. static unsigned int rt5739_get_mode(struct regulator_dev *rdev)
  66. {
  67. const struct regulator_desc *desc = rdev->desc;
  68. struct regmap *regmap = rdev_get_regmap(rdev);
  69. unsigned int mask, val;
  70. int ret;
  71. if (desc->vsel_reg == RT5739_REG_NSEL0)
  72. mask = RT5739_MODEVSEL0_MASK;
  73. else
  74. mask = RT5739_MODEVSEL1_MASK;
  75. ret = regmap_read(regmap, RT5739_REG_CNTL1, &val);
  76. if (ret)
  77. return REGULATOR_MODE_INVALID;
  78. if (val & mask)
  79. return REGULATOR_MODE_FAST;
  80. return REGULATOR_MODE_NORMAL;
  81. }
  82. static int rt5739_set_suspend_voltage(struct regulator_dev *rdev, int uV)
  83. {
  84. const struct regulator_desc *desc = rdev->desc;
  85. struct regmap *regmap = rdev_get_regmap(rdev);
  86. unsigned int reg, vsel;
  87. int max_uV;
  88. max_uV = desc->min_uV + desc->uV_step * (desc->n_voltages - 1);
  89. if (uV < desc->min_uV || uV > max_uV)
  90. return -EINVAL;
  91. if (desc->vsel_reg == RT5739_REG_NSEL0)
  92. reg = RT5739_REG_NSEL1;
  93. else
  94. reg = RT5739_REG_NSEL0;
  95. vsel = (uV - desc->min_uV) / desc->uV_step;
  96. return regmap_write(regmap, reg, vsel);
  97. }
  98. static int rt5739_set_suspend_enable(struct regulator_dev *rdev)
  99. {
  100. const struct regulator_desc *desc = rdev->desc;
  101. struct regmap *regmap = rdev_get_regmap(rdev);
  102. unsigned int mask;
  103. if (desc->vsel_reg == RT5739_REG_NSEL0)
  104. mask = RT5739_ENVSEL1_MASK;
  105. else
  106. mask = RT5739_ENVSEL0_MASK;
  107. return regmap_update_bits(regmap, desc->enable_reg, mask, mask);
  108. }
  109. static int rt5739_set_suspend_disable(struct regulator_dev *rdev)
  110. {
  111. const struct regulator_desc *desc = rdev->desc;
  112. struct regmap *regmap = rdev_get_regmap(rdev);
  113. unsigned int mask;
  114. if (desc->vsel_reg == RT5739_REG_NSEL0)
  115. mask = RT5739_ENVSEL1_MASK;
  116. else
  117. mask = RT5739_ENVSEL0_MASK;
  118. return regmap_update_bits(regmap, desc->enable_reg, mask, 0);
  119. }
  120. static int rt5739_set_suspend_mode(struct regulator_dev *rdev,
  121. unsigned int mode)
  122. {
  123. const struct regulator_desc *desc = rdev->desc;
  124. struct regmap *regmap = rdev_get_regmap(rdev);
  125. unsigned int mask, val;
  126. if (desc->vsel_reg == RT5739_REG_NSEL0)
  127. mask = RT5739_MODEVSEL1_MASK;
  128. else
  129. mask = RT5739_MODEVSEL0_MASK;
  130. switch (mode) {
  131. case REGULATOR_MODE_FAST:
  132. val = mask;
  133. break;
  134. case REGULATOR_MODE_NORMAL:
  135. val = 0;
  136. break;
  137. default:
  138. return -EINVAL;
  139. }
  140. return regmap_update_bits(regmap, RT5739_REG_CNTL1, mask, val);
  141. }
  142. static const struct regulator_ops rt5739_regulator_ops = {
  143. .list_voltage = regulator_list_voltage_linear,
  144. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  145. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  146. .enable = regulator_enable_regmap,
  147. .disable = regulator_disable_regmap,
  148. .is_enabled = regulator_is_enabled_regmap,
  149. .set_active_discharge = regulator_set_active_discharge_regmap,
  150. .set_mode = rt5739_set_mode,
  151. .get_mode = rt5739_get_mode,
  152. .set_suspend_voltage = rt5739_set_suspend_voltage,
  153. .set_suspend_enable = rt5739_set_suspend_enable,
  154. .set_suspend_disable = rt5739_set_suspend_disable,
  155. .set_suspend_mode = rt5739_set_suspend_mode,
  156. };
  157. static unsigned int rt5739_of_map_mode(unsigned int mode)
  158. {
  159. switch (mode) {
  160. case RT5739_AUTO_MODE:
  161. return REGULATOR_MODE_NORMAL;
  162. case RT5739_FPWM_MODE:
  163. return REGULATOR_MODE_FAST;
  164. default:
  165. return REGULATOR_MODE_INVALID;
  166. }
  167. }
  168. static void rt5739_init_regulator_desc(struct regulator_desc *desc,
  169. bool vsel_active_high, u8 did)
  170. {
  171. /* Fixed */
  172. desc->name = "rt5739-regulator";
  173. desc->owner = THIS_MODULE;
  174. desc->ops = &rt5739_regulator_ops;
  175. desc->vsel_mask = RT5739_VSEL_MASK;
  176. desc->enable_reg = RT5739_REG_CNTL2;
  177. desc->active_discharge_reg = RT5739_REG_CNTL1;
  178. desc->active_discharge_mask = RT5739_ACTD_MASK;
  179. desc->active_discharge_on = RT5739_ACTD_MASK;
  180. desc->of_map_mode = rt5739_of_map_mode;
  181. /* Assigned by vsel level */
  182. if (vsel_active_high) {
  183. desc->vsel_reg = RT5739_REG_NSEL1;
  184. desc->enable_mask = RT5739_ENVSEL1_MASK;
  185. } else {
  186. desc->vsel_reg = RT5739_REG_NSEL0;
  187. desc->enable_mask = RT5739_ENVSEL0_MASK;
  188. }
  189. /* Assigned by CHIPDIE ID */
  190. switch (did) {
  191. case RT5733_CHIPDIE_ID:
  192. desc->n_voltages = RT5733_N_VOLTS;
  193. desc->min_uV = RT5733_VOLT_MINUV;
  194. desc->uV_step = RT5733_VOLT_STPUV;
  195. break;
  196. default:
  197. desc->n_voltages = RT5739_N_VOLTS;
  198. desc->min_uV = RT5739_VOLT_MINUV;
  199. desc->uV_step = RT5739_VOLT_STPUV;
  200. break;
  201. }
  202. }
  203. static const struct regmap_config rt5739_regmap_config = {
  204. .name = "rt5739",
  205. .reg_bits = 8,
  206. .val_bits = 8,
  207. .max_register = RT5739_REG_CNTL4,
  208. };
  209. static int rt5739_probe(struct i2c_client *i2c)
  210. {
  211. struct device *dev = &i2c->dev;
  212. struct regulator_desc *desc;
  213. struct regmap *regmap;
  214. struct gpio_desc *enable_gpio;
  215. struct regulator_config cfg = {};
  216. struct regulator_dev *rdev;
  217. bool vsel_acth;
  218. unsigned int vid;
  219. int ret;
  220. desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
  221. if (!desc)
  222. return -ENOMEM;
  223. enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
  224. if (IS_ERR(enable_gpio))
  225. return dev_err_probe(dev, PTR_ERR(enable_gpio), "Failed to get 'enable' gpio\n");
  226. else if (enable_gpio)
  227. usleep_range(RT5739_I2CRDY_TIMEUS, RT5739_I2CRDY_TIMEUS + 1000);
  228. regmap = devm_regmap_init_i2c(i2c, &rt5739_regmap_config);
  229. if (IS_ERR(regmap))
  230. return dev_err_probe(dev, PTR_ERR(regmap), "Failed to init regmap\n");
  231. ret = regmap_read(regmap, RT5739_REG_ID1, &vid);
  232. if (ret)
  233. return dev_err_probe(dev, ret, "Failed to read VID\n");
  234. /* RT5739: (VID & MASK) must be 0 */
  235. if (vid & RT5739_VID_MASK)
  236. return dev_err_probe(dev, -ENODEV, "Incorrect VID (0x%02x)\n", vid);
  237. vsel_acth = device_property_read_bool(dev, "richtek,vsel-active-high");
  238. rt5739_init_regulator_desc(desc, vsel_acth, vid & RT5739_DID_MASK);
  239. cfg.dev = dev;
  240. cfg.of_node = dev_of_node(dev);
  241. cfg.init_data = of_get_regulator_init_data(dev, dev_of_node(dev), desc);
  242. rdev = devm_regulator_register(dev, desc, &cfg);
  243. if (IS_ERR(rdev))
  244. return dev_err_probe(dev, PTR_ERR(rdev), "Failed to register regulator\n");
  245. return 0;
  246. }
  247. static const struct of_device_id rt5739_device_table[] = {
  248. { .compatible = "richtek,rt5733" },
  249. { .compatible = "richtek,rt5739" },
  250. { /* sentinel */ }
  251. };
  252. MODULE_DEVICE_TABLE(of, rt5739_device_table);
  253. static struct i2c_driver rt5739_driver = {
  254. .driver = {
  255. .name = "rt5739",
  256. .probe_type = PROBE_PREFER_ASYNCHRONOUS,
  257. .of_match_table = rt5739_device_table,
  258. },
  259. .probe = rt5739_probe,
  260. };
  261. module_i2c_driver(rt5739_driver);
  262. MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
  263. MODULE_DESCRIPTION("Richtek RT5739 regulator driver");
  264. MODULE_LICENSE("GPL");