From cd455647f1f10ce750123f91ab1d0e68ca30ac1b Mon Sep 17 00:00:00 2001 From: hhb Date: Tue, 8 Mar 2011 20:45:33 +0800 Subject: [PATCH] migrate touch screen driver xpt2046 --- arch/arm/mach-rk29/board-rk29-phonesdk.c | 119 +++++--- drivers/input/touchscreen/Kconfig | 91 ++++-- drivers/input/touchscreen/Makefile | 5 +- drivers/input/touchscreen/calib_iface_ts.c | 49 +-- drivers/input/touchscreen/calibration_ts.c | 2 +- drivers/input/touchscreen/calibration_ts.h | 2 + drivers/input/touchscreen/largenum_ts.c | 0 drivers/input/touchscreen/largenum_ts.h | 6 +- drivers/input/touchscreen/xpt2046_cbn_ts.c | 283 +++++++++++------- drivers/input/touchscreen/xpt2046_cbn_ts.h | 10 + drivers/input/touchscreen/xpt2046_ts.c | 261 ++++++++++------ drivers/input/touchscreen/xpt2046_ts.h | 10 + .../input/touchscreen/xpt2046_ts_320X480.c | 4 +- 13 files changed, 547 insertions(+), 295 deletions(-) mode change 100644 => 100755 drivers/input/touchscreen/calibration_ts.c mode change 100644 => 100755 drivers/input/touchscreen/calibration_ts.h mode change 100644 => 100755 drivers/input/touchscreen/largenum_ts.c mode change 100644 => 100755 drivers/input/touchscreen/largenum_ts.h mode change 100644 => 100755 drivers/input/touchscreen/xpt2046_cbn_ts.h diff --git a/arch/arm/mach-rk29/board-rk29-phonesdk.c b/arch/arm/mach-rk29/board-rk29-phonesdk.c index 92b32224ac89..e46a8130b956 100755 --- a/arch/arm/mach-rk29/board-rk29-phonesdk.c +++ b/arch/arm/mach-rk29/board-rk29-phonesdk.c @@ -1,4 +1,4 @@ -/* arch/arm/mach-rk29/board-rk29.c +/* arch/arm/mach-rk29/board-rk29-phonesdk.c * * Copyright (C) 2010 ROCKCHIP, Inc. * @@ -54,9 +54,19 @@ #include #include "devices.h" + + + +/*set touchscreen different type header*/ +#if defined(CONFIG_TOUCHSCREEN_XPT2046_NORMAL_SPI) +#include "../../../drivers/input/touchscreen/xpt2046_ts.h" +#elif defined(CONFIG_TOUCHSCREEN_XPT2046_TSLIB_SPI) +#include "../../../drivers/input/touchscreen/xpt2046_tslib_ts.h" +#elif defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) #include "../../../drivers/input/touchscreen/xpt2046_cbn_ts.h" -#include "../../../drivers/misc/gps/rk29_gps.h" +#endif +#include "../../../drivers/misc/gps/rk29_gps.h" /* Set memory size of pmem */ #ifdef CONFIG_RK29_MEM_SIZE_M @@ -125,7 +135,7 @@ struct rk29_nand_platform_data rk29_nand_data = { #define LCD_CLK_PIN INVALID_GPIO #define LCD_CS_PIN INVALID_GPIO /***************************************************************************************** -* frame buffe devices +* frame buffer devices * author: zyw@rock-chips.com *****************************************************************************************/ #define FB_ID 0 @@ -2552,83 +2562,106 @@ struct rk29xx_spi_platform_data rk29xx_spi1_platdata = { .io_resume_leakage_bug = spi_io_resume_leakage_bug, }; + /***************************************************************************************** * xpt2046 touch panel - * author: cmc@rock-chips.com + * author: hhb@rock-chips.com *****************************************************************************************/ -#define XPT2046_GPIO_INT RK29_PIN0_PA3 +#define XPT2046_GPIO_INT RK29_PIN4_PD5 //中断脚 #define DEBOUNCE_REPTIME 3 -#if defined(CONFIG_TOUCHSCREEN_XPT2046_320X480_SPI) +#if defined(CONFIG_TOUCHSCREEN_XPT2046_NORMAL_SPI) || defined(CONFIG_TOUCHSCREEN_XPT2046_TSLIB_SPI) static struct xpt2046_platform_data xpt2046_info = { .model = 2046, .keep_vref_on = 1, .swap_xy = 0, - .x_min = 0, - .x_max = 320, - .y_min = 0, - .y_max = 480, .debounce_max = 7, .debounce_rep = DEBOUNCE_REPTIME, .debounce_tol = 20, .gpio_pendown = XPT2046_GPIO_INT, + .pendown_iomux_name = GPIO4D5_CPUTRACECTL_NAME, + .pendown_iomux_mode = GPIO4H_GPIO4D5, + .touch_virtualkey_length = 60, .penirq_recheck_delay_usecs = 1, -}; -#elif defined(CONFIG_TOUCHSCREEN_XPT2046_320X480_CBN_SPI) -static struct xpt2046_platform_data xpt2046_info = { - .model = 2046, - .keep_vref_on = 1, - .swap_xy = 0, +#if defined(CONFIG_TOUCHSCREEN_480X800) + .x_min = 0, + .x_max = 480, + .y_min = 0, + .y_max = 800, + .touch_ad_top = 3940, + .touch_ad_bottom = 310, + .touch_ad_left = 3772, + .touch_ad_right = 340, +#elif defined(CONFIG_TOUCHSCREEN_800X480) + .x_min = 0, + .x_max = 800, + .y_min = 0, + .y_max = 480, + .touch_ad_top = 2447, + .touch_ad_bottom = 207, + .touch_ad_left = 5938, + .touch_ad_right = 153, +#elif defined(CONFIG_TOUCHSCREEN_320X480) .x_min = 0, .x_max = 320, .y_min = 0, .y_max = 480, - .debounce_max = 7, - .debounce_rep = DEBOUNCE_REPTIME, - .debounce_tol = 20, - .gpio_pendown = XPT2046_GPIO_INT, - .penirq_recheck_delay_usecs = 1, + .touch_ad_top = 3166, + .touch_ad_bottom = 256, + .touch_ad_left = 3658, + .touch_ad_right = 380, +#endif }; -#elif defined(CONFIG_TOUCHSCREEN_XPT2046_SPI) +#elif defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) static struct xpt2046_platform_data xpt2046_info = { .model = 2046, .keep_vref_on = 1, - .swap_xy = 1, - .x_min = 0, - .x_max = 800, - .y_min = 0, - .y_max = 480, + .swap_xy = 0, .debounce_max = 7, .debounce_rep = DEBOUNCE_REPTIME, .debounce_tol = 20, .gpio_pendown = XPT2046_GPIO_INT, - + .pendown_iomux_name = GPIO4D5_CPUTRACECTL_NAME, + .pendown_iomux_mode = GPIO4H_GPIO4D5, + .touch_virtualkey_length = 60, .penirq_recheck_delay_usecs = 1, -}; -#elif defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) -static struct xpt2046_platform_data xpt2046_info = { - .model = 2046, - .keep_vref_on = 1, - .swap_xy = 1, + +#if defined(CONFIG_TOUCHSCREEN_480X800) + .x_min = 0, + .x_max = 480, + .y_min = 0, + .y_max = 800, + .screen_x = { 70, 410, 70, 410, 240}, + .screen_y = { 50, 50, 740, 740, 400}, + .uncali_x_default = { 3267, 831, 3139, 715, 1845 }, + .uncali_y_default = { 3638, 3664, 564, 591, 2087 }, +#elif defined(CONFIG_TOUCHSCREEN_800X480) .x_min = 0, .x_max = 800, .y_min = 0, .y_max = 480, - .debounce_max = 7, - .debounce_rep = DEBOUNCE_REPTIME, - .debounce_tol = 20, - .gpio_pendown = XPT2046_GPIO_INT, - - .penirq_recheck_delay_usecs = 1, + .screen_x[5] = { 50, 750, 50, 750, 400}; + .screen_y[5] = { 40, 40, 440, 440, 240}; + .uncali_x_default[5] = { 438, 565, 3507, 3631, 2105 }; + .uncali_y_default[5] = { 3756, 489, 3792, 534, 2159 }; +#elif defined(CONFIG_TOUCHSCREEN_320X480) + .x_min = 0, + .x_max = 320, + .y_min = 0, + .y_max = 480, + .screen_x[5] = { 50, 270, 50, 270, 160}; + .screen_y[5] = { 40, 40, 440, 440, 240}; + .uncali_x_default[5] = { 812, 3341, 851, 3371, 2183 }; + .uncali_y_default[5] = { 442, 435, 3193, 3195, 2004 }; +#endif }; #endif static struct spi_board_info board_spi_devices[] = { -#if defined(CONFIG_TOUCHSCREEN_XPT2046_320X480_SPI) || defined(CONFIG_TOUCHSCREEN_XPT2046_320X480_CBN_SPI)\ - ||defined(CONFIG_TOUCHSCREEN_XPT2046_SPI) || defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) +#if defined(CONFIG_TOUCHSCREEN_XPT2046_SPI) { .modalias = "xpt2046_ts", - .chip_select = 0, + .chip_select = 0,// 2, .max_speed_hz = 125 * 1000 * 26,/* (max sample rate @ 3V) * (cmd + data + overhead) */ .bus_num = 0, .irq = XPT2046_GPIO_INT, diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 40faa3160bb4..0e9e0bbdfee2 100755 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -11,30 +11,83 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN -choice - prompt "XPT2046 based touchscreens: SPI Interface" - default TOUCHSCREEN_XPT2046_CBN_SPI +config TOUCHSCREEN_XPT2046_SPI + tristate "XPT2046 based touchscreens:SPI Interface" + depends on SPIM_RK29 + + config TOUCHSCREEN_XPT2046_NORMAL_SPI + tristate "normal mode" + depends on TOUCHSCREEN_XPT2046_SPI + + config TOUCHSCREEN_480X800 + tristate "480X800 resolution" + depends on TOUCHSCREEN_XPT2046_NORMAL_SPI + + config TOUCHSCREEN_800X480 + tristate "800X480 resolution" + depends on TOUCHSCREEN_XPT2046_NORMAL_SPI + + config TOUCHSCREEN_320X480 + tristate "320X480 resolution" + depends on TOUCHSCREEN_XPT2046_NORMAL_SPI + + config TOUCHSCREEN_XPT2046_TSLIB_SPI + tristate "tslib mode" + depends on TOUCHSCREEN_XPT2046_SPI + + config TOUCHSCREEN_480X800 + tristate "480X800 resolution" + depends on TOUCHSCREEN_XPT2046_TSLIB_SPI + + config TOUCHSCREEN_800X480 + tristate "800X480 resolution" + depends on TOUCHSCREEN_XPT2046_TSLIB_SPI + + config TOUCHSCREEN_320X480 + tristate "320X480 resolution" + depends on TOUCHSCREEN_XPT2046_TSLIB_SPI + + config TOUCHSCREEN_XPT2046_CBN_SPI + tristate "calibration mode" + depends on TOUCHSCREEN_XPT2046_SPI + + config TOUCHSCREEN_480X800 + tristate "480X800 resolution" + depends on TOUCHSCREEN_XPT2046_CBN_SPI + + config TOUCHSCREEN_800X480 + tristate "800X480 resolution" + depends on TOUCHSCREEN_XPT2046_CBN_SPI + + config TOUCHSCREEN_320X480 + tristate "320X480 resolution" + depends on TOUCHSCREEN_XPT2046_CBN_SPI + +#choice +# prompt "XPT2046 based touchscreens: SPI Interface" +# default TOUCHSCREEN_XPT2046_CBN_SPI - config TOUCHSCREEN_XPT2046_SPI_NOCHOOSE - bool "DO NOT CHOOSE TOUCHSCREEN_XPT2046" +# config TOUCHSCREEN_XPT2046_SPI_NOCHOOSE +# bool "DO NOT CHOOSE TOUCHSCREEN_XPT2046" - config TOUCHSCREEN_XPT2046_SPI - bool "800X480 TOUCHSCREEN" - depends on SPIM_RK2818 || SPIM_RK29 +# config TOUCHSCREEN_XPT2046_SPI +# bool "800X480 TOUCHSCREEN" +# depends on SPIM_RK2818 || SPIM_RK29 - config TOUCHSCREEN_XPT2046_CBN_SPI - bool "800X480 CALIBRATION TOUCHSCREEN" - depends on SPIM_RK2818 || SPIM_RK29 +# config TOUCHSCREEN_XPT2046_CBN_SPI +# bool "800X480 CALIBRATION TOUCHSCREEN" +# depends on SPIM_RK2818 || SPIM_RK29 - config TOUCHSCREEN_XPT2046_320X480_SPI - bool "320X480 TOUCHSCREEN" - depends on SPIM_RK2818 || SPIM_RK29 +# config TOUCHSCREEN_XPT2046_320X480_SPI +# bool "320X480 TOUCHSCREEN" +# depends on SPIM_RK2818 || SPIM_RK29 - config TOUCHSCREEN_XPT2046_320X480_CBN_SPI - bool "320X480 CALIBRATION TOUCHSCREEN" - depends on SPIM_RK2818 || SPIM_RK29 - -endchoice +# config TOUCHSCREEN_XPT2046_320X480_CBN_SPI +# bool "320X480 CALIBRATION TOUCHSCREEN" +# depends on SPIM_RK2818 || SPIM_RK29 +#endchoice + + config TOUCHSCREEN_ADS7846 tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" depends on SPI_MASTER diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 486f923df853..e2288952af1d 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -43,10 +43,9 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o -obj-$(CONFIG_TOUCHSCREEN_XPT2046_SPI) += xpt2046_ts.o +obj-$(CONFIG_TOUCHSCREEN_XPT2046_NORMAL_SPI) += xpt2046_ts.o +obj-$(CONFIG_TOUCHSCREEN_XPT2046_TSLIB_SPI) += xpt2046_tslib_ts.o ts_lib/ obj-$(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) += xpt2046_cbn_ts.o calibration_ts.o largenum_ts.o calib_iface_ts.o -obj-$(CONFIG_TOUCHSCREEN_XPT2046_320X480_SPI) += xpt2046_ts_320X480.o -obj-$(CONFIG_TOUCHSCREEN_XPT2046_320X480_CBN_SPI) += xpt2046_cbn_ts.o calibration_ts.o largenum_ts.o calib_iface_ts.o obj-$(CONFIG_TOUCHSCREEN_IT7250) += ctp_it7250.o obj-$(CONFIG_RK28_I2C_TS_NTP070) += ntp070.o obj-$(CONFIG_HANNSTAR_P1003) += hannstar_p1003.o diff --git a/drivers/input/touchscreen/calib_iface_ts.c b/drivers/input/touchscreen/calib_iface_ts.c index 1d9335c808e4..d67502b2f371 100755 --- a/drivers/input/touchscreen/calib_iface_ts.c +++ b/drivers/input/touchscreen/calib_iface_ts.c @@ -33,35 +33,33 @@ extern volatile struct adc_point gADPoint; extern volatile int gZvalue[3]; #endif - -#if defined(CONFIG_TOUCHSCREEN_XPT2046_320X480_CBN_SPI) - int screen_x[5] = { 50, 270, 50, 270, 160}; - int screen_y[5] = { 40, 40, 440, 440, 240}; -#elif defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) - int screen_x[5] = { 50, 750, 50, 750, 400}; - int screen_y[5] = { 40, 40, 440, 440, 240}; -#elif defined(CONFIG_TOUCHSCREEN_XPT2046_1024X600_CBN_SPI) - int screen_x[5] = {50, 974, 50, 974, 512}; - int screen_y[5] = {50, 50, 550, 550, 300}; -#endif - - - - +#if 0 #if defined(CONFIG_MACH_RK2818INFO_IT50) && defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) + int screen_x[5] = { 50, 750, 50, 750, 400}; + int screen_y[5] = { 40, 40, 440, 440, 240}; int uncali_x_default[5] = { 3735, 301, 3754, 290, 1993 }; int uncali_y_default[5] = { 3442, 3497, 413, 459, 1880 }; #elif defined(CONFIG_MACH_RK2818INFO) && defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) + int screen_x[5] = { 50, 750, 50, 750, 400}; + int screen_y[5] = { 40, 40, 440, 440, 240}; int uncali_x_default[5] = { 438, 565, 3507, 3631, 2105 }; int uncali_y_default[5] = { 3756, 489, 3792, 534, 2159 }; #elif (defined(CONFIG_MACH_RAHO) || defined(CONFIG_MACH_RAHOSDK) || defined(CONFIG_MACH_RK2818INFO))&& defined(CONFIG_TOUCHSCREEN_XPT2046_320X480_CBN_SPI) + int screen_x[5] = { 50, 270, 50, 270, 160}; + int screen_y[5] = { 40, 40, 440, 440, 240}; int uncali_x_default[5] = { 812, 3341, 851, 3371, 2183 }; int uncali_y_default[5] = { 442, 435, 3193, 3195, 2004 }; -#elif defined(CONFIG_MACH_RK29SDK) && defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) - int uncali_x_default[5] = { 3735, 301, 3754, 290, 1993 }; - int uncali_y_default[5] = { 3442, 3497, 413, 459, 1880 }; +#elif defined(CONFIG_MACH_Z5) && defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI) + int uncali_x_default[5] = { 3267, 831, 3139, 715, 1845 }; + int uncali_y_default[5] = { 3638, 3664, 564, 591, 2087 }; + int screen_x[5] = { 70, 410, 70, 410, 240}; + int screen_y[5] = { 50, 50, 740, 740, 400}; #endif - +#endif +int screen_x[5] = { 0 }; +int screen_y[5] = { 0 }; +int uncali_x_default[5] = { 0 }; +int uncali_y_default[5] = { 0 }; int uncali_x[5] = { 0 }; int uncali_y[5] = { 0 }; @@ -163,7 +161,7 @@ static CLASS_ATTR(calistatus, 0666, touch_cali_status, NULL); static CLASS_ATTR(pressure, 0666, touch_pressure, NULL); #endif -static int __init tp_calib_iface_init(void) +int tp_calib_iface_init(int *x,int *y,int *uncali_x, int *uncali_y) { int ret = 0; int err = 0; @@ -175,6 +173,11 @@ static int __init tp_calib_iface_init(void) return -ENOMEM; } + memcpy(screen_x,x,5*sizeof(int)); + memcpy(screen_y,y,5*sizeof(int)); + memcpy(uncali_x_default,uncali_x,5*sizeof(int)); + memcpy(uncali_y_default,uncali_y,5*sizeof(int)); + err = TouchPanelSetCalibration(4, screen_x, screen_y, uncali_x_default, uncali_y_default); printk("tp_calib_iface_init---%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", uncali_x_default[0], uncali_y_default[0], @@ -205,7 +208,7 @@ static int __init tp_calib_iface_init(void) return ret; } -static void __exit tp_calib_iface_exit(void) +void tp_calib_iface_exit(void) { class_remove_file(tp_class, &class_attr_touchcheck); class_remove_file(tp_class, &class_attr_touchadc); @@ -216,8 +219,8 @@ static void __exit tp_calib_iface_exit(void) class_destroy(tp_class); } -module_init(tp_calib_iface_init); -module_exit(tp_calib_iface_exit); +//module_init(tp_calib_iface_init); +//module_exit(tp_calib_iface_exit); MODULE_AUTHOR("Yongle Lai"); MODULE_DESCRIPTION("XPT2046 TPC driver @ Rockchip"); diff --git a/drivers/input/touchscreen/calibration_ts.c b/drivers/input/touchscreen/calibration_ts.c old mode 100644 new mode 100755 index 4da9f9d6a1c3..70f611154c5a --- a/drivers/input/touchscreen/calibration_ts.c +++ b/drivers/input/touchscreen/calibration_ts.c @@ -518,7 +518,7 @@ int TouchFilter(unsigned short* x,unsigned short* y,bool isdown) ClearBuff(); ret=TS_ERR_TDOWN; } - if(!TS_isINVALID(x,y)) + if(!TS_isINVALID(*x,*y)) addToBuff(x,y); if(sBuffIndex #include #include - +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif #include "xpt2046_cbn_ts.h" #include "calibration_ts.h" /* @@ -46,20 +49,16 @@ * note. The strength of filtering can be set in the board-* specific * files. */ -#define XPT2046_DEBUG 1 +#define XPT2046_DEBUG 0 #if XPT2046_DEBUG #define xpt2046printk(msg...) printk(msg); #else #define xpt2046printk(msg...) #endif -//#define TS_POLL_DELAY (15 * 1000000) /* ns delay before the first sample */ -//#define TS_POLL_PERIOD (15 * 1000000) /* ns delay between samples */ #define TS_POLL_DELAY (10 * 1000000) /* ns delay before the first sample */ #define TS_POLL_PERIOD (20 * 1000000) /* ns delay between samples */ - -#define DEBOUNCE_REPTIME 3 /* this driver doesn't aim at the peak continuous sample rate */ #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) @@ -87,32 +86,33 @@ struct xpt2046_packet { struct xpt2046 { struct input_dev *input; - char phys[32]; - char name[32]; - + char phys[32]; + char name[32]; + char pendown_iomux_name[IOMUX_NAME_SIZE]; struct spi_device *spi; - u16 model; - bool swap_xy; - + u16 model; + u16 x_min, x_max; + u16 y_min, y_max; + u16 debounce_max; + u16 debounce_tol; + u16 debounce_rep; + u16 penirq_recheck_delay_usecs; + bool swap_xy; + struct xpt2046_packet *packet; struct spi_transfer xfer[18]; struct spi_message msg[5]; struct spi_message *last_msg; - int msg_idx; - int read_cnt; - int read_rep; - int last_read; - - u16 debounce_max; - u16 debounce_tol; - u16 debounce_rep; - - u16 penirq_recheck_delay_usecs; - + int msg_idx; + int read_cnt; + int read_rep; + int last_read; + int pendown_iomux_mode; + int touch_virtualkey_length; spinlock_t lock; - struct hrtimer timer; + struct hrtimer timer; unsigned pendown:1; /* P: lock */ unsigned pending:1; /* P: lock */ // FIXME remove "irq_disabled" @@ -121,12 +121,15 @@ struct xpt2046 { unsigned is_suspended:1; int (*filter)(void *data, int data_idx, int *val); - void *filter_data; - void (*filter_cleanup)(void *data); + void *filter_data; + void (*filter_cleanup)(void *data); int (*get_pendown_state)(void); int gpio_pendown; - void (*wait_for_sync)(void); + void (*wait_for_sync)(void); +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif }; /* leave chip selected when we're done, for quicker re-select? */ @@ -195,21 +198,24 @@ struct dfr_req { struct spi_message msg; struct spi_transfer xfer[4]; }; -typedef struct -{ - s16 x; - s16 y; -}POINT; +volatile struct adc_point gADPoint; static void xpt2046_enable(struct xpt2046 *ts); static void xpt2046_disable(struct xpt2046 *ts); +static int xpt2046_verifyAndConvert(struct xpt2046 *ts,int adx, int ady,int *x, int *y) +{ + xpt2046printk("%s:(%d/%d)\n",__FUNCTION__,*x, *y); + + if((*x< ts->x_min) || (*x > ts->x_max)) + return 1; -volatile struct adc_point gADPoint; - - + if((*y< ts->y_min) || (*y > ts->y_max + ts->touch_virtualkey_length)) + return 1; + return 0; +} static int device_suspended(struct device *dev) { struct xpt2046 *ts = dev_get_drvdata(dev); @@ -249,14 +255,12 @@ static int xpt2046_read12_dfr(struct device *dev, unsigned command) CS_CHANGE(req->xfer[3]); spi_message_add_tail(&req->xfer[3], &req->msg); - printk(KERN_INFO "req->command:%x, req->sample:%02x, req->pwrdown:%x, req->dummy:%02x\n", req->command, req->sample, req->pwrdown, req->dummy); ts->irq_disabled = 1; disable_irq(spi->irq); status = spi_sync(spi, &req->msg); ts->irq_disabled = 0; enable_irq(spi->irq); - printk(KERN_INFO "req->command:%x, req->sample:%02x, req->pwrdown:%x, req->dummy:%02x\n", req->command, req->sample, req->pwrdown, req->dummy); - + if (status == 0) { /* on-wire is a must-ignore bit, a BE12 value, then padding */ status = be16_to_cpu(req->sample); @@ -293,14 +297,13 @@ static void null_wait_for_sync(void) * The SPI transfer completion callback does the real work. It reports * touchscreen events and reactivates the timer (or IRQ) as appropriate. */ - static void xpt2046_rx(void *xpt) { struct xpt2046 *ts = xpt; struct xpt2046_packet *packet = ts->packet; unsigned Rt = 1; u16 x, y; - int xd,yd; + int cal_x,cal_y; /* xpt2046_rx_val() did in-place conversion (including byteswap) from * on-the-wire format as part of debouncing to get stable readings. */ @@ -348,30 +351,36 @@ static void xpt2046_rx(void *xpt) */ if (Rt) { struct input_dev *input = ts->input; - if (!ts->pendown) { - input_report_key(input, BTN_TOUCH, 1); - ts->pendown = 1; - xpt2046printk("***>%s:input_report_key(pen down)\n",__FUNCTION__); - } - TouchPanelCalibrateAPoint(x, y, &xd, &yd); + TouchPanelCalibrateAPoint(x, y, &cal_x, &cal_y); - xd = xd / 4; - yd = yd / 4; + cal_x = cal_x / 4; + cal_y = cal_y / 4; gADPoint.x = x; gADPoint.y = y; if (ts->swap_xy) - swap(x, y); + swap(cal_x, cal_y); + if(xpt2046_verifyAndConvert(ts,cal_x,cal_y,&cal_x,&cal_y)) + { + xpt2046printk("***>%s:xpt2046_verifyAndConvert fail\n",__FUNCTION__); + goto out; + } - input_report_abs(input, ABS_X, xd); - input_report_abs(input, ABS_Y, yd); + if (!ts->pendown) { + input_report_key(input, BTN_TOUCH, 1); + ts->pendown = 1; + xpt2046printk("***>%s:input_report_key(pen down)\n",__FUNCTION__); + } + + input_report_abs(input, ABS_X, cal_x); + input_report_abs(input, ABS_Y, cal_y); input_sync(input); - xpt2046printk("***>%s:input_report_abs(%4d/%4d)\n",__FUNCTION__,xd, yd); + xpt2046printk("***>%s:input_report_abs(%4d/%4d)\n",__FUNCTION__,cal_x, cal_y); } - +out: hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_MODE_REL); } @@ -382,7 +391,7 @@ static int xpt2046_debounce(void *xpt, int data_idx, int *val) static int average_val[2]; - xpt2046printk("***>%s:%d,%d,%d,%d,%ld,%d,%d,%d\n",__FUNCTION__, + xpt2046printk("***>%s:%d,%d,%d,%d,%d,%d,%d,%d\n",__FUNCTION__, data_idx,ts->last_read, ts->read_cnt,ts->debounce_max, abs(ts->last_read - *val),ts->debounce_tol, @@ -396,16 +405,13 @@ static int xpt2046_debounce(void *xpt, int data_idx, int *val) ts->read_cnt++; return XPT2046_FILTER_REPEAT; } - if(*val == 4095 || *val == 0) { ts->read_cnt = 0; ts->last_read = 0; memset(average_val,0,sizeof(average_val)); xpt2046printk("***>%s:*val == 4095 || *val == 0\n",__FUNCTION__); - return XPT2046_FILTER_IGNORE; - } @@ -510,8 +516,6 @@ static enum hrtimer_restart xpt2046_timer(struct hrtimer *handle) spin_lock(&ts->lock); - xpt2046printk("***>%s.....%s.....%d\n",__FILE__,__FUNCTION__,__LINE__); - if (unlikely(!get_pendown_state(ts) || device_suspended(&ts->spi->dev))) { if (ts->pendown) { @@ -556,11 +560,14 @@ static irqreturn_t xpt2046_irq(int irq, void *handle) if (likely(get_pendown_state(ts))) { if (!ts->irq_disabled) { - + /* The ARM do_simple_IRQ() dispatcher doesn't act + * like the other dispatchers: it will report IRQs + * even after they've been disabled. We work around + * that here. (The "generic irq" framework may help...) + */ ts->irq_disabled = 1; disable_irq_nosync(ts->spi->irq); ts->pending = 1; - hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), HRTIMER_MODE_REL); } @@ -611,10 +618,8 @@ static void xpt2046_enable(struct xpt2046 *ts) enable_irq(ts->spi->irq); } -static int xpt2046_suspend(struct spi_device *spi, pm_message_t message) +static int xpt2046_pSuspend(struct xpt2046 *ts) { - struct xpt2046 *ts = dev_get_drvdata(&spi->dev); - spin_lock_irq(&ts->lock); ts->is_suspended = 1; @@ -623,13 +628,10 @@ static int xpt2046_suspend(struct spi_device *spi, pm_message_t message) spin_unlock_irq(&ts->lock); return 0; - } -static int xpt2046_resume(struct spi_device *spi) +static int xpt2046_pResume(struct xpt2046 *ts) { - struct xpt2046 *ts = dev_get_drvdata(&spi->dev); - spin_lock_irq(&ts->lock); ts->is_suspended = 0; @@ -640,6 +642,55 @@ static int xpt2046_resume(struct spi_device *spi) return 0; } +#if !defined(CONFIG_HAS_EARLYSUSPEND) +static int xpt2046_suspend(struct spi_device *spi, pm_message_t message) +{ + struct xpt2046 *ts = dev_get_drvdata(&spi->dev); + + printk("xpt2046_suspend\n"); + + xpt2046_pSuspend(ts); + + return 0; +} + +static int xpt2046_resume(struct spi_device *spi) +{ + struct xpt2046 *ts = dev_get_drvdata(&spi->dev); + + printk("xpt2046_resume\n"); + + xpt2046_pResume(ts); + + return 0; +} + +#elif defined(CONFIG_HAS_EARLYSUSPEND) +static void xpt2046_early_suspend(struct early_suspend *h) +{ + struct xpt2046 *ts; + ts = container_of(h, struct xpt2046, early_suspend); + + printk("xpt2046_suspend early\n"); + + xpt2046_pSuspend(ts); + + return; +} + +static void xpt2046_late_resume(struct early_suspend *h) +{ + struct xpt2046 *ts; + ts = container_of(h, struct xpt2046, early_suspend); + + printk("xpt2046_resume late\n"); + + xpt2046_pResume(ts); + + return; +} +#endif + static int __devinit setup_pendown(struct spi_device *spi, struct xpt2046 *ts) { struct xpt2046_platform_data *pdata = spi->dev.platform_data; @@ -659,33 +710,34 @@ static int __devinit setup_pendown(struct spi_device *spi, struct xpt2046 *ts) return 0; } - if (pdata->io_init) { + if (pdata->io_init) { err = pdata->io_init(); if (err) dev_err(&spi->dev, "xpt2046 io_init fail\n"); } + ts->gpio_pendown = pdata->gpio_pendown; + strcpy(ts->pendown_iomux_name,pdata->pendown_iomux_name); + ts->pendown_iomux_mode = pdata->pendown_iomux_mode; + + rk29_mux_api_set(ts->pendown_iomux_name,pdata->pendown_iomux_mode); err = gpio_request(pdata->gpio_pendown, "xpt2046_pendown"); if (err) { dev_err(&spi->dev, "failed to request pendown GPIO%d\n", pdata->gpio_pendown); return err; } - - err = gpio_direction_input(pdata->gpio_pendown); - if (err) { - dev_err(&spi->dev, "failed to switch GPIO to input%d\n", + + err = gpio_pull_updown(pdata->gpio_pendown, GPIOPullUp); + if (err) { + dev_err(&spi->dev, "failed to pullup pendown GPIO%d\n", pdata->gpio_pendown); return err; - } - - gpio_pull_updown(pdata->gpio_pendown,GPIOPullUp); - + } ts->gpio_pendown = pdata->gpio_pendown; return 0; } - static int __devinit xpt2046_probe(struct spi_device *spi) { struct xpt2046 *ts; @@ -705,12 +757,12 @@ static int __devinit xpt2046_probe(struct spi_device *spi) spi->irq = gpio_to_irq(spi->irq); dev_dbg(&spi->dev, "no IRQ?\n"); } - - if (!pdata) { + + if (!pdata) { dev_err(&spi->dev, "empty platform_data\n"); return -EFAULT; - } - + } + /* don't exceed max specified sample rate */ if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { dev_dbg(&spi->dev, "f(sample) %d KHz?\n", @@ -749,7 +801,7 @@ static int __devinit xpt2046_probe(struct spi_device *spi) spin_lock_init(&ts->lock); ts->model = pdata->model ? : 2046; - + if (pdata->filter != NULL) { if (pdata->filter_init != NULL) { err = pdata->filter_init(pdata, &ts->filter_data); @@ -778,9 +830,16 @@ static int __devinit xpt2046_probe(struct spi_device *spi) pdata->penirq_recheck_delay_usecs; ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; + ts->x_min = pdata->x_min; + ts->x_max = pdata->x_max; + ts->y_min = pdata->y_min; + ts->y_max = pdata->y_max; + + ts->touch_virtualkey_length = pdata->touch_virtualkey_length; + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); - snprintf(ts->name, sizeof(ts->name), "XPT%d Touchscreen", ts->model); + snprintf(ts->name, sizeof(ts->name), "xpt%d-touchscreen", ts->model); input_dev->name = ts->name; input_dev->phys = ts->phys; @@ -789,16 +848,17 @@ static int __devinit xpt2046_probe(struct spi_device *spi) input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, - pdata->x_min ? : 0, - pdata->x_max ? : MAX_12BIT, + ts->x_min ? : 0, + ts->x_max ? : MAX_12BIT, 0, 0); input_set_abs_params(input_dev, ABS_Y, - pdata->y_min ? : 0, - pdata->y_max ? : MAX_12BIT, + ts->y_min ? : 0, + ts->y_max ? : MAX_12BIT, 0, 0); vref = pdata->keep_vref_on; + tp_calib_iface_init(pdata->screen_x,pdata->screen_y,pdata->uncali_x_default,pdata->uncali_y_default); /* set up the transfers to read touchscreen state; this assumes we * use formula #2 for pressure, not #3. */ @@ -862,7 +922,7 @@ static int __devinit xpt2046_probe(struct spi_device *spi) if (request_irq(spi->irq, xpt2046_irq, IRQF_TRIGGER_FALLING, spi->dev.driver->name, ts)) { - printk("%s:trying pin change workaround on irq %d\n",__FUNCTION__,spi->irq); + xpt2046printk("%s:trying pin change workaround on irq %d\n",__FUNCTION__,spi->irq); err = request_irq(spi->irq, xpt2046_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, spi->dev.driver->name, ts); @@ -871,8 +931,6 @@ static int __devinit xpt2046_probe(struct spi_device *spi) goto err_free_gpio; } } - - xpt2046printk("***>%s:touchscreen irq %d\n",__FUNCTION__,spi->irq); /* take a first sample, leaving nPENIRQ active and vREF off; avoid @@ -880,20 +938,21 @@ static int __devinit xpt2046_probe(struct spi_device *spi) */ xpt2046_read12_dfr(&spi->dev,READ_X(1)); - //err = sysfs_create_group(&spi->dev.kobj, &xpt2046_attr_group); - if (err) - goto err_remove_hwmon; - err = input_register_device(input_dev); if (err) goto err_remove_attr_group; - printk("xpt2046_ts: driver initialized\n"); +#ifdef CONFIG_HAS_EARLYSUSPEND + ts->early_suspend.suspend = xpt2046_early_suspend; + ts->early_suspend.resume = xpt2046_late_resume; + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + register_early_suspend(&ts->early_suspend); +#endif + + xpt2046printk("xpt2046_ts: driver initialized\n"); return 0; err_remove_attr_group: - //sysfs_remove_group(&spi->dev.kobj, &xpt2046_attr_group); - err_remove_hwmon: free_irq(spi->irq, ts); err_free_gpio: if (ts->gpio_pendown != -1) @@ -908,15 +967,19 @@ static int __devinit xpt2046_probe(struct spi_device *spi) return err; } + static int __devexit xpt2046_remove(struct spi_device *spi) { struct xpt2046 *ts = dev_get_drvdata(&spi->dev); input_unregister_device(ts->input); - + +#if !defined(CONFIG_HAS_EARLYSUSPEND) xpt2046_suspend(spi, PMSG_SUSPEND); - - //sysfs_remove_group(&spi->dev.kobj, &xpt2046_attr_group); +#elif defined(CONFIG_HAS_EARLYSUSPEND) + xpt2046_early_suspend(&ts->early_suspend); + unregister_early_suspend(&ts->early_suspend); +#endif free_irq(ts->spi->irq, ts); /* suspend left the IRQ disabled */ @@ -930,7 +993,9 @@ static int __devexit xpt2046_remove(struct spi_device *spi) kfree(ts->packet); kfree(ts); - + + tp_calib_iface_exit(); + dev_dbg(&spi->dev, "unregistered touchscreen\n"); return 0; } @@ -943,19 +1008,19 @@ static struct spi_driver xpt2046_driver = { }, .probe = xpt2046_probe, .remove = __devexit_p(xpt2046_remove), +#ifndef CONFIG_HAS_EARLYSUSPEND .suspend = xpt2046_suspend, .resume = xpt2046_resume, +#endif }; static int __init xpt2046_init(void) { int ret; - - xpt2046printk("Touch panel drive XPT2046 driver init...\n"); - gADPoint.x = 0; gADPoint.y = 0; - + + xpt2046printk("Touch panel drive XPT2046 driver init...\n"); ret = spi_register_driver(&xpt2046_driver); if (ret) { @@ -976,6 +1041,6 @@ static void __exit xpt2046_exit(void) module_init(xpt2046_init); module_exit(xpt2046_exit); -MODULE_DESCRIPTION("rk2818 spi xpt2046 TouchScreen Driver"); +MODULE_DESCRIPTION("rk29xx spi xpt2046 TouchScreen Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("spi:xpt2046"); diff --git a/drivers/input/touchscreen/xpt2046_cbn_ts.h b/drivers/input/touchscreen/xpt2046_cbn_ts.h old mode 100644 new mode 100755 index 73f84c19e0cc..d2b30bd494b0 --- a/drivers/input/touchscreen/xpt2046_cbn_ts.h +++ b/drivers/input/touchscreen/xpt2046_cbn_ts.h @@ -15,6 +15,9 @@ #ifndef __DRIVERS_TOUCHSCREEN_XPT2046_CBN_TS_H #define __DRIVERS_TOUCHSCREEN_XPT2046_CBN_TS_H + +#define IOMUX_NAME_SIZE 20 + enum xpt2046_filter { XPT2046_FILTER_OK, XPT2046_FILTER_REPEAT, @@ -44,6 +47,13 @@ struct xpt2046_platform_data { int gpio_pendown; /* the GPIO used to decide the pendown * state if get_pendown_state == NULL */ + char pendown_iomux_name[IOMUX_NAME_SIZE]; + int pendown_iomux_mode; + int touch_virtualkey_length; + int screen_x[5]; + int screen_y[5]; + int uncali_x_default[5]; + int uncali_y_default[5]; int (*get_pendown_state)(void); int (*filter_init) (struct xpt2046_platform_data *pdata, void **filter_data); diff --git a/drivers/input/touchscreen/xpt2046_ts.c b/drivers/input/touchscreen/xpt2046_ts.c index 0bc38b8bc676..418a863f5198 100755 --- a/drivers/input/touchscreen/xpt2046_ts.c +++ b/drivers/input/touchscreen/xpt2046_ts.c @@ -1,7 +1,7 @@ /* - * drivers/input/touchscreen/xpt2046_ts.c - driver for rk2818 spi xpt2046 device and console + * drivers/input/touchscreen/xpt2046_ts.c - driver for rk29 spi xpt2046 device and console * - * Copyright (C) 2010 ROCKCHIP, Inc. + * Copyright (C) 2011 ROCKCHIP, Inc. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -23,7 +23,10 @@ #include #include #include - +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif #include "xpt2046_ts.h" /* @@ -52,38 +55,10 @@ #else #define xpt2046printk(msg...) #endif -#define LCD_MAX_LENGTH 800 -#define LCD_MAX_WIDTH 480 - -#ifdef CONFIG_MACH_RK2818INFO_IT50 -#define PT2046_TOUCH_AD_LEFT 207 -#define PT2046_TOUCH_AD_RIGHT 3940 -#define PT2046_TOUCH_AD_TOP 3624 -#define PT2046_TOUCH_AD_BOTTOM 153 - -#define AD_TO_X(adx) (LCD_MAX_WIDTH * ( PT2046_TOUCH_AD_TOP - adx) / ( PT2046_TOUCH_AD_TOP - PT2046_TOUCH_AD_BOTTOM)) -#define AD_TO_Y(ady) (LCD_MAX_LENGTH * ( ady - PT2046_TOUCH_AD_LEFT ) / (PT2046_TOUCH_AD_RIGHT - PT2046_TOUCH_AD_LEFT)) -/* -#define PT2046_TOUCH_AD_LEFT 4000 -#define PT2046_TOUCH_AD_RIGHT 110 -#define PT2046_TOUCH_AD_TOP 110 -#define PT2046_TOUCH_AD_BOTTOM 3800 -#define AD_TO_Y(adx) (LCD_MAX_WIDTH * ( PT2046_TOUCH_AD_BOTTOM - adx) / ( PT2046_TOUCH_AD_BOTTOM - PT2046_TOUCH_AD_TOP )) -#define AD_TO_X(ady) (LCD_MAX_LENGTH * (PT2046_TOUCH_AD_LEFT - ady) / (PT2046_TOUCH_AD_LEFT - PT2046_TOUCH_AD_RIGHT)) -*/ -#else -#define PT2046_TOUCH_AD_LEFT 3855 -#define PT2046_TOUCH_AD_RIGHT 260 -#define PT2046_TOUCH_AD_TOP 300 -#define PT2046_TOUCH_AD_BOTTOM 3755 -#define AD_TO_X(adx) (LCD_MAX_WIDTH * (adx - PT2046_TOUCH_AD_TOP) / ( PT2046_TOUCH_AD_BOTTOM - PT2046_TOUCH_AD_TOP )) -#define AD_TO_Y(ady) (LCD_MAX_LENGTH * (PT2046_TOUCH_AD_LEFT - ady) / (PT2046_TOUCH_AD_LEFT - PT2046_TOUCH_AD_RIGHT)) -#endif #define TS_POLL_DELAY (10 * 1000000) /* ns delay before the first sample */ #define TS_POLL_PERIOD (20 * 1000000) /* ns delay between samples */ -#define DEBOUNCE_REPTIME 3 /* this driver doesn't aim at the peak continuous sample rate */ #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) @@ -111,32 +86,37 @@ struct xpt2046_packet { struct xpt2046 { struct input_dev *input; - char phys[32]; - char name[32]; - + char phys[32]; + char name[32]; + char pendown_iomux_name[IOMUX_NAME_SIZE]; struct spi_device *spi; - u16 model; - bool swap_xy; - + u16 model; + u16 x_min, x_max; + u16 y_min, y_max; + u16 debounce_max; + u16 debounce_tol; + u16 debounce_rep; + u16 penirq_recheck_delay_usecs; + bool swap_xy; + struct xpt2046_packet *packet; struct spi_transfer xfer[18]; struct spi_message msg[5]; struct spi_message *last_msg; - int msg_idx; - int read_cnt; - int read_rep; - int last_read; - - u16 debounce_max; - u16 debounce_tol; - u16 debounce_rep; - - u16 penirq_recheck_delay_usecs; - + int msg_idx; + int read_cnt; + int read_rep; + int last_read; + int pendown_iomux_mode; + int touch_ad_top; + int touch_ad_bottom; + int touch_ad_left; + int touch_ad_right; + int touch_virtualkey_length; spinlock_t lock; - struct hrtimer timer; + struct hrtimer timer; unsigned pendown:1; /* P: lock */ unsigned pending:1; /* P: lock */ // FIXME remove "irq_disabled" @@ -145,12 +125,15 @@ struct xpt2046 { unsigned is_suspended:1; int (*filter)(void *data, int data_idx, int *val); - void *filter_data; - void (*filter_cleanup)(void *data); + void *filter_data; + void (*filter_cleanup)(void *data); int (*get_pendown_state)(void); int gpio_pendown; - void (*wait_for_sync)(void); + void (*wait_for_sync)(void); +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif }; /* leave chip selected when we're done, for quicker re-select? */ @@ -222,7 +205,22 @@ struct dfr_req { static void xpt2046_enable(struct xpt2046 *ts); static void xpt2046_disable(struct xpt2046 *ts); +static int xpt2046_verifyAndConvert(struct xpt2046 *ts,u16 adx, u16 ady,u16 *x, u16 *y) +{ + *x = ts->x_max * (ts->touch_ad_left - adx)/(ts->touch_ad_left - ts->touch_ad_right); + *y = ts->y_max * (ts->touch_ad_top - ady)/(ts->touch_ad_top - ts->touch_ad_bottom); + + xpt2046printk("%s:(%d/%d)\n",__FUNCTION__,*x, *y); + + if((*x< ts->x_min) || (*x > ts->x_max)) + return 1; + if((*y< ts->y_min) || (*y > ts->y_max + ts->touch_virtualkey_length)) + return 1; + + + return 0; +} static int device_suspended(struct device *dev) { struct xpt2046 *ts = dev_get_drvdata(dev); @@ -304,7 +302,6 @@ static void null_wait_for_sync(void) * The SPI transfer completion callback does the real work. It reports * touchscreen events and reactivates the timer (or IRQ) as appropriate. */ - static void xpt2046_rx(void *xpt) { struct xpt2046 *ts = xpt; @@ -359,17 +356,21 @@ static void xpt2046_rx(void *xpt) */ if (Rt) { struct input_dev *input = ts->input; + + if (ts->swap_xy) + swap(x, y); + + if(xpt2046_verifyAndConvert(ts,x,y,&x,&y)) + { + xpt2046printk("***>%s:xpt2046_verifyAndConvert fail\n",__FUNCTION__); + goto out; + } + if (!ts->pendown) { input_report_key(input, BTN_TOUCH, 1); ts->pendown = 1; xpt2046printk("***>%s:input_report_key(pen down)\n",__FUNCTION__); - } - - x = AD_TO_X(x); - y = AD_TO_Y(y); - - if (ts->swap_xy) - swap(x, y); + } input_report_abs(input, ABS_X, x); input_report_abs(input, ABS_Y, y); @@ -377,7 +378,7 @@ static void xpt2046_rx(void *xpt) input_sync(input); xpt2046printk("***>%s:input_report_abs(%4d/%4d)\n",__FUNCTION__,x, y); } - +out: hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_MODE_REL); } @@ -410,13 +411,7 @@ static int xpt2046_debounce(void *xpt, int data_idx, int *val) xpt2046printk("***>%s:*val == 4095 || *val == 0\n",__FUNCTION__); return XPT2046_FILTER_IGNORE; } - /* discard the first sample. */ -/* if(!ts->read_cnt) - { - ts->read_cnt++; - return XPT2046_FILTER_REPEAT; - } -move discard ahead */ + if (ts->read_cnt==1 || (abs(ts->last_read - *val) > ts->debounce_tol)) { /* Start over collecting consistent readings. */ @@ -466,6 +461,7 @@ static int xpt2046_no_filter(void *xpt, int data_idx, int *val) return XPT2046_FILTER_OK; } +//#define spi_async(a,b) static void xpt2046_rx_val(void *xpt) { struct xpt2046 *ts = xpt; @@ -621,10 +617,8 @@ static void xpt2046_enable(struct xpt2046 *ts) enable_irq(ts->spi->irq); } -static int xpt2046_suspend(struct spi_device *spi, pm_message_t message) +static int xpt2046_pSuspend(struct xpt2046 *ts) { - struct xpt2046 *ts = dev_get_drvdata(&spi->dev); - spin_lock_irq(&ts->lock); ts->is_suspended = 1; @@ -633,13 +627,10 @@ static int xpt2046_suspend(struct spi_device *spi, pm_message_t message) spin_unlock_irq(&ts->lock); return 0; - } -static int xpt2046_resume(struct spi_device *spi) +static int xpt2046_pResume(struct xpt2046 *ts) { - struct xpt2046 *ts = dev_get_drvdata(&spi->dev); - spin_lock_irq(&ts->lock); ts->is_suspended = 0; @@ -650,6 +641,55 @@ static int xpt2046_resume(struct spi_device *spi) return 0; } +#if !defined(CONFIG_HAS_EARLYSUSPEND) +static int xpt2046_suspend(struct spi_device *spi, pm_message_t message) +{ + struct xpt2046 *ts = dev_get_drvdata(&spi->dev); + + printk("xpt2046_suspend\n"); + + xpt2046_pSuspend(ts); + + return 0; +} + +static int xpt2046_resume(struct spi_device *spi) +{ + struct xpt2046 *ts = dev_get_drvdata(&spi->dev); + + printk("xpt2046_resume\n"); + + xpt2046_pResume(ts); + + return 0; +} + +#elif defined(CONFIG_HAS_EARLYSUSPEND) +static void xpt2046_early_suspend(struct early_suspend *h) +{ + struct xpt2046 *ts; + ts = container_of(h, struct xpt2046, early_suspend); + + printk("xpt2046_suspend early\n"); + + xpt2046_pSuspend(ts); + + return; +} + +static void xpt2046_late_resume(struct early_suspend *h) +{ + struct xpt2046 *ts; + ts = container_of(h, struct xpt2046, early_suspend); + + printk("xpt2046_resume late\n"); + + xpt2046_pResume(ts); + + return; +} +#endif + static int __devinit setup_pendown(struct spi_device *spi, struct xpt2046 *ts) { struct xpt2046_platform_data *pdata = spi->dev.platform_data; @@ -674,14 +714,25 @@ static int __devinit setup_pendown(struct spi_device *spi, struct xpt2046 *ts) if (err) dev_err(&spi->dev, "xpt2046 io_init fail\n"); } - + + ts->gpio_pendown = pdata->gpio_pendown; + strcpy(ts->pendown_iomux_name,pdata->pendown_iomux_name); + ts->pendown_iomux_mode = pdata->pendown_iomux_mode; + + rk29_mux_api_set(ts->pendown_iomux_name,pdata->pendown_iomux_mode); err = gpio_request(pdata->gpio_pendown, "xpt2046_pendown"); if (err) { dev_err(&spi->dev, "failed to request pendown GPIO%d\n", pdata->gpio_pendown); return err; } - + + err = gpio_pull_updown(pdata->gpio_pendown, GPIOPullUp); + if (err) { + dev_err(&spi->dev, "failed to pullup pendown GPIO%d\n", + pdata->gpio_pendown); + return err; + } ts->gpio_pendown = pdata->gpio_pendown; return 0; } @@ -697,8 +748,6 @@ static int __devinit xpt2046_probe(struct spi_device *spi) int vref; int err; - - if (!spi->irq) { dev_dbg(&spi->dev, "no IRQ?\n"); return -ENODEV; @@ -751,7 +800,7 @@ static int __devinit xpt2046_probe(struct spi_device *spi) spin_lock_init(&ts->lock); ts->model = pdata->model ? : 2046; - + if (pdata->filter != NULL) { if (pdata->filter_init != NULL) { err = pdata->filter_init(pdata, &ts->filter_data); @@ -780,9 +829,20 @@ static int __devinit xpt2046_probe(struct spi_device *spi) pdata->penirq_recheck_delay_usecs; ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; - + ts->x_min = pdata->x_min; + ts->x_max = pdata->x_max; + ts->y_min = pdata->y_min; + ts->y_max = pdata->y_max; + + ts->touch_ad_top = pdata->touch_ad_top; + ts->touch_ad_bottom= pdata->touch_ad_bottom; + ts->touch_ad_left= pdata->touch_ad_left; + ts->touch_ad_right= pdata->touch_ad_right; + + ts->touch_virtualkey_length = pdata->touch_virtualkey_length; + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); - snprintf(ts->name, sizeof(ts->name), "XPT%d Touchscreen", ts->model); + snprintf(ts->name, sizeof(ts->name), "xpt%d-touchscreen", ts->model); input_dev->name = ts->name; input_dev->phys = ts->phys; @@ -791,12 +851,12 @@ static int __devinit xpt2046_probe(struct spi_device *spi) input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, - pdata->x_min ? : 0, - pdata->x_max ? : MAX_12BIT, + ts->x_min ? : 0, + ts->x_max ? : MAX_12BIT, 0, 0); input_set_abs_params(input_dev, ABS_Y, - pdata->y_min ? : 0, - pdata->y_max ? : MAX_12BIT, + ts->y_min ? : 0, + ts->y_max ? : MAX_12BIT, 0, 0); vref = pdata->keep_vref_on; @@ -864,7 +924,7 @@ static int __devinit xpt2046_probe(struct spi_device *spi) if (request_irq(spi->irq, xpt2046_irq, IRQF_TRIGGER_FALLING, spi->dev.driver->name, ts)) { - printk("%s:trying pin change workaround on irq %d\n",__FUNCTION__,spi->irq); + xpt2046printk("%s:trying pin change workaround on irq %d\n",__FUNCTION__,spi->irq); err = request_irq(spi->irq, xpt2046_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, spi->dev.driver->name, ts); @@ -883,7 +943,15 @@ static int __devinit xpt2046_probe(struct spi_device *spi) err = input_register_device(input_dev); if (err) goto err_remove_attr_group; - printk("xpt2046_ts: driver initialized\n"); + +#ifdef CONFIG_HAS_EARLYSUSPEND + ts->early_suspend.suspend = xpt2046_early_suspend; + ts->early_suspend.resume = xpt2046_late_resume; + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + register_early_suspend(&ts->early_suspend); +#endif + + xpt2046printk("xpt2046_ts: driver initialized\n"); return 0; err_remove_attr_group: @@ -906,8 +974,13 @@ static int __devexit xpt2046_remove(struct spi_device *spi) struct xpt2046 *ts = dev_get_drvdata(&spi->dev); input_unregister_device(ts->input); - + +#if !defined(CONFIG_HAS_EARLYSUSPEND) xpt2046_suspend(spi, PMSG_SUSPEND); +#elif defined(CONFIG_HAS_EARLYSUSPEND) + xpt2046_early_suspend(&ts->early_suspend); + unregister_early_suspend(&ts->early_suspend); +#endif free_irq(ts->spi->irq, ts); /* suspend left the IRQ disabled */ @@ -934,22 +1007,26 @@ static struct spi_driver xpt2046_driver = { }, .probe = xpt2046_probe, .remove = __devexit_p(xpt2046_remove), +#ifndef CONFIG_HAS_EARLYSUSPEND .suspend = xpt2046_suspend, .resume = xpt2046_resume, +#endif }; - +extern int spi_register_driver(struct spi_driver *sdrv); static int __init xpt2046_init(void) { return spi_register_driver(&xpt2046_driver); } -module_init(xpt2046_init); + static void __exit xpt2046_exit(void) { + xpt2046printk("Touch panel drive XPT2046 driver exit...\n"); spi_unregister_driver(&xpt2046_driver); } +module_init(xpt2046_init); module_exit(xpt2046_exit); -MODULE_DESCRIPTION("rk2818 spi xpt2046 TouchScreen Driver"); +MODULE_DESCRIPTION("rk29xx spi xpt2046 TouchScreen Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("spi:xpt2046"); diff --git a/drivers/input/touchscreen/xpt2046_ts.h b/drivers/input/touchscreen/xpt2046_ts.h index 4ff65ba1eb69..3c3b90f2bbf9 100755 --- a/drivers/input/touchscreen/xpt2046_ts.h +++ b/drivers/input/touchscreen/xpt2046_ts.h @@ -15,6 +15,9 @@ #ifndef __DRIVERS_TOUCHSCREEN_XPT2046_TS_H #define __DRIVERS_TOUCHSCREEN_XPT2046_TS_H + +#define IOMUX_NAME_SIZE 20 + enum xpt2046_filter { XPT2046_FILTER_OK, XPT2046_FILTER_REPEAT, @@ -44,6 +47,13 @@ struct xpt2046_platform_data { int gpio_pendown; /* the GPIO used to decide the pendown * state if get_pendown_state == NULL */ + char pendown_iomux_name[IOMUX_NAME_SIZE]; + int pendown_iomux_mode; + int touch_ad_top; + int touch_ad_bottom; + int touch_ad_left; + int touch_ad_right; + int touch_virtualkey_length; int (*get_pendown_state)(void); int (*filter_init) (struct xpt2046_platform_data *pdata, void **filter_data); diff --git a/drivers/input/touchscreen/xpt2046_ts_320X480.c b/drivers/input/touchscreen/xpt2046_ts_320X480.c index 565a8b0e73b2..e2628e211976 100755 --- a/drivers/input/touchscreen/xpt2046_ts_320X480.c +++ b/drivers/input/touchscreen/xpt2046_ts_320X480.c @@ -1,7 +1,7 @@ /* - * drivers/input/touchscreen/xpt2046_ts.c - driver for rk2818 spi xpt2046 device and console + * drivers/input/touchscreen/xpt2046_ts.c - driver for rk29 spi xpt2046 device and console * - * Copyright (C) 2010 ROCKCHIP, Inc. + * Copyright (C) 2011 ROCKCHIP, Inc. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and -- 2.34.1