diff options
Diffstat (limited to 'drivers/power/ab8500_charger.c')
-rw-r--r-- | drivers/power/ab8500_charger.c | 270 |
1 files changed, 112 insertions, 158 deletions
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index f249a65b02e1..6089ee7bc609 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c | |||
@@ -57,7 +57,9 @@ | |||
57 | 57 | ||
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 AB8540_VBUS_IN_CURR_LIM_SHIFT 2 | ||
60 | #define AUTO_VBUS_IN_CURR_LIM_SHIFT 4 | 61 | #define AUTO_VBUS_IN_CURR_LIM_SHIFT 4 |
62 | #define AB8540_AUTO_VBUS_IN_CURR_MASK 0x3F | ||
61 | #define VBUS_IN_CURR_LIM_RETRY_SET_TIME 30 /* seconds */ | 63 | #define VBUS_IN_CURR_LIM_RETRY_SET_TIME 30 /* seconds */ |
62 | 64 | ||
63 | #define LED_INDICATOR_PWM_ENA 0x01 | 65 | #define LED_INDICATOR_PWM_ENA 0x01 |
@@ -82,6 +84,7 @@ | |||
82 | #define AB8500_USB_LINK_STATUS 0x78 | 84 | #define AB8500_USB_LINK_STATUS 0x78 |
83 | #define AB8505_USB_LINK_STATUS 0xF8 | 85 | #define AB8505_USB_LINK_STATUS 0xF8 |
84 | #define AB8500_STD_HOST_SUSP 0x18 | 86 | #define AB8500_STD_HOST_SUSP 0x18 |
87 | #define USB_LINK_STATUS_SHIFT 3 | ||
85 | 88 | ||
86 | /* Watchdog timeout constant */ | 89 | /* Watchdog timeout constant */ |
87 | #define WD_TIMER 0x30 /* 4min */ | 90 | #define WD_TIMER 0x30 /* 4min */ |
@@ -751,8 +754,7 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
751 | "VBUS has collapsed\n"); | 754 | "VBUS has collapsed\n"); |
752 | ret = -ENXIO; | 755 | ret = -ENXIO; |
753 | break; | 756 | break; |
754 | } | 757 | } else { |
755 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | ||
756 | dev_dbg(di->dev, "USB Type - Charging not allowed\n"); | 758 | dev_dbg(di->dev, "USB Type - Charging not allowed\n"); |
757 | di->max_usb_in_curr.usb_type_max = | 759 | di->max_usb_in_curr.usb_type_max = |
758 | USB_CH_IP_CUR_LVL_0P05; | 760 | USB_CH_IP_CUR_LVL_0P05; |
@@ -807,30 +809,22 @@ static int ab8500_charger_read_usb_type(struct ab8500_charger *di) | |||
807 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); | 809 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); |
808 | return ret; | 810 | return ret; |
809 | } | 811 | } |
810 | if (is_ab8500(di->parent)) { | 812 | if (is_ab8500(di->parent)) |
811 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, | 813 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, |
812 | AB8500_USB_LINE_STAT_REG, &val); | 814 | AB8500_USB_LINE_STAT_REG, &val); |
813 | } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | 815 | else |
814 | ret = abx500_get_register_interruptible(di->dev, | 816 | ret = abx500_get_register_interruptible(di->dev, |
815 | AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); | 817 | AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); |
816 | } else { | ||
817 | dev_err(di->dev, "%s unsupported analog baseband\n", __func__); | ||
818 | return -ENXIO; | ||
819 | } | ||
820 | if (ret < 0) { | 818 | if (ret < 0) { |
821 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); | 819 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); |
822 | return ret; | 820 | return ret; |
823 | } | 821 | } |
824 | 822 | ||
825 | /* get the USB type */ | 823 | /* get the USB type */ |
826 | if (is_ab8500(di->parent)) { | 824 | if (is_ab8500(di->parent)) |
827 | val = (val & AB8500_USB_LINK_STATUS) >> 3; | 825 | val = (val & AB8500_USB_LINK_STATUS) >> USB_LINK_STATUS_SHIFT; |
828 | } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | 826 | else |
829 | val = (val & AB8505_USB_LINK_STATUS) >> 3; | 827 | val = (val & AB8505_USB_LINK_STATUS) >> USB_LINK_STATUS_SHIFT; |
830 | } else { | ||
831 | dev_err(di->dev, "%s unsupported analog baseband\n", __func__); | ||
832 | return -ENXIO; | ||
833 | } | ||
834 | ret = ab8500_charger_max_usb_curr(di, | 828 | ret = ab8500_charger_max_usb_curr(di, |
835 | (enum ab8500_charger_link_status) val); | 829 | (enum ab8500_charger_link_status) val); |
836 | 830 | ||
@@ -866,16 +860,12 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) | |||
866 | return ret; | 860 | return ret; |
867 | } | 861 | } |
868 | 862 | ||
869 | if (is_ab8500(di->parent)) { | 863 | if (is_ab8500(di->parent)) |
870 | ret = abx500_get_register_interruptible(di->dev, | 864 | ret = abx500_get_register_interruptible(di->dev, |
871 | AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); | 865 | AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); |
872 | } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | 866 | else |
873 | ret = abx500_get_register_interruptible(di->dev, | 867 | ret = abx500_get_register_interruptible(di->dev, |
874 | AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); | 868 | AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); |
875 | } else { | ||
876 | dev_err(di->dev, "%s unsupported analog baseband\n", __func__); | ||
877 | return -ENXIO; | ||
878 | } | ||
879 | if (ret < 0) { | 869 | if (ret < 0) { |
880 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); | 870 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); |
881 | return ret; | 871 | return ret; |
@@ -889,14 +879,12 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) | |||
889 | */ | 879 | */ |
890 | 880 | ||
891 | /* get the USB type */ | 881 | /* get the USB type */ |
892 | if (is_ab8500(di->parent)) { | 882 | if (is_ab8500(di->parent)) |
893 | val = (val & AB8500_USB_LINK_STATUS) >> 3; | 883 | val = (val & AB8500_USB_LINK_STATUS) >> |
894 | } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | 884 | USB_LINK_STATUS_SHIFT; |
895 | val = (val & AB8505_USB_LINK_STATUS) >> 3; | 885 | else |
896 | } else { | 886 | val = (val & AB8505_USB_LINK_STATUS) >> |
897 | dev_err(di->dev, "%s unsupported analog baseband\n", __func__); | 887 | USB_LINK_STATUS_SHIFT; |
898 | return -ENXIO; | ||
899 | } | ||
900 | if (val) | 888 | if (val) |
901 | break; | 889 | break; |
902 | } | 890 | } |
@@ -991,51 +979,6 @@ static int ab8500_charger_voltage_map[] = { | |||
991 | 4600 , | 979 | 4600 , |
992 | }; | 980 | }; |
993 | 981 | ||
994 | /* | ||
995 | * This array maps the raw hex value to charger current used by the AB8500 | ||
996 | * Values taken from the UM0836 | ||
997 | */ | ||
998 | static int ab8500_charger_current_map[] = { | ||
999 | 100 , | ||
1000 | 200 , | ||
1001 | 300 , | ||
1002 | 400 , | ||
1003 | 500 , | ||
1004 | 600 , | ||
1005 | 700 , | ||
1006 | 800 , | ||
1007 | 900 , | ||
1008 | 1000 , | ||
1009 | 1100 , | ||
1010 | 1200 , | ||
1011 | 1300 , | ||
1012 | 1400 , | ||
1013 | 1500 , | ||
1014 | }; | ||
1015 | |||
1016 | /* | ||
1017 | * This array maps the raw hex value to VBUS input current used by the AB8500 | ||
1018 | * Values taken from the UM0836 | ||
1019 | */ | ||
1020 | static int ab8500_charger_vbus_in_curr_map[] = { | ||
1021 | USB_CH_IP_CUR_LVL_0P05, | ||
1022 | USB_CH_IP_CUR_LVL_0P09, | ||
1023 | USB_CH_IP_CUR_LVL_0P19, | ||
1024 | USB_CH_IP_CUR_LVL_0P29, | ||
1025 | USB_CH_IP_CUR_LVL_0P38, | ||
1026 | USB_CH_IP_CUR_LVL_0P45, | ||
1027 | USB_CH_IP_CUR_LVL_0P5, | ||
1028 | USB_CH_IP_CUR_LVL_0P6, | ||
1029 | USB_CH_IP_CUR_LVL_0P7, | ||
1030 | USB_CH_IP_CUR_LVL_0P8, | ||
1031 | USB_CH_IP_CUR_LVL_0P9, | ||
1032 | USB_CH_IP_CUR_LVL_1P0, | ||
1033 | USB_CH_IP_CUR_LVL_1P1, | ||
1034 | USB_CH_IP_CUR_LVL_1P3, | ||
1035 | USB_CH_IP_CUR_LVL_1P4, | ||
1036 | USB_CH_IP_CUR_LVL_1P5, | ||
1037 | }; | ||
1038 | |||
1039 | static int ab8500_voltage_to_regval(int voltage) | 982 | static int ab8500_voltage_to_regval(int voltage) |
1040 | { | 983 | { |
1041 | int i; | 984 | int i; |
@@ -1057,41 +1000,41 @@ static int ab8500_voltage_to_regval(int voltage) | |||
1057 | return -1; | 1000 | return -1; |
1058 | } | 1001 | } |
1059 | 1002 | ||
1060 | static int ab8500_current_to_regval(int curr) | 1003 | static int ab8500_current_to_regval(struct ab8500_charger *di, int curr) |
1061 | { | 1004 | { |
1062 | int i; | 1005 | int i; |
1063 | 1006 | ||
1064 | if (curr < ab8500_charger_current_map[0]) | 1007 | if (curr < di->bm->chg_output_curr[0]) |
1065 | return 0; | 1008 | return 0; |
1066 | 1009 | ||
1067 | for (i = 0; i < ARRAY_SIZE(ab8500_charger_current_map); i++) { | 1010 | for (i = 0; i < di->bm->n_chg_out_curr; i++) { |
1068 | if (curr < ab8500_charger_current_map[i]) | 1011 | if (curr < di->bm->chg_output_curr[i]) |
1069 | return i - 1; | 1012 | return i - 1; |
1070 | } | 1013 | } |
1071 | 1014 | ||
1072 | /* If not last element, return error */ | 1015 | /* If not last element, return error */ |
1073 | i = ARRAY_SIZE(ab8500_charger_current_map) - 1; | 1016 | i = di->bm->n_chg_out_curr - 1; |
1074 | if (curr == ab8500_charger_current_map[i]) | 1017 | if (curr == di->bm->chg_output_curr[i]) |
1075 | return i; | 1018 | return i; |
1076 | else | 1019 | else |
1077 | return -1; | 1020 | return -1; |
1078 | } | 1021 | } |
1079 | 1022 | ||
1080 | static int ab8500_vbus_in_curr_to_regval(int curr) | 1023 | static int ab8500_vbus_in_curr_to_regval(struct ab8500_charger *di, int curr) |
1081 | { | 1024 | { |
1082 | int i; | 1025 | int i; |
1083 | 1026 | ||
1084 | if (curr < ab8500_charger_vbus_in_curr_map[0]) | 1027 | if (curr < di->bm->chg_input_curr[0]) |
1085 | return 0; | 1028 | return 0; |
1086 | 1029 | ||
1087 | for (i = 0; i < ARRAY_SIZE(ab8500_charger_vbus_in_curr_map); i++) { | 1030 | for (i = 0; i < di->bm->n_chg_in_curr; i++) { |
1088 | if (curr < ab8500_charger_vbus_in_curr_map[i]) | 1031 | if (curr < di->bm->chg_input_curr[i]) |
1089 | return i - 1; | 1032 | return i - 1; |
1090 | } | 1033 | } |
1091 | 1034 | ||
1092 | /* If not last element, return error */ | 1035 | /* If not last element, return error */ |
1093 | i = ARRAY_SIZE(ab8500_charger_vbus_in_curr_map) - 1; | 1036 | i = di->bm->n_chg_in_curr - 1; |
1094 | if (curr == ab8500_charger_vbus_in_curr_map[i]) | 1037 | if (curr == di->bm->chg_input_curr[i]) |
1095 | return i; | 1038 | return i; |
1096 | else | 1039 | else |
1097 | return -1; | 1040 | return -1; |
@@ -1169,7 +1112,7 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, | |||
1169 | int ich, int reg) | 1112 | int ich, int reg) |
1170 | { | 1113 | { |
1171 | int ret = 0; | 1114 | int ret = 0; |
1172 | int auto_curr_index, curr_index, prev_curr_index, shift_value, i; | 1115 | int curr_index, prev_curr_index, shift_value, i; |
1173 | u8 reg_value; | 1116 | u8 reg_value; |
1174 | u32 step_udelay; | 1117 | u32 step_udelay; |
1175 | bool no_stepping = false; | 1118 | bool no_stepping = false; |
@@ -1187,39 +1130,27 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, | |||
1187 | case AB8500_MCH_IPT_CURLVL_REG: | 1130 | case AB8500_MCH_IPT_CURLVL_REG: |
1188 | shift_value = MAIN_CH_INPUT_CURR_SHIFT; | 1131 | shift_value = MAIN_CH_INPUT_CURR_SHIFT; |
1189 | prev_curr_index = (reg_value >> shift_value); | 1132 | prev_curr_index = (reg_value >> shift_value); |
1190 | curr_index = ab8500_current_to_regval(ich); | 1133 | curr_index = ab8500_current_to_regval(di, ich); |
1191 | step_udelay = STEP_UDELAY; | 1134 | step_udelay = STEP_UDELAY; |
1192 | if (!di->ac.charger_connected) | 1135 | if (!di->ac.charger_connected) |
1193 | no_stepping = true; | 1136 | no_stepping = true; |
1194 | break; | 1137 | break; |
1195 | case AB8500_USBCH_IPT_CRNTLVL_REG: | 1138 | case AB8500_USBCH_IPT_CRNTLVL_REG: |
1196 | shift_value = VBUS_IN_CURR_LIM_SHIFT; | 1139 | if (is_ab8540(di->parent)) |
1140 | shift_value = AB8540_VBUS_IN_CURR_LIM_SHIFT; | ||
1141 | else | ||
1142 | shift_value = VBUS_IN_CURR_LIM_SHIFT; | ||
1197 | prev_curr_index = (reg_value >> shift_value); | 1143 | prev_curr_index = (reg_value >> shift_value); |
1198 | curr_index = ab8500_vbus_in_curr_to_regval(ich); | 1144 | curr_index = ab8500_vbus_in_curr_to_regval(di, ich); |
1199 | step_udelay = STEP_UDELAY * 100; | 1145 | step_udelay = STEP_UDELAY * 100; |
1200 | 1146 | ||
1201 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
1202 | AB8500_CH_USBCH_STAT2_REG, ®_value); | ||
1203 | if (ret < 0) { | ||
1204 | dev_err(di->dev, "%s read failed\n", __func__); | ||
1205 | goto exit_set_current; | ||
1206 | } | ||
1207 | auto_curr_index = | ||
1208 | reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT; | ||
1209 | |||
1210 | dev_dbg(di->dev, "%s Auto VBUS curr is %d mA\n", | ||
1211 | __func__, | ||
1212 | ab8500_charger_vbus_in_curr_map[auto_curr_index]); | ||
1213 | |||
1214 | prev_curr_index = min(prev_curr_index, auto_curr_index); | ||
1215 | |||
1216 | if (!di->usb.charger_connected) | 1147 | if (!di->usb.charger_connected) |
1217 | no_stepping = true; | 1148 | no_stepping = true; |
1218 | break; | 1149 | break; |
1219 | case AB8500_CH_OPT_CRNTLVL_REG: | 1150 | case AB8500_CH_OPT_CRNTLVL_REG: |
1220 | shift_value = 0; | 1151 | shift_value = 0; |
1221 | prev_curr_index = (reg_value >> shift_value); | 1152 | prev_curr_index = (reg_value >> shift_value); |
1222 | curr_index = ab8500_current_to_regval(ich); | 1153 | curr_index = ab8500_current_to_regval(di, ich); |
1223 | step_udelay = STEP_UDELAY; | 1154 | step_udelay = STEP_UDELAY; |
1224 | if (curr_index && (curr_index - prev_curr_index) > 1) | 1155 | if (curr_index && (curr_index - prev_curr_index) > 1) |
1225 | step_udelay *= 100; | 1156 | step_udelay *= 100; |
@@ -1459,8 +1390,8 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, | |||
1459 | 1390 | ||
1460 | /* Check if the requested voltage or current is valid */ | 1391 | /* Check if the requested voltage or current is valid */ |
1461 | volt_index = ab8500_voltage_to_regval(vset); | 1392 | volt_index = ab8500_voltage_to_regval(vset); |
1462 | curr_index = ab8500_current_to_regval(iset); | 1393 | curr_index = ab8500_current_to_regval(di, iset); |
1463 | input_curr_index = ab8500_current_to_regval( | 1394 | input_curr_index = ab8500_current_to_regval(di, |
1464 | di->bm->chg_params->ac_curr_max); | 1395 | di->bm->chg_params->ac_curr_max); |
1465 | if (volt_index < 0 || curr_index < 0 || input_curr_index < 0) { | 1396 | if (volt_index < 0 || curr_index < 0 || input_curr_index < 0) { |
1466 | dev_err(di->dev, | 1397 | dev_err(di->dev, |
@@ -1631,7 +1562,7 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, | |||
1631 | 1562 | ||
1632 | /* Check if the requested voltage or current is valid */ | 1563 | /* Check if the requested voltage or current is valid */ |
1633 | volt_index = ab8500_voltage_to_regval(vset); | 1564 | volt_index = ab8500_voltage_to_regval(vset); |
1634 | curr_index = ab8500_current_to_regval(ich_out); | 1565 | curr_index = ab8500_current_to_regval(di, ich_out); |
1635 | if (volt_index < 0 || curr_index < 0) { | 1566 | if (volt_index < 0 || curr_index < 0) { |
1636 | dev_err(di->dev, | 1567 | dev_err(di->dev, |
1637 | "Charger voltage or current too high, " | 1568 | "Charger voltage or current too high, " |
@@ -2396,18 +2327,21 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) | |||
2396 | else | 2327 | else |
2397 | dev_dbg(di->dev, "Error reading USB link status\n"); | 2328 | dev_dbg(di->dev, "Error reading USB link status\n"); |
2398 | 2329 | ||
2399 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) | 2330 | if (is_ab8500(di->parent)) |
2400 | link_status = AB8505_USB_LINK_STATUS; | ||
2401 | else | ||
2402 | link_status = AB8500_USB_LINK_STATUS; | 2331 | link_status = AB8500_USB_LINK_STATUS; |
2332 | else | ||
2333 | link_status = AB8505_USB_LINK_STATUS; | ||
2403 | 2334 | ||
2404 | if (detected_chargers & USB_PW_CONN) { | 2335 | if (detected_chargers & USB_PW_CONN) { |
2405 | if (((val & link_status) >> 3) == USB_STAT_NOT_VALID_LINK && | 2336 | if (((val & link_status) >> USB_LINK_STATUS_SHIFT) == |
2337 | USB_STAT_NOT_VALID_LINK && | ||
2406 | di->invalid_charger_detect_state == 0) { | 2338 | di->invalid_charger_detect_state == 0) { |
2407 | dev_dbg(di->dev, "Invalid charger detected, state= 0\n"); | 2339 | dev_dbg(di->dev, |
2340 | "Invalid charger detected, state= 0\n"); | ||
2408 | /*Enable charger*/ | 2341 | /*Enable charger*/ |
2409 | abx500_mask_and_set_register_interruptible(di->dev, | 2342 | abx500_mask_and_set_register_interruptible(di->dev, |
2410 | AB8500_CHARGER, AB8500_USBCH_CTRL1_REG, 0x01, 0x01); | 2343 | AB8500_CHARGER, AB8500_USBCH_CTRL1_REG, |
2344 | USB_CH_ENA, USB_CH_ENA); | ||
2411 | /*Enable charger detection*/ | 2345 | /*Enable charger detection*/ |
2412 | abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, | 2346 | abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, |
2413 | AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x01); | 2347 | AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x01); |
@@ -2417,15 +2351,17 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) | |||
2417 | 2351 | ||
2418 | } | 2352 | } |
2419 | if (di->invalid_charger_detect_state == 1) { | 2353 | if (di->invalid_charger_detect_state == 1) { |
2420 | dev_dbg(di->dev, "Invalid charger detected, state= 1\n"); | 2354 | dev_dbg(di->dev, |
2355 | "Invalid charger detected, state= 1\n"); | ||
2421 | /*Stop charger detection*/ | 2356 | /*Stop charger detection*/ |
2422 | abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, | 2357 | abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, |
2423 | AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x00); | 2358 | AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x00); |
2424 | /*Check link status*/ | 2359 | /*Check link status*/ |
2425 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, | 2360 | ret = abx500_get_register_interruptible(di->dev, |
2361 | AB8500_USB, | ||
2426 | AB8500_USB_LINE_STAT_REG, &val); | 2362 | AB8500_USB_LINE_STAT_REG, &val); |
2427 | dev_dbg(di->dev, "USB link status= 0x%02x\n", | 2363 | dev_dbg(di->dev, "USB link status= 0x%02x\n", |
2428 | (val & link_status) >> 3); | 2364 | (val & link_status) >> USB_LINK_STATUS_SHIFT); |
2429 | di->invalid_charger_detect_state = 2; | 2365 | di->invalid_charger_detect_state = 2; |
2430 | } | 2366 | } |
2431 | } else { | 2367 | } else { |
@@ -2741,7 +2677,7 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) | |||
2741 | { | 2677 | { |
2742 | struct ab8500_charger *di = container_of(work, | 2678 | struct ab8500_charger *di = container_of(work, |
2743 | struct ab8500_charger, vbus_drop_end_work.work); | 2679 | struct ab8500_charger, vbus_drop_end_work.work); |
2744 | int ret; | 2680 | int ret, curr; |
2745 | u8 reg_value; | 2681 | u8 reg_value; |
2746 | 2682 | ||
2747 | di->flags.vbus_drop_end = false; | 2683 | di->flags.vbus_drop_end = false; |
@@ -2749,32 +2685,41 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) | |||
2749 | /* Reset the drop counter */ | 2685 | /* Reset the drop counter */ |
2750 | abx500_set_register_interruptible(di->dev, | 2686 | abx500_set_register_interruptible(di->dev, |
2751 | AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01); | 2687 | AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01); |
2752 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | 2688 | |
2753 | AB8500_CH_USBCH_STAT2_REG, | 2689 | if (is_ab8540(di->parent)) |
2754 | ®_value); | 2690 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, |
2691 | AB8540_CH_USBCH_STAT3_REG, ®_value); | ||
2692 | else | ||
2693 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
2694 | AB8500_CH_USBCH_STAT2_REG, ®_value); | ||
2755 | if (ret < 0) { | 2695 | if (ret < 0) { |
2756 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); | 2696 | dev_err(di->dev, "%s read failed\n", __func__); |
2757 | } else { | 2697 | return; |
2758 | int curr = ab8500_charger_vbus_in_curr_map[ | 2698 | } |
2699 | |||
2700 | if (is_ab8540(di->parent)) | ||
2701 | curr = di->bm->chg_input_curr[ | ||
2702 | reg_value & AB8540_AUTO_VBUS_IN_CURR_MASK]; | ||
2703 | else | ||
2704 | curr = di->bm->chg_input_curr[ | ||
2759 | reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT]; | 2705 | reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT]; |
2760 | if (di->max_usb_in_curr.calculated_max != curr) { | 2706 | |
2761 | /* USB source is collapsing */ | 2707 | if (di->max_usb_in_curr.calculated_max != curr) { |
2762 | di->max_usb_in_curr.calculated_max = curr; | 2708 | /* USB source is collapsing */ |
2763 | dev_dbg(di->dev, | 2709 | di->max_usb_in_curr.calculated_max = curr; |
2764 | "VBUS input current limiting to %d mA\n", | 2710 | dev_dbg(di->dev, |
2765 | di->max_usb_in_curr.calculated_max); | 2711 | "VBUS input current limiting to %d mA\n", |
2766 | } else { | 2712 | di->max_usb_in_curr.calculated_max); |
2767 | /* | 2713 | } else { |
2768 | * USB source can not give more than this amount. | 2714 | /* |
2769 | * Taking more will collapse the source. | 2715 | * USB source can not give more than this amount. |
2770 | */ | 2716 | * Taking more will collapse the source. |
2771 | di->max_usb_in_curr.set_max = | 2717 | */ |
2772 | di->max_usb_in_curr.calculated_max; | 2718 | di->max_usb_in_curr.set_max = |
2773 | dev_dbg(di->dev, | 2719 | di->max_usb_in_curr.calculated_max; |
2774 | "VBUS input current limited to %d mA\n", | 2720 | dev_dbg(di->dev, |
2775 | di->max_usb_in_curr.set_max); | 2721 | "VBUS input current limited to %d mA\n", |
2776 | return; | 2722 | di->max_usb_in_curr.set_max); |
2777 | } | ||
2778 | } | 2723 | } |
2779 | 2724 | ||
2780 | if (di->usb.charger_connected) | 2725 | if (di->usb.charger_connected) |
@@ -3134,9 +3079,14 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
3134 | goto out; | 3079 | goto out; |
3135 | } | 3080 | } |
3136 | 3081 | ||
3137 | ret = abx500_set_register_interruptible(di->dev, | 3082 | if (is_ab8540(di->parent)) |
3138 | AB8500_CHARGER, | 3083 | ret = abx500_set_register_interruptible(di->dev, |
3139 | AB8500_CH_OPT_CRNTLVL_MAX_REG, CH_OP_CUR_LVL_1P6); | 3084 | AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG, |
3085 | CH_OP_CUR_LVL_2P); | ||
3086 | else | ||
3087 | ret = abx500_set_register_interruptible(di->dev, | ||
3088 | AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG, | ||
3089 | CH_OP_CUR_LVL_1P6); | ||
3140 | if (ret) { | 3090 | if (ret) { |
3141 | dev_err(di->dev, | 3091 | dev_err(di->dev, |
3142 | "failed to set CH_OPT_CRNTLVL_MAX_REG\n"); | 3092 | "failed to set CH_OPT_CRNTLVL_MAX_REG\n"); |
@@ -3144,7 +3094,8 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
3144 | } | 3094 | } |
3145 | } | 3095 | } |
3146 | 3096 | ||
3147 | if (is_ab9540_2p0(di->parent) || is_ab8505_2p0(di->parent)) | 3097 | if (is_ab9540_2p0(di->parent) || is_ab9540_3p0(di->parent) |
3098 | || is_ab8505_2p0(di->parent) || is_ab8540(di->parent)) | ||
3148 | ret = abx500_mask_and_set_register_interruptible(di->dev, | 3099 | ret = abx500_mask_and_set_register_interruptible(di->dev, |
3149 | AB8500_CHARGER, | 3100 | AB8500_CHARGER, |
3150 | AB8500_USBCH_CTRL2_REG, | 3101 | AB8500_USBCH_CTRL2_REG, |
@@ -3250,7 +3201,8 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
3250 | AB8500_RTC_CTRL1_REG, | 3201 | AB8500_RTC_CTRL1_REG, |
3251 | bup_vch_range | vbup33_vrtcn); | 3202 | bup_vch_range | vbup33_vrtcn); |
3252 | if (ret) { | 3203 | if (ret) { |
3253 | dev_err(di->dev, "failed to setup backup battery charging\n"); | 3204 | dev_err(di->dev, |
3205 | "failed to setup backup battery charging\n"); | ||
3254 | goto out; | 3206 | goto out; |
3255 | } | 3207 | } |
3256 | } | 3208 | } |
@@ -3267,14 +3219,16 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
3267 | AB8500_CHARGER, AB8540_USB_PP_MODE_REG, | 3219 | AB8500_CHARGER, AB8540_USB_PP_MODE_REG, |
3268 | BUS_VSYS_VOL_SELECT_MASK, BUS_VSYS_VOL_SELECT_3P6V); | 3220 | BUS_VSYS_VOL_SELECT_MASK, BUS_VSYS_VOL_SELECT_3P6V); |
3269 | if (ret) { | 3221 | if (ret) { |
3270 | dev_err(di->dev, "failed to setup usb power path vsys voltage\n"); | 3222 | dev_err(di->dev, |
3223 | "failed to setup usb power path vsys voltage\n"); | ||
3271 | goto out; | 3224 | goto out; |
3272 | } | 3225 | } |
3273 | ret = abx500_mask_and_set_register_interruptible(di->dev, | 3226 | ret = abx500_mask_and_set_register_interruptible(di->dev, |
3274 | AB8500_CHARGER, AB8540_USB_PP_CHR_REG, | 3227 | AB8500_CHARGER, AB8540_USB_PP_CHR_REG, |
3275 | BUS_PP_PRECHG_CURRENT_MASK, 0); | 3228 | BUS_PP_PRECHG_CURRENT_MASK, 0); |
3276 | if (ret) { | 3229 | if (ret) { |
3277 | dev_err(di->dev, "failed to setup usb power path prechage current\n"); | 3230 | dev_err(di->dev, |
3231 | "failed to setup usb power path prechage current\n"); | ||
3278 | goto out; | 3232 | goto out; |
3279 | } | 3233 | } |
3280 | } | 3234 | } |
@@ -3537,8 +3491,8 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
3537 | di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current; | 3491 | di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current; |
3538 | di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ | 3492 | di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ |
3539 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; | 3493 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; |
3540 | di->ac_chg.max_out_curr = ab8500_charger_current_map[ | 3494 | di->ac_chg.max_out_curr = |
3541 | ARRAY_SIZE(ab8500_charger_current_map) - 1]; | 3495 | di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1]; |
3542 | di->ac_chg.wdt_refresh = CHG_WD_INTERVAL; | 3496 | di->ac_chg.wdt_refresh = CHG_WD_INTERVAL; |
3543 | di->ac_chg.enabled = di->bm->ac_enabled; | 3497 | di->ac_chg.enabled = di->bm->ac_enabled; |
3544 | di->ac_chg.external = false; | 3498 | di->ac_chg.external = false; |
@@ -3566,8 +3520,8 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
3566 | di->usb_chg.ops.pre_chg_enable = &ab8540_charger_usb_pre_chg_enable; | 3520 | di->usb_chg.ops.pre_chg_enable = &ab8540_charger_usb_pre_chg_enable; |
3567 | di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ | 3521 | di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ |
3568 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; | 3522 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; |
3569 | di->usb_chg.max_out_curr = ab8500_charger_current_map[ | 3523 | di->usb_chg.max_out_curr = |
3570 | ARRAY_SIZE(ab8500_charger_current_map) - 1]; | 3524 | di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1]; |
3571 | di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; | 3525 | di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; |
3572 | di->usb_chg.enabled = di->bm->usb_enabled; | 3526 | di->usb_chg.enabled = di->bm->usb_enabled; |
3573 | di->usb_chg.external = false; | 3527 | di->usb_chg.external = false; |