触摸屏属于一个标准的input dev.所以我们按照输入子系统的流程来实现驱动开发。
实际板子与CTPM的通讯连接基于IIC总线,所以我们需要把驱动挂载到IIC总线下面去,也就是注册IIC驱动到iic_core.c中去。
实例化一个IIC设备有多种方式,仿照上一次的24cxx IIC设备的创建,我们来实现ft5x06IIC设备的创建。
因实际板子上TS IC使用的是ft5206,所以先实例化设备:
好像win10下面的自带浏览器有点问题,代码段怪怪的,蛋疼。
这里有一个头文件:
#ifndef __FT5X06_H__
#define __FT5X06_H__
#define FT5X0X_REG_FIRMID 0xa6
struct ft5x06_platform_data {
uint32_t gpio_irq; // IRQ port
uint32_t irq_cfg;
uint32_t gpio_wakeup; // Wakeup support
uint32_t wakeup_cfg;
uint32_t gpio_reset; // Reset support
uint32_t reset_cfg;
int screen_max_x;
int screen_max_y;
int pressure_max;
};
#endif
static struct ft5x06_platform_data ft5x06_pdata =
{
.gpio_irq = S5PV210_GPH1(6),
.irq_cfg = S3C_GPIO_SFN(0xf),
.screen_max_x = 800,
.screen_max_y = 480,
.pressure_max = 200,
};
static struct i2c_board_info smdkv210_i2c_devs2[] __initdata = {
/* To Be Updated */
{ I2C_BOARD_INFO("ft5x06",(0x70 >> 1)),
.platform_data = &ft5x06_pdata,
},
};
i2c_register_board_info(2, smdkv210_i2c_devs2,
ARRAY_SIZE(smdkv210_i2c_devs2));
首先,设备如何初始化是和驱动紧密相关的,所以在初始化一个设备时,一定需要读它对应的驱动是如何编写的,需要传递哪些参数。我们知道TS的IIC是挂载iic2上的,而上一个24cxx是挂在iic0上的,所以有i2c_register_board_info()里的第一个参数传入0还是2的区别。
驱动的编写。
上一章我们讲了多点触摸的协议。知道了根据触摸屏硬件是否支持,我们可以使用A类或者B类协议来实现多点触摸数据的上报。
这里的驱动使用A类协议上报数据.
中断:
中断服务程序分为两个部分:顶半部和底半部,通常我们在顶半部处理比较紧急的代码,底半部处理相对不紧急的代码。如果你的中断处理函数很大很长,都放在顶半部里是很不明智的。
底半部的实现机制:
1)tasklist:本质工作在进程上下文
2)工作者队列:把推后的work交给内核的一个线程去调度,允许重新调度与睡眠。
3)软中断
我们的中断处理程序中有用到工作者队列,所以这边就提一下。
驱动主要上报ABS事件。point(x,y),描述一个点最小的描述单元是x,y坐标。所以我们至少需要上报这两个参数。
触摸会产生中断,中断会使能工作者队列。工作者队列会读数据,上报数据。整个流程得以实现。
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <mach/gpio.h>
#include <linux/gpio.h>
#include <asm/io.h>
#include <linux/irq.h>
#include <asm/bitops.h>
#include <linux/input/ft5x06.h>
#include <linux/input/mt.h>
#include <plat/gpio-cfg.h>
#define FT5X06_TP_MAX 5
#define TOUCH_MAX_X 0x700
#define TOUCH_MAX_Y 0x400
#define FT5X06_NAME "ft5x06"
static const struct i2c_device_id ft5x06_id[] =
{
{
"ft5206",0},
{}
};
static int swap_xy = 0;
static int scal_xy = 0;
struct ft5x06_event
{