import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / input / touchscreen / mediatek / pixcir168 / pixcir168_driver.c
CommitLineData
6fa3eb70
S
1#include <linux/init.h>
2#include <linux/module.h>
3#include <linux/delay.h>
4#include <linux/i2c.h>
5#include <linux/input.h>
6#include <linux/slab.h>
7#include <linux/gpio.h>
8#include <linux/sched.h>
9#include <linux/kthread.h>
10#include <linux/bitops.h>
11#include <linux/kernel.h>
12#include <linux/delay.h>
13#include <linux/byteorder/generic.h>
14#ifdef CONFIG_HAS_EARLYSUSPEND
15#include <linux/earlysuspend.h>
16#endif
17#include <linux/interrupt.h>
18#include <linux/time.h>
19#include <linux/rtpm_prio.h>
20#include <linux/dma-mapping.h>
21
22#include "tpd_custom_pixcir168.h"
23#include "tpd.h"
24#include <cust_eint.h>
25
26#ifndef TPD_NO_GPIO
27#include "cust_gpio_usage.h"
28#endif
29
30#define ABS(x) ((x<0)?-x:x)
31
32
33extern struct tpd_device *tpd;
34
35static int tpd_flag = 0;
36static int tpd_halt = 0;
37static u8 *I2CDMABuf_va = 0;
38static u32 I2CDMABuf_pa = 0;
39static struct task_struct *thread = NULL;
40static DECLARE_WAIT_QUEUE_HEAD(waiter);
41
42#ifdef TPD_HAVE_BUTTON
43static int tpd_keys_local[TPD_KEY_COUNT] = TPD_KEYS;
44static int tpd_keys_dim_local[TPD_KEY_COUNT][4] = TPD_KEYS_DIM;
45#endif
46#if (defined(TPD_WARP_START) && defined(TPD_WARP_END))
47static int tpd_wb_start_local[TPD_WARP_CNT] = TPD_WARP_START;
48static int tpd_wb_end_local[TPD_WARP_CNT] = TPD_WARP_END;
49#endif
50#if (defined(TPD_HAVE_CALIBRATION) && !defined(TPD_CUSTOM_CALIBRATION))
51//static int tpd_calmat_local[8] = TPD_CALIBRATION_MATRIX;
52static int tpd_def_calmat_local[8] = TPD_CALIBRATION_MATRIX;
53#endif
54
55static void tpd_eint_interrupt_handler(void);
56static int touch_event_handler(void *unused);
57static int tpd_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
58static int tpd_i2c_detect(struct i2c_client *client, struct i2c_board_info *info);
59static int tpd_i2c_remove(struct i2c_client *client);
60#if 0
61extern void mt65xx_eint_unmask(unsigned int line);
62extern void mt65xx_eint_mask(unsigned int line);
63extern void mt65xx_eint_set_hw_debounce(kal_uint8 eintno, kal_uint32 ms);
64extern kal_uint32 mt65xx_eint_set_sens(kal_uint8 eintno, kal_bool sens);
65extern void mt65xx_eint_registration(kal_uint8 eintno, kal_bool Dbounce_En,
66 kal_bool ACT_Polarity, void (EINT_FUNC_PTR)(void),
67 kal_bool auto_umask);
68#endif
69static struct i2c_client *i2c_client = NULL;
70static const struct i2c_device_id tpd_i2c_id[] = {{"mtk-tpd",0},{}};
71static unsigned short force[] = {0, 0xB8, I2C_CLIENT_END,I2C_CLIENT_END};
72static const unsigned short * const forces[] = { force, NULL };
73//static struct i2c_client_address_data addr_data = { .forces = forces,};
74static struct i2c_board_info __initdata i2c_tpd = { I2C_BOARD_INFO("mtk-tpd", (0xB8>>1))};
75
76
77struct i2c_driver tpd_i2c_driver = {
78 .probe = tpd_i2c_probe,
79 .remove = tpd_i2c_remove,
80 .detect = tpd_i2c_detect,
81 .driver.name = "mtk-tpd",
82 .id_table = tpd_i2c_id,
83 .address_list = (const unsigned short*) forces,
84};
85
86static int tpd_i2c_detect(struct i2c_client *client, struct i2c_board_info *info) {
87 strcpy(info->type, "mtk-tpd");
88 return 0;
89}
90
91/*
92static int tpd_i2c_write(struct i2c_client *client, const uint8_t *buf, int len)
93{
94 int i = 0;
95 for(i = 0 ; i < len; i++)
96 {
97 I2CDMABuf_va[i] = buf[i];
98 }
99
100 if(len < 8)
101 {
102 client->addr = ( client->addr & I2C_MASK_FLAG ) | I2C_ENEXT_FLAG;
103 return i2c_master_send(client, buf, len);
104 }
105 else
106 {
107 client->addr = client->addr & I2C_MASK_FLAG | I2C_DMA_FLAG | I2C_ENEXT_FLAG;
108 return i2c_master_send(client, I2CDMABuf_pa, len);
109 }
110}
111*/
112
113static int tpd_i2c_read(struct i2c_client *client, uint8_t *buf, int len)
114{
115 int i = 0, ret = 0;
116
117 if(len < 8)
118 {
119 client->addr = ( client->addr & I2C_MASK_FLAG ) | I2C_ENEXT_FLAG;
120 return i2c_master_recv(client, buf, len);
121 }
122 else
123 {
124 client->addr = ( ( client->addr & I2C_MASK_FLAG ) | I2C_DMA_FLAG ) | I2C_ENEXT_FLAG;
125 ret = i2c_master_recv(client, (u8 *)I2CDMABuf_pa, len);
126
127 if(ret < 0)
128 {
129 return ret;
130 }
131
132 for(i = 0; i < len; i++)
133 {
134 buf[i] = I2CDMABuf_va[i];
135 }
136 }
137 return ret;
138}
139
140static int tpd_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) {
141 int err = 0;// ret = -1;
142
143 #ifdef TPD_NO_GPIO
144 u16 temp;
145 temp = *(volatile u16 *) TPD_RESET_PIN_ADDR;
146 temp = temp | 0x40;
147 *(volatile u16 *) TPD_RESET_PIN_ADDR = temp;
148 #endif
149 i2c_client = client;
150
151 printk("MediaTek touch panel i2c probe\n");
152
153 #ifndef TPD_NO_GPIO
154
155 mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);
156 mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);
157 mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ZERO);
158 msleep(10);
159 mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE);
160
161 mt_set_gpio_mode(GPIO_CTP_EINT_PIN, GPIO_CTP_EINT_PIN_M_EINT);
162 mt_set_gpio_dir(GPIO_CTP_EINT_PIN, GPIO_DIR_IN);
163 mt_set_gpio_pull_enable(GPIO_CTP_EINT_PIN, GPIO_PULL_ENABLE);
164 mt_set_gpio_pull_select(GPIO_CTP_EINT_PIN, GPIO_PULL_UP);
165 #endif
166
167 msleep(50);
168
169 I2CDMABuf_va = (u8 *)dma_alloc_coherent(NULL, 4096, &I2CDMABuf_pa, GFP_KERNEL);
170 if(!I2CDMABuf_va)
171 {
172 printk("Allocate Touch DMA I2C Buffer failed!\n");
173 return -1;
174 }
175
176 thread = kthread_run(touch_event_handler, 0, TPD_DEVICE);
177 if (IS_ERR(thread)) {
178 err = PTR_ERR(thread);
179 TPD_DMESG(TPD_DEVICE " failed to create kernel thread: %d\n", err);
180 }
181
182 tpd_load_status = 1;
183
184 //mt65xx_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_SENSITIVE);
185 //mt65xx_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);
186 mt_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_TYPE, tpd_eint_interrupt_handler, 1);
187 mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
188
189 printk("MediaTek touch panel i2c probe success\n");
190
191 return 0;
192}
193
194void tpd_eint_interrupt_handler(void)
195{
196 TPD_DEBUG_PRINT_INT;
197 tpd_flag=1;
198 wake_up_interruptible(&waiter);
199}
200
201static int tpd_i2c_remove(struct i2c_client *client)
202{
203 if(I2CDMABuf_va)
204 {
205 dma_free_coherent(NULL, 4096, I2CDMABuf_va, I2CDMABuf_pa);
206 I2CDMABuf_va = NULL;
207 I2CDMABuf_pa = 0;
208 }
209 return 0;
210}
211
212void tpd_down(int raw_x, int raw_y, int x, int y, int p) {
213 input_report_abs(tpd->dev, ABS_PRESSURE, 128);
214 input_report_key(tpd->dev, BTN_TOUCH, 1);
215 input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 128);
216 input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, 128);
217 input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
218 input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
219 input_mt_sync(tpd->dev);
220 TPD_DEBUG("D[%4d %4d %4d]\n", x, y, p);
221 TPD_EM_PRINT(raw_x, raw_y, x, y, p, 1);
222}
223
224void tpd_up(int raw_x, int raw_y, int x, int y, int p) {
225 //input_report_abs(tpd->dev, ABS_PRESSURE, 0);
226 input_report_key(tpd->dev, BTN_TOUCH, 0);
227 //input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 0);
228 //input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, 0);
229 //input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
230 //input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
231 input_mt_sync(tpd->dev);
232 TPD_DEBUG("U[%4d %4d %4d]\n", x, y, 0);
233 TPD_EM_PRINT(raw_x, raw_y, x, y, p, 0);
234}
235
236static int touch_event_handler(void *unused)
237{
238 struct sched_param param = { .sched_priority = RTPM_PRIO_TPD };
239 static int x1, y1, x2, y2, raw_x1, raw_y1, raw_x2, raw_y2;
240 int temp_x1 = x1, temp_y1 = y1, temp_raw_x1 = raw_x1, temp_raw_y1 = raw_y1;
241 int lastUp_x = 0, lastUp_y = 0;
242 char buffer[10];
243 int ret = -1, touching, oldtouching;//int pending = 0
244 unsigned char Wrbuf[1] = {0};
245
246 sched_setscheduler(current, SCHED_RR, &param);
247 do{
248 set_current_state(TASK_INTERRUPTIBLE);
249 while (tpd_halt) {tpd_flag = 0; msleep(20);}
250 wait_event_interruptible(waiter, tpd_flag != 0);
251 tpd_flag = 0;
252 TPD_DEBUG_SET_TIME;
253 set_current_state(TASK_RUNNING);
254
255 i2c_client->addr = ( i2c_client->addr & I2C_MASK_FLAG ) | I2C_ENEXT_FLAG;
256 ret = i2c_master_send(i2c_client, Wrbuf, 1);
257 if(ret != sizeof(Wrbuf))
258 {
259 TPD_DEBUG("[mtk-tpd] i2c write communcate error: 0x%x\n", ret);
260 continue;
261 }
262 i2c_client->addr = ( ( i2c_client->addr & I2C_MASK_FLAG ) | I2C_DMA_FLAG ) | I2C_ENEXT_FLAG;
263 ret = tpd_i2c_read(i2c_client, buffer, 7);
264 buffer[7] = buffer[8] = buffer[9] = 0;
265 if (ret != 7)//sizeof(buffer)
266 {
267 TPD_DEBUG("[mtk-tpd] i2c read communcate error: 0x%x\n", ret);
268 continue;
269 }
270 i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG;
271
272 touching = buffer[0];
273 if(touching > 0)
274 {
275 raw_x1 = x1 = ((buffer[3] << 8) | buffer[2]);
276 raw_y1 = y1 = ((buffer[5] << 8) | buffer[4]);
277 }
278 if(touching > 1)
279 {
280 raw_x2 = x2 = ((buffer[7] << 8) | buffer[6]);
281 raw_y2 = y2 = ((buffer[9] << 8) | buffer[8]);
282 }
283 oldtouching = buffer[1];
284 TPD_DEBUG("[mtk-tpd]:raw_x1:%d, raw_y1:%d, raw_x2:%d, raw_y2:%d\n", raw_x1, raw_y1, raw_x2, raw_y2);
285 TPD_DEBUG("[mtk-tpd]:touch:%d, old_touch:%d\n", touching, oldtouching);
286 switch(touching)
287 {
288 case 0:
289 /* touching=0, oldtouching 0 is invalid */
290 if(oldtouching > 0)
291 {
292 //tpd_up(raw_y1, raw_x1, y1, x1, 0);
293 //tpd_up(raw_x1, raw_y1, x1, y1, 0);
294 lastUp_x = x1;
295 lastUp_y = y1;
296 }
297 if(oldtouching > 1)
298 {
299 //tpd_up(raw_y2, raw_x2, y2, x2, 0);
300 //tpd_up(raw_x2, raw_y2, x2, y2, 0);
301 //lastUp_x = x1;
302 //lastUp_y = y1;
303 }
304 tpd_up(lastUp_x, lastUp_y, lastUp_x, lastUp_y, 0);
305 break;
306 case 1:
307 tpd_calibrate(&x1, &y1);
308 //tpd_down(raw_y1, raw_x1, y1, x1, 1);
309 tpd_down(raw_x1, raw_y1, x1, y1, 1);
310 if(oldtouching == 2)
311 {
312 if(abs(x1 - x2) < 2 && abs(y1 - y2) < 2) // need to adjust.
313 {
314 //tpd_up(temp_raw_y1, temp_raw_x1, temp_y1, temp_x1, 0);
315
316 //For ICS
317 //tpd_up(temp_raw_x1, temp_raw_y1, temp_x1, temp_y1, 0);
318 }
319 else
320 {
321 //tpd_up(raw_y2, raw_x2, y2, x2, 0);
322
323 //For ICS
324 //tpd_up(raw_x2, raw_y2, x2, y2, 0);
325 }
326 }
327 break;
328 case 2:
329 tpd_calibrate(&x1, &y1);
330 //tpd_down(raw_y1, raw_x1, y1, x1, 1);
331 tpd_down(raw_x1, raw_y1, x1, y1, 1);
332 //tpd_calibrate(&x2, &y2);
333 //tpd_down(raw_y2, raw_x2, y2, x2, 1);
334 //tpd_down(raw_x2, raw_y2, x2, y2, 1);
335 break;
336 default:
337 TPD_DEBUG("[mtk-tpd] invalid touch num: 0x%x\n", touching);
338 continue;
339 }
340 temp_x1 = x1;
341 temp_y1 = y1;
342 temp_raw_x1 = raw_x1;
343 temp_raw_y1 = raw_y1;
344 input_sync(tpd->dev);
345
346 } while (!kthread_should_stop());
347 return 0;
348}
349
350int tpd_local_init(void)
351{
352 if(i2c_add_driver(&tpd_i2c_driver)!=0)
353 {
354 TPD_DMESG("unable to add i2c driver.\n");
355 return -1;
356 }
357
358#ifdef TPD_HAVE_BUTTON
359 tpd_button_setting(TPD_KEY_COUNT, tpd_keys_local, tpd_keys_dim_local);// initialize tpd button data
360#endif
361
362#if (defined(TPD_WARP_START) && defined(TPD_WARP_END))
363 TPD_DO_WARP = 1;
364 memcpy(tpd_wb_start, tpd_wb_start_local, TPD_WARP_CNT*4);
365 memcpy(tpd_wb_end, tpd_wb_start_local, TPD_WARP_CNT*4);
366#endif
367
368#if (defined(TPD_HAVE_CALIBRATION) && !defined(TPD_CUSTOM_CALIBRATION))
369 memcpy(tpd_calmat, tpd_def_calmat_local, 8*4);
370 memcpy(tpd_def_calmat, tpd_def_calmat_local, 8*4);
371#endif
372 TPD_DMESG("end %s, %d\n", __FUNCTION__, __LINE__);
373 tpd_type_cap = 1;
374 return 0;
375}
376
377/* Function to manage low power suspend */
378//void tpd_suspend(struct i2c_client *client, pm_message_t message)
379static void tpd_suspend( struct early_suspend *h )
380{
381 int ret = 0;
382 unsigned char Wrbuf[2] = {0x14, 0x02};
383 tpd_halt = 1;
384 mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);
385
386 i2c_client->addr = ( i2c_client->addr & I2C_MASK_FLAG ) | I2C_ENEXT_FLAG;
387 ret = i2c_master_send(i2c_client, Wrbuf, 2);
388 if(ret != sizeof(Wrbuf))
389 {
390 TPD_DEBUG("[mtk-tpd] i2c write communcate error during suspend: 0x%x\n", ret);
391 }
392}
393
394/* Function to manage power-on resume */
395//void tpd_resume(struct i2c_client *client)
396static void tpd_resume( struct early_suspend *h )
397{
398 int ret = 0;
399 unsigned char Wrbuf[2] = {0x14, 0x00};
400
401 i2c_client->addr = ( i2c_client->addr & I2C_MASK_FLAG ) | I2C_ENEXT_FLAG;
402 ret = i2c_master_send(i2c_client, Wrbuf, 2);
403 if(ret != sizeof(Wrbuf))
404 {
405 TPD_DEBUG("[mtk-tpd] i2c write communcate error during resume: 0x%x\n", ret);
406 }
407 mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
408 tpd_halt = 0;
409}
410
411static struct tpd_driver_t tpd_device_driver = {
412 .tpd_device_name = "pixcir168",
413 .tpd_local_init = tpd_local_init,
414 .suspend = tpd_suspend,
415 .resume = tpd_resume,
416#ifdef TPD_HAVE_BUTTON
417 .tpd_have_button = 1,
418#else
419 .tpd_have_button = 0,
420#endif
421};
422/* called when loaded into kernel */
423static int __init tpd_driver_init(void)
424{
425 printk("MediaTek pixcir168 touch panel driver init\n");
426 i2c_register_board_info(0, &i2c_tpd, 1);
427 if(tpd_driver_add(&tpd_device_driver) < 0)
428 TPD_DMESG("add generic driver failed\n");
429
430 return 0;
431}
432
433/* should never be called */
434static void __exit tpd_driver_exit(void) {
435 TPD_DMESG("MediaTek pixcir168 touch panel driver exit\n");
436 //input_unregister_device(tpd->dev);
437 tpd_driver_remove(&tpd_device_driver);
438}
439
440module_init(tpd_driver_init);
441module_exit(tpd_driver_exit);
442