一、基本开发环境和触摸芯片接口
1、基本开发环境
PC机:Ubuntu12.04 64bit
GCC工具链条:arm-none-linux-gnueabi (gcc version 4.5.1 (ctng-1.8.1-FA))
开发板:友善之臂Tiny4412
板载系统:Android5.0.2
板载系统内核:Linux-3.0.86
2、触摸芯片接口
从上图中可以看出,触摸芯片和开发板之间通过三条线链接:其中两条是用于IIC数据传输,另外一条是用于中断引脚。
二、驱动程序的编写
1、驱动框架和前期准备
由上面可知驱动触摸芯片和主机之间是通过IIC接口链接的,所以需要使用IIC驱动框架:总线、设备、驱动模型;又考虑到触摸屏最终是通过输入子系统的形式来上报输入事件,所以还需要使用输入子系统驱动框架。所以从驱动程序的总体框架来说:要实现IIC驱动框架和输入子系统驱动框架。
为了更好地编写驱动程序,在开始之前,先定义一些宏来表示驱动程序使用的常量,以及定义一些全局变量或者结构体来更好地维护和方便驱动的开发,这一部分代码的实现如下:
/* 定义触摸驱动的名字 */
#define TINY4412_TS_NAME "ft5x0x_ts"
#define TINY4412_TS_MAX_X 800 // x轴最大分辨率
#define TINY4412_TS_MAX_Y 480 // y轴最大分辨率
#define TINY4412_TS_MAX_ID 10 // 由硬件来决定
/* 定义一个结构体用来描述触摸点的信息 */
struct yl_tiny4412_ts_event {
int x; // 获得的触摸点的x坐标
int y; // 获得的触摸点的y坐标
int id; // 获得触摸点的id,用来表示对应的触摸点
};
/* 定义一个全局结构体存放相关成员,更好的方便驱动程序的编写 */
struct yl_tiny4412_ts_config
{
int gpio; // 定义触摸屏外部中断的GPIO口
int touch_points; // 表示当前同时有几个触摸点或者说当前是几点触摸
struct i2c_client *i2c_client; // 用于存放i2c_client指针变量
struct input_dev *input_dev; // 定义一个input_dev结构体指针变量
struct work_struct work_queue; // 定义工作队列,用来处理和触摸相关的事件
struct yl_tiny4412_ts_event ts_event[10]; // 定义一个描述触摸点的数组
};
/* 定义一个 yl_tiny4412_ts_config 结构体的全局变量 */
static struct yl_tiny4412_ts_config yl_tiny4412_ts;
2、IIC框架部分的具体实现
由于IIC驱动程序采用总线、设备、驱动模型来进行实现,所以要自己来实现设备端和驱动端相关的代码。但是在内核中已经实现了设备相关的代码,如下所示:
static struct i2c_board_info i2c_devs1[] __initdata = {
#ifdef CONFIG_TOUCHSCREEN_FT5X0X
{
I2C_BOARD_INFO("ft5x0x_ts", (0x70 >> 1)),
.platform_data = &ft5x0x_pdata,
},
#endif
{
I2C_BOARD_INFO("wm8994", 0x1a),
.platform_data = &wm8994_platform_data,
},
};
所以这里只需要实现IIC驱动端,相关的代码即可。定义一个i2c_driver的结构体变量,具体实现如下:
/* 定义一个id表,用于i2c驱动和设备的匹配 */
static const struct i2c_device_id tiny4412_ts_id[] = {
{ TINY4412_TS_NAME, 0 },
{ }
};
/* 定义一个i2c_driver的实例 */
static struct i2c_driver tiny4412_ts_driver = {
.probe = tiny4412_ts_probe,
.remove = __devexit_p(tiny4412_ts_remove),
.id_table = tiny4412_ts_id,
.driver = {
.name = TINY4412_TS_NAME,
.owner = THIS_MODULE,
},
};
给它添加了一个id_table来匹配设备端代码,在驱动的入口和出口处来注册iic驱动端,代码实现如下:
/* 驱动的入口函数 */
static int __init tiny4412_ts_init(void)
{
yl_tiny4412_ts.gpio = EXYNOS4_GPX1(6); // 获得和触摸屏外部中断相关的GPIO口
return i2c_add_driver(&tiny