事先声明:文章只是记录移植的过程,方便自己查阅。
mini2440开发板触摸屏为NEC的触摸屏,而FriendlyArm上提供的Android内核是针对统宝LCD的,因此需要对触摸屏的驱动进行修改。
1、触摸屏为什么需要校正?
在像素坐标和触摸坐标存在误差。
详细内容:http://sys.firnow.com/linux/x8002010n08m/27s90182549.html
2、具体的修改方法:(还未验证)
对比了统宝触摸屏和NEC触摸屏的器件手册,区别不大,因此最大的区别有可能在触摸屏坐标上(也可以认为是在触摸屏校正上)
通过对比Linux下的NEC触摸屏驱动和Android 下的TPO驱动,发现touch_timer_fire有些许不同。不同的地方在于:
Android中关于TPO驱动部分:
if (updown) {
if (count != 0) {
long tmp;
tmp = xp;
xp = yp;
yp = tmp;
xp >>= 2;
yp >>= 2;
xp = 0x3FF - xp;
spin_lock(&myTS_lock);
if(myTS[7]){
disX = ((myTS[0] * xp) + (myTS[1] * yp) + myTS[2]) / myTS[6];
disY = ((myTS[3] * xp) + (myTS[4] * yp) + myTS[5]) / myTS[6];
//printk(KERN_INFO "disX: %d, disY: %d/n", disX, disY);
disX = disX * 1024 / 240;
disY = disY * 1024 / 320;
}else{
disX = xp;
disY = yp;
}
spin_unlock(&myTS_lock);
if(disX < 0)
disX = 0;
else if(disX > 1023)
disX = 1023;
if(disY < 0)
disY = 0;
else if(disY > 1023)
disY = 1023;
//printk(KERN_INFO "X: %d, Y: %d/n", disX, disY);
input_report_abs(dev, ABS_X, disX);
input_report_abs(dev, ABS_Y, disY);
input_report_key(dev, BTN_TOUCH, 1);
input_report_abs(dev, ABS_PRESSURE, 1);
input_sync(dev);
}
xp = 0;
yp = 0;
count = 0;
iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
} else {
count = 0;
Linux中关于NEC触摸屏驱动部分
if (updown) {
if (ts.count != 0) {
long tmp;
tmp = ts.xp;
ts.xp = ts.yp;
ts.yp = tmp;
ts.xp >>= ts.shift;
ts.yp >>= ts.shift;
#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
{
struct timeval tv;
do_gettimeofday(&tv);
printk(DEBUG_LVL "T: d, X: ld, Y: ld/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;
对比后发现,Linux下的NEC驱动没有进行
disX = ((myTS[0] * xp) + (myTS[1] * yp) + myTS[2]) / myTS[6];
disY = ((myTS[3] * xp) + (myTS[4] * yp) + myTS[5]) / myTS[6];
的坐标转换,因此修改代码如下:
#define NEC_TOUCHSCREEN (0) //add by Roger
#define TPO_TOUCHSCREEN (1)
#define TOUCHSCREEN (NEC_TOUCHSCREEN)
if (updown) {
if (count != 0) {
long tmp;
tmp = xp;
xp = yp;
yp = tmp;
xp >>= 2;
yp >>= 2;
//edit by Roger
#if TOUCHSCREEN == TPO_TOUCHSCREEN
xp = 0x3FF - xp;
spin_lock(&myTS_lock);
if(myTS[7]){
disX = ((myTS[0] * xp) + (myTS[1] * yp) + myTS[2]) / myTS[6];
disY = ((myTS[3] * xp) + (myTS[4] * yp) + myTS[5]) / myTS[6];
//printk(KERN_INFO "disX: %d, disY: %d/n", disX, disY);
disX = disX * 1024 / 240;
disY = disY * 1024 / 320;
}else{
disX = xp;
disY = yp;
}
spin_unlock(&myTS_lock);
if(disX < 0)
disX = 0;
else if(disX > 1023)
disX = 1023;
if(disY < 0)
disY = 0;
else if(disY > 1023)
disY = 1023;
//printk(KERN_INFO "X: %d, Y: %d/n", disX, disY);
input_report_abs(dev, ABS_X, disX);
input_report_abs(dev, ABS_Y, disY);
#elif TOUCHSCREEN == NEC_TOUCHSCREEN
//edit by Roger
input_report_abs(dev, ABS_X, xp);
input_report_abs(dev, ABS_Y, yp);
#endif
input_report_key(dev, BTN_TOUCH, 1);
input_report_abs(dev, ABS_PRESSURE, 1);
input_sync(dev);
}
xp = 0;
yp = 0;
count = 0;
iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
} else {
count = 0;
1月11日修改:
经验证利用上述方法,触摸屏的响应仍然存在问题,上面的办法没有提供校正功能,因此不成功。具体的校正文章,看《【笔记】mini2440的触摸屏驱动移植(二)》,提供了解决方法。
参考资料:
1、s3c2440触摸屏驱动分析(关于oversampling_shift = 2):
http://blog.csdn.net/satanwxd/archive/2010/02/02/5279595.aspx
http://blog.csdn.net/satanwxd/archive/2010/02/02/5279981.aspx
2、s3c2410触摸屏驱动分析:http://blog.csdn.net/sfrysh/archive/2010/08/04/5787645.aspx