mt6370-regulator.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. // SPDX-License-Identifier: GPL-2.0+
  2. #include <linux/bits.h>
  3. #include <linux/gpio/consumer.h>
  4. #include <linux/interrupt.h>
  5. #include <linux/kernel.h>
  6. #include <linux/mod_devicetable.h>
  7. #include <linux/module.h>
  8. #include <linux/of.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/regmap.h>
  11. #include <linux/regulator/driver.h>
  12. #include <linux/regulator/machine.h>
  13. enum {
  14. MT6370_IDX_DSVBOOST = 0,
  15. MT6370_IDX_DSVPOS,
  16. MT6370_IDX_DSVNEG,
  17. MT6370_IDX_VIBLDO,
  18. MT6370_MAX_IDX
  19. };
  20. #define MT6370_REG_LDO_CFG 0x180
  21. #define MT6370_REG_LDO_VOUT 0x181
  22. #define MT6370_REG_DB_CTRL1 0x1B0
  23. #define MT6370_REG_DB_CTRL2 0x1B1
  24. #define MT6370_REG_DB_VBST 0x1B2
  25. #define MT6370_REG_DB_VPOS 0x1B3
  26. #define MT6370_REG_DB_VNEG 0x1B4
  27. #define MT6370_REG_LDO_STAT 0x1DC
  28. #define MT6370_REG_DB_STAT 0x1DF
  29. #define MT6370_LDOOMS_MASK BIT(7)
  30. #define MT6370_LDOEN_MASK BIT(7)
  31. #define MT6370_LDOVOUT_MASK GENMASK(3, 0)
  32. #define MT6370_DBPERD_MASK (BIT(7) | BIT(4))
  33. #define MT6370_DBEXTEN_MASK BIT(0)
  34. #define MT6370_DBVPOSEN_MASK BIT(6)
  35. #define MT6370_DBVPOSDISG_MASK BIT(5)
  36. #define MT6370_DBVNEGEN_MASK BIT(3)
  37. #define MT6370_DBVNEGDISG_MASK BIT(2)
  38. #define MT6370_DBALLON_MASK (MT6370_DBVPOSEN_MASK | MT6370_DBVNEGEN_MASK)
  39. #define MT6370_DBSLEW_MASK GENMASK(7, 6)
  40. #define MT6370_DBVOUT_MASK GENMASK(5, 0)
  41. #define MT6370_LDOOC_EVT_MASK BIT(7)
  42. #define MT6370_POSSCP_EVT_MASK BIT(7)
  43. #define MT6370_NEGSCP_EVT_MASK BIT(6)
  44. #define MT6370_BSTOCP_EVT_MASK BIT(5)
  45. #define MT6370_POSOCP_EVT_MASK BIT(4)
  46. #define MT6370_NEGOCP_EVT_MASK BIT(3)
  47. #define MT6370_LDO_MINUV 1600000
  48. #define MT6370_LDO_STPUV 200000
  49. #define MT6370_LDO_N_VOLT 13
  50. #define MT6370_DBVBOOST_MINUV 4000000
  51. #define MT6370_DBVBOOST_STPUV 50000
  52. #define MT6370_DBVBOOST_N_VOLT 45
  53. #define MT6370_DBVOUT_MINUV 4000000
  54. #define MT6370_DBVOUT_STPUV 50000
  55. #define MT6370_DBVOUT_N_VOLT 41
  56. struct mt6370_priv {
  57. struct device *dev;
  58. struct regmap *regmap;
  59. struct regulator_dev *rdev[MT6370_MAX_IDX];
  60. bool use_external_ctrl;
  61. };
  62. static const unsigned int mt6370_vpos_ramp_tbl[] = { 8540, 5840, 4830, 3000 };
  63. static const unsigned int mt6370_vneg_ramp_tbl[] = { 10090, 6310, 5050, 3150 };
  64. static int mt6370_get_error_flags(struct regulator_dev *rdev,
  65. unsigned int *flags)
  66. {
  67. struct regmap *regmap = rdev_get_regmap(rdev);
  68. unsigned int stat_reg, stat, rpt_flags = 0;
  69. int rid = rdev_get_id(rdev), ret;
  70. if (rid == MT6370_IDX_VIBLDO)
  71. stat_reg = MT6370_REG_LDO_STAT;
  72. else
  73. stat_reg = MT6370_REG_DB_STAT;
  74. ret = regmap_read(regmap, stat_reg, &stat);
  75. if (ret)
  76. return ret;
  77. switch (rid) {
  78. case MT6370_IDX_DSVBOOST:
  79. if (stat & MT6370_BSTOCP_EVT_MASK)
  80. rpt_flags |= REGULATOR_ERROR_OVER_CURRENT;
  81. break;
  82. case MT6370_IDX_DSVPOS:
  83. if (stat & MT6370_POSSCP_EVT_MASK)
  84. rpt_flags |= REGULATOR_ERROR_UNDER_VOLTAGE;
  85. if (stat & MT6370_POSOCP_EVT_MASK)
  86. rpt_flags |= REGULATOR_ERROR_OVER_CURRENT;
  87. break;
  88. case MT6370_IDX_DSVNEG:
  89. if (stat & MT6370_NEGSCP_EVT_MASK)
  90. rpt_flags |= REGULATOR_ERROR_UNDER_VOLTAGE;
  91. if (stat & MT6370_NEGOCP_EVT_MASK)
  92. rpt_flags |= REGULATOR_ERROR_OVER_CURRENT;
  93. break;
  94. default:
  95. if (stat & MT6370_LDOOC_EVT_MASK)
  96. rpt_flags |= REGULATOR_ERROR_OVER_CURRENT;
  97. break;
  98. }
  99. *flags = rpt_flags;
  100. return 0;
  101. }
  102. static const struct regulator_ops mt6370_dbvboost_ops = {
  103. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  104. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  105. .list_voltage = regulator_list_voltage_linear,
  106. .get_bypass = regulator_get_bypass_regmap,
  107. .set_bypass = regulator_set_bypass_regmap,
  108. .get_error_flags = mt6370_get_error_flags,
  109. };
  110. static const struct regulator_ops mt6370_dbvout_ops = {
  111. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  112. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  113. .list_voltage = regulator_list_voltage_linear,
  114. .is_enabled = regulator_is_enabled_regmap,
  115. .enable = regulator_enable_regmap,
  116. .disable = regulator_disable_regmap,
  117. .set_active_discharge = regulator_set_active_discharge_regmap,
  118. .set_ramp_delay = regulator_set_ramp_delay_regmap,
  119. .get_error_flags = mt6370_get_error_flags,
  120. };
  121. static const struct regulator_ops mt6370_ldo_ops = {
  122. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  123. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  124. .list_voltage = regulator_list_voltage_linear,
  125. .is_enabled = regulator_is_enabled_regmap,
  126. .enable = regulator_enable_regmap,
  127. .disable = regulator_disable_regmap,
  128. .set_active_discharge = regulator_set_active_discharge_regmap,
  129. .get_error_flags = mt6370_get_error_flags,
  130. };
  131. static int mt6370_of_parse_cb(struct device_node *np,
  132. const struct regulator_desc *desc,
  133. struct regulator_config *config)
  134. {
  135. struct mt6370_priv *priv = config->driver_data;
  136. struct gpio_desc *enable_gpio;
  137. int ret;
  138. enable_gpio = fwnode_gpiod_get_index(of_fwnode_handle(np), "enable", 0,
  139. GPIOD_OUT_HIGH |
  140. GPIOD_FLAGS_BIT_NONEXCLUSIVE,
  141. desc->name);
  142. if (IS_ERR(enable_gpio)) {
  143. config->ena_gpiod = NULL;
  144. return 0;
  145. }
  146. /*
  147. * RG control by default
  148. * Only if all are using external pin, change all by external control
  149. */
  150. if (priv->use_external_ctrl) {
  151. ret = regmap_update_bits(priv->regmap, MT6370_REG_DB_CTRL1,
  152. MT6370_DBEXTEN_MASK,
  153. MT6370_DBEXTEN_MASK);
  154. if (ret)
  155. return ret;
  156. }
  157. config->ena_gpiod = enable_gpio;
  158. priv->use_external_ctrl = true;
  159. return 0;
  160. }
  161. static const struct regulator_desc mt6370_regulator_descs[] = {
  162. {
  163. .name = "mt6370-dsv-vbst",
  164. .of_match = of_match_ptr("dsvbst"),
  165. .regulators_node = of_match_ptr("regulators"),
  166. .id = MT6370_IDX_DSVBOOST,
  167. .type = REGULATOR_VOLTAGE,
  168. .owner = THIS_MODULE,
  169. .ops = &mt6370_dbvboost_ops,
  170. .min_uV = MT6370_DBVBOOST_MINUV,
  171. .uV_step = MT6370_DBVBOOST_STPUV,
  172. .n_voltages = MT6370_DBVBOOST_N_VOLT,
  173. .vsel_reg = MT6370_REG_DB_VBST,
  174. .vsel_mask = MT6370_DBVOUT_MASK,
  175. .bypass_reg = MT6370_REG_DB_CTRL1,
  176. .bypass_mask = MT6370_DBPERD_MASK,
  177. .bypass_val_on = MT6370_DBPERD_MASK,
  178. },
  179. {
  180. .name = "mt6370-dsv-vpos",
  181. .of_match = of_match_ptr("dsvpos"),
  182. .regulators_node = of_match_ptr("regulators"),
  183. .id = MT6370_IDX_DSVPOS,
  184. .type = REGULATOR_VOLTAGE,
  185. .owner = THIS_MODULE,
  186. .of_parse_cb = mt6370_of_parse_cb,
  187. .ops = &mt6370_dbvout_ops,
  188. .min_uV = MT6370_DBVOUT_MINUV,
  189. .uV_step = MT6370_DBVOUT_STPUV,
  190. .n_voltages = MT6370_DBVOUT_N_VOLT,
  191. .vsel_reg = MT6370_REG_DB_VPOS,
  192. .vsel_mask = MT6370_DBVOUT_MASK,
  193. .enable_reg = MT6370_REG_DB_CTRL2,
  194. .enable_mask = MT6370_DBVPOSEN_MASK,
  195. .ramp_reg = MT6370_REG_DB_VPOS,
  196. .ramp_mask = MT6370_DBSLEW_MASK,
  197. .ramp_delay_table = mt6370_vpos_ramp_tbl,
  198. .n_ramp_values = ARRAY_SIZE(mt6370_vpos_ramp_tbl),
  199. .active_discharge_reg = MT6370_REG_DB_CTRL2,
  200. .active_discharge_mask = MT6370_DBVPOSDISG_MASK,
  201. .active_discharge_on = MT6370_DBVPOSDISG_MASK,
  202. },
  203. {
  204. .name = "mt6370-dsv-vneg",
  205. .of_match = of_match_ptr("dsvneg"),
  206. .regulators_node = of_match_ptr("regulators"),
  207. .id = MT6370_IDX_DSVNEG,
  208. .type = REGULATOR_VOLTAGE,
  209. .owner = THIS_MODULE,
  210. .of_parse_cb = mt6370_of_parse_cb,
  211. .ops = &mt6370_dbvout_ops,
  212. .min_uV = MT6370_DBVOUT_MINUV,
  213. .uV_step = MT6370_DBVOUT_STPUV,
  214. .n_voltages = MT6370_DBVOUT_N_VOLT,
  215. .vsel_reg = MT6370_REG_DB_VNEG,
  216. .vsel_mask = MT6370_DBVOUT_MASK,
  217. .enable_reg = MT6370_REG_DB_CTRL2,
  218. .enable_mask = MT6370_DBVNEGEN_MASK,
  219. .ramp_reg = MT6370_REG_DB_VNEG,
  220. .ramp_mask = MT6370_DBSLEW_MASK,
  221. .ramp_delay_table = mt6370_vneg_ramp_tbl,
  222. .n_ramp_values = ARRAY_SIZE(mt6370_vneg_ramp_tbl),
  223. .active_discharge_reg = MT6370_REG_DB_CTRL2,
  224. .active_discharge_mask = MT6370_DBVNEGDISG_MASK,
  225. .active_discharge_on = MT6370_DBVNEGDISG_MASK,
  226. },
  227. {
  228. .name = "mt6370-vib-ldo",
  229. .of_match = of_match_ptr("vibldo"),
  230. .regulators_node = of_match_ptr("regulators"),
  231. .id = MT6370_IDX_VIBLDO,
  232. .type = REGULATOR_VOLTAGE,
  233. .owner = THIS_MODULE,
  234. .ops = &mt6370_ldo_ops,
  235. .min_uV = MT6370_LDO_MINUV,
  236. .uV_step = MT6370_LDO_STPUV,
  237. .n_voltages = MT6370_LDO_N_VOLT,
  238. .vsel_reg = MT6370_REG_LDO_VOUT,
  239. .vsel_mask = MT6370_LDOVOUT_MASK,
  240. .enable_reg = MT6370_REG_LDO_VOUT,
  241. .enable_mask = MT6370_LDOEN_MASK,
  242. .active_discharge_reg = MT6370_REG_LDO_CFG,
  243. .active_discharge_mask = MT6370_LDOOMS_MASK,
  244. .active_discharge_on = MT6370_LDOOMS_MASK,
  245. }
  246. };
  247. static irqreturn_t mt6370_scp_handler(int irq, void *data)
  248. {
  249. struct regulator_dev *rdev = data;
  250. regulator_notifier_call_chain(rdev, REGULATOR_EVENT_UNDER_VOLTAGE,
  251. NULL);
  252. return IRQ_HANDLED;
  253. }
  254. static irqreturn_t mt6370_ocp_handler(int irq, void *data)
  255. {
  256. struct regulator_dev *rdev = data;
  257. regulator_notifier_call_chain(rdev, REGULATOR_EVENT_OVER_CURRENT, NULL);
  258. return IRQ_HANDLED;
  259. }
  260. static int mt6370_regulator_irq_register(struct mt6370_priv *priv)
  261. {
  262. struct platform_device *pdev = to_platform_device(priv->dev);
  263. static const struct {
  264. const char *name;
  265. int rid;
  266. irq_handler_t handler;
  267. } mt6370_irqs[] = {
  268. { "db_vpos_scp", MT6370_IDX_DSVPOS, mt6370_scp_handler },
  269. { "db_vneg_scp", MT6370_IDX_DSVNEG, mt6370_scp_handler },
  270. { "db_vbst_ocp", MT6370_IDX_DSVBOOST, mt6370_ocp_handler },
  271. { "db_vpos_ocp", MT6370_IDX_DSVPOS, mt6370_ocp_handler },
  272. { "db_vneg_ocp", MT6370_IDX_DSVNEG, mt6370_ocp_handler },
  273. { "ldo_oc", MT6370_IDX_VIBLDO, mt6370_ocp_handler }
  274. };
  275. struct regulator_dev *rdev;
  276. int i, irq, ret;
  277. for (i = 0; i < ARRAY_SIZE(mt6370_irqs); i++) {
  278. irq = platform_get_irq_byname(pdev, mt6370_irqs[i].name);
  279. rdev = priv->rdev[mt6370_irqs[i].rid];
  280. ret = devm_request_threaded_irq(priv->dev, irq, NULL,
  281. mt6370_irqs[i].handler, 0,
  282. mt6370_irqs[i].name, rdev);
  283. if (ret) {
  284. dev_err(priv->dev,
  285. "Failed to register (%d) interrupt\n", i);
  286. return ret;
  287. }
  288. }
  289. return 0;
  290. }
  291. static int mt6370_regualtor_register(struct mt6370_priv *priv)
  292. {
  293. struct regulator_dev *rdev;
  294. struct regulator_config cfg = {};
  295. struct device *parent = priv->dev->parent;
  296. int i;
  297. cfg.dev = parent;
  298. cfg.driver_data = priv;
  299. for (i = 0; i < MT6370_MAX_IDX; i++) {
  300. rdev = devm_regulator_register(priv->dev,
  301. mt6370_regulator_descs + i,
  302. &cfg);
  303. if (IS_ERR(rdev)) {
  304. dev_err(priv->dev,
  305. "Failed to register (%d) regulator\n", i);
  306. return PTR_ERR(rdev);
  307. }
  308. priv->rdev[i] = rdev;
  309. }
  310. return 0;
  311. }
  312. static int mt6370_regulator_probe(struct platform_device *pdev)
  313. {
  314. struct mt6370_priv *priv;
  315. int ret;
  316. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  317. if (!priv)
  318. return -ENOMEM;
  319. priv->dev = &pdev->dev;
  320. priv->regmap = dev_get_regmap(pdev->dev.parent, NULL);
  321. if (!priv->regmap) {
  322. dev_err(&pdev->dev, "Failed to init regmap\n");
  323. return -ENODEV;
  324. }
  325. ret = mt6370_regualtor_register(priv);
  326. if (ret)
  327. return ret;
  328. return mt6370_regulator_irq_register(priv);
  329. }
  330. static const struct platform_device_id mt6370_devid_table[] = {
  331. { "mt6370-regulator", 0},
  332. {}
  333. };
  334. MODULE_DEVICE_TABLE(platform, mt6370_devid_table);
  335. static struct platform_driver mt6370_regulator_driver = {
  336. .driver = {
  337. .name = "mt6370-regulator",
  338. },
  339. .id_table = mt6370_devid_table,
  340. .probe = mt6370_regulator_probe,
  341. };
  342. module_platform_driver(mt6370_regulator_driver);
  343. MODULE_AUTHOR("ChiYuan Huang <[email protected]>");
  344. MODULE_DESCRIPTION("Mediatek MT6370 Regulator Driver");
  345. MODULE_LICENSE("GPL v2");