【笔记】mini2440触摸屏驱动移植

    技术2022-06-29  50

    事先声明:文章只是记录移植的过程,方便自己查阅。

    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


    最新回复(0)