aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/pcf50633-regulator.c
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@gmail.com>2012-03-18 22:55:24 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-04-01 06:59:22 -0400
commit022dcdf083d67db34f5237369d3501ca5708d8eb (patch)
tree042f725b831ecdf267e891a209f7a728d2e40d40 /drivers/regulator/pcf50633-regulator.c
parent7e44bb83a777fd67a70b2188dd31c33db25aef72 (diff)
regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register
The datasheet says 00000000 to 00101110 are reserved, and the min value of the voltage setting is 1.8 V. Thus don't write 0 to AUTO output voltage select register (address 1Ah). Table 50. AUTOOUT - AUTO output voltage select register (address 1Ah) bit description[1] Bit Symbol Access Description 7:0 auto_out R/W VO(prog) = 0.625 + auto_out × 0.025 V eg. 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) ..... ..... 11111110 : 3.800 V 11111111 : 3.800 V This patch also fixes a bug in pcf50633_regulator_list_voltage: In regulator core _regulator_do_set_voltage function: if (rdev->desc->ops->set_voltage) { ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, &selector); if (rdev->desc->ops->list_voltage) selector = rdev->desc->ops->list_voltage(rdev, selector); else selector = -1; The list_voltage call here takes the selector got from set_voltage callback. Thus adding 0x2f to the index in pcf50633_regulator_list_voltage looks wrong to me. e.g. If min_uV < 1.8V, pcf50633_regulator_set_voltage sets 0 to selector. For this case, adding 0x2f to the index in pcf50633_regulator_list_voltage is correct. However, if min_uV == 1.8V, pcf50633_regulator_set_voltage sets 0x2f to selector. Adding 0x2f to the index in pcf50633_regulator_list_voltage in this case is wrong. What this patch does is: The minimal voltage setting for AUTOOUT is 0x2f. Thus for the case min_uV < 1.8, set the voltage setting to 1.8V by writting 0x2f to AUTOOUT register and set selector = 0x2f. So we don't write the rserved range to AUTOOUT register. Which means the possible range of AUTOOUT register value is 0x2f ~ 0xff. We have no problem in regulator_get_voltage. Since we won't write 0~0x2e to AUTOOUT register, we have no problem converting the bits we read to voltage. The equation in auto_voltage_value works fine. For list_voltage, we need to take into account the case selector is 0 ~ 0x2e because the regulator core assumes the selector is starting from 0. This patch returns 0 for the cases selector is 0 ~ 0x2e, which means "this selector code can't be used on this system". The regulator core iterates from 0 to n_voltages to find the small voltage in the specific range. The n_voltages settings for AUTOOUT should be 128 now, including the reserved range of AUTOOUT. Signed-off-by: Axel Lin <axel.lin@gmail.com> Acked-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator/pcf50633-regulator.c')
-rw-r--r--drivers/regulator/pcf50633-regulator.c22
1 files changed, 6 insertions, 16 deletions
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index 6db46c632f13..c05b5d12b2ca 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -52,7 +52,7 @@ static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
52static u8 auto_voltage_bits(unsigned int millivolts) 52static u8 auto_voltage_bits(unsigned int millivolts)
53{ 53{
54 if (millivolts < 1800) 54 if (millivolts < 1800)
55 return 0; 55 return 0x2f;
56 if (millivolts > 3800) 56 if (millivolts > 3800)
57 return 0xff; 57 return 0xff;
58 58
@@ -87,6 +87,9 @@ static u8 ldo_voltage_bits(unsigned int millivolts)
87/* Obtain voltage value from bits */ 87/* Obtain voltage value from bits */
88static unsigned int auto_voltage_value(u8 bits) 88static unsigned int auto_voltage_value(u8 bits)
89{ 89{
90 /* AUTOOUT: 00000000 to 00101110 are reserved.
91 * Return 0 for bits in reserved range, which means this selector code
92 * can't be used on this system */
90 if (bits < 0x2f) 93 if (bits < 0x2f)
91 return 0; 94 return 0;
92 95
@@ -208,20 +211,7 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
208static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, 211static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
209 unsigned int index) 212 unsigned int index)
210{ 213{
211 struct pcf50633 *pcf; 214 int regulator_id = rdev_get_id(rdev);
212 int regulator_id;
213
214 pcf = rdev_get_drvdata(rdev);
215
216 regulator_id = rdev_get_id(rdev);
217
218 switch (regulator_id) {
219 case PCF50633_REGULATOR_AUTO:
220 index += 0x2f;
221 break;
222 default:
223 break;
224 }
225 215
226 return pcf50633_regulator_voltage_value(regulator_id, index); 216 return pcf50633_regulator_voltage_value(regulator_id, index);
227} 217}
@@ -287,7 +277,7 @@ static struct regulator_ops pcf50633_regulator_ops = {
287 277
288static struct regulator_desc regulators[] = { 278static struct regulator_desc regulators[] = {
289 [PCF50633_REGULATOR_AUTO] = 279 [PCF50633_REGULATOR_AUTO] =
290 PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 81), 280 PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 128),
291 [PCF50633_REGULATOR_DOWN1] = 281 [PCF50633_REGULATOR_DOWN1] =
292 PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 96), 282 PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 96),
293 [PCF50633_REGULATOR_DOWN2] = 283 [PCF50633_REGULATOR_DOWN2] =