Search This Blog

Jul 31, 2011

Synaptics RMI4 Multitouch PAD

This part comes from last year. I post it here for memory keeping.

Connection

  • NOTE: nINT is an active-low open-drain pin for which the host must supply an external pull-up resistor.
    DISP2_DAT9        --->  Touch_nINT
    DISPB2_SER_CLK    --->  Touch_I2C_DAT
    DISPB2_SER_DIO    --->  Touch_I2C_CLK
    EIM_A16           --->  Touch_nRST1
    

Touch PAD register.

Part of register map, that we need concern.
AddrNameBit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
0x0014Interrupt status    Abs0ButtonStatusFlash
0x0015Button data       Left
AddrNameBit 7Bit 6Bit 5Bit 4Bit 3 - Bit 2Bit 1 - Bit 0
0x00162D Finger State    Finger State 1Finger State 0
AddrNameBit 7 - Bit 0
0x00172D X position (11:4) Finger 0X position [11:4]
0x00182D Y position (11:4) Finger 0Y position [11:4]
0x001B2D Z Finger 0Z
0x001C2D X position (11:4) Finger 1X position [11:4]
0x001D2D Y position (11:4) Finger 1Y position [11:4]
0x00202D Z Finger 1Z
AddrNameBit 7 - Bit 4Bit 3 - Bit 0
0x00192D Y/X position(3:0) Finger 0Y Position [3:0]X Position [3:0]
0x001A2D Wy/Wx Finger 0WyWx
0x001E2D Y/X position(3:0) Finger 1Y Position [3:0]X Position [3:0]
0x001F2D Wy/Wx Finger 1WyWx

Get touch sample.

I2CReadForTimes(0x2c,0x14,buf,0x11); // read out register value from register addr 0x14.
  ts_sample->int_state = buf[0] & 0xF; // save interrupt status
  ts_sample->button_data = buf[1] & 0x01; // save button_data
  
  switch(buf[0x2] & 0xf) // 2D Finger State
  {
    case 0x0:
 ts_sample->contact_resistance = 0;
 break;
    case 0x01:
    case 0x02:  // bit0-1 is Finger 0 state
 ts_sample->contact_resistance = 1;
 ts_sample->x_position = (((buf[3]<<4))|(buf[5]&0xf));
 ts_sample->y_position = (((buf[4])<<4)|((buf[5]&0xf0)>>4));
 break;
    case 0x04:
    case 0x08: // bit2-3 is Finger 1 state
 ts_sample->contact_resistance = 1;
 ts_sample->x_position = (((buf[8]<<4))|(buf[10]&0xf));
 ts_sample->y_position = (((buf[9])<<4)|((buf[10]&0xf0)>>4)); 
 break;
    case 0x05:
    case 0x06:
    case 0x09:
    case 0x0a: // Finger 0 and Finger 1 press at same time
 ts_sample->contact_resistance = 2;
 ts_sample->x_position = (((buf[3]<<4))|(buf[5]&0xf));
 ts_sample->y_position = (((buf[4])<<4)|((buf[5]&0xf0)>>4));

 ts_sample->x2_position = (((buf[8]<<4))|(buf[10]&0xf));
 ts_sample->y2_position = (((buf[9])<<4)|((buf[10]&0xf0)>>4)); 
 break;

    default :
 printk("fail buf[0x16] = %d \n",buf[2]); // report real finger state value
 return -1;
  }  

Transfer to screen pixel relate position. We use 480x800 for example

if(ts_sample.int_state & 0x08) { // touch screen abs
    if (ts_sample.contact_resistance < 2) {
      if (ts_sample.x_position == 0 && ts_sample.y_position == 0 &&
 ts_sample.contact_resistance == 0) {
 x = last_x;
 y = last_y;
      }
      else
      {// transfer to screen relate position
 x = ts_sample.x_position * 480 / 1894; 
 y = 799 - ts_sample.y_position * 800 / 3245;
      }
      if (x != last_x) {
 input_report_abs(mxc_inputdev, ABS_X, x);
 last_x = x;
      }
      if (y != last_y) {
 input_report_abs(mxc_inputdev, ABS_Y, y);
 last_y = y;
      }
      /* report pressure */
      input_report_abs(mxc_inputdev, ABS_PRESSURE, ts_sample.contact_resistance);
      /* report the BTN_TOUCH */
      if (ts_sample.contact_resistance != last_press)
      {
 input_event(mxc_inputdev, EV_KEY,BTN_TOUCH, ts_sample.contact_resistance);
      }
    }
    input_sync(mxc_inputdev);
    last_press = ts_sample.contact_resistance;
  }
  else if(ts_sample.int_state & 0x04)  // button input
  {
    input_report_key(input_button,KEY_MENU,ts_sample.button_data);
  }

No comments: