Set predefined logical touchpad sizes for several ancient Elan hw v.2

models. This change is based on Linux driver.
Determine logical trace size. It used for calculation of touch sizes
in surface units for MT-protocol type B evdev reports.

Reviewed by:	gonzo
Approved by:	gonzo (mentor)
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D10266
This commit is contained in:
wulf 2017-05-04 23:12:45 +00:00
parent 13d94d2651
commit 5f063c2780

View File

@ -300,6 +300,8 @@ typedef struct elantechhw {
int dpmmy; int dpmmy;
int ntracesx; int ntracesx;
int ntracesy; int ntracesy;
int dptracex;
int dptracey;
int issemimt; int issemimt;
int isclickpad; int isclickpad;
int hascrc; int hascrc;
@ -6280,8 +6282,17 @@ enable_elantech(struct psm_softc *sc, enum probearg arg)
static const int ic2hw[] = static const int ic2hw[] =
/*IC: 0 1 2 3 4 5 6 7 8 9 a b c d e f */ /*IC: 0 1 2 3 4 5 6 7 8 9 a b c d e f */
{ 0, 0, 2, 0, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0 }; { 0, 0, 2, 0, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0 };
static const int fw_sizes[][3] = {
/* FW.vers MaxX MaxY */
{ 0x020030, 1152, 768 },
{ 0x020800, 1152, 768 },
{ 0x020b00, 1152, 768 },
{ 0x040215, 900, 500 },
{ 0x040216, 819, 405 },
{ 0x040219, 900, 500 },
};
elantechhw_t elanhw; elantechhw_t elanhw;
int icversion, hwversion, dptracex, dptracey, id, resp[3], dpix, dpiy; int icversion, hwversion, xtr, i, id, resp[3], dpix, dpiy;
KBDC kbdc = sc->kbdc; KBDC kbdc = sc->kbdc;
VLOG(3, (LOG_DEBUG, "elantech: BEGIN init\n")); VLOG(3, (LOG_DEBUG, "elantech: BEGIN init\n"));
@ -6332,8 +6343,8 @@ enable_elantech(struct psm_softc *sc, enum probearg arg)
return (FALSE); return (FALSE);
} }
elanhw.ntracesx = resp[1] - 1; elanhw.ntracesx = imax(resp[1], 3);
elanhw.ntracesy = resp[2] - 1; elanhw.ntracesy = imax(resp[2], 3);
elanhw.hastrackpoint = (resp[0] & 0x80) != 0; elanhw.hastrackpoint = (resp[0] & 0x80) != 0;
/* Get the touchpad resolution */ /* Get the touchpad resolution */
@ -6367,24 +6378,35 @@ enable_elantech(struct psm_softc *sc, enum probearg arg)
* On HW v.3 touchpads it should be done after switching hardware * On HW v.3 touchpads it should be done after switching hardware
* to real resolution mode (by setting bit 3 of reg10) * to real resolution mode (by setting bit 3 of reg10)
*/ */
elanhw.dptracex = elanhw.dptracey = 64;
for (i = 0; i < nitems(fw_sizes); i++) {
if (elanhw.fwversion == fw_sizes[i][0]) {
elanhw.sizex = fw_sizes[i][1];
elanhw.sizey = fw_sizes[i][2];
goto found;
}
}
if (elantech_cmd(kbdc, hwversion, ELANTECH_FW_ID, resp) != 0) { if (elantech_cmd(kbdc, hwversion, ELANTECH_FW_ID, resp) != 0) {
printf(" Failed to read touchpad size\n"); printf(" Failed to read touchpad size\n");
elanhw.sizex = 10000; /* Arbitrary high values to */ elanhw.sizex = 10000; /* Arbitrary high values to */
elanhw.sizey = 10000; /* prevent clipping in smoother */ elanhw.sizey = 10000; /* prevent clipping in smoother */
} else if (hwversion == 2) { } else if (hwversion == 2) {
dptracex = dptracey = 64;
if ((elanhw.fwversion >> 16) == 0x14 && (resp[1] & 0x10) && if ((elanhw.fwversion >> 16) == 0x14 && (resp[1] & 0x10) &&
!elantech_cmd(kbdc, hwversion, ELANTECH_SAMPLE, resp)) { !elantech_cmd(kbdc, hwversion, ELANTECH_SAMPLE, resp)) {
dptracex = resp[1] / 2; elanhw.dptracex = resp[1] / 2;
dptracey = resp[2] / 2; elanhw.dptracey = resp[2] / 2;
} }
elanhw.sizex = (elanhw.ntracesx - 1) * dptracex; xtr = ((elanhw.fwversion >> 8) == 0x0208) ? 1 : 2;
elanhw.sizey = (elanhw.ntracesy - 1) * dptracey; elanhw.sizex = (elanhw.ntracesx - xtr) * elanhw.dptracex;
elanhw.sizey = (elanhw.ntracesy - xtr) * elanhw.dptracey;
} else { } else {
elanhw.sizex = (resp[0] & 0x0f) << 8 | resp[1]; elanhw.sizex = (resp[0] & 0x0f) << 8 | resp[1];
elanhw.sizey = (resp[0] & 0xf0) << 4 | resp[2]; elanhw.sizey = (resp[0] & 0xf0) << 4 | resp[2];
xtr = (elanhw.sizex % (elanhw.ntracesx - 2) == 0) ? 2 : 1;
elanhw.dptracex = elanhw.sizex / (elanhw.ntracesx - xtr);
elanhw.dptracey = elanhw.sizey / (elanhw.ntracesy - xtr);
} }
found:
if (verbose >= 2) { if (verbose >= 2) {
printf(" Model information:\n"); printf(" Model information:\n");
printf(" MaxX: %d\n", elanhw.sizex); printf(" MaxX: %d\n", elanhw.sizex);
@ -6393,6 +6415,8 @@ enable_elantech(struct psm_softc *sc, enum probearg arg)
printf(" DpmmY: %d\n", elanhw.dpmmy); printf(" DpmmY: %d\n", elanhw.dpmmy);
printf(" TracesX: %d\n", elanhw.ntracesx); printf(" TracesX: %d\n", elanhw.ntracesx);
printf(" TracesY: %d\n", elanhw.ntracesy); printf(" TracesY: %d\n", elanhw.ntracesy);
printf(" DptraceX: %d\n", elanhw.dptracex);
printf(" DptraceY: %d\n", elanhw.dptracey);
printf(" SemiMT: %d\n", elanhw.issemimt); printf(" SemiMT: %d\n", elanhw.issemimt);
printf(" Clickpad: %d\n", elanhw.isclickpad); printf(" Clickpad: %d\n", elanhw.isclickpad);
printf(" Trackpoint: %d\n", elanhw.hastrackpoint); printf(" Trackpoint: %d\n", elanhw.hastrackpoint);