Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b1535293dc816f01b0934718c370f9533c7d635e
Commit:     b1535293dc816f01b0934718c370f9533c7d635e
Parent:     0a196b6fa9b42a2bb49733b37565aaaa97ffb07f
Author:     Chris Pascoe <[EMAIL PROTECTED]>
AuthorDate: Mon Nov 19 10:04:06 2007 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Fri Jan 25 19:02:28 2008 -0200

    V4L/DVB (6643): xc2028: use best match instead of first partial match 
during firmware selection
    
    Rather than picking the first video standard firmware that supports any of
    the standards that the user has requested, try to select one that supports
    as many of them as possible.  This improves the likelihood that the firmware
    we select will support the user's desired TV standard.
    
    Signed-off-by: Chris Pascoe <[EMAIL PROTECTED]>
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 drivers/media/video/tuner-xc2028.c |   46 +++++++++++++++++++++++++++++------
 1 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/drivers/media/video/tuner-xc2028.c 
b/drivers/media/video/tuner-xc2028.c
index e194496..3edf5be 100644
--- a/drivers/media/video/tuner-xc2028.c
+++ b/drivers/media/video/tuner-xc2028.c
@@ -377,9 +377,13 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned 
int type,
                         v4l2_std_id *id)
 {
        struct xc2028_data *priv = fe->tuner_priv;
-       int                i;
+       int                 i, best_i = -1, best_nr_matches = 0;
 
-       tuner_dbg("%s called\n", __FUNCTION__);
+       tuner_dbg("%s called, want type=", __FUNCTION__);
+       if (debug) {
+               dump_firm_type(type);
+               printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
+       }
 
        if (!priv->firm) {
                tuner_err("Error! firmware not loaded\n");
@@ -397,20 +401,45 @@ static int seek_firmware(struct dvb_frontend *fe, 
unsigned int type,
 
        /* Seek for generic video standard match */
        for (i = 0; i < priv->firm_size; i++) {
-               if ((type == priv->firm[i].type) && (*id & priv->firm[i].id))
-                       goto found;
+               v4l2_std_id match_mask;
+               int nr_matches;
+
+               if (type != priv->firm[i].type)
+                       continue;
+
+               match_mask = *id & priv->firm[i].id;
+               if (!match_mask)
+                       continue;
+
+               if ((*id & match_mask) == *id)
+                       goto found; /* Supports all the requested standards */
+
+               nr_matches = hweight64(match_mask);
+               if (nr_matches > best_nr_matches) {
+                       best_nr_matches = nr_matches;
+                       best_i = i;
+               }
+       }
+
+       if (best_nr_matches > 0) {
+               tuner_dbg("Selecting best matching firmware (%d bits) for "
+                         "type=", best_nr_matches);
+               dump_firm_type(type);
+               printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
+               i = best_i;
+               goto found;
        }
 
        /*FIXME: Would make sense to seek for type "hint" match ? */
 
-       i = -EINVAL;
+       i = -ENOENT;
        goto ret;
 
 found:
        *id = priv->firm[i].id;
 
 ret:
-       tuner_dbg("%s firmware for type=", (i < 0)? "Can't find": "Found");
+       tuner_dbg("%s firmware for type=", (i < 0) ? "Can't find" : "Found");
        if (debug) {
                dump_firm_type(type);
                printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
@@ -432,8 +461,9 @@ static int load_firmware(struct dvb_frontend *fe, unsigned 
int type,
                return pos;
 
        tuner_info("Loading firmware for type=");
-       dump_firm_type(type);
-       printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
+       dump_firm_type(priv->firm[pos].type);
+       printk("(%x), id %016llx.\n", priv->firm[pos].type,
+              (unsigned long long)*id);
 
        p = priv->firm[pos].ptr;
        endp = p + priv->firm[pos].size;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to