觸摸屏驅動的移植
流程
注意:看框架圖
1.添加input.c組件
Device Drivers --->
Input device support --->
Generic input layer (needed for keyboard, mouse, ...)
2.添加evdev.c組件
Input device support -- - >
< * > Event interface
3.添加s3c2410_ts.c觸摸屏驅動
修改driver/input/touchscreen/Kconfig
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
配置內核選項
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
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
/*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
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
&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文件的,觸摸屏中斷服務程序中添加如下代碼
{
printk(KERN_INFO "%s():%d\n",__func__,__LINE__);
...
}
當點擊觸摸屏的時候,出現如下現象:
s3c_adc_start : failed to find adc //找不到ADC
問題解決:分析s3c_adc_start函數
if ( !adc) {
printk(KERN_ERR "%s: failed to find adc\n", __func__);
return -EINVAL;
}
搜索adc_dev
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文件
.name = "samsung-adc",
.id = - 1,
.num_resources = ARRAY_SIZE(s3c_adc_resource),
.resource = s3c_adc_resource,
};
解決方法:
{
.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 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)
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_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
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
- > 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庫
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
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\n");
vi plugins/input-raw.c +61
(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\n");
}
由上面的代碼可知,觸摸屏應該還要產生壓力事件
所以,我們應該修改觸摸屏驅動,
vi driver/input/touchsrceen/s3c2410_ts.c
{
...
...
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)