2 * ImgTec IR Raw Decoder found in PowerDown Controller.
4 * Copyright 2010-2014 Imagination Technologies Ltd.
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.
11 * This ties into the input subsystem using the RC-core in raw mode. Raw IR
12 * signal edges are reported and decoded by generic software decoders.
15 #include <linux/spinlock.h>
16 #include <media/rc-core.h>
19 #define ECHO_TIMEOUT_MS 150 /* ms between echos */
21 /* must be called with priv->lock held */
22 static void img_ir_refresh_raw(struct img_ir_priv
*priv
, u32 irq_status
)
24 struct img_ir_priv_raw
*raw
= &priv
->raw
;
25 struct rc_dev
*rc_dev
= priv
->raw
.rdev
;
29 /* find whether both rise and fall was detected */
30 multiple
= ((irq_status
& IMG_IR_IRQ_EDGE
) == IMG_IR_IRQ_EDGE
);
32 * If so, we need to see if the level has actually changed.
33 * If it's just noise that we didn't have time to process,
34 * there's no point reporting it.
36 ir_status
= img_ir_read(priv
, IMG_IR_STATUS
) & IMG_IR_IRRXD
;
37 if (multiple
&& ir_status
== raw
->last_status
)
39 raw
->last_status
= ir_status
;
41 /* report the edge to the IR raw decoders */
42 if (ir_status
) /* low */
43 ir_raw_event_store_edge(rc_dev
, false);
45 ir_raw_event_store_edge(rc_dev
, true);
46 ir_raw_event_handle(rc_dev
);
49 /* called with priv->lock held */
50 void img_ir_isr_raw(struct img_ir_priv
*priv
, u32 irq_status
)
52 struct img_ir_priv_raw
*raw
= &priv
->raw
;
54 /* check not removing */
58 img_ir_refresh_raw(priv
, irq_status
);
60 /* start / push back the echo timer */
61 mod_timer(&raw
->timer
, jiffies
+ msecs_to_jiffies(ECHO_TIMEOUT_MS
));
65 * Echo timer callback function.
66 * The raw decoders expect to get a final sample even if there are no edges, in
67 * order to be assured of the final space. If there are no edges for a certain
68 * time we use this timer to emit a final sample to satisfy them.
70 static void img_ir_echo_timer(struct timer_list
*t
)
72 struct img_ir_priv
*priv
= from_timer(priv
, t
, raw
.timer
);
74 spin_lock_irq(&priv
->lock
);
76 /* check not removing */
79 * It's safe to pass irq_status=0 since it's only used to check
82 img_ir_refresh_raw(priv
, 0);
84 spin_unlock_irq(&priv
->lock
);
87 void img_ir_setup_raw(struct img_ir_priv
*priv
)
94 /* clear and enable edge interrupts */
95 spin_lock_irq(&priv
->lock
);
96 irq_en
= img_ir_read(priv
, IMG_IR_IRQ_ENABLE
);
97 irq_en
|= IMG_IR_IRQ_EDGE
;
98 img_ir_write(priv
, IMG_IR_IRQ_CLEAR
, IMG_IR_IRQ_EDGE
);
99 img_ir_write(priv
, IMG_IR_IRQ_ENABLE
, irq_en
);
100 spin_unlock_irq(&priv
->lock
);
103 int img_ir_probe_raw(struct img_ir_priv
*priv
)
105 struct img_ir_priv_raw
*raw
= &priv
->raw
;
109 /* Set up the echo timer */
110 timer_setup(&raw
->timer
, img_ir_echo_timer
, 0);
112 /* Allocate raw decoder */
113 raw
->rdev
= rdev
= rc_allocate_device(RC_DRIVER_IR_RAW
);
115 dev_err(priv
->dev
, "cannot allocate raw input device\n");
119 rdev
->map_name
= RC_MAP_EMPTY
;
120 rdev
->device_name
= "IMG Infrared Decoder Raw";
122 /* Register raw decoder */
123 error
= rc_register_device(rdev
);
125 dev_err(priv
->dev
, "failed to register raw IR input device\n");
126 rc_free_device(rdev
);
134 void img_ir_remove_raw(struct img_ir_priv
*priv
)
136 struct img_ir_priv_raw
*raw
= &priv
->raw
;
137 struct rc_dev
*rdev
= raw
->rdev
;
143 /* switch off and disable raw (edge) interrupts */
144 spin_lock_irq(&priv
->lock
);
146 irq_en
= img_ir_read(priv
, IMG_IR_IRQ_ENABLE
);
147 irq_en
&= ~IMG_IR_IRQ_EDGE
;
148 img_ir_write(priv
, IMG_IR_IRQ_ENABLE
, irq_en
);
149 img_ir_write(priv
, IMG_IR_IRQ_CLEAR
, IMG_IR_IRQ_EDGE
);
150 spin_unlock_irq(&priv
->lock
);
152 rc_unregister_device(rdev
);
154 del_timer_sync(&raw
->timer
);