diff options
author | Maxim Levitsky <maximlevitsky@gmail.com> | 2010-10-16 18:56:28 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-21 08:59:47 -0400 |
commit | 4651918a4afdd49bdea21d2f919b189ef17a6399 (patch) | |
tree | 73a4e3b5f7da1d655a059bb9b69135cf6f395e02 /drivers/media/IR/ir-lirc-codec.c | |
parent | fb249ca61d469a9cb666ba7e1d992787dc6bad82 (diff) |
[media] IR: extend ir_raw_event and do refactoring
Add new event types for timeout & carrier report
Move timeout handling from ir_raw_event_store_with_filter to
ir-lirc-codec, where it is really needed.
Now lirc bridge ensures proper gap handling.
Extend lirc bridge for carrier & timeout reports
Note: all new ir_raw_event variables now should be initialized
like that: DEFINE_IR_RAW_EVENT(ev);
To clean an existing event, use init_ir_raw_event(&ev);
Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Acked-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/IR/ir-lirc-codec.c')
-rw-r--r-- | drivers/media/IR/ir-lirc-codec.c | 128 |
1 files changed, 90 insertions, 38 deletions
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c index 20ac9a4ce522..1d9c6b0fd0ea 100644 --- a/drivers/media/IR/ir-lirc-codec.c +++ b/drivers/media/IR/ir-lirc-codec.c | |||
@@ -32,6 +32,7 @@ | |||
32 | static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) | 32 | static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) |
33 | { | 33 | { |
34 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 34 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
35 | struct lirc_codec *lirc = &ir_dev->raw->lirc; | ||
35 | int sample; | 36 | int sample; |
36 | 37 | ||
37 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) | 38 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) |
@@ -40,21 +41,57 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
40 | if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf) | 41 | if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf) |
41 | return -EINVAL; | 42 | return -EINVAL; |
42 | 43 | ||
43 | if (IS_RESET(ev)) | 44 | /* Packet start */ |
45 | if (ev.reset) | ||
44 | return 0; | 46 | return 0; |
45 | 47 | ||
46 | IR_dprintk(2, "LIRC data transfer started (%uus %s)\n", | 48 | /* Carrier reports */ |
47 | TO_US(ev.duration), TO_STR(ev.pulse)); | 49 | if (ev.carrier_report) { |
50 | sample = LIRC_FREQUENCY(ev.carrier); | ||
51 | |||
52 | /* Packet end */ | ||
53 | } else if (ev.timeout) { | ||
54 | |||
55 | if (lirc->gap) | ||
56 | return 0; | ||
57 | |||
58 | lirc->gap_start = ktime_get(); | ||
59 | lirc->gap = true; | ||
60 | lirc->gap_duration = ev.duration; | ||
61 | |||
62 | if (!lirc->send_timeout_reports) | ||
63 | return 0; | ||
64 | |||
65 | sample = LIRC_TIMEOUT(ev.duration / 1000); | ||
48 | 66 | ||
49 | sample = ev.duration / 1000; | 67 | /* Normal sample */ |
50 | if (ev.pulse) | 68 | } else { |
51 | sample |= PULSE_BIT; | 69 | |
70 | if (lirc->gap) { | ||
71 | int gap_sample; | ||
72 | |||
73 | lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(), | ||
74 | lirc->gap_start)); | ||
75 | |||
76 | /* Convert to ms and cap by LIRC_VALUE_MASK */ | ||
77 | do_div(lirc->gap_duration, 1000); | ||
78 | lirc->gap_duration = min(lirc->gap_duration, | ||
79 | (u64)LIRC_VALUE_MASK); | ||
80 | |||
81 | gap_sample = LIRC_SPACE(lirc->gap_duration); | ||
82 | lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, | ||
83 | (unsigned char *) &gap_sample); | ||
84 | lirc->gap = false; | ||
85 | } | ||
86 | |||
87 | sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : | ||
88 | LIRC_SPACE(ev.duration / 1000); | ||
89 | } | ||
52 | 90 | ||
53 | lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, | 91 | lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, |
54 | (unsigned char *) &sample); | 92 | (unsigned char *) &sample); |
55 | wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); | 93 | wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); |
56 | 94 | ||
57 | |||
58 | return 0; | 95 | return 0; |
59 | } | 96 | } |
60 | 97 | ||
@@ -102,7 +139,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
102 | struct ir_input_dev *ir_dev; | 139 | struct ir_input_dev *ir_dev; |
103 | int ret = 0; | 140 | int ret = 0; |
104 | void *drv_data; | 141 | void *drv_data; |
105 | __u32 val = 0; | 142 | __u32 val = 0, tmp; |
106 | 143 | ||
107 | lirc = lirc_get_pdata(filep); | 144 | lirc = lirc_get_pdata(filep); |
108 | if (!lirc) | 145 | if (!lirc) |
@@ -130,22 +167,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
130 | case LIRC_SET_SEND_MODE: | 167 | case LIRC_SET_SEND_MODE: |
131 | if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) | 168 | if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) |
132 | return -EINVAL; | 169 | return -EINVAL; |
133 | break; | 170 | return 0; |
134 | 171 | ||
135 | /* TX settings */ | 172 | /* TX settings */ |
136 | case LIRC_SET_TRANSMITTER_MASK: | 173 | case LIRC_SET_TRANSMITTER_MASK: |
137 | if (ir_dev->props->s_tx_mask) | 174 | if (!ir_dev->props->s_tx_mask) |
138 | ret = ir_dev->props->s_tx_mask(drv_data, val); | ||
139 | else | ||
140 | return -EINVAL; | 175 | return -EINVAL; |
141 | break; | 176 | |
177 | return ir_dev->props->s_tx_mask(drv_data, val); | ||
142 | 178 | ||
143 | case LIRC_SET_SEND_CARRIER: | 179 | case LIRC_SET_SEND_CARRIER: |
144 | if (ir_dev->props->s_tx_carrier) | 180 | if (!ir_dev->props->s_tx_carrier) |
145 | ir_dev->props->s_tx_carrier(drv_data, val); | ||
146 | else | ||
147 | return -EINVAL; | 181 | return -EINVAL; |
148 | break; | 182 | |
183 | return ir_dev->props->s_tx_carrier(drv_data, val); | ||
149 | 184 | ||
150 | case LIRC_SET_SEND_DUTY_CYCLE: | 185 | case LIRC_SET_SEND_DUTY_CYCLE: |
151 | if (!ir_dev->props->s_tx_duty_cycle) | 186 | if (!ir_dev->props->s_tx_duty_cycle) |
@@ -154,39 +189,42 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
154 | if (val <= 0 || val >= 100) | 189 | if (val <= 0 || val >= 100) |
155 | return -EINVAL; | 190 | return -EINVAL; |
156 | 191 | ||
157 | ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val); | 192 | return ir_dev->props->s_tx_duty_cycle(drv_data, val); |
158 | break; | ||
159 | 193 | ||
160 | /* RX settings */ | 194 | /* RX settings */ |
161 | case LIRC_SET_REC_CARRIER: | 195 | case LIRC_SET_REC_CARRIER: |
162 | if (ir_dev->props->s_rx_carrier_range) | 196 | if (!ir_dev->props->s_rx_carrier_range) |
163 | ret = ir_dev->props->s_rx_carrier_range( | ||
164 | ir_dev->props->priv, | ||
165 | ir_dev->raw->lirc.carrier_low, val); | ||
166 | else | ||
167 | return -ENOSYS; | 197 | return -ENOSYS; |
168 | 198 | ||
169 | if (!ret) | 199 | if (val <= 0) |
170 | ir_dev->raw->lirc.carrier_low = 0; | 200 | return -EINVAL; |
171 | break; | 201 | |
202 | return ir_dev->props->s_rx_carrier_range(drv_data, | ||
203 | ir_dev->raw->lirc.carrier_low, val); | ||
172 | 204 | ||
173 | case LIRC_SET_REC_CARRIER_RANGE: | 205 | case LIRC_SET_REC_CARRIER_RANGE: |
174 | if (val >= 0) | 206 | if (val <= 0) |
175 | ir_dev->raw->lirc.carrier_low = val; | 207 | return -EINVAL; |
176 | break; | ||
177 | 208 | ||
209 | ir_dev->raw->lirc.carrier_low = val; | ||
210 | return 0; | ||
178 | 211 | ||
179 | case LIRC_GET_REC_RESOLUTION: | 212 | case LIRC_GET_REC_RESOLUTION: |
180 | val = ir_dev->props->rx_resolution; | 213 | val = ir_dev->props->rx_resolution; |
181 | break; | 214 | break; |
182 | 215 | ||
183 | case LIRC_SET_WIDEBAND_RECEIVER: | 216 | case LIRC_SET_WIDEBAND_RECEIVER: |
184 | if (ir_dev->props->s_learning_mode) | 217 | if (!ir_dev->props->s_learning_mode) |
185 | return ir_dev->props->s_learning_mode( | ||
186 | ir_dev->props->priv, !!val); | ||
187 | else | ||
188 | return -ENOSYS; | 218 | return -ENOSYS; |
189 | 219 | ||
220 | return ir_dev->props->s_learning_mode(drv_data, !!val); | ||
221 | |||
222 | case LIRC_SET_MEASURE_CARRIER_MODE: | ||
223 | if (!ir_dev->props->s_carrier_report) | ||
224 | return -ENOSYS; | ||
225 | |||
226 | return ir_dev->props->s_carrier_report(drv_data, !!val); | ||
227 | |||
190 | /* Generic timeout support */ | 228 | /* Generic timeout support */ |
191 | case LIRC_GET_MIN_TIMEOUT: | 229 | case LIRC_GET_MIN_TIMEOUT: |
192 | if (!ir_dev->props->max_timeout) | 230 | if (!ir_dev->props->max_timeout) |
@@ -201,10 +239,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
201 | break; | 239 | break; |
202 | 240 | ||
203 | case LIRC_SET_REC_TIMEOUT: | 241 | case LIRC_SET_REC_TIMEOUT: |
204 | if (val < ir_dev->props->min_timeout || | 242 | if (!ir_dev->props->max_timeout) |
205 | val > ir_dev->props->max_timeout) | 243 | return -ENOSYS; |
206 | return -EINVAL; | 244 | |
207 | ir_dev->props->timeout = val * 1000; | 245 | tmp = val * 1000; |
246 | |||
247 | if (tmp < ir_dev->props->min_timeout || | ||
248 | tmp > ir_dev->props->max_timeout) | ||
249 | return -EINVAL; | ||
250 | |||
251 | ir_dev->props->timeout = tmp; | ||
252 | break; | ||
253 | |||
254 | case LIRC_SET_REC_TIMEOUT_REPORTS: | ||
255 | lirc->send_timeout_reports = !!val; | ||
208 | break; | 256 | break; |
209 | 257 | ||
210 | default: | 258 | default: |
@@ -280,6 +328,10 @@ static int ir_lirc_register(struct input_dev *input_dev) | |||
280 | if (ir_dev->props->s_learning_mode) | 328 | if (ir_dev->props->s_learning_mode) |
281 | features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; | 329 | features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; |
282 | 330 | ||
331 | if (ir_dev->props->s_carrier_report) | ||
332 | features |= LIRC_CAN_MEASURE_CARRIER; | ||
333 | |||
334 | |||
283 | if (ir_dev->props->max_timeout) | 335 | if (ir_dev->props->max_timeout) |
284 | features |= LIRC_CAN_SET_REC_TIMEOUT; | 336 | features |= LIRC_CAN_SET_REC_TIMEOUT; |
285 | 337 | ||