diff options
author | Istvan Varga <istvan_v@mailbox.hu> | 2011-06-04 10:52:34 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 16:52:34 -0400 |
commit | 3db9570482f368cd2f62c258802da21667ec6198 (patch) | |
tree | 6480ad50d0754442a01e204abcf426428cf57140 /drivers/media/common/tuners/xc4000.c | |
parent | fa285bc1bf5a2ebe3252523454def096d86a064b (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.c | 71 |
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 | |||
676 | found: | 655 | found: |
677 | *id = priv->firm[i].id; | 656 | *id = priv->firm[i].id; |
678 | 657 | ||