手把手教你写Linux设备驱动---input子系统(四)--电容屏驱动ft5x06编写(一)(基于友善之臂4412开发板)

这一节,我们将从零开始写tiny4412的触摸屏驱动ft5x06,写这节博客之前,先了解下需要什么知识:

1、i2c驱动相关的知识

2、输入子系统

3、中断

4、工作队列

关于i2c驱动相关的知识,在后期的博文里会专门写几篇博文来进行总结,这里就不再说i2c相关的知识,我们先知道怎么用就行了。

首先,我在ts.h构造了一个ts_info_st结构体,用来存放触摸屏的中断线,x坐标,y坐标,压力值。

用ts_st构造了该触摸屏的设备结构体。

我们还是直接看点实际的东西,上代码:

ts.h

#ifndef __TS_H
#define __TH_H

struct ts_info_st {
	int irq ;
	int xres ;
	int yres ;
	int pressure ;
};

//I2c_transfer 读写设备--->可能睡眠--->用工作队列
struct ts_st {
	int x ;         //坐标
	int y ;
	int irq ;       //中断
	int xres ;
	int yres ;
	int pressure ; //触摸力度
	struct work_struct work ;  //用于创建工作队列用
	struct i2c_client *client ; //用于i2c
	struct input_dev *dev ;    //用于输入子系统
};
#endif

ts_drv.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include "ts.h"

struct ts_st *ts ;
struct ts_info_st *pdata ;
//一旦有中断,就会在串口终端打印中断号
irqreturn_t  ts_handler(int irq , void *data)
{
	printk("ts touch !\n");
	printk("irq : %d\n",irq);
	return IRQ_HANDLED ;

}

//匹配成功就会调用probe函数
int ts_probe(struct i2c_client *client , const struct i2c_device_id *id)
{
	int ret ;
	printk("probe\n");
	//从i2c的client获取设备相关的数据保存到pdata里
	pdata = client->dev.platform_data ;
	ts = kzalloc(sizeof(*ts),GFP_KERNEL);
	if(!ts){
		return -ENOMEM ;
	}
	//给ts指针赋值
	printk("malloc success!\n");
	ts->client = client ;
	ts->irq = pdata->irq ;   //获取中断号
	ts->xres = pdata->xres ; //获取x坐标
	ts->yres = pdata->yres ; //获取y坐标
	ts->pressure = pdata->pressure ;
	//申请输入设备
	ts->dev = input_allocate_device();
	if(!ts->dev){
		ret = -ENOMEM ;
		goto alloc_input_error ;
	}
	ts->dev->name = client->name ; //"myts"-->board_info_
	ts->dev->phys = "xxxxx" ;
	ts->dev->uniq = "20170506" ;
	ts->dev->id.bustype = BUS_I2C ;
	ts->dev->id.vendor = 10010;
	ts->dev->id.product = 10111 ;
	ts->dev->id.version = 1 ;
        //以上赋值是表示注册设备以后的信息,可以通过cat /proc/bus/input查看
	//注册input事件
	ret = input_register_device(ts->dev);
	if(ret){
		goto register_input_error ;
	}
	//注册中断-->中断下降沿
	ret = request_irq(ts->irq , ts_handler , IRQF_TRIGGER_FALLING , client->name , ts) ;
        if(ret){
		goto irq_erro ;
	}
	printk("register irq success!\n");
	return ret ;

	register_input_error:
	input_free_device(ts->dev);

	alloc_input_error:
	kfree(ts);	

	irq_erro :
	input_unregister_device(ts->dev);
	free_irq(ts->irq,&ts);
	kfree(ts);
}

//i2c的id_table
struct i2c_device_id id_table[] = {
	{"myts",123},
	{"herts","456"},
	{},
};

//实现i2c驱动操作结构体
struct i2c_driver ts_drv = {

	.probe = ts_probe ,
	.driver = {
		.name = "myts",
	},
	.id_table = id_table ,
};

static int __init hello_init(void)
{
    printk("Hello, kenerl installed for YYXXXXXXXXXX20170423!\n");
    int ret ;
    ret = i2c_add_driver(&ts_drv); //添加一个i2c驱动
    if(ret != 0){
		printk("i2c add driver fair!\n");
		i2c_del_driver(&ts_drv); //删除一个i2c驱动
		return -1 ;
    }
    printk("i2c_add  driver success!\n");
    return 0;
}

static void __exit hello_cleanup(void)
{
    printk("Good-bye, removed!\n");
    i2c_del_driver(&ts_drv);
}

module_init(hello_init);
module_exit(hello_cleanup);
MODULE_LICENSE("GPL");

编写Makefile,这里我们在外面写一个用驱动就可以加载的模块:

obj-m	+= ts_drv.o

ROOTFS = .
KERNEL_SRC	= /work/android-5.0.2/kernel

all:
	make -C $(KERNEL_SRC) M=`pwd` modules

clean:
	make -C $(KERNEL_SRC) M=`pwd` clean
	rm -rf app

install:
	make -C $(KERNEL_SRC) M=`pwd` modules_install INSTALL_MOD_PATH=$(ROOTFS)

app:
	arm-linux-gcc app.c -o app

写完驱动后,在当前目录下执行make:

然后,我们通过adb push命令,将该ko放入android根文件系统的system目录下。

如果你的系统的分区没有设置成可读可写,还需要在当前目录下执行:adb remount就可以了。

接下来,执行adb push  ts_drv.ko   /system

然后切换到我的minicom终端,此时Android系统已经启动,我切换到system目录下,执行insmod ts_drv.ko后,然后手点击触摸屏,就会有驱动信息弹出来,做这个步骤之前,要把友善提供的内核里的写好的触摸屏驱动给卸载掉,否则不会成功,请注意。

我们看到,触摸屏的时候,中断服务程序就会被调用,打印出中断号。

下一节,我们将进一步完善这个触摸屏驱动程序。

时间: 2024-11-02 22:06:52

手把手教你写Linux设备驱动---input子系统(四)--电容屏驱动ft5x06编写(一)(基于友善之臂4412开发板)的相关文章

手把手教你写Linux设备驱动---input子系统(三)--电容屏事件坐标读取(基于友善之臂4412开发板)

前面我们学习了鼠标是如何如何通过应用程序来读取事件和坐标值的,后面也写了一个简单的input系统的按键驱动程序. 博文如下,讲的内容非常清楚,给小白来入手当然是非常容易的: http://blog.csdn.net/morixinguan/article/details/69808832 这节,我们来学习一下触摸屏事件获取,然后上一个基于4412开发板ft5x0x型号的x,y坐标值读取,后面我们将从零开始实现这款触摸屏的驱动程序: 首先,我们要明白一个概念,触摸屏在input系统中是一类什么事件

手把手教你写Linux设备驱动---input子系统(二)--按键驱动实现(一)(基于友善之臂4412开发板)

在上一节里,我们用一个应用程序实现了鼠标的控制,并控制鼠标用相对位移不断的画一个正方形,感觉非常有意思,这一节,我们将通过一个简单按键实例来真正的实现一个input设备驱动程序. http://blog.csdn.net/morixinguan/article/details/69808832 在写Input驱动之前,我们要了解下这个结构体,在此,我们要包含相应的头文件: #include <linux/input.h> 我们在这个头文件中找到了以下结构体,它就是input设备的核心: //用

手把手教你写Linux设备驱动---input子系统(一)--input事件应用程序的读写实现(基于友善之臂4412开发板)

     这节,我们来说下input子系统,什么是input子系统? input子系统就是输入子系统.      输入子系统是 Linux内核用于管理各种输入设备 (键盘,鼠标,遥控杆,书写板等等 )的部分,用户通过输入子系统进行内核,命令行,图形接口之间的交换.输入子系统在内核里实现,因为设备经常要通过特定的硬件接口被访问 (例如串口, ps/2, usb等等 ),这些硬件接口由内核保护和管理.内核给用户导出一套固定的硬件无关的 input API,供用户空间程序使用. 输入子系统分为三块:

手把手教你写Linux设备驱动---中断(一)(基于友善之臂4412开发板)

今天,我们要来实现一个基于tiny4412开发板上的最简本的按键中断驱动程序,那么,写这个程序之前,我们先来了解下Linux中断的基本知识. 在Linux内核中,每一个能够发出中断请求的硬件设备控制器都有一条名为IRQ的输出线.所有现在存在的IRQ线都与一个名为可编程中断控制器的硬件电路的输入引脚相连,我们可以来看下4412上与板子上相连的按键. 下面这张电路图,也就是4412板子上按键的电路图和CPU的连接关系图: 我们明显可以看到,4个按键分别接在GPX3这几个引脚上,对应着引脚,接下来我们

手把手教你写Linux设备驱动---定时器(一)(基于友善之臂4412开发板)

这个专题我们来说下Linux中的定时器. 在Linux内核中,有这样的一个定时器,叫做内核定时器,内核定时器用于控制某个函数,也就是定时器将要处理的函数在未来的某个特定的时间内执行.内核定时器注册的处理函数只执行一次,即不是循环执行的. 如果对延迟的精度要求不高的话,最简单的实现方法如下---忙等待: Unsigned long j = jiffies + jit_delay * HZ; While(jiffies < j) { -- } 下面来说下具体的参数代表的含义: jiffies:全局变

手把手教你写Linux设备驱动---中断(二)--tasklet实现(基于友善之臂4412开发板)

上节:http://blog.csdn.net/morixinguan/article/details/68958185 在上一节博文中,教会了大家如何来写一个Linux设备的中断程序,实现也非常简单,我们来回顾一下具体的操作流程,只要遵循以下几个步骤即可实现最简单的中断处理程序: 使用中断相关的API和定义时要包含以下头文件: #include <linux/interrupt.h> 然后写中断需要以下步骤 1.申请中断号 使用gpio_to_irq函数,可以从返回值获取到对应的中断号 2.

手把手教你从零实现Linux misc设备驱动一(基于友善之臂4412开发板)

关于如何来写一个misc设备,在前面有篇文章已经介绍了大致的流程,现在就让我们来实现一个最简单的misc设备驱动. http://blog.csdn.net/morixinguan/article/details/52700146 关于前面的字符设备有以下四篇文章,可以做参考: http://blog.csdn.net/morixinguan/article/details/55002774 http://blog.csdn.net/morixinguan/article/details/550

手把手教你写Linux设备驱动---中断(三)--workqueue实现(基于友善之臂4412开发板)

上节,我们讲到如何来实现tasklet小任务机制 http://blog.csdn.net/morixinguan/article/details/69666935 这节,我们来实现一下中断下半部的工作队列: 在写这个demo之前,我们要了解一下工作队列的相关数据结构还有API. 需要包含的头文件: #include <linux/workqueue.h> 基本的数据结构: //工作队列结构 struct work_struct { atomic_long_t data; //链表处理 str

手把手教你从零实现Linux misc设备驱动二(基于友善之臂4412开发板)

上一节,我教大家实现了一个最简单的MISC设备驱动,那么这节,我们将用一个实例来驱动蜂鸣器,这里为了方便,我就不再写应用程序进行测试,直接在驱动里调用open函数,这个程序是在Android系统里跑起来,后面我会教大家如何在Android下写应用测试程序. 我们参考以前写的蜂鸣器驱动程序,将它移植到我们这个程序里,让它成为一个MISC设备. 参考以前写的文章: http://blog.csdn.net/morixinguan/article/details/50628588 接下来,看看代码: