aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c42
-rw-r--r--drivers/media/video/v4l2-common.c36
-rw-r--r--include/media/v4l2-common.h13
3 files changed, 65 insertions, 26 deletions
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index ac23ff53543..829006ebdf3 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -980,35 +980,25 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* initialize hardware #2 */
if (TUNER_ABSENT != dev->tuner_type) {
- if (dev->radio_type != UNSET) {
- v4l2_i2c_new_subdev(&dev->i2c_adap, "tuner", "tuner",
- dev->radio_addr);
- }
- if (dev->tda9887_conf & TDA9887_PRESENT) {
- unsigned short addrs[] = { 0x42, 0x43, 0x4a, 0x4b,
- I2C_CLIENT_END };
+ int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
- v4l2_i2c_new_probed_subdev(&dev->i2c_adap,
- "tuner", "tuner", addrs);
- }
- if (dev->tuner_addr != ADDR_UNSET) {
+ /* Note: radio tuner address is always filled in,
+ so we do not need to probe for a radio tuner device. */
+ if (dev->radio_type != UNSET)
v4l2_i2c_new_subdev(&dev->i2c_adap,
- "tuner", "tuner", dev->tuner_addr);
+ "tuner", "tuner", dev->radio_addr);
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (dev->tuner_addr == ADDR_UNSET) {
+ enum v4l2_i2c_tuner_type type =
+ has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(type));
} else {
- unsigned short addrs[] = {
- 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- I2C_CLIENT_END
- };
-
- if (dev->tda9887_conf & TDA9887_PRESENT) {
- v4l2_i2c_new_probed_subdev(&dev->i2c_adap,
- "tuner", "tuner", addrs + 4);
- } else {
- v4l2_i2c_new_probed_subdev(&dev->i2c_adap,
- "tuner", "tuner", addrs);
- }
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
}
}
saa7134_board_init2(dev);
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 0f450a73477..26e162f13f7 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -991,4 +991,40 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev);
+/* Return a list of I2C tuner addresses to probe. Use only if the tuner
+ addresses are unknown. */
+const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
+{
+ static const unsigned short radio_addrs[] = {
+#if defined(CONFIG_MEDIA_TUNER_TEA5761) || defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE)
+ 0x10,
+#endif
+ 0x60,
+ I2C_CLIENT_END
+ };
+ static const unsigned short demod_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b,
+ I2C_CLIENT_END
+ };
+ static const unsigned short tv_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ I2C_CLIENT_END
+ };
+
+ switch (type) {
+ case ADDRS_RADIO:
+ return radio_addrs;
+ case ADDRS_DEMOD:
+ return demod_addrs;
+ case ADDRS_TV:
+ return tv_addrs;
+ case ADDRS_TV_WITH_DEMOD:
+ return tv_addrs + 4;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
+
#endif
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 95e74f1874e..0f864f8daaf 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -150,6 +150,19 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
const struct v4l2_subdev_ops *ops);
+enum v4l2_i2c_tuner_type {
+ ADDRS_RADIO, /* Radio tuner addresses */
+ ADDRS_DEMOD, /* Demod tuner addresses */
+ ADDRS_TV, /* TV tuner addresses */
+ /* TV tuner addresses if demod is present, this excludes
+ addresses used by the demodulator from the list of
+ candidates. */
+ ADDRS_TV_WITH_DEMOD,
+};
+/* Return a list of I2C tuner addresses to probe. Use only if the tuner
+ addresses are unknown. */
+const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);
+
/* ------------------------------------------------------------------------- */
/* Internal ioctls */