gyro_factory.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #include "inc/gyro_factory.h"
  2. static int gyro_factory_open(struct inode *inode, struct file *file)
  3. {
  4. file->private_data = gyro_context_obj;
  5. if (file->private_data == NULL) {
  6. GYRO_ERR("null pointer!!\n");
  7. return -EINVAL;
  8. }
  9. return nonseekable_open(inode, file);
  10. }
  11. static int gyro_factory_release(struct inode *inode, struct file *file)
  12. {
  13. file->private_data = NULL;
  14. return 0;
  15. }
  16. static int gyro_set_cali(int data[GYRO_AXES_NUM])
  17. {
  18. struct gyro_context *cxt = gyro_context_obj;
  19. GYRO_LOG("factory gyro cali %d,%d,%d\n", data[GYRO_AXIS_X], data[GYRO_AXIS_Y], data[GYRO_AXIS_Z]);
  20. GYRO_LOG("original gyro cali %d,%d,%d\n", cxt->cali_sw[GYRO_AXIS_X], cxt->cali_sw[GYRO_AXIS_Y],
  21. cxt->cali_sw[GYRO_AXIS_Z]);
  22. cxt->cali_sw[GYRO_AXIS_X] += data[GYRO_AXIS_X];
  23. cxt->cali_sw[GYRO_AXIS_Y] += data[GYRO_AXIS_Y];
  24. cxt->cali_sw[GYRO_AXIS_Z] += data[GYRO_AXIS_Z];
  25. GYRO_LOG("GYRO new cali %d,%d,%d\n", cxt->cali_sw[GYRO_AXIS_X], cxt->cali_sw[GYRO_AXIS_Y],
  26. cxt->cali_sw[GYRO_AXIS_Z]);
  27. return 0;
  28. }
  29. static int gyro_clear_cali(void)
  30. {
  31. struct gyro_context *cxt = gyro_context_obj;
  32. cxt->cali_sw[GYRO_AXIS_X] = 0;
  33. cxt->cali_sw[GYRO_AXIS_Y] = 0;
  34. cxt->cali_sw[GYRO_AXIS_Z] = 0;
  35. GYRO_LOG("GYRO after clear cali %d,%d,%d\n", cxt->cali_sw[GYRO_AXIS_X], cxt->cali_sw[GYRO_AXIS_Y],
  36. cxt->cali_sw[GYRO_AXIS_Z]);
  37. return 0;
  38. }
  39. static long gyro_factory_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  40. {
  41. void __user *data;
  42. long err = 0;
  43. struct gyro_context *cxt = gyro_context_obj;
  44. int x, y, z, status;
  45. char strbuf[256];
  46. int cali[3] = {0};
  47. struct SENSOR_DATA sensor_data = {0};
  48. int smtRes;
  49. if (_IOC_DIR(cmd) & _IOC_READ)
  50. err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
  51. else if (_IOC_DIR(cmd) & _IOC_WRITE)
  52. err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
  53. if (err) {
  54. GYRO_ERR("access error: %08X, (%2d, %2d)\n", cmd, _IOC_DIR(cmd), _IOC_SIZE(cmd));
  55. return -EFAULT;
  56. }
  57. switch (cmd) {
  58. case GYROSCOPE_IOCTL_INIT:
  59. if (cxt->gyro_ctl.enable_nodata != NULL) {
  60. err = cxt->gyro_ctl.enable_nodata(1);
  61. if (err < 0) {
  62. GYRO_LOG("GYROSCOPE_IOCTL_READ_SENSORDATA read data fail!\n");
  63. break;
  64. }
  65. GYRO_LOG("GYROSCOPE_IOCTL_INIT\n");
  66. } else
  67. GYRO_LOG("GYROSCOPE_IOCTL_READ_SENSORDATA ");
  68. break;
  69. case GYROSCOPE_IOCTL_SMT_DATA:
  70. data = (void __user *) arg;
  71. if (data == NULL) {
  72. err = -EINVAL;
  73. break;
  74. }
  75. smtRes = 1;
  76. err = copy_to_user(data, &smtRes, sizeof(smtRes));
  77. if (err) {
  78. err = -EINVAL;
  79. GYRO_ERR("copy gyro data to user failed!\n");
  80. }
  81. break;
  82. case GYROSCOPE_IOCTL_READ_SENSORDATA:
  83. data = (void __user *) arg;
  84. if (data == NULL) {
  85. err = -EINVAL;
  86. break;
  87. }
  88. if (cxt->gyro_data.get_data != NULL) {
  89. err = cxt->gyro_data.get_data(&x, &y, &z, &status);
  90. if (err < 0) {
  91. GYRO_LOG("GYROSCOPE_IOCTL_READ_SENSORDATA read data fail!\n");
  92. break;
  93. }
  94. x += cxt->cali_sw[0];
  95. y += cxt->cali_sw[1];
  96. z += cxt->cali_sw[2];
  97. sprintf(strbuf, "%x %x %x", x, y, z);
  98. GYRO_LOG("GYROSCOPE_IOCTL_READ_SENSORDATA read data : (%d, %d, %d)!\n", x, y, z);
  99. GYRO_LOG("GYROSCOPE_IOCTL_READ_SENSORDATA read strbuf : (%s)!\n", strbuf);
  100. if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
  101. err = -EFAULT;
  102. break;
  103. }
  104. } else
  105. GYRO_LOG("GYROSCOPE_IOCTL_READ_SENSORDATA ");
  106. break;
  107. case GYROSCOPE_IOCTL_READ_SENSORDATA_RAW:
  108. data = (void __user *) arg;
  109. if (data == NULL) {
  110. err = -EINVAL;
  111. break;
  112. }
  113. if (cxt->gyro_data.get_raw_data != NULL) {
  114. err = cxt->gyro_data.get_raw_data(&x, &y, &z);
  115. if (err < 0) {
  116. GYRO_LOG("GSENSOR_IOCTL_READ_RAW_DATA read data fail!\n");
  117. break;
  118. }
  119. x += cxt->cali_sw[0];
  120. y += cxt->cali_sw[1];
  121. z += cxt->cali_sw[2];
  122. sprintf(strbuf, "%x %x %x", x, y, z);
  123. GYRO_LOG("GSENSOR_IOCTL_READ_RAW_DATA read data : (%d, %d, %d)!\n", x, y, z);
  124. if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
  125. err = -EFAULT;
  126. break;
  127. }
  128. } else
  129. GYRO_LOG("GSENSOR_IOCTL_READ_RAW_DATA FAIL!\n ");
  130. break;
  131. case GYROSCOPE_IOCTL_SET_CALI:
  132. data = (void __user *)arg;
  133. if (data == NULL) {
  134. err = -EINVAL;
  135. break;
  136. }
  137. if (copy_from_user(&sensor_data, data, sizeof(sensor_data))) {
  138. err = -EFAULT;
  139. break;
  140. }
  141. cali[0] = sensor_data.x;
  142. cali[1] = sensor_data.y;
  143. cali[2] = sensor_data.z;
  144. GYRO_LOG("GYROSCOPE_IOCTL_SET_CALI data : (%d, %d, %d)!\n", cali[0], cali[1], cali[2]);
  145. gyro_set_cali(cali);
  146. break;
  147. case GYROSCOPE_IOCTL_CLR_CALI:
  148. gyro_clear_cali();
  149. break;
  150. case GYROSCOPE_IOCTL_GET_CALI:
  151. data = (void __user *)arg;
  152. if (data == NULL) {
  153. err = -EINVAL;
  154. break;
  155. }
  156. GYRO_LOG("GYROSCOPE_IOCTL_GET_CALI data : (%d, %d, %d)!\n", cxt->cali_sw[0] , cxt->cali_sw[1],
  157. cxt->cali_sw[2]);
  158. sensor_data.x = cxt->cali_sw[0];
  159. sensor_data.y = cxt->cali_sw[1];
  160. sensor_data.z = cxt->cali_sw[2];
  161. if (copy_to_user(data, &sensor_data, sizeof(sensor_data))) {
  162. err = -EFAULT;
  163. break;
  164. }
  165. break;
  166. default:
  167. GYRO_LOG("unknown IOCTL: 0x%08x\n", cmd);
  168. err = -ENOIOCTLCMD;
  169. }
  170. return err;
  171. }
  172. #if IS_ENABLED(CONFIG_COMPAT)
  173. static long compat_gyro_factory_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  174. {
  175. if (!filp->f_op || !filp->f_op->unlocked_ioctl) {
  176. GYRO_ERR("compat_ion_ioctl file has no f_op or no f_op->unlocked_ioctl.\n");
  177. return -ENOTTY;
  178. }
  179. switch (cmd) {
  180. case COMPAT_GYROSCOPE_IOCTL_INIT:
  181. case COMPAT_GYROSCOPE_IOCTL_SMT_DATA:
  182. case COMPAT_GYROSCOPE_IOCTL_READ_SENSORDATA_RAW:
  183. /*case COMPAT_GYROSCOPE_IOCTL_READ_TEMPERATURE:
  184. case COMPAT_GYROSCOPE_IOCTL_GET_POWER_STATUS: */
  185. case COMPAT_GYROSCOPE_IOCTL_READ_SENSORDATA:
  186. /* NVRAM will use below ioctl */
  187. case COMPAT_GYROSCOPE_IOCTL_SET_CALI:
  188. case COMPAT_GYROSCOPE_IOCTL_CLR_CALI:
  189. case COMPAT_GYROSCOPE_IOCTL_GET_CALI:{
  190. GYRO_LOG("compat_ion_ioctl : GYROSCOPE_IOCTL_XXX command is 0x%x\n", cmd);
  191. return filp->f_op->unlocked_ioctl(filp, cmd,
  192. (unsigned long)compat_ptr(arg));
  193. }
  194. default:{
  195. GYRO_ERR("compat_ion_ioctl : No such command!! 0x%x\n", cmd);
  196. return -ENOIOCTLCMD;
  197. }
  198. }
  199. }
  200. #endif
  201. /*----------------------------------------------------------------------------*/
  202. static const struct file_operations gyro_factory_fops = {
  203. .open = gyro_factory_open,
  204. .release = gyro_factory_release,
  205. .unlocked_ioctl = gyro_factory_unlocked_ioctl,
  206. #if IS_ENABLED(CONFIG_COMPAT)
  207. .compat_ioctl = compat_gyro_factory_unlocked_ioctl,
  208. #endif
  209. };
  210. static struct miscdevice gyro_factory_device = {
  211. .minor = MISC_DYNAMIC_MINOR,
  212. .name = "gyroscope",
  213. .fops = &gyro_factory_fops,
  214. };
  215. int gyro_factory_device_init(void)
  216. {
  217. int error = 0;
  218. struct gyro_context *cxt = gyro_context_obj;
  219. if (!cxt->gyro_ctl.is_use_common_factory) {
  220. GYRO_LOG("Node of '/dev/gyroscope' has already existed!\n");
  221. return -1;
  222. }
  223. error = misc_register(&gyro_factory_device);
  224. if (error) {
  225. GYRO_LOG("gyro_factory_device register failed\n");
  226. error = -1;
  227. }
  228. return error;
  229. }