浏览代码

V4L/DVB (6384): Replace TDA9887_SET_CONFIG by TUNER_SET_CONFIG

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>
Mauro Carvalho Chehab 17 年之前
父节点
当前提交
7f1711234e

+ 3 - 0
drivers/media/dvb/dvb-core/dvb_frontend.h

@@ -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);
 

+ 6 - 2
drivers/media/video/bt8xx/bttv-cards.c

@@ -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;

+ 8 - 2
drivers/media/video/cx88/cx88-i2c.c

@@ -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;
 }
 

+ 7 - 1
drivers/media/video/em28xx/em28xx-i2c.c

@@ -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:

+ 0 - 5
drivers/media/video/em28xx/em28xx-video.c

@@ -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); */
 }
 
 /*

+ 11 - 2
drivers/media/video/saa7134/saa7134-cards.c

@@ -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;

+ 13 - 6
drivers/media/video/saa7134/saa7134-dvb.c

@@ -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;
 }

+ 10 - 3
drivers/media/video/saa7134/saa7134-i2c.c

@@ -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;
 }

+ 10 - 2
drivers/media/video/saa7134/saa7134-video.c

@@ -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;
 	}

+ 19 - 4
drivers/media/video/tuner-core.c

@@ -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... */

+ 13 - 2
drivers/media/video/tuner-simple.c

@@ -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);

+ 1 - 1
drivers/media/video/v4l2-common.c

@@ -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",

+ 6 - 1
include/media/v4l2-common.h

@@ -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)