cpcap-battery.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. /*
  2. * Battery driver for CPCAP PMIC
  3. *
  4. * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
  5. *
  6. * Some parts of the code based on earlie Motorola mapphone Linux kernel
  7. * drivers:
  8. *
  9. * Copyright (C) 2009-2010 Motorola, Inc.
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License version 2 as
  13. * published by the Free Software Foundation.
  14. * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  15. * kind, whether express or implied; without even the implied warranty
  16. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. */
  19. #include <linux/delay.h>
  20. #include <linux/err.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/kernel.h>
  23. #include <linux/module.h>
  24. #include <linux/of_device.h>
  25. #include <linux/platform_device.h>
  26. #include <linux/power_supply.h>
  27. #include <linux/reboot.h>
  28. #include <linux/regmap.h>
  29. #include <linux/iio/consumer.h>
  30. #include <linux/iio/types.h>
  31. #include <linux/mfd/motorola-cpcap.h>
  32. #include <asm/div64.h>
  33. /*
  34. * Register bit defines for CPCAP_REG_BPEOL. Some of these seem to
  35. * map to MC13783UG.pdf "Table 5-19. Register 13, Power Control 0"
  36. * to enable BATTDETEN, LOBAT and EOL features. We currently use
  37. * LOBAT interrupts instead of EOL.
  38. */
  39. #define CPCAP_REG_BPEOL_BIT_EOL9 BIT(9) /* Set for EOL irq */
  40. #define CPCAP_REG_BPEOL_BIT_EOL8 BIT(8) /* Set for EOL irq */
  41. #define CPCAP_REG_BPEOL_BIT_UNKNOWN7 BIT(7)
  42. #define CPCAP_REG_BPEOL_BIT_UNKNOWN6 BIT(6)
  43. #define CPCAP_REG_BPEOL_BIT_UNKNOWN5 BIT(5)
  44. #define CPCAP_REG_BPEOL_BIT_EOL_MULTI BIT(4) /* Set for multiple EOL irqs */
  45. #define CPCAP_REG_BPEOL_BIT_UNKNOWN3 BIT(3)
  46. #define CPCAP_REG_BPEOL_BIT_UNKNOWN2 BIT(2)
  47. #define CPCAP_REG_BPEOL_BIT_BATTDETEN BIT(1) /* Enable battery detect */
  48. #define CPCAP_REG_BPEOL_BIT_EOLSEL BIT(0) /* BPDET = 0, EOL = 1 */
  49. #define CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS 250
  50. enum {
  51. CPCAP_BATTERY_IIO_BATTDET,
  52. CPCAP_BATTERY_IIO_VOLTAGE,
  53. CPCAP_BATTERY_IIO_CHRG_CURRENT,
  54. CPCAP_BATTERY_IIO_BATT_CURRENT,
  55. CPCAP_BATTERY_IIO_NR,
  56. };
  57. enum cpcap_battery_irq_action {
  58. CPCAP_BATTERY_IRQ_ACTION_NONE,
  59. CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW,
  60. CPCAP_BATTERY_IRQ_ACTION_POWEROFF,
  61. };
  62. struct cpcap_interrupt_desc {
  63. const char *name;
  64. struct list_head node;
  65. int irq;
  66. enum cpcap_battery_irq_action action;
  67. };
  68. struct cpcap_battery_config {
  69. int ccm;
  70. int cd_factor;
  71. struct power_supply_info info;
  72. };
  73. struct cpcap_coulomb_counter_data {
  74. s32 sample; /* 24 or 32 bits */
  75. s32 accumulator;
  76. s16 offset; /* 10-bits */
  77. };
  78. enum cpcap_battery_state {
  79. CPCAP_BATTERY_STATE_PREVIOUS,
  80. CPCAP_BATTERY_STATE_LATEST,
  81. CPCAP_BATTERY_STATE_NR,
  82. };
  83. struct cpcap_battery_state_data {
  84. int voltage;
  85. int current_ua;
  86. int counter_uah;
  87. int temperature;
  88. ktime_t time;
  89. struct cpcap_coulomb_counter_data cc;
  90. };
  91. struct cpcap_battery_ddata {
  92. struct device *dev;
  93. struct regmap *reg;
  94. struct list_head irq_list;
  95. struct iio_channel *channels[CPCAP_BATTERY_IIO_NR];
  96. struct power_supply *psy;
  97. struct cpcap_battery_config config;
  98. struct cpcap_battery_state_data state[CPCAP_BATTERY_STATE_NR];
  99. atomic_t active;
  100. int status;
  101. u16 vendor;
  102. };
  103. #define CPCAP_NO_BATTERY -400
  104. static struct cpcap_battery_state_data *
  105. cpcap_battery_get_state(struct cpcap_battery_ddata *ddata,
  106. enum cpcap_battery_state state)
  107. {
  108. if (state >= CPCAP_BATTERY_STATE_NR)
  109. return NULL;
  110. return &ddata->state[state];
  111. }
  112. static struct cpcap_battery_state_data *
  113. cpcap_battery_latest(struct cpcap_battery_ddata *ddata)
  114. {
  115. return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_LATEST);
  116. }
  117. static struct cpcap_battery_state_data *
  118. cpcap_battery_previous(struct cpcap_battery_ddata *ddata)
  119. {
  120. return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_PREVIOUS);
  121. }
  122. static int cpcap_charger_battery_temperature(struct cpcap_battery_ddata *ddata,
  123. int *value)
  124. {
  125. struct iio_channel *channel;
  126. int error;
  127. channel = ddata->channels[CPCAP_BATTERY_IIO_BATTDET];
  128. error = iio_read_channel_processed(channel, value);
  129. if (error < 0) {
  130. dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
  131. *value = CPCAP_NO_BATTERY;
  132. return error;
  133. }
  134. *value /= 100;
  135. return 0;
  136. }
  137. static int cpcap_battery_get_voltage(struct cpcap_battery_ddata *ddata)
  138. {
  139. struct iio_channel *channel;
  140. int error, value = 0;
  141. channel = ddata->channels[CPCAP_BATTERY_IIO_VOLTAGE];
  142. error = iio_read_channel_processed(channel, &value);
  143. if (error < 0) {
  144. dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
  145. return 0;
  146. }
  147. return value * 1000;
  148. }
  149. static int cpcap_battery_get_current(struct cpcap_battery_ddata *ddata)
  150. {
  151. struct iio_channel *channel;
  152. int error, value = 0;
  153. channel = ddata->channels[CPCAP_BATTERY_IIO_BATT_CURRENT];
  154. error = iio_read_channel_processed(channel, &value);
  155. if (error < 0) {
  156. dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
  157. return 0;
  158. }
  159. return value * 1000;
  160. }
  161. /**
  162. * cpcap_battery_cc_raw_div - calculate and divide coulomb counter μAms values
  163. * @ddata: device driver data
  164. * @sample: coulomb counter sample value
  165. * @accumulator: coulomb counter integrator value
  166. * @offset: coulomb counter offset value
  167. * @divider: conversion divider
  168. *
  169. * Note that cc_lsb and cc_dur values are from Motorola Linux kernel
  170. * function data_get_avg_curr_ua() and seem to be based on measured test
  171. * results. It also has the following comment:
  172. *
  173. * Adjustment factors are applied here as a temp solution per the test
  174. * results. Need to work out a formal solution for this adjustment.
  175. *
  176. * A coulomb counter for similar hardware seems to be documented in
  177. * "TWL6030 Gas Gauging Basics (Rev. A)" swca095a.pdf in chapter
  178. * "10 Calculating Accumulated Current". We however follow what the
  179. * Motorola mapphone Linux kernel is doing as there may be either a
  180. * TI or ST coulomb counter in the PMIC.
  181. */
  182. static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata,
  183. s32 sample, s32 accumulator,
  184. s16 offset, u32 divider)
  185. {
  186. s64 acc;
  187. u64 tmp;
  188. int avg_current;
  189. u32 cc_lsb;
  190. if (!divider)
  191. return 0;
  192. offset &= 0x7ff; /* 10-bits, signed */
  193. switch (ddata->vendor) {
  194. case CPCAP_VENDOR_ST:
  195. cc_lsb = 95374; /* μAms per LSB */
  196. break;
  197. case CPCAP_VENDOR_TI:
  198. cc_lsb = 91501; /* μAms per LSB */
  199. break;
  200. default:
  201. return -EINVAL;
  202. }
  203. acc = accumulator;
  204. acc = acc - ((s64)sample * offset);
  205. cc_lsb = (cc_lsb * ddata->config.cd_factor) / 1000;
  206. if (acc >= 0)
  207. tmp = acc;
  208. else
  209. tmp = acc * -1;
  210. tmp = tmp * cc_lsb;
  211. do_div(tmp, divider);
  212. avg_current = tmp;
  213. if (acc >= 0)
  214. return -avg_current;
  215. else
  216. return avg_current;
  217. }
  218. /* 3600000μAms = 1μAh */
  219. static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata,
  220. s32 sample, s32 accumulator,
  221. s16 offset)
  222. {
  223. return cpcap_battery_cc_raw_div(ddata, sample,
  224. accumulator, offset,
  225. 3600000);
  226. }
  227. static int cpcap_battery_cc_to_ua(struct cpcap_battery_ddata *ddata,
  228. s32 sample, s32 accumulator,
  229. s16 offset)
  230. {
  231. return cpcap_battery_cc_raw_div(ddata, sample,
  232. accumulator, offset,
  233. sample *
  234. CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS);
  235. }
  236. /**
  237. * cpcap_battery_read_accumulated - reads cpcap coulomb counter
  238. * @ddata: device driver data
  239. * @regs: coulomb counter values
  240. *
  241. * Based on Motorola mapphone kernel function data_read_regs().
  242. * Looking at the registers, the coulomb counter seems similar to
  243. * the coulomb counter in TWL6030. See "TWL6030 Gas Gauging Basics
  244. * (Rev. A) swca095a.pdf for "10 Calculating Accumulated Current".
  245. *
  246. * Note that swca095a.pdf instructs to stop the coulomb counter
  247. * before reading to avoid values changing. Motorola mapphone
  248. * Linux kernel does not do it, so let's assume they've verified
  249. * the data produced is correct.
  250. */
  251. static int
  252. cpcap_battery_read_accumulated(struct cpcap_battery_ddata *ddata,
  253. struct cpcap_coulomb_counter_data *ccd)
  254. {
  255. u16 buf[7]; /* CPCAP_REG_CC1 to CCI */
  256. int error;
  257. ccd->sample = 0;
  258. ccd->accumulator = 0;
  259. ccd->offset = 0;
  260. /* Read coulomb counter register range */
  261. error = regmap_bulk_read(ddata->reg, CPCAP_REG_CCS1,
  262. buf, ARRAY_SIZE(buf));
  263. if (error)
  264. return 0;
  265. /* Sample value CPCAP_REG_CCS1 & 2 */
  266. ccd->sample = (buf[1] & 0x0fff) << 16;
  267. ccd->sample |= buf[0];
  268. if (ddata->vendor == CPCAP_VENDOR_TI)
  269. ccd->sample = sign_extend32(24, ccd->sample);
  270. /* Accumulator value CPCAP_REG_CCA1 & 2 */
  271. ccd->accumulator = ((s16)buf[3]) << 16;
  272. ccd->accumulator |= buf[2];
  273. /* Offset value CPCAP_REG_CCO */
  274. ccd->offset = buf[5];
  275. /* Adjust offset based on mode value CPCAP_REG_CCM? */
  276. if (buf[4] >= 0x200)
  277. ccd->offset |= 0xfc00;
  278. return cpcap_battery_cc_to_uah(ddata,
  279. ccd->sample,
  280. ccd->accumulator,
  281. ccd->offset);
  282. }
  283. /**
  284. * cpcap_battery_cc_get_avg_current - read cpcap coulumb counter
  285. * @ddata: cpcap battery driver device data
  286. */
  287. static int cpcap_battery_cc_get_avg_current(struct cpcap_battery_ddata *ddata)
  288. {
  289. int value, acc, error;
  290. s32 sample = 1;
  291. s16 offset;
  292. if (ddata->vendor == CPCAP_VENDOR_ST)
  293. sample = 4;
  294. /* Coulomb counter integrator */
  295. error = regmap_read(ddata->reg, CPCAP_REG_CCI, &value);
  296. if (error)
  297. return error;
  298. if ((ddata->vendor == CPCAP_VENDOR_TI) && (value > 0x2000))
  299. value = value | 0xc000;
  300. acc = (s16)value;
  301. /* Coulomb counter sample time */
  302. error = regmap_read(ddata->reg, CPCAP_REG_CCM, &value);
  303. if (error)
  304. return error;
  305. if (value < 0x200)
  306. offset = value;
  307. else
  308. offset = value | 0xfc00;
  309. return cpcap_battery_cc_to_ua(ddata, sample, acc, offset);
  310. }
  311. static bool cpcap_battery_full(struct cpcap_battery_ddata *ddata)
  312. {
  313. struct cpcap_battery_state_data *state = cpcap_battery_latest(ddata);
  314. /* Basically anything that measures above 4347000 is full */
  315. if (state->voltage >= (ddata->config.info.voltage_max_design - 4000))
  316. return true;
  317. return false;
  318. }
  319. static int cpcap_battery_update_status(struct cpcap_battery_ddata *ddata)
  320. {
  321. struct cpcap_battery_state_data state, *latest, *previous;
  322. ktime_t now;
  323. int error;
  324. memset(&state, 0, sizeof(state));
  325. now = ktime_get();
  326. latest = cpcap_battery_latest(ddata);
  327. if (latest) {
  328. s64 delta_ms = ktime_to_ms(ktime_sub(now, latest->time));
  329. if (delta_ms < CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS)
  330. return delta_ms;
  331. }
  332. state.time = now;
  333. state.voltage = cpcap_battery_get_voltage(ddata);
  334. state.current_ua = cpcap_battery_get_current(ddata);
  335. state.counter_uah = cpcap_battery_read_accumulated(ddata, &state.cc);
  336. error = cpcap_charger_battery_temperature(ddata,
  337. &state.temperature);
  338. if (error)
  339. return error;
  340. previous = cpcap_battery_previous(ddata);
  341. memcpy(previous, latest, sizeof(*previous));
  342. memcpy(latest, &state, sizeof(*latest));
  343. return 0;
  344. }
  345. static enum power_supply_property cpcap_battery_props[] = {
  346. POWER_SUPPLY_PROP_STATUS,
  347. POWER_SUPPLY_PROP_PRESENT,
  348. POWER_SUPPLY_PROP_TECHNOLOGY,
  349. POWER_SUPPLY_PROP_VOLTAGE_NOW,
  350. POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
  351. POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
  352. POWER_SUPPLY_PROP_CURRENT_AVG,
  353. POWER_SUPPLY_PROP_CURRENT_NOW,
  354. POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
  355. POWER_SUPPLY_PROP_CHARGE_COUNTER,
  356. POWER_SUPPLY_PROP_POWER_NOW,
  357. POWER_SUPPLY_PROP_POWER_AVG,
  358. POWER_SUPPLY_PROP_CAPACITY_LEVEL,
  359. POWER_SUPPLY_PROP_SCOPE,
  360. POWER_SUPPLY_PROP_TEMP,
  361. };
  362. static int cpcap_battery_get_property(struct power_supply *psy,
  363. enum power_supply_property psp,
  364. union power_supply_propval *val)
  365. {
  366. struct cpcap_battery_ddata *ddata = power_supply_get_drvdata(psy);
  367. struct cpcap_battery_state_data *latest, *previous;
  368. u32 sample;
  369. s32 accumulator;
  370. int cached;
  371. s64 tmp;
  372. cached = cpcap_battery_update_status(ddata);
  373. if (cached < 0)
  374. return cached;
  375. latest = cpcap_battery_latest(ddata);
  376. previous = cpcap_battery_previous(ddata);
  377. switch (psp) {
  378. case POWER_SUPPLY_PROP_PRESENT:
  379. if (latest->temperature > CPCAP_NO_BATTERY)
  380. val->intval = 1;
  381. else
  382. val->intval = 0;
  383. break;
  384. case POWER_SUPPLY_PROP_STATUS:
  385. if (cpcap_battery_full(ddata)) {
  386. val->intval = POWER_SUPPLY_STATUS_FULL;
  387. break;
  388. }
  389. if (cpcap_battery_cc_get_avg_current(ddata) < 0)
  390. val->intval = POWER_SUPPLY_STATUS_CHARGING;
  391. else
  392. val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
  393. break;
  394. case POWER_SUPPLY_PROP_TECHNOLOGY:
  395. val->intval = ddata->config.info.technology;
  396. break;
  397. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  398. val->intval = cpcap_battery_get_voltage(ddata);
  399. break;
  400. case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
  401. val->intval = ddata->config.info.voltage_max_design;
  402. break;
  403. case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
  404. val->intval = ddata->config.info.voltage_min_design;
  405. break;
  406. case POWER_SUPPLY_PROP_CURRENT_AVG:
  407. if (cached) {
  408. val->intval = cpcap_battery_cc_get_avg_current(ddata);
  409. break;
  410. }
  411. sample = latest->cc.sample - previous->cc.sample;
  412. accumulator = latest->cc.accumulator - previous->cc.accumulator;
  413. val->intval = cpcap_battery_cc_to_ua(ddata, sample,
  414. accumulator,
  415. latest->cc.offset);
  416. break;
  417. case POWER_SUPPLY_PROP_CURRENT_NOW:
  418. val->intval = latest->current_ua;
  419. break;
  420. case POWER_SUPPLY_PROP_CHARGE_COUNTER:
  421. val->intval = latest->counter_uah;
  422. break;
  423. case POWER_SUPPLY_PROP_POWER_NOW:
  424. tmp = (latest->voltage / 10000) * latest->current_ua;
  425. val->intval = div64_s64(tmp, 100);
  426. break;
  427. case POWER_SUPPLY_PROP_POWER_AVG:
  428. if (cached) {
  429. tmp = cpcap_battery_cc_get_avg_current(ddata);
  430. tmp *= (latest->voltage / 10000);
  431. val->intval = div64_s64(tmp, 100);
  432. break;
  433. }
  434. sample = latest->cc.sample - previous->cc.sample;
  435. accumulator = latest->cc.accumulator - previous->cc.accumulator;
  436. tmp = cpcap_battery_cc_to_ua(ddata, sample, accumulator,
  437. latest->cc.offset);
  438. tmp *= ((latest->voltage + previous->voltage) / 20000);
  439. val->intval = div64_s64(tmp, 100);
  440. break;
  441. case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
  442. if (cpcap_battery_full(ddata))
  443. val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
  444. else if (latest->voltage >= 3750000)
  445. val->intval = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
  446. else if (latest->voltage >= 3300000)
  447. val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
  448. else if (latest->voltage > 3100000)
  449. val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
  450. else if (latest->voltage <= 3100000)
  451. val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
  452. else
  453. val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
  454. break;
  455. case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
  456. val->intval = ddata->config.info.charge_full_design;
  457. break;
  458. case POWER_SUPPLY_PROP_SCOPE:
  459. val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
  460. break;
  461. case POWER_SUPPLY_PROP_TEMP:
  462. val->intval = latest->temperature;
  463. break;
  464. default:
  465. return -EINVAL;
  466. }
  467. return 0;
  468. }
  469. static irqreturn_t cpcap_battery_irq_thread(int irq, void *data)
  470. {
  471. struct cpcap_battery_ddata *ddata = data;
  472. struct cpcap_battery_state_data *latest;
  473. struct cpcap_interrupt_desc *d;
  474. if (!atomic_read(&ddata->active))
  475. return IRQ_NONE;
  476. list_for_each_entry(d, &ddata->irq_list, node) {
  477. if (irq == d->irq)
  478. break;
  479. }
  480. if (!d)
  481. return IRQ_NONE;
  482. latest = cpcap_battery_latest(ddata);
  483. switch (d->action) {
  484. case CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW:
  485. if (latest->counter_uah >= 0)
  486. dev_warn(ddata->dev, "Battery low at 3.3V!\n");
  487. break;
  488. case CPCAP_BATTERY_IRQ_ACTION_POWEROFF:
  489. if (latest->counter_uah >= 0) {
  490. dev_emerg(ddata->dev,
  491. "Battery empty at 3.1V, powering off\n");
  492. orderly_poweroff(true);
  493. }
  494. break;
  495. default:
  496. break;
  497. }
  498. power_supply_changed(ddata->psy);
  499. return IRQ_HANDLED;
  500. }
  501. static int cpcap_battery_init_irq(struct platform_device *pdev,
  502. struct cpcap_battery_ddata *ddata,
  503. const char *name)
  504. {
  505. struct cpcap_interrupt_desc *d;
  506. int irq, error;
  507. irq = platform_get_irq_byname(pdev, name);
  508. if (!irq)
  509. return -ENODEV;
  510. error = devm_request_threaded_irq(ddata->dev, irq, NULL,
  511. cpcap_battery_irq_thread,
  512. IRQF_SHARED,
  513. name, ddata);
  514. if (error) {
  515. dev_err(ddata->dev, "could not get irq %s: %i\n",
  516. name, error);
  517. return error;
  518. }
  519. d = devm_kzalloc(ddata->dev, sizeof(*d), GFP_KERNEL);
  520. if (!d)
  521. return -ENOMEM;
  522. d->name = name;
  523. d->irq = irq;
  524. if (!strncmp(name, "lowbph", 6))
  525. d->action = CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW;
  526. else if (!strncmp(name, "lowbpl", 6))
  527. d->action = CPCAP_BATTERY_IRQ_ACTION_POWEROFF;
  528. list_add(&d->node, &ddata->irq_list);
  529. return 0;
  530. }
  531. static int cpcap_battery_init_interrupts(struct platform_device *pdev,
  532. struct cpcap_battery_ddata *ddata)
  533. {
  534. const char * const cpcap_battery_irqs[] = {
  535. "eol", "lowbph", "lowbpl",
  536. "chrgcurr1", "battdetb"
  537. };
  538. int i, error;
  539. for (i = 0; i < ARRAY_SIZE(cpcap_battery_irqs); i++) {
  540. error = cpcap_battery_init_irq(pdev, ddata,
  541. cpcap_battery_irqs[i]);
  542. if (error)
  543. return error;
  544. }
  545. /* Enable low battery interrupts for 3.3V high and 3.1V low */
  546. error = regmap_update_bits(ddata->reg, CPCAP_REG_BPEOL,
  547. 0xffff,
  548. CPCAP_REG_BPEOL_BIT_BATTDETEN);
  549. if (error)
  550. return error;
  551. return 0;
  552. }
  553. static int cpcap_battery_init_iio(struct cpcap_battery_ddata *ddata)
  554. {
  555. const char * const names[CPCAP_BATTERY_IIO_NR] = {
  556. "battdetb", "battp", "chg_isense", "batti",
  557. };
  558. int error, i;
  559. for (i = 0; i < CPCAP_BATTERY_IIO_NR; i++) {
  560. ddata->channels[i] = devm_iio_channel_get(ddata->dev,
  561. names[i]);
  562. if (IS_ERR(ddata->channels[i])) {
  563. error = PTR_ERR(ddata->channels[i]);
  564. goto out_err;
  565. }
  566. if (!ddata->channels[i]->indio_dev) {
  567. error = -ENXIO;
  568. goto out_err;
  569. }
  570. }
  571. return 0;
  572. out_err:
  573. dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n",
  574. error);
  575. return error;
  576. }
  577. /*
  578. * Based on the values from Motorola mapphone Linux kernel. In the
  579. * the Motorola mapphone Linux kernel tree the value for pm_cd_factor
  580. * is passed to the kernel via device tree. If it turns out to be
  581. * something device specific we can consider that too later.
  582. *
  583. * And looking at the battery full and shutdown values for the stock
  584. * kernel on droid 4, full is 4351000 and software initiates shutdown
  585. * at 3078000. The device will die around 2743000.
  586. */
  587. static const struct cpcap_battery_config cpcap_battery_default_data = {
  588. .ccm = 0x3ff,
  589. .cd_factor = 0x3cc,
  590. .info.technology = POWER_SUPPLY_TECHNOLOGY_LION,
  591. .info.voltage_max_design = 4351000,
  592. .info.voltage_min_design = 3100000,
  593. .info.charge_full_design = 1740000,
  594. };
  595. #ifdef CONFIG_OF
  596. static const struct of_device_id cpcap_battery_id_table[] = {
  597. {
  598. .compatible = "motorola,cpcap-battery",
  599. .data = &cpcap_battery_default_data,
  600. },
  601. {},
  602. };
  603. MODULE_DEVICE_TABLE(of, cpcap_battery_id_table);
  604. #endif
  605. static int cpcap_battery_probe(struct platform_device *pdev)
  606. {
  607. struct power_supply_desc *psy_desc;
  608. struct cpcap_battery_ddata *ddata;
  609. const struct of_device_id *match;
  610. struct power_supply_config psy_cfg = {};
  611. int error;
  612. match = of_match_device(of_match_ptr(cpcap_battery_id_table),
  613. &pdev->dev);
  614. if (!match)
  615. return -EINVAL;
  616. if (!match->data) {
  617. dev_err(&pdev->dev, "no configuration data found\n");
  618. return -ENODEV;
  619. }
  620. ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
  621. if (!ddata)
  622. return -ENOMEM;
  623. INIT_LIST_HEAD(&ddata->irq_list);
  624. ddata->dev = &pdev->dev;
  625. memcpy(&ddata->config, match->data, sizeof(ddata->config));
  626. ddata->reg = dev_get_regmap(ddata->dev->parent, NULL);
  627. if (!ddata->reg)
  628. return -ENODEV;
  629. error = cpcap_get_vendor(ddata->dev, ddata->reg, &ddata->vendor);
  630. if (error)
  631. return error;
  632. platform_set_drvdata(pdev, ddata);
  633. error = regmap_update_bits(ddata->reg, CPCAP_REG_CCM,
  634. 0xffff, ddata->config.ccm);
  635. if (error)
  636. return error;
  637. error = cpcap_battery_init_interrupts(pdev, ddata);
  638. if (error)
  639. return error;
  640. error = cpcap_battery_init_iio(ddata);
  641. if (error)
  642. return error;
  643. psy_desc = devm_kzalloc(ddata->dev, sizeof(*psy_desc), GFP_KERNEL);
  644. if (!psy_desc)
  645. return -ENOMEM;
  646. psy_desc->name = "battery",
  647. psy_desc->type = POWER_SUPPLY_TYPE_BATTERY,
  648. psy_desc->properties = cpcap_battery_props,
  649. psy_desc->num_properties = ARRAY_SIZE(cpcap_battery_props),
  650. psy_desc->get_property = cpcap_battery_get_property,
  651. psy_cfg.of_node = pdev->dev.of_node;
  652. psy_cfg.drv_data = ddata;
  653. ddata->psy = devm_power_supply_register(ddata->dev, psy_desc,
  654. &psy_cfg);
  655. error = PTR_ERR_OR_ZERO(ddata->psy);
  656. if (error) {
  657. dev_err(ddata->dev, "failed to register power supply\n");
  658. return error;
  659. }
  660. atomic_set(&ddata->active, 1);
  661. return 0;
  662. }
  663. static int cpcap_battery_remove(struct platform_device *pdev)
  664. {
  665. struct cpcap_battery_ddata *ddata = platform_get_drvdata(pdev);
  666. int error;
  667. atomic_set(&ddata->active, 0);
  668. error = regmap_update_bits(ddata->reg, CPCAP_REG_BPEOL,
  669. 0xffff, 0);
  670. if (error)
  671. dev_err(&pdev->dev, "could not disable: %i\n", error);
  672. return 0;
  673. }
  674. static struct platform_driver cpcap_battery_driver = {
  675. .driver = {
  676. .name = "cpcap_battery",
  677. .of_match_table = of_match_ptr(cpcap_battery_id_table),
  678. },
  679. .probe = cpcap_battery_probe,
  680. .remove = cpcap_battery_remove,
  681. };
  682. module_platform_driver(cpcap_battery_driver);
  683. MODULE_LICENSE("GPL v2");
  684. MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
  685. MODULE_DESCRIPTION("CPCAP PMIC Battery Driver");