From patchwork Mon Mar 16 11:09:44 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 12390 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n2GBB1nj022521 for ; Mon, 16 Mar 2009 11:11:01 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757655AbZCPLKR (ORCPT ); Mon, 16 Mar 2009 07:10:17 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754612AbZCPLKR (ORCPT ); Mon, 16 Mar 2009 07:10:17 -0400 Received: from bombadil.infradead.org ([18.85.46.34]:60361 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757655AbZCPLKO (ORCPT ); Mon, 16 Mar 2009 07:10:14 -0400 Received: from 200.220.139.66.nipcable.com ([200.220.139.66] helo=gaivota.chehab.org) by bombadil.infradead.org with esmtpsa (Exim 4.69 #1 (Red Hat Linux)) id 1LjAhu-0000nL-GS; Mon, 16 Mar 2009 11:10:11 +0000 Date: Mon, 16 Mar 2009 08:09:44 -0300 From: Mauro Carvalho Chehab To: "Hans Verkuil" Cc: "Trent Piepho" , linux-media@vger.kernel.org Subject: Re: REVIEW: bttv conversion to v4l2_subdev Message-ID: <20090316080944.17115a46@gaivota.chehab.org> In-Reply-To: <37140.62.70.2.252.1237200252.squirrel@webmail.xs4all.nl> References: <37140.62.70.2.252.1237200252.squirrel@webmail.xs4all.nl> X-Mailer: Claws Mail 3.7.0 (GTK+ 2.14.7; i386-redhat-linux-gnu) Mime-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org On Mon, 16 Mar 2009 11:44:12 +0100 (CET) "Hans Verkuil" wrote: > > > Hi Hans, > > > > On Sun, 15 Mar 2009 19:53:06 +0100 > > Hans Verkuil wrote: > > > >> On Sunday 15 March 2009 18:28:42 Trent Piepho wrote: > >> > On Sun, 15 Mar 2009, Hans Verkuil wrote: > >> > > On Sunday 15 March 2009 17:04:43 Trent Piepho wrote: > >> > > > On Sun, 15 Mar 2009, Hans Verkuil wrote: > >> > > > > Hi Mauro, > >> > > > > > >> > > > > Can you review my ~hverkuil/v4l-dvb-bttv2 tree? Except for that small issue with tvaudio that I've already pointed, I've reviewed all but the last one. Since the last one is the one that do most of the job, and, in order to help me and others to review and comment IMO, it is better to send the it through the ML as a patch. This way, people can reply on it, if needed. So, here it is: --- # HG changeset patch # User Hans Verkuil # Date 1237118835 -3600 # Node ID 2b8fedc4d5ab72728ffc9e3f105758bb506eb2db # Parent f97862ee5dcf20923902fd7795200a59b3be4535 bttv: convert to v4l2_subdev. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- a/linux/drivers/media/video/bt8xx/bttv-cards.c Sun Mar 15 10:53:32 2009 +0100 +++ b/linux/drivers/media/video/bt8xx/bttv-cards.c Sun Mar 15 13:07:15 2009 +0100 @@ -97,12 +97,8 @@ 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 tvaudio[BTTV_MAX] = { [0 ... (BTTV_MAX - 1)] = UNSET }; 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 gpiomask = UNSET; static unsigned int audioall = UNSET; static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET }; @@ -114,13 +110,13 @@ module_param(latency, int, 0444); module_param(latency, int, 0444); module_param(gpiomask, int, 0444); module_param(audioall, int, 0444); -module_param(autoload, int, 0444); module_param_array(card, int, NULL, 0444); module_param_array(pll, int, NULL, 0444); module_param_array(tuner, int, NULL, 0444); module_param_array(svhs, int, NULL, 0444); module_param_array(remote, int, NULL, 0444); +module_param_array(tvaudio, int, NULL, 0444); module_param_array(audiomux, int, NULL, 0444); MODULE_PARM_DESC(triton1,"set ETBF pci config bit " @@ -131,7 +127,8 @@ 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(tvaudio, "specify whether tvaudio should be loaded (1) or not (0)," + " default is autodetect"); MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" " [some VIA/SIS chipsets are known to have problem with overlay]"); @@ -3333,8 +3330,10 @@ void __devinit bttv_init_card2(struct bt void __devinit bttv_init_card2(struct bttv *btv) { int addr=ADDR_UNSET; + int load_tvaudio = tvaudio[btv->c.nr]; btv->tuner_type = UNSET; + btv->has_saa6588 = bttv_tvcards[btv->c.type].has_saa6588; if (BTTV_BOARD_UNKNOWN == btv->c.type) { bttv_readee(btv,eeprom_data,0xa0); @@ -3502,8 +3501,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; @@ -3512,7 +3516,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) { @@ -3521,7 +3525,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 ? @@ -3544,31 +3548,94 @@ 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) { + /* Probe for RDS receiver chip */ + static const unsigned short addrs[] = { + 0x20 >> 1, + 0x22 >> 1, + I2C_CLIENT_END + }; + + btv->sd_rds = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, + "saa6588", "saa6588", addrs); + } + /* 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"); + + /* 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].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); + } else 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); + } + + /* If we found a msp34xx, then we're done. */ + if (btv->sd_msp34xx) + return; + + if (load_tvaudio != UNSET) { + printk(KERN_INFO "bttv%d: if you need to set the tvaudio module option to %d, then the\n", + btv->c.nr, load_tvaudio); + printk(KERN_INFO "bttv%d: definition for card type %d needs to be updated.\n", + btv->c.nr, btv->c.type); + printk(KERN_INFO "bttv%d: please report this to the bttv maintainer.\n", btv->c.nr); + } else { + /* tda9875 is now also handled by tvaudio. It used to be + handled by the tda9875 module, but that causes problems + in detecting whether you have a tda9874 or tda9875. It is + better to use tvaudio for both. */ + load_tvaudio = bttv_tvcards[btv->c.type].needs_tvaudio || + !bttv_tvcards[btv->c.type].no_tda9875; + } + + /* Now see if we can find one of the tvaudio devices. */ + if (load_tvaudio) { + static const unsigned short 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 + }; + + btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, + "tvaudio", "tvaudio", addrs); + /* If we found a device supported by tvaudio, then we're done + as well. */ + if (btv->sd_tvaudio) + return; + } + /* Last possibility: it might be a tda7432. */ + if (!bttv_tvcards[btv->c.type].no_tda7432) { + static const unsigned short addrs[] = { + I2C_ADDR_TDA7432 >> 1, + I2C_CLIENT_END + }; + + v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tda7432", + "tda7432", addrs); + } } @@ -3640,6 +3707,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; --- a/linux/drivers/media/video/bt8xx/bttv-driver.c Sun Mar 15 10:53:32 2009 +0100 +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c Sun Mar 15 13:07:15 2009 +0100 @@ -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; @@ -2976,7 +2973,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; @@ -3467,7 +3464,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); @@ -3487,7 +3484,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; } @@ -3520,7 +3517,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); @@ -3562,7 +3559,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; } @@ -3623,7 +3620,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; } @@ -3636,7 +3633,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; } --- a/linux/drivers/media/video/bt8xx/bttv-i2c.c Sun Mar 15 10:53:32 2009 +0100 +++ b/linux/drivers/media/video/bt8xx/bttv-i2c.c Sun Mar 15 13:07:15 2009 +0100 @@ -35,8 +35,6 @@ #include #include #include - -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); --- a/linux/drivers/media/video/bt8xx/bttv.h Sun Mar 15 10:53:32 2009 +0100 +++ b/linux/drivers/media/video/bt8xx/bttv.h Sun Mar 15 13:07:15 2009 +0100 @@ -242,6 +242,7 @@ struct tvcard { unsigned int msp34xx_alt:1; unsigned int no_video:1; /* video pci function is unused */ + unsigned int has_saa6588:1; unsigned int has_dvb:1; unsigned int has_remote:1; unsigned int has_radio:1; @@ -357,7 +358,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); --- a/linux/drivers/media/video/bt8xx/bttvp.h Sun Mar 15 10:53:32 2009 +0100 +++ b/linux/drivers/media/video/bt8xx/bttvp.h Sun Mar 15 13:07:15 2009 +0100 @@ -331,6 +331,7 @@ struct bttv { unsigned int tuner_type; /* tuner chip type */ unsigned int tda9887_conf; unsigned int svhs, dig; + int has_saa6588; struct bttv_pll_info pll; int triton1; int gpioirq; @@ -354,8 +355,9 @@ 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; + struct v4l2_subdev *sd_rds; /* video4linux (1) */ struct video_device *video_dev;