V4L/DVB (3582): Implement correct msp3400 input/output routing

- implement VIDIOC_INT_S_AUDIO_ROUTING for msp3400 and tvaudio
- use the new command in bttv, pvrusb2 and em28xx.
- remove the now obsolete MSP_SET_MATRIX from msp3400 (yeah!)
- remove the obsolete VIDIOC_S_AUDIO from msp3400.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index be567ec..80e4a74 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -37,6 +37,7 @@
 #include "bttvp.h"
 #include <media/v4l2-common.h>
 #include <media/tvaudio.h>
+#include <media/msp3400.h>
 
 #include <linux/dma-mapping.h>
 
@@ -934,11 +935,9 @@
 audio_mux(struct bttv *btv, int input, int mute)
 {
 	int gpio_val, signal;
-	struct v4l2_audio aud_input;
 	struct v4l2_control ctrl;
 	struct i2c_client *c;
 
-	memset(&aud_input, 0, sizeof(aud_input));
 	gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
 		   bttv_tvcards[btv->c.type].gpiomask);
 	signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;
@@ -953,7 +952,6 @@
 		gpio_val = bttv_tvcards[btv->c.type].gpiomute;
 	else
 		gpio_val = bttv_tvcards[btv->c.type].gpiomux[input];
-	aud_input.index = btv->audio;
 
 	gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
 	if (bttv_gpio)
@@ -962,15 +960,51 @@
 		return 0;
 
 	ctrl.id = V4L2_CID_AUDIO_MUTE;
-	/* take automute into account, just btv->mute is not enough */
-	ctrl.value = mute;
+	ctrl.value = btv->mute;
 	bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl);
 	c = btv->i2c_msp34xx_client;
-	if (c)
-		c->driver->command(c, VIDIOC_S_AUDIO, &aud_input);
+	if (c) {
+		struct v4l2_routing route;
+
+		/* Note: the inputs tuner/radio/extern/intern are translated
+		   to msp routings. This assumes common behavior for all msp3400
+		   based TV cards. When this assumption fails, then the
+		   specific MSP routing must be added to the card table.
+		   For now this is sufficient. */
+		switch (input) {
+		case TVAUDIO_INPUT_RADIO:
+			route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1,
+				    MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
+			break;
+		case TVAUDIO_INPUT_EXTERN:
+			route.input = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1,
+				    MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
+			break;
+		case TVAUDIO_INPUT_INTERN:
+			/* Yes, this is the same input as for RADIO. I doubt
+			   if this is ever used. The only board with an INTERN
+			   input is the BTTV_BOARD_AVERMEDIA98. I wonder how
+			   that was tested. My guess is that the whole INTERN
+			   input does not work. */
+			route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1,
+				    MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
+			break;
+		case TVAUDIO_INPUT_TUNER:
+		default:
+			route.input = MSP_INPUT_DEFAULT;
+			break;
+		}
+		route.output = MSP_OUTPUT_DEFAULT;
+		c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+	}
 	c = btv->i2c_tvaudio_client;
-	if (c)
-		c->driver->command(c, VIDIOC_S_AUDIO, &aud_input);
+	if (c) {
+		struct v4l2_routing route;
+
+		route.input = input;
+		route.output = 0;
+		c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+	}
 	return 0;
 }
 
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 2d68a27..f62fd706b 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -28,8 +28,9 @@
 #include <linux/i2c.h>
 #include <linux/usb.h>
 #include <media/tuner.h>
-#include <media/audiochip.h>
+#include <media/msp3400.h>
 #include <media/tveeprom.h>
+#include <media/audiochip.h>
 #include <media/v4l2-common.h>
 
 #include "em28xx.h"
@@ -146,11 +147,12 @@
 		.input          = {{
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = 0,
-			.amux     = 6,
+			.amux     = MSP_INPUT_DEFAULT,
 		},{
 			.type     = EM28XX_VMUX_SVIDEO,
 			.vmux     = 2,
-			.amux     = 1,
+			.amux     = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1,
+					MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART),
 		}},
 	},
 	[EM2820_BOARD_MSI_VOX_USB_2] = {
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 780342f..dfba33d 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -38,6 +38,7 @@
 #include "em28xx.h"
 #include <media/tuner.h>
 #include <media/v4l2-common.h>
+#include <media/msp3400.h>
 
 #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
 		      "Markus Rechberger <mrechberger@gmail.com>, " \
@@ -216,9 +217,14 @@
 	em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
 
 	if (dev->has_msp34xx) {
+		struct v4l2_routing route;
+
 		if (dev->i2s_speed)
 			em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed);
-		em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
+		route.input = dev->ctl_ainput;
+		route.output = MSP_OUTPUT(MSP_OUT_SCART1_DA);
+		/* Note: this is msp3400 specific */
+		em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
 		ainput = EM28XX_AUDIO_SRC_TUNER;
 		em28xx_audio_source(dev, ainput);
 	} else {
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 0425028..8ba1c96 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -555,7 +555,6 @@
 static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
 	struct msp_state *state = i2c_get_clientdata(client);
-	int scart = -1;
 
 	if (msp_debug >= 2)
 		v4l_i2c_print_ioctl(client, cmd);
@@ -660,15 +659,6 @@
 		break;
 	}
 
-	/* msp34xx specific */
-	case MSP_SET_MATRIX:
-	{
-		struct msp_matrix *mspm = arg;
-
-		msp_set_scart(client, mspm->input - 1, mspm->output);
-		break;
-	}
-
 	/* --- v4l2 ioctls --- */
 	case VIDIOC_S_STD:
 	{
@@ -682,36 +672,38 @@
 		return 0;
 	}
 
-	case VIDIOC_S_AUDIO:
+	case VIDIOC_INT_G_AUDIO_ROUTING:
 	{
-		struct v4l2_audio *sarg = arg;
+		struct v4l2_routing *rt = arg;
 
-		switch (sarg->index) {
-		case TVAUDIO_INPUT_RADIO:
-			/* Hauppauge uses IN2 for the radio */
-			state->mode = MSP_MODE_FM_RADIO;
-			scart       = SCART_IN2;
-			break;
-		case TVAUDIO_INPUT_EXTERN:
-			/* IN1 is often used for external input ... */
-			state->mode = MSP_MODE_EXTERN;
-			scart       = SCART_IN1;
-			break;
-		case TVAUDIO_INPUT_INTERN:
-			/* ... sometimes it is IN2 through ;) */
-			state->mode = MSP_MODE_EXTERN;
-			scart       = SCART_IN2;
-			break;
-		case TVAUDIO_INPUT_TUNER:
-			state->mode = -1;
-			break;
+		*rt = state->routing;
+		break;
+	}
+
+	case VIDIOC_INT_S_AUDIO_ROUTING:
+	{
+		struct v4l2_routing *rt = arg;
+		int tuner = (rt->input >> 3) & 1;
+		int old_tuner = (state->routing.input >> 3) & 1;
+		int sc_in = rt->input & 0x7;
+		int sc1_out = rt->output & 0xf;
+		int sc2_out = (rt->output >> 4) & 0xf;
+		u16 val;
+
+		state->routing = *rt;
+		if (state->opmode == OPMODE_AUTOSELECT) {
+			val = msp_read_dem(client, 0x30) & ~0x100;
+			msp_write_dem(client, 0x30, val | (tuner ? 0x100 : 0));
+		} else {
+			val = msp_read_dem(client, 0xbb) & ~0x100;
+			msp_write_dem(client, 0xbb, val | (tuner ? 0x100 : 0));
 		}
-		if (scart >= 0) {
-			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
-			msp_set_scart(client, scart, 0);
-		}
+		msp_set_scart(client, sc_in, 0);
+		msp_set_scart(client, sc1_out, 1);
+		msp_set_scart(client, sc2_out, 2);
 		msp_set_audmode(client);
-		msp_wake_thread(client);
+		if (tuner != old_tuner)
+			msp_wake_thread(client);
 		break;
 	}
 
@@ -941,6 +933,9 @@
 	state->muted = 0;
 	state->i2s_mode = 0;
 	init_waitqueue_head(&state->wq);
+	/* These are the reset input/output positions */
+	state->routing.input = MSP_INPUT_DEFAULT;
+	state->routing.output = MSP_OUTPUT_DEFAULT;
 
 	state->rev1 = msp_read_dsp(client, 0x1e);
 	if (state->rev1 != -1)
diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400-driver.h
index 04821eb..1940748 100644
--- a/drivers/media/video/msp3400-driver.h
+++ b/drivers/media/video/msp3400-driver.h
@@ -4,6 +4,8 @@
 #ifndef MSP3400_DRIVER_H
 #define MSP3400_DRIVER_H
 
+#include <media/msp3400.h>
+
 /* ---------------------------------------------------------------------- */
 
 /* This macro is allowed for *constants* only, gcc must calculate it
@@ -72,7 +74,7 @@
 	int i2s_mode;
 	int main, second;	/* sound carrier */
 	int input;
-	int source;             /* see msp34xxg_set_source */
+	struct v4l2_routing routing;
 
 	/* v4l2 */
 	int audmode;
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index 9ee8dc2..1c794c3 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -187,13 +187,14 @@
 {
 	struct msp_state *state = i2c_get_clientdata(client);
 	struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
+	int tuner = (state->routing.input >> 3) & 1;
 	int i;
 
 	v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
 	state->mode = mode;
 	state->rxsubchans = V4L2_TUNER_SUB_MONO;
 
-	msp_write_dem(client, 0x00bb, data->ad_cv);
+	msp_write_dem(client, 0x00bb, data->ad_cv | (tuner ? 0x100 : 0));
 
 	for (i = 5; i >= 0; i--)               /* fir 1 */
 		msp_write_dem(client, 0x0001, data->fir1[i]);
@@ -783,34 +784,6 @@
  * struct msp: only norm, acb and source are really used in this mode
  */
 
-/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
- * the value for source is the same as bit 15:8 of DSP registers 0x08,
- * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
- */
-static void msp34xxg_set_source(struct i2c_client *client, int source)
-{
-	struct msp_state *state = i2c_get_clientdata(client);
-
-	/* fix matrix mode to stereo and let the msp choose what
-	 * to output according to 'source', as recommended
-	 * for MONO (source==0) downmixing set bit[7:0] to 0x30
-	 */
-	int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20);
-
-	v4l_dbg(1, msp_debug, client, "set source to %d (0x%x)\n", source, value);
-	msp_set_source(client, value);
-	/*
-	 * set identification threshold. Personally, I
-	 * I set it to a higher value that the default
-	 * of 0x190 to ignore noisy stereo signals.
-	 * this needs tuning. (recommended range 0x00a0-0x03c0)
-	 * 0x7f0 = forced mono mode
-	 */
-	/* a2 threshold for stereo/bilingual */
-	msp_write_dem(client, 0x22, msp_stereo_thresh);
-	state->source = source;
-}
-
 static int msp34xxg_modus(struct i2c_client *client)
 {
 	struct msp_state *state = i2c_get_clientdata(client);
@@ -843,10 +816,65 @@
 	return 0x0001;
 }
 
+static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
+ {
+	struct msp_state *state = i2c_get_clientdata(client);
+	int source, matrix;
+
+	switch (state->audmode) {
+	case V4L2_TUNER_MODE_MONO:
+		source = 0; /* mono only */
+		matrix = 0x30;
+		break;
+	case V4L2_TUNER_MODE_LANG1:
+		source = 3; /* stereo or A */
+		matrix = 0x00;
+		break;
+	case V4L2_TUNER_MODE_LANG2:
+		source = 4; /* stereo or B */
+		matrix = 0x10;
+		break;
+	case V4L2_TUNER_MODE_STEREO:
+	default:
+		source = 1; /* stereo or A|B */
+		matrix = 0x20;
+		break;
+	}
+
+	if (in == MSP_DSP_OUT_TUNER)
+		source = (source << 8) | 0x20;
+	/* the msp34x2g puts the MAIN_AVC, MAIN and AUX sources in 12, 13, 14
+	   instead of 11, 12, 13. So we add one for that msp version. */
+	else if (in >= MSP_DSP_OUT_MAIN_AVC && state->has_dolby_pro_logic)
+		source = ((in + 1) << 8) | matrix;
+	else
+		source = (in << 8) | matrix;
+
+	v4l_dbg(1, msp_debug, client, "set source to %d (0x%x) for output %02x\n",
+			in, source, reg);
+	msp_write_dsp(client, reg, source);
+}
+
+static void msp34xxg_set_sources(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+	u32 in = state->routing.input;
+
+	msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
+	/* quasi-peak detector is set to same input as the loudspeaker (MAIN) */
+	msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf);
+	msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf);
+	msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf);
+	if (state->has_scart23_in_scart2_out)
+		msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf);
+	msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf);
+}
+
 /* (re-)initialize the msp34xxg */
 static void msp34xxg_reset(struct i2c_client *client)
 {
 	struct msp_state *state = i2c_get_clientdata(client);
+	int tuner = (state->routing.input >> 3) & 1;
 	int modus;
 
 	/* initialize std to 1 (autodetect) to signal that no standard is
@@ -864,11 +892,12 @@
 
 	/* step-by-step initialisation, as described in the manual */
 	modus = msp34xxg_modus(client);
+	modus |= tuner ? 0x100 : 0;
 	msp_write_dem(client, 0x30, modus);
 
 	/* write the dsps that may have an influence on
 	   standard/audio autodetection right now */
-	msp34xxg_set_source(client, state->source);
+	msp34xxg_set_sources(client);
 
 	msp_write_dsp(client, 0x0d, 0x1900); /* scart */
 	msp_write_dsp(client, 0x0e, 0x3000); /* FM */
@@ -896,7 +925,6 @@
 
 	v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n");
 
-	state->source = 1; /* default */
 	for (;;) {
 		v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n");
 		msp_sleep(state, -1);
@@ -993,7 +1021,6 @@
 static void msp34xxg_set_audmode(struct i2c_client *client)
 {
 	struct msp_state *state = i2c_get_clientdata(client);
-	int source;
 
 	if (state->std == 0x20) {
 	       if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) &&
@@ -1005,25 +1032,7 @@
 	       }
 	}
 
-	switch (state->audmode) {
-	case V4L2_TUNER_MODE_MONO:
-		source = 0; /* mono only */
-		break;
-	case V4L2_TUNER_MODE_STEREO:
-		source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
-		/* problem: that could also mean 2 (scart input) */
-		break;
-	case V4L2_TUNER_MODE_LANG1:
-		source = 3; /* stereo or A */
-		break;
-	case V4L2_TUNER_MODE_LANG2:
-		source = 4; /* stereo or B */
-		break;
-	default:
-		source  = 1;
-		break;
-	}
-	msp34xxg_set_source(client, source);
+	msp34xxg_set_sources(client);
 }
 
 void msp_set_audmode(struct i2c_client *client)
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 15fd55f..4e6d030 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -1682,6 +1682,30 @@
 	case VIDIOC_S_CTRL:
 		return tvaudio_set_ctrl(chip, arg);
 
+	case VIDIOC_INT_G_AUDIO_ROUTING:
+	{
+		struct v4l2_routing *rt = arg;
+
+		rt->input = chip->input;
+		rt->output = 0;
+		break;
+	}
+
+	case VIDIOC_INT_S_AUDIO_ROUTING:
+	{
+		struct v4l2_routing *rt = arg;
+
+		if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4)
+				return -EINVAL;
+		/* There are four inputs: tuner, radio, extern and intern. */
+		chip->input = rt->input;
+		if (chip->muted)
+			break;
+		chip_write_masked(chip, desc->inputreg,
+				desc->inputmap[chip->input], desc->inputmask);
+		break;
+	}
+
 	case VIDIOC_S_AUDIO:
 	{
 		struct v4l2_audio *sarg = arg;
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index d1234d7..6824ee04 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -312,7 +312,6 @@
 	[_IOC_NR(DECODER_DUMP)]                = "DECODER_DUMP",
 #endif
 	[_IOC_NR(AUDC_SET_RADIO)]              = "AUDC_SET_RADIO",
-	[_IOC_NR(MSP_SET_MATRIX)]              = "MSP_SET_MATRIX",
 
 	[_IOC_NR(TUNER_SET_TYPE_ADDR)]         = "TUNER_SET_TYPE_ADDR",
 	[_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
@@ -431,12 +430,6 @@
 		printk ("%s: value=%d\n", s, *p);
 		break;
 	}
-	case MSP_SET_MATRIX:
-	{
-		struct msp_matrix *p=arg;
-		printk ("%s: input=%d, output=%d\n", s, p->input, p->output);
-		break;
-	}
 	case VIDIOC_G_AUDIO:
 	case VIDIOC_S_AUDIO:
 	case VIDIOC_ENUMAUDIO:
@@ -465,7 +458,7 @@
 		struct v4l2_buffer *p=arg;
 		struct v4l2_timecode *tc=&p->timecode;
 		printk ("%s: %02ld:%02d:%02d.%08ld index=%d, type=%s, "
-			"bytesused=%d, flags=0x%08d, "
+			"bytesused=%d, flags=0x%08x, "
 			"field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n",
 				s,
 				(p->timestamp.tv_sec/3600),
@@ -479,7 +472,7 @@
 				prt_names(p->memory,v4l2_memory_names),
 				p->m.userptr);
 		printk ("%s: timecode= %02d:%02d:%02d type=%d, "
-			"flags=0x%08d, frames=%d, userbits=0x%p",
+			"flags=0x%08x, frames=%d, userbits=0x%08p\n",
 				s,tc->hours,tc->minutes,tc->seconds,
 				tc->type, tc->flags, tc->frames, tc->userbits);
 		break;
@@ -665,7 +658,7 @@
 	case VIDIOC_INT_G_VIDEO_ROUTING:
 	{
 		struct v4l2_routing  *p=arg;
-		printk ("%s: input=%d, output=%d\n", s, p->input, p->output);
+		printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output);
 		break;
 	}
 	case VIDIOC_G_SLICED_VBI_CAP:
diff --git a/include/media/msp3400.h b/include/media/msp3400.h
index 26e2658..0be61a0 100644
--- a/include/media/msp3400.h
+++ b/include/media/msp3400.h
@@ -145,9 +145,14 @@
 	 MSP_DSP_TO_SCART1(sc_i2s_src) | \
 	 MSP_DSP_TO_SCART2(sc_i2s_src) | \
 	 MSP_DSP_TO_I2S(sc_i2s_src))
+#define MSP_INPUT_DEFAULT MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1, \
+				    MSP_DSP_OUT_TUNER, MSP_DSP_OUT_TUNER)
 #define MSP_OUTPUT(sc) \
 	(MSP_OUT_TO_SCART1(sc) | \
 	 MSP_OUT_TO_SCART2(sc))
+/* This equals the RESET position of the msp3400 ACB register */
+#define MSP_OUTPUT_DEFAULT (MSP_OUT_TO_SCART1(MSP_OUT_SCART3) | \
+			    MSP_OUT_TO_SCART2(MSP_OUT_SCART1_DA))
 
 /* Tuner inputs vs. msp version */
 /* Chip      TUNER_1   TUNER_2
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 0713047..642520a 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -123,14 +123,6 @@
 /* v4l device was opened in Radio mode, to be replaced by VIDIOC_INT_S_TUNER_MODE */
 #define AUDC_SET_RADIO        _IO('d',88)
 
-/* msp3400 ioctl: will be removed in the near future, to be replaced by
-   VIDIOC_INT_S_AUDIO_ROUTING. */
-struct msp_matrix {
-  int input;
-  int output;
-};
-#define MSP_SET_MATRIX     _IOW('m',17,struct msp_matrix)
-
 /* tuner ioctls */
 
 /* Sets tuner type and its I2C addr */