aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/tuners/xc4000.c
diff options
context:
space:
mode:
authorIstvan Varga <istvan_v@mailbox.hu>2011-06-04 10:52:34 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:52:34 -0400
commit3db9570482f368cd2f62c258802da21667ec6198 (patch)
tree6480ad50d0754442a01e204abcf426428cf57140 /drivers/media/common/tuners/xc4000.c
parentfa285bc1bf5a2ebe3252523454def096d86a064b (diff)
[media] xc4000: simplified seek_firmware()
This patch simplifies the code in seek_firmware(). Signed-off-by: Istvan Varga <istvan_v@mailbox.hu> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/common/tuners/xc4000.c')
-rw-r--r--drivers/media/common/tuners/xc4000.c71
1 files changed, 25 insertions, 46 deletions
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c
index 229a2155b2e8..811519a49f59 100644
--- a/drivers/media/common/tuners/xc4000.c
+++ b/drivers/media/common/tuners/xc4000.c
@@ -605,8 +605,8 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
605 v4l2_std_id *id) 605 v4l2_std_id *id)
606{ 606{
607 struct xc4000_priv *priv = fe->tuner_priv; 607 struct xc4000_priv *priv = fe->tuner_priv;
608 int i, best_i = -1, best_nr_matches = 0; 608 int i, best_i = -1;
609 unsigned int type_mask = 0; 609 unsigned int best_nr_diffs = 255U;
610 610
611 if (!priv->firm) { 611 if (!priv->firm) {
612 printk("Error! firmware not loaded\n"); 612 printk("Error! firmware not loaded\n");
@@ -616,63 +616,42 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
616 if (((type & ~SCODE) == 0) && (*id == 0)) 616 if (((type & ~SCODE) == 0) && (*id == 0))
617 *id = V4L2_STD_PAL; 617 *id = V4L2_STD_PAL;
618 618
619 if (type & BASE)
620 type_mask = BASE_TYPES;
621 else if (type & SCODE) {
622 type &= SCODE_TYPES;
623 type_mask = SCODE_TYPES & ~HAS_IF;
624 } else if (type & DTV_TYPES)
625 type_mask = DTV_TYPES;
626 else if (type & STD_SPECIFIC_TYPES)
627 type_mask = STD_SPECIFIC_TYPES;
628
629 type &= type_mask;
630
631 if (!(type & SCODE))
632 type_mask = ~0;
633
634 /* Seek for exact match */
635 for (i = 0; i < priv->firm_size; i++) {
636 if ((type == (priv->firm[i].type & type_mask)) &&
637 (*id == priv->firm[i].id))
638 goto found;
639 }
640
641 /* Seek for generic video standard match */ 619 /* Seek for generic video standard match */
642 for (i = 0; i < priv->firm_size; i++) { 620 for (i = 0; i < priv->firm_size; i++) {
643 v4l2_std_id match_mask; 621 v4l2_std_id id_diff_mask =
644 int nr_matches; 622 (priv->firm[i].id ^ (*id)) & (*id);
645 623 unsigned int type_diff_mask =
646 if (type != (priv->firm[i].type & type_mask)) 624 (priv->firm[i].type ^ type)
625 & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
626 unsigned int nr_diffs;
627
628 if (type_diff_mask
629 & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
647 continue; 630 continue;
648 631
649 match_mask = *id & priv->firm[i].id; 632 nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
650 if (!match_mask) 633 if (!nr_diffs) /* Supports all the requested standards */
651 continue; 634 goto found;
652
653 if ((*id & match_mask) == *id)
654 goto found; /* Supports all the requested standards */
655 635
656 nr_matches = hweight64(match_mask); 636 if (nr_diffs < best_nr_diffs) {
657 if (nr_matches > best_nr_matches) { 637 best_nr_diffs = nr_diffs;
658 best_nr_matches = nr_matches;
659 best_i = i; 638 best_i = i;
660 } 639 }
661 } 640 }
662 641
663 if (best_nr_matches > 0) { 642 /* FIXME: Would make sense to seek for type "hint" match ? */
664 printk("Selecting best matching firmware (%d bits) for " 643 if (best_i < 0) {
665 "type=", best_nr_matches); 644 i = -ENOENT;
645 goto ret;
646 }
647
648 if (best_nr_diffs > 0U) {
649 printk("Selecting best matching firmware (%u bits differ) for "
650 "type=", best_nr_diffs);
666 printk("(%x), id %016llx:\n", type, (unsigned long long)*id); 651 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
667 i = best_i; 652 i = best_i;
668 goto found;
669 } 653 }
670 654
671 /*FIXME: Would make sense to seek for type "hint" match ? */
672
673 i = -ENOENT;
674 goto ret;
675
676found: 655found:
677 *id = priv->firm[i].id; 656 *id = priv->firm[i].id;
678 657