Commit 36ac1d2f authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (32 commits)
  Input: wm97xx - update email address for Liam Girdwood
  Input: i8042 - add Thinkpad R31 to nomux list
  Input: move map_to_7segment.h to include/linux
  Input: ads7846 - fix cache line sharing issue
  Input: cm109 - add missing newlines to messages
  Input: document i8042.debug in kernel-parameters.txt
  Input: keyboard - fix potential out of bound access to key_map
  Input: psmouse - add OLPC touchpad driver
  Input: psmouse - tweak PSMOUSE_DEFINE_ATTR to support raw set callbacks
  Input: psmouse - add psmouse_queue_work() for ps/2 extension to make use of
  Input: psmouse - export psmouse_set_state for ps/2 extensions to use
  Input: ads7846 - introduce .gpio_pendown to get pendown state
  Input: ALPS - add signature for DualPoint found in Dell Latitude E6500
  Input: serio_raw - allow attaching to translated (SERIO_I8042XL) ports
  Input: cm109 - don't use obsolete logging macros
  Input: atkbd - expand Latitude's force release quirk to other Dells
  Input: bf54x-keys - add power management support
  Input: atmel_tsadcc - improve accuracy
  Input: convert drivers to use strict_strtoul()
  Input: appletouch - handle geyser 3/4 status bits
  ...
parents d7a6119f 4c0e799a
...@@ -796,6 +796,7 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -796,6 +796,7 @@ and is between 256 and 4096 characters. It is defined in the file
Defaults to the default architecture's huge page size Defaults to the default architecture's huge page size
if not specified. if not specified.
i8042.debug [HW] Toggle i8042 debug mode
i8042.direct [HW] Put keyboard port into non-translated mode i8042.direct [HW] Put keyboard port into non-translated mode
i8042.dumbkbd [HW] Pretend that controller can only read data from i8042.dumbkbd [HW] Pretend that controller can only read data from
keyboard and cannot control its state keyboard and cannot control its state
......
...@@ -4618,7 +4618,7 @@ WM97XX TOUCHSCREEN DRIVERS ...@@ -4618,7 +4618,7 @@ WM97XX TOUCHSCREEN DRIVERS
P: Mark Brown P: Mark Brown
M: broonie@opensource.wolfsonmicro.com M: broonie@opensource.wolfsonmicro.com
P: Liam Girdwood P: Liam Girdwood
M: liam.girdwood@wolfsonmicro.com M: lrg@slimlogic.co.uk
L: linux-input@vger.kernel.org L: linux-input@vger.kernel.org
T: git git://opensource.wolfsonmicro.com/linux-2.6-touch T: git git://opensource.wolfsonmicro.com/linux-2.6-touch
W: http://opensource.wolfsonmicro.com/node/7 W: http://opensource.wolfsonmicro.com/node/7
......
...@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) ...@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
return; return;
} }
if (keycode > NR_KEYS) if (keycode >= NR_KEYS)
if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
else else
......
...@@ -231,6 +231,7 @@ static void gameport_find_driver(struct gameport *gameport) ...@@ -231,6 +231,7 @@ static void gameport_find_driver(struct gameport *gameport)
enum gameport_event_type { enum gameport_event_type {
GAMEPORT_REGISTER_PORT, GAMEPORT_REGISTER_PORT,
GAMEPORT_REGISTER_DRIVER, GAMEPORT_REGISTER_DRIVER,
GAMEPORT_ATTACH_DRIVER,
}; };
struct gameport_event { struct gameport_event {
...@@ -245,11 +246,12 @@ static LIST_HEAD(gameport_event_list); ...@@ -245,11 +246,12 @@ static LIST_HEAD(gameport_event_list);
static DECLARE_WAIT_QUEUE_HEAD(gameport_wait); static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
static struct task_struct *gameport_task; static struct task_struct *gameport_task;
static void gameport_queue_event(void *object, struct module *owner, static int gameport_queue_event(void *object, struct module *owner,
enum gameport_event_type event_type) enum gameport_event_type event_type)
{ {
unsigned long flags; unsigned long flags;
struct gameport_event *event; struct gameport_event *event;
int retval = 0;
spin_lock_irqsave(&gameport_event_lock, flags); spin_lock_irqsave(&gameport_event_lock, flags);
...@@ -268,24 +270,34 @@ static void gameport_queue_event(void *object, struct module *owner, ...@@ -268,24 +270,34 @@ static void gameport_queue_event(void *object, struct module *owner,
} }
} }
if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) { event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
if (!try_module_get(owner)) { if (!event) {
printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type); printk(KERN_ERR
kfree(event); "gameport: Not enough memory to queue event %d\n",
goto out; event_type);
} retval = -ENOMEM;
goto out;
event->type = event_type; }
event->object = object;
event->owner = owner;
list_add_tail(&event->node, &gameport_event_list); if (!try_module_get(owner)) {
wake_up(&gameport_wait); printk(KERN_WARNING
} else { "gameport: Can't get module reference, dropping event %d\n",
printk(KERN_ERR "gameport: Not enough memory to queue event %d\n", event_type); event_type);
kfree(event);
retval = -EINVAL;
goto out;
} }
event->type = event_type;
event->object = object;
event->owner = owner;
list_add_tail(&event->node, &gameport_event_list);
wake_up(&gameport_wait);
out: out:
spin_unlock_irqrestore(&gameport_event_lock, flags); spin_unlock_irqrestore(&gameport_event_lock, flags);
return retval;
} }
static void gameport_free_event(struct gameport_event *event) static void gameport_free_event(struct gameport_event *event)
...@@ -378,9 +390,10 @@ static void gameport_handle_event(void) ...@@ -378,9 +390,10 @@ static void gameport_handle_event(void)
} }
/* /*
* Remove all events that have been submitted for a given gameport port. * Remove all events that have been submitted for a given object,
* be it a gameport port or a driver.
*/ */
static void gameport_remove_pending_events(struct gameport *gameport) static void gameport_remove_pending_events(void *object)
{ {
struct list_head *node, *next; struct list_head *node, *next;
struct gameport_event *event; struct gameport_event *event;
...@@ -390,7 +403,7 @@ static void gameport_remove_pending_events(struct gameport *gameport) ...@@ -390,7 +403,7 @@ static void gameport_remove_pending_events(struct gameport *gameport)
list_for_each_safe(node, next, &gameport_event_list) { list_for_each_safe(node, next, &gameport_event_list) {
event = list_entry(node, struct gameport_event, node); event = list_entry(node, struct gameport_event, node);
if (event->object == gameport) { if (event->object == object) {
list_del_init(node); list_del_init(node);
gameport_free_event(event); gameport_free_event(event);
} }
...@@ -705,10 +718,40 @@ static void gameport_add_driver(struct gameport_driver *drv) ...@@ -705,10 +718,40 @@ static void gameport_add_driver(struct gameport_driver *drv)
drv->driver.name, error); drv->driver.name, error);
} }
void __gameport_register_driver(struct gameport_driver *drv, struct module *owner) int __gameport_register_driver(struct gameport_driver *drv, struct module *owner,
const char *mod_name)
{ {
int error;
drv->driver.bus = &gameport_bus; drv->driver.bus = &gameport_bus;
gameport_queue_event(drv, owner, GAMEPORT_REGISTER_DRIVER); drv->driver.owner = owner;
drv->driver.mod_name = mod_name;
/*
* Temporarily disable automatic binding because probing
* takes long time and we are better off doing it in kgameportd
*/
drv->ignore = 1;
error = driver_register(&drv->driver);
if (error) {
printk(KERN_ERR
"gameport: driver_register() failed for %s, error: %d\n",
drv->driver.name, error);
return error;
}
/*
* Reset ignore flag and let kgameportd bind the driver to free ports
*/
drv->ignore = 0;
error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER);
if (error) {
driver_unregister(&drv->driver);
return error;
}
return 0;
} }
void gameport_unregister_driver(struct gameport_driver *drv) void gameport_unregister_driver(struct gameport_driver *drv)
...@@ -716,7 +759,9 @@ void gameport_unregister_driver(struct gameport_driver *drv) ...@@ -716,7 +759,9 @@ void gameport_unregister_driver(struct gameport_driver *drv)
struct gameport *gameport; struct gameport *gameport;
mutex_lock(&gameport_mutex); mutex_lock(&gameport_mutex);
drv->ignore = 1; /* so gameport_find_driver ignores it */ drv->ignore = 1; /* so gameport_find_driver ignores it */
gameport_remove_pending_events(drv);
start_over: start_over:
list_for_each_entry(gameport, &gameport_list, node) { list_for_each_entry(gameport, &gameport_list, node) {
...@@ -729,6 +774,7 @@ void gameport_unregister_driver(struct gameport_driver *drv) ...@@ -729,6 +774,7 @@ void gameport_unregister_driver(struct gameport_driver *drv)
} }
driver_unregister(&drv->driver); driver_unregister(&drv->driver);
mutex_unlock(&gameport_mutex); mutex_unlock(&gameport_mutex);
} }
......
...@@ -414,8 +414,7 @@ static struct gameport_driver a3d_drv = { ...@@ -414,8 +414,7 @@ static struct gameport_driver a3d_drv = {
static int __init a3d_init(void) static int __init a3d_init(void)
{ {
gameport_register_driver(&a3d_drv); return gameport_register_driver(&a3d_drv);
return 0;
} }
static void __exit a3d_exit(void) static void __exit a3d_exit(void)
......
...@@ -572,8 +572,7 @@ static struct gameport_driver adi_drv = { ...@@ -572,8 +572,7 @@ static struct gameport_driver adi_drv = {
static int __init adi_init(void) static int __init adi_init(void)
{ {
gameport_register_driver(&adi_drv); return gameport_register_driver(&adi_drv);
return 0;
} }
static void __exit adi_exit(void) static void __exit adi_exit(void)
......
...@@ -761,9 +761,7 @@ static struct gameport_driver analog_drv = { ...@@ -761,9 +761,7 @@ static struct gameport_driver analog_drv = {
static int __init analog_init(void) static int __init analog_init(void)
{ {
analog_parse_options(); analog_parse_options();
gameport_register_driver(&analog_drv); return gameport_register_driver(&analog_drv);
return 0;
} }
static void __exit analog_exit(void) static void __exit analog_exit(void)
......
...@@ -263,8 +263,7 @@ static struct gameport_driver cobra_drv = { ...@@ -263,8 +263,7 @@ static struct gameport_driver cobra_drv = {
static int __init cobra_init(void) static int __init cobra_init(void)
{ {
gameport_register_driver(&cobra_drv); return gameport_register_driver(&cobra_drv);
return 0;
} }
static void __exit cobra_exit(void) static void __exit cobra_exit(void)
......
...@@ -375,8 +375,7 @@ static struct gameport_driver gf2k_drv = { ...@@ -375,8 +375,7 @@ static struct gameport_driver gf2k_drv = {
static int __init gf2k_init(void) static int __init gf2k_init(void)
{ {
gameport_register_driver(&gf2k_drv); return gameport_register_driver(&gf2k_drv);
return 0;
} }
static void __exit gf2k_exit(void) static void __exit gf2k_exit(void)
......
...@@ -426,8 +426,7 @@ static struct gameport_driver grip_drv = { ...@@ -426,8 +426,7 @@ static struct gameport_driver grip_drv = {
static int __init grip_init(void) static int __init grip_init(void)
{ {
gameport_register_driver(&grip_drv); return gameport_register_driver(&grip_drv);
return 0;
} }
static void __exit grip_exit(void) static void __exit grip_exit(void)
......
...@@ -689,8 +689,7 @@ static struct gameport_driver grip_drv = { ...@@ -689,8 +689,7 @@ static struct gameport_driver grip_drv = {
static int __init grip_init(void) static int __init grip_init(void)
{ {
gameport_register_driver(&grip_drv); return gameport_register_driver(&grip_drv);
return 0;
} }
static void __exit grip_exit(void) static void __exit grip_exit(void)
......
...@@ -283,8 +283,7 @@ static struct gameport_driver guillemot_drv = { ...@@ -283,8 +283,7 @@ static struct gameport_driver guillemot_drv = {
static int __init guillemot_init(void) static int __init guillemot_init(void)
{ {
gameport_register_driver(&guillemot_drv); return gameport_register_driver(&guillemot_drv);
return 0;
} }
static void __exit guillemot_exit(void) static void __exit guillemot_exit(void)
......
...@@ -317,8 +317,7 @@ static struct gameport_driver interact_drv = { ...@@ -317,8 +317,7 @@ static struct gameport_driver interact_drv = {
static int __init interact_init(void) static int __init interact_init(void)
{ {
gameport_register_driver(&interact_drv); return gameport_register_driver(&interact_drv);
return 0;
} }
static void __exit interact_exit(void) static void __exit interact_exit(void)
......
...@@ -161,8 +161,7 @@ static struct gameport_driver joydump_drv = { ...@@ -161,8 +161,7 @@ static struct gameport_driver joydump_drv = {
static int __init joydump_init(void) static int __init joydump_init(void)
{ {
gameport_register_driver(&joydump_drv); return gameport_register_driver(&joydump_drv);
return 0;
} }
static void __exit joydump_exit(void) static void __exit joydump_exit(void)
......
...@@ -818,8 +818,7 @@ static struct gameport_driver sw_drv = { ...@@ -818,8 +818,7 @@ static struct gameport_driver sw_drv = {
static int __init sw_init(void) static int __init sw_init(void)
{ {
gameport_register_driver(&sw_drv); return gameport_register_driver(&sw_drv);
return 0;
} }
static void __exit sw_exit(void) static void __exit sw_exit(void)
......
...@@ -438,8 +438,7 @@ static struct gameport_driver tmdc_drv = { ...@@ -438,8 +438,7 @@ static struct gameport_driver tmdc_drv = {
static int __init tmdc_init(void) static int __init tmdc_init(void)
{ {
gameport_register_driver(&tmdc_drv); return gameport_register_driver(&tmdc_drv);
return 0;
} }
static void __exit tmdc_exit(void) static void __exit tmdc_exit(void)
......
...@@ -834,10 +834,10 @@ static void atkbd_disconnect(struct serio *serio) ...@@ -834,10 +834,10 @@ static void atkbd_disconnect(struct serio *serio)
} }
/* /*
* Most special keys (Fn+F?) on Dell Latitudes do not generate release * Most special keys (Fn+F?) on Dell laptops do not generate release
* events so we have to do it ourselves. * events so we have to do it ourselves.
*/ */
static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd) static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
{ {
const unsigned int forced_release_keys[] = { const unsigned int forced_release_keys[] = {
0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
...@@ -1207,15 +1207,13 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun ...@@ -1207,15 +1207,13 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
{ {
struct input_dev *old_dev, *new_dev; struct input_dev *old_dev, *new_dev;
unsigned long value; unsigned long value;
char *rest;
int err; int err;
unsigned char old_extra, old_set; unsigned char old_extra, old_set;
if (!atkbd->write) if (!atkbd->write)
return -EIO; return -EIO;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value) || value > 1)
if (*rest || value > 1)
return -EINVAL; return -EINVAL;
if (atkbd->extra != value) { if (atkbd->extra != value) {
...@@ -1264,12 +1262,10 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou ...@@ -1264,12 +1262,10 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou
{ {
struct input_dev *old_dev, *new_dev; struct input_dev *old_dev, *new_dev;
unsigned long value; unsigned long value;
char *rest;
int err; int err;
unsigned char old_scroll; unsigned char old_scroll;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value) || value > 1)
if (*rest || value > 1)
return -EINVAL; return -EINVAL;
if (atkbd->scroll != value) { if (atkbd->scroll != value) {
...@@ -1310,15 +1306,13 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) ...@@ -1310,15 +1306,13 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
{ {
struct input_dev *old_dev, *new_dev; struct input_dev *old_dev, *new_dev;
unsigned long value; unsigned long value;
char *rest;
int err; int err;
unsigned char old_set, old_extra; unsigned char old_set, old_extra;
if (!atkbd->write) if (!atkbd->write)
return -EIO; return -EIO;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value) || (value != 2 && value != 3))
if (*rest || (value != 2 && value != 3))
return -EINVAL; return -EINVAL;
if (atkbd->set != value) { if (atkbd->set != value) {
...@@ -1361,15 +1355,13 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t ...@@ -1361,15 +1355,13 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
{ {
struct input_dev *old_dev, *new_dev; struct input_dev *old_dev, *new_dev;
unsigned long value; unsigned long value;
char *rest;
int err; int err;
unsigned char old_softrepeat, old_softraw; unsigned char old_softrepeat, old_softraw;
if (!atkbd->write) if (!atkbd->write)
return -EIO; return -EIO;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value) || value > 1)
if (*rest || value > 1)
return -EINVAL; return -EINVAL;
if (atkbd->softrepeat != value) { if (atkbd->softrepeat != value) {
...@@ -1413,12 +1405,10 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co ...@@ -1413,12 +1405,10 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
{ {
struct input_dev *old_dev, *new_dev; struct input_dev *old_dev, *new_dev;
unsigned long value; unsigned long value;
char *rest;
int err; int err;
unsigned char old_softraw; unsigned char old_softraw;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value) || value > 1)
if (*rest || value > 1)
return -EINVAL; return -EINVAL;
if (atkbd->softraw != value) { if (atkbd->softraw != value) {
...@@ -1461,13 +1451,13 @@ static int __init atkbd_setup_fixup(const struct dmi_system_id *id) ...@@ -1461,13 +1451,13 @@ static int __init atkbd_setup_fixup(const struct dmi_system_id *id)
static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
{ {
.ident = "Dell Latitude series", .ident = "Dell Laptop",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
}, },
.callback = atkbd_setup_fixup, .callback = atkbd_setup_fixup,
.driver_data = atkbd_latitude_keymap_fixup, .driver_data = atkbd_dell_laptop_keymap_fixup,
}, },
{ {
.ident = "HP 2133", .ident = "HP 2133",
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* Modified: * Modified:
* Copyright 2007 Analog Devices Inc. * Copyright 2007-2008 Analog Devices Inc.
* *
* Bugs: Enter bugs at http://blackfin.uclinux.org/ * Bugs: Enter bugs at http://blackfin.uclinux.org/
* *
...@@ -81,6 +81,9 @@ struct bf54x_kpad { ...@@ -81,6 +81,9 @@ struct bf54x_kpad {
unsigned short *keycode; unsigned short *keycode;
struct timer_list timer; struct timer_list timer;
unsigned int keyup_test_jiffies; unsigned int keyup_test_jiffies;
unsigned short kpad_msel;
unsigned short kpad_prescale;
unsigned short kpad_ctl;
}; };
static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad, static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad,
...@@ -360,6 +363,10 @@ static int bfin_kpad_suspend(struct platform_device *pdev, pm_message_t state) ...@@ -360,6 +363,10 @@ static int bfin_kpad_suspend(struct platform_device *pdev, pm_message_t state)
{ {
struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
bf54x_kpad->kpad_msel = bfin_read_KPAD_MSEL();
bf54x_kpad->kpad_prescale = bfin_read_KPAD_PRESCALE();
bf54x_kpad->kpad_ctl = bfin_read_KPAD_CTL();
if (device_may_wakeup(&pdev->dev)) if (device_may_wakeup(&pdev->dev))
enable_irq_wake(bf54x_kpad->irq); enable_irq_wake(bf54x_kpad->irq);
...@@ -370,6 +377,10 @@ static int bfin_kpad_resume(struct platform_device *pdev) ...@@ -370,6 +377,10 @@ static int bfin_kpad_resume(struct platform_device *pdev)
{ {
struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
bfin_write_KPAD_MSEL(bf54x_kpad->kpad_msel);
bfin_write_KPAD_PRESCALE(bf54x_kpad->kpad_prescale);
bfin_write_KPAD_CTL(bf54x_kpad->kpad_ctl);
if (device_may_wakeup(&pdev->dev)) if (device_may_wakeup(&pdev->dev))
disable_irq_wake(bf54x_kpad->irq); disable_irq_wake(bf54x_kpad->irq);
......
...@@ -36,9 +36,10 @@ struct gpio_keys_drvdata { ...@@ -36,9 +36,10 @@ struct gpio_keys_drvdata {
struct gpio_button_data data[0]; struct gpio_button_data data[0];
}; };
static void gpio_keys_report_event(struct gpio_keys_button *button, static void gpio_keys_report_event(struct gpio_button_data *bdata)
struct input_dev *input)
{ {
struct gpio_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned int type = button->type ?: EV_KEY; unsigned int type = button->type ?: EV_KEY;
int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low; int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
...@@ -50,34 +51,23 @@ static void gpio_check_button(unsigned long _data) ...@@ -50,34 +51,23 @@ static void gpio_check_button(unsigned long _data)
{ {
struct gpio_button_data *data = (struct gpio_button_data *)_data; struct gpio_button_data *data = (struct gpio_button_data *)_data;
gpio_keys_report_event(data->button, data->input); gpio_keys_report_event(data);
} }
static irqreturn_t gpio_keys_isr(int irq, void *dev_id) static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
{ {
struct platform_device *pdev = dev_id; struct gpio_button_data *bdata = dev_id;
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; struct gpio_keys_button *button = bdata->button;
struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
int i;
for (i = 0; i < pdata->nbuttons; i++) { BUG_ON(irq != gpio_to_irq(button->gpio));
struct gpio_keys_button *button = &pdata->buttons[i];
if (irq == gpio_to_irq(button->gpio)) { if (button->debounce_interval)
struct gpio_button_data *bdata = &ddata->data[i]; mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(button->debounce_interval));
if (button->debounce_interval) else
mod_timer(&bdata->timer, gpio_keys_report_event(bdata);
jiffies +
msecs_to_jiffies(button->debounce_interval));
else
gpio_keys_report_event(button, bdata->input);
return IRQ_HANDLED;
}
}
return IRQ_NONE; return IRQ_HANDLED;
} }
static int __devinit gpio_keys_probe(struct platform_device *pdev) static int __devinit gpio_keys_probe(struct platform_device *pdev)
...@@ -151,7 +141,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) ...@@ -151,7 +141,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING | IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING, IRQF_TRIGGER_FALLING,
button->desc ? button->desc : "gpio_keys", button->desc ? button->desc : "gpio_keys",
pdev); bdata);
if (error) { if (error) {
pr_err("gpio-keys: Unable to claim irq %d; error %d\n", pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
irq, error); irq, error);
...@@ -178,7 +168,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) ...@@ -178,7 +168,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
fail2: fail2:
while (--i >= 0) { while (--i >= 0) {
free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
if (pdata->buttons[i].debounce_interval) if (pdata->buttons[i].debounce_interval)
del_timer_sync(&ddata->data[i].timer); del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio); gpio_free(pdata->buttons[i].gpio);
...@@ -203,7 +193,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) ...@@ -203,7 +193,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
for (i = 0; i < pdata->nbuttons; i++) { for (i = 0; i < pdata->nbuttons; i++) {
int irq = gpio_to_irq(pdata->buttons[i].gpio); int irq = gpio_to_irq(pdata->buttons[i].gpio);
free_irq(irq, pdev); free_irq(irq, &ddata->data[i]);
if (pdata->buttons[i].debounce_interval) if (pdata->buttons[i].debounce_interval)
del_timer_sync(&ddata->data[i].timer); del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio); gpio_free(pdata->buttons[i].gpio);
......
...@@ -180,6 +180,19 @@ config INPUT_YEALINK ...@@ -180,6 +180,19 @@ config INPUT_YEALINK
To compile this driver as a module, choose M here: the module will be To compile this driver as a module, choose M here: the module will be
called yealink. called yealink.
config INPUT_CM109
tristate "C-Media CM109 USB I/O Controller"
depends on EXPERIMENTAL
depends on USB_ARCH_HAS_HCD
select USB
help
Say Y here if you want to enable keyboard and buzzer functions of the
C-Media CM109 usb phones. The audio part is enabled by the generic
usb sound driver, so you might want to enable that as well.
To compile this driver as a module, choose M here: the module will be
called cm109.
config INPUT_UINPUT config INPUT_UINPUT
tristate "User level driver support" tristate "User level driver support"
help help
......
...@@ -16,6 +16,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o ...@@ -16,6 +16,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
obj-$(CONFIG_INPUT_POWERMATE) += powermate.o obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o obj-$(CONFIG_INPUT_YEALINK) += yealink.o
obj-$(CONFIG_INPUT_CM109) += cm109.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_APANEL) += apanel.o obj-$(CONFIG_INPUT_APANEL) += apanel.o
......
This diff is collapsed.
This diff is collapsed.
...@@ -277,6 +277,16 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { ...@@ -277,6 +277,16 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
{ KE_END, 0 } { KE_END, 0 }
}; };
static struct key_entry keymap_fs_amilo_pro_v3505[] __initdata = {
{ KE_KEY, 0x01, {KEY_HELP} }, /* Fn+F1 */
{ KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Fn+F4 */
{ KE_BLUETOOTH, 0x30 }, /* Fn+F10 */
{ KE_KEY, 0x31, {KEY_MAIL} }, /* mail button */
{ KE_KEY, 0x36, {KEY_WWW} }, /* www button */
{ KE_WIFI, 0x78 }, /* satelite dish button */
{ KE_END, 0 }
};
static struct key_entry keymap_fujitsu_n3510[] __initdata = { static struct key_entry keymap_fujitsu_n3510[] __initdata = {
{ KE_KEY, 0x11, {KEY_PROG1} }, { KE_KEY, 0x11, {KEY_PROG1} },
{ KE_KEY, 0x12, {KEY_PROG2} }, { KE_KEY, 0x12, {KEY_PROG2} },
...@@ -616,6 +626,15 @@ static struct dmi_system_id dmi_ids[] __initdata = { ...@@ -616,6 +626,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
}, },
.driver_data = keymap_fs_amilo_pro_v2000 .driver_data = keymap_fs_amilo_pro_v2000
}, },
{
.callback = dmi_matched,
.ident = "Fujitsu-Siemens Amilo Pro Edition V3505",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"),
},
.driver_data = keymap_fs_amilo_pro_v3505
},
{ {
.callback = dmi_matched, .callback = dmi_matched,
.ident = "Fujitsu-Siemens Amilo M7400", .ident = "Fujitsu-Siemens Amilo M7400",
......
...@@ -52,8 +52,8 @@ ...@@ -52,8 +52,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/usb/input.h> #include <linux/usb/input.h>
#include <linux/map_to_7segment.h>
#include "map_to_7segment.h"
#include "yealink.h" #include "yealink.h"
#define DRIVER_VERSION "yld-20051230" #define DRIVER_VERSION "yld-20051230"
......
...@@ -96,6 +96,16 @@ config MOUSE_PS2_TOUCHKIT ...@@ -96,6 +96,16 @@ config MOUSE_PS2_TOUCHKIT
If unsure, say N. If unsure, say N.
config MOUSE_PS2_OLPC
bool "OLPC PS/2 mouse protocol extension"
depends on MOUSE_PS2 && OLPC
help
Say Y here if you have an OLPC XO-1 laptop (with built-in
PS/2 touchpad/tablet device). The manufacturer calls the
touchpad an HGPK.
If unsure, say N.
config MOUSE_SERIAL config MOUSE_SERIAL
tristate "Serial mouse" tristate "Serial mouse"
select SERIO select SERIO
......
...@@ -21,6 +21,7 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o ...@@ -21,6 +21,7 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
psmouse-objs := psmouse-base.o synaptics.o psmouse-objs := psmouse-base.o synaptics.o
psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o
psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o
psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o
psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o
psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
......
...@@ -54,6 +54,7 @@ static const struct alps_model_info alps_model_data[] = { ...@@ -54,6 +54,7 @@ static const struct alps_model_info alps_model_data[] = {
{ { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
{ { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
{ { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
{ { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */
{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */ { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */
}; };
......
This diff is collapsed.
This diff is collapsed.
/*
* OLPC HGPK (XO-1) touchpad PS/2 mouse driver
*/
#ifndef _HGPK_H
#define _HGPK_H
enum hgpk_model_t {
HGPK_MODEL_PREA = 0x0a, /* pre-B1s */
HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */
HGPK_MODEL_B = 0x28, /* B2s, has capacitance issues */
HGPK_MODEL_C = 0x3c,
HGPK_MODEL_D = 0x50, /* C1, mass production */
};
struct hgpk_data {
struct psmouse *psmouse;
int powered;
int count, x_tally, y_tally; /* hardware workaround stuff */
unsigned long recalib_window;
struct delayed_work recalib_wq;
};
#define hgpk_dbg(psmouse, format, arg...) \
dev_dbg(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_err(psmouse, format, arg...) \
dev_err(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_info(psmouse, format, arg...) \
dev_info(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_warn(psmouse, format, arg...) \
dev_warn(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_notice(psmouse, format, arg...) \
dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#ifdef CONFIG_MOUSE_PS2_OLPC
int hgpk_detect(struct psmouse *psmouse, int set_properties);
int hgpk_init(struct psmouse *psmouse);
#else
static inline int hgpk_detect(struct psmouse *psmouse, int set_properties)
{
return -ENODEV;
}
static inline int hgpk_init(struct psmouse *psmouse)
{
return -ENODEV;
}
#endif
#endif
...@@ -157,10 +157,8 @@ static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data, ...@@ -157,10 +157,8 @@ static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data,
static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count) static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{ {
unsigned long value; unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value) || value > 1)
if (*rest || value > 1)
return -EINVAL; return -EINVAL;
ps2pp_set_smartscroll(psmouse, value); ps2pp_set_smartscroll(psmouse, value);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "synaptics.h" #include "synaptics.h"
#include "logips2pp.h" #include "logips2pp.h"
#include "alps.h" #include "alps.h"
#include "hgpk.h"
#include "lifebook.h" #include "lifebook.h"
#include "trackpoint.h" #include "trackpoint.h"
#include "touchkit_ps2.h" #include "touchkit_ps2.h"
...@@ -201,6 +202,12 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) ...@@ -201,6 +202,12 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
return PSMOUSE_FULL_PACKET; return PSMOUSE_FULL_PACKET;
} }
void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
unsigned long delay)
{
queue_delayed_work(kpsmoused_wq, work, delay);
}
/* /*
* __psmouse_set_state() sets new psmouse state and resets all flags. * __psmouse_set_state() sets new psmouse state and resets all flags.
*/ */
...@@ -220,7 +227,7 @@ static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_sta ...@@ -220,7 +227,7 @@ static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_sta
* is not a concern. * is not a concern.
*/ */
static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
{ {
serio_pause_rx(psmouse->ps2dev.serio); serio_pause_rx(psmouse->ps2dev.serio);
__psmouse_set_state(psmouse, new_state); __psmouse_set_state(psmouse, new_state);
...@@ -305,7 +312,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -305,7 +312,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
psmouse->name, psmouse->phys, psmouse->pktcnt); psmouse->name, psmouse->phys, psmouse->pktcnt);
psmouse->badbyte = psmouse->packet[0]; psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING); __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
queue_work(kpsmoused_wq, &psmouse->resync_work); psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
goto out; goto out;
} }
...@@ -342,7 +349,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -342,7 +349,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) { time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {
psmouse->badbyte = psmouse->packet[0]; psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING); __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
queue_work(kpsmoused_wq, &psmouse->resync_work); psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
goto out; goto out;
} }
...@@ -630,8 +637,20 @@ static int psmouse_extensions(struct psmouse *psmouse, ...@@ -630,8 +637,20 @@ static int psmouse_extensions(struct psmouse *psmouse,
} }
} }
if (max_proto > PSMOUSE_IMEX) { /*
* Try OLPC HGPK touchpad.
*/
if (max_proto > PSMOUSE_IMEX &&
hgpk_detect(psmouse, set_properties) == 0) {
if (!set_properties || hgpk_init(psmouse) == 0)
return PSMOUSE_HGPK;
/*
* Init failed, try basic relative protocols
*/
max_proto = PSMOUSE_IMEX;
}
if (max_proto > PSMOUSE_IMEX) {
if (genius_detect(psmouse, set_properties) == 0) if (genius_detect(psmouse, set_properties) == 0)
return PSMOUSE_GENPS; return PSMOUSE_GENPS;
...@@ -761,6 +780,14 @@ static const struct psmouse_protocol psmouse_protocols[] = { ...@@ -761,6 +780,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.alias = "touchkit", .alias = "touchkit",
.detect = touchkit_ps2_detect, .detect = touchkit_ps2_detect,
}, },
#endif
#ifdef CONFIG_MOUSE_PS2_OLPC
{
.type = PSMOUSE_HGPK,
.name = "OLPC HGPK",
.alias = "hgpk",
.detect = hgpk_detect,
},
#endif #endif
{ {
.type = PSMOUSE_CORTRON, .type = PSMOUSE_CORTRON,
...@@ -935,7 +962,7 @@ static int psmouse_poll(struct psmouse *psmouse) ...@@ -935,7 +962,7 @@ static int psmouse_poll(struct psmouse *psmouse)
static void psmouse_resync(struct work_struct *work) static void psmouse_resync(struct work_struct *work)
{ {
struct psmouse *parent = NULL, *psmouse = struct psmouse *parent = NULL, *psmouse =
container_of(work, struct psmouse, resync_work); container_of(work, struct psmouse, resync_work.work);
struct serio *serio = psmouse->ps2dev.serio; struct serio *serio = psmouse->ps2dev.serio;
psmouse_ret_t rc = PSMOUSE_GOOD_DATA; psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
int failed = 0, enabled = 0; int failed = 0, enabled = 0;
...@@ -1194,7 +1221,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) ...@@ -1194,7 +1221,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
goto err_free; goto err_free;
ps2_init(&psmouse->ps2dev, serio); ps2_init(&psmouse->ps2dev, serio);
INIT_WORK(&psmouse->resync_work, psmouse_resync); INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync);
psmouse->dev = input_dev; psmouse->dev = input_dev;
snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys); snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys);
...@@ -1395,25 +1422,29 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev ...@@ -1395,25 +1422,29 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev
psmouse = serio_get_drvdata(serio); psmouse = serio_get_drvdata(serio);
if (psmouse->state == PSMOUSE_IGNORE) { if (attr->protect) {
retval = -ENODEV; if (psmouse->state == PSMOUSE_IGNORE) {
goto out_unlock; retval = -ENODEV;
} goto out_unlock;
}
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
parent = serio_get_drvdata(serio->parent); parent = serio_get_drvdata(serio->parent);
psmouse_deactivate(parent); psmouse_deactivate(parent);
} }
psmouse_deactivate(psmouse); psmouse_deactivate(psmouse);
}
retval = attr->set(psmouse, attr->data, buf, count); retval = attr->set(psmouse, attr->data, buf, count);
if (retval != -ENODEV) if (attr->protect) {
psmouse_activate(psmouse); if (retval != -ENODEV)
psmouse_activate(psmouse);
if (parent) if (parent)
psmouse_activate(parent); psmouse_activate(parent);
}
out_unlock: out_unlock:
mutex_unlock(&psmouse_mutex); mutex_unlock(&psmouse_mutex);
...@@ -1433,10 +1464,8 @@ static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const ...@@ -1433,10 +1464,8 @@ static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const
{ {
unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset); unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset);
unsigned long value; unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value))
if (*rest)
return -EINVAL; return -EINVAL;
if ((unsigned int)value != value) if ((unsigned int)value != value)
...@@ -1549,10 +1578,8 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co ...@@ -1549,10 +1578,8 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count) static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{ {
unsigned long value; unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value))
if (*rest)
return -EINVAL; return -EINVAL;
psmouse->set_rate(psmouse, value); psmouse->set_rate(psmouse, value);
...@@ -1562,10 +1589,8 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const ...@@ -1562,10 +1589,8 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const
static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count) static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{ {
unsigned long value; unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value))
if (*rest)
return -EINVAL; return -EINVAL;
psmouse->set_resolution(psmouse, value); psmouse->set_resolution(psmouse, value);
......
...@@ -39,7 +39,7 @@ struct psmouse { ...@@ -39,7 +39,7 @@ struct psmouse {
void *private; void *private;
struct input_dev *dev; struct input_dev *dev;
struct ps2dev ps2dev; struct ps2dev ps2dev;
struct work_struct resync_work; struct delayed_work resync_work;
char *vendor; char *vendor;
char *name; char *name;
unsigned char packet[8]; unsigned char packet[8];
...@@ -89,20 +89,24 @@ enum psmouse_type { ...@@ -89,20 +89,24 @@ enum psmouse_type {
PSMOUSE_TRACKPOINT, PSMOUSE_TRACKPOINT,
PSMOUSE_TOUCHKIT_PS2, PSMOUSE_TOUCHKIT_PS2,
PSMOUSE_CORTRON, PSMOUSE_CORTRON,
PSMOUSE_HGPK,
PSMOUSE_AUTO /* This one should always be last */ PSMOUSE_AUTO /* This one should always be last */
}; };
void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
unsigned long delay);
int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command); int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
int psmouse_reset(struct psmouse *psmouse); int psmouse_reset(struct psmouse *psmouse);
void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state);
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution); void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
struct psmouse_attribute { struct psmouse_attribute {
struct device_attribute dattr; struct device_attribute dattr;
void *data; void *data;
ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf); ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
ssize_t (*set)(struct psmouse *psmouse, void *data, ssize_t (*set)(struct psmouse *psmouse, void *data,
const char *buf, size_t count); const char *buf, size_t count);
int protect;
}; };
#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr) #define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr)
...@@ -111,7 +115,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at ...@@ -111,7 +115,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at
ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr, ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count); const char *buf, size_t count);
#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \ #define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \
static ssize_t _show(struct psmouse *, void *data, char *); \ static ssize_t _show(struct psmouse *, void *data, char *); \
static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \ static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \
static struct psmouse_attribute psmouse_attr_##_name = { \ static struct psmouse_attribute psmouse_attr_##_name = { \
...@@ -126,6 +130,10 @@ static struct psmouse_attribute psmouse_attr_##_name = { \ ...@@ -126,6 +130,10 @@ static struct psmouse_attribute psmouse_attr_##_name = { \
.data = _data, \ .data = _data, \
.show = _show, \ .show = _show, \
.set = _set, \ .set = _set, \
.protect = _protect, \
} }
#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \
__PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, 1)
#endif /* _PSMOUSE_H */ #endif /* _PSMOUSE_H */
...@@ -89,10 +89,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, ...@@ -89,10 +89,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
struct trackpoint_attr_data *attr = data; struct trackpoint_attr_data *attr = data;
unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
unsigned long value; unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value) || value > 255)
if (*rest || value > 255)
return -EINVAL; return -EINVAL;
*field = value; *field = value;
...@@ -117,10 +115,8 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, ...@@ -117,10 +115,8 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
struct trackpoint_attr_data *attr = data; struct trackpoint_attr_data *attr = data;
unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
unsigned long value; unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10); if (strict_strtoul(buf, 10, &value) || value > 1)
if (*rest || value > 1)
return -EINVAL; return -EINVAL;
if (attr->inverted) if (attr->inverted)
......
...@@ -322,6 +322,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { ...@@ -322,6 +322,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
}, },
}, },
{
.ident = "IBM 2656",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
},
},
{ } { }
}; };
......
...@@ -373,6 +373,12 @@ static struct serio_device_id serio_raw_serio_ids[] = { ...@@ -373,6 +373,12 @@ static struct serio_device_id serio_raw_serio_ids[] = {
.id = SERIO_ANY, .id = SERIO_ANY,
.extra = SERIO_ANY, .extra = SERIO_ANY,
}, },
{
.type = SERIO_8042_XL,
.proto = SERIO_ANY,
.id = SERIO_ANY,
.extra = SERIO_ANY,
},
{ 0 } { 0 }
}; };
......
...@@ -1202,16 +1202,22 @@ static ssize_t ...@@ -1202,16 +1202,22 @@ static ssize_t
store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
struct aiptek *aiptek = dev_get_drvdata(dev); struct aiptek *aiptek = dev_get_drvdata(dev);
int x; long x;
if (strict_strtol(buf, 10, &x)) {
size_t len = buf[count - 1] == '\n' ? count - 1 : count;
if (strncmp(buf, "disable", len))
return -EINVAL;
if (strcmp(buf, "disable") == 0) {
aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE; aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE;
} else { } else {
x = (int)simple_strtol(buf, NULL, 10); if (x < AIPTEK_TILT_MIN || x > AIPTEK_TILT_MAX)
if (x >= AIPTEK_TILT_MIN && x <= AIPTEK_TILT_MAX) { return -EINVAL;
aiptek->newSetting.xTilt = x;
} aiptek->newSetting.xTilt = x;
} }
return count; return count;
} }
...@@ -1238,16 +1244,22 @@ static ssize_t ...@@ -1238,16 +1244,22 @@ static ssize_t
store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
struct aiptek *aiptek = dev_get_drvdata(dev); struct aiptek *aiptek = dev_get_drvdata(dev);
int y; long y;
if (strict_strtol(buf, 10, &y)) {
size_t len = buf[count - 1] == '\n' ? count - 1 : count;
if (strncmp(buf, "disable", len))
return -EINVAL;
if (strcmp(buf, "disable") == 0) {
aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE; aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE;
} else { } else {
y = (int)simple_strtol(buf, NULL, 10); if (y < AIPTEK_TILT_MIN || y > AIPTEK_TILT_MAX)
if (y >= AIPTEK_TILT_MIN && y <= AIPTEK_TILT_MAX) { return -EINVAL;
aiptek->newSetting.yTilt = y;
} aiptek->newSetting.yTilt = y;
} }
return count; return count;
} }
...@@ -1269,8 +1281,12 @@ static ssize_t ...@@ -1269,8 +1281,12 @@ static ssize_t
store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
struct aiptek *aiptek = dev_get_drvdata(dev); struct aiptek *aiptek = dev_get_drvdata(dev);
long j;
if (strict_strtol(buf, 10, &j))
return -EINVAL;
aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10); aiptek->newSetting.jitterDelay = (int)j;
return count; return count;
} }
...@@ -1294,8 +1310,12 @@ static ssize_t ...@@ -1294,8 +1310,12 @@ static ssize_t
store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
struct aiptek *aiptek = dev_get_drvdata(dev); struct aiptek *aiptek = dev_get_drvdata(dev);
long d;
aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10); if (strict_strtol(buf, 10, &d))
return -EINVAL;
aiptek->newSetting.programmableDelay = (int)d;
return count; return count;
} }
...@@ -1541,8 +1561,11 @@ static ssize_t ...@@ -1541,8 +1561,11 @@ static ssize_t
store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
struct aiptek *aiptek = dev_get_drvdata(dev); struct aiptek *aiptek = dev_get_drvdata(dev);
long w;
if (strict_strtol(buf, 10, &w)) return -EINVAL;
aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10); aiptek->newSetting.wheel = (int)w;
return count; return count;
} }
......
...@@ -69,6 +69,17 @@ struct ts_event { ...@@ -69,6 +69,17 @@ struct ts_event {
int ignore; int ignore;
}; };
/*
* We allocate this separately to avoid cache line sharing issues when
* driver is used with DMA-based SPI controllers (like atmel_spi) on
* systems where main memory is not DMA-coherent (most non-x86 boards).
*/
struct ads7846_packet {
u8 read_x, read_y, read_z1, read_z2, pwrdown;
u16 dummy; /* for the pwrdown read */
struct ts_event tc;
};
struct ads7846 { struct ads7846 {
struct input_dev *input; struct input_dev *input;
char phys[32]; char phys[32];
...@@ -86,9 +97,7 @@ struct ads7846 { ...@@ -86,9 +97,7 @@ struct ads7846 {
u16 x_plate_ohms; u16 x_plate_ohms;
u16 pressure_max; u16 pressure_max;
u8 read_x, read_y, read_z1, read_z2, pwrdown; struct ads7846_packet *packet;
u16 dummy; /* for the pwrdown read */
struct ts_event tc;
struct spi_transfer xfer[18]; struct spi_transfer xfer[18];
struct spi_message msg[5]; struct spi_message msg[5];
...@@ -463,10 +472,11 @@ static ssize_t ads7846_disable_store(struct device *dev, ...@@ -463,10 +472,11 @@ static ssize_t ads7846_disable_store(struct device *dev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct ads7846 *ts = dev_get_drvdata(dev); struct ads7846 *ts = dev_get_drvdata(dev);
char *endp; long i;
int i;
if (strict_strtoul(buf, 10, &i))
return -EINVAL;
i = simple_strtoul(buf, &endp, 10);
spin_lock_irq(&ts->lock); spin_lock_irq(&ts->lock);
if (i) if (i)
...@@ -512,16 +522,17 @@ static int get_pendown_state(struct ads7846 *ts) ...@@ -512,16 +522,17 @@ static int get_pendown_state(struct ads7846 *ts)
static void ads7846_rx(void *ads) static void ads7846_rx(void *ads)
{ {
struct ads7846 *ts = ads; struct ads7846 *ts = ads;
struct ads7846_packet *packet = ts->packet;
unsigned Rt; unsigned Rt;
u16 x, y, z1, z2; u16 x, y, z1, z2;
/* ads7846_rx_val() did in-place conversion (including byteswap) from /* ads7846_rx_val() did in-place conversion (including byteswap) from
* on-the-wire format as part of debouncing to get stable readings. * on-the-wire format as part of debouncing to get stable readings.
*/ */
x = ts->tc.x; x = packet->tc.x;
y = ts->tc.y; y = packet->tc.y;
z1 = ts->tc.z1; z1 = packet->tc.z1;
z2 = ts->tc.z2; z2 = packet->tc.z2;
/* range filtering */ /* range filtering */
if (x == MAX_12BIT) if (x == MAX_12BIT)
...@@ -545,10 +556,10 @@ static void ads7846_rx(void *ads) ...@@ -545,10 +556,10 @@ static void ads7846_rx(void *ads)
* the maximum. Don't report it to user space, repeat at least * the maximum. Don't report it to user space, repeat at least
* once more the measurement * once more the measurement
*/ */
if (ts->tc.ignore || Rt > ts->pressure_max) { if (packet->tc.ignore || Rt > ts->pressure_max) {
#ifdef VERBOSE #ifdef VERBOSE
pr_debug("%s: ignored %d pressure %d\n", pr_debug("%s: ignored %d pressure %d\n",
ts->spi->dev.bus_id, ts->tc.ignore, Rt); ts->spi->dev.bus_id, packet->tc.ignore, Rt);
#endif #endif
hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
HRTIMER_MODE_REL); HRTIMER_MODE_REL);
...@@ -641,6 +652,7 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val) ...@@ -641,6 +652,7 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val)
static void ads7846_rx_val(void *ads) static void ads7846_rx_val(void *ads)
{ {
struct ads7846 *ts = ads; struct ads7846 *ts = ads;
struct ads7846_packet *packet = ts->packet;
struct spi_message *m; struct spi_message *m;
struct spi_transfer *t; struct spi_transfer *t;
int val; int val;
...@@ -660,7 +672,7 @@ static void ads7846_rx_val(void *ads) ...@@ -660,7 +672,7 @@ static void ads7846_rx_val(void *ads)
case ADS7846_FILTER_REPEAT: case ADS7846_FILTER_REPEAT:
break; break;
case ADS7846_FILTER_IGNORE: case ADS7846_FILTER_IGNORE:
ts->tc.ignore = 1; packet->tc.ignore = 1;
/* Last message will contain ads7846_rx() as the /* Last message will contain ads7846_rx() as the
* completion function. * completion function.
*/ */
...@@ -668,7 +680,7 @@ static void ads7846_rx_val(void *ads) ...@@ -668,7 +680,7 @@ static void ads7846_rx_val(void *ads)
break; break;
case ADS7846_FILTER_OK: case ADS7846_FILTER_OK:
*(u16 *)t->rx_buf = val; *(u16 *)t->rx_buf = val;
ts->tc.ignore = 0; packet->tc.ignore = 0;
m = &ts->msg[++ts->msg_idx]; m = &ts->msg[++ts->msg_idx];
break; break;
default: default:
...@@ -773,7 +785,6 @@ static void ads7846_disable(struct ads7846 *ts) ...@@ -773,7 +785,6 @@ static void ads7846_disable(struct ads7846 *ts)
/* we know the chip's in lowpower mode since we always /* we know the chip's in lowpower mode since we always
* leave it that way after every request * leave it that way after every request
*/ */
} }
/* Must be called with ts->lock held */ /* Must be called with ts->lock held */
...@@ -849,6 +860,7 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts) ...@@ -849,6 +860,7 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts)
static int __devinit ads7846_probe(struct spi_device *spi) static int __devinit ads7846_probe(struct spi_device *spi)
{ {
struct ads7846 *ts; struct ads7846 *ts;
struct ads7846_packet *packet;
struct input_dev *input_dev; struct input_dev *input_dev;
struct ads7846_platform_data *pdata = spi->dev.platform_data; struct ads7846_platform_data *pdata = spi->dev.platform_data;
struct spi_message *m; struct spi_message *m;
...@@ -884,14 +896,16 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -884,14 +896,16 @@ static int __devinit ads7846_probe(struct spi_device *spi)
return err; return err;
ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL);
input_dev = input_allocate_device(); input_dev = input_allocate_device();
if (!ts || !input_dev) { if (!ts || !packet || !input_dev) {
err = -ENOMEM; err = -ENOMEM;
goto err_free_mem; goto err_free_mem;
} }
dev_set_drvdata(&spi->dev, ts); dev_set_drvdata(&spi->dev, ts);
ts->packet = packet;
ts->spi = spi; ts->spi = spi;
ts->input = input_dev; ts->input = input_dev;
ts->vref_mv = pdata->vref_mv; ts->vref_mv = pdata->vref_mv;
...@@ -963,13 +977,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -963,13 +977,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m); spi_message_init(m);
/* y- still on; turn on only y+ (and ADC) */ /* y- still on; turn on only y+ (and ADC) */
ts->read_y = READ_Y(vref); packet->read_y = READ_Y(vref);
x->tx_buf = &ts->read_y; x->tx_buf = &packet->read_y;
x->len = 1; x->len = 1;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
x++; x++;
x->rx_buf = &ts->tc.y; x->rx_buf = &packet->tc.y;
x->len = 2; x->len = 2;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
...@@ -981,12 +995,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -981,12 +995,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs; x->delay_usecs = pdata->settle_delay_usecs;
x++; x++;
x->tx_buf = &ts->read_y; x->tx_buf = &packet->read_y;
x->len = 1; x->len = 1;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
x++; x++;
x->rx_buf = &ts->tc.y; x->rx_buf = &packet->tc.y;
x->len = 2; x->len = 2;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
} }
...@@ -999,13 +1013,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -999,13 +1013,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
/* turn y- off, x+ on, then leave in lowpower */ /* turn y- off, x+ on, then leave in lowpower */
x++; x++;
ts->read_x = READ_X(vref); packet->read_x = READ_X(vref);
x->tx_buf = &ts->read_x; x->tx_buf = &packet->read_x;
x->len = 1; x->len = 1;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
x++; x++;
x->rx_buf = &ts->tc.x; x->rx_buf = &packet->tc.x;
x->len = 2; x->len = 2;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
...@@ -1014,12 +1028,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -1014,12 +1028,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs; x->delay_usecs = pdata->settle_delay_usecs;
x++; x++;
x->tx_buf = &ts->read_x; x->tx_buf = &packet->read_x;
x->len = 1; x->len = 1;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
x++; x++;
x->rx_buf = &ts->tc.x; x->rx_buf = &packet->tc.x;
x->len = 2; x->len = 2;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
} }
...@@ -1033,13 +1047,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -1033,13 +1047,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m); spi_message_init(m);
x++; x++;
ts->read_z1 = READ_Z1(vref); packet->read_z1 = READ_Z1(vref);
x->tx_buf = &ts->read_z1; x->tx_buf = &packet->read_z1;
x->len = 1; x->len = 1;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
x++; x++;
x->rx_buf = &ts->tc.z1; x->rx_buf = &packet->tc.z1;
x->len = 2; x->len = 2;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
...@@ -1048,12 +1062,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -1048,12 +1062,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs; x->delay_usecs = pdata->settle_delay_usecs;
x++; x++;
x->tx_buf = &ts->read_z1; x->tx_buf = &packet->read_z1;
x->len = 1; x->len = 1;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
x++; x++;
x->rx_buf = &ts->tc.z1; x->rx_buf = &packet->tc.z1;
x->len = 2; x->len = 2;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
} }
...@@ -1065,13 +1079,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -1065,13 +1079,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m); spi_message_init(m);
x++; x++;
ts->read_z2 = READ_Z2(vref); packet->read_z2 = READ_Z2(vref);
x->tx_buf = &ts->read_z2; x->tx_buf = &packet->read_z2;
x->len = 1; x->len = 1;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
x++; x++;
x->rx_buf = &ts->tc.z2; x->rx_buf = &packet->tc.z2;
x->len = 2; x->len = 2;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
...@@ -1080,12 +1094,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -1080,12 +1094,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs; x->delay_usecs = pdata->settle_delay_usecs;
x++; x++;
x->tx_buf = &ts->read_z2; x->tx_buf = &packet->read_z2;
x->len = 1; x->len = 1;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
x++; x++;
x->rx_buf = &ts->tc.z2; x->rx_buf = &packet->tc.z2;
x->len = 2; x->len = 2;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
} }
...@@ -1099,13 +1113,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -1099,13 +1113,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m); spi_message_init(m);
x++; x++;
ts->pwrdown = PWRDOWN; packet->pwrdown = PWRDOWN;
x->tx_buf = &ts->pwrdown; x->tx_buf = &packet->pwrdown;
x->len = 1; x->len = 1;
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
x++; x++;
x->rx_buf = &ts->dummy; x->rx_buf = &packet->dummy;
x->len = 2; x->len = 2;
CS_CHANGE(*x); CS_CHANGE(*x);
spi_message_add_tail(x, m); spi_message_add_tail(x, m);
...@@ -1158,6 +1172,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) ...@@ -1158,6 +1172,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
ts->filter_cleanup(ts->filter_data); ts->filter_cleanup(ts->filter_data);
err_free_mem: err_free_mem:
input_free_device(input_dev); input_free_device(input_dev);
kfree(packet);
kfree(ts); kfree(ts);
return err; return err;
} }
...@@ -1183,6 +1198,7 @@ static int __devexit ads7846_remove(struct spi_device *spi) ...@@ -1183,6 +1198,7 @@ static int __devexit ads7846_remove(struct spi_device *spi)
if (ts->filter_cleanup) if (ts->filter_cleanup)
ts->filter_cleanup(ts->filter_data); ts->filter_cleanup(ts->filter_data);
kfree(ts->packet);
kfree(ts); kfree(ts);
dev_dbg(&spi->dev, "unregistered touchscreen\n"); dev_dbg(&spi->dev, "unregistered touchscreen\n");
......
...@@ -91,6 +91,9 @@ struct atmel_tsadcc { ...@@ -91,6 +91,9 @@ struct atmel_tsadcc {
char phys[32]; char phys[32];
struct clk *clk; struct clk *clk;
int irq; int irq;
unsigned int prev_absx;
unsigned int prev_absy;
unsigned char bufferedmeasure;
}; };
static void __iomem *tsc_base; static void __iomem *tsc_base;
...@@ -100,10 +103,9 @@ static void __iomem *tsc_base; ...@@ -100,10 +103,9 @@ static void __iomem *tsc_base;
static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev) static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
{ {
struct input_dev *input_dev = ((struct atmel_tsadcc *)dev)->input; struct atmel_tsadcc *ts_dev = (struct atmel_tsadcc *)dev;
struct input_dev *input_dev = ts_dev->input;
unsigned int absx;
unsigned int absy;
unsigned int status; unsigned int status;
unsigned int reg; unsigned int reg;
...@@ -121,6 +123,7 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev) ...@@ -121,6 +123,7 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
input_report_key(input_dev, BTN_TOUCH, 0); input_report_key(input_dev, BTN_TOUCH, 0);
ts_dev->bufferedmeasure = 0;
input_sync(input_dev); input_sync(input_dev);
} else if (status & ATMEL_TSADCC_PENCNT) { } else if (status & ATMEL_TSADCC_PENCNT) {
...@@ -138,16 +141,23 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev) ...@@ -138,16 +141,23 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
} else if (status & ATMEL_TSADCC_EOC(3)) { } else if (status & ATMEL_TSADCC_EOC(3)) {
/* Conversion finished */ /* Conversion finished */
absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10; if (ts_dev->bufferedmeasure) {
absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2); /* Last measurement is always discarded, since it can
* be erroneous.
absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10; * Always report previous measurement */
absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0); input_report_abs(input_dev, ABS_X, ts_dev->prev_absx);
input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy);
input_report_abs(input_dev, ABS_X, absx); input_report_key(input_dev, BTN_TOUCH, 1);
input_report_abs(input_dev, ABS_Y, absy); input_sync(input_dev);
input_report_key(input_dev, BTN_TOUCH, 1); } else
input_sync(input_dev); ts_dev->bufferedmeasure = 1;
/* Now make new measurement */
ts_dev->prev_absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
ts_dev->prev_absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
ts_dev->prev_absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
ts_dev->prev_absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -223,6 +233,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev) ...@@ -223,6 +233,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
} }
ts_dev->input = input_dev; ts_dev->input = input_dev;
ts_dev->bufferedmeasure = 0;
snprintf(ts_dev->phys, sizeof(ts_dev->phys), snprintf(ts_dev->phys, sizeof(ts_dev->phys),
"%s/input0", pdev->dev.bus_id); "%s/input0", pdev->dev.bus_id);
......
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
* Wolfson WM97xx AC97 Codecs. * Wolfson WM97xx AC97 Codecs.
* *
* Copyright 2004, 2007 Wolfson Microelectronics PLC. * Copyright 2004, 2007 Wolfson Microelectronics PLC.
* Author: Liam Girdwood * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
* Parts Copyright : Ian Molton <spyro@f2s.com> * Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru> * Andrew Zabolotny <zap@homelink.ru>
* *
...@@ -296,6 +295,6 @@ module_init(mainstone_wm97xx_init); ...@@ -296,6 +295,6 @@ module_init(mainstone_wm97xx_init);
module_exit(mainstone_wm97xx_exit); module_exit(mainstone_wm97xx_exit);
/* Module information */ /* Module information */
MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone"); MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
* wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec. * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec.
* *
* Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
* Author: Liam Girdwood * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
* Parts Copyright : Ian Molton <spyro@f2s.com> * Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru> * Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk> * Russell King <rmk@arm.linux.org.uk>
...@@ -347,6 +346,6 @@ struct wm97xx_codec_drv wm9705_codec = { ...@@ -347,6 +346,6 @@ struct wm97xx_codec_drv wm9705_codec = {
EXPORT_SYMBOL_GPL(wm9705_codec); EXPORT_SYMBOL_GPL(wm9705_codec);
/* Module information */ /* Module information */
MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
MODULE_DESCRIPTION("WM9705 Touch Screen Driver"); MODULE_DESCRIPTION("WM9705 Touch Screen Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
* wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs. * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs.
* *
* Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
* Author: Liam Girdwood * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
* Parts Copyright : Ian Molton <spyro@f2s.com> * Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru> * Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk> * Russell King <rmk@arm.linux.org.uk>
...@@ -462,6 +461,6 @@ struct wm97xx_codec_drv wm9712_codec = { ...@@ -462,6 +461,6 @@ struct wm97xx_codec_drv wm9712_codec = {
EXPORT_SYMBOL_GPL(wm9712_codec); EXPORT_SYMBOL_GPL(wm9712_codec);
/* Module information */ /* Module information */
MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
MODULE_DESCRIPTION("WM9712 Touch Screen Driver"); MODULE_DESCRIPTION("WM9712 Touch Screen Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
* wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec. * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec.
* *
* Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
* Author: Liam Girdwood * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
* Parts Copyright : Ian Molton <spyro@f2s.com> * Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru> * Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk> * Russell King <rmk@arm.linux.org.uk>
...@@ -476,6 +475,6 @@ struct wm97xx_codec_drv wm9713_codec = { ...@@ -476,6 +475,6 @@ struct wm97xx_codec_drv wm9713_codec = {
EXPORT_SYMBOL_GPL(wm9713_codec); EXPORT_SYMBOL_GPL(wm9713_codec);
/* Module information */ /* Module information */
MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
MODULE_DESCRIPTION("WM9713 Touch Screen Driver"); MODULE_DESCRIPTION("WM9713 Touch Screen Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
* and WM9713 AC97 Codecs. * and WM9713 AC97 Codecs.
* *
* Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
* Author: Liam Girdwood * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
* Parts Copyright : Ian Molton <spyro@f2s.com> * Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru> * Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk> * Russell King <rmk@arm.linux.org.uk>
...@@ -824,6 +823,6 @@ module_init(wm97xx_init); ...@@ -824,6 +823,6 @@ module_init(wm97xx_init);
module_exit(wm97xx_exit); module_exit(wm97xx_exit);
/* Module information */ /* Module information */
MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>"); MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver"); MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -107,6 +107,7 @@ header-y += keyctl.h ...@@ -107,6 +107,7 @@ header-y += keyctl.h
header-y += limits.h header-y += limits.h
header-y += magic.h header-y += magic.h
header-y += major.h header-y += major.h
header-y += map_to_7segment.h
header-y += matroxfb.h header-y += matroxfb.h
header-y += meye.h header-y += meye.h
header-y += minix_fs.h header-y += minix_fs.h
......
...@@ -146,10 +146,11 @@ static inline void gameport_unpin_driver(struct gameport *gameport) ...@@ -146,10 +146,11 @@ static inline void gameport_unpin_driver(struct gameport *gameport)
mutex_unlock(&gameport->drv_mutex); mutex_unlock(&gameport->drv_mutex);
} }
void __gameport_register_driver(struct gameport_driver *drv, struct module *owner); int __gameport_register_driver(struct gameport_driver *drv,
static inline void gameport_register_driver(struct gameport_driver *drv) struct module *owner, const char *mod_name);
static inline int __must_check gameport_register_driver(struct gameport_driver *drv)
{ {
__gameport_register_driver(drv, THIS_MODULE); return __gameport_register_driver(drv, THIS_MODULE, KBUILD_MODNAME);
} }
void gameport_unregister_driver(struct gameport_driver *drv); void gameport_unregister_driver(struct gameport_driver *drv);
......
...@@ -577,9 +577,22 @@ struct input_absinfo { ...@@ -577,9 +577,22 @@ struct input_absinfo {
#define KEY_BRL_DOT9 0x1f9 #define KEY_BRL_DOT9 0x1f9
#define KEY_BRL_DOT10 0x1fa #define KEY_BRL_DOT10 0x1fa
#define KEY_NUMERIC_0 0x200 /* used by phones, remote controls, */
#define KEY_NUMERIC_1 0x201 /* and other keypads */
#define KEY_NUMERIC_2 0x202
#define KEY_NUMERIC_3 0x203
#define KEY_NUMERIC_4 0x204
#define KEY_NUMERIC_5 0x205
#define KEY_NUMERIC_6 0x206
#define KEY_NUMERIC_7 0x207
#define KEY_NUMERIC_8 0x208
#define KEY_NUMERIC_9 0x209
#define KEY_NUMERIC_STAR 0x20a
#define KEY_NUMERIC_POUND 0x20b
/* We avoid low common keys in module aliases so they don't get huge. */ /* We avoid low common keys in module aliases so they don't get huge. */
#define KEY_MIN_INTERESTING KEY_MUTE #define KEY_MIN_INTERESTING KEY_MUTE
#define KEY_MAX 0x1ff #define KEY_MAX 0x2ff
#define KEY_CNT (KEY_MAX+1) #define KEY_CNT (KEY_MAX+1)
/* /*
......
/* /*
* drivers/usb/input/map_to_7segment.h
*
* Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com> * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -36,7 +34,7 @@ ...@@ -36,7 +34,7 @@
* Usage: * Usage:
* *
* Register a map variable, and fill it with a character set: * Register a map variable, and fill it with a character set:
* static SEG7_DEFAULT_MAP(map_seg7); * static SEG7_DEFAULT_MAP(map_seg7);
* *
* *
* Then use for conversion: * Then use for conversion:
......
...@@ -284,7 +284,7 @@ struct pcmcia_device_id { ...@@ -284,7 +284,7 @@ struct pcmcia_device_id {
/* Input */ /* Input */
#define INPUT_DEVICE_ID_EV_MAX 0x1f #define INPUT_DEVICE_ID_EV_MAX 0x1f
#define INPUT_DEVICE_ID_KEY_MIN_INTERESTING 0x71 #define INPUT_DEVICE_ID_KEY_MIN_INTERESTING 0x71
#define INPUT_DEVICE_ID_KEY_MAX 0x1ff #define INPUT_DEVICE_ID_KEY_MAX 0x2ff
#define INPUT_DEVICE_ID_REL_MAX 0x0f #define INPUT_DEVICE_ID_REL_MAX 0x0f
#define INPUT_DEVICE_ID_ABS_MAX 0x3f #define INPUT_DEVICE_ID_ABS_MAX 0x3f
#define INPUT_DEVICE_ID_MSC_MAX 0x07 #define INPUT_DEVICE_ID_MSC_MAX 0x07
......
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