Lines Matching +full:ocv +full:- +full:capacity
1 // SPDX-License-Identifier: GPL-2.0-only
68 /* OCV -- Open Circuit Voltage */
83 * corresponding resistor value -- Ohm / C degeree.
85 #define TBAT_NEG_25D 127773 /* -25 */
86 #define TBAT_NEG_10D 54564 /* -10 */
151 * register 1 bit[7:0] -- bit[11:4] of measured value of voltage
152 * register 0 bit[3:0] -- bit[3:0] of measured value of voltage
160 ret = pm860x_bulk_read(info->i2c, offset, 2, buf); in measure_12bit_voltage()
188 * bit[11:10] -- bit[7:6] of LDO9(0x18) in measure_vbatt()
189 * bit[9:8] -- bit[7:6] of LDO8(0x17) in measure_vbatt()
190 * bit[7:6] -- bit[7:6] of LDO7(0x16) in measure_vbatt()
191 * bit[5:4] -- bit[7:6] of LDO6(0x15) in measure_vbatt()
192 * bit[3:0] -- bit[7:4] of LDO5(0x14) in measure_vbatt()
194 ret = pm860x_bulk_read(info->i2c, PM8607_LDO5, 5, buf); in measure_vbatt()
204 return -EINVAL; in measure_vbatt()
219 ret = pm860x_bulk_read(info->i2c, PM8607_IBAT_MEAS1, 2, buf); in measure_current()
235 return -EINVAL; in set_charger_current()
237 data = ((data - 50) / 50) & 0x1f; in set_charger_current()
238 *old = pm860x_reg_read(info->i2c, PM8607_CHG_CTRL2); in set_charger_current()
240 ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL2, 0x1f, data); in set_charger_current()
252 ret = pm860x_set_bits(info->i2c, PM8607_CCNT, 7, offset & 7); in read_ccnt()
255 ret = pm860x_bulk_read(info->i2c, PM8607_CCNT_MEAS1, 2, buf); in read_ccnt()
278 ccnt->pos += sum; in calc_ccnt()
289 ccnt->neg += sum; in calc_ccnt()
294 ccnt->spos += data; in calc_ccnt()
300 * charge(mAh) = count * 1.6984 * 1e(-8) in calc_ccnt()
304 ccnt->total_chg = (int) ((ccnt->pos * 18236) >> 40); in calc_ccnt()
305 ccnt->total_dischg = (int) ((ccnt->neg * 18236) >> 40); in calc_ccnt()
327 static int calc_ocv(struct pm860x_battery_info *info, int *ocv) in calc_ocv() argument
337 if (!ocv) in calc_ocv()
338 return -EINVAL; in calc_ocv()
353 mutex_lock(&info->lock); in calc_ocv()
354 if (info->present) in calc_ocv()
355 *ocv = vbatt_avg - ibatt_avg * info->resistor / 1000; in calc_ocv()
357 *ocv = vbatt_avg; in calc_ocv()
358 mutex_unlock(&info->lock); in calc_ocv()
359 dev_dbg(info->dev, "VBAT average:%d, OCV:%d\n", vbatt_avg, *ocv); in calc_ocv()
369 int ocv; in calc_soc() local
371 int ret = -EINVAL; in calc_soc()
374 return -EINVAL; in calc_soc()
378 ret = calc_ocv(info, &ocv); in calc_soc()
381 ret = measure_vbatt(info, OCV_MODE_SLEEP, &ocv); in calc_soc()
388 if (ocv < array_soc[count - 1][0]) { in calc_soc()
394 if (ocv >= array_soc[i][0]) { in calc_soc()
415 mutex_lock(&info->lock); in pm860x_batt_handler()
416 ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); in pm860x_batt_handler()
418 info->present = 1; in pm860x_batt_handler()
419 info->temp_type = PM860X_TEMP_TBAT; in pm860x_batt_handler()
421 info->present = 0; in pm860x_batt_handler()
422 info->temp_type = PM860X_TEMP_TINT; in pm860x_batt_handler()
424 mutex_unlock(&info->lock); in pm860x_batt_handler()
440 if (info->temp_type == PM860X_TEMP_TINT) in pm860x_init_battery()
442 ret = pm860x_set_bits(info->i2c, PM8607_MEAS_EN1, data, data); in pm860x_init_battery()
448 ret = pm860x_set_bits(info->i2c, PM8607_MEAS_EN3, data, data); in pm860x_init_battery()
453 ret = pm860x_reg_write(info->i2c, PM8607_MEAS_OFF_TIME1, 0x82); in pm860x_init_battery()
456 ret = pm860x_reg_write(info->i2c, PM8607_MEAS_OFF_TIME2, 0x6c); in pm860x_init_battery()
461 ret = pm860x_set_bits(info->i2c, PM8607_GPADC_MISC1, in pm860x_init_battery()
467 ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL6, in pm860x_init_battery()
472 ret = pm860x_set_bits(info->i2c, PM8607_CCNT, 7 << 3, in pm860x_init_battery()
478 ret = pm860x_set_bits(info->i2c, PM8607_GP_BIAS2, 0xF << 4, in pm860x_init_battery()
484 mutex_lock(&info->lock); in pm860x_init_battery()
485 ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); in pm860x_init_battery()
487 mutex_unlock(&info->lock); in pm860x_init_battery()
491 info->present = 1; in pm860x_init_battery()
492 info->temp_type = PM860X_TEMP_TBAT; in pm860x_init_battery()
494 info->present = 0; in pm860x_init_battery()
495 info->temp_type = PM860X_TEMP_TINT; in pm860x_init_battery()
497 mutex_unlock(&info->lock); in pm860x_init_battery()
503 data = pm860x_reg_read(info->i2c, PM8607_POWER_UP_LOG); in pm860x_init_battery()
506 dev_dbg(info->dev, "battery wake up? %s\n", in pm860x_init_battery()
511 buf[0] = pm860x_reg_read(info->i2c, PM8607_RTC_MISC2); in pm860x_init_battery()
512 buf[1] = pm860x_reg_read(info->i2c, PM8607_RTC1); in pm860x_init_battery()
515 info->start_soc = soc; in pm860x_init_battery()
516 else if (data < soc - 15) in pm860x_init_battery()
517 info->start_soc = soc; in pm860x_init_battery()
519 info->start_soc = data; in pm860x_init_battery()
520 dev_dbg(info->dev, "soc_rtc %d, soc_ocv :%d\n", data, soc); in pm860x_init_battery()
522 pm860x_set_bits(info->i2c, PM8607_POWER_UP_LOG, in pm860x_init_battery()
524 info->start_soc = soc; in pm860x_init_battery()
526 info->last_capacity = info->start_soc; in pm860x_init_battery()
527 dev_dbg(info->dev, "init soc : %d\n", info->last_capacity); in pm860x_init_battery()
542 pm860x_reg_write(info->i2c, PM8607_GPADC1_HIGHTH, data); in set_temp_threshold()
543 dev_dbg(info->dev, "TEMP_HIGHTH : min: %d, 0x%x\n", min, data); in set_temp_threshold()
549 pm860x_reg_write(info->i2c, PM8607_GPADC1_LOWTH, data); in set_temp_threshold()
550 dev_dbg(info->dev, "TEMP_LOWTH:max : %d, 0x%x\n", max, data); in set_temp_threshold()
560 if (info->temp_type == PM860X_TEMP_TINT) { in measure_temp()
564 *data = (*data - 884) * 1000 / 3611; in measure_temp()
573 temp = -30; /* over cold , suppose -30 roughly */ in measure_temp()
577 temp = -15; /* -15 degree, code */ in measure_temp()
581 temp = -5; /* -5 degree */ in measure_temp()
611 dev_dbg(info->dev, "temp_C:%d C,temp_mv:%d mv\n", temp, *data); in measure_temp()
660 ibatt_sum1 = ibatt_sum1 - data; /* discharging */ in calc_resistor()
683 ibatt_sum2 = ibatt_sum2 - data; /* discharging */ in calc_resistor()
695 data = 1000 * (vbatt_sum1 - vbatt_sum2) in calc_resistor()
696 / (ibatt_sum1 - ibatt_sum2); in calc_resistor()
697 if ((data - info->resistor > 0) && in calc_resistor()
698 (data - info->resistor < info->resistor)) in calc_resistor()
699 info->resistor = data; in calc_resistor()
700 if ((info->resistor - data > 0) && in calc_resistor()
701 (info->resistor - data < data)) in calc_resistor()
702 info->resistor = data; in calc_resistor()
709 return -EINVAL; in calc_resistor()
724 data = info->max_capacity * info->start_soc / 100; in calc_capacity()
725 if (ccnt_data.total_dischg - ccnt_data.total_chg <= data) { in calc_capacity()
727 data + ccnt_data.total_chg - ccnt_data.total_dischg; in calc_capacity()
730 calc_soc(info, OCV_MODE_ACTIVE, &info->start_soc); in calc_capacity()
731 dev_dbg(info->dev, "restart soc = %d !\n", in calc_capacity()
732 info->start_soc); in calc_capacity()
736 cap_cc = cap_cc * 100 / info->max_capacity; in calc_capacity()
742 dev_dbg(info->dev, "%s, last cap : %d", __func__, in calc_capacity()
743 info->last_capacity); in calc_capacity()
748 /* Calculate the capacity when discharging(ibat < 0) */ in calc_capacity()
752 cap_ocv = info->last_capacity; in calc_capacity()
757 /* choose the lower capacity value to report in calc_capacity()
765 * CC have some accumulation error, switch to OCV in calc_capacity()
766 * to estimate capacity; in calc_capacity()
768 if (cap_cc < 15 && cap_ocv - cap_cc > 10) in calc_capacity()
773 /* when discharging, make sure current capacity in calc_capacity()
775 if (*cap > info->last_capacity) in calc_capacity()
776 *cap = info->last_capacity; in calc_capacity()
780 info->last_capacity = *cap; in calc_capacity()
782 dev_dbg(info->dev, "%s, cap_ocv:%d cap_cc:%d, cap:%d\n", in calc_capacity()
786 * store the current capacity to RTC domain register, in calc_capacity()
789 pm860x_set_bits(info->i2c, PM8607_RTC_MISC2, RTC_SOC_5LSB, in calc_capacity()
791 pm860x_set_bits(info->i2c, PM8607_RTC1, RTC_SOC_3MSB, in calc_capacity()
800 struct pm860x_battery_info *info = dev_get_drvdata(psy->dev.parent); in pm860x_external_power_changed()
809 struct pm860x_battery_info *info = dev_get_drvdata(psy->dev.parent); in pm860x_batt_get_prop()
815 val->intval = info->present; in pm860x_batt_get_prop()
826 if (!info->present) in pm860x_batt_get_prop()
828 val->intval = data; in pm860x_batt_get_prop()
831 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; in pm860x_batt_get_prop()
838 val->intval = data * 1000; in pm860x_batt_get_prop()
845 val->intval = data * 1000; in pm860x_batt_get_prop()
851 val->intval = data; in pm860x_batt_get_prop()
854 if (info->present) { in pm860x_batt_get_prop()
863 val->intval = data; in pm860x_batt_get_prop()
866 return -ENODEV; in pm860x_batt_get_prop()
875 struct pm860x_battery_info *info = dev_get_drvdata(psy->dev.parent); in pm860x_batt_set_prop()
880 info->start_soc = 100; in pm860x_batt_set_prop()
881 dev_dbg(info->dev, "chg done, update soc = %d\n", in pm860x_batt_set_prop()
882 info->start_soc); in pm860x_batt_set_prop()
885 return -EPERM; in pm860x_batt_set_prop()
903 .name = "battery-monitor",
914 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); in pm860x_battery_probe()
919 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in pm860x_battery_probe()
921 return -ENOMEM; in pm860x_battery_probe()
923 info->irq_cc = platform_get_irq(pdev, 0); in pm860x_battery_probe()
924 if (info->irq_cc < 0) in pm860x_battery_probe()
925 return info->irq_cc; in pm860x_battery_probe()
927 info->irq_batt = platform_get_irq(pdev, 1); in pm860x_battery_probe()
928 if (info->irq_batt < 0) in pm860x_battery_probe()
929 return info->irq_batt; in pm860x_battery_probe()
931 info->chip = chip; in pm860x_battery_probe()
932 info->i2c = in pm860x_battery_probe()
933 (chip->id == CHIP_PM8607) ? chip->client : chip->companion; in pm860x_battery_probe()
934 info->dev = &pdev->dev; in pm860x_battery_probe()
935 info->status = POWER_SUPPLY_STATUS_UNKNOWN; in pm860x_battery_probe()
936 pdata = pdev->dev.platform_data; in pm860x_battery_probe()
938 mutex_init(&info->lock); in pm860x_battery_probe()
943 if (pdata && pdata->max_capacity) in pm860x_battery_probe()
944 info->max_capacity = pdata->max_capacity; in pm860x_battery_probe()
946 info->max_capacity = 1500; /* set default capacity */ in pm860x_battery_probe()
947 if (pdata && pdata->resistor) in pm860x_battery_probe()
948 info->resistor = pdata->resistor; in pm860x_battery_probe()
950 info->resistor = 300; /* set default internal resistor */ in pm860x_battery_probe()
952 info->battery = devm_power_supply_register(&pdev->dev, in pm860x_battery_probe()
955 if (IS_ERR(info->battery)) in pm860x_battery_probe()
956 return PTR_ERR(info->battery); in pm860x_battery_probe()
957 info->battery->dev.parent = &pdev->dev; in pm860x_battery_probe()
959 ret = devm_request_threaded_irq(chip->dev, info->irq_cc, NULL, in pm860x_battery_probe()
963 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", in pm860x_battery_probe()
964 info->irq_cc, ret); in pm860x_battery_probe()
968 ret = devm_request_threaded_irq(chip->dev, info->irq_batt, NULL, in pm860x_battery_probe()
972 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", in pm860x_battery_probe()
973 info->irq_batt, ret); in pm860x_battery_probe()
985 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); in pm860x_battery_suspend()
988 chip->wakeup_flag |= 1 << PM8607_IRQ_CC; in pm860x_battery_suspend()
995 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); in pm860x_battery_resume()
998 chip->wakeup_flag &= ~(1 << PM8607_IRQ_CC); in pm860x_battery_resume()
1008 .name = "88pm860x-battery",