aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-input.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-03-31 15:07:49 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:53:04 -0400
commit92f4fc10d7ba01fd84abbfae963d379c73ba5a0f (patch)
tree7f6023f8b86d284dd437948c02b28bb93476844b /drivers/media/video/cx88/cx88-input.c
parent716aab44df8bb9bdf16abea9013890274329b61f (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.c69
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
164void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) 168static 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
180void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir) 193static 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
211int 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
219void cx88_ir_stop(struct cx88_core *core)
220{
221 if (core->ir->users)
222 __cx88_ir_stop(core);
223}
224
225static 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
233static 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
193int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) 244int 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