zoukankan      html  css  js  c++  java
  • 【Linux高级驱动】触摸屏驱动的移植

    触摸屏驱动的移植

    流程

    注意:看框架图

    1.添加input.c组件

    Device Drivers  --->
     Input device support  --->
      Generic input layer (needed for keyboard, mouse, ...)

    2.添加evdev.c组件

    Device Drivers  --->
     Input device support  --->
      <*>   Event interface

    3.添加s3c2410_ts.c触摸屏驱动

        修改driver/input/touchscreen/Kconfig

    config TOUCHSCREEN_S3C2410
             tristate "Samsung S3C2410/generic touchscreen input driver"
             depends on ARCH_S3C2410 || SAMSUNG_DEV_TS || ARCH_S5PC100  //后面的ARCH_S5PC100为新添加的
             select S3C_ADC
             help
               Say Y here if you have the s3c2410 touchscreen.
               If unsure, say N.To compile this driver as a module, choose M here: the
               module will be called s3c2410_ts

        配置内核选项

    Device Drivers--->
     Input device support  --->
       -*- Generic input layer (needed for keyboard, mouse, ...)
       [*] Touchscreens  --->
            <*>Samsung S3C2410/generic touchscreen input driver

    4.添加设备资源(dev-ts.c)

        vi arch/arm/mach-s5pc100/Kconfig

    config MACH_SMDKC100
              bool "SMDKC100"
              select CPU_S5PC100
              select S3C_DEV_FB
              select S3C_DEV_I2C1
              select S3C_DEV_HSMMC
              select S3C_DEV_HSMMC1
             select S3C_DEV_HSMMC2
              select S5PC100_SETUP_FB_24BPP
              select S5PC100_SETUP_I2C1
              select S5PC100_SETUP_SDHCI
              select S3C_DEV_LED
              select S3C_DEV_RTC
             select SAMSUNG_DEV_TS    //添加的内容
            help
               Machine support for the Samsung SMDKC100

        vi arch/arm/mach-s5pc100/mach-smdkc100.c

    #include<plat/ts.h>
    /*ts*/
    struct s3c2410_ts_mach_info s5pc_tscfg ={
     .delay =200000,
     .oversampling_shift =2,
    };
    static struct platform_device *smdkc100_devices[] __initdata = {
             &s3c_device_i2c0,
             &s3c_device_i2c1,
             &s3c_device_fb,
             &s3c_device_hsmmc0,
             &s3c_device_hsmmc1,
             &s3c_device_hsmmc2,
             &smdkc100_lcd_powerdev,
             &s5pc100_device_iis0,
             &s5pc100_device_ac97,
     
     #ifdef  CONFIG_DM9000
             &s5pc100_device_dm9000,
     #endif
     
      &fsled_device,
             &s3c_device_rtc,
             &s3c_device_ts,    //添加的内容
     };
     
    static void __init smdkc100_machine_init(void)
    {
     ...
     s3c24xx_ts_set_platdata(&s5pc_tscfg);     //s3c_device_ts.dev.platform_data =&s5pc_tscfg 
     ...
    }

    5.修改头文件

        vi arch/arm/mach-s5pc100/include/mach/map.h

    6.添加adc资源(dev-adc.c)

        vi arch/arm/mach-s5pc100/Kconfig

    config MACH_SMDKC100
              bool "SMDKC100"
              select CPU_S5PC100
              select S3C_DEV_FB
              select S3C_DEV_I2C1
              select S3C_DEV_HSMMC
              select S3C_DEV_HSMMC1
       select S3C_DEV_HSMMC2
              select S5PC100_SETUP_FB_24BPP
              select S5PC100_SETUP_I2C1
              select S5PC100_SETUP_SDHCI
              select S3C_DEV_LED
              select S3C_DEV_RTC
       select SAMSUNG_DEV_TS    
        select SAMSUNG_DEV_ADC //添加的内容
            help
               Machine support for the Samsung SMDKC100

        vi arch/arm/mach-s5pc100/mach-smdkc100.c

    static struct platform_device *smdkc100_devices[] __initdata = {
             &s3c_device_i2c0,
             &s3c_device_i2c1,
             &s3c_device_fb,
             &s3c_device_hsmmc0,
             &s3c_device_hsmmc1,
             &s3c_device_hsmmc2,
             &smdkc100_lcd_powerdev,
             &s5pc100_device_iis0,
             &s5pc100_device_ac97,
     
     #ifdef  CONFIG_DM9000
             &s5pc100_device_dm9000,
     #endif
     
       &fsled_device,
             &s3c_device_rtc,
             &s3c_device_ts,    
       &s3c_device_adc //添加的内容 
     };

    测试方式

    测试方法1.驱动调试

        在触摸屏驱动中s3c2410_ts.c文件的,触摸屏中断服务程序中添加如下代码

    static irqreturn_t stylus_irq(int irq, void *dev_id)
    {
     printk(KERN_INFO "%s():%d ",__func__,__LINE__);
     ...
    }

        当点击触摸屏的时候,出现如下现象:

    stylus_irq():164
    s3c_adc_start: failed to find adc  //找不到ADC

        问题解决:分析s3c_adc_start函数

    struct adc_device *adc = adc_dev;  //说明adc_dev为空
    if (!adc) {
     printk(KERN_ERR "%s: failed to find adc ", __func__);
     return -EINVAL;
    }

        搜索adc_dev

    int s3c_adc_probe(struct platform_device *pdev)   //由此可见,probe函数没执行,猜测,匹配不成功
     adc_dev = adc;
    static struct platform_device_id s3c_adc_driver_ids[] = {
     {
      .name           = "s3c24xx-adc",
      .driver_data    = TYPE_S3C24XX,
     },{
      .name           = "s3c64xx-adc",
      .driver_data    = TYPE_S3C64XX,
     },
     { }
    };
    static struct platform_driver s3c_adc_driver = {
     .id_table = s3c_adc_driver_ids,   //按id.name匹配
     .driver  = {
      .name = "s3c-adc",
      .owner = THIS_MODULE,
     },
     .probe  = s3c_adc_probe,
     .remove  = __devexit_p(s3c_adc_remove),
     .suspend = s3c_adc_suspend,
     .resume  = s3c_adc_resume,
    };

        但是在dev-adc.c文件

    struct platform_device s3c_device_adc = {
     .name  = "samsung-adc",
     .id  = -1,
     .num_resources = ARRAY_SIZE(s3c_adc_resource),
     .resource = s3c_adc_resource,
    };

        解决方法:

    static struct platform_device_id s3c_adc_driver_ids[] = {
     {
      .name           = "s3c24xx-adc",
      .driver_data    = TYPE_S3C24XX,
     },{
      .name           = "s3c64xx-adc",
      .driver_data    = TYPE_S3C64XX,
     },{
      .name           = "samsung-adc",
      .driver_data    = TYPE_S3C64XX,
     },
     { }
    };

     

    测试方法2:移植tslib库:校准程序

    2.1 tslib库的移植

        1.拷贝tslib-1.4.tar.gz到ubutun的工作目录,如/home/jason/project

        2.解压缩
            tar -xvf tslib-1.4.tar.gz

        3.配置

     sudo apt-get install autoconf
     sudo apt-get install libtool
     cd tslib
     ./autogen.sh
     mkdir tmp
     echo "ac_cv_func_mallo_0_nonnull=yes">arm-unknown-linux-gnueabi.cache
     ./configure --host=arm-unknown-linux-gnueabi --prefix=$(pwd)/tmp --cache-file=arm-unknown-linux-gnueabi.cache

        4.编译(make)

    make的时候会出现如下错误:
     ts_test.c:(.text+0x1e4): undefined reference to `rpl_malloc'
     解决方法:将config.h.in里的 #undef malloc屏蔽掉  

        5.安装
          
    make install

        6.cd tmp 
          cp * /opt/rootfs 

        7.cd /opt/rootfs/lib
          mkdir ts

        8.cp tslib/plugins  /opt/wlwfs/lib/ts

        9.修改/opt/wlwfs/etc/ts.conf第一行(去掉#号和第一个空格)
          #module_raw input
          改为
          module_raw input

        10.修改etc/profile文件
          vi  etc/profile
          在其中添加如下代码

    export TSLIB_TSDEVICE=/dev/event0   
    export TSLIB_CALIBFILE=/etc/pointercal
    export TSLIB_CONFFILE=/etc/ts.conf
    export TSLIB_PLUGINDIR=/lib/ts
    export TSLIB_CONSOLEDEVICE=/dev/tty
    export TSLIB_FBDEVICE=/dev/fb0    //lcd   

        记得执行:
            source etc/profile

    2.2 移植LCD驱动

        vi linux-2.6.35.5/driver/video/Kconfig

    config FB_S3C
             tristate "Samsung S3C framebuffer support"
             depends on FB && (ARCH_S3C64XX || ARCH_S5PC100(新添加的))
             select FB_CFB_FILLRECT
             select FB_CFB_COPYAREA
             select FB_CFB_IMAGEBLIT
             ---help---
               Frame buffer driver for the built-in FB controller in the Samsung
               SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
               and the S3C64XX series such as the S3C6400 and S3C6410.
               These chips all have the same basic framebuffer design with the
               actual capabilities depending on the chip. For instance the S3C6400
               and S3C6410 support 4 hardware windows whereas the S3C24XX series
               currently only have two.
               Currently the support is only for the S3C6400 and S3C6410 SoCs.

        make menuconfig

    Location:                                                                                               x
          -> Device Drivers                                                                                     x
             -> Graphics support                                                                                 x
               <*> Support for frame buffer devices  --->
       <*>   Samsung S3C framebuffer support   //配置LCD的驱动
         Console display driver support  --->
       <*> Framebuffer Console support
         [*] Bootup logo  --->    //系统中的默认logo 
      [*]   Standard 224-color Linux logo (NEW)

        编译内核:
            make zImage

    2.3 运行tslib库

    ts_calibrate    //在LCD上出现一个点
    xres = 800, yres = 480   //现象
    selected device is not a touchscreen I understand

        问题1:屏幕大小不对(480*272)
        问题2:tslib库认为我们的设备不是触摸屏设备

    解决问题1:

        修改大小 
        vi arch/arm/mach_s5pc100/mach_smdkc100.c

    /* Frame Buffer */
    static struct s3c_fb_pd_win smdkc100_fb_win0 = {
             /* this is to ensure we use win0 */
             .win_mode       = {
                     .pixclock = 1000000000000ULL / ((8+13+3+800)*(7+5+1+480)*80),
                     .left_margin    = 8,
                     .right_margin   = 13,
                     .upper_margin   = 7,
                     .lower_margin   = 5,
                     .hsync_len      = 3,
                     .vsync_len      = 1,
                     .xres           = 800,  //480
                     .yres           = 480,  //272
             },
             .max_bpp        = 32,
             .default_bpp    = 16,
    };
    解决问题2:

        到tslib库里面,搜索selected device is not a touchscreen I understand看它怎么样认为才是一个触摸屏设备

        plugins/input-raw.c:61:         fprintf(stderr, "selected device is not a touchscreen I understand ");
        
    vi plugins/input-raw.c +61

    if (! ((ioctl(ts->fd, EVIOCGVERSION, &version) >= 0) &&
                      (version == EV_VERSION) &&
                      (ioctl(ts->fd, EVIOCGBIT(0, sizeof(bit) * 8), &bit) >= 0) &&
                      (bit & (1 << EV_ABS)) &&
                      (ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit) * 8), &absbit) >= 0) &&
                      (absbit & (1 << ABS_X)) &&
                      (absbit & (1 << ABS_Y)) && (absbit & (1 << ABS_PRESSURE)))) {
                      fprintf(stderr, "selected device is not a touchscreen I understand ");
              }

        由上面的代码可知,触摸屏应该还要产生压力事件
        所以,我们应该修改触摸屏驱动,
        vi driver/input/touchsrceen/s3c2410_ts.c

    static int __devinit s3c2410ts_probe(struct platform_device *pdev)
    {
     ...
     ...
     input_set_abs_params(ts.input, ABS_X, 0, 480, 0, 0);
     input_set_abs_params(ts.input, ABS_Y, 0, 272, 0, 0);
     input_set_abs_params(ts.input, ABS_PRESSURE, 0, 1, 0, 0);   //新添加的
     ...
     ...
    }
    static void touch_timer_fire(unsigned long data)
    {
     ...
     ...
     input_report_abs(ts.input, ABS_X, ts.xp);
     input_report_abs(ts.input, ABS_Y, ts.yp);
     input_report_abs(ts.input, ABS_PRESSURE, 1); //添加的代码
     input_report_key(ts.input, BTN_TOUCH, 1);
     input_sync(ts.input);
     ...
     ...
    }else{
     ...
     input_report_abs(ts.input, ABS_PRESSURE, 0); //添加的代码
     input_report_key(ts.input, BTN_TOUCH, 0);
     input_sync(ts.input);
     ...
    }

    2.4 再次运行tslib库

        ts_calibrate   //需要分别点击5次
        ts_test

    @成鹏致远

    (blogs:http://lcw.cnblogs.com

    (email:wwwlllll@126.com)

    (qq:552158509





  • 相关阅读:
    解决 iOS View Controller Push/Pop 时的黑影
    AFN发送请求失败
    cocoapods安装失败
    cocoapods 更新失败 bad response Not Found 404 (http://ruby.taobao.org/specs.4.8.gz)
    iOS开发: 向右滑动手势功能实现
    虚拟器运行iOS8地图提示错误
    unexpected nil window in _UIApplicationHandleEventFromQueueEvent...
    控制控制器只支持横/竖屏
    UIWebView执行JS语句
    Warning: Attempt to present * on * which is already presenting *
  • 原文地址:https://www.cnblogs.com/lcw/p/3802624.html
Copyright © 2011-2022 走看看