V4L/DVB (6384): Replace TDA9887_SET_CONFIG by TUNER_SET_CONFIG
authorMauro Carvalho Chehab <mchehab@infradead.org>
Thu, 18 Oct 2007 22:56:47 +0000 (19:56 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Fri, 25 Jan 2008 21:00:54 +0000 (19:00 -0200)
Currently, the only tuner-specific device that allows special
configurations is tda9887. However, tea5767 also may require some
special configurations (for example, to specify a different Xtal freq).

This patch replaces TDA9887_SET_CONFIG by a more generic internal ioctl
(TUNER_SET_CONFIG). The newer one allows specifying what tuner is
appliable to a configuration set, and allows an arbitrary configuration
struct.

Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
13 files changed:
drivers/media/dvb/dvb-core/dvb_frontend.h
drivers/media/video/bt8xx/bttv-cards.c
drivers/media/video/cx88/cx88-i2c.c
drivers/media/video/em28xx/em28xx-i2c.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134-i2c.c
drivers/media/video/saa7134/saa7134-video.c
drivers/media/video/tuner-core.c
drivers/media/video/tuner-simple.c
drivers/media/video/v4l2-common.c
include/media/v4l2-common.h

index a5262e8..c49fa04 100644 (file)
@@ -84,6 +84,9 @@ struct dvb_tuner_ops {
        /** 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);
 
index 585d1ef..4f91f98 100644 (file)
@@ -3574,8 +3574,12 @@ void __devinit bttv_init_card2(struct bttv *btv)
        }
 
        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;
index c8b1c50..937497c 100644 (file)
@@ -127,8 +127,14 @@ static int attach_inform(struct i2c_client *client)
                }
        }
 
-       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;
 }
 
index e3a4aa7..e48191f 100644 (file)
@@ -421,6 +421,8 @@ static int attach_inform(struct i2c_client *client)
                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;
@@ -428,7 +430,11 @@ static int attach_inform(struct i2c_client *client)
                        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:
index 0906bc5..bb0933f 100644 (file)
@@ -186,11 +186,6 @@ static void em28xx_config_i2c(struct em28xx *dev)
        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); */
 }
 
 /*
index 98c1b08..78d7d70 100644 (file)
@@ -4570,8 +4570,17 @@ int saa7134_board_init2(struct saa7134_dev *dev)
 
                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;
index e1ab099..a9ca573 100644 (file)
@@ -1073,14 +1073,21 @@ static int dvb_init(struct saa7134_dev *dev)
 
 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;
 }
index 6deaad1..800b397 100644 (file)
@@ -323,7 +323,6 @@ static int attach_inform(struct i2c_client *client)
 {
        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",
@@ -360,7 +359,6 @@ static int attach_inform(struct i2c_client *client)
        }
 
        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;
@@ -372,9 +370,18 @@ static int attach_inform(struct i2c_client *client)
 
                        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;
 }
index 6396d9b..2c1d56a 100644 (file)
@@ -1236,16 +1236,24 @@ static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
                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;
        }
index 9e99f36..d1d6c66 100644 (file)
@@ -889,14 +889,29 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                        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... */
index 7b93d3b..eec13cb 100644 (file)
@@ -355,10 +355,14 @@ static int simple_set_tv_freq(struct dvb_frontend *fe,
        }
        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;
@@ -391,7 +395,8 @@ static int simple_set_tv_freq(struct dvb_frontend *fe,
                }
                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]);
@@ -534,6 +539,11 @@ static int simple_set_radio_freq(struct dvb_frontend *fe,
 
        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)
@@ -546,7 +556,8 @@ static int simple_set_radio_freq(struct dvb_frontend *fe,
                        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);
index 1141b4b..a4d68d3 100644 (file)
@@ -400,7 +400,7 @@ static const char *v4l2_int_ioctls[] = {
 
        [_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",
index 181a40c..c019c1e 100644 (file)
@@ -116,6 +116,11 @@ struct v4l2_decode_vbi_line {
        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 */
@@ -131,7 +136,7 @@ struct v4l2_decode_vbi_line {
 #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)