aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorFrank Schaefer <fschaefer.oss@googlemail.com>2013-01-13 08:20:41 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-02-05 17:38:50 -0500
commit768da3dbcf50b697e5e7a921492b7f0d2cd8a8fb (patch)
tree35dcf06751ac0ecbfec6936d8c256e113197ec40 /drivers/media
parent62ec3f86ff86483ae27b9411179b8ded74558c19 (diff)
[media] em28xx: get rid of the dependency on module ir-kbd-i2c
We already have the key polling functions and the polling infrastructure in em28xx-input, so we can easily get rid of the dependency on module ir-kbd-i2c. For maximum safety, do not touch the key reporting mechanism for those devices. Code size could be improved further but would have minor peformance impacts. Tested with device "Terratec Cinergy 200 USB" (EM2800_BOARD_TERRATEC_CINERGY_200) [mchehab@redhat.com: Fix two checkpatch.pl warnings: ERROR: "foo * bar" should be "foo *bar" (line 465) WARNING: kfree(NULL) is safe this check is probably not required (line 725)] Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/usb/em28xx/em28xx-input.c219
-rw-r--r--drivers/media/usb/em28xx/em28xx.h3
2 files changed, 134 insertions, 88 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index edcd6978f2e1..72cb0cfad8d0 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -62,13 +62,17 @@ struct em28xx_IR {
62 char name[32]; 62 char name[32];
63 char phys[32]; 63 char phys[32];
64 64
65 /* poll external decoder */ 65 /* poll decoder */
66 int polling; 66 int polling;
67 struct delayed_work work; 67 struct delayed_work work;
68 unsigned int full_code:1; 68 unsigned int full_code:1;
69 unsigned int last_readcount; 69 unsigned int last_readcount;
70 u64 rc_type; 70 u64 rc_type;
71 71
72 /* external device (if used) */
73 struct i2c_client *i2c_dev;
74
75 int (*get_key_i2c)(struct i2c_client *, u32 *, u32 *);
72 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); 76 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
73}; 77};
74 78
@@ -76,12 +80,13 @@ struct em28xx_IR {
76 I2C IR based get keycodes - should be used with ir-kbd-i2c 80 I2C IR based get keycodes - should be used with ir-kbd-i2c
77 **********************************************************/ 81 **********************************************************/
78 82
79static int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 83static int em28xx_get_key_terratec(struct i2c_client *i2c_dev,
84 u32 *ir_key, u32 *ir_raw)
80{ 85{
81 unsigned char b; 86 unsigned char b;
82 87
83 /* poll IR chip */ 88 /* poll IR chip */
84 if (1 != i2c_master_recv(ir->c, &b, 1)) 89 if (1 != i2c_master_recv(i2c_dev, &b, 1))
85 return -EIO; 90 return -EIO;
86 91
87 /* it seems that 0xFE indicates that a button is still hold 92 /* it seems that 0xFE indicates that a button is still hold
@@ -100,14 +105,15 @@ static int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
100 return 1; 105 return 1;
101} 106}
102 107
103static int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 108static int em28xx_get_key_em_haup(struct i2c_client *i2c_dev,
109 u32 *ir_key, u32 *ir_raw)
104{ 110{
105 unsigned char buf[2]; 111 unsigned char buf[2];
106 u16 code; 112 u16 code;
107 int size; 113 int size;
108 114
109 /* poll IR chip */ 115 /* poll IR chip */
110 size = i2c_master_recv(ir->c, buf, sizeof(buf)); 116 size = i2c_master_recv(i2c_dev, buf, sizeof(buf));
111 117
112 if (size != 2) 118 if (size != 2)
113 return -EIO; 119 return -EIO;
@@ -144,14 +150,14 @@ static int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
144 return 1; 150 return 1;
145} 151}
146 152
147static int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, 153static int em28xx_get_key_pinnacle_usb_grey(struct i2c_client *i2c_dev,
148 u32 *ir_raw) 154 u32 *ir_key, u32 *ir_raw)
149{ 155{
150 unsigned char buf[3]; 156 unsigned char buf[3];
151 157
152 /* poll IR chip */ 158 /* poll IR chip */
153 159
154 if (3 != i2c_master_recv(ir->c, buf, 3)) 160 if (3 != i2c_master_recv(i2c_dev, buf, 3))
155 return -EIO; 161 return -EIO;
156 162
157 if (buf[0] != 0x00) 163 if (buf[0] != 0x00)
@@ -163,24 +169,24 @@ static int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
163 return 1; 169 return 1;
164} 170}
165 171
166static int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key, 172static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev,
167 u32 *ir_raw) 173 u32 *ir_key, u32 *ir_raw)
168{ 174{
169 unsigned char subaddr, keydetect, key; 175 unsigned char subaddr, keydetect, key;
170 176
171 struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, .buf = &subaddr, .len = 1}, 177 struct i2c_msg msg[] = { { .addr = i2c_dev->addr, .flags = 0, .buf = &subaddr, .len = 1},
172 178
173 { .addr = ir->c->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} }; 179 { .addr = i2c_dev->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} };
174 180
175 subaddr = 0x10; 181 subaddr = 0x10;
176 if (2 != i2c_transfer(ir->c->adapter, msg, 2)) 182 if (2 != i2c_transfer(i2c_dev->adapter, msg, 2))
177 return -EIO; 183 return -EIO;
178 if (keydetect == 0x00) 184 if (keydetect == 0x00)
179 return 0; 185 return 0;
180 186
181 subaddr = 0x00; 187 subaddr = 0x00;
182 msg[1].buf = &key; 188 msg[1].buf = &key;
183 if (2 != i2c_transfer(ir->c->adapter, msg, 2)) 189 if (2 != i2c_transfer(i2c_dev->adapter, msg, 2))
184 return -EIO; 190 return -EIO;
185 if (key == 0x00) 191 if (key == 0x00)
186 return 0; 192 return 0;
@@ -280,6 +286,24 @@ static int em2874_polling_getkey(struct em28xx_IR *ir,
280 Polling code for em28xx 286 Polling code for em28xx
281 **********************************************************/ 287 **********************************************************/
282 288
289static int em28xx_i2c_ir_handle_key(struct em28xx_IR *ir)
290{
291 static u32 ir_key, ir_raw;
292 int rc;
293
294 rc = ir->get_key_i2c(ir->i2c_dev, &ir_key, &ir_raw);
295 if (rc < 0) {
296 dprintk("ir->get_key_i2c() failed: %d\n", rc);
297 return rc;
298 }
299
300 if (rc) {
301 dprintk("%s: keycode = 0x%04x\n", __func__, ir_key);
302 rc_keydown(ir->rc, ir_key, 0);
303 }
304 return 0;
305}
306
283static void em28xx_ir_handle_key(struct em28xx_IR *ir) 307static void em28xx_ir_handle_key(struct em28xx_IR *ir)
284{ 308{
285 int result; 309 int result;
@@ -288,7 +312,7 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
288 /* read the registers containing the IR status */ 312 /* read the registers containing the IR status */
289 result = ir->get_key(ir, &poll_result); 313 result = ir->get_key(ir, &poll_result);
290 if (unlikely(result < 0)) { 314 if (unlikely(result < 0)) {
291 dprintk("ir->get_key() failed %d\n", result); 315 dprintk("ir->get_key() failed: %d\n", result);
292 return; 316 return;
293 } 317 }
294 318
@@ -318,6 +342,14 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
318 } 342 }
319} 343}
320 344
345static void em28xx_i2c_ir_work(struct work_struct *work)
346{
347 struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work.work);
348
349 em28xx_i2c_ir_handle_key(ir);
350 schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
351}
352
321static void em28xx_ir_work(struct work_struct *work) 353static void em28xx_ir_work(struct work_struct *work)
322{ 354{
323 struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work.work); 355 struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work.work);
@@ -330,7 +362,10 @@ static int em28xx_ir_start(struct rc_dev *rc)
330{ 362{
331 struct em28xx_IR *ir = rc->priv; 363 struct em28xx_IR *ir = rc->priv;
332 364
333 INIT_DELAYED_WORK(&ir->work, em28xx_ir_work); 365 if (ir->i2c_dev) /* external i2c device */
366 INIT_DELAYED_WORK(&ir->work, em28xx_i2c_ir_work);
367 else /* internal device */
368 INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
334 schedule_delayed_work(&ir->work, 0); 369 schedule_delayed_work(&ir->work, 0);
335 370
336 return 0; 371 return 0;
@@ -427,49 +462,33 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
427 } 462 }
428} 463}
429 464
430static void em28xx_register_i2c_ir(struct em28xx *dev) 465static struct i2c_client *em28xx_probe_i2c_ir(struct em28xx *dev)
431{ 466{
467 int i = 0;
468 struct i2c_client *i2c_dev = NULL;
432 /* Leadtek winfast tv USBII deluxe can find a non working IR-device */ 469 /* Leadtek winfast tv USBII deluxe can find a non working IR-device */
433 /* at address 0x18, so if that address is needed for another board in */ 470 /* at address 0x18, so if that address is needed for another board in */
434 /* the future, please put it after 0x1f. */ 471 /* the future, please put it after 0x1f. */
435 struct i2c_board_info info;
436 const unsigned short addr_list[] = { 472 const unsigned short addr_list[] = {
437 0x1f, 0x30, 0x47, I2C_CLIENT_END 473 0x1f, 0x30, 0x47, I2C_CLIENT_END
438 }; 474 };
439 475
440 memset(&info, 0, sizeof(struct i2c_board_info)); 476 while (addr_list[i] != I2C_CLIENT_END) {
441 memset(&dev->init_data, 0, sizeof(dev->init_data)); 477 if (i2c_probe_func_quick_read(&dev->i2c_adap, addr_list[i]) == 1) {
442 strlcpy(info.type, "ir_video", I2C_NAME_SIZE); 478 i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
443 479 if (i2c_dev) {
444 /* detect & configure */ 480 i2c_dev->addr = addr_list[i];
445 switch (dev->model) { 481 i2c_dev->adapter = &dev->i2c_adap;
446 case EM2800_BOARD_TERRATEC_CINERGY_200: 482 /* NOTE: as long as we don't register the device
447 case EM2820_BOARD_TERRATEC_CINERGY_250: 483 * at the i2c subsystem, no other fields need to
448 dev->init_data.ir_codes = RC_MAP_EM_TERRATEC; 484 * be set up */
449 dev->init_data.get_key = em28xx_get_key_terratec; 485 }
450 dev->init_data.name = "Terratec Cinergy 200/250"; 486 break;
451 break; 487 }
452 case EM2820_BOARD_PINNACLE_USB_2: 488 i++;
453 dev->init_data.ir_codes = RC_MAP_PINNACLE_GREY;
454 dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
455 dev->init_data.name = "Pinnacle USB2";
456 break;
457 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
458 dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
459 dev->init_data.get_key = em28xx_get_key_em_haup;
460 dev->init_data.name = "WinTV USB2";
461 dev->init_data.type = RC_BIT_RC5;
462 break;
463 case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
464 dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;
465 dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
466 dev->init_data.name = "Winfast TV USBII Deluxe";
467 break;
468 } 489 }
469 490
470 if (dev->init_data.name) 491 return i2c_dev;
471 info.platform_data = &dev->init_data;
472 i2c_new_probed_device(&dev->i2c_adap, &info, addr_list, NULL);
473} 492}
474 493
475/********************************************************** 494/**********************************************************
@@ -565,19 +584,21 @@ static int em28xx_ir_init(struct em28xx *dev)
565 struct rc_dev *rc; 584 struct rc_dev *rc;
566 int err = -ENOMEM; 585 int err = -ENOMEM;
567 u64 rc_type; 586 u64 rc_type;
587 struct i2c_client *i2c_rc_dev = NULL;
568 588
569 if (dev->board.has_snapshot_button) 589 if (dev->board.has_snapshot_button)
570 em28xx_register_snapshot_button(dev); 590 em28xx_register_snapshot_button(dev);
571 591
572 if (dev->board.has_ir_i2c) { 592 if (dev->board.has_ir_i2c) {
573 em28xx_register_i2c_ir(dev); 593 i2c_rc_dev = em28xx_probe_i2c_ir(dev);
574#if defined(CONFIG_MODULES) && defined(MODULE) 594 if (!i2c_rc_dev) {
575 request_module("ir-kbd-i2c"); 595 dev->board.has_ir_i2c = 0;
576#endif 596 em28xx_warn("No i2c IR remote control device found.\n");
577 return 0; 597 return -ENODEV;
598 }
578 } 599 }
579 600
580 if (dev->board.ir_codes == NULL) { 601 if (dev->board.ir_codes == NULL && !dev->board.has_ir_i2c) {
581 /* No remote control support */ 602 /* No remote control support */
582 em28xx_warn("Remote control support is not available for " 603 em28xx_warn("Remote control support is not available for "
583 "this card.\n"); 604 "this card.\n");
@@ -594,45 +615,70 @@ static int em28xx_ir_init(struct em28xx *dev)
594 dev->ir = ir; 615 dev->ir = ir;
595 ir->rc = rc; 616 ir->rc = rc;
596 617
597 /*
598 * em2874 supports more protocols. For now, let's just announce
599 * the two protocols that were already tested
600 */
601 rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC;
602 rc->priv = ir; 618 rc->priv = ir;
603 rc->change_protocol = em28xx_ir_change_protocol;
604 rc->open = em28xx_ir_start; 619 rc->open = em28xx_ir_start;
605 rc->close = em28xx_ir_stop; 620 rc->close = em28xx_ir_stop;
606 621
607 switch (dev->chip_id) { 622 if (dev->board.has_ir_i2c) { /* external i2c device */
608 case CHIP_ID_EM2860: 623 switch (dev->model) {
609 case CHIP_ID_EM2883: 624 case EM2800_BOARD_TERRATEC_CINERGY_200:
610 rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC; 625 case EM2820_BOARD_TERRATEC_CINERGY_250:
611 ir->get_key = default_polling_getkey; 626 rc->map_name = RC_MAP_EM_TERRATEC;
612 break; 627 ir->get_key_i2c = em28xx_get_key_terratec;
613 case CHIP_ID_EM2884: 628 break;
614 case CHIP_ID_EM2874: 629 case EM2820_BOARD_PINNACLE_USB_2:
615 case CHIP_ID_EM28174: 630 rc->map_name = RC_MAP_PINNACLE_GREY;
616 ir->get_key = em2874_polling_getkey; 631 ir->get_key_i2c = em28xx_get_key_pinnacle_usb_grey;
617 rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC | RC_BIT_RC6_0; 632 break;
618 break; 633 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
619 default: 634 rc->map_name = RC_MAP_HAUPPAUGE;
620 err = -ENODEV; 635 ir->get_key_i2c = em28xx_get_key_em_haup;
621 goto error; 636 rc->allowed_protos = RC_BIT_RC5;
637 break;
638 case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
639 rc->map_name = RC_MAP_WINFAST_USBII_DELUXE;
640 ir->get_key_i2c = em28xx_get_key_winfast_usbii_deluxe;
641 break;
642 default:
643 err = -ENODEV;
644 goto error;
645 }
646
647 ir->i2c_dev = i2c_rc_dev;
648 } else { /* internal device */
649 switch (dev->chip_id) {
650 case CHIP_ID_EM2860:
651 case CHIP_ID_EM2883:
652 rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC;
653 ir->get_key = default_polling_getkey;
654 break;
655 case CHIP_ID_EM2884:
656 case CHIP_ID_EM2874:
657 case CHIP_ID_EM28174:
658 ir->get_key = em2874_polling_getkey;
659 rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC |
660 RC_BIT_RC6_0;
661 break;
662 default:
663 err = -ENODEV;
664 goto error;
665 }
666
667 rc->change_protocol = em28xx_ir_change_protocol;
668 rc->map_name = dev->board.ir_codes;
669
670 /* By default, keep protocol field untouched */
671 rc_type = RC_BIT_UNKNOWN;
672 err = em28xx_ir_change_protocol(rc, &rc_type);
673 if (err)
674 goto error;
622 } 675 }
623 676
624 /* By default, keep protocol field untouched */
625 rc_type = RC_BIT_UNKNOWN;
626 err = em28xx_ir_change_protocol(rc, &rc_type);
627 if (err)
628 goto error;
629
630 /* This is how often we ask the chip for IR information */ 677 /* This is how often we ask the chip for IR information */
631 ir->polling = 100; /* ms */ 678 ir->polling = 100; /* ms */
632 679
633 /* init input device */ 680 /* init input device */
634 snprintf(ir->name, sizeof(ir->name), "em28xx IR (%s)", 681 snprintf(ir->name, sizeof(ir->name), "em28xx IR (%s)", dev->name);
635 dev->name);
636 682
637 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); 683 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
638 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 684 strlcat(ir->phys, "/input0", sizeof(ir->phys));
@@ -644,7 +690,6 @@ static int em28xx_ir_init(struct em28xx *dev)
644 rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); 690 rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
645 rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct); 691 rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
646 rc->dev.parent = &dev->udev->dev; 692 rc->dev.parent = &dev->udev->dev;
647 rc->map_name = dev->board.ir_codes;
648 rc->driver_name = MODULE_NAME; 693 rc->driver_name = MODULE_NAME;
649 694
650 /* all done */ 695 /* all done */
@@ -655,6 +700,8 @@ static int em28xx_ir_init(struct em28xx *dev)
655 return 0; 700 return 0;
656 701
657error: 702error:
703 if (ir && ir->i2c_dev)
704 kfree(ir->i2c_dev);
658 dev->ir = NULL; 705 dev->ir = NULL;
659 rc_free_device(rc); 706 rc_free_device(rc);
660 kfree(ir); 707 kfree(ir);
@@ -674,6 +721,8 @@ static int em28xx_ir_fini(struct em28xx *dev)
674 if (ir->rc) 721 if (ir->rc)
675 rc_unregister_device(ir->rc); 722 rc_unregister_device(ir->rc);
676 723
724 kfree(ir->i2c_dev);
725
677 /* done */ 726 /* done */
678 kfree(ir); 727 kfree(ir);
679 dev->ir = NULL; 728 dev->ir = NULL;
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index 2aa4b8472a62..5f0b2c59e846 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -640,9 +640,6 @@ struct em28xx {
640 struct delayed_work sbutton_query_work; 640 struct delayed_work sbutton_query_work;
641 641
642 struct em28xx_dvb *dvb; 642 struct em28xx_dvb *dvb;
643
644 /* I2C keyboard data */
645 struct IR_i2c_init_data init_data;
646}; 643};
647 644
648struct em28xx_ops { 645struct em28xx_ops {