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