gyro_lsm330.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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 "STM"
  20. #define CHIP_ID "LSM330"
  21. #define CALIBRATION_FILE_PATH "/efs/gyro_cal_data"
  22. #define CALIBRATION_DATA_AMOUNT 20
  23. static ssize_t gyro_vendor_show(struct device *dev,
  24. struct device_attribute *attr, char *buf)
  25. {
  26. return sprintf(buf, "%s\n", VENDOR);
  27. }
  28. static ssize_t gyro_name_show(struct device *dev,
  29. struct device_attribute *attr, char *buf)
  30. {
  31. return sprintf(buf, "%s\n", CHIP_ID);
  32. }
  33. int gyro_open_calibration(struct ssp_data *data)
  34. {
  35. int iRet = 0;
  36. mm_segment_t old_fs;
  37. struct file *cal_filp = NULL;
  38. old_fs = get_fs();
  39. set_fs(KERNEL_DS);
  40. cal_filp = filp_open(CALIBRATION_FILE_PATH, O_RDONLY, 0666);
  41. if (IS_ERR(cal_filp)) {
  42. set_fs(old_fs);
  43. iRet = PTR_ERR(cal_filp);
  44. data->gyrocal.x = 0;
  45. data->gyrocal.y = 0;
  46. data->gyrocal.z = 0;
  47. return iRet;
  48. }
  49. iRet = cal_filp->f_op->read(cal_filp, (char *)&data->gyrocal,
  50. 3 * sizeof(int), &cal_filp->f_pos);
  51. if (iRet != 3 * sizeof(int))
  52. iRet = -EIO;
  53. filp_close(cal_filp, current->files);
  54. set_fs(old_fs);
  55. ssp_dbg("[SSP]: open gyro calibration %d, %d, %d\n",
  56. data->gyrocal.x, data->gyrocal.y, data->gyrocal.z);
  57. return iRet;
  58. }
  59. static int save_gyro_caldata(struct ssp_data *data, s16 *iCalData)
  60. {
  61. int iRet = 0;
  62. struct file *cal_filp = NULL;
  63. mm_segment_t old_fs;
  64. data->gyrocal.x = iCalData[0];
  65. data->gyrocal.y = iCalData[1];
  66. data->gyrocal.z = iCalData[2];
  67. ssp_dbg("[SSP]: do gyro calibrate %d, %d, %d\n",
  68. data->gyrocal.x, data->gyrocal.y, data->gyrocal.z);
  69. old_fs = get_fs();
  70. set_fs(KERNEL_DS);
  71. cal_filp = filp_open(CALIBRATION_FILE_PATH,
  72. O_CREAT | O_TRUNC | O_WRONLY, 0666);
  73. if (IS_ERR(cal_filp)) {
  74. pr_err("[SSP]: %s - Can't open calibration file\n", __func__);
  75. set_fs(old_fs);
  76. iRet = PTR_ERR(cal_filp);
  77. return -EIO;
  78. }
  79. iRet = cal_filp->f_op->write(cal_filp, (char *)&data->gyrocal,
  80. 3 * sizeof(int), &cal_filp->f_pos);
  81. if (iRet != 3 * sizeof(int)) {
  82. pr_err("[SSP]: %s - Can't write gyro cal to file\n", __func__);
  83. iRet = -EIO;
  84. }
  85. filp_close(cal_filp, current->files);
  86. set_fs(old_fs);
  87. return iRet;
  88. }
  89. static ssize_t gyro_power_off(struct device *dev,
  90. struct device_attribute *attr, char *buf)
  91. {
  92. ssp_dbg("[SSP]: %s\n", __func__);
  93. return sprintf(buf, "%d\n", 1);
  94. }
  95. static ssize_t gyro_power_on(struct device *dev,
  96. struct device_attribute *attr, char *buf)
  97. {
  98. ssp_dbg("[SSP]: %s\n", __func__);
  99. return sprintf(buf, "%d\n", 1);
  100. }
  101. static ssize_t gyro_get_temp(struct device *dev,
  102. struct device_attribute *attr, char *buf)
  103. {
  104. char chTempBuf[2] = { 0, 10}, chTemp = 0;
  105. int iDelayCnt = 0, iRet = 0;
  106. struct ssp_data *data = dev_get_drvdata(dev);
  107. data->uFactorydataReady = 0;
  108. memset(data->uFactorydata, 0, sizeof(char) * FACTORY_DATA_MAX);
  109. iRet = send_instruction(data, FACTORY_MODE, GYROSCOPE_TEMP_FACTORY,
  110. chTempBuf, 2);
  111. while (!(data->uFactorydataReady & (1 << GYROSCOPE_TEMP_FACTORY))
  112. && (iDelayCnt++ < 150)
  113. && (iRet == SUCCESS))
  114. msleep(20);
  115. if ((iDelayCnt >= 150) || (iRet != SUCCESS)) {
  116. pr_err("[SSP]: %s - Gyro Temp Timeout!!\n", __func__);
  117. goto exit;
  118. }
  119. chTemp = (char)data->uFactorydata[0];
  120. ssp_dbg("[SSP]: %s - %d\n", __func__, chTemp);
  121. exit:
  122. return sprintf(buf, "%d\n", chTemp);
  123. }
  124. static ssize_t gyro_selftest_show(struct device *dev,
  125. struct device_attribute *attr, char *buf)
  126. {
  127. char chTempBuf[2] = { 3, 200};
  128. u8 uFifoPass = 2;
  129. u8 uBypassPass = 2;
  130. u8 uCalPass = 0;
  131. s16 iNOST[3] = {0,}, iST[3] = {0,}, iCalData[3] = {0,};
  132. int iZeroRateData[3] = {0,};
  133. int iDelayCnt = 0, iRet = 0;
  134. struct ssp_data *data = dev_get_drvdata(dev);
  135. data->uFactorydataReady = 0;
  136. memset(data->uFactorydata, 0, sizeof(char) * FACTORY_DATA_MAX);
  137. iRet = send_instruction(data, FACTORY_MODE, GYROSCOPE_FACTORY,
  138. chTempBuf, 2);
  139. while (!(data->uFactorydataReady & (1 << GYROSCOPE_FACTORY))
  140. && (iDelayCnt++ < 150)
  141. && (iRet == SUCCESS))
  142. msleep(20);
  143. if ((iDelayCnt >= 150) || (iRet != SUCCESS)) {
  144. pr_err("[SSP]: %s - Gyro Selftest Timeout!!\n", __func__);
  145. goto exit;
  146. }
  147. iNOST[0] = (s16)((data->uFactorydata[0] << 8) + data->uFactorydata[1]);
  148. iNOST[1] = (s16)((data->uFactorydata[2] << 8) + data->uFactorydata[3]);
  149. iNOST[2] = (s16)((data->uFactorydata[4] << 8) + data->uFactorydata[5]);
  150. iST[0] = (s16)((data->uFactorydata[6] << 8) + data->uFactorydata[7]);
  151. iST[1] = (s16)((data->uFactorydata[8] << 8) + data->uFactorydata[9]);
  152. iST[2] = (s16)((data->uFactorydata[10] << 8) + data->uFactorydata[11]);
  153. iCalData[0] =
  154. (s16)((data->uFactorydata[12] << 8) + data->uFactorydata[13]);
  155. iCalData[1] =
  156. (s16)((data->uFactorydata[14] << 8) + data->uFactorydata[15]);
  157. iCalData[2] =
  158. (s16)((data->uFactorydata[16] << 8) + data->uFactorydata[17]);
  159. uCalPass = data->uFactorydata[18];
  160. uFifoPass = data->uFactorydata[19];
  161. uBypassPass = data->uFactorydata[20];
  162. if (uFifoPass && uBypassPass && uCalPass)
  163. save_gyro_caldata(data, iCalData);
  164. iZeroRateData[0] = (int)(iCalData[0] * 175) / 10000;
  165. iZeroRateData[1] = (int)(iCalData[1] * 175) / 10000;
  166. iZeroRateData[2] = (int)(iCalData[2] * 175) / 10000;
  167. exit:
  168. ssp_dbg("[SSP]: Gyro Selftest - %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
  169. iNOST[0], iNOST[1], iNOST[2], iST[0], iST[1], iST[2],
  170. iZeroRateData[0], iZeroRateData[1], iZeroRateData[2],
  171. uFifoPass & uBypassPass & uCalPass, uFifoPass, uCalPass);
  172. return sprintf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
  173. iNOST[0], iNOST[1], iNOST[2], iST[0], iST[1], iST[2],
  174. iZeroRateData[0], iZeroRateData[1], iZeroRateData[2],
  175. uFifoPass & uBypassPass & uCalPass, uFifoPass, uCalPass);
  176. }
  177. static ssize_t gyro_selftest_dps_store(struct device *dev,
  178. struct device_attribute *attr, const char *buf, size_t count)
  179. {
  180. int iNewDps = 0;
  181. int iDelayCnt = 0, iRet = 0;
  182. char chTempBuf[2] = { 0, 10 };
  183. struct ssp_data *data = dev_get_drvdata(dev);
  184. sscanf(buf, "%d", &iNewDps);
  185. if (iNewDps == GYROSCOPE_DPS250)
  186. chTempBuf[0] = 0;
  187. else if (iNewDps == GYROSCOPE_DPS500)
  188. chTempBuf[0] = 1;
  189. else if (iNewDps == GYROSCOPE_DPS2000)
  190. chTempBuf[0] = 2;
  191. else {
  192. chTempBuf[0] = 1;
  193. iNewDps = GYROSCOPE_DPS500;
  194. }
  195. data->uFactorydataReady = 0;
  196. memset(data->uFactorydata, 0, sizeof(char) * FACTORY_DATA_MAX);
  197. iRet = send_instruction(data, FACTORY_MODE, GYROSCOPE_DPS_FACTORY,
  198. chTempBuf, 2);
  199. while (!(data->uFactorydataReady & (1 << GYROSCOPE_DPS_FACTORY))
  200. && (iDelayCnt++ < 150)
  201. && (iRet == SUCCESS))
  202. msleep(20);
  203. if ((iDelayCnt >= 150) || (iRet != SUCCESS)) {
  204. pr_err("[SSP]: %s - Gyro Selftest DPS Timeout!!\n", __func__);
  205. goto exit;
  206. }
  207. if (data->uFactorydata[0] != SUCCESS) {
  208. pr_err("[SSP]: %s - Gyro Selftest DPS Error!!\n", __func__);
  209. goto exit;
  210. }
  211. data->uGyroDps = (unsigned int)iNewDps;
  212. pr_err("[SSP]: %s - %u dps stored\n", __func__, data->uGyroDps);
  213. exit:
  214. return count;
  215. }
  216. static ssize_t gyro_selftest_dps_show(struct device *dev,
  217. struct device_attribute *attr, char *buf)
  218. {
  219. struct ssp_data *data = dev_get_drvdata(dev);
  220. return sprintf(buf, "%u\n", data->uGyroDps);
  221. }
  222. static DEVICE_ATTR(name, S_IRUGO, gyro_name_show, NULL);
  223. static DEVICE_ATTR(vendor, S_IRUGO, gyro_vendor_show, NULL);
  224. static DEVICE_ATTR(power_off, S_IRUGO, gyro_power_off, NULL);
  225. static DEVICE_ATTR(power_on, S_IRUGO, gyro_power_on, NULL);
  226. static DEVICE_ATTR(temperature, S_IRUGO, gyro_get_temp, NULL);
  227. static DEVICE_ATTR(selftest, S_IRUGO, gyro_selftest_show, NULL);
  228. static DEVICE_ATTR(selftest_dps, S_IRUGO | S_IWUSR | S_IWGRP,
  229. gyro_selftest_dps_show, gyro_selftest_dps_store);
  230. static struct device_attribute *gyro_attrs[] = {
  231. &dev_attr_name,
  232. &dev_attr_vendor,
  233. &dev_attr_selftest,
  234. &dev_attr_power_on,
  235. &dev_attr_power_off,
  236. &dev_attr_temperature,
  237. &dev_attr_selftest_dps,
  238. NULL,
  239. };
  240. void initialize_gyro_factorytest(struct ssp_data *data)
  241. {
  242. struct device *gyro_device = NULL;
  243. sensors_register(gyro_device, data, gyro_attrs, "gyro_sensor");
  244. }