diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/mfd/twl-core.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/mfd/twl-core.c')
-rw-r--r-- | drivers/mfd/twl-core.c | 334 |
1 files changed, 282 insertions, 52 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 720e099e506d..b8f2a4e7f6e7 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -95,7 +95,8 @@ | |||
95 | #define twl_has_rtc() false | 95 | #define twl_has_rtc() false |
96 | #endif | 96 | #endif |
97 | 97 | ||
98 | #if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) | 98 | #if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) ||\ |
99 | defined(CONFIG_TWL6030_USB) || defined(CONFIG_TWL6030_USB_MODULE) | ||
99 | #define twl_has_usb() true | 100 | #define twl_has_usb() true |
100 | #else | 101 | #else |
101 | #define twl_has_usb() false | 102 | #define twl_has_usb() false |
@@ -115,6 +116,12 @@ | |||
115 | #define twl_has_codec() false | 116 | #define twl_has_codec() false |
116 | #endif | 117 | #endif |
117 | 118 | ||
119 | #if defined(CONFIG_CHARGER_TWL4030) || defined(CONFIG_CHARGER_TWL4030_MODULE) | ||
120 | #define twl_has_bci() true | ||
121 | #else | ||
122 | #define twl_has_bci() false | ||
123 | #endif | ||
124 | |||
118 | /* Triton Core internal information (BEGIN) */ | 125 | /* Triton Core internal information (BEGIN) */ |
119 | 126 | ||
120 | /* Last - for index max*/ | 127 | /* Last - for index max*/ |
@@ -191,6 +198,7 @@ | |||
191 | #define TWL6030_BASEADD_GASGAUGE 0x00C0 | 198 | #define TWL6030_BASEADD_GASGAUGE 0x00C0 |
192 | #define TWL6030_BASEADD_PIH 0x00D0 | 199 | #define TWL6030_BASEADD_PIH 0x00D0 |
193 | #define TWL6030_BASEADD_CHARGER 0x00E0 | 200 | #define TWL6030_BASEADD_CHARGER 0x00E0 |
201 | #define TWL6025_BASEADD_CHARGER 0x00DA | ||
194 | 202 | ||
195 | /* subchip/slave 2 0x4A - DFT */ | 203 | /* subchip/slave 2 0x4A - DFT */ |
196 | #define TWL6030_BASEADD_DIEID 0x00C0 | 204 | #define TWL6030_BASEADD_DIEID 0x00C0 |
@@ -202,12 +210,6 @@ | |||
202 | 210 | ||
203 | /* Few power values */ | 211 | /* Few power values */ |
204 | #define R_CFG_BOOT 0x05 | 212 | #define R_CFG_BOOT 0x05 |
205 | #define R_PROTECT_KEY 0x0E | ||
206 | |||
207 | /* access control values for R_PROTECT_KEY */ | ||
208 | #define KEY_UNLOCK1 0xce | ||
209 | #define KEY_UNLOCK2 0xec | ||
210 | #define KEY_LOCK 0x00 | ||
211 | 213 | ||
212 | /* some fields in R_CFG_BOOT */ | 214 | /* some fields in R_CFG_BOOT */ |
213 | #define HFCLK_FREQ_19p2_MHZ (1 << 0) | 215 | #define HFCLK_FREQ_19p2_MHZ (1 << 0) |
@@ -228,6 +230,9 @@ | |||
228 | /* is driver active, bound to a chip? */ | 230 | /* is driver active, bound to a chip? */ |
229 | static bool inuse; | 231 | static bool inuse; |
230 | 232 | ||
233 | /* TWL IDCODE Register value */ | ||
234 | static u32 twl_idcode; | ||
235 | |||
231 | static unsigned int twl_id; | 236 | static unsigned int twl_id; |
232 | unsigned int twl_rev(void) | 237 | unsigned int twl_rev(void) |
233 | { | 238 | { |
@@ -255,7 +260,7 @@ struct twl_mapping { | |||
255 | unsigned char sid; /* Slave ID */ | 260 | unsigned char sid; /* Slave ID */ |
256 | unsigned char base; /* base address */ | 261 | unsigned char base; /* base address */ |
257 | }; | 262 | }; |
258 | struct twl_mapping *twl_map; | 263 | static struct twl_mapping *twl_map; |
259 | 264 | ||
260 | static struct twl_mapping twl4030_map[TWL4030_MODULE_LAST + 1] = { | 265 | static struct twl_mapping twl4030_map[TWL4030_MODULE_LAST + 1] = { |
261 | /* | 266 | /* |
@@ -327,6 +332,7 @@ static struct twl_mapping twl6030_map[] = { | |||
327 | 332 | ||
328 | { SUB_CHIP_ID0, TWL6030_BASEADD_RTC }, | 333 | { SUB_CHIP_ID0, TWL6030_BASEADD_RTC }, |
329 | { SUB_CHIP_ID0, TWL6030_BASEADD_MEM }, | 334 | { SUB_CHIP_ID0, TWL6030_BASEADD_MEM }, |
335 | { SUB_CHIP_ID1, TWL6025_BASEADD_CHARGER }, | ||
330 | }; | 336 | }; |
331 | 337 | ||
332 | /*----------------------------------------------------------------------*/ | 338 | /*----------------------------------------------------------------------*/ |
@@ -486,6 +492,58 @@ EXPORT_SYMBOL(twl_i2c_read_u8); | |||
486 | 492 | ||
487 | /*----------------------------------------------------------------------*/ | 493 | /*----------------------------------------------------------------------*/ |
488 | 494 | ||
495 | /** | ||
496 | * twl_read_idcode_register - API to read the IDCODE register. | ||
497 | * | ||
498 | * Unlocks the IDCODE register and read the 32 bit value. | ||
499 | */ | ||
500 | static int twl_read_idcode_register(void) | ||
501 | { | ||
502 | int err; | ||
503 | |||
504 | err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK, | ||
505 | REG_UNLOCK_TEST_REG); | ||
506 | if (err) { | ||
507 | pr_err("TWL4030 Unable to unlock IDCODE registers -%d\n", err); | ||
508 | goto fail; | ||
509 | } | ||
510 | |||
511 | err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_idcode), | ||
512 | REG_IDCODE_7_0, 4); | ||
513 | if (err) { | ||
514 | pr_err("TWL4030: unable to read IDCODE -%d\n", err); | ||
515 | goto fail; | ||
516 | } | ||
517 | |||
518 | err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x0, REG_UNLOCK_TEST_REG); | ||
519 | if (err) | ||
520 | pr_err("TWL4030 Unable to relock IDCODE registers -%d\n", err); | ||
521 | fail: | ||
522 | return err; | ||
523 | } | ||
524 | |||
525 | /** | ||
526 | * twl_get_type - API to get TWL Si type. | ||
527 | * | ||
528 | * Api to get the TWL Si type from IDCODE value. | ||
529 | */ | ||
530 | int twl_get_type(void) | ||
531 | { | ||
532 | return TWL_SIL_TYPE(twl_idcode); | ||
533 | } | ||
534 | EXPORT_SYMBOL_GPL(twl_get_type); | ||
535 | |||
536 | /** | ||
537 | * twl_get_version - API to get TWL Si version. | ||
538 | * | ||
539 | * Api to get the TWL Si version from IDCODE value. | ||
540 | */ | ||
541 | int twl_get_version(void) | ||
542 | { | ||
543 | return TWL_SIL_REV(twl_idcode); | ||
544 | } | ||
545 | EXPORT_SYMBOL_GPL(twl_get_version); | ||
546 | |||
489 | static struct device * | 547 | static struct device * |
490 | add_numbered_child(unsigned chip, const char *name, int num, | 548 | add_numbered_child(unsigned chip, const char *name, int num, |
491 | void *pdata, unsigned pdata_len, | 549 | void *pdata, unsigned pdata_len, |
@@ -548,7 +606,7 @@ static inline struct device *add_child(unsigned chip, const char *name, | |||
548 | static struct device * | 606 | static struct device * |
549 | add_regulator_linked(int num, struct regulator_init_data *pdata, | 607 | add_regulator_linked(int num, struct regulator_init_data *pdata, |
550 | struct regulator_consumer_supply *consumers, | 608 | struct regulator_consumer_supply *consumers, |
551 | unsigned num_consumers) | 609 | unsigned num_consumers, unsigned long features) |
552 | { | 610 | { |
553 | unsigned sub_chip_id; | 611 | unsigned sub_chip_id; |
554 | /* regulator framework demands init_data ... */ | 612 | /* regulator framework demands init_data ... */ |
@@ -560,6 +618,8 @@ add_regulator_linked(int num, struct regulator_init_data *pdata, | |||
560 | pdata->num_consumer_supplies = num_consumers; | 618 | pdata->num_consumer_supplies = num_consumers; |
561 | } | 619 | } |
562 | 620 | ||
621 | pdata->driver_data = (void *)features; | ||
622 | |||
563 | /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */ | 623 | /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */ |
564 | sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid; | 624 | sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid; |
565 | return add_numbered_child(sub_chip_id, "twl_reg", num, | 625 | return add_numbered_child(sub_chip_id, "twl_reg", num, |
@@ -567,9 +627,10 @@ add_regulator_linked(int num, struct regulator_init_data *pdata, | |||
567 | } | 627 | } |
568 | 628 | ||
569 | static struct device * | 629 | static struct device * |
570 | add_regulator(int num, struct regulator_init_data *pdata) | 630 | add_regulator(int num, struct regulator_init_data *pdata, |
631 | unsigned long features) | ||
571 | { | 632 | { |
572 | return add_regulator_linked(num, pdata, NULL, 0); | 633 | return add_regulator_linked(num, pdata, NULL, 0, features); |
573 | } | 634 | } |
574 | 635 | ||
575 | /* | 636 | /* |
@@ -649,17 +710,20 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
649 | }; | 710 | }; |
650 | 711 | ||
651 | child = add_regulator_linked(TWL4030_REG_VUSB1V5, | 712 | child = add_regulator_linked(TWL4030_REG_VUSB1V5, |
652 | &usb_fixed, &usb1v5, 1); | 713 | &usb_fixed, &usb1v5, 1, |
714 | features); | ||
653 | if (IS_ERR(child)) | 715 | if (IS_ERR(child)) |
654 | return PTR_ERR(child); | 716 | return PTR_ERR(child); |
655 | 717 | ||
656 | child = add_regulator_linked(TWL4030_REG_VUSB1V8, | 718 | child = add_regulator_linked(TWL4030_REG_VUSB1V8, |
657 | &usb_fixed, &usb1v8, 1); | 719 | &usb_fixed, &usb1v8, 1, |
720 | features); | ||
658 | if (IS_ERR(child)) | 721 | if (IS_ERR(child)) |
659 | return PTR_ERR(child); | 722 | return PTR_ERR(child); |
660 | 723 | ||
661 | child = add_regulator_linked(TWL4030_REG_VUSB3V1, | 724 | child = add_regulator_linked(TWL4030_REG_VUSB3V1, |
662 | &usb_fixed, &usb3v1, 1); | 725 | &usb_fixed, &usb3v1, 1, |
726 | features); | ||
663 | if (IS_ERR(child)) | 727 | if (IS_ERR(child)) |
664 | return PTR_ERR(child); | 728 | return PTR_ERR(child); |
665 | 729 | ||
@@ -682,14 +746,69 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
682 | usb3v1.dev = child; | 746 | usb3v1.dev = child; |
683 | } | 747 | } |
684 | } | 748 | } |
749 | if (twl_has_usb() && pdata->usb && twl_class_is_6030()) { | ||
750 | |||
751 | static struct regulator_consumer_supply usb3v3; | ||
752 | int regulator; | ||
753 | |||
754 | if (twl_has_regulator()) { | ||
755 | /* this is a template that gets copied */ | ||
756 | struct regulator_init_data usb_fixed = { | ||
757 | .constraints.valid_modes_mask = | ||
758 | REGULATOR_MODE_NORMAL | ||
759 | | REGULATOR_MODE_STANDBY, | ||
760 | .constraints.valid_ops_mask = | ||
761 | REGULATOR_CHANGE_MODE | ||
762 | | REGULATOR_CHANGE_STATUS, | ||
763 | }; | ||
764 | |||
765 | if (features & TWL6025_SUBCLASS) { | ||
766 | usb3v3.supply = "ldousb"; | ||
767 | regulator = TWL6025_REG_LDOUSB; | ||
768 | } else { | ||
769 | usb3v3.supply = "vusb"; | ||
770 | regulator = TWL6030_REG_VUSB; | ||
771 | } | ||
772 | child = add_regulator_linked(regulator, &usb_fixed, | ||
773 | &usb3v3, 1, | ||
774 | features); | ||
775 | if (IS_ERR(child)) | ||
776 | return PTR_ERR(child); | ||
777 | } | ||
778 | |||
779 | pdata->usb->features = features; | ||
780 | |||
781 | child = add_child(0, "twl6030_usb", | ||
782 | pdata->usb, sizeof(*pdata->usb), | ||
783 | true, | ||
784 | /* irq1 = VBUS_PRES, irq0 = USB ID */ | ||
785 | pdata->irq_base + USBOTG_INTR_OFFSET, | ||
786 | pdata->irq_base + USB_PRES_INTR_OFFSET); | ||
787 | |||
788 | if (IS_ERR(child)) | ||
789 | return PTR_ERR(child); | ||
790 | /* we need to connect regulators to this transceiver */ | ||
791 | if (twl_has_regulator() && child) | ||
792 | usb3v3.dev = child; | ||
793 | } else if (twl_has_regulator() && twl_class_is_6030()) { | ||
794 | if (features & TWL6025_SUBCLASS) | ||
795 | child = add_regulator(TWL6025_REG_LDOUSB, | ||
796 | pdata->ldousb, features); | ||
797 | else | ||
798 | child = add_regulator(TWL6030_REG_VUSB, | ||
799 | pdata->vusb, features); | ||
800 | |||
801 | if (IS_ERR(child)) | ||
802 | return PTR_ERR(child); | ||
803 | } | ||
685 | 804 | ||
686 | if (twl_has_watchdog()) { | 805 | if (twl_has_watchdog() && twl_class_is_4030()) { |
687 | child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); | 806 | child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); |
688 | if (IS_ERR(child)) | 807 | if (IS_ERR(child)) |
689 | return PTR_ERR(child); | 808 | return PTR_ERR(child); |
690 | } | 809 | } |
691 | 810 | ||
692 | if (twl_has_pwrbutton()) { | 811 | if (twl_has_pwrbutton() && twl_class_is_4030()) { |
693 | child = add_child(1, "twl4030_pwrbutton", | 812 | child = add_child(1, "twl4030_pwrbutton", |
694 | NULL, 0, true, pdata->irq_base + 8 + 0, 0); | 813 | NULL, 0, true, pdata->irq_base + 8 + 0, 0); |
695 | if (IS_ERR(child)) | 814 | if (IS_ERR(child)) |
@@ -698,17 +817,17 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
698 | 817 | ||
699 | if (twl_has_codec() && pdata->codec && twl_class_is_4030()) { | 818 | if (twl_has_codec() && pdata->codec && twl_class_is_4030()) { |
700 | sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; | 819 | sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; |
701 | child = add_child(sub_chip_id, "twl4030_codec", | 820 | child = add_child(sub_chip_id, "twl4030-audio", |
702 | pdata->codec, sizeof(*pdata->codec), | 821 | pdata->codec, sizeof(*pdata->codec), |
703 | false, 0, 0); | 822 | false, 0, 0); |
704 | if (IS_ERR(child)) | 823 | if (IS_ERR(child)) |
705 | return PTR_ERR(child); | 824 | return PTR_ERR(child); |
706 | } | 825 | } |
707 | 826 | ||
708 | /* Phoenix*/ | 827 | /* Phoenix codec driver is probed directly atm */ |
709 | if (twl_has_codec() && pdata->codec && twl_class_is_6030()) { | 828 | if (twl_has_codec() && pdata->codec && twl_class_is_6030()) { |
710 | sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; | 829 | sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; |
711 | child = add_child(sub_chip_id, "twl6040_codec", | 830 | child = add_child(sub_chip_id, "twl6040-codec", |
712 | pdata->codec, sizeof(*pdata->codec), | 831 | pdata->codec, sizeof(*pdata->codec), |
713 | false, 0, 0); | 832 | false, 0, 0); |
714 | if (IS_ERR(child)) | 833 | if (IS_ERR(child)) |
@@ -717,46 +836,55 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
717 | 836 | ||
718 | /* twl4030 regulators */ | 837 | /* twl4030 regulators */ |
719 | if (twl_has_regulator() && twl_class_is_4030()) { | 838 | if (twl_has_regulator() && twl_class_is_4030()) { |
720 | child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1); | 839 | child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1, |
840 | features); | ||
721 | if (IS_ERR(child)) | 841 | if (IS_ERR(child)) |
722 | return PTR_ERR(child); | 842 | return PTR_ERR(child); |
723 | 843 | ||
724 | child = add_regulator(TWL4030_REG_VIO, pdata->vio); | 844 | child = add_regulator(TWL4030_REG_VIO, pdata->vio, |
845 | features); | ||
725 | if (IS_ERR(child)) | 846 | if (IS_ERR(child)) |
726 | return PTR_ERR(child); | 847 | return PTR_ERR(child); |
727 | 848 | ||
728 | child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1); | 849 | child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1, |
850 | features); | ||
729 | if (IS_ERR(child)) | 851 | if (IS_ERR(child)) |
730 | return PTR_ERR(child); | 852 | return PTR_ERR(child); |
731 | 853 | ||
732 | child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2); | 854 | child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2, |
855 | features); | ||
733 | if (IS_ERR(child)) | 856 | if (IS_ERR(child)) |
734 | return PTR_ERR(child); | 857 | return PTR_ERR(child); |
735 | 858 | ||
736 | child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1); | 859 | child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1, |
860 | features); | ||
737 | if (IS_ERR(child)) | 861 | if (IS_ERR(child)) |
738 | return PTR_ERR(child); | 862 | return PTR_ERR(child); |
739 | 863 | ||
740 | child = add_regulator(TWL4030_REG_VDAC, pdata->vdac); | 864 | child = add_regulator(TWL4030_REG_VDAC, pdata->vdac, |
865 | features); | ||
741 | if (IS_ERR(child)) | 866 | if (IS_ERR(child)) |
742 | return PTR_ERR(child); | 867 | return PTR_ERR(child); |
743 | 868 | ||
744 | child = add_regulator((features & TWL4030_VAUX2) | 869 | child = add_regulator((features & TWL4030_VAUX2) |
745 | ? TWL4030_REG_VAUX2_4030 | 870 | ? TWL4030_REG_VAUX2_4030 |
746 | : TWL4030_REG_VAUX2, | 871 | : TWL4030_REG_VAUX2, |
747 | pdata->vaux2); | 872 | pdata->vaux2, features); |
748 | if (IS_ERR(child)) | 873 | if (IS_ERR(child)) |
749 | return PTR_ERR(child); | 874 | return PTR_ERR(child); |
750 | 875 | ||
751 | child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1); | 876 | child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1, |
877 | features); | ||
752 | if (IS_ERR(child)) | 878 | if (IS_ERR(child)) |
753 | return PTR_ERR(child); | 879 | return PTR_ERR(child); |
754 | 880 | ||
755 | child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2); | 881 | child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2, |
882 | features); | ||
756 | if (IS_ERR(child)) | 883 | if (IS_ERR(child)) |
757 | return PTR_ERR(child); | 884 | return PTR_ERR(child); |
758 | 885 | ||
759 | child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig); | 886 | child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig, |
887 | features); | ||
760 | if (IS_ERR(child)) | 888 | if (IS_ERR(child)) |
761 | return PTR_ERR(child); | 889 | return PTR_ERR(child); |
762 | } | 890 | } |
@@ -764,70 +892,161 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
764 | /* maybe add LDOs that are omitted on cost-reduced parts */ | 892 | /* maybe add LDOs that are omitted on cost-reduced parts */ |
765 | if (twl_has_regulator() && !(features & TPS_SUBSET) | 893 | if (twl_has_regulator() && !(features & TPS_SUBSET) |
766 | && twl_class_is_4030()) { | 894 | && twl_class_is_4030()) { |
767 | child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2); | 895 | child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2, |
896 | features); | ||
768 | if (IS_ERR(child)) | 897 | if (IS_ERR(child)) |
769 | return PTR_ERR(child); | 898 | return PTR_ERR(child); |
770 | 899 | ||
771 | child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2); | 900 | child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2, |
901 | features); | ||
772 | if (IS_ERR(child)) | 902 | if (IS_ERR(child)) |
773 | return PTR_ERR(child); | 903 | return PTR_ERR(child); |
774 | 904 | ||
775 | child = add_regulator(TWL4030_REG_VSIM, pdata->vsim); | 905 | child = add_regulator(TWL4030_REG_VSIM, pdata->vsim, |
906 | features); | ||
776 | if (IS_ERR(child)) | 907 | if (IS_ERR(child)) |
777 | return PTR_ERR(child); | 908 | return PTR_ERR(child); |
778 | 909 | ||
779 | child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1); | 910 | child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1, |
911 | features); | ||
780 | if (IS_ERR(child)) | 912 | if (IS_ERR(child)) |
781 | return PTR_ERR(child); | 913 | return PTR_ERR(child); |
782 | 914 | ||
783 | child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3); | 915 | child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3, |
916 | features); | ||
784 | if (IS_ERR(child)) | 917 | if (IS_ERR(child)) |
785 | return PTR_ERR(child); | 918 | return PTR_ERR(child); |
786 | 919 | ||
787 | child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4); | 920 | child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4, |
921 | features); | ||
788 | if (IS_ERR(child)) | 922 | if (IS_ERR(child)) |
789 | return PTR_ERR(child); | 923 | return PTR_ERR(child); |
790 | } | 924 | } |
791 | 925 | ||
792 | /* twl6030 regulators */ | 926 | /* twl6030 regulators */ |
927 | if (twl_has_regulator() && twl_class_is_6030() && | ||
928 | !(features & TWL6025_SUBCLASS)) { | ||
929 | child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc, | ||
930 | features); | ||
931 | if (IS_ERR(child)) | ||
932 | return PTR_ERR(child); | ||
933 | |||
934 | child = add_regulator(TWL6030_REG_VPP, pdata->vpp, | ||
935 | features); | ||
936 | if (IS_ERR(child)) | ||
937 | return PTR_ERR(child); | ||
938 | |||
939 | child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim, | ||
940 | features); | ||
941 | if (IS_ERR(child)) | ||
942 | return PTR_ERR(child); | ||
943 | |||
944 | child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio, | ||
945 | features); | ||
946 | if (IS_ERR(child)) | ||
947 | return PTR_ERR(child); | ||
948 | |||
949 | child = add_regulator(TWL6030_REG_VDAC, pdata->vdac, | ||
950 | features); | ||
951 | if (IS_ERR(child)) | ||
952 | return PTR_ERR(child); | ||
953 | |||
954 | child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1, | ||
955 | features); | ||
956 | if (IS_ERR(child)) | ||
957 | return PTR_ERR(child); | ||
958 | |||
959 | child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2, | ||
960 | features); | ||
961 | if (IS_ERR(child)) | ||
962 | return PTR_ERR(child); | ||
963 | |||
964 | child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3, | ||
965 | features); | ||
966 | if (IS_ERR(child)) | ||
967 | return PTR_ERR(child); | ||
968 | |||
969 | child = add_regulator(TWL6030_REG_CLK32KG, pdata->clk32kg, | ||
970 | features); | ||
971 | if (IS_ERR(child)) | ||
972 | return PTR_ERR(child); | ||
973 | } | ||
974 | |||
975 | /* 6030 and 6025 share this regulator */ | ||
793 | if (twl_has_regulator() && twl_class_is_6030()) { | 976 | if (twl_has_regulator() && twl_class_is_6030()) { |
794 | child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc); | 977 | child = add_regulator(TWL6030_REG_VANA, pdata->vana, |
978 | features); | ||
795 | if (IS_ERR(child)) | 979 | if (IS_ERR(child)) |
796 | return PTR_ERR(child); | 980 | return PTR_ERR(child); |
981 | } | ||
797 | 982 | ||
798 | child = add_regulator(TWL6030_REG_VPP, pdata->vpp); | 983 | /* twl6025 regulators */ |
984 | if (twl_has_regulator() && twl_class_is_6030() && | ||
985 | (features & TWL6025_SUBCLASS)) { | ||
986 | child = add_regulator(TWL6025_REG_LDO5, pdata->ldo5, | ||
987 | features); | ||
799 | if (IS_ERR(child)) | 988 | if (IS_ERR(child)) |
800 | return PTR_ERR(child); | 989 | return PTR_ERR(child); |
801 | 990 | ||
802 | child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim); | 991 | child = add_regulator(TWL6025_REG_LDO1, pdata->ldo1, |
992 | features); | ||
803 | if (IS_ERR(child)) | 993 | if (IS_ERR(child)) |
804 | return PTR_ERR(child); | 994 | return PTR_ERR(child); |
805 | 995 | ||
806 | child = add_regulator(TWL6030_REG_VANA, pdata->vana); | 996 | child = add_regulator(TWL6025_REG_LDO7, pdata->ldo7, |
997 | features); | ||
807 | if (IS_ERR(child)) | 998 | if (IS_ERR(child)) |
808 | return PTR_ERR(child); | 999 | return PTR_ERR(child); |
809 | 1000 | ||
810 | child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio); | 1001 | child = add_regulator(TWL6025_REG_LDO6, pdata->ldo6, |
1002 | features); | ||
811 | if (IS_ERR(child)) | 1003 | if (IS_ERR(child)) |
812 | return PTR_ERR(child); | 1004 | return PTR_ERR(child); |
813 | 1005 | ||
814 | child = add_regulator(TWL6030_REG_VDAC, pdata->vdac); | 1006 | child = add_regulator(TWL6025_REG_LDOLN, pdata->ldoln, |
1007 | features); | ||
815 | if (IS_ERR(child)) | 1008 | if (IS_ERR(child)) |
816 | return PTR_ERR(child); | 1009 | return PTR_ERR(child); |
817 | 1010 | ||
818 | child = add_regulator(TWL6030_REG_VUSB, pdata->vusb); | 1011 | child = add_regulator(TWL6025_REG_LDO2, pdata->ldo2, |
1012 | features); | ||
819 | if (IS_ERR(child)) | 1013 | if (IS_ERR(child)) |
820 | return PTR_ERR(child); | 1014 | return PTR_ERR(child); |
821 | 1015 | ||
822 | child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1); | 1016 | child = add_regulator(TWL6025_REG_LDO4, pdata->ldo4, |
1017 | features); | ||
823 | if (IS_ERR(child)) | 1018 | if (IS_ERR(child)) |
824 | return PTR_ERR(child); | 1019 | return PTR_ERR(child); |
825 | 1020 | ||
826 | child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2); | 1021 | child = add_regulator(TWL6025_REG_LDO3, pdata->ldo3, |
1022 | features); | ||
827 | if (IS_ERR(child)) | 1023 | if (IS_ERR(child)) |
828 | return PTR_ERR(child); | 1024 | return PTR_ERR(child); |
829 | 1025 | ||
830 | child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3); | 1026 | child = add_regulator(TWL6025_REG_SMPS3, pdata->smps3, |
1027 | features); | ||
1028 | if (IS_ERR(child)) | ||
1029 | return PTR_ERR(child); | ||
1030 | |||
1031 | child = add_regulator(TWL6025_REG_SMPS4, pdata->smps4, | ||
1032 | features); | ||
1033 | if (IS_ERR(child)) | ||
1034 | return PTR_ERR(child); | ||
1035 | |||
1036 | child = add_regulator(TWL6025_REG_VIO, pdata->vio6025, | ||
1037 | features); | ||
1038 | if (IS_ERR(child)) | ||
1039 | return PTR_ERR(child); | ||
1040 | |||
1041 | } | ||
1042 | |||
1043 | if (twl_has_bci() && pdata->bci && | ||
1044 | !(features & (TPS_SUBSET | TWL5031))) { | ||
1045 | child = add_child(3, "twl4030_bci", | ||
1046 | pdata->bci, sizeof(*pdata->bci), false, | ||
1047 | /* irq0 = CHG_PRES, irq1 = BCI */ | ||
1048 | pdata->irq_base + BCI_PRES_INTR_OFFSET, | ||
1049 | pdata->irq_base + BCI_INTR_OFFSET); | ||
831 | if (IS_ERR(child)) | 1050 | if (IS_ERR(child)) |
832 | return PTR_ERR(child); | 1051 | return PTR_ERR(child); |
833 | } | 1052 | } |
@@ -846,8 +1065,8 @@ static inline int __init protect_pm_master(void) | |||
846 | { | 1065 | { |
847 | int e = 0; | 1066 | int e = 0; |
848 | 1067 | ||
849 | e = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_LOCK, | 1068 | e = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, |
850 | R_PROTECT_KEY); | 1069 | TWL4030_PM_MASTER_PROTECT_KEY); |
851 | return e; | 1070 | return e; |
852 | } | 1071 | } |
853 | 1072 | ||
@@ -855,10 +1074,13 @@ static inline int __init unprotect_pm_master(void) | |||
855 | { | 1074 | { |
856 | int e = 0; | 1075 | int e = 0; |
857 | 1076 | ||
858 | e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_UNLOCK1, | 1077 | e |= twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, |
859 | R_PROTECT_KEY); | 1078 | TWL4030_PM_MASTER_KEY_CFG1, |
860 | e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_UNLOCK2, | 1079 | TWL4030_PM_MASTER_PROTECT_KEY); |
861 | R_PROTECT_KEY); | 1080 | e |= twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, |
1081 | TWL4030_PM_MASTER_KEY_CFG2, | ||
1082 | TWL4030_PM_MASTER_PROTECT_KEY); | ||
1083 | |||
862 | return e; | 1084 | return e; |
863 | } | 1085 | } |
864 | 1086 | ||
@@ -955,13 +1177,14 @@ static int twl_remove(struct i2c_client *client) | |||
955 | } | 1177 | } |
956 | 1178 | ||
957 | /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ | 1179 | /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ |
958 | static int __init | 1180 | static int __devinit |
959 | twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | 1181 | twl_probe(struct i2c_client *client, const struct i2c_device_id *id) |
960 | { | 1182 | { |
961 | int status; | 1183 | int status; |
962 | unsigned i; | 1184 | unsigned i; |
963 | struct twl4030_platform_data *pdata = client->dev.platform_data; | 1185 | struct twl4030_platform_data *pdata = client->dev.platform_data; |
964 | u8 temp; | 1186 | u8 temp; |
1187 | int ret = 0; | ||
965 | 1188 | ||
966 | if (!pdata) { | 1189 | if (!pdata) { |
967 | dev_dbg(&client->dev, "no platform data?\n"); | 1190 | dev_dbg(&client->dev, "no platform data?\n"); |
@@ -1008,6 +1231,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1008 | /* setup clock framework */ | 1231 | /* setup clock framework */ |
1009 | clocks_init(&client->dev, pdata->clock); | 1232 | clocks_init(&client->dev, pdata->clock); |
1010 | 1233 | ||
1234 | /* read TWL IDCODE Register */ | ||
1235 | if (twl_id == TWL4030_CLASS_ID) { | ||
1236 | ret = twl_read_idcode_register(); | ||
1237 | WARN(ret < 0, "Error: reading twl_idcode register value\n"); | ||
1238 | } | ||
1239 | |||
1011 | /* load power event scripts */ | 1240 | /* load power event scripts */ |
1012 | if (twl_has_power() && pdata->power) | 1241 | if (twl_has_power() && pdata->power) |
1013 | twl4030_power_init(pdata->power); | 1242 | twl4030_power_init(pdata->power); |
@@ -1056,6 +1285,7 @@ static const struct i2c_device_id twl_ids[] = { | |||
1056 | { "tps65930", TPS_SUBSET }, /* fewer LDOs and DACs; no charger */ | 1285 | { "tps65930", TPS_SUBSET }, /* fewer LDOs and DACs; no charger */ |
1057 | { "tps65920", TPS_SUBSET }, /* fewer LDOs; no codec or charger */ | 1286 | { "tps65920", TPS_SUBSET }, /* fewer LDOs; no codec or charger */ |
1058 | { "twl6030", TWL6030_CLASS }, /* "Phoenix power chip" */ | 1287 | { "twl6030", TWL6030_CLASS }, /* "Phoenix power chip" */ |
1288 | { "twl6025", TWL6030_CLASS | TWL6025_SUBCLASS }, /* "Phoenix lite" */ | ||
1059 | { /* end of list */ }, | 1289 | { /* end of list */ }, |
1060 | }; | 1290 | }; |
1061 | MODULE_DEVICE_TABLE(i2c, twl_ids); | 1291 | MODULE_DEVICE_TABLE(i2c, twl_ids); |