aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-11-04 08:42:42 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:01:59 -0500
commit159ffe77cd9b1cd7c80c416b5635bdad7e3d7d55 (patch)
tree8081a98549db8ba2b4b1f17034b9c9261c9e0cbd /drivers/media
parenta818e1c8f7fcb42866a8630c508caddaa8edb331 (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.c65
-rw-r--r--drivers/media/video/tuner-driver.h1
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 */ 588LIST_HEAD(tuner_list);
589static 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. */
594static 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 {
46struct tuner { 46struct 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