Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
   1/*
   2 * Driver for the TI bq24190 battery charger.
   3 *
   4 * Author: Mark A. Greer <mgreer@animalcreek.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/interrupt.h>
  13#include <linux/delay.h>
  14#include <linux/of_irq.h>
  15#include <linux/of_device.h>
  16#include <linux/pm_runtime.h>
  17#include <linux/power_supply.h>
  18#include <linux/gpio.h>
  19#include <linux/i2c.h>
  20
  21#include <linux/power/bq24190_charger.h>
  22
  23
  24#define	BQ24190_MANUFACTURER	"Texas Instruments"
  25
  26#define BQ24190_REG_ISC		0x00 /* Input Source Control */
  27#define BQ24190_REG_ISC_EN_HIZ_MASK		BIT(7)
  28#define BQ24190_REG_ISC_EN_HIZ_SHIFT		7
  29#define BQ24190_REG_ISC_VINDPM_MASK		(BIT(6) | BIT(5) | BIT(4) | \
  30						 BIT(3))
  31#define BQ24190_REG_ISC_VINDPM_SHIFT		3
  32#define BQ24190_REG_ISC_IINLIM_MASK		(BIT(2) | BIT(1) | BIT(0))
  33#define BQ24190_REG_ISC_IINLIM_SHIFT		0
  34
  35#define BQ24190_REG_POC		0x01 /* Power-On Configuration */
  36#define BQ24190_REG_POC_RESET_MASK		BIT(7)
  37#define BQ24190_REG_POC_RESET_SHIFT		7
  38#define BQ24190_REG_POC_WDT_RESET_MASK		BIT(6)
  39#define BQ24190_REG_POC_WDT_RESET_SHIFT		6
  40#define BQ24190_REG_POC_CHG_CONFIG_MASK		(BIT(5) | BIT(4))
  41#define BQ24190_REG_POC_CHG_CONFIG_SHIFT	4
  42#define BQ24190_REG_POC_SYS_MIN_MASK		(BIT(3) | BIT(2) | BIT(1))
  43#define BQ24190_REG_POC_SYS_MIN_SHIFT		1
  44#define BQ24190_REG_POC_BOOST_LIM_MASK		BIT(0)
  45#define BQ24190_REG_POC_BOOST_LIM_SHIFT		0
  46
  47#define BQ24190_REG_CCC		0x02 /* Charge Current Control */
  48#define BQ24190_REG_CCC_ICHG_MASK		(BIT(7) | BIT(6) | BIT(5) | \
  49						 BIT(4) | BIT(3) | BIT(2))
  50#define BQ24190_REG_CCC_ICHG_SHIFT		2
  51#define BQ24190_REG_CCC_FORCE_20PCT_MASK	BIT(0)
  52#define BQ24190_REG_CCC_FORCE_20PCT_SHIFT	0
  53
  54#define BQ24190_REG_PCTCC	0x03 /* Pre-charge/Termination Current Cntl */
  55#define BQ24190_REG_PCTCC_IPRECHG_MASK		(BIT(7) | BIT(6) | BIT(5) | \
  56						 BIT(4))
  57#define BQ24190_REG_PCTCC_IPRECHG_SHIFT		4
  58#define BQ24190_REG_PCTCC_ITERM_MASK		(BIT(3) | BIT(2) | BIT(1) | \
  59						 BIT(0))
  60#define BQ24190_REG_PCTCC_ITERM_SHIFT		0
  61
  62#define BQ24190_REG_CVC		0x04 /* Charge Voltage Control */
  63#define BQ24190_REG_CVC_VREG_MASK		(BIT(7) | BIT(6) | BIT(5) | \
  64						 BIT(4) | BIT(3) | BIT(2))
  65#define BQ24190_REG_CVC_VREG_SHIFT		2
  66#define BQ24190_REG_CVC_BATLOWV_MASK		BIT(1)
  67#define BQ24190_REG_CVC_BATLOWV_SHIFT		1
  68#define BQ24190_REG_CVC_VRECHG_MASK		BIT(0)
  69#define BQ24190_REG_CVC_VRECHG_SHIFT		0
  70
  71#define BQ24190_REG_CTTC	0x05 /* Charge Term/Timer Control */
  72#define BQ24190_REG_CTTC_EN_TERM_MASK		BIT(7)
  73#define BQ24190_REG_CTTC_EN_TERM_SHIFT		7
  74#define BQ24190_REG_CTTC_TERM_STAT_MASK		BIT(6)
  75#define BQ24190_REG_CTTC_TERM_STAT_SHIFT	6
  76#define BQ24190_REG_CTTC_WATCHDOG_MASK		(BIT(5) | BIT(4))
  77#define BQ24190_REG_CTTC_WATCHDOG_SHIFT		4
  78#define BQ24190_REG_CTTC_EN_TIMER_MASK		BIT(3)
  79#define BQ24190_REG_CTTC_EN_TIMER_SHIFT		3
  80#define BQ24190_REG_CTTC_CHG_TIMER_MASK		(BIT(2) | BIT(1))
  81#define BQ24190_REG_CTTC_CHG_TIMER_SHIFT	1
  82#define BQ24190_REG_CTTC_JEITA_ISET_MASK	BIT(0)
  83#define BQ24190_REG_CTTC_JEITA_ISET_SHIFT	0
  84
  85#define BQ24190_REG_ICTRC	0x06 /* IR Comp/Thermal Regulation Control */
  86#define BQ24190_REG_ICTRC_BAT_COMP_MASK		(BIT(7) | BIT(6) | BIT(5))
  87#define BQ24190_REG_ICTRC_BAT_COMP_SHIFT	5
  88#define BQ24190_REG_ICTRC_VCLAMP_MASK		(BIT(4) | BIT(3) | BIT(2))
  89#define BQ24190_REG_ICTRC_VCLAMP_SHIFT		2
  90#define BQ24190_REG_ICTRC_TREG_MASK		(BIT(1) | BIT(0))
  91#define BQ24190_REG_ICTRC_TREG_SHIFT		0
  92
  93#define BQ24190_REG_MOC		0x07 /* Misc. Operation Control */
  94#define BQ24190_REG_MOC_DPDM_EN_MASK		BIT(7)
  95#define BQ24190_REG_MOC_DPDM_EN_SHIFT		7
  96#define BQ24190_REG_MOC_TMR2X_EN_MASK		BIT(6)
  97#define BQ24190_REG_MOC_TMR2X_EN_SHIFT		6
  98#define BQ24190_REG_MOC_BATFET_DISABLE_MASK	BIT(5)
  99#define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT	5
 100#define BQ24190_REG_MOC_JEITA_VSET_MASK		BIT(4)
 101#define BQ24190_REG_MOC_JEITA_VSET_SHIFT	4
 102#define BQ24190_REG_MOC_INT_MASK_MASK		(BIT(1) | BIT(0))
 103#define BQ24190_REG_MOC_INT_MASK_SHIFT		0
 104
 105#define BQ24190_REG_SS		0x08 /* System Status */
 106#define BQ24190_REG_SS_VBUS_STAT_MASK		(BIT(7) | BIT(6))
 107#define BQ24190_REG_SS_VBUS_STAT_SHIFT		6
 108#define BQ24190_REG_SS_CHRG_STAT_MASK		(BIT(5) | BIT(4))
 109#define BQ24190_REG_SS_CHRG_STAT_SHIFT		4
 110#define BQ24190_REG_SS_DPM_STAT_MASK		BIT(3)
 111#define BQ24190_REG_SS_DPM_STAT_SHIFT		3
 112#define BQ24190_REG_SS_PG_STAT_MASK		BIT(2)
 113#define BQ24190_REG_SS_PG_STAT_SHIFT		2
 114#define BQ24190_REG_SS_THERM_STAT_MASK		BIT(1)
 115#define BQ24190_REG_SS_THERM_STAT_SHIFT		1
 116#define BQ24190_REG_SS_VSYS_STAT_MASK		BIT(0)
 117#define BQ24190_REG_SS_VSYS_STAT_SHIFT		0
 118
 119#define BQ24190_REG_F		0x09 /* Fault */
 120#define BQ24190_REG_F_WATCHDOG_FAULT_MASK	BIT(7)
 121#define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT	7
 122#define BQ24190_REG_F_BOOST_FAULT_MASK		BIT(6)
 123#define BQ24190_REG_F_BOOST_FAULT_SHIFT		6
 124#define BQ24190_REG_F_CHRG_FAULT_MASK		(BIT(5) | BIT(4))
 125#define BQ24190_REG_F_CHRG_FAULT_SHIFT		4
 126#define BQ24190_REG_F_BAT_FAULT_MASK		BIT(3)
 127#define BQ24190_REG_F_BAT_FAULT_SHIFT		3
 128#define BQ24190_REG_F_NTC_FAULT_MASK		(BIT(2) | BIT(1) | BIT(0))
 129#define BQ24190_REG_F_NTC_FAULT_SHIFT		0
 130
 131#define BQ24190_REG_VPRS	0x0A /* Vendor/Part/Revision Status */
 132#define BQ24190_REG_VPRS_PN_MASK		(BIT(5) | BIT(4) | BIT(3))
 133#define BQ24190_REG_VPRS_PN_SHIFT		3
 134#define BQ24190_REG_VPRS_PN_24190			0x4
 135#define BQ24190_REG_VPRS_PN_24192			0x5 /* Also 24193 */
 136#define BQ24190_REG_VPRS_PN_24192I			0x3
 137#define BQ24190_REG_VPRS_TS_PROFILE_MASK	BIT(2)
 138#define BQ24190_REG_VPRS_TS_PROFILE_SHIFT	2
 139#define BQ24190_REG_VPRS_DEV_REG_MASK		(BIT(1) | BIT(0))
 140#define BQ24190_REG_VPRS_DEV_REG_SHIFT		0
 141
 142/*
 143 * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
 144 * so the first read after a fault returns the latched value and subsequent
 145 * reads return the current value.  In order to return the fault status
 146 * to the user, have the interrupt handler save the reg's value and retrieve
 147 * it in the appropriate health/status routine.  Each routine has its own
 148 * flag indicating whether it should use the value stored by the last run
 149 * of the interrupt handler or do an actual reg read.  That way each routine
 150 * can report back whatever fault may have occured.
 151 */
 152struct bq24190_dev_info {
 153	struct i2c_client		*client;
 154	struct device			*dev;
 155	struct power_supply		charger;
 156	struct power_supply		battery;
 157	char				model_name[I2C_NAME_SIZE];
 158	kernel_ulong_t			model;
 159	unsigned int			gpio_int;
 160	unsigned int			irq;
 161	struct mutex			f_reg_lock;
 162	bool				first_time;
 163	bool				charger_health_valid;
 164	bool				battery_health_valid;
 165	bool				battery_status_valid;
 166	u8				f_reg;
 167	u8				ss_reg;
 168	u8				watchdog;
 169};
 170
 171/*
 172 * The tables below provide a 2-way mapping for the value that goes in
 173 * the register field and the real-world value that it represents.
 174 * The index of the array is the value that goes in the register; the
 175 * number at that index in the array is the real-world value that it
 176 * represents.
 177 */
 178/* REG02[7:2] (ICHG) in uAh */
 179static const int bq24190_ccc_ichg_values[] = {
 180	 512000,  576000,  640000,  704000,  768000,  832000,  896000,  960000,
 181	1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
 182	1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
 183	2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
 184	2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
 185	3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
 186	3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
 187	4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
 188};
 189
 190/* REG04[7:2] (VREG) in uV */
 191static const int bq24190_cvc_vreg_values[] = {
 192	3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
 193	3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
 194	3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
 195	3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
 196	4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
 197	4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
 198	4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
 199	4400000
 200};
 201
 202/* REG06[1:0] (TREG) in tenths of degrees Celcius */
 203static const int bq24190_ictrc_treg_values[] = {
 204	600, 800, 1000, 1200
 205};
 206
 207/*
 208 * Return the index in 'tbl' of greatest value that is less than or equal to
 209 * 'val'.  The index range returned is 0 to 'tbl_size' - 1.  Assumes that
 210 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
 211 * is less than 2^8.
 212 */
 213static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
 214{
 215	int i;
 216
 217	for (i = 1; i < tbl_size; i++)
 218		if (v < tbl[i])
 219			break;
 220
 221	return i - 1;
 222}
 223
 224/* Basic driver I/O routines */
 225
 226static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
 227{
 228	int ret;
 229
 230	ret = i2c_smbus_read_byte_data(bdi->client, reg);
 231	if (ret < 0)
 232		return ret;
 233
 234	*data = ret;
 235	return 0;
 236}
 237
 238static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
 239{
 240	return i2c_smbus_write_byte_data(bdi->client, reg, data);
 241}
 242
 243static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
 244		u8 mask, u8 shift, u8 *data)
 245{
 246	u8 v;
 247	int ret;
 248
 249	ret = bq24190_read(bdi, reg, &v);
 250	if (ret < 0)
 251		return ret;
 252
 253	v &= mask;
 254	v >>= shift;
 255	*data = v;
 256
 257	return 0;
 258}
 259
 260static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
 261		u8 mask, u8 shift, u8 data)
 262{
 263	u8 v;
 264	int ret;
 265
 266	ret = bq24190_read(bdi, reg, &v);
 267	if (ret < 0)
 268		return ret;
 269
 270	v &= ~mask;
 271	v |= ((data << shift) & mask);
 272
 273	return bq24190_write(bdi, reg, v);
 274}
 275
 276static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
 277		u8 reg, u8 mask, u8 shift,
 278		const int tbl[], int tbl_size,
 279		int *val)
 280{
 281	u8 v;
 282	int ret;
 283
 284	ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
 285	if (ret < 0)
 286		return ret;
 287
 288	v = (v >= tbl_size) ? (tbl_size - 1) : v;
 289	*val = tbl[v];
 290
 291	return 0;
 292}
 293
 294static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
 295		u8 reg, u8 mask, u8 shift,
 296		const int tbl[], int tbl_size,
 297		int val)
 298{
 299	u8 idx;
 300
 301	idx = bq24190_find_idx(tbl, tbl_size, val);
 302
 303	return bq24190_write_mask(bdi, reg, mask, shift, idx);
 304}
 305
 306#ifdef CONFIG_SYSFS
 307/*
 308 * There are a numerous options that are configurable on the bq24190
 309 * that go well beyond what the power_supply properties provide access to.
 310 * Provide sysfs access to them so they can be examined and possibly modified
 311 * on the fly.  They will be provided for the charger power_supply object only
 312 * and will be prefixed by 'f_' to make them easier to recognize.
 313 */
 314
 315#define BQ24190_SYSFS_FIELD(_name, r, f, m, store)			\
 316{									\
 317	.attr	= __ATTR(f_##_name, m, bq24190_sysfs_show, store),	\
 318	.reg	= BQ24190_REG_##r,					\
 319	.mask	= BQ24190_REG_##r##_##f##_MASK,				\
 320	.shift	= BQ24190_REG_##r##_##f##_SHIFT,			\
 321}
 322
 323#define BQ24190_SYSFS_FIELD_RW(_name, r, f)				\
 324		BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO,	\
 325				bq24190_sysfs_store)
 326
 327#define BQ24190_SYSFS_FIELD_RO(_name, r, f)				\
 328		BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
 329
 330static ssize_t bq24190_sysfs_show(struct device *dev,
 331		struct device_attribute *attr, char *buf);
 332static ssize_t bq24190_sysfs_store(struct device *dev,
 333		struct device_attribute *attr, const char *buf, size_t count);
 334
 335struct bq24190_sysfs_field_info {
 336	struct device_attribute	attr;
 337	u8	reg;
 338	u8	mask;
 339	u8	shift;
 340};
 341
 342/* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
 343#undef SS
 344
 345static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
 346			/*	sysfs name	reg	field in reg */
 347	BQ24190_SYSFS_FIELD_RW(en_hiz,		ISC,	EN_HIZ),
 348	BQ24190_SYSFS_FIELD_RW(vindpm,		ISC,	VINDPM),
 349	BQ24190_SYSFS_FIELD_RW(iinlim,		ISC,	IINLIM),
 350	BQ24190_SYSFS_FIELD_RW(chg_config,	POC,	CHG_CONFIG),
 351	BQ24190_SYSFS_FIELD_RW(sys_min,		POC,	SYS_MIN),
 352	BQ24190_SYSFS_FIELD_RW(boost_lim,	POC,	BOOST_LIM),
 353	BQ24190_SYSFS_FIELD_RW(ichg,		CCC,	ICHG),
 354	BQ24190_SYSFS_FIELD_RW(force_20_pct,	CCC,	FORCE_20PCT),
 355	BQ24190_SYSFS_FIELD_RW(iprechg,		PCTCC,	IPRECHG),
 356	BQ24190_SYSFS_FIELD_RW(iterm,		PCTCC,	ITERM),
 357	BQ24190_SYSFS_FIELD_RW(vreg,		CVC,	VREG),
 358	BQ24190_SYSFS_FIELD_RW(batlowv,		CVC,	BATLOWV),
 359	BQ24190_SYSFS_FIELD_RW(vrechg,		CVC,	VRECHG),
 360	BQ24190_SYSFS_FIELD_RW(en_term,		CTTC,	EN_TERM),
 361	BQ24190_SYSFS_FIELD_RW(term_stat,	CTTC,	TERM_STAT),
 362	BQ24190_SYSFS_FIELD_RO(watchdog,	CTTC,	WATCHDOG),
 363	BQ24190_SYSFS_FIELD_RW(en_timer,	CTTC,	EN_TIMER),
 364	BQ24190_SYSFS_FIELD_RW(chg_timer,	CTTC,	CHG_TIMER),
 365	BQ24190_SYSFS_FIELD_RW(jeta_iset,	CTTC,	JEITA_ISET),
 366	BQ24190_SYSFS_FIELD_RW(bat_comp,	ICTRC,	BAT_COMP),
 367	BQ24190_SYSFS_FIELD_RW(vclamp,		ICTRC,	VCLAMP),
 368	BQ24190_SYSFS_FIELD_RW(treg,		ICTRC,	TREG),
 369	BQ24190_SYSFS_FIELD_RW(dpdm_en,		MOC,	DPDM_EN),
 370	BQ24190_SYSFS_FIELD_RW(tmr2x_en,	MOC,	TMR2X_EN),
 371	BQ24190_SYSFS_FIELD_RW(batfet_disable,	MOC,	BATFET_DISABLE),
 372	BQ24190_SYSFS_FIELD_RW(jeita_vset,	MOC,	JEITA_VSET),
 373	BQ24190_SYSFS_FIELD_RO(int_mask,	MOC,	INT_MASK),
 374	BQ24190_SYSFS_FIELD_RO(vbus_stat,	SS,	VBUS_STAT),
 375	BQ24190_SYSFS_FIELD_RO(chrg_stat,	SS,	CHRG_STAT),
 376	BQ24190_SYSFS_FIELD_RO(dpm_stat,	SS,	DPM_STAT),
 377	BQ24190_SYSFS_FIELD_RO(pg_stat,		SS,	PG_STAT),
 378	BQ24190_SYSFS_FIELD_RO(therm_stat,	SS,	THERM_STAT),
 379	BQ24190_SYSFS_FIELD_RO(vsys_stat,	SS,	VSYS_STAT),
 380	BQ24190_SYSFS_FIELD_RO(watchdog_fault,	F,	WATCHDOG_FAULT),
 381	BQ24190_SYSFS_FIELD_RO(boost_fault,	F,	BOOST_FAULT),
 382	BQ24190_SYSFS_FIELD_RO(chrg_fault,	F,	CHRG_FAULT),
 383	BQ24190_SYSFS_FIELD_RO(bat_fault,	F,	BAT_FAULT),
 384	BQ24190_SYSFS_FIELD_RO(ntc_fault,	F,	NTC_FAULT),
 385	BQ24190_SYSFS_FIELD_RO(pn,		VPRS,	PN),
 386	BQ24190_SYSFS_FIELD_RO(ts_profile,	VPRS,	TS_PROFILE),
 387	BQ24190_SYSFS_FIELD_RO(dev_reg,		VPRS,	DEV_REG),
 388};
 389
 390static struct attribute *
 391	bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
 392
 393static const struct attribute_group bq24190_sysfs_attr_group = {
 394	.attrs = bq24190_sysfs_attrs,
 395};
 396
 397static void bq24190_sysfs_init_attrs(void)
 398{
 399	int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
 400
 401	for (i = 0; i < limit; i++)
 402		bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
 403
 404	bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
 405}
 406
 407static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
 408		const char *name)
 409{
 410	int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
 411
 412	for (i = 0; i < limit; i++)
 413		if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
 414			break;
 415
 416	if (i >= limit)
 417		return NULL;
 418
 419	return &bq24190_sysfs_field_tbl[i];
 420}
 421
 422static ssize_t bq24190_sysfs_show(struct device *dev,
 423		struct device_attribute *attr, char *buf)
 424{
 425	struct power_supply *psy = dev_get_drvdata(dev);
 426	struct bq24190_dev_info *bdi =
 427			container_of(psy, struct bq24190_dev_info, charger);
 428	struct bq24190_sysfs_field_info *info;
 429	int ret;
 430	u8 v;
 431
 432	info = bq24190_sysfs_field_lookup(attr->attr.name);
 433	if (!info)
 434		return -EINVAL;
 435
 436	ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
 437	if (ret)
 438		return ret;
 439
 440	return scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
 441}
 442
 443static ssize_t bq24190_sysfs_store(struct device *dev,
 444		struct device_attribute *attr, const char *buf, size_t count)
 445{
 446	struct power_supply *psy = dev_get_drvdata(dev);
 447	struct bq24190_dev_info *bdi =
 448			container_of(psy, struct bq24190_dev_info, charger);
 449	struct bq24190_sysfs_field_info *info;
 450	int ret;
 451	u8 v;
 452
 453	info = bq24190_sysfs_field_lookup(attr->attr.name);
 454	if (!info)
 455		return -EINVAL;
 456
 457	ret = kstrtou8(buf, 0, &v);
 458	if (ret < 0)
 459		return ret;
 460
 461	ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
 462	if (ret)
 463		return ret;
 464
 465	return count;
 466}
 467
 468static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
 469{
 470	bq24190_sysfs_init_attrs();
 471
 472	return sysfs_create_group(&bdi->charger.dev->kobj,
 473			&bq24190_sysfs_attr_group);
 474}
 475
 476static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi)
 477{
 478	sysfs_remove_group(&bdi->charger.dev->kobj, &bq24190_sysfs_attr_group);
 479}
 480#else
 481static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
 482{
 483	return 0;
 484}
 485
 486static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {}
 487#endif
 488
 489/*
 490 * According to the "Host Mode and default Mode" section of the
 491 * manual, a write to any register causes the bq24190 to switch
 492 * from default mode to host mode.  It will switch back to default
 493 * mode after a WDT timeout unless the WDT is turned off as well.
 494 * So, by simply turning off the WDT, we accomplish both with the
 495 * same write.
 496 */
 497static int bq24190_set_mode_host(struct bq24190_dev_info *bdi)
 498{
 499	int ret;
 500	u8 v;
 501
 502	ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
 503	if (ret < 0)
 504		return ret;
 505
 506	bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
 507					BQ24190_REG_CTTC_WATCHDOG_SHIFT);
 508	v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
 509
 510	return bq24190_write(bdi, BQ24190_REG_CTTC, v);
 511}
 512
 513static int bq24190_register_reset(struct bq24190_dev_info *bdi)
 514{
 515	int ret, limit = 100;
 516	u8 v;
 517
 518	/* Reset the registers */
 519	ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 520			BQ24190_REG_POC_RESET_MASK,
 521			BQ24190_REG_POC_RESET_SHIFT,
 522			0x1);
 523	if (ret < 0)
 524		return ret;
 525
 526	/* Reset bit will be cleared by hardware so poll until it is */
 527	do {
 528		ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 529				BQ24190_REG_POC_RESET_MASK,
 530				BQ24190_REG_POC_RESET_SHIFT,
 531				&v);
 532		if (ret < 0)
 533			return ret;
 534
 535		if (!v)
 536			break;
 537
 538		udelay(10);
 539	} while (--limit);
 540
 541	if (!limit)
 542		return -EIO;
 543
 544	return 0;
 545}
 546
 547/* Charger power supply property routines */
 548
 549static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
 550		union power_supply_propval *val)
 551{
 552	u8 v;
 553	int type, ret;
 554
 555	ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 556			BQ24190_REG_POC_CHG_CONFIG_MASK,
 557			BQ24190_REG_POC_CHG_CONFIG_SHIFT,
 558			&v);
 559	if (ret < 0)
 560		return ret;
 561
 562	/* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
 563	if (!v) {
 564		type = POWER_SUPPLY_CHARGE_TYPE_NONE;
 565	} else {
 566		ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 567				BQ24190_REG_CCC_FORCE_20PCT_MASK,
 568				BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 569				&v);
 570		if (ret < 0)
 571			return ret;
 572
 573		type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
 574			     POWER_SUPPLY_CHARGE_TYPE_FAST;
 575	}
 576
 577	val->intval = type;
 578
 579	return 0;
 580}
 581
 582static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
 583		const union power_supply_propval *val)
 584{
 585	u8 chg_config, force_20pct, en_term;
 586	int ret;
 587
 588	/*
 589	 * According to the "Termination when REG02[0] = 1" section of
 590	 * the bq24190 manual, the trickle charge could be less than the
 591	 * termination current so it recommends turning off the termination
 592	 * function.
 593	 *
 594	 * Note: AFAICT from the datasheet, the user will have to manually
 595	 * turn off the charging when in 20% mode.  If its not turned off,
 596	 * there could be battery damage.  So, use this mode at your own risk.
 597	 */
 598	switch (val->intval) {
 599	case POWER_SUPPLY_CHARGE_TYPE_NONE:
 600		chg_config = 0x0;
 601		break;
 602	case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
 603		chg_config = 0x1;
 604		force_20pct = 0x1;
 605		en_term = 0x0;
 606		break;
 607	case POWER_SUPPLY_CHARGE_TYPE_FAST:
 608		chg_config = 0x1;
 609		force_20pct = 0x0;
 610		en_term = 0x1;
 611		break;
 612	default:
 613		return -EINVAL;
 614	}
 615
 616	if (chg_config) { /* Enabling the charger */
 617		ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
 618				BQ24190_REG_CCC_FORCE_20PCT_MASK,
 619				BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 620				force_20pct);
 621		if (ret < 0)
 622			return ret;
 623
 624		ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
 625				BQ24190_REG_CTTC_EN_TERM_MASK,
 626				BQ24190_REG_CTTC_EN_TERM_SHIFT,
 627				en_term);
 628		if (ret < 0)
 629			return ret;
 630	}
 631
 632	return bq24190_write_mask(bdi, BQ24190_REG_POC,
 633			BQ24190_REG_POC_CHG_CONFIG_MASK,
 634			BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
 635}
 636
 637static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
 638		union power_supply_propval *val)
 639{
 640	u8 v;
 641	int health, ret;
 642
 643	mutex_lock(&bdi->f_reg_lock);
 644
 645	if (bdi->charger_health_valid) {
 646		v = bdi->f_reg;
 647		bdi->charger_health_valid = false;
 648		mutex_unlock(&bdi->f_reg_lock);
 649	} else {
 650		mutex_unlock(&bdi->f_reg_lock);
 651
 652		ret = bq24190_read(bdi, BQ24190_REG_F, &v);
 653		if (ret < 0)
 654			return ret;
 655	}
 656
 657	if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
 658		/*
 659		 * This could be over-current or over-voltage but there's
 660		 * no way to tell which.  Return 'OVERVOLTAGE' since there
 661		 * isn't an 'OVERCURRENT' value defined that we can return
 662		 * even if it was over-current.
 663		 */
 664		health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
 665	} else {
 666		v &= BQ24190_REG_F_CHRG_FAULT_MASK;
 667		v >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
 668
 669		switch (v) {
 670		case 0x0: /* Normal */
 671			health = POWER_SUPPLY_HEALTH_GOOD;
 672			break;
 673		case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
 674			/*
 675			 * This could be over-voltage or under-voltage
 676			 * and there's no way to tell which.  Instead
 677			 * of looking foolish and returning 'OVERVOLTAGE'
 678			 * when its really under-voltage, just return
 679			 * 'UNSPEC_FAILURE'.
 680			 */
 681			health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
 682			break;
 683		case 0x2: /* Thermal Shutdown */
 684			health = POWER_SUPPLY_HEALTH_OVERHEAT;
 685			break;
 686		case 0x3: /* Charge Safety Timer Expiration */
 687			health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
 688			break;
 689		default:
 690			health = POWER_SUPPLY_HEALTH_UNKNOWN;
 691		}
 692	}
 693
 694	val->intval = health;
 695
 696	return 0;
 697}
 698
 699static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
 700		union power_supply_propval *val)
 701{
 702	u8 v;
 703	int ret;
 704
 705	ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
 706			BQ24190_REG_SS_PG_STAT_MASK,
 707			BQ24190_REG_SS_PG_STAT_SHIFT, &v);
 708	if (ret < 0)
 709		return ret;
 710
 711	val->intval = v;
 712	return 0;
 713}
 714
 715static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
 716		union power_supply_propval *val)
 717{
 718	u8 v;
 719	int curr, ret;
 720
 721	ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
 722			BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
 723			bq24190_ccc_ichg_values,
 724			ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
 725	if (ret < 0)
 726		return ret;
 727
 728	ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 729			BQ24190_REG_CCC_FORCE_20PCT_MASK,
 730			BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
 731	if (ret < 0)
 732		return ret;
 733
 734	/* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
 735	if (v)
 736		curr /= 5;
 737
 738	val->intval = curr;
 739	return 0;
 740}
 741
 742static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
 743		union power_supply_propval *val)
 744{
 745	int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
 746
 747	val->intval = bq24190_ccc_ichg_values[idx];
 748	return 0;
 749}
 750
 751static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
 752		const union power_supply_propval *val)
 753{
 754	u8 v;
 755	int ret, curr = val->intval;
 756
 757	ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 758			BQ24190_REG_CCC_FORCE_20PCT_MASK,
 759			BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
 760	if (ret < 0)
 761		return ret;
 762
 763	/* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
 764	if (v)
 765		curr *= 5;
 766
 767	return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
 768			BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
 769			bq24190_ccc_ichg_values,
 770			ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
 771}
 772
 773static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
 774		union power_supply_propval *val)
 775{
 776	int voltage, ret;
 777
 778	ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
 779			BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
 780			bq24190_cvc_vreg_values,
 781			ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
 782	if (ret < 0)
 783		return ret;
 784
 785	val->intval = voltage;
 786	return 0;
 787}
 788
 789static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
 790		union power_supply_propval *val)
 791{
 792	int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
 793
 794	val->intval = bq24190_cvc_vreg_values[idx];
 795	return 0;
 796}
 797
 798static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
 799		const union power_supply_propval *val)
 800{
 801	return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
 802			BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
 803			bq24190_cvc_vreg_values,
 804			ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
 805}
 806
 807static int bq24190_charger_get_property(struct power_supply *psy,
 808		enum power_supply_property psp, union power_supply_propval *val)
 809{
 810	struct bq24190_dev_info *bdi =
 811			container_of(psy, struct bq24190_dev_info, charger);
 812	int ret;
 813
 814	dev_dbg(bdi->dev, "prop: %d\n", psp);
 815
 816	pm_runtime_get_sync(bdi->dev);
 817
 818	switch (psp) {
 819	case POWER_SUPPLY_PROP_CHARGE_TYPE:
 820		ret = bq24190_charger_get_charge_type(bdi, val);
 821		break;
 822	case POWER_SUPPLY_PROP_HEALTH:
 823		ret = bq24190_charger_get_health(bdi, val);
 824		break;
 825	case POWER_SUPPLY_PROP_ONLINE:
 826		ret = bq24190_charger_get_online(bdi, val);
 827		break;
 828	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 829		ret = bq24190_charger_get_current(bdi, val);
 830		break;
 831	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
 832		ret = bq24190_charger_get_current_max(bdi, val);
 833		break;
 834	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 835		ret = bq24190_charger_get_voltage(bdi, val);
 836		break;
 837	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
 838		ret = bq24190_charger_get_voltage_max(bdi, val);
 839		break;
 840	case POWER_SUPPLY_PROP_SCOPE:
 841		val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
 842		ret = 0;
 843		break;
 844	case POWER_SUPPLY_PROP_MODEL_NAME:
 845		val->strval = bdi->model_name;
 846		ret = 0;
 847		break;
 848	case POWER_SUPPLY_PROP_MANUFACTURER:
 849		val->strval = BQ24190_MANUFACTURER;
 850		ret = 0;
 851		break;
 852	default:
 853		ret = -ENODATA;
 854	}
 855
 856	pm_runtime_put_sync(bdi->dev);
 857	return ret;
 858}
 859
 860static int bq24190_charger_set_property(struct power_supply *psy,
 861		enum power_supply_property psp,
 862		const union power_supply_propval *val)
 863{
 864	struct bq24190_dev_info *bdi =
 865			container_of(psy, struct bq24190_dev_info, charger);
 866	int ret;
 867
 868	dev_dbg(bdi->dev, "prop: %d\n", psp);
 869
 870	pm_runtime_get_sync(bdi->dev);
 871
 872	switch (psp) {
 873	case POWER_SUPPLY_PROP_CHARGE_TYPE:
 874		ret = bq24190_charger_set_charge_type(bdi, val);
 875		break;
 876	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 877		ret = bq24190_charger_set_current(bdi, val);
 878		break;
 879	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 880		ret = bq24190_charger_set_voltage(bdi, val);
 881		break;
 882	default:
 883		ret = -EINVAL;
 884	}
 885
 886	pm_runtime_put_sync(bdi->dev);
 887	return ret;
 888}
 889
 890static int bq24190_charger_property_is_writeable(struct power_supply *psy,
 891		enum power_supply_property psp)
 892{
 893	int ret;
 894
 895	switch (psp) {
 896	case POWER_SUPPLY_PROP_CHARGE_TYPE:
 897	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 898	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 899		ret = 1;
 900		break;
 901	default:
 902		ret = 0;
 903	}
 904
 905	return ret;
 906}
 907
 908static enum power_supply_property bq24190_charger_properties[] = {
 909	POWER_SUPPLY_PROP_TYPE,
 910	POWER_SUPPLY_PROP_HEALTH,
 911	POWER_SUPPLY_PROP_ONLINE,
 912	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
 913	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
 914	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
 915	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
 916	POWER_SUPPLY_PROP_SCOPE,
 917	POWER_SUPPLY_PROP_MODEL_NAME,
 918	POWER_SUPPLY_PROP_MANUFACTURER,
 919};
 920
 921static char *bq24190_charger_supplied_to[] = {
 922	"main-battery",
 923};
 924
 925static void bq24190_charger_init(struct power_supply *charger)
 926{
 927	charger->name = "bq24190-charger";
 928	charger->type = POWER_SUPPLY_TYPE_USB;
 929	charger->properties = bq24190_charger_properties;
 930	charger->num_properties = ARRAY_SIZE(bq24190_charger_properties);
 931	charger->supplied_to = bq24190_charger_supplied_to;
 932	charger->num_supplies = ARRAY_SIZE(bq24190_charger_supplied_to);
 933	charger->get_property = bq24190_charger_get_property;
 934	charger->set_property = bq24190_charger_set_property;
 935	charger->property_is_writeable = bq24190_charger_property_is_writeable;
 936}
 937
 938/* Battery power supply property routines */
 939
 940static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
 941		union power_supply_propval *val)
 942{
 943	u8 ss_reg, chrg_fault;
 944	int status, ret;
 945
 946	mutex_lock(&bdi->f_reg_lock);
 947
 948	if (bdi->battery_status_valid) {
 949		chrg_fault = bdi->f_reg;
 950		bdi->battery_status_valid = false;
 951		mutex_unlock(&bdi->f_reg_lock);
 952	} else {
 953		mutex_unlock(&bdi->f_reg_lock);
 954
 955		ret = bq24190_read(bdi, BQ24190_REG_F, &chrg_fault);
 956		if (ret < 0)
 957			return ret;
 958	}
 959
 960	chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
 961	chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
 962
 963	ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
 964	if (ret < 0)
 965		return ret;
 966
 967	/*
 968	 * The battery must be discharging when any of these are true:
 969	 * - there is no good power source;
 970	 * - there is a charge fault.
 971	 * Could also be discharging when in "supplement mode" but
 972	 * there is no way to tell when its in that mode.
 973	 */
 974	if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
 975		status = POWER_SUPPLY_STATUS_DISCHARGING;
 976	} else {
 977		ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
 978		ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
 979
 980		switch (ss_reg) {
 981		case 0x0: /* Not Charging */
 982			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 983			break;
 984		case 0x1: /* Pre-charge */
 985		case 0x2: /* Fast Charging */
 986			status = POWER_SUPPLY_STATUS_CHARGING;
 987			break;
 988		case 0x3: /* Charge Termination Done */
 989			status = POWER_SUPPLY_STATUS_FULL;
 990			break;
 991		default:
 992			ret = -EIO;
 993		}
 994	}
 995
 996	if (!ret)
 997		val->intval = status;
 998
 999	return ret;
1000}
1001
1002static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1003		union power_supply_propval *val)
1004{
1005	u8 v;
1006	int health, ret;
1007
1008	mutex_lock(&bdi->f_reg_lock);
1009
1010	if (bdi->battery_health_valid) {
1011		v = bdi->f_reg;
1012		bdi->battery_health_valid = false;
1013		mutex_unlock(&bdi->f_reg_lock);
1014	} else {
1015		mutex_unlock(&bdi->f_reg_lock);
1016
1017		ret = bq24190_read(bdi, BQ24190_REG_F, &v);
1018		if (ret < 0)
1019			return ret;
1020	}
1021
1022	if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1023		health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1024	} else {
1025		v &= BQ24190_REG_F_NTC_FAULT_MASK;
1026		v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
1027
1028		switch (v) {
1029		case 0x0: /* Normal */
1030			health = POWER_SUPPLY_HEALTH_GOOD;
1031			break;
1032		case 0x1: /* TS1 Cold */
1033		case 0x3: /* TS2 Cold */
1034		case 0x5: /* Both Cold */
1035			health = POWER_SUPPLY_HEALTH_COLD;
1036			break;
1037		case 0x2: /* TS1 Hot */
1038		case 0x4: /* TS2 Hot */
1039		case 0x6: /* Both Hot */
1040			health = POWER_SUPPLY_HEALTH_OVERHEAT;
1041			break;
1042		default:
1043			health = POWER_SUPPLY_HEALTH_UNKNOWN;
1044		}
1045	}
1046
1047	val->intval = health;
1048	return 0;
1049}
1050
1051static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1052		union power_supply_propval *val)
1053{
1054	u8 batfet_disable;
1055	int ret;
1056
1057	ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1058			BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1059			BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1060	if (ret < 0)
1061		return ret;
1062
1063	val->intval = !batfet_disable;
1064	return 0;
1065}
1066
1067static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1068		const union power_supply_propval *val)
1069{
1070	return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1071			BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1072			BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1073}
1074
1075static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1076		union power_supply_propval *val)
1077{
1078	int temp, ret;
1079
1080	ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1081			BQ24190_REG_ICTRC_TREG_MASK,
1082			BQ24190_REG_ICTRC_TREG_SHIFT,
1083			bq24190_ictrc_treg_values,
1084			ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1085	if (ret < 0)
1086		return ret;
1087
1088	val->intval = temp;
1089	return 0;
1090}
1091
1092static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1093		const union power_supply_propval *val)
1094{
1095	return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1096			BQ24190_REG_ICTRC_TREG_MASK,
1097			BQ24190_REG_ICTRC_TREG_SHIFT,
1098			bq24190_ictrc_treg_values,
1099			ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1100}
1101
1102static int bq24190_battery_get_property(struct power_supply *psy,
1103		enum power_supply_property psp, union power_supply_propval *val)
1104{
1105	struct bq24190_dev_info *bdi =
1106			container_of(psy, struct bq24190_dev_info, battery);
1107	int ret;
1108
1109	dev_dbg(bdi->dev, "prop: %d\n", psp);
1110
1111	pm_runtime_get_sync(bdi->dev);
1112
1113	switch (psp) {
1114	case POWER_SUPPLY_PROP_STATUS:
1115		ret = bq24190_battery_get_status(bdi, val);
1116		break;
1117	case POWER_SUPPLY_PROP_HEALTH:
1118		ret = bq24190_battery_get_health(bdi, val);
1119		break;
1120	case POWER_SUPPLY_PROP_ONLINE:
1121		ret = bq24190_battery_get_online(bdi, val);
1122		break;
1123	case POWER_SUPPLY_PROP_TECHNOLOGY:
1124		/* Could be Li-on or Li-polymer but no way to tell which */
1125		val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1126		ret = 0;
1127		break;
1128	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1129		ret = bq24190_battery_get_temp_alert_max(bdi, val);
1130		break;
1131	case POWER_SUPPLY_PROP_SCOPE:
1132		val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1133		ret = 0;
1134		break;
1135	default:
1136		ret = -ENODATA;
1137	}
1138
1139	pm_runtime_put_sync(bdi->dev);
1140	return ret;
1141}
1142
1143static int bq24190_battery_set_property(struct power_supply *psy,
1144		enum power_supply_property psp,
1145		const union power_supply_propval *val)
1146{
1147	struct bq24190_dev_info *bdi =
1148			container_of(psy, struct bq24190_dev_info, battery);
1149	int ret;
1150
1151	dev_dbg(bdi->dev, "prop: %d\n", psp);
1152
1153	pm_runtime_put_sync(bdi->dev);
1154
1155	switch (psp) {
1156	case POWER_SUPPLY_PROP_ONLINE:
1157		ret = bq24190_battery_set_online(bdi, val);
1158		break;
1159	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1160		ret = bq24190_battery_set_temp_alert_max(bdi, val);
1161		break;
1162	default:
1163		ret = -EINVAL;
1164	}
1165
1166	pm_runtime_put_sync(bdi->dev);
1167	return ret;
1168}
1169
1170static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1171		enum power_supply_property psp)
1172{
1173	int ret;
1174
1175	switch (psp) {
1176	case POWER_SUPPLY_PROP_ONLINE:
1177	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1178		ret = 1;
1179		break;
1180	default:
1181		ret = 0;
1182	}
1183
1184	return ret;
1185}
1186
1187static enum power_supply_property bq24190_battery_properties[] = {
1188	POWER_SUPPLY_PROP_STATUS,
1189	POWER_SUPPLY_PROP_HEALTH,
1190	POWER_SUPPLY_PROP_ONLINE,
1191	POWER_SUPPLY_PROP_TECHNOLOGY,
1192	POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1193	POWER_SUPPLY_PROP_SCOPE,
1194};
1195
1196static void bq24190_battery_init(struct power_supply *battery)
1197{
1198	battery->name = "bq24190-battery";
1199	battery->type = POWER_SUPPLY_TYPE_BATTERY;
1200	battery->properties = bq24190_battery_properties;
1201	battery->num_properties = ARRAY_SIZE(bq24190_battery_properties);
1202	battery->get_property = bq24190_battery_get_property;
1203	battery->set_property = bq24190_battery_set_property;
1204	battery->property_is_writeable = bq24190_battery_property_is_writeable;
1205}
1206
1207static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1208{
1209	struct bq24190_dev_info *bdi = data;
1210	bool alert_userspace = false;
1211	u8 ss_reg, f_reg;
1212	int ret;
1213
1214	pm_runtime_get_sync(bdi->dev);
1215
1216	ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1217	if (ret < 0) {
1218		dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1219		goto out;
1220	}
1221
1222	if (ss_reg != bdi->ss_reg) {
1223		/*
1224		 * The device is in host mode so when PG_STAT goes from 1->0
1225		 * (i.e., power removed) HIZ needs to be disabled.
1226		 */
1227		if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1228				!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1229			ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1230					BQ24190_REG_ISC_EN_HIZ_MASK,
1231					BQ24190_REG_ISC_EN_HIZ_SHIFT,
1232					0);
1233			if (ret < 0)
1234				dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1235					ret);
1236		}
1237
1238		bdi->ss_reg = ss_reg;
1239		alert_userspace = true;
1240	}
1241
1242	mutex_lock(&bdi->f_reg_lock);
1243
1244	ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1245	if (ret < 0) {
1246		mutex_unlock(&bdi->f_reg_lock);
1247		dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1248		goto out;
1249	}
1250
1251	if (f_reg != bdi->f_reg) {
1252		bdi->f_reg = f_reg;
1253		bdi->charger_health_valid = true;
1254		bdi->battery_health_valid = true;
1255		bdi->battery_status_valid = true;
1256
1257		alert_userspace = true;
1258	}
1259
1260	mutex_unlock(&bdi->f_reg_lock);
1261
1262	/*
1263	 * Sometimes bq24190 gives a steady trickle of interrupts even
1264	 * though the watchdog timer is turned off and neither the STATUS
1265	 * nor FAULT registers have changed.  Weed out these sprurious
1266	 * interrupts so userspace isn't alerted for no reason.
1267	 * In addition, the chip always generates an interrupt after
1268	 * register reset so we should ignore that one (the very first
1269	 * interrupt received).
1270	 */
1271	if (alert_userspace && !bdi->first_time) {
1272		power_supply_changed(&bdi->charger);
1273		power_supply_changed(&bdi->battery);
1274		bdi->first_time = false;
1275	}
1276
1277out:
1278	pm_runtime_put_sync(bdi->dev);
1279
1280	dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1281
1282	return IRQ_HANDLED;
1283}
1284
1285static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1286{
1287	u8 v;
1288	int ret;
1289
1290	pm_runtime_get_sync(bdi->dev);
1291
1292	/* First check that the device really is what its supposed to be */
1293	ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1294			BQ24190_REG_VPRS_PN_MASK,
1295			BQ24190_REG_VPRS_PN_SHIFT,
1296			&v);
1297	if (ret < 0)
1298		goto out;
1299
1300	if (v != bdi->model) {
1301		ret = -ENODEV;
1302		goto out;
1303	}
1304
1305	ret = bq24190_register_reset(bdi);
1306	if (ret < 0)
1307		goto out;
1308
1309	ret = bq24190_set_mode_host(bdi);
1310out:
1311	pm_runtime_put_sync(bdi->dev);
1312	return ret;
1313}
1314
1315#ifdef CONFIG_OF
1316static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1317{
1318	bdi->irq = irq_of_parse_and_map(bdi->dev->of_node, 0);
1319	if (bdi->irq <= 0)
1320		return -1;
1321
1322	return 0;
1323}
1324#else
1325static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1326{
1327	return -1;
1328}
1329#endif
1330
1331static int bq24190_setup_pdata(struct bq24190_dev_info *bdi,
1332		struct bq24190_platform_data *pdata)
1333{
1334	int ret;
1335
1336	if (!gpio_is_valid(pdata->gpio_int))
1337		return -1;
1338
1339	ret = gpio_request(pdata->gpio_int, dev_name(bdi->dev));
1340	if (ret < 0)
1341		return -1;
1342
1343	ret = gpio_direction_input(pdata->gpio_int);
1344	if (ret < 0)
1345		goto out;
1346
1347	bdi->irq = gpio_to_irq(pdata->gpio_int);
1348	if (!bdi->irq)
1349		goto out;
1350
1351	bdi->gpio_int = pdata->gpio_int;
1352	return 0;
1353
1354out:
1355	gpio_free(pdata->gpio_int);
1356	return -1;
1357}
1358
1359static int bq24190_probe(struct i2c_client *client,
1360		const struct i2c_device_id *id)
1361{
1362	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1363	struct device *dev = &client->dev;
1364	struct bq24190_platform_data *pdata = client->dev.platform_data;
1365	struct bq24190_dev_info *bdi;
1366	int ret;
1367
1368	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1369		dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1370		return -ENODEV;
1371	}
1372
1373	bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1374	if (!bdi) {
1375		dev_err(dev, "Can't alloc bdi struct\n");
1376		return -ENOMEM;
1377	}
1378
1379	bdi->client = client;
1380	bdi->dev = dev;
1381	bdi->model = id->driver_data;
1382	strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1383	mutex_init(&bdi->f_reg_lock);
1384	bdi->first_time = true;
1385	bdi->charger_health_valid = false;
1386	bdi->battery_health_valid = false;
1387	bdi->battery_status_valid = false;
1388
1389	i2c_set_clientdata(client, bdi);
1390
1391	if (dev->of_node)
1392		ret = bq24190_setup_dt(bdi);
1393	else
1394		ret = bq24190_setup_pdata(bdi, pdata);
1395
1396	if (ret) {
1397		dev_err(dev, "Can't get irq info\n");
1398		return -EINVAL;
1399	}
1400
1401	ret = devm_request_threaded_irq(dev, bdi->irq, NULL,
1402			bq24190_irq_handler_thread,
1403			IRQF_TRIGGER_RISING | IRQF_ONESHOT,
1404			"bq24190-charger", bdi);
1405	if (ret < 0) {
1406		dev_err(dev, "Can't set up irq handler\n");
1407		goto out1;
1408	}
1409
1410	pm_runtime_enable(dev);
1411	pm_runtime_resume(dev);
1412
1413	ret = bq24190_hw_init(bdi);
1414	if (ret < 0) {
1415		dev_err(dev, "Hardware init failed\n");
1416		goto out2;
1417	}
1418
1419	bq24190_charger_init(&bdi->charger);
1420
1421	ret = power_supply_register(dev, &bdi->charger);
1422	if (ret) {
1423		dev_err(dev, "Can't register charger\n");
1424		goto out2;
1425	}
1426
1427	bq24190_battery_init(&bdi->battery);
1428
1429	ret = power_supply_register(dev, &bdi->battery);
1430	if (ret) {
1431		dev_err(dev, "Can't register battery\n");
1432		goto out3;
1433	}
1434
1435	ret = bq24190_sysfs_create_group(bdi);
1436	if (ret) {
1437		dev_err(dev, "Can't create sysfs entries\n");
1438		goto out4;
1439	}
1440
1441	return 0;
1442
1443out4:
1444	power_supply_unregister(&bdi->battery);
1445out3:
1446	power_supply_unregister(&bdi->charger);
1447out2:
1448	pm_runtime_disable(dev);
1449out1:
1450	if (bdi->gpio_int)
1451		gpio_free(bdi->gpio_int);
1452
1453	return ret;
1454}
1455
1456static int bq24190_remove(struct i2c_client *client)
1457{
1458	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1459
1460	pm_runtime_get_sync(bdi->dev);
1461	bq24190_register_reset(bdi);
1462	pm_runtime_put_sync(bdi->dev);
1463
1464	bq24190_sysfs_remove_group(bdi);
1465	power_supply_unregister(&bdi->battery);
1466	power_supply_unregister(&bdi->charger);
1467	pm_runtime_disable(bdi->dev);
1468
1469	if (bdi->gpio_int)
1470		gpio_free(bdi->gpio_int);
1471
1472	return 0;
1473}
1474
1475#ifdef CONFIG_PM_SLEEP
1476static int bq24190_pm_suspend(struct device *dev)
1477{
1478	struct i2c_client *client = to_i2c_client(dev);
1479	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1480
1481	pm_runtime_get_sync(bdi->dev);
1482	bq24190_register_reset(bdi);
1483	pm_runtime_put_sync(bdi->dev);
1484
1485	return 0;
1486}
1487
1488static int bq24190_pm_resume(struct device *dev)
1489{
1490	struct i2c_client *client = to_i2c_client(dev);
1491	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1492
1493	bdi->charger_health_valid = false;
1494	bdi->battery_health_valid = false;
1495	bdi->battery_status_valid = false;
1496
1497	pm_runtime_get_sync(bdi->dev);
1498	bq24190_register_reset(bdi);
1499	pm_runtime_put_sync(bdi->dev);
1500
1501	/* Things may have changed while suspended so alert upper layer */
1502	power_supply_changed(&bdi->charger);
1503	power_supply_changed(&bdi->battery);
1504
1505	return 0;
1506}
1507#endif
1508
1509static SIMPLE_DEV_PM_OPS(bq24190_pm_ops, bq24190_pm_suspend, bq24190_pm_resume);
1510
1511/*
1512 * Only support the bq24190 right now.  The bq24192, bq24192i, and bq24193
1513 * are similar but not identical so the driver needs to be extended to
1514 * support them.
1515 */
1516static const struct i2c_device_id bq24190_i2c_ids[] = {
1517	{ "bq24190", BQ24190_REG_VPRS_PN_24190 },
1518	{ },
1519};
1520
1521#ifdef CONFIG_OF
1522static const struct of_device_id bq24190_of_match[] = {
1523	{ .compatible = "ti,bq24190", },
1524	{ },
1525};
1526MODULE_DEVICE_TABLE(of, bq24190_of_match);
1527#else
1528static const struct of_device_id bq24190_of_match[] = {
1529	{ },
1530};
1531#endif
1532
1533static struct i2c_driver bq24190_driver = {
1534	.probe		= bq24190_probe,
1535	.remove		= bq24190_remove,
1536	.id_table	= bq24190_i2c_ids,
1537	.driver = {
1538		.name		= "bq24190-charger",
1539		.owner		= THIS_MODULE,
1540		.pm		= &bq24190_pm_ops,
1541		.of_match_table	= of_match_ptr(bq24190_of_match),
1542	},
1543};
1544module_i2c_driver(bq24190_driver);
1545
1546MODULE_LICENSE("GPL");
1547MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1548MODULE_ALIAS("i2c:bq24190-charger");
1549MODULE_DESCRIPTION("TI BQ24190 Charger Driver");