diff options
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap-psp-2.6.32/omap3-touchbook/0010-add-touchbook-hid-driver.patch')
-rw-r--r-- | extras/recipes-kernel/linux/linux-omap-psp-2.6.32/omap3-touchbook/0010-add-touchbook-hid-driver.patch | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/omap3-touchbook/0010-add-touchbook-hid-driver.patch b/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/omap3-touchbook/0010-add-touchbook-hid-driver.patch new file mode 100644 index 00000000..aa3b359c --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/omap3-touchbook/0010-add-touchbook-hid-driver.patch | |||
@@ -0,0 +1,339 @@ | |||
1 | From 0f651f19bf9cfecbb76d6f0b251e3d8395f306b8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Gregoire Gentil <gregoire@gentil.com> | ||
3 | Date: Fri, 12 Mar 2010 14:39:07 +0100 | ||
4 | Subject: [PATCH 10/17] add touchbook hid driver | ||
5 | |||
6 | --- | ||
7 | drivers/hid/Kconfig | 7 ++ | ||
8 | drivers/hid/Makefile | 1 + | ||
9 | drivers/hid/hid-ai.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++ | ||
10 | drivers/hid/hid-core.c | 1 + | ||
11 | drivers/hid/hid-ids.h | 3 + | ||
12 | 5 files changed, 272 insertions(+), 0 deletions(-) | ||
13 | create mode 100644 drivers/hid/hid-ai.c | ||
14 | |||
15 | diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig | ||
16 | index 24d90ea..3760565 100644 | ||
17 | --- a/drivers/hid/Kconfig | ||
18 | +++ b/drivers/hid/Kconfig | ||
19 | @@ -62,6 +62,13 @@ config HID_A4TECH | ||
20 | ---help--- | ||
21 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. | ||
22 | |||
23 | +config HID_AI | ||
24 | + tristate "Always Innovating" if EMBEDDED | ||
25 | + depends on USB_HID | ||
26 | + default !EMBEDDED | ||
27 | + ---help--- | ||
28 | + Support for Always Innovating Touch Book. | ||
29 | + | ||
30 | config HID_APPLE | ||
31 | tristate "Apple" if EMBEDDED | ||
32 | depends on (USB_HID || BT_HIDP) | ||
33 | diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile | ||
34 | index 0de2dff..1787952 100644 | ||
35 | --- a/drivers/hid/Makefile | ||
36 | +++ b/drivers/hid/Makefile | ||
37 | @@ -20,6 +20,7 @@ ifdef CONFIG_LOGIRUMBLEPAD2_FF | ||
38 | endif | ||
39 | |||
40 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | ||
41 | +obj-$(CONFIG_HID_AI) += hid-ai.o | ||
42 | obj-$(CONFIG_HID_APPLE) += hid-apple.o | ||
43 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o | ||
44 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o | ||
45 | diff --git a/drivers/hid/hid-ai.c b/drivers/hid/hid-ai.c | ||
46 | new file mode 100644 | ||
47 | index 0000000..83aecaf | ||
48 | --- /dev/null | ||
49 | +++ b/drivers/hid/hid-ai.c | ||
50 | @@ -0,0 +1,260 @@ | ||
51 | +/* | ||
52 | + * USB HID quirks support for the Always Innovating Touch Book | ||
53 | + * Code borrowed from hid-apple.c | ||
54 | + * | ||
55 | + * Copyright (c) 2009 Tim Yamin <plasm@roo.me.uk> | ||
56 | + */ | ||
57 | + | ||
58 | +/* | ||
59 | + * This program is free software; you can redistribute it and/or modify it | ||
60 | + * under the terms of the GNU General Public License as published by the Free | ||
61 | + * Software Foundation; either version 2 of the License, or (at your option) | ||
62 | + * any later version. | ||
63 | + */ | ||
64 | + | ||
65 | +#include <linux/device.h> | ||
66 | +#include <linux/hid.h> | ||
67 | +#include <linux/module.h> | ||
68 | +#include <linux/usb.h> | ||
69 | + | ||
70 | +#include "hid-ids.h" | ||
71 | + | ||
72 | +struct ai_sc { | ||
73 | + unsigned long quirks; | ||
74 | + unsigned int fn_on; | ||
75 | + DECLARE_BITMAP(pressed_fn, KEY_CNT); | ||
76 | +}; | ||
77 | + | ||
78 | +struct ai_key_translation { | ||
79 | + u16 from; | ||
80 | + u16 to; | ||
81 | + u8 flags; | ||
82 | +}; | ||
83 | + | ||
84 | +static struct ai_key_translation ai_fn_keys[] = { | ||
85 | + { KEY_F6, KEY_BRIGHTNESSDOWN }, | ||
86 | + { KEY_F7, KEY_BRIGHTNESSUP }, | ||
87 | + | ||
88 | + { KEY_F8, KEY_MUTE }, | ||
89 | + { KEY_F9, KEY_VOLUMEDOWN }, | ||
90 | + { KEY_F10, KEY_VOLUMEUP }, | ||
91 | + | ||
92 | + { KEY_UP, KEY_PAGEUP }, | ||
93 | + { KEY_DOWN, KEY_PAGEDOWN }, | ||
94 | + { } | ||
95 | +}; | ||
96 | + | ||
97 | +extern unsigned int ai_revision; | ||
98 | +int swap_key = 0; | ||
99 | + | ||
100 | +static struct ai_key_translation *ai_find_translation( | ||
101 | + struct ai_key_translation *table, u16 from) | ||
102 | +{ | ||
103 | + struct ai_key_translation *trans; | ||
104 | + | ||
105 | + /* Look for the translation */ | ||
106 | + for (trans = table; trans->from; trans++) | ||
107 | + if (trans->from == from) | ||
108 | + return trans; | ||
109 | + | ||
110 | + return NULL; | ||
111 | +} | ||
112 | + | ||
113 | +static int ai_event(struct hid_device *hid, struct hid_field *field, | ||
114 | + struct hid_usage *usage, __s32 value) | ||
115 | +{ | ||
116 | + int do_translate; | ||
117 | + | ||
118 | + struct input_dev *input = field->hidinput->input; | ||
119 | + struct ai_sc *asc = hid_get_drvdata(hid); | ||
120 | + struct ai_key_translation *trans; | ||
121 | + | ||
122 | + if (swap_key && usage->code == KEY_RIGHTSHIFT) { | ||
123 | + input_event(input, usage->type, KEY_END, value); | ||
124 | + return 1; | ||
125 | + } | ||
126 | + | ||
127 | + if (swap_key && usage->code == KEY_END) { | ||
128 | + input_event(input, usage->type, KEY_RIGHTSHIFT, value); | ||
129 | + return 1; | ||
130 | + } | ||
131 | + | ||
132 | + if (usage->code == KEY_POWER) { | ||
133 | + asc->fn_on = !!value; | ||
134 | + input_event(input, usage->type, usage->code, value); | ||
135 | + return 1; | ||
136 | + } | ||
137 | + | ||
138 | + trans = ai_find_translation(ai_fn_keys, usage->code); | ||
139 | + if (trans) { | ||
140 | + if (test_bit(usage->code, asc->pressed_fn)) | ||
141 | + do_translate = 1; | ||
142 | + else | ||
143 | + do_translate = asc->fn_on; | ||
144 | + | ||
145 | + if (do_translate) { | ||
146 | + if (value) | ||
147 | + set_bit(usage->code, asc->pressed_fn); | ||
148 | + else | ||
149 | + clear_bit(usage->code, asc->pressed_fn); | ||
150 | + | ||
151 | + input_event(input, usage->type, trans->to, | ||
152 | + value); | ||
153 | + | ||
154 | + return 1; | ||
155 | + } | ||
156 | + } | ||
157 | + | ||
158 | + return 0; | ||
159 | +} | ||
160 | + | ||
161 | +static int ai_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
162 | + struct hid_field *field, struct hid_usage *usage, | ||
163 | + unsigned long **bit, int *max) | ||
164 | +{ | ||
165 | + struct ai_key_translation *trans; | ||
166 | + | ||
167 | + /* Enable all other keys */ | ||
168 | + for (trans = ai_fn_keys; trans->from; trans++) | ||
169 | + set_bit(trans->to, hi->input->keybit); | ||
170 | + | ||
171 | + return 0; | ||
172 | +} | ||
173 | + | ||
174 | +static ssize_t show_swap_key(struct device *dev, | ||
175 | + struct device_attribute *attr, char *buf) | ||
176 | +{ | ||
177 | + return snprintf(buf, PAGE_SIZE, "%d\n", swap_key); | ||
178 | +} | ||
179 | + | ||
180 | +static ssize_t store_swap_key(struct device *dev, | ||
181 | + struct device_attribute *attr, | ||
182 | + const char *buf, size_t count) | ||
183 | +{ | ||
184 | + swap_key = simple_strtoul(buf, NULL, 0); | ||
185 | + | ||
186 | + if (swap_key != 0 && swap_key != 1) { | ||
187 | + swap_key = 0; | ||
188 | + return -EINVAL; | ||
189 | + } | ||
190 | + | ||
191 | + return count; | ||
192 | +} | ||
193 | + | ||
194 | +static struct device_attribute ai_hid_attrs[] = { | ||
195 | + __ATTR(swap_key, S_IRUGO | S_IWUGO, show_swap_key, store_swap_key), | ||
196 | +}; | ||
197 | + | ||
198 | +int ai_create_sysfs(struct hid_device *hdev) | ||
199 | +{ | ||
200 | + int i; | ||
201 | + int r; | ||
202 | + | ||
203 | + for (i = 0; i < ARRAY_SIZE(ai_hid_attrs); i++) { | ||
204 | + r = device_create_file(&hdev->dev, | ||
205 | + &ai_hid_attrs[i]); | ||
206 | + | ||
207 | + if (r) { | ||
208 | + dev_err(&hdev->dev, "failed to create sysfs file\n"); | ||
209 | + return r; | ||
210 | + } | ||
211 | + } | ||
212 | + | ||
213 | + return 0; | ||
214 | +} | ||
215 | + | ||
216 | +void ai_remove_sysfs(struct hid_device *hdev) | ||
217 | +{ | ||
218 | + int i; | ||
219 | + | ||
220 | + for (i = 0; i < ARRAY_SIZE(ai_hid_attrs); i++) | ||
221 | + device_remove_file(&hdev->dev, | ||
222 | + &ai_hid_attrs[i]); | ||
223 | +} | ||
224 | + | ||
225 | +static int ai_probe(struct hid_device *hdev, | ||
226 | + const struct hid_device_id *id) | ||
227 | +{ | ||
228 | + unsigned long quirks = id->driver_data; | ||
229 | + struct ai_sc *asc; | ||
230 | + unsigned int connect_mask = HID_CONNECT_DEFAULT; | ||
231 | + int ret; | ||
232 | + | ||
233 | + asc = kzalloc(sizeof(*asc), GFP_KERNEL); | ||
234 | + if (asc == NULL) { | ||
235 | + dev_err(&hdev->dev, "can't alloc ai descriptor\n"); | ||
236 | + return -ENOMEM; | ||
237 | + } | ||
238 | + | ||
239 | + asc->quirks = quirks; | ||
240 | + hid_set_drvdata(hdev, asc); | ||
241 | + | ||
242 | + ret = hid_parse(hdev); | ||
243 | + if (ret) { | ||
244 | + dev_err(&hdev->dev, "parse failed\n"); | ||
245 | + goto err_free; | ||
246 | + } | ||
247 | + | ||
248 | + ret = ai_create_sysfs(hdev); | ||
249 | + if (ret) { | ||
250 | + dev_err(&hdev->dev, "failed to create sysfs entries\n"); | ||
251 | + goto err_free; | ||
252 | + } | ||
253 | + | ||
254 | + swap_key = (ai_revision >= 4) ? 1 : 0; | ||
255 | + | ||
256 | + ret = hid_hw_start(hdev, connect_mask); | ||
257 | + if (ret) { | ||
258 | + dev_err(&hdev->dev, "hw start failed\n"); | ||
259 | + goto err_free; | ||
260 | + } | ||
261 | + | ||
262 | + return 0; | ||
263 | +err_free: | ||
264 | + kfree(asc); | ||
265 | + return ret; | ||
266 | +} | ||
267 | + | ||
268 | +static void ai_remove(struct hid_device *hdev) | ||
269 | +{ | ||
270 | + hid_hw_stop(hdev); | ||
271 | + kfree(hid_get_drvdata(hdev)); | ||
272 | + ai_remove_sysfs(hdev); | ||
273 | +} | ||
274 | + | ||
275 | +static const struct hid_device_id ai_devices[] = { | ||
276 | + { HID_USB_DEVICE(USB_VENDOR_ID_AI, USB_DEVICE_ID_AI_TOUCH_BOOK) }, | ||
277 | + { } | ||
278 | +}; | ||
279 | + | ||
280 | +MODULE_DEVICE_TABLE(hid, ai_devices); | ||
281 | + | ||
282 | +static struct hid_driver ai_driver = { | ||
283 | + .name = "ai", | ||
284 | + .id_table = ai_devices, | ||
285 | + .probe = ai_probe, | ||
286 | + .remove = ai_remove, | ||
287 | + .event = ai_event, | ||
288 | + .input_mapping = ai_input_mapping, | ||
289 | +}; | ||
290 | + | ||
291 | +static int ai_init(void) | ||
292 | +{ | ||
293 | + int ret; | ||
294 | + | ||
295 | + ret = hid_register_driver(&ai_driver); | ||
296 | + if (ret) | ||
297 | + printk(KERN_ERR "can't register ai driver\n"); | ||
298 | + | ||
299 | + return ret; | ||
300 | +} | ||
301 | + | ||
302 | +static void ai_exit(void) | ||
303 | +{ | ||
304 | + hid_unregister_driver(&ai_driver); | ||
305 | +} | ||
306 | + | ||
307 | +module_init(ai_init); | ||
308 | +module_exit(ai_exit); | ||
309 | +MODULE_LICENSE("GPL"); | ||
310 | +HID_COMPAT_LOAD_DRIVER(ai); | ||
311 | diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c | ||
312 | index 80792d3..f6b5960 100644 | ||
313 | --- a/drivers/hid/hid-core.c | ||
314 | +++ b/drivers/hid/hid-core.c | ||
315 | @@ -1250,6 +1250,7 @@ EXPORT_SYMBOL_GPL(hid_disconnect); | ||
316 | static const struct hid_device_id hid_blacklist[] = { | ||
317 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, | ||
318 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, | ||
319 | + { HID_USB_DEVICE(USB_VENDOR_ID_AI, USB_DEVICE_ID_AI_TOUCH_BOOK) }, | ||
320 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, | ||
321 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, | ||
322 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, | ||
323 | diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h | ||
324 | index 3839340..5a0127d 100644 | ||
325 | --- a/drivers/hid/hid-ids.h | ||
326 | +++ b/drivers/hid/hid-ids.h | ||
327 | @@ -54,6 +54,9 @@ | ||
328 | #define USB_VENDOR_ID_ALPS 0x0433 | ||
329 | #define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 | ||
330 | |||
331 | +#define USB_VENDOR_ID_AI 0xa110 | ||
332 | +#define USB_DEVICE_ID_AI_TOUCH_BOOK 0x0002 | ||
333 | + | ||
334 | #define USB_VENDOR_ID_APPLE 0x05ac | ||
335 | #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 | ||
336 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e | ||
337 | -- | ||
338 | 1.6.6.1 | ||
339 | |||