Commit 2d9f0d96 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Merge branch 'next' into for-linus

Prepare first set of updates for 3.9 merge window.
parents 9937c026 005a69d6
* Freescale i.MX Keypad Port(KPP) device tree bindings
The KPP is designed to interface with a keypad matrix with 2-point contact
or 3-point contact keys. The KPP is designed to simplify the software task
of scanning a keypad matrix. The KPP is capable of detecting, debouncing,
and decoding one or multiple keys pressed simultaneously on a keypad.
Required SoC Specific Properties:
- compatible: Should be "fsl,<soc>-kpp".
- reg: Physical base address of the KPP and length of memory mapped
region.
- interrupts: The KPP interrupt number to the CPU(s).
- clocks: The clock provided by the SoC to the KPP. Some SoCs use dummy
clock(The clock for the KPP is provided by the SoCs automatically).
Required Board Specific Properties:
- pinctrl-names: The definition can be found at
pinctrl/pinctrl-bindings.txt.
- pinctrl-0: The definition can be found at
pinctrl/pinctrl-bindings.txt.
- linux,keymap: The definition can be found at
bindings/input/matrix-keymap.txt.
Example:
kpp: kpp@73f94000 {
compatible = "fsl,imx51-kpp", "fsl,imx21-kpp";
reg = <0x73f94000 0x4000>;
interrupts = <60>;
clocks = <&clks 0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_kpp_1>;
linux,keymap = <0x00000067 /* KEY_UP */
0x0001006c /* KEY_DOWN */
0x00020072 /* KEY_VOLUMEDOWN */
0x00030066 /* KEY_HOME */
0x0100006a /* KEY_RIGHT */
0x01010069 /* KEY_LEFT */
0x0102001c /* KEY_ENTER */
0x01030073 /* KEY_VOLUMEUP */
0x02000040 /* KEY_F6 */
0x02010042 /* KEY_F8 */
0x02020043 /* KEY_F9 */
0x02030044 /* KEY_F10 */
0x0300003b /* KEY_F1 */
0x0301003c /* KEY_F2 */
0x0302003d /* KEY_F3 */
0x03030074>; /* KEY_POWER */
};
* Tegra keyboard controller
The key controller has maximum 24 pins to make matrix keypad. Any pin
can be configured as row or column. The maximum column pin can be 8
and maximum row pins can be 16 for Tegra20/Tegra30.
Required properties:
- compatible: "nvidia,tegra20-kbc"
- reg: Register base address of KBC.
- interrupts: Interrupt number for the KBC.
- nvidia,kbc-row-pins: The KBC pins which are configured as row. This is an
array of pin numbers which is used as rows.
- nvidia,kbc-col-pins: The KBC pins which are configured as column. This is an
array of pin numbers which is used as column.
- linux,keymap: The keymap for keys as described in the binding document
devicetree/bindings/input/matrix-keymap.txt.
Optional properties, in addition to those specified by the shared
matrix-keyboard bindings:
......@@ -19,5 +30,16 @@ Example:
keyboard: keyboard {
compatible = "nvidia,tegra20-kbc";
reg = <0x7000e200 0x100>;
interrupts = <0 85 0x04>;
nvidia,ghost-filter;
nvidia,debounce-delay-ms = <640>;
nvidia,kbc-row-pins = <0 1 2>; /* pin 0, 1, 2 as rows */
nvidia,kbc-col-pins = <11 12 13>; /* pin 11, 12, 13 as columns */
linux,keymap = <0x00000074
0x00010067
0x00020066
0x01010068
0x02000069
0x02010070
0x02020071>;
};
......@@ -3,7 +3,7 @@
#
menu "Input device support"
depends on !S390 && !UML
depends on !UML
config INPUT
tristate "Generic input layer (needed for keyboard, mouse, ...)" if EXPERT
......
......@@ -18,6 +18,7 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src)
{
if (dev->absinfo && test_bit(src, dev->absbit)) {
dev->absinfo[dst] = dev->absinfo[src];
dev->absinfo[dst].fuzz = 0;
dev->absbit[BIT_WORD(dst)] |= BIT_MASK(dst);
}
}
......
......@@ -12,7 +12,7 @@
* the Free Software Foundation.
*/
/* #define WK0701_DEBUG */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define RESERVE 20000
#define SYNC_PULSE 1306000
......@@ -67,6 +67,7 @@ static inline void walkera0701_parse_frame(struct walkera_dev *w)
{
int i;
int val1, val2, val3, val4, val5, val6, val7, val8;
int magic, magic_bit;
int crc1, crc2;
for (crc1 = crc2 = i = 0; i < 10; i++) {
......@@ -102,17 +103,12 @@ static inline void walkera0701_parse_frame(struct walkera_dev *w)
val8 = (w->buf[18] & 1) << 8 | (w->buf[19] << 4) | w->buf[20];
val8 *= (w->buf[18] & 2) - 1; /*sign */
#ifdef WK0701_DEBUG
{
int magic, magic_bit;
magic = (w->buf[21] << 4) | w->buf[22];
magic_bit = (w->buf[24] & 8) >> 3;
printk(KERN_DEBUG
"walkera0701: %4d %4d %4d %4d %4d %4d %4d %4d (magic %2x %d)\n",
val1, val2, val3, val4, val5, val6, val7, val8, magic,
magic_bit);
}
#endif
pr_debug("%4d %4d %4d %4d %4d %4d %4d %4d (magic %2x %d)\n",
val1, val2, val3, val4, val5, val6, val7, val8,
magic, magic_bit);
input_report_abs(w->input_dev, ABS_X, val2);
input_report_abs(w->input_dev, ABS_Y, val1);
input_report_abs(w->input_dev, ABS_Z, val6);
......@@ -187,6 +183,9 @@ static int walkera0701_open(struct input_dev *dev)
{
struct walkera_dev *w = input_get_drvdata(dev);
if (parport_claim(w->pardevice))
return -EBUSY;
parport_enable_irq(w->parport);
return 0;
}
......@@ -197,40 +196,51 @@ static void walkera0701_close(struct input_dev *dev)
parport_disable_irq(w->parport);
hrtimer_cancel(&w->timer);
parport_release(w->pardevice);
}
static int walkera0701_connect(struct walkera_dev *w, int parport)
{
int err = -ENODEV;
int error;
w->parport = parport_find_number(parport);
if (w->parport == NULL)
if (!w->parport) {
pr_err("parport %d does not exist\n", parport);
return -ENODEV;
}
if (w->parport->irq == -1) {
printk(KERN_ERR "walkera0701: parport without interrupt\n");
goto init_err;
pr_err("parport %d does not have interrupt assigned\n",
parport);
error = -EINVAL;
goto err_put_parport;
}
err = -EBUSY;
w->pardevice = parport_register_device(w->parport, "walkera0701",
NULL, NULL, walkera0701_irq_handler,
PARPORT_DEV_EXCL, w);
if (!w->pardevice)
goto init_err;
if (parport_negotiate(w->pardevice->port, IEEE1284_MODE_COMPAT))
goto init_err1;
if (!w->pardevice) {
pr_err("failed to register parport device\n");
error = -EIO;
goto err_put_parport;
}
if (parport_claim(w->pardevice))
goto init_err1;
if (parport_negotiate(w->pardevice->port, IEEE1284_MODE_COMPAT)) {
pr_err("failed to negotiate parport mode\n");
error = -EIO;
goto err_unregister_device;
}
hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
w->timer.function = timer_handler;
w->input_dev = input_allocate_device();
if (!w->input_dev)
goto init_err2;
if (!w->input_dev) {
pr_err("failed to allocate input device\n");
error = -ENOMEM;
goto err_unregister_device;
}
input_set_drvdata(w->input_dev, w);
w->input_dev->name = "Walkera WK-0701 TX";
......@@ -241,6 +251,7 @@ static int walkera0701_connect(struct walkera_dev *w, int parport)
w->input_dev->id.vendor = 0x0001;
w->input_dev->id.product = 0x0001;
w->input_dev->id.version = 0x0100;
w->input_dev->dev.parent = w->parport->dev;
w->input_dev->open = walkera0701_open;
w->input_dev->close = walkera0701_close;
......@@ -254,27 +265,26 @@ static int walkera0701_connect(struct walkera_dev *w, int parport)
input_set_abs_params(w->input_dev, ABS_RUDDER, -512, 512, 0, 0);
input_set_abs_params(w->input_dev, ABS_MISC, -512, 512, 0, 0);
err = input_register_device(w->input_dev);
if (err)
goto init_err3;
error = input_register_device(w->input_dev);
if (error) {
pr_err("failed to register input device\n");
goto err_free_input_dev;
}
return 0;
init_err3:
err_free_input_dev:
input_free_device(w->input_dev);
init_err2:
parport_release(w->pardevice);
init_err1:
err_unregister_device:
parport_unregister_device(w->pardevice);
init_err:
err_put_parport:
parport_put_port(w->parport);
return err;
return error;
}
static void walkera0701_disconnect(struct walkera_dev *w)
{
input_unregister_device(w->input_dev);
parport_release(w->pardevice);
parport_unregister_device(w->pardevice);
parport_put_port(w->parport);
}
......
......@@ -224,7 +224,7 @@ config KEYBOARD_TCA6416
config KEYBOARD_TCA8418
tristate "TCA8418 Keypad Support"
depends on I2C
depends on I2C && GENERIC_HARDIRQS
select INPUT_MATRIXKMAP
help
This driver implements basic keypad functionality
......@@ -303,7 +303,7 @@ config KEYBOARD_HP7XX
config KEYBOARD_LM8323
tristate "LM8323 keypad chip"
depends on I2C
depends on I2C && GENERIC_HARDIRQS
depends on LEDS_CLASS
help
If you say yes here you get support for the National Semiconductor
......@@ -420,7 +420,7 @@ config KEYBOARD_NOMADIK
config KEYBOARD_TEGRA
tristate "NVIDIA Tegra internal matrix keyboard controller support"
depends on ARCH_TEGRA
depends on ARCH_TEGRA && OF
select INPUT_MATRIXKMAP
help
Say Y here if you want to use a matrix keyboard connected directly
......@@ -479,6 +479,16 @@ config KEYBOARD_SAMSUNG
To compile this driver as a module, choose M here: the
module will be called samsung-keypad.
config KEYBOARD_GOLDFISH_EVENTS
depends on GOLDFISH
tristate "Generic Input Event device for Goldfish"
help
Say Y here to get an input event device for the Goldfish virtual
device emulator.
To compile this driver as a module, choose M here: the
module will be called goldfish-events.
config KEYBOARD_STOWAWAY
tristate "Stowaway keyboard"
select SERIO
......
......@@ -13,6 +13,7 @@ obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o
obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
obj-$(CONFIG_KEYBOARD_GOLDFISH_EVENTS) += goldfish_events.o
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o
obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o
......
......@@ -676,6 +676,39 @@ static inline void atkbd_disable(struct atkbd *atkbd)
serio_continue_rx(atkbd->ps2dev.serio);
}
static int atkbd_activate(struct atkbd *atkbd)
{
struct ps2dev *ps2dev = &atkbd->ps2dev;
/*
* Enable the keyboard to receive keystrokes.
*/
if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) {
dev_err(&ps2dev->serio->dev,
"Failed to enable keyboard on %s\n",
ps2dev->serio->phys);
return -1;
}
return 0;
}
/*
* atkbd_deactivate() resets and disables the keyboard from sending
* keystrokes.
*/
static void atkbd_deactivate(struct atkbd *atkbd)
{
struct ps2dev *ps2dev = &atkbd->ps2dev;
if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_DIS))
dev_err(&ps2dev->serio->dev,
"Failed to deactivate keyboard on %s\n",
ps2dev->serio->phys);
}
/*
* atkbd_probe() probes for an AT keyboard on a serio port.
*/
......@@ -726,11 +759,17 @@ static int atkbd_probe(struct atkbd *atkbd)
if (atkbd->id == 0xaca1 && atkbd->translated) {
dev_err(&ps2dev->serio->dev,
"NCD terminal keyboards are only supported on non-translating controlelrs. "
"NCD terminal keyboards are only supported on non-translating controllers. "
"Use i8042.direct=1 to disable translation.\n");
return -1;
}
/*
* Make sure nothing is coming from the keyboard and disturbs our
* internal state.
*/
atkbd_deactivate(atkbd);
return 0;
}
......@@ -825,24 +864,6 @@ static int atkbd_reset_state(struct atkbd *atkbd)
return 0;
}
static int atkbd_activate(struct atkbd *atkbd)
{
struct ps2dev *ps2dev = &atkbd->ps2dev;
/*
* Enable the keyboard to receive keystrokes.
*/
if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) {
dev_err(&ps2dev->serio->dev,
"Failed to enable keyboard on %s\n",
ps2dev->serio->phys);
return -1;
}
return 0;
}
/*
* atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
* reboot.
......@@ -1150,7 +1171,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
atkbd_reset_state(atkbd);
atkbd_activate(atkbd);
} else {
atkbd->set = 2;
......@@ -1165,6 +1185,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
goto fail3;
atkbd_enable(atkbd);
if (serio->write)
atkbd_activate(atkbd);
err = input_register_device(atkbd->dev);
if (err)
......@@ -1208,8 +1230,6 @@ static int atkbd_reconnect(struct serio *serio)
if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra))
goto out;
atkbd_activate(atkbd);
/*
* Restore LED state and repeat rate. While input core
* will do this for us at resume time reconnect may happen
......@@ -1223,7 +1243,17 @@ static int atkbd_reconnect(struct serio *serio)
}
/*
* Reset our state machine in case reconnect happened in the middle
* of multi-byte scancode.
*/
atkbd->xl_bit = 0;
atkbd->emul = 0;
atkbd_enable(atkbd);
if (atkbd->write)
atkbd_activate(atkbd);
retval = 0;
out:
......
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (C) 2012 Intel, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/io.h>
enum {
REG_READ = 0x00,
REG_SET_PAGE = 0x00,
REG_LEN = 0x04,
REG_DATA = 0x08,
PAGE_NAME = 0x00000,
PAGE_EVBITS = 0x10000,
PAGE_ABSDATA = 0x20000 | EV_ABS,
};
struct event_dev {
struct input_dev *input;
int irq;
void __iomem *addr;
char name[0];
};
static irqreturn_t events_interrupt(int irq, void *dev_id)
{
struct event_dev *edev = dev_id;
unsigned type, code, value;
type = __raw_readl(edev->addr + REG_READ);
code = __raw_readl(edev->addr + REG_READ);
value = __raw_readl(edev->addr + REG_READ);
input_event(edev->input, type, code, value);
input_sync(edev->input);
return IRQ_HANDLED;
}
static void events_import_bits(struct event_dev *edev,
unsigned long bits[], unsigned type, size_t count)
{
void __iomem *addr = edev->addr;
int i, j;
size_t size;
uint8_t val;
__raw_writel(PAGE_EVBITS | type, addr + REG_SET_PAGE);
size = __raw_readl(addr + REG_LEN) * 8;
if (size < count)
count = size;
addr += REG_DATA;
for (i = 0; i < count; i += 8) {
val = __raw_readb(addr++);
for (j = 0; j < 8; j++)
if (val & 1 << j)
set_bit(i + j, bits);
}
}
static void events_import_abs_params(struct event_dev *edev)
{
struct input_dev *input_dev = edev->input;
void __iomem *addr = edev->addr;
u32 val[4];
int count;
int i, j;
__raw_writel(PAGE_ABSDATA, addr + REG_SET_PAGE);
count = __raw_readl(addr + REG_LEN) / sizeof(val);
if (count > ABS_MAX)
count = ABS_MAX;
for (i = 0; i < count; i++) {
if (!test_bit(i, input_dev->absbit))
continue;
for (j = 0; j < ARRAY_SIZE(val); j++) {
int offset = (i * ARRAY_SIZE(val) + j) * sizeof(u32);
val[j] = __raw_readl(edev->addr + REG_DATA + offset);
}
input_set_abs_params(input_dev, i,
val[0], val[1], val[2], val[3]);
}
}
static int events_probe(struct platform_device *pdev)
{
struct input_dev *input_dev;
struct event_dev *edev;
struct resource *res;
unsigned keymapnamelen;
void __iomem *addr;
int irq;
int i;
int error;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EINVAL;
addr = devm_ioremap(&pdev->dev, res->start, 4096);
if (!addr)
return -ENOMEM;
__raw_writel(PAGE_NAME, addr + REG_SET_PAGE);
keymapnamelen = __raw_readl(addr + REG_LEN);
edev = devm_kzalloc(&pdev->dev,
sizeof(struct event_dev) + keymapnamelen + 1,
GFP_KERNEL);
if (!edev)
return -ENOMEM;
input_dev = devm_input_allocate_device(&pdev->dev);
if (!input_dev)
return -ENOMEM;
edev->input = input_dev;
edev->addr = addr;
edev->irq = irq;
for (i = 0; i < keymapnamelen; i++)
edev->name[i] = __raw_readb(edev->addr + REG_DATA + i);
pr_debug("events_probe() keymap=%s\n", edev->name);
input_dev->name = edev->name;
input_dev->id.bustype = BUS_HOST;
events_import_bits(edev, input_dev->evbit, EV_SYN, EV_MAX);
events_import_bits(edev, input_dev->keybit, EV_KEY, KEY_MAX);
events_import_bits(edev, input_dev->relbit, EV_REL, REL_MAX);
events_import_bits(edev, input_dev->absbit, EV_ABS, ABS_MAX);
events_import_bits(edev, input_dev->mscbit, EV_MSC, MSC_MAX);
events_import_bits(edev, input_dev->ledbit, EV_LED, LED_MAX);
events_import_bits(edev, input_dev->sndbit, EV_SND, SND_MAX);
events_import_bits(edev, input_dev->ffbit, EV_FF, FF_MAX);
events_import_bits(edev, input_dev->swbit, EV_SW, SW_MAX);
events_import_abs_params(edev);
error = devm_request_irq(&pdev->dev, edev->irq, events_interrupt, 0,
"goldfish-events-keypad", edev);
if (error)
return error;
error = input_register_device(input_dev);
if (error)
return error;
return 0;
}
static struct platform_driver events_driver = {
.probe = events_probe,
.driver = {
.owner = THIS_MODULE,
.name = "goldfish_events",
},
};
module_platform_driver(events_driver);
MODULE_AUTHOR("Brian Swetland");
MODULE_DESCRIPTION("Goldfish Event Device");
MODULE_LICENSE("GPL");
......@@ -20,6 +20,7 @@
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/timer.h>
......@@ -414,15 +415,23 @@ static int imx_keypad_open(struct input_dev *dev)
return -EIO;
}
#ifdef CONFIG_OF
static struct of_device_id imx_keypad_of_match[] = {
{ .compatible = "fsl,imx21-kpp", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_keypad_of_match);
#endif
static int imx_keypad_probe(struct platform_device *pdev)
{
const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data;
struct imx_keypad *keypad;
struct input_dev *input_dev;
struct resource *res;
int irq, error, i;
int irq, error, i, row, col;
if (keymap_data == NULL) {
if (!keymap_data && !pdev->dev.of_node) {
dev_err(&pdev->dev, "no keymap defined\n");
return -EINVAL;
}
......@@ -480,22 +489,6 @@ static int imx_keypad_probe(struct platform_device *pdev)
goto failed_unmap;
}
/* Search for rows and cols enabled */
for (i = 0; i < keymap_data->keymap_size; i++) {
keypad->rows_en_mask |= 1 << KEY_ROW(keymap_data->keymap[i]);
keypad->cols_en_mask |= 1 << KEY_COL(keymap_data->keymap[i]);
}
if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) ||
keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) {
dev_err(&pdev->dev,
"invalid key data (too many rows or colums)\n");
error = -EINVAL;
goto failed_clock_put;
}
dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask);
dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask);
/* Init the Input device */
input_dev->name = pdev->name;
input_dev->id.bustype = BUS_HOST;
......@@ -512,6 +505,19 @@ static int imx_keypad_probe(struct platform_device *pdev)
goto failed_clock_put;
}
/* Search for rows and cols enabled */
for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) {
for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
i = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
if (keypad->keycodes[i] != KEY_RESERVED) {
keypad->rows_en_mask |= 1 << row;
keypad->cols_en_mask |= 1 << col;
}
}
}
dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask);
dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask);
__set_bit(EV_REP, input_dev->evbit);
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
input_set_drvdata(input_dev, keypad);
......@@ -631,6 +637,7 @@ static struct platform_driver imx_keypad_driver = {
.name = "imx-keypad",
.owner = THIS_MODULE,
.pm = &imx_kbd_pm_ops,
.of_match_table = of_match_ptr(imx_keypad_of_match),
},
.probe = imx_keypad_probe,
.remove = imx_keypad_remove,
......
......@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
......@@ -39,6 +40,11 @@
#define QT2160_CMD_GPIOS 6
#define QT2160_CMD_SUBVER 7
#define QT2160_CMD_CALIBRATE 10
#define QT2160_CMD_DRIVE_X 70
#define QT2160_CMD_PWMEN_X 74
#define QT2160_CMD_PWM_DUTY 76
#define QT2160_NUM_LEDS_X 8
#define QT2160_CYCLE_INTERVAL (2*HZ)
......@@ -49,6 +55,17 @@ static unsigned char qt2160_key2code[] = {
KEY_C, KEY_D, KEY_E, KEY_F,
};
#ifdef CONFIG_LEDS_CLASS
struct qt2160_led {
struct qt2160_data *qt2160;
struct led_classdev cdev;
struct work_struct work;
char name[32];
int id;
enum led_brightness new_brightness;
};
#endif
struct qt2160_data {
struct i2c_client *client;
struct input_dev *input;
......@@ -56,8 +73,61 @@ struct qt2160_data {
spinlock_t lock; /* Protects canceling/rescheduling of dwork */
unsigned short keycodes[ARRAY_SIZE(qt2160_key2code)];
u16 key_matrix;
#ifdef CONFIG_LEDS_CLASS
struct qt2160_led leds[QT2160_NUM_LEDS_X];
struct mutex led_lock;
#endif
};
static int qt2160_read(struct i2c_client *client, u8 reg);
static int qt2160_write(struct i2c_client *client, u8 reg, u8 data);
#ifdef CONFIG_LEDS_CLASS
static void qt2160_led_work(struct work_struct *work)
{
struct qt2160_led *led = container_of(work, struct qt2160_led, work);
struct qt2160_data *qt2160 = led->qt2160;
struct i2c_client *client = qt2160->client;
int value = led->new_brightness;
u32 drive, pwmen;
mutex_lock(&qt2160->led_lock);
drive = qt2160_read(client, QT2160_CMD_DRIVE_X);
pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X);
if (value != LED_OFF) {
drive |= (1 << led->id);
pwmen |= (1 << led->id);
} else {
drive &= ~(1 << led->id);
pwmen &= ~(1 << led->id);
}
qt2160_write(client, QT2160_CMD_DRIVE_X, drive);
qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen);
/*
* Changing this register will change the brightness
* of every LED in the qt2160. It's a HW limitation.
*/
if (value != LED_OFF)
qt2160_write(client, QT2160_CMD_PWM_DUTY, value);
mutex_unlock(&qt2160->led_lock);
}
static void qt2160_led_set(struct led_classdev *cdev,
enum led_brightness value)
{
struct qt2160_led *led = container_of(cdev, struct qt2160_led, cdev);
led->new_brightness = value;
schedule_work(&led->work);
}
#endif /* CONFIG_LEDS_CLASS */
static int qt2160_read_block(struct i2c_client *client,
u8 inireg, u8 *buffer, unsigned int count)
{
......@@ -216,6 +286,63 @@ static int qt2160_write(struct i2c_client *client, u8 reg, u8 data)
return ret;
}
#ifdef CONFIG_LEDS_CLASS
static int qt2160_register_leds(struct qt2160_data *qt2160)
{
struct i2c_client *client = qt2160->client;
int ret;
int i;
mutex_init(&qt2160->led_lock);
for (i = 0; i < QT2160_NUM_LEDS_X; i++) {
struct qt2160_led *led = &qt2160->leds[i];
snprintf(led->name, sizeof(led->name), "qt2160:x%d", i);
led->cdev.name = led->name;
led->cdev.brightness_set = qt2160_led_set;
led->cdev.brightness = LED_OFF;
led->id = i;
led->qt2160 = qt2160;
INIT_WORK(&led->work, qt2160_led_work);
ret = led_classdev_register(&client->dev, &led->cdev);
if (ret < 0)
return ret;
}
/* Tur off LEDs */
qt2160_write(client, QT2160_CMD_DRIVE_X, 0);
qt2160_write(client, QT2160_CMD_PWMEN_X, 0);
qt2160_write(client, QT2160_CMD_PWM_DUTY, 0);
return 0;
}
static void qt2160_unregister_leds(struct qt2160_data *qt2160)
{
int i;
for (i = 0; i < QT2160_NUM_LEDS_X; i++) {
led_classdev_unregister(&qt2160->leds[i].cdev);
cancel_work_sync(&qt2160->leds[i].work);
}
}
#else
static inline int qt2160_register_leds(struct qt2160_data *qt2160)
{
return 0;
}
static inline void qt2160_unregister_leds(struct qt2160_data *qt2160)
{
}
#endif
static bool qt2160_identify(struct i2c_client *client)
{
......@@ -314,11 +441,17 @@ static int qt2160_probe(struct i2c_client *client,
}
}
error = qt2160_register_leds(qt2160);
if (error) {
dev_err(&client->dev, "Failed to register leds\n");
goto err_free_irq;
}
error = input_register_device(qt2160->input);
if (error) {
dev_err(&client->dev,
"Failed to register input device\n");
goto err_free_irq;
goto err_unregister_leds;
}
i2c_set_clientdata(client, qt2160);
......@@ -326,6 +459,8 @@ static int qt2160_probe(struct i2c_client *client,
return 0;
err_unregister_leds:
qt2160_unregister_leds(qt2160);
err_free_irq:
if (client->irq)
free_irq(client->irq, qt2160);
......@@ -339,6 +474,8 @@ static int qt2160_remove(struct i2c_client *client)
{
struct qt2160_data *qt2160 = i2c_get_clientdata(client);
qt2160_unregister_leds(qt2160);
/* Release IRQ so no queue will be scheduled */
if (client->irq)
free_irq(client->irq, qt2160);
......
This diff is collapsed.
......@@ -232,7 +232,7 @@ static const struct adxl34x_platform_data adxl34x_default_init = {
.ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY {x,y,z} */
.power_mode = ADXL_AUTO_SLEEP | ADXL_LINK,
.fifo_mode = FIFO_STREAM,
.fifo_mode = ADXL_FIFO_STREAM,
.watermark = 0,
};
......@@ -732,7 +732,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
mutex_init(&ac->mutex);
input_dev->name = "ADXL34x accelerometer";
revid = ac->bops->read(dev, DEVID);
revid = AC_READ(ac, DEVID);
switch (revid) {
case ID_ADXL345:
......@@ -809,7 +809,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS)
ac->fifo_delay = false;
ac->bops->write(dev, POWER_CTL, 0);
AC_WRITE(ac, POWER_CTL, 0);
err = request_threaded_irq(ac->irq, NULL, adxl34x_irq,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
......@@ -827,7 +827,6 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
if (err)
goto err_remove_attr;
AC_WRITE(ac, THRESH_TAP, pdata->tap_threshold);
AC_WRITE(ac, OFSX, pdata->x_axis_offset);
ac->hwcal.x = pdata->x_axis_offset;
AC_WRITE(ac, OFSY, pdata->y_axis_offset);
......
......@@ -46,18 +46,6 @@
#define BMA150_POLL_MAX 200
#define BMA150_POLL_MIN 0
#define BMA150_BW_25HZ 0
#define BMA150_BW_50HZ 1
#define BMA150_BW_100HZ 2
#define BMA150_BW_190HZ 3
#define BMA150_BW_375HZ 4
#define BMA150_BW_750HZ 5
#define BMA150_BW_1500HZ 6
#define BMA150_RANGE_2G 0
#define BMA150_RANGE_4G 1
#define BMA150_RANGE_8G 2
#define BMA150_MODE_NORMAL 0
#define BMA150_MODE_SLEEP 2
#define BMA150_MODE_WAKE_UP 3
......@@ -372,7 +360,7 @@ static int bma150_open(struct bma150_data *bma150)
int error;
error = pm_runtime_get_sync(&bma150->client->dev);
if (error && error != -ENOSYS)
if (error < 0 && error != -ENOSYS)
return error;
/*
......
......@@ -43,7 +43,6 @@ struct vibra_info {
struct device *dev;
struct input_dev *input_dev;
struct workqueue_struct *workqueue;
struct work_struct play_work;
bool enabled;
......@@ -143,19 +142,7 @@ static int vibra_play(struct input_dev *input, void *data,
if (!info->speed)
info->speed = effect->u.rumble.weak_magnitude >> 9;
info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1;
queue_work(info->workqueue, &info->play_work);
return 0;
}
static int twl4030_vibra_open(struct input_dev *input)
{
struct vibra_info *info = input_get_drvdata(input);
info->workqueue = create_singlethread_workqueue("vibra");
if (info->workqueue == NULL) {
dev_err(&input->dev, "couldn't create workqueue\n");
return -ENOMEM;
}
schedule_work(&info->play_work);
return 0;
}
......@@ -164,9 +151,6 @@ static void twl4030_vibra_close(struct input_dev *input)
struct vibra_info *info = input_get_drvdata(input);
cancel_work_sync(&info->play_work);
INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */
destroy_workqueue(info->workqueue);
info->workqueue = NULL;
if (info->enabled)
vibra_disable(info);
......@@ -219,7 +203,7 @@ static int twl4030_vibra_probe(struct platform_device *pdev)
return -EINVAL;
}
info = kzalloc(sizeof(*info), GFP_KERNEL);
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
......@@ -227,11 +211,10 @@ static int twl4030_vibra_probe(struct platform_device *pdev)
info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node);
INIT_WORK(&info->play_work, vibra_play_work);
info->input_dev = input_allocate_device();
info->input_dev = devm_input_allocate_device(&pdev->dev);
if (info->input_dev == NULL) {
dev_err(&pdev->dev, "couldn't allocate input device\n");
ret = -ENOMEM;
goto err_kzalloc;
return -ENOMEM;
}
input_set_drvdata(info->input_dev, info);
......@@ -239,14 +222,13 @@ static int twl4030_vibra_probe(struct platform_device *pdev)
info->input_dev->name = "twl4030:vibrator";
info->input_dev->id.version = 1;
info->input_dev->dev.parent = pdev->dev.parent;
info->input_dev->open = twl4030_vibra_open;
info->input_dev->close = twl4030_vibra_close;
__set_bit(FF_RUMBLE, info->input_dev->ffbit);
ret = input_ff_create_memless(info->input_dev, NULL, vibra_play);
if (ret < 0) {
dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n");
goto err_ialloc;
return ret;
}
ret = input_register_device(info->input_dev);
......@@ -262,28 +244,11 @@ static int twl4030_vibra_probe(struct platform_device *pdev)
err_iff:
input_ff_destroy(info->input_dev);
err_ialloc:
input_free_device(info->input_dev);
err_kzalloc:
kfree(info);
return ret;
}
static int twl4030_vibra_remove(struct platform_device *pdev)
{
struct vibra_info *info = platform_get_drvdata(pdev);
/* this also free ff-memless and calls close if needed */
input_unregister_device(info->input_dev);
kfree(info);
platform_set_drvdata(pdev, NULL);
return 0;
}
static struct platform_driver twl4030_vibra_driver = {
.probe = twl4030_vibra_probe,
.remove = twl4030_vibra_remove,
.driver = {
.name = "twl4030-vibra",
.owner = THIS_MODULE,
......
......@@ -275,7 +275,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev)
return -EINVAL;
}
info = kzalloc(sizeof(*info), GFP_KERNEL);
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info) {
dev_err(&pdev->dev, "couldn't allocate memory\n");
return -ENOMEM;
......@@ -309,53 +309,23 @@ static int twl6040_vibra_probe(struct platform_device *pdev)
if ((!info->vibldrv_res && !info->viblmotor_res) ||
(!info->vibrdrv_res && !info->vibrmotor_res)) {
dev_err(info->dev, "invalid vibra driver/motor resistance\n");
ret = -EINVAL;
goto err_kzalloc;
return -EINVAL;
}
info->irq = platform_get_irq(pdev, 0);
if (info->irq < 0) {
dev_err(info->dev, "invalid irq\n");
ret = -EINVAL;
goto err_kzalloc;
return -EINVAL;
}
mutex_init(&info->mutex);
info->input_dev = input_allocate_device();
if (info->input_dev == NULL) {
dev_err(info->dev, "couldn't allocate input device\n");
ret = -ENOMEM;
goto err_kzalloc;
}
input_set_drvdata(info->input_dev, info);
info->input_dev->name = "twl6040:vibrator";
info->input_dev->id.version = 1;
info->input_dev->dev.parent = pdev->dev.parent;
info->input_dev->close = twl6040_vibra_close;
__set_bit(FF_RUMBLE, info->input_dev->ffbit);
ret = input_ff_create_memless(info->input_dev, NULL, vibra_play);
if (ret < 0) {
dev_err(info->dev, "couldn't register vibrator to FF\n");
goto err_ialloc;
}
ret = input_register_device(info->input_dev);
if (ret < 0) {
dev_err(info->dev, "couldn't register input device\n");
goto err_iff;
}
platform_set_drvdata(pdev, info);
ret = request_threaded_irq(info->irq, NULL, twl6040_vib_irq_handler, 0,
ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
twl6040_vib_irq_handler, 0,
"twl6040_irq_vib", info);
if (ret) {
dev_err(info->dev, "VIB IRQ request failed: %d\n", ret);
goto err_irq;
return ret;
}
info->supplies[0].supply = "vddvibl";
......@@ -368,7 +338,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev)
ARRAY_SIZE(info->supplies), info->supplies);
if (ret) {
dev_err(info->dev, "couldn't get regulators %d\n", ret);
goto err_regulator;
return ret;
}
if (vddvibl_uV) {
......@@ -377,7 +347,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev)
if (ret) {
dev_err(info->dev, "failed to set VDDVIBL volt %d\n",
ret);
goto err_voltage;
goto err_regulator;
}
}
......@@ -387,34 +357,49 @@ static int twl6040_vibra_probe(struct platform_device *pdev)
if (ret) {
dev_err(info->dev, "failed to set VDDVIBR volt %d\n",
ret);
goto err_voltage;
goto err_regulator;
}
}
info->workqueue = alloc_workqueue("twl6040-vibra", 0, 0);
if (info->workqueue == NULL) {
dev_err(info->dev, "couldn't create workqueue\n");
INIT_WORK(&info->play_work, vibra_play_work);
info->input_dev = input_allocate_device();
if (info->input_dev == NULL) {
dev_err(info->dev, "couldn't allocate input device\n");
ret = -ENOMEM;
goto err_voltage;
goto err_regulator;
}
input_set_drvdata(info->input_dev, info);
info->input_dev->name = "twl6040:vibrator";
info->input_dev->id.version = 1;
info->input_dev->dev.parent = pdev->dev.parent;
info->input_dev->close = twl6040_vibra_close;
__set_bit(FF_RUMBLE, info->input_dev->ffbit);
ret = input_ff_create_memless(info->input_dev, NULL, vibra_play);
if (ret < 0) {
dev_err(info->dev, "couldn't register vibrator to FF\n");
goto err_ialloc;
}
INIT_WORK(&info->play_work, vibra_play_work);
ret = input_register_device(info->input_dev);
if (ret < 0) {
dev_err(info->dev, "couldn't register input device\n");
goto err_iff;
}
platform_set_drvdata(pdev, info);
return 0;
err_voltage:
regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies);
err_regulator:
free_irq(info->irq, info);
err_irq:
input_unregister_device(info->input_dev);
info->input_dev = NULL;
err_iff:
if (info->input_dev)
input_ff_destroy(info->input_dev);
err_ialloc:
input_free_device(info->input_dev);
err_kzalloc:
kfree(info);
err_regulator:
regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies);
return ret;
}
......@@ -423,10 +408,7 @@ static int twl6040_vibra_remove(struct platform_device *pdev)
struct vibra_info *info = platform_get_drvdata(pdev);
input_unregister_device(info->input_dev);
free_irq(info->irq, info);
regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies);
destroy_workqueue(info->workqueue);
kfree(info);
return 0;
}
......
......@@ -86,7 +86,7 @@ static int wm831x_on_probe(struct platform_device *pdev)
wm831x_on->wm831x = wm831x;
INIT_DELAYED_WORK(&wm831x_on->work, wm831x_poll_on);
wm831x_on->dev = input_allocate_device();
wm831x_on->dev = devm_input_allocate_device(&pdev->dev);
if (!wm831x_on->dev) {
dev_err(&pdev->dev, "Can't allocate input dev\n");
ret = -ENOMEM;
......@@ -119,7 +119,6 @@ static int wm831x_on_probe(struct platform_device *pdev)
err_irq:
free_irq(irq, wm831x_on);
err_input_dev:
input_free_device(wm831x_on->dev);
err:
return ret;
}
......@@ -131,7 +130,6 @@ static int wm831x_on_remove(struct platform_device *pdev)
free_irq(irq, wm831x_on);
cancel_delayed_work_sync(&wm831x_on->work);
input_unregister_device(wm831x_on->dev);
return 0;
}
......
......@@ -68,6 +68,16 @@ config MOUSE_PS2_SYNAPTICS
If unsure, say Y.
config MOUSE_PS2_CYPRESS
bool "Cypress PS/2 mouse protocol extension" if EXPERT
default y
depends on MOUSE_PS2
help
Say Y here if you have a Cypress PS/2 Trackpad connected to
your system.
If unsure, say Y.
config MOUSE_PS2_LIFEBOOK
bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EXPERT
default y
......@@ -193,6 +203,18 @@ config MOUSE_BCM5974
To compile this driver as a module, choose M here: the
module will be called bcm5974.
config MOUSE_CYAPA
tristate "Cypress APA I2C Trackpad support"
depends on I2C
help
This driver adds support for Cypress All Points Addressable (APA)
I2C Trackpads, including the ones used in 2012 Samsung Chromebooks.
Say Y here if you have a Cypress APA I2C Trackpad.
To compile this driver as a module, choose M here: the module will be
called cyapa.
config MOUSE_INPORT
tristate "InPort/MS/ATIXL busmouse"
depends on ISA
......
......@@ -8,6 +8,7 @@ obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o
obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o
obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o
obj-$(CONFIG_MOUSE_CYAPA) += cyapa.o
obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
obj-$(CONFIG_MOUSE_INPORT) += inport.o
obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o
......@@ -32,3 +33,4 @@ psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o
psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o
psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o
psmouse-$(CONFIG_MOUSE_PS2_CYPRESS) += cypress_ps2.o
This diff is collapsed.
......@@ -12,35 +12,146 @@
#ifndef _ALPS_H
#define _ALPS_H
#define ALPS_PROTO_V1 0
#define ALPS_PROTO_V2 1
#define ALPS_PROTO_V3 2
#define ALPS_PROTO_V4 3
#define ALPS_PROTO_V1 1
#define ALPS_PROTO_V2 2
#define ALPS_PROTO_V3 3
#define ALPS_PROTO_V4 4
/**
* struct alps_model_info - touchpad ID table
* @signature: E7 response string to match.
* @command_mode_resp: For V3/V4 touchpads, the final byte of the EC response
* (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.).
*
* 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; /* v3/v4 only */
unsigned char command_mode_resp;
unsigned char proto_version;
unsigned char byte0, mask0;
unsigned char flags;
};
/**
* struct alps_nibble_commands - encodings for register accesses
* @command: PS/2 command used for the nibble
* @data: Data supplied as an argument to the PS/2 command, if applicable
*
* The ALPS protocol uses magic sequences to transmit binary data to the
* touchpad, as it is generally not OK to send arbitrary bytes out the
* PS/2 port. Each of the sequences in this table sends one nibble of the
* register address or (write) data. Different versions of the ALPS protocol
* use slightly different encodings.
*/
struct alps_nibble_commands {
int command;
unsigned char data;
};
/**
* struct alps_fields - decoded version of the report packet
* @x_map: Bitmap of active X positions for MT.
* @y_map: Bitmap of active Y positions for MT.
* @fingers: Number of fingers for MT.
* @x: X position for ST.
* @y: Y position for ST.
* @z: Z position for ST.
* @first_mp: Packet is the first of a multi-packet report.
* @is_mp: Packet is part of a multi-packet report.
* @left: Left touchpad button is active.
* @right: Right touchpad button is active.
* @middle: Middle touchpad button is active.
* @ts_left: Left trackstick button is active.
* @ts_right: Right trackstick button is active.
* @ts_middle: Middle trackstick button is active.
*/
struct alps_fields {
unsigned int x_map;
unsigned int y_map;
unsigned int fingers;
unsigned int x;
unsigned int y;
unsigned int z;
unsigned int first_mp:1;
unsigned int is_mp:1;
unsigned int left:1;
unsigned int right:1;
unsigned int middle:1;
unsigned int ts_left:1;
unsigned int ts_right:1;
unsigned int ts_middle:1;
};
/**
* 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.
* @nibble_commands: Command mapping used for touchpad register accesses.
* @addr_command: Command used to tell the touchpad that a register address
* follows.
* @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.).
* @x_max: Largest possible X position value.
* @y_max: Largest possible Y position value.
* @x_bits: Number of X bits in the MT bitmap.
* @y_bits: Number of Y bits in the MT bitmap.
* @hw_init: Protocol-specific hardware init function.
* @process_packet: Protocol-specific function to process a report packet.
* @decode_fields: Protocol-specific function to read packet bitfields.
* @set_abs_params: Protocol-specific function to configure the input_dev.
* @prev_fin: Finger bit from previous packet.
* @multi_packet: Multi-packet data in progress.
* @multi_data: Saved multi-packet data.
* @x1: First X coordinate from last MT report.
* @x2: Second X coordinate from last MT report.
* @y1: First Y coordinate from last MT report.
* @y2: Second Y coordinate from last MT report.
* @fingers: Number of fingers from last MT report.
* @quirks: Bitmap of ALPS_QUIRK_*.
* @timer: Timer for flushing out the final report packet in the stream.
*/
struct alps_data {
struct input_dev *dev2; /* Relative device */
char phys[32]; /* Phys */
const struct alps_model_info *i;/* Info */
struct input_dev *dev2;
char phys[32];
/* these are autodetected when the device is identified */
const struct alps_nibble_commands *nibble_commands;
int addr_command; /* Command to set register address */
int prev_fin; /* Finger bit from previous packet */
int multi_packet; /* Multi-packet data in progress */
unsigned char multi_data[6]; /* Saved multi-packet data */
int x1, x2, y1, y2; /* Coordinates from last MT report */
int fingers; /* Number of fingers from MT report */
int addr_command;
unsigned char proto_version;
unsigned char byte0, mask0;
unsigned char flags;
int x_max;
int y_max;
int x_bits;
int y_bits;
int (*hw_init)(struct psmouse *psmouse);
void (*process_packet)(struct psmouse *psmouse);
void (*decode_fields)(struct alps_fields *f, unsigned char *p);
void (*set_abs_params)(struct alps_data *priv, struct input_dev *dev1);
int prev_fin;
int multi_packet;
unsigned char multi_data[6];
int x1, x2, y1, y2;
int fingers;
u8 quirks;
struct timer_list timer;
};
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -95,6 +95,7 @@ enum psmouse_type {
PSMOUSE_ELANTECH,
PSMOUSE_FSP,
PSMOUSE_SYNAPTICS_RELATIVE,
PSMOUSE_CYPRESS,
PSMOUSE_AUTO /* This one should always be last */
};
......
This diff is collapsed.
......@@ -236,6 +236,7 @@ config SERIO_PS2MULT
config SERIO_ARC_PS2
tristate "ARC PS/2 support"
depends on GENERIC_HARDIRQS
help
Say Y here if you have an ARC FPGA platform with a PS/2
controller in it.
......
This diff is collapsed.
......@@ -78,6 +78,7 @@ enum {
INTUOS5L,
WACOM_21UX2,
WACOM_22HD,
DTK,
WACOM_24HD,
CINTIQ,
WACOM_BEE,
......@@ -135,7 +136,6 @@ struct wacom_wac {
int pid;
int battery_capacity;
int num_contacts_left;
int *slots;
};
#endif
......@@ -359,7 +359,7 @@ config TOUCHSCREEN_MCS5000
config TOUCHSCREEN_MMS114
tristate "MELFAS MMS114 touchscreen"
depends on I2C
depends on I2C && GENERIC_HARDIRQS
help
Say Y here if you have the MELFAS MMS114 touchscreen controller
chip in your system.
......
......@@ -193,7 +193,6 @@ static struct spi_driver cyttsp_spi_driver = {
module_spi_driver(cyttsp_spi_driver);
MODULE_ALIAS("spi:cyttsp");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver");
MODULE_AUTHOR("Cypress");
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment