diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/input/touchscreen/semisens/touch.c')
-rwxr-xr-x | ANDROID_3.4.5/drivers/input/touchscreen/semisens/touch.c | 1121 |
1 files changed, 0 insertions, 1121 deletions
diff --git a/ANDROID_3.4.5/drivers/input/touchscreen/semisens/touch.c b/ANDROID_3.4.5/drivers/input/touchscreen/semisens/touch.c deleted file mode 100755 index 39d6ce15..00000000 --- a/ANDROID_3.4.5/drivers/input/touchscreen/semisens/touch.c +++ /dev/null @@ -1,1121 +0,0 @@ -/**************************************************************** - * - * touch.c : I2C Touchscreen driver - * - * Copyright (c) 2013 SEMISENS Co.,Ltd - * http://www.semisens.com - * - ****************************************************************/ -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/device.h> -#include <linux/init.h> -#include <linux/input.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/slab.h> -#include <linux/hrtimer.h> -#include <asm/unaligned.h> -#include <linux/firmware.h> -#include <linux/delay.h> -#include <linux/gpio.h> -#include <linux/i2c.h> - -//---------------------------------------------- -#if defined(CONFIG_HAS_EARLYSUSPEND) - #include <linux/wakelock.h> - #include <linux/earlysuspend.h> - #include <linux/suspend.h> -#endif - -//---------------------------------------------- -#include <linux/input/mt.h> -#include "sn310m-touch-pdata.h" -#include "sn310m-touch.h" - -//---------------------------------------------- -#include "touch.h" -#include <linux/gpio.h> -#include <mach/wmt_iomux.h> - - -extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); -extern int wmt_setsyspara(char *varname, unsigned char *varval); - -#define SN310M_NATIVE_INTERFACE /* This is to debug semisens TSC */ - -#if defined(SN310M_NATIVE_INTERFACE) -#include <linux/miscdevice.h> -#include <linux/syscalls.h> -struct touch* g_ts; -int g_MiscInitialize = 0; -static int P_SN310M_Dist_Probe(struct touch* ts); -static int P_SN310M_Dist_Open(struct inode *inode, struct file *file); -static long P_SN310M_Dist_Ioctl(struct file *file, unsigned int cmd, unsigned long arg); -static void P_SN310M_Dist_Remove(void); -#endif - -// function prototype define -//---------------------------------------------- -#ifdef CONFIG_HAS_EARLYSUSPEND - static void touch_suspend(struct early_suspend *h); - static void touch_resume(struct early_suspend *h); -#endif - -irqreturn_t touch_irq(int irq, void *handle); -#if 0 /* unused */ - static void touch_work(struct touch *ts); -#endif -static void touch_work_q(struct work_struct *work); -static void touch_key_report(struct touch *ts, unsigned char button_data); -static void touch_report_protocol_a(struct touch *ts); -static void touch_report_protocol_b(struct touch *ts); -static void touch_event_clear(struct touch *ts); -#if 0 /* unused */ - static void touch_enable(struct touch *ts); - static void touch_disable(struct touch *ts); -#endif -static void touch_input_close(struct input_dev *input); -static int touch_input_open(struct input_dev *input); -static int touch_check_functionality (struct touch_pdata *pdata); -void touch_hw_reset(struct touch *ts); -int touch_info_display(struct touch *ts); -int touch_probe(struct i2c_client *client, const struct i2c_device_id *client_id); -int touch_remove(struct i2c_client *client); - - -// Kinsey: -#define WMT_TS_I2C_NAME "wmt-ts" -static struct i2c_client *l_client; - - - - -//---------------------------------------------- -irqreturn_t touch_irq(int irq, void *handle) -{ - struct touch *ts = handle; - if (gpio_irqstatus(ts->pdata->irq_gpio)){ - wmt_gpio_ack_irq(ts->pdata->irq_gpio); - if (is_gpio_irqenable(ts->pdata->irq_gpio)){ - wmt_gpio_mask_irq(ts->pdata->irq_gpio); - #ifdef CONFIG_HAS_EARLYSUSPEND - if(!ts->earlysus) - queue_work(ts->work_queue, &ts->work); - #else - queue_work(ts->work_queue, &ts->work); - #endif - } - return IRQ_HANDLED; - } - return IRQ_NONE; - -} - -//---------------------------------------------- -static void touch_work_q(struct work_struct *work) -{ - struct touch *ts = container_of(work, struct touch, work); - ts->pdata->touch_work(ts); -} - -//---------------------------------------------- -static void touch_key_report(struct touch *ts, unsigned char button_data) -{ - static button_u button_old; - button_u button_new; - - button_new.ubyte = button_data; - if(button_old.ubyte != button_new.ubyte) { - if((button_old.bits.bt0_press != button_new.bits.bt0_press) && (ts->pdata->keycnt > 0)) { - if(button_new.bits.bt0_press) input_report_key(ts->input, ts->pdata->keycode[0], true); - else input_report_key(ts->input, ts->pdata->keycode[0], false); - #if defined(DEBUG_TOUCH_KEY) - dbg("keycode[0](0x%04X) %s\n", ts->pdata->keycode[0], button_new.bits.bt0_press ? "press":"release"); - #endif - } - if((button_old.bits.bt1_press != button_new.bits.bt1_press) && (ts->pdata->keycnt > 1)) { - if(button_new.bits.bt1_press) input_report_key(ts->input, ts->pdata->keycode[1], true); - else input_report_key(ts->input, ts->pdata->keycode[1], false); - #if defined(DEBUG_TOUCH_KEY) - dbg("keycode[1](0x%04X) %s\n", ts->pdata->keycode[1], button_new.bits.bt1_press ? "press":"release"); - #endif - } - if((button_old.bits.bt2_press != button_new.bits.bt2_press) && (ts->pdata->keycnt > 2)) { - if(button_new.bits.bt2_press) input_report_key(ts->input, ts->pdata->keycode[2], true); - else input_report_key(ts->input, ts->pdata->keycode[2], false); - #if defined(DEBUG_TOUCH_KEY) - dbg("keycode[2](0x%04X) %s\n", ts->pdata->keycode[2], button_new.bits.bt2_press ? "press":"release"); - #endif - } - if((button_old.bits.bt3_press != button_new.bits.bt3_press) && (ts->pdata->keycnt > 3)) { - if(button_new.bits.bt3_press) input_report_key(ts->input, ts->pdata->keycode[3], true); - else input_report_key(ts->input, ts->pdata->keycode[3], false); - #if defined(DEBUG_TOUCH_KEY) - dbg("keycode[3](0x%04X) %s\n", ts->pdata->keycode[3], button_new.bits.bt3_press ? "press":"release"); - #endif - } - if((button_old.bits.bt4_press != button_new.bits.bt4_press) && (ts->pdata->keycnt > 4)) { - if(button_new.bits.bt4_press) input_report_key(ts->input, ts->pdata->keycode[4], true); - else input_report_key(ts->input, ts->pdata->keycode[4], false); - #if defined(DEBUG_TOUCH_KEY) - dbg("keycode[4](0x%04X) %s\n", ts->pdata->keycode[4], button_new.bits.bt4_press ? "press":"release"); - #endif - } - if((button_old.bits.bt5_press != button_new.bits.bt5_press) && (ts->pdata->keycnt > 5)) { - if(button_new.bits.bt5_press) input_report_key(ts->input, ts->pdata->keycode[5], true); - else input_report_key(ts->input, ts->pdata->keycode[5], false); - #if defined(DEBUG_TOUCH_KEY) - dbg("keycode[5](0x%04X) %s\n", ts->pdata->keycode[5], button_new.bits.bt5_press ? "press":"release"); - #endif - } - if((button_old.bits.bt6_press != button_new.bits.bt6_press) && (ts->pdata->keycnt > 6)) { - if(button_new.bits.bt6_press) input_report_key(ts->input, ts->pdata->keycode[6], true); - else input_report_key(ts->input, ts->pdata->keycode[6], false); - #if defined(DEBUG_TOUCH_KEY) - dbg("keycode[6](0x%04X) %s\n", ts->pdata->keycode[6], button_new.bits.bt6_press ? "press":"release"); - #endif - } - if((button_old.bits.bt7_press != button_new.bits.bt7_press) && (ts->pdata->keycnt > 7)) { - if(button_new.bits.bt7_press) input_report_key(ts->input, ts->pdata->keycode[7], true); - else input_report_key(ts->input, ts->pdata->keycode[7], false); - #if defined(DEBUG_TOUCH_KEY) - dbg("keycode[7](0x%04X) %s\n", ts->pdata->keycode[7], button_new.bits.bt7_press ? "press":"release"); - #endif - } - button_old.ubyte = button_new.ubyte; - } -} - -//---------------------------------------------- -static void touch_report_protocol_a(struct touch *ts) -{ - int id; - - for(id = 0; id < ts->pdata->max_fingers; id++) { - - if(ts->finger[id].event == TS_EVENT_UNKNOWN) continue; - - if(ts->finger[id].event != TS_EVENT_RELEASE) { - if(ts->pdata->id_max) input_report_abs(ts->input, ABS_MT_TRACKING_ID, ts->finger[id].id); - if(ts->pdata->area_max) input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, ts->finger[id].area ? ts->finger[id].area : 10); - if(ts->pdata->press_max) input_report_abs(ts->input, ABS_MT_PRESSURE, ts->finger[id].pressure); - - input_report_abs(ts->input, ABS_MT_POSITION_X, ts->finger[id].x); - input_report_abs(ts->input, ABS_MT_POSITION_Y, ts->finger[id].y); - dbg("%s : id = %d, x = %d, y = %d\n", __func__, ts->finger[id].id, ts->finger[id].x, ts->finger[id].y); - } - else { - ts->finger[id].event = TS_EVENT_UNKNOWN; - dbg("%s : release id = %d\n", __func__, ts->finger[id].id); - } - - input_mt_sync(ts->input); - } - - input_sync(ts->input); -} - -//---------------------------------------------- -static void touch_report_protocol_b(struct touch *ts) -{ - int id; -#if defined(DEBUG_TOUCH) - char *event_str[] = {"unknown", "press", "move", "release"}; -#endif - - for(id = 0; id < ts->pdata->max_fingers; id++) { - if((ts->finger[id].event == TS_EVENT_UNKNOWN) || (ts->finger[id].status == false)) - continue; - - input_mt_slot(ts->input, id); - ts->finger[id].status = false; - - if(ts->finger[id].event != TS_EVENT_RELEASE) { - input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true); - - input_report_abs(ts->input, ABS_MT_TRACKING_ID, ts->finger[id].id); - input_report_abs(ts->input, ABS_MT_POSITION_X, ts->finger[id].x); - input_report_abs(ts->input, ABS_MT_POSITION_Y, ts->finger[id].y); - - if(ts->pdata->area_max) input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, ts->finger[id].area ? ts->finger[id].area : 10); - if(ts->pdata->press_max) input_report_abs(ts->input, ABS_MT_PRESSURE, ts->finger[id].pressure); - -#if defined(DEBUG_TOUCH) - dbg("%s : event = %s, slot = %d, id = %d, x = %d, y = %d\n", __func__, event_str[ts->finger[id].event], id, ts->finger[id].id, ts->finger[id].x, ts->finger[id].y); -#endif - } - else { -#if defined(DEBUG_TOUCH) - dbg("%s : event = %s, slot = %d, id = %d\n", __func__, event_str[ts->finger[id].event], id, ts->finger[id].id); -#endif - ts->finger[id].event = TS_EVENT_UNKNOWN; - input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false); - } - } - input_sync(ts->input); -} - -//---------------------------------------------- -static void touch_event_clear(struct touch *ts) -{ - unsigned char id; - - for(id = 0; id < ts->pdata->max_fingers; id++) { - if(ts->finger[id].event == TS_EVENT_MOVE) { - ts->finger[id].status = true; - ts->finger[id].event = TS_EVENT_RELEASE; - } - } - ts->pdata->report(ts); - if(ts->pdata->keycode) - ts->pdata->key_report(ts, 0x00); -} - -//---------------------------------------------- -static int touch_input_open(struct input_dev *input) -{ - struct touch *ts = input_get_drvdata(input); - - ts->pdata->enable(ts); - - dbg("%s\n", __func__); - - return 0; -} - -//---------------------------------------------- -static void touch_input_close(struct input_dev *input) -{ - struct touch *ts = input_get_drvdata(input); - - ts->pdata->disable(ts); - - dbg("%s\n", __func__); -} - -//---------------------------------------------- -static int touch_check_functionality(struct touch_pdata *pdata) -{ - if(!pdata) { - errlog("Error : Platform data is NULL pointer!\n"); return -1; - } - - pdata->i2c_read = sn310m_i2c_read; - pdata->i2c_write = sn310m_i2c_write; - - pdata->i2c_boot_read = sn310m_i2c_read; - pdata->i2c_boot_write = sn310m_i2c_write; - - pdata->enable = sn310m_enable; - pdata->disable = sn310m_disable; - pdata->probe = sn310m_probe; - - if(!pdata->report) { - if(pdata->id_max) pdata->report = touch_report_protocol_b; - else pdata->report = touch_report_protocol_a; - } - if(!pdata->key_report) pdata->key_report = touch_key_report; - - pdata->touch_work = sn310m_work; - - if(!pdata->irq_func) pdata->irq_func = touch_irq; - - if(!pdata->event_clear) pdata->event_clear = touch_event_clear; - -#ifdef CONFIG_HAS_EARLYSUSPEND - if(!pdata->resume) pdata->resume = touch_resume; - if(!pdata->suspend) pdata->suspend = touch_suspend; -#endif - - //pdata->irq_gpio = 7; - - return 0; -} - -//---------------------------------------------- -void touch_hw_reset(struct touch *ts) -{ - if(ts->pdata->reset_gpio) { - if(gpio_request(ts->pdata->reset_gpio, "touch reset")) { - errlog("--------------------------------------------------------\n"); - errlog("%s : request port error!\n", "touch reset"); - errlog("--------------------------------------------------------\n"); - } - else { - if(ts->pdata->power) { - /* power sequence: reset low -> power on -> reset high */ - gpio_direction_output(ts->pdata->reset_gpio, 0); - gpio_set_value(ts->pdata->reset_gpio, 0); - mdelay(15); - ts->pdata->power(1); - mdelay(50); - gpio_set_value(ts->pdata->reset_gpio, 1); - mdelay(15); - } - else { - /* if there is no power control for touch, then just do reset (high -> low -> high) */ - gpio_direction_output(ts->pdata->reset_gpio, 1); - gpio_set_value(ts->pdata->reset_gpio, 1); - mdelay(15); - gpio_set_value(ts->pdata->reset_gpio, 0); - mdelay(20); - gpio_set_value(ts->pdata->reset_gpio, 1); - mdelay(15); - } - } - } -} - -//---------------------------------------------- -int touch_info_display(struct touch *ts) -{ - errlog("--------------------------------------------------------\n"); - errlog(" TOUCH SCREEN INFORMATION\n"); - errlog("--------------------------------------------------------\n"); - if(ts->pdata->irq_gpio) { - errlog("TOUCH INPUT Name = %s\n", ts->pdata->name); - - switch(ts->pdata->irq_mode) { - default : - case IRQ_MODE_THREAD: errlog("TOUCH IRQ Mode = %s\n", "IRQ_MODE_THREAD"); break; - case IRQ_MODE_NORMAL: errlog("TOUCH IRQ Mode = %s\n", "IRQ_MODE_NORMAL"); break; - case IRQ_MODE_POLLING: errlog("TOUCH IRQ Mode = %s\n", "IRQ_MODE_POLLING"); break; - } - errlog("TOUCH F/W Version = %d.%02d\n", ts->fw_version / 100, ts->fw_version % 100); - errlog("TOUCH FINGRES MAX = %d\n", ts->pdata->max_fingers); - errlog("TOUCH ABS X MAX = %d, TOUCH ABS X MIN = %d\n", ts->pdata->abs_max_x, ts->pdata->abs_min_x); - errlog("TOUCH ABS Y MAX = %d, TOUCH ABS Y MIN = %d\n", ts->pdata->abs_max_y, ts->pdata->abs_min_y); - - if(ts->pdata->area_max) - errlog("TOUCH MAJOR MAX = %d, TOUCH MAJOR MIN = %d\n", ts->pdata->area_max, ts->pdata->area_min); - - if(ts->pdata->press_max) - errlog("TOUCH PRESS MAX = %d, TOUCH PRESS MIN = %d\n", ts->pdata->press_max, ts->pdata->press_min); - - if(ts->pdata->id_max) { - errlog("TOUCH ID MAX = %d, TOUCH ID MIN = %d\n", ts->pdata->id_max, ts->pdata->id_min); - errlog("Mulit-Touch Protocol-B Used.\n"); - } - else - errlog("Mulit-Touch Protocol-A Used.\n"); - - if(ts->pdata->gpio_init) - errlog("GPIO early-init function implemented\n"); - - if(ts->pdata->reset_gpio) - errlog("H/W Reset function implemented\n"); - - #ifdef CONFIG_HAS_EARLYSUSPEND - errlog("Early-suspend function implemented\n"); - #endif - if(ts->pdata->fw_control) - errlog("Firmware update function(sysfs control) implemented\n"); - - /* flashing sample is not implemented yet */ - if(ts->pdata->flash_firmware) - errlog("Firmware update function(udev control) implemented\n"); - - if(ts->pdata->calibration) - errlog("Calibration function implemented\n"); - } - else { - errlog("TOUCH INPUT Name = %s\n", ts->pdata->name); - errlog("Dummy Touchscreen driver!\n"); - } - errlog("--------------------------------------------------------\n"); - return 0; -} - -//---------------------------------------------- -int touch_probe(struct i2c_client *client, const struct i2c_device_id *client_id) -{ - return -1; -} - -//---------------------------------------------- -// -// Power Management function -// -//---------------------------------------------- -#ifdef CONFIG_HAS_EARLYSUSPEND -static void touch_suspend(struct early_suspend *h) -{ - struct touch *ts = container_of(h, struct touch, power); - - dbg("%s++\n", __func__); - - /* TSC enters deep sleep mode */ - dbg("[%s] touch reset goes low!\n", __func__); - gpio_direction_output(ts->pdata->reset_gpio, 0); - gpio_set_value(ts->pdata->reset_gpio, 0); - - ts->pdata->disable(ts); -} - -//---------------------------------------------- -static void touch_resume(struct early_suspend *h) -{ - struct touch *ts = container_of(h, struct touch, power); - - dbg("%s++\n", __func__); - - /* TSC enters active mode */ - dbg("[%s] touch reset goes high!\n", __func__); - gpio_direction_output(ts->pdata->reset_gpio, 1); - gpio_set_value(ts->pdata->reset_gpio, 1); - - ts->pdata->enable(ts); -} -#endif - -//---------------------------------------------- -int touch_remove(struct i2c_client *client) -{ - struct device *dev = &client->dev; - struct touch *ts = dev_get_drvdata(dev); - - dbg("touch_remove++"); - - if(ts->irq) free_irq(ts->irq, ts); - - if(ts->pdata->reset_gpio) gpio_free(ts->pdata->reset_gpio); - - if(ts->pdata->irq_gpio) gpio_free(ts->pdata->irq_gpio); - - input_unregister_device(ts->input); - - dev_set_drvdata(dev, NULL); - -#if defined(SN310M_NATIVE_INTERFACE) - P_SN310M_Dist_Remove(); -#endif - - kfree(ts->finger); ts->finger = NULL; - kfree(ts); ts = NULL; - - return 0; -} - -#if defined(SN310M_NATIVE_INTERFACE) -#define SN310M_DIST_MINOR 250 - -typedef struct { - unsigned int addr; - short *buf; - unsigned int size; -} packet_t; - -static const struct file_operations SN310M_Dist_Fops = -{ - .owner = THIS_MODULE, - .open = P_SN310M_Dist_Open, - .unlocked_ioctl = P_SN310M_Dist_Ioctl, -}; - - -static struct miscdevice SN310M_Dist_MiscDev = -{ - .minor = SN310M_DIST_MINOR, - .name = "sn310m_dist", - .fops = &SN310M_Dist_Fops, - .mode = 0x666, -}; - - -static long P_SN310M_Dist_Ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - packet_t* packet = (packet_t*)arg; - int i; - - mutex_lock(&g_ts->mutex); - switch(cmd) { - case 0: // write data - if(packet->size) { - unsigned short addr = (packet->addr >> 8) | (packet->addr & 0x00ff) << 8; - g_ts->pdata->i2c_write(g_ts->client, (unsigned char *)&addr, sizeof(addr), (unsigned char *)packet->buf, packet->size*2); - dbg("Request I2C Write\n"); - } - break; - - case 1: // read data - if(packet->size) { - unsigned short addr = (packet->addr >> 8) | (packet->addr & 0x00ff) << 8; - short buffer[500] = {0, }; - - g_ts->pdata->i2c_read(g_ts->client, (unsigned char *)&addr, sizeof(addr), (unsigned char *)buffer, packet->size*2); - for(i = 0; (i < packet->size) && (i < 500); i++) { - packet->buf[i] = buffer[i]; - } - dbg("Request I2C Read\n"); - } - break; - - default: - mutex_unlock(&g_ts->mutex); - return -ENOIOCTLCMD; - } - - mutex_unlock(&g_ts->mutex); - return 0; -} - -static int P_SN310M_Dist_Open(struct inode *inode, struct file *file) -{ - return 0; -} - -static int P_SN310M_Dist_Probe(struct touch* ts) -{ - int result = 0; - - g_ts = ts; - result = misc_register(&SN310M_Dist_MiscDev); - if(result == 0) { - dbg("succeeded to register sn310m_misc_device \n"); - } - else { - errlog("failed to register sn310m_misc_device \n"); - } - - return result; -} - -static void P_SN310M_Dist_Remove(void) -{ - misc_deregister(&SN310M_Dist_MiscDev); - g_ts = NULL; -} -#endif -static const struct i2c_device_id sample_ts_id[] = { - { I2C_TOUCH_NAME, 0 }, - {}, -}; - - - -#define TS_DRIVER_NAME "wmt-touch" - -static void wmt_ts_platform_release(struct device *device) -{ - dbg("wmt_ts_platform_release\n"); - return; -} - -static struct platform_device wmt_ts_plt_device = { - .name = TS_DRIVER_NAME, - .id = 0, - .dev = { - .release = wmt_ts_platform_release, - }, -}; - -static int sn310m_keycode[] = { - KEY_HOME, KEY_MENU, KEY_BACK, KEY_SEARCH -}; - -struct touch_pdata sn310m_touch_pdata = { - - .name = "sn310m", // input drv name - .irq_gpio = 7,//SAMPLE_GPIO_0, // irq gpio define - .reset_gpio = 4,//SAMPLE_GPIO_1, // reset gpio define - .reset_level = 0, // reset level setting (1 = High reset, 0 = Low reset) - - .irq_mode = IRQ_MODE_NORMAL, // IRQ_MODE_THREAD, IRQ_MODE_NORMAL, IRQ_MODE_POLLING - .irq_flags = IRQF_SHARED ,//IRQF_TRIGGER_FALLING | IRQF_DISABLED, - - .abs_max_x = 600, - .abs_max_y = 1024, - - .area_max = 10, - .press_max = 255, - - .id_max = 10 + 1, - .id_min = 0, - - .vendor = 0x16B4, - .product = 0x0310, - .version = 0x0001, - - .max_fingers = 5, - - .keycnt = 4, - .keycode = sn310m_keycode, - .lcd_exchg = 0, - - //-------------------------------------------- - // Control function - //-------------------------------------------- - .touch_work = sn310m_work, - .enable = sn310m_enable, - .disable = sn310m_disable, - .early_probe = sn310m_early_probe, - .probe = sn310m_probe, - - //-------------------------------------------- - // I2C control function - //-------------------------------------------- - .i2c_write = sn310m_i2c_write, - .i2c_read = sn310m_i2c_read, - - //-------------------------------------------- - // Calibration function - //-------------------------------------------- - .calibration = sn310m_calibration, - - //-------------------------------------------- - // Firmware update control function - //-------------------------------------------- - .fw_filename = "sn310m_fw.bin", - .fw_filesize = (10 * 1024), // 10K bytes - .input_open = sn310m_input_open, - .flash_firmware = sn310m_flash_firmware, -}; - - -int temp; -static int wmt_ts_probe(struct platform_device *pdev) -{ - int rc = -1; - struct i2c_client *client = l_client; - struct device *dev = &client->dev; - struct touch *ts; - - - dbg("wmt_ts_probe\n"); - - if(!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_err(&client->dev, "i2c byte data not supported\n"); - return -EIO; - } - - - client->dev.platform_data = &sn310m_touch_pdata; - - if(touch_check_functionality(client->dev.platform_data) < 0) { - dev_err(&client->dev, "Platform data is not available!\n"); - return -EINVAL; - } - - if(!(ts = kzalloc(sizeof(struct touch), GFP_KERNEL))) { - errlog("touch struct malloc error!\n"); - return -ENOMEM; - } - ts->client = client; - ts->pdata = client->dev.platform_data; - - - /* by limst, setting gpio for IRQ */ - if(ts->pdata->irq_gpio) { - int ret; - - ts->irq = IRQ_GPIO;//MSM_GPIO_TO_INT(ts->pdata->irq_gpio); - dbg("IRQ_GPIO(%d) IRQ(%d) REG\n", ts->pdata->irq_gpio, ts->irq); - - ret = gpio_request(ts->pdata->irq_gpio, "touch_int"); - if(ret < 0) - errlog("FAIL: touch_int gpio_request\n"); - else - dbg("OK: touch_int gpio_request value(%d)\n", gpio_get_value(ts->pdata->irq_gpio)); - - wmt_gpio_setpull(ts->pdata->irq_gpio,WMT_GPIO_PULL_UP); - gpio_direction_input(ts->pdata->irq_gpio); - wmt_gpio_set_irq_type(ts->pdata->irq_gpio, IRQ_TYPE_EDGE_FALLING); - } - - i2c_set_clientdata(client, ts); - - if(ts->pdata->max_fingers) { - if(!(ts->finger = kzalloc(sizeof(finger_t) * ts->pdata->max_fingers, GFP_KERNEL))) { - kfree(ts); - errlog("touch data struct malloc error!\n"); - return -ENOMEM; - } - } - - if(ts->pdata->gpio_init) ts->pdata->gpio_init(); - - if(ts->pdata->early_probe) { - if((rc = ts->pdata->early_probe(ts)) < 0) - goto err_free_mem; - } - - - dev_set_drvdata(dev, ts); - - if(!(ts->input = input_allocate_device())) - goto err_free_mem; - - snprintf(ts->phys, sizeof(ts->phys), "%s/input0", ts->pdata->name); - - if(!ts->pdata->input_open) ts->input->open = touch_input_open; - else ts->input->open = ts->pdata->input_open; - if(!ts->pdata->input_close) ts->input->close = touch_input_close; - else ts->input->close = ts->pdata->input_close; - - /* - * by limst, for the test purpose, - * input device's name is forcedly set to the name of android idc file - */ - ts->input->name = "qwerty";//idc's filename //"touch_dev"; - //ts->input->name = ts->pdata->name; - ts->input->phys = ts->phys; - ts->input->dev.parent = dev; - ts->input->id.bustype = BUS_I2C; - - ts->input->id.vendor = ts->pdata->vendor; - ts->input->id.product = ts->pdata->product; - ts->input->id.version = ts->pdata->version; - - set_bit(EV_SYN, ts->input->evbit); - set_bit(EV_ABS, ts->input->evbit); - - /* Register Touch Key Event */ - if(ts->pdata->keycode) { - int key; - - set_bit(EV_KEY, ts->input->evbit); - - for(key = 0; key < ts->pdata->keycnt; key++) { - if(ts->pdata->keycode[key] <= 0) continue; - set_bit(ts->pdata->keycode[key] & KEY_MAX, ts->input->keybit); - } - } - - input_set_drvdata(ts->input, ts); - - if (sn310m_touch_pdata.lcd_exchg) { - input_set_abs_params(ts->input, ABS_MT_POSITION_X, ts->pdata->abs_min_y, ts->pdata->abs_max_y, 0, 0); - input_set_abs_params(ts->input, ABS_MT_POSITION_Y, ts->pdata->abs_min_x, ts->pdata->abs_max_x, 0, 0); - } else { - input_set_abs_params(ts->input, ABS_MT_POSITION_X, ts->pdata->abs_min_x, ts->pdata->abs_max_x, 0, 0); - input_set_abs_params(ts->input, ABS_MT_POSITION_Y, ts->pdata->abs_min_y, ts->pdata->abs_max_y, 0, 0); - } - - if(ts->pdata->area_max) - input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, ts->pdata->area_min, ts->pdata->area_max, 0, 0); - - if(ts->pdata->press_max) - input_set_abs_params(ts->input, ABS_MT_PRESSURE, ts->pdata->press_min, ts->pdata->press_max, 0, 0); - - if(ts->pdata->id_max) { - input_set_abs_params(ts->input, ABS_MT_TRACKING_ID, ts->pdata->id_min, ts->pdata->id_max, 0, 0); - input_mt_init_slots(ts->input, ts->pdata->max_fingers); - } - - - mutex_init(&ts->mutex); - if(ts->irq) { - switch(ts->pdata->irq_mode) { - default : - case IRQ_MODE_THREAD: - INIT_WORK(&ts->work, touch_work_q); - if((ts->work_queue = create_singlethread_workqueue("work_queue")) == NULL) - goto err_free_input_mem; - - if((rc = request_threaded_irq(ts->irq, NULL, ts->pdata->irq_func, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, ts->pdata->name, ts))) { - dev_err(dev, "threaded irq %d request fail!\n", ts->irq); - goto err_free_input_mem; - } - break; - case IRQ_MODE_NORMAL: - INIT_WORK(&ts->work, touch_work_q); - if((ts->work_queue = create_singlethread_workqueue("work_queue")) == NULL) - goto err_free_input_mem; - - if((rc = request_irq(ts->irq, ts->pdata->irq_func, ts->pdata->irq_flags, ts->pdata->name, ts))) { - errlog("irq %d request fail!\n", ts->irq); - goto err_free_input_mem; - } - dbg("irq %d request ok!\n", ts->irq); - break; - case IRQ_MODE_POLLING: - errlog("Error IRQ_MODE POLLING!! but defined irq_gpio\n"); - break; - } /* end of switch */ - } - ts->disabled = true; - - if((rc = input_register_device(ts->input))) { - dev_err(dev, "(%s) input register fail!\n", ts->input->name); - goto err_free_input_mem; - } - - /* by limst, added to turn on the power and reset of Touch IC */ - touch_hw_reset(ts); - -#if defined(CONFIG_HAS_EARLYSUSPEND) - if(ts->pdata->suspend) ts->power.suspend = ts->pdata->suspend; - if(ts->pdata->resume) ts->power.resume = ts->pdata->resume; - - ts->power.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1; - - register_early_suspend(&ts->power); -#endif - - if(ts->pdata->probe) { - ts->pdata->probe(ts); - } - - touch_info_display(ts); - -#if defined(SN310M_NATIVE_INTERFACE) - if(P_SN310M_Dist_Probe(ts) < 0) { - errlog("P_SN310M_Dist_Probe(), fail\n"); - } -#endif - - return 0; - - free_irq(ts->irq, ts); - input_unregister_device(ts->input); - err_free_input_mem: - input_free_device(ts->input); - ts->input = NULL; - err_free_mem: - kfree(ts->finger); - ts->finger = NULL; - kfree(ts); - ts = NULL; - return rc; -} - -static int wmt_ts_remove(struct platform_device *pdev) -{ - struct i2c_client *client = l_client; - struct device *dev = &client->dev; - struct touch *ts = dev_get_drvdata(dev); - - dbg("wmt_ts_remove\n"); - - if(ts->irq) free_irq(ts->irq, ts); - - if(ts->pdata->reset_gpio) gpio_free(ts->pdata->reset_gpio); - - if(ts->pdata->irq_gpio) gpio_free(ts->pdata->irq_gpio); - - input_unregister_device(ts->input); - - dev_set_drvdata(dev, NULL); - - #if defined(SN310M_NATIVE_INTERFACE) - P_SN310M_Dist_Remove(); - #endif - - kfree(ts->finger); ts->finger = NULL; - kfree(ts); ts = NULL; - - return 0; -} - -static int wmt_ts_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct i2c_client *client = l_client; - struct device *dev = &client->dev; - struct touch *ts = dev_get_drvdata(dev); - - dbg("%s++\n", __func__); - - /* TSC enters deep sleep mode */ - dbg("[%s] touch reset goes low!\n", __func__); - gpio_direction_output(ts->pdata->reset_gpio, 0); - gpio_set_value(ts->pdata->reset_gpio, 0); - - - ts->pdata->disable(ts); - - return 0; -} -static int wmt_ts_resume(struct platform_device *pdev) -{ - struct i2c_client *client = l_client; - struct device *dev = &client->dev; - struct touch *ts = dev_get_drvdata(dev); - - dbg("%s++\n", __func__); - - /* TSC enters active mode */ - dbg("[%s] touch reset goes high!\n", __func__); - gpio_direction_output(ts->pdata->reset_gpio, 1); - gpio_set_value(ts->pdata->reset_gpio, 1); - - ts->pdata->enable(ts); - //touch_hw_reset(ts); - - return 0; -} - - -static struct platform_driver wmt_ts_plt_driver = { - .driver = { - .name = TS_DRIVER_NAME, - .owner = THIS_MODULE, - }, - .probe = wmt_ts_probe, - .remove = wmt_ts_remove, - .suspend = wmt_ts_suspend, - .resume = wmt_ts_resume, -}; - - - -struct i2c_board_info ts_i2c_board_info = { - .type = WMT_TS_I2C_NAME, - .flags = 0x00, - .platform_data = NULL, - .archdata = NULL, - .irq = -1, -}; - -static int ts_i2c_register_device (void) -{ - struct i2c_board_info *ts_i2c_bi; - struct i2c_adapter *adapter = NULL; - - ts_i2c_board_info.addr =(unsigned short) 0x3c; - ts_i2c_bi = &ts_i2c_board_info; - adapter = i2c_get_adapter(1);/*in bus 1*/ - - if (NULL == adapter) { - errlog("can not get i2c adapter, client address error\n"); - return -1; - } - l_client = i2c_new_device(adapter, ts_i2c_bi); - if (l_client == NULL) { - errlog("allocate i2c client failed\n"); - return -1; - } - i2c_put_adapter(adapter); - return 0; -} - -static void ts_i2c_unregister_device(void) -{ - if (l_client != NULL) - { - i2c_unregister_device(l_client); - l_client = NULL; - } -} - -static struct tp_info l_tpinfo; -static int wmt_check_touch_env(void) -{ - int ret = 0; - int len = 127; - char retval[200] = {0}; - char *p=NULL; - char *s=NULL; - int Enable=0; - - // Get u-boot parameter - ret = wmt_getsyspara("wmt.io.touch", retval, &len); - if(ret){ - errlog("Read wmt.io.touch Failed.\n"); - return -EIO; - } - memset(&l_tpinfo,0,sizeof(l_tpinfo)); - - p = retval; - sscanf(p,"%d:", &Enable); - p = strchr(p,':'); - p++; - s = strchr(p,':'); - strncpy(l_tpinfo.name,p, (s-p)); - p = s+1; - //dbg("ts_name=%s\n", l_tpinfo.name); - - ret = sscanf(p,"%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", - &l_tpinfo.irq_gpio,&l_tpinfo.panelres_x,&l_tpinfo.panelres_y,&l_tpinfo.rst_gpio, - &(l_tpinfo.xaxis),&(l_tpinfo.xdir),&(l_tpinfo.ydir), - &(l_tpinfo.max_finger_num),&l_tpinfo.i2caddr,&l_tpinfo.low_Impendence_mode,&l_tpinfo.download_option); - - if (ret < 8){ - errlog("Wrong format ts u-boot param(%d)!\nwmt.io.touch=%s\n",ret,retval); - return -ENODEV; - } - - //check touch enable - if(Enable == 0){ - errlog("Touch Screen Is Disabled.\n"); - return -ENODEV; - } - if (strstr(l_tpinfo.name, sn310m_touch_pdata.name) == NULL){ - errlog("Can't find %s in the wmt.io.touch\n", sn310m_touch_pdata.name); - return -ENODEV; - } - - errlog("p.x = %d, p.y = %d, gpio=%d, resetgpio=%d,xaxis=%d,xdir=%d,ydri=%d,maxfingernum=%d,,i2c_addr=0x%X,low_Impendence_mode=%d,s_download_option=%d\n", - l_tpinfo.panelres_x, l_tpinfo.panelres_y, l_tpinfo.irq_gpio, l_tpinfo.rst_gpio, - l_tpinfo.xaxis,l_tpinfo.xdir,l_tpinfo.ydir, - l_tpinfo.max_finger_num,l_tpinfo.i2caddr,l_tpinfo.low_Impendence_mode,l_tpinfo.download_option); - - sn310m_touch_pdata.irq_gpio = l_tpinfo.irq_gpio; - sn310m_touch_pdata.reset_gpio = l_tpinfo.rst_gpio; - sn310m_touch_pdata.abs_max_x = l_tpinfo.panelres_x; - sn310m_touch_pdata.abs_max_y = l_tpinfo.panelres_y; - - memset(retval,0,sizeof(retval)); - ret = wmt_getsyspara("wmt.display.fb0", retval, &len); - if (!ret) { - int tmp[6]; - p = retval; - sscanf(p, "%d:[%d:%d:%d:%d:%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); - if (tmp[4] > tmp[5]) - sn310m_touch_pdata.lcd_exchg = 1; - } - - return 0; -} - - -static int __init sample_touch_init(void) -{ - int ret = 0; - - if(wmt_check_touch_env()) - return -ENODEV; - - - if (ts_i2c_register_device()<0){ - errlog("Error to run ts_i2c_register_device()!\n"); - return -1; - } - - ret = platform_device_register(&wmt_ts_plt_device); - if(ret){ - errlog("wmt ts plat device register failed!\n"); - return ret; - } - ret = platform_driver_register(&wmt_ts_plt_driver); - if(ret){ - errlog("can not register platform_driver_register\n"); - platform_device_unregister(&wmt_ts_plt_device); - return ret; - } - return 0; -} - -static void sample_touch_exit(void) -{ - platform_driver_unregister(&wmt_ts_plt_driver); - platform_device_unregister(&wmt_ts_plt_device); - ts_i2c_unregister_device(); - - return; -} - - -module_init(sample_touch_init); -module_exit(sample_touch_exit); - -#ifndef MODULE -__initcall(sample_touch_init); -#endif - - - -MODULE_AUTHOR("SEMISENS Co., Ltd."); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Touchscreen Driver for SN310M"); |