forked from Minki/linux
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull more input updates from Dmitry Torokhov: "The second round of updates for the input subsystem. Updates to ALPS an bfin_roraty drivers and a couple oother fixups" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: psmouse - use IS_ENABLED instead of homegrown code Input: bfin_rotary - introduce open and close methods Input: bfin_rotary - convert to use managed resources Input: bfin_rotary - use generic IO functions Input: bfin_rotary - move pin lists into into platform data Input: bfin_rotary - move platform header to linux/platform_data Input: bfin_rotary - mark suspend and resume code as __maybe_unused Input: bfin_rotary - fix potential oops in interrupt handler Input: ALPS - move v7 packet info to Documentation and v6 packet info Input: ALPS - fix confusing comment in protocol data Input: ALPS - do not mix trackstick and external PS/2 mouse data Input: ALPS - fix trackstick detection on some Dell Latitudes Input: ALPS - consolidate setting protocol parameters Input: ALPS - split protocol data from model info Input: ALPS - make Rushmore a separate protocol Input: ALPS - renumber protocol numbers Input: adi - remove an unnecessary check Input: pxa27x_keypad - remove an unneeded NULL check Input: soc_button_array - use "Windows" key for "Home"
This commit is contained in:
commit
1acd2de5fa
@ -3,8 +3,8 @@ ALPS Touchpad Protocol
|
||||
|
||||
Introduction
|
||||
------------
|
||||
Currently the ALPS touchpad driver supports five protocol versions in use by
|
||||
ALPS touchpads, called versions 1, 2, 3, 4 and 5.
|
||||
Currently the ALPS touchpad driver supports seven protocol versions in use by
|
||||
ALPS touchpads, called versions 1, 2, 3, 4, 5, 6 and 7.
|
||||
|
||||
Since roughly mid-2010 several new ALPS touchpads have been released and
|
||||
integrated into a variety of laptops and netbooks. These new touchpads
|
||||
@ -240,3 +240,67 @@ For mt, the format is:
|
||||
byte 3: 0 x23 x22 x21 x20 x19 x18 x17
|
||||
byte 4: 0 x9 x8 x7 x6 x5 x4 x3
|
||||
byte 5: 0 x16 x15 x14 x13 x12 x11 x10
|
||||
|
||||
ALPS Absolute Mode - Protocol Version 6
|
||||
---------------------------------------
|
||||
|
||||
For trackstick packet, the format is:
|
||||
|
||||
byte 0: 1 1 1 1 1 1 1 1
|
||||
byte 1: 0 X6 X5 X4 X3 X2 X1 X0
|
||||
byte 2: 0 Y6 Y5 Y4 Y3 Y2 Y1 Y0
|
||||
byte 3: ? Y7 X7 ? ? M R L
|
||||
byte 4: Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0
|
||||
byte 5: 0 1 1 1 1 1 1 1
|
||||
|
||||
For touchpad packet, the format is:
|
||||
|
||||
byte 0: 1 1 1 1 1 1 1 1
|
||||
byte 1: 0 0 0 0 x3 x2 x1 x0
|
||||
byte 2: 0 0 0 0 y3 y2 y1 y0
|
||||
byte 3: ? x7 x6 x5 x4 ? r l
|
||||
byte 4: ? y7 y6 y5 y4 ? ? ?
|
||||
byte 5: z7 z6 z5 z4 z3 z2 z1 z0
|
||||
|
||||
(v6 touchpad does not have middle button)
|
||||
|
||||
ALPS Absolute Mode - Protocol Version 7
|
||||
---------------------------------------
|
||||
|
||||
For trackstick packet, the format is:
|
||||
|
||||
byte 0: 0 1 0 0 1 0 0 0
|
||||
byte 1: 1 1 * * 1 M R L
|
||||
byte 2: X7 1 X5 X4 X3 X2 X1 X0
|
||||
byte 3: Z6 1 Y6 X6 1 Y2 Y1 Y0
|
||||
byte 4: Y7 0 Y5 Y4 Y3 1 1 0
|
||||
byte 5: T&P 0 Z5 Z4 Z3 Z2 Z1 Z0
|
||||
|
||||
For touchpad packet, the format is:
|
||||
|
||||
packet-fmt b7 b6 b5 b4 b3 b2 b1 b0
|
||||
byte 0: TWO & MULTI L 1 R M 1 Y0-2 Y0-1 Y0-0
|
||||
byte 0: NEW L 1 X1-5 1 1 Y0-2 Y0-1 Y0-0
|
||||
byte 1: Y0-10 Y0-9 Y0-8 Y0-7 Y0-6 Y0-5 Y0-4 Y0-3
|
||||
byte 2: X0-11 1 X0-10 X0-9 X0-8 X0-7 X0-6 X0-5
|
||||
byte 3: X1-11 1 X0-4 X0-3 1 X0-2 X0-1 X0-0
|
||||
byte 4: TWO X1-10 TWO X1-9 X1-8 X1-7 X1-6 X1-5 X1-4
|
||||
byte 4: MULTI X1-10 TWO X1-9 X1-8 X1-7 X1-6 Y1-5 1
|
||||
byte 4: NEW X1-10 TWO X1-9 X1-8 X1-7 X1-6 0 0
|
||||
byte 5: TWO & NEW Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 Y1-5 Y1-4
|
||||
byte 5: MULTI Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 F-1 F-0
|
||||
|
||||
L: Left button
|
||||
R / M: Non-clickpads: Right / Middle button
|
||||
Clickpads: When > 2 fingers are down, and some fingers
|
||||
are in the button area, then the 2 coordinates reported
|
||||
are for fingers outside the button area and these report
|
||||
extra fingers being present in the right / left button
|
||||
area. Note these fingers are not added to the F field!
|
||||
so if a TWO packet is received and R = 1 then there are
|
||||
3 fingers down, etc.
|
||||
TWO: 1: Two touches present, byte 0/4/5 are in TWO fmt
|
||||
0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt
|
||||
otherwise byte 0 bit 4 must be set and byte 0/4/5 are
|
||||
in NEW fmt
|
||||
F: Number of fingers - 3, 0 means 3 fingers, 1 means 4 ...
|
||||
|
@ -666,7 +666,14 @@ static struct platform_device bfin_sport1_uart_device = {
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_INPUT_BFIN_ROTARY)
|
||||
#include <asm/bfin_rotary.h>
|
||||
#include <linux/platform_data/bfin_rotary.h>
|
||||
|
||||
static const u16 per_cnt[] = {
|
||||
P_CNT_CUD,
|
||||
P_CNT_CDG,
|
||||
P_CNT_CZM,
|
||||
0
|
||||
};
|
||||
|
||||
static struct bfin_rotary_platform_data bfin_rotary_data = {
|
||||
/*.rotary_up_key = KEY_UP,*/
|
||||
@ -676,9 +683,15 @@ static struct bfin_rotary_platform_data bfin_rotary_data = {
|
||||
.debounce = 10, /* 0..17 */
|
||||
.mode = ROT_QUAD_ENC | ROT_DEBE,
|
||||
.pm_wakeup = 1,
|
||||
.pin_list = per_cnt,
|
||||
};
|
||||
|
||||
static struct resource bfin_rotary_resources[] = {
|
||||
{
|
||||
.start = CNT_CONFIG,
|
||||
.end = CNT_CONFIG + 0xff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = IRQ_CNT,
|
||||
.end = IRQ_CNT,
|
||||
|
@ -1092,7 +1092,14 @@ static struct platform_device bfin_device_gpiokeys = {
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_INPUT_BFIN_ROTARY)
|
||||
#include <asm/bfin_rotary.h>
|
||||
#include <linux/platform_data/bfin_rotary.h>
|
||||
|
||||
static const u16 per_cnt[] = {
|
||||
P_CNT_CUD,
|
||||
P_CNT_CDG,
|
||||
P_CNT_CZM,
|
||||
0
|
||||
};
|
||||
|
||||
static struct bfin_rotary_platform_data bfin_rotary_data = {
|
||||
/*.rotary_up_key = KEY_UP,*/
|
||||
@ -1102,9 +1109,15 @@ static struct bfin_rotary_platform_data bfin_rotary_data = {
|
||||
.debounce = 10, /* 0..17 */
|
||||
.mode = ROT_QUAD_ENC | ROT_DEBE,
|
||||
.pm_wakeup = 1,
|
||||
.pin_list = per_cnt,
|
||||
};
|
||||
|
||||
static struct resource bfin_rotary_resources[] = {
|
||||
{
|
||||
.start = CNT_CONFIG,
|
||||
.end = CNT_CONFIG + 0xff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = IRQ_CNT,
|
||||
.end = IRQ_CNT,
|
||||
|
@ -159,7 +159,7 @@ static struct platform_device bf54x_kpad_device = {
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_INPUT_BFIN_ROTARY)
|
||||
#include <asm/bfin_rotary.h>
|
||||
#include <linux/platform_data/bfin_rotary.h>
|
||||
|
||||
static struct bfin_rotary_platform_data bfin_rotary_data = {
|
||||
/*.rotary_up_key = KEY_UP,*/
|
||||
@ -172,6 +172,11 @@ static struct bfin_rotary_platform_data bfin_rotary_data = {
|
||||
};
|
||||
|
||||
static struct resource bfin_rotary_resources[] = {
|
||||
{
|
||||
.start = CNT_CONFIG,
|
||||
.end = CNT_CONFIG + 0xff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = IRQ_CNT,
|
||||
.end = IRQ_CNT,
|
||||
|
@ -75,7 +75,7 @@ static struct platform_device bfin_isp1760_device = {
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_INPUT_BFIN_ROTARY)
|
||||
#include <asm/bfin_rotary.h>
|
||||
#include <linux/platform_data/bfin_rotary.h>
|
||||
|
||||
static struct bfin_rotary_platform_data bfin_rotary_data = {
|
||||
/*.rotary_up_key = KEY_UP,*/
|
||||
@ -87,6 +87,11 @@ static struct bfin_rotary_platform_data bfin_rotary_data = {
|
||||
};
|
||||
|
||||
static struct resource bfin_rotary_resources[] = {
|
||||
{
|
||||
.start = CNT_CONFIG,
|
||||
.end = CNT_CONFIG + 0xff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = IRQ_CNT,
|
||||
.end = IRQ_CNT,
|
||||
|
@ -535,8 +535,7 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
|
||||
}
|
||||
}
|
||||
fail2: for (i = 0; i < 2; i++)
|
||||
if (port->adi[i].dev)
|
||||
input_free_device(port->adi[i].dev);
|
||||
input_free_device(port->adi[i].dev);
|
||||
gameport_close(gameport);
|
||||
fail1: gameport_set_drvdata(gameport, NULL);
|
||||
kfree(port);
|
||||
|
@ -345,13 +345,11 @@ static int pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
|
||||
{
|
||||
const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
|
||||
struct input_dev *input_dev = keypad->input_dev;
|
||||
const struct matrix_keymap_data *keymap_data =
|
||||
pdata ? pdata->matrix_keymap_data : NULL;
|
||||
unsigned short keycode;
|
||||
int i;
|
||||
int error;
|
||||
|
||||
error = matrix_keypad_build_keymap(keymap_data, NULL,
|
||||
error = matrix_keypad_build_keymap(pdata->matrix_keymap_data, NULL,
|
||||
pdata->matrix_key_rows,
|
||||
pdata->matrix_key_cols,
|
||||
keypad->keycodes, input_dev);
|
||||
|
@ -7,29 +7,37 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_data/bfin_rotary.h>
|
||||
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/bfin_rotary.h>
|
||||
|
||||
static const u16 per_cnt[] = {
|
||||
P_CNT_CUD,
|
||||
P_CNT_CDG,
|
||||
P_CNT_CZM,
|
||||
0
|
||||
};
|
||||
#define CNT_CONFIG_OFF 0 /* CNT Config Offset */
|
||||
#define CNT_IMASK_OFF 4 /* CNT Interrupt Mask Offset */
|
||||
#define CNT_STATUS_OFF 8 /* CNT Status Offset */
|
||||
#define CNT_COMMAND_OFF 12 /* CNT Command Offset */
|
||||
#define CNT_DEBOUNCE_OFF 16 /* CNT Debounce Offset */
|
||||
#define CNT_COUNTER_OFF 20 /* CNT Counter Offset */
|
||||
#define CNT_MAX_OFF 24 /* CNT Maximum Count Offset */
|
||||
#define CNT_MIN_OFF 28 /* CNT Minimum Count Offset */
|
||||
|
||||
struct bfin_rot {
|
||||
struct input_dev *input;
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
unsigned int up_key;
|
||||
unsigned int down_key;
|
||||
unsigned int button_key;
|
||||
unsigned int rel_code;
|
||||
|
||||
unsigned short mode;
|
||||
unsigned short debounce;
|
||||
|
||||
unsigned short cnt_config;
|
||||
unsigned short cnt_imask;
|
||||
unsigned short cnt_debounce;
|
||||
@ -59,18 +67,17 @@ static void report_rotary_event(struct bfin_rot *rotary, int delta)
|
||||
|
||||
static irqreturn_t bfin_rotary_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct platform_device *pdev = dev_id;
|
||||
struct bfin_rot *rotary = platform_get_drvdata(pdev);
|
||||
struct bfin_rot *rotary = dev_id;
|
||||
int delta;
|
||||
|
||||
switch (bfin_read_CNT_STATUS()) {
|
||||
switch (readw(rotary->base + CNT_STATUS_OFF)) {
|
||||
|
||||
case ICII:
|
||||
break;
|
||||
|
||||
case UCII:
|
||||
case DCII:
|
||||
delta = bfin_read_CNT_COUNTER();
|
||||
delta = readl(rotary->base + CNT_COUNTER_OFF);
|
||||
if (delta)
|
||||
report_rotary_event(rotary, delta);
|
||||
break;
|
||||
@ -83,16 +90,52 @@ static irqreturn_t bfin_rotary_isr(int irq, void *dev_id)
|
||||
break;
|
||||
}
|
||||
|
||||
bfin_write_CNT_COMMAND(W1LCNT_ZERO); /* Clear COUNTER */
|
||||
bfin_write_CNT_STATUS(-1); /* Clear STATUS */
|
||||
writew(W1LCNT_ZERO, rotary->base + CNT_COMMAND_OFF); /* Clear COUNTER */
|
||||
writew(-1, rotary->base + CNT_STATUS_OFF); /* Clear STATUS */
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int bfin_rotary_open(struct input_dev *input)
|
||||
{
|
||||
struct bfin_rot *rotary = input_get_drvdata(input);
|
||||
unsigned short val;
|
||||
|
||||
if (rotary->mode & ROT_DEBE)
|
||||
writew(rotary->debounce & DPRESCALE,
|
||||
rotary->base + CNT_DEBOUNCE_OFF);
|
||||
|
||||
writew(rotary->mode & ~CNTE, rotary->base + CNT_CONFIG_OFF);
|
||||
|
||||
val = UCIE | DCIE;
|
||||
if (rotary->button_key)
|
||||
val |= CZMIE;
|
||||
writew(val, rotary->base + CNT_IMASK_OFF);
|
||||
|
||||
writew(rotary->mode | CNTE, rotary->base + CNT_CONFIG_OFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bfin_rotary_close(struct input_dev *input)
|
||||
{
|
||||
struct bfin_rot *rotary = input_get_drvdata(input);
|
||||
|
||||
writew(0, rotary->base + CNT_CONFIG_OFF);
|
||||
writew(0, rotary->base + CNT_IMASK_OFF);
|
||||
}
|
||||
|
||||
static void bfin_rotary_free_action(void *data)
|
||||
{
|
||||
peripheral_free_list(data);
|
||||
}
|
||||
|
||||
static int bfin_rotary_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct bfin_rotary_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct bfin_rotary_platform_data *pdata = dev_get_platdata(dev);
|
||||
struct bfin_rot *rotary;
|
||||
struct resource *res;
|
||||
struct input_dev *input;
|
||||
int error;
|
||||
|
||||
@ -102,18 +145,37 @@ static int bfin_rotary_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
error = peripheral_request_list(per_cnt, dev_name(&pdev->dev));
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "requesting peripherals failed\n");
|
||||
return error;
|
||||
if (pdata->pin_list) {
|
||||
error = peripheral_request_list(pdata->pin_list,
|
||||
dev_name(&pdev->dev));
|
||||
if (error) {
|
||||
dev_err(dev, "requesting peripherals failed: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = devm_add_action(dev, bfin_rotary_free_action,
|
||||
pdata->pin_list);
|
||||
if (error) {
|
||||
dev_err(dev, "setting cleanup action failed: %d\n",
|
||||
error);
|
||||
peripheral_free_list(pdata->pin_list);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
rotary = kzalloc(sizeof(struct bfin_rot), GFP_KERNEL);
|
||||
input = input_allocate_device();
|
||||
if (!rotary || !input) {
|
||||
error = -ENOMEM;
|
||||
goto out1;
|
||||
}
|
||||
rotary = devm_kzalloc(dev, sizeof(struct bfin_rot), GFP_KERNEL);
|
||||
if (!rotary)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
rotary->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(rotary->base))
|
||||
return PTR_ERR(rotary->base);
|
||||
|
||||
input = devm_input_allocate_device(dev);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
||||
rotary->input = input;
|
||||
|
||||
@ -122,9 +184,8 @@ static int bfin_rotary_probe(struct platform_device *pdev)
|
||||
rotary->button_key = pdata->rotary_button_key;
|
||||
rotary->rel_code = pdata->rotary_rel_code;
|
||||
|
||||
error = rotary->irq = platform_get_irq(pdev, 0);
|
||||
if (error < 0)
|
||||
goto out1;
|
||||
rotary->mode = pdata->mode;
|
||||
rotary->debounce = pdata->debounce;
|
||||
|
||||
input->name = pdev->name;
|
||||
input->phys = "bfin-rotary/input0";
|
||||
@ -137,6 +198,9 @@ static int bfin_rotary_probe(struct platform_device *pdev)
|
||||
input->id.product = 0x0001;
|
||||
input->id.version = 0x0100;
|
||||
|
||||
input->open = bfin_rotary_open;
|
||||
input->close = bfin_rotary_close;
|
||||
|
||||
if (rotary->up_key) {
|
||||
__set_bit(EV_KEY, input->evbit);
|
||||
__set_bit(rotary->up_key, input->keybit);
|
||||
@ -151,75 +215,43 @@ static int bfin_rotary_probe(struct platform_device *pdev)
|
||||
__set_bit(rotary->button_key, input->keybit);
|
||||
}
|
||||
|
||||
error = request_irq(rotary->irq, bfin_rotary_isr,
|
||||
0, dev_name(&pdev->dev), pdev);
|
||||
/* Quiesce the device before requesting irq */
|
||||
bfin_rotary_close(input);
|
||||
|
||||
rotary->irq = platform_get_irq(pdev, 0);
|
||||
if (rotary->irq < 0) {
|
||||
dev_err(dev, "No rotary IRQ specified\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
error = devm_request_irq(dev, rotary->irq, bfin_rotary_isr,
|
||||
0, dev_name(dev), rotary);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev,
|
||||
"unable to claim irq %d; error %d\n",
|
||||
dev_err(dev, "unable to claim irq %d; error %d\n",
|
||||
rotary->irq, error);
|
||||
goto out1;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev,
|
||||
"unable to register input device (%d)\n", error);
|
||||
goto out2;
|
||||
dev_err(dev, "unable to register input device (%d)\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (pdata->rotary_button_key)
|
||||
bfin_write_CNT_IMASK(CZMIE);
|
||||
|
||||
if (pdata->mode & ROT_DEBE)
|
||||
bfin_write_CNT_DEBOUNCE(pdata->debounce & DPRESCALE);
|
||||
|
||||
if (pdata->mode)
|
||||
bfin_write_CNT_CONFIG(bfin_read_CNT_CONFIG() |
|
||||
(pdata->mode & ~CNTE));
|
||||
|
||||
bfin_write_CNT_IMASK(bfin_read_CNT_IMASK() | UCIE | DCIE);
|
||||
bfin_write_CNT_CONFIG(bfin_read_CNT_CONFIG() | CNTE);
|
||||
|
||||
platform_set_drvdata(pdev, rotary);
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
out2:
|
||||
free_irq(rotary->irq, pdev);
|
||||
out1:
|
||||
input_free_device(input);
|
||||
kfree(rotary);
|
||||
peripheral_free_list(per_cnt);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int bfin_rotary_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct bfin_rot *rotary = platform_get_drvdata(pdev);
|
||||
|
||||
bfin_write_CNT_CONFIG(0);
|
||||
bfin_write_CNT_IMASK(0);
|
||||
|
||||
free_irq(rotary->irq, pdev);
|
||||
input_unregister_device(rotary->input);
|
||||
peripheral_free_list(per_cnt);
|
||||
|
||||
kfree(rotary);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int bfin_rotary_suspend(struct device *dev)
|
||||
static int __maybe_unused bfin_rotary_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct bfin_rot *rotary = platform_get_drvdata(pdev);
|
||||
|
||||
rotary->cnt_config = bfin_read_CNT_CONFIG();
|
||||
rotary->cnt_imask = bfin_read_CNT_IMASK();
|
||||
rotary->cnt_debounce = bfin_read_CNT_DEBOUNCE();
|
||||
rotary->cnt_config = readw(rotary->base + CNT_CONFIG_OFF);
|
||||
rotary->cnt_imask = readw(rotary->base + CNT_IMASK_OFF);
|
||||
rotary->cnt_debounce = readw(rotary->base + CNT_DEBOUNCE_OFF);
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
enable_irq_wake(rotary->irq);
|
||||
@ -227,38 +259,32 @@ static int bfin_rotary_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bfin_rotary_resume(struct device *dev)
|
||||
static int __maybe_unused bfin_rotary_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct bfin_rot *rotary = platform_get_drvdata(pdev);
|
||||
|
||||
bfin_write_CNT_DEBOUNCE(rotary->cnt_debounce);
|
||||
bfin_write_CNT_IMASK(rotary->cnt_imask);
|
||||
bfin_write_CNT_CONFIG(rotary->cnt_config & ~CNTE);
|
||||
writew(rotary->cnt_debounce, rotary->base + CNT_DEBOUNCE_OFF);
|
||||
writew(rotary->cnt_imask, rotary->base + CNT_IMASK_OFF);
|
||||
writew(rotary->cnt_config & ~CNTE, rotary->base + CNT_CONFIG_OFF);
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
disable_irq_wake(rotary->irq);
|
||||
|
||||
if (rotary->cnt_config & CNTE)
|
||||
bfin_write_CNT_CONFIG(rotary->cnt_config);
|
||||
writew(rotary->cnt_config, rotary->base + CNT_CONFIG_OFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops bfin_rotary_pm_ops = {
|
||||
.suspend = bfin_rotary_suspend,
|
||||
.resume = bfin_rotary_resume,
|
||||
};
|
||||
#endif
|
||||
static SIMPLE_DEV_PM_OPS(bfin_rotary_pm_ops,
|
||||
bfin_rotary_suspend, bfin_rotary_resume);
|
||||
|
||||
static struct platform_driver bfin_rotary_device_driver = {
|
||||
.probe = bfin_rotary_probe,
|
||||
.remove = bfin_rotary_remove,
|
||||
.driver = {
|
||||
.name = "bfin-rotary",
|
||||
#ifdef CONFIG_PM
|
||||
.pm = &bfin_rotary_pm_ops,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
module_platform_driver(bfin_rotary_device_driver);
|
||||
|
@ -195,7 +195,7 @@ static int soc_button_probe(struct platform_device *pdev)
|
||||
|
||||
static struct soc_button_info soc_button_PNP0C40[] = {
|
||||
{ "power", 0, EV_KEY, KEY_POWER, false, true },
|
||||
{ "home", 1, EV_KEY, KEY_HOME, false, true },
|
||||
{ "home", 1, EV_KEY, KEY_LEFTMETA, false, true },
|
||||
{ "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
|
||||
{ "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false },
|
||||
{ "rotation_lock", 4, EV_SW, SW_ROTATE_LOCK, false, false },
|
||||
|
@ -99,36 +99,58 @@ static const struct alps_nibble_commands alps_v6_nibble_commands[] = {
|
||||
#define ALPS_FOUR_BUTTONS 0x40 /* 4 direction button present */
|
||||
#define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with
|
||||
6-byte ALPS packet */
|
||||
#define ALPS_IS_RUSHMORE 0x100 /* device is a rushmore */
|
||||
#define ALPS_BUTTONPAD 0x200 /* device is a clickpad */
|
||||
|
||||
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 */
|
||||
{ { 0x53, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
{ { 0x53, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
{ { 0x60, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, /* HP ze1115 */
|
||||
{ { 0x63, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
{ { 0x63, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
{ { 0x63, 0x02, 0x28 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
|
||||
{ { 0x63, 0x02, 0x3c }, 0x00, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
|
||||
{ { 0x63, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
|
||||
{ { 0x63, 0x02, 0x64 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
{ { 0x63, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */
|
||||
{ { 0x73, 0x00, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */
|
||||
{ { 0x73, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
|
||||
{ { 0x73, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
|
||||
{ { 0x20, 0x02, 0x0e }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
|
||||
{ { 0x22, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
|
||||
{ { 0x22, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
|
||||
{ { 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 */
|
||||
{ { 0x53, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x53, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x60, 0x03, 0xc8 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, /* HP ze1115 */
|
||||
{ { 0x63, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x63, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x63, 0x02, 0x28 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Fujitsu Siemens S6010 */
|
||||
{ { 0x63, 0x02, 0x3c }, 0x00, { ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL } }, /* Toshiba Satellite S2400-103 */
|
||||
{ { 0x63, 0x02, 0x50 }, 0x00, { ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 } }, /* NEC Versa L320 */
|
||||
{ { 0x63, 0x02, 0x64 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x63, 0x03, 0xc8 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D800 */
|
||||
{ { 0x73, 0x00, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT } }, /* ThinkPad R61 8918-5QG */
|
||||
{ { 0x73, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x73, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Ahtec Laptop */
|
||||
|
||||
/*
|
||||
* XXX This entry is suspicious. First byte has zero lower nibble,
|
||||
* which is what a normal mouse would report. Also, the value 0x0e
|
||||
* isn't valid per PS/2 spec.
|
||||
*/
|
||||
{ { 0x20, 0x02, 0x0e }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },
|
||||
|
||||
{ { 0x22, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },
|
||||
{ { 0x22, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D600 */
|
||||
/* 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 */
|
||||
{ { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 },
|
||||
{ { 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 */
|
||||
{ { 0x73, 0x02, 0x64 }, 0x8a, { ALPS_PROTO_V4, 0x8f, 0x8f, 0 } },
|
||||
};
|
||||
|
||||
static const struct alps_protocol_info alps_v3_protocol_data = {
|
||||
ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT
|
||||
};
|
||||
|
||||
static const struct alps_protocol_info alps_v3_rushmore_data = {
|
||||
ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT
|
||||
};
|
||||
|
||||
static const struct alps_protocol_info alps_v5_protocol_data = {
|
||||
ALPS_PROTO_V5, 0xc8, 0xd8, 0
|
||||
};
|
||||
|
||||
static const struct alps_protocol_info alps_v7_protocol_data = {
|
||||
ALPS_PROTO_V7, 0x48, 0x48, ALPS_DUALPOINT
|
||||
};
|
||||
|
||||
static void alps_set_abs_params_st(struct alps_data *priv,
|
||||
@ -136,12 +158,6 @@ static void alps_set_abs_params_st(struct alps_data *priv,
|
||||
static void alps_set_abs_params_mt(struct alps_data *priv,
|
||||
struct input_dev *dev1);
|
||||
|
||||
/*
|
||||
* XXX - this entry is suspicious. First byte has zero lower nibble,
|
||||
* which is what a normal mouse would report. Also, the value 0x0e
|
||||
* isn't valid per PS/2 spec.
|
||||
*/
|
||||
|
||||
/* Packet formats are described in Documentation/input/alps.txt */
|
||||
|
||||
static bool alps_is_valid_first_byte(struct alps_data *priv,
|
||||
@ -150,8 +166,7 @@ static bool alps_is_valid_first_byte(struct alps_data *priv,
|
||||
return (data & priv->mask0) == priv->byte0;
|
||||
}
|
||||
|
||||
static void alps_report_buttons(struct psmouse *psmouse,
|
||||
struct input_dev *dev1, struct input_dev *dev2,
|
||||
static void alps_report_buttons(struct input_dev *dev1, struct input_dev *dev2,
|
||||
int left, int right, int middle)
|
||||
{
|
||||
struct input_dev *dev;
|
||||
@ -161,20 +176,21 @@ static void alps_report_buttons(struct psmouse *psmouse,
|
||||
* other device (dev2) then this event should be also
|
||||
* sent through that device.
|
||||
*/
|
||||
dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
|
||||
dev = (dev2 && test_bit(BTN_LEFT, dev2->key)) ? dev2 : dev1;
|
||||
input_report_key(dev, BTN_LEFT, left);
|
||||
|
||||
dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
|
||||
dev = (dev2 && test_bit(BTN_RIGHT, dev2->key)) ? dev2 : dev1;
|
||||
input_report_key(dev, BTN_RIGHT, right);
|
||||
|
||||
dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
|
||||
dev = (dev2 && test_bit(BTN_MIDDLE, dev2->key)) ? dev2 : dev1;
|
||||
input_report_key(dev, BTN_MIDDLE, middle);
|
||||
|
||||
/*
|
||||
* Sync the _other_ device now, we'll do the first
|
||||
* device later once we report the rest of the events.
|
||||
*/
|
||||
input_sync(dev2);
|
||||
if (dev2)
|
||||
input_sync(dev2);
|
||||
}
|
||||
|
||||
static void alps_process_packet_v1_v2(struct psmouse *psmouse)
|
||||
@ -221,13 +237,13 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
|
||||
input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x));
|
||||
input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
|
||||
|
||||
alps_report_buttons(psmouse, dev2, dev, left, right, middle);
|
||||
alps_report_buttons(dev2, dev, left, right, middle);
|
||||
|
||||
input_sync(dev2);
|
||||
return;
|
||||
}
|
||||
|
||||
alps_report_buttons(psmouse, dev, dev2, left, right, middle);
|
||||
alps_report_buttons(dev, dev2, left, right, middle);
|
||||
|
||||
/* Convert hardware tap to a reasonable Z value */
|
||||
if (ges && !fin)
|
||||
@ -412,7 +428,7 @@ static int alps_process_bitmap(struct alps_data *priv,
|
||||
(2 * (priv->y_bits - 1));
|
||||
|
||||
/* y-bitmap order is reversed, except on rushmore */
|
||||
if (!(priv->flags & ALPS_IS_RUSHMORE)) {
|
||||
if (priv->proto_version != ALPS_PROTO_V3_RUSHMORE) {
|
||||
fields->mt[0].y = priv->y_max - fields->mt[0].y;
|
||||
fields->mt[1].y = priv->y_max - fields->mt[1].y;
|
||||
}
|
||||
@ -648,7 +664,8 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
|
||||
*/
|
||||
if (f->is_mp) {
|
||||
fingers = f->fingers;
|
||||
if (priv->proto_version == ALPS_PROTO_V3) {
|
||||
if (priv->proto_version == ALPS_PROTO_V3 ||
|
||||
priv->proto_version == ALPS_PROTO_V3_RUSHMORE) {
|
||||
if (alps_process_bitmap(priv, f) == 0)
|
||||
fingers = 0; /* Use st data */
|
||||
|
||||
@ -892,34 +909,6 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
|
||||
unsigned char *pkt,
|
||||
unsigned char pkt_id)
|
||||
{
|
||||
/*
|
||||
* packet-fmt b7 b6 b5 b4 b3 b2 b1 b0
|
||||
* Byte0 TWO & MULTI L 1 R M 1 Y0-2 Y0-1 Y0-0
|
||||
* Byte0 NEW L 1 X1-5 1 1 Y0-2 Y0-1 Y0-0
|
||||
* Byte1 Y0-10 Y0-9 Y0-8 Y0-7 Y0-6 Y0-5 Y0-4 Y0-3
|
||||
* Byte2 X0-11 1 X0-10 X0-9 X0-8 X0-7 X0-6 X0-5
|
||||
* Byte3 X1-11 1 X0-4 X0-3 1 X0-2 X0-1 X0-0
|
||||
* Byte4 TWO X1-10 TWO X1-9 X1-8 X1-7 X1-6 X1-5 X1-4
|
||||
* Byte4 MULTI X1-10 TWO X1-9 X1-8 X1-7 X1-6 Y1-5 1
|
||||
* Byte4 NEW X1-10 TWO X1-9 X1-8 X1-7 X1-6 0 0
|
||||
* Byte5 TWO & NEW Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 Y1-5 Y1-4
|
||||
* Byte5 MULTI Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 F-1 F-0
|
||||
* L: Left button
|
||||
* R / M: Non-clickpads: Right / Middle button
|
||||
* Clickpads: When > 2 fingers are down, and some fingers
|
||||
* are in the button area, then the 2 coordinates reported
|
||||
* are for fingers outside the button area and these report
|
||||
* extra fingers being present in the right / left button
|
||||
* area. Note these fingers are not added to the F field!
|
||||
* so if a TWO packet is received and R = 1 then there are
|
||||
* 3 fingers down, etc.
|
||||
* TWO: 1: Two touches present, byte 0/4/5 are in TWO fmt
|
||||
* 0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt
|
||||
* otherwise byte 0 bit 4 must be set and byte 0/4/5 are
|
||||
* in NEW fmt
|
||||
* F: Number of fingers - 3, 0 means 3 fingers, 1 means 4 ...
|
||||
*/
|
||||
|
||||
mt[0].x = ((pkt[2] & 0x80) << 4);
|
||||
mt[0].x |= ((pkt[2] & 0x3F) << 5);
|
||||
mt[0].x |= ((pkt[3] & 0x30) >> 1);
|
||||
@ -1044,17 +1033,6 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* b7 b6 b5 b4 b3 b2 b1 b0
|
||||
* Byte0 0 1 0 0 1 0 0 0
|
||||
* Byte1 1 1 * * 1 M R L
|
||||
* Byte2 X7 1 X5 X4 X3 X2 X1 X0
|
||||
* Byte3 Z6 1 Y6 X6 1 Y2 Y1 Y0
|
||||
* Byte4 Y7 0 Y5 Y4 Y3 1 1 0
|
||||
* Byte5 T&P 0 Z5 Z4 Z3 Z2 Z1 Z0
|
||||
* M / R / L: Middle / Right / Left button
|
||||
*/
|
||||
|
||||
x = ((packet[2] & 0xbf)) | ((packet[3] & 0x10) << 2);
|
||||
y = (packet[3] & 0x07) | (packet[4] & 0xb8) |
|
||||
((packet[3] & 0x20) << 1);
|
||||
@ -1107,23 +1085,89 @@ static void alps_process_packet_v7(struct psmouse *psmouse)
|
||||
alps_process_touchpad_packet_v7(psmouse);
|
||||
}
|
||||
|
||||
static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
|
||||
static DEFINE_MUTEX(alps_mutex);
|
||||
|
||||
static void alps_register_bare_ps2_mouse(struct work_struct *work)
|
||||
{
|
||||
struct alps_data *priv =
|
||||
container_of(work, struct alps_data, dev3_register_work.work);
|
||||
struct psmouse *psmouse = priv->psmouse;
|
||||
struct input_dev *dev3;
|
||||
int error = 0;
|
||||
|
||||
mutex_lock(&alps_mutex);
|
||||
|
||||
if (priv->dev3)
|
||||
goto out;
|
||||
|
||||
dev3 = input_allocate_device();
|
||||
if (!dev3) {
|
||||
psmouse_err(psmouse, "failed to allocate secondary device\n");
|
||||
error = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
snprintf(priv->phys3, sizeof(priv->phys3), "%s/%s",
|
||||
psmouse->ps2dev.serio->phys,
|
||||
(priv->dev2 ? "input2" : "input1"));
|
||||
dev3->phys = priv->phys3;
|
||||
|
||||
/*
|
||||
* format of input device name is: "protocol vendor name"
|
||||
* see function psmouse_switch_protocol() in psmouse-base.c
|
||||
*/
|
||||
dev3->name = "PS/2 ALPS Mouse";
|
||||
|
||||
dev3->id.bustype = BUS_I8042;
|
||||
dev3->id.vendor = 0x0002;
|
||||
dev3->id.product = PSMOUSE_PS2;
|
||||
dev3->id.version = 0x0000;
|
||||
dev3->dev.parent = &psmouse->ps2dev.serio->dev;
|
||||
|
||||
input_set_capability(dev3, EV_REL, REL_X);
|
||||
input_set_capability(dev3, EV_REL, REL_Y);
|
||||
input_set_capability(dev3, EV_KEY, BTN_LEFT);
|
||||
input_set_capability(dev3, EV_KEY, BTN_RIGHT);
|
||||
input_set_capability(dev3, EV_KEY, BTN_MIDDLE);
|
||||
|
||||
__set_bit(INPUT_PROP_POINTER, dev3->propbit);
|
||||
|
||||
error = input_register_device(dev3);
|
||||
if (error) {
|
||||
psmouse_err(psmouse,
|
||||
"failed to register secondary device: %d\n",
|
||||
error);
|
||||
input_free_device(dev3);
|
||||
goto out;
|
||||
}
|
||||
|
||||
priv->dev3 = dev3;
|
||||
|
||||
out:
|
||||
/*
|
||||
* Save the error code so that we can detect that we
|
||||
* already tried to create the device.
|
||||
*/
|
||||
if (error)
|
||||
priv->dev3 = ERR_PTR(error);
|
||||
|
||||
mutex_unlock(&alps_mutex);
|
||||
}
|
||||
|
||||
static void alps_report_bare_ps2_packet(struct input_dev *dev,
|
||||
unsigned char packet[],
|
||||
bool report_buttons)
|
||||
{
|
||||
struct alps_data *priv = psmouse->private;
|
||||
struct input_dev *dev2 = priv->dev2;
|
||||
|
||||
if (report_buttons)
|
||||
alps_report_buttons(psmouse, dev2, psmouse->dev,
|
||||
alps_report_buttons(dev, NULL,
|
||||
packet[0] & 1, packet[0] & 2, packet[0] & 4);
|
||||
|
||||
input_report_rel(dev2, REL_X,
|
||||
input_report_rel(dev, REL_X,
|
||||
packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
|
||||
input_report_rel(dev2, REL_Y,
|
||||
input_report_rel(dev, REL_Y,
|
||||
packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
|
||||
|
||||
input_sync(dev2);
|
||||
input_sync(dev);
|
||||
}
|
||||
|
||||
static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
|
||||
@ -1188,8 +1232,8 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
|
||||
* de-synchronization.
|
||||
*/
|
||||
|
||||
alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3],
|
||||
false);
|
||||
alps_report_bare_ps2_packet(priv->dev2,
|
||||
&psmouse->packet[3], false);
|
||||
|
||||
/*
|
||||
* Continue with the standard ALPS protocol handling,
|
||||
@ -1245,9 +1289,18 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
|
||||
* properly we only do this if the device is fully synchronized.
|
||||
*/
|
||||
if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) {
|
||||
|
||||
/* Register dev3 mouse if we received PS/2 packet first time */
|
||||
if (unlikely(!priv->dev3))
|
||||
psmouse_queue_work(psmouse,
|
||||
&priv->dev3_register_work, 0);
|
||||
|
||||
if (psmouse->pktcnt == 3) {
|
||||
alps_report_bare_ps2_packet(psmouse, psmouse->packet,
|
||||
true);
|
||||
/* Once dev3 mouse device is registered report data */
|
||||
if (likely(!IS_ERR_OR_NULL(priv->dev3)))
|
||||
alps_report_bare_ps2_packet(priv->dev3,
|
||||
psmouse->packet,
|
||||
true);
|
||||
return PSMOUSE_FULL_PACKET;
|
||||
}
|
||||
return PSMOUSE_GOOD_DATA;
|
||||
@ -1275,7 +1328,7 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
|
||||
psmouse->pktcnt - 1,
|
||||
psmouse->packet[psmouse->pktcnt - 1]);
|
||||
|
||||
if (priv->proto_version == ALPS_PROTO_V3 &&
|
||||
if (priv->proto_version == ALPS_PROTO_V3_RUSHMORE &&
|
||||
psmouse->pktcnt == psmouse->pktsize) {
|
||||
/*
|
||||
* Some Dell boxes, such as Latitude E6440 or E7440
|
||||
@ -1780,7 +1833,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
|
||||
* all.
|
||||
*/
|
||||
if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) {
|
||||
psmouse_warn(psmouse, "trackstick E7 report failed\n");
|
||||
psmouse_warn(psmouse, "Failed to initialize trackstick (E7 report failed)\n");
|
||||
ret = -ENODEV;
|
||||
} else {
|
||||
psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param);
|
||||
@ -1945,8 +1998,6 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
|
||||
ALPS_REG_BASE_RUSHMORE);
|
||||
if (reg_val == -EIO)
|
||||
goto error;
|
||||
if (reg_val == -ENODEV)
|
||||
priv->flags &= ~ALPS_DUALPOINT;
|
||||
}
|
||||
|
||||
if (alps_enter_command_mode(psmouse) ||
|
||||
@ -2162,11 +2213,18 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void alps_set_defaults(struct alps_data *priv)
|
||||
static int alps_set_protocol(struct psmouse *psmouse,
|
||||
struct alps_data *priv,
|
||||
const struct alps_protocol_info *protocol)
|
||||
{
|
||||
priv->byte0 = 0x8f;
|
||||
priv->mask0 = 0x8f;
|
||||
priv->flags = ALPS_DUALPOINT;
|
||||
psmouse->private = priv;
|
||||
|
||||
setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse);
|
||||
|
||||
priv->proto_version = protocol->version;
|
||||
priv->byte0 = protocol->byte0;
|
||||
priv->mask0 = protocol->mask0;
|
||||
priv->flags = protocol->flags;
|
||||
|
||||
priv->x_max = 2000;
|
||||
priv->y_max = 1400;
|
||||
@ -2182,6 +2240,7 @@ static void alps_set_defaults(struct alps_data *priv)
|
||||
priv->x_max = 1023;
|
||||
priv->y_max = 767;
|
||||
break;
|
||||
|
||||
case ALPS_PROTO_V3:
|
||||
priv->hw_init = alps_hw_init_v3;
|
||||
priv->process_packet = alps_process_packet_v3;
|
||||
@ -2190,6 +2249,23 @@ static void alps_set_defaults(struct alps_data *priv)
|
||||
priv->nibble_commands = alps_v3_nibble_commands;
|
||||
priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
|
||||
break;
|
||||
|
||||
case ALPS_PROTO_V3_RUSHMORE:
|
||||
priv->hw_init = alps_hw_init_rushmore_v3;
|
||||
priv->process_packet = alps_process_packet_v3;
|
||||
priv->set_abs_params = alps_set_abs_params_mt;
|
||||
priv->decode_fields = alps_decode_rushmore;
|
||||
priv->nibble_commands = alps_v3_nibble_commands;
|
||||
priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
|
||||
priv->x_bits = 16;
|
||||
priv->y_bits = 12;
|
||||
|
||||
if (alps_probe_trackstick_v3(psmouse,
|
||||
ALPS_REG_BASE_RUSHMORE) < 0)
|
||||
priv->flags &= ~ALPS_DUALPOINT;
|
||||
|
||||
break;
|
||||
|
||||
case ALPS_PROTO_V4:
|
||||
priv->hw_init = alps_hw_init_v4;
|
||||
priv->process_packet = alps_process_packet_v4;
|
||||
@ -2197,6 +2273,7 @@ static void alps_set_defaults(struct alps_data *priv)
|
||||
priv->nibble_commands = alps_v4_nibble_commands;
|
||||
priv->addr_command = PSMOUSE_CMD_DISABLE;
|
||||
break;
|
||||
|
||||
case ALPS_PROTO_V5:
|
||||
priv->hw_init = alps_hw_init_dolphin_v1;
|
||||
priv->process_packet = alps_process_touchpad_packet_v3_v5;
|
||||
@ -2204,14 +2281,12 @@ static void alps_set_defaults(struct alps_data *priv)
|
||||
priv->set_abs_params = alps_set_abs_params_mt;
|
||||
priv->nibble_commands = alps_v3_nibble_commands;
|
||||
priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
|
||||
priv->byte0 = 0xc8;
|
||||
priv->mask0 = 0xd8;
|
||||
priv->flags = 0;
|
||||
priv->x_max = 1360;
|
||||
priv->y_max = 660;
|
||||
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;
|
||||
@ -2220,6 +2295,7 @@ static void alps_set_defaults(struct alps_data *priv)
|
||||
priv->x_max = 2047;
|
||||
priv->y_max = 1535;
|
||||
break;
|
||||
|
||||
case ALPS_PROTO_V7:
|
||||
priv->hw_init = alps_hw_init_v7;
|
||||
priv->process_packet = alps_process_packet_v7;
|
||||
@ -2227,19 +2303,21 @@ static void alps_set_defaults(struct alps_data *priv)
|
||||
priv->set_abs_params = alps_set_abs_params_mt;
|
||||
priv->nibble_commands = alps_v3_nibble_commands;
|
||||
priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
|
||||
priv->x_max = 0xfff;
|
||||
priv->y_max = 0x7ff;
|
||||
priv->byte0 = 0x48;
|
||||
priv->mask0 = 0x48;
|
||||
|
||||
if (alps_dolphin_get_device_area(psmouse, priv))
|
||||
return -EIO;
|
||||
|
||||
if (priv->fw_ver[1] != 0xba)
|
||||
priv->flags |= ALPS_BUTTONPAD;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv,
|
||||
unsigned char *e7, unsigned char *ec)
|
||||
static const struct alps_protocol_info *alps_match_table(unsigned char *e7,
|
||||
unsigned char *ec)
|
||||
{
|
||||
const struct alps_model_info *model;
|
||||
int i;
|
||||
@ -2251,23 +2329,18 @@ static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv,
|
||||
(!model->command_mode_resp ||
|
||||
model->command_mode_resp == ec[2])) {
|
||||
|
||||
priv->proto_version = model->proto_version;
|
||||
alps_set_defaults(priv);
|
||||
|
||||
priv->flags = model->flags;
|
||||
priv->byte0 = model->byte0;
|
||||
priv->mask0 = model->mask0;
|
||||
|
||||
return 0;
|
||||
return &model->protocol_info;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
|
||||
{
|
||||
const struct alps_protocol_info *protocol;
|
||||
unsigned char e6[4], e7[4], ec[4];
|
||||
int error;
|
||||
|
||||
/*
|
||||
* First try "E6 report".
|
||||
@ -2293,54 +2366,35 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
|
||||
alps_exit_command_mode(psmouse))
|
||||
return -EIO;
|
||||
|
||||
/* Save the Firmware version */
|
||||
memcpy(priv->fw_ver, ec, 3);
|
||||
|
||||
if (alps_match_table(psmouse, priv, e7, ec) == 0) {
|
||||
return 0;
|
||||
} else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
|
||||
ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) {
|
||||
priv->proto_version = ALPS_PROTO_V5;
|
||||
alps_set_defaults(priv);
|
||||
if (alps_dolphin_get_device_area(psmouse, priv))
|
||||
return -EIO;
|
||||
else
|
||||
return 0;
|
||||
} else if (ec[0] == 0x88 &&
|
||||
((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) {
|
||||
priv->proto_version = ALPS_PROTO_V7;
|
||||
alps_set_defaults(priv);
|
||||
|
||||
return 0;
|
||||
} else if (ec[0] == 0x88 && ec[1] == 0x08) {
|
||||
priv->proto_version = ALPS_PROTO_V3;
|
||||
alps_set_defaults(priv);
|
||||
|
||||
priv->hw_init = alps_hw_init_rushmore_v3;
|
||||
priv->decode_fields = alps_decode_rushmore;
|
||||
priv->x_bits = 16;
|
||||
priv->y_bits = 12;
|
||||
priv->flags |= ALPS_IS_RUSHMORE;
|
||||
|
||||
/* hack to make addr_command, nibble_command available */
|
||||
psmouse->private = priv;
|
||||
|
||||
if (alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE))
|
||||
priv->flags &= ~ALPS_DUALPOINT;
|
||||
|
||||
return 0;
|
||||
} else if (ec[0] == 0x88 && ec[1] == 0x07 &&
|
||||
ec[2] >= 0x90 && ec[2] <= 0x9d) {
|
||||
priv->proto_version = ALPS_PROTO_V3;
|
||||
alps_set_defaults(priv);
|
||||
|
||||
return 0;
|
||||
protocol = alps_match_table(e7, ec);
|
||||
if (!protocol) {
|
||||
if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
|
||||
ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) {
|
||||
protocol = &alps_v5_protocol_data;
|
||||
} else if (ec[0] == 0x88 &&
|
||||
((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) {
|
||||
protocol = &alps_v7_protocol_data;
|
||||
} else if (ec[0] == 0x88 && ec[1] == 0x08) {
|
||||
protocol = &alps_v3_rushmore_data;
|
||||
} else if (ec[0] == 0x88 && ec[1] == 0x07 &&
|
||||
ec[2] >= 0x90 && ec[2] <= 0x9d) {
|
||||
protocol = &alps_v3_protocol_data;
|
||||
} else {
|
||||
psmouse_dbg(psmouse,
|
||||
"Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
psmouse_dbg(psmouse,
|
||||
"Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec);
|
||||
if (priv) {
|
||||
/* Save the Firmware version */
|
||||
memcpy(priv->fw_ver, ec, 3);
|
||||
error = alps_set_protocol(psmouse, priv, protocol);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alps_reconnect(struct psmouse *psmouse)
|
||||
@ -2361,7 +2415,10 @@ static void alps_disconnect(struct psmouse *psmouse)
|
||||
|
||||
psmouse_reset(psmouse);
|
||||
del_timer_sync(&priv->timer);
|
||||
input_unregister_device(priv->dev2);
|
||||
if (priv->dev2)
|
||||
input_unregister_device(priv->dev2);
|
||||
if (!IS_ERR_OR_NULL(priv->dev3))
|
||||
input_unregister_device(priv->dev3);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
@ -2394,25 +2451,12 @@ static void alps_set_abs_params_mt(struct alps_data *priv,
|
||||
|
||||
int alps_init(struct psmouse *psmouse)
|
||||
{
|
||||
struct alps_data *priv;
|
||||
struct input_dev *dev1 = psmouse->dev, *dev2;
|
||||
struct alps_data *priv = psmouse->private;
|
||||
struct input_dev *dev1 = psmouse->dev;
|
||||
int error;
|
||||
|
||||
priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
|
||||
dev2 = input_allocate_device();
|
||||
if (!priv || !dev2)
|
||||
goto init_fail;
|
||||
|
||||
priv->dev2 = dev2;
|
||||
setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse);
|
||||
|
||||
psmouse->private = priv;
|
||||
|
||||
psmouse_reset(psmouse);
|
||||
|
||||
if (alps_identify(psmouse, priv) < 0)
|
||||
goto init_fail;
|
||||
|
||||
if (priv->hw_init(psmouse))
|
||||
error = priv->hw_init(psmouse);
|
||||
if (error)
|
||||
goto init_fail;
|
||||
|
||||
/*
|
||||
@ -2462,36 +2506,57 @@ int alps_init(struct psmouse *psmouse)
|
||||
}
|
||||
|
||||
if (priv->flags & ALPS_DUALPOINT) {
|
||||
struct input_dev *dev2;
|
||||
|
||||
dev2 = input_allocate_device();
|
||||
if (!dev2) {
|
||||
psmouse_err(psmouse,
|
||||
"failed to allocate trackstick device\n");
|
||||
error = -ENOMEM;
|
||||
goto init_fail;
|
||||
}
|
||||
|
||||
snprintf(priv->phys2, sizeof(priv->phys2), "%s/input1",
|
||||
psmouse->ps2dev.serio->phys);
|
||||
dev2->phys = priv->phys2;
|
||||
|
||||
/*
|
||||
* format of input device name is: "protocol vendor name"
|
||||
* see function psmouse_switch_protocol() in psmouse-base.c
|
||||
*/
|
||||
dev2->name = "AlpsPS/2 ALPS DualPoint Stick";
|
||||
|
||||
dev2->id.bustype = BUS_I8042;
|
||||
dev2->id.vendor = 0x0002;
|
||||
dev2->id.product = PSMOUSE_ALPS;
|
||||
dev2->id.version = priv->proto_version;
|
||||
} else {
|
||||
dev2->name = "PS/2 ALPS Mouse";
|
||||
dev2->id.product = PSMOUSE_PS2;
|
||||
dev2->id.version = 0x0000;
|
||||
}
|
||||
dev2->dev.parent = &psmouse->ps2dev.serio->dev;
|
||||
|
||||
snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
|
||||
dev2->phys = priv->phys;
|
||||
dev2->id.bustype = BUS_I8042;
|
||||
dev2->id.vendor = 0x0002;
|
||||
dev2->dev.parent = &psmouse->ps2dev.serio->dev;
|
||||
input_set_capability(dev2, EV_REL, REL_X);
|
||||
input_set_capability(dev2, EV_REL, REL_Y);
|
||||
input_set_capability(dev2, EV_KEY, BTN_LEFT);
|
||||
input_set_capability(dev2, EV_KEY, BTN_RIGHT);
|
||||
input_set_capability(dev2, EV_KEY, BTN_MIDDLE);
|
||||
|
||||
dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
|
||||
dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
|
||||
dev2->keybit[BIT_WORD(BTN_LEFT)] =
|
||||
BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
|
||||
|
||||
__set_bit(INPUT_PROP_POINTER, dev2->propbit);
|
||||
if (priv->flags & ALPS_DUALPOINT)
|
||||
__set_bit(INPUT_PROP_POINTER, dev2->propbit);
|
||||
__set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit);
|
||||
|
||||
if (input_register_device(priv->dev2))
|
||||
goto init_fail;
|
||||
error = input_register_device(dev2);
|
||||
if (error) {
|
||||
psmouse_err(psmouse,
|
||||
"failed to register trackstick device: %d\n",
|
||||
error);
|
||||
input_free_device(dev2);
|
||||
goto init_fail;
|
||||
}
|
||||
|
||||
priv->dev2 = dev2;
|
||||
}
|
||||
|
||||
priv->psmouse = psmouse;
|
||||
|
||||
INIT_DELAYED_WORK(&priv->dev3_register_work,
|
||||
alps_register_bare_ps2_mouse);
|
||||
|
||||
psmouse->protocol_handler = alps_process_byte;
|
||||
psmouse->poll = alps_poll;
|
||||
@ -2509,25 +2574,56 @@ int alps_init(struct psmouse *psmouse)
|
||||
|
||||
init_fail:
|
||||
psmouse_reset(psmouse);
|
||||
input_free_device(dev2);
|
||||
kfree(priv);
|
||||
/*
|
||||
* Even though we did not allocate psmouse->private we do free
|
||||
* it here.
|
||||
*/
|
||||
kfree(psmouse->private);
|
||||
psmouse->private = NULL;
|
||||
return -1;
|
||||
return error;
|
||||
}
|
||||
|
||||
int alps_detect(struct psmouse *psmouse, bool set_properties)
|
||||
{
|
||||
struct alps_data dummy;
|
||||
struct alps_data *priv;
|
||||
int error;
|
||||
|
||||
if (alps_identify(psmouse, &dummy) < 0)
|
||||
return -1;
|
||||
error = alps_identify(psmouse, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/*
|
||||
* Reset the device to make sure it is fully operational:
|
||||
* on some laptops, like certain Dell Latitudes, we may
|
||||
* fail to properly detect presence of trackstick if device
|
||||
* has not been reset.
|
||||
*/
|
||||
psmouse_reset(psmouse);
|
||||
|
||||
priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
error = alps_identify(psmouse, priv);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (set_properties) {
|
||||
psmouse->vendor = "ALPS";
|
||||
psmouse->name = dummy.flags & ALPS_DUALPOINT ?
|
||||
psmouse->name = priv->flags & ALPS_DUALPOINT ?
|
||||
"DualPoint TouchPad" : "GlidePoint";
|
||||
psmouse->model = dummy.proto_version << 8;
|
||||
psmouse->model = priv->proto_version;
|
||||
} else {
|
||||
/*
|
||||
* Destroy alps_data structure we allocated earlier since
|
||||
* this was just a "trial run". Otherwise we'll keep it
|
||||
* to be used by alps_init() which has to be called if
|
||||
* we succeed and set_properties is true.
|
||||
*/
|
||||
kfree(priv);
|
||||
psmouse->private = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -14,13 +14,14 @@
|
||||
|
||||
#include <linux/input/mt.h>
|
||||
|
||||
#define ALPS_PROTO_V1 1
|
||||
#define ALPS_PROTO_V2 2
|
||||
#define ALPS_PROTO_V3 3
|
||||
#define ALPS_PROTO_V4 4
|
||||
#define ALPS_PROTO_V5 5
|
||||
#define ALPS_PROTO_V6 6
|
||||
#define ALPS_PROTO_V7 7 /* t3btl t4s */
|
||||
#define ALPS_PROTO_V1 0x100
|
||||
#define ALPS_PROTO_V2 0x200
|
||||
#define ALPS_PROTO_V3 0x300
|
||||
#define ALPS_PROTO_V3_RUSHMORE 0x310
|
||||
#define ALPS_PROTO_V4 0x400
|
||||
#define ALPS_PROTO_V5 0x500
|
||||
#define ALPS_PROTO_V6 0x600
|
||||
#define ALPS_PROTO_V7 0x700 /* t3btl t4s */
|
||||
|
||||
#define MAX_TOUCHES 2
|
||||
|
||||
@ -45,6 +46,21 @@ enum V7_PACKET_ID {
|
||||
V7_PACKET_ID_UNKNOWN,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct alps_protocol_info - information about protocol used by a device
|
||||
* @version: Indicates V1/V2/V3/...
|
||||
* @byte0: Helps figure out whether a position report packet matches the
|
||||
* known format for this model. The first byte of the report, ANDed with
|
||||
* mask0, should match byte0.
|
||||
* @mask0: The mask used to check the first byte of the report.
|
||||
* @flags: Additional device capabilities (passthrough port, trackstick, etc.).
|
||||
*/
|
||||
struct alps_protocol_info {
|
||||
u16 version;
|
||||
u8 byte0, mask0;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct alps_model_info - touchpad ID table
|
||||
* @signature: E7 response string to match.
|
||||
@ -52,23 +68,16 @@ enum V7_PACKET_ID {
|
||||
* (aka command mode response) identifies the firmware minor version. This
|
||||
* can be used to distinguish different hardware models which are not
|
||||
* uniquely identifiable through their E7 responses.
|
||||
* @proto_version: Indicates V1/V2/V3/...
|
||||
* @byte0: Helps figure out whether a position report packet matches the
|
||||
* known format for this model. The first byte of the report, ANDed with
|
||||
* mask0, should match byte0.
|
||||
* @mask0: The mask used to check the first byte of the report.
|
||||
* @flags: Additional device capabilities (passthrough port, trackstick, etc.).
|
||||
* @protocol_info: information about protcol used by the device.
|
||||
*
|
||||
* Many (but not all) ALPS touchpads can be identified by looking at the
|
||||
* values returned in the "E7 report" and/or the "EC report." This table
|
||||
* lists a number of such touchpads.
|
||||
*/
|
||||
struct alps_model_info {
|
||||
unsigned char signature[3];
|
||||
unsigned char command_mode_resp;
|
||||
unsigned char proto_version;
|
||||
unsigned char byte0, mask0;
|
||||
int flags;
|
||||
u8 signature[3];
|
||||
u8 command_mode_resp;
|
||||
struct alps_protocol_info protocol_info;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -132,8 +141,12 @@ struct alps_fields {
|
||||
|
||||
/**
|
||||
* struct alps_data - private data structure for the ALPS driver
|
||||
* @dev2: "Relative" device used to report trackstick or mouse activity.
|
||||
* @phys: Physical path for the relative device.
|
||||
* @psmouse: Pointer to parent psmouse device
|
||||
* @dev2: Trackstick device (can be NULL).
|
||||
* @dev3: Generic PS/2 mouse (can be NULL, delayed registering).
|
||||
* @phys2: Physical path for the trackstick device.
|
||||
* @phys3: Physical path for the generic PS/2 mouse.
|
||||
* @dev3_register_work: Delayed work for registering PS/2 mouse.
|
||||
* @nibble_commands: Command mapping used for touchpad register accesses.
|
||||
* @addr_command: Command used to tell the touchpad that a register address
|
||||
* follows.
|
||||
@ -160,15 +173,19 @@ struct alps_fields {
|
||||
* @timer: Timer for flushing out the final report packet in the stream.
|
||||
*/
|
||||
struct alps_data {
|
||||
struct psmouse *psmouse;
|
||||
struct input_dev *dev2;
|
||||
char phys[32];
|
||||
struct input_dev *dev3;
|
||||
char phys2[32];
|
||||
char phys3[32];
|
||||
struct delayed_work dev3_register_work;
|
||||
|
||||
/* these are autodetected when the device is identified */
|
||||
const struct alps_nibble_commands *nibble_commands;
|
||||
int addr_command;
|
||||
unsigned char proto_version;
|
||||
unsigned char byte0, mask0;
|
||||
unsigned char fw_ver[3];
|
||||
u16 proto_version;
|
||||
u8 byte0, mask0;
|
||||
u8 fw_ver[3];
|
||||
int flags;
|
||||
int x_max;
|
||||
int y_max;
|
||||
|
@ -710,8 +710,3 @@ err_exit:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool cypress_supported(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -172,7 +172,6 @@ struct cytp_data {
|
||||
#ifdef CONFIG_MOUSE_PS2_CYPRESS
|
||||
int cypress_detect(struct psmouse *psmouse, bool set_properties);
|
||||
int cypress_init(struct psmouse *psmouse);
|
||||
bool cypress_supported(void);
|
||||
#else
|
||||
inline int cypress_detect(struct psmouse *psmouse, bool set_properties)
|
||||
{
|
||||
@ -182,10 +181,6 @@ inline int cypress_init(struct psmouse *psmouse)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
inline bool cypress_supported(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_MOUSE_PS2_CYPRESS */
|
||||
|
||||
#endif /* _CYPRESS_PS2_H */
|
||||
|
@ -424,11 +424,6 @@ fail:
|
||||
return error;
|
||||
}
|
||||
|
||||
bool focaltech_supported(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#else /* CONFIG_MOUSE_PS2_FOCALTECH */
|
||||
|
||||
int focaltech_init(struct psmouse *psmouse)
|
||||
@ -438,9 +433,4 @@ int focaltech_init(struct psmouse *psmouse)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool focaltech_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MOUSE_PS2_FOCALTECH */
|
||||
|
@ -19,6 +19,5 @@
|
||||
|
||||
int focaltech_detect(struct psmouse *psmouse, bool set_properties);
|
||||
int focaltech_init(struct psmouse *psmouse);
|
||||
bool focaltech_supported(void);
|
||||
|
||||
#endif
|
||||
|
@ -727,7 +727,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
||||
if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) {
|
||||
if (max_proto > PSMOUSE_IMEX) {
|
||||
if (!set_properties || focaltech_init(psmouse) == 0) {
|
||||
if (focaltech_supported())
|
||||
if (IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH))
|
||||
return PSMOUSE_FOCALTECH;
|
||||
/*
|
||||
* Note that we need to also restrict
|
||||
@ -776,7 +776,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
||||
* Try activating protocol, but check if support is enabled first, since
|
||||
* we try detecting Synaptics even when protocol is disabled.
|
||||
*/
|
||||
if (synaptics_supported() &&
|
||||
if (IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS) &&
|
||||
(!set_properties || synaptics_init(psmouse) == 0)) {
|
||||
return PSMOUSE_SYNAPTICS;
|
||||
}
|
||||
@ -801,7 +801,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
||||
*/
|
||||
if (max_proto > PSMOUSE_IMEX &&
|
||||
cypress_detect(psmouse, set_properties) == 0) {
|
||||
if (cypress_supported()) {
|
||||
if (IS_ENABLED(CONFIG_MOUSE_PS2_CYPRESS)) {
|
||||
if (cypress_init(psmouse) == 0)
|
||||
return PSMOUSE_CYPRESS;
|
||||
|
||||
|
@ -1454,11 +1454,6 @@ int synaptics_init_relative(struct psmouse *psmouse)
|
||||
return __synaptics_init(psmouse, false);
|
||||
}
|
||||
|
||||
bool synaptics_supported(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#else /* CONFIG_MOUSE_PS2_SYNAPTICS */
|
||||
|
||||
void __init synaptics_module_init(void)
|
||||
@ -1470,9 +1465,4 @@ int synaptics_init(struct psmouse *psmouse)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
bool synaptics_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MOUSE_PS2_SYNAPTICS */
|
||||
|
@ -175,6 +175,5 @@ int synaptics_detect(struct psmouse *psmouse, bool set_properties);
|
||||
int synaptics_init(struct psmouse *psmouse);
|
||||
int synaptics_init_relative(struct psmouse *psmouse);
|
||||
void synaptics_reset(struct psmouse *psmouse);
|
||||
bool synaptics_supported(void);
|
||||
|
||||
#endif /* _SYNAPTICS_H */
|
||||
|
@ -40,6 +40,7 @@ struct bfin_rotary_platform_data {
|
||||
unsigned short debounce; /* 0..17 */
|
||||
unsigned short mode;
|
||||
unsigned short pm_wakeup;
|
||||
unsigned short *pin_list;
|
||||
};
|
||||
|
||||
/* CNT_CONFIG bitmasks */
|
Loading…
Reference in New Issue
Block a user