alps-input.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/moduleparam.h>
  4. #include <linux/platform_device.h>
  5. #include <linux/input.h>
  6. #include <linux/mutex.h>
  7. #include <linux/slab.h>
  8. #include <linux/uaccess.h>
  9. #include <linux/miscdevice.h>
  10. #include <linux/fs.h>
  11. #include <linux/ioctl.h>
  12. #include <linux/sensor/sensors_core.h>
  13. #ifdef CONFIG_OF
  14. #include <linux/of_gpio.h>
  15. #endif
  16. #ifdef CONFIG_HAS_EARLYSUSPEND
  17. #include <linux/earlysuspend.h>
  18. #endif
  19. #include <linux/alps_compass_io.h>
  20. #include <linux/input-polldev.h>
  21. #define EVENT_TYPE_ACCEL_X ABS_X
  22. #define EVENT_TYPE_ACCEL_Y ABS_Y
  23. #define EVENT_TYPE_ACCEL_Z ABS_Z
  24. #define EVENT_TYPE_MAG_X ABS_X
  25. #define EVENT_TYPE_MAG_Y ABS_Y
  26. #define EVENT_TYPE_MAG_Z ABS_Z
  27. #define ALPS_POLL_INTERVAL 200 /* msecs */
  28. #define ALPS_INPUT_FUZZ 0 /* input event threshold */
  29. #define ALPS_INPUT_FLAT 0
  30. #define ON 1
  31. #define OFF 0
  32. #ifdef CONFIG_HAS_EARLYSUSPEND
  33. static void alps_early_suspend(struct early_suspend *handler);
  34. static void alps_early_resume(struct early_suspend *handler);
  35. #endif
  36. struct alps_data {
  37. struct platform_device *pdev;
  38. struct input_polled_dev *alps_idev;
  39. struct mutex alps_lock;
  40. struct miscdevice alps_device;
  41. #ifdef CONFIG_HAS_EARLYSUSPEND
  42. struct early_suspend alps_early_suspend_handler;
  43. #endif
  44. int suspend_flag;
  45. int delay;
  46. int flgM;
  47. int flgA;
  48. u32 position;
  49. };
  50. /* for I/O Control */
  51. static long alps_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  52. {
  53. int ret = -1, tmpval;
  54. void __user *argp = (void __user *)arg;
  55. struct alps_data *data = container_of(filp->private_data,
  56. struct alps_data, alps_device);
  57. switch (cmd) {
  58. case ALPSIO_SET_MAGACTIVATE:
  59. ret = copy_from_user(&tmpval, argp, sizeof(tmpval));
  60. if (ret) {
  61. pr_err("%s : failed for ALPSIO_SET_MAGACTIVATE\n",
  62. __func__);
  63. return -EFAULT;
  64. }
  65. #ifdef ALPS_DEBUG
  66. pr_debug("%s : ALPSIO_SET_MAGACTIVATE, flgM = %d\n",
  67. __func__, tmpval);
  68. #endif
  69. mutex_lock(&data->alps_lock);
  70. data->flgM = tmpval;
  71. hscd_activate(1, data->flgM, data->delay);
  72. mutex_unlock(&data->alps_lock);
  73. break;
  74. case ALPSIO_SET_ACCACTIVATE:
  75. pr_err("%s : failed for ALPSIO_SET_ACCACTIVATE\n",
  76. __func__);
  77. break;
  78. /*
  79. ret = copy_from_user(&tmpval, argp, sizeof(tmpval));
  80. if (ret) {
  81. pr_err("%s : failed for ALPSIO_SET_ACCACTIVATE\n",
  82. __func__);
  83. return -EFAULT;
  84. }
  85. #ifdef ALPS_DEBUG
  86. pr_debug("%s : ALPSIO_SET_ACCACTIVATE, flgM = %d\n",
  87. __func__, tmpval);
  88. #endif
  89. mutex_lock(&data->alps_lock);
  90. data->flgA = tmpval;
  91. accsns_activate(1, data->flgA, data->delay);
  92. mutex_unlock(&data->alps_lock);
  93. break;
  94. */
  95. case ALPSIO_SET_DELAY:
  96. ret = copy_from_user(&tmpval, argp, sizeof(tmpval));
  97. if (ret) {
  98. pr_err("%s : failed for ALPSIO_SET_DELAY\n", __func__);
  99. return -EFAULT;
  100. }
  101. mutex_lock(&data->alps_lock);
  102. if (tmpval <= 10)
  103. tmpval = 10;
  104. else if (tmpval <= 20)
  105. tmpval = 20;
  106. else if (tmpval <= 70)
  107. tmpval = 70;
  108. else
  109. tmpval = 200;
  110. data->delay = tmpval;
  111. if (data->flgM)
  112. hscd_activate(1, data->flgM, data->delay);
  113. /* if (data->flgA)
  114. accsns_activate(1, data->flgA, data->delay);*/
  115. mutex_unlock(&data->alps_lock);
  116. pr_info("%s : ALPSIO_SET_DELAY, delay = %d\n",
  117. __func__, data->delay);
  118. break;
  119. case ALPSIO_ACT_SELF_TEST_A:
  120. #ifdef ALPS_DEBUG
  121. pr_debug("%s : ALPSIO_ACT_SELF_TEST_A\n", __func__);
  122. #endif
  123. mutex_lock(&data->alps_lock);
  124. ret = hscd_self_test_A();
  125. mutex_unlock(&data->alps_lock);
  126. if (copy_to_user(argp, &ret, sizeof(ret))) {
  127. pr_err("%s : failed for ALPSIO_ACT_SELF_TEST_A\n",
  128. __func__);
  129. return -EFAULT;
  130. }
  131. break;
  132. case ALPSIO_ACT_SELF_TEST_B:
  133. #ifdef ALPS_DEBUG
  134. pr_debug("%s : ALPSIO_ACT_SELF_TEST_A\n", __func__);
  135. #endif
  136. mutex_lock(&data->alps_lock);
  137. ret = hscd_self_test_B();
  138. mutex_unlock(&data->alps_lock);
  139. if (copy_to_user(argp, &ret, sizeof(ret))) {
  140. pr_err("%s : failed for ALPSIO_ACT_SELF_TEST_B\n",
  141. __func__);
  142. return -EFAULT;
  143. }
  144. break;
  145. default:
  146. return -ENOTTY;
  147. }
  148. return 0;
  149. }
  150. static int alps_io_open(struct inode *inode, struct file *filp)
  151. {
  152. pr_info("alps_io_open\n");
  153. return 0;
  154. }
  155. static int alps_io_release(struct inode *inode, struct file *filp)
  156. {
  157. pr_info("alps_io_release\n");
  158. return 0;
  159. }
  160. static const struct file_operations alps_fops = {
  161. .owner = THIS_MODULE,
  162. .open = alps_io_open,
  163. .release = alps_io_release,
  164. .unlocked_ioctl = alps_ioctl,
  165. };
  166. /*static void accsns_poll(struct input_dev *idev)
  167. {
  168. int xyz[3];
  169. if (accsns_get_acceleration_data(xyz) == 0) {
  170. input_report_abs(idev, EVENT_TYPE_ACCEL_X, xyz[0]);
  171. input_report_abs(idev, EVENT_TYPE_ACCEL_Y, xyz[1]);
  172. input_report_abs(idev, EVENT_TYPE_ACCEL_Z, xyz[2]);
  173. idev->sync = 0;
  174. input_event(idev, EV_SYN, SYN_REPORT, 1);
  175. }
  176. }
  177. */
  178. static void hscd_poll(struct alps_data *data)
  179. {
  180. int xyz[3];
  181. struct input_dev * idev = data->alps_idev->input;
  182. if (hscd_get_magnetic_field_data(xyz) == 0) {
  183. remap_sensor_data_32(xyz, data->position);
  184. input_report_abs(idev, EVENT_TYPE_MAG_X, xyz[0]);
  185. input_report_abs(idev, EVENT_TYPE_MAG_Y, xyz[1]);
  186. input_report_abs(idev, EVENT_TYPE_MAG_Z, xyz[2]);
  187. idev->sync = 0;
  188. input_event(idev, EV_SYN, SYN_REPORT, 2);
  189. }
  190. }
  191. static void alps_poll(struct input_polled_dev *dev)
  192. {
  193. struct alps_data *data = dev->private;
  194. if (!data->suspend_flag) {
  195. mutex_lock(&data->alps_lock);
  196. data->alps_idev->poll_interval = data->delay;
  197. if (data->flgM)
  198. hscd_poll(data);
  199. /* if (data->flgA)
  200. accsns_poll(data->alps_idev->input);*/
  201. mutex_unlock(&data->alps_lock);
  202. }
  203. }
  204. #ifdef CONFIG_OF
  205. static struct of_device_id alps_match_table[] = {
  206. {.compatible = "alps-input",},
  207. {},
  208. };
  209. #else
  210. #define magnetic_match_table NULL
  211. #endif
  212. #ifdef CONFIG_OF
  213. /* device tree parsing */
  214. static int alps_parse_dt(struct device *dev, struct alps_data *data)
  215. {
  216. struct device_node *np = dev->of_node;
  217. if (of_property_read_u32(np, "alps,mag-position", &data->position))
  218. data->position = 0;
  219. pr_info("%s position %d", __func__, data->position);
  220. return 0;
  221. }
  222. #else
  223. static int alps_parse_dt(struct device *dev, struct alps_data *data)
  224. {
  225. data->position = 0;
  226. return -ENODEV;
  227. }
  228. #endif
  229. static int alps_probe(struct platform_device *dev)
  230. {
  231. int ret;
  232. struct alps_data *data;
  233. struct input_dev *idev;
  234. pr_info("alps: alps_probe\n");
  235. data = kzalloc(sizeof(*data), GFP_KERNEL);
  236. if (data == NULL) {
  237. pr_err("%s, failed to alloc memory for module data\n",
  238. __func__);
  239. ret = -ENOMEM;
  240. goto exit;
  241. }
  242. mutex_init(&data->alps_lock);
  243. data->pdev = platform_device_register_simple("alps", -1, NULL, 0);
  244. if (IS_ERR(data->pdev)) {
  245. ret = PTR_ERR(data->pdev);
  246. goto out_driver;
  247. }
  248. data->alps_idev = input_allocate_polled_device();
  249. if (data->alps_idev == NULL) {
  250. ret = -ENOMEM;
  251. goto out_device;
  252. }
  253. if (alps_parse_dt(&dev->dev, data))
  254. pr_err("ALPS parse for position failed");
  255. data->alps_idev->poll = alps_poll;
  256. data->alps_idev->poll_interval = ALPS_POLL_INTERVAL;
  257. data->alps_idev->private = data;
  258. /* initialize the input class */
  259. idev = data->alps_idev->input;
  260. idev->name = "magnetic_sensor";
  261. idev->phys = "alps/input0";
  262. idev->id.bustype = BUS_HOST;
  263. idev->dev.parent = &data->pdev->dev;
  264. idev->evbit[0] = BIT_MASK(EV_ABS);
  265. /* 12-bit output (BMA254) with +/- 2g range */
  266. input_set_abs_params(idev, EVENT_TYPE_ACCEL_X,
  267. 2048, 2047, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
  268. input_set_abs_params(idev, EVENT_TYPE_ACCEL_Y,
  269. 2048, 2047, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
  270. input_set_abs_params(idev, EVENT_TYPE_ACCEL_Z,
  271. 2048, 2047, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
  272. /* 15-bit output (HSCDTD008A) */
  273. input_set_abs_params(idev, EVENT_TYPE_MAG_X,
  274. -16384, 16383, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
  275. input_set_abs_params(idev, EVENT_TYPE_MAG_Y,
  276. -16384, 16383, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
  277. input_set_abs_params(idev, EVENT_TYPE_MAG_Z,
  278. -16384, 16383, ALPS_INPUT_FUZZ, ALPS_INPUT_FLAT);
  279. ret = input_register_polled_device(data->alps_idev);
  280. if (ret)
  281. goto out_idev;
  282. data->alps_device.minor = MISC_DYNAMIC_MINOR;
  283. data->alps_device.name = "alps_io";
  284. data->alps_device.fops = &alps_fops;
  285. ret = misc_register(&data->alps_device);
  286. if (ret)
  287. goto exit_misc_device_register_failed;
  288. #ifdef CONFIG_HAS_EARLYSUSPEND
  289. data->alps_early_suspend_handler.suspend = alps_early_suspend;
  290. data->alps_early_suspend_handler.resume = alps_early_resume;
  291. register_early_suspend(&data->alps_early_suspend_handler);
  292. #endif
  293. ret = sensors_create_symlink(&idev->dev.kobj, idev->name);
  294. if (ret < 0) {
  295. printk("failed to create symlink\n");
  296. return ret;
  297. }
  298. #ifdef CONFIG_SENSOR_USE_SYMLINK
  299. error = sensors_initialize_symlink(idev);
  300. if (error < 0) {
  301. input_free_device(idev);
  302. return error;
  303. }
  304. #endif
  305. mutex_lock(&data->alps_lock);
  306. data->flgA = 0;
  307. data->flgM = 0;
  308. data->delay = 200;
  309. data->suspend_flag = OFF;
  310. mutex_unlock(&data->alps_lock);
  311. platform_set_drvdata(dev,data);
  312. pr_info("%s: success.\n", __func__);
  313. return 0;
  314. exit_misc_device_register_failed:
  315. input_unregister_polled_device(data->alps_idev);
  316. out_idev:
  317. input_free_polled_device(data->alps_idev);
  318. out_device:
  319. platform_device_unregister(data->pdev);
  320. out_driver:
  321. mutex_destroy(&data->alps_lock);
  322. kfree(data);
  323. exit:
  324. pr_err("%s: failed!\n", __func__);
  325. return ret;
  326. }
  327. static int alps_remove(struct platform_device *dev)
  328. {
  329. struct alps_data *data = platform_get_drvdata(dev);
  330. #ifdef CONFIG_HAS_EARLYSUSPEND
  331. unregister_early_suspend(&data->alps_early_suspend_handler);
  332. #endif
  333. misc_deregister(&data->alps_device);
  334. input_unregister_polled_device(data->alps_idev);
  335. input_free_polled_device(data->alps_idev);
  336. platform_device_unregister(data->pdev);
  337. mutex_destroy(&data->alps_lock);
  338. kfree(data);
  339. return 0;
  340. }
  341. static int alps_suspend(struct device *dev)
  342. {
  343. struct platform_device *pdev = to_platform_device(dev);
  344. struct alps_data *data = platform_get_drvdata(pdev);
  345. mutex_lock(&data->alps_lock);
  346. data->suspend_flag = ON;
  347. mutex_unlock(&data->alps_lock);
  348. return 0;
  349. }
  350. static int alps_resume(struct device *dev)
  351. {
  352. struct platform_device *pdev = to_platform_device(dev);
  353. struct alps_data *data = platform_get_drvdata(pdev);
  354. mutex_lock(&data->alps_lock);
  355. data->suspend_flag = OFF;
  356. mutex_unlock(&data->alps_lock);
  357. return 0;
  358. }
  359. #ifdef CONFIG_HAS_EARLYSUSPEND
  360. static void alps_early_suspend(struct early_suspend *handler)
  361. {
  362. struct alps_data *data;
  363. data = container_of(handler, struct alps_data,
  364. alps_early_suspend_handler);
  365. mutex_lock(&data->alps_lock);
  366. data->suspend_flag = ON;
  367. mutex_unlock(&data->alps_lock);
  368. }
  369. static void alps_early_resume(struct early_suspend *handler)
  370. {
  371. struct alps_data *data;
  372. data = container_of(handler, struct alps_data,
  373. alps_early_suspend_handler);
  374. mutex_lock(&data->alps_lock);
  375. data->suspend_flag = OFF;
  376. mutex_unlock(&data->alps_lock);
  377. }
  378. #endif
  379. static const struct dev_pm_ops alps_pm_ops = {
  380. .suspend = alps_suspend,
  381. .resume = alps_resume
  382. };
  383. static struct platform_driver alps_driver = {
  384. .driver = {
  385. #ifndef CONFIG_HAS_EARLYSUSPEND
  386. .pm = &alps_pm_ops,
  387. #endif
  388. .name = "alps-input",
  389. .owner = THIS_MODULE,
  390. .of_match_table = alps_match_table,
  391. },
  392. .probe = alps_probe,
  393. .remove = alps_remove,
  394. };
  395. static int __init alps_init(void)
  396. {
  397. return platform_driver_register(&alps_driver);
  398. }
  399. static void __exit alps_exit(void)
  400. {
  401. platform_driver_unregister(&alps_driver);
  402. }
  403. module_init(alps_init);
  404. module_exit(alps_exit);
  405. MODULE_DESCRIPTION("Alps Input Device");
  406. MODULE_AUTHOR("ALPS");
  407. MODULE_LICENSE("GPL v2");