tps65090-regulator.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /*
  2. * Regulator driver for tps65090 power management chip.
  3. *
  4. * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. * This program is distributed in the hope it will be useful, but WITHOUT
  9. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. * more details.
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>
  14. */
  15. #include <linux/module.h>
  16. #include <linux/init.h>
  17. #include <linux/gpio.h>
  18. #include <linux/of_gpio.h>
  19. #include <linux/slab.h>
  20. #include <linux/err.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/regulator/driver.h>
  23. #include <linux/regulator/machine.h>
  24. #include <linux/regulator/of_regulator.h>
  25. #include <linux/mfd/tps65090.h>
  26. struct tps65090_regulator {
  27. struct device *dev;
  28. struct regulator_desc *desc;
  29. struct regulator_dev *rdev;
  30. };
  31. static struct regulator_ops tps65090_ext_control_ops = {
  32. };
  33. static struct regulator_ops tps65090_reg_contol_ops = {
  34. .enable = regulator_enable_regmap,
  35. .disable = regulator_disable_regmap,
  36. .is_enabled = regulator_is_enabled_regmap,
  37. };
  38. static struct regulator_ops tps65090_ldo_ops = {
  39. };
  40. #define tps65090_REG_DESC(_id, _sname, _en_reg, _ops) \
  41. { \
  42. .name = "TPS65090_RAILS"#_id, \
  43. .supply_name = _sname, \
  44. .id = TPS65090_REGULATOR_##_id, \
  45. .ops = &_ops, \
  46. .enable_reg = _en_reg, \
  47. .enable_mask = BIT(0), \
  48. .type = REGULATOR_VOLTAGE, \
  49. .owner = THIS_MODULE, \
  50. }
  51. static struct regulator_desc tps65090_regulator_desc[] = {
  52. tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, tps65090_reg_contol_ops),
  53. tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, tps65090_reg_contol_ops),
  54. tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, tps65090_reg_contol_ops),
  55. tps65090_REG_DESC(FET1, "infet1", 0x0F, tps65090_reg_contol_ops),
  56. tps65090_REG_DESC(FET2, "infet2", 0x10, tps65090_reg_contol_ops),
  57. tps65090_REG_DESC(FET3, "infet3", 0x11, tps65090_reg_contol_ops),
  58. tps65090_REG_DESC(FET4, "infet4", 0x12, tps65090_reg_contol_ops),
  59. tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_reg_contol_ops),
  60. tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_reg_contol_ops),
  61. tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_reg_contol_ops),
  62. tps65090_REG_DESC(LDO1, "vsys-l1", 0, tps65090_ldo_ops),
  63. tps65090_REG_DESC(LDO2, "vsys-l2", 0, tps65090_ldo_ops),
  64. };
  65. static inline bool is_dcdc(int id)
  66. {
  67. switch (id) {
  68. case TPS65090_REGULATOR_DCDC1:
  69. case TPS65090_REGULATOR_DCDC2:
  70. case TPS65090_REGULATOR_DCDC3:
  71. return true;
  72. default:
  73. return false;
  74. }
  75. }
  76. static int tps65090_config_ext_control(
  77. struct tps65090_regulator *ri, bool enable)
  78. {
  79. int ret;
  80. struct device *parent = ri->dev->parent;
  81. unsigned int reg_en_reg = ri->desc->enable_reg;
  82. if (enable)
  83. ret = tps65090_set_bits(parent, reg_en_reg, 1);
  84. else
  85. ret = tps65090_clr_bits(parent, reg_en_reg, 1);
  86. if (ret < 0)
  87. dev_err(ri->dev, "Error in updating reg 0x%x\n", reg_en_reg);
  88. return ret;
  89. }
  90. static int tps65090_regulator_disable_ext_control(
  91. struct tps65090_regulator *ri,
  92. struct tps65090_regulator_plat_data *tps_pdata)
  93. {
  94. int ret = 0;
  95. struct device *parent = ri->dev->parent;
  96. unsigned int reg_en_reg = ri->desc->enable_reg;
  97. /*
  98. * First enable output for internal control if require.
  99. * And then disable external control.
  100. */
  101. if (tps_pdata->reg_init_data->constraints.always_on ||
  102. tps_pdata->reg_init_data->constraints.boot_on) {
  103. ret = tps65090_set_bits(parent, reg_en_reg, 0);
  104. if (ret < 0) {
  105. dev_err(ri->dev, "Error in set reg 0x%x\n", reg_en_reg);
  106. return ret;
  107. }
  108. }
  109. return tps65090_config_ext_control(ri, false);
  110. }
  111. static void tps65090_configure_regulator_config(
  112. struct tps65090_regulator_plat_data *tps_pdata,
  113. struct regulator_config *config)
  114. {
  115. if (gpio_is_valid(tps_pdata->gpio)) {
  116. int gpio_flag = GPIOF_OUT_INIT_LOW;
  117. if (tps_pdata->reg_init_data->constraints.always_on ||
  118. tps_pdata->reg_init_data->constraints.boot_on)
  119. gpio_flag = GPIOF_OUT_INIT_HIGH;
  120. config->ena_gpio = tps_pdata->gpio;
  121. config->ena_gpio_flags = gpio_flag;
  122. }
  123. }
  124. #ifdef CONFIG_OF
  125. static struct of_regulator_match tps65090_matches[] = {
  126. { .name = "dcdc1", },
  127. { .name = "dcdc2", },
  128. { .name = "dcdc3", },
  129. { .name = "fet1", },
  130. { .name = "fet2", },
  131. { .name = "fet3", },
  132. { .name = "fet4", },
  133. { .name = "fet5", },
  134. { .name = "fet6", },
  135. { .name = "fet7", },
  136. { .name = "ldo1", },
  137. { .name = "ldo2", },
  138. };
  139. static struct tps65090_platform_data *tps65090_parse_dt_reg_data(
  140. struct platform_device *pdev,
  141. struct of_regulator_match **tps65090_reg_matches)
  142. {
  143. struct tps65090_platform_data *tps65090_pdata;
  144. struct device_node *np = pdev->dev.parent->of_node;
  145. struct device_node *regulators;
  146. int idx = 0, ret;
  147. struct tps65090_regulator_plat_data *reg_pdata;
  148. tps65090_pdata = devm_kzalloc(&pdev->dev, sizeof(*tps65090_pdata),
  149. GFP_KERNEL);
  150. if (!tps65090_pdata) {
  151. dev_err(&pdev->dev, "Memory alloc for tps65090_pdata failed\n");
  152. return ERR_PTR(-ENOMEM);
  153. }
  154. reg_pdata = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX *
  155. sizeof(*reg_pdata), GFP_KERNEL);
  156. if (!reg_pdata) {
  157. dev_err(&pdev->dev, "Memory alloc for reg_pdata failed\n");
  158. return ERR_PTR(-ENOMEM);
  159. }
  160. regulators = of_find_node_by_name(np, "regulators");
  161. if (!regulators) {
  162. dev_err(&pdev->dev, "regulator node not found\n");
  163. return ERR_PTR(-ENODEV);
  164. }
  165. ret = of_regulator_match(&pdev->dev, regulators, tps65090_matches,
  166. ARRAY_SIZE(tps65090_matches));
  167. if (ret < 0) {
  168. dev_err(&pdev->dev,
  169. "Error parsing regulator init data: %d\n", ret);
  170. return ERR_PTR(ret);
  171. }
  172. *tps65090_reg_matches = tps65090_matches;
  173. for (idx = 0; idx < ARRAY_SIZE(tps65090_matches); idx++) {
  174. struct regulator_init_data *ri_data;
  175. struct tps65090_regulator_plat_data *rpdata;
  176. rpdata = &reg_pdata[idx];
  177. ri_data = tps65090_matches[idx].init_data;
  178. if (!ri_data || !tps65090_matches[idx].of_node)
  179. continue;
  180. rpdata->reg_init_data = ri_data;
  181. rpdata->enable_ext_control = of_property_read_bool(
  182. tps65090_matches[idx].of_node,
  183. "ti,enable-ext-control");
  184. if (rpdata->enable_ext_control)
  185. rpdata->gpio = of_get_named_gpio(np,
  186. "dcdc-ext-control-gpios", 0);
  187. tps65090_pdata->reg_pdata[idx] = rpdata;
  188. }
  189. return tps65090_pdata;
  190. }
  191. #else
  192. static inline struct tps65090_platform_data *tps65090_parse_dt_reg_data(
  193. struct platform_device *pdev,
  194. struct of_regulator_match **tps65090_reg_matches)
  195. {
  196. *tps65090_reg_matches = NULL;
  197. return NULL;
  198. }
  199. #endif
  200. static int tps65090_regulator_probe(struct platform_device *pdev)
  201. {
  202. struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent);
  203. struct tps65090_regulator *ri = NULL;
  204. struct regulator_config config = { };
  205. struct regulator_dev *rdev;
  206. struct tps65090_regulator_plat_data *tps_pdata;
  207. struct tps65090_regulator *pmic;
  208. struct tps65090_platform_data *tps65090_pdata;
  209. struct of_regulator_match *tps65090_reg_matches = NULL;
  210. int num;
  211. int ret;
  212. dev_dbg(&pdev->dev, "Probing regulator\n");
  213. tps65090_pdata = dev_get_platdata(pdev->dev.parent);
  214. if (!tps65090_pdata && tps65090_mfd->dev->of_node)
  215. tps65090_pdata = tps65090_parse_dt_reg_data(pdev,
  216. &tps65090_reg_matches);
  217. if (IS_ERR_OR_NULL(tps65090_pdata)) {
  218. dev_err(&pdev->dev, "Platform data missing\n");
  219. return tps65090_pdata ? PTR_ERR(tps65090_pdata) : -EINVAL;
  220. }
  221. pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic),
  222. GFP_KERNEL);
  223. if (!pmic) {
  224. dev_err(&pdev->dev, "mem alloc for pmic failed\n");
  225. return -ENOMEM;
  226. }
  227. for (num = 0; num < TPS65090_REGULATOR_MAX; num++) {
  228. tps_pdata = tps65090_pdata->reg_pdata[num];
  229. ri = &pmic[num];
  230. ri->dev = &pdev->dev;
  231. ri->desc = &tps65090_regulator_desc[num];
  232. /*
  233. * TPS5090 DCDC support the control from external digital input.
  234. * Configure it as per platform data.
  235. */
  236. if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data) {
  237. if (tps_pdata->enable_ext_control) {
  238. tps65090_configure_regulator_config(
  239. tps_pdata, &config);
  240. ri->desc->ops = &tps65090_ext_control_ops;
  241. } else {
  242. ret = tps65090_regulator_disable_ext_control(
  243. ri, tps_pdata);
  244. if (ret < 0) {
  245. dev_err(&pdev->dev,
  246. "failed disable ext control\n");
  247. goto scrub;
  248. }
  249. }
  250. }
  251. config.dev = pdev->dev.parent;
  252. config.driver_data = ri;
  253. config.regmap = tps65090_mfd->rmap;
  254. if (tps_pdata)
  255. config.init_data = tps_pdata->reg_init_data;
  256. else
  257. config.init_data = NULL;
  258. if (tps65090_reg_matches)
  259. config.of_node = tps65090_reg_matches[num].of_node;
  260. else
  261. config.of_node = NULL;
  262. rdev = regulator_register(ri->desc, &config);
  263. if (IS_ERR(rdev)) {
  264. dev_err(&pdev->dev, "failed to register regulator %s\n",
  265. ri->desc->name);
  266. ret = PTR_ERR(rdev);
  267. goto scrub;
  268. }
  269. ri->rdev = rdev;
  270. /* Enable external control if it is require */
  271. if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data &&
  272. tps_pdata->enable_ext_control) {
  273. ret = tps65090_config_ext_control(ri, true);
  274. if (ret < 0) {
  275. /* Increment num to get unregister rdev */
  276. num++;
  277. goto scrub;
  278. }
  279. }
  280. }
  281. platform_set_drvdata(pdev, pmic);
  282. return 0;
  283. scrub:
  284. while (--num >= 0) {
  285. ri = &pmic[num];
  286. regulator_unregister(ri->rdev);
  287. }
  288. return ret;
  289. }
  290. static int tps65090_regulator_remove(struct platform_device *pdev)
  291. {
  292. struct tps65090_regulator *pmic = platform_get_drvdata(pdev);
  293. struct tps65090_regulator *ri;
  294. int num;
  295. for (num = 0; num < TPS65090_REGULATOR_MAX; ++num) {
  296. ri = &pmic[num];
  297. regulator_unregister(ri->rdev);
  298. }
  299. return 0;
  300. }
  301. static struct platform_driver tps65090_regulator_driver = {
  302. .driver = {
  303. .name = "tps65090-pmic",
  304. .owner = THIS_MODULE,
  305. },
  306. .probe = tps65090_regulator_probe,
  307. .remove = tps65090_regulator_remove,
  308. };
  309. static int __init tps65090_regulator_init(void)
  310. {
  311. return platform_driver_register(&tps65090_regulator_driver);
  312. }
  313. subsys_initcall(tps65090_regulator_init);
  314. static void __exit tps65090_regulator_exit(void)
  315. {
  316. platform_driver_unregister(&tps65090_regulator_driver);
  317. }
  318. module_exit(tps65090_regulator_exit);
  319. MODULE_DESCRIPTION("tps65090 regulator driver");
  320. MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
  321. MODULE_LICENSE("GPL v2");
  322. MODULE_ALIAS("platform:tps65090-pmic");