* [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register @ 2012-03-17 0:07 Axel Lin 2012-03-17 0:08 ` [PATCH v2 2/2] regulator: Convert pcf50633 to get_voltage_sel Axel Lin 2012-03-18 11:06 ` [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register Lars-Peter Clausen 0 siblings, 2 replies; 6+ messages in thread From: Axel Lin @ 2012-03-17 0:07 UTC (permalink / raw) To: linux-kernel; +Cc: Lars-Peter Clausen, Liam Girdwood, Mark Brown 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. It is wrong to do "index += 0x2f" for PCF50633_REGULATOR_AUTO in pcf50633_regulator_list_voltage. The purpose of adding 0x2f to index is because current code return 0 in auto_voltage_bits when millivolts < 1800. For millivolts > 1800, adding 0x2f to index is wrong. We should handle this by return 0 if the selector is in the reserved range of AUTOOUT. Signed-off-by: Axel Lin <axel.lin@gmail.com> --- drivers/regulator/pcf50633-regulator.c | 23 +++++------------------ 1 files changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 6db46c6..9ef7dff 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] = { static u8 auto_voltage_bits(unsigned int millivolts) { if (millivolts < 1800) - return 0; + return 0x2f; if (millivolts > 3800) return 0xff; @@ -87,9 +87,6 @@ static u8 ldo_voltage_bits(unsigned int millivolts) /* Obtain voltage value from bits */ static unsigned int auto_voltage_value(u8 bits) { - if (bits < 0x2f) - return 0; - return 625 + (bits * 25); } @@ -161,6 +158,9 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id, switch (id) { case PCF50633_REGULATOR_AUTO: + /* AUTOOUT: 00000000 to 00101110 are reserved */ + if (bits < 0x2f) + return 0; millivolts = auto_voltage_value(bits); break; case PCF50633_REGULATOR_DOWN1: @@ -208,20 +208,7 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, unsigned int index) { - struct pcf50633 *pcf; - int regulator_id; - - pcf = rdev_get_drvdata(rdev); - - regulator_id = rdev_get_id(rdev); - - switch (regulator_id) { - case PCF50633_REGULATOR_AUTO: - index += 0x2f; - break; - default: - break; - } + int regulator_id = rdev_get_id(rdev); return pcf50633_regulator_voltage_value(regulator_id, index); } -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] regulator: Convert pcf50633 to get_voltage_sel 2012-03-17 0:07 [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register Axel Lin @ 2012-03-17 0:08 ` Axel Lin 2012-03-18 11:09 ` Lars-Peter Clausen 2012-03-18 11:06 ` [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register Lars-Peter Clausen 1 sibling, 1 reply; 6+ messages in thread From: Axel Lin @ 2012-03-17 0:08 UTC (permalink / raw) To: linux-kernel; +Cc: Lars-Peter Clausen, Liam Girdwood, Mark Brown Convert pcf50633 to get_voltage_sel and then we can remove pcf50633_regulator_voltage_value function and move its implementation to pcf50633_regulator_list_voltage. Signed-off-by: Axel Lin <axel.lin@gmail.com> --- drivers/regulator/pcf50633-regulator.c | 65 ++++++++++++++----------------- 1 files changed, 29 insertions(+), 36 deletions(-) diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 9ef7dff..b02cbb9 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c @@ -151,23 +151,43 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, return pcf50633_reg_write(pcf, regnr, volt_bits); } -static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id, - u8 bits) +static int pcf50633_regulator_get_voltage_sel(struct regulator_dev *rdev) { + struct pcf50633 *pcf; + int regulator_id; + u8 volt_bits, regnr; + + pcf = rdev_get_drvdata(rdev); + + regulator_id = rdev_get_id(rdev); + if (regulator_id >= PCF50633_NUM_REGULATORS) + return -EINVAL; + + regnr = pcf50633_regulator_registers[regulator_id]; + + volt_bits = pcf50633_reg_read(pcf, regnr); + + 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 (id) { + switch (regulator_id) { case PCF50633_REGULATOR_AUTO: /* AUTOOUT: 00000000 to 00101110 are reserved */ - if (bits < 0x2f) + if (index < 0x2f) return 0; - millivolts = auto_voltage_value(bits); + millivolts = auto_voltage_value(index); break; case PCF50633_REGULATOR_DOWN1: - millivolts = down_voltage_value(bits); + millivolts = down_voltage_value(index); break; case PCF50633_REGULATOR_DOWN2: - millivolts = down_voltage_value(bits); + millivolts = down_voltage_value(index); break; case PCF50633_REGULATOR_LDO1: case PCF50633_REGULATOR_LDO2: @@ -177,7 +197,7 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id, case PCF50633_REGULATOR_LDO6: case PCF50633_REGULATOR_HCLDO: case PCF50633_REGULATOR_MEMLDO: - millivolts = ldo_voltage_value(bits); + millivolts = ldo_voltage_value(index); break; default: return -EINVAL; @@ -186,33 +206,6 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id, return millivolts * 1000; } -static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) -{ - struct pcf50633 *pcf; - int regulator_id; - u8 volt_bits, regnr; - - pcf = rdev_get_drvdata(rdev); - - regulator_id = rdev_get_id(rdev); - if (regulator_id >= PCF50633_NUM_REGULATORS) - return -EINVAL; - - regnr = pcf50633_regulator_registers[regulator_id]; - - volt_bits = pcf50633_reg_read(pcf, regnr); - - return pcf50633_regulator_voltage_value(regulator_id, volt_bits); -} - -static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, - unsigned int index) -{ - int regulator_id = rdev_get_id(rdev); - - return pcf50633_regulator_voltage_value(regulator_id, index); -} - static int pcf50633_regulator_enable(struct regulator_dev *rdev) { struct pcf50633 *pcf = rdev_get_drvdata(rdev); @@ -265,7 +258,7 @@ static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev) static struct regulator_ops pcf50633_regulator_ops = { .set_voltage = pcf50633_regulator_set_voltage, - .get_voltage = pcf50633_regulator_get_voltage, + .get_voltage_sel = pcf50633_regulator_get_voltage_sel, .list_voltage = pcf50633_regulator_list_voltage, .enable = pcf50633_regulator_enable, .disable = pcf50633_regulator_disable, -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] regulator: Convert pcf50633 to get_voltage_sel 2012-03-17 0:08 ` [PATCH v2 2/2] regulator: Convert pcf50633 to get_voltage_sel Axel Lin @ 2012-03-18 11:09 ` Lars-Peter Clausen 0 siblings, 0 replies; 6+ messages in thread From: Lars-Peter Clausen @ 2012-03-18 11:09 UTC (permalink / raw) To: Axel Lin; +Cc: linux-kernel, Liam Girdwood, Mark Brown On 03/17/2012 01:08 AM, Axel Lin wrote: > Convert pcf50633 to get_voltage_sel and then we can remove > pcf50633_regulator_voltage_value function and move its implementation > to pcf50633_regulator_list_voltage. > > Signed-off-by: Axel Lin <axel.lin@gmail.com> Acked-by: Lars-Peter Clausen <lars@metafoo.de> One minor comment inline though. > --- > drivers/regulator/pcf50633-regulator.c | 65 ++++++++++++++----------------- > 1 files changed, 29 insertions(+), 36 deletions(-) > > diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c > index 9ef7dff..b02cbb9 100644 > --- a/drivers/regulator/pcf50633-regulator.c > +++ b/drivers/regulator/pcf50633-regulator.c > @@ -151,23 +151,43 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, > return pcf50633_reg_write(pcf, regnr, volt_bits); > } > > -static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id, > - u8 bits) > +static int pcf50633_regulator_get_voltage_sel(struct regulator_dev *rdev) > { > + struct pcf50633 *pcf; > + int regulator_id; > + u8 volt_bits, regnr; > + > + pcf = rdev_get_drvdata(rdev); > + > + regulator_id = rdev_get_id(rdev); > + if (regulator_id >= PCF50633_NUM_REGULATORS) > + return -EINVAL; > + > + regnr = pcf50633_regulator_registers[regulator_id]; > + > + volt_bits = pcf50633_reg_read(pcf, regnr); > + > + return volt_bits; Might as well just do "return pcf50633_reg_read(pcf, regnr);" ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register 2012-03-17 0:07 [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register Axel Lin 2012-03-17 0:08 ` [PATCH v2 2/2] regulator: Convert pcf50633 to get_voltage_sel Axel Lin @ 2012-03-18 11:06 ` Lars-Peter Clausen 2012-03-19 2:53 ` Axel Lin 1 sibling, 1 reply; 6+ messages in thread From: Lars-Peter Clausen @ 2012-03-18 11:06 UTC (permalink / raw) To: Axel Lin; +Cc: linux-kernel, Liam Girdwood, Mark Brown On 03/17/2012 01:07 AM, Axel Lin wrote: > 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. > It is wrong to do "index += 0x2f" for PCF50633_REGULATOR_AUTO in > pcf50633_regulator_list_voltage. The purpose of adding 0x2f to index is because > current code return 0 in auto_voltage_bits when millivolts < 1800. > For millivolts > 1800, adding 0x2f to index is wrong. > I think you misunderstood what the current code does. The first usable voltage is 1.8V which is equal to a index of of 0x2f. So the driver adds 0x2f to the index so that there is not a headroom of 0x2f unusable voltages. So a selector of 0 translates to 1.8V, a selector of 1 translates to 1.825V and so on. I can see why you'd want to change it to simplify the code, but you also have to change the number of voltages for the AUTO regulator to 128. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register 2012-03-18 11:06 ` [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register Lars-Peter Clausen @ 2012-03-19 2:53 ` Axel Lin 2012-03-19 9:07 ` Lars-Peter Clausen 0 siblings, 1 reply; 6+ messages in thread From: Axel Lin @ 2012-03-19 2:53 UTC (permalink / raw) To: Lars-Peter Clausen; +Cc: linux-kernel, Liam Girdwood, Mark Brown 2012/3/18 Lars-Peter Clausen <lars@metafoo.de>: > On 03/17/2012 01:07 AM, Axel Lin wrote: >> 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. >> It is wrong to do "index += 0x2f" for PCF50633_REGULATOR_AUTO in >> pcf50633_regulator_list_voltage. The purpose of adding 0x2f to index is because >> current code return 0 in auto_voltage_bits when millivolts < 1800. >> For millivolts > 1800, adding 0x2f to index is wrong. >> > > I think you misunderstood what the current code does. The first usable voltage > is 1.8V which is equal to a index of of 0x2f. So the driver adds 0x2f to the > index so that there is not a headroom of 0x2f unusable voltages. So a selector > of 0 translates to 1.8V, a selector of 1 translates to 1.825V and so on. I think what I wry to explain is: 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 exactly what you want. 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". > > I can see why you'd want to change it to simplify the code, but you also have > to change the number of voltages for the AUTO regulator to 128. yes, I missed that. The regulator core iterates from 0 to n_voltages to find the small voltage in the specific range. So yes, I think the n_voltages settings for AUTOOUT should be 128 now, including the reserved range of AUTOOUT. I'll send a V3 for review and update the commit log. Thanks, Axel ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register 2012-03-19 2:53 ` Axel Lin @ 2012-03-19 9:07 ` Lars-Peter Clausen 0 siblings, 0 replies; 6+ messages in thread From: Lars-Peter Clausen @ 2012-03-19 9:07 UTC (permalink / raw) To: axel.lin; +Cc: linux-kernel, Liam Girdwood, Mark Brown On 03/19/2012 03:53 AM, Axel Lin wrote: > 2012/3/18 Lars-Peter Clausen <lars@metafoo.de>: >> On 03/17/2012 01:07 AM, Axel Lin wrote: >>> 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. >>> It is wrong to do "index += 0x2f" for PCF50633_REGULATOR_AUTO in >>> pcf50633_regulator_list_voltage. The purpose of adding 0x2f to index is because >>> current code return 0 in auto_voltage_bits when millivolts < 1800. >>> For millivolts > 1800, adding 0x2f to index is wrong. >>> >> >> I think you misunderstood what the current code does. The first usable voltage >> is 1.8V which is equal to a index of of 0x2f. So the driver adds 0x2f to the >> index so that there is not a headroom of 0x2f unusable voltages. So a selector >> of 0 translates to 1.8V, a selector of 1 translates to 1.825V and so on. > I think what I wry to explain is: > 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. > Ah ok, now I understand what you mean. When the selector parameter to set_voltage was introduced we already had list_voltage adding the 0x2f, so from my point of view list_voltage is correct and the bug is in the commit which introduced the selector parameter to select voltage, that's why I was confused as to why you think there was a bug in list_voltage. But it all makes sense now, thanks. Luckily the bug is not so critical, since selector is not really used in _regulator_do_set_voltage in this case except for the trace message. - Lars ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-03-19 9:05 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-03-17 0:07 [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register Axel Lin 2012-03-17 0:08 ` [PATCH v2 2/2] regulator: Convert pcf50633 to get_voltage_sel Axel Lin 2012-03-18 11:09 ` Lars-Peter Clausen 2012-03-18 11:06 ` [PATCH v2 1/2] regulator: pcf50633: Don't write to reserved bits of AUTO output voltage select register Lars-Peter Clausen 2012-03-19 2:53 ` Axel Lin 2012-03-19 9:07 ` Lars-Peter Clausen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox