Lines Matching +full:usb +full:- +full:sdp
1 // SPDX-License-Identifier: GPL-2.0-only
20 * a) Trickle-charge with constant current (8).
21 * b) pre-charge with constant current (6)
22 * c) fast-charge, first with constant current (5) phase. After
30 *(4)` `.` ` ` ` ` ` ` ` ` ` ` ` ` ` ----------------------------.
32 * . o----+/:/ ` ` ` ` ` ` ` ` ` ` ` ` `.` ` (5)
34 * . + /- -- .
35 * . +`/- + .
36 * . o/- -: .
38 * . .--+ `/ .
40 * . -` + -- .
41 * . (2) ...`` + :- .
42 * . ...`` + -: .
43 *(3)` `.`."" ` ` ` `+-------- ` ` ` ` ` ` `.:` ` ` ` ` ` ` ` ` .` ` (6)
45 * . + -: .
46 * . + -:. .
47 * . + .--. .
49 * -..............` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` + ` ` ` .` ` (8)
50 * . + -
51 * -------------------------------------------------+++++++++-->
71 #include "bd99954-charger.h"
74 u16 precharge_current; /* Trickle-charge Current */
85 u16 itrich_set; /* Trickle-charge Current Setting */
86 u16 iprech_set; /* Pre-Charge Current Setting */
87 u16 ichg_set; /* Fast-Charge constant current */
89 u16 vprechg_th_set; /* Pre-charge Voltage Threshold Setting */
90 u16 vrechg_set; /* Re-charge Battery Voltage Setting */
186 ret = regmap_field_read(bd->rmap_fields[F_BATTEMP], &tmp); in bd9995x_get_prop_batt_health()
213 ret = regmap_field_read(bd->rmap_fields[F_CHGSTM_STATE], &tmp); in bd9995x_get_prop_charge_type()
236 ret = regmap_field_read(bd->rmap_fields[F_BATTEMP], &tmp); in bd9995x_get_prop_batt_present()
247 ret = regmap_field_read(bd->rmap_fields[F_VBAT_VAL], &tmp); in bd9995x_get_prop_batt_voltage()
260 ret = regmap_field_read(bd->rmap_fields[F_IBATP_VAL], &tmp); in bd9995x_get_prop_batt_current()
273 ret = regmap_field_read(bd->rmap_fields[F_THERM_VAL], &tmp); in bd9995x_get_prop_batt_temp()
277 return (200 - tmp) * 10; in bd9995x_get_prop_batt_temp()
288 mutex_lock(&bd->lock); in bd9995x_power_supply_get_property()
289 state = bd->state; in bd9995x_power_supply_get_property()
290 mutex_unlock(&bd->lock); in bd9995x_power_supply_get_property()
299 val->intval = POWER_SUPPLY_STATUS_CHARGING; in bd9995x_power_supply_get_property()
303 val->intval = POWER_SUPPLY_STATUS_FULL; in bd9995x_power_supply_get_property()
322 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in bd9995x_power_supply_get_property()
326 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; in bd9995x_power_supply_get_property()
332 val->strval = BD9995X_MANUFACTURER; in bd9995x_power_supply_get_property()
336 val->intval = state.online; in bd9995x_power_supply_get_property()
340 ret = regmap_field_read(bd->rmap_fields[F_IBATP_VAL], &tmp); in bd9995x_power_supply_get_property()
343 val->intval = tmp * 1000; in bd9995x_power_supply_get_property()
347 ret = regmap_field_read(bd->rmap_fields[F_IBATP_AVE_VAL], &tmp); in bd9995x_power_supply_get_property()
350 val->intval = tmp * 1000; in bd9995x_power_supply_get_property()
356 * target current for fast-charging constant current phase. in bd9995x_power_supply_get_property()
366 ret = regmap_field_read(bd->rmap_fields[F_SEL_ILIM_VAL], &tmp); in bd9995x_power_supply_get_property()
369 val->intval = tmp * 1000; in bd9995x_power_supply_get_property()
374 val->intval = 0; in bd9995x_power_supply_get_property()
378 ret = regmap_field_read(bd->rmap_fields[F_VFASTCHG_REG_SET1], in bd9995x_power_supply_get_property()
387 val->intval = clamp_val(tmp << 4, 2560, 19200); in bd9995x_power_supply_get_property()
388 val->intval *= 1000; in bd9995x_power_supply_get_property()
392 ret = regmap_field_read(bd->rmap_fields[F_ITERM_SET], &tmp); in bd9995x_power_supply_get_property()
396 val->intval = tmp << 6; in bd9995x_power_supply_get_property()
397 /* Maximum is 1024 mA - no matter what register says */ in bd9995x_power_supply_get_property()
398 val->intval = min(val->intval, 1024); in bd9995x_power_supply_get_property()
399 val->intval *= 1000; in bd9995x_power_supply_get_property()
404 val->intval = bd9995x_get_prop_batt_present(bd); in bd9995x_power_supply_get_property()
408 val->intval = bd9995x_get_prop_batt_voltage(bd); in bd9995x_power_supply_get_property()
412 val->intval = bd9995x_get_prop_batt_current(bd); in bd9995x_power_supply_get_property()
416 val->intval = bd9995x_get_prop_charge_type(bd); in bd9995x_power_supply_get_property()
420 val->intval = bd9995x_get_prop_batt_health(bd); in bd9995x_power_supply_get_property()
424 val->intval = bd9995x_get_prop_batt_temp(bd); in bd9995x_power_supply_get_property()
428 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; in bd9995x_power_supply_get_property()
432 val->strval = "bd99954"; in bd9995x_power_supply_get_property()
436 return -EINVAL; in bd9995x_power_supply_get_property()
452 bd->rmap_fields[F_CHGSTM_STATE], &state->chgstm_status, in bd9995x_get_chip_state()
454 bd->rmap_fields[F_VBAT_VSYS_STATUS], in bd9995x_get_chip_state()
455 &state->vbat_vsys_status, in bd9995x_get_chip_state()
457 bd->rmap_fields[F_VBUS_VCC_STATUS], in bd9995x_get_chip_state()
458 &state->vbus_vcc_status, in bd9995x_get_chip_state()
471 if (state->vbus_vcc_status & STATUS_VCC_DET || in bd9995x_get_chip_state()
472 state->vbus_vcc_status & STATUS_VBUS_DET) in bd9995x_get_chip_state()
473 state->online = 1; in bd9995x_get_chip_state()
475 state->online = 0; in bd9995x_get_chip_state()
492 * So lets implement really simple and hopefully bullet-proof handler: in bd9995x_irq_handler_thread()
494 * re-read all interesting statuses + give the framework a nudge. in bd9995x_irq_handler_thread()
503 ret = regmap_read(bd->rmap, INT0_STATUS, &status); in bd9995x_irq_handler_thread()
505 dev_err(bd->dev, "Failed to read IRQ status\n"); in bd9995x_irq_handler_thread()
509 ret = regmap_field_read(bd->rmap_fields[F_INT0_SET], &mask); in bd9995x_irq_handler_thread()
511 dev_err(bd->dev, "Failed to read IRQ mask\n"); in bd9995x_irq_handler_thread()
519 /* Lowest bit does not represent any sub-registers */ in bd9995x_irq_handler_thread()
525 ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], 0); in bd9995x_irq_handler_thread()
527 dev_err(bd->dev, "Failed to mask F_INT0\n"); in bd9995x_irq_handler_thread()
531 ret = regmap_write(bd->rmap, INT0_STATUS, status); in bd9995x_irq_handler_thread()
533 dev_err(bd->dev, "Failed to ack F_INT0\n"); in bd9995x_irq_handler_thread()
544 bd->rmap_fields[F_INT1_SET], in bd9995x_irq_handler_thread()
545 bd->rmap_fields[F_INT2_SET], in bd9995x_irq_handler_thread()
546 bd->rmap_fields[F_INT3_SET], in bd9995x_irq_handler_thread()
547 bd->rmap_fields[F_INT4_SET], in bd9995x_irq_handler_thread()
548 bd->rmap_fields[F_INT5_SET], in bd9995x_irq_handler_thread()
549 bd->rmap_fields[F_INT6_SET], in bd9995x_irq_handler_thread()
550 bd->rmap_fields[F_INT7_SET], in bd9995x_irq_handler_thread()
554 ret = regmap_read(bd->rmap, sub_status_reg[i], &sub_status); in bd9995x_irq_handler_thread()
556 dev_err(bd->dev, "Failed to read IRQ sub-status\n"); in bd9995x_irq_handler_thread()
562 dev_err(bd->dev, "Failed to read IRQ sub-mask\n"); in bd9995x_irq_handler_thread()
566 /* Ack active sub-statuses */ in bd9995x_irq_handler_thread()
569 ret = regmap_write(bd->rmap, sub_status_reg[i], sub_status); in bd9995x_irq_handler_thread()
571 dev_err(bd->dev, "Failed to ack sub-IRQ\n"); in bd9995x_irq_handler_thread()
576 ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], mask); in bd9995x_irq_handler_thread()
584 dev_err(bd->dev, "Failed to read chip state\n"); in bd9995x_irq_handler_thread()
586 mutex_lock(&bd->lock); in bd9995x_irq_handler_thread()
587 bd->state = state; in bd9995x_irq_handler_thread()
588 mutex_unlock(&bd->lock); in bd9995x_irq_handler_thread()
590 power_supply_changed(bd->charger); in bd9995x_irq_handler_thread()
596 ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], mask); in bd9995x_irq_handler_thread()
598 dev_err(bd->dev, in bd9995x_irq_handler_thread()
599 "Failed to un-mask F_INT0 - IRQ permanently disabled\n"); in bd9995x_irq_handler_thread()
610 ret = regmap_raw_write(bd->rmap, SYSTEM_CTRL_SET, &tmp, 2); in __bd9995x_chip_reset()
615 ret = regmap_field_read(bd->rmap_fields[F_OTPLD_STATE], &state); in __bd9995x_chip_reset()
620 } while (state == 0 && --rst_check_counter); in __bd9995x_chip_reset()
623 dev_err(bd->dev, "chip reset not completed\n"); in __bd9995x_chip_reset()
624 return -ETIMEDOUT; in __bd9995x_chip_reset()
628 ret = regmap_raw_write(bd->rmap, SYSTEM_CTRL_SET, &tmp, 2); in __bd9995x_chip_reset()
638 struct bd9995x_init_data *id = &bd->init_data; in bd9995x_hw_init()
644 /* Enable the charging trigger after SDP charger attached */ in bd9995x_hw_init()
646 /* Enable charging trigger after SDP charger attached */ in bd9995x_hw_init()
654 /* Select current limitation when SDP charger attached*/ in bd9995x_hw_init()
658 {F_VSYSREG_SET, id->vsysreg_set}, in bd9995x_hw_init()
659 /* Activate USB charging and DC/DC converter */ in bd9995x_hw_init()
669 {F_IBUS_LIM_SET, id->ibus_lim_set}, in bd9995x_hw_init()
670 {F_ICC_LIM_SET, id->icc_lim_set}, in bd9995x_hw_init()
672 {F_ITERM_SET, id->iterm_set}, in bd9995x_hw_init()
673 /* Trickle-charge Current Setting */ in bd9995x_hw_init()
674 {F_ITRICH_SET, id->itrich_set}, in bd9995x_hw_init()
675 /* Pre-charge Current setting */ in bd9995x_hw_init()
676 {F_IPRECH_SET, id->iprech_set}, in bd9995x_hw_init()
678 {F_ICHG_SET, id->ichg_set}, in bd9995x_hw_init()
680 {F_VFASTCHG_REG_SET1, id->vfastchg_reg_set1}, in bd9995x_hw_init()
681 /* Set Pre-charge Voltage Threshold for trickle charging. */ in bd9995x_hw_init()
682 {F_VPRECHG_TH_SET, id->vprechg_th_set}, in bd9995x_hw_init()
683 {F_VRECHG_SET, id->vrechg_set}, in bd9995x_hw_init()
684 {F_VBATOVP_SET, id->vbatovp_set}, in bd9995x_hw_init()
687 /* Disable fast-charging watchdog */ in bd9995x_hw_init()
689 /* Disable pre-charging watchdog */ in bd9995x_hw_init()
713 ret = regmap_field_write(bd->rmap_fields[init_data[i].id], in bd9995x_hw_init()
716 dev_err(bd->dev, "failed to initialize charger (%d)\n", in bd9995x_hw_init()
726 mutex_lock(&bd->lock); in bd9995x_hw_init()
727 bd->state = state; in bd9995x_hw_init()
728 mutex_unlock(&bd->lock); in bd9995x_hw_init()
754 .name = "bd9995x-charger",
762 * Limit configurations for vbus-input-current and vcc-vacp-input-current
779 /* Possible trickle, pre-charging and termination current values */
795 * Fast charging voltage regulation, starting re-charging limit
837 /* Possible settings for switching from trickle to pre-charging limits */
857 /* Possible current values for fast-charging constant current phase */
890 struct bd9995x_init_data *init = &bd->init_data; in bd9995x_fw_probe()
893 .name = "trickle-charging current", in bd9995x_fw_probe()
897 .data = &init->itrich_set, in bd9995x_fw_probe()
899 .name = "pre-charging current", in bd9995x_fw_probe()
903 .data = &init->iprech_set, in bd9995x_fw_probe()
905 .name = "pre-to-trickle charge voltage threshold", in bd9995x_fw_probe()
909 .data = &init->vprechg_th_set, in bd9995x_fw_probe()
915 .data = &init->iterm_set, in bd9995x_fw_probe()
917 .name = "charging re-start voltage", in bd9995x_fw_probe()
921 .data = &init->vrechg_set, in bd9995x_fw_probe()
927 .data = &init->vbatovp_set, in bd9995x_fw_probe()
929 .name = "fast-charging max current", in bd9995x_fw_probe()
933 .data = &init->ichg_set, in bd9995x_fw_probe()
935 .name = "fast-charging voltage", in bd9995x_fw_probe()
939 .data = &init->vfastchg_reg_set1, in bd9995x_fw_probe()
944 .prop = "rohm,vsys-regulation-microvolt", in bd9995x_fw_probe()
947 .data = &init->vsysreg_set, in bd9995x_fw_probe()
949 .prop = "rohm,vbus-input-current-limit-microamp", in bd9995x_fw_probe()
952 .data = &init->ibus_lim_set, in bd9995x_fw_probe()
954 .prop = "rohm,vcc-input-current-limit-microamp", in bd9995x_fw_probe()
957 .data = &init->icc_lim_set, in bd9995x_fw_probe()
965 ret = power_supply_get_battery_info(bd->charger, &info); in bd9995x_fw_probe()
974 if (val == -EINVAL) in bd9995x_fw_probe()
980 dev_err(bd->dev, "Unsupported value for %s\n", in bd9995x_fw_probe()
983 power_supply_put_battery_info(bd->charger, &info); in bd9995x_fw_probe()
984 return -EINVAL; in bd9995x_fw_probe()
987 dev_warn(bd->dev, in bd9995x_fw_probe()
988 "Unsupported value for %s - using smaller\n", in bd9995x_fw_probe()
994 power_supply_put_battery_info(bd->charger, &info); in bd9995x_fw_probe()
997 ret = device_property_read_u32(bd->dev, props[i].prop, in bd9995x_fw_probe()
1000 dev_err(bd->dev, "failed to read %s", props[i].prop); in bd9995x_fw_probe()
1010 dev_err(bd->dev, "Unsupported value for '%s'\n", in bd9995x_fw_probe()
1013 return -EINVAL; in bd9995x_fw_probe()
1017 dev_warn(bd->dev, in bd9995x_fw_probe()
1018 "Unsupported value for '%s' - using smaller\n", in bd9995x_fw_probe()
1035 struct device *dev = &client->dev; in bd9995x_probe()
1043 return -ENOMEM; in bd9995x_probe()
1045 bd->client = client; in bd9995x_probe()
1046 bd->dev = dev; in bd9995x_probe()
1048 psy_cfg.of_node = dev->of_node; in bd9995x_probe()
1050 mutex_init(&bd->lock); in bd9995x_probe()
1052 bd->rmap = devm_regmap_init_i2c(client, &bd9995x_regmap_config); in bd9995x_probe()
1053 if (IS_ERR(bd->rmap)) { in bd9995x_probe()
1055 return PTR_ERR(bd->rmap); in bd9995x_probe()
1061 bd->rmap_fields[i] = devm_regmap_field_alloc(dev, bd->rmap, in bd9995x_probe()
1063 if (IS_ERR(bd->rmap_fields[i])) { in bd9995x_probe()
1065 return PTR_ERR(bd->rmap_fields[i]); in bd9995x_probe()
1071 ret = regmap_field_read(bd->rmap_fields[F_CHIP_ID], &bd->chip_id); in bd9995x_probe()
1077 if (bd->chip_id != BD99954_ID) { in bd9995x_probe()
1079 bd->chip_id); in bd9995x_probe()
1080 return -ENODEV; in bd9995x_probe()
1083 ret = regmap_field_read(bd->rmap_fields[F_CHIP_REV], &bd->chip_rev); in bd9995x_probe()
1089 dev_info(bd->dev, "Found BD99954 chip rev %d\n", bd->chip_rev); in bd9995x_probe()
1095 bd->charger = devm_power_supply_register(bd->dev, in bd9995x_probe()
1098 if (IS_ERR(bd->charger)) { in bd9995x_probe()
1100 return PTR_ERR(bd->charger); in bd9995x_probe()
1119 return devm_request_threaded_irq(dev, client->irq, NULL, in bd9995x_probe()
1133 .name = "bd9995x-charger",