Commit | Line | Data |
---|---|---|
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 <mach/eint.h> | |
21 | #include <linux/proc_fs.h> | |
22 | #include <asm/uaccess.h> | |
23 | #include <cust_eint.h> | |
24 | #include <linux/jiffies.h> | |
25 | ||
26 | #include "tpd.h" | |
27 | #include "gn_mms144.h" | |
28 | #include "gn_mms144_bin_isc.h" | |
29 | ||
30 | #define TP_DEV_NAME "mms144" | |
31 | #define I2C_RETRY_CNT 5 //Fixed value | |
32 | #define DOWNLOAD_RETRY_CNT 5 //Fixed value | |
33 | #define MELFAS_DOWNLOAD 1 //Fixed value | |
34 | ||
35 | #define PRESS_KEY 1 //Fixed value | |
36 | #define RELEASE_KEY 0 //Fixed value | |
37 | ||
38 | #define TS_READ_LEN_ADDR 0x0F //Fixed value | |
39 | #define TS_READ_START_ADDR 0x10 //Fixed value | |
40 | #define TS_READ_REGS_LEN 66 //Fixed value | |
41 | #define TS_WRITE_REGS_LEN 16 //Fixed value | |
42 | ||
43 | #define TS_MAX_TOUCH 10 //Model Dependent | |
44 | #define TS_READ_HW_VER_ADDR 0xF1 //Model Dependent | |
45 | #define TS_READ_SW_VER_ADDR 0xF5 //Model Dependent | |
46 | ||
47 | #define MELFAS_HW_REVISON 0x01 //Model Dependent | |
48 | #define MELFAS_FW_VERSION 0x02 //Model Dependent | |
49 | ||
50 | #define MELFAS_MAX_TRANSACTION_LENGTH 66 | |
51 | #define MELFAS_MAX_I2C_TRANSFER_SIZE 7 | |
52 | #define MELFAS_I2C_DEVICE_ADDRESS_LEN 1 | |
53 | //#define I2C_MASTER_CLOCK 400 | |
54 | #define MELFAS_I2C_MASTER_CLOCK 100 | |
55 | #define MELFAS_I2C_ADDRESS 0x48 | |
56 | ||
57 | #define REPORT_MT_DOWN(touch_number, x, y, width, strength) \ | |
58 | do { \ | |
59 | input_report_abs(tpd->dev, ABS_PRESSURE, strength); \ | |
60 | input_report_key(tpd->dev, BTN_TOUCH, 1); \ | |
61 | input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, touch_number);\ | |
62 | input_report_abs(tpd->dev, ABS_MT_POSITION_X, x); \ | |
63 | input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y); \ | |
64 | input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, width); \ | |
65 | input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, strength); \ | |
66 | input_mt_sync(tpd->dev); \ | |
67 | } while (0) | |
68 | ||
69 | #define REPORT_MT_UP() \ | |
70 | do { \ | |
71 | input_report_key(tpd->dev, BTN_TOUCH, 0); \ | |
72 | input_mt_sync(tpd->dev); \ | |
73 | } while (0) | |
74 | ||
75 | ||
76 | static int melfas_tpd_flag = 0; | |
77 | ||
78 | static struct muti_touch_info g_Mtouch_info[TS_MAX_TOUCH]; | |
79 | //static int tsp_keycodes[4] = {KEY_MENU, KEY_HOME, KEY_SEARCH, KEY_BACK}; | |
80 | ||
81 | #ifdef TPD_HAVE_BUTTON | |
82 | #define TPD_KEY_COUNT 4 | |
83 | #define TPD_KEYS { KEY_HOME,KEY_MENU,KEY_BACK, KEY_SEARCH} | |
84 | #define TPD_KEYS_DIM {{60,850,120,100},{180,850,120,100},{300,850,120,100},{420,850,120,100}} | |
85 | static int tpd_keys_local[TPD_KEY_COUNT] = TPD_KEYS; | |
86 | static int tpd_keys_dim_local[TPD_KEY_COUNT][4] = TPD_KEYS_DIM; | |
87 | #endif | |
88 | ||
89 | ||
90 | static DECLARE_WAIT_QUEUE_HEAD(melfas_waiter); | |
91 | ||
92 | static struct i2c_client *melfas_i2c_client = NULL; | |
93 | ||
94 | static const struct i2c_device_id melfas_tpd_id[] = {{TP_DEV_NAME,0},{}}; | |
95 | static struct i2c_board_info __initdata melfas_i2c_tpd={ I2C_BOARD_INFO(TP_DEV_NAME, MELFAS_I2C_ADDRESS)}; | |
96 | ||
97 | static int melfas_tpd_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id); | |
98 | static int melfas_tpd_i2c_remove(struct i2c_client *client); | |
99 | static int melfas_tpd_i2c_detect(struct i2c_client *client, struct i2c_board_info *info); | |
100 | extern int isc_fw_download(struct i2c_client *client, const u8 *data, size_t len); | |
101 | static int melfas_i2c_read(struct i2c_client *client, u16 addr, u16 len, u8 *rxbuf); | |
102 | ||
103 | static void melfas_ts_release_all_finger(void); | |
104 | ||
105 | ||
106 | extern struct tpd_device *tpd; | |
107 | ||
108 | ||
109 | ||
110 | static struct i2c_driver melfas_tpd_i2c_driver = | |
111 | { | |
112 | .probe = melfas_tpd_i2c_probe, | |
113 | .remove = __devexit_p(melfas_tpd_i2c_remove), | |
114 | .detect = melfas_tpd_i2c_detect, | |
115 | .driver.name = "mtk-tpd", | |
116 | .id_table = melfas_tpd_id, | |
117 | #ifndef CONFIG_HAS_EARLYSUSPEND | |
118 | .suspend = melfas_ts_suspend, | |
119 | .resume = melfas_ts_resume, | |
120 | #endif | |
121 | ||
122 | }; | |
123 | ||
124 | #define VAR_CHAR_NUM_MAX 20 | |
125 | ||
126 | #if defined (GN_MTK_BSP) | |
127 | static ssize_t show_update_pro(struct kobject *kobj, struct kobj_attribute *attr, char *buf) | |
128 | { | |
129 | #if defined(TPD_UPDATE_FW) | |
130 | char ver[20]; | |
131 | TPD_DMESG(" show_update_fw_pro\n"); | |
132 | ||
133 | melfas_update_show_reg(ver); | |
134 | snprintf(buf, VAR_CHAR_NUM_MAX, "%s", ver); | |
135 | #endif | |
136 | return 0; | |
137 | ||
138 | } | |
139 | static ssize_t store_update_pro(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) | |
140 | { | |
141 | //char strbuf[10]="OK\n"; | |
142 | ||
143 | TPD_DMESG(" store_update_fw_pro\n"); | |
144 | TPD_DMESG(" store_update_fw_pro--%s----\n",buf); | |
145 | if(!strcmp(buf , "update")) | |
146 | { | |
147 | #if defined(TPD_UPDATE_FW) | |
148 | melfas_tpd_update_fw(); | |
149 | #endif | |
150 | } | |
151 | // snprintf(buf, VAR_CHAR_NUM_MAX, "%s", strbuf); | |
152 | return 0; | |
153 | ||
154 | } | |
155 | ||
156 | static struct kobj_attribute update_firmware_attribute = { | |
157 | .attr = {.name = "update", .mode = 0664}, | |
158 | .show = show_update_pro, | |
159 | .store = store_update_pro, | |
160 | }; | |
161 | static int tpd_create_attr(void) | |
162 | { | |
163 | int ret; | |
164 | struct kobject *kobject_ts; | |
165 | kobject_ts = kobject_create_and_add("touch_screen", NULL); | |
166 | if (!kobject_ts) | |
167 | { | |
168 | printk("create kobjetct error!\n"); | |
169 | return -1; | |
170 | } | |
171 | ||
172 | ret = sysfs_create_file(kobject_ts, &update_firmware_attribute.attr); | |
173 | if (ret) { | |
174 | kobject_put(kobject_ts); | |
175 | printk("create file error\n"); | |
176 | return -1; | |
177 | } | |
178 | return 0; | |
179 | ||
180 | } | |
181 | #endif | |
182 | ||
183 | ||
184 | ||
185 | ||
186 | static void esd_rest_tp(void) | |
187 | { | |
188 | printk("==========tp have inter esd =============\n"); | |
189 | mt_set_gpio_mode(GPIO_CTP_EN_PIN, GPIO_CTP_EN_PIN_M_GPIO); | |
190 | mt_set_gpio_dir(GPIO_CTP_EN_PIN, GPIO_DIR_OUT); | |
191 | mt_set_gpio_out(GPIO_CTP_EN_PIN, GPIO_OUT_ZERO); | |
192 | msleep(100); | |
193 | mt_set_gpio_mode(GPIO_CTP_EN_PIN, GPIO_CTP_EN_PIN_M_GPIO); | |
194 | mt_set_gpio_dir(GPIO_CTP_EN_PIN, GPIO_DIR_OUT); | |
195 | mt_set_gpio_out(GPIO_CTP_EN_PIN, GPIO_OUT_ONE); | |
196 | ||
197 | } | |
198 | ||
199 | static int melfas_touch_event_handler(void *unused) | |
200 | { | |
201 | uint8_t buf[TS_READ_REGS_LEN] = { 0 }; | |
202 | int i, read_num, fingerID, Touch_Type = 0, touchState = 0;//, keyID = 0; | |
203 | //uint8_t buf_esd[2]={0}; | |
204 | ||
205 | struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; | |
206 | ||
207 | ||
208 | sched_setscheduler(current, SCHED_RR, ¶m); | |
209 | ||
210 | do | |
211 | { | |
212 | set_current_state(TASK_INTERRUPTIBLE); | |
213 | ||
214 | wait_event_interruptible(melfas_waiter, melfas_tpd_flag != 0); | |
215 | ||
216 | melfas_tpd_flag = 0; | |
217 | set_current_state(TASK_RUNNING); | |
218 | ||
219 | melfas_i2c_read(melfas_i2c_client, TS_READ_LEN_ADDR, 1, buf); | |
220 | read_num = buf[0]; | |
221 | if(read_num) | |
222 | { | |
223 | melfas_i2c_read(melfas_i2c_client, TS_READ_START_ADDR, read_num, buf); | |
224 | //printk("esd 0x10 register = %2X\n",buf[0]); | |
225 | if(0x0F == buf[0]) | |
226 | { | |
227 | esd_rest_tp(); | |
228 | continue; | |
229 | } | |
230 | ||
231 | for (i = 0; i < read_num; i = i + 6) | |
232 | { | |
233 | Touch_Type = (buf[i] >> 5) & 0x03; | |
234 | ||
235 | /* touch type is panel */ | |
236 | if (Touch_Type == TOUCH_SCREEN) | |
237 | { | |
238 | fingerID = (buf[i] & 0x0F) - 1; | |
239 | touchState = (buf[i] & 0x80); | |
240 | ||
241 | g_Mtouch_info[fingerID].posX = (uint16_t)(buf[i + 1] & 0x0F) << 8 | buf[i + 2]; | |
242 | g_Mtouch_info[fingerID].posY = (uint16_t)(buf[i + 1] & 0xF0) << 4 | buf[i + 3]; | |
243 | g_Mtouch_info[fingerID].area = buf[i + 4]; | |
244 | ||
245 | if (touchState) | |
246 | g_Mtouch_info[fingerID].pressure = buf[i + 5]; | |
247 | else | |
248 | g_Mtouch_info[fingerID].pressure = 0; | |
249 | } | |
250 | } | |
251 | for (i = 0; i < TS_MAX_TOUCH; i++) | |
252 | { | |
253 | if (g_Mtouch_info[i].pressure == -1) | |
254 | continue; | |
255 | ||
256 | ||
257 | if(g_Mtouch_info[i].pressure == 0) | |
258 | { | |
259 | // release event | |
260 | REPORT_MT_UP(); | |
261 | } | |
262 | else | |
263 | { | |
264 | REPORT_MT_DOWN(i, g_Mtouch_info[i].posX, g_Mtouch_info[i].posY, g_Mtouch_info[i].area, g_Mtouch_info[i].pressure); | |
265 | } | |
266 | TPD_DEBUG("[TSP] %s: Touch ID: %d, State : %d, x: %d, y: %d, z: %d w: %d\n", __FUNCTION__, | |
267 | i, (g_Mtouch_info[i].pressure > 0), g_Mtouch_info[i].posX, g_Mtouch_info[i].posY, g_Mtouch_info[i].pressure, g_Mtouch_info[i].area); | |
268 | ||
269 | ||
270 | if (g_Mtouch_info[i].pressure == 0) | |
271 | g_Mtouch_info[i].pressure = -1; | |
272 | } | |
273 | ||
274 | if ( tpd != NULL && tpd->dev != NULL ) | |
275 | input_sync(tpd->dev); | |
276 | ||
277 | } | |
278 | //else | |
279 | //{ | |
280 | // REPORT_MT_UP(); | |
281 | //} | |
282 | ||
283 | } while ( !kthread_should_stop() ); | |
284 | ||
285 | return 0; | |
286 | } | |
287 | ||
288 | static void melfas_i2c_tpd_eint_interrupt_handler(void) | |
289 | { | |
290 | TPD_DEBUG_PRINT_INT; | |
291 | melfas_tpd_flag=1; | |
292 | wake_up_interruptible(&melfas_waiter); | |
293 | } | |
294 | ||
295 | int melfas_i2c_write_bytes( struct i2c_client *client, u16 addr, int len, u8 *txbuf ) | |
296 | { | |
297 | u8 buffer[MELFAS_MAX_TRANSACTION_LENGTH]={0}; | |
298 | u16 left = len; | |
299 | u8 offset = 0; | |
300 | u8 retry = 0; | |
301 | ||
302 | struct i2c_msg msg = | |
303 | { | |
304 | .addr = ((client->addr&I2C_MASK_FLAG )|(I2C_ENEXT_FLAG )), | |
305 | .flags = 0, | |
306 | .buf = buffer, | |
307 | .timing = MELFAS_I2C_MASTER_CLOCK, | |
308 | }; | |
309 | ||
310 | ||
311 | if ( txbuf == NULL ) | |
312 | return -1; | |
313 | ||
314 | TPD_DEBUG("i2c_write_bytes to device %02X address %04X len %d\n", client->addr, addr, len ); | |
315 | ||
316 | while ( left > 0 ) | |
317 | { | |
318 | retry = 0; | |
319 | ||
320 | buffer[0] = (u8)addr+offset; | |
321 | ||
322 | if ( left > MELFAS_MAX_I2C_TRANSFER_SIZE ) | |
323 | { | |
324 | memcpy( &buffer[MELFAS_I2C_DEVICE_ADDRESS_LEN], &txbuf[offset], MELFAS_MAX_I2C_TRANSFER_SIZE ); | |
325 | msg.len = MELFAS_MAX_TRANSACTION_LENGTH; | |
326 | left -= MELFAS_MAX_I2C_TRANSFER_SIZE; | |
327 | offset += MELFAS_MAX_I2C_TRANSFER_SIZE; | |
328 | } | |
329 | else | |
330 | { | |
331 | memcpy( &buffer[MELFAS_I2C_DEVICE_ADDRESS_LEN], &txbuf[offset], left ); | |
332 | msg.len = left + MELFAS_I2C_DEVICE_ADDRESS_LEN; | |
333 | left = 0; | |
334 | } | |
335 | ||
336 | TPD_DEBUG("byte left %d offset %d\n", left, offset ); | |
337 | ||
338 | while ( i2c_transfer( client->adapter, &msg, 1 ) != 1 ) | |
339 | { | |
340 | retry++; | |
341 | ||
342 | if ( retry == I2C_RETRY_CNT ) | |
343 | { | |
344 | TPD_DEBUG("I2C write 0x%X%X length=%d failed\n", buffer[0], buffer[1], len); | |
345 | TPD_DMESG("I2C write 0x%X%X length=%d failed\n", buffer[0], buffer[1], len); | |
346 | return -1; | |
347 | } | |
348 | else | |
349 | TPD_DEBUG("I2C write retry %d addr 0x%X%X\n", retry, buffer[0], buffer[1]); | |
350 | ||
351 | } | |
352 | } | |
353 | ||
354 | return 0; | |
355 | } | |
356 | ||
357 | static int melfas_i2c_read(struct i2c_client *client, u16 addr, u16 len, u8 *rxbuf) | |
358 | { | |
359 | u8 buffer[MELFAS_I2C_DEVICE_ADDRESS_LEN]={0}; | |
360 | u8 retry; | |
361 | u16 left = len; | |
362 | u8 offset = 0; | |
363 | ||
364 | struct i2c_msg msg[2] = | |
365 | { | |
366 | { | |
367 | .addr = ((client->addr&I2C_MASK_FLAG )|(I2C_ENEXT_FLAG )), | |
368 | .flags = 0, | |
369 | .buf = buffer, | |
370 | .len = MELFAS_I2C_DEVICE_ADDRESS_LEN, | |
371 | .timing = MELFAS_I2C_MASTER_CLOCK | |
372 | }, | |
373 | { | |
374 | .addr = ((client->addr&I2C_MASK_FLAG )|(I2C_ENEXT_FLAG )), | |
375 | .flags = I2C_M_RD, | |
376 | .timing = MELFAS_I2C_MASTER_CLOCK | |
377 | }, | |
378 | }; | |
379 | ||
380 | if ( rxbuf == NULL ) | |
381 | return -1; | |
382 | ||
383 | TPD_DEBUG("i2c_read_bytes to device %02X address %04X len %d\n", client->addr, addr, len ); | |
384 | ||
385 | while ( left > 0 ) | |
386 | { | |
387 | buffer[0] = (u8)addr+offset; | |
388 | ||
389 | msg[1].buf = &rxbuf[offset]; | |
390 | ||
391 | if ( left > MELFAS_MAX_TRANSACTION_LENGTH ) | |
392 | { | |
393 | msg[1].len = MELFAS_MAX_TRANSACTION_LENGTH; | |
394 | left -= MELFAS_MAX_TRANSACTION_LENGTH; | |
395 | offset += MELFAS_MAX_TRANSACTION_LENGTH; | |
396 | } | |
397 | else | |
398 | { | |
399 | msg[1].len = left; | |
400 | left = 0; | |
401 | } | |
402 | ||
403 | retry = 0; | |
404 | ||
405 | while ( i2c_transfer( client->adapter, &msg[0], 2 ) != 2 ) | |
406 | { | |
407 | retry++; | |
408 | ||
409 | if ( retry == I2C_RETRY_CNT ) | |
410 | { | |
411 | TPD_DEBUG("I2C read 0x%X length=%d failed\n", addr + offset, len); | |
412 | TPD_DMESG("I2C read 0x%X length=%d failed\n", addr + offset, len); | |
413 | return -1; | |
414 | } | |
415 | } | |
416 | } | |
417 | ||
418 | return 0; | |
419 | } | |
420 | ||
421 | static int melfas_check_firmware(struct i2c_client *client, u8 *val) | |
422 | { | |
423 | int ret = 0; | |
424 | //uint8_t i = 0; | |
425 | ||
426 | ||
427 | ret = melfas_i2c_read(client, TS_READ_HW_VER_ADDR, 1, &val[0]); | |
428 | ret = melfas_i2c_read(client, TS_READ_SW_VER_ADDR, 1, &val[1]); | |
429 | ||
430 | if (ret >= 0) | |
431 | { | |
432 | TPD_DMESG("[melfas_tpd]: HW Revision[0x%02x] SW Version[0x%02x] \n", val[0], val[1]); | |
433 | } | |
434 | ||
435 | if (ret < 0) | |
436 | { | |
437 | TPD_DMESG("[melfas_tpd] %s,%d: i2c read fail[%d] \n", __FUNCTION__, __LINE__, ret); | |
438 | } | |
439 | ||
440 | return ret; | |
441 | } | |
442 | ||
443 | static int melfas_firmware_update(struct i2c_client *client) | |
444 | { | |
445 | int ret = 0; | |
446 | uint8_t fw_ver[2] = {0, }; | |
447 | ||
448 | ret = melfas_check_firmware(client, fw_ver); | |
449 | if (ret < 0) | |
450 | TPD_DMESG("[melfas_tpd] check_firmware fail! [%d]", ret); | |
451 | else | |
452 | { | |
453 | #if 0//MELFAS_DOWNLOAD | |
454 | if (fw_ver[1] < MELFAS_FW_VERSION) | |
455 | { | |
456 | int ver; | |
457 | ||
458 | TPD_DMESG("[melfas_tpd] %s: \n", __func__); | |
459 | ret = isc_fw_download(client, MELFAS_binary, MELFAS_binary_nLength); | |
460 | if (ret < 0) | |
461 | { | |
462 | //ret = isp_fw_download(MELFAS_MMS100_Initial_binary, MELFAS_MMS100_Initial_nLength); | |
463 | if (ret != 0) | |
464 | { | |
465 | TPD_DMESG("[melfas_tpd] error updating firmware to version 0x%02x \n", MELFAS_FW_VERSION); | |
466 | ret = -1; | |
467 | } | |
468 | else | |
469 | { | |
470 | ret = isc_fw_download(client, MELFAS_binary, MELFAS_binary_nLength); | |
471 | } | |
472 | } | |
473 | } | |
474 | #endif | |
475 | } | |
476 | ||
477 | return ret; | |
478 | } | |
479 | static int melfas_tpd_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) | |
480 | { | |
481 | int err = 0; | |
482 | struct task_struct *thread = NULL; | |
483 | ||
484 | TPD_DMESG("[melfas_tpd] %s\n", __func__); | |
485 | ||
486 | //power on | |
487 | mt_set_gpio_mode(GPIO_CTP_EN_PIN, GPIO_CTP_EN_PIN_M_GPIO); | |
488 | mt_set_gpio_dir(GPIO_CTP_EN_PIN, GPIO_DIR_OUT); | |
489 | mt_set_gpio_out(GPIO_CTP_EN_PIN, GPIO_OUT_ONE); | |
490 | ||
491 | msleep(200); | |
492 | ||
493 | melfas_i2c_client = client; | |
494 | ||
495 | melfas_firmware_update(client); | |
496 | ||
497 | #if defined (GN_MTK_BSP) | |
498 | err = tpd_create_attr(); | |
499 | if(err) | |
500 | { | |
501 | TPD_DMESG(" tpd create attribute err = %d\n", err); | |
502 | } | |
503 | #endif | |
504 | ||
505 | thread = kthread_run(melfas_touch_event_handler, 0, TPD_DEVICE); | |
506 | ||
507 | if (IS_ERR(thread)) | |
508 | { | |
509 | err = PTR_ERR(thread); | |
510 | TPD_DMESG(TPD_DEVICE "[melfas_tpd] failed to create kernel thread: %d\n", err); | |
511 | } | |
512 | ||
513 | // set INT mode | |
514 | mt_set_gpio_mode(GPIO_CTP_EINT_PIN, GPIO_CTP_EINT_PIN_M_EINT); | |
515 | mt_set_gpio_dir(GPIO_CTP_EINT_PIN, GPIO_DIR_IN); | |
516 | mt_set_gpio_pull_enable(GPIO_CTP_EINT_PIN, GPIO_PULL_ENABLE); | |
517 | mt_set_gpio_pull_select(GPIO_CTP_EINT_PIN, GPIO_PULL_UP); | |
518 | ||
519 | msleep(50); | |
520 | ||
521 | //mt65xx_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_SENSITIVE); | |
522 | //mt65xx_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN); | |
523 | mt_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_TYPE, tpd_eint_interrupt_handler, 1); | |
524 | mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); | |
525 | tpd_load_status = 1; | |
526 | ||
527 | return 0; | |
528 | ||
529 | } | |
530 | static int melfas_tpd_i2c_remove(struct i2c_client *client) | |
531 | { | |
532 | return 0; | |
533 | } | |
534 | static int melfas_tpd_i2c_detect(struct i2c_client *client, struct i2c_board_info *info) | |
535 | { | |
536 | TPD_DMESG("[melfas_tpd] %s\n", __func__); | |
537 | strcpy(info->type, "mtk-tpd"); | |
538 | return 0; | |
539 | } | |
540 | static int melfas_tpd_local_init(void) | |
541 | { | |
542 | ||
543 | TPD_DMESG("[melfas_tpd] end %s, %d\n", __FUNCTION__, __LINE__); | |
544 | if(i2c_add_driver(&melfas_tpd_i2c_driver)!=0) | |
545 | { | |
546 | TPD_DMESG("[melfas_tpd] unable to add i2c driver.\n"); | |
547 | return -1; | |
548 | } | |
549 | if(tpd_load_status == 0) | |
550 | { | |
551 | TPD_DMESG("[melfas_tpd] add error touch panel driver.\n"); | |
552 | i2c_del_driver(&melfas_tpd_i2c_driver); | |
553 | return -1; | |
554 | } | |
555 | #ifdef TPD_HAVE_BUTTON | |
556 | tpd_button_setting(TPD_KEY_COUNT, tpd_keys_local, tpd_keys_dim_local); | |
557 | #endif | |
558 | ||
559 | ||
560 | tpd_type_cap = 1; | |
561 | ||
562 | return 0; | |
563 | } | |
564 | ||
565 | ||
566 | #ifdef SLOT_TYPE | |
567 | static void melfas_ts_release_all_finger(void) | |
568 | { | |
569 | int i; | |
570 | TPD_DMESG("[melfas_tpd] %s\n", __func__); | |
571 | for (i = 0; i < TS_MAX_TOUCH; i++) | |
572 | { | |
573 | input_mt_slot(tpd->dev, i); | |
574 | input_mt_report_slot_state(tpd->dev, MT_TOOL_FINGER, false); | |
575 | } | |
576 | input_sync(tpd->dev); | |
577 | } | |
578 | #else | |
579 | static void melfas_ts_release_all_finger(void) | |
580 | { | |
581 | int i; | |
582 | TPD_DMESG("[melfas_tpd] %s\n", __func__); | |
583 | ||
584 | for(i=0; i<TS_MAX_TOUCH; i++) | |
585 | { | |
586 | if(-1 == g_Mtouch_info[i].pressure) | |
587 | continue; | |
588 | ||
589 | if(g_Mtouch_info[i].pressure == 0) | |
590 | input_mt_sync(tpd->dev); | |
591 | ||
592 | if(0 == g_Mtouch_info[i].pressure) | |
593 | g_Mtouch_info[i].pressure = -1; | |
594 | } | |
595 | input_sync(tpd->dev); | |
596 | } | |
597 | #endif | |
598 | ||
599 | ||
600 | #ifdef CONFIG_HAS_EARLYSUSPEND | |
601 | static void melfas_tpd_early_suspend(struct early_suspend *h) | |
602 | { | |
603 | TPD_DMESG("[melfas_tpd] %s\n", __func__); | |
604 | ||
605 | melfas_ts_release_all_finger(); | |
606 | ||
607 | //irq mask | |
608 | mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); | |
609 | //power down | |
610 | mt_set_gpio_mode(GPIO_CTP_EN_PIN, GPIO_CTP_EN_PIN_M_GPIO); | |
611 | mt_set_gpio_dir(GPIO_CTP_EN_PIN, GPIO_DIR_OUT); | |
612 | mt_set_gpio_out(GPIO_CTP_EN_PIN, GPIO_OUT_ZERO); | |
613 | } | |
614 | ||
615 | static void melfas_tpd_late_resume(struct early_suspend *h) | |
616 | { | |
617 | //int ret; | |
618 | //struct melfas_ts_data *ts = i2c_get_clientdata(client); | |
619 | ||
620 | TPD_DMESG("[melfas_tpd] %s\n", __func__); | |
621 | ||
622 | //power on | |
623 | mt_set_gpio_mode(GPIO_CTP_EN_PIN, GPIO_CTP_EN_PIN_M_GPIO); | |
624 | mt_set_gpio_dir(GPIO_CTP_EN_PIN, GPIO_DIR_OUT); | |
625 | mt_set_gpio_out(GPIO_CTP_EN_PIN, GPIO_OUT_ONE); | |
626 | msleep(200); | |
627 | //irq unmask | |
628 | mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); | |
629 | } | |
630 | #endif | |
631 | ||
632 | static struct tpd_driver_t melfas_tpd_device_driver = | |
633 | { | |
634 | .tpd_device_name = "melfas_mms144", | |
635 | .tpd_local_init = melfas_tpd_local_init, | |
636 | #ifdef CONFIG_HAS_EARLYSUSPEND | |
637 | .suspend = melfas_tpd_early_suspend, | |
638 | .resume = melfas_tpd_late_resume, | |
639 | #endif | |
640 | #ifdef TPD_HAVE_BUTTON | |
641 | .tpd_have_button = 1, | |
642 | #else | |
643 | .tpd_have_button = 0, | |
644 | #endif | |
645 | ||
646 | ||
647 | }; | |
648 | ||
649 | /* called when loaded into kernel */ | |
650 | static int __init melfas_tpd_driver_init(void) | |
651 | { | |
652 | TPD_DMESG("[melfas_tpd] %s\n", __func__); | |
653 | i2c_register_board_info(0, &melfas_i2c_tpd, 1); | |
654 | if ( tpd_driver_add(&melfas_tpd_device_driver) < 0) | |
655 | TPD_DMESG("[melfas_tpd] add generic driver failed\n"); | |
656 | ||
657 | return 0; | |
658 | } | |
659 | ||
660 | /* should never be called */ | |
661 | static void __exit melfas_tpd_driver_exit(void) | |
662 | { | |
663 | TPD_DMESG("[melfas_tpd] %s\n", __func__); | |
664 | tpd_driver_remove(&melfas_tpd_device_driver); | |
665 | } | |
666 | ||
667 | ||
668 | module_init(melfas_tpd_driver_init); | |
669 | module_exit(melfas_tpd_driver_exit); | |
670 |