From 4e92920b4ba25a0a70dd056e0dd7b4b4fd1a3dc6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 3 Oct 2012 12:42:06 +0100 Subject: regulator: lp8788-ldo: Staticise non-exported symbol Signed-off-by: Mark Brown diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index 6796eeb..e496ba0 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -126,7 +126,7 @@ struct lp8788_ldo { }; /* DLDO 1, 2, 3, 9 voltage table */ -const int lp8788_dldo1239_vtbl[] = { +static const int lp8788_dldo1239_vtbl[] = { 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, -- cgit v0.10.2 From 0c57067430a2b729bc08c92b17eb4f29d9bbfaae Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Sat, 6 Oct 2012 20:47:46 +0530 Subject: regulator: tps51632: Add tps51632 regulator driver The TPS51632 is a driverless step down controller with serial control. Advanced features such as D-Cap+ architecture with overlapping pulse support and OSR overshoot reduction provide fast transient response, lowest output capacitance and high efficiency. The TPS51632 supports both I2C and DVFS interfaces (through PWM) for dynamic control of the output voltage and current monitor telemetry. Add regulator driver for TPS51632. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 67d47b59..aa9e8a1 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -335,6 +335,17 @@ config REGULATOR_PALMAS on the muxing. This is handled automatically in the driver by reading the mux info from OTP. +config REGULATOR_TPS51632 + tristate "TI TPS51632 Power Regulator" + depends on I2C + select REGMAP_I2C + help + This driver supports TPS51632 voltage regulator chip. + The TPS52632 is 3-2-1 Phase D-Cap+ Step Down Driverless Controller + with Serial VID control and DVFS. + The voltage output can be configure through I2C interface or PWM + interface. + config REGULATOR_TPS6105X tristate "TI TPS6105X Power regulators" depends on TPS6105X diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e431eed..ec1aec4 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o +obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c new file mode 100644 index 0000000..3460364 --- /dev/null +++ b/drivers/regulator/tps51632-regulator.c @@ -0,0 +1,332 @@ +/* + * tps51632-regulator.c -- TI TPS51632 + * + * Regulator driver for TPS51632 3-2-1 Phase D-Cap Step Down Driverless + * Controller with serial VID control and DVFS. + * + * Copyright (c) 2012, NVIDIA Corporation. + * + * Author: Laxman Dewangan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register definitions */ +#define TPS51632_VOLTAGE_SELECT_REG 0x0 +#define TPS51632_VOLTAGE_BASE_REG 0x1 +#define TPS51632_OFFSET_REG 0x2 +#define TPS51632_IMON_REG 0x3 +#define TPS51632_VMAX_REG 0x4 +#define TPS51632_DVFS_CONTROL_REG 0x5 +#define TPS51632_POWER_STATE_REG 0x6 +#define TPS51632_SLEW_REGS 0x7 +#define TPS51632_FAULT_REG 0x14 + +#define TPS51632_MAX_REG 0x15 + +#define TPS51632_VOUT_MASK 0x7F +#define TPS51632_VOUT_OFFSET_MASK 0x1F +#define TPS51632_VMAX_MASK 0x7F +#define TPS51632_VMAX_LOCK 0x80 + +/* TPS51632_DVFS_CONTROL_REG */ +#define TPS51632_DVFS_PWMEN 0x1 +#define TPS51632_DVFS_STEP_20 0x2 +#define TPS51632_DVFS_VMAX_PG 0x4 +#define TPS51632_DVFS_PWMRST 0x8 +#define TPS51632_DVFS_OCA_EN 0x10 +#define TPS51632_DVFS_FCCM 0x20 + +/* TPS51632_POWER_STATE_REG */ +#define TPS51632_POWER_STATE_MASK 0x03 +#define TPS51632_POWER_STATE_MULTI_PHASE_CCM 0x0 +#define TPS51632_POWER_STATE_SINGLE_PHASE_CCM 0x1 +#define TPS51632_POWER_STATE_SINGLE_PHASE_DCM 0x2 + +#define TPS51632_MIN_VOLATGE 500000 +#define TPS51632_MAX_VOLATGE 1520000 +#define TPS51632_VOLATGE_STEP_10mV 10000 +#define TPS51632_VOLATGE_STEP_20mV 20000 +#define TPS51632_MAX_VSEL 0x7F +#define TPS51632_MIN_VSEL 0x19 +#define TPS51632_DEFAULT_RAMP_DELAY 6000 +#define TPS51632_VOLT_VSEL(uV) \ + (DIV_ROUND_UP(uV - TPS51632_MIN_VOLATGE, \ + TPS51632_VOLATGE_STEP_10mV) + \ + TPS51632_MIN_VSEL) + +/* TPS51632 chip information */ +struct tps51632_chip { + struct device *dev; + struct regulator_desc desc; + struct regulator_dev *rdev; + struct regmap *regmap; + bool enable_pwm_dvfs; +}; + +static int tps51632_dcdc_get_voltage_sel(struct regulator_dev *rdev) +{ + struct tps51632_chip *tps = rdev_get_drvdata(rdev); + unsigned int data; + int ret; + unsigned int reg = TPS51632_VOLTAGE_SELECT_REG; + int vsel; + + if (tps->enable_pwm_dvfs) + reg = TPS51632_VOLTAGE_BASE_REG; + + ret = regmap_read(tps->regmap, reg, &data); + if (ret < 0) { + dev_err(tps->dev, "reg read failed, err %d\n", ret); + return ret; + } + + vsel = data & TPS51632_VOUT_MASK; + + if (vsel < TPS51632_MIN_VSEL) + return 0; + else + return vsel - TPS51632_MIN_VSEL; +} + +static int tps51632_dcdc_set_voltage_sel(struct regulator_dev *rdev, + unsigned selector) +{ + struct tps51632_chip *tps = rdev_get_drvdata(rdev); + int vsel; + int ret; + unsigned int reg = TPS51632_VOLTAGE_SELECT_REG; + + if (tps->enable_pwm_dvfs) + reg = TPS51632_VOLTAGE_BASE_REG; + + vsel = selector + TPS51632_MIN_VSEL; + if (vsel > TPS51632_MAX_VSEL) + return -EINVAL; + + ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_SELECT_REG, vsel); + if (ret < 0) + dev_err(tps->dev, "reg write failed, err %d\n", ret); + return ret; +} + +static int tps51632_dcdc_set_ramp_delay(struct regulator_dev *rdev, + int ramp_delay) +{ + struct tps51632_chip *tps = rdev_get_drvdata(rdev); + int bit = ramp_delay/6000; + int ret; + + if (bit) + bit--; + ret = regmap_write(tps->regmap, TPS51632_SLEW_REGS, BIT(bit)); + if (ret < 0) + dev_err(tps->dev, "SLEW reg write failed, err %d\n", ret); + return ret; +} + +static struct regulator_ops tps51632_dcdc_ops = { + .get_voltage_sel = tps51632_dcdc_get_voltage_sel, + .set_voltage_sel = tps51632_dcdc_set_voltage_sel, + .list_voltage = regulator_list_voltage_linear, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_ramp_delay = tps51632_dcdc_set_ramp_delay, +}; + +static int __devinit tps51632_init_dcdc(struct tps51632_chip *tps, + struct tps51632_regulator_platform_data *pdata) +{ + int ret; + uint8_t control = 0; + int vsel; + + if (!pdata->enable_pwm_dvfs) + goto skip_pwm_config; + + control |= TPS51632_DVFS_PWMEN; + tps->enable_pwm_dvfs = pdata->enable_pwm_dvfs; + vsel = TPS51632_VOLT_VSEL(pdata->base_voltage_uV); + ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_BASE_REG, vsel); + if (ret < 0) { + dev_err(tps->dev, "BASE reg write failed, err %d\n", ret); + return ret; + } + + if (pdata->dvfs_step_20mV) + control |= TPS51632_DVFS_STEP_20; + + if (pdata->max_voltage_uV) { + unsigned int vmax; + /** + * TPS51632 hw behavior: VMAX register can be write only + * once as it get locked after first write. The lock get + * reset only when device is power-reset. + * Write register only when lock bit is not enabled. + */ + ret = regmap_read(tps->regmap, TPS51632_VMAX_REG, &vmax); + if (ret < 0) { + dev_err(tps->dev, "VMAX read failed, err %d\n", ret); + return ret; + } + if (!(vmax & TPS51632_VMAX_LOCK)) { + vsel = TPS51632_VOLT_VSEL(pdata->max_voltage_uV); + ret = regmap_write(tps->regmap, TPS51632_VMAX_REG, + vsel); + if (ret < 0) { + dev_err(tps->dev, + "VMAX write failed, err %d\n", ret); + return ret; + } + } + } + +skip_pwm_config: + ret = regmap_write(tps->regmap, TPS51632_DVFS_CONTROL_REG, control); + if (ret < 0) + dev_err(tps->dev, "DVFS reg write failed, err %d\n", ret); + return ret; +} + +static bool rd_wr_reg(struct device *dev, unsigned int reg) +{ + if ((reg >= 0x8) && (reg <= 0x10)) + return false; + return true; +} + +static const struct regmap_config tps51632_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .writeable_reg = rd_wr_reg, + .readable_reg = rd_wr_reg, + .max_register = TPS51632_MAX_REG - 1, + .cache_type = REGCACHE_RBTREE, +}; + +static int __devinit tps51632_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tps51632_regulator_platform_data *pdata; + struct regulator_dev *rdev; + struct tps51632_chip *tps; + int ret; + struct regulator_config config = { }; + + pdata = client->dev.platform_data; + if (!pdata) { + dev_err(&client->dev, "No Platform data\n"); + return -EINVAL; + } + + tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); + if (!tps) { + dev_err(&client->dev, "Memory allocation failed\n"); + return -ENOMEM; + } + + tps->dev = &client->dev; + tps->desc.name = id->name; + tps->desc.id = 0; + tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY; + tps->desc.min_uV = TPS51632_MIN_VOLATGE; + tps->desc.uV_step = TPS51632_VOLATGE_STEP_10mV; + tps->desc.n_voltages = (TPS51632_MAX_VSEL - TPS51632_MIN_VSEL) + 1; + tps->desc.ops = &tps51632_dcdc_ops; + tps->desc.type = REGULATOR_VOLTAGE; + tps->desc.owner = THIS_MODULE; + + tps->regmap = devm_regmap_init_i2c(client, &tps51632_regmap_config); + if (IS_ERR(tps->regmap)) { + ret = PTR_ERR(tps->regmap); + dev_err(&client->dev, "regmap init failed, err %d\n", ret); + return ret; + } + i2c_set_clientdata(client, tps); + + ret = tps51632_init_dcdc(tps, pdata); + if (ret < 0) { + dev_err(tps->dev, "Init failed, err = %d\n", ret); + return ret; + } + + /* Register the regulators */ + config.dev = &client->dev; + config.init_data = pdata->reg_init_data; + config.driver_data = tps; + config.regmap = tps->regmap; + config.of_node = client->dev.of_node; + + rdev = regulator_register(&tps->desc, &config); + if (IS_ERR(rdev)) { + dev_err(tps->dev, "regulator register failed\n"); + return PTR_ERR(rdev); + } + + tps->rdev = rdev; + return 0; +} + +static int __devexit tps51632_remove(struct i2c_client *client) +{ + struct tps51632_chip *tps = i2c_get_clientdata(client); + + regulator_unregister(tps->rdev); + return 0; +} + +static const struct i2c_device_id tps51632_id[] = { + {.name = "tps51632",}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, tps51632_id); + +static struct i2c_driver tps51632_i2c_driver = { + .driver = { + .name = "tps51632", + .owner = THIS_MODULE, + }, + .probe = tps51632_probe, + .remove = __devexit_p(tps51632_remove), + .id_table = tps51632_id, +}; + +static int __init tps51632_init(void) +{ + return i2c_add_driver(&tps51632_i2c_driver); +} +subsys_initcall(tps51632_init); + +static void __exit tps51632_cleanup(void) +{ + i2c_del_driver(&tps51632_i2c_driver); +} +module_exit(tps51632_cleanup); + +MODULE_AUTHOR("Laxman Dewangan "); +MODULE_DESCRIPTION("TPS51632 voltage regulator driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/regulator/tps51632-regulator.h b/include/linux/regulator/tps51632-regulator.h new file mode 100644 index 0000000..d00841e --- /dev/null +++ b/include/linux/regulator/tps51632-regulator.h @@ -0,0 +1,47 @@ +/* + * tps51632-regulator.h -- TPS51632 regulator + * + * Interface for regulator driver for TPS51632 3-2-1 Phase D-Cap Step Down + * Driverless Controller with serial VID control and DVFS. + * + * Copyright (C) 2012 NVIDIA Corporation + + * Author: Laxman Dewangan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __LINUX_REGULATOR_TPS51632_H +#define __LINUX_REGULATOR_TPS51632_H + +/* + * struct tps51632_regulator_platform_data - tps51632 regulator platform data. + * + * @reg_init_data: The regulator init data. + * @enable_pwm_dvfs: Enable PWM DVFS or not. + * @dvfs_step_20mV: Step for DVFS is 20mV or 10mV. + * @max_voltage_uV: Maximum possible voltage in PWM-DVFS mode. + * @base_voltage_uV: Base voltage when PWM-DVFS enabled. + */ +struct tps51632_regulator_platform_data { + struct regulator_init_data *reg_init_data; + bool enable_pwm_dvfs; + bool dvfs_step_20mV; + int max_voltage_uV; + int base_voltage_uV; +}; + +#endif /* __LINUX_REGULATOR_TPS51632_H */ -- cgit v0.10.2 From bd7a2b600ace90c8819495b639a744c8f5c68feb Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Mon, 24 Sep 2012 18:56:53 +0100 Subject: regulator: core: Support for continuous voltage range Some regulators can set any voltage within the constraints range, not being limited to specified operating points. This patch makes it possible to describe such regulator and makes the regulator_is_supported_voltage() function behave correctly. Signed-off-by: Pawel Moll Signed-off-by: Mark Brown diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c4829c..f7c74db 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1979,6 +1979,11 @@ int regulator_is_supported_voltage(struct regulator *regulator, return ret; } + /* Any voltage within constrains range is fine? */ + if (rdev->desc->continuous_voltage_range) + return min_uV >= rdev->constraints->min_uV && + max_uV <= rdev->constraints->max_uV; + ret = regulator_count_voltages(regulator); if (ret < 0) return ret; diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 7932a3b..f2b72b2 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -181,6 +181,8 @@ enum regulator_type { * @type: Indicates if the regulator is a voltage or current regulator. * @owner: Module providing the regulator, used for refcounting. * + * @continuous_voltage_range: Indicates if the regulator can set any + * voltage within constrains range. * @n_voltages: Number of selectors available for ops.list_voltage(). * * @min_uV: Voltage given by the lowest selector (if linear mapping) @@ -199,6 +201,7 @@ struct regulator_desc { const char *name; const char *supply_name; int id; + bool continuous_voltage_range; unsigned n_voltages; struct regulator_ops *ops; int irq; -- cgit v0.10.2 From 31e54086dd7bb86ad40f1d76a9063f2a95866b87 Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Mon, 24 Sep 2012 18:56:54 +0100 Subject: regulator: Versatile Express regulator driver Implementation of the regulator framework driver for the Versatile Express voltage control. Devices without voltage constraints (ie. "regulator-[min|max]-microvolt" properties in the DT node) are treated as fixed (or rather read-only) regulators. Signed-off-by: Pawel Moll Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/regulator/vexpress.txt b/Documentation/devicetree/bindings/regulator/vexpress.txt new file mode 100644 index 0000000..d775f72 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/vexpress.txt @@ -0,0 +1,32 @@ +Versatile Express voltage regulators +------------------------------------ + +Requires node properties: +- "compatible" value: "arm,vexpress-volt" +- "arm,vexpress-sysreg,func" when controlled via vexpress-sysreg + (see Documentation/devicetree/bindings/arm/vexpress-sysreg.txt + for more details) + +Required regulator properties: +- "regulator-name" +- "regulator-always-on" + +Optional regulator properties: +- "regulator-min-microvolt" +- "regulator-max-microvolt" + +See Documentation/devicetree/bindings/regulator/regulator.txt +for more details about the regulator properties. + +When no "regulator-[min|max]-microvolt" properties are defined, +the device is treated as fixed (or rather "read-only") regulator. + +Example: + volt@0 { + compatible = "arm,vexpress-volt"; + arm,vexpress-sysreg,func = <2 0>; + regulator-name = "Cores"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1050000>; + regulator-always-on; + }; diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 67d47b59..b44b019 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -422,6 +422,13 @@ config REGULATOR_TWL4030 This driver supports the voltage regulators provided by this family of companion chips. +config REGULATOR_VEXPRESS + tristate "Versatile Express regulators" + depends on VEXPRESS_CONFIG + help + This driver provides support for voltage regulators available + on the ARM Ltd's Versatile Express platform. + config REGULATOR_WM831X tristate "Wolfson Microelectronics WM831x PMIC regulators" depends on MFD_WM831X diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e431eed..9fa7a7b 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o +obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c new file mode 100644 index 0000000..1702945 --- /dev/null +++ b/drivers/regulator/vexpress.c @@ -0,0 +1,146 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Copyright (C) 2012 ARM Limited + */ + +#define DRVNAME "vexpress-regulator" +#define pr_fmt(fmt) DRVNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +struct vexpress_regulator { + struct regulator_desc desc; + struct regulator_dev *regdev; + struct vexpress_config_func *func; +}; + +static int vexpress_regulator_get_voltage(struct regulator_dev *regdev) +{ + struct vexpress_regulator *reg = rdev_get_drvdata(regdev); + u32 uV; + int err = vexpress_config_read(reg->func, 0, &uV); + + return err ? err : uV; +} + +static int vexpress_regulator_set_voltage(struct regulator_dev *regdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct vexpress_regulator *reg = rdev_get_drvdata(regdev); + + return vexpress_config_write(reg->func, 0, min_uV); +} + +static struct regulator_ops vexpress_regulator_ops_ro = { + .get_voltage = vexpress_regulator_get_voltage, +}; + +static struct regulator_ops vexpress_regulator_ops = { + .get_voltage = vexpress_regulator_get_voltage, + .set_voltage = vexpress_regulator_set_voltage, +}; + +static int vexpress_regulator_probe(struct platform_device *pdev) +{ + int err; + struct vexpress_regulator *reg; + struct regulator_init_data *init_data; + struct regulator_config config = { }; + + reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL); + if (!reg) { + err = -ENOMEM; + goto error_kzalloc; + } + + reg->func = vexpress_config_func_get_by_dev(&pdev->dev); + if (!reg->func) { + err = -ENXIO; + goto error_get_func; + } + + reg->desc.name = dev_name(&pdev->dev); + reg->desc.type = REGULATOR_VOLTAGE; + reg->desc.owner = THIS_MODULE; + reg->desc.continuous_voltage_range = true; + + init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); + if (!init_data) { + err = -EINVAL; + goto error_get_regulator_init_data; + } + + init_data->constraints.apply_uV = 0; + if (init_data->constraints.min_uV && init_data->constraints.max_uV) + reg->desc.ops = &vexpress_regulator_ops; + else + reg->desc.ops = &vexpress_regulator_ops_ro; + + config.dev = &pdev->dev; + config.init_data = init_data; + config.driver_data = reg; + config.of_node = pdev->dev.of_node; + + reg->regdev = regulator_register(®->desc, &config); + if (IS_ERR(reg->regdev)) { + err = PTR_ERR(reg->regdev); + goto error_regulator_register; + } + + platform_set_drvdata(pdev, reg); + + return 0; + +error_regulator_register: +error_get_regulator_init_data: + vexpress_config_func_put(reg->func); +error_get_func: +error_kzalloc: + return err; +} + +static int __devexit vexpress_regulator_remove(struct platform_device *pdev) +{ + struct vexpress_regulator *reg = platform_get_drvdata(pdev); + + vexpress_config_func_put(reg->func); + regulator_unregister(reg->regdev); + + return 0; +} + +static struct of_device_id vexpress_regulator_of_match[] = { + { .compatible = "arm,vexpress-volt", }, +}; + +static struct platform_driver vexpress_regulator_driver = { + .probe = vexpress_regulator_probe, + .remove = __devexit_p(vexpress_regulator_remove), + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + .of_match_table = vexpress_regulator_of_match, + }, +}; + +module_platform_driver(vexpress_regulator_driver); + +MODULE_AUTHOR("Pawel Moll "); +MODULE_DESCRIPTION("Versatile Express regulator"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:vexpress-regulator"); -- cgit v0.10.2 From 9f4e45f77e8a532c8a7e39268e844821dbf7fe91 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 17 Oct 2012 09:00:20 +0800 Subject: regulator: vexpress: Add terminating entry for vexpress_regulator_of_match table The of_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c index 1702945..1d55811 100644 --- a/drivers/regulator/vexpress.c +++ b/drivers/regulator/vexpress.c @@ -126,6 +126,7 @@ static int __devexit vexpress_regulator_remove(struct platform_device *pdev) static struct of_device_id vexpress_regulator_of_match[] = { { .compatible = "arm,vexpress-volt", }, + { } }; static struct platform_driver vexpress_regulator_driver = { -- cgit v0.10.2 From 6d2c896b72322ccca465b57123e66890ebddb0ab Mon Sep 17 00:00:00 2001 From: Yadwinder Singh Brar Date: Tue, 16 Oct 2012 17:24:18 +0530 Subject: regulator: max77686: Use already set opmode while re-enabling regulators. This patch adds basic support to take care of opmode(if any) which can be set by set_suspend_[disable/mode] callbacks. Signed-off-by: Yadwinder Singh Brar Signed-off-by: Mark Brown diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 2a67d08..20dae7b 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -67,8 +67,18 @@ enum max77686_ramp_rate { struct max77686_data { struct regulator_dev *rdev[MAX77686_REGULATORS]; + unsigned int opmode[MAX77686_REGULATORS]; }; +int max77686_enable(struct regulator_dev *rdev) +{ + struct max77686_data *max77686 = rdev_get_drvdata(rdev); + + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, + max77686->opmode[rdev->desc->id]); +} + static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) { unsigned int ramp_value = RAMP_RATE_NO_CTRL; @@ -98,7 +108,7 @@ static struct regulator_ops max77686_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, + .enable = max77686_enable, .disable = regulator_disable_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -109,7 +119,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, + .enable = max77686_enable, .disable = regulator_disable_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -314,12 +324,14 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev) config.dev = &pdev->dev; config.regmap = iodev->regmap; + config.driver_data = max77686; platform_set_drvdata(pdev, max77686); for (i = 0; i < MAX77686_REGULATORS; i++) { config.init_data = pdata->regulators[i].initdata; config.of_node = pdata->regulators[i].of_node; + max77686->opmode[i] = regulators[i].enable_mask; max77686->rdev[i] = regulator_register(®ulators[i], &config); if (IS_ERR(max77686->rdev[i])) { ret = PTR_ERR(max77686->rdev[i]); -- cgit v0.10.2 From 15282ba9ea9d22c437dd53e589b937207b6a38ce Mon Sep 17 00:00:00 2001 From: Yadwinder Singh Brar Date: Tue, 16 Oct 2012 17:24:19 +0530 Subject: regulator: max77686: Add set_suspend_disable/set_suspend_mode callbacks. This patch implements set_suspend_disable callback for BUCKs which support only switch ON/OFF modes during system suspend state, and set_suspend_mode callbacks for LDOs which also suport Low power mode and switch ON/OFF modes. Signed-off-by: Yadwinder Singh Brar Signed-off-by: Mark Brown diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 20dae7b..383eb9d 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -70,6 +70,82 @@ struct max77686_data { unsigned int opmode[MAX77686_REGULATORS]; }; +/* Some BUCKS supports Normal[ON/OFF] mode during suspend */ +static int max77686_buck_set_suspend_disable(struct regulator_dev *rdev) +{ + unsigned int val; + struct max77686_data *max77686 = rdev_get_drvdata(rdev); + + if (rdev->desc->id == MAX77686_BUCK1) + val = 0x1; + else + val = 0x1 << MAX77686_OPMODE_BUCK234_SHIFT; + + max77686->opmode[rdev->desc->id] = val; + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, + val); +} + +/* Some LDOs supports [LPM/Normal]ON mode during suspend state */ +static int max77686_set_suspend_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct max77686_data *max77686 = rdev_get_drvdata(rdev); + unsigned int val; + + /* BUCK[5-9] doesn't support this feature */ + if (rdev->desc->id >= MAX77686_BUCK5) + return 0; + + switch (mode) { + case REGULATOR_MODE_IDLE: /* ON in LP Mode */ + val = 0x2 << MAX77686_OPMODE_SHIFT; + break; + case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ + val = 0x3 << MAX77686_OPMODE_SHIFT; + break; + default: + pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", + rdev->desc->name, mode); + return -EINVAL; + } + + max77686->opmode[rdev->desc->id] = val; + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, + val); +} + +/* Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state */ +static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + unsigned int val; + struct max77686_data *max77686 = rdev_get_drvdata(rdev); + + switch (mode) { + case REGULATOR_MODE_STANDBY: /* switch off */ + val = 0x1 << MAX77686_OPMODE_SHIFT; + break; + case REGULATOR_MODE_IDLE: /* ON in LP Mode */ + val = 0x2 << MAX77686_OPMODE_SHIFT; + break; + case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ + val = 0x3 << MAX77686_OPMODE_SHIFT; + break; + default: + pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", + rdev->desc->name, mode); + return -EINVAL; + } + + max77686->opmode[rdev->desc->id] = val; + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, + val); +} + int max77686_enable(struct regulator_dev *rdev) { struct max77686_data *max77686 = rdev_get_drvdata(rdev); @@ -113,6 +189,31 @@ static struct regulator_ops max77686_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_suspend_mode = max77686_set_suspend_mode, +}; + +static struct regulator_ops max77686_ldo_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = max77686_enable, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_suspend_mode = max77686_ldo_set_suspend_mode, +}; + +static struct regulator_ops max77686_buck1_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = max77686_enable, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_suspend_disable = max77686_buck_set_suspend_disable, }; static struct regulator_ops max77686_buck_dvs_ops = { @@ -125,6 +226,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .set_voltage_time_sel = regulator_set_voltage_time_sel, .set_ramp_delay = max77686_set_ramp_delay, + .set_suspend_disable = max77686_buck_set_suspend_disable, }; #define regulator_desc_ldo(num) { \ @@ -143,9 +245,41 @@ static struct regulator_ops max77686_buck_dvs_ops = { .enable_mask = MAX77686_OPMODE_MASK \ << MAX77686_OPMODE_SHIFT, \ } +#define regulator_desc_lpm_ldo(num) { \ + .name = "LDO"#num, \ + .id = MAX77686_LDO##num, \ + .ops = &max77686_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = MAX77686_LDO_MINUV, \ + .uV_step = MAX77686_LDO_UVSTEP, \ + .ramp_delay = MAX77686_RAMP_DELAY, \ + .n_voltages = MAX77686_VSEL_MASK + 1, \ + .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ + .vsel_mask = MAX77686_VSEL_MASK, \ + .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ + .enable_mask = MAX77686_OPMODE_MASK \ + << MAX77686_OPMODE_SHIFT, \ +} #define regulator_desc_ldo_low(num) { \ .name = "LDO"#num, \ .id = MAX77686_LDO##num, \ + .ops = &max77686_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = MAX77686_LDO_LOW_MINUV, \ + .uV_step = MAX77686_LDO_LOW_UVSTEP, \ + .ramp_delay = MAX77686_RAMP_DELAY, \ + .n_voltages = MAX77686_VSEL_MASK + 1, \ + .vsel_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ + .vsel_mask = MAX77686_VSEL_MASK, \ + .enable_reg = MAX77686_REG_LDO1CTRL1 + num - 1, \ + .enable_mask = MAX77686_OPMODE_MASK \ + << MAX77686_OPMODE_SHIFT, \ +} +#define regulator_desc_ldo1_low(num) { \ + .name = "LDO"#num, \ + .id = MAX77686_LDO##num, \ .ops = &max77686_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ @@ -177,7 +311,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { #define regulator_desc_buck1(num) { \ .name = "BUCK"#num, \ .id = MAX77686_BUCK##num, \ - .ops = &max77686_ops, \ + .ops = &max77686_buck1_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ .min_uV = MAX77686_BUCK_MINUV, \ @@ -207,7 +341,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { } static struct regulator_desc regulators[] = { - regulator_desc_ldo_low(1), + regulator_desc_ldo1_low(1), regulator_desc_ldo_low(2), regulator_desc_ldo(3), regulator_desc_ldo(4), @@ -216,13 +350,13 @@ static struct regulator_desc regulators[] = { regulator_desc_ldo_low(7), regulator_desc_ldo_low(8), regulator_desc_ldo(9), - regulator_desc_ldo(10), - regulator_desc_ldo(11), - regulator_desc_ldo(12), + regulator_desc_lpm_ldo(10), + regulator_desc_lpm_ldo(11), + regulator_desc_lpm_ldo(12), regulator_desc_ldo(13), - regulator_desc_ldo(14), + regulator_desc_lpm_ldo(14), regulator_desc_ldo_low(15), - regulator_desc_ldo(16), + regulator_desc_lpm_ldo(16), regulator_desc_ldo(17), regulator_desc_ldo(18), regulator_desc_ldo(19), -- cgit v0.10.2 From a9a5659ac61b9e21d17993a6c0fbbeb83e182526 Mon Sep 17 00:00:00 2001 From: AnilKumar Ch Date: Mon, 15 Oct 2012 17:45:58 +0530 Subject: regulator: tps65910: fix BUG_ON() shown with vrtc regulator Fix BUG_ON() error if tps65910 VRTC regulator is used with out rdev->desc->volt_table data. Recent changes in regulator core driver which add support for "regulator_list_voltage_table" have BUG_ON() if regulator descriptor do not voltage table information. This patch adds the voltage table information to fix the issue. Signed-off-by: AnilKumar Ch Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 793adda..1d2dd18 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -38,6 +38,11 @@ static const unsigned int VIO_VSEL_table[] = { /* VSEL tables for TPS65910 specific LDOs and dcdc's */ +/* supported VRTC voltages in microvolts */ +static const unsigned int VRTC_VSEL_table[] = { + 1800000, +}; + /* supported VDD3 voltages in microvolts */ static const unsigned int VDD3_VSEL_table[] = { 5000000, @@ -95,6 +100,8 @@ static struct tps_info tps65910_regs[] = { { .name = "vrtc", .vin_name = "vcc7", + .n_voltages = ARRAY_SIZE(VRTC_VSEL_table), + .voltage_table = VRTC_VSEL_table, .enable_time_us = 2200, }, { -- cgit v0.10.2 From 24282a1ca33b4a2cdfb907fb7a3ba4d0f6e93311 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 9 Oct 2012 15:18:59 +0530 Subject: regulator: tps65090: Register all regulators in single probe call MFD driver registers the regulator driver once per device and hence it is require to register all regulators in single probe call. Following are details of changes done to achieve this: - Move the regulator enums to mfd header and remove the tps65090-regulator.h as it does not contain more info. - Add max regulator and register all regulators even if there is no regulator init data from platform. - Convert regulator init data to pointer type in platform data. - Add input supply name in regulator desc to provide input supply. - Separate desc information from driver information. - Disable external control bit to have control through register write. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 001ad55..5f7f931 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -24,15 +24,11 @@ #include #include #include -#include struct tps65090_regulator { - int id; - /* used by regulator core */ - struct regulator_desc desc; - - /* Device */ struct device *dev; + struct regulator_desc *desc; + struct regulator_dev *rdev; }; static struct regulator_ops tps65090_ops = { @@ -41,44 +37,80 @@ static struct regulator_ops tps65090_ops = { .is_enabled = regulator_is_enabled_regmap, }; -#define tps65090_REG(_id) \ +#define tps65090_REG_DESC(_id, _sname, _en_reg, _ops) \ { \ - .id = TPS65090_ID_##_id, \ - .desc = { \ - .name = tps65090_rails(_id), \ - .id = TPS65090_ID_##_id, \ - .ops = &tps65090_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .enable_reg = (TPS65090_ID_##_id) + 12, \ - .enable_mask = BIT(0), \ - }, \ + .name = "TPS65090_RAILS"#_id, \ + .supply_name = _sname, \ + .id = TPS65090_ID_##_id, \ + .ops = &_ops, \ + .enable_reg = _en_reg, \ + .enable_mask = BIT(0), \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ } -static struct tps65090_regulator TPS65090_regulator[] = { - tps65090_REG(DCDC1), - tps65090_REG(DCDC2), - tps65090_REG(DCDC3), - tps65090_REG(FET1), - tps65090_REG(FET2), - tps65090_REG(FET3), - tps65090_REG(FET4), - tps65090_REG(FET5), - tps65090_REG(FET6), - tps65090_REG(FET7), +static struct regulator_desc tps65090_regulator_desc[] = { + tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, tps65090_ops), + tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, tps65090_ops), + tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, tps65090_ops), + tps65090_REG_DESC(FET1, "infet1", 0x0F, tps65090_ops), + tps65090_REG_DESC(FET2, "infet2", 0x10, tps65090_ops), + tps65090_REG_DESC(FET3, "infet3", 0x11, tps65090_ops), + tps65090_REG_DESC(FET4, "infet4", 0x12, tps65090_ops), + tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_ops), + tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_ops), + tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_ops), }; -static inline struct tps65090_regulator *find_regulator_info(int id) +static inline bool is_dcdc(int id) { - struct tps65090_regulator *ri; - int i; + switch (id) { + case TPS65090_ID_DCDC1: + case TPS65090_ID_DCDC2: + case TPS65090_ID_DCDC3: + return true; + default: + return false; + } +} - for (i = 0; i < ARRAY_SIZE(TPS65090_regulator); i++) { - ri = &TPS65090_regulator[i]; - if (ri->desc.id == id) - return ri; +static int __devinit tps65090_config_ext_control( + struct tps65090_regulator *ri, bool enable) +{ + int ret; + struct device *parent = ri->dev->parent; + unsigned int reg_en_reg = ri->desc->enable_reg; + + if (enable) + ret = tps65090_set_bits(parent, reg_en_reg, 1); + else + ret = tps65090_clr_bits(parent, reg_en_reg, 1); + if (ret < 0) + dev_err(ri->dev, "Error in updating reg 0x%x\n", reg_en_reg); + return ret; +} + +static int __devinit tps65090_regulator_disable_ext_control( + struct tps65090_regulator *ri, + struct tps65090_regulator_plat_data *tps_pdata) +{ + int ret = 0; + struct device *parent = ri->dev->parent; + unsigned int reg_en_reg = ri->desc->enable_reg; + + /* + * First enable output for internal control if require. + * And then disable external control. + */ + if (tps_pdata->reg_init_data->constraints.always_on || + tps_pdata->reg_init_data->constraints.boot_on) { + ret = tps65090_set_bits(parent, reg_en_reg, 0); + if (ret < 0) { + dev_err(ri->dev, "Error in set reg 0x%x\n", reg_en_reg); + return ret; + } } - return NULL; + return tps65090_config_ext_control(ri, false); } static int __devinit tps65090_regulator_probe(struct platform_device *pdev) @@ -87,40 +119,87 @@ static int __devinit tps65090_regulator_probe(struct platform_device *pdev) struct tps65090_regulator *ri = NULL; struct regulator_config config = { }; struct regulator_dev *rdev; - struct tps65090_regulator_platform_data *tps_pdata; - int id = pdev->id; + struct tps65090_regulator_plat_data *tps_pdata; + struct tps65090_regulator *pmic; + struct tps65090_platform_data *tps65090_pdata; + int num; + int ret; - dev_dbg(&pdev->dev, "Probing regulator %d\n", id); + dev_dbg(&pdev->dev, "Probing regulator\n"); - ri = find_regulator_info(id); - if (ri == NULL) { - dev_err(&pdev->dev, "invalid regulator ID specified\n"); + tps65090_pdata = dev_get_platdata(pdev->dev.parent); + if (!tps65090_pdata) { + dev_err(&pdev->dev, "Platform data missing\n"); return -EINVAL; } - tps_pdata = pdev->dev.platform_data; - ri->dev = &pdev->dev; - - config.dev = &pdev->dev; - config.init_data = &tps_pdata->regulator; - config.driver_data = ri; - config.regmap = tps65090_mfd->rmap; - - rdev = regulator_register(&ri->desc, &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "failed to register regulator %s\n", - ri->desc.name); - return PTR_ERR(rdev); + + pmic = devm_kzalloc(&pdev->dev, TPS65090_ID_MAX * sizeof(*pmic), + GFP_KERNEL); + if (!pmic) { + dev_err(&pdev->dev, "mem alloc for pmic failed\n"); + return -ENOMEM; + } + + for (num = 0; num < TPS65090_ID_MAX; num++) { + tps_pdata = tps65090_pdata->reg_pdata[num]; + + ri = &pmic[num]; + ri->dev = &pdev->dev; + ri->desc = &tps65090_regulator_desc[num]; + + /* + * TPS5090 DCDC support the control from external digital input. + * It may be possible that during boot, the external control is + * enabled. Disabling external control for DCDC. + */ + if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data) { + ret = tps65090_regulator_disable_ext_control( + ri, tps_pdata); + if (ret < 0) { + dev_err(&pdev->dev, + "failed disable ext control\n"); + goto scrub; + } + } + config.dev = &pdev->dev; + config.driver_data = ri; + config.regmap = tps65090_mfd->rmap; + if (tps_pdata) + config.init_data = tps_pdata->reg_init_data; + else + config.init_data = NULL; + + rdev = regulator_register(ri->desc, &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "failed to register regulator %s\n", + ri->desc->name); + ret = PTR_ERR(rdev); + goto scrub; + } + ri->rdev = rdev; } - platform_set_drvdata(pdev, rdev); + platform_set_drvdata(pdev, pmic); return 0; + +scrub: + while (--num >= 0) { + ri = &pmic[num]; + regulator_unregister(ri->rdev); + } + return ret; } static int __devexit tps65090_regulator_remove(struct platform_device *pdev) { - struct regulator_dev *rdev = platform_get_drvdata(pdev); + struct tps65090_regulator *pmic = platform_get_drvdata(pdev); + struct tps65090_regulator *ri; + int num; - regulator_unregister(rdev); + for (num = 0; num < TPS65090_ID_MAX; ++num) { + ri = &pmic[num]; + regulator_unregister(ri->rdev); + } return 0; } diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h index 6bc31d8..d06c633 100644 --- a/include/linux/mfd/tps65090.h +++ b/include/linux/mfd/tps65090.h @@ -24,6 +24,23 @@ #include +/* TPS65090 Regulator ID */ +enum { + TPS65090_ID_DCDC1, + TPS65090_ID_DCDC2, + TPS65090_ID_DCDC3, + TPS65090_ID_FET1, + TPS65090_ID_FET2, + TPS65090_ID_FET3, + TPS65090_ID_FET4, + TPS65090_ID_FET5, + TPS65090_ID_FET6, + TPS65090_ID_FET7, + + /* Last entry for maximum ID */ + TPS65090_ID_MAX, +}; + struct tps65090 { struct mutex lock; struct device *dev; @@ -41,10 +58,21 @@ struct tps65090_subdev_info { void *platform_data; }; +/* + * struct tps65090_regulator_plat_data + * + * @reg_init_data: The regulator init data. + */ + +struct tps65090_regulator_plat_data { + struct regulator_init_data *reg_init_data; +}; + struct tps65090_platform_data { int irq_base; int num_subdevs; struct tps65090_subdev_info *subdevs; + struct tps65090_regulator_plat_data *reg_pdata[TPS65090_ID_MAX]; }; /* diff --git a/include/linux/regulator/tps65090-regulator.h b/include/linux/regulator/tps65090-regulator.h deleted file mode 100644 index 0fa04b6..0000000 --- a/include/linux/regulator/tps65090-regulator.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Regulator driver interface for TI TPS65090 PMIC family - * - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. - - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __REGULATOR_TPS65090_H -#define __REGULATOR_TPS65090_H - -#include - -#define tps65090_rails(_name) "tps65090_"#_name - -enum { - TPS65090_ID_DCDC1, - TPS65090_ID_DCDC2, - TPS65090_ID_DCDC3, - TPS65090_ID_FET1, - TPS65090_ID_FET2, - TPS65090_ID_FET3, - TPS65090_ID_FET4, - TPS65090_ID_FET5, - TPS65090_ID_FET6, - TPS65090_ID_FET7, -}; - -/* - * struct tps65090_regulator_platform_data - * - * @regulator: The regulator init data. - * @slew_rate_uV_per_us: Slew rate microvolt per microsec. - */ - -struct tps65090_regulator_platform_data { - struct regulator_init_data regulator; -}; - -#endif /* __REGULATOR_TPS65090_H */ -- cgit v0.10.2 From 8620ca9f77b71a0069a6151e859b988117ef1fa5 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 9 Oct 2012 15:19:00 +0530 Subject: regulator: tps65090: rename driver name and regulator name To make the names proper and more appropriate: Rename the driver name from tps65090-regulator to tps65090-pmic. Rename the regulators from TPS65090_ID_* to TPS65090_REGULATOR_* Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 5f7f931..584a185 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -41,7 +41,7 @@ static struct regulator_ops tps65090_ops = { { \ .name = "TPS65090_RAILS"#_id, \ .supply_name = _sname, \ - .id = TPS65090_ID_##_id, \ + .id = TPS65090_REGULATOR_##_id, \ .ops = &_ops, \ .enable_reg = _en_reg, \ .enable_mask = BIT(0), \ @@ -65,9 +65,9 @@ static struct regulator_desc tps65090_regulator_desc[] = { static inline bool is_dcdc(int id) { switch (id) { - case TPS65090_ID_DCDC1: - case TPS65090_ID_DCDC2: - case TPS65090_ID_DCDC3: + case TPS65090_REGULATOR_DCDC1: + case TPS65090_REGULATOR_DCDC2: + case TPS65090_REGULATOR_DCDC3: return true; default: return false; @@ -133,14 +133,14 @@ static int __devinit tps65090_regulator_probe(struct platform_device *pdev) return -EINVAL; } - pmic = devm_kzalloc(&pdev->dev, TPS65090_ID_MAX * sizeof(*pmic), + pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic), GFP_KERNEL); if (!pmic) { dev_err(&pdev->dev, "mem alloc for pmic failed\n"); return -ENOMEM; } - for (num = 0; num < TPS65090_ID_MAX; num++) { + for (num = 0; num < TPS65090_REGULATOR_MAX; num++) { tps_pdata = tps65090_pdata->reg_pdata[num]; ri = &pmic[num]; @@ -196,7 +196,7 @@ static int __devexit tps65090_regulator_remove(struct platform_device *pdev) struct tps65090_regulator *ri; int num; - for (num = 0; num < TPS65090_ID_MAX; ++num) { + for (num = 0; num < TPS65090_REGULATOR_MAX; ++num) { ri = &pmic[num]; regulator_unregister(ri->rdev); } @@ -205,7 +205,7 @@ static int __devexit tps65090_regulator_remove(struct platform_device *pdev) static struct platform_driver tps65090_regulator_driver = { .driver = { - .name = "tps65090-regulator", + .name = "tps65090-pmic", .owner = THIS_MODULE, }, .probe = tps65090_regulator_probe, diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h index d06c633..958bf15 100644 --- a/include/linux/mfd/tps65090.h +++ b/include/linux/mfd/tps65090.h @@ -26,19 +26,19 @@ /* TPS65090 Regulator ID */ enum { - TPS65090_ID_DCDC1, - TPS65090_ID_DCDC2, - TPS65090_ID_DCDC3, - TPS65090_ID_FET1, - TPS65090_ID_FET2, - TPS65090_ID_FET3, - TPS65090_ID_FET4, - TPS65090_ID_FET5, - TPS65090_ID_FET6, - TPS65090_ID_FET7, + TPS65090_REGULATOR_DCDC1, + TPS65090_REGULATOR_DCDC2, + TPS65090_REGULATOR_DCDC3, + TPS65090_REGULATOR_FET1, + TPS65090_REGULATOR_FET2, + TPS65090_REGULATOR_FET3, + TPS65090_REGULATOR_FET4, + TPS65090_REGULATOR_FET5, + TPS65090_REGULATOR_FET6, + TPS65090_REGULATOR_FET7, /* Last entry for maximum ID */ - TPS65090_ID_MAX, + TPS65090_REGULATOR_MAX, }; struct tps65090 { @@ -72,7 +72,7 @@ struct tps65090_platform_data { int irq_base; int num_subdevs; struct tps65090_subdev_info *subdevs; - struct tps65090_regulator_plat_data *reg_pdata[TPS65090_ID_MAX]; + struct tps65090_regulator_plat_data *reg_pdata[TPS65090_REGULATOR_MAX]; }; /* -- cgit v0.10.2 From 3a81ef8c27cea5c749a45765da4e06a7af75be2b Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 9 Oct 2012 15:19:01 +0530 Subject: regulator: tps65090: Add support for LDO regulators TPS65090 supports the two LDOs, LDO1 and LDO2. These are always ON regulators. The output on these LDOs are available once the input voltage available for these LDOs. Add support for these LDOs regulators. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 584a185..0732d9b 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -37,6 +37,9 @@ static struct regulator_ops tps65090_ops = { .is_enabled = regulator_is_enabled_regmap, }; +static struct regulator_ops tps65090_ldo_ops = { +}; + #define tps65090_REG_DESC(_id, _sname, _en_reg, _ops) \ { \ .name = "TPS65090_RAILS"#_id, \ @@ -60,6 +63,8 @@ static struct regulator_desc tps65090_regulator_desc[] = { tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_ops), tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_ops), tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_ops), + tps65090_REG_DESC(LDO1, "vsys_l1", 0, tps65090_ldo_ops), + tps65090_REG_DESC(LDO2, "vsys_l2", 0, tps65090_ldo_ops), }; static inline bool is_dcdc(int id) diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h index 958bf15..5989212 100644 --- a/include/linux/mfd/tps65090.h +++ b/include/linux/mfd/tps65090.h @@ -36,6 +36,8 @@ enum { TPS65090_REGULATOR_FET5, TPS65090_REGULATOR_FET6, TPS65090_REGULATOR_FET7, + TPS65090_REGULATOR_LDO1, + TPS65090_REGULATOR_LDO2, /* Last entry for maximum ID */ TPS65090_REGULATOR_MAX, -- cgit v0.10.2 From f329b1755b475f64f0472cda1ae9602e092f6f05 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 9 Oct 2012 15:19:02 +0530 Subject: regulator: tps65090: add external control support for DCDC The TPS65090's DCDC output can also be enable/disable through the external digital input signal. Add support for enable/disable either through register access via I2C or through external control inputs. The external control inputs can be driven through GPIOs also and hence adding support for passing the GPIO number. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 0732d9b..4124138 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -31,10 +32,13 @@ struct tps65090_regulator { struct regulator_dev *rdev; }; -static struct regulator_ops tps65090_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, +static struct regulator_ops tps65090_ext_control_ops = { +}; + +static struct regulator_ops tps65090_reg_contol_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, }; static struct regulator_ops tps65090_ldo_ops = { @@ -53,16 +57,16 @@ static struct regulator_ops tps65090_ldo_ops = { } static struct regulator_desc tps65090_regulator_desc[] = { - tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, tps65090_ops), - tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, tps65090_ops), - tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, tps65090_ops), - tps65090_REG_DESC(FET1, "infet1", 0x0F, tps65090_ops), - tps65090_REG_DESC(FET2, "infet2", 0x10, tps65090_ops), - tps65090_REG_DESC(FET3, "infet3", 0x11, tps65090_ops), - tps65090_REG_DESC(FET4, "infet4", 0x12, tps65090_ops), - tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_ops), - tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_ops), - tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_ops), + tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, tps65090_reg_contol_ops), + tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, tps65090_reg_contol_ops), + tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, tps65090_reg_contol_ops), + tps65090_REG_DESC(FET1, "infet1", 0x0F, tps65090_reg_contol_ops), + tps65090_REG_DESC(FET2, "infet2", 0x10, tps65090_reg_contol_ops), + tps65090_REG_DESC(FET3, "infet3", 0x11, tps65090_reg_contol_ops), + tps65090_REG_DESC(FET4, "infet4", 0x12, tps65090_reg_contol_ops), + tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_reg_contol_ops), + tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_reg_contol_ops), + tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_reg_contol_ops), tps65090_REG_DESC(LDO1, "vsys_l1", 0, tps65090_ldo_ops), tps65090_REG_DESC(LDO2, "vsys_l2", 0, tps65090_ldo_ops), }; @@ -118,6 +122,22 @@ static int __devinit tps65090_regulator_disable_ext_control( return tps65090_config_ext_control(ri, false); } +static void __devinit tps65090_configure_regulator_config( + struct tps65090_regulator_plat_data *tps_pdata, + struct regulator_config *config) +{ + if (gpio_is_valid(tps_pdata->gpio)) { + int gpio_flag = GPIOF_OUT_INIT_LOW; + + if (tps_pdata->reg_init_data->constraints.always_on || + tps_pdata->reg_init_data->constraints.boot_on) + gpio_flag = GPIOF_OUT_INIT_HIGH; + + config->ena_gpio = tps_pdata->gpio; + config->ena_gpio_flags = gpio_flag; + } +} + static int __devinit tps65090_regulator_probe(struct platform_device *pdev) { struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent); @@ -154,18 +174,24 @@ static int __devinit tps65090_regulator_probe(struct platform_device *pdev) /* * TPS5090 DCDC support the control from external digital input. - * It may be possible that during boot, the external control is - * enabled. Disabling external control for DCDC. + * Configure it as per platform data. */ if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data) { - ret = tps65090_regulator_disable_ext_control( + if (tps_pdata->enable_ext_control) { + tps65090_configure_regulator_config( + tps_pdata, &config); + ri->desc->ops = &tps65090_ext_control_ops; + } else { + ret = tps65090_regulator_disable_ext_control( ri, tps_pdata); - if (ret < 0) { - dev_err(&pdev->dev, + if (ret < 0) { + dev_err(&pdev->dev, "failed disable ext control\n"); - goto scrub; + goto scrub; + } } } + config.dev = &pdev->dev; config.driver_data = ri; config.regmap = tps65090_mfd->rmap; @@ -182,6 +208,17 @@ static int __devinit tps65090_regulator_probe(struct platform_device *pdev) goto scrub; } ri->rdev = rdev; + + /* Enable external control if it is require */ + if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data && + tps_pdata->enable_ext_control) { + ret = tps65090_config_ext_control(ri, true); + if (ret < 0) { + /* Increment num to get unregister rdev */ + num++; + goto scrub; + } + } } platform_set_drvdata(pdev, pmic); diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h index 5989212..804e280 100644 --- a/include/linux/mfd/tps65090.h +++ b/include/linux/mfd/tps65090.h @@ -64,10 +64,15 @@ struct tps65090_subdev_info { * struct tps65090_regulator_plat_data * * @reg_init_data: The regulator init data. + * @enable_ext_control: Enable extrenal control or not. Only available for + * DCDC1, DCDC2 and DCDC3. + * @gpio: Gpio number if external control is enabled and controlled through + * gpio. */ - struct tps65090_regulator_plat_data { struct regulator_init_data *reg_init_data; + bool enable_ext_control; + int gpio; }; struct tps65090_platform_data { -- cgit v0.10.2 From 006694d099e86e5a928fb39bdea280ab42c9d59c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 15 Oct 2012 14:16:59 +0100 Subject: regulator: gpio-regulator: Allow use of GPIO controlled regulators though DT Here we provide the GPIO Regulator driver with Device Tree capability, so that when a platform is booting with DT instead of platform data we can still make full use of it. Signed-off-by: Lee Jones Reviewed-by: Stephen Warren Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt new file mode 100644 index 0000000..3703be2 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt @@ -0,0 +1,36 @@ +GPIO controlled regulators + +Required properties: +- compatible : Must be "regulator-gpio". + +Optional properties: +- gpio-enable : GPIO to use to enable/disable the regulator. +- gpios : GPIO group used to control voltage. +- states : Selection of available voltages and GPIO configs. +- 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; + + gpio-enable = <&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; + }; diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 8b5944f..e467d0a 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -28,9 +28,12 @@ #include #include #include +#include #include #include #include +#include +#include struct gpio_regulator_data { struct regulator_desc desc; @@ -129,6 +132,84 @@ 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); + 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, @@ -137,10 +218,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) { @@ -270,12 +358,18 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id regulator_gpio_of_match[] __devinitconst = { + { .compatible = "regulator-gpio", }, + {}, +}; + 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 = regulator_gpio_of_match, }, }; -- cgit v0.10.2 From 38d34035e6e8a0b23752682a279d3a61ff75450e Mon Sep 17 00:00:00 2001 From: Yadwinder Singh Brar Date: Mon, 22 Oct 2012 09:39:28 +0530 Subject: regulator: max77686: Make max77686_enable() static. This patch fixes a sparse warning. Since max77686_enable() is a callback,so it should be static. Signed-off-by: Yadwinder Singh Brar Signed-off-by: Mark Brown diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 383eb9d..c9bec16 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -146,7 +146,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, val); } -int max77686_enable(struct regulator_dev *rdev) +static int max77686_enable(struct regulator_dev *rdev) { struct max77686_data *max77686 = rdev_get_drvdata(rdev); -- cgit v0.10.2 From 7bde76726fa296defc0eafc602284a7676817348 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 1 Nov 2012 14:02:36 +0800 Subject: regulator: tps51632: Fix trivial typo for TPS51632 Kconfig help text Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index aa9e8a1..2fd5808 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -341,7 +341,7 @@ config REGULATOR_TPS51632 select REGMAP_I2C help This driver supports TPS51632 voltage regulator chip. - The TPS52632 is 3-2-1 Phase D-Cap+ Step Down Driverless Controller + The TPS51632 is 3-2-1 Phase D-Cap+ Step Down Driverless Controller with Serial VID control and DVFS. The voltage output can be configure through I2C interface or PWM interface. -- cgit v0.10.2 From 45b6f8e8fc014fe404d155a657a04b25b861001d Mon Sep 17 00:00:00 2001 From: Qing Xu Date: Wed, 7 Nov 2012 18:09:53 +0800 Subject: regulator: max8925: support dt for regulator Signed-off-by: Qing Xu Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/regulator/max8925-regulator.txt b/Documentation/devicetree/bindings/regulator/max8925-regulator.txt new file mode 100644 index 0000000..073b41d --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/max8925-regulator.txt @@ -0,0 +1,29 @@ +Max8925 Voltage regulators + +max8925 regulator device register is still handled by mfd_add_devices, not by +of_xxx, so, it is not necessary to add compatible name. Also, those reg +offset and id info is stored in mfd_cell(see max8925-core.c), as a result +there is not private properties in dts. + +node's name should match with the definition in max8925_regulator_matches +(see max8925-regulator.c) + + +Optional properties: +- Any optional property defined in bindings/regulator/regulator.txt + + +Example: + + + regulators { + SDV1 { + regulator-min-microvolt = <637500>; + regulator-max-microvolt = <1425000>; + regulator-boot-on; + regulator-always-on; + }; + + ... + ... + } diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 9bb0be3..2b54979 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #define SD1_DVM_VMIN 850000 #define SD1_DVM_VMAX 1000000 @@ -187,6 +189,34 @@ static struct regulator_ops max8925_regulator_ldo_ops = { .enable_reg = MAX8925_LDOCTL##_id, \ } +#ifdef CONFIG_OF +static struct of_regulator_match max8925_regulator_matches[] = { + { .name = "SDV1",}, + { .name = "SDV2",}, + { .name = "SDV3",}, + { .name = "LDO1",}, + { .name = "LDO2",}, + { .name = "LDO3",}, + { .name = "LDO4",}, + { .name = "LDO5",}, + { .name = "LDO6",}, + { .name = "LDO7",}, + { .name = "LDO8",}, + { .name = "LDO9",}, + { .name = "LDO10",}, + { .name = "LDO11",}, + { .name = "LDO12",}, + { .name = "LDO13",}, + { .name = "LDO14",}, + { .name = "LDO15",}, + { .name = "LDO16",}, + { .name = "LDO17",}, + { .name = "LDO18",}, + { .name = "LDO19",}, + { .name = "LDO20",}, +}; +#endif + static struct max8925_regulator_info max8925_regulator_info[] = { MAX8925_SDV(1, 637.5, 1425, 12.5), MAX8925_SDV(2, 650, 2225, 25), @@ -214,6 +244,36 @@ static struct max8925_regulator_info max8925_regulator_info[] = { MAX8925_LDO(20, 750, 3900, 50), }; +#ifdef CONFIG_OF +static int max8925_regulator_dt_init(struct platform_device *pdev, + struct max8925_regulator_info *info, + struct regulator_config *config, + int ridx) +{ + struct device_node *nproot, *np; + int rcount; + nproot = pdev->dev.parent->of_node; + if (!nproot) + return -ENODEV; + np = of_find_node_by_name(nproot, "regulators"); + if (!np) { + dev_err(&pdev->dev, "failed to find regulators node\n"); + return -ENODEV; + } + + rcount = of_regulator_match(&pdev->dev, np, + &max8925_regulator_matches[ridx], 1); + if (rcount < 0) + return -ENODEV; + config->init_data = max8925_regulator_matches[ridx].init_data; + config->of_node = max8925_regulator_matches[ridx].of_node; + + return 0; +} +#else +#define max8925_regulator_dt_init(w, x, y, z) (-1) +#endif + static int __devinit max8925_regulator_probe(struct platform_device *pdev) { struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -222,7 +282,7 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev) struct max8925_regulator_info *ri; struct resource *res; struct regulator_dev *rdev; - int i; + int i, regulator_idx; res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (!res) { @@ -231,9 +291,12 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev) } for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) { ri = &max8925_regulator_info[i]; - if (ri->vol_reg == res->start) + if (ri->vol_reg == res->start) { + regulator_idx = i; break; + } } + if (i == ARRAY_SIZE(max8925_regulator_info)) { dev_err(&pdev->dev, "Failed to find regulator %llu\n", (unsigned long long)res->start); @@ -243,9 +306,12 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev) ri->chip = chip; config.dev = &pdev->dev; - config.init_data = pdata; config.driver_data = ri; + if (max8925_regulator_dt_init(pdev, ri, &config, regulator_idx)) + if (pdata) + config.init_data = pdata; + rdev = regulator_register(&ri->desc, &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", -- cgit v0.10.2 From 560615ef8b95bb9aa4ea77ccaf3b2114dc93206f Mon Sep 17 00:00:00 2001 From: Qing Xu Date: Thu, 8 Nov 2012 10:31:32 +0800 Subject: regulator: max8925: update dt regulator binding doc remove linux specific references, enumerates all supported regulators Signed-off-by: Qing Xu Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/regulator/max8925-regulator.txt b/Documentation/devicetree/bindings/regulator/max8925-regulator.txt index 073b41d..0057695 100644 --- a/Documentation/devicetree/bindings/regulator/max8925-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/max8925-regulator.txt @@ -1,29 +1,40 @@ Max8925 Voltage regulators -max8925 regulator device register is still handled by mfd_add_devices, not by -of_xxx, so, it is not necessary to add compatible name. Also, those reg -offset and id info is stored in mfd_cell(see max8925-core.c), as a result -there is not private properties in dts. - -node's name should match with the definition in max8925_regulator_matches -(see max8925-regulator.c) - +Required nodes: +-nodes: + - SDV1 for SDV SDV1 + - SDV2 for SDV SDV2 + - SDV3 for SDV SDV3 + - LDO1 for LDO LDO1 + - LDO2 for LDO LDO2 + - LDO3 for LDO LDO3 + - LDO4 for LDO LDO4 + - LDO5 for LDO LDO5 + - LDO6 for LDO LDO6 + - LDO7 for LDO LDO7 + - LDO8 for LDO LDO8 + - LDO9 for LDO LDO9 + - LDO10 for LDO LDO10 + - LDO11 for LDO LDO11 + - LDO12 for LDO LDO12 + - LDO13 for LDO LDO13 + - LDO14 for LDO LDO14 + - LDO15 for LDO LDO15 + - LDO16 for LDO LDO16 + - LDO17 for LDO LDO17 + - LDO18 for LDO LDO18 + - LDO19 for LDO LDO19 + - LDO20 for LDO LDO20 Optional properties: - Any optional property defined in bindings/regulator/regulator.txt - Example: + SDV1 { + regulator-min-microvolt = <637500>; + regulator-max-microvolt = <1425000>; + regulator-boot-on; + regulator-always-on; + }; - regulators { - SDV1 { - regulator-min-microvolt = <637500>; - regulator-max-microvolt = <1425000>; - regulator-boot-on; - regulator-always-on; - }; - - ... - ... - } -- cgit v0.10.2 From 1a0bb679bcee5233dc5134e4f5fbf97d8caf8bbb Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Sun, 11 Nov 2012 20:42:01 +0530 Subject: regulator: tps80031: add regulator driver for tps80031 Add regulator driver for Texas Instrument TPS80031/TPS80032 device. TPS80031/ TPS80032 Fully Integrated Power Management with Power Path and Battery Charger. It has 5 configurable step-down converters, 11 general purpose LDOs, VBUS generator and digital output to control regulators. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 67d47b59..2a1554b 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -415,6 +415,15 @@ config REGULATOR_TPS65912 help This driver supports TPS65912 voltage regulator chip. +config REGULATOR_TPS80031 + tristate "TI TPS80031/TPS80032 power regualtor driver" + depends on MFD_TPS80031 + help + TPS80031/ TPS80032 Fully Integrated Power Management with Power + Path and Battery Charger. It has 5 configurable step-down + converters, 11 general purpose LDOs, VBUS generator and digital + output to control regulators. + config REGULATOR_TWL4030 bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC" depends on TWL4030_CORE diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e431eed..e588266 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o +obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c new file mode 100644 index 0000000..0484478 --- /dev/null +++ b/drivers/regulator/tps80031-regulator.c @@ -0,0 +1,789 @@ +/* + * tps80031-regulator.c -- TI TPS80031 regulator driver. + * + * Regulator driver for TITPS80031/TPS80032 Fully Integrated Power + * Management with Power Path and Battery Charger. + * + * Copyright (c) 2012, NVIDIA Corporation. + * + * Author: Laxman Dewangan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Flags for DCDC Voltage reading */ +#define DCDC_OFFSET_EN BIT(0) +#define DCDC_EXTENDED_EN BIT(1) +#define TRACK_MODE_ENABLE BIT(2) + +#define SMPS_MULTOFFSET_VIO BIT(1) +#define SMPS_MULTOFFSET_SMPS1 BIT(3) +#define SMPS_MULTOFFSET_SMPS2 BIT(4) +#define SMPS_MULTOFFSET_SMPS3 BIT(6) +#define SMPS_MULTOFFSET_SMPS4 BIT(0) + +#define SMPS_CMD_MASK 0xC0 +#define SMPS_VSEL_MASK 0x3F +#define LDO_VSEL_MASK 0x1F +#define LDO_TRACK_VSEL_MASK 0x3F + +#define MISC2_LDOUSB_IN_VSYS BIT(4) +#define MISC2_LDOUSB_IN_PMID BIT(3) +#define MISC2_LDOUSB_IN_MASK 0x18 + +#define MISC2_LDO3_SEL_VIB_VAL BIT(0) +#define MISC2_LDO3_SEL_VIB_MASK 0x1 + +#define BOOST_HW_PWR_EN BIT(5) +#define BOOST_HW_PWR_EN_MASK BIT(5) + +#define OPA_MODE_EN BIT(6) +#define OPA_MODE_EN_MASK BIT(6) + +#define USB_VBUS_CTRL_SET 0x04 +#define USB_VBUS_CTRL_CLR 0x05 +#define VBUS_DISCHRG 0x20 + +struct tps80031_regulator_info { + /* Regulator register address.*/ + u8 trans_reg; + u8 state_reg; + u8 force_reg; + u8 volt_reg; + u8 volt_id; + + /*Power request bits */ + int preq_bit; + + /* used by regulator core */ + struct regulator_desc desc; + +}; + +struct tps80031_regulator { + struct device *dev; + struct regulator_dev *rdev; + struct tps80031_regulator_info *rinfo; + + u8 device_flags; + unsigned int config_flags; + unsigned int ext_ctrl_flag; +}; + +static inline struct device *to_tps80031_dev(struct regulator_dev *rdev) +{ + return rdev_get_dev(rdev)->parent->parent; +} + +static int tps80031_reg_is_enabled(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + u8 reg_val; + int ret; + + if (ri->ext_ctrl_flag & EXT_PWR_REQ) + return true; + + ret = tps80031_read(parent, SLAVE_ID1, ri->rinfo->state_reg, ®_val); + if (ret < 0) { + dev_err(&rdev->dev, "Reg 0x%02x read failed, err = %d\n", + ri->rinfo->state_reg, ret); + return ret; + } + return ((reg_val & STATE_MASK) == STATE_ON); +} + +static int tps80031_reg_enable(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + int ret; + + if (ri->ext_ctrl_flag & EXT_PWR_REQ) + return 0; + + ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->state_reg, + STATE_ON, STATE_MASK); + if (ret < 0) { + dev_err(&rdev->dev, "Reg 0x%02x update failed, err = %d\n", + ri->rinfo->state_reg, ret); + return ret; + } + return ret; +} + +static int tps80031_reg_disable(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + int ret; + + if (ri->ext_ctrl_flag & EXT_PWR_REQ) + return 0; + + ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->state_reg, + STATE_OFF, STATE_MASK); + if (ret < 0) + dev_err(&rdev->dev, "Reg 0x%02x update failed, err = %d\n", + ri->rinfo->state_reg, ret); + return ret; +} + +/* DCDC voltages for the selector of 58 to 63 */ +static int tps80031_dcdc_voltages[4][5] = { + { 1350, 1500, 1800, 1900, 2100}, + { 1350, 1500, 1800, 1900, 2100}, + { 2084, 2315, 2778, 2932, 3241}, + { 4167, 2315, 2778, 2932, 3241}, +}; + +static int tps80031_dcdc_list_voltage(struct regulator_dev *rdev, unsigned sel) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + int volt_index = ri->device_flags & 0x3; + + if (sel == 0) + return 0; + else if (sel < 58) + return regulator_list_voltage_linear(rdev, sel - 1); + else + return tps80031_dcdc_voltages[volt_index][sel - 58] * 1000; +} + +static int tps80031_dcdc_set_voltage_sel(struct regulator_dev *rdev, + unsigned vsel) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + int ret; + u8 reg_val; + + if (ri->rinfo->force_reg) { + ret = tps80031_read(parent, ri->rinfo->volt_id, + ri->rinfo->force_reg, ®_val); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", + ri->rinfo->force_reg, ret); + return ret; + } + if (!(reg_val & SMPS_CMD_MASK)) { + ret = tps80031_update(parent, ri->rinfo->volt_id, + ri->rinfo->force_reg, vsel, SMPS_VSEL_MASK); + if (ret < 0) + dev_err(ri->dev, + "reg 0x%02x update failed, e = %d\n", + ri->rinfo->force_reg, ret); + return ret; + } + } + ret = tps80031_update(parent, ri->rinfo->volt_id, + ri->rinfo->volt_reg, vsel, SMPS_VSEL_MASK); + if (ret < 0) + dev_err(ri->dev, "reg 0x%02x update failed, e = %d\n", + ri->rinfo->volt_reg, ret); + return ret; +} + +static int tps80031_dcdc_get_voltage_sel(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + uint8_t vsel = 0; + int ret; + + if (ri->rinfo->force_reg) { + ret = tps80031_read(parent, ri->rinfo->volt_id, + ri->rinfo->force_reg, &vsel); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", + ri->rinfo->force_reg, ret); + return ret; + } + + if (!(vsel & SMPS_CMD_MASK)) + return vsel & SMPS_VSEL_MASK; + } + ret = tps80031_read(parent, ri->rinfo->volt_id, + ri->rinfo->volt_reg, &vsel); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", + ri->rinfo->volt_reg, ret); + return ret; + } + return vsel & SMPS_VSEL_MASK; +} + +static int tps80031_ldo_set_voltage_sel(struct regulator_dev *rdev, + unsigned sel) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + int ret; + + /* Check for valid setting for TPS80031 or TPS80032-ES1.0 */ + if ((ri->rinfo->desc.id == TPS80031_REGULATOR_LDO2) && + (ri->device_flags & TRACK_MODE_ENABLE)) { + unsigned nvsel = (sel) & 0x1F; + if (((tps80031_get_chip_info(parent) == TPS80031) || + ((tps80031_get_chip_info(parent) == TPS80032) && + (tps80031_get_pmu_version(parent) == 0x0))) && + ((nvsel == 0x0) || (nvsel >= 0x19 && nvsel <= 0x1F))) { + dev_err(ri->dev, + "Invalid sel %d in track mode LDO2\n", + nvsel); + return -EINVAL; + } + } + + ret = tps80031_write(parent, ri->rinfo->volt_id, + ri->rinfo->volt_reg, sel); + if (ret < 0) + dev_err(ri->dev, "Error in writing reg 0x%02x, e = %d\n", + ri->rinfo->volt_reg, ret); + return ret; +} + +static int tps80031_ldo_get_voltage_sel(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + uint8_t vsel; + int ret; + + ret = tps80031_read(parent, ri->rinfo->volt_id, + ri->rinfo->volt_reg, &vsel); + if (ret < 0) { + dev_err(ri->dev, "Error in writing the Voltage register\n"); + return ret; + } + return vsel & rdev->desc->vsel_mask; +} + +static int tps80031_ldo_list_voltage(struct regulator_dev *rdev, unsigned sel) +{ + if (sel == 0) + return 0; + else + return regulator_list_voltage_linear(rdev, sel - 1); +} + +static int tps80031_vbus_is_enabled(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + int ret = -EIO; + uint8_t ctrl1 = 0; + uint8_t ctrl3 = 0; + + ret = tps80031_read(parent, SLAVE_ID2, + TPS80031_CHARGERUSB_CTRL1, &ctrl1); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", + TPS80031_CHARGERUSB_CTRL1, ret); + return ret; + } + ret = tps80031_read(parent, SLAVE_ID2, + TPS80031_CHARGERUSB_CTRL3, &ctrl3); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", + TPS80031_CHARGERUSB_CTRL1, ret); + return ret; + } + if ((ctrl1 & OPA_MODE_EN) && (ctrl3 & BOOST_HW_PWR_EN)) + return 1; + return ret; +} + +static int tps80031_vbus_enable(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + int ret; + + ret = tps80031_set_bits(parent, SLAVE_ID2, + TPS80031_CHARGERUSB_CTRL1, OPA_MODE_EN); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", + TPS80031_CHARGERUSB_CTRL1, ret); + return ret; + } + + ret = tps80031_set_bits(parent, SLAVE_ID2, + TPS80031_CHARGERUSB_CTRL3, BOOST_HW_PWR_EN); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", + TPS80031_CHARGERUSB_CTRL3, ret); + return ret; + } + return ret; +} + +static int tps80031_vbus_disable(struct regulator_dev *rdev) +{ + struct tps80031_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps80031_dev(rdev); + int ret = 0; + + if (ri->config_flags & VBUS_DISCHRG_EN_PDN) { + ret = tps80031_write(parent, SLAVE_ID2, + USB_VBUS_CTRL_SET, VBUS_DISCHRG); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x write failed, e = %d\n", + USB_VBUS_CTRL_SET, ret); + return ret; + } + } + + ret = tps80031_clr_bits(parent, SLAVE_ID2, + TPS80031_CHARGERUSB_CTRL1, OPA_MODE_EN); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x clearbit failed, e = %d\n", + TPS80031_CHARGERUSB_CTRL1, ret); + return ret; + } + + ret = tps80031_clr_bits(parent, SLAVE_ID2, + TPS80031_CHARGERUSB_CTRL3, BOOST_HW_PWR_EN); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x clearbit failed, e = %d\n", + TPS80031_CHARGERUSB_CTRL3, ret); + return ret; + } + + mdelay(DIV_ROUND_UP(ri->rinfo->desc.enable_time, 1000)); + if (ri->config_flags & VBUS_DISCHRG_EN_PDN) { + ret = tps80031_write(parent, SLAVE_ID2, + USB_VBUS_CTRL_CLR, VBUS_DISCHRG); + if (ret < 0) { + dev_err(ri->dev, "reg 0x%02x write failed, e = %d\n", + USB_VBUS_CTRL_CLR, ret); + return ret; + } + } + return ret; +} + +static struct regulator_ops tps80031_dcdc_ops = { + .list_voltage = tps80031_dcdc_list_voltage, + .set_voltage_sel = tps80031_dcdc_set_voltage_sel, + .get_voltage_sel = tps80031_dcdc_get_voltage_sel, + .enable = tps80031_reg_enable, + .disable = tps80031_reg_disable, + .is_enabled = tps80031_reg_is_enabled, +}; + +static struct regulator_ops tps80031_ldo_ops = { + .list_voltage = tps80031_ldo_list_voltage, + .set_voltage_sel = tps80031_ldo_set_voltage_sel, + .get_voltage_sel = tps80031_ldo_get_voltage_sel, + .enable = tps80031_reg_enable, + .disable = tps80031_reg_disable, + .is_enabled = tps80031_reg_is_enabled, +}; + +static struct regulator_ops tps80031_vbus_sw_ops = { + .enable = tps80031_vbus_enable, + .disable = tps80031_vbus_disable, + .is_enabled = tps80031_vbus_is_enabled, +}; + +static struct regulator_ops tps80031_vbus_hw_ops = { +}; + +static struct regulator_ops tps80031_ext_reg_ops = { + .enable = tps80031_reg_enable, + .disable = tps80031_reg_disable, + .is_enabled = tps80031_reg_is_enabled, +}; + +/* Non-exiting default definition for some register */ +#define TPS80031_SMPS3_CFG_FORCE 0 +#define TPS80031_SMPS4_CFG_FORCE 0 + +#define TPS80031_VBUS_CFG_TRANS 0 +#define TPS80031_VBUS_CFG_STATE 0 + +#define TPS80031_REG_SMPS(_id, _volt_id, _pbit) \ +{ \ + .trans_reg = TPS80031_##_id##_CFG_TRANS, \ + .state_reg = TPS80031_##_id##_CFG_STATE, \ + .force_reg = TPS80031_##_id##_CFG_FORCE, \ + .volt_reg = TPS80031_##_id##_CFG_VOLTAGE, \ + .volt_id = SLAVE_##_volt_id, \ + .preq_bit = _pbit, \ + .desc = { \ + .name = "tps80031_"#_id, \ + .id = TPS80031_REGULATOR_##_id, \ + .n_voltages = 63, \ + .ops = &tps80031_dcdc_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .enable_time = 500, \ + }, \ +} + +#define TPS80031_REG_LDO(_id, _preq_bit) \ +{ \ + .trans_reg = TPS80031_##_id##_CFG_TRANS, \ + .state_reg = TPS80031_##_id##_CFG_STATE, \ + .volt_reg = TPS80031_##_id##_CFG_VOLTAGE, \ + .volt_id = SLAVE_ID1, \ + .preq_bit = _preq_bit, \ + .desc = { \ + .owner = THIS_MODULE, \ + .name = "tps80031_"#_id, \ + .id = TPS80031_REGULATOR_##_id, \ + .ops = &tps80031_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .min_uV = 1000000, \ + .uV_step = 100000, \ + .n_voltages = 25, \ + .vsel_mask = LDO_VSEL_MASK, \ + .enable_time = 500, \ + }, \ +} + +#define TPS80031_REG_FIXED(_id, max_mV, _ops, _delay, _pbit) \ +{ \ + .trans_reg = TPS80031_##_id##_CFG_TRANS, \ + .state_reg = TPS80031_##_id##_CFG_STATE, \ + .volt_id = SLAVE_ID1, \ + .preq_bit = _pbit, \ + .desc = { \ + .name = "tps80031_"#_id, \ + .id = TPS80031_REGULATOR_##_id, \ + .n_voltages = 2, \ + .ops = &_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .enable_time = _delay, \ + }, \ +} + +static struct tps80031_regulator_info tps80031_rinfo[TPS80031_REGULATOR_MAX] = { + TPS80031_REG_SMPS(VIO, ID0, 4), + TPS80031_REG_SMPS(SMPS1, ID0, 0), + TPS80031_REG_SMPS(SMPS2, ID0, 1), + TPS80031_REG_SMPS(SMPS3, ID1, 2), + TPS80031_REG_SMPS(SMPS4, ID1, 3), + TPS80031_REG_LDO(VANA, -1), + TPS80031_REG_LDO(LDO1, 8), + TPS80031_REG_LDO(LDO2, 9), + TPS80031_REG_LDO(LDO3, 10), + TPS80031_REG_LDO(LDO4, 11), + TPS80031_REG_LDO(LDO5, 12), + TPS80031_REG_LDO(LDO6, 13), + TPS80031_REG_LDO(LDO7, 14), + TPS80031_REG_LDO(LDOLN, 15), + TPS80031_REG_LDO(LDOUSB, 5), + TPS80031_REG_FIXED(VBUS, 5000, tps80031_vbus_hw_ops, 100000, -1), + TPS80031_REG_FIXED(REGEN1, 3300, tps80031_ext_reg_ops, 0, 16), + TPS80031_REG_FIXED(REGEN2, 3300, tps80031_ext_reg_ops, 0, 17), + TPS80031_REG_FIXED(SYSEN, 3300, tps80031_ext_reg_ops, 0, 18), +}; + +static int tps80031_power_req_config(struct device *parent, + struct tps80031_regulator *ri, + struct tps80031_regulator_platform_data *tps80031_pdata) +{ + int ret = 0; + + if (ri->rinfo->preq_bit < 0) + goto skip_pwr_req_config; + + ret = tps80031_ext_power_req_config(parent, ri->ext_ctrl_flag, + ri->rinfo->preq_bit, ri->rinfo->state_reg, + ri->rinfo->trans_reg); + if (ret < 0) { + dev_err(ri->dev, "ext powerreq config failed, err = %d\n", ret); + return ret; + } + +skip_pwr_req_config: + if (tps80031_pdata->ext_ctrl_flag & PWR_ON_ON_SLEEP) { + ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->trans_reg, + TRANS_SLEEP_ON, TRANS_SLEEP_MASK); + if (ret < 0) { + dev_err(ri->dev, "Reg 0x%02x update failed, e %d\n", + ri->rinfo->trans_reg, ret); + return ret; + } + } + return ret; +} + +static int tps80031_regulator_config(struct device *parent, + struct tps80031_regulator *ri, + struct tps80031_regulator_platform_data *tps80031_pdata) +{ + int ret = 0; + + switch (ri->rinfo->desc.id) { + case TPS80031_REGULATOR_LDOUSB: + if (ri->config_flags & + (USBLDO_INPUT_VSYS | USBLDO_INPUT_PMID)) { + unsigned val = 0; + if (ri->config_flags & USBLDO_INPUT_VSYS) + val = MISC2_LDOUSB_IN_VSYS; + else + val = MISC2_LDOUSB_IN_PMID; + + ret = tps80031_update(parent, SLAVE_ID1, + TPS80031_MISC2, val, MISC2_LDOUSB_IN_MASK); + if (ret < 0) { + dev_err(ri->dev, + "LDOUSB config failed, e= %d\n", ret); + return ret; + } + } + break; + + case TPS80031_REGULATOR_LDO3: + if (ri->config_flags & LDO3_OUTPUT_VIB) { + ret = tps80031_update(parent, SLAVE_ID1, + TPS80031_MISC2, MISC2_LDO3_SEL_VIB_VAL, + MISC2_LDO3_SEL_VIB_MASK); + if (ret < 0) { + dev_err(ri->dev, + "LDO3 config failed, e = %d\n", ret); + return ret; + } + } + break; + + case TPS80031_REGULATOR_VBUS: + /* Provide SW control Ops if VBUS is SW control */ + if (!(ri->config_flags & VBUS_SW_ONLY)) + ri->rinfo->desc.ops = &tps80031_vbus_sw_ops; + break; + default: + break; + } + + /* Configure Active state to ON, SLEEP to OFF and OFF_state to OFF */ + ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->trans_reg, + TRANS_ACTIVE_ON | TRANS_SLEEP_OFF | TRANS_OFF_OFF, + TRANS_ACTIVE_MASK | TRANS_SLEEP_MASK | TRANS_OFF_MASK); + if (ret < 0) { + dev_err(ri->dev, "trans reg update failed, e %d\n", ret); + return ret; + } + + return ret; +} + +static int check_smps_mode_mult(struct device *parent, + struct tps80031_regulator *ri) +{ + int mult_offset; + int ret; + u8 smps_offset; + u8 smps_mult; + + ret = tps80031_read(parent, SLAVE_ID1, + TPS80031_SMPS_OFFSET, &smps_offset); + if (ret < 0) { + dev_err(parent, "Error in reading smps offset register\n"); + return ret; + } + + ret = tps80031_read(parent, SLAVE_ID1, + TPS80031_SMPS_MULT, &smps_mult); + if (ret < 0) { + dev_err(parent, "Error in reading smps mult register\n"); + return ret; + } + + switch (ri->rinfo->desc.id) { + case TPS80031_REGULATOR_VIO: + mult_offset = SMPS_MULTOFFSET_VIO; + break; + case TPS80031_REGULATOR_SMPS1: + mult_offset = SMPS_MULTOFFSET_SMPS1; + break; + case TPS80031_REGULATOR_SMPS2: + mult_offset = SMPS_MULTOFFSET_SMPS2; + break; + case TPS80031_REGULATOR_SMPS3: + mult_offset = SMPS_MULTOFFSET_SMPS3; + break; + case TPS80031_REGULATOR_SMPS4: + mult_offset = SMPS_MULTOFFSET_SMPS4; + break; + case TPS80031_REGULATOR_LDO2: + ri->device_flags = smps_mult & BIT(5) ? TRACK_MODE_ENABLE : 0; + /* TRACK mode the ldo2 varies from 600mV to 1300mV */ + if (ri->device_flags & TRACK_MODE_ENABLE) { + ri->rinfo->desc.min_uV = 600000; + ri->rinfo->desc.uV_step = 12500; + ri->rinfo->desc.n_voltages = 57; + ri->rinfo->desc.vsel_mask = LDO_TRACK_VSEL_MASK; + } + return 0; + default: + return 0; + } + + ri->device_flags = (smps_offset & mult_offset) ? DCDC_OFFSET_EN : 0; + ri->device_flags |= (smps_mult & mult_offset) ? DCDC_EXTENDED_EN : 0; + switch (ri->device_flags) { + case 0: + ri->rinfo->desc.min_uV = 607700; + ri->rinfo->desc.uV_step = 12660; + break; + case DCDC_OFFSET_EN: + ri->rinfo->desc.min_uV = 700000; + ri->rinfo->desc.uV_step = 12500; + break; + case DCDC_EXTENDED_EN: + ri->rinfo->desc.min_uV = 1852000; + ri->rinfo->desc.uV_step = 38600; + break; + case DCDC_OFFSET_EN | DCDC_EXTENDED_EN: + ri->rinfo->desc.min_uV = 2161000; + ri->rinfo->desc.uV_step = 38600; + break; + } + return 0; +} + +static int __devinit tps80031_regulator_probe(struct platform_device *pdev) +{ + struct tps80031_platform_data *pdata; + struct tps80031_regulator_platform_data *tps_pdata; + struct tps80031_regulator_info *rinfo; + struct tps80031_regulator *ri; + struct tps80031_regulator *pmic; + struct regulator_dev *rdev; + struct regulator_config config = { }; + int ret; + int num; + + pdata = dev_get_platdata(pdev->dev.parent); + + if (!pdata) { + dev_err(&pdev->dev, "No platform data\n"); + return -EINVAL; + } + + pmic = devm_kzalloc(&pdev->dev, + TPS80031_REGULATOR_MAX * sizeof(*pmic), GFP_KERNEL); + if (!pmic) { + dev_err(&pdev->dev, "mem alloc for pmic failed\n"); + return -ENOMEM; + } + + for (num = 0; num < TPS80031_REGULATOR_MAX; ++num) { + tps_pdata = pdata->regulator_pdata[num]; + rinfo = &tps80031_rinfo[num]; + ri = &pmic[num]; + ri->rinfo = rinfo; + ri->dev = &pdev->dev; + + check_smps_mode_mult(pdev->dev.parent, ri); + config.dev = &pdev->dev; + config.init_data = NULL; + config.driver_data = ri; + if (tps_pdata) { + config.init_data = tps_pdata->reg_init_data; + ri->config_flags = tps_pdata->config_flags; + ri->ext_ctrl_flag = tps_pdata->ext_ctrl_flag; + ret = tps80031_regulator_config(pdev->dev.parent, + ri, tps_pdata); + if (ret < 0) { + dev_err(&pdev->dev, + "regulator config failed, e %d\n", ret); + goto fail; + } + + ret = tps80031_power_req_config(pdev->dev.parent, + ri, tps_pdata); + if (ret < 0) { + dev_err(&pdev->dev, + "pwr_req config failed, err %d\n", ret); + goto fail; + } + } + rdev = regulator_register(&ri->rinfo->desc, &config); + if (IS_ERR_OR_NULL(rdev)) { + dev_err(&pdev->dev, + "register regulator failed %s\n", + ri->rinfo->desc.name); + ret = PTR_ERR(rdev); + goto fail; + } + ri->rdev = rdev; + } + + platform_set_drvdata(pdev, pmic); + return 0; +fail: + while (--num >= 0) { + ri = &pmic[num]; + regulator_unregister(ri->rdev); + } + return ret; +} + +static int __devexit tps80031_regulator_remove(struct platform_device *pdev) +{ + struct tps80031_regulator *pmic = platform_get_drvdata(pdev); + struct tps80031_regulator *ri = NULL; + int num; + + for (num = 0; num < TPS80031_REGULATOR_MAX; ++num) { + ri = &pmic[num]; + regulator_unregister(ri->rdev); + } + return 0; +} + +static struct platform_driver tps80031_regulator_driver = { + .driver = { + .name = "tps80031-pmic", + .owner = THIS_MODULE, + }, + .probe = tps80031_regulator_probe, + .remove = __devexit_p(tps80031_regulator_remove), +}; + +static int __init tps80031_regulator_init(void) +{ + return platform_driver_register(&tps80031_regulator_driver); +} +subsys_initcall(tps80031_regulator_init); + +static void __exit tps80031_regulator_exit(void) +{ + platform_driver_unregister(&tps80031_regulator_driver); +} +module_exit(tps80031_regulator_exit); + +MODULE_ALIAS("platform:tps80031-regulator"); +MODULE_DESCRIPTION("Regulator Driver for TI TPS80031 PMIC"); +MODULE_AUTHOR("Laxman Dewangan "); +MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From dea05fe66edb4540a53ed6623794c4978315256a Mon Sep 17 00:00:00 2001 From: Frank Li Date: Mon, 12 Nov 2012 17:58:28 +0800 Subject: regulator: gpio-regulator: doc: Fix wrong key gpio-enable Wrong description in binding document. Doc use "gpio-enable", but code use "enable-gpio" In drivers/regulator/gpio-regulator.c config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0); Signed-off-by: Frank Li Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt index 3703be2..f71f808 100644 --- a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt @@ -4,7 +4,7 @@ Required properties: - compatible : Must be "regulator-gpio". Optional properties: -- gpio-enable : GPIO to use to enable/disable the regulator. +- enable-gpio : GPIO to use to enable/disable the regulator. - gpios : GPIO group used to control voltage. - states : Selection of available voltages and GPIO configs. - startup-delay-us : Startup time in microseconds. @@ -23,7 +23,7 @@ Example: regulator-max-microvolt = <2600000>; regulator-boot-on; - gpio-enable = <&gpio0 23 0x4>; + enable-gpio = <&gpio0 23 0x4>; gpios = <&gpio0 24 0x4 &gpio0 25 0x4>; states = <1800000 0x3 -- cgit v0.10.2 From f8a9f757cb425c4784b80b001c7a77c7810b499f Mon Sep 17 00:00:00 2001 From: Frank Li Date: Mon, 12 Nov 2012 17:59:52 +0800 Subject: regulator: gpio-regulator: fix can't find regulator node in dt Need initilize of_node in regulator config when register regulator, otherwise regulator driver think it is no-dt device. in regulator_dev_lookup list_for_each_entry(r, ®ulator_list, list) if (r->dev.parent && node == r->dev.of_node) return r r->dev.of_noe will be zero if miss config in cfg. Signed-off-by: Frank Li Signed-off-by: Mark Brown diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index e467d0a..faa2f71 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -303,6 +303,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; -- cgit v0.10.2 From fe1e43f7190da98b396265639845a6cc0d748aad Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 14 Nov 2012 16:47:10 +0900 Subject: regulator: core: Add regulator_is_supported_voltage_tol() If consumers wish to set voltages based on a tolerance it stands to reason that they will also want to query for support in the same manner. Signed-off-by: Mark Brown Acked-by: Liam Girdwood diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index c43cd35..49415a2 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -367,4 +367,12 @@ static inline int regulator_set_voltage_tol(struct regulator *regulator, new_uV - tol_uV, new_uV + tol_uV); } +static inline int regulator_is_supported_voltage_tol(struct regulator *regulator, + int target_uV, int tol_uV) +{ + return regulator_is_supported_voltage(regulator, + target_uV - tol_uV, + target_uV + tol_uV); +} + #endif -- cgit v0.10.2 From 216f2b9c95ac6e4f00b08df807bc4454434a9afb Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 14 Nov 2012 11:51:36 +0000 Subject: regulator: gpio-regulator: Catch 'no states property' misuse A selection of voltage or current values (AKA states) should always be specified when using a GPIO regulator. If there are no switchable states then the fixed regulators should be used instead. Signed-off-by: Lee Jones Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt index f71f808..63c6598 100644 --- a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt @@ -2,11 +2,12 @@ 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. -- states : Selection of available voltages and GPIO configs. - startup-delay-us : Startup time in microseconds. - enable-active-high : Polarity of GPIO is active high (default is low). diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index faa2f71..dc92605 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -183,6 +183,11 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) /* 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, -- cgit v0.10.2 From 64e481603ab46bcd1466fdaffca50f25bf123f83 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Thu, 18 Oct 2012 19:36:09 +0530 Subject: mfd: tps6586x: move regulator dt parsing to regulator driver Moving regulator node parsing to regulator driver in place of parsing it on mfd driver. The motivation for this change are: - MFD core driver should not depends on regulator and able to instantiate device without regulator. - The API for matching regulators are in regulator core and it is good that regulator driver only calls this API. - Regulator specific support should be in regulator driver only to ease any enhancement/modification for regulators. - The regulator driver is now registered as mfd sub device and all regulator registration is done from single probe call. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index acab3ef..05acef8 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -201,7 +201,6 @@ config MFD_TPS6586X depends on I2C=y && GENERIC_HARDIRQS select MFD_CORE select REGMAP_I2C - depends on REGULATOR help If you say yes here you get support for the TPS6586X series of Power Management chips. diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 4674643..9d67bd9 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include @@ -99,6 +97,9 @@ static struct mfd_cell tps6586x_cell[] = { .name = "tps6586x-gpio", }, { + .name = "tps6586x-pmic", + }, + { .name = "tps6586x-rtc", }, { @@ -350,80 +351,19 @@ failed: } #ifdef CONFIG_OF -static struct of_regulator_match tps6586x_matches[] = { - { .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS }, - { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, - { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, - { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, - { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 }, - { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 }, - { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 }, - { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 }, - { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 }, - { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 }, - { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 }, - { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 }, - { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 }, - { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 }, - { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC }, -}; - static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) { - const unsigned int num = ARRAY_SIZE(tps6586x_matches); struct device_node *np = client->dev.of_node; struct tps6586x_platform_data *pdata; - struct tps6586x_subdev_info *devs; - struct device_node *regs; - const char *sys_rail_name = NULL; - unsigned int count; - unsigned int i, j; - int err; - - regs = of_find_node_by_name(np, "regulators"); - if (!regs) - return NULL; - - err = of_regulator_match(&client->dev, regs, tps6586x_matches, num); - if (err < 0) { - of_node_put(regs); - return NULL; - } - - of_node_put(regs); - count = err; - - devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL); - if (!devs) - return NULL; - - for (i = 0, j = 0; i < num && j < count; i++) { - struct regulator_init_data *reg_idata; - - if (!tps6586x_matches[i].init_data) - continue; - - reg_idata = tps6586x_matches[i].init_data; - devs[j].name = "tps6586x-regulator"; - devs[j].platform_data = tps6586x_matches[i].init_data; - devs[j].id = (int)tps6586x_matches[i].driver_data; - if (devs[j].id == TPS6586X_ID_SYS) - sys_rail_name = reg_idata->constraints.name; - - if ((devs[j].id == TPS6586X_ID_LDO_5) || - (devs[j].id == TPS6586X_ID_LDO_RTC)) - reg_idata->supply_regulator = sys_rail_name; - - devs[j].of_node = tps6586x_matches[i].of_node; - j++; - } pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) + if (!pdata) { + dev_err(&client->dev, "Memory allocation failed\n"); return NULL; + } - pdata->num_subdevs = count; - pdata->subdevs = devs; + pdata->num_subdevs = 0; + pdata->subdevs = NULL; pdata->gpio_base = -1; pdata->irq_base = -1; pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller"); diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index ce1e7cb..913c903 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -17,10 +17,12 @@ #include #include #include +#include #include #include #include #include +#include #include /* supply control and voltage setting */ @@ -255,10 +257,10 @@ static inline int tps6586x_regulator_preinit(struct device *parent, 1 << ri->enable_bit[1]); } -static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev) +static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev, + int id, struct regulator_init_data *p) { struct device *parent = pdev->dev.parent; - struct regulator_init_data *p = pdev->dev.platform_data; struct tps6586x_settings *setting = p->driver_data; uint8_t reg; @@ -269,7 +271,7 @@ static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev) return 0; /* only SM0 and SM1 can have the slew rate settings */ - switch (pdev->id) { + switch (id) { case TPS6586X_ID_SM_0: reg = TPS6586X_SM0SL; break; @@ -298,54 +300,181 @@ static inline struct tps6586x_regulator *find_regulator_info(int id) return NULL; } +#ifdef CONFIG_OF +static struct of_regulator_match tps6586x_matches[] = { + { .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS }, + { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, + { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, + { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, + { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 }, + { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 }, + { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 }, + { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 }, + { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 }, + { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 }, + { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 }, + { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 }, + { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 }, + { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 }, + { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC }, +}; + +static struct tps6586x_platform_data *tps6586x_parse_regulator_dt( + struct platform_device *pdev, + struct of_regulator_match **tps6586x_reg_matches) +{ + const unsigned int num = ARRAY_SIZE(tps6586x_matches); + struct device_node *np = pdev->dev.parent->of_node; + struct device_node *regs; + const char *sys_rail = NULL; + unsigned int i; + struct tps6586x_platform_data *pdata; + int err; + + regs = of_find_node_by_name(np, "regulators"); + if (!regs) { + dev_err(&pdev->dev, "regulator node not found\n"); + return NULL; + } + + err = of_regulator_match(&pdev->dev, regs, tps6586x_matches, num); + if (err < 0) { + dev_err(&pdev->dev, "Regulator match failed, e %d\n", err); + of_node_put(regs); + return NULL; + } + + of_node_put(regs); + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dev_err(&pdev->dev, "Memory alloction failed\n"); + return NULL; + } + + for (i = 0; i < num; i++) { + int id; + if (!tps6586x_matches[i].init_data) + continue; + + pdata->reg_init_data[i] = tps6586x_matches[i].init_data; + id = (int)tps6586x_matches[i].driver_data; + if (id == TPS6586X_ID_SYS) + sys_rail = pdata->reg_init_data[i]->constraints.name; + + if ((id == TPS6586X_ID_LDO_5) || (id == TPS6586X_ID_LDO_RTC)) + pdata->reg_init_data[i]->supply_regulator = sys_rail; + } + *tps6586x_reg_matches = tps6586x_matches; + return pdata; +} +#else +static struct tps6586x_platform_data *tps6586x_parse_regulator_dt( + struct platform_device *pdev, + struct of_regulator_match **tps6586x_reg_matches) +{ + *tps6586x_reg_matches = NULL; + return NULL; +} +#endif + static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) { struct tps6586x_regulator *ri = NULL; struct regulator_config config = { }; - struct regulator_dev *rdev; - int id = pdev->id; + struct regulator_dev **rdev; + struct regulator_init_data *reg_data; + struct tps6586x_platform_data *pdata; + struct of_regulator_match *tps6586x_reg_matches = NULL; + int id; int err; dev_dbg(&pdev->dev, "Probing regulator %d\n", id); - ri = find_regulator_info(id); - if (ri == NULL) { - dev_err(&pdev->dev, "invalid regulator ID specified\n"); - return -EINVAL; - } + pdata = dev_get_platdata(pdev->dev.parent); + if ((!pdata) && (pdev->dev.parent->of_node)) + pdata = tps6586x_parse_regulator_dt(pdev, + &tps6586x_reg_matches); - err = tps6586x_regulator_preinit(pdev->dev.parent, ri); - if (err) - return err; + if (!pdata) { + dev_err(&pdev->dev, "Platform data not available, exiting\n"); + return -ENODEV; + } - config.dev = pdev->dev.parent; - config.of_node = pdev->dev.of_node; - config.init_data = pdev->dev.platform_data; - config.driver_data = ri; + rdev = devm_kzalloc(&pdev->dev, TPS6586X_ID_MAX_REGULATOR * + sizeof(*rdev), GFP_KERNEL); + if (!rdev) { + dev_err(&pdev->dev, "Mmemory alloc failed\n"); + return -ENOMEM; + } - rdev = regulator_register(&ri->desc, &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "failed to register regulator %s\n", - ri->desc.name); - return PTR_ERR(rdev); + for (id = 0; id < TPS6586X_ID_MAX_REGULATOR; ++id) { + reg_data = pdata->reg_init_data[id]; + + ri = find_regulator_info(id); + if (!ri) { + dev_err(&pdev->dev, "invalid regulator ID specified\n"); + err = -EINVAL; + goto fail; + } + + err = tps6586x_regulator_preinit(pdev->dev.parent, ri); + if (err) { + dev_err(&pdev->dev, + "regulator %d preinit failed, e %d\n", id, err); + goto fail; + } + + config.dev = pdev->dev.parent; + config.init_data = reg_data; + config.driver_data = ri; + + if (tps6586x_reg_matches) + config.of_node = tps6586x_reg_matches[id].of_node; + + rdev[id] = regulator_register(&ri->desc, &config); + if (IS_ERR(rdev[id])) { + dev_err(&pdev->dev, "failed to register regulator %s\n", + ri->desc.name); + err = PTR_ERR(rdev[id]); + goto fail; + } + + if (reg_data) { + err = tps6586x_regulator_set_slew_rate(pdev, id, + reg_data); + if (err < 0) { + dev_err(&pdev->dev, + "Slew rate config failed, e %d\n", err); + regulator_unregister(rdev[id]); + goto fail; + } + } } platform_set_drvdata(pdev, rdev); + return 0; - return tps6586x_regulator_set_slew_rate(pdev); +fail: + while (--id >= 0) + regulator_unregister(rdev[id]); + return err; } static int __devexit tps6586x_regulator_remove(struct platform_device *pdev) { - struct regulator_dev *rdev = platform_get_drvdata(pdev); + struct regulator_dev **rdev = platform_get_drvdata(pdev); + int id = TPS6586X_ID_MAX_REGULATOR; + + while (--id >= 0) + regulator_unregister(rdev[id]); - regulator_unregister(rdev); return 0; } static struct platform_driver tps6586x_regulator_driver = { .driver = { - .name = "tps6586x-regulator", + .name = "tps6586x-pmic", .owner = THIS_MODULE, }, .probe = tps6586x_regulator_probe, diff --git a/include/linux/mfd/tps6586x.h b/include/linux/mfd/tps6586x.h index 2dd1231..f8da0e1 100644 --- a/include/linux/mfd/tps6586x.h +++ b/include/linux/mfd/tps6586x.h @@ -29,6 +29,7 @@ enum { TPS6586X_ID_LDO_8, TPS6586X_ID_LDO_9, TPS6586X_ID_LDO_RTC, + TPS6586X_ID_MAX_REGULATOR, }; enum { @@ -79,6 +80,8 @@ struct tps6586x_platform_data { int gpio_base; int irq_base; bool pm_off; + + struct regulator_init_data *reg_init_data[TPS6586X_ID_MAX_REGULATOR]; }; /* -- cgit v0.10.2 From f6130be652d0b4fbf710d83a816298c007e59ed1 Mon Sep 17 00:00:00 2001 From: Ashish Jangam Date: Thu, 1 Nov 2012 13:57:56 +0530 Subject: regulator: DA9055 regulator driver This is the Regulator patch for the DA9055 PMIC and has got dependency on the DA9055 MFD core. This patch support all of the DA9055 regulators. The output voltages are fully programmable through I2C interface only. The platform data with regulation constraints is passed down from the board to the regulator. This patch is functionaly tested on SMDK6410 board. DA9055 Evaluation board was connected to the SMDK6410 board. Signed-off-by: David Dajun Chen Signed-off-by: Ashish Jangam Signed-off-by: Mark Brown diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 67d47b59..a162573 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -109,6 +109,16 @@ config REGULATOR_DA9052 This driver supports the voltage regulators of DA9052-BC and DA9053-AA/Bx PMIC. +config REGULATOR_DA9055 + tristate "Dialog Semiconductor DA9055 regulators" + depends on MFD_DA9055 + help + Say y here to support the BUCKs and LDOs regulators found on + Dialog Semiconductor DA9055 PMIC. + + This driver can also be built as a module. If so, the module + will be called da9055-regulator. + config REGULATOR_FAN53555 tristate "Fairchild FAN53555 Regulator" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e431eed..4b754e9 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o +obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c new file mode 100644 index 0000000..8994178 --- /dev/null +++ b/drivers/regulator/da9055-regulator.c @@ -0,0 +1,663 @@ +/* +* Regulator driver for DA9055 PMIC +* +* Copyright(c) 2012 Dialog Semiconductor Ltd. +* +* Author: David Dajun Chen +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define DA9055_MIN_UA 0 +#define DA9055_MAX_UA 3 + +#define DA9055_LDO_MODE_SYNC 0 +#define DA9055_LDO_MODE_SLEEP 1 + +#define DA9055_BUCK_MODE_SLEEP 1 +#define DA9055_BUCK_MODE_SYNC 2 +#define DA9055_BUCK_MODE_AUTO 3 + +/* DA9055 REGULATOR IDs */ +#define DA9055_ID_BUCK1 0 +#define DA9055_ID_BUCK2 1 +#define DA9055_ID_LDO1 2 +#define DA9055_ID_LDO2 3 +#define DA9055_ID_LDO3 4 +#define DA9055_ID_LDO4 5 +#define DA9055_ID_LDO5 6 +#define DA9055_ID_LDO6 7 + +/* DA9055 BUCK current limit */ +static const int da9055_current_limits[] = { 500000, 600000, 700000, 800000 }; + +struct da9055_conf_reg { + int reg; + int sel_mask; + int en_mask; +}; + +struct da9055_volt_reg { + int reg_a; + int reg_b; + int sl_shift; + int v_offset; + int v_mask; + int v_shift; +}; + +struct da9055_mode_reg { + int reg; + int mask; + int shift; +}; + +struct da9055_regulator_info { + struct regulator_desc reg_desc; + struct da9055_conf_reg conf; + struct da9055_volt_reg volt; + struct da9055_mode_reg mode; +}; + +struct da9055_regulator { + struct da9055 *da9055; + struct da9055_regulator_info *info; + struct regulator_dev *rdev; + enum gpio_select reg_rselect; +}; + +static unsigned int da9055_buck_get_mode(struct regulator_dev *rdev) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + int ret, mode = 0; + + ret = da9055_reg_read(regulator->da9055, info->mode.reg); + if (ret < 0) + return ret; + + switch ((ret & info->mode.mask) >> info->mode.shift) { + case DA9055_BUCK_MODE_SYNC: + mode = REGULATOR_MODE_FAST; + break; + case DA9055_BUCK_MODE_AUTO: + mode = REGULATOR_MODE_NORMAL; + break; + case DA9055_BUCK_MODE_SLEEP: + mode = REGULATOR_MODE_STANDBY; + break; + } + + return mode; +} + +static int da9055_buck_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + int val = 0; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = DA9055_BUCK_MODE_SYNC << info->mode.shift; + break; + case REGULATOR_MODE_NORMAL: + val = DA9055_BUCK_MODE_AUTO << info->mode.shift; + break; + case REGULATOR_MODE_STANDBY: + val = DA9055_BUCK_MODE_SLEEP << info->mode.shift; + break; + } + + return da9055_reg_update(regulator->da9055, info->mode.reg, + info->mode.mask, val); +} + +static unsigned int da9055_ldo_get_mode(struct regulator_dev *rdev) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + int ret; + + ret = da9055_reg_read(regulator->da9055, info->volt.reg_b); + if (ret < 0) + return ret; + + if (ret >> info->volt.sl_shift) + return REGULATOR_MODE_STANDBY; + else + return REGULATOR_MODE_NORMAL; +} + +static int da9055_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + struct da9055_volt_reg volt = info->volt; + int val = 0; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + case REGULATOR_MODE_FAST: + val = DA9055_LDO_MODE_SYNC; + break; + case REGULATOR_MODE_STANDBY: + val = DA9055_LDO_MODE_SLEEP; + break; + } + + return da9055_reg_update(regulator->da9055, volt.reg_b, + 1 << volt.sl_shift, + val << volt.sl_shift); +} + +static int da9055_buck_get_current_limit(struct regulator_dev *rdev) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + int ret; + + ret = da9055_reg_read(regulator->da9055, DA9055_REG_BUCK_LIM); + if (ret < 0) + return ret; + + ret &= info->mode.mask; + return da9055_current_limits[ret >> info->mode.shift]; +} + +static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA, + int max_uA) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + int i, val = 0; + + if (min_uA > da9055_current_limits[DA9055_MAX_UA] || + max_uA < da9055_current_limits[DA9055_MIN_UA]) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(da9055_current_limits); i++) { + if (min_uA <= da9055_current_limits[i]) { + val = i; + break; + } + } + + return da9055_reg_update(regulator->da9055, DA9055_REG_BUCK_LIM, + info->mode.mask, val << info->mode.shift); +} + +static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + struct da9055_volt_reg volt = info->volt; + int ret, sel; + + /* + * There are two voltage register set A & B for voltage ramping but + * either one of then can be active therefore we first determine + * the active register set. + */ + ret = da9055_reg_read(regulator->da9055, info->conf.reg); + if (ret < 0) + return ret; + + ret &= info->conf.sel_mask; + + /* Get the voltage for the active register set A/B */ + if (ret == DA9055_REGUALTOR_SET_A) + ret = da9055_reg_read(regulator->da9055, volt.reg_a); + else + ret = da9055_reg_read(regulator->da9055, volt.reg_b); + + if (ret < 0) + return ret; + + sel = (ret & volt.v_mask); + if (sel <= volt.v_offset) + return 0; + else + return sel; +} + +static int da9055_regulator_set_voltage_bits(struct regulator_dev *rdev, + unsigned int reg, + unsigned int selector) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + + /* Takes care of voltage range that does not start with 0 offset. */ + selector += info->volt.v_offset; + + /* Set the voltage */ + return da9055_reg_update(regulator->da9055, reg, info->volt.v_mask, + selector); + +} + +static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, + unsigned int selector) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + int ret; + + /* + * Regulator register set A/B is not selected through GPIO therefore + * we use default register set A for voltage ramping. + */ + if (regulator->reg_rselect == NO_GPIO) { + /* Select register set A */ + ret = da9055_reg_update(regulator->da9055, info->conf.reg, + info->conf.sel_mask, DA9055_SEL_REG_A); + if (ret < 0) + return ret; + + /* Set the voltage */ + return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_a, + selector); + } + + /* + * Here regulator register set A/B is selected through GPIO. + * Therefore we first determine the selected register set A/B and + * then set the desired voltage for that register set A/B. + */ + ret = da9055_reg_read(regulator->da9055, info->conf.reg); + if (ret < 0) + return ret; + + ret &= info->conf.sel_mask; + + /* Set the voltage */ + if (ret == DA9055_REGUALTOR_SET_A) + return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_a, + selector); + else + return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_b, + selector); +} + +static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev, + int uV) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + int ret; + + /* Select register set B for suspend voltage ramping. */ + if (regulator->reg_rselect == NO_GPIO) { + ret = da9055_reg_update(regulator->da9055, info->conf.reg, + info->conf.sel_mask, DA9055_SEL_REG_B); + if (ret < 0) + return ret; + } + + ret = regulator_map_voltage_linear(rdev, uV, uV); + if (ret < 0) + return ret; + + return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_b, ret); +} + +static int da9055_suspend_enable(struct regulator_dev *rdev) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + + /* Select register set B for voltage ramping. */ + if (regulator->reg_rselect == NO_GPIO) + return da9055_reg_update(regulator->da9055, info->conf.reg, + info->conf.sel_mask, DA9055_SEL_REG_B); + else + return 0; +} + +static int da9055_suspend_disable(struct regulator_dev *rdev) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + + /* Diselect register set B. */ + if (regulator->reg_rselect == NO_GPIO) + return da9055_reg_update(regulator->da9055, info->conf.reg, + info->conf.sel_mask, DA9055_SEL_REG_A); + else + return 0; +} + +static struct regulator_ops da9055_buck_ops = { + .get_mode = da9055_buck_get_mode, + .set_mode = da9055_buck_set_mode, + + .get_current_limit = da9055_buck_get_current_limit, + .set_current_limit = da9055_buck_set_current_limit, + + .get_voltage_sel = da9055_regulator_get_voltage_sel, + .set_voltage_sel = da9055_regulator_set_voltage_sel, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + + .set_suspend_voltage = da9055_regulator_set_suspend_voltage, + .set_suspend_enable = da9055_suspend_enable, + .set_suspend_disable = da9055_suspend_disable, + .set_suspend_mode = da9055_buck_set_mode, +}; + +static struct regulator_ops da9055_ldo_ops = { + .get_mode = da9055_ldo_get_mode, + .set_mode = da9055_ldo_set_mode, + + .get_voltage_sel = da9055_regulator_get_voltage_sel, + .set_voltage_sel = da9055_regulator_set_voltage_sel, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + + .set_suspend_voltage = da9055_regulator_set_suspend_voltage, + .set_suspend_enable = da9055_suspend_enable, + .set_suspend_disable = da9055_suspend_disable, + .set_suspend_mode = da9055_ldo_set_mode, + +}; + +#define DA9055_LDO(_id, step, min, max, vbits, voffset) \ +{\ + .reg_desc = {\ + .name = #_id,\ + .ops = &da9055_ldo_ops,\ + .type = REGULATOR_VOLTAGE,\ + .id = DA9055_ID_##_id,\ + .n_voltages = (max - min) / step + 1, \ + .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ + .enable_mask = 1, \ + .min_uV = (min) * 1000,\ + .uV_step = (step) * 1000,\ + .owner = THIS_MODULE,\ + },\ + .conf = {\ + .reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ + .sel_mask = (1 << 4),\ + .en_mask = 1,\ + },\ + .volt = {\ + .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \ + .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \ + .sl_shift = 7,\ + .v_offset = (voffset),\ + .v_mask = (1 << (vbits)) - 1,\ + .v_shift = (vbits),\ + },\ +} + +#define DA9055_BUCK(_id, step, min, max, vbits, voffset, mbits, sbits) \ +{\ + .reg_desc = {\ + .name = #_id,\ + .ops = &da9055_buck_ops,\ + .type = REGULATOR_VOLTAGE,\ + .id = DA9055_ID_##_id,\ + .n_voltages = (max - min) / step + 1, \ + .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ + .enable_mask = 1,\ + .min_uV = (min) * 1000,\ + .uV_step = (step) * 1000,\ + .owner = THIS_MODULE,\ + },\ + .conf = {\ + .reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ + .sel_mask = (1 << 4),\ + .en_mask = 1,\ + },\ + .volt = {\ + .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \ + .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \ + .sl_shift = 7,\ + .v_offset = (voffset),\ + .v_mask = (1 << (vbits)) - 1,\ + .v_shift = (vbits),\ + },\ + .mode = {\ + .reg = DA9055_REG_BCORE_MODE,\ + .mask = (mbits),\ + .shift = (sbits),\ + },\ +} + +static struct da9055_regulator_info da9055_regulator_info[] = { + DA9055_BUCK(BUCK1, 25, 725, 2075, 6, 9, 0xc, 2), + DA9055_BUCK(BUCK2, 25, 925, 2500, 6, 0, 3, 0), + DA9055_LDO(LDO1, 50, 900, 3300, 6, 2), + DA9055_LDO(LDO2, 50, 900, 3300, 6, 3), + DA9055_LDO(LDO3, 50, 900, 3300, 6, 2), + DA9055_LDO(LDO4, 50, 900, 3300, 6, 2), + DA9055_LDO(LDO5, 50, 900, 2750, 6, 2), + DA9055_LDO(LDO6, 20, 900, 3300, 7, 0), +}; + +/* + * Configures regulator to be controlled either through GPIO 1 or 2. + * GPIO can control regulator state and/or select the regulator register + * set A/B for voltage ramping. + */ +static __devinit int da9055_gpio_init(struct da9055_regulator *regulator, + struct regulator_config *config, + struct da9055_pdata *pdata, int id) +{ + struct da9055_regulator_info *info = regulator->info; + int ret = 0; + + if (pdata->gpio_ren && pdata->gpio_ren[id]) { + char name[18]; + int gpio_mux = pdata->gpio_ren[id]; + + config->ena_gpio = pdata->ena_gpio[id]; + config->ena_gpio_flags = GPIOF_OUT_INIT_HIGH; + config->ena_gpio_invert = 1; + + /* + * GPI pin is muxed with regulator to control the + * regulator state. + */ + sprintf(name, "DA9055 GPI %d", gpio_mux); + ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN, + name); + if (ret < 0) + goto err; + + /* + * Let the regulator know that its state is controlled + * through GPI. + */ + ret = da9055_reg_update(regulator->da9055, info->conf.reg, + DA9055_E_GPI_MASK, + pdata->reg_ren[id] + << DA9055_E_GPI_SHIFT); + if (ret < 0) + goto err; + } + + if (pdata->gpio_rsel && pdata->gpio_ren[id]) { + char name[18]; + int gpio_mux = pdata->gpio_rsel[id]; + + regulator->reg_rselect = pdata->reg_rsel[id]; + + /* + * GPI pin is muxed with regulator to select the + * regulator register set A/B for voltage ramping. + */ + sprintf(name, "DA9055 GPI %d", gpio_mux); + ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN, + name); + if (ret < 0) + goto err; + + /* + * Let the regulator know that its register set A/B + * will be selected through GPI for voltage ramping. + */ + ret = da9055_reg_update(regulator->da9055, info->conf.reg, + DA9055_V_GPI_MASK, + pdata->reg_rsel[id] + << DA9055_V_GPI_SHIFT); + } + +err: + return ret; +} + +static irqreturn_t da9055_ldo5_6_oc_irq(int irq, void *data) +{ + struct da9055_regulator *regulator = data; + + regulator_notifier_call_chain(regulator->rdev, + REGULATOR_EVENT_OVER_CURRENT, NULL); + + return IRQ_HANDLED; +} + +static inline struct da9055_regulator_info *find_regulator_info(int id) +{ + struct da9055_regulator_info *info; + int i; + + for (i = 0; i < ARRAY_SIZE(da9055_regulator_info); i++) { + info = &da9055_regulator_info[i]; + if (info->reg_desc.id == id) + return info; + } + + return NULL; +} + +static int __devinit da9055_regulator_probe(struct platform_device *pdev) +{ + struct regulator_config config = { }; + struct da9055_regulator *regulator; + struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent); + struct da9055_pdata *pdata = da9055->dev->platform_data; + int ret, irq; + + if (pdata == NULL || pdata->regulators[pdev->id] == NULL) + return -ENODEV; + + regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9055_regulator), + GFP_KERNEL); + if (!regulator) + return -ENOMEM; + + regulator->info = find_regulator_info(pdev->id); + if (regulator->info == NULL) { + dev_err(&pdev->dev, "invalid regulator ID specified\n"); + return -EINVAL; + } + + regulator->da9055 = da9055; + config.dev = &pdev->dev; + config.driver_data = regulator; + config.regmap = da9055->regmap; + + if (pdata && pdata->regulators) + config.init_data = pdata->regulators[pdev->id]; + + ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); + if (ret < 0) + return ret; + + regulator->rdev = regulator_register(®ulator->info->reg_desc, + &config); + if (IS_ERR(regulator->rdev)) { + dev_err(&pdev->dev, "Failed to register regulator %s\n", + regulator->info->reg_desc.name); + ret = PTR_ERR(regulator->rdev); + return ret; + } + + /* Only LDO 5 and 6 has got the over current interrupt */ + if (pdev->id == DA9055_ID_LDO5 || pdev->id == DA9055_ID_LDO6) { + irq = platform_get_irq_byname(pdev, "REGULATOR"); + irq = regmap_irq_get_virq(da9055->irq_data, irq); + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, + da9055_ldo5_6_oc_irq, + IRQF_TRIGGER_HIGH | + IRQF_ONESHOT | + IRQF_PROBE_SHARED, + pdev->name, regulator); + if (ret != 0) { + if (ret != -EBUSY) { + dev_err(&pdev->dev, + "Failed to request Regulator IRQ %d: %d\n", + irq, ret); + goto err_regulator; + } + } + } + + platform_set_drvdata(pdev, regulator); + + return 0; + +err_regulator: + regulator_unregister(regulator->rdev); + return ret; +} + +static int __devexit da9055_regulator_remove(struct platform_device *pdev) +{ + struct da9055_regulator *regulator = platform_get_drvdata(pdev); + + regulator_unregister(regulator->rdev); + + return 0; +} + +static struct platform_driver da9055_regulator_driver = { + .probe = da9055_regulator_probe, + .remove = __devexit_p(da9055_regulator_remove), + .driver = { + .name = "da9055-regulator", + .owner = THIS_MODULE, + }, +}; + +static int __init da9055_regulator_init(void) +{ + return platform_driver_register(&da9055_regulator_driver); +} +subsys_initcall(da9055_regulator_init); + +static void __exit da9055_regulator_exit(void) +{ + platform_driver_unregister(&da9055_regulator_driver); +} +module_exit(da9055_regulator_exit); + +MODULE_AUTHOR("David Dajun Chen "); +MODULE_DESCRIPTION("Power Regulator driver for Dialog DA9055 PMIC"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:da9055-regulator"); diff --git a/include/linux/mfd/da9055/pdata.h b/include/linux/mfd/da9055/pdata.h index 147293b..f87a6c1 100644 --- a/include/linux/mfd/da9055/pdata.h +++ b/include/linux/mfd/da9055/pdata.h @@ -25,8 +25,29 @@ struct da9055_pdata { int gpio_base; struct regulator_init_data *regulators[DA9055_MAX_REGULATORS]; - bool reset_enable; /* Enable RTC in RESET Mode */ - enum gpio_select *gpio_rsel; /* Select regulator set thru GPIO 1/2 */ - enum gpio_select *gpio_ren; /* Enable regulator thru GPIO 1/2 */ + /* Enable RTC in RESET Mode */ + bool reset_enable; + /* + * GPI muxed pin to control + * regulator state A/B, 0 if not available. + */ + int *gpio_ren; + /* + * GPI muxed pin to control + * regulator set, 0 if not available. + */ + int *gpio_rsel; + /* + * Regulator mode control bits value (GPI offset) that + * that controls the regulator state, 0 if not available. + */ + enum gpio_select *reg_ren; + /* + * Regulator mode control bits value (GPI offset) that + * controls the regulator set A/B, 0 if not available. + */ + enum gpio_select *reg_rsel; + /* GPIOs to enable regulator, 0 if not available */ + int *ena_gpio; }; #endif /* __DA9055_PDATA_H */ -- cgit v0.10.2 From b92f787d1479ffbf6350114a7353e2fd32cafc41 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 14 Nov 2012 21:09:29 +0530 Subject: regulator: tps80031: add prefix TPS80031 on common defines. Pefix "TPS80031" is added on all defines of tps80031 header to avoid conflict with other header definitions. Update the regualtor driver of tps80031 to use the same name. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index 0484478..a37ede8 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -105,16 +105,17 @@ static int tps80031_reg_is_enabled(struct regulator_dev *rdev) u8 reg_val; int ret; - if (ri->ext_ctrl_flag & EXT_PWR_REQ) + if (ri->ext_ctrl_flag & TPS80031_EXT_PWR_REQ) return true; - ret = tps80031_read(parent, SLAVE_ID1, ri->rinfo->state_reg, ®_val); + ret = tps80031_read(parent, TPS80031_SLAVE_ID1, ri->rinfo->state_reg, + ®_val); if (ret < 0) { dev_err(&rdev->dev, "Reg 0x%02x read failed, err = %d\n", ri->rinfo->state_reg, ret); return ret; } - return ((reg_val & STATE_MASK) == STATE_ON); + return ((reg_val & TPS80031_STATE_MASK) == TPS80031_STATE_ON); } static int tps80031_reg_enable(struct regulator_dev *rdev) @@ -123,11 +124,11 @@ static int tps80031_reg_enable(struct regulator_dev *rdev) struct device *parent = to_tps80031_dev(rdev); int ret; - if (ri->ext_ctrl_flag & EXT_PWR_REQ) + if (ri->ext_ctrl_flag & TPS80031_EXT_PWR_REQ) return 0; - ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->state_reg, - STATE_ON, STATE_MASK); + ret = tps80031_update(parent, TPS80031_SLAVE_ID1, ri->rinfo->state_reg, + TPS80031_STATE_ON, TPS80031_STATE_MASK); if (ret < 0) { dev_err(&rdev->dev, "Reg 0x%02x update failed, err = %d\n", ri->rinfo->state_reg, ret); @@ -142,11 +143,11 @@ static int tps80031_reg_disable(struct regulator_dev *rdev) struct device *parent = to_tps80031_dev(rdev); int ret; - if (ri->ext_ctrl_flag & EXT_PWR_REQ) + if (ri->ext_ctrl_flag & TPS80031_EXT_PWR_REQ) return 0; - ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->state_reg, - STATE_OFF, STATE_MASK); + ret = tps80031_update(parent, TPS80031_SLAVE_ID1, ri->rinfo->state_reg, + TPS80031_STATE_OFF, TPS80031_STATE_MASK); if (ret < 0) dev_err(&rdev->dev, "Reg 0x%02x update failed, err = %d\n", ri->rinfo->state_reg, ret); @@ -299,14 +300,14 @@ static int tps80031_vbus_is_enabled(struct regulator_dev *rdev) uint8_t ctrl1 = 0; uint8_t ctrl3 = 0; - ret = tps80031_read(parent, SLAVE_ID2, + ret = tps80031_read(parent, TPS80031_SLAVE_ID2, TPS80031_CHARGERUSB_CTRL1, &ctrl1); if (ret < 0) { dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", TPS80031_CHARGERUSB_CTRL1, ret); return ret; } - ret = tps80031_read(parent, SLAVE_ID2, + ret = tps80031_read(parent, TPS80031_SLAVE_ID2, TPS80031_CHARGERUSB_CTRL3, &ctrl3); if (ret < 0) { dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", @@ -324,7 +325,7 @@ static int tps80031_vbus_enable(struct regulator_dev *rdev) struct device *parent = to_tps80031_dev(rdev); int ret; - ret = tps80031_set_bits(parent, SLAVE_ID2, + ret = tps80031_set_bits(parent, TPS80031_SLAVE_ID2, TPS80031_CHARGERUSB_CTRL1, OPA_MODE_EN); if (ret < 0) { dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", @@ -332,7 +333,7 @@ static int tps80031_vbus_enable(struct regulator_dev *rdev) return ret; } - ret = tps80031_set_bits(parent, SLAVE_ID2, + ret = tps80031_set_bits(parent, TPS80031_SLAVE_ID2, TPS80031_CHARGERUSB_CTRL3, BOOST_HW_PWR_EN); if (ret < 0) { dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", @@ -348,8 +349,8 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev) struct device *parent = to_tps80031_dev(rdev); int ret = 0; - if (ri->config_flags & VBUS_DISCHRG_EN_PDN) { - ret = tps80031_write(parent, SLAVE_ID2, + if (ri->config_flags & TPS80031_VBUS_DISCHRG_EN_PDN) { + ret = tps80031_write(parent, TPS80031_SLAVE_ID2, USB_VBUS_CTRL_SET, VBUS_DISCHRG); if (ret < 0) { dev_err(ri->dev, "reg 0x%02x write failed, e = %d\n", @@ -358,7 +359,7 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev) } } - ret = tps80031_clr_bits(parent, SLAVE_ID2, + ret = tps80031_clr_bits(parent, TPS80031_SLAVE_ID2, TPS80031_CHARGERUSB_CTRL1, OPA_MODE_EN); if (ret < 0) { dev_err(ri->dev, "reg 0x%02x clearbit failed, e = %d\n", @@ -366,7 +367,7 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev) return ret; } - ret = tps80031_clr_bits(parent, SLAVE_ID2, + ret = tps80031_clr_bits(parent, TPS80031_SLAVE_ID2, TPS80031_CHARGERUSB_CTRL3, BOOST_HW_PWR_EN); if (ret < 0) { dev_err(ri->dev, "reg 0x%02x clearbit failed, e = %d\n", @@ -375,8 +376,8 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev) } mdelay(DIV_ROUND_UP(ri->rinfo->desc.enable_time, 1000)); - if (ri->config_flags & VBUS_DISCHRG_EN_PDN) { - ret = tps80031_write(parent, SLAVE_ID2, + if (ri->config_flags & TPS80031_VBUS_DISCHRG_EN_PDN) { + ret = tps80031_write(parent, TPS80031_SLAVE_ID2, USB_VBUS_CTRL_CLR, VBUS_DISCHRG); if (ret < 0) { dev_err(ri->dev, "reg 0x%02x write failed, e = %d\n", @@ -433,7 +434,7 @@ static struct regulator_ops tps80031_ext_reg_ops = { .state_reg = TPS80031_##_id##_CFG_STATE, \ .force_reg = TPS80031_##_id##_CFG_FORCE, \ .volt_reg = TPS80031_##_id##_CFG_VOLTAGE, \ - .volt_id = SLAVE_##_volt_id, \ + .volt_id = TPS80031_SLAVE_##_volt_id, \ .preq_bit = _pbit, \ .desc = { \ .name = "tps80031_"#_id, \ @@ -451,7 +452,7 @@ static struct regulator_ops tps80031_ext_reg_ops = { .trans_reg = TPS80031_##_id##_CFG_TRANS, \ .state_reg = TPS80031_##_id##_CFG_STATE, \ .volt_reg = TPS80031_##_id##_CFG_VOLTAGE, \ - .volt_id = SLAVE_ID1, \ + .volt_id = TPS80031_SLAVE_ID1, \ .preq_bit = _preq_bit, \ .desc = { \ .owner = THIS_MODULE, \ @@ -471,7 +472,7 @@ static struct regulator_ops tps80031_ext_reg_ops = { { \ .trans_reg = TPS80031_##_id##_CFG_TRANS, \ .state_reg = TPS80031_##_id##_CFG_STATE, \ - .volt_id = SLAVE_ID1, \ + .volt_id = TPS80031_SLAVE_ID1, \ .preq_bit = _pbit, \ .desc = { \ .name = "tps80031_"#_id, \ @@ -524,9 +525,10 @@ static int tps80031_power_req_config(struct device *parent, } skip_pwr_req_config: - if (tps80031_pdata->ext_ctrl_flag & PWR_ON_ON_SLEEP) { - ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->trans_reg, - TRANS_SLEEP_ON, TRANS_SLEEP_MASK); + if (tps80031_pdata->ext_ctrl_flag & TPS80031_PWR_ON_ON_SLEEP) { + ret = tps80031_update(parent, TPS80031_SLAVE_ID1, + ri->rinfo->trans_reg, TPS80031_TRANS_SLEEP_ON, + TPS80031_TRANS_SLEEP_MASK); if (ret < 0) { dev_err(ri->dev, "Reg 0x%02x update failed, e %d\n", ri->rinfo->trans_reg, ret); @@ -544,16 +546,17 @@ static int tps80031_regulator_config(struct device *parent, switch (ri->rinfo->desc.id) { case TPS80031_REGULATOR_LDOUSB: - if (ri->config_flags & - (USBLDO_INPUT_VSYS | USBLDO_INPUT_PMID)) { + if (ri->config_flags & (TPS80031_USBLDO_INPUT_VSYS | + TPS80031_USBLDO_INPUT_PMID)) { unsigned val = 0; - if (ri->config_flags & USBLDO_INPUT_VSYS) + if (ri->config_flags & TPS80031_USBLDO_INPUT_VSYS) val = MISC2_LDOUSB_IN_VSYS; else val = MISC2_LDOUSB_IN_PMID; - ret = tps80031_update(parent, SLAVE_ID1, - TPS80031_MISC2, val, MISC2_LDOUSB_IN_MASK); + ret = tps80031_update(parent, TPS80031_SLAVE_ID1, + TPS80031_MISC2, val, + MISC2_LDOUSB_IN_MASK); if (ret < 0) { dev_err(ri->dev, "LDOUSB config failed, e= %d\n", ret); @@ -563,8 +566,8 @@ static int tps80031_regulator_config(struct device *parent, break; case TPS80031_REGULATOR_LDO3: - if (ri->config_flags & LDO3_OUTPUT_VIB) { - ret = tps80031_update(parent, SLAVE_ID1, + if (ri->config_flags & TPS80031_LDO3_OUTPUT_VIB) { + ret = tps80031_update(parent, TPS80031_SLAVE_ID1, TPS80031_MISC2, MISC2_LDO3_SEL_VIB_VAL, MISC2_LDO3_SEL_VIB_MASK); if (ret < 0) { @@ -577,7 +580,7 @@ static int tps80031_regulator_config(struct device *parent, case TPS80031_REGULATOR_VBUS: /* Provide SW control Ops if VBUS is SW control */ - if (!(ri->config_flags & VBUS_SW_ONLY)) + if (!(ri->config_flags & TPS80031_VBUS_SW_ONLY)) ri->rinfo->desc.ops = &tps80031_vbus_sw_ops; break; default: @@ -585,9 +588,10 @@ static int tps80031_regulator_config(struct device *parent, } /* Configure Active state to ON, SLEEP to OFF and OFF_state to OFF */ - ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->trans_reg, - TRANS_ACTIVE_ON | TRANS_SLEEP_OFF | TRANS_OFF_OFF, - TRANS_ACTIVE_MASK | TRANS_SLEEP_MASK | TRANS_OFF_MASK); + ret = tps80031_update(parent, TPS80031_SLAVE_ID1, ri->rinfo->trans_reg, + TPS80031_TRANS_ACTIVE_ON | TPS80031_TRANS_SLEEP_OFF | + TPS80031_TRANS_OFF_OFF, TPS80031_TRANS_ACTIVE_MASK | + TPS80031_TRANS_SLEEP_MASK | TPS80031_TRANS_OFF_MASK); if (ret < 0) { dev_err(ri->dev, "trans reg update failed, e %d\n", ret); return ret; @@ -604,14 +608,14 @@ static int check_smps_mode_mult(struct device *parent, u8 smps_offset; u8 smps_mult; - ret = tps80031_read(parent, SLAVE_ID1, + ret = tps80031_read(parent, TPS80031_SLAVE_ID1, TPS80031_SMPS_OFFSET, &smps_offset); if (ret < 0) { dev_err(parent, "Error in reading smps offset register\n"); return ret; } - ret = tps80031_read(parent, SLAVE_ID1, + ret = tps80031_read(parent, TPS80031_SLAVE_ID1, TPS80031_SMPS_MULT, &smps_mult); if (ret < 0) { dev_err(parent, "Error in reading smps mult register\n"); -- cgit v0.10.2 From 26cbd3073394b966654294c8cb9cb2fec870c567 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 16 Nov 2012 00:35:14 +0800 Subject: regulator: da9055: Fix checking wrong value in da9055_gpio_init Check pdata->gpio_rsel && pdata->gpio_rsel[id] for the case GPI pin is muxed with regulator to select the regulator register set A/B for voltage ramping. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 8994178..79c5665 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -501,7 +501,7 @@ static __devinit int da9055_gpio_init(struct da9055_regulator *regulator, goto err; } - if (pdata->gpio_rsel && pdata->gpio_ren[id]) { + if (pdata->gpio_rsel && pdata->gpio_rsel[id]) { char name[18]; int gpio_mux = pdata->gpio_rsel[id]; -- cgit v0.10.2 From 5928f5389664fffa295c39bbe23de73069124451 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Mon, 19 Nov 2012 06:58:29 +0530 Subject: regulator: max8973: add regulator driver support The MAXIM MAX8973 high-efficiency, three phase, DC-DC step-down switching regulator delievers up to 9A of output current. Each phase operates at a 2MHz fixed frequency with a 120 deg shift from the adjacent phase, allowing the use of small magnetic component. Add regulator driver for this device. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 67d47b59..2b80312 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -204,6 +204,16 @@ config REGULATOR_MAX8952 via I2C bus. Maxim 8952 has one voltage output and supports 4 DVS modes ranging from 0.77V to 1.40V by 0.01V steps. +config REGULATOR_MAX8973 + tristate "Maxim MAX8973 voltage regulator " + depends on I2C + select REGMAP_I2C + help + The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down + switching regulator delievers up to 9A of output current. Each + phase operates at a 2MHz fixed frequency with a 120 deg shift + from the adjacent phase, allowing the use of small magnetic component. + config REGULATOR_MAX8997 tristate "Maxim 8997/8966 regulator" depends on MFD_MAX8997 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e431eed..3b51e0d 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o obj-$(CONFIG_REGULATOR_MAX8907) += max8907-regulator.o obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o +obj-$(CONFIG_REGULATOR_MAX8973) += max8973-regulator.o obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c new file mode 100644 index 0000000..e6328f9 --- /dev/null +++ b/drivers/regulator/max8973-regulator.c @@ -0,0 +1,505 @@ +/* + * max8973-regulator.c -- Maxim max8973 + * + * Regulator driver for MAXIM 8973 DC-DC step-down switching regulator. + * + * Copyright (c) 2012, NVIDIA Corporation. + * + * Author: Laxman Dewangan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register definitions */ +#define MAX8973_VOUT 0x0 +#define MAX8973_VOUT_DVS 0x1 +#define MAX8973_CONTROL1 0x2 +#define MAX8973_CONTROL2 0x3 +#define MAX8973_CHIPID1 0x4 +#define MAX8973_CHIPID2 0x5 + +#define MAX8973_MAX_VOUT_REG 2 + +/* MAX8973_VOUT */ +#define MAX8973_VOUT_ENABLE BIT(7) +#define MAX8973_VOUT_MASK 0x7F + +/* MAX8973_VOUT_DVS */ +#define MAX8973_DVS_VOUT_MASK 0x7F + +/* MAX8973_CONTROL1 */ +#define MAX8973_SNS_ENABLE BIT(7) +#define MAX8973_FPWM_EN_M BIT(6) +#define MAX8973_NFSR_ENABLE BIT(5) +#define MAX8973_AD_ENABLE BIT(4) +#define MAX8973_BIAS_ENABLE BIT(3) +#define MAX8973_FREQSHIFT_9PER BIT(2) + +#define MAX8973_RAMP_12mV_PER_US 0x0 +#define MAX8973_RAMP_25mV_PER_US 0x1 +#define MAX8973_RAMP_50mV_PER_US 0x2 +#define MAX8973_RAMP_200mV_PER_US 0x3 + +/* MAX8973_CONTROL2 */ +#define MAX8973_WDTMR_ENABLE BIT(6) +#define MAX8973_DISCH_ENBABLE BIT(5) +#define MAX8973_FT_ENABLE BIT(4) + +#define MAX8973_CKKADV_TRIP_DISABLE 0xC +#define MAX8973_CKKADV_TRIP_75mV_PER_US 0x0 +#define MAX8973_CKKADV_TRIP_150mV_PER_US 0x4 +#define MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS 0x8 +#define MAX8973_CONTROL_CLKADV_TRIP_MASK 0x00030000 + +#define MAX8973_INDUCTOR_MIN_30_PER 0x0 +#define MAX8973_INDUCTOR_NOMINAL 0x1 +#define MAX8973_INDUCTOR_PLUS_30_PER 0x2 +#define MAX8973_INDUCTOR_PLUS_60_PER 0x3 +#define MAX8973_CONTROL_INDUCTOR_VALUE_MASK 0x00300000 + +#define MAX8973_MIN_VOLATGE 606250 +#define MAX8973_MAX_VOLATGE 1400000 +#define MAX8973_VOLATGE_STEP 6250 +#define MAX8973_BUCK_N_VOLTAGE 0x80 + +/* Maxim 8973 chip information */ +struct max8973_chip { + struct device *dev; + struct regulator_desc desc; + struct regulator_dev *rdev; + struct regmap *regmap; + bool enable_external_control; + int dvs_gpio; + int lru_index[MAX8973_MAX_VOUT_REG]; + int curr_vout_val[MAX8973_MAX_VOUT_REG]; + int curr_vout_reg; + int curr_gpio_val; + bool valid_dvs_gpio; +}; + +/* + * find_voltage_set_register: Find new voltage configuration register (VOUT). + * The finding of the new VOUT register will be based on the LRU mechanism. + * Each VOUT register will have different voltage configured . This + * Function will look if any of the VOUT register have requested voltage set + * or not. + * - If it is already there then it will make that register as most + * recently used and return as found so that caller need not to set + * the VOUT register but need to set the proper gpios to select this + * VOUT register. + * - If requested voltage is not found then it will use the least + * recently mechanism to get new VOUT register for new configuration + * and will return not_found so that caller need to set new VOUT + * register and then gpios (both). + */ +static bool find_voltage_set_register(struct max8973_chip *tps, + int req_vsel, int *vout_reg, int *gpio_val) +{ + int i; + bool found = false; + int new_vout_reg = tps->lru_index[MAX8973_MAX_VOUT_REG - 1]; + int found_index = MAX8973_MAX_VOUT_REG - 1; + + for (i = 0; i < MAX8973_MAX_VOUT_REG; ++i) { + if (tps->curr_vout_val[tps->lru_index[i]] == req_vsel) { + new_vout_reg = tps->lru_index[i]; + found_index = i; + found = true; + goto update_lru_index; + } + } + +update_lru_index: + for (i = found_index; i > 0; i--) + tps->lru_index[i] = tps->lru_index[i - 1]; + + tps->lru_index[0] = new_vout_reg; + *gpio_val = new_vout_reg; + *vout_reg = MAX8973_VOUT + new_vout_reg; + return found; +} + +static int max8973_dcdc_get_voltage_sel(struct regulator_dev *rdev) +{ + struct max8973_chip *max = rdev_get_drvdata(rdev); + unsigned int data; + int ret; + + ret = regmap_read(max->regmap, max->curr_vout_reg, &data); + if (ret < 0) { + dev_err(max->dev, "register %d read failed, err = %d\n", + max->curr_vout_reg, ret); + return ret; + } + return data & MAX8973_VOUT_MASK; +} + +static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev, + unsigned vsel) +{ + struct max8973_chip *max = rdev_get_drvdata(rdev); + int ret; + bool found = false; + int vout_reg = max->curr_vout_reg; + int gpio_val = max->curr_gpio_val; + + /* + * If gpios are available to select the VOUT register then least + * recently used register for new configuration. + */ + if (max->valid_dvs_gpio) + found = find_voltage_set_register(max, vsel, + &vout_reg, &gpio_val); + + if (!found) { + ret = regmap_update_bits(max->regmap, vout_reg, + MAX8973_VOUT_MASK, vsel); + if (ret < 0) { + dev_err(max->dev, "register %d update failed, err %d\n", + vout_reg, ret); + return ret; + } + max->curr_vout_reg = vout_reg; + max->curr_vout_val[gpio_val] = vsel; + } + + /* Select proper VOUT register vio gpios */ + if (max->valid_dvs_gpio) { + gpio_set_value_cansleep(max->dvs_gpio, gpio_val & 0x1); + max->curr_gpio_val = gpio_val; + } + return 0; +} + +static int max8973_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + struct max8973_chip *max = rdev_get_drvdata(rdev); + int ret; + int pwm; + + /* Enable force PWM mode in FAST mode only. */ + switch (mode) { + case REGULATOR_MODE_FAST: + pwm = MAX8973_FPWM_EN_M; + break; + + case REGULATOR_MODE_NORMAL: + pwm = 0; + break; + + default: + return -EINVAL; + } + + ret = regmap_update_bits(max->regmap, MAX8973_CONTROL1, + MAX8973_FPWM_EN_M, pwm); + if (ret < 0) + dev_err(max->dev, "register %d update failed, err %d\n", + MAX8973_CONTROL1, ret); + return ret; +} + +static unsigned int max8973_dcdc_get_mode(struct regulator_dev *rdev) +{ + struct max8973_chip *max = rdev_get_drvdata(rdev); + unsigned int data; + int ret; + + ret = regmap_read(max->regmap, MAX8973_CONTROL1, &data); + if (ret < 0) { + dev_err(max->dev, "register %d read failed, err %d\n", + MAX8973_CONTROL1, ret); + return ret; + } + return (data & MAX8973_FPWM_EN_M) ? + REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; +} + +static struct regulator_ops max8973_dcdc_ops = { + .get_voltage_sel = max8973_dcdc_get_voltage_sel, + .set_voltage_sel = max8973_dcdc_set_voltage_sel, + .list_voltage = regulator_list_voltage_linear, + .set_mode = max8973_dcdc_set_mode, + .get_mode = max8973_dcdc_get_mode, +}; + +static int __devinit max8973_init_dcdc(struct max8973_chip *max, + struct max8973_regulator_platform_data *pdata) +{ + int ret; + uint8_t control1 = 0; + uint8_t control2 = 0; + + if (pdata->control_flags & MAX8973_CONTROL_REMOTE_SENSE_ENABLE) + control1 |= MAX8973_SNS_ENABLE; + + if (!(pdata->control_flags & MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE)) + control1 |= MAX8973_NFSR_ENABLE; + + if (pdata->control_flags & MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE) + control1 |= MAX8973_AD_ENABLE; + + if (pdata->control_flags & MAX8973_CONTROL_BIAS_ENABLE) + control1 |= MAX8973_BIAS_ENABLE; + + if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE) + control1 |= MAX8973_FREQSHIFT_9PER; + + /* Set ramp delay */ + if (pdata->reg_init_data && + pdata->reg_init_data->constraints.ramp_delay) { + if (pdata->reg_init_data->constraints.ramp_delay < 25000) + control1 = MAX8973_RAMP_12mV_PER_US; + else if (pdata->reg_init_data->constraints.ramp_delay < 50000) + control1 = MAX8973_RAMP_25mV_PER_US; + else if (pdata->reg_init_data->constraints.ramp_delay < 200000) + control1 = MAX8973_RAMP_50mV_PER_US; + else + control1 = MAX8973_RAMP_200mV_PER_US; + } else { + control1 = MAX8973_RAMP_12mV_PER_US; + max->desc.ramp_delay = 12500; + } + + if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE)) + control2 |= MAX8973_DISCH_ENBABLE; + + /* Clock advance trip configuration */ + switch (pdata->control_flags & MAX8973_CONTROL_CLKADV_TRIP_MASK) { + case MAX8973_CONTROL_CLKADV_TRIP_DISABLED: + control2 |= MAX8973_CKKADV_TRIP_DISABLE; + break; + + case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US: + control2 |= MAX8973_CKKADV_TRIP_75mV_PER_US; + break; + + case MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US: + control2 |= MAX8973_CKKADV_TRIP_150mV_PER_US; + break; + + case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US_HIST_DIS: + control2 |= MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS; + break; + } + + /* Configure inductor value */ + switch (pdata->control_flags & MAX8973_CONTROL_INDUCTOR_VALUE_MASK) { + case MAX8973_CONTROL_INDUCTOR_VALUE_NOMINAL: + control2 |= MAX8973_INDUCTOR_NOMINAL; + break; + + case MAX8973_CONTROL_INDUCTOR_VALUE_MINUS_30_PER: + control2 |= MAX8973_INDUCTOR_MIN_30_PER; + break; + + case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_30_PER: + control2 |= MAX8973_INDUCTOR_PLUS_30_PER; + break; + + case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_60_PER: + control2 |= MAX8973_INDUCTOR_PLUS_60_PER; + break; + } + + ret = regmap_write(max->regmap, MAX8973_CONTROL1, control1); + if (ret < 0) { + dev_err(max->dev, "register %d write failed, err = %d", + MAX8973_CONTROL1, ret); + return ret; + } + + ret = regmap_write(max->regmap, MAX8973_CONTROL2, control2); + if (ret < 0) { + dev_err(max->dev, "register %d write failed, err = %d", + MAX8973_CONTROL2, ret); + return ret; + } + + /* If external control is enabled then disable EN bit */ + if (max->enable_external_control) { + ret = regmap_update_bits(max->regmap, MAX8973_VOUT, + MAX8973_VOUT_ENABLE, 0); + if (ret < 0) + dev_err(max->dev, "register %d update failed, err = %d", + MAX8973_VOUT, ret); + } + return ret; +} + +static const struct regmap_config max8973_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = MAX8973_CHIPID2, + .cache_type = REGCACHE_RBTREE, +}; + +static int __devinit max8973_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max8973_regulator_platform_data *pdata; + struct regulator_config config = { }; + struct regulator_dev *rdev; + struct max8973_chip *max; + int ret; + + pdata = client->dev.platform_data; + if (!pdata) { + dev_err(&client->dev, "No Platform data"); + return -EIO; + } + + max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL); + if (!max) { + dev_err(&client->dev, "Memory allocation for max failed\n"); + return -ENOMEM; + } + + max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config); + if (IS_ERR(max->regmap)) { + ret = PTR_ERR(max->regmap); + dev_err(&client->dev, "regmap init failed, err %d\n", ret); + return ret; + } + + i2c_set_clientdata(client, max); + max->dev = &client->dev; + max->desc.name = id->name; + max->desc.id = 0; + max->desc.ops = &max8973_dcdc_ops; + max->desc.type = REGULATOR_VOLTAGE; + max->desc.owner = THIS_MODULE; + max->desc.min_uV = MAX8973_MIN_VOLATGE; + max->desc.uV_step = MAX8973_VOLATGE_STEP; + max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE; + + if (pdata->enable_ext_control) { + max->desc.enable_reg = MAX8973_VOUT; + max->desc.enable_mask = MAX8973_VOUT_ENABLE; + max8973_dcdc_ops.enable = regulator_is_enabled_regmap; + max8973_dcdc_ops.disable = regulator_disable_regmap; + max8973_dcdc_ops.is_enabled = regulator_is_enabled_regmap; + } + + max->enable_external_control = pdata->enable_ext_control; + max->dvs_gpio = pdata->dvs_gpio; + max->curr_gpio_val = pdata->dvs_def_state; + max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state; + max->lru_index[0] = max->curr_vout_reg; + max->valid_dvs_gpio = false; + + if (gpio_is_valid(max->dvs_gpio)) { + int gpio_flags; + int i; + + gpio_flags = (pdata->dvs_def_state) ? + GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; + ret = devm_gpio_request_one(&client->dev, max->dvs_gpio, + gpio_flags, "max8973-dvs"); + if (ret) { + dev_err(&client->dev, + "gpio_request for gpio %d failed, err = %d\n", + max->dvs_gpio, ret); + return ret; + } + max->valid_dvs_gpio = true; + + /* + * Initialize the lru index with vout_reg id + * The index 0 will be most recently used and + * set with the max->curr_vout_reg */ + for (i = 0; i < MAX8973_MAX_VOUT_REG; ++i) + max->lru_index[i] = i; + max->lru_index[0] = max->curr_vout_reg; + max->lru_index[max->curr_vout_reg] = 0; + } + + ret = max8973_init_dcdc(max, pdata); + if (ret < 0) { + dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret); + return ret; + } + + config.dev = &client->dev; + config.init_data = pdata->reg_init_data; + config.driver_data = max; + config.of_node = client->dev.of_node; + config.regmap = max->regmap; + + /* Register the regulators */ + rdev = regulator_register(&max->desc, &config); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(max->dev, "regulator register failed, err %d\n", ret); + return ret; + } + + max->rdev = rdev; + return 0; +} + +static int __devexit max8973_remove(struct i2c_client *client) +{ + struct max8973_chip *max = i2c_get_clientdata(client); + + regulator_unregister(max->rdev); + return 0; +} + +static const struct i2c_device_id max8973_id[] = { + {.name = "max8973",}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, max8973_id); + +static struct i2c_driver max8973_i2c_driver = { + .driver = { + .name = "max8973", + .owner = THIS_MODULE, + }, + .probe = max8973_probe, + .remove = __devexit_p(max8973_remove), + .id_table = max8973_id, +}; + +static int __init max8973_init(void) +{ + return i2c_add_driver(&max8973_i2c_driver); +} +subsys_initcall(max8973_init); + +static void __exit max8973_cleanup(void) +{ + i2c_del_driver(&max8973_i2c_driver); +} +module_exit(max8973_cleanup); + +MODULE_AUTHOR("Laxman Dewangan "); +MODULE_DESCRIPTION("MAX8973 voltage regulator driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/regulator/max8973-regulator.h b/include/linux/regulator/max8973-regulator.h new file mode 100644 index 0000000..f8acc05 --- /dev/null +++ b/include/linux/regulator/max8973-regulator.h @@ -0,0 +1,72 @@ +/* + * max8973-regulator.h -- MAXIM 8973 regulator + * + * Interface for regulator driver for MAXIM 8973 DC-DC step-down + * switching regulator. + * + * Copyright (C) 2012 NVIDIA Corporation + + * Author: Laxman Dewangan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __LINUX_REGULATOR_MAX8973_H +#define __LINUX_REGULATOR_MAX8973_H + +/* + * Control flags for configuration of the device. + * Client need to pass this information with ORed + */ +#define MAX8973_CONTROL_REMOTE_SENSE_ENABLE 0x00000001 +#define MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE 0x00000002 +#define MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE 0x00000004 +#define MAX8973_CONTROL_BIAS_ENABLE 0x00000008 +#define MAX8973_CONTROL_PULL_DOWN_ENABLE 0x00000010 +#define MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE 0x00000020 + +#define MAX8973_CONTROL_CLKADV_TRIP_DISABLED 0x00000000 +#define MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US 0x00010000 +#define MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US 0x00020000 +#define MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US_HIST_DIS 0x00030000 + +#define MAX8973_CONTROL_INDUCTOR_VALUE_NOMINAL 0x00000000 +#define MAX8973_CONTROL_INDUCTOR_VALUE_MINUS_30_PER 0x00100000 +#define MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_30_PER 0x00200000 +#define MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_60_PER 0x00300000 + +/* + * struct max8973_regulator_platform_data - max8973 regulator platform data. + * + * @reg_init_data: The regulator init data. + * @control_flags: Control flags which are ORed value of above flags to + * configure device. + * @enable_ext_control: Enable the voltage enable/disable through external + * control signal from EN input pin. If it is false then + * voltage output will be enabled/disabled through EN bit of + * device register. + * @dvs_gpio: GPIO for dvs. It should be -1 if this is tied with fixed logic. + * @dvs_def_state: Default state of dvs. 1 if it is high else 0. + */ +struct max8973_regulator_platform_data { + struct regulator_init_data *reg_init_data; + unsigned long control_flags; + bool enable_ext_control; + int dvs_gpio; + unsigned dvs_def_state:1; +}; + +#endif /* __LINUX_REGULATOR_MAX8973_H */ -- cgit v0.10.2 From 5eb9f2b96381ac3fa4a5910c37213c1cb62e9c65 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:20:42 -0500 Subject: regulator: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Mark Brown diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 1c5ab01..2d798ca 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -481,7 +481,7 @@ static struct platform_driver pm8607_regulator_driver = { .owner = THIS_MODULE, }, .probe = pm8607_regulator_probe, - .remove = __devexit_p(pm8607_regulator_remove), + .remove = pm8607_regulator_remove, .id_table = pm8607_regulator_driver_ids, }; diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index 167c93f..4285b30 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c @@ -201,7 +201,7 @@ static struct platform_driver aat2870_regulator_driver = { .owner = THIS_MODULE, }, .probe = aat2870_regulator_probe, - .remove = __devexit_p(aat2870_regulator_remove), + .remove = aat2870_regulator_remove, }; static int __init aat2870_regulator_init(void) diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index df4ad89..9fae59d 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -589,7 +589,7 @@ static struct platform_driver ab3100_regulators_driver = { .owner = THIS_MODULE, }, .probe = ab3100_regulators_probe, - .remove = __devexit_p(ab3100_regulators_remove), + .remove = ab3100_regulators_remove, }; static __init int ab3100_regulators_init(void) diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index e3d1d06..987b047 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -836,7 +836,7 @@ static __devexit int ab8500_regulator_remove(struct platform_device *pdev) static struct platform_driver ab8500_regulator_driver = { .probe = ab8500_regulator_probe, - .remove = __devexit_p(ab8500_regulator_remove), + .remove = ab8500_regulator_remove, .driver = { .name = "ab8500-regulator", .owner = THIS_MODULE, diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index f123f7e..7921d01 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c @@ -266,7 +266,7 @@ static int __devexit ad5398_remove(struct i2c_client *client) static struct i2c_driver ad5398_driver = { .probe = ad5398_probe, - .remove = __devexit_p(ad5398_remove), + .remove = ad5398_remove, .driver = { .name = "ad5398", }, diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 1af9768..e8ae656 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -210,7 +210,7 @@ static struct platform_driver anatop_regulator_driver = { .of_match_table = of_anatop_regulator_match_tbl, }, .probe = anatop_regulator_probe, - .remove = __devexit_p(anatop_regulator_remove), + .remove = anatop_regulator_remove, }; static int __init anatop_regulator_init(void) diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index d184aa3..7502394 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -126,7 +126,7 @@ static __devexit int arizona_ldo1_remove(struct platform_device *pdev) static struct platform_driver arizona_ldo1_driver = { .probe = arizona_ldo1_probe, - .remove = __devexit_p(arizona_ldo1_remove), + .remove = arizona_ldo1_remove, .driver = { .name = "arizona-ldo1", .owner = THIS_MODULE, diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index d9b1f82..8c6eeba 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -177,7 +177,7 @@ static __devexit int arizona_micsupp_remove(struct platform_device *pdev) static struct platform_driver arizona_micsupp_driver = { .probe = arizona_micsupp_probe, - .remove = __devexit_p(arizona_micsupp_remove), + .remove = arizona_micsupp_remove, .driver = { .name = "arizona-micsupp", .owner = THIS_MODULE, diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index 36c5b92..43db3a5 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -513,7 +513,7 @@ static struct platform_driver da903x_regulator_driver = { .owner = THIS_MODULE, }, .probe = da903x_regulator_probe, - .remove = __devexit_p(da903x_regulator_remove), + .remove = da903x_regulator_remove, }; static int __init da903x_regulator_init(void) diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 27355b1..9caa6e6 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -440,7 +440,7 @@ static int __devexit da9052_regulator_remove(struct platform_device *pdev) static struct platform_driver da9052_regulator_driver = { .probe = da9052_regulator_probe, - .remove = __devexit_p(da9052_regulator_remove), + .remove = da9052_regulator_remove, .driver = { .name = "da9052-regulator", .owner = THIS_MODULE, diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 339f4d7..5279eff 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -311,7 +311,7 @@ static struct i2c_driver fan53555_regulator_driver = { .name = "fan53555-regulator", }, .probe = fan53555_regulator_probe, - .remove = __devexit_p(fan53555_regulator_remove), + .remove = fan53555_regulator_remove, .id_table = fan53555_id, }; diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 185468c..73a6a59 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -255,7 +255,7 @@ MODULE_DEVICE_TABLE(of, fixed_of_match); static struct platform_driver regulator_fixed_voltage_driver = { .probe = reg_fixed_voltage_probe, - .remove = __devexit_p(reg_fixed_voltage_remove), + .remove = reg_fixed_voltage_remove, .driver = { .name = "reg-fixed-voltage", .owner = THIS_MODULE, diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index dc92605..902e041 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -371,7 +371,7 @@ static const struct of_device_id regulator_gpio_of_match[] __devinitconst = { static struct platform_driver gpio_regulator_driver = { .probe = gpio_regulator_probe, - .remove = __devexit_p(gpio_regulator_remove), + .remove = gpio_regulator_remove, .driver = { .name = "gpio-regulator", .owner = THIS_MODULE, diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index d8ecf49..2c415e9 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -174,7 +174,7 @@ static struct i2c_driver isl6271a_i2c_driver = { .owner = THIS_MODULE, }, .probe = isl6271a_probe, - .remove = __devexit_p(isl6271a_remove), + .remove = isl6271a_remove, .id_table = isl6271a_id, }; diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 7c6e3b8..e10726a 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -498,7 +498,7 @@ static struct i2c_driver lp3971_i2c_driver = { .owner = THIS_MODULE, }, .probe = lp3971_i2c_probe, - .remove = __devexit_p(lp3971_i2c_remove), + .remove = lp3971_i2c_remove, .id_table = lp3971_i2c_id, }; diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c index 3cdc755..262f2d2 100644 --- a/drivers/regulator/lp3972.c +++ b/drivers/regulator/lp3972.c @@ -594,7 +594,7 @@ static struct i2c_driver lp3972_i2c_driver = { .owner = THIS_MODULE, }, .probe = lp3972_i2c_probe, - .remove = __devexit_p(lp3972_i2c_remove), + .remove = lp3972_i2c_remove, .id_table = lp3972_i2c_id, }; diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 708f4b6..622ad5e 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -914,7 +914,7 @@ static struct i2c_driver lp872x_driver = { .owner = THIS_MODULE, }, .probe = lp872x_probe, - .remove = __devexit_p(lp872x_remove), + .remove = lp872x_remove, .id_table = lp872x_ids, }; diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c index ba3e0aa..35643d2 100644 --- a/drivers/regulator/lp8788-buck.c +++ b/drivers/regulator/lp8788-buck.c @@ -554,7 +554,7 @@ static int __devexit lp8788_buck_remove(struct platform_device *pdev) static struct platform_driver lp8788_buck_driver = { .probe = lp8788_buck_probe, - .remove = __devexit_p(lp8788_buck_remove), + .remove = lp8788_buck_remove, .driver = { .name = LP8788_DEV_BUCK, .owner = THIS_MODULE, diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index 6796eeb..93399f1 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -761,7 +761,7 @@ static int __devexit lp8788_dldo_remove(struct platform_device *pdev) static struct platform_driver lp8788_dldo_driver = { .probe = lp8788_dldo_probe, - .remove = __devexit_p(lp8788_dldo_remove), + .remove = lp8788_dldo_remove, .driver = { .name = LP8788_DEV_DLDO, .owner = THIS_MODULE, @@ -817,7 +817,7 @@ static int __devexit lp8788_aldo_remove(struct platform_device *pdev) static struct platform_driver lp8788_aldo_driver = { .probe = lp8788_aldo_probe, - .remove = __devexit_p(lp8788_aldo_remove), + .remove = lp8788_aldo_remove, .driver = { .name = LP8788_DEV_ALDO, .owner = THIS_MODULE, diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index f67af3c..184a92f 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -207,7 +207,7 @@ MODULE_DEVICE_TABLE(i2c, max1586_id); static struct i2c_driver max1586_pmic_driver = { .probe = max1586_pmic_probe, - .remove = __devexit_p(max1586_pmic_remove), + .remove = max1586_pmic_remove, .driver = { .name = "max1586", .owner = THIS_MODULE, diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 2a67d08..7374f5e 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -360,7 +360,7 @@ static struct platform_driver max77686_pmic_driver = { .owner = THIS_MODULE, }, .probe = max77686_pmic_probe, - .remove = __devexit_p(max77686_pmic_remove), + .remove = max77686_pmic_remove, .id_table = max77686_pmic_id, }; diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 9d540cd..d78d4aa 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -291,7 +291,7 @@ MODULE_DEVICE_TABLE(i2c, max8649_id); static struct i2c_driver max8649_driver = { .probe = max8649_regulator_probe, - .remove = __devexit_p(max8649_regulator_remove), + .remove = max8649_regulator_remove, .driver = { .name = "max8649", }, diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 8d53174..b009a5e 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -440,7 +440,7 @@ MODULE_DEVICE_TABLE(i2c, max8660_id); static struct i2c_driver max8660_driver = { .probe = max8660_probe, - .remove = __devexit_p(max8660_remove), + .remove = max8660_remove, .driver = { .name = "max8660", .owner = THIS_MODULE, diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index af76075..882e7cb 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c @@ -385,7 +385,7 @@ static struct platform_driver max8907_regulator_driver = { .owner = THIS_MODULE, }, .probe = max8907_regulator_probe, - .remove = __devexit_p(max8907_regulator_remove), + .remove = max8907_regulator_remove, }; static int __init max8907_regulator_init(void) diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 2b54979..85d419ed 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -339,7 +339,7 @@ static struct platform_driver max8925_regulator_driver = { .owner = THIS_MODULE, }, .probe = max8925_regulator_probe, - .remove = __devexit_p(max8925_regulator_remove), + .remove = max8925_regulator_remove, }; static int __init max8925_regulator_init(void) diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index 355ca7b..d575e5f 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c @@ -268,7 +268,7 @@ MODULE_DEVICE_TABLE(i2c, max8952_ids); static struct i2c_driver max8952_pmic_driver = { .probe = max8952_pmic_probe, - .remove = __devexit_p(max8952_pmic_remove), + .remove = max8952_pmic_remove, .driver = { .name = "max8952", }, diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index e39a0c7..2b97ec8 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -1143,7 +1143,7 @@ static struct platform_driver max8997_pmic_driver = { .owner = THIS_MODULE, }, .probe = max8997_pmic_probe, - .remove = __devexit_p(max8997_pmic_remove), + .remove = max8997_pmic_remove, .id_table = max8997_pmic_id, }; diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 5dfa920..1edb01c 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -842,7 +842,7 @@ static struct platform_driver max8998_pmic_driver = { .owner = THIS_MODULE, }, .probe = max8998_pmic_probe, - .remove = __devexit_p(max8998_pmic_remove), + .remove = max8998_pmic_remove, .id_table = max8998_pmic_id, }; diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 0801a6d..940f659 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -465,7 +465,7 @@ static struct platform_driver mc13783_regulator_driver = { .name = "mc13783-regulator", .owner = THIS_MODULE, }, - .remove = __devexit_p(mc13783_regulator_remove), + .remove = mc13783_regulator_remove, .probe = mc13783_regulator_probe, }; diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index 1fa6381..f3646cf 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -606,7 +606,7 @@ static struct platform_driver mc13892_regulator_driver = { .name = "mc13892-regulator", .owner = THIS_MODULE, }, - .remove = __devexit_p(mc13892_regulator_remove), + .remove = mc13892_regulator_remove, .probe = mc13892_regulator_probe, }; diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 07aee69..4e0d3b5 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -890,7 +890,7 @@ static struct platform_driver palmas_driver = { .owner = THIS_MODULE, }, .probe = palmas_probe, - .remove = __devexit_p(palmas_remove), + .remove = palmas_remove, }; static int __init palmas_init(void) diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c index 68777ac..1f349bf 100644 --- a/drivers/regulator/pcap-regulator.c +++ b/drivers/regulator/pcap-regulator.c @@ -271,7 +271,7 @@ static struct platform_driver pcap_regulator_driver = { .owner = THIS_MODULE, }, .probe = pcap_regulator_probe, - .remove = __devexit_p(pcap_regulator_remove), + .remove = pcap_regulator_remove, }; static int __init pcap_regulator_init(void) diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 092e5cb..02c9e1c 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c @@ -237,7 +237,7 @@ static struct platform_driver pcf50633_regulator_driver = { .name = "pcf50633-regltr", }, .probe = pcf50633_regulator_probe, - .remove = __devexit_p(pcf50633_regulator_remove), + .remove = pcf50633_regulator_remove, }; static int __init pcf50633_regulator_init(void) diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index 8bf4e8c..ca2b5ed 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -214,7 +214,7 @@ static struct platform_driver rc5t583_regulator_driver = { .owner = THIS_MODULE, }, .probe = rc5t583_regulator_probe, - .remove = __devexit_p(rc5t583_regulator_remove), + .remove = rc5t583_regulator_remove, }; static int __init rc5t583_regulator_init(void) diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 926f9c8..c2723ca 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -330,7 +330,7 @@ static struct platform_driver s2mps11_pmic_driver = { .owner = THIS_MODULE, }, .probe = s2mps11_pmic_probe, - .remove = __devexit_p(s2mps11_pmic_remove), + .remove = s2mps11_pmic_remove, .id_table = s2mps11_pmic_id, }; diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index abe64a3..d606ca0 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -798,7 +798,7 @@ static struct platform_driver s5m8767_pmic_driver = { .owner = THIS_MODULE, }, .probe = s5m8767_pmic_probe, - .remove = __devexit_p(s5m8767_pmic_remove), + .remove = s5m8767_pmic_remove, .id_table = s5m8767_pmic_id, }; diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index 3460364..687b0cc 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c @@ -311,7 +311,7 @@ static struct i2c_driver tps51632_i2c_driver = { .owner = THIS_MODULE, }, .probe = tps51632_probe, - .remove = __devexit_p(tps51632_remove), + .remove = tps51632_remove, .id_table = tps51632_id, }; diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index 1378409..9516f44 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c @@ -172,7 +172,7 @@ static struct platform_driver tps6105x_regulator_driver = { .owner = THIS_MODULE, }, .probe = tps6105x_regulator_probe, - .remove = __devexit_p(tps6105x_regulator_remove), + .remove = tps6105x_regulator_remove, }; static __init int tps6105x_regulator_init(void) diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index 68729a7..bd0f9f8 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -531,7 +531,7 @@ static struct i2c_driver tps62360_i2c_driver = { .of_match_table = of_match_ptr(tps62360_of_match), }, .probe = tps62360_probe, - .remove = __devexit_p(tps62360_remove), + .remove = tps62360_remove, .shutdown = tps62360_shutdown, .id_table = tps62360_id, }; diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 6998d57..427b311 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -446,7 +446,7 @@ static struct i2c_driver tps_65023_i2c_driver = { .owner = THIS_MODULE, }, .probe = tps_65023_probe, - .remove = __devexit_p(tps_65023_remove), + .remove = tps_65023_remove, .id_table = tps_65023_id, }; diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 07d01cc..c953e8f 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -456,7 +456,7 @@ static struct platform_driver tps6507x_pmic_driver = { .owner = THIS_MODULE, }, .probe = tps6507x_pmic_probe, - .remove = __devexit_p(tps6507x_pmic_remove), + .remove = tps6507x_pmic_remove, }; static int __init tps6507x_pmic_init(void) diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 4124138..99c912b 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -251,7 +251,7 @@ static struct platform_driver tps65090_regulator_driver = { .owner = THIS_MODULE, }, .probe = tps65090_regulator_probe, - .remove = __devexit_p(tps65090_regulator_remove), + .remove = tps65090_regulator_remove, }; static int __init tps65090_regulator_init(void) diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index ab00cab..73681ea 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -415,7 +415,7 @@ static struct platform_driver tps65217_regulator_driver = { .name = "tps65217-pmic", }, .probe = tps65217_regulator_probe, - .remove = __devexit_p(tps65217_regulator_remove), + .remove = tps65217_regulator_remove, }; static int __init tps65217_regulator_init(void) diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 058d2f2..f5a01bc 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c @@ -649,7 +649,7 @@ fail: static struct spi_driver pmic_driver = { .probe = pmic_probe, - .remove = __devexit_p(pmic_remove), + .remove = pmic_remove, .driver = { .name = "tps6524x", .owner = THIS_MODULE, diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index ce1e7cb..491b16a 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -349,7 +349,7 @@ static struct platform_driver tps6586x_regulator_driver = { .owner = THIS_MODULE, }, .probe = tps6586x_regulator_probe, - .remove = __devexit_p(tps6586x_regulator_remove), + .remove = tps6586x_regulator_remove, }; static int __init tps6586x_regulator_init(void) diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 793adda..2e1e57b 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -1231,7 +1231,7 @@ static struct platform_driver tps65910_driver = { .owner = THIS_MODULE, }, .probe = tps65910_probe, - .remove = __devexit_p(tps65910_remove), + .remove = tps65910_remove, .shutdown = tps65910_shutdown, }; diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index 18b2a1d..ba7e623 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c @@ -541,7 +541,7 @@ static struct platform_driver tps65912_driver = { .owner = THIS_MODULE, }, .probe = tps65912_probe, - .remove = __devexit_p(tps65912_remove), + .remove = tps65912_remove, }; static int __init tps65912_init(void) diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index a37ede8..d90c23b 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -772,7 +772,7 @@ static struct platform_driver tps80031_regulator_driver = { .owner = THIS_MODULE, }, .probe = tps80031_regulator_probe, - .remove = __devexit_p(tps80031_regulator_remove), + .remove = tps80031_regulator_remove, }; static int __init tps80031_regulator_init(void) diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 7eb986a..eac8540 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -1255,7 +1255,7 @@ MODULE_ALIAS("platform:twl_reg"); static struct platform_driver twlreg_driver = { .probe = twlreg_probe, - .remove = __devexit_p(twlreg_remove), + .remove = twlreg_remove, /* NOTE: short name, to work around driver model truncation of * "twl_regulator.12" (and friends) to "twl_regulator.1". */ diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c index 1d55811..4056201 100644 --- a/drivers/regulator/vexpress.c +++ b/drivers/regulator/vexpress.c @@ -131,7 +131,7 @@ static struct of_device_id vexpress_regulator_of_match[] = { static struct platform_driver vexpress_regulator_driver = { .probe = vexpress_regulator_probe, - .remove = __devexit_p(vexpress_regulator_remove), + .remove = vexpress_regulator_remove, .driver = { .name = DRVNAME, .owner = THIS_MODULE, diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c index c038e74..ec97b3e 100644 --- a/drivers/regulator/virtual.c +++ b/drivers/regulator/virtual.c @@ -337,7 +337,7 @@ static int __devexit regulator_virtual_remove(struct platform_device *pdev) static struct platform_driver regulator_virtual_consumer_driver = { .probe = regulator_virtual_probe, - .remove = __devexit_p(regulator_virtual_remove), + .remove = regulator_virtual_remove, .driver = { .name = "reg-virt-consumer", .owner = THIS_MODULE, diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 782c228..16d7ebd 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -582,7 +582,7 @@ static __devexit int wm831x_buckv_remove(struct platform_device *pdev) static struct platform_driver wm831x_buckv_driver = { .probe = wm831x_buckv_probe, - .remove = __devexit_p(wm831x_buckv_remove), + .remove = wm831x_buckv_remove, .driver = { .name = "wm831x-buckv", .owner = THIS_MODULE, @@ -725,7 +725,7 @@ static __devexit int wm831x_buckp_remove(struct platform_device *pdev) static struct platform_driver wm831x_buckp_driver = { .probe = wm831x_buckp_probe, - .remove = __devexit_p(wm831x_buckp_remove), + .remove = wm831x_buckp_remove, .driver = { .name = "wm831x-buckp", .owner = THIS_MODULE, @@ -860,7 +860,7 @@ static __devexit int wm831x_boostp_remove(struct platform_device *pdev) static struct platform_driver wm831x_boostp_driver = { .probe = wm831x_boostp_probe, - .remove = __devexit_p(wm831x_boostp_remove), + .remove = wm831x_boostp_remove, .driver = { .name = "wm831x-boostp", .owner = THIS_MODULE, @@ -948,7 +948,7 @@ static __devexit int wm831x_epe_remove(struct platform_device *pdev) static struct platform_driver wm831x_epe_driver = { .probe = wm831x_epe_probe, - .remove = __devexit_p(wm831x_epe_remove), + .remove = wm831x_epe_remove, .driver = { .name = "wm831x-epe", .owner = THIS_MODULE, diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 2646a19..1f807a8 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -236,7 +236,7 @@ static __devexit int wm831x_isink_remove(struct platform_device *pdev) static struct platform_driver wm831x_isink_driver = { .probe = wm831x_isink_probe, - .remove = __devexit_p(wm831x_isink_remove), + .remove = wm831x_isink_remove, .driver = { .name = "wm831x-isink", .owner = THIS_MODULE, diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index c2dc039..2df0600 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -349,7 +349,7 @@ static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev) static struct platform_driver wm831x_gp_ldo_driver = { .probe = wm831x_gp_ldo_probe, - .remove = __devexit_p(wm831x_gp_ldo_remove), + .remove = wm831x_gp_ldo_remove, .driver = { .name = "wm831x-ldo", .owner = THIS_MODULE, @@ -603,7 +603,7 @@ static __devexit int wm831x_aldo_remove(struct platform_device *pdev) static struct platform_driver wm831x_aldo_driver = { .probe = wm831x_aldo_probe, - .remove = __devexit_p(wm831x_aldo_remove), + .remove = wm831x_aldo_remove, .driver = { .name = "wm831x-aldo", .owner = THIS_MODULE, @@ -748,7 +748,7 @@ static __devexit int wm831x_alive_ldo_remove(struct platform_device *pdev) static struct platform_driver wm831x_alive_ldo_driver = { .probe = wm831x_alive_ldo_probe, - .remove = __devexit_p(wm831x_alive_ldo_remove), + .remove = wm831x_alive_ldo_remove, .driver = { .name = "wm831x-alive-ldo", .owner = THIS_MODULE, diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 27c746e..1bb1551 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -261,7 +261,7 @@ static struct platform_driver wm8400_regulator_driver = { .name = "wm8400-regulator", }, .probe = wm8400_regulator_probe, - .remove = __devexit_p(wm8400_regulator_remove), + .remove = wm8400_regulator_remove, }; /** diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 86bb48d..28b4548 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -155,7 +155,7 @@ static __devexit int wm8994_ldo_remove(struct platform_device *pdev) static struct platform_driver wm8994_ldo_driver = { .probe = wm8994_ldo_probe, - .remove = __devexit_p(wm8994_ldo_remove), + .remove = wm8994_ldo_remove, .driver = { .name = "wm8994-ldo", .owner = THIS_MODULE, -- cgit v0.10.2 From a5023574d120ca3b9337cedd4e27de90cae9aff7 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:22:22 -0500 Subject: regulator: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Mark Brown diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 2d798ca..c09b5d9 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -394,7 +394,7 @@ static int pm8607_regulator_dt_init(struct platform_device *pdev, #define pm8607_regulator_dt_init(x, y, z) (-1) #endif -static int __devinit pm8607_regulator_probe(struct platform_device *pdev) +static int pm8607_regulator_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm8607_regulator_info *info = NULL; diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 9fae59d..7a04d5f 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -494,7 +494,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { * for all the different regulators. */ -static int __devinit ab3100_regulators_probe(struct platform_device *pdev) +static int ab3100_regulators_probe(struct platform_device *pdev) { struct ab3100_platform_data *plfdata = pdev->dev.platform_data; struct regulator_config config = { }; diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 987b047..af81325 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -641,7 +641,7 @@ static struct ab8500_reg_init ab8500_reg_init[] = { REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), }; -static __devinit int +static int ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value) { int err; @@ -676,7 +676,7 @@ ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value) return 0; } -static __devinit int ab8500_regulator_register(struct platform_device *pdev, +static int ab8500_regulator_register(struct platform_device *pdev, struct regulator_init_data *init_data, int id, struct device_node *np) @@ -735,7 +735,7 @@ static struct of_regulator_match ab8500_regulator_matches[] = { { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, }, }; -static __devinit int +static int ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np) { int err, i; @@ -751,7 +751,7 @@ ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np) return 0; } -static __devinit int ab8500_regulator_probe(struct platform_device *pdev) +static int ab8500_regulator_probe(struct platform_device *pdev) { struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct ab8500_platform_data *pdata; diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index 7921d01..cd855d9 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c @@ -211,7 +211,7 @@ static const struct i2c_device_id ad5398_id[] = { }; MODULE_DEVICE_TABLE(i2c, ad5398_id); -static int __devinit ad5398_probe(struct i2c_client *client, +static int ad5398_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct regulator_init_data *init_data = client->dev.platform_data; diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index e8ae656..a900c29 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -87,7 +87,7 @@ static struct regulator_ops anatop_rops = { .map_voltage = regulator_map_voltage_linear, }; -static int __devinit anatop_regulator_probe(struct platform_device *pdev) +static int anatop_regulator_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 7502394..7e9ad7c 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -67,7 +67,7 @@ static const struct regulator_init_data arizona_ldo1_default = { .num_consumer_supplies = 1, }; -static __devinit int arizona_ldo1_probe(struct platform_device *pdev) +static int arizona_ldo1_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 8c6eeba..3c3631c 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -115,7 +115,7 @@ static const struct regulator_init_data arizona_micsupp_default = { .num_consumer_supplies = 1, }; -static __devinit int arizona_micsupp_probe(struct platform_device *pdev) +static int arizona_micsupp_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index 43db3a5..ab4a6d6 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -460,7 +460,7 @@ static inline struct da903x_regulator_info *find_regulator_info(int id) return NULL; } -static int __devinit da903x_regulator_probe(struct platform_device *pdev) +static int da903x_regulator_probe(struct platform_device *pdev) { struct da903x_regulator_info *ri = NULL; struct regulator_dev *rdev; diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 9caa6e6..ba703d8 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -365,7 +365,7 @@ static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id, return NULL; } -static int __devinit da9052_regulator_probe(struct platform_device *pdev) +static int da9052_regulator_probe(struct platform_device *pdev) { struct regulator_config config = { }; struct da9052_regulator *regulator; diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 359f8d1..219d162 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -412,7 +412,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { }, }; -static __devinit int db8500_regulator_register(struct platform_device *pdev, +static int db8500_regulator_register(struct platform_device *pdev, struct regulator_init_data *init_data, int id, struct device_node *np) @@ -474,7 +474,7 @@ static struct of_regulator_match db8500_regulator_matches[] = { { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, }; -static __devinit int +static int db8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np) { @@ -491,7 +491,7 @@ db8500_regulator_of_probe(struct platform_device *pdev, return 0; } -static int __devinit db8500_regulator_probe(struct platform_device *pdev) +static int db8500_regulator_probe(struct platform_device *pdev) { struct regulator_init_data *db8500_init_data = dev_get_platdata(&pdev->dev); diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index f2e5ecd..afc3e89 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c @@ -173,7 +173,7 @@ int __attribute__((weak)) dbx500_regulator_testcase( return 0; } -int __devinit +int ux500_regulator_debug_init(struct platform_device *pdev, struct dbx500_regulator_info *regulator_info, int num_regulators) diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index 03a1d7c..df9f425 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c @@ -37,7 +37,7 @@ static struct regulator_desc dummy_desc = { .ops = &dummy_ops, }; -static int __devinit dummy_regulator_probe(struct platform_device *pdev) +static int dummy_regulator_probe(struct platform_device *pdev) { struct regulator_config config = { }; int ret; diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 5279eff..199172a 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -230,7 +230,7 @@ static struct regmap_config fan53555_regmap_config = { .val_bits = 8, }; -static int __devinit fan53555_regulator_probe(struct i2c_client *client, +static int fan53555_regulator_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct fan53555_device_info *di; diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 73a6a59..5aa0be0 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -134,7 +134,7 @@ static struct regulator_ops fixed_voltage_ops = { .list_voltage = fixed_voltage_list_voltage, }; -static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) +static int reg_fixed_voltage_probe(struct platform_device *pdev) { struct fixed_voltage_config *config; struct fixed_voltage_data *drvdata; diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 902e041..5ffee5e 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -220,7 +220,7 @@ static struct regulator_ops gpio_regulator_current_ops = { .set_current_limit = gpio_regulator_set_current_limit, }; -static int __devinit gpio_regulator_probe(struct platform_device *pdev) +static int gpio_regulator_probe(struct platform_device *pdev) { struct gpio_regulator_config *config = pdev->dev.platform_data; struct device_node *np = pdev->dev.of_node; diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index 2c415e9..1732108 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -106,7 +106,7 @@ static const struct regulator_desc isl_rd[] = { }, }; -static int __devinit isl6271a_probe(struct i2c_client *i2c, +static int isl6271a_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct regulator_config config = { }; diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index e10726a..95b7299 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -386,7 +386,7 @@ static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val) return ret; } -static int __devinit setup_regulators(struct lp3971 *lp3971, +static int setup_regulators(struct lp3971 *lp3971, struct lp3971_platform_data *pdata) { int i, err; @@ -429,7 +429,7 @@ err_nomem: return err; } -static int __devinit lp3971_i2c_probe(struct i2c_client *i2c, +static int lp3971_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct lp3971 *lp3971; diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c index 262f2d2..acf71be 100644 --- a/drivers/regulator/lp3972.c +++ b/drivers/regulator/lp3972.c @@ -481,7 +481,7 @@ static const struct regulator_desc regulators[] = { }, }; -static int __devinit setup_regulators(struct lp3972 *lp3972, +static int setup_regulators(struct lp3972 *lp3972, struct lp3972_platform_data *pdata) { int i, err; @@ -523,7 +523,7 @@ err_nomem: return err; } -static int __devinit lp3972_i2c_probe(struct i2c_client *i2c, +static int lp3972_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct lp3972 *lp3972; diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c index 35643d2..1a3623a 100644 --- a/drivers/regulator/lp8788-buck.c +++ b/drivers/regulator/lp8788-buck.c @@ -504,7 +504,7 @@ set_default_dvs_mode: default_dvs_mode[id]); } -static __devinit int lp8788_buck_probe(struct platform_device *pdev) +static int lp8788_buck_probe(struct platform_device *pdev) { struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); int id = pdev->id; diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index 93399f1..e69a5b6 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -712,7 +712,7 @@ set_default_ldo_enable_mode: val[enable_id]); } -static __devinit int lp8788_dldo_probe(struct platform_device *pdev) +static int lp8788_dldo_probe(struct platform_device *pdev) { struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); int id = pdev->id; @@ -768,7 +768,7 @@ static struct platform_driver lp8788_dldo_driver = { }, }; -static __devinit int lp8788_aldo_probe(struct platform_device *pdev) +static int lp8788_aldo_probe(struct platform_device *pdev) { struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); int id = pdev->id; diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 184a92f..1609810 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -125,7 +125,7 @@ static struct regulator_desc max1586_reg[] = { }, }; -static int __devinit max1586_pmic_probe(struct i2c_client *client, +static int max1586_pmic_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { struct regulator_dev **rdev; diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 7374f5e..da028d0 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -280,7 +280,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, } #endif /* CONFIG_OF */ -static __devinit int max77686_pmic_probe(struct platform_device *pdev) +static int max77686_pmic_probe(struct platform_device *pdev) { struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index d78d4aa..d4397f9 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -176,7 +176,7 @@ static struct regmap_config max8649_regmap_config = { .val_bits = 8, }; -static int __devinit max8649_regulator_probe(struct i2c_client *client, +static int max8649_regulator_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct max8649_platform_data *pdata = client->dev.platform_data; diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index b009a5e..a44589f 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -305,7 +305,7 @@ static const struct regulator_desc max8660_reg[] = { }, }; -static int __devinit max8660_probe(struct i2c_client *client, +static int max8660_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { struct regulator_dev **rdev; diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index 882e7cb..99bae75 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c @@ -275,7 +275,7 @@ static inline struct device_node *match_of_node(int index) } #endif -static __devinit int max8907_regulator_probe(struct platform_device *pdev) +static int max8907_regulator_probe(struct platform_device *pdev) { struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent); struct max8907_platform_data *pdata = dev_get_platdata(max8907->dev); diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 85d419ed..cd06708 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -274,7 +274,7 @@ static int max8925_regulator_dt_init(struct platform_device *pdev, #define max8925_regulator_dt_init(w, x, y, z) (-1) #endif -static int __devinit max8925_regulator_probe(struct platform_device *pdev) +static int max8925_regulator_probe(struct platform_device *pdev) { struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); struct regulator_init_data *pdata = pdev->dev.platform_data; diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index d575e5f..2186208 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c @@ -126,7 +126,7 @@ static const struct regulator_desc regulator = { .owner = THIS_MODULE, }; -static int __devinit max8952_pmic_probe(struct i2c_client *client, +static int max8952_pmic_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 2b97ec8..323ec2b 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -933,7 +933,7 @@ static struct regulator_desc regulators[] = { max8997_charger_fixedstate_ops), }; -static __devinit int max8997_pmic_probe(struct platform_device *pdev) +static int max8997_pmic_probe(struct platform_device *pdev) { struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 1edb01c..d80ce6c 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -633,7 +633,7 @@ static struct regulator_desc regulators[] = { } }; -static __devinit int max8998_pmic_probe(struct platform_device *pdev) +static int max8998_pmic_probe(struct platform_device *pdev) { struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 940f659..54f42b3 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -392,7 +392,7 @@ static struct regulator_ops mc13783_gpo_regulator_ops = { .set_voltage = mc13xxx_fixed_regulator_set_voltage, }; -static int __devinit mc13783_regulator_probe(struct platform_device *pdev) +static int mc13783_regulator_probe(struct platform_device *pdev) { struct mc13xxx_regulator_priv *priv; struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent); diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index f3646cf..9804a31 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -486,7 +486,7 @@ static unsigned int mc13892_vcam_get_mode(struct regulator_dev *rdev) } -static int __devinit mc13892_regulator_probe(struct platform_device *pdev) +static int mc13892_regulator_probe(struct platform_device *pdev) { struct mc13xxx_regulator_priv *priv; struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 88cbb83..4ed89c6 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -162,7 +162,7 @@ struct regulator_ops mc13xxx_fixed_regulator_ops = { EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops); #ifdef CONFIG_OF -int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev) +int mc13xxx_get_num_regulators_dt(struct platform_device *pdev) { struct device_node *parent, *child; int num = 0; @@ -179,7 +179,7 @@ int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt); -struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( +struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt( struct platform_device *pdev, struct mc13xxx_regulator *regulators, int num_regulators) { diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 4e0d3b5..b047744 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -595,7 +595,7 @@ static struct of_regulator_match palmas_matches[] = { { .name = "ldousb", }, }; -static void __devinit palmas_dt_to_pdata(struct device *dev, +static void palmas_dt_to_pdata(struct device *dev, struct device_node *node, struct palmas_pmic_platform_data *pdata) { @@ -663,7 +663,7 @@ static void __devinit palmas_dt_to_pdata(struct device *dev, } -static __devinit int palmas_probe(struct platform_device *pdev) +static int palmas_probe(struct platform_device *pdev) { struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data; diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c index 1f349bf..4f3e445 100644 --- a/drivers/regulator/pcap-regulator.c +++ b/drivers/regulator/pcap-regulator.c @@ -236,7 +236,7 @@ static const struct regulator_desc pcap_regulators[] = { VREG(VAUX4), VREG(VSIM), VREG(VSIM2), VREG(VVIB), VREG(SW1), VREG(SW2), }; -static int __devinit pcap_regulator_probe(struct platform_device *pdev) +static int pcap_regulator_probe(struct platform_device *pdev) { struct regulator_dev *rdev; void *pcap = dev_get_drvdata(pdev->dev.parent); diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 02c9e1c..51cb1bb 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c @@ -196,7 +196,7 @@ static const struct regulator_desc regulators[] = { [PCF50633_REGULATOR_MEMLDO] = PCF50633_REGULATOR("memldo", MEMLDO, 28), }; -static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) +static int pcf50633_regulator_probe(struct platform_device *pdev) { struct regulator_dev *rdev; struct pcf50633 *pcf; diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index ca2b5ed..7f83f33 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -119,7 +119,7 @@ static struct rc5t583_regulator_info rc5t583_reg_info[RC5T583_REGULATOR_MAX] = { RC5T583_REG(LDO9, LDOEN1, 1, LDODIS1, 1, 0x7F, 900, 3400, 25000, 133), }; -static int __devinit rc5t583_regulator_probe(struct platform_device *pdev) +static int rc5t583_regulator_probe(struct platform_device *pdev) { struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index c2723ca..c918e99 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -231,7 +231,7 @@ static struct regulator_desc regulators[] = { regulator_desc_buck10, }; -static __devinit int s2mps11_pmic_probe(struct platform_device *pdev) +static int s2mps11_pmic_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index d606ca0..15f3cca 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -499,7 +499,7 @@ static struct regulator_desc regulators[] = { s5m8767_regulator_desc(BUCK9), }; -static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) +static int s5m8767_pmic_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index 687b0cc..ff79a46 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c @@ -157,7 +157,7 @@ static struct regulator_ops tps51632_dcdc_ops = { .set_ramp_delay = tps51632_dcdc_set_ramp_delay, }; -static int __devinit tps51632_init_dcdc(struct tps51632_chip *tps, +static int tps51632_init_dcdc(struct tps51632_chip *tps, struct tps51632_regulator_platform_data *pdata) { int ret; @@ -227,7 +227,7 @@ static const struct regmap_config tps51632_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static int __devinit tps51632_probe(struct i2c_client *client, +static int tps51632_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct tps51632_regulator_platform_data *pdata; diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index 9516f44..f8c0c92 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c @@ -127,7 +127,7 @@ static const struct regulator_desc tps6105x_regulator_desc = { /* * Registers the chip as a voltage regulator */ -static int __devinit tps6105x_regulator_probe(struct platform_device *pdev) +static int tps6105x_regulator_probe(struct platform_device *pdev) { struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev); struct tps6105x_platform_data *pdata = tps6105x->pdata; diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index bd0f9f8..7fba9ff 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -243,7 +243,7 @@ static struct regulator_ops tps62360_dcdc_ops = { .get_mode = tps62360_get_mode, }; -static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps, +static int tps62360_init_dcdc(struct tps62360_chip *tps, struct tps62360_regulator_platform_data *pdata) { int ret; @@ -339,7 +339,7 @@ static const struct of_device_id tps62360_of_match[] = { MODULE_DEVICE_TABLE(of, tps62360_of_match); #endif -static int __devinit tps62360_probe(struct i2c_client *client, +static int tps62360_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct regulator_config config = { }; diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 427b311..a039206 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -219,7 +219,7 @@ static struct regmap_config tps65023_regmap_config = { .val_bits = 8, }; -static int __devinit tps_65023_probe(struct i2c_client *client, +static int tps_65023_probe(struct i2c_client *client, const struct i2c_device_id *id) { const struct tps_driver_data *drv_data = (void *)id->driver_data; diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index c953e8f..6c45d5a 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -356,7 +356,7 @@ static struct regulator_ops tps6507x_pmic_ops = { .list_voltage = regulator_list_voltage_table, }; -static __devinit int tps6507x_pmic_probe(struct platform_device *pdev) +static int tps6507x_pmic_probe(struct platform_device *pdev) { struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); struct tps_info *info = &tps6507x_pmic_regs[0]; diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 99c912b..cc5be1f 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -83,7 +83,7 @@ static inline bool is_dcdc(int id) } } -static int __devinit tps65090_config_ext_control( +static int tps65090_config_ext_control( struct tps65090_regulator *ri, bool enable) { int ret; @@ -99,7 +99,7 @@ static int __devinit tps65090_config_ext_control( return ret; } -static int __devinit tps65090_regulator_disable_ext_control( +static int tps65090_regulator_disable_ext_control( struct tps65090_regulator *ri, struct tps65090_regulator_plat_data *tps_pdata) { @@ -122,7 +122,7 @@ static int __devinit tps65090_regulator_disable_ext_control( return tps65090_config_ext_control(ri, false); } -static void __devinit tps65090_configure_regulator_config( +static void tps65090_configure_regulator_config( struct tps65090_regulator_plat_data *tps_pdata, struct regulator_config *config) { @@ -138,7 +138,7 @@ static void __devinit tps65090_configure_regulator_config( } } -static int __devinit tps65090_regulator_probe(struct platform_device *pdev) +static int tps65090_regulator_probe(struct platform_device *pdev) { struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent); struct tps65090_regulator *ri = NULL; diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 73681ea..e34fb86 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -332,7 +332,7 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) } #endif -static int __devinit tps65217_regulator_probe(struct platform_device *pdev) +static int tps65217_regulator_probe(struct platform_device *pdev) { struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); struct tps65217_board *pdata = dev_get_platdata(tps->dev); diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index f5a01bc..843ee0a 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c @@ -592,7 +592,7 @@ static int pmic_remove(struct spi_device *spi) return 0; } -static int __devinit pmic_probe(struct spi_device *spi) +static int pmic_probe(struct spi_device *spi) { struct tps6524x *hw; struct device *dev = &spi->dev; diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 491b16a..b91400c 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -298,7 +298,7 @@ static inline struct tps6586x_regulator *find_regulator_info(int id) return NULL; } -static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) +static int tps6586x_regulator_probe(struct platform_device *pdev) { struct tps6586x_regulator *ri = NULL; struct regulator_config config = { }; diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 2e1e57b..276eeb5 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -1026,7 +1026,7 @@ static inline struct tps65910_board *tps65910_parse_dt_reg_data( } #endif -static __devinit int tps65910_probe(struct platform_device *pdev) +static int tps65910_probe(struct platform_device *pdev) { struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index ba7e623..35b2a6f 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c @@ -459,7 +459,7 @@ static struct regulator_ops tps65912_ops_ldo = { .list_voltage = tps65912_list_voltage, }; -static __devinit int tps65912_probe(struct platform_device *pdev) +static int tps65912_probe(struct platform_device *pdev) { struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index d90c23b..cdfcbc9 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -675,7 +675,7 @@ static int check_smps_mode_mult(struct device *parent, return 0; } -static int __devinit tps80031_regulator_probe(struct platform_device *pdev) +static int tps80031_regulator_probe(struct platform_device *pdev) { struct tps80031_platform_data *pdata; struct tps80031_regulator_platform_data *tps_pdata; diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index eac8540..66e62a2 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -1116,7 +1116,7 @@ static const struct of_device_id twl_of_match[] __devinitconst = { }; MODULE_DEVICE_TABLE(of, twl_of_match); -static int __devinit twlreg_probe(struct platform_device *pdev) +static int twlreg_probe(struct platform_device *pdev) { int i, id; struct twlreg_info *info; diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c index ec97b3e..be0dd18 100644 --- a/drivers/regulator/virtual.c +++ b/drivers/regulator/virtual.c @@ -285,7 +285,7 @@ static const struct attribute_group regulator_virtual_attr_group = { .attrs = regulator_virtual_attributes, }; -static int __devinit regulator_virtual_probe(struct platform_device *pdev) +static int regulator_virtual_probe(struct platform_device *pdev) { char *reg_id = pdev->dev.platform_data; struct virtual_consumer_data *drvdata; diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 16d7ebd..54e9778 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -387,7 +387,7 @@ static struct regulator_ops wm831x_buckv_ops = { * Set up DVS control. We just log errors since we can still run * (with reduced performance) if we fail. */ -static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, +static void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, struct wm831x_buckv_pdata *pdata) { struct wm831x *wm831x = dcdc->wm831x; @@ -448,7 +448,7 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, } } -static __devinit int wm831x_buckv_probe(struct platform_device *pdev) +static int wm831x_buckv_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; @@ -623,7 +623,7 @@ static struct regulator_ops wm831x_buckp_ops = { .set_suspend_mode = wm831x_dcdc_set_suspend_mode, }; -static __devinit int wm831x_buckp_probe(struct platform_device *pdev) +static int wm831x_buckp_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; @@ -771,7 +771,7 @@ static struct regulator_ops wm831x_boostp_ops = { .disable = regulator_disable_regmap, }; -static __devinit int wm831x_boostp_probe(struct platform_device *pdev) +static int wm831x_boostp_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; @@ -883,7 +883,7 @@ static struct regulator_ops wm831x_epe_ops = { .get_status = wm831x_dcdc_get_status, }; -static __devinit int wm831x_epe_probe(struct platform_device *pdev) +static int wm831x_epe_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 1f807a8..ac4bdff 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -148,7 +148,7 @@ static irqreturn_t wm831x_isink_irq(int irq, void *data) } -static __devinit int wm831x_isink_probe(struct platform_device *pdev) +static int wm831x_isink_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 2df0600..90f657f 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -247,7 +247,7 @@ static struct regulator_ops wm831x_gp_ldo_ops = { .disable = regulator_disable_regmap, }; -static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) +static int wm831x_gp_ldo_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; @@ -504,7 +504,7 @@ static struct regulator_ops wm831x_aldo_ops = { .disable = regulator_disable_regmap, }; -static __devinit int wm831x_aldo_probe(struct platform_device *pdev) +static int wm831x_aldo_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; @@ -660,7 +660,7 @@ static struct regulator_ops wm831x_alive_ldo_ops = { .disable = regulator_disable_regmap, }; -static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) +static int wm831x_alive_ldo_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 1bb1551..c155ec3 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -226,7 +226,7 @@ static struct regulator_desc regulators[] = { }, }; -static int __devinit wm8400_regulator_probe(struct platform_device *pdev) +static int wm8400_regulator_probe(struct platform_device *pdev) { struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]); struct regulator_config config = { }; diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 28b4548..ea0fdd5 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -99,7 +99,7 @@ static const struct regulator_desc wm8994_ldo_desc[] = { }, }; -static __devinit int wm8994_ldo_probe(struct platform_device *pdev) +static int wm8994_ldo_probe(struct platform_device *pdev) { struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent); struct wm8994_pdata *pdata = wm8994->dev->platform_data; -- cgit v0.10.2 From 13ae633cf729b0ecb677b75b04886ff8fada8fad Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 20 Nov 2012 10:02:06 +0900 Subject: regulator: wm831x: Set the new rather than old value for DVS VSEL Reported-by: Guennadi Liakhovetski Signed-off-by: Mark Brown Cc: stable@vger.kernel.org diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 782c228..416fe0a 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -290,7 +290,7 @@ static int wm831x_buckv_set_voltage_sel(struct regulator_dev *rdev, if (vsel > dcdc->dvs_vsel) { ret = wm831x_set_bits(wm831x, dvs_reg, WM831X_DC1_DVS_VSEL_MASK, - dcdc->dvs_vsel); + vsel); if (ret == 0) dcdc->dvs_vsel = vsel; else -- cgit v0.10.2 From 8dc995f56ef7aedb41873fdeaa1971f3aa166ebd Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:10 -0500 Subject: regulator: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Mark Brown diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index c09b5d9..2b55711 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -454,7 +454,7 @@ static int pm8607_regulator_probe(struct platform_device *pdev) return 0; } -static int __devexit pm8607_regulator_remove(struct platform_device *pdev) +static int pm8607_regulator_remove(struct platform_device *pdev) { struct pm8607_regulator_info *info = platform_get_drvdata(pdev); diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index 4285b30..8b58763 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c @@ -187,7 +187,7 @@ static int aat2870_regulator_probe(struct platform_device *pdev) return 0; } -static int __devexit aat2870_regulator_remove(struct platform_device *pdev) +static int aat2870_regulator_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 7a04d5f..111ec69 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -571,7 +571,7 @@ static int ab3100_regulators_probe(struct platform_device *pdev) return 0; } -static int __devexit ab3100_regulators_remove(struct platform_device *pdev) +static int ab3100_regulators_remove(struct platform_device *pdev) { int i; diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index af81325..09014f3 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -817,7 +817,7 @@ static int ab8500_regulator_probe(struct platform_device *pdev) return 0; } -static __devexit int ab8500_regulator_remove(struct platform_device *pdev) +static int ab8500_regulator_remove(struct platform_device *pdev) { int i; diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index cd855d9..6b981b5 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c @@ -256,7 +256,7 @@ err: return ret; } -static int __devexit ad5398_remove(struct i2c_client *client) +static int ad5398_remove(struct i2c_client *client) { struct ad5398_chip_info *chip = i2c_get_clientdata(client); diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index a900c29..1aa5246 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -186,7 +186,7 @@ anatop_probe_end: return ret; } -static int __devexit anatop_regulator_remove(struct platform_device *pdev) +static int anatop_regulator_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); struct anatop_regulator *sreg = rdev_get_drvdata(rdev); diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 7e9ad7c..b44fa6f 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -115,7 +115,7 @@ static int arizona_ldo1_probe(struct platform_device *pdev) return 0; } -static __devexit int arizona_ldo1_remove(struct platform_device *pdev) +static int arizona_ldo1_remove(struct platform_device *pdev) { struct arizona_ldo1 *ldo1 = platform_get_drvdata(pdev); diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 3c3631c..5ae2d3e 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -166,7 +166,7 @@ static int arizona_micsupp_probe(struct platform_device *pdev) return 0; } -static __devexit int arizona_micsupp_remove(struct platform_device *pdev) +static int arizona_micsupp_remove(struct platform_device *pdev) { struct arizona_micsupp *micsupp = platform_get_drvdata(pdev); diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index ab4a6d6..2afa573 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -499,7 +499,7 @@ static int da903x_regulator_probe(struct platform_device *pdev) return 0; } -static int __devexit da903x_regulator_remove(struct platform_device *pdev) +static int da903x_regulator_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index ba703d8..d6fbfd3 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -430,7 +430,7 @@ static int da9052_regulator_probe(struct platform_device *pdev) return 0; } -static int __devexit da9052_regulator_remove(struct platform_device *pdev) +static int da9052_regulator_remove(struct platform_device *pdev) { struct da9052_regulator *regulator = platform_get_drvdata(pdev); diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index afc3e89..261f3d2 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c @@ -230,7 +230,7 @@ exit_no_debugfs: return -ENOMEM; } -int __devexit ux500_regulator_debug_exit(void) +int ux500_regulator_debug_exit(void) { debugfs_remove_recursive(rdebug.dir); kfree(rdebug.state_after_suspend); diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 199172a..9165b0c 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -293,7 +293,7 @@ static int fan53555_regulator_probe(struct i2c_client *client, } -static int __devexit fan53555_regulator_remove(struct i2c_client *client) +static int fan53555_regulator_remove(struct i2c_client *client) { struct fan53555_device_info *di = i2c_get_clientdata(client); diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 5aa0be0..48d5b76 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -234,7 +234,7 @@ err: return ret; } -static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev) +static int reg_fixed_voltage_remove(struct platform_device *pdev) { struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev); diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 5ffee5e..3ee79c8 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -348,7 +348,7 @@ err: return ret; } -static int __devexit gpio_regulator_remove(struct platform_device *pdev) +static int gpio_regulator_remove(struct platform_device *pdev) { struct gpio_regulator_data *drvdata = platform_get_drvdata(pdev); diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index 1732108..d1e5bee 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -151,7 +151,7 @@ error: return err; } -static int __devexit isl6271a_remove(struct i2c_client *i2c) +static int isl6271a_remove(struct i2c_client *i2c) { struct isl_pmic *pmic = i2c_get_clientdata(i2c); int i; diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 95b7299..5f68ff1 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -472,7 +472,7 @@ err_detect: return ret; } -static int __devexit lp3971_i2c_remove(struct i2c_client *i2c) +static int lp3971_i2c_remove(struct i2c_client *i2c) { struct lp3971 *lp3971 = i2c_get_clientdata(i2c); int i; diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c index acf71be..69c42c3 100644 --- a/drivers/regulator/lp3972.c +++ b/drivers/regulator/lp3972.c @@ -569,7 +569,7 @@ err_detect: return ret; } -static int __devexit lp3972_i2c_remove(struct i2c_client *i2c) +static int lp3972_i2c_remove(struct i2c_client *i2c) { struct lp3972 *lp3972 = i2c_get_clientdata(i2c); int i; diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 622ad5e..9289ead 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -893,7 +893,7 @@ err_dev: return ret; } -static int __devexit lp872x_remove(struct i2c_client *cl) +static int lp872x_remove(struct i2c_client *cl) { struct lp872x *lp = i2c_get_clientdata(cl); diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c index 1a3623a..6cc02c3 100644 --- a/drivers/regulator/lp8788-buck.c +++ b/drivers/regulator/lp8788-buck.c @@ -542,7 +542,7 @@ static int lp8788_buck_probe(struct platform_device *pdev) return 0; } -static int __devexit lp8788_buck_remove(struct platform_device *pdev) +static int lp8788_buck_remove(struct platform_device *pdev) { struct lp8788_buck *buck = platform_get_drvdata(pdev); diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index e69a5b6..26753a0 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -749,7 +749,7 @@ static int lp8788_dldo_probe(struct platform_device *pdev) return 0; } -static int __devexit lp8788_dldo_remove(struct platform_device *pdev) +static int lp8788_dldo_remove(struct platform_device *pdev) { struct lp8788_ldo *ldo = platform_get_drvdata(pdev); @@ -805,7 +805,7 @@ static int lp8788_aldo_probe(struct platform_device *pdev) return 0; } -static int __devexit lp8788_aldo_remove(struct platform_device *pdev) +static int lp8788_aldo_remove(struct platform_device *pdev) { struct lp8788_ldo *ldo = platform_get_drvdata(pdev); diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 1609810..3a035ec 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -188,7 +188,7 @@ err: return ret; } -static int __devexit max1586_pmic_remove(struct i2c_client *client) +static int max1586_pmic_remove(struct i2c_client *client) { struct max1586_data *max1586 = i2c_get_clientdata(client); int i; diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index da028d0..cb99e90 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -337,7 +337,7 @@ err: return ret; } -static int __devexit max77686_pmic_remove(struct platform_device *pdev) +static int max77686_pmic_remove(struct platform_device *pdev) { struct max77686_data *max77686 = platform_get_drvdata(pdev); int i; diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index d4397f9..3ca1438 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -271,7 +271,7 @@ static int max8649_regulator_probe(struct i2c_client *client, return 0; } -static int __devexit max8649_regulator_remove(struct i2c_client *client) +static int max8649_regulator_remove(struct i2c_client *client) { struct max8649_regulator_info *info = i2c_get_clientdata(client); diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index a44589f..4d7c635 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -420,7 +420,7 @@ err_out: return ret; } -static int __devexit max8660_remove(struct i2c_client *client) +static int max8660_remove(struct i2c_client *client) { struct max8660 *max8660 = i2c_get_clientdata(client); int i; diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index 99bae75..d1a7751 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c @@ -368,7 +368,7 @@ err_unregister_regulator: return ret; } -static __devexit int max8907_regulator_remove(struct platform_device *pdev) +static int max8907_regulator_remove(struct platform_device *pdev) { struct max8907_regulator *pmic = platform_get_drvdata(pdev); int i; diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index cd06708..446a854 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -323,7 +323,7 @@ static int max8925_regulator_probe(struct platform_device *pdev) return 0; } -static int __devexit max8925_regulator_remove(struct platform_device *pdev) +static int max8925_regulator_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index 2186208..fc7935a 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c @@ -247,7 +247,7 @@ static int max8952_pmic_probe(struct i2c_client *client, return 0; } -static int __devexit max8952_pmic_remove(struct i2c_client *client) +static int max8952_pmic_remove(struct i2c_client *client) { struct max8952_data *max8952 = i2c_get_clientdata(client); struct max8952_platform_data *pdata = max8952->pdata; diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 323ec2b..cea9ec9 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -1120,7 +1120,7 @@ err_out: return ret; } -static int __devexit max8997_pmic_remove(struct platform_device *pdev) +static int max8997_pmic_remove(struct platform_device *pdev) { struct max8997_data *max8997 = platform_get_drvdata(pdev); struct regulator_dev **rdev = max8997->rdev; diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index d80ce6c..b821d08 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -818,7 +818,7 @@ err_out: return ret; } -static int __devexit max8998_pmic_remove(struct platform_device *pdev) +static int max8998_pmic_remove(struct platform_device *pdev) { struct max8998_data *max8998 = platform_get_drvdata(pdev); struct regulator_dev **rdev = max8998->rdev; diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 54f42b3..c46c670 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -445,7 +445,7 @@ err: return ret; } -static int __devexit mc13783_regulator_remove(struct platform_device *pdev) +static int mc13783_regulator_remove(struct platform_device *pdev) { struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); struct mc13xxx_regulator_platform_data *pdata = diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index 9804a31..0d84b1f 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -588,7 +588,7 @@ err_unlock: return ret; } -static int __devexit mc13892_regulator_remove(struct platform_device *pdev) +static int mc13892_regulator_remove(struct platform_device *pdev) { struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); int i; diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index b047744..3d44592 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -868,7 +868,7 @@ err_unregister_regulator: return ret; } -static int __devexit palmas_remove(struct platform_device *pdev) +static int palmas_remove(struct platform_device *pdev) { struct palmas_pmic *pmic = platform_get_drvdata(pdev); int id; diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c index 4f3e445..4899342 100644 --- a/drivers/regulator/pcap-regulator.c +++ b/drivers/regulator/pcap-regulator.c @@ -255,7 +255,7 @@ static int pcap_regulator_probe(struct platform_device *pdev) return 0; } -static int __devexit pcap_regulator_remove(struct platform_device *pdev) +static int pcap_regulator_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 51cb1bb..d776f51 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c @@ -222,7 +222,7 @@ static int pcf50633_regulator_probe(struct platform_device *pdev) return 0; } -static int __devexit pcf50633_regulator_remove(struct platform_device *pdev) +static int pcf50633_regulator_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index 7f83f33..9e6f786 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -198,7 +198,7 @@ clean_exit: return ret; } -static int __devexit rc5t583_regulator_remove(struct platform_device *pdev) +static int rc5t583_regulator_remove(struct platform_device *pdev) { struct rc5t583_regulator *regs = platform_get_drvdata(pdev); int id; diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index c918e99..85fc086 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -307,7 +307,7 @@ err: return ret; } -static int __devexit s2mps11_pmic_remove(struct platform_device *pdev) +static int s2mps11_pmic_remove(struct platform_device *pdev) { struct s2mps11_info *s2mps11 = platform_get_drvdata(pdev); int i; diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 15f3cca..2b822be 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -773,7 +773,7 @@ err: return ret; } -static int __devexit s5m8767_pmic_remove(struct platform_device *pdev) +static int s5m8767_pmic_remove(struct platform_device *pdev) { struct s5m8767_info *s5m8767 = platform_get_drvdata(pdev); struct regulator_dev **rdev = s5m8767->rdev; diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index ff79a46..a9c3a4a 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c @@ -290,7 +290,7 @@ static int tps51632_probe(struct i2c_client *client, return 0; } -static int __devexit tps51632_remove(struct i2c_client *client) +static int tps51632_remove(struct i2c_client *client) { struct tps51632_chip *tps = i2c_get_clientdata(client); diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index f8c0c92..ec9453f 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c @@ -159,7 +159,7 @@ static int tps6105x_regulator_probe(struct platform_device *pdev) return 0; } -static int __devexit tps6105x_regulator_remove(struct platform_device *pdev) +static int tps6105x_regulator_remove(struct platform_device *pdev) { struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev); regulator_unregister(tps6105x->regulator); diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index 7fba9ff..acbd63f 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -490,7 +490,7 @@ static int tps62360_probe(struct i2c_client *client, * * Unregister TPS driver as an i2c client device driver */ -static int __devexit tps62360_remove(struct i2c_client *client) +static int tps62360_remove(struct i2c_client *client) { struct tps62360_chip *tps = i2c_get_clientdata(client); diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index a039206..9b9af6d 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -319,7 +319,7 @@ static int tps_65023_probe(struct i2c_client *client, return error; } -static int __devexit tps_65023_remove(struct i2c_client *client) +static int tps_65023_remove(struct i2c_client *client) { struct tps_pmic *tps = i2c_get_clientdata(client); int i; diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 6c45d5a..0233cfb 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -439,7 +439,7 @@ fail: return error; } -static int __devexit tps6507x_pmic_remove(struct platform_device *pdev) +static int tps6507x_pmic_remove(struct platform_device *pdev) { struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); struct tps6507x_pmic *tps = tps6507x_dev->pmic; diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index cc5be1f..3974a99 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -232,7 +232,7 @@ scrub: return ret; } -static int __devexit tps65090_regulator_remove(struct platform_device *pdev) +static int tps65090_regulator_remove(struct platform_device *pdev) { struct tps65090_regulator *pmic = platform_get_drvdata(pdev); struct tps65090_regulator *ri; diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index e34fb86..73dce76 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -397,7 +397,7 @@ err_unregister_regulator: return ret; } -static int __devexit tps65217_regulator_remove(struct platform_device *pdev) +static int tps65217_regulator_remove(struct platform_device *pdev) { struct tps65217 *tps = platform_get_drvdata(pdev); unsigned int i; diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 7206f4e..9ce4410 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -461,7 +461,7 @@ fail: return err; } -static int __devexit tps6586x_regulator_remove(struct platform_device *pdev) +static int tps6586x_regulator_remove(struct platform_device *pdev) { struct regulator_dev **rdev = platform_get_drvdata(pdev); int id = TPS6586X_ID_MAX_REGULATOR; diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 276eeb5..6b77bbf 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -1184,7 +1184,7 @@ err_unregister_regulator: return err; } -static int __devexit tps65910_remove(struct platform_device *pdev) +static int tps65910_remove(struct platform_device *pdev) { struct tps65910_reg *pmic = platform_get_drvdata(pdev); int i; diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index 35b2a6f..17e994e 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c @@ -525,7 +525,7 @@ err: return err; } -static int __devexit tps65912_remove(struct platform_device *pdev) +static int tps65912_remove(struct platform_device *pdev) { struct tps65912_reg *tps65912_reg = platform_get_drvdata(pdev); int i; diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index cdfcbc9..127d175 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -753,7 +753,7 @@ fail: return ret; } -static int __devexit tps80031_regulator_remove(struct platform_device *pdev) +static int tps80031_regulator_remove(struct platform_device *pdev) { struct tps80031_regulator *pmic = platform_get_drvdata(pdev); struct tps80031_regulator *ri = NULL; diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 66e62a2..493c8c6 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -1241,7 +1241,7 @@ static int twlreg_probe(struct platform_device *pdev) return 0; } -static int __devexit twlreg_remove(struct platform_device *pdev) +static int twlreg_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); struct twlreg_info *info = rdev->reg_data; diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c index 4056201..4668c7f 100644 --- a/drivers/regulator/vexpress.c +++ b/drivers/regulator/vexpress.c @@ -114,7 +114,7 @@ error_kzalloc: return err; } -static int __devexit vexpress_regulator_remove(struct platform_device *pdev) +static int vexpress_regulator_remove(struct platform_device *pdev) { struct vexpress_regulator *reg = platform_get_drvdata(pdev); diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c index be0dd18..01c66e9 100644 --- a/drivers/regulator/virtual.c +++ b/drivers/regulator/virtual.c @@ -321,7 +321,7 @@ static int regulator_virtual_probe(struct platform_device *pdev) return 0; } -static int __devexit regulator_virtual_remove(struct platform_device *pdev) +static int regulator_virtual_remove(struct platform_device *pdev) { struct virtual_consumer_data *drvdata = platform_get_drvdata(pdev); diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 54e9778..33297bc 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -562,7 +562,7 @@ err: return ret; } -static __devexit int wm831x_buckv_remove(struct platform_device *pdev) +static int wm831x_buckv_remove(struct platform_device *pdev) { struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); struct wm831x *wm831x = dcdc->wm831x; @@ -710,7 +710,7 @@ err: return ret; } -static __devexit int wm831x_buckp_remove(struct platform_device *pdev) +static int wm831x_buckp_remove(struct platform_device *pdev) { struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); @@ -845,7 +845,7 @@ err: return ret; } -static __devexit int wm831x_boostp_remove(struct platform_device *pdev) +static int wm831x_boostp_remove(struct platform_device *pdev) { struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); @@ -936,7 +936,7 @@ err: return ret; } -static __devexit int wm831x_epe_remove(struct platform_device *pdev) +static int wm831x_epe_remove(struct platform_device *pdev) { struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index ac4bdff..68586ee 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -221,7 +221,7 @@ err: return ret; } -static __devexit int wm831x_isink_remove(struct platform_device *pdev) +static int wm831x_isink_remove(struct platform_device *pdev) { struct wm831x_isink *isink = platform_get_drvdata(pdev); diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 90f657f..1ec379a 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -334,7 +334,7 @@ err: return ret; } -static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev) +static int wm831x_gp_ldo_remove(struct platform_device *pdev) { struct wm831x_ldo *ldo = platform_get_drvdata(pdev); @@ -590,7 +590,7 @@ err: return ret; } -static __devexit int wm831x_aldo_remove(struct platform_device *pdev) +static int wm831x_aldo_remove(struct platform_device *pdev) { struct wm831x_ldo *ldo = platform_get_drvdata(pdev); @@ -737,7 +737,7 @@ err: return ret; } -static __devexit int wm831x_alive_ldo_remove(struct platform_device *pdev) +static int wm831x_alive_ldo_remove(struct platform_device *pdev) { struct wm831x_ldo *ldo = platform_get_drvdata(pdev); diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index c155ec3..c6a32ea 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -246,7 +246,7 @@ static int wm8400_regulator_probe(struct platform_device *pdev) return 0; } -static int __devexit wm8400_regulator_remove(struct platform_device *pdev) +static int wm8400_regulator_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index ea0fdd5..6ff8723 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -142,7 +142,7 @@ err: return ret; } -static __devexit int wm8994_ldo_remove(struct platform_device *pdev) +static int wm8994_ldo_remove(struct platform_device *pdev) { struct wm8994_ldo *ldo = platform_get_drvdata(pdev); -- cgit v0.10.2 From 369cf602f364a60c72b8258c21eca8793939328f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 20 Nov 2012 15:36:46 +0800 Subject: regulator: da9055: Properly handle voltage range that doesn't start with 0 offset This patch implements map_voltage and list_voltage callbacks to properly handle the case voltage range that doesn't start with 0 offset. Now we adjust the selector in map_voltage() before calling set_voltage_sel(). And return 0 in list_voltage() for invalid selectors. With above change, we can remove da9055_regulator_set_voltage_bits function. One tricky part is that we need adding voffset to n_voltages. Although for the cases "selector < voffset" are invalid, we need add voffset to n_voltage so regulator_list_voltage() won't fail while checking the boundary for selector before calling list_voltage callback. Signed-off-by: Axel Lin Tested-by: Ashish Jangam Signed-off-by: Mark Brown diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 79c5665..121564b 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -204,6 +204,41 @@ static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA, info->mode.mask, val << info->mode.shift); } +static int da9055_list_voltage(struct regulator_dev *rdev, unsigned selector) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + + if (selector >= rdev->desc->n_voltages) + return -EINVAL; + + if (selector < info->volt.v_offset) + return 0; + + selector -= info->volt.v_offset; + return rdev->desc->min_uV + (rdev->desc->uV_step * selector); +} + +static int da9055_map_voltage(struct regulator_dev *rdev, int min_uV, + int max_uV) +{ + struct da9055_regulator *regulator = rdev_get_drvdata(rdev); + struct da9055_regulator_info *info = regulator->info; + int sel, voltage; + + if (min_uV < rdev->desc->min_uV) + min_uV = rdev->desc->min_uV; + + sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); + sel += info->volt.v_offset; + + voltage = da9055_list_voltage(rdev, sel); + if (voltage < min_uV || voltage > max_uV) + return -EINVAL; + + return sel; +} + static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) { struct da9055_regulator *regulator = rdev_get_drvdata(rdev); @@ -238,22 +273,6 @@ static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) return sel; } -static int da9055_regulator_set_voltage_bits(struct regulator_dev *rdev, - unsigned int reg, - unsigned int selector) -{ - struct da9055_regulator *regulator = rdev_get_drvdata(rdev); - struct da9055_regulator_info *info = regulator->info; - - /* Takes care of voltage range that does not start with 0 offset. */ - selector += info->volt.v_offset; - - /* Set the voltage */ - return da9055_reg_update(regulator->da9055, reg, info->volt.v_mask, - selector); - -} - static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector) { @@ -273,8 +292,8 @@ static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, return ret; /* Set the voltage */ - return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_a, - selector); + return da9055_reg_update(regulator->da9055, info->volt.reg_a, + info->volt.v_mask, selector); } /* @@ -290,11 +309,11 @@ static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, /* Set the voltage */ if (ret == DA9055_REGUALTOR_SET_A) - return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_a, - selector); + return da9055_reg_update(regulator->da9055, info->volt.reg_a, + info->volt.v_mask, selector); else - return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_b, - selector); + return da9055_reg_update(regulator->da9055, info->volt.reg_b, + info->volt.v_mask, selector); } static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev, @@ -312,11 +331,12 @@ static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev, return ret; } - ret = regulator_map_voltage_linear(rdev, uV, uV); + ret = da9055_map_voltage(rdev, uV, uV); if (ret < 0) return ret; - return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_b, ret); + return da9055_reg_update(regulator->da9055, info->volt.reg_b, + info->volt.v_mask, ret); } static int da9055_suspend_enable(struct regulator_dev *rdev) @@ -354,8 +374,8 @@ static struct regulator_ops da9055_buck_ops = { .get_voltage_sel = da9055_regulator_get_voltage_sel, .set_voltage_sel = da9055_regulator_set_voltage_sel, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .list_voltage = da9055_list_voltage, + .map_voltage = da9055_map_voltage, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -372,8 +392,8 @@ static struct regulator_ops da9055_ldo_ops = { .get_voltage_sel = da9055_regulator_get_voltage_sel, .set_voltage_sel = da9055_regulator_set_voltage_sel, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .list_voltage = da9055_list_voltage, + .map_voltage = da9055_map_voltage, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -392,7 +412,7 @@ static struct regulator_ops da9055_ldo_ops = { .ops = &da9055_ldo_ops,\ .type = REGULATOR_VOLTAGE,\ .id = DA9055_ID_##_id,\ - .n_voltages = (max - min) / step + 1, \ + .n_voltages = (max - min) / step + 1 + (voffset), \ .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ .enable_mask = 1, \ .min_uV = (min) * 1000,\ @@ -421,7 +441,7 @@ static struct regulator_ops da9055_ldo_ops = { .ops = &da9055_buck_ops,\ .type = REGULATOR_VOLTAGE,\ .id = DA9055_ID_##_id,\ - .n_voltages = (max - min) / step + 1, \ + .n_voltages = (max - min) / step + 1 + (voffset), \ .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ .enable_mask = 1,\ .min_uV = (min) * 1000,\ -- cgit v0.10.2 From 1a8f85d402a2bf3b86c08c696a0adf36656f770a Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Tue, 20 Nov 2012 18:07:41 +0100 Subject: regulator: add missing prototype for regulator_is_supported_voltage avoids needs for CONFIG_REGULATOR in sdhci.c Signed-off-by: Philip Rakity Reviewed-by: Eric Miao Signed-off-by: Eric Miao Signed-off-by: Mark Brown diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index c43cd35..4e3ec91 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -358,6 +358,10 @@ static inline void regulator_set_drvdata(struct regulator *regulator, { } +static inline int regulator_count_voltages(struct regulator *regulator) +{ + return 0; +} #endif static inline int regulator_set_voltage_tol(struct regulator *regulator, -- cgit v0.10.2 From e05f70c2686004df9794a3ec426d16009062b749 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 22 Nov 2012 09:47:08 +0800 Subject: regulator: max8973: Fix callback setting for max8973_dcdc_ops.enable Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index e6328f9..140ff9d 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c @@ -401,7 +401,7 @@ static int __devinit max8973_probe(struct i2c_client *client, if (pdata->enable_ext_control) { max->desc.enable_reg = MAX8973_VOUT; max->desc.enable_mask = MAX8973_VOUT_ENABLE; - max8973_dcdc_ops.enable = regulator_is_enabled_regmap; + max8973_dcdc_ops.enable = regulator_enable_regmap; max8973_dcdc_ops.disable = regulator_disable_regmap; max8973_dcdc_ops.is_enabled = regulator_is_enabled_regmap; } -- cgit v0.10.2 From 1a7ae58e2c5feb2c0f35e773223949a8fa672433 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 22 Nov 2012 16:30:44 +0800 Subject: regulator: tps80031: Trivial cleanups This patch includes below cleanups: - Fix typo in comment - Fix showing wrong register in dev_err - Remove unnecessary rinfo variable - Add TPS80032 to MODULE_DESCRIPTION Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index a37ede8..aaab3d7 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -1,7 +1,7 @@ /* * tps80031-regulator.c -- TI TPS80031 regulator driver. * - * Regulator driver for TITPS80031/TPS80032 Fully Integrated Power + * Regulator driver for TI TPS80031/TPS80032 Fully Integrated Power * Management with Power Path and Battery Charger. * * Copyright (c) 2012, NVIDIA Corporation. @@ -311,7 +311,7 @@ static int tps80031_vbus_is_enabled(struct regulator_dev *rdev) TPS80031_CHARGERUSB_CTRL3, &ctrl3); if (ret < 0) { dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", - TPS80031_CHARGERUSB_CTRL1, ret); + TPS80031_CHARGERUSB_CTRL3, ret); return ret; } if ((ctrl1 & OPA_MODE_EN) && (ctrl3 & BOOST_HW_PWR_EN)) @@ -679,7 +679,6 @@ static int __devinit tps80031_regulator_probe(struct platform_device *pdev) { struct tps80031_platform_data *pdata; struct tps80031_regulator_platform_data *tps_pdata; - struct tps80031_regulator_info *rinfo; struct tps80031_regulator *ri; struct tps80031_regulator *pmic; struct regulator_dev *rdev; @@ -703,9 +702,8 @@ static int __devinit tps80031_regulator_probe(struct platform_device *pdev) for (num = 0; num < TPS80031_REGULATOR_MAX; ++num) { tps_pdata = pdata->regulator_pdata[num]; - rinfo = &tps80031_rinfo[num]; ri = &pmic[num]; - ri->rinfo = rinfo; + ri->rinfo = &tps80031_rinfo[num]; ri->dev = &pdev->dev; check_smps_mode_mult(pdev->dev.parent, ri); @@ -788,6 +786,6 @@ static void __exit tps80031_regulator_exit(void) module_exit(tps80031_regulator_exit); MODULE_ALIAS("platform:tps80031-regulator"); -MODULE_DESCRIPTION("Regulator Driver for TI TPS80031 PMIC"); +MODULE_DESCRIPTION("Regulator Driver for TI TPS80031/TPS80032 PMIC"); MODULE_AUTHOR("Laxman Dewangan "); MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From bf0caae3036563ef84d1dcb7b2c7fcbda59a889d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 23 Nov 2012 09:25:54 +0800 Subject: regulator: tps80031: Implement list_voltage and set n_voltages = 1 for fixed regulators Implement list_voltage for fixed regulators, otherwise regulator_is_supported_voltage() returns 0. Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index aaab3d7..ce48049 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -407,15 +407,18 @@ static struct regulator_ops tps80031_ldo_ops = { }; static struct regulator_ops tps80031_vbus_sw_ops = { + .list_voltage = regulator_list_voltage_linear, .enable = tps80031_vbus_enable, .disable = tps80031_vbus_disable, .is_enabled = tps80031_vbus_is_enabled, }; static struct regulator_ops tps80031_vbus_hw_ops = { + .list_voltage = regulator_list_voltage_linear, }; static struct regulator_ops tps80031_ext_reg_ops = { + .list_voltage = regulator_list_voltage_linear, .enable = tps80031_reg_enable, .disable = tps80031_reg_disable, .is_enabled = tps80031_reg_is_enabled, @@ -477,7 +480,8 @@ static struct regulator_ops tps80031_ext_reg_ops = { .desc = { \ .name = "tps80031_"#_id, \ .id = TPS80031_REGULATOR_##_id, \ - .n_voltages = 2, \ + .min_uV = max_mV * 1000, \ + .n_voltages = 1, \ .ops = &_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ -- cgit v0.10.2 From f1e64f90269c197a0619535917210543c0112fcc Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 22 Nov 2012 11:12:08 +0100 Subject: regulator: add a regulator driver for the AS3711 PMIC This driver supports the 4 DCDC and 8 LDO regulators on the AS3711 PMIC. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mark Brown diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 67d47b59..f73d6f5 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -450,5 +450,12 @@ config REGULATOR_WM8994 This driver provides support for the voltage regulators on the WM8994 CODEC. +config REGULATOR_AS3711 + tristate "AS3711 PMIC" + depends on MFD_AS3711 + help + This driver provides support for the voltage regulators on the + AS3711 PMIC + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e431eed..c1557ac 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o +obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c new file mode 100644 index 0000000..81578bf --- /dev/null +++ b/drivers/regulator/as3711-regulator.c @@ -0,0 +1,379 @@ +/* + * AS3711 PMIC regulator driver, using DCDC Step Down and LDO supplies + * + * Copyright (C) 2012 Renesas Electronics Corporation + * Author: Guennadi Liakhovetski, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the version 2 of the GNU General Public License as + * published by the Free Software Foundation + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct as3711_regulator_info { + struct regulator_desc desc; + unsigned int max_uV; +}; + +struct as3711_regulator { + struct as3711_regulator_info *reg_info; + struct regulator_dev *rdev; +}; + +static int as3711_list_voltage_sd(struct regulator_dev *rdev, + unsigned int selector) +{ + if (selector >= rdev->desc->n_voltages) + return -EINVAL; + + if (!selector) + return 0; + if (selector < 0x41) + return 600000 + selector * 12500; + if (selector < 0x71) + return 1400000 + (selector - 0x40) * 25000; + return 2600000 + (selector - 0x70) * 50000; +} + +static int as3711_list_voltage_aldo(struct regulator_dev *rdev, + unsigned int selector) +{ + if (selector >= rdev->desc->n_voltages) + return -EINVAL; + + if (selector < 0x10) + return 1200000 + selector * 50000; + return 1800000 + (selector - 0x10) * 100000; +} + +static int as3711_list_voltage_dldo(struct regulator_dev *rdev, + unsigned int selector) +{ + if (selector >= rdev->desc->n_voltages || + (selector > 0x10 && selector < 0x20)) + return -EINVAL; + + if (selector < 0x11) + return 900000 + selector * 50000; + return 1750000 + (selector - 0x20) * 50000; +} + +static int as3711_bound_check(struct regulator_dev *rdev, + int *min_uV, int *max_uV) +{ + struct as3711_regulator_info *info = container_of(rdev->desc, + struct as3711_regulator_info, desc); + struct as3711_regulator *reg = rdev->reg_data; + + WARN_ON(reg->reg_info != info); + + dev_dbg(&rdev->dev, "%s(), %d, %d, %d\n", __func__, + *min_uV, rdev->desc->min_uV, info->max_uV); + + if (*max_uV < *min_uV || + *min_uV >= info->max_uV || rdev->desc->min_uV >= *max_uV) + return -EINVAL; + + if (rdev->desc->n_voltages == 1) + return 0; + + if (*max_uV > info->max_uV) + *max_uV = info->max_uV; + + if (*min_uV < rdev->desc->min_uV) + *min_uV = rdev->desc->min_uV; + + return *min_uV; +} + +static int as3711_sel_check(int min, int max, int bottom, int step) +{ + int ret, voltage; + + /* Round up min, when dividing: keeps us within the range */ + ret = (min - bottom + step - 1) / step; + voltage = ret * step + bottom; + pr_debug("%s(): select %d..%d in %d+N*%d: %d\n", __func__, + min, max, bottom, step, ret); + if (voltage > max) { + /* + * Try 1 down. It will take us below min, but as long we stay + * above bottom, we're fine. + */ + ret--; + voltage = ret * step + bottom; + if (voltage < bottom) + return -EINVAL; + } + return ret; +} + +static int as3711_map_voltage_sd(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + int ret; + + ret = as3711_bound_check(rdev, &min_uV, &max_uV); + if (ret <= 0) + return ret; + + if (min_uV <= 1400000) + return as3711_sel_check(min_uV, max_uV, 600000, 12500); + + if (min_uV <= 2600000) + return as3711_sel_check(min_uV, max_uV, 1400000, 25000) + 0x40; + + return as3711_sel_check(min_uV, max_uV, 2600000, 50000) + 0x70; +} + +/* + * The regulator API supports 4 modes of operataion: FAST, NORMAL, IDLE and + * STANDBY. We map them in the following way to AS3711 SD1-4 DCDC modes: + * FAST: sdX_fast=1 + * NORMAL: low_noise=1 + * IDLE: low_noise=0 + */ + +static int as3711_set_mode_sd(struct regulator_dev *rdev, unsigned int mode) +{ + unsigned int fast_bit = rdev->desc->enable_mask, + low_noise_bit = fast_bit << 4; + u8 val; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = fast_bit | low_noise_bit; + break; + case REGULATOR_MODE_NORMAL: + val = low_noise_bit; + break; + case REGULATOR_MODE_IDLE: + val = 0; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(rdev->regmap, AS3711_SD_CONTROL_1, + low_noise_bit | fast_bit, val); +} + +static unsigned int as3711_get_mode_sd(struct regulator_dev *rdev) +{ + unsigned int fast_bit = rdev->desc->enable_mask, + low_noise_bit = fast_bit << 4, mask = fast_bit | low_noise_bit; + unsigned int val; + int ret = regmap_read(rdev->regmap, AS3711_SD_CONTROL_1, &val); + + if (ret < 0) + return ret; + + if ((val & mask) == mask) + return REGULATOR_MODE_FAST; + + if ((val & mask) == low_noise_bit) + return REGULATOR_MODE_NORMAL; + + if (!(val & mask)) + return REGULATOR_MODE_IDLE; + + return -EINVAL; +} + +static int as3711_map_voltage_aldo(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + int ret; + + ret = as3711_bound_check(rdev, &min_uV, &max_uV); + if (ret <= 0) + return ret; + + if (min_uV <= 1800000) + return as3711_sel_check(min_uV, max_uV, 1200000, 50000); + + return as3711_sel_check(min_uV, max_uV, 1800000, 100000) + 0x10; +} + +static int as3711_map_voltage_dldo(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + int ret; + + ret = as3711_bound_check(rdev, &min_uV, &max_uV); + if (ret <= 0) + return ret; + + if (min_uV <= 1700000) + return as3711_sel_check(min_uV, max_uV, 900000, 50000); + + return as3711_sel_check(min_uV, max_uV, 1750000, 50000) + 0x20; +} + +static struct regulator_ops as3711_sd_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = as3711_list_voltage_sd, + .map_voltage = as3711_map_voltage_sd, + .get_mode = as3711_get_mode_sd, + .set_mode = as3711_set_mode_sd, +}; + +static struct regulator_ops as3711_aldo_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = as3711_list_voltage_aldo, + .map_voltage = as3711_map_voltage_aldo, +}; + +static struct regulator_ops as3711_dldo_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = as3711_list_voltage_dldo, + .map_voltage = as3711_map_voltage_dldo, +}; + +#define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _vshift, _min_uV, _max_uV, _sfx) \ + [AS3711_REGULATOR_ ## _id] = { \ + .desc = { \ + .name = "as3711-regulator-" # _id, \ + .id = AS3711_REGULATOR_ ## _id, \ + .n_voltages = (_vmask + 1), \ + .ops = &as3711_ ## _sfx ## _ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .vsel_reg = AS3711_ ## _id ## _VOLTAGE, \ + .vsel_mask = _vmask << _vshift, \ + .enable_reg = AS3711_ ## _en_reg, \ + .enable_mask = BIT(_en_bit), \ + .min_uV = _min_uV, \ + }, \ + .max_uV = _max_uV, \ +} + +static struct as3711_regulator_info as3711_reg_info[] = { + AS3711_REG(SD_1, SD_CONTROL, 0, 0x7f, 0, 612500, 3350000, sd), + AS3711_REG(SD_2, SD_CONTROL, 1, 0x7f, 0, 612500, 3350000, sd), + AS3711_REG(SD_3, SD_CONTROL, 2, 0x7f, 0, 612500, 3350000, sd), + AS3711_REG(SD_4, SD_CONTROL, 3, 0x7f, 0, 612500, 3350000, sd), + AS3711_REG(LDO_1, LDO_1_VOLTAGE, 7, 0x1f, 0, 1200000, 3300000, aldo), + AS3711_REG(LDO_2, LDO_2_VOLTAGE, 7, 0x1f, 0, 1200000, 3300000, aldo), + AS3711_REG(LDO_3, LDO_3_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), + AS3711_REG(LDO_4, LDO_4_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), + AS3711_REG(LDO_5, LDO_5_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), + AS3711_REG(LDO_6, LDO_6_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), + AS3711_REG(LDO_7, LDO_7_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), + AS3711_REG(LDO_8, LDO_8_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo), + /* StepUp output voltage depends on supplying regulator */ +}; + +#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_info) + +static int as3711_regulator_probe(struct platform_device *pdev) +{ + struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev); + struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent); + struct regulator_init_data *reg_data; + struct regulator_config config = {.dev = &pdev->dev,}; + struct as3711_regulator *reg = NULL; + struct as3711_regulator *regs; + struct regulator_dev *rdev; + struct as3711_regulator_info *ri; + int ret; + int id; + + if (!pdata) + dev_dbg(&pdev->dev, "No platform data...\n"); + + regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM * + sizeof(struct as3711_regulator), GFP_KERNEL); + if (!regs) { + dev_err(&pdev->dev, "Memory allocation failed exiting..\n"); + return -ENOMEM; + } + + for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) { + reg_data = pdata ? pdata->init_data[id] : NULL; + + /* No need to register if there is no regulator data */ + if (!ri->desc.name) + continue; + + reg = ®s[id]; + reg->reg_info = ri; + + config.init_data = reg_data; + config.driver_data = reg; + config.regmap = as3711->regmap; + + rdev = regulator_register(&ri->desc, &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "Failed to register regulator %s\n", + ri->desc.name); + ret = PTR_ERR(rdev); + goto eregreg; + } + reg->rdev = rdev; + } + platform_set_drvdata(pdev, regs); + return 0; + +eregreg: + while (--id >= 0) + regulator_unregister(regs[id].rdev); + + return ret; +} + +static int as3711_regulator_remove(struct platform_device *pdev) +{ + struct as3711_regulator *regs = platform_get_drvdata(pdev); + int id; + + for (id = 0; id < AS3711_REGULATOR_NUM; ++id) + regulator_unregister(regs[id].rdev); + return 0; +} + +static struct platform_driver as3711_regulator_driver = { + .driver = { + .name = "as3711-regulator", + .owner = THIS_MODULE, + }, + .probe = as3711_regulator_probe, + .remove = as3711_regulator_remove, +}; + +static int __init as3711_regulator_init(void) +{ + return platform_driver_register(&as3711_regulator_driver); +} +subsys_initcall(as3711_regulator_init); + +static void __exit as3711_regulator_exit(void) +{ + platform_driver_unregister(&as3711_regulator_driver); +} +module_exit(as3711_regulator_exit); + +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_DESCRIPTION("AS3711 regulator driver"); +MODULE_ALIAS("platform:as3711-regulator"); +MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From 56968658ff8564e9f264b4bcb4f2ab98f70146a2 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 23 Nov 2012 14:07:42 +0530 Subject: regulator: max8973: provide enable/disable if external control disabled If external control is enabled then do not provide regulator enable/disable apis. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index 140ff9d..3ee2638 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c @@ -398,7 +398,7 @@ static int __devinit max8973_probe(struct i2c_client *client, max->desc.uV_step = MAX8973_VOLATGE_STEP; max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE; - if (pdata->enable_ext_control) { + if (!pdata->enable_ext_control) { max->desc.enable_reg = MAX8973_VOUT; max->desc.enable_mask = MAX8973_VOUT_ENABLE; max8973_dcdc_ops.enable = regulator_enable_regmap; -- cgit v0.10.2 From d95420b8602c7302cd19881cda23c61e456e2294 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 23 Nov 2012 23:47:16 +0800 Subject: regulator: tps65090: Add MODULE_ALIAS This driver can be built as a module, add MODULE_ALIAS for it. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 4124138..1ef8eb6 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -269,3 +269,4 @@ module_exit(tps65090_regulator_exit); MODULE_DESCRIPTION("tps65090 regulator driver"); MODULE_AUTHOR("Venu Byravarasu "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:tps65090-pmic"); -- cgit v0.10.2 From 11ec7bf001e7bfd37f244042032e15dac2c301bc Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 23 Nov 2012 13:33:13 +0530 Subject: regulator: max8997: reorder buck1/2/5 dvs setup code The BUCKxDVSx register programming is now moved prior to setting up of the gpio based dvs mode. This will ensure that all the BUCKxDVSx registers are programmed with appropriate voltage values before the gpio based dvs mode is selected for buck1/2/5. Signed-off-by: Thomas Abraham Reviewed-by: Tomasz Figa Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index e39a0c7..04d9f29 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -1019,6 +1019,19 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) max_buck5, 0x3f); } + /* Initialize all the DVS related BUCK registers */ + for (i = 0; i < 8; i++) { + max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i, + max8997->buck1_vol[i], + 0x3f); + max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i, + max8997->buck2_vol[i], + 0x3f); + max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i, + max8997->buck5_vol[i], + 0x3f); + } + /* * If buck 1, 2, and 5 do not care DVS GPIO settings, ignore them. * If at least one of them cares, set gpios. @@ -1068,19 +1081,6 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) max8997_update_reg(i2c, MAX8997_REG_BUCK5CTRL, (pdata->buck5_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); - /* Initialize all the DVS related BUCK registers */ - for (i = 0; i < 8; i++) { - max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i, - max8997->buck1_vol[i], - 0x3f); - max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i, - max8997->buck2_vol[i], - 0x3f); - max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i, - max8997->buck5_vol[i], - 0x3f); - } - /* Misc Settings */ max8997->ramp_delay = 10; /* set 10mV/us, which is the default */ max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9); -- cgit v0.10.2 From 068a8c8239d50a5fd025c97f94945d9f2ffa3438 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 23 Nov 2012 13:33:14 +0530 Subject: regulator: max8997: limit the number of dvs registers programmed in non-dvs mode In case the gpio based volatage selection mode is not used for either of buck 1/2/5, then only the BUCKxDVS1 register need to be programmed. So determine whether dvs mode is used and limit the loop count appropriately. Signed-off-by: Thomas Abraham Reviewed-by: Tomasz Figa Signed-off-by: Mark Brown diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 04d9f29..64cf2ee 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -941,7 +941,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) struct regulator_dev **rdev; struct max8997_data *max8997; struct i2c_client *i2c; - int i, ret, size; + int i, ret, size, nr_dvs; u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0; if (!pdata) { @@ -973,7 +973,10 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) memcpy(max8997->buck125_gpios, pdata->buck125_gpios, sizeof(int) * 3); max8997->ignore_gpiodvs_side_effect = pdata->ignore_gpiodvs_side_effect; - for (i = 0; i < 8; i++) { + nr_dvs = (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs || + pdata->buck5_gpiodvs) ? 8 : 1; + + for (i = 0; i < nr_dvs; i++) { max8997->buck1_vol[i] = ret = max8997_get_voltage_proper_val( &buck1245_voltage_map_desc, @@ -1020,7 +1023,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) } /* Initialize all the DVS related BUCK registers */ - for (i = 0; i < 8; i++) { + for (i = 0; i < nr_dvs; i++) { max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i, max8997->buck1_vol[i], 0x3f); -- cgit v0.10.2 From 77b71b370ed06c75bdebef09be438d5275f70fc1 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Tue, 27 Nov 2012 14:04:32 +0530 Subject: regulator: add device tree support for max8997 Add device tree based discovery support for max8997. Signed-off-by: Thomas Abraham Acked-by: MyungJoo Ham Reviewed-by: Tomasz Figa Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/regulator/max8997-regulator.txt b/Documentation/devicetree/bindings/regulator/max8997-regulator.txt new file mode 100644 index 0000000..9fd69a1 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/max8997-regulator.txt @@ -0,0 +1,146 @@ +* Maxim MAX8997 Voltage and Current Regulator + +The Maxim MAX8997 is a multi-function device which includes volatage and +current regulators, rtc, charger controller and other sub-blocks. It is +interfaced to the host controller using a i2c interface. Each sub-block is +addressed by the host system using different i2c slave address. This document +describes the bindings for 'pmic' sub-block of max8997. + +Required properties: +- compatible: Should be "maxim,max8997-pmic". +- reg: Specifies the i2c slave address of the pmic block. It should be 0x66. + +- max8997,pmic-buck1-dvs-voltage: A set of 8 voltage values in micro-volt (uV) + units for buck1 when changing voltage using gpio dvs. Refer to [1] below + for additional information. + +- max8997,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV) + units for buck2 when changing voltage using gpio dvs. Refer to [1] below + for additional information. + +- max8997,pmic-buck5-dvs-voltage: A set of 8 voltage values in micro-volt (uV) + units for buck5 when changing voltage using gpio dvs. Refer to [1] below + for additional information. + +[1] If none of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional + property is specified, the 'max8997,pmic-buck[1/2/5]-dvs-voltage' + property should specify atleast one voltage level (which would be a + safe operating voltage). + + If either of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional + property is specified, then all the eigth voltage values for the + 'max8997,pmic-buck[1/2/5]-dvs-voltage' should be specified. + +Optional properties: +- interrupt-parent: Specifies the phandle of the interrupt controller to which + the interrupts from max8997 are delivered to. +- interrupts: Interrupt specifiers for two interrupt sources. + - First interrupt specifier is for 'irq1' interrupt. + - Second interrupt specifier is for 'alert' interrupt. +- max8997,pmic-buck1-uses-gpio-dvs: 'buck1' can be controlled by gpio dvs. +- max8997,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs. +- max8997,pmic-buck5-uses-gpio-dvs: 'buck5' can be controlled by gpio dvs. + +Additional properties required if either of the optional properties are used: +- max8997,pmic-ignore-gpiodvs-side-effect: When GPIO-DVS mode is used for + multiple bucks, changing the voltage value of one of the bucks may affect + that of another buck, which is the side effect of the change (set_voltage). + Use this property to ignore such side effects and change the voltage. + +- max8997,pmic-buck125-default-dvs-idx: Default voltage setting selected from + the possible 8 options selectable by the dvs gpios. The value of this + property should be between 0 and 7. If not specified or if out of range, the + default value of this property is set to 0. + +- max8997,pmic-buck125-dvs-gpios: GPIO specifiers for three host gpio's used + for dvs. The format of the gpio specifier depends in the gpio controller. + +Regulators: The regulators of max8997 that have to be instantiated should be +included in a sub-node named 'regulators'. Regulator nodes included in this +sub-node should be of the format as listed below. + + regulator_name { + standard regulator bindings here + }; + +The following are the names of the regulators that the max8997 pmic block +supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number +as per the datasheet of max8997. + + - LDOn + - valid values for n are 1 to 18 and 21 + - Example: LDO0, LD01, LDO2, LDO21 + - BUCKn + - valid values for n are 1 to 7. + - Example: BUCK1, BUCK2, BUCK3, BUCK7 + + - ENVICHG: Battery Charging Current Monitor Output. This is a fixed + voltage type regulator + + - ESAFEOUT1: (ldo19) + - ESAFEOUT2: (ld020) + + - CHARGER_CV: main battery charger voltage control + - CHARGER: main battery charger current control + - CHARGER_TOPOFF: end of charge current threshold level + +The bindings inside the regulator nodes use the standard regulator bindings +which are documented elsewhere. + +Example: + + max8997_pmic@66 { + compatible = "maxim,max8997-pmic"; + interrupt-parent = <&wakeup_eint>; + reg = <0x66>; + interrupts = <4 0>, <3 0>; + + max8997,pmic-buck1-uses-gpio-dvs; + max8997,pmic-buck2-uses-gpio-dvs; + max8997,pmic-buck5-uses-gpio-dvs; + + max8997,pmic-ignore-gpiodvs-side-effect; + max8997,pmic-buck125-default-dvs-idx = <0>; + + max8997,pmic-buck125-dvs-gpios = <&gpx0 0 1 0 0>, /* SET1 */ + <&gpx0 1 1 0 0>, /* SET2 */ + <&gpx0 2 1 0 0>; /* SET3 */ + + max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>, + <1250000>, <1200000>, + <1150000>, <1100000>, + <1000000>, <950000>; + + max8997,pmic-buck2-dvs-voltage = <1100000>, <1100000>, + <1100000>, <1100000>, + <1000000>, <1000000>, + <1000000>, <1000000>; + + max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>; + + regulators { + ldo1_reg: LDO1 { + regulator-name = "VDD_ABB_3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ldo2_reg: LDO2 { + regulator-name = "VDD_ALIVE_1.1V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + buck1_reg: BUCK1 { + regulator-name = "VDD_ARM_1.2V"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + }; + }; + }; diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index f1235170..abd5c80 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -21,8 +21,10 @@ * This driver is based on max8998.c */ +#include #include #include +#include #include #include #include @@ -47,6 +49,13 @@ static struct mfd_cell max8997_devs[] = { { .name = "max8997-led", .id = 2 }, }; +#ifdef CONFIG_OF +static struct of_device_id __devinitdata max8997_pmic_dt_match[] = { + { .compatible = "maxim,max8997-pmic", .data = TYPE_MAX8997 }, + {}, +}; +#endif + int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) { struct max8997_dev *max8997 = i2c_get_clientdata(i2c); @@ -123,6 +132,58 @@ int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask) } EXPORT_SYMBOL_GPL(max8997_update_reg); +#ifdef CONFIG_OF +/* + * Only the common platform data elements for max8997 are parsed here from the + * device tree. Other sub-modules of max8997 such as pmic, rtc and others have + * to parse their own platform data elements from device tree. + * + * The max8997 platform data structure is instantiated here and the drivers for + * the sub-modules need not instantiate another instance while parsing their + * platform data. + */ +static struct max8997_platform_data *max8997_i2c_parse_dt_pdata( + struct device *dev) +{ + struct max8997_platform_data *pd; + + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); + if (!pd) { + dev_err(dev, "could not allocate memory for pdata\n"); + return ERR_PTR(-ENOMEM); + } + + pd->ono = irq_of_parse_and_map(dev->of_node, 1); + + /* + * ToDo: the 'wakeup' member in the platform data is more of a linux + * specfic information. Hence, there is no binding for that yet and + * not parsed here. + */ + + return pd; +} +#else +static struct max8997_platform_data *max8997_i2c_parse_dt_pdata( + struct device *dev) +{ + return 0; +} +#endif + +static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ +#ifdef CONFIG_OF + if (i2c->dev.of_node) { + const struct of_device_id *match; + match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node); + return (int)match->data; + } +#endif + return (int)id->driver_data; +} + static int max8997_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -137,12 +198,21 @@ static int max8997_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, max8997); max8997->dev = &i2c->dev; max8997->i2c = i2c; - max8997->type = id->driver_data; + max8997->type = max8997_i2c_get_driver_data(i2c, id); max8997->irq = i2c->irq; + if (max8997->dev->of_node) { + pdata = max8997_i2c_parse_dt_pdata(max8997->dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto err; + } + } + if (!pdata) goto err; + max8997->pdata = pdata; max8997->ono = pdata->ono; mutex_init(&max8997->iolock); @@ -434,6 +504,7 @@ static struct i2c_driver max8997_i2c_driver = { .name = "max8997", .owner = THIS_MODULE, .pm = &max8997_pm, + .of_match_table = of_match_ptr(max8997_pmic_dt_match), }, .probe = max8997_i2c_probe, .remove = max8997_i2c_remove, diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 64cf2ee..b56c432 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include struct max8997_data { struct device *dev; @@ -933,10 +935,145 @@ static struct regulator_desc regulators[] = { max8997_charger_fixedstate_ops), }; +#ifdef CONFIG_OF +static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev, + struct max8997_platform_data *pdata, + struct device_node *pmic_np) +{ + int i, gpio; + + for (i = 0; i < 3; i++) { + gpio = of_get_named_gpio(pmic_np, + "max8997,pmic-buck125-dvs-gpios", i); + if (!gpio_is_valid(gpio)) { + dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio); + return -EINVAL; + } + pdata->buck125_gpios[i] = gpio; + } + return 0; +} + +static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, + struct max8997_platform_data *pdata) +{ + struct device_node *pmic_np, *regulators_np, *reg_np; + struct max8997_regulator_data *rdata; + unsigned int i, dvs_voltage_nr = 1, ret; + + pmic_np = iodev->dev->of_node; + if (!pmic_np) { + dev_err(iodev->dev, "could not find pmic sub-node\n"); + return -ENODEV; + } + + regulators_np = of_find_node_by_name(pmic_np, "regulators"); + if (!regulators_np) { + dev_err(iodev->dev, "could not find regulators sub-node\n"); + return -EINVAL; + } + + /* count the number of regulators to be supported in pmic */ + pdata->num_regulators = 0; + for_each_child_of_node(regulators_np, reg_np) + pdata->num_regulators++; + + rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * + pdata->num_regulators, GFP_KERNEL); + if (!rdata) { + dev_err(iodev->dev, "could not allocate memory for " + "regulator data\n"); + return -ENOMEM; + } + + pdata->regulators = rdata; + for_each_child_of_node(regulators_np, reg_np) { + for (i = 0; i < ARRAY_SIZE(regulators); i++) + if (!of_node_cmp(reg_np->name, regulators[i].name)) + break; + + if (i == ARRAY_SIZE(regulators)) { + dev_warn(iodev->dev, "don't know how to configure " + "regulator %s\n", reg_np->name); + continue; + } + + rdata->id = i; + rdata->initdata = of_get_regulator_init_data( + iodev->dev, reg_np); + rdata->reg_node = reg_np; + rdata++; + } + + if (of_get_property(pmic_np, "max8997,pmic-buck1-uses-gpio-dvs", NULL)) + pdata->buck1_gpiodvs = true; + + if (of_get_property(pmic_np, "max8997,pmic-buck2-uses-gpio-dvs", NULL)) + pdata->buck2_gpiodvs = true; + + if (of_get_property(pmic_np, "max8997,pmic-buck5-uses-gpio-dvs", NULL)) + pdata->buck5_gpiodvs = true; + + if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs || + pdata->buck5_gpiodvs) { + ret = max8997_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np); + if (ret) + return -EINVAL; + + if (of_property_read_u32(pmic_np, + "max8997,pmic-buck125-default-dvs-idx", + &pdata->buck125_default_idx)) { + pdata->buck125_default_idx = 0; + } else { + if (pdata->buck125_default_idx >= 8) { + pdata->buck125_default_idx = 0; + dev_info(iodev->dev, "invalid value for " + "default dvs index, using 0 instead\n"); + } + } + + if (of_get_property(pmic_np, + "max8997,pmic-ignore-gpiodvs-side-effect", NULL)) + pdata->ignore_gpiodvs_side_effect = true; + + dvs_voltage_nr = 8; + } + + if (of_property_read_u32_array(pmic_np, + "max8997,pmic-buck1-dvs-voltage", + pdata->buck1_voltage, dvs_voltage_nr)) { + dev_err(iodev->dev, "buck1 voltages not specified\n"); + return -EINVAL; + } + + if (of_property_read_u32_array(pmic_np, + "max8997,pmic-buck2-dvs-voltage", + pdata->buck2_voltage, dvs_voltage_nr)) { + dev_err(iodev->dev, "buck2 voltages not specified\n"); + return -EINVAL; + } + + if (of_property_read_u32_array(pmic_np, + "max8997,pmic-buck5-dvs-voltage", + pdata->buck5_voltage, dvs_voltage_nr)) { + dev_err(iodev->dev, "buck5 voltages not specified\n"); + return -EINVAL; + } + + return 0; +} +#else +static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, + struct max8997_platform_data *pdata) +{ + return 0; +} +#endif /* CONFIG_OF */ + static __devinit int max8997_pmic_probe(struct platform_device *pdev) { struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); - struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); + struct max8997_platform_data *pdata = iodev->pdata; struct regulator_config config = { }; struct regulator_dev **rdev; struct max8997_data *max8997; @@ -944,11 +1081,17 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) int i, ret, size, nr_dvs; u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0; - if (!pdata) { + if (IS_ERR_OR_NULL(pdata)) { dev_err(pdev->dev.parent, "No platform init data supplied.\n"); return -ENODEV; } + if (iodev->dev->of_node) { + ret = max8997_pmic_dt_parse_pdata(iodev, pdata); + if (ret) + return ret; + } + max8997 = devm_kzalloc(&pdev->dev, sizeof(struct max8997_data), GFP_KERNEL); if (!max8997) @@ -1104,6 +1247,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) config.dev = max8997->dev; config.init_data = pdata->regulators[i].initdata; config.driver_data = max8997; + config.of_node = pdata->regulators[i].reg_node; rdev[i] = regulator_register(®ulators[id], &config); if (IS_ERR(rdev[i])) { diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index 830152c..6ae21bf 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h @@ -316,6 +316,7 @@ enum max8997_irq { #define MAX8997_NUM_GPIO 12 struct max8997_dev { struct device *dev; + struct max8997_platform_data *pdata; struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */ struct i2c_client *rtc; /* slave addr 0x0c */ struct i2c_client *haptic; /* slave addr 0x90 */ diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h index 328d8e2..1d4a4fe 100644 --- a/include/linux/mfd/max8997.h +++ b/include/linux/mfd/max8997.h @@ -75,6 +75,7 @@ enum max8998_regulators { struct max8997_regulator_data { int id; struct regulator_init_data *initdata; + struct device_node *reg_node; }; enum max8997_muic_usb_type { -- cgit v0.10.2 From 33234e791de2ac3ea915158e042907748191cabd Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 27 Nov 2012 10:24:33 +0800 Subject: regulator: core: Allow specific minimal selector for starting linear mapping Some drivers (at least 3 drivers) have such variant of linear mapping that the first few selectors are invalid and the reset are linear mapping. Let's support this case in core. This patch adds linear_min_sel in struct regulator_desc, so we can allow specific minimal selector for starting linear mapping. Then extends regulator_[map|list]_voltage_linear() to support this feature. Note that for selectors less than min_linear_index, we need count them to n_voltages so regulator_list_voltage() won't fail while checking the boundary for selector before calling list_voltage callback. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e872c8b..02a249b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1897,6 +1897,10 @@ int regulator_list_voltage_linear(struct regulator_dev *rdev, { if (selector >= rdev->desc->n_voltages) return -EINVAL; + if (selector < rdev->desc->linear_min_sel) + return 0; + + selector -= rdev->desc->linear_min_sel; return rdev->desc->min_uV + (rdev->desc->uV_step * selector); } @@ -2120,6 +2124,8 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev, if (ret < 0) return ret; + ret += rdev->desc->linear_min_sel; + /* Map back into a voltage to verify we're still in bounds */ voltage = rdev->desc->ops->list_voltage(rdev, ret); if (voltage < min_uV || voltage > max_uV) diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 7932a3b..d9ce98a 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -185,6 +185,7 @@ enum regulator_type { * * @min_uV: Voltage given by the lowest selector (if linear mapping) * @uV_step: Voltage increase with each selector (if linear mapping) + * @linear_min_sel: Minimal selector for starting linear mapping * @ramp_delay: Time to settle down after voltage change (unit: uV/us) * @volt_table: Voltage mapping table (if table based mapping) * @@ -207,6 +208,7 @@ struct regulator_desc { unsigned int min_uV; unsigned int uV_step; + unsigned int linear_min_sel; unsigned int ramp_delay; const unsigned int *volt_table; -- cgit v0.10.2 From 9119ff6af541feee1daaa5cba3a4b3b5751a2d09 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 27 Nov 2012 10:27:34 +0800 Subject: regulator: palmas: Use linear_min_sel and regulator_[map|list]_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 07aee69..111d76b 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -436,44 +436,14 @@ static int palmas_is_enabled_ldo(struct regulator_dev *dev) return !!(reg); } -static int palmas_list_voltage_ldo(struct regulator_dev *dev, - unsigned selector) -{ - if (!selector) - return 0; - - /* voltage is 0.85V + (selector * 0.05v) */ - return 850000 + (selector * 50000); -} - -static int palmas_map_voltage_ldo(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - int ret, voltage; - - if (min_uV == 0) - return 0; - - if (min_uV < 900000) - min_uV = 900000; - ret = DIV_ROUND_UP(min_uV - 900000, 50000) + 1; - - /* Map back into a voltage to verify we're still in bounds */ - voltage = palmas_list_voltage_ldo(rdev, ret); - if (voltage < min_uV || voltage > max_uV) - return -EINVAL; - - return ret; -} - static struct regulator_ops palmas_ops_ldo = { .is_enabled = palmas_is_enabled_ldo, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .list_voltage = palmas_list_voltage_ldo, - .map_voltage = palmas_map_voltage_ldo, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, }; /* @@ -821,6 +791,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].type = REGULATOR_VOLTAGE; pmic->desc[id].owner = THIS_MODULE; + pmic->desc[id].min_uV = 900000; + pmic->desc[id].uV_step = 50000; + pmic->desc[id].linear_min_sel = 1; pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, palmas_regs_info[id].vsel_addr); pmic->desc[id].vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; -- cgit v0.10.2 From 6b1f8a45666877d4885c03d9472657fd73edfa8b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 27 Nov 2012 10:26:14 +0800 Subject: regulator: da9055: Use linear_min_sel and regulator_[map|list]_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 121564b..2253559 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -57,7 +57,6 @@ struct da9055_volt_reg { int reg_a; int reg_b; int sl_shift; - int v_offset; int v_mask; int v_shift; }; @@ -204,41 +203,6 @@ static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA, info->mode.mask, val << info->mode.shift); } -static int da9055_list_voltage(struct regulator_dev *rdev, unsigned selector) -{ - struct da9055_regulator *regulator = rdev_get_drvdata(rdev); - struct da9055_regulator_info *info = regulator->info; - - if (selector >= rdev->desc->n_voltages) - return -EINVAL; - - if (selector < info->volt.v_offset) - return 0; - - selector -= info->volt.v_offset; - return rdev->desc->min_uV + (rdev->desc->uV_step * selector); -} - -static int da9055_map_voltage(struct regulator_dev *rdev, int min_uV, - int max_uV) -{ - struct da9055_regulator *regulator = rdev_get_drvdata(rdev); - struct da9055_regulator_info *info = regulator->info; - int sel, voltage; - - if (min_uV < rdev->desc->min_uV) - min_uV = rdev->desc->min_uV; - - sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); - sel += info->volt.v_offset; - - voltage = da9055_list_voltage(rdev, sel); - if (voltage < min_uV || voltage > max_uV) - return -EINVAL; - - return sel; -} - static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) { struct da9055_regulator *regulator = rdev_get_drvdata(rdev); @@ -267,10 +231,7 @@ static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) return ret; sel = (ret & volt.v_mask); - if (sel <= volt.v_offset) - return 0; - else - return sel; + return sel; } static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, @@ -331,7 +292,7 @@ static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev, return ret; } - ret = da9055_map_voltage(rdev, uV, uV); + ret = regulator_map_voltage_linear(rdev, uV, uV); if (ret < 0) return ret; @@ -374,8 +335,8 @@ static struct regulator_ops da9055_buck_ops = { .get_voltage_sel = da9055_regulator_get_voltage_sel, .set_voltage_sel = da9055_regulator_set_voltage_sel, - .list_voltage = da9055_list_voltage, - .map_voltage = da9055_map_voltage, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -392,8 +353,8 @@ static struct regulator_ops da9055_ldo_ops = { .get_voltage_sel = da9055_regulator_get_voltage_sel, .set_voltage_sel = da9055_regulator_set_voltage_sel, - .list_voltage = da9055_list_voltage, - .map_voltage = da9055_map_voltage, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -417,6 +378,7 @@ static struct regulator_ops da9055_ldo_ops = { .enable_mask = 1, \ .min_uV = (min) * 1000,\ .uV_step = (step) * 1000,\ + .linear_min_sel = (voffset),\ .owner = THIS_MODULE,\ },\ .conf = {\ @@ -428,7 +390,6 @@ static struct regulator_ops da9055_ldo_ops = { .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \ .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \ .sl_shift = 7,\ - .v_offset = (voffset),\ .v_mask = (1 << (vbits)) - 1,\ .v_shift = (vbits),\ },\ @@ -446,6 +407,7 @@ static struct regulator_ops da9055_ldo_ops = { .enable_mask = 1,\ .min_uV = (min) * 1000,\ .uV_step = (step) * 1000,\ + .linear_min_sel = (voffset),\ .owner = THIS_MODULE,\ },\ .conf = {\ @@ -457,7 +419,6 @@ static struct regulator_ops da9055_ldo_ops = { .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \ .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \ .sl_shift = 7,\ - .v_offset = (voffset),\ .v_mask = (1 << (vbits)) - 1,\ .v_shift = (vbits),\ },\ -- cgit v0.10.2 From 9997f3ffbbcde01bcd5966eeb26bc41243715021 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 26 Nov 2012 23:42:14 +0800 Subject: regulator: tps51632: Fix writing to wrong register when enable_pwm_dvfs is set When tps->enable_pwm_dvfs is true, write to TPS51632_VOLTAGE_BASE_REG rather than TPS51632_VOLTAGE_SELECT_REG. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index 3460364..e88bfe4 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c @@ -128,7 +128,7 @@ static int tps51632_dcdc_set_voltage_sel(struct regulator_dev *rdev, if (vsel > TPS51632_MAX_VSEL) return -EINVAL; - ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_SELECT_REG, vsel); + ret = regmap_write(tps->regmap, reg, vsel); if (ret < 0) dev_err(tps->dev, "reg write failed, err %d\n", ret); return ret; -- cgit v0.10.2 From 10835600cf8f3459cb4420fc2a6b9f57bad15307 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 27 Nov 2012 04:44:28 +0530 Subject: regulator: tps6586x: fix build warning in debug build When building the driver in debug mode, it generates warning as drivers/regulator/tps6586x-regulator.c: In function 'tps6586x_regulator_probe': drivers/regulator/tps6586x-regulator.c:392:9: warning: 'id' is used uninitialized in this function [-Wuninitialized] Fix this warning. Signed-off-by: Laxman Dewangan Reported-by: Stephen Warren Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 913c903..c3e0c97 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -389,7 +389,7 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) int id; int err; - dev_dbg(&pdev->dev, "Probing regulator %d\n", id); + dev_dbg(&pdev->dev, "Probing regulator\n"); pdata = dev_get_platdata(pdev->dev.parent); if ((!pdata) && (pdev->dev.parent->of_node)) -- cgit v0.10.2 From f509fd46c164524d06a33b01a64f9bd2033e4825 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 26 Nov 2012 15:26:41 +0800 Subject: regulator: da9055: Select maximum current in specific range for set_current_limit Selecting the minimal value is only true for voltage regulators. For current regulators the maximum in the given range should be selected instead. This issue was reported by Heiko Stuebner for gpio-regulator driver [1], and the conclusion is to select the max current for current regulators [2]. [1] https://lkml.org/lkml/2012/8/5/162 [2] https://lkml.org/lkml/2012/8/6/183 This patch also ensures da9055_buck_set_current_limit return -EINVAL when the supported current limit does not meet the request range. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 121564b..db59ce7 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -187,21 +187,18 @@ static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA, { struct da9055_regulator *regulator = rdev_get_drvdata(rdev); struct da9055_regulator_info *info = regulator->info; - int i, val = 0; - - if (min_uA > da9055_current_limits[DA9055_MAX_UA] || - max_uA < da9055_current_limits[DA9055_MIN_UA]) - return -EINVAL; + int i; - for (i = 0; i < ARRAY_SIZE(da9055_current_limits); i++) { - if (min_uA <= da9055_current_limits[i]) { - val = i; - break; - } + for (i = ARRAY_SIZE(da9055_current_limits) - 1; i >= 0; i--) { + if ((min_uA <= da9055_current_limits[i]) && + (da9055_current_limits[i] <= max_uA)) + return da9055_reg_update(regulator->da9055, + DA9055_REG_BUCK_LIM, + info->mode.mask, + i << info->mode.shift); } - return da9055_reg_update(regulator->da9055, DA9055_REG_BUCK_LIM, - info->mode.mask, val << info->mode.shift); + return -EINVAL; } static int da9055_list_voltage(struct regulator_dev *rdev, unsigned selector) -- cgit v0.10.2 From 1e369bcd032e3fb76e232be9c5642b0833ba62f4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 26 Nov 2012 15:23:38 +0800 Subject: regulator: da9052: Ensure setting current limit within specific range Checking da9052_current_limits[row][i] <= max_uA is not enough, it is possible da9052_current_limits[row][i] may less than the requested min_uA. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 27355b1..0a2586a 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -129,17 +129,17 @@ static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA, else if (offset == 0) row = 1; - if (min_uA > da9052_current_limits[row][DA9052_MAX_UA] || - max_uA < da9052_current_limits[row][DA9052_MIN_UA]) - return -EINVAL; - for (i = DA9052_CURRENT_RANGE - 1; i >= 0; i--) { - if (da9052_current_limits[row][i] <= max_uA) { + if ((min_uA <= da9052_current_limits[row][i]) && + (da9052_current_limits[row][i] <= max_uA)) { reg_val = i; break; } } + if (i < 0) + return -EINVAL; + /* Determine the even or odd position of the buck current limit * register field */ -- cgit v0.10.2 From f7ebaaeb0b4b97b20c1816f11884e7bfe610a2fa Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Sat, 24 Nov 2012 11:13:28 +0900 Subject: regulator: s2mps11: Fix ramp delay value shift operation This patch fix the abnormal ramp delay setting. The shift operation was wrong. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown Cc: stable@vger.kernel.org diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 926f9c8..3fd1b88 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -269,16 +269,16 @@ static __devinit int s2mps11_pmic_probe(struct platform_device *pdev) if (ramp_enable) { if (s2mps11->buck2_ramp) - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay2) >> 6; + ramp_reg |= get_ramp_delay(s2mps11->ramp_delay2) << 6; if (s2mps11->buck3_ramp || s2mps11->buck4_ramp) - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay34) >> 4; + ramp_reg |= get_ramp_delay(s2mps11->ramp_delay34) << 4; sec_reg_write(iodev, S2MPS11_REG_RAMP, ramp_reg | ramp_enable); } ramp_reg &= 0x00; - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay5) >> 6; - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay16) >> 4; - ramp_reg |= get_ramp_delay(s2mps11->ramp_delay7810) >> 2; + ramp_reg |= get_ramp_delay(s2mps11->ramp_delay5) << 6; + ramp_reg |= get_ramp_delay(s2mps11->ramp_delay16) << 4; + ramp_reg |= get_ramp_delay(s2mps11->ramp_delay7810) << 2; ramp_reg |= get_ramp_delay(s2mps11->ramp_delay9); sec_reg_write(iodev, S2MPS11_REG_RAMP_BUCK, ramp_reg); -- cgit v0.10.2 From 16ed9f0701d2bb06d96754ba1d3edbf9aa5faeef Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 24 Nov 2012 00:50:52 +0800 Subject: regulator: as3711: Fix valid min_uV/max_UV checking in as3711_bound_check Below cases are supposed to be valid: min_uV == max_uV == info->max_uV min_uV == max_uV == rdev->desc->min_uV Don't return -EINVAL for above cases. This patch also includes below cleanups: - Use rdev_get_drvdata(rdev) instead of rdev->reg_data. - Remove unnecessary WARN_ON, it looks pointless. Signed-off-by: Axel Lin Acked-by: Guennadi Liakhovetski Signed-off-by: Mark Brown diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index 81578bf..5e813b9 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c @@ -69,17 +69,14 @@ static int as3711_list_voltage_dldo(struct regulator_dev *rdev, static int as3711_bound_check(struct regulator_dev *rdev, int *min_uV, int *max_uV) { - struct as3711_regulator_info *info = container_of(rdev->desc, - struct as3711_regulator_info, desc); - struct as3711_regulator *reg = rdev->reg_data; - - WARN_ON(reg->reg_info != info); + struct as3711_regulator *reg = rdev_get_drvdata(rdev); + struct as3711_regulator_info *info = reg->reg_info; dev_dbg(&rdev->dev, "%s(), %d, %d, %d\n", __func__, *min_uV, rdev->desc->min_uV, info->max_uV); if (*max_uV < *min_uV || - *min_uV >= info->max_uV || rdev->desc->min_uV >= *max_uV) + *min_uV > info->max_uV || rdev->desc->min_uV > *max_uV) return -EINVAL; if (rdev->desc->n_voltages == 1) -- cgit v0.10.2 From 7a4beda0c6a87af26b7e2144842a0205fa9fd674 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 24 Nov 2012 00:53:22 +0800 Subject: regulator: as3711: Fix the logic in as3711_sel_check Below equation means the "voltage" is the "smallest" voltage within specific range. ret = DIV_ROUND_UP(min - bottom) / step; voltage = ret * step + bottom; If we do try 1 down when (voltage > max), new voltage is then less than min voltage. Which means the new voltage is not in the requested voltage range. This patch also includes below cleanups: - Use DIV_ROUND_UP - rename variable 'ret' to 'sel' for better readability because as3711_sel_check returns the selector. Signed-off-by: Axel Lin Acked-by: Guennadi Liakhovetski Signed-off-by: Mark Brown diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index 5e813b9..2f1341d 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c @@ -93,24 +93,17 @@ static int as3711_bound_check(struct regulator_dev *rdev, static int as3711_sel_check(int min, int max, int bottom, int step) { - int ret, voltage; + int sel, voltage; /* Round up min, when dividing: keeps us within the range */ - ret = (min - bottom + step - 1) / step; - voltage = ret * step + bottom; + sel = DIV_ROUND_UP(min - bottom, step); + voltage = sel * step + bottom; pr_debug("%s(): select %d..%d in %d+N*%d: %d\n", __func__, - min, max, bottom, step, ret); - if (voltage > max) { - /* - * Try 1 down. It will take us below min, but as long we stay - * above bottom, we're fine. - */ - ret--; - voltage = ret * step + bottom; - if (voltage < bottom) - return -EINVAL; - } - return ret; + min, max, bottom, step, sel); + if (voltage > max) + return -EINVAL; + + return sel; } static int as3711_map_voltage_sd(struct regulator_dev *rdev, -- cgit v0.10.2 From 86a14501180de78ccec1e513b031a06ea60c973f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 27 Nov 2012 17:02:29 +0000 Subject: regulator: arizona-ldo1: Add enable time Signed-off-by: Mark Brown diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index d184aa3..9d50458 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -56,6 +56,7 @@ static const struct regulator_desc arizona_ldo1 = { .min_uV = 900000, .uV_step = 50000, .n_voltages = 6, + .enable_time = 500, .owner = THIS_MODULE, }; -- cgit v0.10.2 From 55a18aef2e963c43d3a0ae20c1dfd404830aa6f9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 27 Nov 2012 17:51:46 +0000 Subject: regulator: arizona-ldo1: Support DVFS in default constraints Some Arizona devices such as the WM5102 can use DVFS on their digital core, for these devices allow the voltage range to vary in the default setup. Signed-off-by: Mark Brown diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 9d50458..36c1c5c 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -61,6 +61,16 @@ static const struct regulator_desc arizona_ldo1 = { .owner = THIS_MODULE, }; +static const struct regulator_init_data arizona_ldo1_dvfs = { + .constraints = { + .min_uV = 1200000, + .max_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = 1, +}; + static const struct regulator_init_data arizona_ldo1_default = { .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS, @@ -88,7 +98,15 @@ static __devinit int arizona_ldo1_probe(struct platform_device *pdev) * default init_data for it. This will be overridden with * platform data if provided. */ - ldo1->init_data = arizona_ldo1_default; + switch (arizona->type) { + case WM5102: + ldo1->init_data = arizona_ldo1_dvfs; + break; + default: + ldo1->init_data = arizona_ldo1_default; + break; + } + ldo1->init_data.consumer_supplies = &ldo1->supply; ldo1->supply.supply = "DCVDD"; ldo1->supply.dev_name = dev_name(arizona->dev); -- cgit v0.10.2 From 8a7f0c61c0c0dfdf5d5d878fe93ae20b4fd14ee2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 27 Nov 2012 18:25:13 +0000 Subject: regulator: arizona-ldo1: Add additional top voltage The number of voltage slots supported by the LDO is 7, not 6. Signed-off-by: Mark Brown diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 36c1c5c..800c8ad 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -55,7 +55,7 @@ static const struct regulator_desc arizona_ldo1 = { .bypass_mask = ARIZONA_LDO1_BYPASS, .min_uV = 900000, .uV_step = 50000, - .n_voltages = 6, + .n_voltages = 7, .enable_time = 500, .owner = THIS_MODULE, -- cgit v0.10.2 From 73ee29460e5d0adbb46e4962df69ae2465746612 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 27 Nov 2012 18:48:33 +0000 Subject: regulator: arizona-ldo1: Support 1.8V mode Some Arizona device support a 1.8V output mode. Enable this in the driver. Signed-off-by: Mark Brown diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index 01b9255..b829a57 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c @@ -775,6 +775,7 @@ static const struct reg_default wm5102_reg_default[] = { { 0x00000154, 0x0000 }, /* R340 - Rate Estimator 3 */ { 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */ { 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */ + { 0x00000161, 0x0000 }, /* R353 - Dynamic Frequency Scaling 1 */ { 0x00000171, 0x0000 }, /* R369 - FLL1 Control 1 */ { 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */ { 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */ @@ -1564,6 +1565,7 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) case ARIZONA_RATE_ESTIMATOR_3: case ARIZONA_RATE_ESTIMATOR_4: case ARIZONA_RATE_ESTIMATOR_5: + case ARIZONA_DYNAMIC_FREQUENCY_SCALING_1: case ARIZONA_FLL1_CONTROL_1: case ARIZONA_FLL1_CONTROL_2: case ARIZONA_FLL1_CONTROL_3: @@ -1596,6 +1598,7 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) case ARIZONA_FLL2_GPIO_CLOCK: case ARIZONA_MIC_CHARGE_PUMP_1: case ARIZONA_LDO1_CONTROL_1: + case ARIZONA_LDO1_CONTROL_2: case ARIZONA_LDO2_CONTROL_1: case ARIZONA_MIC_BIAS_CTRL_1: case ARIZONA_MIC_BIAS_CTRL_2: diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 800c8ad..739faf9 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -34,6 +34,108 @@ struct arizona_ldo1 { struct regulator_init_data init_data; }; +static int arizona_ldo1_hc_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + if (selector >= rdev->desc->n_voltages) + return -EINVAL; + + if (selector == rdev->desc->n_voltages - 1) + return 1800000; + else + return rdev->desc->min_uV + (rdev->desc->uV_step * selector); +} + +static int arizona_ldo1_hc_map_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + int sel; + + sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); + if (sel >= rdev->desc->n_voltages) + sel = rdev->desc->n_voltages - 1; + + return sel; +} + +static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, + unsigned sel) +{ + struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); + struct regmap *regmap = ldo->arizona->regmap; + unsigned int val; + int ret; + + if (sel == rdev->desc->n_voltages - 1) + val = ARIZONA_LDO1_HI_PWR; + else + val = 0; + + ret = regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_2, + ARIZONA_LDO1_HI_PWR, val); + if (ret != 0) + return ret; + + ret = regmap_update_bits(regmap, ARIZONA_DYNAMIC_FREQUENCY_SCALING_1, + ARIZONA_SUBSYS_MAX_FREQ, val); + if (ret != 0) + return ret; + + if (val) + return 0; + + val = sel << ARIZONA_LDO1_VSEL_SHIFT; + + return regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_1, + ARIZONA_LDO1_VSEL_MASK, val); +} + +static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev) +{ + struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); + struct regmap *regmap = ldo->arizona->regmap; + unsigned int val; + int ret; + + ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_2, &val); + if (ret != 0) + return ret; + + if (val & ARIZONA_LDO1_HI_PWR) + return rdev->desc->n_voltages - 1; + + ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_1, &val); + if (ret != 0) + return ret; + + return (val & ARIZONA_LDO1_VSEL_MASK) >> ARIZONA_LDO1_VSEL_SHIFT; +} + +static struct regulator_ops arizona_ldo1_hc_ops = { + .list_voltage = arizona_ldo1_hc_list_voltage, + .map_voltage = arizona_ldo1_hc_map_voltage, + .get_voltage_sel = arizona_ldo1_hc_get_voltage_sel, + .set_voltage_sel = arizona_ldo1_hc_set_voltage_sel, + .get_bypass = regulator_get_bypass_regmap, + .set_bypass = regulator_set_bypass_regmap, +}; + +static const struct regulator_desc arizona_ldo1_hc = { + .name = "LDO1", + .supply_name = "LDOVDD", + .type = REGULATOR_VOLTAGE, + .ops = &arizona_ldo1_hc_ops, + + .bypass_reg = ARIZONA_LDO1_CONTROL_1, + .bypass_mask = ARIZONA_LDO1_BYPASS, + .min_uV = 900000, + .uV_step = 50000, + .n_voltages = 8, + .enable_time = 500, + + .owner = THIS_MODULE, +}; + static struct regulator_ops arizona_ldo1_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, @@ -81,6 +183,7 @@ static const struct regulator_init_data arizona_ldo1_default = { static __devinit int arizona_ldo1_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + const struct regulator_desc *desc; struct regulator_config config = { }; struct arizona_ldo1 *ldo1; int ret; @@ -100,9 +203,11 @@ static __devinit int arizona_ldo1_probe(struct platform_device *pdev) */ switch (arizona->type) { case WM5102: + desc = &arizona_ldo1_hc; ldo1->init_data = arizona_ldo1_dvfs; break; default: + desc = &arizona_ldo1; ldo1->init_data = arizona_ldo1_default; break; } @@ -121,7 +226,7 @@ static __devinit int arizona_ldo1_probe(struct platform_device *pdev) else config.init_data = &ldo1->init_data; - ldo1->regulator = regulator_register(&arizona_ldo1, &config); + ldo1->regulator = regulator_register(desc, &config); if (IS_ERR(ldo1->regulator)) { ret = PTR_ERR(ldo1->regulator); dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h index 7671a28..ba26e99 100644 --- a/include/linux/mfd/arizona/registers.h +++ b/include/linux/mfd/arizona/registers.h @@ -76,6 +76,7 @@ #define ARIZONA_RATE_ESTIMATOR_3 0x154 #define ARIZONA_RATE_ESTIMATOR_4 0x155 #define ARIZONA_RATE_ESTIMATOR_5 0x156 +#define ARIZONA_DYNAMIC_FREQUENCY_SCALING_1 0x161 #define ARIZONA_FLL1_CONTROL_1 0x171 #define ARIZONA_FLL1_CONTROL_2 0x172 #define ARIZONA_FLL1_CONTROL_3 0x173 @@ -110,6 +111,7 @@ #define ARIZONA_FLL2_GPIO_CLOCK 0x1AA #define ARIZONA_MIC_CHARGE_PUMP_1 0x200 #define ARIZONA_LDO1_CONTROL_1 0x210 +#define ARIZONA_LDO1_CONTROL_2 0x212 #define ARIZONA_LDO2_CONTROL_1 0x213 #define ARIZONA_MIC_BIAS_CTRL_1 0x218 #define ARIZONA_MIC_BIAS_CTRL_2 0x219 @@ -1574,6 +1576,13 @@ #define ARIZONA_SAMPLE_RATE_DETECT_D_WIDTH 5 /* SAMPLE_RATE_DETECT_D - [4:0] */ /* + * R353 (0x161) - Dynamic Frequency Scaling 1 + */ +#define ARIZONA_SUBSYS_MAX_FREQ 0x0001 /* SUBSYS_MAX_FREQ */ +#define ARIZONA_SUBSYS_MAX_FREQ_SHIFT 0 /* SUBSYS_MAX_FREQ */ +#define ARIZONA_SUBSYS_MAX_FREQ_WIDTH 1 /* SUBSYS_MAX_FREQ */ + +/* * R369 (0x171) - FLL1 Control 1 */ #define ARIZONA_FLL1_FREERUN 0x0002 /* FLL1_FREERUN */ @@ -1889,6 +1898,13 @@ #define ARIZONA_LDO1_ENA_WIDTH 1 /* LDO1_ENA */ /* + * R530 (0x212) - LDO1 Control 2 + */ +#define ARIZONA_LDO1_HI_PWR 0x0001 /* LDO1_HI_PWR */ +#define ARIZONA_LDO1_HI_PWR_SHIFT 0 /* LDO1_HI_PWR */ +#define ARIZONA_LDO1_HI_PWR_WIDTH 1 /* LDO1_HI_PWR */ + +/* * R531 (0x213) - LDO2 Control 1 */ #define ARIZONA_LDO2_VSEL_MASK 0x07E0 /* LDO2_VSEL - [10:5] */ -- cgit v0.10.2 From dd8004af2b0e903b2ee9fce305cb615245fa12ee Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 28 Nov 2012 17:09:27 +0000 Subject: regulator: core: Log when a device causes a voltage constraint fail Helps with figuring out when things went wrong. Signed-off-by: Mark Brown diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e872c8b..e7fffd1 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -199,8 +199,11 @@ static int regulator_check_consumers(struct regulator_dev *rdev, *min_uV = regulator->min_uV; } - if (*min_uV > *max_uV) + if (*min_uV > *max_uV) { + dev_err(regulator->dev, "Restricting voltage, %u-%uuV\n", + regulator->min_uV, regulator->max_uV); return -EINVAL; + } return 0; } -- cgit v0.10.2 From fff15bef48e846d2670c86c95f8dbc3f84bbe866 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 27 Nov 2012 18:48:56 +0000 Subject: regulator: core: Say what unsupportable voltage constraints are Signed-off-by: Mark Brown diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e7fffd1..7fbbd82 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -883,7 +883,9 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, /* final: [min_uV..max_uV] valid iff constraints valid */ if (max_uV < min_uV) { - rdev_err(rdev, "unsupportable voltage constraints\n"); + rdev_err(rdev, + "unsupportable voltage constraints %u-%uuV\n", + min_uV, max_uV); return -EINVAL; } -- cgit v0.10.2 From 9507281855080081084ed8526cfe1353c37407c4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 27 Nov 2012 14:55:49 +0000 Subject: regulator: arizona-micsupp: Add ramp time information Signed-off-by: Mark Brown diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index d9b1f82..93d0604 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -101,6 +101,8 @@ static const struct regulator_desc arizona_micsupp = { .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1, .bypass_mask = ARIZONA_CPMIC_BYPASS, + .enable_time = 3000, + .owner = THIS_MODULE, }; -- cgit v0.10.2 From 05cf34c1af48e2e1308a03fbc778039243bebd3a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 28 Nov 2012 10:41:04 +0800 Subject: regulator: pcf50633: Use linear_min_sel and regulator_[map|list]_voltage_linear This driver can be converted to use linear_min_sel and regulator_[map|list]_voltage_linear. Below shows the equation (from Datasheet) for each LDOs. For AUTOOUT: VO(prog) = 0.625 + auto_out x 0.025 V; e.g. (00000000 to 00101110: reserved) 00101111: 1.8 V (min) 01010011: 2.7 V 01101010: 3.275 V 01101011: 3.300 V 01101100: 3.325 V 01111111 : 3.800 V (max) The linear mapping start from 0x2f selector. Thus we convert this equation to: VO(prog) = 1.8 + (selector - linear_min_sel) x 0.025 V (min_uV = 1800000, uV_step = 25000, linear_min_sel = 0x2f) For DOWNxOUT: VO(prog) = 0.625 + downx_out x 0.025 V; e.g. 00000000 : 0.625 V (min) 00010111 : 1.200 V 00101111 : 1.800 V 01011111 : 3.000 V (max) For xLDOOUT: VO(prog) = 0.9 + xldo_out x 0.1 V; e.g. 00000: 0.9 V 00001: 1.0 V 11000 : 3.3 V 11011 : 3.6 V Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 092e5cb..769272a 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c @@ -24,12 +24,15 @@ #include #include -#define PCF50633_REGULATOR(_name, _id, _n) \ +#define PCF50633_REGULATOR(_name, _id, _min_uV, _uV_step, _min_sel, _n) \ { \ .name = _name, \ .id = PCF50633_REGULATOR_##_id, \ .ops = &pcf50633_regulator_ops, \ .n_voltages = _n, \ + .min_uV = _min_uV, \ + .uV_step = _uV_step, \ + .linear_min_sel = _min_sel, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ .vsel_reg = PCF50633_REG_##_id##OUT, \ @@ -38,162 +41,39 @@ .enable_mask = PCF50633_REGULATOR_ON, \ } -/* Bits from voltage value */ -static u8 auto_voltage_bits(unsigned int millivolts) -{ - if (millivolts < 1800) - return 0x2f; - if (millivolts > 3800) - return 0xff; - - millivolts -= 625; - - return millivolts / 25; -} - -static u8 down_voltage_bits(unsigned int millivolts) -{ - if (millivolts < 625) - return 0; - else if (millivolts > 3000) - return 0xff; - - millivolts -= 625; - - return millivolts / 25; -} - -static u8 ldo_voltage_bits(unsigned int millivolts) -{ - if (millivolts < 900) - return 0; - else if (millivolts > 3600) - return 0x1f; - - millivolts -= 900; - return millivolts / 100; -} - -/* Obtain voltage value from bits */ -static unsigned int auto_voltage_value(u8 bits) -{ - /* AUTOOUT: 00000000 to 00101110 are reserved. - * Return 0 for bits in reserved range, which means this selector code - * can't be used on this system */ - if (bits < 0x2f) - return 0; - - return 625 + (bits * 25); -} - - -static unsigned int down_voltage_value(u8 bits) -{ - return 625 + (bits * 25); -} - - -static unsigned int ldo_voltage_value(u8 bits) -{ - bits &= 0x1f; - - return 900 + (bits * 100); -} - -static int pcf50633_regulator_map_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - struct pcf50633 *pcf; - int regulator_id, millivolts; - u8 volt_bits; - - pcf = rdev_get_drvdata(rdev); - - regulator_id = rdev_get_id(rdev); - if (regulator_id >= PCF50633_NUM_REGULATORS) - return -EINVAL; - - millivolts = min_uV / 1000; - - switch (regulator_id) { - case PCF50633_REGULATOR_AUTO: - volt_bits = auto_voltage_bits(millivolts); - break; - case PCF50633_REGULATOR_DOWN1: - case PCF50633_REGULATOR_DOWN2: - volt_bits = down_voltage_bits(millivolts); - break; - case PCF50633_REGULATOR_LDO1: - case PCF50633_REGULATOR_LDO2: - case PCF50633_REGULATOR_LDO3: - case PCF50633_REGULATOR_LDO4: - case PCF50633_REGULATOR_LDO5: - case PCF50633_REGULATOR_LDO6: - case PCF50633_REGULATOR_HCLDO: - case PCF50633_REGULATOR_MEMLDO: - volt_bits = ldo_voltage_bits(millivolts); - break; - default: - return -EINVAL; - } - - return volt_bits; -} - -static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, - unsigned int index) -{ - int regulator_id = rdev_get_id(rdev); - - int millivolts; - - switch (regulator_id) { - case PCF50633_REGULATOR_AUTO: - millivolts = auto_voltage_value(index); - break; - case PCF50633_REGULATOR_DOWN1: - case PCF50633_REGULATOR_DOWN2: - millivolts = down_voltage_value(index); - break; - case PCF50633_REGULATOR_LDO1: - case PCF50633_REGULATOR_LDO2: - case PCF50633_REGULATOR_LDO3: - case PCF50633_REGULATOR_LDO4: - case PCF50633_REGULATOR_LDO5: - case PCF50633_REGULATOR_LDO6: - case PCF50633_REGULATOR_HCLDO: - case PCF50633_REGULATOR_MEMLDO: - millivolts = ldo_voltage_value(index); - break; - default: - return -EINVAL; - } - - return millivolts * 1000; -} - static struct regulator_ops pcf50633_regulator_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .list_voltage = pcf50633_regulator_list_voltage, - .map_voltage = pcf50633_regulator_map_voltage, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, }; static const struct regulator_desc regulators[] = { - [PCF50633_REGULATOR_AUTO] = PCF50633_REGULATOR("auto", AUTO, 128), - [PCF50633_REGULATOR_DOWN1] = PCF50633_REGULATOR("down1", DOWN1, 96), - [PCF50633_REGULATOR_DOWN2] = PCF50633_REGULATOR("down2", DOWN2, 96), - [PCF50633_REGULATOR_LDO1] = PCF50633_REGULATOR("ldo1", LDO1, 28), - [PCF50633_REGULATOR_LDO2] = PCF50633_REGULATOR("ldo2", LDO2, 28), - [PCF50633_REGULATOR_LDO3] = PCF50633_REGULATOR("ldo3", LDO3, 28), - [PCF50633_REGULATOR_LDO4] = PCF50633_REGULATOR("ldo4", LDO4, 28), - [PCF50633_REGULATOR_LDO5] = PCF50633_REGULATOR("ldo5", LDO5, 28), - [PCF50633_REGULATOR_LDO6] = PCF50633_REGULATOR("ldo6", LDO6, 28), - [PCF50633_REGULATOR_HCLDO] = PCF50633_REGULATOR("hcldo", HCLDO, 28), - [PCF50633_REGULATOR_MEMLDO] = PCF50633_REGULATOR("memldo", MEMLDO, 28), + [PCF50633_REGULATOR_AUTO] = + PCF50633_REGULATOR("auto", AUTO, 1800000, 25000, 0x2f, 128), + [PCF50633_REGULATOR_DOWN1] = + PCF50633_REGULATOR("down1", DOWN1, 625000, 25000, 0, 96), + [PCF50633_REGULATOR_DOWN2] = + PCF50633_REGULATOR("down2", DOWN2, 625000, 25000, 0, 96), + [PCF50633_REGULATOR_LDO1] = + PCF50633_REGULATOR("ldo1", LDO1, 900000, 100000, 0, 28), + [PCF50633_REGULATOR_LDO2] = + PCF50633_REGULATOR("ldo2", LDO2, 900000, 100000, 0, 28), + [PCF50633_REGULATOR_LDO3] = + PCF50633_REGULATOR("ldo3", LDO3, 900000, 100000, 0, 28), + [PCF50633_REGULATOR_LDO4] = + PCF50633_REGULATOR("ldo4", LDO4, 900000, 100000, 0, 28), + [PCF50633_REGULATOR_LDO5] = + PCF50633_REGULATOR("ldo5", LDO5, 900000, 100000, 0, 28), + [PCF50633_REGULATOR_LDO6] = + PCF50633_REGULATOR("ldo6", LDO6, 900000, 100000, 0, 28), + [PCF50633_REGULATOR_HCLDO] = + PCF50633_REGULATOR("hcldo", HCLDO, 900000, 100000, 0, 28), + [PCF50633_REGULATOR_MEMLDO] = + PCF50633_REGULATOR("memldo", MEMLDO, 900000, 100000, 0, 28), }; static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) -- cgit v0.10.2 From bd0ec7c1e52423429d9ee7b34e2c899f01db01b0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 28 Nov 2012 07:22:54 +0800 Subject: regulator: tps51632: Use linear_min_sel and regulator_[map|list]_voltage_linear Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index 3460364..dce5eb3 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c @@ -106,29 +106,23 @@ static int tps51632_dcdc_get_voltage_sel(struct regulator_dev *rdev) } vsel = data & TPS51632_VOUT_MASK; - - if (vsel < TPS51632_MIN_VSEL) - return 0; - else - return vsel - TPS51632_MIN_VSEL; + return vsel; } static int tps51632_dcdc_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { struct tps51632_chip *tps = rdev_get_drvdata(rdev); - int vsel; int ret; unsigned int reg = TPS51632_VOLTAGE_SELECT_REG; if (tps->enable_pwm_dvfs) reg = TPS51632_VOLTAGE_BASE_REG; - vsel = selector + TPS51632_MIN_VSEL; - if (vsel > TPS51632_MAX_VSEL) + if (selector > TPS51632_MAX_VSEL) return -EINVAL; - ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_SELECT_REG, vsel); + ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_SELECT_REG, selector); if (ret < 0) dev_err(tps->dev, "reg write failed, err %d\n", ret); return ret; @@ -254,7 +248,8 @@ static int __devinit tps51632_probe(struct i2c_client *client, tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY; tps->desc.min_uV = TPS51632_MIN_VOLATGE; tps->desc.uV_step = TPS51632_VOLATGE_STEP_10mV; - tps->desc.n_voltages = (TPS51632_MAX_VSEL - TPS51632_MIN_VSEL) + 1; + tps->desc.linear_min_sel = TPS51632_MIN_VSEL; + tps->desc.n_voltages = TPS51632_MAX_VSEL + 1; tps->desc.ops = &tps51632_dcdc_ops; tps->desc.type = REGULATOR_VOLTAGE; tps->desc.owner = THIS_MODULE; -- cgit v0.10.2 From 1a679930e1750c342d7e5fac787dc47484daec2e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 30 Nov 2012 13:19:33 +0800 Subject: regulator: wm831x-dcdc: Ensure selected voltage falls within requested range Use DIV_ROUND_UP to ensure selected voltage won't less than min_uV due to integer truncation. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 782c228..411cb12 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -223,7 +223,7 @@ static int wm831x_buckv_map_voltage(struct regulator_dev *rdev, if (min_uV < 600000) vsel = 0; else if (min_uV <= 1800000) - vsel = ((min_uV - 600000) / 12500) + 8; + vsel = DIV_ROUND_UP(min_uV - 600000, 12500) + 8; else return -EINVAL; -- cgit v0.10.2 From 43f1f2165e12d15a262ad1d0827d2960fe66f75b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 30 Nov 2012 20:39:53 +0800 Subject: regulator: wm831x-dcdc: Add MODULE_ALIAS for wm831x-boostp Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 411cb12..2680260 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -993,4 +993,5 @@ MODULE_DESCRIPTION("WM831x DC-DC convertor driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:wm831x-buckv"); MODULE_ALIAS("platform:wm831x-buckp"); +MODULE_ALIAS("platform:wm831x-boostp"); MODULE_ALIAS("platform:wm831x-epe"); -- cgit v0.10.2 From dbc705183a41f8ae209673fbc555d9923b0ebb7f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 30 Nov 2012 16:52:49 +0800 Subject: regulator: tps51632: Ensure [base|max]_voltage_uV pdata settings are valid If pdata->base_voltage_uV is missing or the settings of pdata->base_voltage_uV and pdata->max_voltage_uV are out of range, TPS51632_VOLT_VSEL macro returns wrong vsel. Thus add checking [base|max]_voltage_uV pdata settings in probe. Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index e88bfe4..dc7023e 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c @@ -242,6 +242,21 @@ static int __devinit tps51632_probe(struct i2c_client *client, return -EINVAL; } + if (pdata->enable_pwm_dvfs) { + if ((pdata->base_voltage_uV < TPS51632_MIN_VOLATGE) || + (pdata->base_voltage_uV > TPS51632_MAX_VOLATGE)) { + dev_err(&client->dev, "Invalid base_voltage_uV setting\n"); + return -EINVAL; + } + + if ((pdata->max_voltage_uV) && + ((pdata->max_voltage_uV < TPS51632_MIN_VOLATGE) || + (pdata->max_voltage_uV > TPS51632_MAX_VOLATGE))) { + dev_err(&client->dev, "Invalid max_voltage_uV setting\n"); + return -EINVAL; + } + } + tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); if (!tps) { dev_err(&client->dev, "Memory allocation failed\n"); -- cgit v0.10.2 From d1e7de3007c6e34c5e6d5e1b707b5aba4a1cd57f Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 4 Dec 2012 15:01:01 +0100 Subject: regulators: add regulator_can_change_voltage() function Introduce a regulator_can_change_voltage() function for the subsytems or drivers which might check if applying voltage change is possible and use special workaround code when the driver is used with fixed regulators or regulators with disabled ability to change the voltage. Signed-off-by: Marek Szyprowski Signed-off-by: Mark Brown diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e872c8b..59e0863 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1867,6 +1867,28 @@ int regulator_is_enabled(struct regulator *regulator) EXPORT_SYMBOL_GPL(regulator_is_enabled); /** + * regulator_can_change_voltage - check if regulator can change voltage + * @regulator: regulator source + * + * Returns positive if the regulator driver backing the source/client + * can change its voltage, false otherwise. Usefull for detecting fixed + * or dummy regulators and disabling voltage change logic in the client + * driver. + */ +int regulator_can_change_voltage(struct regulator *regulator) +{ + struct regulator_dev *rdev = regulator->rdev; + + if (rdev->constraints && + rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE && + rdev->desc->n_voltages > 1) + return 1; + + return 0; +} +EXPORT_SYMBOL_GPL(regulator_can_change_voltage); + +/** * regulator_count_voltages - count regulator_list_voltage() selectors * @regulator: regulator source * diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index c43cd35..5d0f7c1 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -160,6 +160,7 @@ int regulator_bulk_force_disable(int num_consumers, void regulator_bulk_free(int num_consumers, struct regulator_bulk_data *consumers); +int regulator_can_change_voltage(struct regulator *regulator); int regulator_count_voltages(struct regulator *regulator); int regulator_list_voltage(struct regulator *regulator, unsigned selector); int regulator_is_supported_voltage(struct regulator *regulator, -- cgit v0.10.2 From ad02e846878ca35e9d3fa584be8ee770e9e14fce Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 29 Nov 2012 09:59:16 +0800 Subject: regulator: palmas: Return raw register values as the selectors in [get|set]_voltage_sel Don't adjust the selector in [get|set]_voltage_sel, fix it in list_voltage() instead. For smps*(except smps10), the vsel reg-value and voltage mapping as below: reg-value volt (uV) ( Assume RANGE is x1 ) 0 0 1 500000 2 500000 3 500000 4 500000 5 500000 6 500000 (0.49V + 1 * 0.01V) * RANGE 7 510000 (0.49V + 2 * 0.01V) * RANGE 8 520000 (0.49V + 3 * 0.01V) * RANGE 9 530000 (0.49V + 4 * 0.01V) * RANGE .... The linear mapping is start from selector 6. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 07aee69..151c0c4 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -309,19 +309,22 @@ static int palmas_list_voltage_smps(struct regulator_dev *dev, int id = rdev_get_id(dev); int mult = 1; - if (!selector) - return 0; - /* Read the multiplier set in VSEL register to return * the correct voltage. */ if (pmic->range[id]) mult = 2; - /* Voltage is (0.49V + (selector * 0.01V)) * RANGE - * as defined in data sheet. RANGE is either x1 or x2 - */ - return (490000 + (selector * 10000)) * mult; + if (selector == 0) + return 0; + else if (selector < 6) + return 500000 * mult; + else + /* Voltage is linear mapping starting from selector 6, + * volt = (0.49V + ((selector - 5) * 0.01V)) * RANGE + * RANGE is either x1 or x2 + */ + return (490000 + ((selector - 5) * 10000)) * mult; } static int palmas_get_voltage_smps_sel(struct regulator_dev *dev) @@ -338,15 +341,6 @@ static int palmas_get_voltage_smps_sel(struct regulator_dev *dev) selector = reg & PALMAS_SMPS12_VOLTAGE_VSEL_MASK; - /* Adjust selector to match list_voltage ranges */ - if ((selector > 0) && (selector < 6)) - selector = 6; - if (!selector) - selector = 5; - if (selector > 121) - selector = 121; - selector -= 5; - return selector; } @@ -355,19 +349,15 @@ static int palmas_set_voltage_smps_sel(struct regulator_dev *dev, { struct palmas_pmic *pmic = rdev_get_drvdata(dev); int id = rdev_get_id(dev); - unsigned int reg = 0; - unsigned int addr; + unsigned int reg, addr; addr = palmas_regs_info[id].vsel_addr; + reg = selector; /* Make sure we don't change the value of RANGE */ if (pmic->range[id]) reg |= PALMAS_SMPS12_VOLTAGE_RANGE; - /* Adjust the linux selector into range used in VSEL register */ - if (selector) - reg |= selector + 5; - palmas_smps_write(pmic->palmas, addr, reg); return 0; @@ -386,11 +376,11 @@ static int palmas_map_voltage_smps(struct regulator_dev *rdev, if (pmic->range[id]) { /* RANGE is x2 */ if (min_uV < 1000000) min_uV = 1000000; - ret = DIV_ROUND_UP(min_uV - 1000000, 20000) + 1; + ret = DIV_ROUND_UP(min_uV - 1000000, 20000) + 6; } else { /* RANGE is x1 */ if (min_uV < 500000) min_uV = 500000; - ret = DIV_ROUND_UP(min_uV - 500000, 10000) + 1; + ret = DIV_ROUND_UP(min_uV - 500000, 10000) + 6; } /* Map back into a voltage to verify we're still in bounds */ -- cgit v0.10.2 From bdc4baacebdae1e90124b62a66607faec1a0a7fb Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 29 Nov 2012 10:01:44 +0800 Subject: regulator: palmas: Convert palmas_ops_smps to regulator_[get|set]_voltage_sel_regmap Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 151c0c4..f4142b4 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -327,42 +327,6 @@ static int palmas_list_voltage_smps(struct regulator_dev *dev, return (490000 + ((selector - 5) * 10000)) * mult; } -static int palmas_get_voltage_smps_sel(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - int selector; - unsigned int reg; - unsigned int addr; - - addr = palmas_regs_info[id].vsel_addr; - - palmas_smps_read(pmic->palmas, addr, ®); - - selector = reg & PALMAS_SMPS12_VOLTAGE_VSEL_MASK; - - return selector; -} - -static int palmas_set_voltage_smps_sel(struct regulator_dev *dev, - unsigned selector) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg, addr; - - addr = palmas_regs_info[id].vsel_addr; - reg = selector; - - /* Make sure we don't change the value of RANGE */ - if (pmic->range[id]) - reg |= PALMAS_SMPS12_VOLTAGE_RANGE; - - palmas_smps_write(pmic->palmas, addr, reg); - - return 0; -} - static int palmas_map_voltage_smps(struct regulator_dev *rdev, int min_uV, int max_uV) { @@ -397,8 +361,8 @@ static struct regulator_ops palmas_ops_smps = { .disable = palmas_disable_smps, .set_mode = palmas_set_mode_smps, .get_mode = palmas_get_mode_smps, - .get_voltage_sel = palmas_get_voltage_smps_sel, - .set_voltage_sel = palmas_set_voltage_smps_sel, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = palmas_list_voltage_smps, .map_voltage = palmas_map_voltage_smps, }; @@ -723,6 +687,14 @@ static __devinit int palmas_probe(struct platform_device *pdev) continue; } + /* Initialise sleep/init values from platform data */ + if (pdata && pdata->reg_init[id]) { + reg_init = pdata->reg_init[id]; + ret = palmas_smps_init(palmas, id, reg_init); + if (ret) + goto err_unregister_regulator; + } + /* Register the regulators */ pmic->desc[id].name = palmas_regs_info[id].name; pmic->desc[id].id = id; @@ -743,29 +715,11 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].uV_step = 1250000; break; default: - pmic->desc[id].ops = &palmas_ops_smps; - pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; - } - - pmic->desc[id].type = REGULATOR_VOLTAGE; - pmic->desc[id].owner = THIS_MODULE; - - /* Initialise sleep/init values from platform data */ - if (pdata) { - reg_init = pdata->reg_init[id]; - if (reg_init) { - ret = palmas_smps_init(palmas, id, reg_init); - if (ret) - goto err_unregister_regulator; - } - } - - /* - * read and store the RANGE bit for later use - * This must be done before regulator is probed otherwise - * we error in probe with unsuportable ranges. - */ - if (id != PALMAS_REG_SMPS10) { + /* + * Read and store the RANGE bit for later use + * This must be done before regulator is probed, + * otherwise we error in probe with unsupportable ranges. + */ addr = palmas_regs_info[id].vsel_addr; ret = palmas_smps_read(pmic->palmas, addr, ®); @@ -773,8 +727,19 @@ static __devinit int palmas_probe(struct platform_device *pdev) goto err_unregister_regulator; if (reg & PALMAS_SMPS12_VOLTAGE_RANGE) pmic->range[id] = 1; + + pmic->desc[id].ops = &palmas_ops_smps; + pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; + pmic->desc[id].vsel_reg = + PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + palmas_regs_info[id].vsel_addr); + pmic->desc[id].vsel_mask = + PALMAS_SMPS12_VOLTAGE_VSEL_MASK; } + pmic->desc[id].type = REGULATOR_VOLTAGE; + pmic->desc[id].owner = THIS_MODULE; + if (pdata) config.init_data = pdata->reg_data[id]; else -- cgit v0.10.2 From ec4f7b88b4a89253ec922d48f77b269ce5cffc2c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 4 Dec 2012 10:32:05 +0800 Subject: regulator: gpio-regulator: Add ifdef CONFIG_OF guard for regulator_gpio_of_match Use of_match_ptr and add ifdef CONFIG_OF guard for regulator_gpio_of_match. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index dc92605..8c4e237 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -364,10 +364,12 @@ 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, @@ -375,7 +377,7 @@ static struct platform_driver gpio_regulator_driver = { .driver = { .name = "gpio-regulator", .owner = THIS_MODULE, - .of_match_table = regulator_gpio_of_match, + .of_match_table = of_match_ptr(regulator_gpio_of_match), }, }; -- cgit v0.10.2 From 40b5aa8f0d06865c00a7cf4169cbe37d73e137a3 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 7 Dec 2012 09:47:57 +0800 Subject: regulator: lp8788-ldo: Remove val array in lp8788_config_ldo_enable_mode To clear the mask bit, setting data argument to be 0 with proper mask setting for lp8788_update_bits. We don't need the var array here. Signed-off-by: Axel Lin Acked-by: Milo(Woogyom) Kim Signed-off-by: Mark Brown diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index e496ba0..40897eb 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -662,14 +662,6 @@ static int lp8788_config_ldo_enable_mode(struct lp8788_ldo *ldo, [EN_DLDO7] = LP8788_EN_SEL_DLDO7_M, [EN_DLDO911] = LP8788_EN_SEL_DLDO911_M, }; - u8 val[] = { - [EN_ALDO1] = 0 << 5, - [EN_ALDO234] = 0 << 4, - [EN_ALDO5] = 0 << 3, - [EN_ALDO7] = 0 << 2, - [EN_DLDO7] = 0 << 1, - [EN_DLDO911] = 0 << 0, - }; switch (id) { case DLDO7: @@ -708,8 +700,7 @@ static int lp8788_config_ldo_enable_mode(struct lp8788_ldo *ldo, return ret; set_default_ldo_enable_mode: - return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], - val[enable_id]); + return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], 0); } static __devinit int lp8788_dldo_probe(struct platform_device *pdev) -- cgit v0.10.2 From 7fa8a5975784cce646b3763e5d9957f8d688c9ce Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 6 Dec 2012 08:24:11 +0800 Subject: regulator: tps80031: Convert tps80031_ldo_ops to linear_min_sel and list_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index ce48049..b54300c 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -284,14 +284,6 @@ static int tps80031_ldo_get_voltage_sel(struct regulator_dev *rdev) return vsel & rdev->desc->vsel_mask; } -static int tps80031_ldo_list_voltage(struct regulator_dev *rdev, unsigned sel) -{ - if (sel == 0) - return 0; - else - return regulator_list_voltage_linear(rdev, sel - 1); -} - static int tps80031_vbus_is_enabled(struct regulator_dev *rdev) { struct tps80031_regulator *ri = rdev_get_drvdata(rdev); @@ -398,7 +390,7 @@ static struct regulator_ops tps80031_dcdc_ops = { }; static struct regulator_ops tps80031_ldo_ops = { - .list_voltage = tps80031_ldo_list_voltage, + .list_voltage = regulator_list_voltage_linear, .set_voltage_sel = tps80031_ldo_set_voltage_sel, .get_voltage_sel = tps80031_ldo_get_voltage_sel, .enable = tps80031_reg_enable, @@ -465,6 +457,7 @@ static struct regulator_ops tps80031_ext_reg_ops = { .type = REGULATOR_VOLTAGE, \ .min_uV = 1000000, \ .uV_step = 100000, \ + .linear_min_sel = 1, \ .n_voltages = 25, \ .vsel_mask = LDO_VSEL_MASK, \ .enable_time = 500, \ -- cgit v0.10.2 From 131a5b9d82f802e8e0320e81abf38ed2781bb35a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 7 Dec 2012 17:25:13 +0800 Subject: regulator: lp8788-buck: Kill _gpio_request function Simply use devm_gpio_request_one() instead. Signed-off-by: Axel Lin Acked-by: Milo(Woogyom) Kim Signed-off-by: Mark Brown diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c index ba3e0aa..fab2590 100644 --- a/drivers/regulator/lp8788-buck.c +++ b/drivers/regulator/lp8788-buck.c @@ -429,18 +429,6 @@ static struct regulator_desc lp8788_buck_desc[] = { }, }; -static int _gpio_request(struct lp8788_buck *buck, int gpio, char *name) -{ - struct device *dev = buck->lp->dev; - - if (!gpio_is_valid(gpio)) { - dev_err(dev, "invalid gpio: %d\n", gpio); - return -EINVAL; - } - - return devm_gpio_request_one(dev, gpio, DVS_LOW, name); -} - static int lp8788_dvs_gpio_request(struct lp8788_buck *buck, enum lp8788_buck_id id) { @@ -452,7 +440,8 @@ static int lp8788_dvs_gpio_request(struct lp8788_buck *buck, switch (id) { case BUCK1: gpio = pdata->buck1_dvs->gpio; - ret = _gpio_request(buck, gpio, b1_name); + ret = devm_gpio_request_one(buck->lp->dev, gpio, DVS_LOW, + b1_name); if (ret) return ret; @@ -461,7 +450,8 @@ static int lp8788_dvs_gpio_request(struct lp8788_buck *buck, case BUCK2: for (i = 0 ; i < LP8788_NUM_BUCK2_DVS ; i++) { gpio = pdata->buck2_dvs->gpio[i]; - ret = _gpio_request(buck, gpio, b2_name[i]); + ret = devm_gpio_request_one(buck->lp->dev, gpio, + DVS_LOW, b2_name[i]); if (ret) return ret; } -- cgit v0.10.2 From 4efd9dfecbf19a7a28f29b1142c07ba8327f2c8a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 29 Nov 2012 13:19:43 +0800 Subject: regulator: max1586: Implement get_voltage_sel callback This is required since commit f7df20ec32 "regulator: core: Use list_voltage() to read single voltage regulators", otherwise _regulator_get_voltage returns rdev->desc->ops->list_voltage(rdev, 0). The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back the set up value. Thus this patch caches the setting when setting new voltage. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index f67af3c..ed2d391 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -44,6 +44,9 @@ struct max1586_data { unsigned int min_uV; unsigned int max_uV; + unsigned int v3_curr_sel; + unsigned int v6_curr_sel; + struct regulator_dev *rdev[0]; }; @@ -63,31 +66,60 @@ static int v6_voltages_uv[] = { 1, 1800000, 2500000, 3000000 }; * R24 and R25=100kOhm as described in the data sheet. * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm */ +static int max1586_v3_get_voltage_sel(struct regulator_dev *rdev) +{ + struct max1586_data *max1586 = rdev_get_drvdata(rdev); + + return max1586->v3_curr_sel; +} + static int max1586_v3_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { struct max1586_data *max1586 = rdev_get_drvdata(rdev); struct i2c_client *client = max1586->client; + int ret; u8 v3_prog; dev_dbg(&client->dev, "changing voltage v3 to %dmv\n", regulator_list_voltage_linear(rdev, selector) / 1000); v3_prog = I2C_V3_SELECT | (u8) selector; - return i2c_smbus_write_byte(client, v3_prog); + ret = i2c_smbus_write_byte(client, v3_prog); + if (ret) + return ret; + + max1586->v3_curr_sel = selector; + + return 0; +} + +static int max1586_v6_get_voltage_sel(struct regulator_dev *rdev) +{ + struct max1586_data *max1586 = rdev_get_drvdata(rdev); + + return max1586->v6_curr_sel; } static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector) { - struct i2c_client *client = rdev_get_drvdata(rdev); + struct max1586_data *max1586 = rdev_get_drvdata(rdev); + struct i2c_client *client = max1586->client; u8 v6_prog; + int ret; dev_dbg(&client->dev, "changing voltage v6 to %dmv\n", rdev->desc->volt_table[selector] / 1000); v6_prog = I2C_V6_SELECT | (u8) selector; - return i2c_smbus_write_byte(client, v6_prog); + ret = i2c_smbus_write_byte(client, v6_prog); + if (ret) + return ret; + + max1586->v6_curr_sel = selector; + + return 0; } /* @@ -95,12 +127,14 @@ static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev, * the set up value. */ static struct regulator_ops max1586_v3_ops = { + .get_voltage_sel = max1586_v3_get_voltage_sel, .set_voltage_sel = max1586_v3_set_voltage_sel, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, }; static struct regulator_ops max1586_v6_ops = { + .get_voltage_sel = max1586_v6_get_voltage_sel, .set_voltage_sel = max1586_v6_set_voltage_sel, .list_voltage = regulator_list_voltage_table, }; @@ -148,6 +182,10 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000; max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000; + /* Set curr_sel to default voltage on power-up */ + max1586->v3_curr_sel = 24; /* 1.3V */ + max1586->v6_curr_sel = 0; + rdev = max1586->rdev; for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) { id = pdata->subdevs[i].id; -- cgit v0.10.2 From 985884db501d7026257d122c3cc32a7005a9a864 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 9 Dec 2012 08:05:45 +0800 Subject: regulator: anatop: Use linear_min_sel with linear mapping By setting linear_min_sel to anatop_reg->min_bit_val, we can avoid adjust the anatop_reg->min_bit_val offset in [set|get]_voltage_sel. With this chance we can refactor this driver to use regulator_[get|set]_voltage_sel_regmap. Signed-off-by: Axel Lin Reviewed-by: Ying-Chun Liu Signed-off-by: Mark Brown diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 1af9768..b78b622 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -48,18 +48,16 @@ static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg, unsigned selector) { struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); - u32 val, mask; + u32 mask; if (!anatop_reg->control_reg) return -ENOTSUPP; - val = anatop_reg->min_bit_val + selector; - dev_dbg(®->dev, "%s: calculated val %d\n", __func__, val); mask = ((1 << anatop_reg->vol_bit_width) - 1) << anatop_reg->vol_bit_shift; - val <<= anatop_reg->vol_bit_shift; + selector <<= anatop_reg->vol_bit_shift; regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg, - mask, val); + mask, selector); return 0; } @@ -77,7 +75,7 @@ static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg) anatop_reg->vol_bit_shift; val = (val & mask) >> anatop_reg->vol_bit_shift; - return val - anatop_reg->min_bit_val; + return val; } static struct regulator_ops anatop_rops = { @@ -158,10 +156,11 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) goto anatop_probe_end; } - rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) - / 25000 + 1; + rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1 + + sreg->min_bit_val; rdesc->min_uV = sreg->min_voltage; rdesc->uV_step = 25000; + rdesc->linear_min_sel = sreg->min_bit_val; config.dev = &pdev->dev; config.init_data = initdata; -- cgit v0.10.2 From e1b0144f9997d3d52c46785143699d82dd525f1d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 9 Dec 2012 08:07:43 +0800 Subject: regulator: anatop: Use regulator_[get|set]_voltage_sel_regmap Call regulator_[get|set]_voltage_sel_regmap instead of open code. Signed-off-by: Axel Lin Reviewed-by: Ying-Chun Liu Signed-off-by: Mark Brown diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index b78b622..b6182e1 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -48,34 +48,21 @@ static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg, unsigned selector) { struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); - u32 mask; if (!anatop_reg->control_reg) return -ENOTSUPP; - mask = ((1 << anatop_reg->vol_bit_width) - 1) << - anatop_reg->vol_bit_shift; - selector <<= anatop_reg->vol_bit_shift; - regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg, - mask, selector); - - return 0; + return regulator_set_voltage_sel_regmap(reg, selector); } static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg) { struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); - u32 val, mask; if (!anatop_reg->control_reg) return -ENOTSUPP; - regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val); - mask = ((1 << anatop_reg->vol_bit_width) - 1) << - anatop_reg->vol_bit_shift; - val = (val & mask) >> anatop_reg->vol_bit_shift; - - return val; + return regulator_get_voltage_sel_regmap(reg); } static struct regulator_ops anatop_rops = { @@ -161,11 +148,15 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) rdesc->min_uV = sreg->min_voltage; rdesc->uV_step = 25000; rdesc->linear_min_sel = sreg->min_bit_val; + rdesc->vsel_reg = sreg->control_reg; + rdesc->vsel_mask = ((1 << sreg->vol_bit_width) - 1) << + sreg->vol_bit_shift; config.dev = &pdev->dev; config.init_data = initdata; config.driver_data = sreg; config.of_node = pdev->dev.of_node; + config.regmap = sreg->anatop; /* register regulator */ rdev = regulator_register(rdesc, &config); -- cgit v0.10.2 From ad0b8b9e82b63ad2cc5e6822448adc897f49a5c4 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 10 Dec 2012 08:55:52 +0000 Subject: regulator: gpio-regulator: Fix logical error in for() loop The cond-statement of this particular for() loop will always be true as long as at least one voltage-shifting GPIO is present. If it wasn't for the break below, we'd be stuck in a forever loop. This patch inserts the correct cond-statement into the statement. Cc: Mark Brown Signed-off-by: Lee Jones Signed-off-by: Mark Brown diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 8c4e237..84e585f 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -174,7 +174,7 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) if (!config->gpios) return ERR_PTR(-ENOMEM); - for (i = 0; config->nr_gpios; i++) { + for (i = 0; i < config->nr_gpios; i++) { gpio = of_get_named_gpio(np, "gpios", i); if (gpio < 0) break; -- cgit v0.10.2 From 3708903ee60b1b89cbeee00cbc76e9fdbcbbed2e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 10 Dec 2012 08:55:53 +0000 Subject: regulator: gpio-regulator: gpio_set_value should use cansleep If it's possible for gpio_set_value to sleep, we should be using the *_cansleep call instead. This patch fixes multiple warnings from gpiolib. Cc: Mark Brown Signed-off-by: Lee Jones Signed-off-by: Mark Brown diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 84e585f..9f40b0d 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -82,7 +82,7 @@ static int gpio_regulator_set_voltage(struct regulator_dev *dev, for (ptr = 0; ptr < data->nr_gpios; ptr++) { state = (target & (1 << ptr)) >> ptr; - gpio_set_value(data->gpios[ptr].gpio, state); + gpio_set_value_cansleep(data->gpios[ptr].gpio, state); } data->state = target; @@ -119,7 +119,7 @@ static int gpio_regulator_set_current_limit(struct regulator_dev *dev, for (ptr = 0; ptr < data->nr_gpios; ptr++) { state = (target & (1 << ptr)) >> ptr; - gpio_set_value(data->gpios[ptr].gpio, state); + gpio_set_value_cansleep(data->gpios[ptr].gpio, state); } data->state = target; -- cgit v0.10.2 From 9bb096ff375f41e4c22000fd21f0ed01e2348c3e Mon Sep 17 00:00:00 2001 From: Amit Daniel Kachhap Date: Mon, 10 Dec 2012 18:19:39 +0530 Subject: regulator: s5m8767: Fix to work when platform registers less regulators Signed-off-by: Amit Daniel Kachhap Signed-off-by: Mark Brown diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index abe64a3..213c18b 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -168,7 +168,7 @@ static unsigned int s5m8767_opmode_reg[][4] = { static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, int *enable_ctrl) { - int reg_id = rdev_get_id(rdev); + int i, reg_id = rdev_get_id(rdev); unsigned int mode; struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); @@ -195,8 +195,17 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, return -EINVAL; } - mode = s5m8767->opmode[reg_id].mode; - *enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT; + for (i = 0; i < s5m8767->num_regulators; i++) { + if (s5m8767->opmode[i].id == reg_id) { + mode = s5m8767->opmode[i].mode; + break; + } + } + + if (i < s5m8767->num_regulators) + *enable_ctrl = + s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT; + return 0; } @@ -547,7 +556,7 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) rdev = s5m8767->rdev; s5m8767->dev = &pdev->dev; s5m8767->iodev = iodev; - s5m8767->num_regulators = S5M8767_REG_MAX - 2; + s5m8767->num_regulators = pdata->num_regulators; platform_set_drvdata(pdev, s5m8767); s5m8767->buck_gpioindex = pdata->buck_default_idx; -- cgit v0.10.2 From da130ab2dfd5201d5c09e83882f30d62f29ab5f5 Mon Sep 17 00:00:00 2001 From: Amit Daniel Kachhap Date: Mon, 10 Dec 2012 18:19:40 +0530 Subject: regulator: s5m8767: Fix to read the first DVS register. This patch modifies the DVS register read function to select correct DVS1 register. This change is required because the GPIO select pin is 000 in unintialized state and hence selects the DVS1 register. Signed-off-by: Amit Daniel Kachhap Signed-off-by: Mark Brown diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 213c18b..4afca9d 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -272,17 +272,17 @@ static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg) reg = S5M8767_REG_BUCK1CTRL2; break; case S5M8767_BUCK2: - reg = S5M8767_REG_BUCK2DVS2; + reg = S5M8767_REG_BUCK2DVS1; if (s5m8767->buck2_gpiodvs) reg += s5m8767->buck_gpioindex; break; case S5M8767_BUCK3: - reg = S5M8767_REG_BUCK3DVS2; + reg = S5M8767_REG_BUCK3DVS1; if (s5m8767->buck3_gpiodvs) reg += s5m8767->buck_gpioindex; break; case S5M8767_BUCK4: - reg = S5M8767_REG_BUCK4DVS2; + reg = S5M8767_REG_BUCK4DVS1; if (s5m8767->buck4_gpiodvs) reg += s5m8767->buck_gpioindex; break; -- cgit v0.10.2 From 76c854d1dfdce33354dc2481e5db31f27c6be3e3 Mon Sep 17 00:00:00 2001 From: Amit Daniel Kachhap Date: Mon, 10 Dec 2012 18:19:41 +0530 Subject: regulator: s5m8767: Fix to work even if no DVS gpio present Signed-off-by: Amit Daniel Kachhap Signed-off-by: Mark Brown diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 4afca9d..8ef5b33 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -626,9 +626,16 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) } } - if (gpio_is_valid(pdata->buck_gpios[0]) && - gpio_is_valid(pdata->buck_gpios[1]) && - gpio_is_valid(pdata->buck_gpios[2])) { + if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || + pdata->buck4_gpiodvs) { + + if (!gpio_is_valid(pdata->buck_gpios[0]) || + !gpio_is_valid(pdata->buck_gpios[1]) || + !gpio_is_valid(pdata->buck_gpios[2])) { + dev_err(&pdev->dev, "GPIO NOT VALID\n"); + return -EINVAL; + } + ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[0], "S5M8767 SET1"); if (ret) @@ -653,10 +660,6 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) /* SET3 GPIO */ gpio_direction_output(pdata->buck_gpios[2], (s5m8767->buck_gpioindex >> 0) & 0x1); - } else { - dev_err(&pdev->dev, "GPIO NOT VALID\n"); - ret = -EINVAL; - return ret; } ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[0], "S5M8767 DS2"); -- cgit v0.10.2 From 8a23b4e03d6873ec50f7d212de78ff01e393fc1a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 11 Dec 2012 20:36:37 +0800 Subject: regulator: core: Fix logic to determinate if regulator can change voltage Having a linear_min_sel setting means the first linear_min_sel selectors are invalid. We need to subtract linear_min_sel when use n_voltages to determinate if regulator can change voltage. Signed-off-by: Axel Lin Signed-off-by: Mark Brown diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 1c8ff8c..f3cdfe5 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1881,7 +1881,7 @@ int regulator_can_change_voltage(struct regulator *regulator) if (rdev->constraints && rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE && - rdev->desc->n_voltages > 1) + (rdev->desc->n_voltages - rdev->desc->linear_min_sel) > 1) return 1; return 0; -- cgit v0.10.2