File Index
Files and directories
Sign in
FILE

bq24190_charger.c

File preview with syntax highlighting.

linux-6.19.14/drivers/power/supply/bq24190_charger.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Driver for the TI bq24190 battery charger.
   4 *
   5 * Author: Mark A. Greer <mgreer@animalcreek.com>
   6 */
   7
   8#include <linux/mod_devicetable.h>
   9#include <linux/module.h>
  10#include <linux/interrupt.h>
  11#include <linux/delay.h>
  12#include <linux/pm_runtime.h>
  13#include <linux/power_supply.h>
  14#include <linux/power/bq24190_charger.h>
  15#include <linux/regulator/driver.h>
  16#include <linux/regulator/machine.h>
  17#include <linux/workqueue.h>
  18#include <linux/i2c.h>
  19#include <linux/extcon-provider.h>
  20
  21#define	BQ24190_MANUFACTURER	"Texas Instruments"
  22
  23#define BQ24190_REG_ISC		0x00 /* Input Source Control */
  24#define BQ24190_REG_ISC_EN_HIZ_MASK		BIT(7)
  25#define BQ24190_REG_ISC_EN_HIZ_SHIFT		7
  26#define BQ24190_REG_ISC_VINDPM_MASK		(BIT(6) | BIT(5) | BIT(4) | \
  27						 BIT(3))
  28#define BQ24190_REG_ISC_VINDPM_SHIFT		3
  29#define BQ24190_REG_ISC_IINLIM_MASK		(BIT(2) | BIT(1) | BIT(0))
  30#define BQ24190_REG_ISC_IINLIM_SHIFT		0
  31
  32#define BQ24190_REG_POC		0x01 /* Power-On Configuration */
  33#define BQ24190_REG_POC_RESET_MASK		BIT(7)
  34#define BQ24190_REG_POC_RESET_SHIFT		7
  35#define BQ24190_REG_POC_WDT_RESET_MASK		BIT(6)
  36#define BQ24190_REG_POC_WDT_RESET_SHIFT		6
  37#define BQ24190_REG_POC_CHG_CONFIG_MASK		(BIT(5) | BIT(4))
  38#define BQ24190_REG_POC_CHG_CONFIG_SHIFT	4
  39#define BQ24190_REG_POC_CHG_CONFIG_DISABLE	0x0
  40#define BQ24190_REG_POC_CHG_CONFIG_CHARGE	0x1
  41#define BQ24190_REG_POC_CHG_CONFIG_OTG		0x2
  42#define BQ24190_REG_POC_CHG_CONFIG_OTG_ALT	0x3
  43#define BQ24296_REG_POC_OTG_CONFIG_MASK		BIT(5)
  44#define BQ24296_REG_POC_OTG_CONFIG_SHIFT	5
  45#define BQ24296_REG_POC_CHG_CONFIG_MASK		BIT(4)
  46#define BQ24296_REG_POC_CHG_CONFIG_SHIFT	4
  47#define BQ24296_REG_POC_OTG_CONFIG_DISABLE	0x0
  48#define BQ24296_REG_POC_OTG_CONFIG_OTG		0x1
  49#define BQ24190_REG_POC_SYS_MIN_MASK		(BIT(3) | BIT(2) | BIT(1))
  50#define BQ24190_REG_POC_SYS_MIN_SHIFT		1
  51#define BQ24190_REG_POC_SYS_MIN_MIN			3000
  52#define BQ24190_REG_POC_SYS_MIN_MAX			3700
  53#define BQ24190_REG_POC_BOOST_LIM_MASK		BIT(0)
  54#define BQ24190_REG_POC_BOOST_LIM_SHIFT		0
  55
  56#define BQ24190_REG_CCC		0x02 /* Charge Current Control */
  57#define BQ24190_REG_CCC_ICHG_MASK		(BIT(7) | BIT(6) | BIT(5) | \
  58						 BIT(4) | BIT(3) | BIT(2))
  59#define BQ24190_REG_CCC_ICHG_SHIFT		2
  60#define BQ24190_REG_CCC_FORCE_20PCT_MASK	BIT(0)
  61#define BQ24190_REG_CCC_FORCE_20PCT_SHIFT	0
  62
  63#define BQ24190_REG_PCTCC	0x03 /* Pre-charge/Termination Current Cntl */
  64#define BQ24190_REG_PCTCC_IPRECHG_MASK		(BIT(7) | BIT(6) | BIT(5) | \
  65						 BIT(4))
  66#define BQ24190_REG_PCTCC_IPRECHG_SHIFT		4
  67#define BQ24190_REG_PCTCC_IPRECHG_MIN			128
  68#define BQ24190_REG_PCTCC_IPRECHG_MAX			2048
  69#define BQ24190_REG_PCTCC_ITERM_MASK		(BIT(3) | BIT(2) | BIT(1) | \
  70						 BIT(0))
  71#define BQ24190_REG_PCTCC_ITERM_SHIFT		0
  72#define BQ24190_REG_PCTCC_ITERM_MIN			128
  73#define BQ24190_REG_PCTCC_ITERM_MAX			2048
  74
  75#define BQ24190_REG_CVC		0x04 /* Charge Voltage Control */
  76#define BQ24190_REG_CVC_VREG_MASK		(BIT(7) | BIT(6) | BIT(5) | \
  77						 BIT(4) | BIT(3) | BIT(2))
  78#define BQ24190_REG_CVC_VREG_SHIFT		2
  79#define BQ24190_REG_CVC_BATLOWV_MASK		BIT(1)
  80#define BQ24190_REG_CVC_BATLOWV_SHIFT		1
  81#define BQ24190_REG_CVC_VRECHG_MASK		BIT(0)
  82#define BQ24190_REG_CVC_VRECHG_SHIFT		0
  83
  84#define BQ24190_REG_CTTC	0x05 /* Charge Term/Timer Control */
  85#define BQ24190_REG_CTTC_EN_TERM_MASK		BIT(7)
  86#define BQ24190_REG_CTTC_EN_TERM_SHIFT		7
  87#define BQ24190_REG_CTTC_TERM_STAT_MASK		BIT(6)
  88#define BQ24190_REG_CTTC_TERM_STAT_SHIFT	6
  89#define BQ24190_REG_CTTC_WATCHDOG_MASK		(BIT(5) | BIT(4))
  90#define BQ24190_REG_CTTC_WATCHDOG_SHIFT		4
  91#define BQ24190_REG_CTTC_EN_TIMER_MASK		BIT(3)
  92#define BQ24190_REG_CTTC_EN_TIMER_SHIFT		3
  93#define BQ24190_REG_CTTC_CHG_TIMER_MASK		(BIT(2) | BIT(1))
  94#define BQ24190_REG_CTTC_CHG_TIMER_SHIFT	1
  95#define BQ24190_REG_CTTC_JEITA_ISET_MASK	BIT(0)
  96#define BQ24190_REG_CTTC_JEITA_ISET_SHIFT	0
  97
  98#define BQ24190_REG_ICTRC	0x06 /* IR Comp/Thermal Regulation Control */
  99#define BQ24190_REG_ICTRC_BAT_COMP_MASK		(BIT(7) | BIT(6) | BIT(5))
 100#define BQ24190_REG_ICTRC_BAT_COMP_SHIFT	5
 101#define BQ24190_REG_ICTRC_VCLAMP_MASK		(BIT(4) | BIT(3) | BIT(2))
 102#define BQ24190_REG_ICTRC_VCLAMP_SHIFT		2
 103#define BQ24190_REG_ICTRC_TREG_MASK		(BIT(1) | BIT(0))
 104#define BQ24190_REG_ICTRC_TREG_SHIFT		0
 105
 106#define BQ24190_REG_MOC		0x07 /* Misc. Operation Control */
 107#define BQ24190_REG_MOC_DPDM_EN_MASK		BIT(7)
 108#define BQ24190_REG_MOC_DPDM_EN_SHIFT		7
 109#define BQ24190_REG_MOC_TMR2X_EN_MASK		BIT(6)
 110#define BQ24190_REG_MOC_TMR2X_EN_SHIFT		6
 111#define BQ24190_REG_MOC_BATFET_DISABLE_MASK	BIT(5)
 112#define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT	5
 113#define BQ24190_REG_MOC_JEITA_VSET_MASK		BIT(4)
 114#define BQ24190_REG_MOC_JEITA_VSET_SHIFT	4
 115#define BQ24190_REG_MOC_INT_MASK_MASK		(BIT(1) | BIT(0))
 116#define BQ24190_REG_MOC_INT_MASK_SHIFT		0
 117
 118#define BQ24190_REG_SS		0x08 /* System Status */
 119#define BQ24190_REG_SS_VBUS_STAT_MASK		(BIT(7) | BIT(6))
 120#define BQ24190_REG_SS_VBUS_STAT_SHIFT		6
 121#define BQ24190_REG_SS_CHRG_STAT_MASK		(BIT(5) | BIT(4))
 122#define BQ24190_REG_SS_CHRG_STAT_SHIFT		4
 123#define BQ24190_REG_SS_DPM_STAT_MASK		BIT(3)
 124#define BQ24190_REG_SS_DPM_STAT_SHIFT		3
 125#define BQ24190_REG_SS_PG_STAT_MASK		BIT(2)
 126#define BQ24190_REG_SS_PG_STAT_SHIFT		2
 127#define BQ24190_REG_SS_THERM_STAT_MASK		BIT(1)
 128#define BQ24190_REG_SS_THERM_STAT_SHIFT		1
 129#define BQ24190_REG_SS_VSYS_STAT_MASK		BIT(0)
 130#define BQ24190_REG_SS_VSYS_STAT_SHIFT		0
 131
 132#define BQ24190_REG_F		0x09 /* Fault */
 133#define BQ24190_REG_F_WATCHDOG_FAULT_MASK	BIT(7)
 134#define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT	7
 135#define BQ24190_REG_F_BOOST_FAULT_MASK		BIT(6)
 136#define BQ24190_REG_F_BOOST_FAULT_SHIFT		6
 137#define BQ24190_REG_F_CHRG_FAULT_MASK		(BIT(5) | BIT(4))
 138#define BQ24190_REG_F_CHRG_FAULT_SHIFT		4
 139#define BQ24190_REG_F_BAT_FAULT_MASK		BIT(3)
 140#define BQ24190_REG_F_BAT_FAULT_SHIFT		3
 141#define BQ24190_REG_F_NTC_FAULT_MASK		(BIT(2) | BIT(1) | BIT(0))
 142#define BQ24190_REG_F_NTC_FAULT_SHIFT		0
 143#define BQ24296_REG_F_NTC_FAULT_MASK		(BIT(1) | BIT(0))
 144#define BQ24296_REG_F_NTC_FAULT_SHIFT		0
 145
 146#define BQ24190_REG_VPRS	0x0A /* Vendor/Part/Revision Status */
 147#define BQ24190_REG_VPRS_PN_MASK		(BIT(5) | BIT(4) | BIT(3))
 148#define BQ24190_REG_VPRS_PN_SHIFT		3
 149#define BQ24190_REG_VPRS_PN_24190		0x4
 150#define BQ24190_REG_VPRS_PN_24192		0x5 /* Also 24193, 24196 */
 151#define BQ24190_REG_VPRS_PN_24192I		0x3
 152#define BQ24296_REG_VPRS_PN_MASK		(BIT(7) | BIT(6) | BIT(5))
 153#define BQ24296_REG_VPRS_PN_SHIFT		5
 154#define BQ24296_REG_VPRS_PN_24296		0x1
 155#define BQ24296_REG_VPRS_PN_24297		0x3
 156#define BQ24190_REG_VPRS_TS_PROFILE_MASK	BIT(2)
 157#define BQ24190_REG_VPRS_TS_PROFILE_SHIFT	2
 158#define BQ24190_REG_VPRS_DEV_REG_MASK		(BIT(1) | BIT(0))
 159#define BQ24190_REG_VPRS_DEV_REG_SHIFT		0
 160
 161/*
 162 * The tables below provide a 2-way mapping for the value that goes in
 163 * the register field and the real-world value that it represents.
 164 * The index of the array is the value that goes in the register; the
 165 * number at that index in the array is the real-world value that it
 166 * represents.
 167 */
 168
 169/* REG00[2:0] (IINLIM) in uAh */
 170static const int bq24190_isc_iinlim_values[] = {
 171	 100000,  150000,  500000,  900000, 1200000, 1500000, 2000000, 3000000
 172};
 173
 174/* REG02[7:2] (ICHG) in uAh */
 175static const int bq24190_ccc_ichg_values[] = {
 176	 512000,  576000,  640000,  704000,  768000,  832000,  896000,  960000,
 177	1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
 178	1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
 179	2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
 180	2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
 181	3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
 182	3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
 183	4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
 184};
 185
 186/* ICHG higher than 3008mA is not supported in BQ24296 */
 187#define BQ24296_CCC_ICHG_VALUES_LEN	40
 188
 189/* REG04[7:2] (VREG) in uV */
 190static const int bq24190_cvc_vreg_values[] = {
 191	3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
 192	3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
 193	3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
 194	3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
 195	4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
 196	4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
 197	4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
 198	4400000
 199};
 200
 201/* REG06[1:0] (TREG) in tenths of degrees Celsius */
 202static const int bq24190_ictrc_treg_values[] = {
 203	600, 800, 1000, 1200
 204};
 205
 206enum bq24190_chip {
 207	BQ24190,
 208	BQ24192,
 209	BQ24192i,
 210	BQ24193,
 211	BQ24196,
 212	BQ24296,
 213	BQ24297,
 214};
 215
 216/*
 217 * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
 218 * so the first read after a fault returns the latched value and subsequent
 219 * reads return the current value.  In order to return the fault status
 220 * to the user, have the interrupt handler save the reg's value and retrieve
 221 * it in the appropriate health/status routine.
 222 */
 223struct bq24190_dev_info {
 224	struct i2c_client		*client;
 225	struct device			*dev;
 226	struct extcon_dev		*edev;
 227	struct power_supply		*charger;
 228	struct power_supply		*battery;
 229	struct delayed_work		input_current_limit_work;
 230	char				model_name[I2C_NAME_SIZE];
 231	bool				initialized;
 232	bool				irq_event;
 233	bool				otg_vbus_enabled;
 234	int				charge_type;
 235	u16				sys_min;
 236	u16				iprechg;
 237	u16				iterm;
 238	u32				ichg;
 239	u32				ichg_max;
 240	u32				vreg;
 241	u32				vreg_max;
 242	struct mutex			f_reg_lock;
 243	u8				f_reg;
 244	u8				ss_reg;
 245	u8				watchdog;
 246	const struct bq24190_chip_info	*info;
 247};
 248
 249struct bq24190_chip_info {
 250	int ichg_array_size;
 251#ifdef CONFIG_REGULATOR
 252	const struct regulator_desc *vbus_desc;
 253#endif
 254	int (*check_chip)(struct bq24190_dev_info *bdi);
 255	int (*set_chg_config)(struct bq24190_dev_info *bdi, const u8 chg_config);
 256	int (*set_otg_vbus)(struct bq24190_dev_info *bdi, bool enable);
 257	u8 ntc_fault_mask;
 258	int (*get_ntc_status)(const u8 value);
 259};
 260
 261static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
 262					   const union power_supply_propval *val);
 263
 264static const unsigned int bq24190_usb_extcon_cable[] = {
 265	EXTCON_USB,
 266	EXTCON_NONE,
 267};
 268
 269
 270/*
 271 * Return the index in 'tbl' of greatest value that is less than or equal to
 272 * 'val'.  The index range returned is 0 to 'tbl_size' - 1.  Assumes that
 273 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
 274 * is less than 2^8.
 275 */
 276static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
 277{
 278	int i;
 279
 280	for (i = 1; i < tbl_size; i++)
 281		if (v < tbl[i])
 282			break;
 283
 284	return i - 1;
 285}
 286
 287/* Basic driver I/O routines */
 288
 289static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
 290{
 291	int ret;
 292
 293	ret = i2c_smbus_read_byte_data(bdi->client, reg);
 294	if (ret < 0)
 295		return ret;
 296
 297	*data = ret;
 298	return 0;
 299}
 300
 301static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
 302{
 303	return i2c_smbus_write_byte_data(bdi->client, reg, data);
 304}
 305
 306static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
 307		u8 mask, u8 shift, u8 *data)
 308{
 309	u8 v;
 310	int ret;
 311
 312	ret = bq24190_read(bdi, reg, &v);
 313	if (ret < 0)
 314		return ret;
 315
 316	v &= mask;
 317	v >>= shift;
 318	*data = v;
 319
 320	return 0;
 321}
 322
 323static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
 324		u8 mask, u8 shift, u8 data)
 325{
 326	u8 v;
 327	int ret;
 328
 329	ret = bq24190_read(bdi, reg, &v);
 330	if (ret < 0)
 331		return ret;
 332
 333	v &= ~mask;
 334	v |= ((data << shift) & mask);
 335
 336	return bq24190_write(bdi, reg, v);
 337}
 338
 339static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
 340		u8 reg, u8 mask, u8 shift,
 341		const int tbl[], int tbl_size,
 342		int *val)
 343{
 344	u8 v;
 345	int ret;
 346
 347	ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
 348	if (ret < 0)
 349		return ret;
 350
 351	v = (v >= tbl_size) ? (tbl_size - 1) : v;
 352	*val = tbl[v];
 353
 354	return 0;
 355}
 356
 357static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
 358		u8 reg, u8 mask, u8 shift,
 359		const int tbl[], int tbl_size,
 360		int val)
 361{
 362	u8 idx;
 363
 364	idx = bq24190_find_idx(tbl, tbl_size, val);
 365
 366	return bq24190_write_mask(bdi, reg, mask, shift, idx);
 367}
 368
 369#ifdef CONFIG_SYSFS
 370/*
 371 * There are a numerous options that are configurable on the bq24190
 372 * that go well beyond what the power_supply properties provide access to.
 373 * Provide sysfs access to them so they can be examined and possibly modified
 374 * on the fly.  They will be provided for the charger power_supply object only
 375 * and will be prefixed by 'f_' to make them easier to recognize.
 376 */
 377
 378#define BQ24190_SYSFS_FIELD(_name, r, f, m, store)			\
 379{									\
 380	.attr	= __ATTR(f_##_name, m, bq24190_sysfs_show, store),	\
 381	.reg	= BQ24190_REG_##r,					\
 382	.mask	= BQ24190_REG_##r##_##f##_MASK,				\
 383	.shift	= BQ24190_REG_##r##_##f##_SHIFT,			\
 384}
 385
 386#define BQ24190_SYSFS_FIELD_RW(_name, r, f)				\
 387		BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO,	\
 388				bq24190_sysfs_store)
 389
 390#define BQ24190_SYSFS_FIELD_RO(_name, r, f)				\
 391		BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
 392
 393static ssize_t bq24190_sysfs_show(struct device *dev,
 394		struct device_attribute *attr, char *buf);
 395static ssize_t bq24190_sysfs_store(struct device *dev,
 396		struct device_attribute *attr, const char *buf, size_t count);
 397
 398struct bq24190_sysfs_field_info {
 399	struct device_attribute	attr;
 400	u8	reg;
 401	u8	mask;
 402	u8	shift;
 403};
 404
 405/* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
 406#undef SS
 407
 408static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
 409			/*	sysfs name	reg	field in reg */
 410	BQ24190_SYSFS_FIELD_RW(en_hiz,		ISC,	EN_HIZ),
 411	BQ24190_SYSFS_FIELD_RW(vindpm,		ISC,	VINDPM),
 412	BQ24190_SYSFS_FIELD_RW(iinlim,		ISC,	IINLIM),
 413	BQ24190_SYSFS_FIELD_RW(chg_config,	POC,	CHG_CONFIG),
 414	BQ24190_SYSFS_FIELD_RW(sys_min,		POC,	SYS_MIN),
 415	BQ24190_SYSFS_FIELD_RW(boost_lim,	POC,	BOOST_LIM),
 416	BQ24190_SYSFS_FIELD_RW(ichg,		CCC,	ICHG),
 417	BQ24190_SYSFS_FIELD_RW(force_20_pct,	CCC,	FORCE_20PCT),
 418	BQ24190_SYSFS_FIELD_RW(iprechg,		PCTCC,	IPRECHG),
 419	BQ24190_SYSFS_FIELD_RW(iterm,		PCTCC,	ITERM),
 420	BQ24190_SYSFS_FIELD_RW(vreg,		CVC,	VREG),
 421	BQ24190_SYSFS_FIELD_RW(batlowv,		CVC,	BATLOWV),
 422	BQ24190_SYSFS_FIELD_RW(vrechg,		CVC,	VRECHG),
 423	BQ24190_SYSFS_FIELD_RW(en_term,		CTTC,	EN_TERM),
 424	BQ24190_SYSFS_FIELD_RW(term_stat,	CTTC,	TERM_STAT),
 425	BQ24190_SYSFS_FIELD_RO(watchdog,	CTTC,	WATCHDOG),
 426	BQ24190_SYSFS_FIELD_RW(en_timer,	CTTC,	EN_TIMER),
 427	BQ24190_SYSFS_FIELD_RW(chg_timer,	CTTC,	CHG_TIMER),
 428	BQ24190_SYSFS_FIELD_RW(jeita_iset,	CTTC,	JEITA_ISET),
 429	BQ24190_SYSFS_FIELD_RW(bat_comp,	ICTRC,	BAT_COMP),
 430	BQ24190_SYSFS_FIELD_RW(vclamp,		ICTRC,	VCLAMP),
 431	BQ24190_SYSFS_FIELD_RW(treg,		ICTRC,	TREG),
 432	BQ24190_SYSFS_FIELD_RW(dpdm_en,		MOC,	DPDM_EN),
 433	BQ24190_SYSFS_FIELD_RW(tmr2x_en,	MOC,	TMR2X_EN),
 434	BQ24190_SYSFS_FIELD_RW(batfet_disable,	MOC,	BATFET_DISABLE),
 435	BQ24190_SYSFS_FIELD_RW(jeita_vset,	MOC,	JEITA_VSET),
 436	BQ24190_SYSFS_FIELD_RO(int_mask,	MOC,	INT_MASK),
 437	BQ24190_SYSFS_FIELD_RO(vbus_stat,	SS,	VBUS_STAT),
 438	BQ24190_SYSFS_FIELD_RO(chrg_stat,	SS,	CHRG_STAT),
 439	BQ24190_SYSFS_FIELD_RO(dpm_stat,	SS,	DPM_STAT),
 440	BQ24190_SYSFS_FIELD_RO(pg_stat,		SS,	PG_STAT),
 441	BQ24190_SYSFS_FIELD_RO(therm_stat,	SS,	THERM_STAT),
 442	BQ24190_SYSFS_FIELD_RO(vsys_stat,	SS,	VSYS_STAT),
 443	BQ24190_SYSFS_FIELD_RO(watchdog_fault,	F,	WATCHDOG_FAULT),
 444	BQ24190_SYSFS_FIELD_RO(boost_fault,	F,	BOOST_FAULT),
 445	BQ24190_SYSFS_FIELD_RO(chrg_fault,	F,	CHRG_FAULT),
 446	BQ24190_SYSFS_FIELD_RO(bat_fault,	F,	BAT_FAULT),
 447	BQ24190_SYSFS_FIELD_RO(ntc_fault,	F,	NTC_FAULT),
 448	BQ24190_SYSFS_FIELD_RO(pn,		VPRS,	PN),
 449	BQ24190_SYSFS_FIELD_RO(ts_profile,	VPRS,	TS_PROFILE),
 450	BQ24190_SYSFS_FIELD_RO(dev_reg,		VPRS,	DEV_REG),
 451};
 452
 453static struct attribute *
 454	bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
 455
 456ATTRIBUTE_GROUPS(bq24190_sysfs);
 457
 458static void bq24190_sysfs_init_attrs(void)
 459{
 460	int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
 461
 462	for (i = 0; i < limit; i++)
 463		bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
 464
 465	bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
 466}
 467
 468static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
 469		const char *name)
 470{
 471	int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
 472
 473	for (i = 0; i < limit; i++)
 474		if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
 475			break;
 476
 477	if (i >= limit)
 478		return NULL;
 479
 480	return &bq24190_sysfs_field_tbl[i];
 481}
 482
 483static ssize_t bq24190_sysfs_show(struct device *dev,
 484		struct device_attribute *attr, char *buf)
 485{
 486	struct power_supply *psy = dev_to_psy(dev);
 487	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
 488	struct bq24190_sysfs_field_info *info;
 489	ssize_t count;
 490	int ret;
 491	u8 v;
 492
 493	info = bq24190_sysfs_field_lookup(attr->attr.name);
 494	if (!info)
 495		return -EINVAL;
 496
 497	ret = pm_runtime_resume_and_get(bdi->dev);
 498	if (ret < 0)
 499		return ret;
 500
 501	ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
 502	if (ret)
 503		count = ret;
 504	else
 505		count = sysfs_emit(buf, "%hhx\n", v);
 506
 507	pm_runtime_put_autosuspend(bdi->dev);
 508
 509	return count;
 510}
 511
 512static ssize_t bq24190_sysfs_store(struct device *dev,
 513		struct device_attribute *attr, const char *buf, size_t count)
 514{
 515	struct power_supply *psy = dev_to_psy(dev);
 516	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
 517	struct bq24190_sysfs_field_info *info;
 518	int ret;
 519	u8 v;
 520
 521	info = bq24190_sysfs_field_lookup(attr->attr.name);
 522	if (!info)
 523		return -EINVAL;
 524
 525	ret = kstrtou8(buf, 0, &v);
 526	if (ret < 0)
 527		return ret;
 528
 529	ret = pm_runtime_resume_and_get(bdi->dev);
 530	if (ret < 0)
 531		return ret;
 532
 533	ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
 534	if (ret)
 535		count = ret;
 536
 537	pm_runtime_put_autosuspend(bdi->dev);
 538
 539	return count;
 540}
 541#endif
 542
 543static int bq24190_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
 544{
 545	union power_supply_propval val = { .intval = bdi->charge_type };
 546	int ret;
 547
 548	ret = pm_runtime_resume_and_get(bdi->dev);
 549	if (ret < 0) {
 550		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
 551		return ret;
 552	}
 553
 554	bdi->otg_vbus_enabled = enable;
 555	if (enable)
 556		ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 557					 BQ24190_REG_POC_CHG_CONFIG_MASK,
 558					 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
 559					 BQ24190_REG_POC_CHG_CONFIG_OTG);
 560	else
 561		ret = bq24190_charger_set_charge_type(bdi, &val);
 562
 563	pm_runtime_put_autosuspend(bdi->dev);
 564
 565	return ret;
 566}
 567
 568static int bq24296_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
 569{
 570	union power_supply_propval val = { .intval = bdi->charge_type };
 571	int ret;
 572
 573	ret = pm_runtime_resume_and_get(bdi->dev);
 574	if (ret < 0) {
 575		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
 576		return ret;
 577	}
 578
 579	bdi->otg_vbus_enabled = enable;
 580	if (enable) {
 581		ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 582					 BQ24296_REG_POC_CHG_CONFIG_MASK,
 583					 BQ24296_REG_POC_CHG_CONFIG_SHIFT,
 584					 BQ24190_REG_POC_CHG_CONFIG_DISABLE);
 585
 586		if (ret < 0)
 587			goto out;
 588
 589		ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 590					 BQ24296_REG_POC_OTG_CONFIG_MASK,
 591					 BQ24296_REG_POC_OTG_CONFIG_SHIFT,
 592					 BQ24296_REG_POC_OTG_CONFIG_OTG);
 593	} else {
 594		ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 595					 BQ24296_REG_POC_OTG_CONFIG_MASK,
 596					 BQ24296_REG_POC_OTG_CONFIG_SHIFT,
 597					 BQ24296_REG_POC_OTG_CONFIG_DISABLE);
 598		if (ret < 0)
 599			goto out;
 600
 601		ret = bq24190_charger_set_charge_type(bdi, &val);
 602	}
 603
 604out:
 605	pm_runtime_put_autosuspend(bdi->dev);
 606
 607	return ret;
 608}
 609
 610#ifdef CONFIG_REGULATOR
 611static int bq24190_vbus_enable(struct regulator_dev *dev)
 612{
 613	return bq24190_set_otg_vbus(rdev_get_drvdata(dev), true);
 614}
 615
 616static int bq24190_vbus_disable(struct regulator_dev *dev)
 617{
 618	return bq24190_set_otg_vbus(rdev_get_drvdata(dev), false);
 619}
 620
 621static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
 622{
 623	struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
 624	int ret;
 625	u8 val;
 626
 627	ret = pm_runtime_resume_and_get(bdi->dev);
 628	if (ret < 0) {
 629		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
 630		return ret;
 631	}
 632
 633	ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 634				BQ24190_REG_POC_CHG_CONFIG_MASK,
 635				BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val);
 636
 637	pm_runtime_put_autosuspend(bdi->dev);
 638
 639	if (ret)
 640		return ret;
 641
 642	bdi->otg_vbus_enabled = (val == BQ24190_REG_POC_CHG_CONFIG_OTG ||
 643				 val == BQ24190_REG_POC_CHG_CONFIG_OTG_ALT);
 644	return bdi->otg_vbus_enabled;
 645}
 646
 647static int bq24296_vbus_enable(struct regulator_dev *dev)
 648{
 649	return bq24296_set_otg_vbus(rdev_get_drvdata(dev), true);
 650}
 651
 652static int bq24296_vbus_disable(struct regulator_dev *dev)
 653{
 654	return bq24296_set_otg_vbus(rdev_get_drvdata(dev), false);
 655}
 656
 657static int bq24296_vbus_is_enabled(struct regulator_dev *dev)
 658{
 659	struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
 660	int ret;
 661	u8 val;
 662
 663	ret = pm_runtime_resume_and_get(bdi->dev);
 664	if (ret < 0) {
 665		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
 666		return ret;
 667	}
 668
 669	ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 670				BQ24296_REG_POC_OTG_CONFIG_MASK,
 671				BQ24296_REG_POC_OTG_CONFIG_SHIFT, &val);
 672
 673	pm_runtime_put_autosuspend(bdi->dev);
 674
 675	if (ret)
 676		return ret;
 677
 678	bdi->otg_vbus_enabled = (val == BQ24296_REG_POC_OTG_CONFIG_OTG);
 679
 680	return bdi->otg_vbus_enabled;
 681}
 682
 683static const struct regulator_ops bq24190_vbus_ops = {
 684	.enable = bq24190_vbus_enable,
 685	.disable = bq24190_vbus_disable,
 686	.is_enabled = bq24190_vbus_is_enabled,
 687};
 688
 689static const struct regulator_desc bq24190_vbus_desc = {
 690	.name = "usb_otg_vbus",
 691	.of_match = "usb-otg-vbus",
 692	.type = REGULATOR_VOLTAGE,
 693	.owner = THIS_MODULE,
 694	.ops = &bq24190_vbus_ops,
 695	.fixed_uV = 5000000,
 696	.n_voltages = 1,
 697};
 698
 699static const struct regulator_ops bq24296_vbus_ops = {
 700	.enable = bq24296_vbus_enable,
 701	.disable = bq24296_vbus_disable,
 702	.is_enabled = bq24296_vbus_is_enabled,
 703};
 704
 705static const struct regulator_desc bq24296_vbus_desc = {
 706	.name = "usb_otg_vbus",
 707	.of_match = "usb-otg-vbus",
 708	.type = REGULATOR_VOLTAGE,
 709	.owner = THIS_MODULE,
 710	.ops = &bq24296_vbus_ops,
 711	.fixed_uV = 5000000,
 712	.n_voltages = 1,
 713};
 714
 715static const struct regulator_init_data bq24190_vbus_init_data = {
 716	.constraints = {
 717		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
 718	},
 719};
 720
 721static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
 722{
 723	struct bq24190_platform_data *pdata = bdi->dev->platform_data;
 724	struct regulator_config cfg = { };
 725	struct regulator_dev *reg;
 726	int ret = 0;
 727
 728	cfg.dev = bdi->dev;
 729	if (pdata && pdata->regulator_init_data)
 730		cfg.init_data = pdata->regulator_init_data;
 731	else
 732		cfg.init_data = &bq24190_vbus_init_data;
 733	cfg.driver_data = bdi;
 734	reg = devm_regulator_register(bdi->dev, bdi->info->vbus_desc, &cfg);
 735	if (IS_ERR(reg)) {
 736		ret = PTR_ERR(reg);
 737		dev_err(bdi->dev, "Can't register regulator: %d\n", ret);
 738	}
 739
 740	return ret;
 741}
 742#else
 743static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
 744{
 745	return 0;
 746}
 747#endif
 748
 749static int bq24190_set_config(struct bq24190_dev_info *bdi)
 750{
 751	int ret;
 752	u8 v;
 753
 754	ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
 755	if (ret < 0)
 756		return ret;
 757
 758	bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
 759					BQ24190_REG_CTTC_WATCHDOG_SHIFT);
 760
 761	/*
 762	 * According to the "Host Mode and default Mode" section of the
 763	 * manual, a write to any register causes the bq24190 to switch
 764	 * from default mode to host mode.  It will switch back to default
 765	 * mode after a WDT timeout unless the WDT is turned off as well.
 766	 * So, by simply turning off the WDT, we accomplish both with the
 767	 * same write.
 768	 */
 769	v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
 770
 771	ret = bq24190_write(bdi, BQ24190_REG_CTTC, v);
 772	if (ret < 0)
 773		return ret;
 774
 775	if (bdi->sys_min) {
 776		v = bdi->sys_min / 100 - 30; // manual section 9.5.1.2, table 9
 777		ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 778					 BQ24190_REG_POC_SYS_MIN_MASK,
 779					 BQ24190_REG_POC_SYS_MIN_SHIFT,
 780					 v);
 781		if (ret < 0)
 782			return ret;
 783	}
 784
 785	if (bdi->iprechg) {
 786		v = bdi->iprechg / 128 - 1; // manual section 9.5.1.4, table 11
 787		ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
 788					 BQ24190_REG_PCTCC_IPRECHG_MASK,
 789					 BQ24190_REG_PCTCC_IPRECHG_SHIFT,
 790					 v);
 791		if (ret < 0)
 792			return ret;
 793	}
 794
 795	if (bdi->iterm) {
 796		v = bdi->iterm / 128 - 1; // manual section 9.5.1.4, table 11
 797		ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
 798					 BQ24190_REG_PCTCC_ITERM_MASK,
 799					 BQ24190_REG_PCTCC_ITERM_SHIFT,
 800					 v);
 801		if (ret < 0)
 802			return ret;
 803	}
 804
 805	if (bdi->ichg) {
 806		ret = bq24190_set_field_val(bdi, BQ24190_REG_CCC,
 807					    BQ24190_REG_CCC_ICHG_MASK,
 808					    BQ24190_REG_CCC_ICHG_SHIFT,
 809					    bq24190_ccc_ichg_values,
 810					    bdi->info->ichg_array_size,
 811					    bdi->ichg);
 812		if (ret < 0)
 813			return ret;
 814	}
 815
 816	if (bdi->vreg) {
 817		ret = bq24190_set_field_val(bdi, BQ24190_REG_CVC,
 818					    BQ24190_REG_CVC_VREG_MASK,
 819					    BQ24190_REG_CVC_VREG_SHIFT,
 820					    bq24190_cvc_vreg_values,
 821					    ARRAY_SIZE(bq24190_cvc_vreg_values),
 822					    bdi->vreg);
 823		if (ret < 0)
 824			return ret;
 825	}
 826
 827	return 0;
 828}
 829
 830static int bq24190_register_reset(struct bq24190_dev_info *bdi)
 831{
 832	int ret, limit = 100;
 833	u8 v;
 834
 835	/*
 836	 * This prop. can be passed on device instantiation from platform code:
 837	 * struct property_entry pe[] =
 838	 *   { PROPERTY_ENTRY_BOOL("disable-reset"), ... };
 839	 * struct i2c_board_info bi =
 840	 *   { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
 841	 * struct i2c_adapter ad = { ... };
 842	 * i2c_add_adapter(&ad);
 843	 * i2c_new_client_device(&ad, &bi);
 844	 */
 845	if (device_property_read_bool(bdi->dev, "disable-reset"))
 846		return 0;
 847
 848	/* Reset the registers */
 849	ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 850			BQ24190_REG_POC_RESET_MASK,
 851			BQ24190_REG_POC_RESET_SHIFT,
 852			0x1);
 853	if (ret < 0)
 854		return ret;
 855
 856	/* Reset bit will be cleared by hardware so poll until it is */
 857	do {
 858		ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 859				BQ24190_REG_POC_RESET_MASK,
 860				BQ24190_REG_POC_RESET_SHIFT,
 861				&v);
 862		if (ret < 0)
 863			return ret;
 864
 865		if (v == 0)
 866			return 0;
 867
 868		usleep_range(100, 200);
 869	} while (--limit);
 870
 871	return -EIO;
 872}
 873
 874/* Charger power supply property routines */
 875
 876static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
 877		union power_supply_propval *val)
 878{
 879	u8 v;
 880	int type, ret;
 881
 882	ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 883			BQ24190_REG_POC_CHG_CONFIG_MASK,
 884			BQ24190_REG_POC_CHG_CONFIG_SHIFT,
 885			&v);
 886	if (ret < 0)
 887		return ret;
 888
 889	/* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
 890	if (!v) {
 891		type = POWER_SUPPLY_CHARGE_TYPE_NONE;
 892	} else {
 893		ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 894				BQ24190_REG_CCC_FORCE_20PCT_MASK,
 895				BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 896				&v);
 897		if (ret < 0)
 898			return ret;
 899
 900		type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
 901			     POWER_SUPPLY_CHARGE_TYPE_FAST;
 902	}
 903
 904	val->intval = type;
 905
 906	return 0;
 907}
 908
 909static int bq24190_battery_set_chg_config(struct bq24190_dev_info *bdi,
 910		const u8 chg_config)
 911{
 912	return bq24190_write_mask(bdi, BQ24190_REG_POC,
 913			BQ24190_REG_POC_CHG_CONFIG_MASK,
 914			BQ24190_REG_POC_CHG_CONFIG_SHIFT,
 915			chg_config);
 916}
 917
 918static int bq24296_battery_set_chg_config(struct bq24190_dev_info *bdi,
 919		const u8 chg_config)
 920{
 921	return bq24190_write_mask(bdi, BQ24190_REG_POC,
 922			BQ24296_REG_POC_CHG_CONFIG_MASK,
 923			BQ24296_REG_POC_CHG_CONFIG_SHIFT,
 924			chg_config);
 925}
 926
 927static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
 928		const union power_supply_propval *val)
 929{
 930	u8 chg_config, force_20pct, en_term;
 931	int ret;
 932
 933	/*
 934	 * According to the "Termination when REG02[0] = 1" section of
 935	 * the bq24190 manual, the trickle charge could be less than the
 936	 * termination current so it recommends turning off the termination
 937	 * function.
 938	 *
 939	 * Note: AFAICT from the datasheet, the user will have to manually
 940	 * turn off the charging when in 20% mode.  If its not turned off,
 941	 * there could be battery damage.  So, use this mode at your own risk.
 942	 */
 943	switch (val->intval) {
 944	case POWER_SUPPLY_CHARGE_TYPE_NONE:
 945		chg_config = 0x0;
 946		break;
 947	case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
 948		chg_config = 0x1;
 949		force_20pct = 0x1;
 950		en_term = 0x0;
 951		break;
 952	case POWER_SUPPLY_CHARGE_TYPE_FAST:
 953		chg_config = 0x1;
 954		force_20pct = 0x0;
 955		en_term = 0x1;
 956		break;
 957	default:
 958		return -EINVAL;
 959	}
 960
 961	bdi->charge_type = val->intval;
 962	/*
 963	 * If the 5V Vbus boost regulator is enabled delay setting
 964	 * the charge-type until its gets disabled.
 965	 */
 966	if (bdi->otg_vbus_enabled)
 967		return 0;
 968
 969	if (chg_config) { /* Enabling the charger */
 970		ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
 971				BQ24190_REG_CCC_FORCE_20PCT_MASK,
 972				BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 973				force_20pct);
 974		if (ret < 0)
 975			return ret;
 976
 977		ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
 978				BQ24190_REG_CTTC_EN_TERM_MASK,
 979				BQ24190_REG_CTTC_EN_TERM_SHIFT,
 980				en_term);
 981		if (ret < 0)
 982			return ret;
 983	}
 984
 985	return bdi->info->set_chg_config(bdi, chg_config);
 986}
 987
 988static int bq24190_charger_get_ntc_status(u8 value)
 989{
 990	int health;
 991
 992	switch (value >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
 993	case 0x1: /* TS1  Cold */
 994	case 0x3: /* TS2  Cold */
 995	case 0x5: /* Both Cold */
 996		health = POWER_SUPPLY_HEALTH_COLD;
 997		break;
 998	case 0x2: /* TS1  Hot */
 999	case 0x4: /* TS2  Hot */
1000	case 0x6: /* Both Hot */
1001		health = POWER_SUPPLY_HEALTH_OVERHEAT;
1002		break;
1003	default:
1004		health = POWER_SUPPLY_HEALTH_UNKNOWN;
1005	}
1006
1007	return health;
1008}
1009
1010static int bq24296_charger_get_ntc_status(u8 value)
1011{
1012	int health;
1013
1014	switch (value >> BQ24296_REG_F_NTC_FAULT_SHIFT & 0x3) {
1015	case 0x0: /* Normal */
1016		health = POWER_SUPPLY_HEALTH_GOOD;
1017		break;
1018	case 0x1: /* Hot */
1019		health = POWER_SUPPLY_HEALTH_OVERHEAT;
1020		break;
1021	case 0x2: /* Cold */
1022		health = POWER_SUPPLY_HEALTH_COLD;
1023		break;
1024	default:
1025		health = POWER_SUPPLY_HEALTH_UNKNOWN;
1026	}
1027
1028	return health;
1029}
1030
1031static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
1032		union power_supply_propval *val)
1033{
1034	u8 v;
1035	int health;
1036
1037	mutex_lock(&bdi->f_reg_lock);
1038	v = bdi->f_reg;
1039	mutex_unlock(&bdi->f_reg_lock);
1040
1041	if (v & bdi->info->ntc_fault_mask) {
1042		health = bdi->info->get_ntc_status(v);
1043	} else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1044		health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1045	} else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
1046		switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
1047		case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
1048			/*
1049			 * This could be over-voltage or under-voltage
1050			 * and there's no way to tell which.  Instead
1051			 * of looking foolish and returning 'OVERVOLTAGE'
1052			 * when its really under-voltage, just return
1053			 * 'UNSPEC_FAILURE'.
1054			 */
1055			health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
1056			break;
1057		case 0x2: /* Thermal Shutdown */
1058			health = POWER_SUPPLY_HEALTH_OVERHEAT;
1059			break;
1060		case 0x3: /* Charge Safety Timer Expiration */
1061			health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
1062			break;
1063		default:  /* prevent compiler warning */
1064			health = -1;
1065		}
1066	} else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
1067		/*
1068		 * This could be over-current or over-voltage but there's
1069		 * no way to tell which.  Return 'OVERVOLTAGE' since there
1070		 * isn't an 'OVERCURRENT' value defined that we can return
1071		 * even if it was over-current.
1072		 */
1073		health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1074	} else {
1075		health = POWER_SUPPLY_HEALTH_GOOD;
1076	}
1077
1078	val->intval = health;
1079
1080	return 0;
1081}
1082
1083static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
1084		union power_supply_propval *val)
1085{
1086	u8 pg_stat, batfet_disable;
1087	int ret;
1088
1089	ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
1090			BQ24190_REG_SS_PG_STAT_MASK,
1091			BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat);
1092	if (ret < 0)
1093		return ret;
1094
1095	ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1096			BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1097			BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1098	if (ret < 0)
1099		return ret;
1100
1101	val->intval = pg_stat && !batfet_disable;
1102
1103	return 0;
1104}
1105
1106static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1107				      const union power_supply_propval *val);
1108static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1109				      union power_supply_propval *val);
1110static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1111					      union power_supply_propval *val);
1112static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1113					      const union power_supply_propval *val);
1114
1115static int bq24190_charger_set_online(struct bq24190_dev_info *bdi,
1116				      const union power_supply_propval *val)
1117{
1118	return bq24190_battery_set_online(bdi, val);
1119}
1120
1121static int bq24190_charger_get_status(struct bq24190_dev_info *bdi,
1122				      union power_supply_propval *val)
1123{
1124	return bq24190_battery_get_status(bdi, val);
1125}
1126
1127static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi,
1128					      union power_supply_propval *val)
1129{
1130	return bq24190_battery_get_temp_alert_max(bdi, val);
1131}
1132
1133static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi,
1134					      const union power_supply_propval *val)
1135{
1136	return bq24190_battery_set_temp_alert_max(bdi, val);
1137}
1138
1139static int bq24190_charger_get_precharge(struct bq24190_dev_info *bdi,
1140		union power_supply_propval *val)
1141{
1142	u8 v;
1143	int curr, ret;
1144
1145	ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
1146			BQ24190_REG_PCTCC_IPRECHG_MASK,
1147			BQ24190_REG_PCTCC_IPRECHG_SHIFT, &v);
1148	if (ret < 0)
1149		return ret;
1150
1151	curr = ++v * 128 * 1000;
1152
1153	ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1154			BQ24190_REG_CCC_FORCE_20PCT_MASK,
1155			BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1156	if (ret < 0)
1157		return ret;
1158
1159	/* If FORCE_20PCT is enabled, then current is 50% of IPRECHG value */
1160	if (v)
1161		curr /= 2;
1162
1163	val->intval = curr;
1164
1165	return 0;
1166}
1167
1168static int bq24190_charger_get_charge_term(struct bq24190_dev_info *bdi,
1169		union power_supply_propval *val)
1170{
1171	u8 v;
1172	int ret;
1173
1174	ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
1175			BQ24190_REG_PCTCC_ITERM_MASK,
1176			BQ24190_REG_PCTCC_ITERM_SHIFT, &v);
1177	if (ret < 0)
1178		return ret;
1179
1180	val->intval = ++v * 128 * 1000;
1181	return 0;
1182}
1183
1184static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
1185		union power_supply_propval *val)
1186{
1187	u8 v;
1188	int curr, ret;
1189
1190	ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
1191			BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1192			bq24190_ccc_ichg_values,
1193			bdi->info->ichg_array_size, &curr);
1194	if (ret < 0)
1195		return ret;
1196
1197	ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1198			BQ24190_REG_CCC_FORCE_20PCT_MASK,
1199			BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1200	if (ret < 0)
1201		return ret;
1202
1203	/* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
1204	if (v)
1205		curr /= 5;
1206
1207	val->intval = curr;
1208	return 0;
1209}
1210
1211static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
1212		const union power_supply_propval *val)
1213{
1214	u8 v;
1215	int ret, curr = val->intval;
1216
1217	ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1218			BQ24190_REG_CCC_FORCE_20PCT_MASK,
1219			BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1220	if (ret < 0)
1221		return ret;
1222
1223	/* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
1224	if (v)
1225		curr *= 5;
1226
1227	if (curr > bdi->ichg_max)
1228		return -EINVAL;
1229
1230	ret = bq24190_set_field_val(bdi, BQ24190_REG_CCC,
1231			BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1232			bq24190_ccc_ichg_values,
1233			bdi->info->ichg_array_size, curr);
1234	if (ret < 0)
1235		return ret;
1236
1237	bdi->ichg = curr;
1238
1239	return 0;
1240}
1241
1242static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
1243		union power_supply_propval *val)
1244{
1245	int voltage, ret;
1246
1247	ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
1248			BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1249			bq24190_cvc_vreg_values,
1250			ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
1251	if (ret < 0)
1252		return ret;
1253
1254	val->intval = voltage;
1255	return 0;
1256}
1257
1258static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
1259		const union power_supply_propval *val)
1260{
1261	int ret;
1262
1263	if (val->intval > bdi->vreg_max)
1264		return -EINVAL;
1265
1266	ret = bq24190_set_field_val(bdi, BQ24190_REG_CVC,
1267			BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1268			bq24190_cvc_vreg_values,
1269			ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
1270	if (ret < 0)
1271		return ret;
1272
1273	bdi->vreg = val->intval;
1274
1275	return 0;
1276}
1277
1278static int bq24190_charger_get_iinlimit(struct bq24190_dev_info *bdi,
1279		union power_supply_propval *val)
1280{
1281	int iinlimit, ret;
1282
1283	ret = bq24190_get_field_val(bdi, BQ24190_REG_ISC,
1284			BQ24190_REG_ISC_IINLIM_MASK,
1285			BQ24190_REG_ISC_IINLIM_SHIFT,
1286			bq24190_isc_iinlim_values,
1287			ARRAY_SIZE(bq24190_isc_iinlim_values), &iinlimit);
1288	if (ret < 0)
1289		return ret;
1290
1291	val->intval = iinlimit;
1292	return 0;
1293}
1294
1295static int bq24190_charger_set_iinlimit(struct bq24190_dev_info *bdi,
1296		const union power_supply_propval *val)
1297{
1298	return bq24190_set_field_val(bdi, BQ24190_REG_ISC,
1299			BQ24190_REG_ISC_IINLIM_MASK,
1300			BQ24190_REG_ISC_IINLIM_SHIFT,
1301			bq24190_isc_iinlim_values,
1302			ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval);
1303}
1304
1305static int bq24190_charger_get_property(struct power_supply *psy,
1306		enum power_supply_property psp, union power_supply_propval *val)
1307{
1308	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1309	int ret;
1310
1311	dev_dbg(bdi->dev, "prop: %d\n", psp);
1312
1313	ret = pm_runtime_resume_and_get(bdi->dev);
1314	if (ret < 0)
1315		return ret;
1316
1317	switch (psp) {
1318	case POWER_SUPPLY_PROP_CHARGE_TYPE:
1319	case POWER_SUPPLY_PROP_CHARGE_TYPES:
1320		ret = bq24190_charger_get_charge_type(bdi, val);
1321		break;
1322	case POWER_SUPPLY_PROP_HEALTH:
1323		ret = bq24190_charger_get_health(bdi, val);
1324		break;
1325	case POWER_SUPPLY_PROP_ONLINE:
1326		ret = bq24190_charger_get_online(bdi, val);
1327		break;
1328	case POWER_SUPPLY_PROP_STATUS:
1329		ret = bq24190_charger_get_status(bdi, val);
1330		break;
1331	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1332		ret =  bq24190_charger_get_temp_alert_max(bdi, val);
1333		break;
1334	case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
1335		ret = bq24190_charger_get_precharge(bdi, val);
1336		break;
1337	case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
1338		ret = bq24190_charger_get_charge_term(bdi, val);
1339		break;
1340	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1341		ret = bq24190_charger_get_current(bdi, val);
1342		break;
1343	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
1344		val->intval = bdi->ichg_max;
1345		ret = 0;
1346		break;
1347	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1348		ret = bq24190_charger_get_voltage(bdi, val);
1349		break;
1350	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
1351		val->intval = bdi->vreg_max;
1352		ret = 0;
1353		break;
1354	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1355		ret = bq24190_charger_get_iinlimit(bdi, val);
1356		break;
1357	case POWER_SUPPLY_PROP_SCOPE:
1358		val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1359		ret = 0;
1360		break;
1361	case POWER_SUPPLY_PROP_MODEL_NAME:
1362		val->strval = bdi->model_name;
1363		ret = 0;
1364		break;
1365	case POWER_SUPPLY_PROP_MANUFACTURER:
1366		val->strval = BQ24190_MANUFACTURER;
1367		ret = 0;
1368		break;
1369	default:
1370		ret = -ENODATA;
1371	}
1372
1373	pm_runtime_put_autosuspend(bdi->dev);
1374
1375	return ret;
1376}
1377
1378static int bq24190_charger_set_property(struct power_supply *psy,
1379		enum power_supply_property psp,
1380		const union power_supply_propval *val)
1381{
1382	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1383	int ret;
1384
1385	dev_dbg(bdi->dev, "prop: %d\n", psp);
1386
1387	ret = pm_runtime_resume_and_get(bdi->dev);
1388	if (ret < 0)
1389		return ret;
1390
1391	switch (psp) {
1392	case POWER_SUPPLY_PROP_ONLINE:
1393		ret = bq24190_charger_set_online(bdi, val);
1394		break;
1395	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1396		ret = bq24190_charger_set_temp_alert_max(bdi, val);
1397		break;
1398	case POWER_SUPPLY_PROP_CHARGE_TYPE:
1399	case POWER_SUPPLY_PROP_CHARGE_TYPES:
1400		ret = bq24190_charger_set_charge_type(bdi, val);
1401		break;
1402	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1403		ret = bq24190_charger_set_current(bdi, val);
1404		break;
1405	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1406		ret = bq24190_charger_set_voltage(bdi, val);
1407		break;
1408	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1409		ret = bq24190_charger_set_iinlimit(bdi, val);
1410		break;
1411	default:
1412		ret = -EINVAL;
1413	}
1414
1415	pm_runtime_put_autosuspend(bdi->dev);
1416
1417	return ret;
1418}
1419
1420static int bq24190_charger_property_is_writeable(struct power_supply *psy,
1421		enum power_supply_property psp)
1422{
1423	switch (psp) {
1424	case POWER_SUPPLY_PROP_ONLINE:
1425	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1426	case POWER_SUPPLY_PROP_CHARGE_TYPE:
1427	case POWER_SUPPLY_PROP_CHARGE_TYPES:
1428	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1429	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1430	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1431		return 1;
1432	default:
1433		return 0;
1434	}
1435}
1436
1437static void bq24190_input_current_limit_work(struct work_struct *work)
1438{
1439	struct bq24190_dev_info *bdi =
1440		container_of(work, struct bq24190_dev_info,
1441			     input_current_limit_work.work);
1442	union power_supply_propval val;
1443	int ret;
1444
1445	ret = power_supply_get_property_from_supplier(bdi->charger,
1446						      POWER_SUPPLY_PROP_CURRENT_MAX,
1447						      &val);
1448	if (ret)
1449		return;
1450
1451	bq24190_charger_set_property(bdi->charger,
1452				     POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1453				     &val);
1454	power_supply_changed(bdi->charger);
1455}
1456
1457/* Sync the input-current-limit with our parent supply (if we have one) */
1458static void bq24190_charger_external_power_changed(struct power_supply *psy)
1459{
1460	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1461
1462	/*
1463	 * The Power-Good detection may take up to 220ms, sometimes
1464	 * the external charger detection is quicker, and the bq24190 will
1465	 * reset to iinlim based on its own charger detection (which is not
1466	 * hooked up when using external charger detection) resulting in a
1467	 * too low default 500mA iinlim. Delay setting the input-current-limit
1468	 * for 300ms to avoid this.
1469	 */
1470	queue_delayed_work(system_percpu_wq, &bdi->input_current_limit_work,
1471			   msecs_to_jiffies(300));
1472}
1473
1474static enum power_supply_property bq24190_charger_properties[] = {
1475	POWER_SUPPLY_PROP_CHARGE_TYPE,
1476	POWER_SUPPLY_PROP_CHARGE_TYPES,
1477	POWER_SUPPLY_PROP_HEALTH,
1478	POWER_SUPPLY_PROP_ONLINE,
1479	POWER_SUPPLY_PROP_STATUS,
1480	POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1481	POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
1482	POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
1483	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
1484	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
1485	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
1486	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
1487	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1488	POWER_SUPPLY_PROP_SCOPE,
1489	POWER_SUPPLY_PROP_MODEL_NAME,
1490	POWER_SUPPLY_PROP_MANUFACTURER,
1491};
1492
1493static char *bq24190_charger_supplied_to[] = {
1494	"main-battery",
1495};
1496
1497static const struct power_supply_desc bq24190_charger_desc = {
1498	.name			= "bq24190-charger",
1499	.type			= POWER_SUPPLY_TYPE_USB,
1500	.properties		= bq24190_charger_properties,
1501	.num_properties		= ARRAY_SIZE(bq24190_charger_properties),
1502	.get_property		= bq24190_charger_get_property,
1503	.set_property		= bq24190_charger_set_property,
1504	.property_is_writeable	= bq24190_charger_property_is_writeable,
1505	.external_power_changed	= bq24190_charger_external_power_changed,
1506	.charge_types		= BIT(POWER_SUPPLY_CHARGE_TYPE_NONE)    |
1507				  BIT(POWER_SUPPLY_CHARGE_TYPE_TRICKLE) |
1508				  BIT(POWER_SUPPLY_CHARGE_TYPE_FAST),
1509};
1510
1511/* Battery power supply property routines */
1512
1513static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1514		union power_supply_propval *val)
1515{
1516	u8 ss_reg, chrg_fault;
1517	int status, ret;
1518
1519	mutex_lock(&bdi->f_reg_lock);
1520	chrg_fault = bdi->f_reg;
1521	mutex_unlock(&bdi->f_reg_lock);
1522
1523	chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
1524	chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
1525
1526	ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1527	if (ret < 0)
1528		return ret;
1529
1530	/*
1531	 * The battery must be discharging when any of these are true:
1532	 * - there is no good power source;
1533	 * - there is a charge fault.
1534	 * Could also be discharging when in "supplement mode" but
1535	 * there is no way to tell when its in that mode.
1536	 */
1537	if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
1538		status = POWER_SUPPLY_STATUS_DISCHARGING;
1539	} else {
1540		ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
1541		ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
1542
1543		switch (ss_reg) {
1544		case 0x0: /* Not Charging */
1545			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1546			break;
1547		case 0x1: /* Pre-charge */
1548		case 0x2: /* Fast Charging */
1549			status = POWER_SUPPLY_STATUS_CHARGING;
1550			break;
1551		case 0x3: /* Charge Termination Done */
1552			status = POWER_SUPPLY_STATUS_FULL;
1553			break;
1554		default:
1555			ret = -EIO;
1556		}
1557	}
1558
1559	if (!ret)
1560		val->intval = status;
1561
1562	return ret;
1563}
1564
1565static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1566		union power_supply_propval *val)
1567{
1568	u8 v;
1569	int health;
1570
1571	mutex_lock(&bdi->f_reg_lock);
1572	v = bdi->f_reg;
1573	mutex_unlock(&bdi->f_reg_lock);
1574
1575	if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1576		health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1577	} else {
1578		v &= bdi->info->ntc_fault_mask;
1579
1580		health = v ? bdi->info->get_ntc_status(v) : POWER_SUPPLY_HEALTH_GOOD;
1581	}
1582
1583	val->intval = health;
1584	return 0;
1585}
1586
1587static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1588		union power_supply_propval *val)
1589{
1590	u8 batfet_disable;
1591	int ret;
1592
1593	ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1594			BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1595			BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1596	if (ret < 0)
1597		return ret;
1598
1599	val->intval = !batfet_disable;
1600	return 0;
1601}
1602
1603static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1604		const union power_supply_propval *val)
1605{
1606	return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1607			BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1608			BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1609}
1610
1611static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1612		union power_supply_propval *val)
1613{
1614	int temp, ret;
1615
1616	ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1617			BQ24190_REG_ICTRC_TREG_MASK,
1618			BQ24190_REG_ICTRC_TREG_SHIFT,
1619			bq24190_ictrc_treg_values,
1620			ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1621	if (ret < 0)
1622		return ret;
1623
1624	val->intval = temp;
1625	return 0;
1626}
1627
1628static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1629		const union power_supply_propval *val)
1630{
1631	return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1632			BQ24190_REG_ICTRC_TREG_MASK,
1633			BQ24190_REG_ICTRC_TREG_SHIFT,
1634			bq24190_ictrc_treg_values,
1635			ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1636}
1637
1638static int bq24190_battery_get_property(struct power_supply *psy,
1639		enum power_supply_property psp, union power_supply_propval *val)
1640{
1641	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1642	int ret;
1643
1644	dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1645	dev_dbg(bdi->dev, "prop: %d\n", psp);
1646
1647	ret = pm_runtime_resume_and_get(bdi->dev);
1648	if (ret < 0)
1649		return ret;
1650
1651	switch (psp) {
1652	case POWER_SUPPLY_PROP_STATUS:
1653		ret = bq24190_battery_get_status(bdi, val);
1654		break;
1655	case POWER_SUPPLY_PROP_HEALTH:
1656		ret = bq24190_battery_get_health(bdi, val);
1657		break;
1658	case POWER_SUPPLY_PROP_ONLINE:
1659		ret = bq24190_battery_get_online(bdi, val);
1660		break;
1661	case POWER_SUPPLY_PROP_TECHNOLOGY:
1662		/* Could be Li-on or Li-polymer but no way to tell which */
1663		val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1664		ret = 0;
1665		break;
1666	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1667		ret = bq24190_battery_get_temp_alert_max(bdi, val);
1668		break;
1669	case POWER_SUPPLY_PROP_SCOPE:
1670		val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1671		ret = 0;
1672		break;
1673	default:
1674		ret = -ENODATA;
1675	}
1676
1677	pm_runtime_put_autosuspend(bdi->dev);
1678
1679	return ret;
1680}
1681
1682static int bq24190_battery_set_property(struct power_supply *psy,
1683		enum power_supply_property psp,
1684		const union power_supply_propval *val)
1685{
1686	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1687	int ret;
1688
1689	dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1690	dev_dbg(bdi->dev, "prop: %d\n", psp);
1691
1692	ret = pm_runtime_resume_and_get(bdi->dev);
1693	if (ret < 0)
1694		return ret;
1695
1696	switch (psp) {
1697	case POWER_SUPPLY_PROP_ONLINE:
1698		ret = bq24190_battery_set_online(bdi, val);
1699		break;
1700	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1701		ret = bq24190_battery_set_temp_alert_max(bdi, val);
1702		break;
1703	default:
1704		ret = -EINVAL;
1705	}
1706
1707	pm_runtime_put_autosuspend(bdi->dev);
1708
1709	return ret;
1710}
1711
1712static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1713		enum power_supply_property psp)
1714{
1715	int ret;
1716
1717	switch (psp) {
1718	case POWER_SUPPLY_PROP_ONLINE:
1719	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1720		ret = 1;
1721		break;
1722	default:
1723		ret = 0;
1724	}
1725
1726	return ret;
1727}
1728
1729static enum power_supply_property bq24190_battery_properties[] = {
1730	POWER_SUPPLY_PROP_STATUS,
1731	POWER_SUPPLY_PROP_HEALTH,
1732	POWER_SUPPLY_PROP_ONLINE,
1733	POWER_SUPPLY_PROP_TECHNOLOGY,
1734	POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1735	POWER_SUPPLY_PROP_SCOPE,
1736};
1737
1738static const struct power_supply_desc bq24190_battery_desc = {
1739	.name			= "bq24190-battery",
1740	.type			= POWER_SUPPLY_TYPE_BATTERY,
1741	.properties		= bq24190_battery_properties,
1742	.num_properties		= ARRAY_SIZE(bq24190_battery_properties),
1743	.get_property		= bq24190_battery_get_property,
1744	.set_property		= bq24190_battery_set_property,
1745	.property_is_writeable	= bq24190_battery_property_is_writeable,
1746};
1747
1748static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
1749{
1750	bool otg_enabled;
1751	int ret;
1752
1753	otg_enabled = !!(ss_reg & BQ24190_REG_SS_VBUS_STAT_MASK);
1754	ret = extcon_set_state_sync(bdi->edev, EXTCON_USB, otg_enabled);
1755	if (ret < 0)
1756		dev_err(bdi->dev, "Can't set extcon state to %d: %d\n",
1757			otg_enabled, ret);
1758
1759	return ret;
1760}
1761
1762static void bq24190_check_status(struct bq24190_dev_info *bdi)
1763{
1764	const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1765	u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK;
1766	bool alert_charger = false, alert_battery = false;
1767	u8 ss_reg = 0, f_reg = 0;
1768	int i, ret;
1769
1770	battery_mask_f |= bdi->info->ntc_fault_mask;
1771
1772	ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1773	if (ret < 0) {
1774		dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1775		return;
1776	}
1777
1778	i = 0;
1779	do {
1780		ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1781		if (ret < 0) {
1782			dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1783			return;
1784		}
1785	} while (f_reg && ++i < 2);
1786
1787	/* ignore over/under voltage fault after disconnect */
1788	if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1789	    !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1790		f_reg = 0;
1791
1792	if (f_reg != bdi->f_reg) {
1793		dev_warn(bdi->dev,
1794			"Fault: boost %d, charge %d, battery %d, ntc %d\n",
1795			!!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1796			!!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1797			!!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1798			!!(f_reg & bdi->info->ntc_fault_mask));
1799
1800		mutex_lock(&bdi->f_reg_lock);
1801		if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1802			alert_battery = true;
1803		if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1804			alert_charger = true;
1805		bdi->f_reg = f_reg;
1806		mutex_unlock(&bdi->f_reg_lock);
1807	}
1808
1809	if (ss_reg != bdi->ss_reg) {
1810		/*
1811		 * The device is in host mode so when PG_STAT goes from 1->0
1812		 * (i.e., power removed) HIZ needs to be disabled.
1813		 */
1814		if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1815				!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1816			ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1817					BQ24190_REG_ISC_EN_HIZ_MASK,
1818					BQ24190_REG_ISC_EN_HIZ_SHIFT,
1819					0);
1820			if (ret < 0)
1821				dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1822					ret);
1823		}
1824
1825		if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1826			alert_battery = true;
1827		if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1828			alert_charger = true;
1829		bdi->ss_reg = ss_reg;
1830	}
1831
1832	if (alert_charger || alert_battery) {
1833		power_supply_changed(bdi->charger);
1834		bq24190_configure_usb_otg(bdi, ss_reg);
1835	}
1836	if (alert_battery && bdi->battery)
1837		power_supply_changed(bdi->battery);
1838
1839	dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1840}
1841
1842static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1843{
1844	struct bq24190_dev_info *bdi = data;
1845	int error;
1846
1847	bdi->irq_event = true;
1848	error = pm_runtime_resume_and_get(bdi->dev);
1849	if (error < 0) {
1850		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1851		return IRQ_NONE;
1852	}
1853	bq24190_check_status(bdi);
1854	pm_runtime_put_autosuspend(bdi->dev);
1855	bdi->irq_event = false;
1856
1857	return IRQ_HANDLED;
1858}
1859
1860static int bq24190_check_chip(struct bq24190_dev_info *bdi)
1861{
1862	u8 v;
1863	int ret;
1864
1865	ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1866			BQ24190_REG_VPRS_PN_MASK,
1867			BQ24190_REG_VPRS_PN_SHIFT,
1868			&v);
1869	if (ret < 0)
1870		return ret;
1871
1872	switch (v) {
1873	case BQ24190_REG_VPRS_PN_24190:
1874	case BQ24190_REG_VPRS_PN_24192:
1875	case BQ24190_REG_VPRS_PN_24192I:
1876		break;
1877	default:
1878		dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1879		return -ENODEV;
1880	}
1881
1882	return 0;
1883}
1884
1885static int bq24296_check_chip(struct bq24190_dev_info *bdi)
1886{
1887	u8 v;
1888	int ret;
1889
1890	ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1891			BQ24296_REG_VPRS_PN_MASK,
1892			BQ24296_REG_VPRS_PN_SHIFT,
1893			&v);
1894	if (ret < 0)
1895		return ret;
1896
1897	switch (v) {
1898	case BQ24296_REG_VPRS_PN_24296:
1899	case BQ24296_REG_VPRS_PN_24297:
1900		break;
1901	default:
1902		dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1903		return -ENODEV;
1904	}
1905
1906	return 0;
1907}
1908
1909static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1910{
1911	int ret;
1912
1913	ret = bdi->info->check_chip(bdi);
1914	if (ret < 0)
1915		return ret;
1916
1917	ret = bq24190_register_reset(bdi);
1918	if (ret < 0)
1919		return ret;
1920
1921	ret = bq24190_set_config(bdi);
1922	if (ret < 0)
1923		return ret;
1924
1925	return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1926}
1927
1928static int bq24190_get_config(struct bq24190_dev_info *bdi)
1929{
1930	const char * const s = "ti,system-minimum-microvolt";
1931	struct power_supply_battery_info *info;
1932	int v, idx;
1933
1934	idx = bdi->info->ichg_array_size - 1;
1935
1936	bdi->ichg_max = bq24190_ccc_ichg_values[idx];
1937
1938	idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
1939	bdi->vreg_max = bq24190_cvc_vreg_values[idx];
1940
1941	if (device_property_read_u32(bdi->dev, s, &v) == 0) {
1942		v /= 1000;
1943		if (v >= BQ24190_REG_POC_SYS_MIN_MIN
1944		 && v <= BQ24190_REG_POC_SYS_MIN_MAX)
1945			bdi->sys_min = v;
1946		else
1947			dev_warn(bdi->dev, "invalid value for %s: %u\n", s, v);
1948	}
1949
1950	if (!power_supply_get_battery_info(bdi->charger, &info)) {
1951		v = info->precharge_current_ua / 1000;
1952		if (v >= BQ24190_REG_PCTCC_IPRECHG_MIN
1953		 && v <= BQ24190_REG_PCTCC_IPRECHG_MAX)
1954			bdi->iprechg = v;
1955		else
1956			dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n",
1957				 v);
1958
1959		v = info->charge_term_current_ua / 1000;
1960		if (v >= BQ24190_REG_PCTCC_ITERM_MIN
1961		 && v <= BQ24190_REG_PCTCC_ITERM_MAX)
1962			bdi->iterm = v;
1963		else
1964			dev_warn(bdi->dev, "invalid value for battery:charge-term-current-microamp: %d\n",
1965				 v);
1966
1967		/* These are optional, so no warning when not set */
1968		v = info->constant_charge_current_max_ua;
1969		if (v >= bq24190_ccc_ichg_values[0] && v <= bdi->ichg_max)
1970			bdi->ichg = bdi->ichg_max = v;
1971
1972		v = info->constant_charge_voltage_max_uv;
1973		if (v >= bq24190_cvc_vreg_values[0] && v <= bdi->vreg_max)
1974			bdi->vreg = bdi->vreg_max = v;
1975
1976		power_supply_put_battery_info(bdi->charger, info);
1977	}
1978
1979	return 0;
1980}
1981
1982static const struct bq24190_chip_info bq24190_chip_info_tbl[] = {
1983	[BQ24190] = {
1984		.ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
1985#ifdef CONFIG_REGULATOR
1986		.vbus_desc = &bq24190_vbus_desc,
1987#endif
1988		.check_chip = bq24190_check_chip,
1989		.set_chg_config = bq24190_battery_set_chg_config,
1990		.ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
1991		.get_ntc_status = bq24190_charger_get_ntc_status,
1992		.set_otg_vbus = bq24190_set_otg_vbus,
1993	},
1994	[BQ24192] = {
1995		.ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
1996#ifdef CONFIG_REGULATOR
1997		.vbus_desc = &bq24190_vbus_desc,
1998#endif
1999		.check_chip = bq24190_check_chip,
2000		.set_chg_config = bq24190_battery_set_chg_config,
2001		.ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
2002		.get_ntc_status = bq24190_charger_get_ntc_status,
2003		.set_otg_vbus = bq24190_set_otg_vbus,
2004	},
2005	[BQ24192i] = {
2006		.ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
2007#ifdef CONFIG_REGULATOR
2008		.vbus_desc = &bq24190_vbus_desc,
2009#endif
2010		.check_chip = bq24190_check_chip,
2011		.set_chg_config = bq24190_battery_set_chg_config,
2012		.ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
2013		.get_ntc_status = bq24190_charger_get_ntc_status,
2014		.set_otg_vbus = bq24190_set_otg_vbus,
2015	},
2016	[BQ24193] = {
2017		.ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
2018#ifdef CONFIG_REGULATOR
2019		.vbus_desc = &bq24190_vbus_desc,
2020#endif
2021		.check_chip = bq24190_check_chip,
2022		.set_chg_config = bq24190_battery_set_chg_config,
2023		.ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
2024		.get_ntc_status = bq24190_charger_get_ntc_status,
2025		.set_otg_vbus = bq24190_set_otg_vbus,
2026	},
2027	[BQ24196] = {
2028		.ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
2029#ifdef CONFIG_REGULATOR
2030		.vbus_desc = &bq24190_vbus_desc,
2031#endif
2032		.check_chip = bq24190_check_chip,
2033		.set_chg_config = bq24190_battery_set_chg_config,
2034		.ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
2035		.get_ntc_status = bq24190_charger_get_ntc_status,
2036		.set_otg_vbus = bq24190_set_otg_vbus,
2037	},
2038	[BQ24296] = {
2039		.ichg_array_size = BQ24296_CCC_ICHG_VALUES_LEN,
2040#ifdef CONFIG_REGULATOR
2041		.vbus_desc = &bq24296_vbus_desc,
2042#endif
2043		.check_chip = bq24296_check_chip,
2044		.set_chg_config = bq24296_battery_set_chg_config,
2045		.ntc_fault_mask = BQ24296_REG_F_NTC_FAULT_MASK,
2046		.get_ntc_status = bq24296_charger_get_ntc_status,
2047		.set_otg_vbus = bq24296_set_otg_vbus,
2048	},
2049	[BQ24297] = {
2050		.ichg_array_size = BQ24296_CCC_ICHG_VALUES_LEN,
2051#ifdef CONFIG_REGULATOR
2052		.vbus_desc = &bq24296_vbus_desc,
2053#endif
2054		.check_chip = bq24296_check_chip,
2055		.set_chg_config = bq24296_battery_set_chg_config,
2056		.ntc_fault_mask = BQ24296_REG_F_NTC_FAULT_MASK,
2057		.get_ntc_status = bq24296_charger_get_ntc_status,
2058		.set_otg_vbus = bq24296_set_otg_vbus,
2059	},
2060};
2061
2062static int bq24190_probe(struct i2c_client *client)
2063{
2064	const struct i2c_device_id *id = i2c_client_get_device_id(client);
2065	struct i2c_adapter *adapter = client->adapter;
2066	struct device *dev = &client->dev;
2067	struct power_supply_config charger_cfg = {}, battery_cfg = {};
2068	struct bq24190_dev_info *bdi;
2069	int ret;
2070
2071	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
2072		dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
2073		return -ENODEV;
2074	}
2075
2076	bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
2077	if (!bdi) {
2078		dev_err(dev, "Can't alloc bdi struct\n");
2079		return -ENOMEM;
2080	}
2081
2082	bdi->client = client;
2083	bdi->dev = dev;
2084	strscpy(bdi->model_name, id->name, sizeof(bdi->model_name));
2085	bdi->info = i2c_get_match_data(client);
2086	mutex_init(&bdi->f_reg_lock);
2087	bdi->charge_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
2088	bdi->f_reg = 0;
2089	bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
2090	INIT_DELAYED_WORK(&bdi->input_current_limit_work,
2091			  bq24190_input_current_limit_work);
2092
2093	i2c_set_clientdata(client, bdi);
2094
2095	if (client->irq <= 0) {
2096		dev_err(dev, "Can't get irq info\n");
2097		return -EINVAL;
2098	}
2099
2100	bdi->edev = devm_extcon_dev_allocate(dev, bq24190_usb_extcon_cable);
2101	if (IS_ERR(bdi->edev))
2102		return PTR_ERR(bdi->edev);
2103
2104	ret = devm_extcon_dev_register(dev, bdi->edev);
2105	if (ret < 0)
2106		return ret;
2107
2108	pm_runtime_enable(dev);
2109	pm_runtime_use_autosuspend(dev);
2110	pm_runtime_set_autosuspend_delay(dev, 600);
2111	ret = pm_runtime_get_sync(dev);
2112	if (ret < 0) {
2113		dev_err(dev, "pm_runtime_get failed: %i\n", ret);
2114		goto out_pmrt;
2115	}
2116
2117#ifdef CONFIG_SYSFS
2118	bq24190_sysfs_init_attrs();
2119	charger_cfg.attr_grp = bq24190_sysfs_groups;
2120#endif
2121
2122	charger_cfg.drv_data = bdi;
2123	charger_cfg.fwnode = dev_fwnode(dev);
2124	charger_cfg.supplied_to = bq24190_charger_supplied_to;
2125	charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to);
2126	bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
2127						&charger_cfg);
2128	if (IS_ERR(bdi->charger)) {
2129		dev_err(dev, "Can't register charger\n");
2130		ret = PTR_ERR(bdi->charger);
2131		goto out_pmrt;
2132	}
2133
2134	/* the battery class is deprecated and will be removed. */
2135	/* in the interim, this property hides it.              */
2136	if (!device_property_read_bool(dev, "omit-battery-class")) {
2137		battery_cfg.drv_data = bdi;
2138		bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
2139						     &battery_cfg);
2140		if (IS_ERR(bdi->battery)) {
2141			dev_err(dev, "Can't register battery\n");
2142			ret = PTR_ERR(bdi->battery);
2143			goto out_charger;
2144		}
2145	}
2146
2147	ret = bq24190_get_config(bdi);
2148	if (ret < 0) {
2149		dev_err(dev, "Can't get devicetree config\n");
2150		goto out_charger;
2151	}
2152
2153	ret = bq24190_hw_init(bdi);
2154	if (ret < 0) {
2155		dev_err(dev, "Hardware init failed\n");
2156		goto out_charger;
2157	}
2158
2159	ret = bq24190_configure_usb_otg(bdi, bdi->ss_reg);
2160	if (ret < 0)
2161		goto out_charger;
2162
2163	bdi->initialized = true;
2164
2165	ret = devm_request_threaded_irq(dev, client->irq, NULL,
2166			bq24190_irq_handler_thread,
2167			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2168			"bq24190-charger", bdi);
2169	if (ret < 0) {
2170		dev_err(dev, "Can't set up irq handler\n");
2171		goto out_charger;
2172	}
2173
2174	ret = bq24190_register_vbus_regulator(bdi);
2175	if (ret < 0)
2176		goto out_charger;
2177
2178	enable_irq_wake(client->irq);
2179
2180	pm_runtime_put_autosuspend(dev);
2181
2182	return 0;
2183
2184out_charger:
2185	if (!IS_ERR_OR_NULL(bdi->battery))
2186		power_supply_unregister(bdi->battery);
2187	power_supply_unregister(bdi->charger);
2188
2189out_pmrt:
2190	pm_runtime_put_sync(dev);
2191	pm_runtime_dont_use_autosuspend(dev);
2192	pm_runtime_disable(dev);
2193	return ret;
2194}
2195
2196static void bq24190_remove(struct i2c_client *client)
2197{
2198	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2199	int error;
2200
2201	cancel_delayed_work_sync(&bdi->input_current_limit_work);
2202	error = pm_runtime_resume_and_get(bdi->dev);
2203	if (error < 0)
2204		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
2205
2206	bq24190_register_reset(bdi);
2207	if (bdi->battery)
2208		power_supply_unregister(bdi->battery);
2209	power_supply_unregister(bdi->charger);
2210	if (error >= 0)
2211		pm_runtime_put_sync(bdi->dev);
2212	pm_runtime_dont_use_autosuspend(bdi->dev);
2213	pm_runtime_disable(bdi->dev);
2214}
2215
2216static void bq24190_shutdown(struct i2c_client *client)
2217{
2218	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2219
2220	/* Turn off 5V boost regulator on shutdown */
2221	bdi->info->set_otg_vbus(bdi, false);
2222}
2223
2224static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
2225{
2226	struct i2c_client *client = to_i2c_client(dev);
2227	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2228
2229	if (!bdi->initialized)
2230		return 0;
2231
2232	dev_dbg(bdi->dev, "%s\n", __func__);
2233
2234	return 0;
2235}
2236
2237static __maybe_unused int bq24190_runtime_resume(struct device *dev)
2238{
2239	struct i2c_client *client = to_i2c_client(dev);
2240	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2241
2242	if (!bdi->initialized)
2243		return 0;
2244
2245	if (!bdi->irq_event) {
2246		dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
2247		bq24190_check_status(bdi);
2248	}
2249
2250	return 0;
2251}
2252
2253static __maybe_unused int bq24190_pm_suspend(struct device *dev)
2254{
2255	struct i2c_client *client = to_i2c_client(dev);
2256	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2257	int error;
2258
2259	error = pm_runtime_resume_and_get(bdi->dev);
2260	if (error < 0)
2261		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
2262
2263	bq24190_register_reset(bdi);
2264
2265	if (error >= 0) {
2266		pm_runtime_put_autosuspend(bdi->dev);
2267	}
2268
2269	return 0;
2270}
2271
2272static __maybe_unused int bq24190_pm_resume(struct device *dev)
2273{
2274	struct i2c_client *client = to_i2c_client(dev);
2275	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2276	int error;
2277
2278	bdi->f_reg = 0;
2279	bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
2280
2281	error = pm_runtime_resume_and_get(bdi->dev);
2282	if (error < 0)
2283		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
2284
2285	bq24190_register_reset(bdi);
2286	bq24190_set_config(bdi);
2287	bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
2288
2289	if (error >= 0) {
2290		pm_runtime_put_autosuspend(bdi->dev);
2291	}
2292
2293	/* Things may have changed while suspended so alert upper layer */
2294	power_supply_changed(bdi->charger);
2295	if (bdi->battery)
2296		power_supply_changed(bdi->battery);
2297
2298	return 0;
2299}
2300
2301static const struct dev_pm_ops bq24190_pm_ops = {
2302	SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
2303			   NULL)
2304	SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
2305};
2306
2307static const struct i2c_device_id bq24190_i2c_ids[] = {
2308	{ "bq24190", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24190] },
2309	{ "bq24192", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24192] },
2310	{ "bq24192i", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24192i] },
2311	{ "bq24193", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24193] },
2312	{ "bq24196", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24196] },
2313	{ "bq24296", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24296] },
2314	{ "bq24297", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24297] },
2315	{ },
2316};
2317MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
2318
2319static const struct of_device_id bq24190_of_match[] = {
2320	{ .compatible = "ti,bq24190", .data = &bq24190_chip_info_tbl[BQ24190] },
2321	{ .compatible = "ti,bq24192", .data = &bq24190_chip_info_tbl[BQ24192] },
2322	{ .compatible = "ti,bq24192i", .data = &bq24190_chip_info_tbl[BQ24192i] },
2323	{ .compatible = "ti,bq24193", .data = &bq24190_chip_info_tbl[BQ24193] },
2324	{ .compatible = "ti,bq24196", .data = &bq24190_chip_info_tbl[BQ24196] },
2325	{ .compatible = "ti,bq24296", .data = &bq24190_chip_info_tbl[BQ24296] },
2326	{ .compatible = "ti,bq24297", .data = &bq24190_chip_info_tbl[BQ24297] },
2327	{ },
2328};
2329MODULE_DEVICE_TABLE(of, bq24190_of_match);
2330
2331static struct i2c_driver bq24190_driver = {
2332	.probe		= bq24190_probe,
2333	.remove		= bq24190_remove,
2334	.shutdown	= bq24190_shutdown,
2335	.id_table	= bq24190_i2c_ids,
2336	.driver = {
2337		.name		= "bq24190-charger",
2338		.pm		= &bq24190_pm_ops,
2339		.of_match_table	= bq24190_of_match,
2340	},
2341};
2342module_i2c_driver(bq24190_driver);
2343
2344MODULE_LICENSE("GPL");
2345MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
2346MODULE_DESCRIPTION("TI BQ24190 Charger Driver");
~/ Read-only file preview.