diff options
Diffstat (limited to 'drivers/regulator/core.c')
| -rw-r--r-- | drivers/regulator/core.c | 126 |
1 files changed, 108 insertions, 18 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 4c1f999041dd..a3c3785901f5 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/suspend.h> | 24 | #include <linux/suspend.h> |
| 25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
| 26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
| 27 | #include <linux/gpio/consumer.h> | ||
| 27 | #include <linux/of.h> | 28 | #include <linux/of.h> |
| 28 | #include <linux/regmap.h> | 29 | #include <linux/regmap.h> |
| 29 | #include <linux/regulator/of_regulator.h> | 30 | #include <linux/regulator/of_regulator.h> |
| @@ -77,7 +78,7 @@ struct regulator_map { | |||
| 77 | */ | 78 | */ |
| 78 | struct regulator_enable_gpio { | 79 | struct regulator_enable_gpio { |
| 79 | struct list_head list; | 80 | struct list_head list; |
| 80 | int gpio; | 81 | struct gpio_desc *gpiod; |
| 81 | u32 enable_count; /* a number of enabled shared GPIO */ | 82 | u32 enable_count; /* a number of enabled shared GPIO */ |
| 82 | u32 request_count; /* a number of requested shared GPIO */ | 83 | u32 request_count; /* a number of requested shared GPIO */ |
| 83 | unsigned int ena_gpio_invert:1; | 84 | unsigned int ena_gpio_invert:1; |
| @@ -846,7 +847,9 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, | |||
| 846 | rdev->constraints->min_uV == rdev->constraints->max_uV) { | 847 | rdev->constraints->min_uV == rdev->constraints->max_uV) { |
| 847 | int current_uV = _regulator_get_voltage(rdev); | 848 | int current_uV = _regulator_get_voltage(rdev); |
| 848 | if (current_uV < 0) { | 849 | if (current_uV < 0) { |
| 849 | rdev_err(rdev, "failed to get the current voltage\n"); | 850 | rdev_err(rdev, |
| 851 | "failed to get the current voltage(%d)\n", | ||
| 852 | current_uV); | ||
| 850 | return current_uV; | 853 | return current_uV; |
| 851 | } | 854 | } |
| 852 | if (current_uV < rdev->constraints->min_uV || | 855 | if (current_uV < rdev->constraints->min_uV || |
| @@ -856,8 +859,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, | |||
| 856 | rdev->constraints->max_uV); | 859 | rdev->constraints->max_uV); |
| 857 | if (ret < 0) { | 860 | if (ret < 0) { |
| 858 | rdev_err(rdev, | 861 | rdev_err(rdev, |
| 859 | "failed to apply %duV constraint\n", | 862 | "failed to apply %duV constraint(%d)\n", |
| 860 | rdev->constraints->min_uV); | 863 | rdev->constraints->min_uV, ret); |
| 861 | return ret; | 864 | return ret; |
| 862 | } | 865 | } |
| 863 | } | 866 | } |
| @@ -1660,10 +1663,13 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev, | |||
| 1660 | const struct regulator_config *config) | 1663 | const struct regulator_config *config) |
| 1661 | { | 1664 | { |
| 1662 | struct regulator_enable_gpio *pin; | 1665 | struct regulator_enable_gpio *pin; |
| 1666 | struct gpio_desc *gpiod; | ||
| 1663 | int ret; | 1667 | int ret; |
| 1664 | 1668 | ||
| 1669 | gpiod = gpio_to_desc(config->ena_gpio); | ||
| 1670 | |||
| 1665 | list_for_each_entry(pin, ®ulator_ena_gpio_list, list) { | 1671 | list_for_each_entry(pin, ®ulator_ena_gpio_list, list) { |
| 1666 | if (pin->gpio == config->ena_gpio) { | 1672 | if (pin->gpiod == gpiod) { |
| 1667 | rdev_dbg(rdev, "GPIO %d is already used\n", | 1673 | rdev_dbg(rdev, "GPIO %d is already used\n", |
| 1668 | config->ena_gpio); | 1674 | config->ena_gpio); |
| 1669 | goto update_ena_gpio_to_rdev; | 1675 | goto update_ena_gpio_to_rdev; |
| @@ -1682,7 +1688,7 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev, | |||
| 1682 | return -ENOMEM; | 1688 | return -ENOMEM; |
| 1683 | } | 1689 | } |
| 1684 | 1690 | ||
| 1685 | pin->gpio = config->ena_gpio; | 1691 | pin->gpiod = gpiod; |
| 1686 | pin->ena_gpio_invert = config->ena_gpio_invert; | 1692 | pin->ena_gpio_invert = config->ena_gpio_invert; |
| 1687 | list_add(&pin->list, ®ulator_ena_gpio_list); | 1693 | list_add(&pin->list, ®ulator_ena_gpio_list); |
| 1688 | 1694 | ||
| @@ -1701,10 +1707,10 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev) | |||
| 1701 | 1707 | ||
| 1702 | /* Free the GPIO only in case of no use */ | 1708 | /* Free the GPIO only in case of no use */ |
| 1703 | list_for_each_entry_safe(pin, n, ®ulator_ena_gpio_list, list) { | 1709 | list_for_each_entry_safe(pin, n, ®ulator_ena_gpio_list, list) { |
| 1704 | if (pin->gpio == rdev->ena_pin->gpio) { | 1710 | if (pin->gpiod == rdev->ena_pin->gpiod) { |
| 1705 | if (pin->request_count <= 1) { | 1711 | if (pin->request_count <= 1) { |
| 1706 | pin->request_count = 0; | 1712 | pin->request_count = 0; |
| 1707 | gpio_free(pin->gpio); | 1713 | gpiod_put(pin->gpiod); |
| 1708 | list_del(&pin->list); | 1714 | list_del(&pin->list); |
| 1709 | kfree(pin); | 1715 | kfree(pin); |
| 1710 | } else { | 1716 | } else { |
| @@ -1732,8 +1738,8 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) | |||
| 1732 | if (enable) { | 1738 | if (enable) { |
| 1733 | /* Enable GPIO at initial use */ | 1739 | /* Enable GPIO at initial use */ |
| 1734 | if (pin->enable_count == 0) | 1740 | if (pin->enable_count == 0) |
| 1735 | gpio_set_value_cansleep(pin->gpio, | 1741 | gpiod_set_value_cansleep(pin->gpiod, |
| 1736 | !pin->ena_gpio_invert); | 1742 | !pin->ena_gpio_invert); |
| 1737 | 1743 | ||
| 1738 | pin->enable_count++; | 1744 | pin->enable_count++; |
| 1739 | } else { | 1745 | } else { |
| @@ -1744,8 +1750,8 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) | |||
| 1744 | 1750 | ||
| 1745 | /* Disable GPIO if not used */ | 1751 | /* Disable GPIO if not used */ |
| 1746 | if (pin->enable_count <= 1) { | 1752 | if (pin->enable_count <= 1) { |
| 1747 | gpio_set_value_cansleep(pin->gpio, | 1753 | gpiod_set_value_cansleep(pin->gpiod, |
| 1748 | pin->ena_gpio_invert); | 1754 | pin->ena_gpio_invert); |
| 1749 | pin->enable_count = 0; | 1755 | pin->enable_count = 0; |
| 1750 | } | 1756 | } |
| 1751 | } | 1757 | } |
| @@ -2180,7 +2186,13 @@ int regulator_count_voltages(struct regulator *regulator) | |||
| 2180 | { | 2186 | { |
| 2181 | struct regulator_dev *rdev = regulator->rdev; | 2187 | struct regulator_dev *rdev = regulator->rdev; |
| 2182 | 2188 | ||
| 2183 | return rdev->desc->n_voltages ? : -EINVAL; | 2189 | if (rdev->desc->n_voltages) |
| 2190 | return rdev->desc->n_voltages; | ||
| 2191 | |||
| 2192 | if (!rdev->supply) | ||
| 2193 | return -EINVAL; | ||
| 2194 | |||
| 2195 | return regulator_count_voltages(rdev->supply); | ||
| 2184 | } | 2196 | } |
| 2185 | EXPORT_SYMBOL_GPL(regulator_count_voltages); | 2197 | EXPORT_SYMBOL_GPL(regulator_count_voltages); |
| 2186 | 2198 | ||
| @@ -2203,12 +2215,17 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector) | |||
| 2203 | if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector) | 2215 | if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector) |
| 2204 | return rdev->desc->fixed_uV; | 2216 | return rdev->desc->fixed_uV; |
| 2205 | 2217 | ||
| 2206 | if (!ops->list_voltage || selector >= rdev->desc->n_voltages) | 2218 | if (ops->list_voltage) { |
| 2219 | if (selector >= rdev->desc->n_voltages) | ||
| 2220 | return -EINVAL; | ||
| 2221 | mutex_lock(&rdev->mutex); | ||
| 2222 | ret = ops->list_voltage(rdev, selector); | ||
| 2223 | mutex_unlock(&rdev->mutex); | ||
| 2224 | } else if (rdev->supply) { | ||
| 2225 | ret = regulator_list_voltage(rdev->supply, selector); | ||
| 2226 | } else { | ||
| 2207 | return -EINVAL; | 2227 | return -EINVAL; |
| 2208 | 2228 | } | |
| 2209 | mutex_lock(&rdev->mutex); | ||
| 2210 | ret = ops->list_voltage(rdev, selector); | ||
| 2211 | mutex_unlock(&rdev->mutex); | ||
| 2212 | 2229 | ||
| 2213 | if (ret > 0) { | 2230 | if (ret > 0) { |
| 2214 | if (ret < rdev->constraints->min_uV) | 2231 | if (ret < rdev->constraints->min_uV) |
| @@ -2222,6 +2239,77 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector) | |||
| 2222 | EXPORT_SYMBOL_GPL(regulator_list_voltage); | 2239 | EXPORT_SYMBOL_GPL(regulator_list_voltage); |
| 2223 | 2240 | ||
| 2224 | /** | 2241 | /** |
| 2242 | * regulator_get_regmap - get the regulator's register map | ||
| 2243 | * @regulator: regulator source | ||
| 2244 | * | ||
| 2245 | * Returns the register map for the given regulator, or an ERR_PTR value | ||
| 2246 | * if the regulator doesn't use regmap. | ||
| 2247 | */ | ||
| 2248 | struct regmap *regulator_get_regmap(struct regulator *regulator) | ||
| 2249 | { | ||
| 2250 | struct regmap *map = regulator->rdev->regmap; | ||
| 2251 | |||
| 2252 | return map ? map : ERR_PTR(-EOPNOTSUPP); | ||
| 2253 | } | ||
| 2254 | |||
| 2255 | /** | ||
| 2256 | * regulator_get_hardware_vsel_register - get the HW voltage selector register | ||
| 2257 | * @regulator: regulator source | ||
| 2258 | * @vsel_reg: voltage selector register, output parameter | ||
| 2259 | * @vsel_mask: mask for voltage selector bitfield, output parameter | ||
| 2260 | * | ||
| 2261 | * Returns the hardware register offset and bitmask used for setting the | ||
| 2262 | * regulator voltage. This might be useful when configuring voltage-scaling | ||
| 2263 | * hardware or firmware that can make I2C requests behind the kernel's back, | ||
| 2264 | * for example. | ||
| 2265 | * | ||
| 2266 | * On success, the output parameters @vsel_reg and @vsel_mask are filled in | ||
| 2267 | * and 0 is returned, otherwise a negative errno is returned. | ||
| 2268 | */ | ||
| 2269 | int regulator_get_hardware_vsel_register(struct regulator *regulator, | ||
| 2270 | unsigned *vsel_reg, | ||
| 2271 | unsigned *vsel_mask) | ||
| 2272 | { | ||
| 2273 | struct regulator_dev *rdev = regulator->rdev; | ||
| 2274 | struct regulator_ops *ops = rdev->desc->ops; | ||
| 2275 | |||
| 2276 | if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap) | ||
| 2277 | return -EOPNOTSUPP; | ||
| 2278 | |||
| 2279 | *vsel_reg = rdev->desc->vsel_reg; | ||
| 2280 | *vsel_mask = rdev->desc->vsel_mask; | ||
| 2281 | |||
| 2282 | return 0; | ||
| 2283 | } | ||
| 2284 | EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register); | ||
| 2285 | |||
| 2286 | /** | ||
| 2287 | * regulator_list_hardware_vsel - get the HW-specific register value for a selector | ||
| 2288 | * @regulator: regulator source | ||
| 2289 | * @selector: identify voltage to list | ||
| 2290 | * | ||
| 2291 | * Converts the selector to a hardware-specific voltage selector that can be | ||
| 2292 | * directly written to the regulator registers. The address of the voltage | ||
| 2293 | * register can be determined by calling @regulator_get_hardware_vsel_register. | ||
| 2294 | * | ||
| 2295 | * On error a negative errno is returned. | ||
| 2296 | */ | ||
| 2297 | int regulator_list_hardware_vsel(struct regulator *regulator, | ||
| 2298 | unsigned selector) | ||
| 2299 | { | ||
| 2300 | struct regulator_dev *rdev = regulator->rdev; | ||
| 2301 | struct regulator_ops *ops = rdev->desc->ops; | ||
| 2302 | |||
| 2303 | if (selector >= rdev->desc->n_voltages) | ||
| 2304 | return -EINVAL; | ||
| 2305 | if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap) | ||
| 2306 | return -EOPNOTSUPP; | ||
| 2307 | |||
| 2308 | return selector; | ||
| 2309 | } | ||
| 2310 | EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel); | ||
| 2311 | |||
| 2312 | /** | ||
| 2225 | * regulator_get_linear_step - return the voltage step size between VSEL values | 2313 | * regulator_get_linear_step - return the voltage step size between VSEL values |
| 2226 | * @regulator: regulator source | 2314 | * @regulator: regulator source |
| 2227 | * | 2315 | * |
| @@ -2618,6 +2706,8 @@ static int _regulator_get_voltage(struct regulator_dev *rdev) | |||
| 2618 | ret = rdev->desc->ops->list_voltage(rdev, 0); | 2706 | ret = rdev->desc->ops->list_voltage(rdev, 0); |
| 2619 | } else if (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1)) { | 2707 | } else if (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1)) { |
| 2620 | ret = rdev->desc->fixed_uV; | 2708 | ret = rdev->desc->fixed_uV; |
| 2709 | } else if (rdev->supply) { | ||
| 2710 | ret = regulator_get_voltage(rdev->supply); | ||
| 2621 | } else { | 2711 | } else { |
| 2622 | return -EINVAL; | 2712 | return -EINVAL; |
| 2623 | } | 2713 | } |
