aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Kozlowski <k.kozlowski@samsung.com>2016-03-28 00:09:56 -0400
committerMark Brown <broonie@kernel.org>2016-03-28 05:36:30 -0400
commit3b672623079bb3e5685b8549e514f2dfaa564406 (patch)
tree0eaa65253ad7d7cd044eee535dc116391f9b92cf
parentf55532a0c0b8bb6148f4e07853b876ef73bc69ca (diff)
regulator: s2mps11: Fix invalid selector mask and voltages for buck9
The buck9 regulator of S2MPS11 PMIC had incorrect vsel_mask (0xff instead of 0x1f) thus reading entire register as buck9's voltage. This effectively caused regulator core to interpret values as higher voltages than they were and then to set real voltage much lower than intended. The buck9 provides power to other regulators, including LDO13 and LDO19 which supply the MMC2 (SD card). On Odroid XU3/XU4 the lower voltage caused SD card detection errors on Odroid XU3/XU4: mmc1: card never left busy state mmc1: error -110 whilst initialising SD card During driver probe the regulator core was checking whether initial voltage matches the constraints. With incorrect vsel_mask of 0xff and default value of 0x50, the core interpreted this as 5 V which is outside of constraints (3-3.775 V). Then the regulator core was adjusting the voltage to match the constraints. With incorrect vsel_mask this new voltage mapped to a vere low voltage in the driver. Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Signed-off-by: Mark Brown <broonie@kernel.org> Cc: <stable@vger.kernel.org>
-rw-r--r--drivers/regulator/s2mps11.c28
-rw-r--r--include/linux/mfd/samsung/s2mps11.h2
2 files changed, 24 insertions, 6 deletions
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index d24e2c783dc5..6dfa3502e1f1 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -308,7 +308,7 @@ static struct regulator_ops s2mps11_buck_ops = {
308 .enable_mask = S2MPS11_ENABLE_MASK \ 308 .enable_mask = S2MPS11_ENABLE_MASK \
309} 309}
310 310
311#define regulator_desc_s2mps11_buck6_10(num, min, step) { \ 311#define regulator_desc_s2mps11_buck67810(num, min, step) { \
312 .name = "BUCK"#num, \ 312 .name = "BUCK"#num, \
313 .id = S2MPS11_BUCK##num, \ 313 .id = S2MPS11_BUCK##num, \
314 .ops = &s2mps11_buck_ops, \ 314 .ops = &s2mps11_buck_ops, \
@@ -324,6 +324,22 @@ static struct regulator_ops s2mps11_buck_ops = {
324 .enable_mask = S2MPS11_ENABLE_MASK \ 324 .enable_mask = S2MPS11_ENABLE_MASK \
325} 325}
326 326
327#define regulator_desc_s2mps11_buck9 { \
328 .name = "BUCK9", \
329 .id = S2MPS11_BUCK9, \
330 .ops = &s2mps11_buck_ops, \
331 .type = REGULATOR_VOLTAGE, \
332 .owner = THIS_MODULE, \
333 .min_uV = MIN_3000_MV, \
334 .uV_step = STEP_25_MV, \
335 .n_voltages = S2MPS11_BUCK9_N_VOLTAGES, \
336 .ramp_delay = S2MPS11_RAMP_DELAY, \
337 .vsel_reg = S2MPS11_REG_B9CTRL2, \
338 .vsel_mask = S2MPS11_BUCK9_VSEL_MASK, \
339 .enable_reg = S2MPS11_REG_B9CTRL1, \
340 .enable_mask = S2MPS11_ENABLE_MASK \
341}
342
327static const struct regulator_desc s2mps11_regulators[] = { 343static const struct regulator_desc s2mps11_regulators[] = {
328 regulator_desc_s2mps11_ldo(1, STEP_25_MV), 344 regulator_desc_s2mps11_ldo(1, STEP_25_MV),
329 regulator_desc_s2mps11_ldo(2, STEP_50_MV), 345 regulator_desc_s2mps11_ldo(2, STEP_50_MV),
@@ -368,11 +384,11 @@ static const struct regulator_desc s2mps11_regulators[] = {
368 regulator_desc_s2mps11_buck1_4(3), 384 regulator_desc_s2mps11_buck1_4(3),
369 regulator_desc_s2mps11_buck1_4(4), 385 regulator_desc_s2mps11_buck1_4(4),
370 regulator_desc_s2mps11_buck5, 386 regulator_desc_s2mps11_buck5,
371 regulator_desc_s2mps11_buck6_10(6, MIN_600_MV, STEP_6_25_MV), 387 regulator_desc_s2mps11_buck67810(6, MIN_600_MV, STEP_6_25_MV),
372 regulator_desc_s2mps11_buck6_10(7, MIN_600_MV, STEP_6_25_MV), 388 regulator_desc_s2mps11_buck67810(7, MIN_600_MV, STEP_6_25_MV),
373 regulator_desc_s2mps11_buck6_10(8, MIN_600_MV, STEP_6_25_MV), 389 regulator_desc_s2mps11_buck67810(8, MIN_600_MV, STEP_6_25_MV),
374 regulator_desc_s2mps11_buck6_10(9, MIN_3000_MV, STEP_25_MV), 390 regulator_desc_s2mps11_buck9,
375 regulator_desc_s2mps11_buck6_10(10, MIN_750_MV, STEP_12_5_MV), 391 regulator_desc_s2mps11_buck67810(10, MIN_750_MV, STEP_12_5_MV),
376}; 392};
377 393
378static struct regulator_ops s2mps14_reg_ops; 394static struct regulator_ops s2mps14_reg_ops;
diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h
index b288965e8101..2c14eeca46f0 100644
--- a/include/linux/mfd/samsung/s2mps11.h
+++ b/include/linux/mfd/samsung/s2mps11.h
@@ -173,10 +173,12 @@ enum s2mps11_regulators {
173 173
174#define S2MPS11_LDO_VSEL_MASK 0x3F 174#define S2MPS11_LDO_VSEL_MASK 0x3F
175#define S2MPS11_BUCK_VSEL_MASK 0xFF 175#define S2MPS11_BUCK_VSEL_MASK 0xFF
176#define S2MPS11_BUCK9_VSEL_MASK 0x1F
176#define S2MPS11_ENABLE_MASK (0x03 << S2MPS11_ENABLE_SHIFT) 177#define S2MPS11_ENABLE_MASK (0x03 << S2MPS11_ENABLE_SHIFT)
177#define S2MPS11_ENABLE_SHIFT 0x06 178#define S2MPS11_ENABLE_SHIFT 0x06
178#define S2MPS11_LDO_N_VOLTAGES (S2MPS11_LDO_VSEL_MASK + 1) 179#define S2MPS11_LDO_N_VOLTAGES (S2MPS11_LDO_VSEL_MASK + 1)
179#define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1) 180#define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1)
181#define S2MPS11_BUCK9_N_VOLTAGES (S2MPS11_BUCK9_VSEL_MASK + 1)
180#define S2MPS11_RAMP_DELAY 25000 /* uV/us */ 182#define S2MPS11_RAMP_DELAY 25000 /* uV/us */
181 183
182#define S2MPS11_CTRL1_PWRHOLD_MASK BIT(4) 184#define S2MPS11_CTRL1_PWRHOLD_MASK BIT(4)