summaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorJordan Nien <jnien@nvidia.com>2018-04-23 04:34:48 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-05-04 00:43:57 -0400
commit481d7c934e643dc7f6400ee331cde23e42e8fdb8 (patch)
tree9fd3fedb9fb60002605d7a23c0c4c3e4e1dcdcb8 /drivers/input/touchscreen
parent680f66da3a560599fd74d52695a3a1b0d4977c9a (diff)
input: touch: eeti: initial eeti platform usb driver.
- version: 2018/04/27 Bug 2084587 Bug 200404999 IP audit bug: Bug 200408817 Change-Id: If0a693f2dfa41971e9d1718444f4c9f6f0c1e640 Signed-off-by: EETI <touch_fae@eeti.com> Signed-off-by: Jordan Nien <jnien@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1700605 GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/Kconfig12
-rw-r--r--drivers/input/touchscreen/Makefile3
-rw-r--r--drivers/input/touchscreen/exc80_ts_usb.c1378
3 files changed, 1392 insertions, 1 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index c5e1c6773..c87cd3bc7 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -54,4 +54,16 @@ config TOUCHSCREEN_EXC80
54 To compile this driver as a module, choose M here: the 54 To compile this driver as a module, choose M here: the
55 module will be called EGALAX. 55 module will be called EGALAX.
56 56
57config TOUCHSCREEN_EXC80_USB
58 tristate "EGALAX_EXC80 USB based touchscreens"
59 help
60 Say Y here if you have a touchscreen interface using the
61 EGALAX controller, and your board-specific initialization
62 code includes that in its table.
63
64 If unsure, say N (but it's safe to say "Y").
65
66 To compile this driver as a module, choose M here: the
67 module will be called egalax_ts_usb.
68
57endif 69endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index b88114db8..0389c3658 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_TOUCHSCREEN_NVIDIA_ATMEL_MXT) += atmel_mxt_ts_nv.o 1obj-$(CONFIG_TOUCHSCREEN_NVIDIA_ATMEL_MXT) += atmel_mxt_ts_nv.o
2obj-$(CONFIG_TOUCHSCREEN_RM31080A) += rm31080a_ts.o rm31080a_ctrl.o 2obj-$(CONFIG_TOUCHSCREEN_RM31080A) += rm31080a_ts.o rm31080a_ctrl.o
3obj-$(CONFIG_TOUCHSCREEN_LR388K7) += lr388k7_ts.o 3obj-$(CONFIG_TOUCHSCREEN_LR388K7) += lr388k7_ts.o
4obj-$(CONFIG_TOUCHSCREEN_EXC80) += exc80_ts.o \ No newline at end of file 4obj-$(CONFIG_TOUCHSCREEN_EXC80) += exc80_ts.o
5obj-$(CONFIG_TOUCHSCREEN_EXC80_USB) += exc80_ts_usb.o \ No newline at end of file
diff --git a/drivers/input/touchscreen/exc80_ts_usb.c b/drivers/input/touchscreen/exc80_ts_usb.c
new file mode 100644
index 000000000..89d21f3b5
--- /dev/null
+++ b/drivers/input/touchscreen/exc80_ts_usb.c
@@ -0,0 +1,1378 @@
1/*
2 *
3 * Touch Screen USB Driver for EETI Controller
4 *
5 * Copyright (C) 2000-2018 eGalax_eMPIA Technology Inc. All rights reserved.
6 * Copyright (c) 2018 NVIDIA CORPORATION. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#define RELEASE_DATE "2018/04/27"
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/wait.h>
26#include <linux/delay.h>
27#include <linux/device.h>
28#include <linux/usb.h>
29#include <linux/usb/input.h>
30#include <linux/hid.h>
31#include <linux/uaccess.h>
32#include <linux/kfifo.h>
33#include <linux/version.h>
34#include <linux/input.h>
35#include <linux/timer.h>
36#include <linux/proc_fs.h>
37#include <linux/seq_file.h>
38#include <linux/miscdevice.h>
39#include <linux/slab.h>
40#include <linux/poll.h>
41#include <linux/input/mt.h>
42#include <linux/platform_device.h>
43#include <linux/of_gpio.h>
44#include <linux/regulator/consumer.h>
45
46#define EETI_USB_DEVICE_ID 0x0EEF
47#define EETI_USB_PRODUCT_ID 0xCC01
48#define EETI_USB_BL_PRODUCT_ID 0x79FD
49
50#define MAX_EVENTS 600
51#define MAX_USB_LEN 64U
52#define FIFO_SIZE 8192
53#define MAX_SUPPORT_POINT 16
54#define REPORTID_VENDOR 0x03
55#define REPORTID_MTOUCH 0x06
56#define MAX_RESOLUTION 4095
57#define MAX_Z_RESOLUTION 1023
58
59struct tag_mt_contacts {
60 unsigned char id;
61 signed char status;
62 unsigned short x;
63 unsigned short y;
64 unsigned short z;
65};
66
67struct _egalax_usb {
68 unsigned char *data;
69 dma_addr_t data_dma;
70 unsigned char *buffer;
71 int buf_len;
72 struct urb *irq;
73 struct usb_device *udev;
74 struct usb_interface *interface;
75 unsigned char work_state;
76 unsigned char down_cnt;
77 char phys[128];
78 wait_queue_head_t sysfs_query_queue;
79 bool sysfs_query_wait;
80 unsigned char sysfs_hook_cmd[3];
81 unsigned char sysfs_cmd_result[MAX_USB_LEN];
82};
83
84struct egalax_char_dev {
85 int open_cnts;
86 struct kfifo data_kfifo;
87 unsigned char *p_fifo_buf;
88 spinlock_t fifo_lock;
89 struct semaphore sem;
90 wait_queue_head_t fifo_inq;
91};
92
93static struct _egalax_usb *p_egalax_usb_dev;
94static struct egalax_char_dev *p_char_dev;
95static atomic_t egalax_char_available = ATOMIC_INIT(1);
96static atomic_t wait_command_ack = ATOMIC_INIT(0);
97static struct input_dev *input_dev;
98static struct tag_mt_contacts p_contact_buf[MAX_SUPPORT_POINT];
99static char fifo_read_buf[MAX_USB_LEN];
100static int total_pts_cnt, recv_pts_cnt;
101static bool misc_registered;
102static bool sysfs_created;
103
104/* DT for platform */
105int g_reset_gpio;
106bool g_enable_high;
107struct regulator *g_regulator_hv;
108struct regulator *g_regulator_5v0;
109struct regulator *g_regulator_3v3;
110struct regulator *g_regulator_1v8;
111bool g_flip_x;
112bool g_flip_y;
113
114#define DBG_MODULE 0x00000001U
115#define DBG_CDEV 0x00000002U
116#define DBG_PROC 0x00000004U
117#define DBG_POINT 0x00000008U
118#define DBG_INT 0x00000010U
119#define DBG_USB 0x00000020U
120#define DBG_SUSP 0x00000040U
121#define DBG_INPUT 0x00000080U
122#define DBG_CONST 0x00000100U
123#define DBG_IDLE 0x00000200U
124#define DBG_WAKEUP 0x00000400U
125#define DBG_BUTTON 0x00000800U
126static unsigned int dbg_level = DBG_MODULE|DBG_SUSP;
127
128#define PROC_FS_NAME "egalax_dbg"
129#define PROC_FS_MAX_LEN 8
130static struct proc_dir_entry *p_dbg_proc_file;
131
132#define EGALAX_DBG(level, fmt, args...) \
133do { if ((level & dbg_level) > 0U) { \
134pr_debug("egalax_usb: " fmt, ## args); } \
135} while (false)
136
137#define EETI_HID_SET_REPORT_VALUE 0x203
138static int send_usb_data(struct _egalax_usb *egalax_usb, unsigned char *buf,
139 int len)
140{
141 int ret;
142 struct usb_interface *intf = egalax_usb->interface;
143
144 ret = usb_control_msg(egalax_usb->udev,
145 usb_sndctrlpipe(egalax_usb->udev, 0),
146 HID_REQ_SET_REPORT,
147 USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE,
148 EETI_HID_SET_REPORT_VALUE,
149 intf->cur_altsetting->desc.bInterfaceNumber,
150 buf, len, USB_CTRL_SET_TIMEOUT);
151
152 if (ret < 0) {
153 EGALAX_DBG(DBG_MODULE,
154 "Can't send data to device with err:%d\n", ret);
155 }
156 return ret;
157}
158
159static void run_fw_init(struct _egalax_usb *egalax_usb)
160{
161 unsigned char *buf;
162 char retry = 3, ret = 0;
163
164 buf = kzalloc(3, GFP_NOIO);
165 if (buf == NULL) {
166 EGALAX_DBG(DBG_MODULE, " Can't alloc buffer to do FW init\n");
167 return;
168 }
169
170 while (retry--) {
171 buf[0] = 0x05; buf[1] = 0x02; buf[2] = 0x00;
172 ret = send_usb_data(egalax_usb, buf, 3);
173 if (ret < 0) {
174 EGALAX_DBG(DBG_MODULE,
175 " Send FW init command failed!\n");
176 } else
177 break;
178 }
179
180 if (ret < 0)
181 EGALAX_DBG(DBG_MODULE, " %s faiiled!\n", __func__);
182 else
183 EGALAX_DBG(DBG_MODULE, " %s done!\n", __func__);
184
185 kfree(buf);
186}
187
188static int egalax_cdev_open(struct inode *inode, struct file *filp)
189{
190 if (!atomic_dec_and_test(&egalax_char_available)) {
191 atomic_inc(&egalax_char_available);
192 return -EBUSY;
193 }
194
195 p_char_dev->open_cnts++;
196 filp->private_data = p_char_dev;
197
198 EGALAX_DBG(DBG_CDEV, " CDev open done!\n");
199 try_module_get(THIS_MODULE);
200 return 0;
201}
202
203static int egalax_cdev_release(struct inode *inode, struct file *filp)
204{
205 struct egalax_char_dev *cdev = filp->private_data;
206
207 atomic_inc(&egalax_char_available);
208
209 cdev->open_cnts--;
210
211 kfifo_reset(&cdev->data_kfifo);
212
213 EGALAX_DBG(DBG_CDEV, " CDev release done!\n");
214 module_put(THIS_MODULE);
215 return 0;
216}
217
218static ssize_t egalax_cdev_read(struct file *file, char __user *buf,
219 size_t count, loff_t *offset)
220{
221 int read_cnt, ret, fifo_len;
222 struct egalax_char_dev *cdev = file->private_data;
223
224 if (down_interruptible(&cdev->sem))
225 return -ERESTARTSYS;
226
227 fifo_len = kfifo_len(&cdev->data_kfifo);
228
229 while (fifo_len < 1) {
230 /* release the lock */
231 up(&cdev->sem);
232 if (file->f_flags & O_NONBLOCK)
233 return -EAGAIN;
234
235 if (wait_event_interruptible(cdev->fifo_inq,
236 kfifo_len(&cdev->data_kfifo) > 0)) {
237 /* signal: tell the fs layer to handle it */
238 return -ERESTARTSYS;
239 }
240
241 if (down_interruptible(&cdev->sem))
242 return -ERESTARTSYS;
243 }
244
245 if (count > MAX_USB_LEN)
246 count = MAX_USB_LEN;
247
248 read_cnt = kfifo_out_locked(&cdev->data_kfifo, fifo_read_buf, count,
249 &cdev->fifo_lock);
250
251 EGALAX_DBG(DBG_CDEV, " \"%s\" reading fifo data count=%d\n",
252 current->comm, read_cnt);
253
254 ret = copy_to_user(buf, fifo_read_buf, read_cnt) ? -EFAULT : read_cnt;
255
256 up(&cdev->sem);
257
258 return ret;
259}
260
261static ssize_t egalax_cdev_write(struct file *file, const char __user *buf,
262 size_t count, loff_t *offset)
263{
264 struct egalax_char_dev *cdev = file->private_data;
265 int ret = 0;
266 char *tmp;
267
268 if (p_egalax_usb_dev == NULL)
269 return -ENODEV;
270
271 if (down_interruptible(&cdev->sem))
272 return -ERESTARTSYS;
273
274 if (count > MAX_USB_LEN)
275 count = MAX_USB_LEN;
276
277 tmp = kzalloc(MAX_USB_LEN, GFP_NOIO);
278 if (tmp == NULL) {
279 up(&cdev->sem);
280 return -ENOMEM;
281 }
282
283 if (copy_from_user(tmp, buf, count)) {
284 up(&cdev->sem);
285 kfree(tmp);
286 return -EFAULT;
287 }
288
289 ret = send_usb_data(p_egalax_usb_dev, tmp, MAX_USB_LEN);
290
291 up(&cdev->sem);
292 EGALAX_DBG(DBG_CDEV, " USB writing %d bytes.\n", ret);
293 kfree(tmp);
294
295 return (ret < 0 ? -1 : count);
296}
297
298static unsigned int egalax_cdev_poll(struct file *filp,
299 struct poll_table_struct *wait)
300{
301 struct egalax_char_dev *cdev = filp->private_data;
302 unsigned int mask = 0;
303 int fifo_len;
304
305 down(&cdev->sem);
306 poll_wait(filp, &cdev->fifo_inq, wait);
307
308 fifo_len = kfifo_len(&cdev->data_kfifo);
309
310 if (fifo_len > 0)
311 mask |= POLLIN | POLLRDNORM;
312
313 if ((FIFO_SIZE - fifo_len) > MAX_USB_LEN)
314 mask |= POLLOUT | POLLWRNORM;
315
316 up(&cdev->sem);
317 return mask;
318}
319
320static int egalax_proc_show(struct seq_file *seqfilp, void *v)
321{
322 seq_printf(seqfilp,
323 "EETI USB for All Points.\nDebug Level: 0x%08X\nRelease Date: %s\n",
324 dbg_level, RELEASE_DATE);
325
326 return 0;
327}
328
329static int egalax_proc_open(struct inode *inode, struct file *filp)
330{
331 EGALAX_DBG(DBG_PROC, " \"%s\" call proc_open\n", current->comm);
332 return single_open(filp, egalax_proc_show, NULL);
333}
334
335static ssize_t egalax_proc_write(struct file *file, const char __user *buf,
336 size_t count, loff_t *offset)
337{
338 char procfs_buffer_size = 0;
339 unsigned char procfs_buf[PROC_FS_MAX_LEN+1] = {0};
340 unsigned int new_level = 0;
341
342 EGALAX_DBG(DBG_PROC, " \"%s\" call proc_write\n", current->comm);
343
344 procfs_buffer_size = count;
345 if (procfs_buffer_size > PROC_FS_MAX_LEN)
346 procfs_buffer_size = PROC_FS_MAX_LEN+1;
347
348 if (copy_from_user(procfs_buf, buf, procfs_buffer_size)) {
349 EGALAX_DBG(DBG_PROC, " proc_write faied at copy_from_user\n");
350 return -EFAULT;
351 }
352
353 if (!kstrtouint(procfs_buf, 16, &new_level))
354 dbg_level = new_level;
355
356 EGALAX_DBG(DBG_PROC, " Switch Debug Level to 0x%08X\n", dbg_level);
357
358 return procfs_buffer_size;
359}
360
361static bool sys_sendcmd_wait(unsigned char *by_send_cmd, int n_send_cmd_len,
362 unsigned char *by_hook_cmd, int n_hook_cmd_len,
363 int nTimeOut)
364{
365 int i;
366 bool b_ret = true;
367
368 if (p_egalax_usb_dev == NULL)
369 return false;
370
371 memset(p_egalax_usb_dev->sysfs_cmd_result, 0,
372 sizeof(p_egalax_usb_dev->sysfs_cmd_result));
373
374 for (i = 0; i < 3; i++) {
375 if (i < n_hook_cmd_len)
376 p_egalax_usb_dev->sysfs_hook_cmd[i] = by_hook_cmd[i];
377 else
378 p_egalax_usb_dev->sysfs_hook_cmd[i] = 0xFF;
379 }
380 p_egalax_usb_dev->sysfs_query_wait = true;
381
382 if (send_usb_data(p_egalax_usb_dev, by_send_cmd, n_send_cmd_len) < 0) {
383 b_ret = false;
384 } else {
385 wait_event_interruptible_timeout(
386 p_egalax_usb_dev->sysfs_query_queue,
387 !p_egalax_usb_dev->sysfs_query_wait,
388 nTimeOut);
389
390 if (p_egalax_usb_dev->sysfs_query_wait)
391 b_ret = false;
392 else
393 b_ret = true;
394 }
395 p_egalax_usb_dev->sysfs_query_wait = false;
396 return b_ret;
397}
398
399#define OP_MODE_GET 0x00
400#define OP_MODE_SET 0x01
401static ssize_t sys_show_version(struct device *dev,
402 struct device_attribute *attr, char *buf)
403{
404 unsigned char send_cmd_buf[MAX_USB_LEN] = {
405 0x03, 0x04, 0x36, 0x91, 0x01, OP_MODE_GET};
406 bool b_ret = true;
407
408 b_ret = sys_sendcmd_wait(send_cmd_buf, MAX_USB_LEN,
409 send_cmd_buf+2, 3, HZ);
410 if (b_ret)
411 return snprintf(buf, PAGE_SIZE, "Driver: %s FW: %s\n",
412 RELEASE_DATE, p_egalax_usb_dev->sysfs_cmd_result+6);
413 else
414 return snprintf(buf, PAGE_SIZE, "Driver: %s FW: Invalid\n",
415 RELEASE_DATE);
416}
417
418static ssize_t sys_show_touchevent(struct device *dev,
419 struct device_attribute *attr, char *buf)
420{
421 unsigned char send_cmd_buf[MAX_USB_LEN] = {
422 0x03, 0x04, 0x36, 0x91, 0x02, OP_MODE_GET};
423 bool b_ret = true;
424 int code = 0;
425
426 b_ret = sys_sendcmd_wait(send_cmd_buf, MAX_USB_LEN,
427 send_cmd_buf+2, 3, HZ);
428 if (b_ret) {
429 code = p_egalax_usb_dev->sysfs_cmd_result[6];
430 code += (p_egalax_usb_dev->sysfs_cmd_result[7]<<8);
431 code += (p_egalax_usb_dev->sysfs_cmd_result[8]<<16);
432 code += (p_egalax_usb_dev->sysfs_cmd_result[9]<<24);
433 return snprintf(buf, PAGE_SIZE, "0x%08X\n", code);
434 } else
435 return snprintf(buf, PAGE_SIZE, "Invalid\n");
436}
437
438static ssize_t sys_show_reportmode(struct device *dev,
439 struct device_attribute *attr, char *buf)
440{
441 unsigned char send_cmd_buf[MAX_USB_LEN] = {
442 0x03, 0x04, 0x36, 0x91, 0x04, OP_MODE_GET};
443 bool b_ret = true;
444
445 b_ret = sys_sendcmd_wait(send_cmd_buf, MAX_USB_LEN,
446 send_cmd_buf+2, 3, HZ);
447 if (b_ret)
448 return snprintf(buf, PAGE_SIZE, "%02X\n",
449 p_egalax_usb_dev->sysfs_cmd_result[6]);
450 else
451 return snprintf(buf, PAGE_SIZE, "Invalid\n");
452}
453
454#define NV_REPORTMODE_MAX 0x06
455static ssize_t sys_store_reportmode(struct device *dev,
456 struct device_attribute *attr,
457 const char *buf, size_t count)
458{
459 unsigned char send_cmd_buf[MAX_USB_LEN] = {
460 0x03, 0x05, 0x36, 0x91, 0x04, OP_MODE_SET};
461 bool b_ret = true;
462 char mode;
463
464 if (count != 2)
465 return -EINVAL;
466
467 mode = buf[0] - '0';
468 if (mode > NV_REPORTMODE_MAX || mode < 0)
469 return -EINVAL;
470
471 send_cmd_buf[6] = mode;
472
473 b_ret = sys_sendcmd_wait(send_cmd_buf, MAX_USB_LEN,
474 send_cmd_buf+2, 3, HZ);
475 if (b_ret)
476 return count;
477 else
478 return -EIO;
479}
480
481static ssize_t sys_show_bypassmode(struct device *dev,
482 struct device_attribute *attr, char *buf)
483{
484 unsigned char send_cmd_buf[MAX_USB_LEN] = {
485 0x03, 0x04, 0x36, 0x91, 0x05, OP_MODE_GET};
486 bool b_ret = true;
487
488 b_ret = sys_sendcmd_wait(send_cmd_buf, MAX_USB_LEN,
489 send_cmd_buf+2, 3, HZ);
490 if (b_ret)
491 return snprintf(buf, PAGE_SIZE, "%02X\n",
492 p_egalax_usb_dev->sysfs_cmd_result[6]);
493 else
494 return snprintf(buf, PAGE_SIZE, "Invalid\n");
495}
496
497#define NV_BYPASSMODE_MAX 0x02
498static ssize_t sys_store_bypassmode(struct device *dev,
499 struct device_attribute *attr,
500 const char *buf, size_t count)
501{
502 unsigned char send_cmd_buf[MAX_USB_LEN] = {
503 0x03, 0x05, 0x36, 0x91, 0x05, OP_MODE_SET};
504 bool b_ret = true;
505 char mode;
506
507 if (count != 2)
508 return -EINVAL;
509
510 mode = buf[0]-'0';
511 if (mode > NV_BYPASSMODE_MAX || mode < 0)
512 return -EINVAL;
513
514 send_cmd_buf[6] = mode;
515
516 b_ret = sys_sendcmd_wait(send_cmd_buf, MAX_USB_LEN,
517 send_cmd_buf+2, 3, HZ);
518 if (b_ret)
519 return count;
520 else
521 return -EIO;
522}
523
524static ssize_t sys_show_calibration(struct device *dev,
525 struct device_attribute *attr, char *buf)
526{
527 unsigned char send_cmd_buf[MAX_USB_LEN] = {
528 0x03, 0x02, 0x3F, 0x4E};
529 bool b_ret = true;
530 unsigned int status = 0;
531
532 b_ret = sys_sendcmd_wait(send_cmd_buf, MAX_USB_LEN,
533 send_cmd_buf+2, 3, HZ);
534 if (b_ret) {
535 status = p_egalax_usb_dev->sysfs_cmd_result[4];
536 status += p_egalax_usb_dev->sysfs_cmd_result[5]<<8;
537 if (status&0x00000100)
538 return sprintf(buf, "0xff\n");
539 else
540 return sprintf(buf, "0x00\n");
541 } else
542 return sprintf(buf, "0x00\n");
543}
544
545static DEVICE_ATTR(version, 0440, sys_show_version, NULL);
546static DEVICE_ATTR(touch_event, 0440, sys_show_touchevent, NULL);
547static DEVICE_ATTR(report_mode, 0640, sys_show_reportmode,
548 sys_store_reportmode);
549static DEVICE_ATTR(bypass_mode, 0640, sys_show_bypassmode,
550 sys_store_bypassmode);
551static DEVICE_ATTR(calibration, 0440, sys_show_calibration, NULL);
552
553static struct attribute *egalax_attributes[] = {
554 &dev_attr_version.attr,
555 &dev_attr_touch_event.attr,
556 &dev_attr_report_mode.attr,
557 &dev_attr_bypass_mode.attr,
558 &dev_attr_calibration.attr,
559 NULL,
560};
561
562static const struct attribute_group egalax_attr_group = {
563 .attrs = egalax_attributes,
564};
565
566#define STYLUS_MASK 0x10
567#define MAX_POINT_PER_PACKET 5U
568#define POINT_STRUCT_SIZE 10U
569static void ProcessParallelReport(unsigned char *buf,
570 struct _egalax_usb *p_egalax_usb)
571{
572 unsigned char i, index = 0, cnt_down = 0, cnt_up = 0, shift = 0;
573 unsigned char status = 0;
574 unsigned short contact_id = 0, x = 0, y = 0, z = 0;
575
576 if (total_pts_cnt <= 0) {
577 if (buf[1] == 0 || buf[1] > MAX_SUPPORT_POINT) {
578 EGALAX_DBG(DBG_POINT,
579 " NumsofContacts mismatch, skip packet\n");
580 return;
581 }
582
583 total_pts_cnt = buf[1];
584 recv_pts_cnt = 0;
585 } else if (buf[1] > 0) {
586 total_pts_cnt = 0;
587 recv_pts_cnt = 0;
588 EGALAX_DBG(DBG_POINT,
589 " NumsofContacts mismatch, skip packet\n");
590 return;
591 }
592
593 while (index < MAX_POINT_PER_PACKET) {
594 shift = index * POINT_STRUCT_SIZE + 2;
595 status = buf[shift];
596 contact_id = buf[shift+1];
597 x = ((buf[shift+3]<<8) + buf[shift+2]);
598 y = ((buf[shift+5]<<8) + buf[shift+4]);
599 z = ((buf[shift+7]<<8) + buf[shift+6]);
600
601 if (contact_id >= MAX_SUPPORT_POINT) {
602 total_pts_cnt = 0;
603 recv_pts_cnt = 0;
604 EGALAX_DBG(DBG_POINT, " Get error ContactID.\n");
605 return;
606 }
607
608 EGALAX_DBG(DBG_POINT,
609 "Get Point[%d] Update: Status=%d X=%d Y=%d\n",
610 contact_id, status, x, y);
611
612 #ifdef _SWITCH_XY
613 short tmp = x;
614
615 x = y;
616 y = tmp;
617 #endif
618
619 if (g_flip_x)
620 x = MAX_RESOLUTION - x;
621
622
623 if (g_flip_y)
624 y = MAX_RESOLUTION - y;
625
626 p_contact_buf[recv_pts_cnt].id = contact_id;
627 p_contact_buf[recv_pts_cnt].status = status;
628 p_contact_buf[recv_pts_cnt].x = x;
629 p_contact_buf[recv_pts_cnt].y = y;
630 p_contact_buf[recv_pts_cnt].z = z;
631
632 recv_pts_cnt++;
633 index++;
634
635 /* Recv all points, send input report */
636 if (recv_pts_cnt == total_pts_cnt) {
637 for (i = 0; i < recv_pts_cnt; i++) {
638 input_mt_slot(input_dev, p_contact_buf[i].id);
639 if ((p_contact_buf[i].status &
640 STYLUS_MASK) != 0) {
641 input_mt_report_slot_state(input_dev,
642 MT_TOOL_PEN,
643 ((p_contact_buf[i].status&0x01)
644 != 0));
645 } else {
646 input_mt_report_slot_state(input_dev,
647 MT_TOOL_FINGER,
648 ((p_contact_buf[i].status&0x01)
649 != 0));
650 }
651
652 if ((p_contact_buf[i].status & 0x01) != 0) {
653 input_report_abs(input_dev,
654 ABS_MT_POSITION_X,
655 p_contact_buf[i].x);
656 input_report_abs(input_dev,
657 ABS_MT_POSITION_Y,
658 p_contact_buf[i].y);
659 input_report_abs(input_dev,
660 ABS_MT_PRESSURE,
661 p_contact_buf[i].z);
662 }
663
664 if (p_contact_buf[i].status)
665 cnt_down++;
666 else
667 cnt_up++;
668 }
669
670 input_sync(input_dev);
671
672 EGALAX_DBG(DBG_POINT,
673 "Input sync point data done! (Down:%d Up:%d)\n",
674 cnt_down, cnt_up);
675
676 total_pts_cnt = 0;
677 recv_pts_cnt = 0;
678 return;
679 }
680 }
681}
682
683static void egalax_usb_measure(struct _egalax_usb *egalax_usb,
684 unsigned char *buf, int len)
685{
686 int loop = 3, ret;
687
688 EGALAX_DBG(DBG_USB, " %s\n", __func__);
689
690 if (buf[0] != REPORTID_MTOUCH && buf[0] != REPORTID_VENDOR) {
691 EGALAX_DBG(DBG_USB,
692 "USB read error data with Len=%d hedaer=%d\n", len, buf[0]);
693 return;
694 }
695
696 switch (buf[0]) {
697 case REPORTID_VENDOR:
698 EGALAX_DBG(DBG_USB, " USB get vendor command packet\n");
699 atomic_set(&wait_command_ack, 1);
700 if (egalax_usb->sysfs_query_wait &&
701 egalax_usb->sysfs_hook_cmd[0] == buf[2] &&
702 ((egalax_usb->sysfs_hook_cmd[1] == 0xFF) ||
703 egalax_usb->sysfs_hook_cmd[1] == buf[3]) &&
704 ((egalax_usb->sysfs_hook_cmd[2] == 0xFF) ||
705 egalax_usb->sysfs_hook_cmd[2] == buf[4])) {
706 memcpy(egalax_usb->sysfs_cmd_result,
707 buf, buf[1]+2);
708 egalax_usb->sysfs_query_wait = false;
709 wake_up_interruptible(
710 &egalax_usb->sysfs_query_queue);
711 break;
712 }
713
714 /* If someone reading now! put the data into the buffer! */
715 if (p_char_dev->open_cnts > 0) {
716 loop = 3;
717 do {
718 ret = wait_event_timeout(p_char_dev->fifo_inq,
719 kfifo_avail(
720 &p_char_dev->data_kfifo) >= len, HZ);
721 } while (ret <= 0 && --loop);
722
723 /* fifo size is ready */
724 if (ret > 0) {
725 ret = kfifo_in_locked(&p_char_dev->data_kfifo,
726 buf, len, &p_char_dev->fifo_lock);
727 wake_up_interruptible(&p_char_dev->fifo_inq);
728 } else {
729 EGALAX_DBG(DBG_CDEV,
730 " [Warning] fifo size is overflow.\n");
731 }
732 }
733 break;
734 case REPORTID_MTOUCH:
735 ProcessParallelReport(buf, egalax_usb);
736 break;
737 default:
738 break;
739 }
740}
741
742static void egalax_usb_irq(struct urb *urb)
743{
744 struct _egalax_usb *egalax_usb = urb->context;
745 int retval;
746
747 EGALAX_DBG(DBG_INT, " %s\n", __func__);
748
749 switch (urb->status) {
750 case 0:
751 /* success */
752 break;
753 case -ETIME:
754 /* this urb is timing out */
755 EGALAX_DBG(DBG_INT, " urb timed out\n");
756 return;
757 case -ECONNRESET:
758 case -ENOENT:
759 case -ESHUTDOWN:
760 /* this urb is terminated, clean up */
761 EGALAX_DBG(DBG_INT,
762 " urb shutting down with status: %d\n", urb->status);
763 return;
764 default:
765 EGALAX_DBG(DBG_INT,
766 " urb nonzero urb status received: %d\n", urb->status);
767 goto exit;
768 }
769
770 egalax_usb_measure(egalax_usb, egalax_usb->data, urb->actual_length);
771
772exit:
773 usb_mark_last_busy(egalax_usb->udev);
774 retval = usb_submit_urb(urb, GFP_ATOMIC);
775 if (retval)
776 EGALAX_DBG(DBG_INT,
777 " usb_submit_urb failed with result: %d\n", retval);
778}
779
780static int exc80_input_open(struct input_dev *dev)
781{
782 return 0;
783}
784
785static void exc80_input_close(struct input_dev *dev)
786{
787}
788
789static int exc80_input_disable(struct input_dev *dev)
790{
791 unsigned char send_cmd_buf[MAX_USB_LEN] = {
792 0x03, 0x04, 0x36, 0x67, 0x02, 0x00};
793
794 if (sys_sendcmd_wait(send_cmd_buf, MAX_USB_LEN, send_cmd_buf+2, 3, HZ))
795 return 0;
796
797 return -EIO;
798}
799
800static int exc80_input_enable(struct input_dev *dev)
801{
802 unsigned char send_cmd_buf[MAX_USB_LEN] = {
803 0x03, 0x04, 0x36, 0x67, 0x02, 0x01};
804
805 if (sys_sendcmd_wait(send_cmd_buf, MAX_USB_LEN, send_cmd_buf+2, 3, HZ))
806 return 0;
807
808 return -EIO;
809}
810
811static struct input_dev *allocate_Input_Dev(struct _egalax_usb *egalax_usb,
812 struct usb_interface *intf)
813{
814 int ret;
815 struct input_dev *p_input_dev = NULL;
816
817 p_input_dev = input_allocate_device();
818 if (p_input_dev == NULL) {
819 EGALAX_DBG(DBG_MODULE, " Failed to allocate input device\n");
820 return NULL;/* -ENOMEM; */
821 }
822
823 p_input_dev->name = "eGalax_Touch_Screen";
824 p_input_dev->phys = egalax_usb->phys;
825 usb_to_input_id(interface_to_usbdev(intf), &p_input_dev->id);
826 p_input_dev->dev.parent = &intf->dev;
827 p_input_dev->open = exc80_input_open;
828 p_input_dev->close = exc80_input_close;
829 p_input_dev->enable = exc80_input_enable;
830 p_input_dev->disable = exc80_input_disable;
831 p_input_dev->enabled = true;
832 input_set_drvdata(p_input_dev, egalax_usb);
833
834 set_bit(EV_ABS, p_input_dev->evbit);
835 __set_bit(INPUT_PROP_DIRECT, p_input_dev->propbit);
836 input_mt_init_slots(p_input_dev, MAX_SUPPORT_POINT, 0);
837 input_set_abs_params(p_input_dev, ABS_MT_POSITION_X, 0,
838 MAX_RESOLUTION, 0, 0);
839 input_set_abs_params(p_input_dev, ABS_MT_POSITION_Y, 0,
840 MAX_RESOLUTION, 0, 0);
841 input_set_abs_params(p_input_dev, ABS_MT_PRESSURE, 0,
842 MAX_Z_RESOLUTION, 0, 0);
843 input_set_abs_params(p_input_dev, ABS_MT_TOOL_TYPE, 0,
844 MT_TOOL_MAX, 0, 0);
845
846 input_set_events_per_packet(p_input_dev, MAX_EVENTS);
847
848 ret = input_register_device(p_input_dev);
849 if (ret) {
850 EGALAX_DBG(DBG_MODULE,
851 " Unable to register input device, err: %d\n", ret);
852 input_free_device(p_input_dev);
853 p_input_dev = NULL;
854 }
855
856 return p_input_dev;
857}
858
859static void egalax_usb_free_buffers(struct usb_device *udev,
860 struct _egalax_usb *egalax_usb)
861{
862 usb_free_coherent(udev, MAX_USB_LEN, egalax_usb->data,
863 egalax_usb->data_dma);
864 kfree(egalax_usb->buffer);
865}
866
867static const struct file_operations egalax_cdev_fops = {
868 .owner = THIS_MODULE,
869 .read = egalax_cdev_read,
870 .write = egalax_cdev_write,
871 .open = egalax_cdev_open,
872 .release = egalax_cdev_release,
873 .poll = egalax_cdev_poll,
874};
875
876static struct miscdevice egalax_misc_dev = {
877 .minor = MISC_DYNAMIC_MINOR,
878 .name = "touch",
879 .fops = &egalax_cdev_fops,
880};
881
882static const struct file_operations egalax_proc_fops = {
883 .owner = THIS_MODULE,
884 .open = egalax_proc_open,
885 .read = seq_read,
886 .write = egalax_proc_write,
887 .llseek = seq_lseek,
888 .release = single_release,
889};
890
891static struct egalax_char_dev *setup_chardev(void)
892{
893 struct egalax_char_dev *p_char_dev;
894
895 p_char_dev = kzalloc(1*sizeof(struct egalax_char_dev), GFP_KERNEL);
896 if (p_char_dev == NULL)
897 goto fail_cdev;
898
899 spin_lock_init(&p_char_dev->fifo_lock);
900 p_char_dev->p_fifo_buf = kzalloc(sizeof(unsigned char)*FIFO_SIZE,
901 GFP_KERNEL);
902 if (p_char_dev->p_fifo_buf == NULL)
903 goto fail_fifobuf;
904
905 kfifo_init(&p_char_dev->data_kfifo, p_char_dev->p_fifo_buf, FIFO_SIZE);
906 if (!kfifo_initialized(&p_char_dev->data_kfifo))
907 goto fail_kfifo;
908
909 p_char_dev->open_cnts = 0;
910 sema_init(&p_char_dev->sem, 1);
911 init_waitqueue_head(&p_char_dev->fifo_inq);
912
913 return p_char_dev;
914
915fail_kfifo:
916 kfree(p_char_dev->p_fifo_buf);
917fail_fifobuf:
918 kfree(p_char_dev);
919fail_cdev:
920 return NULL;
921}
922
923static void egalax_usb_add_ncb(struct usb_device *udev)
924{
925 int result;
926 struct usb_interface *intf;
927 struct _egalax_usb *egalax_usb;
928 struct usb_endpoint_descriptor *endpoint;
929
930 EGALAX_DBG(DBG_MODULE,
931 " USB device probe (VID=%04X PID=%04X)\n",
932 le16_to_cpu(udev->descriptor.idVendor),
933 le16_to_cpu(udev->descriptor.idProduct));
934
935 if (udev->descriptor.idVendor != EETI_USB_DEVICE_ID ||
936 (udev->descriptor.idProduct != EETI_USB_PRODUCT_ID &&
937 udev->descriptor.idProduct != EETI_USB_BL_PRODUCT_ID)) {
938 EGALAX_DBG(DBG_MODULE, " No support this device.\n");
939 return;
940 }
941
942 intf = usb_ifnum_to_if(udev, 0);
943 if (intf == NULL)
944 return;
945
946 endpoint = &intf->cur_altsetting->endpoint[0].desc;
947 egalax_usb = kzalloc(sizeof(struct _egalax_usb), GFP_KERNEL);
948 if (egalax_usb == NULL)
949 goto out_free;
950
951 p_egalax_usb_dev = egalax_usb;
952
953 egalax_usb->data = usb_alloc_coherent(udev,
954 MAX_USB_LEN, GFP_KERNEL,
955 &egalax_usb->data_dma);
956
957 if (egalax_usb->data == NULL) {
958 EGALAX_DBG(DBG_MODULE, " usb_buffer_alloc failed!\n");
959 goto out_free;
960 }
961
962 egalax_usb->buffer = kzalloc(MAX_USB_LEN, GFP_KERNEL);
963 if (egalax_usb->buffer == NULL) {
964 EGALAX_DBG(DBG_MODULE, " Can't alloc USB buffer!\n");
965 goto out_free_buffers;
966 }
967
968 egalax_usb->irq = usb_alloc_urb(0, GFP_KERNEL);
969 if (egalax_usb->irq == NULL) {
970 EGALAX_DBG(DBG_MODULE, " usb_alloc_urb failed!\n");
971 goto out_free_buffers;
972 }
973
974 egalax_usb->udev = udev;
975 egalax_usb->interface = intf;
976
977 usb_make_path(udev, egalax_usb->phys, sizeof(egalax_usb->phys));
978 strlcat(egalax_usb->phys, "/input0", sizeof(egalax_usb->phys));
979
980 if (input_dev == NULL &&
981 udev->descriptor.idProduct == EETI_USB_PRODUCT_ID) {
982 input_dev = allocate_Input_Dev(egalax_usb, intf);
983 if (input_dev == NULL) {
984 EGALAX_DBG(DBG_MODULE, " allocate_Input_Dev failed\n");
985 goto out_free_buffers;
986 }
987 EGALAX_DBG(DBG_MODULE, " Register input device done\n");
988 } else
989 EGALAX_DBG(DBG_MODULE, " Input device already created!\n");
990
991 usb_fill_int_urb(egalax_usb->irq, egalax_usb->udev,
992 usb_rcvintpipe(egalax_usb->udev,
993 endpoint->bEndpointAddress),
994 egalax_usb->data, MAX_USB_LEN, egalax_usb_irq,
995 egalax_usb, endpoint->bInterval);
996
997 egalax_usb->irq->dev = egalax_usb->udev;
998 egalax_usb->irq->transfer_dma = egalax_usb->data_dma;
999 egalax_usb->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1000
1001 usb_set_intfdata(intf, egalax_usb);
1002
1003 /* start USB function */
1004 if (usb_submit_urb(egalax_usb->irq, GFP_KERNEL)) {
1005 EGALAX_DBG(DBG_MODULE, " usb_submit_urb failed\n");
1006 goto out_unregister_input;
1007 }
1008
1009 result = misc_register(&egalax_misc_dev);
1010 if (result) {
1011 EGALAX_DBG(DBG_MODULE,
1012 " misc device register failed\n");
1013 goto out_unregister_input;
1014 }
1015 misc_registered = true;
1016
1017 result = sysfs_create_group(&egalax_misc_dev.this_device->kobj,
1018 &egalax_attr_group);
1019 if (result) {
1020 EGALAX_DBG(DBG_MODULE,
1021 " Failed to create sysfs attributes:%d\n", result);
1022 goto out_misc_deregister;
1023 }
1024 sysfs_created = true;
1025
1026 /* allocate the character device */
1027 p_char_dev = setup_chardev();
1028 if (p_char_dev == NULL) {
1029 result = -ENOMEM;
1030 goto out_sysfs_remove_group;
1031 }
1032
1033 init_waitqueue_head(&p_egalax_usb_dev->sysfs_query_queue);
1034 p_egalax_usb_dev->sysfs_query_wait = false;
1035 p_egalax_usb_dev->sysfs_hook_cmd[0] = 0xFF;
1036 p_egalax_usb_dev->sysfs_hook_cmd[1] = 0xFF;
1037 p_egalax_usb_dev->sysfs_hook_cmd[2] = 0xFF;
1038
1039 if (udev->descriptor.idProduct != EETI_USB_BL_PRODUCT_ID)
1040 run_fw_init(egalax_usb);
1041
1042 EGALAX_DBG(DBG_MODULE, " USB device probe done\n");
1043
1044 return;
1045
1046out_sysfs_remove_group:
1047 sysfs_remove_group(&egalax_misc_dev.this_device->kobj,
1048 &egalax_attr_group);
1049out_misc_deregister:
1050 misc_deregister(&egalax_misc_dev);
1051out_unregister_input:
1052 input_unregister_device(input_dev);
1053 input_dev = NULL;
1054out_free_buffers:
1055 p_egalax_usb_dev = NULL;
1056 egalax_usb_free_buffers(udev, egalax_usb);
1057out_free:
1058 kfree(egalax_usb);
1059}
1060
1061static void egalax_usb_rm_ncb(struct usb_device *udev)
1062{
1063 if (udev->descriptor.idVendor != EETI_USB_DEVICE_ID ||
1064 (udev->descriptor.idProduct != EETI_USB_PRODUCT_ID &&
1065 udev->descriptor.idProduct != EETI_USB_BL_PRODUCT_ID))
1066 return;
1067
1068 if (p_egalax_usb_dev == NULL || (p_egalax_usb_dev->udev != udev))
1069 return;
1070
1071 EGALAX_DBG(DBG_MODULE, " USB device disconnect!\n");
1072
1073 if (sysfs_created)
1074 sysfs_remove_group(&egalax_misc_dev.this_device->kobj,
1075 &egalax_attr_group);
1076 sysfs_created = false;
1077
1078 if (misc_registered)
1079 misc_deregister(&egalax_misc_dev);
1080 misc_registered = false;
1081
1082 if (p_char_dev != NULL) {
1083 kfree(p_char_dev->p_fifo_buf);
1084 kfree(p_char_dev);
1085 p_char_dev = NULL;
1086 }
1087
1088 usb_kill_urb(p_egalax_usb_dev->irq);
1089 usb_free_urb(p_egalax_usb_dev->irq);
1090 egalax_usb_free_buffers(udev, p_egalax_usb_dev);
1091 kfree(p_egalax_usb_dev);
1092 p_egalax_usb_dev = NULL;
1093 input_dev = NULL;
1094}
1095
1096int egalax_usb_ncb(struct notifier_block *nb, unsigned long usb_event,
1097 void *udev)
1098{
1099 int result = NOTIFY_OK;
1100
1101 switch (usb_event) {
1102 case USB_DEVICE_ADD:
1103 egalax_usb_add_ncb(udev);
1104 break;
1105 case USB_DEVICE_REMOVE:
1106 egalax_usb_rm_ncb(udev);
1107 break;
1108 case USB_BUS_ADD:
1109 case USB_BUS_REMOVE:
1110 break;
1111 default:
1112 result = NOTIFY_BAD;
1113 }
1114 return result;
1115}
1116
1117static struct notifier_block egalax_usb_notifier = {
1118 .notifier_call = egalax_usb_ncb,
1119 .priority = INT_MAX /* Need to be called first of all */
1120};
1121
1122static int request_dt(struct device *dev)
1123{
1124 int result, val;
1125 struct device_node *devnode;
1126
1127 g_reset_gpio = 0;
1128 g_enable_high = false;
1129 g_flip_x = false;
1130 g_flip_y = false;
1131 g_regulator_hv = NULL;
1132 g_regulator_5v0 = NULL;
1133 g_regulator_3v3 = NULL;
1134 g_regulator_1v8 = NULL;
1135
1136 devnode = dev->of_node;
1137 if (devnode) {
1138 /* Touch orientation */
1139 result = of_property_read_u32(devnode, "flip-x", &val);
1140 if (result < 0)
1141 val = 0;
1142 g_flip_x = val != 0 ? true : false;
1143 result = of_property_read_u32(devnode, "flip-y", &val);
1144 if (result < 0)
1145 val = 0;
1146 g_flip_y = val != 0 ? true : false;
1147
1148 if (of_property_read_bool(devnode, "enable-active-high"))
1149 g_enable_high = true;
1150
1151 g_reset_gpio = of_get_named_gpio(devnode,
1152 "reset-gpio", 0);
1153 /* regulator */
1154 g_regulator_hv = devm_regulator_get(
1155 dev, "vdd-ts-hv");
1156 if (IS_ERR(g_regulator_hv)) {
1157 EGALAX_DBG(DBG_MODULE,
1158 "vdd-12v regulator_get failed: %ld\n",
1159 PTR_ERR(g_regulator_hv));
1160 return -EINVAL;
1161 }
1162 g_regulator_5v0 = devm_regulator_get(
1163 dev, "vdd-ts-5v0");
1164 if (IS_ERR(g_regulator_5v0)) {
1165 EGALAX_DBG(DBG_MODULE,
1166 "vdd-5v regulator_get failed: %ld\n",
1167 PTR_ERR(g_regulator_5v0));
1168 return -EINVAL;
1169 }
1170 g_regulator_3v3 = devm_regulator_get(
1171 dev, "vdd-ts-3v3");
1172 if (IS_ERR(g_regulator_3v3)) {
1173 EGALAX_DBG(DBG_MODULE,
1174 "vdd 3v3 regulator_get failed: %ld\n",
1175 PTR_ERR(g_regulator_3v3));
1176 return -EINVAL;
1177 }
1178 g_regulator_1v8 = devm_regulator_get(
1179 dev, "vdd-ts-1v8");
1180 if (IS_ERR(g_regulator_1v8)) {
1181 EGALAX_DBG(DBG_MODULE,
1182 "vdd 18v regulator_get failed: %ld\n",
1183 PTR_ERR(g_regulator_1v8));
1184 return -EINVAL;
1185 }
1186 }
1187
1188 if (!gpio_is_valid(g_reset_gpio)) {
1189 EGALAX_DBG(DBG_MODULE, " gpio[%d] is not valid\n",
1190 g_reset_gpio);
1191 return -EINVAL;
1192 }
1193
1194 result = gpio_request(g_reset_gpio, "rest-gpio");
1195 if (result < 0) {
1196 EGALAX_DBG(DBG_MODULE, " gpio_request[%d] failed: %d\n",
1197 g_reset_gpio, result);
1198 return -EINVAL;
1199 }
1200
1201 return 0;
1202}
1203
1204static void egalax_power_on(void)
1205{
1206 int error = 0;
1207
1208 if (g_enable_high)
1209 gpio_direction_output(g_reset_gpio, 1);
1210 else
1211 gpio_direction_output(g_reset_gpio, 0);
1212
1213 error = regulator_enable(g_regulator_hv);
1214 if (error < 0)
1215 EGALAX_DBG(DBG_MODULE, " regulator enable failed: %d\n",
1216 error);
1217 error = regulator_enable(g_regulator_5v0);
1218 if (error < 0)
1219 EGALAX_DBG(DBG_MODULE, " regulator enable failed: %d\n",
1220 error);
1221 error = regulator_enable(g_regulator_1v8);
1222 if (error < 0)
1223 EGALAX_DBG(DBG_MODULE, " regulator enable failed: %d\n",
1224 error);
1225 error = regulator_enable(g_regulator_3v3);
1226 if (error < 0)
1227 EGALAX_DBG(DBG_MODULE, " regulator enable failed: %d\n",
1228 error);
1229 usleep_range(1000, 5000);
1230 if (g_enable_high)
1231 gpio_direction_output(g_reset_gpio, 0);
1232 else
1233 gpio_direction_output(g_reset_gpio, 1);
1234 EGALAX_DBG(DBG_MODULE, " Device power on!\n");
1235
1236}
1237
1238static void egalax_power_off(void)
1239{
1240 int error = 0;
1241
1242 if (g_enable_high)
1243 gpio_direction_output(g_reset_gpio, 0);
1244 else
1245 gpio_direction_output(g_reset_gpio, 1);
1246
1247 error = regulator_disable(g_regulator_hv);
1248 if (error < 0)
1249 EGALAX_DBG(DBG_MODULE, " regulator enable failed: %d\n",
1250 error);
1251 error = regulator_disable(g_regulator_5v0);
1252 if (error < 0)
1253 EGALAX_DBG(DBG_MODULE, " regulator enable failed: %d\n",
1254 error);
1255 error = regulator_disable(g_regulator_1v8);
1256 if (error < 0)
1257 EGALAX_DBG(DBG_MODULE, " regulator enable failed: %d\n",
1258 error);
1259 error = regulator_disable(g_regulator_3v3);
1260 if (error < 0)
1261 EGALAX_DBG(DBG_MODULE, " regulator enable failed: %d\n",
1262 error);
1263 usleep_range(1000, 5000);
1264 if (g_enable_high)
1265 gpio_direction_output(g_reset_gpio, 1);
1266 else
1267 gpio_direction_output(g_reset_gpio, 0);
1268
1269 EGALAX_DBG(DBG_MODULE, " Device power on!\n");
1270}
1271
1272static int egalax_platform_probe(struct platform_device *pdev)
1273{
1274 int i, result;
1275
1276 p_egalax_usb_dev = NULL;
1277 p_char_dev = NULL;
1278 input_dev = NULL;
1279 total_pts_cnt = 0;
1280 recv_pts_cnt = 0;
1281
1282 for (i = 0; i < MAX_SUPPORT_POINT; i++) {
1283 p_contact_buf[i].status = -1;
1284 p_contact_buf[i].id = 0;
1285 p_contact_buf[i].x = p_contact_buf[i].y =
1286 p_contact_buf[i].z = 0;
1287 }
1288
1289 if (request_dt(&(pdev->dev)) != 0)
1290 return -EINVAL;
1291
1292 egalax_power_on();
1293
1294 p_dbg_proc_file = proc_create(PROC_FS_NAME, 0660, NULL,
1295 &egalax_proc_fops);
1296 if (p_dbg_proc_file == NULL) {
1297 remove_proc_entry(PROC_FS_NAME, NULL);
1298 EGALAX_DBG(DBG_MODULE, " Could not initialize /proc/%s\n",
1299 PROC_FS_NAME);
1300 result = -EINVAL;
1301 goto out_fail;
1302 }
1303
1304 usb_register_notify(&egalax_usb_notifier);
1305 return 0;
1306
1307out_fail:
1308 return result;
1309}
1310
1311static int egalax_platform_remove(struct platform_device *pdev)
1312{
1313 if (p_dbg_proc_file != NULL)
1314 remove_proc_entry(PROC_FS_NAME, NULL);
1315
1316 if (sysfs_created)
1317 sysfs_remove_group(&egalax_misc_dev.this_device->kobj,
1318 &egalax_attr_group);
1319 sysfs_created = false;
1320
1321 if (misc_registered)
1322 misc_deregister(&egalax_misc_dev);
1323 misc_registered = false;
1324
1325 if (p_char_dev != NULL) {
1326 kfree(p_char_dev->p_fifo_buf);
1327 kfree(p_char_dev);
1328 p_char_dev = NULL;
1329 }
1330
1331 egalax_power_off();
1332
1333 gpio_free(g_reset_gpio);
1334
1335 usb_unregister_notify(&egalax_usb_notifier);
1336 return 0;
1337}
1338
1339static void egalax_platform_shutdown(struct platform_device *pdev)
1340{
1341 egalax_power_off();
1342}
1343
1344static const struct of_device_id egalax_usb_idtable[] = {
1345 { .compatible = "eeti,exc80_ts_usb" },
1346 { },
1347};
1348MODULE_DEVICE_TABLE(of, egalax_usb_idtable);
1349
1350static struct platform_driver egalax_platform_driver = {
1351 .driver = {
1352 .name = "exc80_ts_usb",
1353 .owner = THIS_MODULE,
1354 .of_match_table = egalax_usb_idtable,
1355 },
1356 .probe = egalax_platform_probe,
1357 .remove = egalax_platform_remove,
1358 .shutdown = egalax_platform_shutdown,
1359};
1360
1361static void egalax_usb_ts_exit(void)
1362{
1363 EGALAX_DBG(DBG_MODULE, " Driver exit!\n");
1364 platform_driver_unregister(&egalax_platform_driver);
1365}
1366
1367static int egalax_usb_ts_init(void)
1368{
1369 EGALAX_DBG(DBG_MODULE, " Driver init!\n");
1370 return platform_driver_register(&egalax_platform_driver);
1371}
1372
1373module_init(egalax_usb_ts_init);
1374module_exit(egalax_usb_ts_exit);
1375
1376MODULE_AUTHOR("EETI <touch_fae@eeti.com>");
1377MODULE_DESCRIPTION("egalax touch screen usb driver");
1378MODULE_LICENSE("GPL");