Advertisement
Guest User

Untitled

a guest
Feb 13th, 2015
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.43 KB | None | 0 0
  1. /*
  2. * drivers/input/touchscreen/sweep2wake.c
  3. *
  4. *
  5. * Copyright (c) 2013, Dennis Rassmann <showp1984@gmail.com>
  6. *
  7. * Wake Gestures
  8. * Copyright (c) 2014, Aaron Segaert <asegaert@gmail.com>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful, but WITHOUT
  16. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  18. * more details.
  19. *
  20. * You should have received a copy of the GNU General Public License along
  21. * with this program; if not, write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  23. */
  24.  
  25. #include <linux/kernel.h>
  26. #include <linux/module.h>
  27. #include <linux/types.h>
  28. #include <linux/delay.h>
  29. #include <linux/init.h>
  30. #include <linux/err.h>
  31. #include <linux/input/sweep2wake.h>
  32. #include <linux/slab.h>
  33. #include <linux/workqueue.h>
  34. #include <linux/input.h>
  35. #ifndef CONFIG_HAS_EARLYSUSPEND
  36. #include <linux/lcd_notify.h>
  37. #else
  38. #include <linux/earlysuspend.h>
  39. #endif
  40. #include <linux/hrtimer.h>
  41.  
  42. /* uncomment since no touchscreen defines android touch, do that here */
  43. //#define ANDROID_TOUCH_DECLARED
  44.  
  45. /* Version, author, desc, etc */
  46. #define DRIVER_AUTHOR "Dennis Rassmann <showp1984@gmail.com>"
  47. #define DRIVER_DESCRIPTION "Sweep2wake for almost any device"
  48. #define DRIVER_VERSION "1.5"
  49. #define LOGTAG "[sweep2wake]: "
  50.  
  51. MODULE_AUTHOR(DRIVER_AUTHOR);
  52. MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
  53. MODULE_VERSION(DRIVER_VERSION);
  54. MODULE_LICENSE("GPLv2");
  55.  
  56. /* Tuneables */
  57. #define S2W_DEBUG 0
  58. #define S2W_DEFAULT 0
  59. #define S2W_PWRKEY_DUR 60
  60.  
  61. #ifdef CONFIG_MACH_MSM8974_HAMMERHEAD
  62. /* Hammerhead aka Nexus 5 */
  63. #define S2W_Y_MAX 1920
  64. #define S2W_X_MAX 1080
  65. #define S2W_Y_LIMIT S2W_Y_MAX-130
  66. #define S2W_X_B1 400
  67. #define S2W_X_B2 700
  68. #define S2W_X_FINAL 275
  69. #define S2W_Y_NEXT 180
  70. #else
  71. /* defaults */
  72. #define S2W_Y_LIMIT 2350
  73. #define S2W_X_MAX 1540
  74. #define S2W_X_B1 500
  75. #define S2W_X_B2 1000
  76. #define S2W_X_FINAL 300
  77. #endif
  78.  
  79. /* Wake Gestures */
  80. #define SWEEP_TIMEOUT 30
  81. #define TRIGGER_TIMEOUT 50
  82. #define WAKE_GESTURE 0x0b
  83. #define SWEEP_RIGHT 0x01
  84. #define SWEEP_LEFT 0x02
  85. #define SWEEP_UP 0x04
  86. #define SWEEP_DOWN 0x08
  87. #define VIB_STRENGTH 20
  88.  
  89. int gestures_switch = S2W_DEFAULT;
  90. static struct input_dev *gesture_dev;
  91. extern void gestures_setdev(struct input_dev * input_device);
  92. extern void set_vibrate(int value);
  93. int vib_strength = VIB_STRENGTH;
  94.  
  95. /* Resources */
  96. int s2w_switch = S2W_DEFAULT;
  97. static int s2s_switch = S2W_DEFAULT;
  98. static int touch_x = 0, touch_y = 0;
  99. static bool touch_x_called = false, touch_y_called = false;
  100. static bool scr_suspended = false;
  101. static bool exec_countx = true, exec_county = true;
  102. static bool barrierx[2] = {false, false}, barriery[2] = {false, false};
  103. static int firstx = 0, firsty = 0;
  104. static unsigned long firstx_time = 0, firsty_time = 0;
  105. static unsigned long pwrtrigger_time[2] = {0, 0};
  106. #ifndef CONFIG_HAS_EARLYSUSPEND
  107. static struct notifier_block s2w_lcd_notif;
  108. #endif
  109. static struct input_dev * sweep2wake_pwrdev;
  110. static DEFINE_MUTEX(pwrkeyworklock);
  111. static struct workqueue_struct *s2w_input_wq;
  112. static struct work_struct s2w_input_work;
  113.  
  114. /* Read cmdline for s2w */
  115. static int __init read_s2w_cmdline(char *s2w)
  116. {
  117. if (strcmp(s2w, "1") == 0) {
  118. pr_info("[cmdline_s2w]: Sweep2Wake enabled. | s2w='%s'\n", s2w);
  119. s2w_switch = 1;
  120. } else if (strcmp(s2w, "2") == 0) {
  121. pr_info("[cmdline_s2w]: Sweep2Wake disabled. | s2w='%s'\n", s2w);
  122. s2w_switch = 2;
  123. } else if (strcmp(s2w, "0") == 0) {
  124. pr_info("[cmdline_s2w]: Sweep2Wake disabled. | s2w='%s'\n", s2w);
  125. s2w_switch = 0;
  126. } else {
  127. pr_info("[cmdline_s2w]: No valid input found. Going with default: | s2w='%u'\n", s2w_switch);
  128. }
  129. return 1;
  130. }
  131. __setup("s2w=", read_s2w_cmdline);
  132.  
  133. static void report_gesture(int gest)
  134. {
  135. pwrtrigger_time[1] = pwrtrigger_time[0];
  136. pwrtrigger_time[0] = jiffies;
  137.  
  138. if (pwrtrigger_time[0] - pwrtrigger_time[1] < TRIGGER_TIMEOUT)
  139. return;
  140.  
  141. pr_info(LOGTAG"gesture = %d\n", gest);
  142. input_report_rel(gesture_dev, WAKE_GESTURE, gest);
  143. input_sync(gesture_dev);
  144. }
  145.  
  146. /* PowerKey work func */
  147. static void sweep2wake_presspwr(struct work_struct * sweep2wake_presspwr_work) {
  148. if (!mutex_trylock(&pwrkeyworklock))
  149. return;
  150. input_event(sweep2wake_pwrdev, EV_KEY, KEY_POWER, 1);
  151. input_event(sweep2wake_pwrdev, EV_SYN, 0, 0);
  152. msleep(S2W_PWRKEY_DUR);
  153. input_event(sweep2wake_pwrdev, EV_KEY, KEY_POWER, 0);
  154. input_event(sweep2wake_pwrdev, EV_SYN, 0, 0);
  155. msleep(S2W_PWRKEY_DUR);
  156. mutex_unlock(&pwrkeyworklock);
  157. return;
  158. }
  159. static DECLARE_WORK(sweep2wake_presspwr_work, sweep2wake_presspwr);
  160.  
  161. /* PowerKey trigger */
  162. static void sweep2wake_pwrtrigger(void) {
  163. pwrtrigger_time[1] = pwrtrigger_time[0];
  164. pwrtrigger_time[0] = jiffies;
  165.  
  166. if (pwrtrigger_time[0] - pwrtrigger_time[1] < TRIGGER_TIMEOUT)
  167. return;
  168.  
  169. schedule_work(&sweep2wake_presspwr_work);
  170. return;
  171. }
  172.  
  173. /* reset on finger release */
  174. static void sweep2wake_reset(void) {
  175. exec_countx = true;
  176. barrierx[0] = false;
  177. barrierx[1] = false;
  178. firstx = 0;
  179. firstx_time = 0;
  180.  
  181. exec_county = true;
  182. barriery[0] = false;
  183. barriery[1] = false;
  184. firsty = 0;
  185. firsty_time = 0;
  186. }
  187.  
  188. /* Sweep2wake main function */
  189. static void detect_sweep2wake_v(int x, int y, bool st)
  190. {
  191. int prevy = 0, nexty = 0;
  192. bool single_touch = st;
  193.  
  194. if (firsty == 0) {
  195. firsty = y;
  196. firsty_time = jiffies;
  197. }
  198.  
  199. if (x > 100 && x < 980) {
  200. //up
  201. if (firsty > 960 && single_touch && (s2w_switch & SWEEP_UP)) {
  202. prevy = firsty;
  203. nexty = prevy - S2W_Y_NEXT;
  204. if (barriery[0] == true || (y < prevy && y > nexty)) {
  205. prevy = nexty;
  206. nexty -= S2W_Y_NEXT;
  207. barriery[0] = true;
  208. if (barriery[1] == true || (y < prevy && y > nexty)) {
  209. prevy = nexty;
  210. barriery[1] = true;
  211. if (y < prevy) {
  212. if (y < (nexty - S2W_Y_NEXT)) {
  213. if (exec_county && (jiffies - firsty_time < SWEEP_TIMEOUT)) {
  214. pr_info(LOGTAG"sweep up\n");
  215. set_vibrate(vib_strength);
  216. if (gestures_switch) {
  217. report_gesture(3);
  218. } else {
  219. sweep2wake_pwrtrigger();
  220. }
  221. exec_county = false;
  222. }
  223. }
  224. }
  225. }
  226. }
  227. //down
  228. } else if (firsty <= 960 && single_touch && (s2w_switch & SWEEP_DOWN)) {
  229. prevy = firsty;
  230. nexty = prevy + S2W_Y_NEXT;
  231. if (barriery[0] == true || (y > prevy && y < nexty)) {
  232. prevy = nexty;
  233. nexty += S2W_Y_NEXT;
  234. barriery[0] = true;
  235. if (barriery[1] == true || (y > prevy && y < nexty)) {
  236. prevy = nexty;
  237. barriery[1] = true;
  238. if (y > prevy) {
  239. if (y > (nexty + S2W_Y_NEXT)) {
  240. if (exec_county && (jiffies - firsty_time < SWEEP_TIMEOUT)) {
  241. pr_info(LOGTAG"sweep down\n");
  242. set_vibrate(vib_strength);
  243. if (gestures_switch) {
  244. report_gesture(4);
  245. } else {
  246. sweep2wake_pwrtrigger();
  247. }
  248. exec_county = false;
  249. }
  250. }
  251. }
  252. }
  253. }
  254. }
  255. }
  256. }
  257.  
  258. static void detect_sweep2wake_h(int x, int y, bool st, bool wake)
  259. {
  260. int prevx = 0, nextx = 0;
  261. bool single_touch = st;
  262.  
  263. if (firstx == 0) {
  264. firstx = x;
  265. firstx_time = jiffies;
  266. }
  267.  
  268. if (!wake && y < S2W_Y_LIMIT) {
  269. sweep2wake_reset();
  270. return;
  271. }
  272. #if S2W_DEBUG
  273. pr_info(LOGTAG"x,y(%4d,%4d) single:%s\n",
  274. x, y, (single_touch) ? "true" : "false");
  275. #endif
  276. //left->right
  277. if (firstx < 510 && single_touch &&
  278. ((wake && (s2w_switch & SWEEP_RIGHT)) || (!wake && (s2s_switch & SWEEP_RIGHT)))) {
  279. prevx = 0;
  280. nextx = S2W_X_B1;
  281. if ((barrierx[0] == true) ||
  282. ((x > prevx) && (x < nextx))) {
  283. prevx = nextx;
  284. nextx = S2W_X_B2;
  285. barrierx[0] = true;
  286. if ((barrierx[1] == true) ||
  287. ((x > prevx) && (x < nextx))) {
  288. prevx = nextx;
  289. barrierx[1] = true;
  290. if (x > prevx) {
  291. if (x > (S2W_X_MAX - S2W_X_FINAL)) {
  292. if (exec_countx && (jiffies - firstx_time < SWEEP_TIMEOUT)) {
  293. pr_info(LOGTAG"sweep right\n");
  294. set_vibrate(vib_strength);
  295. if (gestures_switch && wake) {
  296. report_gesture(1);
  297. } else {
  298. sweep2wake_pwrtrigger();
  299. }
  300. exec_countx = false;
  301. }
  302. }
  303. }
  304. }
  305. }
  306. //right->left
  307. } else if (firstx >= 510 && single_touch &&
  308. ((wake && (s2w_switch & SWEEP_LEFT)) || (!wake && (s2s_switch & SWEEP_LEFT)))) {
  309. prevx = (S2W_X_MAX - S2W_X_FINAL);
  310. nextx = S2W_X_B2;
  311. if ((barrierx[0] == true) ||
  312. ((x < prevx) && (x > nextx))) {
  313. prevx = nextx;
  314. nextx = S2W_X_B1;
  315. barrierx[0] = true;
  316. if ((barrierx[1] == true) ||
  317. ((x < prevx) && (x > nextx))) {
  318. prevx = nextx;
  319. barrierx[1] = true;
  320. if (x < prevx) {
  321. if (x < S2W_X_FINAL) {
  322. if (exec_countx) {
  323. pr_info(LOGTAG"sweep left\n");
  324. set_vibrate(vib_strength);
  325. if (gestures_switch && wake) {
  326. report_gesture(2);
  327. } else {
  328. sweep2wake_pwrtrigger();
  329. }
  330. exec_countx = false;
  331. }
  332. }
  333. }
  334. }
  335. }
  336. }
  337. }
  338.  
  339. static void s2w_input_callback(struct work_struct *unused) {
  340.  
  341. detect_sweep2wake_h(touch_x, touch_y, true, scr_suspended);
  342. if (scr_suspended)
  343. detect_sweep2wake_v(touch_x, touch_y, true);
  344.  
  345. return;
  346. }
  347.  
  348. static void s2w_input_event(struct input_handle *handle, unsigned int type,
  349. unsigned int code, int value) {
  350. #if S2W_DEBUG
  351. pr_info("sweep2wake: code: %s|%u, val: %i\n",
  352. ((code==ABS_MT_POSITION_X) ? "X" :
  353. (code==ABS_MT_POSITION_Y) ? "Y" :
  354. (code==ABS_MT_TRACKING_ID) ? "ID" :
  355. "undef"), code, value);
  356. #endif
  357. if (code == ABS_MT_SLOT) {
  358. sweep2wake_reset();
  359. return;
  360. }
  361.  
  362. if (code == ABS_MT_TRACKING_ID && value == -1) {
  363. sweep2wake_reset();
  364. return;
  365. }
  366.  
  367. if (code == ABS_MT_POSITION_X) {
  368. touch_x = value;
  369. touch_x_called = true;
  370. }
  371.  
  372. if (code == ABS_MT_POSITION_Y) {
  373. touch_y = value;
  374. touch_y_called = true;
  375. }
  376.  
  377. if (touch_x_called && touch_y_called) {
  378. touch_x_called = false;
  379. touch_y_called = false;
  380. queue_work_on(0, s2w_input_wq, &s2w_input_work);
  381. } else if (!scr_suspended && touch_x_called && !touch_y_called) {
  382. touch_x_called = false;
  383. touch_y_called = false;
  384. queue_work_on(0, s2w_input_wq, &s2w_input_work);
  385. }
  386. }
  387.  
  388. static int input_dev_filter(struct input_dev *dev) {
  389. if (strstr(dev->name, "touch")) {
  390. return 0;
  391. } else {
  392. return 1;
  393. }
  394. }
  395.  
  396. static int s2w_input_connect(struct input_handler *handler,
  397. struct input_dev *dev, const struct input_device_id *id) {
  398. struct input_handle *handle;
  399. int error;
  400.  
  401. if (input_dev_filter(dev))
  402. return -ENODEV;
  403.  
  404. handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
  405. if (!handle)
  406. return -ENOMEM;
  407.  
  408. handle->dev = dev;
  409. handle->handler = handler;
  410. handle->name = "s2w";
  411.  
  412. error = input_register_handle(handle);
  413. if (error)
  414. goto err2;
  415.  
  416. error = input_open_device(handle);
  417. if (error)
  418. goto err1;
  419.  
  420. return 0;
  421. err1:
  422. input_unregister_handle(handle);
  423. err2:
  424. kfree(handle);
  425. return error;
  426. }
  427.  
  428. static void s2w_input_disconnect(struct input_handle *handle) {
  429. input_close_device(handle);
  430. input_unregister_handle(handle);
  431. kfree(handle);
  432. }
  433.  
  434. static const struct input_device_id s2w_ids[] = {
  435. { .driver_info = 1 },
  436. { },
  437. };
  438.  
  439. static struct input_handler s2w_input_handler = {
  440. .event = s2w_input_event,
  441. .connect = s2w_input_connect,
  442. .disconnect = s2w_input_disconnect,
  443. .name = "s2w_inputreq",
  444. .id_table = s2w_ids,
  445. };
  446.  
  447. #ifndef CONFIG_HAS_EARLYSUSPEND
  448. static int lcd_notifier_callback(struct notifier_block *this,
  449. unsigned long event, void *data)
  450. {
  451. switch (event) {
  452. case LCD_EVENT_ON_END:
  453. scr_suspended = false;
  454. break;
  455. case LCD_EVENT_OFF_END:
  456. scr_suspended = true;
  457. break;
  458. default:
  459. break;
  460. }
  461.  
  462. return 0;
  463. }
  464. #else
  465. static void s2w_early_suspend(struct early_suspend *h) {
  466. scr_suspended = true;
  467. }
  468.  
  469. static void s2w_late_resume(struct early_suspend *h) {
  470. scr_suspended = false;
  471. }
  472.  
  473. static struct early_suspend s2w_early_suspend_handler = {
  474. .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
  475. .suspend = s2w_early_suspend,
  476. .resume = s2w_late_resume,
  477. };
  478. #endif
  479.  
  480. /*
  481. * SYSFS stuff below here
  482. */
  483. static ssize_t s2w_sweep2wake_show(struct device *dev,
  484. struct device_attribute *attr, char *buf)
  485. {
  486. size_t count = 0;
  487.  
  488. count += sprintf(buf, "%d\n", s2w_switch);
  489.  
  490. return count;
  491. }
  492.  
  493. static ssize_t s2w_sweep2wake_dump(struct device *dev,
  494. struct device_attribute *attr, const char *buf, size_t count)
  495. {
  496. sscanf(buf, "%d ", &s2w_switch);
  497. if (s2w_switch < 0 || s2w_switch > 15)
  498. s2w_switch = 15;
  499.  
  500. return count;
  501. }
  502.  
  503. static DEVICE_ATTR(sweep2wake, (S_IWUSR|S_IRUGO),
  504. s2w_sweep2wake_show, s2w_sweep2wake_dump);
  505.  
  506. static ssize_t sweep2sleep_show(struct device *dev,
  507. struct device_attribute *attr, char *buf)
  508. {
  509. size_t count = 0;
  510. count += sprintf(buf, "%d\n", s2s_switch);
  511. return count;
  512. }
  513.  
  514. static ssize_t sweep2sleep_dump(struct device *dev,
  515. struct device_attribute *attr, const char *buf, size_t count)
  516. {
  517. if (buf[0] >= '0' && buf[0] <= '3' && buf[1] == '\n')
  518. if (s2s_switch != buf[0] - '0')
  519. s2s_switch = buf[0] - '0';
  520. return count;
  521. }
  522.  
  523. static DEVICE_ATTR(sweep2sleep, (S_IWUSR|S_IRUGO),
  524. sweep2sleep_show, sweep2sleep_dump);
  525.  
  526. static ssize_t s2w_version_show(struct device *dev,
  527. struct device_attribute *attr, char *buf)
  528. {
  529. size_t count = 0;
  530.  
  531. count += sprintf(buf, "%s\n", DRIVER_VERSION);
  532.  
  533. return count;
  534. }
  535.  
  536. static ssize_t s2w_version_dump(struct device *dev,
  537. struct device_attribute *attr, const char *buf, size_t count)
  538. {
  539. return count;
  540. }
  541.  
  542. static DEVICE_ATTR(sweep2wake_version, (S_IWUSR|S_IRUGO),
  543. s2w_version_show, s2w_version_dump);
  544.  
  545. static ssize_t wake_gestures_show(struct device *dev,
  546. struct device_attribute *attr, char *buf)
  547. {
  548. size_t count = 0;
  549. count += sprintf(buf, "%d\n", gestures_switch);
  550. return count;
  551. }
  552.  
  553. static ssize_t wake_gestures_dump(struct device *dev,
  554. struct device_attribute *attr, const char *buf, size_t count)
  555. {
  556. if (buf[0] >= '0' && buf[0] <= '1' && buf[1] == '\n')
  557. if (gestures_switch != buf[0] - '0')
  558. gestures_switch = buf[0] - '0';
  559. return count;
  560. }
  561.  
  562. static DEVICE_ATTR(wake_gestures, (S_IWUSR|S_IRUGO),
  563. wake_gestures_show, wake_gestures_dump);
  564.  
  565. static ssize_t vib_strength_show(struct device *dev,
  566. struct device_attribute *attr, char *buf)
  567. {
  568. size_t count = 0;
  569. count += sprintf(buf, "%d\n", vib_strength);
  570. return count;
  571. }
  572.  
  573. static ssize_t vib_strength_dump(struct device *dev,
  574. struct device_attribute *attr, const char *buf, size_t count)
  575. {
  576. sscanf(buf, "%d ",&vib_strength);
  577. if (vib_strength < 0 || vib_strength > 90)
  578. vib_strength = 20;
  579.  
  580. return count;
  581. }
  582.  
  583. static DEVICE_ATTR(vib_strength, (S_IWUSR|S_IRUGO),
  584. vib_strength_show, vib_strength_dump);
  585.  
  586. /*
  587. * INIT / EXIT stuff below here
  588. */
  589. #ifdef ANDROID_TOUCH_DECLARED
  590. extern struct kobject *android_touch_kobj;
  591. #else
  592. struct kobject *android_touch_kobj;
  593. EXPORT_SYMBOL_GPL(android_touch_kobj);
  594. #endif
  595. static int __init sweep2wake_init(void)
  596. {
  597. int rc = 0;
  598.  
  599. sweep2wake_pwrdev = input_allocate_device();
  600. if (!sweep2wake_pwrdev) {
  601. pr_err("Can't allocate suspend autotest power button\n");
  602. goto err_alloc_dev;
  603. }
  604.  
  605. input_set_capability(sweep2wake_pwrdev, EV_KEY, KEY_POWER);
  606. sweep2wake_pwrdev->name = "s2w_pwrkey";
  607. sweep2wake_pwrdev->phys = "s2w_pwrkey/input0";
  608.  
  609. rc = input_register_device(sweep2wake_pwrdev);
  610. if (rc) {
  611. pr_err("%s: input_register_device err=%d\n", __func__, rc);
  612. goto err_input_dev;
  613. }
  614.  
  615. s2w_input_wq = create_workqueue("s2wiwq");
  616. if (!s2w_input_wq) {
  617. pr_err("%s: Failed to create s2wiwq workqueue\n", __func__);
  618. return -EFAULT;
  619. }
  620. INIT_WORK(&s2w_input_work, s2w_input_callback);
  621. rc = input_register_handler(&s2w_input_handler);
  622. if (rc)
  623. pr_err("%s: Failed to register s2w_input_handler\n", __func__);
  624.  
  625. gesture_dev = input_allocate_device();
  626. if (!gesture_dev) {
  627. goto err_alloc_dev;
  628. }
  629.  
  630. gesture_dev->name = "wake_gesture";
  631. gesture_dev->phys = "wake_gesture/input0";
  632. input_set_capability(gesture_dev, EV_REL, WAKE_GESTURE);
  633.  
  634. rc = input_register_device(gesture_dev);
  635. if (rc) {
  636. pr_err("%s: input_register_device err=%d\n", __func__, rc);
  637. goto err_input_dev;
  638. }
  639. gestures_setdev(gesture_dev);
  640.  
  641. #ifndef CONFIG_HAS_EARLYSUSPEND
  642. s2w_lcd_notif.notifier_call = lcd_notifier_callback;
  643. if (lcd_register_client(&s2w_lcd_notif) != 0) {
  644. pr_err("%s: Failed to register lcd callback\n", __func__);
  645. }
  646. #else
  647. register_early_suspend(&s2w_early_suspend_handler);
  648. #endif
  649.  
  650. #ifndef ANDROID_TOUCH_DECLARED
  651. android_touch_kobj = kobject_create_and_add("android_touch", NULL) ;
  652. if (android_touch_kobj == NULL) {
  653. pr_warn("%s: android_touch_kobj create_and_add failed\n", __func__);
  654. }
  655. #endif
  656. rc = sysfs_create_file(android_touch_kobj, &dev_attr_sweep2wake.attr);
  657. if (rc) {
  658. pr_warn("%s: sysfs_create_file failed for sweep2wake\n", __func__);
  659. }
  660. rc = sysfs_create_file(android_touch_kobj, &dev_attr_sweep2sleep.attr);
  661. if (rc) {
  662. pr_warn("%s: sysfs_create_file failed for sweep2sleep\n", __func__);
  663. }
  664. rc = sysfs_create_file(android_touch_kobj, &dev_attr_sweep2wake_version.attr);
  665. if (rc) {
  666. pr_warn("%s: sysfs_create_file failed for sweep2wake_version\n", __func__);
  667. }
  668. rc = sysfs_create_file(android_touch_kobj, &dev_attr_wake_gestures.attr);
  669. if (rc) {
  670. pr_warn("%s: sysfs_create_file failed for wake_gestures\n", __func__);
  671. }
  672. rc = sysfs_create_file(android_touch_kobj, &dev_attr_vib_strength.attr);
  673. if (rc) {
  674. pr_warn("%s: sysfs_create_file failed for vib_strength\n", __func__);
  675. }
  676.  
  677. err_input_dev:
  678. input_free_device(sweep2wake_pwrdev);
  679. err_alloc_dev:
  680. pr_info(LOGTAG"%s done\n", __func__);
  681.  
  682. return 0;
  683. }
  684.  
  685. static void __exit sweep2wake_exit(void)
  686. {
  687. #ifndef ANDROID_TOUCH_DECLARED
  688. kobject_del(android_touch_kobj);
  689. #endif
  690. #ifndef CONFIG_HAS_EARLYSUSPEND
  691. lcd_unregister_client(&s2w_lcd_notif);
  692. #endif
  693. input_unregister_handler(&s2w_input_handler);
  694. destroy_workqueue(s2w_input_wq);
  695. input_unregister_device(sweep2wake_pwrdev);
  696. input_free_device(sweep2wake_pwrdev);
  697. return;
  698. }
  699.  
  700. module_init(sweep2wake_init);
  701. module_exit(sweep2wake_exit);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement