aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx25840
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2006-01-09 12:25:42 -0500
committerMauro Carvalho Chehab <mchehab@brturbo.com.br>2006-01-09 12:25:42 -0500
commita8bbf12ad8a8ad532cea0b67f0127ad90d336b04 (patch)
treebd8d9fb0888a7fe28b4795d7567c01ccf72b3c38 /drivers/media/video/cx25840
parent3578d3dd0b1e468a44a76a83efe90476a854625d (diff)
V4L/DVB (3249): Generalized cx25840 video/audio input handling
- Added VIDIOC_S_AUDIO to set the audio inputs separately. - Removed AUDC_SET_INPUT. - Made the video inputs much more general. - Removed cardtype CID and replaced with a CID to enable the PVR150 workaround. The cardtype is no longer necessary with the general video input change. - Update VIDIOC_LOG_STATUS output to show the video and audio inputs separately. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'drivers/media/video/cx25840')
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c51
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c180
-rw-r--r--drivers/media/video/cx25840/cx25840.h63
3 files changed, 153 insertions, 141 deletions
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 6c44bd9c1704..fe6bc411d71f 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -37,8 +37,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
37 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ 37 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
38 cx25840_write(client, 0x127, 0x50); 38 cx25840_write(client, 0x127, 0x50);
39 39
40 switch (state->audio_input) { 40 if (state->aud_input != CX25840_AUDIO_SERIAL) {
41 case AUDIO_TUNER:
42 switch (freq) { 41 switch (freq) {
43 case 32000: 42 case 32000:
44 /* VID_PLL and AUX_PLL */ 43 /* VID_PLL and AUX_PLL */
@@ -79,12 +78,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
79 cx25840_write4(client, 0x90c, 0xaa4f0108); 78 cx25840_write4(client, 0x90c, 0xaa4f0108);
80 break; 79 break;
81 } 80 }
82 break; 81 } else {
83
84 case AUDIO_EXTERN_1:
85 case AUDIO_EXTERN_2:
86 case AUDIO_INTERN:
87 case AUDIO_RADIO:
88 switch (freq) { 82 switch (freq) {
89 case 32000: 83 case 32000:
90 /* VID_PLL and AUX_PLL */ 84 /* VID_PLL and AUX_PLL */
@@ -137,7 +131,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
137 cx25840_write4(client, 0x90c, 0x55550108); 131 cx25840_write4(client, 0x90c, 0x55550108);
138 break; 132 break;
139 } 133 }
140 break;
141 } 134 }
142 135
143 /* deassert soft reset */ 136 /* deassert soft reset */
@@ -148,48 +141,33 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
148 return 0; 141 return 0;
149} 142}
150 143
151static int set_input(struct i2c_client *client, int audio_input) 144void cx25840_audio_set_path(struct i2c_client *client)
152{ 145{
153 struct cx25840_state *state = i2c_get_clientdata(client); 146 struct cx25840_state *state = i2c_get_clientdata(client);
154 147
155 cx25840_dbg("set audio input (%d)\n", audio_input);
156
157 /* stop microcontroller */ 148 /* stop microcontroller */
158 cx25840_and_or(client, 0x803, ~0x10, 0); 149 cx25840_and_or(client, 0x803, ~0x10, 0);
159 150
160 /* Mute everything to prevent the PFFT! */ 151 /* Mute everything to prevent the PFFT! */
161 cx25840_write(client, 0x8d3, 0x1f); 152 cx25840_write(client, 0x8d3, 0x1f);
162 153
163 switch (audio_input) { 154 if (state->aud_input == CX25840_AUDIO_SERIAL) {
164 case AUDIO_TUNER:
165 /* Set Path1 to Analog Demod Main Channel */
166 cx25840_write4(client, 0x8d0, 0x7038061f);
167
168 /* When the microcontroller detects the
169 * audio format, it will unmute the lines */
170 cx25840_and_or(client, 0x803, ~0x10, 0x10);
171 break;
172
173 case AUDIO_EXTERN_1:
174 case AUDIO_EXTERN_2:
175 case AUDIO_INTERN:
176 case AUDIO_RADIO:
177 /* Set Path1 to Serial Audio Input */ 155 /* Set Path1 to Serial Audio Input */
178 cx25840_write4(client, 0x8d0, 0x12100101); 156 cx25840_write4(client, 0x8d0, 0x12100101);
179 157
180 /* The microcontroller should not be started for the 158 /* The microcontroller should not be started for the
181 * non-tuner inputs: autodetection is specific for 159 * non-tuner inputs: autodetection is specific for
182 * TV audio. */ 160 * TV audio. */
183 break; 161 } else {
162 /* Set Path1 to Analog Demod Main Channel */
163 cx25840_write4(client, 0x8d0, 0x7038061f);
184 164
185 default: 165 /* When the microcontroller detects the
186 cx25840_dbg("Invalid audio input selection %d\n", audio_input); 166 * audio format, it will unmute the lines */
187 return -EINVAL; 167 cx25840_and_or(client, 0x803, ~0x10, 0x10);
188 } 168 }
189 169
190 state->audio_input = audio_input; 170 set_audclk_freq(client, state->audclk_freq);
191
192 return set_audclk_freq(client, state->audclk_freq);
193} 171}
194 172
195inline static int get_volume(struct i2c_client *client) 173inline static int get_volume(struct i2c_client *client)
@@ -292,7 +270,7 @@ inline static void set_mute(struct i2c_client *client, int mute)
292{ 270{
293 struct cx25840_state *state = i2c_get_clientdata(client); 271 struct cx25840_state *state = i2c_get_clientdata(client);
294 272
295 if (state->audio_input == AUDIO_TUNER) { 273 if (state->aud_input != CX25840_AUDIO_SERIAL) {
296 /* Must turn off microcontroller in order to mute sound. 274 /* Must turn off microcontroller in order to mute sound.
297 * Not sure if this is the best method, but it does work. 275 * Not sure if this is the best method, but it does work.
298 * If the microcontroller is running, then it will undo any 276 * If the microcontroller is running, then it will undo any
@@ -316,10 +294,9 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
316 struct v4l2_control *ctrl = arg; 294 struct v4l2_control *ctrl = arg;
317 295
318 switch (cmd) { 296 switch (cmd) {
319 case AUDC_SET_INPUT:
320 return set_input(client, *(int *)arg);
321 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 297 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
322 return set_audclk_freq(client, *(u32 *)arg); 298 return set_audclk_freq(client, *(u32 *)arg);
299
323 case VIDIOC_G_CTRL: 300 case VIDIOC_G_CTRL:
324 switch (ctrl->id) { 301 switch (ctrl->id) {
325 case V4L2_CID_AUDIO_VOLUME: 302 case V4L2_CID_AUDIO_VOLUME:
@@ -341,6 +318,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
341 return -EINVAL; 318 return -EINVAL;
342 } 319 }
343 break; 320 break;
321
344 case VIDIOC_S_CTRL: 322 case VIDIOC_S_CTRL:
345 switch (ctrl->id) { 323 switch (ctrl->id) {
346 case V4L2_CID_AUDIO_VOLUME: 324 case V4L2_CID_AUDIO_VOLUME:
@@ -362,6 +340,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
362 return -EINVAL; 340 return -EINVAL;
363 } 341 }
364 break; 342 break;
343
365 default: 344 default:
366 return -EINVAL; 345 return -EINVAL;
367 } 346 }
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index c2c1e856aa60..a897d6b7d708 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -115,8 +115,8 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask,
115 115
116/* ----------------------------------------------------------------------- */ 116/* ----------------------------------------------------------------------- */
117 117
118static int set_input(struct i2c_client *, enum cx25840_input); 118static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
119static void input_change(struct i2c_client *); 119 enum cx25840_audio_input aud_input);
120static void log_status(struct i2c_client *client); 120static void log_status(struct i2c_client *client);
121 121
122/* ----------------------------------------------------------------------- */ 122/* ----------------------------------------------------------------------- */
@@ -195,10 +195,8 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw)
195 /* AC97 shift */ 195 /* AC97 shift */
196 cx25840_write(client, 0x8cf, 0x0f); 196 cx25840_write(client, 0x8cf, 0x0f);
197 197
198 /* (re)set video input */ 198 /* (re)set input */
199 set_input(client, state->input); 199 set_input(client, state->vid_input, state->aud_input);
200 /* (re)set audio input */
201 cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input);
202 200
203 /* start microcontroller */ 201 /* start microcontroller */
204 cx25840_and_or(client, 0x803, ~0x10, 0x10); 202 cx25840_and_or(client, 0x803, ~0x10, 0x10);
@@ -223,7 +221,7 @@ static void input_change(struct i2c_client *client)
223 cx25840_write(client, 0x80b, 0x10); 221 cx25840_write(client, 0x80b, 0x10);
224 } else if (std & V4L2_STD_NTSC) { 222 } else if (std & V4L2_STD_NTSC) {
225 /* NTSC */ 223 /* NTSC */
226 if (state->cardtype == CARDTYPE_PVR150_WORKAROUND) { 224 if (state->pvr150_workaround) {
227 /* Certain Hauppauge PVR150 models have a hardware bug 225 /* Certain Hauppauge PVR150 models have a hardware bug
228 that causes audio to drop out. For these models the 226 that causes audio to drop out. For these models the
229 audio standard must be set explicitly. 227 audio standard must be set explicitly.
@@ -259,72 +257,68 @@ static void input_change(struct i2c_client *client)
259 } 257 }
260} 258}
261 259
262static int set_input(struct i2c_client *client, enum cx25840_input input) 260static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
261 enum cx25840_audio_input aud_input)
263{ 262{
264 struct cx25840_state *state = i2c_get_clientdata(client); 263 struct cx25840_state *state = i2c_get_clientdata(client);
264 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
265 vid_input <= CX25840_COMPOSITE8);
266 u8 reg;
265 267
266 cx25840_dbg("decoder set input (%d)\n", input); 268 cx25840_dbg("decoder set video input %d, audio input %d\n",
269 vid_input, aud_input);
267 270
268 switch (input) { 271 if (is_composite) {
269 case CX25840_TUNER: 272 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
270 cx25840_dbg("now setting Tuner input\n"); 273 } else {
271 274 int luma = vid_input & 0xf0;
272 if (state->cardtype == CARDTYPE_PVR150 || 275 int chroma = vid_input & 0xf00;
273 state->cardtype == CARDTYPE_PVR150_WORKAROUND) {
274 /* CH_SEL_ADC2=1 */
275 cx25840_and_or(client, 0x102, ~0x2, 0x02);
276 }
277
278 /* Video Input Control */
279 if (state->cardtype == CARDTYPE_PG600) {
280 cx25840_write(client, 0x103, 0x11);
281 } else {
282 cx25840_write(client, 0x103, 0x46);
283 }
284
285 /* INPUT_MODE=0 */
286 cx25840_and_or(client, 0x401, ~0x6, 0x00);
287 break;
288
289 case CX25840_COMPOSITE0:
290 case CX25840_COMPOSITE1:
291 cx25840_dbg("now setting Composite input\n");
292 276
293 /* Video Input Control */ 277 if ((vid_input & ~0xff0) ||
294 if (state->cardtype == CARDTYPE_PG600) { 278 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 ||
295 cx25840_write(client, 0x103, 0x00); 279 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
296 } else { 280 cx25840_err("0x%04x is not a valid video input!\n", vid_input);
297 cx25840_write(client, 0x103, 0x02); 281 return -EINVAL;
298 } 282 }
299 283 reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4);
300 /* INPUT_MODE=0 */ 284 if (chroma >= CX25840_SVIDEO_CHROMA7) {
301 cx25840_and_or(client, 0x401, ~0x6, 0x00); 285 reg &= 0x3f;
302 break; 286 reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2;
303
304 case CX25840_SVIDEO0:
305 case CX25840_SVIDEO1:
306 cx25840_dbg("now setting S-Video input\n");
307
308 /* CH_SEL_ADC2=0 */
309 cx25840_and_or(client, 0x102, ~0x2, 0x00);
310
311 /* Video Input Control */
312 if (state->cardtype == CARDTYPE_PG600) {
313 cx25840_write(client, 0x103, 0x02);
314 } else { 287 } else {
315 cx25840_write(client, 0x103, 0x10); 288 reg &= 0xcf;
289 reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4;
316 } 290 }
291 }
317 292
318 /* INPUT_MODE=1 */ 293 switch (aud_input) {
319 cx25840_and_or(client, 0x401, ~0x6, 0x02); 294 case CX25840_AUDIO_SERIAL:
295 /* do nothing, use serial audio input */
320 break; 296 break;
297 case CX25840_AUDIO4: reg &= ~0x30; break;
298 case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
299 case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
300 case CX25840_AUDIO7: reg &= ~0xc0; break;
301 case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
321 302
322 default: 303 default:
323 cx25840_err("%d is not a valid input!\n", input); 304 cx25840_err("0x%04x is not a valid audio input!\n", aud_input);
324 return -EINVAL; 305 return -EINVAL;
325 } 306 }
326 307
327 state->input = input; 308 cx25840_write(client, 0x103, reg);
309 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
310 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
311 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
312 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
313 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
314 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
315 cx25840_and_or(client, 0x102, ~0x4, 4);
316 else
317 cx25840_and_or(client, 0x102, ~0x4, 0);
318
319 state->vid_input = vid_input;
320 state->aud_input = aud_input;
321 cx25840_audio_set_path(client);
328 input_change(client); 322 input_change(client);
329 return 0; 323 return 0;
330} 324}
@@ -395,18 +389,9 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
395 struct cx25840_state *state = i2c_get_clientdata(client); 389 struct cx25840_state *state = i2c_get_clientdata(client);
396 390
397 switch (ctrl->id) { 391 switch (ctrl->id) {
398 case CX25840_CID_CARDTYPE: 392 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
399 switch (ctrl->value) { 393 state->pvr150_workaround = ctrl->value;
400 case CARDTYPE_PVR150: 394 set_input(client, state->vid_input, state->aud_input);
401 case CARDTYPE_PVR150_WORKAROUND:
402 case CARDTYPE_PG600:
403 state->cardtype = ctrl->value;
404 break;
405 default:
406 return -ERANGE;
407 }
408
409 set_input(client, state->input);
410 break; 395 break;
411 396
412 case V4L2_CID_BRIGHTNESS: 397 case V4L2_CID_BRIGHTNESS:
@@ -465,8 +450,8 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
465 struct cx25840_state *state = i2c_get_clientdata(client); 450 struct cx25840_state *state = i2c_get_clientdata(client);
466 451
467 switch (ctrl->id) { 452 switch (ctrl->id) {
468 case CX25840_CID_CARDTYPE: 453 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
469 ctrl->value = state->cardtype; 454 ctrl->value = state->pvr150_workaround;
470 break; 455 break;
471 case V4L2_CID_BRIGHTNESS: 456 case V4L2_CID_BRIGHTNESS:
472 ctrl->value = cx25840_read(client, 0x414) + 128; 457 ctrl->value = cx25840_read(client, 0x414) + 128;
@@ -615,7 +600,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
615 return cx25840_vbi(client, cmd, arg); 600 return cx25840_vbi(client, cmd, arg);
616 601
617 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 602 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
618 case AUDC_SET_INPUT:
619 result = cx25840_audio(client, cmd, arg); 603 result = cx25840_audio(client, cmd, arg);
620 break; 604 break;
621 605
@@ -652,13 +636,30 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
652 break; 636 break;
653 637
654 case VIDIOC_G_INPUT: 638 case VIDIOC_G_INPUT:
655 *(int *)arg = state->input; 639 *(int *)arg = state->vid_input;
656 break; 640 break;
657 641
658 case VIDIOC_S_INPUT: 642 case VIDIOC_S_INPUT:
659 result = set_input(client, *(int *)arg); 643 result = set_input(client, *(enum cx25840_video_input *)arg, state->aud_input);
660 break; 644 break;
661 645
646 case VIDIOC_S_AUDIO:
647 {
648 struct v4l2_audio *input = arg;
649
650 result = set_input(client, state->vid_input, input->index);
651 break;
652 }
653
654 case VIDIOC_G_AUDIO:
655 {
656 struct v4l2_audio *input = arg;
657
658 memset(input, 0, sizeof(*input));
659 input->index = state->aud_input;
660 break;
661 }
662
662 case VIDIOC_S_FREQUENCY: 663 case VIDIOC_S_FREQUENCY:
663 input_change(client); 664 input_change(client);
664 break; 665 break;
@@ -801,10 +802,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
801 802
802 i2c_set_clientdata(client, state); 803 i2c_set_clientdata(client, state);
803 memset(state, 0, sizeof(struct cx25840_state)); 804 memset(state, 0, sizeof(struct cx25840_state));
804 state->input = CX25840_TUNER; 805 state->vid_input = CX25840_COMPOSITE7;
806 state->aud_input = CX25840_AUDIO8;
805 state->audclk_freq = 48000; 807 state->audclk_freq = 48000;
806 state->audio_input = AUDIO_TUNER; 808 state->pvr150_workaround = 0;
807 state->cardtype = CARDTYPE_PVR150;
808 809
809 cx25840_initialize(client, 1); 810 cx25840_initialize(client, 1);
810 811
@@ -888,6 +889,8 @@ static void log_status(struct i2c_client *client)
888 u8 pref_mode = cx25840_read(client, 0x809); 889 u8 pref_mode = cx25840_read(client, 0x809);
889 u8 afc0 = cx25840_read(client, 0x80b); 890 u8 afc0 = cx25840_read(client, 0x80b);
890 u8 mute_ctl = cx25840_read(client, 0x8d3); 891 u8 mute_ctl = cx25840_read(client, 0x8d3);
892 int vid_input = state->vid_input;
893 int aud_input = state->aud_input;
891 char *p; 894 char *p;
892 895
893 cx25840_info("Video signal: %spresent\n", 896 cx25840_info("Video signal: %spresent\n",
@@ -997,16 +1000,19 @@ static void log_status(struct i2c_client *client)
997 cx25840_info("Specified standard: %s\n", 1000 cx25840_info("Specified standard: %s\n",
998 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); 1001 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
999 1002
1000 switch (state->input) { 1003 if (vid_input >= CX25840_COMPOSITE1 &&
1001 case CX25840_COMPOSITE0: p = "Composite 0"; break; 1004 vid_input <= CX25840_COMPOSITE8) {
1002 case CX25840_COMPOSITE1: p = "Composite 1"; break; 1005 cx25840_info("Specified video input: Composite %d\n",
1003 case CX25840_SVIDEO0: p = "S-Video 0"; break; 1006 vid_input - CX25840_COMPOSITE1 + 1);
1004 case CX25840_SVIDEO1: p = "S-Video 1"; break; 1007 } else {
1005 case CX25840_TUNER: p = "Tuner"; break; 1008 cx25840_info("Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
1009 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
1010 }
1011 if (aud_input) {
1012 cx25840_info("Specified audio input: Tuner (In%d)\n", aud_input);
1013 } else {
1014 cx25840_info("Specified audio input: External\n");
1006 } 1015 }
1007 cx25840_info("Specified input: %s\n", p);
1008 cx25840_info("Specified audio input: %s\n",
1009 state->audio_input == 0 ? "Tuner" : "External");
1010 1016
1011 cx25840_info("Specified audioclock freq: %d Hz\n", state->audclk_freq); 1017 cx25840_info("Specified audioclock freq: %d Hz\n", state->audclk_freq);
1012 1018
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h
index 4731a19092a6..3dc67e79c856 100644
--- a/drivers/media/video/cx25840/cx25840.h
+++ b/drivers/media/video/cx25840/cx25840.h
@@ -39,32 +39,58 @@ extern int cx25840_debug;
39 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ 39 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
40 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) 40 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
41 41
42#define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) 42/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
43 43 present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
44/* The CARDTYPE_PVR150_WORKAROUND cardtype activates a workaround for a 44 certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
45 hardware bug that is present in PVR150 (and possible PVR500) cards that
46 have certain NTSC tuners (tveeprom model numbers 85, 99 and 112). The
47 audio autodetect fails on some channels for these models and the workaround 45 audio autodetect fails on some channels for these models and the workaround
48 is to select the audio standard explicitly. Many thanks to Hauppauge for 46 is to select the audio standard explicitly. Many thanks to Hauppauge for
49 providing this information. */ 47 providing this information. */
50enum cx25840_cardtype { 48#define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0)
51 CARDTYPE_PVR150, 49
52 CARDTYPE_PG600, 50enum cx25840_video_input {
53 CARDTYPE_PVR150_WORKAROUND, 51 /* Composite video inputs In1-In8 */
52 CX25840_COMPOSITE1 = 1,
53 CX25840_COMPOSITE2,
54 CX25840_COMPOSITE3,
55 CX25840_COMPOSITE4,
56 CX25840_COMPOSITE5,
57 CX25840_COMPOSITE6,
58 CX25840_COMPOSITE7,
59 CX25840_COMPOSITE8,
60
61 /* S-Video inputs consist of one luma input (In1-In4) ORed with one
62 chroma input (In5-In8) */
63 CX25840_SVIDEO_LUMA1 = 0x10,
64 CX25840_SVIDEO_LUMA2 = 0x20,
65 CX25840_SVIDEO_LUMA3 = 0x30,
66 CX25840_SVIDEO_LUMA4 = 0x40,
67 CX25840_SVIDEO_CHROMA4 = 0x400,
68 CX25840_SVIDEO_CHROMA5 = 0x500,
69 CX25840_SVIDEO_CHROMA6 = 0x600,
70 CX25840_SVIDEO_CHROMA7 = 0x700,
71 CX25840_SVIDEO_CHROMA8 = 0x800,
72
73 /* S-Video aliases for common luma/chroma combinations */
74 CX25840_SVIDEO1 = 0x510,
75 CX25840_SVIDEO2 = 0x620,
76 CX25840_SVIDEO3 = 0x730,
77 CX25840_SVIDEO4 = 0x840,
54}; 78};
55 79
56enum cx25840_input { 80enum cx25840_audio_input {
57 CX25840_TUNER, 81 /* Audio inputs: serial or In4-In8 */
58 CX25840_COMPOSITE0, 82 CX25840_AUDIO_SERIAL,
59 CX25840_COMPOSITE1, 83 CX25840_AUDIO4 = 4,
60 CX25840_SVIDEO0, 84 CX25840_AUDIO5,
61 CX25840_SVIDEO1 85 CX25840_AUDIO6,
86 CX25840_AUDIO7,
87 CX25840_AUDIO8,
62}; 88};
63 89
64struct cx25840_state { 90struct cx25840_state {
65 enum cx25840_cardtype cardtype; 91 int pvr150_workaround;
66 enum cx25840_input input; 92 enum cx25840_video_input vid_input;
67 int audio_input; 93 enum cx25840_audio_input aud_input;
68 u32 audclk_freq; 94 u32 audclk_freq;
69}; 95};
70 96
@@ -84,6 +110,7 @@ int cx25840_loadfw(struct i2c_client *client);
84/* ----------------------------------------------------------------------- */ 110/* ----------------------------------------------------------------------- */
85/* cx25850-audio.c */ 111/* cx25850-audio.c */
86int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); 112int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg);
113void cx25840_audio_set_path(struct i2c_client *client);
87 114
88/* ----------------------------------------------------------------------- */ 115/* ----------------------------------------------------------------------- */
89/* cx25850-vbi.c */ 116/* cx25850-vbi.c */