该驱动总要有以下重要数据结构:
1.触摸屏的file_operations
引用:static struct file_operations s3c2410_fops={
owner: THIS_MODULE,
open: s3c2410_ts_open,
read: s3c2410_ts_read,
release: s3c2410_ts_release,
#ifdef USE_ASYNC
fasync: s3c2410_ts_fasync,
#endif
poll: s3c2410_ts_poll,
};
2.全局变量TS_DEV结构体,用来保存触摸屏的相关参数、等待处理的消息队列、当前采样数据、上一次采样数据等信息
引用:typedef struct {
unsigned int penStatus;
TS_RET buf[MAX_TS_BUF];
unsigned int head, tail;
wait_queue_head_t wq; /
wait_down_int();
函数request_irq 是Linux 系统中驱动程序注册中断的方法。irq 为所要申请的硬件中断号,handler 为系统所注册的中断处理子程序,irq_flags 为申请时的选项,devname 为指向设备名称的字符指针,dev_id 为申请时告诉系统的设备标识。若中断申请成功则返回0,失败则返回负值。
ret = request_irq(IRQ_ADC_DONE, s3c2410_isr_adc, SA_INTERRUPT,
DEVICE_NAME, s3c2410_isr_adc);
调用该函数来进行A/D转换的中断注册,所要申请的硬件中断号为IRQ_ADC_DONE(62),在arch/irq s.h中定义;系统所注册的中断处理子程序为s3c2410_isr_adc 函数;申请中断选项为SA_INTERRUPT,表示中断处理程序是快速处理程序,即快速处理程序运行时,所有中断都被屏蔽;设备名称定义为DEVICE_NAME,即"s3c2410-ts";而设备标识仍然用中断处理子程序代替。
ret = request_irq(IRQ_TC, s3c2410_isr_tc, SA_INTERRUPT,
DEVICE_NAME, s3c2410_isr_tc);
接着继续调用该函数来进行触摸屏触摸的中断注册,所要申请的硬件中断号为IRQ_TC(61);系统所注册的中断处理子程序为s3c2410_isr_tc 函数;申请中断选项为SA_INTERRUPT,表示中断处理程序是快速处理程序,即快速处理程序运行时,所有中断都被屏蔽;设备名称定义为DEVICE_NAME,即"s3c2410-ts";而设备标识仍然用中断处理子程序代替。
wait_down_int();
调用该宏函数来设置触摸屏为等待中断模式【笔按下产生中断】,具体定义如下:
引用:#define wait_down_int() { ADCTSC = DOWN_INT | XP_PULL_UP_EN | \
XP_AIN | XM_HIZ | YP_AIN | YM_GND | \
XP_PST(WAIT_INT_MODE); }
用该宏函数来设置ADC 触摸屏控制寄存器,参考S3C2410 芯片datasheet 中关于触摸屏的章节,具体设置参数如下:
引用:DOWN_INT = 1<<8 * 0 该位保留且应该设为0 【笔按下或笔抬起中断信号控制位,设为0 表示笔按下产生中断信号】
XP_PULL_UP_EN = 1<<3 * 0 上拉开关使能,设为0 表示XP 引脚上拉使能
XP_AIN = 1<<4 * 1 选择nXPON 引脚输出值,设为1 表示nXPON 引脚输出1,则XP 引脚连接AIN[7] 引脚
XM_HIZ = 1<<5 * 0 选择XMON 引脚输出值,设为0 表示XMON 引脚输出0,则XM 引脚为高阻态
YP_AIN = 1<<6 * 1 选择nYPON 引脚输出值,设为1 表示nYPON 引脚输出1,则YP 引脚连接AIN[5] 引脚
YM_GND = 1<<7 * 1 选择YMON 引脚输出值,设为1 表示YMON 引脚输出1,则YM 引脚为接地
XP_PST(WAIT_INT_MODE); = 3 X坐标Y坐标手动测量设置,设为3 表示等待中断模式
#ifdef CONFIG_DEVFS_FS
devfs_ts_dir = devfs_mk_dir(NULL, "touchscreen", NULL);
devfs_tsraw = devfs_register(devfs_ts_dir, "0raw", DEVFS_FL_DEFAULT,
tsMajor, TSRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,
&s3c2410_fops, NULL);
#endif
这里调用了devfs_mk_dir 函数,在设备文件系统中创建了一个名为touchscreen 的目录,并返回一个带有目录结构的数据结构变量devfs_ts_dir。将该变量作为下一步devfs_register 函数的参数,该参数在调用设备文件系统注册清除函数devfs_unregister 时也要作为参数传入。
调用devfs_register 函数后,会在刚才创建的touchscreen 目录下再创建一个名为0raw 的设备文件节点。该函数的参数中,DEVFS_FL_DEFAULT 为该函数的标志选项,tsMajor 为注册字符设备时系统自动分配的主设备号,TSRAW_MINOR(1)为次设备号,S_IFCHR | S_IRUSR | S_IWUSR 为默认的文件模式,&s3c2410_fops 为传入内核的触摸屏file_operations 结构中的函数接口,私有数据指针为空。返回一个devfs_handle_t 数据结构的变量devfs_tsraw,这会在调用设备文件系统注册清除函数devfs_unregister 时作为参数传入。
模块的退出函数为s3c2410_ts_exit,该函数的工作就是清除已注册的字符设备,中断以及设备文件系统。
引用:static void __exit s3c2410_ts_exit(void)
{
#ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_tsraw);
devfs_unregister(devfs_ts_dir);
#endif
unregister_chrdev(tsMajor, DEVICE_NAME);
#ifdef CONFIG_PM
pm_unregister(tsdev.pm_dev);
#endif
free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);
free_irq(IRQ_TC, s3c2410_isr_tc);
#ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_tsraw);
devfs_unregister(devfs_ts_dir);
#endif
这里首先清除原先后一步创建设备文件节点0raw 的结构变量devfs_tsraw,然后再清除创建touchscreen 目录的结构变量devfs_ts_dir。
unregister_chrdev(tsMajor, DEVICE_NAME);
接下来删除字符设备的注册信息。
void free_irq(unsigned int irq, void *dev_id)
函数free_irq 与函数request_irq 相对应,通常在模块被卸载时调用,负责注销一个已经申请的中断。
free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);
free_irq(IRQ_TC, s3c2410_isr_tc);
最后依次注销A/D转换和定时器这两个已经申请的中断。
lin8331568 于 2009-10-12 08:37:34发表:
学学,用用!
jawanli 于 2009-08-17 21:02:20发表:
学习学习
88833324 于 2009-06-11 22:16:48发表:
学习下
31601 于 2009-04-24 14:22:09发表:
{:3_112:}好的学习