mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
migrate touch screen driver xpt2046
This commit is contained in:
@@ -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,10 +54,20 @@
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#include "devices.h"
|
||||
#include "../../../drivers/input/touchscreen/xpt2046_cbn_ts.h"
|
||||
#include "../../../drivers/misc/gps/rk29_gps.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"
|
||||
#endif
|
||||
|
||||
#include "../../../drivers/misc/gps/rk29_gps.h"
|
||||
|
||||
/* Set memory size of pmem */
|
||||
#ifdef CONFIG_RK29_MEM_SIZE_M
|
||||
#define SDRAM_SIZE (CONFIG_RK29_MEM_SIZE_M * SZ_1M)
|
||||
@@ -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 = 320,
|
||||
.x_max = 480,
|
||||
.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,
|
||||
};
|
||||
#elif defined(CONFIG_TOUCHSCREEN_XPT2046_SPI)
|
||||
static struct xpt2046_platform_data xpt2046_info = {
|
||||
.model = 2046,
|
||||
.keep_vref_on = 1,
|
||||
.swap_xy = 1,
|
||||
.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,
|
||||
.debounce_max = 7,
|
||||
.debounce_rep = DEBOUNCE_REPTIME,
|
||||
.debounce_tol = 20,
|
||||
.gpio_pendown = XPT2046_GPIO_INT,
|
||||
|
||||
.penirq_recheck_delay_usecs = 1,
|
||||
.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,
|
||||
.touch_ad_top = 3166,
|
||||
.touch_ad_bottom = 256,
|
||||
.touch_ad_left = 3658,
|
||||
.touch_ad_right = 380,
|
||||
#endif
|
||||
};
|
||||
#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,
|
||||
|
||||
#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,
|
||||
.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,
|
||||
|
||||
@@ -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_NOCHOOSE
|
||||
bool "DO NOT CHOOSE TOUCHSCREEN_XPT2046"
|
||||
|
||||
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_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
|
||||
config TOUCHSCREEN_XPT2046_SPI
|
||||
tristate "XPT2046 based touchscreens:SPI Interface"
|
||||
depends on SPIM_RK29
|
||||
|
||||
endchoice
|
||||
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
|
||||
# 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_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_ADS7846
|
||||
tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
|
||||
depends on SPI_MASTER
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
2
drivers/input/touchscreen/calibration_ts.c
Normal file → Executable file
2
drivers/input/touchscreen/calibration_ts.c
Normal file → Executable file
@@ -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<FILTER_BUF_LEN)
|
||||
ret=TS_ERR_LOWBUF;
|
||||
|
||||
2
drivers/input/touchscreen/calibration_ts.h
Normal file → Executable file
2
drivers/input/touchscreen/calibration_ts.h
Normal file → Executable file
@@ -54,4 +54,6 @@ TouchPanelCalibrateAPoint(
|
||||
int *pCalY //@PARM The calibrated Y coordinate
|
||||
);
|
||||
|
||||
int tp_calib_iface_init(int *x,int *y,int *uncali_x, int *uncali_y);
|
||||
void tp_calib_iface_exit(void);
|
||||
#endif
|
||||
|
||||
0
drivers/input/touchscreen/largenum_ts.c
Normal file → Executable file
0
drivers/input/touchscreen/largenum_ts.c
Normal file → Executable file
6
drivers/input/touchscreen/largenum_ts.h
Normal file → Executable file
6
drivers/input/touchscreen/largenum_ts.h
Normal file → Executable file
@@ -13,8 +13,8 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_TOUCHSCREEN_LARGENUM_TS_H
|
||||
#define __DRIVERS_TOUCHSCREEN_LARGENUM_TS_H
|
||||
#ifndef LARGENUM_TS_H
|
||||
#define LARGENUM_TS_H
|
||||
|
||||
#define SIZE_OF_LARGENUM 3
|
||||
|
||||
@@ -149,4 +149,4 @@ LargeNumBits(
|
||||
PLARGENUM pNum
|
||||
);
|
||||
|
||||
#endif
|
||||
#endif /* LARGENUM_TS_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* drivers/input/touchscreen/xpt2046_cbn_ts.c - driver for rk2818 spi xpt2046 calibration 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 <linux/gpio.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <mach/iomux.h>
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
#include <linux/earlysuspend.h>
|
||||
#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;
|
||||
|
||||
|
||||
static void xpt2046_enable(struct xpt2046 *ts);
|
||||
static void xpt2046_disable(struct xpt2046 *ts);
|
||||
|
||||
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;
|
||||
|
||||
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");
|
||||
|
||||
10
drivers/input/touchscreen/xpt2046_cbn_ts.h
Normal file → Executable file
10
drivers/input/touchscreen/xpt2046_cbn_ts.h
Normal file → Executable file
@@ -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);
|
||||
|
||||
@@ -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 <linux/gpio.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <mach/iomux.h>
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
#include <linux/earlysuspend.h>
|
||||
#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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user