ssp_c12sd.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. /*
  2. * drivers/sensorhub/ssp_c12sd.c
  3. * Copyright (c) 2012 SAMSUNG ELECTRONICS
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  18. * MA 02110-1301, USA.
  19. */
  20. #include <linux/module.h>
  21. #include <linux/wakelock.h>
  22. #include <linux/workqueue.h>
  23. #include <linux/delay.h>
  24. #include <linux/types.h>
  25. #include <linux/input.h>
  26. #include <linux/platform_device.h>
  27. #include <linux/errno.h>
  28. #include <linux/hrtimer.h>
  29. #include <linux/err.h>
  30. #include <linux/gpio.h>
  31. #include <linux/gpio_event.h>
  32. #include <linux/device.h>
  33. #include <linux/slab.h>
  34. #include <linux/earlysuspend.h>
  35. #include <linux/sensor/guva_c12sd.h>
  36. #include "ssp.h"
  37. #define VENDOR_NAME "GENICOM"
  38. #define CHIP_NAME "GUVA-C12SD"
  39. #ifdef CONFIG_HAS_EARLYSUSPEND
  40. /* early suspend */
  41. static void ssp_early_suspend(struct early_suspend *handler);
  42. static void ssp_late_resume(struct early_suspend *handler);
  43. #endif
  44. struct uv_info {
  45. struct uv_platform_data *pdata;
  46. struct workqueue_struct *uv_wq;
  47. struct work_struct work_uv;
  48. struct device *uv_dev;
  49. struct hrtimer uv_timer;
  50. struct mutex power_lock;
  51. struct mutex read_lock;
  52. struct input_dev *uv_input_dev;
  53. #ifdef CONFIG_HAS_EARLYSUSPEND
  54. struct early_suspend early_suspend;
  55. #endif
  56. ktime_t uv_poll_delay;
  57. int uv_raw_data;
  58. bool onoff;
  59. };
  60. /* sysfs for input device */
  61. static ssize_t uv_poll_delay_show(struct device *dev,
  62. struct device_attribute *attr, char *buf)
  63. {
  64. struct uv_info *uv = dev_get_drvdata(dev);
  65. return snprintf(buf, PAGE_SIZE, "%lld\n",
  66. ktime_to_ns(uv->uv_poll_delay));
  67. }
  68. static ssize_t uv_poll_delay_store(struct device *dev,
  69. struct device_attribute *attr,
  70. const char *buf, size_t size)
  71. {
  72. struct uv_info *uv = dev_get_drvdata(dev);
  73. int64_t new_delay;
  74. int err;
  75. err = kstrtoll(buf, 10, &new_delay);
  76. if (err < 0)
  77. return err;
  78. mutex_lock(&uv->power_lock);
  79. if (uv->onoff) {
  80. hrtimer_cancel(&uv->uv_timer);
  81. cancel_work_sync(&uv->work_uv);
  82. }
  83. if (new_delay != ktime_to_ns(uv->uv_poll_delay)) {
  84. uv->uv_poll_delay = ns_to_ktime(new_delay);
  85. pr_info("%s, poll_delay = %lld\n", __func__, new_delay);
  86. }
  87. if (uv->onoff)
  88. hrtimer_start(&uv->uv_timer, uv->uv_poll_delay,
  89. HRTIMER_MODE_REL);
  90. mutex_unlock(&uv->power_lock);
  91. return size;
  92. }
  93. static ssize_t uv_enable_store(struct device *dev,
  94. struct device_attribute *attr,
  95. const char *buf, size_t size)
  96. {
  97. struct uv_info *uv = dev_get_drvdata(dev);
  98. bool new_value;
  99. if (sysfs_streq(buf, "1")) {
  100. new_value = true;
  101. } else if (sysfs_streq(buf, "0")) {
  102. new_value = false;
  103. } else {
  104. pr_err("%s: invalid value %d\n", __func__, *buf);
  105. return -EINVAL;
  106. }
  107. pr_info("%s, old = %d, new = %d\n", __func__, uv->onoff, new_value);
  108. mutex_lock(&uv->power_lock);
  109. if (new_value && !uv->onoff) { /* Enable */
  110. uv->onoff = new_value;
  111. if (uv->pdata->power_on)
  112. uv->pdata->power_on(uv->onoff);
  113. hrtimer_start(&uv->uv_timer, uv->uv_poll_delay,
  114. HRTIMER_MODE_REL);
  115. } else if (!new_value && uv->onoff) { /* Disable */
  116. hrtimer_cancel(&uv->uv_timer);
  117. uv->onoff = new_value;
  118. if (uv->pdata->power_on)
  119. uv->pdata->power_on(uv->onoff);
  120. } else
  121. pr_err("%s, new_enable = %d\n", __func__, new_value);
  122. mutex_unlock(&uv->power_lock);
  123. return size;
  124. }
  125. static ssize_t uv_enable_show(struct device *dev,
  126. struct device_attribute *attr, char *buf)
  127. {
  128. struct uv_info *uv = dev_get_drvdata(dev);
  129. return snprintf(buf, PAGE_SIZE, "%d\n", uv->onoff);
  130. }
  131. static DEVICE_ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
  132. uv_poll_delay_show, uv_poll_delay_store);
  133. static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
  134. uv_enable_show, uv_enable_store);
  135. static struct attribute *uv_sysfs_attrs[] = {
  136. &dev_attr_enable.attr,
  137. &dev_attr_poll_delay.attr,
  138. NULL
  139. };
  140. static struct attribute_group uv_attribute_group = {
  141. .attrs = uv_sysfs_attrs,
  142. };
  143. /* sysfs for uv sensor class */
  144. static ssize_t get_vendor_name(struct device *dev,
  145. struct device_attribute *attr, char *buf)
  146. {
  147. return snprintf(buf, PAGE_SIZE, "%s\n", VENDOR_NAME);
  148. }
  149. static ssize_t get_chip_name(struct device *dev,
  150. struct device_attribute *attr, char *buf)
  151. {
  152. return snprintf(buf, PAGE_SIZE, "%s\n", CHIP_NAME);
  153. }
  154. static ssize_t get_adc_value(struct device *dev,
  155. struct device_attribute *attr, char *buf)
  156. {
  157. struct uv_info *uv = dev_get_drvdata(dev);
  158. int adc = 0;
  159. /* If power is not turned on, it won't work. */
  160. if (!uv->onoff) {
  161. mutex_lock(&uv->read_lock);
  162. if (uv->pdata->power_on)
  163. uv->pdata->power_on(true);
  164. mdelay(20);
  165. adc = uv->pdata->get_adc_value();
  166. if (uv->pdata->power_on)
  167. uv->pdata->power_on(false);
  168. mutex_unlock(&uv->read_lock);
  169. } else
  170. adc = uv->uv_raw_data;
  171. pr_info("%s: uv_adc = 0x%x, (%dmV)\n", __func__, adc, adc / 1000);
  172. return snprintf(buf, PAGE_SIZE, "%d\n", adc);
  173. }
  174. static ssize_t uv_power_on(struct device *dev,
  175. struct device_attribute *attr, char *buf)
  176. {
  177. struct uv_info *uv = dev_get_drvdata(dev);
  178. if (!uv->onoff && uv->pdata->power_on)
  179. uv->pdata->power_on(true);
  180. pr_info("%s\n", __func__);
  181. return sprintf(buf, "%d\n", 1);
  182. }
  183. static ssize_t uv_power_off(struct device *dev,
  184. struct device_attribute *attr, char *buf)
  185. {
  186. struct uv_info *uv = dev_get_drvdata(dev);
  187. if (!uv->onoff && uv->pdata->power_on)
  188. uv->pdata->power_on(false);
  189. pr_info("%s\n", __func__);
  190. return sprintf(buf, "%d\n", 1);
  191. }
  192. static DEVICE_ATTR(vendor, S_IRUGO, get_vendor_name, NULL);
  193. static DEVICE_ATTR(name, S_IRUGO, get_chip_name, NULL);
  194. static DEVICE_ATTR(raw_data, S_IRUGO, get_adc_value, NULL);
  195. static DEVICE_ATTR(power_on, S_IRUGO, uv_power_on, NULL);
  196. static DEVICE_ATTR(power_off, S_IRUGO, uv_power_off, NULL);
  197. static struct device_attribute *uv_sensor_attrs[] = {
  198. &dev_attr_vendor,
  199. &dev_attr_name,
  200. &dev_attr_raw_data,
  201. &dev_attr_power_on,
  202. &dev_attr_power_off,
  203. NULL
  204. };
  205. /* timer function for uv sensor polling */
  206. static enum hrtimer_restart uv_timer_func(struct hrtimer *timer)
  207. {
  208. struct uv_info *uv
  209. = container_of(timer, struct uv_info, uv_timer);
  210. queue_work(uv->uv_wq, &uv->work_uv);
  211. hrtimer_forward_now(&uv->uv_timer, uv->uv_poll_delay);
  212. return HRTIMER_RESTART;
  213. }
  214. static void work_func_uv(struct work_struct *work)
  215. {
  216. struct uv_info *uv
  217. = container_of(work, struct uv_info, work_uv);
  218. mutex_lock(&uv->read_lock);
  219. uv->uv_raw_data = uv->pdata->get_adc_value();
  220. mutex_unlock(&uv->read_lock);
  221. input_report_rel(uv->uv_input_dev, REL_MISC, uv->uv_raw_data+1);
  222. input_sync(uv->uv_input_dev);
  223. }
  224. static int uv_probe(struct platform_device *pdev)
  225. {
  226. struct uv_info *uv;
  227. struct uv_platform_data *pdata = pdev->dev.platform_data;
  228. int ret = 0;
  229. pr_info("%s: is started\n", __func__);
  230. if (!pdata) {
  231. pr_err("%s: pdata is NULL\n", __func__);
  232. return -ENODEV;
  233. }
  234. if (!pdata->get_adc_value || !pdata->power_on) {
  235. pr_err("%s: need to check pdata\n", __func__);
  236. return -ENODEV;
  237. }
  238. /* allocate memory */
  239. uv = kzalloc(sizeof(struct uv_info), GFP_KERNEL);
  240. if (uv == NULL) {
  241. pr_err("%s: Failed to allocate memory\n", __func__);
  242. return -ENOMEM;
  243. }
  244. uv->pdata = pdata;
  245. if (pdata->power_on) {
  246. uv->pdata->power_on = pdata->power_on;
  247. uv->pdata->power_on(false);
  248. }
  249. uv->onoff = false;
  250. if (pdata->get_adc_value)
  251. uv->pdata->get_adc_value = pdata->get_adc_value;
  252. mutex_init(&uv->power_lock);
  253. mutex_init(&uv->read_lock);
  254. /* allocate uv input device */
  255. uv->uv_input_dev = input_allocate_device();
  256. if (!uv->uv_input_dev) {
  257. pr_err("%s: could not allocate input device\n",
  258. __func__);
  259. goto err_input_allocate_device_uv;
  260. }
  261. input_set_drvdata(uv->uv_input_dev, uv);
  262. uv->uv_input_dev->name = "uv_sensor";
  263. input_set_capability(uv->uv_input_dev, EV_REL, REL_MISC);
  264. ret = input_register_device(uv->uv_input_dev);
  265. if (ret < 0) {
  266. pr_err("%s: could not register input device\n",
  267. __func__);
  268. input_free_device(uv->uv_input_dev);
  269. goto err_input_register_device_uv;
  270. }
  271. ret = sysfs_create_group(&uv->uv_input_dev->dev.kobj,
  272. &uv_attribute_group);
  273. if (ret) {
  274. pr_err("%s: could not create sysfs group\n",
  275. __func__);
  276. goto err_sysfs_create_group_uv;
  277. }
  278. /* timer init */
  279. hrtimer_init(&uv->uv_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  280. uv->uv_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
  281. uv->uv_timer.function = uv_timer_func;
  282. /* workqueue init */
  283. uv->uv_wq = create_singlethread_workqueue("uv_wq");
  284. if (!uv->uv_wq) {
  285. ret = -ENOMEM;
  286. pr_err("%s: could not create uv workqueue\n",
  287. __func__);
  288. goto err_create_uv_workqueue;
  289. }
  290. INIT_WORK(&uv->work_uv, work_func_uv);
  291. /* sysfs for uv sensor */
  292. ret = sensors_register(uv->uv_dev, uv, uv_sensor_attrs,
  293. "uv_sensor");
  294. if (ret) {
  295. pr_err("%s: could not register uv device(%d)\n",
  296. __func__, ret);
  297. goto err_sensor_register_failed;
  298. }
  299. ret = sensors_create_symlink(&uv->uv_input_dev->dev.kobj,
  300. uv->uv_input_dev->name);
  301. if (ret < 0) {
  302. pr_err("%s, sensors_create_symlinks failed!(%d)\n",
  303. __func__, ret);
  304. goto err_uv_input__sysfs_create_link;
  305. }
  306. #ifdef CONFIG_HAS_EARLYSUSPEND
  307. uv->early_suspend.suspend = ssp_early_suspend;
  308. uv->early_suspend.resume = ssp_late_resume;
  309. register_early_suspend(&uv->early_suspend);
  310. #endif
  311. platform_set_drvdata(pdev, uv);
  312. pr_info("%s, success\n", __func__);
  313. return 0;
  314. err_uv_input__sysfs_create_link:
  315. sensors_unregister(uv->uv_dev, uv_sensor_attrs);
  316. err_sensor_register_failed:
  317. destroy_workqueue(uv->uv_wq);
  318. err_create_uv_workqueue:
  319. sysfs_remove_group(&uv->uv_input_dev->dev.kobj,
  320. &uv_attribute_group);
  321. err_sysfs_create_group_uv:
  322. input_unregister_device(uv->uv_input_dev);
  323. err_input_register_device_uv:
  324. err_input_allocate_device_uv:
  325. mutex_destroy(&uv->read_lock);
  326. mutex_destroy(&uv->power_lock);
  327. kfree(uv);
  328. return ret;
  329. }
  330. static int uv_remove(struct platform_device *pdev)
  331. {
  332. struct uv_info *uv = dev_get_drvdata(&pdev->dev);
  333. pr_info("%s+\n", __func__);
  334. if (uv->onoff) {
  335. hrtimer_cancel(&uv->uv_timer);
  336. cancel_work_sync(&uv->work_uv);
  337. }
  338. destroy_workqueue(uv->uv_wq);
  339. #ifdef CONFIG_HAS_EARLYSUSPEND
  340. unregister_early_suspend(&uv->early_suspend);
  341. #endif
  342. sensors_unregister(uv->uv_dev, uv_sensor_attrs);
  343. sysfs_remove_group(&uv->uv_input_dev->dev.kobj,
  344. &uv_attribute_group);
  345. input_unregister_device(uv->uv_input_dev);
  346. if (uv->onoff && uv->pdata->power_on)
  347. uv->pdata->power_on(false);
  348. mutex_destroy(&uv->read_lock);
  349. mutex_destroy(&uv->power_lock);
  350. kfree(uv);
  351. pr_info("%s-\n", __func__);
  352. return 0;
  353. }
  354. #ifdef CONFIG_HAS_EARLYSUSPEND
  355. /* early suspend */
  356. static void ssp_early_suspend(struct early_suspend *handler)
  357. {
  358. struct uv_info *uv;
  359. uv = container_of(handler, struct uv_info, early_suspend);
  360. if (uv->onoff) {
  361. hrtimer_cancel(&uv->uv_timer);
  362. cancel_work_sync(&uv->work_uv);
  363. if (uv->pdata->power_on)
  364. uv->pdata->power_on(false);
  365. }
  366. pr_err("%s, enabled = %d\n", __func__, uv->onoff);
  367. }
  368. static void ssp_late_resume(struct early_suspend *handler)
  369. {
  370. struct uv_info *uv;
  371. uv = container_of(handler, struct uv_info, early_suspend);
  372. if (uv->onoff) {
  373. if (uv->pdata->power_on)
  374. uv->pdata->power_on(true);
  375. hrtimer_start(&uv->uv_timer,
  376. uv->uv_poll_delay, HRTIMER_MODE_REL);
  377. }
  378. pr_err("%s, enabled = %d\n", __func__, uv->onoff);
  379. }
  380. #else
  381. static int uv_suspend(struct platform_device *pdev, pm_message_t state)
  382. {
  383. struct uv_info *uv = dev_get_drvdata(&pdev->dev);
  384. if (uv->onoff) {
  385. hrtimer_cancel(&uv->uv_timer);
  386. cancel_work_sync(&uv->work_uv);
  387. if (uv->pdata->power_on)
  388. uv->pdata->power_on(false);
  389. }
  390. pr_err("%s, enabled = %d\n", __func__, uv->onoff);
  391. return 0;
  392. }
  393. static int uv_resume(struct platform_device *pdev)
  394. {
  395. struct uv_info *uv = dev_get_drvdata(&pdev->dev);
  396. if (uv->onoff) {
  397. if (uv->pdata->power_on)
  398. uv->pdata->power_on(true);
  399. hrtimer_start(&uv->uv_timer,
  400. uv->uv_poll_delay, HRTIMER_MODE_REL);
  401. }
  402. pr_err("%s, enabled = %d\n", __func__, uv->onoff);
  403. return 0;
  404. }
  405. #endif
  406. static void uv_shutdown(struct platform_device *pdev)
  407. {
  408. struct uv_info *uv = dev_get_drvdata(&pdev->dev);
  409. pr_info("%s+\n", __func__);
  410. if (uv->onoff) {
  411. hrtimer_cancel(&uv->uv_timer);
  412. cancel_work_sync(&uv->work_uv);
  413. }
  414. destroy_workqueue(uv->uv_wq);
  415. #ifdef CONFIG_HAS_EARLYSUSPEND
  416. unregister_early_suspend(&uv->early_suspend);
  417. #endif
  418. sensors_unregister(uv->uv_dev, uv_sensor_attrs);
  419. sysfs_remove_group(&uv->uv_input_dev->dev.kobj,
  420. &uv_attribute_group);
  421. input_unregister_device(uv->uv_input_dev);
  422. if (uv->onoff && uv->pdata->power_on)
  423. uv->pdata->power_on(false);
  424. mutex_destroy(&uv->power_lock);
  425. kfree(uv);
  426. pr_info("%s-\n", __func__);
  427. }
  428. static struct platform_driver uv_driver = {
  429. .probe = uv_probe,
  430. .remove = uv_remove,
  431. #ifndef CONFIG_HAS_EARLYSUSPEND
  432. .suspend = uv_suspend,
  433. .resume = uv_resume,
  434. #endif
  435. .shutdown = uv_shutdown,
  436. .driver = {
  437. .name = "uv_sensor",
  438. .owner = THIS_MODULE,
  439. },
  440. };
  441. static int __init uv_init(void)
  442. {
  443. return platform_driver_register(&uv_driver);
  444. }
  445. static void __exit uv_exit(void)
  446. {
  447. platform_driver_unregister(&uv_driver);
  448. }
  449. module_init(uv_init);
  450. module_exit(uv_exit);
  451. MODULE_DESCRIPTION("UV sensor device driver");
  452. MODULE_AUTHOR("OHeon Kwon <koh82.kwon@samsung.com>");
  453. MODULE_LICENSE("GPL");