Commit 01c728a2 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Merge branch 'next' into for-linus

parents 554738da 50a88cb7
...@@ -49,7 +49,9 @@ This information is subject to change. ...@@ -49,7 +49,9 @@ This information is subject to change.
#include <linux/input.h> #include <linux/input.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
unsigned long features[1 + FF_MAX/sizeof(unsigned long)]; #define BITS_TO_LONGS(x) \
(((x) + 8 * sizeof (unsigned long) - 1) / (8 * sizeof (unsigned long)))
unsigned long features[BITS_TO_LONGS(FF_CNT)];
int ioctl(int file_descriptor, int request, unsigned long *features); int ioctl(int file_descriptor, int request, unsigned long *features);
"request" must be EVIOCGBIT(EV_FF, size of features array in bytes ) "request" must be EVIOCGBIT(EV_FF, size of features array in bytes )
......
...@@ -884,6 +884,7 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -884,6 +884,7 @@ and is between 256 and 4096 characters. It is defined in the file
controller controller
i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
controllers controllers
i8042.notimeout [HW] Ignore timeout condition signalled by conroller
i8042.reset [HW] Reset the controller during init and cleanup i8042.reset [HW] Reset the controller during init and cleanup
i8042.unlock [HW] Unlock (ignore) the keylock i8042.unlock [HW] Unlock (ignore) the keylock
......
...@@ -255,6 +255,16 @@ config JOYSTICK_AMIGA ...@@ -255,6 +255,16 @@ config JOYSTICK_AMIGA
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called amijoy. module will be called amijoy.
config JOYSTICK_AS5011
tristate "Austria Microsystem AS5011 joystick"
depends on I2C
help
Say Y here if you have an AS5011 digital joystick connected to your
system.
To compile this driver as a module, choose M here: the
module will be called as5011.
config JOYSTICK_JOYDUMP config JOYSTICK_JOYDUMP
tristate "Gameport data dumper" tristate "Gameport data dumper"
select GAMEPORT select GAMEPORT
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
obj-$(CONFIG_JOYSTICK_A3D) += a3d.o obj-$(CONFIG_JOYSTICK_A3D) += a3d.o
obj-$(CONFIG_JOYSTICK_ADI) += adi.o obj-$(CONFIG_JOYSTICK_ADI) += adi.o
obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o
obj-$(CONFIG_JOYSTICK_AS5011) += as5011.o
obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o
obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o
obj-$(CONFIG_JOYSTICK_DB9) += db9.o obj-$(CONFIG_JOYSTICK_DB9) += db9.o
......
/*
* Copyright (c) 2010, 2011 Fabien Marteau <fabien.marteau@armadeus.com>
* Sponsored by ARMadeus Systems
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Driver for Austria Microsystems joysticks AS5011
*
* TODO:
* - Power on the chip when open() and power down when close()
* - Manage power mode
*/
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/input/as5011.h>
#include <linux/slab.h>
#define DRIVER_DESC "Driver for Austria Microsystems AS5011 joystick"
#define MODULE_DEVICE_ALIAS "as5011"
MODULE_AUTHOR("Fabien Marteau <fabien.marteau@armadeus.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
/* registers */
#define AS5011_CTRL1 0x76
#define AS5011_CTRL2 0x75
#define AS5011_XP 0x43
#define AS5011_XN 0x44
#define AS5011_YP 0x53
#define AS5011_YN 0x54
#define AS5011_X_REG 0x41
#define AS5011_Y_REG 0x42
#define AS5011_X_RES_INT 0x51
#define AS5011_Y_RES_INT 0x52
/* CTRL1 bits */
#define AS5011_CTRL1_LP_PULSED 0x80
#define AS5011_CTRL1_LP_ACTIVE 0x40
#define AS5011_CTRL1_LP_CONTINUE 0x20
#define AS5011_CTRL1_INT_WUP_EN 0x10
#define AS5011_CTRL1_INT_ACT_EN 0x08
#define AS5011_CTRL1_EXT_CLK_EN 0x04
#define AS5011_CTRL1_SOFT_RST 0x02
#define AS5011_CTRL1_DATA_VALID 0x01
/* CTRL2 bits */
#define AS5011_CTRL2_EXT_SAMPLE_EN 0x08
#define AS5011_CTRL2_RC_BIAS_ON 0x04
#define AS5011_CTRL2_INV_SPINNING 0x02
#define AS5011_MAX_AXIS 80
#define AS5011_MIN_AXIS (-80)
#define AS5011_FUZZ 8
#define AS5011_FLAT 40
struct as5011_device {
struct input_dev *input_dev;
struct i2c_client *i2c_client;
unsigned int button_gpio;
unsigned int button_irq;
unsigned int axis_irq;
};
static int as5011_i2c_write(struct i2c_client *client,
uint8_t aregaddr,
uint8_t avalue)
{
uint8_t data[2] = { aregaddr, avalue };
struct i2c_msg msg = {
client->addr, I2C_M_IGNORE_NAK, 2, (uint8_t *)data
};
int error;
error = i2c_transfer(client->adapter, &msg, 1);
return error < 0 ? error : 0;
}
static int as5011_i2c_read(struct i2c_client *client,
uint8_t aregaddr, signed char *value)
{
uint8_t data[2] = { aregaddr };
struct i2c_msg msg_set[2] = {
{ client->addr, I2C_M_REV_DIR_ADDR, 1, (uint8_t *)data },
{ client->addr, I2C_M_RD | I2C_M_NOSTART, 1, (uint8_t *)data }
};
int error;
error = i2c_transfer(client->adapter, msg_set, 2);
if (error < 0)
return error;
*value = data[0] & 0x80 ? -1 * (1 + ~data[0]) : data[0];
return 0;
}
static irqreturn_t as5011_button_interrupt(int irq, void *dev_id)
{
struct as5011_device *as5011 = dev_id;
int val = gpio_get_value_cansleep(as5011->button_gpio);
input_report_key(as5011->input_dev, BTN_JOYSTICK, !val);
input_sync(as5011->input_dev);
return IRQ_HANDLED;
}
static irqreturn_t as5011_axis_interrupt(int irq, void *dev_id)
{
struct as5011_device *as5011 = dev_id;
int error;
signed char x, y;
error = as5011_i2c_read(as5011->i2c_client, AS5011_X_RES_INT, &x);
if (error < 0)
goto out;
error = as5011_i2c_read(as5011->i2c_client, AS5011_Y_RES_INT, &y);
if (error < 0)
goto out;
input_report_abs(as5011->input_dev, ABS_X, x);
input_report_abs(as5011->input_dev, ABS_Y, y);
input_sync(as5011->input_dev);
out:
return IRQ_HANDLED;
}
static int __devinit as5011_configure_chip(struct as5011_device *as5011,
const struct as5011_platform_data *plat_dat)
{
struct i2c_client *client = as5011->i2c_client;
int error;
signed char value;
/* chip soft reset */
error = as5011_i2c_write(client, AS5011_CTRL1,
AS5011_CTRL1_SOFT_RST);
if (error < 0) {
dev_err(&client->dev, "Soft reset failed\n");
return error;
}
mdelay(10);
error = as5011_i2c_write(client, AS5011_CTRL1,
AS5011_CTRL1_LP_PULSED |
AS5011_CTRL1_LP_ACTIVE |
AS5011_CTRL1_INT_ACT_EN);
if (error < 0) {
dev_err(&client->dev, "Power config failed\n");
return error;
}
error = as5011_i2c_write(client, AS5011_CTRL2,
AS5011_CTRL2_INV_SPINNING);
if (error < 0) {
dev_err(&client->dev, "Can't invert spinning\n");
return error;
}
/* write threshold */
error = as5011_i2c_write(client, AS5011_XP, plat_dat->xp);
if (error < 0) {
dev_err(&client->dev, "Can't write threshold\n");
return error;
}
error = as5011_i2c_write(client, AS5011_XN, plat_dat->xn);
if (error < 0) {
dev_err(&client->dev, "Can't write threshold\n");
return error;
}
error = as5011_i2c_write(client, AS5011_YP, plat_dat->yp);
if (error < 0) {
dev_err(&client->dev, "Can't write threshold\n");
return error;
}
error = as5011_i2c_write(client, AS5011_YN, plat_dat->yn);
if (error < 0) {
dev_err(&client->dev, "Can't write threshold\n");
return error;
}
/* to free irq gpio in chip */
error = as5011_i2c_read(client, AS5011_X_RES_INT, &value);
if (error < 0) {
dev_err(&client->dev, "Can't read i2c X resolution value\n");
return error;
}
return 0;
}
static int __devinit as5011_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
const struct as5011_platform_data *plat_data;
struct as5011_device *as5011;
struct input_dev *input_dev;
int irq;
int error;
plat_data = client->dev.platform_data;
if (!plat_data)
return -EINVAL;
if (!plat_data->axis_irq) {
dev_err(&client->dev, "No axis IRQ?\n");
return -EINVAL;
}
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_PROTOCOL_MANGLING)) {
dev_err(&client->dev,
"need i2c bus that supports protocol mangling\n");
return -ENODEV;
}
as5011 = kmalloc(sizeof(struct as5011_device), GFP_KERNEL);
input_dev = input_allocate_device();
if (!as5011 || !input_dev) {
dev_err(&client->dev,
"Can't allocate memory for device structure\n");
error = -ENOMEM;
goto err_free_mem;
}
as5011->i2c_client = client;
as5011->input_dev = input_dev;
as5011->button_gpio = plat_data->button_gpio;
as5011->axis_irq = plat_data->axis_irq;
input_dev->name = "Austria Microsystem as5011 joystick";
input_dev->id.bustype = BUS_I2C;
input_dev->dev.parent = &client->dev;
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(EV_ABS, input_dev->evbit);
__set_bit(BTN_JOYSTICK, input_dev->keybit);
input_set_abs_params(input_dev, ABS_X,
AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);
input_set_abs_params(as5011->input_dev, ABS_Y,
AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);
error = gpio_request(as5011->button_gpio, "AS5011 button");
if (error < 0) {
dev_err(&client->dev, "Failed to request button gpio\n");
goto err_free_mem;
}
irq = gpio_to_irq(as5011->button_gpio);
if (irq < 0) {
dev_err(&client->dev,
"Failed to get irq number for button gpio\n");
goto err_free_button_gpio;
}
as5011->button_irq = irq;
error = request_threaded_irq(as5011->button_irq,
NULL, as5011_button_interrupt,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"as5011_button", as5011);
if (error < 0) {
dev_err(&client->dev,
"Can't allocate button irq %d\n", as5011->button_irq);
goto err_free_button_gpio;
}
error = as5011_configure_chip(as5011, plat_data);
if (error)
goto err_free_button_irq;
error = request_threaded_irq(as5011->axis_irq, NULL,
as5011_axis_interrupt,
plat_data->axis_irqflags,
"as5011_joystick", as5011);
if (error) {
dev_err(&client->dev,
"Can't allocate axis irq %d\n", plat_data->axis_irq);
goto err_free_button_irq;
}
error = input_register_device(as5011->input_dev);
if (error) {
dev_err(&client->dev, "Failed to register input device\n");
goto err_free_axis_irq;
}
i2c_set_clientdata(client, as5011);
return 0;
err_free_axis_irq:
free_irq(as5011->axis_irq, as5011);
err_free_button_irq:
free_irq(as5011->button_irq, as5011);
err_free_button_gpio:
gpio_free(as5011->button_gpio);
err_free_mem:
input_free_device(input_dev);
kfree(as5011);
return error;
}
static int __devexit as5011_remove(struct i2c_client *client)
{
struct as5011_device *as5011 = i2c_get_clientdata(client);
free_irq(as5011->axis_irq, as5011);
free_irq(as5011->button_irq, as5011);
gpio_free(as5011->button_gpio);
input_unregister_device(as5011->input_dev);
kfree(as5011);
return 0;
}
static const struct i2c_device_id as5011_id[] = {
{ MODULE_DEVICE_ALIAS, 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, as5011_id);
static struct i2c_driver as5011_driver = {
.driver = {
.name = "as5011",
},
.probe = as5011_probe,
.remove = __devexit_p(as5011_remove),
.id_table = as5011_id,
};
static int __init as5011_init(void)
{
return i2c_add_driver(&as5011_driver);
}
module_init(as5011_init);
static void __exit as5011_exit(void)
{
i2c_del_driver(&as5011_driver);
}
module_exit(as5011_exit);
...@@ -12,18 +12,6 @@ menuconfig INPUT_KEYBOARD ...@@ -12,18 +12,6 @@ menuconfig INPUT_KEYBOARD
if INPUT_KEYBOARD if INPUT_KEYBOARD
config KEYBOARD_AAED2000
tristate "AAED-2000 keyboard"
depends on MACH_AAED2000
select INPUT_POLLDEV
default y
help
Say Y here to enable the keyboard on the Agilent AAED-2000
development board.
To compile this driver as a module, choose M here: the
module will be called aaed2000_kbd.
config KEYBOARD_ADP5520 config KEYBOARD_ADP5520
tristate "Keypad Support for ADP5520 PMIC" tristate "Keypad Support for ADP5520 PMIC"
depends on PMIC_ADP5520 depends on PMIC_ADP5520
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
# Each configuration option enables a list of files. # Each configuration option enables a list of files.
obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o
obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o
obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
......
/*
* Keyboard driver for the AAED-2000 dev board
*
* Copyright (c) 2006 Nicolas Bellido Y Ortega
*
* Based on corgikbd.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/input-polldev.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/aaed2000.h>
#define KB_ROWS 12
#define KB_COLS 8
#define KB_ROWMASK(r) (1 << (r))
#define SCANCODE(r,c) (((c) * KB_ROWS) + (r))
#define NR_SCANCODES (KB_COLS * KB_ROWS)
#define SCAN_INTERVAL (50) /* ms */
#define KB_ACTIVATE_DELAY (20) /* us */
static unsigned char aaedkbd_keycode[NR_SCANCODES] = {
KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, 0, KEY_SPACE, KEY_KP6, 0, KEY_KPDOT, 0, 0,
KEY_K, KEY_M, KEY_O, KEY_DOT, KEY_SLASH, 0, KEY_F, 0, 0, 0, KEY_LEFTSHIFT, 0,
KEY_I, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, 0, 0, 0, 0, 0, KEY_RIGHTSHIFT, 0,
KEY_8, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, 0, 0, 0, 0, 0, 0, 0,
KEY_J, KEY_H, KEY_B, KEY_KP8, KEY_KP4, 0, KEY_C, KEY_D, KEY_S, KEY_A, 0, KEY_CAPSLOCK,
KEY_Y, KEY_U, KEY_N, KEY_T, 0, 0, KEY_R, KEY_E, KEY_W, KEY_Q, 0, KEY_TAB,
KEY_7, KEY_6, KEY_G, 0, KEY_5, 0, KEY_4, KEY_3, KEY_2, KEY_1, 0, KEY_GRAVE,
0, 0, KEY_COMMA, 0, KEY_KP2, 0, KEY_V, KEY_LEFTALT, KEY_X, KEY_Z, 0, KEY_LEFTCTRL
};
struct aaedkbd {
unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)];
struct input_polled_dev *poll_dev;
int kbdscan_state[KB_COLS];
int kbdscan_count[KB_COLS];
};
#define KBDSCAN_STABLE_COUNT 2
static void aaedkbd_report_col(struct aaedkbd *aaedkbd,
unsigned int col, unsigned int rowd)
{
unsigned int scancode, pressed;
unsigned int row;
for (row = 0; row < KB_ROWS; row++) {
scancode = SCANCODE(row, col);
pressed = rowd & KB_ROWMASK(row);
input_report_key(aaedkbd->poll_dev->input,
aaedkbd->keycode[scancode], pressed);
}
}
/* Scan the hardware keyboard and push any changes up through the input layer */
static void aaedkbd_poll(struct input_polled_dev *dev)
{
struct aaedkbd *aaedkbd = dev->private;
unsigned int col, rowd;
col = 0;
do {
AAEC_GPIO_KSCAN = col + 8;
udelay(KB_ACTIVATE_DELAY);
rowd = AAED_EXT_GPIO & AAED_EGPIO_KBD_SCAN;
if (rowd != aaedkbd->kbdscan_state[col]) {
aaedkbd->kbdscan_count[col] = 0;
aaedkbd->kbdscan_state[col] = rowd;
} else if (++aaedkbd->kbdscan_count[col] >= KBDSCAN_STABLE_COUNT) {
aaedkbd_report_col(aaedkbd, col, rowd);
col++;
}
} while (col < KB_COLS);
AAEC_GPIO_KSCAN = 0x07;
input_sync(dev->input);
}
static int __devinit aaedkbd_probe(struct platform_device *pdev)
{
struct aaedkbd *aaedkbd;
struct input_polled_dev *poll_dev;
struct input_dev *input_dev;
int i;
int error;
aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL);
poll_dev = input_allocate_polled_device();
if (!aaedkbd || !poll_dev) {
error = -ENOMEM;
goto fail;
}
platform_set_drvdata(pdev, aaedkbd);
aaedkbd->poll_dev = poll_dev;
memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode));
poll_dev->private = aaedkbd;
poll_dev->poll = aaedkbd_poll;
poll_dev->poll_interval = SCAN_INTERVAL;
input_dev = poll_dev->input;
input_dev->name = "AAED-2000 Keyboard";
input_dev->phys = "aaedkbd/input0";
input_dev->id.bustype = BUS_HOST;
input_dev->id.vendor = 0x0001;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
input_dev->dev.parent = &pdev->dev;
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
input_dev->keycode = aaedkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(aaedkbd_keycode);
for (i = 0; i < ARRAY_SIZE(aaedkbd_keycode); i++)
set_bit(aaedkbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
error = input_register_polled_device(aaedkbd->poll_dev);
if (error)
goto fail;
return 0;
fail: kfree(aaedkbd);
input_free_polled_device(poll_dev);
return error;
}
static int __devexit aaedkbd_remove(struct platform_device *pdev)
{
struct aaedkbd *aaedkbd = platform_get_drvdata(pdev);
input_unregister_polled_device(aaedkbd->poll_dev);
input_free_polled_device(aaedkbd->poll_dev);
kfree(aaedkbd);
return 0;
}
/* work with hotplug and coldplug */
MODULE_ALIAS("platform:aaed2000-keyboard");
static struct platform_driver aaedkbd_driver = {
.probe = aaedkbd_probe,
.remove = __devexit_p(aaedkbd_remove),
.driver = {
.name = "aaed2000-keyboard",
.owner = THIS_MODULE,
},
};
static int __init aaedkbd_init(void)
{
return platform_driver_register(&aaedkbd_driver);
}
static void __exit aaedkbd_exit(void)
{
platform_driver_unregister(&aaedkbd_driver);
}
module_init(aaedkbd_init);
module_exit(aaedkbd_exit);
MODULE_AUTHOR("Nicolas Bellido Y Ortega");
MODULE_DESCRIPTION("AAED-2000 Keyboard Driver");
MODULE_LICENSE("GPL v2");
...@@ -424,6 +424,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { ...@@ -424,6 +424,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
}, },
}, },
{
/* Dell Vostro V13 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
},
},
{ } { }
}; };
...@@ -545,6 +552,17 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { ...@@ -545,6 +552,17 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
}; };
#endif #endif
static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
{
/* Dell Vostro V13 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
},
},
{ }
};
/* /*
* Some Wistron based laptops need us to explicitly enable the 'Dritek * Some Wistron based laptops need us to explicitly enable the 'Dritek
* keyboard extension' to make their extra keys start generating scancodes. * keyboard extension' to make their extra keys start generating scancodes.
...@@ -896,6 +914,9 @@ static int __init i8042_platform_init(void) ...@@ -896,6 +914,9 @@ static int __init i8042_platform_init(void)
if (dmi_check_system(i8042_dmi_nomux_table)) if (dmi_check_system(i8042_dmi_nomux_table))
i8042_nomux = true; i8042_nomux = true;
if (dmi_check_system(i8042_dmi_notimeout_table))
i8042_notimeout = true;
if (dmi_check_system(i8042_dmi_dritek_table)) if (dmi_check_system(i8042_dmi_dritek_table))
i8042_dritek = true; i8042_dritek = true;
#endif /* CONFIG_X86 */ #endif /* CONFIG_X86 */
......
...@@ -63,6 +63,10 @@ static bool i8042_noloop; ...@@ -63,6 +63,10 @@ static bool i8042_noloop;
module_param_named(noloop, i8042_noloop, bool, 0); module_param_named(noloop, i8042_noloop, bool, 0);
MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port");
static bool i8042_notimeout;
module_param_named(notimeout, i8042_notimeout, bool, 0);
MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042");
#ifdef CONFIG_X86 #ifdef CONFIG_X86
static bool i8042_dritek; static bool i8042_dritek;
module_param_named(dritek, i8042_dritek, bool, 0); module_param_named(dritek, i8042_dritek, bool, 0);
...@@ -504,7 +508,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) ...@@ -504,7 +508,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
} else { } else {
dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) | dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) |
((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0); ((str & I8042_STR_TIMEOUT && !i8042_notimeout) ? SERIO_TIMEOUT : 0);
port_no = (str & I8042_STR_AUXDATA) ? port_no = (str & I8042_STR_AUXDATA) ?
I8042_AUX_PORT_NO : I8042_KBD_PORT_NO; I8042_AUX_PORT_NO : I8042_KBD_PORT_NO;
......
...@@ -10,14 +10,16 @@ ...@@ -10,14 +10,16 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/pm.h>
#include "ad7879.h" #include "ad7879.h"
#define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */ #define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message) static int ad7879_i2c_suspend(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
struct ad7879 *ts = i2c_get_clientdata(client); struct ad7879 *ts = i2c_get_clientdata(client);
ad7879_suspend(ts); ad7879_suspend(ts);
...@@ -25,17 +27,17 @@ static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message) ...@@ -25,17 +27,17 @@ static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message)
return 0; return 0;
} }
static int ad7879_i2c_resume(struct i2c_client *client) static int ad7879_i2c_resume(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
struct ad7879 *ts = i2c_get_clientdata(client); struct ad7879 *ts = i2c_get_clientdata(client);
ad7879_resume(ts); ad7879_resume(ts);
return 0; return 0;
} }
#else
# define ad7879_i2c_suspend NULL static SIMPLE_DEV_PM_OPS(ad7879_i2c_pm, ad7879_i2c_suspend, ad7879_i2c_resume);
# define ad7879_i2c_resume NULL
#endif #endif
/* All registers are word-sized. /* All registers are word-sized.
...@@ -117,11 +119,12 @@ static struct i2c_driver ad7879_i2c_driver = { ...@@ -117,11 +119,12 @@ static struct i2c_driver ad7879_i2c_driver = {
.driver = { .driver = {
.name = "ad7879", .name = "ad7879",
.owner = THIS_MODULE, .owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &ad7879_i2c_pm,
#endif
}, },
.probe = ad7879_i2c_probe, .probe = ad7879_i2c_probe,
.remove = __devexit_p(ad7879_i2c_remove), .remove = __devexit_p(ad7879_i2c_remove),
.suspend = ad7879_i2c_suspend,
.resume = ad7879_i2c_resume,
.id_table = ad7879_id, .id_table = ad7879_id,
}; };
......
...@@ -280,8 +280,9 @@ static int __devinit cy8ctmg110_probe(struct i2c_client *client, ...@@ -280,8 +280,9 @@ static int __devinit cy8ctmg110_probe(struct i2c_client *client,
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) static int cy8ctmg110_suspend(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
struct cy8ctmg110 *ts = i2c_get_clientdata(client); struct cy8ctmg110 *ts = i2c_get_clientdata(client);
if (device_may_wakeup(&client->dev)) if (device_may_wakeup(&client->dev))
...@@ -293,8 +294,9 @@ static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) ...@@ -293,8 +294,9 @@ static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg)
return 0; return 0;
} }
static int cy8ctmg110_resume(struct i2c_client *client) static int cy8ctmg110_resume(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
struct cy8ctmg110 *ts = i2c_get_clientdata(client); struct cy8ctmg110 *ts = i2c_get_clientdata(client);
if (device_may_wakeup(&client->dev)) if (device_may_wakeup(&client->dev))
...@@ -305,6 +307,8 @@ static int cy8ctmg110_resume(struct i2c_client *client) ...@@ -305,6 +307,8 @@ static int cy8ctmg110_resume(struct i2c_client *client)
} }
return 0; return 0;
} }
static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume);
#endif #endif
static int __devexit cy8ctmg110_remove(struct i2c_client *client) static int __devexit cy8ctmg110_remove(struct i2c_client *client)
...@@ -335,14 +339,13 @@ static struct i2c_driver cy8ctmg110_driver = { ...@@ -335,14 +339,13 @@ static struct i2c_driver cy8ctmg110_driver = {
.driver = { .driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = CY8CTMG110_DRIVER_NAME, .name = CY8CTMG110_DRIVER_NAME,
#ifdef CONFIG_PM
.pm = &cy8ctmg110_pm,
#endif
}, },
.id_table = cy8ctmg110_idtable, .id_table = cy8ctmg110_idtable,
.probe = cy8ctmg110_probe, .probe = cy8ctmg110_probe,
.remove = __devexit_p(cy8ctmg110_remove), .remove = __devexit_p(cy8ctmg110_remove),
#ifdef CONFIG_PM
.suspend = cy8ctmg110_suspend,
.resume = cy8ctmg110_resume,
#endif
}; };
static int __init cy8ctmg110_init(void) static int __init cy8ctmg110_init(void)
......
...@@ -261,8 +261,9 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) ...@@ -261,8 +261,9 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) static int eeti_ts_suspend(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
struct eeti_ts_priv *priv = i2c_get_clientdata(client); struct eeti_ts_priv *priv = i2c_get_clientdata(client);
struct input_dev *input_dev = priv->input; struct input_dev *input_dev = priv->input;
...@@ -279,8 +280,9 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) ...@@ -279,8 +280,9 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg)
return 0; return 0;
} }
static int eeti_ts_resume(struct i2c_client *client) static int eeti_ts_resume(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
struct eeti_ts_priv *priv = i2c_get_clientdata(client); struct eeti_ts_priv *priv = i2c_get_clientdata(client);
struct input_dev *input_dev = priv->input; struct input_dev *input_dev = priv->input;
...@@ -296,9 +298,8 @@ static int eeti_ts_resume(struct i2c_client *client) ...@@ -296,9 +298,8 @@ static int eeti_ts_resume(struct i2c_client *client)
return 0; return 0;
} }
#else
#define eeti_ts_suspend NULL static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume);
#define eeti_ts_resume NULL
#endif #endif
static const struct i2c_device_id eeti_ts_id[] = { static const struct i2c_device_id eeti_ts_id[] = {
...@@ -310,11 +311,12 @@ MODULE_DEVICE_TABLE(i2c, eeti_ts_id); ...@@ -310,11 +311,12 @@ MODULE_DEVICE_TABLE(i2c, eeti_ts_id);
static struct i2c_driver eeti_ts_driver = { static struct i2c_driver eeti_ts_driver = {
.driver = { .driver = {
.name = "eeti_ts", .name = "eeti_ts",
#ifdef CONFIG_PM
.pm = &eeti_ts_pm,
#endif
}, },
.probe = eeti_ts_probe, .probe = eeti_ts_probe,
.remove = __devexit_p(eeti_ts_remove), .remove = __devexit_p(eeti_ts_remove),
.suspend = eeti_ts_suspend,
.resume = eeti_ts_resume,
.id_table = eeti_ts_id, .id_table = eeti_ts_id,
}; };
......
...@@ -261,25 +261,27 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client) ...@@ -261,25 +261,27 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client)
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int mcs5000_ts_suspend(struct i2c_client *client, pm_message_t mesg) static int mcs5000_ts_suspend(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
/* Touch sleep mode */ /* Touch sleep mode */
i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP); i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP);
return 0; return 0;
} }
static int mcs5000_ts_resume(struct i2c_client *client) static int mcs5000_ts_resume(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
struct mcs5000_ts_data *data = i2c_get_clientdata(client); struct mcs5000_ts_data *data = i2c_get_clientdata(client);
mcs5000_ts_phys_init(data); mcs5000_ts_phys_init(data);
return 0; return 0;
} }
#else
#define mcs5000_ts_suspend NULL static SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume);
#define mcs5000_ts_resume NULL
#endif #endif
static const struct i2c_device_id mcs5000_ts_id[] = { static const struct i2c_device_id mcs5000_ts_id[] = {
...@@ -291,10 +293,11 @@ MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id); ...@@ -291,10 +293,11 @@ MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id);
static struct i2c_driver mcs5000_ts_driver = { static struct i2c_driver mcs5000_ts_driver = {
.probe = mcs5000_ts_probe, .probe = mcs5000_ts_probe,
.remove = __devexit_p(mcs5000_ts_remove), .remove = __devexit_p(mcs5000_ts_remove),
.suspend = mcs5000_ts_suspend,
.resume = mcs5000_ts_resume,
.driver = { .driver = {
.name = "mcs5000_ts", .name = "mcs5000_ts",
#ifdef CONFIG_PM
.pm = &mcs5000_ts_pm,
#endif
}, },
.id_table = mcs5000_ts_id, .id_table = mcs5000_ts_id,
}; };
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/pm.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/i2c.h> #include <linux/i2c.h>
...@@ -226,8 +227,9 @@ static int migor_ts_remove(struct i2c_client *client) ...@@ -226,8 +227,9 @@ static int migor_ts_remove(struct i2c_client *client)
return 0; return 0;
} }
static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg) static int migor_ts_suspend(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
if (device_may_wakeup(&client->dev)) if (device_may_wakeup(&client->dev))
...@@ -236,8 +238,9 @@ static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg) ...@@ -236,8 +238,9 @@ static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg)
return 0; return 0;
} }
static int migor_ts_resume(struct i2c_client *client) static int migor_ts_resume(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev);
struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
if (device_may_wakeup(&client->dev)) if (device_may_wakeup(&client->dev))
...@@ -246,6 +249,8 @@ static int migor_ts_resume(struct i2c_client *client) ...@@ -246,6 +249,8 @@ static int migor_ts_resume(struct i2c_client *client)
return 0; return 0;
} }
static SIMPLE_DEV_PM_OPS(migor_ts_pm, migor_ts_suspend, migor_ts_resume);
static const struct i2c_device_id migor_ts_id[] = { static const struct i2c_device_id migor_ts_id[] = {
{ "migor_ts", 0 }, { "migor_ts", 0 },
{ } { }
...@@ -255,11 +260,10 @@ MODULE_DEVICE_TABLE(i2c, migor_ts); ...@@ -255,11 +260,10 @@ MODULE_DEVICE_TABLE(i2c, migor_ts);
static struct i2c_driver migor_ts_driver = { static struct i2c_driver migor_ts_driver = {
.driver = { .driver = {
.name = "migor_ts", .name = "migor_ts",
.pm = &migor_ts_pm,
}, },
.probe = migor_ts_probe, .probe = migor_ts_probe,
.remove = migor_ts_remove, .remove = migor_ts_remove,
.suspend = migor_ts_suspend,
.resume = migor_ts_resume,
.id_table = migor_ts_id, .id_table = migor_ts_id,
}; };
......
This diff is collapsed.
...@@ -800,6 +800,7 @@ struct input_keymap_entry { ...@@ -800,6 +800,7 @@ struct input_keymap_entry {
#define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */ #define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */
#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */ #define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */
#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */ #define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
#define SW_MAX 0x0f #define SW_MAX 0x0f
#define SW_CNT (SW_MAX+1) #define SW_CNT (SW_MAX+1)
......
#ifndef _AS5011_H
#define _AS5011_H
/*
* Copyright (c) 2010, 2011 Fabien Marteau <fabien.marteau@armadeus.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
struct as5011_platform_data {
unsigned int button_gpio;
unsigned int axis_irq; /* irq number */
unsigned long axis_irqflags;
char xp, xn; /* threshold for x axis */
char yp, yn; /* threshold for y axis */
};
#endif /* _AS5011_H */
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