ab8500_btemp.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138
  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. /*
  338. * Since there is no interrupt when current measurement is done,
  339. * loop for over 250ms (250ms is one sample conversion time
  340. * with 32.768 Khz RTC clock). Note that a stop time must be set
  341. * since the ab8500_btemp_read_batctrl_voltage call can block and
  342. * take an unknown amount of time to complete.
  343. */
  344. i = 0;
  345. do {
  346. batctrl += ab8500_btemp_read_batctrl_voltage(di);
  347. i++;
  348. msleep(20);
  349. } while (!ab8500_fg_inst_curr_done(di->fg));
  350. batctrl /= i;
  351. ret = ab8500_fg_inst_curr_finalize(di->fg, &inst_curr);
  352. if (ret) {
  353. dev_err(di->dev, "Failed to finalize current measurement\n");
  354. return ret;
  355. }
  356. res = ab8500_btemp_batctrl_volt_to_res(di, batctrl, inst_curr);
  357. ret = ab8500_btemp_curr_source_enable(di, false);
  358. if (ret) {
  359. dev_err(di->dev, "%s curr source disable failed\n", __func__);
  360. return ret;
  361. }
  362. dev_dbg(di->dev, "%s batctrl: %d res: %d inst_curr: %d samples: %d\n",
  363. __func__, batctrl, res, inst_curr, i);
  364. return res;
  365. }
  366. /**
  367. * ab8500_btemp_res_to_temp() - resistance to temperature
  368. * @di: pointer to the ab8500_btemp structure
  369. * @tbl: pointer to the resiatance to temperature table
  370. * @tbl_size: size of the resistance to temperature table
  371. * @res: resistance to calculate the temperature from
  372. *
  373. * This function returns the battery temperature in degrees Celcius
  374. * based on the NTC resistance.
  375. */
  376. static int ab8500_btemp_res_to_temp(struct ab8500_btemp *di,
  377. const struct abx500_res_to_temp *tbl, int tbl_size, int res)
  378. {
  379. int i, temp;
  380. /*
  381. * Calculate the formula for the straight line
  382. * Simple interpolation if we are within
  383. * the resistance table limits, extrapolate
  384. * if resistance is outside the limits.
  385. */
  386. if (res > tbl[0].resist)
  387. i = 0;
  388. else if (res <= tbl[tbl_size - 1].resist)
  389. i = tbl_size - 2;
  390. else {
  391. i = 0;
  392. while (!(res <= tbl[i].resist &&
  393. res > tbl[i + 1].resist))
  394. i++;
  395. }
  396. temp = tbl[i].temp + ((tbl[i + 1].temp - tbl[i].temp) *
  397. (res - tbl[i].resist)) / (tbl[i + 1].resist - tbl[i].resist);
  398. return temp;
  399. }
  400. /**
  401. * ab8500_btemp_measure_temp() - measure battery temperature
  402. * @di: pointer to the ab8500_btemp structure
  403. *
  404. * Returns battery temperature (on success) else the previous temperature
  405. */
  406. static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
  407. {
  408. int temp;
  409. static int prev;
  410. int rbat, rntc, vntc;
  411. u8 id;
  412. id = di->bm->batt_id;
  413. if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL &&
  414. id != BATTERY_UNKNOWN) {
  415. rbat = ab8500_btemp_get_batctrl_res(di);
  416. if (rbat < 0) {
  417. dev_err(di->dev, "%s get batctrl res failed\n",
  418. __func__);
  419. /*
  420. * Return out-of-range temperature so that
  421. * charging is stopped
  422. */
  423. return BTEMP_THERMAL_LOW_LIMIT;
  424. }
  425. temp = ab8500_btemp_res_to_temp(di,
  426. di->bm->bat_type[id].r_to_t_tbl,
  427. di->bm->bat_type[id].n_temp_tbl_elements, rbat);
  428. } else {
  429. vntc = ab8500_gpadc_convert(di->gpadc, BTEMP_BALL);
  430. if (vntc < 0) {
  431. dev_err(di->dev,
  432. "%s gpadc conversion failed,"
  433. " using previous value\n", __func__);
  434. return prev;
  435. }
  436. /*
  437. * The PCB NTC is sourced from VTVOUT via a 230kOhm
  438. * resistor.
  439. */
  440. rntc = 230000 * vntc / (VTVOUT_V - vntc);
  441. temp = ab8500_btemp_res_to_temp(di,
  442. di->bm->bat_type[id].r_to_t_tbl,
  443. di->bm->bat_type[id].n_temp_tbl_elements, rntc);
  444. prev = temp;
  445. }
  446. dev_dbg(di->dev, "Battery temperature is %d\n", temp);
  447. return temp;
  448. }
  449. /**
  450. * ab8500_btemp_id() - Identify the connected battery
  451. * @di: pointer to the ab8500_btemp structure
  452. *
  453. * This function will try to identify the battery by reading the ID
  454. * resistor. Some brands use a combined ID resistor with a NTC resistor to
  455. * both be able to identify and to read the temperature of it.
  456. */
  457. static int ab8500_btemp_id(struct ab8500_btemp *di)
  458. {
  459. int res;
  460. u8 i;
  461. di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA;
  462. di->bm->batt_id = BATTERY_UNKNOWN;
  463. res = ab8500_btemp_get_batctrl_res(di);
  464. if (res < 0) {
  465. dev_err(di->dev, "%s get batctrl res failed\n", __func__);
  466. return -ENXIO;
  467. }
  468. /* BATTERY_UNKNOWN is defined on position 0, skip it! */
  469. for (i = BATTERY_UNKNOWN + 1; i < di->bm->n_btypes; i++) {
  470. if ((res <= di->bm->bat_type[i].resis_high) &&
  471. (res >= di->bm->bat_type[i].resis_low)) {
  472. dev_dbg(di->dev, "Battery detected on %s"
  473. " low %d < res %d < high: %d"
  474. " index: %d\n",
  475. di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL ?
  476. "BATCTRL" : "BATTEMP",
  477. di->bm->bat_type[i].resis_low, res,
  478. di->bm->bat_type[i].resis_high, i);
  479. di->bm->batt_id = i;
  480. break;
  481. }
  482. }
  483. if (di->bm->batt_id == BATTERY_UNKNOWN) {
  484. dev_warn(di->dev, "Battery identified as unknown"
  485. ", resistance %d Ohm\n", res);
  486. return -ENXIO;
  487. }
  488. /*
  489. * We only have to change current source if the
  490. * detected type is Type 1, else we use the 7uA source
  491. */
  492. if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL &&
  493. di->bm->batt_id == 1) {
  494. dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n");
  495. di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA;
  496. }
  497. return di->bm->batt_id;
  498. }
  499. /**
  500. * ab8500_btemp_periodic_work() - Measuring the temperature periodically
  501. * @work: pointer to the work_struct structure
  502. *
  503. * Work function for measuring the temperature periodically
  504. */
  505. static void ab8500_btemp_periodic_work(struct work_struct *work)
  506. {
  507. int interval;
  508. struct ab8500_btemp *di = container_of(work,
  509. struct ab8500_btemp, btemp_periodic_work.work);
  510. if (!di->initialized) {
  511. di->initialized = true;
  512. /* Identify the battery */
  513. if (ab8500_btemp_id(di) < 0)
  514. dev_warn(di->dev, "failed to identify the battery\n");
  515. }
  516. di->bat_temp = ab8500_btemp_measure_temp(di);
  517. if (di->bat_temp != di->prev_bat_temp) {
  518. di->prev_bat_temp = di->bat_temp;
  519. power_supply_changed(&di->btemp_psy);
  520. }
  521. if (di->events.ac_conn || di->events.usb_conn)
  522. interval = di->bm->temp_interval_chg;
  523. else
  524. interval = di->bm->temp_interval_nochg;
  525. /* Schedule a new measurement */
  526. queue_delayed_work(di->btemp_wq,
  527. &di->btemp_periodic_work,
  528. round_jiffies(interval * HZ));
  529. }
  530. /**
  531. * ab8500_btemp_batctrlindb_handler() - battery removal detected
  532. * @irq: interrupt number
  533. * @_di: void pointer that has to address of ab8500_btemp
  534. *
  535. * Returns IRQ status(IRQ_HANDLED)
  536. */
  537. static irqreturn_t ab8500_btemp_batctrlindb_handler(int irq, void *_di)
  538. {
  539. struct ab8500_btemp *di = _di;
  540. dev_err(di->dev, "Battery removal detected!\n");
  541. di->events.batt_rem = true;
  542. power_supply_changed(&di->btemp_psy);
  543. return IRQ_HANDLED;
  544. }
  545. /**
  546. * ab8500_btemp_templow_handler() - battery temp lower than 10 degrees
  547. * @irq: interrupt number
  548. * @_di: void pointer that has to address of ab8500_btemp
  549. *
  550. * Returns IRQ status(IRQ_HANDLED)
  551. */
  552. static irqreturn_t ab8500_btemp_templow_handler(int irq, void *_di)
  553. {
  554. struct ab8500_btemp *di = _di;
  555. if (is_ab8500_2p0_or_earlier(di->parent)) {
  556. dev_dbg(di->dev, "Ignore false btemp low irq"
  557. " for ABB cut 1.0, 1.1 and 2.0\n");
  558. } else {
  559. dev_crit(di->dev, "Battery temperature lower than -10deg c\n");
  560. di->events.btemp_low = true;
  561. di->events.btemp_high = false;
  562. di->events.btemp_medhigh = false;
  563. di->events.btemp_lowmed = false;
  564. power_supply_changed(&di->btemp_psy);
  565. }
  566. return IRQ_HANDLED;
  567. }
  568. /**
  569. * ab8500_btemp_temphigh_handler() - battery temp higher than max temp
  570. * @irq: interrupt number
  571. * @_di: void pointer that has to address of ab8500_btemp
  572. *
  573. * Returns IRQ status(IRQ_HANDLED)
  574. */
  575. static irqreturn_t ab8500_btemp_temphigh_handler(int irq, void *_di)
  576. {
  577. struct ab8500_btemp *di = _di;
  578. dev_crit(di->dev, "Battery temperature is higher than MAX temp\n");
  579. di->events.btemp_high = true;
  580. di->events.btemp_medhigh = false;
  581. di->events.btemp_lowmed = false;
  582. di->events.btemp_low = false;
  583. power_supply_changed(&di->btemp_psy);
  584. return IRQ_HANDLED;
  585. }
  586. /**
  587. * ab8500_btemp_lowmed_handler() - battery temp between low and medium
  588. * @irq: interrupt number
  589. * @_di: void pointer that has to address of ab8500_btemp
  590. *
  591. * Returns IRQ status(IRQ_HANDLED)
  592. */
  593. static irqreturn_t ab8500_btemp_lowmed_handler(int irq, void *_di)
  594. {
  595. struct ab8500_btemp *di = _di;
  596. dev_dbg(di->dev, "Battery temperature is between low and medium\n");
  597. di->events.btemp_lowmed = true;
  598. di->events.btemp_medhigh = false;
  599. di->events.btemp_high = false;
  600. di->events.btemp_low = false;
  601. power_supply_changed(&di->btemp_psy);
  602. return IRQ_HANDLED;
  603. }
  604. /**
  605. * ab8500_btemp_medhigh_handler() - battery temp between medium and high
  606. * @irq: interrupt number
  607. * @_di: void pointer that has to address of ab8500_btemp
  608. *
  609. * Returns IRQ status(IRQ_HANDLED)
  610. */
  611. static irqreturn_t ab8500_btemp_medhigh_handler(int irq, void *_di)
  612. {
  613. struct ab8500_btemp *di = _di;
  614. dev_dbg(di->dev, "Battery temperature is between medium and high\n");
  615. di->events.btemp_medhigh = true;
  616. di->events.btemp_lowmed = false;
  617. di->events.btemp_high = false;
  618. di->events.btemp_low = false;
  619. power_supply_changed(&di->btemp_psy);
  620. return IRQ_HANDLED;
  621. }
  622. /**
  623. * ab8500_btemp_periodic() - Periodic temperature measurements
  624. * @di: pointer to the ab8500_btemp structure
  625. * @enable: enable or disable periodic temperature measurements
  626. *
  627. * Starts of stops periodic temperature measurements. Periodic measurements
  628. * should only be done when a charger is connected.
  629. */
  630. static void ab8500_btemp_periodic(struct ab8500_btemp *di,
  631. bool enable)
  632. {
  633. dev_dbg(di->dev, "Enable periodic temperature measurements: %d\n",
  634. enable);
  635. /*
  636. * Make sure a new measurement is done directly by cancelling
  637. * any pending work
  638. */
  639. cancel_delayed_work_sync(&di->btemp_periodic_work);
  640. if (enable)
  641. queue_delayed_work(di->btemp_wq, &di->btemp_periodic_work, 0);
  642. }
  643. /**
  644. * ab8500_btemp_get_temp() - get battery temperature
  645. * @di: pointer to the ab8500_btemp structure
  646. *
  647. * Returns battery temperature
  648. */
  649. static int ab8500_btemp_get_temp(struct ab8500_btemp *di)
  650. {
  651. int temp = 0;
  652. /*
  653. * The BTEMP events are not reliabe on AB8500 cut2.0
  654. * and prior versions
  655. */
  656. if (is_ab8500_2p0_or_earlier(di->parent)) {
  657. temp = di->bat_temp * 10;
  658. } else {
  659. if (di->events.btemp_low) {
  660. if (temp > di->btemp_ranges.btemp_low_limit)
  661. temp = di->btemp_ranges.btemp_low_limit;
  662. else
  663. temp = di->bat_temp * 10;
  664. } else if (di->events.btemp_high) {
  665. if (temp < di->btemp_ranges.btemp_high_limit)
  666. temp = di->btemp_ranges.btemp_high_limit;
  667. else
  668. temp = di->bat_temp * 10;
  669. } else if (di->events.btemp_lowmed) {
  670. if (temp > di->btemp_ranges.btemp_med_limit)
  671. temp = di->btemp_ranges.btemp_med_limit;
  672. else
  673. temp = di->bat_temp * 10;
  674. } else if (di->events.btemp_medhigh) {
  675. if (temp < di->btemp_ranges.btemp_med_limit)
  676. temp = di->btemp_ranges.btemp_med_limit;
  677. else
  678. temp = di->bat_temp * 10;
  679. } else
  680. temp = di->bat_temp * 10;
  681. }
  682. return temp;
  683. }
  684. /**
  685. * ab8500_btemp_get_batctrl_temp() - get the temperature
  686. * @btemp: pointer to the btemp structure
  687. *
  688. * Returns the batctrl temperature in millidegrees
  689. */
  690. int ab8500_btemp_get_batctrl_temp(struct ab8500_btemp *btemp)
  691. {
  692. return btemp->bat_temp * 1000;
  693. }
  694. /**
  695. * ab8500_btemp_get_property() - get the btemp properties
  696. * @psy: pointer to the power_supply structure
  697. * @psp: pointer to the power_supply_property structure
  698. * @val: pointer to the power_supply_propval union
  699. *
  700. * This function gets called when an application tries to get the btemp
  701. * properties by reading the sysfs files.
  702. * online: presence of the battery
  703. * present: presence of the battery
  704. * technology: battery technology
  705. * temp: battery temperature
  706. * Returns error code in case of failure else 0(on success)
  707. */
  708. static int ab8500_btemp_get_property(struct power_supply *psy,
  709. enum power_supply_property psp,
  710. union power_supply_propval *val)
  711. {
  712. struct ab8500_btemp *di;
  713. di = to_ab8500_btemp_device_info(psy);
  714. switch (psp) {
  715. case POWER_SUPPLY_PROP_PRESENT:
  716. case POWER_SUPPLY_PROP_ONLINE:
  717. if (di->events.batt_rem)
  718. val->intval = 0;
  719. else
  720. val->intval = 1;
  721. break;
  722. case POWER_SUPPLY_PROP_TECHNOLOGY:
  723. val->intval = di->bm->bat_type[di->bm->batt_id].name;
  724. break;
  725. case POWER_SUPPLY_PROP_TEMP:
  726. val->intval = ab8500_btemp_get_temp(di);
  727. break;
  728. default:
  729. return -EINVAL;
  730. }
  731. return 0;
  732. }
  733. static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data)
  734. {
  735. struct power_supply *psy;
  736. struct power_supply *ext;
  737. struct ab8500_btemp *di;
  738. union power_supply_propval ret;
  739. int i, j;
  740. bool psy_found = false;
  741. psy = (struct power_supply *)data;
  742. ext = dev_get_drvdata(dev);
  743. di = to_ab8500_btemp_device_info(psy);
  744. /*
  745. * For all psy where the name of your driver
  746. * appears in any supplied_to
  747. */
  748. for (i = 0; i < ext->num_supplicants; i++) {
  749. if (!strcmp(ext->supplied_to[i], psy->name))
  750. psy_found = true;
  751. }
  752. if (!psy_found)
  753. return 0;
  754. /* Go through all properties for the psy */
  755. for (j = 0; j < ext->num_properties; j++) {
  756. enum power_supply_property prop;
  757. prop = ext->properties[j];
  758. if (ext->get_property(ext, prop, &ret))
  759. continue;
  760. switch (prop) {
  761. case POWER_SUPPLY_PROP_PRESENT:
  762. switch (ext->type) {
  763. case POWER_SUPPLY_TYPE_MAINS:
  764. /* AC disconnected */
  765. if (!ret.intval && di->events.ac_conn) {
  766. di->events.ac_conn = false;
  767. }
  768. /* AC connected */
  769. else if (ret.intval && !di->events.ac_conn) {
  770. di->events.ac_conn = true;
  771. if (!di->events.usb_conn)
  772. ab8500_btemp_periodic(di, true);
  773. }
  774. break;
  775. case POWER_SUPPLY_TYPE_USB:
  776. /* USB disconnected */
  777. if (!ret.intval && di->events.usb_conn) {
  778. di->events.usb_conn = false;
  779. }
  780. /* USB connected */
  781. else if (ret.intval && !di->events.usb_conn) {
  782. di->events.usb_conn = true;
  783. if (!di->events.ac_conn)
  784. ab8500_btemp_periodic(di, true);
  785. }
  786. break;
  787. default:
  788. break;
  789. }
  790. break;
  791. default:
  792. break;
  793. }
  794. }
  795. return 0;
  796. }
  797. /**
  798. * ab8500_btemp_external_power_changed() - callback for power supply changes
  799. * @psy: pointer to the structure power_supply
  800. *
  801. * This function is pointing to the function pointer external_power_changed
  802. * of the structure power_supply.
  803. * This function gets executed when there is a change in the external power
  804. * supply to the btemp.
  805. */
  806. static void ab8500_btemp_external_power_changed(struct power_supply *psy)
  807. {
  808. struct ab8500_btemp *di = to_ab8500_btemp_device_info(psy);
  809. class_for_each_device(power_supply_class, NULL,
  810. &di->btemp_psy, ab8500_btemp_get_ext_psy_data);
  811. }
  812. /* ab8500 btemp driver interrupts and their respective isr */
  813. static struct ab8500_btemp_interrupts ab8500_btemp_irq[] = {
  814. {"BAT_CTRL_INDB", ab8500_btemp_batctrlindb_handler},
  815. {"BTEMP_LOW", ab8500_btemp_templow_handler},
  816. {"BTEMP_HIGH", ab8500_btemp_temphigh_handler},
  817. {"BTEMP_LOW_MEDIUM", ab8500_btemp_lowmed_handler},
  818. {"BTEMP_MEDIUM_HIGH", ab8500_btemp_medhigh_handler},
  819. };
  820. #if defined(CONFIG_PM)
  821. static int ab8500_btemp_resume(struct platform_device *pdev)
  822. {
  823. struct ab8500_btemp *di = platform_get_drvdata(pdev);
  824. ab8500_btemp_periodic(di, true);
  825. return 0;
  826. }
  827. static int ab8500_btemp_suspend(struct platform_device *pdev,
  828. pm_message_t state)
  829. {
  830. struct ab8500_btemp *di = platform_get_drvdata(pdev);
  831. ab8500_btemp_periodic(di, false);
  832. return 0;
  833. }
  834. #else
  835. #define ab8500_btemp_suspend NULL
  836. #define ab8500_btemp_resume NULL
  837. #endif
  838. static int ab8500_btemp_remove(struct platform_device *pdev)
  839. {
  840. struct ab8500_btemp *di = platform_get_drvdata(pdev);
  841. int i, irq;
  842. /* Disable interrupts */
  843. for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) {
  844. irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name);
  845. free_irq(irq, di);
  846. }
  847. /* Delete the work queue */
  848. destroy_workqueue(di->btemp_wq);
  849. flush_scheduled_work();
  850. power_supply_unregister(&di->btemp_psy);
  851. platform_set_drvdata(pdev, NULL);
  852. return 0;
  853. }
  854. static char *supply_interface[] = {
  855. "ab8500_chargalg",
  856. "ab8500_fg",
  857. };
  858. static int ab8500_btemp_probe(struct platform_device *pdev)
  859. {
  860. struct device_node *np = pdev->dev.of_node;
  861. struct abx500_bm_data *plat = pdev->dev.platform_data;
  862. struct ab8500_btemp *di;
  863. int irq, i, ret = 0;
  864. u8 val;
  865. di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
  866. if (!di) {
  867. dev_err(&pdev->dev, "%s no mem for ab8500_btemp\n", __func__);
  868. return -ENOMEM;
  869. }
  870. if (!plat) {
  871. dev_err(&pdev->dev, "no battery management data supplied\n");
  872. return -EINVAL;
  873. }
  874. di->bm = plat;
  875. if (np) {
  876. ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm);
  877. if (ret) {
  878. dev_err(&pdev->dev, "failed to get battery information\n");
  879. return ret;
  880. }
  881. }
  882. /* get parent data */
  883. di->dev = &pdev->dev;
  884. di->parent = dev_get_drvdata(pdev->dev.parent);
  885. di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
  886. di->initialized = false;
  887. /* BTEMP supply */
  888. di->btemp_psy.name = "ab8500_btemp";
  889. di->btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY;
  890. di->btemp_psy.properties = ab8500_btemp_props;
  891. di->btemp_psy.num_properties = ARRAY_SIZE(ab8500_btemp_props);
  892. di->btemp_psy.get_property = ab8500_btemp_get_property;
  893. di->btemp_psy.supplied_to = supply_interface;
  894. di->btemp_psy.num_supplicants = ARRAY_SIZE(supply_interface);
  895. di->btemp_psy.external_power_changed =
  896. ab8500_btemp_external_power_changed;
  897. /* Create a work queue for the btemp */
  898. di->btemp_wq =
  899. create_singlethread_workqueue("ab8500_btemp_wq");
  900. if (di->btemp_wq == NULL) {
  901. dev_err(di->dev, "failed to create work queue\n");
  902. return -ENOMEM;
  903. }
  904. /* Init work for measuring temperature periodically */
  905. INIT_DEFERRABLE_WORK(&di->btemp_periodic_work,
  906. ab8500_btemp_periodic_work);
  907. /* Set BTEMP thermal limits. Low and Med are fixed */
  908. di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT;
  909. di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT;
  910. ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
  911. AB8500_BTEMP_HIGH_TH, &val);
  912. if (ret < 0) {
  913. dev_err(di->dev, "%s ab8500 read failed\n", __func__);
  914. goto free_btemp_wq;
  915. }
  916. switch (val) {
  917. case BTEMP_HIGH_TH_57_0:
  918. case BTEMP_HIGH_TH_57_1:
  919. di->btemp_ranges.btemp_high_limit =
  920. BTEMP_THERMAL_HIGH_LIMIT_57;
  921. break;
  922. case BTEMP_HIGH_TH_52:
  923. di->btemp_ranges.btemp_high_limit =
  924. BTEMP_THERMAL_HIGH_LIMIT_52;
  925. break;
  926. case BTEMP_HIGH_TH_62:
  927. di->btemp_ranges.btemp_high_limit =
  928. BTEMP_THERMAL_HIGH_LIMIT_62;
  929. break;
  930. }
  931. /* Register BTEMP power supply class */
  932. ret = power_supply_register(di->dev, &di->btemp_psy);
  933. if (ret) {
  934. dev_err(di->dev, "failed to register BTEMP psy\n");
  935. goto free_btemp_wq;
  936. }
  937. /* Register interrupts */
  938. for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) {
  939. irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name);
  940. ret = request_threaded_irq(irq, NULL, ab8500_btemp_irq[i].isr,
  941. IRQF_SHARED | IRQF_NO_SUSPEND,
  942. ab8500_btemp_irq[i].name, di);
  943. if (ret) {
  944. dev_err(di->dev, "failed to request %s IRQ %d: %d\n"
  945. , ab8500_btemp_irq[i].name, irq, ret);
  946. goto free_irq;
  947. }
  948. dev_dbg(di->dev, "Requested %s IRQ %d: %d\n",
  949. ab8500_btemp_irq[i].name, irq, ret);
  950. }
  951. platform_set_drvdata(pdev, di);
  952. /* Kick off periodic temperature measurements */
  953. ab8500_btemp_periodic(di, true);
  954. list_add_tail(&di->node, &ab8500_btemp_list);
  955. return ret;
  956. free_irq:
  957. power_supply_unregister(&di->btemp_psy);
  958. /* We also have to free all successfully registered irqs */
  959. for (i = i - 1; i >= 0; i--) {
  960. irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name);
  961. free_irq(irq, di);
  962. }
  963. free_btemp_wq:
  964. destroy_workqueue(di->btemp_wq);
  965. return ret;
  966. }
  967. static const struct of_device_id ab8500_btemp_match[] = {
  968. { .compatible = "stericsson,ab8500-btemp", },
  969. { },
  970. };
  971. static struct platform_driver ab8500_btemp_driver = {
  972. .probe = ab8500_btemp_probe,
  973. .remove = ab8500_btemp_remove,
  974. .suspend = ab8500_btemp_suspend,
  975. .resume = ab8500_btemp_resume,
  976. .driver = {
  977. .name = "ab8500-btemp",
  978. .owner = THIS_MODULE,
  979. .of_match_table = ab8500_btemp_match,
  980. },
  981. };
  982. static int __init ab8500_btemp_init(void)
  983. {
  984. return platform_driver_register(&ab8500_btemp_driver);
  985. }
  986. static void __exit ab8500_btemp_exit(void)
  987. {
  988. platform_driver_unregister(&ab8500_btemp_driver);
  989. }
  990. subsys_initcall_sync(ab8500_btemp_init);
  991. module_exit(ab8500_btemp_exit);
  992. MODULE_LICENSE("GPL v2");
  993. MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy");
  994. MODULE_ALIAS("platform:ab8500-btemp");
  995. MODULE_DESCRIPTION("AB8500 battery temperature driver");