diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/IR/Kconfig | 12 | ||||
-rw-r--r-- | drivers/media/IR/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/IR/ir-core-priv.h | 6 | ||||
-rw-r--r-- | drivers/media/IR/ir-rc5-sz-decoder.c | 153 | ||||
-rw-r--r-- | drivers/media/IR/ir-sysfs.c | 1 | ||||
-rw-r--r-- | drivers/media/IR/keymaps/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/IR/keymaps/rc-rc5-streamzap.c | 81 | ||||
-rw-r--r-- | drivers/media/IR/keymaps/rc-streamzap.c | 82 | ||||
-rw-r--r-- | drivers/media/IR/streamzap.c | 358 |
9 files changed, 349 insertions, 347 deletions
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig index 490c57cc4cfe..152000db3526 100644 --- a/drivers/media/IR/Kconfig +++ b/drivers/media/IR/Kconfig | |||
@@ -79,6 +79,18 @@ config IR_SONY_DECODER | |||
79 | Enable this option if you have an infrared remote control which | 79 | Enable this option if you have an infrared remote control which |
80 | uses the Sony protocol, and you need software decoding support. | 80 | uses the Sony protocol, and you need software decoding support. |
81 | 81 | ||
82 | config IR_RC5_SZ_DECODER | ||
83 | tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol" | ||
84 | depends on IR_CORE | ||
85 | select BITREVERSE | ||
86 | default y | ||
87 | |||
88 | ---help--- | ||
89 | Enable this option if you have IR with RC-5 (streamzap) protocol, | ||
90 | and if the IR is decoded in software. (The Streamzap PC Remote | ||
91 | uses an IR protocol that is almost standard RC-5, but not quite, | ||
92 | as it uses an additional bit). | ||
93 | |||
82 | config IR_LIRC_CODEC | 94 | config IR_LIRC_CODEC |
83 | tristate "Enable IR to LIRC bridge" | 95 | tristate "Enable IR to LIRC bridge" |
84 | depends on IR_CORE | 96 | depends on IR_CORE |
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile index 53676838fe97..953c6c44330a 100644 --- a/drivers/media/IR/Makefile +++ b/drivers/media/IR/Makefile | |||
@@ -11,6 +11,7 @@ obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o | |||
11 | obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o | 11 | obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o |
12 | obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o | 12 | obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o |
13 | obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o | 13 | obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o |
14 | obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o | ||
14 | obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o | 15 | obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o |
15 | 16 | ||
16 | # stand-alone IR receivers/transmitters | 17 | # stand-alone IR receivers/transmitters |
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index a85a8c7c905a..0ad8ea39b39e 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h | |||
@@ -76,6 +76,12 @@ struct ir_raw_event_ctrl { | |||
76 | bool first; | 76 | bool first; |
77 | bool toggle; | 77 | bool toggle; |
78 | } jvc; | 78 | } jvc; |
79 | struct rc5_sz_dec { | ||
80 | int state; | ||
81 | u32 bits; | ||
82 | unsigned count; | ||
83 | unsigned wanted_bits; | ||
84 | } rc5_sz; | ||
79 | struct lirc_codec { | 85 | struct lirc_codec { |
80 | struct ir_input_dev *ir_dev; | 86 | struct ir_input_dev *ir_dev; |
81 | struct lirc_driver *drv; | 87 | struct lirc_driver *drv; |
diff --git a/drivers/media/IR/ir-rc5-sz-decoder.c b/drivers/media/IR/ir-rc5-sz-decoder.c new file mode 100644 index 000000000000..68f11d6acd5b --- /dev/null +++ b/drivers/media/IR/ir-rc5-sz-decoder.c | |||
@@ -0,0 +1,153 @@ | |||
1 | /* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol | ||
2 | * | ||
3 | * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> | ||
4 | * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * This code handles the 15 bit RC5-ish protocol used by the Streamzap | ||
18 | * PC Remote. | ||
19 | * It considers a carrier of 36 kHz, with a total of 15 bits, where | ||
20 | * the first two bits are start bits, and a third one is a filing bit | ||
21 | */ | ||
22 | |||
23 | #include "ir-core-priv.h" | ||
24 | |||
25 | #define RC5_SZ_NBITS 15 | ||
26 | #define RC5_UNIT 888888 /* ns */ | ||
27 | #define RC5_BIT_START (1 * RC5_UNIT) | ||
28 | #define RC5_BIT_END (1 * RC5_UNIT) | ||
29 | |||
30 | enum rc5_sz_state { | ||
31 | STATE_INACTIVE, | ||
32 | STATE_BIT_START, | ||
33 | STATE_BIT_END, | ||
34 | STATE_FINISHED, | ||
35 | }; | ||
36 | |||
37 | /** | ||
38 | * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space | ||
39 | * @input_dev: the struct input_dev descriptor of the device | ||
40 | * @ev: the struct ir_raw_event descriptor of the pulse/space | ||
41 | * | ||
42 | * This function returns -EINVAL if the pulse violates the state machine | ||
43 | */ | ||
44 | static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev) | ||
45 | { | ||
46 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
47 | struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz; | ||
48 | u8 toggle, command, system; | ||
49 | u32 scancode; | ||
50 | |||
51 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ)) | ||
52 | return 0; | ||
53 | |||
54 | if (IS_RESET(ev)) { | ||
55 | data->state = STATE_INACTIVE; | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) | ||
60 | goto out; | ||
61 | |||
62 | again: | ||
63 | IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n", | ||
64 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | ||
65 | |||
66 | if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) | ||
67 | return 0; | ||
68 | |||
69 | switch (data->state) { | ||
70 | |||
71 | case STATE_INACTIVE: | ||
72 | if (!ev.pulse) | ||
73 | break; | ||
74 | |||
75 | data->state = STATE_BIT_START; | ||
76 | data->count = 1; | ||
77 | data->wanted_bits = RC5_SZ_NBITS; | ||
78 | decrease_duration(&ev, RC5_BIT_START); | ||
79 | goto again; | ||
80 | |||
81 | case STATE_BIT_START: | ||
82 | if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2)) | ||
83 | break; | ||
84 | |||
85 | data->bits <<= 1; | ||
86 | if (!ev.pulse) | ||
87 | data->bits |= 1; | ||
88 | data->count++; | ||
89 | data->state = STATE_BIT_END; | ||
90 | return 0; | ||
91 | |||
92 | case STATE_BIT_END: | ||
93 | if (!is_transition(&ev, &ir_dev->raw->prev_ev)) | ||
94 | break; | ||
95 | |||
96 | if (data->count == data->wanted_bits) | ||
97 | data->state = STATE_FINISHED; | ||
98 | else | ||
99 | data->state = STATE_BIT_START; | ||
100 | |||
101 | decrease_duration(&ev, RC5_BIT_END); | ||
102 | goto again; | ||
103 | |||
104 | case STATE_FINISHED: | ||
105 | if (ev.pulse) | ||
106 | break; | ||
107 | |||
108 | /* RC5-sz */ | ||
109 | command = (data->bits & 0x0003F) >> 0; | ||
110 | system = (data->bits & 0x02FC0) >> 6; | ||
111 | toggle = (data->bits & 0x01000) ? 1 : 0; | ||
112 | scancode = system << 6 | command; | ||
113 | |||
114 | IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n", | ||
115 | scancode, toggle); | ||
116 | |||
117 | ir_keydown(input_dev, scancode, toggle); | ||
118 | data->state = STATE_INACTIVE; | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | out: | ||
123 | IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n", | ||
124 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | ||
125 | data->state = STATE_INACTIVE; | ||
126 | return -EINVAL; | ||
127 | } | ||
128 | |||
129 | static struct ir_raw_handler rc5_sz_handler = { | ||
130 | .protocols = IR_TYPE_RC5_SZ, | ||
131 | .decode = ir_rc5_sz_decode, | ||
132 | }; | ||
133 | |||
134 | static int __init ir_rc5_sz_decode_init(void) | ||
135 | { | ||
136 | ir_raw_handler_register(&rc5_sz_handler); | ||
137 | |||
138 | printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n"); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static void __exit ir_rc5_sz_decode_exit(void) | ||
143 | { | ||
144 | ir_raw_handler_unregister(&rc5_sz_handler); | ||
145 | } | ||
146 | |||
147 | module_init(ir_rc5_sz_decode_init); | ||
148 | module_exit(ir_rc5_sz_decode_exit); | ||
149 | |||
150 | MODULE_LICENSE("GPL"); | ||
151 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); | ||
152 | MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); | ||
153 | MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder"); | ||
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index 46d42467f9b4..be09d1995b41 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c | |||
@@ -43,6 +43,7 @@ static struct { | |||
43 | { IR_TYPE_RC6, "rc-6" }, | 43 | { IR_TYPE_RC6, "rc-6" }, |
44 | { IR_TYPE_JVC, "jvc" }, | 44 | { IR_TYPE_JVC, "jvc" }, |
45 | { IR_TYPE_SONY, "sony" }, | 45 | { IR_TYPE_SONY, "sony" }, |
46 | { IR_TYPE_RC5_SZ, "rc-5-sz" }, | ||
46 | { IR_TYPE_LIRC, "lirc" }, | 47 | { IR_TYPE_LIRC, "lirc" }, |
47 | }; | 48 | }; |
48 | 49 | ||
diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile index 950e5d953c6f..c032b9d2e51a 100644 --- a/drivers/media/IR/keymaps/Makefile +++ b/drivers/media/IR/keymaps/Makefile | |||
@@ -58,10 +58,10 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ | |||
58 | rc-purpletv.o \ | 58 | rc-purpletv.o \ |
59 | rc-pv951.o \ | 59 | rc-pv951.o \ |
60 | rc-rc5-hauppauge-new.o \ | 60 | rc-rc5-hauppauge-new.o \ |
61 | rc-rc5-streamzap.o \ | ||
62 | rc-rc5-tv.o \ | 61 | rc-rc5-tv.o \ |
63 | rc-rc6-mce.o \ | 62 | rc-rc6-mce.o \ |
64 | rc-real-audio-220-32-keys.o \ | 63 | rc-real-audio-220-32-keys.o \ |
64 | rc-streamzap.o \ | ||
65 | rc-tbs-nec.o \ | 65 | rc-tbs-nec.o \ |
66 | rc-terratec-cinergy-xs.o \ | 66 | rc-terratec-cinergy-xs.o \ |
67 | rc-tevii-nec.o \ | 67 | rc-tevii-nec.o \ |
diff --git a/drivers/media/IR/keymaps/rc-rc5-streamzap.c b/drivers/media/IR/keymaps/rc-rc5-streamzap.c deleted file mode 100644 index 4c19c58b46d8..000000000000 --- a/drivers/media/IR/keymaps/rc-rc5-streamzap.c +++ /dev/null | |||
@@ -1,81 +0,0 @@ | |||
1 | /* rc-rc5-streamzap.c - Keytable for Streamzap PC Remote, for use | ||
2 | * with the Streamzap PC Remote IR Receiver. | ||
3 | * | ||
4 | * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <media/rc-map.h> | ||
13 | |||
14 | static struct ir_scancode rc5_streamzap[] = { | ||
15 | /* | ||
16 | * FIXME: The Streamzap remote isn't actually true RC-5, it has an extra | ||
17 | * bit in it, which presently throws the in-kernel RC-5 decoder for a loop. | ||
18 | * We either have to enhance the decoder to support it, add a new decoder, | ||
19 | * or just rely on lirc userspace decoding. | ||
20 | */ | ||
21 | { 0x00, KEY_NUMERIC_0 }, | ||
22 | { 0x01, KEY_NUMERIC_1 }, | ||
23 | { 0x02, KEY_NUMERIC_2 }, | ||
24 | { 0x03, KEY_NUMERIC_3 }, | ||
25 | { 0x04, KEY_NUMERIC_4 }, | ||
26 | { 0x05, KEY_NUMERIC_5 }, | ||
27 | { 0x06, KEY_NUMERIC_6 }, | ||
28 | { 0x07, KEY_NUMERIC_7 }, | ||
29 | { 0x08, KEY_NUMERIC_8 }, | ||
30 | { 0x0a, KEY_POWER }, | ||
31 | { 0x0b, KEY_MUTE }, | ||
32 | { 0x0c, KEY_CHANNELUP }, | ||
33 | { 0x0d, KEY_VOLUMEUP }, | ||
34 | { 0x0e, KEY_CHANNELDOWN }, | ||
35 | { 0x0f, KEY_VOLUMEDOWN }, | ||
36 | { 0x10, KEY_UP }, | ||
37 | { 0x11, KEY_LEFT }, | ||
38 | { 0x12, KEY_OK }, | ||
39 | { 0x13, KEY_RIGHT }, | ||
40 | { 0x14, KEY_DOWN }, | ||
41 | { 0x15, KEY_MENU }, | ||
42 | { 0x16, KEY_EXIT }, | ||
43 | { 0x17, KEY_PLAY }, | ||
44 | { 0x18, KEY_PAUSE }, | ||
45 | { 0x19, KEY_STOP }, | ||
46 | { 0x1a, KEY_BACK }, | ||
47 | { 0x1b, KEY_FORWARD }, | ||
48 | { 0x1c, KEY_RECORD }, | ||
49 | { 0x1d, KEY_REWIND }, | ||
50 | { 0x1e, KEY_FASTFORWARD }, | ||
51 | { 0x20, KEY_RED }, | ||
52 | { 0x21, KEY_GREEN }, | ||
53 | { 0x22, KEY_YELLOW }, | ||
54 | { 0x23, KEY_BLUE }, | ||
55 | |||
56 | }; | ||
57 | |||
58 | static struct rc_keymap rc5_streamzap_map = { | ||
59 | .map = { | ||
60 | .scan = rc5_streamzap, | ||
61 | .size = ARRAY_SIZE(rc5_streamzap), | ||
62 | .ir_type = IR_TYPE_RC5, | ||
63 | .name = RC_MAP_RC5_STREAMZAP, | ||
64 | } | ||
65 | }; | ||
66 | |||
67 | static int __init init_rc_map_rc5_streamzap(void) | ||
68 | { | ||
69 | return ir_register_map(&rc5_streamzap_map); | ||
70 | } | ||
71 | |||
72 | static void __exit exit_rc_map_rc5_streamzap(void) | ||
73 | { | ||
74 | ir_unregister_map(&rc5_streamzap_map); | ||
75 | } | ||
76 | |||
77 | module_init(init_rc_map_rc5_streamzap) | ||
78 | module_exit(exit_rc_map_rc5_streamzap) | ||
79 | |||
80 | MODULE_LICENSE("GPL"); | ||
81 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); | ||
diff --git a/drivers/media/IR/keymaps/rc-streamzap.c b/drivers/media/IR/keymaps/rc-streamzap.c new file mode 100644 index 000000000000..df32013a321c --- /dev/null +++ b/drivers/media/IR/keymaps/rc-streamzap.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* rc-streamzap.c - Keytable for Streamzap PC Remote, for use | ||
2 | * with the Streamzap PC Remote IR Receiver. | ||
3 | * | ||
4 | * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <media/rc-map.h> | ||
13 | |||
14 | static struct ir_scancode streamzap[] = { | ||
15 | /* | ||
16 | * The Streamzap remote is almost, but not quite, RC-5, as it has an extra | ||
17 | * bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently, | ||
18 | * an additional RC-5-sz decoder is being deployed to support it, but it | ||
19 | * may be possible to merge it back with the standard RC-5 decoder. | ||
20 | */ | ||
21 | { 0x28c0, KEY_NUMERIC_0 }, | ||
22 | { 0x28c1, KEY_NUMERIC_1 }, | ||
23 | { 0x28c2, KEY_NUMERIC_2 }, | ||
24 | { 0x28c3, KEY_NUMERIC_3 }, | ||
25 | { 0x28c4, KEY_NUMERIC_4 }, | ||
26 | { 0x28c5, KEY_NUMERIC_5 }, | ||
27 | { 0x28c6, KEY_NUMERIC_6 }, | ||
28 | { 0x28c7, KEY_NUMERIC_7 }, | ||
29 | { 0x28c8, KEY_NUMERIC_8 }, | ||
30 | { 0x28c9, KEY_NUMERIC_9 }, | ||
31 | { 0x28ca, KEY_POWER }, | ||
32 | { 0x28cb, KEY_MUTE }, | ||
33 | { 0x28cc, KEY_CHANNELUP }, | ||
34 | { 0x28cd, KEY_VOLUMEUP }, | ||
35 | { 0x28ce, KEY_CHANNELDOWN }, | ||
36 | { 0x28cf, KEY_VOLUMEDOWN }, | ||
37 | { 0x28d0, KEY_UP }, | ||
38 | { 0x28d1, KEY_LEFT }, | ||
39 | { 0x28d2, KEY_OK }, | ||
40 | { 0x28d3, KEY_RIGHT }, | ||
41 | { 0x28d4, KEY_DOWN }, | ||
42 | { 0x28d5, KEY_MENU }, | ||
43 | { 0x28d6, KEY_EXIT }, | ||
44 | { 0x28d7, KEY_PLAY }, | ||
45 | { 0x28d8, KEY_PAUSE }, | ||
46 | { 0x28d9, KEY_STOP }, | ||
47 | { 0x28da, KEY_BACK }, | ||
48 | { 0x28db, KEY_FORWARD }, | ||
49 | { 0x28dc, KEY_RECORD }, | ||
50 | { 0x28dd, KEY_REWIND }, | ||
51 | { 0x28de, KEY_FASTFORWARD }, | ||
52 | { 0x28e0, KEY_RED }, | ||
53 | { 0x28e1, KEY_GREEN }, | ||
54 | { 0x28e2, KEY_YELLOW }, | ||
55 | { 0x28e3, KEY_BLUE }, | ||
56 | |||
57 | }; | ||
58 | |||
59 | static struct rc_keymap streamzap_map = { | ||
60 | .map = { | ||
61 | .scan = streamzap, | ||
62 | .size = ARRAY_SIZE(streamzap), | ||
63 | .ir_type = IR_TYPE_RC5_SZ, | ||
64 | .name = RC_MAP_STREAMZAP, | ||
65 | } | ||
66 | }; | ||
67 | |||
68 | static int __init init_rc_map_streamzap(void) | ||
69 | { | ||
70 | return ir_register_map(&streamzap_map); | ||
71 | } | ||
72 | |||
73 | static void __exit exit_rc_map_streamzap(void) | ||
74 | { | ||
75 | ir_unregister_map(&streamzap_map); | ||
76 | } | ||
77 | |||
78 | module_init(init_rc_map_streamzap) | ||
79 | module_exit(exit_rc_map_streamzap) | ||
80 | |||
81 | MODULE_LICENSE("GPL"); | ||
82 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); | ||
diff --git a/drivers/media/IR/streamzap.c b/drivers/media/IR/streamzap.c index 058e29fd478c..2cf57e64a80b 100644 --- a/drivers/media/IR/streamzap.c +++ b/drivers/media/IR/streamzap.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/input.h> | 38 | #include <linux/input.h> |
39 | #include <media/ir-core.h> | 39 | #include <media/ir-core.h> |
40 | 40 | ||
41 | #define DRIVER_VERSION "1.60" | 41 | #define DRIVER_VERSION "1.61" |
42 | #define DRIVER_NAME "streamzap" | 42 | #define DRIVER_NAME "streamzap" |
43 | #define DRIVER_DESC "Streamzap Remote Control driver" | 43 | #define DRIVER_DESC "Streamzap Remote Control driver" |
44 | 44 | ||
@@ -69,6 +69,13 @@ MODULE_DEVICE_TABLE(usb, streamzap_table); | |||
69 | /* number of samples buffered */ | 69 | /* number of samples buffered */ |
70 | #define SZ_BUF_LEN 128 | 70 | #define SZ_BUF_LEN 128 |
71 | 71 | ||
72 | /* from ir-rc5-sz-decoder.c */ | ||
73 | #ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE | ||
74 | #define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder") | ||
75 | #else | ||
76 | #define load_rc5_sz_decode() 0 | ||
77 | #endif | ||
78 | |||
72 | enum StreamzapDecoderState { | 79 | enum StreamzapDecoderState { |
73 | PulseSpace, | 80 | PulseSpace, |
74 | FullPulse, | 81 | FullPulse, |
@@ -81,7 +88,6 @@ struct streamzap_ir { | |||
81 | 88 | ||
82 | /* ir-core */ | 89 | /* ir-core */ |
83 | struct ir_dev_props *props; | 90 | struct ir_dev_props *props; |
84 | struct ir_raw_event rawir; | ||
85 | 91 | ||
86 | /* core device info */ | 92 | /* core device info */ |
87 | struct device *dev; | 93 | struct device *dev; |
@@ -98,17 +104,6 @@ struct streamzap_ir { | |||
98 | dma_addr_t dma_in; | 104 | dma_addr_t dma_in; |
99 | unsigned int buf_in_len; | 105 | unsigned int buf_in_len; |
100 | 106 | ||
101 | /* timer used to support delay buffering */ | ||
102 | struct timer_list delay_timer; | ||
103 | bool timer_running; | ||
104 | spinlock_t timer_lock; | ||
105 | struct timer_list flush_timer; | ||
106 | bool flush; | ||
107 | |||
108 | /* delay buffer */ | ||
109 | struct kfifo fifo; | ||
110 | bool fifo_initialized; | ||
111 | |||
112 | /* track what state we're in */ | 107 | /* track what state we're in */ |
113 | enum StreamzapDecoderState decoder_state; | 108 | enum StreamzapDecoderState decoder_state; |
114 | /* tracks whether we are currently receiving some signal */ | 109 | /* tracks whether we are currently receiving some signal */ |
@@ -118,7 +113,7 @@ struct streamzap_ir { | |||
118 | /* start time of signal; necessary for gap tracking */ | 113 | /* start time of signal; necessary for gap tracking */ |
119 | struct timeval signal_last; | 114 | struct timeval signal_last; |
120 | struct timeval signal_start; | 115 | struct timeval signal_start; |
121 | /* bool timeout_enabled; */ | 116 | bool timeout_enabled; |
122 | 117 | ||
123 | char name[128]; | 118 | char name[128]; |
124 | char phys[64]; | 119 | char phys[64]; |
@@ -143,122 +138,16 @@ static struct usb_driver streamzap_driver = { | |||
143 | .id_table = streamzap_table, | 138 | .id_table = streamzap_table, |
144 | }; | 139 | }; |
145 | 140 | ||
146 | static void streamzap_stop_timer(struct streamzap_ir *sz) | 141 | static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) |
147 | { | ||
148 | unsigned long flags; | ||
149 | |||
150 | spin_lock_irqsave(&sz->timer_lock, flags); | ||
151 | if (sz->timer_running) { | ||
152 | sz->timer_running = false; | ||
153 | spin_unlock_irqrestore(&sz->timer_lock, flags); | ||
154 | del_timer_sync(&sz->delay_timer); | ||
155 | } else { | ||
156 | spin_unlock_irqrestore(&sz->timer_lock, flags); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static void streamzap_flush_timeout(unsigned long arg) | ||
161 | { | ||
162 | struct streamzap_ir *sz = (struct streamzap_ir *)arg; | ||
163 | |||
164 | dev_info(sz->dev, "%s: callback firing\n", __func__); | ||
165 | |||
166 | /* finally start accepting data */ | ||
167 | sz->flush = false; | ||
168 | } | ||
169 | |||
170 | static void streamzap_delay_timeout(unsigned long arg) | ||
171 | { | ||
172 | struct streamzap_ir *sz = (struct streamzap_ir *)arg; | ||
173 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | ||
174 | unsigned long flags; | ||
175 | int len, ret; | ||
176 | static unsigned long delay; | ||
177 | bool wake = false; | ||
178 | |||
179 | /* deliver data every 10 ms */ | ||
180 | delay = msecs_to_jiffies(10); | ||
181 | |||
182 | spin_lock_irqsave(&sz->timer_lock, flags); | ||
183 | |||
184 | if (kfifo_len(&sz->fifo) > 0) { | ||
185 | ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir)); | ||
186 | if (ret != sizeof(rawir)) | ||
187 | dev_err(sz->dev, "Problem w/kfifo_out...\n"); | ||
188 | ir_raw_event_store(sz->idev, &rawir); | ||
189 | wake = true; | ||
190 | } | ||
191 | |||
192 | len = kfifo_len(&sz->fifo); | ||
193 | if (len > 0) { | ||
194 | while ((len < SZ_BUF_LEN / 2) && | ||
195 | (len < SZ_BUF_LEN * sizeof(int))) { | ||
196 | ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir)); | ||
197 | if (ret != sizeof(rawir)) | ||
198 | dev_err(sz->dev, "Problem w/kfifo_out...\n"); | ||
199 | ir_raw_event_store(sz->idev, &rawir); | ||
200 | wake = true; | ||
201 | len = kfifo_len(&sz->fifo); | ||
202 | } | ||
203 | if (sz->timer_running) | ||
204 | mod_timer(&sz->delay_timer, jiffies + delay); | ||
205 | |||
206 | } else { | ||
207 | sz->timer_running = false; | ||
208 | } | ||
209 | |||
210 | if (wake) | ||
211 | ir_raw_event_handle(sz->idev); | ||
212 | |||
213 | spin_unlock_irqrestore(&sz->timer_lock, flags); | ||
214 | } | ||
215 | |||
216 | static void streamzap_flush_delay_buffer(struct streamzap_ir *sz) | ||
217 | { | 142 | { |
218 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | 143 | ir_raw_event_store(sz->idev, &rawir); |
219 | bool wake = false; | ||
220 | int ret; | ||
221 | |||
222 | while (kfifo_len(&sz->fifo) > 0) { | ||
223 | ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir)); | ||
224 | if (ret != sizeof(rawir)) | ||
225 | dev_err(sz->dev, "Problem w/kfifo_out...\n"); | ||
226 | ir_raw_event_store(sz->idev, &rawir); | ||
227 | wake = true; | ||
228 | } | ||
229 | |||
230 | if (wake) | ||
231 | ir_raw_event_handle(sz->idev); | ||
232 | } | ||
233 | |||
234 | static void sz_push(struct streamzap_ir *sz) | ||
235 | { | ||
236 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | ||
237 | unsigned long flags; | ||
238 | int ret; | ||
239 | |||
240 | spin_lock_irqsave(&sz->timer_lock, flags); | ||
241 | if (kfifo_len(&sz->fifo) >= sizeof(int) * SZ_BUF_LEN) { | ||
242 | ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir)); | ||
243 | if (ret != sizeof(rawir)) | ||
244 | dev_err(sz->dev, "Problem w/kfifo_out...\n"); | ||
245 | ir_raw_event_store(sz->idev, &rawir); | ||
246 | } | ||
247 | |||
248 | kfifo_in(&sz->fifo, &sz->rawir, sizeof(rawir)); | ||
249 | |||
250 | if (!sz->timer_running) { | ||
251 | sz->delay_timer.expires = jiffies + (HZ / 10); | ||
252 | add_timer(&sz->delay_timer); | ||
253 | sz->timer_running = true; | ||
254 | } | ||
255 | |||
256 | spin_unlock_irqrestore(&sz->timer_lock, flags); | ||
257 | } | 144 | } |
258 | 145 | ||
259 | static void sz_push_full_pulse(struct streamzap_ir *sz, | 146 | static void sz_push_full_pulse(struct streamzap_ir *sz, |
260 | unsigned char value) | 147 | unsigned char value) |
261 | { | 148 | { |
149 | struct ir_raw_event rawir; | ||
150 | |||
262 | if (sz->idle) { | 151 | if (sz->idle) { |
263 | long deltv; | 152 | long deltv; |
264 | 153 | ||
@@ -266,33 +155,33 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, | |||
266 | do_gettimeofday(&sz->signal_start); | 155 | do_gettimeofday(&sz->signal_start); |
267 | 156 | ||
268 | deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec; | 157 | deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec; |
269 | sz->rawir.pulse = false; | 158 | rawir.pulse = false; |
270 | if (deltv > 15) { | 159 | if (deltv > 15) { |
271 | /* really long time */ | 160 | /* really long time */ |
272 | sz->rawir.duration = IR_MAX_DURATION; | 161 | rawir.duration = IR_MAX_DURATION; |
273 | } else { | 162 | } else { |
274 | sz->rawir.duration = (int)(deltv * 1000000 + | 163 | rawir.duration = (int)(deltv * 1000000 + |
275 | sz->signal_start.tv_usec - | 164 | sz->signal_start.tv_usec - |
276 | sz->signal_last.tv_usec); | 165 | sz->signal_last.tv_usec); |
277 | sz->rawir.duration -= sz->sum; | 166 | rawir.duration -= sz->sum; |
278 | sz->rawir.duration *= 1000; | 167 | rawir.duration *= 1000; |
279 | sz->rawir.duration &= IR_MAX_DURATION; | 168 | rawir.duration &= IR_MAX_DURATION; |
280 | } | 169 | } |
281 | dev_dbg(sz->dev, "ls %u\n", sz->rawir.duration); | 170 | dev_dbg(sz->dev, "ls %u\n", rawir.duration); |
282 | sz_push(sz); | 171 | sz_push(sz, rawir); |
283 | 172 | ||
284 | sz->idle = 0; | 173 | sz->idle = false; |
285 | sz->sum = 0; | 174 | sz->sum = 0; |
286 | } | 175 | } |
287 | 176 | ||
288 | sz->rawir.pulse = true; | 177 | rawir.pulse = true; |
289 | sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION; | 178 | rawir.duration = ((int) value) * STREAMZAP_RESOLUTION; |
290 | sz->rawir.duration += STREAMZAP_RESOLUTION / 2; | 179 | rawir.duration += STREAMZAP_RESOLUTION / 2; |
291 | sz->sum += sz->rawir.duration; | 180 | sz->sum += rawir.duration; |
292 | sz->rawir.duration *= 1000; | 181 | rawir.duration *= 1000; |
293 | sz->rawir.duration &= IR_MAX_DURATION; | 182 | rawir.duration &= IR_MAX_DURATION; |
294 | dev_dbg(sz->dev, "p %u\n", sz->rawir.duration); | 183 | dev_dbg(sz->dev, "p %u\n", rawir.duration); |
295 | sz_push(sz); | 184 | sz_push(sz, rawir); |
296 | } | 185 | } |
297 | 186 | ||
298 | static void sz_push_half_pulse(struct streamzap_ir *sz, | 187 | static void sz_push_half_pulse(struct streamzap_ir *sz, |
@@ -304,13 +193,15 @@ static void sz_push_half_pulse(struct streamzap_ir *sz, | |||
304 | static void sz_push_full_space(struct streamzap_ir *sz, | 193 | static void sz_push_full_space(struct streamzap_ir *sz, |
305 | unsigned char value) | 194 | unsigned char value) |
306 | { | 195 | { |
307 | sz->rawir.pulse = false; | 196 | struct ir_raw_event rawir; |
308 | sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION; | 197 | |
309 | sz->rawir.duration += STREAMZAP_RESOLUTION / 2; | 198 | rawir.pulse = false; |
310 | sz->sum += sz->rawir.duration; | 199 | rawir.duration = ((int) value) * STREAMZAP_RESOLUTION; |
311 | sz->rawir.duration *= 1000; | 200 | rawir.duration += STREAMZAP_RESOLUTION / 2; |
312 | dev_dbg(sz->dev, "s %u\n", sz->rawir.duration); | 201 | sz->sum += rawir.duration; |
313 | sz_push(sz); | 202 | rawir.duration *= 1000; |
203 | dev_dbg(sz->dev, "s %u\n", rawir.duration); | ||
204 | sz_push(sz, rawir); | ||
314 | } | 205 | } |
315 | 206 | ||
316 | static void sz_push_half_space(struct streamzap_ir *sz, | 207 | static void sz_push_half_space(struct streamzap_ir *sz, |
@@ -330,10 +221,8 @@ static void streamzap_callback(struct urb *urb) | |||
330 | struct streamzap_ir *sz; | 221 | struct streamzap_ir *sz; |
331 | unsigned int i; | 222 | unsigned int i; |
332 | int len; | 223 | int len; |
333 | #if 0 | ||
334 | static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) & | 224 | static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) & |
335 | IR_MAX_DURATION) | 0x03000000); | 225 | IR_MAX_DURATION) | 0x03000000); |
336 | #endif | ||
337 | 226 | ||
338 | if (!urb) | 227 | if (!urb) |
339 | return; | 228 | return; |
@@ -356,57 +245,53 @@ static void streamzap_callback(struct urb *urb) | |||
356 | } | 245 | } |
357 | 246 | ||
358 | dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); | 247 | dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); |
359 | if (!sz->flush) { | 248 | for (i = 0; i < len; i++) { |
360 | for (i = 0; i < urb->actual_length; i++) { | 249 | dev_dbg(sz->dev, "sz idx %d: %x\n", |
361 | dev_dbg(sz->dev, "%d: %x\n", i, | 250 | i, (unsigned char)sz->buf_in[i]); |
362 | (unsigned char)sz->buf_in[i]); | 251 | switch (sz->decoder_state) { |
363 | switch (sz->decoder_state) { | 252 | case PulseSpace: |
364 | case PulseSpace: | 253 | if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) == |
365 | if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) == | 254 | STREAMZAP_PULSE_MASK) { |
366 | STREAMZAP_PULSE_MASK) { | 255 | sz->decoder_state = FullPulse; |
367 | sz->decoder_state = FullPulse; | 256 | continue; |
368 | continue; | 257 | } else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK) |
369 | } else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK) | 258 | == STREAMZAP_SPACE_MASK) { |
370 | == STREAMZAP_SPACE_MASK) { | 259 | sz_push_half_pulse(sz, sz->buf_in[i]); |
371 | sz_push_half_pulse(sz, sz->buf_in[i]); | 260 | sz->decoder_state = FullSpace; |
372 | sz->decoder_state = FullSpace; | 261 | continue; |
373 | continue; | 262 | } else { |
374 | } else { | 263 | sz_push_half_pulse(sz, sz->buf_in[i]); |
375 | sz_push_half_pulse(sz, sz->buf_in[i]); | ||
376 | sz_push_half_space(sz, sz->buf_in[i]); | ||
377 | } | ||
378 | break; | ||
379 | case FullPulse: | ||
380 | sz_push_full_pulse(sz, sz->buf_in[i]); | ||
381 | sz->decoder_state = IgnorePulse; | ||
382 | break; | ||
383 | case FullSpace: | ||
384 | if (sz->buf_in[i] == STREAMZAP_TIMEOUT) { | ||
385 | sz->idle = 1; | ||
386 | streamzap_stop_timer(sz); | ||
387 | #if 0 | ||
388 | if (sz->timeout_enabled) { | ||
389 | sz->rawir.pulse = false; | ||
390 | sz->rawir.duration = timeout; | ||
391 | sz->rawir.duration *= 1000; | ||
392 | sz_push(sz); | ||
393 | } | ||
394 | #endif | ||
395 | streamzap_flush_delay_buffer(sz); | ||
396 | } else | ||
397 | sz_push_full_space(sz, sz->buf_in[i]); | ||
398 | sz->decoder_state = PulseSpace; | ||
399 | break; | ||
400 | case IgnorePulse: | ||
401 | if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) == | ||
402 | STREAMZAP_SPACE_MASK) { | ||
403 | sz->decoder_state = FullSpace; | ||
404 | continue; | ||
405 | } | ||
406 | sz_push_half_space(sz, sz->buf_in[i]); | 264 | sz_push_half_space(sz, sz->buf_in[i]); |
407 | sz->decoder_state = PulseSpace; | ||
408 | break; | ||
409 | } | 265 | } |
266 | break; | ||
267 | case FullPulse: | ||
268 | sz_push_full_pulse(sz, sz->buf_in[i]); | ||
269 | sz->decoder_state = IgnorePulse; | ||
270 | break; | ||
271 | case FullSpace: | ||
272 | if (sz->buf_in[i] == STREAMZAP_TIMEOUT) { | ||
273 | struct ir_raw_event rawir; | ||
274 | |||
275 | rawir.pulse = false; | ||
276 | rawir.duration = timeout * 1000; | ||
277 | sz->idle = true; | ||
278 | if (sz->timeout_enabled) | ||
279 | sz_push(sz, rawir); | ||
280 | ir_raw_event_handle(sz->idev); | ||
281 | } else { | ||
282 | sz_push_full_space(sz, sz->buf_in[i]); | ||
283 | } | ||
284 | sz->decoder_state = PulseSpace; | ||
285 | break; | ||
286 | case IgnorePulse: | ||
287 | if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK) == | ||
288 | STREAMZAP_SPACE_MASK) { | ||
289 | sz->decoder_state = FullSpace; | ||
290 | continue; | ||
291 | } | ||
292 | sz_push_half_space(sz, sz->buf_in[i]); | ||
293 | sz->decoder_state = PulseSpace; | ||
294 | break; | ||
410 | } | 295 | } |
411 | } | 296 | } |
412 | 297 | ||
@@ -446,12 +331,11 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz) | |||
446 | 331 | ||
447 | props->priv = sz; | 332 | props->priv = sz; |
448 | props->driver_type = RC_DRIVER_IR_RAW; | 333 | props->driver_type = RC_DRIVER_IR_RAW; |
449 | /* FIXME: not sure about supported protocols, check on this */ | 334 | props->allowed_protos = IR_TYPE_ALL; |
450 | props->allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6; | ||
451 | 335 | ||
452 | sz->props = props; | 336 | sz->props = props; |
453 | 337 | ||
454 | ret = ir_input_register(idev, RC_MAP_RC5_STREAMZAP, props, DRIVER_NAME); | 338 | ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME); |
455 | if (ret < 0) { | 339 | if (ret < 0) { |
456 | dev_err(dev, "remote input device register failed\n"); | 340 | dev_err(dev, "remote input device register failed\n"); |
457 | goto irdev_failed; | 341 | goto irdev_failed; |
@@ -467,29 +351,6 @@ idev_alloc_failed: | |||
467 | return NULL; | 351 | return NULL; |
468 | } | 352 | } |
469 | 353 | ||
470 | static int streamzap_delay_buf_init(struct streamzap_ir *sz) | ||
471 | { | ||
472 | int ret; | ||
473 | |||
474 | ret = kfifo_alloc(&sz->fifo, sizeof(int) * SZ_BUF_LEN, | ||
475 | GFP_KERNEL); | ||
476 | if (ret == 0) | ||
477 | sz->fifo_initialized = 1; | ||
478 | |||
479 | return ret; | ||
480 | } | ||
481 | |||
482 | static void streamzap_start_flush_timer(struct streamzap_ir *sz) | ||
483 | { | ||
484 | sz->flush_timer.expires = jiffies + HZ; | ||
485 | sz->flush = true; | ||
486 | add_timer(&sz->flush_timer); | ||
487 | |||
488 | sz->urb_in->dev = sz->usbdev; | ||
489 | if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) | ||
490 | dev_err(sz->dev, "urb submit failed\n"); | ||
491 | } | ||
492 | |||
493 | /** | 354 | /** |
494 | * streamzap_probe | 355 | * streamzap_probe |
495 | * | 356 | * |
@@ -575,35 +436,21 @@ static int __devinit streamzap_probe(struct usb_interface *intf, | |||
575 | snprintf(name + strlen(name), sizeof(name) - strlen(name), | 436 | snprintf(name + strlen(name), sizeof(name) - strlen(name), |
576 | " %s", buf); | 437 | " %s", buf); |
577 | 438 | ||
578 | retval = streamzap_delay_buf_init(sz); | ||
579 | if (retval) { | ||
580 | dev_err(&intf->dev, "%s: delay buffer init failed\n", __func__); | ||
581 | goto free_urb_in; | ||
582 | } | ||
583 | |||
584 | sz->idev = streamzap_init_input_dev(sz); | 439 | sz->idev = streamzap_init_input_dev(sz); |
585 | if (!sz->idev) | 440 | if (!sz->idev) |
586 | goto input_dev_fail; | 441 | goto input_dev_fail; |
587 | 442 | ||
588 | sz->idle = true; | 443 | sz->idle = true; |
589 | sz->decoder_state = PulseSpace; | 444 | sz->decoder_state = PulseSpace; |
445 | /* FIXME: don't yet have a way to set this */ | ||
446 | sz->timeout_enabled = true; | ||
590 | #if 0 | 447 | #if 0 |
591 | /* not yet supported, depends on patches from maxim */ | 448 | /* not yet supported, depends on patches from maxim */ |
592 | /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ | 449 | /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ |
593 | sz->timeout_enabled = false; | ||
594 | sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000; | 450 | sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000; |
595 | sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000; | 451 | sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000; |
596 | #endif | 452 | #endif |
597 | 453 | ||
598 | init_timer(&sz->delay_timer); | ||
599 | sz->delay_timer.function = streamzap_delay_timeout; | ||
600 | sz->delay_timer.data = (unsigned long)sz; | ||
601 | spin_lock_init(&sz->timer_lock); | ||
602 | |||
603 | init_timer(&sz->flush_timer); | ||
604 | sz->flush_timer.function = streamzap_flush_timeout; | ||
605 | sz->flush_timer.data = (unsigned long)sz; | ||
606 | |||
607 | do_gettimeofday(&sz->signal_start); | 454 | do_gettimeofday(&sz->signal_start); |
608 | 455 | ||
609 | /* Complete final initialisations */ | 456 | /* Complete final initialisations */ |
@@ -615,16 +462,18 @@ static int __devinit streamzap_probe(struct usb_interface *intf, | |||
615 | 462 | ||
616 | usb_set_intfdata(intf, sz); | 463 | usb_set_intfdata(intf, sz); |
617 | 464 | ||
618 | streamzap_start_flush_timer(sz); | 465 | if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) |
466 | dev_err(sz->dev, "urb submit failed\n"); | ||
619 | 467 | ||
620 | dev_info(sz->dev, "Registered %s on usb%d:%d\n", name, | 468 | dev_info(sz->dev, "Registered %s on usb%d:%d\n", name, |
621 | usbdev->bus->busnum, usbdev->devnum); | 469 | usbdev->bus->busnum, usbdev->devnum); |
622 | 470 | ||
471 | /* Load the streamzap not-quite-rc5 decoder too */ | ||
472 | load_rc5_sz_decode(); | ||
473 | |||
623 | return 0; | 474 | return 0; |
624 | 475 | ||
625 | input_dev_fail: | 476 | input_dev_fail: |
626 | kfifo_free(&sz->fifo); | ||
627 | free_urb_in: | ||
628 | usb_free_urb(sz->urb_in); | 477 | usb_free_urb(sz->urb_in); |
629 | free_buf_in: | 478 | free_buf_in: |
630 | usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in); | 479 | usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in); |
@@ -654,13 +503,6 @@ static void streamzap_disconnect(struct usb_interface *interface) | |||
654 | if (!sz) | 503 | if (!sz) |
655 | return; | 504 | return; |
656 | 505 | ||
657 | if (sz->flush) { | ||
658 | sz->flush = false; | ||
659 | del_timer_sync(&sz->flush_timer); | ||
660 | } | ||
661 | |||
662 | streamzap_stop_timer(sz); | ||
663 | |||
664 | sz->usbdev = NULL; | 506 | sz->usbdev = NULL; |
665 | ir_input_unregister(sz->idev); | 507 | ir_input_unregister(sz->idev); |
666 | usb_kill_urb(sz->urb_in); | 508 | usb_kill_urb(sz->urb_in); |
@@ -674,13 +516,6 @@ static int streamzap_suspend(struct usb_interface *intf, pm_message_t message) | |||
674 | { | 516 | { |
675 | struct streamzap_ir *sz = usb_get_intfdata(intf); | 517 | struct streamzap_ir *sz = usb_get_intfdata(intf); |
676 | 518 | ||
677 | if (sz->flush) { | ||
678 | sz->flush = false; | ||
679 | del_timer_sync(&sz->flush_timer); | ||
680 | } | ||
681 | |||
682 | streamzap_stop_timer(sz); | ||
683 | |||
684 | usb_kill_urb(sz->urb_in); | 519 | usb_kill_urb(sz->urb_in); |
685 | 520 | ||
686 | return 0; | 521 | return 0; |
@@ -690,13 +525,6 @@ static int streamzap_resume(struct usb_interface *intf) | |||
690 | { | 525 | { |
691 | struct streamzap_ir *sz = usb_get_intfdata(intf); | 526 | struct streamzap_ir *sz = usb_get_intfdata(intf); |
692 | 527 | ||
693 | if (sz->fifo_initialized) | ||
694 | kfifo_reset(&sz->fifo); | ||
695 | |||
696 | sz->flush_timer.expires = jiffies + HZ; | ||
697 | sz->flush = true; | ||
698 | add_timer(&sz->flush_timer); | ||
699 | |||
700 | if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { | 528 | if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { |
701 | dev_err(sz->dev, "Error sumbiting urb\n"); | 529 | dev_err(sz->dev, "Error sumbiting urb\n"); |
702 | return -EIO; | 530 | return -EIO; |