《嵌入式设备驱动程序基础笔记》第22期

《嵌入式设备驱动程序基础笔记》第22期linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler)、

欢迎大家来到IT世界,在知识的湖畔探索吧!

linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler)、输入子系统核心层(InputCore)和输入子系统设备驱动层

linux输入子系统的事件处理机制

《嵌入式设备驱动程序基础笔记》第22期

Linux输入子系统支持的数据类型:

EV_SYN 0x00 同步事件

EV_KEY 0x01 按键事件

EV_REL 0x02 相对坐标(如:鼠标移动,报告相对最后一次位置的偏移)

EV_ABS 0x03 绝对坐标(如:触摸屏或操作杆,报告绝对的坐标位置)

EV_MSC 0x04 其它

EV_SW 0x05 开关

EV_LED 0x11 按键/设备灯

EV_SND 0x12 声音/警报

EV_REP 0x14 重复

EV_FF 0x15 力反馈

EV_PWR 0x16 电源

EV_FF_STATUS 0x17 力反馈状态

EV_MAX 0x1f 事件类型最大个数和提供位掩码支持

注:参考内核:/include/linux/input.h

程序设计思路

《嵌入式设备驱动程序基础笔记》第22期

总体编程思路

《嵌入式设备驱动程序基础笔记》第22期

驱动程序

//touch.c#include <linux/errno.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/input.h>#include <linux/init.h>#include <linux/serio.h>#include <linux/delay.h>#include <linux/platform_device.h>#include <linux/clk.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/plat-s3c24xx/ts.h>#include <asm/arch/regs-adc.h>#include <asm/arch/regs-gpio.h>#define Stylus_up_state      (1<<15)#define Start_up_adc           (1<<0)  #define Wait_down_mode   0xd3#define Wait_up_mode        0x1d3struct s3c_ts_regs {	unsigned long adccon;	unsigned long adctsc;	unsigned long adcdly;	unsigned long adcdat0;	unsigned long adcdat1;	unsigned long adcupdn;};//static struct input_dev  * mytouch_dev;static struct input_handle   mytouch_handle;static struct timer_list  ts_timer;static volatile struct s3c_ts_regs *s3c_ts_regs;//函数声明static void s3c_ts_timer_function(unsigned long data);static void enter_wait_down_mode(void);static void enter_wait_up_mode(void);static void configurate_event(void);static void configurate_hardware(void);static int s3c_filter_ts(int *x, int *y);static void enter_measure_xy_mode(void){	s3c_ts_regs->adctsc = 0x0c;}static void start_adc(void){	s3c_ts_regs->adccon |= Start_up_adc;}static irqreturn_t pen_down_up_irq(int irq, void *dev_id){	if(s3c_ts_regs->adcdat0 &  Stylus_up_state )//up	{		printk("touch up");		enter_wait_down_mode();	}	else//down	{		printk("touch down");		enter_measure_xy_mode();		start_adc();	}		return IRQ_HANDLED;}static irqreturn_t adc_irq(int irq, void *dev_id){		static int cnt = 0;	static int x[4], y[4];	int adcdat0, adcdat1;		adcdat0 = s3c_ts_regs->adcdat0;	adcdat1 = s3c_ts_regs->adcdat1;	if (s3c_ts_regs->adcdat0 & Stylus_up_state)	{		cnt = 0;		input_report_abs(mytouch_handle.dev, ABS_PRESSURE, 0);		input_report_key(mytouch_handle.dev, BTN_TOUCH, 0);		input_sync(mytouch_handle.dev);		enter_wait_down_mode();	}	else	{		x[cnt] = adcdat0 & 0x3ff;		y[cnt] = adcdat1 & 0x3ff;		++cnt;		if (cnt == 4)		{			if (s3c_filter_ts(x, y))			{							printk("x = %d, y = %d\n", (x[0]+x[1]+x[2]+x[3])/4, (y[0]+y[1]+y[2]+y[3])/4);				input_report_abs(mytouch_handle.dev, ABS_X, (x[0]+x[1]+x[2]+x[3])/4);				input_report_abs(mytouch_handle.dev, ABS_Y, (y[0]+y[1]+y[2]+y[3])/4);				input_report_abs(mytouch_handle.dev, ABS_PRESSURE, 1);				input_report_key(mytouch_handle.dev, BTN_TOUCH, 1);				input_sync(mytouch_handle.dev);			}			cnt = 0;			enter_wait_up_mode();			mod_timer(&ts_timer, jiffies + HZ/100);		}		else		{			enter_measure_xy_mode();			start_adc();		}			}		return IRQ_HANDLED;}static int s3c_filter_ts(int x[], int y[])//filter{#define ERR_LIMIT 5	int avr_x, avr_y;	int det_x, det_y;	avr_x = (x[0] + x[1])/2;	avr_y = (y[0] + y[1])/2;	det_x = (x[2] > avr_x) ? (x[2] - avr_x) : (avr_x - x[2]);	det_y = (y[2] > avr_y) ? (y[2] - avr_y) : (avr_y - y[2]);	if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))		return 0;	avr_x = (x[1] + x[2])/2;	avr_y = (y[1] + y[2])/2;	det_x = (x[3] > avr_x) ? (x[3] - avr_x) : (avr_x - x[3]);	det_y = (y[3] > avr_y) ? (y[3] - avr_y) : (avr_y - y[3]);	if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))		return 0;		return 1;}static int mytouch_init(void){	mytouch_handle.dev = input_allocate_device();		configurate_event();	input_register_device(mytouch_handle.dev);		configurate_hardware();	return 0;}static void mytouch_exit(void){	free_irq(IRQ_TC, NULL);	free_irq(IRQ_ADC, NULL);	iounmap(s3c_ts_regs);	input_free_device(mytouch_handle.dev);	input_unregister_device(mytouch_handle.dev);	del_timer(&ts_timer);}static void configurate_event(void){	set_bit(EV_KEY,mytouch_handle.dev->evbit);	set_bit(EV_ABS,mytouch_handle.dev->evbit);	set_bit(BTN_TOUCH,mytouch_handle.dev->keybit);	input_set_abs_params(mytouch_handle.dev, ABS_X, 0, 0X3FF,0,0);	input_set_abs_params(mytouch_handle.dev, ABS_Y, 0, 0X3FF,0,0);	input_set_abs_params(mytouch_handle.dev, ABS_PRESSURE, 0, 1,0,0);}static void configurate_hardware(void){	struct clk *adc_clk;	//开启时钟	adc_clk = clk_get(NULL, "adc_clk");	clk_enable(adc_clk);	//io重映射	s3c_ts_regs = ioremap(0x58000000, sizeof(struct s3c_ts_regs));	//ADC配置	//ADCCLK=PCLK/(49+1)=50MHz/(49+1)=1MHz	s3c_ts_regs->adccon = (1<<14)|(49<<6);		s3c_ts_regs->adcdly = 0xffff;	//注册中断	request_irq(IRQ_TC, pen_down_up_irq, IRQF_SAMPLE_RANDOM, "ts_pen", NULL);	request_irq(IRQ_ADC, adc_irq, IRQF_SAMPLE_RANDOM, "adc_clk", NULL);	//注册定时器	init_timer(&ts_timer);	ts_timer.function = s3c_ts_timer_function;	add_timer(&ts_timer);	//进入等待按下模式	enter_wait_down_mode();	}static void s3c_ts_timer_function(unsigned long data){	if (s3c_ts_regs->adcdat0 & Stylus_up_state)	{		input_report_abs(mytouch_handle.dev, ABS_PRESSURE, 0);		input_report_key(mytouch_handle.dev, BTN_TOUCH, 0);		input_sync(mytouch_handle.dev);		enter_wait_down_mode();	}	else	{		enter_measure_xy_mode();		start_adc();	}}static void enter_wait_down_mode(void){	s3c_ts_regs->adctsc = Wait_down_mode;}static void enter_wait_up_mode(void){	s3c_ts_regs->adctsc = Wait_up_mode;	}module_init(mytouch_init);module_exit(mytouch_exit);MODULE_LICENSE("GPL");

欢迎大家来到IT世界,在知识的湖畔探索吧!

Makefile

欢迎大家来到IT世界,在知识的湖畔探索吧!#compile regular
KERN_DIR = /work/system/linux-2.6.22.6
all:
	make -C $(KERN_DIR) M=`pwd` modules
	rm -rf modules.order Module.symvers 
.PHONY:
clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order Module.symvers
obj-m   += touch.o

测试方法:

1. make menuconfig 去掉原来的触摸屏驱动程序

  • -> Device Drivers
  • -> Input device support
  • -> Generic input layer
  • -> Touchscreens
  • <> S3C2410/S3C2440 touchscreens

2,make uImage 使用新内核启动

3. insmod touch.ko

4,按下/松开触摸笔

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/48512.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信