Commit 6c53694f authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: synaptics - split device info into a separate structure

In preparation for SMBus/Intertouch device support, move static device
information that we query form the touchpad upon initialization into
separate structure. This will allow us to query the device without
allocating memory first.

Also stop using "unsigned long", everything fits into 32 bit chunks.
Reviewed-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 8eb92e5c
...@@ -127,9 +127,9 @@ static bool cr48_profile_sensor; ...@@ -127,9 +127,9 @@ static bool cr48_profile_sensor;
struct min_max_quirk { struct min_max_quirk {
const char * const *pnp_ids; const char * const *pnp_ids;
struct { struct {
unsigned long int min, max; u32 min, max;
} board_id; } board_id;
int x_min, x_max, y_min, y_max; u32 x_min, x_max, y_min, y_max;
}; };
static const struct min_max_quirk min_max_pnpid_table[] = { static const struct min_max_quirk min_max_pnpid_table[] = {
...@@ -248,27 +248,31 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned ...@@ -248,27 +248,31 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned
* Read the model-id bytes from the touchpad * Read the model-id bytes from the touchpad
* see also SYN_MODEL_* macros * see also SYN_MODEL_* macros
*/ */
static int synaptics_model_id(struct psmouse *psmouse) static int synaptics_model_id(struct psmouse *psmouse,
struct synaptics_device_info *info)
{ {
struct synaptics_data *priv = psmouse->private;
unsigned char mi[3]; unsigned char mi[3];
int error;
if (synaptics_send_cmd(psmouse, SYN_QUE_MODEL, mi)) error = synaptics_send_cmd(psmouse, SYN_QUE_MODEL, mi);
return -1; if (error)
priv->model_id = (mi[0]<<16) | (mi[1]<<8) | mi[2]; return error;
info->model_id = (mi[0] << 16) | (mi[1] << 8) | mi[2];
return 0; return 0;
} }
static int synaptics_more_extended_queries(struct psmouse *psmouse) static int synaptics_more_extended_queries(struct psmouse *psmouse,
struct synaptics_device_info *info)
{ {
struct synaptics_data *priv = psmouse->private;
unsigned char buf[3]; unsigned char buf[3];
int error;
if (synaptics_send_cmd(psmouse, SYN_QUE_MEXT_CAPAB_10, buf)) error = synaptics_send_cmd(psmouse, SYN_QUE_MEXT_CAPAB_10, buf);
return -1; if (error)
return error;
priv->ext_cap_10 = (buf[0]<<16) | (buf[1]<<8) | buf[2];
info->ext_cap_10 = (buf[0] << 16) | (buf[1] << 8) | buf[2];
return 0; return 0;
} }
...@@ -276,21 +280,24 @@ static int synaptics_more_extended_queries(struct psmouse *psmouse) ...@@ -276,21 +280,24 @@ static int synaptics_more_extended_queries(struct psmouse *psmouse)
* Read the board id and the "More Extended Queries" from the touchpad * Read the board id and the "More Extended Queries" from the touchpad
* The board id is encoded in the "QUERY MODES" response * The board id is encoded in the "QUERY MODES" response
*/ */
static int synaptics_query_modes(struct psmouse *psmouse) static int synaptics_query_modes(struct psmouse *psmouse,
struct synaptics_device_info *info)
{ {
struct synaptics_data *priv = psmouse->private;
unsigned char bid[3]; unsigned char bid[3];
int error;
/* firmwares prior 7.5 have no board_id encoded */ /* firmwares prior 7.5 have no board_id encoded */
if (SYN_ID_FULL(priv->identity) < 0x705) if (SYN_ID_FULL(info->identity) < 0x705)
return 0; return 0;
if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid)) error = synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid);
return -1; if (error)
priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; return error;
info->board_id = ((bid[0] & 0xfc) << 6) | bid[1];
if (SYN_MEXT_CAP_BIT(bid[0])) if (SYN_MEXT_CAP_BIT(bid[0]))
return synaptics_more_extended_queries(psmouse); return synaptics_more_extended_queries(psmouse, info);
return 0; return 0;
} }
...@@ -298,14 +305,17 @@ static int synaptics_query_modes(struct psmouse *psmouse) ...@@ -298,14 +305,17 @@ static int synaptics_query_modes(struct psmouse *psmouse)
/* /*
* Read the firmware id from the touchpad * Read the firmware id from the touchpad
*/ */
static int synaptics_firmware_id(struct psmouse *psmouse) static int synaptics_firmware_id(struct psmouse *psmouse,
struct synaptics_device_info *info)
{ {
struct synaptics_data *priv = psmouse->private;
unsigned char fwid[3]; unsigned char fwid[3];
int error;
if (synaptics_send_cmd(psmouse, SYN_QUE_FIRMWARE_ID, fwid)) error = synaptics_send_cmd(psmouse, SYN_QUE_FIRMWARE_ID, fwid);
return -1; if (error)
priv->firmware_id = (fwid[0] << 16) | (fwid[1] << 8) | fwid[2]; return error;
info->firmware_id = (fwid[0] << 16) | (fwid[1] << 8) | fwid[2];
return 0; return 0;
} }
...@@ -313,53 +323,57 @@ static int synaptics_firmware_id(struct psmouse *psmouse) ...@@ -313,53 +323,57 @@ static int synaptics_firmware_id(struct psmouse *psmouse)
* Read the capability-bits from the touchpad * Read the capability-bits from the touchpad
* see also the SYN_CAP_* macros * see also the SYN_CAP_* macros
*/ */
static int synaptics_capability(struct psmouse *psmouse) static int synaptics_capability(struct psmouse *psmouse,
struct synaptics_device_info *info)
{ {
struct synaptics_data *priv = psmouse->private;
unsigned char cap[3]; unsigned char cap[3];
int error;
if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) error = synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap);
return -1; if (error)
priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2]; return error;
priv->ext_cap = priv->ext_cap_0c = 0;
info->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
info->ext_cap = info->ext_cap_0c = 0;
/* /*
* Older firmwares had submodel ID fixed to 0x47 * Older firmwares had submodel ID fixed to 0x47
*/ */
if (SYN_ID_FULL(priv->identity) < 0x705 && if (SYN_ID_FULL(info->identity) < 0x705 &&
SYN_CAP_SUBMODEL_ID(priv->capabilities) != 0x47) { SYN_CAP_SUBMODEL_ID(info->capabilities) != 0x47) {
return -1; return -ENXIO;
} }
/* /*
* Unless capExtended is set the rest of the flags should be ignored * Unless capExtended is set the rest of the flags should be ignored
*/ */
if (!SYN_CAP_EXTENDED(priv->capabilities)) if (!SYN_CAP_EXTENDED(info->capabilities))
priv->capabilities = 0; info->capabilities = 0;
if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { if (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 1) {
if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
psmouse_warn(psmouse, psmouse_warn(psmouse,
"device claims to have extended capabilities, but I'm not able to read them.\n"); "device claims to have extended capabilities, but I'm not able to read them.\n");
} else { } else {
priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; info->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
/* /*
* if nExtBtn is greater than 8 it should be considered * if nExtBtn is greater than 8 it should be considered
* invalid and treated as 0 * invalid and treated as 0
*/ */
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 8) if (SYN_CAP_MULTI_BUTTON_NO(info->ext_cap) > 8)
priv->ext_cap &= 0xff0fff; info->ext_cap &= 0xff0fff;
} }
} }
if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) { if (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 4) {
if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) { error = synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap);
if (error)
psmouse_warn(psmouse, psmouse_warn(psmouse,
"device claims to have extended capability 0x0c, but I'm not able to read it.\n"); "device claims to have extended capability 0x0c, but I'm not able to read it.\n");
} else { else
priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2]; info->ext_cap_0c =
} (cap[0] << 16) | (cap[1] << 8) | cap[2];
} }
return 0; return 0;
...@@ -369,17 +383,18 @@ static int synaptics_capability(struct psmouse *psmouse) ...@@ -369,17 +383,18 @@ static int synaptics_capability(struct psmouse *psmouse)
* Identify Touchpad * Identify Touchpad
* See also the SYN_ID_* macros * See also the SYN_ID_* macros
*/ */
static int synaptics_identify(struct psmouse *psmouse) static int synaptics_identify(struct psmouse *psmouse,
struct synaptics_device_info *info)
{ {
struct synaptics_data *priv = psmouse->private;
unsigned char id[3]; unsigned char id[3];
int error;
if (synaptics_send_cmd(psmouse, SYN_QUE_IDENTIFY, id)) error = synaptics_send_cmd(psmouse, SYN_QUE_IDENTIFY, id);
return -1; if (error)
priv->identity = (id[0]<<16) | (id[1]<<8) | id[2]; return error;
if (SYN_ID_IS_SYNAPTICS(priv->identity))
return 0; info->identity = (id[0] << 16) | (id[1] << 8) | id[2];
return -1; return SYN_ID_IS_SYNAPTICS(info->identity) ? 0 : -ENXIO;
} }
/* /*
...@@ -387,52 +402,58 @@ static int synaptics_identify(struct psmouse *psmouse) ...@@ -387,52 +402,58 @@ static int synaptics_identify(struct psmouse *psmouse)
* Resolution is left zero if touchpad does not support the query * Resolution is left zero if touchpad does not support the query
*/ */
static int synaptics_resolution(struct psmouse *psmouse) static int synaptics_resolution(struct psmouse *psmouse,
struct synaptics_device_info *info)
{ {
struct synaptics_data *priv = psmouse->private;
unsigned char resp[3]; unsigned char resp[3];
int error;
if (SYN_ID_MAJOR(priv->identity) < 4) if (SYN_ID_MAJOR(info->identity) < 4)
return 0; return 0;
if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, resp) == 0) { error = synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, resp);
if (!error) {
if (resp[0] != 0 && (resp[1] & 0x80) && resp[2] != 0) { if (resp[0] != 0 && (resp[1] & 0x80) && resp[2] != 0) {
priv->x_res = resp[0]; /* x resolution in units/mm */ info->x_res = resp[0]; /* x resolution in units/mm */
priv->y_res = resp[2]; /* y resolution in units/mm */ info->y_res = resp[2]; /* y resolution in units/mm */
} }
} }
if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && if (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 5 &&
SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { SYN_CAP_MAX_DIMENSIONS(info->ext_cap_0c)) {
if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { error = synaptics_send_cmd(psmouse,
SYN_QUE_EXT_MAX_COORDS, resp);
if (error) {
psmouse_warn(psmouse, psmouse_warn(psmouse,
"device claims to have max coordinates query, but I'm not able to read it.\n"); "device claims to have max coordinates query, but I'm not able to read it.\n");
} else { } else {
priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); info->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1);
priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); info->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3);
psmouse_info(psmouse, psmouse_info(psmouse,
"queried max coordinates: x [..%d], y [..%d]\n", "queried max coordinates: x [..%d], y [..%d]\n",
priv->x_max, priv->y_max); info->x_max, info->y_max);
} }
} }
if (SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c) && if (SYN_CAP_MIN_DIMENSIONS(info->ext_cap_0c) &&
(SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 || (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 7 ||
/* /*
* Firmware v8.1 does not report proper number of extended * Firmware v8.1 does not report proper number of extended
* capabilities, but has been proven to report correct min * capabilities, but has been proven to report correct min
* coordinates. * coordinates.
*/ */
SYN_ID_FULL(priv->identity) == 0x801)) { SYN_ID_FULL(info->identity) == 0x801)) {
if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { error = synaptics_send_cmd(psmouse,
SYN_QUE_EXT_MIN_COORDS, resp);
if (error) {
psmouse_warn(psmouse, psmouse_warn(psmouse,
"device claims to have min coordinates query, but I'm not able to read it.\n"); "device claims to have min coordinates query, but I'm not able to read it.\n");
} else { } else {
priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); info->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1);
priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); info->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3);
psmouse_info(psmouse, psmouse_info(psmouse,
"queried min coordinates: x [%d..], y [%d..]\n", "queried min coordinates: x [%d..], y [%d..]\n",
priv->x_min, priv->y_min); info->x_min, info->y_min);
} }
} }
...@@ -443,9 +464,9 @@ static int synaptics_resolution(struct psmouse *psmouse) ...@@ -443,9 +464,9 @@ static int synaptics_resolution(struct psmouse *psmouse)
* Apply quirk(s) if the hardware matches * Apply quirk(s) if the hardware matches
*/ */
static void synaptics_apply_quirks(struct psmouse *psmouse) static void synaptics_apply_quirks(struct psmouse *psmouse,
struct synaptics_device_info *info)
{ {
struct synaptics_data *priv = psmouse->private;
int i; int i;
for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) { for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) {
...@@ -454,41 +475,53 @@ static void synaptics_apply_quirks(struct psmouse *psmouse) ...@@ -454,41 +475,53 @@ static void synaptics_apply_quirks(struct psmouse *psmouse)
continue; continue;
if (min_max_pnpid_table[i].board_id.min != ANY_BOARD_ID && if (min_max_pnpid_table[i].board_id.min != ANY_BOARD_ID &&
priv->board_id < min_max_pnpid_table[i].board_id.min) info->board_id < min_max_pnpid_table[i].board_id.min)
continue; continue;
if (min_max_pnpid_table[i].board_id.max != ANY_BOARD_ID && if (min_max_pnpid_table[i].board_id.max != ANY_BOARD_ID &&
priv->board_id > min_max_pnpid_table[i].board_id.max) info->board_id > min_max_pnpid_table[i].board_id.max)
continue; continue;
priv->x_min = min_max_pnpid_table[i].x_min; info->x_min = min_max_pnpid_table[i].x_min;
priv->x_max = min_max_pnpid_table[i].x_max; info->x_max = min_max_pnpid_table[i].x_max;
priv->y_min = min_max_pnpid_table[i].y_min; info->y_min = min_max_pnpid_table[i].y_min;
priv->y_max = min_max_pnpid_table[i].y_max; info->y_max = min_max_pnpid_table[i].y_max;
psmouse_info(psmouse, psmouse_info(psmouse,
"quirked min/max coordinates: x [%d..%d], y [%d..%d]\n", "quirked min/max coordinates: x [%d..%d], y [%d..%d]\n",
priv->x_min, priv->x_max, info->x_min, info->x_max,
priv->y_min, priv->y_max); info->y_min, info->y_max);
break; break;
} }
} }
static int synaptics_query_hardware(struct psmouse *psmouse) static int synaptics_query_hardware(struct psmouse *psmouse,
struct synaptics_device_info *info)
{ {
if (synaptics_identify(psmouse)) int error;
return -1;
if (synaptics_model_id(psmouse)) error = synaptics_identify(psmouse, info);
return -1; if (error)
if (synaptics_firmware_id(psmouse)) return error;
return -1;
if (synaptics_query_modes(psmouse))
return -1;
if (synaptics_capability(psmouse))
return -1;
if (synaptics_resolution(psmouse))
return -1;
synaptics_apply_quirks(psmouse); error = synaptics_model_id(psmouse, info);
if (error)
return error;
error = synaptics_firmware_id(psmouse, info);
if (error)
return error;
error = synaptics_query_modes(psmouse, info);
if (error)
return error;
error = synaptics_capability(psmouse, info);
if (error)
return error;
error = synaptics_resolution(psmouse, info);
if (error)
return error;
return 0; return 0;
} }
...@@ -498,8 +531,8 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) ...@@ -498,8 +531,8 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
static unsigned char param = 0xc8; static unsigned char param = 0xc8;
struct synaptics_data *priv = psmouse->private; struct synaptics_data *priv = psmouse->private;
if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || if (!(SYN_CAP_ADV_GESTURE(priv->info.ext_cap_0c) ||
SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c))) SYN_CAP_IMAGE_SENSOR(priv->info.ext_cap_0c)))
return 0; return 0;
if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))
...@@ -509,7 +542,7 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) ...@@ -509,7 +542,7 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
return -1; return -1;
/* Advanced gesture mode also sends multi finger data */ /* Advanced gesture mode also sends multi finger data */
priv->capabilities |= BIT(1); priv->info.capabilities |= BIT(1);
return 0; return 0;
} }
...@@ -525,7 +558,7 @@ static int synaptics_set_mode(struct psmouse *psmouse) ...@@ -525,7 +558,7 @@ static int synaptics_set_mode(struct psmouse *psmouse)
priv->mode |= SYN_BIT_DISABLE_GESTURE; priv->mode |= SYN_BIT_DISABLE_GESTURE;
if (psmouse->rate >= 80) if (psmouse->rate >= 80)
priv->mode |= SYN_BIT_HIGH_RATE; priv->mode |= SYN_BIT_HIGH_RATE;
if (SYN_CAP_EXTENDED(priv->capabilities)) if (SYN_CAP_EXTENDED(priv->info.capabilities))
priv->mode |= SYN_BIT_W_MODE; priv->mode |= SYN_BIT_W_MODE;
if (synaptics_mode_cmd(psmouse, priv->mode)) if (synaptics_mode_cmd(psmouse, priv->mode))
...@@ -693,7 +726,7 @@ static void synaptics_parse_ext_buttons(const unsigned char buf[], ...@@ -693,7 +726,7 @@ static void synaptics_parse_ext_buttons(const unsigned char buf[],
struct synaptics_hw_state *hw) struct synaptics_hw_state *hw)
{ {
unsigned int ext_bits = unsigned int ext_bits =
(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; (SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap) + 1) >> 1;
unsigned int ext_mask = GENMASK(ext_bits - 1, 0); unsigned int ext_mask = GENMASK(ext_bits - 1, 0);
hw->ext_buttons = buf[4] & ext_mask; hw->ext_buttons = buf[4] & ext_mask;
...@@ -706,13 +739,13 @@ static int synaptics_parse_hw_state(const unsigned char buf[], ...@@ -706,13 +739,13 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
{ {
memset(hw, 0, sizeof(struct synaptics_hw_state)); memset(hw, 0, sizeof(struct synaptics_hw_state));
if (SYN_MODEL_NEWABS(priv->model_id)) { if (SYN_MODEL_NEWABS(priv->info.model_id)) {
hw->w = (((buf[0] & 0x30) >> 2) | hw->w = (((buf[0] & 0x30) >> 2) |
((buf[0] & 0x04) >> 1) | ((buf[0] & 0x04) >> 1) |
((buf[3] & 0x04) >> 2)); ((buf[3] & 0x04) >> 2));
if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || if ((SYN_CAP_ADV_GESTURE(priv->info.ext_cap_0c) ||
SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) && SYN_CAP_IMAGE_SENSOR(priv->info.ext_cap_0c)) &&
hw->w == 2) { hw->w == 2) {
synaptics_parse_agm(buf, priv, hw); synaptics_parse_agm(buf, priv, hw);
return 1; return 1;
...@@ -765,7 +798,7 @@ static int synaptics_parse_hw_state(const unsigned char buf[], ...@@ -765,7 +798,7 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
hw->left = priv->report_press; hw->left = priv->report_press;
} else if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { } else if (SYN_CAP_CLICKPAD(priv->info.ext_cap_0c)) {
/* /*
* Clickpad's button is transmitted as middle button, * Clickpad's button is transmitted as middle button,
* however, since it is primary button, we will report * however, since it is primary button, we will report
...@@ -773,18 +806,18 @@ static int synaptics_parse_hw_state(const unsigned char buf[], ...@@ -773,18 +806,18 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
*/ */
hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
} else if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { } else if (SYN_CAP_MIDDLE_BUTTON(priv->info.capabilities)) {
hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
if (hw->w == 2) if (hw->w == 2)
hw->scroll = (signed char)(buf[1]); hw->scroll = (signed char)(buf[1]);
} }
if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { if (SYN_CAP_FOUR_BUTTON(priv->info.capabilities)) {
hw->up = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; hw->up = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
} }
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 0 && if (SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap) > 0 &&
((buf[0] ^ buf[3]) & 0x02)) { ((buf[0] ^ buf[3]) & 0x02)) {
synaptics_parse_ext_buttons(buf, priv, hw); synaptics_parse_ext_buttons(buf, priv, hw);
} }
...@@ -853,19 +886,19 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse, ...@@ -853,19 +886,19 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse,
{ {
struct input_dev *dev = psmouse->dev; struct input_dev *dev = psmouse->dev;
struct synaptics_data *priv = psmouse->private; struct synaptics_data *priv = psmouse->private;
int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap) + 1) >> 1;
int i; int i;
if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) if (!SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap))
return; return;
/* Bug in FW 8.1 & 8.2, buttons are reported only when ExtBit is 1 */ /* Bug in FW 8.1 & 8.2, buttons are reported only when ExtBit is 1 */
if ((SYN_ID_FULL(priv->identity) == 0x801 || if ((SYN_ID_FULL(priv->info.identity) == 0x801 ||
SYN_ID_FULL(priv->identity) == 0x802) && SYN_ID_FULL(priv->info.identity) == 0x802) &&
!((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02))
return; return;
if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) { if (!SYN_CAP_EXT_BUTTONS_STICK(priv->info.ext_cap_10)) {
for (i = 0; i < ext_bits; i++) { for (i = 0; i < ext_bits; i++) {
input_report_key(dev, BTN_0 + 2 * i, input_report_key(dev, BTN_0 + 2 * i,
hw->ext_buttons & (1 << i)); hw->ext_buttons & (1 << i));
...@@ -903,10 +936,10 @@ static void synaptics_report_buttons(struct psmouse *psmouse, ...@@ -903,10 +936,10 @@ static void synaptics_report_buttons(struct psmouse *psmouse,
input_report_key(dev, BTN_LEFT, hw->left); input_report_key(dev, BTN_LEFT, hw->left);
input_report_key(dev, BTN_RIGHT, hw->right); input_report_key(dev, BTN_RIGHT, hw->right);
if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) if (SYN_CAP_MIDDLE_BUTTON(priv->info.capabilities))
input_report_key(dev, BTN_MIDDLE, hw->middle); input_report_key(dev, BTN_MIDDLE, hw->middle);
if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { if (SYN_CAP_FOUR_BUTTON(priv->info.capabilities)) {
input_report_key(dev, BTN_FORWARD, hw->up); input_report_key(dev, BTN_FORWARD, hw->up);
input_report_key(dev, BTN_BACK, hw->down); input_report_key(dev, BTN_BACK, hw->down);
} }
...@@ -931,7 +964,7 @@ static void synaptics_report_mt_data(struct psmouse *psmouse, ...@@ -931,7 +964,7 @@ static void synaptics_report_mt_data(struct psmouse *psmouse,
pos[i].y = synaptics_invert_y(hw[i]->y); pos[i].y = synaptics_invert_y(hw[i]->y);
} }
input_mt_assign_slots(dev, slot, pos, nsemi, DMAX * priv->x_res); input_mt_assign_slots(dev, slot, pos, nsemi, DMAX * priv->info.x_res);
for (i = 0; i < nsemi; i++) { for (i = 0; i < nsemi; i++) {
input_mt_slot(dev, slot[i]); input_mt_slot(dev, slot[i]);
...@@ -985,6 +1018,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) ...@@ -985,6 +1018,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
{ {
struct input_dev *dev = psmouse->dev; struct input_dev *dev = psmouse->dev;
struct synaptics_data *priv = psmouse->private; struct synaptics_data *priv = psmouse->private;
struct synaptics_device_info *info = &priv->info;
struct synaptics_hw_state hw; struct synaptics_hw_state hw;
int num_fingers; int num_fingers;
int finger_width; int finger_width;
...@@ -992,7 +1026,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) ...@@ -992,7 +1026,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
if (synaptics_parse_hw_state(psmouse->packet, priv, &hw)) if (synaptics_parse_hw_state(psmouse->packet, priv, &hw))
return; return;
if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { if (SYN_CAP_IMAGE_SENSOR(info->ext_cap_0c)) {
synaptics_image_sensor_process(psmouse, &hw); synaptics_image_sensor_process(psmouse, &hw);
return; return;
} }
...@@ -1020,18 +1054,18 @@ static void synaptics_process_packet(struct psmouse *psmouse) ...@@ -1020,18 +1054,18 @@ static void synaptics_process_packet(struct psmouse *psmouse)
if (hw.z > 0 && hw.x > 1) { if (hw.z > 0 && hw.x > 1) {
num_fingers = 1; num_fingers = 1;
finger_width = 5; finger_width = 5;
if (SYN_CAP_EXTENDED(priv->capabilities)) { if (SYN_CAP_EXTENDED(info->capabilities)) {
switch (hw.w) { switch (hw.w) {
case 0 ... 1: case 0 ... 1:
if (SYN_CAP_MULTIFINGER(priv->capabilities)) if (SYN_CAP_MULTIFINGER(info->capabilities))
num_fingers = hw.w + 2; num_fingers = hw.w + 2;
break; break;
case 2: case 2:
if (SYN_MODEL_PEN(priv->model_id)) if (SYN_MODEL_PEN(info->model_id))
; /* Nothing, treat a pen as a single finger */ ; /* Nothing, treat a pen as a single finger */
break; break;
case 4 ... 15: case 4 ... 15:
if (SYN_CAP_PALMDETECT(priv->capabilities)) if (SYN_CAP_PALMDETECT(info->capabilities))
finger_width = hw.w; finger_width = hw.w;
break; break;
} }
...@@ -1046,7 +1080,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) ...@@ -1046,7 +1080,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
return; return;
} }
if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) if (SYN_CAP_ADV_GESTURE(info->ext_cap_0c))
synaptics_report_semi_mt_data(dev, &hw, &priv->agm, synaptics_report_semi_mt_data(dev, &hw, &priv->agm,
num_fingers); num_fingers);
...@@ -1063,11 +1097,11 @@ static void synaptics_process_packet(struct psmouse *psmouse) ...@@ -1063,11 +1097,11 @@ static void synaptics_process_packet(struct psmouse *psmouse)
} }
input_report_abs(dev, ABS_PRESSURE, hw.z); input_report_abs(dev, ABS_PRESSURE, hw.z);
if (SYN_CAP_PALMDETECT(priv->capabilities)) if (SYN_CAP_PALMDETECT(info->capabilities))
input_report_abs(dev, ABS_TOOL_WIDTH, finger_width); input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1); input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
if (SYN_CAP_MULTIFINGER(priv->capabilities)) { if (SYN_CAP_MULTIFINGER(info->capabilities)) {
input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
} }
...@@ -1129,7 +1163,7 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) ...@@ -1129,7 +1163,7 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
if (unlikely(priv->pkt_type == SYN_NEWABS)) if (unlikely(priv->pkt_type == SYN_NEWABS))
priv->pkt_type = synaptics_detect_pkt_type(psmouse); priv->pkt_type = synaptics_detect_pkt_type(psmouse);
if (SYN_CAP_PASS_THROUGH(priv->capabilities) && if (SYN_CAP_PASS_THROUGH(priv->info.capabilities) &&
synaptics_is_pt_packet(psmouse->packet)) { synaptics_is_pt_packet(psmouse->packet)) {
if (priv->pt_port) if (priv->pt_port)
synaptics_pass_pt_packet(priv->pt_port, synaptics_pass_pt_packet(priv->pt_port,
...@@ -1148,26 +1182,27 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) ...@@ -1148,26 +1182,27 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
* Driver initialization/cleanup functions * Driver initialization/cleanup functions
****************************************************************************/ ****************************************************************************/
static void set_abs_position_params(struct input_dev *dev, static void set_abs_position_params(struct input_dev *dev,
struct synaptics_data *priv, int x_code, struct synaptics_device_info *info,
int y_code) int x_code, int y_code)
{ {
int x_min = priv->x_min ?: XMIN_NOMINAL; int x_min = info->x_min ?: XMIN_NOMINAL;
int x_max = priv->x_max ?: XMAX_NOMINAL; int x_max = info->x_max ?: XMAX_NOMINAL;
int y_min = priv->y_min ?: YMIN_NOMINAL; int y_min = info->y_min ?: YMIN_NOMINAL;
int y_max = priv->y_max ?: YMAX_NOMINAL; int y_max = info->y_max ?: YMAX_NOMINAL;
int fuzz = SYN_CAP_REDUCED_FILTERING(priv->ext_cap_0c) ? int fuzz = SYN_CAP_REDUCED_FILTERING(info->ext_cap_0c) ?
SYN_REDUCED_FILTER_FUZZ : 0; SYN_REDUCED_FILTER_FUZZ : 0;
input_set_abs_params(dev, x_code, x_min, x_max, fuzz, 0); input_set_abs_params(dev, x_code, x_min, x_max, fuzz, 0);
input_set_abs_params(dev, y_code, y_min, y_max, fuzz, 0); input_set_abs_params(dev, y_code, y_min, y_max, fuzz, 0);
input_abs_set_res(dev, x_code, priv->x_res); input_abs_set_res(dev, x_code, info->x_res);
input_abs_set_res(dev, y_code, priv->y_res); input_abs_set_res(dev, y_code, info->y_res);
} }
static void set_input_params(struct psmouse *psmouse, static void set_input_params(struct psmouse *psmouse,
struct synaptics_data *priv) struct synaptics_data *priv)
{ {
struct input_dev *dev = psmouse->dev; struct input_dev *dev = psmouse->dev;
struct synaptics_device_info *info = &priv->info;
int i; int i;
/* Things that apply to both modes */ /* Things that apply to both modes */
...@@ -1176,7 +1211,7 @@ static void set_input_params(struct psmouse *psmouse, ...@@ -1176,7 +1211,7 @@ static void set_input_params(struct psmouse *psmouse,
__set_bit(BTN_LEFT, dev->keybit); __set_bit(BTN_LEFT, dev->keybit);
__set_bit(BTN_RIGHT, dev->keybit); __set_bit(BTN_RIGHT, dev->keybit);
if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) if (SYN_CAP_MIDDLE_BUTTON(info->capabilities))
__set_bit(BTN_MIDDLE, dev->keybit); __set_bit(BTN_MIDDLE, dev->keybit);
if (!priv->absolute_mode) { if (!priv->absolute_mode) {
...@@ -1189,15 +1224,15 @@ static void set_input_params(struct psmouse *psmouse, ...@@ -1189,15 +1224,15 @@ static void set_input_params(struct psmouse *psmouse,
/* Absolute mode */ /* Absolute mode */
__set_bit(EV_ABS, dev->evbit); __set_bit(EV_ABS, dev->evbit);
set_abs_position_params(dev, priv, ABS_X, ABS_Y); set_abs_position_params(dev, &priv->info, ABS_X, ABS_Y);
input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
if (cr48_profile_sensor) if (cr48_profile_sensor)
input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { if (SYN_CAP_IMAGE_SENSOR(info->ext_cap_0c)) {
set_abs_position_params(dev, priv, ABS_MT_POSITION_X, set_abs_position_params(dev, info,
ABS_MT_POSITION_Y); ABS_MT_POSITION_X, ABS_MT_POSITION_Y);
/* Image sensors can report per-contact pressure */ /* Image sensors can report per-contact pressure */
input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
input_mt_init_slots(dev, 2, INPUT_MT_POINTER | INPUT_MT_TRACK); input_mt_init_slots(dev, 2, INPUT_MT_POINTER | INPUT_MT_TRACK);
...@@ -1205,9 +1240,9 @@ static void set_input_params(struct psmouse *psmouse, ...@@ -1205,9 +1240,9 @@ static void set_input_params(struct psmouse *psmouse,
/* Image sensors can signal 4 and 5 finger clicks */ /* Image sensors can signal 4 and 5 finger clicks */
__set_bit(BTN_TOOL_QUADTAP, dev->keybit); __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
__set_bit(BTN_TOOL_QUINTTAP, dev->keybit); __set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
} else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { } else if (SYN_CAP_ADV_GESTURE(info->ext_cap_0c)) {
set_abs_position_params(dev, priv, ABS_MT_POSITION_X, set_abs_position_params(dev, info,
ABS_MT_POSITION_Y); ABS_MT_POSITION_X, ABS_MT_POSITION_Y);
/* /*
* Profile sensor in CR-48 tracks contacts reasonably well, * Profile sensor in CR-48 tracks contacts reasonably well,
* other non-image sensors with AGM use semi-mt. * other non-image sensors with AGM use semi-mt.
...@@ -1218,35 +1253,35 @@ static void set_input_params(struct psmouse *psmouse, ...@@ -1218,35 +1253,35 @@ static void set_input_params(struct psmouse *psmouse,
INPUT_MT_TRACK : INPUT_MT_SEMI_MT)); INPUT_MT_TRACK : INPUT_MT_SEMI_MT));
} }
if (SYN_CAP_PALMDETECT(priv->capabilities)) if (SYN_CAP_PALMDETECT(info->capabilities))
input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
__set_bit(BTN_TOUCH, dev->keybit); __set_bit(BTN_TOUCH, dev->keybit);
__set_bit(BTN_TOOL_FINGER, dev->keybit); __set_bit(BTN_TOOL_FINGER, dev->keybit);
if (SYN_CAP_MULTIFINGER(priv->capabilities)) { if (SYN_CAP_MULTIFINGER(info->capabilities)) {
__set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
__set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
} }
if (SYN_CAP_FOUR_BUTTON(priv->capabilities) || if (SYN_CAP_FOUR_BUTTON(info->capabilities) ||
SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { SYN_CAP_MIDDLE_BUTTON(info->capabilities)) {
__set_bit(BTN_FORWARD, dev->keybit); __set_bit(BTN_FORWARD, dev->keybit);
__set_bit(BTN_BACK, dev->keybit); __set_bit(BTN_BACK, dev->keybit);
} }
if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) if (!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(info->ext_cap); i++)
__set_bit(BTN_0 + i, dev->keybit); __set_bit(BTN_0 + i, dev->keybit);
__clear_bit(EV_REL, dev->evbit); __clear_bit(EV_REL, dev->evbit);
__clear_bit(REL_X, dev->relbit); __clear_bit(REL_X, dev->relbit);
__clear_bit(REL_Y, dev->relbit); __clear_bit(REL_Y, dev->relbit);
if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { if (SYN_CAP_CLICKPAD(info->ext_cap_0c)) {
__set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) && if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) &&
!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) !SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
__set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit); __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit);
/* Clickpads report only left button */ /* Clickpads report only left button */
__clear_bit(BTN_RIGHT, dev->keybit); __clear_bit(BTN_RIGHT, dev->keybit);
...@@ -1300,7 +1335,8 @@ static void synaptics_disconnect(struct psmouse *psmouse) ...@@ -1300,7 +1335,8 @@ static void synaptics_disconnect(struct psmouse *psmouse)
{ {
struct synaptics_data *priv = psmouse->private; struct synaptics_data *priv = psmouse->private;
if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(priv->identity)) if (!priv->absolute_mode &&
SYN_ID_DISGEST_SUPPORTED(priv->info.identity))
device_remove_file(&psmouse->ps2dev.serio->dev, device_remove_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_disable_gesture.dattr); &psmouse_attr_disable_gesture.dattr);
...@@ -1312,7 +1348,7 @@ static void synaptics_disconnect(struct psmouse *psmouse) ...@@ -1312,7 +1348,7 @@ static void synaptics_disconnect(struct psmouse *psmouse)
static int synaptics_reconnect(struct psmouse *psmouse) static int synaptics_reconnect(struct psmouse *psmouse)
{ {
struct synaptics_data *priv = psmouse->private; struct synaptics_data *priv = psmouse->private;
struct synaptics_data old_priv = *priv; struct synaptics_device_info info;
unsigned char param[2]; unsigned char param[2];
int retry = 0; int retry = 0;
int error; int error;
...@@ -1339,7 +1375,7 @@ static int synaptics_reconnect(struct psmouse *psmouse) ...@@ -1339,7 +1375,7 @@ static int synaptics_reconnect(struct psmouse *psmouse)
if (retry > 1) if (retry > 1)
psmouse_dbg(psmouse, "reconnected after %d tries\n", retry); psmouse_dbg(psmouse, "reconnected after %d tries\n", retry);
if (synaptics_query_hardware(psmouse)) { if (synaptics_query_hardware(psmouse, &info)) {
psmouse_err(psmouse, "Unable to query device.\n"); psmouse_err(psmouse, "Unable to query device.\n");
return -1; return -1;
} }
...@@ -1349,16 +1385,16 @@ static int synaptics_reconnect(struct psmouse *psmouse) ...@@ -1349,16 +1385,16 @@ static int synaptics_reconnect(struct psmouse *psmouse)
return -1; return -1;
} }
if (old_priv.identity != priv->identity || if (info.identity != priv->info.identity ||
old_priv.model_id != priv->model_id || info.model_id != priv->info.model_id ||
old_priv.capabilities != priv->capabilities || info.capabilities != priv->info.capabilities ||
old_priv.ext_cap != priv->ext_cap) { info.ext_cap != priv->info.ext_cap) {
psmouse_err(psmouse, psmouse_err(psmouse,
"hardware appears to be different: id(%ld-%ld), model(%ld-%ld), caps(%lx-%lx), ext(%lx-%lx).\n", "hardware appears to be different: id(%u-%u), model(%u-%u), caps(%x-%x), ext(%x-%x).\n",
old_priv.identity, priv->identity, priv->info.identity, info.identity,
old_priv.model_id, priv->model_id, priv->info.model_id, info.model_id,
old_priv.capabilities, priv->capabilities, priv->info.capabilities, info.capabilities,
old_priv.ext_cap, priv->ext_cap); priv->info.ext_cap, info.ext_cap);
return -1; return -1;
} }
...@@ -1442,6 +1478,7 @@ void __init synaptics_module_init(void) ...@@ -1442,6 +1478,7 @@ void __init synaptics_module_init(void)
static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
{ {
struct synaptics_data *priv; struct synaptics_data *priv;
struct synaptics_device_info *info;
int err = -1; int err = -1;
/* /*
...@@ -1460,15 +1497,19 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) ...@@ -1460,15 +1497,19 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
info = &priv->info;
psmouse_reset(psmouse); psmouse_reset(psmouse);
if (synaptics_query_hardware(psmouse)) { if (synaptics_query_hardware(psmouse, info)) {
psmouse_err(psmouse, "Unable to query device.\n"); psmouse_err(psmouse, "Unable to query device.\n");
goto init_fail; goto init_fail;
} }
synaptics_apply_quirks(psmouse, info);
priv->absolute_mode = absolute_mode; priv->absolute_mode = absolute_mode;
if (SYN_ID_DISGEST_SUPPORTED(priv->identity)) if (SYN_ID_DISGEST_SUPPORTED(info->identity))
priv->disable_gesture = true; priv->disable_gesture = true;
/* /*
...@@ -1482,15 +1523,16 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) ...@@ -1482,15 +1523,16 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
goto init_fail; goto init_fail;
} }
priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; priv->pkt_type = SYN_MODEL_NEWABS(info->model_id) ?
SYN_NEWABS : SYN_OLDABS;
psmouse_info(psmouse, psmouse_info(psmouse,
"Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx/%#lx, board id: %lu, fw id: %lu\n", "Touchpad model: %u, fw: %u.%u, id: %#x, caps: %#x/%#x/%#x/%#x, board id: %u, fw id: %u\n",
SYN_ID_MODEL(priv->identity), SYN_ID_MODEL(info->identity),
SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), SYN_ID_MAJOR(info->identity), SYN_ID_MINOR(info->identity),
priv->model_id, info->model_id,
priv->capabilities, priv->ext_cap, priv->ext_cap_0c, info->capabilities, info->ext_cap, info->ext_cap_0c,
priv->ext_cap_10, priv->board_id, priv->firmware_id); info->ext_cap_10, info->board_id, info->firmware_id);
set_input_params(psmouse, priv); set_input_params(psmouse, priv);
...@@ -1501,8 +1543,8 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) ...@@ -1501,8 +1543,8 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
* Hardware info bits seem to be good candidates as they * Hardware info bits seem to be good candidates as they
* are documented to be for Synaptics corp. internal use. * are documented to be for Synaptics corp. internal use.
*/ */
psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) | psmouse->model = ((info->model_id & 0x00ff0000) >> 8) |
(priv->model_id & 0x000000ff); (info->model_id & 0x000000ff);
if (absolute_mode) { if (absolute_mode) {
psmouse->protocol_handler = synaptics_process_byte; psmouse->protocol_handler = synaptics_process_byte;
...@@ -1520,7 +1562,7 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) ...@@ -1520,7 +1562,7 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
/* Synaptics can usually stay in sync without extra help */ /* Synaptics can usually stay in sync without extra help */
psmouse->resync_time = 0; psmouse->resync_time = 0;
if (SYN_CAP_PASS_THROUGH(priv->capabilities)) if (SYN_CAP_PASS_THROUGH(info->capabilities))
synaptics_pt_create(psmouse); synaptics_pt_create(psmouse);
/* /*
...@@ -1535,7 +1577,7 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) ...@@ -1535,7 +1577,7 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
psmouse->rate = 40; psmouse->rate = 40;
} }
if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(priv->identity)) { if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(info->identity)) {
err = device_create_file(&psmouse->ps2dev.serio->dev, err = device_create_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_disable_gesture.dattr); &psmouse_attr_disable_gesture.dattr);
if (err) { if (err) {
......
...@@ -161,19 +161,23 @@ struct synaptics_hw_state { ...@@ -161,19 +161,23 @@ struct synaptics_hw_state {
signed char scroll; signed char scroll;
}; };
/* Data read from the touchpad */
struct synaptics_device_info {
u32 model_id; /* Model-ID */
u32 firmware_id; /* Firmware-ID */
u32 board_id; /* Board-ID */
u32 capabilities; /* Capabilities */
u32 ext_cap; /* Extended Capabilities */
u32 ext_cap_0c; /* Ext Caps from 0x0c query */
u32 ext_cap_10; /* Ext Caps from 0x10 query */
u32 identity; /* Identification */
u32 x_res, y_res; /* X/Y resolution in units/mm */
u32 x_max, y_max; /* Max coordinates (from FW) */
u32 x_min, y_min; /* Min coordinates (from FW) */
};
struct synaptics_data { struct synaptics_data {
/* Data read from the touchpad */ struct synaptics_device_info info;
unsigned long int model_id; /* Model-ID */
unsigned long int firmware_id; /* Firmware-ID */
unsigned long int board_id; /* Board-ID */
unsigned long int capabilities; /* Capabilities */
unsigned long int ext_cap; /* Extended Capabilities */
unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */
unsigned long int ext_cap_10; /* Ext Caps from 0x10 query */
unsigned long int identity; /* Identification */
unsigned int x_res, y_res; /* X/Y resolution in units/mm */
unsigned int x_max, y_max; /* Max coordinates (from FW) */
unsigned int x_min, y_min; /* Min coordinates (from FW) */
unsigned char pkt_type; /* packet type - old, new, etc */ unsigned char pkt_type; /* packet type - old, new, etc */
unsigned char mode; /* current mode byte */ unsigned char mode; /* current mode byte */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment