Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1385255
  • 博文数量: 478
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4833
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-28 11:12
文章分类

全部博文(478)

文章存档

2019年(1)

2018年(27)

2017年(21)

2016年(171)

2015年(258)

我的朋友

分类: Android平台

2018-03-05 17:06:06

原文地址:TP驱动分析(下) 作者:jerry20000

 

三,如何上报数据的?fts_work_func


点击(此处)折叠或打开

  1. static void fts_work_func(struct work_struct *work)

  2. {

  3.       DBG_FUNC(KERN_INFO"Enter %s\n", __func__);

  4.       fts_read_data();

  5. }


可以看到fts_work_func直接调用了fts_read_data()函数。


下面具体分析fts_read_data()函数:



点击(此处)折叠或打开

  1. /***********************************************************************

  2. [function]:

  3. callback: gather the finger information and calculate the X,Y

  4. coordinate then report them to the input system;

  5. [parameters]:

  6. null;

  7. [return]:

  8. null;

  9. ***********************************************************************/

  10. int fts_read_data(void)

  11. {

  12.       struct FTS_TS_DATA_T *data = i2c_get_clientdata(this_client);

  13.       struct FTS_TS_EVENT_T *event = &data->event;

  14.       u8 buf[32] = {0};

  15. ……

  16.       for (k = 0; k < CFG_MAX_POINT_NUM; ++k)

  17.       {

  18.            buf[0] = 3 + k*6;//why should we use this function? See NOTE1

  19.            id = 0xe;

  20.            ret=fts_i2c_rxdata(buf, 6);//read 6 bytes data from where? See NOTE2

  21.            if (ret > 0)

  22.            {

  23.                  id = buf[2]>>4;//if k=0, read data from addr 3, it means addr3 is the start of buf, so buf[2] is addr5. See NOTE3

  24.                  touch_event = buf[0]>>6;//1st Event Flag. See NOTE4

  25.                  if (id >= 0 && id< CFG_MAX_POINT_NUM)

  26.                  {//computate the x,y coordination. First take out the 4 low bits from buf[0],and then put them on the high bit, at last “or” buf[1], the outcome is the value of x coodination.

  27.                       temp = buf[0]& 0x0f;

  28.                       temp = temp<<8;

  29.                       temp = temp | buf[1];

  30.           // x = temp;

  31.                       temp1 = (buf[2])& 0x0f;

  32.                       temp1 = temp1<<8;

  33.                       temp1 = temp1 | buf[3];

  34.                  // y=temp1;

  35.                 switch(orient_num){// we get orient num from items

  36.                 case 1:

  37.                     x = temp;

  38.                     y = temp1;

  39.                     break;

  40.                 case 2:

  41. ……

  42.                 }

  43.                       // buf[5] & buf[6] are not listed in the spec, so I don’t know why.

  44.                       pressure = buf[4] & 0x3f; //it takes on sense??

  45.                       size = buf[5]&0xf0;

  46.                       size = (id<<8)|size;

  47.                       touch_event = buf[0]>>6;


  48.                       if(touch_event == 1)

  49.                             pressure = 0;

  50.                       else

  51.                             pressure = 1;

  52.                  

  53.                       if (touch_event == 0) //press down

  54.                       {

  55.                             if(x >= 0 && x <= SCREEN_MAX_X && y >= 0 && y <= SCREEN_MAX_Y){

  56.                                   _st_finger_infos[id].u2_pressure= pressure;

  57.                                   _st_finger_infos[id].i2_x= (int16_t)x;

  58.                                   _st_finger_infos[id].i2_y= (int16_t)y;

  59.                                   _st_finger_infos[id].ui2_id = size;//size maybe indicate the touch ID.

  60.                                   _si_touch_num ++;

  61.                             } else {

  62.                                   //format key1.x1.y1.key2.x2.y2.key3.x3.y3.span (x,y is topleft coordinate)

  63.                                   for(i=0; i<key_num; i++)

  64.                                   {

  65.                                        if((x >= keys_data[i].x-key_span) && (x <= keys_data[i].x+key_span) && (y >= keys_data[i].y-key_span) && (y <= keys_data[i].y+key_span)) {

  66.                                              input_report_key(data->input_dev, keys_data[i].value, 1);

  67.                                              keys_data[i].press = 1;

  68.                                              key_id = i;

  69.                                              break;

  70.                                        }

  71.                                   }

  72.                             }

  73.                        } else if (touch_event == 1) { //up event

  74.                             _st_finger_infos[id].u2_pressure= 0;

  75.                             if(key_id !=0x80) {

  76.                                   for(i=0;i<key_num;i++){

  77.                                        if(keys_data[i].press == 1)

  78.                                              input_report_key(data->input_dev, keys_data[i].value, 0);

  79.                                   }

  80.                                  key_id=0x80;

  81.                             }

  82.                       } else if (touch_event == 2) { //move event

  83.                             _st_finger_infos[id].u2_pressure= pressure;

  84.                             _st_finger_infos[id].i2_x= (int16_t)x;

  85.                             _st_finger_infos[id].i2_y= (int16_t)y;

  86.                             _st_finger_infos[id].ui2_id = size;

  87.                             _si_touch_num ++;

  88.                       } else /*bad event, ignore*/

  89.                             continue;


  90.                       if (touch_event == 1) {

  91.                             DBG_EVENT("[TSP]id=%d up\n", id);

  92.                       } else {//if event is down or moving, report them.

  93.                             for(i= 0; i<CFG_MAX_POINT_NUM; ++i)

  94.                             {

  95.                                   if (_st_finger_infos[i].u2_pressure != 0){//report new input event

  96.                                   input_report_abs(data->input_dev,

  97.                                                    ABS_MT_TRACKING_ID, _st_finger_infos[i].ui2_id);

  98.                                   input_report_abs(data->input_dev,

  99.                                         ABS_MT_TOUCH_MAJOR, _st_finger_infos[i].u2_pressure);

  100.                                   input_report_abs(data->input_dev,

  101.                                         ABS_MT_POSITION_X, _st_finger_infos[i].i2_x);

  102.                                   input_report_abs(data->input_dev,

  103.                                                    ABS_MT_POSITION_Y, _st_finger_infos[i].i2_y);

  104.                                   input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 50);

  105.                                   input_mt_sync(data->input_dev);

  106.                                   }

  107.                             }

  108.                             input_sync(data->input_dev);

  109.                       }


  110.                       if (_si_touch_num == 0 ) {

  111.                             fts_ts_release();

  112.                       }

  113.                       _si_touch_num = 0;

  114.                  }

  115.            } else {

  116.            printk("[TSP] ERROR: in %s, line %d, ret= %d\n", __FUNCTION__,__LINE__,ret);

  117.            }

  118.            i_count ++;

  119.       }//while(id != 0xf && i_count < 1);


  120.       event->touch_point = touch_point_num;

  121.       if (event->touch_point == 0)

  122.            return 1;

  123.       switch (event->touch_point) {

  124.            case 5:

  125.                  event->x5 = touch_info[4].i2_x;

  126.                  event->y5 = touch_info[4].i2_y;

  127.                  event->pressure5 = touch_info[4].u2_pressure;

  128.            case 4:

  129.                  event->x4 = touch_info[3].i2_x;

  130.                  event->y4 = touch_info[3].i2_y;

  131.                  event->pressure4 = touch_info[3].u2_pressure;

  132.            case 3:

  133.                  event->x3 = touch_info[2].i2_x;

  134.                  event->y3 = touch_info[2].i2_y;

  135.                  event->pressure3 = touch_info[2].u2_pressure;

  136.            case 2:

  137.                  event->x2 = touch_info[1].i2_x;

  138.                  event->y2 = touch_info[1].i2_y;

  139.                  event->pressure2 = touch_info[1].u2_pressure;

  140.            case 1:

  141.                  event->x1 = touch_info[0].i2_x;

  142.                  event->y1 = touch_info[0].i2_y;

  143.                  event->pressure1 = touch_info[0].u2_pressure;

  144.                  break;

  145.            default:

  146.                  return -1;

  147.       }

  148.       return 0;

  149. }

NOTE1: buf[0] = 3 + k*6


为什么要这样写?

先来看datasheet吧。

K=0时,buf[0] = 3; 先从03h这里读取x,y的坐标;

K=1时,buf[0] = 9; 09h这里读取x,y的坐标;

……

NOTE2: ret=fts_i2c_rxdata(buf, 6);

追踪一下代码,不难发现调用过程是这样的:

fts_i2c_rxdata(u8 *rxdata, int length)

----> i2c_transfer(this_client->adapter, &msg, 1)

--------> adap->algo->master_xfer(adap, msgs, num);

//在这里其实就是imap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num);

再回到fts_i2c_rxdata(buf, 6)函数,其代码贴出如下:

static int fts_i2c_rxdata(u8 *rxdata, int length)

{

      struct i2c_msg msg;

      msg.addr = this_client->addr;

      msg.flags = 0;

      msg.len = 1;

      msg.buf = rxdata;

      ret = i2c_transfer(this_client->adapter, &msg, 1);

      msg.addr = this_client->addr;

      msg.flags = I2C_M_RD;

      msg.len = length;

      msg.buf = rxdata;

      ret = i2c_transfer(this_client->adapter, &msg, 1);

}//省略了一些语句。

上面可以看到i2c_transfer被调用了两次,也就是执行了两次的i2c/写过程。为什么要这样呢?

第一个i2c_msg 数据结构完成写操作,写入的数值为待读出的寄存器编号;第二个i2c_msg 数据结

构完成读操作,从先前指定的寄存器中读出数据。即一次完整的读操作其实是要先进行写、再进行读的。

NOTE3: id = buf[2]>>4;

如果k=0,即从触摸IC寄存器的03h处开始读数据到buf中,那么这里的buf[2]即是05h,即:

buf[2]>>4,即可取buf的第4位到最高位的数据,即取出Touch ID,它表示第几个触摸点。(注意这里定义的bufint 类型,故buf32bit, 16位在这里用不到。)

NOTE4: touch_event = buf[0]>>6;

按上面的分析可以知道,buf[0]其实是对应着03h,帮把buf[0]右移6位,即对应着第一个点的Event Flag

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