/*
 * Battery driver for CPCAP PMIC
 *
 * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
 *
 * Some parts of the code based on earlie Motorola mapphone Linux kernel
 * drivers:
 *
 * Copyright (C) 2009-2010 Motorola, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.

 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/reboot.h>
#include <linux/regmap.h>

#include <linux/iio/consumer.h>
#include <linux/iio/types.h>
#include <linux/mfd/motorola-cpcap.h>

/*
 * Register bit defines for CPCAP_REG_BPEOL. Some of these seem to
 * map to MC13783UG.pdf "Table 5-19. Register 13, Power Control 0"
 * to enable BATTDETEN, LOBAT and EOL features. We currently use
 * LOBAT interrupts instead of EOL.
 */
#define CPCAP_REG_BPEOL_BIT_EOL9	BIT(9)	/* Set for EOL irq */
#define CPCAP_REG_BPEOL_BIT_EOL8	BIT(8)	/* Set for EOL irq */
#define CPCAP_REG_BPEOL_BIT_UNKNOWN7	BIT(7)
#define CPCAP_REG_BPEOL_BIT_UNKNOWN6	BIT(6)
#define CPCAP_REG_BPEOL_BIT_UNKNOWN5	BIT(5)
#define CPCAP_REG_BPEOL_BIT_EOL_MULTI	BIT(4)	/* Set for multiple EOL irqs */
#define CPCAP_REG_BPEOL_BIT_UNKNOWN3	BIT(3)
#define CPCAP_REG_BPEOL_BIT_UNKNOWN2	BIT(2)
#define CPCAP_REG_BPEOL_BIT_BATTDETEN	BIT(1)	/* Enable battery detect */
#define CPCAP_REG_BPEOL_BIT_EOLSEL	BIT(0)	/* BPDET = 0, EOL = 1 */

/*
 * Register bit defines for CPCAP_REG_CCC1. These seem similar to the twl6030
 * coulomb counter registers rather than the mc13892 registers. Both twl6030
 * and mc13892 set bits 2 and 1 to reset and clear registers. But mc13892
 * sets bit 0 to start the coulomb counter while twl6030 sets bit 0 to stop
 * the coulomb counter like cpcap does. So for now, we use the twl6030 style
 * naming for the registers.
 */
#define CPCAP_REG_CCC1_ACTIVE_MODE1	BIT(4)	/* Update rate */
#define CPCAP_REG_CCC1_ACTIVE_MODE0	BIT(3)	/* Update rate */
#define CPCAP_REG_CCC1_AUTOCLEAR	BIT(2)	/* Resets sample registers */
#define CPCAP_REG_CCC1_CAL_EN		BIT(1)	/* Clears after write in 1s */
#define CPCAP_REG_CCC1_PAUSE		BIT(0)	/* Stop counters, allow write */
#define CPCAP_REG_CCC1_RESET_MASK	(CPCAP_REG_CCC1_AUTOCLEAR | \
					 CPCAP_REG_CCC1_CAL_EN)

#define CPCAP_REG_CCCC2_RATE1		BIT(5)
#define CPCAP_REG_CCCC2_RATE0		BIT(4)
#define CPCAP_REG_CCCC2_ENABLE		BIT(3)

#define CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS	250

enum {
	CPCAP_BATTERY_IIO_BATTDET,
	CPCAP_BATTERY_IIO_VOLTAGE,
	CPCAP_BATTERY_IIO_CHRG_CURRENT,
	CPCAP_BATTERY_IIO_BATT_CURRENT,
	CPCAP_BATTERY_IIO_NR,
};

enum cpcap_battery_irq_action {
	CPCAP_BATTERY_IRQ_ACTION_NONE,
	CPCAP_BATTERY_IRQ_ACTION_CC_CAL_DONE,
	CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW,
	CPCAP_BATTERY_IRQ_ACTION_POWEROFF,
};

struct cpcap_interrupt_desc {
	const char *name;
	struct list_head node;
	int irq;
	enum cpcap_battery_irq_action action;
};

struct cpcap_battery_config {
	int cd_factor;
	struct power_supply_info info;
	struct power_supply_battery_info bat;
};

struct cpcap_coulomb_counter_data {
	s32 sample;		/* 24 or 32 bits */
	s32 accumulator;
	s16 offset;		/* 9 bits */
	s16 integrator;		/* 13 or 16 bits */
};

enum cpcap_battery_state {
	CPCAP_BATTERY_STATE_PREVIOUS,
	CPCAP_BATTERY_STATE_LATEST,
	CPCAP_BATTERY_STATE_NR,
};

struct cpcap_battery_state_data {
	int voltage;
	int current_ua;
	int counter_uah;
	int temperature;
	ktime_t time;
	struct cpcap_coulomb_counter_data cc;
};

struct cpcap_battery_ddata {
	struct device *dev;
	struct regmap *reg;
	struct list_head irq_list;
	struct iio_channel *channels[CPCAP_BATTERY_IIO_NR];
	struct power_supply *psy;
	struct cpcap_battery_config config;
	struct cpcap_battery_state_data state[CPCAP_BATTERY_STATE_NR];
	u32 cc_lsb;		/* μAms per LSB */
	atomic_t active;
	int status;
	u16 vendor;
};

#define CPCAP_NO_BATTERY	-400

static struct cpcap_battery_state_data *
cpcap_battery_get_state(struct cpcap_battery_ddata *ddata,
			enum cpcap_battery_state state)
{
	if (state >= CPCAP_BATTERY_STATE_NR)
		return NULL;

	return &ddata->state[state];
}

static struct cpcap_battery_state_data *
cpcap_battery_latest(struct cpcap_battery_ddata *ddata)
{
	return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_LATEST);
}

static struct cpcap_battery_state_data *
cpcap_battery_previous(struct cpcap_battery_ddata *ddata)
{
	return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_PREVIOUS);
}

static int cpcap_charger_battery_temperature(struct cpcap_battery_ddata *ddata,
					     int *value)
{
	struct iio_channel *channel;
	int error;

	channel = ddata->channels[CPCAP_BATTERY_IIO_BATTDET];
	error = iio_read_channel_processed(channel, value);
	if (error < 0) {
		dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
		*value = CPCAP_NO_BATTERY;

		return error;
	}

	*value /= 100;

	return 0;
}

static int cpcap_battery_get_voltage(struct cpcap_battery_ddata *ddata)
{
	struct iio_channel *channel;
	int error, value = 0;

	channel = ddata->channels[CPCAP_BATTERY_IIO_VOLTAGE];
	error = iio_read_channel_processed(channel, &value);
	if (error < 0) {
		dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);

		return 0;
	}

	return value * 1000;
}

static int cpcap_battery_get_current(struct cpcap_battery_ddata *ddata)
{
	struct iio_channel *channel;
	int error, value = 0;

	channel = ddata->channels[CPCAP_BATTERY_IIO_BATT_CURRENT];
	error = iio_read_channel_processed(channel, &value);
	if (error < 0) {
		dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);

		return 0;
	}

	return value * 1000;
}

/**
 * cpcap_battery_cc_raw_div - calculate and divide coulomb counter μAms values
 * @ddata: device driver data
 * @sample: coulomb counter sample value
 * @accumulator: coulomb counter integrator value
 * @offset: coulomb counter offset value
 * @divider: conversion divider
 *
 * Note that cc_lsb and cc_dur values are from Motorola Linux kernel
 * function data_get_avg_curr_ua() and seem to be based on measured test
 * results. It also has the following comment:
 *
 * Adjustment factors are applied here as a temp solution per the test
 * results. Need to work out a formal solution for this adjustment.
 *
 * A coulomb counter for similar hardware seems to be documented in
 * "TWL6030 Gas Gauging Basics (Rev. A)" swca095a.pdf in chapter
 * "10 Calculating Accumulated Current". We however follow what the
 * Motorola mapphone Linux kernel is doing as there may be either a
 * TI or ST coulomb counter in the PMIC.
 */
static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata,
				    s32 sample, s32 accumulator,
				    s16 offset, u32 divider)
{
	s64 acc;

	if (!divider)
		return 0;

	acc = accumulator;
	acc -= (s64)sample * offset;
	acc *= ddata->cc_lsb;
	acc *= -1;
	acc = div_s64(acc, divider);

	return acc;
}

/* 3600000μAms = 1μAh */
static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata,
				   s32 sample, s32 accumulator,
				   s16 offset)
{
	return cpcap_battery_cc_raw_div(ddata, sample,
					accumulator, offset,
					3600000);
}

static int cpcap_battery_cc_to_ua(struct cpcap_battery_ddata *ddata,
				  s32 sample, s32 accumulator,
				  s16 offset)
{
	return cpcap_battery_cc_raw_div(ddata, sample,
					accumulator, offset,
					sample *
					CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS);
}

/**
 * cpcap_battery_read_accumulated - reads cpcap coulomb counter
 * @ddata: device driver data
 * @ccd: coulomb counter values
 *
 * Based on Motorola mapphone kernel function data_read_regs().
 * Looking at the registers, the coulomb counter seems similar to
 * the coulomb counter in TWL6030. See "TWL6030 Gas Gauging Basics
 * (Rev. A) swca095a.pdf for "10 Calculating Accumulated Current".
 *
 * Note that swca095a.pdf instructs to stop the coulomb counter
 * before reading to avoid values changing. Motorola mapphone
 * Linux kernel does not do it, so let's assume they've verified
 * the data produced is correct.
 */
static int
cpcap_battery_read_accumulated(struct cpcap_battery_ddata *ddata,
			       struct cpcap_coulomb_counter_data *ccd)
{
	u16 buf[7];	/* CPCAP_REG_CCS1 to CCI */
	int error;

	ccd->sample = 0;
	ccd->accumulator = 0;
	ccd->offset = 0;
	ccd->integrator = 0;

	/* Read coulomb counter register range */
	error = regmap_bulk_read(ddata->reg, CPCAP_REG_CCS1,
				 buf, ARRAY_SIZE(buf));
	if (error)
		return 0;

	/* Sample value CPCAP_REG_CCS1 & 2 */
	ccd->sample = (buf[1] & 0x0fff) << 16;
	ccd->sample |= buf[0];
	if (ddata->vendor == CPCAP_VENDOR_TI)
		ccd->sample = sign_extend32(24, ccd->sample);

	/* Accumulator value CPCAP_REG_CCA1 & 2 */
	ccd->accumulator = ((s16)buf[3]) << 16;
	ccd->accumulator |= buf[2];

	/*
	 * Coulomb counter calibration offset is CPCAP_REG_CCM,
	 * REG_CCO seems unused
	 */
	ccd->offset = buf[4];
	ccd->offset = sign_extend32(ccd->offset, 9);

	/* Integrator register CPCAP_REG_CCI */
	if (ddata->vendor == CPCAP_VENDOR_TI)
		ccd->integrator = sign_extend32(buf[6], 13);
	else
		ccd->integrator = (s16)buf[6];

	return cpcap_battery_cc_to_uah(ddata,
				       ccd->sample,
				       ccd->accumulator,
				       ccd->offset);
}

/**
 * cpcap_battery_cc_get_avg_current - read cpcap coulumb counter
 * @ddata: cpcap battery driver device data
 */
static int cpcap_battery_cc_get_avg_current(struct cpcap_battery_ddata *ddata)
{
	int value, acc, error;
	s32 sample;
	s16 offset;

	/* Coulomb counter integrator */
	error = regmap_read(ddata->reg, CPCAP_REG_CCI, &value);
	if (error)
		return error;

	if (ddata->vendor == CPCAP_VENDOR_TI) {
		acc = sign_extend32(value, 13);
		sample = 1;
	} else {
		acc = (s16)value;
		sample = 4;
	}

	/* Coulomb counter calibration offset  */
	error = regmap_read(ddata->reg, CPCAP_REG_CCM, &value);
	if (error)
		return error;

	offset = sign_extend32(value, 9);

	return cpcap_battery_cc_to_ua(ddata, sample, acc, offset);
}

static bool cpcap_battery_full(struct cpcap_battery_ddata *ddata)
{
	struct cpcap_battery_state_data *state = cpcap_battery_latest(ddata);

	if (state->voltage >=
	    (ddata->config.bat.constant_charge_voltage_max_uv - 18000))
		return true;

	return false;
}

static int cpcap_battery_update_status(struct cpcap_battery_ddata *ddata)
{
	struct cpcap_battery_state_data state, *latest, *previous;
	ktime_t now;
	int error;

	memset(&state, 0, sizeof(state));
	now = ktime_get();

	latest = cpcap_battery_latest(ddata);
	if (latest) {
		s64 delta_ms = ktime_to_ms(ktime_sub(now, latest->time));

		if (delta_ms < CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS)
			return delta_ms;
	}

	state.time = now;
	state.voltage = cpcap_battery_get_voltage(ddata);
	state.current_ua = cpcap_battery_get_current(ddata);
	state.counter_uah = cpcap_battery_read_accumulated(ddata, &state.cc);

	error = cpcap_charger_battery_temperature(ddata,
						  &state.temperature);
	if (error)
		return error;

	previous = cpcap_battery_previous(ddata);
	memcpy(previous, latest, sizeof(*previous));
	memcpy(latest, &state, sizeof(*latest));

	return 0;
}

static enum power_supply_property cpcap_battery_props[] = {
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_TECHNOLOGY,
	POWER_SUPPLY_PROP_VOLTAGE_NOW,
	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
	POWER_SUPPLY_PROP_CURRENT_AVG,
	POWER_SUPPLY_PROP_CURRENT_NOW,
	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
	POWER_SUPPLY_PROP_CHARGE_COUNTER,
	POWER_SUPPLY_PROP_POWER_NOW,
	POWER_SUPPLY_PROP_POWER_AVG,
	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
	POWER_SUPPLY_PROP_SCOPE,
	POWER_SUPPLY_PROP_TEMP,
};

static int cpcap_battery_get_property(struct power_supply *psy,
				      enum power_supply_property psp,
				      union power_supply_propval *val)
{
	struct cpcap_battery_ddata *ddata = power_supply_get_drvdata(psy);
	struct cpcap_battery_state_data *latest, *previous;
	u32 sample;
	s32 accumulator;
	int cached;
	s64 tmp;

	cached = cpcap_battery_update_status(ddata);
	if (cached < 0)
		return cached;

	latest = cpcap_battery_latest(ddata);
	previous = cpcap_battery_previous(ddata);

	switch (psp) {
	case POWER_SUPPLY_PROP_PRESENT:
		if (latest->temperature > CPCAP_NO_BATTERY)
			val->intval = 1;
		else
			val->intval = 0;
		break;
	case POWER_SUPPLY_PROP_STATUS:
		if (cpcap_battery_full(ddata)) {
			val->intval = POWER_SUPPLY_STATUS_FULL;
			break;
		}
		if (cpcap_battery_cc_get_avg_current(ddata) < 0)
			val->intval = POWER_SUPPLY_STATUS_CHARGING;
		else
			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
		break;
	case POWER_SUPPLY_PROP_TECHNOLOGY:
		val->intval = ddata->config.info.technology;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		val->intval = cpcap_battery_get_voltage(ddata);
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
		val->intval = ddata->config.info.voltage_max_design;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
		val->intval = ddata->config.info.voltage_min_design;
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
		val->intval = ddata->config.bat.constant_charge_voltage_max_uv;
		break;
	case POWER_SUPPLY_PROP_CURRENT_AVG:
		sample = latest->cc.sample - previous->cc.sample;
		if (!sample) {
			val->intval = cpcap_battery_cc_get_avg_current(ddata);
			break;
		}
		accumulator = latest->cc.accumulator - previous->cc.accumulator;
		val->intval = cpcap_battery_cc_to_ua(ddata, sample,
						     accumulator,
						     latest->cc.offset);
		break;
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		val->intval = latest->current_ua;
		break;
	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
		val->intval = latest->counter_uah;
		break;
	case POWER_SUPPLY_PROP_POWER_NOW:
		tmp = (latest->voltage / 10000) * latest->current_ua;
		val->intval = div64_s64(tmp, 100);
		break;
	case POWER_SUPPLY_PROP_POWER_AVG:
		sample = latest->cc.sample - previous->cc.sample;
		if (!sample) {
			tmp = cpcap_battery_cc_get_avg_current(ddata);
			tmp *= (latest->voltage / 10000);
			val->intval = div64_s64(tmp, 100);
			break;
		}
		accumulator = latest->cc.accumulator - previous->cc.accumulator;
		tmp = cpcap_battery_cc_to_ua(ddata, sample, accumulator,
					     latest->cc.offset);
		tmp *= ((latest->voltage + previous->voltage) / 20000);
		val->intval = div64_s64(tmp, 100);
		break;
	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
		if (cpcap_battery_full(ddata))
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
		else if (latest->voltage >= 3750000)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
		else if (latest->voltage >= 3300000)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
		else if (latest->voltage > 3100000)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
		else if (latest->voltage <= 3100000)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
		else
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
		val->intval = ddata->config.info.charge_full_design;
		break;
	case POWER_SUPPLY_PROP_SCOPE:
		val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
		break;
	case POWER_SUPPLY_PROP_TEMP:
		val->intval = latest->temperature;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int cpcap_battery_update_charger(struct cpcap_battery_ddata *ddata,
					int const_charge_voltage)
{
	union power_supply_propval prop;
	union power_supply_propval val;
	struct power_supply *charger;
	int error;

	charger = power_supply_get_by_name("usb");
	if (!charger)
		return -ENODEV;

	error = power_supply_get_property(charger,
				POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
				&prop);
	if (error)
		return error;

	/* Allow charger const voltage lower than battery const voltage */
	if (const_charge_voltage > prop.intval)
		return 0;

	val.intval = const_charge_voltage;

	return power_supply_set_property(charger,
			POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
			&val);
}

static int cpcap_battery_set_property(struct power_supply *psy,
				      enum power_supply_property psp,
				      const union power_supply_propval *val)
{
	struct cpcap_battery_ddata *ddata = power_supply_get_drvdata(psy);

	switch (psp) {
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
		if (val->intval < ddata->config.info.voltage_min_design)
			return -EINVAL;
		if (val->intval > ddata->config.info.voltage_max_design)
			return -EINVAL;

		ddata->config.bat.constant_charge_voltage_max_uv = val->intval;

		return cpcap_battery_update_charger(ddata, val->intval);
	default:
		return -EINVAL;
	}

	return 0;
}

static int cpcap_battery_property_is_writeable(struct power_supply *psy,
					       enum power_supply_property psp)
{
	switch (psp) {
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
		return 1;
	default:
		return 0;
	}
}

static irqreturn_t cpcap_battery_irq_thread(int irq, void *data)
{
	struct cpcap_battery_ddata *ddata = data;
	struct cpcap_battery_state_data *latest;
	struct cpcap_interrupt_desc *d;

	if (!atomic_read(&ddata->active))
		return IRQ_NONE;

	list_for_each_entry(d, &ddata->irq_list, node) {
		if (irq == d->irq)
			break;
	}

	if (!d)
		return IRQ_NONE;

	latest = cpcap_battery_latest(ddata);

	switch (d->action) {
	case CPCAP_BATTERY_IRQ_ACTION_CC_CAL_DONE:
		dev_info(ddata->dev, "Coulomb counter calibration done\n");
		break;
	case CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW:
		if (latest->current_ua >= 0)
			dev_warn(ddata->dev, "Battery low at %imV!\n",
				latest->voltage / 1000);
		break;
	case CPCAP_BATTERY_IRQ_ACTION_POWEROFF:
		if (latest->current_ua >= 0 && latest->voltage <= 3200000) {
			dev_emerg(ddata->dev,
				  "Battery empty at %imV, powering off\n",
				  latest->voltage / 1000);
			orderly_poweroff(true);
		}
		break;
	default:
		break;
	}

	power_supply_changed(ddata->psy);

	return IRQ_HANDLED;
}

static int cpcap_battery_init_irq(struct platform_device *pdev,
				  struct cpcap_battery_ddata *ddata,
				  const char *name)
{
	struct cpcap_interrupt_desc *d;
	int irq, error;

	irq = platform_get_irq_byname(pdev, name);
	if (irq < 0)
		return irq;

	error = devm_request_threaded_irq(ddata->dev, irq, NULL,
					  cpcap_battery_irq_thread,
					  IRQF_SHARED,
					  name, ddata);
	if (error) {
		dev_err(ddata->dev, "could not get irq %s: %i\n",
			name, error);

		return error;
	}

	d = devm_kzalloc(ddata->dev, sizeof(*d), GFP_KERNEL);
	if (!d)
		return -ENOMEM;

	d->name = name;
	d->irq = irq;

	if (!strncmp(name, "cccal", 5))
		d->action = CPCAP_BATTERY_IRQ_ACTION_CC_CAL_DONE;
	else if (!strncmp(name, "lowbph", 6))
		d->action = CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW;
	else if (!strncmp(name, "lowbpl", 6))
		d->action = CPCAP_BATTERY_IRQ_ACTION_POWEROFF;

	list_add(&d->node, &ddata->irq_list);

	return 0;
}

static int cpcap_battery_init_interrupts(struct platform_device *pdev,
					 struct cpcap_battery_ddata *ddata)
{
	static const char * const cpcap_battery_irqs[] = {
		"eol", "lowbph", "lowbpl",
		"chrgcurr1", "battdetb"
	};
	int i, error;

	for (i = 0; i < ARRAY_SIZE(cpcap_battery_irqs); i++) {
		error = cpcap_battery_init_irq(pdev, ddata,
					       cpcap_battery_irqs[i]);
		if (error)
			return error;
	}

	/* Enable calibration interrupt if already available in dts */
	cpcap_battery_init_irq(pdev, ddata, "cccal");

	/* Enable low battery interrupts for 3.3V high and 3.1V low */
	error = regmap_update_bits(ddata->reg, CPCAP_REG_BPEOL,
				   0xffff,
				   CPCAP_REG_BPEOL_BIT_BATTDETEN);
	if (error)
		return error;

	return 0;
}

static int cpcap_battery_init_iio(struct cpcap_battery_ddata *ddata)
{
	const char * const names[CPCAP_BATTERY_IIO_NR] = {
		"battdetb", "battp", "chg_isense", "batti",
	};
	int error, i;

	for (i = 0; i < CPCAP_BATTERY_IIO_NR; i++) {
		ddata->channels[i] = devm_iio_channel_get(ddata->dev,
							  names[i]);
		if (IS_ERR(ddata->channels[i])) {
			error = PTR_ERR(ddata->channels[i]);
			goto out_err;
		}

		if (!ddata->channels[i]->indio_dev) {
			error = -ENXIO;
			goto out_err;
		}
	}

	return 0;

out_err:
	if (error != -EPROBE_DEFER)
		dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n",
			error);

	return error;
}

/* Calibrate coulomb counter */
static int cpcap_battery_calibrate(struct cpcap_battery_ddata *ddata)
{
	int error, ccc1, value;
	unsigned long timeout;

	error = regmap_read(ddata->reg, CPCAP_REG_CCC1, &ccc1);
	if (error)
		return error;

	timeout = jiffies + msecs_to_jiffies(6000);

	/* Start calibration */
	error = regmap_update_bits(ddata->reg, CPCAP_REG_CCC1,
				   0xffff,
				   CPCAP_REG_CCC1_CAL_EN);
	if (error)
		goto restore;

	while (time_before(jiffies, timeout)) {
		error = regmap_read(ddata->reg, CPCAP_REG_CCC1, &value);
		if (error)
			goto restore;

		if (!(value & CPCAP_REG_CCC1_CAL_EN))
			break;

		error = regmap_read(ddata->reg, CPCAP_REG_CCM, &value);
		if (error)
			goto restore;

		msleep(300);
	}

	/* Read calibration offset from CCM */
	error = regmap_read(ddata->reg, CPCAP_REG_CCM, &value);
	if (error)
		goto restore;

	dev_info(ddata->dev, "calibration done: 0x%04x\n", value);

restore:
	if (error)
		dev_err(ddata->dev, "%s: error %i\n", __func__, error);

	error = regmap_update_bits(ddata->reg, CPCAP_REG_CCC1,
				   0xffff, ccc1);
	if (error)
		dev_err(ddata->dev, "%s: restore error %i\n",
			__func__, error);

	return error;
}

/*
 * Based on the values from Motorola mapphone Linux kernel. In the
 * the Motorola mapphone Linux kernel tree the value for pm_cd_factor
 * is passed to the kernel via device tree. If it turns out to be
 * something device specific we can consider that too later.
 *
 * And looking at the battery full and shutdown values for the stock
 * kernel on droid 4, full is 4351000 and software initiates shutdown
 * at 3078000. The device will die around 2743000.
 */
static const struct cpcap_battery_config cpcap_battery_default_data = {
	.cd_factor = 0x3cc,
	.info.technology = POWER_SUPPLY_TECHNOLOGY_LION,
	.info.voltage_max_design = 4351000,
	.info.voltage_min_design = 3100000,
	.info.charge_full_design = 1740000,
	.bat.constant_charge_voltage_max_uv = 4200000,
};

#ifdef CONFIG_OF
static const struct of_device_id cpcap_battery_id_table[] = {
	{
		.compatible = "motorola,cpcap-battery",
		.data = &cpcap_battery_default_data,
	},
	{},
};
MODULE_DEVICE_TABLE(of, cpcap_battery_id_table);
#endif

static int cpcap_battery_probe(struct platform_device *pdev)
{
	struct power_supply_desc *psy_desc;
	struct cpcap_battery_ddata *ddata;
	const struct of_device_id *match;
	struct power_supply_config psy_cfg = {};
	int error;

	match = of_match_device(of_match_ptr(cpcap_battery_id_table),
				&pdev->dev);
	if (!match)
		return -EINVAL;

	if (!match->data) {
		dev_err(&pdev->dev, "no configuration data found\n");

		return -ENODEV;
	}

	ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
	if (!ddata)
		return -ENOMEM;

	INIT_LIST_HEAD(&ddata->irq_list);
	ddata->dev = &pdev->dev;
	memcpy(&ddata->config, match->data, sizeof(ddata->config));

	ddata->reg = dev_get_regmap(ddata->dev->parent, NULL);
	if (!ddata->reg)
		return -ENODEV;

	error = cpcap_get_vendor(ddata->dev, ddata->reg, &ddata->vendor);
	if (error)
		return error;

	switch (ddata->vendor) {
	case CPCAP_VENDOR_ST:
		ddata->cc_lsb = 95374;	/* μAms per LSB */
		break;
	case CPCAP_VENDOR_TI:
		ddata->cc_lsb = 91501;	/* μAms per LSB */
		break;
	default:
		return -EINVAL;
	}
	ddata->cc_lsb = (ddata->cc_lsb * ddata->config.cd_factor) / 1000;

	platform_set_drvdata(pdev, ddata);

	error = cpcap_battery_init_interrupts(pdev, ddata);
	if (error)
		return error;

	error = cpcap_battery_init_iio(ddata);
	if (error)
		return error;

	psy_desc = devm_kzalloc(ddata->dev, sizeof(*psy_desc), GFP_KERNEL);
	if (!psy_desc)
		return -ENOMEM;

	psy_desc->name = "battery";
	psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
	psy_desc->properties = cpcap_battery_props;
	psy_desc->num_properties = ARRAY_SIZE(cpcap_battery_props);
	psy_desc->get_property = cpcap_battery_get_property;
	psy_desc->set_property = cpcap_battery_set_property;
	psy_desc->property_is_writeable = cpcap_battery_property_is_writeable;

	psy_cfg.of_node = pdev->dev.of_node;
	psy_cfg.drv_data = ddata;

	ddata->psy = devm_power_supply_register(ddata->dev, psy_desc,
						&psy_cfg);
	error = PTR_ERR_OR_ZERO(ddata->psy);
	if (error) {
		dev_err(ddata->dev, "failed to register power supply\n");
		return error;
	}

	atomic_set(&ddata->active, 1);

	error = cpcap_battery_calibrate(ddata);
	if (error)
		return error;

	return 0;
}

static int cpcap_battery_remove(struct platform_device *pdev)
{
	struct cpcap_battery_ddata *ddata = platform_get_drvdata(pdev);
	int error;

	atomic_set(&ddata->active, 0);
	error = regmap_update_bits(ddata->reg, CPCAP_REG_BPEOL,
				   0xffff, 0);
	if (error)
		dev_err(&pdev->dev, "could not disable: %i\n", error);

	return 0;
}

static struct platform_driver cpcap_battery_driver = {
	.driver	= {
		.name		= "cpcap_battery",
		.of_match_table = of_match_ptr(cpcap_battery_id_table),
	},
	.probe	= cpcap_battery_probe,
	.remove = cpcap_battery_remove,
};
module_platform_driver(cpcap_battery_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
MODULE_DESCRIPTION("CPCAP PMIC Battery Driver");
