/** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
        int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len);
 
+       /** This is to allow setting tuner-specific configs */
+       int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
+
        int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency);
        int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
 
 
        }
 
        if (btv->tda9887_conf) {
-               bttv_call_i2c_clients(btv, TDA9887_SET_CONFIG,
-                                                       &btv->tda9887_conf);
+               struct v4l2_priv_tun_config tda9887_cfg;
+
+               tda9887_cfg.tuner = TUNER_TDA9887;
+               tda9887_cfg.priv = &btv->tda9887_conf;
+
+               bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg);
        }
 
        btv->svhs = bttv_tvcards[btv->c.type].svhs;
 
                }
        }
 
-       if (core->board.tda9887_conf)
-               client->driver->command(client, TDA9887_SET_CONFIG, &core->board.tda9887_conf);
+       if (core->board.tda9887_conf) {
+               struct v4l2_priv_tun_config tda9887_cfg;
+
+               tda9887_cfg.tuner = TUNER_TDA9887;
+               tda9887_cfg.priv  = &core->board.tda9887_conf;
+
+               client->driver->command(client, TUNER_SET_CONFIG, &tda9887_cfg);
+       }
        return 0;
 }
 
 
                case 0x96:
                case 0x94:
                {
+                       struct v4l2_priv_tun_config tda9887_cfg;
+
                        struct tuner_setup tun_setup;
 
                        tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
                        tun_setup.addr = client->addr;
 
                        em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
-                       em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf);
+
+                       tda9887_cfg.tuner = TUNER_TDA9887;
+                       tda9887_cfg.priv = &dev->tda9887_conf;
+                       em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG,
+                                               &tda9887_cfg);
                        break;
                }
                case 0x42:
 
        f.frequency = 9076;     /* FIXME:remove magic number */
        dev->ctl_freq = f.frequency;
        em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
-
-       /* configure tda9887 */
-
-
-/*     em28xx_i2c_call_clients(dev,VIDIOC_S_STD,&dev->tvnorm->id); */
 }
 
 /*
 
 
                printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type);
                if (dev->tuner_type == TUNER_PHILIPS_FMD1216ME_MK3) {
-                       dev->tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | TDA9887_PORT2_ACTIVE;
-                       saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG, &dev->tda9887_conf);
+                       struct v4l2_priv_tun_config tda9887_cfg;
+
+                       tda9887_cfg.tuner = TUNER_TDA9887;
+                       tda9887_cfg.priv  = &dev->tda9887_conf;
+
+                       dev->tda9887_conf = TDA9887_PRESENT      |
+                                           TDA9887_PORT1_ACTIVE |
+                                           TDA9887_PORT2_ACTIVE;
+
+                       saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
+                                                &tda9887_cfg);
                }
 
                tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
 
 
 static int dvb_fini(struct saa7134_dev *dev)
 {
-       static int on  = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
+       /* FIXME: I suspect that this code is bogus, since the entry for
+          Pinnacle 300I DVB-T PAL already defines the proper init to allow
+          the detection of mt2032 (TDA9887_PORT2_INACTIVE)
+        */
+       if (dev->board == SAA7134_BOARD_PINNACLE_300I_DVBT_PAL) {
+               struct v4l2_priv_tun_config tda9887_cfg;
+               static int on  = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
+
+               tda9887_cfg.tuner = TUNER_TDA9887;
+               tda9887_cfg.priv  = &on;
 
-       switch (dev->board) {
-       case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
                /* otherwise we don't detect the tuner on next insmod */
-               saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
-               break;
-       };
+               saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg);
+       }
+
        videobuf_dvb_unregister(&dev->dvb);
        return 0;
 }
 
 {
        struct saa7134_dev *dev = client->adapter->algo_data;
        int tuner = dev->tuner_type;
-       int conf  = dev->tda9887_conf;
        struct tuner_setup tun_setup;
 
        d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
        }
 
        if (tuner != UNSET) {
-
                tun_setup.type = tuner;
                tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
                tun_setup.config = saa7134_boards[dev->board].tuner_config;
 
                        client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
                }
+
+               if (tuner == TUNER_TDA9887) {
+                       struct v4l2_priv_tun_config tda9887_cfg;
+
+                       tda9887_cfg.tuner = TUNER_TDA9887;
+                       tda9887_cfg.priv = &dev->tda9887_conf;
+
+                       client->driver->command(client, TUNER_SET_CONFIG,
+                                               &tda9887_cfg);
+               }
        }
 
-       client->driver->command(client, TDA9887_SET_CONFIG, &conf);
 
        return 0;
 }
 
                restart_overlay = 1;
                break;
        case V4L2_CID_PRIVATE_AUTOMUTE:
+       {
+               struct v4l2_priv_tun_config tda9887_cfg;
+
+               tda9887_cfg.tuner = TUNER_TDA9887;
+               tda9887_cfg.priv = &dev->tda9887_conf;
+
                dev->ctl_automute = c->value;
                if (dev->tda9887_conf) {
                        if (dev->ctl_automute)
                                dev->tda9887_conf |= TDA9887_AUTOMUTE;
                        else
                                dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
-                       saa7134_i2c_call_clients(dev, TDA9887_SET_CONFIG,
-                                                &dev->tda9887_conf);
+
+                       saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
+                                                &tda9887_cfg);
                }
                break;
+       }
        default:
                return -EINVAL;
        }
 
                        return 0;
                }
 #endif
-       case TDA9887_SET_CONFIG:
-               if (t->type == TUNER_TDA9887) {
-                       int *i = arg;
+       case TUNER_SET_CONFIG:
+       {
+               struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
+               struct v4l2_priv_tun_config *cfg = arg;
+
+               if (t->type != cfg->tuner)
+                       break;
 
-                       t->tda9887_config = *i;
+               if (t->type == TUNER_TDA9887) {
+                       t->tda9887_config = *(unsigned int *)cfg->priv;
                        set_freq(client, t->tv_freq);
+                       break;
                }
+
+               if (NULL == fe_tuner_ops->set_config) {
+                       tuner_warn("Tuner frontend module has no way to "
+                                  "set config\n");
+                       break;
+               }
+               fe_tuner_ops->set_config(&t->fe, cfg->priv);
+
                break;
+       }
        /* --- v4l ioctls --- */
        /* take care: bttv does userspace copying, we'll get a
           kernel pointer here... */
 
        }
        priv->last_div = div;
        if (t_params->has_tda9887) {
+               struct v4l2_priv_tun_config tda9887_cfg;
                int config = 0;
                int is_secam_l = (params->std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) &&
                        !(params->std & ~(V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC));
 
+               tda9887_cfg.tuner = TUNER_TDA9887;
+               tda9887_cfg.priv  = &config;
+
                if (params->std == V4L2_STD_SECAM_LC) {
                        if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc)
                                config |= TDA9887_PORT1_ACTIVE;
                }
                if (t_params->default_pll_gating_18)
                        config |= TDA9887_GATING_18;
-               i2c_clients_command(priv->i2c_props.adap, TDA9887_SET_CONFIG, &config);
+               i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
+                                   &tda9887_cfg);
        }
        tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
                  buffer[0],buffer[1],buffer[2],buffer[3]);
 
        if (t_params->has_tda9887) {
                int config = 0;
+               struct v4l2_priv_tun_config tda9887_cfg;
+
+               tda9887_cfg.tuner = TUNER_TDA9887;
+               tda9887_cfg.priv = &config;
+
                if (t_params->port1_active && !t_params->port1_fm_high_sensitivity)
                        config |= TDA9887_PORT1_ACTIVE;
                if (t_params->port2_active && !t_params->port2_fm_high_sensitivity)
                        config |= TDA9887_GAIN_NORMAL;
                if (t_params->radio_if == 2)
                        config |= TDA9887_RIF_41_3;
-               i2c_clients_command(priv->i2c_props.adap, TDA9887_SET_CONFIG, &config);
+               i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
+                                       &tda9887_cfg);
        }
        if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4)))
                tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
 
 
        [_IOC_NR(TUNER_SET_TYPE_ADDR)]         = "TUNER_SET_TYPE_ADDR",
        [_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
-       [_IOC_NR(TDA9887_SET_CONFIG)]          = "TDA9887_SET_CONFIG",
+       [_IOC_NR(TUNER_SET_CONFIG)]            = "TUNER_SET_CONFIG",
 
        [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)]     = "VIDIOC_INT_S_TUNER_MODE",
        [_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
 
        u32 type;               /* VBI service type (V4L2_SLICED_*). 0 if no service found */
 };
 
+struct v4l2_priv_tun_config {
+       int tuner;
+       void *priv;
+};
+
 /* audio ioctls */
 
 /* v4l device was opened in Radio mode, to be replaced by VIDIOC_INT_S_TUNER_MODE */
 #define TUNER_SET_STANDBY            _IOW('d', 91, int)
 
 /* Sets tda9887 specific stuff, like port1, port2 and qss */
-#define TDA9887_SET_CONFIG           _IOW('d', 92, int)
+#define TUNER_SET_CONFIG           _IOW('d', 92, struct v4l2_priv_tun_config)
 
 /* Switch the tuner to a specific tuner mode. Replacement of AUDC_SET_RADIO */
 #define VIDIOC_INT_S_TUNER_MODE             _IOW('d', 93, enum v4l2_tuner_type)