Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: twl4030 voltage enumeration (v2)

Update previously-posted twl4030 regulator driver to export
supported voltages to upper layers using a new mechanism.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>

authored by

David Brownell and committed by
Liam Girdwood
66b659e6 fa16a5c1

+23 -39
+23 -39
drivers/regulator/twl4030-regulator.c
··· 42 42 43 43 /* chip constraints on regulator behavior */ 44 44 u16 min_mV; 45 - u16 max_mV; 46 45 47 46 /* used by regulator core */ 48 47 struct regulator_desc desc; ··· 257 258 }; 258 259 259 260 261 + static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) 262 + { 263 + struct twlreg_info *info = rdev_get_drvdata(rdev); 264 + int mV = info->table[index]; 265 + 266 + return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000); 267 + } 268 + 260 269 static int 261 270 twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) 262 271 { ··· 278 271 if (IS_UNSUP(mV)) 279 272 continue; 280 273 uV = LDO_MV(mV) * 1000; 274 + 275 + /* REVISIT for VAUX2, first match may not be best/lowest */ 281 276 282 277 /* use the first in-range value */ 283 278 if (min_uV <= uV && uV <= max_uV) ··· 302 293 } 303 294 304 295 static struct regulator_ops twl4030ldo_ops = { 296 + .list_voltage = twl4030ldo_list_voltage, 297 + 305 298 .set_voltage = twl4030ldo_set_voltage, 306 299 .get_voltage = twl4030ldo_get_voltage, 307 300 ··· 321 310 /* 322 311 * Fixed voltage LDOs don't have a VSEL field to update. 323 312 */ 313 + static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index) 314 + { 315 + struct twlreg_info *info = rdev_get_drvdata(rdev); 316 + 317 + return info->min_mV * 1000; 318 + } 319 + 324 320 static int twl4030fixed_get_voltage(struct regulator_dev *rdev) 325 321 { 326 322 struct twlreg_info *info = rdev_get_drvdata(rdev); ··· 336 318 } 337 319 338 320 static struct regulator_ops twl4030fixed_ops = { 321 + .list_voltage = twl4030fixed_list_voltage, 322 + 339 323 .get_voltage = twl4030fixed_get_voltage, 340 324 341 325 .enable = twl4030reg_enable, ··· 359 339 .desc = { \ 360 340 .name = #label, \ 361 341 .id = TWL4030_REG_##label, \ 342 + .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ 362 343 .ops = &twl4030ldo_ops, \ 363 344 .type = REGULATOR_VOLTAGE, \ 364 345 .owner = THIS_MODULE, \ ··· 370 349 .base = offset, \ 371 350 .id = num, \ 372 351 .min_mV = mVolts, \ 373 - .max_mV = mVolts, \ 374 352 .desc = { \ 375 353 .name = #label, \ 376 354 .id = TWL4030_REG_##label, \ 355 + .n_voltages = 1, \ 377 356 .ops = &twl4030fixed_ops, \ 378 357 .type = REGULATOR_VOLTAGE, \ 379 358 .owner = THIS_MODULE, \ ··· 419 398 struct regulator_init_data *initdata; 420 399 struct regulation_constraints *c; 421 400 struct regulator_dev *rdev; 422 - int min_uV, max_uV; 423 401 424 402 for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) { 425 403 if (twl4030_regs[i].desc.id != pdev->id) 426 404 continue; 427 405 info = twl4030_regs + i; 428 - min_uV = info->min_mV * 1000; 429 - max_uV = info->max_mV * 1000; 430 406 break; 431 407 } 432 408 if (!info) ··· 437 419 * this driver and the chip itself can actually do. 438 420 */ 439 421 c = &initdata->constraints; 440 - if (!c->min_uV || c->min_uV < min_uV) 441 - c->min_uV = min_uV; 442 - if (!c->max_uV || c->max_uV > max_uV) 443 - c->max_uV = max_uV; 444 422 c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY; 445 423 c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE 446 424 | REGULATOR_CHANGE_MODE ··· 481 467 482 468 static int __init twl4030reg_init(void) 483 469 { 484 - unsigned i, j; 485 - 486 - /* determine min/max voltage constraints, taking into account 487 - * whether set_voltage() will use the "unsupported" settings 488 - */ 489 - for (i = 0; i < ARRAY_SIZE(twl4030_regs); i++) { 490 - struct twlreg_info *info = twl4030_regs + i; 491 - const u16 *table; 492 - 493 - /* fixed-voltage regulators */ 494 - if (!info->table_len) 495 - continue; 496 - 497 - /* LDO regulators: */ 498 - for (j = 0, table = info->table; 499 - j < info->table_len; 500 - j++, table++) { 501 - u16 mV = *table; 502 - 503 - if (IS_UNSUP(mV)) 504 - continue; 505 - mV = LDO_MV(mV); 506 - 507 - if (info->min_mV == 0 || info->min_mV > mV) 508 - info->min_mV = mV; 509 - if (info->max_mV < mV) 510 - info->max_mV = mV; 511 - } 512 - } 513 - 514 470 return platform_driver_register(&twl4030reg_driver); 515 471 } 516 472 subsys_initcall(twl4030reg_init);