ab8500_btemp.c 29 KB

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