aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/twl4030-core.c174
-rw-r--r--include/linux/i2c/twl4030.h47
2 files changed, 211 insertions, 10 deletions
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index f5486cce86f4..8ab9ee8543a6 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -33,6 +33,8 @@
33#include <linux/clk.h> 33#include <linux/clk.h>
34#include <linux/err.h> 34#include <linux/err.h>
35 35
36#include <linux/regulator/machine.h>
37
36#include <linux/i2c.h> 38#include <linux/i2c.h>
37#include <linux/i2c/twl4030.h> 39#include <linux/i2c/twl4030.h>
38 40
@@ -71,6 +73,13 @@
71#define twl_has_gpio() false 73#define twl_has_gpio() false
72#endif 74#endif
73 75
76#if defined(CONFIG_REGULATOR_TWL4030) \
77 || defined(CONFIG_REGULATOR_TWL4030_MODULE)
78#define twl_has_regulator() true
79#else
80#define twl_has_regulator() false
81#endif
82
74#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE) 83#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE)
75#define twl_has_madc() true 84#define twl_has_madc() true
76#else 85#else
@@ -149,6 +158,10 @@
149#define HIGH_PERF_SQ (1 << 3) 158#define HIGH_PERF_SQ (1 << 3)
150 159
151 160
161/* chip-specific feature flags, for i2c_device_id.driver_data */
162#define TWL4030_VAUX2 BIT(0) /* pre-5030 voltage ranges */
163#define TPS_SUBSET BIT(1) /* tps659[23]0 have fewer LDOs */
164
152/*----------------------------------------------------------------------*/ 165/*----------------------------------------------------------------------*/
153 166
154/* is driver active, bound to a chip? */ 167/* is driver active, bound to a chip? */
@@ -352,7 +365,8 @@ EXPORT_SYMBOL(twl4030_i2c_read_u8);
352 365
353/*----------------------------------------------------------------------*/ 366/*----------------------------------------------------------------------*/
354 367
355static struct device *add_child(unsigned chip, const char *name, 368static struct device *
369add_numbered_child(unsigned chip, const char *name, int num,
356 void *pdata, unsigned pdata_len, 370 void *pdata, unsigned pdata_len,
357 bool can_wakeup, int irq0, int irq1) 371 bool can_wakeup, int irq0, int irq1)
358{ 372{
@@ -360,7 +374,7 @@ static struct device *add_child(unsigned chip, const char *name,
360 struct twl4030_client *twl = &twl4030_modules[chip]; 374 struct twl4030_client *twl = &twl4030_modules[chip];
361 int status; 375 int status;
362 376
363 pdev = platform_device_alloc(name, -1); 377 pdev = platform_device_alloc(name, num);
364 if (!pdev) { 378 if (!pdev) {
365 dev_dbg(&twl->client->dev, "can't alloc dev\n"); 379 dev_dbg(&twl->client->dev, "can't alloc dev\n");
366 status = -ENOMEM; 380 status = -ENOMEM;
@@ -402,17 +416,52 @@ err:
402 return &pdev->dev; 416 return &pdev->dev;
403} 417}
404 418
419static inline struct device *add_child(unsigned chip, const char *name,
420 void *pdata, unsigned pdata_len,
421 bool can_wakeup, int irq0, int irq1)
422{
423 return add_numbered_child(chip, name, -1, pdata, pdata_len,
424 can_wakeup, irq0, irq1);
425}
426
427static struct device *
428add_regulator_linked(int num, struct regulator_init_data *pdata,
429 struct regulator_consumer_supply *consumers,
430 unsigned num_consumers)
431{
432 /* regulator framework demands init_data ... */
433 if (!pdata)
434 return NULL;
435
436 if (consumers && !pdata->consumer_supplies) {
437 pdata->consumer_supplies = consumers;
438 pdata->num_consumer_supplies = num_consumers;
439 }
440
441 /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */
442 return add_numbered_child(3, "twl4030_reg", num,
443 pdata, sizeof(*pdata), false, 0, 0);
444}
445
446static struct device *
447add_regulator(int num, struct regulator_init_data *pdata)
448{
449 return add_regulator_linked(num, pdata, NULL, 0);
450}
451
405/* 452/*
406 * NOTE: We know the first 8 IRQs after pdata->base_irq are 453 * NOTE: We know the first 8 IRQs after pdata->base_irq are
407 * for the PIH, and the next are for the PWR_INT SIH, since 454 * for the PIH, and the next are for the PWR_INT SIH, since
408 * that's how twl_init_irq() sets things up. 455 * that's how twl_init_irq() sets things up.
409 */ 456 */
410 457
411static int add_children(struct twl4030_platform_data *pdata) 458static int
459add_children(struct twl4030_platform_data *pdata, unsigned long features)
412{ 460{
413 struct device *child; 461 struct device *child;
462 struct device *usb_transceiver = NULL;
414 463
415 if (twl_has_bci() && pdata->bci) { 464 if (twl_has_bci() && pdata->bci && !(features & TPS_SUBSET)) {
416 child = add_child(3, "twl4030_bci", 465 child = add_child(3, "twl4030_bci",
417 pdata->bci, sizeof(*pdata->bci), 466 pdata->bci, sizeof(*pdata->bci),
418 false, 467 false,
@@ -469,6 +518,111 @@ static int add_children(struct twl4030_platform_data *pdata)
469 pdata->irq_base + 8 + 2, pdata->irq_base + 4); 518 pdata->irq_base + 8 + 2, pdata->irq_base + 4);
470 if (IS_ERR(child)) 519 if (IS_ERR(child))
471 return PTR_ERR(child); 520 return PTR_ERR(child);
521
522 /* we need to connect regulators to this transceiver */
523 usb_transceiver = child;
524 }
525
526 if (twl_has_regulator()) {
527 /*
528 child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1);
529 if (IS_ERR(child))
530 return PTR_ERR(child);
531 */
532
533 child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1);
534 if (IS_ERR(child))
535 return PTR_ERR(child);
536
537 child = add_regulator(TWL4030_REG_VDAC, pdata->vdac);
538 if (IS_ERR(child))
539 return PTR_ERR(child);
540
541 child = add_regulator((features & TWL4030_VAUX2)
542 ? TWL4030_REG_VAUX2_4030
543 : TWL4030_REG_VAUX2,
544 pdata->vaux2);
545 if (IS_ERR(child))
546 return PTR_ERR(child);
547 }
548
549 if (twl_has_regulator() && usb_transceiver) {
550 static struct regulator_consumer_supply usb1v5 = {
551 .supply = "usb1v5",
552 };
553 static struct regulator_consumer_supply usb1v8 = {
554 .supply = "usb1v8",
555 };
556 static struct regulator_consumer_supply usb3v1 = {
557 .supply = "usb3v1",
558 };
559 static struct regulator_consumer_supply usbcp = {
560 .supply = "usbcp",
561 };
562
563 /* this is a template that gets copied */
564 struct regulator_init_data usb_fixed = {
565 .constraints.valid_modes_mask =
566 REGULATOR_MODE_NORMAL
567 | REGULATOR_MODE_STANDBY,
568 .constraints.valid_ops_mask =
569 REGULATOR_CHANGE_MODE
570 | REGULATOR_CHANGE_STATUS,
571 };
572
573 usb1v5.dev = usb_transceiver;
574 usb1v8.dev = usb_transceiver;
575 usb3v1.dev = usb_transceiver;
576 usbcp.dev = usb_transceiver;
577
578 child = add_regulator_linked(TWL4030_REG_VUSB1V5, &usb_fixed,
579 &usb1v5, 1);
580 if (IS_ERR(child))
581 return PTR_ERR(child);
582
583 child = add_regulator_linked(TWL4030_REG_VUSB1V8, &usb_fixed,
584 &usb1v8, 1);
585 if (IS_ERR(child))
586 return PTR_ERR(child);
587
588 child = add_regulator_linked(TWL4030_REG_VUSB3V1, &usb_fixed,
589 &usb3v1, 1);
590 if (IS_ERR(child))
591 return PTR_ERR(child);
592
593 child = add_regulator_linked(TWL4030_REG_VUSBCP, &usb_fixed,
594 &usbcp, 1);
595 if (IS_ERR(child))
596 return PTR_ERR(child);
597 }
598
599 /* maybe add LDOs that are omitted on cost-reduced parts */
600 if (twl_has_regulator() && !(features & TPS_SUBSET)) {
601 /*
602 child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
603 if (IS_ERR(child))
604 return PTR_ERR(child);
605 */
606
607 child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
608 if (IS_ERR(child))
609 return PTR_ERR(child);
610
611 child = add_regulator(TWL4030_REG_VSIM, pdata->vsim);
612 if (IS_ERR(child))
613 return PTR_ERR(child);
614
615 child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1);
616 if (IS_ERR(child))
617 return PTR_ERR(child);
618
619 child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3);
620 if (IS_ERR(child))
621 return PTR_ERR(child);
622
623 child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4);
624 if (IS_ERR(child))
625 return PTR_ERR(child);
472 } 626 }
473 627
474 return 0; 628 return 0;
@@ -632,7 +786,7 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
632 goto fail; 786 goto fail;
633 } 787 }
634 788
635 status = add_children(pdata); 789 status = add_children(pdata, id->driver_data);
636fail: 790fail:
637 if (status < 0) 791 if (status < 0)
638 twl4030_remove(client); 792 twl4030_remove(client);
@@ -640,11 +794,11 @@ fail:
640} 794}
641 795
642static const struct i2c_device_id twl4030_ids[] = { 796static const struct i2c_device_id twl4030_ids[] = {
643 { "twl4030", 0 }, /* "Triton 2" */ 797 { "twl4030", TWL4030_VAUX2 }, /* "Triton 2" */
644 { "tps65950", 0 }, /* catalog version of twl4030 */ 798 { "twl5030", 0 }, /* T2 updated */
645 { "tps65930", 0 }, /* fewer LDOs and DACs; no charger */ 799 { "tps65950", 0 }, /* catalog version of twl5030 */
646 { "tps65920", 0 }, /* fewer LDOs; no codec or charger */ 800 { "tps65930", TPS_SUBSET }, /* fewer LDOs and DACs; no charger */
647 { "twl5030", 0 }, /* T2 updated */ 801 { "tps65920", TPS_SUBSET }, /* fewer LDOs; no codec or charger */
648 { /* end of list */ }, 802 { /* end of list */ },
649}; 803};
650MODULE_DEVICE_TABLE(i2c, twl4030_ids); 804MODULE_DEVICE_TABLE(i2c, twl4030_ids);
diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
index d4846695bcd0..e06555d40d35 100644
--- a/include/linux/i2c/twl4030.h
+++ b/include/linux/i2c/twl4030.h
@@ -278,6 +278,18 @@ struct twl4030_platform_data {
278 struct twl4030_keypad_data *keypad; 278 struct twl4030_keypad_data *keypad;
279 struct twl4030_usb_data *usb; 279 struct twl4030_usb_data *usb;
280 280
281 /* LDO regulators */
282 struct regulator_init_data *vdac;
283 struct regulator_init_data *vpll1;
284 struct regulator_init_data *vpll2;
285 struct regulator_init_data *vmmc1;
286 struct regulator_init_data *vmmc2;
287 struct regulator_init_data *vsim;
288 struct regulator_init_data *vaux1;
289 struct regulator_init_data *vaux2;
290 struct regulator_init_data *vaux3;
291 struct regulator_init_data *vaux4;
292
281 /* REVISIT more to come ... _nothing_ should be hard-wired */ 293 /* REVISIT more to come ... _nothing_ should be hard-wired */
282}; 294};
283 295
@@ -309,4 +321,39 @@ int twl4030_set_gpio_debounce(int gpio, int enable);
309 static inline int twl4030charger_usb_en(int enable) { return 0; } 321 static inline int twl4030charger_usb_en(int enable) { return 0; }
310#endif 322#endif
311 323
324/*----------------------------------------------------------------------*/
325
326/* Linux-specific regulator identifiers ... for now, we only support
327 * the LDOs, and leave the three buck converters alone. VDD1 and VDD2
328 * need to tie into hardware based voltage scaling (cpufreq etc), while
329 * VIO is generally fixed.
330 */
331
332/* EXTERNAL dc-to-dc buck converters */
333#define TWL4030_REG_VDD1 0
334#define TWL4030_REG_VDD2 1
335#define TWL4030_REG_VIO 2
336
337/* EXTERNAL LDOs */
338#define TWL4030_REG_VDAC 3
339#define TWL4030_REG_VPLL1 4
340#define TWL4030_REG_VPLL2 5 /* not on all chips */
341#define TWL4030_REG_VMMC1 6
342#define TWL4030_REG_VMMC2 7 /* not on all chips */
343#define TWL4030_REG_VSIM 8 /* not on all chips */
344#define TWL4030_REG_VAUX1 9 /* not on all chips */
345#define TWL4030_REG_VAUX2_4030 10 /* (twl4030-specific) */
346#define TWL4030_REG_VAUX2 11 /* (twl5030 and newer) */
347#define TWL4030_REG_VAUX3 12 /* not on all chips */
348#define TWL4030_REG_VAUX4 13 /* not on all chips */
349
350/* INTERNAL LDOs */
351#define TWL4030_REG_VINTANA1 14
352#define TWL4030_REG_VINTANA2 15
353#define TWL4030_REG_VINTDIG 16
354#define TWL4030_REG_VUSB1V5 17
355#define TWL4030_REG_VUSB1V8 18
356#define TWL4030_REG_VUSB3V1 19
357#define TWL4030_REG_VUSBCP 20
358
312#endif /* End of __TWL4030_H */ 359#endif /* End of __TWL4030_H */