magnetic_yas532.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  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. /*************************************************************************/
  17. /* factory Sysfs */
  18. /*************************************************************************/
  19. #define VENDOR "YAMAHA"
  20. #define CHIP_ID "YAS532"
  21. #define MAG_HW_OFFSET_FILE_PATH "/efs/hw_offset"
  22. int mag_open_hwoffset(struct ssp_data *data)
  23. {
  24. int iRet = 0;
  25. mm_segment_t old_fs;
  26. struct file *cal_filp = NULL;
  27. old_fs = get_fs();
  28. set_fs(KERNEL_DS);
  29. cal_filp = filp_open(MAG_HW_OFFSET_FILE_PATH, O_RDONLY, 0666);
  30. if (IS_ERR(cal_filp)) {
  31. pr_err("[SSP] %s: filp_open failed\n", __func__);
  32. set_fs(old_fs);
  33. iRet = PTR_ERR(cal_filp);
  34. data->magoffset.x = 0;
  35. data->magoffset.y = 0;
  36. data->magoffset.z = 0;
  37. return iRet;
  38. }
  39. iRet = cal_filp->f_op->read(cal_filp, (char *)&data->magoffset,
  40. 3 * sizeof(char), &cal_filp->f_pos);
  41. if (iRet != 3 * sizeof(char)) {
  42. pr_err("[SSP] %s: filp_open failed\n", __func__);
  43. iRet = -EIO;
  44. }
  45. filp_close(cal_filp, current->files);
  46. set_fs(old_fs);
  47. ssp_dbg("[SSP]: %s: %d, %d, %d\n", __func__,
  48. (s8)data->magoffset.x,
  49. (s8)data->magoffset.y,
  50. (s8)data->magoffset.z);
  51. if ((data->magoffset.x == 0) && (data->magoffset.y == 0)
  52. && (data->magoffset.z == 0))
  53. return ERROR;
  54. return iRet;
  55. }
  56. int mag_store_hwoffset(struct ssp_data *data)
  57. {
  58. int iRet = 0;
  59. struct file *cal_filp = NULL;
  60. mm_segment_t old_fs;
  61. if (get_hw_offset(data) < 0) {
  62. pr_err("[SSP]: %s - get_hw_offset failed\n", __func__);
  63. return ERROR;
  64. } else {
  65. old_fs = get_fs();
  66. set_fs(KERNEL_DS);
  67. cal_filp = filp_open(MAG_HW_OFFSET_FILE_PATH,
  68. O_CREAT | O_TRUNC | O_WRONLY, 0666);
  69. if (IS_ERR(cal_filp)) {
  70. pr_err("[SSP]: %s - Can't open hw_offset file\n",
  71. __func__);
  72. set_fs(old_fs);
  73. iRet = PTR_ERR(cal_filp);
  74. return iRet;
  75. }
  76. iRet = cal_filp->f_op->write(cal_filp,
  77. (char *)&data->magoffset,
  78. 3 * sizeof(char), &cal_filp->f_pos);
  79. if (iRet != 3 * sizeof(char)) {
  80. pr_err("[SSP]: %s - Can't write the hw_offset"
  81. " to file\n", __func__);
  82. iRet = -EIO;
  83. }
  84. filp_close(cal_filp, current->files);
  85. set_fs(old_fs);
  86. return iRet;
  87. }
  88. }
  89. int set_hw_offset(struct ssp_data *data)
  90. {
  91. char chTxBuf[4] = { 0, };
  92. char chRxBuf = 0;
  93. int iRet = 0;
  94. if (waiting_wakeup_mcu(data) < 0 ||
  95. data->fw_dl_state == FW_DL_STATE_DOWNLOADING) {
  96. pr_info("[SSP] : %s, skip DL state = %d\n", __func__,
  97. data->fw_dl_state);
  98. return FAIL;
  99. }
  100. chTxBuf[0] = MSG2SSP_AP_SET_MAGNETIC_HWOFFSET;
  101. chTxBuf[1] = data->magoffset.x;
  102. chTxBuf[2] = data->magoffset.y;
  103. chTxBuf[3] = data->magoffset.z;
  104. iRet = ssp_i2c_read(data, chTxBuf, 4, &chRxBuf, 1, DEFAULT_RETRIES);
  105. if ((chRxBuf != MSG_ACK) || (iRet != SUCCESS)) {
  106. pr_err("[SSP]: %s - i2c fail %d, %d\n",
  107. __func__, iRet, chRxBuf);
  108. iRet = ERROR;
  109. }
  110. pr_info("[SSP]: %s: x: %d, y: %d, z: %d\n", __func__,
  111. (s8)chTxBuf[1], (s8)chTxBuf[2], (s8)chTxBuf[3]);
  112. return iRet;
  113. }
  114. int get_hw_offset(struct ssp_data *data)
  115. {
  116. char chTxBuf = 0;
  117. char chRxBuf[3] = { 0, };
  118. int iRet = 0;
  119. if (waiting_wakeup_mcu(data) < 0)
  120. return ERROR;
  121. chTxBuf = MSG2SSP_AP_GET_MAGNETIC_HWOFFSET;
  122. data->magoffset.x = 0;
  123. data->magoffset.y = 0;
  124. data->magoffset.z = 0;
  125. iRet = ssp_i2c_read(data, &chTxBuf, 1, chRxBuf, 3, DEFAULT_RETRIES);
  126. if (iRet != SUCCESS) {
  127. pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
  128. iRet = ERROR;
  129. }
  130. data->magoffset.x = chRxBuf[0];
  131. data->magoffset.y = chRxBuf[1];
  132. data->magoffset.z = chRxBuf[2];
  133. pr_info("[SSP]: %s: x: %d, y: %d, z: %d\n", __func__,
  134. (s8)data->magoffset.x,
  135. (s8)data->magoffset.y,
  136. (s8)data->magoffset.z);
  137. return iRet;
  138. }
  139. static ssize_t magnetic_vendor_show(struct device *dev,
  140. struct device_attribute *attr, char *buf)
  141. {
  142. return sprintf(buf, "%s\n", VENDOR);
  143. }
  144. static ssize_t magnetic_name_show(struct device *dev,
  145. struct device_attribute *attr, char *buf)
  146. {
  147. return sprintf(buf, "%s\n", CHIP_ID);
  148. }
  149. static int check_rawdata_spec(struct ssp_data *data)
  150. {
  151. if ((data->buf[GEOMAGNETIC_SENSOR].x == 0) &&
  152. (data->buf[GEOMAGNETIC_SENSOR].y == 0) &&
  153. (data->buf[GEOMAGNETIC_SENSOR].z == 0))
  154. return FAIL;
  155. else
  156. return SUCCESS;
  157. }
  158. static ssize_t raw_data_show(struct device *dev,
  159. struct device_attribute *attr, char *buf)
  160. {
  161. struct ssp_data *data = dev_get_drvdata(dev);
  162. pr_info("[SSP] %s - %d,%d,%d\n", __func__,
  163. data->buf[GEOMAGNETIC_SENSOR].x,
  164. data->buf[GEOMAGNETIC_SENSOR].y,
  165. data->buf[GEOMAGNETIC_SENSOR].z);
  166. if (data->bGeomagneticRawEnabled == false) {
  167. data->buf[GEOMAGNETIC_SENSOR].x = -1;
  168. data->buf[GEOMAGNETIC_SENSOR].y = -1;
  169. data->buf[GEOMAGNETIC_SENSOR].z = -1;
  170. } else {
  171. if (data->buf[GEOMAGNETIC_SENSOR].x > 18000)
  172. data->buf[GEOMAGNETIC_SENSOR].x = 18000;
  173. else if (data->buf[GEOMAGNETIC_SENSOR].x < -18000)
  174. data->buf[GEOMAGNETIC_SENSOR].x = -18000;
  175. if (data->buf[GEOMAGNETIC_SENSOR].y > 18000)
  176. data->buf[GEOMAGNETIC_SENSOR].y = 18000;
  177. else if (data->buf[GEOMAGNETIC_SENSOR].y < -18000)
  178. data->buf[GEOMAGNETIC_SENSOR].y = -18000;
  179. if (data->buf[GEOMAGNETIC_SENSOR].z > 18000)
  180. data->buf[GEOMAGNETIC_SENSOR].z = 18000;
  181. else if (data->buf[GEOMAGNETIC_SENSOR].z < -18000)
  182. data->buf[GEOMAGNETIC_SENSOR].z = -18000;
  183. }
  184. return snprintf(buf, PAGE_SIZE, "%d,%d,%d\n",
  185. data->buf[GEOMAGNETIC_SENSOR].x,
  186. data->buf[GEOMAGNETIC_SENSOR].y,
  187. data->buf[GEOMAGNETIC_SENSOR].z);
  188. }
  189. static ssize_t raw_data_store(struct device *dev,
  190. struct device_attribute *attr, const char *buf, size_t size)
  191. {
  192. char chTempbuf[2] = { 1, 20};
  193. int iRet;
  194. int64_t dEnable;
  195. int iRetries = 50;
  196. struct ssp_data *data = dev_get_drvdata(dev);
  197. iRet = kstrtoll(buf, 10, &dEnable);
  198. if (iRet < 0)
  199. return iRet;
  200. if (dEnable) {
  201. data->buf[GEOMAGNETIC_SENSOR].x = 0;
  202. data->buf[GEOMAGNETIC_SENSOR].y = 0;
  203. data->buf[GEOMAGNETIC_SENSOR].z = 0;
  204. send_instruction(data, ADD_SENSOR, GEOMAGNETIC_RAW,
  205. chTempbuf, 2);
  206. do {
  207. msleep(20);
  208. if (check_rawdata_spec(data) == SUCCESS)
  209. break;
  210. } while (--iRetries);
  211. if (iRetries > 0) {
  212. pr_info("[SSP] %s - success, %d\n", __func__, iRetries);
  213. data->bGeomagneticRawEnabled = true;
  214. } else {
  215. pr_err("[SSP] %s - wait timeout, %d\n", __func__,
  216. iRetries);
  217. data->bGeomagneticRawEnabled = false;
  218. }
  219. } else {
  220. send_instruction(data, REMOVE_SENSOR, GEOMAGNETIC_RAW,
  221. chTempbuf, 2);
  222. data->bGeomagneticRawEnabled = false;
  223. }
  224. return size;
  225. }
  226. static int check_data_spec(struct ssp_data *data)
  227. {
  228. if ((data->buf[GEOMAGNETIC_SENSOR].x == 0) &&
  229. (data->buf[GEOMAGNETIC_SENSOR].y == 0) &&
  230. (data->buf[GEOMAGNETIC_SENSOR].z == 0))
  231. return FAIL;
  232. else if ((data->buf[GEOMAGNETIC_SENSOR].x > 6500) ||
  233. (data->buf[GEOMAGNETIC_SENSOR].x < -6500) ||
  234. (data->buf[GEOMAGNETIC_SENSOR].y > 6500) ||
  235. (data->buf[GEOMAGNETIC_SENSOR].y < -6500) ||
  236. (data->buf[GEOMAGNETIC_SENSOR].z > 6500) ||
  237. (data->buf[GEOMAGNETIC_SENSOR].z < -6500))
  238. return FAIL;
  239. else
  240. return SUCCESS;
  241. }
  242. static ssize_t adc_data_read(struct device *dev,
  243. struct device_attribute *attr, char *buf)
  244. {
  245. bool bSuccess = false;
  246. u8 chTempbuf[2] = {1, 20};
  247. s16 iSensorBuf[3] = {0, };
  248. int iRetries = 10;
  249. struct ssp_data *data = dev_get_drvdata(dev);
  250. data->buf[GEOMAGNETIC_SENSOR].x = 0;
  251. data->buf[GEOMAGNETIC_SENSOR].y = 0;
  252. data->buf[GEOMAGNETIC_SENSOR].z = 0;
  253. if (!(atomic_read(&data->aSensorEnable) & (1 << GEOMAGNETIC_SENSOR)))
  254. send_instruction(data, ADD_SENSOR, GEOMAGNETIC_SENSOR,
  255. chTempbuf, 2);
  256. do {
  257. msleep(60);
  258. if (check_data_spec(data) == SUCCESS)
  259. break;
  260. } while (--iRetries);
  261. if (iRetries > 0)
  262. bSuccess = true;
  263. iSensorBuf[0] = data->buf[GEOMAGNETIC_SENSOR].x;
  264. iSensorBuf[1] = data->buf[GEOMAGNETIC_SENSOR].y;
  265. iSensorBuf[2] = data->buf[GEOMAGNETIC_SENSOR].z;
  266. if (!(atomic_read(&data->aSensorEnable) & (1 << GEOMAGNETIC_SENSOR)))
  267. send_instruction(data, REMOVE_SENSOR, GEOMAGNETIC_SENSOR,
  268. chTempbuf, 2);
  269. pr_info("[SSP]: %s - x = %d, y = %d, z = %d\n", __func__,
  270. iSensorBuf[0], iSensorBuf[1], iSensorBuf[2]);
  271. return sprintf(buf, "%s,%d,%d,%d\n", (bSuccess ? "OK" : "NG"),
  272. iSensorBuf[0], iSensorBuf[1], iSensorBuf[2]);
  273. }
  274. static ssize_t magnetic_get_selftest(struct device *dev,
  275. struct device_attribute *attr, char *buf)
  276. {
  277. char chTempBuf[2] = { 0, 10 };
  278. int iDelayCnt = 0, iRet = 0, iTimeoutReties = 0;
  279. s8 id = 0, x = 0, y1 = 0, y2 = 0, dir = 0;
  280. s16 sx = 0, sy = 0, ohx = 0, ohy = 0, ohz = 0;
  281. s8 err[7] = {-1, };
  282. struct ssp_data *data = dev_get_drvdata(dev);
  283. reties:
  284. iDelayCnt = 0;
  285. data->uFactorydataReady = 0;
  286. memset(data->uFactorydata, 0, sizeof(char) * FACTORY_DATA_MAX);
  287. iRet = send_instruction(data, FACTORY_MODE, GEOMAGNETIC_FACTORY,
  288. chTempBuf, 2);
  289. while (!(data->uFactorydataReady & (1 << GEOMAGNETIC_FACTORY))
  290. && (iDelayCnt++ < 50)
  291. && (iRet == SUCCESS))
  292. msleep(20);
  293. if ((iDelayCnt >= 50) || (iRet != SUCCESS)) {
  294. pr_err("[SSP]: %s - Magnetic Selftest Timeout!! %d\n",
  295. __func__, iRet);
  296. if (iTimeoutReties++ < 3)
  297. goto reties;
  298. else
  299. goto exit;
  300. }
  301. mdelay(5);
  302. id = (s8)(data->uFactorydata[0]);
  303. err[0] = (s8)(data->uFactorydata[1]);
  304. err[1] = (s8)(data->uFactorydata[2]);
  305. err[2] = (s8)(data->uFactorydata[3]);
  306. x = (s8)(data->uFactorydata[4]);
  307. y1 = (s8)(data->uFactorydata[5]);
  308. y2 = (s8)(data->uFactorydata[6]);
  309. err[3] = (s8)(data->uFactorydata[7]);
  310. dir = (s8)(data->uFactorydata[8]);
  311. err[4] = (s8)(data->uFactorydata[9]);
  312. ohx = (s16)((data->uFactorydata[10] << 8) + data->uFactorydata[11]);
  313. ohy = (s16)((data->uFactorydata[12] << 8) + data->uFactorydata[13]);
  314. ohz = (s16)((data->uFactorydata[14] << 8) + data->uFactorydata[15]);
  315. err[6] = (s8)(data->uFactorydata[16]);
  316. sx = (s16)((data->uFactorydata[17] << 8) + data->uFactorydata[18]);
  317. sy = (s16)((data->uFactorydata[19] << 8) + data->uFactorydata[20]);
  318. err[5] = (s8)(data->uFactorydata[21]);
  319. if (unlikely(id != 0x2))
  320. err[0] = -1;
  321. if (unlikely(x < -30 || x > 30))
  322. err[3] = -1;
  323. if (unlikely(y1 < -30 || y1 > 30))
  324. err[3] = -1;
  325. if (unlikely(y2 < -30 || y2 > 30))
  326. err[3] = -1;
  327. if (unlikely(sx < 17 || sy < 22))
  328. err[5] = -1;
  329. if (unlikely(ohx < -600 || ohx > 600))
  330. err[6] = -1;
  331. if (unlikely(ohy < -600 || ohy > 600))
  332. err[6] = -1;
  333. if (unlikely(ohz < -600 || ohz > 600))
  334. err[6] = -1;
  335. pr_info("[SSP] %s\n"
  336. "[SSP] Test1 - err = %d, id = %d\n"
  337. "[SSP] Test3 - err = %d\n"
  338. "[SSP] Test4 - err = %d, offset = %d,%d,%d\n"
  339. "[SSP] Test5 - err = %d, direction = %d\n"
  340. "[SSP] Test6 - err = %d, sensitivity = %d,%d\n"
  341. "[SSP] Test7 - err = %d, offset = %d,%d,%d\n"
  342. "[SSP] Test2 - err = %d\n",
  343. __func__, err[0], id, err[2], err[3], x, y1, y2, err[4], dir,
  344. err[5], sx, sy, err[6], ohx, ohy, ohz, err[1]);
  345. exit:
  346. return sprintf(buf,
  347. "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
  348. err[0], id, err[2], err[3], x, y1, y2, err[4], dir,
  349. err[5], sx, sy, err[6], ohx, ohy, ohz, err[1]);
  350. }
  351. static ssize_t hw_offset_show(struct device *dev,
  352. struct device_attribute *attr, char *buf)
  353. {
  354. struct ssp_data *data = dev_get_drvdata(dev);
  355. mag_open_hwoffset(data);
  356. pr_info("[SSP] %s: %d %d %d\n", __func__,
  357. (s8)data->magoffset.x,
  358. (s8)data->magoffset.y,
  359. (s8)data->magoffset.z);
  360. return sprintf(buf, "%d %d %d\n",
  361. (s8)data->magoffset.x,
  362. (s8)data->magoffset.y,
  363. (s8)data->magoffset.z);
  364. }
  365. static DEVICE_ATTR(name, S_IRUGO, magnetic_name_show, NULL);
  366. static DEVICE_ATTR(vendor, S_IRUGO, magnetic_vendor_show, NULL);
  367. static DEVICE_ATTR(raw_data, S_IRUGO | S_IWUSR | S_IWGRP,
  368. raw_data_show, raw_data_store);
  369. static DEVICE_ATTR(adc, S_IRUGO, adc_data_read, NULL);
  370. static DEVICE_ATTR(selftest, S_IRUGO, magnetic_get_selftest, NULL);
  371. static DEVICE_ATTR(hw_offset, S_IRUGO, hw_offset_show, NULL);
  372. static struct device_attribute *mag_attrs[] = {
  373. &dev_attr_name,
  374. &dev_attr_vendor,
  375. &dev_attr_adc,
  376. &dev_attr_raw_data,
  377. &dev_attr_selftest,
  378. &dev_attr_hw_offset,
  379. NULL,
  380. };
  381. void initialize_magnetic_factorytest(struct ssp_data *data)
  382. {
  383. sensors_register(data->mag_device, data, mag_attrs, "magnetic_sensor");
  384. }
  385. void remove_magnetic_factorytest(struct ssp_data *data)
  386. {
  387. sensors_unregister(data->mag_device, mag_attrs);
  388. }