zForce红外触屏处理芯片驱动源码有两套,分别为linux&Android、wince系统实现。
我用的是linux系统,应用不是QT实现的,界面都是opengl实现,所以,要自行处理触屏输入控制。
linux的触屏驱动使用了input子系统,前一天已经做了一个基本学习,现在分析一下驱动实现。
硬件接口:
IR触屏使用I2C访问,有数据时,DATAREADY会置低,3.3V供电,PIN10接地。
I2C访问不是一般器件的寄存器式的读写操作,而是基于zForce的通信协议访问。
测试时可以参考zForce的通信协议说明,实际驱动已经实现所有协议内容,不做具体分析。
触屏模块硬件和软件适配修改有:
1. 需要提供一个IRQ,连接DATAREADY
我的板子上用的是GPIO的IRQ,需要初始化GPIO pin mux,输入和中断使能,下降沿触发(以后再具体分析GPIO的驱动架构)
2. 对接I2C3
使用TI的芯片,其linux内核中I2C的驱动使用的是new style驱动模型。
在I2C模块,修改全局变量:
static struct i2c_board_info __initdata ti814x_i2c_boardinfo1[] = {
{
.type = "zforce",
.addr = 0x50,// zForce I2C address
.irq = 200, // gpio irq number
},
};
I2C初始化函数中增加:
omap_register_i2c_bus(3, 100, ti814x_i2c_boardinfo1,ARRAY_SIZE(ti814x_i2c_boardinfo1));这个函数是由CPU提供商实现,作用是用new style方式注册I2C总线及设备,具体实现以后分析。
zForce模块初始化函数调用
static struct i2c_driver zforce_ts_driver =
{
.driver = {
.name = "zforce",
.owner = THIS_MODULE,
},
.probe = zforce_ts_probe,
.remove = zforce_ts_remove,
.suspend = zforce_ts_suspend,
.resume = zforce_ts_resume,
.id_table = zforce_ts_id,
};
i2c_add_driver ( &zforce_ts_driver );driver和device匹配,OS会调用driver的probe函数:zforce_ts_probe
配置input参数:
dev_set_drvdata ( &client->dev, priv );
input = input_allocate_device();
if ( !input )
{
dev_err ( &client->dev, "Failed to allocate input device.\n" );
error = -ENOMEM;
goto err1;
}
input->evbit[0] = BIT_MASK ( EV_KEY ) | BIT_MASK ( EV_ABS );
input->keybit[BIT_WORD ( BTN_TOUCH )] = BIT_MASK ( BTN_TOUCH );
// Setup the coordinate system (span from 0 to MAX in both axis)
input_set_abs_params( input, ABS_MT_TOUCH_MAJOR, 0, 0xFF, 0, 0);
input_set_abs_params( input, ABS_MT_TOUCH_MINOR, 0, 0xFF, 0, 0);
input_set_abs_params( input, ABS_MT_ORIENTATION, 0, 1, 0, 0);
input_set_abs_params( input, ABS_MT_TRACKING_ID, 0, 0XFFF, 0, 0);
input_set_abs_params ( input, ABS_MT_POSITION_X, 0, MAX_X, 0, 0 );
input_set_abs_params ( input, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0 );
input_mt_create_slots( input, MAX_COORDS);
input->name = client->name;
input->id.bustype = BUS_I2C;
input->dev.parent = &client->dev;
input_set_drvdata ( input, priv );
error = input_register_device ( input );配置中断和中断处理函数:
INIT_DELAYED_WORK ( &priv->work, zforce_ts_isr_bh );
init_completion ( &priv->complete );
error = request_irq ( priv->irq, zforce_ts_isr_th, IRQF_TRIGGER_LOW, client->name, priv );这里使用:
1.工作队列实现中断的上下半部分处理,
2.完成量实现内核线程同步。
最终,驱动获取触屏信息后:
for ( ; i < numberOfTouches; ++i )
{
priv->tInfo[i].id -= 1;
input_mt_slot( priv->input, priv->tInfo[i].id);
/* Report input */
if ( ( priv->tInfo[i].state == 0 ) || ( priv->tInfo[i].state == 1 ) )
{
input_event( priv->input, EV_ABS, ABS_MT_TRACKING_ID, priv->tInfo[i].id );
priv->tInfo[i].x = MAX_X - ( ( scaledMax_X / ( priv->width ) ) * ( priv->tInfo[i].x ) ) >> 16;
priv->tInfo[i].y = MAX_Y - ( ( scaledMax_Y / ( priv->height ) ) * ( priv->tInfo[i].y ) ) >> 16;
input_event( priv->input, EV_ABS, ABS_MT_POSITION_X, priv->tInfo[i].x );
input_event( priv->input, EV_ABS, ABS_MT_POSITION_Y, priv->tInfo[i].y );
}
else
{
input_event( priv->input, EV_ABS, ABS_MT_TRACKING_ID, -1);
}
}
input_event( priv->input, EV_KEY, BTN_TOUCH, 1);其中,<span style="font-family: Arial, Helvetica, sans-serif;">ABS_MT_TRACKING_ID对应多点触控的不同点ID。</span>
本文主要分析zForce红外触屏处理芯片在Linux系统的驱动实现。内容涉及硬件接口、I2C通信协议以及触屏模块的硬件和软件适配修改,包括设置IRQ、GPIO中断和I2C3的对接。驱动工作流程包括中断上下半部处理和内核线程同步。

1万+

被折叠的 条评论
为什么被折叠?



