diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-03-31 15:07:49 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:53:04 -0400 |
commit | 92f4fc10d7ba01fd84abbfae963d379c73ba5a0f (patch) | |
tree | 7f6023f8b86d284dd437948c02b28bb93476844b /drivers/media/video/cx88/cx88-input.c | |
parent | 716aab44df8bb9bdf16abea9013890274329b61f (diff) |
V4L/DVB: cx88: Only start IR if the input device is opened
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx88/cx88-input.c')
-rw-r--r-- | drivers/media/video/cx88/cx88-input.c | 69 |
1 files changed, 60 insertions, 9 deletions
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 8b52546c6e1d..8bd95be89e67 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -40,6 +40,10 @@ struct cx88_IR { | |||
40 | struct cx88_core *core; | 40 | struct cx88_core *core; |
41 | struct input_dev *input; | 41 | struct input_dev *input; |
42 | struct ir_input_state ir; | 42 | struct ir_input_state ir; |
43 | struct ir_dev_props props; | ||
44 | |||
45 | int users; | ||
46 | |||
43 | char name[32]; | 47 | char name[32]; |
44 | char phys[32]; | 48 | char phys[32]; |
45 | 49 | ||
@@ -161,8 +165,16 @@ static enum hrtimer_restart cx88_ir_work(struct hrtimer *timer) | |||
161 | return HRTIMER_RESTART; | 165 | return HRTIMER_RESTART; |
162 | } | 166 | } |
163 | 167 | ||
164 | void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) | 168 | static int __cx88_ir_start(void *priv) |
165 | { | 169 | { |
170 | struct cx88_core *core = priv; | ||
171 | struct cx88_IR *ir; | ||
172 | |||
173 | if (!core || !core->ir) | ||
174 | return -EINVAL; | ||
175 | |||
176 | ir = core->ir; | ||
177 | |||
166 | if (ir->polling) { | 178 | if (ir->polling) { |
167 | hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 179 | hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
168 | ir->timer.function = cx88_ir_work; | 180 | ir->timer.function = cx88_ir_work; |
@@ -175,10 +187,18 @@ void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) | |||
175 | cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ | 187 | cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ |
176 | cx_write(MO_DDSCFG_IO, 0x5); /* enable */ | 188 | cx_write(MO_DDSCFG_IO, 0x5); /* enable */ |
177 | } | 189 | } |
190 | return 0; | ||
178 | } | 191 | } |
179 | 192 | ||
180 | void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir) | 193 | static void __cx88_ir_stop(void *priv) |
181 | { | 194 | { |
195 | struct cx88_core *core = priv; | ||
196 | struct cx88_IR *ir; | ||
197 | |||
198 | if (!core || !core->ir) | ||
199 | return; | ||
200 | |||
201 | ir = core->ir; | ||
182 | if (ir->sampling) { | 202 | if (ir->sampling) { |
183 | cx_write(MO_DDSCFG_IO, 0x0); | 203 | cx_write(MO_DDSCFG_IO, 0x0); |
184 | core->pci_irqmask &= ~PCI_INT_IR_SMPINT; | 204 | core->pci_irqmask &= ~PCI_INT_IR_SMPINT; |
@@ -188,6 +208,37 @@ void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir) | |||
188 | hrtimer_cancel(&ir->timer); | 208 | hrtimer_cancel(&ir->timer); |
189 | } | 209 | } |
190 | 210 | ||
211 | int cx88_ir_start(struct cx88_core *core) | ||
212 | { | ||
213 | if (core->ir->users) | ||
214 | return __cx88_ir_start(core); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | void cx88_ir_stop(struct cx88_core *core) | ||
220 | { | ||
221 | if (core->ir->users) | ||
222 | __cx88_ir_stop(core); | ||
223 | } | ||
224 | |||
225 | static int cx88_ir_open(void *priv) | ||
226 | { | ||
227 | struct cx88_core *core = priv; | ||
228 | |||
229 | core->ir->users++; | ||
230 | return __cx88_ir_start(core); | ||
231 | } | ||
232 | |||
233 | static void cx88_ir_close(void *priv) | ||
234 | { | ||
235 | struct cx88_core *core = priv; | ||
236 | |||
237 | core->ir->users--; | ||
238 | if (!core->ir->users) | ||
239 | __cx88_ir_stop(core); | ||
240 | } | ||
241 | |||
191 | /* ---------------------------------------------------------------------- */ | 242 | /* ---------------------------------------------------------------------- */ |
192 | 243 | ||
193 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | 244 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) |
@@ -383,19 +434,19 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
383 | ir->core = core; | 434 | ir->core = core; |
384 | core->ir = ir; | 435 | core->ir = ir; |
385 | 436 | ||
386 | cx88_ir_start(core, ir); | 437 | ir->props.priv = core; |
438 | ir->props.open = cx88_ir_open; | ||
439 | ir->props.close = cx88_ir_close; | ||
387 | 440 | ||
388 | /* all done */ | 441 | /* all done */ |
389 | err = ir_input_register(ir->input, ir_codes, NULL, MODULE_NAME); | 442 | err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME); |
390 | if (err) | 443 | if (err) |
391 | goto err_out_stop; | 444 | goto err_out_free; |
392 | 445 | ||
393 | return 0; | 446 | return 0; |
394 | 447 | ||
395 | err_out_stop: | ||
396 | cx88_ir_stop(core, ir); | ||
397 | core->ir = NULL; | ||
398 | err_out_free: | 448 | err_out_free: |
449 | core->ir = NULL; | ||
399 | kfree(ir); | 450 | kfree(ir); |
400 | return err; | 451 | return err; |
401 | } | 452 | } |
@@ -408,7 +459,7 @@ int cx88_ir_fini(struct cx88_core *core) | |||
408 | if (NULL == ir) | 459 | if (NULL == ir) |
409 | return 0; | 460 | return 0; |
410 | 461 | ||
411 | cx88_ir_stop(core, ir); | 462 | cx88_ir_stop(core); |
412 | ir_input_unregister(ir->input); | 463 | ir_input_unregister(ir->input); |
413 | kfree(ir); | 464 | kfree(ir); |
414 | 465 | ||