Lines Matching +full:current +full:- +full:boost +full:- +full:microamp
1 // SPDX-License-Identifier: GPL-2.0-only
16 * Curve (1) represents charging current.
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
24 * voltage phase until charging current has dropped to termination
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"
76 u16 ibus_lim_set; /* VBUS input current limitation */
77 u16 icc_lim_set; /* VCC/VACP Input Current Limit Setting */
78 u16 itrich_set; /* Trickle-charge Current Setting */
79 u16 iprech_set; /* Pre-Charge Current Setting */
80 u16 ichg_set; /* Fast-Charge constant current */
82 u16 vprechg_th_set; /* Pre-charge Voltage Threshold Setting */
83 u16 vrechg_set; /* Re-charge Battery Voltage Setting */
85 u16 iterm_set; /* Charging termination current */
179 ret = regmap_field_read(bd->rmap_fields[F_BATTEMP], &tmp);
206 ret = regmap_field_read(bd->rmap_fields[F_CHGSTM_STATE], &tmp);
229 ret = regmap_field_read(bd->rmap_fields[F_BATTEMP], &tmp);
240 ret = regmap_field_read(bd->rmap_fields[F_VBAT_VAL], &tmp);
253 ret = regmap_field_read(bd->rmap_fields[F_IBATP_VAL], &tmp);
266 ret = regmap_field_read(bd->rmap_fields[F_THERM_VAL], &tmp);
270 return (200 - tmp) * 10;
281 mutex_lock(&bd->lock);
282 state = bd->state;
283 mutex_unlock(&bd->lock);
292 val->intval = POWER_SUPPLY_STATUS_CHARGING;
296 val->intval = POWER_SUPPLY_STATUS_FULL;
315 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
319 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
325 val->strval = BD9995X_MANUFACTURER;
329 val->intval = state.online;
333 ret = regmap_field_read(bd->rmap_fields[F_IBATP_VAL], &tmp);
336 val->intval = tmp * 1000;
340 ret = regmap_field_read(bd->rmap_fields[F_IBATP_AVE_VAL], &tmp);
343 val->intval = tmp * 1000;
349 * target current for fast-charging constant current phase.
359 ret = regmap_field_read(bd->rmap_fields[F_SEL_ILIM_VAL], &tmp);
362 val->intval = tmp * 1000;
367 val->intval = 0;
371 ret = regmap_field_read(bd->rmap_fields[F_VFASTCHG_REG_SET1],
380 val->intval = clamp_val(tmp << 4, 2560, 19200);
381 val->intval *= 1000;
385 ret = regmap_field_read(bd->rmap_fields[F_ITERM_SET], &tmp);
389 val->intval = tmp << 6;
390 /* Maximum is 1024 mA - no matter what register says */
391 val->intval = min(val->intval, 1024);
392 val->intval *= 1000;
397 val->intval = bd9995x_get_prop_batt_present(bd);
401 val->intval = bd9995x_get_prop_batt_voltage(bd);
405 val->intval = bd9995x_get_prop_batt_current(bd);
409 val->intval = bd9995x_get_prop_charge_type(bd);
413 val->intval = bd9995x_get_prop_batt_health(bd);
417 val->intval = bd9995x_get_prop_batt_temp(bd);
421 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
425 val->strval = "bd99954";
429 return -EINVAL;
445 bd->rmap_fields[F_CHGSTM_STATE], &state->chgstm_status,
447 bd->rmap_fields[F_VBAT_VSYS_STATUS],
448 &state->vbat_vsys_status,
450 bd->rmap_fields[F_VBUS_VCC_STATUS],
451 &state->vbus_vcc_status,
464 if (state->vbus_vcc_status & STATUS_VCC_DET ||
465 state->vbus_vcc_status & STATUS_VBUS_DET)
466 state->online = 1;
468 state->online = 0;
485 * So lets implement really simple and hopefully bullet-proof handler:
487 * re-read all interesting statuses + give the framework a nudge.
496 ret = regmap_read(bd->rmap, INT0_STATUS, &status);
498 dev_err(bd->dev, "Failed to read IRQ status\n");
502 ret = regmap_field_read(bd->rmap_fields[F_INT0_SET], &mask);
504 dev_err(bd->dev, "Failed to read IRQ mask\n");
512 /* Lowest bit does not represent any sub-registers */
518 ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], 0);
520 dev_err(bd->dev, "Failed to mask F_INT0\n");
524 ret = regmap_write(bd->rmap, INT0_STATUS, status);
526 dev_err(bd->dev, "Failed to ack F_INT0\n");
537 bd->rmap_fields[F_INT1_SET],
538 bd->rmap_fields[F_INT2_SET],
539 bd->rmap_fields[F_INT3_SET],
540 bd->rmap_fields[F_INT4_SET],
541 bd->rmap_fields[F_INT5_SET],
542 bd->rmap_fields[F_INT6_SET],
543 bd->rmap_fields[F_INT7_SET],
547 ret = regmap_read(bd->rmap, sub_status_reg[i], &sub_status);
549 dev_err(bd->dev, "Failed to read IRQ sub-status\n");
555 dev_err(bd->dev, "Failed to read IRQ sub-mask\n");
559 /* Ack active sub-statuses */
562 ret = regmap_write(bd->rmap, sub_status_reg[i], sub_status);
564 dev_err(bd->dev, "Failed to ack sub-IRQ\n");
569 ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], mask);
577 dev_err(bd->dev, "Failed to read chip state\n");
579 mutex_lock(&bd->lock);
580 bd->state = state;
581 mutex_unlock(&bd->lock);
583 power_supply_changed(bd->charger);
589 ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], mask);
591 dev_err(bd->dev,
592 "Failed to un-mask F_INT0 - IRQ permanently disabled\n");
603 ret = regmap_raw_write(bd->rmap, SYSTEM_CTRL_SET, &tmp, 2);
608 ret = regmap_field_read(bd->rmap_fields[F_OTPLD_STATE], &state);
613 } while (state == 0 && --rst_check_counter);
616 dev_err(bd->dev, "chip reset not completed\n");
617 return -ETIMEDOUT;
621 ret = regmap_raw_write(bd->rmap, SYSTEM_CTRL_SET, &tmp, 2);
631 struct bd9995x_init_data *id = &bd->init_data;
645 /* Disable automatic limitation of the input current */
647 /* Select current limitation when SDP charger attached*/
649 /* Select current limitation when DCP charger attached */
651 {F_VSYSREG_SET, id->vsysreg_set},
658 /* Disable Input current Limit setting voltage measurement */
660 /* Disable input current limiting */
662 {F_IBUS_LIM_SET, id->ibus_lim_set},
663 {F_ICC_LIM_SET, id->icc_lim_set},
664 /* Charge Termination Current Setting to 0*/
665 {F_ITERM_SET, id->iterm_set},
666 /* Trickle-charge Current Setting */
667 {F_ITRICH_SET, id->itrich_set},
668 /* Pre-charge Current setting */
669 {F_IPRECH_SET, id->iprech_set},
670 /* Fast Charge Current for constant current phase */
671 {F_ICHG_SET, id->ichg_set},
673 {F_VFASTCHG_REG_SET1, id->vfastchg_reg_set1},
674 /* Set Pre-charge Voltage Threshold for trickle charging. */
675 {F_VPRECHG_TH_SET, id->vprechg_th_set},
676 {F_VRECHG_SET, id->vrechg_set},
677 {F_VBATOVP_SET, id->vbatovp_set},
678 /* Reverse buck boost voltage Setting */
680 /* Disable fast-charging watchdog */
682 /* Disable pre-charging watchdog */
706 ret = regmap_field_write(bd->rmap_fields[init_data[i].id],
709 dev_err(bd->dev, "failed to initialize charger (%d)\n",
719 mutex_lock(&bd->lock);
720 bd->state = state;
721 mutex_unlock(&bd->lock);
747 .name = "bd9995x-charger",
755 * Limit configurations for vbus-input-current and vcc-vacp-input-current
767 /* Possible trickle, pre-charging and termination current values */
774 * Fast charging voltage regulation, starting re-charging limit
790 /* Possible settings for switching from trickle to pre-charging limits */
797 /* Possible current values for fast-charging constant current phase */
825 struct bd9995x_init_data *init = &bd->init_data;
828 .name = "trickle-charging current",
831 .data = &init->itrich_set,
833 .name = "pre-charging current",
836 .data = &init->iprech_set,
838 .name = "pre-to-trickle charge voltage threshold",
841 .data = &init->vprechg_th_set,
843 .name = "charging termination current",
846 .data = &init->iterm_set,
848 .name = "charging re-start voltage",
851 .data = &init->vrechg_set,
856 .data = &init->vbatovp_set,
858 .name = "fast-charging max current",
861 .data = &init->ichg_set,
863 .name = "fast-charging voltage",
866 .data = &init->vfastchg_reg_set1,
871 .prop = "rohm,vsys-regulation-microvolt",
874 .data = &init->vsysreg_set,
876 .prop = "rohm,vbus-input-current-limit-microamp",
879 .data = &init->ibus_lim_set,
881 .prop = "rohm,vcc-input-current-limit-microamp",
884 .data = &init->icc_lim_set,
892 ret = power_supply_get_battery_info(bd->charger, &info);
897 battery_inits[0].info_data = &info->tricklecharge_current_ua;
898 battery_inits[1].info_data = &info->precharge_current_ua;
899 battery_inits[2].info_data = &info->precharge_voltage_max_uv;
900 battery_inits[3].info_data = &info->charge_term_current_ua;
901 battery_inits[4].info_data = &info->charge_restart_voltage_uv;
902 battery_inits[5].info_data = &info->overvoltage_limit_uv;
903 battery_inits[6].info_data = &info->constant_charge_current_max_ua;
904 battery_inits[7].info_data = &info->constant_charge_voltage_max_uv;
911 if (val == -EINVAL)
917 dev_err(bd->dev, "Unsupported value for %s\n",
920 power_supply_put_battery_info(bd->charger, info);
921 return -EINVAL;
924 dev_warn(bd->dev,
925 "Unsupported value for %s - using smaller\n",
931 power_supply_put_battery_info(bd->charger, info);
934 ret = device_property_read_u32(bd->dev, props[i].prop,
937 dev_err(bd->dev, "failed to read %s", props[i].prop);
947 dev_err(bd->dev, "Unsupported value for '%s'\n",
950 return -EINVAL;
954 dev_warn(bd->dev,
955 "Unsupported value for '%s' - using smaller\n",
972 struct device *dev = &client->dev;
980 return -ENOMEM;
982 bd->client = client;
983 bd->dev = dev;
987 mutex_init(&bd->lock);
989 bd->rmap = devm_regmap_init_i2c(client, &bd9995x_regmap_config);
990 if (IS_ERR(bd->rmap)) {
992 return PTR_ERR(bd->rmap);
998 bd->rmap_fields[i] = devm_regmap_field_alloc(dev, bd->rmap,
1000 if (IS_ERR(bd->rmap_fields[i])) {
1002 return PTR_ERR(bd->rmap_fields[i]);
1008 ret = regmap_field_read(bd->rmap_fields[F_CHIP_ID], &bd->chip_id);
1014 if (bd->chip_id != BD99954_ID) {
1016 bd->chip_id);
1017 return -ENODEV;
1020 ret = regmap_field_read(bd->rmap_fields[F_CHIP_REV], &bd->chip_rev);
1026 dev_info(bd->dev, "Found BD99954 chip rev %d\n", bd->chip_rev);
1032 bd->charger = devm_power_supply_register(bd->dev,
1035 if (IS_ERR(bd->charger)) {
1037 return PTR_ERR(bd->charger);
1056 return devm_request_threaded_irq(dev, client->irq, NULL,
1070 .name = "bd9995x-charger",