V4L/DVB (11380): v4l2-subdev: change s_routing prototype

It is no longer needed to use a struct pointer as argument, since v4l2_subdev
doesn't require that ioctl-like approach anymore. Instead just pass the input,
output and config (new!) arguments directly.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index d63e152..9e9a755 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -652,7 +652,7 @@
 }
 
 static int au8522_s_video_routing(struct v4l2_subdev *sd,
-				  const struct v4l2_routing *route)
+					u32 input, u32 output, u32 config)
 {
 	struct au8522_state *state = to_state(sd);
 
@@ -663,11 +663,11 @@
 	   closed), and then came back to analog mode */
 	au8522_writereg(state, 0x106, 1);
 
-	if (route->input == AU8522_COMPOSITE_CH1) {
+	if (input == AU8522_COMPOSITE_CH1) {
 		au8522_setup_cvbs_mode(state);
-	} else if (route->input == AU8522_SVIDEO_CH13) {
+	} else if (input == AU8522_SVIDEO_CH13) {
 		au8522_setup_svideo_mode(state);
-	} else if (route->input == AU8522_COMPOSITE_CH4_SIF) {
+	} else if (input == AU8522_COMPOSITE_CH4_SIF) {
 		au8522_setup_cvbs_tuner_mode(state);
 	} else {
 		printk(KERN_ERR "au8522 mode not currently supported\n");
@@ -677,10 +677,10 @@
 }
 
 static int au8522_s_audio_routing(struct v4l2_subdev *sd,
-				  const struct v4l2_routing *route)
+					u32 input, u32 output, u32 config)
 {
 	struct au8522_state *state = to_state(sd);
-	set_audio_input(state, route->input);
+	set_audio_input(state, input);
 	return 0;
 }
 
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
index 873c30a..97b0034 100644
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/video/adv7170.c
@@ -219,18 +219,19 @@
 	return 0;
 }
 
-static int adv7170_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int adv7170_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct adv7170 *encoder = to_adv7170(sd);
 
-	/* RJ: route->input = 0: input is from decoder
-	   route->input = 1: input is from ZR36060
-	   route->input = 2: color bar */
+	/* RJ: input = 0: input is from decoder
+	   input = 1: input is from ZR36060
+	   input = 2: color bar */
 
 	v4l2_dbg(1, debug, sd, "set input from %s\n",
-			route->input == 0 ? "decoder" : "ZR36060");
+			input == 0 ? "decoder" : "ZR36060");
 
-	switch (route->input) {
+	switch (input) {
 	case 0:
 		adv7170_write(sd, 0x01, 0x20);
 		adv7170_write(sd, 0x08, TR1CAPT);	/* TR1 */
@@ -250,11 +251,11 @@
 		break;
 
 	default:
-		v4l2_dbg(1, debug, sd, "illegal input: %d\n", route->input);
+		v4l2_dbg(1, debug, sd, "illegal input: %d\n", input);
 		return -EINVAL;
 	}
-	v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[route->input]);
-	encoder->input = route->input;
+	v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[input]);
+	encoder->input = input;
 	return 0;
 }
 
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
index ff12103..cf8c06c 100644
--- a/drivers/media/video/adv7175.c
+++ b/drivers/media/video/adv7175.c
@@ -237,15 +237,16 @@
 	return 0;
 }
 
-static int adv7175_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int adv7175_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct adv7175 *encoder = to_adv7175(sd);
 
-	/* RJ: route->input = 0: input is from decoder
-	   route->input = 1: input is from ZR36060
-	   route->input = 2: color bar */
+	/* RJ: input = 0: input is from decoder
+	   input = 1: input is from ZR36060
+	   input = 2: color bar */
 
-	switch (route->input) {
+	switch (input) {
 	case 0:
 		adv7175_write(sd, 0x01, 0x00);
 
@@ -288,11 +289,11 @@
 		break;
 
 	default:
-		v4l2_dbg(1, debug, sd, "illegal input: %d\n", route->input);
+		v4l2_dbg(1, debug, sd, "illegal input: %d\n", input);
 		return -EINVAL;
 	}
-	v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[route->input]);
-	encoder->input = route->input;
+	v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[input]);
+	encoder->input = input;
 	return 0;
 }
 
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 19b23f2..27bedc6 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -1154,7 +1154,6 @@
 	struct au0828_fh *fh = priv;
 	struct au0828_dev *dev = fh->dev;
 	int i;
-	struct v4l2_routing route;
 
 	dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__,
 		index);
@@ -1180,9 +1179,8 @@
 		break;
 	}
 
-	route.input = AUVI_INPUT(index).vmux;
-	route.output = 0;
-	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, &route);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+			AUVI_INPUT(index).vmux, 0, 0);
 
 	for (i = 0; i < AU0828_MAX_INPUT; i++) {
 		int enable = 0;
@@ -1205,8 +1203,8 @@
 		}
 	}
 
-	route.input = AUVI_INPUT(index).amux;
-	v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, &route);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+			AUVI_INPUT(index).amux, 0, 0);
 	return 0;
 }
 
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index 9f84032..f9330e3 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -292,21 +292,22 @@
 	return 0;
 }
 
-static int bt819_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int bt819_s_routing(struct v4l2_subdev *sd,
+			   u32 input, u32 output, u32 config)
 {
 	struct bt819 *decoder = to_bt819(sd);
 
-	v4l2_dbg(1, debug, sd, "set input %x\n", route->input);
+	v4l2_dbg(1, debug, sd, "set input %x\n", input);
 
-	if (route->input < 0 || route->input > 7)
+	if (input < 0 || input > 7)
 		return -EINVAL;
 
 	if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
 		v4l2_err(sd, "no notify found!\n");
 
-	if (decoder->input != route->input) {
+	if (decoder->input != input) {
 		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
-		decoder->input = route->input;
+		decoder->input = input;
 		/* select mode */
 		if (decoder->input == 0) {
 			bt819_setbit(decoder, 0x0b, 6, 0);
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
index 78db395..d0b4d49 100644
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/video/bt856.c
@@ -142,16 +142,17 @@
 	return 0;
 }
 
-static int bt856_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int bt856_s_routing(struct v4l2_subdev *sd,
+			   u32 input, u32 output, u32 config)
 {
 	struct bt856 *encoder = to_bt856(sd);
 
-	v4l2_dbg(1, debug, sd, "set input %d\n", route->input);
+	v4l2_dbg(1, debug, sd, "set input %d\n", input);
 
 	/* We only have video bus.
-	 * route->input= 0: input is from bt819
-	 * route->input= 1: input is from ZR36060 */
-	switch (route->input) {
+	 * input= 0: input is from bt819
+	 * input= 1: input is from ZR36060 */
+	switch (input) {
 	case 0:
 		bt856_setbit(encoder, 0xde, 4, 0);
 		bt856_setbit(encoder, 0xde, 3, 1);
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
index 350cae4..af7e3a5 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/video/bt866.c
@@ -99,7 +99,8 @@
 	return 0;
 }
 
-static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int bt866_s_routing(struct v4l2_subdev *sd,
+			   u32 input, u32 output, u32 config)
 {
 	static const __u8 init[] = {
 		0xc8, 0xcc, /* CRSCALE */
@@ -137,7 +138,7 @@
 
 	val = encoder->reg[0xdc];
 
-	if (route->input == 0)
+	if (input == 0)
 		val |= 0x40; /* CBSWAP */
 	else
 		val &= ~0x40; /* !CBSWAP */
@@ -145,15 +146,15 @@
 	bt866_write(encoder, 0xdc, val);
 
 	val = encoder->reg[0xcc];
-	if (route->input == 2)
+	if (input == 2)
 		val |= 0x01; /* OSDBAR */
 	else
 		val &= ~0x01; /* !OSDBAR */
 	bt866_write(encoder, 0xcc, val);
 
-	v4l2_dbg(1, debug, sd, "set input %d\n", route->input);
+	v4l2_dbg(1, debug, sd, "set input %d\n", input);
 
-	switch (route->input) {
+	switch (input) {
 	case 0:
 	case 1:
 	case 2:
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 41c31ea..74f619d 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -1198,7 +1198,7 @@
 	ctrl.value = btv->mute;
 	bttv_call_all(btv, core, s_ctrl, &ctrl);
 	if (btv->sd_msp34xx) {
-		struct v4l2_routing route;
+		u32 in;
 
 		/* Note: the inputs tuner/radio/extern/intern are translated
 		   to msp routings. This assumes common behavior for all msp3400
@@ -1207,11 +1207,11 @@
 		   For now this is sufficient. */
 		switch (input) {
 		case TVAUDIO_INPUT_RADIO:
-			route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
+			in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
 				    MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
 			break;
 		case TVAUDIO_INPUT_EXTERN:
-			route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
+			in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
 				    MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
 			break;
 		case TVAUDIO_INPUT_INTERN:
@@ -1220,7 +1220,7 @@
 			   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_SCART2, MSP_IN_TUNER1,
+			in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
 				    MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
 			break;
 		case TVAUDIO_INPUT_TUNER:
@@ -1229,21 +1229,18 @@
 			   is the only difference between the VOODOOTV_FM
 			   and VOODOOTV_200 */
 			if (btv->c.type == BTTV_BOARD_VOODOOTV_200)
-				route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER2, \
+				in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER2, \
 					MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER);
 			else
-				route.input = MSP_INPUT_DEFAULT;
+				in = MSP_INPUT_DEFAULT;
 			break;
 		}
-		route.output = MSP_OUTPUT_DEFAULT;
-		v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing, &route);
+		v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing,
+			       in, MSP_OUTPUT_DEFAULT, 0);
 	}
 	if (btv->sd_tvaudio) {
-		struct v4l2_routing route;
-
-		route.input = input;
-		route.output = 0;
-		v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, &route);
+		v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing,
+				input, 0, 0);
 	}
 	return 0;
 }
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 9714059..57dc170 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -53,14 +53,15 @@
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int cs5345_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cs5345_s_routing(struct v4l2_subdev *sd,
+			    u32 input, u32 output, u32 config)
 {
-	if ((route->input & 0xf) > 6) {
-		v4l2_err(sd, "Invalid input %d.\n", route->input);
+	if ((input & 0xf) > 6) {
+		v4l2_err(sd, "Invalid input %d.\n", input);
 		return -EINVAL;
 	}
-	cs5345_write(sd, 0x09, route->input & 0xf);
-	cs5345_write(sd, 0x05, route->input & 0xf0);
+	cs5345_write(sd, 0x09, input & 0xf);
+	cs5345_write(sd, 0x05, input & 0xf0);
 	return 0;
 }
 
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 5aeb066..80bca8d 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -58,17 +58,18 @@
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int cs53l32a_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cs53l32a_s_routing(struct v4l2_subdev *sd,
+			      u32 input, u32 output, u32 config)
 {
 	/* There are 2 physical inputs, but the second input can be
 	   placed in two modes, the first mode bypasses the PGA (gain),
 	   the second goes through the PGA. Hence there are three
 	   possible inputs to choose from. */
-	if (route->input > 2) {
-		v4l2_err(sd, "Invalid input %d.\n", route->input);
+	if (input > 2) {
+		v4l2_err(sd, "Invalid input %d.\n", input);
 		return -EINVAL;
 	}
-	cs53l32a_write(sd, 0x01, 0x01 + (route->input << 4));
+	cs53l32a_write(sd, 0x01, 0x01 + (input << 4));
 	return 0;
 }
 
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index bb5c516..1519e91 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -33,7 +33,6 @@
 int cx18_audio_set_io(struct cx18 *cx)
 {
 	const struct cx18_card_audio_input *in;
-	struct v4l2_routing route;
 	u32 val;
 	int err;
 
@@ -44,13 +43,11 @@
 		in = &cx->card->audio_inputs[cx->audio_input];
 
 	/* handle muxer chips */
-	route.input = in->muxer_input;
-	route.output = 0;
-	v4l2_subdev_call(cx->sd_extmux, audio, s_routing, &route);
+	v4l2_subdev_call(cx->sd_extmux, audio, s_routing,
+			in->audio_input, 0, 0);
 
-	route.input = in->audio_input;
 	err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl,
-			       audio, s_routing, &route);
+			       audio, s_routing, in->audio_input, 0, 0);
 	if (err)
 		return err;
 
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 9b3e574..cf2bd88 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -547,19 +547,19 @@
 }
 
 static int cx18_av_s_video_routing(struct v4l2_subdev *sd,
-				   const struct v4l2_routing *route)
+				   u32 input, u32 output, u32 config)
 {
 	struct cx18_av_state *state = to_cx18_av_state(sd);
 	struct cx18 *cx = v4l2_get_subdevdata(sd);
-	return set_input(cx, route->input, state->aud_input);
+	return set_input(cx, input, state->aud_input);
 }
 
 static int cx18_av_s_audio_routing(struct v4l2_subdev *sd,
-				   const struct v4l2_routing *route)
+				   u32 input, u32 output, u32 config)
 {
 	struct cx18_av_state *state = to_cx18_av_state(sd);
 	struct cx18 *cx = v4l2_get_subdevdata(sd);
-	return set_input(cx, state->vid_input, route->input);
+	return set_input(cx, state->vid_input, input);
 }
 
 static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index ae2460e..86a204b 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -156,12 +156,12 @@
 }
 
 static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
-				   const struct v4l2_routing *route)
+				   u32 input, u32 output, u32 config)
 {
 	struct cx18 *cx = v4l2_get_subdevdata(sd);
 	u32 data;
 
-	switch (route->input) {
+	switch (input) {
 	case 0:
 		data = cx->card->gpio_audio_input.tuner;
 		break;
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index f572080..cdefd90 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -932,7 +932,7 @@
 		CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n",
 			route->input, route->output);
 		cx18_call_hw(cx, cx->card->hw_audio_ctrl, audio, s_routing,
-			     route);
+			     route->input, route->output, 0);
 		break;
 	}
 
diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/video/cx18/cx18-video.c
index 6fdaded..6dc84aa 100644
--- a/drivers/media/video/cx18/cx18-video.c
+++ b/drivers/media/video/cx18/cx18-video.c
@@ -25,20 +25,8 @@
 
 void cx18_video_set_io(struct cx18 *cx)
 {
-	struct v4l2_routing route;
 	int inp = cx->active_input;
-	u32 type;
 
-	route.input = cx->card->video_inputs[inp].video_input;
-	route.output = 0;
-	v4l2_subdev_call(cx->sd_av, video, s_routing, &route);
-
-	type = cx->card->video_inputs[inp].video_type;
-
-	if (type == CX18_CARD_INPUT_VID_TUNER)
-		route.input = 0;  /* Tuner */
-	else if (type < CX18_CARD_INPUT_COMPOSITE1)
-		route.input = 2;  /* S-Video */
-	else
-		route.input = 1;  /* Composite */
+	v4l2_subdev_call(cx->sd_av, video, s_routing,
+			cx->card->video_inputs[inp].video_input, 0, 0);
 }
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index f209fe1..c8a32b1 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -357,10 +357,7 @@
  */
 void cx231xx_config_i2c(struct cx231xx *dev)
 {
-	struct v4l2_routing route;
-
-	route.input = INPUT(dev->video_input)->vmux;
-	route.output = 0;
+	/* u32 input = INPUT(dev->video_input)->vmux; */
 
 	call_all(dev, video, s_stream, 1);
 }
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 0645703..a23ae73 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -820,17 +820,12 @@
 
 void video_mux(struct cx231xx *dev, int index)
 {
-
-	struct v4l2_routing route;
-
-	route.input = INPUT(index)->vmux;
-	route.output = 0;
 	dev->video_input = index;
 	dev->ctl_ainput = INPUT(index)->amux;
 
 	cx231xx_set_video_input_mux(dev, index);
 
-	cx25840_call(dev, video, s_routing, &route);
+	cx25840_call(dev, video, s_routing, INPUT(index)->vmux, 0, 0);
 
 	cx231xx_set_audio_input(dev, dev->ctl_ainput);
 
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index ce7b3f8..68068c6 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -393,9 +393,6 @@
 
 static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
 {
-	struct v4l2_routing route;
-	memset(&route, 0, sizeof(route));
-
 	dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
 		__func__,
 		input, INPUT(input)->vmux,
@@ -403,10 +400,9 @@
 		INPUT(input)->gpio2, INPUT(input)->gpio3);
 	dev->input = input;
 
-	route.input = INPUT(input)->vmux;
-
 	/* Tell the internal A/V decoder */
-	v4l2_subdev_call(dev->sd_cx25840, video, s_routing, &route);
+	v4l2_subdev_call(dev->sd_cx25840, video, s_routing,
+			INPUT(input)->vmux, 0, 0);
 
 	return 0;
 }
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 6209027..0be51b6 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1322,22 +1322,24 @@
 	return 0;
 }
 
-static int cx25840_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cx25840_s_video_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
 {
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	return set_input(client, route->input, state->aud_input);
+	return set_input(client, input, state->aud_input);
 }
 
-static int cx25840_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cx25840_s_audio_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
 {
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
 	if (state->is_cx25836)
 		return -EINVAL;
-	return set_input(client, state->vid_input, route->input);
+	return set_input(client, state->vid_input, input);
 }
 
 static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 61afa89..ec0425d 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -428,10 +428,8 @@
 		   routes for different inputs. HVR-1300 surely does */
 		if (core->board.audio_chip &&
 		    core->board.audio_chip == V4L2_IDENT_WM8775) {
-			struct v4l2_routing route;
-
-			route.input = INPUT(input).audioroute;
-			call_all(core, audio, s_routing, &route);
+			call_all(core, audio, s_routing,
+					INPUT(input).audioroute, 0, 0);
 		}
 		/* cx2388's C-ADC is connected to the tuner only.
 		   When used with S-Video, that ADC is busy dealing with
@@ -823,10 +821,8 @@
 		if (core->board.radio.audioroute) {
 			if(core->board.audio_chip &&
 				core->board.audio_chip == V4L2_IDENT_WM8775) {
-				struct v4l2_routing route;
-
-				route.input = core->board.radio.audioroute;
-				call_all(core, audio, s_routing, &route);
+				call_all(core, audio, s_routing,
+					core->board.radio.audioroute, 0, 0);
 			}
 			/* "I2S ADC mode" */
 			core->tvaudio = WW_I2SADC;
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 8f8f20e..192b76c 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1018,14 +1018,9 @@
  */
 void em28xx_wake_i2c(struct em28xx *dev)
 {
-	struct v4l2_routing route;
-	int zero = 0;
-
-	route.input  = INPUT(dev->ctl_input)->vmux;
-	route.output = 0;
-
-	v4l2_device_call_all(&dev->v4l2_dev, 0, core,  reset, zero);
-	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, &route);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core,  reset, 0);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+			INPUT(dev->ctl_input)->vmux, 0, 0);
 	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
 }
 
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 9648784..882796e 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -515,10 +515,6 @@
 
 static void video_mux(struct em28xx *dev, int index)
 {
-	struct v4l2_routing route;
-
-	route.input = INPUT(index)->vmux;
-	route.output = 0;
 	dev->ctl_input = index;
 	dev->ctl_ainput = INPUT(index)->amux;
 	dev->ctl_aoutput = INPUT(index)->aout;
@@ -526,25 +522,22 @@
 	if (!dev->ctl_aoutput)
 		dev->ctl_aoutput = EM28XX_AOUT_MASTER;
 
-	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, &route);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+			INPUT(index)->vmux, 0, 0);
 
 	if (dev->board.has_msp34xx) {
 		if (dev->i2s_speed) {
 			v4l2_device_call_all(&dev->v4l2_dev, 0, audio,
 				s_i2s_clock_freq, dev->i2s_speed);
 		}
-		route.input  = dev->ctl_ainput;
-		route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
-
 		/* Note: this is msp3400 specific */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, &route);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+			 dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
 	}
 
 	if (dev->board.adecoder != EM28XX_NOADECODER) {
-		route.input  = dev->ctl_ainput;
-		route.output = dev->ctl_aoutput;
-
-		v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, &route);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+			dev->ctl_ainput, dev->ctl_aoutput, 0);
 	}
 
 	em28xx_audio_analog_set(dev);
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index 0dd5f53..ceb05bd 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -248,15 +248,16 @@
 	return 0;
 }
 
-static int subdev_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int subdev_s_audio_routing(struct v4l2_subdev *sd,
+				  u32 input, u32 output, u32 config)
 {
 	struct ivtv *itv = sd_to_ivtv(sd);
 	u16 mask, data;
 
-	if (route->input > 2)
+	if (input > 2)
 		return -EINVAL;
 	mask = itv->card->gpio_audio_input.mask;
-	switch (route->input) {
+	switch (input) {
 	case 0:
 		data = itv->card->gpio_audio_input.tuner;
 		break;
@@ -318,17 +319,18 @@
 	return 0;
 }
 
-static int subdev_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int subdev_s_video_routing(struct v4l2_subdev *sd,
+				  u32 input, u32 output, u32 config)
 {
 	struct ivtv *itv = sd_to_ivtv(sd);
 	u16 mask, data;
 
-	if (route->input > 2) /* 0:Tuner 1:Composite 2:S-Video */
+	if (input > 2) /* 0:Tuner 1:Composite 2:S-Video */
 		return -EINVAL;
 	mask = itv->card->gpio_video_input.mask;
-	if  (route->input == 0)
+	if (input == 0)
 		data = itv->card->gpio_video_input.tuner;
-	else if  (route->input == 1)
+	else if (input == 1)
 		data = itv->card->gpio_video_input.composite;
 	else
 		data = itv->card->gpio_video_input.svideo;
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 052fbe9..cf48b6ab 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1033,7 +1033,6 @@
 static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
 {
 	struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
-	struct v4l2_routing route;
 
 	if (outp >= itv->card->nof_outputs)
 		return -EINVAL;
@@ -1046,9 +1045,9 @@
 		   itv->active_output, outp);
 
 	itv->active_output = outp;
-	route.input = SAA7127_INPUT_TYPE_NORMAL;
-	route.output = itv->card->video_outputs[outp].video_output;
-	ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, &route);
+	ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
+			SAA7127_INPUT_TYPE_NORMAL,
+			itv->card->video_outputs[outp].video_output, 0);
 
 	return 0;
 }
@@ -1738,7 +1737,8 @@
 	case VIDIOC_INT_S_AUDIO_ROUTING: {
 		struct v4l2_routing *route = arg;
 
-		ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, route);
+		ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing,
+				route->input, route->output, 0);
 		break;
 	}
 
diff --git a/drivers/media/video/ivtv/ivtv-routing.c b/drivers/media/video/ivtv/ivtv-routing.c
index 3fd3022..8898c56 100644
--- a/drivers/media/video/ivtv/ivtv-routing.c
+++ b/drivers/media/video/ivtv/ivtv-routing.c
@@ -34,7 +34,7 @@
 void ivtv_audio_set_io(struct ivtv *itv)
 {
 	const struct ivtv_card_audio_input *in;
-	struct v4l2_routing route;
+	u32 input, output = 0;
 
 	/* Determine which input to use */
 	if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
@@ -43,73 +43,77 @@
 		in = &itv->card->audio_inputs[itv->audio_input];
 
 	/* handle muxer chips */
-	route.input = in->muxer_input;
-	route.output = 0;
+	input = in->muxer_input;
 	if (itv->card->hw_muxer & IVTV_HW_M52790)
-		route.output = M52790_OUT_STEREO;
-	v4l2_subdev_call(itv->sd_muxer, audio, s_routing, &route);
+		output = M52790_OUT_STEREO;
+	v4l2_subdev_call(itv->sd_muxer, audio, s_routing,
+			input, output, 0);
 
-	route.input = in->audio_input;
-	route.output = 0;
+	input = in->audio_input;
+	output = 0;
 	if (itv->card->hw_audio & IVTV_HW_MSP34XX)
-		route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
-	ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, &route);
+		output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
+	ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing,
+			input, output, 0);
 }
 
 /* Selects the video input and output according to the current
    settings. */
 void ivtv_video_set_io(struct ivtv *itv)
 {
-	struct v4l2_routing route;
 	int inp = itv->active_input;
+	u32 input;
 	u32 type;
 
-	route.input = itv->card->video_inputs[inp].video_input;
-	route.output = 0;
-	v4l2_subdev_call(itv->sd_video, video, s_routing, &route);
+	v4l2_subdev_call(itv->sd_video, video, s_routing,
+		itv->card->video_inputs[inp].video_input, 0, 0);
 
 	type = itv->card->video_inputs[inp].video_type;
 
 	if (type == IVTV_CARD_INPUT_VID_TUNER) {
-		route.input = 0;  /* Tuner */
+		input = 0;  /* Tuner */
 	} else if (type < IVTV_CARD_INPUT_COMPOSITE1) {
-		route.input = 2;  /* S-Video */
+		input = 2;  /* S-Video */
 	} else {
-		route.input = 1;  /* Composite */
+		input = 1;  /* Composite */
 	}
 
 	if (itv->card->hw_video & IVTV_HW_GPIO)
-		ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing, &route);
+		ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing,
+				input, 0, 0);
 
 	if (itv->card->hw_video & IVTV_HW_UPD64031A) {
 		if (type == IVTV_CARD_INPUT_VID_TUNER ||
 		    type >= IVTV_CARD_INPUT_COMPOSITE1) {
 			/* Composite: GR on, connect to 3DYCS */
-			route.input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE;
+			input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE;
 		} else {
 			/* S-Video: GR bypassed, turn it off */
-			route.input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE;
+			input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE;
 		}
-		route.input |= itv->card->gr_config;
+		input |= itv->card->gr_config;
 
-		ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing, &route);
+		ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing,
+				input, 0, 0);
 	}
 
 	if (itv->card->hw_video & IVTV_HW_UPD6408X) {
-		route.input = UPD64083_YCS_MODE;
+		input = UPD64083_YCS_MODE;
 		if (type > IVTV_CARD_INPUT_VID_TUNER &&
 		    type < IVTV_CARD_INPUT_COMPOSITE1) {
-			/* S-Video uses YCNR mode and internal Y-ADC, the upd64031a
-			   is not used. */
-			route.input |= UPD64083_YCNR_MODE;
+			/* S-Video uses YCNR mode and internal Y-ADC, the
+			   upd64031a is not used. */
+			input |= UPD64083_YCNR_MODE;
 		}
 		else if (itv->card->hw_video & IVTV_HW_UPD64031A) {
-		  /* Use upd64031a output for tuner and composite(CX23416GYC only) inputs */
-		  if ((type == IVTV_CARD_INPUT_VID_TUNER)||
-		      (itv->card->type == IVTV_CARD_CX23416GYC)) {
-		    route.input |= UPD64083_EXT_Y_ADC;
-		  }
+			/* Use upd64031a output for tuner and
+			   composite(CX23416GYC only) inputs */
+			if (type == IVTV_CARD_INPUT_VID_TUNER ||
+			    itv->card->type == IVTV_CARD_CX23416GYC) {
+				input |= UPD64083_EXT_Y_ADC;
+			}
 		}
-		ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing, &route);
+		ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing,
+				input, 0, 0);
 	}
 }
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
index 4e5f0e7..fab8e02 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/video/ks0127.c
@@ -409,11 +409,12 @@
 	}
 }
 
-static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int ks0127_s_routing(struct v4l2_subdev *sd,
+			    u32 input, u32 output, u32 config)
 {
 	struct ks0127 *ks = to_ks0127(sd);
 
-	switch (route->input) {
+	switch (input) {
 	case KS_INPUT_COMPOSITE_1:
 	case KS_INPUT_COMPOSITE_2:
 	case KS_INPUT_COMPOSITE_3:
@@ -421,13 +422,13 @@
 	case KS_INPUT_COMPOSITE_5:
 	case KS_INPUT_COMPOSITE_6:
 		v4l2_dbg(1, debug, sd,
-			"s_routing %d: Composite\n", route->input);
+			"s_routing %d: Composite\n", input);
 		/* autodetect 50/60 Hz */
 		ks0127_and_or(sd, KS_CMDA,   0xfc, 0x00);
 		/* VSE=0 */
 		ks0127_and_or(sd, KS_CMDA,   ~0x40, 0x00);
 		/* set input line */
-		ks0127_and_or(sd, KS_CMDB,   0xb0, route->input);
+		ks0127_and_or(sd, KS_CMDB,   0xb0, input);
 		/* non-freerunning mode */
 		ks0127_and_or(sd, KS_CMDC,   0x70, 0x0a);
 		/* analog input */
@@ -455,13 +456,13 @@
 	case KS_INPUT_SVIDEO_2:
 	case KS_INPUT_SVIDEO_3:
 		v4l2_dbg(1, debug, sd,
-			"s_routing %d: S-Video\n", route->input);
+			"s_routing %d: S-Video\n", input);
 		/* autodetect 50/60 Hz */
 		ks0127_and_or(sd, KS_CMDA,   0xfc, 0x00);
 		/* VSE=0 */
 		ks0127_and_or(sd, KS_CMDA,   ~0x40, 0x00);
 		/* set input line */
-		ks0127_and_or(sd, KS_CMDB,   0xb0, route->input);
+		ks0127_and_or(sd, KS_CMDB,   0xb0, input);
 		/* non-freerunning mode */
 		ks0127_and_or(sd, KS_CMDC,   0x70, 0x0a);
 		/* analog input */
@@ -496,7 +497,7 @@
 
 		ks0127_and_or(sd, KS_CMDA,   0xff, 0x40); /* VSE=1 */
 		/* set input line and VALIGN */
-		ks0127_and_or(sd, KS_CMDB,   0xb0, (route->input | 0x40));
+		ks0127_and_or(sd, KS_CMDB,   0xb0, (input | 0x40));
 		/* freerunning mode, */
 		/* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0  VMEM=1*/
 		ks0127_and_or(sd, KS_CMDC,   0x70, 0x87);
@@ -531,7 +532,7 @@
 
 	default:
 		v4l2_dbg(1, debug, sd,
-			"s_routing: Unknown input %d\n", route->input);
+			"s_routing: Unknown input %d\n", input);
 		break;
 	}
 
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index 1f340fe..d7317e7 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -69,12 +69,13 @@
    part of the audio output routing. The normal case is that another
    chip takes care of the actual muting so making it part of the
    output routing seems to be the right thing to do for now. */
-static int m52790_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int m52790_s_routing(struct v4l2_subdev *sd,
+			    u32 input, u32 output, u32 config)
 {
 	struct m52790_state *state = to_state(sd);
 
-	state->input = route->input;
-	state->output = route->output;
+	state->input = input;
+	state->output = output;
 	m52790_write(sd);
 	return 0;
 }
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 38e6397..e9df3cb 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -505,25 +505,26 @@
 	return 0;
 }
 
-static int msp_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
+static int msp_s_routing(struct v4l2_subdev *sd,
+			 u32 input, u32 output, u32 config)
 {
 	struct msp_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	int tuner = (rt->input >> 3) & 1;
-	int sc_in = rt->input & 0x7;
-	int sc1_out = rt->output & 0xf;
-	int sc2_out = (rt->output >> 4) & 0xf;
+	int tuner = (input >> 3) & 1;
+	int sc_in = input & 0x7;
+	int sc1_out = output & 0xf;
+	int sc2_out = (output >> 4) & 0xf;
 	u16 val, reg;
 	int i;
 	int extern_input = 1;
 
-	if (state->routing.input == rt->input &&
-			state->routing.output == rt->output)
+	if (state->route_in == input && state->route_out == output)
 		return 0;
-	state->routing = *rt;
+	state->route_in = input;
+	state->route_out = output;
 	/* check if the tuner input is used */
 	for (i = 0; i < 5; i++) {
-		if (((rt->input >> (4 + i * 4)) & 0xf) == 0)
+		if (((input >> (4 + i * 4)) & 0xf) == 0)
 			extern_input = 0;
 	}
 	state->mode = extern_input ? MSP_MODE_EXTERN : MSP_MODE_AM_DETECT;
@@ -673,7 +674,7 @@
 	}
 	v4l_info(client, "Audmode:  0x%04x\n", state->audmode);
 	v4l_info(client, "Routing:  0x%08x (input) 0x%08x (output)\n",
-			state->routing.input, state->routing.output);
+			state->route_in, state->route_out);
 	v4l_info(client, "ACB:      0x%04x\n", state->acb);
 	return 0;
 }
@@ -761,8 +762,8 @@
 	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->route_in = MSP_INPUT_DEFAULT;
+	state->route_out = 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 3fe1c1b..d6b3e6d 100644
--- a/drivers/media/video/msp3400-driver.h
+++ b/drivers/media/video/msp3400-driver.h
@@ -80,7 +80,8 @@
 	int i2s_mode;
 	int main, second;	/* sound carrier */
 	int input;
-	struct v4l2_routing routing;
+	u32 route_in;
+	u32 route_out;
 
 	/* v4l2 */
 	int audmode;
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index a655e9c..168bca7 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -188,7 +188,7 @@
 {
 	struct msp_state *state = to_state(i2c_get_clientdata(client));
 	struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
-	int tuner = (state->routing.input >> 3) & 1;
+	int tuner = (state->route_in >> 3) & 1;
 	int i;
 
 	v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
@@ -896,7 +896,7 @@
 static void msp34xxg_set_sources(struct i2c_client *client)
 {
 	struct msp_state *state = to_state(i2c_get_clientdata(client));
-	u32 in = state->routing.input;
+	u32 in = state->route_in;
 
 	msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
 	/* quasi-peak detector is set to same input as the loudspeaker (MAIN) */
@@ -912,7 +912,7 @@
 static void msp34xxg_reset(struct i2c_client *client)
 {
 	struct msp_state *state = to_state(i2c_get_clientdata(client));
-	int tuner = (state->routing.input >> 3) & 1;
+	int tuner = (state->route_in >> 3) & 1;
 	int modus;
 
 	/* initialize std to 1 (autodetect) to signal that no standard is
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index a547c85..3be5a71 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -83,9 +83,14 @@
 static int video_audio_connect[MXB_INPUTS] =
 	{ 0, 1, 3, 3 };
 
+struct mxb_routing {
+	u32 input;
+	u32 output;
+};
+
 /* These are the necessary input-output-pins for bringing one audio source
    (see above) to the CD-output. Note that gain is set to 0 in this table. */
-static struct v4l2_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
+static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
 	{ { 1, 1 }, { 1, 1 } },	/* Tuner */
 	{ { 5, 1 }, { 6, 1 } },	/* AUX 1 */
 	{ { 4, 1 }, { 6, 1 } },	/* AUX 2 */
@@ -97,7 +102,7 @@
 
 /* These are the necessary input-output-pins for bringing one audio source
    (see above) to the line-output. Note that gain is set to 0 in this table. */
-static struct v4l2_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
+static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
 	{ { 2, 3 }, { 1, 2 } },
 	{ { 5, 3 }, { 6, 2 } },
 	{ { 4, 3 }, { 6, 2 } },
@@ -134,10 +139,6 @@
 
 #define saa7111a_call(mxb, o, f, args...) \
 	v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
-#define tea6420_1_call(mxb, o, f, args...) \
-	v4l2_subdev_call(mxb->tea6420_1, o, f, ##args)
-#define tea6420_2_call(mxb, o, f, args...) \
-	v4l2_subdev_call(mxb->tea6420_2, o, f, ##args)
 #define tda9840_call(mxb, o, f, args...) \
 	v4l2_subdev_call(mxb->tda9840, o, f, ##args)
 #define tea6415c_call(mxb, o, f, args...) \
@@ -147,6 +148,22 @@
 #define call_all(dev, o, f, args...) \
 	v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
 
+static inline void tea6420_route_cd(struct mxb *mxb, int idx)
+{
+	v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
+		TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
+	v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
+		TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
+}
+
+static inline void tea6420_route_line(struct mxb *mxb, int idx)
+{
+	v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
+		TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
+	v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
+		TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0);
+}
+
 static struct saa7146_extension extension;
 
 static int mxb_probe(struct saa7146_dev *dev)
@@ -268,7 +285,6 @@
 	struct i2c_msg msg;
 	struct tuner_setup tun_setup;
 	v4l2_std_id std = V4L2_STD_PAL_BG;
-	struct v4l2_routing route;
 
 	int i = 0, err = 0;
 
@@ -277,9 +293,8 @@
 
 	/* select tuner-output on saa7111a */
 	i = 0;
-	route.input = SAA7115_COMPOSITE0;
-	route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS;
-	saa7111a_call(mxb, video, s_routing, &route);
+	saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
+		SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS, 0);
 
 	/* select a tuner type */
 	tun_setup.mode_mask = T_ANALOG_TV;
@@ -296,20 +311,14 @@
 	tuner_call(mxb, core, s_std, std);
 
 	/* mute audio on tea6420s */
-	tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]);
-	tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]);
-	tea6420_1_call(mxb, audio, s_routing, &TEA6420_cd[6][0]);
-	tea6420_2_call(mxb, audio, s_routing, &TEA6420_cd[6][1]);
+	tea6420_route_line(mxb, 6);
+	tea6420_route_cd(mxb, 6);
 
 	/* switch to tuner-channel on tea6415c */
-	route.input = 3;
-	route.output = 17;
-	tea6415c_call(mxb, video, s_routing, &route);
+	tea6415c_call(mxb, video, s_routing, 3, 17, 0);
 
 	/* select tuner-output on multicable on tea6415c */
-	route.input = 3;
-	route.output = 13;
-	tea6415c_call(mxb, video, s_routing, &route);
+	tea6415c_call(mxb, video, s_routing, 3, 13, 0);
 
 	/* the rest for mxb */
 	mxb->cur_input = 0;
@@ -433,18 +442,9 @@
 
 	if (vc->id == V4L2_CID_AUDIO_MUTE) {
 		mxb->cur_mute = vc->value;
-		if (!vc->value) {
-			/* switch the audio-source */
-			tea6420_1_call(mxb, audio, s_routing,
-					&TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
-			tea6420_2_call(mxb, audio, s_routing,
-					&TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
-		} else {
-			tea6420_1_call(mxb, audio, s_routing,
-					&TEA6420_line[6][0]);
-			tea6420_2_call(mxb, audio, s_routing,
-					&TEA6420_line[6][1]);
-		}
+		/* switch the audio-source */
+		tea6420_route_line(mxb, vc->value ? 6 :
+				video_audio_connect[mxb->cur_input]);
 		DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
 	}
 	return 0;
@@ -473,7 +473,7 @@
 {
 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
-	struct v4l2_routing route;
+	int err = 0;
 	int i = 0;
 
 	DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
@@ -491,16 +491,12 @@
 	switch (input) {
 	case TUNER:
 		i = SAA7115_COMPOSITE0;
-		route.input = 3;
-		route.output = 17;
 
-		if (tea6415c_call(mxb, video, s_routing, &route)) {
-			printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
-			return -EFAULT;
-		}
+		err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
+
 		/* connect tuner-output always to multicable */
-		route.input = 3;
-		route.output = 13;
+		if (!err)
+			err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
 		break;
 	case AUX3_YC:
 		/* nothing to be done here. aux3_yc is
@@ -514,37 +510,20 @@
 		break;
 	case AUX1:
 		i = SAA7115_COMPOSITE0;
-		route.input = 1;
-		route.output = 17;
+		err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
 		break;
 	}
 
-	/* switch video in tea6415c only if necessary */
-	switch (input) {
-	case TUNER:
-	case AUX1:
-		if (tea6415c_call(mxb, video, s_routing, &route)) {
-			printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
-			return -EFAULT;
-		}
-		break;
-	default:
-		break;
-	}
+	if (err)
+		return err;
 
 	/* switch video in saa7111a */
-	route.input = i;
-	route.output = 0;
-	if (saa7111a_call(mxb, video, s_routing, &route))
+	if (saa7111a_call(mxb, video, s_routing, i, 0, 0))
 		printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
 
 	/* switch the audio-source only if necessary */
-	if (0 == mxb->cur_mute) {
-		tea6420_1_call(mxb, audio, s_routing,
-				&TEA6420_line[video_audio_connect[input]][0]);
-		tea6420_2_call(mxb, audio, s_routing,
-				&TEA6420_line[video_audio_connect[input]][1]);
-	}
+	if (0 == mxb->cur_mute)
+		tea6420_route_line(mxb, video_audio_connect[input]);
 
 	return 0;
 }
@@ -686,9 +665,7 @@
 
 		DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
 
-		tea6420_1_call(mxb, audio, s_routing, &TEA6420_cd[i][0]);
-		tea6420_2_call(mxb, audio, s_routing, &TEA6420_cd[i][1]);
-
+		tea6420_route_cd(mxb, i);
 		return 0;
 	}
 	case MXB_S_AUDIO_LINE:
@@ -701,9 +678,7 @@
 		}
 
 		DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
-		tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[i][0]);
-		tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[i][1]);
-
+		tea6420_route_line(mxb, i);
 		return 0;
 	}
 	default:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index ccf2a3c..10ef1a2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -58,9 +58,9 @@
 void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 {
 	if (hdw->input_dirty || hdw->force_dirty) {
-		struct v4l2_routing route;
 		const struct routing_scheme *sp;
 		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+		u32 input;
 
 		pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
 
@@ -68,7 +68,7 @@
 		    ((sp = routing_schemes + sid) != NULL) &&
 		    (hdw->input_val >= 0) &&
 		    (hdw->input_val < sp->cnt)) {
-			route.input = sp->def[hdw->input_val];
+			input = sp->def[hdw->input_val];
 		} else {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 				   "*** WARNING *** subdev msp3400 set_input:"
@@ -77,8 +77,8 @@
 				   sid, hdw->input_val);
 			return;
 		}
-		route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
-		sd->ops->audio->s_routing(sd, &route);
+		sd->ops->audio->s_routing(sd, input,
+			MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
 	}
 }
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
index b5c3428..9023adf 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
@@ -60,16 +60,16 @@
 void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 {
 	if (hdw->input_dirty || hdw->force_dirty) {
-		struct v4l2_routing route;
 		const struct routing_scheme *sp;
 		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+		u32 input;
 		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
 			   hdw->input_val);
 		if ((sid < ARRAY_SIZE(routing_schemes)) &&
 		    ((sp = routing_schemes + sid) != NULL) &&
 		    (hdw->input_val >= 0) &&
 		    (hdw->input_val < sp->cnt)) {
-			route.input = sp->def[hdw->input_val];
+			input = sp->def[hdw->input_val];
 		} else {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 				   "*** WARNING *** subdev v4l2 set_input:"
@@ -78,8 +78,7 @@
 				   sid, hdw->input_val);
 			return;
 		}
-		route.output = 0;
-		sd->ops->audio->s_routing(sd, &route);
+		sd->ops->audio->s_routing(sd, input, 0, 0);
 	}
 }
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 4e017ff..05e5235 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -105,14 +105,11 @@
 {
 	pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
 	if (hdw->input_dirty || hdw->force_dirty) {
-		struct v4l2_routing route;
 		enum cx25840_video_input vid_input;
 		enum cx25840_audio_input aud_input;
 		const struct routing_scheme *sp;
 		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
 
-		memset(&route, 0, sizeof(route));
-
 		if ((sid < ARRAY_SIZE(routing_schemes)) &&
 		    ((sp = routing_schemes + sid) != NULL) &&
 		    (hdw->input_val >= 0) &&
@@ -131,10 +128,8 @@
 		pvr2_trace(PVR2_TRACE_CHIPS,
 			   "subdev cx2584x set_input vid=0x%x aud=0x%x",
 			   vid_input, aud_input);
-		route.input = (u32)vid_input;
-		sd->ops->video->s_routing(sd, &route);
-		route.input = (u32)aud_input;
-		sd->ops->audio->s_routing(sd, &route);
+		sd->ops->video->s_routing(sd, (u32)vid_input, 0, 0);
+		sd->ops->audio->s_routing(sd, (u32)aud_input, 0, 0);
 	}
 }
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index b3862f5..d2fe7c8 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -75,16 +75,17 @@
 void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 {
 	if (hdw->input_dirty || hdw->force_dirty) {
-		struct v4l2_routing route;
 		const struct routing_scheme *sp;
 		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+		u32 input;
+
 		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
 			   hdw->input_val);
 		if ((sid < ARRAY_SIZE(routing_schemes)) &&
 		    ((sp = routing_schemes + sid) != NULL) &&
 		    (hdw->input_val >= 0) &&
 		    (hdw->input_val < sp->cnt)) {
-			route.input = sp->def[hdw->input_val];
+			input = sp->def[hdw->input_val];
 		} else {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 				   "*** WARNING *** subdev v4l2 set_input:"
@@ -93,8 +94,7 @@
 				   sid, hdw->input_val);
 			return;
 		}
-		route.output = 0;
-		sd->ops->video->s_routing(sd, &route);
+		sd->ops->video->s_routing(sd, input, 0, 0);
 	}
 }
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
index 1670aa4..8c1eae0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -39,24 +39,22 @@
 void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 {
 	if (hdw->input_dirty || hdw->force_dirty) {
-		struct v4l2_routing route;
-
-		memset(&route, 0, sizeof(route));
+		u32 input;
 
 		switch (hdw->input_val) {
 		case PVR2_CVAL_INPUT_RADIO:
-			route.input = 1;
+			input = 1;
 			break;
 		default:
 			/* All other cases just use the second input */
-			route.input = 2;
+			input = 2;
 			break;
 		}
 		pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775"
 			   " set_input(val=%d route=0x%x)",
-			   hdw->input_val, route.input);
+			   hdw->input_val, input);
 
-		sd->ops->audio->s_routing(sd, &route);
+		sd->ops->audio->s_routing(sd, input, 0, 0);
 	}
 }
 
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 8bb1fc1..5c24c99 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -299,17 +299,18 @@
 	return 0;
 }
 
-static int saa7110_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa7110_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct saa7110 *decoder = to_saa7110(sd);
 
-	if (route->input < 0 || route->input >= SAA7110_MAX_INPUT) {
-		v4l2_dbg(1, debug, sd, "input=%d not available\n", route->input);
+	if (input < 0 || input >= SAA7110_MAX_INPUT) {
+		v4l2_dbg(1, debug, sd, "input=%d not available\n", input);
 		return -EINVAL;
 	}
-	if (decoder->input != route->input) {
-		saa7110_selmux(sd, route->input);
-		v4l2_dbg(1, debug, sd, "switched to input=%d\n", route->input);
+	if (decoder->input != input) {
+		saa7110_selmux(sd, input);
+		v4l2_dbg(1, debug, sd, "switched to input=%d\n", input);
 	}
 	return 0;
 }
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index c0e66a8..44873a0 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1228,30 +1228,32 @@
 	return 0;
 }
 
-static int saa711x_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa711x_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct saa711x_state *state = to_state(sd);
-	u32 input = route->input;
 	u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0;
 
-	v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n", route->input, route->output);
+	v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
+		input, output);
+
 	/* saa7111/3 does not have these inputs */
 	if ((state->ident == V4L2_IDENT_SAA7113 ||
 	     state->ident == V4L2_IDENT_SAA7111) &&
-	    (route->input == SAA7115_COMPOSITE4 ||
-	     route->input == SAA7115_COMPOSITE5)) {
+	    (input == SAA7115_COMPOSITE4 ||
+	     input == SAA7115_COMPOSITE5)) {
 		return -EINVAL;
 	}
-	if (route->input > SAA7115_SVIDEO3)
+	if (input > SAA7115_SVIDEO3)
 		return -EINVAL;
-	if (route->output > SAA7115_IPORT_ON)
+	if (output > SAA7115_IPORT_ON)
 		return -EINVAL;
-	if (state->input == route->input && state->output == route->output)
+	if (state->input == input && state->output == output)
 		return 0;
 	v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
-		(route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
-		(route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
-	state->input = route->input;
+		(input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
+		(output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
+	state->input = input;
 
 	/* saa7111 has slightly different input numbering */
 	if (state->ident == V4L2_IDENT_SAA7111) {
@@ -1260,10 +1262,10 @@
 		/* saa7111 specific */
 		saa711x_write(sd, R_10_CHROMA_CNTL_2,
 				(saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
-				((route->output & 0xc0) ^ 0x40));
+				((output & 0xc0) ^ 0x40));
 		saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
 				(saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
-				((route->output & 2) ? 0x0a : 0));
+				((output & 2) ? 0x0a : 0));
 	}
 
 	/* select mode */
@@ -1276,7 +1278,7 @@
 			(saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
 			(state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
 
-	state->output = route->output;
+	state->output = output;
 	if (state->ident == V4L2_IDENT_SAA7114 ||
 			state->ident == V4L2_IDENT_SAA7115) {
 		saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 128bb8b..2fe7a70 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -570,15 +570,16 @@
 	return saa7127_set_std(sd, std);
 }
 
-static int saa7127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa7127_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct saa7127_state *state = to_state(sd);
 	int rc = 0;
 
-	if (state->input_type != route->input)
-		rc = saa7127_set_input_type(sd, route->input);
-	if (rc == 0 && state->output_type != route->output)
-		rc = saa7127_set_output_type(sd, route->output);
+	if (state->input_type != input)
+		rc = saa7127_set_input_type(sd, input);
+	if (rc == 0 && state->output_type != output)
+		rc = saa7127_set_output_type(sd, output);
 	return rc;
 }
 
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index b73801c..b15c409 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -1104,22 +1104,22 @@
 	},
 };
 
-static int saa717x_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa717x_s_video_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
 {
 	struct saa717x_state *decoder = to_state(sd);
-	int inp = route->input;
-	int is_tuner = inp & 0x80;  /* tuner input flag */
+	int is_tuner = input & 0x80;  /* tuner input flag */
 
-	inp &= 0x7f;
+	input &= 0x7f;
 
-	v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", inp);
+	v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input);
 	/* inputs from 0-9 are available*/
 	/* saa717x have mode0-mode9 but mode5 is reserved. */
-	if (inp < 0 || inp > 9 || inp == 5)
+	if (input < 0 || input > 9 || input == 5)
 		return -EINVAL;
 
-	if (decoder->input != inp) {
-		int input_line = inp;
+	if (decoder->input != input) {
+		int input_line = input;
 
 		decoder->input = input_line;
 		v4l2_dbg(1, debug, sd,  "now setting %s input %d\n",
@@ -1276,12 +1276,13 @@
 	return 0;
 }
 
-static int saa717x_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa717x_s_audio_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
 {
 	struct saa717x_state *decoder = to_state(sd);
 
-	if (route->input < 3) { /* FIXME! --tadachi */
-		decoder->audio_input = route->input;
+	if (input < 3) { /* FIXME! --tadachi */
+		decoder->audio_input = input;
 		v4l2_dbg(1, debug, sd,
 				"set decoder audio input to %d\n",
 				decoder->audio_input);
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
index 75747b1..212baa1 100644
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/video/saa7185.c
@@ -245,14 +245,15 @@
 	return 0;
 }
 
-static int saa7185_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa7185_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct saa7185 *encoder = to_saa7185(sd);
 
-	/* RJ: route->input = 0: input is from SA7111
-	 route->input = 1: input is from ZR36060 */
+	/* RJ: input = 0: input is from SA7111
+	 input = 1: input is from ZR36060 */
 
-	switch (route->input) {
+	switch (input) {
 	case 0:
 		/* turn off colorbar */
 		saa7185_write(sd, 0x3a, 0x0f);
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index 13ab4f2..a251377 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -160,14 +160,14 @@
 /* Helper functions */
 
 static int saa7191_s_routing(struct v4l2_subdev *sd,
-				const struct v4l2_routing *route)
+			     u32 input, u32 output, u32 config)
 {
 	struct saa7191 *decoder = to_saa7191(sd);
 	u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA);
 	u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK);
 	int err;
 
-	switch (route->input) {
+	switch (input) {
 	case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
 		iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
 			  | SAA7191_IOCK_GPSW2);
@@ -190,7 +190,7 @@
 	if (err)
 		return -EIO;
 
-	decoder->input = route->input;
+	decoder->input = input;
 
 	return 0;
 }
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index ff696d1..d4a9ed4 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -47,12 +47,11 @@
 
 
 /* makes a connection between the input-pin 'i' and the output-pin 'o' */
-static int tea6415c_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int tea6415c_s_routing(struct v4l2_subdev *sd,
+			      u32 i, u32 o, u32 config)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	u8 byte = 0;
-	u32 i = route->input;
-	u32 o = route->output;
 	int ret;
 
 	v4l2_dbg(1, debug, sd, "i=%d, o=%d\n", i, o);
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index 8a55b46..ced6ead 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -48,15 +48,15 @@
 
 /* make a connection between the input 'i' and the output 'o'
    with gain 'g' (note: i = 6 means 'mute') */
-static int tea6420_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int tea6420_s_routing(struct v4l2_subdev *sd,
+			     u32 i, u32 o, u32 config)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	int i = route->input;
-	int o = route->output & 0xf;
-	int g = (route->output >> 4) & 0xf;
+	int g = (o >> 4) & 0xf;
 	u8 byte;
 	int ret;
 
+	o &= 0xf;
 	v4l2_dbg(1, debug, sd, "i=%d, o=%d, g=%d\n", i, o, g);
 
 	/* check if the parameters are valid */
@@ -133,13 +133,8 @@
 
 	/* set initial values: set "mute"-input to all outputs at gain 0 */
 	err = 0;
-	for (i = 1; i < 5; i++) {
-		struct v4l2_routing route;
-
-		route.input = 6;
-		route.output = i;
-		err += tea6420_s_routing(sd, &route);
-	}
+	for (i = 1; i < 5; i++)
+		err += tea6420_s_routing(sd, 6, i, 0);
 	if (err) {
 		v4l_dbg(1, debug, client, "could not initialize tea6420\n");
 		return -ENODEV;
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 17d50e3..0869baf 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -1781,17 +1781,18 @@
 	return -EINVAL;
 }
 
-static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
+static int tvaudio_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct CHIPSTATE *chip = to_state(sd);
 	struct CHIPDESC *desc = chip->desc;
 
 	if (!(desc->flags & CHIP_HAS_INPUTSEL))
 		return 0;
-	if (rt->input >= 4)
+	if (input >= 4)
 		return -EINVAL;
 	/* There are four inputs: tuner, radio, extern and intern. */
-	chip->input = rt->input;
+	chip->input = input;
 	if (chip->muted)
 		return 0;
 	chip_write_masked(chip, desc->inputreg,
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 4aea84a..2d38e25 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -69,7 +69,8 @@
 	struct v4l2_subdev sd;
 
 	v4l2_std_id norm;	/* Current set standard */
-	struct v4l2_routing route;
+	u32 input;
+	u32 output;
 	int enable;
 	int bright;
 	int contrast;
@@ -280,10 +281,10 @@
 	int input = 0;
 	unsigned char val;
 
-	if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable)
+	if ((decoder->output & TVP5150_BLACK_SCREEN) || !decoder->enable)
 		input = 8;
 
-	switch (decoder->route.input) {
+	switch (decoder->input) {
 	case TVP5150_COMPOSITE1:
 		input |= 2;
 		/* fall through */
@@ -299,8 +300,8 @@
 
 	v4l2_dbg(1, debug, sd, "Selecting video route: route input=%i, output=%i "
 			"=> tvp5150 input=%i, opmode=%i\n",
-			decoder->route.input,decoder->route.output,
-			input, opmode );
+			decoder->input, decoder->output,
+			input, opmode);
 
 	tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode);
 	tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input);
@@ -309,7 +310,7 @@
 	 * For Composite and TV, it should be the reverse
 	 */
 	val = tvp5150_read(sd, TVP5150_MISC_CTL);
-	if (decoder->route.input == TVP5150_SVIDEO)
+	if (decoder->input == TVP5150_SVIDEO)
 		val = (val & ~0x40) | 0x10;
 	else
 		val = (val & ~0x10) | 0x40;
@@ -878,11 +879,13 @@
 			I2C Command
  ****************************************************************************/
 
-static int tvp5150_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int tvp5150_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct tvp5150 *decoder = to_tvp5150(sd);
 
-	decoder->route = *route;
+	decoder->input = input;
+	decoder->output = output;
 	tvp5150_selmux(sd);
 	return 0;
 }
@@ -1077,7 +1080,7 @@
 		 c->addr << 1, c->adapter->name);
 
 	core->norm = V4L2_STD_ALL;	/* Default is autodetect */
-	core->route.input = TVP5150_COMPOSITE1;
+	core->input = TVP5150_COMPOSITE1;
 	core->enable = 1;
 	core->bright = 128;
 	core->contrast = 128;
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index c0ac651..a07a3fb 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -124,17 +124,18 @@
 
 /* ------------------------------------------------------------------------ */
 
-static int upd64031a_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int upd64031a_s_routing(struct v4l2_subdev *sd,
+			       u32 input, u32 output, u32 config)
 {
 	struct upd64031a_state *state = to_state(sd);
 	u8 r00, r05, r08;
 
-	state->gr_mode = (route->input & 3) << 6;
-	state->direct_3dycs_connect = (route->input & 0xc) << 4;
+	state->gr_mode = (input & 3) << 6;
+	state->direct_3dycs_connect = (input & 0xc) << 4;
 	state->ext_comp_sync =
-		(route->input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
+		(input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
 	state->ext_vert_sync =
-		(route->input & UPD64031A_VERTICAL_EXTERNAL) << 2;
+		(input & UPD64031A_VERTICAL_EXTERNAL) << 2;
 	r00 = (state->regs[R00] & ~GR_MODE_MASK) | state->gr_mode;
 	r05 = (state->regs[R00] & ~SYNC_CIRCUIT_MASK) |
 		state->ext_comp_sync | state->ext_vert_sync;
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 410c915..6eb0e5b 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -102,15 +102,16 @@
 
 /* ------------------------------------------------------------------------ */
 
-static int upd64083_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int upd64083_s_routing(struct v4l2_subdev *sd,
+			      u32 input, u32 output, u32 config)
 {
 	struct upd64083_state *state = to_state(sd);
 	u8 r00, r02;
 
-	if (route->input > 7 || (route->input & 6) == 6)
+	if (input > 7 || (input & 6) == 6)
 		return -EINVAL;
-	state->mode = (route->input & 3) << 6;
-	state->ext_y_adc = (route->input & UPD64083_EXT_Y_ADC) << 3;
+	state->mode = (input & 3) << 6;
+	state->ext_y_adc = (input & UPD64083_EXT_Y_ADC) << 3;
 	r00 = (state->regs[R00] & ~(3 << 6)) | state->mode;
 	r02 = (state->regs[R02] & ~(1 << 5)) | state->ext_y_adc;
 	upd64083_write(sd, R00, r00);
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index a0feb1c..8bc03b9 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -2597,7 +2597,6 @@
 	/* inputs #1 and #2 are variable for SAA7111 and SAA7113 */
 	int mode[4]= {SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3};
 	int audio[]= {1, 0, 0, 0};
-	struct v4l2_routing route;
 	//channel 0 is TV with audiochannel 1 (tuner mono)
 	//channel 1 is Composite with audio channel 0 (line in)
 	//channel 2 is S-Video with audio channel 0 (line in)
@@ -2630,9 +2629,7 @@
 			mode[2] = SAA7115_SVIDEO1;
 			break;
 	}
-	route.input = mode[channel];
-	route.output = 0;
-	call_all(usbvision, video, s_routing, &route);
+	call_all(usbvision, video, s_routing, mode[channel], 0, 0);
 	usbvision_set_audio(usbvision, audio[channel]);
 	return 0;
 }
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 2fb7454..43e0998 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -2565,12 +2565,11 @@
 		int input;
 		int data_norm;
 		v4l2_std_id norm;
-		struct v4l2_routing route = { 0, 0 };
 
 		input = VINO_INPUT_COMPOSITE;
 
-		route.input = vino_get_saa7191_input(input);
-		ret = decoder_call(video, s_routing, &route);
+		ret = decoder_call(video, s_routing,
+				vino_get_saa7191_input(input), 0, 0);
 		if (ret) {
 			ret = -EINVAL;
 			goto out;
@@ -2656,10 +2655,9 @@
 		if (vino_drvdata->decoder_owner == vcs->channel) {
 			int data_norm;
 			v4l2_std_id norm;
-			struct v4l2_routing route = { 0, 0 };
 
-			route.input = vino_get_saa7191_input(input);
-			ret = decoder_call(video, s_routing, &route);
+			ret = decoder_call(video, s_routing,
+					vino_get_saa7191_input(input), 0, 0);
 			if (ret) {
 				vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
 				ret = -EINVAL;
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 59a8bb0..97e0ce2 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -376,33 +376,34 @@
 	return 0;
 }
 
-static int vpx3220_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int vpx3220_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	int data;
 
-	/* RJ:   route->input = 0: ST8 (PCTV) input
-		 route->input = 1: COMPOSITE  input
-		 route->input = 2: SVHS       input  */
+	/* RJ:   input = 0: ST8 (PCTV) input
+		 input = 1: COMPOSITE  input
+		 input = 2: SVHS       input  */
 
-	const int input[3][2] = {
+	const int input_vals[3][2] = {
 		{0x0c, 0},
 		{0x0d, 0},
 		{0x0e, 1}
 	};
 
-	if (route->input < 0 || route->input > 2)
+	if (input < 0 || input > 2)
 		return -EINVAL;
 
-	v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[route->input]);
+	v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]);
 
-	vpx3220_write(sd, 0x33, input[route->input][0]);
+	vpx3220_write(sd, 0x33, input_vals[input][0]);
 
 	data = vpx3220_fp_read(sd, 0xf2) & ~(0x0020);
 	if (data < 0)
 		return data;
 	/* 0x0010 is required to latch the setting */
 	vpx3220_fp_write(sd, 0xf2,
-			data | (input[route->input][1] << 5) | 0x0010);
+			data | (input_vals[input][1] << 5) | 0x0010);
 
 	udelay(10);
 	return 0;
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index eddf11a..f1f261a 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -79,7 +79,8 @@
 	return -1;
 }
 
-static int wm8775_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int wm8775_s_routing(struct v4l2_subdev *sd,
+			    u32 input, u32 output, u32 config)
 {
 	struct wm8775_state *state = to_state(sd);
 
@@ -88,11 +89,11 @@
 	   16 combinations.
 	   If only one input is active (the normal case) then the
 	   input values 1, 2, 4 or 8 should be used. */
-	if (route->input > 15) {
-		v4l2_err(sd, "Invalid input %d.\n", route->input);
+	if (input > 15) {
+		v4l2_err(sd, "Invalid input %d.\n", input);
 		return -EINVAL;
 	}
-	state->input = route->input;
+	state->input = input;
 	if (state->muted)
 		return 0;
 	wm8775_write(sd, R21, 0x0c0);
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 1ef70b0..ea6c577 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -1087,10 +1087,8 @@
 		detect_guest_activity(zr);
 	test_interrupts(zr);
 	if (!pass_through) {
-		struct v4l2_routing route = { 2, 0 };
-
 		decoder_call(zr, video, s_stream, 0);
-		encoder_call(zr, video, s_routing, &route);
+		encoder_call(zr, video, s_routing, 2, 0, 0);
 	}
 
 	zr->zoran_proc = NULL;
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c
index 25e565f..f6c2fb4 100644
--- a/drivers/media/video/zoran/zoran_device.c
+++ b/drivers/media/video/zoran/zoran_device.c
@@ -971,7 +971,6 @@
 	struct vfe_settings cap;
 	int field_size =
 	    zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff;
-	struct v4l2_routing route = { 0, 0 };
 
 	zr->codec_mode = mode;
 
@@ -994,8 +993,7 @@
 		 */
 		set_videobus_dir(zr, 0);
 		decoder_call(zr, video, s_stream, 1);
-		route.input = 0;
-		encoder_call(zr, video, s_routing, &route);
+		encoder_call(zr, video, s_routing, 0, 0, 0);
 
 		/* Take the JPEG codec and the VFE out of sleep */
 		jpeg_codec_sleep(zr, 0);
@@ -1043,8 +1041,7 @@
 		 */
 		decoder_call(zr, video, s_stream, 0);
 		set_videobus_dir(zr, 1);
-		route.input = 1;
-		encoder_call(zr, video, s_routing, &route);
+		encoder_call(zr, video, s_routing, 1, 0, 0);
 
 		/* Take the JPEG codec and the VFE out of sleep */
 		jpeg_codec_sleep(zr, 0);
@@ -1089,8 +1086,7 @@
 		zr36057_adjust_vfe(zr, mode);
 
 		decoder_call(zr, video, s_stream, 1);
-		route.input = 0;
-		encoder_call(zr, video, s_routing, &route);
+		encoder_call(zr, video, s_routing, 0, 0, 0);
 
 		dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr));
 		break;
@@ -1571,8 +1567,6 @@
 void
 zoran_init_hardware (struct zoran *zr)
 {
-	struct v4l2_routing route = { 0, 0 };
-
 	/* Enable bus-mastering */
 	zoran_set_pci_master(zr, 1);
 
@@ -1581,16 +1575,14 @@
 		zr->card.init(zr);
 	}
 
-	route.input = zr->card.input[zr->input].muxsel;
-
 	decoder_call(zr, core, init, 0);
 	decoder_call(zr, core, s_std, zr->norm);
-	decoder_call(zr, video, s_routing, &route);
+	decoder_call(zr, video, s_routing,
+		zr->card.input[zr->input].muxsel, 0, 0);
 
 	encoder_call(zr, core, init, 0);
 	encoder_call(zr, video, s_std_output, zr->norm);
-	route.input = 0;
-	encoder_call(zr, video, s_routing, &route);
+	encoder_call(zr, video, s_routing, 0, 0, 0);
 
 	/* toggle JPEG codec sleep to sync PLL */
 	jpeg_codec_sleep(zr, 1);
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 979e8d0..092333b 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -1018,10 +1018,8 @@
 		zoran_set_pci_master(zr, 0);
 
 		if (!pass_through) {	/* Switch to color bar */
-			struct v4l2_routing route = { 2, 0 };
-
 			decoder_call(zr, video, s_stream, 0);
-			encoder_call(zr, video, s_routing, &route);
+			encoder_call(zr, video, s_routing, 2, 0, 0);
 		}
 	}
 
@@ -1496,8 +1494,6 @@
 zoran_set_input (struct zoran *zr,
 		 int           input)
 {
-	struct v4l2_routing route = { 0, 0 };
-
 	if (input == zr->input) {
 		return 0;
 	}
@@ -1519,10 +1515,10 @@
 		return -EINVAL;
 	}
 
-	route.input = zr->card.input[input].muxsel;
 	zr->input = input;
 
-	decoder_call(zr, video, s_routing, &route);
+	decoder_call(zr, video, s_routing,
+			zr->card.input[input].muxsel, 0, 0);
 
 	return 0;
 }
@@ -1748,7 +1744,6 @@
 	case BUZIOC_G_STATUS:
 	{
 		struct zoran_status *bstat = arg;
-		struct v4l2_routing route = { 0, 0 };
 		int status = 0, res = 0;
 		v4l2_std_id norm;
 
@@ -1762,8 +1757,6 @@
 			return -EINVAL;
 		}
 
-		route.input = zr->card.input[bstat->input].muxsel;
-
 		mutex_lock(&zr->resource_lock);
 
 		if (zr->codec_mode != BUZ_MODE_IDLE) {
@@ -1775,7 +1768,8 @@
 			goto gstat_unlock_and_return;
 		}
 
-		decoder_call(zr, video, s_routing, &route);
+		decoder_call(zr, video, s_routing,
+				zr->card.input[bstat->input].muxsel, 0, 0);
 
 		/* sleep 1 second */
 		ssleep(1);
@@ -1785,8 +1779,8 @@
 		decoder_call(zr, video, g_input_status, &status);
 
 		/* restore previous input and norm */
-		route.input = zr->card.input[zr->input].muxsel;
-		decoder_call(zr, video, s_routing, &route);
+		decoder_call(zr, video, s_routing,
+				zr->card.input[zr->input].muxsel, 0, 0);
 gstat_unlock_and_return:
 		mutex_unlock(&zr->resource_lock);