aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2007-11-26 00:07:26 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:03:05 -0500
commitf5174af201f2e22c101bb02d06343e4bc5f056de (patch)
treea13e51ad387953b17f11360a5cb89d8abc0ea551 /drivers
parentaaf7884db395332ae8474f3ea5bcdd39c0a941ea (diff)
V4L/DVB (6698): pvrusb2: Implement signal routing schemes
The exact routing of video and audio signals within a device is a device-specific attribute. Hauppauge devices do it one way; other types of device may route things differently. Unfortunately it is rather impractical to define chip-specific routing at the device attribute level, so instead what happens here is that "schemes" are defined. Each chip level interface implements its part of a given scheme and the scheme as a whole is made into a device specific attribute controlled via a table entry in pvrusb2-devattr.c. The only scheme defined here is for Hauppauge devices, but clearly this opens the door for other possibilities to follow. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c62
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c69
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h9
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c51
5 files changed, 140 insertions, 53 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 379645e481c6..9a7c8e9c3e8b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -35,34 +35,58 @@ struct pvr2_msp3400_handler {
35}; 35};
36 36
37 37
38
39struct routing_scheme {
40 const int *def;
41 unsigned int cnt;
42};
43
44static const int routing_scheme0[] = {
45 [PVR2_CVAL_INPUT_TV] = MSP_INPUT_DEFAULT,
46 [PVR2_CVAL_INPUT_RADIO] = MSP_INPUT(MSP_IN_SCART2,
47 MSP_IN_TUNER1,
48 MSP_DSP_IN_SCART,
49 MSP_DSP_IN_SCART),
50 [PVR2_CVAL_INPUT_COMPOSITE] = MSP_INPUT(MSP_IN_SCART1,
51 MSP_IN_TUNER1,
52 MSP_DSP_IN_SCART,
53 MSP_DSP_IN_SCART),
54 [PVR2_CVAL_INPUT_SVIDEO] = MSP_INPUT(MSP_IN_SCART1,
55 MSP_IN_TUNER1,
56 MSP_DSP_IN_SCART,
57 MSP_DSP_IN_SCART),
58};
59
60static const struct routing_scheme routing_schemes[] = {
61 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
62 .def = routing_scheme0,
63 .cnt = ARRAY_SIZE(routing_scheme0),
64 },
65};
66
38/* This function selects the correct audio input source */ 67/* This function selects the correct audio input source */
39static void set_stereo(struct pvr2_msp3400_handler *ctxt) 68static void set_stereo(struct pvr2_msp3400_handler *ctxt)
40{ 69{
41 struct pvr2_hdw *hdw = ctxt->hdw; 70 struct pvr2_hdw *hdw = ctxt->hdw;
42 struct v4l2_routing route; 71 struct v4l2_routing route;
72 const struct routing_scheme *sp;
73 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
43 74
44 pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo"); 75 pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo");
45 76
46 route.input = MSP_INPUT_DEFAULT; 77 if ((sid < ARRAY_SIZE(routing_schemes)) &&
47 route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); 78 ((sp = routing_schemes + sid) != 0) &&
48 switch (hdw->input_val) { 79 (hdw->input_val >= 0) &&
49 case PVR2_CVAL_INPUT_TV: 80 (hdw->input_val < sp->cnt)) {
50 break; 81 route.input = sp->def[hdw->input_val];
51 case PVR2_CVAL_INPUT_RADIO: 82 } else {
52 /* Assume that msp34xx also handle FM decoding, in which case 83 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
53 we're still using the tuner. */ 84 "*** WARNING *** i2c msp3400 v4l2 set_stereo:"
54 /* HV: actually it is more likely to be the SCART2 input if 85 " Invalid routing scheme (%u) and/or input (%d)",
55 the ivtv experience is any indication. */ 86 sid,hdw->input_val);
56 route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, 87 return;
57 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
58 break;
59 case PVR2_CVAL_INPUT_SVIDEO:
60 case PVR2_CVAL_INPUT_COMPOSITE:
61 /* SCART 1 input */
62 route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
63 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
64 break;
65 } 88 }
89 route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
66 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); 90 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
67} 91}
68 92
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 2cca817e4144..b6714c41ea75 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -49,34 +49,65 @@ struct pvr2_v4l_cx2584x {
49}; 49};
50 50
51 51
52struct routing_scheme_item {
53 int vid;
54 int aud;
55};
56
57struct routing_scheme {
58 const struct routing_scheme_item *def;
59 unsigned int cnt;
60};
61
62static const struct routing_scheme_item routing_scheme0[] = {
63 [PVR2_CVAL_INPUT_TV] = {
64 .vid = CX25840_COMPOSITE7,
65 .aud = CX25840_AUDIO8,
66 },
67 [PVR2_CVAL_INPUT_RADIO] = { /* Treat the same as composite */
68 .vid = CX25840_COMPOSITE3,
69 .aud = CX25840_AUDIO_SERIAL,
70 },
71 [PVR2_CVAL_INPUT_COMPOSITE] = {
72 .vid = CX25840_COMPOSITE3,
73 .aud = CX25840_AUDIO_SERIAL,
74 },
75 [PVR2_CVAL_INPUT_SVIDEO] = {
76 .vid = CX25840_SVIDEO1,
77 .aud = CX25840_AUDIO_SERIAL,
78 },
79};
80
81static const struct routing_scheme routing_schemes[] = {
82 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
83 .def = routing_scheme0,
84 .cnt = ARRAY_SIZE(routing_scheme0),
85 },
86};
87
52static void set_input(struct pvr2_v4l_cx2584x *ctxt) 88static void set_input(struct pvr2_v4l_cx2584x *ctxt)
53{ 89{
54 struct pvr2_hdw *hdw = ctxt->hdw; 90 struct pvr2_hdw *hdw = ctxt->hdw;
55 struct v4l2_routing route; 91 struct v4l2_routing route;
56 enum cx25840_video_input vid_input; 92 enum cx25840_video_input vid_input;
57 enum cx25840_audio_input aud_input; 93 enum cx25840_audio_input aud_input;
94 const struct routing_scheme *sp;
95 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
58 96
59 memset(&route,0,sizeof(route)); 97 memset(&route,0,sizeof(route));
60 98
61 switch(hdw->input_val) { 99 if ((sid < ARRAY_SIZE(routing_schemes)) &&
62 case PVR2_CVAL_INPUT_TV: 100 ((sp = routing_schemes + sid) != 0) &&
63 vid_input = CX25840_COMPOSITE7; 101 (hdw->input_val >= 0) &&
64 aud_input = CX25840_AUDIO8; 102 (hdw->input_val < sp->cnt)) {
65 break; 103 vid_input = sp->def[hdw->input_val].vid;
66 case PVR2_CVAL_INPUT_RADIO: // Treat same as composite 104 aud_input = sp->def[hdw->input_val].aud;
67 case PVR2_CVAL_INPUT_COMPOSITE: 105 } else {
68 vid_input = CX25840_COMPOSITE3; 106 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
69 aud_input = CX25840_AUDIO_SERIAL; 107 "*** WARNING *** i2c cx2584x set_input:"
70 break; 108 " Invalid routing scheme (%u) and/or input (%d)",
71 case PVR2_CVAL_INPUT_SVIDEO: 109 sid,hdw->input_val);
72 vid_input = CX25840_SVIDEO1; 110 return;
73 aud_input = CX25840_AUDIO_SERIAL;
74 break;
75 default:
76 // Just set it to be composite input for now...
77 vid_input = CX25840_COMPOSITE3;
78 aud_input = CX25840_AUDIO_SERIAL;
79 break;
80 } 111 }
81 112
82 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x", 113 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x",
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 54a401e8bb14..464a13a06494 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -73,6 +73,7 @@ const struct pvr2_device_desc pvr2_device_descriptions[] = {
73 .fx2_firmware.lst = pvr2_fw1_names_29xxx, 73 .fx2_firmware.lst = pvr2_fw1_names_29xxx,
74 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx), 74 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx),
75 .flag_has_hauppauge_rom = !0, 75 .flag_has_hauppauge_rom = !0,
76 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
76 }, 77 },
77 [PVR2_HDW_TYPE_24XXX] = { 78 [PVR2_HDW_TYPE_24XXX] = {
78 .description = "WinTV PVR USB2 Model Category 24xxxx", 79 .description = "WinTV PVR USB2 Model Category 24xxxx",
@@ -84,6 +85,7 @@ const struct pvr2_device_desc pvr2_device_descriptions[] = {
84 .flag_has_cx25840 = !0, 85 .flag_has_cx25840 = !0,
85 .flag_has_wm8775 = !0, 86 .flag_has_wm8775 = !0,
86 .flag_has_hauppauge_rom = !0, 87 .flag_has_hauppauge_rom = !0,
88 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
87 }, 89 },
88}; 90};
89 91
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index f63c3ddb8a72..05eb2c669ee8 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -35,6 +35,7 @@ struct pvr2_string_table {
35 unsigned int cnt; 35 unsigned int cnt;
36}; 36};
37 37
38#define PVR2_ROUTING_SCHEME_HAUPPAUGE 0
38 39
39/* This describes a particular hardware type (except for the USB device ID 40/* This describes a particular hardware type (except for the USB device ID
40 which must live in a separate structure due to environmental 41 which must live in a separate structure due to environmental
@@ -55,6 +56,14 @@ struct pvr2_device_desc {
55 was initialized from internal ROM. */ 56 was initialized from internal ROM. */
56 struct pvr2_string_table fx2_firmware; 57 struct pvr2_string_table fx2_firmware;
57 58
59 /* Signal routing scheme used by device, contains one of
60 PVR2_ROUTING_SCHEME_XXX. Schemes have to be defined as we
61 encounter them. This is an arbitrary integer scheme id; its
62 meaning is contained entirely within the driver and is
63 interpreted by logic which must send commands to the chip-level
64 drivers (search for things which touch this field). */
65 unsigned int signal_routing_scheme;
66
58 /* V4L tuner type ID to use with this device (only used if the 67 /* V4L tuner type ID to use with this device (only used if the
59 driver could not discover the type any other way). */ 68 driver could not discover the type any other way). */
60 int default_tuner_type; 69 int default_tuner_type;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index 767e49022f9b..7c47345501b6 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -49,29 +49,50 @@ struct pvr2_v4l_decoder {
49}; 49};
50 50
51 51
52struct routing_scheme {
53 const int *def;
54 unsigned int cnt;
55};
56
57
58static const int routing_scheme0[] = {
59 [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
60 /* In radio mode, we mute the video, but point at one
61 spot just to stay consistent */
62 [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
63 [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE5,
64 [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2,
65};
66
67static const struct routing_scheme routing_schemes[] = {
68 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
69 .def = routing_scheme0,
70 .cnt = ARRAY_SIZE(routing_scheme0),
71 },
72};
73
52static void set_input(struct pvr2_v4l_decoder *ctxt) 74static void set_input(struct pvr2_v4l_decoder *ctxt)
53{ 75{
54 struct pvr2_hdw *hdw = ctxt->hdw; 76 struct pvr2_hdw *hdw = ctxt->hdw;
55 struct v4l2_routing route; 77 struct v4l2_routing route;
78 const struct routing_scheme *sp;
79 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
56 80
57 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val); 81 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val);
58 switch(hdw->input_val) { 82
59 case PVR2_CVAL_INPUT_TV: 83 if ((sid < ARRAY_SIZE(routing_schemes)) &&
60 route.input = SAA7115_COMPOSITE4; 84 ((sp = routing_schemes + sid) != 0) &&
61 break; 85 (hdw->input_val >= 0) &&
62 case PVR2_CVAL_INPUT_COMPOSITE: 86 (hdw->input_val < sp->cnt)) {
63 route.input = SAA7115_COMPOSITE5; 87 route.input = sp->def[hdw->input_val];
64 break; 88 } else {
65 case PVR2_CVAL_INPUT_SVIDEO: 89 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
66 route.input = SAA7115_SVIDEO2; 90 "*** WARNING *** i2c v4l2 set_input:"
67 break; 91 " Invalid routing scheme (%u) and/or input (%d)",
68 case PVR2_CVAL_INPUT_RADIO: 92 sid,hdw->input_val);
69 // In radio mode, we mute the video, but point at one
70 // spot just to stay consistent
71 route.input = SAA7115_COMPOSITE5;
72 default:
73 return; 93 return;
74 } 94 }
95
75 route.output = 0; 96 route.output = 0;
76 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); 97 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
77} 98}