18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci// BQ25980 Battery Charger Driver 38c2ecf20Sopenharmony_ci// Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/err.h> 68c2ecf20Sopenharmony_ci#include <linux/i2c.h> 78c2ecf20Sopenharmony_ci#include <linux/init.h> 88c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 98c2ecf20Sopenharmony_ci#include <linux/kernel.h> 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci#include <linux/gpio/consumer.h> 128c2ecf20Sopenharmony_ci#include <linux/power_supply.h> 138c2ecf20Sopenharmony_ci#include <linux/regmap.h> 148c2ecf20Sopenharmony_ci#include <linux/types.h> 158c2ecf20Sopenharmony_ci#include <linux/delay.h> 168c2ecf20Sopenharmony_ci#include <linux/device.h> 178c2ecf20Sopenharmony_ci#include <linux/moduleparam.h> 188c2ecf20Sopenharmony_ci#include <linux/slab.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include "bq25980_charger.h" 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistruct bq25980_state { 238c2ecf20Sopenharmony_ci bool dischg; 248c2ecf20Sopenharmony_ci bool ovp; 258c2ecf20Sopenharmony_ci bool ocp; 268c2ecf20Sopenharmony_ci bool wdt; 278c2ecf20Sopenharmony_ci bool tflt; 288c2ecf20Sopenharmony_ci bool online; 298c2ecf20Sopenharmony_ci bool ce; 308c2ecf20Sopenharmony_ci bool hiz; 318c2ecf20Sopenharmony_ci bool bypass; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci u32 vbat_adc; 348c2ecf20Sopenharmony_ci u32 vsys_adc; 358c2ecf20Sopenharmony_ci u32 ibat_adc; 368c2ecf20Sopenharmony_ci}; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cienum bq25980_id { 398c2ecf20Sopenharmony_ci BQ25980, 408c2ecf20Sopenharmony_ci BQ25975, 418c2ecf20Sopenharmony_ci BQ25960, 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistruct bq25980_chip_info { 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci int model_id; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci const struct regmap_config *regmap_config; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci int busocp_def; 518c2ecf20Sopenharmony_ci int busocp_sc_max; 528c2ecf20Sopenharmony_ci int busocp_byp_max; 538c2ecf20Sopenharmony_ci int busocp_sc_min; 548c2ecf20Sopenharmony_ci int busocp_byp_min; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci int busovp_sc_def; 578c2ecf20Sopenharmony_ci int busovp_byp_def; 588c2ecf20Sopenharmony_ci int busovp_sc_step; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci int busovp_sc_offset; 618c2ecf20Sopenharmony_ci int busovp_byp_step; 628c2ecf20Sopenharmony_ci int busovp_byp_offset; 638c2ecf20Sopenharmony_ci int busovp_sc_min; 648c2ecf20Sopenharmony_ci int busovp_sc_max; 658c2ecf20Sopenharmony_ci int busovp_byp_min; 668c2ecf20Sopenharmony_ci int busovp_byp_max; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci int batovp_def; 698c2ecf20Sopenharmony_ci int batovp_max; 708c2ecf20Sopenharmony_ci int batovp_min; 718c2ecf20Sopenharmony_ci int batovp_step; 728c2ecf20Sopenharmony_ci int batovp_offset; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci int batocp_def; 758c2ecf20Sopenharmony_ci int batocp_max; 768c2ecf20Sopenharmony_ci}; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistruct bq25980_init_data { 798c2ecf20Sopenharmony_ci u32 ichg; 808c2ecf20Sopenharmony_ci u32 bypass_ilim; 818c2ecf20Sopenharmony_ci u32 sc_ilim; 828c2ecf20Sopenharmony_ci u32 vreg; 838c2ecf20Sopenharmony_ci u32 iterm; 848c2ecf20Sopenharmony_ci u32 iprechg; 858c2ecf20Sopenharmony_ci u32 bypass_vlim; 868c2ecf20Sopenharmony_ci u32 sc_vlim; 878c2ecf20Sopenharmony_ci u32 ichg_max; 888c2ecf20Sopenharmony_ci u32 vreg_max; 898c2ecf20Sopenharmony_ci}; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistruct bq25980_device { 928c2ecf20Sopenharmony_ci struct i2c_client *client; 938c2ecf20Sopenharmony_ci struct device *dev; 948c2ecf20Sopenharmony_ci struct power_supply *charger; 958c2ecf20Sopenharmony_ci struct power_supply *battery; 968c2ecf20Sopenharmony_ci struct mutex lock; 978c2ecf20Sopenharmony_ci struct regmap *regmap; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci char model_name[I2C_NAME_SIZE]; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci struct bq25980_init_data init_data; 1028c2ecf20Sopenharmony_ci const struct bq25980_chip_info *chip_info; 1038c2ecf20Sopenharmony_ci struct bq25980_state state; 1048c2ecf20Sopenharmony_ci int watchdog_timer; 1058c2ecf20Sopenharmony_ci}; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistatic struct reg_default bq25980_reg_defs[] = { 1088c2ecf20Sopenharmony_ci {BQ25980_BATOVP, 0x5A}, 1098c2ecf20Sopenharmony_ci {BQ25980_BATOVP_ALM, 0x46}, 1108c2ecf20Sopenharmony_ci {BQ25980_BATOCP, 0x51}, 1118c2ecf20Sopenharmony_ci {BQ25980_BATOCP_ALM, 0x50}, 1128c2ecf20Sopenharmony_ci {BQ25980_BATUCP_ALM, 0x28}, 1138c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_1, 0x0}, 1148c2ecf20Sopenharmony_ci {BQ25980_BUSOVP, 0x26}, 1158c2ecf20Sopenharmony_ci {BQ25980_BUSOVP_ALM, 0x22}, 1168c2ecf20Sopenharmony_ci {BQ25980_BUSOCP, 0xD}, 1178c2ecf20Sopenharmony_ci {BQ25980_BUSOCP_ALM, 0xC}, 1188c2ecf20Sopenharmony_ci {BQ25980_TEMP_CONTROL, 0x30}, 1198c2ecf20Sopenharmony_ci {BQ25980_TDIE_ALM, 0xC8}, 1208c2ecf20Sopenharmony_ci {BQ25980_TSBUS_FLT, 0x15}, 1218c2ecf20Sopenharmony_ci {BQ25980_TSBAT_FLG, 0x15}, 1228c2ecf20Sopenharmony_ci {BQ25980_VAC_CONTROL, 0x0}, 1238c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_2, 0x0}, 1248c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_3, 0x20}, 1258c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_4, 0x1D}, 1268c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_5, 0x18}, 1278c2ecf20Sopenharmony_ci {BQ25980_STAT1, 0x0}, 1288c2ecf20Sopenharmony_ci {BQ25980_STAT2, 0x0}, 1298c2ecf20Sopenharmony_ci {BQ25980_STAT3, 0x0}, 1308c2ecf20Sopenharmony_ci {BQ25980_STAT4, 0x0}, 1318c2ecf20Sopenharmony_ci {BQ25980_STAT5, 0x0}, 1328c2ecf20Sopenharmony_ci {BQ25980_FLAG1, 0x0}, 1338c2ecf20Sopenharmony_ci {BQ25980_FLAG2, 0x0}, 1348c2ecf20Sopenharmony_ci {BQ25980_FLAG3, 0x0}, 1358c2ecf20Sopenharmony_ci {BQ25980_FLAG4, 0x0}, 1368c2ecf20Sopenharmony_ci {BQ25980_FLAG5, 0x0}, 1378c2ecf20Sopenharmony_ci {BQ25980_MASK1, 0x0}, 1388c2ecf20Sopenharmony_ci {BQ25980_MASK2, 0x0}, 1398c2ecf20Sopenharmony_ci {BQ25980_MASK3, 0x0}, 1408c2ecf20Sopenharmony_ci {BQ25980_MASK4, 0x0}, 1418c2ecf20Sopenharmony_ci {BQ25980_MASK5, 0x0}, 1428c2ecf20Sopenharmony_ci {BQ25980_DEVICE_INFO, 0x8}, 1438c2ecf20Sopenharmony_ci {BQ25980_ADC_CONTROL1, 0x0}, 1448c2ecf20Sopenharmony_ci {BQ25980_ADC_CONTROL2, 0x0}, 1458c2ecf20Sopenharmony_ci {BQ25980_IBUS_ADC_LSB, 0x0}, 1468c2ecf20Sopenharmony_ci {BQ25980_IBUS_ADC_MSB, 0x0}, 1478c2ecf20Sopenharmony_ci {BQ25980_VBUS_ADC_LSB, 0x0}, 1488c2ecf20Sopenharmony_ci {BQ25980_VBUS_ADC_MSB, 0x0}, 1498c2ecf20Sopenharmony_ci {BQ25980_VAC1_ADC_LSB, 0x0}, 1508c2ecf20Sopenharmony_ci {BQ25980_VAC2_ADC_LSB, 0x0}, 1518c2ecf20Sopenharmony_ci {BQ25980_VOUT_ADC_LSB, 0x0}, 1528c2ecf20Sopenharmony_ci {BQ25980_VBAT_ADC_LSB, 0x0}, 1538c2ecf20Sopenharmony_ci {BQ25980_IBAT_ADC_MSB, 0x0}, 1548c2ecf20Sopenharmony_ci {BQ25980_IBAT_ADC_LSB, 0x0}, 1558c2ecf20Sopenharmony_ci {BQ25980_TSBUS_ADC_LSB, 0x0}, 1568c2ecf20Sopenharmony_ci {BQ25980_TSBAT_ADC_LSB, 0x0}, 1578c2ecf20Sopenharmony_ci {BQ25980_TDIE_ADC_LSB, 0x0}, 1588c2ecf20Sopenharmony_ci {BQ25980_DEGLITCH_TIME, 0x0}, 1598c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_6, 0x0}, 1608c2ecf20Sopenharmony_ci}; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistatic struct reg_default bq25975_reg_defs[] = { 1638c2ecf20Sopenharmony_ci {BQ25980_BATOVP, 0x5A}, 1648c2ecf20Sopenharmony_ci {BQ25980_BATOVP_ALM, 0x46}, 1658c2ecf20Sopenharmony_ci {BQ25980_BATOCP, 0x51}, 1668c2ecf20Sopenharmony_ci {BQ25980_BATOCP_ALM, 0x50}, 1678c2ecf20Sopenharmony_ci {BQ25980_BATUCP_ALM, 0x28}, 1688c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_1, 0x0}, 1698c2ecf20Sopenharmony_ci {BQ25980_BUSOVP, 0x26}, 1708c2ecf20Sopenharmony_ci {BQ25980_BUSOVP_ALM, 0x22}, 1718c2ecf20Sopenharmony_ci {BQ25980_BUSOCP, 0xD}, 1728c2ecf20Sopenharmony_ci {BQ25980_BUSOCP_ALM, 0xC}, 1738c2ecf20Sopenharmony_ci {BQ25980_TEMP_CONTROL, 0x30}, 1748c2ecf20Sopenharmony_ci {BQ25980_TDIE_ALM, 0xC8}, 1758c2ecf20Sopenharmony_ci {BQ25980_TSBUS_FLT, 0x15}, 1768c2ecf20Sopenharmony_ci {BQ25980_TSBAT_FLG, 0x15}, 1778c2ecf20Sopenharmony_ci {BQ25980_VAC_CONTROL, 0x0}, 1788c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_2, 0x0}, 1798c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_3, 0x20}, 1808c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_4, 0x1D}, 1818c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_5, 0x18}, 1828c2ecf20Sopenharmony_ci {BQ25980_STAT1, 0x0}, 1838c2ecf20Sopenharmony_ci {BQ25980_STAT2, 0x0}, 1848c2ecf20Sopenharmony_ci {BQ25980_STAT3, 0x0}, 1858c2ecf20Sopenharmony_ci {BQ25980_STAT4, 0x0}, 1868c2ecf20Sopenharmony_ci {BQ25980_STAT5, 0x0}, 1878c2ecf20Sopenharmony_ci {BQ25980_FLAG1, 0x0}, 1888c2ecf20Sopenharmony_ci {BQ25980_FLAG2, 0x0}, 1898c2ecf20Sopenharmony_ci {BQ25980_FLAG3, 0x0}, 1908c2ecf20Sopenharmony_ci {BQ25980_FLAG4, 0x0}, 1918c2ecf20Sopenharmony_ci {BQ25980_FLAG5, 0x0}, 1928c2ecf20Sopenharmony_ci {BQ25980_MASK1, 0x0}, 1938c2ecf20Sopenharmony_ci {BQ25980_MASK2, 0x0}, 1948c2ecf20Sopenharmony_ci {BQ25980_MASK3, 0x0}, 1958c2ecf20Sopenharmony_ci {BQ25980_MASK4, 0x0}, 1968c2ecf20Sopenharmony_ci {BQ25980_MASK5, 0x0}, 1978c2ecf20Sopenharmony_ci {BQ25980_DEVICE_INFO, 0x8}, 1988c2ecf20Sopenharmony_ci {BQ25980_ADC_CONTROL1, 0x0}, 1998c2ecf20Sopenharmony_ci {BQ25980_ADC_CONTROL2, 0x0}, 2008c2ecf20Sopenharmony_ci {BQ25980_IBUS_ADC_LSB, 0x0}, 2018c2ecf20Sopenharmony_ci {BQ25980_IBUS_ADC_MSB, 0x0}, 2028c2ecf20Sopenharmony_ci {BQ25980_VBUS_ADC_LSB, 0x0}, 2038c2ecf20Sopenharmony_ci {BQ25980_VBUS_ADC_MSB, 0x0}, 2048c2ecf20Sopenharmony_ci {BQ25980_VAC1_ADC_LSB, 0x0}, 2058c2ecf20Sopenharmony_ci {BQ25980_VAC2_ADC_LSB, 0x0}, 2068c2ecf20Sopenharmony_ci {BQ25980_VOUT_ADC_LSB, 0x0}, 2078c2ecf20Sopenharmony_ci {BQ25980_VBAT_ADC_LSB, 0x0}, 2088c2ecf20Sopenharmony_ci {BQ25980_IBAT_ADC_MSB, 0x0}, 2098c2ecf20Sopenharmony_ci {BQ25980_IBAT_ADC_LSB, 0x0}, 2108c2ecf20Sopenharmony_ci {BQ25980_TSBUS_ADC_LSB, 0x0}, 2118c2ecf20Sopenharmony_ci {BQ25980_TSBAT_ADC_LSB, 0x0}, 2128c2ecf20Sopenharmony_ci {BQ25980_TDIE_ADC_LSB, 0x0}, 2138c2ecf20Sopenharmony_ci {BQ25980_DEGLITCH_TIME, 0x0}, 2148c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_6, 0x0}, 2158c2ecf20Sopenharmony_ci}; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_cistatic struct reg_default bq25960_reg_defs[] = { 2188c2ecf20Sopenharmony_ci {BQ25980_BATOVP, 0x5A}, 2198c2ecf20Sopenharmony_ci {BQ25980_BATOVP_ALM, 0x46}, 2208c2ecf20Sopenharmony_ci {BQ25980_BATOCP, 0x51}, 2218c2ecf20Sopenharmony_ci {BQ25980_BATOCP_ALM, 0x50}, 2228c2ecf20Sopenharmony_ci {BQ25980_BATUCP_ALM, 0x28}, 2238c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_1, 0x0}, 2248c2ecf20Sopenharmony_ci {BQ25980_BUSOVP, 0x26}, 2258c2ecf20Sopenharmony_ci {BQ25980_BUSOVP_ALM, 0x22}, 2268c2ecf20Sopenharmony_ci {BQ25980_BUSOCP, 0xD}, 2278c2ecf20Sopenharmony_ci {BQ25980_BUSOCP_ALM, 0xC}, 2288c2ecf20Sopenharmony_ci {BQ25980_TEMP_CONTROL, 0x30}, 2298c2ecf20Sopenharmony_ci {BQ25980_TDIE_ALM, 0xC8}, 2308c2ecf20Sopenharmony_ci {BQ25980_TSBUS_FLT, 0x15}, 2318c2ecf20Sopenharmony_ci {BQ25980_TSBAT_FLG, 0x15}, 2328c2ecf20Sopenharmony_ci {BQ25980_VAC_CONTROL, 0x0}, 2338c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_2, 0x0}, 2348c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_3, 0x20}, 2358c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_4, 0x1D}, 2368c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_5, 0x18}, 2378c2ecf20Sopenharmony_ci {BQ25980_STAT1, 0x0}, 2388c2ecf20Sopenharmony_ci {BQ25980_STAT2, 0x0}, 2398c2ecf20Sopenharmony_ci {BQ25980_STAT3, 0x0}, 2408c2ecf20Sopenharmony_ci {BQ25980_STAT4, 0x0}, 2418c2ecf20Sopenharmony_ci {BQ25980_STAT5, 0x0}, 2428c2ecf20Sopenharmony_ci {BQ25980_FLAG1, 0x0}, 2438c2ecf20Sopenharmony_ci {BQ25980_FLAG2, 0x0}, 2448c2ecf20Sopenharmony_ci {BQ25980_FLAG3, 0x0}, 2458c2ecf20Sopenharmony_ci {BQ25980_FLAG4, 0x0}, 2468c2ecf20Sopenharmony_ci {BQ25980_FLAG5, 0x0}, 2478c2ecf20Sopenharmony_ci {BQ25980_MASK1, 0x0}, 2488c2ecf20Sopenharmony_ci {BQ25980_MASK2, 0x0}, 2498c2ecf20Sopenharmony_ci {BQ25980_MASK3, 0x0}, 2508c2ecf20Sopenharmony_ci {BQ25980_MASK4, 0x0}, 2518c2ecf20Sopenharmony_ci {BQ25980_MASK5, 0x0}, 2528c2ecf20Sopenharmony_ci {BQ25980_DEVICE_INFO, 0x8}, 2538c2ecf20Sopenharmony_ci {BQ25980_ADC_CONTROL1, 0x0}, 2548c2ecf20Sopenharmony_ci {BQ25980_ADC_CONTROL2, 0x0}, 2558c2ecf20Sopenharmony_ci {BQ25980_IBUS_ADC_LSB, 0x0}, 2568c2ecf20Sopenharmony_ci {BQ25980_IBUS_ADC_MSB, 0x0}, 2578c2ecf20Sopenharmony_ci {BQ25980_VBUS_ADC_LSB, 0x0}, 2588c2ecf20Sopenharmony_ci {BQ25980_VBUS_ADC_MSB, 0x0}, 2598c2ecf20Sopenharmony_ci {BQ25980_VAC1_ADC_LSB, 0x0}, 2608c2ecf20Sopenharmony_ci {BQ25980_VAC2_ADC_LSB, 0x0}, 2618c2ecf20Sopenharmony_ci {BQ25980_VOUT_ADC_LSB, 0x0}, 2628c2ecf20Sopenharmony_ci {BQ25980_VBAT_ADC_LSB, 0x0}, 2638c2ecf20Sopenharmony_ci {BQ25980_IBAT_ADC_MSB, 0x0}, 2648c2ecf20Sopenharmony_ci {BQ25980_IBAT_ADC_LSB, 0x0}, 2658c2ecf20Sopenharmony_ci {BQ25980_TSBUS_ADC_LSB, 0x0}, 2668c2ecf20Sopenharmony_ci {BQ25980_TSBAT_ADC_LSB, 0x0}, 2678c2ecf20Sopenharmony_ci {BQ25980_TDIE_ADC_LSB, 0x0}, 2688c2ecf20Sopenharmony_ci {BQ25980_DEGLITCH_TIME, 0x0}, 2698c2ecf20Sopenharmony_ci {BQ25980_CHRGR_CTRL_6, 0x0}, 2708c2ecf20Sopenharmony_ci}; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_cistatic int bq25980_watchdog_time[BQ25980_NUM_WD_VAL] = {5000, 10000, 50000, 2738c2ecf20Sopenharmony_ci 300000}; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cistatic int bq25980_get_input_curr_lim(struct bq25980_device *bq) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci unsigned int busocp_reg_code; 2788c2ecf20Sopenharmony_ci int ret; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_BUSOCP, &busocp_reg_code); 2818c2ecf20Sopenharmony_ci if (ret) 2828c2ecf20Sopenharmony_ci return ret; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci return (busocp_reg_code * BQ25980_BUSOCP_STEP_uA) + BQ25980_BUSOCP_OFFSET_uA; 2858c2ecf20Sopenharmony_ci} 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_cistatic int bq25980_set_hiz(struct bq25980_device *bq, int setting) 2888c2ecf20Sopenharmony_ci{ 2898c2ecf20Sopenharmony_ci return regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 2908c2ecf20Sopenharmony_ci BQ25980_EN_HIZ, setting); 2918c2ecf20Sopenharmony_ci} 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_cistatic int bq25980_set_input_curr_lim(struct bq25980_device *bq, int busocp) 2948c2ecf20Sopenharmony_ci{ 2958c2ecf20Sopenharmony_ci unsigned int busocp_reg_code; 2968c2ecf20Sopenharmony_ci int ret; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci if (!busocp) 2998c2ecf20Sopenharmony_ci return bq25980_set_hiz(bq, BQ25980_ENABLE_HIZ); 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci bq25980_set_hiz(bq, BQ25980_DISABLE_HIZ); 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci if (busocp < BQ25980_BUSOCP_MIN_uA) 3048c2ecf20Sopenharmony_ci busocp = BQ25980_BUSOCP_MIN_uA; 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci if (bq->state.bypass) 3078c2ecf20Sopenharmony_ci busocp = min(busocp, bq->chip_info->busocp_sc_max); 3088c2ecf20Sopenharmony_ci else 3098c2ecf20Sopenharmony_ci busocp = min(busocp, bq->chip_info->busocp_byp_max); 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci busocp_reg_code = (busocp - BQ25980_BUSOCP_OFFSET_uA) 3128c2ecf20Sopenharmony_ci / BQ25980_BUSOCP_STEP_uA; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci ret = regmap_write(bq->regmap, BQ25980_BUSOCP, busocp_reg_code); 3158c2ecf20Sopenharmony_ci if (ret) 3168c2ecf20Sopenharmony_ci return ret; 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci return regmap_write(bq->regmap, BQ25980_BUSOCP_ALM, busocp_reg_code); 3198c2ecf20Sopenharmony_ci} 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_cistatic int bq25980_get_input_volt_lim(struct bq25980_device *bq) 3228c2ecf20Sopenharmony_ci{ 3238c2ecf20Sopenharmony_ci unsigned int busovp_reg_code; 3248c2ecf20Sopenharmony_ci unsigned int busovp_offset; 3258c2ecf20Sopenharmony_ci unsigned int busovp_step; 3268c2ecf20Sopenharmony_ci int ret; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci if (bq->state.bypass) { 3298c2ecf20Sopenharmony_ci busovp_step = bq->chip_info->busovp_byp_step; 3308c2ecf20Sopenharmony_ci busovp_offset = bq->chip_info->busovp_byp_offset; 3318c2ecf20Sopenharmony_ci } else { 3328c2ecf20Sopenharmony_ci busovp_step = bq->chip_info->busovp_sc_step; 3338c2ecf20Sopenharmony_ci busovp_offset = bq->chip_info->busovp_sc_offset; 3348c2ecf20Sopenharmony_ci } 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_BUSOVP, &busovp_reg_code); 3378c2ecf20Sopenharmony_ci if (ret) 3388c2ecf20Sopenharmony_ci return ret; 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci return (busovp_reg_code * busovp_step) + busovp_offset; 3418c2ecf20Sopenharmony_ci} 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_cistatic int bq25980_set_input_volt_lim(struct bq25980_device *bq, int busovp) 3448c2ecf20Sopenharmony_ci{ 3458c2ecf20Sopenharmony_ci unsigned int busovp_reg_code; 3468c2ecf20Sopenharmony_ci unsigned int busovp_step; 3478c2ecf20Sopenharmony_ci unsigned int busovp_offset; 3488c2ecf20Sopenharmony_ci int ret; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci if (bq->state.bypass) { 3518c2ecf20Sopenharmony_ci busovp_step = bq->chip_info->busovp_byp_step; 3528c2ecf20Sopenharmony_ci busovp_offset = bq->chip_info->busovp_byp_offset; 3538c2ecf20Sopenharmony_ci if (busovp > bq->chip_info->busovp_byp_max) 3548c2ecf20Sopenharmony_ci busovp = bq->chip_info->busovp_byp_max; 3558c2ecf20Sopenharmony_ci else if (busovp < bq->chip_info->busovp_byp_min) 3568c2ecf20Sopenharmony_ci busovp = bq->chip_info->busovp_byp_min; 3578c2ecf20Sopenharmony_ci } else { 3588c2ecf20Sopenharmony_ci busovp_step = bq->chip_info->busovp_sc_step; 3598c2ecf20Sopenharmony_ci busovp_offset = bq->chip_info->busovp_sc_offset; 3608c2ecf20Sopenharmony_ci if (busovp > bq->chip_info->busovp_sc_max) 3618c2ecf20Sopenharmony_ci busovp = bq->chip_info->busovp_sc_max; 3628c2ecf20Sopenharmony_ci else if (busovp < bq->chip_info->busovp_sc_min) 3638c2ecf20Sopenharmony_ci busovp = bq->chip_info->busovp_sc_min; 3648c2ecf20Sopenharmony_ci } 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci busovp_reg_code = (busovp - busovp_offset) / busovp_step; 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci ret = regmap_write(bq->regmap, BQ25980_BUSOVP, busovp_reg_code); 3698c2ecf20Sopenharmony_ci if (ret) 3708c2ecf20Sopenharmony_ci return ret; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci return regmap_write(bq->regmap, BQ25980_BUSOVP_ALM, busovp_reg_code); 3738c2ecf20Sopenharmony_ci} 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_cistatic int bq25980_get_const_charge_curr(struct bq25980_device *bq) 3768c2ecf20Sopenharmony_ci{ 3778c2ecf20Sopenharmony_ci unsigned int batocp_reg_code; 3788c2ecf20Sopenharmony_ci int ret; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_BATOCP, &batocp_reg_code); 3818c2ecf20Sopenharmony_ci if (ret) 3828c2ecf20Sopenharmony_ci return ret; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci return (batocp_reg_code & BQ25980_BATOCP_MASK) * 3858c2ecf20Sopenharmony_ci BQ25980_BATOCP_STEP_uA; 3868c2ecf20Sopenharmony_ci} 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_cistatic int bq25980_set_const_charge_curr(struct bq25980_device *bq, int batocp) 3898c2ecf20Sopenharmony_ci{ 3908c2ecf20Sopenharmony_ci unsigned int batocp_reg_code; 3918c2ecf20Sopenharmony_ci int ret; 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci batocp = max(batocp, BQ25980_BATOCP_MIN_uA); 3948c2ecf20Sopenharmony_ci batocp = min(batocp, bq->chip_info->batocp_max); 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci batocp_reg_code = batocp / BQ25980_BATOCP_STEP_uA; 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci ret = regmap_update_bits(bq->regmap, BQ25980_BATOCP, 3998c2ecf20Sopenharmony_ci BQ25980_BATOCP_MASK, batocp_reg_code); 4008c2ecf20Sopenharmony_ci if (ret) 4018c2ecf20Sopenharmony_ci return ret; 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci return regmap_update_bits(bq->regmap, BQ25980_BATOCP_ALM, 4048c2ecf20Sopenharmony_ci BQ25980_BATOCP_MASK, batocp_reg_code); 4058c2ecf20Sopenharmony_ci} 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_cistatic int bq25980_get_const_charge_volt(struct bq25980_device *bq) 4088c2ecf20Sopenharmony_ci{ 4098c2ecf20Sopenharmony_ci unsigned int batovp_reg_code; 4108c2ecf20Sopenharmony_ci int ret; 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_BATOVP, &batovp_reg_code); 4138c2ecf20Sopenharmony_ci if (ret) 4148c2ecf20Sopenharmony_ci return ret; 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci return ((batovp_reg_code * bq->chip_info->batovp_step) + 4178c2ecf20Sopenharmony_ci bq->chip_info->batovp_offset); 4188c2ecf20Sopenharmony_ci} 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_cistatic int bq25980_set_const_charge_volt(struct bq25980_device *bq, int batovp) 4218c2ecf20Sopenharmony_ci{ 4228c2ecf20Sopenharmony_ci unsigned int batovp_reg_code; 4238c2ecf20Sopenharmony_ci int ret; 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci if (batovp < bq->chip_info->batovp_min) 4268c2ecf20Sopenharmony_ci batovp = bq->chip_info->batovp_min; 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci if (batovp > bq->chip_info->batovp_max) 4298c2ecf20Sopenharmony_ci batovp = bq->chip_info->batovp_max; 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci batovp_reg_code = (batovp - bq->chip_info->batovp_offset) / 4328c2ecf20Sopenharmony_ci bq->chip_info->batovp_step; 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci ret = regmap_write(bq->regmap, BQ25980_BATOVP, batovp_reg_code); 4358c2ecf20Sopenharmony_ci if (ret) 4368c2ecf20Sopenharmony_ci return ret; 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci return regmap_write(bq->regmap, BQ25980_BATOVP_ALM, batovp_reg_code); 4398c2ecf20Sopenharmony_ci} 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_cistatic int bq25980_set_bypass(struct bq25980_device *bq, bool en_bypass) 4428c2ecf20Sopenharmony_ci{ 4438c2ecf20Sopenharmony_ci int ret; 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci if (en_bypass) 4468c2ecf20Sopenharmony_ci ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 4478c2ecf20Sopenharmony_ci BQ25980_EN_BYPASS, BQ25980_EN_BYPASS); 4488c2ecf20Sopenharmony_ci else 4498c2ecf20Sopenharmony_ci ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 4508c2ecf20Sopenharmony_ci BQ25980_EN_BYPASS, en_bypass); 4518c2ecf20Sopenharmony_ci if (ret) 4528c2ecf20Sopenharmony_ci return ret; 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci bq->state.bypass = en_bypass; 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci return bq->state.bypass; 4578c2ecf20Sopenharmony_ci} 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_cistatic int bq25980_set_chg_en(struct bq25980_device *bq, bool en_chg) 4608c2ecf20Sopenharmony_ci{ 4618c2ecf20Sopenharmony_ci int ret; 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci if (en_chg) 4648c2ecf20Sopenharmony_ci ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 4658c2ecf20Sopenharmony_ci BQ25980_CHG_EN, BQ25980_CHG_EN); 4668c2ecf20Sopenharmony_ci else 4678c2ecf20Sopenharmony_ci ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 4688c2ecf20Sopenharmony_ci BQ25980_CHG_EN, en_chg); 4698c2ecf20Sopenharmony_ci if (ret) 4708c2ecf20Sopenharmony_ci return ret; 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci bq->state.ce = en_chg; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci return 0; 4758c2ecf20Sopenharmony_ci} 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_cistatic int bq25980_get_adc_ibus(struct bq25980_device *bq) 4788c2ecf20Sopenharmony_ci{ 4798c2ecf20Sopenharmony_ci int ibus_adc_lsb, ibus_adc_msb; 4808c2ecf20Sopenharmony_ci u16 ibus_adc; 4818c2ecf20Sopenharmony_ci int ret; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_IBUS_ADC_MSB, &ibus_adc_msb); 4848c2ecf20Sopenharmony_ci if (ret) 4858c2ecf20Sopenharmony_ci return ret; 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_IBUS_ADC_LSB, &ibus_adc_lsb); 4888c2ecf20Sopenharmony_ci if (ret) 4898c2ecf20Sopenharmony_ci return ret; 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci ibus_adc = (ibus_adc_msb << 8) | ibus_adc_lsb; 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci if (ibus_adc_msb & BQ25980_ADC_POLARITY_BIT) 4948c2ecf20Sopenharmony_ci return ((ibus_adc ^ 0xffff) + 1) * BQ25980_ADC_CURR_STEP_uA; 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci return ibus_adc * BQ25980_ADC_CURR_STEP_uA; 4978c2ecf20Sopenharmony_ci} 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_cistatic int bq25980_get_adc_vbus(struct bq25980_device *bq) 5008c2ecf20Sopenharmony_ci{ 5018c2ecf20Sopenharmony_ci int vbus_adc_lsb, vbus_adc_msb; 5028c2ecf20Sopenharmony_ci u16 vbus_adc; 5038c2ecf20Sopenharmony_ci int ret; 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_VBUS_ADC_MSB, &vbus_adc_msb); 5068c2ecf20Sopenharmony_ci if (ret) 5078c2ecf20Sopenharmony_ci return ret; 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_VBUS_ADC_LSB, &vbus_adc_lsb); 5108c2ecf20Sopenharmony_ci if (ret) 5118c2ecf20Sopenharmony_ci return ret; 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci vbus_adc = (vbus_adc_msb << 8) | vbus_adc_lsb; 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci return vbus_adc * BQ25980_ADC_VOLT_STEP_uV; 5168c2ecf20Sopenharmony_ci} 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_cistatic int bq25980_get_ibat_adc(struct bq25980_device *bq) 5198c2ecf20Sopenharmony_ci{ 5208c2ecf20Sopenharmony_ci int ret; 5218c2ecf20Sopenharmony_ci int ibat_adc_lsb, ibat_adc_msb; 5228c2ecf20Sopenharmony_ci int ibat_adc; 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_IBAT_ADC_MSB, &ibat_adc_msb); 5258c2ecf20Sopenharmony_ci if (ret) 5268c2ecf20Sopenharmony_ci return ret; 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_IBAT_ADC_LSB, &ibat_adc_lsb); 5298c2ecf20Sopenharmony_ci if (ret) 5308c2ecf20Sopenharmony_ci return ret; 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci ibat_adc = (ibat_adc_msb << 8) | ibat_adc_lsb; 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci if (ibat_adc_msb & BQ25980_ADC_POLARITY_BIT) 5358c2ecf20Sopenharmony_ci return ((ibat_adc ^ 0xffff) + 1) * BQ25980_ADC_CURR_STEP_uA; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci return ibat_adc * BQ25980_ADC_CURR_STEP_uA; 5388c2ecf20Sopenharmony_ci} 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_cistatic int bq25980_get_adc_vbat(struct bq25980_device *bq) 5418c2ecf20Sopenharmony_ci{ 5428c2ecf20Sopenharmony_ci int vsys_adc_lsb, vsys_adc_msb; 5438c2ecf20Sopenharmony_ci u16 vsys_adc; 5448c2ecf20Sopenharmony_ci int ret; 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_VBAT_ADC_MSB, &vsys_adc_msb); 5478c2ecf20Sopenharmony_ci if (ret) 5488c2ecf20Sopenharmony_ci return ret; 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_VBAT_ADC_LSB, &vsys_adc_lsb); 5518c2ecf20Sopenharmony_ci if (ret) 5528c2ecf20Sopenharmony_ci return ret; 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci vsys_adc = (vsys_adc_msb << 8) | vsys_adc_lsb; 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci return vsys_adc * BQ25980_ADC_VOLT_STEP_uV; 5578c2ecf20Sopenharmony_ci} 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_cistatic int bq25980_get_state(struct bq25980_device *bq, 5608c2ecf20Sopenharmony_ci struct bq25980_state *state) 5618c2ecf20Sopenharmony_ci{ 5628c2ecf20Sopenharmony_ci unsigned int chg_ctrl_2; 5638c2ecf20Sopenharmony_ci unsigned int stat1; 5648c2ecf20Sopenharmony_ci unsigned int stat2; 5658c2ecf20Sopenharmony_ci unsigned int stat3; 5668c2ecf20Sopenharmony_ci unsigned int stat4; 5678c2ecf20Sopenharmony_ci unsigned int ibat_adc_msb; 5688c2ecf20Sopenharmony_ci int ret; 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_STAT1, &stat1); 5718c2ecf20Sopenharmony_ci if (ret) 5728c2ecf20Sopenharmony_ci return ret; 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_STAT2, &stat2); 5758c2ecf20Sopenharmony_ci if (ret) 5768c2ecf20Sopenharmony_ci return ret; 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_STAT3, &stat3); 5798c2ecf20Sopenharmony_ci if (ret) 5808c2ecf20Sopenharmony_ci return ret; 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_STAT4, &stat4); 5838c2ecf20Sopenharmony_ci if (ret) 5848c2ecf20Sopenharmony_ci return ret; 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_CHRGR_CTRL_2, &chg_ctrl_2); 5878c2ecf20Sopenharmony_ci if (ret) 5888c2ecf20Sopenharmony_ci return ret; 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci ret = regmap_read(bq->regmap, BQ25980_IBAT_ADC_MSB, &ibat_adc_msb); 5918c2ecf20Sopenharmony_ci if (ret) 5928c2ecf20Sopenharmony_ci return ret; 5938c2ecf20Sopenharmony_ci 5948c2ecf20Sopenharmony_ci state->dischg = ibat_adc_msb & BQ25980_ADC_POLARITY_BIT; 5958c2ecf20Sopenharmony_ci state->ovp = (stat1 & BQ25980_STAT1_OVP_MASK) | 5968c2ecf20Sopenharmony_ci (stat3 & BQ25980_STAT3_OVP_MASK); 5978c2ecf20Sopenharmony_ci state->ocp = (stat1 & BQ25980_STAT1_OCP_MASK) | 5988c2ecf20Sopenharmony_ci (stat2 & BQ25980_STAT2_OCP_MASK); 5998c2ecf20Sopenharmony_ci state->tflt = stat4 & BQ25980_STAT4_TFLT_MASK; 6008c2ecf20Sopenharmony_ci state->wdt = stat4 & BQ25980_WD_STAT; 6018c2ecf20Sopenharmony_ci state->online = stat3 & BQ25980_PRESENT_MASK; 6028c2ecf20Sopenharmony_ci state->ce = chg_ctrl_2 & BQ25980_CHG_EN; 6038c2ecf20Sopenharmony_ci state->hiz = chg_ctrl_2 & BQ25980_EN_HIZ; 6048c2ecf20Sopenharmony_ci state->bypass = chg_ctrl_2 & BQ25980_EN_BYPASS; 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci return 0; 6078c2ecf20Sopenharmony_ci} 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_cistatic int bq25980_get_battery_property(struct power_supply *psy, 6108c2ecf20Sopenharmony_ci enum power_supply_property psp, 6118c2ecf20Sopenharmony_ci union power_supply_propval *val) 6128c2ecf20Sopenharmony_ci{ 6138c2ecf20Sopenharmony_ci struct bq25980_device *bq = power_supply_get_drvdata(psy); 6148c2ecf20Sopenharmony_ci int ret = 0; 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci switch (psp) { 6178c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 6188c2ecf20Sopenharmony_ci val->intval = bq->init_data.ichg_max; 6198c2ecf20Sopenharmony_ci break; 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 6228c2ecf20Sopenharmony_ci val->intval = bq->init_data.vreg_max; 6238c2ecf20Sopenharmony_ci break; 6248c2ecf20Sopenharmony_ci 6258c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CURRENT_NOW: 6268c2ecf20Sopenharmony_ci ret = bq25980_get_ibat_adc(bq); 6278c2ecf20Sopenharmony_ci val->intval = ret; 6288c2ecf20Sopenharmony_ci break; 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_VOLTAGE_NOW: 6318c2ecf20Sopenharmony_ci ret = bq25980_get_adc_vbat(bq); 6328c2ecf20Sopenharmony_ci if (ret < 0) 6338c2ecf20Sopenharmony_ci return ret; 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci val->intval = ret; 6368c2ecf20Sopenharmony_ci break; 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci default: 6398c2ecf20Sopenharmony_ci return -EINVAL; 6408c2ecf20Sopenharmony_ci } 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci return ret; 6438c2ecf20Sopenharmony_ci} 6448c2ecf20Sopenharmony_ci 6458c2ecf20Sopenharmony_cistatic int bq25980_set_charger_property(struct power_supply *psy, 6468c2ecf20Sopenharmony_ci enum power_supply_property prop, 6478c2ecf20Sopenharmony_ci const union power_supply_propval *val) 6488c2ecf20Sopenharmony_ci{ 6498c2ecf20Sopenharmony_ci struct bq25980_device *bq = power_supply_get_drvdata(psy); 6508c2ecf20Sopenharmony_ci int ret = -EINVAL; 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ci switch (prop) { 6538c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 6548c2ecf20Sopenharmony_ci ret = bq25980_set_input_curr_lim(bq, val->intval); 6558c2ecf20Sopenharmony_ci if (ret) 6568c2ecf20Sopenharmony_ci return ret; 6578c2ecf20Sopenharmony_ci break; 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: 6608c2ecf20Sopenharmony_ci ret = bq25980_set_input_volt_lim(bq, val->intval); 6618c2ecf20Sopenharmony_ci if (ret) 6628c2ecf20Sopenharmony_ci return ret; 6638c2ecf20Sopenharmony_ci break; 6648c2ecf20Sopenharmony_ci 6658c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_TYPE: 6668c2ecf20Sopenharmony_ci ret = bq25980_set_bypass(bq, val->intval); 6678c2ecf20Sopenharmony_ci if (ret) 6688c2ecf20Sopenharmony_ci return ret; 6698c2ecf20Sopenharmony_ci break; 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_STATUS: 6728c2ecf20Sopenharmony_ci ret = bq25980_set_chg_en(bq, val->intval); 6738c2ecf20Sopenharmony_ci if (ret) 6748c2ecf20Sopenharmony_ci return ret; 6758c2ecf20Sopenharmony_ci break; 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 6788c2ecf20Sopenharmony_ci ret = bq25980_set_const_charge_curr(bq, val->intval); 6798c2ecf20Sopenharmony_ci if (ret) 6808c2ecf20Sopenharmony_ci return ret; 6818c2ecf20Sopenharmony_ci break; 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 6848c2ecf20Sopenharmony_ci ret = bq25980_set_const_charge_volt(bq, val->intval); 6858c2ecf20Sopenharmony_ci if (ret) 6868c2ecf20Sopenharmony_ci return ret; 6878c2ecf20Sopenharmony_ci break; 6888c2ecf20Sopenharmony_ci 6898c2ecf20Sopenharmony_ci default: 6908c2ecf20Sopenharmony_ci return -EINVAL; 6918c2ecf20Sopenharmony_ci } 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci return ret; 6948c2ecf20Sopenharmony_ci} 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_cistatic int bq25980_get_charger_property(struct power_supply *psy, 6978c2ecf20Sopenharmony_ci enum power_supply_property psp, 6988c2ecf20Sopenharmony_ci union power_supply_propval *val) 6998c2ecf20Sopenharmony_ci{ 7008c2ecf20Sopenharmony_ci struct bq25980_device *bq = power_supply_get_drvdata(psy); 7018c2ecf20Sopenharmony_ci struct bq25980_state state; 7028c2ecf20Sopenharmony_ci int ret = 0; 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci mutex_lock(&bq->lock); 7058c2ecf20Sopenharmony_ci ret = bq25980_get_state(bq, &state); 7068c2ecf20Sopenharmony_ci mutex_unlock(&bq->lock); 7078c2ecf20Sopenharmony_ci if (ret) 7088c2ecf20Sopenharmony_ci return ret; 7098c2ecf20Sopenharmony_ci 7108c2ecf20Sopenharmony_ci switch (psp) { 7118c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_MANUFACTURER: 7128c2ecf20Sopenharmony_ci val->strval = BQ25980_MANUFACTURER; 7138c2ecf20Sopenharmony_ci break; 7148c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_MODEL_NAME: 7158c2ecf20Sopenharmony_ci val->strval = bq->model_name; 7168c2ecf20Sopenharmony_ci break; 7178c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_ONLINE: 7188c2ecf20Sopenharmony_ci val->intval = state.online; 7198c2ecf20Sopenharmony_ci break; 7208c2ecf20Sopenharmony_ci 7218c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: 7228c2ecf20Sopenharmony_ci ret = bq25980_get_input_volt_lim(bq); 7238c2ecf20Sopenharmony_ci if (ret < 0) 7248c2ecf20Sopenharmony_ci return ret; 7258c2ecf20Sopenharmony_ci val->intval = ret; 7268c2ecf20Sopenharmony_ci break; 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 7298c2ecf20Sopenharmony_ci ret = bq25980_get_input_curr_lim(bq); 7308c2ecf20Sopenharmony_ci if (ret < 0) 7318c2ecf20Sopenharmony_ci return ret; 7328c2ecf20Sopenharmony_ci 7338c2ecf20Sopenharmony_ci val->intval = ret; 7348c2ecf20Sopenharmony_ci break; 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_HEALTH: 7378c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_HEALTH_GOOD; 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci if (state.tflt) 7408c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 7418c2ecf20Sopenharmony_ci else if (state.ovp) 7428c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 7438c2ecf20Sopenharmony_ci else if (state.ocp) 7448c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_HEALTH_OVERCURRENT; 7458c2ecf20Sopenharmony_ci else if (state.wdt) 7468c2ecf20Sopenharmony_ci val->intval = 7478c2ecf20Sopenharmony_ci POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE; 7488c2ecf20Sopenharmony_ci break; 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_STATUS: 7518c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_ci if ((state.ce) && (!state.hiz)) 7548c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_STATUS_CHARGING; 7558c2ecf20Sopenharmony_ci else if (state.dischg) 7568c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 7578c2ecf20Sopenharmony_ci else if (!state.ce) 7588c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 7598c2ecf20Sopenharmony_ci break; 7608c2ecf20Sopenharmony_ci 7618c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_TYPE: 7628c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_ci if (!state.ce) 7658c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; 7668c2ecf20Sopenharmony_ci else if (state.bypass) 7678c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; 7688c2ecf20Sopenharmony_ci else if (!state.bypass) 7698c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD; 7708c2ecf20Sopenharmony_ci break; 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CURRENT_NOW: 7738c2ecf20Sopenharmony_ci ret = bq25980_get_adc_ibus(bq); 7748c2ecf20Sopenharmony_ci if (ret < 0) 7758c2ecf20Sopenharmony_ci return ret; 7768c2ecf20Sopenharmony_ci 7778c2ecf20Sopenharmony_ci val->intval = ret; 7788c2ecf20Sopenharmony_ci break; 7798c2ecf20Sopenharmony_ci 7808c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_VOLTAGE_NOW: 7818c2ecf20Sopenharmony_ci ret = bq25980_get_adc_vbus(bq); 7828c2ecf20Sopenharmony_ci if (ret < 0) 7838c2ecf20Sopenharmony_ci return ret; 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_ci val->intval = ret; 7868c2ecf20Sopenharmony_ci break; 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 7898c2ecf20Sopenharmony_ci ret = bq25980_get_const_charge_curr(bq); 7908c2ecf20Sopenharmony_ci if (ret < 0) 7918c2ecf20Sopenharmony_ci return ret; 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci val->intval = ret; 7948c2ecf20Sopenharmony_ci break; 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 7978c2ecf20Sopenharmony_ci ret = bq25980_get_const_charge_volt(bq); 7988c2ecf20Sopenharmony_ci if (ret < 0) 7998c2ecf20Sopenharmony_ci return ret; 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_ci val->intval = ret; 8028c2ecf20Sopenharmony_ci break; 8038c2ecf20Sopenharmony_ci 8048c2ecf20Sopenharmony_ci default: 8058c2ecf20Sopenharmony_ci return -EINVAL; 8068c2ecf20Sopenharmony_ci } 8078c2ecf20Sopenharmony_ci 8088c2ecf20Sopenharmony_ci return ret; 8098c2ecf20Sopenharmony_ci} 8108c2ecf20Sopenharmony_ci 8118c2ecf20Sopenharmony_cistatic bool bq25980_state_changed(struct bq25980_device *bq, 8128c2ecf20Sopenharmony_ci struct bq25980_state *new_state) 8138c2ecf20Sopenharmony_ci{ 8148c2ecf20Sopenharmony_ci struct bq25980_state old_state; 8158c2ecf20Sopenharmony_ci 8168c2ecf20Sopenharmony_ci mutex_lock(&bq->lock); 8178c2ecf20Sopenharmony_ci old_state = bq->state; 8188c2ecf20Sopenharmony_ci mutex_unlock(&bq->lock); 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_ci return (old_state.dischg != new_state->dischg || 8218c2ecf20Sopenharmony_ci old_state.ovp != new_state->ovp || 8228c2ecf20Sopenharmony_ci old_state.ocp != new_state->ocp || 8238c2ecf20Sopenharmony_ci old_state.online != new_state->online || 8248c2ecf20Sopenharmony_ci old_state.wdt != new_state->wdt || 8258c2ecf20Sopenharmony_ci old_state.tflt != new_state->tflt || 8268c2ecf20Sopenharmony_ci old_state.ce != new_state->ce || 8278c2ecf20Sopenharmony_ci old_state.hiz != new_state->hiz || 8288c2ecf20Sopenharmony_ci old_state.bypass != new_state->bypass); 8298c2ecf20Sopenharmony_ci} 8308c2ecf20Sopenharmony_ci 8318c2ecf20Sopenharmony_cistatic irqreturn_t bq25980_irq_handler_thread(int irq, void *private) 8328c2ecf20Sopenharmony_ci{ 8338c2ecf20Sopenharmony_ci struct bq25980_device *bq = private; 8348c2ecf20Sopenharmony_ci struct bq25980_state state; 8358c2ecf20Sopenharmony_ci int ret; 8368c2ecf20Sopenharmony_ci 8378c2ecf20Sopenharmony_ci ret = bq25980_get_state(bq, &state); 8388c2ecf20Sopenharmony_ci if (ret < 0) 8398c2ecf20Sopenharmony_ci goto irq_out; 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_ci if (!bq25980_state_changed(bq, &state)) 8428c2ecf20Sopenharmony_ci goto irq_out; 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_ci mutex_lock(&bq->lock); 8458c2ecf20Sopenharmony_ci bq->state = state; 8468c2ecf20Sopenharmony_ci mutex_unlock(&bq->lock); 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci power_supply_changed(bq->charger); 8498c2ecf20Sopenharmony_ci 8508c2ecf20Sopenharmony_ciirq_out: 8518c2ecf20Sopenharmony_ci return IRQ_HANDLED; 8528c2ecf20Sopenharmony_ci} 8538c2ecf20Sopenharmony_ci 8548c2ecf20Sopenharmony_cistatic enum power_supply_property bq25980_power_supply_props[] = { 8558c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_MANUFACTURER, 8568c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_MODEL_NAME, 8578c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_STATUS, 8588c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_ONLINE, 8598c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_HEALTH, 8608c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT, 8618c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 8628c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_TYPE, 8638c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 8648c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 8658c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CURRENT_NOW, 8668c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_VOLTAGE_NOW, 8678c2ecf20Sopenharmony_ci}; 8688c2ecf20Sopenharmony_ci 8698c2ecf20Sopenharmony_cistatic enum power_supply_property bq25980_battery_props[] = { 8708c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 8718c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 8728c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CURRENT_NOW, 8738c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_VOLTAGE_NOW, 8748c2ecf20Sopenharmony_ci}; 8758c2ecf20Sopenharmony_ci 8768c2ecf20Sopenharmony_cistatic char *bq25980_charger_supplied_to[] = { 8778c2ecf20Sopenharmony_ci "main-battery", 8788c2ecf20Sopenharmony_ci}; 8798c2ecf20Sopenharmony_ci 8808c2ecf20Sopenharmony_cistatic int bq25980_property_is_writeable(struct power_supply *psy, 8818c2ecf20Sopenharmony_ci enum power_supply_property prop) 8828c2ecf20Sopenharmony_ci{ 8838c2ecf20Sopenharmony_ci switch (prop) { 8848c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 8858c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 8868c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 8878c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_TYPE: 8888c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_STATUS: 8898c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: 8908c2ecf20Sopenharmony_ci return true; 8918c2ecf20Sopenharmony_ci default: 8928c2ecf20Sopenharmony_ci return false; 8938c2ecf20Sopenharmony_ci } 8948c2ecf20Sopenharmony_ci} 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_cistatic const struct power_supply_desc bq25980_power_supply_desc = { 8978c2ecf20Sopenharmony_ci .name = "bq25980-charger", 8988c2ecf20Sopenharmony_ci .type = POWER_SUPPLY_TYPE_MAINS, 8998c2ecf20Sopenharmony_ci .properties = bq25980_power_supply_props, 9008c2ecf20Sopenharmony_ci .num_properties = ARRAY_SIZE(bq25980_power_supply_props), 9018c2ecf20Sopenharmony_ci .get_property = bq25980_get_charger_property, 9028c2ecf20Sopenharmony_ci .set_property = bq25980_set_charger_property, 9038c2ecf20Sopenharmony_ci .property_is_writeable = bq25980_property_is_writeable, 9048c2ecf20Sopenharmony_ci}; 9058c2ecf20Sopenharmony_ci 9068c2ecf20Sopenharmony_cistatic struct power_supply_desc bq25980_battery_desc = { 9078c2ecf20Sopenharmony_ci .name = "bq25980-battery", 9088c2ecf20Sopenharmony_ci .type = POWER_SUPPLY_TYPE_BATTERY, 9098c2ecf20Sopenharmony_ci .get_property = bq25980_get_battery_property, 9108c2ecf20Sopenharmony_ci .properties = bq25980_battery_props, 9118c2ecf20Sopenharmony_ci .num_properties = ARRAY_SIZE(bq25980_battery_props), 9128c2ecf20Sopenharmony_ci .property_is_writeable = bq25980_property_is_writeable, 9138c2ecf20Sopenharmony_ci}; 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_ci 9168c2ecf20Sopenharmony_cistatic bool bq25980_is_volatile_reg(struct device *dev, unsigned int reg) 9178c2ecf20Sopenharmony_ci{ 9188c2ecf20Sopenharmony_ci switch (reg) { 9198c2ecf20Sopenharmony_ci case BQ25980_CHRGR_CTRL_2: 9208c2ecf20Sopenharmony_ci case BQ25980_STAT1...BQ25980_FLAG5: 9218c2ecf20Sopenharmony_ci case BQ25980_ADC_CONTROL1...BQ25980_TDIE_ADC_LSB: 9228c2ecf20Sopenharmony_ci return true; 9238c2ecf20Sopenharmony_ci default: 9248c2ecf20Sopenharmony_ci return false; 9258c2ecf20Sopenharmony_ci } 9268c2ecf20Sopenharmony_ci} 9278c2ecf20Sopenharmony_ci 9288c2ecf20Sopenharmony_cistatic const struct regmap_config bq25980_regmap_config = { 9298c2ecf20Sopenharmony_ci .reg_bits = 8, 9308c2ecf20Sopenharmony_ci .val_bits = 8, 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ci .max_register = BQ25980_CHRGR_CTRL_6, 9338c2ecf20Sopenharmony_ci .reg_defaults = bq25980_reg_defs, 9348c2ecf20Sopenharmony_ci .num_reg_defaults = ARRAY_SIZE(bq25980_reg_defs), 9358c2ecf20Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 9368c2ecf20Sopenharmony_ci .volatile_reg = bq25980_is_volatile_reg, 9378c2ecf20Sopenharmony_ci}; 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_cistatic const struct regmap_config bq25975_regmap_config = { 9408c2ecf20Sopenharmony_ci .reg_bits = 8, 9418c2ecf20Sopenharmony_ci .val_bits = 8, 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci .max_register = BQ25980_CHRGR_CTRL_6, 9448c2ecf20Sopenharmony_ci .reg_defaults = bq25975_reg_defs, 9458c2ecf20Sopenharmony_ci .num_reg_defaults = ARRAY_SIZE(bq25975_reg_defs), 9468c2ecf20Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 9478c2ecf20Sopenharmony_ci .volatile_reg = bq25980_is_volatile_reg, 9488c2ecf20Sopenharmony_ci}; 9498c2ecf20Sopenharmony_ci 9508c2ecf20Sopenharmony_cistatic const struct regmap_config bq25960_regmap_config = { 9518c2ecf20Sopenharmony_ci .reg_bits = 8, 9528c2ecf20Sopenharmony_ci .val_bits = 8, 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ci .max_register = BQ25980_CHRGR_CTRL_6, 9558c2ecf20Sopenharmony_ci .reg_defaults = bq25960_reg_defs, 9568c2ecf20Sopenharmony_ci .num_reg_defaults = ARRAY_SIZE(bq25960_reg_defs), 9578c2ecf20Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 9588c2ecf20Sopenharmony_ci .volatile_reg = bq25980_is_volatile_reg, 9598c2ecf20Sopenharmony_ci}; 9608c2ecf20Sopenharmony_ci 9618c2ecf20Sopenharmony_cistatic const struct bq25980_chip_info bq25980_chip_info_tbl[] = { 9628c2ecf20Sopenharmony_ci [BQ25980] = { 9638c2ecf20Sopenharmony_ci .model_id = BQ25980, 9648c2ecf20Sopenharmony_ci .regmap_config = &bq25980_regmap_config, 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci .busocp_def = BQ25980_BUSOCP_DFLT_uA, 9678c2ecf20Sopenharmony_ci .busocp_sc_min = BQ25960_BUSOCP_SC_MAX_uA, 9688c2ecf20Sopenharmony_ci .busocp_sc_max = BQ25980_BUSOCP_SC_MAX_uA, 9698c2ecf20Sopenharmony_ci .busocp_byp_max = BQ25980_BUSOCP_BYP_MAX_uA, 9708c2ecf20Sopenharmony_ci .busocp_byp_min = BQ25980_BUSOCP_MIN_uA, 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci .busovp_sc_def = BQ25980_BUSOVP_DFLT_uV, 9738c2ecf20Sopenharmony_ci .busovp_byp_def = BQ25980_BUSOVP_BYPASS_DFLT_uV, 9748c2ecf20Sopenharmony_ci .busovp_sc_step = BQ25980_BUSOVP_SC_STEP_uV, 9758c2ecf20Sopenharmony_ci .busovp_sc_offset = BQ25980_BUSOVP_SC_OFFSET_uV, 9768c2ecf20Sopenharmony_ci .busovp_byp_step = BQ25980_BUSOVP_BYP_STEP_uV, 9778c2ecf20Sopenharmony_ci .busovp_byp_offset = BQ25980_BUSOVP_BYP_OFFSET_uV, 9788c2ecf20Sopenharmony_ci .busovp_sc_min = BQ25980_BUSOVP_SC_MIN_uV, 9798c2ecf20Sopenharmony_ci .busovp_sc_max = BQ25980_BUSOVP_SC_MAX_uV, 9808c2ecf20Sopenharmony_ci .busovp_byp_min = BQ25980_BUSOVP_BYP_MIN_uV, 9818c2ecf20Sopenharmony_ci .busovp_byp_max = BQ25980_BUSOVP_BYP_MAX_uV, 9828c2ecf20Sopenharmony_ci 9838c2ecf20Sopenharmony_ci .batovp_def = BQ25980_BATOVP_DFLT_uV, 9848c2ecf20Sopenharmony_ci .batovp_max = BQ25980_BATOVP_MAX_uV, 9858c2ecf20Sopenharmony_ci .batovp_min = BQ25980_BATOVP_MIN_uV, 9868c2ecf20Sopenharmony_ci .batovp_step = BQ25980_BATOVP_STEP_uV, 9878c2ecf20Sopenharmony_ci .batovp_offset = BQ25980_BATOVP_OFFSET_uV, 9888c2ecf20Sopenharmony_ci 9898c2ecf20Sopenharmony_ci .batocp_def = BQ25980_BATOCP_DFLT_uA, 9908c2ecf20Sopenharmony_ci .batocp_max = BQ25980_BATOCP_MAX_uA, 9918c2ecf20Sopenharmony_ci }, 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_ci [BQ25975] = { 9948c2ecf20Sopenharmony_ci .model_id = BQ25975, 9958c2ecf20Sopenharmony_ci .regmap_config = &bq25975_regmap_config, 9968c2ecf20Sopenharmony_ci 9978c2ecf20Sopenharmony_ci .busocp_def = BQ25975_BUSOCP_DFLT_uA, 9988c2ecf20Sopenharmony_ci .busocp_sc_min = BQ25975_BUSOCP_SC_MAX_uA, 9998c2ecf20Sopenharmony_ci .busocp_sc_max = BQ25975_BUSOCP_SC_MAX_uA, 10008c2ecf20Sopenharmony_ci .busocp_byp_min = BQ25980_BUSOCP_MIN_uA, 10018c2ecf20Sopenharmony_ci .busocp_byp_max = BQ25975_BUSOCP_BYP_MAX_uA, 10028c2ecf20Sopenharmony_ci 10038c2ecf20Sopenharmony_ci .busovp_sc_def = BQ25975_BUSOVP_DFLT_uV, 10048c2ecf20Sopenharmony_ci .busovp_byp_def = BQ25975_BUSOVP_BYPASS_DFLT_uV, 10058c2ecf20Sopenharmony_ci .busovp_sc_step = BQ25975_BUSOVP_SC_STEP_uV, 10068c2ecf20Sopenharmony_ci .busovp_sc_offset = BQ25975_BUSOVP_SC_OFFSET_uV, 10078c2ecf20Sopenharmony_ci .busovp_byp_step = BQ25975_BUSOVP_BYP_STEP_uV, 10088c2ecf20Sopenharmony_ci .busovp_byp_offset = BQ25975_BUSOVP_BYP_OFFSET_uV, 10098c2ecf20Sopenharmony_ci .busovp_sc_min = BQ25975_BUSOVP_SC_MIN_uV, 10108c2ecf20Sopenharmony_ci .busovp_sc_max = BQ25975_BUSOVP_SC_MAX_uV, 10118c2ecf20Sopenharmony_ci .busovp_byp_min = BQ25975_BUSOVP_BYP_MIN_uV, 10128c2ecf20Sopenharmony_ci .busovp_byp_max = BQ25975_BUSOVP_BYP_MAX_uV, 10138c2ecf20Sopenharmony_ci 10148c2ecf20Sopenharmony_ci .batovp_def = BQ25975_BATOVP_DFLT_uV, 10158c2ecf20Sopenharmony_ci .batovp_max = BQ25975_BATOVP_MAX_uV, 10168c2ecf20Sopenharmony_ci .batovp_min = BQ25975_BATOVP_MIN_uV, 10178c2ecf20Sopenharmony_ci .batovp_step = BQ25975_BATOVP_STEP_uV, 10188c2ecf20Sopenharmony_ci .batovp_offset = BQ25975_BATOVP_OFFSET_uV, 10198c2ecf20Sopenharmony_ci 10208c2ecf20Sopenharmony_ci .batocp_def = BQ25980_BATOCP_DFLT_uA, 10218c2ecf20Sopenharmony_ci .batocp_max = BQ25980_BATOCP_MAX_uA, 10228c2ecf20Sopenharmony_ci }, 10238c2ecf20Sopenharmony_ci 10248c2ecf20Sopenharmony_ci [BQ25960] = { 10258c2ecf20Sopenharmony_ci .model_id = BQ25960, 10268c2ecf20Sopenharmony_ci .regmap_config = &bq25960_regmap_config, 10278c2ecf20Sopenharmony_ci 10288c2ecf20Sopenharmony_ci .busocp_def = BQ25960_BUSOCP_DFLT_uA, 10298c2ecf20Sopenharmony_ci .busocp_sc_min = BQ25960_BUSOCP_SC_MAX_uA, 10308c2ecf20Sopenharmony_ci .busocp_sc_max = BQ25960_BUSOCP_SC_MAX_uA, 10318c2ecf20Sopenharmony_ci .busocp_byp_min = BQ25960_BUSOCP_SC_MAX_uA, 10328c2ecf20Sopenharmony_ci .busocp_byp_max = BQ25960_BUSOCP_BYP_MAX_uA, 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_ci .busovp_sc_def = BQ25975_BUSOVP_DFLT_uV, 10358c2ecf20Sopenharmony_ci .busovp_byp_def = BQ25975_BUSOVP_BYPASS_DFLT_uV, 10368c2ecf20Sopenharmony_ci .busovp_sc_step = BQ25960_BUSOVP_SC_STEP_uV, 10378c2ecf20Sopenharmony_ci .busovp_sc_offset = BQ25960_BUSOVP_SC_OFFSET_uV, 10388c2ecf20Sopenharmony_ci .busovp_byp_step = BQ25960_BUSOVP_BYP_STEP_uV, 10398c2ecf20Sopenharmony_ci .busovp_byp_offset = BQ25960_BUSOVP_BYP_OFFSET_uV, 10408c2ecf20Sopenharmony_ci .busovp_sc_min = BQ25960_BUSOVP_SC_MIN_uV, 10418c2ecf20Sopenharmony_ci .busovp_sc_max = BQ25960_BUSOVP_SC_MAX_uV, 10428c2ecf20Sopenharmony_ci .busovp_byp_min = BQ25960_BUSOVP_BYP_MIN_uV, 10438c2ecf20Sopenharmony_ci .busovp_byp_max = BQ25960_BUSOVP_BYP_MAX_uV, 10448c2ecf20Sopenharmony_ci 10458c2ecf20Sopenharmony_ci .batovp_def = BQ25960_BATOVP_DFLT_uV, 10468c2ecf20Sopenharmony_ci .batovp_max = BQ25960_BATOVP_MAX_uV, 10478c2ecf20Sopenharmony_ci .batovp_min = BQ25960_BATOVP_MIN_uV, 10488c2ecf20Sopenharmony_ci .batovp_step = BQ25960_BATOVP_STEP_uV, 10498c2ecf20Sopenharmony_ci .batovp_offset = BQ25960_BATOVP_OFFSET_uV, 10508c2ecf20Sopenharmony_ci 10518c2ecf20Sopenharmony_ci .batocp_def = BQ25960_BATOCP_DFLT_uA, 10528c2ecf20Sopenharmony_ci .batocp_max = BQ25960_BATOCP_MAX_uA, 10538c2ecf20Sopenharmony_ci }, 10548c2ecf20Sopenharmony_ci}; 10558c2ecf20Sopenharmony_ci 10568c2ecf20Sopenharmony_cistatic int bq25980_power_supply_init(struct bq25980_device *bq, 10578c2ecf20Sopenharmony_ci struct device *dev) 10588c2ecf20Sopenharmony_ci{ 10598c2ecf20Sopenharmony_ci struct power_supply_config psy_cfg = { .drv_data = bq, 10608c2ecf20Sopenharmony_ci .of_node = dev->of_node, }; 10618c2ecf20Sopenharmony_ci 10628c2ecf20Sopenharmony_ci psy_cfg.supplied_to = bq25980_charger_supplied_to; 10638c2ecf20Sopenharmony_ci psy_cfg.num_supplicants = ARRAY_SIZE(bq25980_charger_supplied_to); 10648c2ecf20Sopenharmony_ci 10658c2ecf20Sopenharmony_ci bq->charger = devm_power_supply_register(bq->dev, 10668c2ecf20Sopenharmony_ci &bq25980_power_supply_desc, 10678c2ecf20Sopenharmony_ci &psy_cfg); 10688c2ecf20Sopenharmony_ci if (IS_ERR(bq->charger)) 10698c2ecf20Sopenharmony_ci return -EINVAL; 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_ci bq->battery = devm_power_supply_register(bq->dev, 10728c2ecf20Sopenharmony_ci &bq25980_battery_desc, 10738c2ecf20Sopenharmony_ci &psy_cfg); 10748c2ecf20Sopenharmony_ci if (IS_ERR(bq->battery)) 10758c2ecf20Sopenharmony_ci return -EINVAL; 10768c2ecf20Sopenharmony_ci 10778c2ecf20Sopenharmony_ci return 0; 10788c2ecf20Sopenharmony_ci} 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_cistatic int bq25980_hw_init(struct bq25980_device *bq) 10818c2ecf20Sopenharmony_ci{ 10828c2ecf20Sopenharmony_ci struct power_supply_battery_info bat_info = { }; 10838c2ecf20Sopenharmony_ci int wd_reg_val = BQ25980_WATCHDOG_DIS; 10848c2ecf20Sopenharmony_ci int wd_max_val = BQ25980_NUM_WD_VAL - 1; 10858c2ecf20Sopenharmony_ci int ret = 0; 10868c2ecf20Sopenharmony_ci int curr_val; 10878c2ecf20Sopenharmony_ci int volt_val; 10888c2ecf20Sopenharmony_ci int i; 10898c2ecf20Sopenharmony_ci 10908c2ecf20Sopenharmony_ci if (bq->watchdog_timer) { 10918c2ecf20Sopenharmony_ci if (bq->watchdog_timer >= bq25980_watchdog_time[wd_max_val]) 10928c2ecf20Sopenharmony_ci wd_reg_val = wd_max_val; 10938c2ecf20Sopenharmony_ci else { 10948c2ecf20Sopenharmony_ci for (i = 0; i < wd_max_val; i++) { 10958c2ecf20Sopenharmony_ci if (bq->watchdog_timer > bq25980_watchdog_time[i] && 10968c2ecf20Sopenharmony_ci bq->watchdog_timer < bq25980_watchdog_time[i + 1]) { 10978c2ecf20Sopenharmony_ci wd_reg_val = i; 10988c2ecf20Sopenharmony_ci break; 10998c2ecf20Sopenharmony_ci } 11008c2ecf20Sopenharmony_ci } 11018c2ecf20Sopenharmony_ci } 11028c2ecf20Sopenharmony_ci } 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_3, 11058c2ecf20Sopenharmony_ci BQ25980_WATCHDOG_MASK, wd_reg_val); 11068c2ecf20Sopenharmony_ci if (ret) 11078c2ecf20Sopenharmony_ci return ret; 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_ci ret = power_supply_get_battery_info(bq->charger, &bat_info); 11108c2ecf20Sopenharmony_ci if (ret) { 11118c2ecf20Sopenharmony_ci dev_warn(bq->dev, "battery info missing\n"); 11128c2ecf20Sopenharmony_ci return -EINVAL; 11138c2ecf20Sopenharmony_ci } 11148c2ecf20Sopenharmony_ci 11158c2ecf20Sopenharmony_ci bq->init_data.ichg_max = bat_info.constant_charge_current_max_ua; 11168c2ecf20Sopenharmony_ci bq->init_data.vreg_max = bat_info.constant_charge_voltage_max_uv; 11178c2ecf20Sopenharmony_ci 11188c2ecf20Sopenharmony_ci if (bq->state.bypass) { 11198c2ecf20Sopenharmony_ci ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 11208c2ecf20Sopenharmony_ci BQ25980_EN_BYPASS, BQ25980_EN_BYPASS); 11218c2ecf20Sopenharmony_ci if (ret) 11228c2ecf20Sopenharmony_ci return ret; 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_ci curr_val = bq->init_data.bypass_ilim; 11258c2ecf20Sopenharmony_ci volt_val = bq->init_data.bypass_vlim; 11268c2ecf20Sopenharmony_ci } else { 11278c2ecf20Sopenharmony_ci curr_val = bq->init_data.sc_ilim; 11288c2ecf20Sopenharmony_ci volt_val = bq->init_data.sc_vlim; 11298c2ecf20Sopenharmony_ci } 11308c2ecf20Sopenharmony_ci 11318c2ecf20Sopenharmony_ci ret = bq25980_set_input_curr_lim(bq, curr_val); 11328c2ecf20Sopenharmony_ci if (ret) 11338c2ecf20Sopenharmony_ci return ret; 11348c2ecf20Sopenharmony_ci 11358c2ecf20Sopenharmony_ci ret = bq25980_set_input_volt_lim(bq, volt_val); 11368c2ecf20Sopenharmony_ci if (ret) 11378c2ecf20Sopenharmony_ci return ret; 11388c2ecf20Sopenharmony_ci 11398c2ecf20Sopenharmony_ci return regmap_update_bits(bq->regmap, BQ25980_ADC_CONTROL1, 11408c2ecf20Sopenharmony_ci BQ25980_ADC_EN, BQ25980_ADC_EN); 11418c2ecf20Sopenharmony_ci} 11428c2ecf20Sopenharmony_ci 11438c2ecf20Sopenharmony_cistatic int bq25980_parse_dt(struct bq25980_device *bq) 11448c2ecf20Sopenharmony_ci{ 11458c2ecf20Sopenharmony_ci int ret; 11468c2ecf20Sopenharmony_ci 11478c2ecf20Sopenharmony_ci ret = device_property_read_u32(bq->dev, "ti,watchdog-timeout-ms", 11488c2ecf20Sopenharmony_ci &bq->watchdog_timer); 11498c2ecf20Sopenharmony_ci if (ret) 11508c2ecf20Sopenharmony_ci bq->watchdog_timer = BQ25980_WATCHDOG_MIN; 11518c2ecf20Sopenharmony_ci 11528c2ecf20Sopenharmony_ci if (bq->watchdog_timer > BQ25980_WATCHDOG_MAX || 11538c2ecf20Sopenharmony_ci bq->watchdog_timer < BQ25980_WATCHDOG_MIN) 11548c2ecf20Sopenharmony_ci return -EINVAL; 11558c2ecf20Sopenharmony_ci 11568c2ecf20Sopenharmony_ci ret = device_property_read_u32(bq->dev, 11578c2ecf20Sopenharmony_ci "ti,sc-ovp-limit-microvolt", 11588c2ecf20Sopenharmony_ci &bq->init_data.sc_vlim); 11598c2ecf20Sopenharmony_ci if (ret) 11608c2ecf20Sopenharmony_ci bq->init_data.sc_vlim = bq->chip_info->busovp_sc_def; 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci if (bq->init_data.sc_vlim > bq->chip_info->busovp_sc_max || 11638c2ecf20Sopenharmony_ci bq->init_data.sc_vlim < bq->chip_info->busovp_sc_min) { 11648c2ecf20Sopenharmony_ci dev_err(bq->dev, "SC ovp limit is out of range\n"); 11658c2ecf20Sopenharmony_ci return -EINVAL; 11668c2ecf20Sopenharmony_ci } 11678c2ecf20Sopenharmony_ci 11688c2ecf20Sopenharmony_ci ret = device_property_read_u32(bq->dev, 11698c2ecf20Sopenharmony_ci "ti,sc-ocp-limit-microamp", 11708c2ecf20Sopenharmony_ci &bq->init_data.sc_ilim); 11718c2ecf20Sopenharmony_ci if (ret) 11728c2ecf20Sopenharmony_ci bq->init_data.sc_ilim = bq->chip_info->busocp_def; 11738c2ecf20Sopenharmony_ci 11748c2ecf20Sopenharmony_ci if (bq->init_data.sc_ilim > bq->chip_info->busocp_sc_max || 11758c2ecf20Sopenharmony_ci bq->init_data.sc_ilim < bq->chip_info->busocp_sc_min) { 11768c2ecf20Sopenharmony_ci dev_err(bq->dev, "SC ocp limit is out of range\n"); 11778c2ecf20Sopenharmony_ci return -EINVAL; 11788c2ecf20Sopenharmony_ci } 11798c2ecf20Sopenharmony_ci 11808c2ecf20Sopenharmony_ci ret = device_property_read_u32(bq->dev, 11818c2ecf20Sopenharmony_ci "ti,bypass-ovp-limit-microvolt", 11828c2ecf20Sopenharmony_ci &bq->init_data.bypass_vlim); 11838c2ecf20Sopenharmony_ci if (ret) 11848c2ecf20Sopenharmony_ci bq->init_data.bypass_vlim = bq->chip_info->busovp_byp_def; 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_ci if (bq->init_data.bypass_vlim > bq->chip_info->busovp_byp_max || 11878c2ecf20Sopenharmony_ci bq->init_data.bypass_vlim < bq->chip_info->busovp_byp_min) { 11888c2ecf20Sopenharmony_ci dev_err(bq->dev, "Bypass ovp limit is out of range\n"); 11898c2ecf20Sopenharmony_ci return -EINVAL; 11908c2ecf20Sopenharmony_ci } 11918c2ecf20Sopenharmony_ci 11928c2ecf20Sopenharmony_ci ret = device_property_read_u32(bq->dev, 11938c2ecf20Sopenharmony_ci "ti,bypass-ocp-limit-microamp", 11948c2ecf20Sopenharmony_ci &bq->init_data.bypass_ilim); 11958c2ecf20Sopenharmony_ci if (ret) 11968c2ecf20Sopenharmony_ci bq->init_data.bypass_ilim = bq->chip_info->busocp_def; 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_ci if (bq->init_data.bypass_ilim > bq->chip_info->busocp_byp_max || 11998c2ecf20Sopenharmony_ci bq->init_data.bypass_ilim < bq->chip_info->busocp_byp_min) { 12008c2ecf20Sopenharmony_ci dev_err(bq->dev, "Bypass ocp limit is out of range\n"); 12018c2ecf20Sopenharmony_ci return -EINVAL; 12028c2ecf20Sopenharmony_ci } 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_ci 12058c2ecf20Sopenharmony_ci bq->state.bypass = device_property_read_bool(bq->dev, 12068c2ecf20Sopenharmony_ci "ti,bypass-enable"); 12078c2ecf20Sopenharmony_ci return 0; 12088c2ecf20Sopenharmony_ci} 12098c2ecf20Sopenharmony_ci 12108c2ecf20Sopenharmony_cistatic int bq25980_probe(struct i2c_client *client, 12118c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 12128c2ecf20Sopenharmony_ci{ 12138c2ecf20Sopenharmony_ci struct device *dev = &client->dev; 12148c2ecf20Sopenharmony_ci struct bq25980_device *bq; 12158c2ecf20Sopenharmony_ci int ret; 12168c2ecf20Sopenharmony_ci 12178c2ecf20Sopenharmony_ci bq = devm_kzalloc(dev, sizeof(*bq), GFP_KERNEL); 12188c2ecf20Sopenharmony_ci if (!bq) 12198c2ecf20Sopenharmony_ci return -ENOMEM; 12208c2ecf20Sopenharmony_ci 12218c2ecf20Sopenharmony_ci bq->client = client; 12228c2ecf20Sopenharmony_ci bq->dev = dev; 12238c2ecf20Sopenharmony_ci 12248c2ecf20Sopenharmony_ci mutex_init(&bq->lock); 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_ci strncpy(bq->model_name, id->name, I2C_NAME_SIZE); 12278c2ecf20Sopenharmony_ci bq->chip_info = &bq25980_chip_info_tbl[id->driver_data]; 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_ci bq->regmap = devm_regmap_init_i2c(client, 12308c2ecf20Sopenharmony_ci bq->chip_info->regmap_config); 12318c2ecf20Sopenharmony_ci if (IS_ERR(bq->regmap)) { 12328c2ecf20Sopenharmony_ci dev_err(dev, "Failed to allocate register map\n"); 12338c2ecf20Sopenharmony_ci return PTR_ERR(bq->regmap); 12348c2ecf20Sopenharmony_ci } 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_ci i2c_set_clientdata(client, bq); 12378c2ecf20Sopenharmony_ci 12388c2ecf20Sopenharmony_ci ret = bq25980_parse_dt(bq); 12398c2ecf20Sopenharmony_ci if (ret) { 12408c2ecf20Sopenharmony_ci dev_err(dev, "Failed to read device tree properties%d\n", ret); 12418c2ecf20Sopenharmony_ci return ret; 12428c2ecf20Sopenharmony_ci } 12438c2ecf20Sopenharmony_ci 12448c2ecf20Sopenharmony_ci if (client->irq) { 12458c2ecf20Sopenharmony_ci ret = devm_request_threaded_irq(dev, client->irq, NULL, 12468c2ecf20Sopenharmony_ci bq25980_irq_handler_thread, 12478c2ecf20Sopenharmony_ci IRQF_TRIGGER_FALLING | 12488c2ecf20Sopenharmony_ci IRQF_ONESHOT, 12498c2ecf20Sopenharmony_ci dev_name(&client->dev), bq); 12508c2ecf20Sopenharmony_ci if (ret) 12518c2ecf20Sopenharmony_ci return ret; 12528c2ecf20Sopenharmony_ci } 12538c2ecf20Sopenharmony_ci 12548c2ecf20Sopenharmony_ci ret = bq25980_power_supply_init(bq, dev); 12558c2ecf20Sopenharmony_ci if (ret) { 12568c2ecf20Sopenharmony_ci dev_err(dev, "Failed to register power supply\n"); 12578c2ecf20Sopenharmony_ci return ret; 12588c2ecf20Sopenharmony_ci } 12598c2ecf20Sopenharmony_ci 12608c2ecf20Sopenharmony_ci ret = bq25980_hw_init(bq); 12618c2ecf20Sopenharmony_ci if (ret) { 12628c2ecf20Sopenharmony_ci dev_err(dev, "Cannot initialize the chip.\n"); 12638c2ecf20Sopenharmony_ci return ret; 12648c2ecf20Sopenharmony_ci } 12658c2ecf20Sopenharmony_ci 12668c2ecf20Sopenharmony_ci return 0; 12678c2ecf20Sopenharmony_ci} 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_cistatic const struct i2c_device_id bq25980_i2c_ids[] = { 12708c2ecf20Sopenharmony_ci { "bq25980", BQ25980 }, 12718c2ecf20Sopenharmony_ci { "bq25975", BQ25975 }, 12728c2ecf20Sopenharmony_ci { "bq25975", BQ25975 }, 12738c2ecf20Sopenharmony_ci {}, 12748c2ecf20Sopenharmony_ci}; 12758c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, bq25980_i2c_ids); 12768c2ecf20Sopenharmony_ci 12778c2ecf20Sopenharmony_cistatic const struct of_device_id bq25980_of_match[] = { 12788c2ecf20Sopenharmony_ci { .compatible = "ti,bq25980", .data = (void *)BQ25980 }, 12798c2ecf20Sopenharmony_ci { .compatible = "ti,bq25975", .data = (void *)BQ25975 }, 12808c2ecf20Sopenharmony_ci { .compatible = "ti,bq25960", .data = (void *)BQ25960 }, 12818c2ecf20Sopenharmony_ci { }, 12828c2ecf20Sopenharmony_ci}; 12838c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, bq25980_of_match); 12848c2ecf20Sopenharmony_ci 12858c2ecf20Sopenharmony_cistatic struct i2c_driver bq25980_driver = { 12868c2ecf20Sopenharmony_ci .driver = { 12878c2ecf20Sopenharmony_ci .name = "bq25980-charger", 12888c2ecf20Sopenharmony_ci .of_match_table = bq25980_of_match, 12898c2ecf20Sopenharmony_ci }, 12908c2ecf20Sopenharmony_ci .probe = bq25980_probe, 12918c2ecf20Sopenharmony_ci .id_table = bq25980_i2c_ids, 12928c2ecf20Sopenharmony_ci}; 12938c2ecf20Sopenharmony_cimodule_i2c_driver(bq25980_driver); 12948c2ecf20Sopenharmony_ci 12958c2ecf20Sopenharmony_ciMODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 12968c2ecf20Sopenharmony_ciMODULE_AUTHOR("Ricardo Rivera-Matos <r-rivera-matos@ti.com>"); 12978c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("bq25980 charger driver"); 12988c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 1299