diff options
author | David Härdeman <david@hardeman.nu> | 2010-10-29 15:08:28 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-12-29 05:16:38 -0500 |
commit | 5b2e303f6df1e0b1a903950c5d613a20c8c71a37 (patch) | |
tree | 2fdd9dfedac05cc473e282e7d20331863b58b6f8 /drivers | |
parent | d8b4b5822f51e2142b731b42c81e3f03eec475b2 (diff) |
[media] rc-core: convert winbond-cir
Move winbond-cir from drivers/input/misc/ into drivers/media/rc/
and convert it to use rc-core.
Signed-off-by: David Härdeman <david@hardeman.nu>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/misc/Kconfig | 18 | ||||
-rw-r--r-- | drivers/input/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/rc/Kconfig | 17 | ||||
-rw-r--r-- | drivers/media/rc/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/rc/winbond-cir.c (renamed from drivers/input/misc/winbond-cir.c) | 886 |
5 files changed, 123 insertions, 800 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index b99b8cbde02f..c1a81bcdb319 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -294,24 +294,6 @@ config INPUT_SGI_BTNS | |||
294 | To compile this driver as a module, choose M here: the | 294 | To compile this driver as a module, choose M here: the |
295 | module will be called sgi_btns. | 295 | module will be called sgi_btns. |
296 | 296 | ||
297 | config INPUT_WINBOND_CIR | ||
298 | tristate "Winbond IR remote control" | ||
299 | depends on X86 && PNP | ||
300 | select NEW_LEDS | ||
301 | select LEDS_CLASS | ||
302 | select LEDS_TRIGGERS | ||
303 | select BITREVERSE | ||
304 | help | ||
305 | Say Y here if you want to use the IR remote functionality found | ||
306 | in some Winbond SuperI/O chips. Currently only the WPCD376I | ||
307 | chip is supported (included in some Intel Media series motherboards). | ||
308 | |||
309 | IR Receive and wake-on-IR from suspend and power-off is currently | ||
310 | supported. | ||
311 | |||
312 | To compile this driver as a module, choose M here: the module will be | ||
313 | called winbond_cir. | ||
314 | |||
315 | config HP_SDC_RTC | 297 | config HP_SDC_RTC |
316 | tristate "HP SDC Real Time Clock" | 298 | tristate "HP SDC Real Time Clock" |
317 | depends on (GSC || HP300) && SERIO | 299 | depends on (GSC || HP300) && SERIO |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 1fe1f6c8b737..06b2b5154038 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -38,7 +38,6 @@ obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | |||
38 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o | 38 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o |
39 | obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o | 39 | obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o |
40 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 40 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o |
41 | obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o | ||
42 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | 41 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o |
43 | obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o | 42 | obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o |
44 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o | 43 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o |
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index d05003d0995f..2d1546889c9b 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig | |||
@@ -164,4 +164,21 @@ config IR_STREAMZAP | |||
164 | To compile this driver as a module, choose M here: the | 164 | To compile this driver as a module, choose M here: the |
165 | module will be called streamzap. | 165 | module will be called streamzap. |
166 | 166 | ||
167 | config IR_WINBOND_CIR | ||
168 | tristate "Winbond IR remote control" | ||
169 | depends on X86 && PNP | ||
170 | depends on IR_CORE | ||
171 | select NEW_LEDS | ||
172 | select LEDS_CLASS | ||
173 | select LEDS_TRIGGERS | ||
174 | select BITREVERSE | ||
175 | ---help--- | ||
176 | Say Y here if you want to use the IR remote functionality found | ||
177 | in some Winbond SuperI/O chips. Currently only the WPCD376I | ||
178 | chip is supported (included in some Intel Media series | ||
179 | motherboards). | ||
180 | |||
181 | To compile this driver as a module, choose M here: the module will | ||
182 | be called winbond_cir. | ||
183 | |||
167 | endif #IR_CORE | 184 | endif #IR_CORE |
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 1eb24e6bc55c..859c12cc03ff 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile | |||
@@ -20,3 +20,4 @@ obj-$(CONFIG_IR_MCEUSB) += mceusb.o | |||
20 | obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o | 20 | obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o |
21 | obj-$(CONFIG_IR_ENE) += ene_ir.o | 21 | obj-$(CONFIG_IR_ENE) += ene_ir.o |
22 | obj-$(CONFIG_IR_STREAMZAP) += streamzap.o | 22 | obj-$(CONFIG_IR_STREAMZAP) += streamzap.o |
23 | obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o | ||
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 64f1de7960c6..0ee16ec23bbf 100644 --- a/drivers/input/misc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c | |||
@@ -7,10 +7,10 @@ | |||
7 | * with minor modifications. | 7 | * with minor modifications. |
8 | * | 8 | * |
9 | * Original Author: David Härdeman <david@hardeman.nu> | 9 | * Original Author: David Härdeman <david@hardeman.nu> |
10 | * Copyright (C) 2009 David Härdeman <david@hardeman.nu> | 10 | * Copyright (C) 2009 - 2010 David Härdeman <david@hardeman.nu> |
11 | * | 11 | * |
12 | * Dedicated to Matilda, my newborn daughter, without whose loving attention | 12 | * Dedicated to my daughter Matilda, without whose loving attention this |
13 | * this driver would have been finished in half the time and with a fraction | 13 | * driver would have been finished in half the time and with a fraction |
14 | * of the bugs. | 14 | * of the bugs. |
15 | * | 15 | * |
16 | * Written using: | 16 | * Written using: |
@@ -19,15 +19,11 @@ | |||
19 | * o DSDT dumps | 19 | * o DSDT dumps |
20 | * | 20 | * |
21 | * Supported features: | 21 | * Supported features: |
22 | * o RC6 | ||
23 | * o Wake-On-CIR functionality | 22 | * o Wake-On-CIR functionality |
24 | * | 23 | * |
25 | * To do: | 24 | * To do: |
26 | * o Test NEC and RC5 | 25 | * o Learning |
27 | * | 26 | * o IR Transmit |
28 | * Left as an exercise for the reader: | ||
29 | * o Learning (I have neither the hardware, nor the need) | ||
30 | * o IR Transmit (ibid) | ||
31 | * | 27 | * |
32 | * This program is free software; you can redistribute it and/or modify | 28 | * This program is free software; you can redistribute it and/or modify |
33 | * it under the terms of the GNU General Public License as published by | 29 | * it under the terms of the GNU General Public License as published by |
@@ -48,15 +44,13 @@ | |||
48 | #include <linux/pnp.h> | 44 | #include <linux/pnp.h> |
49 | #include <linux/interrupt.h> | 45 | #include <linux/interrupt.h> |
50 | #include <linux/timer.h> | 46 | #include <linux/timer.h> |
51 | #include <linux/input.h> | ||
52 | #include <linux/leds.h> | 47 | #include <linux/leds.h> |
53 | #include <linux/list.h> | ||
54 | #include <linux/spinlock.h> | 48 | #include <linux/spinlock.h> |
55 | #include <linux/pci_ids.h> | 49 | #include <linux/pci_ids.h> |
56 | #include <linux/io.h> | 50 | #include <linux/io.h> |
57 | #include <linux/bitrev.h> | 51 | #include <linux/bitrev.h> |
58 | #include <linux/bitops.h> | ||
59 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
53 | #include <media/ir-core.h> | ||
60 | 54 | ||
61 | #define DRVNAME "winbond-cir" | 55 | #define DRVNAME "winbond-cir" |
62 | 56 | ||
@@ -108,7 +102,7 @@ | |||
108 | #define WBCIR_REG_SP3_IRCR2 0x04 /* Infrared Control 2 */ | 102 | #define WBCIR_REG_SP3_IRCR2 0x04 /* Infrared Control 2 */ |
109 | /* Bank 6 */ | 103 | /* Bank 6 */ |
110 | #define WBCIR_REG_SP3_IRCR3 0x00 /* Infrared Control 3 */ | 104 | #define WBCIR_REG_SP3_IRCR3 0x00 /* Infrared Control 3 */ |
111 | #define WBCIR_REG_SP3_SIR_PW 0x02 /* SIR Pulse Width */ | 105 | #define WBCIR_REG_SP3_SIR_PW 0x02 /* SIR Pulse Width */ |
112 | /* Bank 7 */ | 106 | /* Bank 7 */ |
113 | #define WBCIR_REG_SP3_IRRXDC 0x00 /* IR RX Demod Control */ | 107 | #define WBCIR_REG_SP3_IRRXDC 0x00 /* IR RX Demod Control */ |
114 | #define WBCIR_REG_SP3_IRTXMC 0x01 /* IR TX Mod Control */ | 108 | #define WBCIR_REG_SP3_IRTXMC 0x01 /* IR TX Mod Control */ |
@@ -153,7 +147,7 @@ enum wbcir_bank { | |||
153 | WBCIR_BANK_7 = 0xF4, | 147 | WBCIR_BANK_7 = 0xF4, |
154 | }; | 148 | }; |
155 | 149 | ||
156 | /* Supported IR Protocols */ | 150 | /* Supported power-on IR Protocols */ |
157 | enum wbcir_protocol { | 151 | enum wbcir_protocol { |
158 | IR_PROTOCOL_RC5 = 0x0, | 152 | IR_PROTOCOL_RC5 = 0x0, |
159 | IR_PROTOCOL_NEC = 0x1, | 153 | IR_PROTOCOL_NEC = 0x1, |
@@ -164,113 +158,35 @@ enum wbcir_protocol { | |||
164 | #define WBCIR_NAME "Winbond CIR" | 158 | #define WBCIR_NAME "Winbond CIR" |
165 | #define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */ | 159 | #define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */ |
166 | #define WBCIR_ID_CHIP 0x04 /* Chip ID for the WPCD376I */ | 160 | #define WBCIR_ID_CHIP 0x04 /* Chip ID for the WPCD376I */ |
167 | #define IR_KEYPRESS_TIMEOUT 250 /* FIXME: should be per-protocol? */ | ||
168 | #define INVALID_SCANCODE 0x7FFFFFFF /* Invalid with all protos */ | 161 | #define INVALID_SCANCODE 0x7FFFFFFF /* Invalid with all protos */ |
169 | #define WAKEUP_IOMEM_LEN 0x10 /* Wake-Up I/O Reg Len */ | 162 | #define WAKEUP_IOMEM_LEN 0x10 /* Wake-Up I/O Reg Len */ |
170 | #define EHFUNC_IOMEM_LEN 0x10 /* Enhanced Func I/O Reg Len */ | 163 | #define EHFUNC_IOMEM_LEN 0x10 /* Enhanced Func I/O Reg Len */ |
171 | #define SP_IOMEM_LEN 0x08 /* Serial Port 3 (IR) Reg Len */ | 164 | #define SP_IOMEM_LEN 0x08 /* Serial Port 3 (IR) Reg Len */ |
172 | #define WBCIR_MAX_IDLE_BYTES 10 | ||
173 | |||
174 | static DEFINE_SPINLOCK(wbcir_lock); | ||
175 | static DEFINE_RWLOCK(keytable_lock); | ||
176 | 165 | ||
177 | struct wbcir_key { | 166 | /* Per-device data */ |
178 | u32 scancode; | ||
179 | unsigned int keycode; | ||
180 | }; | ||
181 | |||
182 | struct wbcir_keyentry { | ||
183 | struct wbcir_key key; | ||
184 | struct list_head list; | ||
185 | }; | ||
186 | |||
187 | static struct wbcir_key rc6_def_keymap[] = { | ||
188 | { 0x800F0400, KEY_NUMERIC_0 }, | ||
189 | { 0x800F0401, KEY_NUMERIC_1 }, | ||
190 | { 0x800F0402, KEY_NUMERIC_2 }, | ||
191 | { 0x800F0403, KEY_NUMERIC_3 }, | ||
192 | { 0x800F0404, KEY_NUMERIC_4 }, | ||
193 | { 0x800F0405, KEY_NUMERIC_5 }, | ||
194 | { 0x800F0406, KEY_NUMERIC_6 }, | ||
195 | { 0x800F0407, KEY_NUMERIC_7 }, | ||
196 | { 0x800F0408, KEY_NUMERIC_8 }, | ||
197 | { 0x800F0409, KEY_NUMERIC_9 }, | ||
198 | { 0x800F041D, KEY_NUMERIC_STAR }, | ||
199 | { 0x800F041C, KEY_NUMERIC_POUND }, | ||
200 | { 0x800F0410, KEY_VOLUMEUP }, | ||
201 | { 0x800F0411, KEY_VOLUMEDOWN }, | ||
202 | { 0x800F0412, KEY_CHANNELUP }, | ||
203 | { 0x800F0413, KEY_CHANNELDOWN }, | ||
204 | { 0x800F040E, KEY_MUTE }, | ||
205 | { 0x800F040D, KEY_VENDOR }, /* Vista Logo Key */ | ||
206 | { 0x800F041E, KEY_UP }, | ||
207 | { 0x800F041F, KEY_DOWN }, | ||
208 | { 0x800F0420, KEY_LEFT }, | ||
209 | { 0x800F0421, KEY_RIGHT }, | ||
210 | { 0x800F0422, KEY_OK }, | ||
211 | { 0x800F0423, KEY_ESC }, | ||
212 | { 0x800F040F, KEY_INFO }, | ||
213 | { 0x800F040A, KEY_CLEAR }, | ||
214 | { 0x800F040B, KEY_ENTER }, | ||
215 | { 0x800F045B, KEY_RED }, | ||
216 | { 0x800F045C, KEY_GREEN }, | ||
217 | { 0x800F045D, KEY_YELLOW }, | ||
218 | { 0x800F045E, KEY_BLUE }, | ||
219 | { 0x800F045A, KEY_TEXT }, | ||
220 | { 0x800F0427, KEY_SWITCHVIDEOMODE }, | ||
221 | { 0x800F040C, KEY_POWER }, | ||
222 | { 0x800F0450, KEY_RADIO }, | ||
223 | { 0x800F0448, KEY_PVR }, | ||
224 | { 0x800F0447, KEY_AUDIO }, | ||
225 | { 0x800F0426, KEY_EPG }, | ||
226 | { 0x800F0449, KEY_CAMERA }, | ||
227 | { 0x800F0425, KEY_TV }, | ||
228 | { 0x800F044A, KEY_VIDEO }, | ||
229 | { 0x800F0424, KEY_DVD }, | ||
230 | { 0x800F0416, KEY_PLAY }, | ||
231 | { 0x800F0418, KEY_PAUSE }, | ||
232 | { 0x800F0419, KEY_STOP }, | ||
233 | { 0x800F0414, KEY_FASTFORWARD }, | ||
234 | { 0x800F041A, KEY_NEXT }, | ||
235 | { 0x800F041B, KEY_PREVIOUS }, | ||
236 | { 0x800F0415, KEY_REWIND }, | ||
237 | { 0x800F0417, KEY_RECORD }, | ||
238 | }; | ||
239 | |||
240 | /* Registers and other state is protected by wbcir_lock */ | ||
241 | struct wbcir_data { | 167 | struct wbcir_data { |
168 | spinlock_t spinlock; | ||
169 | |||
242 | unsigned long wbase; /* Wake-Up Baseaddr */ | 170 | unsigned long wbase; /* Wake-Up Baseaddr */ |
243 | unsigned long ebase; /* Enhanced Func. Baseaddr */ | 171 | unsigned long ebase; /* Enhanced Func. Baseaddr */ |
244 | unsigned long sbase; /* Serial Port Baseaddr */ | 172 | unsigned long sbase; /* Serial Port Baseaddr */ |
245 | unsigned int irq; /* Serial Port IRQ */ | 173 | unsigned int irq; /* Serial Port IRQ */ |
246 | 174 | ||
247 | struct input_dev *input_dev; | 175 | struct rc_dev *dev; |
248 | struct timer_list timer_keyup; | 176 | |
249 | struct led_trigger *rxtrigger; | 177 | struct led_trigger *rxtrigger; |
250 | struct led_trigger *txtrigger; | 178 | struct led_trigger *txtrigger; |
251 | struct led_classdev led; | 179 | struct led_classdev led; |
252 | 180 | ||
253 | u32 last_scancode; | 181 | /* RX irdata state */ |
254 | unsigned int last_keycode; | 182 | bool irdata_active; |
255 | u8 last_toggle; | 183 | bool irdata_error; |
256 | u8 keypressed; | 184 | struct ir_raw_event ev; |
257 | unsigned long keyup_jiffies; | ||
258 | unsigned int idle_count; | ||
259 | |||
260 | /* RX irdata and parsing state */ | ||
261 | unsigned long irdata[30]; | ||
262 | unsigned int irdata_count; | ||
263 | unsigned int irdata_idle; | ||
264 | unsigned int irdata_off; | ||
265 | unsigned int irdata_error; | ||
266 | |||
267 | /* Protected by keytable_lock */ | ||
268 | struct list_head keytable; | ||
269 | }; | 185 | }; |
270 | 186 | ||
271 | static enum wbcir_protocol protocol = IR_PROTOCOL_RC6; | 187 | static enum wbcir_protocol protocol = IR_PROTOCOL_RC6; |
272 | module_param(protocol, uint, 0444); | 188 | module_param(protocol, uint, 0444); |
273 | MODULE_PARM_DESC(protocol, "IR protocol to use " | 189 | MODULE_PARM_DESC(protocol, "IR protocol to use for the power-on command " |
274 | "(0 = RC5, 1 = NEC, 2 = RC6A, default)"); | 190 | "(0 = RC5, 1 = NEC, 2 = RC6A, default)"); |
275 | 191 | ||
276 | static int invert; /* default = 0 */ | 192 | static int invert; /* default = 0 */ |
@@ -327,7 +243,7 @@ wbcir_led_brightness_get(struct led_classdev *led_cdev) | |||
327 | 243 | ||
328 | static void | 244 | static void |
329 | wbcir_led_brightness_set(struct led_classdev *led_cdev, | 245 | wbcir_led_brightness_set(struct led_classdev *led_cdev, |
330 | enum led_brightness brightness) | 246 | enum led_brightness brightness) |
331 | { | 247 | { |
332 | struct wbcir_data *data = container_of(led_cdev, | 248 | struct wbcir_data *data = container_of(led_cdev, |
333 | struct wbcir_data, | 249 | struct wbcir_data, |
@@ -338,7 +254,7 @@ wbcir_led_brightness_set(struct led_classdev *led_cdev, | |||
338 | WBCIR_LED_ENABLE); | 254 | WBCIR_LED_ENABLE); |
339 | } | 255 | } |
340 | 256 | ||
341 | /* Manchester encodes bits to RC6 message cells (see wbcir_parse_rc6) */ | 257 | /* Manchester encodes bits to RC6 message cells (see wbcir_shutdown) */ |
342 | static u8 | 258 | static u8 |
343 | wbcir_to_rc6cells(u8 val) | 259 | wbcir_to_rc6cells(u8 val) |
344 | { | 260 | { |
@@ -357,579 +273,6 @@ wbcir_to_rc6cells(u8 val) | |||
357 | return coded; | 273 | return coded; |
358 | } | 274 | } |
359 | 275 | ||
360 | |||
361 | |||
362 | /***************************************************************************** | ||
363 | * | ||
364 | * INPUT FUNCTIONS | ||
365 | * | ||
366 | *****************************************************************************/ | ||
367 | |||
368 | static unsigned int | ||
369 | wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode) | ||
370 | { | ||
371 | struct wbcir_keyentry *keyentry; | ||
372 | unsigned int keycode = KEY_RESERVED; | ||
373 | unsigned long flags; | ||
374 | |||
375 | read_lock_irqsave(&keytable_lock, flags); | ||
376 | |||
377 | list_for_each_entry(keyentry, &data->keytable, list) { | ||
378 | if (keyentry->key.scancode == scancode) { | ||
379 | keycode = keyentry->key.keycode; | ||
380 | break; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | read_unlock_irqrestore(&keytable_lock, flags); | ||
385 | return keycode; | ||
386 | } | ||
387 | |||
388 | static int | ||
389 | wbcir_getkeycode(struct input_dev *dev, | ||
390 | unsigned int scancode, unsigned int *keycode) | ||
391 | { | ||
392 | struct wbcir_data *data = input_get_drvdata(dev); | ||
393 | |||
394 | *keycode = wbcir_do_getkeycode(data, scancode); | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int | ||
399 | wbcir_setkeycode(struct input_dev *dev, | ||
400 | unsigned int scancode, unsigned int keycode) | ||
401 | { | ||
402 | struct wbcir_data *data = input_get_drvdata(dev); | ||
403 | struct wbcir_keyentry *keyentry; | ||
404 | struct wbcir_keyentry *new_keyentry; | ||
405 | unsigned long flags; | ||
406 | unsigned int old_keycode = KEY_RESERVED; | ||
407 | |||
408 | new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); | ||
409 | if (!new_keyentry) | ||
410 | return -ENOMEM; | ||
411 | |||
412 | write_lock_irqsave(&keytable_lock, flags); | ||
413 | |||
414 | list_for_each_entry(keyentry, &data->keytable, list) { | ||
415 | if (keyentry->key.scancode != scancode) | ||
416 | continue; | ||
417 | |||
418 | old_keycode = keyentry->key.keycode; | ||
419 | keyentry->key.keycode = keycode; | ||
420 | |||
421 | if (keyentry->key.keycode == KEY_RESERVED) { | ||
422 | list_del(&keyentry->list); | ||
423 | kfree(keyentry); | ||
424 | } | ||
425 | |||
426 | break; | ||
427 | } | ||
428 | |||
429 | set_bit(keycode, dev->keybit); | ||
430 | |||
431 | if (old_keycode == KEY_RESERVED) { | ||
432 | new_keyentry->key.scancode = scancode; | ||
433 | new_keyentry->key.keycode = keycode; | ||
434 | list_add(&new_keyentry->list, &data->keytable); | ||
435 | } else { | ||
436 | kfree(new_keyentry); | ||
437 | clear_bit(old_keycode, dev->keybit); | ||
438 | list_for_each_entry(keyentry, &data->keytable, list) { | ||
439 | if (keyentry->key.keycode == old_keycode) { | ||
440 | set_bit(old_keycode, dev->keybit); | ||
441 | break; | ||
442 | } | ||
443 | } | ||
444 | } | ||
445 | |||
446 | write_unlock_irqrestore(&keytable_lock, flags); | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | /* | ||
451 | * Timer function to report keyup event some time after keydown is | ||
452 | * reported by the ISR. | ||
453 | */ | ||
454 | static void | ||
455 | wbcir_keyup(unsigned long cookie) | ||
456 | { | ||
457 | struct wbcir_data *data = (struct wbcir_data *)cookie; | ||
458 | unsigned long flags; | ||
459 | |||
460 | /* | ||
461 | * data->keyup_jiffies is used to prevent a race condition if a | ||
462 | * hardware interrupt occurs at this point and the keyup timer | ||
463 | * event is moved further into the future as a result. | ||
464 | * | ||
465 | * The timer will then be reactivated and this function called | ||
466 | * again in the future. We need to exit gracefully in that case | ||
467 | * to allow the input subsystem to do its auto-repeat magic or | ||
468 | * a keyup event might follow immediately after the keydown. | ||
469 | */ | ||
470 | |||
471 | spin_lock_irqsave(&wbcir_lock, flags); | ||
472 | |||
473 | if (time_is_after_eq_jiffies(data->keyup_jiffies) && data->keypressed) { | ||
474 | data->keypressed = 0; | ||
475 | led_trigger_event(data->rxtrigger, LED_OFF); | ||
476 | input_report_key(data->input_dev, data->last_keycode, 0); | ||
477 | input_sync(data->input_dev); | ||
478 | } | ||
479 | |||
480 | spin_unlock_irqrestore(&wbcir_lock, flags); | ||
481 | } | ||
482 | |||
483 | static void | ||
484 | wbcir_keydown(struct wbcir_data *data, u32 scancode, u8 toggle) | ||
485 | { | ||
486 | unsigned int keycode; | ||
487 | |||
488 | /* Repeat? */ | ||
489 | if (data->last_scancode == scancode && | ||
490 | data->last_toggle == toggle && | ||
491 | data->keypressed) | ||
492 | goto set_timer; | ||
493 | data->last_scancode = scancode; | ||
494 | |||
495 | /* Do we need to release an old keypress? */ | ||
496 | if (data->keypressed) { | ||
497 | input_report_key(data->input_dev, data->last_keycode, 0); | ||
498 | input_sync(data->input_dev); | ||
499 | data->keypressed = 0; | ||
500 | } | ||
501 | |||
502 | /* Report scancode */ | ||
503 | input_event(data->input_dev, EV_MSC, MSC_SCAN, (int)scancode); | ||
504 | |||
505 | /* Do we know this scancode? */ | ||
506 | keycode = wbcir_do_getkeycode(data, scancode); | ||
507 | if (keycode == KEY_RESERVED) | ||
508 | goto set_timer; | ||
509 | |||
510 | /* Register a keypress */ | ||
511 | input_report_key(data->input_dev, keycode, 1); | ||
512 | data->keypressed = 1; | ||
513 | data->last_keycode = keycode; | ||
514 | data->last_toggle = toggle; | ||
515 | |||
516 | set_timer: | ||
517 | input_sync(data->input_dev); | ||
518 | led_trigger_event(data->rxtrigger, | ||
519 | data->keypressed ? LED_FULL : LED_OFF); | ||
520 | data->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); | ||
521 | mod_timer(&data->timer_keyup, data->keyup_jiffies); | ||
522 | } | ||
523 | |||
524 | |||
525 | |||
526 | /***************************************************************************** | ||
527 | * | ||
528 | * IR PARSING FUNCTIONS | ||
529 | * | ||
530 | *****************************************************************************/ | ||
531 | |||
532 | /* Resets all irdata */ | ||
533 | static void | ||
534 | wbcir_reset_irdata(struct wbcir_data *data) | ||
535 | { | ||
536 | memset(data->irdata, 0, sizeof(data->irdata)); | ||
537 | data->irdata_count = 0; | ||
538 | data->irdata_off = 0; | ||
539 | data->irdata_error = 0; | ||
540 | data->idle_count = 0; | ||
541 | } | ||
542 | |||
543 | /* Adds one bit of irdata */ | ||
544 | static void | ||
545 | add_irdata_bit(struct wbcir_data *data, int set) | ||
546 | { | ||
547 | if (data->irdata_count >= sizeof(data->irdata) * 8) { | ||
548 | data->irdata_error = 1; | ||
549 | return; | ||
550 | } | ||
551 | |||
552 | if (set) | ||
553 | __set_bit(data->irdata_count, data->irdata); | ||
554 | data->irdata_count++; | ||
555 | } | ||
556 | |||
557 | /* Gets count bits of irdata */ | ||
558 | static u16 | ||
559 | get_bits(struct wbcir_data *data, int count) | ||
560 | { | ||
561 | u16 val = 0x0; | ||
562 | |||
563 | if (data->irdata_count - data->irdata_off < count) { | ||
564 | data->irdata_error = 1; | ||
565 | return 0x0; | ||
566 | } | ||
567 | |||
568 | while (count > 0) { | ||
569 | val <<= 1; | ||
570 | if (test_bit(data->irdata_off, data->irdata)) | ||
571 | val |= 0x1; | ||
572 | count--; | ||
573 | data->irdata_off++; | ||
574 | } | ||
575 | |||
576 | return val; | ||
577 | } | ||
578 | |||
579 | /* Reads 16 cells and converts them to a byte */ | ||
580 | static u8 | ||
581 | wbcir_rc6cells_to_byte(struct wbcir_data *data) | ||
582 | { | ||
583 | u16 raw = get_bits(data, 16); | ||
584 | u8 val = 0x00; | ||
585 | int bit; | ||
586 | |||
587 | for (bit = 0; bit < 8; bit++) { | ||
588 | switch (raw & 0x03) { | ||
589 | case 0x01: | ||
590 | break; | ||
591 | case 0x02: | ||
592 | val |= (0x01 << bit); | ||
593 | break; | ||
594 | default: | ||
595 | data->irdata_error = 1; | ||
596 | break; | ||
597 | } | ||
598 | raw >>= 2; | ||
599 | } | ||
600 | |||
601 | return val; | ||
602 | } | ||
603 | |||
604 | /* Decodes a number of bits from raw RC5 data */ | ||
605 | static u8 | ||
606 | wbcir_get_rc5bits(struct wbcir_data *data, unsigned int count) | ||
607 | { | ||
608 | u16 raw = get_bits(data, count * 2); | ||
609 | u8 val = 0x00; | ||
610 | int bit; | ||
611 | |||
612 | for (bit = 0; bit < count; bit++) { | ||
613 | switch (raw & 0x03) { | ||
614 | case 0x01: | ||
615 | val |= (0x01 << bit); | ||
616 | break; | ||
617 | case 0x02: | ||
618 | break; | ||
619 | default: | ||
620 | data->irdata_error = 1; | ||
621 | break; | ||
622 | } | ||
623 | raw >>= 2; | ||
624 | } | ||
625 | |||
626 | return val; | ||
627 | } | ||
628 | |||
629 | static void | ||
630 | wbcir_parse_rc6(struct device *dev, struct wbcir_data *data) | ||
631 | { | ||
632 | /* | ||
633 | * Normal bits are manchester coded as follows: | ||
634 | * cell0 + cell1 = logic "0" | ||
635 | * cell1 + cell0 = logic "1" | ||
636 | * | ||
637 | * The IR pulse has the following components: | ||
638 | * | ||
639 | * Leader - 6 * cell1 - discarded | ||
640 | * Gap - 2 * cell0 - discarded | ||
641 | * Start bit - Normal Coding - always "1" | ||
642 | * Mode Bit 2 - 0 - Normal Coding | ||
643 | * Toggle bit - Normal Coding with double bit time, | ||
644 | * e.g. cell0 + cell0 + cell1 + cell1 | ||
645 | * means logic "0". | ||
646 | * | ||
647 | * The rest depends on the mode, the following modes are known: | ||
648 | * | ||
649 | * MODE 0: | ||
650 | * Address Bit 7 - 0 - Normal Coding | ||
651 | * Command Bit 7 - 0 - Normal Coding | ||
652 | * | ||
653 | * MODE 6: | ||
654 | * The above Toggle Bit is used as a submode bit, 0 = A, 1 = B. | ||
655 | * Submode B is for pointing devices, only remotes using submode A | ||
656 | * are supported. | ||
657 | * | ||
658 | * Customer range bit - 0 => Customer = 7 bits, 0...127 | ||
659 | * 1 => Customer = 15 bits, 32768...65535 | ||
660 | * Customer Bits - Normal Coding | ||
661 | * | ||
662 | * Customer codes are allocated by Philips. The rest of the bits | ||
663 | * are customer dependent. The following is commonly used (and the | ||
664 | * only supported config): | ||
665 | * | ||
666 | * Toggle Bit - Normal Coding | ||
667 | * Address Bit 6 - 0 - Normal Coding | ||
668 | * Command Bit 7 - 0 - Normal Coding | ||
669 | * | ||
670 | * All modes are followed by at least 6 * cell0. | ||
671 | * | ||
672 | * MODE 0 msglen: | ||
673 | * 1 * 2 (start bit) + 3 * 2 (mode) + 2 * 2 (toggle) + | ||
674 | * 8 * 2 (address) + 8 * 2 (command) = | ||
675 | * 44 cells | ||
676 | * | ||
677 | * MODE 6A msglen: | ||
678 | * 1 * 2 (start bit) + 3 * 2 (mode) + 2 * 2 (submode) + | ||
679 | * 1 * 2 (customer range bit) + 7/15 * 2 (customer bits) + | ||
680 | * 1 * 2 (toggle bit) + 7 * 2 (address) + 8 * 2 (command) = | ||
681 | * 60 - 76 cells | ||
682 | */ | ||
683 | u8 mode; | ||
684 | u8 toggle; | ||
685 | u16 customer = 0x0; | ||
686 | u8 address; | ||
687 | u8 command; | ||
688 | u32 scancode; | ||
689 | |||
690 | /* Leader mark */ | ||
691 | while (get_bits(data, 1) && !data->irdata_error) | ||
692 | /* Do nothing */; | ||
693 | |||
694 | /* Leader space */ | ||
695 | if (get_bits(data, 1)) { | ||
696 | dev_dbg(dev, "RC6 - Invalid leader space\n"); | ||
697 | return; | ||
698 | } | ||
699 | |||
700 | /* Start bit */ | ||
701 | if (get_bits(data, 2) != 0x02) { | ||
702 | dev_dbg(dev, "RC6 - Invalid start bit\n"); | ||
703 | return; | ||
704 | } | ||
705 | |||
706 | /* Mode */ | ||
707 | mode = get_bits(data, 6); | ||
708 | switch (mode) { | ||
709 | case 0x15: /* 010101 = b000 */ | ||
710 | mode = 0; | ||
711 | break; | ||
712 | case 0x29: /* 101001 = b110 */ | ||
713 | mode = 6; | ||
714 | break; | ||
715 | default: | ||
716 | dev_dbg(dev, "RC6 - Invalid mode\n"); | ||
717 | return; | ||
718 | } | ||
719 | |||
720 | /* Toggle bit / Submode bit */ | ||
721 | toggle = get_bits(data, 4); | ||
722 | switch (toggle) { | ||
723 | case 0x03: | ||
724 | toggle = 0; | ||
725 | break; | ||
726 | case 0x0C: | ||
727 | toggle = 1; | ||
728 | break; | ||
729 | default: | ||
730 | dev_dbg(dev, "RC6 - Toggle bit error\n"); | ||
731 | break; | ||
732 | } | ||
733 | |||
734 | /* Customer */ | ||
735 | if (mode == 6) { | ||
736 | if (toggle != 0) { | ||
737 | dev_dbg(dev, "RC6B - Not Supported\n"); | ||
738 | return; | ||
739 | } | ||
740 | |||
741 | customer = wbcir_rc6cells_to_byte(data); | ||
742 | |||
743 | if (customer & 0x80) { | ||
744 | /* 15 bit customer value */ | ||
745 | customer <<= 8; | ||
746 | customer |= wbcir_rc6cells_to_byte(data); | ||
747 | } | ||
748 | } | ||
749 | |||
750 | /* Address */ | ||
751 | address = wbcir_rc6cells_to_byte(data); | ||
752 | if (mode == 6) { | ||
753 | toggle = address >> 7; | ||
754 | address &= 0x7F; | ||
755 | } | ||
756 | |||
757 | /* Command */ | ||
758 | command = wbcir_rc6cells_to_byte(data); | ||
759 | |||
760 | /* Create scancode */ | ||
761 | scancode = command; | ||
762 | scancode |= address << 8; | ||
763 | scancode |= customer << 16; | ||
764 | |||
765 | /* Last sanity check */ | ||
766 | if (data->irdata_error) { | ||
767 | dev_dbg(dev, "RC6 - Cell error(s)\n"); | ||
768 | return; | ||
769 | } | ||
770 | |||
771 | dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X " | ||
772 | "toggle %u mode %u scan 0x%08X\n", | ||
773 | address, | ||
774 | command, | ||
775 | customer, | ||
776 | (unsigned int)toggle, | ||
777 | (unsigned int)mode, | ||
778 | scancode); | ||
779 | |||
780 | wbcir_keydown(data, scancode, toggle); | ||
781 | } | ||
782 | |||
783 | static void | ||
784 | wbcir_parse_rc5(struct device *dev, struct wbcir_data *data) | ||
785 | { | ||
786 | /* | ||
787 | * Bits are manchester coded as follows: | ||
788 | * cell1 + cell0 = logic "0" | ||
789 | * cell0 + cell1 = logic "1" | ||
790 | * (i.e. the reverse of RC6) | ||
791 | * | ||
792 | * Start bit 1 - "1" - discarded | ||
793 | * Start bit 2 - Must be inverted to get command bit 6 | ||
794 | * Toggle bit | ||
795 | * Address Bit 4 - 0 | ||
796 | * Command Bit 5 - 0 | ||
797 | */ | ||
798 | u8 toggle; | ||
799 | u8 address; | ||
800 | u8 command; | ||
801 | u32 scancode; | ||
802 | |||
803 | /* Start bit 1 */ | ||
804 | if (!get_bits(data, 1)) { | ||
805 | dev_dbg(dev, "RC5 - Invalid start bit\n"); | ||
806 | return; | ||
807 | } | ||
808 | |||
809 | /* Start bit 2 */ | ||
810 | if (!wbcir_get_rc5bits(data, 1)) | ||
811 | command = 0x40; | ||
812 | else | ||
813 | command = 0x00; | ||
814 | |||
815 | toggle = wbcir_get_rc5bits(data, 1); | ||
816 | address = wbcir_get_rc5bits(data, 5); | ||
817 | command |= wbcir_get_rc5bits(data, 6); | ||
818 | scancode = address << 7 | command; | ||
819 | |||
820 | /* Last sanity check */ | ||
821 | if (data->irdata_error) { | ||
822 | dev_dbg(dev, "RC5 - Invalid message\n"); | ||
823 | return; | ||
824 | } | ||
825 | |||
826 | dev_dbg(dev, "IR-RC5 ad %u cm %u t %u s %u\n", | ||
827 | (unsigned int)address, | ||
828 | (unsigned int)command, | ||
829 | (unsigned int)toggle, | ||
830 | (unsigned int)scancode); | ||
831 | |||
832 | wbcir_keydown(data, scancode, toggle); | ||
833 | } | ||
834 | |||
835 | static void | ||
836 | wbcir_parse_nec(struct device *dev, struct wbcir_data *data) | ||
837 | { | ||
838 | /* | ||
839 | * Each bit represents 560 us. | ||
840 | * | ||
841 | * Leader - 9 ms burst | ||
842 | * Gap - 4.5 ms silence | ||
843 | * Address1 bit 0 - 7 - Address 1 | ||
844 | * Address2 bit 0 - 7 - Address 2 | ||
845 | * Command1 bit 0 - 7 - Command 1 | ||
846 | * Command2 bit 0 - 7 - Command 2 | ||
847 | * | ||
848 | * Note the bit order! | ||
849 | * | ||
850 | * With the old NEC protocol, Address2 was the inverse of Address1 | ||
851 | * and Command2 was the inverse of Command1 and were used as | ||
852 | * an error check. | ||
853 | * | ||
854 | * With NEC extended, Address1 is the LSB of the Address and | ||
855 | * Address2 is the MSB, Command parsing remains unchanged. | ||
856 | * | ||
857 | * A repeat message is coded as: | ||
858 | * Leader - 9 ms burst | ||
859 | * Gap - 2.25 ms silence | ||
860 | * Repeat - 560 us active | ||
861 | */ | ||
862 | u8 address1; | ||
863 | u8 address2; | ||
864 | u8 command1; | ||
865 | u8 command2; | ||
866 | u16 address; | ||
867 | u32 scancode; | ||
868 | |||
869 | /* Leader mark */ | ||
870 | while (get_bits(data, 1) && !data->irdata_error) | ||
871 | /* Do nothing */; | ||
872 | |||
873 | /* Leader space */ | ||
874 | if (get_bits(data, 4)) { | ||
875 | dev_dbg(dev, "NEC - Invalid leader space\n"); | ||
876 | return; | ||
877 | } | ||
878 | |||
879 | /* Repeat? */ | ||
880 | if (get_bits(data, 1)) { | ||
881 | if (!data->keypressed) { | ||
882 | dev_dbg(dev, "NEC - Stray repeat message\n"); | ||
883 | return; | ||
884 | } | ||
885 | |||
886 | dev_dbg(dev, "IR-NEC repeat s %u\n", | ||
887 | (unsigned int)data->last_scancode); | ||
888 | |||
889 | wbcir_keydown(data, data->last_scancode, data->last_toggle); | ||
890 | return; | ||
891 | } | ||
892 | |||
893 | /* Remaining leader space */ | ||
894 | if (get_bits(data, 3)) { | ||
895 | dev_dbg(dev, "NEC - Invalid leader space\n"); | ||
896 | return; | ||
897 | } | ||
898 | |||
899 | address1 = bitrev8(get_bits(data, 8)); | ||
900 | address2 = bitrev8(get_bits(data, 8)); | ||
901 | command1 = bitrev8(get_bits(data, 8)); | ||
902 | command2 = bitrev8(get_bits(data, 8)); | ||
903 | |||
904 | /* Sanity check */ | ||
905 | if (data->irdata_error) { | ||
906 | dev_dbg(dev, "NEC - Invalid message\n"); | ||
907 | return; | ||
908 | } | ||
909 | |||
910 | /* Check command validity */ | ||
911 | if (command1 != ~command2) { | ||
912 | dev_dbg(dev, "NEC - Command bytes mismatch\n"); | ||
913 | return; | ||
914 | } | ||
915 | |||
916 | /* Check for extended NEC protocol */ | ||
917 | address = address1; | ||
918 | if (address1 != ~address2) | ||
919 | address |= address2 << 8; | ||
920 | |||
921 | scancode = address << 8 | command1; | ||
922 | |||
923 | dev_dbg(dev, "IR-NEC ad %u cm %u s %u\n", | ||
924 | (unsigned int)address, | ||
925 | (unsigned int)command1, | ||
926 | (unsigned int)scancode); | ||
927 | |||
928 | wbcir_keydown(data, scancode, !data->last_toggle); | ||
929 | } | ||
930 | |||
931 | |||
932 | |||
933 | /***************************************************************************** | 276 | /***************************************************************************** |
934 | * | 277 | * |
935 | * INTERRUPT FUNCTIONS | 278 | * INTERRUPT FUNCTIONS |
@@ -941,75 +284,88 @@ wbcir_irq_handler(int irqno, void *cookie) | |||
941 | { | 284 | { |
942 | struct pnp_dev *device = cookie; | 285 | struct pnp_dev *device = cookie; |
943 | struct wbcir_data *data = pnp_get_drvdata(device); | 286 | struct wbcir_data *data = pnp_get_drvdata(device); |
944 | struct device *dev = &device->dev; | ||
945 | u8 status; | ||
946 | unsigned long flags; | 287 | unsigned long flags; |
947 | u8 irdata[8]; | 288 | u8 irdata[8]; |
289 | u8 disable = true; | ||
290 | u8 status; | ||
948 | int i; | 291 | int i; |
949 | unsigned int hw; | ||
950 | 292 | ||
951 | spin_lock_irqsave(&wbcir_lock, flags); | 293 | spin_lock_irqsave(&data->spinlock, flags); |
952 | 294 | ||
953 | wbcir_select_bank(data, WBCIR_BANK_0); | 295 | wbcir_select_bank(data, WBCIR_BANK_0); |
954 | 296 | ||
955 | status = inb(data->sbase + WBCIR_REG_SP3_EIR); | 297 | status = inb(data->sbase + WBCIR_REG_SP3_EIR); |
956 | 298 | ||
957 | if (!(status & (WBCIR_IRQ_RX | WBCIR_IRQ_ERR))) { | 299 | if (!(status & (WBCIR_IRQ_RX | WBCIR_IRQ_ERR))) { |
958 | spin_unlock_irqrestore(&wbcir_lock, flags); | 300 | spin_unlock_irqrestore(&data->spinlock, flags); |
959 | return IRQ_NONE; | 301 | return IRQ_NONE; |
960 | } | 302 | } |
961 | 303 | ||
962 | if (status & WBCIR_IRQ_ERR) | 304 | /* Check for e.g. buffer overflow */ |
963 | data->irdata_error = 1; | 305 | if (status & WBCIR_IRQ_ERR) { |
306 | data->irdata_error = true; | ||
307 | ir_raw_event_reset(data->dev); | ||
308 | } | ||
964 | 309 | ||
965 | if (!(status & WBCIR_IRQ_RX)) | 310 | if (!(status & WBCIR_IRQ_RX)) |
966 | goto out; | 311 | goto out; |
967 | 312 | ||
313 | if (!data->irdata_active) { | ||
314 | data->irdata_active = true; | ||
315 | led_trigger_event(data->rxtrigger, LED_FULL); | ||
316 | } | ||
317 | |||
968 | /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ | 318 | /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ |
969 | insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[0], 8); | 319 | insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[0], 8); |
970 | 320 | ||
971 | for (i = 0; i < sizeof(irdata); i++) { | 321 | for (i = 0; i < 8; i++) { |
972 | hw = hweight8(irdata[i]); | 322 | u8 pulse; |
973 | if (hw > 4) | 323 | u32 duration; |
974 | add_irdata_bit(data, 0); | ||
975 | else | ||
976 | add_irdata_bit(data, 1); | ||
977 | 324 | ||
978 | if (hw == 8) | 325 | if (irdata[i] != 0xFF && irdata[i] != 0x00) |
979 | data->idle_count++; | 326 | disable = false; |
980 | else | 327 | |
981 | data->idle_count = 0; | 328 | if (data->irdata_error) |
329 | continue; | ||
330 | |||
331 | pulse = irdata[i] & 0x80 ? false : true; | ||
332 | duration = (irdata[i] & 0x7F) * 10000; /* ns */ | ||
333 | |||
334 | if (data->ev.pulse != pulse) { | ||
335 | if (data->ev.duration != 0) { | ||
336 | ir_raw_event_store(data->dev, &data->ev); | ||
337 | data->ev.duration = 0; | ||
338 | } | ||
339 | |||
340 | data->ev.pulse = pulse; | ||
341 | } | ||
342 | |||
343 | data->ev.duration += duration; | ||
982 | } | 344 | } |
983 | 345 | ||
984 | if (data->idle_count > WBCIR_MAX_IDLE_BYTES) { | 346 | if (disable) { |
985 | /* Set RXINACTIVE... */ | 347 | if (data->ev.duration != 0 && !data->irdata_error) { |
348 | ir_raw_event_store(data->dev, &data->ev); | ||
349 | data->ev.duration = 0; | ||
350 | } | ||
351 | |||
352 | /* Set RXINACTIVE */ | ||
986 | outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR); | 353 | outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR); |
987 | 354 | ||
988 | /* ...and drain the FIFO */ | 355 | /* Drain the FIFO */ |
989 | while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) | 356 | while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) |
990 | inb(data->sbase + WBCIR_REG_SP3_RXDATA); | 357 | inb(data->sbase + WBCIR_REG_SP3_RXDATA); |
991 | 358 | ||
992 | dev_dbg(dev, "IRDATA:\n"); | 359 | ir_raw_event_reset(data->dev); |
993 | for (i = 0; i < data->irdata_count; i += BITS_PER_LONG) | 360 | data->irdata_error = false; |
994 | dev_dbg(dev, "0x%08lX\n", data->irdata[i/BITS_PER_LONG]); | 361 | data->irdata_active = false; |
995 | 362 | led_trigger_event(data->rxtrigger, LED_OFF); | |
996 | switch (protocol) { | ||
997 | case IR_PROTOCOL_RC5: | ||
998 | wbcir_parse_rc5(dev, data); | ||
999 | break; | ||
1000 | case IR_PROTOCOL_RC6: | ||
1001 | wbcir_parse_rc6(dev, data); | ||
1002 | break; | ||
1003 | case IR_PROTOCOL_NEC: | ||
1004 | wbcir_parse_nec(dev, data); | ||
1005 | break; | ||
1006 | } | ||
1007 | |||
1008 | wbcir_reset_irdata(data); | ||
1009 | } | 363 | } |
1010 | 364 | ||
365 | ir_raw_event_handle(data->dev); | ||
366 | |||
1011 | out: | 367 | out: |
1012 | spin_unlock_irqrestore(&wbcir_lock, flags); | 368 | spin_unlock_irqrestore(&data->spinlock, flags); |
1013 | return IRQ_HANDLED; | 369 | return IRQ_HANDLED; |
1014 | } | 370 | } |
1015 | 371 | ||
@@ -1199,6 +555,10 @@ finish: | |||
1199 | wbcir_select_bank(data, WBCIR_BANK_0); | 555 | wbcir_select_bank(data, WBCIR_BANK_0); |
1200 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | 556 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); |
1201 | 557 | ||
558 | /* Disable LED */ | ||
559 | data->irdata_active = false; | ||
560 | led_trigger_event(data->rxtrigger, LED_OFF); | ||
561 | |||
1202 | /* | 562 | /* |
1203 | * ACPI will set the HW disable bit for SP3 which means that the | 563 | * ACPI will set the HW disable bit for SP3 which means that the |
1204 | * output signals are left in an undefined state which may cause | 564 | * output signals are left in an undefined state which may cause |
@@ -1323,8 +683,15 @@ wbcir_init_hw(struct wbcir_data *data) | |||
1323 | /* Clear AUX status bits */ | 683 | /* Clear AUX status bits */ |
1324 | outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); | 684 | outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); |
1325 | 685 | ||
686 | /* Clear IR decoding state */ | ||
687 | data->irdata_active = false; | ||
688 | led_trigger_event(data->rxtrigger, LED_OFF); | ||
689 | data->irdata_error = false; | ||
690 | data->ev.duration = 0; | ||
691 | ir_raw_event_reset(data->dev); | ||
692 | ir_raw_event_handle(data->dev); | ||
693 | |||
1326 | /* Enable interrupts */ | 694 | /* Enable interrupts */ |
1327 | wbcir_reset_irdata(data); | ||
1328 | outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); | 695 | outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); |
1329 | } | 696 | } |
1330 | 697 | ||
@@ -1361,6 +728,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) | |||
1361 | 728 | ||
1362 | pnp_set_drvdata(device, data); | 729 | pnp_set_drvdata(device, data); |
1363 | 730 | ||
731 | spin_lock_init(&data->spinlock); | ||
1364 | data->ebase = pnp_port_start(device, 0); | 732 | data->ebase = pnp_port_start(device, 0); |
1365 | data->wbase = pnp_port_start(device, 1); | 733 | data->wbase = pnp_port_start(device, 1); |
1366 | data->sbase = pnp_port_start(device, 2); | 734 | data->sbase = pnp_port_start(device, 2); |
@@ -1426,43 +794,25 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) | |||
1426 | if (err) | 794 | if (err) |
1427 | goto exit_unregister_rxtrigger; | 795 | goto exit_unregister_rxtrigger; |
1428 | 796 | ||
1429 | data->input_dev = input_allocate_device(); | 797 | data->dev = rc_allocate_device(); |
1430 | if (!data->input_dev) { | 798 | if (!data->dev) { |
1431 | err = -ENOMEM; | 799 | err = -ENOMEM; |
1432 | goto exit_unregister_led; | 800 | goto exit_unregister_led; |
1433 | } | 801 | } |
1434 | 802 | ||
1435 | data->input_dev->evbit[0] = BIT(EV_KEY); | 803 | data->dev->driver_name = WBCIR_NAME; |
1436 | data->input_dev->name = WBCIR_NAME; | 804 | data->dev->input_name = WBCIR_NAME; |
1437 | data->input_dev->phys = "wbcir/cir0"; | 805 | data->dev->input_phys = "wbcir/cir0"; |
1438 | data->input_dev->id.bustype = BUS_HOST; | 806 | data->dev->input_id.bustype = BUS_HOST; |
1439 | data->input_dev->id.vendor = PCI_VENDOR_ID_WINBOND; | 807 | data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND; |
1440 | data->input_dev->id.product = WBCIR_ID_FAMILY; | 808 | data->dev->input_id.product = WBCIR_ID_FAMILY; |
1441 | data->input_dev->id.version = WBCIR_ID_CHIP; | 809 | data->dev->input_id.version = WBCIR_ID_CHIP; |
1442 | data->input_dev->getkeycode = wbcir_getkeycode; | 810 | data->dev->priv = data; |
1443 | data->input_dev->setkeycode = wbcir_setkeycode; | 811 | data->dev->dev.parent = &device->dev; |
1444 | input_set_capability(data->input_dev, EV_MSC, MSC_SCAN); | 812 | |
1445 | input_set_drvdata(data->input_dev, data); | 813 | err = rc_register_device(data->dev); |
1446 | |||
1447 | err = input_register_device(data->input_dev); | ||
1448 | if (err) | 814 | if (err) |
1449 | goto exit_free_input; | 815 | goto exit_free_rc; |
1450 | |||
1451 | data->last_scancode = INVALID_SCANCODE; | ||
1452 | INIT_LIST_HEAD(&data->keytable); | ||
1453 | setup_timer(&data->timer_keyup, wbcir_keyup, (unsigned long)data); | ||
1454 | |||
1455 | /* Load default keymaps */ | ||
1456 | if (protocol == IR_PROTOCOL_RC6) { | ||
1457 | int i; | ||
1458 | for (i = 0; i < ARRAY_SIZE(rc6_def_keymap); i++) { | ||
1459 | err = wbcir_setkeycode(data->input_dev, | ||
1460 | (int)rc6_def_keymap[i].scancode, | ||
1461 | (int)rc6_def_keymap[i].keycode); | ||
1462 | if (err) | ||
1463 | goto exit_unregister_keys; | ||
1464 | } | ||
1465 | } | ||
1466 | 816 | ||
1467 | device_init_wakeup(&device->dev, 1); | 817 | device_init_wakeup(&device->dev, 1); |
1468 | 818 | ||
@@ -1470,21 +820,8 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) | |||
1470 | 820 | ||
1471 | return 0; | 821 | return 0; |
1472 | 822 | ||
1473 | exit_unregister_keys: | 823 | exit_free_rc: |
1474 | if (!list_empty(&data->keytable)) { | 824 | rc_free_device(data->dev); |
1475 | struct wbcir_keyentry *key; | ||
1476 | struct wbcir_keyentry *keytmp; | ||
1477 | |||
1478 | list_for_each_entry_safe(key, keytmp, &data->keytable, list) { | ||
1479 | list_del(&key->list); | ||
1480 | kfree(key); | ||
1481 | } | ||
1482 | } | ||
1483 | input_unregister_device(data->input_dev); | ||
1484 | /* Can't call input_free_device on an unregistered device */ | ||
1485 | data->input_dev = NULL; | ||
1486 | exit_free_input: | ||
1487 | input_free_device(data->input_dev); | ||
1488 | exit_unregister_led: | 825 | exit_unregister_led: |
1489 | led_classdev_unregister(&data->led); | 826 | led_classdev_unregister(&data->led); |
1490 | exit_unregister_rxtrigger: | 827 | exit_unregister_rxtrigger: |
@@ -1510,15 +847,11 @@ static void __devexit | |||
1510 | wbcir_remove(struct pnp_dev *device) | 847 | wbcir_remove(struct pnp_dev *device) |
1511 | { | 848 | { |
1512 | struct wbcir_data *data = pnp_get_drvdata(device); | 849 | struct wbcir_data *data = pnp_get_drvdata(device); |
1513 | struct wbcir_keyentry *key; | ||
1514 | struct wbcir_keyentry *keytmp; | ||
1515 | 850 | ||
1516 | /* Disable interrupts */ | 851 | /* Disable interrupts */ |
1517 | wbcir_select_bank(data, WBCIR_BANK_0); | 852 | wbcir_select_bank(data, WBCIR_BANK_0); |
1518 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | 853 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); |
1519 | 854 | ||
1520 | del_timer_sync(&data->timer_keyup); | ||
1521 | |||
1522 | free_irq(data->irq, device); | 855 | free_irq(data->irq, device); |
1523 | 856 | ||
1524 | /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ | 857 | /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ |
@@ -1530,8 +863,7 @@ wbcir_remove(struct pnp_dev *device) | |||
1530 | /* Clear BUFF_EN, END_EN, MATCH_EN */ | 863 | /* Clear BUFF_EN, END_EN, MATCH_EN */ |
1531 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); | 864 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); |
1532 | 865 | ||
1533 | /* This will generate a keyup event if necessary */ | 866 | rc_unregister_device(data->dev); |
1534 | input_unregister_device(data->input_dev); | ||
1535 | 867 | ||
1536 | led_trigger_unregister_simple(data->rxtrigger); | 868 | led_trigger_unregister_simple(data->rxtrigger); |
1537 | led_trigger_unregister_simple(data->txtrigger); | 869 | led_trigger_unregister_simple(data->txtrigger); |
@@ -1544,11 +876,6 @@ wbcir_remove(struct pnp_dev *device) | |||
1544 | release_region(data->ebase, EHFUNC_IOMEM_LEN); | 876 | release_region(data->ebase, EHFUNC_IOMEM_LEN); |
1545 | release_region(data->sbase, SP_IOMEM_LEN); | 877 | release_region(data->sbase, SP_IOMEM_LEN); |
1546 | 878 | ||
1547 | list_for_each_entry_safe(key, keytmp, &data->keytable, list) { | ||
1548 | list_del(&key->list); | ||
1549 | kfree(key); | ||
1550 | } | ||
1551 | |||
1552 | kfree(data); | 879 | kfree(data); |
1553 | 880 | ||
1554 | pnp_set_drvdata(device, NULL); | 881 | pnp_set_drvdata(device, NULL); |
@@ -1581,8 +908,7 @@ wbcir_init(void) | |||
1581 | case IR_PROTOCOL_RC6: | 908 | case IR_PROTOCOL_RC6: |
1582 | break; | 909 | break; |
1583 | default: | 910 | default: |
1584 | printk(KERN_ERR DRVNAME ": Invalid protocol argument\n"); | 911 | printk(KERN_ERR DRVNAME ": Invalid power-on protocol\n"); |
1585 | return -EINVAL; | ||
1586 | } | 912 | } |
1587 | 913 | ||
1588 | ret = pnp_register_driver(&wbcir_driver); | 914 | ret = pnp_register_driver(&wbcir_driver); |
@@ -1598,11 +924,9 @@ wbcir_exit(void) | |||
1598 | pnp_unregister_driver(&wbcir_driver); | 924 | pnp_unregister_driver(&wbcir_driver); |
1599 | } | 925 | } |
1600 | 926 | ||
1601 | MODULE_AUTHOR("David Härdeman <david@hardeman.nu>"); | ||
1602 | MODULE_DESCRIPTION("Winbond SuperI/O Consumer IR Driver"); | ||
1603 | MODULE_LICENSE("GPL"); | ||
1604 | |||
1605 | module_init(wbcir_init); | 927 | module_init(wbcir_init); |
1606 | module_exit(wbcir_exit); | 928 | module_exit(wbcir_exit); |
1607 | 929 | ||
1608 | 930 | MODULE_AUTHOR("David Härdeman <david@hardeman.nu>"); | |
931 | MODULE_DESCRIPTION("Winbond SuperI/O Consumer IR Driver"); | ||
932 | MODULE_LICENSE("GPL"); | ||