Add gpio based voltage switching regulator
RFC 1/1 Add gpio based voltage switching regulator
This patch adds support for regulators that can switch between two voltage levels by setting a gpio.
An example such a regulator is the TI-tps65024x regulator family. They contain 4 fixed and 1 runtime-switchable voltage regulators. The switch can be used by a cpufreq driver to set the core voltage on some SoCs, for example the S3C2416/2450.
Handling of set_voltage calls with a range that fits neither the low nor the high voltage is determined by the inbetween_high option. When set to 1 the high voltage is used, on 0 the low voltage is used and on -EINVAL an error is returned, disallowing the usage of the voltage range.
---
I'm not hung up on the "inbetween handling", in fact at the moment it seems to not belong there. But I'm not sure on how to handle frequency tables like
[0] = { 1000000, 1150000 },
[1] = { 1150000, 1250000 },
[2] = { 1250000, 1350000 },I.e. the middle value should use the voltage in 2 for switch regulators, but the defined value for more intelligent ones.
drivers/regulator/Kconfig | 8 + drivers/regulator/Makefile | 1 + drivers/regulator/switch.c | 320 ++++++++++++++++++++++++++++++++++++++ include/linux/regulator/switch.h | 65 ++++++++ 4 files changed, 394 insertions(+), 0 deletions(-)
drivers/regulator/Kconfig +8 -0
@@ -45,6 +45,14 @@ config REGULATOR_FIXED_VOLTAGE useful for systems which use a combination of software managed regulators and simple non-configurable regulators. +config REGULATOR_SWITCHED_VOLTAGE + tristate "Switched voltage regulator support" + help + This driver provides support for regulators that can switch + between two voltages by setting a gpio, + useful for systems which use a combination of software + managed regulators and simple non-configurable regulators. + config REGULATOR_VIRTUAL_CONSUMER tristate "Virtual regulator consumer support" help
drivers/regulator/Makefile +1 -0
@@ -5,6 +5,7 @@ obj-$(CONFIG_REGULATOR) += core.o dummy.o obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o +obj-$(CONFIG_REGULATOR_SWITCHED_VOLTAGE) += switch.o obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
drivers/regulator/switch.c new file +320 -0
320 lines not on this page · raw message
include/linux/regulator/switch.h new file +65 -0
65 lines not on this page · raw message
Signature · 1 line
tg: (c6a389f..) topic/drivers/reg-switch (depends on: master)
Quoted 2 lines · Heiko Stübner
This patch adds support for regulators that can switch between two voltage levels by setting a gpio.
This really should be scalable beyond two voltages, or at least prepared for that possibility.
Quoted 5 lines
Handling of
set_voltagecalls with a range that fits neither the low nor the high voltage is determined by theinbetween_highoption. When set to 1 the high voltage is used, on 0 the low voltage is used and on-EINVALan error is returned, disallowing the usage of the voltage range.
No, don't do this. If you can't set the requested voltage then fail. This is not in the least bit driver specific.
Quoted 8 lines
I'm not hung up on the "inbetween handling", in fact at the moment it seems to not belong there. But I'm not sure on how to handle frequency tables like
[0] = { 1000000, 1150000 }, [1] = { 1150000, 1250000 }, [2] = { 1250000, 1350000 },I.e. the middle value should use the voltage in 2 for switch regulators, but the defined value for more intelligent ones.
I'm afraid I can't parse this, sorry.
drivers/regulator/switch.c line 2
Quoted 3 lines
drivers/regulator/switch.c new file +2
-0@@ -0,0 +1,320 @@ +/* +* switched.c
This needs a better name.
Otherwise this looks good, the main thing is the ability to support more voltages.
Hi Mark,
thanks for your comments.
Am Montag, 26. September 2011, 14:51:55 schrieb Mark Brown:
Quoted 6 lines · Heiko Stübner
Quoted 2 lines
This patch adds support for regulators that can switch between two voltage levels by setting a gpio.
This really should be scalable beyond two voltages, or at least prepared for that possibility.
I think I've come up with a solution for this but would like to make sure I'm on the right track. So my general idea is to define the platform_data like
static struct switched_voltage_config es600_dcdc3 = { [...]
.switch_gpios = {
GPIO1, /* bit 0 in matrix */
GPIO2, /* bit 1 in matrix */
},
.nr_switch_gpios = 2,
.switch_matrix = {
{ .microvolts = 1000000, .gpio_state = (0 << 1) | (0 << 0) },
{ .microvolts = 1100000, .gpio_state = (0 << 1) | (1 << 0) },
{ .microvolts = 1200000, .gpio_state = (1 << 1) | (0 << 0) },
{ .microvolts = 1300000, .gpio_state = (1 << 1) | (1 << 0) },
},
.nr_switch_matrix = 4,[...]
};
i.e. each voltage keeps the target gpio state in a bit-field which makes the mapping current_state -> voltage in get_voltage very easy.
set_voltage would then look like
gpio_state = get_gpio_state_for_voltage(microvolts);
for(ptr = 0; ptr < nr_switch_gpios; ptr++) {
state = ( gpio_state & (1 << ptr) ) >> ptr;
gpio_set_value(switch_gpios[ptr], state);
}i.e. simply extracting the target setting from the bitfield for each gpio.
If using integers for the state, this would scale up to 16 gpios and voltage-permutations thereof.
Reasonable?
Quoted 8 lines
Quoted 5 lines
Handling of
set_voltagecalls with a range that fits neither the low nor the high voltage is determined by theinbetween_highoption. When set to 1 the high voltage is used, on 0 the low voltage is used and on-EINVALan error is returned, disallowing the usage of the voltage range.No, don't do this. If you can't set the requested voltage then fail. This is not in the least bit driver specific.
ok
Quoted 5 lines
drivers/regulator/switch.c line 2
Quoted 3 lines
drivers/regulator/switch.c new file +2
-0@@ -0,0 +1,320 @@ +/* +* switched.c This needs a better name.
"gpio-regulator"?
I'm quite open to suggestions :-)
Quoted 2 lines
Otherwise this looks good, the main thing is the ability to support more voltages.
Heiko
Quoted 5 lines · Heiko Stübner
.switch_gpios = {
GPIO1, /* bit 0 in matrix */
GPIO2, /* bit 1 in matrix */
},
.nr_switch_gpios = 2,This seems like a good plan.
Quoted 4 lines
Quoted 1 line
This needs a better name.
"gpio-regulator"?
I'm quite open to suggestions :-)
That would be better, yes.
RFC v2 1/1 Add gpio-regulator driver
As suggested by Mark Brown, I created a more generalised gpio-regulator driver.
It is definitly not finished - it just implements my idea and compiles - real world testing and fixing follows this weekend. If possible I'd just like to make sure I'm on the right track this time :-) .
As the mechanisms of setting gpio states don't change with the regulator type it is also possible to use it as a current regulator.
Therefore it could replace i.e. the bq24022/bq2407x driver later on.
Platform data for the 3 gpio controlled regulators I know of could look like:
struct gpio_regulator_config bq24022 = {
.supply_name = "bq24022",
.gpios = {
GPIO_ISET2,
},
.nr_gpios = 1,
.gpio_states = {
{ .value = 100000, gpios = (0 << 0) },
{ .value = 500000, gpios = (1 << 0) },
},
.nr_gpio_states = 2,
.state_at_boot = (0 << 0),
.type = REGULATOR_CURRENT,
};struct gpio_regulator_config bq24075 = {
.supply_name = "bq24075",
.gpios = {
GPIO_EN1,
GPIO_EN2,
},
.nr_gpios = 2,
.gpio_states = {
{ .value = 100000, gpios = (0 << 1) | (0 << 0) },
{ .value = 500000, gpios = (0 << 1) | (1 << 0) },
{ .value = 975000, gpios = (1 << 1) | (0 << 0) },
},
.nr_gpio_states = 3,
.state_at_boot = (0 << 1)|(0 << 0),
.type = REGULATOR_CURRENT,
};struct gpio_regulator_config tps650240 = {
.supply_name = "tps650240-dcdc3",
.gpios = {
GPIO_DEFDCDC3,
},
.nr_gpios = 1,
.gpio_states = {
{ .value = 1000000, gpios = (0 << 0) },
{ .value = 1300000, gpios = (1 << 0) },
},
.nr_gpio_states = 2,
.state_at_boot = (1 << 0),
.type = REGULATOR_VOLTAGE,
};Comments?
--- drivers/regulator/Kconfig | 6 + drivers/regulator/Makefile | 1 + drivers/regulator/gpio-regulator.c | 361 ++++++++++++++++++++++++++++++ include/linux/regulator/gpio-regulator.h | 84 +++++++ 4 files changed, 452 insertions(+), 0 deletions(-) create mode 100644 drivers/regulator/gpio-regulator.c create mode 100644 include/linux/regulator/gpio-regulator.h
drivers/regulator/Kconfig +6 -0
@@ -72,6 +72,12 @@ config REGULATOR_USERSPACE_CONSUMER If unsure, say no. +config REGULATOR_GPIO + tristate "gpio regulator support" + help + This driver provides support for regulators that can be + controlled by setting gpios. + config REGULATOR_BQ24022 tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" help
drivers/regulator/Makefile +1 -0
@@ -9,6 +9,7 @@ obj-$(CONFIG_REGULATOR_SWITCHED_VOLTAGE) += switch.o obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o +obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
drivers/regulator/gpio-regulator.c new file +363 -0
363 lines not on this page · raw message
include/linux/regulator/gpio-regulator.h new file +84 -0
84 lines not on this page · raw message
Signature · 1 line
1.7.5.4