本移植是先从 Ben Dooks 的网站上下载了部分代码,同时在网下载了一个2410的
touch screen 驱动程序,做了简单修改完成的.这个简单的触摸屏驱动程序还不是
很完善,还需要改进.
简单触摸屏驱动移植过程如下:
一. 如果你的kernel里面没有 reg-adc.h 则需要到 Ben Dooks 的网站下载相关补丁
文件位置在 include/asm-arm/arch-s3c2410/regs-adc.h, 并在其添加如下内容
#define S3C2410_ADCTSC_XY_PST_N (0x0<<0)
#define S3C2410_ADCTSC_XY_PST_X (0x1<<0)
#define S3C2410_ADCTSC_XY_PST_Y (0x2<<0)
#define S3C2410_ADCTSC_XY_PST_W (0x3<<0)
二.将下载的2410的驱动程序代码复制到 drivers/input/touchscreen/ 下名为
s3c2440_ts.c .
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch/regs-adc.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/s3c2440_ts.h>
//#include <asm/hardware/clock.h>
#include <asm/arch/regs-clock.h>
#include <linux/clk.h>
/* For ts.dev.id.version */
#define S3C2440TSVERSION 0x0101
#define WAIT4INT(x) (((x)<<8) | \
S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
S3C2410_ADCTSC_XY_PST_W)
#define AUTOPST (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST_N)
#define DEBUG_LVL KERN_INFO
#ifdef CONFIG_TOUCHSCREEN_S3C2440_DEBUG
#define DBG(x...) printk(KERN_INFO x)
#else
#define DBG(x...) do { } while (0)
#endif
/*
* Definitions & global arrays.
*/
static char *s3c2440ts_name = "s3c2440 TouchScreen";
/*
* Per-touchscreen data.
*/
struct s3c2440ts {
struct input_dev *dev;
long xp;
long yp;
int count;
int shift;
char phys[32];
};
static struct s3c2440ts ts;
static void __iomem *base_addr;
static void touch_timer_fire(unsigned long data)
{
unsigned long data0;
unsigned long data1;
int updown;
data0 = readl(base_addr+S3C2410_ADCDAT0);
data1 = readl(base_addr+S3C2410_ADCDAT1);
updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
DBG(" data0 = %x, data1 = %x updown = %d %s : %s : line = %d\n", data0, data1, updown,
__FUNCTION__, __FILE__, __LINE__);
if (updown) {
if (ts.count != 0) {
ts.xp >>= ts.shift;
ts.yp >>= ts.shift;
#ifdef CONFIG_TOUCHSCREEN_S3C2440_DEBUG
{
struct timeval tv;
do_gettimeofday(&tv);
printk(DEBUG_LVL "T: %06d, X: %03ld, Y: %03ld\n", (int)tv.tv_usec, ts.xp, ts.yp);
}
#endif
input_report_abs(ts.dev, ABS_X, ts.xp);
input_report_abs(ts.dev, ABS_Y, ts.yp);
input_report_key(ts.dev, BTN_TOUCH, 1);
input_report_abs(ts.dev, ABS_PRESSURE, 1);
input_sync(ts.dev);
}
ts.xp = 0;
ts.yp = 0;
ts.count = 0;
writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
} else {
ts.count = 0;
input_report_key(ts.dev, BTN_TOUCH, 0);
input_report_abs(ts.dev, ABS_PRESSURE, 0);
input_sync(ts.dev);
writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
}
}
