1*5069185fSDan Murphy // SPDX-License-Identifier: GPL-2.0 2*5069185fSDan Murphy // BQ25980 Battery Charger Driver 3*5069185fSDan Murphy // Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ 4*5069185fSDan Murphy 5*5069185fSDan Murphy #include <linux/err.h> 6*5069185fSDan Murphy #include <linux/i2c.h> 7*5069185fSDan Murphy #include <linux/init.h> 8*5069185fSDan Murphy #include <linux/interrupt.h> 9*5069185fSDan Murphy #include <linux/kernel.h> 10*5069185fSDan Murphy #include <linux/module.h> 11*5069185fSDan Murphy #include <linux/gpio/consumer.h> 12*5069185fSDan Murphy #include <linux/power_supply.h> 13*5069185fSDan Murphy #include <linux/regmap.h> 14*5069185fSDan Murphy #include <linux/types.h> 15*5069185fSDan Murphy #include <linux/delay.h> 16*5069185fSDan Murphy #include <linux/device.h> 17*5069185fSDan Murphy #include <linux/moduleparam.h> 18*5069185fSDan Murphy #include <linux/slab.h> 19*5069185fSDan Murphy 20*5069185fSDan Murphy #include "bq25980_charger.h" 21*5069185fSDan Murphy 22*5069185fSDan Murphy struct bq25980_state { 23*5069185fSDan Murphy bool dischg; 24*5069185fSDan Murphy bool ovp; 25*5069185fSDan Murphy bool ocp; 26*5069185fSDan Murphy bool wdt; 27*5069185fSDan Murphy bool tflt; 28*5069185fSDan Murphy bool online; 29*5069185fSDan Murphy bool ce; 30*5069185fSDan Murphy bool hiz; 31*5069185fSDan Murphy bool bypass; 32*5069185fSDan Murphy 33*5069185fSDan Murphy u32 vbat_adc; 34*5069185fSDan Murphy u32 vsys_adc; 35*5069185fSDan Murphy u32 ibat_adc; 36*5069185fSDan Murphy }; 37*5069185fSDan Murphy 38*5069185fSDan Murphy enum bq25980_id { 39*5069185fSDan Murphy BQ25980, 40*5069185fSDan Murphy BQ25975, 41*5069185fSDan Murphy BQ25960, 42*5069185fSDan Murphy }; 43*5069185fSDan Murphy 44*5069185fSDan Murphy struct bq25980_chip_info { 45*5069185fSDan Murphy 46*5069185fSDan Murphy int model_id; 47*5069185fSDan Murphy 48*5069185fSDan Murphy const struct regmap_config *regmap_config; 49*5069185fSDan Murphy 50*5069185fSDan Murphy int busocp_def; 51*5069185fSDan Murphy int busocp_sc_max; 52*5069185fSDan Murphy int busocp_byp_max; 53*5069185fSDan Murphy int busocp_sc_min; 54*5069185fSDan Murphy int busocp_byp_min; 55*5069185fSDan Murphy 56*5069185fSDan Murphy int busovp_sc_def; 57*5069185fSDan Murphy int busovp_byp_def; 58*5069185fSDan Murphy int busovp_sc_step; 59*5069185fSDan Murphy 60*5069185fSDan Murphy int busovp_sc_offset; 61*5069185fSDan Murphy int busovp_byp_step; 62*5069185fSDan Murphy int busovp_byp_offset; 63*5069185fSDan Murphy int busovp_sc_min; 64*5069185fSDan Murphy int busovp_sc_max; 65*5069185fSDan Murphy int busovp_byp_min; 66*5069185fSDan Murphy int busovp_byp_max; 67*5069185fSDan Murphy 68*5069185fSDan Murphy int batovp_def; 69*5069185fSDan Murphy int batovp_max; 70*5069185fSDan Murphy int batovp_min; 71*5069185fSDan Murphy int batovp_step; 72*5069185fSDan Murphy int batovp_offset; 73*5069185fSDan Murphy 74*5069185fSDan Murphy int batocp_def; 75*5069185fSDan Murphy int batocp_max; 76*5069185fSDan Murphy }; 77*5069185fSDan Murphy 78*5069185fSDan Murphy struct bq25980_init_data { 79*5069185fSDan Murphy u32 ichg; 80*5069185fSDan Murphy u32 bypass_ilim; 81*5069185fSDan Murphy u32 sc_ilim; 82*5069185fSDan Murphy u32 vreg; 83*5069185fSDan Murphy u32 iterm; 84*5069185fSDan Murphy u32 iprechg; 85*5069185fSDan Murphy u32 bypass_vlim; 86*5069185fSDan Murphy u32 sc_vlim; 87*5069185fSDan Murphy u32 ichg_max; 88*5069185fSDan Murphy u32 vreg_max; 89*5069185fSDan Murphy }; 90*5069185fSDan Murphy 91*5069185fSDan Murphy struct bq25980_device { 92*5069185fSDan Murphy struct i2c_client *client; 93*5069185fSDan Murphy struct device *dev; 94*5069185fSDan Murphy struct power_supply *charger; 95*5069185fSDan Murphy struct power_supply *battery; 96*5069185fSDan Murphy struct mutex lock; 97*5069185fSDan Murphy struct regmap *regmap; 98*5069185fSDan Murphy 99*5069185fSDan Murphy char model_name[I2C_NAME_SIZE]; 100*5069185fSDan Murphy 101*5069185fSDan Murphy struct bq25980_init_data init_data; 102*5069185fSDan Murphy const struct bq25980_chip_info *chip_info; 103*5069185fSDan Murphy struct bq25980_state state; 104*5069185fSDan Murphy int watchdog_timer; 105*5069185fSDan Murphy }; 106*5069185fSDan Murphy 107*5069185fSDan Murphy static struct reg_default bq25980_reg_defs[] = { 108*5069185fSDan Murphy {BQ25980_BATOVP, 0x5A}, 109*5069185fSDan Murphy {BQ25980_BATOVP_ALM, 0x46}, 110*5069185fSDan Murphy {BQ25980_BATOCP, 0x51}, 111*5069185fSDan Murphy {BQ25980_BATOCP_ALM, 0x50}, 112*5069185fSDan Murphy {BQ25980_BATUCP_ALM, 0x28}, 113*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_1, 0x0}, 114*5069185fSDan Murphy {BQ25980_BUSOVP, 0x26}, 115*5069185fSDan Murphy {BQ25980_BUSOVP_ALM, 0x22}, 116*5069185fSDan Murphy {BQ25980_BUSOCP, 0xD}, 117*5069185fSDan Murphy {BQ25980_BUSOCP_ALM, 0xC}, 118*5069185fSDan Murphy {BQ25980_TEMP_CONTROL, 0x30}, 119*5069185fSDan Murphy {BQ25980_TDIE_ALM, 0xC8}, 120*5069185fSDan Murphy {BQ25980_TSBUS_FLT, 0x15}, 121*5069185fSDan Murphy {BQ25980_TSBAT_FLG, 0x15}, 122*5069185fSDan Murphy {BQ25980_VAC_CONTROL, 0x0}, 123*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_2, 0x0}, 124*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_3, 0x20}, 125*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_4, 0x1D}, 126*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_5, 0x18}, 127*5069185fSDan Murphy {BQ25980_STAT1, 0x0}, 128*5069185fSDan Murphy {BQ25980_STAT2, 0x0}, 129*5069185fSDan Murphy {BQ25980_STAT3, 0x0}, 130*5069185fSDan Murphy {BQ25980_STAT4, 0x0}, 131*5069185fSDan Murphy {BQ25980_STAT5, 0x0}, 132*5069185fSDan Murphy {BQ25980_FLAG1, 0x0}, 133*5069185fSDan Murphy {BQ25980_FLAG2, 0x0}, 134*5069185fSDan Murphy {BQ25980_FLAG3, 0x0}, 135*5069185fSDan Murphy {BQ25980_FLAG4, 0x0}, 136*5069185fSDan Murphy {BQ25980_FLAG5, 0x0}, 137*5069185fSDan Murphy {BQ25980_MASK1, 0x0}, 138*5069185fSDan Murphy {BQ25980_MASK2, 0x0}, 139*5069185fSDan Murphy {BQ25980_MASK3, 0x0}, 140*5069185fSDan Murphy {BQ25980_MASK4, 0x0}, 141*5069185fSDan Murphy {BQ25980_MASK5, 0x0}, 142*5069185fSDan Murphy {BQ25980_DEVICE_INFO, 0x8}, 143*5069185fSDan Murphy {BQ25980_ADC_CONTROL1, 0x0}, 144*5069185fSDan Murphy {BQ25980_ADC_CONTROL2, 0x0}, 145*5069185fSDan Murphy {BQ25980_IBUS_ADC_LSB, 0x0}, 146*5069185fSDan Murphy {BQ25980_IBUS_ADC_MSB, 0x0}, 147*5069185fSDan Murphy {BQ25980_VBUS_ADC_LSB, 0x0}, 148*5069185fSDan Murphy {BQ25980_VBUS_ADC_MSB, 0x0}, 149*5069185fSDan Murphy {BQ25980_VAC1_ADC_LSB, 0x0}, 150*5069185fSDan Murphy {BQ25980_VAC2_ADC_LSB, 0x0}, 151*5069185fSDan Murphy {BQ25980_VOUT_ADC_LSB, 0x0}, 152*5069185fSDan Murphy {BQ25980_VBAT_ADC_LSB, 0x0}, 153*5069185fSDan Murphy {BQ25980_IBAT_ADC_MSB, 0x0}, 154*5069185fSDan Murphy {BQ25980_IBAT_ADC_LSB, 0x0}, 155*5069185fSDan Murphy {BQ25980_TSBUS_ADC_LSB, 0x0}, 156*5069185fSDan Murphy {BQ25980_TSBAT_ADC_LSB, 0x0}, 157*5069185fSDan Murphy {BQ25980_TDIE_ADC_LSB, 0x0}, 158*5069185fSDan Murphy {BQ25980_DEGLITCH_TIME, 0x0}, 159*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_6, 0x0}, 160*5069185fSDan Murphy }; 161*5069185fSDan Murphy 162*5069185fSDan Murphy static struct reg_default bq25975_reg_defs[] = { 163*5069185fSDan Murphy {BQ25980_BATOVP, 0x5A}, 164*5069185fSDan Murphy {BQ25980_BATOVP_ALM, 0x46}, 165*5069185fSDan Murphy {BQ25980_BATOCP, 0x51}, 166*5069185fSDan Murphy {BQ25980_BATOCP_ALM, 0x50}, 167*5069185fSDan Murphy {BQ25980_BATUCP_ALM, 0x28}, 168*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_1, 0x0}, 169*5069185fSDan Murphy {BQ25980_BUSOVP, 0x26}, 170*5069185fSDan Murphy {BQ25980_BUSOVP_ALM, 0x22}, 171*5069185fSDan Murphy {BQ25980_BUSOCP, 0xD}, 172*5069185fSDan Murphy {BQ25980_BUSOCP_ALM, 0xC}, 173*5069185fSDan Murphy {BQ25980_TEMP_CONTROL, 0x30}, 174*5069185fSDan Murphy {BQ25980_TDIE_ALM, 0xC8}, 175*5069185fSDan Murphy {BQ25980_TSBUS_FLT, 0x15}, 176*5069185fSDan Murphy {BQ25980_TSBAT_FLG, 0x15}, 177*5069185fSDan Murphy {BQ25980_VAC_CONTROL, 0x0}, 178*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_2, 0x0}, 179*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_3, 0x20}, 180*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_4, 0x1D}, 181*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_5, 0x18}, 182*5069185fSDan Murphy {BQ25980_STAT1, 0x0}, 183*5069185fSDan Murphy {BQ25980_STAT2, 0x0}, 184*5069185fSDan Murphy {BQ25980_STAT3, 0x0}, 185*5069185fSDan Murphy {BQ25980_STAT4, 0x0}, 186*5069185fSDan Murphy {BQ25980_STAT5, 0x0}, 187*5069185fSDan Murphy {BQ25980_FLAG1, 0x0}, 188*5069185fSDan Murphy {BQ25980_FLAG2, 0x0}, 189*5069185fSDan Murphy {BQ25980_FLAG3, 0x0}, 190*5069185fSDan Murphy {BQ25980_FLAG4, 0x0}, 191*5069185fSDan Murphy {BQ25980_FLAG5, 0x0}, 192*5069185fSDan Murphy {BQ25980_MASK1, 0x0}, 193*5069185fSDan Murphy {BQ25980_MASK2, 0x0}, 194*5069185fSDan Murphy {BQ25980_MASK3, 0x0}, 195*5069185fSDan Murphy {BQ25980_MASK4, 0x0}, 196*5069185fSDan Murphy {BQ25980_MASK5, 0x0}, 197*5069185fSDan Murphy {BQ25980_DEVICE_INFO, 0x8}, 198*5069185fSDan Murphy {BQ25980_ADC_CONTROL1, 0x0}, 199*5069185fSDan Murphy {BQ25980_ADC_CONTROL2, 0x0}, 200*5069185fSDan Murphy {BQ25980_IBUS_ADC_LSB, 0x0}, 201*5069185fSDan Murphy {BQ25980_IBUS_ADC_MSB, 0x0}, 202*5069185fSDan Murphy {BQ25980_VBUS_ADC_LSB, 0x0}, 203*5069185fSDan Murphy {BQ25980_VBUS_ADC_MSB, 0x0}, 204*5069185fSDan Murphy {BQ25980_VAC1_ADC_LSB, 0x0}, 205*5069185fSDan Murphy {BQ25980_VAC2_ADC_LSB, 0x0}, 206*5069185fSDan Murphy {BQ25980_VOUT_ADC_LSB, 0x0}, 207*5069185fSDan Murphy {BQ25980_VBAT_ADC_LSB, 0x0}, 208*5069185fSDan Murphy {BQ25980_IBAT_ADC_MSB, 0x0}, 209*5069185fSDan Murphy {BQ25980_IBAT_ADC_LSB, 0x0}, 210*5069185fSDan Murphy {BQ25980_TSBUS_ADC_LSB, 0x0}, 211*5069185fSDan Murphy {BQ25980_TSBAT_ADC_LSB, 0x0}, 212*5069185fSDan Murphy {BQ25980_TDIE_ADC_LSB, 0x0}, 213*5069185fSDan Murphy {BQ25980_DEGLITCH_TIME, 0x0}, 214*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_6, 0x0}, 215*5069185fSDan Murphy }; 216*5069185fSDan Murphy 217*5069185fSDan Murphy static struct reg_default bq25960_reg_defs[] = { 218*5069185fSDan Murphy {BQ25980_BATOVP, 0x5A}, 219*5069185fSDan Murphy {BQ25980_BATOVP_ALM, 0x46}, 220*5069185fSDan Murphy {BQ25980_BATOCP, 0x51}, 221*5069185fSDan Murphy {BQ25980_BATOCP_ALM, 0x50}, 222*5069185fSDan Murphy {BQ25980_BATUCP_ALM, 0x28}, 223*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_1, 0x0}, 224*5069185fSDan Murphy {BQ25980_BUSOVP, 0x26}, 225*5069185fSDan Murphy {BQ25980_BUSOVP_ALM, 0x22}, 226*5069185fSDan Murphy {BQ25980_BUSOCP, 0xD}, 227*5069185fSDan Murphy {BQ25980_BUSOCP_ALM, 0xC}, 228*5069185fSDan Murphy {BQ25980_TEMP_CONTROL, 0x30}, 229*5069185fSDan Murphy {BQ25980_TDIE_ALM, 0xC8}, 230*5069185fSDan Murphy {BQ25980_TSBUS_FLT, 0x15}, 231*5069185fSDan Murphy {BQ25980_TSBAT_FLG, 0x15}, 232*5069185fSDan Murphy {BQ25980_VAC_CONTROL, 0x0}, 233*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_2, 0x0}, 234*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_3, 0x20}, 235*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_4, 0x1D}, 236*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_5, 0x18}, 237*5069185fSDan Murphy {BQ25980_STAT1, 0x0}, 238*5069185fSDan Murphy {BQ25980_STAT2, 0x0}, 239*5069185fSDan Murphy {BQ25980_STAT3, 0x0}, 240*5069185fSDan Murphy {BQ25980_STAT4, 0x0}, 241*5069185fSDan Murphy {BQ25980_STAT5, 0x0}, 242*5069185fSDan Murphy {BQ25980_FLAG1, 0x0}, 243*5069185fSDan Murphy {BQ25980_FLAG2, 0x0}, 244*5069185fSDan Murphy {BQ25980_FLAG3, 0x0}, 245*5069185fSDan Murphy {BQ25980_FLAG4, 0x0}, 246*5069185fSDan Murphy {BQ25980_FLAG5, 0x0}, 247*5069185fSDan Murphy {BQ25980_MASK1, 0x0}, 248*5069185fSDan Murphy {BQ25980_MASK2, 0x0}, 249*5069185fSDan Murphy {BQ25980_MASK3, 0x0}, 250*5069185fSDan Murphy {BQ25980_MASK4, 0x0}, 251*5069185fSDan Murphy {BQ25980_MASK5, 0x0}, 252*5069185fSDan Murphy {BQ25980_DEVICE_INFO, 0x8}, 253*5069185fSDan Murphy {BQ25980_ADC_CONTROL1, 0x0}, 254*5069185fSDan Murphy {BQ25980_ADC_CONTROL2, 0x0}, 255*5069185fSDan Murphy {BQ25980_IBUS_ADC_LSB, 0x0}, 256*5069185fSDan Murphy {BQ25980_IBUS_ADC_MSB, 0x0}, 257*5069185fSDan Murphy {BQ25980_VBUS_ADC_LSB, 0x0}, 258*5069185fSDan Murphy {BQ25980_VBUS_ADC_MSB, 0x0}, 259*5069185fSDan Murphy {BQ25980_VAC1_ADC_LSB, 0x0}, 260*5069185fSDan Murphy {BQ25980_VAC2_ADC_LSB, 0x0}, 261*5069185fSDan Murphy {BQ25980_VOUT_ADC_LSB, 0x0}, 262*5069185fSDan Murphy {BQ25980_VBAT_ADC_LSB, 0x0}, 263*5069185fSDan Murphy {BQ25980_IBAT_ADC_MSB, 0x0}, 264*5069185fSDan Murphy {BQ25980_IBAT_ADC_LSB, 0x0}, 265*5069185fSDan Murphy {BQ25980_TSBUS_ADC_LSB, 0x0}, 266*5069185fSDan Murphy {BQ25980_TSBAT_ADC_LSB, 0x0}, 267*5069185fSDan Murphy {BQ25980_TDIE_ADC_LSB, 0x0}, 268*5069185fSDan Murphy {BQ25980_DEGLITCH_TIME, 0x0}, 269*5069185fSDan Murphy {BQ25980_CHRGR_CTRL_6, 0x0}, 270*5069185fSDan Murphy }; 271*5069185fSDan Murphy 272*5069185fSDan Murphy static int bq25980_watchdog_time[BQ25980_NUM_WD_VAL] = {5000, 10000, 50000, 273*5069185fSDan Murphy 300000}; 274*5069185fSDan Murphy 275*5069185fSDan Murphy static int bq25980_get_input_curr_lim(struct bq25980_device *bq) 276*5069185fSDan Murphy { 277*5069185fSDan Murphy unsigned int busocp_reg_code; 278*5069185fSDan Murphy int ret; 279*5069185fSDan Murphy 280*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_BUSOCP, &busocp_reg_code); 281*5069185fSDan Murphy if (ret) 282*5069185fSDan Murphy return ret; 283*5069185fSDan Murphy 284*5069185fSDan Murphy return (busocp_reg_code * BQ25980_BUSOCP_STEP_uA) + BQ25980_BUSOCP_OFFSET_uA; 285*5069185fSDan Murphy } 286*5069185fSDan Murphy 287*5069185fSDan Murphy static int bq25980_set_hiz(struct bq25980_device *bq, int setting) 288*5069185fSDan Murphy { 289*5069185fSDan Murphy return regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 290*5069185fSDan Murphy BQ25980_EN_HIZ, setting); 291*5069185fSDan Murphy } 292*5069185fSDan Murphy 293*5069185fSDan Murphy static int bq25980_set_input_curr_lim(struct bq25980_device *bq, int busocp) 294*5069185fSDan Murphy { 295*5069185fSDan Murphy unsigned int busocp_reg_code; 296*5069185fSDan Murphy int ret; 297*5069185fSDan Murphy 298*5069185fSDan Murphy if (!busocp) 299*5069185fSDan Murphy return bq25980_set_hiz(bq, BQ25980_ENABLE_HIZ); 300*5069185fSDan Murphy 301*5069185fSDan Murphy bq25980_set_hiz(bq, BQ25980_DISABLE_HIZ); 302*5069185fSDan Murphy 303*5069185fSDan Murphy if (busocp < BQ25980_BUSOCP_MIN_uA) 304*5069185fSDan Murphy busocp = BQ25980_BUSOCP_MIN_uA; 305*5069185fSDan Murphy 306*5069185fSDan Murphy if (bq->state.bypass) 307*5069185fSDan Murphy busocp = min(busocp, bq->chip_info->busocp_sc_max); 308*5069185fSDan Murphy else 309*5069185fSDan Murphy busocp = min(busocp, bq->chip_info->busocp_byp_max); 310*5069185fSDan Murphy 311*5069185fSDan Murphy busocp_reg_code = (busocp - BQ25980_BUSOCP_OFFSET_uA) 312*5069185fSDan Murphy / BQ25980_BUSOCP_STEP_uA; 313*5069185fSDan Murphy 314*5069185fSDan Murphy ret = regmap_write(bq->regmap, BQ25980_BUSOCP, busocp_reg_code); 315*5069185fSDan Murphy if (ret) 316*5069185fSDan Murphy return ret; 317*5069185fSDan Murphy 318*5069185fSDan Murphy return regmap_write(bq->regmap, BQ25980_BUSOCP_ALM, busocp_reg_code); 319*5069185fSDan Murphy } 320*5069185fSDan Murphy 321*5069185fSDan Murphy static int bq25980_get_input_volt_lim(struct bq25980_device *bq) 322*5069185fSDan Murphy { 323*5069185fSDan Murphy unsigned int busovp_reg_code; 324*5069185fSDan Murphy unsigned int busovp_offset; 325*5069185fSDan Murphy unsigned int busovp_step; 326*5069185fSDan Murphy int ret; 327*5069185fSDan Murphy 328*5069185fSDan Murphy if (bq->state.bypass) { 329*5069185fSDan Murphy busovp_step = bq->chip_info->busovp_byp_step; 330*5069185fSDan Murphy busovp_offset = bq->chip_info->busovp_byp_offset; 331*5069185fSDan Murphy } else { 332*5069185fSDan Murphy busovp_step = bq->chip_info->busovp_sc_step; 333*5069185fSDan Murphy busovp_offset = bq->chip_info->busovp_sc_offset; 334*5069185fSDan Murphy } 335*5069185fSDan Murphy 336*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_BUSOVP, &busovp_reg_code); 337*5069185fSDan Murphy if (ret) 338*5069185fSDan Murphy return ret; 339*5069185fSDan Murphy 340*5069185fSDan Murphy return (busovp_reg_code * busovp_step) + busovp_offset; 341*5069185fSDan Murphy } 342*5069185fSDan Murphy 343*5069185fSDan Murphy static int bq25980_set_input_volt_lim(struct bq25980_device *bq, int busovp) 344*5069185fSDan Murphy { 345*5069185fSDan Murphy unsigned int busovp_reg_code; 346*5069185fSDan Murphy unsigned int busovp_step; 347*5069185fSDan Murphy unsigned int busovp_offset; 348*5069185fSDan Murphy int ret; 349*5069185fSDan Murphy 350*5069185fSDan Murphy if (bq->state.bypass) { 351*5069185fSDan Murphy busovp_step = bq->chip_info->busovp_byp_step; 352*5069185fSDan Murphy busovp_offset = bq->chip_info->busovp_byp_offset; 353*5069185fSDan Murphy if (busovp > bq->chip_info->busovp_byp_max) 354*5069185fSDan Murphy busovp = bq->chip_info->busovp_byp_max; 355*5069185fSDan Murphy else if (busovp < bq->chip_info->busovp_byp_min) 356*5069185fSDan Murphy busovp = bq->chip_info->busovp_byp_min; 357*5069185fSDan Murphy } else { 358*5069185fSDan Murphy busovp_step = bq->chip_info->busovp_sc_step; 359*5069185fSDan Murphy busovp_offset = bq->chip_info->busovp_sc_offset; 360*5069185fSDan Murphy if (busovp > bq->chip_info->busovp_sc_max) 361*5069185fSDan Murphy busovp = bq->chip_info->busovp_sc_max; 362*5069185fSDan Murphy else if (busovp < bq->chip_info->busovp_sc_min) 363*5069185fSDan Murphy busovp = bq->chip_info->busovp_sc_min; 364*5069185fSDan Murphy } 365*5069185fSDan Murphy 366*5069185fSDan Murphy busovp_reg_code = (busovp - busovp_offset) / busovp_step; 367*5069185fSDan Murphy 368*5069185fSDan Murphy ret = regmap_write(bq->regmap, BQ25980_BUSOVP, busovp_reg_code); 369*5069185fSDan Murphy if (ret) 370*5069185fSDan Murphy return ret; 371*5069185fSDan Murphy 372*5069185fSDan Murphy return regmap_write(bq->regmap, BQ25980_BUSOVP_ALM, busovp_reg_code); 373*5069185fSDan Murphy } 374*5069185fSDan Murphy 375*5069185fSDan Murphy static int bq25980_get_const_charge_curr(struct bq25980_device *bq) 376*5069185fSDan Murphy { 377*5069185fSDan Murphy unsigned int batocp_reg_code; 378*5069185fSDan Murphy int ret; 379*5069185fSDan Murphy 380*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_BATOCP, &batocp_reg_code); 381*5069185fSDan Murphy if (ret) 382*5069185fSDan Murphy return ret; 383*5069185fSDan Murphy 384*5069185fSDan Murphy return (batocp_reg_code & BQ25980_BATOCP_MASK) * 385*5069185fSDan Murphy BQ25980_BATOCP_STEP_uA; 386*5069185fSDan Murphy } 387*5069185fSDan Murphy 388*5069185fSDan Murphy static int bq25980_set_const_charge_curr(struct bq25980_device *bq, int batocp) 389*5069185fSDan Murphy { 390*5069185fSDan Murphy unsigned int batocp_reg_code; 391*5069185fSDan Murphy int ret; 392*5069185fSDan Murphy 393*5069185fSDan Murphy batocp = max(batocp, BQ25980_BATOCP_MIN_uA); 394*5069185fSDan Murphy batocp = min(batocp, bq->chip_info->batocp_max); 395*5069185fSDan Murphy 396*5069185fSDan Murphy batocp_reg_code = batocp / BQ25980_BATOCP_STEP_uA; 397*5069185fSDan Murphy 398*5069185fSDan Murphy ret = regmap_update_bits(bq->regmap, BQ25980_BATOCP, 399*5069185fSDan Murphy BQ25980_BATOCP_MASK, batocp_reg_code); 400*5069185fSDan Murphy if (ret) 401*5069185fSDan Murphy return ret; 402*5069185fSDan Murphy 403*5069185fSDan Murphy return regmap_update_bits(bq->regmap, BQ25980_BATOCP_ALM, 404*5069185fSDan Murphy BQ25980_BATOCP_MASK, batocp_reg_code); 405*5069185fSDan Murphy } 406*5069185fSDan Murphy 407*5069185fSDan Murphy static int bq25980_get_const_charge_volt(struct bq25980_device *bq) 408*5069185fSDan Murphy { 409*5069185fSDan Murphy unsigned int batovp_reg_code; 410*5069185fSDan Murphy int ret; 411*5069185fSDan Murphy 412*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_BATOVP, &batovp_reg_code); 413*5069185fSDan Murphy if (ret) 414*5069185fSDan Murphy return ret; 415*5069185fSDan Murphy 416*5069185fSDan Murphy return ((batovp_reg_code * bq->chip_info->batovp_step) + 417*5069185fSDan Murphy bq->chip_info->batovp_offset); 418*5069185fSDan Murphy } 419*5069185fSDan Murphy 420*5069185fSDan Murphy static int bq25980_set_const_charge_volt(struct bq25980_device *bq, int batovp) 421*5069185fSDan Murphy { 422*5069185fSDan Murphy unsigned int batovp_reg_code; 423*5069185fSDan Murphy int ret; 424*5069185fSDan Murphy 425*5069185fSDan Murphy if (batovp < bq->chip_info->batovp_min) 426*5069185fSDan Murphy batovp = bq->chip_info->batovp_min; 427*5069185fSDan Murphy 428*5069185fSDan Murphy if (batovp > bq->chip_info->batovp_max) 429*5069185fSDan Murphy batovp = bq->chip_info->batovp_max; 430*5069185fSDan Murphy 431*5069185fSDan Murphy batovp_reg_code = (batovp - bq->chip_info->batovp_offset) / 432*5069185fSDan Murphy bq->chip_info->batovp_step; 433*5069185fSDan Murphy 434*5069185fSDan Murphy ret = regmap_write(bq->regmap, BQ25980_BATOVP, batovp_reg_code); 435*5069185fSDan Murphy if (ret) 436*5069185fSDan Murphy return ret; 437*5069185fSDan Murphy 438*5069185fSDan Murphy return regmap_write(bq->regmap, BQ25980_BATOVP_ALM, batovp_reg_code); 439*5069185fSDan Murphy } 440*5069185fSDan Murphy 441*5069185fSDan Murphy static int bq25980_set_bypass(struct bq25980_device *bq, bool en_bypass) 442*5069185fSDan Murphy { 443*5069185fSDan Murphy int ret; 444*5069185fSDan Murphy 445*5069185fSDan Murphy if (en_bypass) 446*5069185fSDan Murphy ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 447*5069185fSDan Murphy BQ25980_EN_BYPASS, BQ25980_EN_BYPASS); 448*5069185fSDan Murphy else 449*5069185fSDan Murphy ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 450*5069185fSDan Murphy BQ25980_EN_BYPASS, en_bypass); 451*5069185fSDan Murphy if (ret) 452*5069185fSDan Murphy return ret; 453*5069185fSDan Murphy 454*5069185fSDan Murphy bq->state.bypass = en_bypass; 455*5069185fSDan Murphy 456*5069185fSDan Murphy return bq->state.bypass; 457*5069185fSDan Murphy } 458*5069185fSDan Murphy 459*5069185fSDan Murphy static int bq25980_set_chg_en(struct bq25980_device *bq, bool en_chg) 460*5069185fSDan Murphy { 461*5069185fSDan Murphy int ret; 462*5069185fSDan Murphy 463*5069185fSDan Murphy if (en_chg) 464*5069185fSDan Murphy ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 465*5069185fSDan Murphy BQ25980_CHG_EN, BQ25980_CHG_EN); 466*5069185fSDan Murphy else 467*5069185fSDan Murphy ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 468*5069185fSDan Murphy BQ25980_CHG_EN, en_chg); 469*5069185fSDan Murphy if (ret) 470*5069185fSDan Murphy return ret; 471*5069185fSDan Murphy 472*5069185fSDan Murphy bq->state.ce = en_chg; 473*5069185fSDan Murphy 474*5069185fSDan Murphy return 0; 475*5069185fSDan Murphy } 476*5069185fSDan Murphy 477*5069185fSDan Murphy static int bq25980_get_adc_ibus(struct bq25980_device *bq) 478*5069185fSDan Murphy { 479*5069185fSDan Murphy int ibus_adc_lsb, ibus_adc_msb; 480*5069185fSDan Murphy u16 ibus_adc; 481*5069185fSDan Murphy int ret; 482*5069185fSDan Murphy 483*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_IBUS_ADC_MSB, &ibus_adc_msb); 484*5069185fSDan Murphy if (ret) 485*5069185fSDan Murphy return ret; 486*5069185fSDan Murphy 487*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_IBUS_ADC_LSB, &ibus_adc_lsb); 488*5069185fSDan Murphy if (ret) 489*5069185fSDan Murphy return ret; 490*5069185fSDan Murphy 491*5069185fSDan Murphy ibus_adc = (ibus_adc_msb << 8) | ibus_adc_lsb; 492*5069185fSDan Murphy 493*5069185fSDan Murphy if (ibus_adc_msb & BQ25980_ADC_POLARITY_BIT) 494*5069185fSDan Murphy return ((ibus_adc ^ 0xffff) + 1) * BQ25980_ADC_CURR_STEP_uA; 495*5069185fSDan Murphy 496*5069185fSDan Murphy return ibus_adc * BQ25980_ADC_CURR_STEP_uA; 497*5069185fSDan Murphy } 498*5069185fSDan Murphy 499*5069185fSDan Murphy static int bq25980_get_adc_vbus(struct bq25980_device *bq) 500*5069185fSDan Murphy { 501*5069185fSDan Murphy int vbus_adc_lsb, vbus_adc_msb; 502*5069185fSDan Murphy u16 vbus_adc; 503*5069185fSDan Murphy int ret; 504*5069185fSDan Murphy 505*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_VBUS_ADC_MSB, &vbus_adc_msb); 506*5069185fSDan Murphy if (ret) 507*5069185fSDan Murphy return ret; 508*5069185fSDan Murphy 509*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_VBUS_ADC_LSB, &vbus_adc_lsb); 510*5069185fSDan Murphy if (ret) 511*5069185fSDan Murphy return ret; 512*5069185fSDan Murphy 513*5069185fSDan Murphy vbus_adc = (vbus_adc_msb << 8) | vbus_adc_lsb; 514*5069185fSDan Murphy 515*5069185fSDan Murphy return vbus_adc * BQ25980_ADC_VOLT_STEP_uV; 516*5069185fSDan Murphy } 517*5069185fSDan Murphy 518*5069185fSDan Murphy static int bq25980_get_ibat_adc(struct bq25980_device *bq) 519*5069185fSDan Murphy { 520*5069185fSDan Murphy int ret; 521*5069185fSDan Murphy int ibat_adc_lsb, ibat_adc_msb; 522*5069185fSDan Murphy int ibat_adc; 523*5069185fSDan Murphy 524*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_IBAT_ADC_MSB, &ibat_adc_msb); 525*5069185fSDan Murphy if (ret) 526*5069185fSDan Murphy return ret; 527*5069185fSDan Murphy 528*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_IBAT_ADC_LSB, &ibat_adc_lsb); 529*5069185fSDan Murphy if (ret) 530*5069185fSDan Murphy return ret; 531*5069185fSDan Murphy 532*5069185fSDan Murphy ibat_adc = (ibat_adc_msb << 8) | ibat_adc_lsb; 533*5069185fSDan Murphy 534*5069185fSDan Murphy if (ibat_adc_msb & BQ25980_ADC_POLARITY_BIT) 535*5069185fSDan Murphy return ((ibat_adc ^ 0xffff) + 1) * BQ25980_ADC_CURR_STEP_uA; 536*5069185fSDan Murphy 537*5069185fSDan Murphy return ibat_adc * BQ25980_ADC_CURR_STEP_uA; 538*5069185fSDan Murphy } 539*5069185fSDan Murphy 540*5069185fSDan Murphy static int bq25980_get_adc_vbat(struct bq25980_device *bq) 541*5069185fSDan Murphy { 542*5069185fSDan Murphy int vsys_adc_lsb, vsys_adc_msb; 543*5069185fSDan Murphy u16 vsys_adc; 544*5069185fSDan Murphy int ret; 545*5069185fSDan Murphy 546*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_VBAT_ADC_MSB, &vsys_adc_msb); 547*5069185fSDan Murphy if (ret) 548*5069185fSDan Murphy return ret; 549*5069185fSDan Murphy 550*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_VBAT_ADC_LSB, &vsys_adc_lsb); 551*5069185fSDan Murphy if (ret) 552*5069185fSDan Murphy return ret; 553*5069185fSDan Murphy 554*5069185fSDan Murphy vsys_adc = (vsys_adc_msb << 8) | vsys_adc_lsb; 555*5069185fSDan Murphy 556*5069185fSDan Murphy return vsys_adc * BQ25980_ADC_VOLT_STEP_uV; 557*5069185fSDan Murphy } 558*5069185fSDan Murphy 559*5069185fSDan Murphy static int bq25980_get_state(struct bq25980_device *bq, 560*5069185fSDan Murphy struct bq25980_state *state) 561*5069185fSDan Murphy { 562*5069185fSDan Murphy unsigned int chg_ctrl_2; 563*5069185fSDan Murphy unsigned int stat1; 564*5069185fSDan Murphy unsigned int stat2; 565*5069185fSDan Murphy unsigned int stat3; 566*5069185fSDan Murphy unsigned int stat4; 567*5069185fSDan Murphy unsigned int ibat_adc_msb; 568*5069185fSDan Murphy int ret; 569*5069185fSDan Murphy 570*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_STAT1, &stat1); 571*5069185fSDan Murphy if (ret) 572*5069185fSDan Murphy return ret; 573*5069185fSDan Murphy 574*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_STAT2, &stat2); 575*5069185fSDan Murphy if (ret) 576*5069185fSDan Murphy return ret; 577*5069185fSDan Murphy 578*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_STAT3, &stat3); 579*5069185fSDan Murphy if (ret) 580*5069185fSDan Murphy return ret; 581*5069185fSDan Murphy 582*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_STAT4, &stat4); 583*5069185fSDan Murphy if (ret) 584*5069185fSDan Murphy return ret; 585*5069185fSDan Murphy 586*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_CHRGR_CTRL_2, &chg_ctrl_2); 587*5069185fSDan Murphy if (ret) 588*5069185fSDan Murphy return ret; 589*5069185fSDan Murphy 590*5069185fSDan Murphy ret = regmap_read(bq->regmap, BQ25980_IBAT_ADC_MSB, &ibat_adc_msb); 591*5069185fSDan Murphy if (ret) 592*5069185fSDan Murphy return ret; 593*5069185fSDan Murphy 594*5069185fSDan Murphy state->dischg = ibat_adc_msb & BQ25980_ADC_POLARITY_BIT; 595*5069185fSDan Murphy state->ovp = (stat1 & BQ25980_STAT1_OVP_MASK) | 596*5069185fSDan Murphy (stat3 & BQ25980_STAT3_OVP_MASK); 597*5069185fSDan Murphy state->ocp = (stat1 & BQ25980_STAT1_OCP_MASK) | 598*5069185fSDan Murphy (stat2 & BQ25980_STAT2_OCP_MASK); 599*5069185fSDan Murphy state->tflt = stat4 & BQ25980_STAT4_TFLT_MASK; 600*5069185fSDan Murphy state->wdt = stat4 & BQ25980_WD_STAT; 601*5069185fSDan Murphy state->online = stat3 & BQ25980_PRESENT_MASK; 602*5069185fSDan Murphy state->ce = chg_ctrl_2 & BQ25980_CHG_EN; 603*5069185fSDan Murphy state->hiz = chg_ctrl_2 & BQ25980_EN_HIZ; 604*5069185fSDan Murphy state->bypass = chg_ctrl_2 & BQ25980_EN_BYPASS; 605*5069185fSDan Murphy 606*5069185fSDan Murphy return 0; 607*5069185fSDan Murphy } 608*5069185fSDan Murphy 609*5069185fSDan Murphy static int bq25980_set_battery_property(struct power_supply *psy, 610*5069185fSDan Murphy enum power_supply_property psp, 611*5069185fSDan Murphy const union power_supply_propval *val) 612*5069185fSDan Murphy { 613*5069185fSDan Murphy struct bq25980_device *bq = power_supply_get_drvdata(psy); 614*5069185fSDan Murphy int ret = 0; 615*5069185fSDan Murphy 616*5069185fSDan Murphy if (ret) 617*5069185fSDan Murphy return ret; 618*5069185fSDan Murphy 619*5069185fSDan Murphy switch (psp) { 620*5069185fSDan Murphy case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 621*5069185fSDan Murphy ret = bq25980_set_const_charge_curr(bq, val->intval); 622*5069185fSDan Murphy if (ret) 623*5069185fSDan Murphy return ret; 624*5069185fSDan Murphy break; 625*5069185fSDan Murphy 626*5069185fSDan Murphy case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 627*5069185fSDan Murphy ret = bq25980_set_const_charge_volt(bq, val->intval); 628*5069185fSDan Murphy if (ret) 629*5069185fSDan Murphy return ret; 630*5069185fSDan Murphy break; 631*5069185fSDan Murphy 632*5069185fSDan Murphy default: 633*5069185fSDan Murphy return -EINVAL; 634*5069185fSDan Murphy } 635*5069185fSDan Murphy 636*5069185fSDan Murphy return ret; 637*5069185fSDan Murphy } 638*5069185fSDan Murphy 639*5069185fSDan Murphy static int bq25980_get_battery_property(struct power_supply *psy, 640*5069185fSDan Murphy enum power_supply_property psp, 641*5069185fSDan Murphy union power_supply_propval *val) 642*5069185fSDan Murphy { 643*5069185fSDan Murphy struct bq25980_device *bq = power_supply_get_drvdata(psy); 644*5069185fSDan Murphy int ret = 0; 645*5069185fSDan Murphy 646*5069185fSDan Murphy switch (psp) { 647*5069185fSDan Murphy case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 648*5069185fSDan Murphy val->intval = bq->init_data.ichg_max; 649*5069185fSDan Murphy break; 650*5069185fSDan Murphy 651*5069185fSDan Murphy case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 652*5069185fSDan Murphy val->intval = bq->init_data.vreg_max; 653*5069185fSDan Murphy break; 654*5069185fSDan Murphy 655*5069185fSDan Murphy case POWER_SUPPLY_PROP_CURRENT_NOW: 656*5069185fSDan Murphy ret = bq25980_get_ibat_adc(bq); 657*5069185fSDan Murphy val->intval = ret; 658*5069185fSDan Murphy break; 659*5069185fSDan Murphy 660*5069185fSDan Murphy case POWER_SUPPLY_PROP_VOLTAGE_NOW: 661*5069185fSDan Murphy ret = bq25980_get_adc_vbat(bq); 662*5069185fSDan Murphy if (ret < 0) 663*5069185fSDan Murphy return ret; 664*5069185fSDan Murphy 665*5069185fSDan Murphy val->intval = ret; 666*5069185fSDan Murphy break; 667*5069185fSDan Murphy 668*5069185fSDan Murphy default: 669*5069185fSDan Murphy return -EINVAL; 670*5069185fSDan Murphy } 671*5069185fSDan Murphy 672*5069185fSDan Murphy return ret; 673*5069185fSDan Murphy } 674*5069185fSDan Murphy 675*5069185fSDan Murphy static int bq25980_set_charger_property(struct power_supply *psy, 676*5069185fSDan Murphy enum power_supply_property prop, 677*5069185fSDan Murphy const union power_supply_propval *val) 678*5069185fSDan Murphy { 679*5069185fSDan Murphy struct bq25980_device *bq = power_supply_get_drvdata(psy); 680*5069185fSDan Murphy int ret = -EINVAL; 681*5069185fSDan Murphy 682*5069185fSDan Murphy switch (prop) { 683*5069185fSDan Murphy case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 684*5069185fSDan Murphy ret = bq25980_set_input_curr_lim(bq, val->intval); 685*5069185fSDan Murphy if (ret) 686*5069185fSDan Murphy return ret; 687*5069185fSDan Murphy break; 688*5069185fSDan Murphy 689*5069185fSDan Murphy case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: 690*5069185fSDan Murphy ret = bq25980_set_input_volt_lim(bq, val->intval); 691*5069185fSDan Murphy if (ret) 692*5069185fSDan Murphy return ret; 693*5069185fSDan Murphy break; 694*5069185fSDan Murphy 695*5069185fSDan Murphy case POWER_SUPPLY_PROP_CHARGE_TYPE: 696*5069185fSDan Murphy ret = bq25980_set_bypass(bq, val->intval); 697*5069185fSDan Murphy if (ret) 698*5069185fSDan Murphy return ret; 699*5069185fSDan Murphy break; 700*5069185fSDan Murphy 701*5069185fSDan Murphy case POWER_SUPPLY_PROP_STATUS: 702*5069185fSDan Murphy ret = bq25980_set_chg_en(bq, val->intval); 703*5069185fSDan Murphy if (ret) 704*5069185fSDan Murphy return ret; 705*5069185fSDan Murphy break; 706*5069185fSDan Murphy 707*5069185fSDan Murphy default: 708*5069185fSDan Murphy return -EINVAL; 709*5069185fSDan Murphy } 710*5069185fSDan Murphy 711*5069185fSDan Murphy return ret; 712*5069185fSDan Murphy } 713*5069185fSDan Murphy 714*5069185fSDan Murphy static int bq25980_get_charger_property(struct power_supply *psy, 715*5069185fSDan Murphy enum power_supply_property psp, 716*5069185fSDan Murphy union power_supply_propval *val) 717*5069185fSDan Murphy { 718*5069185fSDan Murphy struct bq25980_device *bq = power_supply_get_drvdata(psy); 719*5069185fSDan Murphy struct bq25980_state state; 720*5069185fSDan Murphy int ret = 0; 721*5069185fSDan Murphy 722*5069185fSDan Murphy mutex_lock(&bq->lock); 723*5069185fSDan Murphy ret = bq25980_get_state(bq, &state); 724*5069185fSDan Murphy mutex_unlock(&bq->lock); 725*5069185fSDan Murphy if (ret) 726*5069185fSDan Murphy return ret; 727*5069185fSDan Murphy 728*5069185fSDan Murphy switch (psp) { 729*5069185fSDan Murphy case POWER_SUPPLY_PROP_MANUFACTURER: 730*5069185fSDan Murphy val->strval = BQ25980_MANUFACTURER; 731*5069185fSDan Murphy break; 732*5069185fSDan Murphy case POWER_SUPPLY_PROP_MODEL_NAME: 733*5069185fSDan Murphy val->strval = bq->model_name; 734*5069185fSDan Murphy break; 735*5069185fSDan Murphy case POWER_SUPPLY_PROP_ONLINE: 736*5069185fSDan Murphy val->intval = state.online; 737*5069185fSDan Murphy break; 738*5069185fSDan Murphy 739*5069185fSDan Murphy case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: 740*5069185fSDan Murphy ret = bq25980_get_input_volt_lim(bq); 741*5069185fSDan Murphy if (ret < 0) 742*5069185fSDan Murphy return ret; 743*5069185fSDan Murphy val->intval = ret; 744*5069185fSDan Murphy break; 745*5069185fSDan Murphy 746*5069185fSDan Murphy case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 747*5069185fSDan Murphy ret = bq25980_get_input_curr_lim(bq); 748*5069185fSDan Murphy if (ret < 0) 749*5069185fSDan Murphy return ret; 750*5069185fSDan Murphy 751*5069185fSDan Murphy val->intval = ret; 752*5069185fSDan Murphy break; 753*5069185fSDan Murphy 754*5069185fSDan Murphy case POWER_SUPPLY_PROP_HEALTH: 755*5069185fSDan Murphy val->intval = POWER_SUPPLY_HEALTH_GOOD; 756*5069185fSDan Murphy 757*5069185fSDan Murphy if (state.tflt) 758*5069185fSDan Murphy val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 759*5069185fSDan Murphy else if (state.ovp) 760*5069185fSDan Murphy val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 761*5069185fSDan Murphy else if (state.ocp) 762*5069185fSDan Murphy val->intval = POWER_SUPPLY_HEALTH_OVERCURRENT; 763*5069185fSDan Murphy else if (state.wdt) 764*5069185fSDan Murphy val->intval = 765*5069185fSDan Murphy POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE; 766*5069185fSDan Murphy break; 767*5069185fSDan Murphy 768*5069185fSDan Murphy case POWER_SUPPLY_PROP_STATUS: 769*5069185fSDan Murphy val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 770*5069185fSDan Murphy 771*5069185fSDan Murphy if ((state.ce) && (!state.hiz)) 772*5069185fSDan Murphy val->intval = POWER_SUPPLY_STATUS_CHARGING; 773*5069185fSDan Murphy else if (state.dischg) 774*5069185fSDan Murphy val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 775*5069185fSDan Murphy else if (!state.ce) 776*5069185fSDan Murphy val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 777*5069185fSDan Murphy break; 778*5069185fSDan Murphy 779*5069185fSDan Murphy case POWER_SUPPLY_PROP_CHARGE_TYPE: 780*5069185fSDan Murphy val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; 781*5069185fSDan Murphy 782*5069185fSDan Murphy if (!state.ce) 783*5069185fSDan Murphy val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; 784*5069185fSDan Murphy else if (state.bypass) 785*5069185fSDan Murphy val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; 786*5069185fSDan Murphy else if (!state.bypass) 787*5069185fSDan Murphy val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD; 788*5069185fSDan Murphy break; 789*5069185fSDan Murphy 790*5069185fSDan Murphy case POWER_SUPPLY_PROP_CURRENT_NOW: 791*5069185fSDan Murphy ret = bq25980_get_adc_ibus(bq); 792*5069185fSDan Murphy if (ret < 0) 793*5069185fSDan Murphy return ret; 794*5069185fSDan Murphy 795*5069185fSDan Murphy val->intval = ret; 796*5069185fSDan Murphy break; 797*5069185fSDan Murphy 798*5069185fSDan Murphy case POWER_SUPPLY_PROP_VOLTAGE_NOW: 799*5069185fSDan Murphy ret = bq25980_get_adc_vbus(bq); 800*5069185fSDan Murphy if (ret < 0) 801*5069185fSDan Murphy return ret; 802*5069185fSDan Murphy 803*5069185fSDan Murphy val->intval = ret; 804*5069185fSDan Murphy break; 805*5069185fSDan Murphy 806*5069185fSDan Murphy case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 807*5069185fSDan Murphy ret = bq25980_get_const_charge_curr(bq); 808*5069185fSDan Murphy if (ret < 0) 809*5069185fSDan Murphy return ret; 810*5069185fSDan Murphy 811*5069185fSDan Murphy val->intval = ret; 812*5069185fSDan Murphy break; 813*5069185fSDan Murphy 814*5069185fSDan Murphy case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 815*5069185fSDan Murphy ret = bq25980_get_const_charge_volt(bq); 816*5069185fSDan Murphy if (ret < 0) 817*5069185fSDan Murphy return ret; 818*5069185fSDan Murphy 819*5069185fSDan Murphy val->intval = ret; 820*5069185fSDan Murphy break; 821*5069185fSDan Murphy 822*5069185fSDan Murphy default: 823*5069185fSDan Murphy return -EINVAL; 824*5069185fSDan Murphy } 825*5069185fSDan Murphy 826*5069185fSDan Murphy return ret; 827*5069185fSDan Murphy } 828*5069185fSDan Murphy 829*5069185fSDan Murphy static bool bq25980_state_changed(struct bq25980_device *bq, 830*5069185fSDan Murphy struct bq25980_state *new_state) 831*5069185fSDan Murphy { 832*5069185fSDan Murphy struct bq25980_state old_state; 833*5069185fSDan Murphy 834*5069185fSDan Murphy mutex_lock(&bq->lock); 835*5069185fSDan Murphy old_state = bq->state; 836*5069185fSDan Murphy mutex_unlock(&bq->lock); 837*5069185fSDan Murphy 838*5069185fSDan Murphy return (old_state.dischg != new_state->dischg || 839*5069185fSDan Murphy old_state.ovp != new_state->ovp || 840*5069185fSDan Murphy old_state.ocp != new_state->ocp || 841*5069185fSDan Murphy old_state.online != new_state->online || 842*5069185fSDan Murphy old_state.wdt != new_state->wdt || 843*5069185fSDan Murphy old_state.tflt != new_state->tflt || 844*5069185fSDan Murphy old_state.ce != new_state->ce || 845*5069185fSDan Murphy old_state.hiz != new_state->hiz || 846*5069185fSDan Murphy old_state.bypass != new_state->bypass); 847*5069185fSDan Murphy } 848*5069185fSDan Murphy 849*5069185fSDan Murphy static irqreturn_t bq25980_irq_handler_thread(int irq, void *private) 850*5069185fSDan Murphy { 851*5069185fSDan Murphy struct bq25980_device *bq = private; 852*5069185fSDan Murphy struct bq25980_state state; 853*5069185fSDan Murphy int ret; 854*5069185fSDan Murphy 855*5069185fSDan Murphy ret = bq25980_get_state(bq, &state); 856*5069185fSDan Murphy if (ret < 0) 857*5069185fSDan Murphy goto irq_out; 858*5069185fSDan Murphy 859*5069185fSDan Murphy if (!bq25980_state_changed(bq, &state)) 860*5069185fSDan Murphy goto irq_out; 861*5069185fSDan Murphy 862*5069185fSDan Murphy mutex_lock(&bq->lock); 863*5069185fSDan Murphy bq->state = state; 864*5069185fSDan Murphy mutex_unlock(&bq->lock); 865*5069185fSDan Murphy 866*5069185fSDan Murphy power_supply_changed(bq->charger); 867*5069185fSDan Murphy 868*5069185fSDan Murphy irq_out: 869*5069185fSDan Murphy return IRQ_HANDLED; 870*5069185fSDan Murphy } 871*5069185fSDan Murphy 872*5069185fSDan Murphy static enum power_supply_property bq25980_power_supply_props[] = { 873*5069185fSDan Murphy POWER_SUPPLY_PROP_MANUFACTURER, 874*5069185fSDan Murphy POWER_SUPPLY_PROP_MODEL_NAME, 875*5069185fSDan Murphy POWER_SUPPLY_PROP_STATUS, 876*5069185fSDan Murphy POWER_SUPPLY_PROP_ONLINE, 877*5069185fSDan Murphy POWER_SUPPLY_PROP_HEALTH, 878*5069185fSDan Murphy POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT, 879*5069185fSDan Murphy POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 880*5069185fSDan Murphy POWER_SUPPLY_PROP_CHARGE_TYPE, 881*5069185fSDan Murphy POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 882*5069185fSDan Murphy POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 883*5069185fSDan Murphy POWER_SUPPLY_PROP_CURRENT_NOW, 884*5069185fSDan Murphy POWER_SUPPLY_PROP_VOLTAGE_NOW, 885*5069185fSDan Murphy }; 886*5069185fSDan Murphy 887*5069185fSDan Murphy static enum power_supply_property bq25980_battery_props[] = { 888*5069185fSDan Murphy POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 889*5069185fSDan Murphy POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 890*5069185fSDan Murphy POWER_SUPPLY_PROP_CURRENT_NOW, 891*5069185fSDan Murphy POWER_SUPPLY_PROP_VOLTAGE_NOW, 892*5069185fSDan Murphy }; 893*5069185fSDan Murphy 894*5069185fSDan Murphy static char *bq25980_charger_supplied_to[] = { 895*5069185fSDan Murphy "main-battery", 896*5069185fSDan Murphy }; 897*5069185fSDan Murphy 898*5069185fSDan Murphy static int bq25980_property_is_writeable(struct power_supply *psy, 899*5069185fSDan Murphy enum power_supply_property prop) 900*5069185fSDan Murphy { 901*5069185fSDan Murphy switch (prop) { 902*5069185fSDan Murphy case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 903*5069185fSDan Murphy case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 904*5069185fSDan Murphy case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 905*5069185fSDan Murphy case POWER_SUPPLY_PROP_CHARGE_TYPE: 906*5069185fSDan Murphy case POWER_SUPPLY_PROP_STATUS: 907*5069185fSDan Murphy case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: 908*5069185fSDan Murphy return true; 909*5069185fSDan Murphy default: 910*5069185fSDan Murphy return false; 911*5069185fSDan Murphy } 912*5069185fSDan Murphy } 913*5069185fSDan Murphy 914*5069185fSDan Murphy static const struct power_supply_desc bq25980_power_supply_desc = { 915*5069185fSDan Murphy .name = "bq25980-charger", 916*5069185fSDan Murphy .type = POWER_SUPPLY_TYPE_MAINS, 917*5069185fSDan Murphy .properties = bq25980_power_supply_props, 918*5069185fSDan Murphy .num_properties = ARRAY_SIZE(bq25980_power_supply_props), 919*5069185fSDan Murphy .get_property = bq25980_get_charger_property, 920*5069185fSDan Murphy .set_property = bq25980_set_charger_property, 921*5069185fSDan Murphy .property_is_writeable = bq25980_property_is_writeable, 922*5069185fSDan Murphy }; 923*5069185fSDan Murphy 924*5069185fSDan Murphy static struct power_supply_desc bq25980_battery_desc = { 925*5069185fSDan Murphy .name = "bq25980-battery", 926*5069185fSDan Murphy .type = POWER_SUPPLY_TYPE_BATTERY, 927*5069185fSDan Murphy .get_property = bq25980_get_battery_property, 928*5069185fSDan Murphy .set_property = bq25980_set_battery_property, 929*5069185fSDan Murphy .properties = bq25980_battery_props, 930*5069185fSDan Murphy .num_properties = ARRAY_SIZE(bq25980_battery_props), 931*5069185fSDan Murphy .property_is_writeable = bq25980_property_is_writeable, 932*5069185fSDan Murphy }; 933*5069185fSDan Murphy 934*5069185fSDan Murphy 935*5069185fSDan Murphy static bool bq25980_is_volatile_reg(struct device *dev, unsigned int reg) 936*5069185fSDan Murphy { 937*5069185fSDan Murphy switch (reg) { 938*5069185fSDan Murphy case BQ25980_CHRGR_CTRL_2: 939*5069185fSDan Murphy case BQ25980_STAT1...BQ25980_FLAG5: 940*5069185fSDan Murphy case BQ25980_ADC_CONTROL1...BQ25980_TDIE_ADC_LSB: 941*5069185fSDan Murphy return true; 942*5069185fSDan Murphy default: 943*5069185fSDan Murphy return false; 944*5069185fSDan Murphy } 945*5069185fSDan Murphy } 946*5069185fSDan Murphy 947*5069185fSDan Murphy static const struct regmap_config bq25980_regmap_config = { 948*5069185fSDan Murphy .reg_bits = 8, 949*5069185fSDan Murphy .val_bits = 8, 950*5069185fSDan Murphy 951*5069185fSDan Murphy .max_register = BQ25980_CHRGR_CTRL_6, 952*5069185fSDan Murphy .reg_defaults = bq25980_reg_defs, 953*5069185fSDan Murphy .num_reg_defaults = ARRAY_SIZE(bq25980_reg_defs), 954*5069185fSDan Murphy .cache_type = REGCACHE_RBTREE, 955*5069185fSDan Murphy .volatile_reg = bq25980_is_volatile_reg, 956*5069185fSDan Murphy }; 957*5069185fSDan Murphy 958*5069185fSDan Murphy static const struct regmap_config bq25975_regmap_config = { 959*5069185fSDan Murphy .reg_bits = 8, 960*5069185fSDan Murphy .val_bits = 8, 961*5069185fSDan Murphy 962*5069185fSDan Murphy .max_register = BQ25980_CHRGR_CTRL_6, 963*5069185fSDan Murphy .reg_defaults = bq25975_reg_defs, 964*5069185fSDan Murphy .num_reg_defaults = ARRAY_SIZE(bq25975_reg_defs), 965*5069185fSDan Murphy .cache_type = REGCACHE_RBTREE, 966*5069185fSDan Murphy .volatile_reg = bq25980_is_volatile_reg, 967*5069185fSDan Murphy }; 968*5069185fSDan Murphy 969*5069185fSDan Murphy static const struct regmap_config bq25960_regmap_config = { 970*5069185fSDan Murphy .reg_bits = 8, 971*5069185fSDan Murphy .val_bits = 8, 972*5069185fSDan Murphy 973*5069185fSDan Murphy .max_register = BQ25980_CHRGR_CTRL_6, 974*5069185fSDan Murphy .reg_defaults = bq25960_reg_defs, 975*5069185fSDan Murphy .num_reg_defaults = ARRAY_SIZE(bq25960_reg_defs), 976*5069185fSDan Murphy .cache_type = REGCACHE_RBTREE, 977*5069185fSDan Murphy .volatile_reg = bq25980_is_volatile_reg, 978*5069185fSDan Murphy }; 979*5069185fSDan Murphy 980*5069185fSDan Murphy static const struct bq25980_chip_info bq25980_chip_info_tbl[] = { 981*5069185fSDan Murphy [BQ25980] = { 982*5069185fSDan Murphy .model_id = BQ25980, 983*5069185fSDan Murphy .regmap_config = &bq25980_regmap_config, 984*5069185fSDan Murphy 985*5069185fSDan Murphy .busocp_def = BQ25980_BUSOCP_DFLT_uA, 986*5069185fSDan Murphy .busocp_sc_min = BQ25960_BUSOCP_SC_MAX_uA, 987*5069185fSDan Murphy .busocp_sc_max = BQ25980_BUSOCP_SC_MAX_uA, 988*5069185fSDan Murphy .busocp_byp_max = BQ25980_BUSOCP_BYP_MAX_uA, 989*5069185fSDan Murphy .busocp_byp_min = BQ25980_BUSOCP_MIN_uA, 990*5069185fSDan Murphy 991*5069185fSDan Murphy .busovp_sc_def = BQ25980_BUSOVP_DFLT_uV, 992*5069185fSDan Murphy .busovp_byp_def = BQ25980_BUSOVP_BYPASS_DFLT_uV, 993*5069185fSDan Murphy .busovp_sc_step = BQ25980_BUSOVP_SC_STEP_uV, 994*5069185fSDan Murphy .busovp_sc_offset = BQ25980_BUSOVP_SC_OFFSET_uV, 995*5069185fSDan Murphy .busovp_byp_step = BQ25980_BUSOVP_BYP_STEP_uV, 996*5069185fSDan Murphy .busovp_byp_offset = BQ25980_BUSOVP_BYP_OFFSET_uV, 997*5069185fSDan Murphy .busovp_sc_min = BQ25980_BUSOVP_SC_MIN_uV, 998*5069185fSDan Murphy .busovp_sc_max = BQ25980_BUSOVP_SC_MAX_uV, 999*5069185fSDan Murphy .busovp_byp_min = BQ25980_BUSOVP_BYP_MIN_uV, 1000*5069185fSDan Murphy .busovp_byp_max = BQ25980_BUSOVP_BYP_MAX_uV, 1001*5069185fSDan Murphy 1002*5069185fSDan Murphy .batovp_def = BQ25980_BATOVP_DFLT_uV, 1003*5069185fSDan Murphy .batovp_max = BQ25980_BATOVP_MAX_uV, 1004*5069185fSDan Murphy .batovp_min = BQ25980_BATOVP_MIN_uV, 1005*5069185fSDan Murphy .batovp_step = BQ25980_BATOVP_STEP_uV, 1006*5069185fSDan Murphy .batovp_offset = BQ25980_BATOVP_OFFSET_uV, 1007*5069185fSDan Murphy 1008*5069185fSDan Murphy .batocp_def = BQ25980_BATOCP_DFLT_uA, 1009*5069185fSDan Murphy .batocp_max = BQ25980_BATOCP_MAX_uA, 1010*5069185fSDan Murphy }, 1011*5069185fSDan Murphy 1012*5069185fSDan Murphy [BQ25975] = { 1013*5069185fSDan Murphy .model_id = BQ25975, 1014*5069185fSDan Murphy .regmap_config = &bq25975_regmap_config, 1015*5069185fSDan Murphy 1016*5069185fSDan Murphy .busocp_def = BQ25975_BUSOCP_DFLT_uA, 1017*5069185fSDan Murphy .busocp_sc_min = BQ25975_BUSOCP_SC_MAX_uA, 1018*5069185fSDan Murphy .busocp_sc_max = BQ25975_BUSOCP_SC_MAX_uA, 1019*5069185fSDan Murphy .busocp_byp_min = BQ25980_BUSOCP_MIN_uA, 1020*5069185fSDan Murphy .busocp_byp_max = BQ25975_BUSOCP_BYP_MAX_uA, 1021*5069185fSDan Murphy 1022*5069185fSDan Murphy .busovp_sc_def = BQ25975_BUSOVP_DFLT_uV, 1023*5069185fSDan Murphy .busovp_byp_def = BQ25975_BUSOVP_BYPASS_DFLT_uV, 1024*5069185fSDan Murphy .busovp_sc_step = BQ25975_BUSOVP_SC_STEP_uV, 1025*5069185fSDan Murphy .busovp_sc_offset = BQ25975_BUSOVP_SC_OFFSET_uV, 1026*5069185fSDan Murphy .busovp_byp_step = BQ25975_BUSOVP_BYP_STEP_uV, 1027*5069185fSDan Murphy .busovp_byp_offset = BQ25975_BUSOVP_BYP_OFFSET_uV, 1028*5069185fSDan Murphy .busovp_sc_min = BQ25975_BUSOVP_SC_MIN_uV, 1029*5069185fSDan Murphy .busovp_sc_max = BQ25975_BUSOVP_SC_MAX_uV, 1030*5069185fSDan Murphy .busovp_byp_min = BQ25975_BUSOVP_BYP_MIN_uV, 1031*5069185fSDan Murphy .busovp_byp_max = BQ25975_BUSOVP_BYP_MAX_uV, 1032*5069185fSDan Murphy 1033*5069185fSDan Murphy .batovp_def = BQ25975_BATOVP_DFLT_uV, 1034*5069185fSDan Murphy .batovp_max = BQ25975_BATOVP_MAX_uV, 1035*5069185fSDan Murphy .batovp_min = BQ25975_BATOVP_MIN_uV, 1036*5069185fSDan Murphy .batovp_step = BQ25975_BATOVP_STEP_uV, 1037*5069185fSDan Murphy .batovp_offset = BQ25975_BATOVP_OFFSET_uV, 1038*5069185fSDan Murphy 1039*5069185fSDan Murphy .batocp_def = BQ25980_BATOCP_DFLT_uA, 1040*5069185fSDan Murphy .batocp_max = BQ25980_BATOCP_MAX_uA, 1041*5069185fSDan Murphy }, 1042*5069185fSDan Murphy 1043*5069185fSDan Murphy [BQ25960] = { 1044*5069185fSDan Murphy .model_id = BQ25960, 1045*5069185fSDan Murphy .regmap_config = &bq25960_regmap_config, 1046*5069185fSDan Murphy 1047*5069185fSDan Murphy .busocp_def = BQ25960_BUSOCP_DFLT_uA, 1048*5069185fSDan Murphy .busocp_sc_min = BQ25960_BUSOCP_SC_MAX_uA, 1049*5069185fSDan Murphy .busocp_sc_max = BQ25960_BUSOCP_SC_MAX_uA, 1050*5069185fSDan Murphy .busocp_byp_min = BQ25960_BUSOCP_SC_MAX_uA, 1051*5069185fSDan Murphy .busocp_byp_max = BQ25960_BUSOCP_BYP_MAX_uA, 1052*5069185fSDan Murphy 1053*5069185fSDan Murphy .busovp_sc_def = BQ25975_BUSOVP_DFLT_uV, 1054*5069185fSDan Murphy .busovp_byp_def = BQ25975_BUSOVP_BYPASS_DFLT_uV, 1055*5069185fSDan Murphy .busovp_sc_step = BQ25960_BUSOVP_SC_STEP_uV, 1056*5069185fSDan Murphy .busovp_sc_offset = BQ25960_BUSOVP_SC_OFFSET_uV, 1057*5069185fSDan Murphy .busovp_byp_step = BQ25960_BUSOVP_BYP_STEP_uV, 1058*5069185fSDan Murphy .busovp_byp_offset = BQ25960_BUSOVP_BYP_OFFSET_uV, 1059*5069185fSDan Murphy .busovp_sc_min = BQ25960_BUSOVP_SC_MIN_uV, 1060*5069185fSDan Murphy .busovp_sc_max = BQ25960_BUSOVP_SC_MAX_uV, 1061*5069185fSDan Murphy .busovp_byp_min = BQ25960_BUSOVP_BYP_MIN_uV, 1062*5069185fSDan Murphy .busovp_byp_max = BQ25960_BUSOVP_BYP_MAX_uV, 1063*5069185fSDan Murphy 1064*5069185fSDan Murphy .batovp_def = BQ25960_BATOVP_DFLT_uV, 1065*5069185fSDan Murphy .batovp_max = BQ25960_BATOVP_MAX_uV, 1066*5069185fSDan Murphy .batovp_min = BQ25960_BATOVP_MIN_uV, 1067*5069185fSDan Murphy .batovp_step = BQ25960_BATOVP_STEP_uV, 1068*5069185fSDan Murphy .batovp_offset = BQ25960_BATOVP_OFFSET_uV, 1069*5069185fSDan Murphy 1070*5069185fSDan Murphy .batocp_def = BQ25960_BATOCP_DFLT_uA, 1071*5069185fSDan Murphy .batocp_max = BQ25960_BATOCP_MAX_uA, 1072*5069185fSDan Murphy }, 1073*5069185fSDan Murphy }; 1074*5069185fSDan Murphy 1075*5069185fSDan Murphy static int bq25980_power_supply_init(struct bq25980_device *bq, 1076*5069185fSDan Murphy struct device *dev) 1077*5069185fSDan Murphy { 1078*5069185fSDan Murphy struct power_supply_config psy_cfg = { .drv_data = bq, 1079*5069185fSDan Murphy .of_node = dev->of_node, }; 1080*5069185fSDan Murphy 1081*5069185fSDan Murphy psy_cfg.supplied_to = bq25980_charger_supplied_to; 1082*5069185fSDan Murphy psy_cfg.num_supplicants = ARRAY_SIZE(bq25980_charger_supplied_to); 1083*5069185fSDan Murphy 1084*5069185fSDan Murphy bq->charger = devm_power_supply_register(bq->dev, 1085*5069185fSDan Murphy &bq25980_power_supply_desc, 1086*5069185fSDan Murphy &psy_cfg); 1087*5069185fSDan Murphy if (IS_ERR(bq->charger)) 1088*5069185fSDan Murphy return -EINVAL; 1089*5069185fSDan Murphy 1090*5069185fSDan Murphy bq->battery = devm_power_supply_register(bq->dev, 1091*5069185fSDan Murphy &bq25980_battery_desc, 1092*5069185fSDan Murphy &psy_cfg); 1093*5069185fSDan Murphy if (IS_ERR(bq->battery)) 1094*5069185fSDan Murphy return -EINVAL; 1095*5069185fSDan Murphy 1096*5069185fSDan Murphy return 0; 1097*5069185fSDan Murphy } 1098*5069185fSDan Murphy 1099*5069185fSDan Murphy static int bq25980_hw_init(struct bq25980_device *bq) 1100*5069185fSDan Murphy { 1101*5069185fSDan Murphy struct power_supply_battery_info bat_info = { }; 1102*5069185fSDan Murphy int wd_reg_val; 1103*5069185fSDan Murphy int ret = 0; 1104*5069185fSDan Murphy int curr_val; 1105*5069185fSDan Murphy int volt_val; 1106*5069185fSDan Murphy int i; 1107*5069185fSDan Murphy 1108*5069185fSDan Murphy if (!bq->watchdog_timer) { 1109*5069185fSDan Murphy ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_3, 1110*5069185fSDan Murphy BQ25980_WATCHDOG_DIS, 1111*5069185fSDan Murphy BQ25980_WATCHDOG_DIS); 1112*5069185fSDan Murphy } else { 1113*5069185fSDan Murphy for (i = 0; i < BQ25980_NUM_WD_VAL; i++) { 1114*5069185fSDan Murphy if (bq->watchdog_timer > bq25980_watchdog_time[i] && 1115*5069185fSDan Murphy bq->watchdog_timer < bq25980_watchdog_time[i + 1]) { 1116*5069185fSDan Murphy wd_reg_val = i; 1117*5069185fSDan Murphy break; 1118*5069185fSDan Murphy } 1119*5069185fSDan Murphy } 1120*5069185fSDan Murphy 1121*5069185fSDan Murphy ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_3, 1122*5069185fSDan Murphy BQ25980_WATCHDOG_MASK, wd_reg_val); 1123*5069185fSDan Murphy } 1124*5069185fSDan Murphy if (ret) 1125*5069185fSDan Murphy return ret; 1126*5069185fSDan Murphy 1127*5069185fSDan Murphy ret = power_supply_get_battery_info(bq->charger, &bat_info); 1128*5069185fSDan Murphy if (ret) { 1129*5069185fSDan Murphy dev_warn(bq->dev, "battery info missing\n"); 1130*5069185fSDan Murphy return -EINVAL; 1131*5069185fSDan Murphy } 1132*5069185fSDan Murphy 1133*5069185fSDan Murphy bq->init_data.ichg_max = bat_info.constant_charge_current_max_ua; 1134*5069185fSDan Murphy bq->init_data.vreg_max = bat_info.constant_charge_voltage_max_uv; 1135*5069185fSDan Murphy 1136*5069185fSDan Murphy if (bq->state.bypass) { 1137*5069185fSDan Murphy ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2, 1138*5069185fSDan Murphy BQ25980_EN_BYPASS, BQ25980_EN_BYPASS); 1139*5069185fSDan Murphy if (ret) 1140*5069185fSDan Murphy return ret; 1141*5069185fSDan Murphy 1142*5069185fSDan Murphy curr_val = bq->init_data.bypass_ilim; 1143*5069185fSDan Murphy volt_val = bq->init_data.bypass_vlim; 1144*5069185fSDan Murphy } else { 1145*5069185fSDan Murphy curr_val = bq->init_data.sc_ilim; 1146*5069185fSDan Murphy volt_val = bq->init_data.sc_vlim; 1147*5069185fSDan Murphy } 1148*5069185fSDan Murphy 1149*5069185fSDan Murphy ret = bq25980_set_input_curr_lim(bq, curr_val); 1150*5069185fSDan Murphy if (ret) 1151*5069185fSDan Murphy return ret; 1152*5069185fSDan Murphy 1153*5069185fSDan Murphy ret = bq25980_set_input_volt_lim(bq, volt_val); 1154*5069185fSDan Murphy if (ret) 1155*5069185fSDan Murphy return ret; 1156*5069185fSDan Murphy 1157*5069185fSDan Murphy return regmap_update_bits(bq->regmap, BQ25980_ADC_CONTROL1, 1158*5069185fSDan Murphy BQ25980_ADC_EN, BQ25980_ADC_EN); 1159*5069185fSDan Murphy } 1160*5069185fSDan Murphy 1161*5069185fSDan Murphy static int bq25980_parse_dt(struct bq25980_device *bq) 1162*5069185fSDan Murphy { 1163*5069185fSDan Murphy int ret; 1164*5069185fSDan Murphy 1165*5069185fSDan Murphy ret = device_property_read_u32(bq->dev, "ti,watchdog-timeout-ms", 1166*5069185fSDan Murphy &bq->watchdog_timer); 1167*5069185fSDan Murphy if (ret) 1168*5069185fSDan Murphy bq->watchdog_timer = BQ25980_WATCHDOG_MIN; 1169*5069185fSDan Murphy 1170*5069185fSDan Murphy if (bq->watchdog_timer > BQ25980_WATCHDOG_MAX || 1171*5069185fSDan Murphy bq->watchdog_timer < BQ25980_WATCHDOG_MIN) 1172*5069185fSDan Murphy return -EINVAL; 1173*5069185fSDan Murphy 1174*5069185fSDan Murphy ret = device_property_read_u32(bq->dev, 1175*5069185fSDan Murphy "ti,sc-ovp-limit-microvolt", 1176*5069185fSDan Murphy &bq->init_data.sc_vlim); 1177*5069185fSDan Murphy if (ret) 1178*5069185fSDan Murphy bq->init_data.sc_vlim = bq->chip_info->busovp_sc_def; 1179*5069185fSDan Murphy 1180*5069185fSDan Murphy if (bq->init_data.sc_vlim > bq->chip_info->busovp_sc_max || 1181*5069185fSDan Murphy bq->init_data.sc_vlim < bq->chip_info->busovp_sc_min) { 1182*5069185fSDan Murphy dev_err(bq->dev, "SC ovp limit is out of range\n"); 1183*5069185fSDan Murphy return -EINVAL; 1184*5069185fSDan Murphy } 1185*5069185fSDan Murphy 1186*5069185fSDan Murphy ret = device_property_read_u32(bq->dev, 1187*5069185fSDan Murphy "ti,sc-ocp-limit-microamp", 1188*5069185fSDan Murphy &bq->init_data.sc_ilim); 1189*5069185fSDan Murphy if (ret) 1190*5069185fSDan Murphy bq->init_data.sc_ilim = bq->chip_info->busocp_def; 1191*5069185fSDan Murphy 1192*5069185fSDan Murphy if (bq->init_data.sc_ilim > bq->chip_info->busocp_sc_max || 1193*5069185fSDan Murphy bq->init_data.sc_ilim < bq->chip_info->busocp_sc_min) { 1194*5069185fSDan Murphy dev_err(bq->dev, "SC ocp limit is out of range\n"); 1195*5069185fSDan Murphy return -EINVAL; 1196*5069185fSDan Murphy } 1197*5069185fSDan Murphy 1198*5069185fSDan Murphy ret = device_property_read_u32(bq->dev, 1199*5069185fSDan Murphy "ti,bypass-ovp-limit-microvolt", 1200*5069185fSDan Murphy &bq->init_data.bypass_vlim); 1201*5069185fSDan Murphy if (ret) 1202*5069185fSDan Murphy bq->init_data.bypass_vlim = bq->chip_info->busovp_byp_def; 1203*5069185fSDan Murphy 1204*5069185fSDan Murphy if (bq->init_data.bypass_vlim > bq->chip_info->busovp_byp_max || 1205*5069185fSDan Murphy bq->init_data.bypass_vlim < bq->chip_info->busovp_byp_min) { 1206*5069185fSDan Murphy dev_err(bq->dev, "Bypass ovp limit is out of range\n"); 1207*5069185fSDan Murphy return -EINVAL; 1208*5069185fSDan Murphy } 1209*5069185fSDan Murphy 1210*5069185fSDan Murphy ret = device_property_read_u32(bq->dev, 1211*5069185fSDan Murphy "ti,bypass-ocp-limit-microamp", 1212*5069185fSDan Murphy &bq->init_data.bypass_ilim); 1213*5069185fSDan Murphy if (ret) 1214*5069185fSDan Murphy bq->init_data.bypass_ilim = bq->chip_info->busocp_def; 1215*5069185fSDan Murphy 1216*5069185fSDan Murphy if (bq->init_data.bypass_ilim > bq->chip_info->busocp_byp_max || 1217*5069185fSDan Murphy bq->init_data.bypass_ilim < bq->chip_info->busocp_byp_min) { 1218*5069185fSDan Murphy dev_err(bq->dev, "Bypass ocp limit is out of range\n"); 1219*5069185fSDan Murphy return -EINVAL; 1220*5069185fSDan Murphy } 1221*5069185fSDan Murphy 1222*5069185fSDan Murphy 1223*5069185fSDan Murphy bq->state.bypass = device_property_read_bool(bq->dev, 1224*5069185fSDan Murphy "ti,bypass-enable"); 1225*5069185fSDan Murphy return 0; 1226*5069185fSDan Murphy } 1227*5069185fSDan Murphy 1228*5069185fSDan Murphy static int bq25980_probe(struct i2c_client *client, 1229*5069185fSDan Murphy const struct i2c_device_id *id) 1230*5069185fSDan Murphy { 1231*5069185fSDan Murphy struct device *dev = &client->dev; 1232*5069185fSDan Murphy struct bq25980_device *bq; 1233*5069185fSDan Murphy int ret; 1234*5069185fSDan Murphy 1235*5069185fSDan Murphy bq = devm_kzalloc(dev, sizeof(*bq), GFP_KERNEL); 1236*5069185fSDan Murphy if (!bq) 1237*5069185fSDan Murphy return -ENOMEM; 1238*5069185fSDan Murphy 1239*5069185fSDan Murphy bq->client = client; 1240*5069185fSDan Murphy bq->dev = dev; 1241*5069185fSDan Murphy 1242*5069185fSDan Murphy mutex_init(&bq->lock); 1243*5069185fSDan Murphy 1244*5069185fSDan Murphy strncpy(bq->model_name, id->name, I2C_NAME_SIZE); 1245*5069185fSDan Murphy bq->chip_info = &bq25980_chip_info_tbl[id->driver_data]; 1246*5069185fSDan Murphy 1247*5069185fSDan Murphy bq->regmap = devm_regmap_init_i2c(client, 1248*5069185fSDan Murphy bq->chip_info->regmap_config); 1249*5069185fSDan Murphy if (IS_ERR(bq->regmap)) { 1250*5069185fSDan Murphy dev_err(dev, "Failed to allocate register map\n"); 1251*5069185fSDan Murphy return PTR_ERR(bq->regmap); 1252*5069185fSDan Murphy } 1253*5069185fSDan Murphy 1254*5069185fSDan Murphy i2c_set_clientdata(client, bq); 1255*5069185fSDan Murphy 1256*5069185fSDan Murphy ret = bq25980_parse_dt(bq); 1257*5069185fSDan Murphy if (ret) { 1258*5069185fSDan Murphy dev_err(dev, "Failed to read device tree properties%d\n", ret); 1259*5069185fSDan Murphy return ret; 1260*5069185fSDan Murphy } 1261*5069185fSDan Murphy 1262*5069185fSDan Murphy if (client->irq) { 1263*5069185fSDan Murphy ret = devm_request_threaded_irq(dev, client->irq, NULL, 1264*5069185fSDan Murphy bq25980_irq_handler_thread, 1265*5069185fSDan Murphy IRQF_TRIGGER_FALLING | 1266*5069185fSDan Murphy IRQF_ONESHOT, 1267*5069185fSDan Murphy dev_name(&client->dev), bq); 1268*5069185fSDan Murphy if (ret) 1269*5069185fSDan Murphy return ret; 1270*5069185fSDan Murphy } 1271*5069185fSDan Murphy 1272*5069185fSDan Murphy ret = bq25980_power_supply_init(bq, dev); 1273*5069185fSDan Murphy if (ret) { 1274*5069185fSDan Murphy dev_err(dev, "Failed to register power supply\n"); 1275*5069185fSDan Murphy return ret; 1276*5069185fSDan Murphy } 1277*5069185fSDan Murphy 1278*5069185fSDan Murphy ret = bq25980_hw_init(bq); 1279*5069185fSDan Murphy if (ret) { 1280*5069185fSDan Murphy dev_err(dev, "Cannot initialize the chip.\n"); 1281*5069185fSDan Murphy return ret; 1282*5069185fSDan Murphy } 1283*5069185fSDan Murphy 1284*5069185fSDan Murphy return 0; 1285*5069185fSDan Murphy } 1286*5069185fSDan Murphy 1287*5069185fSDan Murphy static const struct i2c_device_id bq25980_i2c_ids[] = { 1288*5069185fSDan Murphy { "bq25980", BQ25980 }, 1289*5069185fSDan Murphy { "bq25975", BQ25975 }, 1290*5069185fSDan Murphy { "bq25975", BQ25975 }, 1291*5069185fSDan Murphy {}, 1292*5069185fSDan Murphy }; 1293*5069185fSDan Murphy MODULE_DEVICE_TABLE(i2c, bq25980_i2c_ids); 1294*5069185fSDan Murphy 1295*5069185fSDan Murphy static const struct of_device_id bq25980_of_match[] = { 1296*5069185fSDan Murphy { .compatible = "ti,bq25980", .data = (void *)BQ25980 }, 1297*5069185fSDan Murphy { .compatible = "ti,bq25975", .data = (void *)BQ25975 }, 1298*5069185fSDan Murphy { .compatible = "ti,bq25960", .data = (void *)BQ25960 }, 1299*5069185fSDan Murphy { }, 1300*5069185fSDan Murphy }; 1301*5069185fSDan Murphy MODULE_DEVICE_TABLE(of, bq25980_of_match); 1302*5069185fSDan Murphy 1303*5069185fSDan Murphy static struct i2c_driver bq25980_driver = { 1304*5069185fSDan Murphy .driver = { 1305*5069185fSDan Murphy .name = "bq25980-charger", 1306*5069185fSDan Murphy .of_match_table = bq25980_of_match, 1307*5069185fSDan Murphy }, 1308*5069185fSDan Murphy .probe = bq25980_probe, 1309*5069185fSDan Murphy .id_table = bq25980_i2c_ids, 1310*5069185fSDan Murphy }; 1311*5069185fSDan Murphy module_i2c_driver(bq25980_driver); 1312*5069185fSDan Murphy 1313*5069185fSDan Murphy MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 1314*5069185fSDan Murphy MODULE_AUTHOR("Ricardo Rivera-Matos <r-rivera-matos@ti.com>"); 1315*5069185fSDan Murphy MODULE_DESCRIPTION("bq25980 charger driver"); 1316*5069185fSDan Murphy MODULE_LICENSE("GPL v2"); 1317