linux-004-egalax_i2c_touchcontroller.patch 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  1. From a12a55f6571c5992f5a88e8bbbaabf442c0be88c Mon Sep 17 00:00:00 2001
  2. From: Reinhard Russinger <reinhard@russinger.at>
  3. Date: Wed, 3 May 2017 08:25:31 +0200
  4. Subject: [PATCH 1/1] add egalax i2c touchcontroller driver
  5. ---
  6. drivers/input/touchscreen/Kconfig | 10 +
  7. drivers/input/touchscreen/Makefile | 1 +
  8. drivers/input/touchscreen/egalax_i2c.c | 961 +++++++++++++++++++++++++++++++++
  9. 3 files changed, 972 insertions(+)
  10. create mode 100644 drivers/input/touchscreen/egalax_i2c.c
  11. diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
  12. index 2fb1f43..01f4776 100644
  13. --- a/drivers/input/touchscreen/Kconfig
  14. +++ b/drivers/input/touchscreen/Kconfig
  15. @@ -318,6 +318,16 @@ config TOUCHSCREEN_FT6236
  16. To compile this driver as a module, choose M here: the
  17. module will be called ft6236.
  18. +config TOUCHSCREEN_EGALAX_I2C
  19. + tristate "EETI eGalax (egalax_i2c) multi-touch panel support for i2C"
  20. + depends on I2C && OF
  21. + help
  22. + Say Y here to enable support for I2C connected EETI
  23. + eGalax multi-touch panels.
  24. +
  25. + To compile this driver as a module, choose M here: the
  26. + module will be called egalax_i2c.
  27. +
  28. config TOUCHSCREEN_FUJITSU
  29. tristate "Fujitsu serial touchscreen"
  30. select SERIO
  31. diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
  32. index b4373d6..67ed603 100644
  33. --- a/drivers/input/touchscreen/Makefile
  34. +++ b/drivers/input/touchscreen/Makefile
  35. @@ -34,6 +34,7 @@ obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
  36. obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
  37. obj-$(CONFIG_TOUCHSCREEN_ELAN) += elants_i2c.o
  38. obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
  39. +obj-$(CONFIG_TOUCHSCREEN_EGALAX_I2C) += egalax_i2c.o
  40. obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o
  41. obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
  42. obj-$(CONFIG_TOUCHSCREEN_FT6236) += ft6236.o
  43. diff --git a/drivers/input/touchscreen/egalax_i2c.c b/drivers/input/touchscreen/egalax_i2c.c
  44. new file mode 100644
  45. index 0000000..9ee5566
  46. --- /dev/null
  47. +++ b/drivers/input/touchscreen/egalax_i2c.c
  48. @@ -0,0 +1,961 @@
  49. +/*
  50. + *
  51. + * Touch Screen I2C Driver for EETI Controller
  52. + *
  53. + * Copyright (C) 2000-2015 eGalax_eMPIA Technology Inc.
  54. + * All Rights Reserved.
  55. + *
  56. + * This program is free software; you can redistribute it and/or modify
  57. + * it under the terms of the GNU General Public License as published by
  58. + * the Free Software Foundation; either version 2 of the License, or
  59. + * (at your option) any later version.
  60. + *
  61. + * This program is distributed in the hope that it will be useful,
  62. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  63. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  64. + * GNU General Public License for more details.
  65. + *
  66. + */
  67. +
  68. +#define RELEASE_DATE "2015/04/23"
  69. +
  70. +#include <linux/module.h>
  71. +#include <linux/init.h>
  72. +#include <linux/kernel.h>
  73. +#include <linux/interrupt.h>
  74. +#include <linux/wait.h>
  75. +#include <linux/delay.h>
  76. +#include <linux/i2c.h>
  77. +#include <linux/gpio.h>
  78. +#include <linux/device.h>
  79. +#include <asm/uaccess.h>
  80. +#include <linux/kfifo.h>
  81. +#include <linux/version.h>
  82. +#include <linux/input.h>
  83. +#include <linux/irq.h>
  84. +#include <linux/timer.h>
  85. +#include <linux/proc_fs.h>
  86. +#include <linux/seq_file.h>
  87. +#include <linux/miscdevice.h>
  88. +#include <linux/slab.h>
  89. +#include <linux/poll.h>
  90. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
  91. +#include <linux/input/mt.h>
  92. +#endif
  93. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
  94. +#include <linux/of_gpio.h>
  95. +#endif
  96. +
  97. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
  98. + #define __devinit
  99. + #define __devexit
  100. + #define __devexit_p(x) x
  101. +#endif
  102. +
  103. +#ifdef CONFIG_HAS_EARLYSUSPEND
  104. + #include <linux/earlysuspend.h>
  105. + static struct early_suspend egalax_early_suspend;
  106. +#endif
  107. +
  108. +// Global define to enable function
  109. +//#define _SWITCH_XY
  110. +//#define _CONVERT_Y
  111. +
  112. +#define MAX_EVENTS 600
  113. +#define MAX_I2C_LEN 64
  114. +#define FIFO_SIZE 8192 //(PAGE_SIZE*2)
  115. +#define MAX_SUPPORT_POINT 16
  116. +#define REPORTID_MOUSE 0x01
  117. +#define REPORTID_VENDOR 0x03
  118. +#define REPORTID_MTOUCH 0x06//0x04
  119. +#define MAX_RESOLUTION 4095
  120. +
  121. +// running mode
  122. +#define MODE_STOP 0
  123. +#define MODE_WORKING 1
  124. +#define MODE_IDLE 2
  125. +#define MODE_SUSPEND 3
  126. +
  127. +struct tagMTContacts {
  128. + unsigned char ID;
  129. + signed char Status;
  130. + unsigned short X;
  131. + unsigned short Y;
  132. +};
  133. +
  134. +struct _egalax_i2c {
  135. + struct workqueue_struct *ktouch_wq;
  136. + struct work_struct work_irq;
  137. + struct delayed_work delay_work_ioctl;
  138. + struct mutex mutex_wq;
  139. + struct i2c_client *client;
  140. + unsigned char work_state;
  141. + unsigned char skip_packet;
  142. + unsigned int ioctl_cmd;
  143. + int interrupt_gpio;
  144. +};
  145. +
  146. +struct egalax_char_dev
  147. +{
  148. + int OpenCnts;
  149. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
  150. + struct kfifo* pDataKFiFo;
  151. +#else
  152. + struct kfifo DataKFiFo;
  153. +#endif
  154. + unsigned char *pFiFoBuf;
  155. + spinlock_t FiFoLock;
  156. + struct semaphore sem;
  157. + wait_queue_head_t fifo_inq;
  158. +};
  159. +
  160. +static struct _egalax_i2c *p_egalax_i2c_dev = NULL; // allocated in egalax_i2c_probe
  161. +static struct egalax_char_dev *p_char_dev = NULL; // allocated in init_module
  162. +static atomic_t egalax_char_available = ATOMIC_INIT(1);
  163. +static atomic_t wait_command_ack = ATOMIC_INIT(0);
  164. +static struct input_dev *input_dev = NULL;
  165. +static struct tagMTContacts pContactBuf[MAX_SUPPORT_POINT];
  166. +static unsigned char input_report_buf[MAX_I2C_LEN+2];
  167. +
  168. +#define DBG_MODULE 0x00000001
  169. +#define DBG_CDEV 0x00000002
  170. +#define DBG_PROC 0x00000004
  171. +#define DBG_POINT 0x00000008
  172. +#define DBG_INT 0x00000010
  173. +#define DBG_I2C 0x00000020
  174. +#define DBG_SUSP 0x00000040
  175. +#define DBG_INPUT 0x00000080
  176. +#define DBG_CONST 0x00000100
  177. +#define DBG_IDLE 0x00000200
  178. +#define DBG_WAKEUP 0x00000400
  179. +#define DBG_BUTTON 0x00000800
  180. +static unsigned int DbgLevel = DBG_MODULE|DBG_SUSP;
  181. +
  182. +#define PROC_FS_NAME "egalax_dbg"
  183. +#define PROC_FS_MAX_LEN 8
  184. +static struct proc_dir_entry *dbgProcFile;
  185. +
  186. +#define EGALAX_DBG(level, fmt, args...) do{ if( (level&DbgLevel)>0 ) \
  187. + printk( KERN_DEBUG "[egalax_i2c]: " fmt, ## args); }while(0)
  188. +
  189. +static int egalax_I2C_read(unsigned char *pBuf, unsigned short len)
  190. +{
  191. + struct i2c_msg xfer;
  192. + unsigned char cmdbuf[2]={0x27, 0x00};
  193. +
  194. + if(pBuf==NULL)
  195. + return -1;
  196. +
  197. + // Write register first
  198. + xfer.addr = p_egalax_i2c_dev->client->addr;
  199. + xfer.flags = 0;
  200. + xfer.len = 2;
  201. + xfer.buf = cmdbuf;
  202. + i2c_transfer(p_egalax_i2c_dev->client->adapter, &xfer, 1);
  203. +
  204. + // Read device data
  205. + xfer.addr = p_egalax_i2c_dev->client->addr;
  206. + xfer.flags = I2C_M_RD;
  207. + xfer.len = len;
  208. + xfer.buf = pBuf;
  209. +
  210. + if(i2c_transfer(p_egalax_i2c_dev->client->adapter, &xfer, 1) != 1)
  211. + {
  212. + EGALAX_DBG(DBG_I2C, " %s: i2c transfer fail\n", __func__);
  213. + return -EIO;
  214. + }
  215. + else
  216. + EGALAX_DBG(DBG_I2C, " %s: i2c transfer success\n", __func__);
  217. +
  218. + return 0;
  219. +}
  220. +
  221. +static int egalax_I2C_write(unsigned short reg, unsigned char *pBuf, unsigned short len)
  222. +{
  223. + unsigned char cmdbuf[4+len];
  224. + struct i2c_msg xfer;
  225. +
  226. + if(pBuf==NULL)
  227. + return -1;
  228. +
  229. + cmdbuf[0] = reg & 0x00FF;
  230. + cmdbuf[1] = (reg >> 8) & 0x00FF;
  231. + cmdbuf[2] = (len+2) & 0x00FF;
  232. + cmdbuf[3] = ((len+2) >> 8) & 0x00FF;
  233. + memcpy(cmdbuf+4, pBuf, len);
  234. +
  235. + // Write data to device
  236. + xfer.addr = p_egalax_i2c_dev->client->addr;
  237. + xfer.flags = 0;
  238. + xfer.len = sizeof(cmdbuf);
  239. + xfer.buf = cmdbuf;
  240. +
  241. + if(i2c_transfer(p_egalax_i2c_dev->client->adapter, &xfer, 1) != 1)
  242. + {
  243. + EGALAX_DBG(DBG_I2C, " %s: i2c transfer fail\n", __func__);
  244. + return -EIO;
  245. + }
  246. + else
  247. + EGALAX_DBG(DBG_I2C, " %s: i2c transfer success\n", __func__);
  248. +
  249. + return 0;
  250. +}
  251. +
  252. +static int egalax_cdev_open(struct inode *inode, struct file *filp)
  253. +{
  254. + if( !atomic_dec_and_test(&egalax_char_available) )
  255. + {
  256. + atomic_inc(&egalax_char_available);
  257. + return -EBUSY; // already open
  258. + }
  259. +
  260. + p_char_dev->OpenCnts++;
  261. + filp->private_data = p_char_dev;// Used by the read and write metheds
  262. +
  263. + EGALAX_DBG(DBG_CDEV, " CDev open done!\n");
  264. + try_module_get(THIS_MODULE);
  265. + return 0;
  266. +}
  267. +
  268. +static int egalax_cdev_release(struct inode *inode, struct file *filp)
  269. +{
  270. + struct egalax_char_dev *cdev = filp->private_data;
  271. +
  272. + atomic_inc(&egalax_char_available); // release the device
  273. +
  274. + cdev->OpenCnts--;
  275. +
  276. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
  277. + kfifo_reset( cdev->pDataKFiFo );
  278. +#else
  279. + kfifo_reset( &cdev->DataKFiFo );
  280. +#endif
  281. +
  282. + EGALAX_DBG(DBG_CDEV, " CDev release done!\n");
  283. + module_put(THIS_MODULE);
  284. + return 0;
  285. +}
  286. +
  287. +static char fifo_read_buf[MAX_I2C_LEN];
  288. +static ssize_t egalax_cdev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
  289. +{
  290. + int read_cnt, ret, fifoLen;
  291. + struct egalax_char_dev *cdev = file->private_data;
  292. +
  293. + if( down_interruptible(&cdev->sem) )
  294. + return -ERESTARTSYS;
  295. +
  296. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
  297. + fifoLen = kfifo_len(cdev->pDataKFiFo);
  298. +#else
  299. + fifoLen = kfifo_len(&cdev->DataKFiFo);
  300. +#endif
  301. +
  302. + while( fifoLen<1 ) // nothing to read
  303. + {
  304. + up(&cdev->sem); // release the lock
  305. + if( file->f_flags & O_NONBLOCK )
  306. + return -EAGAIN;
  307. +
  308. + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
  309. + if( wait_event_interruptible(cdev->fifo_inq, kfifo_len( cdev->pDataKFiFo )>0) )
  310. + #else
  311. + if( wait_event_interruptible(cdev->fifo_inq, kfifo_len( &cdev->DataKFiFo )>0) )
  312. + #endif
  313. + {
  314. + return -ERESTARTSYS; // signal: tell the fs layer to handle it
  315. + }
  316. +
  317. + if( down_interruptible(&cdev->sem) )
  318. + return -ERESTARTSYS;
  319. + }
  320. +
  321. + if(count > MAX_I2C_LEN)
  322. + count = MAX_I2C_LEN;
  323. +
  324. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
  325. + read_cnt = kfifo_get(cdev->pDataKFiFo, fifo_read_buf, count);
  326. +#else
  327. + read_cnt = kfifo_out_locked(&cdev->DataKFiFo, fifo_read_buf, count, &cdev->FiFoLock);
  328. +#endif
  329. + EGALAX_DBG(DBG_CDEV, " \"%s\" reading fifo data count=%d\n", current->comm, read_cnt);
  330. +
  331. + ret = copy_to_user(buf, fifo_read_buf, read_cnt)?-EFAULT:read_cnt;
  332. +
  333. + up(&cdev->sem);
  334. +
  335. + return ret;
  336. +}
  337. +
  338. +static ssize_t egalax_cdev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
  339. +{
  340. + struct egalax_char_dev *cdev = file->private_data;
  341. + int ret=0;
  342. + char *tmp;
  343. +
  344. + if( down_interruptible(&cdev->sem) )
  345. + return -ERESTARTSYS;
  346. +
  347. + if (count > MAX_I2C_LEN)
  348. + count = MAX_I2C_LEN;
  349. +
  350. + tmp = kzalloc(MAX_I2C_LEN, GFP_KERNEL);
  351. + if(tmp==NULL)
  352. + {
  353. + up(&cdev->sem);
  354. + return -ENOMEM;
  355. + }
  356. +
  357. + if(copy_from_user(tmp, buf, count))
  358. + {
  359. + up(&cdev->sem);
  360. + kfree(tmp);
  361. + return -EFAULT;
  362. + }
  363. +
  364. + ret = egalax_I2C_write(0x0067, tmp, MAX_I2C_LEN);
  365. +
  366. + up(&cdev->sem);
  367. + EGALAX_DBG(DBG_CDEV, " I2C writing %zu bytes.\n", count);
  368. + kfree(tmp);
  369. +
  370. + return (ret==0?count:-1);
  371. +}
  372. +
  373. +static unsigned int egalax_cdev_poll(struct file *filp, struct poll_table_struct *wait)
  374. +{
  375. + struct egalax_char_dev *cdev = filp->private_data;
  376. + unsigned int mask = 0;
  377. + int fifoLen;
  378. +
  379. + down(&cdev->sem);
  380. + poll_wait(filp, &cdev->fifo_inq, wait);
  381. +
  382. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
  383. + fifoLen = kfifo_len(cdev->pDataKFiFo);
  384. +#else
  385. + fifoLen = kfifo_len(&cdev->DataKFiFo);
  386. +#endif
  387. +
  388. + if( fifoLen > 0 )
  389. + mask |= POLLIN | POLLRDNORM; /* readable */
  390. + if( (FIFO_SIZE - fifoLen) > MAX_I2C_LEN )
  391. + mask |= POLLOUT | POLLWRNORM; /* writable */
  392. +
  393. + up(&cdev->sem);
  394. + return mask;
  395. +}
  396. +
  397. +static int egalax_proc_show(struct seq_file* seqfilp, void *v)
  398. +{
  399. + seq_printf(seqfilp, "EETI I2C for All Points.\nDebug Level: 0x%08X\nRelease Date: %s\n", DbgLevel, RELEASE_DATE);
  400. + return 0;
  401. +}
  402. +
  403. +static int egalax_proc_open(struct inode *inode, struct file *filp)
  404. +{
  405. + EGALAX_DBG(DBG_PROC, " \"%s\" call proc_open\n", current->comm);
  406. + return single_open(filp, egalax_proc_show, NULL);
  407. +}
  408. +
  409. +static ssize_t egalax_proc_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
  410. +{
  411. + char procfs_buffer_size = 0;
  412. + unsigned char procfs_buf[PROC_FS_MAX_LEN+1] = {0};
  413. +
  414. + EGALAX_DBG(DBG_PROC, " \"%s\" call proc_write\n", current->comm);
  415. +
  416. + procfs_buffer_size = count;
  417. + if(procfs_buffer_size > PROC_FS_MAX_LEN )
  418. + procfs_buffer_size = PROC_FS_MAX_LEN+1;
  419. +
  420. + if( copy_from_user(procfs_buf, buf, procfs_buffer_size) )
  421. + {
  422. + EGALAX_DBG(DBG_PROC, " proc_write faied at copy_from_user\n");
  423. + return -EFAULT;
  424. + }
  425. +
  426. + sscanf(procfs_buf, "%x", &DbgLevel);
  427. + EGALAX_DBG(DBG_PROC, " Switch Debug Level to 0x%08X\n", DbgLevel);
  428. +
  429. + return procfs_buffer_size;
  430. +}
  431. +
  432. +#define MAX_POINT_PER_PACKET 5
  433. +#define POINT_STRUCT_SIZE 10
  434. +static int TotalPtsCnt=0, RecvPtsCnt=0;
  435. +static void ProcessReport(unsigned char *buf, struct _egalax_i2c *p_egalax_i2c)
  436. +{
  437. + unsigned char i, index=0, cnt_down=0, cnt_up=0, shift=0;
  438. + unsigned char status=0;
  439. + unsigned short contactID=0, x=0, y=0;
  440. +
  441. + if(TotalPtsCnt<=0)
  442. + {
  443. + if(buf[1]==0 || buf[1]>MAX_SUPPORT_POINT)
  444. + {
  445. + EGALAX_DBG(DBG_POINT, " NumsofContacts mismatch, skip packet\n");
  446. + return;
  447. + }
  448. +
  449. + TotalPtsCnt = buf[1];
  450. + RecvPtsCnt = 0;
  451. + }
  452. + else if(buf[1]>0)
  453. + {
  454. + TotalPtsCnt = RecvPtsCnt = 0;
  455. + EGALAX_DBG(DBG_POINT, " NumsofContacts mismatch, skip packet\n");
  456. + return;
  457. + }
  458. +
  459. + while(index<MAX_POINT_PER_PACKET)
  460. + {
  461. + shift = index * POINT_STRUCT_SIZE + 2;
  462. + status = buf[shift] & 0x01;
  463. + contactID = buf[shift+1];
  464. + x = ((buf[shift+3]<<8) + buf[shift+2]);
  465. + y = ((buf[shift+5]<<8) + buf[shift+4]);
  466. +
  467. + if( contactID>=MAX_SUPPORT_POINT )
  468. + {
  469. + TotalPtsCnt = RecvPtsCnt = 0;
  470. + EGALAX_DBG(DBG_POINT, " Get error ContactID.\n");
  471. + return;
  472. + }
  473. +
  474. + EGALAX_DBG(DBG_POINT, " Get Point[%d] Update: Status=%d X=%d Y=%d\n", contactID, status, x, y);
  475. +
  476. + #ifdef _SWITCH_XY
  477. + short tmp = x;
  478. + x = y;
  479. + y = tmp;
  480. + #endif
  481. + #ifdef _CONVERT_X
  482. + x = MAX_RESOLUTION-x;
  483. + #endif
  484. +
  485. + #ifdef _CONVERT_Y
  486. + y = MAX_RESOLUTION-y;
  487. + #endif
  488. +
  489. + pContactBuf[RecvPtsCnt].ID = contactID;
  490. + pContactBuf[RecvPtsCnt].Status = status;
  491. + pContactBuf[RecvPtsCnt].X = x;
  492. + pContactBuf[RecvPtsCnt].Y = y;
  493. +
  494. + RecvPtsCnt++;
  495. + index++;
  496. +
  497. + // Recv all points, send input report
  498. + if(RecvPtsCnt==TotalPtsCnt)
  499. + {
  500. + for(i=0; i<RecvPtsCnt; i++)
  501. + {
  502. + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
  503. + input_mt_slot(input_dev, pContactBuf[i].ID);
  504. + input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, pContactBuf[i].Status);
  505. + if(pContactBuf[i].Status)
  506. + {
  507. + input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, pContactBuf[i].Status);
  508. + input_report_abs(input_dev, ABS_MT_POSITION_X, pContactBuf[i].X);
  509. + input_report_abs(input_dev, ABS_MT_POSITION_Y, pContactBuf[i].Y);
  510. + }
  511. + #else
  512. + input_report_abs(input_dev, ABS_MT_TRACKING_ID, pContactBuf[i].ID);
  513. + input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, pContactBuf[i].Status);
  514. + input_report_abs(input_dev, ABS_MT_POSITION_X, pContactBuf[i].X);
  515. + input_report_abs(input_dev, ABS_MT_POSITION_Y, pContactBuf[i].Y);
  516. + input_report_abs(input_dev, ABS_MT_WIDTH_MAJOR, 0);
  517. + input_mt_sync(input_dev);
  518. + #endif
  519. +
  520. + if(pContactBuf[i].Status)
  521. + cnt_down++;
  522. + else
  523. + cnt_up++;
  524. + }
  525. + #ifndef CONFIG_HAS_EARLYSUSPEND //We use this config to distinguish Linux and Android
  526. + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
  527. + input_mt_report_pointer_emulation(input_dev, true);
  528. + #endif
  529. + #endif
  530. + input_sync(input_dev);
  531. + EGALAX_DBG(DBG_POINT, " Input sync point data done! (Down:%d Up:%d)\n", cnt_down, cnt_up);
  532. +
  533. + TotalPtsCnt = RecvPtsCnt = 0;
  534. + return;
  535. + }
  536. + }
  537. +}
  538. +
  539. +static struct input_dev * allocate_Input_Dev(void)
  540. +{
  541. + int ret;
  542. + struct input_dev *pInputDev=NULL;
  543. +
  544. + pInputDev = input_allocate_device();
  545. + if(pInputDev == NULL)
  546. + {
  547. + EGALAX_DBG(DBG_MODULE, " Failed to allocate input device\n");
  548. + return NULL;//-ENOMEM;
  549. + }
  550. +
  551. + pInputDev->name = "eGalax_Touch_Screen";
  552. + pInputDev->phys = "I2C";
  553. + pInputDev->id.bustype = BUS_I2C;
  554. + pInputDev->id.vendor = 0x0EEF;
  555. + pInputDev->id.product = 0x0020;
  556. + pInputDev->id.version = 0x0001;
  557. +
  558. + set_bit(EV_ABS, pInputDev->evbit);
  559. +#ifndef CONFIG_HAS_EARLYSUSPEND //We use this config to distinguish Linux and Android
  560. + set_bit(EV_KEY, pInputDev->evbit);
  561. + __set_bit(BTN_TOUCH, pInputDev->keybit);
  562. + input_set_abs_params(pInputDev, ABS_X, 0, MAX_RESOLUTION, 0, 0);
  563. + input_set_abs_params(pInputDev, ABS_Y, 0, MAX_RESOLUTION, 0, 0);
  564. +#endif
  565. +
  566. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
  567. + __set_bit(INPUT_PROP_DIRECT, pInputDev->propbit);
  568. + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
  569. + input_mt_init_slots(pInputDev, MAX_SUPPORT_POINT, 0);
  570. + #else
  571. + input_mt_init_slots(pInputDev, MAX_SUPPORT_POINT);
  572. + #endif
  573. + input_set_abs_params(pInputDev, ABS_MT_POSITION_X, 0, MAX_RESOLUTION, 0, 0);
  574. + input_set_abs_params(pInputDev, ABS_MT_POSITION_Y, 0, MAX_RESOLUTION, 0, 0);
  575. + input_set_abs_params(pInputDev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
  576. +#else
  577. + input_set_abs_params(pInputDev, ABS_MT_POSITION_X, 0, MAX_RESOLUTION, 0, 0);
  578. + input_set_abs_params(pInputDev, ABS_MT_POSITION_Y, 0, MAX_RESOLUTION, 0, 0);
  579. + input_set_abs_params(pInputDev, ABS_MT_WIDTH_MAJOR, 0, MAX_RESOLUTION, 0, 0); //Size
  580. + input_set_abs_params(pInputDev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); //Pressure
  581. + input_set_abs_params(pInputDev, ABS_MT_TRACKING_ID, 0, MAX_SUPPORT_POINT, 0, 0);
  582. +#endif // #if LINUX_VERSION_CODE > KERNEL_VERSION(3,0,0)
  583. +
  584. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
  585. + input_set_events_per_packet(pInputDev, MAX_EVENTS);
  586. +#endif
  587. +
  588. + ret = input_register_device(pInputDev);
  589. + if(ret)
  590. + {
  591. + EGALAX_DBG(DBG_MODULE, " Unable to register input device.\n");
  592. + input_free_device(pInputDev);
  593. + pInputDev = NULL;
  594. + }
  595. +
  596. + return pInputDev;
  597. +}
  598. +
  599. +static int egalax_i2c_measure(struct _egalax_i2c *egalax_i2c)
  600. +{
  601. + int ret=0, frameLen=0, loop=3, i;
  602. +
  603. + EGALAX_DBG(DBG_INT, " egalax_i2c_measure\n");
  604. +
  605. + if( egalax_I2C_read(input_report_buf, MAX_I2C_LEN+2) < 0)
  606. + {
  607. + EGALAX_DBG(DBG_I2C, " I2C read input report fail!\n");
  608. + return -1;
  609. + }
  610. +
  611. + if( DbgLevel&DBG_I2C )
  612. + {
  613. + char dbgmsg[(MAX_I2C_LEN+2)*4];
  614. + for(i=0; i<MAX_I2C_LEN+2; i++)
  615. + sprintf(dbgmsg+i*4, "[%02X]", input_report_buf[i]);
  616. + EGALAX_DBG(DBG_I2C, " Buf=%s\n", dbgmsg);
  617. + }
  618. +
  619. + frameLen = input_report_buf[0] + (input_report_buf[1]<<8);
  620. + EGALAX_DBG(DBG_I2C, " I2C read data with Len=%d\n", frameLen);
  621. +
  622. + if(frameLen==0)
  623. + {
  624. + EGALAX_DBG(DBG_MODULE, " Device reset\n");
  625. + return -1;
  626. + }
  627. +
  628. + switch(input_report_buf[2])
  629. + {
  630. + case REPORTID_MTOUCH:
  631. + if( !egalax_i2c->skip_packet && egalax_i2c->work_state==MODE_WORKING )
  632. + ProcessReport(input_report_buf+2, egalax_i2c);
  633. + ret = 0;
  634. + break;
  635. + case REPORTID_VENDOR:
  636. + atomic_set(&wait_command_ack, 1);
  637. + EGALAX_DBG(DBG_I2C, " I2C get vendor command packet\n");
  638. +
  639. + if( p_char_dev->OpenCnts>0 ) // If someone reading now! put the data into the buffer!
  640. + {
  641. + loop=3;
  642. + do {
  643. + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
  644. + ret = wait_event_timeout(p_char_dev->fifo_inq, (FIFO_SIZE-kfifo_len(p_char_dev->pDataKFiFo))>=MAX_I2C_LEN, HZ);
  645. + #else
  646. + ret = wait_event_timeout(p_char_dev->fifo_inq, kfifo_avail(&p_char_dev->DataKFiFo)>=MAX_I2C_LEN, HZ);
  647. + #endif
  648. + }while(ret<=0 && --loop);
  649. +
  650. + if(ret>0) // fifo size is ready
  651. + {
  652. + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
  653. + ret = kfifo_put(p_char_dev->pDataKFiFo, input_report_buf+2, MAX_I2C_LEN);
  654. + #else
  655. + ret = kfifo_in_locked(&p_char_dev->DataKFiFo, input_report_buf+2, MAX_I2C_LEN, &p_char_dev->FiFoLock);
  656. + #endif
  657. +
  658. + wake_up_interruptible( &p_char_dev->fifo_inq );
  659. + }
  660. + else
  661. + EGALAX_DBG(DBG_CDEV, " [Warning] Can't write data because fifo size is overflow.\n");
  662. + }
  663. +
  664. + break;
  665. + default:
  666. + EGALAX_DBG(DBG_I2C, " I2C read error data with hedaer=%d\n", input_report_buf[2]);
  667. + ret = -1;
  668. + break;
  669. + }
  670. +
  671. + return ret;
  672. +}
  673. +
  674. +static void egalax_i2c_wq_irq(struct work_struct *work)
  675. +{
  676. + struct _egalax_i2c *egalax_i2c = container_of(work, struct _egalax_i2c, work_irq);
  677. + struct i2c_client *client = egalax_i2c->client;
  678. +
  679. + EGALAX_DBG(DBG_INT, " egalax_i2c_wq run\n");
  680. +
  681. + /*continue recv data*/
  682. + while( !gpio_get_value(egalax_i2c->interrupt_gpio) )
  683. + {
  684. + egalax_i2c_measure(egalax_i2c);
  685. + schedule();
  686. + }
  687. +
  688. + if( egalax_i2c->skip_packet > 0 )
  689. + egalax_i2c->skip_packet = 0;
  690. +
  691. + enable_irq(client->irq);
  692. +
  693. + EGALAX_DBG(DBG_INT, " egalax_i2c_wq leave\n");
  694. +}
  695. +
  696. +static irqreturn_t egalax_i2c_interrupt(int irq, void *dev_id)
  697. +{
  698. + struct _egalax_i2c *egalax_i2c = (struct _egalax_i2c *)dev_id;
  699. +
  700. + EGALAX_DBG(DBG_INT, " INT with irq:%d\n", irq);
  701. +
  702. + disable_irq_nosync(irq);
  703. +
  704. + queue_work(egalax_i2c->ktouch_wq, &egalax_i2c->work_irq);
  705. +
  706. + return IRQ_HANDLED;
  707. +}
  708. +
  709. +#ifdef CONFIG_HAS_EARLYSUSPEND
  710. +static void egalax_i2c_early_suspend(struct early_suspend *handler)
  711. +{
  712. + pm_message_t state;
  713. + state.event = PM_EVENT_SUSPEND;
  714. +
  715. + EGALAX_DBG(DBG_SUSP, " %s\n", __func__);
  716. + egalax_i2c_pm_suspend(p_egalax_i2c_dev->client, state);
  717. +}
  718. +
  719. +static void egalax_i2c_early_resume(struct early_suspend *handler)
  720. +{
  721. + EGALAX_DBG(DBG_SUSP, " %s\n", __func__);
  722. + egalax_i2c_pm_resume(p_egalax_i2c_dev->client);
  723. +}
  724. +#endif // #ifdef CONFIG_HAS_EARLYSUSPEND
  725. +
  726. +static int __devinit egalax_i2c_probe(struct i2c_client *client, const struct i2c_device_id *idp)
  727. +{
  728. + int ret;
  729. + struct device_node *devnode;
  730. +
  731. + EGALAX_DBG(DBG_MODULE, " Start probe\n");
  732. +
  733. + p_egalax_i2c_dev = (struct _egalax_i2c *)kzalloc(sizeof(struct _egalax_i2c), GFP_KERNEL);
  734. + if (!p_egalax_i2c_dev)
  735. + {
  736. + EGALAX_DBG(DBG_MODULE, " Request memory failed\n");
  737. + ret = -ENOMEM;
  738. + goto fail1;
  739. + }
  740. +
  741. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
  742. + devnode = client->dev.of_node;
  743. + if(devnode) //if use the device tree config
  744. + {
  745. + p_egalax_i2c_dev->interrupt_gpio = of_get_named_gpio(devnode, "int-gpios", 0);
  746. + }
  747. +#else
  748. + {
  749. + p_egalax_i2c_dev->interrupt_gpio = irq_to_gpio(client->irq);
  750. + }
  751. +#endif
  752. +
  753. + if( !gpio_is_valid(p_egalax_i2c_dev->interrupt_gpio) )
  754. + {
  755. + ret = -ENODEV;
  756. + goto fail1;
  757. + }
  758. + ret = gpio_request(p_egalax_i2c_dev->interrupt_gpio, "Touch IRQ");
  759. + if(ret<0)
  760. + {
  761. + EGALAX_DBG(DBG_MODULE, " gpio_request[%d] failed: %d\n", p_egalax_i2c_dev->interrupt_gpio, ret);
  762. + if(ret!=-EBUSY)
  763. + goto fail1;
  764. + }
  765. + gpio_direction_input(p_egalax_i2c_dev->interrupt_gpio);
  766. +
  767. + input_dev = allocate_Input_Dev();
  768. + if(input_dev==NULL)
  769. + {
  770. + EGALAX_DBG(DBG_MODULE, " allocate_Input_Dev failed\n");
  771. + ret = -EINVAL;
  772. + goto fail2;
  773. + }
  774. + EGALAX_DBG(DBG_MODULE, " Register input device done\n");
  775. +
  776. + p_egalax_i2c_dev->client = client;
  777. + mutex_init(&p_egalax_i2c_dev->mutex_wq);
  778. +
  779. + p_egalax_i2c_dev->ktouch_wq = create_singlethread_workqueue("egalax_touch_wq");
  780. + INIT_WORK(&p_egalax_i2c_dev->work_irq, egalax_i2c_wq_irq);
  781. +
  782. + i2c_set_clientdata(client, p_egalax_i2c_dev);
  783. +
  784. + if( gpio_get_value(p_egalax_i2c_dev->interrupt_gpio) )
  785. + p_egalax_i2c_dev->skip_packet = 0;
  786. + else
  787. + p_egalax_i2c_dev->skip_packet = 1;
  788. +
  789. + p_egalax_i2c_dev->work_state = MODE_WORKING;
  790. +
  791. + ret = request_irq(client->irq, egalax_i2c_interrupt, IRQF_TRIGGER_LOW, client->name, p_egalax_i2c_dev);
  792. + if( ret )
  793. + {
  794. + EGALAX_DBG(DBG_MODULE, " Request irq(%d) failed\n", client->irq);
  795. + goto fail3;
  796. + }
  797. + EGALAX_DBG(DBG_MODULE, " Request irq(%d) gpio(%d) with result:%d\n", client->irq, p_egalax_i2c_dev->interrupt_gpio, ret);
  798. +
  799. +#ifdef CONFIG_HAS_EARLYSUSPEND
  800. + egalax_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
  801. + egalax_early_suspend.suspend = egalax_i2c_early_suspend;
  802. + egalax_early_suspend.resume = egalax_i2c_early_resume;
  803. + register_early_suspend(&egalax_early_suspend);
  804. + EGALAX_DBG(DBG_MODULE, " Register early_suspend done\n");
  805. +#endif
  806. +
  807. + EGALAX_DBG(DBG_MODULE, " I2C probe done\n");
  808. + return 0;
  809. +
  810. +fail3:
  811. + i2c_set_clientdata(client, NULL);
  812. + destroy_workqueue(p_egalax_i2c_dev->ktouch_wq);
  813. + free_irq(client->irq, p_egalax_i2c_dev);
  814. + input_unregister_device(input_dev);
  815. + input_dev = NULL;
  816. +fail2:
  817. + gpio_free(p_egalax_i2c_dev->interrupt_gpio);
  818. +fail1:
  819. + kfree(p_egalax_i2c_dev);
  820. + p_egalax_i2c_dev = NULL;
  821. +
  822. + EGALAX_DBG(DBG_MODULE, " I2C probe failed\n");
  823. + return ret;
  824. +}
  825. +
  826. +static int __devexit egalax_i2c_remove(struct i2c_client *client)
  827. +{
  828. + struct _egalax_i2c *egalax_i2c = i2c_get_clientdata(client);
  829. +
  830. + egalax_i2c->work_state = MODE_STOP;
  831. +
  832. + cancel_work_sync(&egalax_i2c->work_irq);
  833. +
  834. + if(client->irq)
  835. + {
  836. + disable_irq(client->irq);
  837. + free_irq(client->irq, egalax_i2c);
  838. + }
  839. +
  840. + gpio_free(egalax_i2c->interrupt_gpio);
  841. +
  842. + if(egalax_i2c->ktouch_wq)
  843. + destroy_workqueue(egalax_i2c->ktouch_wq);
  844. +
  845. +#ifdef CONFIG_HAS_EARLYSUSPEND
  846. + unregister_early_suspend(&egalax_early_suspend);
  847. +#endif
  848. +
  849. + if(input_dev)
  850. + {
  851. + EGALAX_DBG(DBG_MODULE, " Unregister input device\n");
  852. + input_unregister_device(input_dev);
  853. + input_dev = NULL;
  854. + }
  855. +
  856. + i2c_set_clientdata(client, NULL);
  857. + kfree(egalax_i2c);
  858. + p_egalax_i2c_dev = NULL;
  859. +
  860. + return 0;
  861. +}
  862. +
  863. +static const struct i2c_device_id egalax_i2c_idtable[] = {
  864. + { "egalax_i2c", 0 },
  865. + { }
  866. +};
  867. +
  868. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
  869. +static const struct of_device_id egalax_i2c_dt_ids[] = {
  870. + { .compatible = "eeti,egalax_i2c" },
  871. + { }
  872. +};
  873. +#endif
  874. +
  875. +MODULE_DEVICE_TABLE(i2c, egalax_i2c_idtable);
  876. +
  877. +static struct i2c_driver egalax_i2c_driver = {
  878. + .driver = {
  879. + .name = "egalax_i2c",
  880. + .owner = THIS_MODULE,
  881. + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
  882. + .of_match_table = egalax_i2c_dt_ids,
  883. + #endif
  884. + },
  885. + .id_table = egalax_i2c_idtable,
  886. + .probe = egalax_i2c_probe,
  887. + .remove = __devexit_p(egalax_i2c_remove),
  888. +};
  889. +
  890. +static const struct file_operations egalax_cdev_fops = {
  891. + .owner = THIS_MODULE,
  892. + .read = egalax_cdev_read,
  893. + .write = egalax_cdev_write,
  894. + .open = egalax_cdev_open,
  895. + .release= egalax_cdev_release,
  896. + .poll = egalax_cdev_poll,
  897. +};
  898. +
  899. +static const struct file_operations egalax_proc_fops = {
  900. + .owner = THIS_MODULE,
  901. + .open = egalax_proc_open,
  902. + .read = seq_read,
  903. + .write = egalax_proc_write,
  904. + .llseek = seq_lseek,
  905. + .release = single_release,
  906. +};
  907. +
  908. +static struct miscdevice egalax_misc_dev = {
  909. + .minor = MISC_DYNAMIC_MINOR,
  910. + .name = "egalax_i2c",
  911. + .fops = &egalax_cdev_fops,
  912. +};
  913. +
  914. +static void egalax_i2c_ts_exit(void)
  915. +{
  916. + if(p_char_dev)
  917. + {
  918. + if( p_char_dev->pFiFoBuf )
  919. + kfree(p_char_dev->pFiFoBuf);
  920. +
  921. + kfree(p_char_dev);
  922. + p_char_dev = NULL;
  923. + }
  924. +
  925. + misc_deregister(&egalax_misc_dev);
  926. +
  927. + i2c_del_driver(&egalax_i2c_driver);
  928. +
  929. + remove_proc_entry(PROC_FS_NAME, NULL);
  930. +
  931. + EGALAX_DBG(DBG_MODULE, " Exit driver done!\n");
  932. +}
  933. +
  934. +static struct egalax_char_dev* setup_chardev(void)
  935. +{
  936. + struct egalax_char_dev *pCharDev;
  937. +
  938. + pCharDev = kzalloc(1*sizeof(struct egalax_char_dev), GFP_KERNEL);
  939. + if(!pCharDev)
  940. + goto fail_cdev;
  941. +
  942. + spin_lock_init( &pCharDev->FiFoLock );
  943. + pCharDev->pFiFoBuf = kzalloc(sizeof(unsigned char)*FIFO_SIZE, GFP_KERNEL);
  944. + if(!pCharDev->pFiFoBuf)
  945. + goto fail_fifobuf;
  946. +
  947. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
  948. + pCharDev->pDataKFiFo = kfifo_init(pCharDev->pFiFoBuf, FIFO_SIZE, GFP_KERNEL, &pCharDev->FiFoLock);
  949. + if( pCharDev->pDataKFiFo==NULL )
  950. + goto fail_kfifo;
  951. +#else
  952. + kfifo_init(&pCharDev->DataKFiFo, pCharDev->pFiFoBuf, FIFO_SIZE);
  953. + if( !kfifo_initialized(&pCharDev->DataKFiFo) )
  954. + goto fail_kfifo;
  955. +#endif
  956. +
  957. + pCharDev->OpenCnts = 0;
  958. + sema_init(&pCharDev->sem, 1);
  959. + init_waitqueue_head(&pCharDev->fifo_inq);
  960. +
  961. + return pCharDev;
  962. +
  963. +fail_kfifo:
  964. + kfree(pCharDev->pFiFoBuf);
  965. +fail_fifobuf:
  966. + kfree(pCharDev);
  967. +fail_cdev:
  968. + return NULL;
  969. +}
  970. +
  971. +static int egalax_i2c_ts_init(void)
  972. +{
  973. + int result;
  974. +
  975. + result = misc_register(&egalax_misc_dev);
  976. + if(result)
  977. + {
  978. + EGALAX_DBG(DBG_MODULE, " misc device register failed\n");
  979. + goto fail;
  980. + }
  981. +
  982. + p_char_dev = setup_chardev(); // allocate the character device
  983. + if(!p_char_dev)
  984. + {
  985. + result = -ENOMEM;
  986. + goto fail;
  987. + }
  988. +
  989. + dbgProcFile = proc_create(PROC_FS_NAME, S_IRUGO|S_IWUGO, NULL, &egalax_proc_fops);
  990. + if (dbgProcFile == NULL)
  991. + {
  992. + remove_proc_entry(PROC_FS_NAME, NULL);
  993. + EGALAX_DBG(DBG_MODULE, " Could not initialize /proc/%s\n", PROC_FS_NAME);
  994. + }
  995. +
  996. + EGALAX_DBG(DBG_MODULE, " Driver init done!\n");
  997. + return i2c_add_driver(&egalax_i2c_driver);
  998. +
  999. +fail:
  1000. + egalax_i2c_ts_exit();
  1001. + return result;
  1002. +}
  1003. +
  1004. +module_init(egalax_i2c_ts_init);
  1005. +module_exit(egalax_i2c_ts_exit);
  1006. +
  1007. +MODULE_AUTHOR("EETI <touch_fae@eeti.com>");
  1008. +MODULE_DESCRIPTION("egalax all points controller i2c driver");
  1009. +MODULE_LICENSE("GPL");
  1010. --
  1011. 1.9.1