gyro_mpu6500.c 19 KB

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