temphumidity_shtc1.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. /*
  2. * Copyright (C) 2012, Samsung Electronics Co. Ltd. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include "../ssp.h"
  16. #include <linux/qpnp/qpnp-adc.h>
  17. /*************************************************************************/
  18. /* factory Sysfs */
  19. /*************************************************************************/
  20. #define VENDOR "SENSIRION"
  21. #define CHIP_ID "SHTC1"
  22. #define DONE_CAL 3
  23. #define SHTC1_IOCTL_MAGIC 0xFB
  24. #define IOCTL_READ_COMPLETE _IOR(SHTC1_IOCTL_MAGIC, 0x01, unsigned short *)
  25. #define IOCTL_READ_ADC_BATT_DATA _IOR(SHTC1_IOCTL_MAGIC, 0x02, unsigned short *)
  26. #define IOCTL_READ_ADC_CHG_DATA _IOR(SHTC1_IOCTL_MAGIC, 0x03, unsigned short *)
  27. #define IOCTL_READ_THM_SHTC1_DATA _IOR(SHTC1_IOCTL_MAGIC, 0x04, short *)
  28. #define IOCTL_READ_HUM_SHTC1_DATA _IOR(SHTC1_IOCTL_MAGIC, 0x05, unsigned short *)
  29. #define IOCTL_READ_THM_BARO_DATA _IOR(SHTC1_IOCTL_MAGIC, 0x06, unsigned short *)
  30. #define IOCTL_READ_THM_GYRO_DATA _IOR(SHTC1_IOCTL_MAGIC, 0x07, unsigned short *)
  31. #if defined(CONFIG_MACH_KLTE_EUR)
  32. #define MODEL_NAME "SM-G900F"
  33. #elif defined(CONFIG_MACH_KLTE_ATT)
  34. #define MODEL_NAME "SM-G900A"
  35. #elif defined(CONFIG_MACH_KLTE_SPR)
  36. #define MODEL_NAME "SM-G900P"
  37. #elif defined(CONFIG_MACH_KLTE_TMO)
  38. #define MODEL_NAME "SM-G900T"
  39. #elif defined(CONFIG_MACH_KLTE_USC)
  40. #define MODEL_NAME "SM-G900R4"
  41. #elif defined(CONFIG_MACH_KLTE_VZW)
  42. #define MODEL_NAME "SM-G900V"
  43. #elif defined(CONFIG_MACH_KLTE_DCM)
  44. #define MODEL_NAME "SM-G900D"
  45. #elif defined(CONFIG_MACH_KACTIVELTE_DCM)
  46. #define MODEL_NAME "SM-G870D"
  47. #elif defined(CONFIG_MACH_KLTE_KDI)
  48. #define MODEL_NAME "SM-G900J"
  49. #elif defined(CONFIG_MACH_KLTE_SBM)
  50. #define MODEL_NAME "SM-G900Z"
  51. #elif defined(CONFIG_MACH_KLTE_CMCC)
  52. #define MODEL_NAME "SM-G9008V"
  53. #elif defined(CONFIG_MACH_KLTE_CMCCDUOS)
  54. #define MODEL_NAME "SM-G9008W"
  55. #elif defined(CONFIG_MACH_KLTE_CU)
  56. #define MODEL_NAME "SM-G9006V"
  57. #elif defined(CONFIG_MACH_KLTE_CUDUOS)
  58. #define MODEL_NAME "SM-G9006W"
  59. #elif defined(CONFIG_MACH_KLTE_CTC)
  60. #define MODEL_NAME "SM-G9009W"
  61. #elif defined(CONFIG_MACH_K3GDUOS_CTC)
  62. #define MODEL_NAME "SM-G9009D"
  63. #elif defined(CONFIG_MACH_KLTE_CAN)
  64. #define MODEL_NAME "SM-G900W8"
  65. #elif defined(CONFIG_MACH_KLTE_SKT)
  66. #define MODEL_NAME "SM-G900S"
  67. #elif defined(CONFIG_MACH_KLTE_KTT)
  68. #define MODEL_NAME "SM-G900K"
  69. #elif defined(CONFIG_MACH_KLTE_LGT)
  70. #define MODEL_NAME "SM-G900L"
  71. #else
  72. #define MODEL_NAME "SM-G900"
  73. #endif
  74. static struct cp_thm_adc_table temp_table_batt[] = {
  75. {636, 600}, {659, 590}, {683, 580}, {707, 570}, {730, 560},
  76. {754, 550}, {782, 540}, {810, 530}, {838, 520}, {866, 510},
  77. {894, 500}, {924, 490}, {953, 480}, {982, 470}, {1011, 460},
  78. {1040, 450}, {1077, 440}, {1114, 430}, {1152, 420}, {1189, 410},
  79. {1227, 400}, {1259, 390}, {1293, 380}, {1326, 370}, {1360, 360},
  80. {1394, 350}, {1435, 340}, {1476, 330}, {1516, 320}, {1557, 310},
  81. {1598, 300}, {1642, 290}, {1687, 280}, {1731, 270}, {1776, 260},
  82. {1820, 250}, {1866, 240}, {1913, 230}, {1961, 220}, {2008, 210},
  83. {2055, 200}, {2111, 190}, {2166, 180}, {2222, 170}, {2277, 160},
  84. {2333, 150}, {2382, 140}, {2431, 130}, {2480, 120}, {2529, 110},
  85. {2578, 100}, {2624, 90}, {2670, 80}, {2717, 70}, {2763, 60},
  86. {2810, 50}, {2851, 40}, {2892, 30}, {2933, 20}, {2973, 10},
  87. {3014, 0}, {3056, -10}, {3099, -20}, {3142, -30}, {3185, -40},
  88. {3229, -50}, {3320, -60}, {3336, -70}, {3352, -80}, {3368, -90},
  89. {3385, -100}, {3494, -110}, {3509, -120}, {3524, -130}, {3539, -140},
  90. {3554, -150}, {3614, -160}, {3629, -170}, {3644, -180},{3659, -190},
  91. {3674, -200}
  92. };
  93. static struct cp_thm_adc_table temp_table_chg[] = {
  94. {636, 600}, {659, 590}, {682, 580}, {705, 570}, {728, 560},
  95. {751, 550}, {779, 540}, {808, 530}, {837, 520}, {866, 510},
  96. {895, 500}, {924, 490}, {953, 480}, {982, 470}, {1011, 460},
  97. {1040, 450}, {1077, 440}, {1115, 430}, {1152, 420}, {1189, 410},
  98. {1227, 400}, {1260, 390}, {1293, 380}, {1326, 370}, {1360, 360},
  99. {1393, 350}, {1435, 340}, {1477, 330}, {1520, 320}, {1562, 310},
  100. {1604, 300}, {1648, 290}, {1691, 280}, {1735, 270}, {1778, 260},
  101. {1822, 250}, {1869, 240}, {1915, 230}, {1962, 220}, {2009, 210},
  102. {2056, 200}, {2110, 190}, {2164, 180}, {2219, 170}, {2273, 160},
  103. {2328, 150}, {2379, 140}, {2430, 130}, {2481, 120}, {2532, 110},
  104. {2584, 100}, {2629, 90}, {2674, 80}, {2719, 70}, {2764, 60},
  105. {2810, 50}, {2852, 40}, {2895, 30}, {2937, 20}, {2980, 10},
  106. {3022, 0}, {3063, -10}, {3103, -20}, {3144, -30}, {3184, -40},
  107. {3225, -50}, {3257, -60}, {3290, -70}, {3322, -80}, {3355, -90},
  108. {3387, -100}, {3523, -110}, {3532, -120}, {3540, -130}, {3549, -140},
  109. {3558, -150}, {3654, -160}, {3658, -170}, {3661, -180}, {3664, -190},
  110. {3667, -200}
  111. };
  112. struct qpnp_vadc_chip *ssp_vadc;
  113. static long ssp_temphumidity_ioctl(struct file *file, unsigned int cmd,
  114. unsigned long arg)
  115. {
  116. struct ssp_data *data
  117. = container_of(file->private_data,
  118. struct ssp_data, shtc1_device);
  119. void __user *argp = (void __user *)arg;
  120. int retries = 2;
  121. int length = 0;
  122. int ret = 0;
  123. if (data->bulk_buffer == NULL)
  124. return -EINVAL;
  125. length = data->bulk_buffer->len;
  126. mutex_lock(&data->bulk_temp_read_lock);
  127. switch (cmd) {
  128. case IOCTL_READ_COMPLETE: /* free */
  129. if(data->bulk_buffer) {
  130. kfree(data->bulk_buffer);
  131. data->bulk_buffer = NULL;
  132. }
  133. length = 1;
  134. break;
  135. case IOCTL_READ_ADC_BATT_DATA:
  136. while (retries--) {
  137. ret = copy_to_user(argp,
  138. data->bulk_buffer->batt,
  139. data->bulk_buffer->len*2);
  140. if (likely(!ret))
  141. break;
  142. }
  143. if (unlikely(ret)) {
  144. pr_err("[SSP] read bluk adc1 data err(%d)", ret);
  145. goto ioctl_error;
  146. }
  147. break;
  148. case IOCTL_READ_ADC_CHG_DATA:
  149. while (retries--) {
  150. ret = copy_to_user(argp,
  151. data->bulk_buffer->chg,
  152. data->bulk_buffer->len*2);
  153. if (likely(!ret))
  154. break;
  155. }
  156. if (unlikely(ret)) {
  157. pr_err("[SSP] read bluk adc1 data err(%d)", ret);
  158. goto ioctl_error;
  159. }
  160. break;
  161. case IOCTL_READ_THM_SHTC1_DATA:
  162. while (retries--) {
  163. ret = copy_to_user(argp,
  164. data->bulk_buffer->temp,
  165. data->bulk_buffer->len*2);
  166. if (likely(!ret))
  167. break;
  168. }
  169. if (unlikely(ret)) {
  170. pr_err("[SSP] read bluk adc1 data err(%d)", ret);
  171. goto ioctl_error;
  172. }
  173. break;
  174. case IOCTL_READ_HUM_SHTC1_DATA:
  175. while (retries--) {
  176. ret = copy_to_user(argp,
  177. data->bulk_buffer->humidity,
  178. data->bulk_buffer->len*2);
  179. if (likely(!ret))
  180. break;
  181. }
  182. if (unlikely(ret)) {
  183. pr_err("[SSP] read bluk adc1 data err(%d)", ret);
  184. goto ioctl_error;
  185. }
  186. break;
  187. case IOCTL_READ_THM_BARO_DATA:
  188. while (retries--) {
  189. ret = copy_to_user(argp,
  190. data->bulk_buffer->baro,
  191. data->bulk_buffer->len*2);
  192. if (likely(!ret))
  193. break;
  194. }
  195. if (unlikely(ret)) {
  196. pr_err("[SSP] read bluk adc1 data err(%d)", ret);
  197. goto ioctl_error;
  198. }
  199. break;
  200. case IOCTL_READ_THM_GYRO_DATA:
  201. while (retries--) {
  202. ret = copy_to_user(argp,
  203. data->bulk_buffer->gyro,
  204. data->bulk_buffer->len*2);
  205. if (likely(!ret))
  206. break;
  207. }
  208. if (unlikely(ret)) {
  209. pr_err("[SSP] read bluk adc1 data err(%d)", ret);
  210. goto ioctl_error;
  211. }
  212. break;
  213. default:
  214. pr_err("[SSP] temp ioctl cmd err(%d)", cmd);
  215. ret = EINVAL;
  216. goto ioctl_error;
  217. }
  218. mutex_unlock(&data->bulk_temp_read_lock);
  219. return length;
  220. ioctl_error:
  221. mutex_unlock(&data->bulk_temp_read_lock);
  222. return -ret;
  223. }
  224. static struct file_operations ssp_temphumidity_fops = {
  225. .owner = THIS_MODULE,
  226. .open = nonseekable_open,
  227. .unlocked_ioctl = ssp_temphumidity_ioctl,
  228. };
  229. static int get_cp_thm_value(struct ssp_data *data)
  230. {
  231. int err = 0;
  232. struct qpnp_vadc_result results;
  233. mutex_lock(&data->cp_temp_adc_lock);
  234. err = qpnp_vadc_read(ssp_vadc, LR_MUX6_PU1_AMUX_THM3, &results);
  235. mutex_unlock(&data->cp_temp_adc_lock);
  236. if (err) {
  237. pr_err("%s : error reading chn %d, rc = %d\n",
  238. __func__, LR_MUX6_PU2_AMUX_THM3, err);
  239. return err;
  240. }
  241. return results.adc_code;
  242. }
  243. static int get_cp_thm2_value(struct ssp_data *data)
  244. {
  245. int err = 0;
  246. struct qpnp_vadc_result results;
  247. mutex_lock(&data->cp_temp_adc_lock);
  248. err = qpnp_vadc_read(ssp_vadc, LR_MUX8_PU1_AMUX_THM4, &results);
  249. mutex_unlock(&data->cp_temp_adc_lock);
  250. if (err) {
  251. pr_err("%s : error reading chn %d, rc = %d\n",
  252. __func__, LR_MUX8_PU2_AMUX_THM4, err);
  253. return err;
  254. }
  255. return results.adc_code;
  256. }
  257. static int convert_adc_to_temp(struct ssp_data *data, unsigned int adc)
  258. {
  259. int err = 0;
  260. struct qpnp_vadc_result results;
  261. mutex_lock(&data->cp_temp_adc_lock);
  262. err = qpnp_vadc_read(ssp_vadc, LR_MUX6_PU1_AMUX_THM3, &results);
  263. mutex_unlock(&data->cp_temp_adc_lock);
  264. if (err) {
  265. pr_err("%s : error reading chn %d, rc = %d\n",
  266. __func__, LR_MUX6_PU2_AMUX_THM3, err);
  267. return err;
  268. }
  269. return results.physical * 10;
  270. }
  271. static int convert_adc_to_temp2(struct ssp_data *data, unsigned int adc)
  272. {
  273. int err = 0;
  274. struct qpnp_vadc_result results;
  275. mutex_lock(&data->cp_temp_adc_lock);
  276. err = qpnp_vadc_read(ssp_vadc, LR_MUX8_PU1_AMUX_THM4, &results);
  277. mutex_unlock(&data->cp_temp_adc_lock);
  278. if (err) {
  279. pr_err("%s : error reading chn %d, rc = %d\n",
  280. __func__, LR_MUX8_PU2_AMUX_THM4, err);
  281. return err;
  282. }
  283. return results.physical * 10;
  284. }
  285. static ssize_t temphumidity_vendor_show(struct device *dev,
  286. struct device_attribute *attr, char *buf)
  287. {
  288. return sprintf(buf, "%s\n", VENDOR);
  289. }
  290. static ssize_t temphumidity_name_show(struct device *dev,
  291. struct device_attribute *attr, char *buf)
  292. {
  293. return sprintf(buf, "%s\n", CHIP_ID);
  294. }
  295. static ssize_t engine_version_show(struct device *dev,
  296. struct device_attribute *attr, char *buf)
  297. {
  298. struct ssp_data *data = dev_get_drvdata(dev);
  299. pr_info("[SSP] %s - engine_ver = %s_%s\n",
  300. __func__, MODEL_NAME, data->comp_engine_ver);
  301. return sprintf(buf, "%s_%s\n",
  302. MODEL_NAME, data->comp_engine_ver);
  303. }
  304. static ssize_t engine_version_store(struct device *dev,
  305. struct device_attribute *attr, const char *buf, size_t size)
  306. {
  307. struct ssp_data *data = dev_get_drvdata(dev);
  308. kfree(data->comp_engine_ver);
  309. data->comp_engine_ver =
  310. kzalloc(((strlen(buf)+1) * sizeof(char)), GFP_KERNEL);
  311. strncpy(data->comp_engine_ver, buf, strlen(buf)+1);
  312. pr_info("[SSP] %s - engine_ver = %s, %s\n",
  313. __func__, data->comp_engine_ver, buf);
  314. return size;
  315. }
  316. static ssize_t engine_version2_show(struct device *dev,
  317. struct device_attribute *attr, char *buf)
  318. {
  319. struct ssp_data *data = dev_get_drvdata(dev);
  320. pr_info("[SSP] %s - engine_ver2 = %s_%s\n",
  321. __func__, MODEL_NAME, data->comp_engine_ver2);
  322. return sprintf(buf, "%s_%s\n",
  323. MODEL_NAME, data->comp_engine_ver2);
  324. }
  325. static ssize_t engine_version2_store(struct device *dev,
  326. struct device_attribute *attr, const char *buf, size_t size)
  327. {
  328. struct ssp_data *data = dev_get_drvdata(dev);
  329. kfree(data->comp_engine_ver2);
  330. data->comp_engine_ver2 =
  331. kzalloc(((strlen(buf)+1) * sizeof(char)), GFP_KERNEL);
  332. strncpy(data->comp_engine_ver2, buf, strlen(buf)+1);
  333. pr_info("[SSP] %s - engine_ver2 = %s, %s\n",
  334. __func__, data->comp_engine_ver2, buf);
  335. return size;
  336. }
  337. static ssize_t pam_adc_show(struct device *dev,
  338. struct device_attribute *attr, char *buf)
  339. {
  340. struct ssp_data *data = dev_get_drvdata(dev);
  341. int adc = 0;
  342. if (data->bSspShutdown == true) {
  343. adc = 0;
  344. goto exit;
  345. }
  346. adc = get_cp_thm_value(data);
  347. /* pr_info("[SSP] %s cp_thm = %dmV\n", __func__, adc); */
  348. exit:
  349. return sprintf(buf, "%d\n", adc);
  350. }
  351. static ssize_t pam_adc2_show(struct device *dev,
  352. struct device_attribute *attr, char *buf)
  353. {
  354. struct ssp_data *data = dev_get_drvdata(dev);
  355. int adc;
  356. if (data->bSspShutdown == true) {
  357. adc = 0;
  358. goto exit;
  359. }
  360. adc = get_cp_thm2_value(data);
  361. /* pr_info("[SSP] %s cp_thm = %dmV\n", __func__, adc); */
  362. exit:
  363. return sprintf(buf, "%d\n", adc);
  364. }
  365. static ssize_t pam_temp_show(struct device *dev,
  366. struct device_attribute *attr, char *buf)
  367. {
  368. struct ssp_data *data = dev_get_drvdata(dev);
  369. int adc, temp;
  370. adc = get_cp_thm_value(data);
  371. if (adc < 0) {
  372. pr_err("[SSP] %s - reading adc failed.(%d)\n", __func__, adc);
  373. temp = adc;
  374. } else {
  375. temp = convert_adc_to_temp(data, adc);
  376. }
  377. pr_info("[SSP] %s cp_temperature(Celsius * 10) = %d\n",
  378. __func__, temp);
  379. return sprintf(buf, "%d\n", temp);
  380. }
  381. static ssize_t pam_temp2_show(struct device *dev,
  382. struct device_attribute *attr, char *buf)
  383. {
  384. struct ssp_data *data = dev_get_drvdata(dev);
  385. int adc, temp;
  386. adc = get_cp_thm_value(data);
  387. if (adc < 0) {
  388. pr_err("[SSP] %s - reading adc failed.(%d)\n", __func__, adc);
  389. temp = adc;
  390. } else {
  391. temp = convert_adc_to_temp2(data, adc);
  392. }
  393. pr_info("[SSP] %s cp_temperature(Celsius * 10) = %d\n",
  394. __func__, temp);
  395. return sprintf(buf, "%d\n", temp);
  396. }
  397. s16 get_hub_adc(struct ssp_data *data, u32 chan) {
  398. s16 adc = -1;
  399. int iRet = 0;
  400. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  401. msg->cmd = MSG2SSP_AP_GET_THERM;
  402. msg->length = 2;
  403. msg->options = AP2HUB_READ;
  404. msg->data = chan;
  405. msg->buffer = (char *) &adc;
  406. msg->free_buffer = 0;
  407. iRet = ssp_spi_sync(data, msg, 1000);
  408. if (iRet != SUCCESS) {
  409. pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
  410. iRet = ERROR;
  411. }
  412. return adc;
  413. }
  414. static ssize_t hub_batt_adc_show(struct device *dev,
  415. struct device_attribute *attr, char *buf)
  416. {
  417. struct ssp_data *data = dev_get_drvdata(dev);
  418. static s16 prev_adc = 1865;
  419. s16 adc;
  420. if (data->bSspShutdown == true){
  421. adc = 0;
  422. goto exit;
  423. }
  424. adc = get_hub_adc(data, ADC_BATT);
  425. if (adc > 0)
  426. prev_adc = adc;
  427. else
  428. adc = prev_adc;
  429. pr_info("[SSP]: %s: adc %d\n", __func__, adc);
  430. exit:
  431. return sprintf(buf, "%d\n", adc);
  432. }
  433. static ssize_t hub_chg_adc_show(struct device *dev,
  434. struct device_attribute *attr, char *buf)
  435. {
  436. struct ssp_data *data = dev_get_drvdata(dev);
  437. static s16 prev_adc = 1630;
  438. s16 adc;
  439. if (data->bSspShutdown == true){
  440. adc = 0;
  441. goto exit;
  442. }
  443. adc = get_hub_adc(data, ADC_CHG);
  444. if (adc > 0)
  445. prev_adc = adc;
  446. else
  447. adc = prev_adc;
  448. pr_info("[SSP]: %s: adc %d\n", __func__, adc);
  449. exit:
  450. return sprintf(buf, "%d\n", adc);
  451. }
  452. static ssize_t hub_batt_temp_show(struct device *dev,
  453. struct device_attribute *attr, char *buf)
  454. {
  455. struct ssp_data *data = dev_get_drvdata(dev);
  456. int low = 0;
  457. int high = 0;
  458. int mid = 0;
  459. u8 array_size = ARRAY_SIZE(temp_table_batt);
  460. s16 adc = get_hub_adc(data, ADC_BATT);
  461. high = array_size - 1;
  462. while (low <= high) {
  463. mid = (low + high) / 2;
  464. if (temp_table_batt[mid].adc > adc)
  465. high = mid - 1;
  466. else if (temp_table_batt[mid].adc < adc)
  467. low = mid + 1;
  468. else
  469. break;
  470. }
  471. pr_info("[SSP]: %s: adc %d\n", __func__, temp_table_batt[mid].temperature);
  472. return sprintf(buf, "%d\n", temp_table_batt[mid].temperature);
  473. }
  474. static ssize_t hub_chg_temp_show(struct device *dev,
  475. struct device_attribute *attr, char *buf)
  476. {
  477. struct ssp_data *data = dev_get_drvdata(dev);
  478. int low = 0;
  479. int high = 0;
  480. int mid = 0;
  481. u8 array_size = ARRAY_SIZE(temp_table_chg);
  482. s16 adc = get_hub_adc(data, ADC_CHG);
  483. high = array_size - 1;
  484. while (low <= high) {
  485. mid = (low + high) / 2;
  486. if (temp_table_chg[mid].adc > adc)
  487. high = mid - 1;
  488. else if (temp_table_chg[mid].adc < adc)
  489. low = mid + 1;
  490. else
  491. break;
  492. }
  493. pr_info("[SSP]: %s: adc %d\n", __func__, temp_table_chg[mid].temperature);
  494. return sprintf(buf, "%d\n", temp_table_chg[mid].temperature);
  495. }
  496. static ssize_t temphumidity_crc_check(struct device *dev,
  497. struct device_attribute *attr, char *buf)
  498. {
  499. char chTempBuf = 0xff;
  500. int iRet = 0;
  501. struct ssp_data *data = dev_get_drvdata(dev);
  502. struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  503. msg->cmd = TEMPHUMIDITY_CRC_FACTORY;
  504. msg->length = 1;
  505. msg->options = AP2HUB_READ;
  506. msg->buffer = &chTempBuf;
  507. msg->free_buffer = 0;
  508. iRet = ssp_spi_sync(data, msg, 1000);
  509. if (iRet != SUCCESS) {
  510. pr_err("[SSP]: %s - Temphumidity check crc Timeout!! %d\n", __func__,
  511. iRet);
  512. goto exit;
  513. }
  514. pr_info("[SSP] : %s -Check_CRC : %d\n", __func__,
  515. chTempBuf);
  516. exit:
  517. if (chTempBuf == 1)
  518. return sprintf(buf, "%s\n", "OK");
  519. else if (chTempBuf == 2)
  520. return sprintf(buf, "%s\n", "NG_NC");
  521. else
  522. return sprintf(buf, "%s\n", "NG");
  523. }
  524. ssize_t temphumidity_send_accuracy(struct device *dev,
  525. struct device_attribute *attr, const char *buf, size_t size)
  526. {
  527. struct ssp_data *data = dev_get_drvdata(dev);
  528. u8 accuracy;
  529. if (kstrtou8(buf, 10, &accuracy) < 0) {
  530. pr_err("[SSP] %s - read buf is fail(%s)\n", __func__, buf);
  531. return size;
  532. }
  533. if (accuracy == DONE_CAL)
  534. ssp_send_cmd(data, MSG2SSP_AP_TEMPHUMIDITY_CAL_DONE, 0);
  535. pr_info("[SSP] %s - accuracy = %d\n", __func__, accuracy);
  536. return size;
  537. }
  538. static DEVICE_ATTR(name, S_IRUGO, temphumidity_name_show, NULL);
  539. static DEVICE_ATTR(vendor, S_IRUGO, temphumidity_vendor_show, NULL);
  540. static DEVICE_ATTR(engine_ver, S_IRUGO | S_IWUSR | S_IWGRP,
  541. engine_version_show, engine_version_store);
  542. static DEVICE_ATTR(engine_ver2, S_IRUGO | S_IWUSR | S_IWGRP,
  543. engine_version2_show, engine_version2_store);
  544. static DEVICE_ATTR(cp_thm, S_IRUGO, pam_adc_show, NULL);
  545. static DEVICE_ATTR(cp_thm2, S_IRUGO, pam_adc2_show, NULL);
  546. static DEVICE_ATTR(cp_temperature, S_IRUGO, pam_temp_show, NULL);
  547. static DEVICE_ATTR(cp_temperature2, S_IRUGO, pam_temp2_show, NULL);
  548. static DEVICE_ATTR(mcu_batt_adc, S_IRUGO, hub_batt_adc_show, NULL);
  549. static DEVICE_ATTR(mcu_chg_adc, S_IRUGO, hub_chg_adc_show, NULL);
  550. static DEVICE_ATTR(batt_temperature, S_IRUGO, hub_batt_temp_show, NULL);
  551. static DEVICE_ATTR(chg_temperature, S_IRUGO, hub_chg_temp_show, NULL);
  552. static DEVICE_ATTR(crc_check, S_IRUGO,
  553. temphumidity_crc_check, NULL);
  554. static DEVICE_ATTR(send_accuracy, S_IWUSR | S_IWGRP,
  555. NULL, temphumidity_send_accuracy);
  556. static struct device_attribute *temphumidity_attrs[] = {
  557. &dev_attr_name,
  558. &dev_attr_vendor,
  559. &dev_attr_engine_ver,
  560. &dev_attr_engine_ver2,
  561. &dev_attr_cp_thm,
  562. &dev_attr_cp_thm2,
  563. &dev_attr_cp_temperature,
  564. &dev_attr_cp_temperature2,
  565. &dev_attr_mcu_batt_adc,
  566. &dev_attr_mcu_chg_adc,
  567. &dev_attr_batt_temperature,
  568. &dev_attr_chg_temperature,
  569. &dev_attr_crc_check,
  570. &dev_attr_send_accuracy,
  571. NULL,
  572. };
  573. void initialize_temphumidity_factorytest(struct ssp_data *data)
  574. {
  575. int ret;
  576. sensors_register(data->temphumidity_device,
  577. data, temphumidity_attrs, "temphumidity_sensor");
  578. data->shtc1_device.minor = MISC_DYNAMIC_MINOR;
  579. data->shtc1_device.name = "shtc1_sensor";
  580. data->shtc1_device.fops = &ssp_temphumidity_fops;
  581. ret = misc_register(&data->shtc1_device);
  582. if (ret < 0) {
  583. pr_err("register temphumidity misc device err(%d)", ret);
  584. }
  585. ssp_vadc = qpnp_get_vadc(&data->spi->dev, "temphumidity_sensor");
  586. if (IS_ERR(ssp_vadc)) {
  587. ret = PTR_ERR(ssp_vadc);
  588. if (ret != -EPROBE_DEFER)
  589. pr_err("%s: Fail to get vadc %d\n", __func__, ret);
  590. }
  591. }
  592. void remove_temphumidity_factorytest(struct ssp_data *data)
  593. {
  594. if (data->comp_engine_ver != NULL)
  595. kfree(data->comp_engine_ver);
  596. if (data->comp_engine_ver2 != NULL)
  597. kfree(data->comp_engine_ver2);
  598. sensors_unregister(data->temphumidity_device, temphumidity_attrs);
  599. ssp_temphumidity_fops.unlocked_ioctl = NULL;
  600. misc_deregister(&data->shtc1_device);
  601. }