搜档网
当前位置:搜档网 › 触摸屏和lcd驱动所遇问题及解决

触摸屏和lcd驱动所遇问题及解决

2009-08-08 19:55 由于进来搞这东西的时间不是很多,一个触摸屏驱动居然托两个星期,今天总是有点眉目了, 虽然还没完全弄懂其中的道理, 但总算是好用了.先把移植过程写一下,还是以引用网上现有的移植方法为主, 再结合我自己遇到的问题进行修改和补充:

到网上下载s3c2410_ts.c和s3c2410_ts.h两个文件.

复制s3c2410_ts.c到linux2.6.20/drivers/input/touchscreen 目录下
以及复制s3c2410_ts.h到linux2.6.14/include/asm-arm/arch-s3c2410目录下

-------------------修改Makefile------------------
修改 linux2.6.20/drivers/input/touchscreen 目录下的 makefile

在最后添加:obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o

------------------修改Konfig--------------------
修改 linux2.6.20/ drivers/input/touchscreen/Kconfig

config TOUCHSCREEN_S3C2410
tristate "Samsung S3C2410 touchscreen input driver"
depends on ARCH_S3C2410 && INPUT && INPUT_TOUCHSCREEN
select SERIO
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.

config TOUCHSCREEN_S3C2410_DEBUG
boolean "Samsung S3C2410 touchscreen debug messages"
depends on TOUCHSCREEN_S3C2410
help
Select this if you want debug messages

--------------配置内核---------------
Device drivers –>
Input device support –>
[*]Touchscreen interface
(240) Horizontal screen resolution
(320) Vertical screen resolution
[*]Event interface
[*]Event debugging
如果不加几项的话会的一些让人很难以理解的问题出现:(见最后)
Touchscreens –>
[*]Samsung S3C2410 touchscreen input driver
[*]Samsung s3c2410 touchscreen debug message
---------------- --------------------------------------------------------
在 /linux-2.6.20/arch/arm/mach-s3c2410/mach-smdk2410.c, 中增加如下内容:
#include
#include
static struct s3c2410_ts_mach_info sbc2410_ts_cfg __initdata = {
.delay = 10000,
.presc = 49,
.oversampling_shift = 2,
};
在smdk2410_devices结构中,添加:
&s3c_device_ts,
在smdk2410_map_io函数中添加:
set_s3c2410ts_info(&sbc2410_ts_cfg);
-------------------------- ----------------------
在 /linux-2.6.20/ arch/arm/mach-s3c2410/devs.h 文件中添加:
extern struct platform_device s3c_device_ts;

-----------------------------------------------
在arch/arm/mach-s3c2410/devs.c文件中添加如下几行:
/*for s3c2410 touchscreen*/
#include
/* Touchscreen */
static struct s3c2410_ts_mach_info s3c2410ts_info;

void __init set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info){
memcpy(&s3c2410ts_info,hard_s3c2410ts_info,sizeof(struct s3c2410_ts_mach_info));
}
EXPORT_SYMBOL(set_s3c2410ts_info);

struct platform_device s3c_device_ts = {
.name =

"s3c2410-ts",
.id = -1,
.dev = {
.platform_data = &s3c2410ts_info,
}
};
EXPORT_SYMBOL(s3c_device_ts);
------------------------------------------------------------------
修改include/asm-arm/arch-s3c2410/regs-adc.h
#define S3C2410_ADCTSC_XY_PST (0×3<<0)改为define S3C2410_ADCTSC_XY_PST(x) (((x)&0×3)<<0)

-------------------------------------------------------------------
编译下载内核
启动内核是时出现相关启动信息:
s3c2410 TouchScreen successfully loaded
input: s3c2410 TouchScreen as /class/input/input0

启动后执行:
/ $ cat /proc/bus/input/devices
输出以下信息:
I: Bus=0013 Vendor=dead Product=beef Version=0101
N: Name="s3c2410 TouchScreen"
P: Phys=
S: Sysfs=/class/input/input0
H: Handlers=event0 ts0 evbug
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0
B: ABS=1000003


-------------------------------------------------------------------
出现的问题:
内核启动后/dev/下没有触摸屏驱动的相应节点,设备无法起用.
解决办法:
手动添加相应节点,如下
\$ mkdir /dev/input
\$ mknod /dev/input/ts0 c 13 64 注: 13 64为主次设备号,从网上直接copy过来的,目前还不知道如何获取

--------------------------------------------------------------------
测试(驱动程序中已被添加了测试代码):

\$ cat /dev/ts0 然后触摸屏幕,打印出来的是乱码。
改变printk 打印级别
echo 8 > /proc/sys/kernel/printk
打印所有内核信息,再触摸,有坐标显示了。


注: 如果配置内核时不加入如下配置:
[*]Event interface
[*]Event debugging

手动添加节点/dev/input/ts0 c 13 64后,节点无效,表现为用cat /dev/ts0测试时输出信息为"没有该设备".


ARM-LINUX]移植2.6.31.12内核到立宇泰ARMSYS2440开发板之LCD驱动+触摸屏驱动
分类: Arm 2010-03-04 09:24 504人阅读 评论(0) 收藏 举报
移植完内核和网卡驱动后,下一步就是移植LCD驱动和触摸屏驱动,使我们的tft屏亮起来。



注意:文件系统因为是只读的,因此设备节点一律需要手动添加,包括console、null、lcd的fb、ts等。



7. LCD驱动移植

LCD驱动我们采取了两种方法来移植,每一种方法都可以。一种是移植开发板自带内核中的LCD驱动,另一种就是修改新内核中的LCD驱动。在这里我们分别列出:

1). 移植开发板自带内核中的LCD驱动

将板子自带的驱动s3c2410fb.c和.h文件拷备到新内核的drivers/video/目录下,替换原来的文件。

修改s3c2410fb.c: 主要是修改头文件引用,因为两个内核之间的目录结构有差异。如:

新内核 旧内核

无 #include

#i

nclude #include

#include #include

#include #include
#include #include
修改arch/arm/mach-s3c2410/mach-smdk2410.c,增加LCD相关的map:

static struct map_desc smdk2410_iodesc[] __initdata = {
/* nothing here yet */
{vSMDK2410_ETH_IO,pSMDK2410_ETH_IO,SZ_1M,MT_DEVICE}, // 8900 zhangw
IODESC_ENT(LCD), // zhangw
IODESC_ENT(GPIO), // zhangw
IODESC_ENT(DMA), // zhangw
IODESC_ENT(IRQ), // zhangw
};

修改后,注意map.h中添加S3C24XX_VA_LCD等的定义,编译内核,烧到板子上启动;

启动后会出现访问空指针的问题,经查看,是regs-lcd.h中的S3C2410_LCDREG(x)的定义不同造成的,参照原有内核中的进行修改。

因为我们的内核是只读的cramfs,而新内核虽然是配置了devfs支持,但因为没有源码支持,因此devfs还是无效,因此要保证/dev下有framebuffer的节点fb0,若没有,用mknod命令在文件系统中添加,然后重新烧写文件系统,最好是把你可能用到的所有设备节点都建好备用,建节点属性可以参考原有内核中的设备节点属性。



板子启动后,发现文字和图像是左右反着的,左右互换了,从网上查,参考了"S3C2410下LCD驱动程序移植及GUI程序编写.pdf",以为是参数问题,修改参数无效。最后发现是LCD屏硬件连接不牢,导致屏幕显示不稳定,唉,准备工作没做足啊!

检查了LCD硬件连接没问题后,LCD显示正常了。



2). 修改新内核中的LCD驱动

新内核的LCD驱动修改更简单一些,主要就是mach信息的修改。

原有内核驱动中的mach信息为:

struct pxafb_mach_info S3C2410_800X480_info = {
.pixclock = 174757,
.xres = 800,
.yres = 480,
.bpp = 16,
.hsync_len = 95,
.left_margin = 14,
.right_margin = 46,
.vsync_len = 1,
.upper_margin = 10,
.lower_margin = 31,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.cmap_greyscale = 0,
.cmap_inverse = 0,
.cmap_static = 0,
.reg = {
lcdcon1 : (1<<8)|(1<<7)|(3<<5)|(12<<1),
lcdcon2 : (31<<24)|(479<<14)|(

10<<6)|1,
lcdcon3 : (39<<19)|(799<<8)|23,
lcdcon4 : (13<<8)|95,
lcdcon5 : (1<<11)|(1<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(1<<3)|1,
}
};

lcdcon1~5的值有对应的宏可以查看,位置:arch/arm/mach-s3c2410/include/mach/regs-lcd.h

修改arch/arm/mach-s3c2410/mach-smdk2410.c:

/* LCD driver info */

static struct s3c2410fb_display s3c2410_lcd_cfg[] __initdata = {

{
/* Config for 800X480 LCD */
.lcdcon5 = (1<<11)|(1<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(1<<3)|1,
.type = S3C2410_LCDCON1_TFT,
.pixclock = 174757,
.xres = 800,
.yres = 480,
.bpp = 16,
.hsync_len = 95,
.left_margin = 14,
.right_margin = 46,
.vsync_len = 1,
.upper_margin = 10,
.lower_margin = 31,
},
};

static struct s3c2410fb_mach_info s3c2410_fb_info __initdata = {
.displays = s3c2410_lcd_cfg,
.num_displays = ARRAY_SIZE(s3c2410_lcd_cfg),
.default_display = 0,

.lpcsel = ((0xCE6) & ~7) | 1<<4,

};



在smdk2410_init()函数中添加s3c24xx_fb_set_platdata(&s3c2410_fb_info);



编译内核即可,当然这里还没有小企鹅,可以参照原有内核的方法添加,启动后就会有小企鹅了。



8. 触摸屏驱动移植

触摸屏驱动移植主要是将原有内核中的驱动拿过来进行修改。

1). 配置dev和mach信息:

修改devs.c: 增加ts设备定义

/* Touchscreen */
static struct s3c2410_ts_mach_info s3c2410ts_info;

void __init set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
{
memcpy(&s3c2410ts_info,hard_s3c2410ts_info,sizeof(struct s3c2410_ts_mach_info));
}
EXPORT_SYMBOL(set_s3c2410ts_info);

struct platform_device s3c_device_ts = {
.name = "s3c2410-ts",
.id = -1,
.dev = {
.platform_data = &s3c2410ts_info,
}
};
EXPORT_SYMBOL(s3c_device_ts);

修改devs.h:增加ts设备声明

extern struct platform_device s3c_device_ts;

修改mach-smdk2410.c:增加ts设备的mach信息

static struct s3c2410

_ts_mach_info smdk2410_ts_cfg __initdata = {

.delay = 10000,

.presc = 49,

.oversampling_shift = 2,

};

static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_rtc,
&s3c_device_ts,
};

static void __init smdk2410_init(void)
{
s3c_i2c0_set_platdata(NULL);
s3c24xx_fb_set_platdata(&s3c2410_fb_info);
set_s3c2410ts_info(&smdk2410_ts_cfg);
platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
smdk_machine_init();
}


2). 增加ts内核驱动配置及源码

将s3c2410ts.c拷备到新内核arch/arm/mach-s3c2410/include/mach/目录下,s3c2410ts.h拷到arch/arm/mach-s3c2410/include/mach/目录下。

修改arch/arm/mach-s3c2410/include/mach/目录下Kconfig,增加:

choice
prompt "S3C2410 touchscreen driver"
default S3C2410_TS
depends on ARCH_S3C2410

config S3C2410_TS
tristate "touchscreen added by zhangw"

endchoice

修改arch/arm/mach-s3c2410/include/mach/目录下Makefile,增加:

obj-$(CONFIG_S3C2410_TS) += s3c2410ts.o

修改s3c2410ts.c:

头文件引用修改:蓝色部分是修改的

//zhangw #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//zhangw #include

#include
#include
#include

#include

#include

添加宏定义:

#define SA_INTERRUPT IRQF_DISABLED

屏蔽宏:

#ifdef CONFIG_PM
#undef CONFIG_PM
#endif

#ifdef CONFIG_DEVFS_FS
#undef CONFIG_DEVFS_FS
#endif

屏蔽函数:

//clk_use(adc_clock);

修改后,编译内核,烧写内核。启动后触摸屏可用。

selected device is not a touchscreen I understand
对linux3.2.5源码移植了nandflash,LCD,yaffs2,DM9000,touchscreen,RTC,WatchDog,鼠标驱动。并用测试程序进行了驱动测试。基本都和移植2.6.30差不多。主要遇到1个问题,比较费时。执行ts_calibration触摸无反应。解决方法如下:

1,selected device is not a touchscreen I understand
想去找源码,没找到。(后来知道,我是有源码的。)
2,可能是配置问题。也没看到有什么错。probe是成功了。
3,看到一句信息。
input_polldev: version magic '2.6.30.4-EmbedSky mod_unload ARMv4 ' should be '3.2.5apple2.0 mod_unload ARMv4 p2v8 '
insmod: can't insert '/lib/input-polldev.ko': invalid module format
怀疑input-polldev.ko没有加载出错。于是在kenrel中,发现根本没选择该项,于是选成y,加载到kernel中。然后在文件系统中删除ismod input-polldev.ko。
4,结果还是不行。于是用原本的kernel,发现input-polldev.ko模块不加载也没问题,触摸屏照用。于是只能把问题集中到“selected device is not a touchscreen I understand”
去看tslib中的源码。发现问题出在input_raw.c文件中。找到了线索。

arm交叉编译工具中的头文件库中的linux/input.h中的EV_VERSION定义为
#define EV_VERSION 0x010000
而linux内核include/linux/input.h中的EV_VERSION定义为
#define EV_VERSION 0x010001
由此可见问题就出现在内核的输入子系统的版本号不匹配的问题

解决办法:
1.将内核源代码里的include/linux/input.h中的
#define EV_VERSION 0x010001
改为:
#define EV_VERSION 0x010000
在友善的6410开发板上,友善已经将TSLIB移好了,但是不提供TSLIB的源代码,我需要自己
移植一下TSLIB,但是一直没有移植成功,在这里请教各位高手:

具体移植步骤如下:

一:下载TSLIB1.4版本解压,通过如下方式配置:
./configure --divfix=/usr/local/lib/ --host=arm-none-linux-gnueabi ac_cv_func_malloc_0_nonnull=yes
make
make install

二:修改etc下的ts.conf为下面内容:
module_raw input
module_raw h3600
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear

三:将安装目录下的bin,etc,include,lib四个文件夹打包,

将打包的文件
拷备到开发板的文件系统,解压到文件系统的/usr/local目录

四:修改开发板文件系统的/etc/profile文件,添加环境变量如下:
export TSLIB_ROOT=/usr/local
export LD_LIBRARY_PATH=/usr/local/lib
export TSLIB_TSDEVICE=/dev/touchscreen
export TSLIB_CONFFILE=/usr/local/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/local/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0

重启机器,进入TSLIB校屏界面,依次点五个点,发现点得非常的轻就有反应了,
很容易点一个点时被认为点了两个点,而且点完后在/etc下没有生成校准文件。

进入系统后执行/usr/local/bin下的ts_calibrate,ts_test文件都没有反应。
好像有时改得可以在这里校屏了,但是每次点下采样的值都是一样的,根本
无法校准。

我发现网上说TSLIB_TSDEVICE需要设置为/dev/touchscreen/下的某个文件,如
event0等,但是在我/dev下就只有一个touchscreen文件。

不知是什么原因造成的?为什么会无法校屏呢?

-----------------------------------------------------------------------
答案1:

补充:

将ts.conf里面的module_raw h3600屏掉后,进入校屏界面时触摸点它自动就晃
了一圈,然后就进入了QT的欢迎界面,点击触摸屏没有反应。进入/usr/local/
bin下执行./ts_calibrate,屏上有校准界面出来但是没有光标,终端打印如下
信息:
xres = 480, yres = 272
selected device is not a touchscreen I understand
Took 4 samples...
Top left : X = -9004812 Y = 1
Took 4 samples...
Top right : X = -9004812 Y = 1
Took 4 samples...
Bot right : X = -9004812 Y = 1
Took 4 samples...
Bot left : X = -9004812 Y = 1
Took 4 samples...
Center : X = -9004812 Y = 1
ts_calibrate: determinant is too small -- 0.000000
Calibration failed.
执行./ts_test时,测试界面也出现了,中间那个十字架一直在闪,终端提示如下
信息:
selected device is not a touchscreen I understand

-----------------------------------------------------------------------
答案2[推荐答案]:

cat /proc/bus/input/devices
看看哪个是你的 ts 设备。

一般会对应
/dev/input/event?

如果这些没有的话,可能你的触摸平驱动并不完整。


-----------------------------------------------------------------------
答案3[推荐答案]:

内核里面input device的event接口打开

-----------------------------------------------------------------------
答案4:

回pottichu:使用cat /proc/bus/input/devices命令后什么也没有显示;

回l2y3n2:内核里面input device的event接口打开?

使用友善自己的TSLIB,只在文件系统里面有,没提供源代码,是可以校屏的。

说明驱动是正常的吧?

-----------------------------------------------------------------------
答案5:

tsl

ib1.4移植到6410开发板,使用/dev/touchscreen,触摸无反应,请问遇到报“mini6410-ts:touch event buffer full”错误的情况吗?


相关主题