On Fri, 15 Sep 2006, Walter Haidinger wrote: > Hi! > > I've trouble recording bilingual (or stereo?) with my PVR-150. > That is, setting 'ivtvctl -z 1' should result in "stereo" with > lang1 and lang2 on left/right channel simultaneously. > ... > > Perhaps it's another small bug in the cx25840 driver? I've already > applied the patch from the misc directory to fix the color bug.
Yes, it was a bug in the cx25840 driver of the 2.6.16 kernel, fixed in 2.6.17. After comparing the 2.6.16/2.6.17 sources, Google turned up Hans Verkuil's patch: http://lkml.org/lkml/2006/3/20/282 Appended below is the patch for the cx25840 driver, backported for the 2.6.16 kernel. Please note that it already incorporates the misc/cx25840.diff patch from the ivtv-0.6.3 sources to fix the color bug (also fixed in 2.6.17). I've made a single change and set the default(?) language mode to stereo rather than lang1: state->audmode = V4L2_TUNER_MODE_STEREO; instead of state->audmode = V4L2_TUNER_MODE_LANG1; at line 926 of cx25840-core.c. To apply, do (if the attached patch is in your home directory): cd /usr/src/linux/drivers/media/video/cx25840 patch -p0 < ~/cx25840.diff and recompile your kernel. To install the module (all on a single line): install -m 644 -g root -o root /usr/src/linux/drivers/media/video/cx25840/cx25840.ko /lib/modules/`uname -r`/kernel/drivers/media/video/cx25840/ Regards, Walter --- cx25840-core.c-2.6.16.27 2006-09-19 17:08:24.000000000 +0200 +++ cx25840-core.c 2006-09-19 16:57:33.000000000 +0200 @@ -176,9 +176,9 @@ cx25840_write(client, 0x4a5, 0x00); cx25840_write(client, 0x402, 0x00); /* 8. */ - cx25840_write(client, 0x401, 0x18); - cx25840_write(client, 0x4a2, 0x10); - cx25840_write(client, 0x402, 0x04); + cx25840_and_or(client, 0x401, ~0x18, 0); + cx25840_and_or(client, 0x4a2, ~0x10, 0x10); + /* steps 8c and 8d are done in change_input() */ /* 10. */ cx25840_write(client, 0x8d3, 0x1f); cx25840_write(client, 0x8e3, 0x03); @@ -209,6 +209,17 @@ struct cx25840_state *state = i2c_get_clientdata(client); v4l2_std_id std = cx25840_get_v4lstd(client); + /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */ + if (std & V4L2_STD_SECAM) { + cx25840_write(client, 0x402, 0); + } + else { + cx25840_write(client, 0x402, 0x04); + cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); + } + cx25840_and_or(client, 0x401, ~0x60, 0); + cx25840_and_or(client, 0x401, ~0x60, 0x60); + /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC instead of V4L2_STD_PAL. Someone needs to test this. */ if (std & V4L2_STD_PAL) { @@ -343,6 +354,15 @@ } } + /* Follow step 9 of section 3.16 in the cx25840 datasheet. + Without this PAL may display a vertical ghosting effect. + This happens for example with the Yuan MPC622. */ + if (fmt >= 4 && fmt < 8) { + /* Set format to NTSC-M */ + cx25840_and_or(client, 0x400, ~0xf, 1); + /* Turn off LCOMB */ + cx25840_and_or(client, 0x47b, ~6, 0); + } cx25840_and_or(client, 0x400, ~0xf, fmt); cx25840_vbi_setup(client); return 0; @@ -359,7 +379,14 @@ } switch (fmt) { - case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR; + case 0x1: + { + /* if the audio std is A2-M, then this is the South Korean + NTSC standard */ + if (cx25840_read(client, 0x805) == 2) + return V4L2_STD_NTSC_M_KR; + return V4L2_STD_NTSC_M; + } case 0x2: return V4L2_STD_NTSC_M_JP; case 0x3: return V4L2_STD_NTSC_443; case 0x4: return V4L2_STD_PAL; @@ -743,6 +770,7 @@ memset(input, 0, sizeof(*input)); input->index = state->aud_input; + input->capability = V4L2_AUDCAP_STEREO; break; } @@ -753,7 +781,6 @@ case VIDIOC_G_TUNER: { u8 mode = cx25840_read(client, 0x804); - u8 pref = cx25840_read(client, 0x809) & 0xf; u8 vpres = cx25840_read(client, 0x80a) & 0x10; int val = 0; @@ -773,44 +800,49 @@ val |= V4L2_TUNER_SUB_MONO; if (mode == 2 || mode == 4) - val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; if (mode & 0x10) val |= V4L2_TUNER_SUB_SAP; vt->rxsubchans = val; - - switch (pref) { - case 0: - vt->audmode = V4L2_TUNER_MODE_MONO; - break; - case 1: - case 2: - vt->audmode = V4L2_TUNER_MODE_LANG2; - break; - case 4: - default: - vt->audmode = V4L2_TUNER_MODE_STEREO; - } + vt->audmode = state->audmode; break; } case VIDIOC_S_TUNER: + if (state->radio) + break; + switch (vt->audmode) { case V4L2_TUNER_MODE_MONO: - case V4L2_TUNER_MODE_LANG1: - /* Force PREF_MODE to MONO */ + /* mono -> mono + stereo -> mono + bilingual -> lang1 */ cx25840_and_or(client, 0x809, ~0xf, 0x00); break; - case V4L2_TUNER_MODE_STEREO: - /* Force PREF_MODE to STEREO */ + case V4L2_TUNER_MODE_LANG1: + /* mono -> mono + stereo -> stereo + bilingual -> lang1 */ cx25840_and_or(client, 0x809, ~0xf, 0x04); break; + case V4L2_TUNER_MODE_STEREO: + /* mono -> mono + stereo -> stereo + bilingual -> lang1/lang2 */ + cx25840_and_or(client, 0x809, ~0xf, 0x07); + break; case V4L2_TUNER_MODE_LANG2: - /* Force PREF_MODE to LANG2 */ + /* mono -> mono + stereo ->stereo + bilingual -> lang2 */ cx25840_and_or(client, 0x809, ~0xf, 0x01); break; + default: + return -EINVAL; } + state->audmode = vt->audmode; break; case VIDIOC_G_FMT: @@ -891,6 +923,7 @@ state->aud_input = CX25840_AUDIO8; state->audclk_freq = 48000; state->pvr150_workaround = 0; + state->audmode = V4L2_TUNER_MODE_STEREO; cx25840_initialize(client, 1); --- cx25840.h-2.6.16.27 2006-09-19 17:08:35.000000000 +0200 +++ cx25840.h 2006-09-19 16:42:43.000000000 +0200 @@ -78,6 +78,7 @@ enum cx25840_video_input vid_input; enum cx25840_audio_input aud_input; u32 audclk_freq; + int audmode; }; /* ----------------------------------------------------------------------- */ _______________________________________________ ivtv-users mailing list [email protected] http://ivtvdriver.org/mailman/listinfo/ivtv-users
