@@ -294,9 +294,18 @@ void set_ps2_mouse_emulation(bool disable)
294294}
295295void set_power (bool standby )
296296{
297- int data = BIT (11 ) + standby ? 1 : 0 ;
297+ uint16_t data = BIT (11 ) | ( standby ? 0x01 : 0x0 ) ;
298298
299- i2c_write_offset16 (I2C_PORT_TOUCHPAD , TOUCHPAD_I2C_HID_EP | I2C_FLAG_ADDR16_LITTLE_ENDIAN , PCT3854_COMMAND , data , 1 );
299+ i2c_write_offset16 (I2C_PORT_TOUCHPAD ,
300+ TOUCHPAD_I2C_HID_EP | I2C_FLAG_ADDR16_LITTLE_ENDIAN , PCT3854_COMMAND , data , 2 );
301+ }
302+
303+ void set_reset (void )
304+ {
305+ uint16_t data = BIT (8 );
306+
307+ i2c_write_offset16 (I2C_PORT_TOUCHPAD ,
308+ TOUCHPAD_I2C_HID_EP | I2C_FLAG_ADDR16_LITTLE_ENDIAN , PCT3854_COMMAND , data , 2 );
300309}
301310
302311void setup_touchpad (void )
@@ -329,6 +338,7 @@ void read_touchpad_in_report(void)
329338 int need_reset = 0 ;
330339 uint8_t data [128 ];
331340 int xfer_len = 0 ;
341+ int report_mode = PS2MOUSE_REPORT_UNKNOWN ;
332342 int16_t x , y ;
333343 uint8_t response_byte = 0x08 ;
334344
@@ -359,7 +369,11 @@ void read_touchpad_in_report(void)
359369 CPRINTS ("PS2M Touchpad need to reset" );
360370 xfer_len = 6 ;
361371 need_reset = 1 ;
362- }
372+ } else if (xfer_len == 7 )
373+ report_mode = PS2MOUSE_REPORT_HYBRID ;
374+ else if (xfer_len == 8 )
375+ report_mode = PS2MOUSE_REPORT_PARALLEL ;
376+
363377 xfer_len = MIN (126 , xfer_len - 2 );
364378 rv = i2c_xfer_unlocked (I2C_PORT_TOUCHPAD ,
365379 TOUCHPAD_I2C_HID_EP | I2C_FLAG_ADDR16_LITTLE_ENDIAN ,
@@ -403,8 +417,20 @@ void read_touchpad_in_report(void)
403417 if (rv == EC_SUCCESS && data [2 ] == 0x02 ) {
404418 /*0x0800 02 04 feff 0000
405419 *0x0800 02 04 fdff ffff */
406- x = (int16_t )(data [4 ] + (data [5 ] << 8 ));
407- y = - (int16_t )(data [6 ] + (data [7 ] << 8 ));
420+ if (report_mode == PS2MOUSE_REPORT_HYBRID ) {
421+
422+ if (data [4 ] & 0x80 )
423+ x = (int16_t )(data [4 ] + (0xff << 8 ));
424+ else
425+ x = (int16_t )data [4 ];
426+ if (data [5 ] & 0x80 )
427+ y = - (int16_t )(data [5 ] + (0xff << 8 ));
428+ else
429+ y = - (int16_t )data [5 ];
430+ } else {
431+ x = (int16_t )(data [4 ] + (data [5 ] << 8 ));
432+ y = - (int16_t )(data [6 ] + (data [7 ] << 8 ));
433+ }
408434 x = MIN (255 , MAX (x , -255 ));
409435 y = MIN (255 , MAX (y , -255 ));
410436 /*button data*/
@@ -491,6 +517,8 @@ void mouse_interrupt_handler_task(void *p)
491517 CPRINTS ("PS2M Configuring for ps2 emulation mode" );
492518 /*tp takes about 80 ms to come up, wait a bit*/
493519 usleep (200 * MSEC );
520+ set_power (false);
521+ set_reset ();
494522 setup_touchpad ();
495523
496524 gpio_enable_interrupt (GPIO_SOC_TP_INT_L );
@@ -501,12 +529,15 @@ void mouse_interrupt_handler_task(void *p)
501529 }
502530 if (power_state == POWER_S0S3 || power_state == POWER_S5 ) {
503531 /* Power Down */
532+ set_power (true);
504533 gpio_disable_interrupt (GPIO_SOC_TP_INT_L );
505534 gpio_disable_interrupt (GPIO_EC_I2C_3_SDA );
506535 }
507536 }
508537 if (evt & PS2MOUSE_EVT_REENABLE ) {
509538 CPRINTS ("PS2M renabling" );
539+ set_power (false);
540+ set_reset ();
510541 setup_touchpad ();
511542 gpio_enable_interrupt (GPIO_SOC_TP_INT_L );
512543 gpio_enable_interrupt (GPIO_EC_I2C_3_SDA );
0 commit comments