88pm860x_battery.c 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  1. /*
  2. * Battery driver for Marvell 88PM860x PMIC
  3. *
  4. * Copyright (c) 2012 Marvell International Ltd.
  5. * Author: Jett Zhou <jtzhou@marvell.com>
  6. * Haojian Zhuang <haojian.zhuang@marvell.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/module.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/slab.h>
  16. #include <linux/mutex.h>
  17. #include <linux/string.h>
  18. #include <linux/power_supply.h>
  19. #include <linux/mfd/88pm860x.h>
  20. #include <linux/delay.h>
  21. /* bit definitions of Status Query Interface 2 */
  22. #define STATUS2_CHG (1 << 2)
  23. #define STATUS2_BAT (1 << 3)
  24. #define STATUS2_VBUS (1 << 4)
  25. /* bit definitions of Measurement Enable 1 Register */
  26. #define MEAS1_TINT (1 << 3)
  27. #define MEAS1_GP1 (1 << 5)
  28. /* bit definitions of Measurement Enable 3 Register */
  29. #define MEAS3_IBAT (1 << 0)
  30. #define MEAS3_BAT_DET (1 << 1)
  31. #define MEAS3_CC (1 << 2)
  32. /* bit definitions of Measurement Off Time Register */
  33. #define MEAS_OFF_SLEEP_EN (1 << 1)
  34. /* bit definitions of GPADC Bias Current 2 Register */
  35. #define GPBIAS2_GPADC1_SET (2 << 4)
  36. /* GPADC1 Bias Current value in uA unit */
  37. #define GPBIAS2_GPADC1_UA ((GPBIAS2_GPADC1_SET >> 4) * 5 + 1)
  38. /* bit definitions of GPADC Misc 1 Register */
  39. #define GPMISC1_GPADC_EN (1 << 0)
  40. /* bit definitions of Charger Control 6 Register */
  41. #define CC6_BAT_DET_GPADC1 1
  42. /* bit definitions of Coulomb Counter Reading Register */
  43. #define CCNT_AVG_SEL (4 << 3)
  44. /* bit definitions of RTC miscellaneous Register1 */
  45. #define RTC_SOC_5LSB (0x1F << 3)
  46. /* bit definitions of RTC Register1 */
  47. #define RTC_SOC_3MSB (0x7)
  48. /* bit definitions of Power up Log register */
  49. #define BAT_WU_LOG (1<<6)
  50. /* coulomb counter index */
  51. #define CCNT_POS1 0
  52. #define CCNT_POS2 1
  53. #define CCNT_NEG1 2
  54. #define CCNT_NEG2 3
  55. #define CCNT_SPOS 4
  56. #define CCNT_SNEG 5
  57. /* OCV -- Open Circuit Voltage */
  58. #define OCV_MODE_ACTIVE 0
  59. #define OCV_MODE_SLEEP 1
  60. /* Vbat range of CC for measuring Rbat */
  61. #define LOW_BAT_THRESHOLD 3600
  62. #define VBATT_RESISTOR_MIN 3800
  63. #define VBATT_RESISTOR_MAX 4100
  64. /* TBAT for batt, TINT for chip itself */
  65. #define PM860X_TEMP_TINT (0)
  66. #define PM860X_TEMP_TBAT (1)
  67. /*
  68. * Battery temperature based on NTC resistor, defined
  69. * corresponding resistor value -- Ohm / C degeree.
  70. */
  71. #define TBAT_NEG_25D 127773 /* -25 */
  72. #define TBAT_NEG_10D 54564 /* -10 */
  73. #define TBAT_0D 32330 /* 0 */
  74. #define TBAT_10D 19785 /* 10 */
  75. #define TBAT_20D 12468 /* 20 */
  76. #define TBAT_30D 8072 /* 30 */
  77. #define TBAT_40D 5356 /* 40 */
  78. struct pm860x_battery_info {
  79. struct pm860x_chip *chip;
  80. struct i2c_client *i2c;
  81. struct device *dev;
  82. struct power_supply *battery;
  83. struct mutex lock;
  84. int status;
  85. int irq_cc;
  86. int irq_batt;
  87. int max_capacity;
  88. int resistor; /* Battery Internal Resistor */
  89. int last_capacity;
  90. int start_soc;
  91. unsigned present:1;
  92. unsigned temp_type:1; /* TINT or TBAT */
  93. };
  94. struct ccnt {
  95. unsigned long long int pos;
  96. unsigned long long int neg;
  97. unsigned int spos;
  98. unsigned int sneg;
  99. int total_chg; /* mAh(3.6C) */
  100. int total_dischg; /* mAh(3.6C) */
  101. };
  102. /*
  103. * State of Charge.
  104. * The first number is mAh(=3.6C), and the second number is percent point.
  105. */
  106. static int array_soc[][2] = {
  107. {4170, 100}, {4154, 99}, {4136, 98}, {4122, 97}, {4107, 96},
  108. {4102, 95}, {4088, 94}, {4081, 93}, {4070, 92}, {4060, 91},
  109. {4053, 90}, {4044, 89}, {4035, 88}, {4028, 87}, {4019, 86},
  110. {4013, 85}, {4006, 84}, {3995, 83}, {3987, 82}, {3982, 81},
  111. {3976, 80}, {3968, 79}, {3962, 78}, {3954, 77}, {3946, 76},
  112. {3941, 75}, {3934, 74}, {3929, 73}, {3922, 72}, {3916, 71},
  113. {3910, 70}, {3904, 69}, {3898, 68}, {3892, 67}, {3887, 66},
  114. {3880, 65}, {3874, 64}, {3868, 63}, {3862, 62}, {3854, 61},
  115. {3849, 60}, {3843, 59}, {3840, 58}, {3833, 57}, {3829, 56},
  116. {3824, 55}, {3818, 54}, {3815, 53}, {3810, 52}, {3808, 51},
  117. {3804, 50}, {3801, 49}, {3798, 48}, {3796, 47}, {3792, 46},
  118. {3789, 45}, {3785, 44}, {3784, 43}, {3782, 42}, {3780, 41},
  119. {3777, 40}, {3776, 39}, {3774, 38}, {3772, 37}, {3771, 36},
  120. {3769, 35}, {3768, 34}, {3764, 33}, {3763, 32}, {3760, 31},
  121. {3760, 30}, {3754, 29}, {3750, 28}, {3749, 27}, {3744, 26},
  122. {3740, 25}, {3734, 24}, {3732, 23}, {3728, 22}, {3726, 21},
  123. {3720, 20}, {3716, 19}, {3709, 18}, {3703, 17}, {3698, 16},
  124. {3692, 15}, {3683, 14}, {3675, 13}, {3670, 12}, {3665, 11},
  125. {3661, 10}, {3649, 9}, {3637, 8}, {3622, 7}, {3609, 6},
  126. {3580, 5}, {3558, 4}, {3540, 3}, {3510, 2}, {3429, 1},
  127. };
  128. static struct ccnt ccnt_data;
  129. /*
  130. * register 1 bit[7:0] -- bit[11:4] of measured value of voltage
  131. * register 0 bit[3:0] -- bit[3:0] of measured value of voltage
  132. */
  133. static int measure_12bit_voltage(struct pm860x_battery_info *info,
  134. int offset, int *data)
  135. {
  136. unsigned char buf[2];
  137. int ret;
  138. ret = pm860x_bulk_read(info->i2c, offset, 2, buf);
  139. if (ret < 0)
  140. return ret;
  141. *data = ((buf[0] & 0xff) << 4) | (buf[1] & 0x0f);
  142. /* V_MEAS(mV) = data * 1.8 * 1000 / (2^12) */
  143. *data = ((*data & 0xfff) * 9 * 25) >> 9;
  144. return 0;
  145. }
  146. static int measure_vbatt(struct pm860x_battery_info *info, int state,
  147. int *data)
  148. {
  149. unsigned char buf[5];
  150. int ret;
  151. switch (state) {
  152. case OCV_MODE_ACTIVE:
  153. ret = measure_12bit_voltage(info, PM8607_VBAT_MEAS1, data);
  154. if (ret)
  155. return ret;
  156. /* V_BATT_MEAS(mV) = value * 3 * 1.8 * 1000 / (2^12) */
  157. *data *= 3;
  158. break;
  159. case OCV_MODE_SLEEP:
  160. /*
  161. * voltage value of VBATT in sleep mode is saved in different
  162. * registers.
  163. * bit[11:10] -- bit[7:6] of LDO9(0x18)
  164. * bit[9:8] -- bit[7:6] of LDO8(0x17)
  165. * bit[7:6] -- bit[7:6] of LDO7(0x16)
  166. * bit[5:4] -- bit[7:6] of LDO6(0x15)
  167. * bit[3:0] -- bit[7:4] of LDO5(0x14)
  168. */
  169. ret = pm860x_bulk_read(info->i2c, PM8607_LDO5, 5, buf);
  170. if (ret < 0)
  171. return ret;
  172. ret = ((buf[4] >> 6) << 10) | ((buf[3] >> 6) << 8)
  173. | ((buf[2] >> 6) << 6) | ((buf[1] >> 6) << 4)
  174. | (buf[0] >> 4);
  175. /* V_BATT_MEAS(mV) = data * 3 * 1.8 * 1000 / (2^12) */
  176. *data = ((*data & 0xff) * 27 * 25) >> 9;
  177. break;
  178. default:
  179. return -EINVAL;
  180. }
  181. return 0;
  182. }
  183. /*
  184. * Return value is signed data.
  185. * Negative value means discharging, and positive value means charging.
  186. */
  187. static int measure_current(struct pm860x_battery_info *info, int *data)
  188. {
  189. unsigned char buf[2];
  190. short s;
  191. int ret;
  192. ret = pm860x_bulk_read(info->i2c, PM8607_IBAT_MEAS1, 2, buf);
  193. if (ret < 0)
  194. return ret;
  195. s = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff);
  196. /* current(mA) = value * 0.125 */
  197. *data = s >> 3;
  198. return 0;
  199. }
  200. static int set_charger_current(struct pm860x_battery_info *info, int data,
  201. int *old)
  202. {
  203. int ret;
  204. if (data < 50 || data > 1600 || !old)
  205. return -EINVAL;
  206. data = ((data - 50) / 50) & 0x1f;
  207. *old = pm860x_reg_read(info->i2c, PM8607_CHG_CTRL2);
  208. *old = (*old & 0x1f) * 50 + 50;
  209. ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL2, 0x1f, data);
  210. if (ret < 0)
  211. return ret;
  212. return 0;
  213. }
  214. static int read_ccnt(struct pm860x_battery_info *info, int offset,
  215. int *ccnt)
  216. {
  217. unsigned char buf[2];
  218. int ret;
  219. ret = pm860x_set_bits(info->i2c, PM8607_CCNT, 7, offset & 7);
  220. if (ret < 0)
  221. goto out;
  222. ret = pm860x_bulk_read(info->i2c, PM8607_CCNT_MEAS1, 2, buf);
  223. if (ret < 0)
  224. goto out;
  225. *ccnt = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff);
  226. return 0;
  227. out:
  228. return ret;
  229. }
  230. static int calc_ccnt(struct pm860x_battery_info *info, struct ccnt *ccnt)
  231. {
  232. unsigned int sum;
  233. int ret;
  234. int data;
  235. ret = read_ccnt(info, CCNT_POS1, &data);
  236. if (ret)
  237. goto out;
  238. sum = data & 0xffff;
  239. ret = read_ccnt(info, CCNT_POS2, &data);
  240. if (ret)
  241. goto out;
  242. sum |= (data & 0xffff) << 16;
  243. ccnt->pos += sum;
  244. ret = read_ccnt(info, CCNT_NEG1, &data);
  245. if (ret)
  246. goto out;
  247. sum = data & 0xffff;
  248. ret = read_ccnt(info, CCNT_NEG2, &data);
  249. if (ret)
  250. goto out;
  251. sum |= (data & 0xffff) << 16;
  252. sum = ~sum + 1; /* since it's negative */
  253. ccnt->neg += sum;
  254. ret = read_ccnt(info, CCNT_SPOS, &data);
  255. if (ret)
  256. goto out;
  257. ccnt->spos += data;
  258. ret = read_ccnt(info, CCNT_SNEG, &data);
  259. if (ret)
  260. goto out;
  261. /*
  262. * charge(mAh) = count * 1.6984 * 1e(-8)
  263. * = count * 16984 * 1.024 * 1.024 * 1.024 / (2 ^ 40)
  264. * = count * 18236 / (2 ^ 40)
  265. */
  266. ccnt->total_chg = (int) ((ccnt->pos * 18236) >> 40);
  267. ccnt->total_dischg = (int) ((ccnt->neg * 18236) >> 40);
  268. return 0;
  269. out:
  270. return ret;
  271. }
  272. static int clear_ccnt(struct pm860x_battery_info *info, struct ccnt *ccnt)
  273. {
  274. int data;
  275. memset(ccnt, 0, sizeof(*ccnt));
  276. /* read to clear ccnt */
  277. read_ccnt(info, CCNT_POS1, &data);
  278. read_ccnt(info, CCNT_POS2, &data);
  279. read_ccnt(info, CCNT_NEG1, &data);
  280. read_ccnt(info, CCNT_NEG2, &data);
  281. read_ccnt(info, CCNT_SPOS, &data);
  282. read_ccnt(info, CCNT_SNEG, &data);
  283. return 0;
  284. }
  285. /* Calculate Open Circuit Voltage */
  286. static int calc_ocv(struct pm860x_battery_info *info, int *ocv)
  287. {
  288. int ret;
  289. int i;
  290. int data;
  291. int vbatt_avg;
  292. int vbatt_sum;
  293. int ibatt_avg;
  294. int ibatt_sum;
  295. if (!ocv)
  296. return -EINVAL;
  297. for (i = 0, ibatt_sum = 0, vbatt_sum = 0; i < 10; i++) {
  298. ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
  299. if (ret)
  300. goto out;
  301. vbatt_sum += data;
  302. ret = measure_current(info, &data);
  303. if (ret)
  304. goto out;
  305. ibatt_sum += data;
  306. }
  307. vbatt_avg = vbatt_sum / 10;
  308. ibatt_avg = ibatt_sum / 10;
  309. mutex_lock(&info->lock);
  310. if (info->present)
  311. *ocv = vbatt_avg - ibatt_avg * info->resistor / 1000;
  312. else
  313. *ocv = vbatt_avg;
  314. mutex_unlock(&info->lock);
  315. dev_dbg(info->dev, "VBAT average:%d, OCV:%d\n", vbatt_avg, *ocv);
  316. return 0;
  317. out:
  318. return ret;
  319. }
  320. /* Calculate State of Charge (percent points) */
  321. static int calc_soc(struct pm860x_battery_info *info, int state, int *soc)
  322. {
  323. int i;
  324. int ocv;
  325. int count;
  326. int ret = -EINVAL;
  327. if (!soc)
  328. return -EINVAL;
  329. switch (state) {
  330. case OCV_MODE_ACTIVE:
  331. ret = calc_ocv(info, &ocv);
  332. break;
  333. case OCV_MODE_SLEEP:
  334. ret = measure_vbatt(info, OCV_MODE_SLEEP, &ocv);
  335. break;
  336. }
  337. if (ret)
  338. return ret;
  339. count = ARRAY_SIZE(array_soc);
  340. if (ocv < array_soc[count - 1][0]) {
  341. *soc = 0;
  342. return 0;
  343. }
  344. for (i = 0; i < count; i++) {
  345. if (ocv >= array_soc[i][0]) {
  346. *soc = array_soc[i][1];
  347. break;
  348. }
  349. }
  350. return 0;
  351. }
  352. static irqreturn_t pm860x_coulomb_handler(int irq, void *data)
  353. {
  354. struct pm860x_battery_info *info = data;
  355. calc_ccnt(info, &ccnt_data);
  356. return IRQ_HANDLED;
  357. }
  358. static irqreturn_t pm860x_batt_handler(int irq, void *data)
  359. {
  360. struct pm860x_battery_info *info = data;
  361. int ret;
  362. mutex_lock(&info->lock);
  363. ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
  364. if (ret & STATUS2_BAT) {
  365. info->present = 1;
  366. info->temp_type = PM860X_TEMP_TBAT;
  367. } else {
  368. info->present = 0;
  369. info->temp_type = PM860X_TEMP_TINT;
  370. }
  371. mutex_unlock(&info->lock);
  372. /* clear ccnt since battery is attached or dettached */
  373. clear_ccnt(info, &ccnt_data);
  374. return IRQ_HANDLED;
  375. }
  376. static void pm860x_init_battery(struct pm860x_battery_info *info)
  377. {
  378. unsigned char buf[2];
  379. int ret;
  380. int data;
  381. int bat_remove;
  382. int soc;
  383. /* measure enable on GPADC1 */
  384. data = MEAS1_GP1;
  385. if (info->temp_type == PM860X_TEMP_TINT)
  386. data |= MEAS1_TINT;
  387. ret = pm860x_set_bits(info->i2c, PM8607_MEAS_EN1, data, data);
  388. if (ret)
  389. goto out;
  390. /* measure enable on IBAT, BAT_DET, CC. IBAT is depend on CC. */
  391. data = MEAS3_IBAT | MEAS3_BAT_DET | MEAS3_CC;
  392. ret = pm860x_set_bits(info->i2c, PM8607_MEAS_EN3, data, data);
  393. if (ret)
  394. goto out;
  395. /* measure disable CC in sleep time */
  396. ret = pm860x_reg_write(info->i2c, PM8607_MEAS_OFF_TIME1, 0x82);
  397. if (ret)
  398. goto out;
  399. ret = pm860x_reg_write(info->i2c, PM8607_MEAS_OFF_TIME2, 0x6c);
  400. if (ret)
  401. goto out;
  402. /* enable GPADC */
  403. ret = pm860x_set_bits(info->i2c, PM8607_GPADC_MISC1,
  404. GPMISC1_GPADC_EN, GPMISC1_GPADC_EN);
  405. if (ret < 0)
  406. goto out;
  407. /* detect battery via GPADC1 */
  408. ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL6,
  409. CC6_BAT_DET_GPADC1, CC6_BAT_DET_GPADC1);
  410. if (ret < 0)
  411. goto out;
  412. ret = pm860x_set_bits(info->i2c, PM8607_CCNT, 7 << 3,
  413. CCNT_AVG_SEL);
  414. if (ret < 0)
  415. goto out;
  416. /* set GPADC1 bias */
  417. ret = pm860x_set_bits(info->i2c, PM8607_GP_BIAS2, 0xF << 4,
  418. GPBIAS2_GPADC1_SET);
  419. if (ret < 0)
  420. goto out;
  421. /* check whether battery present) */
  422. mutex_lock(&info->lock);
  423. ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
  424. if (ret < 0) {
  425. mutex_unlock(&info->lock);
  426. goto out;
  427. }
  428. if (ret & STATUS2_BAT) {
  429. info->present = 1;
  430. info->temp_type = PM860X_TEMP_TBAT;
  431. } else {
  432. info->present = 0;
  433. info->temp_type = PM860X_TEMP_TINT;
  434. }
  435. mutex_unlock(&info->lock);
  436. calc_soc(info, OCV_MODE_ACTIVE, &soc);
  437. data = pm860x_reg_read(info->i2c, PM8607_POWER_UP_LOG);
  438. bat_remove = data & BAT_WU_LOG;
  439. dev_dbg(info->dev, "battery wake up? %s\n",
  440. bat_remove != 0 ? "yes" : "no");
  441. /* restore SOC from RTC domain register */
  442. if (bat_remove == 0) {
  443. buf[0] = pm860x_reg_read(info->i2c, PM8607_RTC_MISC2);
  444. buf[1] = pm860x_reg_read(info->i2c, PM8607_RTC1);
  445. data = ((buf[1] & 0x3) << 5) | ((buf[0] >> 3) & 0x1F);
  446. if (data > soc + 15)
  447. info->start_soc = soc;
  448. else if (data < soc - 15)
  449. info->start_soc = soc;
  450. else
  451. info->start_soc = data;
  452. dev_dbg(info->dev, "soc_rtc %d, soc_ocv :%d\n", data, soc);
  453. } else {
  454. pm860x_set_bits(info->i2c, PM8607_POWER_UP_LOG,
  455. BAT_WU_LOG, BAT_WU_LOG);
  456. info->start_soc = soc;
  457. }
  458. info->last_capacity = info->start_soc;
  459. dev_dbg(info->dev, "init soc : %d\n", info->last_capacity);
  460. out:
  461. return;
  462. }
  463. static void set_temp_threshold(struct pm860x_battery_info *info,
  464. int min, int max)
  465. {
  466. int data;
  467. /* (tmp << 8) / 1800 */
  468. if (min <= 0)
  469. data = 0;
  470. else
  471. data = (min << 8) / 1800;
  472. pm860x_reg_write(info->i2c, PM8607_GPADC1_HIGHTH, data);
  473. dev_dbg(info->dev, "TEMP_HIGHTH : min: %d, 0x%x\n", min, data);
  474. if (max <= 0)
  475. data = 0xff;
  476. else
  477. data = (max << 8) / 1800;
  478. pm860x_reg_write(info->i2c, PM8607_GPADC1_LOWTH, data);
  479. dev_dbg(info->dev, "TEMP_LOWTH:max : %d, 0x%x\n", max, data);
  480. }
  481. static int measure_temp(struct pm860x_battery_info *info, int *data)
  482. {
  483. int ret;
  484. int temp;
  485. int min;
  486. int max;
  487. if (info->temp_type == PM860X_TEMP_TINT) {
  488. ret = measure_12bit_voltage(info, PM8607_TINT_MEAS1, data);
  489. if (ret)
  490. return ret;
  491. *data = (*data - 884) * 1000 / 3611;
  492. } else {
  493. ret = measure_12bit_voltage(info, PM8607_GPADC1_MEAS1, data);
  494. if (ret)
  495. return ret;
  496. /* meausered Vtbat(mV) / Ibias_current(11uA)*/
  497. *data = (*data * 1000) / GPBIAS2_GPADC1_UA;
  498. if (*data > TBAT_NEG_25D) {
  499. temp = -30; /* over cold , suppose -30 roughly */
  500. max = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
  501. set_temp_threshold(info, 0, max);
  502. } else if (*data > TBAT_NEG_10D) {
  503. temp = -15; /* -15 degree, code */
  504. max = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
  505. set_temp_threshold(info, 0, max);
  506. } else if (*data > TBAT_0D) {
  507. temp = -5; /* -5 degree */
  508. min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
  509. max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
  510. set_temp_threshold(info, min, max);
  511. } else if (*data > TBAT_10D) {
  512. temp = 5; /* in range of (0, 10) */
  513. min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
  514. max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
  515. set_temp_threshold(info, min, max);
  516. } else if (*data > TBAT_20D) {
  517. temp = 15; /* in range of (10, 20) */
  518. min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
  519. max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
  520. set_temp_threshold(info, min, max);
  521. } else if (*data > TBAT_30D) {
  522. temp = 25; /* in range of (20, 30) */
  523. min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
  524. max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
  525. set_temp_threshold(info, min, max);
  526. } else if (*data > TBAT_40D) {
  527. temp = 35; /* in range of (30, 40) */
  528. min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
  529. max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
  530. set_temp_threshold(info, min, max);
  531. } else {
  532. min = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
  533. set_temp_threshold(info, min, 0);
  534. temp = 45; /* over heat ,suppose 45 roughly */
  535. }
  536. dev_dbg(info->dev, "temp_C:%d C,temp_mv:%d mv\n", temp, *data);
  537. *data = temp;
  538. }
  539. return 0;
  540. }
  541. static int calc_resistor(struct pm860x_battery_info *info)
  542. {
  543. int vbatt_sum1;
  544. int vbatt_sum2;
  545. int chg_current;
  546. int ibatt_sum1;
  547. int ibatt_sum2;
  548. int data;
  549. int ret;
  550. int i;
  551. ret = measure_current(info, &data);
  552. /* make sure that charging is launched by data > 0 */
  553. if (ret || data < 0)
  554. goto out;
  555. ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
  556. if (ret)
  557. goto out;
  558. /* calculate resistor only in CC charge mode */
  559. if (data < VBATT_RESISTOR_MIN || data > VBATT_RESISTOR_MAX)
  560. goto out;
  561. /* current is saved */
  562. if (set_charger_current(info, 500, &chg_current))
  563. goto out;
  564. /*
  565. * set charge current as 500mA, wait about 500ms till charging
  566. * process is launched and stable with the newer charging current.
  567. */
  568. msleep(500);
  569. for (i = 0, vbatt_sum1 = 0, ibatt_sum1 = 0; i < 10; i++) {
  570. ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
  571. if (ret)
  572. goto out_meas;
  573. vbatt_sum1 += data;
  574. ret = measure_current(info, &data);
  575. if (ret)
  576. goto out_meas;
  577. if (data < 0)
  578. ibatt_sum1 = ibatt_sum1 - data; /* discharging */
  579. else
  580. ibatt_sum1 = ibatt_sum1 + data; /* charging */
  581. }
  582. if (set_charger_current(info, 100, &ret))
  583. goto out_meas;
  584. /*
  585. * set charge current as 100mA, wait about 500ms till charging
  586. * process is launched and stable with the newer charging current.
  587. */
  588. msleep(500);
  589. for (i = 0, vbatt_sum2 = 0, ibatt_sum2 = 0; i < 10; i++) {
  590. ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
  591. if (ret)
  592. goto out_meas;
  593. vbatt_sum2 += data;
  594. ret = measure_current(info, &data);
  595. if (ret)
  596. goto out_meas;
  597. if (data < 0)
  598. ibatt_sum2 = ibatt_sum2 - data; /* discharging */
  599. else
  600. ibatt_sum2 = ibatt_sum2 + data; /* charging */
  601. }
  602. /* restore current setting */
  603. if (set_charger_current(info, chg_current, &ret))
  604. goto out_meas;
  605. if ((vbatt_sum1 > vbatt_sum2) && (ibatt_sum1 > ibatt_sum2) &&
  606. (ibatt_sum2 > 0)) {
  607. /* calculate resistor in discharging case */
  608. data = 1000 * (vbatt_sum1 - vbatt_sum2)
  609. / (ibatt_sum1 - ibatt_sum2);
  610. if ((data - info->resistor > 0) &&
  611. (data - info->resistor < info->resistor))
  612. info->resistor = data;
  613. if ((info->resistor - data > 0) &&
  614. (info->resistor - data < data))
  615. info->resistor = data;
  616. }
  617. return 0;
  618. out_meas:
  619. set_charger_current(info, chg_current, &ret);
  620. out:
  621. return -EINVAL;
  622. }
  623. static int calc_capacity(struct pm860x_battery_info *info, int *cap)
  624. {
  625. int ret;
  626. int data;
  627. int ibat;
  628. int cap_ocv = 0;
  629. int cap_cc = 0;
  630. ret = calc_ccnt(info, &ccnt_data);
  631. if (ret)
  632. goto out;
  633. soc:
  634. data = info->max_capacity * info->start_soc / 100;
  635. if (ccnt_data.total_dischg - ccnt_data.total_chg <= data) {
  636. cap_cc =
  637. data + ccnt_data.total_chg - ccnt_data.total_dischg;
  638. } else {
  639. clear_ccnt(info, &ccnt_data);
  640. calc_soc(info, OCV_MODE_ACTIVE, &info->start_soc);
  641. dev_dbg(info->dev, "restart soc = %d !\n",
  642. info->start_soc);
  643. goto soc;
  644. }
  645. cap_cc = cap_cc * 100 / info->max_capacity;
  646. if (cap_cc < 0)
  647. cap_cc = 0;
  648. else if (cap_cc > 100)
  649. cap_cc = 100;
  650. dev_dbg(info->dev, "%s, last cap : %d", __func__,
  651. info->last_capacity);
  652. ret = measure_current(info, &ibat);
  653. if (ret)
  654. goto out;
  655. /* Calculate the capacity when discharging(ibat < 0) */
  656. if (ibat < 0) {
  657. ret = calc_soc(info, OCV_MODE_ACTIVE, &cap_ocv);
  658. if (ret)
  659. cap_ocv = info->last_capacity;
  660. ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
  661. if (ret)
  662. goto out;
  663. if (data <= LOW_BAT_THRESHOLD) {
  664. /* choose the lower capacity value to report
  665. * between vbat and CC when vbat < 3.6v;
  666. * than 3.6v;
  667. */
  668. *cap = min(cap_ocv, cap_cc);
  669. } else {
  670. /* when detect vbat > 3.6v, but cap_cc < 15,and
  671. * cap_ocv is 10% larger than cap_cc, we can think
  672. * CC have some accumulation error, switch to OCV
  673. * to estimate capacity;
  674. * */
  675. if (cap_cc < 15 && cap_ocv - cap_cc > 10)
  676. *cap = cap_ocv;
  677. else
  678. *cap = cap_cc;
  679. }
  680. /* when discharging, make sure current capacity
  681. * is lower than last*/
  682. if (*cap > info->last_capacity)
  683. *cap = info->last_capacity;
  684. } else {
  685. *cap = cap_cc;
  686. }
  687. info->last_capacity = *cap;
  688. dev_dbg(info->dev, "%s, cap_ocv:%d cap_cc:%d, cap:%d\n",
  689. (ibat < 0) ? "discharging" : "charging",
  690. cap_ocv, cap_cc, *cap);
  691. /*
  692. * store the current capacity to RTC domain register,
  693. * after next power up , it will be restored.
  694. */
  695. pm860x_set_bits(info->i2c, PM8607_RTC_MISC2, RTC_SOC_5LSB,
  696. (*cap & 0x1F) << 3);
  697. pm860x_set_bits(info->i2c, PM8607_RTC1, RTC_SOC_3MSB,
  698. ((*cap >> 5) & 0x3));
  699. return 0;
  700. out:
  701. return ret;
  702. }
  703. static void pm860x_external_power_changed(struct power_supply *psy)
  704. {
  705. struct pm860x_battery_info *info = dev_get_drvdata(psy->dev.parent);
  706. calc_resistor(info);
  707. }
  708. static int pm860x_batt_get_prop(struct power_supply *psy,
  709. enum power_supply_property psp,
  710. union power_supply_propval *val)
  711. {
  712. struct pm860x_battery_info *info = dev_get_drvdata(psy->dev.parent);
  713. int data;
  714. int ret;
  715. switch (psp) {
  716. case POWER_SUPPLY_PROP_PRESENT:
  717. val->intval = info->present;
  718. break;
  719. case POWER_SUPPLY_PROP_CAPACITY:
  720. ret = calc_capacity(info, &data);
  721. if (ret)
  722. return ret;
  723. if (data < 0)
  724. data = 0;
  725. else if (data > 100)
  726. data = 100;
  727. /* return 100 if battery is not attached */
  728. if (!info->present)
  729. data = 100;
  730. val->intval = data;
  731. break;
  732. case POWER_SUPPLY_PROP_TECHNOLOGY:
  733. val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
  734. break;
  735. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  736. /* return real vbatt Voltage */
  737. ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
  738. if (ret)
  739. return ret;
  740. val->intval = data * 1000;
  741. break;
  742. case POWER_SUPPLY_PROP_VOLTAGE_AVG:
  743. /* return Open Circuit Voltage (not measured voltage) */
  744. ret = calc_ocv(info, &data);
  745. if (ret)
  746. return ret;
  747. val->intval = data * 1000;
  748. break;
  749. case POWER_SUPPLY_PROP_CURRENT_NOW:
  750. ret = measure_current(info, &data);
  751. if (ret)
  752. return ret;
  753. val->intval = data;
  754. break;
  755. case POWER_SUPPLY_PROP_TEMP:
  756. if (info->present) {
  757. ret = measure_temp(info, &data);
  758. if (ret)
  759. return ret;
  760. data *= 10;
  761. } else {
  762. /* Fake Temp 25C Without Battery */
  763. data = 250;
  764. }
  765. val->intval = data;
  766. break;
  767. default:
  768. return -ENODEV;
  769. }
  770. return 0;
  771. }
  772. static int pm860x_batt_set_prop(struct power_supply *psy,
  773. enum power_supply_property psp,
  774. const union power_supply_propval *val)
  775. {
  776. struct pm860x_battery_info *info = dev_get_drvdata(psy->dev.parent);
  777. switch (psp) {
  778. case POWER_SUPPLY_PROP_CHARGE_FULL:
  779. clear_ccnt(info, &ccnt_data);
  780. info->start_soc = 100;
  781. dev_dbg(info->dev, "chg done, update soc = %d\n",
  782. info->start_soc);
  783. break;
  784. default:
  785. return -EPERM;
  786. }
  787. return 0;
  788. }
  789. static enum power_supply_property pm860x_batt_props[] = {
  790. POWER_SUPPLY_PROP_PRESENT,
  791. POWER_SUPPLY_PROP_CAPACITY,
  792. POWER_SUPPLY_PROP_TECHNOLOGY,
  793. POWER_SUPPLY_PROP_VOLTAGE_NOW,
  794. POWER_SUPPLY_PROP_VOLTAGE_AVG,
  795. POWER_SUPPLY_PROP_CURRENT_NOW,
  796. POWER_SUPPLY_PROP_TEMP,
  797. };
  798. static const struct power_supply_desc pm860x_battery_desc = {
  799. .name = "battery-monitor",
  800. .type = POWER_SUPPLY_TYPE_BATTERY,
  801. .properties = pm860x_batt_props,
  802. .num_properties = ARRAY_SIZE(pm860x_batt_props),
  803. .get_property = pm860x_batt_get_prop,
  804. .set_property = pm860x_batt_set_prop,
  805. .external_power_changed = pm860x_external_power_changed,
  806. };
  807. static int pm860x_battery_probe(struct platform_device *pdev)
  808. {
  809. struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
  810. struct pm860x_battery_info *info;
  811. struct pm860x_power_pdata *pdata;
  812. int ret;
  813. info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
  814. if (!info)
  815. return -ENOMEM;
  816. info->irq_cc = platform_get_irq(pdev, 0);
  817. if (info->irq_cc <= 0) {
  818. dev_err(&pdev->dev, "No IRQ resource!\n");
  819. return -EINVAL;
  820. }
  821. info->irq_batt = platform_get_irq(pdev, 1);
  822. if (info->irq_batt <= 0) {
  823. dev_err(&pdev->dev, "No IRQ resource!\n");
  824. return -EINVAL;
  825. }
  826. info->chip = chip;
  827. info->i2c =
  828. (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
  829. info->dev = &pdev->dev;
  830. info->status = POWER_SUPPLY_STATUS_UNKNOWN;
  831. pdata = pdev->dev.platform_data;
  832. mutex_init(&info->lock);
  833. platform_set_drvdata(pdev, info);
  834. pm860x_init_battery(info);
  835. if (pdata && pdata->max_capacity)
  836. info->max_capacity = pdata->max_capacity;
  837. else
  838. info->max_capacity = 1500; /* set default capacity */
  839. if (pdata && pdata->resistor)
  840. info->resistor = pdata->resistor;
  841. else
  842. info->resistor = 300; /* set default internal resistor */
  843. info->battery = devm_power_supply_register(&pdev->dev,
  844. &pm860x_battery_desc,
  845. NULL);
  846. if (IS_ERR(info->battery))
  847. return PTR_ERR(info->battery);
  848. info->battery->dev.parent = &pdev->dev;
  849. ret = devm_request_threaded_irq(chip->dev, info->irq_cc, NULL,
  850. pm860x_coulomb_handler, IRQF_ONESHOT,
  851. "coulomb", info);
  852. if (ret < 0) {
  853. dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
  854. info->irq_cc, ret);
  855. return ret;
  856. }
  857. ret = devm_request_threaded_irq(chip->dev, info->irq_batt, NULL,
  858. pm860x_batt_handler,
  859. IRQF_ONESHOT, "battery", info);
  860. if (ret < 0) {
  861. dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
  862. info->irq_batt, ret);
  863. return ret;
  864. }
  865. return 0;
  866. }
  867. #ifdef CONFIG_PM_SLEEP
  868. static int pm860x_battery_suspend(struct device *dev)
  869. {
  870. struct platform_device *pdev = to_platform_device(dev);
  871. struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
  872. if (device_may_wakeup(dev))
  873. chip->wakeup_flag |= 1 << PM8607_IRQ_CC;
  874. return 0;
  875. }
  876. static int pm860x_battery_resume(struct device *dev)
  877. {
  878. struct platform_device *pdev = to_platform_device(dev);
  879. struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
  880. if (device_may_wakeup(dev))
  881. chip->wakeup_flag &= ~(1 << PM8607_IRQ_CC);
  882. return 0;
  883. }
  884. #endif
  885. static SIMPLE_DEV_PM_OPS(pm860x_battery_pm_ops,
  886. pm860x_battery_suspend, pm860x_battery_resume);
  887. static struct platform_driver pm860x_battery_driver = {
  888. .driver = {
  889. .name = "88pm860x-battery",
  890. .pm = &pm860x_battery_pm_ops,
  891. },
  892. .probe = pm860x_battery_probe,
  893. };
  894. module_platform_driver(pm860x_battery_driver);
  895. MODULE_DESCRIPTION("Marvell 88PM860x Battery driver");
  896. MODULE_LICENSE("GPL");