aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/ab8500_charger.c
diff options
context:
space:
mode:
authorAnton Vorontsov <anton@enomsg.org>2013-01-05 20:14:22 -0500
committerAnton Vorontsov <anton@enomsg.org>2013-01-05 20:14:22 -0500
commit240fbe2347f1bb58c45fe07fd7c1e5ed96e2e983 (patch)
tree8481027b056197db888e51eae47a8f95931b84cb /drivers/power/ab8500_charger.c
parent2fbb520d2079186727786b728ebc5bf20fc85520 (diff)
parent215cf5c93d2deda4df38d0c9b2429ab2e86808a5 (diff)
Merge branch 'for-anton' of git://git.linaro.org/people/ljones/linux-3.0-ux500
Diffstat (limited to 'drivers/power/ab8500_charger.c')
-rw-r--r--drivers/power/ab8500_charger.c222
1 files changed, 158 insertions, 64 deletions
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index 3be9c0ee3fc5..e5755f0ba831 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -79,6 +79,9 @@
79/* Lowest charger voltage is 3.39V -> 0x4E */ 79/* Lowest charger voltage is 3.39V -> 0x4E */
80#define LOW_VOLT_REG 0x4E 80#define LOW_VOLT_REG 0x4E
81 81
82/* Step up/down delay in us */
83#define STEP_UDELAY 1000
84
82/* UsbLineStatus register - usb types */ 85/* UsbLineStatus register - usb types */
83enum ab8500_charger_link_status { 86enum ab8500_charger_link_status {
84 USB_STAT_NOT_CONFIGURED, 87 USB_STAT_NOT_CONFIGURED,
@@ -186,7 +189,7 @@ struct ab8500_charger_usb_state {
186 * @autopower_cfg platform specific power config support for "pwron after pwrloss" 189 * @autopower_cfg platform specific power config support for "pwron after pwrloss"
187 * @parent: Pointer to the struct ab8500 190 * @parent: Pointer to the struct ab8500
188 * @gpadc: Pointer to the struct gpadc 191 * @gpadc: Pointer to the struct gpadc
189 * @bat: Pointer to the abx500_bm platform data 192 * @bm: Platform specific battery management information
190 * @flags: Structure for information about events triggered 193 * @flags: Structure for information about events triggered
191 * @usb_state: Structure for usb stack information 194 * @usb_state: Structure for usb stack information
192 * @ac_chg: AC charger power supply 195 * @ac_chg: AC charger power supply
@@ -223,7 +226,7 @@ struct ab8500_charger {
223 bool autopower_cfg; 226 bool autopower_cfg;
224 struct ab8500 *parent; 227 struct ab8500 *parent;
225 struct ab8500_gpadc *gpadc; 228 struct ab8500_gpadc *gpadc;
226 struct abx500_bm_data *bat; 229 struct abx500_bm_data *bm;
227 struct ab8500_charger_event_flags flags; 230 struct ab8500_charger_event_flags flags;
228 struct ab8500_charger_usb_state usb_state; 231 struct ab8500_charger_usb_state usb_state;
229 struct ux500_charger ac_chg; 232 struct ux500_charger ac_chg;
@@ -936,6 +939,88 @@ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di)
936} 939}
937 940
938/** 941/**
942 * ab8500_charger_set_current() - set charger current
943 * @di: pointer to the ab8500_charger structure
944 * @ich: charger current, in mA
945 * @reg: select what charger register to set
946 *
947 * Set charger current.
948 * There is no state machine in the AB to step up/down the charger
949 * current to avoid dips and spikes on MAIN, VBUS and VBAT when
950 * charging is started. Instead we need to implement
951 * this charger current step-up/down here.
952 * Returns error code in case of failure else 0(on success)
953 */
954static int ab8500_charger_set_current(struct ab8500_charger *di,
955 int ich, int reg)
956{
957 int ret, i;
958 int curr_index, prev_curr_index, shift_value;
959 u8 reg_value;
960
961 switch (reg) {
962 case AB8500_MCH_IPT_CURLVL_REG:
963 shift_value = MAIN_CH_INPUT_CURR_SHIFT;
964 curr_index = ab8500_current_to_regval(ich);
965 break;
966 case AB8500_USBCH_IPT_CRNTLVL_REG:
967 shift_value = VBUS_IN_CURR_LIM_SHIFT;
968 curr_index = ab8500_vbus_in_curr_to_regval(ich);
969 break;
970 case AB8500_CH_OPT_CRNTLVL_REG:
971 shift_value = 0;
972 curr_index = ab8500_current_to_regval(ich);
973 break;
974 default:
975 dev_err(di->dev, "%s current register not valid\n", __func__);
976 return -ENXIO;
977 }
978
979 if (curr_index < 0) {
980 dev_err(di->dev, "requested current limit out-of-range\n");
981 return -ENXIO;
982 }
983
984 ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
985 reg, &reg_value);
986 if (ret < 0) {
987 dev_err(di->dev, "%s read failed\n", __func__);
988 return ret;
989 }
990 prev_curr_index = (reg_value >> shift_value);
991
992 /* only update current if it's been changed */
993 if (prev_curr_index == curr_index)
994 return 0;
995
996 dev_dbg(di->dev, "%s set charger current: %d mA for reg: 0x%02x\n",
997 __func__, ich, reg);
998
999 if (prev_curr_index > curr_index) {
1000 for (i = prev_curr_index - 1; i >= curr_index; i--) {
1001 ret = abx500_set_register_interruptible(di->dev,
1002 AB8500_CHARGER, reg, (u8) i << shift_value);
1003 if (ret) {
1004 dev_err(di->dev, "%s write failed\n", __func__);
1005 return ret;
1006 }
1007 usleep_range(STEP_UDELAY, STEP_UDELAY * 2);
1008 }
1009 } else {
1010 for (i = prev_curr_index + 1; i <= curr_index; i++) {
1011 ret = abx500_set_register_interruptible(di->dev,
1012 AB8500_CHARGER, reg, (u8) i << shift_value);
1013 if (ret) {
1014 dev_err(di->dev, "%s write failed\n", __func__);
1015 return ret;
1016 }
1017 usleep_range(STEP_UDELAY, STEP_UDELAY * 2);
1018 }
1019 }
1020 return ret;
1021}
1022
1023/**
939 * ab8500_charger_set_vbus_in_curr() - set VBUS input current limit 1024 * ab8500_charger_set_vbus_in_curr() - set VBUS input current limit
940 * @di: pointer to the ab8500_charger structure 1025 * @di: pointer to the ab8500_charger structure
941 * @ich_in: charger input current limit 1026 * @ich_in: charger input current limit
@@ -946,12 +1031,10 @@ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di)
946static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di, 1031static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di,
947 int ich_in) 1032 int ich_in)
948{ 1033{
949 int ret;
950 int input_curr_index;
951 int min_value; 1034 int min_value;
952 1035
953 /* We should always use to lowest current limit */ 1036 /* We should always use to lowest current limit */
954 min_value = min(di->bat->chg_params->usb_curr_max, ich_in); 1037 min_value = min(di->bm->chg_params->usb_curr_max, ich_in);
955 1038
956 switch (min_value) { 1039 switch (min_value) {
957 case 100: 1040 case 100:
@@ -966,19 +1049,38 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di,
966 break; 1049 break;
967 } 1050 }
968 1051
969 input_curr_index = ab8500_vbus_in_curr_to_regval(min_value); 1052 return ab8500_charger_set_current(di, min_value,
970 if (input_curr_index < 0) { 1053 AB8500_USBCH_IPT_CRNTLVL_REG);
971 dev_err(di->dev, "VBUS input current limit too high\n"); 1054}
972 return -ENXIO;
973 }
974 1055
975 ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, 1056/**
976 AB8500_USBCH_IPT_CRNTLVL_REG, 1057 * ab8500_charger_set_main_in_curr() - set main charger input current
977 input_curr_index << VBUS_IN_CURR_LIM_SHIFT); 1058 * @di: pointer to the ab8500_charger structure
978 if (ret) 1059 * @ich_in: input charger current, in mA
979 dev_err(di->dev, "%s write failed\n", __func__); 1060 *
1061 * Set main charger input current.
1062 * Returns error code in case of failure else 0(on success)
1063 */
1064static int ab8500_charger_set_main_in_curr(struct ab8500_charger *di,
1065 int ich_in)
1066{
1067 return ab8500_charger_set_current(di, ich_in,
1068 AB8500_MCH_IPT_CURLVL_REG);
1069}
980 1070
981 return ret; 1071/**
1072 * ab8500_charger_set_output_curr() - set charger output current
1073 * @di: pointer to the ab8500_charger structure
1074 * @ich_out: output charger current, in mA
1075 *
1076 * Set charger output current.
1077 * Returns error code in case of failure else 0(on success)
1078 */
1079static int ab8500_charger_set_output_curr(struct ab8500_charger *di,
1080 int ich_out)
1081{
1082 return ab8500_charger_set_current(di, ich_out,
1083 AB8500_CH_OPT_CRNTLVL_REG);
982} 1084}
983 1085
984/** 1086/**
@@ -1074,7 +1176,7 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
1074 volt_index = ab8500_voltage_to_regval(vset); 1176 volt_index = ab8500_voltage_to_regval(vset);
1075 curr_index = ab8500_current_to_regval(iset); 1177 curr_index = ab8500_current_to_regval(iset);
1076 input_curr_index = ab8500_current_to_regval( 1178 input_curr_index = ab8500_current_to_regval(
1077 di->bat->chg_params->ac_curr_max); 1179 di->bm->chg_params->ac_curr_max);
1078 if (volt_index < 0 || curr_index < 0 || input_curr_index < 0) { 1180 if (volt_index < 0 || curr_index < 0 || input_curr_index < 0) {
1079 dev_err(di->dev, 1181 dev_err(di->dev,
1080 "Charger voltage or current too high, " 1182 "Charger voltage or current too high, "
@@ -1090,23 +1192,24 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
1090 return ret; 1192 return ret;
1091 } 1193 }
1092 /* MainChInputCurr: current that can be drawn from the charger*/ 1194 /* MainChInputCurr: current that can be drawn from the charger*/
1093 ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, 1195 ret = ab8500_charger_set_main_in_curr(di,
1094 AB8500_MCH_IPT_CURLVL_REG, 1196 di->bm->chg_params->ac_curr_max);
1095 input_curr_index << MAIN_CH_INPUT_CURR_SHIFT);
1096 if (ret) { 1197 if (ret) {
1097 dev_err(di->dev, "%s write failed\n", __func__); 1198 dev_err(di->dev, "%s Failed to set MainChInputCurr\n",
1199 __func__);
1098 return ret; 1200 return ret;
1099 } 1201 }
1100 /* ChOutputCurentLevel: protected output current */ 1202 /* ChOutputCurentLevel: protected output current */
1101 ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, 1203 ret = ab8500_charger_set_output_curr(di, iset);
1102 AB8500_CH_OPT_CRNTLVL_REG, (u8) curr_index);
1103 if (ret) { 1204 if (ret) {
1104 dev_err(di->dev, "%s write failed\n", __func__); 1205 dev_err(di->dev, "%s "
1206 "Failed to set ChOutputCurentLevel\n",
1207 __func__);
1105 return ret; 1208 return ret;
1106 } 1209 }
1107 1210
1108 /* Check if VBAT overshoot control should be enabled */ 1211 /* Check if VBAT overshoot control should be enabled */
1109 if (!di->bat->enable_overshoot) 1212 if (!di->bm->enable_overshoot)
1110 overshoot = MAIN_CH_NO_OVERSHOOT_ENA_N; 1213 overshoot = MAIN_CH_NO_OVERSHOOT_ENA_N;
1111 1214
1112 /* Enable Main Charger */ 1215 /* Enable Main Charger */
@@ -1158,12 +1261,11 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger,
1158 return ret; 1261 return ret;
1159 } 1262 }
1160 1263
1161 ret = abx500_set_register_interruptible(di->dev, 1264 ret = ab8500_charger_set_output_curr(di, 0);
1162 AB8500_CHARGER,
1163 AB8500_CH_OPT_CRNTLVL_REG, CH_OP_CUR_LVL_0P1);
1164 if (ret) { 1265 if (ret) {
1165 dev_err(di->dev, 1266 dev_err(di->dev, "%s "
1166 "%s write failed\n", __func__); 1267 "Failed to set ChOutputCurentLevel\n",
1268 __func__);
1167 return ret; 1269 return ret;
1168 } 1270 }
1169 } else { 1271 } else {
@@ -1266,14 +1368,15 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger,
1266 return ret; 1368 return ret;
1267 } 1369 }
1268 /* ChOutputCurentLevel: protected output current */ 1370 /* ChOutputCurentLevel: protected output current */
1269 ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, 1371 ret = ab8500_charger_set_output_curr(di, ich_out);
1270 AB8500_CH_OPT_CRNTLVL_REG, (u8) curr_index);
1271 if (ret) { 1372 if (ret) {
1272 dev_err(di->dev, "%s write failed\n", __func__); 1373 dev_err(di->dev, "%s "
1374 "Failed to set ChOutputCurentLevel\n",
1375 __func__);
1273 return ret; 1376 return ret;
1274 } 1377 }
1275 /* Check if VBAT overshoot control should be enabled */ 1378 /* Check if VBAT overshoot control should be enabled */
1276 if (!di->bat->enable_overshoot) 1379 if (!di->bm->enable_overshoot)
1277 overshoot = USB_CHG_NO_OVERSHOOT_ENA_N; 1380 overshoot = USB_CHG_NO_OVERSHOOT_ENA_N;
1278 1381
1279 /* Enable USB Charger */ 1382 /* Enable USB Charger */
@@ -1366,7 +1469,6 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
1366 int ich_out) 1469 int ich_out)
1367{ 1470{
1368 int ret; 1471 int ret;
1369 int curr_index;
1370 struct ab8500_charger *di; 1472 struct ab8500_charger *di;
1371 1473
1372 if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS) 1474 if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS)
@@ -1376,18 +1478,11 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
1376 else 1478 else
1377 return -ENXIO; 1479 return -ENXIO;
1378 1480
1379 curr_index = ab8500_current_to_regval(ich_out); 1481 ret = ab8500_charger_set_output_curr(di, ich_out);
1380 if (curr_index < 0) {
1381 dev_err(di->dev,
1382 "Charger current too high, "
1383 "charging not started\n");
1384 return -ENXIO;
1385 }
1386
1387 ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1388 AB8500_CH_OPT_CRNTLVL_REG, (u8) curr_index);
1389 if (ret) { 1482 if (ret) {
1390 dev_err(di->dev, "%s write failed\n", __func__); 1483 dev_err(di->dev, "%s "
1484 "Failed to set ChOutputCurentLevel\n",
1485 __func__);
1391 return ret; 1486 return ret;
1392 } 1487 }
1393 1488
@@ -2359,8 +2454,8 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di)
2359 ret = abx500_set_register_interruptible(di->dev, 2454 ret = abx500_set_register_interruptible(di->dev,
2360 AB8500_RTC, 2455 AB8500_RTC,
2361 AB8500_RTC_BACKUP_CHG_REG, 2456 AB8500_RTC_BACKUP_CHG_REG,
2362 di->bat->bkup_bat_v | 2457 di->bm->bkup_bat_v |
2363 di->bat->bkup_bat_i); 2458 di->bm->bkup_bat_i);
2364 if (ret) { 2459 if (ret) {
2365 dev_err(di->dev, "failed to setup backup battery charging\n"); 2460 dev_err(di->dev, "failed to setup backup battery charging\n");
2366 goto out; 2461 goto out;
@@ -2541,6 +2636,7 @@ static char *supply_interface[] = {
2541static int ab8500_charger_probe(struct platform_device *pdev) 2636static int ab8500_charger_probe(struct platform_device *pdev)
2542{ 2637{
2543 struct device_node *np = pdev->dev.of_node; 2638 struct device_node *np = pdev->dev.of_node;
2639 struct abx500_bm_data *plat = pdev->dev.platform_data;
2544 struct ab8500_charger *di; 2640 struct ab8500_charger *di;
2545 int irq, i, charger_status, ret = 0; 2641 int irq, i, charger_status, ret = 0;
2546 2642
@@ -2549,24 +2645,22 @@ static int ab8500_charger_probe(struct platform_device *pdev)
2549 dev_err(&pdev->dev, "%s no mem for ab8500_charger\n", __func__); 2645 dev_err(&pdev->dev, "%s no mem for ab8500_charger\n", __func__);
2550 return -ENOMEM; 2646 return -ENOMEM;
2551 } 2647 }
2552 di->bat = pdev->mfd_cell->platform_data; 2648
2553 if (!di->bat) { 2649 if (!plat) {
2554 if (np) { 2650 dev_err(&pdev->dev, "no battery management data supplied\n");
2555 ret = bmdevs_of_probe(&pdev->dev, np, &di->bat); 2651 return -EINVAL;
2556 if (ret) { 2652 }
2557 dev_err(&pdev->dev, 2653 di->bm = plat;
2558 "failed to get battery information\n"); 2654
2559 return ret; 2655 if (np) {
2560 } 2656 ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm);
2561 di->autopower_cfg = of_property_read_bool(np, "autopower_cfg"); 2657 if (ret) {
2562 } else { 2658 dev_err(&pdev->dev, "failed to get battery information\n");
2563 dev_err(&pdev->dev, "missing dt node for ab8500_charger\n"); 2659 return ret;
2564 return -EINVAL;
2565 } 2660 }
2566 } else { 2661 di->autopower_cfg = of_property_read_bool(np, "autopower_cfg");
2567 dev_info(&pdev->dev, "falling back to legacy platform data\n"); 2662 } else
2568 di->autopower_cfg = false; 2663 di->autopower_cfg = false;
2569 }
2570 2664
2571 /* get parent data */ 2665 /* get parent data */
2572 di->dev = &pdev->dev; 2666 di->dev = &pdev->dev;