Re: [PATCH 1/1] Feature: Support ALPS v6.

From: Henrik Rydberg
Date: Fri Mar 29 2013 - 12:43:28 EST


Hi Ivan,

> Tested on Dell 7720. Works fine.
>
> Signed-off-by: Valyushkov Ivan <ktopisal@xxxxxxxxx>
> ---
> drivers/input/mouse/alps.c | 464 +++++++++++++++++++++++++++++++++++++++++---
> drivers/input/mouse/alps.h | 2 +
> 2 files changed, 443 insertions(+), 23 deletions(-)

This patch does not seem to apply to Linus' tree, nor to next. What
tree is it based on?

>
> diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
> index e229fa3..38361bc 100644
> --- a/drivers/input/mouse/alps.c
> +++ b/drivers/input/mouse/alps.c
> @@ -15,6 +15,8 @@
> * the Free Software Foundation.
> */
>
> +#define DEBUG
> +

Looks like the patch needs to be cleaned a bit.

> #include <linux/slab.h>
> #include <linux/input.h>
> #include <linux/input/mt.h>
> @@ -30,9 +32,6 @@
> #define ALPS_V3_X_MAX 2000
> #define ALPS_V3_Y_MAX 1400
>
> -#define ALPS_BITMAP_X_BITS 15
> -#define ALPS_BITMAP_Y_BITS 11
> -
> #define ALPS_CMD_NIBBLE_10 0x01f2
>
> static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
> @@ -84,6 +83,12 @@ static const struct alps_nibble_commands alps_v4_nibble_commands[] = {
> #define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with
> 6-byte ALPS packet */
>
> +/* Set these based upon protocol version */
> +static int ALPS_X_MAX; /* right edge */
> +static int ALPS_Y_MAX; /* bottom edge */
> +static int ALPS_BITMAP_X_BITS; /* mt number of x bits */
> +static int ALPS_BITMAP_Y_BITS; /* mt number of y bits */
> +
> static const struct alps_model_info alps_model_data[] = {
> { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
> { { 0x33, 0x02, 0x0a }, 0x00, ALPS_PROTO_V1, 0x88, 0xf8, 0 }, /* UMAX-530T */
> @@ -112,6 +117,9 @@ static const struct alps_model_info alps_model_data[] = {
> { { 0x73, 0x02, 0x64 }, 0x9b, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT },
> { { 0x73, 0x02, 0x64 }, 0x9d, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT },
> { { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 },
> + { { 0x73, 0x03, 0x0a }, 0x1d, ALPS_PROTO_V5, 0x8f, 0x8f, ALPS_DUALPOINT }, /* Dell Latitude E6430 */
> + { { 0x73, 0x03, 0x50 }, 0x0d, ALPS_PROTO_V6, 0xc8, 0xc8, 0 }, /* Dell Inspiron N5110 */
> + { { 0x73, 0x03, 0x50 }, 0x02, ALPS_PROTO_V6, 0xc8, 0xc8, 0 } /* Dell Inspiron 17R 7720 */
> };
>
> /*
> @@ -355,9 +363,9 @@ static int alps_process_bitmap(unsigned int x_map, unsigned int y_map,
> }
> }
>
> - *x1 = (ALPS_V3_X_MAX * (2 * x_low.start_bit + x_low.num_bits - 1)) /
> + *x1 = (ALPS_X_MAX * (2 * x_low.start_bit + x_low.num_bits - 1)) /
> (2 * (ALPS_BITMAP_X_BITS - 1));
> - *y1 = (ALPS_V3_Y_MAX * (2 * y_low.start_bit + y_low.num_bits - 1)) /
> + *y1 = (ALPS_Y_MAX * (2 * y_low.start_bit + y_low.num_bits - 1)) /
> (2 * (ALPS_BITMAP_Y_BITS - 1));
>
> if (fingers > 1) {
> @@ -388,7 +396,7 @@ static void alps_report_semi_mt_data(struct input_dev *dev, int num_fingers,
> alps_set_slot(dev, 1, num_fingers == 2, x2, y2);
> }
>
> -static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
> +static void alps_process_trackstick_packet_v3_v5(struct psmouse *psmouse)
> {
> struct alps_data *priv = psmouse->private;
> unsigned char *packet = psmouse->packet;
> @@ -448,7 +456,7 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
> return;
> }
>
> -static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
> +static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
> {
> struct alps_data *priv = psmouse->private;
> unsigned char *packet = psmouse->packet;
> @@ -579,7 +587,7 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
> }
> }
>
> -static void alps_process_packet_v3(struct psmouse *psmouse)
> +static void alps_process_packet_v3_v5(struct psmouse *psmouse)
> {
> unsigned char *packet = psmouse->packet;
>
> @@ -592,11 +600,11 @@ static void alps_process_packet_v3(struct psmouse *psmouse)
> * of packets.
> */
> if (packet[5] == 0x3f) {
> - alps_process_trackstick_packet_v3(psmouse);
> + alps_process_trackstick_packet_v3_v5(psmouse);
> return;
> }
>
> - alps_process_touchpad_packet_v3(psmouse);
> + alps_process_touchpad_packet_v3_v5(psmouse);
> }
>
> static void alps_process_packet_v4(struct psmouse *psmouse)
> @@ -696,6 +704,91 @@ static void alps_process_packet_v4(struct psmouse *psmouse)
> input_sync(dev);
> }
>
> +/* This is similar logic to alps_process_touchpad_packet_v3_v5. The
> + bitfield positions are different.
> +*/
> +static void alps_process_packet_v6(struct psmouse *psmouse)
> +{
> + struct alps_data *priv = psmouse->private;
> + unsigned char *packet = psmouse->packet;
> + struct input_dev *dev = psmouse->dev;
> + int x, y, z;
> + int left, right, middle;
> + int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
> + int fingers = 0;
> + unsigned long int x_bitmap, y_bitmap;
> +
> + /* multitouch packet */
> + if (priv->multi_packet) {
> + if (packet[0] & 0x20) {
> + fingers = ((packet[0] & 0x6) >> 1 |
> + (packet[0] & 0x10) >> 2);
> + x_bitmap = ((packet[2] & 0x60) >> 5) |
> + ((packet[4] & 0x7f) << 2) |
> + ((packet[5] & 0x7f) << 9) |
> + ((packet[3] & 0x07) << 16) |
> + ((packet[3] & 0x70) << 15) |
> + ((packet[0] & 0x01) << 22);
> + y_bitmap = (packet[1] & 0x7f) |
> + ((packet[2] & 0x1f) << 7);
> + alps_process_bitmap(x_bitmap, y_bitmap,
> + &x1, &y1, &x2, &y2);
> + packet = priv->multi_data;
> + } else {
> + priv->multi_packet = 0;
> + }
> + }
> +
> + if (packet[0] & 0x20)
> + return;
> +
> + if (!priv->multi_packet && (packet[0] & 0x2)) {
> + priv->multi_packet = 1;
> + memcpy(priv->multi_data, packet, sizeof(priv->multi_data));
> + return;
> + }
> + priv->multi_packet = 0;
> +
> + left = packet[3] & 0x1;
> + right = packet[3] & 0x2;
> + middle = packet[3] & 0x4;
> +
> + x = ((packet[1] & 0x7f) | ((packet[4] & 0x0f) << 7));
> + y = ((packet[2] & 0x7f) | ((packet[4] & 0xf0) << 3));
> + z = (packet[0] & 4) ? 0 : packet[5] & 0x7f;
> +
> + if (x && y && !z)
> + return;
> +
> + if (!fingers) {
> + x1 = x;
> + y1 = y;
> + fingers = z > 0 ? 1 : 0;
> + }
> +
> + if (z > 64)
> + input_report_key(dev, BTN_TOUCH, 1);
> + else
> + input_report_key(dev, BTN_TOUCH, 0);

It is ok to pass boolean variables in a single call.

> +
> + alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
> +
> + input_mt_report_finger_count(dev, fingers);
> +
> + input_report_key(dev, BTN_LEFT, left);
> + input_report_key(dev, BTN_RIGHT, right);
> + input_report_key(dev, BTN_MIDDLE, middle);

Strange indentation here.

> +
> + if (z > 0) {
> + input_report_abs(dev, ABS_X, x);
> + input_report_abs(dev, ABS_Y, y);
> + }
> + input_report_abs(dev, ABS_PRESSURE, z);
> +
> + input_sync(dev);
> +}
> +
> +
> static void alps_process_packet(struct psmouse *psmouse)
> {
> struct alps_data *priv = psmouse->private;
> @@ -707,11 +800,17 @@ static void alps_process_packet(struct psmouse *psmouse)
> alps_process_packet_v1_v2(psmouse);
> break;
> case ALPS_PROTO_V3:
> - alps_process_packet_v3(psmouse);
> + alps_process_packet_v3_v5(psmouse);
> break;
> case ALPS_PROTO_V4:
> alps_process_packet_v4(psmouse);
> break;
> + case ALPS_PROTO_V5:
> + alps_process_packet_v3_v5(psmouse);
> + break;
> + case ALPS_PROTO_V6:
> + alps_process_packet_v6(psmouse);
> + break;
> }
> }
>
> @@ -731,6 +830,12 @@ static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
> input_report_rel(dev2, REL_Y,
> packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
>
> + /* log buttons, REL_X, REL_Y */
> + psmouse_dbg(psmouse, "bare_ps2_packet: %x %d %d\n",
> + packet[0]&7,
> + packet[1] - ((packet[0]<<4)&0x100),
> + ((packet[0] << 3) & 0x100) - packet[2]);
> +
> input_sync(dev2);
> }
>
> @@ -767,8 +872,9 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
> psmouse->packet[5]) & 0x80) ||
> (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) {
> psmouse_dbg(psmouse,
> - "refusing packet %4ph (suspected interleaved ps/2)\n",
> - psmouse->packet + 3);
> + "refusing packet %x %x %x %x (suspected interleaved ps/2)\n",
> + psmouse->packet[3], psmouse->packet[4],
> + psmouse->packet[5], psmouse->packet[6]);
> return PSMOUSE_BAD_DATA;
> }
>
> @@ -830,8 +936,9 @@ static void alps_flush_packet(unsigned long data)
> psmouse->packet[4] |
> psmouse->packet[5]) & 0x80) {
> psmouse_dbg(psmouse,
> - "refusing packet %3ph (suspected interleaved ps/2)\n",
> - psmouse->packet + 3);
> + "refusing packet %x %x %x (suspected interleaved ps/2)\n",
> + psmouse->packet[3], psmouse->packet[4],
> + psmouse->packet[5]);
> } else {
> alps_process_packet(psmouse);
> }
> @@ -870,12 +977,18 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
> }
>
> /* Bytes 2 - pktsize should have 0 in the highest bit */
> - if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
> - (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
> - psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
> - psmouse->pktcnt - 1,
> - psmouse->packet[psmouse->pktcnt - 1]);
> - return PSMOUSE_BAD_DATA;
> +
> + /* This test is not valid for V6 multi-touch mode!
> + Need to restructure this code down the road */
> + if (model->proto_version != ALPS_PROTO_V6) {
> +
> + if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
> + (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
> + psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
> + psmouse->pktcnt - 1,
> + psmouse->packet[psmouse->pktcnt - 1]);
> + return PSMOUSE_BAD_DATA;
> + }
> }
>
> if (psmouse->pktcnt == psmouse->pktsize) {
> @@ -981,7 +1094,11 @@ static int alps_enter_command_mode(struct psmouse *psmouse,
> return -1;
> }
>
> - if (param[0] != 0x88 && param[1] != 0x07) {
> + /* Warning - cannot determine model yet because some devices have same
> + E7 response but are differentiated by the command mode response
> + */
> + if ((param[0] != 0x88 && param[1] != 0x07) /* For V1-V5 */
> + && (param[0] != 0x73 && param[1] != 0x01)) { /* For V6 */
> psmouse_dbg(psmouse,
> "unknown response while entering command mode: %2.2x %2.2x %2.2x\n",
> param[0], param[1], param[2]);
> @@ -1088,6 +1205,10 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
> psmouse_dbg(psmouse,
> "Unknown command mode response %2.2x\n",
> param[0]);
> + else
> + psmouse_dbg(psmouse,
> + "Model=%d, proto_version=%d\n",
> + i, model->proto_version);
> }
> }
>
> @@ -1517,6 +1638,261 @@ error:
> return -1;
> }
>
> +static int alps_hw_init_v5(struct psmouse *psmouse)
> +{
> + struct ps2dev *ps2dev = &psmouse->ps2dev;
> + unsigned char param[4];
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_BAT);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_BAT);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + param[0] = 0x64;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> + param[0] = 0x64;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
> + param[0] = 0xc8;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + param[0] = 0x14;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + param[0] = 0x64;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + param[0] = 0x64;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + param[0] = 0x14;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + param[0] = 0xc8;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + param[0] = 0x00;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + param[0] = 0x01;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
> + param[0] = 0x64;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> +
> + param[0] = 0x64;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> + param[0] = 0x64;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_ENABLE);
> +
> + return 0;
> +}

Eww... please tell me there is a more compressed way to initialize the device.

> +
> +static int alps_hw_init_v6(struct psmouse *psmouse)
> +{
> + struct alps_data *priv = psmouse->private;
> + struct ps2dev *ps2dev = &psmouse->ps2dev;
> + unsigned char param[4];
> +
> + /* Doesn't seem to be necessary but we keep here in case
> + registers need to be used */
> + priv->nibble_commands = alps_v3_nibble_commands;
> +
> + priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
> + ps2_command(ps2dev, param, PSMOUSE_CMD_RESET_BAT);
> + if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID)
> + psmouse_dbg(psmouse, "Bad reset %2.2x %2.2x", param[0], param[1]);
> +
> + ps2_command(ps2dev, param, PSMOUSE_CMD_RESET_BAT);
> + if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID)
> + psmouse_dbg(psmouse, "Bad reset %2.2x %2.2x", param[0], param[1]);
> +
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
> +
> + /* E6 report */
> + param[0] = 0;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRES);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> +
> + /* ?? */
> + param[0] = 0x03;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRES);
> +
> + /* Set 9-byte to 8-byte */
> + param[0] = 0xc8;
> + param[1] = 0x64;
> + param[2] = 0x50;
> + if (ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
> + ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE) ||
> + ps2_command(ps2dev, &param[2], PSMOUSE_CMD_SETRATE) ||
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
> + return -1;
> +
> + /* Set rate and enable data reporting? */
> + param[0] = 0xc8;
> + param[1] = 0x50;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_GETID);
> +
> + param[0] = 0x64;
> + param[1] = 0x03;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRES);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE);
> +
> + ps2_command(ps2dev, param, PSMOUSE_CMD_RESET_BAT);
> + if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID)
> + psmouse_dbg(psmouse, "Bad reset %2.2x %2.2x", param[0], param[1]);
> +
> + /* E7 report */
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> +
> + /* Enter command mode */
> + alps_enter_command_mode(psmouse, param);
> +
> + /* exit command mode */
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> + /* param should be bf 1a 04 */
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
> + /* param should be 89 95 84 */
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> + param[0] = 0x28;
> + param[1] = 0x50;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE);
> +
> + /* Enter command mode */
> + alps_enter_command_mode(psmouse, param);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> +
> + param[0] = 0x64;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21);
> + param[0] = 0x64;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
> +
> + /* out of cmd mode? */
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> +
> + param[0] = 0x64;
> + param[1] = 0x28;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> +
> + param[0] = 0x50;
> + param[1] = 0x0a;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
> +
> + param[0] = 0x50;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE);
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
> +
> + param[0] = 0x03;
> + ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRES);
> +
> + ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
> +
> + return 0;
> +}

Ditto.

> +
> +
> static int alps_hw_init(struct psmouse *psmouse)
> {
> struct alps_data *priv = psmouse->private;
> @@ -1534,6 +1910,12 @@ static int alps_hw_init(struct psmouse *psmouse)
> case ALPS_PROTO_V4:
> ret = alps_hw_init_v4(psmouse);
> break;
> + case ALPS_PROTO_V5:
> + ret = alps_hs_init_v5(psmouse);
> + break;
> + case ALPS_PROTO_V6:
> + ret = alps_hw_init_v6(psmouse);
> + break;
> }
>
> return ret;
> @@ -1618,7 +2000,7 @@ int alps_init(struct psmouse *psmouse)
> case ALPS_PROTO_V3:
> case ALPS_PROTO_V4:
> set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
> - input_mt_init_slots(dev1, 2, 0);
> + input_mt_init_slots(dev1, 2);

Nope - please refresh your patch to apply to Linus' tree.

> input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0);
> input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0);
>
> @@ -1629,6 +2011,42 @@ int alps_init(struct psmouse *psmouse)
> input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0);
> input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0);
> break;
> + case ALPS_PROTO_V5:
> + set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
> + input_mt_init_slots(dev1, 2);
> + ALPS_BITMAP_X_BITS = 15;
> + ALPS_BITMAP_Y_BITS = 11;
> + ALPS_X_MAX = 2000;
> + ALPS_Y_MAX = 1400;
> + input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_X_MAX, 0, 0);
> + input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_Y_MAX, 0, 0);
> +
> + set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit);
> + set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
> + set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
> +
> + input_set_abs_params(dev1, ABS_X, 0, ALPS_X_MAX, 0, 0);
> + input_set_abs_params(dev1, ABS_Y, 0, ALPS_Y_MAX, 0, 0);
> + break;
> + case ALPS_PROTO_V6:
> + set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
> + ALPS_BITMAP_X_BITS = 23;
> + ALPS_BITMAP_Y_BITS = 12;
> + ALPS_X_MAX = 1360;
> + ALPS_Y_MAX = 660;
> +
> + input_mt_init_slots(dev1, 2);
> + input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_X_MAX, 0, 0);
> + input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_Y_MAX, 0, 0);
> +
> + set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit);
> + set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
> + set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
> +
> + input_set_abs_params(dev1, ABS_X, 0, ALPS_X_MAX, 0, 0);
> + input_set_abs_params(dev1, ABS_Y, 0, ALPS_Y_MAX, 0, 0);
> +
> + break;
> }
>
> input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
> diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
> index ae1ac35..75a06af 100644
> --- a/drivers/input/mouse/alps.h
> +++ b/drivers/input/mouse/alps.h
> @@ -16,6 +16,8 @@
> #define ALPS_PROTO_V2 1
> #define ALPS_PROTO_V3 2
> #define ALPS_PROTO_V4 3
> +#define ALPS_PROTO_V5 4
> +#define ALPS_PROTO_V6 5
>
> struct alps_model_info {
> unsigned char signature[3];
> --
> 1.7.7.6
>

Thanks,
Henrik
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/