Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: Add driver for gpio-controlled regulators

This patch adds support for regulators that can be controlled via gpios.

Examples for such regulators are the TI-tps65024x voltage regulators
with 4 fixed and 1 runtime-switchable voltage regulators
or the TI-bq240XX charger regulators.

The number of controlling gpios is not limited, the mapping between
voltage/current and target gpio state is done via the states map
and the driver can be used for either voltage or current regulators.

A mapping for a regulator with two GPIOs could look like:

gpios = {
{ .gpio = GPIO1, .flags = GPIOF_OUT_INIT_HIGH, .label = "gpio name 1" },
{ .gpio = GPIO2, .flags = GPIOF_OUT_INIT_LOW, .label = "gpio name 2" },
}

The flags element of the gpios array determines the initial state of
the gpio, set during probe. The initial state of the regulator is also
calculated from these values

states = {
{ .value = volt_or_cur1, .gpios = (0 << 1) | (0 << 0) },
{ .value = volt_or_cur2, .gpios = (0 << 1) | (1 << 0) },
{ .value = volt_or_cur3, .gpios = (1 << 1) | (0 << 0) },
{ .value = volt_or_cur4, .gpios = (1 << 1) | (1 << 0) },
}

The target-state for the n-th gpio is determined by the n-th bit
in the bitfield of the target-value.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Heiko Stübner and committed by
Mark Brown
3f0292ae e3efe666

+454
+9
drivers/regulator/Kconfig
··· 64 64 65 65 If unsure, say no. 66 66 67 + config REGULATOR_GPIO 68 + tristate "GPIO regulator support" 69 + help 70 + This driver provides support for regulators that can be 71 + controlled via gpios. 72 + It is capable of supporting current and voltage regulators 73 + and the platform has to provide a mapping of GPIO-states 74 + to target volts/amps. 75 + 67 76 config REGULATOR_BQ24022 68 77 tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" 69 78 help
+1
drivers/regulator/Makefile
··· 8 8 obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o 9 9 obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o 10 10 11 + obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o 11 12 obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o 12 13 obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o 13 14 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
+357
drivers/regulator/gpio-regulator.c
··· 1 + /* 2 + * gpio-regulator.c 3 + * 4 + * Copyright 2011 Heiko Stuebner <heiko@sntech.de> 5 + * 6 + * based on fixed.c 7 + * 8 + * Copyright 2008 Wolfson Microelectronics PLC. 9 + * 10 + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 11 + * 12 + * Copyright (c) 2009 Nokia Corporation 13 + * Roger Quadros <ext-roger.quadros@nokia.com> 14 + * 15 + * This program is free software; you can redistribute it and/or 16 + * modify it under the terms of the GNU General Public License as 17 + * published by the Free Software Foundation; either version 2 of the 18 + * License, or (at your option) any later version. 19 + * 20 + * This is useful for systems with mixed controllable and 21 + * non-controllable regulators, as well as for allowing testing on 22 + * systems with no controllable regulators. 23 + */ 24 + 25 + #include <linux/err.h> 26 + #include <linux/mutex.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/regulator/driver.h> 29 + #include <linux/regulator/machine.h> 30 + #include <linux/regulator/gpio-regulator.h> 31 + #include <linux/gpio.h> 32 + #include <linux/delay.h> 33 + #include <linux/slab.h> 34 + 35 + struct gpio_regulator_data { 36 + struct regulator_desc desc; 37 + struct regulator_dev *dev; 38 + 39 + int enable_gpio; 40 + bool enable_high; 41 + bool is_enabled; 42 + unsigned startup_delay; 43 + 44 + struct gpio *gpios; 45 + int nr_gpios; 46 + 47 + struct gpio_regulator_state *states; 48 + int nr_states; 49 + 50 + int state; 51 + }; 52 + 53 + static int gpio_regulator_is_enabled(struct regulator_dev *dev) 54 + { 55 + struct gpio_regulator_data *data = rdev_get_drvdata(dev); 56 + 57 + return data->is_enabled; 58 + } 59 + 60 + static int gpio_regulator_enable(struct regulator_dev *dev) 61 + { 62 + struct gpio_regulator_data *data = rdev_get_drvdata(dev); 63 + 64 + if (gpio_is_valid(data->enable_gpio)) { 65 + gpio_set_value_cansleep(data->enable_gpio, data->enable_high); 66 + data->is_enabled = true; 67 + } 68 + 69 + return 0; 70 + } 71 + 72 + static int gpio_regulator_disable(struct regulator_dev *dev) 73 + { 74 + struct gpio_regulator_data *data = rdev_get_drvdata(dev); 75 + 76 + if (gpio_is_valid(data->enable_gpio)) { 77 + gpio_set_value_cansleep(data->enable_gpio, !data->enable_high); 78 + data->is_enabled = false; 79 + } 80 + 81 + return 0; 82 + } 83 + 84 + static int gpio_regulator_enable_time(struct regulator_dev *dev) 85 + { 86 + struct gpio_regulator_data *data = rdev_get_drvdata(dev); 87 + 88 + return data->startup_delay; 89 + } 90 + 91 + static int gpio_regulator_get_value(struct regulator_dev *dev) 92 + { 93 + struct gpio_regulator_data *data = rdev_get_drvdata(dev); 94 + int ptr; 95 + 96 + for (ptr = 0; ptr < data->nr_states; ptr++) 97 + if (data->states[ptr].gpios == data->state) 98 + return data->states[ptr].value; 99 + 100 + return -EINVAL; 101 + } 102 + 103 + static int gpio_regulator_set_value(struct regulator_dev *dev, 104 + int min, int max) 105 + { 106 + struct gpio_regulator_data *data = rdev_get_drvdata(dev); 107 + int ptr, target, state; 108 + 109 + target = -1; 110 + for (ptr = 0; ptr < data->nr_states; ptr++) 111 + if (data->states[ptr].value >= min && 112 + data->states[ptr].value <= max) 113 + target = data->states[ptr].gpios; 114 + 115 + if (target < 0) 116 + return -EINVAL; 117 + 118 + for (ptr = 0; ptr < data->nr_gpios; ptr++) { 119 + state = (target & (1 << ptr)) >> ptr; 120 + gpio_set_value(data->gpios[ptr].gpio, state); 121 + } 122 + data->state = target; 123 + 124 + return 0; 125 + } 126 + 127 + static int gpio_regulator_set_voltage(struct regulator_dev *dev, 128 + int min_uV, int max_uV, 129 + unsigned *selector) 130 + { 131 + return gpio_regulator_set_value(dev, min_uV, max_uV); 132 + } 133 + 134 + static int gpio_regulator_list_voltage(struct regulator_dev *dev, 135 + unsigned selector) 136 + { 137 + struct gpio_regulator_data *data = rdev_get_drvdata(dev); 138 + 139 + if (selector >= data->nr_states) 140 + return -EINVAL; 141 + 142 + return data->states[selector].value; 143 + } 144 + 145 + static int gpio_regulator_set_current_limit(struct regulator_dev *dev, 146 + int min_uA, int max_uA) 147 + { 148 + return gpio_regulator_set_value(dev, min_uA, max_uA); 149 + } 150 + 151 + static struct regulator_ops gpio_regulator_voltage_ops = { 152 + .is_enabled = gpio_regulator_is_enabled, 153 + .enable = gpio_regulator_enable, 154 + .disable = gpio_regulator_disable, 155 + .enable_time = gpio_regulator_enable_time, 156 + .get_voltage = gpio_regulator_get_value, 157 + .set_voltage = gpio_regulator_set_voltage, 158 + .list_voltage = gpio_regulator_list_voltage, 159 + }; 160 + 161 + static struct regulator_ops gpio_regulator_current_ops = { 162 + .is_enabled = gpio_regulator_is_enabled, 163 + .enable = gpio_regulator_enable, 164 + .disable = gpio_regulator_disable, 165 + .enable_time = gpio_regulator_enable_time, 166 + .get_current_limit = gpio_regulator_get_value, 167 + .set_current_limit = gpio_regulator_set_current_limit, 168 + }; 169 + 170 + static int __devinit gpio_regulator_probe(struct platform_device *pdev) 171 + { 172 + struct gpio_regulator_config *config = pdev->dev.platform_data; 173 + struct gpio_regulator_data *drvdata; 174 + int ptr, ret, state; 175 + 176 + drvdata = kzalloc(sizeof(struct gpio_regulator_data), GFP_KERNEL); 177 + if (drvdata == NULL) { 178 + dev_err(&pdev->dev, "Failed to allocate device data\n"); 179 + return -ENOMEM; 180 + } 181 + 182 + drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); 183 + if (drvdata->desc.name == NULL) { 184 + dev_err(&pdev->dev, "Failed to allocate supply name\n"); 185 + ret = -ENOMEM; 186 + goto err; 187 + } 188 + 189 + drvdata->gpios = kmemdup(config->gpios, 190 + config->nr_gpios * sizeof(struct gpio), 191 + GFP_KERNEL); 192 + if (drvdata->gpios == NULL) { 193 + dev_err(&pdev->dev, "Failed to allocate gpio data\n"); 194 + ret = -ENOMEM; 195 + goto err_name; 196 + } 197 + 198 + drvdata->states = kmemdup(config->states, 199 + config->nr_states * 200 + sizeof(struct gpio_regulator_state), 201 + GFP_KERNEL); 202 + if (drvdata->states == NULL) { 203 + dev_err(&pdev->dev, "Failed to allocate state data\n"); 204 + ret = -ENOMEM; 205 + goto err_memgpio; 206 + } 207 + drvdata->nr_states = config->nr_states; 208 + 209 + drvdata->desc.owner = THIS_MODULE; 210 + 211 + /* handle regulator type*/ 212 + switch (config->type) { 213 + case REGULATOR_VOLTAGE: 214 + drvdata->desc.type = REGULATOR_VOLTAGE; 215 + drvdata->desc.ops = &gpio_regulator_voltage_ops; 216 + drvdata->desc.n_voltages = config->nr_states; 217 + break; 218 + case REGULATOR_CURRENT: 219 + drvdata->desc.type = REGULATOR_CURRENT; 220 + drvdata->desc.ops = &gpio_regulator_current_ops; 221 + break; 222 + default: 223 + dev_err(&pdev->dev, "No regulator type set\n"); 224 + ret = -EINVAL; 225 + goto err_memgpio; 226 + break; 227 + } 228 + 229 + drvdata->enable_gpio = config->enable_gpio; 230 + drvdata->startup_delay = config->startup_delay; 231 + 232 + if (gpio_is_valid(config->enable_gpio)) { 233 + drvdata->enable_high = config->enable_high; 234 + 235 + ret = gpio_request(config->enable_gpio, config->supply_name); 236 + if (ret) { 237 + dev_err(&pdev->dev, 238 + "Could not obtain regulator enable GPIO %d: %d\n", 239 + config->enable_gpio, ret); 240 + goto err_memstate; 241 + } 242 + 243 + /* set output direction without changing state 244 + * to prevent glitch 245 + */ 246 + if (config->enabled_at_boot) { 247 + drvdata->is_enabled = true; 248 + ret = gpio_direction_output(config->enable_gpio, 249 + config->enable_high); 250 + } else { 251 + drvdata->is_enabled = false; 252 + ret = gpio_direction_output(config->enable_gpio, 253 + !config->enable_high); 254 + } 255 + 256 + if (ret) { 257 + dev_err(&pdev->dev, 258 + "Could not configure regulator enable GPIO %d direction: %d\n", 259 + config->enable_gpio, ret); 260 + goto err_enablegpio; 261 + } 262 + } else { 263 + /* Regulator without GPIO control is considered 264 + * always enabled 265 + */ 266 + drvdata->is_enabled = true; 267 + } 268 + 269 + drvdata->nr_gpios = config->nr_gpios; 270 + ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios); 271 + if (ret) { 272 + dev_err(&pdev->dev, 273 + "Could not obtain regulator setting GPIOs: %d\n", ret); 274 + goto err_enablegpio; 275 + } 276 + 277 + /* build initial state from gpio init data. */ 278 + state = 0; 279 + for (ptr = 0; ptr < drvdata->nr_gpios; ptr++) { 280 + if (config->gpios[ptr].flags & GPIOF_OUT_INIT_HIGH) 281 + state |= (1 << ptr); 282 + } 283 + drvdata->state = state; 284 + 285 + drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, 286 + config->init_data, drvdata); 287 + if (IS_ERR(drvdata->dev)) { 288 + ret = PTR_ERR(drvdata->dev); 289 + dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); 290 + goto err_stategpio; 291 + } 292 + 293 + platform_set_drvdata(pdev, drvdata); 294 + 295 + return 0; 296 + 297 + err_stategpio: 298 + gpio_free_array(drvdata->gpios, drvdata->nr_gpios); 299 + err_enablegpio: 300 + if (gpio_is_valid(config->enable_gpio)) 301 + gpio_free(config->enable_gpio); 302 + err_memstate: 303 + kfree(drvdata->states); 304 + err_memgpio: 305 + kfree(drvdata->gpios); 306 + err_name: 307 + kfree(drvdata->desc.name); 308 + err: 309 + kfree(drvdata); 310 + return ret; 311 + } 312 + 313 + static int __devexit gpio_regulator_remove(struct platform_device *pdev) 314 + { 315 + struct gpio_regulator_data *drvdata = platform_get_drvdata(pdev); 316 + 317 + regulator_unregister(drvdata->dev); 318 + 319 + gpio_free_array(drvdata->gpios, drvdata->nr_gpios); 320 + 321 + kfree(drvdata->states); 322 + kfree(drvdata->gpios); 323 + 324 + if (gpio_is_valid(drvdata->enable_gpio)) 325 + gpio_free(drvdata->enable_gpio); 326 + 327 + kfree(drvdata->desc.name); 328 + kfree(drvdata); 329 + 330 + return 0; 331 + } 332 + 333 + static struct platform_driver gpio_regulator_driver = { 334 + .probe = gpio_regulator_probe, 335 + .remove = __devexit_p(gpio_regulator_remove), 336 + .driver = { 337 + .name = "gpio-regulator", 338 + .owner = THIS_MODULE, 339 + }, 340 + }; 341 + 342 + static int __init gpio_regulator_init(void) 343 + { 344 + return platform_driver_register(&gpio_regulator_driver); 345 + } 346 + subsys_initcall(gpio_regulator_init); 347 + 348 + static void __exit gpio_regulator_exit(void) 349 + { 350 + platform_driver_unregister(&gpio_regulator_driver); 351 + } 352 + module_exit(gpio_regulator_exit); 353 + 354 + MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 355 + MODULE_DESCRIPTION("gpio voltage regulator"); 356 + MODULE_LICENSE("GPL"); 357 + MODULE_ALIAS("platform:gpio-regulator");
+87
include/linux/regulator/gpio-regulator.h
··· 1 + /* 2 + * gpio-regulator.h 3 + * 4 + * Copyright 2011 Heiko Stuebner <heiko@sntech.de> 5 + * 6 + * based on fixed.h 7 + * 8 + * Copyright 2008 Wolfson Microelectronics PLC. 9 + * 10 + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 11 + * 12 + * Copyright (c) 2009 Nokia Corporation 13 + * Roger Quadros <ext-roger.quadros@nokia.com> 14 + * 15 + * This program is free software; you can redistribute it and/or 16 + * modify it under the terms of the GNU General Public License as 17 + * published by the Free Software Foundation; either version 2 of the 18 + * License, or (at your option) any later version. 19 + */ 20 + 21 + #ifndef __REGULATOR_GPIO_H 22 + #define __REGULATOR_GPIO_H 23 + 24 + struct regulator_init_data; 25 + 26 + enum regulator_type; 27 + 28 + /** 29 + * struct gpio_regulator_state - state description 30 + * @value: microvolts or microamps 31 + * @gpios: bitfield of gpio target-states for the value 32 + * 33 + * This structure describes a supported setting of the regulator 34 + * and the necessary gpio-state to achieve it. 35 + * 36 + * The n-th bit in the bitfield describes the state of the n-th GPIO 37 + * from the gpios-array defined in gpio_regulator_config below. 38 + */ 39 + struct gpio_regulator_state { 40 + int value; 41 + int gpios; 42 + }; 43 + 44 + /** 45 + * struct gpio_regulator_config - config structure 46 + * @supply_name: Name of the regulator supply 47 + * @enable_gpio: GPIO to use for enable control 48 + * set to -EINVAL if not used 49 + * @enable_high: Polarity of enable GPIO 50 + * 1 = Active high, 0 = Active low 51 + * @enabled_at_boot: Whether regulator has been enabled at 52 + * boot or not. 1 = Yes, 0 = No 53 + * This is used to keep the regulator at 54 + * the default state 55 + * @startup_delay: Start-up time in microseconds 56 + * @gpios: Array containing the gpios needed to control 57 + * the setting of the regulator 58 + * @nr_gpios: Number of gpios 59 + * @states: Array of gpio_regulator_state entries describing 60 + * the gpio state for specific voltages 61 + * @nr_states: Number of states available 62 + * @regulator_type: either REGULATOR_CURRENT or REGULATOR_VOLTAGE 63 + * @init_data: regulator_init_data 64 + * 65 + * This structure contains gpio-voltage regulator configuration 66 + * information that must be passed by platform code to the 67 + * gpio-voltage regulator driver. 68 + */ 69 + struct gpio_regulator_config { 70 + const char *supply_name; 71 + 72 + int enable_gpio; 73 + unsigned enable_high:1; 74 + unsigned enabled_at_boot:1; 75 + unsigned startup_delay; 76 + 77 + struct gpio *gpios; 78 + int nr_gpios; 79 + 80 + struct gpio_regulator_state *states; 81 + int nr_states; 82 + 83 + enum regulator_type type; 84 + struct regulator_init_data *init_data; 85 + }; 86 + 87 + #endif