在drivers/input/touchscreen/ft5302_tp/ft5302_ts.c中
module_init(ft5x0x_ts_init);
-
static int __init ft5x0x_ts_init(void)
-
{
-
ret = i2c_add_driver(&ft5x0x_ts_driver);
-
return ret;
-
}
其中ft5x0x_ts_driver结构如下:
-
static struct i2c_driver ft5x0x_ts_driver = {
-
.probe = ft5x0x_ts_probe,
-
.remove = __devexit_p(ft5x0x_ts_remove),
-
.id_table = ft5x0x_ts_id,
-
.driver = {
-
.name = FT5X0X_NAME,
-
.owner = THIS_MODULE,
-
},
-
};
在probe函数中
-
static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
-
{
-
struct ft5x0x_ts_dev *ft5x0x_ts;
-
struct ft5x0x_platform_data *pdata = pdata = client->dev.platform_data;
-
struct input_dev *input_dev;
-
u8 buf_w[1];
-
u8 buf_r[1];
-
unsigned char reg_value;
-
unsigned char reg_version;
-
int result, irq = 0;
-
-
ft5x0x_ts = (struct ft5x0x_ts_dev *)kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL);
-
input_dev = input_allocate_device();
-
ft5x0x_ts->input_dev = input_dev;
-
ft5x0x_ts->client = this_client = client;
-
ft5x0x_ts->irq = client->irq;
-
-
__set_bit(EV_ABS, input_dev->evbit);
-
__set_bit(EV_KEY, input_dev->evbit);
-
__set_bit(EV_REP, input_dev->evbit);
-
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
-
set_bit(ABS_MT_POSITION_X, input_dev->absbit);
-
set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
-
set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
-
set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);
-
-
input_mt_init_slots(input_dev, MAX_CONTACTS);
-
-
input_set_abs_params(input_dev,ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
-
input_set_abs_params(input_dev,ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
-
input_set_abs_params(input_dev,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
-
input_set_abs_params(input_dev,ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
-
input_dev->name = FT5X0X_NAME;
-
input_register_device(input_dev);
-
-
g_dev = ft5x0x_ts;
-
-
i2c_set_clientdata(client, ft5x0x_ts);
-
INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work); //动态建立一个工作队列
-
ft5x0x_ts->ts_workqueue = create_workqueue(FT5X0X_NAME);
-
-
ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq);
-
-
err0:
-
msleep(200);
-
fts_register_read(FT5X0X_REG_FIRMID, ®_version,1);
-
fts_register_read(FT5X0X_REG_REPORT_RATE, ®_value,1);
-
fts_register_read(FT5X0X_REG_THRES, ®_value,1);
-
fts_register_read(FT5X0X_REG_NOISE_MODE, ®_value,1);
-
-
//注册中断
-
request_irq(ft5x0x_ts->irq, ft5x0x_ts_interrupt, IRQF_TRIGGER_FALLING, "ft5x0x_ts", ft5x0x_ts);
-
disable_irq_nosync(g_dev->irq);
-
//打开中断
-
enable_irq(g_dev->irq);
-
-
return 0;
-
}
当有按键按下时
-
static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id)
-
{
-
struct ft5x0x_ts_dev *ft5x0x_ts = dev_id;
-
del_timer(&ft5x0x_ts->timer); //关闭内核定时器
-
disable_irq_nosync(g_dev->irq); //关中断
-
queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work); //把任务交给指定的工作队列
-
return IRQ_HANDLED;
-
}
INIT_WORK
(&ft5x0x_ts
->pen_event_work
, ft5x0x_ts_pen_irq_work
); //动态建立一个工作队列
进入工作队列处理函数:
-
static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
-
{
-
ft5x0x_read_data();
-
ft5x0x_report_value();
-
enable_irq(g_dev->irq);
-
}
-
static int ft5x0x_read_data(void)
-
{
-
struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
-
struct ts_event *event = &data->event;
-
u8 buf[61]= {0};
-
ret = ft5x0x_i2c_rxdata(buf, 61); //读取数据
-
memset(event, ~0x00, sizeof(struct ts_event));
-
event->touch_point = buf[2] & 0x0f; //查看有几个手指按下
-
if (event->touch_point == 0) { //如果没有手指按下,直接返回
-
return 0;
-
}
-
switch (event->touch_point) { //最多只能看到5个手指
-
case 5: //将手指的状态与坐标值记录下来
-
event->point[4].status = (buf[0x1b] & 0xc0)>>6;
-
event->point[4].id = (buf[0x1d] & 0xf0)>>4;
-
event->point[4].x = ((s16)(buf[0x1b] & 0x07)<<8 | (s16)buf[0x1c]);
-
event->point[4].y = (s16)(buf[0x1d] & 0x07)<<8 | (s16)buf[0x1e];
-
case 4:
-
case 3:
-
case 2:
-
case 1:
-
event->point[0].status = (buf[0x03] & 0xc0)>>6;
-
event->point[0].id = (buf[0x05] & 0xf0)>>4;
-
event->point[0].x= (s16)(buf[0x03] & 0x07)<<8 | (s16)buf[0x04];
-
event->point[0].y = (s16)(buf[0x05] & 0x07)<<8 | (s16)buf[0x06];
-
default:
-
return 0;
-
}
-
}
-
static void ft5x0x_report_value(void)
-
{
-
struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
-
struct ts_event *event = &data->event;
-
int key_id = 0xff;
-
down_table = 0;
-
for(i=0; i<event->touch_point; i++)
-
{
-
event->point[i].x=event->point[i].x;
-
input_mt_slot(data->input_dev, event->point[i].id);
-
-
input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id);
-
-
down_table |= 1 << event->point[i].id;
-
input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 100);
-
input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->point[i].x);
-
input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->point[i].y);
-
input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 100);
-
}
-
-
for(i=0; i<MAX_CONTACTS; i++) {
-
if( ( (~down_table) & 1<<i) && !(up_table & 1<<i) )
-
{
-
input_mt_slot(data->input_dev, i);
-
input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
-
}
-
}
-
up_table = ~down_table;
-
input_sync(data->input_dev);
-
}
关于内核定时器:
setup_timer
(&ft5x0x_ts
->timer
, Touch_timer_release
, (unsigned long
)ft5x0x_ts
);
data
->timer
.expires
= jiffies
+8
;
add_timer
(&data
->timer
);
时间一到执行内核定时器处理函数
-
static void Touch_timer_release(unsigned long ft_ts_pdev)
-
{
-
do_something();
-
}
阅读(2386) | 评论(0) | 转发(1) |