LINUX驱动之触摸屏

1 前言

从技术原理来区别触摸屏,可将触摸屏分为5个种类:矢量压力传感技术触摸屏,电阻技术触摸屏,电容技术触摸屏,红外线技术触摸屏,表面声波技术触摸屏,每一种触摸屏都有其各自的优缺点,要了解哪种触摸屏是适用于哪种场合,关键就在于要懂的每一类触摸屏技术的工作原理和特定,我们将以电阻触摸屏为例子讲解.
1.1 电阻式触摸屏
电阻式触摸屏中最常用和普及的触摸屏是四项式触摸屏,其结构由X层和Y层组成,中间由微小的绝缘点隔开,当触摸屏没有压力时,X层和Y层处于断开状态,当有压力时,触摸屏X层和Y层导通,通过X层的探针可以测出Y层接触点的电压,通过电压可以确定触摸点在Y层的位置,比如触摸点电压/总电压=Y值/Y轴长度,这样通过等式关系求出Y值,同样,通过Y层的探针可以测出X层接触点的电压,通过电压可以确定触摸点在X层的位置,这样就可以得到触摸点在触摸屏上的位置(x,y)
在这里插入图片描述
1.2 2440电阻式触摸屏接口的工作模式
2440触摸屏接口有4种工作模式,在不同的工作模式下,触摸屏设备完成不同的功能,在某些情况下,几种工作模式需要相互配合,才能完成一定的功能.这4种工作模式分别如下:
1.2.1 正常转化模式
在不使用触摸屏设备时,可以单独适用触摸屏接口中共用的数模转换器ADC,在这种模式下,可以通过设置寄存器启动普通的A/D转换,当转换结束时,触摸屏触摸点的电压会被写到ADC寄存器中,我们可以通过电压转换为我们的触摸点x,y坐标
1.2.2等待中断模式
设置触摸屏接口控制器的ADC寄存器,触摸屏就处于中断模式,这时触摸屏等待触摸信号的到来,当触摸信号到来时,触摸屏接口控制器将通过INT_TC线产生中断信号,表示有触摸动作发生,当中断发生,触摸屏可以转换为其他两种状态来读取触摸点的位置(x,y),这两种模式是独立的X/Y位置转化模式和自动X/Y位置转化模式
1.2.3独立的X/Y位置转换模式
独立的X/Y位置转换模式由两个子模式,分别是X位置模式和Y位置模式,X位置模式将转换后的X坐标写到ADC寄存器的DATA位中,然后产生中断,由中断服务子函数来处理,Y位置模式道理一样
1.2.4自动X/Y位置转换模式
这种模式触摸屏接口控制器自动转化X位置和Y位置,X,Y位置转化后写到ADC寄存器XPDATA,YPDATA位中,触摸屏接口控制器会通过中断线产生中断信号

触摸屏驱动程序分析

在这里插入图片描述
我们之前的文章已经讲过input输入子系统,触摸屏的驱动就是建立在这套子系统的基础之上,“evdev.c”文件作为handler事件层来处理硬件层device发起的请求,所以触摸屏驱动需要注册一个"input_dev"结构体,下面我们来分析下三星公司提供的触摸屏驱动

static int __init s3c2410ts_init(void)
{
   
//	init_MUTEX(&gADClock);
	return platform_driver_register(&s3c2410ts_driver);
}

入口函数很简单,注册了一个平台驱动,内核中有同名的平台设备"s3c2410-ts"时,s3c2410ts_driver结构中的probe函数就会被调用,我们看下probe函数里面做了什么

static int __init s3c2410ts_probe(struct platform_device *pdev)
{
   
	struct s3c2410_ts_mach_info *info;//定义了s3c2410触摸屏接口相关硬件的配置信息总结构体指针
	struct input_dev *input_dev;

	info = ( struct s3c2410_ts_mach_info *)pdev->dev.platform_data;//从device的平台数据dev->platform_data中获得指向struct s3c2410_ts_mach_info结构体指针

	if (!info)/*指针为空则表示没有平台数据,退出*/
	{
   
		printk(KERN_ERR "Hm... too bad : no platform data for ts\n");
		return -EINVAL;
	}

#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG  //如果定义了这个宏则打印信息表示进入触摸屏初始化工作
	printk(DEBUG_LVL "Entering s3c2410ts_init\n");
#endif

	adc_clock = clk_get(NULL, "adc");//获得ADC时钟源,并赋给adc_clock指针
	if (!adc_clock) {
     //如果没有正确获取ADC时钟源则表示错误,退出
		printk(KERN_ERR "failed to get adc clock source\n");
		return -ENOENT;
	}
	clk_enable(adc_clock);//使能ADC时钟

#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG//如果定义了这个宏则打印信息表示进入启动ADC实时时钟
	printk(DEBUG_LVL "got and enabled clock\n");
#endif

	base_addr=ioremap(S3C2410_PA_ADC,0x20);//映射ADC寄存器的地址
	if (base_addr == NULL) {
     //出错处理
		printk(KERN_ERR "Failed to remap register block\n");
		return -ENOMEM;
	}

	/* Configure GPIOs */
	s3c2410_ts_connect();//配置触摸屏的引脚

	if ((info->presc&0xff) > 0)//如果正确则设置ADC分配系数
		iowrite32(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\
			     base_addr+S3C2410_ADCCON);
	else
		iowrite32(0,base_addr+S3C2410_ADCCON);//否则不分频,分频系数为0


	/* Initialise registers */
	if ((info->delay&0xffff) > 0)
		iowrite32(info->delay & 0xffff,  base_addr+S3C2410_ADCDLY);

	iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);//是触摸屏处于等待中断状态

	/* Initialise input stuff */
	memset(&ts, 0, sizeof(struct s3c2410ts));//将全局成员ts各个成员初始化为0
	/*申请并初始化一个input输入设备*/
	input_dev = input_allocate_device();

	if (!input_dev) {
   
		printk(KERN_ERR "Unable to allocate the input device !!\n");
		return -ENOMEM;
	}

	ts.dev = input_dev;
	ts.dev->evbit[0] = BIT(EV_SYN) | BIT
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值