Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 812b1f9d authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (10446): cx18: Finally get sliced VBI working - for 525 line 60 Hz systems at least



Sliced VBI, in the manner that ivtv implements it as a separate data stream,
now works for 525 line 60 Hz systems like NTSC-M.  It may work for 625 line
50 Hz systems, but I have more engineering work to do, to verify it is operating
properly.  Sliced data insertion into the MPEG PS should be working, but is
untested.

Signed-off-by: default avatarAndy Walls <awalls@radix.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 466df464
Loading
Loading
Loading
Loading
+33 −11
Original line number Diff line number Diff line
@@ -172,11 +172,11 @@ static void cx18_av_initialize(struct cx18 *cx)
	/*
	 * Initial VBI setup
	 * VIP-1.1, 10 bit mode, enable Raw, disable sliced,
	 * don't clamp raw samples when codes are in use, 4 byte user D-words,
	 * programmed IDID, RP code V bit transition on VBLANK, data during
	 * don't clamp raw samples when codes are in use, 1 byte user D-words,
	 * IDID0 has line #, RP code V bit transition on VBLANK, data during
	 * blanking intervals
	 */
	cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010252e);
	cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e);

	/* Set the video input.
	   The setting in MODE_CTRL gets lost when we do the above setup */
@@ -218,6 +218,7 @@ void cx18_av_std_setup(struct cx18 *cx)
		cx18_av_write(cx, 0x49f, 0x14);

	if (std & V4L2_STD_625_50) {
		/* FIXME - revisit these for Sliced VBI */
		hblank = 132;
		hactive = 720;
		burst = 93;
@@ -241,13 +242,34 @@ void cx18_av_std_setup(struct cx18 *cx)
			sc = 672351;
		}
	} else {
		/*
		 * The following relationships of half line counts should hold:
		 * 525 = vsync + vactive + vblank656
		 * 12 = vblank656 - vblank
		 *
		 * vsync:     always 6 half-lines of vsync pulses
		 * vactive:   half lines of active video
		 * vblank656: half lines, after line 3, of blanked video
		 * vblank:    half lines, after line 9, of blanked video
		 *
		 * vblank656 starts counting from the falling edge of the first
		 * 	vsync pulse (start of line 4)
		 * vblank starts counting from the after the 6 vsync pulses and
		 * 	6 equalization pulses (start of line 10)
		 *
		 * For 525 line systems the driver will extract VBI information
		 * from lines 10 through 21.  To avoid the EAV RP code from
		 * toggling at the start of hblank at line 22, where sliced VBI
		 * data from line 21 is stuffed, also treat line 22 as blanked.
		 */
		vblank656 = 38; /* lines  4 through  22 */
		vblank = 26;	/* lines 10 through  22 */
		vactive = 481;  /* lines 23 through 262.5 */

		hactive = 720;
		hblank = 122;
		vactive = 487;
		luma_lpf = 1;
		uv_lpf = 1;
		vblank = 26;
		vblank656 = 26;

		src_decimation = 0x21f;
		if (std == V4L2_STD_PAL_60) {
@@ -330,14 +352,14 @@ void cx18_av_std_setup(struct cx18 *cx)
	cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
	cx18_av_write(cx, 0x47e, 0xff & sc >> 16);

	/* Sets VBI parameters */
	if (std & V4L2_STD_625_50) {
		cx18_av_write(cx, 0x47f, 0x01);
		state->vbi_line_offset = 5;
		state->slicer_line_delay = 1;
		state->slicer_line_offset = (6 + state->slicer_line_delay - 2);
	} else {
		cx18_av_write(cx, 0x47f, 0x00);
		state->vbi_line_offset = 8;
		state->slicer_line_delay = 0;
		state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
	}
	cx18_av_write(cx, 0x47f, state->slicer_line_delay);
}

/* ----------------------------------------------------------------------- */
+18 −1
Original line number Diff line number Diff line
@@ -79,11 +79,28 @@ struct cx18_av_state {
	enum cx18_av_audio_input aud_input;
	u32 audclk_freq;
	int audmode;
	int vbi_line_offset;
	int default_volume;
	u32 id;
	u32 rev;
	int is_initialized;

	/*
	 * The VBI slicer starts operating and counting lines, begining at
	 * slicer line count of 1, at D lines after the deassertion of VRESET
	 * This staring field line, S, is 6 or 10 for 625 or 525 line systems.
	 * Sliced ancillary data captured on VBI slicer line M is sent at the
	 * beginning of the next VBI slicer line, VBI slicer line count N = M+1.
	 * Thus when the VBI slicer reports a VBI slicer line number with
	 * ancillary data, the IDID0 byte indicates VBI slicer line N.
	 * The actual field line that the captured data comes from is
	 * L = M+(S+D-1) = N-1+(S+D-1) = N + (S+D-2).
	 *
	 * D is the slicer_line_delay value programmed into register 0x47f.
	 * (S+D-2) is the slicer_line_offset used to convert slicer reported
	 * line counts to actual field lines.
	 */
	int slicer_line_delay;
	int slicer_line_offset;
};


+5 −5
Original line number Diff line number Diff line
@@ -182,7 +182,6 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
	case VIDIOC_S_FMT:
	{
		int is_pal = !(state->std & V4L2_STD_525_60);
		int vbi_offset = is_pal ? 1 : 0;
		int i, x;
		u8 lcr[24];

@@ -199,7 +198,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
			cx18_av_std_setup(cx);

			/* VBI Offset */
			cx18_av_write(cx, 0x47f, vbi_offset);
			cx18_av_write(cx, 0x47f, state->slicer_line_delay);
			cx18_av_write(cx, 0x404, 0x2e);
			break;
		}
@@ -213,7 +212,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
		/* Sliced VBI */
		cx18_av_write(cx, 0x404, 0x32);	/* Ancillary data */
		cx18_av_write(cx, 0x406, 0x13);
		cx18_av_write(cx, 0x47f, vbi_offset);
		cx18_av_write(cx, 0x47f, state->slicer_line_delay);

		/* Force impossible lines to 0 */
		if (is_pal) {
@@ -261,7 +260,8 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
		}

		cx18_av_write(cx, 0x43c, 0x16);
		cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22);
		/* FIXME - should match vblank set in cx18_av_std_setup() */
		cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
		break;
	}

@@ -286,7 +286,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
		did = anc->did;
		sdid = anc->sdid & 0xf;
		l = anc->idid[0] & 0x3f;
		l += state->vbi_line_offset;
		l += state->slicer_line_offset;
		p = anc->payload;

		/* Decode the SDID set by the slicer */
+3 −1
Original line number Diff line number Diff line
@@ -633,7 +633,9 @@ static void __devinit cx18_init_struct2(struct cx18 *cx)
	cx->av_state.aud_input = CX18_AV_AUDIO8;
	cx->av_state.audclk_freq = 48000;
	cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
	cx->av_state.vbi_line_offset = 8;
	cx->av_state.slicer_line_delay = 0;
	cx->av_state.slicer_line_offset =
		(10 + cx->av_state.slicer_line_delay - 2);
}

static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
+15 −4
Original line number Diff line number Diff line
@@ -360,9 +360,16 @@ static void cx18_vbi_setup(struct cx18_stream *s)
	if (raw) {
		lines = cx->vbi.count * 2;
	} else {
		lines = cx->is_60hz ? 24 : 38;
		if (cx->is_60hz)
			lines += 2;
		/*
		 * For 525/60 systems, according to the VIP 2 & BT.656 std:
		 * The EAV RP code's Field bit toggles on line 4, a few lines
		 * after the Vertcal Blank bit has already toggled.
		 * Tell the encoder to capture 21-4+1=18 lines per field,
		 * since we want lines 10 through 21.
		 *
		 * FIXME - revisit for 625/50 systems
		 */
		lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38;
	}

	data[0] = s->handle;
@@ -402,9 +409,13 @@ static void cx18_vbi_setup(struct cx18_stream *s)
		 *
		 * Since the V bit is only allowed to toggle in the EAV RP code,
		 * just before the first active region line, these two
		 * are problematic and we have to ignore them:
		 * are problematic:
		 * 0x90 (Task                         HorizontalBlank)
		 * 0xd0 (Task EvenField               HorizontalBlank)
		 *
		 * We have set the digitzer to consider the first active line
		 * as part of VerticalBlank as well so we don't have to look for
		 * these problem codes nor lose the last line of sliced data.
		 */
		data[4] = 0xB0F0B0F0;
		/*
Loading