PS2 Elantech mostly working still disabled
Does handle coords correctly, but two finger jumps position somewhere We can also report actual buttons, but not sure how movementmaker handles it. Will do cleanup once working To test or help out return B_OK in probe_elantech
This commit is contained in:
parent
586138b632
commit
3431cf5b06
@ -112,6 +112,9 @@ const char* kElantechPath[4] = {
|
|||||||
|
|
||||||
#define ELANTECH_HISTORY_SIZE 256
|
#define ELANTECH_HISTORY_SIZE 256
|
||||||
|
|
||||||
|
#define STATUS_PACKET 0x0
|
||||||
|
#define HEAD_PACKET 0x1
|
||||||
|
#define MOTION_PACKET 0x2
|
||||||
|
|
||||||
static hardware_specs gHardwareSpecs;
|
static hardware_specs gHardwareSpecs;
|
||||||
|
|
||||||
@ -120,7 +123,7 @@ static status_t
|
|||||||
get_elantech_movement(elantech_cookie *cookie, mouse_movement *movement)
|
get_elantech_movement(elantech_cookie *cookie, mouse_movement *movement)
|
||||||
{
|
{
|
||||||
touch_event event;
|
touch_event event;
|
||||||
uint8 event_buffer[PS2_PACKET_ELANTECH];
|
uint8 packet[PS2_PACKET_ELANTECH];
|
||||||
|
|
||||||
status_t status = acquire_sem_etc(cookie->sem, 1, B_CAN_INTERRUPT, 0);
|
status_t status = acquire_sem_etc(cookie->sem, 1, B_CAN_INTERRUPT, 0);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
@ -131,69 +134,75 @@ get_elantech_movement(elantech_cookie *cookie, mouse_movement *movement)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet_buffer_read(cookie->ring_buffer, event_buffer,
|
if (packet_buffer_read(cookie->ring_buffer, packet,
|
||||||
cookie->dev->packet_size) != cookie->dev->packet_size) {
|
cookie->dev->packet_size) != cookie->dev->packet_size) {
|
||||||
TRACE("ELANTECH: error copying buffer\n");
|
TRACE("ELANTECH: error copying buffer\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cookie->crcEnabled && (event_buffer[3] & 0x08) != 0) {
|
if (cookie->crcEnabled && (packet[3] & 0x08) != 0) {
|
||||||
TRACE("ELANTECH: bad crc buffer\n");
|
TRACE("ELANTECH: bad crc buffer\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
} else if (!cookie->crcEnabled && ((event_buffer[0] & 0x0c) != 0x04
|
} else if (!cookie->crcEnabled && ((packet[0] & 0x0c) != 0x04
|
||||||
|| (event_buffer[3] & 0x1c) != 0x10)) {
|
|| (packet[3] & 0x1c) != 0x10)) {
|
||||||
TRACE("ELANTECH: bad crc buffer\n");
|
TRACE("ELANTECH: bad crc buffer\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
uint8 type = event_buffer[3] & 3;
|
// https://www.kernel.org/doc/html/v4.16/input/devices/elantech.html
|
||||||
TRACE("ELANTECH: packet type %d\n", type);
|
uint8 packet_type = packet[3] & 3;
|
||||||
|
TRACE("ELANTECH: packet type %d\n", packet_type);
|
||||||
TRACE("ELANTECH: packet content 0x%02x%02x%02x%02x%02x%02x\n",
|
TRACE("ELANTECH: packet content 0x%02x%02x%02x%02x%02x%02x\n",
|
||||||
event_buffer[0], event_buffer[1], event_buffer[2], event_buffer[3],
|
packet[0], packet[1], packet[2], packet[3],
|
||||||
event_buffer[4], event_buffer[5]);
|
packet[4], packet[5]);
|
||||||
switch (type) {
|
switch (packet_type) {
|
||||||
case 0:
|
case STATUS_PACKET:
|
||||||
// fingers
|
//fingers, no palm
|
||||||
cookie->fingers = event_buffer[1] & 0x1f;
|
cookie->fingers = (packet[4] & 0x80) == 0 ? packet[1] & 0x1f: 0;
|
||||||
|
dprintf("ELANTECH: Fingers %d, raw %x (STATUS)\n", cookie->fingers, packet[1]);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case HEAD_PACKET:
|
||||||
if ((((event_buffer[3] & 0xe0) >> 5) - 1) != 0) {
|
dprintf("ELANTECH: Fingers %d, raw %x (HEAD)\n", (packet[3] & 0xe0) >>5, packet[3]);
|
||||||
// only process first finger
|
// only process first finger
|
||||||
|
if ((packet[3] & 0xe0) != 0x20)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
|
||||||
event.zPressure = (event_buffer[1] & 0xf0)
|
event.zPressure = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
|
||||||
| ((event_buffer[4] & 0xf0) >> 4);
|
|
||||||
|
|
||||||
cookie->previousZ = event.zPressure;
|
cookie->previousZ = event.zPressure;
|
||||||
|
|
||||||
event.xPosition = ((event_buffer[1] & 0xf) << 8) | event_buffer[2];
|
cookie->x = event.xPosition = ((packet[1] & 0xf) << 8) | packet[2];
|
||||||
event.yPosition = (((event_buffer[4] & 0xf) << 8)
|
cookie->y = event.yPosition = ((packet[4] & 0xf) << 8) | packet[5];
|
||||||
| event_buffer[5]);
|
dprintf("ELANTECH: Pos: %d:%d\n (HEAD)", cookie->x, cookie->y);
|
||||||
TRACE("ELANTECH: buttons 0x%x x %" B_PRIu32 " y %" B_PRIu32
|
TRACE("ELANTECH: buttons 0x%x x %" B_PRIu32 " y %" B_PRIu32
|
||||||
" z %d\n", event.buttons, event.xPosition, event.yPosition,
|
" z %d\n", event.buttons, event.xPosition, event.yPosition,
|
||||||
event.zPressure);
|
event.zPressure);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case MOTION_PACKET:
|
||||||
TRACE("ELANTECH: packet type motion\n");
|
dprintf("ELANTECH: Fingers %d, raw %x (MOTION)\n", (packet[3] & 0xe0) >>5, packet[3]); //Most likely palm
|
||||||
// TODO
|
if (cookie->fingers == 0) return B_OK;
|
||||||
return B_OK;
|
//handle overflow and delta values
|
||||||
|
if ((packet[0] & 0x10) == 1) {
|
||||||
|
event.xPosition = cookie->x += 5 * (int8)packet[1];
|
||||||
|
event.yPosition = cookie->y += 5 * (int8)packet[2];
|
||||||
|
} else {
|
||||||
|
event.xPosition = cookie->x += (int8)packet[1];
|
||||||
|
event.yPosition = cookie->y += (int8)packet[2];
|
||||||
|
}
|
||||||
|
dprintf("ELANTECH: Pos: %d:%d (Motion\n", cookie->x, cookie->y);
|
||||||
|
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE("ELANTECH: unknown packet type %d\n", type);
|
dprintf("ELANTECH: unknown packet type %d\n", packet_type);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.buttons = 0;
|
event.buttons = 0;
|
||||||
// finger on touchpad
|
event.wValue = cookie->fingers == 1 ? 4 :0;
|
||||||
if ((cookie->fingers & 1) != 0) {
|
|
||||||
// finger with normal width
|
|
||||||
event.wValue = 4;
|
|
||||||
} else {
|
|
||||||
event.wValue = 3;
|
|
||||||
}
|
|
||||||
status = cookie->movementMaker.EventToMovement(&event, movement);
|
status = cookie->movementMaker.EventToMovement(&event, movement);
|
||||||
|
|
||||||
if (cookie->movementMaker.WasEdgeMotion()
|
if (cookie->movementMaker.WasEdgeMotion()
|
||||||
|| cookie->movementMaker.TapDragStarted()) {
|
|| cookie->movementMaker.TapDragStarted()) {
|
||||||
gEventProducer.FireEvent(cookie, event_buffer);
|
gEventProducer.FireEvent(cookie, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -566,7 +575,7 @@ elantech_open(const char *name, uint32 flags, void **_cookie)
|
|||||||
goto err4;
|
goto err4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRACE("ELANTECH: version 0x%" B_PRIu32 " (0x%" B_PRIu32 ")\n",
|
INFO("ELANTECH: version 0x%" B_PRIu32 " (0x%" B_PRIu32 ")\n",
|
||||||
cookie->version, cookie->fwVersion);
|
cookie->version, cookie->fwVersion);
|
||||||
|
|
||||||
if (cookie->version >= 3)
|
if (cookie->version >= 3)
|
||||||
@ -698,7 +707,7 @@ elantech_ioctl(void *_cookie, uint32 op, void *buffer, size_t length)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case MS_SET_TOUCHPAD_SETTINGS:
|
case MS_SET_TOUCHPAD_SETTINGS:
|
||||||
TRACE("ELANTECH: MS_SET_TOUCHPAD_SETTINGS");
|
TRACE("ELANTECH: MS_SET_TOUCHPAD_SETTINGS\n");
|
||||||
user_memcpy(&cookie->settings, buffer, sizeof(touchpad_settings));
|
user_memcpy(&cookie->settings, buffer, sizeof(touchpad_settings));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
@ -708,7 +717,7 @@ elantech_ioctl(void *_cookie, uint32 op, void *buffer, size_t length)
|
|||||||
sizeof(bigtime_t));
|
sizeof(bigtime_t));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
TRACE("ELANTECH: unknown opcode: %" B_PRIu32 "\n", op);
|
INFO("ELANTECH: unknown opcode: 0x%" B_PRIx32 "\n", op);
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,18 +27,27 @@ typedef struct {
|
|||||||
sem_id sem;
|
sem_id sem;
|
||||||
struct packet_buffer* ring_buffer;
|
struct packet_buffer* ring_buffer;
|
||||||
size_t packet_index;
|
size_t packet_index;
|
||||||
uint8 buffer[PS2_PACKET_ELANTECH];
|
|
||||||
uint8 mode;
|
|
||||||
|
|
||||||
uint8 previousZ;
|
|
||||||
TouchpadMovement movementMaker;
|
TouchpadMovement movementMaker;
|
||||||
|
|
||||||
touchpad_settings settings;
|
touchpad_settings settings;
|
||||||
uint32 version;
|
uint32 version;
|
||||||
uint32 fwVersion;
|
uint32 fwVersion;
|
||||||
uint8 capabilities[3];
|
|
||||||
bool crcEnabled;
|
uint32 x;
|
||||||
|
uint32 y;
|
||||||
uint32 fingers;
|
uint32 fingers;
|
||||||
|
|
||||||
|
|
||||||
|
uint8 buffer[PS2_PACKET_ELANTECH];
|
||||||
|
uint8 capabilities[3];
|
||||||
|
|
||||||
|
uint8 previousZ;
|
||||||
|
|
||||||
|
uint8 mode;
|
||||||
|
bool crcEnabled;
|
||||||
|
|
||||||
|
|
||||||
status_t (*send_command)(ps2_dev* dev, uint8 cmd, uint8 *in, int in_count);
|
status_t (*send_command)(ps2_dev* dev, uint8 cmd, uint8 *in, int in_count);
|
||||||
} elantech_cookie;
|
} elantech_cookie;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user