diff options
-rw-r--r-- | drivers/power/ab8500_bmdata.c | 91 | ||||
-rw-r--r-- | drivers/power/ab8500_btemp.c | 42 | ||||
-rw-r--r-- | drivers/power/ab8500_charger.c | 270 | ||||
-rw-r--r-- | include/linux/mfd/abx500.h | 10 | ||||
-rw-r--r-- | include/linux/mfd/abx500/ab8500-bm.h | 5 |
5 files changed, 248 insertions, 170 deletions
diff --git a/drivers/power/ab8500_bmdata.c b/drivers/power/ab8500_bmdata.c index e8759763fbe0..85742a6d29ff 100644 --- a/drivers/power/ab8500_bmdata.c +++ b/drivers/power/ab8500_bmdata.c | |||
@@ -414,13 +414,20 @@ static const struct abx500_fg_parameters fg = { | |||
414 | .pcut_debounce_time = 2, | 414 | .pcut_debounce_time = 2, |
415 | }; | 415 | }; |
416 | 416 | ||
417 | static const struct abx500_maxim_parameters maxi_params = { | 417 | static const struct abx500_maxim_parameters ab8500_maxi_params = { |
418 | .ena_maxi = true, | 418 | .ena_maxi = true, |
419 | .chg_curr = 910, | 419 | .chg_curr = 910, |
420 | .wait_cycles = 10, | 420 | .wait_cycles = 10, |
421 | .charger_curr_step = 100, | 421 | .charger_curr_step = 100, |
422 | }; | 422 | }; |
423 | 423 | ||
424 | static const struct abx500_maxim_parameters abx540_maxi_params = { | ||
425 | .ena_maxi = true, | ||
426 | .chg_curr = 3000, | ||
427 | .wait_cycles = 10, | ||
428 | .charger_curr_step = 200, | ||
429 | }; | ||
430 | |||
424 | static const struct abx500_bm_charger_parameters chg = { | 431 | static const struct abx500_bm_charger_parameters chg = { |
425 | .usb_volt_max = 5500, | 432 | .usb_volt_max = 5500, |
426 | .usb_curr_max = 1500, | 433 | .usb_curr_max = 1500, |
@@ -428,6 +435,46 @@ static const struct abx500_bm_charger_parameters chg = { | |||
428 | .ac_curr_max = 1500, | 435 | .ac_curr_max = 1500, |
429 | }; | 436 | }; |
430 | 437 | ||
438 | /* | ||
439 | * This array maps the raw hex value to charger output current used by the | ||
440 | * AB8500 values | ||
441 | */ | ||
442 | static int ab8500_charge_output_curr_map[] = { | ||
443 | 100, 200, 300, 400, 500, 600, 700, 800, | ||
444 | 900, 1000, 1100, 1200, 1300, 1400, 1500, 1500, | ||
445 | }; | ||
446 | |||
447 | static int ab8540_charge_output_curr_map[] = { | ||
448 | 0, 0, 0, 75, 100, 125, 150, 175, | ||
449 | 200, 225, 250, 275, 300, 325, 350, 375, | ||
450 | 400, 425, 450, 475, 500, 525, 550, 575, | ||
451 | 600, 625, 650, 675, 700, 725, 750, 775, | ||
452 | 800, 825, 850, 875, 900, 925, 950, 975, | ||
453 | 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, | ||
454 | 1200, 1225, 1250, 1275, 1300, 1325, 1350, 1375, | ||
455 | 1400, 1425, 1450, 1500, 1600, 1700, 1900, 2000, | ||
456 | }; | ||
457 | |||
458 | /* | ||
459 | * This array maps the raw hex value to charger input current used by the | ||
460 | * AB8500 values | ||
461 | */ | ||
462 | static int ab8500_charge_input_curr_map[] = { | ||
463 | 50, 98, 193, 290, 380, 450, 500, 600, | ||
464 | 700, 800, 900, 1000, 1100, 1300, 1400, 1500, | ||
465 | }; | ||
466 | |||
467 | static int ab8540_charge_input_curr_map[] = { | ||
468 | 25, 50, 75, 100, 125, 150, 175, 200, | ||
469 | 225, 250, 275, 300, 325, 350, 375, 400, | ||
470 | 425, 450, 475, 500, 525, 550, 575, 600, | ||
471 | 625, 650, 675, 700, 725, 750, 775, 800, | ||
472 | 825, 850, 875, 900, 925, 950, 975, 1000, | ||
473 | 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, | ||
474 | 1225, 1250, 1275, 1300, 1325, 1350, 1375, 1400, | ||
475 | 1425, 1450, 1475, 1500, 1500, 1500, 1500, 1500, | ||
476 | }; | ||
477 | |||
431 | struct abx500_bm_data ab8500_bm_data = { | 478 | struct abx500_bm_data ab8500_bm_data = { |
432 | .temp_under = 3, | 479 | .temp_under = 3, |
433 | .temp_low = 8, | 480 | .temp_low = 8, |
@@ -447,15 +494,53 @@ struct abx500_bm_data ab8500_bm_data = { | |||
447 | .fg_res = 100, | 494 | .fg_res = 100, |
448 | .cap_levels = &cap_levels, | 495 | .cap_levels = &cap_levels, |
449 | .bat_type = bat_type_thermistor, | 496 | .bat_type = bat_type_thermistor, |
450 | .n_btypes = 3, | 497 | .n_btypes = ARRAY_SIZE(bat_type_thermistor), |
451 | .batt_id = 0, | 498 | .batt_id = 0, |
452 | .interval_charging = 5, | 499 | .interval_charging = 5, |
453 | .interval_not_charging = 120, | 500 | .interval_not_charging = 120, |
454 | .temp_hysteresis = 3, | 501 | .temp_hysteresis = 3, |
455 | .gnd_lift_resistance = 34, | 502 | .gnd_lift_resistance = 34, |
456 | .maxi = &maxi_params, | 503 | .chg_output_curr = ab8500_charge_output_curr_map, |
504 | .n_chg_out_curr = ARRAY_SIZE(ab8500_charge_output_curr_map), | ||
505 | .maxi = &ab8500_maxi_params, | ||
457 | .chg_params = &chg, | 506 | .chg_params = &chg, |
458 | .fg_params = &fg, | 507 | .fg_params = &fg, |
508 | .chg_input_curr = ab8500_charge_input_curr_map, | ||
509 | .n_chg_in_curr = ARRAY_SIZE(ab8500_charge_input_curr_map), | ||
510 | }; | ||
511 | |||
512 | struct abx500_bm_data ab8540_bm_data = { | ||
513 | .temp_under = 3, | ||
514 | .temp_low = 8, | ||
515 | .temp_high = 43, | ||
516 | .temp_over = 48, | ||
517 | .main_safety_tmr_h = 4, | ||
518 | .temp_interval_chg = 20, | ||
519 | .temp_interval_nochg = 120, | ||
520 | .usb_safety_tmr_h = 4, | ||
521 | .bkup_bat_v = BUP_VCH_SEL_2P6V, | ||
522 | .bkup_bat_i = BUP_ICH_SEL_150UA, | ||
523 | .no_maintenance = false, | ||
524 | .capacity_scaling = false, | ||
525 | .adc_therm = ABx500_ADC_THERM_BATCTRL, | ||
526 | .chg_unknown_bat = false, | ||
527 | .enable_overshoot = false, | ||
528 | .fg_res = 100, | ||
529 | .cap_levels = &cap_levels, | ||
530 | .bat_type = bat_type_thermistor, | ||
531 | .n_btypes = ARRAY_SIZE(bat_type_thermistor), | ||
532 | .batt_id = 0, | ||
533 | .interval_charging = 5, | ||
534 | .interval_not_charging = 120, | ||
535 | .temp_hysteresis = 3, | ||
536 | .gnd_lift_resistance = 0, | ||
537 | .maxi = &abx540_maxi_params, | ||
538 | .chg_params = &chg, | ||
539 | .fg_params = &fg, | ||
540 | .chg_output_curr = ab8540_charge_output_curr_map, | ||
541 | .n_chg_out_curr = ARRAY_SIZE(ab8540_charge_output_curr_map), | ||
542 | .chg_input_curr = ab8540_charge_input_curr_map, | ||
543 | .n_chg_in_curr = ARRAY_SIZE(ab8540_charge_input_curr_map), | ||
459 | }; | 544 | }; |
460 | 545 | ||
461 | int ab8500_bm_of_probe(struct device *dev, | 546 | int ab8500_bm_of_probe(struct device *dev, |
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c index 91ad3edf6197..7336dcf45f7e 100644 --- a/drivers/power/ab8500_btemp.c +++ b/drivers/power/ab8500_btemp.c | |||
@@ -42,6 +42,9 @@ | |||
42 | #define BTEMP_BATCTRL_CURR_SRC_16UA 16 | 42 | #define BTEMP_BATCTRL_CURR_SRC_16UA 16 |
43 | #define BTEMP_BATCTRL_CURR_SRC_18UA 18 | 43 | #define BTEMP_BATCTRL_CURR_SRC_18UA 18 |
44 | 44 | ||
45 | #define BTEMP_BATCTRL_CURR_SRC_60UA 60 | ||
46 | #define BTEMP_BATCTRL_CURR_SRC_120UA 120 | ||
47 | |||
45 | #define to_ab8500_btemp_device_info(x) container_of((x), \ | 48 | #define to_ab8500_btemp_device_info(x) container_of((x), \ |
46 | struct ab8500_btemp, btemp_psy); | 49 | struct ab8500_btemp, btemp_psy); |
47 | 50 | ||
@@ -216,7 +219,12 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, | |||
216 | /* Only do this for batteries with internal NTC */ | 219 | /* Only do this for batteries with internal NTC */ |
217 | if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) { | 220 | if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) { |
218 | 221 | ||
219 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | 222 | if (is_ab8540(di->parent)) { |
223 | if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_60UA) | ||
224 | curr = BAT_CTRL_60U_ENA; | ||
225 | else | ||
226 | curr = BAT_CTRL_120U_ENA; | ||
227 | } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | ||
220 | if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_16UA) | 228 | if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_16UA) |
221 | curr = BAT_CTRL_16U_ENA; | 229 | curr = BAT_CTRL_16U_ENA; |
222 | else | 230 | else |
@@ -257,7 +265,14 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, | |||
257 | } else if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) { | 265 | } else if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) { |
258 | dev_dbg(di->dev, "Disable BATCTRL curr source\n"); | 266 | dev_dbg(di->dev, "Disable BATCTRL curr source\n"); |
259 | 267 | ||
260 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | 268 | if (is_ab8540(di->parent)) { |
269 | /* Write 0 to the curr bits */ | ||
270 | ret = abx500_mask_and_set_register_interruptible( | ||
271 | di->dev, | ||
272 | AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, | ||
273 | BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA, | ||
274 | ~(BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA)); | ||
275 | } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | ||
261 | /* Write 0 to the curr bits */ | 276 | /* Write 0 to the curr bits */ |
262 | ret = abx500_mask_and_set_register_interruptible( | 277 | ret = abx500_mask_and_set_register_interruptible( |
263 | di->dev, | 278 | di->dev, |
@@ -314,7 +329,13 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, | |||
314 | * if we got an error above | 329 | * if we got an error above |
315 | */ | 330 | */ |
316 | disable_curr_source: | 331 | disable_curr_source: |
317 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | 332 | if (is_ab8540(di->parent)) { |
333 | /* Write 0 to the curr bits */ | ||
334 | ret = abx500_mask_and_set_register_interruptible(di->dev, | ||
335 | AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, | ||
336 | BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA, | ||
337 | ~(BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA)); | ||
338 | } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | ||
318 | /* Write 0 to the curr bits */ | 339 | /* Write 0 to the curr bits */ |
319 | ret = abx500_mask_and_set_register_interruptible(di->dev, | 340 | ret = abx500_mask_and_set_register_interruptible(di->dev, |
320 | AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, | 341 | AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, |
@@ -541,7 +562,9 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) | |||
541 | { | 562 | { |
542 | int res; | 563 | int res; |
543 | u8 i; | 564 | u8 i; |
544 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) | 565 | if (is_ab8540(di->parent)) |
566 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_60UA; | ||
567 | else if (is_ab9540(di->parent) || is_ab8505(di->parent)) | ||
545 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; | 568 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; |
546 | else | 569 | else |
547 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; | 570 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; |
@@ -582,9 +605,14 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) | |||
582 | * detected type is Type 1, else we use the 7uA source | 605 | * detected type is Type 1, else we use the 7uA source |
583 | */ | 606 | */ |
584 | if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && | 607 | if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && |
585 | di->bm->batt_id == 1) { | 608 | di->bm->batt_id == 1) { |
586 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | 609 | if (is_ab8540(di->parent)) { |
587 | dev_dbg(di->dev, "Set BATCTRL current source to 16uA\n"); | 610 | dev_dbg(di->dev, |
611 | "Set BATCTRL current source to 60uA\n"); | ||
612 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_60UA; | ||
613 | } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { | ||
614 | dev_dbg(di->dev, | ||
615 | "Set BATCTRL current source to 16uA\n"); | ||
588 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; | 616 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; |
589 | } else { | 617 | } else { |
590 | dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); | 618 | dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); |
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; |
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index cd71d8eadf50..33b0253569a3 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h | |||
@@ -246,7 +246,11 @@ struct abx500_bm_charger_parameters { | |||
246 | * @interval_not_charging charge alg cycle period time when not charging (sec) | 246 | * @interval_not_charging charge alg cycle period time when not charging (sec) |
247 | * @temp_hysteresis temperature hysteresis | 247 | * @temp_hysteresis temperature hysteresis |
248 | * @gnd_lift_resistance Battery ground to phone ground resistance (mOhm) | 248 | * @gnd_lift_resistance Battery ground to phone ground resistance (mOhm) |
249 | * @maxi: maximization parameters | 249 | * @n_chg_out_curr number of elements in array chg_output_curr |
250 | * @n_chg_in_curr number of elements in array chg_input_curr | ||
251 | * @chg_output_curr charger output current level map | ||
252 | * @chg_input_curr charger input current level map | ||
253 | * @maxi maximization parameters | ||
250 | * @cap_levels capacity in percent for the different capacity levels | 254 | * @cap_levels capacity in percent for the different capacity levels |
251 | * @bat_type table of supported battery types | 255 | * @bat_type table of supported battery types |
252 | * @chg_params charger parameters | 256 | * @chg_params charger parameters |
@@ -281,6 +285,10 @@ struct abx500_bm_data { | |||
281 | int interval_not_charging; | 285 | int interval_not_charging; |
282 | int temp_hysteresis; | 286 | int temp_hysteresis; |
283 | int gnd_lift_resistance; | 287 | int gnd_lift_resistance; |
288 | int n_chg_out_curr; | ||
289 | int n_chg_in_curr; | ||
290 | int *chg_output_curr; | ||
291 | int *chg_input_curr; | ||
284 | const struct abx500_maxim_parameters *maxi; | 292 | const struct abx500_maxim_parameters *maxi; |
285 | const struct abx500_bm_capacity_levels *cap_levels; | 293 | const struct abx500_bm_capacity_levels *cap_levels; |
286 | struct abx500_battery_type *bat_type; | 294 | struct abx500_battery_type *bat_type; |
diff --git a/include/linux/mfd/abx500/ab8500-bm.h b/include/linux/mfd/abx500/ab8500-bm.h index 0ebf0c5d1f88..ee1c1626c886 100644 --- a/include/linux/mfd/abx500/ab8500-bm.h +++ b/include/linux/mfd/abx500/ab8500-bm.h | |||
@@ -33,7 +33,7 @@ | |||
33 | #define AB8500_CH_STATUS2_REG 0x01 | 33 | #define AB8500_CH_STATUS2_REG 0x01 |
34 | #define AB8500_CH_USBCH_STAT1_REG 0x02 | 34 | #define AB8500_CH_USBCH_STAT1_REG 0x02 |
35 | #define AB8500_CH_USBCH_STAT2_REG 0x03 | 35 | #define AB8500_CH_USBCH_STAT2_REG 0x03 |
36 | #define AB8500_CH_FSM_STAT_REG 0x04 | 36 | #define AB8540_CH_USBCH_STAT3_REG 0x04 |
37 | #define AB8500_CH_STAT_REG 0x05 | 37 | #define AB8500_CH_STAT_REG 0x05 |
38 | 38 | ||
39 | /* | 39 | /* |
@@ -157,6 +157,7 @@ | |||
157 | #define CH_OP_CUR_LVL_1P4 0x0D | 157 | #define CH_OP_CUR_LVL_1P4 0x0D |
158 | #define CH_OP_CUR_LVL_1P5 0x0E | 158 | #define CH_OP_CUR_LVL_1P5 0x0E |
159 | #define CH_OP_CUR_LVL_1P6 0x0F | 159 | #define CH_OP_CUR_LVL_1P6 0x0F |
160 | #define CH_OP_CUR_LVL_2P 0x3F | ||
160 | 161 | ||
161 | /* BTEMP High thermal limits */ | 162 | /* BTEMP High thermal limits */ |
162 | #define BTEMP_HIGH_TH_57_0 0x00 | 163 | #define BTEMP_HIGH_TH_57_0 0x00 |
@@ -246,6 +247,8 @@ enum bup_vch_sel { | |||
246 | #define BAT_CTRL_20U_ENA 0x02 | 247 | #define BAT_CTRL_20U_ENA 0x02 |
247 | #define BAT_CTRL_18U_ENA 0x01 | 248 | #define BAT_CTRL_18U_ENA 0x01 |
248 | #define BAT_CTRL_16U_ENA 0x02 | 249 | #define BAT_CTRL_16U_ENA 0x02 |
250 | #define BAT_CTRL_60U_ENA 0x01 | ||
251 | #define BAT_CTRL_120U_ENA 0x02 | ||
249 | #define BAT_CTRL_CMP_ENA 0x04 | 252 | #define BAT_CTRL_CMP_ENA 0x04 |
250 | #define FORCE_BAT_CTRL_CMP_HIGH 0x08 | 253 | #define FORCE_BAT_CTRL_CMP_HIGH 0x08 |
251 | #define BAT_CTRL_PULL_UP_ENA 0x10 | 254 | #define BAT_CTRL_PULL_UP_ENA 0x10 |