The patch number 11280 was added via Mauro Carvalho Chehab <[email protected]>
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        Linux Media Mailing List <[email protected]>

------

From: Mauro Carvalho Chehab  <[email protected]>
merge: http://www.linuxtv.org/hg/~hverkuil/v4l-dvb-bttv


Signed-off-by: Mauro Carvalho Chehab <[email protected]>


---

 linux/drivers/media/video/bt8xx/Kconfig       |    1 
 linux/drivers/media/video/bt8xx/bttv-cards.c  |  187 +++++++++++++++---
 linux/drivers/media/video/bt8xx/bttv-driver.c |   43 +---
 linux/drivers/media/video/bt8xx/bttv-i2c.c    |   52 -----
 linux/drivers/media/video/bt8xx/bttv.h        |    7 
 linux/drivers/media/video/bt8xx/bttvp.h       |    5 
 linux/drivers/media/video/tvaudio.c           |  158 ++++++++++++++-
 7 files changed, 341 insertions(+), 112 deletions(-)

diff -r 055d56e8f2d1 -r df7a51ffa2ba linux/drivers/media/video/bt8xx/Kconfig
--- a/linux/drivers/media/video/bt8xx/Kconfig   Sun Mar 29 05:51:18 2009 -0300
+++ b/linux/drivers/media/video/bt8xx/Kconfig   Sun Mar 29 05:58:58 2009 -0300
@@ -10,7 +10,6 @@ config VIDEO_BT848
        select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
        select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
        select VIDEO_TDA7432 if VIDEO_HELPER_CHIPS_AUTO
-       select VIDEO_TDA9875 if VIDEO_HELPER_CHIPS_AUTO
        ---help---
          Support for BT848 based frame grabber/overlay boards. This includes
          the Miro, Hauppauge and STB boards. Please read the material in
diff -r 055d56e8f2d1 -r df7a51ffa2ba 
linux/drivers/media/video/bt8xx/bttv-cards.c
--- a/linux/drivers/media/video/bt8xx/bttv-cards.c      Sun Mar 29 05:51:18 
2009 -0300
+++ b/linux/drivers/media/video/bt8xx/bttv-cards.c      Sun Mar 29 05:58:58 
2009 -0300
@@ -97,12 +97,10 @@ static unsigned int tuner[BTTV_MAX]  = {
 static unsigned int tuner[BTTV_MAX]  = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
 static unsigned int svhs[BTTV_MAX]   = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
 static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
+static unsigned int audiodev[BTTV_MAX];
+static unsigned int saa6588[BTTV_MAX];
 static struct bttv  *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL };
-#ifdef MODULE
-static unsigned int autoload = 1;
-#else
-static unsigned int autoload;
-#endif
+static unsigned int autoload = UNSET;
 static unsigned int gpiomask = UNSET;
 static unsigned int audioall = UNSET;
 static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET };
@@ -121,6 +119,7 @@ module_param_array(tuner,    int, NULL, 
 module_param_array(tuner,    int, NULL, 0444);
 module_param_array(svhs,     int, NULL, 0444);
 module_param_array(remote,   int, NULL, 0444);
+module_param_array(audiodev, int, NULL, 0444);
 module_param_array(audiomux, int, NULL, 0444);
 
 MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
@@ -131,7 +130,14 @@ MODULE_PARM_DESC(card,"specify TV/grabbe
 MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a 
list");
 MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 
MHz)");
 MODULE_PARM_DESC(tuner,"specify installed tuner type");
-MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, 
default is 1 (yes)");
+MODULE_PARM_DESC(autoload, "obsolete option, please do not use anymore");
+MODULE_PARM_DESC(audiodev, "specify audio device:\n"
+               "\t\t-1 = no audio\n"
+               "\t\t 0 = autodetect (default)\n"
+               "\t\t 1 = msp3400\n"
+               "\t\t 2 = tda7432\n"
+               "\t\t 3 = tvaudio");
+MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) 
is to use the card definition.");
 MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 
enables)"
                " [some VIA/SIS chipsets are known to have problem with 
overlay]");
 
@@ -3356,6 +3362,17 @@ void __devinit bttv_init_card1(struct bt
 /* initialization part two -- after registering i2c bus */
 void __devinit bttv_init_card2(struct bttv *btv)
 {
+       static const unsigned short tvaudio_addrs[] = {
+               I2C_ADDR_TDA8425   >> 1,
+               I2C_ADDR_TEA6300   >> 1,
+               I2C_ADDR_TEA6420   >> 1,
+               I2C_ADDR_TDA9840   >> 1,
+               I2C_ADDR_TDA985x_L >> 1,
+               I2C_ADDR_TDA985x_H >> 1,
+               I2C_ADDR_TDA9874   >> 1,
+               I2C_ADDR_PIC16C54  >> 1,
+               I2C_CLIENT_END
+       };
        int addr=ADDR_UNSET;
 
        btv->tuner_type = UNSET;
@@ -3519,6 +3536,12 @@ void __devinit bttv_init_card2(struct bt
                printk(KERN_INFO "bttv%d: tuner type=%d\n", btv->c.nr,
                       btv->tuner_type);
 
+       if (autoload != UNSET) {
+               printk(KERN_WARNING "bttv%d: the autoload option is 
obsolete.\n", btv->c.nr);
+               printk(KERN_WARNING "bttv%d: use option msp3400, tda7432 or 
tvaudio to\n", btv->c.nr);
+               printk(KERN_WARNING "bttv%d: override which audio module should 
be used.\n", btv->c.nr);
+       }
+
        if (UNSET == btv->tuner_type)
                btv->tuner_type = TUNER_ABSENT;
 
@@ -3526,8 +3549,13 @@ void __devinit bttv_init_card2(struct bt
                struct tuner_setup tun_setup;
 
                /* Load tuner module before issuing tuner config call! */
-               if (autoload)
-                       request_module("tuner");
+               if (bttv_tvcards[btv->c.type].has_radio)
+                       v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+                               "tuner", "tuner", 
v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+               v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner",
+                               "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+               v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner",
+                               "tuner", 
v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
 
                tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
                tun_setup.type = btv->tuner_type;
@@ -3536,7 +3564,7 @@ void __devinit bttv_init_card2(struct bt
                if (bttv_tvcards[btv->c.type].has_radio)
                        tun_setup.mode_mask |= T_RADIO;
 
-               bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
+               bttv_call_all(btv, tuner, s_type_addr, &tun_setup);
        }
 
        if (btv->tda9887_conf) {
@@ -3545,7 +3573,7 @@ void __devinit bttv_init_card2(struct bt
                tda9887_cfg.tuner = TUNER_TDA9887;
                tda9887_cfg.priv = &btv->tda9887_conf;
 
-               bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg);
+               bttv_call_all(btv, tuner, s_config, &tda9887_cfg);
        }
 
        btv->dig = bttv_tvcards[btv->c.type].has_dig_in ?
@@ -3568,31 +3596,127 @@ void __devinit bttv_init_card2(struct bt
        if (bttv_tvcards[btv->c.type].audio_mode_gpio)
                btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio;
 
-       if (!autoload)
-               return;
-
        if (btv->tuner_type == TUNER_ABSENT)
                return;  /* no tuner or related drivers to load */
 
+       if (btv->has_saa6588 || saa6588[btv->c.nr]) {
+               /* Probe for RDS receiver chip */
+               static const unsigned short addrs[] = {
+                       0x20 >> 1,
+                       0x22 >> 1,
+                       I2C_CLIENT_END
+               };
+               struct v4l2_subdev *sd;
+
+               sd = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+                               "saa6588", "saa6588", addrs);
+               btv->has_saa6588 = (sd != NULL);
+       }
+
        /* try to detect audio/fader chips */
-       if (!bttv_tvcards[btv->c.type].no_msp34xx &&
-           bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx") >=0)
-               request_module("msp3400");
-
-       if (bttv_tvcards[btv->c.type].msp34xx_alt &&
-           bttv_I2CRead(btv, I2C_ADDR_MSP3400_ALT, "MSP34xx (alternate 
address)") >=0)
-               request_module("msp3400");
-
-       if (!bttv_tvcards[btv->c.type].no_tda9875 &&
-           bttv_I2CRead(btv, I2C_ADDR_TDA9875, "TDA9875") >=0)
-               request_module("tda9875");
-
-       if (!bttv_tvcards[btv->c.type].no_tda7432 &&
-           bttv_I2CRead(btv, I2C_ADDR_TDA7432, "TDA7432") >=0)
-               request_module("tda7432");
-
-       if (bttv_tvcards[btv->c.type].needs_tvaudio)
-               request_module("tvaudio");
+
+       /* First check if the user specified the audio chip via a module
+          option. */
+
+       switch (audiodev[btv->c.nr]) {
+       case -1:
+               return; /* do not load any audio module */
+
+       case 0: /* autodetect */
+               break;
+
+       case 1: {
+               /* The user specified that we should probe for msp3400 */
+               static const unsigned short addrs[] = {
+                       I2C_ADDR_MSP3400 >> 1,
+                       I2C_ADDR_MSP3400_ALT >> 1,
+                       I2C_CLIENT_END
+               };
+
+               btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+                               "msp3400", "msp3400", addrs);
+               if (btv->sd_msp34xx)
+                       return;
+               goto no_audio;
+       }
+
+       case 2: {
+               /* The user specified that we should probe for tda7432 */
+               static const unsigned short addrs[] = {
+                       I2C_ADDR_TDA7432 >> 1,
+                       I2C_CLIENT_END
+               };
+
+               if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+                               "tda7432", "tda7432", addrs))
+                       return;
+               goto no_audio;
+       }
+
+       case 3: {
+               /* The user specified that we should probe for tvaudio */
+               btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+                               "tvaudio", "tvaudio", tvaudio_addrs);
+               if (btv->sd_tvaudio)
+                       return;
+               goto no_audio;
+       }
+
+       default:
+               printk(KERN_WARNING "bttv%d: unknown audiodev value!\n",
+                       btv->c.nr);
+               return;
+       }
+
+       /* There were no overrides, so now we try to discover this through the
+          card definition */
+
+       /* probe for msp3400 first: this driver can detect whether or not
+          it really is a msp3400, so it will return NULL when the device
+          found is really something else (e.g. a tea6300). */
+       if (!bttv_tvcards[btv->c.type].no_msp34xx) {
+               static const unsigned short addrs[] = {
+                       I2C_ADDR_MSP3400 >> 1,
+                       I2C_CLIENT_END
+               };
+
+               btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+                               "msp3400", "msp3400", addrs);
+       } else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
+               static const unsigned short addrs[] = {
+                       I2C_ADDR_MSP3400_ALT >> 1,
+                       I2C_CLIENT_END
+               };
+
+               btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+                               "msp3400", "msp3400", addrs);
+       }
+
+       /* If we found a msp34xx, then we're done. */
+       if (btv->sd_msp34xx)
+               return;
+
+       /* it might also be a tda7432. */
+       if (!bttv_tvcards[btv->c.type].no_tda7432) {
+               static const unsigned short addrs[] = {
+                       I2C_ADDR_TDA7432 >> 1,
+                       I2C_CLIENT_END
+               };
+
+               if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+                               "tda7432", "tda7432", addrs))
+                       return;
+       }
+
+       /* Now see if we can find one of the tvaudio devices. */
+       btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+                       "tvaudio", "tvaudio", tvaudio_addrs);
+       if (btv->sd_tvaudio)
+               return;
+
+no_audio:
+       printk(KERN_WARNING "bttv%d: audio absent, no audio device found!\n",
+                       btv->c.nr);
 }
 
 
@@ -3664,6 +3788,7 @@ static int terratec_active_radio_upgrade
                printk("bttv%d: Terratec Active Radio Upgrade found.\n",
                       btv->c.nr);
                btv->has_radio    = 1;
+               btv->has_saa6588  = 1;
                btv->has_matchbox = 1;
        } else {
                btv->has_radio    = 0;
diff -r 055d56e8f2d1 -r df7a51ffa2ba 
linux/drivers/media/video/bt8xx/bttv-driver.c
--- a/linux/drivers/media/video/bt8xx/bttv-driver.c     Sun Mar 29 05:51:18 
2009 -0300
+++ b/linux/drivers/media/video/bt8xx/bttv-driver.c     Sun Mar 29 05:58:58 
2009 -0300
@@ -1181,7 +1181,6 @@ audio_mux(struct bttv *btv, int input, i
 {
        int gpio_val, signal;
        struct v4l2_control ctrl;
-       struct i2c_client *c;
 
        gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
                   bttv_tvcards[btv->c.type].gpiomask);
@@ -1220,9 +1219,8 @@ audio_mux(struct bttv *btv, int input, i
 
        ctrl.id = V4L2_CID_AUDIO_MUTE;
        ctrl.value = btv->mute;
-       bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl);
-       c = btv->i2c_msp34xx_client;
-       if (c) {
+       bttv_call_all(btv, core, s_ctrl, &ctrl);
+       if (btv->sd_msp34xx) {
                struct v4l2_routing route;
 
                /* Note: the inputs tuner/radio/extern/intern are translated
@@ -1261,15 +1259,14 @@ audio_mux(struct bttv *btv, int input, i
                        break;
                }
                route.output = MSP_OUTPUT_DEFAULT;
-               c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
-       }
-       c = btv->i2c_tvaudio_client;
-       if (c) {
+               v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing, &route);
+       }
+       if (btv->sd_tvaudio) {
                struct v4l2_routing route;
 
                route.input = input;
                route.output = 0;
-               c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+               v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, &route);
        }
        return 0;
 }
@@ -1360,7 +1357,7 @@ set_tvnorm(struct bttv *btv, unsigned in
 #endif
        }
        id = tvnorm->v4l2_id;
-       bttv_call_i2c_clients(btv, VIDIOC_S_STD, &id);
+       bttv_call_all(btv, tuner, s_std, id);
 
        return 0;
 }
@@ -1504,7 +1501,7 @@ static int bttv_g_ctrl(struct file *file
        case V4L2_CID_AUDIO_BALANCE:
        case V4L2_CID_AUDIO_BASS:
        case V4L2_CID_AUDIO_TREBLE:
-               bttv_call_i2c_clients(btv, VIDIOC_G_CTRL, c);
+               bttv_call_all(btv, core, g_ctrl, c);
                break;
 
        case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -1578,12 +1575,12 @@ static int bttv_s_ctrl(struct file *file
                if (btv->volume_gpio)
                        btv->volume_gpio(btv, c->value);
 
-               bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c);
+               bttv_call_all(btv, core, s_ctrl, c);
                break;
        case V4L2_CID_AUDIO_BALANCE:
        case V4L2_CID_AUDIO_BASS:
        case V4L2_CID_AUDIO_TREBLE:
-               bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c);
+               bttv_call_all(btv, core, s_ctrl, c);
                break;
 
        case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -2001,7 +1998,7 @@ static int bttv_s_tuner(struct file *fil
                return -EINVAL;
 
        mutex_lock(&btv->lock);
-       bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t);
+       bttv_call_all(btv, tuner, s_tuner, t);
 
        if (btv->audio_mode_gpio)
                btv->audio_mode_gpio(btv, t, 1);
@@ -2046,7 +2043,7 @@ static int bttv_s_frequency(struct file 
                return -EINVAL;
        mutex_lock(&btv->lock);
        btv->freq = f->frequency;
-       bttv_call_i2c_clients(btv, VIDIOC_S_FREQUENCY, f);
+       bttv_call_all(btv, tuner, s_frequency, f);
        if (btv->has_matchbox && btv->radio_user)
                tea5757_set_freq(btv, btv->freq);
        mutex_unlock(&btv->lock);
@@ -2060,7 +2057,7 @@ static int bttv_log_status(struct file *
 
        printk(KERN_INFO "bttv%d: ========  START STATUS CARD #%d  ========\n",
                        btv->c.nr, btv->c.nr);
-       bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL);
+       bttv_call_all(btv, core, log_status);
        printk(KERN_INFO "bttv%d: ========  END STATUS CARD   #%d  ========\n",
                        btv->c.nr, btv->c.nr);
        return 0;
@@ -2974,7 +2971,7 @@ static int bttv_g_tuner(struct file *fil
 
        mutex_lock(&btv->lock);
        t->rxsubchans = V4L2_TUNER_SUB_MONO;
-       bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+       bttv_call_all(btv, tuner, g_tuner, t);
        strcpy(t->name, "Television");
        t->capability = V4L2_TUNER_CAP_NORM;
        t->type       = V4L2_TUNER_ANALOG_TV;
@@ -3465,7 +3462,7 @@ static int radio_open(struct file *file)
 
        btv->radio_user++;
 
-       bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
+       bttv_call_all(btv, tuner, s_radio);
        audio_input(btv,TVAUDIO_INPUT_RADIO);
 
        mutex_unlock(&btv->lock);
@@ -3485,7 +3482,7 @@ static int radio_release(struct file *fi
 
        btv->radio_user--;
 
-       bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
+       bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd);
 
        return 0;
 }
@@ -3518,7 +3515,7 @@ static int radio_g_tuner(struct file *fi
        strcpy(t->name, "Radio");
        t->type = V4L2_TUNER_RADIO;
 
-       bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+       bttv_call_all(btv, tuner, g_tuner, t);
 
        if (btv->audio_mode_gpio)
                btv->audio_mode_gpio(btv, t, 0);
@@ -3560,7 +3557,7 @@ static int radio_s_tuner(struct file *fi
        if (0 != t->index)
                return -EINVAL;
 
-       bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+       bttv_call_all(btv, tuner, g_tuner, t);
        return 0;
 }
 
@@ -3621,7 +3618,7 @@ static ssize_t radio_read(struct file *f
        cmd.instance = file;
        cmd.result = -ENODEV;
 
-       bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd);
+       bttv_call_all(btv, core, ioctl, RDS_CMD_READ, &cmd);
 
        return cmd.result;
 }
@@ -3634,7 +3631,7 @@ static unsigned int radio_poll(struct fi
        cmd.instance = file;
        cmd.event_list = wait;
        cmd.result = -ENODEV;
-       bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd);
+       bttv_call_all(btv, core, ioctl, RDS_CMD_POLL, &cmd);
 
        return cmd.result;
 }
diff -r 055d56e8f2d1 -r df7a51ffa2ba linux/drivers/media/video/bt8xx/bttv-i2c.c
--- a/linux/drivers/media/video/bt8xx/bttv-i2c.c        Sun Mar 29 05:51:18 
2009 -0300
+++ b/linux/drivers/media/video/bt8xx/bttv-i2c.c        Sun Mar 29 05:58:58 
2009 -0300
@@ -35,8 +35,6 @@
 #include <media/v4l2-common.h>
 #include <linux/jiffies.h>
 #include <asm/io.h>
-
-static int attach_inform(struct i2c_client *client);
 
 static int i2c_debug;
 static int i2c_hw;
@@ -269,51 +267,6 @@ static const struct i2c_algorithm bttv_a
 /* ----------------------------------------------------------------------- */
 /* I2C functions - common stuff                                            */
 
-static int attach_inform(struct i2c_client *client)
-{
-       struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter);
-       struct bttv *btv = to_bttv(v4l2_dev);
-       int addr=ADDR_UNSET;
-
-
-       if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
-               addr = bttv_tvcards[btv->c.type].tuner_addr;
-
-
-       if (bttv_debug)
-               printk(KERN_DEBUG "bttv%d: %s i2c attach 
[addr=0x%x,client=%s]\n",
-                       btv->c.nr, client->driver->driver.name, client->addr,
-                       client->name);
-       if (!client->driver->command)
-               return 0;
-
-       if (client->driver->id == I2C_DRIVERID_MSP3400)
-               btv->i2c_msp34xx_client = client;
-       if (client->driver->id == I2C_DRIVERID_TVAUDIO)
-               btv->i2c_tvaudio_client = client;
-       if (btv->tuner_type != TUNER_ABSENT) {
-               struct tuner_setup tun_setup;
-
-               if (addr == ADDR_UNSET || addr == client->addr) {
-                       tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | 
T_RADIO;
-                       tun_setup.type = btv->tuner_type;
-                       tun_setup.addr = addr;
-                       bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, 
&tun_setup);
-               }
-
-       }
-
-       return 0;
-}
-
-void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
-{
-       if (0 != btv->i2c_rc)
-               return;
-       i2c_clients_command(&btv->c.i2c_adap, cmd, arg);
-}
-
-
 /* read I2C */
 int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
 {
@@ -424,8 +377,9 @@ int __devinit init_bttv_i2c(struct bttv 
                btv->c.i2c_adap.algo_data = &btv->i2c_algo;
        }
        btv->c.i2c_adap.owner = THIS_MODULE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
        btv->c.i2c_adap.class = I2C_CLASS_TV_ANALOG;
-       btv->c.i2c_adap.client_register = attach_inform;
+#endif
 
        btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
        snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
@@ -435,10 +389,12 @@ int __devinit init_bttv_i2c(struct bttv 
        i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev);
        btv->i2c_client.adapter = &btv->c.i2c_adap;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
        if (bttv_tvcards[btv->c.type].no_video)
                btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG;
        if (bttv_tvcards[btv->c.type].has_dvb)
                btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
+#endif
 
        if (btv->use_i2c_hw) {
                btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
diff -r 055d56e8f2d1 -r df7a51ffa2ba linux/drivers/media/video/bt8xx/bttv.h
--- a/linux/drivers/media/video/bt8xx/bttv.h    Sun Mar 29 05:51:18 2009 -0300
+++ b/linux/drivers/media/video/bt8xx/bttv.h    Sun Mar 29 05:58:58 2009 -0300
@@ -241,6 +241,9 @@ struct tvcard {
        unsigned int no_tda7432:1;
        unsigned int needs_tvaudio:1;
        unsigned int msp34xx_alt:1;
+       /* Note: currently no card definition needs to mark the presence
+          of a RDS saa6588 chip. If this is ever needed, then add a new
+          'has_saa6588' bit here. */
 
        unsigned int no_video:1; /* video pci function is unused */
        unsigned int has_dvb:1;
@@ -358,7 +361,9 @@ void bttv_gpio_bits(struct bttv_core *co
 /* ---------------------------------------------------------- */
 /* i2c                                                        */
 
-extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void 
*arg);
+#define bttv_call_all(btv, o, f, args...) \
+       v4l2_device_call_all(&btv->c.v4l2_dev, 0, o, f, ##args)
+
 extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
 extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char 
b1,
                         unsigned char b2, int both);
diff -r 055d56e8f2d1 -r df7a51ffa2ba linux/drivers/media/video/bt8xx/bttvp.h
--- a/linux/drivers/media/video/bt8xx/bttvp.h   Sun Mar 29 05:51:18 2009 -0300
+++ b/linux/drivers/media/video/bt8xx/bttvp.h   Sun Mar 29 05:58:58 2009 -0300
@@ -331,6 +331,7 @@ struct bttv {
        unsigned int tuner_type;  /* tuner chip type */
        unsigned int tda9887_conf;
        unsigned int svhs, dig;
+       unsigned int has_saa6588:1;
        struct bttv_pll_info pll;
        int triton1;
        int gpioirq;
@@ -354,8 +355,8 @@ struct bttv {
        int                        i2c_state, i2c_rc;
        int                        i2c_done;
        wait_queue_head_t          i2c_queue;
-       struct i2c_client         *i2c_msp34xx_client;
-       struct i2c_client         *i2c_tvaudio_client;
+       struct v4l2_subdev        *sd_msp34xx;
+       struct v4l2_subdev        *sd_tvaudio;
 
        /* video4linux (1) */
        struct video_device *video_dev;
diff -r 055d56e8f2d1 -r df7a51ffa2ba linux/drivers/media/video/tvaudio.c
--- a/linux/drivers/media/video/tvaudio.c       Sun Mar 29 05:51:18 2009 -0300
+++ b/linux/drivers/media/video/tvaudio.c       Sun Mar 29 05:58:58 2009 -0300
@@ -1055,6 +1055,116 @@ static int tda9874a_initialize(struct CH
        return 0;
 }
 
+/* ---------------------------------------------------------------------- */
+/* audio chip description - defines+functions for tda9875                 */
+/* The TDA9875 is made by Philips Semiconductor
+ * http://www.semiconductors.philips.com
+ * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
+ *
+ */
+
+/* subaddresses for TDA9875 */
+#define TDA9875_MUT         0x12  /*General mute  (value --> 0b11001100*/
+#define TDA9875_CFG         0x01  /* Config register (value --> 0b00000000 */
+#define TDA9875_DACOS       0x13  /*DAC i/o select (ADC) 0b0000100*/
+#define TDA9875_LOSR        0x16  /*Line output select regirter 0b0100 0001*/
+
+#define TDA9875_CH1V        0x0c  /*Channel 1 volume (mute)*/
+#define TDA9875_CH2V        0x0d  /*Channel 2 volume (mute)*/
+#define TDA9875_SC1         0x14  /*SCART 1 in (mono)*/
+#define TDA9875_SC2         0x15  /*SCART 2 in (mono)*/
+
+#define TDA9875_ADCIS       0x17  /*ADC input select (mono) 0b0110 000*/
+#define TDA9875_AER         0x19  /*Audio effect (AVL+Pseudo) 0b0000 0110*/
+#define TDA9875_MCS         0x18  /*Main channel select (DAC) 0b0000100*/
+#define TDA9875_MVL         0x1a  /* Main volume gauche */
+#define TDA9875_MVR         0x1b  /* Main volume droite */
+#define TDA9875_MBA         0x1d  /* Main Basse */
+#define TDA9875_MTR         0x1e  /* Main treble */
+#define TDA9875_ACS         0x1f  /* Auxilary channel select (FM) 0b0000000*/
+#define TDA9875_AVL         0x20  /* Auxilary volume gauche */
+#define TDA9875_AVR         0x21  /* Auxilary volume droite */
+#define TDA9875_ABA         0x22  /* Auxilary Basse */
+#define TDA9875_ATR         0x23  /* Auxilary treble */
+
+#define TDA9875_MSR         0x02  /* Monitor select register */
+#define TDA9875_C1MSB       0x03  /* Carrier 1 (FM) frequency register MSB */
+#define TDA9875_C1MIB       0x04  /* Carrier 1 (FM) frequency register (16-8]b 
*/
+#define TDA9875_C1LSB       0x05  /* Carrier 1 (FM) frequency register LSB */
+#define TDA9875_C2MSB       0x06  /* Carrier 2 (nicam) frequency register MSB 
*/
+#define TDA9875_C2MIB       0x07  /* Carrier 2 (nicam) frequency register 
(16-8]b */
+#define TDA9875_C2LSB       0x08  /* Carrier 2 (nicam) frequency register LSB 
*/
+#define TDA9875_DCR         0x09  /* Demodulateur configuration regirter*/
+#define TDA9875_DEEM        0x0a  /* FM de-emphasis regirter*/
+#define TDA9875_FMAT        0x0b  /* FM Matrix regirter*/
+
+/* values */
+#define TDA9875_MUTE_ON            0xff /* general mute */
+#define TDA9875_MUTE_OFF    0xcc /* general no mute */
+
+static int tda9875_initialize(struct CHIPSTATE *chip)
+{
+       chip_write(chip, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/
+       chip_write(chip, TDA9875_MSR, 0x03);    /* Monitor 0b00000XXX*/
+       chip_write(chip, TDA9875_C1MSB, 0x00);  /*Car1(FM) MSB XMHz*/
+       chip_write(chip, TDA9875_C1MIB, 0x00);  /*Car1(FM) MIB XMHz*/
+       chip_write(chip, TDA9875_C1LSB, 0x00);  /*Car1(FM) LSB XMHz*/
+       chip_write(chip, TDA9875_C2MSB, 0x00);  /*Car2(NICAM) MSB XMHz*/
+       chip_write(chip, TDA9875_C2MIB, 0x00);  /*Car2(NICAM) MIB XMHz*/
+       chip_write(chip, TDA9875_C2LSB, 0x00);  /*Car2(NICAM) LSB XMHz*/
+       chip_write(chip, TDA9875_DCR, 0x00);    /*Demod config 0x00*/
+       chip_write(chip, TDA9875_DEEM, 0x44);   /*DE-Emph 0b0100 0100*/
+       chip_write(chip, TDA9875_FMAT, 0x00);   /*FM Matrix reg 0x00*/
+       chip_write(chip, TDA9875_SC1, 0x00);    /* SCART 1 (SC1)*/
+       chip_write(chip, TDA9875_SC2, 0x01);    /* SCART 2 (sc2)*/
+
+       chip_write(chip, TDA9875_CH1V, 0x10);  /* Channel volume 1 mute*/
+       chip_write(chip, TDA9875_CH2V, 0x10);  /* Channel volume 2 mute */
+       chip_write(chip, TDA9875_DACOS, 0x02); /* sig DAC i/o(in:nicam)*/
+       chip_write(chip, TDA9875_ADCIS, 0x6f); /* sig ADC input(in:mono)*/
+       chip_write(chip, TDA9875_LOSR, 0x00);  /* line out (in:mono)*/
+       chip_write(chip, TDA9875_AER, 0x00);   /*06 Effect (AVL+PSEUDO) */
+       chip_write(chip, TDA9875_MCS, 0x44);   /* Main ch select (DAC) */
+       chip_write(chip, TDA9875_MVL, 0x03);   /* Vol Main left 10dB */
+       chip_write(chip, TDA9875_MVR, 0x03);   /* Vol Main right 10dB*/
+       chip_write(chip, TDA9875_MBA, 0x00);   /* Main Bass Main 0dB*/
+       chip_write(chip, TDA9875_MTR, 0x00);   /* Main Treble Main 0dB*/
+       chip_write(chip, TDA9875_ACS, 0x44);   /* Aux chan select (dac)*/
+       chip_write(chip, TDA9875_AVL, 0x00);   /* Vol Aux left 0dB*/
+       chip_write(chip, TDA9875_AVR, 0x00);   /* Vol Aux right 0dB*/
+       chip_write(chip, TDA9875_ABA, 0x00);   /* Aux Bass Main 0dB*/
+       chip_write(chip, TDA9875_ATR, 0x00);   /* Aux Aigus Main 0dB*/
+
+       chip_write(chip, TDA9875_MUT, 0xcc);   /* General mute  */
+       return 0;
+}
+
+static int tda9875_volume(int val) { return (unsigned char)(val / 602 - 84); }
+static int tda9875_bass(int val) { return (unsigned char)(max(-12, val / 2115 
- 15)); }
+static int tda9875_treble(int val) { return (unsigned char)(val / 2622 - 12); }
+
+/* ----------------------------------------------------------------------- */
+
+
+/* *********************** *
+ * i2c interface functions *
+ * *********************** */
+
+static int tda9875_checkit(struct CHIPSTATE *chip)
+{
+       struct v4l2_subdev *sd = &chip->sd;
+       int dic, rev;
+
+       dic = chip_read2(chip, 254);
+       rev = chip_read2(chip, 255);
+
+       if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */
+               v4l2_info(sd, "found tda9875%s rev. %d.\n",
+                       dic == 0 ? "" : "A", rev);
+               return 1;
+       }
+       return 0;
+}
 
 /* ---------------------------------------------------------------------- */
 /* audio chip descriptions - defines+functions for tea6420                */
@@ -1288,6 +1398,7 @@ static int tda9855  = 1;
 static int tda9855  = 1;
 static int tda9873  = 1;
 static int tda9874a = 1;
+static int tda9875  = 1;
 static int tea6300;    /* default 0 - address clash with msp34xx */
 static int tea6320;    /* default 0 - address clash with msp34xx */
 static int tea6420  = 1;
@@ -1300,6 +1411,7 @@ module_param(tda9855, int, 0444);
 module_param(tda9855, int, 0444);
 module_param(tda9873, int, 0444);
 module_param(tda9874a, int, 0444);
+module_param(tda9875, int, 0444);
 module_param(tea6300, int, 0444);
 module_param(tea6320, int, 0444);
 module_param(tea6420, int, 0444);
@@ -1355,6 +1467,26 @@ static struct CHIPDESC chiplist[] = {
                .checkit    = tda9874a_checkit,
                .getmode    = tda9874a_getmode,
                .setmode    = tda9874a_setmode,
+       },
+       {
+               .name       = "tda9875",
+               .insmodopt  = &tda9875,
+               .addr_lo    = I2C_ADDR_TDA9875 >> 1,
+               .addr_hi    = I2C_ADDR_TDA9875 >> 1,
+               .flags      = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
+
+               /* callbacks */
+               .initialize = tda9875_initialize,
+               .checkit    = tda9875_checkit,
+               .volfunc    = tda9875_volume,
+               .bassfunc   = tda9875_bass,
+               .treblefunc = tda9875_treble,
+               .leftreg    = TDA9875_MVL,
+               .rightreg   = TDA9875_MVR,
+               .bassreg    = TDA9875_MBA,
+               .treblereg  = TDA9875_MTR,
+               .leftinit   = 58880,
+               .rightinit  = 58880,
        },
        {
                .name       = "tda9850",
@@ -1519,6 +1651,8 @@ static int tvaudio_g_ctrl(struct v4l2_su
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
+               if (!(desc->flags & CHIP_HAS_INPUTSEL))
+                       break;
                ctrl->value=chip->muted;
                return 0;
        case V4L2_CID_AUDIO_VOLUME:
@@ -1560,6 +1694,9 @@ static int tvaudio_s_ctrl(struct v4l2_su
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
+               if (!(desc->flags & CHIP_HAS_INPUTSEL))
+                       break;
+
                if (ctrl->value < 0 || ctrl->value >= 2)
                        return -ERANGE;
                chip->muted = ctrl->value;
@@ -1644,7 +1781,9 @@ static int tvaudio_queryctrl(struct v4l2
 
        switch (qc->id) {
        case V4L2_CID_AUDIO_MUTE:
-               return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+               if (desc->flags & CHIP_HAS_INPUTSEL)
+                       return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+               break;
        case V4L2_CID_AUDIO_VOLUME:
                if (desc->flags & CHIP_HAS_VOLUME)
                        return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 
58880);
@@ -1669,7 +1808,9 @@ static int tvaudio_s_routing(struct v4l2
        struct CHIPSTATE *chip = to_state(sd);
        struct CHIPDESC *desc = chip->desc;
 
-       if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4)
+       if (!(desc->flags & CHIP_HAS_INPUTSEL))
+               return 0;
+       if (rt->input >= 4)
                return -EINVAL;
        /* There are four inputs: tuner, radio, extern and intern. */
        chip->input = rt->input;
@@ -1686,8 +1827,11 @@ static int tvaudio_s_tuner(struct v4l2_s
        struct CHIPDESC *desc = chip->desc;
        int mode = 0;
 
+       if (!desc->setmode)
+               return 0;
        if (chip->radio)
                return 0;
+
        switch (vt->audmode) {
        case V4L2_TUNER_MODE_MONO:
        case V4L2_TUNER_MODE_STEREO:
@@ -1703,7 +1847,7 @@ static int tvaudio_s_tuner(struct v4l2_s
        }
        chip->audmode = vt->audmode;
 
-       if (desc->setmode && mode) {
+       if (mode) {
                chip->watch_stereo = 0;
                /* del_timer(&chip->wt); */
                chip->mode = mode;
@@ -1718,15 +1862,17 @@ static int tvaudio_g_tuner(struct v4l2_s
        struct CHIPDESC *desc = chip->desc;
        int mode = V4L2_TUNER_MODE_MONO;
 
+       if (!desc->getmode)
+               return 0;
        if (chip->radio)
                return 0;
+
        vt->audmode = chip->audmode;
        vt->rxsubchans = 0;
        vt->capability = V4L2_TUNER_CAP_STEREO |
                V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
 
-       if (desc->getmode)
-               mode = desc->getmode(chip);
+       mode = desc->getmode(chip);
 
        if (mode & V4L2_TUNER_MODE_MONO)
                vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
@@ -1916,6 +2062,7 @@ static int tvaudio_probe(struct i2c_clie
        }
 
        chip->thread = NULL;
+       init_timer(&chip->wt);
        if (desc->flags & CHIP_NEED_CHECKMODE) {
                if (!desc->getmode || !desc->setmode) {
                        /* This shouldn't be happen. Warn user, but keep working
@@ -1925,7 +2072,6 @@ static int tvaudio_probe(struct i2c_clie
                        return 0;
                }
                /* start async thread */
-               init_timer(&chip->wt);
                chip->wt.function = chip_thread_wake;
                chip->wt.data     = (unsigned long)chip;
                chip->thread = kthread_run(chip_thread, chip, client->name);


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/df7a51ffa2baddae044a318c928f960488b9ec38

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to