diff options
Diffstat (limited to 'drivers/power/ab8500_charger.c')
-rw-r--r-- | drivers/power/ab8500_charger.c | 699 |
1 files changed, 497 insertions, 202 deletions
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 24b30b7ea5ca..a558318b169c 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/notifier.h> | ||
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
20 | #include <linux/power_supply.h> | 21 | #include <linux/power_supply.h> |
@@ -52,10 +53,15 @@ | |||
52 | #define VBUS_DET_DBNC100 0x02 | 53 | #define VBUS_DET_DBNC100 0x02 |
53 | #define VBUS_DET_DBNC1 0x01 | 54 | #define VBUS_DET_DBNC1 0x01 |
54 | #define OTP_ENABLE_WD 0x01 | 55 | #define OTP_ENABLE_WD 0x01 |
56 | #define DROP_COUNT_RESET 0x01 | ||
57 | #define USB_CH_DET 0x01 | ||
55 | 58 | ||
56 | #define MAIN_CH_INPUT_CURR_SHIFT 4 | 59 | #define MAIN_CH_INPUT_CURR_SHIFT 4 |
57 | #define VBUS_IN_CURR_LIM_SHIFT 4 | 60 | #define VBUS_IN_CURR_LIM_SHIFT 4 |
61 | #define AB8540_VBUS_IN_CURR_LIM_SHIFT 2 | ||
58 | #define AUTO_VBUS_IN_CURR_LIM_SHIFT 4 | 62 | #define AUTO_VBUS_IN_CURR_LIM_SHIFT 4 |
63 | #define AB8540_AUTO_VBUS_IN_CURR_MASK 0x3F | ||
64 | #define VBUS_IN_CURR_LIM_RETRY_SET_TIME 30 /* seconds */ | ||
59 | 65 | ||
60 | #define LED_INDICATOR_PWM_ENA 0x01 | 66 | #define LED_INDICATOR_PWM_ENA 0x01 |
61 | #define LED_INDICATOR_PWM_DIS 0x00 | 67 | #define LED_INDICATOR_PWM_DIS 0x00 |
@@ -77,7 +83,9 @@ | |||
77 | 83 | ||
78 | /* UsbLineStatus register bit masks */ | 84 | /* UsbLineStatus register bit masks */ |
79 | #define AB8500_USB_LINK_STATUS 0x78 | 85 | #define AB8500_USB_LINK_STATUS 0x78 |
86 | #define AB8505_USB_LINK_STATUS 0xF8 | ||
80 | #define AB8500_STD_HOST_SUSP 0x18 | 87 | #define AB8500_STD_HOST_SUSP 0x18 |
88 | #define USB_LINK_STATUS_SHIFT 3 | ||
81 | 89 | ||
82 | /* Watchdog timeout constant */ | 90 | /* Watchdog timeout constant */ |
83 | #define WD_TIMER 0x30 /* 4min */ | 91 | #define WD_TIMER 0x30 /* 4min */ |
@@ -96,6 +104,10 @@ | |||
96 | #define AB8500_SW_CONTROL_FALLBACK 0x03 | 104 | #define AB8500_SW_CONTROL_FALLBACK 0x03 |
97 | /* Wait for enumeration before charing in us */ | 105 | /* Wait for enumeration before charing in us */ |
98 | #define WAIT_ACA_RID_ENUMERATION (5 * 1000) | 106 | #define WAIT_ACA_RID_ENUMERATION (5 * 1000) |
107 | /*External charger control*/ | ||
108 | #define AB8500_SYS_CHARGER_CONTROL_REG 0x52 | ||
109 | #define EXTERNAL_CHARGER_DISABLE_REG_VAL 0x03 | ||
110 | #define EXTERNAL_CHARGER_ENABLE_REG_VAL 0x07 | ||
99 | 111 | ||
100 | /* UsbLineStatus register - usb types */ | 112 | /* UsbLineStatus register - usb types */ |
101 | enum ab8500_charger_link_status { | 113 | enum ab8500_charger_link_status { |
@@ -196,10 +208,15 @@ struct ab8500_charger_usb_state { | |||
196 | spinlock_t usb_lock; | 208 | spinlock_t usb_lock; |
197 | }; | 209 | }; |
198 | 210 | ||
211 | struct ab8500_charger_max_usb_in_curr { | ||
212 | int usb_type_max; | ||
213 | int set_max; | ||
214 | int calculated_max; | ||
215 | }; | ||
216 | |||
199 | /** | 217 | /** |
200 | * struct ab8500_charger - ab8500 Charger device information | 218 | * struct ab8500_charger - ab8500 Charger device information |
201 | * @dev: Pointer to the structure device | 219 | * @dev: Pointer to the structure device |
202 | * @max_usb_in_curr: Max USB charger input current | ||
203 | * @vbus_detected: VBUS detected | 220 | * @vbus_detected: VBUS detected |
204 | * @vbus_detected_start: | 221 | * @vbus_detected_start: |
205 | * VBUS detected during startup | 222 | * VBUS detected during startup |
@@ -214,7 +231,6 @@ struct ab8500_charger_usb_state { | |||
214 | * @autopower Indicate if we should have automatic pwron after pwrloss | 231 | * @autopower Indicate if we should have automatic pwron after pwrloss |
215 | * @autopower_cfg platform specific power config support for "pwron after pwrloss" | 232 | * @autopower_cfg platform specific power config support for "pwron after pwrloss" |
216 | * @invalid_charger_detect_state State when forcing AB to use invalid charger | 233 | * @invalid_charger_detect_state State when forcing AB to use invalid charger |
217 | * @is_usb_host: Indicate if last detected USB type is host | ||
218 | * @is_aca_rid: Incicate if accessory is ACA type | 234 | * @is_aca_rid: Incicate if accessory is ACA type |
219 | * @current_stepping_sessions: | 235 | * @current_stepping_sessions: |
220 | * Counter for current stepping sessions | 236 | * Counter for current stepping sessions |
@@ -223,6 +239,7 @@ struct ab8500_charger_usb_state { | |||
223 | * @bm: Platform specific battery management information | 239 | * @bm: Platform specific battery management information |
224 | * @flags: Structure for information about events triggered | 240 | * @flags: Structure for information about events triggered |
225 | * @usb_state: Structure for usb stack information | 241 | * @usb_state: Structure for usb stack information |
242 | * @max_usb_in_curr: Max USB charger input current | ||
226 | * @ac_chg: AC charger power supply | 243 | * @ac_chg: AC charger power supply |
227 | * @usb_chg: USB charger power supply | 244 | * @usb_chg: USB charger power supply |
228 | * @ac: Structure that holds the AC charger properties | 245 | * @ac: Structure that holds the AC charger properties |
@@ -254,7 +271,6 @@ struct ab8500_charger_usb_state { | |||
254 | */ | 271 | */ |
255 | struct ab8500_charger { | 272 | struct ab8500_charger { |
256 | struct device *dev; | 273 | struct device *dev; |
257 | int max_usb_in_curr; | ||
258 | bool vbus_detected; | 274 | bool vbus_detected; |
259 | bool vbus_detected_start; | 275 | bool vbus_detected_start; |
260 | bool ac_conn; | 276 | bool ac_conn; |
@@ -266,7 +282,6 @@ struct ab8500_charger { | |||
266 | bool autopower; | 282 | bool autopower; |
267 | bool autopower_cfg; | 283 | bool autopower_cfg; |
268 | int invalid_charger_detect_state; | 284 | int invalid_charger_detect_state; |
269 | bool is_usb_host; | ||
270 | int is_aca_rid; | 285 | int is_aca_rid; |
271 | atomic_t current_stepping_sessions; | 286 | atomic_t current_stepping_sessions; |
272 | struct ab8500 *parent; | 287 | struct ab8500 *parent; |
@@ -274,6 +289,7 @@ struct ab8500_charger { | |||
274 | struct abx500_bm_data *bm; | 289 | struct abx500_bm_data *bm; |
275 | struct ab8500_charger_event_flags flags; | 290 | struct ab8500_charger_event_flags flags; |
276 | struct ab8500_charger_usb_state usb_state; | 291 | struct ab8500_charger_usb_state usb_state; |
292 | struct ab8500_charger_max_usb_in_curr max_usb_in_curr; | ||
277 | struct ux500_charger ac_chg; | 293 | struct ux500_charger ac_chg; |
278 | struct ux500_charger usb_chg; | 294 | struct ux500_charger usb_chg; |
279 | struct ab8500_charger_info ac; | 295 | struct ab8500_charger_info ac; |
@@ -415,13 +431,18 @@ static void ab8500_charger_set_usb_connected(struct ab8500_charger *di, | |||
415 | if (connected != di->usb.charger_connected) { | 431 | if (connected != di->usb.charger_connected) { |
416 | dev_dbg(di->dev, "USB connected:%i\n", connected); | 432 | dev_dbg(di->dev, "USB connected:%i\n", connected); |
417 | di->usb.charger_connected = connected; | 433 | di->usb.charger_connected = connected; |
434 | |||
435 | if (!connected) | ||
436 | di->flags.vbus_drop_end = false; | ||
437 | |||
418 | sysfs_notify(&di->usb_chg.psy.dev->kobj, NULL, "present"); | 438 | sysfs_notify(&di->usb_chg.psy.dev->kobj, NULL, "present"); |
419 | 439 | ||
420 | if (connected) { | 440 | if (connected) { |
421 | mutex_lock(&di->charger_attached_mutex); | 441 | mutex_lock(&di->charger_attached_mutex); |
422 | mutex_unlock(&di->charger_attached_mutex); | 442 | mutex_unlock(&di->charger_attached_mutex); |
423 | 443 | ||
424 | queue_delayed_work(di->charger_wq, | 444 | if (is_ab8500(di->parent)) |
445 | queue_delayed_work(di->charger_wq, | ||
425 | &di->usb_charger_attached_work, | 446 | &di->usb_charger_attached_work, |
426 | HZ); | 447 | HZ); |
427 | } else { | 448 | } else { |
@@ -668,23 +689,19 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
668 | case USB_STAT_STD_HOST_C_S: | 689 | case USB_STAT_STD_HOST_C_S: |
669 | dev_dbg(di->dev, "USB Type - Standard host is " | 690 | dev_dbg(di->dev, "USB Type - Standard host is " |
670 | "detected through USB driver\n"); | 691 | "detected through USB driver\n"); |
671 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 692 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
672 | di->is_usb_host = true; | ||
673 | di->is_aca_rid = 0; | 693 | di->is_aca_rid = 0; |
674 | break; | 694 | break; |
675 | case USB_STAT_HOST_CHG_HS_CHIRP: | 695 | case USB_STAT_HOST_CHG_HS_CHIRP: |
676 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 696 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
677 | di->is_usb_host = true; | ||
678 | di->is_aca_rid = 0; | 697 | di->is_aca_rid = 0; |
679 | break; | 698 | break; |
680 | case USB_STAT_HOST_CHG_HS: | 699 | case USB_STAT_HOST_CHG_HS: |
681 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 700 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
682 | di->is_usb_host = true; | ||
683 | di->is_aca_rid = 0; | 701 | di->is_aca_rid = 0; |
684 | break; | 702 | break; |
685 | case USB_STAT_ACA_RID_C_HS: | 703 | case USB_STAT_ACA_RID_C_HS: |
686 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P9; | 704 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P9; |
687 | di->is_usb_host = false; | ||
688 | di->is_aca_rid = 0; | 705 | di->is_aca_rid = 0; |
689 | break; | 706 | break; |
690 | case USB_STAT_ACA_RID_A: | 707 | case USB_STAT_ACA_RID_A: |
@@ -693,8 +710,7 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
693 | * can consume (900mA). Closest level is 500mA | 710 | * can consume (900mA). Closest level is 500mA |
694 | */ | 711 | */ |
695 | dev_dbg(di->dev, "USB_STAT_ACA_RID_A detected\n"); | 712 | dev_dbg(di->dev, "USB_STAT_ACA_RID_A detected\n"); |
696 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 713 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
697 | di->is_usb_host = false; | ||
698 | di->is_aca_rid = 1; | 714 | di->is_aca_rid = 1; |
699 | break; | 715 | break; |
700 | case USB_STAT_ACA_RID_B: | 716 | case USB_STAT_ACA_RID_B: |
@@ -702,38 +718,35 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
702 | * Dedicated charger level minus 120mA (20mA for ACA and | 718 | * Dedicated charger level minus 120mA (20mA for ACA and |
703 | * 100mA for potential accessory). Closest level is 1300mA | 719 | * 100mA for potential accessory). Closest level is 1300mA |
704 | */ | 720 | */ |
705 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P3; | 721 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P3; |
706 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, | 722 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, |
707 | di->max_usb_in_curr); | 723 | di->max_usb_in_curr.usb_type_max); |
708 | di->is_usb_host = false; | ||
709 | di->is_aca_rid = 1; | 724 | di->is_aca_rid = 1; |
710 | break; | 725 | break; |
711 | case USB_STAT_HOST_CHG_NM: | 726 | case USB_STAT_HOST_CHG_NM: |
712 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 727 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
713 | di->is_usb_host = true; | ||
714 | di->is_aca_rid = 0; | 728 | di->is_aca_rid = 0; |
715 | break; | 729 | break; |
716 | case USB_STAT_DEDICATED_CHG: | 730 | case USB_STAT_DEDICATED_CHG: |
717 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; | 731 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P5; |
718 | di->is_usb_host = false; | ||
719 | di->is_aca_rid = 0; | 732 | di->is_aca_rid = 0; |
720 | break; | 733 | break; |
721 | case USB_STAT_ACA_RID_C_HS_CHIRP: | 734 | case USB_STAT_ACA_RID_C_HS_CHIRP: |
722 | case USB_STAT_ACA_RID_C_NM: | 735 | case USB_STAT_ACA_RID_C_NM: |
723 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; | 736 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P5; |
724 | di->is_usb_host = false; | ||
725 | di->is_aca_rid = 1; | 737 | di->is_aca_rid = 1; |
726 | break; | 738 | break; |
727 | case USB_STAT_NOT_CONFIGURED: | 739 | case USB_STAT_NOT_CONFIGURED: |
728 | if (di->vbus_detected) { | 740 | if (di->vbus_detected) { |
729 | di->usb_device_is_unrecognised = true; | 741 | di->usb_device_is_unrecognised = true; |
730 | dev_dbg(di->dev, "USB Type - Legacy charger.\n"); | 742 | dev_dbg(di->dev, "USB Type - Legacy charger.\n"); |
731 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; | 743 | di->max_usb_in_curr.usb_type_max = |
744 | USB_CH_IP_CUR_LVL_1P5; | ||
732 | break; | 745 | break; |
733 | } | 746 | } |
734 | case USB_STAT_HM_IDGND: | 747 | case USB_STAT_HM_IDGND: |
735 | dev_err(di->dev, "USB Type - Charging not allowed\n"); | 748 | dev_err(di->dev, "USB Type - Charging not allowed\n"); |
736 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; | 749 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; |
737 | ret = -ENXIO; | 750 | ret = -ENXIO; |
738 | break; | 751 | break; |
739 | case USB_STAT_RESERVED: | 752 | case USB_STAT_RESERVED: |
@@ -743,12 +756,13 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
743 | "VBUS has collapsed\n"); | 756 | "VBUS has collapsed\n"); |
744 | ret = -ENXIO; | 757 | ret = -ENXIO; |
745 | break; | 758 | break; |
746 | } | 759 | } else { |
747 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | ||
748 | dev_dbg(di->dev, "USB Type - Charging not allowed\n"); | 760 | dev_dbg(di->dev, "USB Type - Charging not allowed\n"); |
749 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; | 761 | di->max_usb_in_curr.usb_type_max = |
762 | USB_CH_IP_CUR_LVL_0P05; | ||
750 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", | 763 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", |
751 | link_status, di->max_usb_in_curr); | 764 | link_status, |
765 | di->max_usb_in_curr.usb_type_max); | ||
752 | ret = -ENXIO; | 766 | ret = -ENXIO; |
753 | break; | 767 | break; |
754 | } | 768 | } |
@@ -757,23 +771,24 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
757 | case USB_STAT_CARKIT_2: | 771 | case USB_STAT_CARKIT_2: |
758 | case USB_STAT_ACA_DOCK_CHARGER: | 772 | case USB_STAT_ACA_DOCK_CHARGER: |
759 | case USB_STAT_CHARGER_LINE_1: | 773 | case USB_STAT_CHARGER_LINE_1: |
760 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 774 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
761 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, | 775 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, |
762 | di->max_usb_in_curr); | 776 | di->max_usb_in_curr.usb_type_max); |
763 | case USB_STAT_NOT_VALID_LINK: | 777 | case USB_STAT_NOT_VALID_LINK: |
764 | dev_err(di->dev, "USB Type invalid - try charging anyway\n"); | 778 | dev_err(di->dev, "USB Type invalid - try charging anyway\n"); |
765 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 779 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
766 | break; | 780 | break; |
767 | 781 | ||
768 | default: | 782 | default: |
769 | dev_err(di->dev, "USB Type - Unknown\n"); | 783 | dev_err(di->dev, "USB Type - Unknown\n"); |
770 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; | 784 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; |
771 | ret = -ENXIO; | 785 | ret = -ENXIO; |
772 | break; | 786 | break; |
773 | }; | 787 | }; |
774 | 788 | ||
789 | di->max_usb_in_curr.set_max = di->max_usb_in_curr.usb_type_max; | ||
775 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", | 790 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", |
776 | link_status, di->max_usb_in_curr); | 791 | link_status, di->max_usb_in_curr.set_max); |
777 | 792 | ||
778 | return ret; | 793 | return ret; |
779 | } | 794 | } |
@@ -796,21 +811,22 @@ static int ab8500_charger_read_usb_type(struct ab8500_charger *di) | |||
796 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); | 811 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); |
797 | return ret; | 812 | return ret; |
798 | } | 813 | } |
799 | if (is_ab8500(di->parent)) { | 814 | if (is_ab8500(di->parent)) |
800 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, | 815 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, |
801 | AB8500_USB_LINE_STAT_REG, &val); | 816 | AB8500_USB_LINE_STAT_REG, &val); |
802 | } else { | 817 | else |
803 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) | 818 | ret = abx500_get_register_interruptible(di->dev, |
804 | ret = abx500_get_register_interruptible(di->dev, | 819 | AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); |
805 | AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); | ||
806 | } | ||
807 | if (ret < 0) { | 820 | if (ret < 0) { |
808 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); | 821 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); |
809 | return ret; | 822 | return ret; |
810 | } | 823 | } |
811 | 824 | ||
812 | /* get the USB type */ | 825 | /* get the USB type */ |
813 | val = (val & AB8500_USB_LINK_STATUS) >> 3; | 826 | if (is_ab8500(di->parent)) |
827 | val = (val & AB8500_USB_LINK_STATUS) >> USB_LINK_STATUS_SHIFT; | ||
828 | else | ||
829 | val = (val & AB8505_USB_LINK_STATUS) >> USB_LINK_STATUS_SHIFT; | ||
814 | ret = ab8500_charger_max_usb_curr(di, | 830 | ret = ab8500_charger_max_usb_curr(di, |
815 | (enum ab8500_charger_link_status) val); | 831 | (enum ab8500_charger_link_status) val); |
816 | 832 | ||
@@ -865,7 +881,12 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) | |||
865 | */ | 881 | */ |
866 | 882 | ||
867 | /* get the USB type */ | 883 | /* get the USB type */ |
868 | val = (val & AB8500_USB_LINK_STATUS) >> 3; | 884 | if (is_ab8500(di->parent)) |
885 | val = (val & AB8500_USB_LINK_STATUS) >> | ||
886 | USB_LINK_STATUS_SHIFT; | ||
887 | else | ||
888 | val = (val & AB8505_USB_LINK_STATUS) >> | ||
889 | USB_LINK_STATUS_SHIFT; | ||
869 | if (val) | 890 | if (val) |
870 | break; | 891 | break; |
871 | } | 892 | } |
@@ -960,51 +981,6 @@ static int ab8500_charger_voltage_map[] = { | |||
960 | 4600 , | 981 | 4600 , |
961 | }; | 982 | }; |
962 | 983 | ||
963 | /* | ||
964 | * This array maps the raw hex value to charger current used by the AB8500 | ||
965 | * Values taken from the UM0836 | ||
966 | */ | ||
967 | static int ab8500_charger_current_map[] = { | ||
968 | 100 , | ||
969 | 200 , | ||
970 | 300 , | ||
971 | 400 , | ||
972 | 500 , | ||
973 | 600 , | ||
974 | 700 , | ||
975 | 800 , | ||
976 | 900 , | ||
977 | 1000 , | ||
978 | 1100 , | ||
979 | 1200 , | ||
980 | 1300 , | ||
981 | 1400 , | ||
982 | 1500 , | ||
983 | }; | ||
984 | |||
985 | /* | ||
986 | * This array maps the raw hex value to VBUS input current used by the AB8500 | ||
987 | * Values taken from the UM0836 | ||
988 | */ | ||
989 | static int ab8500_charger_vbus_in_curr_map[] = { | ||
990 | USB_CH_IP_CUR_LVL_0P05, | ||
991 | USB_CH_IP_CUR_LVL_0P09, | ||
992 | USB_CH_IP_CUR_LVL_0P19, | ||
993 | USB_CH_IP_CUR_LVL_0P29, | ||
994 | USB_CH_IP_CUR_LVL_0P38, | ||
995 | USB_CH_IP_CUR_LVL_0P45, | ||
996 | USB_CH_IP_CUR_LVL_0P5, | ||
997 | USB_CH_IP_CUR_LVL_0P6, | ||
998 | USB_CH_IP_CUR_LVL_0P7, | ||
999 | USB_CH_IP_CUR_LVL_0P8, | ||
1000 | USB_CH_IP_CUR_LVL_0P9, | ||
1001 | USB_CH_IP_CUR_LVL_1P0, | ||
1002 | USB_CH_IP_CUR_LVL_1P1, | ||
1003 | USB_CH_IP_CUR_LVL_1P3, | ||
1004 | USB_CH_IP_CUR_LVL_1P4, | ||
1005 | USB_CH_IP_CUR_LVL_1P5, | ||
1006 | }; | ||
1007 | |||
1008 | static int ab8500_voltage_to_regval(int voltage) | 984 | static int ab8500_voltage_to_regval(int voltage) |
1009 | { | 985 | { |
1010 | int i; | 986 | int i; |
@@ -1026,41 +1002,41 @@ static int ab8500_voltage_to_regval(int voltage) | |||
1026 | return -1; | 1002 | return -1; |
1027 | } | 1003 | } |
1028 | 1004 | ||
1029 | static int ab8500_current_to_regval(int curr) | 1005 | static int ab8500_current_to_regval(struct ab8500_charger *di, int curr) |
1030 | { | 1006 | { |
1031 | int i; | 1007 | int i; |
1032 | 1008 | ||
1033 | if (curr < ab8500_charger_current_map[0]) | 1009 | if (curr < di->bm->chg_output_curr[0]) |
1034 | return 0; | 1010 | return 0; |
1035 | 1011 | ||
1036 | for (i = 0; i < ARRAY_SIZE(ab8500_charger_current_map); i++) { | 1012 | for (i = 0; i < di->bm->n_chg_out_curr; i++) { |
1037 | if (curr < ab8500_charger_current_map[i]) | 1013 | if (curr < di->bm->chg_output_curr[i]) |
1038 | return i - 1; | 1014 | return i - 1; |
1039 | } | 1015 | } |
1040 | 1016 | ||
1041 | /* If not last element, return error */ | 1017 | /* If not last element, return error */ |
1042 | i = ARRAY_SIZE(ab8500_charger_current_map) - 1; | 1018 | i = di->bm->n_chg_out_curr - 1; |
1043 | if (curr == ab8500_charger_current_map[i]) | 1019 | if (curr == di->bm->chg_output_curr[i]) |
1044 | return i; | 1020 | return i; |
1045 | else | 1021 | else |
1046 | return -1; | 1022 | return -1; |
1047 | } | 1023 | } |
1048 | 1024 | ||
1049 | static int ab8500_vbus_in_curr_to_regval(int curr) | 1025 | static int ab8500_vbus_in_curr_to_regval(struct ab8500_charger *di, int curr) |
1050 | { | 1026 | { |
1051 | int i; | 1027 | int i; |
1052 | 1028 | ||
1053 | if (curr < ab8500_charger_vbus_in_curr_map[0]) | 1029 | if (curr < di->bm->chg_input_curr[0]) |
1054 | return 0; | 1030 | return 0; |
1055 | 1031 | ||
1056 | for (i = 0; i < ARRAY_SIZE(ab8500_charger_vbus_in_curr_map); i++) { | 1032 | for (i = 0; i < di->bm->n_chg_in_curr; i++) { |
1057 | if (curr < ab8500_charger_vbus_in_curr_map[i]) | 1033 | if (curr < di->bm->chg_input_curr[i]) |
1058 | return i - 1; | 1034 | return i - 1; |
1059 | } | 1035 | } |
1060 | 1036 | ||
1061 | /* If not last element, return error */ | 1037 | /* If not last element, return error */ |
1062 | i = ARRAY_SIZE(ab8500_charger_vbus_in_curr_map) - 1; | 1038 | i = di->bm->n_chg_in_curr - 1; |
1063 | if (curr == ab8500_charger_vbus_in_curr_map[i]) | 1039 | if (curr == di->bm->chg_input_curr[i]) |
1064 | return i; | 1040 | return i; |
1065 | else | 1041 | else |
1066 | return -1; | 1042 | return -1; |
@@ -1077,28 +1053,48 @@ static int ab8500_vbus_in_curr_to_regval(int curr) | |||
1077 | */ | 1053 | */ |
1078 | static int ab8500_charger_get_usb_cur(struct ab8500_charger *di) | 1054 | static int ab8500_charger_get_usb_cur(struct ab8500_charger *di) |
1079 | { | 1055 | { |
1056 | int ret = 0; | ||
1080 | switch (di->usb_state.usb_current) { | 1057 | switch (di->usb_state.usb_current) { |
1081 | case 100: | 1058 | case 100: |
1082 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P09; | 1059 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P09; |
1083 | break; | 1060 | break; |
1084 | case 200: | 1061 | case 200: |
1085 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P19; | 1062 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P19; |
1086 | break; | 1063 | break; |
1087 | case 300: | 1064 | case 300: |
1088 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P29; | 1065 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P29; |
1089 | break; | 1066 | break; |
1090 | case 400: | 1067 | case 400: |
1091 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P38; | 1068 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P38; |
1092 | break; | 1069 | break; |
1093 | case 500: | 1070 | case 500: |
1094 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 1071 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
1095 | break; | 1072 | break; |
1096 | default: | 1073 | default: |
1097 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; | 1074 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; |
1098 | return -1; | 1075 | ret = -EPERM; |
1099 | break; | 1076 | break; |
1100 | }; | 1077 | }; |
1101 | return 0; | 1078 | di->max_usb_in_curr.set_max = di->max_usb_in_curr.usb_type_max; |
1079 | return ret; | ||
1080 | } | ||
1081 | |||
1082 | /** | ||
1083 | * ab8500_charger_check_continue_stepping() - Check to allow stepping | ||
1084 | * @di: pointer to the ab8500_charger structure | ||
1085 | * @reg: select what charger register to check | ||
1086 | * | ||
1087 | * Check if current stepping should be allowed to continue. | ||
1088 | * Checks if charger source has not collapsed. If it has, further stepping | ||
1089 | * is not allowed. | ||
1090 | */ | ||
1091 | static bool ab8500_charger_check_continue_stepping(struct ab8500_charger *di, | ||
1092 | int reg) | ||
1093 | { | ||
1094 | if (reg == AB8500_USBCH_IPT_CRNTLVL_REG) | ||
1095 | return !di->flags.vbus_drop_end; | ||
1096 | else | ||
1097 | return true; | ||
1102 | } | 1098 | } |
1103 | 1099 | ||
1104 | /** | 1100 | /** |
@@ -1118,7 +1114,7 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, | |||
1118 | int ich, int reg) | 1114 | int ich, int reg) |
1119 | { | 1115 | { |
1120 | int ret = 0; | 1116 | int ret = 0; |
1121 | int auto_curr_index, curr_index, prev_curr_index, shift_value, i; | 1117 | int curr_index, prev_curr_index, shift_value, i; |
1122 | u8 reg_value; | 1118 | u8 reg_value; |
1123 | u32 step_udelay; | 1119 | u32 step_udelay; |
1124 | bool no_stepping = false; | 1120 | bool no_stepping = false; |
@@ -1136,39 +1132,27 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, | |||
1136 | case AB8500_MCH_IPT_CURLVL_REG: | 1132 | case AB8500_MCH_IPT_CURLVL_REG: |
1137 | shift_value = MAIN_CH_INPUT_CURR_SHIFT; | 1133 | shift_value = MAIN_CH_INPUT_CURR_SHIFT; |
1138 | prev_curr_index = (reg_value >> shift_value); | 1134 | prev_curr_index = (reg_value >> shift_value); |
1139 | curr_index = ab8500_current_to_regval(ich); | 1135 | curr_index = ab8500_current_to_regval(di, ich); |
1140 | step_udelay = STEP_UDELAY; | 1136 | step_udelay = STEP_UDELAY; |
1141 | if (!di->ac.charger_connected) | 1137 | if (!di->ac.charger_connected) |
1142 | no_stepping = true; | 1138 | no_stepping = true; |
1143 | break; | 1139 | break; |
1144 | case AB8500_USBCH_IPT_CRNTLVL_REG: | 1140 | case AB8500_USBCH_IPT_CRNTLVL_REG: |
1145 | shift_value = VBUS_IN_CURR_LIM_SHIFT; | 1141 | if (is_ab8540(di->parent)) |
1142 | shift_value = AB8540_VBUS_IN_CURR_LIM_SHIFT; | ||
1143 | else | ||
1144 | shift_value = VBUS_IN_CURR_LIM_SHIFT; | ||
1146 | prev_curr_index = (reg_value >> shift_value); | 1145 | prev_curr_index = (reg_value >> shift_value); |
1147 | curr_index = ab8500_vbus_in_curr_to_regval(ich); | 1146 | curr_index = ab8500_vbus_in_curr_to_regval(di, ich); |
1148 | step_udelay = STEP_UDELAY * 100; | 1147 | step_udelay = STEP_UDELAY * 100; |
1149 | 1148 | ||
1150 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
1151 | AB8500_CH_USBCH_STAT2_REG, ®_value); | ||
1152 | if (ret < 0) { | ||
1153 | dev_err(di->dev, "%s read failed\n", __func__); | ||
1154 | goto exit_set_current; | ||
1155 | } | ||
1156 | auto_curr_index = | ||
1157 | reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT; | ||
1158 | |||
1159 | dev_dbg(di->dev, "%s Auto VBUS curr is %d mA\n", | ||
1160 | __func__, | ||
1161 | ab8500_charger_vbus_in_curr_map[auto_curr_index]); | ||
1162 | |||
1163 | prev_curr_index = min(prev_curr_index, auto_curr_index); | ||
1164 | |||
1165 | if (!di->usb.charger_connected) | 1149 | if (!di->usb.charger_connected) |
1166 | no_stepping = true; | 1150 | no_stepping = true; |
1167 | break; | 1151 | break; |
1168 | case AB8500_CH_OPT_CRNTLVL_REG: | 1152 | case AB8500_CH_OPT_CRNTLVL_REG: |
1169 | shift_value = 0; | 1153 | shift_value = 0; |
1170 | prev_curr_index = (reg_value >> shift_value); | 1154 | prev_curr_index = (reg_value >> shift_value); |
1171 | curr_index = ab8500_current_to_regval(ich); | 1155 | curr_index = ab8500_current_to_regval(di, ich); |
1172 | step_udelay = STEP_UDELAY; | 1156 | step_udelay = STEP_UDELAY; |
1173 | if (curr_index && (curr_index - prev_curr_index) > 1) | 1157 | if (curr_index && (curr_index - prev_curr_index) > 1) |
1174 | step_udelay *= 100; | 1158 | step_udelay *= 100; |
@@ -1219,7 +1203,8 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, | |||
1219 | usleep_range(step_udelay, step_udelay * 2); | 1203 | usleep_range(step_udelay, step_udelay * 2); |
1220 | } | 1204 | } |
1221 | } else { | 1205 | } else { |
1222 | for (i = prev_curr_index + 1; i <= curr_index; i++) { | 1206 | bool allow = true; |
1207 | for (i = prev_curr_index + 1; i <= curr_index && allow; i++) { | ||
1223 | dev_dbg(di->dev, "curr change_2 to: %x for 0x%02x\n", | 1208 | dev_dbg(di->dev, "curr change_2 to: %x for 0x%02x\n", |
1224 | (u8)i << shift_value, reg); | 1209 | (u8)i << shift_value, reg); |
1225 | ret = abx500_set_register_interruptible(di->dev, | 1210 | ret = abx500_set_register_interruptible(di->dev, |
@@ -1230,6 +1215,8 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, | |||
1230 | } | 1215 | } |
1231 | if (i != curr_index) | 1216 | if (i != curr_index) |
1232 | usleep_range(step_udelay, step_udelay * 2); | 1217 | usleep_range(step_udelay, step_udelay * 2); |
1218 | |||
1219 | allow = ab8500_charger_check_continue_stepping(di, reg); | ||
1233 | } | 1220 | } |
1234 | } | 1221 | } |
1235 | 1222 | ||
@@ -1255,6 +1242,11 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di, | |||
1255 | 1242 | ||
1256 | /* We should always use to lowest current limit */ | 1243 | /* We should always use to lowest current limit */ |
1257 | min_value = min(di->bm->chg_params->usb_curr_max, ich_in); | 1244 | min_value = min(di->bm->chg_params->usb_curr_max, ich_in); |
1245 | if (di->max_usb_in_curr.set_max > 0) | ||
1246 | min_value = min(di->max_usb_in_curr.set_max, min_value); | ||
1247 | |||
1248 | if (di->usb_state.usb_current >= 0) | ||
1249 | min_value = min(di->usb_state.usb_current, min_value); | ||
1258 | 1250 | ||
1259 | switch (min_value) { | 1251 | switch (min_value) { |
1260 | case 100: | 1252 | case 100: |
@@ -1400,8 +1392,8 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, | |||
1400 | 1392 | ||
1401 | /* Check if the requested voltage or current is valid */ | 1393 | /* Check if the requested voltage or current is valid */ |
1402 | volt_index = ab8500_voltage_to_regval(vset); | 1394 | volt_index = ab8500_voltage_to_regval(vset); |
1403 | curr_index = ab8500_current_to_regval(iset); | 1395 | curr_index = ab8500_current_to_regval(di, iset); |
1404 | input_curr_index = ab8500_current_to_regval( | 1396 | input_curr_index = ab8500_current_to_regval(di, |
1405 | di->bm->chg_params->ac_curr_max); | 1397 | di->bm->chg_params->ac_curr_max); |
1406 | if (volt_index < 0 || curr_index < 0 || input_curr_index < 0) { | 1398 | if (volt_index < 0 || curr_index < 0 || input_curr_index < 0) { |
1407 | dev_err(di->dev, | 1399 | dev_err(di->dev, |
@@ -1572,7 +1564,7 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, | |||
1572 | 1564 | ||
1573 | /* Check if the requested voltage or current is valid */ | 1565 | /* Check if the requested voltage or current is valid */ |
1574 | volt_index = ab8500_voltage_to_regval(vset); | 1566 | volt_index = ab8500_voltage_to_regval(vset); |
1575 | curr_index = ab8500_current_to_regval(ich_out); | 1567 | curr_index = ab8500_current_to_regval(di, ich_out); |
1576 | if (volt_index < 0 || curr_index < 0) { | 1568 | if (volt_index < 0 || curr_index < 0) { |
1577 | dev_err(di->dev, | 1569 | dev_err(di->dev, |
1578 | "Charger voltage or current too high, " | 1570 | "Charger voltage or current too high, " |
@@ -1609,7 +1601,8 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, | |||
1609 | di->usb.charger_online = 1; | 1601 | di->usb.charger_online = 1; |
1610 | 1602 | ||
1611 | /* USBChInputCurr: current that can be drawn from the usb */ | 1603 | /* USBChInputCurr: current that can be drawn from the usb */ |
1612 | ret = ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | 1604 | ret = ab8500_charger_set_vbus_in_curr(di, |
1605 | di->max_usb_in_curr.usb_type_max); | ||
1613 | if (ret) { | 1606 | if (ret) { |
1614 | dev_err(di->dev, "setting USBChInputCurr failed\n"); | 1607 | dev_err(di->dev, "setting USBChInputCurr failed\n"); |
1615 | return ret; | 1608 | return ret; |
@@ -1668,8 +1661,7 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, | |||
1668 | dev_dbg(di->dev, "%s Disabled USB charging\n", __func__); | 1661 | dev_dbg(di->dev, "%s Disabled USB charging\n", __func__); |
1669 | 1662 | ||
1670 | /* Cancel any pending Vbat check work */ | 1663 | /* Cancel any pending Vbat check work */ |
1671 | if (delayed_work_pending(&di->check_vbat_work)) | 1664 | cancel_delayed_work(&di->check_vbat_work); |
1672 | cancel_delayed_work(&di->check_vbat_work); | ||
1673 | 1665 | ||
1674 | } | 1666 | } |
1675 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 1667 | ab8500_power_supply_changed(di, &di->usb_chg.psy); |
@@ -1677,6 +1669,128 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, | |||
1677 | return ret; | 1669 | return ret; |
1678 | } | 1670 | } |
1679 | 1671 | ||
1672 | static int ab8500_external_charger_prepare(struct notifier_block *charger_nb, | ||
1673 | unsigned long event, void *data) | ||
1674 | { | ||
1675 | int ret; | ||
1676 | struct device *dev = data; | ||
1677 | /*Toggle External charger control pin*/ | ||
1678 | ret = abx500_set_register_interruptible(dev, AB8500_SYS_CTRL1_BLOCK, | ||
1679 | AB8500_SYS_CHARGER_CONTROL_REG, | ||
1680 | EXTERNAL_CHARGER_DISABLE_REG_VAL); | ||
1681 | if (ret < 0) { | ||
1682 | dev_err(dev, "write reg failed %d\n", ret); | ||
1683 | goto out; | ||
1684 | } | ||
1685 | ret = abx500_set_register_interruptible(dev, AB8500_SYS_CTRL1_BLOCK, | ||
1686 | AB8500_SYS_CHARGER_CONTROL_REG, | ||
1687 | EXTERNAL_CHARGER_ENABLE_REG_VAL); | ||
1688 | if (ret < 0) | ||
1689 | dev_err(dev, "Write reg failed %d\n", ret); | ||
1690 | |||
1691 | out: | ||
1692 | return ret; | ||
1693 | } | ||
1694 | |||
1695 | /** | ||
1696 | * ab8500_charger_usb_check_enable() - enable usb charging | ||
1697 | * @charger: pointer to the ux500_charger structure | ||
1698 | * @vset: charging voltage | ||
1699 | * @iset: charger output current | ||
1700 | * | ||
1701 | * Check if the VBUS charger has been disconnected and reconnected without | ||
1702 | * AB8500 rising an interrupt. Returns 0 on success. | ||
1703 | */ | ||
1704 | static int ab8500_charger_usb_check_enable(struct ux500_charger *charger, | ||
1705 | int vset, int iset) | ||
1706 | { | ||
1707 | u8 usbch_ctrl1 = 0; | ||
1708 | int ret = 0; | ||
1709 | |||
1710 | struct ab8500_charger *di = to_ab8500_charger_usb_device_info(charger); | ||
1711 | |||
1712 | if (!di->usb.charger_connected) | ||
1713 | return ret; | ||
1714 | |||
1715 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
1716 | AB8500_USBCH_CTRL1_REG, &usbch_ctrl1); | ||
1717 | if (ret < 0) { | ||
1718 | dev_err(di->dev, "ab8500 read failed %d\n", __LINE__); | ||
1719 | return ret; | ||
1720 | } | ||
1721 | dev_dbg(di->dev, "USB charger ctrl: 0x%02x\n", usbch_ctrl1); | ||
1722 | |||
1723 | if (!(usbch_ctrl1 & USB_CH_ENA)) { | ||
1724 | dev_info(di->dev, "Charging has been disabled abnormally and will be re-enabled\n"); | ||
1725 | |||
1726 | ret = abx500_mask_and_set_register_interruptible(di->dev, | ||
1727 | AB8500_CHARGER, AB8500_CHARGER_CTRL, | ||
1728 | DROP_COUNT_RESET, DROP_COUNT_RESET); | ||
1729 | if (ret < 0) { | ||
1730 | dev_err(di->dev, "ab8500 write failed %d\n", __LINE__); | ||
1731 | return ret; | ||
1732 | } | ||
1733 | |||
1734 | ret = ab8500_charger_usb_en(&di->usb_chg, true, vset, iset); | ||
1735 | if (ret < 0) { | ||
1736 | dev_err(di->dev, "Failed to enable VBUS charger %d\n", | ||
1737 | __LINE__); | ||
1738 | return ret; | ||
1739 | } | ||
1740 | } | ||
1741 | return ret; | ||
1742 | } | ||
1743 | |||
1744 | /** | ||
1745 | * ab8500_charger_ac_check_enable() - enable usb charging | ||
1746 | * @charger: pointer to the ux500_charger structure | ||
1747 | * @vset: charging voltage | ||
1748 | * @iset: charger output current | ||
1749 | * | ||
1750 | * Check if the AC charger has been disconnected and reconnected without | ||
1751 | * AB8500 rising an interrupt. Returns 0 on success. | ||
1752 | */ | ||
1753 | static int ab8500_charger_ac_check_enable(struct ux500_charger *charger, | ||
1754 | int vset, int iset) | ||
1755 | { | ||
1756 | u8 mainch_ctrl1 = 0; | ||
1757 | int ret = 0; | ||
1758 | |||
1759 | struct ab8500_charger *di = to_ab8500_charger_ac_device_info(charger); | ||
1760 | |||
1761 | if (!di->ac.charger_connected) | ||
1762 | return ret; | ||
1763 | |||
1764 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
1765 | AB8500_MCH_CTRL1, &mainch_ctrl1); | ||
1766 | if (ret < 0) { | ||
1767 | dev_err(di->dev, "ab8500 read failed %d\n", __LINE__); | ||
1768 | return ret; | ||
1769 | } | ||
1770 | dev_dbg(di->dev, "AC charger ctrl: 0x%02x\n", mainch_ctrl1); | ||
1771 | |||
1772 | if (!(mainch_ctrl1 & MAIN_CH_ENA)) { | ||
1773 | dev_info(di->dev, "Charging has been disabled abnormally and will be re-enabled\n"); | ||
1774 | |||
1775 | ret = abx500_mask_and_set_register_interruptible(di->dev, | ||
1776 | AB8500_CHARGER, AB8500_CHARGER_CTRL, | ||
1777 | DROP_COUNT_RESET, DROP_COUNT_RESET); | ||
1778 | |||
1779 | if (ret < 0) { | ||
1780 | dev_err(di->dev, "ab8500 write failed %d\n", __LINE__); | ||
1781 | return ret; | ||
1782 | } | ||
1783 | |||
1784 | ret = ab8500_charger_ac_en(&di->usb_chg, true, vset, iset); | ||
1785 | if (ret < 0) { | ||
1786 | dev_err(di->dev, "failed to enable AC charger %d\n", | ||
1787 | __LINE__); | ||
1788 | return ret; | ||
1789 | } | ||
1790 | } | ||
1791 | return ret; | ||
1792 | } | ||
1793 | |||
1680 | /** | 1794 | /** |
1681 | * ab8500_charger_watchdog_kick() - kick charger watchdog | 1795 | * ab8500_charger_watchdog_kick() - kick charger watchdog |
1682 | * @di: pointer to the ab8500_charger structure | 1796 | * @di: pointer to the ab8500_charger structure |
@@ -1734,8 +1848,68 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger, | |||
1734 | 1848 | ||
1735 | /* Reset the main and usb drop input current measurement counter */ | 1849 | /* Reset the main and usb drop input current measurement counter */ |
1736 | ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, | 1850 | ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, |
1737 | AB8500_CHARGER_CTRL, | 1851 | AB8500_CHARGER_CTRL, DROP_COUNT_RESET); |
1738 | 0x1); | 1852 | if (ret) { |
1853 | dev_err(di->dev, "%s write failed\n", __func__); | ||
1854 | return ret; | ||
1855 | } | ||
1856 | |||
1857 | return ret; | ||
1858 | } | ||
1859 | |||
1860 | /** | ||
1861 | * ab8540_charger_power_path_enable() - enable usb power path mode | ||
1862 | * @charger: pointer to the ux500_charger structure | ||
1863 | * @enable: enable/disable flag | ||
1864 | * | ||
1865 | * Enable or disable the power path for usb mode | ||
1866 | * Returns error code in case of failure else 0(on success) | ||
1867 | */ | ||
1868 | static int ab8540_charger_power_path_enable(struct ux500_charger *charger, | ||
1869 | bool enable) | ||
1870 | { | ||
1871 | int ret; | ||
1872 | struct ab8500_charger *di; | ||
1873 | |||
1874 | if (charger->psy.type == POWER_SUPPLY_TYPE_USB) | ||
1875 | di = to_ab8500_charger_usb_device_info(charger); | ||
1876 | else | ||
1877 | return -ENXIO; | ||
1878 | |||
1879 | ret = abx500_mask_and_set_register_interruptible(di->dev, | ||
1880 | AB8500_CHARGER, AB8540_USB_PP_MODE_REG, | ||
1881 | BUS_POWER_PATH_MODE_ENA, enable); | ||
1882 | if (ret) { | ||
1883 | dev_err(di->dev, "%s write failed\n", __func__); | ||
1884 | return ret; | ||
1885 | } | ||
1886 | |||
1887 | return ret; | ||
1888 | } | ||
1889 | |||
1890 | |||
1891 | /** | ||
1892 | * ab8540_charger_usb_pre_chg_enable() - enable usb pre change | ||
1893 | * @charger: pointer to the ux500_charger structure | ||
1894 | * @enable: enable/disable flag | ||
1895 | * | ||
1896 | * Enable or disable the pre-chage for usb mode | ||
1897 | * Returns error code in case of failure else 0(on success) | ||
1898 | */ | ||
1899 | static int ab8540_charger_usb_pre_chg_enable(struct ux500_charger *charger, | ||
1900 | bool enable) | ||
1901 | { | ||
1902 | int ret; | ||
1903 | struct ab8500_charger *di; | ||
1904 | |||
1905 | if (charger->psy.type == POWER_SUPPLY_TYPE_USB) | ||
1906 | di = to_ab8500_charger_usb_device_info(charger); | ||
1907 | else | ||
1908 | return -ENXIO; | ||
1909 | |||
1910 | ret = abx500_mask_and_set_register_interruptible(di->dev, | ||
1911 | AB8500_CHARGER, AB8540_USB_PP_CHR_REG, | ||
1912 | BUS_POWER_PATH_PRECHG_ENA, enable); | ||
1739 | if (ret) { | 1913 | if (ret) { |
1740 | dev_err(di->dev, "%s write failed\n", __func__); | 1914 | dev_err(di->dev, "%s write failed\n", __func__); |
1741 | return ret; | 1915 | return ret; |
@@ -1823,9 +1997,10 @@ static void ab8500_charger_check_vbat_work(struct work_struct *work) | |||
1823 | di->vbat > VBAT_TRESH_IP_CUR_RED))) { | 1997 | di->vbat > VBAT_TRESH_IP_CUR_RED))) { |
1824 | 1998 | ||
1825 | dev_dbg(di->dev, "Vbat did cross threshold, curr: %d, new: %d," | 1999 | dev_dbg(di->dev, "Vbat did cross threshold, curr: %d, new: %d," |
1826 | " old: %d\n", di->max_usb_in_curr, di->vbat, | 2000 | " old: %d\n", di->max_usb_in_curr.usb_type_max, |
1827 | di->old_vbat); | 2001 | di->vbat, di->old_vbat); |
1828 | ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | 2002 | ab8500_charger_set_vbus_in_curr(di, |
2003 | di->max_usb_in_curr.usb_type_max); | ||
1829 | power_supply_changed(&di->usb_chg.psy); | 2004 | power_supply_changed(&di->usb_chg.psy); |
1830 | } | 2005 | } |
1831 | 2006 | ||
@@ -2105,7 +2280,8 @@ static void ab8500_charger_usb_link_attach_work(struct work_struct *work) | |||
2105 | 2280 | ||
2106 | /* Update maximum input current if USB enumeration is not detected */ | 2281 | /* Update maximum input current if USB enumeration is not detected */ |
2107 | if (!di->usb.charger_online) { | 2282 | if (!di->usb.charger_online) { |
2108 | ret = ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | 2283 | ret = ab8500_charger_set_vbus_in_curr(di, |
2284 | di->max_usb_in_curr.usb_type_max); | ||
2109 | if (ret) | 2285 | if (ret) |
2110 | return; | 2286 | return; |
2111 | } | 2287 | } |
@@ -2125,6 +2301,7 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) | |||
2125 | int detected_chargers; | 2301 | int detected_chargers; |
2126 | int ret; | 2302 | int ret; |
2127 | u8 val; | 2303 | u8 val; |
2304 | u8 link_status; | ||
2128 | 2305 | ||
2129 | struct ab8500_charger *di = container_of(work, | 2306 | struct ab8500_charger *di = container_of(work, |
2130 | struct ab8500_charger, usb_link_status_work); | 2307 | struct ab8500_charger, usb_link_status_work); |
@@ -2144,38 +2321,61 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) | |||
2144 | * to start the charging process. but by jumping | 2321 | * to start the charging process. but by jumping |
2145 | * thru a few hoops it can be forced to start. | 2322 | * thru a few hoops it can be forced to start. |
2146 | */ | 2323 | */ |
2147 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, | 2324 | if (is_ab8500(di->parent)) |
2148 | AB8500_USB_LINE_STAT_REG, &val); | 2325 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, |
2326 | AB8500_USB_LINE_STAT_REG, &val); | ||
2327 | else | ||
2328 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, | ||
2329 | AB8500_USB_LINK1_STAT_REG, &val); | ||
2330 | |||
2149 | if (ret >= 0) | 2331 | if (ret >= 0) |
2150 | dev_dbg(di->dev, "UsbLineStatus register = 0x%02x\n", val); | 2332 | dev_dbg(di->dev, "UsbLineStatus register = 0x%02x\n", val); |
2151 | else | 2333 | else |
2152 | dev_dbg(di->dev, "Error reading USB link status\n"); | 2334 | dev_dbg(di->dev, "Error reading USB link status\n"); |
2153 | 2335 | ||
2336 | if (is_ab8500(di->parent)) | ||
2337 | link_status = AB8500_USB_LINK_STATUS; | ||
2338 | else | ||
2339 | link_status = AB8505_USB_LINK_STATUS; | ||
2340 | |||
2154 | if (detected_chargers & USB_PW_CONN) { | 2341 | if (detected_chargers & USB_PW_CONN) { |
2155 | if (((val & AB8500_USB_LINK_STATUS) >> 3) == USB_STAT_NOT_VALID_LINK && | 2342 | if (((val & link_status) >> USB_LINK_STATUS_SHIFT) == |
2343 | USB_STAT_NOT_VALID_LINK && | ||
2156 | di->invalid_charger_detect_state == 0) { | 2344 | di->invalid_charger_detect_state == 0) { |
2157 | dev_dbg(di->dev, "Invalid charger detected, state= 0\n"); | 2345 | dev_dbg(di->dev, |
2346 | "Invalid charger detected, state= 0\n"); | ||
2158 | /*Enable charger*/ | 2347 | /*Enable charger*/ |
2159 | abx500_mask_and_set_register_interruptible(di->dev, | 2348 | abx500_mask_and_set_register_interruptible(di->dev, |
2160 | AB8500_CHARGER, AB8500_USBCH_CTRL1_REG, 0x01, 0x01); | 2349 | AB8500_CHARGER, AB8500_USBCH_CTRL1_REG, |
2350 | USB_CH_ENA, USB_CH_ENA); | ||
2161 | /*Enable charger detection*/ | 2351 | /*Enable charger detection*/ |
2162 | abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, | 2352 | abx500_mask_and_set_register_interruptible(di->dev, |
2163 | AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x01); | 2353 | AB8500_USB, AB8500_USB_LINE_CTRL2_REG, |
2354 | USB_CH_DET, USB_CH_DET); | ||
2164 | di->invalid_charger_detect_state = 1; | 2355 | di->invalid_charger_detect_state = 1; |
2165 | /*exit and wait for new link status interrupt.*/ | 2356 | /*exit and wait for new link status interrupt.*/ |
2166 | return; | 2357 | return; |
2167 | 2358 | ||
2168 | } | 2359 | } |
2169 | if (di->invalid_charger_detect_state == 1) { | 2360 | if (di->invalid_charger_detect_state == 1) { |
2170 | dev_dbg(di->dev, "Invalid charger detected, state= 1\n"); | 2361 | dev_dbg(di->dev, |
2362 | "Invalid charger detected, state= 1\n"); | ||
2171 | /*Stop charger detection*/ | 2363 | /*Stop charger detection*/ |
2172 | abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, | 2364 | abx500_mask_and_set_register_interruptible(di->dev, |
2173 | AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x00); | 2365 | AB8500_USB, AB8500_USB_LINE_CTRL2_REG, |
2366 | USB_CH_DET, 0x00); | ||
2174 | /*Check link status*/ | 2367 | /*Check link status*/ |
2175 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, | 2368 | if (is_ab8500(di->parent)) |
2176 | AB8500_USB_LINE_STAT_REG, &val); | 2369 | ret = abx500_get_register_interruptible(di->dev, |
2370 | AB8500_USB, AB8500_USB_LINE_STAT_REG, | ||
2371 | &val); | ||
2372 | else | ||
2373 | ret = abx500_get_register_interruptible(di->dev, | ||
2374 | AB8500_USB, AB8500_USB_LINK1_STAT_REG, | ||
2375 | &val); | ||
2376 | |||
2177 | dev_dbg(di->dev, "USB link status= 0x%02x\n", | 2377 | dev_dbg(di->dev, "USB link status= 0x%02x\n", |
2178 | (val & AB8500_USB_LINK_STATUS) >> 3); | 2378 | (val & link_status) >> USB_LINK_STATUS_SHIFT); |
2179 | di->invalid_charger_detect_state = 2; | 2379 | di->invalid_charger_detect_state = 2; |
2180 | } | 2380 | } |
2181 | } else { | 2381 | } else { |
@@ -2273,7 +2473,7 @@ static void ab8500_charger_usb_state_changed_work(struct work_struct *work) | |||
2273 | if (!ab8500_charger_get_usb_cur(di)) { | 2473 | if (!ab8500_charger_get_usb_cur(di)) { |
2274 | /* Update maximum input current */ | 2474 | /* Update maximum input current */ |
2275 | ret = ab8500_charger_set_vbus_in_curr(di, | 2475 | ret = ab8500_charger_set_vbus_in_curr(di, |
2276 | di->max_usb_in_curr); | 2476 | di->max_usb_in_curr.usb_type_max); |
2277 | if (ret) | 2477 | if (ret) |
2278 | return; | 2478 | return; |
2279 | 2479 | ||
@@ -2422,7 +2622,9 @@ static irqreturn_t ab8500_charger_mainchplugdet_handler(int irq, void *_di) | |||
2422 | 2622 | ||
2423 | mutex_lock(&di->charger_attached_mutex); | 2623 | mutex_lock(&di->charger_attached_mutex); |
2424 | mutex_unlock(&di->charger_attached_mutex); | 2624 | mutex_unlock(&di->charger_attached_mutex); |
2425 | queue_delayed_work(di->charger_wq, | 2625 | |
2626 | if (is_ab8500(di->parent)) | ||
2627 | queue_delayed_work(di->charger_wq, | ||
2426 | &di->ac_charger_attached_work, | 2628 | &di->ac_charger_attached_work, |
2427 | HZ); | 2629 | HZ); |
2428 | return IRQ_HANDLED; | 2630 | return IRQ_HANDLED; |
@@ -2491,6 +2693,8 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) | |||
2491 | { | 2693 | { |
2492 | struct ab8500_charger *di = container_of(work, | 2694 | struct ab8500_charger *di = container_of(work, |
2493 | struct ab8500_charger, vbus_drop_end_work.work); | 2695 | struct ab8500_charger, vbus_drop_end_work.work); |
2696 | int ret, curr; | ||
2697 | u8 reg_value; | ||
2494 | 2698 | ||
2495 | di->flags.vbus_drop_end = false; | 2699 | di->flags.vbus_drop_end = false; |
2496 | 2700 | ||
@@ -2498,8 +2702,45 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) | |||
2498 | abx500_set_register_interruptible(di->dev, | 2702 | abx500_set_register_interruptible(di->dev, |
2499 | AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01); | 2703 | AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01); |
2500 | 2704 | ||
2705 | if (is_ab8540(di->parent)) | ||
2706 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
2707 | AB8540_CH_USBCH_STAT3_REG, ®_value); | ||
2708 | else | ||
2709 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
2710 | AB8500_CH_USBCH_STAT2_REG, ®_value); | ||
2711 | if (ret < 0) { | ||
2712 | dev_err(di->dev, "%s read failed\n", __func__); | ||
2713 | return; | ||
2714 | } | ||
2715 | |||
2716 | if (is_ab8540(di->parent)) | ||
2717 | curr = di->bm->chg_input_curr[ | ||
2718 | reg_value & AB8540_AUTO_VBUS_IN_CURR_MASK]; | ||
2719 | else | ||
2720 | curr = di->bm->chg_input_curr[ | ||
2721 | reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT]; | ||
2722 | |||
2723 | if (di->max_usb_in_curr.calculated_max != curr) { | ||
2724 | /* USB source is collapsing */ | ||
2725 | di->max_usb_in_curr.calculated_max = curr; | ||
2726 | dev_dbg(di->dev, | ||
2727 | "VBUS input current limiting to %d mA\n", | ||
2728 | di->max_usb_in_curr.calculated_max); | ||
2729 | } else { | ||
2730 | /* | ||
2731 | * USB source can not give more than this amount. | ||
2732 | * Taking more will collapse the source. | ||
2733 | */ | ||
2734 | di->max_usb_in_curr.set_max = | ||
2735 | di->max_usb_in_curr.calculated_max; | ||
2736 | dev_dbg(di->dev, | ||
2737 | "VBUS input current limited to %d mA\n", | ||
2738 | di->max_usb_in_curr.set_max); | ||
2739 | } | ||
2740 | |||
2501 | if (di->usb.charger_connected) | 2741 | if (di->usb.charger_connected) |
2502 | ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | 2742 | ab8500_charger_set_vbus_in_curr(di, |
2743 | di->max_usb_in_curr.usb_type_max); | ||
2503 | } | 2744 | } |
2504 | 2745 | ||
2505 | /** | 2746 | /** |
@@ -2654,8 +2895,13 @@ static irqreturn_t ab8500_charger_vbuschdropend_handler(int irq, void *_di) | |||
2654 | 2895 | ||
2655 | dev_dbg(di->dev, "VBUS charger drop ended\n"); | 2896 | dev_dbg(di->dev, "VBUS charger drop ended\n"); |
2656 | di->flags.vbus_drop_end = true; | 2897 | di->flags.vbus_drop_end = true; |
2898 | |||
2899 | /* | ||
2900 | * VBUS might have dropped due to bad connection. | ||
2901 | * Schedule a new input limit set to the value SW requests. | ||
2902 | */ | ||
2657 | queue_delayed_work(di->charger_wq, &di->vbus_drop_end_work, | 2903 | queue_delayed_work(di->charger_wq, &di->vbus_drop_end_work, |
2658 | round_jiffies(30 * HZ)); | 2904 | round_jiffies(VBUS_IN_CURR_LIM_RETRY_SET_TIME * HZ)); |
2659 | 2905 | ||
2660 | return IRQ_HANDLED; | 2906 | return IRQ_HANDLED; |
2661 | } | 2907 | } |
@@ -2836,6 +3082,7 @@ static int ab8500_charger_usb_get_property(struct power_supply *psy, | |||
2836 | static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | 3082 | static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) |
2837 | { | 3083 | { |
2838 | int ret = 0; | 3084 | int ret = 0; |
3085 | u8 bup_vch_range = 0, vbup33_vrtcn = 0; | ||
2839 | 3086 | ||
2840 | /* Setup maximum charger current and voltage for ABB cut2.0 */ | 3087 | /* Setup maximum charger current and voltage for ABB cut2.0 */ |
2841 | if (!is_ab8500_1p1_or_earlier(di->parent)) { | 3088 | if (!is_ab8500_1p1_or_earlier(di->parent)) { |
@@ -2848,9 +3095,14 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
2848 | goto out; | 3095 | goto out; |
2849 | } | 3096 | } |
2850 | 3097 | ||
2851 | ret = abx500_set_register_interruptible(di->dev, | 3098 | if (is_ab8540(di->parent)) |
2852 | AB8500_CHARGER, | 3099 | ret = abx500_set_register_interruptible(di->dev, |
2853 | AB8500_CH_OPT_CRNTLVL_MAX_REG, CH_OP_CUR_LVL_1P6); | 3100 | AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG, |
3101 | CH_OP_CUR_LVL_2P); | ||
3102 | else | ||
3103 | ret = abx500_set_register_interruptible(di->dev, | ||
3104 | AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG, | ||
3105 | CH_OP_CUR_LVL_1P6); | ||
2854 | if (ret) { | 3106 | if (ret) { |
2855 | dev_err(di->dev, | 3107 | dev_err(di->dev, |
2856 | "failed to set CH_OPT_CRNTLVL_MAX_REG\n"); | 3108 | "failed to set CH_OPT_CRNTLVL_MAX_REG\n"); |
@@ -2858,7 +3110,8 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
2858 | } | 3110 | } |
2859 | } | 3111 | } |
2860 | 3112 | ||
2861 | if (is_ab9540_2p0(di->parent) || is_ab8505_2p0(di->parent)) | 3113 | if (is_ab9540_2p0(di->parent) || is_ab9540_3p0(di->parent) |
3114 | || is_ab8505_2p0(di->parent) || is_ab8540(di->parent)) | ||
2862 | ret = abx500_mask_and_set_register_interruptible(di->dev, | 3115 | ret = abx500_mask_and_set_register_interruptible(di->dev, |
2863 | AB8500_CHARGER, | 3116 | AB8500_CHARGER, |
2864 | AB8500_USBCH_CTRL2_REG, | 3117 | AB8500_USBCH_CTRL2_REG, |
@@ -2930,14 +3183,6 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
2930 | goto out; | 3183 | goto out; |
2931 | } | 3184 | } |
2932 | 3185 | ||
2933 | /* Set charger watchdog timeout */ | ||
2934 | ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, | ||
2935 | AB8500_CH_WD_TIMER_REG, WD_TIMER); | ||
2936 | if (ret) { | ||
2937 | dev_err(di->dev, "failed to set charger watchdog timeout\n"); | ||
2938 | goto out; | ||
2939 | } | ||
2940 | |||
2941 | ret = ab8500_charger_led_en(di, false); | 3186 | ret = ab8500_charger_led_en(di, false); |
2942 | if (ret < 0) { | 3187 | if (ret < 0) { |
2943 | dev_err(di->dev, "failed to disable LED\n"); | 3188 | dev_err(di->dev, "failed to disable LED\n"); |
@@ -2945,15 +3190,30 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
2945 | } | 3190 | } |
2946 | 3191 | ||
2947 | /* Backup battery voltage and current */ | 3192 | /* Backup battery voltage and current */ |
3193 | if (di->bm->bkup_bat_v > BUP_VCH_SEL_3P1V) | ||
3194 | bup_vch_range = BUP_VCH_RANGE; | ||
3195 | if (di->bm->bkup_bat_v == BUP_VCH_SEL_3P3V) | ||
3196 | vbup33_vrtcn = VBUP33_VRTCN; | ||
3197 | |||
2948 | ret = abx500_set_register_interruptible(di->dev, | 3198 | ret = abx500_set_register_interruptible(di->dev, |
2949 | AB8500_RTC, | 3199 | AB8500_RTC, |
2950 | AB8500_RTC_BACKUP_CHG_REG, | 3200 | AB8500_RTC_BACKUP_CHG_REG, |
2951 | di->bm->bkup_bat_v | | 3201 | (di->bm->bkup_bat_v & 0x3) | di->bm->bkup_bat_i); |
2952 | di->bm->bkup_bat_i); | ||
2953 | if (ret) { | 3202 | if (ret) { |
2954 | dev_err(di->dev, "failed to setup backup battery charging\n"); | 3203 | dev_err(di->dev, "failed to setup backup battery charging\n"); |
2955 | goto out; | 3204 | goto out; |
2956 | } | 3205 | } |
3206 | if (is_ab8540(di->parent)) { | ||
3207 | ret = abx500_set_register_interruptible(di->dev, | ||
3208 | AB8500_RTC, | ||
3209 | AB8500_RTC_CTRL1_REG, | ||
3210 | bup_vch_range | vbup33_vrtcn); | ||
3211 | if (ret) { | ||
3212 | dev_err(di->dev, | ||
3213 | "failed to setup backup battery charging\n"); | ||
3214 | goto out; | ||
3215 | } | ||
3216 | } | ||
2957 | 3217 | ||
2958 | /* Enable backup battery charging */ | 3218 | /* Enable backup battery charging */ |
2959 | abx500_mask_and_set_register_interruptible(di->dev, | 3219 | abx500_mask_and_set_register_interruptible(di->dev, |
@@ -2962,6 +3222,25 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
2962 | if (ret < 0) | 3222 | if (ret < 0) |
2963 | dev_err(di->dev, "%s mask and set failed\n", __func__); | 3223 | dev_err(di->dev, "%s mask and set failed\n", __func__); |
2964 | 3224 | ||
3225 | if (is_ab8540(di->parent)) { | ||
3226 | ret = abx500_mask_and_set_register_interruptible(di->dev, | ||
3227 | AB8500_CHARGER, AB8540_USB_PP_MODE_REG, | ||
3228 | BUS_VSYS_VOL_SELECT_MASK, BUS_VSYS_VOL_SELECT_3P6V); | ||
3229 | if (ret) { | ||
3230 | dev_err(di->dev, | ||
3231 | "failed to setup usb power path vsys voltage\n"); | ||
3232 | goto out; | ||
3233 | } | ||
3234 | ret = abx500_mask_and_set_register_interruptible(di->dev, | ||
3235 | AB8500_CHARGER, AB8540_USB_PP_CHR_REG, | ||
3236 | BUS_PP_PRECHG_CURRENT_MASK, 0); | ||
3237 | if (ret) { | ||
3238 | dev_err(di->dev, | ||
3239 | "failed to setup usb power path prechage current\n"); | ||
3240 | goto out; | ||
3241 | } | ||
3242 | } | ||
3243 | |||
2965 | out: | 3244 | out: |
2966 | return ret; | 3245 | return ret; |
2967 | } | 3246 | } |
@@ -3055,11 +3334,8 @@ static int ab8500_charger_resume(struct platform_device *pdev) | |||
3055 | dev_err(di->dev, "Failed to kick WD!\n"); | 3334 | dev_err(di->dev, "Failed to kick WD!\n"); |
3056 | 3335 | ||
3057 | /* If not already pending start a new timer */ | 3336 | /* If not already pending start a new timer */ |
3058 | if (!delayed_work_pending( | 3337 | queue_delayed_work(di->charger_wq, &di->kick_wd_work, |
3059 | &di->kick_wd_work)) { | 3338 | round_jiffies(WD_KICK_INTERVAL)); |
3060 | queue_delayed_work(di->charger_wq, &di->kick_wd_work, | ||
3061 | round_jiffies(WD_KICK_INTERVAL)); | ||
3062 | } | ||
3063 | } | 3339 | } |
3064 | 3340 | ||
3065 | /* If we still have a HW failure, schedule a new check */ | 3341 | /* If we still have a HW failure, schedule a new check */ |
@@ -3079,12 +3355,9 @@ static int ab8500_charger_suspend(struct platform_device *pdev, | |||
3079 | { | 3355 | { |
3080 | struct ab8500_charger *di = platform_get_drvdata(pdev); | 3356 | struct ab8500_charger *di = platform_get_drvdata(pdev); |
3081 | 3357 | ||
3082 | /* Cancel any pending HW failure check */ | 3358 | /* Cancel any pending jobs */ |
3083 | if (delayed_work_pending(&di->check_hw_failure_work)) | 3359 | cancel_delayed_work(&di->check_hw_failure_work); |
3084 | cancel_delayed_work(&di->check_hw_failure_work); | 3360 | cancel_delayed_work(&di->vbus_drop_end_work); |
3085 | |||
3086 | if (delayed_work_pending(&di->vbus_drop_end_work)) | ||
3087 | cancel_delayed_work(&di->vbus_drop_end_work); | ||
3088 | 3361 | ||
3089 | flush_delayed_work(&di->attach_work); | 3362 | flush_delayed_work(&di->attach_work); |
3090 | flush_delayed_work(&di->usb_charger_attached_work); | 3363 | flush_delayed_work(&di->usb_charger_attached_work); |
@@ -3107,6 +3380,10 @@ static int ab8500_charger_suspend(struct platform_device *pdev, | |||
3107 | #define ab8500_charger_resume NULL | 3380 | #define ab8500_charger_resume NULL |
3108 | #endif | 3381 | #endif |
3109 | 3382 | ||
3383 | static struct notifier_block charger_nb = { | ||
3384 | .notifier_call = ab8500_external_charger_prepare, | ||
3385 | }; | ||
3386 | |||
3110 | static int ab8500_charger_remove(struct platform_device *pdev) | 3387 | static int ab8500_charger_remove(struct platform_device *pdev) |
3111 | { | 3388 | { |
3112 | struct ab8500_charger *di = platform_get_drvdata(pdev); | 3389 | struct ab8500_charger *di = platform_get_drvdata(pdev); |
@@ -3136,13 +3413,18 @@ static int ab8500_charger_remove(struct platform_device *pdev) | |||
3136 | /* Delete the work queue */ | 3413 | /* Delete the work queue */ |
3137 | destroy_workqueue(di->charger_wq); | 3414 | destroy_workqueue(di->charger_wq); |
3138 | 3415 | ||
3416 | /* Unregister external charger enable notifier */ | ||
3417 | if (!di->ac_chg.enabled) | ||
3418 | blocking_notifier_chain_unregister( | ||
3419 | &charger_notifier_list, &charger_nb); | ||
3420 | |||
3139 | flush_scheduled_work(); | 3421 | flush_scheduled_work(); |
3140 | if(di->usb_chg.enabled) | 3422 | if (di->usb_chg.enabled) |
3141 | power_supply_unregister(&di->usb_chg.psy); | 3423 | power_supply_unregister(&di->usb_chg.psy); |
3142 | #if !defined(CONFIG_CHARGER_PM2301) | 3424 | |
3143 | if(di->ac_chg.enabled) | 3425 | if (di->ac_chg.enabled && !di->ac_chg.external) |
3144 | power_supply_unregister(&di->ac_chg.psy); | 3426 | power_supply_unregister(&di->ac_chg.psy); |
3145 | #endif | 3427 | |
3146 | platform_set_drvdata(pdev, NULL); | 3428 | platform_set_drvdata(pdev, NULL); |
3147 | 3429 | ||
3148 | return 0; | 3430 | return 0; |
@@ -3206,16 +3488,22 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
3206 | di->ac_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), | 3488 | di->ac_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), |
3207 | /* ux500_charger sub-class */ | 3489 | /* ux500_charger sub-class */ |
3208 | di->ac_chg.ops.enable = &ab8500_charger_ac_en; | 3490 | di->ac_chg.ops.enable = &ab8500_charger_ac_en; |
3491 | di->ac_chg.ops.check_enable = &ab8500_charger_ac_check_enable; | ||
3209 | di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; | 3492 | di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; |
3210 | di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current; | 3493 | di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current; |
3211 | di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ | 3494 | di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ |
3212 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; | 3495 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; |
3213 | di->ac_chg.max_out_curr = ab8500_charger_current_map[ | 3496 | di->ac_chg.max_out_curr = |
3214 | ARRAY_SIZE(ab8500_charger_current_map) - 1]; | 3497 | di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1]; |
3215 | di->ac_chg.wdt_refresh = CHG_WD_INTERVAL; | 3498 | di->ac_chg.wdt_refresh = CHG_WD_INTERVAL; |
3216 | di->ac_chg.enabled = di->bm->ac_enabled; | 3499 | di->ac_chg.enabled = di->bm->ac_enabled; |
3217 | di->ac_chg.external = false; | 3500 | di->ac_chg.external = false; |
3218 | 3501 | ||
3502 | /*notifier for external charger enabling*/ | ||
3503 | if (!di->ac_chg.enabled) | ||
3504 | blocking_notifier_chain_register( | ||
3505 | &charger_notifier_list, &charger_nb); | ||
3506 | |||
3219 | /* USB supply */ | 3507 | /* USB supply */ |
3220 | /* power_supply base class */ | 3508 | /* power_supply base class */ |
3221 | di->usb_chg.psy.name = "ab8500_usb"; | 3509 | di->usb_chg.psy.name = "ab8500_usb"; |
@@ -3227,15 +3515,20 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
3227 | di->usb_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), | 3515 | di->usb_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), |
3228 | /* ux500_charger sub-class */ | 3516 | /* ux500_charger sub-class */ |
3229 | di->usb_chg.ops.enable = &ab8500_charger_usb_en; | 3517 | di->usb_chg.ops.enable = &ab8500_charger_usb_en; |
3518 | di->usb_chg.ops.check_enable = &ab8500_charger_usb_check_enable; | ||
3230 | di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; | 3519 | di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; |
3231 | di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current; | 3520 | di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current; |
3521 | di->usb_chg.ops.pp_enable = &ab8540_charger_power_path_enable; | ||
3522 | di->usb_chg.ops.pre_chg_enable = &ab8540_charger_usb_pre_chg_enable; | ||
3232 | di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ | 3523 | di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ |
3233 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; | 3524 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; |
3234 | di->usb_chg.max_out_curr = ab8500_charger_current_map[ | 3525 | di->usb_chg.max_out_curr = |
3235 | ARRAY_SIZE(ab8500_charger_current_map) - 1]; | 3526 | di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1]; |
3236 | di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; | 3527 | di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; |
3237 | di->usb_chg.enabled = di->bm->usb_enabled; | 3528 | di->usb_chg.enabled = di->bm->usb_enabled; |
3238 | di->usb_chg.external = false; | 3529 | di->usb_chg.external = false; |
3530 | di->usb_chg.power_path = di->bm->usb_power_path; | ||
3531 | di->usb_state.usb_current = -1; | ||
3239 | 3532 | ||
3240 | /* Create a work queue for the charger */ | 3533 | /* Create a work queue for the charger */ |
3241 | di->charger_wq = | 3534 | di->charger_wq = |
@@ -3316,7 +3609,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
3316 | } | 3609 | } |
3317 | 3610 | ||
3318 | /* Register AC charger class */ | 3611 | /* Register AC charger class */ |
3319 | if(di->ac_chg.enabled) { | 3612 | if (di->ac_chg.enabled) { |
3320 | ret = power_supply_register(di->dev, &di->ac_chg.psy); | 3613 | ret = power_supply_register(di->dev, &di->ac_chg.psy); |
3321 | if (ret) { | 3614 | if (ret) { |
3322 | dev_err(di->dev, "failed to register AC charger\n"); | 3615 | dev_err(di->dev, "failed to register AC charger\n"); |
@@ -3325,7 +3618,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
3325 | } | 3618 | } |
3326 | 3619 | ||
3327 | /* Register USB charger class */ | 3620 | /* Register USB charger class */ |
3328 | if(di->usb_chg.enabled) { | 3621 | if (di->usb_chg.enabled) { |
3329 | ret = power_supply_register(di->dev, &di->usb_chg.psy); | 3622 | ret = power_supply_register(di->dev, &di->usb_chg.psy); |
3330 | if (ret) { | 3623 | if (ret) { |
3331 | dev_err(di->dev, "failed to register USB charger\n"); | 3624 | dev_err(di->dev, "failed to register USB charger\n"); |
@@ -3385,14 +3678,16 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
3385 | ch_stat = ab8500_charger_detect_chargers(di, false); | 3678 | ch_stat = ab8500_charger_detect_chargers(di, false); |
3386 | 3679 | ||
3387 | if ((ch_stat & AC_PW_CONN) == AC_PW_CONN) { | 3680 | if ((ch_stat & AC_PW_CONN) == AC_PW_CONN) { |
3388 | queue_delayed_work(di->charger_wq, | 3681 | if (is_ab8500(di->parent)) |
3389 | &di->ac_charger_attached_work, | 3682 | queue_delayed_work(di->charger_wq, |
3390 | HZ); | 3683 | &di->ac_charger_attached_work, |
3684 | HZ); | ||
3391 | } | 3685 | } |
3392 | if ((ch_stat & USB_PW_CONN) == USB_PW_CONN) { | 3686 | if ((ch_stat & USB_PW_CONN) == USB_PW_CONN) { |
3393 | queue_delayed_work(di->charger_wq, | 3687 | if (is_ab8500(di->parent)) |
3394 | &di->usb_charger_attached_work, | 3688 | queue_delayed_work(di->charger_wq, |
3395 | HZ); | 3689 | &di->usb_charger_attached_work, |
3690 | HZ); | ||
3396 | } | 3691 | } |
3397 | 3692 | ||
3398 | mutex_unlock(&di->charger_attached_mutex); | 3693 | mutex_unlock(&di->charger_attached_mutex); |
@@ -3410,10 +3705,10 @@ free_irq: | |||
3410 | put_usb_phy: | 3705 | put_usb_phy: |
3411 | usb_put_phy(di->usb_phy); | 3706 | usb_put_phy(di->usb_phy); |
3412 | free_usb: | 3707 | free_usb: |
3413 | if(di->usb_chg.enabled) | 3708 | if (di->usb_chg.enabled) |
3414 | power_supply_unregister(&di->usb_chg.psy); | 3709 | power_supply_unregister(&di->usb_chg.psy); |
3415 | free_ac: | 3710 | free_ac: |
3416 | if(di->ac_chg.enabled) | 3711 | if (di->ac_chg.enabled) |
3417 | power_supply_unregister(&di->ac_chg.psy); | 3712 | power_supply_unregister(&di->ac_chg.psy); |
3418 | free_charger_wq: | 3713 | free_charger_wq: |
3419 | destroy_workqueue(di->charger_wq); | 3714 | destroy_workqueue(di->charger_wq); |