diff options
Diffstat (limited to 'drivers/media/IR/ir-nec-decoder.c')
-rw-r--r-- | drivers/media/IR/ir-nec-decoder.c | 120 |
1 files changed, 67 insertions, 53 deletions
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index 14609d9580a8..ba79233112ef 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c | |||
@@ -17,13 +17,15 @@ | |||
17 | 17 | ||
18 | #define NEC_NBITS 32 | 18 | #define NEC_NBITS 32 |
19 | #define NEC_UNIT 562500 /* ns */ | 19 | #define NEC_UNIT 562500 /* ns */ |
20 | #define NEC_HEADER_PULSE PULSE(16) | 20 | #define NEC_HEADER_PULSE (16 * NEC_UNIT) |
21 | #define NECX_HEADER_PULSE PULSE(8) /* Less common NEC variant */ | 21 | #define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */ |
22 | #define NEC_HEADER_SPACE SPACE(8) | 22 | #define NEC_HEADER_SPACE (8 * NEC_UNIT) |
23 | #define NEC_REPEAT_SPACE SPACE(4) | 23 | #define NEC_REPEAT_SPACE (8 * NEC_UNIT) |
24 | #define NEC_BIT_PULSE PULSE(1) | 24 | #define NEC_BIT_PULSE (1 * NEC_UNIT) |
25 | #define NEC_BIT_0_SPACE SPACE(1) | 25 | #define NEC_BIT_0_SPACE (1 * NEC_UNIT) |
26 | #define NEC_BIT_1_SPACE SPACE(3) | 26 | #define NEC_BIT_1_SPACE (3 * NEC_UNIT) |
27 | #define NEC_TRAILER_PULSE (1 * NEC_UNIT) | ||
28 | #define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */ | ||
27 | 29 | ||
28 | /* Used to register nec_decoder clients */ | 30 | /* Used to register nec_decoder clients */ |
29 | static LIST_HEAD(decoder_list); | 31 | static LIST_HEAD(decoder_list); |
@@ -119,15 +121,14 @@ static struct attribute_group decoder_attribute_group = { | |||
119 | /** | 121 | /** |
120 | * ir_nec_decode() - Decode one NEC pulse or space | 122 | * ir_nec_decode() - Decode one NEC pulse or space |
121 | * @input_dev: the struct input_dev descriptor of the device | 123 | * @input_dev: the struct input_dev descriptor of the device |
122 | * @duration: duration in ns of pulse/space | 124 | * @duration: the struct ir_raw_event descriptor of the pulse/space |
123 | * | 125 | * |
124 | * This function returns -EINVAL if the pulse violates the state machine | 126 | * This function returns -EINVAL if the pulse violates the state machine |
125 | */ | 127 | */ |
126 | static int ir_nec_decode(struct input_dev *input_dev, s64 duration) | 128 | static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) |
127 | { | 129 | { |
128 | struct decoder_data *data; | 130 | struct decoder_data *data; |
129 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 131 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
130 | int u; | ||
131 | u32 scancode; | 132 | u32 scancode; |
132 | u8 address, not_address, command, not_command; | 133 | u8 address, not_address, command, not_command; |
133 | 134 | ||
@@ -138,59 +139,88 @@ static int ir_nec_decode(struct input_dev *input_dev, s64 duration) | |||
138 | if (!data->enabled) | 139 | if (!data->enabled) |
139 | return 0; | 140 | return 0; |
140 | 141 | ||
141 | if (IS_RESET(duration)) { | 142 | if (IS_RESET(ev)) { |
142 | data->state = STATE_INACTIVE; | 143 | data->state = STATE_INACTIVE; |
143 | return 0; | 144 | return 0; |
144 | } | 145 | } |
145 | 146 | ||
146 | u = TO_UNITS(duration, NEC_UNIT); | 147 | IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n", |
147 | if (DURATION(u) == 0) | 148 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
148 | goto out; | ||
149 | |||
150 | IR_dprintk(2, "NEC decode started at state %d (%i units, %ius)\n", | ||
151 | data->state, u, TO_US(duration)); | ||
152 | 149 | ||
153 | switch (data->state) { | 150 | switch (data->state) { |
154 | 151 | ||
155 | case STATE_INACTIVE: | 152 | case STATE_INACTIVE: |
156 | if (u == NEC_HEADER_PULSE || u == NECX_HEADER_PULSE) { | 153 | if (!ev.pulse) |
157 | data->count = 0; | 154 | break; |
158 | data->state = STATE_HEADER_SPACE; | 155 | |
159 | } | 156 | if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) && |
157 | !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2)) | ||
158 | break; | ||
159 | |||
160 | data->count = 0; | ||
161 | data->state = STATE_HEADER_SPACE; | ||
160 | return 0; | 162 | return 0; |
161 | 163 | ||
162 | case STATE_HEADER_SPACE: | 164 | case STATE_HEADER_SPACE: |
163 | if (u == NEC_HEADER_SPACE) { | 165 | if (ev.pulse) |
166 | break; | ||
167 | |||
168 | if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) { | ||
164 | data->state = STATE_BIT_PULSE; | 169 | data->state = STATE_BIT_PULSE; |
165 | return 0; | 170 | return 0; |
166 | } else if (u == NEC_REPEAT_SPACE) { | 171 | } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { |
167 | ir_repeat(input_dev); | 172 | ir_repeat(input_dev); |
168 | IR_dprintk(1, "Repeat last key\n"); | 173 | IR_dprintk(1, "Repeat last key\n"); |
169 | data->state = STATE_TRAILER_PULSE; | 174 | data->state = STATE_TRAILER_PULSE; |
170 | return 0; | 175 | return 0; |
171 | } | 176 | } |
177 | |||
172 | break; | 178 | break; |
173 | 179 | ||
174 | case STATE_BIT_PULSE: | 180 | case STATE_BIT_PULSE: |
175 | if (u == NEC_BIT_PULSE) { | 181 | if (!ev.pulse) |
176 | data->state = STATE_BIT_SPACE; | 182 | break; |
177 | return 0; | 183 | |
178 | } | 184 | if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2)) |
179 | break; | 185 | break; |
186 | |||
187 | data->state = STATE_BIT_SPACE; | ||
188 | return 0; | ||
180 | 189 | ||
181 | case STATE_BIT_SPACE: | 190 | case STATE_BIT_SPACE: |
182 | if (u != NEC_BIT_0_SPACE && u != NEC_BIT_1_SPACE) | 191 | if (ev.pulse) |
183 | break; | 192 | break; |
184 | 193 | ||
185 | data->nec_bits <<= 1; | 194 | data->nec_bits <<= 1; |
186 | if (u == NEC_BIT_1_SPACE) | 195 | if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) |
187 | data->nec_bits |= 1; | 196 | data->nec_bits |= 1; |
197 | else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2)) | ||
198 | break; | ||
188 | data->count++; | 199 | data->count++; |
189 | 200 | ||
190 | if (data->count != NEC_NBITS) { | 201 | if (data->count == NEC_NBITS) |
202 | data->state = STATE_TRAILER_PULSE; | ||
203 | else | ||
191 | data->state = STATE_BIT_PULSE; | 204 | data->state = STATE_BIT_PULSE; |
192 | return 0; | 205 | |
193 | } | 206 | return 0; |
207 | |||
208 | case STATE_TRAILER_PULSE: | ||
209 | if (!ev.pulse) | ||
210 | break; | ||
211 | |||
212 | if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2)) | ||
213 | break; | ||
214 | |||
215 | data->state = STATE_TRAILER_SPACE; | ||
216 | return 0; | ||
217 | |||
218 | case STATE_TRAILER_SPACE: | ||
219 | if (ev.pulse) | ||
220 | break; | ||
221 | |||
222 | if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) | ||
223 | break; | ||
194 | 224 | ||
195 | address = bitrev8((data->nec_bits >> 24) & 0xff); | 225 | address = bitrev8((data->nec_bits >> 24) & 0xff); |
196 | not_address = bitrev8((data->nec_bits >> 16) & 0xff); | 226 | not_address = bitrev8((data->nec_bits >> 16) & 0xff); |
@@ -210,34 +240,18 @@ static int ir_nec_decode(struct input_dev *input_dev, s64 duration) | |||
210 | command; | 240 | command; |
211 | IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode); | 241 | IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode); |
212 | } else { | 242 | } else { |
213 | /* normal NEC */ | 243 | /* Normal NEC */ |
214 | scancode = address << 8 | command; | 244 | scancode = address << 8 | command; |
215 | IR_dprintk(1, "NEC scancode 0x%04x\n", scancode); | 245 | IR_dprintk(1, "NEC scancode 0x%04x\n", scancode); |
216 | } | 246 | } |
217 | 247 | ||
218 | ir_keydown(input_dev, scancode, 0); | 248 | ir_keydown(input_dev, scancode, 0); |
219 | data->state = STATE_TRAILER_PULSE; | 249 | data->state = STATE_INACTIVE; |
220 | return 0; | 250 | return 0; |
221 | |||
222 | case STATE_TRAILER_PULSE: | ||
223 | if (u > 0) { | ||
224 | data->state = STATE_TRAILER_SPACE; | ||
225 | return 0; | ||
226 | } | ||
227 | break; | ||
228 | |||
229 | case STATE_TRAILER_SPACE: | ||
230 | if (u < 0) { | ||
231 | data->state = STATE_INACTIVE; | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | break; | ||
236 | } | 251 | } |
237 | 252 | ||
238 | out: | 253 | IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n", |
239 | IR_dprintk(1, "NEC decode failed at state %d (%i units, %ius)\n", | 254 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
240 | data->state, u, TO_US(duration)); | ||
241 | data->state = STATE_INACTIVE; | 255 | data->state = STATE_INACTIVE; |
242 | return -EINVAL; | 256 | return -EINVAL; |
243 | } | 257 | } |