Commit | Line | Data |
---|---|---|
30dd9e0c JH |
1 | /* |
2 | * ImgTec IR Hardware Decoder found in PowerDown Controller. | |
3 | * | |
4 | * Copyright 2010-2014 Imagination Technologies Ltd. | |
5 | * | |
2ac6f630 JH |
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 the | |
8 | * Free Software Foundation; either version 2 of the License, or (at your | |
9 | * option) any later version. | |
10 | * | |
30dd9e0c JH |
11 | * This ties into the input subsystem using the RC-core. Protocol support is |
12 | * provided in separate modules which provide the parameters and scancode | |
13 | * translation functions to set up the hardware decoder and interpret the | |
14 | * resulting input. | |
15 | */ | |
16 | ||
17 | #include <linux/bitops.h> | |
18 | #include <linux/clk.h> | |
19 | #include <linux/interrupt.h> | |
20 | #include <linux/spinlock.h> | |
21 | #include <linux/timer.h> | |
22 | #include <media/rc-core.h> | |
23 | #include "img-ir.h" | |
24 | ||
25 | /* Decoders lock (only modified to preprocess them) */ | |
26 | static DEFINE_SPINLOCK(img_ir_decoders_lock); | |
27 | ||
635abb70 | 28 | extern struct img_ir_decoder img_ir_nec; |
69336533 | 29 | extern struct img_ir_decoder img_ir_jvc; |
e72b21ab | 30 | extern struct img_ir_decoder img_ir_sony; |
3c11305e | 31 | extern struct img_ir_decoder img_ir_sharp; |
46b35083 | 32 | extern struct img_ir_decoder img_ir_sanyo; |
635abb70 | 33 | |
30dd9e0c JH |
34 | static bool img_ir_decoders_preprocessed; |
35 | static struct img_ir_decoder *img_ir_decoders[] = { | |
635abb70 JH |
36 | #ifdef CONFIG_IR_IMG_NEC |
37 | &img_ir_nec, | |
69336533 JH |
38 | #endif |
39 | #ifdef CONFIG_IR_IMG_JVC | |
40 | &img_ir_jvc, | |
e72b21ab JH |
41 | #endif |
42 | #ifdef CONFIG_IR_IMG_SONY | |
43 | &img_ir_sony, | |
3c11305e JH |
44 | #endif |
45 | #ifdef CONFIG_IR_IMG_SHARP | |
46 | &img_ir_sharp, | |
46b35083 JH |
47 | #endif |
48 | #ifdef CONFIG_IR_IMG_SANYO | |
49 | &img_ir_sanyo, | |
635abb70 | 50 | #endif |
30dd9e0c JH |
51 | NULL |
52 | }; | |
53 | ||
54 | #define IMG_IR_F_FILTER BIT(RC_FILTER_NORMAL) /* enable filtering */ | |
55 | #define IMG_IR_F_WAKE BIT(RC_FILTER_WAKEUP) /* enable waking */ | |
56 | ||
57 | /* code type quirks */ | |
58 | ||
59 | #define IMG_IR_QUIRK_CODE_BROKEN 0x1 /* Decode is broken */ | |
60 | #define IMG_IR_QUIRK_CODE_LEN_INCR 0x2 /* Bit length needs increment */ | |
61 | ||
62 | /* functions for preprocessing timings, ensuring max is set */ | |
63 | ||
64 | static void img_ir_timing_preprocess(struct img_ir_timing_range *range, | |
65 | unsigned int unit) | |
66 | { | |
67 | if (range->max < range->min) | |
68 | range->max = range->min; | |
69 | if (unit) { | |
70 | /* multiply by unit and convert to microseconds */ | |
71 | range->min = (range->min*unit)/1000; | |
72 | range->max = (range->max*unit + 999)/1000; /* round up */ | |
73 | } | |
74 | } | |
75 | ||
76 | static void img_ir_symbol_timing_preprocess(struct img_ir_symbol_timing *timing, | |
77 | unsigned int unit) | |
78 | { | |
79 | img_ir_timing_preprocess(&timing->pulse, unit); | |
80 | img_ir_timing_preprocess(&timing->space, unit); | |
81 | } | |
82 | ||
83 | static void img_ir_timings_preprocess(struct img_ir_timings *timings, | |
84 | unsigned int unit) | |
85 | { | |
86 | img_ir_symbol_timing_preprocess(&timings->ldr, unit); | |
87 | img_ir_symbol_timing_preprocess(&timings->s00, unit); | |
88 | img_ir_symbol_timing_preprocess(&timings->s01, unit); | |
89 | img_ir_symbol_timing_preprocess(&timings->s10, unit); | |
90 | img_ir_symbol_timing_preprocess(&timings->s11, unit); | |
91 | /* default s10 and s11 to s00 and s01 if no leader */ | |
92 | if (unit) | |
93 | /* multiply by unit and convert to microseconds (round up) */ | |
94 | timings->ft.ft_min = (timings->ft.ft_min*unit + 999)/1000; | |
95 | } | |
96 | ||
97 | /* functions for filling empty fields with defaults */ | |
98 | ||
99 | static void img_ir_timing_defaults(struct img_ir_timing_range *range, | |
100 | struct img_ir_timing_range *defaults) | |
101 | { | |
102 | if (!range->min) | |
103 | range->min = defaults->min; | |
104 | if (!range->max) | |
105 | range->max = defaults->max; | |
106 | } | |
107 | ||
108 | static void img_ir_symbol_timing_defaults(struct img_ir_symbol_timing *timing, | |
109 | struct img_ir_symbol_timing *defaults) | |
110 | { | |
111 | img_ir_timing_defaults(&timing->pulse, &defaults->pulse); | |
112 | img_ir_timing_defaults(&timing->space, &defaults->space); | |
113 | } | |
114 | ||
115 | static void img_ir_timings_defaults(struct img_ir_timings *timings, | |
116 | struct img_ir_timings *defaults) | |
117 | { | |
118 | img_ir_symbol_timing_defaults(&timings->ldr, &defaults->ldr); | |
119 | img_ir_symbol_timing_defaults(&timings->s00, &defaults->s00); | |
120 | img_ir_symbol_timing_defaults(&timings->s01, &defaults->s01); | |
121 | img_ir_symbol_timing_defaults(&timings->s10, &defaults->s10); | |
122 | img_ir_symbol_timing_defaults(&timings->s11, &defaults->s11); | |
123 | if (!timings->ft.ft_min) | |
124 | timings->ft.ft_min = defaults->ft.ft_min; | |
125 | } | |
126 | ||
127 | /* functions for converting timings to register values */ | |
128 | ||
129 | /** | |
130 | * img_ir_control() - Convert control struct to control register value. | |
131 | * @control: Control data | |
132 | * | |
133 | * Returns: The control register value equivalent of @control. | |
134 | */ | |
135 | static u32 img_ir_control(const struct img_ir_control *control) | |
136 | { | |
137 | u32 ctrl = control->code_type << IMG_IR_CODETYPE_SHIFT; | |
138 | if (control->decoden) | |
139 | ctrl |= IMG_IR_DECODEN; | |
140 | if (control->hdrtog) | |
141 | ctrl |= IMG_IR_HDRTOG; | |
142 | if (control->ldrdec) | |
143 | ctrl |= IMG_IR_LDRDEC; | |
144 | if (control->decodinpol) | |
145 | ctrl |= IMG_IR_DECODINPOL; | |
146 | if (control->bitorien) | |
147 | ctrl |= IMG_IR_BITORIEN; | |
148 | if (control->d1validsel) | |
149 | ctrl |= IMG_IR_D1VALIDSEL; | |
150 | if (control->bitinv) | |
151 | ctrl |= IMG_IR_BITINV; | |
152 | if (control->decodend2) | |
153 | ctrl |= IMG_IR_DECODEND2; | |
154 | if (control->bitoriend2) | |
155 | ctrl |= IMG_IR_BITORIEND2; | |
156 | if (control->bitinvd2) | |
157 | ctrl |= IMG_IR_BITINVD2; | |
158 | return ctrl; | |
159 | } | |
160 | ||
161 | /** | |
162 | * img_ir_timing_range_convert() - Convert microsecond range. | |
163 | * @out: Output timing range in clock cycles with a shift. | |
164 | * @in: Input timing range in microseconds. | |
165 | * @tolerance: Tolerance as a fraction of 128 (roughly percent). | |
166 | * @clock_hz: IR clock rate in Hz. | |
167 | * @shift: Shift of output units. | |
168 | * | |
169 | * Converts min and max from microseconds to IR clock cycles, applies a | |
170 | * tolerance, and shifts for the register, rounding in the right direction. | |
171 | * Note that in and out can safely be the same object. | |
172 | */ | |
173 | static void img_ir_timing_range_convert(struct img_ir_timing_range *out, | |
174 | const struct img_ir_timing_range *in, | |
175 | unsigned int tolerance, | |
176 | unsigned long clock_hz, | |
177 | unsigned int shift) | |
178 | { | |
179 | unsigned int min = in->min; | |
180 | unsigned int max = in->max; | |
181 | /* add a tolerance */ | |
182 | min = min - (min*tolerance >> 7); | |
183 | max = max + (max*tolerance >> 7); | |
184 | /* convert from microseconds into clock cycles */ | |
185 | min = min*clock_hz / 1000000; | |
186 | max = (max*clock_hz + 999999) / 1000000; /* round up */ | |
187 | /* apply shift and copy to output */ | |
188 | out->min = min >> shift; | |
189 | out->max = (max + ((1 << shift) - 1)) >> shift; /* round up */ | |
190 | } | |
191 | ||
192 | /** | |
193 | * img_ir_symbol_timing() - Convert symbol timing struct to register value. | |
194 | * @timing: Symbol timing data | |
195 | * @tolerance: Timing tolerance where 0-128 represents 0-100% | |
196 | * @clock_hz: Frequency of source clock in Hz | |
197 | * @pd_shift: Shift to apply to symbol period | |
198 | * @w_shift: Shift to apply to symbol width | |
199 | * | |
200 | * Returns: Symbol timing register value based on arguments. | |
201 | */ | |
202 | static u32 img_ir_symbol_timing(const struct img_ir_symbol_timing *timing, | |
203 | unsigned int tolerance, | |
204 | unsigned long clock_hz, | |
205 | unsigned int pd_shift, | |
206 | unsigned int w_shift) | |
207 | { | |
208 | struct img_ir_timing_range hw_pulse, hw_period; | |
209 | /* we calculate period in hw_period, then convert in place */ | |
210 | hw_period.min = timing->pulse.min + timing->space.min; | |
211 | hw_period.max = timing->pulse.max + timing->space.max; | |
212 | img_ir_timing_range_convert(&hw_period, &hw_period, | |
213 | tolerance, clock_hz, pd_shift); | |
214 | img_ir_timing_range_convert(&hw_pulse, &timing->pulse, | |
215 | tolerance, clock_hz, w_shift); | |
216 | /* construct register value */ | |
217 | return (hw_period.max << IMG_IR_PD_MAX_SHIFT) | | |
218 | (hw_period.min << IMG_IR_PD_MIN_SHIFT) | | |
219 | (hw_pulse.max << IMG_IR_W_MAX_SHIFT) | | |
220 | (hw_pulse.min << IMG_IR_W_MIN_SHIFT); | |
221 | } | |
222 | ||
223 | /** | |
224 | * img_ir_free_timing() - Convert free time timing struct to register value. | |
225 | * @timing: Free symbol timing data | |
226 | * @clock_hz: Source clock frequency in Hz | |
227 | * | |
228 | * Returns: Free symbol timing register value. | |
229 | */ | |
230 | static u32 img_ir_free_timing(const struct img_ir_free_timing *timing, | |
231 | unsigned long clock_hz) | |
232 | { | |
233 | unsigned int minlen, maxlen, ft_min; | |
234 | /* minlen is only 5 bits, and round minlen to multiple of 2 */ | |
235 | if (timing->minlen < 30) | |
236 | minlen = timing->minlen & -2; | |
237 | else | |
238 | minlen = 30; | |
239 | /* maxlen has maximum value of 48, and round maxlen to multiple of 2 */ | |
240 | if (timing->maxlen < 48) | |
241 | maxlen = (timing->maxlen + 1) & -2; | |
242 | else | |
243 | maxlen = 48; | |
244 | /* convert and shift ft_min, rounding upwards */ | |
245 | ft_min = (timing->ft_min*clock_hz + 999999) / 1000000; | |
246 | ft_min = (ft_min + 7) >> 3; | |
247 | /* construct register value */ | |
b9e28d1f JH |
248 | return (maxlen << IMG_IR_MAXLEN_SHIFT) | |
249 | (minlen << IMG_IR_MINLEN_SHIFT) | | |
250 | (ft_min << IMG_IR_FT_MIN_SHIFT); | |
30dd9e0c JH |
251 | } |
252 | ||
253 | /** | |
254 | * img_ir_free_timing_dynamic() - Update free time register value. | |
255 | * @st_ft: Static free time register value from img_ir_free_timing. | |
256 | * @filter: Current filter which may additionally restrict min/max len. | |
257 | * | |
258 | * Returns: Updated free time register value based on the current filter. | |
259 | */ | |
260 | static u32 img_ir_free_timing_dynamic(u32 st_ft, struct img_ir_filter *filter) | |
261 | { | |
262 | unsigned int minlen, maxlen, newminlen, newmaxlen; | |
263 | ||
264 | /* round minlen, maxlen to multiple of 2 */ | |
265 | newminlen = filter->minlen & -2; | |
266 | newmaxlen = (filter->maxlen + 1) & -2; | |
267 | /* extract min/max len from register */ | |
268 | minlen = (st_ft & IMG_IR_MINLEN) >> IMG_IR_MINLEN_SHIFT; | |
269 | maxlen = (st_ft & IMG_IR_MAXLEN) >> IMG_IR_MAXLEN_SHIFT; | |
270 | /* if the new values are more restrictive, update the register value */ | |
271 | if (newminlen > minlen) { | |
272 | st_ft &= ~IMG_IR_MINLEN; | |
273 | st_ft |= newminlen << IMG_IR_MINLEN_SHIFT; | |
274 | } | |
275 | if (newmaxlen < maxlen) { | |
276 | st_ft &= ~IMG_IR_MAXLEN; | |
277 | st_ft |= newmaxlen << IMG_IR_MAXLEN_SHIFT; | |
278 | } | |
279 | return st_ft; | |
280 | } | |
281 | ||
282 | /** | |
283 | * img_ir_timings_convert() - Convert timings to register values | |
284 | * @regs: Output timing register values | |
285 | * @timings: Input timing data | |
286 | * @tolerance: Timing tolerance where 0-128 represents 0-100% | |
287 | * @clock_hz: Source clock frequency in Hz | |
288 | */ | |
289 | static void img_ir_timings_convert(struct img_ir_timing_regvals *regs, | |
290 | const struct img_ir_timings *timings, | |
291 | unsigned int tolerance, | |
292 | unsigned int clock_hz) | |
293 | { | |
294 | /* leader symbol timings are divided by 16 */ | |
295 | regs->ldr = img_ir_symbol_timing(&timings->ldr, tolerance, clock_hz, | |
296 | 4, 4); | |
297 | /* other symbol timings, pd fields only are divided by 2 */ | |
298 | regs->s00 = img_ir_symbol_timing(&timings->s00, tolerance, clock_hz, | |
299 | 1, 0); | |
300 | regs->s01 = img_ir_symbol_timing(&timings->s01, tolerance, clock_hz, | |
301 | 1, 0); | |
302 | regs->s10 = img_ir_symbol_timing(&timings->s10, tolerance, clock_hz, | |
303 | 1, 0); | |
304 | regs->s11 = img_ir_symbol_timing(&timings->s11, tolerance, clock_hz, | |
305 | 1, 0); | |
306 | regs->ft = img_ir_free_timing(&timings->ft, clock_hz); | |
307 | } | |
308 | ||
309 | /** | |
310 | * img_ir_decoder_preprocess() - Preprocess timings in decoder. | |
311 | * @decoder: Decoder to be preprocessed. | |
312 | * | |
313 | * Ensures that the symbol timing ranges are valid with respect to ordering, and | |
314 | * does some fixed conversion on them. | |
315 | */ | |
316 | static void img_ir_decoder_preprocess(struct img_ir_decoder *decoder) | |
317 | { | |
318 | /* default tolerance */ | |
319 | if (!decoder->tolerance) | |
320 | decoder->tolerance = 10; /* percent */ | |
321 | /* and convert tolerance to fraction out of 128 */ | |
322 | decoder->tolerance = decoder->tolerance * 128 / 100; | |
323 | ||
324 | /* fill in implicit fields */ | |
325 | img_ir_timings_preprocess(&decoder->timings, decoder->unit); | |
326 | ||
327 | /* do the same for repeat timings if applicable */ | |
328 | if (decoder->repeat) { | |
329 | img_ir_timings_preprocess(&decoder->rtimings, decoder->unit); | |
330 | img_ir_timings_defaults(&decoder->rtimings, &decoder->timings); | |
331 | } | |
332 | } | |
333 | ||
334 | /** | |
335 | * img_ir_decoder_convert() - Generate internal timings in decoder. | |
336 | * @decoder: Decoder to be converted to internal timings. | |
337 | * @timings: Timing register values. | |
338 | * @clock_hz: IR clock rate in Hz. | |
339 | * | |
340 | * Fills out the repeat timings and timing register values for a specific clock | |
341 | * rate. | |
342 | */ | |
343 | static void img_ir_decoder_convert(const struct img_ir_decoder *decoder, | |
344 | struct img_ir_reg_timings *reg_timings, | |
345 | unsigned int clock_hz) | |
346 | { | |
347 | /* calculate control value */ | |
348 | reg_timings->ctrl = img_ir_control(&decoder->control); | |
349 | ||
350 | /* fill in implicit fields and calculate register values */ | |
351 | img_ir_timings_convert(®_timings->timings, &decoder->timings, | |
352 | decoder->tolerance, clock_hz); | |
353 | ||
354 | /* do the same for repeat timings if applicable */ | |
355 | if (decoder->repeat) | |
356 | img_ir_timings_convert(®_timings->rtimings, | |
357 | &decoder->rtimings, decoder->tolerance, | |
358 | clock_hz); | |
359 | } | |
360 | ||
361 | /** | |
362 | * img_ir_write_timings() - Write timings to the hardware now | |
363 | * @priv: IR private data | |
364 | * @regs: Timing register values to write | |
365 | * @type: RC filter type (RC_FILTER_*) | |
366 | * | |
367 | * Write timing register values @regs to the hardware, taking into account the | |
368 | * current filter which may impose restrictions on the length of the expected | |
369 | * data. | |
370 | */ | |
371 | static void img_ir_write_timings(struct img_ir_priv *priv, | |
372 | struct img_ir_timing_regvals *regs, | |
373 | enum rc_filter_type type) | |
374 | { | |
375 | struct img_ir_priv_hw *hw = &priv->hw; | |
376 | ||
377 | /* filter may be more restrictive to minlen, maxlen */ | |
378 | u32 ft = regs->ft; | |
379 | if (hw->flags & BIT(type)) | |
380 | ft = img_ir_free_timing_dynamic(regs->ft, &hw->filters[type]); | |
381 | /* write to registers */ | |
382 | img_ir_write(priv, IMG_IR_LEAD_SYMB_TIMING, regs->ldr); | |
383 | img_ir_write(priv, IMG_IR_S00_SYMB_TIMING, regs->s00); | |
384 | img_ir_write(priv, IMG_IR_S01_SYMB_TIMING, regs->s01); | |
385 | img_ir_write(priv, IMG_IR_S10_SYMB_TIMING, regs->s10); | |
386 | img_ir_write(priv, IMG_IR_S11_SYMB_TIMING, regs->s11); | |
387 | img_ir_write(priv, IMG_IR_FREE_SYMB_TIMING, ft); | |
388 | dev_dbg(priv->dev, "timings: ldr=%#x, s=[%#x, %#x, %#x, %#x], ft=%#x\n", | |
389 | regs->ldr, regs->s00, regs->s01, regs->s10, regs->s11, ft); | |
390 | } | |
391 | ||
392 | static void img_ir_write_filter(struct img_ir_priv *priv, | |
393 | struct img_ir_filter *filter) | |
394 | { | |
395 | if (filter) { | |
396 | dev_dbg(priv->dev, "IR filter=%016llx & %016llx\n", | |
397 | (unsigned long long)filter->data, | |
398 | (unsigned long long)filter->mask); | |
399 | img_ir_write(priv, IMG_IR_IRQ_MSG_DATA_LW, (u32)filter->data); | |
400 | img_ir_write(priv, IMG_IR_IRQ_MSG_DATA_UP, (u32)(filter->data | |
401 | >> 32)); | |
402 | img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_LW, (u32)filter->mask); | |
403 | img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_UP, (u32)(filter->mask | |
404 | >> 32)); | |
405 | } else { | |
406 | dev_dbg(priv->dev, "IR clearing filter\n"); | |
407 | img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_LW, 0); | |
408 | img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_UP, 0); | |
409 | } | |
410 | } | |
411 | ||
412 | /* caller must have lock */ | |
413 | static void _img_ir_set_filter(struct img_ir_priv *priv, | |
414 | struct img_ir_filter *filter) | |
415 | { | |
416 | struct img_ir_priv_hw *hw = &priv->hw; | |
417 | u32 irq_en, irq_on; | |
418 | ||
419 | irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE); | |
420 | if (filter) { | |
421 | /* Only use the match interrupt */ | |
422 | hw->filters[RC_FILTER_NORMAL] = *filter; | |
423 | hw->flags |= IMG_IR_F_FILTER; | |
424 | irq_on = IMG_IR_IRQ_DATA_MATCH; | |
425 | irq_en &= ~(IMG_IR_IRQ_DATA_VALID | IMG_IR_IRQ_DATA2_VALID); | |
426 | } else { | |
427 | /* Only use the valid interrupt */ | |
428 | hw->flags &= ~IMG_IR_F_FILTER; | |
429 | irq_en &= ~IMG_IR_IRQ_DATA_MATCH; | |
430 | irq_on = IMG_IR_IRQ_DATA_VALID | IMG_IR_IRQ_DATA2_VALID; | |
431 | } | |
432 | irq_en |= irq_on; | |
433 | ||
434 | img_ir_write_filter(priv, filter); | |
435 | /* clear any interrupts we're enabling so we don't handle old ones */ | |
436 | img_ir_write(priv, IMG_IR_IRQ_CLEAR, irq_on); | |
437 | img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en); | |
438 | } | |
439 | ||
440 | /* caller must have lock */ | |
441 | static void _img_ir_set_wake_filter(struct img_ir_priv *priv, | |
442 | struct img_ir_filter *filter) | |
443 | { | |
444 | struct img_ir_priv_hw *hw = &priv->hw; | |
445 | if (filter) { | |
446 | /* Enable wake, and copy filter for later */ | |
447 | hw->filters[RC_FILTER_WAKEUP] = *filter; | |
448 | hw->flags |= IMG_IR_F_WAKE; | |
449 | } else { | |
450 | /* Disable wake */ | |
451 | hw->flags &= ~IMG_IR_F_WAKE; | |
452 | } | |
453 | } | |
454 | ||
455 | /* Callback for setting scancode filter */ | |
456 | static int img_ir_set_filter(struct rc_dev *dev, enum rc_filter_type type, | |
457 | struct rc_scancode_filter *sc_filter) | |
458 | { | |
459 | struct img_ir_priv *priv = dev->priv; | |
460 | struct img_ir_priv_hw *hw = &priv->hw; | |
461 | struct img_ir_filter filter, *filter_ptr = &filter; | |
462 | int ret = 0; | |
463 | ||
464 | dev_dbg(priv->dev, "IR scancode %sfilter=%08x & %08x\n", | |
465 | type == RC_FILTER_WAKEUP ? "wake " : "", | |
466 | sc_filter->data, | |
467 | sc_filter->mask); | |
468 | ||
469 | spin_lock_irq(&priv->lock); | |
470 | ||
471 | /* filtering can always be disabled */ | |
472 | if (!sc_filter->mask) { | |
473 | filter_ptr = NULL; | |
474 | goto set_unlock; | |
475 | } | |
476 | ||
477 | /* current decoder must support scancode filtering */ | |
478 | if (!hw->decoder || !hw->decoder->filter) { | |
479 | ret = -EINVAL; | |
480 | goto unlock; | |
481 | } | |
482 | ||
483 | /* convert scancode filter to raw filter */ | |
484 | filter.minlen = 0; | |
485 | filter.maxlen = ~0; | |
486 | ret = hw->decoder->filter(sc_filter, &filter, hw->enabled_protocols); | |
487 | if (ret) | |
488 | goto unlock; | |
489 | dev_dbg(priv->dev, "IR raw %sfilter=%016llx & %016llx\n", | |
490 | type == RC_FILTER_WAKEUP ? "wake " : "", | |
491 | (unsigned long long)filter.data, | |
492 | (unsigned long long)filter.mask); | |
493 | ||
494 | set_unlock: | |
495 | /* apply raw filters */ | |
496 | switch (type) { | |
497 | case RC_FILTER_NORMAL: | |
498 | _img_ir_set_filter(priv, filter_ptr); | |
499 | break; | |
500 | case RC_FILTER_WAKEUP: | |
501 | _img_ir_set_wake_filter(priv, filter_ptr); | |
502 | break; | |
503 | default: | |
504 | ret = -EINVAL; | |
54ece68d | 505 | } |
30dd9e0c JH |
506 | |
507 | unlock: | |
508 | spin_unlock_irq(&priv->lock); | |
509 | return ret; | |
510 | } | |
511 | ||
23c843b5 DH |
512 | static int img_ir_set_normal_filter(struct rc_dev *dev, |
513 | struct rc_scancode_filter *sc_filter) | |
514 | { | |
120703f9 | 515 | return img_ir_set_filter(dev, RC_FILTER_NORMAL, sc_filter); |
23c843b5 DH |
516 | } |
517 | ||
518 | static int img_ir_set_wakeup_filter(struct rc_dev *dev, | |
519 | struct rc_scancode_filter *sc_filter) | |
520 | { | |
521 | return img_ir_set_filter(dev, RC_FILTER_WAKEUP, sc_filter); | |
522 | } | |
523 | ||
30dd9e0c JH |
524 | /** |
525 | * img_ir_set_decoder() - Set the current decoder. | |
526 | * @priv: IR private data. | |
527 | * @decoder: Decoder to use with immediate effect. | |
528 | * @proto: Protocol bitmap (or 0 to use decoder->type). | |
529 | */ | |
530 | static void img_ir_set_decoder(struct img_ir_priv *priv, | |
531 | const struct img_ir_decoder *decoder, | |
532 | u64 proto) | |
533 | { | |
534 | struct img_ir_priv_hw *hw = &priv->hw; | |
535 | struct rc_dev *rdev = hw->rdev; | |
536 | u32 ir_status, irq_en; | |
537 | spin_lock_irq(&priv->lock); | |
538 | ||
539 | /* switch off and disable interrupts */ | |
540 | img_ir_write(priv, IMG_IR_CONTROL, 0); | |
541 | irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE); | |
542 | img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en & IMG_IR_IRQ_EDGE); | |
543 | img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_ALL & ~IMG_IR_IRQ_EDGE); | |
544 | ||
545 | /* ack any data already detected */ | |
546 | ir_status = img_ir_read(priv, IMG_IR_STATUS); | |
547 | if (ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)) { | |
548 | ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2); | |
549 | img_ir_write(priv, IMG_IR_STATUS, ir_status); | |
550 | img_ir_read(priv, IMG_IR_DATA_LW); | |
551 | img_ir_read(priv, IMG_IR_DATA_UP); | |
552 | } | |
553 | ||
554 | /* stop the end timer and switch back to normal mode */ | |
555 | del_timer_sync(&hw->end_timer); | |
556 | hw->mode = IMG_IR_M_NORMAL; | |
557 | ||
558 | /* clear the wakeup scancode filter */ | |
559 | rdev->scancode_filters[RC_FILTER_WAKEUP].data = 0; | |
560 | rdev->scancode_filters[RC_FILTER_WAKEUP].mask = 0; | |
561 | ||
562 | /* clear raw filters */ | |
563 | _img_ir_set_filter(priv, NULL); | |
564 | _img_ir_set_wake_filter(priv, NULL); | |
565 | ||
566 | /* clear the enabled protocols */ | |
567 | hw->enabled_protocols = 0; | |
568 | ||
569 | /* switch decoder */ | |
570 | hw->decoder = decoder; | |
571 | if (!decoder) | |
572 | goto unlock; | |
573 | ||
574 | /* set the enabled protocols */ | |
575 | if (!proto) | |
576 | proto = decoder->type; | |
577 | hw->enabled_protocols = proto; | |
578 | ||
579 | /* write the new timings */ | |
580 | img_ir_decoder_convert(decoder, &hw->reg_timings, hw->clk_hz); | |
581 | img_ir_write_timings(priv, &hw->reg_timings.timings, RC_FILTER_NORMAL); | |
582 | ||
583 | /* set up and enable */ | |
584 | img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl); | |
585 | ||
586 | ||
587 | unlock: | |
588 | spin_unlock_irq(&priv->lock); | |
589 | } | |
590 | ||
591 | /** | |
592 | * img_ir_decoder_compatable() - Find whether a decoder will work with a device. | |
593 | * @priv: IR private data. | |
594 | * @dec: Decoder to check. | |
595 | * | |
596 | * Returns: true if @dec is compatible with the device @priv refers to. | |
597 | */ | |
598 | static bool img_ir_decoder_compatible(struct img_ir_priv *priv, | |
599 | const struct img_ir_decoder *dec) | |
600 | { | |
601 | unsigned int ct; | |
602 | ||
603 | /* don't accept decoders using code types which aren't supported */ | |
604 | ct = dec->control.code_type; | |
605 | if (priv->hw.ct_quirks[ct] & IMG_IR_QUIRK_CODE_BROKEN) | |
606 | return false; | |
607 | ||
608 | return true; | |
609 | } | |
610 | ||
611 | /** | |
612 | * img_ir_allowed_protos() - Get allowed protocols from global decoder list. | |
613 | * @priv: IR private data. | |
614 | * | |
615 | * Returns: Mask of protocols supported by the device @priv refers to. | |
616 | */ | |
617 | static u64 img_ir_allowed_protos(struct img_ir_priv *priv) | |
618 | { | |
619 | u64 protos = 0; | |
620 | struct img_ir_decoder **decp; | |
621 | ||
622 | for (decp = img_ir_decoders; *decp; ++decp) { | |
623 | const struct img_ir_decoder *dec = *decp; | |
624 | if (img_ir_decoder_compatible(priv, dec)) | |
625 | protos |= dec->type; | |
626 | } | |
627 | return protos; | |
628 | } | |
629 | ||
630 | /* Callback for changing protocol using sysfs */ | |
631 | static int img_ir_change_protocol(struct rc_dev *dev, u64 *ir_type) | |
632 | { | |
633 | struct img_ir_priv *priv = dev->priv; | |
634 | struct img_ir_priv_hw *hw = &priv->hw; | |
635 | struct rc_dev *rdev = hw->rdev; | |
636 | struct img_ir_decoder **decp; | |
637 | u64 wakeup_protocols; | |
638 | ||
639 | if (!*ir_type) { | |
640 | /* disable all protocols */ | |
641 | img_ir_set_decoder(priv, NULL, 0); | |
642 | goto success; | |
643 | } | |
644 | for (decp = img_ir_decoders; *decp; ++decp) { | |
645 | const struct img_ir_decoder *dec = *decp; | |
646 | if (!img_ir_decoder_compatible(priv, dec)) | |
647 | continue; | |
648 | if (*ir_type & dec->type) { | |
649 | *ir_type &= dec->type; | |
650 | img_ir_set_decoder(priv, dec, *ir_type); | |
651 | goto success; | |
652 | } | |
653 | } | |
654 | return -EINVAL; | |
655 | ||
656 | success: | |
657 | /* | |
658 | * Only allow matching wakeup protocols for now, and only if filtering | |
659 | * is supported. | |
660 | */ | |
661 | wakeup_protocols = *ir_type; | |
662 | if (!hw->decoder || !hw->decoder->filter) | |
663 | wakeup_protocols = 0; | |
664 | rc_set_allowed_wakeup_protocols(rdev, wakeup_protocols); | |
665 | rc_set_enabled_wakeup_protocols(rdev, wakeup_protocols); | |
666 | return 0; | |
667 | } | |
668 | ||
669 | /* Changes ir-core protocol device attribute */ | |
670 | static void img_ir_set_protocol(struct img_ir_priv *priv, u64 proto) | |
671 | { | |
672 | struct rc_dev *rdev = priv->hw.rdev; | |
673 | ||
674 | spin_lock_irq(&rdev->rc_map.lock); | |
675 | rdev->rc_map.rc_type = __ffs64(proto); | |
676 | spin_unlock_irq(&rdev->rc_map.lock); | |
677 | ||
678 | mutex_lock(&rdev->lock); | |
679 | rc_set_enabled_protocols(rdev, proto); | |
680 | rc_set_allowed_wakeup_protocols(rdev, proto); | |
681 | rc_set_enabled_wakeup_protocols(rdev, proto); | |
682 | mutex_unlock(&rdev->lock); | |
683 | } | |
684 | ||
685 | /* Set up IR decoders */ | |
686 | static void img_ir_init_decoders(void) | |
687 | { | |
688 | struct img_ir_decoder **decp; | |
689 | ||
690 | spin_lock(&img_ir_decoders_lock); | |
691 | if (!img_ir_decoders_preprocessed) { | |
692 | for (decp = img_ir_decoders; *decp; ++decp) | |
693 | img_ir_decoder_preprocess(*decp); | |
694 | img_ir_decoders_preprocessed = true; | |
695 | } | |
696 | spin_unlock(&img_ir_decoders_lock); | |
697 | } | |
698 | ||
699 | #ifdef CONFIG_PM_SLEEP | |
700 | /** | |
701 | * img_ir_enable_wake() - Switch to wake mode. | |
702 | * @priv: IR private data. | |
703 | * | |
704 | * Returns: non-zero if the IR can wake the system. | |
705 | */ | |
706 | static int img_ir_enable_wake(struct img_ir_priv *priv) | |
707 | { | |
708 | struct img_ir_priv_hw *hw = &priv->hw; | |
709 | int ret = 0; | |
710 | ||
711 | spin_lock_irq(&priv->lock); | |
712 | if (hw->flags & IMG_IR_F_WAKE) { | |
713 | /* interrupt only on a match */ | |
714 | hw->suspend_irqen = img_ir_read(priv, IMG_IR_IRQ_ENABLE); | |
715 | img_ir_write(priv, IMG_IR_IRQ_ENABLE, IMG_IR_IRQ_DATA_MATCH); | |
716 | img_ir_write_filter(priv, &hw->filters[RC_FILTER_WAKEUP]); | |
717 | img_ir_write_timings(priv, &hw->reg_timings.timings, | |
718 | RC_FILTER_WAKEUP); | |
719 | hw->mode = IMG_IR_M_WAKE; | |
720 | ret = 1; | |
721 | } | |
722 | spin_unlock_irq(&priv->lock); | |
723 | return ret; | |
724 | } | |
725 | ||
726 | /** | |
727 | * img_ir_disable_wake() - Switch out of wake mode. | |
728 | * @priv: IR private data | |
729 | * | |
730 | * Returns: 1 if the hardware should be allowed to wake from a sleep state. | |
731 | * 0 otherwise. | |
732 | */ | |
733 | static int img_ir_disable_wake(struct img_ir_priv *priv) | |
734 | { | |
735 | struct img_ir_priv_hw *hw = &priv->hw; | |
736 | int ret = 0; | |
737 | ||
738 | spin_lock_irq(&priv->lock); | |
739 | if (hw->flags & IMG_IR_F_WAKE) { | |
740 | /* restore normal filtering */ | |
741 | if (hw->flags & IMG_IR_F_FILTER) { | |
742 | img_ir_write(priv, IMG_IR_IRQ_ENABLE, | |
743 | (hw->suspend_irqen & IMG_IR_IRQ_EDGE) | | |
744 | IMG_IR_IRQ_DATA_MATCH); | |
745 | img_ir_write_filter(priv, | |
746 | &hw->filters[RC_FILTER_NORMAL]); | |
747 | } else { | |
748 | img_ir_write(priv, IMG_IR_IRQ_ENABLE, | |
749 | (hw->suspend_irqen & IMG_IR_IRQ_EDGE) | | |
750 | IMG_IR_IRQ_DATA_VALID | | |
751 | IMG_IR_IRQ_DATA2_VALID); | |
752 | img_ir_write_filter(priv, NULL); | |
753 | } | |
754 | img_ir_write_timings(priv, &hw->reg_timings.timings, | |
755 | RC_FILTER_NORMAL); | |
756 | hw->mode = IMG_IR_M_NORMAL; | |
757 | ret = 1; | |
758 | } | |
759 | spin_unlock_irq(&priv->lock); | |
760 | return ret; | |
761 | } | |
762 | #endif /* CONFIG_PM_SLEEP */ | |
763 | ||
764 | /* lock must be held */ | |
765 | static void img_ir_begin_repeat(struct img_ir_priv *priv) | |
766 | { | |
767 | struct img_ir_priv_hw *hw = &priv->hw; | |
768 | if (hw->mode == IMG_IR_M_NORMAL) { | |
769 | /* switch to repeat timings */ | |
770 | img_ir_write(priv, IMG_IR_CONTROL, 0); | |
771 | hw->mode = IMG_IR_M_REPEATING; | |
772 | img_ir_write_timings(priv, &hw->reg_timings.rtimings, | |
773 | RC_FILTER_NORMAL); | |
774 | img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl); | |
775 | } | |
776 | } | |
777 | ||
778 | /* lock must be held */ | |
779 | static void img_ir_end_repeat(struct img_ir_priv *priv) | |
780 | { | |
781 | struct img_ir_priv_hw *hw = &priv->hw; | |
782 | if (hw->mode == IMG_IR_M_REPEATING) { | |
783 | /* switch to normal timings */ | |
784 | img_ir_write(priv, IMG_IR_CONTROL, 0); | |
785 | hw->mode = IMG_IR_M_NORMAL; | |
786 | img_ir_write_timings(priv, &hw->reg_timings.timings, | |
787 | RC_FILTER_NORMAL); | |
788 | img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl); | |
789 | } | |
790 | } | |
791 | ||
792 | /* lock must be held */ | |
793 | static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw) | |
794 | { | |
795 | struct img_ir_priv_hw *hw = &priv->hw; | |
796 | const struct img_ir_decoder *dec = hw->decoder; | |
797 | int ret = IMG_IR_SCANCODE; | |
120703f9 DH |
798 | u32 scancode; |
799 | enum rc_type protocol = RC_TYPE_UNKNOWN; | |
800 | ||
30dd9e0c | 801 | if (dec->scancode) |
120703f9 | 802 | ret = dec->scancode(len, raw, &protocol, &scancode, hw->enabled_protocols); |
30dd9e0c JH |
803 | else if (len >= 32) |
804 | scancode = (u32)raw; | |
805 | else if (len < 32) | |
806 | scancode = (u32)raw & ((1 << len)-1); | |
807 | dev_dbg(priv->dev, "data (%u bits) = %#llx\n", | |
808 | len, (unsigned long long)raw); | |
809 | if (ret == IMG_IR_SCANCODE) { | |
810 | dev_dbg(priv->dev, "decoded scan code %#x\n", scancode); | |
120703f9 | 811 | rc_keydown(hw->rdev, protocol, scancode, 0); |
30dd9e0c JH |
812 | img_ir_end_repeat(priv); |
813 | } else if (ret == IMG_IR_REPEATCODE) { | |
814 | if (hw->mode == IMG_IR_M_REPEATING) { | |
815 | dev_dbg(priv->dev, "decoded repeat code\n"); | |
816 | rc_repeat(hw->rdev); | |
817 | } else { | |
818 | dev_dbg(priv->dev, "decoded unexpected repeat code, ignoring\n"); | |
819 | } | |
820 | } else { | |
821 | dev_dbg(priv->dev, "decode failed (%d)\n", ret); | |
822 | return; | |
823 | } | |
824 | ||
825 | ||
826 | if (dec->repeat) { | |
827 | unsigned long interval; | |
828 | ||
829 | img_ir_begin_repeat(priv); | |
830 | ||
831 | /* update timer, but allowing for 1/8th tolerance */ | |
832 | interval = dec->repeat + (dec->repeat >> 3); | |
833 | mod_timer(&hw->end_timer, | |
834 | jiffies + msecs_to_jiffies(interval)); | |
835 | } | |
836 | } | |
837 | ||
838 | /* timer function to end waiting for repeat. */ | |
839 | static void img_ir_end_timer(unsigned long arg) | |
840 | { | |
841 | struct img_ir_priv *priv = (struct img_ir_priv *)arg; | |
842 | ||
843 | spin_lock_irq(&priv->lock); | |
844 | img_ir_end_repeat(priv); | |
845 | spin_unlock_irq(&priv->lock); | |
846 | } | |
847 | ||
848 | #ifdef CONFIG_COMMON_CLK | |
849 | static void img_ir_change_frequency(struct img_ir_priv *priv, | |
850 | struct clk_notifier_data *change) | |
851 | { | |
852 | struct img_ir_priv_hw *hw = &priv->hw; | |
853 | ||
854 | dev_dbg(priv->dev, "clk changed %lu HZ -> %lu HZ\n", | |
855 | change->old_rate, change->new_rate); | |
856 | ||
857 | spin_lock_irq(&priv->lock); | |
858 | if (hw->clk_hz == change->new_rate) | |
859 | goto unlock; | |
860 | hw->clk_hz = change->new_rate; | |
861 | /* refresh current timings */ | |
862 | if (hw->decoder) { | |
863 | img_ir_decoder_convert(hw->decoder, &hw->reg_timings, | |
864 | hw->clk_hz); | |
865 | switch (hw->mode) { | |
866 | case IMG_IR_M_NORMAL: | |
867 | img_ir_write_timings(priv, &hw->reg_timings.timings, | |
868 | RC_FILTER_NORMAL); | |
869 | break; | |
870 | case IMG_IR_M_REPEATING: | |
871 | img_ir_write_timings(priv, &hw->reg_timings.rtimings, | |
872 | RC_FILTER_NORMAL); | |
873 | break; | |
874 | #ifdef CONFIG_PM_SLEEP | |
875 | case IMG_IR_M_WAKE: | |
876 | img_ir_write_timings(priv, &hw->reg_timings.timings, | |
877 | RC_FILTER_WAKEUP); | |
878 | break; | |
879 | #endif | |
880 | } | |
881 | } | |
882 | unlock: | |
883 | spin_unlock_irq(&priv->lock); | |
884 | } | |
885 | ||
886 | static int img_ir_clk_notify(struct notifier_block *self, unsigned long action, | |
887 | void *data) | |
888 | { | |
889 | struct img_ir_priv *priv = container_of(self, struct img_ir_priv, | |
890 | hw.clk_nb); | |
891 | switch (action) { | |
892 | case POST_RATE_CHANGE: | |
893 | img_ir_change_frequency(priv, data); | |
894 | break; | |
895 | default: | |
896 | break; | |
897 | } | |
898 | return NOTIFY_OK; | |
899 | } | |
900 | #endif /* CONFIG_COMMON_CLK */ | |
901 | ||
902 | /* called with priv->lock held */ | |
903 | void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status) | |
904 | { | |
905 | struct img_ir_priv_hw *hw = &priv->hw; | |
906 | u32 ir_status, len, lw, up; | |
907 | unsigned int ct; | |
908 | ||
909 | /* use the current decoder */ | |
910 | if (!hw->decoder) | |
911 | return; | |
912 | ||
913 | ir_status = img_ir_read(priv, IMG_IR_STATUS); | |
914 | if (!(ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2))) | |
915 | return; | |
916 | ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2); | |
917 | img_ir_write(priv, IMG_IR_STATUS, ir_status); | |
918 | ||
919 | len = (ir_status & IMG_IR_RXDLEN) >> IMG_IR_RXDLEN_SHIFT; | |
920 | /* some versions report wrong length for certain code types */ | |
921 | ct = hw->decoder->control.code_type; | |
922 | if (hw->ct_quirks[ct] & IMG_IR_QUIRK_CODE_LEN_INCR) | |
923 | ++len; | |
924 | ||
925 | lw = img_ir_read(priv, IMG_IR_DATA_LW); | |
926 | up = img_ir_read(priv, IMG_IR_DATA_UP); | |
927 | img_ir_handle_data(priv, len, (u64)up << 32 | lw); | |
928 | } | |
929 | ||
930 | void img_ir_setup_hw(struct img_ir_priv *priv) | |
931 | { | |
932 | struct img_ir_decoder **decp; | |
933 | ||
934 | if (!priv->hw.rdev) | |
935 | return; | |
936 | ||
937 | /* Use the first available decoder (or disable stuff if NULL) */ | |
938 | for (decp = img_ir_decoders; *decp; ++decp) { | |
939 | const struct img_ir_decoder *dec = *decp; | |
940 | if (img_ir_decoder_compatible(priv, dec)) { | |
941 | img_ir_set_protocol(priv, dec->type); | |
942 | img_ir_set_decoder(priv, dec, 0); | |
943 | return; | |
944 | } | |
945 | } | |
946 | img_ir_set_decoder(priv, NULL, 0); | |
947 | } | |
948 | ||
949 | /** | |
950 | * img_ir_probe_hw_caps() - Probe capabilities of the hardware. | |
951 | * @priv: IR private data. | |
952 | */ | |
953 | static void img_ir_probe_hw_caps(struct img_ir_priv *priv) | |
954 | { | |
955 | struct img_ir_priv_hw *hw = &priv->hw; | |
956 | /* | |
957 | * When a version of the block becomes available without these quirks, | |
958 | * they'll have to depend on the core revision. | |
959 | */ | |
960 | hw->ct_quirks[IMG_IR_CODETYPE_PULSELEN] | |
961 | |= IMG_IR_QUIRK_CODE_LEN_INCR; | |
962 | hw->ct_quirks[IMG_IR_CODETYPE_BIPHASE] | |
963 | |= IMG_IR_QUIRK_CODE_BROKEN; | |
964 | hw->ct_quirks[IMG_IR_CODETYPE_2BITPULSEPOS] | |
965 | |= IMG_IR_QUIRK_CODE_BROKEN; | |
966 | } | |
967 | ||
968 | int img_ir_probe_hw(struct img_ir_priv *priv) | |
969 | { | |
970 | struct img_ir_priv_hw *hw = &priv->hw; | |
971 | struct rc_dev *rdev; | |
972 | int error; | |
973 | ||
974 | /* Ensure hardware decoders have been preprocessed */ | |
975 | img_ir_init_decoders(); | |
976 | ||
977 | /* Probe hardware capabilities */ | |
978 | img_ir_probe_hw_caps(priv); | |
979 | ||
980 | /* Set up the end timer */ | |
981 | setup_timer(&hw->end_timer, img_ir_end_timer, (unsigned long)priv); | |
982 | ||
983 | /* Register a clock notifier */ | |
984 | if (!IS_ERR(priv->clk)) { | |
985 | hw->clk_hz = clk_get_rate(priv->clk); | |
986 | #ifdef CONFIG_COMMON_CLK | |
987 | hw->clk_nb.notifier_call = img_ir_clk_notify; | |
988 | error = clk_notifier_register(priv->clk, &hw->clk_nb); | |
989 | if (error) | |
990 | dev_warn(priv->dev, | |
991 | "failed to register clock notifier\n"); | |
992 | #endif | |
993 | } else { | |
994 | hw->clk_hz = 32768; | |
995 | } | |
996 | ||
997 | /* Allocate hardware decoder */ | |
998 | hw->rdev = rdev = rc_allocate_device(); | |
999 | if (!rdev) { | |
1000 | dev_err(priv->dev, "cannot allocate input device\n"); | |
1001 | error = -ENOMEM; | |
1002 | goto err_alloc_rc; | |
1003 | } | |
1004 | rdev->priv = priv; | |
1005 | rdev->map_name = RC_MAP_EMPTY; | |
1006 | rc_set_allowed_protocols(rdev, img_ir_allowed_protos(priv)); | |
1007 | rdev->input_name = "IMG Infrared Decoder"; | |
23c843b5 DH |
1008 | rdev->s_filter = img_ir_set_normal_filter; |
1009 | rdev->s_wakeup_filter = img_ir_set_wakeup_filter; | |
30dd9e0c JH |
1010 | |
1011 | /* Register hardware decoder */ | |
1012 | error = rc_register_device(rdev); | |
1013 | if (error) { | |
1014 | dev_err(priv->dev, "failed to register IR input device\n"); | |
1015 | goto err_register_rc; | |
1016 | } | |
1017 | ||
1018 | /* | |
1019 | * Set this after rc_register_device as no protocols have been | |
1020 | * registered yet. | |
1021 | */ | |
1022 | rdev->change_protocol = img_ir_change_protocol; | |
1023 | ||
1024 | device_init_wakeup(priv->dev, 1); | |
1025 | ||
1026 | return 0; | |
1027 | ||
1028 | err_register_rc: | |
1029 | img_ir_set_decoder(priv, NULL, 0); | |
1030 | hw->rdev = NULL; | |
1031 | rc_free_device(rdev); | |
1032 | err_alloc_rc: | |
1033 | #ifdef CONFIG_COMMON_CLK | |
1034 | if (!IS_ERR(priv->clk)) | |
1035 | clk_notifier_unregister(priv->clk, &hw->clk_nb); | |
1036 | #endif | |
1037 | return error; | |
1038 | } | |
1039 | ||
1040 | void img_ir_remove_hw(struct img_ir_priv *priv) | |
1041 | { | |
1042 | struct img_ir_priv_hw *hw = &priv->hw; | |
1043 | struct rc_dev *rdev = hw->rdev; | |
1044 | if (!rdev) | |
1045 | return; | |
1046 | img_ir_set_decoder(priv, NULL, 0); | |
1047 | hw->rdev = NULL; | |
1048 | rc_unregister_device(rdev); | |
1049 | #ifdef CONFIG_COMMON_CLK | |
1050 | if (!IS_ERR(priv->clk)) | |
1051 | clk_notifier_unregister(priv->clk, &hw->clk_nb); | |
1052 | #endif | |
1053 | } | |
1054 | ||
1055 | #ifdef CONFIG_PM_SLEEP | |
1056 | int img_ir_suspend(struct device *dev) | |
1057 | { | |
1058 | struct img_ir_priv *priv = dev_get_drvdata(dev); | |
1059 | ||
1060 | if (device_may_wakeup(dev) && img_ir_enable_wake(priv)) | |
1061 | enable_irq_wake(priv->irq); | |
1062 | return 0; | |
1063 | } | |
1064 | ||
1065 | int img_ir_resume(struct device *dev) | |
1066 | { | |
1067 | struct img_ir_priv *priv = dev_get_drvdata(dev); | |
1068 | ||
1069 | if (device_may_wakeup(dev) && img_ir_disable_wake(priv)) | |
1070 | disable_irq_wake(priv->irq); | |
1071 | return 0; | |
1072 | } | |
1073 | #endif /* CONFIG_PM_SLEEP */ |