stub-regulator.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #define pr_fmt(fmt) "%s: " fmt, __func__
  14. #include <linux/module.h>
  15. #include <linux/err.h>
  16. #include <linux/kernel.h>
  17. #include <linux/of.h>
  18. #include <linux/of_device.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/slab.h>
  21. #include <linux/types.h>
  22. #include <linux/regulator/driver.h>
  23. #include <linux/regulator/of_regulator.h>
  24. #include <linux/regulator/stub-regulator.h>
  25. #define STUB_REGULATOR_MAX_NAME 40
  26. struct regulator_stub {
  27. struct regulator_desc rdesc;
  28. struct regulator_dev *rdev;
  29. int voltage;
  30. bool enabled;
  31. int mode;
  32. int hpm_min_load;
  33. int system_uA;
  34. char name[STUB_REGULATOR_MAX_NAME];
  35. };
  36. static int regulator_stub_set_voltage(struct regulator_dev *rdev, int min_uV,
  37. int max_uV, unsigned *selector)
  38. {
  39. struct regulator_stub *vreg_priv = rdev_get_drvdata(rdev);
  40. vreg_priv->voltage = min_uV;
  41. return 0;
  42. }
  43. static int regulator_stub_get_voltage(struct regulator_dev *rdev)
  44. {
  45. struct regulator_stub *vreg_priv = rdev_get_drvdata(rdev);
  46. return vreg_priv->voltage;
  47. }
  48. static int regulator_stub_list_voltage(struct regulator_dev *rdev,
  49. unsigned selector)
  50. {
  51. struct regulation_constraints *constraints = rdev->constraints;
  52. if (selector >= 2)
  53. return -EINVAL;
  54. else if (selector == 0)
  55. return constraints->min_uV;
  56. else
  57. return constraints->max_uV;
  58. }
  59. static unsigned int regulator_stub_get_mode(struct regulator_dev *rdev)
  60. {
  61. struct regulator_stub *vreg_priv = rdev_get_drvdata(rdev);
  62. return vreg_priv->mode;
  63. }
  64. static int regulator_stub_set_mode(struct regulator_dev *rdev,
  65. unsigned int mode)
  66. {
  67. struct regulator_stub *vreg_priv = rdev_get_drvdata(rdev);
  68. if (mode != REGULATOR_MODE_NORMAL && mode != REGULATOR_MODE_IDLE) {
  69. dev_err(&rdev->dev, "%s: invalid mode requested %u\n",
  70. __func__, mode);
  71. return -EINVAL;
  72. }
  73. vreg_priv->mode = mode;
  74. return 0;
  75. }
  76. static unsigned int regulator_stub_get_optimum_mode(struct regulator_dev *rdev,
  77. int input_uV, int output_uV, int load_uA)
  78. {
  79. struct regulator_stub *vreg_priv = rdev_get_drvdata(rdev);
  80. unsigned int mode;
  81. if (load_uA + vreg_priv->system_uA >= vreg_priv->hpm_min_load)
  82. mode = REGULATOR_MODE_NORMAL;
  83. else
  84. mode = REGULATOR_MODE_IDLE;
  85. return mode;
  86. }
  87. static int regulator_stub_enable(struct regulator_dev *rdev)
  88. {
  89. struct regulator_stub *vreg_priv = rdev_get_drvdata(rdev);
  90. vreg_priv->enabled = true;
  91. return 0;
  92. }
  93. static int regulator_stub_disable(struct regulator_dev *rdev)
  94. {
  95. struct regulator_stub *vreg_priv = rdev_get_drvdata(rdev);
  96. vreg_priv->enabled = false;
  97. return 0;
  98. }
  99. static int regulator_stub_is_enabled(struct regulator_dev *rdev)
  100. {
  101. struct regulator_stub *vreg_priv = rdev_get_drvdata(rdev);
  102. return vreg_priv->enabled;
  103. }
  104. /* Real regulator operations. */
  105. static struct regulator_ops regulator_stub_ops = {
  106. .enable = regulator_stub_enable,
  107. .disable = regulator_stub_disable,
  108. .is_enabled = regulator_stub_is_enabled,
  109. .set_voltage = regulator_stub_set_voltage,
  110. .get_voltage = regulator_stub_get_voltage,
  111. .list_voltage = regulator_stub_list_voltage,
  112. .set_mode = regulator_stub_set_mode,
  113. .get_mode = regulator_stub_get_mode,
  114. .get_optimum_mode = regulator_stub_get_optimum_mode,
  115. };
  116. static void regulator_stub_cleanup(struct regulator_stub *vreg_priv)
  117. {
  118. if (vreg_priv && vreg_priv->rdev)
  119. regulator_unregister(vreg_priv->rdev);
  120. kfree(vreg_priv);
  121. }
  122. static int __devinit regulator_stub_probe(struct platform_device *pdev)
  123. {
  124. struct regulator_init_data *init_data = NULL;
  125. struct device *dev = &pdev->dev;
  126. struct stub_regulator_pdata *vreg_pdata;
  127. struct regulator_desc *rdesc;
  128. struct regulator_stub *vreg_priv;
  129. int rc;
  130. vreg_priv = kzalloc(sizeof(*vreg_priv), GFP_KERNEL);
  131. if (!vreg_priv) {
  132. dev_err(dev, "%s: Unable to allocate memory\n",
  133. __func__);
  134. return -ENOMEM;
  135. }
  136. if (dev->of_node) {
  137. /* Use device tree. */
  138. init_data = of_get_regulator_init_data(dev,
  139. dev->of_node);
  140. if (!init_data) {
  141. dev_err(dev, "%s: unable to allocate memory\n",
  142. __func__);
  143. rc = -ENOMEM;
  144. goto err_probe;
  145. }
  146. if (init_data->constraints.name == NULL) {
  147. dev_err(dev, "%s: regulator name not specified\n",
  148. __func__);
  149. rc = -EINVAL;
  150. goto err_probe;
  151. }
  152. if (of_get_property(dev->of_node, "parent-supply", NULL))
  153. init_data->supply_regulator = "parent";
  154. of_property_read_u32(dev->of_node, "qcom,system-load",
  155. &vreg_priv->system_uA);
  156. of_property_read_u32(dev->of_node, "qcom,hpm-min-load",
  157. &vreg_priv->hpm_min_load);
  158. init_data->constraints.input_uV = init_data->constraints.max_uV;
  159. init_data->constraints.valid_ops_mask
  160. |= REGULATOR_CHANGE_STATUS;
  161. init_data->constraints.valid_ops_mask
  162. |= REGULATOR_CHANGE_VOLTAGE;
  163. init_data->constraints.valid_ops_mask
  164. |= REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_DRMS;
  165. init_data->constraints.valid_modes_mask
  166. = REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE;
  167. } else {
  168. /* Use platform data. */
  169. vreg_pdata = dev->platform_data;
  170. if (!vreg_pdata) {
  171. dev_err(dev, "%s: no platform data\n", __func__);
  172. rc = -EINVAL;
  173. goto err_probe;
  174. }
  175. init_data = &vreg_pdata->init_data;
  176. vreg_priv->system_uA = vreg_pdata->system_uA;
  177. vreg_priv->hpm_min_load = vreg_pdata->hpm_min_load;
  178. }
  179. dev_set_drvdata(dev, vreg_priv);
  180. rdesc = &vreg_priv->rdesc;
  181. strlcpy(vreg_priv->name, init_data->constraints.name,
  182. STUB_REGULATOR_MAX_NAME);
  183. rdesc->name = vreg_priv->name;
  184. rdesc->ops = &regulator_stub_ops;
  185. /*
  186. * Ensure that voltage set points are handled correctly for regulators
  187. * which have a specified voltage constraint range, as well as those
  188. * that do not.
  189. */
  190. if (init_data->constraints.min_uV == 0 &&
  191. init_data->constraints.max_uV == 0)
  192. rdesc->n_voltages = 0;
  193. else
  194. rdesc->n_voltages = 2;
  195. rdesc->id = pdev->id;
  196. rdesc->owner = THIS_MODULE;
  197. rdesc->type = REGULATOR_VOLTAGE;
  198. vreg_priv->voltage = init_data->constraints.min_uV;
  199. if (vreg_priv->system_uA >= vreg_priv->hpm_min_load)
  200. vreg_priv->mode = REGULATOR_MODE_NORMAL;
  201. else
  202. vreg_priv->mode = REGULATOR_MODE_IDLE;
  203. vreg_priv->rdev = regulator_register(rdesc, dev, init_data, vreg_priv,
  204. dev->of_node);
  205. if (IS_ERR(vreg_priv->rdev)) {
  206. rc = PTR_ERR(vreg_priv->rdev);
  207. vreg_priv->rdev = NULL;
  208. if (rc != -EPROBE_DEFER)
  209. dev_err(dev, "%s: regulator_register failed\n",
  210. __func__);
  211. goto err_probe;
  212. }
  213. return 0;
  214. err_probe:
  215. regulator_stub_cleanup(vreg_priv);
  216. return rc;
  217. }
  218. static int __devexit regulator_stub_remove(struct platform_device *pdev)
  219. {
  220. struct regulator_stub *vreg_priv = dev_get_drvdata(&pdev->dev);
  221. regulator_stub_cleanup(vreg_priv);
  222. return 0;
  223. }
  224. static struct of_device_id regulator_stub_match_table[] = {
  225. { .compatible = "qcom," STUB_REGULATOR_DRIVER_NAME, },
  226. {}
  227. };
  228. static struct platform_driver regulator_stub_driver = {
  229. .probe = regulator_stub_probe,
  230. .remove = __devexit_p(regulator_stub_remove),
  231. .driver = {
  232. .name = STUB_REGULATOR_DRIVER_NAME,
  233. .owner = THIS_MODULE,
  234. .of_match_table = regulator_stub_match_table,
  235. },
  236. };
  237. int __init regulator_stub_init(void)
  238. {
  239. static int registered;
  240. if (registered)
  241. return 0;
  242. else
  243. registered = 1;
  244. return platform_driver_register(&regulator_stub_driver);
  245. }
  246. postcore_initcall(regulator_stub_init);
  247. EXPORT_SYMBOL(regulator_stub_init);
  248. static void __exit regulator_stub_exit(void)
  249. {
  250. platform_driver_unregister(&regulator_stub_driver);
  251. }
  252. module_exit(regulator_stub_exit);
  253. MODULE_LICENSE("GPL v2");
  254. MODULE_DESCRIPTION("stub regulator driver");
  255. MODULE_VERSION("1.0");
  256. MODULE_ALIAS("platform: " STUB_REGULATOR_DRIVER_NAME);