PageRenderTime 44ms CodeModel.GetById 16ms app.highlight 24ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/power/bq20z75.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 709 lines | 558 code | 106 blank | 45 comment | 88 complexity | b4b6c7ca55e9f6ac95191191d8b85344 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/*
  2 * Gas Gauge driver for TI's BQ20Z75
  3 *
  4 * Copyright (c) 2010, NVIDIA Corporation.
  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 as published by
  8 * the Free Software Foundation; either version 2 of the License, or
  9 * (at your option) any later version.
 10 *
 11 * This program is distributed in the hope that it will be useful, but WITHOUT
 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 14 * more details.
 15 *
 16 * You should have received a copy of the GNU General Public License along
 17 * with this program; if not, write to the Free Software Foundation, Inc.,
 18 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 19 */
 20
 21#include <linux/init.h>
 22#include <linux/module.h>
 23#include <linux/kernel.h>
 24#include <linux/err.h>
 25#include <linux/power_supply.h>
 26#include <linux/i2c.h>
 27#include <linux/slab.h>
 28#include <linux/interrupt.h>
 29#include <linux/gpio.h>
 30
 31#include <linux/power/bq20z75.h>
 32
 33enum {
 34	REG_MANUFACTURER_DATA,
 35	REG_TEMPERATURE,
 36	REG_VOLTAGE,
 37	REG_CURRENT,
 38	REG_CAPACITY,
 39	REG_TIME_TO_EMPTY,
 40	REG_TIME_TO_FULL,
 41	REG_STATUS,
 42	REG_CYCLE_COUNT,
 43	REG_SERIAL_NUMBER,
 44	REG_REMAINING_CAPACITY,
 45	REG_REMAINING_CAPACITY_CHARGE,
 46	REG_FULL_CHARGE_CAPACITY,
 47	REG_FULL_CHARGE_CAPACITY_CHARGE,
 48	REG_DESIGN_CAPACITY,
 49	REG_DESIGN_CAPACITY_CHARGE,
 50	REG_DESIGN_VOLTAGE,
 51};
 52
 53/* Battery Mode defines */
 54#define BATTERY_MODE_OFFSET		0x03
 55#define BATTERY_MODE_MASK		0x8000
 56enum bq20z75_battery_mode {
 57	BATTERY_MODE_AMPS,
 58	BATTERY_MODE_WATTS
 59};
 60
 61/* manufacturer access defines */
 62#define MANUFACTURER_ACCESS_STATUS	0x0006
 63#define MANUFACTURER_ACCESS_SLEEP	0x0011
 64
 65/* battery status value bits */
 66#define BATTERY_DISCHARGING		0x40
 67#define BATTERY_FULL_CHARGED		0x20
 68#define BATTERY_FULL_DISCHARGED		0x10
 69
 70#define BQ20Z75_DATA(_psp, _addr, _min_value, _max_value) { \
 71	.psp = _psp, \
 72	.addr = _addr, \
 73	.min_value = _min_value, \
 74	.max_value = _max_value, \
 75}
 76
 77static const struct bq20z75_device_data {
 78	enum power_supply_property psp;
 79	u8 addr;
 80	int min_value;
 81	int max_value;
 82} bq20z75_data[] = {
 83	[REG_MANUFACTURER_DATA] =
 84		BQ20Z75_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535),
 85	[REG_TEMPERATURE] =
 86		BQ20Z75_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535),
 87	[REG_VOLTAGE] =
 88		BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_NOW, 0x09, 0, 20000),
 89	[REG_CURRENT] =
 90		BQ20Z75_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768,
 91			32767),
 92	[REG_CAPACITY] =
 93		BQ20Z75_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100),
 94	[REG_REMAINING_CAPACITY] =
 95		BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535),
 96	[REG_REMAINING_CAPACITY_CHARGE] =
 97		BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_NOW, 0x0F, 0, 65535),
 98	[REG_FULL_CHARGE_CAPACITY] =
 99		BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL, 0x10, 0, 65535),
100	[REG_FULL_CHARGE_CAPACITY_CHARGE] =
101		BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL, 0x10, 0, 65535),
102	[REG_TIME_TO_EMPTY] =
103		BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0,
104			65535),
105	[REG_TIME_TO_FULL] =
106		BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0,
107			65535),
108	[REG_STATUS] =
109		BQ20Z75_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535),
110	[REG_CYCLE_COUNT] =
111		BQ20Z75_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535),
112	[REG_DESIGN_CAPACITY] =
113		BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 0x18, 0,
114			65535),
115	[REG_DESIGN_CAPACITY_CHARGE] =
116		BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 0x18, 0,
117			65535),
118	[REG_DESIGN_VOLTAGE] =
119		BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 0x19, 0,
120			65535),
121	[REG_SERIAL_NUMBER] =
122		BQ20Z75_DATA(POWER_SUPPLY_PROP_SERIAL_NUMBER, 0x1C, 0, 65535),
123};
124
125static enum power_supply_property bq20z75_properties[] = {
126	POWER_SUPPLY_PROP_STATUS,
127	POWER_SUPPLY_PROP_HEALTH,
128	POWER_SUPPLY_PROP_PRESENT,
129	POWER_SUPPLY_PROP_TECHNOLOGY,
130	POWER_SUPPLY_PROP_CYCLE_COUNT,
131	POWER_SUPPLY_PROP_VOLTAGE_NOW,
132	POWER_SUPPLY_PROP_CURRENT_NOW,
133	POWER_SUPPLY_PROP_CAPACITY,
134	POWER_SUPPLY_PROP_TEMP,
135	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
136	POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
137	POWER_SUPPLY_PROP_SERIAL_NUMBER,
138	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
139	POWER_SUPPLY_PROP_ENERGY_NOW,
140	POWER_SUPPLY_PROP_ENERGY_FULL,
141	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
142	POWER_SUPPLY_PROP_CHARGE_NOW,
143	POWER_SUPPLY_PROP_CHARGE_FULL,
144	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
145};
146
147struct bq20z75_info {
148	struct i2c_client		*client;
149	struct power_supply		power_supply;
150	struct bq20z75_platform_data	*pdata;
151	bool				is_present;
152	bool				gpio_detect;
153	bool				enable_detection;
154	int				irq;
155};
156
157static int bq20z75_read_word_data(struct i2c_client *client, u8 address)
158{
159	struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
160	s32 ret = 0;
161	int retries = 1;
162
163	if (bq20z75_device->pdata)
164		retries = max(bq20z75_device->pdata->i2c_retry_count + 1, 1);
165
166	while (retries > 0) {
167		ret = i2c_smbus_read_word_data(client, address);
168		if (ret >= 0)
169			break;
170		retries--;
171	}
172
173	if (ret < 0) {
174		dev_dbg(&client->dev,
175			"%s: i2c read at address 0x%x failed\n",
176			__func__, address);
177		return ret;
178	}
179
180	return le16_to_cpu(ret);
181}
182
183static int bq20z75_write_word_data(struct i2c_client *client, u8 address,
184	u16 value)
185{
186	struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
187	s32 ret = 0;
188	int retries = 1;
189
190	if (bq20z75_device->pdata)
191		retries = max(bq20z75_device->pdata->i2c_retry_count + 1, 1);
192
193	while (retries > 0) {
194		ret = i2c_smbus_write_word_data(client, address,
195			le16_to_cpu(value));
196		if (ret >= 0)
197			break;
198		retries--;
199	}
200
201	if (ret < 0) {
202		dev_dbg(&client->dev,
203			"%s: i2c write to address 0x%x failed\n",
204			__func__, address);
205		return ret;
206	}
207
208	return 0;
209}
210
211static int bq20z75_get_battery_presence_and_health(
212	struct i2c_client *client, enum power_supply_property psp,
213	union power_supply_propval *val)
214{
215	s32 ret;
216	struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
217
218	if (psp == POWER_SUPPLY_PROP_PRESENT &&
219		bq20z75_device->gpio_detect) {
220		ret = gpio_get_value(
221			bq20z75_device->pdata->battery_detect);
222		if (ret == bq20z75_device->pdata->battery_detect_present)
223			val->intval = 1;
224		else
225			val->intval = 0;
226		bq20z75_device->is_present = val->intval;
227		return ret;
228	}
229
230	/* Write to ManufacturerAccess with
231	 * ManufacturerAccess command and then
232	 * read the status */
233	ret = bq20z75_write_word_data(client,
234		bq20z75_data[REG_MANUFACTURER_DATA].addr,
235		MANUFACTURER_ACCESS_STATUS);
236	if (ret < 0) {
237		if (psp == POWER_SUPPLY_PROP_PRESENT)
238			val->intval = 0; /* battery removed */
239		return ret;
240	}
241
242	ret = bq20z75_read_word_data(client,
243		bq20z75_data[REG_MANUFACTURER_DATA].addr);
244	if (ret < 0)
245		return ret;
246
247	if (ret < bq20z75_data[REG_MANUFACTURER_DATA].min_value ||
248	    ret > bq20z75_data[REG_MANUFACTURER_DATA].max_value) {
249		val->intval = 0;
250		return 0;
251	}
252
253	/* Mask the upper nibble of 2nd byte and
254	 * lower byte of response then
255	 * shift the result by 8 to get status*/
256	ret &= 0x0F00;
257	ret >>= 8;
258	if (psp == POWER_SUPPLY_PROP_PRESENT) {
259		if (ret == 0x0F)
260			/* battery removed */
261			val->intval = 0;
262		else
263			val->intval = 1;
264	} else if (psp == POWER_SUPPLY_PROP_HEALTH) {
265		if (ret == 0x09)
266			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
267		else if (ret == 0x0B)
268			val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
269		else if (ret == 0x0C)
270			val->intval = POWER_SUPPLY_HEALTH_DEAD;
271		else
272			val->intval = POWER_SUPPLY_HEALTH_GOOD;
273	}
274
275	return 0;
276}
277
278static int bq20z75_get_battery_property(struct i2c_client *client,
279	int reg_offset, enum power_supply_property psp,
280	union power_supply_propval *val)
281{
282	s32 ret;
283
284	ret = bq20z75_read_word_data(client,
285		bq20z75_data[reg_offset].addr);
286	if (ret < 0)
287		return ret;
288
289	/* returned values are 16 bit */
290	if (bq20z75_data[reg_offset].min_value < 0)
291		ret = (s16)ret;
292
293	if (ret >= bq20z75_data[reg_offset].min_value &&
294	    ret <= bq20z75_data[reg_offset].max_value) {
295		val->intval = ret;
296		if (psp == POWER_SUPPLY_PROP_STATUS) {
297			if (ret & BATTERY_FULL_CHARGED)
298				val->intval = POWER_SUPPLY_STATUS_FULL;
299			else if (ret & BATTERY_FULL_DISCHARGED)
300				val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
301			else if (ret & BATTERY_DISCHARGING)
302				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
303			else
304				val->intval = POWER_SUPPLY_STATUS_CHARGING;
305		}
306	} else {
307		if (psp == POWER_SUPPLY_PROP_STATUS)
308			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
309		else
310			val->intval = 0;
311	}
312
313	return 0;
314}
315
316static void  bq20z75_unit_adjustment(struct i2c_client *client,
317	enum power_supply_property psp, union power_supply_propval *val)
318{
319#define BASE_UNIT_CONVERSION		1000
320#define BATTERY_MODE_CAP_MULT_WATT	(10 * BASE_UNIT_CONVERSION)
321#define TIME_UNIT_CONVERSION		60
322#define TEMP_KELVIN_TO_CELSIUS		2731
323	switch (psp) {
324	case POWER_SUPPLY_PROP_ENERGY_NOW:
325	case POWER_SUPPLY_PROP_ENERGY_FULL:
326	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
327		/* bq20z75 provides energy in units of 10mWh.
328		 * Convert to µWh
329		 */
330		val->intval *= BATTERY_MODE_CAP_MULT_WATT;
331		break;
332
333	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
334	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
335	case POWER_SUPPLY_PROP_CURRENT_NOW:
336	case POWER_SUPPLY_PROP_CHARGE_NOW:
337	case POWER_SUPPLY_PROP_CHARGE_FULL:
338	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
339		val->intval *= BASE_UNIT_CONVERSION;
340		break;
341
342	case POWER_SUPPLY_PROP_TEMP:
343		/* bq20z75 provides battery temperature in 0.1K
344		 * so convert it to 0.1°C
345		 */
346		val->intval -= TEMP_KELVIN_TO_CELSIUS;
347		break;
348
349	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
350	case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
351		/* bq20z75 provides time to empty and time to full in minutes.
352		 * Convert to seconds
353		 */
354		val->intval *= TIME_UNIT_CONVERSION;
355		break;
356
357	default:
358		dev_dbg(&client->dev,
359			"%s: no need for unit conversion %d\n", __func__, psp);
360	}
361}
362
363static enum bq20z75_battery_mode
364bq20z75_set_battery_mode(struct i2c_client *client,
365	enum bq20z75_battery_mode mode)
366{
367	int ret, original_val;
368
369	original_val = bq20z75_read_word_data(client, BATTERY_MODE_OFFSET);
370	if (original_val < 0)
371		return original_val;
372
373	if ((original_val & BATTERY_MODE_MASK) == mode)
374		return mode;
375
376	if (mode == BATTERY_MODE_AMPS)
377		ret = original_val & ~BATTERY_MODE_MASK;
378	else
379		ret = original_val | BATTERY_MODE_MASK;
380
381	ret = bq20z75_write_word_data(client, BATTERY_MODE_OFFSET, ret);
382	if (ret < 0)
383		return ret;
384
385	return original_val & BATTERY_MODE_MASK;
386}
387
388static int bq20z75_get_battery_capacity(struct i2c_client *client,
389	int reg_offset, enum power_supply_property psp,
390	union power_supply_propval *val)
391{
392	s32 ret;
393	enum bq20z75_battery_mode mode = BATTERY_MODE_WATTS;
394
395	if (power_supply_is_amp_property(psp))
396		mode = BATTERY_MODE_AMPS;
397
398	mode = bq20z75_set_battery_mode(client, mode);
399	if (mode < 0)
400		return mode;
401
402	ret = bq20z75_read_word_data(client, bq20z75_data[reg_offset].addr);
403	if (ret < 0)
404		return ret;
405
406	if (psp == POWER_SUPPLY_PROP_CAPACITY) {
407		/* bq20z75 spec says that this can be >100 %
408		* even if max value is 100 % */
409		val->intval = min(ret, 100);
410	} else
411		val->intval = ret;
412
413	ret = bq20z75_set_battery_mode(client, mode);
414	if (ret < 0)
415		return ret;
416
417	return 0;
418}
419
420static char bq20z75_serial[5];
421static int bq20z75_get_battery_serial_number(struct i2c_client *client,
422	union power_supply_propval *val)
423{
424	int ret;
425
426	ret = bq20z75_read_word_data(client,
427		bq20z75_data[REG_SERIAL_NUMBER].addr);
428	if (ret < 0)
429		return ret;
430
431	ret = sprintf(bq20z75_serial, "%04x", ret);
432	val->strval = bq20z75_serial;
433
434	return 0;
435}
436
437static int bq20z75_get_property_index(struct i2c_client *client,
438	enum power_supply_property psp)
439{
440	int count;
441	for (count = 0; count < ARRAY_SIZE(bq20z75_data); count++)
442		if (psp == bq20z75_data[count].psp)
443			return count;
444
445	dev_warn(&client->dev,
446		"%s: Invalid Property - %d\n", __func__, psp);
447
448	return -EINVAL;
449}
450
451static int bq20z75_get_property(struct power_supply *psy,
452	enum power_supply_property psp,
453	union power_supply_propval *val)
454{
455	int ret = 0;
456	struct bq20z75_info *bq20z75_device = container_of(psy,
457				struct bq20z75_info, power_supply);
458	struct i2c_client *client = bq20z75_device->client;
459
460	switch (psp) {
461	case POWER_SUPPLY_PROP_PRESENT:
462	case POWER_SUPPLY_PROP_HEALTH:
463		ret = bq20z75_get_battery_presence_and_health(client, psp, val);
464		if (psp == POWER_SUPPLY_PROP_PRESENT)
465			return 0;
466		break;
467
468	case POWER_SUPPLY_PROP_TECHNOLOGY:
469		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
470		break;
471
472	case POWER_SUPPLY_PROP_ENERGY_NOW:
473	case POWER_SUPPLY_PROP_ENERGY_FULL:
474	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
475	case POWER_SUPPLY_PROP_CHARGE_NOW:
476	case POWER_SUPPLY_PROP_CHARGE_FULL:
477	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
478	case POWER_SUPPLY_PROP_CAPACITY:
479		ret = bq20z75_get_property_index(client, psp);
480		if (ret < 0)
481			break;
482
483		ret = bq20z75_get_battery_capacity(client, ret, psp, val);
484		break;
485
486	case POWER_SUPPLY_PROP_SERIAL_NUMBER:
487		ret = bq20z75_get_battery_serial_number(client, val);
488		break;
489
490	case POWER_SUPPLY_PROP_STATUS:
491	case POWER_SUPPLY_PROP_CYCLE_COUNT:
492	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
493	case POWER_SUPPLY_PROP_CURRENT_NOW:
494	case POWER_SUPPLY_PROP_TEMP:
495	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
496	case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
497	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
498		ret = bq20z75_get_property_index(client, psp);
499		if (ret < 0)
500			break;
501
502		ret = bq20z75_get_battery_property(client, ret, psp, val);
503		break;
504
505	default:
506		dev_err(&client->dev,
507			"%s: INVALID property\n", __func__);
508		return -EINVAL;
509	}
510
511	if (!bq20z75_device->enable_detection)
512		goto done;
513
514	if (!bq20z75_device->gpio_detect &&
515		bq20z75_device->is_present != (ret >= 0)) {
516		bq20z75_device->is_present = (ret >= 0);
517		power_supply_changed(&bq20z75_device->power_supply);
518	}
519
520done:
521	if (!ret) {
522		/* Convert units to match requirements for power supply class */
523		bq20z75_unit_adjustment(client, psp, val);
524	}
525
526	dev_dbg(&client->dev,
527		"%s: property = %d, value = %x\n", __func__, psp, val->intval);
528
529	if (ret && bq20z75_device->is_present)
530		return ret;
531
532	/* battery not present, so return NODATA for properties */
533	if (ret)
534		return -ENODATA;
535
536	return 0;
537}
538
539static irqreturn_t bq20z75_irq(int irq, void *devid)
540{
541	struct power_supply *battery = devid;
542
543	power_supply_changed(battery);
544
545	return IRQ_HANDLED;
546}
547
548static int __devinit bq20z75_probe(struct i2c_client *client,
549	const struct i2c_device_id *id)
550{
551	struct bq20z75_info *bq20z75_device;
552	struct bq20z75_platform_data *pdata = client->dev.platform_data;
553	int rc;
554	int irq;
555
556	bq20z75_device = kzalloc(sizeof(struct bq20z75_info), GFP_KERNEL);
557	if (!bq20z75_device)
558		return -ENOMEM;
559
560	bq20z75_device->client = client;
561	bq20z75_device->enable_detection = false;
562	bq20z75_device->gpio_detect = false;
563	bq20z75_device->power_supply.name = "battery";
564	bq20z75_device->power_supply.type = POWER_SUPPLY_TYPE_BATTERY;
565	bq20z75_device->power_supply.properties = bq20z75_properties;
566	bq20z75_device->power_supply.num_properties =
567		ARRAY_SIZE(bq20z75_properties);
568	bq20z75_device->power_supply.get_property = bq20z75_get_property;
569
570	if (pdata) {
571		bq20z75_device->gpio_detect =
572			gpio_is_valid(pdata->battery_detect);
573		bq20z75_device->pdata = pdata;
574	}
575
576	i2c_set_clientdata(client, bq20z75_device);
577
578	if (!bq20z75_device->gpio_detect)
579		goto skip_gpio;
580
581	rc = gpio_request(pdata->battery_detect, dev_name(&client->dev));
582	if (rc) {
583		dev_warn(&client->dev, "Failed to request gpio: %d\n", rc);
584		bq20z75_device->gpio_detect = false;
585		goto skip_gpio;
586	}
587
588	rc = gpio_direction_input(pdata->battery_detect);
589	if (rc) {
590		dev_warn(&client->dev, "Failed to get gpio as input: %d\n", rc);
591		gpio_free(pdata->battery_detect);
592		bq20z75_device->gpio_detect = false;
593		goto skip_gpio;
594	}
595
596	irq = gpio_to_irq(pdata->battery_detect);
597	if (irq <= 0) {
598		dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
599		gpio_free(pdata->battery_detect);
600		bq20z75_device->gpio_detect = false;
601		goto skip_gpio;
602	}
603
604	rc = request_irq(irq, bq20z75_irq,
605		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
606		dev_name(&client->dev), &bq20z75_device->power_supply);
607	if (rc) {
608		dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
609		gpio_free(pdata->battery_detect);
610		bq20z75_device->gpio_detect = false;
611		goto skip_gpio;
612	}
613
614	bq20z75_device->irq = irq;
615
616skip_gpio:
617
618	rc = power_supply_register(&client->dev, &bq20z75_device->power_supply);
619	if (rc) {
620		dev_err(&client->dev,
621			"%s: Failed to register power supply\n", __func__);
622		goto exit_psupply;
623	}
624
625	dev_info(&client->dev,
626		"%s: battery gas gauge device registered\n", client->name);
627
628	return 0;
629
630exit_psupply:
631	if (bq20z75_device->irq)
632		free_irq(bq20z75_device->irq, &bq20z75_device->power_supply);
633	if (bq20z75_device->gpio_detect)
634		gpio_free(pdata->battery_detect);
635
636	kfree(bq20z75_device);
637
638	return rc;
639}
640
641static int __devexit bq20z75_remove(struct i2c_client *client)
642{
643	struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
644
645	if (bq20z75_device->irq)
646		free_irq(bq20z75_device->irq, &bq20z75_device->power_supply);
647	if (bq20z75_device->gpio_detect)
648		gpio_free(bq20z75_device->pdata->battery_detect);
649
650	power_supply_unregister(&bq20z75_device->power_supply);
651	kfree(bq20z75_device);
652	bq20z75_device = NULL;
653
654	return 0;
655}
656
657#if defined CONFIG_PM
658static int bq20z75_suspend(struct i2c_client *client,
659	pm_message_t state)
660{
661	struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
662	s32 ret;
663
664	/* write to manufacturer access with sleep command */
665	ret = bq20z75_write_word_data(client,
666		bq20z75_data[REG_MANUFACTURER_DATA].addr,
667		MANUFACTURER_ACCESS_SLEEP);
668	if (bq20z75_device->is_present && ret < 0)
669		return ret;
670
671	return 0;
672}
673#else
674#define bq20z75_suspend		NULL
675#endif
676/* any smbus transaction will wake up bq20z75 */
677#define bq20z75_resume		NULL
678
679static const struct i2c_device_id bq20z75_id[] = {
680	{ "bq20z75", 0 },
681	{}
682};
683MODULE_DEVICE_TABLE(i2c, bq20z75_id);
684
685static struct i2c_driver bq20z75_battery_driver = {
686	.probe		= bq20z75_probe,
687	.remove		= __devexit_p(bq20z75_remove),
688	.suspend	= bq20z75_suspend,
689	.resume		= bq20z75_resume,
690	.id_table	= bq20z75_id,
691	.driver = {
692		.name	= "bq20z75-battery",
693	},
694};
695
696static int __init bq20z75_battery_init(void)
697{
698	return i2c_add_driver(&bq20z75_battery_driver);
699}
700module_init(bq20z75_battery_init);
701
702static void __exit bq20z75_battery_exit(void)
703{
704	i2c_del_driver(&bq20z75_battery_driver);
705}
706module_exit(bq20z75_battery_exit);
707
708MODULE_DESCRIPTION("BQ20z75 battery monitor driver");
709MODULE_LICENSE("GPL");