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
Defaults to the default architecture's huge page size
if not specified.
i8042.debug [HW] Toggle i8042 debug mode
i8042.direct [HW] Put keyboard port into non-translated mode
i8042.dumbkbd [HW] Pretend that controller can only read data from
keyboard and cannot control its state
......
......@@ -4618,7 +4618,7 @@ WM97XX TOUCHSCREEN DRIVERS
P: Mark Brown
M: broonie@opensource.wolfsonmicro.com
P: Liam Girdwood
M: liam.girdwood@wolfsonmicro.com
M: lrg@slimlogic.co.uk
L: linux-input@vger.kernel.org
T: git git://opensource.wolfsonmicro.com/linux-2.6-touch
W: http://opensource.wolfsonmicro.com/node/7
......
......@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
return;
}
if (keycode > NR_KEYS)
if (keycode >= NR_KEYS)
if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
else
......
......@@ -231,6 +231,7 @@ static void gameport_find_driver(struct gameport *gameport)
enum gameport_event_type {
GAMEPORT_REGISTER_PORT,
GAMEPORT_REGISTER_DRIVER,
GAMEPORT_ATTACH_DRIVER,
};
struct gameport_event {
......@@ -245,11 +246,12 @@ static LIST_HEAD(gameport_event_list);
static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
static struct task_struct *gameport_task;
static void gameport_queue_event(void *object, struct module *owner,
enum gameport_event_type event_type)
static int gameport_queue_event(void *object, struct module *owner,
enum gameport_event_type event_type)
{
unsigned long flags;
struct gameport_event *event;
int retval = 0;
spin_lock_irqsave(&gameport_event_lock, flags);
......@@ -268,24 +270,34 @@ static void gameport_queue_event(void *object, struct module *owner,
}
}
if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) {
if (!try_module_get(owner)) {
printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type);
kfree(event);
goto out;
}
event->type = event_type;
event->object = object;
event->owner = owner;
event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
if (!event) {
printk(KERN_ERR
"gameport: Not enough memory to queue event %d\n",
event_type);
retval = -ENOMEM;
goto out;
}
list_add_tail(&event->node, &gameport_event_list);
wake_up(&gameport_wait);
} else {
printk(KERN_ERR "gameport: Not enough memory to queue event %d\n", event_type);
if (!try_module_get(owner)) {
printk(KERN_WARNING
"gameport: Can't get module reference, dropping event %d\n",
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:
spin_unlock_irqrestore(&gameport_event_lock, flags);
return retval;
}
static void gameport_free_event(struct gameport_event *event)
......@@ -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 gameport_event *event;
......@@ -390,7 +403,7 @@ static void gameport_remove_pending_events(struct gameport *gameport)
list_for_each_safe(node, next, &gameport_event_list) {
event = list_entry(node, struct gameport_event, node);
if (event->object == gameport) {
if (event->object == object) {
list_del_init(node);
gameport_free_event(event);
}
......@@ -705,10 +718,40 @@ static void gameport_add_driver(struct gameport_driver *drv)
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;
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)
......@@ -716,7 +759,9 @@ void gameport_unregister_driver(struct gameport_driver *drv)
struct gameport *gameport;
mutex_lock(&gameport_mutex);
drv->ignore = 1; /* so gameport_find_driver ignores it */
gameport_remove_pending_events(drv);
start_over:
list_for_each_entry(gameport, &gameport_list, node) {
......@@ -729,6 +774,7 @@ void gameport_unregister_driver(struct gameport_driver *drv)
}
driver_unregister(&drv->driver);
mutex_unlock(&gameport_mutex);
}
......
......@@ -414,8 +414,7 @@ static struct gameport_driver a3d_drv = {
static int __init a3d_init(void)
{
gameport_register_driver(&a3d_drv);
return 0;
return gameport_register_driver(&a3d_drv);
}
static void __exit a3d_exit(void)
......
......@@ -572,8 +572,7 @@ static struct gameport_driver adi_drv = {
static int __init adi_init(void)
{
gameport_register_driver(&adi_drv);
return 0;
return gameport_register_driver(&adi_drv);
}
static void __exit adi_exit(void)
......
......@@ -761,9 +761,7 @@ static struct gameport_driver analog_drv = {
static int __init analog_init(void)
{
analog_parse_options();
gameport_register_driver(&analog_drv);
return 0;
return gameport_register_driver(&analog_drv);
}
static void __exit analog_exit(void)
......
......@@ -263,8 +263,7 @@ static struct gameport_driver cobra_drv = {
static int __init cobra_init(void)
{
gameport_register_driver(&cobra_drv);
return 0;
return gameport_register_driver(&cobra_drv);
}
static void __exit cobra_exit(void)
......
......@@ -375,8 +375,7 @@ static struct gameport_driver gf2k_drv = {
static int __init gf2k_init(void)
{
gameport_register_driver(&gf2k_drv);
return 0;
return gameport_register_driver(&gf2k_drv);
}
static void __exit gf2k_exit(void)
......
......@@ -426,8 +426,7 @@ static struct gameport_driver grip_drv = {
static int __init grip_init(void)
{
gameport_register_driver(&grip_drv);
return 0;
return gameport_register_driver(&grip_drv);
}
static void __exit grip_exit(void)
......
......@@ -689,8 +689,7 @@ static struct gameport_driver grip_drv = {
static int __init grip_init(void)
{
gameport_register_driver(&grip_drv);
return 0;
return gameport_register_driver(&grip_drv);
}
static void __exit grip_exit(void)
......
......@@ -283,8 +283,7 @@ static struct gameport_driver guillemot_drv = {
static int __init guillemot_init(void)
{
gameport_register_driver(&guillemot_drv);
return 0;
return gameport_register_driver(&guillemot_drv);
}
static void __exit guillemot_exit(void)
......
......@@ -317,8 +317,7 @@ static struct gameport_driver interact_drv = {
static int __init interact_init(void)
{
gameport_register_driver(&interact_drv);
return 0;
return gameport_register_driver(&interact_drv);
}
static void __exit interact_exit(void)
......
......@@ -161,8 +161,7 @@ static struct gameport_driver joydump_drv = {
static int __init joydump_init(void)
{
gameport_register_driver(&joydump_drv);
return 0;
return gameport_register_driver(&joydump_drv);
}
static void __exit joydump_exit(void)
......
......@@ -818,8 +818,7 @@ static struct gameport_driver sw_drv = {
static int __init sw_init(void)
{
gameport_register_driver(&sw_drv);
return 0;
return gameport_register_driver(&sw_drv);
}
static void __exit sw_exit(void)
......
......@@ -438,8 +438,7 @@ static struct gameport_driver tmdc_drv = {
static int __init tmdc_init(void)
{
gameport_register_driver(&tmdc_drv);
return 0;
return gameport_register_driver(&tmdc_drv);
}
static void __exit tmdc_exit(void)
......
......@@ -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.
*/
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[] = {
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
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
int err;
unsigned char old_extra, old_set;
if (!atkbd->write)
return -EIO;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->extra != value) {
......@@ -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;
unsigned long value;
char *rest;
int err;
unsigned char old_scroll;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->scroll != value) {
......@@ -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;
unsigned long value;
char *rest;
int err;
unsigned char old_set, old_extra;
if (!atkbd->write)
return -EIO;
value = simple_strtoul(buf, &rest, 10);
if (*rest || (value != 2 && value != 3))
if (strict_strtoul(buf, 10, &value) || (value != 2 && value != 3))
return -EINVAL;
if (atkbd->set != value) {
......@@ -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;
unsigned long value;
char *rest;
int err;
unsigned char old_softrepeat, old_softraw;
if (!atkbd->write)
return -EIO;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->softrepeat != value) {
......@@ -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;
unsigned long value;
char *rest;
int err;
unsigned char old_softraw;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->softraw != value) {
......@@ -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 = {
{
.ident = "Dell Latitude series",
.ident = "Dell Laptop",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
},
.callback = atkbd_setup_fixup,
.driver_data = atkbd_latitude_keymap_fixup,
.driver_data = atkbd_dell_laptop_keymap_fixup,
},
{
.ident = "HP 2133",
......
......@@ -8,7 +8,7 @@
*
*
* Modified:
* Copyright 2007 Analog Devices Inc.
* Copyright 2007-2008 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
......@@ -81,6 +81,9 @@ struct bf54x_kpad {
unsigned short *keycode;
struct timer_list timer;
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,
......@@ -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);
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))
enable_irq_wake(bf54x_kpad->irq);
......@@ -370,6 +377,10 @@ static int bfin_kpad_resume(struct platform_device *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))
disable_irq_wake(bf54x_kpad->irq);
......
......@@ -36,9 +36,10 @@ struct gpio_keys_drvdata {
struct gpio_button_data data[0];
};
static void gpio_keys_report_event(struct gpio_keys_button *button,
struct input_dev *input)
static void gpio_keys_report_event(struct gpio_button_data *bdata)
{
struct gpio_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned int type = button->type ?: EV_KEY;
int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
......@@ -50,34 +51,23 @@ static void gpio_check_button(unsigned long _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)
{
struct platform_device *pdev = dev_id;
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
int i;
struct gpio_button_data *bdata = dev_id;
struct gpio_keys_button *button = bdata->button;
for (i = 0; i < pdata->nbuttons; i++) {
struct gpio_keys_button *button = &pdata->buttons[i];
BUG_ON(irq != gpio_to_irq(button->gpio));
if (irq == gpio_to_irq(button->gpio)) {
struct gpio_button_data *bdata = &ddata->data[i];
if (button->debounce_interval)
mod_timer(&bdata->timer,
jiffies +
msecs_to_jiffies(button->debounce_interval));
else
gpio_keys_report_event(button, bdata->input);
return IRQ_HANDLED;
}
}
if (button->debounce_interval)
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(button->debounce_interval));
else
gpio_keys_report_event(bdata);
return IRQ_NONE;
return IRQ_HANDLED;
}
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_TRIGGER_FALLING,
button->desc ? button->desc : "gpio_keys",
pdev);
bdata);
if (error) {
pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
irq, error);
......@@ -178,7 +168,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
fail2:
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)
del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio);
......@@ -203,7 +193,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
for (i = 0; i < pdata->nbuttons; i++) {
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)
del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio);
......
......@@ -180,6 +180,19 @@ config INPUT_YEALINK
To compile this driver as a module, choose M here: the module will be
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
tristate "User level driver support"
help
......
......@@ -16,6 +16,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
obj-$(CONFIG_INPUT_CM109) += cm109.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.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 = {
{ 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 = {
{ KE_KEY, 0x11, {KEY_PROG1} },
{ KE_KEY, 0x12, {KEY_PROG2} },
......@@ -616,6 +626,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
},
.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,
.ident = "Fujitsu-Siemens Amilo M7400",
......
......@@ -52,8 +52,8 @@
#include <linux/module.h>
#include <linux/rwsem.h>
#include <linux/usb/input.h>
#include <linux/map_to_7segment.h>
#include "map_to_7segment.h"
#include "yealink.h"
#define DRIVER_VERSION "yld-20051230"
......
......@@ -96,6 +96,16 @@ config MOUSE_PS2_TOUCHKIT
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
tristate "Serial mouse"
select SERIO
......
......@@ -21,6 +21,7 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
psmouse-objs := psmouse-base.o synaptics.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_LIFEBOOK) += lifebook.o
psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
......
......@@ -54,6 +54,7 @@ static const struct alps_model_info alps_model_data[] = {
{ { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
{ { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
{ { 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 */
};
......
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,
static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
ps2pp_set_smartscroll(psmouse, value);
......
......@@ -25,6 +25,7 @@
#include "synaptics.h"
#include "logips2pp.h"
#include "alps.h"
#include "hgpk.h"
#include "lifebook.h"
#include "trackpoint.h"
#include "touchkit_ps2.h"
......@@ -201,6 +202,12 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
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.
*/
......@@ -220,7 +227,7 @@ static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_sta
* 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);
__psmouse_set_state(psmouse, new_state);
......@@ -305,7 +312,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
psmouse->name, psmouse->phys, psmouse->pktcnt);
psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
queue_work(kpsmoused_wq, &psmouse->resync_work);
psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
goto out;
}
......@@ -342,7 +349,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {
psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
queue_work(kpsmoused_wq, &psmouse->resync_work);
psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
goto out;
}
......@@ -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)
return PSMOUSE_GENPS;
......@@ -761,6 +780,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.alias = "touchkit",
.detect = touchkit_ps2_detect,
},
#endif
#ifdef CONFIG_MOUSE_PS2_OLPC
{
.type = PSMOUSE_HGPK,
.name = "OLPC HGPK",
.alias = "hgpk",
.detect = hgpk_detect,
},
#endif
{
.type = PSMOUSE_CORTRON,
......@@ -935,7 +962,7 @@ static int psmouse_poll(struct psmouse *psmouse)
static void psmouse_resync(struct work_struct *work)
{
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;
psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
int failed = 0, enabled = 0;
......@@ -1194,7 +1221,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
goto err_free;
ps2_init(&psmouse->ps2dev, serio);
INIT_WORK(&psmouse->resync_work, psmouse_resync);
INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync);
psmouse->dev = input_dev;
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
psmouse = serio_get_drvdata(serio);
if (psmouse->state == PSMOUSE_IGNORE) {
retval = -ENODEV;
goto out_unlock;
}
if (attr->protect) {
if (psmouse->state == PSMOUSE_IGNORE) {
retval = -ENODEV;
goto out_unlock;
}
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
parent = serio_get_drvdata(serio->parent);
psmouse_deactivate(parent);
}
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
parent = serio_get_drvdata(serio->parent);
psmouse_deactivate(parent);
}
psmouse_deactivate(psmouse);
psmouse_deactivate(psmouse);
}
retval = attr->set(psmouse, attr->data, buf, count);
if (retval != -ENODEV)
psmouse_activate(psmouse);
if (attr->protect) {
if (retval != -ENODEV)
psmouse_activate(psmouse);
if (parent)
psmouse_activate(parent);
if (parent)
psmouse_activate(parent);
}
out_unlock:
mutex_unlock(&psmouse_mutex);
......@@ -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 long value;
char *rest;
value = simple_strtoul(buf, &rest, 10);
if (*rest)
if (strict_strtoul(buf, 10, &value))
return -EINVAL;
if ((unsigned int)value != value)
......@@ -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)
{
unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10);
if (*rest)
if (strict_strtoul(buf, 10, &value))
return -EINVAL;
psmouse->set_rate(psmouse, value);
......@@ -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)
{
unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10);
if (*rest)
if (strict_strtoul(buf, 10, &value))
return -EINVAL;
psmouse->set_resolution(psmouse, value);
......
......@@ -39,7 +39,7 @@ struct psmouse {
void *private;
struct input_dev *dev;
struct ps2dev ps2dev;
struct work_struct resync_work;
struct delayed_work resync_work;
char *vendor;
char *name;
unsigned char packet[8];
......@@ -89,20 +89,24 @@ enum psmouse_type {
PSMOUSE_TRACKPOINT,
PSMOUSE_TOUCHKIT_PS2,
PSMOUSE_CORTRON,
PSMOUSE_HGPK,
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_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);
struct psmouse_attribute {
struct device_attribute dattr;
void *data;
ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
ssize_t (*set)(struct psmouse *psmouse, void *data,
const char *buf, size_t count);
int protect;
};
#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
ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
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 _set(struct psmouse *, void *data, const char *, size_t); \
static struct psmouse_attribute psmouse_attr_##_name = { \
......@@ -126,6 +130,10 @@ static struct psmouse_attribute psmouse_attr_##_name = { \
.data = _data, \
.show = _show, \
.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 */
......@@ -89,10 +89,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
struct trackpoint_attr_data *attr = data;
unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 255)
if (strict_strtoul(buf, 10, &value) || value > 255)
return -EINVAL;
*field = value;
......@@ -117,10 +115,8 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
struct trackpoint_attr_data *attr = data;
unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (attr->inverted)
......
......@@ -322,6 +322,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
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[] = {
.id = SERIO_ANY,
.extra = SERIO_ANY,
},
{
.type = SERIO_8042_XL,
.proto = SERIO_ANY,
.id = SERIO_ANY,
.extra = SERIO_ANY,
},
{ 0 }
};
......
......@@ -1202,16 +1202,22 @@ static ssize_t
store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
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;
} else {
x = (int)simple_strtol(buf, NULL, 10);
if (x >= AIPTEK_TILT_MIN && x <= AIPTEK_TILT_MAX) {
aiptek->newSetting.xTilt = x;
}
if (x < AIPTEK_TILT_MIN || x > AIPTEK_TILT_MAX)
return -EINVAL;
aiptek->newSetting.xTilt = x;
}
return count;
}
......@@ -1238,16 +1244,22 @@ static ssize_t
store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
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;
} else {
y = (int)simple_strtol(buf, NULL, 10);
if (y >= AIPTEK_TILT_MIN && y <= AIPTEK_TILT_MAX) {
aiptek->newSetting.yTilt = y;
}
if (y < AIPTEK_TILT_MIN || y > AIPTEK_TILT_MAX)
return -EINVAL;
aiptek->newSetting.yTilt = y;
}
return count;
}
......@@ -1269,8 +1281,12 @@ static ssize_t
store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
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;
}
......@@ -1294,8 +1310,12 @@ static ssize_t
store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
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;
}
......@@ -1541,8 +1561,11 @@ static ssize_t
store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
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;
}
......
......@@ -69,6 +69,17 @@ struct ts_event {
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 input_dev *input;
char phys[32];
......@@ -86,9 +97,7 @@ struct ads7846 {
u16 x_plate_ohms;
u16 pressure_max;
u8 read_x, read_y, read_z1, read_z2, pwrdown;
u16 dummy; /* for the pwrdown read */
struct ts_event tc;
struct ads7846_packet *packet;
struct spi_transfer xfer[18];
struct spi_message msg[5];
......@@ -463,10 +472,11 @@ static ssize_t ads7846_disable_store(struct device *dev,
const char *buf, size_t count)
{
struct ads7846 *ts = dev_get_drvdata(dev);
char *endp;
int i;
long i;
if (strict_strtoul(buf, 10, &i))
return -EINVAL;
i = simple_strtoul(buf, &endp, 10);
spin_lock_irq(&ts->lock);
if (i)
......@@ -512,16 +522,17 @@ static int get_pendown_state(struct ads7846 *ts)
static void ads7846_rx(void *ads)
{
struct ads7846 *ts = ads;
struct ads7846_packet *packet = ts->packet;
unsigned Rt;
u16 x, y, z1, z2;
/* ads7846_rx_val() did in-place conversion (including byteswap) from
* on-the-wire format as part of debouncing to get stable readings.
*/
x = ts->tc.x;
y = ts->tc.y;
z1 = ts->tc.z1;
z2 = ts->tc.z2;
x = packet->tc.x;
y = packet->tc.y;
z1 = packet->tc.z1;
z2 = packet->tc.z2;
/* range filtering */
if (x == MAX_12BIT)
......@@ -545,10 +556,10 @@ static void ads7846_rx(void *ads)
* the maximum. Don't report it to user space, repeat at least
* once more the measurement
*/
if (ts->tc.ignore || Rt > ts->pressure_max) {
if (packet->tc.ignore || Rt > ts->pressure_max) {
#ifdef VERBOSE
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
hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
HRTIMER_MODE_REL);
......@@ -641,6 +652,7 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val)
static void ads7846_rx_val(void *ads)
{
struct ads7846 *ts = ads;
struct ads7846_packet *packet = ts->packet;
struct spi_message *m;
struct spi_transfer *t;
int val;
......@@ -660,7 +672,7 @@ static void ads7846_rx_val(void *ads)
case ADS7846_FILTER_REPEAT:
break;
case ADS7846_FILTER_IGNORE:
ts->tc.ignore = 1;
packet->tc.ignore = 1;
/* Last message will contain ads7846_rx() as the
* completion function.
*/
......@@ -668,7 +680,7 @@ static void ads7846_rx_val(void *ads)
break;
case ADS7846_FILTER_OK:
*(u16 *)t->rx_buf = val;
ts->tc.ignore = 0;
packet->tc.ignore = 0;
m = &ts->msg[++ts->msg_idx];
break;
default:
......@@ -773,7 +785,6 @@ static void ads7846_disable(struct ads7846 *ts)
/* we know the chip's in lowpower mode since we always
* leave it that way after every request
*/
}
/* Must be called with ts->lock held */
......@@ -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)
{
struct ads7846 *ts;
struct ads7846_packet *packet;
struct input_dev *input_dev;
struct ads7846_platform_data *pdata = spi->dev.platform_data;
struct spi_message *m;
......@@ -884,14 +896,16 @@ static int __devinit ads7846_probe(struct spi_device *spi)
return err;
ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL);
input_dev = input_allocate_device();
if (!ts || !input_dev) {
if (!ts || !packet || !input_dev) {
err = -ENOMEM;
goto err_free_mem;
}
dev_set_drvdata(&spi->dev, ts);
ts->packet = packet;
ts->spi = spi;
ts->input = input_dev;
ts->vref_mv = pdata->vref_mv;
......@@ -963,13 +977,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m);
/* y- still on; turn on only y+ (and ADC) */
ts->read_y = READ_Y(vref);
x->tx_buf = &ts->read_y;
packet->read_y = READ_Y(vref);
x->tx_buf = &packet->read_y;
x->len = 1;
spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->tc.y;
x->rx_buf = &packet->tc.y;
x->len = 2;
spi_message_add_tail(x, m);
......@@ -981,12 +995,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs;
x++;
x->tx_buf = &ts->read_y;
x->tx_buf = &packet->read_y;
x->len = 1;
spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->tc.y;
x->rx_buf = &packet->tc.y;
x->len = 2;
spi_message_add_tail(x, m);
}
......@@ -999,13 +1013,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
/* turn y- off, x+ on, then leave in lowpower */
x++;
ts->read_x = READ_X(vref);
x->tx_buf = &ts->read_x;
packet->read_x = READ_X(vref);
x->tx_buf = &packet->read_x;
x->len = 1;
spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->tc.x;
x->rx_buf = &packet->tc.x;
x->len = 2;
spi_message_add_tail(x, m);
......@@ -1014,12 +1028,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs;
x++;
x->tx_buf = &ts->read_x;
x->tx_buf = &packet->read_x;
x->len = 1;
spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->tc.x;
x->rx_buf = &packet->tc.x;
x->len = 2;
spi_message_add_tail(x, m);
}
......@@ -1033,13 +1047,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m);
x++;
ts->read_z1 = READ_Z1(vref);
x->tx_buf = &ts->read_z1;
packet->read_z1 = READ_Z1(vref);
x->tx_buf = &packet->read_z1;
x->len = 1;
spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->tc.z1;
x->rx_buf = &packet->tc.z1;
x->len = 2;
spi_message_add_tail(x, m);
......@@ -1048,12 +1062,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs;
x++;
x->tx_buf = &ts->read_z1;
x->tx_buf = &packet->read_z1;
x->len = 1;
spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->tc.z1;
x->rx_buf = &packet->tc.z1;
x->len = 2;
spi_message_add_tail(x, m);
}
......@@ -1065,13 +1079,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m);
x++;
ts->read_z2 = READ_Z2(vref);
x->tx_buf = &ts->read_z2;
packet->read_z2 = READ_Z2(vref);
x->tx_buf = &packet->read_z2;
x->len = 1;
spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->tc.z2;
x->rx_buf = &packet->tc.z2;
x->len = 2;
spi_message_add_tail(x, m);
......@@ -1080,12 +1094,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs;
x++;
x->tx_buf = &ts->read_z2;
x->tx_buf = &packet->read_z2;
x->len = 1;
spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->tc.z2;
x->rx_buf = &packet->tc.z2;
x->len = 2;
spi_message_add_tail(x, m);
}
......@@ -1099,13 +1113,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m);
x++;
ts->pwrdown = PWRDOWN;
x->tx_buf = &ts->pwrdown;
packet->pwrdown = PWRDOWN;
x->tx_buf = &packet->pwrdown;
x->len = 1;
spi_message_add_tail(x, m);
x++;
x->rx_buf = &ts->dummy;
x->rx_buf = &packet->dummy;
x->len = 2;
CS_CHANGE(*x);
spi_message_add_tail(x, m);
......@@ -1158,6 +1172,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
ts->filter_cleanup(ts->filter_data);
err_free_mem:
input_free_device(input_dev);
kfree(packet);
kfree(ts);
return err;
}
......@@ -1183,6 +1198,7 @@ static int __devexit ads7846_remove(struct spi_device *spi)
if (ts->filter_cleanup)
ts->filter_cleanup(ts->filter_data);
kfree(ts->packet);
kfree(ts);
dev_dbg(&spi->dev, "unregistered touchscreen\n");
......
......@@ -91,6 +91,9 @@ struct atmel_tsadcc {
char phys[32];
struct clk *clk;
int irq;
unsigned int prev_absx;
unsigned int prev_absy;
unsigned char bufferedmeasure;
};
static void __iomem *tsc_base;
......@@ -100,10 +103,9 @@ static void __iomem *tsc_base;
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 reg;
......@@ -121,6 +123,7 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
input_report_key(input_dev, BTN_TOUCH, 0);
ts_dev->bufferedmeasure = 0;
input_sync(input_dev);
} else if (status & ATMEL_TSADCC_PENCNT) {
......@@ -138,16 +141,23 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
} else if (status & ATMEL_TSADCC_EOC(3)) {
/* Conversion finished */
absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
input_report_abs(input_dev, ABS_X, absx);
input_report_abs(input_dev, ABS_Y, absy);
input_report_key(input_dev, BTN_TOUCH, 1);
input_sync(input_dev);
if (ts_dev->bufferedmeasure) {
/* Last measurement is always discarded, since it can
* be erroneous.
* Always report previous measurement */
input_report_abs(input_dev, ABS_X, ts_dev->prev_absx);
input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy);
input_report_key(input_dev, BTN_TOUCH, 1);
input_sync(input_dev);
} else
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;
......@@ -223,6 +233,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
}
ts_dev->input = input_dev;
ts_dev->bufferedmeasure = 0;
snprintf(ts_dev->phys, sizeof(ts_dev->phys),
"%s/input0", pdev->dev.bus_id);
......
......@@ -3,8 +3,7 @@
* Wolfson WM97xx AC97 Codecs.
*
* Copyright 2004, 2007 Wolfson Microelectronics PLC.
* Author: Liam Girdwood
* liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
* Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru>
*
......@@ -296,6 +295,6 @@ module_init(mainstone_wm97xx_init);
module_exit(mainstone_wm97xx_exit);
/* 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_LICENSE("GPL");
......@@ -2,8 +2,7 @@
* wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec.
*
* Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
* Author: Liam Girdwood
* liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
* Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk>
......@@ -347,6 +346,6 @@ struct wm97xx_codec_drv wm9705_codec = {
EXPORT_SYMBOL_GPL(wm9705_codec);
/* 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_LICENSE("GPL");
......@@ -2,8 +2,7 @@
* wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs.
*
* Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
* Author: Liam Girdwood
* liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
* Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk>
......@@ -462,6 +461,6 @@ struct wm97xx_codec_drv wm9712_codec = {
EXPORT_SYMBOL_GPL(wm9712_codec);
/* 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_LICENSE("GPL");
......@@ -2,8 +2,7 @@
* wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec.
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
* Author: Liam Girdwood
* liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
* Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk>
......@@ -476,6 +475,6 @@ struct wm97xx_codec_drv wm9713_codec = {
EXPORT_SYMBOL_GPL(wm9713_codec);
/* 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_LICENSE("GPL");
......@@ -3,8 +3,7 @@
* and WM9713 AC97 Codecs.
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
* Author: Liam Girdwood
* liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
* Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk>
......@@ -824,6 +823,6 @@ module_init(wm97xx_init);
module_exit(wm97xx_exit);
/* 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_LICENSE("GPL");
......@@ -107,6 +107,7 @@ header-y += keyctl.h
header-y += limits.h
header-y += magic.h
header-y += major.h
header-y += map_to_7segment.h
header-y += matroxfb.h
header-y += meye.h
header-y += minix_fs.h
......
......@@ -146,10 +146,11 @@ static inline void gameport_unpin_driver(struct gameport *gameport)
mutex_unlock(&gameport->drv_mutex);
}
void __gameport_register_driver(struct gameport_driver *drv, struct module *owner);
static inline void gameport_register_driver(struct gameport_driver *drv)
int __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);
......
......@@ -577,9 +577,22 @@ struct input_absinfo {
#define KEY_BRL_DOT9 0x1f9
#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. */
#define KEY_MIN_INTERESTING KEY_MUTE
#define KEY_MAX 0x1ff
#define KEY_MAX 0x2ff
#define KEY_CNT (KEY_MAX+1)
/*
......
/*
* drivers/usb/input/map_to_7segment.h
*
* Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
*
* This program is free software; you can redistribute it and/or
......@@ -36,7 +34,7 @@
* Usage:
*
* 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:
......
......@@ -284,7 +284,7 @@ struct pcmcia_device_id {
/* Input */
#define INPUT_DEVICE_ID_EV_MAX 0x1f
#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_ABS_MAX 0x3f
#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