cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cpcap-charger.c (25625B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Motorola CPCAP PMIC battery charger driver
      4 *
      5 * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
      6 *
      7 * Rewritten for Linux power framework with some parts based on
      8 * on earlier driver found in the Motorola Linux kernel:
      9 *
     10 * Copyright (C) 2009-2010 Motorola, Inc.
     11 */
     12
     13#include <linux/atomic.h>
     14#include <linux/init.h>
     15#include <linux/module.h>
     16#include <linux/slab.h>
     17#include <linux/err.h>
     18#include <linux/interrupt.h>
     19#include <linux/notifier.h>
     20#include <linux/of.h>
     21#include <linux/of_platform.h>
     22#include <linux/platform_device.h>
     23#include <linux/power_supply.h>
     24#include <linux/regmap.h>
     25
     26#include <linux/gpio/consumer.h>
     27#include <linux/usb/phy_companion.h>
     28#include <linux/phy/omap_usb.h>
     29#include <linux/usb/otg.h>
     30#include <linux/iio/consumer.h>
     31#include <linux/mfd/motorola-cpcap.h>
     32
     33/*
     34 * CPCAP_REG_CRM register bits. For documentation of somewhat similar hardware,
     35 * see NXP "MC13783 Power Management and Audio Circuit Users's Guide"
     36 * MC13783UG.pdf chapter "8.5 Battery Interface Register Summary". The registers
     37 * and values for CPCAP are different, but some of the internal components seem
     38 * similar. Also see the Motorola Linux kernel cpcap-regbits.h. CPCAP_REG_CHRGR_1
     39 * bits that seem to describe the CRM register.
     40 */
     41#define CPCAP_REG_CRM_UNUSED_641_15	BIT(15)	/* 641 = register number */
     42#define CPCAP_REG_CRM_UNUSED_641_14	BIT(14)	/* 641 = register number */
     43#define CPCAP_REG_CRM_CHRG_LED_EN	BIT(13)	/* Charger LED */
     44#define CPCAP_REG_CRM_RVRSMODE		BIT(12)	/* USB VBUS output enable */
     45#define CPCAP_REG_CRM_ICHRG_TR1		BIT(11)	/* Trickle charge current */
     46#define CPCAP_REG_CRM_ICHRG_TR0		BIT(10)
     47#define CPCAP_REG_CRM_FET_OVRD		BIT(9)	/* 0 = hardware, 1 = FET_CTRL */
     48#define CPCAP_REG_CRM_FET_CTRL		BIT(8)	/* BPFET 1 if FET_OVRD set */
     49#define CPCAP_REG_CRM_VCHRG3		BIT(7)	/* Charge voltage bits */
     50#define CPCAP_REG_CRM_VCHRG2		BIT(6)
     51#define CPCAP_REG_CRM_VCHRG1		BIT(5)
     52#define CPCAP_REG_CRM_VCHRG0		BIT(4)
     53#define CPCAP_REG_CRM_ICHRG3		BIT(3)	/* Charge current bits */
     54#define CPCAP_REG_CRM_ICHRG2		BIT(2)
     55#define CPCAP_REG_CRM_ICHRG1		BIT(1)
     56#define CPCAP_REG_CRM_ICHRG0		BIT(0)
     57
     58/* CPCAP_REG_CRM trickle charge voltages */
     59#define CPCAP_REG_CRM_TR(val)		(((val) & 0x3) << 10)
     60#define CPCAP_REG_CRM_TR_0A00		CPCAP_REG_CRM_TR(0x0)
     61#define CPCAP_REG_CRM_TR_0A24		CPCAP_REG_CRM_TR(0x1)
     62#define CPCAP_REG_CRM_TR_0A48		CPCAP_REG_CRM_TR(0x2)
     63#define CPCAP_REG_CRM_TR_0A72		CPCAP_REG_CRM_TR(0x4)
     64
     65/*
     66 * CPCAP_REG_CRM charge voltages based on the ADC channel 1 values.
     67 * Note that these register bits don't match MC13783UG.pdf VCHRG
     68 * register bits.
     69 */
     70#define CPCAP_REG_CRM_VCHRG(val)	(((val) & 0xf) << 4)
     71#define CPCAP_REG_CRM_VCHRG_3V80	CPCAP_REG_CRM_VCHRG(0x0)
     72#define CPCAP_REG_CRM_VCHRG_4V10	CPCAP_REG_CRM_VCHRG(0x1)
     73#define CPCAP_REG_CRM_VCHRG_4V12	CPCAP_REG_CRM_VCHRG(0x2)
     74#define CPCAP_REG_CRM_VCHRG_4V15	CPCAP_REG_CRM_VCHRG(0x3)
     75#define CPCAP_REG_CRM_VCHRG_4V17	CPCAP_REG_CRM_VCHRG(0x4)
     76#define CPCAP_REG_CRM_VCHRG_4V20	CPCAP_REG_CRM_VCHRG(0x5)
     77#define CPCAP_REG_CRM_VCHRG_4V23	CPCAP_REG_CRM_VCHRG(0x6)
     78#define CPCAP_REG_CRM_VCHRG_4V25	CPCAP_REG_CRM_VCHRG(0x7)
     79#define CPCAP_REG_CRM_VCHRG_4V27	CPCAP_REG_CRM_VCHRG(0x8)
     80#define CPCAP_REG_CRM_VCHRG_4V30	CPCAP_REG_CRM_VCHRG(0x9)
     81#define CPCAP_REG_CRM_VCHRG_4V33	CPCAP_REG_CRM_VCHRG(0xa)
     82#define CPCAP_REG_CRM_VCHRG_4V35	CPCAP_REG_CRM_VCHRG(0xb)
     83#define CPCAP_REG_CRM_VCHRG_4V38	CPCAP_REG_CRM_VCHRG(0xc)
     84#define CPCAP_REG_CRM_VCHRG_4V40	CPCAP_REG_CRM_VCHRG(0xd)
     85#define CPCAP_REG_CRM_VCHRG_4V42	CPCAP_REG_CRM_VCHRG(0xe)
     86#define CPCAP_REG_CRM_VCHRG_4V44	CPCAP_REG_CRM_VCHRG(0xf)
     87
     88/*
     89 * CPCAP_REG_CRM charge currents. These seem to match MC13783UG.pdf
     90 * values in "Table 8-3. Charge Path Regulator Current Limit
     91 * Characteristics" for the nominal values.
     92 *
     93 * Except 70mA and 1.596A and unlimited, these are simply 88.7mA / step.
     94 */
     95#define CPCAP_REG_CRM_ICHRG(val)	(((val) & 0xf) << 0)
     96#define CPCAP_REG_CRM_ICHRG_0A000	CPCAP_REG_CRM_ICHRG(0x0)
     97#define CPCAP_REG_CRM_ICHRG_0A070	CPCAP_REG_CRM_ICHRG(0x1)
     98#define CPCAP_REG_CRM_ICHRG_0A177	CPCAP_REG_CRM_ICHRG(0x2)
     99#define CPCAP_REG_CRM_ICHRG_0A266	CPCAP_REG_CRM_ICHRG(0x3)
    100#define CPCAP_REG_CRM_ICHRG_0A355	CPCAP_REG_CRM_ICHRG(0x4)
    101#define CPCAP_REG_CRM_ICHRG_0A443	CPCAP_REG_CRM_ICHRG(0x5)
    102#define CPCAP_REG_CRM_ICHRG_0A532	CPCAP_REG_CRM_ICHRG(0x6)
    103#define CPCAP_REG_CRM_ICHRG_0A621	CPCAP_REG_CRM_ICHRG(0x7)
    104#define CPCAP_REG_CRM_ICHRG_0A709	CPCAP_REG_CRM_ICHRG(0x8)
    105#define CPCAP_REG_CRM_ICHRG_0A798	CPCAP_REG_CRM_ICHRG(0x9)
    106#define CPCAP_REG_CRM_ICHRG_0A886	CPCAP_REG_CRM_ICHRG(0xa)
    107#define CPCAP_REG_CRM_ICHRG_0A975	CPCAP_REG_CRM_ICHRG(0xb)
    108#define CPCAP_REG_CRM_ICHRG_1A064	CPCAP_REG_CRM_ICHRG(0xc)
    109#define CPCAP_REG_CRM_ICHRG_1A152	CPCAP_REG_CRM_ICHRG(0xd)
    110#define CPCAP_REG_CRM_ICHRG_1A596	CPCAP_REG_CRM_ICHRG(0xe)
    111#define CPCAP_REG_CRM_ICHRG_NO_LIMIT	CPCAP_REG_CRM_ICHRG(0xf)
    112
    113/* CPCAP_REG_VUSBC register bits needed for VBUS */
    114#define CPCAP_BIT_VBUS_SWITCH		BIT(0)	/* VBUS boost to 5V */
    115
    116enum {
    117	CPCAP_CHARGER_IIO_BATTDET,
    118	CPCAP_CHARGER_IIO_VOLTAGE,
    119	CPCAP_CHARGER_IIO_VBUS,
    120	CPCAP_CHARGER_IIO_CHRG_CURRENT,
    121	CPCAP_CHARGER_IIO_BATT_CURRENT,
    122	CPCAP_CHARGER_IIO_NR,
    123};
    124
    125struct cpcap_charger_ddata {
    126	struct device *dev;
    127	struct regmap *reg;
    128	struct list_head irq_list;
    129	struct delayed_work detect_work;
    130	struct delayed_work vbus_work;
    131	struct gpio_desc *gpio[2];		/* gpio_reven0 & 1 */
    132
    133	struct iio_channel *channels[CPCAP_CHARGER_IIO_NR];
    134
    135	struct power_supply *usb;
    136
    137	struct phy_companion comparator;	/* For USB VBUS */
    138	unsigned int vbus_enabled:1;
    139	unsigned int feeding_vbus:1;
    140	atomic_t active;
    141
    142	int status;
    143	int voltage;
    144	int limit_current;
    145};
    146
    147struct cpcap_interrupt_desc {
    148	int irq;
    149	struct list_head node;
    150	const char *name;
    151};
    152
    153struct cpcap_charger_ints_state {
    154	bool chrg_det;
    155	bool rvrs_chrg;
    156	bool vbusov;
    157
    158	bool chrg_se1b;
    159	bool rvrs_mode;
    160	bool chrgcurr2;
    161	bool chrgcurr1;
    162	bool vbusvld;
    163
    164	bool battdetb;
    165};
    166
    167static enum power_supply_property cpcap_charger_props[] = {
    168	POWER_SUPPLY_PROP_STATUS,
    169	POWER_SUPPLY_PROP_ONLINE,
    170	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
    171	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
    172	POWER_SUPPLY_PROP_VOLTAGE_NOW,
    173	POWER_SUPPLY_PROP_CURRENT_NOW,
    174};
    175
    176static int cpcap_charger_get_charge_voltage(struct cpcap_charger_ddata *ddata)
    177{
    178	struct iio_channel *channel;
    179	int error, value = 0;
    180
    181	channel = ddata->channels[CPCAP_CHARGER_IIO_VOLTAGE];
    182	error = iio_read_channel_processed(channel, &value);
    183	if (error < 0) {
    184		dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
    185
    186		return 0;
    187	}
    188
    189	return value;
    190}
    191
    192static int cpcap_charger_get_charge_current(struct cpcap_charger_ddata *ddata)
    193{
    194	struct iio_channel *channel;
    195	int error, value = 0;
    196
    197	channel = ddata->channels[CPCAP_CHARGER_IIO_CHRG_CURRENT];
    198	error = iio_read_channel_processed(channel, &value);
    199	if (error < 0) {
    200		dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
    201
    202		return 0;
    203	}
    204
    205	return value;
    206}
    207
    208static int cpcap_charger_get_property(struct power_supply *psy,
    209				      enum power_supply_property psp,
    210				      union power_supply_propval *val)
    211{
    212	struct cpcap_charger_ddata *ddata = dev_get_drvdata(psy->dev.parent);
    213
    214	switch (psp) {
    215	case POWER_SUPPLY_PROP_STATUS:
    216		val->intval = ddata->status;
    217		break;
    218	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
    219		val->intval = ddata->limit_current;
    220		break;
    221	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
    222		val->intval = ddata->voltage;
    223		break;
    224	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
    225		if (ddata->status == POWER_SUPPLY_STATUS_CHARGING)
    226			val->intval = cpcap_charger_get_charge_voltage(ddata) *
    227				1000;
    228		else
    229			val->intval = 0;
    230		break;
    231	case POWER_SUPPLY_PROP_CURRENT_NOW:
    232		if (ddata->status == POWER_SUPPLY_STATUS_CHARGING)
    233			val->intval = cpcap_charger_get_charge_current(ddata) *
    234				1000;
    235		else
    236			val->intval = 0;
    237		break;
    238	case POWER_SUPPLY_PROP_ONLINE:
    239		val->intval = ddata->status == POWER_SUPPLY_STATUS_CHARGING;
    240		break;
    241	default:
    242		return -EINVAL;
    243	}
    244
    245	return 0;
    246}
    247
    248static int cpcap_charger_match_voltage(int voltage)
    249{
    250	switch (voltage) {
    251	case 0 ... 4100000 - 1: return 3800000;
    252	case 4100000 ... 4120000 - 1: return 4100000;
    253	case 4120000 ... 4150000 - 1: return 4120000;
    254	case 4150000 ... 4170000 - 1: return 4150000;
    255	case 4170000 ... 4200000 - 1: return 4170000;
    256	case 4200000 ... 4230000 - 1: return 4200000;
    257	case 4230000 ... 4250000 - 1: return 4230000;
    258	case 4250000 ... 4270000 - 1: return 4250000;
    259	case 4270000 ... 4300000 - 1: return 4270000;
    260	case 4300000 ... 4330000 - 1: return 4300000;
    261	case 4330000 ... 4350000 - 1: return 4330000;
    262	case 4350000 ... 4380000 - 1: return 4350000;
    263	case 4380000 ... 4400000 - 1: return 4380000;
    264	case 4400000 ... 4420000 - 1: return 4400000;
    265	case 4420000 ... 4440000 - 1: return 4420000;
    266	case 4440000: return 4440000;
    267	default: return 0;
    268	}
    269}
    270
    271static int
    272cpcap_charger_get_bat_const_charge_voltage(struct cpcap_charger_ddata *ddata)
    273{
    274	union power_supply_propval prop;
    275	struct power_supply *battery;
    276	int voltage = ddata->voltage;
    277	int error;
    278
    279	battery = power_supply_get_by_name("battery");
    280	if (battery) {
    281		error = power_supply_get_property(battery,
    282				POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
    283				&prop);
    284		if (!error)
    285			voltage = prop.intval;
    286
    287		power_supply_put(battery);
    288	}
    289
    290	return voltage;
    291}
    292
    293static int cpcap_charger_current_to_regval(int microamp)
    294{
    295	int miliamp = microamp / 1000;
    296	int res;
    297
    298	if (miliamp < 0)
    299		return -EINVAL;
    300	if (miliamp < 70)
    301		return CPCAP_REG_CRM_ICHRG(0x0);
    302	if (miliamp < 177)
    303		return CPCAP_REG_CRM_ICHRG(0x1);
    304	if (miliamp >= 1596)
    305		return CPCAP_REG_CRM_ICHRG(0xe);
    306
    307	res = microamp / 88666;
    308	if (res > 0xd)
    309		res = 0xd;
    310	return CPCAP_REG_CRM_ICHRG(res);
    311}
    312
    313static int cpcap_charger_set_property(struct power_supply *psy,
    314				      enum power_supply_property psp,
    315				      const union power_supply_propval *val)
    316{
    317	struct cpcap_charger_ddata *ddata = dev_get_drvdata(psy->dev.parent);
    318	int voltage, batvolt;
    319
    320	switch (psp) {
    321	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
    322		if (cpcap_charger_current_to_regval(val->intval) < 0)
    323			return -EINVAL;
    324		ddata->limit_current = val->intval;
    325		schedule_delayed_work(&ddata->detect_work, 0);
    326		break;
    327	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
    328		voltage = cpcap_charger_match_voltage(val->intval);
    329		batvolt = cpcap_charger_get_bat_const_charge_voltage(ddata);
    330		if (voltage > batvolt)
    331			voltage = batvolt;
    332		ddata->voltage = voltage;
    333		schedule_delayed_work(&ddata->detect_work, 0);
    334		break;
    335	default:
    336		return -EINVAL;
    337	}
    338
    339	return 0;
    340}
    341
    342static int cpcap_charger_property_is_writeable(struct power_supply *psy,
    343					       enum power_supply_property psp)
    344{
    345	switch (psp) {
    346	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
    347	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
    348		return 1;
    349	default:
    350		return 0;
    351	}
    352}
    353
    354static void cpcap_charger_set_cable_path(struct cpcap_charger_ddata *ddata,
    355					 bool enabled)
    356{
    357	if (!ddata->gpio[0])
    358		return;
    359
    360	gpiod_set_value(ddata->gpio[0], enabled);
    361}
    362
    363static void cpcap_charger_set_inductive_path(struct cpcap_charger_ddata *ddata,
    364					     bool enabled)
    365{
    366	if (!ddata->gpio[1])
    367		return;
    368
    369	gpiod_set_value(ddata->gpio[1], enabled);
    370}
    371
    372static void cpcap_charger_update_state(struct cpcap_charger_ddata *ddata,
    373				       int state)
    374{
    375	const char *status;
    376
    377	if (state > POWER_SUPPLY_STATUS_FULL) {
    378		dev_warn(ddata->dev, "unknown state: %i\n", state);
    379
    380		return;
    381	}
    382
    383	ddata->status = state;
    384
    385	switch (state) {
    386	case POWER_SUPPLY_STATUS_DISCHARGING:
    387		status = "DISCONNECTED";
    388		break;
    389	case POWER_SUPPLY_STATUS_NOT_CHARGING:
    390		status = "DETECTING";
    391		break;
    392	case POWER_SUPPLY_STATUS_CHARGING:
    393		status = "CHARGING";
    394		break;
    395	case POWER_SUPPLY_STATUS_FULL:
    396		status = "DONE";
    397		break;
    398	default:
    399		return;
    400	}
    401
    402	dev_dbg(ddata->dev, "state: %s\n", status);
    403}
    404
    405static int cpcap_charger_disable(struct cpcap_charger_ddata *ddata)
    406{
    407	int error;
    408
    409	error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, 0x3fff,
    410				   CPCAP_REG_CRM_FET_OVRD |
    411				   CPCAP_REG_CRM_FET_CTRL);
    412	if (error)
    413		dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
    414
    415	return error;
    416}
    417
    418static int cpcap_charger_enable(struct cpcap_charger_ddata *ddata,
    419				int max_voltage, int charge_current,
    420				int trickle_current)
    421{
    422	int error;
    423
    424	if (!max_voltage || !charge_current)
    425		return -EINVAL;
    426
    427	dev_dbg(ddata->dev, "enable: %i %i %i\n",
    428		max_voltage, charge_current, trickle_current);
    429
    430	error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, 0x3fff,
    431				   CPCAP_REG_CRM_CHRG_LED_EN |
    432				   trickle_current |
    433				   CPCAP_REG_CRM_FET_OVRD |
    434				   CPCAP_REG_CRM_FET_CTRL |
    435				   max_voltage |
    436				   charge_current);
    437	if (error)
    438		dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
    439
    440	return error;
    441}
    442
    443static bool cpcap_charger_vbus_valid(struct cpcap_charger_ddata *ddata)
    444{
    445	int error, value = 0;
    446	struct iio_channel *channel =
    447		ddata->channels[CPCAP_CHARGER_IIO_VBUS];
    448
    449	error = iio_read_channel_processed(channel, &value);
    450	if (error >= 0)
    451		return value > 3900;
    452
    453	dev_err(ddata->dev, "error reading VBUS: %i\n", error);
    454
    455	return false;
    456}
    457
    458/* VBUS control functions for the USB PHY companion */
    459static void cpcap_charger_vbus_work(struct work_struct *work)
    460{
    461	struct cpcap_charger_ddata *ddata;
    462	bool vbus = false;
    463	int error;
    464
    465	ddata = container_of(work, struct cpcap_charger_ddata,
    466			     vbus_work.work);
    467
    468	if (ddata->vbus_enabled) {
    469		vbus = cpcap_charger_vbus_valid(ddata);
    470		if (vbus) {
    471			dev_dbg(ddata->dev, "VBUS already provided\n");
    472
    473			return;
    474		}
    475
    476		ddata->feeding_vbus = true;
    477		cpcap_charger_set_cable_path(ddata, false);
    478		cpcap_charger_set_inductive_path(ddata, false);
    479
    480		error = cpcap_charger_disable(ddata);
    481		if (error)
    482			goto out_err;
    483
    484		cpcap_charger_update_state(ddata,
    485					   POWER_SUPPLY_STATUS_DISCHARGING);
    486
    487		error = regmap_update_bits(ddata->reg, CPCAP_REG_VUSBC,
    488					   CPCAP_BIT_VBUS_SWITCH,
    489					   CPCAP_BIT_VBUS_SWITCH);
    490		if (error)
    491			goto out_err;
    492
    493		error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
    494					   CPCAP_REG_CRM_RVRSMODE,
    495					   CPCAP_REG_CRM_RVRSMODE);
    496		if (error)
    497			goto out_err;
    498	} else {
    499		error = regmap_update_bits(ddata->reg, CPCAP_REG_VUSBC,
    500					   CPCAP_BIT_VBUS_SWITCH, 0);
    501		if (error)
    502			goto out_err;
    503
    504		error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
    505					   CPCAP_REG_CRM_RVRSMODE, 0);
    506		if (error)
    507			goto out_err;
    508
    509		cpcap_charger_set_cable_path(ddata, true);
    510		cpcap_charger_set_inductive_path(ddata, true);
    511		ddata->feeding_vbus = false;
    512	}
    513
    514	return;
    515
    516out_err:
    517	cpcap_charger_update_state(ddata, POWER_SUPPLY_STATUS_UNKNOWN);
    518	dev_err(ddata->dev, "%s could not %s vbus: %i\n", __func__,
    519		ddata->vbus_enabled ? "enable" : "disable", error);
    520}
    521
    522static int cpcap_charger_set_vbus(struct phy_companion *comparator,
    523				  bool enabled)
    524{
    525	struct cpcap_charger_ddata *ddata =
    526		container_of(comparator, struct cpcap_charger_ddata,
    527			     comparator);
    528
    529	ddata->vbus_enabled = enabled;
    530	schedule_delayed_work(&ddata->vbus_work, 0);
    531
    532	return 0;
    533}
    534
    535/* Charger interrupt handling functions */
    536
    537static int cpcap_charger_get_ints_state(struct cpcap_charger_ddata *ddata,
    538					struct cpcap_charger_ints_state *s)
    539{
    540	int val, error;
    541
    542	error = regmap_read(ddata->reg, CPCAP_REG_INTS1, &val);
    543	if (error)
    544		return error;
    545
    546	s->chrg_det = val & BIT(13);
    547	s->rvrs_chrg = val & BIT(12);
    548	s->vbusov = val & BIT(11);
    549
    550	error = regmap_read(ddata->reg, CPCAP_REG_INTS2, &val);
    551	if (error)
    552		return error;
    553
    554	s->chrg_se1b = val & BIT(13);
    555	s->rvrs_mode = val & BIT(6);
    556	s->chrgcurr2 = val & BIT(5);
    557	s->chrgcurr1 = val & BIT(4);
    558	s->vbusvld = val & BIT(3);
    559
    560	error = regmap_read(ddata->reg, CPCAP_REG_INTS4, &val);
    561	if (error)
    562		return error;
    563
    564	s->battdetb = val & BIT(6);
    565
    566	return 0;
    567}
    568
    569static int cpcap_charger_voltage_to_regval(int voltage)
    570{
    571	int offset;
    572
    573	switch (voltage) {
    574	case 0 ... 4100000 - 1:
    575		return 0;
    576	case 4100000 ... 4200000 - 1:
    577		offset = 1;
    578		break;
    579	case 4200000 ... 4300000 - 1:
    580		offset = 0;
    581		break;
    582	case 4300000 ... 4380000 - 1:
    583		offset = -1;
    584		break;
    585	case 4380000 ... 4440000:
    586		offset = -2;
    587		break;
    588	default:
    589		return 0;
    590	}
    591
    592	return ((voltage - 4100000) / 20000) + offset;
    593}
    594
    595static void cpcap_charger_disconnect(struct cpcap_charger_ddata *ddata,
    596				     int state, unsigned long delay)
    597{
    598	int error;
    599
    600	/* Update battery state before disconnecting the charger */
    601	switch (state) {
    602	case POWER_SUPPLY_STATUS_DISCHARGING:
    603	case POWER_SUPPLY_STATUS_FULL:
    604		power_supply_changed(ddata->usb);
    605		break;
    606	default:
    607		break;
    608	}
    609
    610	error = cpcap_charger_disable(ddata);
    611	if (error) {
    612		cpcap_charger_update_state(ddata, POWER_SUPPLY_STATUS_UNKNOWN);
    613		return;
    614	}
    615
    616	cpcap_charger_update_state(ddata, state);
    617	power_supply_changed(ddata->usb);
    618	schedule_delayed_work(&ddata->detect_work, delay);
    619}
    620
    621static void cpcap_usb_detect(struct work_struct *work)
    622{
    623	struct cpcap_charger_ddata *ddata;
    624	struct cpcap_charger_ints_state s;
    625	int error, new_state;
    626
    627	ddata = container_of(work, struct cpcap_charger_ddata,
    628			     detect_work.work);
    629
    630	error = cpcap_charger_get_ints_state(ddata, &s);
    631	if (error)
    632		return;
    633
    634	/* Just init the state if a charger is connected with no chrg_det set */
    635	if (!s.chrg_det && s.chrgcurr1 && s.vbusvld) {
    636		cpcap_charger_update_state(ddata,
    637					   POWER_SUPPLY_STATUS_NOT_CHARGING);
    638
    639		return;
    640	}
    641
    642	/*
    643	 * If battery voltage is higher than charge voltage, it may have been
    644	 * charged to 4.35V by Android. Try again in 10 minutes.
    645	 */
    646	if (cpcap_charger_get_charge_voltage(ddata) > ddata->voltage) {
    647		cpcap_charger_disconnect(ddata,
    648					 POWER_SUPPLY_STATUS_NOT_CHARGING,
    649					 HZ * 60 * 10);
    650
    651		return;
    652	}
    653
    654	/* Delay for 80ms to avoid vbus bouncing when usb cable is plugged in */
    655	usleep_range(80000, 120000);
    656
    657	/* Throttle chrgcurr2 interrupt for charger done and retry */
    658	switch (ddata->status) {
    659	case POWER_SUPPLY_STATUS_CHARGING:
    660		if (s.chrgcurr2)
    661			break;
    662		new_state = POWER_SUPPLY_STATUS_FULL;
    663
    664		if (s.chrgcurr1 && s.vbusvld) {
    665			cpcap_charger_disconnect(ddata, new_state, HZ * 5);
    666			return;
    667		}
    668		break;
    669	case POWER_SUPPLY_STATUS_FULL:
    670		if (!s.chrgcurr2)
    671			break;
    672		if (s.vbusvld)
    673			new_state = POWER_SUPPLY_STATUS_NOT_CHARGING;
    674		else
    675			new_state = POWER_SUPPLY_STATUS_DISCHARGING;
    676
    677		cpcap_charger_disconnect(ddata, new_state, HZ * 5);
    678
    679		return;
    680	default:
    681		break;
    682	}
    683
    684	if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) &&
    685	    s.chrgcurr1) {
    686		int max_current;
    687		int vchrg, ichrg;
    688		union power_supply_propval val;
    689		struct power_supply *battery;
    690
    691		battery = power_supply_get_by_name("battery");
    692		if (IS_ERR_OR_NULL(battery)) {
    693			dev_err(ddata->dev, "battery power_supply not available %li\n",
    694					PTR_ERR(battery));
    695			return;
    696		}
    697
    698		error = power_supply_get_property(battery, POWER_SUPPLY_PROP_PRESENT, &val);
    699		power_supply_put(battery);
    700		if (error)
    701			goto out_err;
    702
    703		if (val.intval) {
    704			max_current = 1596000;
    705		} else {
    706			dev_info(ddata->dev, "battery not inserted, charging disabled\n");
    707			max_current = 0;
    708		}
    709
    710		if (max_current > ddata->limit_current)
    711			max_current = ddata->limit_current;
    712
    713		ichrg = cpcap_charger_current_to_regval(max_current);
    714		vchrg = cpcap_charger_voltage_to_regval(ddata->voltage);
    715		error = cpcap_charger_enable(ddata,
    716					     CPCAP_REG_CRM_VCHRG(vchrg),
    717					     ichrg, 0);
    718		if (error)
    719			goto out_err;
    720		cpcap_charger_update_state(ddata,
    721					   POWER_SUPPLY_STATUS_CHARGING);
    722	} else {
    723		error = cpcap_charger_disable(ddata);
    724		if (error)
    725			goto out_err;
    726		cpcap_charger_update_state(ddata,
    727					   POWER_SUPPLY_STATUS_DISCHARGING);
    728	}
    729
    730	power_supply_changed(ddata->usb);
    731	return;
    732
    733out_err:
    734	cpcap_charger_update_state(ddata, POWER_SUPPLY_STATUS_UNKNOWN);
    735	dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
    736}
    737
    738static irqreturn_t cpcap_charger_irq_thread(int irq, void *data)
    739{
    740	struct cpcap_charger_ddata *ddata = data;
    741
    742	if (!atomic_read(&ddata->active))
    743		return IRQ_NONE;
    744
    745	schedule_delayed_work(&ddata->detect_work, 0);
    746
    747	return IRQ_HANDLED;
    748}
    749
    750static int cpcap_usb_init_irq(struct platform_device *pdev,
    751			      struct cpcap_charger_ddata *ddata,
    752			      const char *name)
    753{
    754	struct cpcap_interrupt_desc *d;
    755	int irq, error;
    756
    757	irq = platform_get_irq_byname(pdev, name);
    758	if (irq < 0)
    759		return -ENODEV;
    760
    761	error = devm_request_threaded_irq(ddata->dev, irq, NULL,
    762					  cpcap_charger_irq_thread,
    763					  IRQF_SHARED | IRQF_ONESHOT,
    764					  name, ddata);
    765	if (error) {
    766		dev_err(ddata->dev, "could not get irq %s: %i\n",
    767			name, error);
    768
    769		return error;
    770	}
    771
    772	d = devm_kzalloc(ddata->dev, sizeof(*d), GFP_KERNEL);
    773	if (!d)
    774		return -ENOMEM;
    775
    776	d->name = name;
    777	d->irq = irq;
    778	list_add(&d->node, &ddata->irq_list);
    779
    780	return 0;
    781}
    782
    783static const char * const cpcap_charger_irqs[] = {
    784	/* REG_INT_0 */
    785	"chrg_det", "rvrs_chrg",
    786
    787	/* REG_INT1 */
    788	"chrg_se1b", "se0conn", "rvrs_mode", "chrgcurr2", "chrgcurr1", "vbusvld",
    789
    790	/* REG_INT_3 */
    791	"battdetb",
    792};
    793
    794static int cpcap_usb_init_interrupts(struct platform_device *pdev,
    795				     struct cpcap_charger_ddata *ddata)
    796{
    797	int i, error;
    798
    799	for (i = 0; i < ARRAY_SIZE(cpcap_charger_irqs); i++) {
    800		error = cpcap_usb_init_irq(pdev, ddata, cpcap_charger_irqs[i]);
    801		if (error)
    802			return error;
    803	}
    804
    805	return 0;
    806}
    807
    808static void cpcap_charger_init_optional_gpios(struct cpcap_charger_ddata *ddata)
    809{
    810	int i;
    811
    812	for (i = 0; i < 2; i++) {
    813		ddata->gpio[i] = devm_gpiod_get_index(ddata->dev, "mode",
    814						      i, GPIOD_OUT_HIGH);
    815		if (IS_ERR(ddata->gpio[i])) {
    816			dev_info(ddata->dev, "no mode change GPIO%i: %li\n",
    817				 i, PTR_ERR(ddata->gpio[i]));
    818			ddata->gpio[i] = NULL;
    819		}
    820	}
    821}
    822
    823static int cpcap_charger_init_iio(struct cpcap_charger_ddata *ddata)
    824{
    825	const char * const names[CPCAP_CHARGER_IIO_NR] = {
    826		"battdetb", "battp", "vbus", "chg_isense", "batti",
    827	};
    828	int error, i;
    829
    830	for (i = 0; i < CPCAP_CHARGER_IIO_NR; i++) {
    831		ddata->channels[i] = devm_iio_channel_get(ddata->dev,
    832							  names[i]);
    833		if (IS_ERR(ddata->channels[i])) {
    834			error = PTR_ERR(ddata->channels[i]);
    835			goto out_err;
    836		}
    837
    838		if (!ddata->channels[i]->indio_dev) {
    839			error = -ENXIO;
    840			goto out_err;
    841		}
    842	}
    843
    844	return 0;
    845
    846out_err:
    847	if (error != -EPROBE_DEFER)
    848		dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n",
    849			error);
    850
    851	return error;
    852}
    853
    854static char *cpcap_charger_supplied_to[] = {
    855	"battery",
    856};
    857
    858static const struct power_supply_desc cpcap_charger_usb_desc = {
    859	.name		= "usb",
    860	.type		= POWER_SUPPLY_TYPE_USB,
    861	.properties	= cpcap_charger_props,
    862	.num_properties	= ARRAY_SIZE(cpcap_charger_props),
    863	.get_property	= cpcap_charger_get_property,
    864	.set_property	= cpcap_charger_set_property,
    865	.property_is_writeable = cpcap_charger_property_is_writeable,
    866};
    867
    868#ifdef CONFIG_OF
    869static const struct of_device_id cpcap_charger_id_table[] = {
    870	{
    871		.compatible = "motorola,mapphone-cpcap-charger",
    872	},
    873	{},
    874};
    875MODULE_DEVICE_TABLE(of, cpcap_charger_id_table);
    876#endif
    877
    878static int cpcap_charger_probe(struct platform_device *pdev)
    879{
    880	struct cpcap_charger_ddata *ddata;
    881	const struct of_device_id *of_id;
    882	struct power_supply_config psy_cfg = {};
    883	int error;
    884
    885	of_id = of_match_device(of_match_ptr(cpcap_charger_id_table),
    886				&pdev->dev);
    887	if (!of_id)
    888		return -EINVAL;
    889
    890	ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
    891	if (!ddata)
    892		return -ENOMEM;
    893
    894	ddata->dev = &pdev->dev;
    895	ddata->voltage = 4200000;
    896	ddata->limit_current = 532000;
    897
    898	ddata->reg = dev_get_regmap(ddata->dev->parent, NULL);
    899	if (!ddata->reg)
    900		return -ENODEV;
    901
    902	INIT_LIST_HEAD(&ddata->irq_list);
    903	INIT_DELAYED_WORK(&ddata->detect_work, cpcap_usb_detect);
    904	INIT_DELAYED_WORK(&ddata->vbus_work, cpcap_charger_vbus_work);
    905	platform_set_drvdata(pdev, ddata);
    906
    907	error = cpcap_charger_init_iio(ddata);
    908	if (error)
    909		return error;
    910
    911	atomic_set(&ddata->active, 1);
    912
    913	psy_cfg.of_node = pdev->dev.of_node;
    914	psy_cfg.drv_data = ddata;
    915	psy_cfg.supplied_to = cpcap_charger_supplied_to;
    916	psy_cfg.num_supplicants = ARRAY_SIZE(cpcap_charger_supplied_to),
    917
    918	ddata->usb = devm_power_supply_register(ddata->dev,
    919						&cpcap_charger_usb_desc,
    920						&psy_cfg);
    921	if (IS_ERR(ddata->usb)) {
    922		error = PTR_ERR(ddata->usb);
    923		dev_err(ddata->dev, "failed to register USB charger: %i\n",
    924			error);
    925
    926		return error;
    927	}
    928
    929	error = cpcap_usb_init_interrupts(pdev, ddata);
    930	if (error)
    931		return error;
    932
    933	ddata->comparator.set_vbus = cpcap_charger_set_vbus;
    934	error = omap_usb2_set_comparator(&ddata->comparator);
    935	if (error == -ENODEV) {
    936		dev_info(ddata->dev, "charger needs phy, deferring probe\n");
    937		return -EPROBE_DEFER;
    938	}
    939
    940	cpcap_charger_init_optional_gpios(ddata);
    941
    942	schedule_delayed_work(&ddata->detect_work, 0);
    943
    944	return 0;
    945}
    946
    947static void cpcap_charger_shutdown(struct platform_device *pdev)
    948{
    949	struct cpcap_charger_ddata *ddata = platform_get_drvdata(pdev);
    950	int error;
    951
    952	atomic_set(&ddata->active, 0);
    953	error = omap_usb2_set_comparator(NULL);
    954	if (error)
    955		dev_warn(ddata->dev, "could not clear USB comparator: %i\n",
    956			 error);
    957
    958	error = cpcap_charger_disable(ddata);
    959	if (error) {
    960		cpcap_charger_update_state(ddata, POWER_SUPPLY_STATUS_UNKNOWN);
    961		dev_warn(ddata->dev, "could not clear charger: %i\n",
    962			 error);
    963	}
    964	cpcap_charger_update_state(ddata, POWER_SUPPLY_STATUS_DISCHARGING);
    965	cancel_delayed_work_sync(&ddata->vbus_work);
    966	cancel_delayed_work_sync(&ddata->detect_work);
    967}
    968
    969static int cpcap_charger_remove(struct platform_device *pdev)
    970{
    971	cpcap_charger_shutdown(pdev);
    972
    973	return 0;
    974}
    975
    976static struct platform_driver cpcap_charger_driver = {
    977	.probe = cpcap_charger_probe,
    978	.driver	= {
    979		.name	= "cpcap-charger",
    980		.of_match_table = of_match_ptr(cpcap_charger_id_table),
    981	},
    982	.shutdown = cpcap_charger_shutdown,
    983	.remove	= cpcap_charger_remove,
    984};
    985module_platform_driver(cpcap_charger_driver);
    986
    987MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
    988MODULE_DESCRIPTION("CPCAP Battery Charger Interface driver");
    989MODULE_LICENSE("GPL v2");
    990MODULE_ALIAS("platform:cpcap-charger");