aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx/em28xx-input.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-12-14 00:54:22 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:10:23 -0500
commit950b0f5a0bf764663a6aa4397d105ad571c64a83 (patch)
tree74dcfdfc52a7594c300dc63ffbf42744a8ef715c /drivers/media/video/em28xx/em28xx-input.c
parent09b01b90eb08769a64159ff4f81efe4badf6a49b (diff)
V4L/DVB (13637): em28xx: allow changing keycode table protocol
Experimental patch to allow changing the IR protocol. Currently, it support changing between RC-5 and NEC protocols. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-input.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c80
1 files changed, 54 insertions, 26 deletions
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index fbfbab6841cd..ebb75a867f03 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -75,6 +75,10 @@ struct em28xx_IR {
75 unsigned int repeat_interval; 75 unsigned int repeat_interval;
76 76
77 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); 77 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
78
79 /* IR device properties */
80
81 struct ir_dev_props props;
78}; 82};
79 83
80/********************************************************** 84/**********************************************************
@@ -336,35 +340,25 @@ static void em28xx_ir_stop(struct em28xx_IR *ir)
336 cancel_delayed_work_sync(&ir->work); 340 cancel_delayed_work_sync(&ir->work);
337} 341}
338 342
339int em28xx_ir_init(struct em28xx *dev) 343int em28xx_ir_change_protocol(void *priv, enum ir_type ir_type)
340{ 344{
341 struct em28xx_IR *ir; 345 int rc = 0;
342 struct input_dev *input_dev; 346 struct em28xx_IR *ir = priv;
343 u8 ir_config; 347 struct em28xx *dev = ir->dev;
344 int err = -ENOMEM; 348 u8 ir_config = EM2874_IR_RC5;
345
346 if (dev->board.ir_codes == NULL) {
347 /* No remote control support */
348 return 0;
349 }
350
351 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
352 input_dev = input_allocate_device();
353 if (!ir || !input_dev)
354 goto err_out_free;
355
356 ir->input = input_dev;
357 ir_config = EM2874_IR_RC5;
358 349
359 /* Adjust xclk based o IR table for RC5/NEC tables */ 350 /* Adjust xclk based o IR table for RC5/NEC tables */
360 if (dev->board.ir_codes->ir_type == IR_TYPE_RC5) { 351
352 if (ir_type == IR_TYPE_RC5) {
361 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; 353 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
362 ir->full_code = 1; 354 ir->full_code = 1;
363 } else if (dev->board.ir_codes->ir_type == IR_TYPE_NEC) { 355 } else if (ir_type == IR_TYPE_NEC) {
364 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; 356 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
365 ir_config = EM2874_IR_NEC; 357 ir_config = EM2874_IR_NEC;
366 ir->full_code = 1; 358 ir->full_code = 1;
367 } 359 } else
360 rc = -EINVAL;
361
368 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, 362 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
369 EM28XX_XCLK_IR_RC5_MODE); 363 EM28XX_XCLK_IR_RC5_MODE);
370 364
@@ -380,9 +374,42 @@ int em28xx_ir_init(struct em28xx *dev)
380 break; 374 break;
381 default: 375 default:
382 printk("Unrecognized em28xx chip id: IR not supported\n"); 376 printk("Unrecognized em28xx chip id: IR not supported\n");
383 goto err_out_free; 377 rc = -EINVAL;
378 }
379
380 return rc;
381}
382
383int em28xx_ir_init(struct em28xx *dev)
384{
385 struct em28xx_IR *ir;
386 struct input_dev *input_dev;
387 int err = -ENOMEM;
388
389 if (dev->board.ir_codes == NULL) {
390 /* No remote control support */
391 return 0;
384 } 392 }
385 393
394 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
395 input_dev = input_allocate_device();
396 if (!ir || !input_dev)
397 goto err_out_free;
398
399 /* record handles to ourself */
400 ir->dev = dev;
401 dev->ir = ir;
402
403 ir->input = input_dev;
404
405 /*
406 * em2874 supports more protocols. For now, let's just announce
407 * the two protocols that were already tested
408 */
409 ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
410 ir->props.priv = ir;
411 ir->props.change_protocol = em28xx_ir_change_protocol;
412
386 /* This is how often we ask the chip for IR information */ 413 /* This is how often we ask the chip for IR information */
387 ir->polling = 100; /* ms */ 414 ir->polling = 100; /* ms */
388 415
@@ -393,6 +420,8 @@ int em28xx_ir_init(struct em28xx *dev)
393 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); 420 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
394 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 421 strlcat(ir->phys, "/input0", sizeof(ir->phys));
395 422
423 /* Set IR protocol */
424 em28xx_ir_change_protocol(ir, dev->board.ir_codes->ir_type);
396 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); 425 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
397 if (err < 0) 426 if (err < 0)
398 goto err_out_free; 427 goto err_out_free;
@@ -405,14 +434,13 @@ int em28xx_ir_init(struct em28xx *dev)
405 input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); 434 input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
406 435
407 input_dev->dev.parent = &dev->udev->dev; 436 input_dev->dev.parent = &dev->udev->dev;
408 /* record handles to ourself */ 437
409 ir->dev = dev;
410 dev->ir = ir;
411 438
412 em28xx_ir_start(ir); 439 em28xx_ir_start(ir);
413 440
414 /* all done */ 441 /* all done */
415 err = ir_input_register(ir->input, dev->board.ir_codes, NULL); 442 err = ir_input_register(ir->input, dev->board.ir_codes,
443 &ir->props);
416 if (err) 444 if (err)
417 goto err_out_stop; 445 goto err_out_stop;
418 446