ab8500_btemp.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135
  1. /*
  2. * Copyright (C) ST-Ericsson SA 2012
  3. *
  4. * Battery temperature driver for AB8500
  5. *
  6. * License Terms: GNU General Public License v2
  7. * Author:
  8. * Johan Palsson <johan.palsson@stericsson.com>
  9. * Karl Komierowski <karl.komierowski@stericsson.com>
  10. * Arun R Murthy <arun.murthy@stericsson.com>
  11. */
  12. #include <linux/init.h>
  13. #include <linux/module.h>
  14. #include <linux/device.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/delay.h>
  17. #include <linux/slab.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/power_supply.h>
  20. #include <linux/completion.h>
  21. #include <linux/workqueue.h>
  22. #include <linux/jiffies.h>
  23. #include <linux/of.h>
  24. #include <linux/mfd/core.h>
  25. #include <linux/mfd/abx500.h>
  26. #include <linux/mfd/abx500/ab8500.h>
  27. #include <linux/mfd/abx500/ab8500-bm.h>
  28. #include <linux/mfd/abx500/ab8500-gpadc.h>
  29. #define VTVOUT_V 1800
  30. #define BTEMP_THERMAL_LOW_LIMIT -10
  31. #define BTEMP_THERMAL_MED_LIMIT 0
  32. #define BTEMP_THERMAL_HIGH_LIMIT_52 52
  33. #define BTEMP_THERMAL_HIGH_LIMIT_57 57
  34. #define BTEMP_THERMAL_HIGH_LIMIT_62 62
  35. #define BTEMP_BATCTRL_CURR_SRC_7UA 7
  36. #define BTEMP_BATCTRL_CURR_SRC_20UA 20
  37. #define to_ab8500_btemp_device_info(x) container_of((x), \
  38. struct ab8500_btemp, btemp_psy);
  39. /**
  40. * struct ab8500_btemp_interrupts - ab8500 interrupts
  41. * @name: name of the interrupt
  42. * @isr function pointer to the isr
  43. */
  44. struct ab8500_btemp_interrupts {
  45. char *name;
  46. irqreturn_t (*isr)(int irq, void *data);
  47. };
  48. struct ab8500_btemp_events {
  49. bool batt_rem;
  50. bool btemp_high;
  51. bool btemp_medhigh;
  52. bool btemp_lowmed;
  53. bool btemp_low;
  54. bool ac_conn;
  55. bool usb_conn;
  56. };
  57. struct ab8500_btemp_ranges {
  58. int btemp_high_limit;
  59. int btemp_med_limit;
  60. int btemp_low_limit;
  61. };
  62. /**
  63. * struct ab8500_btemp - ab8500 BTEMP device information
  64. * @dev: Pointer to the structure device
  65. * @node: List of AB8500 BTEMPs, hence prepared for reentrance
  66. * @curr_source: What current source we use, in uA
  67. * @bat_temp: Battery temperature in degree Celcius
  68. * @prev_bat_temp Last dispatched battery temperature
  69. * @parent: Pointer to the struct ab8500
  70. * @gpadc: Pointer to the struct gpadc
  71. * @fg: Pointer to the struct fg
  72. * @bm: Platform specific battery management information
  73. * @btemp_psy: Structure for BTEMP specific battery properties
  74. * @events: Structure for information about events triggered
  75. * @btemp_ranges: Battery temperature range structure
  76. * @btemp_wq: Work queue for measuring the temperature periodically
  77. * @btemp_periodic_work: Work for measuring the temperature periodically
  78. * @initialized: True if battery id read.
  79. */
  80. struct ab8500_btemp {
  81. struct device *dev;
  82. struct list_head node;
  83. int curr_source;
  84. int bat_temp;
  85. int prev_bat_temp;
  86. struct ab8500 *parent;
  87. struct ab8500_gpadc *gpadc;
  88. struct ab8500_fg *fg;
  89. struct abx500_bm_data *bm;
  90. struct power_supply btemp_psy;
  91. struct ab8500_btemp_events events;
  92. struct ab8500_btemp_ranges btemp_ranges;
  93. struct workqueue_struct *btemp_wq;
  94. struct delayed_work btemp_periodic_work;
  95. bool initialized;
  96. };
  97. /* BTEMP power supply properties */
  98. static enum power_supply_property ab8500_btemp_props[] = {
  99. POWER_SUPPLY_PROP_PRESENT,
  100. POWER_SUPPLY_PROP_ONLINE,
  101. POWER_SUPPLY_PROP_TECHNOLOGY,
  102. POWER_SUPPLY_PROP_TEMP,
  103. };
  104. static LIST_HEAD(ab8500_btemp_list);
  105. /**
  106. * ab8500_btemp_get() - returns a reference to the primary AB8500 BTEMP
  107. * (i.e. the first BTEMP in the instance list)
  108. */
  109. struct ab8500_btemp *ab8500_btemp_get(void)
  110. {
  111. struct ab8500_btemp *btemp;
  112. btemp = list_first_entry(&ab8500_btemp_list, struct ab8500_btemp, node);
  113. return btemp;
  114. }
  115. /**
  116. * ab8500_btemp_batctrl_volt_to_res() - convert batctrl voltage to resistance
  117. * @di: pointer to the ab8500_btemp structure
  118. * @v_batctrl: measured batctrl voltage
  119. * @inst_curr: measured instant current
  120. *
  121. * This function returns the battery resistance that is
  122. * derived from the BATCTRL voltage.
  123. * Returns value in Ohms.
  124. */
  125. static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di,
  126. int v_batctrl, int inst_curr)
  127. {
  128. int rbs;
  129. if (is_ab8500_1p1_or_earlier(di->parent)) {
  130. /*
  131. * For ABB cut1.0 and 1.1 BAT_CTRL is internally
  132. * connected to 1.8V through a 450k resistor
  133. */
  134. return (450000 * (v_batctrl)) / (1800 - v_batctrl);
  135. }
  136. if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL) {
  137. /*
  138. * If the battery has internal NTC, we use the current
  139. * source to calculate the resistance, 7uA or 20uA
  140. */
  141. rbs = (v_batctrl * 1000
  142. - di->bm->gnd_lift_resistance * inst_curr)
  143. / di->curr_source;
  144. } else {
  145. /*
  146. * BAT_CTRL is internally
  147. * connected to 1.8V through a 80k resistor
  148. */
  149. rbs = (80000 * (v_batctrl)) / (1800 - v_batctrl);
  150. }
  151. return rbs;
  152. }
  153. /**
  154. * ab8500_btemp_read_batctrl_voltage() - measure batctrl voltage
  155. * @di: pointer to the ab8500_btemp structure
  156. *
  157. * This function returns the voltage on BATCTRL. Returns value in mV.
  158. */
  159. static int ab8500_btemp_read_batctrl_voltage(struct ab8500_btemp *di)
  160. {
  161. int vbtemp;
  162. static int prev;
  163. vbtemp = ab8500_gpadc_convert(di->gpadc, BAT_CTRL);
  164. if (vbtemp < 0) {
  165. dev_err(di->dev,
  166. "%s gpadc conversion failed, using previous value",
  167. __func__);
  168. return prev;
  169. }
  170. prev = vbtemp;
  171. return vbtemp;
  172. }
  173. /**
  174. * ab8500_btemp_curr_source_enable() - enable/disable batctrl current source
  175. * @di: pointer to the ab8500_btemp structure
  176. * @enable: enable or disable the current source
  177. *
  178. * Enable or disable the current sources for the BatCtrl AD channel
  179. */
  180. static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di,
  181. bool enable)
  182. {
  183. int curr;
  184. int ret = 0;
  185. /*
  186. * BATCTRL current sources are included on AB8500 cut2.0
  187. * and future versions
  188. */
  189. if (is_ab8500_1p1_or_earlier(di->parent))
  190. return 0;
  191. /* Only do this for batteries with internal NTC */
  192. if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) {
  193. if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_7UA)
  194. curr = BAT_CTRL_7U_ENA;
  195. else
  196. curr = BAT_CTRL_20U_ENA;
  197. dev_dbg(di->dev, "Set BATCTRL %duA\n", di->curr_source);
  198. ret = abx500_mask_and_set_register_interruptible(di->dev,
  199. AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
  200. FORCE_BAT_CTRL_CMP_HIGH, FORCE_BAT_CTRL_CMP_HIGH);
  201. if (ret) {
  202. dev_err(di->dev, "%s failed setting cmp_force\n",
  203. __func__);
  204. return ret;
  205. }
  206. /*
  207. * We have to wait one 32kHz cycle before enabling
  208. * the current source, since ForceBatCtrlCmpHigh needs
  209. * to be written in a separate cycle
  210. */
  211. udelay(32);
  212. ret = abx500_set_register_interruptible(di->dev,
  213. AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
  214. FORCE_BAT_CTRL_CMP_HIGH | curr);
  215. if (ret) {
  216. dev_err(di->dev, "%s failed enabling current source\n",
  217. __func__);
  218. goto disable_curr_source;
  219. }
  220. } else if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) {
  221. dev_dbg(di->dev, "Disable BATCTRL curr source\n");
  222. /* Write 0 to the curr bits */
  223. ret = abx500_mask_and_set_register_interruptible(di->dev,
  224. AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
  225. BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA,
  226. ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA));
  227. if (ret) {
  228. dev_err(di->dev, "%s failed disabling current source\n",
  229. __func__);
  230. goto disable_curr_source;
  231. }
  232. /* Enable Pull-Up and comparator */
  233. ret = abx500_mask_and_set_register_interruptible(di->dev,
  234. AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
  235. BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA,
  236. BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA);
  237. if (ret) {
  238. dev_err(di->dev, "%s failed enabling PU and comp\n",
  239. __func__);
  240. goto enable_pu_comp;
  241. }
  242. /*
  243. * We have to wait one 32kHz cycle before disabling
  244. * ForceBatCtrlCmpHigh since this needs to be written
  245. * in a separate cycle
  246. */
  247. udelay(32);
  248. /* Disable 'force comparator' */
  249. ret = abx500_mask_and_set_register_interruptible(di->dev,
  250. AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
  251. FORCE_BAT_CTRL_CMP_HIGH, ~FORCE_BAT_CTRL_CMP_HIGH);
  252. if (ret) {
  253. dev_err(di->dev, "%s failed disabling force comp\n",
  254. __func__);
  255. goto disable_force_comp;
  256. }
  257. }
  258. return ret;
  259. /*
  260. * We have to try unsetting FORCE_BAT_CTRL_CMP_HIGH one more time
  261. * if we got an error above
  262. */
  263. disable_curr_source:
  264. /* Write 0 to the curr bits */
  265. ret = abx500_mask_and_set_register_interruptible(di->dev,
  266. AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
  267. BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA,
  268. ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA));
  269. if (ret) {
  270. dev_err(di->dev, "%s failed disabling current source\n",
  271. __func__);
  272. return ret;
  273. }
  274. enable_pu_comp:
  275. /* Enable Pull-Up and comparator */
  276. ret = abx500_mask_and_set_register_interruptible(di->dev,
  277. AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
  278. BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA,
  279. BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA);
  280. if (ret) {
  281. dev_err(di->dev, "%s failed enabling PU and comp\n",
  282. __func__);
  283. return ret;
  284. }
  285. disable_force_comp:
  286. /*
  287. * We have to wait one 32kHz cycle before disabling
  288. * ForceBatCtrlCmpHigh since this needs to be written
  289. * in a separate cycle
  290. */
  291. udelay(32);
  292. /* Disable 'force comparator' */
  293. ret = abx500_mask_and_set_register_interruptible(di->dev,
  294. AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE,
  295. FORCE_BAT_CTRL_CMP_HIGH, ~FORCE_BAT_CTRL_CMP_HIGH);
  296. if (ret) {
  297. dev_err(di->dev, "%s failed disabling force comp\n",
  298. __func__);
  299. return ret;
  300. }
  301. return ret;
  302. }
  303. /**
  304. * ab8500_btemp_get_batctrl_res() - get battery resistance
  305. * @di: pointer to the ab8500_btemp structure
  306. *
  307. * This function returns the battery pack identification resistance.
  308. * Returns value in Ohms.
  309. */
  310. static int ab8500_btemp_get_batctrl_res(struct ab8500_btemp *di)
  311. {
  312. int ret;
  313. int batctrl = 0;
  314. int res;
  315. int inst_curr;
  316. int i;
  317. /*
  318. * BATCTRL current sources are included on AB8500 cut2.0
  319. * and future versions
  320. */
  321. ret = ab8500_btemp_curr_source_enable(di, true);
  322. if (ret) {
  323. dev_err(di->dev, "%s curr source enabled failed\n", __func__);
  324. return ret;
  325. }
  326. if (!di->fg)
  327. di->fg = ab8500_fg_get();
  328. if (!di->fg) {
  329. dev_err(di->dev, "No fg found\n");
  330. return -EINVAL;
  331. }
  332. ret = ab8500_fg_inst_curr_start(di->fg);
  333. if (ret) {
  334. dev_err(di->dev, "Failed to start current measurement\n");
  335. return ret;
  336. }
  337. do {
  338. msleep(20);
  339. } while (!ab8500_fg_inst_curr_started(di->fg));
  340. i = 0;
  341. do {
  342. batctrl += ab8500_btemp_read_batctrl_voltage(di);
  343. i++;
  344. msleep(20);
  345. } while (!ab8500_fg_inst_curr_done(di->fg));
  346. batctrl /= i;
  347. ret = ab8500_fg_inst_curr_finalize(di->fg, &inst_curr);
  348. if (ret) {
  349. dev_err(di->dev, "Failed to finalize current measurement\n");
  350. return ret;
  351. }
  352. res = ab8500_btemp_batctrl_volt_to_res(di, batctrl, inst_curr);
  353. ret = ab8500_btemp_curr_source_enable(di, false);
  354. if (ret) {
  355. dev_err(di->dev, "%s curr source disable failed\n", __func__);
  356. return ret;
  357. }
  358. dev_dbg(di->dev, "%s batctrl: %d res: %d inst_curr: %d samples: %d\n",
  359. __func__, batctrl, res, inst_curr, i);
  360. return res;
  361. }
  362. /**
  363. * ab8500_btemp_res_to_temp() - resistance to temperature
  364. * @di: pointer to the ab8500_btemp structure
  365. * @tbl: pointer to the resiatance to temperature table
  366. * @tbl_size: size of the resistance to temperature table
  367. * @res: resistance to calculate the temperature from
  368. *
  369. * This function returns the battery temperature in degrees Celcius
  370. * based on the NTC resistance.
  371. */
  372. static int ab8500_btemp_res_to_temp(struct ab8500_btemp *di,
  373. const struct abx500_res_to_temp *tbl, int tbl_size, int res)
  374. {
  375. int i, temp;
  376. /*
  377. * Calculate the formula for the straight line
  378. * Simple interpolation if we are within
  379. * the resistance table limits, extrapolate
  380. * if resistance is outside the limits.
  381. */
  382. if (res > tbl[0].resist)
  383. i = 0;
  384. else if (res <= tbl[tbl_size - 1].resist)
  385. i = tbl_size - 2;
  386. else {
  387. i = 0;
  388. while (!(res <= tbl[i].resist &&
  389. res > tbl[i + 1].resist))
  390. i++;
  391. }
  392. temp = tbl[i].temp + ((tbl[i + 1].temp - tbl[i].temp) *
  393. (res - tbl[i].resist)) / (tbl[i + 1].resist - tbl[i].resist);
  394. return temp;
  395. }
  396. /**
  397. * ab8500_btemp_measure_temp() - measure battery temperature
  398. * @di: pointer to the ab8500_btemp structure
  399. *
  400. * Returns battery temperature (on success) else the previous temperature
  401. */
  402. static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
  403. {
  404. int temp;
  405. static int prev;
  406. int rbat, rntc, vntc;
  407. u8 id;
  408. id = di->bm->batt_id;
  409. if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL &&
  410. id != BATTERY_UNKNOWN) {
  411. rbat = ab8500_btemp_get_batctrl_res(di);
  412. if (rbat < 0) {
  413. dev_err(di->dev, "%s get batctrl res failed\n",
  414. __func__);
  415. /*
  416. * Return out-of-range temperature so that
  417. * charging is stopped
  418. */
  419. return BTEMP_THERMAL_LOW_LIMIT;
  420. }
  421. temp = ab8500_btemp_res_to_temp(di,
  422. di->bm->bat_type[id].r_to_t_tbl,
  423. di->bm->bat_type[id].n_temp_tbl_elements, rbat);
  424. } else {
  425. vntc = ab8500_gpadc_convert(di->gpadc, BTEMP_BALL);
  426. if (vntc < 0) {
  427. dev_err(di->dev,
  428. "%s gpadc conversion failed,"
  429. " using previous value\n", __func__);
  430. return prev;
  431. }
  432. /*
  433. * The PCB NTC is sourced from VTVOUT via a 230kOhm
  434. * resistor.
  435. */
  436. rntc = 230000 * vntc / (VTVOUT_V - vntc);
  437. temp = ab8500_btemp_res_to_temp(di,
  438. di->bm->bat_type[id].r_to_t_tbl,
  439. di->bm->bat_type[id].n_temp_tbl_elements, rntc);
  440. prev = temp;
  441. }
  442. dev_dbg(di->dev, "Battery temperature is %d\n", temp);
  443. return temp;
  444. }
  445. /**
  446. * ab8500_btemp_id() - Identify the connected battery
  447. * @di: pointer to the ab8500_btemp structure
  448. *
  449. * This function will try to identify the battery by reading the ID
  450. * resistor. Some brands use a combined ID resistor with a NTC resistor to
  451. * both be able to identify and to read the temperature of it.
  452. */
  453. static int ab8500_btemp_id(struct ab8500_btemp *di)
  454. {
  455. int res;
  456. u8 i;
  457. di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA;
  458. di->bm->batt_id = BATTERY_UNKNOWN;
  459. res = ab8500_btemp_get_batctrl_res(di);
  460. if (res < 0) {
  461. dev_err(di->dev, "%s get batctrl res failed\n", __func__);
  462. return -ENXIO;
  463. }
  464. /* BATTERY_UNKNOWN is defined on position 0, skip it! */
  465. for (i = BATTERY_UNKNOWN + 1; i < di->bm->n_btypes; i++) {
  466. if ((res <= di->bm->bat_type[i].resis_high) &&
  467. (res >= di->bm->bat_type[i].resis_low)) {
  468. dev_dbg(di->dev, "Battery detected on %s"
  469. " low %d < res %d < high: %d"
  470. " index: %d\n",
  471. di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL ?
  472. "BATCTRL" : "BATTEMP",
  473. di->bm->bat_type[i].resis_low, res,
  474. di->bm->bat_type[i].resis_high, i);
  475. di->bm->batt_id = i;
  476. break;
  477. }
  478. }
  479. if (di->bm->batt_id == BATTERY_UNKNOWN) {
  480. dev_warn(di->dev, "Battery identified as unknown"
  481. ", resistance %d Ohm\n", res);
  482. return -ENXIO;
  483. }
  484. /*
  485. * We only have to change current source if the
  486. * detected type is Type 1, else we use the 7uA source
  487. */
  488. if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL &&
  489. di->bm->batt_id == 1) {
  490. dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n");
  491. di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA;
  492. }
  493. return di->bm->batt_id;
  494. }
  495. /**
  496. * ab8500_btemp_periodic_work() - Measuring the temperature periodically
  497. * @work: pointer to the work_struct structure
  498. *
  499. * Work function for measuring the temperature periodically
  500. */
  501. static void ab8500_btemp_periodic_work(struct work_struct *work)
  502. {
  503. int interval;
  504. struct ab8500_btemp *di = container_of(work,
  505. struct ab8500_btemp, btemp_periodic_work.work);
  506. if (!di->initialized) {
  507. di->initialized = true;
  508. /* Identify the battery */
  509. if (ab8500_btemp_id(di) < 0)
  510. dev_warn(di->dev, "failed to identify the battery\n");
  511. }
  512. di->bat_temp = ab8500_btemp_measure_temp(di);
  513. if (di->bat_temp != di->prev_bat_temp) {
  514. di->prev_bat_temp = di->bat_temp;
  515. power_supply_changed(&di->btemp_psy);
  516. }
  517. if (di->events.ac_conn || di->events.usb_conn)
  518. interval = di->bm->temp_interval_chg;
  519. else
  520. interval = di->bm->temp_interval_nochg;
  521. /* Schedule a new measurement */
  522. queue_delayed_work(di->btemp_wq,
  523. &di->btemp_periodic_work,
  524. round_jiffies(interval * HZ));
  525. }
  526. /**
  527. * ab8500_btemp_batctrlindb_handler() - battery removal detected
  528. * @irq: interrupt number
  529. * @_di: void pointer that has to address of ab8500_btemp
  530. *
  531. * Returns IRQ status(IRQ_HANDLED)
  532. */
  533. static irqreturn_t ab8500_btemp_batctrlindb_handler(int irq, void *_di)
  534. {
  535. struct ab8500_btemp *di = _di;
  536. dev_err(di->dev, "Battery removal detected!\n");
  537. di->events.batt_rem = true;
  538. power_supply_changed(&di->btemp_psy);
  539. return IRQ_HANDLED;
  540. }
  541. /**
  542. * ab8500_btemp_templow_handler() - battery temp lower than 10 degrees
  543. * @irq: interrupt number
  544. * @_di: void pointer that has to address of ab8500_btemp
  545. *
  546. * Returns IRQ status(IRQ_HANDLED)
  547. */
  548. static irqreturn_t ab8500_btemp_templow_handler(int irq, void *_di)
  549. {
  550. struct ab8500_btemp *di = _di;
  551. if (is_ab8500_2p0_or_earlier(di->parent)) {
  552. dev_dbg(di->dev, "Ignore false btemp low irq"
  553. " for ABB cut 1.0, 1.1 and 2.0\n");
  554. } else {
  555. dev_crit(di->dev, "Battery temperature lower than -10deg c\n");
  556. di->events.btemp_low = true;
  557. di->events.btemp_high = false;
  558. di->events.btemp_medhigh = false;
  559. di->events.btemp_lowmed = false;
  560. power_supply_changed(&di->btemp_psy);
  561. }
  562. return IRQ_HANDLED;
  563. }
  564. /**
  565. * ab8500_btemp_temphigh_handler() - battery temp higher than max temp
  566. * @irq: interrupt number
  567. * @_di: void pointer that has to address of ab8500_btemp
  568. *
  569. * Returns IRQ status(IRQ_HANDLED)
  570. */
  571. static irqreturn_t ab8500_btemp_temphigh_handler(int irq, void *_di)
  572. {
  573. struct ab8500_btemp *di = _di;
  574. dev_crit(di->dev, "Battery temperature is higher than MAX temp\n");
  575. di->events.btemp_high = true;
  576. di->events.btemp_medhigh = false;
  577. di->events.btemp_lowmed = false;
  578. di->events.btemp_low = false;
  579. power_supply_changed(&di->btemp_psy);
  580. return IRQ_HANDLED;
  581. }
  582. /**
  583. * ab8500_btemp_lowmed_handler() - battery temp between low and medium
  584. * @irq: interrupt number
  585. * @_di: void pointer that has to address of ab8500_btemp
  586. *
  587. * Returns IRQ status(IRQ_HANDLED)
  588. */
  589. static irqreturn_t ab8500_btemp_lowmed_handler(int irq, void *_di)
  590. {
  591. struct ab8500_btemp *di = _di;
  592. dev_dbg(di->dev, "Battery temperature is between low and medium\n");
  593. di->events.btemp_lowmed = true;
  594. di->events.btemp_medhigh = false;
  595. di->events.btemp_high = false;
  596. di->events.btemp_low = false;
  597. power_supply_changed(&di->btemp_psy);
  598. return IRQ_HANDLED;
  599. }
  600. /**
  601. * ab8500_btemp_medhigh_handler() - battery temp between medium and high
  602. * @irq: interrupt number
  603. * @_di: void pointer that has to address of ab8500_btemp
  604. *
  605. * Returns IRQ status(IRQ_HANDLED)
  606. */
  607. static irqreturn_t ab8500_btemp_medhigh_handler(int irq, void *_di)
  608. {
  609. struct ab8500_btemp *di = _di;
  610. dev_dbg(di->dev, "Battery temperature is between medium and high\n");
  611. di->events.btemp_medhigh = true;
  612. di->events.btemp_lowmed = false;
  613. di->events.btemp_high = false;
  614. di->events.btemp_low = false;
  615. power_supply_changed(&di->btemp_psy);
  616. return IRQ_HANDLED;
  617. }
  618. /**
  619. * ab8500_btemp_periodic() - Periodic temperature measurements
  620. * @di: pointer to the ab8500_btemp structure
  621. * @enable: enable or disable periodic temperature measurements
  622. *
  623. * Starts of stops periodic temperature measurements. Periodic measurements
  624. * should only be done when a charger is connected.
  625. */
  626. static void ab8500_btemp_periodic(struct ab8500_btemp *di,
  627. bool enable)
  628. {
  629. dev_dbg(di->dev, "Enable periodic temperature measurements: %d\n",
  630. enable);
  631. /*
  632. * Make sure a new measurement is done directly by cancelling
  633. * any pending work
  634. */
  635. cancel_delayed_work_sync(&di->btemp_periodic_work);
  636. if (enable)
  637. queue_delayed_work(di->btemp_wq, &di->btemp_periodic_work, 0);
  638. }
  639. /**
  640. * ab8500_btemp_get_temp() - get battery temperature
  641. * @di: pointer to the ab8500_btemp structure
  642. *
  643. * Returns battery temperature
  644. */
  645. static int ab8500_btemp_get_temp(struct ab8500_btemp *di)
  646. {
  647. int temp = 0;
  648. /*
  649. * The BTEMP events are not reliabe on AB8500 cut2.0
  650. * and prior versions
  651. */
  652. if (is_ab8500_2p0_or_earlier(di->parent)) {
  653. temp = di->bat_temp * 10;
  654. } else {
  655. if (di->events.btemp_low) {
  656. if (temp > di->btemp_ranges.btemp_low_limit)
  657. temp = di->btemp_ranges.btemp_low_limit;
  658. else
  659. temp = di->bat_temp * 10;
  660. } else if (di->events.btemp_high) {
  661. if (temp < di->btemp_ranges.btemp_high_limit)
  662. temp = di->btemp_ranges.btemp_high_limit;
  663. else
  664. temp = di->bat_temp * 10;
  665. } else if (di->events.btemp_lowmed) {
  666. if (temp > di->btemp_ranges.btemp_med_limit)
  667. temp = di->btemp_ranges.btemp_med_limit;
  668. else
  669. temp = di->bat_temp * 10;
  670. } else if (di->events.btemp_medhigh) {
  671. if (temp < di->btemp_ranges.btemp_med_limit)
  672. temp = di->btemp_ranges.btemp_med_limit;
  673. else
  674. temp = di->bat_temp * 10;
  675. } else
  676. temp = di->bat_temp * 10;
  677. }
  678. return temp;
  679. }
  680. /**
  681. * ab8500_btemp_get_batctrl_temp() - get the temperature
  682. * @btemp: pointer to the btemp structure
  683. *
  684. * Returns the batctrl temperature in millidegrees
  685. */
  686. int ab8500_btemp_get_batctrl_temp(struct ab8500_btemp *btemp)
  687. {
  688. return btemp->bat_temp * 1000;
  689. }
  690. /**
  691. * ab8500_btemp_get_property() - get the btemp properties
  692. * @psy: pointer to the power_supply structure
  693. * @psp: pointer to the power_supply_property structure
  694. * @val: pointer to the power_supply_propval union
  695. *
  696. * This function gets called when an application tries to get the btemp
  697. * properties by reading the sysfs files.
  698. * online: presence of the battery
  699. * present: presence of the battery
  700. * technology: battery technology
  701. * temp: battery temperature
  702. * Returns error code in case of failure else 0(on success)
  703. */
  704. static int ab8500_btemp_get_property(struct power_supply *psy,
  705. enum power_supply_property psp,
  706. union power_supply_propval *val)
  707. {
  708. struct ab8500_btemp *di;
  709. di = to_ab8500_btemp_device_info(psy);
  710. switch (psp) {
  711. case POWER_SUPPLY_PROP_PRESENT:
  712. case POWER_SUPPLY_PROP_ONLINE:
  713. if (di->events.batt_rem)
  714. val->intval = 0;
  715. else
  716. val->intval = 1;
  717. break;
  718. case POWER_SUPPLY_PROP_TECHNOLOGY:
  719. val->intval = di->bm->bat_type[di->bm->batt_id].name;
  720. break;
  721. case POWER_SUPPLY_PROP_TEMP:
  722. val->intval = ab8500_btemp_get_temp(di);
  723. break;
  724. default:
  725. return -EINVAL;
  726. }
  727. return 0;
  728. }
  729. static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data)
  730. {
  731. struct power_supply *psy;
  732. struct power_supply *ext;
  733. struct ab8500_btemp *di;
  734. union power_supply_propval ret;
  735. int i, j;
  736. bool psy_found = false;
  737. psy = (struct power_supply *)data;
  738. ext = dev_get_drvdata(dev);
  739. di = to_ab8500_btemp_device_info(psy);
  740. /*
  741. * For all psy where the name of your driver
  742. * appears in any supplied_to
  743. */
  744. for (i = 0; i < ext->num_supplicants; i++) {
  745. if (!strcmp(ext->supplied_to[i], psy->name))
  746. psy_found = true;
  747. }
  748. if (!psy_found)
  749. return 0;
  750. /* Go through all properties for the psy */
  751. for (j = 0; j < ext->num_properties; j++) {
  752. enum power_supply_property prop;
  753. prop = ext->properties[j];
  754. if (ext->get_property(ext, prop, &ret))
  755. continue;
  756. switch (prop) {
  757. case POWER_SUPPLY_PROP_PRESENT:
  758. switch (ext->type) {
  759. case POWER_SUPPLY_TYPE_MAINS:
  760. /* AC disconnected */
  761. if (!ret.intval && di->events.ac_conn) {
  762. di->events.ac_conn = false;
  763. }
  764. /* AC connected */
  765. else if (ret.intval && !di->events.ac_conn) {
  766. di->events.ac_conn = true;
  767. if (!di->events.usb_conn)
  768. ab8500_btemp_periodic(di, true);
  769. }
  770. break;
  771. case POWER_SUPPLY_TYPE_USB:
  772. /* USB disconnected */
  773. if (!ret.intval && di->events.usb_conn) {
  774. di->events.usb_conn = false;
  775. }
  776. /* USB connected */
  777. else if (ret.intval && !di->events.usb_conn) {
  778. di->events.usb_conn = true;
  779. if (!di->events.ac_conn)
  780. ab8500_btemp_periodic(di, true);
  781. }
  782. break;
  783. default:
  784. break;
  785. }
  786. break;
  787. default:
  788. break;
  789. }
  790. }
  791. return 0;
  792. }
  793. /**
  794. * ab8500_btemp_external_power_changed() - callback for power supply changes
  795. * @psy: pointer to the structure power_supply
  796. *
  797. * This function is pointing to the function pointer external_power_changed
  798. * of the structure power_supply.
  799. * This function gets executed when there is a change in the external power
  800. * supply to the btemp.
  801. */
  802. static void ab8500_btemp_external_power_changed(struct power_supply *psy)
  803. {
  804. struct ab8500_btemp *di = to_ab8500_btemp_device_info(psy);
  805. class_for_each_device(power_supply_class, NULL,
  806. &di->btemp_psy, ab8500_btemp_get_ext_psy_data);
  807. }
  808. /* ab8500 btemp driver interrupts and their respective isr */
  809. static struct ab8500_btemp_interrupts ab8500_btemp_irq[] = {
  810. {"BAT_CTRL_INDB", ab8500_btemp_batctrlindb_handler},
  811. {"BTEMP_LOW", ab8500_btemp_templow_handler},
  812. {"BTEMP_HIGH", ab8500_btemp_temphigh_handler},
  813. {"BTEMP_LOW_MEDIUM", ab8500_btemp_lowmed_handler},
  814. {"BTEMP_MEDIUM_HIGH", ab8500_btemp_medhigh_handler},
  815. };
  816. #if defined(CONFIG_PM)
  817. static int ab8500_btemp_resume(struct platform_device *pdev)
  818. {
  819. struct ab8500_btemp *di = platform_get_drvdata(pdev);
  820. ab8500_btemp_periodic(di, true);
  821. return 0;
  822. }
  823. static int ab8500_btemp_suspend(struct platform_device *pdev,
  824. pm_message_t state)
  825. {
  826. struct ab8500_btemp *di = platform_get_drvdata(pdev);
  827. ab8500_btemp_periodic(di, false);
  828. return 0;
  829. }
  830. #else
  831. #define ab8500_btemp_suspend NULL
  832. #define ab8500_btemp_resume NULL
  833. #endif
  834. static int ab8500_btemp_remove(struct platform_device *pdev)
  835. {
  836. struct ab8500_btemp *di = platform_get_drvdata(pdev);
  837. int i, irq;
  838. /* Disable interrupts */
  839. for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) {
  840. irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name);
  841. free_irq(irq, di);
  842. }
  843. /* Delete the work queue */
  844. destroy_workqueue(di->btemp_wq);
  845. flush_scheduled_work();
  846. power_supply_unregister(&di->btemp_psy);
  847. platform_set_drvdata(pdev, NULL);
  848. return 0;
  849. }
  850. static char *supply_interface[] = {
  851. "ab8500_chargalg",
  852. "ab8500_fg",
  853. };
  854. static int ab8500_btemp_probe(struct platform_device *pdev)
  855. {
  856. struct device_node *np = pdev->dev.of_node;
  857. struct abx500_bm_data *plat = pdev->dev.platform_data;
  858. struct ab8500_btemp *di;
  859. int irq, i, ret = 0;
  860. u8 val;
  861. di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
  862. if (!di) {
  863. dev_err(&pdev->dev, "%s no mem for ab8500_btemp\n", __func__);
  864. return -ENOMEM;
  865. }
  866. if (!plat) {
  867. dev_err(&pdev->dev, "no battery management data supplied\n");
  868. return -EINVAL;
  869. }
  870. di->bm = plat;
  871. if (np) {
  872. ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm);
  873. if (ret) {
  874. dev_err(&pdev->dev, "failed to get battery information\n");
  875. return ret;
  876. }
  877. }
  878. /* get parent data */
  879. di->dev = &pdev->dev;
  880. di->parent = dev_get_drvdata(pdev->dev.parent);
  881. di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
  882. di->initialized = false;
  883. /* BTEMP supply */
  884. di->btemp_psy.name = "ab8500_btemp";
  885. di->btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY;
  886. di->btemp_psy.properties = ab8500_btemp_props;
  887. di->btemp_psy.num_properties = ARRAY_SIZE(ab8500_btemp_props);
  888. di->btemp_psy.get_property = ab8500_btemp_get_property;
  889. di->btemp_psy.supplied_to = supply_interface;
  890. di->btemp_psy.num_supplicants = ARRAY_SIZE(supply_interface);
  891. di->btemp_psy.external_power_changed =
  892. ab8500_btemp_external_power_changed;
  893. /* Create a work queue for the btemp */
  894. di->btemp_wq =
  895. create_singlethread_workqueue("ab8500_btemp_wq");
  896. if (di->btemp_wq == NULL) {
  897. dev_err(di->dev, "failed to create work queue\n");
  898. return -ENOMEM;
  899. }
  900. /* Init work for measuring temperature periodically */
  901. INIT_DEFERRABLE_WORK(&di->btemp_periodic_work,
  902. ab8500_btemp_periodic_work);
  903. /* Set BTEMP thermal limits. Low and Med are fixed */
  904. di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT;
  905. di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT;
  906. ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
  907. AB8500_BTEMP_HIGH_TH, &val);
  908. if (ret < 0) {
  909. dev_err(di->dev, "%s ab8500 read failed\n", __func__);
  910. goto free_btemp_wq;
  911. }
  912. switch (val) {
  913. case BTEMP_HIGH_TH_57_0:
  914. case BTEMP_HIGH_TH_57_1:
  915. di->btemp_ranges.btemp_high_limit =
  916. BTEMP_THERMAL_HIGH_LIMIT_57;
  917. break;
  918. case BTEMP_HIGH_TH_52:
  919. di->btemp_ranges.btemp_high_limit =
  920. BTEMP_THERMAL_HIGH_LIMIT_52;
  921. break;
  922. case BTEMP_HIGH_TH_62:
  923. di->btemp_ranges.btemp_high_limit =
  924. BTEMP_THERMAL_HIGH_LIMIT_62;
  925. break;
  926. }
  927. /* Register BTEMP power supply class */
  928. ret = power_supply_register(di->dev, &di->btemp_psy);
  929. if (ret) {
  930. dev_err(di->dev, "failed to register BTEMP psy\n");
  931. goto free_btemp_wq;
  932. }
  933. /* Register interrupts */
  934. for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) {
  935. irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name);
  936. ret = request_threaded_irq(irq, NULL, ab8500_btemp_irq[i].isr,
  937. IRQF_SHARED | IRQF_NO_SUSPEND,
  938. ab8500_btemp_irq[i].name, di);
  939. if (ret) {
  940. dev_err(di->dev, "failed to request %s IRQ %d: %d\n"
  941. , ab8500_btemp_irq[i].name, irq, ret);
  942. goto free_irq;
  943. }
  944. dev_dbg(di->dev, "Requested %s IRQ %d: %d\n",
  945. ab8500_btemp_irq[i].name, irq, ret);
  946. }
  947. platform_set_drvdata(pdev, di);
  948. /* Kick off periodic temperature measurements */
  949. ab8500_btemp_periodic(di, true);
  950. list_add_tail(&di->node, &ab8500_btemp_list);
  951. return ret;
  952. free_irq:
  953. power_supply_unregister(&di->btemp_psy);
  954. /* We also have to free all successfully registered irqs */
  955. for (i = i - 1; i >= 0; i--) {
  956. irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name);
  957. free_irq(irq, di);
  958. }
  959. free_btemp_wq:
  960. destroy_workqueue(di->btemp_wq);
  961. return ret;
  962. }
  963. static const struct of_device_id ab8500_btemp_match[] = {
  964. { .compatible = "stericsson,ab8500-btemp", },
  965. { },
  966. };
  967. static struct platform_driver ab8500_btemp_driver = {
  968. .probe = ab8500_btemp_probe,
  969. .remove = ab8500_btemp_remove,
  970. .suspend = ab8500_btemp_suspend,
  971. .resume = ab8500_btemp_resume,
  972. .driver = {
  973. .name = "ab8500-btemp",
  974. .owner = THIS_MODULE,
  975. .of_match_table = ab8500_btemp_match,
  976. },
  977. };
  978. static int __init ab8500_btemp_init(void)
  979. {
  980. return platform_driver_register(&ab8500_btemp_driver);
  981. }
  982. static void __exit ab8500_btemp_exit(void)
  983. {
  984. platform_driver_unregister(&ab8500_btemp_driver);
  985. }
  986. subsys_initcall_sync(ab8500_btemp_init);
  987. module_exit(ab8500_btemp_exit);
  988. MODULE_LICENSE("GPL v2");
  989. MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy");
  990. MODULE_ALIAS("platform:ab8500-btemp");
  991. MODULE_DESCRIPTION("AB8500 battery temperature driver");