brintos

brintos / linux-shallow public Read only

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