Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov: "An update to ALPS to support devices on Dell XT2 (hopefully working better this time around and although it is largish it should not affect any other ALPS devices) and a tiny update to Elantech driver to support newer devices as well. Also a coupe of new input event codes have been defined" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: ALPS - add support for DualPoint device on Dell XT2 model Input: elantech - add support for newer (August 2013) devices Input: add SW_MUTE_DEVICE switch definition Input: usbtouchscreen - separate report and transmit buffer size handling Input: sur40 - suppress false uninitialized variable warning Input: add key code for ambient light sensor button Input: keyboard - "keycode & KEY_MAX" changes some keycode values
This commit is contained in:
commit
754ac45745
10 changed files with 239 additions and 14 deletions
|
@ -536,7 +536,8 @@ static int adp5588_probe(struct i2c_client *client,
|
|||
__set_bit(EV_REP, input->evbit);
|
||||
|
||||
for (i = 0; i < input->keycodemax; i++)
|
||||
__set_bit(kpad->keycode[i] & KEY_MAX, input->keybit);
|
||||
if (kpad->keycode[i] <= KEY_MAX)
|
||||
__set_bit(kpad->keycode[i], input->keybit);
|
||||
__clear_bit(KEY_RESERVED, input->keybit);
|
||||
|
||||
if (kpad->gpimapsize)
|
||||
|
|
|
@ -992,7 +992,8 @@ static int adp5589_probe(struct i2c_client *client,
|
|||
__set_bit(EV_REP, input->evbit);
|
||||
|
||||
for (i = 0; i < input->keycodemax; i++)
|
||||
__set_bit(kpad->keycode[i] & KEY_MAX, input->keybit);
|
||||
if (kpad->keycode[i] <= KEY_MAX)
|
||||
__set_bit(kpad->keycode[i], input->keybit);
|
||||
__clear_bit(KEY_RESERVED, input->keybit);
|
||||
|
||||
if (kpad->gpimapsize)
|
||||
|
|
|
@ -289,7 +289,8 @@ static int bfin_kpad_probe(struct platform_device *pdev)
|
|||
__set_bit(EV_REP, input->evbit);
|
||||
|
||||
for (i = 0; i < input->keycodemax; i++)
|
||||
__set_bit(bf54x_kpad->keycode[i] & KEY_MAX, input->keybit);
|
||||
if (bf54x_kpad->keycode[i] <= KEY_MAX)
|
||||
__set_bit(bf54x_kpad->keycode[i], input->keybit);
|
||||
__clear_bit(KEY_RESERVED, input->keybit);
|
||||
|
||||
error = input_register_device(input);
|
||||
|
|
|
@ -113,9 +113,12 @@ static int pcf8574_kp_probe(struct i2c_client *client, const struct i2c_device_i
|
|||
idev->keycodemax = ARRAY_SIZE(lp->btncode);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pcf8574_kp_btncode); i++) {
|
||||
lp->btncode[i] = pcf8574_kp_btncode[i];
|
||||
__set_bit(lp->btncode[i] & KEY_MAX, idev->keybit);
|
||||
if (lp->btncode[i] <= KEY_MAX) {
|
||||
lp->btncode[i] = pcf8574_kp_btncode[i];
|
||||
__set_bit(lp->btncode[i], idev->keybit);
|
||||
}
|
||||
}
|
||||
__clear_bit(KEY_RESERVED, idev->keybit);
|
||||
|
||||
sprintf(lp->name, DRV_NAME);
|
||||
sprintf(lp->phys, "kp_data/input0");
|
||||
|
|
|
@ -70,6 +70,25 @@ static const struct alps_nibble_commands alps_v4_nibble_commands[] = {
|
|||
{ PSMOUSE_CMD_SETSCALE11, 0x00 }, /* f */
|
||||
};
|
||||
|
||||
static const struct alps_nibble_commands alps_v6_nibble_commands[] = {
|
||||
{ PSMOUSE_CMD_ENABLE, 0x00 }, /* 0 */
|
||||
{ PSMOUSE_CMD_SETRATE, 0x0a }, /* 1 */
|
||||
{ PSMOUSE_CMD_SETRATE, 0x14 }, /* 2 */
|
||||
{ PSMOUSE_CMD_SETRATE, 0x28 }, /* 3 */
|
||||
{ PSMOUSE_CMD_SETRATE, 0x3c }, /* 4 */
|
||||
{ PSMOUSE_CMD_SETRATE, 0x50 }, /* 5 */
|
||||
{ PSMOUSE_CMD_SETRATE, 0x64 }, /* 6 */
|
||||
{ PSMOUSE_CMD_SETRATE, 0xc8 }, /* 7 */
|
||||
{ PSMOUSE_CMD_GETID, 0x00 }, /* 8 */
|
||||
{ PSMOUSE_CMD_GETINFO, 0x00 }, /* 9 */
|
||||
{ PSMOUSE_CMD_SETRES, 0x00 }, /* a */
|
||||
{ PSMOUSE_CMD_SETRES, 0x01 }, /* b */
|
||||
{ PSMOUSE_CMD_SETRES, 0x02 }, /* c */
|
||||
{ PSMOUSE_CMD_SETRES, 0x03 }, /* d */
|
||||
{ PSMOUSE_CMD_SETSCALE21, 0x00 }, /* e */
|
||||
{ PSMOUSE_CMD_SETSCALE11, 0x00 }, /* f */
|
||||
};
|
||||
|
||||
|
||||
#define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */
|
||||
#define ALPS_PASS 0x04 /* device has a pass-through port */
|
||||
|
@ -103,6 +122,7 @@ static const struct alps_model_info alps_model_data[] = {
|
|||
/* Dell Latitude E5500, E6400, E6500, Precision M4400 */
|
||||
{ { 0x62, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf,
|
||||
ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
|
||||
{ { 0x73, 0x00, 0x14 }, 0x00, ALPS_PROTO_V6, 0xff, 0xff, ALPS_DUALPOINT }, /* Dell XT2 */
|
||||
{ { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
|
||||
{ { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff,
|
||||
ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
|
||||
|
@ -645,6 +665,76 @@ static void alps_process_packet_v3(struct psmouse *psmouse)
|
|||
alps_process_touchpad_packet_v3(psmouse);
|
||||
}
|
||||
|
||||
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;
|
||||
struct input_dev *dev2 = priv->dev2;
|
||||
int x, y, z, left, right, middle;
|
||||
|
||||
/*
|
||||
* We can use Byte5 to distinguish if the packet is from Touchpad
|
||||
* or Trackpoint.
|
||||
* Touchpad: 0 - 0x7E
|
||||
* Trackpoint: 0x7F
|
||||
*/
|
||||
if (packet[5] == 0x7F) {
|
||||
/* It should be a DualPoint when received Trackpoint packet */
|
||||
if (!(priv->flags & ALPS_DUALPOINT))
|
||||
return;
|
||||
|
||||
/* Trackpoint packet */
|
||||
x = packet[1] | ((packet[3] & 0x20) << 2);
|
||||
y = packet[2] | ((packet[3] & 0x40) << 1);
|
||||
z = packet[4];
|
||||
left = packet[3] & 0x01;
|
||||
right = packet[3] & 0x02;
|
||||
middle = packet[3] & 0x04;
|
||||
|
||||
/* To prevent the cursor jump when finger lifted */
|
||||
if (x == 0x7F && y == 0x7F && z == 0x7F)
|
||||
x = y = z = 0;
|
||||
|
||||
/* Divide 4 since trackpoint's speed is too fast */
|
||||
input_report_rel(dev2, REL_X, (char)x / 4);
|
||||
input_report_rel(dev2, REL_Y, -((char)y / 4));
|
||||
|
||||
input_report_key(dev2, BTN_LEFT, left);
|
||||
input_report_key(dev2, BTN_RIGHT, right);
|
||||
input_report_key(dev2, BTN_MIDDLE, middle);
|
||||
|
||||
input_sync(dev2);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Touchpad packet */
|
||||
x = packet[1] | ((packet[3] & 0x78) << 4);
|
||||
y = packet[2] | ((packet[4] & 0x78) << 4);
|
||||
z = packet[5];
|
||||
left = packet[3] & 0x01;
|
||||
right = packet[3] & 0x02;
|
||||
|
||||
if (z > 30)
|
||||
input_report_key(dev, BTN_TOUCH, 1);
|
||||
if (z < 25)
|
||||
input_report_key(dev, BTN_TOUCH, 0);
|
||||
|
||||
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_report_key(dev, BTN_TOOL_FINGER, z > 0);
|
||||
|
||||
/* v6 touchpad does not have middle button */
|
||||
input_report_key(dev, BTN_LEFT, left);
|
||||
input_report_key(dev, BTN_RIGHT, right);
|
||||
|
||||
input_sync(dev);
|
||||
}
|
||||
|
||||
static void alps_process_packet_v4(struct psmouse *psmouse)
|
||||
{
|
||||
struct alps_data *priv = psmouse->private;
|
||||
|
@ -897,7 +987,7 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
|
|||
}
|
||||
|
||||
/* Bytes 2 - pktsize should have 0 in the highest bit */
|
||||
if (priv->proto_version != ALPS_PROTO_V5 &&
|
||||
if ((priv->proto_version < ALPS_PROTO_V5) &&
|
||||
psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
|
||||
(psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
|
||||
psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
|
||||
|
@ -1085,6 +1175,80 @@ static int alps_absolute_mode_v1_v2(struct psmouse *psmouse)
|
|||
return ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
|
||||
}
|
||||
|
||||
static int alps_monitor_mode_send_word(struct psmouse *psmouse, u16 word)
|
||||
{
|
||||
int i, nibble;
|
||||
|
||||
/*
|
||||
* b0-b11 are valid bits, send sequence is inverse.
|
||||
* e.g. when word = 0x0123, nibble send sequence is 3, 2, 1
|
||||
*/
|
||||
for (i = 0; i <= 8; i += 4) {
|
||||
nibble = (word >> i) & 0xf;
|
||||
if (alps_command_mode_send_nibble(psmouse, nibble))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alps_monitor_mode_write_reg(struct psmouse *psmouse,
|
||||
u16 addr, u16 value)
|
||||
{
|
||||
struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
|
||||
/* 0x0A0 is the command to write the word */
|
||||
if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE) ||
|
||||
alps_monitor_mode_send_word(psmouse, 0x0A0) ||
|
||||
alps_monitor_mode_send_word(psmouse, addr) ||
|
||||
alps_monitor_mode_send_word(psmouse, value) ||
|
||||
ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alps_monitor_mode(struct psmouse *psmouse, bool enable)
|
||||
{
|
||||
struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
|
||||
if (enable) {
|
||||
/* EC E9 F5 F5 E7 E6 E7 E9 to enter monitor mode */
|
||||
if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
|
||||
ps2_command(ps2dev, NULL, PSMOUSE_CMD_GETINFO) ||
|
||||
ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
|
||||
ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
|
||||
ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
|
||||
ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
|
||||
ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
|
||||
ps2_command(ps2dev, NULL, PSMOUSE_CMD_GETINFO))
|
||||
return -1;
|
||||
} else {
|
||||
/* EC to exit monitor mode */
|
||||
if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alps_absolute_mode_v6(struct psmouse *psmouse)
|
||||
{
|
||||
u16 reg_val = 0x181;
|
||||
int ret = -1;
|
||||
|
||||
/* enter monitor mode, to write the register */
|
||||
if (alps_monitor_mode(psmouse, true))
|
||||
return -1;
|
||||
|
||||
ret = alps_monitor_mode_write_reg(psmouse, 0x000, reg_val);
|
||||
|
||||
if (alps_monitor_mode(psmouse, false))
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int alps_get_status(struct psmouse *psmouse, char *param)
|
||||
{
|
||||
/* Get status: 0xF5 0xF5 0xF5 0xE9 */
|
||||
|
@ -1189,6 +1353,32 @@ static int alps_hw_init_v1_v2(struct psmouse *psmouse)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int alps_hw_init_v6(struct psmouse *psmouse)
|
||||
{
|
||||
unsigned char param[2] = {0xC8, 0x14};
|
||||
|
||||
/* Enter passthrough mode to let trackpoint enter 6byte raw mode */
|
||||
if (alps_passthrough_mode_v2(psmouse, true))
|
||||
return -1;
|
||||
|
||||
if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
|
||||
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
|
||||
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
|
||||
ps2_command(&psmouse->ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE) ||
|
||||
ps2_command(&psmouse->ps2dev, ¶m[1], PSMOUSE_CMD_SETRATE))
|
||||
return -1;
|
||||
|
||||
if (alps_passthrough_mode_v2(psmouse, false))
|
||||
return -1;
|
||||
|
||||
if (alps_absolute_mode_v6(psmouse)) {
|
||||
psmouse_err(psmouse, "Failed to enable absolute mode\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable or disable passthrough mode to the trackstick.
|
||||
*/
|
||||
|
@ -1553,6 +1743,8 @@ static void alps_set_defaults(struct alps_data *priv)
|
|||
priv->hw_init = alps_hw_init_v1_v2;
|
||||
priv->process_packet = alps_process_packet_v1_v2;
|
||||
priv->set_abs_params = alps_set_abs_params_st;
|
||||
priv->x_max = 1023;
|
||||
priv->y_max = 767;
|
||||
break;
|
||||
case ALPS_PROTO_V3:
|
||||
priv->hw_init = alps_hw_init_v3;
|
||||
|
@ -1584,6 +1776,14 @@ static void alps_set_defaults(struct alps_data *priv)
|
|||
priv->x_bits = 23;
|
||||
priv->y_bits = 12;
|
||||
break;
|
||||
case ALPS_PROTO_V6:
|
||||
priv->hw_init = alps_hw_init_v6;
|
||||
priv->process_packet = alps_process_packet_v6;
|
||||
priv->set_abs_params = alps_set_abs_params_st;
|
||||
priv->nibble_commands = alps_v6_nibble_commands;
|
||||
priv->x_max = 2047;
|
||||
priv->y_max = 1535;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1705,8 +1905,8 @@ static void alps_disconnect(struct psmouse *psmouse)
|
|||
static void alps_set_abs_params_st(struct alps_data *priv,
|
||||
struct input_dev *dev1)
|
||||
{
|
||||
input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
|
||||
input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
|
||||
input_set_abs_params(dev1, ABS_X, 0, priv->x_max, 0, 0);
|
||||
input_set_abs_params(dev1, ABS_Y, 0, priv->y_max, 0, 0);
|
||||
}
|
||||
|
||||
static void alps_set_abs_params_mt(struct alps_data *priv,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define ALPS_PROTO_V3 3
|
||||
#define ALPS_PROTO_V4 4
|
||||
#define ALPS_PROTO_V5 5
|
||||
#define ALPS_PROTO_V6 6
|
||||
|
||||
/**
|
||||
* struct alps_model_info - touchpad ID table
|
||||
|
|
|
@ -1313,6 +1313,7 @@ static int elantech_set_properties(struct elantech_data *etd)
|
|||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
etd->hw_version = 4;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -251,7 +251,7 @@ static void sur40_poll(struct input_polled_dev *polldev)
|
|||
struct sur40_state *sur40 = polldev->private;
|
||||
struct input_dev *input = polldev->input;
|
||||
int result, bulk_read, need_blobs, packet_blobs, i;
|
||||
u32 packet_id;
|
||||
u32 uninitialized_var(packet_id);
|
||||
|
||||
struct sur40_header *header = &sur40->bulk_in_buffer->header;
|
||||
struct sur40_blob *inblob = &sur40->bulk_in_buffer->blobs[0];
|
||||
|
@ -286,7 +286,7 @@ static void sur40_poll(struct input_polled_dev *polldev)
|
|||
if (need_blobs == -1) {
|
||||
need_blobs = le16_to_cpu(header->count);
|
||||
dev_dbg(sur40->dev, "need %d blobs\n", need_blobs);
|
||||
packet_id = header->packet_id;
|
||||
packet_id = le32_to_cpu(header->packet_id);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -106,6 +106,7 @@ struct usbtouch_device_info {
|
|||
struct usbtouch_usb {
|
||||
unsigned char *data;
|
||||
dma_addr_t data_dma;
|
||||
int data_size;
|
||||
unsigned char *buffer;
|
||||
int buf_len;
|
||||
struct urb *irq;
|
||||
|
@ -1521,7 +1522,7 @@ static int usbtouch_reset_resume(struct usb_interface *intf)
|
|||
static void usbtouch_free_buffers(struct usb_device *udev,
|
||||
struct usbtouch_usb *usbtouch)
|
||||
{
|
||||
usb_free_coherent(udev, usbtouch->type->rept_size,
|
||||
usb_free_coherent(udev, usbtouch->data_size,
|
||||
usbtouch->data, usbtouch->data_dma);
|
||||
kfree(usbtouch->buffer);
|
||||
}
|
||||
|
@ -1566,7 +1567,20 @@ static int usbtouch_probe(struct usb_interface *intf,
|
|||
if (!type->process_pkt)
|
||||
type->process_pkt = usbtouch_process_pkt;
|
||||
|
||||
usbtouch->data = usb_alloc_coherent(udev, type->rept_size,
|
||||
usbtouch->data_size = type->rept_size;
|
||||
if (type->get_pkt_len) {
|
||||
/*
|
||||
* When dealing with variable-length packets we should
|
||||
* not request more than wMaxPacketSize bytes at once
|
||||
* as we do not know if there is more data coming or
|
||||
* we filled exactly wMaxPacketSize bytes and there is
|
||||
* nothing else.
|
||||
*/
|
||||
usbtouch->data_size = min(usbtouch->data_size,
|
||||
usb_endpoint_maxp(endpoint));
|
||||
}
|
||||
|
||||
usbtouch->data = usb_alloc_coherent(udev, usbtouch->data_size,
|
||||
GFP_KERNEL, &usbtouch->data_dma);
|
||||
if (!usbtouch->data)
|
||||
goto out_free;
|
||||
|
@ -1626,12 +1640,12 @@ static int usbtouch_probe(struct usb_interface *intf,
|
|||
if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT)
|
||||
usb_fill_int_urb(usbtouch->irq, udev,
|
||||
usb_rcvintpipe(udev, endpoint->bEndpointAddress),
|
||||
usbtouch->data, type->rept_size,
|
||||
usbtouch->data, usbtouch->data_size,
|
||||
usbtouch_irq, usbtouch, endpoint->bInterval);
|
||||
else
|
||||
usb_fill_bulk_urb(usbtouch->irq, udev,
|
||||
usb_rcvbulkpipe(udev, endpoint->bEndpointAddress),
|
||||
usbtouch->data, type->rept_size,
|
||||
usbtouch->data, usbtouch->data_size,
|
||||
usbtouch_irq, usbtouch);
|
||||
|
||||
usbtouch->irq->dev = udev;
|
||||
|
|
|
@ -719,6 +719,8 @@ struct input_keymap_entry {
|
|||
#define BTN_DPAD_LEFT 0x222
|
||||
#define BTN_DPAD_RIGHT 0x223
|
||||
|
||||
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
|
||||
|
||||
#define BTN_TRIGGER_HAPPY 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY1 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY2 0x2c1
|
||||
|
@ -856,6 +858,7 @@ struct input_keymap_entry {
|
|||
#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
|
||||
#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
|
||||
#define SW_LINEIN_INSERT 0x0d /* set = inserted */
|
||||
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
|
||||
#define SW_MAX 0x0f
|
||||
#define SW_CNT (SW_MAX+1)
|
||||
|
||||
|
|
Loading…
Reference in a new issue