gyro_mpu6500.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  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 <linux/kernel.h>
  16. #include "../ssp.h"
  17. /*************************************************************************/
  18. /* factory Sysfs */
  19. /*************************************************************************/
  20. #define VENDOR "INVENSENSE"
  21. #define CHIP_ID "MPU6500"
  22. #define VENDOR_K330 "STM"
  23. #define CHIP_ID_K330 "K330"
  24. #define CALIBRATION_FILE_PATH "/efs/gyro_cal_data"
  25. #define VERBOSE_OUT 1
  26. #define CALIBRATION_DATA_AMOUNT 20
  27. #define DEF_GYRO_FULLSCALE 2000
  28. #define DEF_GYRO_SENS (32768 / DEF_GYRO_FULLSCALE)
  29. #define DEF_BIAS_LSB_THRESH_SELF (20 * DEF_GYRO_SENS)
  30. #define DEF_BIAS_LSB_THRESH_SELF_6500 (30 * DEF_GYRO_SENS)
  31. #define DEF_RMS_LSB_TH_SELF (5 * DEF_GYRO_SENS)
  32. #define DEF_RMS_THRESH ((DEF_RMS_LSB_TH_SELF) * (DEF_RMS_LSB_TH_SELF))
  33. #define DEF_SCALE_FOR_FLOAT (1000)
  34. #define DEF_RMS_SCALE_FOR_RMS (10000)
  35. #define DEF_SQRT_SCALE_FOR_RMS (100)
  36. static ssize_t gyro_vendor_show(struct device *dev,
  37. struct device_attribute *attr, char *buf)
  38. {
  39. struct ssp_data *data = dev_get_drvdata(dev);
  40. if (data->sns_combination == STM_K330_AG)
  41. return sprintf(buf, "%s\n", VENDOR_K330);
  42. else
  43. return sprintf(buf, "%s\n", VENDOR);
  44. }
  45. static ssize_t gyro_name_show(struct device *dev,
  46. struct device_attribute *attr, char *buf)
  47. {
  48. struct ssp_data *data = dev_get_drvdata(dev);
  49. if (data->sns_combination == STM_K330_AG)
  50. return sprintf(buf, "%s\n", CHIP_ID_K330);
  51. else
  52. return sprintf(buf, "%s\n", CHIP_ID);
  53. }
  54. int gyro_open_calibration(struct ssp_data *data)
  55. {
  56. int iRet = 0;
  57. mm_segment_t old_fs;
  58. struct file *cal_filp = NULL;
  59. old_fs = get_fs();
  60. set_fs(KERNEL_DS);
  61. cal_filp = filp_open(CALIBRATION_FILE_PATH, O_RDONLY, 0666);
  62. if (IS_ERR(cal_filp)) {
  63. set_fs(old_fs);
  64. iRet = PTR_ERR(cal_filp);
  65. data->gyrocal.x = 0;
  66. data->gyrocal.y = 0;
  67. data->gyrocal.z = 0;
  68. return iRet;
  69. }
  70. iRet = cal_filp->f_op->read(cal_filp, (char *)&data->gyrocal,
  71. 3 * sizeof(int), &cal_filp->f_pos);
  72. if (iRet != 3 * sizeof(int))
  73. iRet = -EIO;
  74. filp_close(cal_filp, current->files);
  75. set_fs(old_fs);
  76. ssp_dbg("[SSP]: open gyro calibration %d, %d, %d\n",
  77. data->gyrocal.x, data->gyrocal.y, data->gyrocal.z);
  78. return iRet;
  79. }
  80. static int save_gyro_caldata(struct ssp_data *data, s16 *iCalData)
  81. {
  82. int iRet = 0;
  83. struct file *cal_filp = NULL;
  84. mm_segment_t old_fs;
  85. data->gyrocal.x = iCalData[0];
  86. data->gyrocal.y = iCalData[1];
  87. data->gyrocal.z = iCalData[2];
  88. ssp_dbg("[SSP]: do gyro calibrate %d, %d, %d\n",
  89. data->gyrocal.x, data->gyrocal.y, data->gyrocal.z);
  90. old_fs = get_fs();
  91. set_fs(KERNEL_DS);
  92. cal_filp = filp_open(CALIBRATION_FILE_PATH,
  93. O_CREAT | O_TRUNC | O_WRONLY, 0666);
  94. if (IS_ERR(cal_filp)) {
  95. pr_err("[SSP]: %s - Can't open calibration file\n", __func__);
  96. set_fs(old_fs);
  97. iRet = PTR_ERR(cal_filp);
  98. return -EIO;
  99. }
  100. iRet = cal_filp->f_op->write(cal_filp, (char *)&data->gyrocal,
  101. 3 * sizeof(int), &cal_filp->f_pos);
  102. if (iRet != 3 * sizeof(int)) {
  103. pr_err("[SSP]: %s - Can't write gyro cal to file\n", __func__);
  104. iRet = -EIO;
  105. }
  106. filp_close(cal_filp, current->files);
  107. set_fs(old_fs);
  108. return iRet;
  109. }
  110. static ssize_t gyro_power_off(struct device *dev,
  111. struct device_attribute *attr, char *buf)
  112. {
  113. ssp_dbg("[SSP]: %s\n", __func__);
  114. return sprintf(buf, "%d\n", 1);
  115. }
  116. static ssize_t gyro_power_on(struct device *dev,
  117. struct device_attribute *attr, char *buf)
  118. {
  119. ssp_dbg("[SSP]: %s\n", __func__);
  120. return sprintf(buf, "%d\n", 1);
  121. }
  122. short mpu6500_gyro_get_temp(struct ssp_data *data)
  123. {
  124. char chTempBuf[2] = { 0, 10};
  125. unsigned char reg[2];
  126. short temperature = 0;
  127. int iDelayCnt = 0, iRet = 0;
  128. data->uFactorydataReady = 0;
  129. memset(data->uFactorydata, 0, sizeof(char) * FACTORY_DATA_MAX);
  130. iRet = send_instruction(data, FACTORY_MODE, GYROSCOPE_TEMP_FACTORY,
  131. chTempBuf, 2);
  132. while (!(data->uFactorydataReady & (1 << GYROSCOPE_TEMP_FACTORY))
  133. && (iDelayCnt++ < 150)
  134. && (iRet == SUCCESS))
  135. msleep(20);
  136. if ((iDelayCnt >= 150) || (iRet != SUCCESS)) {
  137. pr_err("[SSP]: %s - Gyro Temp Timeout!!\n", __func__);
  138. goto exit;
  139. }
  140. reg[0] = data->uFactorydata[1];
  141. reg[1] = data->uFactorydata[0];
  142. temperature = (short) (((reg[0]) << 8) | reg[1]);
  143. temperature = (((temperature + 521) / 340) + 35);
  144. ssp_dbg("[SSP]: %s - %d\n", __func__, temperature);
  145. exit:
  146. return temperature;
  147. }
  148. char k330_gyro_get_temp(struct ssp_data *data)
  149. {
  150. char chTempBuf[2] = { 0, 10}, chTemp = 0;
  151. int iDelayCnt = 0, iRet = 0;
  152. if (!(data->uSensorState & (1 << GYROSCOPE_SENSOR)))
  153. goto exit;
  154. data->uFactorydataReady = 0;
  155. memset(data->uFactorydata, 0, sizeof(char) * FACTORY_DATA_MAX);
  156. iRet = send_instruction(data, FACTORY_MODE, GYROSCOPE_TEMP_FACTORY,
  157. chTempBuf, 2);
  158. while (!(data->uFactorydataReady & (1 << GYROSCOPE_TEMP_FACTORY))
  159. && (iDelayCnt++ < 150)
  160. && (iRet == SUCCESS))
  161. msleep(20);
  162. if ((iDelayCnt >= 150) || (iRet != SUCCESS)) {
  163. pr_err("[SSP]: %s - Gyro Temp Timeout!!\n", __func__);
  164. goto exit;
  165. }
  166. mdelay(5);
  167. chTemp = (char)data->uFactorydata[0];
  168. ssp_dbg("[SSP]: %s - %d\n", __func__, chTemp);
  169. exit:
  170. return chTemp;
  171. }
  172. static ssize_t gyro_get_temp(struct device *dev,
  173. struct device_attribute *attr, char *buf)
  174. {
  175. short temperature = 0;
  176. struct ssp_data *data = dev_get_drvdata(dev);
  177. if (data->sns_combination == STM_K330_AG)
  178. temperature = (short)k330_gyro_get_temp(data);
  179. else
  180. temperature = mpu6500_gyro_get_temp(data);
  181. return sprintf(buf, "%d\n", temperature);
  182. }
  183. u32 mpu6050_selftest_sqrt(u32 sqsum)
  184. {
  185. u32 sq_rt;
  186. u32 g0, g1, g2, g3, g4;
  187. u32 seed;
  188. u32 next;
  189. u32 step;
  190. g4 = sqsum / 100000000;
  191. g3 = (sqsum - g4 * 100000000) / 1000000;
  192. g2 = (sqsum - g4 * 100000000 - g3 * 1000000) / 10000;
  193. g1 = (sqsum - g4 * 100000000 - g3 * 1000000 - g2 * 10000) / 100;
  194. g0 = (sqsum - g4 * 100000000 - g3 * 1000000 - g2 * 10000 - g1 * 100);
  195. next = g4;
  196. step = 0;
  197. seed = 0;
  198. while (((seed + 1) * (step + 1)) <= next) {
  199. step++;
  200. seed++;
  201. }
  202. sq_rt = seed * 10000;
  203. next = (next - (seed * step)) * 100 + g3;
  204. step = 0;
  205. seed = 2 * seed * 10;
  206. while (((seed + 1) * (step + 1)) <= next) {
  207. step++;
  208. seed++;
  209. }
  210. sq_rt = sq_rt + step * 1000;
  211. next = (next - seed * step) * 100 + g2;
  212. seed = (seed + step) * 10;
  213. step = 0;
  214. while (((seed + 1) * (step + 1)) <= next) {
  215. step++;
  216. seed++;
  217. }
  218. sq_rt = sq_rt + step * 100;
  219. next = (next - seed * step) * 100 + g1;
  220. seed = (seed + step) * 10;
  221. step = 0;
  222. while (((seed + 1) * (step + 1)) <= next) {
  223. step++;
  224. seed++;
  225. }
  226. sq_rt = sq_rt + step * 10;
  227. next = (next - seed * step) * 100 + g0;
  228. seed = (seed + step) * 10;
  229. step = 0;
  230. while (((seed + 1) * (step + 1)) <= next) {
  231. step++;
  232. seed++;
  233. }
  234. sq_rt = sq_rt + step;
  235. return sq_rt;
  236. }
  237. ssize_t k330_gyro_selftest(char *buf, struct ssp_data *data)
  238. {
  239. char chTempBuf[2] = { 3, 200};
  240. u8 uFifoPass = 2;
  241. u8 uBypassPass = 2;
  242. u8 uCalPass = 0;
  243. u8 dummy[2] = {0,};
  244. s16 iNOST[3] = {0,}, iST[3] = {0,}, iCalData[3] = {0,};
  245. s16 iZeroRateData[3] = {0,}, fifo_data[4] = {0,};
  246. int iDelayCnt = 0, iRet = 0;
  247. data->uFactorydataReady = 0;
  248. memset(data->uFactorydata, 0, sizeof(char) * FACTORY_DATA_MAX);
  249. iRet = send_instruction(data, FACTORY_MODE, GYROSCOPE_FACTORY,
  250. chTempBuf, 2);
  251. while (!(data->uFactorydataReady & (1 << GYROSCOPE_FACTORY))
  252. && (iDelayCnt++ < 250)
  253. && (iRet == SUCCESS))
  254. msleep(20);
  255. if ((iDelayCnt >= 250) || (iRet != SUCCESS)) {
  256. pr_err("[SSP]: %s - Gyro Selftest Timeout!!\n", __func__);
  257. goto exit;
  258. }
  259. mdelay(5);
  260. iNOST[0] = (s16)((data->uFactorydata[0] << 8) + data->uFactorydata[1]);
  261. iNOST[1] = (s16)((data->uFactorydata[2] << 8) + data->uFactorydata[3]);
  262. iNOST[2] = (s16)((data->uFactorydata[4] << 8) + data->uFactorydata[5]);
  263. iST[0] = (s16)((data->uFactorydata[6] << 8) + data->uFactorydata[7]);
  264. iST[1] = (s16)((data->uFactorydata[8] << 8) + data->uFactorydata[9]);
  265. iST[2] = (s16)((data->uFactorydata[10] << 8) + data->uFactorydata[11]);
  266. iCalData[0] =
  267. (s16)((data->uFactorydata[12] << 8) + data->uFactorydata[13]);
  268. iCalData[1] =
  269. (s16)((data->uFactorydata[14] << 8) + data->uFactorydata[15]);
  270. iCalData[2] =
  271. (s16)((data->uFactorydata[16] << 8) + data->uFactorydata[17]);
  272. iZeroRateData[0] =
  273. (s16)((data->uFactorydata[18] << 8) + data->uFactorydata[19]);
  274. iZeroRateData[1] =
  275. (s16)((data->uFactorydata[20] << 8) + data->uFactorydata[21]);
  276. iZeroRateData[2] =
  277. (s16)((data->uFactorydata[22] << 8) + data->uFactorydata[23]);
  278. fifo_data[0] = data->uFactorydata[24];
  279. fifo_data[1] =
  280. (s16)((data->uFactorydata[25] << 8) + data->uFactorydata[26]);
  281. fifo_data[2] =
  282. (s16)((data->uFactorydata[27] << 8) + data->uFactorydata[28]);
  283. fifo_data[3] =
  284. (s16)((data->uFactorydata[29] << 8) + data->uFactorydata[30]);
  285. uCalPass = data->uFactorydata[31];
  286. uFifoPass = data->uFactorydata[32];
  287. uBypassPass = data->uFactorydata[33];
  288. dummy[0] = data->uFactorydata[34];
  289. dummy[1] = data->uFactorydata[35];
  290. pr_info("[SSP] %s dummy = 0x%X, 0x%X\n", __func__, dummy[0], dummy[1]);
  291. if (uFifoPass && uBypassPass && uCalPass)
  292. save_gyro_caldata(data, iCalData);
  293. exit:
  294. ssp_dbg("[SSP]: %s - %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
  295. __func__, iNOST[0], iNOST[1], iNOST[2], iST[0], iST[1], iST[2],
  296. iZeroRateData[0], iZeroRateData[1], iZeroRateData[2],
  297. fifo_data[0], fifo_data[1], fifo_data[2], fifo_data[3],
  298. uFifoPass & uBypassPass & uCalPass, uFifoPass, uCalPass);
  299. return sprintf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
  300. iNOST[0], iNOST[1], iNOST[2], iST[0], iST[1], iST[2],
  301. iZeroRateData[0], iZeroRateData[1], iZeroRateData[2],
  302. fifo_data[0], fifo_data[1], fifo_data[2], fifo_data[3],
  303. uFifoPass & uBypassPass & uCalPass, uFifoPass, uCalPass);
  304. }
  305. ssize_t mpu6500_gyro_selftest(char *buf, struct ssp_data *data)
  306. {
  307. char chTempBuf[2] = { 3, 200};
  308. u8 initialized = 0;
  309. s8 hw_result = 0;
  310. int i = 0, j = 0, total_count = 0, ret_val = 0;
  311. long avg[3] = {0,}, rms[3] = {0,};
  312. int gyro_bias[3] = {0,}, gyro_rms[3] = {0,};
  313. s16 shift_ratio[3] = {0,};
  314. s16 iCalData[3] = {0,};
  315. char a_name[3][2] = { "X", "Y", "Z" };
  316. int iDelayCnt = 0, iRet = 0;
  317. int dps_rms[3] = { 0, };
  318. u32 temp = 0;
  319. int bias_thresh = DEF_BIAS_LSB_THRESH_SELF_6500;
  320. data->uFactorydataReady = 0;
  321. memset(data->uFactorydata, 0, sizeof(char) * FACTORY_DATA_MAX);
  322. iRet = send_instruction(data, FACTORY_MODE, GYROSCOPE_FACTORY,
  323. chTempBuf, 2);
  324. while (!(data->uFactorydataReady & (1 << GYROSCOPE_FACTORY))
  325. && (iDelayCnt++ < 150)
  326. && (iRet == SUCCESS))
  327. msleep(20);
  328. if ((iDelayCnt >= 150) || (iRet != SUCCESS)) {
  329. pr_err("[SSP]: %s - Gyro Selftest Timeout!!\n", __func__);
  330. goto exit;
  331. }
  332. initialized = data->uFactorydata[0];
  333. shift_ratio[0] = (s16)((data->uFactorydata[2] << 8) +
  334. data->uFactorydata[1]);
  335. shift_ratio[1] = (s16)((data->uFactorydata[4] << 8) +
  336. data->uFactorydata[3]);
  337. shift_ratio[2] = (s16)((data->uFactorydata[6] << 8) +
  338. data->uFactorydata[5]);
  339. hw_result = (s8)data->uFactorydata[7];
  340. total_count = (int)((data->uFactorydata[11] << 24) +
  341. (data->uFactorydata[10] << 16) +
  342. (data->uFactorydata[9] << 8) +
  343. data->uFactorydata[8]);
  344. avg[0] = (long)((data->uFactorydata[15] << 24) +
  345. (data->uFactorydata[14] << 16) +
  346. (data->uFactorydata[13] << 8) +
  347. data->uFactorydata[12]);
  348. avg[1] = (long)((data->uFactorydata[19] << 24) +
  349. (data->uFactorydata[18] << 16) +
  350. (data->uFactorydata[17] << 8) +
  351. data->uFactorydata[16]);
  352. avg[2] = (long)((data->uFactorydata[23] << 24) +
  353. (data->uFactorydata[22] << 16) +
  354. (data->uFactorydata[21] << 8) +
  355. data->uFactorydata[20]);
  356. rms[0] = (long)((data->uFactorydata[27] << 24) +
  357. (data->uFactorydata[26] << 16) +
  358. (data->uFactorydata[25] << 8) +
  359. data->uFactorydata[24]);
  360. rms[1] = (long)((data->uFactorydata[31] << 24) +
  361. (data->uFactorydata[30] << 16) +
  362. (data->uFactorydata[29] << 8) +
  363. data->uFactorydata[28]);
  364. rms[2] = (long)((data->uFactorydata[35] << 24) +
  365. (data->uFactorydata[34] << 16) +
  366. (data->uFactorydata[33] << 8) +
  367. data->uFactorydata[32]);
  368. pr_info("[SSP] init: %d, total cnt: %d\n", initialized, total_count);
  369. pr_info("[SSP] hw_result: %d, %d, %d, %d\n", hw_result,
  370. shift_ratio[0], shift_ratio[1], shift_ratio[2]);
  371. pr_info("[SSP] avg %+8ld %+8ld %+8ld (LSB)\n", avg[0], avg[1], avg[2]);
  372. pr_info("[SSP] rms %+8ld %+8ld %+8ld (LSB)\n", rms[0], rms[1], rms[2]);
  373. if (hw_result < 0) {
  374. pr_err("[SSP] %s - hw selftest fail(%d), sw selftest skip\n",
  375. __func__, hw_result);
  376. return sprintf(buf, "-1,0,0,0,0,0,0,%d.%d,%d.%d,%d.%d,0,0,0\n",
  377. shift_ratio[0] / 10, shift_ratio[0] % 10,
  378. shift_ratio[1] / 10, shift_ratio[1] % 10,
  379. shift_ratio[2] / 10, shift_ratio[2] % 10);
  380. }
  381. gyro_bias[0] = (avg[0] * DEF_SCALE_FOR_FLOAT) / DEF_GYRO_SENS;
  382. gyro_bias[1] = (avg[1] * DEF_SCALE_FOR_FLOAT) / DEF_GYRO_SENS;
  383. gyro_bias[2] = (avg[2] * DEF_SCALE_FOR_FLOAT) / DEF_GYRO_SENS;
  384. iCalData[0] = (s16)avg[0];
  385. iCalData[1] = (s16)avg[1];
  386. iCalData[2] = (s16)avg[2];
  387. if (VERBOSE_OUT) {
  388. pr_info("[SSP] abs bias : %+8d.%03d %+8d.%03d %+8d.%03d (dps)\n",
  389. (int)abs(gyro_bias[0]) / DEF_SCALE_FOR_FLOAT,
  390. (int)abs(gyro_bias[0]) % DEF_SCALE_FOR_FLOAT,
  391. (int)abs(gyro_bias[1]) / DEF_SCALE_FOR_FLOAT,
  392. (int)abs(gyro_bias[1]) % DEF_SCALE_FOR_FLOAT,
  393. (int)abs(gyro_bias[2]) / DEF_SCALE_FOR_FLOAT,
  394. (int)abs(gyro_bias[2]) % DEF_SCALE_FOR_FLOAT);
  395. }
  396. for (j = 0; j < 3; j++) {
  397. if (unlikely(abs(avg[j]) > bias_thresh)) {
  398. pr_err("[SSP] %s-Gyro bias (%ld) exceeded threshold "
  399. "(threshold = %d LSB)\n", a_name[j],
  400. avg[j], bias_thresh);
  401. ret_val |= 1 << (3 + j);
  402. }
  403. }
  404. /* 3rd, check RMS for dead gyros
  405. If any of the RMS noise value returns zero,
  406. then we might have dead gyro or FIFO/register failure,
  407. the part is sleeping, or the part is not responsive */
  408. if (rms[0] == 0 || rms[1] == 0 || rms[2] == 0)
  409. ret_val |= 1 << 6;
  410. if (VERBOSE_OUT) {
  411. pr_info("[SSP] RMS ^ 2 : %+8ld %+8ld %+8ld\n",
  412. (long)rms[0] / total_count,
  413. (long)rms[1] / total_count, (long)rms[2] / total_count);
  414. }
  415. for (j = 0; j < 3; j++) {
  416. if (unlikely(rms[j] / total_count > DEF_RMS_THRESH)) {
  417. pr_err("[SSP] %s-Gyro rms (%ld) exceeded threshold "
  418. "(threshold = %d LSB)\n", a_name[j],
  419. rms[j] / total_count, DEF_RMS_THRESH);
  420. ret_val |= 1 << (7 + j);
  421. }
  422. }
  423. for (i = 0; i < 3; i++) {
  424. if (rms[i] > 10000) {
  425. temp =
  426. ((u32) (rms[i] / total_count)) *
  427. DEF_RMS_SCALE_FOR_RMS;
  428. } else {
  429. temp =
  430. ((u32) (rms[i] * DEF_RMS_SCALE_FOR_RMS)) /
  431. total_count;
  432. }
  433. if (rms[i] < 0)
  434. temp = 1 << 31;
  435. dps_rms[i] = mpu6050_selftest_sqrt(temp) / DEF_GYRO_SENS;
  436. gyro_rms[i] =
  437. dps_rms[i] * DEF_SCALE_FOR_FLOAT / DEF_SQRT_SCALE_FOR_RMS;
  438. }
  439. pr_info("[SSP] RMS : %+8d.%03d %+8d.%03d %+8d.%03d (dps)\n",
  440. (int)abs(gyro_rms[0]) / DEF_SCALE_FOR_FLOAT,
  441. (int)abs(gyro_rms[0]) % DEF_SCALE_FOR_FLOAT,
  442. (int)abs(gyro_rms[1]) / DEF_SCALE_FOR_FLOAT,
  443. (int)abs(gyro_rms[1]) % DEF_SCALE_FOR_FLOAT,
  444. (int)abs(gyro_rms[2]) / DEF_SCALE_FOR_FLOAT,
  445. (int)abs(gyro_rms[2]) % DEF_SCALE_FOR_FLOAT);
  446. if (likely(!ret_val)) {
  447. save_gyro_caldata(data, iCalData);
  448. } else {
  449. pr_err("[SSP] ret_val != 0, gyrocal is 0 at all axis\n");
  450. data->gyrocal.x = 0;
  451. data->gyrocal.y = 0;
  452. data->gyrocal.z = 0;
  453. }
  454. exit:
  455. ssp_dbg("[SSP]: %s - %d,"
  456. "%d.%03d,%d.%03d,%d.%03d,"
  457. "%d.%03d,%d.%03d,%d.%03d,"
  458. "%d.%d,%d.%d,%d.%d,"
  459. "%d,%d,%d\n",
  460. __func__, ret_val,
  461. (int)abs(gyro_bias[0]/1000),
  462. (int)abs(gyro_bias[0])%1000,
  463. (int)abs(gyro_bias[1]/1000),
  464. (int)abs(gyro_bias[1])%1000,
  465. (int)abs(gyro_bias[2]/1000),
  466. (int)abs(gyro_bias[2])%1000,
  467. gyro_rms[0]/1000,
  468. (int)abs(gyro_rms[0])%1000,
  469. gyro_rms[1]/1000,
  470. (int)abs(gyro_rms[1])%1000,
  471. gyro_rms[2]/1000,
  472. (int)abs(gyro_rms[2])%1000,
  473. shift_ratio[0] / 10, shift_ratio[0] % 10,
  474. shift_ratio[1] / 10, shift_ratio[1] % 10,
  475. shift_ratio[2] / 10, shift_ratio[2] % 10,
  476. (int)(total_count/3),
  477. (int)(total_count/3),
  478. (int)(total_count/3));
  479. return sprintf(buf, "%d,"
  480. "%d.%03d,%d.%03d,%d.%03d,"
  481. "%d.%03d,%d.%03d,%d.%03d,"
  482. "%d.%d,%d.%d,%d.%d,"
  483. "%d,%d,%d\n",
  484. ret_val,
  485. (int)abs(gyro_bias[0]/1000),
  486. (int)abs(gyro_bias[0])%1000,
  487. (int)abs(gyro_bias[1]/1000),
  488. (int)abs(gyro_bias[1])%1000,
  489. (int)abs(gyro_bias[2]/1000),
  490. (int)abs(gyro_bias[2])%1000,
  491. gyro_rms[0]/1000,
  492. (int)abs(gyro_rms[0])%1000,
  493. gyro_rms[1]/1000,
  494. (int)abs(gyro_rms[1])%1000,
  495. gyro_rms[2]/1000,
  496. (int)abs(gyro_rms[2])%1000,
  497. shift_ratio[0] / 10, shift_ratio[0] % 10,
  498. shift_ratio[1] / 10, shift_ratio[1] % 10,
  499. shift_ratio[2] / 10, shift_ratio[2] % 10,
  500. (int)(total_count/3),
  501. (int)(total_count/3),
  502. (int)(total_count/3));
  503. }
  504. static ssize_t gyro_selftest_show(struct device *dev,
  505. struct device_attribute *attr, char *buf)
  506. {
  507. struct ssp_data *data = dev_get_drvdata(dev);
  508. if (data->sns_combination == STM_K330_AG)
  509. return k330_gyro_selftest(buf, data);
  510. else
  511. return mpu6500_gyro_selftest(buf, data);
  512. }
  513. static ssize_t gyro_selftest_dps_store(struct device *dev,
  514. struct device_attribute *attr, const char *buf, size_t count)
  515. {
  516. int iNewDps = 0;
  517. int iDelayCnt = 0, iRet = 0;
  518. char chTempBuf[2] = { 0, 10 };
  519. struct ssp_data *data = dev_get_drvdata(dev);
  520. if (!(data->uSensorState & (1 << GYROSCOPE_SENSOR)))
  521. goto exit;
  522. sscanf(buf, "%d", &iNewDps);
  523. if (iNewDps == GYROSCOPE_DPS250)
  524. chTempBuf[0] = 0;
  525. else if (iNewDps == GYROSCOPE_DPS500)
  526. chTempBuf[0] = 1;
  527. else if (iNewDps == GYROSCOPE_DPS2000)
  528. chTempBuf[0] = 2;
  529. else {
  530. chTempBuf[0] = 1;
  531. iNewDps = GYROSCOPE_DPS500;
  532. }
  533. data->uFactorydataReady = 0;
  534. memset(data->uFactorydata, 0, sizeof(char) * FACTORY_DATA_MAX);
  535. iRet = send_instruction(data, FACTORY_MODE, GYROSCOPE_DPS_FACTORY,
  536. chTempBuf, 2);
  537. while (!(data->uFactorydataReady & (1 << GYROSCOPE_DPS_FACTORY))
  538. && (iDelayCnt++ < 150)
  539. && (iRet == SUCCESS))
  540. msleep(20);
  541. if ((iDelayCnt >= 150) || (iRet != SUCCESS)) {
  542. pr_err("[SSP]: %s - Gyro Selftest DPS Timeout!!\n", __func__);
  543. goto exit;
  544. }
  545. mdelay(5);
  546. if (data->uFactorydata[0] != SUCCESS) {
  547. pr_err("[SSP]: %s - Gyro Selftest DPS Error!!\n", __func__);
  548. goto exit;
  549. }
  550. data->uGyroDps = (unsigned int)iNewDps;
  551. pr_err("[SSP]: %s - %u dps stored\n", __func__, data->uGyroDps);
  552. exit:
  553. return count;
  554. }
  555. static ssize_t gyro_selftest_dps_show(struct device *dev,
  556. struct device_attribute *attr, char *buf)
  557. {
  558. struct ssp_data *data = dev_get_drvdata(dev);
  559. return sprintf(buf, "%u\n", data->uGyroDps);
  560. }
  561. static DEVICE_ATTR(name, S_IRUGO, gyro_name_show, NULL);
  562. static DEVICE_ATTR(vendor, S_IRUGO, gyro_vendor_show, NULL);
  563. static DEVICE_ATTR(power_off, S_IRUGO, gyro_power_off, NULL);
  564. static DEVICE_ATTR(power_on, S_IRUGO, gyro_power_on, NULL);
  565. static DEVICE_ATTR(temperature, S_IRUGO, gyro_get_temp, NULL);
  566. static DEVICE_ATTR(selftest, S_IRUGO, gyro_selftest_show, NULL);
  567. static DEVICE_ATTR(selftest_dps, S_IRUGO | S_IWUSR | S_IWGRP,
  568. gyro_selftest_dps_show, gyro_selftest_dps_store);
  569. static struct device_attribute *gyro_attrs[] = {
  570. &dev_attr_name,
  571. &dev_attr_vendor,
  572. &dev_attr_selftest,
  573. &dev_attr_power_on,
  574. &dev_attr_power_off,
  575. &dev_attr_temperature,
  576. &dev_attr_selftest_dps,
  577. NULL,
  578. };
  579. void initialize_gyro_factorytest(struct ssp_data *data)
  580. {
  581. sensors_register(data->gyro_device, data, gyro_attrs, "gyro_sensor");
  582. }
  583. void remove_gyro_factorytest(struct ssp_data *data)
  584. {
  585. sensors_unregister(data->gyro_device, gyro_attrs);
  586. }