Loading Documentation/input/rotary-encoder.txt 0 → 100644 +101 −0 Original line number Diff line number Diff line rotary-encoder - a generic driver for GPIO connected devices Daniel Mack <daniel@caiaq.de>, Feb 2009 0. Function ----------- Rotary encoders are devices which are connected to the CPU or other peripherals with two wires. The outputs are phase-shifted by 90 degrees and by triggering on falling and rising edges, the turn direction can be determined. The phase diagram of these two outputs look like this: _____ _____ _____ | | | | | | Channel A ____| |_____| |_____| |____ : : : : : : : : : : : : __ _____ _____ _____ | | | | | | | Channel B |_____| |_____| |_____| |__ : : : : : : : : : : : : Event a b c d a b c d a b c d |<-------->| one step For more information, please see http://en.wikipedia.org/wiki/Rotary_encoder 1. Events / state machine ------------------------- a) Rising edge on channel A, channel B in low state This state is used to recognize a clockwise turn b) Rising edge on channel B, channel A in high state When entering this state, the encoder is put into 'armed' state, meaning that there it has seen half the way of a one-step transition. c) Falling edge on channel A, channel B in high state This state is used to recognize a counter-clockwise turn d) Falling edge on channel B, channel A in low state Parking position. If the encoder enters this state, a full transition should have happend, unless it flipped back on half the way. The 'armed' state tells us about that. 2. Platform requirements ------------------------ As there is no hardware dependent call in this driver, the platform it is used with must support gpiolib. Another requirement is that IRQs must be able to fire on both edges. 3. Board integration -------------------- To use this driver in your system, register a platform_device with the name 'rotary-encoder' and associate the IRQs and some specific platform data with it. struct rotary_encoder_platform_data is declared in include/linux/rotary-encoder.h and needs to be filled with the number of steps the encoder has and can carry information about externally inverted signals (because of used invertig buffer or other reasons). Because GPIO to IRQ mapping is platform specific, this information must be given in seperately to the driver. See the example below. ---------<snip>--------- /* board support file example */ #include <linux/input.h> #include <linux/rotary_encoder.h> #define GPIO_ROTARY_A 1 #define GPIO_ROTARY_B 2 static struct rotary_encoder_platform_data my_rotary_encoder_info = { .steps = 24, .axis = ABS_X, .gpio_a = GPIO_ROTARY_A, .gpio_b = GPIO_ROTARY_B, .inverted_a = 0, .inverted_b = 0, }; static struct platform_device rotary_encoder_device = { .name = "rotary-encoder", .id = 0, .dev = { .platform_data = &my_rotary_encoder_info, } }; arch/mips/include/asm/mach-rc32434/gpio.h +3 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,9 @@ struct rb532_gpio_reg { /* Compact Flash GPIO pin */ #define CF_GPIO_NUM 13 /* S1 button GPIO (shared with UART0_SIN) */ #define GPIO_BTN_S1 1 extern void rb532_gpio_set_ilevel(int bit, unsigned gpio); extern void rb532_gpio_set_istat(int bit, unsigned gpio); extern void rb532_gpio_set_func(unsigned gpio); Loading arch/mips/rb532/devices.c +1 −18 Original line number Diff line number Diff line Loading @@ -200,26 +200,9 @@ static struct platform_device rb532_led = { .id = -1, }; static struct gpio_keys_button rb532_gpio_btn[] = { { .gpio = 1, .code = BTN_0, .desc = "S1", .active_low = 1, } }; static struct gpio_keys_platform_data rb532_gpio_btn_data = { .buttons = rb532_gpio_btn, .nbuttons = ARRAY_SIZE(rb532_gpio_btn), }; static struct platform_device rb532_button = { .name = "gpio-keys", .name = "rb532-button", .id = -1, .dev = { .platform_data = &rb532_gpio_btn_data, } }; static struct resource rb532_wdt_res[] = { Loading drivers/input/input.c +10 −3 Original line number Diff line number Diff line Loading @@ -132,6 +132,11 @@ static void input_start_autorepeat(struct input_dev *dev, int code) } } static void input_stop_autorepeat(struct input_dev *dev) { del_timer(&dev->timer); } #define INPUT_IGNORE_EVENT 0 #define INPUT_PASS_TO_HANDLERS 1 #define INPUT_PASS_TO_DEVICE 2 Loading Loading @@ -167,6 +172,8 @@ static void input_handle_event(struct input_dev *dev, __change_bit(code, dev->key); if (value) input_start_autorepeat(dev, code); else input_stop_autorepeat(dev); } disposition = INPUT_PASS_TO_HANDLERS; Loading Loading @@ -737,11 +744,11 @@ static inline void input_wakeup_procfs_readers(void) static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) { int state = input_devices_state; poll_wait(file, &input_devices_poll_wait, wait); if (state != input_devices_state) if (file->f_version != input_devices_state) { file->f_version = input_devices_state; return POLLIN | POLLRDNORM; } return 0; } Loading drivers/input/keyboard/atkbd.c +62 −73 Original line number Diff line number Diff line Loading @@ -229,7 +229,8 @@ struct atkbd { /* * System-specific ketymap fixup routine */ static void (*atkbd_platform_fixup)(struct atkbd *); static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); static void *atkbd_platform_fixup_data; static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, ssize_t (*handler)(struct atkbd *, char *)); Loading Loading @@ -834,87 +835,64 @@ static void atkbd_disconnect(struct serio *serio) } /* * Most special keys (Fn+F?) on Dell laptops do not generate release * events so we have to do it ourselves. * generate release events for the keycodes given in data */ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd, const void *data) { static const unsigned int forced_release_keys[] = { 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, }; int i; const unsigned int *keys = data; unsigned int i; if (atkbd->set == 2) for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) __set_bit(forced_release_keys[i], atkbd->force_release_mask); for (i = 0; keys[i] != -1U; i++) __set_bit(keys[i], atkbd->force_release_mask); } /* * Most special keys (Fn+F?) on Dell laptops do not generate release * events so we have to do it ourselves. */ static unsigned int atkbd_dell_laptop_forced_release_keys[] = { 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, -1U }; /* * Perform fixup for HP system that doesn't generate release * for its video switch */ static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) { static const unsigned int forced_release_keys[] = { 0x94, static unsigned int atkbd_hp_forced_release_keys[] = { 0x94, -1U }; int i; if (atkbd->set == 2) for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) __set_bit(forced_release_keys[i], atkbd->force_release_mask); } /* * Inventec system with broken key release on volume keys */ static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd) { const unsigned int forced_release_keys[] = { 0xae, 0xb0, static unsigned int atkbd_inventec_forced_release_keys[] = { 0xae, 0xb0, -1U }; int i; if (atkbd->set == 2) for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) __set_bit(forced_release_keys[i], atkbd->force_release_mask); } /* * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release * for its volume buttons */ static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd) { const unsigned int forced_release_keys[] = { 0xae, 0xb0, static unsigned int atkbd_hp_zv6100_forced_release_keys[] = { 0xae, 0xb0, -1U }; int i; if (atkbd->set == 2) for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) __set_bit(forced_release_keys[i], atkbd->force_release_mask); } /* * Samsung NC10 with Fn+F? key release not working */ static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd) { const unsigned int forced_release_keys[] = { 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, static unsigned int atkbd_samsung_forced_release_keys[] = { 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U }; int i; if (atkbd->set == 2) for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) __set_bit(forced_release_keys[i], atkbd->force_release_mask); } /* * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop * do not generate release events so we have to do it ourselves. */ static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = { 0xb0, 0xae, -1U }; /* * atkbd_set_keycode_table() initializes keyboard's keycode table Loading Loading @@ -967,7 +945,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) * Perform additional fixups */ if (atkbd_platform_fixup) atkbd_platform_fixup(atkbd); atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data); } /* Loading Loading @@ -1492,9 +1470,11 @@ static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) return sprintf(buf, "%lu\n", atkbd->err_count); } static int __init atkbd_setup_fixup(const struct dmi_system_id *id) static int __init atkbd_setup_forced_release(const struct dmi_system_id *id) { atkbd_platform_fixup = id->driver_data; atkbd_platform_fixup = atkbd_apply_forced_release_keylist; atkbd_platform_fixup_data = id->driver_data; return 0; } Loading @@ -1505,8 +1485,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ }, .callback = atkbd_setup_fixup, .driver_data = atkbd_dell_laptop_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_dell_laptop_forced_release_keys, }, { .ident = "Dell Laptop", Loading @@ -1514,8 +1494,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ }, .callback = atkbd_setup_fixup, .driver_data = atkbd_dell_laptop_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_dell_laptop_forced_release_keys, }, { .ident = "HP 2133", Loading @@ -1523,8 +1503,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), }, .callback = atkbd_setup_fixup, .driver_data = atkbd_hp_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_hp_forced_release_keys, }, { .ident = "HP Pavilion ZV6100", Loading @@ -1532,8 +1512,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), }, .callback = atkbd_setup_fixup, .driver_data = atkbd_hp_zv6100_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_hp_zv6100_forced_release_keys, }, { .ident = "Inventec Symphony", Loading @@ -1541,8 +1521,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), }, .callback = atkbd_setup_fixup, .driver_data = atkbd_inventec_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_inventec_forced_release_keys, }, { .ident = "Samsung NC10", Loading @@ -1550,8 +1530,17 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), }, .callback = atkbd_setup_fixup, .driver_data = atkbd_samsung_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_samsung_forced_release_keys, }, { .ident = "Fujitsu Amilo PA 1510", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), }, .callback = atkbd_setup_forced_release, .driver_data = atkbd_amilo_pa1510_forced_release_keys, }, { } }; Loading Loading
Documentation/input/rotary-encoder.txt 0 → 100644 +101 −0 Original line number Diff line number Diff line rotary-encoder - a generic driver for GPIO connected devices Daniel Mack <daniel@caiaq.de>, Feb 2009 0. Function ----------- Rotary encoders are devices which are connected to the CPU or other peripherals with two wires. The outputs are phase-shifted by 90 degrees and by triggering on falling and rising edges, the turn direction can be determined. The phase diagram of these two outputs look like this: _____ _____ _____ | | | | | | Channel A ____| |_____| |_____| |____ : : : : : : : : : : : : __ _____ _____ _____ | | | | | | | Channel B |_____| |_____| |_____| |__ : : : : : : : : : : : : Event a b c d a b c d a b c d |<-------->| one step For more information, please see http://en.wikipedia.org/wiki/Rotary_encoder 1. Events / state machine ------------------------- a) Rising edge on channel A, channel B in low state This state is used to recognize a clockwise turn b) Rising edge on channel B, channel A in high state When entering this state, the encoder is put into 'armed' state, meaning that there it has seen half the way of a one-step transition. c) Falling edge on channel A, channel B in high state This state is used to recognize a counter-clockwise turn d) Falling edge on channel B, channel A in low state Parking position. If the encoder enters this state, a full transition should have happend, unless it flipped back on half the way. The 'armed' state tells us about that. 2. Platform requirements ------------------------ As there is no hardware dependent call in this driver, the platform it is used with must support gpiolib. Another requirement is that IRQs must be able to fire on both edges. 3. Board integration -------------------- To use this driver in your system, register a platform_device with the name 'rotary-encoder' and associate the IRQs and some specific platform data with it. struct rotary_encoder_platform_data is declared in include/linux/rotary-encoder.h and needs to be filled with the number of steps the encoder has and can carry information about externally inverted signals (because of used invertig buffer or other reasons). Because GPIO to IRQ mapping is platform specific, this information must be given in seperately to the driver. See the example below. ---------<snip>--------- /* board support file example */ #include <linux/input.h> #include <linux/rotary_encoder.h> #define GPIO_ROTARY_A 1 #define GPIO_ROTARY_B 2 static struct rotary_encoder_platform_data my_rotary_encoder_info = { .steps = 24, .axis = ABS_X, .gpio_a = GPIO_ROTARY_A, .gpio_b = GPIO_ROTARY_B, .inverted_a = 0, .inverted_b = 0, }; static struct platform_device rotary_encoder_device = { .name = "rotary-encoder", .id = 0, .dev = { .platform_data = &my_rotary_encoder_info, } };
arch/mips/include/asm/mach-rc32434/gpio.h +3 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,9 @@ struct rb532_gpio_reg { /* Compact Flash GPIO pin */ #define CF_GPIO_NUM 13 /* S1 button GPIO (shared with UART0_SIN) */ #define GPIO_BTN_S1 1 extern void rb532_gpio_set_ilevel(int bit, unsigned gpio); extern void rb532_gpio_set_istat(int bit, unsigned gpio); extern void rb532_gpio_set_func(unsigned gpio); Loading
arch/mips/rb532/devices.c +1 −18 Original line number Diff line number Diff line Loading @@ -200,26 +200,9 @@ static struct platform_device rb532_led = { .id = -1, }; static struct gpio_keys_button rb532_gpio_btn[] = { { .gpio = 1, .code = BTN_0, .desc = "S1", .active_low = 1, } }; static struct gpio_keys_platform_data rb532_gpio_btn_data = { .buttons = rb532_gpio_btn, .nbuttons = ARRAY_SIZE(rb532_gpio_btn), }; static struct platform_device rb532_button = { .name = "gpio-keys", .name = "rb532-button", .id = -1, .dev = { .platform_data = &rb532_gpio_btn_data, } }; static struct resource rb532_wdt_res[] = { Loading
drivers/input/input.c +10 −3 Original line number Diff line number Diff line Loading @@ -132,6 +132,11 @@ static void input_start_autorepeat(struct input_dev *dev, int code) } } static void input_stop_autorepeat(struct input_dev *dev) { del_timer(&dev->timer); } #define INPUT_IGNORE_EVENT 0 #define INPUT_PASS_TO_HANDLERS 1 #define INPUT_PASS_TO_DEVICE 2 Loading Loading @@ -167,6 +172,8 @@ static void input_handle_event(struct input_dev *dev, __change_bit(code, dev->key); if (value) input_start_autorepeat(dev, code); else input_stop_autorepeat(dev); } disposition = INPUT_PASS_TO_HANDLERS; Loading Loading @@ -737,11 +744,11 @@ static inline void input_wakeup_procfs_readers(void) static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) { int state = input_devices_state; poll_wait(file, &input_devices_poll_wait, wait); if (state != input_devices_state) if (file->f_version != input_devices_state) { file->f_version = input_devices_state; return POLLIN | POLLRDNORM; } return 0; } Loading
drivers/input/keyboard/atkbd.c +62 −73 Original line number Diff line number Diff line Loading @@ -229,7 +229,8 @@ struct atkbd { /* * System-specific ketymap fixup routine */ static void (*atkbd_platform_fixup)(struct atkbd *); static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); static void *atkbd_platform_fixup_data; static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, ssize_t (*handler)(struct atkbd *, char *)); Loading Loading @@ -834,87 +835,64 @@ static void atkbd_disconnect(struct serio *serio) } /* * Most special keys (Fn+F?) on Dell laptops do not generate release * events so we have to do it ourselves. * generate release events for the keycodes given in data */ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd, const void *data) { static const unsigned int forced_release_keys[] = { 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, }; int i; const unsigned int *keys = data; unsigned int i; if (atkbd->set == 2) for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) __set_bit(forced_release_keys[i], atkbd->force_release_mask); for (i = 0; keys[i] != -1U; i++) __set_bit(keys[i], atkbd->force_release_mask); } /* * Most special keys (Fn+F?) on Dell laptops do not generate release * events so we have to do it ourselves. */ static unsigned int atkbd_dell_laptop_forced_release_keys[] = { 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, -1U }; /* * Perform fixup for HP system that doesn't generate release * for its video switch */ static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) { static const unsigned int forced_release_keys[] = { 0x94, static unsigned int atkbd_hp_forced_release_keys[] = { 0x94, -1U }; int i; if (atkbd->set == 2) for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) __set_bit(forced_release_keys[i], atkbd->force_release_mask); } /* * Inventec system with broken key release on volume keys */ static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd) { const unsigned int forced_release_keys[] = { 0xae, 0xb0, static unsigned int atkbd_inventec_forced_release_keys[] = { 0xae, 0xb0, -1U }; int i; if (atkbd->set == 2) for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) __set_bit(forced_release_keys[i], atkbd->force_release_mask); } /* * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release * for its volume buttons */ static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd) { const unsigned int forced_release_keys[] = { 0xae, 0xb0, static unsigned int atkbd_hp_zv6100_forced_release_keys[] = { 0xae, 0xb0, -1U }; int i; if (atkbd->set == 2) for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) __set_bit(forced_release_keys[i], atkbd->force_release_mask); } /* * Samsung NC10 with Fn+F? key release not working */ static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd) { const unsigned int forced_release_keys[] = { 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, static unsigned int atkbd_samsung_forced_release_keys[] = { 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U }; int i; if (atkbd->set == 2) for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) __set_bit(forced_release_keys[i], atkbd->force_release_mask); } /* * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop * do not generate release events so we have to do it ourselves. */ static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = { 0xb0, 0xae, -1U }; /* * atkbd_set_keycode_table() initializes keyboard's keycode table Loading Loading @@ -967,7 +945,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) * Perform additional fixups */ if (atkbd_platform_fixup) atkbd_platform_fixup(atkbd); atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data); } /* Loading Loading @@ -1492,9 +1470,11 @@ static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) return sprintf(buf, "%lu\n", atkbd->err_count); } static int __init atkbd_setup_fixup(const struct dmi_system_id *id) static int __init atkbd_setup_forced_release(const struct dmi_system_id *id) { atkbd_platform_fixup = id->driver_data; atkbd_platform_fixup = atkbd_apply_forced_release_keylist; atkbd_platform_fixup_data = id->driver_data; return 0; } Loading @@ -1505,8 +1485,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ }, .callback = atkbd_setup_fixup, .driver_data = atkbd_dell_laptop_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_dell_laptop_forced_release_keys, }, { .ident = "Dell Laptop", Loading @@ -1514,8 +1494,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ }, .callback = atkbd_setup_fixup, .driver_data = atkbd_dell_laptop_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_dell_laptop_forced_release_keys, }, { .ident = "HP 2133", Loading @@ -1523,8 +1503,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), }, .callback = atkbd_setup_fixup, .driver_data = atkbd_hp_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_hp_forced_release_keys, }, { .ident = "HP Pavilion ZV6100", Loading @@ -1532,8 +1512,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), }, .callback = atkbd_setup_fixup, .driver_data = atkbd_hp_zv6100_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_hp_zv6100_forced_release_keys, }, { .ident = "Inventec Symphony", Loading @@ -1541,8 +1521,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), }, .callback = atkbd_setup_fixup, .driver_data = atkbd_inventec_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_inventec_forced_release_keys, }, { .ident = "Samsung NC10", Loading @@ -1550,8 +1530,17 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), }, .callback = atkbd_setup_fixup, .driver_data = atkbd_samsung_keymap_fixup, .callback = atkbd_setup_forced_release, .driver_data = atkbd_samsung_forced_release_keys, }, { .ident = "Fujitsu Amilo PA 1510", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), }, .callback = atkbd_setup_forced_release, .driver_data = atkbd_amilo_pa1510_forced_release_keys, }, { } }; Loading