触摸屏驱动的移植

流程

注意:看框架图

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

#,
 .oversampling_shift ,
};
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\n",__func__,__LINE__);
 ...
}

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

stylus_irq()
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\n", __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文件

,
 .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 hardware windows whereas the S3C24XX series
           currently only have two.
           Currently the support is only for the S3C6400 and S3C6410 SoCs.

make menuconfig

Location-color Linux logo (NEW)

编译内核:
        make zImage

2.3 运行tslib库

ts_calibrate    , yres    //现象
selected device is not a touchscreen I understand

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

解决问题1:

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

))),
                 .left_margin    ,
                 .right_margin   ,
                 .upper_margin   ,
                 .lower_margin   ,
                 .hsync_len      ,
                 .vsync_len      ,
                 .xres           ,  
                 .yres           ,  
         },
         .max_bpp        ,
         .default_bpp    ,
};
解决问题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\n");
    vi plugins/input-raw.c +61

) , sizeof(bit) ), ) ), ) << ABS_PRESSURE)))) {
                  fprintf(stderr, "selected device is not a touchscreen I understand\n");
          }

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

static int __devinit s3c2410ts_probe(struct platform_device , , , );
 input_set_abs_params(ts.input, ABS_Y, , , , );
 input_set_abs_params(ts.input, ABS_PRESSURE, , , , );   ); );
 input_sync(ts.input);
 ...
 ...
}); );
 input_sync(ts.input);
 ...
}

2.4 再次运行tslib库

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

@成鹏致远

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

(email:[email protected]

(qq:552158509)

05-11 17:15