From 24bf10ab2d72863a14187905fd992ca8119c809e Mon Sep 17 00:00:00 2001 From: Stefan Lucke Date: Sun, 18 Feb 2007 01:49:10 -0500 Subject: Input: psmouse - add support for eGalax PS/2 touchscreen controller Based on the touchkit USB and lifebook PS/2 touchscreen driver. The egalax touchsreen controller (PS/2 or USB version) is used in this 7" device: http://www.cartft.com/catalog/il/449 Signed-off-by: Michal Piotrowski Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 21a1de6..6751179 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -14,4 +14,5 @@ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o -psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o trackpoint.o +psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o \ + trackpoint.o touchkit_ps2.o diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 0fe5869..eb63855 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -28,6 +28,7 @@ #include "alps.h" #include "lifebook.h" #include "trackpoint.h" +#include "touchkit_ps2.h" #define DRIVER_DESC "PS/2 mouse driver" @@ -605,14 +606,20 @@ static int psmouse_extensions(struct psmouse *psmouse, } } - if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse, set_properties) == 0) - return PSMOUSE_GENPS; + if (max_proto > PSMOUSE_IMEX) { + + if (genius_detect(psmouse, set_properties) == 0) + return PSMOUSE_GENPS; + + if (ps2pp_init(psmouse, set_properties) == 0) + return PSMOUSE_PS2PP; - if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0) - return PSMOUSE_PS2PP; + if (trackpoint_detect(psmouse, set_properties) == 0) + return PSMOUSE_TRACKPOINT; - if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0) - return PSMOUSE_TRACKPOINT; + if (touchkit_ps2_detect(psmouse, set_properties) == 0) + return PSMOUSE_TOUCHKIT_PS2; + } /* * Reset to defaults in case the device got confused by extended @@ -713,6 +720,12 @@ static const struct psmouse_protocol psmouse_protocols[] = { .detect = trackpoint_detect, }, { + .type = PSMOUSE_TOUCHKIT_PS2, + .name = "touchkitPS/2", + .alias = "touchkit", + .detect = touchkit_ps2_detect, + }, + { .type = PSMOUSE_AUTO, .name = "auto", .alias = "any", diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index cf1de95..3964e8a 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h @@ -87,6 +87,7 @@ enum psmouse_type { PSMOUSE_ALPS, PSMOUSE_LIFEBOOK, PSMOUSE_TRACKPOINT, + PSMOUSE_TOUCHKIT_PS2, PSMOUSE_AUTO /* This one should always be last */ }; diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c new file mode 100644 index 0000000..7b977fd --- /dev/null +++ b/drivers/input/mouse/touchkit_ps2.c @@ -0,0 +1,100 @@ +/* ---------------------------------------------------------------------------- + * touchkit_ps2.c -- Driver for eGalax TouchKit PS/2 Touchscreens + * + * Copyright (C) 2005 by Stefan Lucke + * Copyright (C) 2004 by Daniel Ritz + * Copyright (C) by Todd E. Johnson (mtouchusb.c) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based upon touchkitusb.c + * + * Vendor documentation is available in support section of: + * http://www.egalax.com.tw/ + */ + +#include +#include + +#include +#include +#include + +#include "psmouse.h" +#include "touchkit_ps2.h" + +#define TOUCHKIT_MAX_XC 0x07ff +#define TOUCHKIT_MAX_YC 0x07ff + +#define TOUCHKIT_CMD 0x0a +#define TOUCHKIT_CMD_LENGTH 1 + +#define TOUCHKIT_CMD_ACTIVE 'A' +#define TOUCHKIT_CMD_FIRMWARE_VERSION 'D' +#define TOUCHKIT_CMD_CONTROLLER_TYPE 'E' + +#define TOUCHKIT_SEND_PARMS(s, r, c) ((s) << 12 | (r) << 8 | (c)) + +#define TOUCHKIT_GET_TOUCHED(packet) (((packet)[0]) & 0x01) +#define TOUCHKIT_GET_X(packet) (((packet)[1] << 7) | (packet)[2]) +#define TOUCHKIT_GET_Y(packet) (((packet)[3] << 7) | (packet)[4]) + +static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse) +{ + unsigned char *packet = psmouse->packet; + struct input_dev *dev = psmouse->dev; + + if (psmouse->pktcnt != 5) + return PSMOUSE_GOOD_DATA; + + input_report_abs(dev, ABS_X, TOUCHKIT_GET_X(packet)); + input_report_abs(dev, ABS_Y, TOUCHKIT_GET_Y(packet)); + input_report_key(dev, BTN_TOUCH, TOUCHKIT_GET_TOUCHED(packet)); + input_sync(dev); + + return PSMOUSE_FULL_PACKET; +} + +int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) +{ + struct input_dev *dev = psmouse->dev; + unsigned char param[3]; + int command; + + param[0] = TOUCHKIT_CMD_LENGTH; + param[1] = TOUCHKIT_CMD_ACTIVE; + command = TOUCHKIT_SEND_PARMS(2, 3, TOUCHKIT_CMD); + + if (ps2_command(&psmouse->ps2dev, param, command)) + return -ENODEV; + + if (param[0] != TOUCHKIT_CMD || param[1] != 0x01 || + param[2] != TOUCHKIT_CMD_ACTIVE) + return -ENODEV; + + if (set_properties) { + dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + set_bit(BTN_TOUCH, dev->keybit); + input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); + input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); + + psmouse->vendor = "eGalax"; + psmouse->name = "Touchscreen"; + psmouse->protocol_handler = touchkit_ps2_process_byte; + psmouse->pktsize = 5; + } + + return 0; +} diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h new file mode 100644 index 0000000..3f03fbc --- /dev/null +++ b/drivers/input/mouse/touchkit_ps2.h @@ -0,0 +1,17 @@ +/* ---------------------------------------------------------------------------- + * touchkit_ps2.h -- Driver for eGalax TouchKit PS/2 Touchscreens + * + * Copyright (C) 2005 by Stefan Lucke + * Copyright (c) 2005 Vojtech Pavlik + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef _TOUCHKIT_PS2_H +#define _TOUCHKIT_PS2_H + +int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties); + +#endif -- cgit v0.10.2 From bebb8a2bc180a4c920c57e89b2d713a34c1d096c Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 18 Feb 2007 01:50:18 -0500 Subject: Input: add driver for MIPS Cobalt back panel buttons Tested on Cobalt Qube2. Signed-off-by: Yoichi Yuasa Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 41b4258..5694115 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -40,6 +40,15 @@ config INPUT_M68K_BEEP tristate "M68k Beeper support" depends on M68K +config INPUT_COBALT_BTNS + tristate "Cobalt button interface" + depends on MIPS_COBALT + help + Say Y here if you want to support MIPS Cobalt button interface. + + To compile this driver as a module, choose M here: the + module will be called cobalt_btns. + config INPUT_WISTRON_BTNS tristate "x86 Wistron laptop button interface" depends on X86 && !X86_64 @@ -82,7 +91,7 @@ config INPUT_UINPUT module will be called uinput. config HP_SDC_RTC - tristate "HP SDC Real Time Clock" + tristate "HP SDC Real Time Clock" depends on GSC || HP300 select HP_SDC help diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index e0a8d58..9f08f27 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o +obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c new file mode 100644 index 0000000..b14f49e --- /dev/null +++ b/drivers/input/misc/cobalt_btns.c @@ -0,0 +1,209 @@ +/* + * Cobalt button interface driver. + * + * Copyright (C) 2007 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include +#include +#include +#include +#include + +#define BUTTONS_POLL_INTERVAL 30 /* msec */ +#define BUTTONS_COUNT_THRESHOLD 3 +#define BUTTONS_STATUS_MASK 0xfe000000 + +struct buttons_dev { + struct input_dev *input; + void __iomem *reg; +}; + +struct buttons_map { + uint32_t mask; + int keycode; + int count; +}; + +static struct buttons_map buttons_map[] = { + { 0x02000000, KEY_RESTART, }, + { 0x04000000, KEY_LEFT, }, + { 0x08000000, KEY_UP, }, + { 0x10000000, KEY_DOWN, }, + { 0x20000000, KEY_RIGHT, }, + { 0x40000000, KEY_ENTER, }, + { 0x80000000, KEY_SELECT, }, +}; + +static struct resource cobalt_buttons_resource __initdata = { + .start = 0x1d000000, + .end = 0x1d000003, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device *cobalt_buttons_device; + +static struct timer_list buttons_timer; + +static void handle_buttons(unsigned long data) +{ + struct buttons_map *button = buttons_map; + struct buttons_dev *bdev; + uint32_t status; + int i; + + bdev = (struct buttons_dev *)data; + status = readl(bdev->reg); + status = ~status & BUTTONS_STATUS_MASK; + + for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { + if (status & button->mask) { + button->count++; + } else { + if (button->count >= BUTTONS_COUNT_THRESHOLD) { + input_report_key(bdev->input, button->keycode, 0); + input_sync(bdev->input); + } + button->count = 0; + } + + if (button->count == BUTTONS_COUNT_THRESHOLD) { + input_report_key(bdev->input, button->keycode, 1); + input_sync(bdev->input); + } + + button++; + } + + mod_timer(&buttons_timer, jiffies + msecs_to_jiffies(BUTTONS_POLL_INTERVAL)); +} + +static int cobalt_buttons_open(struct input_dev *dev) +{ + mod_timer(&buttons_timer, jiffies + msecs_to_jiffies(BUTTONS_POLL_INTERVAL)); + + return 0; +} + +static void cobalt_buttons_close(struct input_dev *dev) +{ + del_timer_sync(&buttons_timer); +} + +static int __devinit cobalt_buttons_probe(struct platform_device *pdev) +{ + struct buttons_dev *bdev; + struct input_dev *input; + struct resource *res; + int error, i; + + bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL); + input = input_allocate_device(); + if (!bdev || !input) { + error = -ENOMEM; + goto err_free_mem; + } + + input->name = "Cobalt buttons"; + input->phys = "cobalt/input0"; + input->id.bustype = BUS_HOST; + input->cdev.dev = &pdev->dev; + input->open = cobalt_buttons_open; + input->close = cobalt_buttons_close; + + input->evbit[0] = BIT(EV_KEY); + for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { + set_bit(buttons_map[i].keycode, input->keybit); + buttons_map[i].count = 0; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + error = -EBUSY; + goto err_free_mem; + } + + bdev->input = input; + bdev->reg = ioremap(res->start, res->end - res->start + 1); + dev_set_drvdata(&pdev->dev, bdev); + + setup_timer(&buttons_timer, handle_buttons, (unsigned long)bdev); + + error = input_register_device(input); + if (error) + goto err_iounmap; + + return 0; + + err_iounmap: + iounmap(bdev->reg); + err_free_mem: + input_free_device(input); + kfree(bdev); + dev_set_drvdata(&pdev->dev, NULL); + return error; +} + +static int __devexit cobalt_buttons_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct buttons_dev *bdev = dev_get_drvdata(dev); + + input_unregister_device(bdev->input); + iounmap(bdev->reg); + kfree(bdev); + dev_set_drvdata(dev, NULL); + + return 0; +} + +static struct platform_driver cobalt_buttons_driver = { + .probe = cobalt_buttons_probe, + .remove = __devexit_p(cobalt_buttons_remove), + .driver = { + .name = "Cobalt buttons", + .owner = THIS_MODULE, + }, +}; + +static int __init cobalt_buttons_init(void) +{ + int retval; + + cobalt_buttons_device = platform_device_register_simple("Cobalt buttons", -1, + &cobalt_buttons_resource, 1); + if (IS_ERR(cobalt_buttons_device)) { + retval = PTR_ERR(cobalt_buttons_device); + return retval; + } + + retval = platform_driver_register(&cobalt_buttons_driver); + if (retval < 0) + platform_device_unregister(cobalt_buttons_device); + + return retval; +} + +static void __exit cobalt_buttons_exit(void) +{ + platform_driver_unregister(&cobalt_buttons_driver); + platform_device_unregister(cobalt_buttons_device); +} + +module_init(cobalt_buttons_init); +module_exit(cobalt_buttons_exit); -- cgit v0.10.2 From 969111e900226a8dbd1f596f34c09eecd20afc7d Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 28 Feb 2007 23:51:03 -0500 Subject: Input: ads7846 - add support for the ads7843 touchscreen The ads7843 support has now become almost trivial since the last rework. Signed-off-by: Nicolas Ferre Acked-by: David Brownell Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 0a26e06..2f5fc80 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -39,7 +39,8 @@ /* * This code has been heavily tested on a Nokia 770, and lightly * tested on other ads7846 devices (OSK/Mistral, Lubbock). - * Support for ads7843 and ads7845 has only been stubbed in. + * Support for ads7843 tested on Atmel at91sam926x-EK. + * Support for ads7845 has only been stubbed in. * * IRQ handling needs a workaround because of a shortcoming in handling * edge triggered IRQs on some platforms like the OMAP1/2. These @@ -246,18 +247,16 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) /* REVISIT: take a few more samples, and compare ... */ - /* maybe off internal vREF */ - if (use_internal) { - req->ref_off = REF_OFF; - req->xfer[4].tx_buf = &req->ref_off; - req->xfer[4].len = 1; - spi_message_add_tail(&req->xfer[4], &req->msg); - - req->xfer[5].rx_buf = &req->scratch; - req->xfer[5].len = 2; - CS_CHANGE(req->xfer[5]); - spi_message_add_tail(&req->xfer[5], &req->msg); - } + /* converter in low power mode & enable PENIRQ */ + req->ref_off = PWRDOWN; + req->xfer[4].tx_buf = &req->ref_off; + req->xfer[4].len = 1; + spi_message_add_tail(&req->xfer[4], &req->msg); + + req->xfer[5].rx_buf = &req->scratch; + req->xfer[5].len = 2; + CS_CHANGE(req->xfer[5]); + spi_message_add_tail(&req->xfer[5], &req->msg); ts->irq_disabled = 1; disable_irq(spi->irq); @@ -536,6 +535,9 @@ static void ads7846_rx(void *ads) } else Rt = 0; + if (ts->model == 7843) + Rt = ts->pressure_max / 2; + /* Sample found inconsistent by debouncing or pressure is beyond * the maximum. Don't report it to user space, repeat at least * once more the measurement -- cgit v0.10.2 From 3acaf540a33199141695f2e2fcfa8829053159bf Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 28 Feb 2007 23:51:19 -0500 Subject: Input: HIL - various fixes for HIL drivers - mark some structures const or __read_mostly - hilkbd.c: fix uninitialized spinlock in HIL keyboard driver - hil_mlc.c: use USEC_PER_SEC instead of 1000000 - hp_sdc: bugfix for request_irq()/free_irq() parameters, this prevented multiple load/unload cycles as module Signed-off-by: Helge Deller Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 7cc9728..7143f37 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -51,7 +51,7 @@ MODULE_LICENSE("Dual BSD/GPL"); #define HIL_KBD_SET1_UPBIT 0x01 #define HIL_KBD_SET1_SHIFT 1 -static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] = +static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly = { HIL_KEYCODES_SET1 }; #define HIL_KBD_SET2_UPBIT 0x01 @@ -60,10 +60,10 @@ static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] = #define HIL_KBD_SET3_UPBIT 0x80 #define HIL_KBD_SET3_SHIFT 0 -static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] = +static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] __read_mostly = { HIL_KEYCODES_SET3 }; -static char hil_language[][16] = { HIL_LOCALE_MAP }; +static const char hil_language[][16] = { HIL_LOCALE_MAP }; struct hil_kbd { struct input_dev *dev; @@ -368,7 +368,7 @@ static struct serio_device_id hil_kbd_ids[] = { { 0 } }; -struct serio_driver hil_kbd_serio_drv = { +static struct serio_driver hil_kbd_serio_drv = { .driver = { .name = "hil_kbd", }, diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index 4de4dc2..230f5db 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c @@ -3,7 +3,7 @@ * * Copyright (C) 1998 Philip Blundell * Copyright (C) 1999 Matthew Wilcox - * Copyright (C) 1999-2006 Helge Deller + * Copyright (C) 1999-2007 Helge Deller * * Very basic HP Human Interface Loop (HIL) driver. * This driver handles the keyboard on HP300 (m68k) and on some @@ -89,7 +89,7 @@ MODULE_LICENSE("GPL v2"); #define HIL_READKBDSADR 0xF9 #define HIL_WRITEKBDSADR 0xE9 -static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = +static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly = { HIL_KEYCODES_SET1 }; /* HIL structure */ @@ -211,6 +211,7 @@ hil_keyb_init(void) return -ENODEV; /* already initialized */ } + spin_lock_init(&hil_dev.lock); hil_dev.dev = input_allocate_device(); if (!hil_dev.dev) return -ENOMEM; diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 4fa93ff..0710704 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -408,7 +408,7 @@ static int hilse_operate(hil_mlc *mlc, int repoll) { #define OUT_LAST(pack) \ { HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 }, -struct hilse_node hil_mlc_se[HILSEN_END] = { +const struct hilse_node hil_mlc_se[HILSEN_END] = { /* 0 HILSEN_START */ FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) @@ -530,7 +530,7 @@ struct hilse_node hil_mlc_se[HILSEN_END] = { /* 60 HILSEN_END */ }; -static inline void hilse_setup_input(hil_mlc *mlc, struct hilse_node *node) { +static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node) { switch (node->act) { case HILSE_EXPECT_DISC: @@ -563,21 +563,19 @@ static inline void hilse_setup_input(hil_mlc *mlc, struct hilse_node *node) { #ifdef HIL_MLC_DEBUG static int doze = 0; static int seidx; /* For debug */ -static int kick = 1; #endif static int hilse_donode (hil_mlc *mlc) { - struct hilse_node *node; + const struct hilse_node *node; int nextidx = 0; int sched_long = 0; unsigned long flags; #ifdef HIL_MLC_DEBUG if (mlc->seidx && (mlc->seidx != seidx) && mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { - printk(KERN_DEBUG PREFIX "z%i \n%s {%i}", doze, kick ? "K" : "", mlc->seidx); + printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx); doze = 0; } - kick = 0; seidx = mlc->seidx; #endif @@ -588,7 +586,7 @@ static int hilse_donode (hil_mlc *mlc) { hil_packet pack; case HILSE_FUNC: - if (node->object.func == NULL) break; + BUG_ON(node->object.func == NULL); rc = node->object.func(mlc, node->arg); nextidx = (rc > 0) ? node->ugly : ((rc < 0) ? node->bad : node->good); @@ -674,10 +672,10 @@ static int hilse_donode (hil_mlc *mlc) { if (!sched_long) goto sched; do_gettimeofday(&tv); - tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec); + tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); tv.tv_usec -= mlc->instart.tv_usec; if (tv.tv_usec >= mlc->intimeout) goto sched; - tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / 1000000; + tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / USEC_PER_SEC; if (!tv.tv_usec) goto sched; mod_timer(&hil_mlcs_kicker, jiffies + tv.tv_usec); break; @@ -837,7 +835,7 @@ static void hil_mlc_serio_close(struct serio *serio) { /* TODO wake up interruptable */ } -static struct serio_device_id hil_mlc_serio_id = { +static const struct serio_device_id hil_mlc_serio_id = { .type = SERIO_HIL_MLC, .proto = SERIO_HIL, .extra = SERIO_ANY, @@ -873,6 +871,8 @@ int hil_mlc_register(hil_mlc *mlc) { hil_mlc_copy_di_scratch(mlc, i); mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); mlc->serio[i] = mlc_serio; + snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); + snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); mlc_serio->id = hil_mlc_serio_id; mlc_serio->write = hil_mlc_serio_write; mlc_serio->open = hil_mlc_serio_open; diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index b57370d..353a8a1 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c @@ -748,7 +748,7 @@ void hp_sdc_kicker (unsigned long data) { #if defined(__hppa__) -static struct parisc_device_id hp_sdc_tbl[] = { +static const struct parisc_device_id hp_sdc_tbl[] = { { .hw_type = HPHW_FIO, .hversion_rev = HVERSION_REV_ANY_ID, @@ -817,12 +817,12 @@ static int __init hp_sdc_init(void) #endif errstr = "IRQ not available for"; - if(request_irq(hp_sdc.irq, &hp_sdc_isr, 0, "HP SDC", - (void *) hp_sdc.base_io)) goto err1; + if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM, + "HP SDC", &hp_sdc)) goto err1; errstr = "NMI not available for"; - if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, 0, "HP SDC NMI", - (void *) hp_sdc.base_io)) goto err2; + if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED, + "HP SDC NMI", &hp_sdc)) goto err2; printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); @@ -854,7 +854,7 @@ static int __init hp_sdc_init(void) hp_sdc.dev_err = 0; return 0; err2: - free_irq(hp_sdc.irq, NULL); + free_irq(hp_sdc.irq, &hp_sdc); err1: release_region(hp_sdc.data_io, 2); err0: @@ -898,8 +898,8 @@ static void hp_sdc_exit(void) /* Wait until we know this has been processed by the i8042 */ hp_sdc_spin_ibf(); - free_irq(hp_sdc.nmi, NULL); - free_irq(hp_sdc.irq, NULL); + free_irq(hp_sdc.nmi, &hp_sdc); + free_irq(hp_sdc.irq, &hp_sdc); write_unlock_irq(&hp_sdc.lock); del_timer(&hp_sdc.kicker); diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index aa4a8a4..1f131ff 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c @@ -323,11 +323,12 @@ static int __init hp_sdc_mlc_init(void) mlc->in = &hp_sdc_mlc_in; mlc->out = &hp_sdc_mlc_out; + mlc->priv = &hp_sdc_mlc_priv; + if (hil_mlc_register(mlc)) { printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); goto err0; } - mlc->priv = &hp_sdc_mlc_priv; if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) { printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n"); -- cgit v0.10.2 From ffd51f46cdf856c0b453d2828a74d552cc15f881 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 28 Feb 2007 23:51:29 -0500 Subject: Input: HIL - cleanup coding style Signed-off-by: Helge Deller Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 7143f37..18f4d41 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -94,10 +94,12 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) idx = kbd->idx4/4; p = data[idx - 1]; - if ((p & ~HIL_CMDCT_POL) == - (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report; - if ((p & ~HIL_CMDCT_RPL) == - (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report; + if ((p & ~HIL_CMDCT_POL) == + (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) + goto report; + if ((p & ~HIL_CMDCT_RPL) == + (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) + goto report; /* Not a poll response. See if we are loading config records. */ switch (p & HIL_PKT_DATA_MASK) { @@ -107,27 +109,32 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) for (; i < HIL_KBD_MAX_LENGTH; i++) kbd->idd[i] = 0; break; + case HIL_CMD_RSC: for (i = 0; i < idx; i++) kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_KBD_MAX_LENGTH; i++) kbd->rsc[i] = 0; break; + case HIL_CMD_EXD: for (i = 0; i < idx; i++) kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_KBD_MAX_LENGTH; i++) kbd->exd[i] = 0; break; + case HIL_CMD_RNM: for (i = 0; i < idx; i++) kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_KBD_MAX_LENGTH + 1; i++) kbd->rnm[i] = '\0'; break; + default: /* These occur when device isn't present */ - if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; + if (p == (HIL_ERR_INT | HIL_PKT_CMD)) + break; /* Anything else we'd like to know about. */ printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); break; @@ -139,16 +146,19 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { case HIL_POL_CHARTYPE_NONE: break; + case HIL_POL_CHARTYPE_ASCII: while (cnt < idx - 1) input_report_key(dev, kbd->data[cnt++] & 0x7f, 1); break; + case HIL_POL_CHARTYPE_RSVD1: case HIL_POL_CHARTYPE_RSVD2: case HIL_POL_CHARTYPE_BINARY: while (cnt < idx - 1) input_report_key(dev, kbd->data[cnt++], 1); break; + case HIL_POL_CHARTYPE_SET1: while (cnt < idx - 1) { unsigned int key; @@ -161,6 +171,7 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) input_report_key(dev, key, !up); } break; + case HIL_POL_CHARTYPE_SET2: while (cnt < idx - 1) { unsigned int key; @@ -173,6 +184,7 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) input_report_key(dev, key, !up); } break; + case HIL_POL_CHARTYPE_SET3: while (cnt < idx - 1) { unsigned int key; @@ -191,42 +203,43 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) up(&kbd->sem); } -static void hil_kbd_process_err(struct hil_kbd *kbd) { +static void hil_kbd_process_err(struct hil_kbd *kbd) +{ printk(KERN_WARNING PREFIX "errored HIL packet\n"); kbd->idx4 = 0; up(&kbd->sem); } -static irqreturn_t hil_kbd_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) +static irqreturn_t hil_kbd_interrupt(struct serio *serio, + unsigned char data, unsigned int flags) { struct hil_kbd *kbd; hil_packet packet; int idx; kbd = serio_get_drvdata(serio); - if (kbd == NULL) { - BUG(); - return IRQ_HANDLED; - } + BUG_ON(kbd == NULL); if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) { hil_kbd_process_err(kbd); return IRQ_HANDLED; } idx = kbd->idx4/4; - if (!(kbd->idx4 % 4)) kbd->data[idx] = 0; + if (!(kbd->idx4 % 4)) + kbd->data[idx] = 0; packet = kbd->data[idx]; packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8); kbd->data[idx] = packet; /* Records of N 4-byte hil_packets must terminate with a command. */ - if ((++(kbd->idx4)) % 4) return IRQ_HANDLED; + if ((++(kbd->idx4)) % 4) + return IRQ_HANDLED; if ((packet & 0xffff0000) != HIL_ERR_INT) { hil_kbd_process_err(kbd); return IRQ_HANDLED; } - if (packet & HIL_PKT_CMD) hil_kbd_process_record(kbd); + if (packet & HIL_PKT_CMD) + hil_kbd_process_record(kbd); return IRQ_HANDLED; } @@ -235,10 +248,7 @@ static void hil_kbd_disconnect(struct serio *serio) struct hil_kbd *kbd; kbd = serio_get_drvdata(serio); - if (kbd == NULL) { - BUG(); - return; - } + BUG_ON(kbd == NULL); serio_close(serio); input_unregister_device(kbd->dev); @@ -267,34 +277,34 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) serio_set_drvdata(serio, kbd); kbd->serio = serio; - init_MUTEX_LOCKED(&(kbd->sem)); + init_MUTEX_LOCKED(&kbd->sem); /* Get device info. MLC driver supplies devid/status/etc. */ serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_IDD); - down(&(kbd->sem)); + down(&kbd->sem); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_RSC); - down(&(kbd->sem)); + down(&kbd->sem); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_RNM); - down(&(kbd->sem)); + down(&kbd->sem); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_EXD); - down(&(kbd->sem)); + down(&kbd->sem); - up(&(kbd->sem)); + up(&kbd->sem); did = kbd->idd[0]; idd = kbd->idd + 1; @@ -310,12 +320,11 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) goto bail2; } - if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { + if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); goto bail2; } - kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; @@ -344,8 +353,8 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */ - down(&(kbd->sem)); - up(&(kbd->sem)); + down(&kbd->sem); + up(&kbd->sem); return 0; bail2: @@ -374,20 +383,20 @@ static struct serio_driver hil_kbd_serio_drv = { }, .description = "HP HIL keyboard driver", .id_table = hil_kbd_ids, - .connect = hil_kbd_connect, - .disconnect = hil_kbd_disconnect, - .interrupt = hil_kbd_interrupt + .connect = hil_kbd_connect, + .disconnect = hil_kbd_disconnect, + .interrupt = hil_kbd_interrupt }; static int __init hil_kbd_init(void) { return serio_register_driver(&hil_kbd_serio_drv); } - + static void __exit hil_kbd_exit(void) { serio_unregister_driver(&hil_kbd_serio_drv); } - + module_init(hil_kbd_init); module_exit(hil_kbd_exit); diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index bfb174f..8e9421a 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c @@ -88,10 +88,12 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) idx = ptr->idx4/4; p = data[idx - 1]; - if ((p & ~HIL_CMDCT_POL) == - (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report; - if ((p & ~HIL_CMDCT_RPL) == - (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report; + if ((p & ~HIL_CMDCT_POL) == + (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) + goto report; + if ((p & ~HIL_CMDCT_RPL) == + (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) + goto report; /* Not a poll response. See if we are loading config records. */ switch (p & HIL_PKT_DATA_MASK) { @@ -101,27 +103,32 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) for (; i < HIL_PTR_MAX_LENGTH; i++) ptr->idd[i] = 0; break; + case HIL_CMD_RSC: for (i = 0; i < idx; i++) ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_PTR_MAX_LENGTH; i++) ptr->rsc[i] = 0; break; + case HIL_CMD_EXD: for (i = 0; i < idx; i++) ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_PTR_MAX_LENGTH; i++) ptr->exd[i] = 0; break; + case HIL_CMD_RNM: for (i = 0; i < idx; i++) ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_PTR_MAX_LENGTH + 1; i++) - ptr->rnm[i] = '\0'; + ptr->rnm[i] = 0; break; + default: /* These occur when device isn't present */ - if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; + if (p == (HIL_ERR_INT | HIL_PKT_CMD)) + break; /* Anything else we'd like to know about. */ printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); break; @@ -130,7 +137,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) report: if ((p & HIL_CMDCT_POL) != idx - 1) { - printk(KERN_WARNING PREFIX "Malformed poll packet %x (idx = %i)\n", p, idx); + printk(KERN_WARNING PREFIX + "Malformed poll packet %x (idx = %i)\n", p, idx); goto out; } @@ -139,7 +147,7 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) laxis += i; ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ - absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; + absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; for (cnt = 1; i < laxis; i++) { unsigned int lo,hi,val; @@ -157,7 +165,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) input_report_abs(dev, ABS_X + i, val); } else { val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); - if (i%3) val *= -1; + if (i%3) + val *= -1; input_report_rel(dev, REL_X + i, val); } } @@ -168,10 +177,11 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) btn = ptr->data[cnt++]; up = btn & 1; btn &= 0xfe; - if (btn == 0x8e) { + if (btn == 0x8e) continue; /* TODO: proximity == touch? */ - } - else if ((btn > 0x8c) || (btn < 0x80)) continue; + else + if ((btn > 0x8c) || (btn < 0x80)) + continue; btn = (btn - 0x80) >> 1; btn = ptr->btnmap[btn]; input_report_key(dev, btn, !up); @@ -182,14 +192,14 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) up(&ptr->sem); } -static void hil_ptr_process_err(struct hil_ptr *ptr) { +static void hil_ptr_process_err(struct hil_ptr *ptr) +{ printk(KERN_WARNING PREFIX "errored HIL packet\n"); ptr->idx4 = 0; up(&ptr->sem); - return; } -static irqreturn_t hil_ptr_interrupt(struct serio *serio, +static irqreturn_t hil_ptr_interrupt(struct serio *serio, unsigned char data, unsigned int flags) { struct hil_ptr *ptr; @@ -197,29 +207,29 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio, int idx; ptr = serio_get_drvdata(serio); - if (ptr == NULL) { - BUG(); - return IRQ_HANDLED; - } + BUG_ON(ptr == NULL); if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) { hil_ptr_process_err(ptr); return IRQ_HANDLED; } idx = ptr->idx4/4; - if (!(ptr->idx4 % 4)) ptr->data[idx] = 0; + if (!(ptr->idx4 % 4)) + ptr->data[idx] = 0; packet = ptr->data[idx]; packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8); ptr->data[idx] = packet; /* Records of N 4-byte hil_packets must terminate with a command. */ - if ((++(ptr->idx4)) % 4) return IRQ_HANDLED; + if ((++(ptr->idx4)) % 4) + return IRQ_HANDLED; if ((packet & 0xffff0000) != HIL_ERR_INT) { hil_ptr_process_err(ptr); return IRQ_HANDLED; } - if (packet & HIL_PKT_CMD) + if (packet & HIL_PKT_CMD) hil_ptr_process_record(ptr); + return IRQ_HANDLED; } @@ -228,10 +238,7 @@ static void hil_ptr_disconnect(struct serio *serio) struct hil_ptr *ptr; ptr = serio_get_drvdata(serio); - if (ptr == NULL) { - BUG(); - return; - } + BUG_ON(ptr == NULL); serio_close(serio); input_unregister_device(ptr->dev); @@ -241,7 +248,7 @@ static void hil_ptr_disconnect(struct serio *serio) static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) { struct hil_ptr *ptr; - char *txt; + const char *txt; unsigned int i, naxsets, btntype; uint8_t did, *idd; @@ -260,34 +267,34 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) serio_set_drvdata(serio, ptr); ptr->serio = serio; - init_MUTEX_LOCKED(&(ptr->sem)); + init_MUTEX_LOCKED(&ptr->sem); /* Get device info. MLC driver supplies devid/status/etc. */ serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_IDD); - down(&(ptr->sem)); + down(&ptr->sem); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_RSC); - down(&(ptr->sem)); + down(&ptr->sem); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_RNM); - down(&(ptr->sem)); + down(&ptr->sem); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_EXD); - down(&(ptr->sem)); + down(&ptr->sem); - up(&(ptr->sem)); + up(&ptr->sem); did = ptr->idd[0]; idd = ptr->idd + 1; @@ -301,12 +308,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) ptr->dev->evbit[0] = BIT(EV_ABS); txt = "absolute"; } - if (!ptr->dev->evbit[0]) { + if (!ptr->dev->evbit[0]) goto bail2; - } ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); - if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY); + if (ptr->nbtn) + ptr->dev->evbit[0] |= BIT(EV_KEY); naxsets = HIL_IDD_NUM_AXSETS(*idd); ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); @@ -315,7 +322,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) did, txt); printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n", ptr->nbtn, naxsets, ptr->naxes); - + btntype = BTN_MISC; if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) #ifdef TABLET_SIMULATES_MOUSE @@ -325,7 +332,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) #endif if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) btntype = BTN_TOUCH; - + if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) btntype = BTN_MOUSE; @@ -341,12 +348,10 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) } if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { - for (i = 0; i < ptr->naxes; i++) { + for (i = 0; i < ptr->naxes; i++) set_bit(REL_X + i, ptr->dev->relbit); - } - for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { + for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) set_bit(REL_X + i, ptr->dev->relbit); - } } else { for (i = 0; i < ptr->naxes; i++) { set_bit(ABS_X + i, ptr->dev->absbit); @@ -419,11 +424,11 @@ static int __init hil_ptr_init(void) { return serio_register_driver(&hil_ptr_serio_driver); } - + static void __exit hil_ptr_exit(void) { serio_unregister_driver(&hil_ptr_serio_driver); } - + module_init(hil_ptr_init); module_exit(hil_ptr_exit); diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 0710704..485b074 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -32,11 +32,11 @@ * * Driver theory of operation: * - * Some access methods and an ISR is defined by the sub-driver - * (e.g. hp_sdc_mlc.c). These methods are expected to provide a - * few bits of logic in addition to raw access to the HIL MLC, - * specifically, the ISR, which is entirely registered by the - * sub-driver and invoked directly, must check for record + * Some access methods and an ISR is defined by the sub-driver + * (e.g. hp_sdc_mlc.c). These methods are expected to provide a + * few bits of logic in addition to raw access to the HIL MLC, + * specifically, the ISR, which is entirely registered by the + * sub-driver and invoked directly, must check for record * termination or packet match, at which point a semaphore must * be cleared and then the hil_mlcs_tasklet must be scheduled. * @@ -47,7 +47,7 @@ * itself if output is pending. (This rescheduling should be replaced * at some point with a sub-driver-specific mechanism.) * - * A timer task prods the tasklet once per second to prevent + * A timer task prods the tasklet once per second to prevent * hangups when attached devices do not return expected data * and to initiate probes of the loop for new devices. */ @@ -83,69 +83,85 @@ DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0); /********************** Device info/instance management **********************/ -static void hil_mlc_clear_di_map (hil_mlc *mlc, int val) { +static void hil_mlc_clear_di_map(hil_mlc *mlc, int val) +{ int j; - for (j = val; j < 7 ; j++) { + + for (j = val; j < 7 ; j++) mlc->di_map[j] = -1; - } } -static void hil_mlc_clear_di_scratch (hil_mlc *mlc) { - memset(&(mlc->di_scratch), 0, sizeof(mlc->di_scratch)); +static void hil_mlc_clear_di_scratch(hil_mlc *mlc) +{ + memset(&mlc->di_scratch, 0, sizeof(mlc->di_scratch)); } -static void hil_mlc_copy_di_scratch (hil_mlc *mlc, int idx) { - memcpy(&(mlc->di[idx]), &(mlc->di_scratch), sizeof(mlc->di_scratch)); +static void hil_mlc_copy_di_scratch(hil_mlc *mlc, int idx) +{ + memcpy(&mlc->di[idx], &mlc->di_scratch, sizeof(mlc->di_scratch)); } -static int hil_mlc_match_di_scratch (hil_mlc *mlc) { +static int hil_mlc_match_di_scratch(hil_mlc *mlc) +{ int idx; for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { - int j, found; + int j, found = 0; /* In-use slots are not eligible. */ - found = 0; - for (j = 0; j < 7 ; j++) { - if (mlc->di_map[j] == idx) found++; - } - if (found) continue; - if (!memcmp(mlc->di + idx, - &(mlc->di_scratch), - sizeof(mlc->di_scratch))) break; + for (j = 0; j < 7 ; j++) + if (mlc->di_map[j] == idx) + found++; + + if (found) + continue; + + if (!memcmp(mlc->di + idx, &mlc->di_scratch, + sizeof(mlc->di_scratch))) + break; } - return((idx >= HIL_MLC_DEVMEM) ? -1 : idx); + return idx >= HIL_MLC_DEVMEM ? -1 : idx; } -static int hil_mlc_find_free_di(hil_mlc *mlc) { +static int hil_mlc_find_free_di(hil_mlc *mlc) +{ int idx; - /* TODO: Pick all-zero slots first, failing that, - * randomize the slot picked among those eligible. + + /* TODO: Pick all-zero slots first, failing that, + * randomize the slot picked among those eligible. */ for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { - int j, found; - found = 0; - for (j = 0; j < 7 ; j++) { - if (mlc->di_map[j] == idx) found++; - } - if (!found) break; + int j, found = 0; + + for (j = 0; j < 7 ; j++) + if (mlc->di_map[j] == idx) + found++; + + if (!found) + break; } - return(idx); /* Note: It is guaranteed at least one above will match */ + + return idx; /* Note: It is guaranteed at least one above will match */ } -static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) { +static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) +{ int idx; + for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { - int j, found; - found = 0; - for (j = 0; j < 7 ; j++) { - if (mlc->di_map[j] == idx) found++; - } - if (!found) mlc->serio_map[idx].di_revmap = -1; + int j, found = 0; + + for (j = 0; j < 7 ; j++) + if (mlc->di_map[j] == idx) + found++; + + if (!found) + mlc->serio_map[idx].di_revmap = -1; } } -static void hil_mlc_send_polls(hil_mlc *mlc) { +static void hil_mlc_send_polls(hil_mlc *mlc) +{ int did, i, cnt; struct serio *serio; struct serio_driver *drv; @@ -157,26 +173,31 @@ static void hil_mlc_send_polls(hil_mlc *mlc) { while (mlc->icount < 15 - i) { hil_packet p; + p = mlc->ipacket[i]; if (did != (p & HIL_PKT_ADDR_MASK) >> 8) { - if (drv == NULL || drv->interrupt == NULL) goto skip; + if (drv && drv->interrupt) { + drv->interrupt(serio, 0, 0); + drv->interrupt(serio, HIL_ERR_INT >> 16, 0); + drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); + drv->interrupt(serio, HIL_CMD_POL + cnt, 0); + } - drv->interrupt(serio, 0, 0); - drv->interrupt(serio, HIL_ERR_INT >> 16, 0); - drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); - drv->interrupt(serio, HIL_CMD_POL + cnt, 0); - skip: did = (p & HIL_PKT_ADDR_MASK) >> 8; serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL; drv = (serio != NULL) ? serio->drv : NULL; cnt = 0; } - cnt++; i++; - if (drv == NULL || drv->interrupt == NULL) continue; - drv->interrupt(serio, (p >> 24), 0); - drv->interrupt(serio, (p >> 16) & 0xff, 0); - drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0); - drv->interrupt(serio, p & 0xff, 0); + + cnt++; + i++; + + if (drv && drv->interrupt) { + drv->interrupt(serio, (p >> 24), 0); + drv->interrupt(serio, (p >> 16) & 0xff, 0); + drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0); + drv->interrupt(serio, p & 0xff, 0); + } } } @@ -215,12 +236,16 @@ static void hil_mlc_send_polls(hil_mlc *mlc) { #define HILSEN_DOZE (HILSEN_SAME | HILSEN_SCHED | HILSEN_BREAK) #define HILSEN_SLEEP (HILSEN_SAME | HILSEN_BREAK) -static int hilse_match(hil_mlc *mlc, int unused) { +static int hilse_match(hil_mlc *mlc, int unused) +{ int rc; + rc = hil_mlc_match_di_scratch(mlc); if (rc == -1) { rc = hil_mlc_find_free_di(mlc); - if (rc == -1) goto err; + if (rc == -1) + goto err; + #ifdef HIL_MLC_DEBUG printk(KERN_DEBUG PREFIX "new in slot %i\n", rc); #endif @@ -231,6 +256,7 @@ static int hilse_match(hil_mlc *mlc, int unused) { serio_rescan(mlc->serio[rc]); return -1; } + mlc->di_map[mlc->ddi] = rc; #ifdef HIL_MLC_DEBUG printk(KERN_DEBUG PREFIX "same in slot %i\n", rc); @@ -238,152 +264,177 @@ static int hilse_match(hil_mlc *mlc, int unused) { mlc->serio_map[rc].di_revmap = mlc->ddi; hil_mlc_clean_serio_map(mlc); return 0; + err: printk(KERN_ERR PREFIX "Residual device slots exhausted, close some serios!\n"); return 1; } /* An LCV used to prevent runaway loops, forces 5 second sleep when reset. */ -static int hilse_init_lcv(hil_mlc *mlc, int unused) { +static int hilse_init_lcv(hil_mlc *mlc, int unused) +{ struct timeval tv; do_gettimeofday(&tv); - if(mlc->lcv == 0) goto restart; /* First init, no need to dally */ - if(tv.tv_sec - mlc->lcv_tv.tv_sec < 5) return -1; - restart: + if (mlc->lcv && (tv.tv_sec - mlc->lcv_tv.tv_sec) < 5) + return -1; + mlc->lcv_tv = tv; mlc->lcv = 0; + return 0; } -static int hilse_inc_lcv(hil_mlc *mlc, int lim) { - if (mlc->lcv++ >= lim) return -1; - return 0; +static int hilse_inc_lcv(hil_mlc *mlc, int lim) +{ + return mlc->lcv++ >= lim ? -1 : 0; } #if 0 -static int hilse_set_lcv(hil_mlc *mlc, int val) { +static int hilse_set_lcv(hil_mlc *mlc, int val) +{ mlc->lcv = val; + return 0; } #endif /* Management of the discovered device index (zero based, -1 means no devs) */ -static int hilse_set_ddi(hil_mlc *mlc, int val) { +static int hilse_set_ddi(hil_mlc *mlc, int val) +{ mlc->ddi = val; hil_mlc_clear_di_map(mlc, val + 1); + return 0; } -static int hilse_dec_ddi(hil_mlc *mlc, int unused) { +static int hilse_dec_ddi(hil_mlc *mlc, int unused) +{ mlc->ddi--; - if (mlc->ddi <= -1) { + if (mlc->ddi <= -1) { mlc->ddi = -1; hil_mlc_clear_di_map(mlc, 0); return -1; } hil_mlc_clear_di_map(mlc, mlc->ddi + 1); + return 0; } -static int hilse_inc_ddi(hil_mlc *mlc, int unused) { - if (mlc->ddi >= 6) { - BUG(); - return -1; - } +static int hilse_inc_ddi(hil_mlc *mlc, int unused) +{ + BUG_ON(mlc->ddi >= 6); mlc->ddi++; + return 0; } -static int hilse_take_idd(hil_mlc *mlc, int unused) { +static int hilse_take_idd(hil_mlc *mlc, int unused) +{ int i; - /* Help the state engine: - * Is this a real IDD response or just an echo? + /* Help the state engine: + * Is this a real IDD response or just an echo? * - * Real IDD response does not start with a command. + * Real IDD response does not start with a command. */ - if (mlc->ipacket[0] & HIL_PKT_CMD) goto bail; + if (mlc->ipacket[0] & HIL_PKT_CMD) + goto bail; + /* Should have the command echoed further down. */ for (i = 1; i < 16; i++) { - if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) == + if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) == (mlc->ipacket[0] & HIL_PKT_ADDR_MASK)) && - (mlc->ipacket[i] & HIL_PKT_CMD) && + (mlc->ipacket[i] & HIL_PKT_CMD) && ((mlc->ipacket[i] & HIL_PKT_DATA_MASK) == HIL_CMD_IDD)) break; } - if (i > 15) goto bail; + if (i > 15) + goto bail; + /* And the rest of the packets should still be clear. */ - while (++i < 16) { - if (mlc->ipacket[i]) break; - } - if (i < 16) goto bail; - for (i = 0; i < 16; i++) { - mlc->di_scratch.idd[i] = + while (++i < 16) + if (mlc->ipacket[i]) + break; + + if (i < 16) + goto bail; + + for (i = 0; i < 16; i++) + mlc->di_scratch.idd[i] = mlc->ipacket[i] & HIL_PKT_DATA_MASK; - } + /* Next step is to see if RSC supported */ - if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC) + if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC) return HILSEN_NEXT; - if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) + + if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) return HILSEN_DOWN | 4; + return 0; + bail: mlc->ddi--; + return -1; /* This should send us off to ACF */ } -static int hilse_take_rsc(hil_mlc *mlc, int unused) { +static int hilse_take_rsc(hil_mlc *mlc, int unused) +{ int i; - for (i = 0; i < 16; i++) { - mlc->di_scratch.rsc[i] = + for (i = 0; i < 16; i++) + mlc->di_scratch.rsc[i] = mlc->ipacket[i] & HIL_PKT_DATA_MASK; - } + /* Next step is to see if EXD supported (IDD has already been read) */ - if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) + if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) return HILSEN_NEXT; + return 0; } -static int hilse_take_exd(hil_mlc *mlc, int unused) { +static int hilse_take_exd(hil_mlc *mlc, int unused) +{ int i; - for (i = 0; i < 16; i++) { - mlc->di_scratch.exd[i] = + for (i = 0; i < 16; i++) + mlc->di_scratch.exd[i] = mlc->ipacket[i] & HIL_PKT_DATA_MASK; - } + /* Next step is to see if RNM supported. */ - if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM) + if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM) return HILSEN_NEXT; + return 0; } -static int hilse_take_rnm(hil_mlc *mlc, int unused) { +static int hilse_take_rnm(hil_mlc *mlc, int unused) +{ int i; - for (i = 0; i < 16; i++) { - mlc->di_scratch.rnm[i] = + for (i = 0; i < 16; i++) + mlc->di_scratch.rnm[i] = mlc->ipacket[i] & HIL_PKT_DATA_MASK; - } - do { - char nam[17]; - snprintf(nam, 16, "%s", mlc->di_scratch.rnm); - nam[16] = '\0'; - printk(KERN_INFO PREFIX "Device name gotten: %s\n", nam); - } while (0); + + printk(KERN_INFO PREFIX "Device name gotten: %16s\n", + mlc->di_scratch.rnm); + return 0; } -static int hilse_operate(hil_mlc *mlc, int repoll) { +static int hilse_operate(hil_mlc *mlc, int repoll) +{ - if (mlc->opercnt == 0) hil_mlcs_probe = 0; + if (mlc->opercnt == 0) + hil_mlcs_probe = 0; mlc->opercnt = 1; hil_mlc_send_polls(mlc); - if (!hil_mlcs_probe) return 0; + if (!hil_mlcs_probe) + return 0; hil_mlcs_probe = 0; mlc->opercnt = 0; return 1; @@ -428,7 +479,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { EXPECT(HIL_ERR_INT | TEST_PACKET(0xa), 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART) OUT(HIL_CTRL_ONLY | 0) /* Disable test mode */ - + /* 9 HILSEN_DHR */ FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) @@ -439,7 +490,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { IN(300000, HILSEN_DHR2, HILSEN_DHR2, HILSEN_NEXT) /* 14 HILSEN_IFC */ - OUT(HIL_PKT_CMD | HIL_CMD_IFC) + OUT(HIL_PKT_CMD | HIL_CMD_IFC) EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, 20000, HILSEN_DISC, HILSEN_DHR2, HILSEN_NEXT ) @@ -455,7 +506,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { /* 18 HILSEN_HEAL */ OUT_LAST(HIL_CMD_ELB) - EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT, + EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT, 20000, HILSEN_REPOLL, HILSEN_DSR, HILSEN_NEXT) FUNC(hilse_dec_ddi, 0, HILSEN_HEAL, HILSEN_NEXT, 0) @@ -503,7 +554,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { /* 44 HILSEN_PROBE */ OUT_LAST(HIL_PKT_CMD | HIL_CMD_EPT) - IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) + IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB) IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1) @@ -514,7 +565,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { /* 52 HILSEN_DSR */ FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0) OUT(HIL_PKT_CMD | HIL_CMD_DSR) - IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC) + IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC) /* 55 HILSEN_REPOLL */ OUT(HIL_PKT_CMD | HIL_CMD_RPL) @@ -523,14 +574,15 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { FUNC(hilse_operate, 1, HILSEN_OPERATE, HILSEN_IFC, HILSEN_PROBE) /* 58 HILSEN_IFCACF */ - OUT(HIL_PKT_CMD | HIL_CMD_IFC) + OUT(HIL_PKT_CMD | HIL_CMD_IFC) EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, 20000, HILSEN_ACF2, HILSEN_DHR2, HILSEN_HEAL) /* 60 HILSEN_END */ }; -static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node) { +static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node) +{ switch (node->act) { case HILSE_EXPECT_DISC: @@ -555,25 +607,25 @@ static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node do_gettimeofday(&(mlc->instart)); mlc->icount = 15; memset(mlc->ipacket, 0, 16 * sizeof(hil_packet)); - BUG_ON(down_trylock(&(mlc->isem))); - - return; + BUG_ON(down_trylock(&mlc->isem)); } #ifdef HIL_MLC_DEBUG -static int doze = 0; +static int doze; static int seidx; /* For debug */ #endif -static int hilse_donode (hil_mlc *mlc) { +static int hilse_donode(hil_mlc *mlc) +{ const struct hilse_node *node; int nextidx = 0; int sched_long = 0; unsigned long flags; #ifdef HIL_MLC_DEBUG - if (mlc->seidx && (mlc->seidx != seidx) && mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { - printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx); + if (mlc->seidx && mlc->seidx != seidx && + mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { + printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx); doze = 0; } @@ -588,50 +640,59 @@ static int hilse_donode (hil_mlc *mlc) { case HILSE_FUNC: BUG_ON(node->object.func == NULL); rc = node->object.func(mlc, node->arg); - nextidx = (rc > 0) ? node->ugly : + nextidx = (rc > 0) ? node->ugly : ((rc < 0) ? node->bad : node->good); - if (nextidx == HILSEN_FOLLOW) nextidx = rc; + if (nextidx == HILSEN_FOLLOW) + nextidx = rc; break; + case HILSE_EXPECT_LAST: case HILSE_EXPECT_DISC: case HILSE_EXPECT: case HILSE_IN: /* Already set up from previous HILSE_OUT_* */ - write_lock_irqsave(&(mlc->lock), flags); + write_lock_irqsave(&mlc->lock, flags); rc = mlc->in(mlc, node->arg); if (rc == 2) { nextidx = HILSEN_DOZE; sched_long = 1; - write_unlock_irqrestore(&(mlc->lock), flags); + write_unlock_irqrestore(&mlc->lock, flags); break; } - if (rc == 1) nextidx = node->ugly; - else if (rc == 0) nextidx = node->good; - else nextidx = node->bad; + if (rc == 1) + nextidx = node->ugly; + else if (rc == 0) + nextidx = node->good; + else + nextidx = node->bad; mlc->istarted = 0; - write_unlock_irqrestore(&(mlc->lock), flags); + write_unlock_irqrestore(&mlc->lock, flags); break; + case HILSE_OUT_LAST: - write_lock_irqsave(&(mlc->lock), flags); + write_lock_irqsave(&mlc->lock, flags); pack = node->object.packet; pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT); goto out; + case HILSE_OUT_DISC: - write_lock_irqsave(&(mlc->lock), flags); + write_lock_irqsave(&mlc->lock, flags); pack = node->object.packet; pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT); goto out; + case HILSE_OUT: - write_lock_irqsave(&(mlc->lock), flags); + write_lock_irqsave(&mlc->lock, flags); pack = node->object.packet; out: - if (mlc->istarted) goto out2; + if (mlc->istarted) + goto out2; /* Prepare to receive input */ if ((node + 1)->act & HILSE_IN) hilse_setup_input(mlc, node + 1); out2: - write_unlock_irqrestore(&(mlc->lock), flags); + write_unlock_irqrestore(&mlc->lock, flags); if (down_trylock(&mlc->osem)) { nextidx = HILSEN_DOZE; @@ -639,37 +700,39 @@ static int hilse_donode (hil_mlc *mlc) { } up(&mlc->osem); - write_lock_irqsave(&(mlc->lock), flags); - if (!(mlc->ostarted)) { + write_lock_irqsave(&mlc->lock, flags); + if (!mlc->ostarted) { mlc->ostarted = 1; mlc->opacket = pack; mlc->out(mlc); nextidx = HILSEN_DOZE; - write_unlock_irqrestore(&(mlc->lock), flags); + write_unlock_irqrestore(&mlc->lock, flags); break; } mlc->ostarted = 0; do_gettimeofday(&(mlc->instart)); - write_unlock_irqrestore(&(mlc->lock), flags); + write_unlock_irqrestore(&mlc->lock, flags); nextidx = HILSEN_NEXT; break; + case HILSE_CTS: nextidx = mlc->cts(mlc) ? node->bad : node->good; break; + default: BUG(); - nextidx = 0; - break; } #ifdef HIL_MLC_DEBUG - if (nextidx == HILSEN_DOZE) doze++; + if (nextidx == HILSEN_DOZE) + doze++; #endif while (nextidx & HILSEN_SCHED) { struct timeval tv; - if (!sched_long) goto sched; + if (!sched_long) + goto sched; do_gettimeofday(&tv); tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); @@ -682,17 +745,24 @@ static int hilse_donode (hil_mlc *mlc) { sched: tasklet_schedule(&hil_mlcs_tasklet); break; - } - if (nextidx & HILSEN_DOWN) mlc->seidx += nextidx & HILSEN_MASK; - else if (nextidx & HILSEN_UP) mlc->seidx -= nextidx & HILSEN_MASK; - else mlc->seidx = nextidx & HILSEN_MASK; + } + + if (nextidx & HILSEN_DOWN) + mlc->seidx += nextidx & HILSEN_MASK; + else if (nextidx & HILSEN_UP) + mlc->seidx -= nextidx & HILSEN_MASK; + else + mlc->seidx = nextidx & HILSEN_MASK; + + if (nextidx & HILSEN_BREAK) + return 1; - if (nextidx & HILSEN_BREAK) return 1; return 0; } /******************** tasklet context functions **************************/ -static void hil_mlcs_process(unsigned long unused) { +static void hil_mlcs_process(unsigned long unused) +{ struct list_head *tmp; read_lock(&hil_mlcs_lock); @@ -700,19 +770,20 @@ static void hil_mlcs_process(unsigned long unused) { struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list); while (hilse_donode(mlc) == 0) { #ifdef HIL_MLC_DEBUG - if (mlc->seidx != 41 && - mlc->seidx != 42 && - mlc->seidx != 43) - printk(KERN_DEBUG PREFIX " + "); + if (mlc->seidx != 41 && + mlc->seidx != 42 && + mlc->seidx != 43) + printk(KERN_DEBUG PREFIX " + "); #endif - }; + } } read_unlock(&hil_mlcs_lock); } /************************* Keepalive timer task *********************/ -void hil_mlcs_timer (unsigned long data) { +void hil_mlcs_timer(unsigned long data) +{ hil_mlcs_probe = 1; tasklet_schedule(&hil_mlcs_tasklet); /* Re-insert the periodic task. */ @@ -722,28 +793,25 @@ void hil_mlcs_timer (unsigned long data) { /******************** user/kernel context functions **********************/ -static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { +static int hil_mlc_serio_write(struct serio *serio, unsigned char c) +{ struct hil_mlc_serio_map *map; struct hil_mlc *mlc; struct serio_driver *drv; uint8_t *idx, *last; map = serio->port_data; - if (map == NULL) { - BUG(); - return -EIO; - } + BUG_ON(map == NULL); + mlc = map->mlc; - if (mlc == NULL) { - BUG(); - return -EIO; - } - mlc->serio_opacket[map->didx] |= + BUG_ON(mlc == NULL); + + mlc->serio_opacket[map->didx] |= ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx])); if (mlc->serio_oidx[map->didx] >= 3) { /* for now only commands */ - if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) + if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) return -EIO; switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) { case HIL_CMD_IDD: @@ -769,12 +837,11 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { return -EIO; emu: drv = serio->drv; - if (drv == NULL) { - BUG(); - return -EIO; - } + BUG_ON(drv == NULL); + last = idx + 15; - while ((last != idx) && (*last == 0)) last--; + while ((last != idx) && (*last == 0)) + last--; while (idx != last) { drv->interrupt(serio, 0, 0); @@ -787,14 +854,15 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { drv->interrupt(serio, HIL_ERR_INT >> 16, 0); drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); drv->interrupt(serio, *idx, 0); - + mlc->serio_oidx[map->didx] = 0; mlc->serio_opacket[map->didx] = 0; return 0; } -static int hil_mlc_serio_open(struct serio *serio) { +static int hil_mlc_serio_open(struct serio *serio) +{ struct hil_mlc_serio_map *map; struct hil_mlc *mlc; @@ -802,33 +870,24 @@ static int hil_mlc_serio_open(struct serio *serio) { return -EBUSY; map = serio->port_data; - if (map == NULL) { - BUG(); - return -ENODEV; - } + BUG_ON(map == NULL); + mlc = map->mlc; - if (mlc == NULL) { - BUG(); - return -ENODEV; - } + BUG_ON(mlc == NULL); return 0; } -static void hil_mlc_serio_close(struct serio *serio) { +static void hil_mlc_serio_close(struct serio *serio) +{ struct hil_mlc_serio_map *map; struct hil_mlc *mlc; map = serio->port_data; - if (map == NULL) { - BUG(); - return; - } + BUG_ON(map == NULL); + mlc = map->mlc; - if (mlc == NULL) { - BUG(); - return; - } + BUG_ON(mlc == NULL); serio_set_drvdata(serio, NULL); serio->drv = NULL; @@ -842,27 +901,26 @@ static const struct serio_device_id hil_mlc_serio_id = { .id = SERIO_ANY, }; -int hil_mlc_register(hil_mlc *mlc) { +int hil_mlc_register(hil_mlc *mlc) +{ int i; - unsigned long flags; + unsigned long flags; - if (mlc == NULL) { - return -EINVAL; - } + BUG_ON(mlc == NULL); mlc->istarted = 0; - mlc->ostarted = 0; + mlc->ostarted = 0; - rwlock_init(&mlc->lock); - init_MUTEX(&(mlc->osem)); + rwlock_init(&mlc->lock); + init_MUTEX(&mlc->osem); - init_MUTEX(&(mlc->isem)); - mlc->icount = -1; - mlc->imatch = 0; + init_MUTEX(&mlc->isem); + mlc->icount = -1; + mlc->imatch = 0; mlc->opercnt = 0; - init_MUTEX_LOCKED(&(mlc->csem)); + init_MUTEX_LOCKED(&(mlc->csem)); hil_mlc_clear_di_scratch(mlc); hil_mlc_clear_di_map(mlc, 0); @@ -897,19 +955,18 @@ int hil_mlc_register(hil_mlc *mlc) { return 0; } -int hil_mlc_unregister(hil_mlc *mlc) { +int hil_mlc_unregister(hil_mlc *mlc) +{ struct list_head *tmp; - unsigned long flags; + unsigned long flags; int i; - if (mlc == NULL) - return -EINVAL; + BUG_ON(mlc == NULL); write_lock_irqsave(&hil_mlcs_lock, flags); - list_for_each(tmp, &hil_mlcs) { + list_for_each(tmp, &hil_mlcs) if (list_entry(tmp, hil_mlc, list) == mlc) goto found; - } /* not found in list */ write_unlock_irqrestore(&hil_mlcs_lock, flags); @@ -918,7 +975,7 @@ int hil_mlc_unregister(hil_mlc *mlc) { found: list_del(tmp); - write_unlock_irqrestore(&hil_mlcs_lock, flags); + write_unlock_irqrestore(&hil_mlcs_lock, flags); for (i = 0; i < HIL_MLC_DEVMEM; i++) { serio_unregister_port(mlc->serio[i]); @@ -942,7 +999,7 @@ static int __init hil_mlc_init(void) return 0; } - + static void __exit hil_mlc_exit(void) { del_timer(&hil_mlcs_kicker); @@ -950,6 +1007,6 @@ static void __exit hil_mlc_exit(void) tasklet_disable(&hil_mlcs_tasklet); tasklet_kill(&hil_mlcs_tasklet); } - + module_init(hil_mlc_init); module_exit(hil_mlc_exit); diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index 353a8a1..31826e6 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c @@ -34,27 +34,27 @@ * * Driver theory of operation: * - * hp_sdc_put does all writing to the SDC. ISR can run on a different - * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time + * hp_sdc_put does all writing to the SDC. ISR can run on a different + * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time * (it cannot really benefit from SMP anyway.) A tasket fit this perfectly. * - * All data coming back from the SDC is sent via interrupt and can be read - * fully in the ISR, so there are no latency/throughput problems there. - * The problem is with output, due to the slow clock speed of the SDC - * compared to the CPU. This should not be too horrible most of the time, - * but if used with HIL devices that support the multibyte transfer command, - * keeping outbound throughput flowing at the 6500KBps that the HIL is + * All data coming back from the SDC is sent via interrupt and can be read + * fully in the ISR, so there are no latency/throughput problems there. + * The problem is with output, due to the slow clock speed of the SDC + * compared to the CPU. This should not be too horrible most of the time, + * but if used with HIL devices that support the multibyte transfer command, + * keeping outbound throughput flowing at the 6500KBps that the HIL is * capable of is more than can be done at HZ=100. * - * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf - * is set to 0 when the IBF flag in the status register has cleared. ISR - * may do this, and may also access the parts of queued transactions related - * to reading data back from the SDC, but otherwise will not touch the + * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf + * is set to 0 when the IBF flag in the status register has cleared. ISR + * may do this, and may also access the parts of queued transactions related + * to reading data back from the SDC, but otherwise will not touch the * hp_sdc state. Whenever a register is written hp_sdc.ibf is set to 1. * * The i8042 write index and the values in the 4-byte input buffer * starting at 0x70 are kept track of in hp_sdc.wi, and .r7[], respectively, - * to minimize the amount of IO needed to the SDC. However these values + * to minimize the amount of IO needed to the SDC. However these values * do not need to be locked since they are only ever accessed by hp_sdc_put. * * A timer task schedules the tasklet once per second just to make @@ -106,33 +106,39 @@ EXPORT_SYMBOL(hp_sdc_dequeue_transaction); static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */ /*************** primitives for use in any context *********************/ -static inline uint8_t hp_sdc_status_in8 (void) { +static inline uint8_t hp_sdc_status_in8(void) +{ uint8_t status; unsigned long flags; write_lock_irqsave(&hp_sdc.ibf_lock, flags); status = sdc_readb(hp_sdc.status_io); - if (!(status & HP_SDC_STATUS_IBF)) hp_sdc.ibf = 0; + if (!(status & HP_SDC_STATUS_IBF)) + hp_sdc.ibf = 0; write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); return status; } -static inline uint8_t hp_sdc_data_in8 (void) { - return sdc_readb(hp_sdc.data_io); +static inline uint8_t hp_sdc_data_in8(void) +{ + return sdc_readb(hp_sdc.data_io); } -static inline void hp_sdc_status_out8 (uint8_t val) { +static inline void hp_sdc_status_out8(uint8_t val) +{ unsigned long flags; write_lock_irqsave(&hp_sdc.ibf_lock, flags); hp_sdc.ibf = 1; - if ((val & 0xf0) == 0xe0) hp_sdc.wi = 0xff; + if ((val & 0xf0) == 0xe0) + hp_sdc.wi = 0xff; sdc_writeb(val, hp_sdc.status_io); write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); } -static inline void hp_sdc_data_out8 (uint8_t val) { +static inline void hp_sdc_data_out8(uint8_t val) +{ unsigned long flags; write_lock_irqsave(&hp_sdc.ibf_lock, flags); @@ -141,11 +147,12 @@ static inline void hp_sdc_data_out8 (uint8_t val) { write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); } -/* Care must be taken to only invoke hp_sdc_spin_ibf when - * absolutely needed, or in rarely invoked subroutines. - * Not only does it waste CPU cycles, it also wastes bus cycles. +/* Care must be taken to only invoke hp_sdc_spin_ibf when + * absolutely needed, or in rarely invoked subroutines. + * Not only does it waste CPU cycles, it also wastes bus cycles. */ -static inline void hp_sdc_spin_ibf(void) { +static inline void hp_sdc_spin_ibf(void) +{ unsigned long flags; rwlock_t *lock; @@ -158,19 +165,21 @@ static inline void hp_sdc_spin_ibf(void) { } read_unlock(lock); write_lock(lock); - while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) {}; + while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) + { } hp_sdc.ibf = 0; write_unlock_irqrestore(lock, flags); } /************************ Interrupt context functions ************************/ -static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) { +static void hp_sdc_take(int irq, void *dev_id, uint8_t status, uint8_t data) +{ hp_sdc_transaction *curr; read_lock(&hp_sdc.rtq_lock); if (hp_sdc.rcurr < 0) { - read_unlock(&hp_sdc.rtq_lock); + read_unlock(&hp_sdc.rtq_lock); return; } curr = hp_sdc.tq[hp_sdc.rcurr]; @@ -183,25 +192,27 @@ static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) { if (hp_sdc.rqty <= 0) { /* All data has been gathered. */ - if(curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) { - if (curr->act.semaphore) up(curr->act.semaphore); - } - if(curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) { + if (curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) + if (curr->act.semaphore) + up(curr->act.semaphore); + + if (curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) if (curr->act.irqhook) curr->act.irqhook(irq, dev_id, status, data); - } + curr->actidx = curr->idx; curr->idx++; /* Return control of this transaction */ write_lock(&hp_sdc.rtq_lock); - hp_sdc.rcurr = -1; + hp_sdc.rcurr = -1; hp_sdc.rqty = 0; write_unlock(&hp_sdc.rtq_lock); tasklet_schedule(&hp_sdc.task); } } -static irqreturn_t hp_sdc_isr(int irq, void *dev_id) { +static irqreturn_t hp_sdc_isr(int irq, void *dev_id) +{ uint8_t status, data; status = hp_sdc_status_in8(); @@ -209,67 +220,74 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id) { data = hp_sdc_data_in8(); /* For now we are ignoring these until we get the SDC to behave. */ - if (((status & 0xf1) == 0x51) && data == 0x82) { - return IRQ_HANDLED; - } + if (((status & 0xf1) == 0x51) && data == 0x82) + return IRQ_HANDLED; - switch(status & HP_SDC_STATUS_IRQMASK) { - case 0: /* This case is not documented. */ + switch (status & HP_SDC_STATUS_IRQMASK) { + case 0: /* This case is not documented. */ break; - case HP_SDC_STATUS_USERTIMER: - case HP_SDC_STATUS_PERIODIC: - case HP_SDC_STATUS_TIMER: + + case HP_SDC_STATUS_USERTIMER: + case HP_SDC_STATUS_PERIODIC: + case HP_SDC_STATUS_TIMER: read_lock(&hp_sdc.hook_lock); - if (hp_sdc.timer != NULL) + if (hp_sdc.timer != NULL) hp_sdc.timer(irq, dev_id, status, data); read_unlock(&hp_sdc.hook_lock); break; - case HP_SDC_STATUS_REG: + + case HP_SDC_STATUS_REG: hp_sdc_take(irq, dev_id, status, data); break; - case HP_SDC_STATUS_HILCMD: - case HP_SDC_STATUS_HILDATA: + + case HP_SDC_STATUS_HILCMD: + case HP_SDC_STATUS_HILDATA: read_lock(&hp_sdc.hook_lock); if (hp_sdc.hil != NULL) hp_sdc.hil(irq, dev_id, status, data); read_unlock(&hp_sdc.hook_lock); break; - case HP_SDC_STATUS_PUP: + + case HP_SDC_STATUS_PUP: read_lock(&hp_sdc.hook_lock); if (hp_sdc.pup != NULL) hp_sdc.pup(irq, dev_id, status, data); - else printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n"); + else + printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n"); read_unlock(&hp_sdc.hook_lock); break; - default: + + default: read_lock(&hp_sdc.hook_lock); if (hp_sdc.cooked != NULL) hp_sdc.cooked(irq, dev_id, status, data); read_unlock(&hp_sdc.hook_lock); break; } + return IRQ_HANDLED; } -static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) { +static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) +{ int status; - + status = hp_sdc_status_in8(); printk(KERN_WARNING PREFIX "NMI !\n"); -#if 0 +#if 0 if (status & HP_SDC_NMISTATUS_FHS) { read_lock(&hp_sdc.hook_lock); - if (hp_sdc.timer != NULL) + if (hp_sdc.timer != NULL) hp_sdc.timer(irq, dev_id, status, 0); read_unlock(&hp_sdc.hook_lock); - } - else { + } else { /* TODO: pass this on to the HIL handler, or do SAK here? */ printk(KERN_WARNING PREFIX "HIL NMI\n"); } #endif + return IRQ_HANDLED; } @@ -278,13 +296,17 @@ static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) { unsigned long hp_sdc_put(void); -static void hp_sdc_tasklet(unsigned long foo) { - +static void hp_sdc_tasklet(unsigned long foo) +{ write_lock_irq(&hp_sdc.rtq_lock); + if (hp_sdc.rcurr >= 0) { struct timeval tv; + do_gettimeofday(&tv); - if (tv.tv_sec > hp_sdc.rtv.tv_sec) tv.tv_usec += 1000000; + if (tv.tv_sec > hp_sdc.rtv.tv_sec) + tv.tv_usec += USEC_PER_SEC; + if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) { hp_sdc_transaction *curr; uint8_t tmp; @@ -300,27 +322,29 @@ static void hp_sdc_tasklet(unsigned long foo) { hp_sdc.rqty = 0; tmp = curr->seq[curr->actidx]; curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD; - if(tmp & HP_SDC_ACT_SEMAPHORE) { - if (curr->act.semaphore) + if (tmp & HP_SDC_ACT_SEMAPHORE) + if (curr->act.semaphore) up(curr->act.semaphore); - } - if(tmp & HP_SDC_ACT_CALLBACK) { + + if (tmp & HP_SDC_ACT_CALLBACK) { /* Note this means that irqhooks may be called * in tasklet/bh context. */ - if (curr->act.irqhook) + if (curr->act.irqhook) curr->act.irqhook(0, NULL, 0, 0); } + curr->actidx = curr->idx; curr->idx++; - hp_sdc.rcurr = -1; + hp_sdc.rcurr = -1; } } write_unlock_irq(&hp_sdc.rtq_lock); hp_sdc_put(); } -unsigned long hp_sdc_put(void) { +unsigned long hp_sdc_put(void) +{ hp_sdc_transaction *curr; uint8_t act; int idx, curridx; @@ -333,19 +357,24 @@ unsigned long hp_sdc_put(void) { requires output, so we skip to the administrativa. */ if (hp_sdc.ibf) { hp_sdc_status_in8(); - if (hp_sdc.ibf) goto finish; + if (hp_sdc.ibf) + goto finish; } anew: /* See if we are in the middle of a sequence. */ - if (hp_sdc.wcurr < 0) hp_sdc.wcurr = 0; + if (hp_sdc.wcurr < 0) + hp_sdc.wcurr = 0; read_lock_irq(&hp_sdc.rtq_lock); - if (hp_sdc.rcurr == hp_sdc.wcurr) hp_sdc.wcurr++; + if (hp_sdc.rcurr == hp_sdc.wcurr) + hp_sdc.wcurr++; read_unlock_irq(&hp_sdc.rtq_lock); - if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; + if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) + hp_sdc.wcurr = 0; curridx = hp_sdc.wcurr; - if (hp_sdc.tq[curridx] != NULL) goto start; + if (hp_sdc.tq[curridx] != NULL) + goto start; while (++curridx != hp_sdc.wcurr) { if (curridx >= HP_SDC_QUEUE_LEN) { @@ -358,7 +387,8 @@ unsigned long hp_sdc_put(void) { continue; } read_unlock_irq(&hp_sdc.rtq_lock); - if (hp_sdc.tq[curridx] != NULL) break; /* Found one. */ + if (hp_sdc.tq[curridx] != NULL) + break; /* Found one. */ } if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */ curridx = -1; @@ -374,7 +404,8 @@ unsigned long hp_sdc_put(void) { goto finish; } - if (hp_sdc.wcurr == -1) goto done; + if (hp_sdc.wcurr == -1) + goto done; curr = hp_sdc.tq[curridx]; idx = curr->actidx; @@ -383,20 +414,23 @@ unsigned long hp_sdc_put(void) { hp_sdc.tq[curridx] = NULL; /* Interleave outbound data between the transactions. */ hp_sdc.wcurr++; - if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; - goto finish; + if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) + hp_sdc.wcurr = 0; + goto finish; } act = curr->seq[idx]; idx++; if (curr->idx >= curr->endidx) { - if (act & HP_SDC_ACT_DEALLOC) kfree(curr); + if (act & HP_SDC_ACT_DEALLOC) + kfree(curr); hp_sdc.tq[curridx] = NULL; /* Interleave outbound data between the transactions. */ hp_sdc.wcurr++; - if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; - goto finish; + if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) + hp_sdc.wcurr = 0; + goto finish; } while (act & HP_SDC_ACT_PRECMD) { @@ -409,9 +443,10 @@ unsigned long hp_sdc_put(void) { curr->idx++; /* act finished? */ if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD) - goto actdone; + goto actdone; /* skip quantity field if data-out sequence follows. */ - if (act & HP_SDC_ACT_DATAOUT) curr->idx++; + if (act & HP_SDC_ACT_DATAOUT) + curr->idx++; goto finish; } if (act & HP_SDC_ACT_DATAOUT) { @@ -423,15 +458,15 @@ unsigned long hp_sdc_put(void) { hp_sdc_data_out8(curr->seq[curr->idx]); curr->idx++; /* act finished? */ - if ((curr->idx - idx >= qty) && - ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT)) + if (curr->idx - idx >= qty && + (act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT) goto actdone; goto finish; } idx += qty; act &= ~HP_SDC_ACT_DATAOUT; - } - else while (act & HP_SDC_ACT_DATAREG) { + } else + while (act & HP_SDC_ACT_DATAREG) { int mask; uint8_t w7[4]; @@ -445,26 +480,30 @@ unsigned long hp_sdc_put(void) { act &= ~HP_SDC_ACT_DATAREG; break; } - + w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0]; w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1]; w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2]; w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3]; - + if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 || - w7[hp_sdc.wi-0x70] == hp_sdc.r7[hp_sdc.wi-0x70]) { + w7[hp_sdc.wi - 0x70] == hp_sdc.r7[hp_sdc.wi - 0x70]) { int i = 0; - /* Need to point the write index register */ - while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++; + /* Need to point the write index register */ + while (i < 4 && w7[i] == hp_sdc.r7[i]) + i++; + if (i < 4) { hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i); hp_sdc.wi = 0x70 + i; goto finish; } + idx++; if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG) goto actdone; + curr->idx = idx; act &= ~HP_SDC_ACT_DATAREG; break; @@ -476,12 +515,13 @@ unsigned long hp_sdc_put(void) { { int i = 0; - while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++; + while ((i < 4) && w7[i] == hp_sdc.r7[i]) + i++; if (i >= 4) { curr->idx = idx + 1; - if ((act & HP_SDC_ACT_DURING) == + if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG) - goto actdone; + goto actdone; } } goto finish; @@ -497,7 +537,7 @@ unsigned long hp_sdc_put(void) { if (act & HP_SDC_ACT_POSTCMD) { - uint8_t postcmd; + uint8_t postcmd; /* curr->idx should == idx at this point. */ postcmd = curr->seq[idx]; @@ -505,12 +545,12 @@ unsigned long hp_sdc_put(void) { if (act & HP_SDC_ACT_DATAIN) { /* Start a new read */ - hp_sdc.rqty = curr->seq[curr->idx]; + hp_sdc.rqty = curr->seq[curr->idx]; do_gettimeofday(&hp_sdc.rtv); curr->idx++; /* Still need to lock here in case of spurious irq. */ write_lock_irq(&hp_sdc.rtq_lock); - hp_sdc.rcurr = curridx; + hp_sdc.rcurr = curridx; write_unlock_irq(&hp_sdc.rtq_lock); hp_sdc_status_out8(postcmd); goto finish; @@ -519,64 +559,69 @@ unsigned long hp_sdc_put(void) { goto actdone; } -actdone: - if (act & HP_SDC_ACT_SEMAPHORE) { + actdone: + if (act & HP_SDC_ACT_SEMAPHORE) up(curr->act.semaphore); - } - else if (act & HP_SDC_ACT_CALLBACK) { + else if (act & HP_SDC_ACT_CALLBACK) curr->act.irqhook(0,NULL,0,0); - } + if (curr->idx >= curr->endidx) { /* This transaction is over. */ - if (act & HP_SDC_ACT_DEALLOC) kfree(curr); + if (act & HP_SDC_ACT_DEALLOC) + kfree(curr); hp_sdc.tq[curridx] = NULL; - } - else { + } else { curr->actidx = idx + 1; curr->idx = idx + 2; } /* Interleave outbound data between the transactions. */ hp_sdc.wcurr++; - if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; + if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) + hp_sdc.wcurr = 0; finish: - /* If by some quirk IBF has cleared and our ISR has run to + /* If by some quirk IBF has cleared and our ISR has run to see that that has happened, do it all again. */ - if (!hp_sdc.ibf && limit++ < 20) goto anew; + if (!hp_sdc.ibf && limit++ < 20) + goto anew; done: - if (hp_sdc.wcurr >= 0) tasklet_schedule(&hp_sdc.task); + if (hp_sdc.wcurr >= 0) + tasklet_schedule(&hp_sdc.task); write_unlock(&hp_sdc.lock); + return 0; } /******* Functions called in either user or kernel context ****/ -int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { +int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) +{ unsigned long flags; int i; if (this == NULL) { tasklet_schedule(&hp_sdc.task); return -EINVAL; - }; + } write_lock_irqsave(&hp_sdc.lock, flags); /* Can't have same transaction on queue twice */ - for (i=0; i < HP_SDC_QUEUE_LEN; i++) - if (hp_sdc.tq[i] == this) goto fail; + for (i = 0; i < HP_SDC_QUEUE_LEN; i++) + if (hp_sdc.tq[i] == this) + goto fail; this->actidx = 0; this->idx = 1; /* Search for empty slot */ - for (i=0; i < HP_SDC_QUEUE_LEN; i++) { + for (i = 0; i < HP_SDC_QUEUE_LEN; i++) if (hp_sdc.tq[i] == NULL) { hp_sdc.tq[i] = this; write_unlock_irqrestore(&hp_sdc.lock, flags); tasklet_schedule(&hp_sdc.task); return 0; } - } + write_unlock_irqrestore(&hp_sdc.lock, flags); printk(KERN_WARNING PREFIX "No free slot to add transaction.\n"); return -EBUSY; @@ -587,7 +632,8 @@ int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { return -EINVAL; } -int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) { +int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) +{ unsigned long flags; int i; @@ -595,8 +641,9 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) { /* TODO: don't remove it if it's not done. */ - for (i=0; i < HP_SDC_QUEUE_LEN; i++) - if (hp_sdc.tq[i] == this) hp_sdc.tq[i] = NULL; + for (i = 0; i < HP_SDC_QUEUE_LEN; i++) + if (hp_sdc.tq[i] == this) + hp_sdc.tq[i] = NULL; write_unlock_irqrestore(&hp_sdc.lock, flags); return 0; @@ -605,11 +652,11 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) { /********************** User context functions **************************/ -int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) { - - if (callback == NULL || hp_sdc.dev == NULL) { +int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) +{ + if (callback == NULL || hp_sdc.dev == NULL) return -EINVAL; - } + write_lock_irq(&hp_sdc.hook_lock); if (hp_sdc.timer != NULL) { write_unlock_irq(&hp_sdc.hook_lock); @@ -629,11 +676,11 @@ int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) { return 0; } -int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) { - - if (callback == NULL || hp_sdc.dev == NULL) { +int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) +{ + if (callback == NULL || hp_sdc.dev == NULL) return -EINVAL; - } + write_lock_irq(&hp_sdc.hook_lock); if (hp_sdc.hil != NULL) { write_unlock_irq(&hp_sdc.hook_lock); @@ -650,11 +697,11 @@ int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) { return 0; } -int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) { - - if (callback == NULL || hp_sdc.dev == NULL) { +int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) +{ + if (callback == NULL || hp_sdc.dev == NULL) return -EINVAL; - } + write_lock_irq(&hp_sdc.hook_lock); if (hp_sdc.cooked != NULL) { write_unlock_irq(&hp_sdc.hook_lock); @@ -672,9 +719,8 @@ int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) { return 0; } -int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) { - - +int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) +{ write_lock_irq(&hp_sdc.hook_lock); if ((callback != hp_sdc.timer) || (hp_sdc.timer == NULL)) { @@ -694,8 +740,8 @@ int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) { return 0; } -int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) { - +int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) +{ write_lock_irq(&hp_sdc.hook_lock); if ((callback != hp_sdc.hil) || (hp_sdc.hil == NULL)) { @@ -715,8 +761,8 @@ int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) { return 0; } -int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) { - +int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) +{ write_lock_irq(&hp_sdc.hook_lock); if ((callback != hp_sdc.cooked) || (hp_sdc.cooked == NULL)) { @@ -738,7 +784,8 @@ int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) { /************************* Keepalive timer task *********************/ -void hp_sdc_kicker (unsigned long data) { +void hp_sdc_kicker (unsigned long data) +{ tasklet_schedule(&hp_sdc.task); /* Re-insert the periodic task. */ mod_timer(&hp_sdc.kicker, jiffies + HZ); @@ -750,10 +797,10 @@ void hp_sdc_kicker (unsigned long data) { static const struct parisc_device_id hp_sdc_tbl[] = { { - .hw_type = HPHW_FIO, + .hw_type = HPHW_FIO, .hversion_rev = HVERSION_REV_ANY_ID, .hversion = HVERSION_ANY_ID, - .sversion = 0x73, + .sversion = 0x73, }, { 0, } }; @@ -772,16 +819,15 @@ static struct parisc_driver hp_sdc_driver = { static int __init hp_sdc_init(void) { - int i; char *errstr; hp_sdc_transaction t_sync; uint8_t ts_sync[6]; struct semaphore s_sync; - rwlock_init(&hp_sdc.lock); - rwlock_init(&hp_sdc.ibf_lock); - rwlock_init(&hp_sdc.rtq_lock); - rwlock_init(&hp_sdc.hook_lock); + rwlock_init(&hp_sdc.lock); + rwlock_init(&hp_sdc.ibf_lock); + rwlock_init(&hp_sdc.rtq_lock); + rwlock_init(&hp_sdc.hook_lock); hp_sdc.timer = NULL; hp_sdc.hil = NULL; @@ -796,7 +842,8 @@ static int __init hp_sdc_init(void) hp_sdc.r7[3] = 0xff; hp_sdc.ibf = 1; - for (i = 0; i < HP_SDC_QUEUE_LEN; i++) hp_sdc.tq[i] = NULL; + memset(&hp_sdc.tq, 0, sizeof(hp_sdc.tq)); + hp_sdc.wcurr = -1; hp_sdc.rcurr = -1; hp_sdc.rqty = 0; @@ -804,27 +851,32 @@ static int __init hp_sdc_init(void) hp_sdc.dev_err = -ENODEV; errstr = "IO not found for"; - if (!hp_sdc.base_io) goto err0; + if (!hp_sdc.base_io) + goto err0; errstr = "IRQ not found for"; - if (!hp_sdc.irq) goto err0; + if (!hp_sdc.irq) + goto err0; hp_sdc.dev_err = -EBUSY; #if defined(__hppa__) errstr = "IO not available for"; - if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) goto err0; -#endif + if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) + goto err0; +#endif errstr = "IRQ not available for"; if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM, - "HP SDC", &hp_sdc)) goto err1; + "HP SDC", &hp_sdc)) + goto err1; errstr = "NMI not available for"; if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED, - "HP SDC NMI", &hp_sdc)) goto err2; + "HP SDC NMI", &hp_sdc)) + goto err2; - printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", + printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); hp_sdc_status_in8(); @@ -858,9 +910,10 @@ static int __init hp_sdc_init(void) err1: release_region(hp_sdc.data_io, 2); err0: - printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n", + printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n", errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); hp_sdc.dev = NULL; + return hp_sdc.dev_err; } @@ -868,8 +921,10 @@ static int __init hp_sdc_init(void) static int __init hp_sdc_init_hppa(struct parisc_device *d) { - if (!d) return 1; - if (hp_sdc.dev != NULL) return 1; /* We only expect one SDC */ + if (!d) + return 1; + if (hp_sdc.dev != NULL) + return 1; /* We only expect one SDC */ hp_sdc.dev = d; hp_sdc.irq = d->irq; @@ -906,10 +961,8 @@ static void hp_sdc_exit(void) tasklet_kill(&hp_sdc.task); -/* release_region(hp_sdc.data_io, 2); */ - #if defined(__hppa__) - if (unregister_parisc_driver(&hp_sdc_driver)) + if (unregister_parisc_driver(&hp_sdc_driver)) printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); #endif } @@ -923,7 +976,7 @@ static int __init hp_sdc_register(void) mm_segment_t fs; unsigned char i; #endif - + hp_sdc.dev = NULL; hp_sdc.dev_err = 0; #if defined(__hppa__) @@ -960,8 +1013,8 @@ static int __init hp_sdc_register(void) tq_init.seq = tq_init_seq; tq_init.act.semaphore = &tq_init_sem; - tq_init_seq[0] = - HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; + tq_init_seq[0] = + HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; tq_init_seq[1] = HP_SDC_CMD_READ_KCC; tq_init_seq[2] = 1; tq_init_seq[3] = 0; @@ -979,13 +1032,13 @@ static int __init hp_sdc_register(void) } hp_sdc.r11 = tq_init_seq[4]; if (hp_sdc.r11 & HP_SDC_CFG_NEW) { - char *str; + const char *str; printk(KERN_INFO PREFIX "New style SDC\n"); tq_init_seq[1] = HP_SDC_CMD_READ_XTD; tq_init.actidx = 0; tq_init.idx = 1; down(&tq_init_sem); - hp_sdc_enqueue_transaction(&tq_init); + hp_sdc_enqueue_transaction(&tq_init); down(&tq_init_sem); up(&tq_init_sem); if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) { @@ -995,15 +1048,13 @@ static int __init hp_sdc_register(void) hp_sdc.r7e = tq_init_seq[4]; HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str) printk(KERN_INFO PREFIX "Revision: %s\n", str); - if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) { + if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) printk(KERN_INFO PREFIX "TI SN76494 beeper present\n"); - } - if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) { + if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n"); - } printk(KERN_INFO PREFIX "Spunking the self test register to force PUP " "on next firmware reset.\n"); - tq_init_seq[0] = HP_SDC_ACT_PRECMD | + tq_init_seq[0] = HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; tq_init_seq[1] = HP_SDC_CMD_SET_STR; tq_init_seq[2] = 1; @@ -1012,14 +1063,12 @@ static int __init hp_sdc_register(void) tq_init.idx = 1; tq_init.endidx = 4; down(&tq_init_sem); - hp_sdc_enqueue_transaction(&tq_init); + hp_sdc_enqueue_transaction(&tq_init); down(&tq_init_sem); up(&tq_init_sem); - } - else { - printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n", + } else + printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n", (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087"); - } return 0; } @@ -1027,13 +1076,13 @@ static int __init hp_sdc_register(void) module_init(hp_sdc_register); module_exit(hp_sdc_exit); -/* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64) +/* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64) * cycles cycles-adj time * between two consecutive mfctl(16)'s: 4 n/a 63ns * hp_sdc_spin_ibf when idle: 119 115 1.7us * gsc_writeb status register: 83 79 1.2us * IBF to clear after sending SET_IM: 6204 6006 93us - * IBF to clear after sending LOAD_RT: 4467 4352 68us + * IBF to clear after sending LOAD_RT: 4467 4352 68us * IBF to clear after sending two LOAD_RTs: 18974 18859 295us * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us * cmd to ~IBF READ_T1 2nd time right after: 5158403 n/a 81ms diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index 1f131ff..cb0b288 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c @@ -58,12 +58,13 @@ struct hp_sdc_mlc_priv_s { } hp_sdc_mlc_priv; /************************* Interrupt context ******************************/ -static void hp_sdc_mlc_isr (int irq, void *dev_id, - uint8_t status, uint8_t data) { - int idx; +static void hp_sdc_mlc_isr (int irq, void *dev_id, + uint8_t status, uint8_t data) +{ + int idx; hil_mlc *mlc = &hp_sdc_mlc; - write_lock(&(mlc->lock)); + write_lock(&mlc->lock); if (mlc->icount < 0) { printk(KERN_WARNING PREFIX "HIL Overflow!\n"); up(&mlc->isem); @@ -73,239 +74,247 @@ static void hp_sdc_mlc_isr (int irq, void *dev_id, if ((status & HP_SDC_STATUS_IRQMASK) == HP_SDC_STATUS_HILDATA) { mlc->ipacket[idx] |= data | HIL_ERR_INT; mlc->icount--; - if (hp_sdc_mlc_priv.got5x) goto check; - if (!idx) goto check; - if ((mlc->ipacket[idx-1] & HIL_PKT_ADDR_MASK) != + if (hp_sdc_mlc_priv.got5x || !idx) + goto check; + if ((mlc->ipacket[idx - 1] & HIL_PKT_ADDR_MASK) != (mlc->ipacket[idx] & HIL_PKT_ADDR_MASK)) { mlc->ipacket[idx] &= ~HIL_PKT_ADDR_MASK; - mlc->ipacket[idx] |= (mlc->ipacket[idx-1] - & HIL_PKT_ADDR_MASK); + mlc->ipacket[idx] |= (mlc->ipacket[idx - 1] + & HIL_PKT_ADDR_MASK); } goto check; } /* We know status is 5X */ - if (data & HP_SDC_HIL_ISERR) goto err; - mlc->ipacket[idx] = + if (data & HP_SDC_HIL_ISERR) + goto err; + mlc->ipacket[idx] = (data & HP_SDC_HIL_R1MASK) << HIL_PKT_ADDR_SHIFT; hp_sdc_mlc_priv.got5x = 1; goto out; check: hp_sdc_mlc_priv.got5x = 0; - if (mlc->imatch == 0) goto done; - if ((mlc->imatch == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) - && (mlc->ipacket[idx] == (mlc->imatch | idx))) goto done; - if (mlc->ipacket[idx] == mlc->imatch) goto done; + if (mlc->imatch == 0) + goto done; + if ((mlc->imatch == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) + && (mlc->ipacket[idx] == (mlc->imatch | idx))) + goto done; + if (mlc->ipacket[idx] == mlc->imatch) + goto done; goto out; - err: + err: printk(KERN_DEBUG PREFIX "err code %x\n", data); + switch (data) { case HP_SDC_HIL_RC_DONE: printk(KERN_WARNING PREFIX "Bastard SDC reconfigured loop!\n"); break; + case HP_SDC_HIL_ERR: - mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_PERR | - HIL_ERR_FERR | HIL_ERR_FOF; + mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_PERR | + HIL_ERR_FERR | HIL_ERR_FOF; break; + case HP_SDC_HIL_TO: mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_LERR; break; + case HP_SDC_HIL_RC: printk(KERN_WARNING PREFIX "Bastard SDC decided to reconfigure loop!\n"); break; + default: printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data); break; } + /* No more data will be coming due to an error. */ done: tasklet_schedule(mlc->tasklet); - up(&(mlc->isem)); + up(&mlc->isem); out: - write_unlock(&(mlc->lock)); + write_unlock(&mlc->lock); } /******************** Tasklet or userspace context functions ****************/ -static int hp_sdc_mlc_in (hil_mlc *mlc, suseconds_t timeout) { +static int hp_sdc_mlc_in(hil_mlc *mlc, suseconds_t timeout) +{ unsigned long flags; struct hp_sdc_mlc_priv_s *priv; int rc = 2; priv = mlc->priv; - write_lock_irqsave(&(mlc->lock), flags); + write_lock_irqsave(&mlc->lock, flags); /* Try to down the semaphore */ - if (down_trylock(&(mlc->isem))) { + if (down_trylock(&mlc->isem)) { struct timeval tv; if (priv->emtestmode) { - mlc->ipacket[0] = - HIL_ERR_INT | (mlc->opacket & - (HIL_PKT_CMD | - HIL_PKT_ADDR_MASK | + mlc->ipacket[0] = + HIL_ERR_INT | (mlc->opacket & + (HIL_PKT_CMD | + HIL_PKT_ADDR_MASK | HIL_PKT_DATA_MASK)); mlc->icount = 14; /* printk(KERN_DEBUG PREFIX ">[%x]\n", mlc->ipacket[0]); */ goto wasup; } do_gettimeofday(&tv); - tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec); + tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); if (tv.tv_usec - mlc->instart.tv_usec > mlc->intimeout) { - /* printk("!%i %i", - tv.tv_usec - mlc->instart.tv_usec, - mlc->intimeout); - */ + /* printk("!%i %i", + tv.tv_usec - mlc->instart.tv_usec, + mlc->intimeout); + */ rc = 1; - up(&(mlc->isem)); + up(&mlc->isem); } goto done; } wasup: - up(&(mlc->isem)); + up(&mlc->isem); rc = 0; goto done; done: - write_unlock_irqrestore(&(mlc->lock), flags); + write_unlock_irqrestore(&mlc->lock, flags); return rc; } -static int hp_sdc_mlc_cts (hil_mlc *mlc) { +static int hp_sdc_mlc_cts(hil_mlc *mlc) +{ struct hp_sdc_mlc_priv_s *priv; unsigned long flags; - priv = mlc->priv; + priv = mlc->priv; - write_lock_irqsave(&(mlc->lock), flags); + write_lock_irqsave(&mlc->lock, flags); /* Try to down the semaphores -- they should be up. */ - if (down_trylock(&(mlc->isem))) { - BUG(); - goto busy; - } - if (down_trylock(&(mlc->osem))) { - BUG(); - up(&(mlc->isem)); - goto busy; - } - up(&(mlc->isem)); - up(&(mlc->osem)); + BUG_ON(down_trylock(&mlc->isem)); + BUG_ON(down_trylock(&mlc->osem)); - if (down_trylock(&(mlc->csem))) { - if (priv->trans.act.semaphore != &(mlc->csem)) goto poll; - goto busy; + up(&mlc->isem); + up(&mlc->osem); + + if (down_trylock(&mlc->csem)) { + if (priv->trans.act.semaphore != &mlc->csem) + goto poll; + else + goto busy; } - if (!(priv->tseq[4] & HP_SDC_USE_LOOP)) goto done; + + if (!(priv->tseq[4] & HP_SDC_USE_LOOP)) + goto done; poll: - priv->trans.act.semaphore = &(mlc->csem); + priv->trans.act.semaphore = &mlc->csem; priv->trans.actidx = 0; priv->trans.idx = 1; priv->trans.endidx = 5; - priv->tseq[0] = + priv->tseq[0] = HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; priv->tseq[1] = HP_SDC_CMD_READ_USE; priv->tseq[2] = 1; priv->tseq[3] = 0; priv->tseq[4] = 0; - hp_sdc_enqueue_transaction(&(priv->trans)); + hp_sdc_enqueue_transaction(&priv->trans); busy: - write_unlock_irqrestore(&(mlc->lock), flags); + write_unlock_irqrestore(&mlc->lock, flags); return 1; done: - priv->trans.act.semaphore = &(mlc->osem); - up(&(mlc->csem)); - write_unlock_irqrestore(&(mlc->lock), flags); + priv->trans.act.semaphore = &mlc->osem; + up(&mlc->csem); + write_unlock_irqrestore(&mlc->lock, flags); return 0; } -static void hp_sdc_mlc_out (hil_mlc *mlc) { +static void hp_sdc_mlc_out(hil_mlc *mlc) +{ struct hp_sdc_mlc_priv_s *priv; unsigned long flags; priv = mlc->priv; - write_lock_irqsave(&(mlc->lock), flags); - + write_lock_irqsave(&mlc->lock, flags); + /* Try to down the semaphore -- it should be up. */ - if (down_trylock(&(mlc->osem))) { - BUG(); - goto done; - } + BUG_ON(down_trylock(&mlc->osem)); - if (mlc->opacket & HIL_DO_ALTER_CTRL) goto do_control; + if (mlc->opacket & HIL_DO_ALTER_CTRL) + goto do_control; do_data: if (priv->emtestmode) { - up(&(mlc->osem)); + up(&mlc->osem); goto done; } /* Shouldn't be sending commands when loop may be busy */ - if (down_trylock(&(mlc->csem))) { - BUG(); - goto done; - } - up(&(mlc->csem)); + BUG_ON(down_trylock(&mlc->csem)); + up(&mlc->csem); priv->trans.actidx = 0; priv->trans.idx = 1; - priv->trans.act.semaphore = &(mlc->osem); + priv->trans.act.semaphore = &mlc->osem; priv->trans.endidx = 6; - priv->tseq[0] = + priv->tseq[0] = HP_SDC_ACT_DATAREG | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_SEMAPHORE; priv->tseq[1] = 0x7; - priv->tseq[2] = - (mlc->opacket & + priv->tseq[2] = + (mlc->opacket & (HIL_PKT_ADDR_MASK | HIL_PKT_CMD)) >> HIL_PKT_ADDR_SHIFT; - priv->tseq[3] = - (mlc->opacket & HIL_PKT_DATA_MASK) + priv->tseq[3] = + (mlc->opacket & HIL_PKT_DATA_MASK) >> HIL_PKT_DATA_SHIFT; priv->tseq[4] = 0; /* No timeout */ - if (priv->tseq[3] == HIL_CMD_DHR) priv->tseq[4] = 1; + if (priv->tseq[3] == HIL_CMD_DHR) + priv->tseq[4] = 1; priv->tseq[5] = HP_SDC_CMD_DO_HIL; goto enqueue; do_control: priv->emtestmode = mlc->opacket & HIL_CTRL_TEST; - + /* we cannot emulate this, it should not be used. */ BUG_ON((mlc->opacket & (HIL_CTRL_APE | HIL_CTRL_IPF)) == HIL_CTRL_APE); - - if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY) goto control_only; - if (mlc->opacket & HIL_CTRL_APE) { - BUG(); /* Should not send command/data after engaging APE */ - goto done; - } - /* Disengaging APE this way would not be valid either since + + if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY) + goto control_only; + + /* Should not send command/data after engaging APE */ + BUG_ON(mlc->opacket & HIL_CTRL_APE); + + /* Disengaging APE this way would not be valid either since * the loop must be allowed to idle. * - * So, it works out that we really never actually send control - * and data when using SDC, we just send the data. + * So, it works out that we really never actually send control + * and data when using SDC, we just send the data. */ goto do_data; control_only: priv->trans.actidx = 0; priv->trans.idx = 1; - priv->trans.act.semaphore = &(mlc->osem); + priv->trans.act.semaphore = &mlc->osem; priv->trans.endidx = 4; - priv->tseq[0] = + priv->tseq[0] = HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; priv->tseq[1] = HP_SDC_CMD_SET_LPC; priv->tseq[2] = 1; - // priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC; + /* priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC; */ priv->tseq[3] = 0; if (mlc->opacket & HIL_CTRL_APE) { priv->tseq[3] |= HP_SDC_LPC_APE_IPF; - down_trylock(&(mlc->csem)); - } + down_trylock(&mlc->csem); + } enqueue: - hp_sdc_enqueue_transaction(&(priv->trans)); + hp_sdc_enqueue_transaction(&priv->trans); done: - write_unlock_irqrestore(&(mlc->lock), flags); + write_unlock_irqrestore(&mlc->lock, flags); } static int __init hp_sdc_mlc_init(void) @@ -316,14 +325,13 @@ static int __init hp_sdc_mlc_init(void) hp_sdc_mlc_priv.emtestmode = 0; hp_sdc_mlc_priv.trans.seq = hp_sdc_mlc_priv.tseq; - hp_sdc_mlc_priv.trans.act.semaphore = &(mlc->osem); + hp_sdc_mlc_priv.trans.act.semaphore = &mlc->osem; hp_sdc_mlc_priv.got5x = 0; - mlc->cts = &hp_sdc_mlc_cts; - mlc->in = &hp_sdc_mlc_in; - mlc->out = &hp_sdc_mlc_out; - - mlc->priv = &hp_sdc_mlc_priv; + mlc->cts = &hp_sdc_mlc_cts; + mlc->in = &hp_sdc_mlc_in; + mlc->out = &hp_sdc_mlc_out; + mlc->priv = &hp_sdc_mlc_priv; if (hil_mlc_register(mlc)) { printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); @@ -336,10 +344,9 @@ static int __init hp_sdc_mlc_init(void) } return 0; err1: - if (hil_mlc_unregister(mlc)) { + if (hil_mlc_unregister(mlc)) printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" "This is bad. Could cause an oops.\n"); - } err0: return -EBUSY; } @@ -347,14 +354,14 @@ static int __init hp_sdc_mlc_init(void) static void __exit hp_sdc_mlc_exit(void) { hil_mlc *mlc = &hp_sdc_mlc; - if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr)) { + + if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr)) printk(KERN_ERR PREFIX "Failed to release the raw HIL ISR hook.\n" "This is bad. Could cause an oops.\n"); - } - if (hil_mlc_unregister(mlc)) { + + if (hil_mlc_unregister(mlc)) printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" "This is bad. Could cause an oops.\n"); - } } module_init(hp_sdc_mlc_init); -- cgit v0.10.2 From 243db53bbd8503065b21fd6e8265387048eb569b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 7 Mar 2007 01:44:59 -0500 Subject: Input: psmouse - do not force stream mode Forcing stream mode after reset confuses some devices (reported by Andrea Arcangeli) so let's take it out - spec says that after reset mouse should already be in stream mode. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index eb63855..33a3251 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -836,12 +836,6 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) static void psmouse_initialize(struct psmouse *psmouse) { /* - * We set the mouse into streaming mode. - */ - - ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM); - -/* * We set the mouse report rate, resolution and scaling. */ -- cgit v0.10.2 From bc413c9563db6d596e841b2756ed3fccc48de5c0 Mon Sep 17 00:00:00 2001 From: Eric Piel Date: Wed, 7 Mar 2007 01:45:16 -0500 Subject: Input: wistron - add support for TravelMate 610 Add support for Acer TravelMate 610 to wistron_btns. All special keys are detected, but the 2 leds are not handled (yet). Signed-off-by: Eric Piel Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index e1183ae..39e43759 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -324,6 +324,21 @@ static struct key_entry keymap_acer_travelmate_240[] = { { KE_END, 0 } }; +/* Wifi subsystem only activates the led. Therefore we need to pass + * wifi event as a normal key, then userspace can really change the wifi state. + * TODO we need to export led state to userspace (wifi and mail) */ +static struct key_entry keymap_acer_travelmate_610[] = { + { KE_KEY, 0x01, KEY_HELP }, + { KE_KEY, 0x02, KEY_CONFIG }, + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_KEY, 0x13, KEY_PROG3 }, + { KE_KEY, 0x14, KEY_MAIL }, + { KE_KEY, 0x15, KEY_WWW }, + { KE_KEY, 0x40, KEY_WLAN }, /* Wifi */ + { KE_END, 0 } +}; + static struct key_entry keymap_aopen_1559as[] = { { KE_KEY, 0x01, KEY_HELP }, { KE_KEY, 0x06, KEY_PROG3 }, @@ -408,6 +423,15 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, { .callback = dmi_matched, + .ident = "Acer TravelMate 610", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ACER"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), + }, + .driver_data = keymap_acer_travelmate_610 + }, + { + .callback = dmi_matched, .ident = "AOpen 1559AS", .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), -- cgit v0.10.2 From 15e03ae811475c2beebfde18717935ee9ce64617 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 7 Mar 2007 23:20:17 -0500 Subject: Input: export 'uniq' in /proc/bus/input/devices Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/input.c b/drivers/input/input.c index a9a706f..9b3bfce 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -439,6 +439,7 @@ static int input_devices_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : ""); seq_printf(seq, "S: Sysfs=%s\n", path ? path : ""); + seq_printf(seq, "U: Uniq=%s\n", dev->uniq ? dev->uniq : ""); seq_printf(seq, "H: Handlers="); list_for_each_entry(handle, &dev->h_list, d_node) -- cgit v0.10.2 From cb9def4dff9fe7e3d3114eba4e2d89f52265e22c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 7 Mar 2007 23:20:26 -0500 Subject: Input: let driver core create class device attribute groups Rely on device core to create attribute groups for input devices instead of open-coding it. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/input.c b/drivers/input/input.c index 9b3bfce..4486402 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -754,6 +754,13 @@ static struct attribute_group input_dev_caps_attr_group = { .attrs = input_dev_caps_attrs, }; +static struct attribute_group *input_dev_attr_groups[] = { + &input_dev_attr_group, + &input_dev_id_attr_group, + &input_dev_caps_attr_group, + NULL +}; + static void input_dev_release(struct class_device *class_dev) { struct input_dev *dev = to_input_dev(class_dev); @@ -907,6 +914,7 @@ struct input_dev *input_allocate_device(void) dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); if (dev) { dev->cdev.class = &input_class; + dev->cdev.groups = input_dev_attr_groups; class_device_initialize(&dev->cdev); mutex_init(&dev->mutex); INIT_LIST_HEAD(&dev->h_list); @@ -979,18 +987,6 @@ int input_register_device(struct input_dev *dev) if (error) return error; - error = sysfs_create_group(&dev->cdev.kobj, &input_dev_attr_group); - if (error) - goto fail1; - - error = sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group); - if (error) - goto fail2; - - error = sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group); - if (error) - goto fail3; - path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); printk(KERN_INFO "input: %s as %s\n", dev->name ? dev->name : "Unspecified device", path ? path : "N/A"); @@ -1008,11 +1004,6 @@ int input_register_device(struct input_dev *dev) input_wakeup_procfs_readers(); return 0; - - fail3: sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); - fail2: sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); - fail1: class_device_del(&dev->cdev); - return error; } EXPORT_SYMBOL(input_register_device); @@ -1037,10 +1028,6 @@ void input_unregister_device(struct input_dev *dev) list_del_init(&dev->node); - sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); - sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); - sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); - class_device_unregister(&dev->cdev); input_wakeup_procfs_readers(); -- cgit v0.10.2 From 55e3d9224b60df0fd2dc36bff9b538ce40fd9586 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sat, 10 Mar 2007 01:39:54 -0500 Subject: Input: psmouse - allow disabing certain protocol extensions Allow ALPS, LOGIPS2PP, LIFEBOOK, TRACKPOINT and TOUCHKIT protocol extensions of psmouse to be disabled during compilation. This will allow users save some memory when they are sure that they will only use a certain type of mice. Signed-off-by: Andres Salomon Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 35d998c..d0d0744 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -37,6 +37,65 @@ config MOUSE_PS2 To compile this driver as a module, choose M here: the module will be called psmouse. +config MOUSE_PS2_ALPS + bool "ALPS PS/2 mouse protocol extension" if EMBEDDED + default y + depends on MOUSE_PS2 + ---help--- + Say Y here if you have an ALPS PS/2 touchpad connected to + your system. + + If unsure, say Y. + +config MOUSE_PS2_LOGIPS2PP + bool "Logictech PS/2++ mouse protocol extension" if EMBEDDED + default y + depends on MOUSE_PS2 + ---help--- + Say Y here if you have a Logictech PS/2++ mouse connected to + your system. + + If unsure, say Y. + +config MOUSE_PS2_SYNAPTICS + bool "Synaptics PS/2 mouse protocol extension" if EMBEDDED + default y + depends on MOUSE_PS2 + ---help--- + Say Y here if you have a Synaptics PS/2 TouchPad connected to + your system. + + If unsure, say Y. + +config MOUSE_PS2_LIFEBOOK + bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED + default y + depends on MOUSE_PS2 + ---help--- + Say Y here if you have a Fujitsu B-series Lifebook PS/2 + TouchScreen connected to your system. + + If unsure, say Y. + +config MOUSE_PS2_TRACKPOINT + bool "IBM Trackpoint PS/2 mouse protocol extension" if EMBEDDED + default y + depends on MOUSE_PS2 + ---help--- + Say Y here if you have an IBM Trackpoint PS/2 mouse connected + to your system. + + If unsure, say Y. + +config MOUSE_PS2_TOUCHKIT + bool "eGalax TouchKit PS/2 protocol extension" + depends on MOUSE_PS2 + ---help--- + Say Y here if you have an eGalax TouchKit PS/2 touchscreen + connected to your system. + + If unsure, say N. + config MOUSE_SERIAL tristate "Serial mouse" select SERIO @@ -118,7 +177,7 @@ config MOUSE_VSXXXAA digitizer (VSXXX-AB) DEC produced. config MOUSE_HIL - tristate "HIL pointers (mice etc)." + tristate "HIL pointers (mice etc)." depends on GSC || HP300 select HP_SDC select HIL_MLC diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 6751179..83477d5 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -14,5 +14,10 @@ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o -psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o \ - trackpoint.o touchkit_ps2.o +psmouse-objs := psmouse-base.o synaptics.o + +psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o +psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o +psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o +psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o +psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index 69db732..f85ac40 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -12,9 +12,6 @@ #ifndef _ALPS_H #define _ALPS_H -int alps_detect(struct psmouse *psmouse, int set_properties); -int alps_init(struct psmouse *psmouse); - struct alps_model_info { unsigned char signature[3]; unsigned char byte0, mask0; @@ -29,4 +26,18 @@ struct alps_data { int prev_fin; /* Finger bit from previous packet */ }; +#ifdef CONFIG_MOUSE_PS2_ALPS +int alps_detect(struct psmouse *psmouse, int set_properties); +int alps_init(struct psmouse *psmouse); +#else +inline int alps_detect(struct psmouse *psmouse, int set_properties) +{ + return -ENOSYS; +} +inline int alps_init(struct psmouse *psmouse) +{ + return -ENOSYS; +} +#endif /* CONFIG_MOUSE_PS2_ALPS */ + #endif diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h index be1c094..c1647cf 100644 --- a/drivers/input/mouse/lifebook.h +++ b/drivers/input/mouse/lifebook.h @@ -11,7 +11,18 @@ #ifndef _LIFEBOOK_H #define _LIFEBOOK_H +#ifdef CONFIG_MOUSE_PS2_LIFEBOOK int lifebook_detect(struct psmouse *psmouse, int set_properties); int lifebook_init(struct psmouse *psmouse); +#else +inline int lifebook_detect(struct psmouse *psmouse, int set_properties) +{ + return -ENOSYS; +} +inline int lifebook_init(struct psmouse *psmouse) +{ + return -ENOSYS; +} +#endif #endif diff --git a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h index 64a8ec5..6e57125 100644 --- a/drivers/input/mouse/logips2pp.h +++ b/drivers/input/mouse/logips2pp.h @@ -11,6 +11,13 @@ #ifndef _LOGIPS2PP_H #define _LOGIPS2PP_H +#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP int ps2pp_init(struct psmouse *psmouse, int set_properties); +#else +inline int ps2pp_init(struct psmouse *psmouse, int set_properties) +{ + return -ENOSYS; +} +#endif /* CONFIG_MOUSE_PS2_LOGIPS2PP */ #endif diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 33a3251..e6c9e7b 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -570,7 +570,9 @@ static int psmouse_extensions(struct psmouse *psmouse, return PSMOUSE_THINKPS; /* - * Try Synaptics TouchPad + * Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol + * support is disabled in config - we need to know if it is synaptics so we + * can reset it properly after probing for intellimouse. */ if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { synaptics_hardware = 1; @@ -661,12 +663,14 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = 1, .detect = ps2bare_detect, }, +#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP { .type = PSMOUSE_PS2PP, .name = "PS2++", .alias = "logitech", .detect = ps2pp_init, }, +#endif { .type = PSMOUSE_THINKPS, .name = "ThinkPS/2", @@ -693,6 +697,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = 1, .detect = im_explorer_detect, }, +#ifdef CONFIG_MOUSE_PS2_SYNAPTICS { .type = PSMOUSE_SYNAPTICS, .name = "SynPS/2", @@ -700,6 +705,8 @@ static const struct psmouse_protocol psmouse_protocols[] = { .detect = synaptics_detect, .init = synaptics_init, }, +#endif +#ifdef CONFIG_MOUSE_PS2_ALPS { .type = PSMOUSE_ALPS, .name = "AlpsPS/2", @@ -707,24 +714,31 @@ static const struct psmouse_protocol psmouse_protocols[] = { .detect = alps_detect, .init = alps_init, }, +#endif +#ifdef CONFIG_MOUSE_PS2_LIFEBOOK { .type = PSMOUSE_LIFEBOOK, .name = "LBPS/2", .alias = "lifebook", .init = lifebook_init, }, +#endif +#ifdef CONFIG_MOUSE_PS2_TRACKPOINT { .type = PSMOUSE_TRACKPOINT, .name = "TPPS/2", .alias = "trackpoint", .detect = trackpoint_detect, }, +#endif +#ifdef CONFIG_MOUSE_PS2_TOUCHKIT { .type = PSMOUSE_TOUCHKIT_PS2, .name = "touchkitPS/2", .alias = "touchkit", .detect = touchkit_ps2_detect, }, +#endif { .type = PSMOUSE_AUTO, .name = "auto", diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index f0f9413..e42a0a4 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -40,33 +40,70 @@ #define YMIN_NOMINAL 1408 #define YMAX_NOMINAL 4448 + /***************************************************************************** - * Synaptics communications functions + * Stuff we need even when we do not want native Synaptics support ****************************************************************************/ /* - * Send a command to the synpatics touchpad by special commands + * Set the synaptics touchpad mode byte by special commands */ -static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) +static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) { - if (psmouse_sliced_command(psmouse, c)) + unsigned char param[1]; + + if (psmouse_sliced_command(psmouse, mode)) return -1; - if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) + param[0] = SYN_PS_SET_MODE2; + if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE)) return -1; return 0; } +int synaptics_detect(struct psmouse *psmouse, int set_properties) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + unsigned char param[4]; + + param[0] = 0; + + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); + + if (param[1] != 0x47) + return -ENODEV; + + if (set_properties) { + psmouse->vendor = "Synaptics"; + psmouse->name = "TouchPad"; + } + + return 0; +} + +void synaptics_reset(struct psmouse *psmouse) +{ + /* reset touchpad back to relative mode, gestures enabled */ + synaptics_mode_cmd(psmouse, 0); +} + +#ifdef CONFIG_MOUSE_PS2_SYNAPTICS + +/***************************************************************************** + * Synaptics communications functions + ****************************************************************************/ + /* - * Set the synaptics touchpad mode byte by special commands + * Send a command to the synpatics touchpad by special commands */ -static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) +static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) { - unsigned char param[1]; - - if (psmouse_sliced_command(psmouse, mode)) + if (psmouse_sliced_command(psmouse, c)) return -1; - param[0] = SYN_PS_SET_MODE2; - if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE)) + if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) return -1; return 0; } @@ -529,12 +566,6 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) clear_bit(REL_Y, dev->relbit); } -void synaptics_reset(struct psmouse *psmouse) -{ - /* reset touchpad back to relative mode, gestures enabled */ - synaptics_mode_cmd(psmouse, 0); -} - static void synaptics_disconnect(struct psmouse *psmouse) { synaptics_reset(psmouse); @@ -569,30 +600,6 @@ static int synaptics_reconnect(struct psmouse *psmouse) return 0; } -int synaptics_detect(struct psmouse *psmouse, int set_properties) -{ - struct ps2dev *ps2dev = &psmouse->ps2dev; - unsigned char param[4]; - - param[0] = 0; - - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); - - if (param[1] != 0x47) - return -1; - - if (set_properties) { - psmouse->vendor = "Synaptics"; - psmouse->name = "TouchPad"; - } - - return 0; -} - #if defined(__i386__) #include static struct dmi_system_id toshiba_dmi_table[] = { @@ -680,4 +687,12 @@ int synaptics_init(struct psmouse *psmouse) return -1; } +#else /* CONFIG_MOUSE_PS2_SYNAPTICS */ + +int synaptics_init(struct psmouse *psmouse) +{ + return -ENOSYS; +} + +#endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 68fff1d..02aa4cf 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -9,10 +9,6 @@ #ifndef _SYNAPTICS_H #define _SYNAPTICS_H -extern int synaptics_detect(struct psmouse *psmouse, int set_properties); -extern int synaptics_init(struct psmouse *psmouse); -extern void synaptics_reset(struct psmouse *psmouse); - /* synaptics queries */ #define SYN_QUE_IDENTIFY 0x00 #define SYN_QUE_MODES 0x01 @@ -62,9 +58,9 @@ extern void synaptics_reset(struct psmouse *psmouse); #define SYN_MODE_WMODE(m) ((m) & (1 << 0)) /* synaptics identify query bits */ -#define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) -#define SYN_ID_MAJOR(i) ((i) & 0x0f) -#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) +#define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) +#define SYN_ID_MAJOR(i) ((i) & 0x0f) +#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) /* synaptics special commands */ @@ -98,8 +94,8 @@ struct synaptics_hw_state { struct synaptics_data { /* Data read from the touchpad */ unsigned long int model_id; /* Model-ID */ - unsigned long int capabilities; /* Capabilities */ - unsigned long int ext_cap; /* Extended Capabilities */ + unsigned long int capabilities; /* Capabilities */ + unsigned long int ext_cap; /* Extended Capabilities */ unsigned long int identity; /* Identification */ unsigned char pkt_type; /* packet type - old, new, etc */ @@ -107,4 +103,8 @@ struct synaptics_data { int scroll; }; +int synaptics_detect(struct psmouse *psmouse, int set_properties); +int synaptics_init(struct psmouse *psmouse); +void synaptics_reset(struct psmouse *psmouse); + #endif /* _SYNAPTICS_H */ diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h index 3f03fbc..61e9dfd 100644 --- a/drivers/input/mouse/touchkit_ps2.h +++ b/drivers/input/mouse/touchkit_ps2.h @@ -12,6 +12,13 @@ #ifndef _TOUCHKIT_PS2_H #define _TOUCHKIT_PS2_H +#ifdef CONFIG_MOUSE_PS2_TOUCHKIT int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties); +#else +inline int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) +{ + return -ENOSYS; +} +#endif /* CONFIG_MOUSE_PS2_TOUCHKIT */ #endif diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index 050298b..c10a6e7 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h @@ -142,6 +142,13 @@ struct trackpoint_data unsigned char ext_dev; }; -extern int trackpoint_detect(struct psmouse *psmouse, int set_properties); +#ifdef CONFIG_MOUSE_PS2_TRACKPOINT +int trackpoint_detect(struct psmouse *psmouse, int set_properties); +#else +inline int trackpoint_detect(struct psmouse *psmouse, int set_properties) +{ + return -ENOSYS; +} +#endif /* CONFIG_MOUSE_PS2_TRACKPOINT */ #endif /* _TRACKPOINT_H */ -- cgit v0.10.2 From c8e4c77277ca5db0c4ddbfb4bc628b8abad585b0 Mon Sep 17 00:00:00 2001 From: Marvin Raaijmakers Date: Wed, 14 Mar 2007 22:50:42 -0400 Subject: Input: add getkeycode and setkeycode methods Allow drivers to implement their own get and set keycode methods. This will allow drivers to change their keymaps without allocating huge tables covering entire range of possible scancodes. Signed-off-by: Dmitry Torokhov diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index cb8d691..3d211e8 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -159,65 +159,41 @@ static int sysrq_alt_use; static int sysrq_alt; /* - * Translation of scancodes to keycodes. We set them on only the first attached - * keyboard - for per-keyboard setting, /dev/input/event is more useful. + * Translation of scancodes to keycodes. We set them on only the first + * keyboard in the list that accepts the scancode and keycode. + * Explanation for not choosing the first attached keyboard anymore: + * USB keyboards for example have two event devices: one for all "normal" + * keys and one for extra function keys (like "volume up", "make coffee", + * etc.). So this means that scancodes for the extra function keys won't + * be valid for the first event device, but will be for the second. */ int getkeycode(unsigned int scancode) { - struct list_head *node; - struct input_dev *dev = NULL; + struct input_handle *handle; + int keycode; + int error = -ENODEV; - list_for_each(node, &kbd_handler.h_list) { - struct input_handle *handle = to_handle_h(node); - if (handle->dev->keycodesize) { - dev = handle->dev; - break; - } + list_for_each_entry(handle, &kbd_handler.h_list, h_node) { + error = handle->dev->getkeycode(handle->dev, scancode, &keycode); + if (!error) + return keycode; } - if (!dev) - return -ENODEV; - - if (scancode >= dev->keycodemax) - return -EINVAL; - - return INPUT_KEYCODE(dev, scancode); + return error; } int setkeycode(unsigned int scancode, unsigned int keycode) { - struct list_head *node; - struct input_dev *dev = NULL; - unsigned int i, oldkey; + struct input_handle *handle; + int error = -ENODEV; - list_for_each(node, &kbd_handler.h_list) { - struct input_handle *handle = to_handle_h(node); - if (handle->dev->keycodesize) { - dev = handle->dev; + list_for_each_entry(handle, &kbd_handler.h_list, h_node) { + error = handle->dev->setkeycode(handle->dev, scancode, keycode); + if (!error) break; - } } - if (!dev) - return -ENODEV; - - if (scancode >= dev->keycodemax) - return -EINVAL; - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) - return -EINVAL; - - oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); - - clear_bit(oldkey, dev->keybit); - set_bit(keycode, dev->keybit); - - for (i = 0; i < dev->keycodemax; i++) - if (INPUT_KEYCODE(dev,i) == oldkey) - set_bit(oldkey, dev->keybit); - - return 0; + return error; } /* @@ -225,10 +201,9 @@ int setkeycode(unsigned int scancode, unsigned int keycode) */ static void kd_nosound(unsigned long ignored) { - struct list_head *node; + struct input_handle *handle; - list_for_each(node, &kbd_handler.h_list) { - struct input_handle *handle = to_handle_h(node); + list_for_each_entry(handle, &kbd_handler.h_list, h_node) { if (test_bit(EV_SND, handle->dev->evbit)) { if (test_bit(SND_TONE, handle->dev->sndbit)) input_inject_event(handle, EV_SND, SND_TONE, 0); diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6439f37..64b47de 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -434,32 +434,21 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, case EVIOCGKEYCODE: if (get_user(t, ip)) return -EFAULT; - if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) - return -EINVAL; - if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) + + error = dev->getkeycode(dev, t, &v); + if (error) + return error; + + if (put_user(v, ip + 1)) return -EFAULT; + return 0; case EVIOCSKEYCODE: - if (get_user(t, ip)) - return -EFAULT; - if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) - return -EINVAL; - if (get_user(v, ip + 1)) + if (get_user(t, ip) || get_user(v, ip + 1)) return -EFAULT; - if (v < 0 || v > KEY_MAX) - return -EINVAL; - if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) - return -EINVAL; - - u = SET_INPUT_KEYCODE(dev, t, v); - clear_bit(u, dev->keybit); - set_bit(v, dev->keybit); - for (i = 0; i < dev->keycodemax; i++) - if (INPUT_KEYCODE(dev, i) == u) - set_bit(u, dev->keybit); - return 0; + return dev->setkeycode(dev, t, v); case EVIOCSFF: if (copy_from_user(&effect, p, sizeof(effect))) diff --git a/drivers/input/input.c b/drivers/input/input.c index 4486402..26393a6 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -299,6 +299,87 @@ void input_close_device(struct input_handle *handle) } EXPORT_SYMBOL(input_close_device); +static int input_fetch_keycode(struct input_dev *dev, int scancode) +{ + switch (dev->keycodesize) { + case 1: + return ((u8 *)dev->keycode)[scancode]; + + case 2: + return ((u16 *)dev->keycode)[scancode]; + + default: + return ((u32 *)dev->keycode)[scancode]; + } +} + +static int input_default_getkeycode(struct input_dev *dev, + int scancode, int *keycode) +{ + if (!dev->keycodesize) + return -EINVAL; + + if (scancode < 0 || scancode >= dev->keycodemax) + return -EINVAL; + + *keycode = input_fetch_keycode(dev, scancode); + + return 0; +} + +static int input_default_setkeycode(struct input_dev *dev, + int scancode, int keycode) +{ + int old_keycode; + int i; + + if (scancode < 0 || scancode >= dev->keycodemax) + return -EINVAL; + + if (keycode < 0 || keycode > KEY_MAX) + return -EINVAL; + + if (!dev->keycodesize) + return -EINVAL; + + if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) + return -EINVAL; + + switch (dev->keycodesize) { + case 1: { + u8 *k = (u8 *)dev->keycode; + old_keycode = k[scancode]; + k[scancode] = keycode; + break; + } + case 2: { + u16 *k = (u16 *)dev->keycode; + old_keycode = k[scancode]; + k[scancode] = keycode; + break; + } + default: { + u32 *k = (u32 *)dev->keycode; + old_keycode = k[scancode]; + k[scancode] = keycode; + break; + } + } + + clear_bit(old_keycode, dev->keybit); + set_bit(keycode, dev->keybit); + + for (i = 0; i < dev->keycodemax; i++) { + if (input_fetch_keycode(dev, i) == old_keycode) { + set_bit(old_keycode, dev->keybit); + break; /* Setting the bit twice is useless, so break */ + } + } + + return 0; +} + + static void input_link_handle(struct input_handle *handle) { list_add_tail(&handle->d_node, &handle->dev->h_list); @@ -978,6 +1059,12 @@ int input_register_device(struct input_dev *dev) dev->rep[REP_PERIOD] = 33; } + if (!dev->getkeycode) + dev->getkeycode = input_default_getkeycode; + + if (!dev->setkeycode) + dev->setkeycode = input_default_setkeycode; + list_add_tail(&dev->node, &input_dev_list); snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), diff --git a/include/linux/input.h b/include/linux/input.h index bde65c8..3a8b8c6 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -913,33 +913,6 @@ struct ff_effect { #define BIT(x) (1UL<<((x)%BITS_PER_LONG)) #define LONG(x) ((x)/BITS_PER_LONG) -#define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \ - ((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode]))) - -#define SET_INPUT_KEYCODE(dev, scancode, val) \ - ({ unsigned __old; \ - switch (dev->keycodesize) { \ - case 1: { \ - u8 *k = (u8 *)dev->keycode; \ - __old = k[scancode]; \ - k[scancode] = val; \ - break; \ - } \ - case 2: { \ - u16 *k = (u16 *)dev->keycode; \ - __old = k[scancode]; \ - k[scancode] = val; \ - break; \ - } \ - default: { \ - u32 *k = (u32 *)dev->keycode; \ - __old = k[scancode]; \ - k[scancode] = val; \ - break; \ - } \ - } \ - __old; }) - struct input_dev { void *private; @@ -962,6 +935,8 @@ struct input_dev { unsigned int keycodemax; unsigned int keycodesize; void *keycode; + int (*setkeycode)(struct input_dev *dev, int scancode, int keycode); + int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode); struct ff_device *ff; @@ -1104,7 +1079,7 @@ struct input_handle { }; #define to_dev(n) container_of(n,struct input_dev,node) -#define to_handler(n) container_of(n,struct input_handler,node); +#define to_handler(n) container_of(n,struct input_handler,node) #define to_handle(n) container_of(n,struct input_handle,d_node) #define to_handle_h(n) container_of(n,struct input_handle,h_node) -- cgit v0.10.2 From 54f9e36cb83e7da17dc0596d365fe019a25c226f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 16 Mar 2007 00:57:25 -0400 Subject: Input: simplify input_free_device() Now that sysfs attributes that were marked for deletion can't access their devices we do not need to set name, phys and uniq to NULL. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/input.c b/drivers/input/input.c index 26393a6..5629e39 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1024,14 +1024,8 @@ EXPORT_SYMBOL(input_allocate_device); */ void input_free_device(struct input_dev *dev) { - if (dev) { - - mutex_lock(&dev->mutex); - dev->name = dev->phys = dev->uniq = NULL; - mutex_unlock(&dev->mutex); - + if (dev) input_put_device(dev); - } } EXPORT_SYMBOL(input_free_device); -- cgit v0.10.2 From 867d2682e92a3999e3862f1679cfcb549142d776 Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Fri, 16 Mar 2007 00:58:37 -0400 Subject: Input: sermouse - improve protocol error recovery When using MS protocol the driver should wait for a byte with bit 6 set before assuming that it sees beginning of a data packet. This should allow driver better cope with lost bytes and prevent spurious left/right button events when serial communication is disturbed by a CPU-hungry real-time process. Also fix some formatting. Signed-off-by: Peter Osterlund Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index a85d747..0ac448a 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -69,7 +69,8 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data) switch (sermouse->count) { case 0: - if ((data & 0xf8) != 0x80) return; + if ((data & 0xf8) != 0x80) + return; input_report_key(dev, BTN_LEFT, !(data & 4)); input_report_key(dev, BTN_RIGHT, !(data & 1)); input_report_key(dev, BTN_MIDDLE, !(data & 2)); @@ -107,7 +108,10 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data) struct input_dev *dev = sermouse->dev; signed char *buf = sermouse->buf; - if (data & 0x40) sermouse->count = 0; + if (data & 0x40) + sermouse->count = 0; + else if (sermouse->count == 0) + return; switch (sermouse->count) { @@ -169,7 +173,8 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data) case 5: case 7: /* Ignore anything besides MZ++ */ - if (sermouse->type != SERIO_MZPP) break; + if (sermouse->type != SERIO_MZPP) + break; switch (buf[1]) { @@ -206,13 +211,16 @@ static irqreturn_t sermouse_interrupt(struct serio *serio, { struct sermouse *sermouse = serio_get_drvdata(serio); - if (time_after(jiffies, sermouse->last + HZ/10)) sermouse->count = 0; + if (time_after(jiffies, sermouse->last + HZ/10)) + sermouse->count = 0; + sermouse->last = jiffies; if (sermouse->type > SERIO_SUN) sermouse_process_ms(sermouse, data); else sermouse_process_msc(sermouse, data); + return IRQ_HANDLED; } -- cgit v0.10.2 From 5a90e5bca96696f1daa0bb0a9db299eb40241ada Mon Sep 17 00:00:00 2001 From: Rodolfo Giometti Date: Fri, 16 Mar 2007 00:58:52 -0400 Subject: Input: add support for PXA27x keyboard controller Signed-off-by: Rodolfo Giometti Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 6450968..be65e50 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -203,6 +203,15 @@ config KEYBOARD_OMAP To compile this driver as a module, choose M here: the module will be called omap-keypad. +config KEYBOARD_PXA27x + tristate "PXA27x keyboard support" + depends on PXA27x + help + Enable support for PXA27x matrix keyboard controller + + To compile this driver as a module, choose M here: the + module will be called pxa27x_keyboard. + config KEYBOARD_AAED2000 tristate "AAED-2000 keyboard" depends on MACH_AAED2000 diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 586a0fe..fc1d1f2 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o +obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keyboard.o obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c new file mode 100644 index 0000000..1a2afbf --- /dev/null +++ b/drivers/input/keyboard/pxa27x_keyboard.c @@ -0,0 +1,258 @@ +/* + * linux/drivers/input/keyboard/pxa27x_keyboard.c + * + * Driver for the pxa27x matrix keyboard controller. + * + * Created: Feb 22, 2007 + * Author: Rodolfo Giometti + * + * Based on a previous implementations by Kevin O'Connor + * and Alex Osborne and + * on some suggestions by Nicolas Pitre . + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define DRIVER_NAME "pxa27x-keyboard" + +#define KPASMKP(col) (col/2 == 0 ? KPASMKP0 : \ + col/2 == 1 ? KPASMKP1 : \ + col/2 == 2 ? KPASMKP2 : KPASMKP3) +#define KPASMKPx_MKC(row, col) (1 << (row + 16 * (col % 2))) + +static irqreturn_t pxakbd_irq_handler(int irq, void *dev_id) +{ + struct platform_device *pdev = dev_id; + struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; + struct input_dev *input_dev = platform_get_drvdata(pdev); + unsigned long kpc = KPC; + int p, row, col, rel; + + if (kpc & KPC_DI) { + unsigned long kpdk = KPDK; + + if (!(kpdk & KPDK_DKP)) { + /* better luck next time */ + } else if (kpc & KPC_REE0) { + unsigned long kprec = KPREC; + KPREC = 0x7f; + + if (kprec & KPREC_OF0) + rel = (kprec & 0xff) + 0x7f; + else if (kprec & KPREC_UF0) + rel = (kprec & 0xff) - 0x7f - 0xff; + else + rel = (kprec & 0xff) - 0x7f; + + if (rel) { + input_report_rel(input_dev, REL_WHEEL, rel); + input_sync(input_dev); + } + } + } + + if (kpc & KPC_MI) { + /* report the status of every button */ + for (row = 0; row < pdata->nr_rows; row++) { + for (col = 0; col < pdata->nr_cols; col++) { + p = KPASMKP(col) & KPASMKPx_MKC(row, col) ? + 1 : 0; + pr_debug("keycode %x - pressed %x\n", + pdata->keycodes[row][col], p); + input_report_key(input_dev, + pdata->keycodes[row][col], p); + } + } + input_sync(input_dev); + } + + return IRQ_HANDLED; +} + +static int pxakbd_open(struct input_dev *dev) +{ + /* Set keypad control register */ + KPC |= (KPC_ASACT | + KPC_MS_ALL | + (2 << 6) | KPC_REE0 | KPC_DK_DEB_SEL | + KPC_ME | KPC_MIE | KPC_DE | KPC_DIE); + + KPC &= ~KPC_AS; /* disable automatic scan */ + KPC &= ~KPC_IMKP; /* do not ignore multiple keypresses */ + + /* Set rotary count to mid-point value */ + KPREC = 0x7F; + + /* Enable unit clock */ + pxa_set_cken(CKEN19_KEYPAD, 1); + + return 0; +} + +static void pxakbd_close(struct input_dev *dev) +{ + /* Disable clock unit */ + pxa_set_cken(CKEN19_KEYPAD, 0); +} + +#ifdef CONFIG_PM +static int pxakbd_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; + + /* Save controller status */ + pdata->reg_kpc = KPC; + pdata->reg_kprec = KPREC; + + return 0; +} + +static int pxakbd_resume(struct platform_device *pdev) +{ + struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; + struct input_dev *input_dev = platform_get_drvdata(pdev); + + mutex_lock(&input_dev->mutex); + + if (input_dev->users) { + /* Restore controller status */ + KPC = pdata->reg_kpc; + KPREC = pdata->reg_kprec; + + /* Enable unit clock */ + pxa_set_cken(CKEN19_KEYPAD, 1); + } + + mutex_unlock(&input_dev->mutex); + + return 0; +} +#else +#define pxakbd_suspend NULL +#define pxakbd_resume NULL +#endif + +static int __devinit pxakbd_probe(struct platform_device *pdev) +{ + struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; + struct input_dev *input_dev; + int i, row, col, error; + + /* Create and register the input driver. */ + input_dev = input_allocate_device(); + if (!input_dev) { + printk(KERN_ERR "Cannot request keypad device\n"); + return -ENOMEM; + } + + input_dev->name = DRIVER_NAME; + input_dev->id.bustype = BUS_HOST; + input_dev->open = pxakbd_open; + input_dev->close = pxakbd_close; + input_dev->cdev.dev = &pdev->dev; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); + input_dev->relbit[LONG(REL_WHEEL)] = BIT(REL_WHEEL); + for (row = 0; row < pdata->nr_rows; row++) { + for (col = 0; col < pdata->nr_cols; col++) { + int code = pdata->keycodes[row][col]; + if (code > 0) + set_bit(code, input_dev->keybit); + } + } + + error = request_irq(IRQ_KEYPAD, pxakbd_irq_handler, SA_INTERRUPT, + DRIVER_NAME, pdev); + if (error) { + printk(KERN_ERR "Cannot request keypad IRQ\n"); + pxa_set_cken(CKEN19_KEYPAD, 0); + goto err_free_dev; + } + + platform_set_drvdata(pdev, input_dev); + + /* Register the input device */ + error = input_register_device(input_dev); + if (error) + goto err_free_irq; + + /* Setup GPIOs. */ + for (i = 0; i < pdata->nr_rows + pdata->nr_cols; i++) + pxa_gpio_mode(pdata->gpio_modes[i]); + + /* + * Store rows/cols info into keyboard registers. + */ + + KPC |= (pdata->nr_rows - 1) << 26; + KPC |= (pdata->nr_cols - 1) << 23; + + for (col = 0; col < pdata->nr_cols; col++) + KPC |= KPC_MS0 << col; + + return 0; + + err_free_irq: + platform_set_drvdata(pdev, NULL); + free_irq(IRQ_KEYPAD, pdev); + err_free_dev: + input_free_device(input_dev); + return error; +} + +static int __devexit pxakbd_remove(struct platform_device *pdev) +{ + struct input_dev *input_dev = platform_get_drvdata(pdev); + + input_unregister_device(input_dev); + free_irq(IRQ_KEYPAD, pdev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver pxakbd_driver = { + .probe = pxakbd_probe, + .remove = __devexit_p(pxakbd_remove), + .suspend = pxakbd_suspend, + .resume = pxakbd_resume, + .driver = { + .name = DRIVER_NAME, + }, +}; + +static int __init pxakbd_init(void) +{ + return platform_driver_register(&pxakbd_driver); +} + +static void __exit pxakbd_exit(void) +{ + platform_driver_unregister(&pxakbd_driver); +} + +module_init(pxakbd_init); +module_exit(pxakbd_exit); + +MODULE_DESCRIPTION("PXA27x Matrix Keyboard Driver"); +MODULE_LICENSE("GPL"); diff --git a/include/asm-arm/arch-pxa/pxa27x_keyboard.h b/include/asm-arm/arch-pxa/pxa27x_keyboard.h new file mode 100644 index 0000000..3aaff92 --- /dev/null +++ b/include/asm-arm/arch-pxa/pxa27x_keyboard.h @@ -0,0 +1,13 @@ +#define PXAKBD_MAXROW 8 +#define PXAKBD_MAXCOL 8 + +struct pxa27x_keyboard_platform_data { + int nr_rows, nr_cols; + int keycodes[PXAKBD_MAXROW][PXAKBD_MAXCOL]; + int gpio_modes[PXAKBD_MAXROW + PXAKBD_MAXCOL]; + +#ifdef CONFIG_PM + u32 reg_kpc; + u32 reg_kprec; +#endif +}; -- cgit v0.10.2 From 9575499dfebc0f0fbbf122223f02e9e92630661d Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 16 Mar 2007 00:59:29 -0400 Subject: Input: HIL - fix rwlock recursion bug The following bug happens when insmoding hp_sdc_mlc.ko: HP SDC MLC: Registering the System Domain Controller's HIL MLC. BUG: rwlock recursion on CPU#0, hotplug/1814, 00854734 Backtrace: [<10267560>] _raw_write_lock+0x50/0x88 [<10104008>] _write_lock_irqsave+0x14/0x24 [<008537d4>] hp_sdc_mlc_out+0x38/0x25c [hp_sdc_mlc] [<0084ebd8>] hilse_donode+0x308/0x470 [hil_mlc] [<0084ed80>] hil_mlcs_process+0x40/0x6c [hil_mlc] [<10130f80>] tasklet_action+0x78/0xb8 [<10130cec>] __do_softirq+0x60/0xcc [<1010428c>] __lock_text_end+0x38/0x48 [<10108348>] do_cpu_irq_mask+0xf0/0x11c [<1010b068>] intr_return+0x0/0xc Signed-off-by: Helge Deller Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 485b074..93a1a6b 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -716,7 +716,9 @@ static int hilse_donode(hil_mlc *mlc) break; case HILSE_CTS: + write_lock_irqsave(&mlc->lock, flags); nextidx = mlc->cts(mlc) ? node->bad : node->good; + write_unlock_irqrestore(&mlc->lock, flags); break; default: diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index 31826e6..6af1998 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c @@ -100,6 +100,7 @@ EXPORT_SYMBOL(hp_sdc_release_timer_irq); EXPORT_SYMBOL(hp_sdc_release_hil_irq); EXPORT_SYMBOL(hp_sdc_release_cooked_irq); +EXPORT_SYMBOL(__hp_sdc_enqueue_transaction); EXPORT_SYMBOL(hp_sdc_enqueue_transaction); EXPORT_SYMBOL(hp_sdc_dequeue_transaction); @@ -593,18 +594,15 @@ unsigned long hp_sdc_put(void) } /******* Functions called in either user or kernel context ****/ -int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) +int __hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { - unsigned long flags; int i; if (this == NULL) { - tasklet_schedule(&hp_sdc.task); + BUG(); return -EINVAL; } - write_lock_irqsave(&hp_sdc.lock, flags); - /* Can't have same transaction on queue twice */ for (i = 0; i < HP_SDC_QUEUE_LEN; i++) if (hp_sdc.tq[i] == this) @@ -617,21 +615,29 @@ int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) for (i = 0; i < HP_SDC_QUEUE_LEN; i++) if (hp_sdc.tq[i] == NULL) { hp_sdc.tq[i] = this; - write_unlock_irqrestore(&hp_sdc.lock, flags); tasklet_schedule(&hp_sdc.task); return 0; } - write_unlock_irqrestore(&hp_sdc.lock, flags); printk(KERN_WARNING PREFIX "No free slot to add transaction.\n"); return -EBUSY; fail: - write_unlock_irqrestore(&hp_sdc.lock,flags); printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n"); return -EINVAL; } +int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { + unsigned long flags; + int ret; + + write_lock_irqsave(&hp_sdc.lock, flags); + ret = __hp_sdc_enqueue_transaction(this); + write_unlock_irqrestore(&hp_sdc.lock,flags); + + return ret; +} + int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) { unsigned long flags; diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index cb0b288..c45ea74 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c @@ -142,14 +142,11 @@ static void hp_sdc_mlc_isr (int irq, void *dev_id, static int hp_sdc_mlc_in(hil_mlc *mlc, suseconds_t timeout) { - unsigned long flags; struct hp_sdc_mlc_priv_s *priv; int rc = 2; priv = mlc->priv; - write_lock_irqsave(&mlc->lock, flags); - /* Try to down the semaphore */ if (down_trylock(&mlc->isem)) { struct timeval tv; @@ -178,21 +175,16 @@ static int hp_sdc_mlc_in(hil_mlc *mlc, suseconds_t timeout) wasup: up(&mlc->isem); rc = 0; - goto done; done: - write_unlock_irqrestore(&mlc->lock, flags); return rc; } static int hp_sdc_mlc_cts(hil_mlc *mlc) { struct hp_sdc_mlc_priv_s *priv; - unsigned long flags; priv = mlc->priv; - write_lock_irqsave(&mlc->lock, flags); - /* Try to down the semaphores -- they should be up. */ BUG_ON(down_trylock(&mlc->isem)); BUG_ON(down_trylock(&mlc->osem)); @@ -221,26 +213,21 @@ static int hp_sdc_mlc_cts(hil_mlc *mlc) priv->tseq[2] = 1; priv->tseq[3] = 0; priv->tseq[4] = 0; - hp_sdc_enqueue_transaction(&priv->trans); + __hp_sdc_enqueue_transaction(&priv->trans); busy: - write_unlock_irqrestore(&mlc->lock, flags); return 1; done: priv->trans.act.semaphore = &mlc->osem; up(&mlc->csem); - write_unlock_irqrestore(&mlc->lock, flags); return 0; } static void hp_sdc_mlc_out(hil_mlc *mlc) { struct hp_sdc_mlc_priv_s *priv; - unsigned long flags; priv = mlc->priv; - write_lock_irqsave(&mlc->lock, flags); - /* Try to down the semaphore -- it should be up. */ BUG_ON(down_trylock(&mlc->osem)); @@ -250,7 +237,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc) do_data: if (priv->emtestmode) { up(&mlc->osem); - goto done; + return; } /* Shouldn't be sending commands when loop may be busy */ BUG_ON(down_trylock(&mlc->csem)); @@ -313,8 +300,6 @@ static void hp_sdc_mlc_out(hil_mlc *mlc) } enqueue: hp_sdc_enqueue_transaction(&priv->trans); - done: - write_unlock_irqrestore(&mlc->lock, flags); } static int __init hp_sdc_mlc_init(void) diff --git a/include/linux/hp_sdc.h b/include/linux/hp_sdc.h index debd715..9db3d45 100644 --- a/include/linux/hp_sdc.h +++ b/include/linux/hp_sdc.h @@ -71,6 +71,7 @@ typedef struct { struct semaphore *semaphore; /* Semaphore to sleep on. */ } act; } hp_sdc_transaction; +int __hp_sdc_enqueue_transaction(hp_sdc_transaction *this); int hp_sdc_enqueue_transaction(hp_sdc_transaction *this); int hp_sdc_dequeue_transaction(hp_sdc_transaction *this); -- cgit v0.10.2 From 6e782584e0713ea89da151333e7fe754c8f40324 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 16 Mar 2007 00:59:42 -0400 Subject: Input: i8042 - add HP Pavilion DV4017EA to the MUX blacklist This should get rid of "atkbd.c: Suprious NAK on isa0060/serio0" messages caused by broken MUX implementation. The box does not have external PS/2 ports so disabling MUX mode is safe. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index d36bd54..5c007d4 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -160,6 +160,17 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { }, }, { + /* + * Errors on MUX ports are reported without raising AUXDATA + * causing "spurious NAK" messages. + */ + .ident = "HP Pavilion DV4017EA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), + }, + }, + { .ident = "Toshiba P10", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), -- cgit v0.10.2 From 5b2a08262a8c952fef008154933953f083ca5766 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:29:46 -0400 Subject: Input: rework handle creation code - consolidate code for binding handlers to a device - return error codes from handlers connect() methods back to input core and log failures Signed-off-by: Dmitry Torokhov diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 3d211e8..5971254 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -41,7 +41,6 @@ #include #include -static void kbd_disconnect(struct input_handle *handle); extern void ctrl_alt_del(void); /* @@ -1260,11 +1259,11 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, * likes it, it can open it and get events from it. In this (kbd_connect) * function, we should decide which VT to bind that keyboard to initially. */ -static struct input_handle *kbd_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) +static int kbd_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct input_handle *handle; + int error; int i; for (i = KEY_RESERVED; i < BTN_MISC; i++) @@ -1272,24 +1271,37 @@ static struct input_handle *kbd_connect(struct input_handler *handler, break; if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) - return NULL; + return -ENODEV; handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); if (!handle) - return NULL; + return -ENOMEM; handle->dev = dev; handle->handler = handler; handle->name = "kbd"; - input_open_device(handle); + error = input_register_handle(handle); + if (error) + goto err_free_handle; + + error = input_open_device(handle); + if (error) + goto err_unregister_handle; + + return 0; - return handle; + err_unregister_handle: + input_unregister_handle(handle); + err_free_handle: + kfree(handle); + return error; } static void kbd_disconnect(struct input_handle *handle) { input_close_device(handle); + input_unregister_handle(handle); kfree(handle); } diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c index 5a9653c..c21f2f1 100644 --- a/drivers/input/evbug.c +++ b/drivers/input/evbug.c @@ -38,31 +38,43 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Input driver event debug module"); MODULE_LICENSE("GPL"); -static char evbug_name[] = "evbug"; - static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", handle->dev->phys, type, code, value); } -static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) +static int evbug_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct input_handle *handle; + int error; - if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) - return NULL; + handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + if (!handle) + return -ENOMEM; handle->dev = dev; handle->handler = handler; - handle->name = evbug_name; + handle->name = "evbug"; + + error = input_register_handle(handle); + if (error) + goto err_free_handle; - input_open_device(handle); + error = input_open_device(handle); + if (error) + goto err_unregister_handle; printk(KERN_DEBUG "evbug.c: Connected device: \"%s\", %s\n", dev->name, dev->phys); - return handle; + return 0; + + err_unregister_handle: + input_unregister_handle(handle); + err_free_handle: + kfree(handle); + return error; } static void evbug_disconnect(struct input_handle *handle) @@ -70,7 +82,7 @@ static void evbug_disconnect(struct input_handle *handle) printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys); input_close_device(handle); - + input_unregister_handle(handle); kfree(handle); } diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 64b47de..840fa19 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -605,21 +605,24 @@ static const struct file_operations evdev_fops = { .flush = evdev_flush }; -static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) +static int evdev_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct evdev *evdev; struct class_device *cdev; + dev_t devt; int minor; + int error; for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++); if (minor == EVDEV_MINORS) { printk(KERN_ERR "evdev: no more free evdev devices\n"); - return NULL; + return -ENFILE; } - if (!(evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL))) - return NULL; + evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); + if (!evdev) + return -ENOMEM; INIT_LIST_HEAD(&evdev->list); init_waitqueue_head(&evdev->wait); @@ -634,15 +637,35 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct evdev_table[minor] = evdev; - cdev = class_device_create(&input_class, &dev->cdev, - MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), - dev->cdev.dev, evdev->name); + devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), + + cdev = class_device_create(&input_class, &dev->cdev, devt, + dev->cdev.dev, evdev->name); + if (IS_ERR(cdev)) { + error = PTR_ERR(cdev); + goto err_free_evdev; + } /* temporary symlink to keep userspace happy */ - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, - evdev->name); + error = sysfs_create_link(&input_class.subsys.kset.kobj, + &cdev->kobj, evdev->name); + if (error) + goto err_cdev_destroy; + + error = input_register_handle(&evdev->handle); + if (error) + goto err_remove_link; - return &evdev->handle; + return 0; + + err_remove_link: + sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name); + err_cdev_destroy: + class_device_destroy(&input_class, devt); + err_free_evdev: + kfree(evdev); + evdev_table[minor] = NULL; + return error; } static void evdev_disconnect(struct input_handle *handle) @@ -650,6 +673,8 @@ static void evdev_disconnect(struct input_handle *handle) struct evdev *evdev = handle->private; struct evdev_list *list; + input_unregister_handle(handle); + sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); diff --git a/drivers/input/input.c b/drivers/input/input.c index 5629e39..86b2707 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -380,12 +380,6 @@ static int input_default_setkeycode(struct input_dev *dev, } -static void input_link_handle(struct input_handle *handle) -{ - list_add_tail(&handle->d_node, &handle->dev->h_list); - list_add_tail(&handle->h_node, &handle->handler->h_list); -} - #define MATCH_BIT(bit, max) \ for (i = 0; i < NBITS(max); i++) \ if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \ @@ -432,6 +426,29 @@ static const struct input_device_id *input_match_device(const struct input_devic return NULL; } +static int input_attach_handler(struct input_dev *dev, struct input_handler *handler) +{ + const struct input_device_id *id; + int error; + + if (handler->blacklist && input_match_device(handler->blacklist, dev)) + return -ENODEV; + + id = input_match_device(handler->id_table, dev); + if (!id) + return -ENODEV; + + error = handler->connect(handler, dev, id); + if (error && error != -ENODEV) + printk(KERN_ERR + "input: failed to attach handler %s to device %s, " + "error: %d\n", + handler->name, kobject_name(&dev->cdev.kobj), error); + + return error; +} + + #ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_bus_input_dir; @@ -1032,9 +1049,7 @@ EXPORT_SYMBOL(input_free_device); int input_register_device(struct input_dev *dev) { static atomic_t input_no = ATOMIC_INIT(0); - struct input_handle *handle; struct input_handler *handler; - const struct input_device_id *id; const char *path; int error; @@ -1074,13 +1089,7 @@ int input_register_device(struct input_dev *dev) kfree(path); list_for_each_entry(handler, &input_handler_list, node) - if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) - if ((id = input_match_device(handler->id_table, dev))) - if ((handle = handler->connect(handler, dev, id))) { - input_link_handle(handle); - if (handler->start) - handler->start(handle); - } + input_attach_handler(dev, handler); input_wakeup_procfs_readers(); @@ -1090,7 +1099,7 @@ EXPORT_SYMBOL(input_register_device); void input_unregister_device(struct input_dev *dev) { - struct list_head *node, *next; + struct input_handle *handle, *next; int code; for (code = 0; code <= KEY_MAX; code++) @@ -1100,12 +1109,9 @@ void input_unregister_device(struct input_dev *dev) del_timer_sync(&dev->timer); - list_for_each_safe(node, next, &dev->h_list) { - struct input_handle * handle = to_handle(node); - list_del_init(&handle->d_node); - list_del_init(&handle->h_node); + list_for_each_entry_safe(handle, next, &dev->h_list, d_node) handle->handler->disconnect(handle); - } + WARN_ON(!list_empty(&dev->h_list)); list_del_init(&dev->node); @@ -1118,8 +1124,6 @@ EXPORT_SYMBOL(input_unregister_device); int input_register_handler(struct input_handler *handler) { struct input_dev *dev; - struct input_handle *handle; - const struct input_device_id *id; INIT_LIST_HEAD(&handler->h_list); @@ -1133,13 +1137,7 @@ int input_register_handler(struct input_handler *handler) list_add_tail(&handler->node, &input_handler_list); list_for_each_entry(dev, &input_dev_list, node) - if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) - if ((id = input_match_device(handler->id_table, dev))) - if ((handle = handler->connect(handler, dev, id))) { - input_link_handle(handle); - if (handler->start) - handler->start(handle); - } + input_attach_handler(dev, handler); input_wakeup_procfs_readers(); return 0; @@ -1148,14 +1146,11 @@ EXPORT_SYMBOL(input_register_handler); void input_unregister_handler(struct input_handler *handler) { - struct list_head *node, *next; + struct input_handle *handle, *next; - list_for_each_safe(node, next, &handler->h_list) { - struct input_handle * handle = to_handle_h(node); - list_del_init(&handle->h_node); - list_del_init(&handle->d_node); + list_for_each_entry_safe(handle, next, &handler->h_list, h_node) handler->disconnect(handle); - } + WARN_ON(!list_empty(&handler->h_list)); list_del_init(&handler->node); @@ -1166,6 +1161,27 @@ void input_unregister_handler(struct input_handler *handler) } EXPORT_SYMBOL(input_unregister_handler); +int input_register_handle(struct input_handle *handle) +{ + struct input_handler *handler = handle->handler; + + list_add_tail(&handle->d_node, &handle->dev->h_list); + list_add_tail(&handle->h_node, &handler->h_list); + + if (handler->start) + handler->start(handle); + + return 0; +} +EXPORT_SYMBOL(input_register_handle); + +void input_unregister_handle(struct input_handle *handle) +{ + list_del_init(&handle->h_node); + list_del_init(&handle->d_node); +} +EXPORT_SYMBOL(input_unregister_handle); + static int input_open_file(struct inode *inode, struct file *file) { struct input_handler *handler = input_table[iminor(inode) >> 5]; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 9f3529a..cf24a5b 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -465,21 +465,24 @@ static const struct file_operations joydev_fops = { .fasync = joydev_fasync, }; -static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) +static int joydev_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct joydev *joydev; struct class_device *cdev; + dev_t devt; int i, j, t, minor; + int error; for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); if (minor == JOYDEV_MINORS) { printk(KERN_ERR "joydev: no more free joydev devices\n"); - return NULL; + return -ENFILE; } - if (!(joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL))) - return NULL; + joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL); + if (!joydev) + return -ENOMEM; INIT_LIST_HEAD(&joydev->list); init_waitqueue_head(&joydev->wait); @@ -534,22 +537,45 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct joydev_table[minor] = joydev; - cdev = class_device_create(&input_class, &dev->cdev, - MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), - dev->cdev.dev, joydev->name); + devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), + + cdev = class_device_create(&input_class, &dev->cdev, devt, + dev->cdev.dev, joydev->name); + if (IS_ERR(cdev)) { + error = PTR_ERR(cdev); + goto err_free_joydev; + } /* temporary symlink to keep userspace happy */ - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, - joydev->name); + error = sysfs_create_link(&input_class.subsys.kset.kobj, + &cdev->kobj, joydev->name); + if (error) + goto err_cdev_destroy; + + error = input_register_handle(&joydev->handle); + if (error) + goto err_remove_link; + + return 0; - return &joydev->handle; + err_remove_link: + sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name); + err_cdev_destroy: + class_device_destroy(&input_class, devt); + err_free_joydev: + joydev_table[minor] = NULL; + kfree(joydev); + return error; } + static void joydev_disconnect(struct input_handle *handle) { struct joydev *joydev = handle->private; struct joydev_list *list; + input_unregister_handle(handle); + sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); joydev->exist = 0; diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 664bcc8..007e72f 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -624,23 +624,27 @@ static const struct file_operations mousedev_fops = { .fasync = mousedev_fasync, }; -static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) +static int mousedev_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct mousedev *mousedev; struct class_device *cdev; - int minor = 0; + dev_t devt; + int minor; + int error; for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); if (minor == MOUSEDEV_MINORS) { printk(KERN_ERR "mousedev: no more free mousedev devices\n"); - return NULL; + return -ENFILE; } - if (!(mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL))) - return NULL; + mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); + if (!mousedev) + return -ENOMEM; INIT_LIST_HEAD(&mousedev->list); + INIT_LIST_HEAD(&mousedev->mixdev_node); init_waitqueue_head(&mousedev->wait); mousedev->minor = minor; @@ -651,20 +655,45 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru mousedev->handle.private = mousedev; sprintf(mousedev->name, "mouse%d", minor); - if (mousedev_mix.open) - input_open_device(&mousedev->handle); - mousedev_table[minor] = mousedev; - cdev = class_device_create(&input_class, &dev->cdev, - MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), - dev->cdev.dev, mousedev->name); + devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), + + cdev = class_device_create(&input_class, &dev->cdev, devt, + dev->cdev.dev, mousedev->name); + if (IS_ERR(cdev)) { + error = PTR_ERR(cdev); + goto err_free_mousedev; + } /* temporary symlink to keep userspace happy */ - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, - mousedev->name); + error = sysfs_create_link(&input_class.subsys.kset.kobj, + &cdev->kobj, mousedev->name); + if (error) + goto err_cdev_destroy; - return &mousedev->handle; + error = input_register_handle(&mousedev->handle); + if (error) + goto err_remove_link; + + if (mousedev_mix.open) { + error = input_open_device(&mousedev->handle); + if (error) + goto err_unregister_handle; + } + + return 0; + + err_unregister_handle: + input_unregister_handle(&mousedev->handle); + err_remove_link: + sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name); + err_cdev_destroy: + class_device_destroy(&input_class, devt); + err_free_mousedev: + mousedev_table[minor] = NULL; + kfree(mousedev); + return error; } static void mousedev_disconnect(struct input_handle *handle) @@ -672,6 +701,8 @@ static void mousedev_disconnect(struct input_handle *handle) struct mousedev *mousedev = handle->private; struct mousedev_list *list; + input_unregister_handle(handle); + sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); diff --git a/drivers/input/power.c b/drivers/input/power.c index ee82464..e28d264 100644 --- a/drivers/input/power.c +++ b/drivers/input/power.c @@ -41,14 +41,14 @@ static struct input_handler power_handler; * Power management can't be done in a interrupt context. So we have to * use keventd. */ -static int suspend_button_pushed = 0; -static void suspend_button_task_handler(void *data) +static int suspend_button_pushed; +static void suspend_button_task_handler(struct work_struct *work) { udelay(200); /* debounce */ suspend_button_pushed = 0; } -static DECLARE_WORK(suspend_button_task, suspend_button_task_handler, NULL); +static DECLARE_WORK(suspend_button_task, suspend_button_task_handler); static void power_event(struct input_handle *handle, unsigned int type, unsigned int code, int down) @@ -63,9 +63,9 @@ static void power_event(struct input_handle *handle, unsigned int type, printk("Powering down entire device\n"); if (!suspend_button_pushed) { - suspend_button_pushed = 1; - schedule_work(&suspend_button_task); - } + suspend_button_pushed = 1; + schedule_work(&suspend_button_task); + } break; case KEY_POWER: /* Hum power down the machine. */ @@ -84,7 +84,7 @@ static void power_event(struct input_handle *handle, unsigned int type, dev->state = PM_RESUME; else dev->state = PM_SUSPEND; - pm_send(dev->pm_dev, dev->state, dev); + /* pm_send(dev->pm_dev, dev->state, dev); */ break; case KEY_POWER: /* Turn the input device off completely ? */ @@ -96,27 +96,41 @@ static void power_event(struct input_handle *handle, unsigned int type, return; } -static struct input_handle *power_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) +static int power_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct input_handle *handle; + int error; - if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) - return NULL; + handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + if (!handle) + return -ENOMEM; handle->dev = dev; handle->handler = handler; + handle->name = "power"; - input_open_device(handle); + error = input_register_handle(handle); + if (error) + goto err_free_handle; - printk(KERN_INFO "power.c: Adding power management to input layer\n"); - return handle; + error = input_open_device(handle); + if (error) + goto err_unregister_handle; + + return 0; + + err_unregister_handle: + input_unregister_handle(handle); + err_free_handle: + kfree(handle); + return error; } static void power_disconnect(struct input_handle *handle) { input_close_device(handle); + input_unregister_handle(handle); kfree(handle); } @@ -135,7 +149,7 @@ static const struct input_device_id power_ids[] = { .flags = INPUT_DEVICE_ID_MATCH_EVBIT, .evbit = { BIT(EV_PWR) }, }, - { }, /* Terminating entry */ + { }, /* Terminating entry */ }; MODULE_DEVICE_TABLE(input, power_ids); diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 0300dca..a23aedc 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -155,7 +155,7 @@ static int tsdev_open(struct inode *inode, struct file *file) "for removal.\nSee Documentation/feature-removal-schedule.txt " "for details.\n"); - if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK]) + if (i >= TSDEV_MINORS) return -ENODEV; if (!(list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL))) @@ -246,14 +246,14 @@ static int tsdev_ioctl(struct inode *inode, struct file *file, switch (cmd) { case TS_GET_CAL: - if (copy_to_user ((void __user *)arg, &tsdev->cal, - sizeof (struct ts_calibration))) + if (copy_to_user((void __user *)arg, &tsdev->cal, + sizeof (struct ts_calibration))) retval = -EFAULT; break; case TS_SET_CAL: - if (copy_from_user (&tsdev->cal, (void __user *)arg, - sizeof (struct ts_calibration))) + if (copy_from_user(&tsdev->cal, (void __user *)arg, + sizeof (struct ts_calibration))) retval = -EFAULT; break; @@ -370,23 +370,25 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, wake_up_interruptible(&tsdev->wait); } -static struct input_handle *tsdev_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) +static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct tsdev *tsdev; struct class_device *cdev; + dev_t devt; int minor, delta; + int error; for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++); if (minor >= TSDEV_MINORS / 2) { printk(KERN_ERR "tsdev: You have way too many touchscreens\n"); - return NULL; + return -ENFILE; } - if (!(tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL))) - return NULL; + tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL); + if (!tsdev) + return -ENOMEM; INIT_LIST_HEAD(&tsdev->list); init_waitqueue_head(&tsdev->wait); @@ -415,15 +417,35 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, tsdev_table[minor] = tsdev; - cdev = class_device_create(&input_class, &dev->cdev, - MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), - dev->cdev.dev, tsdev->name); + devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), + + cdev = class_device_create(&input_class, &dev->cdev, devt, + dev->cdev.dev, tsdev->name); + if (IS_ERR(cdev)) { + error = PTR_ERR(cdev); + goto err_free_tsdev; + } /* temporary symlink to keep userspace happy */ - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, - tsdev->name); + error = sysfs_create_link(&input_class.subsys.kset.kobj, + &cdev->kobj, tsdev->name); + if (error) + goto err_cdev_destroy; - return &tsdev->handle; + error = input_register_handle(&tsdev->handle); + if (error) + goto err_remove_link; + + return 0; + + err_remove_link: + sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name); + err_cdev_destroy: + class_device_destroy(&input_class, devt); + err_free_tsdev: + tsdev_table[minor] = NULL; + kfree(tsdev); + return error; } static void tsdev_disconnect(struct input_handle *handle) @@ -431,6 +453,8 @@ static void tsdev_disconnect(struct input_handle *handle) struct tsdev *tsdev = handle->private; struct tsdev_list *list; + input_unregister_handle(handle); + sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); diff --git a/include/linux/input.h b/include/linux/input.h index 3a8b8c6..a51d6cf 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1049,7 +1049,7 @@ struct input_handler { void *private; void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); - struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); + int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); void (*disconnect)(struct input_handle *handle); void (*start)(struct input_handle *handle); @@ -1102,6 +1102,9 @@ void input_unregister_device(struct input_dev *); int input_register_handler(struct input_handler *); void input_unregister_handler(struct input_handler *); +int input_register_handle(struct input_handle *); +void input_unregister_handle(struct input_handle *); + int input_grab_device(struct input_handle *); void input_release_device(struct input_handle *); -- cgit v0.10.2 From d0ffb9be866519775da19c0a6790f5431c1a8dc6 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:30:00 -0400 Subject: Input: handlers - rename 'list' to 'client' The naming convention in input handlers was very confusing - client stuctures were called lists, regular lists were also called lists making anyone looking at the code go mad. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 840fa19..8a4cce5 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -29,11 +29,11 @@ struct evdev { char name[16]; struct input_handle handle; wait_queue_head_t wait; - struct evdev_list *grab; - struct list_head list; + struct evdev_client *grab; + struct list_head client_list; }; -struct evdev_list { +struct evdev_client { struct input_event buffer[EVDEV_BUFFER_SIZE]; int head; int tail; @@ -47,28 +47,28 @@ static struct evdev *evdev_table[EVDEV_MINORS]; static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { struct evdev *evdev = handle->private; - struct evdev_list *list; + struct evdev_client *client; if (evdev->grab) { - list = evdev->grab; + client = evdev->grab; - do_gettimeofday(&list->buffer[list->head].time); - list->buffer[list->head].type = type; - list->buffer[list->head].code = code; - list->buffer[list->head].value = value; - list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1); + do_gettimeofday(&client->buffer[client->head].time); + client->buffer[client->head].type = type; + client->buffer[client->head].code = code; + client->buffer[client->head].value = value; + client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1); - kill_fasync(&list->fasync, SIGIO, POLL_IN); + kill_fasync(&client->fasync, SIGIO, POLL_IN); } else - list_for_each_entry(list, &evdev->list, node) { + list_for_each_entry(client, &evdev->client_list, node) { - do_gettimeofday(&list->buffer[list->head].time); - list->buffer[list->head].type = type; - list->buffer[list->head].code = code; - list->buffer[list->head].value = value; - list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1); + do_gettimeofday(&client->buffer[client->head].time); + client->buffer[client->head].type = type; + client->buffer[client->head].code = code; + client->buffer[client->head].value = value; + client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1); - kill_fasync(&list->fasync, SIGIO, POLL_IN); + kill_fasync(&client->fasync, SIGIO, POLL_IN); } wake_up_interruptible(&evdev->wait); @@ -76,22 +76,23 @@ static void evdev_event(struct input_handle *handle, unsigned int type, unsigned static int evdev_fasync(int fd, struct file *file, int on) { + struct evdev_client *client = file->private_data; int retval; - struct evdev_list *list = file->private_data; - retval = fasync_helper(fd, file, on, &list->fasync); + retval = fasync_helper(fd, file, on, &client->fasync); return retval < 0 ? retval : 0; } static int evdev_flush(struct file *file, fl_owner_t id) { - struct evdev_list *list = file->private_data; + struct evdev_client *client = file->private_data; + struct evdev *evdev = client->evdev; - if (!list->evdev->exist) + if (!evdev->exist) return -ENODEV; - return input_flush_device(&list->evdev->handle, file); + return input_flush_device(&evdev->handle, file); } static void evdev_free(struct evdev *evdev) @@ -100,48 +101,55 @@ static void evdev_free(struct evdev *evdev) kfree(evdev); } -static int evdev_release(struct inode * inode, struct file * file) +static int evdev_release(struct inode *inode, struct file *file) { - struct evdev_list *list = file->private_data; + struct evdev_client *client = file->private_data; + struct evdev *evdev = client->evdev; - if (list->evdev->grab == list) { - input_release_device(&list->evdev->handle); - list->evdev->grab = NULL; + if (evdev->grab == client) { + input_release_device(&evdev->handle); + evdev->grab = NULL; } evdev_fasync(-1, file, 0); - list_del(&list->node); + list_del(&client->node); + kfree(client); - if (!--list->evdev->open) { - if (list->evdev->exist) - input_close_device(&list->evdev->handle); + if (!--evdev->open) { + if (evdev->exist) + input_close_device(&evdev->handle); else - evdev_free(list->evdev); + evdev_free(evdev); } - kfree(list); return 0; } -static int evdev_open(struct inode * inode, struct file * file) +static int evdev_open(struct inode *inode, struct file *file) { - struct evdev_list *list; + struct evdev_client *client; + struct evdev *evdev; int i = iminor(inode) - EVDEV_MINOR_BASE; - if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist) + if (i >= EVDEV_MINORS) + return -ENODEV; + + evdev = evdev_table[i]; + + if (!evdev || !evdev->exist) return -ENODEV; - if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL))) + client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); + if (!client) return -ENOMEM; - list->evdev = evdev_table[i]; - list_add_tail(&list->node, &evdev_table[i]->list); - file->private_data = list; + client->evdev = evdev; + list_add_tail(&client->node, &evdev->client_list); - if (!list->evdev->open++) - if (list->evdev->exist) - input_open_device(&list->evdev->handle); + if (!evdev->open++ && evdev->exist) + input_open_device(&evdev->handle); + file->private_data = client; return 0; } @@ -243,54 +251,55 @@ static int evdev_event_to_user(char __user *buffer, const struct input_event *ev #endif /* CONFIG_COMPAT */ -static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) +static ssize_t evdev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - struct evdev_list *list = file->private_data; + struct evdev_client *client = file->private_data; + struct evdev *evdev = client->evdev; struct input_event event; int retval = 0; - if (!list->evdev->exist) + if (!evdev->exist) return -ENODEV; while (retval < count) { if (evdev_event_from_user(buffer + retval, &event)) return -EFAULT; - input_inject_event(&list->evdev->handle, event.type, event.code, event.value); + input_inject_event(&evdev->handle, event.type, event.code, event.value); retval += evdev_event_size(); } return retval; } -static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) +static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - struct evdev_list *list = file->private_data; + struct evdev_client *client = file->private_data; + struct evdev *evdev = client->evdev; int retval; if (count < evdev_event_size()) return -EINVAL; - if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK)) + if (client->head == client->tail && evdev->exist && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(list->evdev->wait, - list->head != list->tail || (!list->evdev->exist)); - + retval = wait_event_interruptible(evdev->wait, + client->head != client->tail || !evdev->exist); if (retval) return retval; - if (!list->evdev->exist) + if (!evdev->exist) return -ENODEV; - while (list->head != list->tail && retval + evdev_event_size() <= count) { + while (client->head != client->tail && retval + evdev_event_size() <= count) { - struct input_event *event = (struct input_event *) list->buffer + list->tail; + struct input_event *event = (struct input_event *) client->buffer + client->tail; if (evdev_event_to_user(buffer + retval, event)) return -EFAULT; - list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1); + client->tail = (client->tail + 1) & (EVDEV_BUFFER_SIZE - 1); retval += evdev_event_size(); } @@ -300,11 +309,12 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count /* No kernel lock - fine */ static unsigned int evdev_poll(struct file *file, poll_table *wait) { - struct evdev_list *list = file->private_data; + struct evdev_client *client = file->private_data; + struct evdev *evdev = client->evdev; - poll_wait(file, &list->evdev->wait, wait); - return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | - (list->evdev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &evdev->wait, wait); + return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) | + (evdev->exist ? 0 : (POLLHUP | POLLERR)); } #ifdef CONFIG_COMPAT @@ -387,8 +397,8 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p) static long evdev_ioctl_handler(struct file *file, unsigned int cmd, void __user *p, int compat_mode) { - struct evdev_list *list = file->private_data; - struct evdev *evdev = list->evdev; + struct evdev_client *client = file->private_data; + struct evdev *evdev = client->evdev; struct input_dev *dev = evdev->handle.dev; struct input_absinfo abs; struct ff_effect effect; @@ -476,10 +486,10 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, return -EBUSY; if (input_grab_device(&evdev->handle)) return -EBUSY; - evdev->grab = list; + evdev->grab = client; return 0; } else { - if (evdev->grab != list) + if (evdev->grab != client) return -EINVAL; input_release_device(&evdev->handle); evdev->grab = NULL; @@ -624,7 +634,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, if (!evdev) return -ENOMEM; - INIT_LIST_HEAD(&evdev->list); + INIT_LIST_HEAD(&evdev->client_list); init_waitqueue_head(&evdev->wait); evdev->exist = 1; @@ -671,7 +681,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, static void evdev_disconnect(struct input_handle *handle) { struct evdev *evdev = handle->private; - struct evdev_list *list; + struct evdev_client *client; input_unregister_handle(handle); @@ -684,8 +694,8 @@ static void evdev_disconnect(struct input_handle *handle) input_flush_device(handle, NULL); input_close_device(handle); wake_up_interruptible(&evdev->wait); - list_for_each_entry(list, &evdev->list, node) - kill_fasync(&list->fasync, SIGIO, POLL_HUP); + list_for_each_entry(client, &evdev->client_list, node) + kill_fasync(&client->fasync, SIGIO, POLL_HUP); } else evdev_free(evdev); } diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index cf24a5b..09b8223 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -43,7 +43,7 @@ struct joydev { char name[16]; struct input_handle handle; wait_queue_head_t wait; - struct list_head list; + struct list_head client_list; struct js_corr corr[ABS_MAX + 1]; struct JS_DATA_SAVE_TYPE glue; int nabs; @@ -55,7 +55,7 @@ struct joydev { __s16 abs[ABS_MAX + 1]; }; -struct joydev_list { +struct joydev_client { struct js_event buffer[JOYDEV_BUFFER_SIZE]; int head; int tail; @@ -87,7 +87,7 @@ static int joydev_correct(int value, struct js_corr *corr) static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { struct joydev *joydev = handle->private; - struct joydev_list *list; + struct joydev_client *client; struct js_event event; switch (type) { @@ -115,15 +115,15 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne event.time = jiffies_to_msecs(jiffies); - list_for_each_entry(list, &joydev->list, node) { + list_for_each_entry(client, &joydev->client_list, node) { - memcpy(list->buffer + list->head, &event, sizeof(struct js_event)); + memcpy(client->buffer + client->head, &event, sizeof(struct js_event)); - if (list->startup == joydev->nabs + joydev->nkey) - if (list->tail == (list->head = (list->head + 1) & (JOYDEV_BUFFER_SIZE - 1))) - list->startup = 0; + if (client->startup == joydev->nabs + joydev->nkey) + if (client->tail == (client->head = (client->head + 1) & (JOYDEV_BUFFER_SIZE - 1))) + client->startup = 0; - kill_fasync(&list->fasync, SIGIO, POLL_IN); + kill_fasync(&client->fasync, SIGIO, POLL_IN); } wake_up_interruptible(&joydev->wait); @@ -132,9 +132,9 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne static int joydev_fasync(int fd, struct file *file, int on) { int retval; - struct joydev_list *list = file->private_data; + struct joydev_client *client = file->private_data; - retval = fasync_helper(fd, file, on, &list->fasync); + retval = fasync_helper(fd, file, on, &client->fasync); return retval < 0 ? retval : 0; } @@ -145,60 +145,66 @@ static void joydev_free(struct joydev *joydev) kfree(joydev); } -static int joydev_release(struct inode * inode, struct file * file) +static int joydev_release(struct inode *inode, struct file *file) { - struct joydev_list *list = file->private_data; + struct joydev_client *client = file->private_data; + struct joydev *joydev = client->joydev; joydev_fasync(-1, file, 0); - list_del(&list->node); + list_del(&client->node); + kfree(client); - if (!--list->joydev->open) { - if (list->joydev->exist) - input_close_device(&list->joydev->handle); + if (!--joydev->open) { + if (joydev->exist) + input_close_device(&joydev->handle); else - joydev_free(list->joydev); + joydev_free(joydev); } - kfree(list); return 0; } static int joydev_open(struct inode *inode, struct file *file) { - struct joydev_list *list; + struct joydev_client *client; + struct joydev *joydev; int i = iminor(inode) - JOYDEV_MINOR_BASE; - if (i >= JOYDEV_MINORS || !joydev_table[i]) + if (i >= JOYDEV_MINORS) + return -ENODEV; + + joydev = joydev_table[i]; + if (!joydev || !joydev->exist) return -ENODEV; - if (!(list = kzalloc(sizeof(struct joydev_list), GFP_KERNEL))) + client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); + if (!client) return -ENOMEM; - list->joydev = joydev_table[i]; - list_add_tail(&list->node, &joydev_table[i]->list); - file->private_data = list; + client->joydev = joydev; + list_add_tail(&client->node, &joydev->client_list); - if (!list->joydev->open++) - if (list->joydev->exist) - input_open_device(&list->joydev->handle); + if (!joydev->open++ && joydev->exist) + input_open_device(&joydev->handle); + file->private_data = client; return 0; } -static ssize_t joydev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) +static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { return -EINVAL; } static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct joydev_list *list = file->private_data; - struct joydev *joydev = list->joydev; + struct joydev_client *client = file->private_data; + struct joydev *joydev = client->joydev; struct input_dev *input = joydev->handle.dev; int retval = 0; - if (!list->joydev->exist) + if (!joydev->exist) return -ENODEV; if (count < sizeof(struct js_event)) @@ -217,56 +223,55 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE))) return -EFAULT; - list->startup = 0; - list->tail = list->head; + client->startup = 0; + client->tail = client->head; return sizeof(struct JS_DATA_TYPE); } - if (list->startup == joydev->nabs + joydev->nkey && - list->head == list->tail && (file->f_flags & O_NONBLOCK)) + if (client->startup == joydev->nabs + joydev->nkey && + client->head == client->tail && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(list->joydev->wait, - !list->joydev->exist || - list->startup < joydev->nabs + joydev->nkey || - list->head != list->tail); - + retval = wait_event_interruptible(joydev->wait, + !joydev->exist || + client->startup < joydev->nabs + joydev->nkey || + client->head != client->tail); if (retval) return retval; - if (!list->joydev->exist) + if (!joydev->exist) return -ENODEV; - while (list->startup < joydev->nabs + joydev->nkey && retval + sizeof(struct js_event) <= count) { + while (client->startup < joydev->nabs + joydev->nkey && retval + sizeof(struct js_event) <= count) { struct js_event event; event.time = jiffies_to_msecs(jiffies); - if (list->startup < joydev->nkey) { + if (client->startup < joydev->nkey) { event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; - event.number = list->startup; + event.number = client->startup; event.value = !!test_bit(joydev->keypam[event.number], input->key); } else { event.type = JS_EVENT_AXIS | JS_EVENT_INIT; - event.number = list->startup - joydev->nkey; + event.number = client->startup - joydev->nkey; event.value = joydev->abs[event.number]; } if (copy_to_user(buf + retval, &event, sizeof(struct js_event))) return -EFAULT; - list->startup++; + client->startup++; retval += sizeof(struct js_event); } - while (list->head != list->tail && retval + sizeof(struct js_event) <= count) { + while (client->head != client->tail && retval + sizeof(struct js_event) <= count) { - if (copy_to_user(buf + retval, list->buffer + list->tail, sizeof(struct js_event))) + if (copy_to_user(buf + retval, client->buffer + client->tail, sizeof(struct js_event))) return -EFAULT; - list->tail = (list->tail + 1) & (JOYDEV_BUFFER_SIZE - 1); + client->tail = (client->tail + 1) & (JOYDEV_BUFFER_SIZE - 1); retval += sizeof(struct js_event); } @@ -276,11 +281,12 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo /* No kernel lock - fine */ static unsigned int joydev_poll(struct file *file, poll_table *wait) { - struct joydev_list *list = file->private_data; + struct joydev_client *client = file->private_data; + struct joydev *joydev = client->joydev; - poll_wait(file, &list->joydev->wait, wait); - return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ? - (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &joydev->wait, wait); + return ((client->head != client->tail || client->startup < joydev->nabs + joydev->nkey) ? + (POLLIN | POLLRDNORM) : 0) | (joydev->exist ? 0 : (POLLHUP | POLLERR)); } static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp) @@ -374,8 +380,8 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u #ifdef CONFIG_COMPAT static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct joydev_list *list = file->private_data; - struct joydev *joydev = list->joydev; + struct joydev_client *client = file->private_data; + struct joydev *joydev = client->joydev; void __user *argp = (void __user *)arg; s32 tmp32; struct JS_DATA_SAVE_TYPE_32 ds32; @@ -428,8 +434,8 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct joydev_list *list = file->private_data; - struct joydev *joydev = list->joydev; + struct joydev_client *client = file->private_data; + struct joydev *joydev = client->joydev; void __user *argp = (void __user *)arg; if (!joydev->exist) @@ -484,7 +490,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, if (!joydev) return -ENOMEM; - INIT_LIST_HEAD(&joydev->list); + INIT_LIST_HEAD(&joydev->client_list); init_waitqueue_head(&joydev->wait); joydev->minor = minor; @@ -572,7 +578,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, static void joydev_disconnect(struct input_handle *handle) { struct joydev *joydev = handle->private; - struct joydev_list *list; + struct joydev_client *client; input_unregister_handle(handle); @@ -583,8 +589,8 @@ static void joydev_disconnect(struct input_handle *handle) if (joydev->open) { input_close_device(handle); wake_up_interruptible(&joydev->wait); - list_for_each_entry(list, &joydev->list, node) - kill_fasync(&list->fasync, SIGIO, POLL_HUP); + list_for_each_entry(client, &joydev->client_list, node) + kill_fasync(&client->fasync, SIGIO, POLL_HUP); } else joydev_free(joydev); } diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 007e72f..f6a6268 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -63,7 +63,7 @@ struct mousedev { int minor; char name[16]; wait_queue_head_t wait; - struct list_head list; + struct list_head client_list; struct input_handle handle; struct mousedev_hw_data packet; @@ -85,7 +85,7 @@ struct mousedev_motion { }; #define PACKET_QUEUE_LEN 16 -struct mousedev_list { +struct mousedev_client { struct fasync_struct *fasync; struct mousedev *mousedev; struct list_head node; @@ -223,47 +223,47 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_hw_data *packet) { - struct mousedev_list *list; + struct mousedev_client *client; struct mousedev_motion *p; unsigned long flags; int wake_readers = 0; - list_for_each_entry(list, &mousedev->list, node) { - spin_lock_irqsave(&list->packet_lock, flags); + list_for_each_entry(client, &mousedev->client_list, node) { + spin_lock_irqsave(&client->packet_lock, flags); - p = &list->packets[list->head]; - if (list->ready && p->buttons != mousedev->packet.buttons) { - unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN; - if (new_head != list->tail) { - p = &list->packets[list->head = new_head]; + p = &client->packets[client->head]; + if (client->ready && p->buttons != mousedev->packet.buttons) { + unsigned int new_head = (client->head + 1) % PACKET_QUEUE_LEN; + if (new_head != client->tail) { + p = &client->packets[client->head = new_head]; memset(p, 0, sizeof(struct mousedev_motion)); } } if (packet->abs_event) { - p->dx += packet->x - list->pos_x; - p->dy += packet->y - list->pos_y; - list->pos_x = packet->x; - list->pos_y = packet->y; + p->dx += packet->x - client->pos_x; + p->dy += packet->y - client->pos_y; + client->pos_x = packet->x; + client->pos_y = packet->y; } - list->pos_x += packet->dx; - list->pos_x = list->pos_x < 0 ? 0 : (list->pos_x >= xres ? xres : list->pos_x); - list->pos_y += packet->dy; - list->pos_y = list->pos_y < 0 ? 0 : (list->pos_y >= yres ? yres : list->pos_y); + client->pos_x += packet->dx; + client->pos_x = client->pos_x < 0 ? 0 : (client->pos_x >= xres ? xres : client->pos_x); + client->pos_y += packet->dy; + client->pos_y = client->pos_y < 0 ? 0 : (client->pos_y >= yres ? yres : client->pos_y); p->dx += packet->dx; p->dy += packet->dy; p->dz += packet->dz; p->buttons = mousedev->packet.buttons; - if (p->dx || p->dy || p->dz || p->buttons != list->last_buttons) - list->ready = 1; + if (p->dx || p->dy || p->dz || p->buttons != client->last_buttons) + client->ready = 1; - spin_unlock_irqrestore(&list->packet_lock, flags); + spin_unlock_irqrestore(&client->packet_lock, flags); - if (list->ready) { - kill_fasync(&list->fasync, SIGIO, POLL_IN); + if (client->ready) { + kill_fasync(&client->fasync, SIGIO, POLL_IN); wake_readers = 1; } } @@ -351,9 +351,9 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig static int mousedev_fasync(int fd, struct file *file, int on) { int retval; - struct mousedev_list *list = file->private_data; + struct mousedev_client *client = file->private_data; - retval = fasync_helper(fd, file, on, &list->fasync); + retval = fasync_helper(fd, file, on, &client->fasync); return retval < 0 ? retval : 0; } @@ -380,32 +380,33 @@ static void mixdev_release(void) } } -static int mousedev_release(struct inode * inode, struct file * file) +static int mousedev_release(struct inode *inode, struct file *file) { - struct mousedev_list *list = file->private_data; + struct mousedev_client *client = file->private_data; + struct mousedev *mousedev = client->mousedev; mousedev_fasync(-1, file, 0); - list_del(&list->node); + list_del(&client->node); + kfree(client); - if (!--list->mousedev->open) { - if (list->mousedev->minor == MOUSEDEV_MIX) + if (!--mousedev->open) { + if (mousedev->minor == MOUSEDEV_MIX) mixdev_release(); else if (!mousedev_mix.open) { - if (list->mousedev->exist) - input_close_device(&list->mousedev->handle); + if (mousedev->exist) + input_close_device(&mousedev->handle); else - mousedev_free(list->mousedev); + mousedev_free(mousedev); } } - kfree(list); return 0; } -static int mousedev_open(struct inode * inode, struct file * file) +static int mousedev_open(struct inode *inode, struct file *file) { - struct mousedev_list *list; + struct mousedev_client *client; struct input_handle *handle; struct mousedev *mousedev; int i; @@ -417,31 +418,36 @@ static int mousedev_open(struct inode * inode, struct file * file) #endif i = iminor(inode) - MOUSEDEV_MINOR_BASE; - if (i >= MOUSEDEV_MINORS || !mousedev_table[i]) + if (i >= MOUSEDEV_MINORS) + return -ENODEV; + + mousedev = mousedev_table[i]; + if (!mousedev) return -ENODEV; - if (!(list = kzalloc(sizeof(struct mousedev_list), GFP_KERNEL))) + client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); + if (!client) return -ENOMEM; - spin_lock_init(&list->packet_lock); - list->pos_x = xres / 2; - list->pos_y = yres / 2; - list->mousedev = mousedev_table[i]; - list_add_tail(&list->node, &mousedev_table[i]->list); - file->private_data = list; + spin_lock_init(&client->packet_lock); + client->pos_x = xres / 2; + client->pos_y = yres / 2; + client->mousedev = mousedev; + list_add_tail(&client->node, &mousedev->client_list); - if (!list->mousedev->open++) { - if (list->mousedev->minor == MOUSEDEV_MIX) { + if (!mousedev->open++) { + if (mousedev->minor == MOUSEDEV_MIX) { list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { - mousedev = handle->private; - if (!mousedev->open && mousedev->exist) + struct mousedev *md = handle->private; + if (!md->open && md->exist) input_open_device(handle); } } else - if (!mousedev_mix.open && list->mousedev->exist) - input_open_device(&list->mousedev->handle); + if (!mousedev_mix.open && mousedev->exist) + input_open_device(&mousedev->handle); } + file->private_data = client; return 0; } @@ -450,13 +456,13 @@ static inline int mousedev_limit_delta(int delta, int limit) return delta > limit ? limit : (delta < -limit ? -limit : delta); } -static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data) +static void mousedev_packet(struct mousedev_client *client, signed char *ps2_data) { struct mousedev_motion *p; unsigned long flags; - spin_lock_irqsave(&list->packet_lock, flags); - p = &list->packets[list->tail]; + spin_lock_irqsave(&client->packet_lock, flags); + p = &client->packets[client->tail]; ps2_data[0] = 0x08 | ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07); ps2_data[1] = mousedev_limit_delta(p->dx, 127); @@ -464,44 +470,44 @@ static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data) p->dx -= ps2_data[1]; p->dy -= ps2_data[2]; - switch (list->mode) { + switch (client->mode) { case MOUSEDEV_EMUL_EXPS: ps2_data[3] = mousedev_limit_delta(p->dz, 7); p->dz -= ps2_data[3]; ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1); - list->bufsiz = 4; + client->bufsiz = 4; break; case MOUSEDEV_EMUL_IMPS: ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); ps2_data[3] = mousedev_limit_delta(p->dz, 127); p->dz -= ps2_data[3]; - list->bufsiz = 4; + client->bufsiz = 4; break; case MOUSEDEV_EMUL_PS2: default: ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); p->dz = 0; - list->bufsiz = 3; + client->bufsiz = 3; break; } if (!p->dx && !p->dy && !p->dz) { - if (list->tail == list->head) { - list->ready = 0; - list->last_buttons = p->buttons; + if (client->tail == client->head) { + client->ready = 0; + client->last_buttons = p->buttons; } else - list->tail = (list->tail + 1) % PACKET_QUEUE_LEN; + client->tail = (client->tail + 1) % PACKET_QUEUE_LEN; } - spin_unlock_irqrestore(&list->packet_lock, flags); + spin_unlock_irqrestore(&client->packet_lock, flags); } -static ssize_t mousedev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) +static ssize_t mousedev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - struct mousedev_list *list = file->private_data; + struct mousedev_client *client = file->private_data; unsigned char c; unsigned int i; @@ -510,95 +516,95 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si if (get_user(c, buffer + i)) return -EFAULT; - if (c == mousedev_imex_seq[list->imexseq]) { - if (++list->imexseq == MOUSEDEV_SEQ_LEN) { - list->imexseq = 0; - list->mode = MOUSEDEV_EMUL_EXPS; + if (c == mousedev_imex_seq[client->imexseq]) { + if (++client->imexseq == MOUSEDEV_SEQ_LEN) { + client->imexseq = 0; + client->mode = MOUSEDEV_EMUL_EXPS; } } else - list->imexseq = 0; + client->imexseq = 0; - if (c == mousedev_imps_seq[list->impsseq]) { - if (++list->impsseq == MOUSEDEV_SEQ_LEN) { - list->impsseq = 0; - list->mode = MOUSEDEV_EMUL_IMPS; + if (c == mousedev_imps_seq[client->impsseq]) { + if (++client->impsseq == MOUSEDEV_SEQ_LEN) { + client->impsseq = 0; + client->mode = MOUSEDEV_EMUL_IMPS; } } else - list->impsseq = 0; + client->impsseq = 0; - list->ps2[0] = 0xfa; + client->ps2[0] = 0xfa; switch (c) { case 0xeb: /* Poll */ - mousedev_packet(list, &list->ps2[1]); - list->bufsiz++; /* account for leading ACK */ + mousedev_packet(client, &client->ps2[1]); + client->bufsiz++; /* account for leading ACK */ break; case 0xf2: /* Get ID */ - switch (list->mode) { - case MOUSEDEV_EMUL_PS2: list->ps2[1] = 0; break; - case MOUSEDEV_EMUL_IMPS: list->ps2[1] = 3; break; - case MOUSEDEV_EMUL_EXPS: list->ps2[1] = 4; break; + switch (client->mode) { + case MOUSEDEV_EMUL_PS2: client->ps2[1] = 0; break; + case MOUSEDEV_EMUL_IMPS: client->ps2[1] = 3; break; + case MOUSEDEV_EMUL_EXPS: client->ps2[1] = 4; break; } - list->bufsiz = 2; + client->bufsiz = 2; break; case 0xe9: /* Get info */ - list->ps2[1] = 0x60; list->ps2[2] = 3; list->ps2[3] = 200; - list->bufsiz = 4; + client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200; + client->bufsiz = 4; break; case 0xff: /* Reset */ - list->impsseq = list->imexseq = 0; - list->mode = MOUSEDEV_EMUL_PS2; - list->ps2[1] = 0xaa; list->ps2[2] = 0x00; - list->bufsiz = 3; + client->impsseq = client->imexseq = 0; + client->mode = MOUSEDEV_EMUL_PS2; + client->ps2[1] = 0xaa; client->ps2[2] = 0x00; + client->bufsiz = 3; break; default: - list->bufsiz = 1; + client->bufsiz = 1; break; } - list->buffer = list->bufsiz; + client->buffer = client->bufsiz; } - kill_fasync(&list->fasync, SIGIO, POLL_IN); + kill_fasync(&client->fasync, SIGIO, POLL_IN); - wake_up_interruptible(&list->mousedev->wait); + wake_up_interruptible(&client->mousedev->wait); return count; } -static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) +static ssize_t mousedev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - struct mousedev_list *list = file->private_data; + struct mousedev_client *client = file->private_data; int retval = 0; - if (!list->ready && !list->buffer && (file->f_flags & O_NONBLOCK)) + if (!client->ready && !client->buffer && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(list->mousedev->wait, - !list->mousedev->exist || list->ready || list->buffer); + retval = wait_event_interruptible(client->mousedev->wait, + !client->mousedev->exist || client->ready || client->buffer); if (retval) return retval; - if (!list->mousedev->exist) + if (!client->mousedev->exist) return -ENODEV; - if (!list->buffer && list->ready) { - mousedev_packet(list, list->ps2); - list->buffer = list->bufsiz; + if (!client->buffer && client->ready) { + mousedev_packet(client, client->ps2); + client->buffer = client->bufsiz; } - if (count > list->buffer) - count = list->buffer; + if (count > client->buffer) + count = client->buffer; - list->buffer -= count; + client->buffer -= count; - if (copy_to_user(buffer, list->ps2 + list->bufsiz - list->buffer - count, count)) + if (copy_to_user(buffer, client->ps2 + client->bufsiz - client->buffer - count, count)) return -EFAULT; return count; @@ -607,11 +613,12 @@ static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t co /* No kernel lock - fine */ static unsigned int mousedev_poll(struct file *file, poll_table *wait) { - struct mousedev_list *list = file->private_data; + struct mousedev_client *client = file->private_data; + struct mousedev *mousedev = client->mousedev; - poll_wait(file, &list->mousedev->wait, wait); - return ((list->ready || list->buffer) ? (POLLIN | POLLRDNORM) : 0) | - (list->mousedev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &mousedev->wait, wait); + return ((client->ready || client->buffer) ? (POLLIN | POLLRDNORM) : 0) | + (mousedev->exist ? 0 : (POLLHUP | POLLERR)); } static const struct file_operations mousedev_fops = { @@ -643,7 +650,7 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev if (!mousedev) return -ENOMEM; - INIT_LIST_HEAD(&mousedev->list); + INIT_LIST_HEAD(&mousedev->client_list); INIT_LIST_HEAD(&mousedev->mixdev_node); init_waitqueue_head(&mousedev->wait); @@ -699,7 +706,7 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev static void mousedev_disconnect(struct input_handle *handle) { struct mousedev *mousedev = handle->private; - struct mousedev_list *list; + struct mousedev_client *client; input_unregister_handle(handle); @@ -711,8 +718,8 @@ static void mousedev_disconnect(struct input_handle *handle) if (mousedev->open) { input_close_device(handle); wake_up_interruptible(&mousedev->wait); - list_for_each_entry(list, &mousedev->list, node) - kill_fasync(&list->fasync, SIGIO, POLL_HUP); + list_for_each_entry(client, &mousedev->client_list, node) + kill_fasync(&client->fasync, SIGIO, POLL_HUP); } else { if (mousedev_mix.open) input_close_device(handle); @@ -745,7 +752,7 @@ static const struct input_device_id mousedev_ids[] = { .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_TOOL_WIDTH) }, }, /* A touchpad */ - { }, /* Terminating entry */ + { }, /* Terminating entry */ }; MODULE_DEVICE_TABLE(input, mousedev_ids); @@ -777,7 +784,7 @@ static int __init mousedev_init(void) return error; memset(&mousedev_mix, 0, sizeof(struct mousedev)); - INIT_LIST_HEAD(&mousedev_mix.list); + INIT_LIST_HEAD(&mousedev_mix.client_list); init_waitqueue_head(&mousedev_mix.wait); mousedev_table[MOUSEDEV_MIX] = &mousedev_mix; mousedev_mix.exist = 1; diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index a23aedc..fbef35d 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -111,13 +111,13 @@ struct tsdev { int minor; char name[8]; wait_queue_head_t wait; - struct list_head list; + struct list_head client_list; struct input_handle handle; int x, y, pressure; struct ts_calibration cal; }; -struct tsdev_list { +struct tsdev_client { struct fasync_struct *fasync; struct list_head node; struct tsdev *tsdev; @@ -139,17 +139,18 @@ static struct tsdev *tsdev_table[TSDEV_MINORS/2]; static int tsdev_fasync(int fd, struct file *file, int on) { - struct tsdev_list *list = file->private_data; + struct tsdev_client *client = file->private_data; int retval; - retval = fasync_helper(fd, file, on, &list->fasync); + retval = fasync_helper(fd, file, on, &client->fasync); return retval < 0 ? retval : 0; } static int tsdev_open(struct inode *inode, struct file *file) { int i = iminor(inode) - TSDEV_MINOR_BASE; - struct tsdev_list *list; + struct tsdev_client *client; + struct tsdev *tsdev; printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled " "for removal.\nSee Documentation/feature-removal-schedule.txt " @@ -158,19 +159,22 @@ static int tsdev_open(struct inode *inode, struct file *file) if (i >= TSDEV_MINORS) return -ENODEV; - if (!(list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL))) + tsdev = tsdev_table[i & TSDEV_MINOR_MASK]; + if (!tsdev || !tsdev->exist) + return -ENODEV; + + client = kzalloc(sizeof(struct tsdev_client), GFP_KERNEL); + if (!client) return -ENOMEM; - list->raw = (i >= TSDEV_MINORS/2) ? 1 : 0; + client->tsdev = tsdev; + client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0; + list_add_tail(&client->node, &tsdev->client_list); - i &= TSDEV_MINOR_MASK; - list->tsdev = tsdev_table[i]; - list_add_tail(&list->node, &tsdev_table[i]->list); - file->private_data = list; + if (!tsdev->open++ && tsdev->exist) + input_open_device(&tsdev->handle); - if (!list->tsdev->open++) - if (list->tsdev->exist) - input_open_device(&list->tsdev->handle); + file->private_data = client; return 0; } @@ -182,45 +186,48 @@ static void tsdev_free(struct tsdev *tsdev) static int tsdev_release(struct inode *inode, struct file *file) { - struct tsdev_list *list = file->private_data; + struct tsdev_client *client = file->private_data; + struct tsdev *tsdev = client->tsdev; tsdev_fasync(-1, file, 0); - list_del(&list->node); - if (!--list->tsdev->open) { - if (list->tsdev->exist) - input_close_device(&list->tsdev->handle); + list_del(&client->node); + kfree(client); + + if (!--tsdev->open) { + if (tsdev->exist) + input_close_device(&tsdev->handle); else - tsdev_free(list->tsdev); + tsdev_free(tsdev); } - kfree(list); + return 0; } static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, - loff_t * ppos) + loff_t *ppos) { - struct tsdev_list *list = file->private_data; + struct tsdev_client *client = file->private_data; + struct tsdev *tsdev = client->tsdev; int retval = 0; - if (list->head == list->tail && list->tsdev->exist && (file->f_flags & O_NONBLOCK)) + if (client->head == client->tail && tsdev->exist && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(list->tsdev->wait, - list->head != list->tail || !list->tsdev->exist); - + retval = wait_event_interruptible(tsdev->wait, + client->head != client->tail || !tsdev->exist); if (retval) return retval; - if (!list->tsdev->exist) + if (!tsdev->exist) return -ENODEV; - while (list->head != list->tail && + while (client->head != client->tail && retval + sizeof (struct ts_event) <= count) { - if (copy_to_user (buffer + retval, list->event + list->tail, + if (copy_to_user (buffer + retval, client->event + client->tail, sizeof (struct ts_event))) return -EFAULT; - list->tail = (list->tail + 1) & (TSDEV_BUFFER_SIZE - 1); + client->tail = (client->tail + 1) & (TSDEV_BUFFER_SIZE - 1); retval += sizeof (struct ts_event); } @@ -228,20 +235,21 @@ static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, } /* No kernel lock - fine */ -static unsigned int tsdev_poll(struct file *file, poll_table * wait) +static unsigned int tsdev_poll(struct file *file, poll_table *wait) { - struct tsdev_list *list = file->private_data; + struct tsdev_client *client = file->private_data; + struct tsdev *tsdev = client->tsdev; - poll_wait(file, &list->tsdev->wait, wait); - return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | - (list->tsdev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &tsdev->wait, wait); + return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) | + (tsdev->exist ? 0 : (POLLHUP | POLLERR)); } static int tsdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct tsdev_list *list = file->private_data; - struct tsdev *tsdev = list->tsdev; + struct tsdev_client *client = file->private_data; + struct tsdev *tsdev = client->tsdev; int retval = 0; switch (cmd) { @@ -279,7 +287,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { struct tsdev *tsdev = handle->private; - struct tsdev_list *list; + struct tsdev_client *client; struct timeval time; switch (type) { @@ -343,18 +351,18 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, if (type != EV_SYN || code != SYN_REPORT) return; - list_for_each_entry(list, &tsdev->list, node) { + list_for_each_entry(client, &tsdev->client_list, node) { int x, y, tmp; do_gettimeofday(&time); - list->event[list->head].millisecs = time.tv_usec / 100; - list->event[list->head].pressure = tsdev->pressure; + client->event[client->head].millisecs = time.tv_usec / 100; + client->event[client->head].pressure = tsdev->pressure; x = tsdev->x; y = tsdev->y; /* Calibration */ - if (!list->raw) { + if (!client->raw) { x = ((x * tsdev->cal.xscale) >> 8) + tsdev->cal.xtrans; y = ((y * tsdev->cal.yscale) >> 8) + tsdev->cal.ytrans; if (tsdev->cal.xyswap) { @@ -362,10 +370,10 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, } } - list->event[list->head].x = x; - list->event[list->head].y = y; - list->head = (list->head + 1) & (TSDEV_BUFFER_SIZE - 1); - kill_fasync(&list->fasync, SIGIO, POLL_IN); + client->event[client->head].x = x; + client->event[client->head].y = y; + client->head = (client->head + 1) & (TSDEV_BUFFER_SIZE - 1); + kill_fasync(&client->fasync, SIGIO, POLL_IN); } wake_up_interruptible(&tsdev->wait); } @@ -390,7 +398,7 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, if (!tsdev) return -ENOMEM; - INIT_LIST_HEAD(&tsdev->list); + INIT_LIST_HEAD(&tsdev->client_list); init_waitqueue_head(&tsdev->wait); sprintf(tsdev->name, "ts%d", minor); @@ -451,7 +459,7 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, static void tsdev_disconnect(struct input_handle *handle) { struct tsdev *tsdev = handle->private; - struct tsdev_list *list; + struct tsdev_client *client; input_unregister_handle(handle); @@ -463,8 +471,8 @@ static void tsdev_disconnect(struct input_handle *handle) if (tsdev->open) { input_close_device(handle); wake_up_interruptible(&tsdev->wait); - list_for_each_entry(list, &tsdev->list, node) - kill_fasync(&list->fasync, SIGIO, POLL_HUP); + list_for_each_entry(client, &tsdev->client_list, node) + kill_fasync(&client->fasync, SIGIO, POLL_HUP); } else tsdev_free(tsdev); } -- cgit v0.10.2 From d542ed82fdc72cf63549deec19e86ee4addf2499 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:30:15 -0400 Subject: Input: handlers - handle errors from input_open_device() Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 8a4cce5..6cff809 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -130,6 +130,7 @@ static int evdev_open(struct inode *inode, struct file *file) struct evdev_client *client; struct evdev *evdev; int i = iminor(inode) - EVDEV_MINOR_BASE; + int error; if (i >= EVDEV_MINORS) return -ENODEV; @@ -146,8 +147,14 @@ static int evdev_open(struct inode *inode, struct file *file) client->evdev = evdev; list_add_tail(&client->node, &evdev->client_list); - if (!evdev->open++ && evdev->exist) - input_open_device(&evdev->handle); + if (!evdev->open++ && evdev->exist) { + error = input_open_device(&evdev->handle); + if (error) { + list_del(&client->node); + kfree(client); + return error; + } + } file->private_data = client; return 0; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 09b8223..4f37224 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -170,6 +170,7 @@ static int joydev_open(struct inode *inode, struct file *file) struct joydev_client *client; struct joydev *joydev; int i = iminor(inode) - JOYDEV_MINOR_BASE; + int error; if (i >= JOYDEV_MINORS) return -ENODEV; @@ -185,8 +186,14 @@ static int joydev_open(struct inode *inode, struct file *file) client->joydev = joydev; list_add_tail(&client->node, &joydev->client_list); - if (!joydev->open++ && joydev->exist) - input_open_device(&joydev->handle); + if (!joydev->open++ && joydev->exist) { + error = input_open_device(&joydev->handle); + if (error) { + list_del(&client->node); + kfree(client); + return error; + } + } file->private_data = client; return 0; diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index f6a6268..764970f 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -66,6 +66,9 @@ struct mousedev { struct list_head client_list; struct input_handle handle; + struct list_head mixdev_node; + int mixdev_open; + struct mousedev_hw_data packet; unsigned int pkt_count; int old_x[4], old_y[4]; @@ -111,6 +114,7 @@ static struct input_handler mousedev_handler; static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; static struct mousedev mousedev_mix; +static LIST_HEAD(mousedev_mix_list); #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) @@ -364,18 +368,63 @@ static void mousedev_free(struct mousedev *mousedev) kfree(mousedev); } -static void mixdev_release(void) +static int mixdev_add_device(struct mousedev *mousedev) { - struct input_handle *handle; + int error; - list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { - struct mousedev *mousedev = handle->private; + if (mousedev_mix.open) { + error = input_open_device(&mousedev->handle); + if (error) + return error; - if (!mousedev->open) { - if (mousedev->exist) - input_close_device(&mousedev->handle); - else - mousedev_free(mousedev); + mousedev->open++; + mousedev->mixdev_open++; + } + + list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); + + return 0; +} + +static void mixdev_remove_device(struct mousedev *mousedev) +{ + if (mousedev->mixdev_open) { + mousedev->mixdev_open = 0; + if (!--mousedev->open && mousedev->exist) + input_close_device(&mousedev->handle); + } + + list_del_init(&mousedev->mixdev_node); +} + +static void mixdev_open_devices(void) +{ + struct mousedev *mousedev; + + list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { + if (mousedev->exist && !mousedev->open) { + if (input_open_device(&mousedev->handle)) + continue; + + mousedev->open++; + mousedev->mixdev_open++; + } + } +} + +static void mixdev_close_devices(void) +{ + struct mousedev *mousedev, *next; + + list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) { + if (mousedev->mixdev_open) { + mousedev->mixdev_open = 0; + if (!--mousedev->open) { + if (mousedev->exist) + input_close_device(&mousedev->handle); + else + mousedev_free(mousedev); + } } } } @@ -392,23 +441,22 @@ static int mousedev_release(struct inode *inode, struct file *file) if (!--mousedev->open) { if (mousedev->minor == MOUSEDEV_MIX) - mixdev_release(); - else if (!mousedev_mix.open) { - if (mousedev->exist) - input_close_device(&mousedev->handle); - else - mousedev_free(mousedev); - } + mixdev_close_devices(); + else if (mousedev->exist) + input_close_device(&mousedev->handle); + else + mousedev_free(mousedev); } return 0; } + static int mousedev_open(struct inode *inode, struct file *file) { struct mousedev_client *client; - struct input_handle *handle; struct mousedev *mousedev; + int error; int i; #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX @@ -436,15 +484,16 @@ static int mousedev_open(struct inode *inode, struct file *file) list_add_tail(&client->node, &mousedev->client_list); if (!mousedev->open++) { - if (mousedev->minor == MOUSEDEV_MIX) { - list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { - struct mousedev *md = handle->private; - if (!md->open && md->exist) - input_open_device(handle); + if (mousedev->minor == MOUSEDEV_MIX) + mixdev_open_devices(); + else if (mousedev->exist) { + error = input_open_device(&mousedev->handle); + if (error) { + list_del(&client->node); + kfree(client); + return error; } - } else - if (!mousedev_mix.open && mousedev->exist) - input_open_device(&mousedev->handle); + } } file->private_data = client; @@ -683,11 +732,9 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev if (error) goto err_remove_link; - if (mousedev_mix.open) { - error = input_open_device(&mousedev->handle); - if (error) - goto err_unregister_handle; - } + error = mixdev_add_device(mousedev); + if (error) + goto err_unregister_handle; return 0; @@ -715,16 +762,15 @@ static void mousedev_disconnect(struct input_handle *handle) MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); mousedev->exist = 0; + mixdev_remove_device(mousedev); + if (mousedev->open) { input_close_device(handle); wake_up_interruptible(&mousedev->wait); list_for_each_entry(client, &mousedev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); - } else { - if (mousedev_mix.open) - input_close_device(handle); + } else mousedev_free(mousedev); - } } static const struct input_device_id mousedev_ids[] = { diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index fbef35d..8e2d2c9 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -151,6 +151,7 @@ static int tsdev_open(struct inode *inode, struct file *file) int i = iminor(inode) - TSDEV_MINOR_BASE; struct tsdev_client *client; struct tsdev *tsdev; + int error; printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled " "for removal.\nSee Documentation/feature-removal-schedule.txt " @@ -171,8 +172,14 @@ static int tsdev_open(struct inode *inode, struct file *file) client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0; list_add_tail(&client->node, &tsdev->client_list); - if (!tsdev->open++ && tsdev->exist) - input_open_device(&tsdev->handle); + if (!tsdev->open++ && tsdev->exist) { + error = input_open_device(&tsdev->handle); + if (error) { + list_del(&client->node); + kfree(client); + return error; + } + } file->private_data = client; return 0; -- cgit v0.10.2 From 598972d4fb39c8a0826b396e45dc2a8c1dbe4f11 Mon Sep 17 00:00:00 2001 From: Johann Deneux Date: Thu, 12 Apr 2007 01:30:24 -0400 Subject: Input: iforce - use usb_kill_urb instead of usb_unlink_urb Using usb_unlink_urb can cause iforce_open to fail when called soon after iforce_release. Also updated my email address and replaced calls to printk() by dbg(), warn(), info(), err()... Signed-off-by: Johann Deneux Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c index 8fb0c19..f2a4381 100644 --- a/drivers/input/joystick/iforce/iforce-ff.c +++ b/drivers/input/joystick/iforce/iforce-ff.c @@ -2,7 +2,7 @@ * $Id: iforce-ff.c,v 1.9 2002/02/02 19:28:35 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2001-2002 Johann Deneux + * Copyright (c) 2001-2002, 2007 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ @@ -205,7 +205,7 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new) int i; if (new->type != FF_SPRING && new->type != FF_FRICTION) { - printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n"); + warn("bad effect type in need_condition_modifier"); return 0; } @@ -227,7 +227,7 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new) static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect) { if (effect->type != FF_CONSTANT) { - printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n"); + warn("bad effect type in need_envelope_modifier"); return 0; } @@ -258,7 +258,7 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec break; default: - printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n"); + warn("bad effect type in need_envelope_modifier"); } return 0; @@ -271,7 +271,7 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec static int need_period_modifier(struct ff_effect *old, struct ff_effect *new) { if (new->type != FF_PERIODIC) { - printk(KERN_WARNING "iforce.c: bad effect type in need_period_modifier\n"); + warn("bad effect type in need_period_modifier"); return 0; } return (old->u.periodic.period != new->u.periodic.period diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 3393a37..bd5a6de 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -2,7 +2,7 @@ * $Id: iforce-main.c,v 1.19 2002/07/07 10:22:50 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2001-2002 Johann Deneux + * Copyright (c) 2001-2002, 2007 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ @@ -29,7 +29,7 @@ #include "iforce.h" -MODULE_AUTHOR("Vojtech Pavlik , Johann Deneux "); +MODULE_AUTHOR("Vojtech Pavlik , Johann Deneux "); MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver"); MODULE_LICENSE("GPL"); @@ -220,7 +220,7 @@ static void iforce_release(struct input_dev *dev) /* Check: no effects should be present in memory */ for (i = 0; i < dev->ff->max_effects; i++) { if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) { - printk(KERN_WARNING "iforce_release: Device still owns effects\n"); + warn("iforce_release: Device still owns effects"); break; } } @@ -232,7 +232,7 @@ static void iforce_release(struct input_dev *dev) switch (iforce->bus) { #ifdef CONFIG_JOYSTICK_IFORCE_USB case IFORCE_USB: - usb_unlink_urb(iforce->irq); + usb_kill_urb(iforce->irq); /* The device was unplugged before the file * was released */ @@ -324,7 +324,7 @@ int iforce_init_device(struct iforce *iforce) break; if (i == 20) { /* 5 seconds */ - printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n"); + err("Timeout waiting for response from device."); error = -ENODEV; goto fail; } @@ -336,26 +336,26 @@ int iforce_init_device(struct iforce *iforce) if (!iforce_get_id_packet(iforce, "M")) input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1]; else - printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet M\n"); + warn("Device does not respond to id packet M"); if (!iforce_get_id_packet(iforce, "P")) input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1]; else - printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet P\n"); + warn("Device does not respond to id packet P"); if (!iforce_get_id_packet(iforce, "B")) iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1]; else - printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n"); + warn("Device does not respond to id packet B"); if (!iforce_get_id_packet(iforce, "N")) ff_effects = iforce->edata[1]; else - printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n"); + warn("Device does not respond to id packet N"); /* Check if the device can store more effects than the driver can really handle */ if (ff_effects > IFORCE_EFFECTS_MAX) { - printk(KERN_WARNING "iforce: Limiting number of effects to %d (device reports %d)\n", + warn("Limiting number of effects to %d (device reports %d)", IFORCE_EFFECTS_MAX, ff_effects); ff_effects = IFORCE_EFFECTS_MAX; } @@ -457,8 +457,6 @@ int iforce_init_device(struct iforce *iforce) if (error) goto fail; - printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open); - return 0; fail: input_free_device(input_dev); diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 808f059..21c4e13 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c @@ -2,7 +2,7 @@ * $Id: iforce-packets.c,v 1.16 2002/07/07 10:22:50 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2001-2002 Johann Deneux + * Copyright (c) 2001-2002, 2007 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ @@ -39,10 +39,10 @@ void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) { int i; - printk(KERN_DEBUG "iforce.c: %s ( cmd = %04x, data = ", msg, cmd); + printk(KERN_DEBUG __FILE__ ": %s cmd = %04x, data = ", msg, cmd); for (i = 0; i < LO(cmd); i++) printk("%02x ", data[i]); - printk(")\n"); + printk("\n"); } /* @@ -65,8 +65,9 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data) head = iforce->xmit.head; tail = iforce->xmit.tail; + if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) { - printk(KERN_WARNING "iforce.c: not enough space in xmit buffer to send new packet\n"); + warn("not enough space in xmit buffer to send new packet"); spin_unlock_irqrestore(&iforce->xmit_lock, flags); return -1; } @@ -126,8 +127,6 @@ int iforce_control_playback(struct iforce* iforce, u16 id, unsigned int value) { unsigned char data[3]; -printk(KERN_DEBUG "iforce-packets.c: control_playback %d %d\n", id, value); - data[0] = LO(id); data[1] = (value > 0) ? ((value > 1) ? 0x41 : 0x01) : 0; data[2] = LO(value); @@ -151,7 +150,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr) return 0; } } - printk(KERN_WARNING "iforce-packets.c: unused effect %04x updated !!!\n", addr); + warn("unused effect %04x updated !!!", addr); return -1; } @@ -162,7 +161,7 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) static int being_used = 0; if (being_used) - printk(KERN_WARNING "iforce-packets.c: re-entrant call to iforce_process %d\n", being_used); + warn("re-entrant call to iforce_process %d", being_used); being_used++; #ifdef CONFIG_JOYSTICK_IFORCE_232 @@ -266,7 +265,7 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet) return -1; } #else - printk(KERN_ERR "iforce_get_id_packet: iforce->bus = USB!\n"); + err("iforce_get_id_packet: iforce->bus = USB!"); #endif break; @@ -284,13 +283,12 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet) return -1; } #else - printk(KERN_ERR "iforce_get_id_packet: iforce->bus = SERIO!\n"); + err("iforce_get_id_packet: iforce->bus = SERIO!"); #endif break; default: - printk(KERN_ERR "iforce_get_id_packet: iforce->bus = %d\n", - iforce->bus); + err("iforce_get_id_packet: iforce->bus = %d", iforce->bus); break; } diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c index ec4be53..7b4bc19 100644 --- a/drivers/input/joystick/iforce/iforce-serio.c +++ b/drivers/input/joystick/iforce/iforce-serio.c @@ -2,7 +2,7 @@ * $Id: iforce-serio.c,v 1.4 2002/01/28 22:45:00 jdeneux Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik - * Copyright (c) 2001 Johann Deneux + * Copyright (c) 2001, 2007 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 80cdebc..750099d 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -2,7 +2,7 @@ * $Id: iforce-usb.c,v 1.16 2002/06/09 11:08:04 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2001-2002 Johann Deneux + * Copyright (c) 2001-2002, 2007 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ @@ -65,7 +65,7 @@ void iforce_usb_xmit(struct iforce *iforce) XMIT_INC(iforce->xmit.tail, n); if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) { - printk(KERN_WARNING "iforce-usb.c: iforce_usb_xmit: usb_submit_urb failed %d\n", n); + warn("usb_submit_urb failed %d\n", n); } /* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended. @@ -110,7 +110,7 @@ static void iforce_usb_out(struct urb *urb) struct iforce *iforce = urb->context; if (urb->status) { - printk(KERN_DEBUG "iforce_usb_out: urb->status %d, exiting", urb->status); + dbg("urb->status %d, exiting", urb->status); return; } @@ -190,10 +190,9 @@ fail: /* Called by iforce_delete() */ void iforce_usb_delete(struct iforce* iforce) { - usb_unlink_urb(iforce->irq); -/* Is it ok to unlink those ? */ - usb_unlink_urb(iforce->out); - usb_unlink_urb(iforce->ctrl); + usb_kill_urb(iforce->irq); + usb_kill_urb(iforce->out); + usb_kill_urb(iforce->ctrl); usb_free_urb(iforce->irq); usb_free_urb(iforce->out); diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index ffaeaef..dadcf4f 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h @@ -2,7 +2,7 @@ * $Id: iforce.h,v 1.13 2002/07/07 10:22:50 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2001-2002 Johann Deneux + * Copyright (c) 2001-2002, 2007 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ -- cgit v0.10.2 From 887cc127233f34e833d074380f433a04de207563 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:30:41 -0400 Subject: Input: synaptics - export model bits Encode synaptics model in psmouse->model so it will be exported via sysfs as input_dev->id.version and become visible for applications. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index e42a0a4..c77788b 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -655,6 +655,16 @@ int synaptics_init(struct psmouse *psmouse) set_input_params(psmouse->dev, priv); + /* + * Encode touchpad model so that it can be used to set + * input device->id.version and be visible to userspace. + * Because version is __u16 we have to drop something. + * Hardware info bits seem to be good candidates as they + * are documented to be for Synaptics corp. internal use. + */ + psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) | + (priv->model_id & 0x000000ff); + psmouse->protocol_handler = synaptics_process_byte; psmouse->set_rate = synaptics_set_rate; psmouse->disconnect = synaptics_disconnect; -- cgit v0.10.2 From 9e35d20663344b38339ffb6127ba08285f3397a9 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:30:52 -0400 Subject: Input: keyboard handler - use printk_ratelimit() Use printk_ratelimit() to protect ourselves from buggy drivers or devices endlessly generating invalid events. Suggested by Andrew Morton. Signed-off-by: Dmitry Torokhov diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 5971254..c06e86a 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1135,7 +1135,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw) if (emulate_raw(vc, keycode, !down << 7)) - if (keycode < BTN_MISC) + if (keycode < BTN_MISC && printk_ratelimit()) printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode); #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ -- cgit v0.10.2 From f3901d9e3bf2b57604358eea62f3414000772e2a Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 12 Apr 2007 01:31:05 -0400 Subject: Input: remove no longer used power.c handler Delete the never-compiled source file drivers/input/power.c, and remove its entry from the corresponding Makefile, as there is no Kconfig file that refers to the config option INPUT_POWER Signed-off-by: Robert P. J. Day Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/Makefile b/drivers/input/Makefile index da575de..b4cd106 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o obj-$(CONFIG_INPUT_JOYDEV) += joydev.o obj-$(CONFIG_INPUT_EVDEV) += evdev.o obj-$(CONFIG_INPUT_TSDEV) += tsdev.o -obj-$(CONFIG_INPUT_POWER) += power.o obj-$(CONFIG_INPUT_EVBUG) += evbug.o obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/ diff --git a/drivers/input/power.c b/drivers/input/power.c deleted file mode 100644 index e28d264..0000000 --- a/drivers/input/power.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * $Id: power.c,v 1.10 2001/09/25 09:17:15 vojtech Exp $ - * - * Copyright (c) 2001 "Crazy" James Simmons - * - * Input driver Power Management. - * - * Sponsored by Transvirtual Technology. - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Should you need to contact me, the author, you can do so by - * e-mail - mail your message to . - */ - -#include -#include -#include -#include -#include -#include -#include - -static struct input_handler power_handler; - -/* - * Power management can't be done in a interrupt context. So we have to - * use keventd. - */ -static int suspend_button_pushed; -static void suspend_button_task_handler(struct work_struct *work) -{ - udelay(200); /* debounce */ - suspend_button_pushed = 0; -} - -static DECLARE_WORK(suspend_button_task, suspend_button_task_handler); - -static void power_event(struct input_handle *handle, unsigned int type, - unsigned int code, int down) -{ - struct input_dev *dev = handle->dev; - - printk("Entering power_event\n"); - - if (type == EV_PWR) { - switch (code) { - case KEY_SUSPEND: - printk("Powering down entire device\n"); - - if (!suspend_button_pushed) { - suspend_button_pushed = 1; - schedule_work(&suspend_button_task); - } - break; - case KEY_POWER: - /* Hum power down the machine. */ - break; - default: - return; - } - } - - if (type == EV_KEY) { - switch (code) { - case KEY_SUSPEND: - printk("Powering down input device\n"); - /* This is risky. See pm.h for details. */ - if (dev->state != PM_RESUME) - dev->state = PM_RESUME; - else - dev->state = PM_SUSPEND; - /* pm_send(dev->pm_dev, dev->state, dev); */ - break; - case KEY_POWER: - /* Turn the input device off completely ? */ - break; - default: - return; - } - } - return; -} - -static int power_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) -{ - struct input_handle *handle; - int error; - - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = "power"; - - error = input_register_handle(handle); - if (error) - goto err_free_handle; - - error = input_open_device(handle); - if (error) - goto err_unregister_handle; - - return 0; - - err_unregister_handle: - input_unregister_handle(handle); - err_free_handle: - kfree(handle); - return error; -} - -static void power_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -static const struct input_device_id power_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT(EV_KEY) }, - .keybit = { [LONG(KEY_SUSPEND)] = BIT(KEY_SUSPEND) } - }, - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT(EV_KEY) }, - .keybit = { [LONG(KEY_POWER)] = BIT(KEY_POWER) } - }, - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT(EV_PWR) }, - }, - { }, /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(input, power_ids); - -static struct input_handler power_handler = { - .event = power_event, - .connect = power_connect, - .disconnect = power_disconnect, - .name = "power", - .id_table = power_ids, -}; - -static int __init power_init(void) -{ - return input_register_handler(&power_handler); -} - -static void __exit power_exit(void) -{ - input_unregister_handler(&power_handler); -} - -module_init(power_init); -module_exit(power_exit); - -MODULE_AUTHOR("James Simmons "); -MODULE_DESCRIPTION("Input Power Management driver"); -MODULE_LICENSE("GPL"); -- cgit v0.10.2 From f42649e84831efc69d5f621f1c36a39b4e384a99 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:31:13 -0400 Subject: Input: ALPS - handle errors from input_register_device() Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4e71a66..cf3e466 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -424,14 +424,15 @@ int alps_init(struct psmouse *psmouse) struct input_dev *dev1 = psmouse->dev, *dev2; int version; - psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); + priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); dev2 = input_allocate_device(); if (!priv || !dev2) goto init_fail; priv->dev2 = dev2; - if (!(priv->i = alps_get_model(psmouse, &version))) + priv->i = alps_get_model(psmouse, &version); + if (!priv->i) goto init_fail; if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) @@ -480,7 +481,8 @@ int alps_init(struct psmouse *psmouse) dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - input_register_device(priv->dev2); + if (input_register_device(priv->dev2)) + goto init_fail; psmouse->protocol_handler = alps_process_byte; psmouse->poll = alps_poll; @@ -491,9 +493,11 @@ int alps_init(struct psmouse *psmouse) /* We are having trouble resyncing ALPS touchpads so disable it for now */ psmouse->resync_time = 0; + psmouse->private = priv; return 0; init_fail: + psmouse_reset(psmouse); input_free_device(dev2); kfree(priv); return -1; @@ -504,7 +508,8 @@ int alps_detect(struct psmouse *psmouse, int set_properties) int version; const struct alps_model_info *model; - if (!(model = alps_get_model(psmouse, &version))) + model = alps_get_model(psmouse, &version); + if (!model) return -1; if (set_properties) { diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index f85ac40..4bbddc9 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -20,7 +20,6 @@ struct alps_model_info { struct alps_data { struct input_dev *dev2; /* Relative device */ - char name[32]; /* Name */ char phys[32]; /* Phys */ const struct alps_model_info *i;/* Info */ int prev_fin; /* Finger bit from previous packet */ -- cgit v0.10.2 From 0d9d93c411c9351ba186f5ec910b10da7c1d9d14 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:31:55 -0400 Subject: Input: mousedev - fix sudden warps with touchpads Pete Zaitcev reports that with his touchpad, if he lifts the finger and places it elsewhere, the pointer sometimes warps dramatically. This happens because we don't store coordinates unless we detect a touch so sometimes we have stale coordinates in queue (from where the finger left the pad) and averaging makes cursor to jump across the screen. The solution is to always store the latest coordinates. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 764970f..3b8011c 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -124,32 +124,33 @@ static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mous int size, tmp; enum { FRACTION_DENOM = 128 }; - if (mousedev->touch) { - size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; - if (size == 0) - size = 256 * 2; - - switch (code) { - case ABS_X: - fx(0) = value; - if (mousedev->pkt_count >= 2) { - tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size; - tmp += mousedev->frac_dx; - mousedev->packet.dx = tmp / FRACTION_DENOM; - mousedev->frac_dx = tmp - mousedev->packet.dx * FRACTION_DENOM; - } - break; + switch (code) { + case ABS_X: + fx(0) = value; + if (mousedev->touch && mousedev->pkt_count >= 2) { + size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; + if (size == 0) + size = 256 * 2; + tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size; + tmp += mousedev->frac_dx; + mousedev->packet.dx = tmp / FRACTION_DENOM; + mousedev->frac_dx = tmp - mousedev->packet.dx * FRACTION_DENOM; + } + break; - case ABS_Y: - fy(0) = value; - if (mousedev->pkt_count >= 2) { - tmp = -((value - fy(2)) * (256 * FRACTION_DENOM)) / size; - tmp += mousedev->frac_dy; - mousedev->packet.dy = tmp / FRACTION_DENOM; - mousedev->frac_dy = tmp - mousedev->packet.dy * FRACTION_DENOM; - } - break; - } + case ABS_Y: + fy(0) = value; + if (mousedev->touch && mousedev->pkt_count >= 2) { + /* use X size to keep the same scale */ + size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; + if (size == 0) + size = 256 * 2; + tmp = -((value - fy(2)) * (256 * FRACTION_DENOM)) / size; + tmp += mousedev->frac_dy; + mousedev->packet.dy = tmp / FRACTION_DENOM; + mousedev->frac_dy = tmp - mousedev->packet.dy * FRACTION_DENOM; + } + break; } } -- cgit v0.10.2 From 8d04ddb64c7bf62aec1102fddc5336a68bcaebe9 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:32:09 -0400 Subject: Input: i8042 - disable interfaces when switching to legacy mode Disable both keyboard and auxiliary interfaces before switching to legacy mode to prevent atkbd from getting "empty" interrupts. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index ec195a3..ff40b5c 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -762,6 +762,13 @@ static void i8042_controller_reset(void) i8042_flush(); /* + * Disable both KBD and AUX interfaces so they don't get in the way + */ + + i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS; + i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); + +/* * Disable MUX mode if present. */ -- cgit v0.10.2 From 688897b0d4910e097f34c0e263d649cf2036eb45 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:32:22 -0400 Subject: Input: logips2pp - ignore mice reporting model as 0 There are mice reporting to logitech's queries with model of 0. Do not claim that these are Logitech mice. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index d3ddea2..74a8ba7 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -338,12 +338,12 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) param[1] = 0; ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); - if (!param[1]) - return -1; - model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); buttons = param[1]; + if (!model || !buttons) + return -1; + if ((model_info = get_model_info(model)) != NULL) { /* -- cgit v0.10.2 From 6480e2a275ff8ff48ae23a011616fcf819ed7a4e Mon Sep 17 00:00:00 2001 From: Eric Piel Date: Thu, 12 Apr 2007 01:32:34 -0400 Subject: Input: wistron - add acerhk laptop database Acerhk supports already a lot of laptops. Lets import its database so that everyone can benefit of the work of Olaf Tauber. Only the "tm_new" laptops were imported. "tm_old" laptops could be possible but requires more testing and probably only few laptops are still alive. "dritek" laptops should probably be imported into a different driver. Also compress the keymaps by fitting each entry on an int. Most of the dmi matching was written based on google searches, so it's rather prone to errors. That's why I'm asking people to confirm it works. Support to generate switch input events was added as some laptops indicate lid open/close through this interface. This adds the following hardware: Acer TravelMate 370 Acer TravelMate 380 Acer TravelMate C300 Acer TravelMate C100 Acer TravelMate C110 Acer TravelMate 250 Acer TravelMate 350 Acer TravelMate 620 Acer TravelMate 630 Acer TravelMate 220 Acer TravelMate 230 Acer TravelMate 260 Acer TravelMate 280 Acer TravelMate 360 Acer TravelMate 2100 Acer TravelMate 2410 Acer Aspire 1500 Acer Aspire 1600 Acer Aspire 3020 Acer Aspire 5020 Medion MD 2900 Medion MD 40100 Medion MD 95400 Medion MD 96500 Fujitsu Siemens Amilo 7820 Signed-off-by: Eric Piel Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 39e43759..47de377 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -233,10 +233,20 @@ static void bios_set_state(u8 subsys, int enable) struct key_entry { char type; /* See KE_* below */ u8 code; - unsigned keycode; /* For KE_KEY */ + union { + u16 keycode; /* For KE_KEY */ + struct { /* For KE_SW */ + u8 code; + u8 value; + } sw; + }; }; -enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH }; +enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; + +#define FE_MAIL_LED 0x01 +#define FE_WIFI_LED 0x02 +#define FE_UNTESTED 0x80 static const struct key_entry *keymap; /* = NULL; Current key map */ static int have_wifi; @@ -261,104 +271,301 @@ static struct key_entry keymap_empty[] = { }; static struct key_entry keymap_fs_amilo_pro_v2000[] = { - { KE_KEY, 0x01, KEY_HELP }, - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_WIFI, 0x30, 0 }, - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x36, KEY_WWW }, + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_WIFI, 0x30 }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, { KE_END, 0 } }; static struct key_entry keymap_fujitsu_n3510[] = { - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_KEY, 0x36, KEY_WWW }, - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x71, KEY_STOPCD }, - { KE_KEY, 0x72, KEY_PLAYPAUSE }, - { KE_KEY, 0x74, KEY_REWIND }, - { KE_KEY, 0x78, KEY_FORWARD }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x71, {KEY_STOPCD} }, + { KE_KEY, 0x72, {KEY_PLAYPAUSE} }, + { KE_KEY, 0x74, {KEY_REWIND} }, + { KE_KEY, 0x78, {KEY_FORWARD} }, { KE_END, 0 } }; static struct key_entry keymap_wistron_ms2111[] = { - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_KEY, 0x13, KEY_PROG3 }, - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x36, KEY_WWW }, - { KE_END, 0 } + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x13, {KEY_PROG3} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_END, FE_MAIL_LED } +}; + +static struct key_entry keymap_wistron_md40100[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ + { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } }; static struct key_entry keymap_wistron_ms2141[] = { - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_WIFI, 0x30, 0 }, - { KE_KEY, 0x22, KEY_REWIND }, - { KE_KEY, 0x23, KEY_FORWARD }, - { KE_KEY, 0x24, KEY_PLAYPAUSE }, - { KE_KEY, 0x25, KEY_STOPCD }, - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x36, KEY_WWW }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_WIFI, 0x30 }, + { KE_KEY, 0x22, {KEY_REWIND} }, + { KE_KEY, 0x23, {KEY_FORWARD} }, + { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, + { KE_KEY, 0x25, {KEY_STOPCD} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, { KE_END, 0 } }; static struct key_entry keymap_acer_aspire_1500[] = { - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_WIFI, 0x30, 0 }, - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x36, KEY_WWW }, - { KE_BLUETOOTH, 0x44, 0 }, - { KE_END, 0 } + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x03, {KEY_POWER} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_WIFI, 0x30 }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_KEY, 0x49, {KEY_CONFIG} }, + { KE_BLUETOOTH, 0x44 }, + { KE_END, FE_UNTESTED } +}; + +static struct key_entry keymap_acer_aspire_1600[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x03, {KEY_POWER} }, + { KE_KEY, 0x08, {KEY_MUTE} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x13, {KEY_PROG3} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_KEY, 0x49, {KEY_CONFIG} }, + { KE_WIFI, 0x30 }, + { KE_BLUETOOTH, 0x44 }, + { KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +/* 3020 has been tested */ +static struct key_entry keymap_acer_aspire_5020[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x03, {KEY_POWER} }, + { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_KEY, 0x6a, {KEY_CONFIG} }, + { KE_WIFI, 0x30 }, + { KE_BLUETOOTH, 0x44 }, + { KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_2410[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x6d, {KEY_POWER} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_KEY, 0x6a, {KEY_CONFIG} }, + { KE_WIFI, 0x30 }, + { KE_BLUETOOTH, 0x44 }, + { KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_110[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x03, {KEY_POWER} }, + { KE_KEY, 0x08, {KEY_MUTE} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x20, {KEY_VOLUMEUP} }, + { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */ + { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */ + { KE_WIFI, 0x30 }, + { KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_300[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x03, {KEY_POWER} }, + { KE_KEY, 0x08, {KEY_MUTE} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x20, {KEY_VOLUMEUP} }, + { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_WIFI, 0x30 }, + { KE_BLUETOOTH, 0x44 }, + { KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_380[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x03, {KEY_POWER} }, /* not 370 */ + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x13, {KEY_PROG3} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_WIFI, 0x30 }, + { KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +/* unusual map */ +static struct key_entry keymap_acer_travelmate_220[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x11, {KEY_MAIL} }, + { KE_KEY, 0x12, {KEY_WWW} }, + { KE_KEY, 0x13, {KEY_PROG2} }, + { KE_KEY, 0x31, {KEY_PROG1} }, + { KE_END, FE_WIFI_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_230[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_END, FE_WIFI_LED | FE_UNTESTED } }; static struct key_entry keymap_acer_travelmate_240[] = { - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x36, KEY_WWW }, - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_BLUETOOTH, 0x44, 0 }, - { KE_WIFI, 0x30, 0 }, - { KE_END, 0 } + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x03, {KEY_POWER} }, + { KE_KEY, 0x08, {KEY_MUTE} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_BLUETOOTH, 0x44 }, + { KE_WIFI, 0x30 }, + { KE_END, FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_350[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x13, {KEY_MAIL} }, + { KE_KEY, 0x14, {KEY_PROG3} }, + { KE_KEY, 0x15, {KEY_WWW} }, + { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_360[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x13, {KEY_MAIL} }, + { KE_KEY, 0x14, {KEY_PROG3} }, + { KE_KEY, 0x15, {KEY_WWW} }, + { KE_KEY, 0x40, {KEY_WLAN} }, + { KE_END, FE_WIFI_LED | FE_UNTESTED } /* no mail led */ }; /* Wifi subsystem only activates the led. Therefore we need to pass * wifi event as a normal key, then userspace can really change the wifi state. * TODO we need to export led state to userspace (wifi and mail) */ static struct key_entry keymap_acer_travelmate_610[] = { - { KE_KEY, 0x01, KEY_HELP }, - { KE_KEY, 0x02, KEY_CONFIG }, - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_KEY, 0x13, KEY_PROG3 }, - { KE_KEY, 0x14, KEY_MAIL }, - { KE_KEY, 0x15, KEY_WWW }, - { KE_KEY, 0x40, KEY_WLAN }, /* Wifi */ - { KE_END, 0 } + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG3} }, + { KE_KEY, 0x13, {KEY_PROG3} }, + { KE_KEY, 0x14, {KEY_MAIL} }, + { KE_KEY, 0x15, {KEY_WWW} }, + { KE_KEY, 0x40, {KEY_WLAN} }, + { KE_END, FE_MAIL_LED | FE_WIFI_LED } +}; + +static struct key_entry keymap_acer_travelmate_630[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x03, {KEY_POWER} }, + { KE_KEY, 0x08, {KEY_MUTE} }, /* not 620 */ + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x13, {KEY_PROG3} }, + { KE_KEY, 0x20, {KEY_VOLUMEUP} }, + { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_WIFI, 0x30 }, + { KE_END, FE_MAIL_LED | FE_UNTESTED } }; static struct key_entry keymap_aopen_1559as[] = { - { KE_KEY, 0x01, KEY_HELP }, - { KE_KEY, 0x06, KEY_PROG3 }, - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_WIFI, 0x30, 0 }, - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x36, KEY_WWW }, + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x06, {KEY_PROG3} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_WIFI, 0x30 }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, { KE_END, 0 }, }; static struct key_entry keymap_fs_amilo_d88x0[] = { - { KE_KEY, 0x01, KEY_HELP }, - { KE_KEY, 0x08, KEY_MUTE }, - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x36, KEY_WWW }, - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_KEY, 0x13, KEY_PROG3 }, - { KE_END, 0 } + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x08, {KEY_MUTE} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x13, {KEY_PROG3} }, + { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_wistron_md2900[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_WIFI, 0x30 }, + { KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_wistron_md96500[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ + { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ + { KE_KEY, 0x08, {KEY_MUTE} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x20, {KEY_VOLUMEUP} }, + { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, + { KE_KEY, 0x22, {KEY_REWIND} }, + { KE_KEY, 0x23, {KEY_FORWARD} }, + { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, + { KE_KEY, 0x25, {KEY_STOPCD} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_WIFI, 0x30 }, + { KE_BLUETOOTH, 0x44 }, + { KE_END, FE_UNTESTED } }; /* @@ -405,6 +612,133 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, { .callback = dmi_matched, + .ident = "Acer Aspire 1600", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), + }, + .driver_data = keymap_acer_aspire_1600 + }, + { + .callback = dmi_matched, + .ident = "Acer Aspire 3020", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), + }, + .driver_data = keymap_acer_aspire_5020 + }, + { + .callback = dmi_matched, + .ident = "Acer Aspire 5020", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), + }, + .driver_data = keymap_acer_aspire_5020 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 2100", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), + }, + .driver_data = keymap_acer_aspire_5020 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 2410", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), + }, + .driver_data = keymap_acer_travelmate_2410 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate C300", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), + }, + .driver_data = keymap_acer_travelmate_300 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate C100", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), + }, + .driver_data = keymap_acer_travelmate_300 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate C110", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), + }, + .driver_data = keymap_acer_travelmate_110 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 380", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), + }, + .driver_data = keymap_acer_travelmate_380 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 370", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), + }, + .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 220", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), + }, + .driver_data = keymap_acer_travelmate_220 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 260", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), + }, + .driver_data = keymap_acer_travelmate_220 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 230", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), + /* acerhk looks for "TravelMate F4..." ?! */ + }, + .driver_data = keymap_acer_travelmate_230 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 280", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), + }, + .driver_data = keymap_acer_travelmate_230 + }, + { + .callback = dmi_matched, .ident = "Acer TravelMate 240", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), @@ -414,6 +748,15 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, { .callback = dmi_matched, + .ident = "Acer TravelMate 250", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), + }, + .driver_data = keymap_acer_travelmate_240 + }, + { + .callback = dmi_matched, .ident = "Acer TravelMate 2424NWXCi", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), @@ -423,6 +766,24 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, { .callback = dmi_matched, + .ident = "Acer TravelMate 350", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), + }, + .driver_data = keymap_acer_travelmate_350 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 360", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), + }, + .driver_data = keymap_acer_travelmate_360 + }, + { + .callback = dmi_matched, .ident = "Acer TravelMate 610", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ACER"), @@ -432,6 +793,24 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, { .callback = dmi_matched, + .ident = "Acer TravelMate 620", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), + }, + .driver_data = keymap_acer_travelmate_630 + }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 630", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), + }, + .driver_data = keymap_acer_travelmate_630 + }, + { + .callback = dmi_matched, .ident = "AOpen 1559AS", .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), @@ -450,6 +829,51 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, { .callback = dmi_matched, + .ident = "Medion MD 40100", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), + DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), + }, + .driver_data = keymap_wistron_md40100 + }, + { + .callback = dmi_matched, + .ident = "Medion MD 2900", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), + DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), + }, + .driver_data = keymap_wistron_md2900 + }, + { + .callback = dmi_matched, + .ident = "Medion MD 96500", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), + DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), + }, + .driver_data = keymap_wistron_md96500 + }, + { + .callback = dmi_matched, + .ident = "Medion MD 95400", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), + DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), + }, + .driver_data = keymap_wistron_md96500 + }, + { + .callback = dmi_matched, + .ident = "Fujitsu Siemens Amilo D7820", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ + DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), + }, + .driver_data = keymap_fs_amilo_d88x0 + }, + { + .callback = dmi_matched, .ident = "Fujitsu Siemens Amilo D88x0", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), @@ -500,12 +924,28 @@ static int __devinit setup_input_dev(void) input_dev->cdev.dev = &wistron_device->dev; for (key = keymap; key->type != KE_END; key++) { - if (key->type == KE_KEY) { - input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY); - set_bit(key->keycode, input_dev->keybit); + switch (key->type) { + case KE_KEY: + set_bit(EV_KEY, input_dev->evbit); + set_bit(key->keycode, input_dev->keybit); + break; + + case KE_SW: + set_bit(EV_SW, input_dev->evbit); + set_bit(key->sw.code, input_dev->swbit); + break; + + default: + ; } } + /* reads information flags on KE_END */ + if (key->code & FE_UNTESTED) + printk(KERN_WARNING "Untested laptop multimedia keys, " + "please report success or failure to eric.piel" + "@tremplin-utc.net\n"); + error = input_register_device(input_dev); if (error) { input_free_device(input_dev); @@ -523,6 +963,12 @@ static void report_key(unsigned keycode) input_sync(input_dev); } +static void report_switch(unsigned code, int value) +{ + input_report_switch(input_dev, code, value); + input_sync(input_dev); +} + /* Driver core */ static int wifi_enabled; @@ -543,6 +989,10 @@ static void handle_key(u8 code) report_key(key->keycode); break; + case KE_SW: + report_switch(key->sw.code, key->sw.value); + break; + case KE_WIFI: if (have_wifi) { wifi_enabled = !wifi_enabled; @@ -558,6 +1008,7 @@ static void handle_key(u8 code) break; case KE_END: + break; default: BUG(); } diff --git a/include/linux/input.h b/include/linux/input.h index a51d6cf..9bd984b 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -506,6 +506,7 @@ struct input_absinfo { #define KEY_VOICEMAIL 0x1ac #define KEY_ADDRESSBOOK 0x1ad #define KEY_MESSENGER 0x1ae +#define KEY_DISPLAYTOGGLE 0x1af /* Turn display (LCD) on and off */ #define KEY_DEL_EOL 0x1c0 #define KEY_DEL_EOS 0x1c1 -- cgit v0.10.2 From 7b0a4cd7601774d1312f477a879f86b0968880fd Mon Sep 17 00:00:00 2001 From: Eric Piel Date: Thu, 12 Apr 2007 01:32:41 -0400 Subject: Input: wistron - introduce generic keymap It turns out that the keymaps in the wistron driver are almost the same, the main difference being some keys which may not exist and leds which might not be present. Therefore it's possible to write a generic keymap which would allow the use of an unknown keyboard with little drawbacks. The user can select it specifying the parameter "keymap=generic". Signed-off-by: Eric Piel Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 47de377..b9ef1df 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -58,7 +58,7 @@ MODULE_PARM_DESC(force, "Load even if computer is not in database"); static char *keymap_name; /* = NULL; */ module_param_named(keymap, keymap_name, charp, 0); -MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected"); +MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected [generic, 1557/MS2141]"); static struct platform_device *wistron_device; @@ -568,6 +568,42 @@ static struct key_entry keymap_wistron_md96500[] = { { KE_END, FE_UNTESTED } }; +static struct key_entry keymap_wistron_generic[] = { + { KE_KEY, 0x01, {KEY_HELP} }, + { KE_KEY, 0x02, {KEY_CONFIG} }, + { KE_KEY, 0x03, {KEY_POWER} }, + { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ + { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ + { KE_KEY, 0x08, {KEY_MUTE} }, + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_KEY, 0x13, {KEY_PROG3} }, + { KE_KEY, 0x14, {KEY_MAIL} }, + { KE_KEY, 0x15, {KEY_WWW} }, + { KE_KEY, 0x20, {KEY_VOLUMEUP} }, + { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, + { KE_KEY, 0x22, {KEY_REWIND} }, + { KE_KEY, 0x23, {KEY_FORWARD} }, + { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, + { KE_KEY, 0x25, {KEY_STOPCD} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ + { KE_KEY, 0x40, {KEY_WLAN} }, + { KE_KEY, 0x49, {KEY_CONFIG} }, + { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */ + { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */ + { KE_KEY, 0x6a, {KEY_CONFIG} }, + { KE_KEY, 0x6d, {KEY_POWER} }, + { KE_KEY, 0x71, {KEY_STOPCD} }, + { KE_KEY, 0x72, {KEY_PLAYPAUSE} }, + { KE_KEY, 0x74, {KEY_REWIND} }, + { KE_KEY, 0x78, {KEY_FORWARD} }, + { KE_WIFI, 0x30 }, + { KE_BLUETOOTH, 0x44 }, + { KE_END, 0 } +}; + /* * If your machine is not here (which is currently rather likely), please send * a list of buttons and their key codes (reported when loading this module @@ -886,15 +922,17 @@ static struct dmi_system_id dmi_ids[] __initdata = { static int __init select_keymap(void) { + dmi_check_system(dmi_ids); if (keymap_name != NULL) { if (strcmp (keymap_name, "1557/MS2141") == 0) keymap = keymap_wistron_ms2141; + else if (strcmp (keymap_name, "generic") == 0) + keymap = keymap_wistron_generic; else { printk(KERN_ERR "wistron_btns: Keymap unknown\n"); return -EINVAL; } } - dmi_check_system(dmi_ids); if (keymap == NULL) { if (!force) { printk(KERN_ERR "wistron_btns: System unknown\n"); -- cgit v0.10.2 From 55d29c98418df737e87dbdfc36c78d3ed99a6698 Mon Sep 17 00:00:00 2001 From: Eric Piel Date: Thu, 12 Apr 2007 01:32:49 -0400 Subject: Input: wistron - declare keymaps as initdata As the number of keymaps increases and is very unlikely to reduce, this patch helps to reduce memory consumption by declaring all keymaps as __initdata and copying right keymap during DMI detection. On x86 this make the module size at runtime going from 10616 to 9428: a bit more than 1kb saved. Signed-off-by: Eric Piel Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index b9ef1df..793cee3 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -50,7 +50,7 @@ MODULE_AUTHOR("Miloslav Trmac "); MODULE_DESCRIPTION("Wistron laptop button driver"); MODULE_LICENSE("GPL v2"); -MODULE_VERSION("0.1"); +MODULE_VERSION("0.2"); static int force; /* = 0; */ module_param(force, bool, 0); @@ -266,11 +266,11 @@ static int __init dmi_matched(struct dmi_system_id *dmi) return 1; } -static struct key_entry keymap_empty[] = { +static struct key_entry keymap_empty[] __initdata = { { KE_END, 0 } }; -static struct key_entry keymap_fs_amilo_pro_v2000[] = { +static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x11, {KEY_PROG1} }, { KE_KEY, 0x12, {KEY_PROG2} }, @@ -280,7 +280,7 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] = { { KE_END, 0 } }; -static struct key_entry keymap_fujitsu_n3510[] = { +static struct key_entry keymap_fujitsu_n3510[] __initdata = { { KE_KEY, 0x11, {KEY_PROG1} }, { KE_KEY, 0x12, {KEY_PROG2} }, { KE_KEY, 0x36, {KEY_WWW} }, @@ -292,7 +292,7 @@ static struct key_entry keymap_fujitsu_n3510[] = { { KE_END, 0 } }; -static struct key_entry keymap_wistron_ms2111[] = { +static struct key_entry keymap_wistron_ms2111[] __initdata = { { KE_KEY, 0x11, {KEY_PROG1} }, { KE_KEY, 0x12, {KEY_PROG2} }, { KE_KEY, 0x13, {KEY_PROG3} }, @@ -301,7 +301,7 @@ static struct key_entry keymap_wistron_ms2111[] = { { KE_END, FE_MAIL_LED } }; -static struct key_entry keymap_wistron_md40100[] = { +static struct key_entry keymap_wistron_md40100[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x31, {KEY_MAIL} }, @@ -310,7 +310,7 @@ static struct key_entry keymap_wistron_md40100[] = { { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } }; -static struct key_entry keymap_wistron_ms2141[] = { +static struct key_entry keymap_wistron_ms2141[] __initdata = { { KE_KEY, 0x11, {KEY_PROG1} }, { KE_KEY, 0x12, {KEY_PROG2} }, { KE_WIFI, 0x30 }, @@ -323,7 +323,7 @@ static struct key_entry keymap_wistron_ms2141[] = { { KE_END, 0 } }; -static struct key_entry keymap_acer_aspire_1500[] = { +static struct key_entry keymap_acer_aspire_1500[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x03, {KEY_POWER} }, { KE_KEY, 0x11, {KEY_PROG1} }, @@ -336,7 +336,7 @@ static struct key_entry keymap_acer_aspire_1500[] = { { KE_END, FE_UNTESTED } }; -static struct key_entry keymap_acer_aspire_1600[] = { +static struct key_entry keymap_acer_aspire_1600[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x03, {KEY_POWER} }, { KE_KEY, 0x08, {KEY_MUTE} }, @@ -352,7 +352,7 @@ static struct key_entry keymap_acer_aspire_1600[] = { }; /* 3020 has been tested */ -static struct key_entry keymap_acer_aspire_5020[] = { +static struct key_entry keymap_acer_aspire_5020[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x03, {KEY_POWER} }, { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ @@ -366,7 +366,7 @@ static struct key_entry keymap_acer_aspire_5020[] = { { KE_END, FE_MAIL_LED | FE_UNTESTED } }; -static struct key_entry keymap_acer_travelmate_2410[] = { +static struct key_entry keymap_acer_travelmate_2410[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x6d, {KEY_POWER} }, { KE_KEY, 0x11, {KEY_PROG1} }, @@ -379,7 +379,7 @@ static struct key_entry keymap_acer_travelmate_2410[] = { { KE_END, FE_MAIL_LED | FE_UNTESTED } }; -static struct key_entry keymap_acer_travelmate_110[] = { +static struct key_entry keymap_acer_travelmate_110[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x03, {KEY_POWER} }, @@ -396,7 +396,7 @@ static struct key_entry keymap_acer_travelmate_110[] = { { KE_END, FE_MAIL_LED | FE_UNTESTED } }; -static struct key_entry keymap_acer_travelmate_300[] = { +static struct key_entry keymap_acer_travelmate_300[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x03, {KEY_POWER} }, @@ -412,7 +412,7 @@ static struct key_entry keymap_acer_travelmate_300[] = { { KE_END, FE_MAIL_LED | FE_UNTESTED } }; -static struct key_entry keymap_acer_travelmate_380[] = { +static struct key_entry keymap_acer_travelmate_380[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x03, {KEY_POWER} }, /* not 370 */ @@ -426,7 +426,7 @@ static struct key_entry keymap_acer_travelmate_380[] = { }; /* unusual map */ -static struct key_entry keymap_acer_travelmate_220[] = { +static struct key_entry keymap_acer_travelmate_220[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x11, {KEY_MAIL} }, @@ -436,7 +436,7 @@ static struct key_entry keymap_acer_travelmate_220[] = { { KE_END, FE_WIFI_LED | FE_UNTESTED } }; -static struct key_entry keymap_acer_travelmate_230[] = { +static struct key_entry keymap_acer_travelmate_230[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x11, {KEY_PROG1} }, @@ -446,7 +446,7 @@ static struct key_entry keymap_acer_travelmate_230[] = { { KE_END, FE_WIFI_LED | FE_UNTESTED } }; -static struct key_entry keymap_acer_travelmate_240[] = { +static struct key_entry keymap_acer_travelmate_240[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x03, {KEY_POWER} }, @@ -460,7 +460,7 @@ static struct key_entry keymap_acer_travelmate_240[] = { { KE_END, FE_UNTESTED } }; -static struct key_entry keymap_acer_travelmate_350[] = { +static struct key_entry keymap_acer_travelmate_350[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x11, {KEY_PROG1} }, @@ -471,7 +471,7 @@ static struct key_entry keymap_acer_travelmate_350[] = { { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } }; -static struct key_entry keymap_acer_travelmate_360[] = { +static struct key_entry keymap_acer_travelmate_360[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x11, {KEY_PROG1} }, @@ -486,7 +486,7 @@ static struct key_entry keymap_acer_travelmate_360[] = { /* Wifi subsystem only activates the led. Therefore we need to pass * wifi event as a normal key, then userspace can really change the wifi state. * TODO we need to export led state to userspace (wifi and mail) */ -static struct key_entry keymap_acer_travelmate_610[] = { +static struct key_entry keymap_acer_travelmate_610[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x11, {KEY_PROG1} }, @@ -498,7 +498,7 @@ static struct key_entry keymap_acer_travelmate_610[] = { { KE_END, FE_MAIL_LED | FE_WIFI_LED } }; -static struct key_entry keymap_acer_travelmate_630[] = { +static struct key_entry keymap_acer_travelmate_630[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x03, {KEY_POWER} }, @@ -514,7 +514,7 @@ static struct key_entry keymap_acer_travelmate_630[] = { { KE_END, FE_MAIL_LED | FE_UNTESTED } }; -static struct key_entry keymap_aopen_1559as[] = { +static struct key_entry keymap_aopen_1559as[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x06, {KEY_PROG3} }, { KE_KEY, 0x11, {KEY_PROG1} }, @@ -525,7 +525,7 @@ static struct key_entry keymap_aopen_1559as[] = { { KE_END, 0 }, }; -static struct key_entry keymap_fs_amilo_d88x0[] = { +static struct key_entry keymap_fs_amilo_d88x0[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x08, {KEY_MUTE} }, { KE_KEY, 0x31, {KEY_MAIL} }, @@ -536,7 +536,7 @@ static struct key_entry keymap_fs_amilo_d88x0[] = { { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } }; -static struct key_entry keymap_wistron_md2900[] = { +static struct key_entry keymap_wistron_md2900[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x11, {KEY_PROG1} }, @@ -547,7 +547,7 @@ static struct key_entry keymap_wistron_md2900[] = { { KE_END, FE_MAIL_LED | FE_UNTESTED } }; -static struct key_entry keymap_wistron_md96500[] = { +static struct key_entry keymap_wistron_md96500[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ @@ -568,7 +568,7 @@ static struct key_entry keymap_wistron_md96500[] = { { KE_END, FE_UNTESTED } }; -static struct key_entry keymap_wistron_generic[] = { +static struct key_entry keymap_wistron_generic[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x03, {KEY_POWER} }, @@ -920,6 +920,26 @@ static struct dmi_system_id dmi_ids[] __initdata = { { NULL, } }; +/* Copy the good keymap, as the original ones are free'd */ +static int __init copy_keymap(void) +{ + const struct key_entry *key; + struct key_entry *new_keymap; + unsigned int length = 1; + + for (key = keymap; key->type != KE_END; key++) + length++; + + new_keymap = kmalloc(length * sizeof(struct key_entry), GFP_KERNEL); + if (!new_keymap) + return -ENOMEM; + + memcpy(new_keymap, keymap, length * sizeof(struct key_entry)); + keymap = new_keymap; + + return 0; +} + static int __init select_keymap(void) { dmi_check_system(dmi_ids); @@ -940,7 +960,8 @@ static int __init select_keymap(void) } keymap = keymap_empty; } - return 0; + + return copy_keymap(); } /* Input layer interface */ @@ -1203,6 +1224,7 @@ static void __exit wb_module_exit(void) platform_device_unregister(wistron_device); platform_driver_unregister(&wistron_driver); unmap_bios(); + kfree(keymap); } module_init(wb_module_init); -- cgit v0.10.2 From 1b726a02d97cef2471521ae6947416f7374c6590 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:33:00 -0400 Subject: Input: gtco - handle errors from input_register_device() Also fix URB leak in gtco_probe error path, formatting fixes. Signed-off-by: Dmitry Torokhov diff --git a/drivers/usb/input/gtco.c b/drivers/usb/input/gtco.c index 203cdc1bb..aa9c676 100644 --- a/drivers/usb/input/gtco.c +++ b/drivers/usb/input/gtco.c @@ -187,7 +187,6 @@ struct hid_descriptor /* - * * This is an abbreviated parser for the HID Report Descriptor. We * know what devices we are talking to, so this is by no means meant * to be generic. We can make some safe assumptions: @@ -204,7 +203,7 @@ struct hid_descriptor static void parse_hid_report_descriptor(struct gtco *device, char * report, int length) { - int x,i=0; + int x, i = 0; /* Tag primitive vars */ __u8 prefix; @@ -215,7 +214,6 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report, __u16 data16 = 0; __u32 data32 = 0; - /* For parsing logic */ int inputnum = 0; __u32 usage = 0; @@ -227,44 +225,44 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report, /* Debug stuff */ char maintype='x'; char globtype[12]; - int indent=0; - char indentstr[10]=""; - + int indent = 0; + char indentstr[10] = ""; dbg("======>>>>>>PARSE<<<<<<======"); /* Walk this report and pull out the info we need */ - while (imax_X == 0){ + dbg("GER: X Usage: 0x%x", usage); + if (device->max_X == 0) { device->max_X = globalval[TAG_GLOB_LOG_MAX]; device->min_X = globalval[TAG_GLOB_LOG_MIN]; } - break; + case 1: /* Y coord */ - dbg("GER: Y Usage: 0x%x",usage); - if (device->max_Y == 0){ + dbg("GER: Y Usage: 0x%x", usage); + if (device->max_Y == 0) { device->max_Y = globalval[TAG_GLOB_LOG_MAX]; device->min_Y = globalval[TAG_GLOB_LOG_MIN]; } break; + default: /* Tilt X */ - if (usage == DIGITIZER_USAGE_TILT_X){ - if (device->maxtilt_X == 0){ + if (usage == DIGITIZER_USAGE_TILT_X) { + if (device->maxtilt_X == 0) { device->maxtilt_X = globalval[TAG_GLOB_LOG_MAX]; device->mintilt_X = globalval[TAG_GLOB_LOG_MIN]; } } /* Tilt Y */ - if (usage == DIGITIZER_USAGE_TILT_Y){ - if (device->maxtilt_Y == 0){ + if (usage == DIGITIZER_USAGE_TILT_Y) { + if (device->maxtilt_Y == 0) { device->maxtilt_Y = globalval[TAG_GLOB_LOG_MAX]; device->mintilt_Y = globalval[TAG_GLOB_LOG_MIN]; } } - /* Pressure */ - if (usage == DIGITIZER_USAGE_TIP_PRESSURE){ - if (device->maxpressure == 0){ + if (usage == DIGITIZER_USAGE_TIP_PRESSURE) { + if (device->maxpressure == 0) { device->maxpressure = globalval[TAG_GLOB_LOG_MAX]; device->minpressure = globalval[TAG_GLOB_LOG_MIN]; } @@ -341,192 +337,206 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report, } inputnum++; - - break; + case TAG_MAIN_OUTPUT: - maintype='O'; + maintype = 'O'; break; + case TAG_MAIN_FEATURE: - maintype='F'; + maintype = 'F'; break; + case TAG_MAIN_COL_START: - maintype='S'; + maintype = 'S'; - if (data==0){ + if (data == 0) { dbg("======>>>>>> Physical"); - strcpy(globtype,"Physical"); - }else{ + strcpy(globtype, "Physical"); + } else dbg("======>>>>>>"); - } /* Indent the debug output */ indent++; - for (x=0;xusage == 0){ + if (device->usage == 0) device->usage = data; - } - strcpy(globtype,"USAGE"); + + strcpy(globtype, "USAGE"); break; - case TAG_GLOB_LOG_MIN : - strcpy(globtype,"LOG_MIN"); + + case TAG_GLOB_LOG_MIN: + strcpy(globtype, "LOG_MIN"); break; - case TAG_GLOB_LOG_MAX : - strcpy(globtype,"LOG_MAX"); + + case TAG_GLOB_LOG_MAX: + strcpy(globtype, "LOG_MAX"); break; - case TAG_GLOB_PHYS_MIN : - strcpy(globtype,"PHYS_MIN"); + + case TAG_GLOB_PHYS_MIN: + strcpy(globtype, "PHYS_MIN"); break; - case TAG_GLOB_PHYS_MAX : - strcpy(globtype,"PHYS_MAX"); + + case TAG_GLOB_PHYS_MAX: + strcpy(globtype, "PHYS_MAX"); break; - case TAG_GLOB_UNIT_EXP : - strcpy(globtype,"EXP"); + + case TAG_GLOB_UNIT_EXP: + strcpy(globtype, "EXP"); break; - case TAG_GLOB_UNIT : - strcpy(globtype,"UNIT"); + + case TAG_GLOB_UNIT: + strcpy(globtype, "UNIT"); break; - case TAG_GLOB_REPORT_SZ : - strcpy(globtype,"REPORT_SZ"); + + case TAG_GLOB_REPORT_SZ: + strcpy(globtype, "REPORT_SZ"); break; - case TAG_GLOB_REPORT_ID : - strcpy(globtype,"REPORT_ID"); + + case TAG_GLOB_REPORT_ID: + strcpy(globtype, "REPORT_ID"); /* New report, restart numbering */ - inputnum=0; + inputnum = 0; break; + case TAG_GLOB_REPORT_CNT: - strcpy(globtype,"REPORT_CNT"); + strcpy(globtype, "REPORT_CNT"); break; - case TAG_GLOB_PUSH : - strcpy(globtype,"PUSH"); + + case TAG_GLOB_PUSH: + strcpy(globtype, "PUSH"); break; + case TAG_GLOB_POP: - strcpy(globtype,"POP"); + strcpy(globtype, "POP"); break; } - /* Check to make sure we have a good tag number so we don't overflow array */ - if (tag < TAG_GLOB_MAX){ - switch (size){ + if (tag < TAG_GLOB_MAX) { + switch (size) { case 1: - dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data); - globalval[tag]=data; + dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x", + indentstr, globtype, tag, size, data); + globalval[tag] = data; break; + case 2: - dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data16); - globalval[tag]=data16; + dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x", + indentstr, globtype, tag, size, data16); + globalval[tag] = data16; break; + case 4: - dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data32); - globalval[tag]=data32; + dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x", + indentstr, globtype, tag, size, data32); + globalval[tag] = data32; break; } - }else{ + } else { dbg("%sGLOBALTAG: ILLEGAL TAG:%d SIZE: %d ", - indentstr,tag,size); + indentstr, tag, size); } - - break; case TYPE_LOCAL: - switch(tag){ + switch (tag) { case TAG_GLOB_USAGE: - strcpy(globtype,"USAGE"); + strcpy(globtype, "USAGE"); /* Always 1 byte */ usage = data; break; - case TAG_GLOB_LOG_MIN : - strcpy(globtype,"MIN"); + + case TAG_GLOB_LOG_MIN: + strcpy(globtype, "MIN"); break; - case TAG_GLOB_LOG_MAX : - strcpy(globtype,"MAX"); + + case TAG_GLOB_LOG_MAX: + strcpy(globtype, "MAX"); break; + default: - strcpy(globtype,"UNKNOWN"); + strcpy(globtype, "UNKNOWN"); + break; } - switch (size){ + switch (size) { case 1: dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", - indentstr,tag,globtype,size,data); + indentstr, tag, globtype, size, data); break; + case 2: dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", - indentstr,tag,globtype,size,data16); + indentstr, tag, globtype, size, data16); break; + case 4: dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", - indentstr,tag,globtype,size,data32); + indentstr, tag, globtype, size, data32); break; } break; } - } - } - - /* INPUT DRIVER Routines */ - /* - * Called when opening the input device. This will submit the URB to - * the usb system so we start getting reports + * Called when opening the input device. This will submit the URB to + * the usb system so we start getting reports */ static int gtco_input_open(struct input_dev *inputdev) { @@ -534,21 +544,20 @@ static int gtco_input_open(struct input_dev *inputdev) device = inputdev->private; device->urbinfo->dev = device->usbdev; - if (usb_submit_urb(device->urbinfo, GFP_KERNEL)) { + if (usb_submit_urb(device->urbinfo, GFP_KERNEL)) return -EIO; - } + return 0; } -/** - Called when closing the input device. This will unlink the URB -*/ +/* + * Called when closing the input device. This will unlink the URB + */ static void gtco_input_close(struct input_dev *inputdev) { struct gtco *device = inputdev->private; usb_kill_urb(device->urbinfo); - } @@ -564,15 +573,12 @@ static void gtco_setup_caps(struct input_dev *inputdev) { struct gtco *device = inputdev->private; - /* Which events */ inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); - /* Misc event menu block */ inputdev->mscbit[0] = BIT(MSC_SCAN)|BIT(MSC_SERIAL)|BIT(MSC_RAW) ; - /* Absolute values based on HID report info */ input_set_abs_params(inputdev, ABS_X, device->min_X, device->max_X, 0, 0); @@ -590,17 +596,12 @@ static void gtco_setup_caps(struct input_dev *inputdev) input_set_abs_params(inputdev, ABS_PRESSURE, device->minpressure, device->maxpressure, 0, 0); - /* Transducer */ - input_set_abs_params(inputdev, ABS_MISC, 0,0xFF, 0, 0); - + input_set_abs_params(inputdev, ABS_MISC, 0, 0xFF, 0, 0); } - - /* USB Routines */ - /* * URB callback routine. Called when we get IRQ reports from the * digitizer. @@ -610,9 +611,7 @@ static void gtco_setup_caps(struct input_dev *inputdev) */ static void gtco_urb_callback(struct urb *urbinfo) { - - - struct gtco *device = urbinfo->context; + struct gtco *device = urbinfo->context; struct input_dev *inputdev; int rc; u32 val = 0; @@ -621,19 +620,20 @@ static void gtco_urb_callback(struct urb *urbinfo) inputdev = device->inputdevice; - /* Was callback OK? */ - if ((urbinfo->status == -ECONNRESET ) || - (urbinfo->status == -ENOENT ) || - (urbinfo->status == -ESHUTDOWN )){ + if (urbinfo->status == -ECONNRESET || + urbinfo->status == -ENOENT || + urbinfo->status == -ESHUTDOWN) { /* Shutdown is occurring. Return and don't queue up any more */ return; } - if (urbinfo->status != 0 ) { - /* Some unknown error. Hopefully temporary. Just go and */ - /* requeue an URB */ + if (urbinfo->status != 0) { + /* + * Some unknown error. Hopefully temporary. Just go and + * requeue an URB + */ goto resubmit; } @@ -642,10 +642,9 @@ static void gtco_urb_callback(struct urb *urbinfo) */ /* PID dependent when we interpret the report */ - if ((inputdev->id.product == PID_1000 )|| - (inputdev->id.product == PID_1001 )|| - (inputdev->id.product == PID_1002 )) - { + if (inputdev->id.product == PID_1000 || + inputdev->id.product == PID_1001 || + inputdev->id.product == PID_1002) { /* * Switch on the report ID @@ -653,10 +652,10 @@ static void gtco_urb_callback(struct urb *urbinfo) * the report number. We can just fall through the case * statements if we start with the highest number report */ - switch(device->buffer[0]){ + switch (device->buffer[0]) { case 5: /* Pressure is 9 bits */ - val = ((u16)(device->buffer[8]) << 1); + val = ((u16)(device->buffer[8]) << 1); val |= (u16)(device->buffer[7] >> 7); input_report_abs(inputdev, ABS_PRESSURE, device->buffer[8]); @@ -664,7 +663,6 @@ static void gtco_urb_callback(struct urb *urbinfo) /* Mask out the Y tilt value used for pressure */ device->buffer[7] = (u8)((device->buffer[7]) & 0x7F); - /* Fall thru */ case 4: /* Tilt */ @@ -684,11 +682,10 @@ static void gtco_urb_callback(struct urb *urbinfo) input_report_abs(inputdev, ABS_TILT_Y, (s32)valsigned); /* Fall thru */ - case 2: case 3: /* Convert buttons, only 5 bits possible */ - val = (device->buffer[5])&MASK_BUTTON; + val = (device->buffer[5]) & MASK_BUTTON; /* We don't apply any meaning to the bitmask, just report */ @@ -696,132 +693,109 @@ static void gtco_urb_callback(struct urb *urbinfo) /* Fall thru */ case 1: - /* All reports have X and Y coords in the same place */ - val = le16_to_cpu(get_unaligned((__le16 *) &(device->buffer[1]))); + val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[1])); input_report_abs(inputdev, ABS_X, val); - val = le16_to_cpu(get_unaligned((__le16 *) &(device->buffer[3]))); + val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[3])); input_report_abs(inputdev, ABS_Y, val); - /* Ditto for proximity bit */ - if (device->buffer[5]& MASK_INRANGE){ - val = 1; - }else{ - val=0; - } + val = device->buffer[5] & MASK_INRANGE ? 1 : 0; input_report_abs(inputdev, ABS_DISTANCE, val); - /* Report 1 is an exception to how we handle buttons */ /* Buttons are an index, not a bitmask */ - if (device->buffer[0] == 1){ + if (device->buffer[0] == 1) { - /* Convert buttons, 5 bit index */ - /* Report value of index set as one, - the rest as 0 */ - val = device->buffer[5]& MASK_BUTTON; + /* + * Convert buttons, 5 bit index + * Report value of index set as one, + * the rest as 0 + */ + val = device->buffer[5] & MASK_BUTTON; dbg("======>>>>>>REPORT 1: val 0x%X(%d)", - val,val); + val, val); /* * We don't apply any meaning to the button * index, just report it */ input_event(inputdev, EV_MSC, MSC_SERIAL, val); - - } - break; + case 7: /* Menu blocks */ input_event(inputdev, EV_MSC, MSC_SCAN, device->buffer[1]); - - break; - } - - } + /* Other pid class */ - if ((inputdev->id.product == PID_400 )|| - (inputdev->id.product == PID_401 )) - { + if (inputdev->id.product == PID_400 || + inputdev->id.product == PID_401) { /* Report 2 */ - if (device->buffer[0] == 2){ + if (device->buffer[0] == 2) { /* Menu blocks */ - input_event(inputdev, EV_MSC, MSC_SCAN, - device->buffer[1]); + input_event(inputdev, EV_MSC, MSC_SCAN, device->buffer[1]); } /* Report 1 */ - if (device->buffer[0] == 1){ + if (device->buffer[0] == 1) { char buttonbyte; - /* IF X max > 64K, we still a bit from the y report */ - if (device->max_X > 0x10000){ + if (device->max_X > 0x10000) { - val = (u16)(((u16)(device->buffer[2]<<8))|((u8)(device->buffer[1]))); - val |= (u32)(((u8)device->buffer[3]&0x1)<< 16); + val = (u16)(((u16)(device->buffer[2] << 8)) | (u8)device->buffer[1]); + val |= (u32)(((u8)device->buffer[3] & 0x1) << 16); input_report_abs(inputdev, ABS_X, val); - le_buffer[0] = (u8)((u8)(device->buffer[3])>>1); - le_buffer[0] |= (u8)((device->buffer[3]&0x1)<<7); - - le_buffer[1] = (u8)(device->buffer[4]>>1); - le_buffer[1] |= (u8)((device->buffer[5]&0x1)<<7); + le_buffer[0] = (u8)((u8)(device->buffer[3]) >> 1); + le_buffer[0] |= (u8)((device->buffer[3] & 0x1) << 7); - val = le16_to_cpu(get_unaligned((__le16 *)(le_buffer))); + le_buffer[1] = (u8)(device->buffer[4] >> 1); + le_buffer[1] |= (u8)((device->buffer[5] & 0x1) << 7); + val = le16_to_cpu(get_unaligned((__le16 *)le_buffer)); input_report_abs(inputdev, ABS_Y, val); - /* * Shift the button byte right by one to * make it look like the standard report */ - buttonbyte = (device->buffer[5])>>1; - }else{ + buttonbyte = device->buffer[5] >> 1; + } else { - val = le16_to_cpu(get_unaligned((__le16 *) (&(device->buffer[1])))); + val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[1])); input_report_abs(inputdev, ABS_X, val); - val = le16_to_cpu(get_unaligned((__le16 *) (&(device->buffer[3])))); + val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[3])); input_report_abs(inputdev, ABS_Y, val); buttonbyte = device->buffer[5]; - } - /* BUTTONS and PROXIMITY */ - if (buttonbyte& MASK_INRANGE){ - val = 1; - }else{ - val=0; - } + val = buttonbyte & MASK_INRANGE ? 1 : 0; input_report_abs(inputdev, ABS_DISTANCE, val); /* Convert buttons, only 4 bits possible */ - val = buttonbyte&0x0F; + val = buttonbyte & 0x0F; #ifdef USE_BUTTONS - for ( i=0;i<5;i++){ - input_report_key(inputdev, BTN_DIGI+i,val&(1<buffer[6]); - } } @@ -833,10 +807,8 @@ static void gtco_urb_callback(struct urb *urbinfo) resubmit: rc = usb_submit_urb(urbinfo, GFP_ATOMIC); - if (rc != 0) { - err("usb_submit_urb failed rc=0x%x",rc); - } - + if (rc != 0) + err("usb_submit_urb failed rc=0x%x", rc); } /* @@ -854,58 +826,46 @@ static int gtco_probe(struct usb_interface *usbinterface, const struct usb_device_id *id) { - struct gtco *device = NULL; - char path[PATHLENGTH]; - struct input_dev *inputdev; + struct gtco *gtco; + struct input_dev *input_dev; struct hid_descriptor *hid_desc; - char *report; - int result=0, retry; + char *report = NULL; + int result = 0, retry; + int error; struct usb_endpoint_descriptor *endpoint; /* Allocate memory for device structure */ - device = kzalloc(sizeof(struct gtco), GFP_KERNEL); - if (device == NULL) { + gtco = kzalloc(sizeof(struct gtco), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!gtco || !input_dev) { err("No more memory"); - return -ENOMEM; + error = -ENOMEM; + goto err_free_devs; } - - device->inputdevice = input_allocate_device(); - if (!device->inputdevice){ - kfree(device); - err("No more memory"); - return -ENOMEM; - } - - /* Get pointer to the input device */ - inputdev = device->inputdevice; + /* Set pointer to the input device */ + gtco->inputdevice = input_dev; /* Save interface information */ - device->usbdev = usb_get_dev(interface_to_usbdev(usbinterface)); - + gtco->usbdev = usb_get_dev(interface_to_usbdev(usbinterface)); /* Allocate some data for incoming reports */ - device->buffer = usb_buffer_alloc(device->usbdev, REPORT_MAX_SIZE, - GFP_KERNEL, &(device->buf_dma)); - if (!device->buffer){ - input_free_device(device->inputdevice); - kfree(device); - err("No more memory"); - return -ENOMEM; + gtco->buffer = usb_buffer_alloc(gtco->usbdev, REPORT_MAX_SIZE, + GFP_KERNEL, >co->buf_dma); + if (!gtco->buffer) { + err("No more memory for us buffers"); + error = -ENOMEM; + goto err_free_devs; } /* Allocate URB for reports */ - device->urbinfo = usb_alloc_urb(0, GFP_KERNEL); - if (!device->urbinfo) { - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, - device->buffer, device->buf_dma); - input_free_device(device->inputdevice); - kfree(device); - err("No more memory"); + gtco->urbinfo = usb_alloc_urb(0, GFP_KERNEL); + if (!gtco->urbinfo) { + err("Failed to allocate URB"); return -ENOMEM; + goto err_free_buf; } - /* * The endpoint is always altsetting 0, we know this since we know * this device only has one interrupt endpoint @@ -913,51 +873,43 @@ static int gtco_probe(struct usb_interface *usbinterface, endpoint = &usbinterface->altsetting[0].endpoint[0].desc; /* Some debug */ - dbg("gtco # interfaces: %d",usbinterface->num_altsetting); - dbg("num endpoints: %d",usbinterface->cur_altsetting->desc.bNumEndpoints); - dbg("interface class: %d",usbinterface->cur_altsetting->desc.bInterfaceClass); - dbg("endpoint: attribute:0x%x type:0x%x",endpoint->bmAttributes,endpoint->bDescriptorType); + dbg("gtco # interfaces: %d", usbinterface->num_altsetting); + dbg("num endpoints: %d", usbinterface->cur_altsetting->desc.bNumEndpoints); + dbg("interface class: %d", usbinterface->cur_altsetting->desc.bInterfaceClass); + dbg("endpoint: attribute:0x%x type:0x%x", endpoint->bmAttributes, endpoint->bDescriptorType); if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) dbg("endpoint: we have interrupt endpoint\n"); - dbg("endpoint extra len:%d ",usbinterface->altsetting[0].extralen); - - + dbg("endpoint extra len:%d ", usbinterface->altsetting[0].extralen); /* * Find the HID descriptor so we can find out the size of the * HID report descriptor */ if (usb_get_extra_descriptor(usbinterface->cur_altsetting, - HID_DEVICE_TYPE,&hid_desc) != 0){ + HID_DEVICE_TYPE, &hid_desc) != 0){ err("Can't retrieve exta USB descriptor to get hid report descriptor length"); - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, - device->buffer, device->buf_dma); - input_free_device(device->inputdevice); - kfree(device); - return -EIO; + error = -EIO; + goto err_free_urb; } dbg("Extra descriptor success: type:%d len:%d", hid_desc->bDescriptorType, hid_desc->wDescriptorLength); - if (!(report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL))) { - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, - device->buffer, device->buf_dma); - - input_free_device(device->inputdevice); - kfree(device); - err("No more memory"); - return -ENOMEM; + report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); + if (!report) { + err("No more memory for report"); + error = -ENOMEM; + goto err_free_urb; } /* Couple of tries to get reply */ - for (retry=0;retry<3;retry++) { - result = usb_control_msg(device->usbdev, - usb_rcvctrlpipe(device->usbdev, 0), + for (retry = 0; retry < 3; retry++) { + result = usb_control_msg(gtco->usbdev, + usb_rcvctrlpipe(gtco->usbdev, 0), USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (REPORT_DEVICE_TYPE << 8), + REPORT_DEVICE_TYPE << 8, 0, /* interface */ report, hid_desc->wDescriptorLength, @@ -969,72 +921,75 @@ static int gtco_probe(struct usb_interface *usbinterface, /* If we didn't get the report, fail */ dbg("usb_control_msg result: :%d", result); - if (result != hid_desc->wDescriptorLength){ - kfree(report); - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, - device->buffer, device->buf_dma); - input_free_device(device->inputdevice); - kfree(device); + if (result != hid_desc->wDescriptorLength) { err("Failed to get HID Report Descriptor of size: %d", hid_desc->wDescriptorLength); - return -EIO; + error = -EIO; + goto err_free_urb; } - /* Now we parse the report */ - parse_hid_report_descriptor(device,report,result); + parse_hid_report_descriptor(gtco, report, result); /* Now we delete it */ kfree(report); /* Create a device file node */ - usb_make_path(device->usbdev, path, PATHLENGTH); - sprintf(device->usbpath, "%s/input0", path); - + usb_make_path(gtco->usbdev, gtco->usbpath, sizeof(gtco->usbpath)); + strlcat(gtco->usbpath, "/input0", sizeof(gtco->usbpath)); /* Set Input device functions */ - inputdev->open = gtco_input_open; - inputdev->close = gtco_input_close; + input_dev->open = gtco_input_open; + input_dev->close = gtco_input_close; /* Set input device information */ - inputdev->name = "GTCO_CalComp"; - inputdev->phys = device->usbpath; - inputdev->private = device; - + input_dev->name = "GTCO_CalComp"; + input_dev->phys = gtco->usbpath; + input_dev->private = gtco; /* Now set up all the input device capabilities */ - gtco_setup_caps(inputdev); + gtco_setup_caps(input_dev); /* Set input device required ID information */ - usb_to_input_id(device->usbdev, &device->inputdevice->id); - inputdev->cdev.dev = &usbinterface->dev; + usb_to_input_id(gtco->usbdev, &input_dev->id); + input_dev->cdev.dev = &usbinterface->dev; /* Setup the URB, it will be posted later on open of input device */ endpoint = &usbinterface->altsetting[0].endpoint[0].desc; - usb_fill_int_urb(device->urbinfo, - device->usbdev, - usb_rcvintpipe(device->usbdev, + usb_fill_int_urb(gtco->urbinfo, + gtco->usbdev, + usb_rcvintpipe(gtco->usbdev, endpoint->bEndpointAddress), - device->buffer, + gtco->buffer, REPORT_MAX_SIZE, gtco_urb_callback, - device, + gtco, endpoint->bInterval); - device->urbinfo->transfer_dma = device->buf_dma; - device->urbinfo->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - + gtco->urbinfo->transfer_dma = gtco->buf_dma; + gtco->urbinfo->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - /* Save device pointer in USB interface device */ - usb_set_intfdata(usbinterface, device); + /* Save gtco pointer in USB interface gtco */ + usb_set_intfdata(usbinterface, gtco); /* All done, now register the input device */ - input_register_device(inputdev); + error = input_register_device(input_dev); + if (error) + goto err_free_urb; - info( "gtco driver created usb: %s\n", path); return 0; + err_free_urb: + usb_free_urb(gtco->urbinfo); + err_free_buf: + usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE, + gtco->buffer, gtco->buf_dma); + err_free_devs: + kfree(report); + input_free_device(input_dev); + kfree(gtco); + return error; } /* @@ -1044,50 +999,46 @@ static int gtco_probe(struct usb_interface *usbinterface, */ static void gtco_disconnect(struct usb_interface *interface) { - /* Grab private device ptr */ - struct gtco *device = usb_get_intfdata (interface); - struct input_dev *inputdev; - - inputdev = device->inputdevice; + struct gtco *gtco = usb_get_intfdata(interface); /* Now reverse all the registration stuff */ - if (device) { - input_unregister_device(inputdev); - usb_kill_urb(device->urbinfo); - usb_free_urb(device->urbinfo); - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, - device->buffer, device->buf_dma); - kfree(device); + if (gtco) { + input_unregister_device(gtco->inputdevice); + usb_kill_urb(gtco->urbinfo); + usb_free_urb(gtco->urbinfo); + usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE, + gtco->buffer, gtco->buf_dma); + kfree(gtco); } info("gtco driver disconnected"); } - /* STANDARD MODULE LOAD ROUTINES */ static struct usb_driver gtco_driverinfo_table = { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) - .owner = THIS_MODULE, -#endif - .name = "gtco", - .id_table = gtco_usbid_table, - .probe = gtco_probe, - .disconnect = gtco_disconnect, + .name = "gtco", + .id_table = gtco_usbid_table, + .probe = gtco_probe, + .disconnect = gtco_disconnect, }; + /* * Register this module with the USB subsystem */ static int __init gtco_init(void) { - int rc; - rc = usb_register(>co_driverinfo_table); - if (rc) { - err("usb_register() failed rc=0x%x", rc); + int error; + + error = usb_register(>co_driverinfo_table); + if (error) { + err("usb_register() failed rc=0x%x", error); + return error; } - printk("GTCO usb driver version: %s",GTCO_VERSION); - return rc; + + printk("GTCO usb driver version: %s", GTCO_VERSION); + return 0; } /* @@ -1098,7 +1049,7 @@ static void __exit gtco_exit(void) usb_deregister(>co_driverinfo_table); } -module_init (gtco_init); -module_exit (gtco_exit); +module_init(gtco_init); +module_exit(gtco_exit); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From a1421d3c780c373d5f74a0ab99b0652041d61876 Mon Sep 17 00:00:00 2001 From: Peter Stokes Date: Thu, 12 Apr 2007 01:33:10 -0400 Subject: Input: add logical channel support for ATI Remote Wonder II The ATI Remote Wonder II can be configured with one of 16 unique logical channels. Allowing up to 16 remotes to be used independently within range of each other. This change adds functionality to configure the receiver and filter the input data to respond or exclude remotes configured with different logical channels. Signed-off-by: Peter Stokes Acked-by: Ville Syrjala Signed-off-by: Greg Kroah-Hartman Signed-off-by: Dmitry Torokhov diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c index 83f1f79..6459be9 100644 --- a/drivers/usb/input/ati_remote2.c +++ b/drivers/usb/input/ati_remote2.c @@ -2,6 +2,7 @@ * ati_remote2 - ATI/Philips USB RF remote driver * * Copyright (C) 2005 Ville Syrjala + * Copyright (C) 2007 Peter Stokes * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -11,13 +12,29 @@ #include #define DRIVER_DESC "ATI/Philips USB RF remote driver" -#define DRIVER_VERSION "0.1" +#define DRIVER_VERSION "0.2" MODULE_DESCRIPTION(DRIVER_DESC); MODULE_VERSION(DRIVER_VERSION); MODULE_AUTHOR("Ville Syrjala "); MODULE_LICENSE("GPL"); +/* + * ATI Remote Wonder II Channel Configuration + * + * The remote control can by assigned one of sixteen "channels" in order to facilitate + * the use of multiple remote controls within range of each other. + * A remote's "channel" may be altered by pressing and holding the "PC" button for + * approximately 3 seconds, after which the button will slowly flash the count of the + * currently configured "channel", using the numeric keypad enter a number between 1 and + * 16 and then the "PC" button again, the button will slowly flash the count of the + * newly configured "channel". + */ + +static unsigned int channel_mask = 0xFFFF; +module_param(channel_mask, uint, 0644); +MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); + static unsigned int mode_mask = 0x1F; module_param(mode_mask, uint, 0644); MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); @@ -146,15 +163,23 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2) { struct input_dev *idev = ar2->idev; u8 *data = ar2->buf[0]; + int channel, mode; + + channel = data[0] >> 4; + + if (!((1 << channel) & channel_mask)) + return; - if (data[0] > 4) { + mode = data[0] & 0x0F; + + if (mode > 4) { dev_err(&ar2->intf[0]->dev, "Unknown mode byte (%02x %02x %02x %02x)\n", data[3], data[2], data[1], data[0]); return; } - if (!((1 << data[0]) & mode_mask)) + if (!((1 << mode) & mode_mask)) return; input_event(idev, EV_REL, REL_X, (s8) data[1]); @@ -177,9 +202,16 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2) { struct input_dev *idev = ar2->idev; u8 *data = ar2->buf[1]; - int hw_code, index; + int channel, mode, hw_code, index; + + channel = data[0] >> 4; + + if (!((1 << channel) & channel_mask)) + return; - if (data[0] > 4) { + mode = data[0] & 0x0F; + + if (mode > 4) { dev_err(&ar2->intf[1]->dev, "Unknown mode byte (%02x %02x %02x %02x)\n", data[3], data[2], data[1], data[0]); @@ -199,16 +231,16 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2) * events for the mouse pad so we filter out any subsequent * events from the same mode key. */ - if (ar2->mode == data[0]) + if (ar2->mode == mode) return; if (data[1] == 0) - ar2->mode = data[0]; + ar2->mode = mode; - hw_code |= data[0] << 8; + hw_code |= mode << 8; } - if (!((1 << data[0]) & mode_mask)) + if (!((1 << mode) & mode_mask)) return; index = ati_remote2_lookup(hw_code); @@ -379,6 +411,41 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2) } } +static int ati_remote2_setup(struct ati_remote2 *ar2) +{ + int r, i, channel; + + /* + * Configure receiver to only accept input from remote "channel" + * channel == 0 -> Accept input from any remote channel + * channel == 1 -> Only accept input from remote channel 1 + * channel == 2 -> Only accept input from remote channel 2 + * ... + * channel == 16 -> Only accept input from remote channel 16 + */ + + channel = 0; + for (i = 0; i < 16; i++) { + if ((1 << i) & channel_mask) { + if (!(~(1 << i) & 0xFFFF & channel_mask)) + channel = i + 1; + break; + } + } + + r = usb_control_msg(ar2->udev, usb_sndctrlpipe(ar2->udev, 0), + 0x20, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + channel, 0x0, NULL, 0, USB_CTRL_SET_TIMEOUT); + if (r) { + dev_err(&ar2->udev->dev, "%s - failed to set channel due to error: %d\n", + __FUNCTION__, r); + return r; + } + + return 0; +} + static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); @@ -409,6 +476,10 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d if (r) goto fail2; + r = ati_remote2_setup(ar2); + if (r) + goto fail2; + usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); -- cgit v0.10.2 From 21298f7153f71c7fa70247518851f7aac41c4781 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:33:19 -0400 Subject: Input: logips2pp - add model 1 information It turns out I had an old 2-button Logitech mouse that responds to Logitech's queries with model of 1. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 74a8ba7..9df74b7 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -200,6 +200,7 @@ static void ps2pp_disconnect(struct psmouse *psmouse) static const struct ps2pp_info *get_model_info(unsigned char model) { static const struct ps2pp_info ps2pp_list[] = { + { 1, 0, 0 }, /* Simple 2-button mouse */ { 12, 0, PS2PP_SIDE_BTN}, { 13, 0, 0 }, { 15, PS2PP_KIND_MX, /* MX1000 */ -- cgit v0.10.2 From db61a9124880a1d79b7b320d4b6bef717f23e485 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:33:28 -0400 Subject: Input: remove old USB touchscreen drivers itmtoch, mtouchusb and touchkitusb have been replaced with composite usbtouchscreen driver and can be removed now. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index a9d206c..f8c35b6 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile @@ -38,9 +38,6 @@ obj-$(CONFIG_USB_KBD) += usbkbd.o obj-$(CONFIG_USB_KBTAB) += kbtab.o obj-$(CONFIG_USB_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_USB_MOUSE) += usbmouse.o -obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o -obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o -obj-$(CONFIG_USB_EGALAX) += touchkitusb.o obj-$(CONFIG_USB_TOUCHSCREEN) += usbtouchscreen.o obj-$(CONFIG_USB_POWERMATE) += powermate.o obj-$(CONFIG_USB_WACOM) += wacom.o diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c deleted file mode 100644 index aac968a..0000000 --- a/drivers/usb/input/itmtouch.c +++ /dev/null @@ -1,271 +0,0 @@ -/****************************************************************************** - * itmtouch.c -- Driver for ITM touchscreen panel - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Based upon original work by Chris Collins . - * - * Kudos to ITM for providing me with the datasheet for the panel, - * even though it was a day later than I had finished writing this - * driver. - * - * It has meant that I've been able to correct my interpretation of the - * protocol packets however. - * - * CC -- 2003/9/29 - * - * History - * 1.0 & 1.1 2003 (CC) vojtech@suse.cz - * Original version for 2.4.x kernels - * - * 1.2 02/03/2005 (HCE) hc@mivu.no - * Complete rewrite to support Linux 2.6.10, thanks to mtouchusb.c for hints. - * Unfortunately no calibration support at this time. - * - * 1.2.1 09/03/2005 (HCE) hc@mivu.no - * Code cleanup and adjusting syntax to start matching kernel standards - * - * 1.2.2 10/05/2006 (MJA) massad@gmail.com - * Flag for detecting if the screen was being touch was incorrectly - * inverted, so no touch events were being detected. - * - *****************************************************************************/ - -#include -#include -#include -#include -#include - -/* only an 8 byte buffer necessary for a single packet */ -#define ITM_BUFSIZE 8 -#define PATH_SIZE 64 - -#define USB_VENDOR_ID_ITMINC 0x0403 -#define USB_PRODUCT_ID_TOUCHPANEL 0xf9e9 - -#define DRIVER_AUTHOR "Hans-Christian Egtvedt " -#define DRIVER_VERSION "v1.2.2" -#define DRIVER_DESC "USB ITM Inc Touch Panel Driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); -MODULE_LICENSE( DRIVER_LICENSE ); - -struct itmtouch_dev { - struct usb_device *usbdev; /* usb device */ - struct input_dev *inputdev; /* input device */ - struct urb *readurb; /* urb */ - char rbuf[ITM_BUFSIZE]; /* data */ - int users; - char name[128]; - char phys[64]; -}; - -static struct usb_device_id itmtouch_ids [] = { - { USB_DEVICE(USB_VENDOR_ID_ITMINC, USB_PRODUCT_ID_TOUCHPANEL) }, - { } -}; - -static void itmtouch_irq(struct urb *urb) -{ - struct itmtouch_dev *itmtouch = urb->context; - unsigned char *data = urb->transfer_buffer; - struct input_dev *dev = itmtouch->inputdev; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ETIME: - /* this urb is timing out */ - dbg("%s - urb timed out - was the device unplugged?", - __FUNCTION__); - return; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __FUNCTION__, urb->status); - goto exit; - } - - /* if pressure has been released, then don't report X/Y */ - if (!(data[7] & 0x20)) { - input_report_abs(dev, ABS_X, (data[0] & 0x1F) << 7 | (data[3] & 0x7F)); - input_report_abs(dev, ABS_Y, (data[1] & 0x1F) << 7 | (data[4] & 0x7F)); - } - - input_report_abs(dev, ABS_PRESSURE, (data[2] & 1) << 7 | (data[5] & 0x7F)); - input_report_key(dev, BTN_TOUCH, ~data[7] & 0x20); - input_sync(dev); - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - printk(KERN_ERR "%s - usb_submit_urb failed with result: %d", - __FUNCTION__, retval); -} - -static int itmtouch_open(struct input_dev *input) -{ - struct itmtouch_dev *itmtouch = input->private; - - itmtouch->readurb->dev = itmtouch->usbdev; - - if (usb_submit_urb(itmtouch->readurb, GFP_KERNEL)) - return -EIO; - - return 0; -} - -static void itmtouch_close(struct input_dev *input) -{ - struct itmtouch_dev *itmtouch = input->private; - - usb_kill_urb(itmtouch->readurb); -} - -static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct itmtouch_dev *itmtouch; - struct input_dev *input_dev; - struct usb_host_interface *interface; - struct usb_endpoint_descriptor *endpoint; - struct usb_device *udev = interface_to_usbdev(intf); - unsigned int pipe; - unsigned int maxp; - - interface = intf->cur_altsetting; - endpoint = &interface->endpoint[0].desc; - - itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!itmtouch || !input_dev) { - err("%s - Out of memory.", __FUNCTION__); - goto fail; - } - - itmtouch->usbdev = udev; - itmtouch->inputdev = input_dev; - - if (udev->manufacturer) - strlcpy(itmtouch->name, udev->manufacturer, sizeof(itmtouch->name)); - - if (udev->product) { - if (udev->manufacturer) - strlcat(itmtouch->name, " ", sizeof(itmtouch->name)); - strlcat(itmtouch->name, udev->product, sizeof(itmtouch->name)); - } - - if (!strlen(itmtouch->name)) - sprintf(itmtouch->name, "USB ITM touchscreen"); - - usb_make_path(udev, itmtouch->phys, sizeof(itmtouch->phys)); - strlcpy(itmtouch->phys, "/input0", sizeof(itmtouch->phys)); - - input_dev->name = itmtouch->name; - input_dev->phys = itmtouch->phys; - usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; - input_dev->private = itmtouch; - - input_dev->open = itmtouch_open; - input_dev->close = itmtouch_close; - - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); - input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - - /* device limits */ - /* as specified by the ITM datasheet, X and Y are 12bit, - * Z (pressure) is 8 bit. However, the fields are defined up - * to 14 bits for future possible expansion. - */ - input_set_abs_params(input_dev, ABS_X, 0, 0x0FFF, 2, 0); - input_set_abs_params(input_dev, ABS_Y, 0, 0x0FFF, 2, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xFF, 2, 0); - - /* initialise the URB so we can read from the transport stream */ - pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress); - maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); - - if (maxp > ITM_BUFSIZE) - maxp = ITM_BUFSIZE; - - itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL); - if (!itmtouch->readurb) { - dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__); - goto fail; - } - - usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf, - maxp, itmtouch_irq, itmtouch, endpoint->bInterval); - - input_register_device(itmtouch->inputdev); - - usb_set_intfdata(intf, itmtouch); - - return 0; - - fail: input_free_device(input_dev); - kfree(itmtouch); - return -ENOMEM; -} - -static void itmtouch_disconnect(struct usb_interface *intf) -{ - struct itmtouch_dev *itmtouch = usb_get_intfdata(intf); - - usb_set_intfdata(intf, NULL); - - if (itmtouch) { - input_unregister_device(itmtouch->inputdev); - usb_kill_urb(itmtouch->readurb); - usb_free_urb(itmtouch->readurb); - kfree(itmtouch); - } -} - -MODULE_DEVICE_TABLE(usb, itmtouch_ids); - -static struct usb_driver itmtouch_driver = { - .name = "itmtouch", - .probe = itmtouch_probe, - .disconnect = itmtouch_disconnect, - .id_table = itmtouch_ids, -}; - -static int __init itmtouch_init(void) -{ - info(DRIVER_DESC " " DRIVER_VERSION); - info(DRIVER_AUTHOR); - return usb_register(&itmtouch_driver); -} - -static void __exit itmtouch_exit(void) -{ - usb_deregister(&itmtouch_driver); -} - -module_init(itmtouch_init); -module_exit(itmtouch_exit); diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c deleted file mode 100644 index 92c4e07..0000000 --- a/drivers/usb/input/mtouchusb.c +++ /dev/null @@ -1,332 +0,0 @@ -/****************************************************************************** - * mtouchusb.c -- Driver for Microtouch (Now 3M) USB Touchscreens - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Based upon original work by Radoslaw Garbacz (usb-support@ite.pl) - * (http://freshmeat.net/projects/3mtouchscreendriver) - * - * History - * - * 0.3 & 0.4 2002 (TEJ) tejohnson@yahoo.com - * Updated to 2.4.18, then 2.4.19 - * Old version still relied on stealing a minor - * - * 0.5 02/26/2004 (TEJ) tejohnson@yahoo.com - * Complete rewrite using Linux Input in 2.6.3 - * Unfortunately no calibration support at this time - * - * 1.4 04/25/2004 (TEJ) tejohnson@yahoo.com - * Changed reset from standard USB dev reset to vendor reset - * Changed data sent to host from compensated to raw coordinates - * Eliminated vendor/product module params - * Performed multiple successful tests with an EXII-5010UC - * - * 1.5 02/27/2005 ddstreet@ieee.org - * Added module parameter to select raw or hw-calibrated coordinate reporting - * - *****************************************************************************/ - -#include -#include -#include -#include -#include - -#define MTOUCHUSB_MIN_XC 0x0 -#define MTOUCHUSB_MAX_RAW_XC 0x4000 -#define MTOUCHUSB_MAX_CALIB_XC 0xffff -#define MTOUCHUSB_XC_FUZZ 0x0 -#define MTOUCHUSB_XC_FLAT 0x0 -#define MTOUCHUSB_MIN_YC 0x0 -#define MTOUCHUSB_MAX_RAW_YC 0x4000 -#define MTOUCHUSB_MAX_CALIB_YC 0xffff -#define MTOUCHUSB_YC_FUZZ 0x0 -#define MTOUCHUSB_YC_FLAT 0x0 - -#define MTOUCHUSB_ASYNC_REPORT 1 -#define MTOUCHUSB_RESET 7 -#define MTOUCHUSB_REPORT_DATA_SIZE 11 -#define MTOUCHUSB_REQ_CTRLLR_ID 10 - -#define MTOUCHUSB_GET_RAW_XC(data) (data[8]<<8 | data[7]) -#define MTOUCHUSB_GET_CALIB_XC(data) (data[4]<<8 | data[3]) -#define MTOUCHUSB_GET_RAW_YC(data) (data[10]<<8 | data[9]) -#define MTOUCHUSB_GET_CALIB_YC(data) (data[6]<<8 | data[5]) -#define MTOUCHUSB_GET_XC(data) (raw_coordinates ? \ - MTOUCHUSB_GET_RAW_XC(data) : \ - MTOUCHUSB_GET_CALIB_XC(data)) -#define MTOUCHUSB_GET_YC(data) (raw_coordinates ? \ - MTOUCHUSB_GET_RAW_YC(data) : \ - MTOUCHUSB_GET_CALIB_YC(data)) -#define MTOUCHUSB_GET_TOUCHED(data) ((data[2] & 0x40) ? 1:0) - -#define DRIVER_VERSION "v1.5" -#define DRIVER_AUTHOR "Todd E. Johnson, tejohnson@yahoo.com" -#define DRIVER_DESC "3M USB Touchscreen Driver" -#define DRIVER_LICENSE "GPL" - -static int raw_coordinates = 1; - -module_param(raw_coordinates, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(raw_coordinates, "report raw coordinate values (y, default) or hardware-calibrated coordinate values (n)"); - -struct mtouch_usb { - unsigned char *data; - dma_addr_t data_dma; - struct urb *irq; - struct usb_device *udev; - struct input_dev *input; - char name[128]; - char phys[64]; -}; - -static struct usb_device_id mtouchusb_devices[] = { - { USB_DEVICE(0x0596, 0x0001) }, - { } -}; - -static void mtouchusb_irq(struct urb *urb) -{ - struct mtouch_usb *mtouch = urb->context; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ETIME: - /* this urb is timing out */ - dbg("%s - urb timed out - was the device unplugged?", - __FUNCTION__); - return; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __FUNCTION__, urb->status); - goto exit; - } - - input_report_key(mtouch->input, BTN_TOUCH, - MTOUCHUSB_GET_TOUCHED(mtouch->data)); - input_report_abs(mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data)); - input_report_abs(mtouch->input, ABS_Y, - (raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC) - - MTOUCHUSB_GET_YC(mtouch->data)); - input_sync(mtouch->input); - -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - err("%s - usb_submit_urb failed with result: %d", - __FUNCTION__, retval); -} - -static int mtouchusb_open(struct input_dev *input) -{ - struct mtouch_usb *mtouch = input->private; - - mtouch->irq->dev = mtouch->udev; - - if (usb_submit_urb(mtouch->irq, GFP_ATOMIC)) - return -EIO; - - return 0; -} - -static void mtouchusb_close(struct input_dev *input) -{ - struct mtouch_usb *mtouch = input->private; - - usb_kill_urb(mtouch->irq); -} - -static int mtouchusb_alloc_buffers(struct usb_device *udev, struct mtouch_usb *mtouch) -{ - dbg("%s - called", __FUNCTION__); - - mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE, - GFP_ATOMIC, &mtouch->data_dma); - - if (!mtouch->data) - return -1; - - return 0; -} - -static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *mtouch) -{ - dbg("%s - called", __FUNCTION__); - - if (mtouch->data) - usb_buffer_free(udev, MTOUCHUSB_REPORT_DATA_SIZE, - mtouch->data, mtouch->data_dma); -} - -static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct mtouch_usb *mtouch; - struct input_dev *input_dev; - struct usb_host_interface *interface; - struct usb_endpoint_descriptor *endpoint; - struct usb_device *udev = interface_to_usbdev(intf); - int nRet; - - dbg("%s - called", __FUNCTION__); - - dbg("%s - setting interface", __FUNCTION__); - interface = intf->cur_altsetting; - - dbg("%s - setting endpoint", __FUNCTION__); - endpoint = &interface->endpoint[0].desc; - - mtouch = kzalloc(sizeof(struct mtouch_usb), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!mtouch || !input_dev) { - err("%s - Out of memory.", __FUNCTION__); - goto fail1; - } - - dbg("%s - allocating buffers", __FUNCTION__); - if (mtouchusb_alloc_buffers(udev, mtouch)) - goto fail2; - - mtouch->udev = udev; - mtouch->input = input_dev; - - if (udev->manufacturer) - strlcpy(mtouch->name, udev->manufacturer, sizeof(mtouch->name)); - - if (udev->product) { - if (udev->manufacturer) - strlcat(mtouch->name, " ", sizeof(mtouch->name)); - strlcat(mtouch->name, udev->product, sizeof(mtouch->name)); - } - - if (!strlen(mtouch->name)) - snprintf(mtouch->name, sizeof(mtouch->name), - "USB Touchscreen %04x:%04x", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); - - usb_make_path(udev, mtouch->phys, sizeof(mtouch->phys)); - strlcpy(mtouch->phys, "/input0", sizeof(mtouch->phys)); - - input_dev->name = mtouch->name; - input_dev->phys = mtouch->phys; - usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; - input_dev->private = mtouch; - - input_dev->open = mtouchusb_open; - input_dev->close = mtouchusb_close; - - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, MTOUCHUSB_MIN_XC, - raw_coordinates ? MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC, - MTOUCHUSB_XC_FUZZ, MTOUCHUSB_XC_FLAT); - input_set_abs_params(input_dev, ABS_Y, MTOUCHUSB_MIN_YC, - raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC, - MTOUCHUSB_YC_FUZZ, MTOUCHUSB_YC_FLAT); - - nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0), - MTOUCHUSB_RESET, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); - dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d", - __FUNCTION__, nRet); - - dbg("%s - usb_alloc_urb: mtouch->irq", __FUNCTION__); - mtouch->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!mtouch->irq) { - dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__); - goto fail2; - } - - dbg("%s - usb_fill_int_urb", __FUNCTION__); - usb_fill_int_urb(mtouch->irq, mtouch->udev, - usb_rcvintpipe(mtouch->udev, 0x81), - mtouch->data, MTOUCHUSB_REPORT_DATA_SIZE, - mtouchusb_irq, mtouch, endpoint->bInterval); - - dbg("%s - input_register_device", __FUNCTION__); - input_register_device(mtouch->input); - - nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0), - MTOUCHUSB_ASYNC_REPORT, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); - dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", - __FUNCTION__, nRet); - - usb_set_intfdata(intf, mtouch); - return 0; - -fail2: mtouchusb_free_buffers(udev, mtouch); -fail1: input_free_device(input_dev); - kfree(mtouch); - return -ENOMEM; -} - -static void mtouchusb_disconnect(struct usb_interface *intf) -{ - struct mtouch_usb *mtouch = usb_get_intfdata(intf); - - dbg("%s - called", __FUNCTION__); - usb_set_intfdata(intf, NULL); - if (mtouch) { - dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__); - usb_kill_urb(mtouch->irq); - input_unregister_device(mtouch->input); - usb_free_urb(mtouch->irq); - mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch); - kfree(mtouch); - } -} - -MODULE_DEVICE_TABLE(usb, mtouchusb_devices); - -static struct usb_driver mtouchusb_driver = { - .name = "mtouchusb", - .probe = mtouchusb_probe, - .disconnect = mtouchusb_disconnect, - .id_table = mtouchusb_devices, -}; - -static int __init mtouchusb_init(void) -{ - dbg("%s - called", __FUNCTION__); - return usb_register(&mtouchusb_driver); -} - -static void __exit mtouchusb_cleanup(void) -{ - dbg("%s - called", __FUNCTION__); - usb_deregister(&mtouchusb_driver); -} - -module_init(mtouchusb_init); -module_exit(mtouchusb_cleanup); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c deleted file mode 100644 index 2a314b0..0000000 --- a/drivers/usb/input/touchkitusb.c +++ /dev/null @@ -1,392 +0,0 @@ -/****************************************************************************** - * touchkitusb.c -- Driver for eGalax TouchKit USB Touchscreens - * - * Copyright (C) 2004-2005 by Daniel Ritz - * Copyright (C) by Todd E. Johnson (mtouchusb.c) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Based upon mtouchusb.c - * - *****************************************************************************/ - -//#define DEBUG - -#include -#include -#include -#include -#include - -#define TOUCHKIT_MIN_XC 0x0 -#define TOUCHKIT_MAX_XC 0x07ff -#define TOUCHKIT_XC_FUZZ 0x0 -#define TOUCHKIT_XC_FLAT 0x0 -#define TOUCHKIT_MIN_YC 0x0 -#define TOUCHKIT_MAX_YC 0x07ff -#define TOUCHKIT_YC_FUZZ 0x0 -#define TOUCHKIT_YC_FLAT 0x0 -#define TOUCHKIT_REPORT_DATA_SIZE 16 - -#define TOUCHKIT_DOWN 0x01 - -#define TOUCHKIT_PKT_TYPE_MASK 0xFE -#define TOUCHKIT_PKT_TYPE_REPT 0x80 -#define TOUCHKIT_PKT_TYPE_DIAG 0x0A - -#define DRIVER_VERSION "v0.1" -#define DRIVER_AUTHOR "Daniel Ritz " -#define DRIVER_DESC "eGalax TouchKit USB HID Touchscreen Driver" - -static int swap_xy; -module_param(swap_xy, bool, 0644); -MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); - -struct touchkit_usb { - unsigned char *data; - dma_addr_t data_dma; - char buffer[TOUCHKIT_REPORT_DATA_SIZE]; - int buf_len; - struct urb *irq; - struct usb_device *udev; - struct input_dev *input; - char name[128]; - char phys[64]; -}; - -static struct usb_device_id touchkit_devices[] = { - {USB_DEVICE(0x3823, 0x0001)}, - {USB_DEVICE(0x0123, 0x0001)}, - {USB_DEVICE(0x0eef, 0x0001)}, - {USB_DEVICE(0x0eef, 0x0002)}, - {} -}; - -/* helpers to read the data */ -static inline int touchkit_get_touched(char *data) -{ - return (data[0] & TOUCHKIT_DOWN) ? 1 : 0; -} - -static inline int touchkit_get_x(char *data) -{ - return ((data[3] & 0x0F) << 7) | (data[4] & 0x7F); -} - -static inline int touchkit_get_y(char *data) -{ - return ((data[1] & 0x0F) << 7) | (data[2] & 0x7F); -} - - -/* processes one input packet. */ -static void touchkit_process_pkt(struct touchkit_usb *touchkit, char *pkt) -{ - int x, y; - - /* only process report packets */ - if ((pkt[0] & TOUCHKIT_PKT_TYPE_MASK) != TOUCHKIT_PKT_TYPE_REPT) - return; - - if (swap_xy) { - y = touchkit_get_x(pkt); - x = touchkit_get_y(pkt); - } else { - x = touchkit_get_x(pkt); - y = touchkit_get_y(pkt); - } - - input_report_key(touchkit->input, BTN_TOUCH, touchkit_get_touched(pkt)); - input_report_abs(touchkit->input, ABS_X, x); - input_report_abs(touchkit->input, ABS_Y, y); - input_sync(touchkit->input); -} - - -static int touchkit_get_pkt_len(char *buf) -{ - switch (buf[0] & TOUCHKIT_PKT_TYPE_MASK) { - case TOUCHKIT_PKT_TYPE_REPT: - return 5; - - case TOUCHKIT_PKT_TYPE_DIAG: - return buf[1] + 2; - } - - return 0; -} - -static void touchkit_process(struct touchkit_usb *touchkit, int len) -{ - char *buffer; - int pkt_len, buf_len, pos; - - /* if the buffer contains data, append */ - if (unlikely(touchkit->buf_len)) { - int tmp; - - /* if only 1 byte in buffer, add another one to get length */ - if (touchkit->buf_len == 1) - touchkit->buffer[1] = touchkit->data[0]; - - pkt_len = touchkit_get_pkt_len(touchkit->buffer); - - /* unknown packet: drop everything */ - if (!pkt_len) - return; - - /* append, process */ - tmp = pkt_len - touchkit->buf_len; - memcpy(touchkit->buffer + touchkit->buf_len, touchkit->data, tmp); - touchkit_process_pkt(touchkit, touchkit->buffer); - - buffer = touchkit->data + tmp; - buf_len = len - tmp; - } else { - buffer = touchkit->data; - buf_len = len; - } - - /* only one byte left in buffer */ - if (unlikely(buf_len == 1)) { - touchkit->buffer[0] = buffer[0]; - touchkit->buf_len = 1; - return; - } - - /* loop over the buffer */ - pos = 0; - while (pos < buf_len) { - /* get packet len */ - pkt_len = touchkit_get_pkt_len(buffer + pos); - - /* unknown packet: drop everything */ - if (unlikely(!pkt_len)) - return; - - /* full packet: process */ - if (likely(pkt_len <= buf_len)) { - touchkit_process_pkt(touchkit, buffer + pos); - } else { - /* incomplete packet: save in buffer */ - memcpy(touchkit->buffer, buffer + pos, buf_len - pos); - touchkit->buf_len = buf_len - pos; - } - pos += pkt_len; - } -} - - -static void touchkit_irq(struct urb *urb) -{ - struct touchkit_usb *touchkit = urb->context; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ETIME: - /* this urb is timing out */ - dbg("%s - urb timed out - was the device unplugged?", - __FUNCTION__); - return; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __FUNCTION__, urb->status); - goto exit; - } - - touchkit_process(touchkit, urb->actual_length); - -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - err("%s - usb_submit_urb failed with result: %d", - __FUNCTION__, retval); -} - -static int touchkit_open(struct input_dev *input) -{ - struct touchkit_usb *touchkit = input->private; - - touchkit->irq->dev = touchkit->udev; - - if (usb_submit_urb(touchkit->irq, GFP_ATOMIC)) - return -EIO; - - return 0; -} - -static void touchkit_close(struct input_dev *input) -{ - struct touchkit_usb *touchkit = input->private; - - usb_kill_urb(touchkit->irq); -} - -static int touchkit_alloc_buffers(struct usb_device *udev, - struct touchkit_usb *touchkit) -{ - touchkit->data = usb_buffer_alloc(udev, TOUCHKIT_REPORT_DATA_SIZE, - GFP_ATOMIC, &touchkit->data_dma); - - if (!touchkit->data) - return -1; - - return 0; -} - -static void touchkit_free_buffers(struct usb_device *udev, - struct touchkit_usb *touchkit) -{ - if (touchkit->data) - usb_buffer_free(udev, TOUCHKIT_REPORT_DATA_SIZE, - touchkit->data, touchkit->data_dma); -} - -static int touchkit_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct touchkit_usb *touchkit; - struct input_dev *input_dev; - struct usb_host_interface *interface; - struct usb_endpoint_descriptor *endpoint; - struct usb_device *udev = interface_to_usbdev(intf); - - interface = intf->cur_altsetting; - endpoint = &interface->endpoint[0].desc; - - touchkit = kzalloc(sizeof(struct touchkit_usb), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!touchkit || !input_dev) - goto out_free; - - if (touchkit_alloc_buffers(udev, touchkit)) - goto out_free; - - touchkit->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!touchkit->irq) { - dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__); - goto out_free_buffers; - } - - touchkit->udev = udev; - touchkit->input = input_dev; - - if (udev->manufacturer) - strlcpy(touchkit->name, udev->manufacturer, sizeof(touchkit->name)); - - if (udev->product) { - if (udev->manufacturer) - strlcat(touchkit->name, " ", sizeof(touchkit->name)); - strlcat(touchkit->name, udev->product, sizeof(touchkit->name)); - } - - if (!strlen(touchkit->name)) - snprintf(touchkit->name, sizeof(touchkit->name), - "USB Touchscreen %04x:%04x", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); - - usb_make_path(udev, touchkit->phys, sizeof(touchkit->phys)); - strlcpy(touchkit->phys, "/input0", sizeof(touchkit->phys)); - - input_dev->name = touchkit->name; - input_dev->phys = touchkit->phys; - usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; - input_dev->private = touchkit; - input_dev->open = touchkit_open; - input_dev->close = touchkit_close; - - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, TOUCHKIT_MIN_XC, TOUCHKIT_MAX_XC, - TOUCHKIT_XC_FUZZ, TOUCHKIT_XC_FLAT); - input_set_abs_params(input_dev, ABS_Y, TOUCHKIT_MIN_YC, TOUCHKIT_MAX_YC, - TOUCHKIT_YC_FUZZ, TOUCHKIT_YC_FLAT); - - usb_fill_int_urb(touchkit->irq, touchkit->udev, - usb_rcvintpipe(touchkit->udev, 0x81), - touchkit->data, TOUCHKIT_REPORT_DATA_SIZE, - touchkit_irq, touchkit, endpoint->bInterval); - - touchkit->irq->transfer_dma = touchkit->data_dma; - touchkit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - input_register_device(touchkit->input); - - usb_set_intfdata(intf, touchkit); - return 0; - -out_free_buffers: - touchkit_free_buffers(udev, touchkit); -out_free: - input_free_device(input_dev); - kfree(touchkit); - return -ENOMEM; -} - -static void touchkit_disconnect(struct usb_interface *intf) -{ - struct touchkit_usb *touchkit = usb_get_intfdata(intf); - - dbg("%s - called", __FUNCTION__); - - if (!touchkit) - return; - - dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__); - usb_set_intfdata(intf, NULL); - usb_kill_urb(touchkit->irq); - input_unregister_device(touchkit->input); - usb_free_urb(touchkit->irq); - touchkit_free_buffers(interface_to_usbdev(intf), touchkit); - kfree(touchkit); -} - -MODULE_DEVICE_TABLE(usb, touchkit_devices); - -static struct usb_driver touchkit_driver = { - .name = "touchkitusb", - .probe = touchkit_probe, - .disconnect = touchkit_disconnect, - .id_table = touchkit_devices, -}; - -static int __init touchkit_init(void) -{ - return usb_register(&touchkit_driver); -} - -static void __exit touchkit_cleanup(void) -{ - usb_deregister(&touchkit_driver); -} - -module_init(touchkit_init); -module_exit(touchkit_cleanup); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 5014186de89708d0e9eed60526b698d5b786b707 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:33:39 -0400 Subject: Input: USB devices - handle errors when registering input devices Signed-off-by: Dmitry Torokhov diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index 909138e..270bb05 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c @@ -135,6 +135,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ struct usb_acecad *acecad; struct input_dev *input_dev; int pipe, maxp; + int err = -ENOMEM; if (interface->desc.bNumEndpoints != 1) return -ENODEV; @@ -149,16 +150,22 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL); input_dev = input_allocate_device(); - if (!acecad || !input_dev) + if (!acecad || !input_dev) { + err = -ENOMEM; goto fail1; + } acecad->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &acecad->data_dma); - if (!acecad->data) + if (!acecad->data) { + err= -ENOMEM; goto fail1; + } acecad->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!acecad->irq) + if (!acecad->irq) { + err = -ENOMEM; goto fail2; + } acecad->usbdev = dev; acecad->input = input_dev; @@ -221,7 +228,9 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ acecad->irq->transfer_dma = acecad->data_dma; acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - input_register_device(acecad->input); + err = input_register_device(acecad->input); + if (err) + goto fail2; usb_set_intfdata(intf, acecad); @@ -230,7 +239,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ fail2: usb_buffer_free(dev, 8, acecad->data, acecad->data_dma); fail1: input_free_device(input_dev); kfree(acecad); - return -ENOMEM; + return err; } static void usb_acecad_disconnect(struct usb_interface *intf) diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index f857935..8c1ab1c 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -1972,6 +1972,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) AIPTEK_PROGRAMMABLE_DELAY_200, AIPTEK_PROGRAMMABLE_DELAY_300 }; + int err = -ENOMEM; /* programmableDelay is where the command-line specified * delay is kept. We make it the first element of speeds[], @@ -2133,7 +2134,9 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Register the tablet as an Input Device */ - input_register_device(aiptek->inputdev); + err = input_register_device(aiptek->inputdev); + if (err) + goto fail2; /* We now will look for the evdev device which is mapped to * the tablet. The partial name is kept in the link list of @@ -2165,23 +2168,13 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) return 0; -fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, + fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, aiptek->data_dma); -fail1: input_free_device(inputdev); + fail1: input_free_device(inputdev); kfree(aiptek); - return -ENOMEM; + return err; } -/* Forward declaration */ -static void aiptek_disconnect(struct usb_interface *intf); - -static struct usb_driver aiptek_driver = { - .name = "aiptek", - .probe = aiptek_probe, - .disconnect = aiptek_disconnect, - .id_table = aiptek_ids, -}; - /*********************************************************************** * Deal with tablet disconnecting from the system. */ @@ -2206,6 +2199,13 @@ static void aiptek_disconnect(struct usb_interface *intf) } } +static struct usb_driver aiptek_driver = { + .name = "aiptek", + .probe = aiptek_probe, + .disconnect = aiptek_disconnect, + .id_table = aiptek_ids, +}; + static int __init aiptek_init(void) { int result = usb_register(&aiptek_driver); diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index c77291d..3622132 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c @@ -491,8 +491,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int int_in_endpointAddr = 0; - int i, retval = -ENOMEM; - + int i, error = -ENOMEM; /* set up the endpoint information */ /* use only the first interrupt-in endpoint */ @@ -567,17 +566,13 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id } dev->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->urb) { - retval = -ENOMEM; + if (!dev->urb) goto err_free_devs; - } dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL, &dev->urb->transfer_dma); - if (!dev->data) { - retval = -ENOMEM; + if (!dev->data) goto err_free_urb; - } usb_fill_int_urb(dev->urb, udev, usb_rcvintpipe(udev, int_in_endpointAddr), @@ -633,20 +628,25 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); set_bit(BTN_LEFT, input_dev->keybit); - input_register_device(dev->input); + error = input_register_device(dev->input); + if (error) + goto err_free_buffer; /* save our data pointer in this interface device */ usb_set_intfdata(iface, dev); return 0; + err_free_buffer: + usb_buffer_free(dev->udev, dev->datalen, + dev->data, dev->urb->transfer_dma); err_free_urb: usb_free_urb(dev->urb); err_free_devs: usb_set_intfdata(iface, NULL); kfree(dev); input_free_device(input_dev); - return retval; + return error; } static void atp_disconnect(struct usb_interface *iface) diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index b724e36..a1ae9ee 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c @@ -772,15 +772,17 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de goto fail3; /* Set up and register input device */ - input_register_device(ati_remote->idev); + err = input_register_device(ati_remote->idev); + if (err) + goto fail3; usb_set_intfdata(interface, ati_remote); return 0; -fail3: usb_kill_urb(ati_remote->irq_urb); + fail3: usb_kill_urb(ati_remote->irq_urb); usb_kill_urb(ati_remote->out_urb); -fail2: ati_remote_free_buffers(ati_remote); -fail1: input_free_device(input_dev); + fail2: ati_remote_free_buffers(ati_remote); + fail1: input_free_device(input_dev); kfree(ati_remote); return err; } diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c index 6459be9..5656278 100644 --- a/drivers/usb/input/ati_remote2.c +++ b/drivers/usb/input/ati_remote2.c @@ -337,7 +337,7 @@ static void ati_remote2_complete_key(struct urb *urb) static int ati_remote2_input_init(struct ati_remote2 *ar2) { struct input_dev *idev; - int i; + int i, retval; idev = input_allocate_device(); if (!idev) @@ -364,11 +364,11 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) usb_to_input_id(ar2->udev, &idev->id); idev->cdev.dev = &ar2->udev->dev; - i = input_register_device(idev); - if (i) + retval = input_register_device(idev); + if (retval) input_free_device(idev); - return i; + return retval; } static int ati_remote2_urb_init(struct ati_remote2 *ar2) diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index fedbcb1..64da987 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c @@ -122,6 +122,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_endpoint_descriptor *endpoint; struct kbtab *kbtab; struct input_dev *input_dev; + int error = -ENOMEM; kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL); input_dev = input_allocate_device(); @@ -168,15 +169,19 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i kbtab->irq->transfer_dma = kbtab->data_dma; kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - input_register_device(kbtab->dev); + error = input_register_device(kbtab->dev); + if (error) + goto fail3; usb_set_intfdata(intf, kbtab); + return 0; -fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma); -fail1: input_free_device(input_dev); + fail3: usb_free_urb(kbtab->irq); + fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma); + fail1: input_free_device(input_dev); kfree(kbtab); - return -ENOMEM; + return error; } static void kbtab_disconnect(struct usb_interface *intf) diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index 98bd323..d32a768 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c @@ -437,7 +437,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic struct usb_endpoint_descriptor *endpoint; struct usb_keyspan *remote; struct input_dev *input_dev; - int i, retval; + int i, error; endpoint = keyspan_get_in_endpoint(interface->cur_altsetting); if (!endpoint) @@ -446,7 +446,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic remote = kzalloc(sizeof(*remote), GFP_KERNEL); input_dev = input_allocate_device(); if (!remote || !input_dev) { - retval = -ENOMEM; + error = -ENOMEM; goto fail1; } @@ -458,19 +458,19 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma); if (!remote->in_buffer) { - retval = -ENOMEM; + error = -ENOMEM; goto fail1; } remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); if (!remote->irq_urb) { - retval = -ENOMEM; + error = -ENOMEM; goto fail2; } - retval = keyspan_setup(udev); - if (retval) { - retval = -ENODEV; + error = keyspan_setup(udev); + if (error) { + error = -ENODEV; goto fail3; } @@ -517,7 +517,9 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* we can register the device now, as it is ready */ - input_register_device(remote->input); + error = input_register_device(remote->input); + if (error) + goto fail3; /* save our data pointer in this interface device */ usb_set_intfdata(interface, remote); @@ -529,7 +531,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic fail1: kfree(remote); input_free_device(input_dev); - return retval; + return error; } /* diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index fea97e5..ce27449 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c @@ -308,7 +308,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i struct powermate_device *pm; struct input_dev *input_dev; int pipe, maxp; - int err = -ENOMEM; + int error = -ENOMEM; interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; @@ -387,11 +387,14 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i /* register our interrupt URB with the USB system */ if (usb_submit_urb(pm->irq, GFP_KERNEL)) { - err = -EIO; + error = -EIO; goto fail4; } - input_register_device(pm->input); + error = input_register_device(pm->input); + if (error) + goto fail5; + /* force an update of everything */ pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS; @@ -400,12 +403,13 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i usb_set_intfdata(intf, pm); return 0; -fail4: usb_free_urb(pm->config); -fail3: usb_free_urb(pm->irq); -fail2: powermate_free_buffers(udev, pm); -fail1: input_free_device(input_dev); + fail5: usb_kill_urb(pm->irq); + fail4: usb_free_urb(pm->config); + fail3: usb_free_urb(pm->irq); + fail2: powermate_free_buffers(udev, pm); + fail1: input_free_device(input_dev); kfree(pm); - return err; + return error; } /* Called when a USB device we've accepted ownership of is removed */ diff --git a/drivers/usb/input/wacom_sys.c b/drivers/usb/input/wacom_sys.c index 12b4274..48988e6 100644 --- a/drivers/usb/input/wacom_sys.c +++ b/drivers/usb/input/wacom_sys.c @@ -201,6 +201,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i struct wacom *wacom; struct wacom_wac *wacom_wac; struct input_dev *input_dev; + int error = -ENOMEM; char rep_data[2], limit = 0; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); @@ -252,7 +253,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom->irq->transfer_dma = wacom->data_dma; wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - input_register_device(wacom->dev); + error = input_register_device(wacom->dev); + if (error) + goto fail3; /* Ask the tablet to report tablet data. Repeat until it succeeds */ do { @@ -265,11 +268,12 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i usb_set_intfdata(intf, wacom); return 0; -fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); -fail1: input_free_device(input_dev); + fail3: usb_free_urb(wacom->irq); + fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); + fail1: input_free_device(input_dev); kfree(wacom); kfree(wacom_wac); - return -ENOMEM; + return error; } static void wacom_disconnect(struct usb_interface *intf) diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index e4bc76e..ca03d1f 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -312,6 +312,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id struct input_dev *input_dev; struct usb_endpoint_descriptor *ep_irq_in; int i; + int error = -ENOMEM; for (i = 0; xpad_device[i].idVendor; i++) { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && @@ -373,15 +374,18 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->irq_in->transfer_dma = xpad->idata_dma; xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - input_register_device(xpad->dev); + error = input_register_device(xpad->dev); + if (error) + goto fail3; usb_set_intfdata(intf, xpad); return 0; -fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); -fail1: input_free_device(input_dev); + fail3: usb_free_urb(xpad->irq_in); + fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); + fail1: input_free_device(input_dev); kfree(xpad); - return -ENOMEM; + return error; } diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index caff8e6..688abcd 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c @@ -955,7 +955,9 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) } } - input_register_device(yld->idev); + ret = input_register_device(yld->idev); + if (ret) + return usb_cleanup(yld, ret); usb_set_intfdata(intf, yld); -- cgit v0.10.2 From 3abccf36081ac827cf5d14db6837117f088937eb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:33:51 -0400 Subject: Input: add input_{get|set}_drvdata() helpers Add helpers to set up and access driver-specific data in input device structure. Once conversion to struct driver is complete we will drop input_dev->private and will use dev_get_drvdata() and dev_set_drvdata(). Signed-off-by: Dmitry Torokhov diff --git a/include/linux/input.h b/include/linux/input.h index 9bd984b..d0bea97 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1097,6 +1097,16 @@ static inline void input_put_device(struct input_dev *dev) class_device_put(&dev->cdev); } +static inline void *input_get_drvdata(struct input_dev *dev) +{ + return dev->private; +} + +static inline void input_set_drvdata(struct input_dev *dev, void *data) +{ + dev->private = data; +} + int input_register_device(struct input_dev *); void input_unregister_device(struct input_dev *); -- cgit v0.10.2 From 0ca1804f2e4d78e6a037da23f96aa56f762e78fb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:34:02 -0400 Subject: Input: drivers/input/mice - don't access dev->private directly Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index 8e9421a..6c67aa4 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c @@ -259,8 +259,6 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) if (!ptr->dev) goto bail0; - ptr->dev->private = ptr; - if (serio_open(serio, driver)) goto bail1; diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index e6c9e7b..5444905 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1083,7 +1083,6 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse { struct input_dev *input_dev = psmouse->dev; - input_dev->private = psmouse; input_dev->cdev.dev = &psmouse->ps2dev.serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index 0ac448a..1cb40e7 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -271,7 +271,6 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); - input_dev->private = sermouse; if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit); if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit); diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index c3d64fc..d65e8a9 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -509,7 +509,6 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) input_dev->phys = mouse->phys; input_dev->id.bustype = BUS_RS232; input_dev->cdev.dev = &serio->dev; - input_dev->private = mouse; set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ set_bit (EV_REL, input_dev->evbit); -- cgit v0.10.2 From 40b9b0b82e664bfdf26fd33014d52e23ff80b9f4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:34:08 -0400 Subject: Input: drivers/input/touchscreen - don't access dev->private directly Use input_get_drvdata() and input_set_drvdata() instead. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index e294558..4965c05 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -301,7 +301,6 @@ static int __init corgits_probe(struct platform_device *pdev) input_dev->id.product = 0x0002; input_dev->id.version = 0x0100; input_dev->cdev.dev = &pdev->dev; - input_dev->private = corgi_ts; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 9d61cd1..7e2f326 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c @@ -312,7 +312,6 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv) init_completion(&elo->cmd_done); snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys); - input_dev->private = elo; input_dev->name = "Elo Serial TouchScreen"; input_dev->phys = elo->phys; input_dev->id.bustype = BUS_RS232; diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 9157eb1..399eb4a 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c @@ -130,7 +130,6 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) gunze->dev = input_dev; snprintf(gunze->phys, sizeof(serio->phys), "%s/input0", serio->phys); - input_dev->private = gunze; input_dev->name = "Gunze AHL-51S TouchScreen"; input_dev->phys = gunze->phys; input_dev->id.bustype = BUS_RS232; diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index c4116d4..2b01ace 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c @@ -147,7 +147,7 @@ enum flite_pwr { unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr) { unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness; - struct h3600_dev *ts = dev->private; + struct h3600_dev *ts = input_get_drvdata(dev); /* Must be in this order */ ts->serio->write(ts->serio, 1); @@ -260,7 +260,7 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { #if 0 - struct h3600_dev *ts = dev->private; + struct h3600_dev *ts = input_get_drvdata(dev); switch (type) { case EV_LED: { @@ -368,7 +368,8 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */ input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = ts; + + input_set_drvdata(input_dev, ts); input_dev->event = h3600ts_event; diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index c3c2d73..53b0683 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c @@ -144,7 +144,6 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) mtouch->dev = input_dev; snprintf(mtouch->phys, sizeof(mtouch->phys), "%s/input0", serio->phys); - input_dev->private = mtouch; input_dev->name = "MicroTouch Serial TouchScreen"; input_dev->phys = mtouch->phys; input_dev->id.bustype = BUS_RS232; diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index bd27679..65a4e0a 100644 --- a/drivers/input/touchscreen/penmount.c +++ b/drivers/input/touchscreen/penmount.c @@ -105,7 +105,6 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv) pm->dev = input_dev; snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys); - input_dev->private = pm; input_dev->name = "Penmount Serial TouchScreen"; input_dev->phys = pm->phys; input_dev->id.bustype = BUS_RS232; diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c index 35ba46c..63d2d44 100644 --- a/drivers/input/touchscreen/touchright.c +++ b/drivers/input/touchscreen/touchright.c @@ -118,7 +118,6 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv) tr->dev = input_dev; snprintf(tr->phys, sizeof(tr->phys), "%s/input0", serio->phys); - input_dev->private = tr; input_dev->name = "Touchright Serial TouchScreen"; input_dev->phys = tr->phys; input_dev->id.bustype = BUS_RS232; diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c index 4dc073d..3da9c8c 100644 --- a/drivers/input/touchscreen/touchwin.c +++ b/drivers/input/touchscreen/touchwin.c @@ -125,7 +125,6 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv) tw->dev = input_dev; snprintf(tw->phys, sizeof(tw->phys), "%s/input0", serio->phys); - input_dev->private = tw; input_dev->name = "Touchwindow Serial TouchScreen"; input_dev->phys = tw->phys; input_dev->id.bustype = BUS_RS232; diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index c7db4032..fe4bdf6 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -369,7 +369,7 @@ static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid) static int ucb1400_ts_open(struct input_dev *idev) { - struct ucb1400 *ucb = idev->private; + struct ucb1400 *ucb = input_get_drvdata(idev); int ret = 0; BUG_ON(ucb->ts_task); @@ -385,7 +385,7 @@ static int ucb1400_ts_open(struct input_dev *idev) static void ucb1400_ts_close(struct input_dev *idev) { - struct ucb1400 *ucb = idev->private; + struct ucb1400 *ucb = input_get_drvdata(idev); if (ucb->ts_task) kthread_stop(ucb->ts_task); @@ -507,7 +507,8 @@ static int ucb1400_ts_probe(struct device *dev) } printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq); - idev->private = ucb; + input_set_drvdata(idev, ucb); + idev->cdev.dev = dev; idev->name = "UCB1400 touchscreen interface"; idev->id.vendor = ucb1400_reg_read(ucb, AC97_VENDOR_ID1); -- cgit v0.10.2 From 8715c1cfadf8cce24e79d254f95bd4a84c7741f0 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:34:14 -0400 Subject: Input: drivers/input/joystick - don't access dev->private directly Use input_get_drvdata() and input_set_drvdata() instead. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index b11a4bb..4ac1a8f 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c @@ -241,7 +241,7 @@ static void a3d_adc_close(struct gameport *gameport) static int a3d_open(struct input_dev *dev) { - struct a3d *a3d = dev->private; + struct a3d *a3d = input_get_drvdata(dev); gameport_start_polling(a3d->gameport); return 0; @@ -253,7 +253,7 @@ static int a3d_open(struct input_dev *dev) static void a3d_close(struct input_dev *dev) { - struct a3d *a3d = dev->private; + struct a3d *a3d = input_get_drvdata(dev); gameport_stop_polling(a3d->gameport); } @@ -315,10 +315,11 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.product = a3d->mode; input_dev->id.version = 0x0100; input_dev->cdev.dev = &gameport->dev; - input_dev->private = a3d; input_dev->open = a3d_open; input_dev->close = a3d_close; + input_set_drvdata(input_dev, a3d); + if (a3d->mode == A3D_MODE_PXL) { int axes[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER }; diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index 6279ced..e835352 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c @@ -290,7 +290,7 @@ static void adi_poll(struct gameport *gameport) static int adi_open(struct input_dev *dev) { - struct adi_port *port = dev->private; + struct adi_port *port = input_get_drvdata(dev); gameport_start_polling(port->gameport); return 0; @@ -302,7 +302,7 @@ static int adi_open(struct input_dev *dev) static void adi_close(struct input_dev *dev) { - struct adi_port *port = dev->private; + struct adi_port *port = input_get_drvdata(dev); gameport_stop_polling(port->gameport); } @@ -425,7 +425,8 @@ static int adi_init_input(struct adi *adi, struct adi_port *port, int half) input_dev->id.product = adi->id; input_dev->id.version = 0x0100; input_dev->cdev.dev = &port->gameport->dev; - input_dev->private = port; + + input_set_drvdata(input_dev, port); input_dev->open = adi_open; input_dev->close = adi_close; diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 51f1e4b..7244e29 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -343,7 +343,7 @@ static void analog_poll(struct gameport *gameport) static int analog_open(struct input_dev *dev) { - struct analog_port *port = dev->private; + struct analog_port *port = input_get_drvdata(dev); gameport_start_polling(port->gameport); return 0; @@ -355,7 +355,7 @@ static int analog_open(struct input_dev *dev) static void analog_close(struct input_dev *dev) { - struct analog_port *port = dev->private; + struct analog_port *port = input_get_drvdata(dev); gameport_stop_polling(port->gameport); } @@ -450,9 +450,11 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i input_dev->id.product = analog->mask >> 4; input_dev->id.version = 0x0100; + input_set_drvdata(input_dev, port); + input_dev->open = analog_open; input_dev->close = analog_close; - input_dev->private = port; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = j = 0; i < 4; i++) diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 034ec39..2075363 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c @@ -142,7 +142,7 @@ static void cobra_poll(struct gameport *gameport) static int cobra_open(struct input_dev *dev) { - struct cobra *cobra = dev->private; + struct cobra *cobra = input_get_drvdata(dev); gameport_start_polling(cobra->gameport); return 0; @@ -150,7 +150,7 @@ static int cobra_open(struct input_dev *dev) static void cobra_close(struct input_dev *dev) { - struct cobra *cobra = dev->private; + struct cobra *cobra = input_get_drvdata(dev); gameport_stop_polling(cobra->gameport); } @@ -212,7 +212,8 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.product = 0x0008; input_dev->id.version = 0x0100; input_dev->cdev.dev = &gameport->dev; - input_dev->private = cobra; + + input_set_drvdata(input_dev, cobra); input_dev->open = cobra_open; input_dev->close = cobra_close; diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index b41bd2e..c27593b 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -518,7 +518,7 @@ static void db9_timer(unsigned long private) static int db9_open(struct input_dev *dev) { - struct db9 *db9 = dev->private; + struct db9 *db9 = input_get_drvdata(dev); struct parport *port = db9->pd->port; int err; @@ -542,7 +542,7 @@ static int db9_open(struct input_dev *dev) static void db9_close(struct input_dev *dev) { - struct db9 *db9 = dev->private; + struct db9 *db9 = input_get_drvdata(dev); struct parport *port = db9->pd->port; mutex_lock(&db9->mutex); @@ -625,7 +625,8 @@ static struct db9 __init *db9_probe(int parport, int mode) input_dev->id.vendor = 0x0002; input_dev->id.product = mode; input_dev->id.version = 0x0100; - input_dev->private = db9; + + input_set_drvdata(input_dev, db9); input_dev->open = db9_open; input_dev->close = db9_close; diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 711e4b3..c71b58f 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -591,7 +591,7 @@ static void gc_timer(unsigned long private) static int gc_open(struct input_dev *dev) { - struct gc *gc = dev->private; + struct gc *gc = input_get_drvdata(dev); int err; err = mutex_lock_interruptible(&gc->mutex); @@ -610,7 +610,7 @@ static int gc_open(struct input_dev *dev) static void gc_close(struct input_dev *dev) { - struct gc *gc = dev->private; + struct gc *gc = input_get_drvdata(dev); mutex_lock(&gc->mutex); if (!--gc->used) { @@ -646,7 +646,8 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) input_dev->id.vendor = 0x0001; input_dev->id.product = pad_type; input_dev->id.version = 0x0100; - input_dev->private = gc; + + input_set_drvdata(input_dev, gc); input_dev->open = gc_open; input_dev->close = gc_close; diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index bacbab5..ac7db7a 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -220,7 +220,7 @@ static void gf2k_poll(struct gameport *gameport) static int gf2k_open(struct input_dev *dev) { - struct gf2k *gf2k = dev->private; + struct gf2k *gf2k = input_get_drvdata(dev); gameport_start_polling(gf2k->gameport); return 0; @@ -228,7 +228,7 @@ static int gf2k_open(struct input_dev *dev) static void gf2k_close(struct input_dev *dev) { - struct gf2k *gf2k = dev->private; + struct gf2k *gf2k = input_get_drvdata(dev); gameport_stop_polling(gf2k->gameport); } @@ -309,10 +309,12 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.product = gf2k->id; input_dev->id.version = 0x0100; input_dev->cdev.dev = &gameport->dev; - input_dev->private = gf2k; + + input_set_drvdata(input_dev, gf2k); input_dev->open = gf2k_open; input_dev->close = gf2k_close; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; i < gf2k_axes[gf2k->id]; i++) diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index 17a90c4..41da7f1 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -285,7 +285,7 @@ static void grip_poll(struct gameport *gameport) static int grip_open(struct input_dev *dev) { - struct grip *grip = dev->private; + struct grip *grip = input_get_drvdata(dev); gameport_start_polling(grip->gameport); return 0; @@ -293,7 +293,7 @@ static int grip_open(struct input_dev *dev) static void grip_close(struct input_dev *dev) { - struct grip *grip = dev->private; + struct grip *grip = input_get_drvdata(dev); gameport_stop_polling(grip->gameport); } @@ -364,7 +364,8 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.product = grip->mode[i]; input_dev->id.version = 0x0100; input_dev->cdev.dev = &gameport->dev; - input_dev->private = grip; + + input_set_drvdata(input_dev, grip); input_dev->open = grip_open; input_dev->close = grip_close; diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 8120a9c..1771d5d 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c @@ -562,7 +562,7 @@ static void grip_poll(struct gameport *gameport) static int grip_open(struct input_dev *dev) { - struct grip_mp *grip = dev->private; + struct grip_mp *grip = input_get_drvdata(dev); gameport_start_polling(grip->gameport); return 0; @@ -574,9 +574,9 @@ static int grip_open(struct input_dev *dev) static void grip_close(struct input_dev *dev) { - struct grip_mp *grip = dev->private; + struct grip_mp *grip = input_get_drvdata(dev); - gameport_start_polling(grip->gameport); + gameport_stop_polling(grip->gameport); } /* @@ -600,7 +600,8 @@ static int register_slot(int slot, struct grip_mp *grip) input_dev->id.product = 0x0100 + port->mode; input_dev->id.version = 0x0100; input_dev->cdev.dev = &grip->gameport->dev; - input_dev->private = grip; + + input_set_drvdata(input_dev, grip); input_dev->open = grip_open; input_dev->close = grip_close; diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index dbc5d92..3e022dc 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c @@ -156,7 +156,7 @@ static void guillemot_poll(struct gameport *gameport) static int guillemot_open(struct input_dev *dev) { - struct guillemot *guillemot = dev->private; + struct guillemot *guillemot = input_get_drvdata(dev); gameport_start_polling(guillemot->gameport); return 0; @@ -168,7 +168,7 @@ static int guillemot_open(struct input_dev *dev) static void guillemot_close(struct input_dev *dev) { - struct guillemot *guillemot = dev->private; + struct guillemot *guillemot = input_get_drvdata(dev); gameport_stop_polling(guillemot->gameport); } @@ -232,7 +232,8 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * input_dev->id.product = guillemot_type[i].id; input_dev->id.version = (int)data[14] << 8 | data[15]; input_dev->cdev.dev = &gameport->dev; - input_dev->private = guillemot; + + input_set_drvdata(input_dev, guillemot); input_dev->open = guillemot_open; input_dev->close = guillemot_close; diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index fec8b3d..f0ff783 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c @@ -185,7 +185,7 @@ static void interact_poll(struct gameport *gameport) static int interact_open(struct input_dev *dev) { - struct interact *interact = dev->private; + struct interact *interact = input_get_drvdata(dev); gameport_start_polling(interact->gameport); return 0; @@ -197,7 +197,7 @@ static int interact_open(struct input_dev *dev) static void interact_close(struct input_dev *dev) { - struct interact *interact = dev->private; + struct interact *interact = input_get_drvdata(dev); gameport_stop_polling(interact->gameport); } @@ -262,7 +262,8 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT; input_dev->id.product = interact_type[i].id; input_dev->id.version = 0x0100; - input_dev->private = interact; + + input_set_drvdata(input_dev, interact); input_dev->open = interact_open; input_dev->close = interact_close; diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index 4112789..31f6866 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c @@ -169,7 +169,6 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = magellan; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index e58b22c..f800c39 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -509,7 +509,7 @@ static void sw_poll(struct gameport *gameport) static int sw_open(struct input_dev *dev) { - struct sw *sw = dev->private; + struct sw *sw = input_get_drvdata(dev); gameport_start_polling(sw->gameport); return 0; @@ -517,7 +517,7 @@ static int sw_open(struct input_dev *dev) static void sw_close(struct input_dev *dev) { - struct sw *sw = dev->private; + struct sw *sw = input_get_drvdata(dev); gameport_stop_polling(sw->gameport); } @@ -752,7 +752,8 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.product = sw->type; input_dev->id.version = 0x0100; input_dev->cdev.dev = &gameport->dev; - input_dev->private = sw; + + input_set_drvdata(input_dev, sw); input_dev->open = sw_open; input_dev->close = sw_close; diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 08bf113..dd611de 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -227,7 +227,6 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = id; input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = spaceball; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index c9c7921..f5e4966 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c @@ -184,7 +184,6 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = spaceorb; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index ecb0916..b6a6f21 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c @@ -155,7 +155,6 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = stinger; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index bb23ed2..53260d1 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c @@ -265,7 +265,7 @@ static void tmdc_poll(struct gameport *gameport) static int tmdc_open(struct input_dev *dev) { - struct tmdc *tmdc = dev->private; + struct tmdc *tmdc = input_get_drvdata(dev); gameport_start_polling(tmdc->gameport); return 0; @@ -273,7 +273,7 @@ static int tmdc_open(struct input_dev *dev) static void tmdc_close(struct input_dev *dev) { - struct tmdc *tmdc = dev->private; + struct tmdc *tmdc = input_get_drvdata(dev); gameport_stop_polling(tmdc->gameport); } @@ -327,7 +327,8 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data) input_dev->id.product = model->id; input_dev->id.version = 0x0100; input_dev->cdev.dev = &tmdc->gameport->dev; - input_dev->private = tmdc; + + input_set_drvdata(input_dev, tmdc); input_dev->open = tmdc_open; input_dev->close = tmdc_close; diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index 037d348..0f2c608 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -122,7 +122,7 @@ static void tgfx_timer(unsigned long private) static int tgfx_open(struct input_dev *dev) { - struct tgfx *tgfx = dev->private; + struct tgfx *tgfx = input_get_drvdata(dev); int err; err = mutex_lock_interruptible(&tgfx->sem); @@ -141,7 +141,7 @@ static int tgfx_open(struct input_dev *dev) static void tgfx_close(struct input_dev *dev) { - struct tgfx *tgfx = dev->private; + struct tgfx *tgfx = input_get_drvdata(dev); mutex_lock(&tgfx->sem); if (!--tgfx->used) { @@ -224,7 +224,8 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) input_dev->id.product = n_buttons[i]; input_dev->id.version = 0x0100; - input_dev->private = tgfx; + input_set_drvdata(input_dev, tgfx); + input_dev->open = tgfx_open; input_dev->close = tgfx_close; diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 9cf17d6..458a129 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c @@ -206,7 +206,6 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = twidjoy; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index 29d339a..e0927a5 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c @@ -161,7 +161,6 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = warrior; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); -- cgit v0.10.2 From b356872fa48a3f6b6f187444b0ea55e6e21c3575 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:34:20 -0400 Subject: Input: drivers/input/keyboard - don't access dev->private directly Use input_get_drvdata() and input_set_drvdata() instead. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c index 65fcb6a..e584413 100644 --- a/drivers/input/keyboard/aaed2000_kbd.c +++ b/drivers/input/keyboard/aaed2000_kbd.c @@ -97,7 +97,7 @@ static void aaedkbd_work(void *data) static int aaedkbd_open(struct input_dev *indev) { - struct aaedkbd *aaedkbd = indev->private; + struct aaedkbd *aaedkbd = input_get_drvdata(indev); schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); @@ -106,7 +106,7 @@ static int aaedkbd_open(struct input_dev *indev) static void aaedkbd_close(struct input_dev *indev) { - struct aaedkbd *aaedkbd = indev->private; + struct aaedkbd *aaedkbd = input_get_drvdata(indev); cancel_delayed_work(&aaedkbd->workq); flush_scheduled_work(); @@ -142,7 +142,7 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->cdev.dev = &pdev->dev; - input_dev->private = aaedkbd; + input_set_drvdata(input_dev, aaedkbd); input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = aaedkbd->keycode; diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 6638770..0475473 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -586,7 +586,7 @@ static void atkbd_event_work(struct work_struct *work) static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct atkbd *atkbd = dev->private; + struct atkbd *atkbd = input_get_drvdata(dev); if (!atkbd->write) return -1; @@ -883,9 +883,10 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) input_dev->id.product = atkbd->translated ? 1 : atkbd->set; input_dev->id.version = atkbd->id; input_dev->event = atkbd_event; - input_dev->private = atkbd; input_dev->cdev.dev = &atkbd->ps2dev.serio->dev; + input_set_drvdata(input_dev, atkbd); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC); if (atkbd->write) { diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 1016c94..25dd879 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -324,7 +324,6 @@ static int __init corgikbd_probe(struct platform_device *pdev) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->cdev.dev = &pdev->dev; - input_dev->private = corgikbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); input_dev->keycode = corgikbd->keycode; diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index fa03a00..b943993 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -66,7 +66,6 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) input->name = pdev->name; input->phys = "gpio-keys/input0"; input->cdev.dev = &pdev->dev; - input->private = pdata; input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 18f4d41..087d4df2 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -269,8 +269,6 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) if (!kbd->dev) goto bail0; - kbd->dev->private = kbd; - if (serio_open(serio, drv)) goto bail1; diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index 230f5db..73b85cb 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c @@ -215,7 +215,6 @@ hil_keyb_init(void) hil_dev.dev = input_allocate_device(); if (!hil_dev.dev) return -ENOMEM; - hil_dev.dev->private = &hil_dev; #if defined(CONFIG_HP300) if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 3d4d0a0..257b9d4 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -515,7 +515,7 @@ static int lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct lkkbd *lk = dev->private; + struct lkkbd *lk = input_get_drvdata (dev); unsigned char leds_on = 0; unsigned char leds_off = 0; @@ -668,7 +668,8 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; input_dev->event = lkkbd_event; - input_dev->private = lk; + + input_set_drvdata (input_dev, lk); set_bit (EV_KEY, input_dev->evbit); set_bit (EV_LED, input_dev->evbit); diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 2ade518..764f5ee 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c @@ -231,7 +231,6 @@ static int locomokbd_probe(struct locomo_dev *dev) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->private = locomokbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = locomokbd->keycode; diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index aa29b50..179f3a4 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c @@ -105,7 +105,6 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = nkbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = nkbd->keycode; diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 5680a6d..1790f0c 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -371,7 +371,6 @@ static int __init omap_kp_probe(struct platform_device *pdev) input_dev->name = "omap-keypad"; input_dev->phys = "omap-keypad/input0"; input_dev->cdev.dev = &pdev->dev; - input_dev->private = omap_kp; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 8a2166c..bc96074 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -372,7 +372,6 @@ static int __init spitzkbd_probe(struct platform_device *dev) spitzkbd->input = input_dev; - input_dev->private = spitzkbd; input_dev->name = "Spitz Keyboard"; input_dev->phys = spitzkbd->phys; input_dev->cdev.dev = &dev->dev; diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c index f7b5c5b..c109620 100644 --- a/drivers/input/keyboard/stowaway.c +++ b/drivers/input/keyboard/stowaway.c @@ -109,7 +109,6 @@ static int skbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = skbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = skbd->keycode; diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index cc02383..ca74b2b 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -146,7 +146,7 @@ out: static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct sunkbd *sunkbd = dev->private; + struct sunkbd *sunkbd = input_get_drvdata(dev); switch (type) { @@ -272,7 +272,9 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = sunkbd->type; input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = sunkbd; + + input_set_drvdata(input_dev, sunkbd); + input_dev->event = sunkbd_event; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP); diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index a820934..11d9708 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c @@ -109,7 +109,6 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->cdev.dev = &serio->dev; - input_dev->private = xtkbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = xtkbd->keycode; -- cgit v0.10.2 From 373f9713dccc8fc8e076157001a60133455c0550 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:34:33 -0400 Subject: Input: drivers/input/misc - don't access dev->private directly Use input_get_drvdata() and input_set_drvdata() instead. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index 105c6fc..da6650c 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c @@ -51,7 +51,7 @@ static void ixp4xx_spkr_control(unsigned int pin, unsigned int count) static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - unsigned int pin = (unsigned int) dev->private; + unsigned int pin = (unsigned int) input_get_drvdata(input_dev); unsigned int count = 0; if (type != EV_SND) @@ -99,7 +99,8 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) if (!input_dev) return -ENOMEM; - input_dev->private = (void *) dev->id; + input_set_drvdata(input_dev, (void *) dev->id); + input_dev->name = "ixp4xx beeper", input_dev->phys = "ixp4xx/gpio"; input_dev->id.bustype = BUS_HOST; @@ -136,7 +137,7 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) static int __devexit ixp4xx_spkr_remove(struct platform_device *dev) { struct input_dev *input_dev = platform_get_drvdata(dev); - unsigned int pin = (unsigned int) input_dev->private; + unsigned int pin = (unsigned int) input_get_drvdata(input_dev); input_unregister_device(input_dev); platform_set_drvdata(dev, NULL); @@ -153,7 +154,7 @@ static int __devexit ixp4xx_spkr_remove(struct platform_device *dev) static void ixp4xx_spkr_shutdown(struct platform_device *dev) { struct input_dev *input_dev = platform_get_drvdata(dev); - unsigned int pin = (unsigned int) input_dev->private; + unsigned int pin = (unsigned int) input_get_drvdata(input_dev); /* turn off the speaker */ disable_irq(IRQ_IXP4XX_TIMER2); diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 4255623..031467e 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -41,9 +41,7 @@ static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct uinput_device *udev; - - udev = dev->private; + struct uinput_device *udev = input_get_drvdata(dev); udev->buff[udev->head].type = type; udev->buff[udev->head].code = code; @@ -136,7 +134,7 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff request.u.upload.effect = effect; request.u.upload.old = old; - retval = uinput_request_reserve_slot(dev->private, &request); + retval = uinput_request_reserve_slot(input_get_drvdata(dev), &request); if (!retval) retval = uinput_request_submit(dev, &request); @@ -156,7 +154,7 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) request.code = UI_FF_ERASE; request.u.effect_id = effect_id; - retval = uinput_request_reserve_slot(dev->private, &request); + retval = uinput_request_reserve_slot(input_get_drvdata(dev), &request); if (!retval) retval = uinput_request_submit(dev, &request); @@ -274,7 +272,7 @@ static int uinput_allocate_device(struct uinput_device *udev) return -ENOMEM; udev->dev->event = uinput_dev_event; - udev->dev->private = udev; + input_set_drvdata(udev->dev, udev); return 0; } -- cgit v0.10.2 From 7791bdae71243050132ede7ea1558c828b69458f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:34:39 -0400 Subject: Input: drivers/usb/input - don't access dev->private directly Use input_get_drvdata() and input_set_drvdata() instead. Signed-off-by: Dmitry Torokhov diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index 270bb05..75972b7 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c @@ -111,7 +111,7 @@ resubmit: static int usb_acecad_open(struct input_dev *dev) { - struct usb_acecad *acecad = dev->private; + struct usb_acecad *acecad = input_get_drvdata(dev); acecad->irq->dev = acecad->usbdev; if (usb_submit_urb(acecad->irq, GFP_KERNEL)) @@ -122,7 +122,7 @@ static int usb_acecad_open(struct input_dev *dev) static void usb_acecad_close(struct input_dev *dev) { - struct usb_acecad *acecad = dev->private; + struct usb_acecad *acecad = input_get_drvdata(dev); usb_kill_urb(acecad->irq); } @@ -186,7 +186,8 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ input_dev->phys = acecad->phys; usb_to_input_id(dev, &input_dev->id); input_dev->cdev.dev = &intf->dev; - input_dev->private = acecad; + + input_set_drvdata(input_dev, acecad); input_dev->open = usb_acecad_open; input_dev->close = usb_acecad_close; diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 8c1ab1c..8b33a8e 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -798,7 +798,7 @@ MODULE_DEVICE_TABLE(usb, aiptek_ids); */ static int aiptek_open(struct input_dev *inputdev) { - struct aiptek *aiptek = inputdev->private; + struct aiptek *aiptek = input_get_drvdata(inputdev); aiptek->urb->dev = aiptek->usbdev; if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0) @@ -812,7 +812,7 @@ static int aiptek_open(struct input_dev *inputdev) */ static void aiptek_close(struct input_dev *inputdev) { - struct aiptek *aiptek = inputdev->private; + struct aiptek *aiptek = input_get_drvdata(inputdev); usb_kill_urb(aiptek->urb); } @@ -2045,7 +2045,9 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) inputdev->phys = aiptek->features.usbPath; usb_to_input_id(usbdev, &inputdev->id); inputdev->cdev.dev = &intf->dev; - inputdev->private = aiptek; + + input_set_drvdata(inputdev, aiptek); + inputdev->open = aiptek_open; inputdev->close = aiptek_close; diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index 3622132..ef6166a 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c @@ -466,7 +466,7 @@ exit: static int atp_open(struct input_dev *input) { - struct atp *dev = input->private; + struct atp *dev = input_get_drvdata(input); if (usb_submit_urb(dev->urb, GFP_ATOMIC)) return -EIO; @@ -477,7 +477,7 @@ static int atp_open(struct input_dev *input) static void atp_close(struct input_dev *input) { - struct atp *dev = input->private; + struct atp *dev = input_get_drvdata(input); usb_kill_urb(dev->urb); dev->open = 0; @@ -586,7 +586,8 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id usb_to_input_id(dev->udev, &input_dev->id); input_dev->cdev.dev = &iface->dev; - input_dev->private = dev; + input_set_drvdata(input_dev, dev); + input_dev->open = atp_open; input_dev->close = atp_close; diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index a1ae9ee..876b2725 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c @@ -318,7 +318,7 @@ static void ati_remote_dump(unsigned char *data, unsigned int len) */ static int ati_remote_open(struct input_dev *inputdev) { - struct ati_remote *ati_remote = inputdev->private; + struct ati_remote *ati_remote = input_get_drvdata(inputdev); /* On first open, submit the read urb which was set up previously. */ ati_remote->irq_urb->dev = ati_remote->udev; @@ -336,7 +336,7 @@ static int ati_remote_open(struct input_dev *inputdev) */ static void ati_remote_close(struct input_dev *inputdev) { - struct ati_remote *ati_remote = inputdev->private; + struct ati_remote *ati_remote = input_get_drvdata(inputdev); usb_kill_urb(ati_remote->irq_urb); } @@ -653,7 +653,8 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) if (ati_remote_tbl[i].type == EV_KEY) set_bit(ati_remote_tbl[i].code, idev->keybit); - idev->private = ati_remote; + input_set_drvdata(idev, ati_remote); + idev->open = ati_remote_open; idev->close = ati_remote_close; diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c index 5656278..3c38ac6 100644 --- a/drivers/usb/input/ati_remote2.c +++ b/drivers/usb/input/ati_remote2.c @@ -131,7 +131,7 @@ static struct usb_driver ati_remote2_driver = { static int ati_remote2_open(struct input_dev *idev) { - struct ati_remote2 *ar2 = idev->private; + struct ati_remote2 *ar2 = input_get_drvdata(idev); int r; r = usb_submit_urb(ar2->urb[0], GFP_KERNEL); @@ -153,7 +153,7 @@ static int ati_remote2_open(struct input_dev *idev) static void ati_remote2_close(struct input_dev *idev) { - struct ati_remote2 *ar2 = idev->private; + struct ati_remote2 *ar2 = input_get_drvdata(idev); usb_kill_urb(ar2->urb[0]); usb_kill_urb(ar2->urb[1]); @@ -344,7 +344,7 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) return -ENOMEM; ar2->idev = idev; - idev->private = ar2; + input_set_drvdata(idev, ar2); idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); diff --git a/drivers/usb/input/gtco.c b/drivers/usb/input/gtco.c index aa9c676..75cce2a 100644 --- a/drivers/usb/input/gtco.c +++ b/drivers/usb/input/gtco.c @@ -540,8 +540,7 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report, */ static int gtco_input_open(struct input_dev *inputdev) { - struct gtco *device; - device = inputdev->private; + struct gtco *device = input_get_drvdata(inputdev); device->urbinfo->dev = device->usbdev; if (usb_submit_urb(device->urbinfo, GFP_KERNEL)) @@ -555,7 +554,7 @@ static int gtco_input_open(struct input_dev *inputdev) */ static void gtco_input_close(struct input_dev *inputdev) { - struct gtco *device = inputdev->private; + struct gtco *device = input_get_drvdata(inputdev); usb_kill_urb(device->urbinfo); } @@ -569,9 +568,9 @@ static void gtco_input_close(struct input_dev *inputdev) * placed in the struct gtco structure * */ -static void gtco_setup_caps(struct input_dev *inputdev) +static void gtco_setup_caps(struct input_dev *inputdev) { - struct gtco *device = inputdev->private; + struct gtco *device = input_get_drvdata(inputdev); /* Which events */ inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); @@ -945,7 +944,8 @@ static int gtco_probe(struct usb_interface *usbinterface, /* Set input device information */ input_dev->name = "GTCO_CalComp"; input_dev->phys = gtco->usbpath; - input_dev->private = gtco; + + input_set_drvdata(input_dev, gtco); /* Now set up all the input device capabilities */ gtco_setup_caps(input_dev); diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index 64da987..7ec999a 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c @@ -100,7 +100,7 @@ MODULE_DEVICE_TABLE(usb, kbtab_ids); static int kbtab_open(struct input_dev *dev) { - struct kbtab *kbtab = dev->private; + struct kbtab *kbtab = input_get_drvdata(dev); kbtab->irq->dev = kbtab->usbdev; if (usb_submit_urb(kbtab->irq, GFP_KERNEL)) @@ -111,7 +111,7 @@ static int kbtab_open(struct input_dev *dev) static void kbtab_close(struct input_dev *dev) { - struct kbtab *kbtab = dev->private; + struct kbtab *kbtab = input_get_drvdata(dev); usb_kill_urb(kbtab->irq); } @@ -147,7 +147,8 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i input_dev->phys = kbtab->phys; usb_to_input_id(dev, &input_dev->id); input_dev->cdev.dev = &intf->dev; - input_dev->private = kbtab; + + input_set_drvdata(input_dev, kbtab); input_dev->open = kbtab_open; input_dev->close = kbtab_close; diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index d32a768..daf8f21 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c @@ -394,7 +394,7 @@ resubmit: static int keyspan_open(struct input_dev *dev) { - struct usb_keyspan *remote = dev->private; + struct usb_keyspan *remote = input_get_drvdata(dev); remote->irq_urb->dev = remote->udev; if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) @@ -405,7 +405,7 @@ static int keyspan_open(struct input_dev *dev) static void keyspan_close(struct input_dev *dev) { - struct usb_keyspan *remote = dev->private; + struct usb_keyspan *remote = input_get_drvdata(dev); usb_kill_urb(remote->irq_urb); } @@ -502,7 +502,8 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic if (keyspan_key_table[i] != KEY_RESERVED) set_bit(keyspan_key_table[i], input_dev->keybit); - input_dev->private = remote; + input_set_drvdata(input_dev, remote); + input_dev->open = keyspan_open; input_dev->close = keyspan_close; diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index ce27449..f951a44 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c @@ -252,7 +252,7 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne static int powermate_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int _value) { unsigned int command = (unsigned int)_value; - struct powermate_device *pm = dev->private; + struct powermate_device *pm = input_get_drvdata(dev); if (type == EV_MSC && code == MSC_PULSELED){ /* @@ -360,7 +360,8 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i input_dev->phys = pm->phys; usb_to_input_id(udev, &input_dev->id); input_dev->cdev.dev = &intf->dev; - input_dev->private = pm; + + input_set_drvdata(input_dev, pm); input_dev->event = powermate_input_event; diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c index 86e37a2..1696927 100644 --- a/drivers/usb/input/usbtouchscreen.c +++ b/drivers/usb/input/usbtouchscreen.c @@ -647,7 +647,7 @@ exit: static int usbtouch_open(struct input_dev *input) { - struct usbtouch_usb *usbtouch = input->private; + struct usbtouch_usb *usbtouch = input_get_drvdata(input); usbtouch->irq->dev = usbtouch->udev; @@ -659,7 +659,7 @@ static int usbtouch_open(struct input_dev *input) static void usbtouch_close(struct input_dev *input) { - struct usbtouch_usb *usbtouch = input->private; + struct usbtouch_usb *usbtouch = input_get_drvdata(input); usb_kill_urb(usbtouch->irq); } @@ -741,7 +741,9 @@ static int usbtouch_probe(struct usb_interface *intf, input_dev->phys = usbtouch->phys; usb_to_input_id(udev, &input_dev->id); input_dev->cdev.dev = &intf->dev; - input_dev->private = usbtouch; + + input_set_drvdata(input_dev, usbtouch); + input_dev->open = usbtouch_open; input_dev->close = usbtouch_close; diff --git a/drivers/usb/input/wacom_sys.c b/drivers/usb/input/wacom_sys.c index 48988e6..7793ffb 100644 --- a/drivers/usb/input/wacom_sys.c +++ b/drivers/usb/input/wacom_sys.c @@ -122,7 +122,7 @@ void wacom_input_sync(void *wcombo) static int wacom_open(struct input_dev *dev) { - struct wacom *wacom = dev->private; + struct wacom *wacom = input_get_drvdata(dev); wacom->irq->dev = wacom->usbdev; if (usb_submit_urb(wacom->irq, GFP_KERNEL)) @@ -133,7 +133,7 @@ static int wacom_open(struct input_dev *dev) static void wacom_close(struct input_dev *dev) { - struct wacom *wacom = dev->private; + struct wacom *wacom = input_get_drvdata(dev); usb_kill_urb(wacom->irq); } @@ -231,7 +231,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i usb_to_input_id(dev, &input_dev->id); input_dev->cdev.dev = &intf->dev; - input_dev->private = wacom; + + input_set_drvdata(input_dev, wacom); + input_dev->open = wacom_open; input_dev->close = wacom_close; diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index ca03d1f..b001796 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -267,7 +267,7 @@ exit: static int xpad_open (struct input_dev *dev) { - struct usb_xpad *xpad = dev->private; + struct usb_xpad *xpad = input_get_drvdata(dev); xpad->irq_in->dev = xpad->udev; if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) @@ -278,7 +278,7 @@ static int xpad_open (struct input_dev *dev) static void xpad_close (struct input_dev *dev) { - struct usb_xpad *xpad = dev->private; + struct usb_xpad *xpad = input_get_drvdata(dev); usb_kill_urb(xpad->irq_in); } @@ -346,7 +346,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id input_dev->phys = xpad->phys; usb_to_input_id(udev, &input_dev->id); input_dev->cdev.dev = &intf->dev; - input_dev->private = xpad; + + input_set_drvdata(input_dev, xpad); + input_dev->open = xpad_open; input_dev->close = xpad_close; diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index 688abcd..294224e 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c @@ -502,7 +502,7 @@ static int input_ev(struct input_dev *dev, unsigned int type, static int input_open(struct input_dev *dev) { - struct yealink_dev *yld = dev->private; + struct yealink_dev *yld = input_get_drvdata(dev); int i, ret; dbg("%s", __FUNCTION__); @@ -529,7 +529,7 @@ static int input_open(struct input_dev *dev) static void input_close(struct input_dev *dev) { - struct yealink_dev *yld = dev->private; + struct yealink_dev *yld = input_get_drvdata(dev); usb_kill_urb(yld->urb_ctl); usb_kill_urb(yld->urb_irq); @@ -939,7 +939,8 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_to_input_id(udev, &input_dev->id); input_dev->cdev.dev = &intf->dev; - input_dev->private = yld; + input_set_drvdata(input_dev, yld); + input_dev->open = input_open; input_dev->close = input_close; /* input_dev->event = input_ev; TODO */ -- cgit v0.10.2 From 88a447a030bfec9f1e8666daf27d9d73c8c92448 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:34:47 -0400 Subject: Input: prepare to switching to struct device In preparation to switching to struct device and class device going away provide an alias to allow drivers that create devices to use either input_dev->cdev.dev or input_dev->dev.parent to put them into sysfs tree. The former will go away once conversion to struct device is complete. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/input.c b/drivers/input/input.c index 86b2707..173c286 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1079,6 +1079,9 @@ int input_register_device(struct input_dev *dev) snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); + if (!dev->cdev.dev) + dev->cdev.dev = dev->dev.parent; + error = class_device_add(&dev->cdev); if (error) return error; diff --git a/include/linux/input.h b/include/linux/input.h index d0bea97..7b6d7c4 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -972,6 +972,9 @@ struct input_dev { unsigned int users; struct class_device cdev; + union { /* temporarily so while we switching to struct device */ + struct device *parent; + } dev; struct list_head h_list; struct list_head node; -- cgit v0.10.2 From 469ba4dff954389f58cebb3df645e24433dcd565 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:34:58 -0400 Subject: Input: keyboards - switch to using input_dev->dev.parent In preparation for struct class_device -> struct device input core conversion, switch to using input_dev->dev.parent when specifying device position in sysfs tree. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c index e584413..3a37505 100644 --- a/drivers/input/keyboard/aaed2000_kbd.c +++ b/drivers/input/keyboard/aaed2000_kbd.c @@ -141,7 +141,8 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &pdev->dev; + input_dev->dev.parent = &pdev->dev; + input_set_drvdata(input_dev, aaedkbd); input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 0475473..be1fe46 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -883,7 +883,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) input_dev->id.product = atkbd->translated ? 1 : atkbd->set; input_dev->id.version = atkbd->id; input_dev->event = atkbd_event; - input_dev->cdev.dev = &atkbd->ps2dev.serio->dev; + input_dev->dev.parent = &atkbd->ps2dev.serio->dev; input_set_drvdata(input_dev, atkbd); diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 25dd879..6578bff 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -323,7 +323,7 @@ static int __init corgikbd_probe(struct platform_device *pdev) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &pdev->dev; + input_dev->dev.parent = &pdev->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); input_dev->keycode = corgikbd->keycode; diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index b943993..71771ba 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -65,7 +65,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) input->name = pdev->name; input->phys = "gpio-keys/input0"; - input->cdev.dev = &pdev->dev; + input->dev.parent = &pdev->dev; input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 087d4df2..cdd254f 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -335,7 +335,7 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) kbd->dev->id.vendor = PCI_VENDOR_ID_HP; kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ - kbd->dev->cdev.dev = &serio->dev; + kbd->dev->dev.parent = &serio->dev; for (i = 0; i < 128; i++) { set_bit(hil_kbd_set1[i], kbd->dev->keybit); diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 257b9d4..1b08f4e 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -666,7 +666,7 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_LKKBD; input_dev->id.product = 0; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->event = lkkbd_event; input_set_drvdata (input_dev, lk); diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 764f5ee..7a41b27 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c @@ -231,6 +231,7 @@ static int locomokbd_probe(struct locomo_dev *dev) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; + input_dev->dev.parent = &dev->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = locomokbd->keycode; diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index 179f3a4..b97a41e 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c @@ -104,7 +104,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_NEWTON; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = nkbd->keycode; diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 1790f0c..3a22863 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -370,7 +370,7 @@ static int __init omap_kp_probe(struct platform_device *pdev) set_bit(keymap[i] & KEY_MAX, input_dev->keybit); input_dev->name = "omap-keypad"; input_dev->phys = "omap-keypad/input0"; - input_dev->cdev.dev = &pdev->dev; + input_dev->dev.parent = &pdev->dev; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c index 1a2afbf..993df87 100644 --- a/drivers/input/keyboard/pxa27x_keyboard.c +++ b/drivers/input/keyboard/pxa27x_keyboard.c @@ -169,7 +169,7 @@ static int __devinit pxakbd_probe(struct platform_device *pdev) input_dev->id.bustype = BUS_HOST; input_dev->open = pxakbd_open; input_dev->close = pxakbd_close; - input_dev->cdev.dev = &pdev->dev; + input_dev->dev.parent = &pdev->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); input_dev->relbit[LONG(REL_WHEEL)] = BIT(REL_WHEEL); diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index bc96074..41b8038 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -374,7 +374,7 @@ static int __init spitzkbd_probe(struct platform_device *dev) input_dev->name = "Spitz Keyboard"; input_dev->phys = spitzkbd->phys; - input_dev->cdev.dev = &dev->dev; + input_dev->dev.parent = &dev->dev; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c index c109620..b44b068 100644 --- a/drivers/input/keyboard/stowaway.c +++ b/drivers/input/keyboard/stowaway.c @@ -108,7 +108,7 @@ static int skbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_STOWAWAY; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = skbd->keycode; diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index ca74b2b..1d4e396 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -271,7 +271,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_SUNKBD; input_dev->id.product = sunkbd->type; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_set_drvdata(input_dev, sunkbd); diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index 11d9708..f3a56eb 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c @@ -108,7 +108,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = xtkbd->keycode; -- cgit v0.10.2 From c0f82d570c84f2592367e350a92ebd71e72ba68a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:35:03 -0400 Subject: Input: USB devices - switch to using input_dev->dev.parent In preparation for struct class_device -> struct device input core conversion, switch to using input_dev->dev.parent when specifying device position in sysfs tree. Signed-off-by: Dmitry Torokhov diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index 75972b7..be8e924 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c @@ -185,7 +185,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ input_dev->name = acecad->name; input_dev->phys = acecad->phys; usb_to_input_id(dev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; + input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, acecad); diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 8b33a8e..cc0a498 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -2044,7 +2044,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) inputdev->name = "Aiptek"; inputdev->phys = aiptek->features.usbPath; usb_to_input_id(usbdev, &inputdev->id); - inputdev->cdev.dev = &intf->dev; + inputdev->dev.parent = &intf->dev; input_set_drvdata(inputdev, aiptek); diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index ef6166a..e321526 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c @@ -584,7 +584,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id input_dev->name = "appletouch"; input_dev->phys = dev->phys; usb_to_input_id(dev->udev, &input_dev->id); - input_dev->cdev.dev = &iface->dev; + input_dev->dev.parent = &iface->dev; input_set_drvdata(input_dev, dev); diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 876b2725..5d3ddb9 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c @@ -662,7 +662,7 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) idev->phys = ati_remote->phys; usb_to_input_id(ati_remote->udev, &idev->id); - idev->cdev.dev = &ati_remote->udev->dev; + idev->dev.parent = &ati_remote->udev->dev; } static int ati_remote_initialize(struct ati_remote *ati_remote) diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c index 3c38ac6..a9032aa 100644 --- a/drivers/usb/input/ati_remote2.c +++ b/drivers/usb/input/ati_remote2.c @@ -362,7 +362,7 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) idev->phys = ar2->phys; usb_to_input_id(ar2->udev, &idev->id); - idev->cdev.dev = &ar2->udev->dev; + idev->dev.parent = &ar2->udev->dev; retval = input_register_device(idev); if (retval) diff --git a/drivers/usb/input/gtco.c b/drivers/usb/input/gtco.c index 75cce2a..dbd207e 100644 --- a/drivers/usb/input/gtco.c +++ b/drivers/usb/input/gtco.c @@ -952,7 +952,7 @@ static int gtco_probe(struct usb_interface *usbinterface, /* Set input device required ID information */ usb_to_input_id(gtco->usbdev, &input_dev->id); - input_dev->cdev.dev = &usbinterface->dev; + input_dev->dev.parent = &usbinterface->dev; /* Setup the URB, it will be posted later on open of input device */ endpoint = &usbinterface->altsetting[0].endpoint[0].desc; diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index 7ec999a..c4781b9 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c @@ -146,7 +146,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i input_dev->name = "KB Gear Tablet"; input_dev->phys = kbtab->phys; usb_to_input_id(dev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; + input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, kbtab); diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index daf8f21..1bffc9f 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c @@ -495,7 +495,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic input_dev->name = remote->name; input_dev->phys = remote->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &interface->dev; + input_dev->dev.parent = &interface->dev; input_dev->evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */ for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++) diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index f951a44..4f93a76 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c @@ -359,7 +359,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i input_dev->phys = pm->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; + input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, pm); diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c index 1696927..e082941 100644 --- a/drivers/usb/input/usbtouchscreen.c +++ b/drivers/usb/input/usbtouchscreen.c @@ -740,7 +740,7 @@ static int usbtouch_probe(struct usb_interface *intf, input_dev->name = usbtouch->name; input_dev->phys = usbtouch->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; + input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, usbtouch); diff --git a/drivers/usb/input/wacom_sys.c b/drivers/usb/input/wacom_sys.c index 7793ffb..1fe4820 100644 --- a/drivers/usb/input/wacom_sys.c +++ b/drivers/usb/input/wacom_sys.c @@ -230,7 +230,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom->wacom_wac = wacom_wac; usb_to_input_id(dev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; + input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, wacom); diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index b001796..7357239 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -345,7 +345,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id input_dev->name = xpad_device[i].name; input_dev->phys = xpad->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; + input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, xpad); diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index 294224e..c54f1a5 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c @@ -937,7 +937,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) input_dev->name = nfo->name; input_dev->phys = yld->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &intf->dev; + input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, yld); -- cgit v0.10.2 From 28aa7f1c8178db8b277a6e11325ef09adea8ac46 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:35:09 -0400 Subject: Input: mice - switch to using input_dev->dev.parent In preparation for struct class_device -> struct device input core conversion, switch to using input_dev->dev.parent when specifying device position in sysfs tree. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index 6c67aa4..449bf4d 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c @@ -378,7 +378,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) ptr->dev->id.vendor = PCI_VENDOR_ID_HP; ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ - ptr->dev->cdev.dev = &serio->dev; + ptr->dev->dev.parent = &serio->dev; input_register_device(ptr->dev); printk(KERN_INFO "input: %s (%s), ID: %d\n", diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 5444905..f15f695 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1083,7 +1083,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse { struct input_dev *input_dev = psmouse->dev; - input_dev->cdev.dev = &psmouse->ps2dev.serio->dev; + input_dev->dev.parent = &psmouse->ps2dev.serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index 1cb40e7..77b8ee2 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -266,7 +266,7 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = sermouse->type; input_dev->id.product = c; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index d65e8a9..4a32157 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -508,7 +508,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) input_dev->name = mouse->name; input_dev->phys = mouse->phys; input_dev->id.bustype = BUS_RS232; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ set_bit (EV_REL, input_dev->evbit); -- cgit v0.10.2 From a5394fb075a80212765ee3cd4a7842bdccf5fc0a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:35:14 -0400 Subject: Input: touchscreens - switch to using input_dev->dev.parent In preparation for struct class_device -> struct device input core conversion, switch to using input_dev->dev.parent when specifying device position in sysfs tree. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 2f5fc80..693e3b2 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -899,7 +899,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) input_dev->name = "ADS784x Touchscreen"; input_dev->phys = ts->phys; - input_dev->cdev.dev = &spi->dev; + input_dev->dev.parent = &spi->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 4965c05..e6a31d1 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -300,7 +300,7 @@ static int __init corgits_probe(struct platform_device *pdev) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0002; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &pdev->dev; + input_dev->dev.parent = &pdev->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 7e2f326..557d781 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c @@ -318,7 +318,7 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_ELO; input_dev->id.product = elo->id; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 399eb4a..39d6026 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c @@ -136,6 +136,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_GUNZE; input_dev->id.product = 0x0051; input_dev->id.version = 0x0100; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0); diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index 2b01ace..09ed780 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c @@ -367,7 +367,7 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_H3600; input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */ input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_set_drvdata(input_dev, ts); diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index 53b0683..4ec3b1f 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c @@ -150,6 +150,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_MICROTOUCH; input_dev->id.product = 0; input_dev->id.version = 0x0100; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0); diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index 65a4e0a..f2c0d3c 100644 --- a/drivers/input/touchscreen/penmount.c +++ b/drivers/input/touchscreen/penmount.c @@ -111,7 +111,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_PENMOUNT; input_dev->id.product = 0; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c index 63d2d44..3def7bb 100644 --- a/drivers/input/touchscreen/touchright.c +++ b/drivers/input/touchscreen/touchright.c @@ -124,6 +124,7 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_TOUCHRIGHT; input_dev->id.product = 0; input_dev->id.version = 0x0100; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0); diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c index 3da9c8c..ac4bdcf 100644 --- a/drivers/input/touchscreen/touchwin.c +++ b/drivers/input/touchscreen/touchwin.c @@ -131,6 +131,7 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_TOUCHWIN; input_dev->id.product = 0; input_dev->id.version = 0x0100; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0); diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index fe4bdf6..5200f4c 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -509,7 +509,7 @@ static int ucb1400_ts_probe(struct device *dev) input_set_drvdata(idev, ucb); - idev->cdev.dev = dev; + idev->dev.parent = dev; idev->name = "UCB1400 touchscreen interface"; idev->id.vendor = ucb1400_reg_read(ucb, AC97_VENDOR_ID1); idev->id.product = id; -- cgit v0.10.2 From 935e658e89678a7e3427b90cd7a1c86025d95bfe Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:35:26 -0400 Subject: Input: joysticks - switch to using input_dev->dev.parent In preparation for struct class_device -> struct device input core conversion, switch to using input_dev->dev.parent when specifying device position in sysfs tree. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index 4ac1a8f..ff701ab 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c @@ -314,7 +314,7 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.vendor = GAMEPORT_ID_VENDOR_MADCATZ; input_dev->id.product = a3d->mode; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &gameport->dev; + input_dev->dev.parent = &gameport->dev; input_dev->open = a3d_open; input_dev->close = a3d_close; diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index e835352..28140c4 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c @@ -424,7 +424,7 @@ static int adi_init_input(struct adi *adi, struct adi_port *port, int half) input_dev->id.vendor = GAMEPORT_ID_VENDOR_LOGITECH; input_dev->id.product = adi->id; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &port->gameport->dev; + input_dev->dev.parent = &port->gameport->dev; input_set_drvdata(input_dev, port); diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 7244e29..1c1afb5 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -449,6 +449,7 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG; input_dev->id.product = analog->mask >> 4; input_dev->id.version = 0x0100; + input_dev->dev.parent = &port->gameport->dev; input_set_drvdata(input_dev, port); diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 2075363..d3352a8 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c @@ -211,7 +211,7 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.vendor = GAMEPORT_ID_VENDOR_CREATIVE; input_dev->id.product = 0x0008; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &gameport->dev; + input_dev->dev.parent = &gameport->dev; input_set_drvdata(input_dev, cobra); diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index ac7db7a..d514aeb 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -308,7 +308,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.vendor = GAMEPORT_ID_VENDOR_GENIUS; input_dev->id.product = gf2k->id; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &gameport->dev; + input_dev->dev.parent = &gameport->dev; input_set_drvdata(input_dev, gf2k); diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index 41da7f1..73eb5ab 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -363,7 +363,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; input_dev->id.product = grip->mode[i]; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &gameport->dev; + input_dev->dev.parent = &gameport->dev; input_set_drvdata(input_dev, grip); diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 1771d5d..555319e 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c @@ -599,7 +599,7 @@ static int register_slot(int slot, struct grip_mp *grip) input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; input_dev->id.product = 0x0100 + port->mode; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &grip->gameport->dev; + input_dev->dev.parent = &grip->gameport->dev; input_set_drvdata(input_dev, grip); diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 3e022dc..d4e8073 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c @@ -231,7 +231,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT; input_dev->id.product = guillemot_type[i].id; input_dev->id.version = (int)data[14] << 8 | data[15]; - input_dev->cdev.dev = &gameport->dev; + input_dev->dev.parent = &gameport->dev; input_set_drvdata(input_dev, guillemot); diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index bd5a6de..fb129c4 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -287,13 +287,13 @@ int iforce_init_device(struct iforce *iforce) #ifdef CONFIG_JOYSTICK_IFORCE_USB case IFORCE_USB: input_dev->id.bustype = BUS_USB; - input_dev->cdev.dev = &iforce->usbdev->dev; + input_dev->dev.parent = &iforce->usbdev->dev; break; #endif #ifdef CONFIG_JOYSTICK_IFORCE_232 case IFORCE_232: input_dev->id.bustype = BUS_RS232; - input_dev->cdev.dev = &iforce->serio->dev; + input_dev->dev.parent = &iforce->serio->dev; break; #endif } diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index f0ff783..1aec1e9 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c @@ -262,6 +262,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT; input_dev->id.product = interact_type[i].id; input_dev->id.version = 0x0100; + input_dev->dev.parent = &gameport->dev; input_set_drvdata(input_dev, interact); diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index 31f6866..b35604e 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c @@ -168,7 +168,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_MAGELLAN; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index f800c39..2adf73f 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -751,7 +751,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT; input_dev->id.product = sw->type; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &gameport->dev; + input_dev->dev.parent = &gameport->dev; input_set_drvdata(input_dev, sw); diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index dd611de..abb7c4c 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -226,7 +226,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_SPACEBALL; input_dev->id.product = id; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index f5e4966..c4937f1 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c @@ -183,7 +183,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_SPACEORB; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index b6a6f21..8581ee9 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c @@ -154,7 +154,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_STINGER; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index 53260d1..3b36ee0 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c @@ -326,7 +326,7 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data) input_dev->id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER; input_dev->id.product = model->id; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &tmdc->gameport->dev; + input_dev->dev.parent = &tmdc->gameport->dev; input_set_drvdata(input_dev, tmdc); diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 458a129..c91504e 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c @@ -205,10 +205,9 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_TWIDJOY; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4); input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4); diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index e0927a5..4e85f72 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c @@ -160,7 +160,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_WARRIOR; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &serio->dev; + input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); -- cgit v0.10.2 From 293e6392d72dfaef1f6aef605769869512bec45d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:35:32 -0400 Subject: Input: misc devices - switch to using input_dev->dev.parent In preparation for struct class_device -> struct device input core conversion, switch to using input_dev->dev.parent when specifying device position in sysfs tree. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index da6650c..3d4b619 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c @@ -107,7 +107,7 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) input_dev->id.vendor = 0x001f; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &dev->dev; + input_dev->dev.parent = &dev->dev; input_dev->evbit[0] = BIT(EV_SND); input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c index 8d6c383..e9f26e7 100644 --- a/drivers/input/misc/m68kspkr.c +++ b/drivers/input/misc/m68kspkr.c @@ -63,7 +63,7 @@ static int __devinit m68kspkr_probe(struct platform_device *dev) input_dev->id.vendor = 0x001f; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = &dev->dev; + input_dev->dev.parent = &dev->dev; input_dev->evbit[0] = BIT(EV_SND); input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index afd3221..31989dc 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -78,7 +78,7 @@ static int __devinit pcspkr_probe(struct platform_device *dev) pcspkr_dev->id.vendor = 0x001f; pcspkr_dev->id.product = 0x0001; pcspkr_dev->id.version = 0x0100; - pcspkr_dev->cdev.dev = &dev->dev; + pcspkr_dev->dev.parent = &dev->dev; pcspkr_dev->evbit[0] = BIT(EV_SND); pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 106c94f..e36ec1d 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -28,7 +28,7 @@ struct sparcspkr_state { static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); + struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent); unsigned int count = 0; unsigned long flags; @@ -61,7 +61,7 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); + struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent); unsigned int count = 0; unsigned long flags; @@ -113,7 +113,7 @@ static int __devinit sparcspkr_probe(struct device *dev) input_dev->id.vendor = 0x001f; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = dev; + input_dev->dev.parent = dev; input_dev->evbit[0] = BIT(EV_SND); input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); -- cgit v0.10.2 From b5b16c5296c3276bb409a948173d557241b74379 Mon Sep 17 00:00:00 2001 From: Cliff Brake Date: Thu, 12 Apr 2007 01:35:43 -0400 Subject: Input: ucb1400 - make delays configurable This patch adds module parameters for several timing values used in the driver. These values can vary based on the hardware design and how much capacitive filtering there is on the touch panel inputs, and the resistance of the panel. Signed-off-by: Cliff Brake Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 5200f4c..24000f0 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -97,6 +97,8 @@ struct ucb1400 { }; static int adcsync; +static int ts_delay = 55; /* us */ +static int ts_delay_pressure; /* us */ static inline u16 ucb1400_reg_read(struct ucb1400 *ucb, u16 reg) { @@ -159,6 +161,7 @@ static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400 *ucb) UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); + udelay(ts_delay_pressure); return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); } @@ -180,7 +183,7 @@ static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400 *ucb) UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - udelay(55); + udelay(ts_delay); return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); } @@ -203,7 +206,7 @@ static inline unsigned int ucb1400_ts_read_ypos(struct ucb1400 *ucb) UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - udelay(55); + udelay(ts_delay); return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPX); } @@ -571,7 +574,15 @@ static void __exit ucb1400_ts_exit(void) driver_unregister(&ucb1400_ts_driver); } -module_param(adcsync, int, 0444); +module_param(adcsync, bool, 0444); +MODULE_PARM_DESC(adcsync, "Synchronize touch readings with ADCSYNC pin."); + +module_param(ts_delay, int, 0444); +MODULE_PARM_DESC(ts_delay, "Delay between panel setup and position read. Default = 55us."); + +module_param(ts_delay_pressure, int, 0444); +MODULE_PARM_DESC(ts_delay_pressure, + "delay between panel setup and pressure read. Default = 0us."); module_init(ucb1400_ts_init); module_exit(ucb1400_ts_exit); -- cgit v0.10.2 From b7fd4a0aa52c95309219240bf9c5fd210a6e7061 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Apr 2007 01:35:51 -0400 Subject: Input: pxa27x - do not use deprecated SA_INTERRUPT flag IRQF_DISABLED is the proper name. Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c index 993df87..06eaf76 100644 --- a/drivers/input/keyboard/pxa27x_keyboard.c +++ b/drivers/input/keyboard/pxa27x_keyboard.c @@ -181,7 +181,7 @@ static int __devinit pxakbd_probe(struct platform_device *pdev) } } - error = request_irq(IRQ_KEYPAD, pxakbd_irq_handler, SA_INTERRUPT, + error = request_irq(IRQ_KEYPAD, pxakbd_irq_handler, IRQF_DISABLED, DRIVER_NAME, pdev); if (error) { printk(KERN_ERR "Cannot request keypad IRQ\n"); -- cgit v0.10.2 From 0de9550971a0ee614ea4f06655e8a49aa3a942a8 Mon Sep 17 00:00:00 2001 From: Karl Pickett Date: Thu, 12 Apr 2007 01:35:59 -0400 Subject: Input: ati_remote - make button repeat sensitivity configurable ati_remote causes repeats after only .23 seconds with my remote and makes it hard to use comfortably. Make a precise way of setting the repeat delay time in milliseconds and default it to 500ms. The old behavior can be had by setting repeat_delay = 0. Signed-off-by: Karl Pickett Signed-off-by: Vincent Vanackere Signed-off-by: Dmitry Torokhov diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 5d3ddb9..471aab2 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c @@ -120,6 +120,7 @@ * behaviour. */ #define FILTER_TIME 60 /* msec */ +#define REPEAT_DELAY 500 /* msec */ static unsigned long channel_mask; module_param(channel_mask, ulong, 0644); @@ -133,6 +134,10 @@ static int repeat_filter = FILTER_TIME; module_param(repeat_filter, int, 0644); MODULE_PARM_DESC(repeat_filter, "Repeat filter time, default = 60 msec"); +static int repeat_delay = REPEAT_DELAY; +module_param(repeat_delay, int, 0644); +MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec"); + #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) #undef err #define err(format, arg...) printk(KERN_ERR format , ## arg) @@ -174,6 +179,8 @@ struct ati_remote { unsigned char old_data[2]; /* Detect duplicate events */ unsigned long old_jiffies; unsigned long acc_jiffies; /* handle acceleration */ + unsigned long first_jiffies; + unsigned int repeat_count; char name[NAME_BUFSIZE]; @@ -501,21 +508,31 @@ static void ati_remote_input_report(struct urb *urb) } if (ati_remote_tbl[index].kind == KIND_FILTERED) { + unsigned long now = jiffies; + /* Filter duplicate events which happen "too close" together. */ if (ati_remote->old_data[0] == data[1] && ati_remote->old_data[1] == data[2] && - time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(repeat_filter))) { + time_before(now, ati_remote->old_jiffies + + msecs_to_jiffies(repeat_filter))) { ati_remote->repeat_count++; } else { ati_remote->repeat_count = 0; + ati_remote->first_jiffies = now; } ati_remote->old_data[0] = data[1]; ati_remote->old_data[1] = data[2]; - ati_remote->old_jiffies = jiffies; + ati_remote->old_jiffies = now; + /* Ensure we skip at least the 4 first duplicate events (generated + * by a single keypress), and continue skipping until repeat_delay + * msecs have passed + */ if (ati_remote->repeat_count > 0 && - ati_remote->repeat_count < 5) + (ati_remote->repeat_count < 5 || + time_before(now, ati_remote->first_jiffies + + msecs_to_jiffies(repeat_delay)))) return; -- cgit v0.10.2 From d0a0515fc30b55d4b09395d44762c5f41d6d02d5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:36:12 -0400 Subject: Input: cobalt buttons - separate device and driver registration Create platform device for cobalt buttons as part of arch setup. This makes the driver follow current driver model more closely. Signed-off-by: Dmitry Torokhov Acked-by: Yoichi Yuasa diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile index 225ac8f..c35ee25 100644 --- a/arch/mips/cobalt/Makefile +++ b/arch/mips/cobalt/Makefile @@ -2,7 +2,7 @@ # Makefile for the Cobalt micro systems family specific parts of the kernel # -obj-y := irq.o reset.o setup.o +obj-y := irq.o reset.o setup.o buttons.o obj-$(CONFIG_EARLY_PRINTK) += console.o diff --git a/arch/mips/cobalt/buttons.c b/arch/mips/cobalt/buttons.c new file mode 100644 index 0000000..9e14398 --- /dev/null +++ b/arch/mips/cobalt/buttons.c @@ -0,0 +1,54 @@ +/* + * Cobalt buttons platform device. + * + * Copyright (C) 2007 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +static struct resource cobalt_buttons_resource __initdata = { + .start = 0x1d000000, + .end = 0x1d000003, + .flags = IORESOURCE_MEM, +}; + +static __init int cobalt_add_buttons(void) +{ + struct platform_device *pd; + int error; + + pd = platform_device_alloc("Cobalt buttons", -1); + if (!pd) + return -ENOMEM; + + error = platform_device_add_resources(pd, &cobalt_buttons_resource, 1); + if (error) + goto err_free_device; + + error = platform_device_add(pd); + if (error) + goto err_free_device; + + return 0; + + err_free_device: + platform_device_put(pd); + return error; +} +device_initcall(cobalt_add_buttons); diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index b14f49e..b9b2d77 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c @@ -50,14 +50,6 @@ static struct buttons_map buttons_map[] = { { 0x80000000, KEY_SELECT, }, }; -static struct resource cobalt_buttons_resource __initdata = { - .start = 0x1d000000, - .end = 0x1d000003, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device *cobalt_buttons_device; - static struct timer_list buttons_timer; static void handle_buttons(unsigned long data) @@ -183,26 +175,12 @@ static struct platform_driver cobalt_buttons_driver = { static int __init cobalt_buttons_init(void) { - int retval; - - cobalt_buttons_device = platform_device_register_simple("Cobalt buttons", -1, - &cobalt_buttons_resource, 1); - if (IS_ERR(cobalt_buttons_device)) { - retval = PTR_ERR(cobalt_buttons_device); - return retval; - } - - retval = platform_driver_register(&cobalt_buttons_driver); - if (retval < 0) - platform_device_unregister(cobalt_buttons_device); - - return retval; + return platform_driver_register(&cobalt_buttons_driver); } static void __exit cobalt_buttons_exit(void) { platform_driver_unregister(&cobalt_buttons_driver); - platform_device_unregister(cobalt_buttons_device); } module_init(cobalt_buttons_init); -- cgit v0.10.2 From e7afcd1bf784dde4cd6c6efbf9a4709626cc8e08 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:36:25 -0400 Subject: Input: lifebook - work properly on Panasonic CF-18 Panasonic CF18 has an active multiplexing controller with touchscreen connected to one port and a touchpad to another. Use "phys" from serio port to activate lifebook protoocol only on the port that has touchscreen connected to it. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 29542f0..28d9770 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -20,6 +20,14 @@ #include "psmouse.h" #include "lifebook.h" +static const char *desired_serio_phys; + +static int lifebook_set_serio_phys(struct dmi_system_id *d) +{ + desired_serio_phys = d->driver_data; + return 0; +} + static struct dmi_system_id lifebook_dmi_table[] = { { .ident = "FLORA-ie 55mi", @@ -56,6 +64,8 @@ static struct dmi_system_id lifebook_dmi_table[] = { .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), }, + .callback = lifebook_set_serio_phys, + .driver_data = "isa0060/serio3", }, { .ident = "Lifebook B142", @@ -138,6 +148,10 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties) if (!dmi_check_system(lifebook_dmi_table)) return -1; + if (desired_serio_phys && + strcmp(psmouse->ps2dev.serio->phys, desired_serio_phys)) + return -1; + if (set_properties) { psmouse->vendor = "Fujitsu"; psmouse->name = "Lifebook TouchScreen"; -- cgit v0.10.2 From 1b118799cceab69d80c162bc661c77fdc33dd756 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Apr 2007 01:36:34 -0400 Subject: Input: lifebook - activate 6-byte protocol on select models It appears that if we turn on 6-byte Lifebook protocol on Panasonic CF-28 its touchpad is left alone and generates standard 3-byte PS/2 data stream with relative packets instead of being converted in 3-byte Lifebook protocol with absolute coordinates - in other words what get what we need to distinguish between touchscreen and touchpad. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 28d9770..6ac7177 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -28,6 +28,14 @@ static int lifebook_set_serio_phys(struct dmi_system_id *d) return 0; } +static unsigned char lifebook_use_6byte_proto; + +static int lifebook_set_6byte_proto(struct dmi_system_id *d) +{ + lifebook_use_6byte_proto = 1; + return 0; +} + static struct dmi_system_id lifebook_dmi_table[] = { { .ident = "FLORA-ie 55mi", @@ -68,6 +76,14 @@ static struct dmi_system_id lifebook_dmi_table[] = { .driver_data = "isa0060/serio3", }, { + .ident = "Panasonic CF-28", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), + DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"), + }, + .callback = lifebook_set_6byte_proto, + }, + { .ident = "Lifebook B142", .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), @@ -78,23 +94,53 @@ static struct dmi_system_id lifebook_dmi_table[] = { static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) { - unsigned char *packet = psmouse->packet; struct input_dev *dev = psmouse->dev; + unsigned char *packet = psmouse->packet; + int relative_packet = packet[0] & 0x08; - if (psmouse->pktcnt != 3) - return PSMOUSE_GOOD_DATA; - - /* calculate X and Y */ - if ((packet[0] & 0x08) == 0x00) { - input_report_abs(dev, ABS_X, - (packet[1] | ((packet[0] & 0x30) << 4))); - input_report_abs(dev, ABS_Y, - 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); + if (relative_packet || !lifebook_use_6byte_proto) { + if (psmouse->pktcnt != 3) + return PSMOUSE_GOOD_DATA; } else { + switch (psmouse->pktcnt) { + case 1: + return (packet[0] & 0xf8) == 0x00 ? + PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; + case 2: + return PSMOUSE_GOOD_DATA; + case 3: + return ((packet[2] & 0x30) << 2) == (packet[2] & 0xc0) ? + PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; + case 4: + return (packet[3] & 0xf8) == 0xc0 ? + PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; + case 5: + return (packet[4] & 0xc0) == (packet[2] & 0xc0) ? + PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; + case 6: + if (((packet[5] & 0x30) << 2) != (packet[5] & 0xc0)) + return PSMOUSE_BAD_DATA; + if ((packet[5] & 0xc0) != (packet[1] & 0xc0)) + return PSMOUSE_BAD_DATA; + break; /* report data */ + } + } + + if (relative_packet) { input_report_rel(dev, REL_X, ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); input_report_rel(dev, REL_Y, -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); + } else if (lifebook_use_6byte_proto) { + input_report_abs(dev, ABS_X, + ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f)); + input_report_abs(dev, ABS_Y, + 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f))); + } else { + input_report_abs(dev, ABS_X, + (packet[1] | ((packet[0] & 0x30) << 4))); + input_report_abs(dev, ABS_Y, + 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); } input_report_key(dev, BTN_LEFT, packet[0] & 0x01); @@ -119,7 +165,7 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) you leave this call out the touchsreen will never send absolute coordinates */ - param = 0x07; + param = lifebook_use_6byte_proto ? 0x08 : 0x07; ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); return 0; @@ -163,6 +209,7 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties) int lifebook_init(struct psmouse *psmouse) { struct input_dev *input_dev = psmouse->dev; + int max_coord = lifebook_use_6byte_proto ? 1024 : 4096; if (lifebook_absolute_mode(psmouse)) return -1; @@ -171,13 +218,18 @@ int lifebook_init(struct psmouse *psmouse) input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); - input_set_abs_params(input_dev, ABS_X, 0, 1024, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, 1024, 0, 0); + input_set_abs_params(input_dev, ABS_X, 0, max_coord, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, max_coord, 0, 0); psmouse->protocol_handler = lifebook_process_byte; psmouse->set_resolution = lifebook_set_resolution; psmouse->disconnect = lifebook_disconnect; psmouse->reconnect = lifebook_absolute_mode; + + /* + * Use packet size = 3 even when using 6-byte protocol because + * that's what POLL will return on Lifebooks (according to spec). + */ psmouse->pktsize = 3; return 0; -- cgit v0.10.2 From 43887ba15a0c1e293be63793541fe444778c0474 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 25 Apr 2007 00:39:31 -0400 Subject: Input: lifebook - add signature of Panasonic CF-29 Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 6ac7177..aa3b245 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -84,6 +84,14 @@ static struct dmi_system_id lifebook_dmi_table[] = { .callback = lifebook_set_6byte_proto, }, { + .ident = "Panasonic CF-29", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), + DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), + }, + .callback = lifebook_set_6byte_proto, + }, + { .ident = "Lifebook B142", .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), -- cgit v0.10.2 From 2ebdcc615bde8317058d76ce1f24a67f59185884 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 25 Apr 2007 00:39:53 -0400 Subject: Input: lifebook - split into 2 devices Have lifebook protocol register 2 separate input devices - one for the touchscreen reporting absolute coordinates and touches and another one for touchpad reporting relative coordinates and left and right button presses. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index aa3b245..1740cad 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -20,6 +20,11 @@ #include "psmouse.h" #include "lifebook.h" +struct lifebook_data { + struct input_dev *dev2; /* Relative device */ + char phys[32]; +}; + static const char *desired_serio_phys; static int lifebook_set_serio_phys(struct dmi_system_id *d) @@ -102,7 +107,9 @@ static struct dmi_system_id lifebook_dmi_table[] = { static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) { - struct input_dev *dev = psmouse->dev; + struct lifebook_data *priv = psmouse->private; + struct input_dev *dev1 = psmouse->dev; + struct input_dev *dev2 = priv->dev2; unsigned char *packet = psmouse->packet; int relative_packet = packet[0] & 0x08; @@ -135,27 +142,35 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) } if (relative_packet) { - input_report_rel(dev, REL_X, - ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); - input_report_rel(dev, REL_Y, - -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); + if (!dev2) + printk(KERN_WARNING "lifebook.c: got relative packet " + "but no relative device set up\n"); } else if (lifebook_use_6byte_proto) { - input_report_abs(dev, ABS_X, + input_report_abs(dev1, ABS_X, ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f)); - input_report_abs(dev, ABS_Y, + input_report_abs(dev1, ABS_Y, 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f))); } else { - input_report_abs(dev, ABS_X, + input_report_abs(dev1, ABS_X, (packet[1] | ((packet[0] & 0x30) << 4))); - input_report_abs(dev, ABS_Y, + input_report_abs(dev1, ABS_Y, 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); } - input_report_key(dev, BTN_LEFT, packet[0] & 0x01); - input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); - input_report_key(dev, BTN_TOUCH, packet[0] & 0x04); + input_report_key(dev1, BTN_TOUCH, packet[0] & 0x04); + input_sync(dev1); - input_sync(dev); + if (dev2) { + if (relative_packet) { + input_report_rel(dev2, REL_X, + ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); + input_report_rel(dev2, REL_Y, + -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); + } + input_report_key(dev2, BTN_LEFT, packet[0] & 0x01); + input_report_key(dev2, BTN_RIGHT, packet[0] & 0x02); + input_sync(dev2); + } return PSMOUSE_FULL_PACKET; } @@ -179,6 +194,14 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) return 0; } +static void lifebook_relative_mode(struct psmouse *psmouse) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + unsigned char param = 0x06; + + ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); +} + static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution) { static const unsigned char params[] = { 0, 1, 2, 2, 3 }; @@ -195,6 +218,8 @@ static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolu static void lifebook_disconnect(struct psmouse *psmouse) { psmouse_reset(psmouse); + kfree(psmouse->private); + psmouse->private = NULL; } int lifebook_detect(struct psmouse *psmouse, int set_properties) @@ -214,26 +239,74 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties) return 0; } +static int lifebook_create_relative_device(struct psmouse *psmouse) +{ + struct input_dev *dev2; + struct lifebook_data *priv; + int error = -ENOMEM; + + priv = kzalloc(sizeof(struct lifebook_data), GFP_KERNEL); + dev2 = input_allocate_device(); + if (!priv || !dev2) + goto err_out; + + priv->dev2 = dev2; + snprintf(priv->phys, sizeof(priv->phys), + "%s/input1", psmouse->ps2dev.serio->phys); + + dev2->phys = priv->phys; + dev2->name = "PS/2 Touchpad"; + dev2->id.bustype = BUS_I8042; + dev2->id.vendor = 0x0002; + dev2->id.product = PSMOUSE_LIFEBOOK; + dev2->id.version = 0x0000; + dev2->dev.parent = &psmouse->ps2dev.serio->dev; + + dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + dev2->relbit[LONG(REL_X)] = BIT(REL_X) | BIT(REL_Y); + dev2->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); + + error = input_register_device(priv->dev2); + if (error) + goto err_out; + + psmouse->private = priv; + return 0; + + err_out: + input_free_device(dev2); + kfree(priv); + return error; +} + int lifebook_init(struct psmouse *psmouse) { - struct input_dev *input_dev = psmouse->dev; + struct input_dev *dev1 = psmouse->dev; int max_coord = lifebook_use_6byte_proto ? 1024 : 4096; if (lifebook_absolute_mode(psmouse)) return -1; - input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); - input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); - input_set_abs_params(input_dev, ABS_X, 0, max_coord, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, max_coord, 0, 0); + dev1->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); + dev1->relbit[0] = 0; + dev1->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); + input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); + + if (!desired_serio_phys) { + if (lifebook_create_relative_device(psmouse)) { + lifebook_relative_mode(psmouse); + return -1; + } + } psmouse->protocol_handler = lifebook_process_byte; psmouse->set_resolution = lifebook_set_resolution; psmouse->disconnect = lifebook_disconnect; psmouse->reconnect = lifebook_absolute_mode; + psmouse->model = lifebook_use_6byte_proto ? 6 : 3; + /* * Use packet size = 3 even when using 6-byte protocol because * that's what POLL will return on Lifebooks (according to spec). -- cgit v0.10.2 From cc8310e33b0439b43cdb19de55b2507cb27bd229 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 25 Apr 2007 00:40:32 -0400 Subject: Input: i8042 - add Panasonic CF-29 to nomux list There is no data coming from touchscreen on Panasonic CF-29 notebook unless keyboard controller is in legacy mode. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 5c007d4..196cdf5 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -161,6 +161,17 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { }, { /* + * No data is coming from the touchscreen unless KBC + * is in legacy mode. + */ + .ident = "Panasonic CF-29", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), + DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), + }, + }, + { + /* * Errors on MUX ports are reported without raising AUXDATA * causing "spurious NAK" messages. */ -- cgit v0.10.2 From b9973954c5f3264a2afa6ec357adb542f4b76e06 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 25 Apr 2007 00:40:53 -0400 Subject: Input: i8042 - add Fujitsu touchscreen/touchpad PNP IDs Add PNP IDs for Fujitsu touchscreen/touchpad for AUX port detection to latch onto. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 196cdf5..6858bc5 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -302,6 +302,8 @@ static struct pnp_driver i8042_pnp_kbd_driver = { }; static struct pnp_device_id pnp_aux_devids[] = { + { .id = "FJC6000", .driver_data = 0 }, + { .id = "FJC6001", .driver_data = 0 }, { .id = "PNP0f03", .driver_data = 0 }, { .id = "PNP0f0b", .driver_data = 0 }, { .id = "PNP0f0e", .driver_data = 0 }, -- cgit v0.10.2 From 534565f254490227e3bec20d50f387800960acd9 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 25 Apr 2007 00:53:18 -0400 Subject: Input: add input_set_capability() helper Add input_set_capability() helper used to indicate that an input device supports a certain event without need to manipulate bitmaps directly. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/input.c b/drivers/input/input.c index 173c286..915e9ab 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1046,6 +1046,62 @@ void input_free_device(struct input_dev *dev) } EXPORT_SYMBOL(input_free_device); +/** + * input_set_capability - mark device as capable of a certain event + * @dev: device that is capable of emitting or accepting event + * @type: type of the event (EV_KEY, EV_REL, etc...) + * @code: event code + * + * In addition to setting up corresponding bit in appropriate capability + * bitmap the function also adjusts dev->evbit. + */ +void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code) +{ + switch (type) { + case EV_KEY: + __set_bit(code, dev->keybit); + break; + + case EV_REL: + __set_bit(code, dev->relbit); + break; + + case EV_ABS: + __set_bit(code, dev->absbit); + break; + + case EV_MSC: + __set_bit(code, dev->mscbit); + break; + + case EV_SW: + __set_bit(code, dev->swbit); + break; + + case EV_LED: + __set_bit(code, dev->ledbit); + break; + + case EV_SND: + __set_bit(code, dev->sndbit); + break; + + case EV_FF: + __set_bit(code, dev->ffbit); + break; + + default: + printk(KERN_ERR + "input_set_capability: unknown type %u (code %u)\n", + type, code); + dump_stack(); + return; + } + + __set_bit(type, dev->evbit); +} +EXPORT_SYMBOL(input_set_capability); + int input_register_device(struct input_dev *dev) { static atomic_t input_no = ATOMIC_INIT(0); diff --git a/include/linux/input.h b/include/linux/input.h index 7b6d7c4..1789ee9 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1160,6 +1160,8 @@ static inline void input_sync(struct input_dev *dev) input_event(dev, EV_SYN, SYN_REPORT, 0); } +void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code); + static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat) { dev->absmin[axis] = min; -- cgit v0.10.2 From fd013ce8d42a6667bea2a3c6dca37da8842ab2bf Mon Sep 17 00:00:00 2001 From: Eric Piel Date: Sun, 29 Apr 2007 23:41:53 -0400 Subject: Input: wistron - fix typo in keymap for Acer TM610 This patch fixes typo that prevented PROG2 key from working on Acer Travelmate 610. Signed-off-by: Eric Piel Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 793cee3..961aad7 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -490,7 +490,7 @@ static struct key_entry keymap_acer_travelmate_610[] __initdata = { { KE_KEY, 0x01, {KEY_HELP} }, { KE_KEY, 0x02, {KEY_CONFIG} }, { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG3} }, + { KE_KEY, 0x12, {KEY_PROG2} }, { KE_KEY, 0x13, {KEY_PROG3} }, { KE_KEY, 0x14, {KEY_MAIL} }, { KE_KEY, 0x15, {KEY_WWW} }, -- cgit v0.10.2 From 85796e7d939a39787f10a643477298678fed85db Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Apr 2007 23:42:08 -0400 Subject: Input: update some documentation Input-programming.txt got out of sync with the latest changes in input core; let's refresh it. Signed-off-by: Dmitry Torokhov diff --git a/Documentation/input/input-programming.txt b/Documentation/input/input-programming.txt index 180e0689..d9d5230 100644 --- a/Documentation/input/input-programming.txt +++ b/Documentation/input/input-programming.txt @@ -1,5 +1,3 @@ -$Id: input-programming.txt,v 1.4 2001/05/04 09:47:14 vojtech Exp $ - Programming input drivers ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -20,28 +18,51 @@ pressed or released a BUTTON_IRQ happens. The driver could look like: #include #include +static struct input_dev *button_dev; + static void button_interrupt(int irq, void *dummy, struct pt_regs *fp) { - input_report_key(&button_dev, BTN_1, inb(BUTTON_PORT) & 1); - input_sync(&button_dev); + input_report_key(button_dev, BTN_1, inb(BUTTON_PORT) & 1); + input_sync(button_dev); } static int __init button_init(void) { + int error; + if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) { printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq); return -EBUSY; } - - button_dev.evbit[0] = BIT(EV_KEY); - button_dev.keybit[LONG(BTN_0)] = BIT(BTN_0); - - input_register_device(&button_dev); + + button_dev = input_allocate_device(); + if (!button_dev) { + printk(KERN_ERR "button.c: Not enough memory\n"); + error = -ENOMEM; + goto err_free_irq; + } + + button_dev->evbit[0] = BIT(EV_KEY); + button_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); + + error = input_register_device(button_dev); + if (error) { + printk(KERN_ERR "button.c: Failed to register device\n"); + goto err_free_dev; + } + + return 0; + + err_free_dev: + input_free_device(button_dev); + err_free_irq: + free_irq(BUTTON_IRQ, button_interrupt); + return error; } static void __exit button_exit(void) { - input_unregister_device(&button_dev); + input_unregister_device(button_dev); free_irq(BUTTON_IRQ, button_interrupt); } @@ -58,17 +79,18 @@ In the _init function, which is called either upon module load or when booting the kernel, it grabs the required resources (it should also check for the presence of the device). -Then it sets the input bitfields. This way the device driver tells the other +Then it allocates a new input device structure with input_aloocate_device() +and sets up input bitfields. This way the device driver tells the other parts of the input systems what it is - what events can be generated or -accepted by this input device. Our example device can only generate EV_KEY type -events, and from those only BTN_0 event code. Thus we only set these two -bits. We could have used +accepted by this input device. Our example device can only generate EV_KEY +type events, and from those only BTN_0 event code. Thus we only set these +two bits. We could have used set_bit(EV_KEY, button_dev.evbit); set_bit(BTN_0, button_dev.keybit); as well, but with more than single bits the first approach tends to be -shorter. +shorter. Then the example driver registers the input device structure by calling @@ -76,16 +98,15 @@ Then the example driver registers the input device structure by calling This adds the button_dev structure to linked lists of the input driver and calls device handler modules _connect functions to tell them a new input -device has appeared. Because the _connect functions may call kmalloc(, -GFP_KERNEL), which can sleep, input_register_device() must not be called -from an interrupt or with a spinlock held. +device has appeared. input_register_device() may sleep and therefore must +not be called from an interrupt or with a spinlock held. While in use, the only used function of the driver is button_interrupt() which upon every interrupt from the button checks its state and reports it -via the +via the input_report_key() @@ -113,16 +134,10 @@ can use the open and close callback to know when it can stop polling or release the interrupt and when it must resume polling or grab the interrupt again. To do that, we would add this to our example driver: -int button_used = 0; - static int button_open(struct input_dev *dev) { - if (button_used++) - return 0; - if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) { printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq); - button_used--; return -EBUSY; } @@ -131,20 +146,21 @@ static int button_open(struct input_dev *dev) static void button_close(struct input_dev *dev) { - if (!--button_used) - free_irq(IRQ_AMIGA_VERTB, button_interrupt); + free_irq(IRQ_AMIGA_VERTB, button_interrupt); } static int __init button_init(void) { ... - button_dev.open = button_open; - button_dev.close = button_close; + button_dev->open = button_open; + button_dev->close = button_close; ... } -Note the button_used variable - we have to track how many times the open -function was called to know when exactly our device stops being used. +Note that input core keeps track of number of users for the device and +makes sure that dev->open() is called only when the first user connects +to the device and that dev->close() is called when the very last user +disconnects. Calls to both callbacks are serialized. The open() callback should return a 0 in case of success or any nonzero value in case of failure. The close() callback (which is void) must always succeed. @@ -175,7 +191,7 @@ set the corresponding bits and call the input_report_rel(struct input_dev *dev, int code, int value) -function. Events are generated only for nonzero value. +function. Events are generated only for nonzero value. However EV_ABS requires a little special care. Before calling input_register_device, you have to fill additional fields in the input_dev @@ -187,6 +203,10 @@ the ABS_X axis: button_dev.absfuzz[ABS_X] = 4; button_dev.absflat[ABS_X] = 8; +Or, you can just say: + + input_set_abs_params(button_dev, ABS_X, 0, 255, 4, 8); + This setting would be appropriate for a joystick X axis, with the minimum of 0, maximum of 255 (which the joystick *must* be able to reach, no problem if it sometimes reports more, but it must be able to always reach the min and @@ -197,14 +217,7 @@ If you don't need absfuzz and absflat, you can set them to zero, which mean that the thing is precise and always returns to exactly the center position (if it has any). -1.4 The void *private field -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This field in the input structure can be used to point to any private data -structures in the input device driver, in case the driver handles more than -one device. You'll need it in the open and close callbacks. - -1.5 NBITS(), LONG(), BIT() +1.4 NBITS(), LONG(), BIT() ~~~~~~~~~~~~~~~~~~~~~~~~~~ These three macros from input.h help some bitfield computations: @@ -213,13 +226,9 @@ These three macros from input.h help some bitfield computations: LONG(x) - returns the index in the array in longs for bit x BIT(x) - returns the index in a long for bit x -1.6 The number, id* and name fields +1.5 The id* and name fields ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The dev->number is assigned by the input system to the input device when it -is registered. It has no use except for identifying the device to the user -in system messages. - The dev->name should be set before registering the input device by the input device driver. It's a string like 'Generic button device' containing a user friendly name of the device. @@ -234,15 +243,25 @@ driver. The id and name fields can be passed to userland via the evdev interface. -1.7 The keycode, keycodemax, keycodesize fields +1.6 The keycode, keycodemax, keycodesize fields ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -These two fields will be used for any input devices that report their data -as scancodes. If not all scancodes can be known by autodetection, they may -need to be set by userland utilities. The keycode array then is an array -used to map from scancodes to input system keycodes. The keycode max will -contain the size of the array and keycodesize the size of each entry in it -(in bytes). +These three fields should be used by input devices that have dense keymaps. +The keycode is an array used to map from scancodes to input system keycodes. +The keycode max should contain the size of the array and keycodesize the +size of each entry in it (in bytes). + +Userspace can query and alter current scancode to keycode mappings using +EVIOCGKEYCODE and EVIOCSKEYCODE ioctls on corresponding evdev interface. +When a device has all 3 aforementioned fields filled in, the driver may +rely on kernel's default implementation of setting and querying keycode +mappings. + +1.7 dev->getkeycode() and dev->setkeycode() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +getkeycode() and setkeycode() callbacks allow drivers to override default +keycode/keycodesize/keycodemax mapping mechanism provided by input core +and implement sparse keycode maps. 1.8 Key autorepeat ~~~~~~~~~~~~~~~~~~ @@ -266,7 +285,7 @@ direction - from the system to the input device driver. If your input device driver can handle these events, it has to set the respective bits in evbit, *and* also the callback routine: - button_dev.event = button_event; + button_dev->event = button_event; int button_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); { -- cgit v0.10.2 From 0dcd8073673115eeb67343787f244905f62532f2 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Apr 2007 23:42:45 -0400 Subject: Input: add skeleton for simple polled devices input-polldev provides a skeleton for supporting simple input devices that need to be periodically scanned or polled to detect changes in their state. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 5694115..696c960 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -90,6 +90,17 @@ config INPUT_UINPUT To compile this driver as a module, choose M here: the module will be called uinput. +config INPUT_POLLDEV + tristate "Polled input device skeleton" + help + Say Y here if you are using a driver for an input + device that periodically polls hardware state. This + option is only useful for out-of-tree drivers since + in-tree drivers select it automatically. + + To compile this driver as a module, choose M here: the + module will be called input-polldev. + config HP_SDC_RTC tristate "HP SDC Real Time Clock" depends on GSC || HP300 diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 9f08f27..21e3cca 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -4,6 +4,7 @@ # Each configuration option enables a list of files. +obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o diff --git a/drivers/input/misc/input-polldev.c b/drivers/input/misc/input-polldev.c new file mode 100644 index 0000000..1b2b9c9 --- /dev/null +++ b/drivers/input/misc/input-polldev.c @@ -0,0 +1,171 @@ +/* + * Generic implementation of a polled input device + + * Copyright (c) 2007 Dmitry Torokhov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include +#include +#include + +static DEFINE_MUTEX(polldev_mutex); +static int polldev_users; +static struct workqueue_struct *polldev_wq; + +static int input_polldev_start_workqueue(void) +{ + int retval; + + retval = mutex_lock_interruptible(&polldev_mutex); + if (retval) + return retval; + + if (!polldev_users) { + polldev_wq = create_singlethread_workqueue("ipolldevd"); + if (!polldev_wq) { + printk(KERN_ERR "input-polldev: failed to create " + "ipolldevd workqueue\n"); + retval = -ENOMEM; + goto out; + } + } + + polldev_users++; + + out: + mutex_unlock(&polldev_mutex); + return retval; +} + +static void input_polldev_stop_workqueue(void) +{ + mutex_lock(&polldev_mutex); + + if (!--polldev_users) + destroy_workqueue(polldev_wq); + + mutex_unlock(&polldev_mutex); +} + +static void input_polled_device_work(struct work_struct *work) +{ + struct input_polled_dev *dev = + container_of(work, struct input_polled_dev, work.work); + + dev->poll(dev); + queue_delayed_work(polldev_wq, &dev->work, + msecs_to_jiffies(dev->poll_interval)); +} + +static int input_open_polled_device(struct input_dev *input) +{ + struct input_polled_dev *dev = input->private; + int error; + + error = input_polldev_start_workqueue(); + if (error) + return error; + + if (dev->flush) + dev->flush(dev); + + queue_delayed_work(polldev_wq, &dev->work, + msecs_to_jiffies(dev->poll_interval)); + + return 0; +} + +static void input_close_polled_device(struct input_dev *input) +{ + struct input_polled_dev *dev = input->private; + + cancel_rearming_delayed_workqueue(polldev_wq, &dev->work); + input_polldev_stop_workqueue(); +} + +/** + * input_allocate_polled_device - allocated memory polled device + * + * The function allocates memory for a polled device and also + * for an input device associated with this polled device. + */ +struct input_polled_dev *input_allocate_polled_device(void) +{ + struct input_polled_dev *dev; + + dev = kzalloc(sizeof(struct input_polled_dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->input = input_allocate_device(); + if (!dev->input) { + kfree(dev); + return NULL; + } + + return dev; +} +EXPORT_SYMBOL(input_allocate_polled_device); + +/** + * input_free_polled_device - free memory allocated for polled device + * @dev: device to free + * + * The function frees memory allocated for polling device and drops + * reference to the associated input device (if present). + */ +void input_free_polled_device(struct input_polled_dev *dev) +{ + if (dev) { + input_free_device(dev->input); + kfree(dev); + } +} +EXPORT_SYMBOL(input_free_polled_device); + +/** + * input_register_polled_device - register polled device + * @dev: device to register + * + * The function registers previously initialized polled input device + * with input layer. The device should be allocated with call to + * input_allocate_polled_device(). Callers should also set up poll() + * method and set up capabilities (id, name, phys, bits) of the + * corresponing input_dev structure. + */ +int input_register_polled_device(struct input_polled_dev *dev) +{ + struct input_dev *input = dev->input; + + INIT_DELAYED_WORK(&dev->work, input_polled_device_work); + if (!dev->poll_interval) + dev->poll_interval = 500; + input->private = dev; + input->open = input_open_polled_device; + input->close = input_close_polled_device; + + return input_register_device(input); +} +EXPORT_SYMBOL(input_register_polled_device); + +/** + * input_unregister_polled_device - unregister polled device + * @dev: device to unregister + * + * The function unregisters previously registered polled input + * device from input layer. Polling is stopped and device is + * ready to be freed with call to input_free_polled_device(). + * Callers should not attempt to access dev->input pointer + * after calling this function. + */ +void input_unregister_polled_device(struct input_polled_dev *dev) +{ + input_unregister_device(dev->input); + dev->input = NULL; +} +EXPORT_SYMBOL(input_unregister_polled_device); + diff --git a/include/linux/input-polldev.h b/include/linux/input-polldev.h new file mode 100644 index 0000000..597a007 --- /dev/null +++ b/include/linux/input-polldev.h @@ -0,0 +1,46 @@ +#ifndef _INPUT_POLLDEV_H +#define _INPUT_POLLDEV_H + +/* + * Copyright (c) 2007 Dmitry Torokhov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include +#include + +/** + * struct input_polled_dev - simple polled input device + * @private: private driver data + * @flush: driver-supplied method that flushes device's state upon + * opening (optional) + * @poll: driver-supplied method that polls the device and posts + * input events (mandatory). + * @poll_interval: specifies how often the poll() method shoudl be called. + * @input: input device structire associated with the polled device. + * Must be properly initialized by the driver (id, name, phys, bits). + * + * Polled input device provides a skeleton for supporting simple input + * devices that do not raise interrupts but have to be periodically + * scanned or polled to detect changes in their state. + */ +struct input_polled_dev { + void *private; + + void (*flush)(struct input_polled_dev *dev); + void (*poll)(struct input_polled_dev *dev); + unsigned int poll_interval; /* msec */ + + struct input_dev *input; + struct delayed_work work; +}; + +struct input_polled_dev *input_allocate_polled_device(void); +void input_free_polled_device(struct input_polled_dev *dev); +int input_register_polled_device(struct input_polled_dev *dev); +void input_unregister_polled_device(struct input_polled_dev *dev); + +#endif -- cgit v0.10.2 From 3d29cdff999c37b3876082278a8134a0642a02cd Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 Apr 2007 23:43:06 -0400 Subject: Input: cobalt_btns - convert to use polldev library Signed-off-by: Dmitry Torokhov Acked-by: Yoichi Yuasa diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 696c960..1d0d3e7 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -43,6 +43,7 @@ config INPUT_M68K_BEEP config INPUT_COBALT_BTNS tristate "Cobalt button interface" depends on MIPS_COBALT + select INPUT_POLLDEV help Say Y here if you want to support MIPS Cobalt button interface. diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index b9b2d77..064b079 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c @@ -18,19 +18,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include -#include +#include #include #include #include -#include -#include #define BUTTONS_POLL_INTERVAL 30 /* msec */ #define BUTTONS_COUNT_THRESHOLD 3 #define BUTTONS_STATUS_MASK 0xfe000000 struct buttons_dev { - struct input_dev *input; + struct input_polled_dev *poll_dev; void __iomem *reg; }; @@ -50,16 +48,14 @@ static struct buttons_map buttons_map[] = { { 0x80000000, KEY_SELECT, }, }; -static struct timer_list buttons_timer; - -static void handle_buttons(unsigned long data) +static void handle_buttons(struct input_polled_dev *dev) { struct buttons_map *button = buttons_map; - struct buttons_dev *bdev; + struct buttons_dev *bdev = dev->private; + struct input_dev *input = dev->input; uint32_t status; int i; - bdev = (struct buttons_dev *)data; status = readl(bdev->reg); status = ~status & BUTTONS_STATUS_MASK; @@ -68,55 +64,45 @@ static void handle_buttons(unsigned long data) button->count++; } else { if (button->count >= BUTTONS_COUNT_THRESHOLD) { - input_report_key(bdev->input, button->keycode, 0); - input_sync(bdev->input); + input_report_key(input, button->keycode, 0); + input_sync(input); } button->count = 0; } if (button->count == BUTTONS_COUNT_THRESHOLD) { - input_report_key(bdev->input, button->keycode, 1); - input_sync(bdev->input); + input_report_key(input, button->keycode, 1); + input_sync(input); } button++; } - - mod_timer(&buttons_timer, jiffies + msecs_to_jiffies(BUTTONS_POLL_INTERVAL)); -} - -static int cobalt_buttons_open(struct input_dev *dev) -{ - mod_timer(&buttons_timer, jiffies + msecs_to_jiffies(BUTTONS_POLL_INTERVAL)); - - return 0; -} - -static void cobalt_buttons_close(struct input_dev *dev) -{ - del_timer_sync(&buttons_timer); } static int __devinit cobalt_buttons_probe(struct platform_device *pdev) { struct buttons_dev *bdev; + struct input_polled_dev *poll_dev; struct input_dev *input; struct resource *res; int error, i; bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL); - input = input_allocate_device(); - if (!bdev || !input) { + poll_dev = input_allocate_polled_device(); + if (!bdev || !poll_dev) { error = -ENOMEM; goto err_free_mem; } + poll_dev->private = bdev; + poll_dev->poll = handle_buttons; + poll_dev->poll_interval = BUTTONS_POLL_INTERVAL; + + input = poll_dev->input; input->name = "Cobalt buttons"; input->phys = "cobalt/input0"; input->id.bustype = BUS_HOST; input->cdev.dev = &pdev->dev; - input->open = cobalt_buttons_open; - input->close = cobalt_buttons_close; input->evbit[0] = BIT(EV_KEY); for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { @@ -130,13 +116,11 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev) goto err_free_mem; } - bdev->input = input; + bdev->poll_dev = poll_dev; bdev->reg = ioremap(res->start, res->end - res->start + 1); dev_set_drvdata(&pdev->dev, bdev); - setup_timer(&buttons_timer, handle_buttons, (unsigned long)bdev); - - error = input_register_device(input); + error = input_register_polled_device(poll_dev); if (error) goto err_iounmap; @@ -145,7 +129,7 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev) err_iounmap: iounmap(bdev->reg); err_free_mem: - input_free_device(input); + input_free_polled_device(poll_dev); kfree(bdev); dev_set_drvdata(&pdev->dev, NULL); return error; @@ -156,7 +140,8 @@ static int __devexit cobalt_buttons_remove(struct platform_device *pdev) struct device *dev = &pdev->dev; struct buttons_dev *bdev = dev_get_drvdata(dev); - input_unregister_device(bdev->input); + input_unregister_polled_device(bdev->poll_dev); + input_free_polled_device(bdev->poll_dev); iounmap(bdev->reg); kfree(bdev); dev_set_drvdata(dev, NULL); -- cgit v0.10.2 From 84767d00a8fd54dd97866561f6e2ee246c8e1cdc Mon Sep 17 00:00:00 2001 From: Roman Moravcik Date: Tue, 1 May 2007 00:39:13 -0400 Subject: Input: gpio_keys - add support for switches (EV_SW) Signed-off-by: Roman Moravcik Signed-off-by: Paul Sokolovsky Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 0d2796c..7392122 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -35,11 +35,14 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) struct input_dev *input = platform_get_drvdata(pdev); for (i = 0; i < pdata->nbuttons; i++) { - int gpio = pdata->buttons[i].gpio; + struct gpio_keys_button *button = &pdata->buttons[i]; + int gpio = button->gpio; + if (irq == gpio_to_irq(gpio)) { - int state = (gpio_get_value(gpio) ? 1 : 0) ^ (pdata->buttons[i].active_low); + unsigned int type = button->type ?: EV_KEY; + int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low; - input_report_key(input, pdata->buttons[i].keycode, state); + input_event(input, type, button->code, !!state); input_sync(input); } } @@ -71,19 +74,21 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) input->id.version = 0x0100; for (i = 0; i < pdata->nbuttons; i++) { - int code = pdata->buttons[i].keycode; - int irq = gpio_to_irq(pdata->buttons[i].gpio); + struct gpio_keys_button *button = &pdata->buttons[i]; + int irq = gpio_to_irq(button->gpio); + unsigned int type = button->type ?: EV_KEY; set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM, - pdata->buttons[i].desc ? pdata->buttons[i].desc : "gpio_keys", + button->desc ? button->desc : "gpio_keys", pdev); if (error) { printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", irq, error); goto fail; } - set_bit(code, input->keybit); + + input_set_capability(input, type, button->code); } error = input_register_device(input); diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index 2b217c7..265d178 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -3,10 +3,11 @@ struct gpio_keys_button { /* Configuration parameters */ - int keycode; + int code; /* input event code (KEY_*, SW_*) */ int gpio; int active_low; char *desc; + int type; /* input event type (EV_KEY, EV_SW) */ }; struct gpio_keys_platform_data { -- cgit v0.10.2