|
@@ -418,6 +418,49 @@ int psmouse_reset(struct psmouse *psmouse)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Here we set the mouse resolution.
|
|
|
+ */
|
|
|
+
|
|
|
+void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
|
|
|
+{
|
|
|
+ static const unsigned char params[] = { 0, 1, 2, 2, 3 };
|
|
|
+ unsigned char p;
|
|
|
+
|
|
|
+ if (resolution == 0 || resolution > 200)
|
|
|
+ resolution = 200;
|
|
|
+
|
|
|
+ p = params[resolution / 50];
|
|
|
+ ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
|
|
|
+ psmouse->resolution = 25 << p;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Here we set the mouse report rate.
|
|
|
+ */
|
|
|
+
|
|
|
+static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
|
|
|
+{
|
|
|
+ static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
|
|
|
+ unsigned char r;
|
|
|
+ int i = 0;
|
|
|
+
|
|
|
+ while (rates[i] > rate) i++;
|
|
|
+ r = rates[i];
|
|
|
+ ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
|
|
|
+ psmouse->rate = r;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
|
|
|
+ */
|
|
|
+
|
|
|
+static int psmouse_poll(struct psmouse *psmouse)
|
|
|
+{
|
|
|
+ return ps2_command(&psmouse->ps2dev, psmouse->packet,
|
|
|
+ PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
/*
|
|
|
* Genius NetMouse magic init.
|
|
@@ -602,6 +645,56 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Apply default settings to the psmouse structure. Most of them will
|
|
|
+ * be overridden by individual protocol initialization routines.
|
|
|
+ */
|
|
|
+
|
|
|
+static void psmouse_apply_defaults(struct psmouse *psmouse)
|
|
|
+{
|
|
|
+ struct input_dev *input_dev = psmouse->dev;
|
|
|
+
|
|
|
+ memset(input_dev->evbit, 0, sizeof(input_dev->evbit));
|
|
|
+ memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
|
|
|
+ memset(input_dev->relbit, 0, sizeof(input_dev->relbit));
|
|
|
+ memset(input_dev->absbit, 0, sizeof(input_dev->absbit));
|
|
|
+ memset(input_dev->mscbit, 0, sizeof(input_dev->mscbit));
|
|
|
+
|
|
|
+ __set_bit(EV_KEY, input_dev->evbit);
|
|
|
+ __set_bit(EV_REL, input_dev->evbit);
|
|
|
+
|
|
|
+ __set_bit(BTN_LEFT, input_dev->keybit);
|
|
|
+ __set_bit(BTN_RIGHT, input_dev->keybit);
|
|
|
+
|
|
|
+ __set_bit(REL_X, input_dev->relbit);
|
|
|
+ __set_bit(REL_Y, input_dev->relbit);
|
|
|
+
|
|
|
+ psmouse->set_rate = psmouse_set_rate;
|
|
|
+ psmouse->set_resolution = psmouse_set_resolution;
|
|
|
+ psmouse->poll = psmouse_poll;
|
|
|
+ psmouse->protocol_handler = psmouse_process_byte;
|
|
|
+ psmouse->pktsize = 3;
|
|
|
+ psmouse->reconnect = NULL;
|
|
|
+ psmouse->disconnect = NULL;
|
|
|
+ psmouse->cleanup = NULL;
|
|
|
+ psmouse->pt_activate = NULL;
|
|
|
+ psmouse->pt_deactivate = NULL;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Apply default settings to the psmouse structure and call specified
|
|
|
+ * protocol detection or initialization routine.
|
|
|
+ */
|
|
|
+static int psmouse_do_detect(int (*detect)(struct psmouse *psmouse,
|
|
|
+ bool set_properties),
|
|
|
+ struct psmouse *psmouse, bool set_properties)
|
|
|
+{
|
|
|
+ if (set_properties)
|
|
|
+ psmouse_apply_defaults(psmouse);
|
|
|
+
|
|
|
+ return detect(psmouse, set_properties);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* psmouse_extensions() probes for any extensions to the basic PS/2 protocol
|
|
|
* the mouse may have.
|
|
@@ -616,7 +709,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|
|
* We always check for lifebook because it does not disturb mouse
|
|
|
* (it only checks DMI information).
|
|
|
*/
|
|
|
- if (lifebook_detect(psmouse, set_properties) == 0) {
|
|
|
+ if (psmouse_do_detect(lifebook_detect, psmouse, set_properties) == 0) {
|
|
|
if (max_proto > PSMOUSE_IMEX) {
|
|
|
if (!set_properties || lifebook_init(psmouse) == 0)
|
|
|
return PSMOUSE_LIFEBOOK;
|
|
@@ -628,15 +721,18 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|
|
* upsets the thinkingmouse).
|
|
|
*/
|
|
|
|
|
|
- if (max_proto > PSMOUSE_IMEX && thinking_detect(psmouse, set_properties) == 0)
|
|
|
+ if (max_proto > PSMOUSE_IMEX &&
|
|
|
+ psmouse_do_detect(thinking_detect, psmouse, set_properties) == 0) {
|
|
|
return PSMOUSE_THINKPS;
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol
|
|
|
* support is disabled in config - we need to know if it is synaptics so we
|
|
|
* can reset it properly after probing for intellimouse.
|
|
|
*/
|
|
|
- if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) {
|
|
|
+ if (max_proto > PSMOUSE_PS2 &&
|
|
|
+ psmouse_do_detect(synaptics_detect, psmouse, set_properties) == 0) {
|
|
|
synaptics_hardware = true;
|
|
|
|
|
|
if (max_proto > PSMOUSE_IMEX) {
|
|
@@ -667,7 +763,8 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|
|
*/
|
|
|
if (max_proto > PSMOUSE_IMEX) {
|
|
|
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
|
|
|
- if (alps_detect(psmouse, set_properties) == 0) {
|
|
|
+ if (psmouse_do_detect(alps_detect,
|
|
|
+ psmouse, set_properties) == 0) {
|
|
|
if (!set_properties || alps_init(psmouse) == 0)
|
|
|
return PSMOUSE_ALPS;
|
|
|
/*
|
|
@@ -681,7 +778,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|
|
* Try OLPC HGPK touchpad.
|
|
|
*/
|
|
|
if (max_proto > PSMOUSE_IMEX &&
|
|
|
- hgpk_detect(psmouse, set_properties) == 0) {
|
|
|
+ psmouse_do_detect(hgpk_detect, psmouse, set_properties) == 0) {
|
|
|
if (!set_properties || hgpk_init(psmouse) == 0)
|
|
|
return PSMOUSE_HGPK;
|
|
|
/*
|
|
@@ -694,7 +791,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|
|
* Try Elantech touchpad.
|
|
|
*/
|
|
|
if (max_proto > PSMOUSE_IMEX &&
|
|
|
- elantech_detect(psmouse, set_properties) == 0) {
|
|
|
+ psmouse_do_detect(elantech_detect, psmouse, set_properties) == 0) {
|
|
|
if (!set_properties || elantech_init(psmouse) == 0)
|
|
|
return PSMOUSE_ELANTECH;
|
|
|
/*
|
|
@@ -703,18 +800,21 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|
|
max_proto = PSMOUSE_IMEX;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
if (max_proto > PSMOUSE_IMEX) {
|
|
|
- if (genius_detect(psmouse, set_properties) == 0)
|
|
|
+ if (psmouse_do_detect(genius_detect,
|
|
|
+ psmouse, set_properties) == 0)
|
|
|
return PSMOUSE_GENPS;
|
|
|
|
|
|
- if (ps2pp_init(psmouse, set_properties) == 0)
|
|
|
+ if (psmouse_do_detect(ps2pp_init,
|
|
|
+ psmouse, set_properties) == 0)
|
|
|
return PSMOUSE_PS2PP;
|
|
|
|
|
|
- if (trackpoint_detect(psmouse, set_properties) == 0)
|
|
|
+ if (psmouse_do_detect(trackpoint_detect,
|
|
|
+ psmouse, set_properties) == 0)
|
|
|
return PSMOUSE_TRACKPOINT;
|
|
|
|
|
|
- if (touchkit_ps2_detect(psmouse, set_properties) == 0)
|
|
|
+ if (psmouse_do_detect(touchkit_ps2_detect,
|
|
|
+ psmouse, set_properties) == 0)
|
|
|
return PSMOUSE_TOUCHKIT_PS2;
|
|
|
}
|
|
|
|
|
@@ -723,7 +823,8 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|
|
* Trackpoint devices (causing TP_READ_ID command to time out).
|
|
|
*/
|
|
|
if (max_proto > PSMOUSE_IMEX) {
|
|
|
- if (fsp_detect(psmouse, set_properties) == 0) {
|
|
|
+ if (psmouse_do_detect(fsp_detect,
|
|
|
+ psmouse, set_properties) == 0) {
|
|
|
if (!set_properties || fsp_init(psmouse) == 0)
|
|
|
return PSMOUSE_FSP;
|
|
|
/*
|
|
@@ -741,17 +842,23 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|
|
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
|
|
|
psmouse_reset(psmouse);
|
|
|
|
|
|
- if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0)
|
|
|
+ if (max_proto >= PSMOUSE_IMEX &&
|
|
|
+ psmouse_do_detect(im_explorer_detect,
|
|
|
+ psmouse, set_properties) == 0) {
|
|
|
return PSMOUSE_IMEX;
|
|
|
+ }
|
|
|
|
|
|
- if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse, set_properties) == 0)
|
|
|
+ if (max_proto >= PSMOUSE_IMPS &&
|
|
|
+ psmouse_do_detect(intellimouse_detect,
|
|
|
+ psmouse, set_properties) == 0) {
|
|
|
return PSMOUSE_IMPS;
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* Okay, all failed, we have a standard mouse here. The number of the buttons
|
|
|
* is still a question, though. We assume 3.
|
|
|
*/
|
|
|
- ps2bare_detect(psmouse, set_properties);
|
|
|
+ psmouse_do_detect(ps2bare_detect, psmouse, set_properties);
|
|
|
|
|
|
if (synaptics_hardware) {
|
|
|
/*
|
|
@@ -964,39 +1071,6 @@ static int psmouse_probe(struct psmouse *psmouse)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Here we set the mouse resolution.
|
|
|
- */
|
|
|
-
|
|
|
-void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
|
|
|
-{
|
|
|
- static const unsigned char params[] = { 0, 1, 2, 2, 3 };
|
|
|
- unsigned char p;
|
|
|
-
|
|
|
- if (resolution == 0 || resolution > 200)
|
|
|
- resolution = 200;
|
|
|
-
|
|
|
- p = params[resolution / 50];
|
|
|
- ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
|
|
|
- psmouse->resolution = 25 << p;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Here we set the mouse report rate.
|
|
|
- */
|
|
|
-
|
|
|
-static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
|
|
|
-{
|
|
|
- static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
|
|
|
- unsigned char r;
|
|
|
- int i = 0;
|
|
|
-
|
|
|
- while (rates[i] > rate) i++;
|
|
|
- r = rates[i];
|
|
|
- ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
|
|
|
- psmouse->rate = r;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* psmouse_initialize() initializes the mouse to a sane state.
|
|
|
*/
|
|
@@ -1042,16 +1116,6 @@ static void psmouse_deactivate(struct psmouse *psmouse)
|
|
|
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
|
|
|
- */
|
|
|
-
|
|
|
-static int psmouse_poll(struct psmouse *psmouse)
|
|
|
-{
|
|
|
- return ps2_command(&psmouse->ps2dev, psmouse->packet,
|
|
|
- PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
/*
|
|
|
* psmouse_resync() attempts to re-validate current protocol.
|
|
@@ -1252,18 +1316,9 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
|
|
|
|
|
|
input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
|
|
|
|
|
|
- input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
|
|
|
- input_dev->keybit[BIT_WORD(BTN_MOUSE)] =
|
|
|
- BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
|
|
|
- input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
|
|
|
-
|
|
|
- psmouse->set_rate = psmouse_set_rate;
|
|
|
- psmouse->set_resolution = psmouse_set_resolution;
|
|
|
- psmouse->poll = psmouse_poll;
|
|
|
- psmouse->protocol_handler = psmouse_process_byte;
|
|
|
- psmouse->pktsize = 3;
|
|
|
-
|
|
|
if (proto && (proto->detect || proto->init)) {
|
|
|
+ psmouse_apply_defaults(psmouse);
|
|
|
+
|
|
|
if (proto->detect && proto->detect(psmouse, true) < 0)
|
|
|
return -1;
|
|
|
|