diff options
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-input.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-input.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 20a0001e8885..5c3fd9411b1f 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -39,6 +39,8 @@ static unsigned int ir_debug; | |||
39 | module_param(ir_debug, int, 0644); | 39 | module_param(ir_debug, int, 0644); |
40 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | 40 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); |
41 | 41 | ||
42 | #define MODULE_NAME "em28xx" | ||
43 | |||
42 | #define i2cdprintk(fmt, arg...) \ | 44 | #define i2cdprintk(fmt, arg...) \ |
43 | if (ir_debug) { \ | 45 | if (ir_debug) { \ |
44 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ | 46 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ |
@@ -360,14 +362,20 @@ static void em28xx_ir_work(struct work_struct *work) | |||
360 | schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); | 362 | schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); |
361 | } | 363 | } |
362 | 364 | ||
363 | static void em28xx_ir_start(struct em28xx_IR *ir) | 365 | static int em28xx_ir_start(void *priv) |
364 | { | 366 | { |
367 | struct em28xx_IR *ir = priv; | ||
368 | |||
365 | INIT_DELAYED_WORK(&ir->work, em28xx_ir_work); | 369 | INIT_DELAYED_WORK(&ir->work, em28xx_ir_work); |
366 | schedule_delayed_work(&ir->work, 0); | 370 | schedule_delayed_work(&ir->work, 0); |
371 | |||
372 | return 0; | ||
367 | } | 373 | } |
368 | 374 | ||
369 | static void em28xx_ir_stop(struct em28xx_IR *ir) | 375 | static void em28xx_ir_stop(void *priv) |
370 | { | 376 | { |
377 | struct em28xx_IR *ir = priv; | ||
378 | |||
371 | cancel_delayed_work_sync(&ir->work); | 379 | cancel_delayed_work_sync(&ir->work); |
372 | } | 380 | } |
373 | 381 | ||
@@ -380,7 +388,6 @@ int em28xx_ir_change_protocol(void *priv, u64 ir_type) | |||
380 | 388 | ||
381 | /* Adjust xclk based o IR table for RC5/NEC tables */ | 389 | /* Adjust xclk based o IR table for RC5/NEC tables */ |
382 | 390 | ||
383 | dev->board.ir_codes->ir_type = IR_TYPE_OTHER; | ||
384 | if (ir_type == IR_TYPE_RC5) { | 391 | if (ir_type == IR_TYPE_RC5) { |
385 | dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; | 392 | dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; |
386 | ir->full_code = 1; | 393 | ir->full_code = 1; |
@@ -388,11 +395,9 @@ int em28xx_ir_change_protocol(void *priv, u64 ir_type) | |||
388 | dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; | 395 | dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; |
389 | ir_config = EM2874_IR_NEC; | 396 | ir_config = EM2874_IR_NEC; |
390 | ir->full_code = 1; | 397 | ir->full_code = 1; |
391 | } else | 398 | } else if (ir_type != IR_TYPE_UNKNOWN) |
392 | rc = -EINVAL; | 399 | rc = -EINVAL; |
393 | 400 | ||
394 | dev->board.ir_codes->ir_type = ir_type; | ||
395 | |||
396 | em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, | 401 | em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, |
397 | EM28XX_XCLK_IR_RC5_MODE); | 402 | EM28XX_XCLK_IR_RC5_MODE); |
398 | 403 | ||
@@ -443,6 +448,13 @@ int em28xx_ir_init(struct em28xx *dev) | |||
443 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; | 448 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; |
444 | ir->props.priv = ir; | 449 | ir->props.priv = ir; |
445 | ir->props.change_protocol = em28xx_ir_change_protocol; | 450 | ir->props.change_protocol = em28xx_ir_change_protocol; |
451 | ir->props.open = em28xx_ir_start; | ||
452 | ir->props.close = em28xx_ir_stop; | ||
453 | |||
454 | /* By default, keep protocol field untouched */ | ||
455 | err = em28xx_ir_change_protocol(ir, IR_TYPE_UNKNOWN); | ||
456 | if (err) | ||
457 | goto err_out_free; | ||
446 | 458 | ||
447 | /* This is how often we ask the chip for IR information */ | 459 | /* This is how often we ask the chip for IR information */ |
448 | ir->polling = 100; /* ms */ | 460 | ir->polling = 100; /* ms */ |
@@ -455,7 +467,6 @@ int em28xx_ir_init(struct em28xx *dev) | |||
455 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); | 467 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); |
456 | 468 | ||
457 | /* Set IR protocol */ | 469 | /* Set IR protocol */ |
458 | em28xx_ir_change_protocol(ir, dev->board.ir_codes->ir_type); | ||
459 | err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); | 470 | err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); |
460 | if (err < 0) | 471 | if (err < 0) |
461 | goto err_out_free; | 472 | goto err_out_free; |
@@ -470,17 +481,15 @@ int em28xx_ir_init(struct em28xx *dev) | |||
470 | input_dev->dev.parent = &dev->udev->dev; | 481 | input_dev->dev.parent = &dev->udev->dev; |
471 | 482 | ||
472 | 483 | ||
473 | em28xx_ir_start(ir); | ||
474 | 484 | ||
475 | /* all done */ | 485 | /* all done */ |
476 | err = ir_input_register(ir->input, dev->board.ir_codes, | 486 | err = ir_input_register(ir->input, dev->board.ir_codes, |
477 | &ir->props); | 487 | &ir->props, MODULE_NAME); |
478 | if (err) | 488 | if (err) |
479 | goto err_out_stop; | 489 | goto err_out_stop; |
480 | 490 | ||
481 | return 0; | 491 | return 0; |
482 | err_out_stop: | 492 | err_out_stop: |
483 | em28xx_ir_stop(ir); | ||
484 | dev->ir = NULL; | 493 | dev->ir = NULL; |
485 | err_out_free: | 494 | err_out_free: |
486 | kfree(ir); | 495 | kfree(ir); |