diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/power/ab8500_charger.c | 169 |
1 files changed, 120 insertions, 49 deletions
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index f1d712308b02..547f6ea1b695 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #define MAIN_CH_INPUT_CURR_SHIFT 4 | 58 | #define MAIN_CH_INPUT_CURR_SHIFT 4 |
59 | #define VBUS_IN_CURR_LIM_SHIFT 4 | 59 | #define VBUS_IN_CURR_LIM_SHIFT 4 |
60 | #define AUTO_VBUS_IN_CURR_LIM_SHIFT 4 | 60 | #define AUTO_VBUS_IN_CURR_LIM_SHIFT 4 |
61 | #define VBUS_IN_CURR_LIM_RETRY_SET_TIME 30 /* seconds */ | ||
61 | 62 | ||
62 | #define LED_INDICATOR_PWM_ENA 0x01 | 63 | #define LED_INDICATOR_PWM_ENA 0x01 |
63 | #define LED_INDICATOR_PWM_DIS 0x00 | 64 | #define LED_INDICATOR_PWM_DIS 0x00 |
@@ -202,10 +203,15 @@ struct ab8500_charger_usb_state { | |||
202 | spinlock_t usb_lock; | 203 | spinlock_t usb_lock; |
203 | }; | 204 | }; |
204 | 205 | ||
206 | struct ab8500_charger_max_usb_in_curr { | ||
207 | int usb_type_max; | ||
208 | int set_max; | ||
209 | int calculated_max; | ||
210 | }; | ||
211 | |||
205 | /** | 212 | /** |
206 | * struct ab8500_charger - ab8500 Charger device information | 213 | * struct ab8500_charger - ab8500 Charger device information |
207 | * @dev: Pointer to the structure device | 214 | * @dev: Pointer to the structure device |
208 | * @max_usb_in_curr: Max USB charger input current | ||
209 | * @vbus_detected: VBUS detected | 215 | * @vbus_detected: VBUS detected |
210 | * @vbus_detected_start: | 216 | * @vbus_detected_start: |
211 | * VBUS detected during startup | 217 | * VBUS detected during startup |
@@ -220,7 +226,6 @@ struct ab8500_charger_usb_state { | |||
220 | * @autopower Indicate if we should have automatic pwron after pwrloss | 226 | * @autopower Indicate if we should have automatic pwron after pwrloss |
221 | * @autopower_cfg platform specific power config support for "pwron after pwrloss" | 227 | * @autopower_cfg platform specific power config support for "pwron after pwrloss" |
222 | * @invalid_charger_detect_state State when forcing AB to use invalid charger | 228 | * @invalid_charger_detect_state State when forcing AB to use invalid charger |
223 | * @is_usb_host: Indicate if last detected USB type is host | ||
224 | * @is_aca_rid: Incicate if accessory is ACA type | 229 | * @is_aca_rid: Incicate if accessory is ACA type |
225 | * @current_stepping_sessions: | 230 | * @current_stepping_sessions: |
226 | * Counter for current stepping sessions | 231 | * Counter for current stepping sessions |
@@ -229,6 +234,7 @@ struct ab8500_charger_usb_state { | |||
229 | * @bm: Platform specific battery management information | 234 | * @bm: Platform specific battery management information |
230 | * @flags: Structure for information about events triggered | 235 | * @flags: Structure for information about events triggered |
231 | * @usb_state: Structure for usb stack information | 236 | * @usb_state: Structure for usb stack information |
237 | * @max_usb_in_curr: Max USB charger input current | ||
232 | * @ac_chg: AC charger power supply | 238 | * @ac_chg: AC charger power supply |
233 | * @usb_chg: USB charger power supply | 239 | * @usb_chg: USB charger power supply |
234 | * @ac: Structure that holds the AC charger properties | 240 | * @ac: Structure that holds the AC charger properties |
@@ -260,7 +266,6 @@ struct ab8500_charger_usb_state { | |||
260 | */ | 266 | */ |
261 | struct ab8500_charger { | 267 | struct ab8500_charger { |
262 | struct device *dev; | 268 | struct device *dev; |
263 | int max_usb_in_curr; | ||
264 | bool vbus_detected; | 269 | bool vbus_detected; |
265 | bool vbus_detected_start; | 270 | bool vbus_detected_start; |
266 | bool ac_conn; | 271 | bool ac_conn; |
@@ -272,7 +277,6 @@ struct ab8500_charger { | |||
272 | bool autopower; | 277 | bool autopower; |
273 | bool autopower_cfg; | 278 | bool autopower_cfg; |
274 | int invalid_charger_detect_state; | 279 | int invalid_charger_detect_state; |
275 | bool is_usb_host; | ||
276 | int is_aca_rid; | 280 | int is_aca_rid; |
277 | atomic_t current_stepping_sessions; | 281 | atomic_t current_stepping_sessions; |
278 | struct ab8500 *parent; | 282 | struct ab8500 *parent; |
@@ -280,6 +284,7 @@ struct ab8500_charger { | |||
280 | struct abx500_bm_data *bm; | 284 | struct abx500_bm_data *bm; |
281 | struct ab8500_charger_event_flags flags; | 285 | struct ab8500_charger_event_flags flags; |
282 | struct ab8500_charger_usb_state usb_state; | 286 | struct ab8500_charger_usb_state usb_state; |
287 | struct ab8500_charger_max_usb_in_curr max_usb_in_curr; | ||
283 | struct ux500_charger ac_chg; | 288 | struct ux500_charger ac_chg; |
284 | struct ux500_charger usb_chg; | 289 | struct ux500_charger usb_chg; |
285 | struct ab8500_charger_info ac; | 290 | struct ab8500_charger_info ac; |
@@ -421,6 +426,10 @@ static void ab8500_charger_set_usb_connected(struct ab8500_charger *di, | |||
421 | if (connected != di->usb.charger_connected) { | 426 | if (connected != di->usb.charger_connected) { |
422 | dev_dbg(di->dev, "USB connected:%i\n", connected); | 427 | dev_dbg(di->dev, "USB connected:%i\n", connected); |
423 | di->usb.charger_connected = connected; | 428 | di->usb.charger_connected = connected; |
429 | |||
430 | if (!connected) | ||
431 | di->flags.vbus_drop_end = false; | ||
432 | |||
424 | sysfs_notify(&di->usb_chg.psy.dev->kobj, NULL, "present"); | 433 | sysfs_notify(&di->usb_chg.psy.dev->kobj, NULL, "present"); |
425 | 434 | ||
426 | if (connected) { | 435 | if (connected) { |
@@ -674,23 +683,19 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
674 | case USB_STAT_STD_HOST_C_S: | 683 | case USB_STAT_STD_HOST_C_S: |
675 | dev_dbg(di->dev, "USB Type - Standard host is " | 684 | dev_dbg(di->dev, "USB Type - Standard host is " |
676 | "detected through USB driver\n"); | 685 | "detected through USB driver\n"); |
677 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 686 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
678 | di->is_usb_host = true; | ||
679 | di->is_aca_rid = 0; | 687 | di->is_aca_rid = 0; |
680 | break; | 688 | break; |
681 | case USB_STAT_HOST_CHG_HS_CHIRP: | 689 | case USB_STAT_HOST_CHG_HS_CHIRP: |
682 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 690 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
683 | di->is_usb_host = true; | ||
684 | di->is_aca_rid = 0; | 691 | di->is_aca_rid = 0; |
685 | break; | 692 | break; |
686 | case USB_STAT_HOST_CHG_HS: | 693 | case USB_STAT_HOST_CHG_HS: |
687 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 694 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
688 | di->is_usb_host = true; | ||
689 | di->is_aca_rid = 0; | 695 | di->is_aca_rid = 0; |
690 | break; | 696 | break; |
691 | case USB_STAT_ACA_RID_C_HS: | 697 | case USB_STAT_ACA_RID_C_HS: |
692 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P9; | 698 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P9; |
693 | di->is_usb_host = false; | ||
694 | di->is_aca_rid = 0; | 699 | di->is_aca_rid = 0; |
695 | break; | 700 | break; |
696 | case USB_STAT_ACA_RID_A: | 701 | case USB_STAT_ACA_RID_A: |
@@ -699,8 +704,7 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
699 | * can consume (900mA). Closest level is 500mA | 704 | * can consume (900mA). Closest level is 500mA |
700 | */ | 705 | */ |
701 | dev_dbg(di->dev, "USB_STAT_ACA_RID_A detected\n"); | 706 | dev_dbg(di->dev, "USB_STAT_ACA_RID_A detected\n"); |
702 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 707 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
703 | di->is_usb_host = false; | ||
704 | di->is_aca_rid = 1; | 708 | di->is_aca_rid = 1; |
705 | break; | 709 | break; |
706 | case USB_STAT_ACA_RID_B: | 710 | case USB_STAT_ACA_RID_B: |
@@ -708,38 +712,35 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
708 | * Dedicated charger level minus 120mA (20mA for ACA and | 712 | * Dedicated charger level minus 120mA (20mA for ACA and |
709 | * 100mA for potential accessory). Closest level is 1300mA | 713 | * 100mA for potential accessory). Closest level is 1300mA |
710 | */ | 714 | */ |
711 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P3; | 715 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P3; |
712 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, | 716 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, |
713 | di->max_usb_in_curr); | 717 | di->max_usb_in_curr.usb_type_max); |
714 | di->is_usb_host = false; | ||
715 | di->is_aca_rid = 1; | 718 | di->is_aca_rid = 1; |
716 | break; | 719 | break; |
717 | case USB_STAT_HOST_CHG_NM: | 720 | case USB_STAT_HOST_CHG_NM: |
718 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 721 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
719 | di->is_usb_host = true; | ||
720 | di->is_aca_rid = 0; | 722 | di->is_aca_rid = 0; |
721 | break; | 723 | break; |
722 | case USB_STAT_DEDICATED_CHG: | 724 | case USB_STAT_DEDICATED_CHG: |
723 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; | 725 | 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 = 0; | 726 | di->is_aca_rid = 0; |
726 | break; | 727 | break; |
727 | case USB_STAT_ACA_RID_C_HS_CHIRP: | 728 | case USB_STAT_ACA_RID_C_HS_CHIRP: |
728 | case USB_STAT_ACA_RID_C_NM: | 729 | case USB_STAT_ACA_RID_C_NM: |
729 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; | 730 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P5; |
730 | di->is_usb_host = false; | ||
731 | di->is_aca_rid = 1; | 731 | di->is_aca_rid = 1; |
732 | break; | 732 | break; |
733 | case USB_STAT_NOT_CONFIGURED: | 733 | case USB_STAT_NOT_CONFIGURED: |
734 | if (di->vbus_detected) { | 734 | if (di->vbus_detected) { |
735 | di->usb_device_is_unrecognised = true; | 735 | di->usb_device_is_unrecognised = true; |
736 | dev_dbg(di->dev, "USB Type - Legacy charger.\n"); | 736 | dev_dbg(di->dev, "USB Type - Legacy charger.\n"); |
737 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; | 737 | di->max_usb_in_curr.usb_type_max = |
738 | USB_CH_IP_CUR_LVL_1P5; | ||
738 | break; | 739 | break; |
739 | } | 740 | } |
740 | case USB_STAT_HM_IDGND: | 741 | case USB_STAT_HM_IDGND: |
741 | dev_err(di->dev, "USB Type - Charging not allowed\n"); | 742 | dev_err(di->dev, "USB Type - Charging not allowed\n"); |
742 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; | 743 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; |
743 | ret = -ENXIO; | 744 | ret = -ENXIO; |
744 | break; | 745 | break; |
745 | case USB_STAT_RESERVED: | 746 | case USB_STAT_RESERVED: |
@@ -752,9 +753,11 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
752 | } | 753 | } |
753 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | 754 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { |
754 | dev_dbg(di->dev, "USB Type - Charging not allowed\n"); | 755 | dev_dbg(di->dev, "USB Type - Charging not allowed\n"); |
755 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; | 756 | di->max_usb_in_curr.usb_type_max = |
757 | USB_CH_IP_CUR_LVL_0P05; | ||
756 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", | 758 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", |
757 | link_status, di->max_usb_in_curr); | 759 | link_status, |
760 | di->max_usb_in_curr.usb_type_max); | ||
758 | ret = -ENXIO; | 761 | ret = -ENXIO; |
759 | break; | 762 | break; |
760 | } | 763 | } |
@@ -763,23 +766,24 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
763 | case USB_STAT_CARKIT_2: | 766 | case USB_STAT_CARKIT_2: |
764 | case USB_STAT_ACA_DOCK_CHARGER: | 767 | case USB_STAT_ACA_DOCK_CHARGER: |
765 | case USB_STAT_CHARGER_LINE_1: | 768 | case USB_STAT_CHARGER_LINE_1: |
766 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 769 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
767 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, | 770 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, |
768 | di->max_usb_in_curr); | 771 | di->max_usb_in_curr.usb_type_max); |
769 | case USB_STAT_NOT_VALID_LINK: | 772 | case USB_STAT_NOT_VALID_LINK: |
770 | dev_err(di->dev, "USB Type invalid - try charging anyway\n"); | 773 | dev_err(di->dev, "USB Type invalid - try charging anyway\n"); |
771 | 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; |
772 | break; | 775 | break; |
773 | 776 | ||
774 | default: | 777 | default: |
775 | dev_err(di->dev, "USB Type - Unknown\n"); | 778 | dev_err(di->dev, "USB Type - Unknown\n"); |
776 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; | 779 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; |
777 | ret = -ENXIO; | 780 | ret = -ENXIO; |
778 | break; | 781 | break; |
779 | }; | 782 | }; |
780 | 783 | ||
784 | di->max_usb_in_curr.set_max = di->max_usb_in_curr.usb_type_max; | ||
781 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", | 785 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", |
782 | link_status, di->max_usb_in_curr); | 786 | link_status, di->max_usb_in_curr.set_max); |
783 | 787 | ||
784 | return ret; | 788 | return ret; |
785 | } | 789 | } |
@@ -1083,28 +1087,48 @@ static int ab8500_vbus_in_curr_to_regval(int curr) | |||
1083 | */ | 1087 | */ |
1084 | static int ab8500_charger_get_usb_cur(struct ab8500_charger *di) | 1088 | static int ab8500_charger_get_usb_cur(struct ab8500_charger *di) |
1085 | { | 1089 | { |
1090 | int ret = 0; | ||
1086 | switch (di->usb_state.usb_current) { | 1091 | switch (di->usb_state.usb_current) { |
1087 | case 100: | 1092 | case 100: |
1088 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P09; | 1093 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P09; |
1089 | break; | 1094 | break; |
1090 | case 200: | 1095 | case 200: |
1091 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P19; | 1096 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P19; |
1092 | break; | 1097 | break; |
1093 | case 300: | 1098 | case 300: |
1094 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P29; | 1099 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P29; |
1095 | break; | 1100 | break; |
1096 | case 400: | 1101 | case 400: |
1097 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P38; | 1102 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P38; |
1098 | break; | 1103 | break; |
1099 | case 500: | 1104 | case 500: |
1100 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 1105 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; |
1101 | break; | 1106 | break; |
1102 | default: | 1107 | default: |
1103 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; | 1108 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; |
1104 | return -1; | 1109 | ret = -EPERM; |
1105 | break; | 1110 | break; |
1106 | }; | 1111 | }; |
1107 | return 0; | 1112 | di->max_usb_in_curr.set_max = di->max_usb_in_curr.usb_type_max; |
1113 | return ret; | ||
1114 | } | ||
1115 | |||
1116 | /** | ||
1117 | * ab8500_charger_check_continue_stepping() - Check to allow stepping | ||
1118 | * @di: pointer to the ab8500_charger structure | ||
1119 | * @reg: select what charger register to check | ||
1120 | * | ||
1121 | * Check if current stepping should be allowed to continue. | ||
1122 | * Checks if charger source has not collapsed. If it has, further stepping | ||
1123 | * is not allowed. | ||
1124 | */ | ||
1125 | static bool ab8500_charger_check_continue_stepping(struct ab8500_charger *di, | ||
1126 | int reg) | ||
1127 | { | ||
1128 | if (reg == AB8500_USBCH_IPT_CRNTLVL_REG) | ||
1129 | return !di->flags.vbus_drop_end; | ||
1130 | else | ||
1131 | return true; | ||
1108 | } | 1132 | } |
1109 | 1133 | ||
1110 | /** | 1134 | /** |
@@ -1225,7 +1249,8 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, | |||
1225 | usleep_range(step_udelay, step_udelay * 2); | 1249 | usleep_range(step_udelay, step_udelay * 2); |
1226 | } | 1250 | } |
1227 | } else { | 1251 | } else { |
1228 | for (i = prev_curr_index + 1; i <= curr_index; i++) { | 1252 | bool allow = true; |
1253 | for (i = prev_curr_index + 1; i <= curr_index && allow; i++) { | ||
1229 | dev_dbg(di->dev, "curr change_2 to: %x for 0x%02x\n", | 1254 | dev_dbg(di->dev, "curr change_2 to: %x for 0x%02x\n", |
1230 | (u8)i << shift_value, reg); | 1255 | (u8)i << shift_value, reg); |
1231 | ret = abx500_set_register_interruptible(di->dev, | 1256 | ret = abx500_set_register_interruptible(di->dev, |
@@ -1236,6 +1261,8 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, | |||
1236 | } | 1261 | } |
1237 | if (i != curr_index) | 1262 | if (i != curr_index) |
1238 | usleep_range(step_udelay, step_udelay * 2); | 1263 | usleep_range(step_udelay, step_udelay * 2); |
1264 | |||
1265 | allow = ab8500_charger_check_continue_stepping(di, reg); | ||
1239 | } | 1266 | } |
1240 | } | 1267 | } |
1241 | 1268 | ||
@@ -1261,6 +1288,11 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di, | |||
1261 | 1288 | ||
1262 | /* We should always use to lowest current limit */ | 1289 | /* We should always use to lowest current limit */ |
1263 | min_value = min(di->bm->chg_params->usb_curr_max, ich_in); | 1290 | min_value = min(di->bm->chg_params->usb_curr_max, ich_in); |
1291 | if (di->max_usb_in_curr.set_max > 0) | ||
1292 | min_value = min(di->max_usb_in_curr.set_max, min_value); | ||
1293 | |||
1294 | if (di->usb_state.usb_current >= 0) | ||
1295 | min_value = min(di->usb_state.usb_current, min_value); | ||
1264 | 1296 | ||
1265 | switch (min_value) { | 1297 | switch (min_value) { |
1266 | case 100: | 1298 | case 100: |
@@ -1615,7 +1647,8 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, | |||
1615 | di->usb.charger_online = 1; | 1647 | di->usb.charger_online = 1; |
1616 | 1648 | ||
1617 | /* USBChInputCurr: current that can be drawn from the usb */ | 1649 | /* USBChInputCurr: current that can be drawn from the usb */ |
1618 | ret = ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | 1650 | ret = ab8500_charger_set_vbus_in_curr(di, |
1651 | di->max_usb_in_curr.usb_type_max); | ||
1619 | if (ret) { | 1652 | if (ret) { |
1620 | dev_err(di->dev, "setting USBChInputCurr failed\n"); | 1653 | dev_err(di->dev, "setting USBChInputCurr failed\n"); |
1621 | return ret; | 1654 | return ret; |
@@ -1950,9 +1983,10 @@ static void ab8500_charger_check_vbat_work(struct work_struct *work) | |||
1950 | di->vbat > VBAT_TRESH_IP_CUR_RED))) { | 1983 | di->vbat > VBAT_TRESH_IP_CUR_RED))) { |
1951 | 1984 | ||
1952 | dev_dbg(di->dev, "Vbat did cross threshold, curr: %d, new: %d," | 1985 | dev_dbg(di->dev, "Vbat did cross threshold, curr: %d, new: %d," |
1953 | " old: %d\n", di->max_usb_in_curr, di->vbat, | 1986 | " old: %d\n", di->max_usb_in_curr.usb_type_max, |
1954 | di->old_vbat); | 1987 | di->vbat, di->old_vbat); |
1955 | ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | 1988 | ab8500_charger_set_vbus_in_curr(di, |
1989 | di->max_usb_in_curr.usb_type_max); | ||
1956 | power_supply_changed(&di->usb_chg.psy); | 1990 | power_supply_changed(&di->usb_chg.psy); |
1957 | } | 1991 | } |
1958 | 1992 | ||
@@ -2232,7 +2266,8 @@ static void ab8500_charger_usb_link_attach_work(struct work_struct *work) | |||
2232 | 2266 | ||
2233 | /* Update maximum input current if USB enumeration is not detected */ | 2267 | /* Update maximum input current if USB enumeration is not detected */ |
2234 | if (!di->usb.charger_online) { | 2268 | if (!di->usb.charger_online) { |
2235 | ret = ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | 2269 | ret = ab8500_charger_set_vbus_in_curr(di, |
2270 | di->max_usb_in_curr.usb_type_max); | ||
2236 | if (ret) | 2271 | if (ret) |
2237 | return; | 2272 | return; |
2238 | } | 2273 | } |
@@ -2400,7 +2435,7 @@ static void ab8500_charger_usb_state_changed_work(struct work_struct *work) | |||
2400 | if (!ab8500_charger_get_usb_cur(di)) { | 2435 | if (!ab8500_charger_get_usb_cur(di)) { |
2401 | /* Update maximum input current */ | 2436 | /* Update maximum input current */ |
2402 | ret = ab8500_charger_set_vbus_in_curr(di, | 2437 | ret = ab8500_charger_set_vbus_in_curr(di, |
2403 | di->max_usb_in_curr); | 2438 | di->max_usb_in_curr.usb_type_max); |
2404 | if (ret) | 2439 | if (ret) |
2405 | return; | 2440 | return; |
2406 | 2441 | ||
@@ -2618,15 +2653,45 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) | |||
2618 | { | 2653 | { |
2619 | struct ab8500_charger *di = container_of(work, | 2654 | struct ab8500_charger *di = container_of(work, |
2620 | struct ab8500_charger, vbus_drop_end_work.work); | 2655 | struct ab8500_charger, vbus_drop_end_work.work); |
2656 | int ret; | ||
2657 | u8 reg_value; | ||
2621 | 2658 | ||
2622 | di->flags.vbus_drop_end = false; | 2659 | di->flags.vbus_drop_end = false; |
2623 | 2660 | ||
2624 | /* Reset the drop counter */ | 2661 | /* Reset the drop counter */ |
2625 | abx500_set_register_interruptible(di->dev, | 2662 | abx500_set_register_interruptible(di->dev, |
2626 | AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01); | 2663 | AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01); |
2664 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
2665 | AB8500_CH_USBCH_STAT2_REG, | ||
2666 | ®_value); | ||
2667 | if (ret < 0) { | ||
2668 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); | ||
2669 | } else { | ||
2670 | int curr = ab8500_charger_vbus_in_curr_map[ | ||
2671 | reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT]; | ||
2672 | if (di->max_usb_in_curr.calculated_max != curr) { | ||
2673 | /* USB source is collapsing */ | ||
2674 | di->max_usb_in_curr.calculated_max = curr; | ||
2675 | dev_dbg(di->dev, | ||
2676 | "VBUS input current limiting to %d mA\n", | ||
2677 | di->max_usb_in_curr.calculated_max); | ||
2678 | } else { | ||
2679 | /* | ||
2680 | * USB source can not give more than this amount. | ||
2681 | * Taking more will collapse the source. | ||
2682 | */ | ||
2683 | di->max_usb_in_curr.set_max = | ||
2684 | di->max_usb_in_curr.calculated_max; | ||
2685 | dev_dbg(di->dev, | ||
2686 | "VBUS input current limited to %d mA\n", | ||
2687 | di->max_usb_in_curr.set_max); | ||
2688 | return; | ||
2689 | } | ||
2690 | } | ||
2627 | 2691 | ||
2628 | if (di->usb.charger_connected) | 2692 | if (di->usb.charger_connected) |
2629 | ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | 2693 | ab8500_charger_set_vbus_in_curr(di, |
2694 | di->max_usb_in_curr.usb_type_max); | ||
2630 | } | 2695 | } |
2631 | 2696 | ||
2632 | /** | 2697 | /** |
@@ -2781,8 +2846,13 @@ static irqreturn_t ab8500_charger_vbuschdropend_handler(int irq, void *_di) | |||
2781 | 2846 | ||
2782 | dev_dbg(di->dev, "VBUS charger drop ended\n"); | 2847 | dev_dbg(di->dev, "VBUS charger drop ended\n"); |
2783 | di->flags.vbus_drop_end = true; | 2848 | di->flags.vbus_drop_end = true; |
2849 | |||
2850 | /* | ||
2851 | * VBUS might have dropped due to bad connection. | ||
2852 | * Schedule a new input limit set to the value SW requests. | ||
2853 | */ | ||
2784 | queue_delayed_work(di->charger_wq, &di->vbus_drop_end_work, | 2854 | queue_delayed_work(di->charger_wq, &di->vbus_drop_end_work, |
2785 | round_jiffies(30 * HZ)); | 2855 | round_jiffies(VBUS_IN_CURR_LIM_RETRY_SET_TIME * HZ)); |
2786 | 2856 | ||
2787 | return IRQ_HANDLED; | 2857 | return IRQ_HANDLED; |
2788 | } | 2858 | } |
@@ -3394,6 +3464,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
3394 | di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; | 3464 | di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; |
3395 | di->usb_chg.enabled = di->bm->usb_enabled; | 3465 | di->usb_chg.enabled = di->bm->usb_enabled; |
3396 | di->usb_chg.external = false; | 3466 | di->usb_chg.external = false; |
3467 | di->usb_state.usb_current = -1; | ||
3397 | 3468 | ||
3398 | /* Create a work queue for the charger */ | 3469 | /* Create a work queue for the charger */ |
3399 | di->charger_wq = | 3470 | di->charger_wq = |