fixed.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * fixed.c
  3. *
  4. * Copyright 2008 Wolfson Microelectronics PLC.
  5. *
  6. * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  7. *
  8. * Copyright (c) 2009 Nokia Corporation
  9. * Roger Quadros <ext-roger.quadros@nokia.com>
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of the
  14. * License, or (at your option) any later version.
  15. *
  16. * This is useful for systems with mixed controllable and
  17. * non-controllable regulators, as well as for allowing testing on
  18. * systems with no controllable regulators.
  19. */
  20. #include <linux/err.h>
  21. #include <linux/mutex.h>
  22. #include <linux/module.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/regulator/driver.h>
  25. #include <linux/regulator/fixed.h>
  26. #include <linux/gpio.h>
  27. #include <linux/slab.h>
  28. #include <linux/of.h>
  29. #include <linux/of_gpio.h>
  30. #include <linux/regulator/of_regulator.h>
  31. #include <linux/regulator/machine.h>
  32. struct fixed_voltage_data {
  33. struct regulator_desc desc;
  34. struct regulator_dev *dev;
  35. };
  36. /**
  37. * of_get_fixed_voltage_config - extract fixed_voltage_config structure info
  38. * @dev: device requesting for fixed_voltage_config
  39. *
  40. * Populates fixed_voltage_config structure by extracting data from device
  41. * tree node, returns a pointer to the populated structure of NULL if memory
  42. * alloc fails.
  43. */
  44. static struct fixed_voltage_config *
  45. of_get_fixed_voltage_config(struct device *dev)
  46. {
  47. struct fixed_voltage_config *config;
  48. struct device_node *np = dev->of_node;
  49. const __be32 *delay;
  50. struct regulator_init_data *init_data;
  51. config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config),
  52. GFP_KERNEL);
  53. if (!config)
  54. return ERR_PTR(-ENOMEM);
  55. config->init_data = of_get_regulator_init_data(dev, dev->of_node);
  56. if (!config->init_data)
  57. return ERR_PTR(-EINVAL);
  58. init_data = config->init_data;
  59. init_data->constraints.apply_uV = 0;
  60. config->supply_name = init_data->constraints.name;
  61. if (init_data->constraints.min_uV == init_data->constraints.max_uV) {
  62. config->microvolts = init_data->constraints.min_uV;
  63. } else {
  64. dev_err(dev,
  65. "Fixed regulator specified with variable voltages\n");
  66. return ERR_PTR(-EINVAL);
  67. }
  68. if (init_data->constraints.boot_on)
  69. config->enabled_at_boot = true;
  70. config->gpio = of_get_named_gpio(np, "gpio", 0);
  71. /*
  72. * of_get_named_gpio() currently returns ENODEV rather than
  73. * EPROBE_DEFER. This code attempts to be compatible with both
  74. * for now; the ENODEV check can be removed once the API is fixed.
  75. * of_get_named_gpio() doesn't differentiate between a missing
  76. * property (which would be fine here, since the GPIO is optional)
  77. * and some other error. Patches have been posted for both issues.
  78. * Once they are check in, we should replace this with:
  79. * if (config->gpio < 0 && config->gpio != -ENOENT)
  80. */
  81. if ((config->gpio == -ENODEV) || (config->gpio == -EPROBE_DEFER))
  82. return ERR_PTR(-EPROBE_DEFER);
  83. delay = of_get_property(np, "startup-delay-us", NULL);
  84. if (delay)
  85. config->startup_delay = be32_to_cpu(*delay);
  86. if (of_find_property(np, "enable-active-high", NULL))
  87. config->enable_high = true;
  88. if (of_find_property(np, "gpio-open-drain", NULL))
  89. config->gpio_is_open_drain = true;
  90. if (of_find_property(np, "vin-supply", NULL))
  91. config->input_supply = "vin";
  92. return config;
  93. }
  94. static struct regulator_ops fixed_voltage_ops = {
  95. };
  96. static int reg_fixed_voltage_probe(struct platform_device *pdev)
  97. {
  98. struct fixed_voltage_config *config;
  99. struct fixed_voltage_data *drvdata;
  100. struct regulator_config cfg = { };
  101. int ret;
  102. if (pdev->dev.of_node) {
  103. config = of_get_fixed_voltage_config(&pdev->dev);
  104. if (IS_ERR(config))
  105. return PTR_ERR(config);
  106. } else {
  107. config = dev_get_platdata(&pdev->dev);
  108. }
  109. if (!config)
  110. return -ENOMEM;
  111. drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
  112. GFP_KERNEL);
  113. if (drvdata == NULL) {
  114. dev_err(&pdev->dev, "Failed to allocate device data\n");
  115. ret = -ENOMEM;
  116. goto err;
  117. }
  118. drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL);
  119. if (drvdata->desc.name == NULL) {
  120. dev_err(&pdev->dev, "Failed to allocate supply name\n");
  121. ret = -ENOMEM;
  122. goto err;
  123. }
  124. drvdata->desc.type = REGULATOR_VOLTAGE;
  125. drvdata->desc.owner = THIS_MODULE;
  126. drvdata->desc.ops = &fixed_voltage_ops;
  127. drvdata->desc.enable_time = config->startup_delay;
  128. if (config->input_supply) {
  129. drvdata->desc.supply_name = kstrdup(config->input_supply,
  130. GFP_KERNEL);
  131. if (!drvdata->desc.supply_name) {
  132. dev_err(&pdev->dev,
  133. "Failed to allocate input supply\n");
  134. ret = -ENOMEM;
  135. goto err_name;
  136. }
  137. }
  138. if (config->microvolts)
  139. drvdata->desc.n_voltages = 1;
  140. drvdata->desc.fixed_uV = config->microvolts;
  141. if (config->gpio >= 0)
  142. cfg.ena_gpio = config->gpio;
  143. cfg.ena_gpio_invert = !config->enable_high;
  144. if (config->enabled_at_boot) {
  145. if (config->enable_high)
  146. cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
  147. else
  148. cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW;
  149. } else {
  150. if (config->enable_high)
  151. cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW;
  152. else
  153. cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
  154. }
  155. if (config->gpio_is_open_drain)
  156. cfg.ena_gpio_flags |= GPIOF_OPEN_DRAIN;
  157. cfg.dev = &pdev->dev;
  158. cfg.init_data = config->init_data;
  159. cfg.driver_data = drvdata;
  160. cfg.of_node = pdev->dev.of_node;
  161. drvdata->dev = regulator_register(&drvdata->desc, &cfg);
  162. if (IS_ERR(drvdata->dev)) {
  163. ret = PTR_ERR(drvdata->dev);
  164. dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
  165. goto err_input;
  166. }
  167. platform_set_drvdata(pdev, drvdata);
  168. dev_dbg(&pdev->dev, "%s supplying %duV\n", drvdata->desc.name,
  169. drvdata->desc.fixed_uV);
  170. return 0;
  171. err_input:
  172. kfree(drvdata->desc.supply_name);
  173. err_name:
  174. kfree(drvdata->desc.name);
  175. err:
  176. return ret;
  177. }
  178. static int reg_fixed_voltage_remove(struct platform_device *pdev)
  179. {
  180. struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev);
  181. regulator_unregister(drvdata->dev);
  182. kfree(drvdata->desc.supply_name);
  183. kfree(drvdata->desc.name);
  184. return 0;
  185. }
  186. #if defined(CONFIG_OF)
  187. static const struct of_device_id fixed_of_match[] = {
  188. { .compatible = "regulator-fixed", },
  189. {},
  190. };
  191. MODULE_DEVICE_TABLE(of, fixed_of_match);
  192. #endif
  193. static struct platform_driver regulator_fixed_voltage_driver = {
  194. .probe = reg_fixed_voltage_probe,
  195. .remove = reg_fixed_voltage_remove,
  196. .driver = {
  197. .name = "reg-fixed-voltage",
  198. .owner = THIS_MODULE,
  199. .of_match_table = of_match_ptr(fixed_of_match),
  200. },
  201. };
  202. static int __init regulator_fixed_voltage_init(void)
  203. {
  204. return platform_driver_register(&regulator_fixed_voltage_driver);
  205. }
  206. subsys_initcall(regulator_fixed_voltage_init);
  207. static void __exit regulator_fixed_voltage_exit(void)
  208. {
  209. platform_driver_unregister(&regulator_fixed_voltage_driver);
  210. }
  211. module_exit(regulator_fixed_voltage_exit);
  212. MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
  213. MODULE_DESCRIPTION("Fixed voltage regulator");
  214. MODULE_LICENSE("GPL");
  215. MODULE_ALIAS("platform:reg-fixed-voltage");