This source file includes following definitions.
- img_ir_refresh_raw
- img_ir_isr_raw
- img_ir_echo_timer
- img_ir_setup_raw
- img_ir_probe_raw
- img_ir_remove_raw
1
2
3
4
5
6
7
8
9
10
11 #include <linux/spinlock.h>
12 #include <media/rc-core.h>
13 #include "img-ir.h"
14
15 #define ECHO_TIMEOUT_MS 150
16
17
18 static void img_ir_refresh_raw(struct img_ir_priv *priv, u32 irq_status)
19 {
20 struct img_ir_priv_raw *raw = &priv->raw;
21 struct rc_dev *rc_dev = priv->raw.rdev;
22 int multiple;
23 u32 ir_status;
24
25
26 multiple = ((irq_status & IMG_IR_IRQ_EDGE) == IMG_IR_IRQ_EDGE);
27
28
29
30
31
32 ir_status = img_ir_read(priv, IMG_IR_STATUS) & IMG_IR_IRRXD;
33 if (multiple && ir_status == raw->last_status)
34 return;
35 raw->last_status = ir_status;
36
37
38 if (ir_status)
39 ir_raw_event_store_edge(rc_dev, false);
40 else
41 ir_raw_event_store_edge(rc_dev, true);
42 ir_raw_event_handle(rc_dev);
43 }
44
45
46 void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status)
47 {
48 struct img_ir_priv_raw *raw = &priv->raw;
49
50
51 if (!raw->rdev)
52 return;
53
54 img_ir_refresh_raw(priv, irq_status);
55
56
57 mod_timer(&raw->timer, jiffies + msecs_to_jiffies(ECHO_TIMEOUT_MS));
58 }
59
60
61
62
63
64
65
66 static void img_ir_echo_timer(struct timer_list *t)
67 {
68 struct img_ir_priv *priv = from_timer(priv, t, raw.timer);
69
70 spin_lock_irq(&priv->lock);
71
72
73 if (priv->raw.rdev)
74
75
76
77
78 img_ir_refresh_raw(priv, 0);
79
80 spin_unlock_irq(&priv->lock);
81 }
82
83 void img_ir_setup_raw(struct img_ir_priv *priv)
84 {
85 u32 irq_en;
86
87 if (!priv->raw.rdev)
88 return;
89
90
91 spin_lock_irq(&priv->lock);
92 irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
93 irq_en |= IMG_IR_IRQ_EDGE;
94 img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
95 img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
96 spin_unlock_irq(&priv->lock);
97 }
98
99 int img_ir_probe_raw(struct img_ir_priv *priv)
100 {
101 struct img_ir_priv_raw *raw = &priv->raw;
102 struct rc_dev *rdev;
103 int error;
104
105
106 timer_setup(&raw->timer, img_ir_echo_timer, 0);
107
108
109 raw->rdev = rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
110 if (!rdev) {
111 dev_err(priv->dev, "cannot allocate raw input device\n");
112 return -ENOMEM;
113 }
114 rdev->priv = priv;
115 rdev->map_name = RC_MAP_EMPTY;
116 rdev->device_name = "IMG Infrared Decoder Raw";
117
118
119 error = rc_register_device(rdev);
120 if (error) {
121 dev_err(priv->dev, "failed to register raw IR input device\n");
122 rc_free_device(rdev);
123 raw->rdev = NULL;
124 return error;
125 }
126
127 return 0;
128 }
129
130 void img_ir_remove_raw(struct img_ir_priv *priv)
131 {
132 struct img_ir_priv_raw *raw = &priv->raw;
133 struct rc_dev *rdev = raw->rdev;
134 u32 irq_en;
135
136 if (!rdev)
137 return;
138
139
140 spin_lock_irq(&priv->lock);
141 raw->rdev = NULL;
142 irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
143 irq_en &= ~IMG_IR_IRQ_EDGE;
144 img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
145 img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
146 spin_unlock_irq(&priv->lock);
147
148 rc_unregister_device(rdev);
149
150 del_timer_sync(&raw->timer);
151 }