Loading Documentation/devicetree/bindings/regulator/gpio-regulator.txt 0 → 100644 +37 −0 Original line number Diff line number Diff line GPIO controlled regulators Required properties: - compatible : Must be "regulator-gpio". - states : Selection of available voltages and GPIO configs. if there are no states, then use a fixed regulator Optional properties: - enable-gpio : GPIO to use to enable/disable the regulator. - gpios : GPIO group used to control voltage. - startup-delay-us : Startup time in microseconds. - enable-active-high : Polarity of GPIO is active high (default is low). Any property defined as part of the core regulator binding defined in regulator.txt can also be used. Example: mmciv: gpio-regulator { compatible = "regulator-gpio"; regulator-name = "mmci-gpio-supply"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <2600000>; regulator-boot-on; enable-gpio = <&gpio0 23 0x4>; gpios = <&gpio0 24 0x4 &gpio0 25 0x4>; states = <1800000 0x3 2200000 0x2 2600000 0x1 2900000 0x0>; startup-delay-us = <100000>; enable-active-high; }; drivers/regulator/gpio-regulator.c +102 −0 Original line number Diff line number Diff line Loading @@ -28,9 +28,12 @@ #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> #include <linux/regulator/of_regulator.h> #include <linux/regulator/gpio-regulator.h> #include <linux/gpio.h> #include <linux/slab.h> #include <linux/of.h> #include <linux/of_gpio.h> struct gpio_regulator_data { struct regulator_desc desc; Loading Loading @@ -129,6 +132,89 @@ static struct regulator_ops gpio_regulator_voltage_ops = { .list_voltage = gpio_regulator_list_voltage, }; struct gpio_regulator_config * of_get_gpio_regulator_config(struct device *dev, struct device_node *np) { struct gpio_regulator_config *config; struct property *prop; const char *regtype; int proplen, gpio, i; config = devm_kzalloc(dev, sizeof(struct gpio_regulator_config), GFP_KERNEL); if (!config) return ERR_PTR(-ENOMEM); config->init_data = of_get_regulator_init_data(dev, np); if (!config->init_data) return ERR_PTR(-EINVAL); config->supply_name = config->init_data->constraints.name; if (of_property_read_bool(np, "enable-active-high")) config->enable_high = true; if (of_property_read_bool(np, "enable-at-boot")) config->enabled_at_boot = true; of_property_read_u32(np, "startup-delay-us", &config->startup_delay); config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0); /* Fetch GPIOs. */ for (i = 0; ; i++) if (of_get_named_gpio(np, "gpios", i) < 0) break; config->nr_gpios = i; config->gpios = devm_kzalloc(dev, sizeof(struct gpio) * config->nr_gpios, GFP_KERNEL); if (!config->gpios) return ERR_PTR(-ENOMEM); for (i = 0; config->nr_gpios; i++) { gpio = of_get_named_gpio(np, "gpios", i); if (gpio < 0) break; config->gpios[i].gpio = gpio; } /* Fetch states. */ prop = of_find_property(np, "states", NULL); if (!prop) { dev_err(dev, "No 'states' property found\n"); return ERR_PTR(-EINVAL); } proplen = prop->length / sizeof(int); config->states = devm_kzalloc(dev, sizeof(struct gpio_regulator_state) * (proplen / 2), GFP_KERNEL); if (!config->states) return ERR_PTR(-ENOMEM); for (i = 0; i < proplen / 2; i++) { config->states[i].value = be32_to_cpup((int *)prop->value + (i * 2)); config->states[i].gpios = be32_to_cpup((int *)prop->value + (i * 2 + 1)); } config->nr_states = i; of_property_read_string(np, "regulator-type", ®type); if (!strncmp("voltage", regtype, 7)) config->type = REGULATOR_VOLTAGE; else if (!strncmp("current", regtype, 7)) config->type = REGULATOR_CURRENT; return config; } static struct regulator_ops gpio_regulator_current_ops = { .get_current_limit = gpio_regulator_get_value, .set_current_limit = gpio_regulator_set_current_limit, Loading @@ -137,10 +223,17 @@ static struct regulator_ops gpio_regulator_current_ops = { static int __devinit gpio_regulator_probe(struct platform_device *pdev) { struct gpio_regulator_config *config = pdev->dev.platform_data; struct device_node *np = pdev->dev.of_node; struct gpio_regulator_data *drvdata; struct regulator_config cfg = { }; int ptr, ret, state; if (np) { config = of_get_gpio_regulator_config(&pdev->dev, np); if (IS_ERR(config)) return PTR_ERR(config); } drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), GFP_KERNEL); if (drvdata == NULL) { Loading Loading @@ -215,6 +308,7 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) cfg.dev = &pdev->dev; cfg.init_data = config->init_data; cfg.driver_data = drvdata; cfg.of_node = np; if (config->enable_gpio >= 0) cfg.ena_gpio = config->enable_gpio; Loading Loading @@ -270,12 +364,20 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev) return 0; } #if defined(CONFIG_OF) static const struct of_device_id regulator_gpio_of_match[] __devinitconst = { { .compatible = "regulator-gpio", }, {}, }; #endif static struct platform_driver gpio_regulator_driver = { .probe = gpio_regulator_probe, .remove = __devexit_p(gpio_regulator_remove), .driver = { .name = "gpio-regulator", .owner = THIS_MODULE, .of_match_table = of_match_ptr(regulator_gpio_of_match), }, }; Loading Loading
Documentation/devicetree/bindings/regulator/gpio-regulator.txt 0 → 100644 +37 −0 Original line number Diff line number Diff line GPIO controlled regulators Required properties: - compatible : Must be "regulator-gpio". - states : Selection of available voltages and GPIO configs. if there are no states, then use a fixed regulator Optional properties: - enable-gpio : GPIO to use to enable/disable the regulator. - gpios : GPIO group used to control voltage. - startup-delay-us : Startup time in microseconds. - enable-active-high : Polarity of GPIO is active high (default is low). Any property defined as part of the core regulator binding defined in regulator.txt can also be used. Example: mmciv: gpio-regulator { compatible = "regulator-gpio"; regulator-name = "mmci-gpio-supply"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <2600000>; regulator-boot-on; enable-gpio = <&gpio0 23 0x4>; gpios = <&gpio0 24 0x4 &gpio0 25 0x4>; states = <1800000 0x3 2200000 0x2 2600000 0x1 2900000 0x0>; startup-delay-us = <100000>; enable-active-high; };
drivers/regulator/gpio-regulator.c +102 −0 Original line number Diff line number Diff line Loading @@ -28,9 +28,12 @@ #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> #include <linux/regulator/of_regulator.h> #include <linux/regulator/gpio-regulator.h> #include <linux/gpio.h> #include <linux/slab.h> #include <linux/of.h> #include <linux/of_gpio.h> struct gpio_regulator_data { struct regulator_desc desc; Loading Loading @@ -129,6 +132,89 @@ static struct regulator_ops gpio_regulator_voltage_ops = { .list_voltage = gpio_regulator_list_voltage, }; struct gpio_regulator_config * of_get_gpio_regulator_config(struct device *dev, struct device_node *np) { struct gpio_regulator_config *config; struct property *prop; const char *regtype; int proplen, gpio, i; config = devm_kzalloc(dev, sizeof(struct gpio_regulator_config), GFP_KERNEL); if (!config) return ERR_PTR(-ENOMEM); config->init_data = of_get_regulator_init_data(dev, np); if (!config->init_data) return ERR_PTR(-EINVAL); config->supply_name = config->init_data->constraints.name; if (of_property_read_bool(np, "enable-active-high")) config->enable_high = true; if (of_property_read_bool(np, "enable-at-boot")) config->enabled_at_boot = true; of_property_read_u32(np, "startup-delay-us", &config->startup_delay); config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0); /* Fetch GPIOs. */ for (i = 0; ; i++) if (of_get_named_gpio(np, "gpios", i) < 0) break; config->nr_gpios = i; config->gpios = devm_kzalloc(dev, sizeof(struct gpio) * config->nr_gpios, GFP_KERNEL); if (!config->gpios) return ERR_PTR(-ENOMEM); for (i = 0; config->nr_gpios; i++) { gpio = of_get_named_gpio(np, "gpios", i); if (gpio < 0) break; config->gpios[i].gpio = gpio; } /* Fetch states. */ prop = of_find_property(np, "states", NULL); if (!prop) { dev_err(dev, "No 'states' property found\n"); return ERR_PTR(-EINVAL); } proplen = prop->length / sizeof(int); config->states = devm_kzalloc(dev, sizeof(struct gpio_regulator_state) * (proplen / 2), GFP_KERNEL); if (!config->states) return ERR_PTR(-ENOMEM); for (i = 0; i < proplen / 2; i++) { config->states[i].value = be32_to_cpup((int *)prop->value + (i * 2)); config->states[i].gpios = be32_to_cpup((int *)prop->value + (i * 2 + 1)); } config->nr_states = i; of_property_read_string(np, "regulator-type", ®type); if (!strncmp("voltage", regtype, 7)) config->type = REGULATOR_VOLTAGE; else if (!strncmp("current", regtype, 7)) config->type = REGULATOR_CURRENT; return config; } static struct regulator_ops gpio_regulator_current_ops = { .get_current_limit = gpio_regulator_get_value, .set_current_limit = gpio_regulator_set_current_limit, Loading @@ -137,10 +223,17 @@ static struct regulator_ops gpio_regulator_current_ops = { static int __devinit gpio_regulator_probe(struct platform_device *pdev) { struct gpio_regulator_config *config = pdev->dev.platform_data; struct device_node *np = pdev->dev.of_node; struct gpio_regulator_data *drvdata; struct regulator_config cfg = { }; int ptr, ret, state; if (np) { config = of_get_gpio_regulator_config(&pdev->dev, np); if (IS_ERR(config)) return PTR_ERR(config); } drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), GFP_KERNEL); if (drvdata == NULL) { Loading Loading @@ -215,6 +308,7 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) cfg.dev = &pdev->dev; cfg.init_data = config->init_data; cfg.driver_data = drvdata; cfg.of_node = np; if (config->enable_gpio >= 0) cfg.ena_gpio = config->enable_gpio; Loading Loading @@ -270,12 +364,20 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev) return 0; } #if defined(CONFIG_OF) static const struct of_device_id regulator_gpio_of_match[] __devinitconst = { { .compatible = "regulator-gpio", }, {}, }; #endif static struct platform_driver gpio_regulator_driver = { .probe = gpio_regulator_probe, .remove = __devexit_p(gpio_regulator_remove), .driver = { .name = "gpio-regulator", .owner = THIS_MODULE, .of_match_table = of_match_ptr(regulator_gpio_of_match), }, }; Loading