diff options
Diffstat (limited to 'drivers/regulator/s2mps11.c')
-rw-r--r-- | drivers/regulator/s2mps11.c | 365 |
1 files changed, 283 insertions, 82 deletions
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index d9e557990577..68fd54702edb 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -1,13 +1,18 @@ | |||
1 | /* | 1 | /* |
2 | * s2mps11.c | 2 | * s2mps11.c |
3 | * | 3 | * |
4 | * Copyright (c) 2012 Samsung Electronics Co., Ltd | 4 | * Copyright (c) 2012-2014 Samsung Electronics Co., Ltd |
5 | * http://www.samsung.com | 5 | * http://www.samsung.com |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
9 | * Free Software Foundation; either version 2 of the License, or (at your | 9 | * Free Software Foundation; either version 2 of the License, or (at your |
10 | * option) any later version. | 10 | * option) any later version. |
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
11 | * | 16 | * |
12 | */ | 17 | */ |
13 | 18 | ||
@@ -24,18 +29,21 @@ | |||
24 | #include <linux/regulator/of_regulator.h> | 29 | #include <linux/regulator/of_regulator.h> |
25 | #include <linux/mfd/samsung/core.h> | 30 | #include <linux/mfd/samsung/core.h> |
26 | #include <linux/mfd/samsung/s2mps11.h> | 31 | #include <linux/mfd/samsung/s2mps11.h> |
27 | 32 | #include <linux/mfd/samsung/s2mps14.h> | |
28 | #define S2MPS11_REGULATOR_CNT ARRAY_SIZE(regulators) | ||
29 | 33 | ||
30 | struct s2mps11_info { | 34 | struct s2mps11_info { |
31 | struct regulator_dev *rdev[S2MPS11_REGULATOR_MAX]; | 35 | unsigned int rdev_num; |
32 | |||
33 | int ramp_delay2; | 36 | int ramp_delay2; |
34 | int ramp_delay34; | 37 | int ramp_delay34; |
35 | int ramp_delay5; | 38 | int ramp_delay5; |
36 | int ramp_delay16; | 39 | int ramp_delay16; |
37 | int ramp_delay7810; | 40 | int ramp_delay7810; |
38 | int ramp_delay9; | 41 | int ramp_delay9; |
42 | /* | ||
43 | * One bit for each S2MPS14 regulator whether the suspend mode | ||
44 | * was enabled. | ||
45 | */ | ||
46 | unsigned int s2mps14_suspend_state:30; | ||
39 | }; | 47 | }; |
40 | 48 | ||
41 | static int get_ramp_delay(int ramp_delay) | 49 | static int get_ramp_delay(int ramp_delay) |
@@ -65,7 +73,7 @@ static int s2mps11_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | |||
65 | unsigned int ramp_delay = 0; | 73 | unsigned int ramp_delay = 0; |
66 | int old_volt, new_volt; | 74 | int old_volt, new_volt; |
67 | 75 | ||
68 | switch (rdev->desc->id) { | 76 | switch (rdev_get_id(rdev)) { |
69 | case S2MPS11_BUCK2: | 77 | case S2MPS11_BUCK2: |
70 | ramp_delay = s2mps11->ramp_delay2; | 78 | ramp_delay = s2mps11->ramp_delay2; |
71 | break; | 79 | break; |
@@ -105,7 +113,7 @@ static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | |||
105 | unsigned int ramp_enable = 1, enable_shift = 0; | 113 | unsigned int ramp_enable = 1, enable_shift = 0; |
106 | int ret; | 114 | int ret; |
107 | 115 | ||
108 | switch (rdev->desc->id) { | 116 | switch (rdev_get_id(rdev)) { |
109 | case S2MPS11_BUCK1: | 117 | case S2MPS11_BUCK1: |
110 | if (ramp_delay > s2mps11->ramp_delay16) | 118 | if (ramp_delay > s2mps11->ramp_delay16) |
111 | s2mps11->ramp_delay16 = ramp_delay; | 119 | s2mps11->ramp_delay16 = ramp_delay; |
@@ -236,7 +244,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
236 | .set_ramp_delay = s2mps11_set_ramp_delay, | 244 | .set_ramp_delay = s2mps11_set_ramp_delay, |
237 | }; | 245 | }; |
238 | 246 | ||
239 | #define regulator_desc_ldo1(num) { \ | 247 | #define regulator_desc_s2mps11_ldo1(num) { \ |
240 | .name = "LDO"#num, \ | 248 | .name = "LDO"#num, \ |
241 | .id = S2MPS11_LDO##num, \ | 249 | .id = S2MPS11_LDO##num, \ |
242 | .ops = &s2mps11_ldo_ops, \ | 250 | .ops = &s2mps11_ldo_ops, \ |
@@ -250,7 +258,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
250 | .enable_reg = S2MPS11_REG_L1CTRL + num - 1, \ | 258 | .enable_reg = S2MPS11_REG_L1CTRL + num - 1, \ |
251 | .enable_mask = S2MPS11_ENABLE_MASK \ | 259 | .enable_mask = S2MPS11_ENABLE_MASK \ |
252 | } | 260 | } |
253 | #define regulator_desc_ldo2(num) { \ | 261 | #define regulator_desc_s2mps11_ldo2(num) { \ |
254 | .name = "LDO"#num, \ | 262 | .name = "LDO"#num, \ |
255 | .id = S2MPS11_LDO##num, \ | 263 | .id = S2MPS11_LDO##num, \ |
256 | .ops = &s2mps11_ldo_ops, \ | 264 | .ops = &s2mps11_ldo_ops, \ |
@@ -265,7 +273,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
265 | .enable_mask = S2MPS11_ENABLE_MASK \ | 273 | .enable_mask = S2MPS11_ENABLE_MASK \ |
266 | } | 274 | } |
267 | 275 | ||
268 | #define regulator_desc_buck1_4(num) { \ | 276 | #define regulator_desc_s2mps11_buck1_4(num) { \ |
269 | .name = "BUCK"#num, \ | 277 | .name = "BUCK"#num, \ |
270 | .id = S2MPS11_BUCK##num, \ | 278 | .id = S2MPS11_BUCK##num, \ |
271 | .ops = &s2mps11_buck_ops, \ | 279 | .ops = &s2mps11_buck_ops, \ |
@@ -281,7 +289,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
281 | .enable_mask = S2MPS11_ENABLE_MASK \ | 289 | .enable_mask = S2MPS11_ENABLE_MASK \ |
282 | } | 290 | } |
283 | 291 | ||
284 | #define regulator_desc_buck5 { \ | 292 | #define regulator_desc_s2mps11_buck5 { \ |
285 | .name = "BUCK5", \ | 293 | .name = "BUCK5", \ |
286 | .id = S2MPS11_BUCK5, \ | 294 | .id = S2MPS11_BUCK5, \ |
287 | .ops = &s2mps11_buck_ops, \ | 295 | .ops = &s2mps11_buck_ops, \ |
@@ -297,7 +305,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
297 | .enable_mask = S2MPS11_ENABLE_MASK \ | 305 | .enable_mask = S2MPS11_ENABLE_MASK \ |
298 | } | 306 | } |
299 | 307 | ||
300 | #define regulator_desc_buck6_8(num) { \ | 308 | #define regulator_desc_s2mps11_buck6_8(num) { \ |
301 | .name = "BUCK"#num, \ | 309 | .name = "BUCK"#num, \ |
302 | .id = S2MPS11_BUCK##num, \ | 310 | .id = S2MPS11_BUCK##num, \ |
303 | .ops = &s2mps11_buck_ops, \ | 311 | .ops = &s2mps11_buck_ops, \ |
@@ -313,7 +321,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
313 | .enable_mask = S2MPS11_ENABLE_MASK \ | 321 | .enable_mask = S2MPS11_ENABLE_MASK \ |
314 | } | 322 | } |
315 | 323 | ||
316 | #define regulator_desc_buck9 { \ | 324 | #define regulator_desc_s2mps11_buck9 { \ |
317 | .name = "BUCK9", \ | 325 | .name = "BUCK9", \ |
318 | .id = S2MPS11_BUCK9, \ | 326 | .id = S2MPS11_BUCK9, \ |
319 | .ops = &s2mps11_buck_ops, \ | 327 | .ops = &s2mps11_buck_ops, \ |
@@ -329,7 +337,7 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
329 | .enable_mask = S2MPS11_ENABLE_MASK \ | 337 | .enable_mask = S2MPS11_ENABLE_MASK \ |
330 | } | 338 | } |
331 | 339 | ||
332 | #define regulator_desc_buck10 { \ | 340 | #define regulator_desc_s2mps11_buck10 { \ |
333 | .name = "BUCK10", \ | 341 | .name = "BUCK10", \ |
334 | .id = S2MPS11_BUCK10, \ | 342 | .id = S2MPS11_BUCK10, \ |
335 | .ops = &s2mps11_buck_ops, \ | 343 | .ops = &s2mps11_buck_ops, \ |
@@ -345,72 +353,252 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
345 | .enable_mask = S2MPS11_ENABLE_MASK \ | 353 | .enable_mask = S2MPS11_ENABLE_MASK \ |
346 | } | 354 | } |
347 | 355 | ||
348 | static struct regulator_desc regulators[] = { | 356 | static const struct regulator_desc s2mps11_regulators[] = { |
349 | regulator_desc_ldo2(1), | 357 | regulator_desc_s2mps11_ldo2(1), |
350 | regulator_desc_ldo1(2), | 358 | regulator_desc_s2mps11_ldo1(2), |
351 | regulator_desc_ldo1(3), | 359 | regulator_desc_s2mps11_ldo1(3), |
352 | regulator_desc_ldo1(4), | 360 | regulator_desc_s2mps11_ldo1(4), |
353 | regulator_desc_ldo1(5), | 361 | regulator_desc_s2mps11_ldo1(5), |
354 | regulator_desc_ldo2(6), | 362 | regulator_desc_s2mps11_ldo2(6), |
355 | regulator_desc_ldo1(7), | 363 | regulator_desc_s2mps11_ldo1(7), |
356 | regulator_desc_ldo1(8), | 364 | regulator_desc_s2mps11_ldo1(8), |
357 | regulator_desc_ldo1(9), | 365 | regulator_desc_s2mps11_ldo1(9), |
358 | regulator_desc_ldo1(10), | 366 | regulator_desc_s2mps11_ldo1(10), |
359 | regulator_desc_ldo2(11), | 367 | regulator_desc_s2mps11_ldo2(11), |
360 | regulator_desc_ldo1(12), | 368 | regulator_desc_s2mps11_ldo1(12), |
361 | regulator_desc_ldo1(13), | 369 | regulator_desc_s2mps11_ldo1(13), |
362 | regulator_desc_ldo1(14), | 370 | regulator_desc_s2mps11_ldo1(14), |
363 | regulator_desc_ldo1(15), | 371 | regulator_desc_s2mps11_ldo1(15), |
364 | regulator_desc_ldo1(16), | 372 | regulator_desc_s2mps11_ldo1(16), |
365 | regulator_desc_ldo1(17), | 373 | regulator_desc_s2mps11_ldo1(17), |
366 | regulator_desc_ldo1(18), | 374 | regulator_desc_s2mps11_ldo1(18), |
367 | regulator_desc_ldo1(19), | 375 | regulator_desc_s2mps11_ldo1(19), |
368 | regulator_desc_ldo1(20), | 376 | regulator_desc_s2mps11_ldo1(20), |
369 | regulator_desc_ldo1(21), | 377 | regulator_desc_s2mps11_ldo1(21), |
370 | regulator_desc_ldo2(22), | 378 | regulator_desc_s2mps11_ldo2(22), |
371 | regulator_desc_ldo2(23), | 379 | regulator_desc_s2mps11_ldo2(23), |
372 | regulator_desc_ldo1(24), | 380 | regulator_desc_s2mps11_ldo1(24), |
373 | regulator_desc_ldo1(25), | 381 | regulator_desc_s2mps11_ldo1(25), |
374 | regulator_desc_ldo1(26), | 382 | regulator_desc_s2mps11_ldo1(26), |
375 | regulator_desc_ldo2(27), | 383 | regulator_desc_s2mps11_ldo2(27), |
376 | regulator_desc_ldo1(28), | 384 | regulator_desc_s2mps11_ldo1(28), |
377 | regulator_desc_ldo1(29), | 385 | regulator_desc_s2mps11_ldo1(29), |
378 | regulator_desc_ldo1(30), | 386 | regulator_desc_s2mps11_ldo1(30), |
379 | regulator_desc_ldo1(31), | 387 | regulator_desc_s2mps11_ldo1(31), |
380 | regulator_desc_ldo1(32), | 388 | regulator_desc_s2mps11_ldo1(32), |
381 | regulator_desc_ldo1(33), | 389 | regulator_desc_s2mps11_ldo1(33), |
382 | regulator_desc_ldo1(34), | 390 | regulator_desc_s2mps11_ldo1(34), |
383 | regulator_desc_ldo1(35), | 391 | regulator_desc_s2mps11_ldo1(35), |
384 | regulator_desc_ldo1(36), | 392 | regulator_desc_s2mps11_ldo1(36), |
385 | regulator_desc_ldo1(37), | 393 | regulator_desc_s2mps11_ldo1(37), |
386 | regulator_desc_ldo1(38), | 394 | regulator_desc_s2mps11_ldo1(38), |
387 | regulator_desc_buck1_4(1), | 395 | regulator_desc_s2mps11_buck1_4(1), |
388 | regulator_desc_buck1_4(2), | 396 | regulator_desc_s2mps11_buck1_4(2), |
389 | regulator_desc_buck1_4(3), | 397 | regulator_desc_s2mps11_buck1_4(3), |
390 | regulator_desc_buck1_4(4), | 398 | regulator_desc_s2mps11_buck1_4(4), |
391 | regulator_desc_buck5, | 399 | regulator_desc_s2mps11_buck5, |
392 | regulator_desc_buck6_8(6), | 400 | regulator_desc_s2mps11_buck6_8(6), |
393 | regulator_desc_buck6_8(7), | 401 | regulator_desc_s2mps11_buck6_8(7), |
394 | regulator_desc_buck6_8(8), | 402 | regulator_desc_s2mps11_buck6_8(8), |
395 | regulator_desc_buck9, | 403 | regulator_desc_s2mps11_buck9, |
396 | regulator_desc_buck10, | 404 | regulator_desc_s2mps11_buck10, |
405 | }; | ||
406 | |||
407 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) | ||
408 | { | ||
409 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | ||
410 | unsigned int val; | ||
411 | |||
412 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) | ||
413 | val = S2MPS14_ENABLE_SUSPEND; | ||
414 | else | ||
415 | val = rdev->desc->enable_mask; | ||
416 | |||
417 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
418 | rdev->desc->enable_mask, val); | ||
419 | } | ||
420 | |||
421 | static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) | ||
422 | { | ||
423 | int ret; | ||
424 | unsigned int val; | ||
425 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | ||
426 | |||
427 | /* LDO3 should be always on and does not support suspend mode */ | ||
428 | if (rdev_get_id(rdev) == S2MPS14_LDO3) | ||
429 | return 0; | ||
430 | |||
431 | ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); | ||
432 | if (ret < 0) | ||
433 | return ret; | ||
434 | |||
435 | s2mps11->s2mps14_suspend_state |= (1 << rdev_get_id(rdev)); | ||
436 | /* | ||
437 | * Don't enable suspend mode if regulator is already disabled because | ||
438 | * this would effectively for a short time turn on the regulator after | ||
439 | * resuming. | ||
440 | * However we still want to toggle the suspend_state bit for regulator | ||
441 | * in case if it got enabled before suspending the system. | ||
442 | */ | ||
443 | if (!(val & rdev->desc->enable_mask)) | ||
444 | return 0; | ||
445 | |||
446 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
447 | rdev->desc->enable_mask, S2MPS14_ENABLE_SUSPEND); | ||
448 | } | ||
449 | |||
450 | static struct regulator_ops s2mps14_reg_ops = { | ||
451 | .list_voltage = regulator_list_voltage_linear, | ||
452 | .map_voltage = regulator_map_voltage_linear, | ||
453 | .is_enabled = regulator_is_enabled_regmap, | ||
454 | .enable = s2mps14_regulator_enable, | ||
455 | .disable = regulator_disable_regmap, | ||
456 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
457 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
458 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
459 | .set_suspend_disable = s2mps14_regulator_set_suspend_disable, | ||
460 | }; | ||
461 | |||
462 | #define regulator_desc_s2mps14_ldo1(num) { \ | ||
463 | .name = "LDO"#num, \ | ||
464 | .id = S2MPS14_LDO##num, \ | ||
465 | .ops = &s2mps14_reg_ops, \ | ||
466 | .type = REGULATOR_VOLTAGE, \ | ||
467 | .owner = THIS_MODULE, \ | ||
468 | .min_uV = S2MPS14_LDO_MIN_800MV, \ | ||
469 | .uV_step = S2MPS14_LDO_STEP_25MV, \ | ||
470 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
471 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
472 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
473 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
474 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
475 | } | ||
476 | #define regulator_desc_s2mps14_ldo2(num) { \ | ||
477 | .name = "LDO"#num, \ | ||
478 | .id = S2MPS14_LDO##num, \ | ||
479 | .ops = &s2mps14_reg_ops, \ | ||
480 | .type = REGULATOR_VOLTAGE, \ | ||
481 | .owner = THIS_MODULE, \ | ||
482 | .min_uV = S2MPS14_LDO_MIN_1800MV, \ | ||
483 | .uV_step = S2MPS14_LDO_STEP_25MV, \ | ||
484 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
485 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
486 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
487 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
488 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
489 | } | ||
490 | #define regulator_desc_s2mps14_ldo3(num) { \ | ||
491 | .name = "LDO"#num, \ | ||
492 | .id = S2MPS14_LDO##num, \ | ||
493 | .ops = &s2mps14_reg_ops, \ | ||
494 | .type = REGULATOR_VOLTAGE, \ | ||
495 | .owner = THIS_MODULE, \ | ||
496 | .min_uV = S2MPS14_LDO_MIN_800MV, \ | ||
497 | .uV_step = S2MPS14_LDO_STEP_12_5MV, \ | ||
498 | .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ | ||
499 | .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
500 | .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ | ||
501 | .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ | ||
502 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
503 | } | ||
504 | #define regulator_desc_s2mps14_buck1235(num) { \ | ||
505 | .name = "BUCK"#num, \ | ||
506 | .id = S2MPS14_BUCK##num, \ | ||
507 | .ops = &s2mps14_reg_ops, \ | ||
508 | .type = REGULATOR_VOLTAGE, \ | ||
509 | .owner = THIS_MODULE, \ | ||
510 | .min_uV = S2MPS14_BUCK1235_MIN_600MV, \ | ||
511 | .uV_step = S2MPS14_BUCK1235_STEP_6_25MV, \ | ||
512 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | ||
513 | .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \ | ||
514 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ | ||
515 | .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ | ||
516 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | ||
517 | .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ | ||
518 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
519 | } | ||
520 | #define regulator_desc_s2mps14_buck4(num) { \ | ||
521 | .name = "BUCK"#num, \ | ||
522 | .id = S2MPS14_BUCK##num, \ | ||
523 | .ops = &s2mps14_reg_ops, \ | ||
524 | .type = REGULATOR_VOLTAGE, \ | ||
525 | .owner = THIS_MODULE, \ | ||
526 | .min_uV = S2MPS14_BUCK4_MIN_1400MV, \ | ||
527 | .uV_step = S2MPS14_BUCK4_STEP_12_5MV, \ | ||
528 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | ||
529 | .linear_min_sel = S2MPS14_BUCK4_START_SEL, \ | ||
530 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ | ||
531 | .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ | ||
532 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | ||
533 | .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ | ||
534 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
535 | } | ||
536 | |||
537 | static const struct regulator_desc s2mps14_regulators[] = { | ||
538 | regulator_desc_s2mps14_ldo3(1), | ||
539 | regulator_desc_s2mps14_ldo3(2), | ||
540 | regulator_desc_s2mps14_ldo1(3), | ||
541 | regulator_desc_s2mps14_ldo1(4), | ||
542 | regulator_desc_s2mps14_ldo3(5), | ||
543 | regulator_desc_s2mps14_ldo3(6), | ||
544 | regulator_desc_s2mps14_ldo1(7), | ||
545 | regulator_desc_s2mps14_ldo2(8), | ||
546 | regulator_desc_s2mps14_ldo3(9), | ||
547 | regulator_desc_s2mps14_ldo3(10), | ||
548 | regulator_desc_s2mps14_ldo1(11), | ||
549 | regulator_desc_s2mps14_ldo2(12), | ||
550 | regulator_desc_s2mps14_ldo2(13), | ||
551 | regulator_desc_s2mps14_ldo2(14), | ||
552 | regulator_desc_s2mps14_ldo2(15), | ||
553 | regulator_desc_s2mps14_ldo2(16), | ||
554 | regulator_desc_s2mps14_ldo2(17), | ||
555 | regulator_desc_s2mps14_ldo2(18), | ||
556 | regulator_desc_s2mps14_ldo1(19), | ||
557 | regulator_desc_s2mps14_ldo1(20), | ||
558 | regulator_desc_s2mps14_ldo1(21), | ||
559 | regulator_desc_s2mps14_ldo3(22), | ||
560 | regulator_desc_s2mps14_ldo1(23), | ||
561 | regulator_desc_s2mps14_ldo2(24), | ||
562 | regulator_desc_s2mps14_ldo2(25), | ||
563 | regulator_desc_s2mps14_buck1235(1), | ||
564 | regulator_desc_s2mps14_buck1235(2), | ||
565 | regulator_desc_s2mps14_buck1235(3), | ||
566 | regulator_desc_s2mps14_buck4(4), | ||
567 | regulator_desc_s2mps14_buck1235(5), | ||
397 | }; | 568 | }; |
398 | 569 | ||
399 | static int s2mps11_pmic_probe(struct platform_device *pdev) | 570 | static int s2mps11_pmic_probe(struct platform_device *pdev) |
400 | { | 571 | { |
401 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 572 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
402 | struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); | 573 | struct sec_platform_data *pdata = iodev->pdata; |
403 | struct of_regulator_match rdata[S2MPS11_REGULATOR_MAX]; | 574 | struct of_regulator_match *rdata = NULL; |
404 | struct device_node *reg_np = NULL; | 575 | struct device_node *reg_np = NULL; |
405 | struct regulator_config config = { }; | 576 | struct regulator_config config = { }; |
406 | struct s2mps11_info *s2mps11; | 577 | struct s2mps11_info *s2mps11; |
407 | int i, ret; | 578 | int i, ret = 0; |
579 | const struct regulator_desc *regulators; | ||
580 | enum sec_device_type dev_type; | ||
408 | 581 | ||
409 | s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), | 582 | s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), |
410 | GFP_KERNEL); | 583 | GFP_KERNEL); |
411 | if (!s2mps11) | 584 | if (!s2mps11) |
412 | return -ENOMEM; | 585 | return -ENOMEM; |
413 | 586 | ||
587 | dev_type = platform_get_device_id(pdev)->driver_data; | ||
588 | switch (dev_type) { | ||
589 | case S2MPS11X: | ||
590 | s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); | ||
591 | regulators = s2mps11_regulators; | ||
592 | break; | ||
593 | case S2MPS14X: | ||
594 | s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators); | ||
595 | regulators = s2mps14_regulators; | ||
596 | break; | ||
597 | default: | ||
598 | dev_err(&pdev->dev, "Invalid device type: %u\n", dev_type); | ||
599 | return -EINVAL; | ||
600 | }; | ||
601 | |||
414 | if (!iodev->dev->of_node) { | 602 | if (!iodev->dev->of_node) { |
415 | if (pdata) { | 603 | if (pdata) { |
416 | goto common_reg; | 604 | goto common_reg; |
@@ -421,16 +609,22 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) | |||
421 | } | 609 | } |
422 | } | 610 | } |
423 | 611 | ||
424 | for (i = 0; i < S2MPS11_REGULATOR_CNT; i++) | 612 | rdata = kzalloc(sizeof(*rdata) * s2mps11->rdev_num, GFP_KERNEL); |
613 | if (!rdata) | ||
614 | return -ENOMEM; | ||
615 | |||
616 | for (i = 0; i < s2mps11->rdev_num; i++) | ||
425 | rdata[i].name = regulators[i].name; | 617 | rdata[i].name = regulators[i].name; |
426 | 618 | ||
427 | reg_np = of_find_node_by_name(iodev->dev->of_node, "regulators"); | 619 | reg_np = of_get_child_by_name(iodev->dev->of_node, "regulators"); |
428 | if (!reg_np) { | 620 | if (!reg_np) { |
429 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | 621 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); |
430 | return -EINVAL; | 622 | ret = -EINVAL; |
623 | goto out; | ||
431 | } | 624 | } |
432 | 625 | ||
433 | of_regulator_match(&pdev->dev, reg_np, rdata, S2MPS11_REGULATOR_MAX); | 626 | of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num); |
627 | of_node_put(reg_np); | ||
434 | 628 | ||
435 | common_reg: | 629 | common_reg: |
436 | platform_set_drvdata(pdev, s2mps11); | 630 | platform_set_drvdata(pdev, s2mps11); |
@@ -438,29 +632,36 @@ common_reg: | |||
438 | config.dev = &pdev->dev; | 632 | config.dev = &pdev->dev; |
439 | config.regmap = iodev->regmap_pmic; | 633 | config.regmap = iodev->regmap_pmic; |
440 | config.driver_data = s2mps11; | 634 | config.driver_data = s2mps11; |
441 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) { | 635 | for (i = 0; i < s2mps11->rdev_num; i++) { |
636 | struct regulator_dev *regulator; | ||
637 | |||
442 | if (!reg_np) { | 638 | if (!reg_np) { |
443 | config.init_data = pdata->regulators[i].initdata; | 639 | config.init_data = pdata->regulators[i].initdata; |
640 | config.of_node = pdata->regulators[i].reg_node; | ||
444 | } else { | 641 | } else { |
445 | config.init_data = rdata[i].init_data; | 642 | config.init_data = rdata[i].init_data; |
446 | config.of_node = rdata[i].of_node; | 643 | config.of_node = rdata[i].of_node; |
447 | } | 644 | } |
448 | 645 | ||
449 | s2mps11->rdev[i] = devm_regulator_register(&pdev->dev, | 646 | regulator = devm_regulator_register(&pdev->dev, |
450 | ®ulators[i], &config); | 647 | ®ulators[i], &config); |
451 | if (IS_ERR(s2mps11->rdev[i])) { | 648 | if (IS_ERR(regulator)) { |
452 | ret = PTR_ERR(s2mps11->rdev[i]); | 649 | ret = PTR_ERR(regulator); |
453 | dev_err(&pdev->dev, "regulator init failed for %d\n", | 650 | dev_err(&pdev->dev, "regulator init failed for %d\n", |
454 | i); | 651 | i); |
455 | return ret; | 652 | goto out; |
456 | } | 653 | } |
457 | } | 654 | } |
458 | 655 | ||
459 | return 0; | 656 | out: |
657 | kfree(rdata); | ||
658 | |||
659 | return ret; | ||
460 | } | 660 | } |
461 | 661 | ||
462 | static const struct platform_device_id s2mps11_pmic_id[] = { | 662 | static const struct platform_device_id s2mps11_pmic_id[] = { |
463 | { "s2mps11-pmic", 0}, | 663 | { "s2mps11-pmic", S2MPS11X}, |
664 | { "s2mps14-pmic", S2MPS14X}, | ||
464 | { }, | 665 | { }, |
465 | }; | 666 | }; |
466 | MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); | 667 | MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); |
@@ -488,5 +689,5 @@ module_exit(s2mps11_pmic_exit); | |||
488 | 689 | ||
489 | /* Module information */ | 690 | /* Module information */ |
490 | MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); | 691 | MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); |
491 | MODULE_DESCRIPTION("SAMSUNG S2MPS11 Regulator Driver"); | 692 | MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14 Regulator Driver"); |
492 | MODULE_LICENSE("GPL"); | 693 | MODULE_LICENSE("GPL"); |