Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2150769
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: Android平台

2014-02-10 09:30:04


在drivers/input/touchscreen/ft5302_tp/ft5302_ts.c中
module_init(ft5x0x_ts_init);
  1. static int __init ft5x0x_ts_init(void)
  2. {
  3.     ret = i2c_add_driver(&ft5x0x_ts_driver);
  4.     return ret;
  5. }
其中ft5x0x_ts_driver结构如下:
  1. static struct i2c_driver ft5x0x_ts_driver = {
  2.     .probe        = ft5x0x_ts_probe,
  3.     .remove        = __devexit_p(ft5x0x_ts_remove),
  4.     .id_table    = ft5x0x_ts_id,
  5.     .driver    = {
  6.         .name    = FT5X0X_NAME,
  7.         .owner    = THIS_MODULE,
  8.     },
  9. };

在probe函数中
  1. static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
  2. {
  3.     struct ft5x0x_ts_dev *ft5x0x_ts;
  4.     struct ft5x0x_platform_data *pdata = pdata = client->dev.platform_data;
  5.     struct input_dev *input_dev;
  6.     u8 buf_w[1];
  7.     u8 buf_r[1];
  8.     unsigned char reg_value;
  9.     unsigned char reg_version;
  10.     int result, irq = 0;

  11.     ft5x0x_ts = (struct ft5x0x_ts_dev *)kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL);
  12.     input_dev = input_allocate_device();
  13.     ft5x0x_ts->input_dev = input_dev;
  14.     ft5x0x_ts->client = this_client = client;
  15.     ft5x0x_ts->irq = client->irq;

  16.     __set_bit(EV_ABS, input_dev->evbit);
  17.     __set_bit(EV_KEY, input_dev->evbit);
  18.     __set_bit(EV_REP, input_dev->evbit);
  19.     __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
  20.     set_bit(ABS_MT_POSITION_X, input_dev->absbit);
  21.     set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
  22.     set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
  23.     set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);

  24.     input_mt_init_slots(input_dev, MAX_CONTACTS);

  25.     input_set_abs_params(input_dev,ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
  26.     input_set_abs_params(input_dev,ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
  27.     input_set_abs_params(input_dev,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
  28.     input_set_abs_params(input_dev,ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
  29.     input_dev->name        = FT5X0X_NAME;
  30.     input_register_device(input_dev);

  31.     g_dev = ft5x0x_ts;

  32.     i2c_set_clientdata(client, ft5x0x_ts);
  33.     INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);   //动态建立一个工作队列
  34.     ft5x0x_ts->ts_workqueue = create_workqueue(FT5X0X_NAME);

  35.     ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq);
  36.    
  37. err0:
  38.     msleep(200);
  39.     fts_register_read(FT5X0X_REG_FIRMID, &reg_version,1);
  40.     fts_register_read(FT5X0X_REG_REPORT_RATE, &reg_value,1);
  41.     fts_register_read(FT5X0X_REG_THRES, &reg_value,1);
  42.     fts_register_read(FT5X0X_REG_NOISE_MODE, &reg_value,1);
  43.    
  44.     //注册中断
  45.     request_irq(ft5x0x_ts->irq, ft5x0x_ts_interrupt, IRQF_TRIGGER_FALLING, "ft5x0x_ts", ft5x0x_ts);
  46.     disable_irq_nosync(g_dev->irq);
  47.     //打开中断
  48.     enable_irq(g_dev->irq);

  49.     return 0;
  50. }
当有按键按下时
  1. static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id)
  2. {
  3.     struct ft5x0x_ts_dev *ft5x0x_ts = dev_id;
  4.     del_timer(&ft5x0x_ts->timer);               //关闭内核定时器
  5.     disable_irq_nosync(g_dev->irq);             //关中断
  6.     queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work); //把任务交给指定的工作队列
  7.     return IRQ_HANDLED;
  8. }
INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);   //动态建立一个工作队列
进入工作队列处理函数:
  1. static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
  2. {
  3.     ft5x0x_read_data();
  4.     ft5x0x_report_value();
  5.     enable_irq(g_dev->irq);
  6. }



  1. static int ft5x0x_read_data(void)
  2. {
  3.     struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
  4.     struct ts_event *event = &data->event;
  5.     u8 buf[61]= {0};
  6.     ret = ft5x0x_i2c_rxdata(buf, 61);     //读取数据
  7.     memset(event, ~0x00, sizeof(struct ts_event));
  8.     event->touch_point = buf[2] & 0x0f;   //查看有几个手指按下
  9.     if (event->touch_point == 0) {        //如果没有手指按下,直接返回
  10.         return 0;
  11.     }
  12.     switch (event->touch_point) {     //最多只能看到5个手指
  13.     case 5:                           //将手指的状态与坐标值记录下来
  14.         event->point[4].status = (buf[0x1b] & 0xc0)>>6;
  15.         event->point[4].id = (buf[0x1d] & 0xf0)>>4;
  16.         event->point[4].x = ((s16)(buf[0x1b] & 0x07)<<8 | (s16)buf[0x1c]);
  17.         event->point[4].y = (s16)(buf[0x1d] & 0x07)<<8 | (s16)buf[0x1e];
  18.     case 4:      
  19.     case 3:
  20.     case 2:      
  21.     case 1:
  22.         event->point[0].status = (buf[0x03] & 0xc0)>>6;
  23.         event->point[0].id = (buf[0x05] & 0xf0)>>4;
  24.         event->point[0].x= (s16)(buf[0x03] & 0x07)<<8 | (s16)buf[0x04];
  25.         event->point[0].y = (s16)(buf[0x05] & 0x07)<<8 | (s16)buf[0x06];       
  26.     default:
  27.         return 0;
  28.     }
  29. }




  1. static void ft5x0x_report_value(void)
  2. {
  3.     struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
  4.     struct ts_event *event = &data->event;
  5.     int key_id = 0xff;
  6.     down_table = 0;
  7.     for(i=0; i<event->touch_point; i++)
  8.     {
  9.         event->point[i].x=event->point[i].x;
  10.         input_mt_slot(data->input_dev, event->point[i].id);

  11.         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id);

  12.         down_table |= 1 << event->point[i].id;
  13.         input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 100);
  14.         input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->point[i].x);
  15.         input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->point[i].y);
  16.         input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 100);
  17.     }

  18.     for(i=0; i<MAX_CONTACTS; i++) {
  19.         if( ( (~down_table) & 1<<i) && !(up_table & 1<<i) )
  20.         {
  21.             input_mt_slot(data->input_dev, i);
  22.             input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
  23.         }
  24.     }
  25.     up_table = ~down_table;
  26.     input_sync(data->input_dev);
  27. }   




关于内核定时器:
setup_timer(&ft5x0x_ts->timer, Touch_timer_release, (unsigned long)ft5x0x_ts);
data->timer.expires    = jiffies +8;
add_timer(&data->timer);
时间一到执行内核定时器处理函数
  1. static void Touch_timer_release(unsigned long ft_ts_pdev)
  2. {
  3.    do_something();
  4. }








阅读(2386) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~