diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2007-11-04 08:42:42 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:01:59 -0500 |
commit | 159ffe77cd9b1cd7c80c416b5635bdad7e3d7d55 (patch) | |
tree | 8081a98549db8ba2b4b1f17034b9c9261c9e0cbd /drivers/media | |
parent | a818e1c8f7fcb42866a8630c508caddaa8edb331 (diff) |
V4L/DVB (6553): tuner: replace default_mode_mask
The default_mode_mask global is replaced by a list of tuner structs. The
tuner driver now walks that list to see which radio and/or tv tuner
devices are registered to a given i2c adapter.
The default_mode_mask global had to go since this is no longer supported
with the new bus-based I2C API.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/tuner-core.c | 65 | ||||
-rw-r--r-- | drivers/media/video/tuner-driver.h | 1 |
2 files changed, 55 insertions, 11 deletions
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 3ec50dbed742..4f2bd2dd15c7 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -585,8 +585,38 @@ static void tuner_status(struct dvb_frontend *fe) | |||
585 | 585 | ||
586 | /* ---------------------------------------------------------------------- */ | 586 | /* ---------------------------------------------------------------------- */ |
587 | 587 | ||
588 | /* static vars: used only in tuner_attach and tuner_probe */ | 588 | LIST_HEAD(tuner_list); |
589 | static unsigned default_mode_mask; | 589 | |
590 | /* Search for existing radio and/or TV tuners on the given I2C adapter. | ||
591 | Note that when this function is called from tuner_attach you can be | ||
592 | certain no other devices will be added/deleted at the same time, I2C | ||
593 | core protects against that. */ | ||
594 | static void tuner_lookup(struct i2c_adapter *adap, | ||
595 | struct tuner **radio, struct tuner **tv) | ||
596 | { | ||
597 | struct tuner *pos; | ||
598 | |||
599 | *radio = NULL; | ||
600 | *tv = NULL; | ||
601 | |||
602 | list_for_each_entry(pos, &tuner_list, list) { | ||
603 | int mode_mask; | ||
604 | |||
605 | if (pos->i2c->adapter != adap || | ||
606 | pos->i2c->driver->id != I2C_DRIVERID_TUNER) | ||
607 | continue; | ||
608 | |||
609 | mode_mask = pos->mode_mask & ~T_STANDBY; | ||
610 | if (*radio == NULL && mode_mask == T_RADIO) | ||
611 | *radio = pos; | ||
612 | /* Note: currently TDA9887 is the only demod-only | ||
613 | device. If other devices appear then we need to | ||
614 | make this test more general. */ | ||
615 | else if (*tv == NULL && pos->type != TUNER_TDA9887 && | ||
616 | (pos->mode_mask & (T_ANALOG_TV | T_DIGITAL_TV))) | ||
617 | *tv = pos; | ||
618 | } | ||
619 | } | ||
590 | 620 | ||
591 | /* During client attach, set_type is called by adapter's attach_inform callback. | 621 | /* During client attach, set_type is called by adapter's attach_inform callback. |
592 | set_type must then be completed by tuner_attach. | 622 | set_type must then be completed by tuner_attach. |
@@ -595,6 +625,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
595 | { | 625 | { |
596 | struct i2c_client *client; | 626 | struct i2c_client *client; |
597 | struct tuner *t; | 627 | struct tuner *t; |
628 | struct tuner *radio; | ||
629 | struct tuner *tv; | ||
598 | 630 | ||
599 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | 631 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); |
600 | if (NULL == client) | 632 | if (NULL == client) |
@@ -638,7 +670,9 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
638 | t->mode_mask = T_RADIO; | 670 | t->mode_mask = T_RADIO; |
639 | t->mode = T_STANDBY; | 671 | t->mode = T_STANDBY; |
640 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ | 672 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ |
641 | default_mode_mask &= ~T_RADIO; | 673 | tuner_lookup(t->i2c->adapter, &radio, &tv); |
674 | if (tv) | ||
675 | tv->mode_mask &= ~T_RADIO; | ||
642 | 676 | ||
643 | goto register_client; | 677 | goto register_client; |
644 | } | 678 | } |
@@ -665,7 +699,9 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
665 | t->mode_mask = T_RADIO; | 699 | t->mode_mask = T_RADIO; |
666 | t->mode = T_STANDBY; | 700 | t->mode = T_STANDBY; |
667 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ | 701 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ |
668 | default_mode_mask &= ~T_RADIO; | 702 | tuner_lookup(t->i2c->adapter, &radio, &tv); |
703 | if (tv) | ||
704 | tv->mode_mask &= ~T_RADIO; | ||
669 | 705 | ||
670 | goto register_client; | 706 | goto register_client; |
671 | } | 707 | } |
@@ -673,13 +709,21 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
673 | } | 709 | } |
674 | } | 710 | } |
675 | 711 | ||
676 | /* Initializes only the first adapter found */ | 712 | /* Initializes only the first TV tuner on this adapter. Why only the |
677 | if (default_mode_mask != T_UNINITIALIZED) { | 713 | first? Because there are some devices (notably the ones with TI |
678 | tuner_dbg ("Setting mode_mask to 0x%02x\n", default_mode_mask); | 714 | tuners) that have more than one i2c address for the *same* device. |
679 | t->mode_mask = default_mode_mask; | 715 | Experience shows that, except for just one case, the first |
716 | address is the right one. The exception is a Russian tuner | ||
717 | (ACORP_Y878F). So, the desired behavior is just to enable the | ||
718 | first found TV tuner. */ | ||
719 | tuner_lookup(t->i2c->adapter, &radio, &tv); | ||
720 | if (tv == NULL) { | ||
721 | t->mode_mask = T_ANALOG_TV | T_DIGITAL_TV; | ||
722 | if (radio == NULL) | ||
723 | t->mode_mask |= T_RADIO; | ||
724 | tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask); | ||
680 | t->tv_freq = 400 * 16; /* Sets freq to VHF High */ | 725 | t->tv_freq = 400 * 16; /* Sets freq to VHF High */ |
681 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ | 726 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ |
682 | default_mode_mask = T_UNINITIALIZED; | ||
683 | } | 727 | } |
684 | 728 | ||
685 | /* Should be just before return */ | 729 | /* Should be just before return */ |
@@ -729,8 +773,6 @@ static int tuner_probe(struct i2c_adapter *adap) | |||
729 | "in i2c probe ignore list!\n"); | 773 | "in i2c probe ignore list!\n"); |
730 | } | 774 | } |
731 | 775 | ||
732 | default_mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; | ||
733 | |||
734 | if (adap->class & I2C_CLASS_TV_ANALOG) | 776 | if (adap->class & I2C_CLASS_TV_ANALOG) |
735 | return i2c_probe(adap, &addr_data, tuner_attach); | 777 | return i2c_probe(adap, &addr_data, tuner_attach); |
736 | return 0; | 778 | return 0; |
@@ -752,6 +794,7 @@ static int tuner_detach(struct i2c_client *client) | |||
752 | if (ops && ops->release) | 794 | if (ops && ops->release) |
753 | ops->release(&t->fe); | 795 | ops->release(&t->fe); |
754 | 796 | ||
797 | list_del(&t->list); | ||
755 | kfree(t); | 798 | kfree(t); |
756 | kfree(client); | 799 | kfree(client); |
757 | return 0; | 800 | return 0; |
diff --git a/drivers/media/video/tuner-driver.h b/drivers/media/video/tuner-driver.h index 1c60229dcd0a..3ff2943ecc11 100644 --- a/drivers/media/video/tuner-driver.h +++ b/drivers/media/video/tuner-driver.h | |||
@@ -46,6 +46,7 @@ struct analog_tuner_ops { | |||
46 | struct tuner { | 46 | struct tuner { |
47 | /* device */ | 47 | /* device */ |
48 | struct i2c_client *i2c; | 48 | struct i2c_client *i2c; |
49 | struct list_head list; /* list of tuners */ | ||
49 | 50 | ||
50 | unsigned int type; /* chip type */ | 51 | unsigned int type; /* chip type */ |
51 | 52 | ||