diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 10:24:07 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 10:24:07 -0800 |
commit | 1896a1346a80b2dac1f63a338f1e2ee0b6484646 (patch) | |
tree | 825b59dd33886398f541488d2b5eb65cbd353bdb /drivers | |
parent | e691d24e9c5007486bef59c589c2a2d784e0c30b (diff) | |
parent | fa63bd4aa53aecc38956cbdd50f8ff9ed0d6d5ba (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6: (45 commits)
regulator: missing index in PTR_ERR() in isl6271a_probe()
regulator: Assign return value of mc13xxx_reg_rmw to ret
regulator: Add initial per-regulator debugfs support
regulator: Make regulator_has_full_constraints a bool
regulator: Clean up logging a bit
regulator: Optimise out noop voltage changes
regulator: Add API to re-apply voltage to hardware
regulator: Staticise non-exported functions in mc13892
regulator: Only notify voltage changes when they succeed
regulator: Provide a selector based set_voltage_sel() operation
regulator: Factor out voltage set operation into a separate function
regulator: Convert WM8994 to use get_voltage_sel()
regulator: Convert WM835x to use get_voltage_sel()
regulator: Allow modular build of mc13xxx-core
regulator: support PMIC mc13892
make mc13783 regulator code generic
Change the register name definitions for mc13783
mach-ux500: Updated and connected ab8500 regulator board configuration
regulators: Removed macros for initialization of ab8500 regulators
regulators: Added verbose debug messages to ab8500 regulators
...
Diffstat (limited to 'drivers')
32 files changed, 2613 insertions, 697 deletions
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 2ce2eb71d0f5..dd6308499bd4 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -249,7 +249,7 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) } static int pm8607_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) + int min_uV, int max_uV, unsigned *selector) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); uint8_t val, mask; @@ -263,6 +263,7 @@ static int pm8607_set_voltage(struct regulator_dev *rdev, ret = choose_voltage(rdev, min_uV, max_uV); if (ret < 0) return -EINVAL; + *selector = ret; val = (uint8_t)(ret << info->vol_shift); mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index dd30e883d4a7..e1d943619ab8 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -186,13 +186,25 @@ config REGULATOR_PCAP This driver provides support for the voltage regulators of the PCAP2 PMIC. +config REGULATOR_MC13XXX_CORE + tristate + config REGULATOR_MC13783 tristate "Support regulators on Freescale MC13783 PMIC" depends on MFD_MC13783 + select REGULATOR_MC13XXX_CORE help Say y here to support the regulators found on the Freescale MC13783 PMIC. +config REGULATOR_MC13892 + tristate "Support regulators on Freescale MC13892 PMIC" + depends on MFD_MC13XXX + select REGULATOR_MC13XXX_CORE + help + Say y here to support the regulators found on the Freescale MC13892 + PMIC. + config REGULATOR_AB3100 tristate "ST-Ericsson AB3100 Regulator functions" depends on AB3100_CORE @@ -250,5 +262,15 @@ config REGULATOR_TPS6586X help This driver supports TPS6586X voltage regulator chips. +config REGULATOR_TPS6524X + tristate "TI TPS6524X Power regulators" + depends on SPI + help + This driver supports TPS6524X voltage regulator chips. TPS6524X + provides three step-down converters and two general-purpose LDO + voltage regulators. This device is interfaced using a customized + serial interface currently supported on the sequencer serial + port controller. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index bff815736780..0b5e88c2b8d7 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -30,10 +30,13 @@ obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o 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_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o +obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index b349266a43de..ed6feaf9398d 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -362,7 +362,8 @@ static int ab3100_get_best_voltage_index(struct regulator_dev *reg, } static int ab3100_set_voltage_regulator(struct regulator_dev *reg, - int min_uV, int max_uV) + int min_uV, int max_uV, + unsigned *selector) { struct ab3100_regulator *abreg = reg->reg_data; u8 regval; @@ -373,6 +374,8 @@ static int ab3100_set_voltage_regulator(struct regulator_dev *reg, if (bestindex < 0) return bestindex; + *selector = bestindex; + err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg, ®val); if (err) { diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index db6b70f20511..d9a052c53aec 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -3,18 +3,13 @@ * * License Terms: GNU General Public License v2 * - * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson + * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson + * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson * * AB8500 peripheral regulators * - * AB8500 supports the following regulators, - * LDOs - VAUDIO, VANAMIC2/2, VDIGMIC, VINTCORE12, VTVOUT, - * VAUX1/2/3, VANA - * - * for DB8500 cut 1.0 and previous versions of the silicon, all accesses - * to registers are through the DB8500 SPI. In cut 1.1 onwards, these - * accesses are through the DB8500 PRCMU I2C - * + * AB8500 supports the following regulators: + * VAUX1/2/3, VINTCORE, VTVOUT, VAUDIO, VAMIC1/2, VDMIC, VANA */ #include <linux/init.h> #include <linux/kernel.h> @@ -28,38 +23,37 @@ /** * struct ab8500_regulator_info - ab8500 regulator information + * @dev: device pointer * @desc: regulator description - * @ab8500: ab8500 parent * @regulator_dev: regulator device * @max_uV: maximum voltage (for variable voltage supplies) * @min_uV: minimum voltage (for variable voltage supplies) * @fixed_uV: typical voltage (for fixed voltage supplies) * @update_bank: bank to control on/off * @update_reg: register to control on/off - * @mask: mask to enable/disable regulator - * @enable: bits to enable the regulator in normal(high power) mode + * @update_mask: mask to enable/disable regulator + * @update_val_enable: bits to enable the regulator in normal (high power) mode * @voltage_bank: bank to control regulator voltage * @voltage_reg: register to control regulator voltage * @voltage_mask: mask to control regulator voltage - * @supported_voltages: supported voltage table + * @voltages: supported voltage table * @voltages_len: number of supported voltages for the regulator */ struct ab8500_regulator_info { struct device *dev; struct regulator_desc desc; - struct ab8500 *ab8500; struct regulator_dev *regulator; int max_uV; int min_uV; int fixed_uV; u8 update_bank; u8 update_reg; - u8 mask; - u8 enable; + u8 update_mask; + u8 update_val_enable; u8 voltage_bank; u8 voltage_reg; u8 voltage_mask; - int const *supported_voltages; + int const *voltages; int voltages_len; }; @@ -83,6 +77,17 @@ static const int ldo_vauxn_voltages[] = { 3300000, }; +static const int ldo_vaux3_voltages[] = { + 1200000, + 1500000, + 1800000, + 2100000, + 2500000, + 2750000, + 2790000, + 2910000, +}; + static const int ldo_vintcore_voltages[] = { 1200000, 1225000, @@ -95,57 +100,80 @@ static const int ldo_vintcore_voltages[] = { static int ab8500_regulator_enable(struct regulator_dev *rdev) { - int regulator_id, ret; + int ret; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - regulator_id = rdev_get_id(rdev); - if (regulator_id >= AB8500_NUM_REGULATORS) + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; + } ret = abx500_mask_and_set_register_interruptible(info->dev, - info->update_bank, info->update_reg, info->mask, info->enable); + info->update_bank, info->update_reg, + info->update_mask, info->update_val_enable); if (ret < 0) dev_err(rdev_get_dev(rdev), "couldn't set enable bits for regulator\n"); + + dev_vdbg(rdev_get_dev(rdev), + "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", + info->desc.name, info->update_bank, info->update_reg, + info->update_mask, info->update_val_enable); + return ret; } static int ab8500_regulator_disable(struct regulator_dev *rdev) { - int regulator_id, ret; + int ret; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - regulator_id = rdev_get_id(rdev); - if (regulator_id >= AB8500_NUM_REGULATORS) + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; + } ret = abx500_mask_and_set_register_interruptible(info->dev, - info->update_bank, info->update_reg, info->mask, 0x0); + info->update_bank, info->update_reg, + info->update_mask, 0x0); if (ret < 0) dev_err(rdev_get_dev(rdev), "couldn't set disable bits for regulator\n"); + + dev_vdbg(rdev_get_dev(rdev), + "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", + info->desc.name, info->update_bank, info->update_reg, + info->update_mask, 0x0); + return ret; } static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) { - int regulator_id, ret; + int ret; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - u8 value; + u8 regval; - regulator_id = rdev_get_id(rdev); - if (regulator_id >= AB8500_NUM_REGULATORS) + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; + } ret = abx500_get_register_interruptible(info->dev, - info->update_bank, info->update_reg, &value); + info->update_bank, info->update_reg, ®val); if (ret < 0) { dev_err(rdev_get_dev(rdev), "couldn't read 0x%x register\n", info->update_reg); return ret; } - if (value & info->mask) + dev_vdbg(rdev_get_dev(rdev), + "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x," + " 0x%x\n", + info->desc.name, info->update_bank, info->update_reg, + info->update_mask, regval); + + if (regval & info->update_mask) return true; else return false; @@ -153,12 +181,12 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) { - int regulator_id; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - regulator_id = rdev_get_id(rdev); - if (regulator_id >= AB8500_NUM_REGULATORS) + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; + } /* return the uV for the fixed regulators */ if (info->fixed_uV) @@ -167,33 +195,40 @@ static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) if (selector >= info->voltages_len) return -EINVAL; - return info->supported_voltages[selector]; + return info->voltages[selector]; } static int ab8500_regulator_get_voltage(struct regulator_dev *rdev) { - int regulator_id, ret; + int ret, val; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - u8 value; + u8 regval; - regulator_id = rdev_get_id(rdev); - if (regulator_id >= AB8500_NUM_REGULATORS) + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; + } - ret = abx500_get_register_interruptible(info->dev, info->voltage_bank, - info->voltage_reg, &value); + ret = abx500_get_register_interruptible(info->dev, + info->voltage_bank, info->voltage_reg, ®val); if (ret < 0) { dev_err(rdev_get_dev(rdev), "couldn't read voltage reg for regulator\n"); return ret; } + dev_vdbg(rdev_get_dev(rdev), + "%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x," + " 0x%x\n", + info->desc.name, info->voltage_bank, info->voltage_reg, + info->voltage_mask, regval); + /* vintcore has a different layout */ - value &= info->voltage_mask; - if (regulator_id == AB8500_LDO_INTCORE) - ret = info->supported_voltages[value >> 0x3]; + val = regval & info->voltage_mask; + if (info->desc.id == AB8500_LDO_INTCORE) + ret = info->voltages[val >> 0x3]; else - ret = info->supported_voltages[value]; + ret = info->voltages[val]; return ret; } @@ -206,8 +241,8 @@ static int ab8500_get_best_voltage_index(struct regulator_dev *rdev, /* check the supported voltage */ for (i = 0; i < info->voltages_len; i++) { - if ((info->supported_voltages[i] >= min_uV) && - (info->supported_voltages[i] <= max_uV)) + if ((info->voltages[i] >= min_uV) && + (info->voltages[i] <= max_uV)) return i; } @@ -215,14 +250,17 @@ static int ab8500_get_best_voltage_index(struct regulator_dev *rdev, } static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) + int min_uV, int max_uV, + unsigned *selector) { - int regulator_id, ret; + int ret; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + u8 regval; - regulator_id = rdev_get_id(rdev); - if (regulator_id >= AB8500_NUM_REGULATORS) + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; + } /* get the appropriate voltages within the range */ ret = ab8500_get_best_voltage_index(rdev, min_uV, max_uV); @@ -232,14 +270,23 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, return ret; } + *selector = ret; + /* set the registers for the request */ + regval = (u8)ret; ret = abx500_mask_and_set_register_interruptible(info->dev, - info->voltage_bank, info->voltage_reg, - info->voltage_mask, (u8)ret); + info->voltage_bank, info->voltage_reg, + info->voltage_mask, regval); if (ret < 0) dev_err(rdev_get_dev(rdev), "couldn't set voltage reg for regulator\n"); + dev_vdbg(rdev_get_dev(rdev), + "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x," + " 0x%x\n", + info->desc.name, info->voltage_bank, info->voltage_reg, + info->voltage_mask, regval); + return ret; } @@ -254,17 +301,17 @@ static struct regulator_ops ab8500_regulator_ops = { static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) { - int regulator_id; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - regulator_id = rdev_get_id(rdev); - if (regulator_id >= AB8500_NUM_REGULATORS) + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; + } return info->fixed_uV; } -static struct regulator_ops ab8500_ldo_fixed_ops = { +static struct regulator_ops ab8500_regulator_fixed_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, @@ -272,88 +319,197 @@ static struct regulator_ops ab8500_ldo_fixed_ops = { .list_voltage = ab8500_list_voltage, }; -#define AB8500_LDO(_id, min, max, bank, reg, reg_mask, \ - reg_enable, volt_bank, volt_reg, volt_mask, \ - voltages, len_volts) \ -{ \ - .desc = { \ - .name = "LDO-" #_id, \ - .ops = &ab8500_regulator_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = AB8500_LDO_##_id, \ - .owner = THIS_MODULE, \ - }, \ - .min_uV = (min) * 1000, \ - .max_uV = (max) * 1000, \ - .update_bank = bank, \ - .update_reg = reg, \ - .mask = reg_mask, \ - .enable = reg_enable, \ - .voltage_bank = volt_bank, \ - .voltage_reg = volt_reg, \ - .voltage_mask = volt_mask, \ - .supported_voltages = voltages, \ - .voltages_len = len_volts, \ - .fixed_uV = 0, \ -} - -#define AB8500_FIXED_LDO(_id, fixed, bank, reg, \ - reg_mask, reg_enable) \ -{ \ - .desc = { \ - .name = "LDO-" #_id, \ - .ops = &ab8500_ldo_fixed_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = AB8500_LDO_##_id, \ - .owner = THIS_MODULE, \ - }, \ - .fixed_uV = fixed * 1000, \ - .update_bank = bank, \ - .update_reg = reg, \ - .mask = reg_mask, \ - .enable = reg_enable, \ -} - -static struct ab8500_regulator_info ab8500_regulator_info[] = { +static struct ab8500_regulator_info + ab8500_regulator_info[AB8500_NUM_REGULATORS] = { /* - * Variable Voltage LDOs - * name, min uV, max uV, ctrl bank, ctrl reg, reg mask, enable mask, - * volt ctrl bank, volt ctrl reg, volt ctrl mask, volt table, - * num supported volts + * Variable Voltage Regulators + * name, min mV, max mV, + * update bank, reg, mask, enable val + * volt bank, reg, mask, table, table length */ - AB8500_LDO(AUX1, 1100, 3300, 0x04, 0x09, 0x3, 0x1, 0x04, 0x1f, 0xf, - ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), - AB8500_LDO(AUX2, 1100, 3300, 0x04, 0x09, 0xc, 0x4, 0x04, 0x20, 0xf, - ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), - AB8500_LDO(AUX3, 1100, 3300, 0x04, 0x0a, 0x3, 0x1, 0x04, 0x21, 0xf, - ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), - AB8500_LDO(INTCORE, 1100, 3300, 0x03, 0x80, 0x4, 0x4, 0x03, 0x80, 0x38, - ldo_vintcore_voltages, ARRAY_SIZE(ldo_vintcore_voltages)), + [AB8500_LDO_AUX1] = { + .desc = { + .name = "LDO-AUX1", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUX1, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), + }, + .min_uV = 1100000, + .max_uV = 3300000, + .update_bank = 0x04, + .update_reg = 0x09, + .update_mask = 0x03, + .update_val_enable = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x1f, + .voltage_mask = 0x0f, + .voltages = ldo_vauxn_voltages, + .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), + }, + [AB8500_LDO_AUX2] = { + .desc = { + .name = "LDO-AUX2", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUX2, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), + }, + .min_uV = 1100000, + .max_uV = 3300000, + .update_bank = 0x04, + .update_reg = 0x09, + .update_mask = 0x0c, + .update_val_enable = 0x04, + .voltage_bank = 0x04, + .voltage_reg = 0x20, + .voltage_mask = 0x0f, + .voltages = ldo_vauxn_voltages, + .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), + }, + [AB8500_LDO_AUX3] = { + .desc = { + .name = "LDO-AUX3", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUX3, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages), + }, + .min_uV = 1100000, + .max_uV = 3300000, + .update_bank = 0x04, + .update_reg = 0x0a, + .update_mask = 0x03, + .update_val_enable = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x21, + .voltage_mask = 0x07, + .voltages = ldo_vaux3_voltages, + .voltages_len = ARRAY_SIZE(ldo_vaux3_voltages), + }, + [AB8500_LDO_INTCORE] = { + .desc = { + .name = "LDO-INTCORE", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_INTCORE, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages), + }, + .min_uV = 1100000, + .max_uV = 3300000, + .update_bank = 0x03, + .update_reg = 0x80, + .update_mask = 0x44, + .update_val_enable = 0x04, + .voltage_bank = 0x03, + .voltage_reg = 0x80, + .voltage_mask = 0x38, + .voltages = ldo_vintcore_voltages, + .voltages_len = ARRAY_SIZE(ldo_vintcore_voltages), + }, /* - * Fixed Voltage LDOs - * name, o/p uV, ctrl bank, ctrl reg, enable, disable + * Fixed Voltage Regulators + * name, fixed mV, + * update bank, reg, mask, enable val */ - AB8500_FIXED_LDO(TVOUT, 2000, 0x03, 0x80, 0x2, 0x2), - AB8500_FIXED_LDO(AUDIO, 2000, 0x03, 0x83, 0x2, 0x2), - AB8500_FIXED_LDO(ANAMIC1, 2050, 0x03, 0x83, 0x4, 0x4), - AB8500_FIXED_LDO(ANAMIC2, 2050, 0x03, 0x83, 0x8, 0x8), - AB8500_FIXED_LDO(DMIC, 1800, 0x03, 0x83, 0x10, 0x10), - AB8500_FIXED_LDO(ANA, 1200, 0x03, 0x83, 0xc, 0x4), -}; + [AB8500_LDO_TVOUT] = { + .desc = { + .name = "LDO-TVOUT", + .ops = &ab8500_regulator_fixed_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_TVOUT, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 2000000, + .update_bank = 0x03, + .update_reg = 0x80, + .update_mask = 0x82, + .update_val_enable = 0x02, + }, + [AB8500_LDO_AUDIO] = { + .desc = { + .name = "LDO-AUDIO", + .ops = &ab8500_regulator_fixed_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUDIO, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 2000000, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x02, + .update_val_enable = 0x02, + }, + [AB8500_LDO_ANAMIC1] = { + .desc = { + .name = "LDO-ANAMIC1", + .ops = &ab8500_regulator_fixed_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_ANAMIC1, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 2050000, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x08, + .update_val_enable = 0x08, + }, + [AB8500_LDO_ANAMIC2] = { + .desc = { + .name = "LDO-ANAMIC2", + .ops = &ab8500_regulator_fixed_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_ANAMIC2, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 2050000, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x10, + .update_val_enable = 0x10, + }, + [AB8500_LDO_DMIC] = { + .desc = { + .name = "LDO-DMIC", + .ops = &ab8500_regulator_fixed_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_DMIC, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 1800000, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x04, + .update_val_enable = 0x04, + }, + [AB8500_LDO_ANA] = { + .desc = { + .name = "LDO-ANA", + .ops = &ab8500_regulator_fixed_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_ANA, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 1200000, + .update_bank = 0x04, + .update_reg = 0x06, + .update_mask = 0x0c, + .update_val_enable = 0x04, + }, -static inline struct ab8500_regulator_info *find_regulator_info(int id) -{ - struct ab8500_regulator_info *info; - int i; - for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { - info = &ab8500_regulator_info[i]; - if (info->desc.id == id) - return info; - } - return NULL; -} +}; static __devinit int ab8500_regulator_probe(struct platform_device *pdev) { @@ -366,6 +522,16 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) return -EINVAL; } pdata = dev_get_platdata(ab8500->dev); + if (!pdata) { + dev_err(&pdev->dev, "null pdata\n"); + return -EINVAL; + } + + /* make sure the platform data has the correct size */ + if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) { + dev_err(&pdev->dev, "platform configuration error\n"); + return -EINVAL; + } /* register all regulators */ for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { @@ -374,10 +540,22 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) /* assign per-regulator data */ info = &ab8500_regulator_info[i]; info->dev = &pdev->dev; - info->ab8500 = ab8500; + /* fix for hardware before ab8500v2.0 */ + if (abx500_get_chip_id(info->dev) < 0x20) { + if (info->desc.id == AB8500_LDO_AUX3) { + info->desc.n_voltages = + ARRAY_SIZE(ldo_vauxn_voltages); + info->voltages = ldo_vauxn_voltages; + info->voltages_len = + ARRAY_SIZE(ldo_vauxn_voltages); + info->voltage_mask = 0xf; + } + } + + /* register regulator with framework */ info->regulator = regulator_register(&info->desc, &pdev->dev, - pdata->regulator[i], info); + &pdata->regulator[i], info); if (IS_ERR(info->regulator)) { err = PTR_ERR(info->regulator); dev_err(&pdev->dev, "failed to register regulator %s\n", @@ -389,6 +567,9 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) } return err; } + + dev_vdbg(rdev_get_dev(info->regulator), + "%s-probed\n", info->desc.name); } return 0; @@ -401,6 +582,10 @@ static __devexit int ab8500_regulator_remove(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { struct ab8500_regulator_info *info = NULL; info = &ab8500_regulator_info[i]; + + dev_vdbg(rdev_get_dev(info->regulator), + "%s-remove\n", info->desc.name); + regulator_unregister(info->regulator); } diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ba521f0f0fac..9fa20957847d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -13,8 +13,11 @@ * */ +#define pr_fmt(fmt) "%s: " fmt, __func__ + #include <linux/kernel.h> #include <linux/init.h> +#include <linux/debugfs.h> #include <linux/device.h> #include <linux/slab.h> #include <linux/err.h> @@ -25,16 +28,30 @@ #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> +#define CREATE_TRACE_POINTS +#include <trace/events/regulator.h> + #include "dummy.h" -#define REGULATOR_VERSION "0.5" +#define rdev_err(rdev, fmt, ...) \ + pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) +#define rdev_warn(rdev, fmt, ...) \ + pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) +#define rdev_info(rdev, fmt, ...) \ + pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) +#define rdev_dbg(rdev, fmt, ...) \ + pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) static DEFINE_MUTEX(regulator_list_mutex); static LIST_HEAD(regulator_list); static LIST_HEAD(regulator_map_list); -static int has_full_constraints; +static bool has_full_constraints; static bool board_wants_dummy_regulator; +#ifdef CONFIG_DEBUG_FS +static struct dentry *debugfs_root; +#endif + /* * struct regulator_map * @@ |