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");
/* 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);
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;