Skip to content

Commit

Permalink
V4L/DVB (6643): xc2028: use best match instead of first partial match…
Browse files Browse the repository at this point in the history
… 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 <c.pascoe@itee.uq.edu.au>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
  • Loading branch information
Chris Pascoe authored and Mauro Carvalho Chehab committed Jan 25, 2008
1 parent 0a196b6 commit b153529
Showing 1 changed file with 38 additions and 8 deletions.
46 changes: 38 additions & 8 deletions drivers/media/video/tuner-xc2028.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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);
Expand All @@ -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;
Expand Down

0 comments on commit b153529

Please sign in to comment.