diff --git a/[refs] b/[refs] index 1e28d648d031..0cebdf6372a2 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 65f88f89c94d877794a6006f210d75d2974a182e +refs/heads/master: 7deeed13170e634adc4552ff94588d6301a3da83 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index bc272bf0ff97..2c1dfb271613 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1856,7 +1856,7 @@ W: http://www.openib.org/ T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git S: Supported -INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS +INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS P: Dmitry Torokhov M: dmitry.torokhov@gmail.com M: dtor@mail.ru diff --git a/trunk/drivers/char/keyboard.c b/trunk/drivers/char/keyboard.c index 90965b4def5c..1b094509b1d2 100644 --- a/trunk/drivers/char/keyboard.c +++ b/trunk/drivers/char/keyboard.c @@ -1005,8 +1005,8 @@ static const unsigned short x86_keycodes[256] = 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339, 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, - 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361, - 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114, + 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, + 291,108,381,281,290,272,292,305,280, 99,112,257,258,359,113,114, 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116, 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307, 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c index ab4b2d9b5327..be6b93c20f60 100644 --- a/trunk/drivers/input/evdev.c +++ b/trunk/drivers/input/evdev.c @@ -30,7 +30,6 @@ struct evdev { wait_queue_head_t wait; struct evdev_client *grab; struct list_head client_list; - struct device dev; }; struct evdev_client { @@ -95,10 +94,8 @@ static int evdev_flush(struct file *file, fl_owner_t id) return input_flush_device(&evdev->handle, file); } -static void evdev_free(struct device *dev) +static void evdev_free(struct evdev *evdev) { - struct evdev *evdev = container_of(dev, struct evdev, dev); - evdev_table[evdev->minor] = NULL; kfree(evdev); } @@ -117,10 +114,12 @@ static int evdev_release(struct inode *inode, struct file *file) list_del(&client->node); kfree(client); - if (!--evdev->open && evdev->exist) - input_close_device(&evdev->handle); - - put_device(&evdev->dev); + if (!--evdev->open) { + if (evdev->exist) + input_close_device(&evdev->handle); + else + evdev_free(evdev); + } return 0; } @@ -140,32 +139,24 @@ static int evdev_open(struct inode *inode, struct file *file) if (!evdev || !evdev->exist) return -ENODEV; - get_device(&evdev->dev); - client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); - if (!client) { - error = -ENOMEM; - goto err_put_evdev; - } + if (!client) + return -ENOMEM; client->evdev = evdev; list_add_tail(&client->node, &evdev->client_list); if (!evdev->open++ && evdev->exist) { error = input_open_device(&evdev->handle); - if (error) - goto err_free_client; + if (error) { + list_del(&client->node); + kfree(client); + return error; + } } file->private_data = client; return 0; - - err_free_client: - list_del(&client->node); - kfree(client); - err_put_evdev: - put_device(&evdev->dev); - return error; } #ifdef CONFIG_COMPAT @@ -634,6 +625,8 @@ 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; @@ -656,32 +649,38 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, evdev->handle.name = evdev->name; evdev->handle.handler = handler; evdev->handle.private = evdev; - snprintf(evdev->name, sizeof(evdev->name), "event%d", minor); - - snprintf(evdev->dev.bus_id, sizeof(evdev->dev.bus_id), - "event%d", minor); - evdev->dev.class = &input_class; - evdev->dev.parent = &dev->dev; - evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor); - evdev->dev.release = evdev_free; - device_initialize(&evdev->dev); + sprintf(evdev->name, "event%d", minor); evdev_table[minor] = evdev; - error = device_add(&evdev->dev); - if (error) + 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 */ + error = sysfs_create_link(&input_class.subsys.kobj, + &cdev->kobj, evdev->name); + if (error) + goto err_cdev_destroy; error = input_register_handle(&evdev->handle); if (error) - goto err_delete_evdev; + goto err_remove_link; return 0; - err_delete_evdev: - device_del(&evdev->dev); + err_remove_link: + sysfs_remove_link(&input_class.subsys.kobj, evdev->name); + err_cdev_destroy: + class_device_destroy(&input_class, devt); err_free_evdev: - put_device(&evdev->dev); + kfree(evdev); + evdev_table[minor] = NULL; return error; } @@ -691,8 +690,10 @@ static void evdev_disconnect(struct input_handle *handle) struct evdev_client *client; input_unregister_handle(handle); - device_del(&evdev->dev); + sysfs_remove_link(&input_class.subsys.kobj, evdev->name); + class_device_destroy(&input_class, + MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); evdev->exist = 0; if (evdev->open) { @@ -701,9 +702,8 @@ static void evdev_disconnect(struct input_handle *handle) list_for_each_entry(client, &evdev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); wake_up_interruptible(&evdev->wait); - } - - put_device(&evdev->dev); + } else + evdev_free(evdev); } static const struct input_device_id evdev_ids[] = { diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index 75b4d2a83dd9..ccd8abafcb70 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -442,7 +442,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han printk(KERN_ERR "input: failed to attach handler %s to device %s, " "error: %d\n", - handler->name, kobject_name(&dev->dev.kobj), error); + handler->name, kobject_name(&dev->cdev.kobj), error); return error; } @@ -527,7 +527,7 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name, static int input_devices_seq_show(struct seq_file *seq, void *v) { struct input_dev *dev = container_of(v, struct input_dev, node); - const char *path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); + const char *path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); struct input_handle *handle; seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", @@ -682,17 +682,15 @@ static inline int input_proc_init(void) { return 0; } static inline void input_proc_exit(void) { } #endif -#define INPUT_DEV_STRING_ATTR_SHOW(name) \ -static ssize_t input_dev_show_##name(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct input_dev *input_dev = to_input_dev(dev); \ - \ - return scnprintf(buf, PAGE_SIZE, "%s\n", \ - input_dev->name ? input_dev->name : ""); \ -} \ -static DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL) +#define INPUT_DEV_STRING_ATTR_SHOW(name) \ +static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \ +{ \ + struct input_dev *input_dev = to_input_dev(dev); \ + \ + return scnprintf(buf, PAGE_SIZE, "%s\n", \ + input_dev->name ? input_dev->name : ""); \ +} \ +static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL); INPUT_DEV_STRING_ATTR_SHOW(name); INPUT_DEV_STRING_ATTR_SHOW(phys); @@ -746,9 +744,7 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id, return len; } -static ssize_t input_dev_show_modalias(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) { struct input_dev *id = to_input_dev(dev); ssize_t len; @@ -757,13 +753,13 @@ static ssize_t input_dev_show_modalias(struct device *dev, return min_t(int, len, PAGE_SIZE); } -static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); +static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); static struct attribute *input_dev_attrs[] = { - &dev_attr_name.attr, - &dev_attr_phys.attr, - &dev_attr_uniq.attr, - &dev_attr_modalias.attr, + &class_device_attr_name.attr, + &class_device_attr_phys.attr, + &class_device_attr_uniq.attr, + &class_device_attr_modalias.attr, NULL }; @@ -771,15 +767,13 @@ static struct attribute_group input_dev_attr_group = { .attrs = input_dev_attrs, }; -#define INPUT_DEV_ID_ATTR(name) \ -static ssize_t input_dev_show_id_##name(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct input_dev *input_dev = to_input_dev(dev); \ - return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \ -} \ -static DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL) +#define INPUT_DEV_ID_ATTR(name) \ +static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \ +{ \ + struct input_dev *input_dev = to_input_dev(dev); \ + return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \ +} \ +static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL); INPUT_DEV_ID_ATTR(bustype); INPUT_DEV_ID_ATTR(vendor); @@ -787,10 +781,10 @@ INPUT_DEV_ID_ATTR(product); INPUT_DEV_ID_ATTR(version); static struct attribute *input_dev_id_attrs[] = { - &dev_attr_bustype.attr, - &dev_attr_vendor.attr, - &dev_attr_product.attr, - &dev_attr_version.attr, + &class_device_attr_bustype.attr, + &class_device_attr_vendor.attr, + &class_device_attr_product.attr, + &class_device_attr_version.attr, NULL }; @@ -819,17 +813,15 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, return len; } -#define INPUT_DEV_CAP_ATTR(ev, bm) \ -static ssize_t input_dev_show_cap_##bm(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct input_dev *input_dev = to_input_dev(dev); \ - int len = input_print_bitmap(buf, PAGE_SIZE, \ - input_dev->bm##bit, ev##_MAX, 1); \ - return min_t(int, len, PAGE_SIZE); \ -} \ -static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) +#define INPUT_DEV_CAP_ATTR(ev, bm) \ +static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \ +{ \ + struct input_dev *input_dev = to_input_dev(dev); \ + int len = input_print_bitmap(buf, PAGE_SIZE, \ + input_dev->bm##bit, ev##_MAX, 1); \ + return min_t(int, len, PAGE_SIZE); \ +} \ +static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL); INPUT_DEV_CAP_ATTR(EV, ev); INPUT_DEV_CAP_ATTR(KEY, key); @@ -842,15 +834,15 @@ INPUT_DEV_CAP_ATTR(FF, ff); INPUT_DEV_CAP_ATTR(SW, sw); static struct attribute *input_dev_caps_attrs[] = { - &dev_attr_ev.attr, - &dev_attr_key.attr, - &dev_attr_rel.attr, - &dev_attr_abs.attr, - &dev_attr_msc.attr, - &dev_attr_led.attr, - &dev_attr_snd.attr, - &dev_attr_ff.attr, - &dev_attr_sw.attr, + &class_device_attr_ev.attr, + &class_device_attr_key.attr, + &class_device_attr_rel.attr, + &class_device_attr_abs.attr, + &class_device_attr_msc.attr, + &class_device_attr_led.attr, + &class_device_attr_snd.attr, + &class_device_attr_ff.attr, + &class_device_attr_sw.attr, NULL }; @@ -866,9 +858,9 @@ static struct attribute_group *input_dev_attr_groups[] = { NULL }; -static void input_dev_release(struct device *device) +static void input_dev_release(struct class_device *class_dev) { - struct input_dev *dev = to_input_dev(device); + struct input_dev *dev = to_input_dev(class_dev); input_ff_destroy(dev); kfree(dev); @@ -955,10 +947,10 @@ static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_ind return err; \ } while (0) -static int input_dev_uevent(struct device *device, char **envp, +static int input_dev_uevent(struct class_device *cdev, char **envp, int num_envp, char *buffer, int buffer_size) { - struct input_dev *dev = to_input_dev(device); + struct input_dev *dev = to_input_dev(cdev); int i = 0; int len = 0; @@ -996,14 +988,10 @@ static int input_dev_uevent(struct device *device, char **envp, return 0; } -static struct device_type input_dev_type = { - .groups = input_dev_attr_groups, - .release = input_dev_release, - .uevent = input_dev_uevent, -}; - struct class input_class = { - .name = "input", + .name = "input", + .release = input_dev_release, + .uevent = input_dev_uevent, }; EXPORT_SYMBOL_GPL(input_class); @@ -1022,9 +1010,9 @@ struct input_dev *input_allocate_device(void) dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); if (dev) { - dev->dev.type = &input_dev_type; - dev->dev.class = &input_class; - device_initialize(&dev->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); INIT_LIST_HEAD(&dev->node); @@ -1143,17 +1131,17 @@ int input_register_device(struct input_dev *dev) list_add_tail(&dev->node, &input_dev_list); - snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), + 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->dev.parent = dev->cdev.dev; + if (!dev->cdev.dev) + dev->cdev.dev = dev->dev.parent; - error = device_add(&dev->dev); + error = class_device_add(&dev->cdev); if (error) return error; - path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); + 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"); kfree(path); @@ -1185,7 +1173,7 @@ void input_unregister_device(struct input_dev *dev) list_del_init(&dev->node); - device_unregister(&dev->dev); + class_device_unregister(&dev->cdev); input_wakeup_procfs_readers(); } diff --git a/trunk/drivers/input/joydev.c b/trunk/drivers/input/joydev.c index a9a0180bfd46..10e3b7bc925f 100644 --- a/trunk/drivers/input/joydev.c +++ b/trunk/drivers/input/joydev.c @@ -43,8 +43,6 @@ struct joydev { struct input_handle handle; wait_queue_head_t wait; struct list_head client_list; - struct device dev; - struct js_corr corr[ABS_MAX + 1]; struct JS_DATA_SAVE_TYPE glue; int nabs; @@ -140,10 +138,8 @@ static int joydev_fasync(int fd, struct file *file, int on) return retval < 0 ? retval : 0; } -static void joydev_free(struct device *dev) +static void joydev_free(struct joydev *joydev) { - struct joydev *joydev = container_of(dev, struct joydev, dev); - joydev_table[joydev->minor] = NULL; kfree(joydev); } @@ -158,10 +154,12 @@ static int joydev_release(struct inode *inode, struct file *file) list_del(&client->node); kfree(client); - if (!--joydev->open && joydev->exist) - input_close_device(&joydev->handle); - - put_device(&joydev->dev); + if (!--joydev->open) { + if (joydev->exist) + input_close_device(&joydev->handle); + else + joydev_free(joydev); + } return 0; } @@ -180,32 +178,24 @@ static int joydev_open(struct inode *inode, struct file *file) if (!joydev || !joydev->exist) return -ENODEV; - get_device(&joydev->dev); - client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); - if (!client) { - error = -ENOMEM; - goto err_put_joydev; - } + if (!client) + return -ENOMEM; client->joydev = joydev; list_add_tail(&client->node, &joydev->client_list); if (!joydev->open++ && joydev->exist) { error = input_open_device(&joydev->handle); - if (error) - goto err_free_client; + if (error) { + list_del(&client->node); + kfree(client); + return error; + } } file->private_data = client; return 0; - - err_free_client: - list_del(&client->node); - kfree(client); - err_put_joydev: - put_device(&joydev->dev); - return error; } static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) @@ -491,6 +481,8 @@ 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; @@ -513,7 +505,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, joydev->handle.name = joydev->name; joydev->handle.handler = handler; joydev->handle.private = joydev; - snprintf(joydev->name, sizeof(joydev->name), "js%d", minor); + sprintf(joydev->name, "js%d", minor); for (i = 0; i < ABS_MAX + 1; i++) if (test_bit(i, dev->absbit)) { @@ -555,30 +547,36 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); } - snprintf(joydev->dev.bus_id, sizeof(joydev->dev.bus_id), - "js%d", minor); - joydev->dev.class = &input_class; - joydev->dev.parent = &dev->dev; - joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor); - joydev->dev.release = joydev_free; - device_initialize(&joydev->dev); - joydev_table[minor] = joydev; - error = device_add(&joydev->dev); - if (error) + 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 */ + error = sysfs_create_link(&input_class.subsys.kobj, + &cdev->kobj, joydev->name); + if (error) + goto err_cdev_destroy; error = input_register_handle(&joydev->handle); if (error) - goto err_delete_joydev; + goto err_remove_link; return 0; - err_delete_joydev: - device_del(&joydev->dev); + err_remove_link: + sysfs_remove_link(&input_class.subsys.kobj, joydev->name); + err_cdev_destroy: + class_device_destroy(&input_class, devt); err_free_joydev: - put_device(&joydev->dev); + joydev_table[minor] = NULL; + kfree(joydev); return error; } @@ -589,8 +587,9 @@ static void joydev_disconnect(struct input_handle *handle) struct joydev_client *client; input_unregister_handle(handle); - device_del(&joydev->dev); + sysfs_remove_link(&input_class.subsys.kobj, joydev->name); + class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); joydev->exist = 0; if (joydev->open) { @@ -598,9 +597,8 @@ static void joydev_disconnect(struct input_handle *handle) list_for_each_entry(client, &joydev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); wake_up_interruptible(&joydev->wait); - } - - put_device(&joydev->dev); + } else + joydev_free(joydev); } static const struct input_device_id joydev_blacklist[] = { diff --git a/trunk/drivers/input/joystick/Kconfig b/trunk/drivers/input/joystick/Kconfig index 12db72d83ea0..b0023452ec90 100644 --- a/trunk/drivers/input/joystick/Kconfig +++ b/trunk/drivers/input/joystick/Kconfig @@ -268,11 +268,4 @@ config JOYSTICK_XPAD To compile this driver as a module, choose M here: the module will be called xpad. -config JOYSTICK_XPAD_FF - bool "X-Box gamepad rumble support" - depends on JOYSTICK_XPAD && INPUT - select INPUT_FF_MEMLESS - ---help--- - Say Y here if you want to take advantage of xbox 360 rumble features. - endif diff --git a/trunk/drivers/input/joystick/grip_mp.c b/trunk/drivers/input/joystick/grip_mp.c index 4ed3a3eadf19..555319e6378c 100644 --- a/trunk/drivers/input/joystick/grip_mp.c +++ b/trunk/drivers/input/joystick/grip_mp.c @@ -320,10 +320,10 @@ static int multiport_io(struct gameport* gameport, int sendflags, int sendcode, static int dig_mode_start(struct gameport *gameport, u32 *packet) { - int i; + int i, seq_len = sizeof(init_seq)/sizeof(int); int flags, tries = 0, bads = 0; - for (i = 0; i < ARRAY_SIZE(init_seq); i++) { /* Send magic sequence */ + for (i = 0; i < seq_len; i++) { /* Send magic sequence */ if (init_seq[i]) gameport_trigger(gameport); udelay(GRIP_INIT_DELAY); diff --git a/trunk/drivers/input/joystick/xpad.c b/trunk/drivers/input/joystick/xpad.c index 244089c52650..8c8cd95a6989 100644 --- a/trunk/drivers/input/joystick/xpad.c +++ b/trunk/drivers/input/joystick/xpad.c @@ -8,7 +8,6 @@ * Ivan Hawkes * 2005 Dominic Cerquetti * 2006 Adam Buchbinder - * 2007 Jan Kratochvil * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -29,7 +28,6 @@ * - information from http://euc.jp/periphs/xbox-controller.ja.html * - the iForce driver drivers/char/joystick/iforce.c * - the skeleton-driver drivers/usb/usb-skeleton.c - * - Xbox 360 information http://www.free60.org/wiki/Gamepad * * Thanks to: * - ITO Takayuki for providing essential xpad information on his website @@ -90,9 +88,6 @@ #define MAP_DPAD_TO_AXES 1 #define MAP_DPAD_UNKNOWN -1 -#define XTYPE_XBOX 0 -#define XTYPE_XBOX360 1 - static int dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); @@ -102,42 +97,40 @@ static const struct xpad_device { u16 idProduct; char *name; u8 dpad_mapping; - u8 xtype; } xpad_device[] = { - { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, - { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, - { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, - { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, - { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, - { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, - { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_XBOX } + { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES }, + { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES }, + { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES }, + { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES }, + { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS }, + { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES }, + { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES }, + { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES }, + { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES }, + { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES }, + { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES }, + { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES }, + { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES }, + { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES }, + { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS }, + { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES }, + { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS }, + { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, + { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, + { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES }, + { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES }, + { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES}, + { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES }, + { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES }, + { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES }, + { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES }, + { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES }, + { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES }, + { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES }, + { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS }, + { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS }, + { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES }, + { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN } }; static const signed short xpad_btn[] = { @@ -153,12 +146,6 @@ static const signed short xpad_btn_pad[] = { -1 /* terminating entry */ }; -static const signed short xpad360_btn[] = { /* buttons for x360 controller */ - BTN_TL, BTN_TR, /* Button LB/RB */ - BTN_MODE, /* The big X button */ - -1 -}; - static const signed short xpad_abs[] = { ABS_X, ABS_Y, /* left stick */ ABS_RX, ABS_RY, /* right stick */ @@ -172,12 +159,8 @@ static const signed short xpad_abs_pad[] = { -1 /* terminating entry */ }; -/* Xbox 360 has a vendor-specific (sub)class, so we cannot match it with only - * USB_INTERFACE_INFO, more to that this device has 4 InterfaceProtocols, - * but we need only one of them. */ static struct usb_device_id xpad_table [] = { { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ - { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) }, /* X-Box 360 controller */ { } }; @@ -191,16 +174,9 @@ struct usb_xpad { unsigned char *idata; /* input data */ dma_addr_t idata_dma; -#ifdef CONFIG_JOYSTICK_XPAD_FF - struct urb *irq_out; /* urb for interrupt out report */ - unsigned char *odata; /* output data */ - dma_addr_t odata_dma; -#endif - char phys[65]; /* physical device path */ int dpad_mapping; /* map d-pad to buttons or to axes */ - int xtype; /* type of xbox device */ }; /* @@ -236,8 +212,8 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ { input_report_key(dev, BTN_LEFT, data[2] & 0x04); input_report_key(dev, BTN_RIGHT, data[2] & 0x08); - input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ - input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ + input_report_key(dev, BTN_0, data[2] & 0x01); // up + input_report_key(dev, BTN_1, data[2] & 0x02); // down } /* start/back buttons and stick press left/right */ @@ -259,64 +235,6 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d input_sync(dev); } -/* - * xpad360_process_packet - * - * Completes a request by converting the data into events for the - * input subsystem. It is version for xbox 360 controller - * - * The used report descriptor was taken from: - * http://www.free60.org/wiki/Gamepad - */ - -static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) -{ - struct input_dev *dev = xpad->dev; - - /* digital pad */ - if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { - input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); - input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); - } else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) { - /* dpad as buttons (right, left, down, up) */ - input_report_key(dev, BTN_LEFT, data[2] & 0x04); - input_report_key(dev, BTN_RIGHT, data[2] & 0x08); - input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ - input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ - } - - /* start/back buttons */ - input_report_key(dev, BTN_START, data[2] & 0x10); - input_report_key(dev, BTN_BACK, data[2] & 0x20); - - /* stick press left/right */ - input_report_key(dev, BTN_THUMBL, data[2] & 0x40); - input_report_key(dev, BTN_THUMBR, data[2] & 0x80); - - /* buttons A,B,X,Y,TL,TR and MODE */ - input_report_key(dev, BTN_A, data[3] & 0x10); - input_report_key(dev, BTN_B, data[3] & 0x20); - input_report_key(dev, BTN_X, data[3] & 0x40); - input_report_key(dev, BTN_Y, data[3] & 0x80); - input_report_key(dev, BTN_TL, data[3] & 0x01); - input_report_key(dev, BTN_TR, data[3] & 0x02); - input_report_key(dev, BTN_MODE, data[3] & 0x04); - - /* left stick */ - input_report_abs(dev, ABS_X, (__s16) (((__s16)data[7] << 8) | (__s16)data[6])); - input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[9] << 8) | (__s16)data[8])); - - /* right stick */ - input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[11] << 8) | (__s16)data[10])); - input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[13] << 8) | (__s16)data[12])); - - /* triggers left/right */ - input_report_abs(dev, ABS_Z, data[4]); - input_report_abs(dev, ABS_RZ, data[5]); - - input_sync(dev); -} - static void xpad_irq_in(struct urb *urb) { struct usb_xpad *xpad = urb->context; @@ -337,10 +255,7 @@ static void xpad_irq_in(struct urb *urb) goto exit; } - if (xpad->xtype == XTYPE_XBOX360) - xpad360_process_packet(xpad, 0, xpad->idata); - else - xpad_process_packet(xpad, 0, xpad->idata); + xpad_process_packet(xpad, 0, xpad->idata); exit: retval = usb_submit_urb (urb, GFP_ATOMIC); @@ -349,114 +264,7 @@ static void xpad_irq_in(struct urb *urb) __FUNCTION__, retval); } -#ifdef CONFIG_JOYSTICK_XPAD_FF -static void xpad_irq_out(struct urb *urb) -{ - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - 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; - } - -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - err("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static int xpad_play_effect(struct input_dev *dev, void *data, - struct ff_effect *effect) -{ - struct usb_xpad *xpad = input_get_drvdata(dev); - - if (effect->type == FF_RUMBLE) { - __u16 strong = effect->u.rumble.strong_magnitude; - __u16 weak = effect->u.rumble.weak_magnitude; - xpad->odata[0] = 0x00; - xpad->odata[1] = 0x08; - xpad->odata[2] = 0x00; - xpad->odata[3] = strong / 256; - xpad->odata[4] = weak / 256; - xpad->odata[5] = 0x00; - xpad->odata[6] = 0x00; - xpad->odata[7] = 0x00; - usb_submit_urb(xpad->irq_out, GFP_KERNEL); - } - - return 0; -} - -static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) -{ - struct usb_endpoint_descriptor *ep_irq_out; - int error = -ENOMEM; - - if (xpad->xtype != XTYPE_XBOX360) - return 0; - - xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, - GFP_ATOMIC, &xpad->odata_dma ); - if (!xpad->odata) - goto fail1; - - xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); - if (!xpad->irq_out) - goto fail2; - - ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; - usb_fill_int_urb(xpad->irq_out, xpad->udev, - usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), - xpad->odata, XPAD_PKT_LEN, - xpad_irq_out, xpad, ep_irq_out->bInterval); - xpad->irq_out->transfer_dma = xpad->odata_dma; - xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); - - error = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); - if (error) - goto fail2; - - return 0; - - fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); - fail1: return error; -} - -static void xpad_stop_ff(struct usb_xpad *xpad) -{ - if (xpad->xtype == XTYPE_XBOX360) - usb_kill_urb(xpad->irq_out); -} - -static void xpad_deinit_ff(struct usb_xpad *xpad) -{ - if (xpad->xtype == XTYPE_XBOX360) { - usb_free_urb(xpad->irq_out); - usb_buffer_free(xpad->udev, XPAD_PKT_LEN, - xpad->odata, xpad->odata_dma); - } -} - -#else -static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; } -static void xpad_stop_ff(struct usb_xpad *xpad) { } -static void xpad_deinit_ff(struct usb_xpad *xpad) { } -#endif - -static int xpad_open(struct input_dev *dev) +static int xpad_open (struct input_dev *dev) { struct usb_xpad *xpad = input_get_drvdata(dev); @@ -467,12 +275,11 @@ static int xpad_open(struct input_dev *dev) return 0; } -static void xpad_close(struct input_dev *dev) +static void xpad_close (struct input_dev *dev) { struct usb_xpad *xpad = input_get_drvdata(dev); usb_kill_urb(xpad->irq_in); - xpad_stop_ff(xpad); } static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) @@ -528,7 +335,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->udev = udev; xpad->dpad_mapping = xpad_device[i].dpad_mapping; - xpad->xtype = xpad_device[i].xtype; if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) xpad->dpad_mapping = dpad_to_buttons; xpad->dev = input_dev; @@ -550,9 +356,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id /* set up buttons */ for (i = 0; xpad_btn[i] >= 0; i++) set_bit(xpad_btn[i], input_dev->keybit); - if (xpad->xtype == XTYPE_XBOX360) - for (i = 0; xpad360_btn[i] >= 0; i++) - set_bit(xpad360_btn[i], input_dev->keybit); if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) for (i = 0; xpad_btn_pad[i] >= 0; i++) set_bit(xpad_btn_pad[i], input_dev->keybit); @@ -564,10 +367,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[i]); - error = xpad_init_ff(intf, xpad); - if (error) - goto fail2; - ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), @@ -597,10 +396,10 @@ static void xpad_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (xpad) { + usb_kill_urb(xpad->irq_in); input_unregister_device(xpad->dev); - xpad_deinit_ff(xpad); usb_free_urb(xpad->irq_in); - usb_buffer_free(xpad->udev, XPAD_PKT_LEN, + usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); kfree(xpad); } diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index 41fc3d03b6eb..9950fcb33650 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -89,7 +89,7 @@ static unsigned char atkbd_set2_keycode[512] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125, 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127, - 159, 0,115, 0,164, 0, 0,116,158, 0,172,166, 0, 0, 0,142, + 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142, 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112, @@ -111,7 +111,7 @@ static unsigned char atkbd_set3_keycode[512] = { 82, 83, 80, 76, 77, 72, 69, 98, 0, 96, 81, 0, 78, 73, 55,183, 184,185,186,187, 74, 94, 92, 93, 0, 0, 0,125,126,127,112, 0, - 0,139,172,163,165,115,152,172,166,140,160,154,113,114,167,168, + 0,139,150,163,165,115,152,150,166,140,160,154,113,114,167,168, 148,149,147,140 }; diff --git a/trunk/drivers/input/keyboard/pxa27x_keyboard.c b/trunk/drivers/input/keyboard/pxa27x_keyboard.c index ebe5eacf2990..f9e82c9ca421 100644 --- a/trunk/drivers/input/keyboard/pxa27x_keyboard.c +++ b/trunk/drivers/input/keyboard/pxa27x_keyboard.c @@ -140,7 +140,7 @@ static int pxakbd_resume(struct platform_device *pdev) KPREC = pdata->reg_kprec; /* Enable unit clock */ - pxa_set_cken(CKEN_KEYPAD, 1); + pxa_set_cken(CKEN19_KEYPAD, 1); } mutex_unlock(&input_dev->mutex); diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index 9b26574f1466..88e29074ac90 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -65,13 +65,9 @@ config INPUT_COBALT_BTNS config INPUT_WISTRON_BTNS tristate "x86 Wistron laptop button interface" depends on X86 && !X86_64 - select INPUT_POLLDEV - select NEW_LEDS - select LEDS_CLASS help Say Y here for support of Winstron laptop button interface, used on - laptops of various brands, including Acer and Fujitsu-Siemens. If - available, mail and wifi leds will be controlable via /sys/class/leds. + laptops of various brands, including Acer and Fujitsu-Siemens. To compile this driver as a module, choose M here: the module will be called wistron_btns. diff --git a/trunk/drivers/input/misc/wistron_btns.c b/trunk/drivers/input/misc/wistron_btns.c index 60121f10f8d9..961aad7a0476 100644 --- a/trunk/drivers/input/misc/wistron_btns.c +++ b/trunk/drivers/input/misc/wistron_btns.c @@ -20,31 +20,37 @@ #include #include #include -#include +#include #include -#include #include #include #include #include #include +#include #include #include -#include -/* How often we poll keys - msecs */ -#define POLL_INTERVAL_DEFAULT 500 /* when idle */ -#define POLL_INTERVAL_BURST 100 /* when a key was recently pressed */ +/* + * Number of attempts to read data from queue per poll; + * the queue can hold up to 31 entries + */ +#define MAX_POLL_ITERATIONS 64 + +#define POLL_FREQUENCY 10 /* Number of polls per second */ + +#if POLL_FREQUENCY > HZ +#error "POLL_FREQUENCY too high" +#endif /* BIOS subsystem IDs */ #define WIFI 0x35 #define BLUETOOTH 0x34 -#define MAIL_LED 0x31 MODULE_AUTHOR("Miloslav Trmac "); MODULE_DESCRIPTION("Wistron laptop button driver"); MODULE_LICENSE("GPL v2"); -MODULE_VERSION("0.3"); +MODULE_VERSION("0.2"); static int force; /* = 0; */ module_param(force, bool, 0); @@ -242,10 +248,9 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; #define FE_WIFI_LED 0x02 #define FE_UNTESTED 0x80 -static struct key_entry *keymap; /* = NULL; Current key map */ +static const struct key_entry *keymap; /* = NULL; Current key map */ static int have_wifi; static int have_bluetooth; -static int have_leds; static int __init dmi_matched(struct dmi_system_id *dmi) { @@ -258,8 +263,6 @@ static int __init dmi_matched(struct dmi_system_id *dmi) else if (key->type == KE_BLUETOOTH) have_bluetooth = 1; } - have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED); - return 1; } @@ -963,163 +966,118 @@ static int __init select_keymap(void) /* Input layer interface */ -static struct input_polled_dev *wistron_idev; -static unsigned long jiffies_last_press; -static int wifi_enabled; -static int bluetooth_enabled; +static struct input_dev *input_dev; -static void report_key(struct input_dev *dev, unsigned int keycode) -{ - input_report_key(dev, keycode, 1); - input_sync(dev); - input_report_key(dev, keycode, 0); - input_sync(dev); -} - -static void report_switch(struct input_dev *dev, unsigned int code, int value) +static int __devinit setup_input_dev(void) { - input_report_switch(dev, code, value); - input_sync(dev); -} - + const struct key_entry *key; + int error; - /* led management */ -static void wistron_mail_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0); -} + input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; -/* same as setting up wifi card, but for laptops on which the led is managed */ -static void wistron_wifi_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - bios_set_state(WIFI, (value != LED_OFF) ? 1 : 0); -} + input_dev->name = "Wistron laptop buttons"; + input_dev->phys = "wistron/input0"; + input_dev->id.bustype = BUS_HOST; + input_dev->cdev.dev = &wistron_device->dev; -static struct led_classdev wistron_mail_led = { - .name = "mail:green", - .brightness_set = wistron_mail_led_set, -}; + for (key = keymap; key->type != KE_END; key++) { + switch (key->type) { + case KE_KEY: + set_bit(EV_KEY, input_dev->evbit); + set_bit(key->keycode, input_dev->keybit); + break; -static struct led_classdev wistron_wifi_led = { - .name = "wifi:red", - .brightness_set = wistron_wifi_led_set, -}; + case KE_SW: + set_bit(EV_SW, input_dev->evbit); + set_bit(key->sw.code, input_dev->swbit); + break; -static void __devinit wistron_led_init(struct device *parent) -{ - if (have_leds & FE_WIFI_LED) { - u16 wifi = bios_get_default_setting(WIFI); - if (wifi & 1) { - wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF; - if (led_classdev_register(parent, &wistron_wifi_led)) - have_leds &= ~FE_WIFI_LED; - else - bios_set_state(WIFI, wistron_wifi_led.brightness); - - } else - have_leds &= ~FE_WIFI_LED; + default: + ; + } } - if (have_leds & FE_MAIL_LED) { - /* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */ - wistron_mail_led.brightness = LED_OFF; - if (led_classdev_register(parent, &wistron_mail_led)) - have_leds &= ~FE_MAIL_LED; - else - bios_set_state(MAIL_LED, wistron_mail_led.brightness); - } -} + /* 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"); -static void __devexit wistron_led_remove(void) -{ - if (have_leds & FE_MAIL_LED) - led_classdev_unregister(&wistron_mail_led); + error = input_register_device(input_dev); + if (error) { + input_free_device(input_dev); + return error; + } - if (have_leds & FE_WIFI_LED) - led_classdev_unregister(&wistron_wifi_led); + return 0; } -static inline void wistron_led_suspend(void) +static void report_key(unsigned keycode) { - if (have_leds & FE_MAIL_LED) - led_classdev_suspend(&wistron_mail_led); - - if (have_leds & FE_WIFI_LED) - led_classdev_suspend(&wistron_wifi_led); + input_report_key(input_dev, keycode, 1); + input_sync(input_dev); + input_report_key(input_dev, keycode, 0); + input_sync(input_dev); } -static inline void wistron_led_resume(void) +static void report_switch(unsigned code, int value) { - if (have_leds & FE_MAIL_LED) - led_classdev_resume(&wistron_mail_led); - - if (have_leds & FE_WIFI_LED) - led_classdev_resume(&wistron_wifi_led); + input_report_switch(input_dev, code, value); + input_sync(input_dev); } -static struct key_entry *wistron_get_entry_by_scancode(int code) -{ - struct key_entry *key; - - for (key = keymap; key->type != KE_END; key++) - if (code == key->code) - return key; - - return NULL; -} + /* Driver core */ -static struct key_entry *wistron_get_entry_by_keycode(int keycode) -{ - struct key_entry *key; +static int wifi_enabled; +static int bluetooth_enabled; - for (key = keymap; key->type != KE_END; key++) - if (key->type == KE_KEY && keycode == key->keycode) - return key; +static void poll_bios(unsigned long); - return NULL; -} +static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0); static void handle_key(u8 code) { - const struct key_entry *key = wistron_get_entry_by_scancode(code); + const struct key_entry *key; - if (key) { - switch (key->type) { - case KE_KEY: - report_key(wistron_idev->input, key->keycode); - break; + for (key = keymap; key->type != KE_END; key++) { + if (code == key->code) { + switch (key->type) { + case KE_KEY: + report_key(key->keycode); + break; - case KE_SW: - report_switch(wistron_idev->input, - key->sw.code, key->sw.value); - break; + case KE_SW: + report_switch(key->sw.code, key->sw.value); + break; - case KE_WIFI: - if (have_wifi) { - wifi_enabled = !wifi_enabled; - bios_set_state(WIFI, wifi_enabled); - } - break; + case KE_WIFI: + if (have_wifi) { + wifi_enabled = !wifi_enabled; + bios_set_state(WIFI, wifi_enabled); + } + break; - case KE_BLUETOOTH: - if (have_bluetooth) { - bluetooth_enabled = !bluetooth_enabled; - bios_set_state(BLUETOOTH, bluetooth_enabled); - } - break; + case KE_BLUETOOTH: + if (have_bluetooth) { + bluetooth_enabled = !bluetooth_enabled; + bios_set_state(BLUETOOTH, bluetooth_enabled); + } + break; - default: - BUG(); + case KE_END: + break; + default: + BUG(); + } + return; } - jiffies_last_press = jiffies; - } else - printk(KERN_NOTICE - "wistron_btns: Unknown key code %02X\n", code); + } + printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code); } -static void poll_bios(bool discard) +static void poll_bios(unsigned long discard) { u8 qlen; u16 val; @@ -1132,118 +1090,15 @@ static void poll_bios(bool discard) if (val != 0 && !discard) handle_key((u8)val); } -} - -static void wistron_flush(struct input_polled_dev *dev) -{ - /* Flush stale event queue */ - poll_bios(true); -} - -static void wistron_poll(struct input_polled_dev *dev) -{ - poll_bios(false); - - /* Increase poll frequency if user is currently pressing keys (< 2s ago) */ - if (time_before(jiffies, jiffies_last_press + 2 * HZ)) - dev->poll_interval = POLL_INTERVAL_BURST; - else - dev->poll_interval = POLL_INTERVAL_DEFAULT; -} - -static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) -{ - const struct key_entry *key = wistron_get_entry_by_scancode(scancode); - - if (key && key->type == KE_KEY) { - *keycode = key->keycode; - return 0; - } - - return -EINVAL; -} - -static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) -{ - struct key_entry *key; - int old_keycode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - - key = wistron_get_entry_by_scancode(scancode); - if (key && key->type == KE_KEY) { - old_keycode = key->keycode; - key->keycode = keycode; - set_bit(keycode, dev->keybit); - if (!wistron_get_entry_by_keycode(old_keycode)) - clear_bit(old_keycode, dev->keybit); - return 0; - } - return -EINVAL; + mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY); } -static int __devinit setup_input_dev(void) -{ - const struct key_entry *key; - struct input_dev *input_dev; - int error; - - wistron_idev = input_allocate_polled_device(); - if (!wistron_idev) - return -ENOMEM; - - wistron_idev->flush = wistron_flush; - wistron_idev->poll = wistron_poll; - wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; - - input_dev = wistron_idev->input; - input_dev->name = "Wistron laptop buttons"; - input_dev->phys = "wistron/input0"; - input_dev->id.bustype = BUS_HOST; - input_dev->dev.parent = &wistron_device->dev; - - input_dev->getkeycode = wistron_getkeycode; - input_dev->setkeycode = wistron_setkeycode; - - for (key = keymap; key->type != KE_END; key++) { - 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: - break; - } - } - - /* 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_polled_device(wistron_idev); - if (error) { - input_free_polled_device(wistron_idev); - return error; - } - - return 0; -} - -/* Driver core */ - static int __devinit wistron_probe(struct platform_device *dev) { - int err; + int err = setup_input_dev(); + if (err) + return err; bios_attach(); cmos_address = bios_get_cmos_address(); @@ -1270,21 +1125,15 @@ static int __devinit wistron_probe(struct platform_device *dev) bios_set_state(BLUETOOTH, bluetooth_enabled); } - wistron_led_init(&dev->dev); - err = setup_input_dev(); - if (err) { - bios_detach(); - return err; - } + poll_bios(1); /* Flush stale event queue and arm timer */ return 0; } static int __devexit wistron_remove(struct platform_device *dev) { - wistron_led_remove(); - input_unregister_polled_device(wistron_idev); - input_free_polled_device(wistron_idev); + del_timer_sync(&poll_timer); + input_unregister_device(input_dev); bios_detach(); return 0; @@ -1293,13 +1142,14 @@ static int __devexit wistron_remove(struct platform_device *dev) #ifdef CONFIG_PM static int wistron_suspend(struct platform_device *dev, pm_message_t state) { + del_timer_sync(&poll_timer); + if (have_wifi) bios_set_state(WIFI, 0); if (have_bluetooth) bios_set_state(BLUETOOTH, 0); - wistron_led_suspend(); return 0; } @@ -1311,8 +1161,7 @@ static int wistron_resume(struct platform_device *dev) if (have_bluetooth) bios_set_state(BLUETOOTH, bluetooth_enabled); - wistron_led_resume(); - poll_bios(true); + poll_bios(1); return 0; } diff --git a/trunk/drivers/input/mouse/Kconfig b/trunk/drivers/input/mouse/Kconfig index 7bbea097cda2..50e06e8dd05d 100644 --- a/trunk/drivers/input/mouse/Kconfig +++ b/trunk/drivers/input/mouse/Kconfig @@ -216,20 +216,4 @@ config MOUSE_HIL help Say Y here to support HIL pointers. -config MOUSE_GPIO - tristate "GPIO mouse" - depends on GENERIC_GPIO - select INPUT_POLLDEV - help - This driver simulates a mouse on GPIO lines of various CPUs (and some - other chips). - - Say Y here if your device has buttons or a simple joystick connected - directly to GPIO lines. Your board-specific setup logic must also - provide a platform device and platform data saying which GPIOs are - used. - - To compile this driver as a module, choose M here: the - module will be called gpio_mouse. - endif diff --git a/trunk/drivers/input/mouse/Makefile b/trunk/drivers/input/mouse/Makefile index 9e6e36330820..aa4ba878533f 100644 --- a/trunk/drivers/input/mouse/Makefile +++ b/trunk/drivers/input/mouse/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_MOUSE_PS2) += psmouse.o obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o -obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o psmouse-objs := psmouse-base.o synaptics.o diff --git a/trunk/drivers/input/mouse/gpio_mouse.c b/trunk/drivers/input/mouse/gpio_mouse.c deleted file mode 100644 index 0936d6ba015c..000000000000 --- a/trunk/drivers/input/mouse/gpio_mouse.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Driver for simulating a mouse on GPIO lines. - * - * Copyright (C) 2007 Atmel Corporation - * - * 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 - -/* - * Timer function which is run every scan_ms ms when the device is opened. - * The dev input varaible is set to the the input_dev pointer. - */ -static void gpio_mouse_scan(struct input_polled_dev *dev) -{ - struct gpio_mouse_platform_data *gpio = dev->private; - struct input_dev *input = dev->input; - int x, y; - - if (gpio->bleft >= 0) - input_report_key(input, BTN_LEFT, - gpio_get_value(gpio->bleft) ^ gpio->polarity); - if (gpio->bmiddle >= 0) - input_report_key(input, BTN_MIDDLE, - gpio_get_value(gpio->bmiddle) ^ gpio->polarity); - if (gpio->bright >= 0) - input_report_key(input, BTN_RIGHT, - gpio_get_value(gpio->bright) ^ gpio->polarity); - - x = (gpio_get_value(gpio->right) ^ gpio->polarity) - - (gpio_get_value(gpio->left) ^ gpio->polarity); - y = (gpio_get_value(gpio->down) ^ gpio->polarity) - - (gpio_get_value(gpio->up) ^ gpio->polarity); - - input_report_rel(input, REL_X, x); - input_report_rel(input, REL_Y, y); - input_sync(input); -} - -static int __init gpio_mouse_probe(struct platform_device *pdev) -{ - struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data; - struct input_polled_dev *input_poll; - struct input_dev *input; - int pin, i; - int error; - - if (!pdata) { - dev_err(&pdev->dev, "no platform data\n"); - error = -ENXIO; - goto out; - } - - if (pdata->scan_ms < 0) { - dev_err(&pdev->dev, "invalid scan time\n"); - error = -EINVAL; - goto out; - } - - for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) { - pin = pdata->pins[i]; - - if (pin < 0) { - - if (i <= GPIO_MOUSE_PIN_RIGHT) { - /* Mouse direction is required. */ - dev_err(&pdev->dev, - "missing GPIO for directions\n"); - error = -EINVAL; - goto out_free_gpios; - } - - if (i == GPIO_MOUSE_PIN_BLEFT) - dev_dbg(&pdev->dev, "no left button defined\n"); - - } else { - error = gpio_request(pin, "gpio_mouse"); - if (error) { - dev_err(&pdev->dev, "fail %d pin (%d idx)\n", - pin, i); - goto out_free_gpios; - } - - gpio_direction_input(pin); - } - } - - input_poll = input_allocate_polled_device(); - if (!input_poll) { - dev_err(&pdev->dev, "not enough memory for input device\n"); - error = -ENOMEM; - goto out_free_gpios; - } - - platform_set_drvdata(pdev, input_poll); - - /* set input-polldev handlers */ - input_poll->private = pdata; - input_poll->poll = gpio_mouse_scan; - input_poll->poll_interval = pdata->scan_ms; - - input = input_poll->input; - input->name = pdev->name; - input->id.bustype = BUS_HOST; - input->dev.parent = &pdev->dev; - - input_set_capability(input, EV_REL, REL_X); - input_set_capability(input, EV_REL, REL_Y); - if (pdata->bleft >= 0) - input_set_capability(input, EV_KEY, BTN_LEFT); - if (pdata->bmiddle >= 0) - input_set_capability(input, EV_KEY, BTN_MIDDLE); - if (pdata->bright >= 0) - input_set_capability(input, EV_KEY, BTN_RIGHT); - - error = input_register_polled_device(input_poll); - if (error) { - dev_err(&pdev->dev, "could not register input device\n"); - goto out_free_polldev; - } - - dev_dbg(&pdev->dev, "%d ms scan time, buttons: %s%s%s\n", - pdata->scan_ms, - pdata->bleft < 0 ? "" : "left ", - pdata->bmiddle < 0 ? "" : "middle ", - pdata->bright < 0 ? "" : "right"); - - return 0; - - out_free_polldev: - input_free_polled_device(input_poll); - platform_set_drvdata(pdev, NULL); - - out_free_gpios: - while (--i >= 0) { - pin = pdata->pins[i]; - if (pin) - gpio_free(pin); - } - out: - return error; -} - -static int __devexit gpio_mouse_remove(struct platform_device *pdev) -{ - struct input_polled_dev *input = platform_get_drvdata(pdev); - struct gpio_mouse_platform_data *pdata = input->private; - int pin, i; - - input_unregister_polled_device(input); - input_free_polled_device(input); - - for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) { - pin = pdata->pins[i]; - if (pin >= 0) - gpio_free(pin); - } - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -struct platform_driver gpio_mouse_device_driver = { - .remove = __devexit_p(gpio_mouse_remove), - .driver = { - .name = "gpio_mouse", - } -}; - -static int __init gpio_mouse_init(void) -{ - return platform_driver_probe(&gpio_mouse_device_driver, - gpio_mouse_probe); -} -module_init(gpio_mouse_init); - -static void __exit gpio_mouse_exit(void) -{ - platform_driver_unregister(&gpio_mouse_device_driver); -} -module_exit(gpio_mouse_exit); - -MODULE_AUTHOR("Hans-Christian Egtvedt "); -MODULE_DESCRIPTION("GPIO mouse driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/mouse/psmouse-base.c b/trunk/drivers/input/mouse/psmouse-base.c index b9f0fb2530e2..f15f695777f8 100644 --- a/trunk/drivers/input/mouse/psmouse-base.c +++ b/trunk/drivers/input/mouse/psmouse-base.c @@ -177,15 +177,6 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) packet[1] |= (packet[0] & 0x40) << 1; } -/* - * Cortron PS2 Trackball reports SIDE button on the 4th bit of the first - * byte. - */ - if (psmouse->type == PSMOUSE_CORTRON) { - input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1); - packet[0] |= 0x08; - } - /* * Generic PS/2 Mouse */ @@ -548,20 +539,6 @@ static int ps2bare_detect(struct psmouse *psmouse, int set_properties) return 0; } -/* - * Cortron PS/2 protocol detection. There's no special way to detect it, so it - * must be forced by sysfs protocol writing. - */ -static int cortron_detect(struct psmouse *psmouse, int set_properties) -{ - if (set_properties) { - psmouse->vendor = "Cortron"; - psmouse->name = "PS/2 Trackball"; - set_bit(BTN_SIDE, psmouse->dev->keybit); - } - - return 0; -} /* * psmouse_extensions() probes for any extensions to the basic PS/2 protocol @@ -762,12 +739,6 @@ static const struct psmouse_protocol psmouse_protocols[] = { .detect = touchkit_ps2_detect, }, #endif - { - .type = PSMOUSE_CORTRON, - .name = "CortronPS/2", - .alias = "cortps", - .detect = cortron_detect, - }, { .type = PSMOUSE_AUTO, .name = "auto", diff --git a/trunk/drivers/input/mouse/psmouse.h b/trunk/drivers/input/mouse/psmouse.h index 27a68835b5ba..3964e8acbc54 100644 --- a/trunk/drivers/input/mouse/psmouse.h +++ b/trunk/drivers/input/mouse/psmouse.h @@ -88,7 +88,6 @@ enum psmouse_type { PSMOUSE_LIFEBOOK, PSMOUSE_TRACKPOINT, PSMOUSE_TOUCHKIT_PS2, - PSMOUSE_CORTRON, PSMOUSE_AUTO /* This one should always be last */ }; diff --git a/trunk/drivers/input/mousedev.c b/trunk/drivers/input/mousedev.c index 9173916b8be5..3f4866d8d18c 100644 --- a/trunk/drivers/input/mousedev.c +++ b/trunk/drivers/input/mousedev.c @@ -64,7 +64,6 @@ struct mousedev { wait_queue_head_t wait; struct list_head client_list; struct input_handle handle; - struct device dev; struct list_head mixdev_node; int mixdev_open; @@ -113,7 +112,7 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 }; static struct input_handler mousedev_handler; static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; -static struct mousedev *mousedev_mix; +static struct mousedev mousedev_mix; static LIST_HEAD(mousedev_mix_list); #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) @@ -219,10 +218,10 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int if (value) { set_bit(index, &mousedev->packet.buttons); - set_bit(index, &mousedev_mix->packet.buttons); + set_bit(index, &mousedev_mix.packet.buttons); } else { clear_bit(index, &mousedev->packet.buttons); - clear_bit(index, &mousedev_mix->packet.buttons); + clear_bit(index, &mousedev_mix.packet.buttons); } } @@ -288,11 +287,11 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value) * motion packet so we won't mess current position. */ set_bit(0, &mousedev->packet.buttons); - set_bit(0, &mousedev_mix->packet.buttons); - mousedev_notify_readers(mousedev, &mousedev_mix->packet); - mousedev_notify_readers(mousedev_mix, &mousedev_mix->packet); + set_bit(0, &mousedev_mix.packet.buttons); + mousedev_notify_readers(mousedev, &mousedev_mix.packet); + mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet); clear_bit(0, &mousedev->packet.buttons); - clear_bit(0, &mousedev_mix->packet.buttons); + clear_bit(0, &mousedev_mix.packet.buttons); } mousedev->touch = mousedev->pkt_count = 0; mousedev->frac_dx = 0; @@ -344,7 +343,7 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig } mousedev_notify_readers(mousedev, &mousedev->packet); - mousedev_notify_readers(mousedev_mix, &mousedev->packet); + mousedev_notify_readers(&mousedev_mix, &mousedev->packet); mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0; mousedev->packet.abs_event = 0; @@ -363,10 +362,8 @@ static int mousedev_fasync(int fd, struct file *file, int on) return retval < 0 ? retval : 0; } -static void mousedev_free(struct device *dev) +static void mousedev_free(struct mousedev *mousedev) { - struct mousedev *mousedev = container_of(dev, struct mousedev, dev); - mousedev_table[mousedev->minor] = NULL; kfree(mousedev); } @@ -375,16 +372,15 @@ static int mixdev_add_device(struct mousedev *mousedev) { int error; - if (mousedev_mix->open) { + if (mousedev_mix.open) { error = input_open_device(&mousedev->handle); if (error) return error; mousedev->open++; - mousedev->mixdev_open = 1; + mousedev->mixdev_open++; } - get_device(&mousedev->dev); list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); return 0; @@ -399,40 +395,36 @@ static void mixdev_remove_device(struct mousedev *mousedev) } list_del_init(&mousedev->mixdev_node); - put_device(&mousedev->dev); } static void mixdev_open_devices(void) { struct mousedev *mousedev; - if (mousedev_mix->open++) - return; - list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { - if (!mousedev->mixdev_open) { - if (!mousedev->open && mousedev->exist) - if (input_open_device(&mousedev->handle)) - continue; + if (mousedev->exist && !mousedev->open) { + if (input_open_device(&mousedev->handle)) + continue; mousedev->open++; - mousedev->mixdev_open = 1; + mousedev->mixdev_open++; } } } static void mixdev_close_devices(void) { - struct mousedev *mousedev; + struct mousedev *mousedev, *next; - if (--mousedev_mix->open) - return; - - list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { + list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) { if (mousedev->mixdev_open) { mousedev->mixdev_open = 0; - if (!--mousedev->open && mousedev->exist) - input_close_device(&mousedev->handle); + if (!--mousedev->open) { + if (mousedev->exist) + input_close_device(&mousedev->handle); + else + mousedev_free(mousedev); + } } } } @@ -447,12 +439,14 @@ static int mousedev_release(struct inode *inode, struct file *file) list_del(&client->node); kfree(client); - if (mousedev->minor == MOUSEDEV_MIX) - mixdev_close_devices(); - else if (!--mousedev->open && mousedev->exist) - input_close_device(&mousedev->handle); - - put_device(&mousedev->dev); + if (!--mousedev->open) { + if (mousedev->minor == MOUSEDEV_MIX) + mixdev_close_devices(); + else if (mousedev->exist) + input_close_device(&mousedev->handle); + else + mousedev_free(mousedev); + } return 0; } @@ -479,13 +473,9 @@ static int mousedev_open(struct inode *inode, struct file *file) if (!mousedev) return -ENODEV; - get_device(&mousedev->dev); - client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); - if (!client) { - error = -ENOMEM; - goto err_put_mousedev; - } + if (!client) + return -ENOMEM; spin_lock_init(&client->packet_lock); client->pos_x = xres / 2; @@ -493,23 +483,21 @@ static int mousedev_open(struct inode *inode, struct file *file) client->mousedev = mousedev; list_add_tail(&client->node, &mousedev->client_list); - if (mousedev->minor == MOUSEDEV_MIX) - mixdev_open_devices(); - else if (!mousedev->open++ && mousedev->exist) { - error = input_open_device(&mousedev->handle); - if (error) - goto err_free_client; + if (!mousedev->open++) { + 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; + } + } } file->private_data = client; return 0; - - err_free_client: - list_del(&client->node); - kfree(client); - err_put_mousedev: - put_device(&mousedev->dev); - return error; } static inline int mousedev_limit_delta(int delta, int limit) @@ -692,96 +680,57 @@ static const struct file_operations mousedev_fops = { .fasync = mousedev_fasync, }; -static struct mousedev *mousedev_create(struct input_dev *dev, - struct input_handler *handler, - int minor) +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; + dev_t devt; + int minor; int error; - mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); - if (!mousedev) { - error = -ENOMEM; - goto err_out; + 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 -ENFILE; } + mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); + if (!mousedev) + return -ENOMEM; + INIT_LIST_HEAD(&mousedev->client_list); INIT_LIST_HEAD(&mousedev->mixdev_node); init_waitqueue_head(&mousedev->wait); - if (minor == MOUSEDEV_MIX) - strlcpy(mousedev->name, "mice", sizeof(mousedev->name)); - else - snprintf(mousedev->name, sizeof(mousedev->name), - "mouse%d", minor); - mousedev->minor = minor; mousedev->exist = 1; mousedev->handle.dev = dev; mousedev->handle.name = mousedev->name; mousedev->handle.handler = handler; mousedev->handle.private = mousedev; - - strlcpy(mousedev->dev.bus_id, mousedev->name, - sizeof(mousedev->dev.bus_id)); - mousedev->dev.class = &input_class; - if (dev) - mousedev->dev.parent = &dev->dev; - mousedev->dev.devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor); - mousedev->dev.release = mousedev_free; - device_initialize(&mousedev->dev); + sprintf(mousedev->name, "mouse%d", minor); mousedev_table[minor] = mousedev; - error = device_add(&mousedev->dev); - if (error) - goto err_free_mousedev; - - return mousedev; - - err_free_mousedev: - put_device(&mousedev->dev); - err_out: - return ERR_PTR(error); -} - -static void mousedev_destroy(struct mousedev *mousedev) -{ - struct mousedev_client *client; - - device_del(&mousedev->dev); - mousedev->exist = 0; + devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), - if (mousedev->open) { - input_close_device(&mousedev->handle); - list_for_each_entry(client, &mousedev->client_list, node) - kill_fasync(&client->fasync, SIGIO, POLL_HUP); - wake_up_interruptible(&mousedev->wait); - } - - put_device(&mousedev->dev); -} - -static int mousedev_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) -{ - struct mousedev *mousedev; - 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 -ENFILE; + 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; } - mousedev = mousedev_create(dev, handler, minor); - if (IS_ERR(mousedev)) - return PTR_ERR(mousedev); + /* temporary symlink to keep userspace happy */ + error = sysfs_create_link(&input_class.subsys.kobj, + &cdev->kobj, mousedev->name); + if (error) + goto err_cdev_destroy; error = input_register_handle(&mousedev->handle); if (error) - goto err_delete_mousedev; + goto err_remove_link; error = mixdev_add_device(mousedev); if (error) @@ -791,18 +740,37 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev err_unregister_handle: input_unregister_handle(&mousedev->handle); - err_delete_mousedev: - device_unregister(&mousedev->dev); + err_remove_link: + sysfs_remove_link(&input_class.subsys.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) { struct mousedev *mousedev = handle->private; + struct mousedev_client *client; - mixdev_remove_device(mousedev); input_unregister_handle(handle); - mousedev_destroy(mousedev); + + sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); + class_device_destroy(&input_class, + MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); + mousedev->exist = 0; + + mixdev_remove_device(mousedev); + + if (mousedev->open) { + input_close_device(handle); + list_for_each_entry(client, &mousedev->client_list, node) + kill_fasync(&client->fasync, SIGIO, POLL_HUP); + wake_up_interruptible(&mousedev->wait); + } else + mousedev_free(mousedev); } static const struct input_device_id mousedev_ids[] = { @@ -854,16 +822,25 @@ static int psaux_registered; static int __init mousedev_init(void) { + struct class_device *cdev; int error; - mousedev_mix = mousedev_create(NULL, &mousedev_handler, MOUSEDEV_MIX); - if (IS_ERR(mousedev_mix)) - return PTR_ERR(mousedev_mix); - error = input_register_handler(&mousedev_handler); - if (error) { - mousedev_destroy(mousedev_mix); + if (error) return error; + + memset(&mousedev_mix, 0, sizeof(struct mousedev)); + INIT_LIST_HEAD(&mousedev_mix.client_list); + init_waitqueue_head(&mousedev_mix.wait); + mousedev_table[MOUSEDEV_MIX] = &mousedev_mix; + mousedev_mix.exist = 1; + mousedev_mix.minor = MOUSEDEV_MIX; + + cdev = class_device_create(&input_class, NULL, + MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice"); + if (IS_ERR(cdev)) { + input_unregister_handler(&mousedev_handler); + return PTR_ERR(cdev); } #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX @@ -886,8 +863,9 @@ static void __exit mousedev_exit(void) if (psaux_registered) misc_deregister(&psaux_mouse); #endif + class_device_destroy(&input_class, + MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX)); input_unregister_handler(&mousedev_handler); - mousedev_destroy(mousedev_mix); } module_init(mousedev_init); diff --git a/trunk/drivers/input/serio/serio_raw.c b/trunk/drivers/input/serio/serio_raw.c index 0403622ae267..887357666c68 100644 --- a/trunk/drivers/input/serio/serio_raw.c +++ b/trunk/drivers/input/serio/serio_raw.c @@ -160,7 +160,7 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, size_t cou { struct serio_raw_list *list = file->private_data; struct serio_raw *serio_raw = list->serio_raw; - char uninitialized_var(c); + char c; ssize_t retval = 0; if (!serio_raw->serio) diff --git a/trunk/drivers/input/tablet/aiptek.c b/trunk/drivers/input/tablet/aiptek.c index 94683f58c9e1..cc0a498763d8 100644 --- a/trunk/drivers/input/tablet/aiptek.c +++ b/trunk/drivers/input/tablet/aiptek.c @@ -82,8 +82,8 @@ /* * Version Information */ -#define DRIVER_VERSION "v2.3 (May 2, 2007)" -#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio/Cedric Brun/Rene van Paassen" +#define DRIVER_VERSION "v1.5 (May-15-2004)" +#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio" #define DRIVER_DESC "Aiptek HyperPen USB Tablet Driver (Linux 2.6.x)" /* @@ -112,7 +112,7 @@ * (returned as Report 3 - absolute coordinates from the mouse) * * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 - * byte0 0 0 0 0 0 0 1 1 + * byte0 0 0 0 0 0 0 1 0 * byte1 X7 X6 X5 X4 X3 X2 X1 X0 * byte2 X15 X14 X13 X12 X11 X10 X9 X8 * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 @@ -134,7 +134,7 @@ * (returned as Report 5 - macrokeys from the mouse) * * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 - * byte0 0 0 0 0 0 1 0 1 + * byte0 0 0 0 0 0 1 0 0 * byte1 0 0 0 BS2 BS Tip IR DV * byte2 0 0 0 0 0 0 1 0 * byte3 0 0 0 K4 K3 K2 K1 K0 @@ -218,9 +218,15 @@ #define AIPTEK_WHEEL_DISABLE (-10101) /* ToolCode values, which BTW are 0x140 .. 0x14f - * We have things set up such that if the tool button has changed, - * the tools get reset. + * We have things set up such that if TOOL_BUTTON_FIRED_BIT is + * not set, we'll send one instance of AIPTEK_TOOL_BUTTON_xxx. + * + * Whenever the user resets the value, TOOL_BUTTON_FIRED_BIT will + * get reset. */ +#define TOOL_BUTTON(x) ((x) & 0x14f) +#define TOOL_BUTTON_FIRED(x) ((x) & 0x200) +#define TOOL_BUTTON_FIRED_BIT 0x200 /* toolMode codes */ #define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN @@ -258,9 +264,9 @@ /* Mouse button programming */ -#define AIPTEK_MOUSE_LEFT_BUTTON 0x04 -#define AIPTEK_MOUSE_RIGHT_BUTTON 0x08 -#define AIPTEK_MOUSE_MIDDLE_BUTTON 0x10 +#define AIPTEK_MOUSE_LEFT_BUTTON 0x01 +#define AIPTEK_MOUSE_RIGHT_BUTTON 0x02 +#define AIPTEK_MOUSE_MIDDLE_BUTTON 0x04 /* Stylus button programming */ @@ -288,6 +294,7 @@ struct aiptek_features { int modelCode; /* Tablet model code (not unique) */ int firmwareCode; /* prom/eeprom version */ char usbPath[64 + 1]; /* device's physical usb path */ + char inputPath[64 + 1]; /* input device path */ }; struct aiptek_settings { @@ -320,32 +327,9 @@ struct aiptek { int inDelay; /* jitter: in jitter delay? */ unsigned long endDelay; /* jitter: time when delay ends */ int previousJitterable; /* jitterable prev value */ - - int lastMacro; /* macro key to reset */ - int previousToolMode; /* pen, pencil, brush, etc. tool */ unsigned char *data; /* incoming packet data */ }; -static const int eventTypes[] = { - EV_KEY, EV_ABS, EV_REL, EV_MSC, -}; - -static const int absEvents[] = { - ABS_X, ABS_Y, ABS_PRESSURE, ABS_TILT_X, ABS_TILT_Y, - ABS_WHEEL, ABS_MISC, -}; - -static const int relEvents[] = { - REL_X, REL_Y, REL_WHEEL, -}; - -static const int buttonEvents[] = { - BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, - BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH, - BTN_TOOL_BRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOUCH, - BTN_STYLUS, BTN_STYLUS2, -}; - /* * Permit easy lookup of keyboard events to send, versus * the bitmap which comes from the tablet. This hides the @@ -361,39 +345,23 @@ static const int macroKeyEvents[] = { }; /*********************************************************************** - * Map values to strings and back. Every map shoudl have the following - * as its last element: { NULL, AIPTEK_INVALID_VALUE }. + * Relative reports deliver values in 2's complement format to + * deal with negative offsets. */ -#define AIPTEK_INVALID_VALUE -1 - -struct aiptek_map { - const char *string; - int value; -}; - -static int map_str_to_val(const struct aiptek_map *map, const char *str, size_t count) -{ - const struct aiptek_map *p; - - if (str[count - 1] == '\n') - count--; - - for (p = map; p->string; p++) - if (!strncmp(str, p->string, count)) - return p->value; - - return AIPTEK_INVALID_VALUE; -} - -static const char *map_val_to_str(const struct aiptek_map *map, int val) +static int aiptek_convert_from_2s_complement(unsigned char c) { - const struct aiptek_map *p; - - for (p = map; p->value != AIPTEK_INVALID_VALUE; p++) - if (val == p->value) - return p->string; + int ret; + unsigned char b = c; + int negate = 0; - return "unknown"; + if ((b & 0x80) != 0) { + b = ~b; + b--; + negate = 1; + } + ret = b; + ret = (negate == 1) ? -ret : ret; + return ret; } /*********************************************************************** @@ -417,9 +385,6 @@ static const char *map_val_to_str(const struct aiptek_map *map, int val) * Proximity. Why two events? I thought it interesting to know if the * Proximity event occurred while the tablet was in absolute or relative * mode. - * Update: REL_MISC proved not to be such a good idea. With REL_MISC you - * get an event transmitted each time. ABS_MISC works better, since it - * can be set and re-set. Thus, only using ABS_MISC from now on. * * Other tablets use the notion of a certain minimum stylus pressure * to infer proximity. While that could have been done, that is yet @@ -476,8 +441,8 @@ static void aiptek_irq(struct urb *urb) aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE; } else { - x = (signed char) data[2]; - y = (signed char) data[3]; + x = aiptek_convert_from_2s_complement(data[2]); + y = aiptek_convert_from_2s_complement(data[3]); /* jitterable keeps track of whether any button has been pressed. * We're also using it to remap the physical mouse button mask @@ -486,20 +451,18 @@ static void aiptek_irq(struct urb *urb) * that a non-zero value indicates that one or more * mouse button was pressed.) */ - jitterable = data[1] & 0x07; + jitterable = data[5] & 0x07; - left = (data[1] & aiptek->curSetting.mouseButtonLeft >> 2) != 0 ? 1 : 0; - right = (data[1] & aiptek->curSetting.mouseButtonRight >> 2) != 0 ? 1 : 0; - middle = (data[1] & aiptek->curSetting.mouseButtonMiddle >> 2) != 0 ? 1 : 0; + left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; + right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; + middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; input_report_key(inputdev, BTN_LEFT, left); input_report_key(inputdev, BTN_MIDDLE, middle); input_report_key(inputdev, BTN_RIGHT, right); - - input_report_abs(inputdev, ABS_MISC, - 1 | AIPTEK_REPORT_TOOL_UNKNOWN); input_report_rel(inputdev, REL_X, x); input_report_rel(inputdev, REL_Y, y); + input_report_rel(inputdev, REL_MISC, 1 | AIPTEK_REPORT_TOOL_UNKNOWN); /* Wheel support is in the form of a single-event * firing. @@ -509,11 +472,6 @@ static void aiptek_irq(struct urb *urb) aiptek->curSetting.wheel); aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; } - if (aiptek->lastMacro != -1) { - input_report_key(inputdev, - macroKeyEvents[aiptek->lastMacro], 0); - aiptek->lastMacro = -1; - } input_sync(inputdev); } } @@ -531,8 +489,8 @@ static void aiptek_irq(struct urb *urb) y = le16_to_cpu(get_unaligned((__le16 *) (data + 3))); z = le16_to_cpu(get_unaligned((__le16 *) (data + 6))); - dv = (data[5] & 0x01) != 0 ? 1 : 0; - p = (data[5] & 0x02) != 0 ? 1 : 0; + p = (data[5] & 0x01) != 0 ? 1 : 0; + dv = (data[5] & 0x02) != 0 ? 1 : 0; tip = (data[5] & 0x04) != 0 ? 1 : 0; /* Use jitterable to re-arrange button masks @@ -547,18 +505,16 @@ static void aiptek_irq(struct urb *urb) * all 'bad' reports... */ if (dv != 0) { - /* If the selected tool changed, reset the old - * tool key, and set the new one. + /* If we've not already sent a tool_button_?? code, do + * so now. Then set FIRED_BIT so it won't be resent unless + * the user forces FIRED_BIT off. */ - if (aiptek->previousToolMode != - aiptek->curSetting.toolMode) { - input_report_key(inputdev, - aiptek->previousToolMode, 0); + if (TOOL_BUTTON_FIRED + (aiptek->curSetting.toolMode) == 0) { input_report_key(inputdev, - aiptek->curSetting.toolMode, + TOOL_BUTTON(aiptek->curSetting.toolMode), 1); - aiptek->previousToolMode = - aiptek->curSetting.toolMode; + aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; } if (p != 0) { @@ -594,11 +550,6 @@ static void aiptek_irq(struct urb *urb) } } input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS); - if (aiptek->lastMacro != -1) { - input_report_key(inputdev, - macroKeyEvents[aiptek->lastMacro], 0); - aiptek->lastMacro = -1; - } input_sync(inputdev); } } @@ -617,25 +568,23 @@ static void aiptek_irq(struct urb *urb) jitterable = data[5] & 0x1c; - dv = (data[5] & 0x01) != 0 ? 1 : 0; - p = (data[5] & 0x02) != 0 ? 1 : 0; + p = (data[5] & 0x01) != 0 ? 1 : 0; + dv = (data[5] & 0x02) != 0 ? 1 : 0; left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; if (dv != 0) { - /* If the selected tool changed, reset the old - * tool key, and set the new one. + /* If we've not already sent a tool_button_?? code, do + * so now. Then set FIRED_BIT so it won't be resent unless + * the user forces FIRED_BIT off. */ - if (aiptek->previousToolMode != - aiptek->curSetting.toolMode) { - input_report_key(inputdev, - aiptek->previousToolMode, 0); + if (TOOL_BUTTON_FIRED + (aiptek->curSetting.toolMode) == 0) { input_report_key(inputdev, - aiptek->curSetting.toolMode, + TOOL_BUTTON(aiptek->curSetting.toolMode), 1); - aiptek->previousToolMode = - aiptek->curSetting.toolMode; + aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; } if (p != 0) { @@ -656,12 +605,7 @@ static void aiptek_irq(struct urb *urb) aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; } } - input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_MOUSE); - if (aiptek->lastMacro != -1) { - input_report_key(inputdev, - macroKeyEvents[aiptek->lastMacro], 0); - aiptek->lastMacro = -1; - } + input_report_rel(inputdev, REL_MISC, p | AIPTEK_REPORT_TOOL_MOUSE); input_sync(inputdev); } } @@ -671,83 +615,98 @@ static void aiptek_irq(struct urb *urb) else if (data[0] == 4) { jitterable = data[1] & 0x18; - dv = (data[1] & 0x01) != 0 ? 1 : 0; - p = (data[1] & 0x02) != 0 ? 1 : 0; + p = (data[1] & 0x01) != 0 ? 1 : 0; + dv = (data[1] & 0x02) != 0 ? 1 : 0; tip = (data[1] & 0x04) != 0 ? 1 : 0; bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0; pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0; - macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1; + macro = data[3]; z = le16_to_cpu(get_unaligned((__le16 *) (data + 4))); - if (dv) { - /* If the selected tool changed, reset the old - * tool key, and set the new one. + if (dv != 0) { + /* If we've not already sent a tool_button_?? code, do + * so now. Then set FIRED_BIT so it won't be resent unless + * the user forces FIRED_BIT off. */ - if (aiptek->previousToolMode != - aiptek->curSetting.toolMode) { - input_report_key(inputdev, - aiptek->previousToolMode, 0); + if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) { input_report_key(inputdev, - aiptek->curSetting.toolMode, + TOOL_BUTTON(aiptek->curSetting.toolMode), 1); - aiptek->previousToolMode = - aiptek->curSetting.toolMode; + aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; } - } - if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) { - input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0); - aiptek->lastMacro = -1; - } + if (p != 0) { + input_report_key(inputdev, BTN_TOUCH, tip); + input_report_key(inputdev, BTN_STYLUS, bs); + input_report_key(inputdev, BTN_STYLUS2, pck); + input_report_abs(inputdev, ABS_PRESSURE, z); + } - if (macro != -1 && macro != aiptek->lastMacro) { - input_report_key(inputdev, macroKeyEvents[macro], 1); - aiptek->lastMacro = macro; + /* For safety, we're sending key 'break' codes for the + * neighboring macro keys. + */ + if (macro > 0) { + input_report_key(inputdev, + macroKeyEvents[macro - 1], 0); + } + if (macro < 25) { + input_report_key(inputdev, + macroKeyEvents[macro + 1], 0); + } + input_report_key(inputdev, macroKeyEvents[macro], p); + input_report_abs(inputdev, ABS_MISC, + p | AIPTEK_REPORT_TOOL_STYLUS); + input_sync(inputdev); } - input_report_abs(inputdev, ABS_MISC, - p | AIPTEK_REPORT_TOOL_STYLUS); - input_sync(inputdev); } /* Report 5s come from the macro keys when pressed by mouse */ else if (data[0] == 5) { jitterable = data[1] & 0x1c; - dv = (data[1] & 0x01) != 0 ? 1 : 0; - p = (data[1] & 0x02) != 0 ? 1 : 0; + p = (data[1] & 0x01) != 0 ? 1 : 0; + dv = (data[1] & 0x02) != 0 ? 1 : 0; left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; - macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0; + macro = data[3]; - if (dv) { - /* If the selected tool changed, reset the old - * tool key, and set the new one. + if (dv != 0) { + /* If we've not already sent a tool_button_?? code, do + * so now. Then set FIRED_BIT so it won't be resent unless + * the user forces FIRED_BIT off. */ - if (aiptek->previousToolMode != - aiptek->curSetting.toolMode) { - input_report_key(inputdev, - aiptek->previousToolMode, 0); - input_report_key(inputdev, - aiptek->curSetting.toolMode, 1); - aiptek->previousToolMode = aiptek->curSetting.toolMode; + if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) { + input_report_key(inputdev, + TOOL_BUTTON(aiptek->curSetting.toolMode), + 1); + aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; } - } - if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) { - input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0); - aiptek->lastMacro = -1; - } + if (p != 0) { + input_report_key(inputdev, BTN_LEFT, left); + input_report_key(inputdev, BTN_MIDDLE, middle); + input_report_key(inputdev, BTN_RIGHT, right); + } + + /* For safety, we're sending key 'break' codes for the + * neighboring macro keys. + */ + if (macro > 0) { + input_report_key(inputdev, + macroKeyEvents[macro - 1], 0); + } + if (macro < 25) { + input_report_key(inputdev, + macroKeyEvents[macro + 1], 0); + } - if (macro != -1 && macro != aiptek->lastMacro) { input_report_key(inputdev, macroKeyEvents[macro], 1); - aiptek->lastMacro = macro; + input_report_rel(inputdev, ABS_MISC, + p | AIPTEK_REPORT_TOOL_MOUSE); + input_sync(inputdev); } - - input_report_abs(inputdev, ABS_MISC, - p | AIPTEK_REPORT_TOOL_MOUSE); - input_sync(inputdev); } /* We have no idea which tool can generate a report 6. Theoretically, * neither need to, having been given reports 4 & 5 for such use. @@ -766,18 +725,15 @@ static void aiptek_irq(struct urb *urb) 0); } - /* If the selected tool changed, reset the old - tool key, and set the new one. - */ - if (aiptek->previousToolMode != - aiptek->curSetting.toolMode) { - input_report_key(inputdev, - aiptek->previousToolMode, 0); + /* If we've not already sent a tool_button_?? code, do + * so now. Then set FIRED_BIT so it won't be resent unless + * the user forces FIRED_BIT off. + */ + if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) { input_report_key(inputdev, - aiptek->curSetting.toolMode, - 1); - aiptek->previousToolMode = - aiptek->curSetting.toolMode; + TOOL_BUTTON(aiptek->curSetting. + toolMode), 1); + aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; } input_report_key(inputdev, macroKeyEvents[macro], 1); @@ -1051,6 +1007,9 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + return snprintf(buf, PAGE_SIZE, "%dx%d\n", aiptek->inputdev->absmax[ABS_X] + 1, aiptek->inputdev->absmax[ABS_Y] + 1); @@ -1064,36 +1023,118 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr */ static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL); +/*********************************************************************** + * support routines for the 'product_id' file + */ +static ssize_t show_tabletProductId(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct aiptek *aiptek = dev_get_drvdata(dev); + + if (aiptek == NULL) + return 0; + + return snprintf(buf, PAGE_SIZE, "0x%04x\n", + aiptek->inputdev->id.product); +} + +static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL); + +/*********************************************************************** + * support routines for the 'vendor_id' file + */ +static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct aiptek *aiptek = dev_get_drvdata(dev); + + if (aiptek == NULL) + return 0; + + return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor); +} + +static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL); + +/*********************************************************************** + * support routines for the 'vendor' file + */ +static ssize_t show_tabletManufacturer(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct aiptek *aiptek = dev_get_drvdata(dev); + int retval; + + if (aiptek == NULL) + return 0; + + retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->manufacturer); + return retval; +} + +static DEVICE_ATTR(vendor, S_IRUGO, show_tabletManufacturer, NULL); + +/*********************************************************************** + * support routines for the 'product' file + */ +static ssize_t show_tabletProduct(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct aiptek *aiptek = dev_get_drvdata(dev); + int retval; + + if (aiptek == NULL) + return 0; + + retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->product); + return retval; +} + +static DEVICE_ATTR(product, S_IRUGO, show_tabletProduct, NULL); + /*********************************************************************** * support routines for the 'pointer_mode' file. Note that this file * both displays current setting and allows reprogramming. */ -static struct aiptek_map pointer_mode_map[] = { - { "stylus", AIPTEK_POINTER_ONLY_STYLUS_MODE }, - { "mouse", AIPTEK_POINTER_ONLY_MOUSE_MODE }, - { "either", AIPTEK_POINTER_EITHER_MODE }, - { NULL, AIPTEK_INVALID_VALUE } -}; - static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); + char *s; + + if (aiptek == NULL) + return 0; + + switch (aiptek->curSetting.pointerMode) { + case AIPTEK_POINTER_ONLY_STYLUS_MODE: + s = "stylus"; + break; + + case AIPTEK_POINTER_ONLY_MOUSE_MODE: + s = "mouse"; + break; + + case AIPTEK_POINTER_EITHER_MODE: + s = "either"; + break; - return snprintf(buf, PAGE_SIZE, "%s\n", - map_val_to_str(pointer_mode_map, - aiptek->curSetting.pointerMode)); + default: + s = "unknown"; + break; + } + return snprintf(buf, PAGE_SIZE, "%s\n", s); } static ssize_t store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - int new_mode = map_str_to_val(pointer_mode_map, buf, count); - - if (new_mode == AIPTEK_INVALID_VALUE) - return -EINVAL; + if (aiptek == NULL) + return 0; - aiptek->newSetting.pointerMode = new_mode; + if (strcmp(buf, "stylus") == 0) { + aiptek->newSetting.pointerMode = + AIPTEK_POINTER_ONLY_STYLUS_MODE; + } else if (strcmp(buf, "mouse") == 0) { + aiptek->newSetting.pointerMode = AIPTEK_POINTER_ONLY_MOUSE_MODE; + } else if (strcmp(buf, "either") == 0) { + aiptek->newSetting.pointerMode = AIPTEK_POINTER_EITHER_MODE; + } return count; } @@ -1105,32 +1146,44 @@ static DEVICE_ATTR(pointer_mode, * support routines for the 'coordinate_mode' file. Note that this file * both displays current setting and allows reprogramming. */ - -static struct aiptek_map coordinate_mode_map[] = { - { "absolute", AIPTEK_COORDINATE_ABSOLUTE_MODE }, - { "relative", AIPTEK_COORDINATE_RELATIVE_MODE }, - { NULL, AIPTEK_INVALID_VALUE } -}; - static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); + char *s; - return snprintf(buf, PAGE_SIZE, "%s\n", - map_val_to_str(coordinate_mode_map, - aiptek->curSetting.coordinateMode)); + if (aiptek == NULL) + return 0; + + switch (aiptek->curSetting.coordinateMode) { + case AIPTEK_COORDINATE_ABSOLUTE_MODE: + s = "absolute"; + break; + + case AIPTEK_COORDINATE_RELATIVE_MODE: + s = "relative"; + break; + + default: + s = "unknown"; + break; + } + return snprintf(buf, PAGE_SIZE, "%s\n", s); } static ssize_t store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - int new_mode = map_str_to_val(coordinate_mode_map, buf, count); - - if (new_mode == AIPTEK_INVALID_VALUE) - return -EINVAL; + if (aiptek == NULL) + return 0; - aiptek->newSetting.coordinateMode = new_mode; + if (strcmp(buf, "absolute") == 0) { + aiptek->newSetting.pointerMode = + AIPTEK_COORDINATE_ABSOLUTE_MODE; + } else if (strcmp(buf, "relative") == 0) { + aiptek->newSetting.pointerMode = + AIPTEK_COORDINATE_RELATIVE_MODE; + } return count; } @@ -1142,37 +1195,73 @@ static DEVICE_ATTR(coordinate_mode, * support routines for the 'tool_mode' file. Note that this file * both displays current setting and allows reprogramming. */ - -static struct aiptek_map tool_mode_map[] = { - { "mouse", AIPTEK_TOOL_BUTTON_MOUSE_MODE }, - { "eraser", AIPTEK_TOOL_BUTTON_ERASER_MODE }, - { "pencil", AIPTEK_TOOL_BUTTON_PENCIL_MODE }, - { "pen", AIPTEK_TOOL_BUTTON_PEN_MODE }, - { "brush", AIPTEK_TOOL_BUTTON_BRUSH_MODE }, - { "airbrush", AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE }, - { "lens", AIPTEK_TOOL_BUTTON_LENS_MODE }, - { NULL, AIPTEK_INVALID_VALUE } -}; - static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); + char *s; + + if (aiptek == NULL) + return 0; + + switch (TOOL_BUTTON(aiptek->curSetting.toolMode)) { + case AIPTEK_TOOL_BUTTON_MOUSE_MODE: + s = "mouse"; + break; + + case AIPTEK_TOOL_BUTTON_ERASER_MODE: + s = "eraser"; + break; + + case AIPTEK_TOOL_BUTTON_PENCIL_MODE: + s = "pencil"; + break; + + case AIPTEK_TOOL_BUTTON_PEN_MODE: + s = "pen"; + break; + + case AIPTEK_TOOL_BUTTON_BRUSH_MODE: + s = "brush"; + break; + + case AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE: + s = "airbrush"; + break; + + case AIPTEK_TOOL_BUTTON_LENS_MODE: + s = "lens"; + break; - return snprintf(buf, PAGE_SIZE, "%s\n", - map_val_to_str(tool_mode_map, - aiptek->curSetting.toolMode)); + default: + s = "unknown"; + break; + } + return snprintf(buf, PAGE_SIZE, "%s\n", s); } static ssize_t store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - int new_mode = map_str_to_val(tool_mode_map, buf, count); + if (aiptek == NULL) + return 0; - if (new_mode == AIPTEK_INVALID_VALUE) - return -EINVAL; + if (strcmp(buf, "mouse") == 0) { + aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_MOUSE_MODE; + } else if (strcmp(buf, "eraser") == 0) { + aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_ERASER_MODE; + } else if (strcmp(buf, "pencil") == 0) { + aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PENCIL_MODE; + } else if (strcmp(buf, "pen") == 0) { + aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PEN_MODE; + } else if (strcmp(buf, "brush") == 0) { + aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_BRUSH_MODE; + } else if (strcmp(buf, "airbrush") == 0) { + aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE; + } else if (strcmp(buf, "lens") == 0) { + aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_LENS_MODE; + } - aiptek->newSetting.toolMode = new_mode; return count; } @@ -1188,6 +1277,9 @@ static ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *att { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + if (aiptek->curSetting.xTilt == AIPTEK_TILT_DISABLE) { return snprintf(buf, PAGE_SIZE, "disable\n"); } else { @@ -1202,6 +1294,9 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char struct aiptek *aiptek = dev_get_drvdata(dev); int x; + if (aiptek == NULL) + return 0; + if (strcmp(buf, "disable") == 0) { aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE; } else { @@ -1224,6 +1319,9 @@ static ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *att { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + if (aiptek->curSetting.yTilt == AIPTEK_TILT_DISABLE) { return snprintf(buf, PAGE_SIZE, "disable\n"); } else { @@ -1238,6 +1336,9 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char struct aiptek *aiptek = dev_get_drvdata(dev); int y; + if (aiptek == NULL) + return 0; + if (strcmp(buf, "disable") == 0) { aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE; } else { @@ -1260,6 +1361,9 @@ static ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribut { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.jitterDelay); } @@ -1268,6 +1372,9 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10); return count; } @@ -1284,6 +1391,9 @@ static ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_at { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.programmableDelay); } @@ -1293,6 +1403,9 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10); return count; } @@ -1301,6 +1414,23 @@ static DEVICE_ATTR(delay, S_IRUGO | S_IWUGO, show_tabletProgrammableDelay, store_tabletProgrammableDelay); +/*********************************************************************** + * support routines for the 'input_path' file. Note that this file + * only displays current setting. + */ +static ssize_t show_tabletInputDevice(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct aiptek *aiptek = dev_get_drvdata(dev); + + if (aiptek == NULL) + return 0; + + return snprintf(buf, PAGE_SIZE, "/dev/input/%s\n", + aiptek->features.inputPath); +} + +static DEVICE_ATTR(input_path, S_IRUGO, show_tabletInputDevice, NULL); + /*********************************************************************** * support routines for the 'event_count' file. Note that this file * only displays current setting. @@ -1309,6 +1439,9 @@ static ssize_t show_tabletEventsReceived(struct device *dev, struct device_attri { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + return snprintf(buf, PAGE_SIZE, "%ld\n", aiptek->eventCount); } @@ -1323,6 +1456,9 @@ static ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_at struct aiptek *aiptek = dev_get_drvdata(dev); char *retMsg; + if (aiptek == NULL) + return 0; + switch (aiptek->diagnostic) { case AIPTEK_DIAGNOSTIC_NA: retMsg = "no errors\n"; @@ -1357,32 +1493,45 @@ static DEVICE_ATTR(diagnostic, S_IRUGO, show_tabletDiagnosticMessage, NULL); * support routines for the 'stylus_upper' file. Note that this file * both displays current setting and allows for setting changing. */ - -static struct aiptek_map stylus_button_map[] = { - { "upper", AIPTEK_STYLUS_UPPER_BUTTON }, - { "lower", AIPTEK_STYLUS_LOWER_BUTTON }, - { NULL, AIPTEK_INVALID_VALUE } -}; - static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); + char *s; + + if (aiptek == NULL) + return 0; + + switch (aiptek->curSetting.stylusButtonUpper) { + case AIPTEK_STYLUS_UPPER_BUTTON: + s = "upper"; + break; + + case AIPTEK_STYLUS_LOWER_BUTTON: + s = "lower"; + break; - return snprintf(buf, PAGE_SIZE, "%s\n", - map_val_to_str(stylus_button_map, - aiptek->curSetting.stylusButtonUpper)); + default: + s = "unknown"; + break; + } + return snprintf(buf, PAGE_SIZE, "%s\n", s); } static ssize_t store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - int new_button = map_str_to_val(stylus_button_map, buf, count); - if (new_button == AIPTEK_INVALID_VALUE) - return -EINVAL; + if (aiptek == NULL) + return 0; - aiptek->newSetting.stylusButtonUpper = new_button; + if (strcmp(buf, "upper") == 0) { + aiptek->newSetting.stylusButtonUpper = + AIPTEK_STYLUS_UPPER_BUTTON; + } else if (strcmp(buf, "lower") == 0) { + aiptek->newSetting.stylusButtonUpper = + AIPTEK_STYLUS_LOWER_BUTTON; + } return count; } @@ -1394,26 +1543,45 @@ static DEVICE_ATTR(stylus_upper, * support routines for the 'stylus_lower' file. Note that this file * both displays current setting and allows for setting changing. */ - static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); + char *s; + + if (aiptek == NULL) + return 0; + + switch (aiptek->curSetting.stylusButtonLower) { + case AIPTEK_STYLUS_UPPER_BUTTON: + s = "upper"; + break; + + case AIPTEK_STYLUS_LOWER_BUTTON: + s = "lower"; + break; - return snprintf(buf, PAGE_SIZE, "%s\n", - map_val_to_str(stylus_button_map, - aiptek->curSetting.stylusButtonLower)); + default: + s = "unknown"; + break; + } + return snprintf(buf, PAGE_SIZE, "%s\n", s); } static ssize_t store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - int new_button = map_str_to_val(stylus_button_map, buf, count); - if (new_button == AIPTEK_INVALID_VALUE) - return -EINVAL; + if (aiptek == NULL) + return 0; - aiptek->newSetting.stylusButtonLower = new_button; + if (strcmp(buf, "upper") == 0) { + aiptek->newSetting.stylusButtonLower = + AIPTEK_STYLUS_UPPER_BUTTON; + } else if (strcmp(buf, "lower") == 0) { + aiptek->newSetting.stylusButtonLower = + AIPTEK_STYLUS_LOWER_BUTTON; + } return count; } @@ -1425,33 +1593,49 @@ static DEVICE_ATTR(stylus_lower, * support routines for the 'mouse_left' file. Note that this file * both displays current setting and allows for setting changing. */ - -static struct aiptek_map mouse_button_map[] = { - { "left", AIPTEK_MOUSE_LEFT_BUTTON }, - { "middle", AIPTEK_MOUSE_MIDDLE_BUTTON }, - { "right", AIPTEK_MOUSE_RIGHT_BUTTON }, - { NULL, AIPTEK_INVALID_VALUE } -}; - static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); + char *s; + + if (aiptek == NULL) + return 0; + + switch (aiptek->curSetting.mouseButtonLeft) { + case AIPTEK_MOUSE_LEFT_BUTTON: + s = "left"; + break; + + case AIPTEK_MOUSE_MIDDLE_BUTTON: + s = "middle"; + break; + + case AIPTEK_MOUSE_RIGHT_BUTTON: + s = "right"; + break; - return snprintf(buf, PAGE_SIZE, "%s\n", - map_val_to_str(mouse_button_map, - aiptek->curSetting.mouseButtonLeft)); + default: + s = "unknown"; + break; + } + return snprintf(buf, PAGE_SIZE, "%s\n", s); } static ssize_t store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - int new_button = map_str_to_val(mouse_button_map, buf, count); - if (new_button == AIPTEK_INVALID_VALUE) - return -EINVAL; + if (aiptek == NULL) + return 0; - aiptek->newSetting.mouseButtonLeft = new_button; + if (strcmp(buf, "left") == 0) { + aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON; + } else if (strcmp(buf, "middle") == 0) { + aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_MIDDLE_BUTTON; + } else if (strcmp(buf, "right") == 0) { + aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_RIGHT_BUTTON; + } return count; } @@ -1466,22 +1650,48 @@ static DEVICE_ATTR(mouse_left, static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); + char *s; - return snprintf(buf, PAGE_SIZE, "%s\n", - map_val_to_str(mouse_button_map, - aiptek->curSetting.mouseButtonMiddle)); + if (aiptek == NULL) + return 0; + + switch (aiptek->curSetting.mouseButtonMiddle) { + case AIPTEK_MOUSE_LEFT_BUTTON: + s = "left"; + break; + + case AIPTEK_MOUSE_MIDDLE_BUTTON: + s = "middle"; + break; + + case AIPTEK_MOUSE_RIGHT_BUTTON: + s = "right"; + break; + + default: + s = "unknown"; + break; + } + return snprintf(buf, PAGE_SIZE, "%s\n", s); } static ssize_t store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - int new_button = map_str_to_val(mouse_button_map, buf, count); - if (new_button == AIPTEK_INVALID_VALUE) - return -EINVAL; + if (aiptek == NULL) + return 0; - aiptek->newSetting.mouseButtonMiddle = new_button; + if (strcmp(buf, "left") == 0) { + aiptek->newSetting.mouseButtonMiddle = AIPTEK_MOUSE_LEFT_BUTTON; + } else if (strcmp(buf, "middle") == 0) { + aiptek->newSetting.mouseButtonMiddle = + AIPTEK_MOUSE_MIDDLE_BUTTON; + } else if (strcmp(buf, "right") == 0) { + aiptek->newSetting.mouseButtonMiddle = + AIPTEK_MOUSE_RIGHT_BUTTON; + } return count; } @@ -1496,22 +1706,47 @@ static DEVICE_ATTR(mouse_middle, static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); + char *s; + + if (aiptek == NULL) + return 0; + + switch (aiptek->curSetting.mouseButtonRight) { + case AIPTEK_MOUSE_LEFT_BUTTON: + s = "left"; + break; + + case AIPTEK_MOUSE_MIDDLE_BUTTON: + s = "middle"; + break; - return snprintf(buf, PAGE_SIZE, "%s\n", - map_val_to_str(mouse_button_map, - aiptek->curSetting.mouseButtonRight)); + case AIPTEK_MOUSE_RIGHT_BUTTON: + s = "right"; + break; + + default: + s = "unknown"; + break; + } + return snprintf(buf, PAGE_SIZE, "%s\n", s); } static ssize_t store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - int new_button = map_str_to_val(mouse_button_map, buf, count); - if (new_button == AIPTEK_INVALID_VALUE) - return -EINVAL; + if (aiptek == NULL) + return 0; - aiptek->newSetting.mouseButtonRight = new_button; + if (strcmp(buf, "left") == 0) { + aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_LEFT_BUTTON; + } else if (strcmp(buf, "middle") == 0) { + aiptek->newSetting.mouseButtonRight = + AIPTEK_MOUSE_MIDDLE_BUTTON; + } else if (strcmp(buf, "right") == 0) { + aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON; + } return count; } @@ -1527,6 +1762,9 @@ static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *att { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + if (aiptek->curSetting.wheel == AIPTEK_WHEEL_DISABLE) { return snprintf(buf, PAGE_SIZE, "disable\n"); } else { @@ -1540,6 +1778,9 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10); return count; } @@ -1553,6 +1794,11 @@ static DEVICE_ATTR(wheel, */ static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf) { + struct aiptek *aiptek = dev_get_drvdata(dev); + + if (aiptek == NULL) + return 0; + /* There is nothing useful to display, so a one-line manual * is in order... */ @@ -1565,6 +1811,9 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + /* We do not care what you write to this file. Merely the action * of writing to this file triggers a tablet reprogramming. */ @@ -1588,6 +1837,9 @@ static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *a { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.odmCode); } @@ -1601,6 +1853,9 @@ static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.modelCode); } @@ -1614,39 +1869,86 @@ static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *at { struct aiptek *aiptek = dev_get_drvdata(dev); + if (aiptek == NULL) + return 0; + return snprintf(buf, PAGE_SIZE, "%04x\n", aiptek->features.firmwareCode); } static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL); -static struct attribute *aiptek_attributes[] = { - &dev_attr_size.attr, - &dev_attr_pointer_mode.attr, - &dev_attr_coordinate_mode.attr, - &dev_attr_tool_mode.attr, - &dev_attr_xtilt.attr, - &dev_attr_ytilt.attr, - &dev_attr_jitter.attr, - &dev_attr_delay.attr, - &dev_attr_event_count.attr, - &dev_attr_diagnostic.attr, - &dev_attr_odm_code.attr, - &dev_attr_model_code.attr, - &dev_attr_firmware_code.attr, - &dev_attr_stylus_lower.attr, - &dev_attr_stylus_upper.attr, - &dev_attr_mouse_left.attr, - &dev_attr_mouse_middle.attr, - &dev_attr_mouse_right.attr, - &dev_attr_wheel.attr, - &dev_attr_execute.attr, - NULL -}; +/*********************************************************************** + * This routine removes all existing sysfs files managed by this device + * driver. + */ +static void aiptek_delete_files(struct device *dev) +{ + device_remove_file(dev, &dev_attr_size); + device_remove_file(dev, &dev_attr_product_id); + device_remove_file(dev, &dev_attr_vendor_id); + device_remove_file(dev, &dev_attr_vendor); + device_remove_file(dev, &dev_attr_product); + device_remove_file(dev, &dev_attr_pointer_mode); + device_remove_file(dev, &dev_attr_coordinate_mode); + device_remove_file(dev, &dev_attr_tool_mode); + device_remove_file(dev, &dev_attr_xtilt); + device_remove_file(dev, &dev_attr_ytilt); + device_remove_file(dev, &dev_attr_jitter); + device_remove_file(dev, &dev_attr_delay); + device_remove_file(dev, &dev_attr_input_path); + device_remove_file(dev, &dev_attr_event_count); + device_remove_file(dev, &dev_attr_diagnostic); + device_remove_file(dev, &dev_attr_odm_code); + device_remove_file(dev, &dev_attr_model_code); + device_remove_file(dev, &dev_attr_firmware_code); + device_remove_file(dev, &dev_attr_stylus_lower); + device_remove_file(dev, &dev_attr_stylus_upper); + device_remove_file(dev, &dev_attr_mouse_left); + device_remove_file(dev, &dev_attr_mouse_middle); + device_remove_file(dev, &dev_attr_mouse_right); + device_remove_file(dev, &dev_attr_wheel); + device_remove_file(dev, &dev_attr_execute); +} -static struct attribute_group aiptek_attribute_group = { - .attrs = aiptek_attributes, -}; +/*********************************************************************** + * This routine creates the sysfs files managed by this device + * driver. + */ +static int aiptek_add_files(struct device *dev) +{ + int ret; + + if ((ret = device_create_file(dev, &dev_attr_size)) || + (ret = device_create_file(dev, &dev_attr_product_id)) || + (ret = device_create_file(dev, &dev_attr_vendor_id)) || + (ret = device_create_file(dev, &dev_attr_vendor)) || + (ret = device_create_file(dev, &dev_attr_product)) || + (ret = device_create_file(dev, &dev_attr_pointer_mode)) || + (ret = device_create_file(dev, &dev_attr_coordinate_mode)) || + (ret = device_create_file(dev, &dev_attr_tool_mode)) || + (ret = device_create_file(dev, &dev_attr_xtilt)) || + (ret = device_create_file(dev, &dev_attr_ytilt)) || + (ret = device_create_file(dev, &dev_attr_jitter)) || + (ret = device_create_file(dev, &dev_attr_delay)) || + (ret = device_create_file(dev, &dev_attr_input_path)) || + (ret = device_create_file(dev, &dev_attr_event_count)) || + (ret = device_create_file(dev, &dev_attr_diagnostic)) || + (ret = device_create_file(dev, &dev_attr_odm_code)) || + (ret = device_create_file(dev, &dev_attr_model_code)) || + (ret = device_create_file(dev, &dev_attr_firmware_code)) || + (ret = device_create_file(dev, &dev_attr_stylus_lower)) || + (ret = device_create_file(dev, &dev_attr_stylus_upper)) || + (ret = device_create_file(dev, &dev_attr_mouse_left)) || + (ret = device_create_file(dev, &dev_attr_mouse_middle)) || + (ret = device_create_file(dev, &dev_attr_mouse_right)) || + (ret = device_create_file(dev, &dev_attr_wheel)) || + (ret = device_create_file(dev, &dev_attr_execute))) { + err("aiptek: killing own sysfs device files\n"); + aiptek_delete_files(dev); + } + return ret; +} /*********************************************************************** * This routine is called when a tablet has been identified. It basically @@ -1659,6 +1961,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) struct usb_endpoint_descriptor *endpoint; struct aiptek *aiptek; struct input_dev *inputdev; + struct input_handle *inputhandle; + struct list_head *node, *next; int i; int speeds[] = { 0, AIPTEK_PROGRAMMABLE_DELAY_50, @@ -1680,23 +1984,17 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL); inputdev = input_allocate_device(); - if (!aiptek || !inputdev) { - warn("aiptek: cannot allocate memory or input device"); + if (!aiptek || !inputdev) goto fail1; - } aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH, GFP_ATOMIC, &aiptek->data_dma); - if (!aiptek->data) { - warn("aiptek: cannot allocate usb buffer"); + if (!aiptek->data) goto fail1; - } aiptek->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!aiptek->urb) { - warn("aiptek: cannot allocate urb"); + if (!aiptek->urb) goto fail2; - } aiptek->inputdev = inputdev; aiptek->usbdev = usbdev; @@ -1704,7 +2002,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) aiptek->inDelay = 0; aiptek->endDelay = 0; aiptek->previousJitterable = 0; - aiptek->lastMacro = -1; /* Set up the curSettings struct. Said struct contains the current * programmable parameters. The newSetting struct contains changes @@ -1757,23 +2054,36 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Now program the capacities of the tablet, in terms of being * an input device. */ - for (i = 0; i < ARRAY_SIZE(eventTypes); ++i) - __set_bit(eventTypes[i], inputdev->evbit); + inputdev->evbit[0] |= BIT(EV_KEY) + | BIT(EV_ABS) + | BIT(EV_REL) + | BIT(EV_MSC); + + inputdev->absbit[0] |= BIT(ABS_MISC); - for (i = 0; i < ARRAY_SIZE(absEvents); ++i) - __set_bit(absEvents[i], inputdev->absbit); + inputdev->relbit[0] |= + (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC)); - for (i = 0; i < ARRAY_SIZE(relEvents); ++i) - __set_bit(relEvents[i], inputdev->relbit); + inputdev->keybit[LONG(BTN_LEFT)] |= + (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE)); - __set_bit(MSC_SERIAL, inputdev->mscbit); + inputdev->keybit[LONG(BTN_DIGI)] |= + (BIT(BTN_TOOL_PEN) | + BIT(BTN_TOOL_RUBBER) | + BIT(BTN_TOOL_PENCIL) | + BIT(BTN_TOOL_AIRBRUSH) | + BIT(BTN_TOOL_BRUSH) | + BIT(BTN_TOOL_MOUSE) | + BIT(BTN_TOOL_LENS) | + BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2)); - /* Set up key and button codes */ - for (i = 0; i < ARRAY_SIZE(buttonEvents); ++i) - __set_bit(buttonEvents[i], inputdev->keybit); + inputdev->mscbit[0] = BIT(MSC_SERIAL); + /* Programming the tablet macro keys needs to be done with a for loop + * as the keycodes are discontiguous. + */ for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i) - __set_bit(macroKeyEvents[i], inputdev->keybit); + set_bit(macroKeyEvents[i], inputdev->keybit); /* * Program the input device coordinate capacities. We do not yet @@ -1824,11 +2134,25 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) } } - /* Murphy says that some day someone will have a tablet that fails the - above test. That's you, Frederic Rodrigo */ - if (i == ARRAY_SIZE(speeds)) { - info("input: Aiptek tried all speeds, no sane response"); + /* Register the tablet as an Input Device + */ + 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 + * input_handles associated with this input device. + * What identifies an evdev input_handler is that it begins + * with 'event', continues with a digit, and that in turn + * is mapped to input/eventN. + */ + list_for_each_safe(node, next, &inputdev->h_list) { + inputhandle = to_handle(node); + if (strncmp(inputhandle->name, "event", 5) == 0) { + strcpy(aiptek->features.inputPath, inputhandle->name); + break; + } } /* Associate this driver's struct with the usb interface. @@ -1837,27 +2161,18 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Set up the sysfs files */ - err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group); - if (err) { - warn("aiptek: cannot create sysfs group err: %d", err); - goto fail3; - } + aiptek_add_files(&intf->dev); - /* Register the tablet as an Input Device + /* Make sure the evdev module is loaded. Assuming evdev IS a module :-) */ - err = input_register_device(aiptek->inputdev); - if (err) { - warn("aiptek: input_register_device returned err: %d", err); - goto fail4; - } + if (request_module("evdev") != 0) + info("aiptek: error loading 'evdev' module"); + return 0; - fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); - fail3: usb_free_urb(aiptek->urb); fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, aiptek->data_dma); - fail1: usb_set_intfdata(intf, NULL); - input_free_device(inputdev); + fail1: input_free_device(inputdev); kfree(aiptek); return err; } @@ -1877,7 +2192,7 @@ static void aiptek_disconnect(struct usb_interface *intf) */ usb_kill_urb(aiptek->urb); input_unregister_device(aiptek->inputdev); - sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); + aiptek_delete_files(&intf->dev); usb_free_urb(aiptek->urb); usb_buffer_free(interface_to_usbdev(intf), AIPTEK_PACKET_LENGTH, diff --git a/trunk/drivers/input/tablet/wacom.h b/trunk/drivers/input/tablet/wacom.h index 6542edb6f76e..ef01a807ec0f 100644 --- a/trunk/drivers/input/tablet/wacom.h +++ b/trunk/drivers/input/tablet/wacom.h @@ -11,7 +11,7 @@ * Copyright (c) 2000 Daniel Egger * Copyright (c) 2001 Frederic Lepied * Copyright (c) 2004 Panagiotis Issaris - * Copyright (c) 2002-2007 Ping Cheng + * Copyright (c) 2002-2006 Ping Cheng * * ChangeLog: * v0.1 (vp) - Initial release @@ -62,9 +62,8 @@ * - Minor data report fix * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, * - where wacom_sys.c deals with system specific code, - * - and wacom_wac.c deals with Wacom specific code + * - and wacom_wac.c deals with Wacom specific code * - Support Intuos3 4x6 - * v1.47 (pc) - Added support for Bamboo */ /* @@ -85,7 +84,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.47" +#define DRIVER_VERSION "v1.46" #define DRIVER_AUTHOR "Vojtech Pavlik " #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" #define DRIVER_LICENSE "GPL" @@ -124,7 +123,6 @@ extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wa extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern __u16 wacom_le16_to_cpu(unsigned char *data); extern __u16 wacom_be16_to_cpu(unsigned char *data); extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); diff --git a/trunk/drivers/input/tablet/wacom_sys.c b/trunk/drivers/input/tablet/wacom_sys.c index 064e123c9b76..83bddef66067 100644 --- a/trunk/drivers/input/tablet/wacom_sys.c +++ b/trunk/drivers/input/tablet/wacom_sys.c @@ -138,12 +138,6 @@ static void wacom_close(struct input_dev *dev) usb_kill_urb(wacom->irq); } -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { input_dev->evbit[0] |= BIT(EV_MSC); diff --git a/trunk/drivers/input/tablet/wacom_wac.c b/trunk/drivers/input/tablet/wacom_wac.c index fc03ba256f4c..7661f03a2db2 100644 --- a/trunk/drivers/input/tablet/wacom_wac.c +++ b/trunk/drivers/input/tablet/wacom_wac.c @@ -178,8 +178,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) case 2: /* Mouse with wheel */ wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); - if (wacom->features->type == WACOM_G4 || - wacom->features->type == WACOM_MO) { + if (wacom->features->type == WACOM_G4) { rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); wacom_report_rel(wcombo, REL_WHEEL, -rw); } else @@ -191,8 +190,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) id = CURSOR_DEVICE_ID; wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); - if (wacom->features->type == WACOM_G4 || - wacom->features->type == WACOM_MO) + if (wacom->features->type == WACOM_G4) wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); else wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); @@ -228,8 +226,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) } /* send pad data */ - switch (wacom->features->type) { - case WACOM_G4: + if (wacom->features->type == WACOM_G4) { if (data[7] & 0xf8) { wacom_input_sync(wcombo); /* sync last event */ wacom->id[1] = 1; @@ -250,33 +247,6 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_abs(wcombo, ABS_MISC, 0); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } - break; - case WACOM_MO: - if ((data[7] & 0xf8) || (data[8] & 0x80)) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = 1; - wacom->serial[1] = (data[7] & 0xf8); - wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); - wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); - wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); - wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); - wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); - wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } - break; } return 1; } @@ -361,7 +331,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_EXTRA, 0); wacom_report_abs(wcombo, ABS_THROTTLE, 0); wacom_report_abs(wcombo, ABS_RZ, 0); - } else { + } else { wacom_report_abs(wcombo, ABS_PRESSURE, 0); wacom_report_abs(wcombo, ABS_TILT_X, 0); wacom_report_abs(wcombo, ABS_TILT_Y, 0); @@ -453,9 +423,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) return result-1; /* Only large I3 and I1 & I2 support Lense Cursor */ - if ((wacom->tool[idx] == BTN_TOOL_LENS) + if((wacom->tool[idx] == BTN_TOOL_LENS) && ((wacom->features->type == INTUOS3) - || (wacom->features->type == INTUOS3S))) + || (wacom->features->type == INTUOS3S))) return 0; /* Cintiq doesn't send data when RDY bit isn't set */ @@ -547,7 +517,6 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) break; case WACOM_G4: case GRAPHIRE: - case WACOM_MO: return (wacom_graphire_irq(wacom_wac, wcombo)); break; case PTU: @@ -569,8 +538,6 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { switch (wacom_wac->features->type) { - case WACOM_MO: - input_dev_mo(input_dev, wacom_wac); case WACOM_G4: input_dev_g4(input_dev, wacom_wac); /* fall through */ @@ -612,7 +579,6 @@ static struct wacom_features wacom_features[] = { { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE }, - { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO }, { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, @@ -661,7 +627,6 @@ static struct usb_device_id wacom_ids[] = { { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, diff --git a/trunk/drivers/input/tablet/wacom_wac.h b/trunk/drivers/input/tablet/wacom_wac.h index a302e229bb8a..a5e12e8756de 100644 --- a/trunk/drivers/input/tablet/wacom_wac.h +++ b/trunk/drivers/input/tablet/wacom_wac.h @@ -25,7 +25,6 @@ enum { INTUOS3, INTUOS3L, CINTIQ, - WACOM_MO, MAX_TYPE }; diff --git a/trunk/drivers/input/touchscreen/Kconfig b/trunk/drivers/input/touchscreen/Kconfig index 69371779806a..e5cca9bd0406 100644 --- a/trunk/drivers/input/touchscreen/Kconfig +++ b/trunk/drivers/input/touchscreen/Kconfig @@ -177,7 +177,6 @@ config TOUCHSCREEN_USB_COMPOSITE - some other eTurboTouch - Gunze AHL61 - DMC TSC-10/25 - - IRTOUCHSYSTEMS/UNITOP Have a look at for a usage description and the required user-space stuff. @@ -220,9 +219,4 @@ config TOUCHSCREEN_USB_DMC_TSC10 bool "DMC TSC-10/25 device support" if EMBEDDED depends on TOUCHSCREEN_USB_COMPOSITE -config TOUCHSCREEN_USB_IRTOUCH - default y - bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED - depends on TOUCHSCREEN_USB_COMPOSITE - endif diff --git a/trunk/drivers/input/touchscreen/usbtouchscreen.c b/trunk/drivers/input/touchscreen/usbtouchscreen.c index b407028ffc59..e3f22852bd09 100644 --- a/trunk/drivers/input/touchscreen/usbtouchscreen.c +++ b/trunk/drivers/input/touchscreen/usbtouchscreen.c @@ -9,7 +9,6 @@ * - eTurboTouch * - Gunze AHL61 * - DMC TSC-10/25 - * - IRTOUCHSYSTEMS/UNITOP * * Copyright (C) 2004-2006 by Daniel Ritz * Copyright (C) by Todd E. Johnson (mtouchusb.c) @@ -111,7 +110,6 @@ enum { DEVTYPE_ETURBO, DEVTYPE_GUNZE, DEVTYPE_DMC_TSC10, - DEVTYPE_IRTOUCH, }; static struct usb_device_id usbtouch_devices[] = { @@ -152,11 +150,6 @@ static struct usb_device_id usbtouch_devices[] = { {USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10}, #endif -#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH - {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, - {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, -#endif - {} }; @@ -422,21 +415,6 @@ static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt) #endif -/***************************************************************************** - * IRTOUCH Part - */ -#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH -static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) -{ - dev->x = (pkt[3] << 8) | pkt[2]; - dev->y = (pkt[5] << 8) | pkt[4]; - dev->touch = (pkt[1] & 0x03) ? 1 : 0; - - return 1; -} -#endif - - /***************************************************************************** * the different device descriptors */ @@ -526,17 +504,6 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { .read_data = dmc_tsc10_read_data, }, #endif - -#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH - [DEVTYPE_IRTOUCH] = { - .min_xc = 0x0, - .max_xc = 0x0fff, - .min_yc = 0x0, - .max_yc = 0x0fff, - .rept_size = 8, - .read_data = irtouch_read_data, - }, -#endif }; diff --git a/trunk/drivers/input/tsdev.c b/trunk/drivers/input/tsdev.c index d2f882e98e5e..2db364898e15 100644 --- a/trunk/drivers/input/tsdev.c +++ b/trunk/drivers/input/tsdev.c @@ -109,11 +109,9 @@ struct tsdev { int open; int minor; char name[8]; - struct input_handle handle; wait_queue_head_t wait; struct list_head client_list; - struct device dev; - + struct input_handle handle; int x, y, pressure; struct ts_calibration cal; }; @@ -165,13 +163,9 @@ static int tsdev_open(struct inode *inode, struct file *file) if (!tsdev || !tsdev->exist) return -ENODEV; - get_device(&tsdev->dev); - client = kzalloc(sizeof(struct tsdev_client), GFP_KERNEL); - if (!client) { - error = -ENOMEM; - goto err_put_tsdev; - } + if (!client) + return -ENOMEM; client->tsdev = tsdev; client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0; @@ -179,25 +173,19 @@ static int tsdev_open(struct inode *inode, struct file *file) if (!tsdev->open++ && tsdev->exist) { error = input_open_device(&tsdev->handle); - if (error) - goto err_free_client; + if (error) { + list_del(&client->node); + kfree(client); + return error; + } } file->private_data = client; return 0; - - err_free_client: - list_del(&client->node); - kfree(client); - err_put_tsdev: - put_device(&tsdev->dev); - return error; } -static void tsdev_free(struct device *dev) +static void tsdev_free(struct tsdev *tsdev) { - struct tsdev *tsdev = container_of(dev, struct tsdev, dev); - tsdev_table[tsdev->minor] = NULL; kfree(tsdev); } @@ -212,10 +200,12 @@ static int tsdev_release(struct inode *inode, struct file *file) list_del(&client->node); kfree(client); - if (!--tsdev->open && tsdev->exist) - input_close_device(&tsdev->handle); - - put_device(&tsdev->dev); + if (!--tsdev->open) { + if (tsdev->exist) + input_close_device(&tsdev->handle); + else + tsdev_free(tsdev); + } return 0; } @@ -371,7 +361,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, int x, y, tmp; do_gettimeofday(&time); - client->event[client->head].millisecs = time.tv_usec / 1000; + client->event[client->head].millisecs = time.tv_usec / 100; client->event[client->head].pressure = tsdev->pressure; x = tsdev->x; @@ -398,6 +388,8 @@ 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; @@ -415,13 +407,14 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, INIT_LIST_HEAD(&tsdev->client_list); init_waitqueue_head(&tsdev->wait); + sprintf(tsdev->name, "ts%d", minor); + tsdev->exist = 1; tsdev->minor = minor; tsdev->handle.dev = dev; tsdev->handle.name = tsdev->name; tsdev->handle.handler = handler; tsdev->handle.private = tsdev; - snprintf(tsdev->name, sizeof(tsdev->name), "ts%d", minor); /* Precompute the rough calibration matrix */ delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1; @@ -436,30 +429,36 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, tsdev->cal.yscale = (yres << 8) / delta; tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8); - snprintf(tsdev->dev.bus_id, sizeof(tsdev->dev.bus_id), - "ts%d", minor); - tsdev->dev.class = &input_class; - tsdev->dev.parent = &dev->dev; - tsdev->dev.devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor); - tsdev->dev.release = tsdev_free; - device_initialize(&tsdev->dev); - tsdev_table[minor] = tsdev; - error = device_add(&tsdev->dev); - if (error) + 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 */ + error = sysfs_create_link(&input_class.subsys.kobj, + &cdev->kobj, tsdev->name); + if (error) + goto err_cdev_destroy; error = input_register_handle(&tsdev->handle); if (error) - goto err_delete_tsdev; + goto err_remove_link; return 0; - err_delete_tsdev: - device_del(&tsdev->dev); + err_remove_link: + sysfs_remove_link(&input_class.subsys.kobj, tsdev->name); + err_cdev_destroy: + class_device_destroy(&input_class, devt); err_free_tsdev: - put_device(&tsdev->dev); + tsdev_table[minor] = NULL; + kfree(tsdev); return error; } @@ -469,8 +468,10 @@ static void tsdev_disconnect(struct input_handle *handle) struct tsdev_client *client; input_unregister_handle(handle); - device_del(&tsdev->dev); + sysfs_remove_link(&input_class.subsys.kobj, tsdev->name); + class_device_destroy(&input_class, + MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); tsdev->exist = 0; if (tsdev->open) { @@ -478,9 +479,8 @@ static void tsdev_disconnect(struct input_handle *handle) list_for_each_entry(client, &tsdev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); wake_up_interruptible(&tsdev->wait); - } - - put_device(&tsdev->dev); + } else + tsdev_free(tsdev); } static const struct input_device_id tsdev_ids[] = { diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index db5b00a792f5..fae138bd2207 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -868,11 +868,6 @@ void kblockd_flush_work(struct work_struct *work); */ #define buffer_heads_over_limit 0 -static inline long blk_congestion_wait(int rw, long timeout) -{ - return io_schedule_timeout(timeout); -} - static inline long nr_blockdev_pages(void) { return 0; diff --git a/trunk/include/linux/gpio_mouse.h b/trunk/include/linux/gpio_mouse.h deleted file mode 100644 index 44ed7aa14d85..000000000000 --- a/trunk/include/linux/gpio_mouse.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Driver for simulating a mouse on GPIO lines. - * - * Copyright (C) 2007 Atmel Corporation - * - * 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 _GPIO_MOUSE_H -#define _GPIO_MOUSE_H - -#define GPIO_MOUSE_POLARITY_ACT_HIGH 0x00 -#define GPIO_MOUSE_POLARITY_ACT_LOW 0x01 - -#define GPIO_MOUSE_PIN_UP 0 -#define GPIO_MOUSE_PIN_DOWN 1 -#define GPIO_MOUSE_PIN_LEFT 2 -#define GPIO_MOUSE_PIN_RIGHT 3 -#define GPIO_MOUSE_PIN_BLEFT 4 -#define GPIO_MOUSE_PIN_BMIDDLE 5 -#define GPIO_MOUSE_PIN_BRIGHT 6 -#define GPIO_MOUSE_PIN_MAX 7 - -/** - * struct gpio_mouse_platform_data - * @scan_ms: integer in ms specifying the scan periode. - * @polarity: Pin polarity, active high or low. - * @up: GPIO line for up value. - * @down: GPIO line for down value. - * @left: GPIO line for left value. - * @right: GPIO line for right value. - * @bleft: GPIO line for left button. - * @bmiddle: GPIO line for middle button. - * @bright: GPIO line for right button. - * - * This struct must be added to the platform_device in the board code. - * It is used by the gpio_mouse driver to setup GPIO lines and to - * calculate mouse movement. - */ -struct gpio_mouse_platform_data { - int scan_ms; - int polarity; - - union { - struct { - int up; - int down; - int left; - int right; - - int bleft; - int bmiddle; - int bright; - }; - int pins[GPIO_MOUSE_PIN_MAX]; - }; -}; - -#endif /* _GPIO_MOUSE_H */ diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index 18c98b543030..d8521c72f69f 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -981,15 +981,15 @@ struct input_dev { struct mutex mutex; /* serializes open and close operations */ unsigned int users; - struct device dev; + struct class_device cdev; union { /* temporarily so while we switching to struct device */ - struct device *dev; - } cdev; + struct device *parent; + } dev; struct list_head h_list; struct list_head node; }; -#define to_input_dev(d) container_of(d, struct input_dev, dev) +#define to_input_dev(d) container_of(d, struct input_dev, cdev) /* * Verify that we are in sync with input_device_id mod_devicetable.h #defines @@ -1096,22 +1096,22 @@ struct input_handle { struct list_head h_node; }; -#define to_dev(n) container_of(n, struct input_dev, 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) +#define to_dev(n) container_of(n,struct input_dev,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) struct input_dev *input_allocate_device(void); void input_free_device(struct input_dev *dev); static inline struct input_dev *input_get_device(struct input_dev *dev) { - return to_input_dev(get_device(&dev->dev)); + return to_input_dev(class_device_get(&dev->cdev)); } static inline void input_put_device(struct input_dev *dev) { - put_device(&dev->dev); + class_device_put(&dev->cdev); } static inline void *input_get_drvdata(struct input_dev *dev) diff --git a/trunk/include/linux/usb.h b/trunk/include/linux/usb.h index 56aa2ee21f1b..94bd38a6d947 100644 --- a/trunk/include/linux/usb.h +++ b/trunk/include/linux/usb.h @@ -728,22 +728,6 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor .idVendor = (vend), .idProduct = (prod), \ .bcdDevice_lo = (lo), .bcdDevice_hi = (hi) -/** - * USB_DEVICE_INTERFACE_PROTOCOL - macro used to describe a usb - * device with a specific interface protocol - * @vend: the 16 bit USB Vendor ID - * @prod: the 16 bit USB Product ID - * @pr: bInterfaceProtocol value - * - * This macro is used to create a struct usb_device_id that matches a - * specific interface protocol of devices. - */ -#define USB_DEVICE_INTERFACE_PROTOCOL(vend,prod,pr) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ - .idVendor = (vend), \ - .idProduct = (prod), \ - .bInterfaceProtocol = (pr) - /** * USB_DEVICE_INFO - macro used to describe a class of usb devices * @cl: bDeviceClass value diff --git a/trunk/sound/ppc/beep.c b/trunk/sound/ppc/beep.c index a1aa89f2faf3..5f38f670102c 100644 --- a/trunk/sound/ppc/beep.c +++ b/trunk/sound/ppc/beep.c @@ -118,7 +118,7 @@ static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type, default: return -1; } - chip = input_get_drvdata(dev); + chip = dev->private; if (! chip || (beep = chip->beep) == NULL) return -1; @@ -239,8 +239,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip) input_dev->evbit[0] = BIT(EV_SND); input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); input_dev->event = snd_pmac_beep_event; - input_dev->dev.parent = &chip->pdev->dev; - input_set_drvdata(input_dev, chip); + input_dev->private = chip; + input_dev->cdev.dev = &chip->pdev->dev; beep->dev = input_dev; beep->buf = dmabuf; @@ -251,8 +251,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip) err = snd_ctl_add(chip->card, beep_ctl); if (err < 0) goto fail1; - - chip->beep = beep; + + chip->beep = beep; err = input_register_device(beep->dev); if (err)