diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-11-04 00:41:24 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-01-21 01:11:06 -0500 |
commit | 1953ea2d8df48f33d2a79042ae1b4a2d5f1548a3 (patch) | |
tree | 0bea6bd9e8e094bccfe37b1d295b9eb3e3606e3f /drivers/input | |
parent | f4f37c8ec7d2491c8885c890ba74254b9adfbeee (diff) |
Input: keyspan_remote - add support for loadable keymaps
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/misc/keyspan_remote.c | 118 |
1 files changed, 67 insertions, 51 deletions
diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c index fd74347047d..86ddd72dbe3 100644 --- a/drivers/input/misc/keyspan_remote.c +++ b/drivers/input/misc/keyspan_remote.c | |||
@@ -46,53 +46,12 @@ MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); | |||
46 | 46 | ||
47 | #define RECV_SIZE 8 /* The UIA-11 type have a 8 byte limit. */ | 47 | #define RECV_SIZE 8 /* The UIA-11 type have a 8 byte limit. */ |
48 | 48 | ||
49 | /* table of devices that work with this driver */ | ||
50 | static struct usb_device_id keyspan_table[] = { | ||
51 | { USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) }, | ||
52 | { } /* Terminating entry */ | ||
53 | }; | ||
54 | |||
55 | /* Structure to store all the real stuff that a remote sends to us. */ | ||
56 | struct keyspan_message { | ||
57 | u16 system; | ||
58 | u8 button; | ||
59 | u8 toggle; | ||
60 | }; | ||
61 | |||
62 | /* Structure used for all the bit testing magic needed to be done. */ | ||
63 | struct bit_tester { | ||
64 | u32 tester; | ||
65 | int len; | ||
66 | int pos; | ||
67 | int bits_left; | ||
68 | u8 buffer[32]; | ||
69 | }; | ||
70 | |||
71 | /* Structure to hold all of our driver specific stuff */ | ||
72 | struct usb_keyspan { | ||
73 | char name[128]; | ||
74 | char phys[64]; | ||
75 | struct usb_device* udev; | ||
76 | struct input_dev *input; | ||
77 | struct usb_interface* interface; | ||
78 | struct usb_endpoint_descriptor* in_endpoint; | ||
79 | struct urb* irq_urb; | ||
80 | int open; | ||
81 | dma_addr_t in_dma; | ||
82 | unsigned char* in_buffer; | ||
83 | |||
84 | /* variables used to parse messages from remote. */ | ||
85 | struct bit_tester data; | ||
86 | int stage; | ||
87 | int toggle; | ||
88 | }; | ||
89 | |||
90 | /* | 49 | /* |
91 | * Table that maps the 31 possible keycodes to input keys. | 50 | * Table that maps the 31 possible keycodes to input keys. |
92 | * Currently there are 15 and 17 button models so RESERVED codes | 51 | * Currently there are 15 and 17 button models so RESERVED codes |
93 | * are blank areas in the mapping. | 52 | * are blank areas in the mapping. |
94 | */ | 53 | */ |
95 | static const int keyspan_key_table[] = { | 54 | static const unsigned short keyspan_key_table[] = { |
96 | KEY_RESERVED, /* 0 is just a place holder. */ | 55 | KEY_RESERVED, /* 0 is just a place holder. */ |
97 | KEY_RESERVED, | 56 | KEY_RESERVED, |
98 | KEY_STOP, | 57 | KEY_STOP, |
@@ -127,6 +86,48 @@ static const int keyspan_key_table[] = { | |||
127 | KEY_MENU | 86 | KEY_MENU |
128 | }; | 87 | }; |
129 | 88 | ||
89 | /* table of devices that work with this driver */ | ||
90 | static struct usb_device_id keyspan_table[] = { | ||
91 | { USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) }, | ||
92 | { } /* Terminating entry */ | ||
93 | }; | ||
94 | |||
95 | /* Structure to store all the real stuff that a remote sends to us. */ | ||
96 | struct keyspan_message { | ||
97 | u16 system; | ||
98 | u8 button; | ||
99 | u8 toggle; | ||
100 | }; | ||
101 | |||
102 | /* Structure used for all the bit testing magic needed to be done. */ | ||
103 | struct bit_tester { | ||
104 | u32 tester; | ||
105 | int len; | ||
106 | int pos; | ||
107 | int bits_left; | ||
108 | u8 buffer[32]; | ||
109 | }; | ||
110 | |||
111 | /* Structure to hold all of our driver specific stuff */ | ||
112 | struct usb_keyspan { | ||
113 | char name[128]; | ||
114 | char phys[64]; | ||
115 | unsigned short keymap[ARRAY_SIZE(keyspan_key_table)]; | ||
116 | struct usb_device *udev; | ||
117 | struct input_dev *input; | ||
118 | struct usb_interface *interface; | ||
119 | struct usb_endpoint_descriptor *in_endpoint; | ||
120 | struct urb* irq_urb; | ||
121 | int open; | ||
122 | dma_addr_t in_dma; | ||
123 | unsigned char *in_buffer; | ||
124 | |||
125 | /* variables used to parse messages from remote. */ | ||
126 | struct bit_tester data; | ||
127 | int stage; | ||
128 | int toggle; | ||
129 | }; | ||
130 | |||
130 | static struct usb_driver keyspan_driver; | 131 | static struct usb_driver keyspan_driver; |
131 | 132 | ||
132 | /* | 133 | /* |
@@ -173,6 +174,15 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) | |||
173 | return 0; | 174 | return 0; |
174 | } | 175 | } |
175 | 176 | ||
177 | static void keyspan_report_button(struct usb_keyspan *remote, int button, int press) | ||
178 | { | ||
179 | struct input_dev *input = remote->input; | ||
180 | |||
181 | input_event(input, EV_MSC, MSC_SCAN, button); | ||
182 | input_report_key(input, remote->keymap[button], press); | ||
183 | input_sync(input); | ||
184 | } | ||
185 | |||
176 | /* | 186 | /* |
177 | * Routine that handles all the logic needed to parse out the message from the remote. | 187 | * Routine that handles all the logic needed to parse out the message from the remote. |
178 | */ | 188 | */ |
@@ -311,9 +321,8 @@ static void keyspan_check_data(struct usb_keyspan *remote) | |||
311 | __FUNCTION__, message.system, message.button, message.toggle); | 321 | __FUNCTION__, message.system, message.button, message.toggle); |
312 | 322 | ||
313 | if (message.toggle != remote->toggle) { | 323 | if (message.toggle != remote->toggle) { |
314 | input_report_key(remote->input, keyspan_key_table[message.button], 1); | 324 | keyspan_report_button(remote, message.button, 1); |
315 | input_report_key(remote->input, keyspan_key_table[message.button], 0); | 325 | keyspan_report_button(remote, message.button, 0); |
316 | input_sync(remote->input); | ||
317 | remote->toggle = message.toggle; | 326 | remote->toggle = message.toggle; |
318 | } | 327 | } |
319 | 328 | ||
@@ -491,16 +500,21 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic | |||
491 | 500 | ||
492 | usb_make_path(udev, remote->phys, sizeof(remote->phys)); | 501 | usb_make_path(udev, remote->phys, sizeof(remote->phys)); |
493 | strlcat(remote->phys, "/input0", sizeof(remote->phys)); | 502 | strlcat(remote->phys, "/input0", sizeof(remote->phys)); |
503 | memcpy(remote->keymap, keyspan_key_table, sizeof(remote->keymap)); | ||
494 | 504 | ||
495 | input_dev->name = remote->name; | 505 | input_dev->name = remote->name; |
496 | input_dev->phys = remote->phys; | 506 | input_dev->phys = remote->phys; |
497 | usb_to_input_id(udev, &input_dev->id); | 507 | usb_to_input_id(udev, &input_dev->id); |
498 | input_dev->dev.parent = &interface->dev; | 508 | input_dev->dev.parent = &interface->dev; |
509 | input_dev->keycode = remote->keymap; | ||
510 | input_dev->keycodesize = sizeof(unsigned short); | ||
511 | input_dev->keycodemax = ARRAY_SIZE(remote->keymap); | ||
499 | 512 | ||
500 | input_dev->evbit[0] = BIT_MASK(EV_KEY); /* We will only report KEY events. */ | 513 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
514 | __set_bit(EV_KEY, input_dev->evbit); | ||
501 | for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++) | 515 | for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++) |
502 | if (keyspan_key_table[i] != KEY_RESERVED) | 516 | __set_bit(keyspan_key_table[i], input_dev->keybit); |
503 | set_bit(keyspan_key_table[i], input_dev->keybit); | 517 | __clear_bit(KEY_RESERVED, input_dev->keybit); |
504 | 518 | ||
505 | input_set_drvdata(input_dev, remote); | 519 | input_set_drvdata(input_dev, remote); |
506 | 520 | ||
@@ -508,12 +522,14 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic | |||
508 | input_dev->close = keyspan_close; | 522 | input_dev->close = keyspan_close; |
509 | 523 | ||
510 | /* | 524 | /* |
511 | * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open() | 525 | * Initialize the URB to access the device. |
526 | * The urb gets sent to the device in keyspan_open() | ||
512 | */ | 527 | */ |
513 | usb_fill_int_urb(remote->irq_urb, | 528 | usb_fill_int_urb(remote->irq_urb, |
514 | remote->udev, usb_rcvintpipe(remote->udev, remote->in_endpoint->bEndpointAddress), | 529 | remote->udev, |
530 | usb_rcvintpipe(remote->udev, endpoint->bEndpointAddress), | ||
515 | remote->in_buffer, RECV_SIZE, keyspan_irq_recv, remote, | 531 | remote->in_buffer, RECV_SIZE, keyspan_irq_recv, remote, |
516 | remote->in_endpoint->bInterval); | 532 | endpoint->bInterval); |
517 | remote->irq_urb->transfer_dma = remote->in_dma; | 533 | remote->irq_urb->transfer_dma = remote->in_dma; |
518 | remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 534 | remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
519 | 535 | ||