accel_factory.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #include "inc/accel_factory.h"
  2. static int acc_factory_open(struct inode *inode, struct file *file)
  3. {
  4. file->private_data = acc_context_obj;
  5. if (file->private_data == NULL) {
  6. ACC_ERR("null pointer!!\n");
  7. return -EINVAL;
  8. }
  9. return nonseekable_open(inode, file);
  10. }
  11. static int acc_factory_release(struct inode *inode, struct file *file)
  12. {
  13. file->private_data = NULL;
  14. return 0;
  15. }
  16. static int acc_set_cali(int data[ACC_AXES_NUM])
  17. {
  18. struct acc_context *cxt = acc_context_obj;
  19. ACC_LOG("factory cali %d,%d,%d\n", data[ACC_AXIS_X], data[ACC_AXIS_Y], data[ACC_AXIS_Z]);
  20. ACC_LOG("original cali %d,%d,%d\n", cxt->cali_sw[ACC_AXIS_X], cxt->cali_sw[ACC_AXIS_Y],
  21. cxt->cali_sw[ACC_AXIS_Z]);
  22. cxt->cali_sw[ACC_AXIS_X] += data[ACC_AXIS_X];
  23. cxt->cali_sw[ACC_AXIS_Y] += data[ACC_AXIS_Y];
  24. cxt->cali_sw[ACC_AXIS_Z] += data[ACC_AXIS_Z];
  25. ACC_LOG("new cali %d,%d,%d\n", cxt->cali_sw[ACC_AXIS_X], cxt->cali_sw[ACC_AXIS_Y],
  26. cxt->cali_sw[ACC_AXIS_Z]);
  27. return 0;
  28. }
  29. static int acc_clear_cali(void)
  30. {
  31. struct acc_context *cxt = acc_context_obj;
  32. cxt->cali_sw[ACC_AXIS_X] = 0;
  33. cxt->cali_sw[ACC_AXIS_Y] = 0;
  34. cxt->cali_sw[ACC_AXIS_Z] = 0;
  35. ACC_LOG("after clear cali %d,%d,%d\n", cxt->cali_sw[ACC_AXIS_X], cxt->cali_sw[ACC_AXIS_Y],
  36. cxt->cali_sw[ACC_AXIS_Z]);
  37. return 0;
  38. }
  39. static long acc_factory_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  40. {
  41. void __user *data;
  42. int err = 0;
  43. struct acc_context *cxt = acc_context_obj;
  44. int x, y, z;
  45. char strbuf[256];
  46. int cali[3] = {0};
  47. struct SENSOR_DATA sensor_data = {0};
  48. if (_IOC_DIR(cmd) & _IOC_READ)
  49. err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
  50. else if (_IOC_DIR(cmd) & _IOC_WRITE)
  51. err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
  52. if (err) {
  53. ACC_ERR("access error: %08X, (%2d, %2d)\n", cmd, _IOC_DIR(cmd), _IOC_SIZE(cmd));
  54. return -EFAULT;
  55. }
  56. switch (cmd) {
  57. case GSENSOR_IOCTL_INIT:
  58. break;
  59. case GSENSOR_IOCTL_READ_CHIPINFO:
  60. break;
  61. case GSENSOR_IOCTL_READ_SENSORDATA:
  62. data = (void __user *) arg;
  63. if (data == NULL) {
  64. err = -EINVAL;
  65. break;
  66. }
  67. if (cxt->acc_ctl.enable_nodata != NULL) {
  68. err = cxt->acc_ctl.enable_nodata(1);
  69. if (err) {
  70. err = cxt->acc_ctl.enable_nodata(1);
  71. if (err) {
  72. err = cxt->acc_ctl.enable_nodata(1);
  73. if (err)
  74. ACC_ERR("acc ioctl enable err 3 timers = %d\n", err);
  75. }
  76. }
  77. ACC_LOG("acc ioctl real enable\n");
  78. }
  79. if (cxt->acc_data.get_data != NULL) {
  80. err = cxt->acc_data.get_raw_data(&x, &y, &z);
  81. if (err < 0) {
  82. ACC_ERR("GSENSOR_IOCTL_READ_SENSORDATA read data fail!\n");
  83. break;
  84. }
  85. x += cxt->cali_sw[0];
  86. y += cxt->cali_sw[1];
  87. z += cxt->cali_sw[2];
  88. sprintf(strbuf, "%x %x %x", x, y, z);
  89. ACC_LOG("GSENSOR_IOCTL_READ_SENSORDATA read data : (%d, %d, %d)!\n", x, y, z);
  90. ACC_LOG("GSENSOR_IOCTL_READ_SENSORDATA read strbuf : (%s)!\n", strbuf);
  91. if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
  92. err = -EFAULT;
  93. break;
  94. }
  95. } else
  96. ACC_ERR("GSENSOR_IOCTL_READ_SENSORDATA ");
  97. break;
  98. case GSENSOR_IOCTL_READ_RAW_DATA:
  99. data = (void __user *) arg;
  100. if (data == NULL) {
  101. err = -EINVAL;
  102. break;
  103. }
  104. if (cxt->acc_data.get_raw_data != NULL) {
  105. err = cxt->acc_data.get_raw_data(&x, &y, &z);
  106. if (err < 0) {
  107. ACC_ERR("GSENSOR_IOCTL_READ_RAW_DATA read data fail!\n");
  108. break;
  109. }
  110. x += cxt->cali_sw[0];
  111. y += cxt->cali_sw[1];
  112. z += cxt->cali_sw[2];
  113. sprintf(strbuf, "%x %x %x", x, y, z);
  114. ACC_LOG("GSENSOR_IOCTL_READ_RAW_DATA read data : (%d, %d, %d)!\n", x, y, z);
  115. if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
  116. err = -EFAULT;
  117. break;
  118. }
  119. } else
  120. ACC_ERR("GSENSOR_IOCTL_READ_SENSORDATA ");
  121. break;
  122. case GSENSOR_IOCTL_SET_CALI:
  123. data = (void __user *)arg;
  124. if (data == NULL) {
  125. err = -EINVAL;
  126. break;
  127. }
  128. if (copy_from_user(&sensor_data, data, sizeof(sensor_data))) {
  129. err = -EFAULT;
  130. break;
  131. }
  132. cali[0] = sensor_data.x;
  133. cali[1] = sensor_data.y;
  134. cali[2] = sensor_data.z;
  135. ACC_LOG("GSENSOR_IOCTL_SET_CALI data : (%d, %d, %d)!\n", cali[0], cali[1], cali[2]);
  136. acc_set_cali(cali);
  137. break;
  138. case GSENSOR_IOCTL_CLR_CALI:
  139. acc_clear_cali();
  140. break;
  141. case GSENSOR_IOCTL_GET_CALI:
  142. data = (void __user *)arg;
  143. if (data == NULL) {
  144. err = -EINVAL;
  145. break;
  146. }
  147. ACC_LOG("GSENSOR_IOCTL_GET_CALI data : (%d, %d, %d)!\n", cxt->cali_sw[0], cxt->cali_sw[1],
  148. cxt->cali_sw[2]);
  149. sensor_data.x = cxt->cali_sw[0];
  150. sensor_data.y = cxt->cali_sw[1];
  151. sensor_data.z = cxt->cali_sw[2];
  152. if (copy_to_user(data, &sensor_data, sizeof(sensor_data))) {
  153. err = -EFAULT;
  154. break;
  155. }
  156. break;
  157. default:
  158. ACC_ERR("unknown IOCTL: 0x%08x\n", cmd);
  159. err = -ENOIOCTLCMD;
  160. }
  161. return err;
  162. }
  163. #if IS_ENABLED(CONFIG_COMPAT)
  164. static long compat_acc_factory_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  165. {
  166. if (!filp->f_op || !filp->f_op->unlocked_ioctl) {
  167. ACC_ERR("compat_ion_ioctl file has no f_op or no f_op->unlocked_ioctl.\n");
  168. return -ENOTTY;
  169. }
  170. switch (cmd) {
  171. case COMPAT_GSENSOR_IOCTL_INIT:
  172. case COMPAT_GSENSOR_IOCTL_READ_CHIPINFO:
  173. /* case COMPAT_GSENSOR_IOCTL_READ_GAIN: */
  174. case COMPAT_GSENSOR_IOCTL_READ_RAW_DATA:
  175. case COMPAT_GSENSOR_IOCTL_READ_SENSORDATA:
  176. /* NVRAM will use below ioctl */
  177. case COMPAT_GSENSOR_IOCTL_SET_CALI:
  178. case COMPAT_GSENSOR_IOCTL_CLR_CALI:
  179. case COMPAT_GSENSOR_IOCTL_GET_CALI:{
  180. ACC_LOG("compat_ion_ioctl : GSENSOR_IOCTL_XXX command is 0x%x\n", cmd);
  181. return filp->f_op->unlocked_ioctl(filp, cmd,
  182. (unsigned long)compat_ptr(arg));
  183. }
  184. default:{
  185. ACC_ERR("compat_ion_ioctl : No such command!! 0x%x\n", cmd);
  186. return -ENOIOCTLCMD;
  187. }
  188. }
  189. }
  190. #endif
  191. /*----------------------------------------------------------------------------*/
  192. static const struct file_operations acc_factory_fops = {
  193. .open = acc_factory_open,
  194. .release = acc_factory_release,
  195. .unlocked_ioctl = acc_factory_unlocked_ioctl,
  196. #if IS_ENABLED(CONFIG_COMPAT)
  197. .compat_ioctl = compat_acc_factory_unlocked_ioctl,
  198. #endif
  199. };
  200. static struct miscdevice acc_factory_device = {
  201. .minor = MISC_DYNAMIC_MINOR,
  202. .name = "gsensor",
  203. .fops = &acc_factory_fops,
  204. };
  205. int acc_factory_device_init(void)
  206. {
  207. int error = 0;
  208. struct acc_context *cxt = acc_context_obj;
  209. if (!cxt->acc_ctl.is_use_common_factory) {
  210. ACC_LOG("Node of '/dev/gsensor' has already existed!\n");
  211. return -1;
  212. }
  213. error = misc_register(&acc_factory_device);
  214. if (error) {
  215. ACC_LOG("acc_factory_device register failed\n");
  216. error = -1;
  217. }
  218. return error;
  219. }