aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/tuner-xc2028.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c
index e19449603d73..3edf5be47197 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,
377 v4l2_std_id *id) 377 v4l2_std_id *id)
378{ 378{
379 struct xc2028_data *priv = fe->tuner_priv; 379 struct xc2028_data *priv = fe->tuner_priv;
380 int i; 380 int i, best_i = -1, best_nr_matches = 0;
381 381
382 tuner_dbg("%s called\n", __FUNCTION__); 382 tuner_dbg("%s called, want type=", __FUNCTION__);
383 if (debug) {
384 dump_firm_type(type);
385 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
386 }
383 387
384 if (!priv->firm) { 388 if (!priv->firm) {
385 tuner_err("Error! firmware not loaded\n"); 389 tuner_err("Error! firmware not loaded\n");
@@ -397,20 +401,45 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
397 401
398 /* Seek for generic video standard match */ 402 /* Seek for generic video standard match */
399 for (i = 0; i < priv->firm_size; i++) { 403 for (i = 0; i < priv->firm_size; i++) {
400 if ((type == priv->firm[i].type) && (*id & priv->firm[i].id)) 404 v4l2_std_id match_mask;
401 goto found; 405 int nr_matches;
406
407 if (type != priv->firm[i].type)
408 continue;
409
410 match_mask = *id & priv->firm[i].id;
411 if (!match_mask)
412 continue;
413
414 if ((*id & match_mask) == *id)
415 goto found; /* Supports all the requested standards */
416
417 nr_matches = hweight64(match_mask);
418 if (nr_matches > best_nr_matches) {
419 best_nr_matches = nr_matches;
420 best_i = i;
421 }
422 }
423
424 if (best_nr_matches > 0) {
425 tuner_dbg("Selecting best matching firmware (%d bits) for "
426 "type=", best_nr_matches);
427 dump_firm_type(type);
428 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
429 i = best_i;
430 goto found;
402 } 431 }
403 432
404 /*FIXME: Would make sense to seek for type "hint" match ? */ 433 /*FIXME: Would make sense to seek for type "hint" match ? */
405 434
406 i = -EINVAL; 435 i = -ENOENT;
407 goto ret; 436 goto ret;
408 437
409found: 438found:
410 *id = priv->firm[i].id; 439 *id = priv->firm[i].id;
411 440
412ret: 441ret:
413 tuner_dbg("%s firmware for type=", (i < 0)? "Can't find": "Found"); 442 tuner_dbg("%s firmware for type=", (i < 0) ? "Can't find" : "Found");
414 if (debug) { 443 if (debug) {
415 dump_firm_type(type); 444 dump_firm_type(type);
416 printk("(%x), id %016llx.\n", type, (unsigned long long)*id); 445 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,
432 return pos; 461 return pos;
433 462
434 tuner_info("Loading firmware for type="); 463 tuner_info("Loading firmware for type=");
435 dump_firm_type(type); 464 dump_firm_type(priv->firm[pos].type);
436 printk("(%x), id %016llx.\n", type, (unsigned long long)*id); 465 printk("(%x), id %016llx.\n", priv->firm[pos].type,
466 (unsigned long long)*id);
437 467
438 p = priv->firm[pos].ptr; 468 p = priv->firm[pos].ptr;
439 endp = p + priv->firm[pos].size; 469 endp = p + priv->firm[pos].size;