Advertisement
Guest User

avs-class2-regulator-idea

a guest
Apr 4th, 2013
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.22 KB | None | 0 0
  1. From 5e754106dd3dc278eec33f0389773190a77b0e38 Mon Sep 17 00:00:00 2001
  2. From: Nishanth Menon <nm@ti.com>
  3. Date: Thu, 4 Apr 2013 23:34:57 -0500
  4. Subject: [RFC PATCH] regulator: introduce TI smartreflex class 2
  5. driver(proof-of-concept)
  6.  
  7. Idea being:
  8. cpufreq-cpu0 driver will use avs class 2 regulator->control actual i2c regulator
  9. reference: 3.2 driver for avs class 2
  10. https://github.com/Angstrom-distribution/meta-ti/blob/master/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am33xx-Add-SmartReflex-support.patch
  11.  
  12. If we ignore the details of the class 1.5 implementation, we will notice
  13. a) regulator set_voltage equivalent set_voltage() is required.
  14. b) this set_voltage does some 'magic stuff' depending on the SoC and AVS class
  15. and calls the 'real regulator' which talks to the PMIC over i2c/spi etc..
  16.  
  17. So, start modeling this under regulator framework itself.
  18.  
  19. Signed-off-by: Nishanth Menon <nm@ti.com>
  20. ---
  21. drivers/regulator/Kconfig | 5 +
  22. drivers/regulator/Makefile | 1 +
  23. .../regulator/ti-smartreflex-class2-regulator.c | 222 ++++++++++++++++++++
  24. 3 files changed, 228 insertions(+)
  25. create mode 100644 drivers/regulator/ti-smartreflex-class2-regulator.c
  26.  
  27. diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
  28. index a5d97ea..c5289f0 100644
  29. --- a/drivers/regulator/Kconfig
  30. +++ b/drivers/regulator/Kconfig
  31. @@ -514,5 +514,10 @@ config REGULATOR_AS3711
  32. This driver provides support for the voltage regulators on the
  33. AS3711 PMIC
  34.  
  35. +config REGULATOR_TIAVSCLASS2
  36. + tristate "Texas Instruments SoC regulator for SmartReflex class 2"
  37. + help
  38. + This driver.. blah blah avs class 2 TBD..
  39. +
  40. endif
  41.  
  42. diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
  43. index 6e82503..ba3f24e 100644
  44. --- a/drivers/regulator/Makefile
  45. +++ b/drivers/regulator/Makefile
  46. @@ -70,6 +70,7 @@ obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
  47. obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
  48. obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
  49. obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
  50. +obj-$(CONFIG_REGULATOR_TIAVSCLASS2) += ti-smartreflex-class2-regulator.o
  51.  
  52.  
  53. ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
  54. diff --git a/drivers/regulator/ti-smartreflex-class2-regulator.c b/drivers/regulator/ti-smartreflex-class2-regulator.c
  55. new file mode 100644
  56. index 0000000..36d1295
  57. --- /dev/null
  58. +++ b/drivers/regulator/ti-smartreflex-class2-regulator.c
  59. @@ -0,0 +1,222 @@
  60. +/* Proof of concept regulator driver */
  61. +#include <linux/module.h>
  62. +#include <linux/string.h>
  63. +#include <linux/slab.h>
  64. +#include <linux/init.h>
  65. +#include <linux/err.h>
  66. +#include <linux/platform_device.h>
  67. +#include <linux/of.h>
  68. +#include <linux/of_device.h>
  69. +#include <linux/regulator/driver.h>
  70. +#include <linux/regulator/machine.h>
  71. +#include <linux/regulator/of_regulator.h>
  72. +#include <linux/regulator/consumer.h>
  73. +
  74. +static int tisr_class2_enable(struct regulator_dev *rdev)
  75. +{
  76. + struct regulator *reg = rdev_get_drvdata(rdev);
  77. +
  78. + if (!reg) {
  79. + pr_err("%s: no regulator drvdata dev\n", __func__);
  80. + return -ENODEV;
  81. + }
  82. + /* TODO: more magic things */
  83. + return regulator_enable(reg);
  84. +}
  85. +
  86. +static int tisr_class2_disable(struct regulator_dev *rdev)
  87. +{
  88. + struct regulator *reg = rdev_get_drvdata(rdev);
  89. +
  90. + if (!reg) {
  91. + pr_err("%s: no regulator drvdata dev\n", __func__);
  92. + return -ENODEV;
  93. + }
  94. + /* TODO: more magic things */
  95. + return regulator_disable(reg);
  96. +}
  97. +
  98. +static int tisr_class2_is_enabled(struct regulator_dev *rdev)
  99. +{
  100. + struct regulator *reg = rdev_get_drvdata(rdev);
  101. +
  102. + if (!reg) {
  103. + pr_err("%s: no regulator drvdata dev\n", __func__);
  104. + return -ENODEV;
  105. + }
  106. + /* TODO: more magic things */
  107. + return regulator_is_enabled(reg);
  108. +}
  109. +
  110. +static int tisr_class2_list_voltage(struct regulator_dev *rdev, unsigned sel)
  111. +{
  112. + struct regulator *reg = rdev_get_drvdata(rdev);
  113. +
  114. + if (!reg) {
  115. + pr_err("%s: no regulator drvdata dev\n", __func__);
  116. + return -ENODEV;
  117. + }
  118. + /* TODO: more magic things */
  119. + return regulator_list_voltage(reg, sel);
  120. +}
  121. +
  122. +static int tisr_class2_set_voltage(struct regulator_dev *rdev, int min_uV,
  123. + int max_uV, unsigned *selector)
  124. +{
  125. + struct regulator *reg = rdev_get_drvdata(rdev);
  126. +
  127. + if (!reg) {
  128. + pr_err("%s: no regulator drvdata dev\n", __func__);
  129. + return -ENODEV;
  130. + }
  131. + /* TODO: more magic things */
  132. + return regulator_set_voltage(reg, min_uV, max_uV);
  133. +}
  134. +
  135. +static int tisr_class2_get_voltage(struct regulator_dev *rdev)
  136. +{
  137. + struct regulator *reg = rdev_get_drvdata(rdev);
  138. +
  139. + if (!reg) {
  140. + pr_err("%s: no regulator drvdata dev\n", __func__);
  141. + return -ENODEV;
  142. + }
  143. +
  144. + /* TODO: more magic things */
  145. + return regulator_get_voltage(reg);
  146. +}
  147. +
  148. +static struct regulator_ops tisr_class2_ops = {
  149. + .enable = tisr_class2_enable,
  150. + .disable = tisr_class2_disable,
  151. + .is_enabled = tisr_class2_is_enabled,
  152. +
  153. + .list_voltage = tisr_class2_list_voltage,
  154. +
  155. + .set_voltage = tisr_class2_set_voltage,
  156. + .get_voltage = tisr_class2_get_voltage,
  157. +
  158. +};
  159. +
  160. +static struct regulator_desc tisr_class2_desc = {
  161. + .ops = &tisr_class2_ops,
  162. + .name = "avsclass2",
  163. + .owner = THIS_MODULE,
  164. +
  165. +};
  166. +
  167. +static const struct of_device_id tisr_class2_of_match[] = {
  168. + {.compatible = "ti,sr_class2",.data = &tisr_class2_desc},
  169. + {},
  170. +};
  171. +
  172. +MODULE_DEVICE_TABLE(of, tisr_class2_of_match);
  173. +
  174. +static int tisr_class2_probe(struct platform_device *pdev)
  175. +{
  176. + struct regulator_init_data *initdata = NULL;
  177. + struct regulation_constraints *c;
  178. + struct regulator_dev *rdev;
  179. + const struct of_device_id *match;
  180. + struct regulator_config config = { };
  181. + const void *temp;
  182. + struct regulator_desc *desc;
  183. + struct regulator *reg;
  184. +
  185. + dev_err(&pdev->dev, "%s: I STARTED\n", __func__);
  186. + match = of_match_device(tisr_class2_of_match, &pdev->dev);
  187. + if (match) {
  188. + temp = match->data;
  189. + initdata = of_get_regulator_init_data(&pdev->dev,
  190. + pdev->dev.of_node);
  191. + }
  192. + if (!initdata) {
  193. + dev_err(&pdev->dev, "XXXYippiee.. no proper OF?\n");
  194. + return -ENODEV;
  195. + }
  196. + if (!temp) {
  197. + dev_err(&pdev->dev, "XXXYippiee.. no proper desc?\n");
  198. + return -ENODEV;
  199. + }
  200. +
  201. + /* look for avs-supply */
  202. + reg = devm_regulator_get(&pdev->dev, "avs");
  203. + if (IS_ERR(reg)) {
  204. + dev_err(&pdev->dev, "failed to get sr_class2 regulator %ld\n",
  205. + PTR_ERR(reg));
  206. + reg = NULL;
  207. + /* try later? */
  208. + return -EPROBE_DEFER;
  209. + }
  210. +
  211. + desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
  212. + if (!desc) {
  213. + dev_err(&pdev->dev, "no memory to alloc!\n");
  214. + return -ENOMEM;
  215. + }
  216. + memcpy(desc, temp, sizeof(*desc));
  217. +
  218. + /*
  219. + * Constrain board-specific capabilities according to what
  220. + * this driver and the chip itself can actually do.
  221. + */
  222. + c = &initdata->constraints;
  223. + c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
  224. + c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
  225. + | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS;
  226. + c->always_on = true;
  227. +
  228. + config.dev = &pdev->dev;
  229. + config.init_data = initdata;
  230. + config.driver_data = reg;
  231. + config.of_node = pdev->dev.of_node;
  232. +
  233. + rdev = regulator_register(desc, &config);
  234. + if (IS_ERR(rdev)) {
  235. + dev_err(&pdev->dev, "can't register %s, %ld\n",
  236. + desc->name, PTR_ERR(rdev));
  237. + return PTR_ERR(rdev);
  238. + }
  239. + platform_set_drvdata(pdev, rdev);
  240. +
  241. + dev_err(&pdev->dev, "%s: I AM DONE\n", __func__);
  242. + return 0;
  243. +}
  244. +
  245. +static int tisr_class2_remove(struct platform_device *pdev)
  246. +{
  247. + struct regulator_dev *rdev = platform_get_drvdata(pdev);
  248. +
  249. + regulator_unregister(rdev);
  250. + return 0;
  251. +}
  252. +
  253. +MODULE_ALIAS("platform:tisr_class2");
  254. +
  255. +static struct platform_driver tisr_class2_driver = {
  256. + .probe = tisr_class2_probe,
  257. + .remove = tisr_class2_remove,
  258. + .driver = {
  259. + .name = "tisr_class2",
  260. + .owner = THIS_MODULE,
  261. + .of_match_table = of_match_ptr(tisr_class2_of_match),
  262. + },
  263. +};
  264. +
  265. +static int __init tisr_class2_init(void)
  266. +{
  267. + return platform_driver_register(&tisr_class2_driver);
  268. +}
  269. +
  270. +subsys_initcall(tisr_class2_init);
  271. +
  272. +static void __exit tisr_class2_exit(void)
  273. +{
  274. + platform_driver_unregister(&tisr_class2_driver);
  275. +}
  276. +
  277. +module_exit(tisr_class2_exit)
  278. +
  279. +MODULE_DESCRIPTION("TI SmartReflex AVS class 2 regulator driver");
  280. +MODULE_AUTHOR("Texas Instruments Inc."
  281. +MODULE_LICENSE("GPL v2");
  282. --
  283. 1.7.9.5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement