msm_tsens.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. /* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. /*
  14. * Qualcomm TSENS Thermal Manager driver
  15. *
  16. */
  17. #include <linux/module.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/thermal.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/delay.h>
  22. #include <linux/slab.h>
  23. #include <linux/io.h>
  24. #include <mach/msm_iomap.h>
  25. #include <linux/pm.h>
  26. /* Trips: from very hot to very cold */
  27. enum tsens_trip_type {
  28. TSENS_TRIP_STAGE3 = 0,
  29. TSENS_TRIP_STAGE2,
  30. TSENS_TRIP_STAGE1,
  31. TSENS_TRIP_STAGE0,
  32. TSENS_TRIP_NUM,
  33. };
  34. #define TSENS_NUM_SENSORS 1 /* There are 5 but only 1 is useful now */
  35. #define TSENS_CAL_DEGC 30 /* degree C used for calibration */
  36. #define TSENS_QFPROM_ADDR (MSM_QFPROM_BASE + 0x000000bc)
  37. #define TSENS_QFPROM_RED_TEMP_SENSOR0_SHIFT 24
  38. #define TSENS_QFPROM_TEMP_SENSOR0_SHIFT 16
  39. #define TSENS_QFPROM_TEMP_SENSOR0_MASK (255 << TSENS_QFPROM_TEMP_SENSOR0_SHIFT)
  40. #define TSENS_SLOPE (0.702) /* slope in (degrees_C / ADC_code) */
  41. #define TSENS_FACTOR (1000) /* convert floating-point into integer */
  42. #define TSENS_CONFIG 01 /* this setting found to be optimal */
  43. #define TSENS_CONFIG_SHIFT 28
  44. #define TSENS_CONFIG_MASK (3 << TSENS_CONFIG_SHIFT)
  45. #define TSENS_CNTL_ADDR (MSM_CLK_CTL_BASE + 0x00003620)
  46. #define TSENS_EN (1 << 0)
  47. #define TSENS_SW_RST (1 << 1)
  48. #define SENSOR0_EN (1 << 3)
  49. #define SENSOR1_EN (1 << 4)
  50. #define SENSOR2_EN (1 << 5)
  51. #define SENSOR3_EN (1 << 6)
  52. #define SENSOR4_EN (1 << 7)
  53. #define TSENS_MIN_STATUS_MASK (1 << 8)
  54. #define TSENS_LOWER_STATUS_CLR (1 << 9)
  55. #define TSENS_UPPER_STATUS_CLR (1 << 10)
  56. #define TSENS_MAX_STATUS_MASK (1 << 11)
  57. #define TSENS_MEASURE_PERIOD 4 /* 1 sec. default as required by Willie */
  58. #define TSENS_SLP_CLK_ENA (1 << 24)
  59. #define TSENS_THRESHOLD_ADDR (MSM_CLK_CTL_BASE + 0x00003624)
  60. #define TSENS_THRESHOLD_MAX_CODE (0xff)
  61. #define TSENS_THRESHOLD_MAX_LIMIT_MASK (TSENS_THRESHOLD_MAX_CODE << 24)
  62. #define TSENS_THRESHOLD_MIN_LIMIT_MASK (TSENS_THRESHOLD_MAX_CODE << 16)
  63. #define TSENS_THRESHOLD_UPPER_LIMIT_MASK (TSENS_THRESHOLD_MAX_CODE << 8)
  64. #define TSENS_THRESHOLD_LOWER_LIMIT_MASK (TSENS_THRESHOLD_MAX_CODE << 0)
  65. /* Initial temperature threshold values */
  66. #define TSENS_LOWER_LIMIT_TH 0x50
  67. #define TSENS_UPPER_LIMIT_TH 0xdf
  68. #define TSENS_MIN_LIMIT_TH 0x38
  69. #define TSENS_MAX_LIMIT_TH 0xff
  70. #define TSENS_S0_STATUS_ADDR (MSM_CLK_CTL_BASE + 0x00003628)
  71. #define TSENS_INT_STATUS_ADDR (MSM_CLK_CTL_BASE + 0x0000363c)
  72. #define TSENS_LOWER_INT_MASK (1 << 1)
  73. #define TSENS_UPPER_INT_MASK (1 << 2)
  74. #define TSENS_TRDY_MASK (1 << 7)
  75. struct tsens_tm_device_sensor {
  76. struct thermal_zone_device *tz_dev;
  77. enum thermal_device_mode mode;
  78. unsigned int sensor_num;
  79. };
  80. struct tsens_tm_device {
  81. struct tsens_tm_device_sensor sensor[TSENS_NUM_SENSORS];
  82. bool prev_reading_avail;
  83. int offset;
  84. struct work_struct work;
  85. uint32_t pm_tsens_thr_data;
  86. };
  87. struct tsens_tm_device *tmdev;
  88. /* Temperature on y axis and ADC-code on x-axis */
  89. static int tsens_tz_code_to_degC(int adc_code)
  90. {
  91. int degC, degcbeforefactor;
  92. degcbeforefactor = adc_code * (int)(TSENS_SLOPE * TSENS_FACTOR)
  93. + tmdev->offset;
  94. if (degcbeforefactor == 0)
  95. degC = degcbeforefactor;
  96. else if (degcbeforefactor > 0)
  97. degC = (degcbeforefactor + TSENS_FACTOR/2) / TSENS_FACTOR;
  98. else /* rounding for negative degrees */
  99. degC = (degcbeforefactor - TSENS_FACTOR/2) / TSENS_FACTOR;
  100. return degC;
  101. }
  102. static int tsens_tz_degC_to_code(int degC)
  103. {
  104. int code = (degC * TSENS_FACTOR - tmdev->offset
  105. + (int)(TSENS_FACTOR * TSENS_SLOPE)/2)
  106. / (int)(TSENS_FACTOR * TSENS_SLOPE);
  107. if (code > 255) /* upper bound */
  108. code = 255;
  109. else if (code < 0) /* lower bound */
  110. code = 0;
  111. return code;
  112. }
  113. static int tsens_tz_get_temp(struct thermal_zone_device *thermal,
  114. unsigned long *temp)
  115. {
  116. struct tsens_tm_device_sensor *tm_sensor = thermal->devdata;
  117. unsigned int code;
  118. if (!tm_sensor || tm_sensor->mode != THERMAL_DEVICE_ENABLED || !temp)
  119. return -EINVAL;
  120. if (!tmdev->prev_reading_avail) {
  121. while (!(readl(TSENS_INT_STATUS_ADDR) & TSENS_TRDY_MASK))
  122. msleep(1);
  123. tmdev->prev_reading_avail = 1;
  124. }
  125. code = readl(TSENS_S0_STATUS_ADDR + (tm_sensor->sensor_num << 2));
  126. *temp = tsens_tz_code_to_degC(code);
  127. return 0;
  128. }
  129. static int tsens_tz_get_mode(struct thermal_zone_device *thermal,
  130. enum thermal_device_mode *mode)
  131. {
  132. struct tsens_tm_device_sensor *tm_sensor = thermal->devdata;
  133. if (!tm_sensor || !mode)
  134. return -EINVAL;
  135. *mode = tm_sensor->mode;
  136. return 0;
  137. }
  138. static int tsens_tz_set_mode(struct thermal_zone_device *thermal,
  139. enum thermal_device_mode mode)
  140. {
  141. struct tsens_tm_device_sensor *tm_sensor = thermal->devdata;
  142. unsigned int reg, mask;
  143. if (!tm_sensor)
  144. return -EINVAL;
  145. if (mode != tm_sensor->mode) {
  146. pr_info("%s: mode: %d --> %d\n", __func__, tm_sensor->mode,
  147. mode);
  148. reg = readl(TSENS_CNTL_ADDR);
  149. mask = 1 << (tm_sensor->sensor_num + 3);
  150. if (mode == THERMAL_DEVICE_ENABLED) {
  151. writel(reg | TSENS_SW_RST, TSENS_CNTL_ADDR);
  152. reg |= mask | TSENS_SLP_CLK_ENA | TSENS_EN;
  153. tmdev->prev_reading_avail = 0;
  154. } else {
  155. reg &= ~mask;
  156. if (!(reg & (((1 << TSENS_NUM_SENSORS) - 1) << 3)))
  157. reg &= ~(TSENS_SLP_CLK_ENA | TSENS_EN);
  158. }
  159. writel(reg, TSENS_CNTL_ADDR);
  160. }
  161. tm_sensor->mode = mode;
  162. return 0;
  163. }
  164. static int tsens_tz_get_trip_type(struct thermal_zone_device *thermal,
  165. int trip, enum thermal_trip_type *type)
  166. {
  167. struct tsens_tm_device_sensor *tm_sensor = thermal->devdata;
  168. if (!tm_sensor || trip < 0 || !type)
  169. return -EINVAL;
  170. switch (trip) {
  171. case TSENS_TRIP_STAGE3:
  172. *type = THERMAL_TRIP_CRITICAL;
  173. break;
  174. case TSENS_TRIP_STAGE2:
  175. *type = THERMAL_TRIP_CONFIGURABLE_HI;
  176. break;
  177. case TSENS_TRIP_STAGE1:
  178. *type = THERMAL_TRIP_CONFIGURABLE_LOW;
  179. break;
  180. case TSENS_TRIP_STAGE0:
  181. *type = THERMAL_TRIP_CRITICAL_LOW;
  182. break;
  183. default:
  184. return -EINVAL;
  185. }
  186. return 0;
  187. }
  188. static int tsens_tz_activate_trip_type(struct thermal_zone_device *thermal,
  189. int trip, enum thermal_trip_activation_mode mode)
  190. {
  191. struct tsens_tm_device_sensor *tm_sensor = thermal->devdata;
  192. unsigned int reg_cntl, reg_th, code, hi_code, lo_code, mask;
  193. if (!tm_sensor || trip < 0)
  194. return -EINVAL;
  195. lo_code = 0;
  196. hi_code = TSENS_THRESHOLD_MAX_CODE;
  197. reg_cntl = readl(TSENS_CNTL_ADDR);
  198. reg_th = readl(TSENS_THRESHOLD_ADDR);
  199. switch (trip) {
  200. case TSENS_TRIP_STAGE3:
  201. code = (reg_th & TSENS_THRESHOLD_MAX_LIMIT_MASK) >> 24;
  202. mask = TSENS_MAX_STATUS_MASK;
  203. if (!(reg_cntl & TSENS_UPPER_STATUS_CLR))
  204. lo_code = (reg_th & TSENS_THRESHOLD_UPPER_LIMIT_MASK)
  205. >> 8;
  206. else if (!(reg_cntl & TSENS_LOWER_STATUS_CLR))
  207. lo_code = (reg_th & TSENS_THRESHOLD_LOWER_LIMIT_MASK);
  208. else if (!(reg_cntl & TSENS_MIN_STATUS_MASK))
  209. lo_code = (reg_th & TSENS_THRESHOLD_MIN_LIMIT_MASK)
  210. >> 16;
  211. break;
  212. case TSENS_TRIP_STAGE2:
  213. code = (reg_th & TSENS_THRESHOLD_UPPER_LIMIT_MASK) >> 8;
  214. mask = TSENS_UPPER_STATUS_CLR;
  215. if (!(reg_cntl & TSENS_MAX_STATUS_MASK))
  216. hi_code = (reg_th & TSENS_THRESHOLD_MAX_LIMIT_MASK)
  217. >> 24;
  218. if (!(reg_cntl & TSENS_LOWER_STATUS_CLR))
  219. lo_code = (reg_th & TSENS_THRESHOLD_LOWER_LIMIT_MASK);
  220. else if (!(reg_cntl & TSENS_MIN_STATUS_MASK))
  221. lo_code = (reg_th & TSENS_THRESHOLD_MIN_LIMIT_MASK)
  222. >> 16;
  223. break;
  224. case TSENS_TRIP_STAGE1:
  225. code = (reg_th & TSENS_THRESHOLD_LOWER_LIMIT_MASK) >> 0;
  226. mask = TSENS_LOWER_STATUS_CLR;
  227. if (!(reg_cntl & TSENS_MIN_STATUS_MASK))
  228. lo_code = (reg_th & TSENS_THRESHOLD_MIN_LIMIT_MASK)
  229. >> 16;
  230. if (!(reg_cntl & TSENS_UPPER_STATUS_CLR))
  231. hi_code = (reg_th & TSENS_THRESHOLD_UPPER_LIMIT_MASK)
  232. >> 8;
  233. else if (!(reg_cntl & TSENS_MAX_STATUS_MASK))
  234. hi_code = (reg_th & TSENS_THRESHOLD_MAX_LIMIT_MASK)
  235. >> 24;
  236. break;
  237. case TSENS_TRIP_STAGE0:
  238. code = (reg_th & TSENS_THRESHOLD_MIN_LIMIT_MASK) >> 16;
  239. mask = TSENS_MIN_STATUS_MASK;
  240. if (!(reg_cntl & TSENS_LOWER_STATUS_CLR))
  241. hi_code = (reg_th & TSENS_THRESHOLD_LOWER_LIMIT_MASK);
  242. else if (!(reg_cntl & TSENS_UPPER_STATUS_CLR))
  243. hi_code = (reg_th & TSENS_THRESHOLD_UPPER_LIMIT_MASK)
  244. >> 8;
  245. else if (!(reg_cntl & TSENS_MAX_STATUS_MASK))
  246. hi_code = (reg_th & TSENS_THRESHOLD_MAX_LIMIT_MASK)
  247. >> 24;
  248. break;
  249. default:
  250. return -EINVAL;
  251. }
  252. if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
  253. writel(reg_cntl | mask, TSENS_CNTL_ADDR);
  254. else {
  255. if (code < lo_code || code > hi_code)
  256. return -EINVAL;
  257. writel(reg_cntl & ~mask, TSENS_CNTL_ADDR);
  258. }
  259. return 0;
  260. }
  261. static int tsens_tz_get_trip_temp(struct thermal_zone_device *thermal,
  262. int trip, unsigned long *temp)
  263. {
  264. struct tsens_tm_device_sensor *tm_sensor = thermal->devdata;
  265. unsigned int reg;
  266. if (!tm_sensor || trip < 0 || !temp)
  267. return -EINVAL;
  268. reg = readl(TSENS_THRESHOLD_ADDR);
  269. switch (trip) {
  270. case TSENS_TRIP_STAGE3:
  271. reg = (reg & TSENS_THRESHOLD_MAX_LIMIT_MASK) >> 24;
  272. break;
  273. case TSENS_TRIP_STAGE2:
  274. reg = (reg & TSENS_THRESHOLD_UPPER_LIMIT_MASK) >> 8;
  275. break;
  276. case TSENS_TRIP_STAGE1:
  277. reg = (reg & TSENS_THRESHOLD_LOWER_LIMIT_MASK) >> 0;
  278. break;
  279. case TSENS_TRIP_STAGE0:
  280. reg = (reg & TSENS_THRESHOLD_MIN_LIMIT_MASK) >> 16;
  281. break;
  282. default:
  283. return -EINVAL;
  284. }
  285. *temp = tsens_tz_code_to_degC(reg);
  286. return 0;
  287. }
  288. static int tsens_tz_get_crit_temp(struct thermal_zone_device *thermal,
  289. unsigned long *temp)
  290. {
  291. return tsens_tz_get_trip_temp(thermal, TSENS_TRIP_STAGE3, temp);
  292. }
  293. static int tsens_tz_set_trip_temp(struct thermal_zone_device *thermal,
  294. int trip, long temp)
  295. {
  296. struct tsens_tm_device_sensor *tm_sensor = thermal->devdata;
  297. unsigned int reg_th, reg_cntl;
  298. int code, hi_code, lo_code, code_err_chk;
  299. code_err_chk = code = tsens_tz_degC_to_code(temp);
  300. if (!tm_sensor || trip < 0)
  301. return -EINVAL;
  302. lo_code = 0;
  303. hi_code = TSENS_THRESHOLD_MAX_CODE;
  304. reg_cntl = readl(TSENS_CNTL_ADDR);
  305. reg_th = readl(TSENS_THRESHOLD_ADDR);
  306. switch (trip) {
  307. case TSENS_TRIP_STAGE3:
  308. code <<= 24;
  309. reg_th &= ~TSENS_THRESHOLD_MAX_LIMIT_MASK;
  310. if (!(reg_cntl & TSENS_UPPER_STATUS_CLR))
  311. lo_code = (reg_th & TSENS_THRESHOLD_UPPER_LIMIT_MASK)
  312. >> 8;
  313. else if (!(reg_cntl & TSENS_LOWER_STATUS_CLR))
  314. lo_code = (reg_th & TSENS_THRESHOLD_LOWER_LIMIT_MASK);
  315. else if (!(reg_cntl & TSENS_MIN_STATUS_MASK))
  316. lo_code = (reg_th & TSENS_THRESHOLD_MIN_LIMIT_MASK)
  317. >> 16;
  318. break;
  319. case TSENS_TRIP_STAGE2:
  320. code <<= 8;
  321. reg_th &= ~TSENS_THRESHOLD_UPPER_LIMIT_MASK;
  322. if (!(reg_cntl & TSENS_MAX_STATUS_MASK))
  323. hi_code = (reg_th & TSENS_THRESHOLD_MAX_LIMIT_MASK)
  324. >> 24;
  325. if (!(reg_cntl & TSENS_LOWER_STATUS_CLR))
  326. lo_code = (reg_th & TSENS_THRESHOLD_LOWER_LIMIT_MASK);
  327. else if (!(reg_cntl & TSENS_MIN_STATUS_MASK))
  328. lo_code = (reg_th & TSENS_THRESHOLD_MIN_LIMIT_MASK)
  329. >> 16;
  330. break;
  331. case TSENS_TRIP_STAGE1:
  332. reg_th &= ~TSENS_THRESHOLD_LOWER_LIMIT_MASK;
  333. if (!(reg_cntl & TSENS_MIN_STATUS_MASK))
  334. lo_code = (reg_th & TSENS_THRESHOLD_MIN_LIMIT_MASK)
  335. >> 16;
  336. if (!(reg_cntl & TSENS_UPPER_STATUS_CLR))
  337. hi_code = (reg_th & TSENS_THRESHOLD_UPPER_LIMIT_MASK)
  338. >> 8;
  339. else if (!(reg_cntl & TSENS_MAX_STATUS_MASK))
  340. hi_code = (reg_th & TSENS_THRESHOLD_MAX_LIMIT_MASK)
  341. >> 24;
  342. break;
  343. case TSENS_TRIP_STAGE0:
  344. code <<= 16;
  345. reg_th &= ~TSENS_THRESHOLD_MIN_LIMIT_MASK;
  346. if (!(reg_cntl & TSENS_LOWER_STATUS_CLR))
  347. hi_code = (reg_th & TSENS_THRESHOLD_LOWER_LIMIT_MASK);
  348. else if (!(reg_cntl & TSENS_UPPER_STATUS_CLR))
  349. hi_code = (reg_th & TSENS_THRESHOLD_UPPER_LIMIT_MASK)
  350. >> 8;
  351. else if (!(reg_cntl & TSENS_MAX_STATUS_MASK))
  352. hi_code = (reg_th & TSENS_THRESHOLD_MAX_LIMIT_MASK)
  353. >> 24;
  354. break;
  355. default:
  356. return -EINVAL;
  357. }
  358. if (code_err_chk < lo_code || code_err_chk > hi_code)
  359. return -EINVAL;
  360. writel(reg_th | code, TSENS_THRESHOLD_ADDR);
  361. return 0;
  362. }
  363. static struct thermal_zone_device_ops tsens_thermal_zone_ops = {
  364. .get_temp = tsens_tz_get_temp,
  365. .get_mode = tsens_tz_get_mode,
  366. .set_mode = tsens_tz_set_mode,
  367. .get_trip_type = tsens_tz_get_trip_type,
  368. .activate_trip_type = tsens_tz_activate_trip_type,
  369. .get_trip_temp = tsens_tz_get_trip_temp,
  370. .set_trip_temp = tsens_tz_set_trip_temp,
  371. .get_crit_temp = tsens_tz_get_crit_temp,
  372. };
  373. static void notify_uspace_tsens_fn(struct work_struct *work)
  374. {
  375. struct tsens_tm_device *tm = container_of(work, struct tsens_tm_device,
  376. work);
  377. /* Currently only Sensor0 is supported. We added support
  378. to notify only the supported Sensor and this portion
  379. needs to be revisited once other sensors are supported */
  380. sysfs_notify(&tm->sensor[0].tz_dev->device.kobj,
  381. NULL, "type");
  382. }
  383. static irqreturn_t tsens_isr(int irq, void *data)
  384. {
  385. unsigned int reg = readl(TSENS_CNTL_ADDR);
  386. writel(reg | TSENS_LOWER_STATUS_CLR | TSENS_UPPER_STATUS_CLR,
  387. TSENS_CNTL_ADDR);
  388. return IRQ_WAKE_THREAD;
  389. }
  390. static irqreturn_t tsens_isr_thread(int irq, void *data)
  391. {
  392. struct tsens_tm_device *tm = data;
  393. unsigned int threshold, threshold_low, i, code, reg, sensor, mask;
  394. bool upper_th_x, lower_th_x;
  395. int adc_code;
  396. mask = ~(TSENS_LOWER_STATUS_CLR | TSENS_UPPER_STATUS_CLR);
  397. threshold = readl(TSENS_THRESHOLD_ADDR);
  398. threshold_low = threshold & TSENS_THRESHOLD_LOWER_LIMIT_MASK;
  399. threshold = (threshold & TSENS_THRESHOLD_UPPER_LIMIT_MASK) >> 8;
  400. reg = sensor = readl(TSENS_CNTL_ADDR);
  401. sensor &= (SENSOR0_EN | SENSOR1_EN | SENSOR2_EN |
  402. SENSOR3_EN | SENSOR4_EN);
  403. sensor >>= 3;
  404. for (i = 0; i < TSENS_NUM_SENSORS; i++) {
  405. if (sensor & 1) {
  406. code = readl(TSENS_S0_STATUS_ADDR + (i << 2));
  407. upper_th_x = code >= threshold;
  408. lower_th_x = code <= threshold_low;
  409. if (upper_th_x)
  410. mask |= TSENS_UPPER_STATUS_CLR;
  411. if (lower_th_x)
  412. mask |= TSENS_LOWER_STATUS_CLR;
  413. if (upper_th_x || lower_th_x) {
  414. /* Notify user space */
  415. schedule_work(&tm->work);
  416. adc_code = readl(TSENS_S0_STATUS_ADDR
  417. + (i << 2));
  418. printk(KERN_INFO"\nTrip point triggered by "
  419. "current temperature (%d degrees) "
  420. "measured by Temperature-Sensor %d\n",
  421. tsens_tz_code_to_degC(adc_code), i);
  422. }
  423. }
  424. sensor >>= 1;
  425. }
  426. writel(reg & mask, TSENS_CNTL_ADDR);
  427. return IRQ_HANDLED;
  428. }
  429. #ifdef CONFIG_PM
  430. static int tsens_suspend(struct device *dev)
  431. {
  432. unsigned int reg;
  433. tmdev->pm_tsens_thr_data = readl_relaxed(TSENS_THRESHOLD_ADDR);
  434. reg = readl_relaxed(TSENS_CNTL_ADDR);
  435. writel_relaxed(reg & ~(TSENS_SLP_CLK_ENA | TSENS_EN), TSENS_CNTL_ADDR);
  436. tmdev->prev_reading_avail = 0;
  437. disable_irq_nosync(TSENS_UPPER_LOWER_INT);
  438. mb();
  439. return 0;
  440. }
  441. static int tsens_resume(struct device *dev)
  442. {
  443. unsigned int reg;
  444. reg = readl_relaxed(TSENS_CNTL_ADDR);
  445. writel_relaxed(reg | TSENS_SW_RST, TSENS_CNTL_ADDR);
  446. reg |= TSENS_SLP_CLK_ENA | TSENS_EN | (TSENS_MEASURE_PERIOD << 16) |
  447. TSENS_MIN_STATUS_MASK | TSENS_MAX_STATUS_MASK |
  448. (((1 << TSENS_NUM_SENSORS) - 1) << 3);
  449. reg = (reg & ~TSENS_CONFIG_MASK) | (TSENS_CONFIG << TSENS_CONFIG_SHIFT);
  450. writel_relaxed(reg, TSENS_CNTL_ADDR);
  451. if (tmdev->sensor->mode == THERMAL_DEVICE_DISABLED) {
  452. writel_relaxed(reg & ~((((1 << TSENS_NUM_SENSORS) - 1) << 3)
  453. | TSENS_SLP_CLK_ENA | TSENS_EN), TSENS_CNTL_ADDR);
  454. }
  455. writel_relaxed(tmdev->pm_tsens_thr_data, TSENS_THRESHOLD_ADDR);
  456. enable_irq(TSENS_UPPER_LOWER_INT);
  457. mb();
  458. return 0;
  459. }
  460. static const struct dev_pm_ops tsens_pm_ops = {
  461. .suspend = tsens_suspend,
  462. .resume = tsens_resume,
  463. };
  464. #endif
  465. static int __devinit tsens_tm_probe(struct platform_device *pdev)
  466. {
  467. unsigned int reg, i, calib_data, calib_data_backup;
  468. int rc;
  469. calib_data = (readl(TSENS_QFPROM_ADDR) & TSENS_QFPROM_TEMP_SENSOR0_MASK)
  470. >> TSENS_QFPROM_TEMP_SENSOR0_SHIFT;
  471. calib_data_backup = readl(TSENS_QFPROM_ADDR)
  472. >> TSENS_QFPROM_RED_TEMP_SENSOR0_SHIFT;
  473. if (calib_data_backup)
  474. calib_data = calib_data_backup;
  475. if (!calib_data) {
  476. pr_err("%s: No temperature sensor data for calibration"
  477. " in QFPROM!\n", __func__);
  478. return -ENODEV;
  479. }
  480. tmdev = kzalloc(sizeof(struct tsens_tm_device), GFP_KERNEL);
  481. if (tmdev == NULL) {
  482. pr_err("%s: kzalloc() failed.\n", __func__);
  483. return -ENOMEM;
  484. }
  485. platform_set_drvdata(pdev, tmdev);
  486. tmdev->offset = TSENS_FACTOR * TSENS_CAL_DEGC
  487. - (int)(TSENS_FACTOR * TSENS_SLOPE) * calib_data;
  488. tmdev->prev_reading_avail = 0;
  489. INIT_WORK(&tmdev->work, notify_uspace_tsens_fn);
  490. reg = readl(TSENS_CNTL_ADDR);
  491. writel(reg | TSENS_SW_RST, TSENS_CNTL_ADDR);
  492. reg |= TSENS_SLP_CLK_ENA | TSENS_EN | (TSENS_MEASURE_PERIOD << 16) |
  493. TSENS_LOWER_STATUS_CLR | TSENS_UPPER_STATUS_CLR |
  494. TSENS_MIN_STATUS_MASK | TSENS_MAX_STATUS_MASK |
  495. (((1 << TSENS_NUM_SENSORS) - 1) << 3);
  496. /* set TSENS_CONFIG bits (bits 29:28 of TSENS_CNTL) to '01';
  497. this setting found to be optimal. */
  498. reg = (reg & ~TSENS_CONFIG_MASK) | (TSENS_CONFIG << TSENS_CONFIG_SHIFT);
  499. writel(reg, TSENS_CNTL_ADDR);
  500. writel((TSENS_LOWER_LIMIT_TH << 0) | (TSENS_UPPER_LIMIT_TH << 8) |
  501. (TSENS_MIN_LIMIT_TH << 16) | (TSENS_MAX_LIMIT_TH << 24),
  502. TSENS_THRESHOLD_ADDR);
  503. for (i = 0; i < TSENS_NUM_SENSORS; i++) {
  504. char name[17];
  505. sprintf(name, "tsens_tz_sensor%d", i);
  506. tmdev->sensor[i].mode = THERMAL_DEVICE_ENABLED;
  507. tmdev->sensor[i].tz_dev = thermal_zone_device_register(name,
  508. TSENS_TRIP_NUM, &tmdev->sensor[i],
  509. &tsens_thermal_zone_ops, 0, 0, 0, 0);
  510. if (tmdev->sensor[i].tz_dev == NULL) {
  511. pr_err("%s: thermal_zone_device_register() failed.\n",
  512. __func__);
  513. kfree(tmdev);
  514. return -ENODEV;
  515. }
  516. tmdev->sensor[i].sensor_num = i;
  517. tmdev->sensor[i].mode = THERMAL_DEVICE_DISABLED;
  518. }
  519. rc = request_threaded_irq(TSENS_UPPER_LOWER_INT, tsens_isr,
  520. tsens_isr_thread, 0, "tsens", tmdev);
  521. if (rc < 0) {
  522. pr_err("%s: request_irq FAIL: %d\n", __func__, rc);
  523. kfree(tmdev);
  524. return rc;
  525. }
  526. writel(reg & ~((((1 << TSENS_NUM_SENSORS) - 1) << 3)
  527. | TSENS_SLP_CLK_ENA | TSENS_EN), TSENS_CNTL_ADDR);
  528. pr_notice("%s: OK\n", __func__);
  529. return 0;
  530. }
  531. static int __devexit tsens_tm_remove(struct platform_device *pdev)
  532. {
  533. struct tsens_tm_device *tmdev = platform_get_drvdata(pdev);
  534. unsigned int reg, i;
  535. reg = readl(TSENS_CNTL_ADDR);
  536. writel(reg & ~(TSENS_SLP_CLK_ENA | TSENS_EN), TSENS_CNTL_ADDR);
  537. for (i = 0; i < TSENS_NUM_SENSORS; i++)
  538. thermal_zone_device_unregister(tmdev->sensor[i].tz_dev);
  539. platform_set_drvdata(pdev, NULL);
  540. free_irq(TSENS_UPPER_LOWER_INT, tmdev);
  541. kfree(tmdev);
  542. return 0;
  543. }
  544. static struct platform_driver tsens_tm_driver = {
  545. .probe = tsens_tm_probe,
  546. .remove = __devexit_p(tsens_tm_remove),
  547. .driver = {
  548. .name = "tsens-tm",
  549. .owner = THIS_MODULE,
  550. #ifdef CONFIG_PM
  551. .pm = &tsens_pm_ops,
  552. #endif
  553. },
  554. };
  555. static int __init tsens_init(void)
  556. {
  557. return platform_driver_register(&tsens_tm_driver);
  558. }
  559. static void __exit tsens_exit(void)
  560. {
  561. platform_driver_unregister(&tsens_tm_driver);
  562. }
  563. module_init(tsens_init);
  564. module_exit(tsens_exit);
  565. MODULE_LICENSE("GPL v2");
  566. MODULE_DESCRIPTION("MSM Temperature Sensor driver");
  567. MODULE_VERSION("1.0");
  568. MODULE_ALIAS("platform:tsens-tm");