Lines Matching +full:battery +full:- +full:profile
1 // SPDX-License-Identifier: GPL-2.0
7 * Author: Xu Shengfei <xsf@rock-chips.com>
28 pr_info("FG_CW221X: %s-%d:" fmt, __func__, __LINE__, ##arg); \
31 #define CW_PROPERTIES "cw221X-bat"
141 dev_err(&client->dev, "IIC error %d\n", ret); in cw_read()
155 dev_err(&client->dev, "IIC error %d\n", ret); in cw_write()
172 dev_err(&client->dev, "IIC error %d\n", ret); in cw_read_word()
178 dev_err(&client->dev, "IIC error %d\n", ret); in cw_read_word()
185 dev_err(&client->dev, "IIC error %d\n", ret); in cw_read_word()
196 /* CW221X iic write profile function */
205 dev_err(&client->dev, "IIC error %d\n", ret); in cw_write_profile()
222 * operation since it is a brand-new calculation based on the latest battery status.
230 ret = cw_write(cw_bat->client, REG_MODE_CONFIG, ®_val); in cw221X_active()
236 ret = cw_write(cw_bat->client, REG_MODE_CONFIG, ®_val); in cw221X_active()
253 * it is a brand-new calculation based on the latest battery status.
261 ret = cw_write(cw_bat->client, REG_MODE_CONFIG, ®_val); in cw221X_sleep()
267 ret = cw_write(cw_bat->client, REG_MODE_CONFIG, ®_val); in cw221X_sleep()
276 * The 0x00 register is an UNSIGNED 8bit read-only register. Its value is
285 ret = cw_read(cw_bat->client, REG_CHIP_ID, ®_val); in cw_get_chip_id()
291 cw_bat->chip_id = chip_id; in cw_get_chip_id()
297 * The VCELL register(0x02 0x03) is an UNSIGNED 14bit read-only register that
298 * updates the battery voltage continuously. Battery voltage is measured between
300 * sigma-delta A/D converter is used and the voltage resolution is 312.5uV. (0.3125mV is *5/16)
308 ret = cw_read_word(cw_bat->client, REG_VCELL_H, reg_val); in cw_get_voltage()
314 cw_bat->voltage = voltage; in cw_get_voltage()
320 * The SOC register(0x04 0x05) is an UNSIGNED 16bit read-only register that indicates
321 * the SOC of the battery. The SOC shows in % format, which means how much percent of
322 * the battery's total available capacity is remaining in the battery now. The SOC can
323 * intrinsically adjust itself to cater to the change of battery status,
339 ret = cw_read_word(cw_bat->client, REG_SOC_INT, reg_val); in cw_get_capacity()
350 cw_bat->ic_soc_h = soc_h; in cw_get_capacity()
351 cw_bat->ic_soc_l = soc_l; in cw_get_capacity()
352 cw_bat->ui_soc = ui_soc; in cw_get_capacity()
359 * It reports the real-time battery temperature
360 * measured at TS pin. The scope is from -40 to 87.5 degrees Celsius,
361 * LSB is 0.5 degree Celsius. TEMP(C) = - 40 + Value(0x06 Reg) / 2
369 ret = cw_read(cw_bat->client, REG_TEMP, ®_val); in cw_get_temp()
373 temp = (int)reg_val * 10 / 2 - 400; in cw_get_temp()
374 cw_bat->temp = temp; in cw_get_temp()
386 dir = -1; in get_complement_code()
387 raw_code = (0xFFFF - raw_code) + 1; in get_complement_code()
403 * the resolution and the full-scale range of the current readings. The LSB of 0x0F
415 ret = cw_read_word(cw_bat->client, REG_CURRENT_H, reg_val); in cw_get_current()
422 if (((cw_bat->fw_version & CW2215_MARK) != 0) || ((cw_bat->fw_version & CW2217_MARK) != 0)) in cw_get_current()
424 else if ((cw_bat->fw_version != 0) && ((cw_bat->fw_version & 0xC0) == CW2218_MARK)) in cw_get_current()
427 cw_bat->cw_current = 0; in cw_get_current()
428 dev_err(cw_bat->dev, "error! cw221x firmware read error!\n"); in cw_get_current()
431 cw_bat->cw_current = cw_current; in cw_get_current()
437 * CYCLECNT is an UNSIGNED 16bit register(0xA4 0xA5) that counts cycle life of the battery.
446 ret = cw_read_word(cw_bat->client, REG_CYCLE_H, reg_val); in cw_get_cycle_count()
451 cw_bat->cycle = cycle / 16; in cw_get_cycle_count()
458 * battery aging by tracking battery internal impedance increment. When the device enters
468 ret = cw_read(cw_bat->client, REG_SOH, ®_val); in cw_get_soh()
473 cw_bat->soh = soh; in cw_get_soh()
491 ret = cw_read(cw_bat->client, REG_FW_VERSION, ®_val); in cw_get_fw_version()
496 cw_bat->fw_version = fw_version; in cw_get_fw_version()
512 cw_bat->voltage, cw_bat->cw_current, cw_bat->ui_soc, cw_bat->temp); in cw_update_data()
534 cw_bat->chip_id, cw_bat->voltage, cw_bat->cw_current, in cw_init_data()
535 cw_bat->ui_soc, cw_bat->temp, cw_bat->fw_version); in cw_init_data()
542 struct device *dev = cw_bat->dev; in cw221x_parse_properties()
546 length = device_property_count_u8(dev, "cellwise,battery-profile"); in cw221x_parse_properties()
548 dev_warn(cw_bat->dev, in cw221x_parse_properties()
549 "No battery-profile found, using current flash contents\n"); in cw221x_parse_properties()
551 dev_err(cw_bat->dev, "battery-profile must be %d bytes\n", in cw221x_parse_properties()
553 return -EINVAL; in cw221x_parse_properties()
556 cw_bat->bat_profile = devm_kzalloc(dev, length, GFP_KERNEL); in cw221x_parse_properties()
557 if (!cw_bat->bat_profile) in cw221x_parse_properties()
558 return -ENOMEM; in cw221x_parse_properties()
561 "cellwise,battery-profile", in cw221x_parse_properties()
562 cw_bat->bat_profile, in cw221x_parse_properties()
574 /* update new battery info */ in cw_config_profile_init()
575 cw_bat->bat_profile = config_profile_info; in cw_config_profile_init()
576 cw_printk("the driver profile:\n"); in cw_config_profile_init()
580 cw_printk("[%d]: 0x%x\n", i, cw_bat->bat_profile[i]); in cw_config_profile_init()
583 /*CW221X update profile function, Often called during initialization*/
594 /* update new battery info */ in cw_config_start_ic()
595 ret = cw_write_profile(cw_bat->client, cw_bat->bat_profile); in cw_config_start_ic()
599 cw_printk("the driver profile:\n"); in cw_config_start_ic()
601 cw_printk("[%d]: 0x%x\n", i, cw_bat->bat_profile[i]); in cw_config_start_ic()
605 ret = cw_write(cw_bat->client, REG_SOC_ALERT, ®_val); in cw_config_start_ic()
611 ret = cw_write(cw_bat->client, REG_GPIO_CONFIG, ®_val); in cw_config_start_ic()
621 cw_read(cw_bat->client, REG_IC_STATE, ®_val); in cw_config_start_ic()
627 return -1; in cw_config_start_ic()
636 * Determine whether the profile needs to be updated
645 ret = cw_read(cw_bat->client, REG_MODE_CONFIG, ®_val); in cw221X_get_state()
651 ret = cw_read(cw_bat->client, REG_SOC_ALERT, ®_val); in cw221X_get_state()
658 ret = cw_read(cw_bat->client, (REG_BAT_PROFILE + i), ®_val); in cw221X_get_state()
663 if (cw_bat->bat_profile[i] != reg_val) in cw221X_get_state()
679 dev_err(cw_bat->dev, "iic read write error"); in cw_init()
682 if (cw_bat->chip_id != IC_VCHIP_ID) { in cw_init()
683 dev_err(cw_bat->dev, "not cw221X\n"); in cw_init()
684 return -1; in cw_init()
689 dev_err(cw_bat->dev, "iic read write error"); in cw_init()
694 cw_printk("need update profile\n"); in cw_init()
700 cw_printk("not need update profile\n"); in cw_init()
722 dev_err(cw_bat->dev, "i2c read error when update data"); in cw_bat_work()
723 if (cw_bat->ui_soc != soc) { in cw_bat_work()
724 soc = cw_bat->ui_soc; in cw_bat_work()
725 power_supply_changed(cw_bat->cw_bat); in cw_bat_work()
727 queue_delayed_work(cw_bat->cwfg_workqueue, in cw_bat_work()
728 &cw_bat->battery_delay_work, in cw_bat_work()
741 ret = -EINVAL; in cw_battery_set_property()
757 val->intval = cw_bat->cycle; in cw_battery_get_property()
760 val->intval = cw_bat->ui_soc; in cw_battery_get_property()
763 if ((cw_bat->ui_soc < 1) && (!power_supply_is_system_supplied())) in cw_battery_get_property()
764 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; in cw_battery_get_property()
765 else if (cw_bat->ui_soc <= 20) in cw_battery_get_property()
766 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW; in cw_battery_get_property()
767 else if (cw_bat->ui_soc <= 70) in cw_battery_get_property()
768 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; in cw_battery_get_property()
769 else if (cw_bat->ui_soc <= 90) in cw_battery_get_property()
770 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_HIGH; in cw_battery_get_property()
772 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL; in cw_battery_get_property()
775 if (cw_bat->ui_soc == 100 * 1000) in cw_battery_get_property()
776 val->intval = POWER_SUPPLY_STATUS_FULL; in cw_battery_get_property()
779 val->intval = POWER_SUPPLY_STATUS_CHARGING; in cw_battery_get_property()
781 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; in cw_battery_get_property()
786 val->intval = 10 * 1000 * 1000;/* uAh */ in cw_battery_get_property()
789 val->intval = POWER_SUPPLY_HEALTH_GOOD; in cw_battery_get_property()
792 val->intval = (cw_bat->voltage <= 0) ? 0 : 1; in cw_battery_get_property()
796 val->intval = cw_bat->voltage * CW_VOL_UNIT; in cw_battery_get_property()
800 val->intval = cw_bat->cw_current * 1000; /* uA */ in cw_battery_get_property()
803 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; in cw_battery_get_property()
806 val->intval = cw_bat->temp; in cw_battery_get_property()
809 ret = -EINVAL; in cw_battery_get_property()
838 cw_bat = devm_kzalloc(&client->dev, sizeof(*cw_bat), GFP_KERNEL); in cw221X_probe()
840 return -ENOMEM; in cw221X_probe()
843 cw_bat->client = client; in cw221X_probe()
844 cw_bat->dev = &client->dev; in cw221X_probe()
846 dev_dbg(cw_bat->dev, "cw221X driver versions-%d\n", 20220830); in cw221X_probe()
854 dev_err(cw_bat->dev, "cw221X init fail!\n"); in cw221X_probe()
860 dev_err(cw_bat->dev, "cw221X init data fail!\n"); in cw221X_probe()
864 psy_desc = devm_kzalloc(&client->dev, sizeof(*psy_desc), GFP_KERNEL); in cw221X_probe()
866 return -ENOMEM; in cw221X_probe()
868 psy_desc->name = CW_PROPERTIES; in cw221X_probe()
869 psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; in cw221X_probe()
870 psy_desc->properties = cw_battery_properties; in cw221X_probe()
871 psy_desc->num_properties = ARRAY_SIZE(cw_battery_properties); in cw221X_probe()
872 psy_desc->get_property = cw_battery_get_property; in cw221X_probe()
873 psy_desc->set_property = cw_battery_set_property; in cw221X_probe()
874 cw_bat->cw_bat = devm_power_supply_register(&client->dev, psy_desc, &psy_cfg); in cw221X_probe()
875 if (IS_ERR(cw_bat->cw_bat)) { in cw221X_probe()
876 ret = PTR_ERR(cw_bat->cw_bat); in cw221X_probe()
877 dev_err(cw_bat->dev, "failed to register battery: %d\n", ret); in cw221X_probe()
881 cw_bat->cwfg_workqueue = create_singlethread_workqueue("cwfg_gauge"); in cw221X_probe()
882 INIT_DELAYED_WORK(&cw_bat->battery_delay_work, cw_bat_work); in cw221X_probe()
883 queue_delayed_work(cw_bat->cwfg_workqueue, in cw221X_probe()
884 &cw_bat->battery_delay_work, in cw221X_probe()
896 cancel_delayed_work_sync(&cw_bat->battery_delay_work); in cw221X_remove()
897 destroy_workqueue(cw_bat->cwfg_workqueue); in cw221X_remove()
907 cancel_delayed_work(&cw_bat->battery_delay_work); in cw_bat_suspend()
916 queue_delayed_work(cw_bat->cwfg_workqueue, in cw_bat_resume()
917 &cw_bat->battery_delay_work, in cw_bat_resume()
958 MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");