aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-01-30 22:33:02 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:38 -0400
commit302df9702192a68578916ef922c33370cbba350d (patch)
treeeab3173a4b82ec26c89b82c50e9bfb0fe2477953 /drivers
parent4325dff220918c2ced82d16c3475d9a5afb1cab3 (diff)
V4L/DVB (10439): cx18: Clean-up and enable sliced VBI handling
Removed legacy ivtv state variables, added comments, and cleaned up sliced VBI related code. Enabled sliced VBI. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c11
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c92
-rw-r--r--drivers/media/video/cx18/cx18-cards.c8
-rw-r--r--drivers/media/video/cx18/cx18-cards.h3
-rw-r--r--drivers/media/video/cx18/cx18-controls.c4
-rw-r--r--drivers/media/video/cx18/cx18-driver.c49
-rw-r--r--drivers/media/video/cx18/cx18-driver.h142
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c54
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c77
-rw-r--r--drivers/media/video/cx18/cx18-streams.c45
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c58
11 files changed, 383 insertions, 160 deletions
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 091f0cac0633..1d197649446e 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -169,9 +169,14 @@ static void cx18_av_initialize(struct cx18 *cx)
169 /* Set VGA_TRACK_RANGE to 0x20 */ 169 /* Set VGA_TRACK_RANGE to 0x20 */
170 cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000); 170 cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
171 171
172 /* Enable VBI capture */ 172 /*
173 cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F); 173 * Initial VBI setup
174 /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */ 174 * VIP-1.1, 10 bit mode, enable Raw, disable sliced,
175 * don't clamp raw samples when codes are in use, 4 byte user D-words,
176 * programmed IDID, RP code V bit transition on VBLANK, data during
177 * blanking intervals
178 */
179 cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010252e);
175 180
176 /* Set the video input. 181 /* Set the video input.
177 The setting in MODE_CTRL gets lost when we do the above setup */ 182 The setting in MODE_CTRL gets lost when we do the above setup */
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index 1527ea4f6b06..72325d774a60 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -24,6 +24,52 @@
24 24
25#include "cx18-driver.h" 25#include "cx18-driver.h"
26 26
27/*
28 * For sliced VBI output, we set up to use VIP-1.1, 10-bit mode,
29 * NN counts 4 bytes Dwords, an IDID of 0x00 0x80 or one with the VBI line #.
30 * Thus, according to the VIP-2 Spec, our VBI ancillary data lines
31 * (should!) look like:
32 * 4 byte EAV code: 0xff 0x00 0x00 0xRP
33 * unknown number of possible idle bytes
34 * 3 byte Anc data preamble: 0x00 0xff 0xff
35 * 1 byte data identifier: ne010iii (parity bits, 010, DID bits)
36 * 1 byte secondary data id: nessssss (parity bits, SDID bits)
37 * 1 byte data word count: necccccc (parity bits, NN Dword count)
38 * 2 byte Internal DID: 0x00 0x80 (programmed value)
39 * 4*NN data bytes
40 * 1 byte checksum
41 * Fill bytes needed to fil out to 4*NN bytes of payload
42 *
43 * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, &
44 * in the vertical blanking interval are:
45 * 0xb0 (Task 0 VerticalBlank HorizontalBlank 0 0 0 0)
46 * 0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0)
47 *
48 * Since the V bit is only allowed to toggle in the EAV RP code, just
49 * before the first active region line and for active lines, they are:
50 * 0x90 (Task 0 0 HorizontalBlank 0 0 0 0)
51 * 0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0)
52 *
53 * The user application DID bytes we care about are:
54 * 0x91 (1 0 010 0 !ActiveLine AncDataPresent)
55 * 0x55 (0 1 010 2ndField !ActiveLine AncDataPresent)
56 *
57 */
58static const u8 sliced_vbi_did[2] = { 0x91, 0x55 };
59
60struct vbi_anc_data {
61 /* u8 eav[4]; */
62 /* u8 idle[]; Variable number of idle bytes */
63 u8 preamble[3];
64 u8 did;
65 u8 sdid;
66 u8 data_count;
67 u8 idid[2];
68 u8 payload[1]; /* 4*data_count of payload */
69 /* u8 checksum; */
70 /* u8 fill[]; Variable number of fill bytes */
71};
72
27static int odd_parity(u8 c) 73static int odd_parity(u8 c)
28{ 74{
29 c ^= (c >> 4); 75 c ^= (c >> 4);
@@ -96,7 +142,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
96 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 142 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
97 0, V4L2_SLICED_WSS_625, 0, /* 4 */ 143 0, V4L2_SLICED_WSS_625, 0, /* 4 */
98 V4L2_SLICED_CAPTION_525, /* 6 */ 144 V4L2_SLICED_CAPTION_525, /* 6 */
99 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ 145 V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 - unlike cx25840 */
100 0, 0, 0, 0 146 0, 0, 0, 0
101 }; 147 };
102 int is_pal = !(state->std & V4L2_STD_525_60); 148 int is_pal = !(state->std & V4L2_STD_525_60);
@@ -220,47 +266,53 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
220 case VIDIOC_INT_DECODE_VBI_LINE: 266 case VIDIOC_INT_DECODE_VBI_LINE:
221 { 267 {
222 struct v4l2_decode_vbi_line *vbi = arg; 268 struct v4l2_decode_vbi_line *vbi = arg;
223 u8 *p = vbi->p; 269 u8 *p;
224 int id1, id2, l, err = 0; 270 struct vbi_anc_data *anc = (struct vbi_anc_data *) vbi->p;
225 271 int did, sdid, l, err = 0;
226 if (p[0] || p[1] != 0xff || p[2] != 0xff || 272
227 (p[3] != 0x55 && p[3] != 0x91)) { 273 /*
274 * Check for the ancillary data header for sliced VBI
275 */
276 if (anc->preamble[0] ||
277 anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
278 (anc->did != sliced_vbi_did[0] &&
279 anc->did != sliced_vbi_did[1])) {
228 vbi->line = vbi->type = 0; 280 vbi->line = vbi->type = 0;
229 break; 281 break;
230 } 282 }
231 283
232 p += 4; 284 did = anc->did;
233 id1 = p[-1]; 285 sdid = anc->sdid & 0xf;
234 id2 = p[0] & 0xf; 286 l = anc->idid[0] & 0x3f;
235 l = p[2] & 0x3f;
236 l += state->vbi_line_offset; 287 l += state->vbi_line_offset;
237 p += 4; 288 p = anc->payload;
238 289
239 switch (id2) { 290 /* Decode the SDID set by the slicer */
291 switch (sdid) {
240 case 1: 292 case 1:
241 id2 = V4L2_SLICED_TELETEXT_B; 293 sdid = V4L2_SLICED_TELETEXT_B;
242 break; 294 break;
243 case 4: 295 case 4:
244 id2 = V4L2_SLICED_WSS_625; 296 sdid = V4L2_SLICED_WSS_625;
245 break; 297 break;
246 case 6: 298 case 6:
247 id2 = V4L2_SLICED_CAPTION_525; 299 sdid = V4L2_SLICED_CAPTION_525;
248 err = !odd_parity(p[0]) || !odd_parity(p[1]); 300 err = !odd_parity(p[0]) || !odd_parity(p[1]);
249 break; 301 break;
250 case 9: 302 case 7: /* Differs from cx25840 */
251 id2 = V4L2_SLICED_VPS; 303 sdid = V4L2_SLICED_VPS;
252 if (decode_vps(p, p) != 0) 304 if (decode_vps(p, p) != 0)
253 err = 1; 305 err = 1;
254 break; 306 break;
255 default: 307 default:
256 id2 = 0; 308 sdid = 0;
257 err = 1; 309 err = 1;
258 break; 310 break;
259 } 311 }
260 312
261 vbi->type = err ? 0 : id2; 313 vbi->type = err ? 0 : sdid;
262 vbi->line = err ? 0 : l; 314 vbi->line = err ? 0 : l;
263 vbi->is_second_field = err ? 0 : (id1 == 0x55); 315 vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
264 vbi->p = p; 316 vbi->p = p;
265 break; 317 break;
266 } 318 }
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index a0d4d2e49d1b..6e2105ac2bc4 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -51,7 +51,7 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
51static const struct cx18_card cx18_card_hvr1600_esmt = { 51static const struct cx18_card cx18_card_hvr1600_esmt = {
52 .type = CX18_CARD_HVR_1600_ESMT, 52 .type = CX18_CARD_HVR_1600_ESMT,
53 .name = "Hauppauge HVR-1600", 53 .name = "Hauppauge HVR-1600",
54 .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", 54 .comment = "Simultaneous Digital and Analog TV capture supported\n",
55 .v4l2_capabilities = CX18_CAP_ENCODER, 55 .v4l2_capabilities = CX18_CAP_ENCODER,
56 .hw_audio_ctrl = CX18_HW_CX23418, 56 .hw_audio_ctrl = CX18_HW_CX23418,
57 .hw_muxer = CX18_HW_CS5345, 57 .hw_muxer = CX18_HW_CS5345,
@@ -97,7 +97,7 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
97static const struct cx18_card cx18_card_hvr1600_samsung = { 97static const struct cx18_card cx18_card_hvr1600_samsung = {
98 .type = CX18_CARD_HVR_1600_SAMSUNG, 98 .type = CX18_CARD_HVR_1600_SAMSUNG,
99 .name = "Hauppauge HVR-1600 (Preproduction)", 99 .name = "Hauppauge HVR-1600 (Preproduction)",
100 .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", 100 .comment = "Simultaneous Digital and Analog TV capture supported\n",
101 .v4l2_capabilities = CX18_CAP_ENCODER, 101 .v4l2_capabilities = CX18_CAP_ENCODER,
102 .hw_audio_ctrl = CX18_HW_CX23418, 102 .hw_audio_ctrl = CX18_HW_CX23418,
103 .hw_muxer = CX18_HW_CS5345, 103 .hw_muxer = CX18_HW_CS5345,
@@ -152,7 +152,7 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = {
152static const struct cx18_card cx18_card_h900 = { 152static const struct cx18_card cx18_card_h900 = {
153 .type = CX18_CARD_COMPRO_H900, 153 .type = CX18_CARD_COMPRO_H900,
154 .name = "Compro VideoMate H900", 154 .name = "Compro VideoMate H900",
155 .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", 155 .comment = "Analog TV capture supported\n",
156 .v4l2_capabilities = CX18_CAP_ENCODER, 156 .v4l2_capabilities = CX18_CAP_ENCODER,
157 .hw_audio_ctrl = CX18_HW_CX23418, 157 .hw_audio_ctrl = CX18_HW_CX23418,
158 .hw_all = CX18_HW_TUNER, 158 .hw_all = CX18_HW_TUNER,
@@ -249,7 +249,7 @@ static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
249static const struct cx18_card cx18_card_cnxt_raptor_pal = { 249static const struct cx18_card cx18_card_cnxt_raptor_pal = {
250 .type = CX18_CARD_CNXT_RAPTOR_PAL, 250 .type = CX18_CARD_CNXT_RAPTOR_PAL,
251 .name = "Conexant Raptor PAL/SECAM", 251 .name = "Conexant Raptor PAL/SECAM",
252 .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", 252 .comment = "Analog TV capture supported\n",
253 .v4l2_capabilities = CX18_CAP_ENCODER, 253 .v4l2_capabilities = CX18_CAP_ENCODER,
254 .hw_audio_ctrl = CX18_HW_CX23418, 254 .hw_audio_ctrl = CX18_HW_CX23418,
255 .hw_muxer = CX18_HW_GPIO, 255 .hw_muxer = CX18_HW_GPIO,
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 6fa7bcb42dde..f8ee29f102d4 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -49,8 +49,7 @@
49/* V4L2 capability aliases */ 49/* V4L2 capability aliases */
50#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ 50#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
51 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \ 51 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \
52 V4L2_CAP_VBI_CAPTURE) 52 V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)
53/* | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */
54 53
55struct cx18_card_video_input { 54struct cx18_card_video_input {
56 u8 video_type; /* video input type */ 55 u8 video_type; /* video input type */
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 17edf305d649..6af4d5c190e1 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -178,8 +178,8 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt
178 int i; 178 int i;
179 179
180 for (i = 0; i < CX18_VBI_FRAMES; i++) { 180 for (i = 0; i < CX18_VBI_FRAMES; i++) {
181 /* Yuck, hardcoded. Needs to be a define */ 181 cx->vbi.sliced_mpeg_data[i] =
182 cx->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL); 182 kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL);
183 if (cx->vbi.sliced_mpeg_data[i] == NULL) { 183 if (cx->vbi.sliced_mpeg_data[i] == NULL) {
184 while (--i >= 0) { 184 while (--i >= 0) {
185 kfree(cx->vbi.sliced_mpeg_data[i]); 185 kfree(cx->vbi.sliced_mpeg_data[i]);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 062f1910e8dd..842ce636e45c 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -586,7 +586,8 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
586 (cx->params.video_temporal_filter_mode << 1) | 586 (cx->params.video_temporal_filter_mode << 1) |
587 (cx->params.video_median_filter_type << 2); 587 (cx->params.video_median_filter_type << 2);
588 cx->params.port = CX2341X_PORT_MEMORY; 588 cx->params.port = CX2341X_PORT_MEMORY;
589 cx->params.capabilities = CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_AC3; 589 cx->params.capabilities =
590 CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_AC3 | CX2341X_CAP_HAS_SLICED_VBI;
590 init_waitqueue_head(&cx->cap_w); 591 init_waitqueue_head(&cx->cap_w);
591 init_waitqueue_head(&cx->mb_apu_waitq); 592 init_waitqueue_head(&cx->mb_apu_waitq);
592 init_waitqueue_head(&cx->mb_cpu_waitq); 593 init_waitqueue_head(&cx->mb_cpu_waitq);
@@ -596,49 +597,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
596 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; 597 cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
597 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; 598 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
598 599
599 /*
600 * The VBI line sizes depend on the pixel clock and the horiz rate
601 *
602 * (1/Fh)*(2*Fp) = Samples/line
603 * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
604 *
605 * Sliced VBI is sent as ancillary data during horizontal blanking
606 * Raw VBI is sent as active video samples during vertcal blanking
607 *
608 * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
609 * length of 720 pixels @ 4:2:2 sampling. Thus...
610 *
611 * For systems that use a 15.734 kHz horizontal rate, such as
612 * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
613 *
614 * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
615 * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
616 *
617 * For systems that use a 15.625 kHz horizontal rate, such as
618 * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
619 *
620 * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
621 * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
622 *
623 */
624
625 /* FIXME: init these based on tuner std & modify when std changes */
626 /* CX18-AV-Core number of VBI samples output per horizontal line */
627 cx->vbi.raw_decoder_line_size = 1444; /* 4 byte SAV + 2 * 720 */
628 cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */
629
630 /* CX18-AV-Core VBI samples/line possibly rounded up */
631 cx->vbi.raw_size = 1444; /* Real max size is 1444 */
632 cx->vbi.sliced_size = 284; /* Real max size is 284 */
633
634 /*
635 * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode
636 * Task Field VerticalBlank HorizontalBlank 0 0 0 0
637 */
638 cx->vbi.raw_decoder_sav_odd_field = 0x20; /* V */
639 cx->vbi.raw_decoder_sav_even_field = 0x60; /* FV */
640 cx->vbi.sliced_decoder_sav_odd_field = 0xB0; /* T VH - actually EAV */
641 cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */
642 return 0; 600 return 0;
643} 601}
644 602
@@ -671,7 +629,6 @@ static void __devinit cx18_init_struct2(struct cx18 *cx)
671 cx->av_state.aud_input = CX18_AV_AUDIO8; 629 cx->av_state.aud_input = CX18_AV_AUDIO8;
672 cx->av_state.audclk_freq = 48000; 630 cx->av_state.audclk_freq = 48000;
673 cx->av_state.audmode = V4L2_TUNER_MODE_LANG1; 631 cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
674 /* FIXME - 8 is NTSC value, investigate */
675 cx->av_state.vbi_line_offset = 8; 632 cx->av_state.vbi_line_offset = 8;
676} 633}
677 634
@@ -936,7 +893,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
936 * suboptimal, as the CVBS and SVideo inputs could use a different std 893 * suboptimal, as the CVBS and SVideo inputs could use a different std
937 * and the buffer could end up being too small in that case. 894 * and the buffer could end up being too small in that case.
938 */ 895 */
939 vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2; 896 vbi_buf_size = vbi_active_samples * (cx->is_60hz ? 24 : 36) / 2;
940 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size; 897 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
941 898
942 if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0) 899 if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index d95c6ace2b96..a41d9c4178f0 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -319,59 +319,121 @@ struct cx18_open_id {
319/* forward declaration of struct defined in cx18-cards.h */ 319/* forward declaration of struct defined in cx18-cards.h */
320struct cx18_card; 320struct cx18_card;
321 321
322/*
323 * A note about "sliced" VBI data as implemented in this driver:
324 *
325 * Currently we collect the sliced VBI in the form of Ancillary Data
326 * packets, inserted by the AV core decoder/digitizer/slicer in the
327 * horizontal blanking region of the VBI lines, in "raw" mode as far as
328 * the Encoder is concerned. We don't ever tell the Encoder itself
329 * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode)
330 *
331 * We then process the ancillary data ourselves to send the sliced data
332 * to the user application directly or build up MPEG-2 private stream 1
333 * packets to splice into (only!) MPEG-2 PS streams for the user app.
334 *
335 * (That's how ivtv essentially does it.)
336 *
337 * The Encoder should be able to extract certain sliced VBI data for
338 * us and provide it in a separate stream or splice it into any type of
339 * MPEG PS or TS stream, but this isn't implemented yet.
340 */
341
342/*
343 * Number of "raw" VBI samples per horizontal line we tell the Encoder to
344 * grab from the decoder/digitizer/slicer output for raw or sliced VBI.
345 * It depends on the pixel clock and the horiz rate:
346 *
347 * (1/Fh)*(2*Fp) = Samples/line
348 * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
349 *
350 * Sliced VBI data is sent as ancillary data during horizontal blanking
351 * Raw VBI is sent as active video samples during vertcal blanking
352 *
353 * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
354 * length of 720 pixels @ 4:2:2 sampling. Thus...
355 *
356 * For systems that use a 15.734 kHz horizontal rate, such as
357 * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
358 *
359 * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
360 * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
361 *
362 * For systems that use a 15.625 kHz horizontal rate, such as
363 * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
364 *
365 * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
366 * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
367 */
368static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */
369static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */
370static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */
322 371
323#define CX18_VBI_FRAMES 32 372#define CX18_VBI_FRAMES 32
324 373
325/* VBI data */
326struct vbi_info { 374struct vbi_info {
327 u32 enc_size; 375 /* Current state of v4l2 VBI settings for this device */
328 u32 frame;
329 u8 cc_data_odd[256];
330 u8 cc_data_even[256];
331 int cc_pos;
332 u8 cc_no_update;
333 u8 vps[5];
334 u8 vps_found;
335 int wss;
336 u8 wss_found;
337 u8 wss_no_update;
338 u32 raw_decoder_line_size;
339 u8 raw_decoder_sav_odd_field;
340 u8 raw_decoder_sav_even_field;
341 u32 sliced_decoder_line_size;
342 u8 sliced_decoder_sav_odd_field;
343 u8 sliced_decoder_sav_even_field;
344 struct v4l2_format in; 376 struct v4l2_format in;
345 /* convenience pointer to sliced struct in vbi_in union */ 377 struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */
346 struct v4l2_sliced_vbi_format *sliced_in; 378 u32 count; /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */
347 u32 service_set_in; 379 u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */
348 int insert_mpeg;
349 380
350 /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. 381 u32 frame; /* Count of VBI buffers/frames received from Encoder */
351 One for /dev/vbi0 and one for /dev/vbi8 */
352 struct v4l2_sliced_vbi_data sliced_data[36];
353 382
354 /* Buffer for VBI data inserted into MPEG stream. 383 /*
355 The first byte is a dummy byte that's never used. 384 * Vars for creation and insertion of MPEG Private Stream 1 packets
356 The next 16 bytes contain the MPEG header for the VBI data, 385 * of sliced VBI data into an MPEG PS
357 the remainder is the actual VBI data. 386 */
358 The max size accepted by the MPEG VBI reinsertion turns out
359 to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
360 where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
361 a single line header byte and 2 * 18 is the number of VBI lines per frame.
362 387
363 However, it seems that the data must be 1K aligned, so we have to 388 /* Boolean: create and insert Private Stream 1 packets into the PS */
364 pad the data until the 1 or 2 K boundary. 389 int insert_mpeg;
390
391 /*
392 * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
393 * Used in cx18-vbi.c only for collecting sliced data, and as a source
394 * during conversion of sliced VBI data into MPEG Priv Stream 1 packets.
395 * We don't need to save state here, but the array may have been a bit
396 * too big (2304 bytes) to alloc from the stack.
397 */
398 struct v4l2_sliced_vbi_data sliced_data[36];
365 399
366 This pointer array will allocate 2049 bytes to store each VBI frame. */ 400 /*
401 * A ring buffer of driver-generated MPEG-2 PS
402 * Program Pack/Private Stream 1 packets for sliced VBI data insertion
403 * into the MPEG PS stream.
404 *
405 * In each sliced_mpeg_data[] buffer is:
406 * 16 byte MPEG-2 PS Program Pack Header
407 * 16 byte MPEG-2 Private Stream 1 PES Header
408 * 4 byte magic number: "itv0" or "ITV0"
409 * 4 byte first field line mask, if "itv0"
410 * 4 byte second field line mask, if "itv0"
411 * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
412 *
413 * Each line in the payload is
414 * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
415 * 42 bytes of line data
416 *
417 * That's a maximum 1552 bytes of payload in the Private Stream 1 packet
418 * which is the payload size a PVR-350 (CX23415) MPEG decoder will
419 * accept for VBI data. So, including the headers, it's a maximum 1584
420 * bytes total.
421 */
422#define CX18_SLICED_MPEG_DATA_MAXSZ 1584
423 /* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */
424#define CX18_SLICED_MPEG_DATA_BUFSZ (CX18_SLICED_MPEG_DATA_MAXSZ+8)
367 u8 *sliced_mpeg_data[CX18_VBI_FRAMES]; 425 u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
368 u32 sliced_mpeg_size[CX18_VBI_FRAMES]; 426 u32 sliced_mpeg_size[CX18_VBI_FRAMES];
369 struct cx18_buffer sliced_mpeg_buf; 427
428 /* Count of Program Pack/Program Stream 1 packets inserted into PS */
370 u32 inserted_frame; 429 u32 inserted_frame;
371 430
372 u32 start[2], count; 431 /*
373 u32 raw_size; 432 * A dummy driver stream transfer buffer with a copy of the next
374 u32 sliced_size; 433 * sliced_mpeg_data[] buffer for output to userland apps.
434 * Only used in cx18-fileops.c, but its state needs to persist at times.
435 */
436 struct cx18_buffer sliced_mpeg_buf;
375}; 437};
376 438
377/* Per cx23418, per I2C bus private algo callback data */ 439/* Per cx23418, per I2C bus private algo callback data */
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 23006f7d9159..0b1dbc67e1ab 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -176,6 +176,8 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
176 *err = 0; 176 *err = 0;
177 while (1) { 177 while (1) {
178 if (s->type == CX18_ENC_STREAM_TYPE_MPG) { 178 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
179 /* Process pending program info updates and pending
180 VBI data */
179 181
180 if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) { 182 if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
181 cx->dualwatch_jiffies = jiffies; 183 cx->dualwatch_jiffies = jiffies;
@@ -260,6 +262,20 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
260 len = ucount; 262 len = ucount;
261 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && 263 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
262 !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) { 264 !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
265 /*
266 * Try to find a good splice point in the PS, just before
267 * an MPEG-2 Program Pack start code, and provide only
268 * up to that point to the user, so it's easy to insert VBI data
269 * the next time around.
270 */
271 /* FIXME - This only works for an MPEG-2 PS, not a TS */
272 /*
273 * An MPEG-2 Program Stream (PS) is a series of
274 * MPEG-2 Program Packs terminated by an
275 * MPEG Program End Code after the last Program Pack.
276 * A Program Pack may hold a PS System Header packet and any
277 * number of Program Elementary Stream (PES) Packets
278 */
263 const char *start = buf->buf + buf->readpos; 279 const char *start = buf->buf + buf->readpos;
264 const char *p = start + 1; 280 const char *p = start + 1;
265 const u8 *q; 281 const u8 *q;
@@ -267,38 +283,54 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
267 int stuffing, i; 283 int stuffing, i;
268 284
269 while (start + len > p) { 285 while (start + len > p) {
286 /* Scan for a 0 to find a potential MPEG-2 start code */
270 q = memchr(p, 0, start + len - p); 287 q = memchr(p, 0, start + len - p);
271 if (q == NULL) 288 if (q == NULL)
272 break; 289 break;
273 p = q + 1; 290 p = q + 1;
291 /*
292 * Keep looking if not a
293 * MPEG-2 Pack header start code: 0x00 0x00 0x01 0xba
294 * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
295 */
274 if ((char *)q + 15 >= buf->buf + buf->bytesused || 296 if ((char *)q + 15 >= buf->buf + buf->bytesused ||
275 q[1] != 0 || q[2] != 1 || q[3] != ch) 297 q[1] != 0 || q[2] != 1 || q[3] != ch)
276 continue; 298 continue;
299
300 /* If expecting the primary video PES */
277 if (!cx->search_pack_header) { 301 if (!cx->search_pack_header) {
302 /* Continue if it couldn't be a PES packet */
278 if ((q[6] & 0xc0) != 0x80) 303 if ((q[6] & 0xc0) != 0x80)
279 continue; 304 continue;
280 if (((q[7] & 0xc0) == 0x80 && 305 /* Check if a PTS or PTS & DTS follow */
281 (q[9] & 0xf0) == 0x20) || 306 if (((q[7] & 0xc0) == 0x80 && /* PTS only */
282 ((q[7] & 0xc0) == 0xc0 && 307 (q[9] & 0xf0) == 0x20) || /* PTS only */
283 (q[9] & 0xf0) == 0x30)) { 308 ((q[7] & 0xc0) == 0xc0 && /* PTS & DTS */
284 ch = 0xba; 309 (q[9] & 0xf0) == 0x30)) { /* DTS follows */
310 /* Assume we found the video PES hdr */
311 ch = 0xba; /* next want a Program Pack*/
285 cx->search_pack_header = 1; 312 cx->search_pack_header = 1;
286 p = q + 9; 313 p = q + 9; /* Skip this video PES hdr */
287 } 314 }
288 continue; 315 continue;
289 } 316 }
317
318 /* We may have found a Program Pack start code */
319
320 /* Get the count of stuffing bytes & verify them */
290 stuffing = q[13] & 7; 321 stuffing = q[13] & 7;
291 /* all stuffing bytes must be 0xff */ 322 /* all stuffing bytes must be 0xff */
292 for (i = 0; i < stuffing; i++) 323 for (i = 0; i < stuffing; i++)
293 if (q[14 + i] != 0xff) 324 if (q[14 + i] != 0xff)
294 break; 325 break;
295 if (i == stuffing && 326 if (i == stuffing && /* right number of stuffing bytes*/
296 (q[4] & 0xc4) == 0x44 && 327 (q[4] & 0xc4) == 0x44 && /* marker check */
297 (q[12] & 3) == 3 && 328 (q[12] & 3) == 3 && /* marker check */
298 q[14 + stuffing] == 0 && 329 q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
299 q[15 + stuffing] == 0 && 330 q[15 + stuffing] == 0 &&
300 q[16 + stuffing] == 1) { 331 q[16 + stuffing] == 1) {
301 cx->search_pack_header = 0; 332 /* We declare we actually found a Program Pack*/
333 cx->search_pack_header = 0; /* expect vid PES */
302 len = (char *)q - start; 334 len = (char *)q - start;
303 cx18_setup_sliced_vbi_buf(cx); 335 cx18_setup_sliced_vbi_buf(cx);
304 break; 336 break;
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 20467fce5251..1adb97220920 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -102,6 +102,19 @@ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
102 } 102 }
103} 103}
104 104
105static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
106{
107 int f, l;
108 u16 set = 0;
109
110 for (f = 0; f < 2; f++) {
111 for (l = 0; l < 24; l++) {
112 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
113 set |= fmt->service_lines[f][l];
114 }
115 }
116 return set != 0;
117}
105 118
106u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) 119u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
107{ 120{
@@ -150,7 +163,7 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
150 163
151 vbifmt->sampling_rate = 27000000; 164 vbifmt->sampling_rate = 27000000;
152 vbifmt->offset = 248; 165 vbifmt->offset = 248;
153 vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4; 166 vbifmt->samples_per_line = vbi_active_samples - 4;
154 vbifmt->sample_format = V4L2_PIX_FMT_GREY; 167 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
155 vbifmt->start[0] = cx->vbi.start[0]; 168 vbifmt->start[0] = cx->vbi.start[0];
156 vbifmt->start[1] = cx->vbi.start[1]; 169 vbifmt->start[1] = cx->vbi.start[1];
@@ -164,7 +177,17 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
164static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, 177static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
165 struct v4l2_format *fmt) 178 struct v4l2_format *fmt)
166{ 179{
167 return -EINVAL; 180 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
181 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
182
183 vbifmt->reserved[0] = 0;
184 vbifmt->reserved[1] = 0;
185 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
186 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
187
188 cx18_av_cmd(cx, VIDIOC_G_FMT, fmt);
189 vbifmt->service_set = cx18_get_service_set(vbifmt);
190 return 0;
168} 191}
169 192
170static int cx18_try_fmt_vid_cap(struct file *file, void *fh, 193static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
@@ -194,7 +217,18 @@ static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
194static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, 217static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
195 struct v4l2_format *fmt) 218 struct v4l2_format *fmt)
196{ 219{
197 return -EINVAL; 220 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
221 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
222
223 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
224 vbifmt->reserved[0] = 0;
225 vbifmt->reserved[1] = 0;
226
227 if (vbifmt->service_set)
228 cx18_expand_service_set(vbifmt, cx->is_50hz);
229 check_service_set(vbifmt, cx->is_50hz);
230 vbifmt->service_set = cx18_get_service_set(vbifmt);
231 return 0;
198} 232}
199 233
200static int cx18_s_fmt_vid_cap(struct file *file, void *fh, 234static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
@@ -250,7 +284,28 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
250static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, 284static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
251 struct v4l2_format *fmt) 285 struct v4l2_format *fmt)
252{ 286{
253 return -EINVAL; 287 struct cx18_open_id *id = fh;
288 struct cx18 *cx = id->cx;
289 int ret;
290 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
291
292 ret = v4l2_prio_check(&cx->prio, &id->prio);
293 if (ret)
294 return ret;
295
296 ret = cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
297 if (ret)
298 return ret;
299
300 if (check_service_set(vbifmt, cx->is_50hz) == 0)
301 return -EINVAL;
302
303 if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
304 return -EBUSY;
305 cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
306 cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
307 memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
308 return 0;
254} 309}
255 310
256static int cx18_g_chip_ident(struct file *file, void *fh, 311static int cx18_g_chip_ident(struct file *file, void *fh,
@@ -548,7 +603,6 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
548 cx->vbi.count = cx->is_50hz ? 18 : 12; 603 cx->vbi.count = cx->is_50hz ? 18 : 12;
549 cx->vbi.start[0] = cx->is_50hz ? 6 : 10; 604 cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
550 cx->vbi.start[1] = cx->is_50hz ? 318 : 273; 605 cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
551 cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284;
552 CX18_DEBUG_INFO("Switching standard to %llx.\n", 606 CX18_DEBUG_INFO("Switching standard to %llx.\n",
553 (unsigned long long) cx->std); 607 (unsigned long long) cx->std);
554 608
@@ -599,6 +653,19 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
599static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, 653static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
600 struct v4l2_sliced_vbi_cap *cap) 654 struct v4l2_sliced_vbi_cap *cap)
601{ 655{
656 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
657 int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
658 int f, l;
659
660 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
661 for (f = 0; f < 2; f++) {
662 for (l = 0; l < 24; l++) {
663 if (valid_service_line(f, l, cx->is_50hz))
664 cap->service_lines[f][l] = set;
665 }
666 }
667 return 0;
668 }
602 return -EINVAL; 669 return -EINVAL;
603} 670}
604 671
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index abc3fe605f00..a89f7f840d95 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -349,10 +349,6 @@ static void cx18_vbi_setup(struct cx18_stream *s)
349 /* setup VBI registers */ 349 /* setup VBI registers */
350 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); 350 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
351 351
352 /* determine number of lines and total number of VBI bytes.
353 A raw line takes 1444 bytes: 4 byte SAV code + 2 * 720
354 A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
355 header, 42 data bytes + checksum (to be confirmed) */
356 if (raw) { 352 if (raw) {
357 lines = cx->vbi.count * 2; 353 lines = cx->vbi.count * 2;
358 } else { 354 } else {
@@ -361,24 +357,53 @@ static void cx18_vbi_setup(struct cx18_stream *s)
361 lines += 2; 357 lines += 2;
362 } 358 }
363 359
364 cx->vbi.enc_size = lines *
365 (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
366
367 data[0] = s->handle; 360 data[0] = s->handle;
368 /* Lines per field */ 361 /* Lines per field */
369 data[1] = (lines / 2) | ((lines / 2) << 16); 362 data[1] = (lines / 2) | ((lines / 2) << 16);
370 /* bytes per line */ 363 /* bytes per line */
371 data[2] = (raw ? cx->vbi.raw_decoder_line_size 364 data[2] = (raw ? vbi_active_samples
372 : cx->vbi.sliced_decoder_line_size); 365 : (cx->is_60hz ? vbi_hblank_samples_60Hz
366 : vbi_hblank_samples_50Hz));
373 /* Every X number of frames a VBI interrupt arrives 367 /* Every X number of frames a VBI interrupt arrives
374 (frames as in 25 or 30 fps) */ 368 (frames as in 25 or 30 fps) */
375 data[3] = 1; 369 data[3] = 1;
376 /* Setup VBI for the cx25840 digitizer */ 370 /*
371 * Set the SAV/EAV RP codes to look for as start/stop points
372 * when in VIP-1.1 mode
373 */
377 if (raw) { 374 if (raw) {
375 /*
376 * Start codes for beginning of "active" line in vertical blank
377 * 0x20 ( VerticalBlank )
378 * 0x60 ( EvenField VerticalBlank )
379 */
378 data[4] = 0x20602060; 380 data[4] = 0x20602060;
381 /*
382 * End codes for end of "active" raw lines and regular lines
383 * 0x30 ( VerticalBlank HorizontalBlank)
384 * 0x70 ( EvenField VerticalBlank HorizontalBlank)
385 * 0x90 (Task HorizontalBlank)
386 * 0xd0 (Task EvenField HorizontalBlank)
387 */
379 data[5] = 0x307090d0; 388 data[5] = 0x307090d0;
380 } else { 389 } else {
390 /*
391 * End codes for active video, we want data in the hblank region
392 * 0xb0 (Task 0 VerticalBlank HorizontalBlank)
393 * 0xf0 (Task EvenField VerticalBlank HorizontalBlank)
394 *
395 * Since the V bit is only allowed to toggle in the EAV RP code,
396 * just before the first active region line, these two
397 * are problematic and we have to ignore them:
398 * 0x90 (Task HorizontalBlank)
399 * 0xd0 (Task EvenField HorizontalBlank)
400 */
381 data[4] = 0xB0F0B0F0; 401 data[4] = 0xB0F0B0F0;
402 /*
403 * Start codes for beginning of active line in vertical blank
404 * 0xa0 (Task VerticalBlank )
405 * 0xe0 (Task EvenField VerticalBlank )
406 */
382 data[5] = 0xA0E0A0E0; 407 data[5] = 0xA0E0A0E0;
383 } 408 }
384 409
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index fb595bd548e8..38d26c42e4cb 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -27,6 +27,16 @@
27#include "cx18-queue.h" 27#include "cx18-queue.h"
28#include "cx18-av-core.h" 28#include "cx18-av-core.h"
29 29
30/*
31 * Raster Reference/Protection (RP) bytes, used in Start/End Active
32 * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start
33 * of VBI sample or VBI ancilliary data regions in the digitial ratser line.
34 *
35 * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0
36 */
37static const u8 raw_vbi_sav_rp[2] = { 0x20, 0x60 }; /* __V_, _FV_ */
38static const u8 sliced_vbi_eav_rp[2] = { 0xb0, 0xf0 }; /* T_VH, TFVH */
39
30static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) 40static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
31{ 41{
32 int line = 0; 42 int line = 0;
@@ -34,10 +44,17 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
34 u32 linemask[2] = { 0, 0 }; 44 u32 linemask[2] = { 0, 0 };
35 unsigned short size; 45 unsigned short size;
36 static const u8 mpeg_hdr_data[] = { 46 static const u8 mpeg_hdr_data[] = {
37 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66, 47 /* MPEG-2 Program Pack */
38 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff, 48 0x00, 0x00, 0x01, 0xba, /* Prog Pack start code */
39 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80, 49 0x44, 0x00, 0x0c, 0x66, 0x24, 0x01, /* SCR, SCR Ext, markers */
40 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff 50 0x01, 0xd1, 0xd3, /* Mux Rate, markers */
51 0xfa, 0xff, 0xff, /* Res, Suff cnt, Stuff */
52 /* MPEG-2 Private Stream 1 PES Packet */
53 0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */
54 0x00, 0x1a, /* length */
55 0x84, 0x80, 0x07, /* flags, hdr data len */
56 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */
57 0xff, 0xff /* stuffing */
41 }; 58 };
42 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */ 59 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
43 int idx = cx->vbi.frame % CX18_VBI_FRAMES; 60 int idx = cx->vbi.frame % CX18_VBI_FRAMES;
@@ -71,7 +88,7 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
71 memcpy(dst + sd + 4, dst + sd + 12, line * 43); 88 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
72 size = 4 + ((43 * line + 3) & ~3); 89 size = 4 + ((43 * line + 3) & ~3);
73 } else { 90 } else {
74 memcpy(dst + sd, "cx0", 4); 91 memcpy(dst + sd, "itv0", 4);
75 memcpy(dst + sd + 4, &linemask[0], 8); 92 memcpy(dst + sd + 4, &linemask[0], 8);
76 size = 12 + ((43 * line + 3) & ~3); 93 size = 12 + ((43 * line + 3) & ~3);
77 } 94 }
@@ -90,10 +107,10 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
90 Returns new compressed size. */ 107 Returns new compressed size. */
91static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size) 108static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
92{ 109{
93 u32 line_size = cx->vbi.raw_decoder_line_size; 110 u32 line_size = vbi_active_samples;
94 u32 lines = cx->vbi.count; 111 u32 lines = cx->vbi.count;
95 u8 sav1 = cx->vbi.raw_decoder_sav_odd_field; 112 u8 sav1 = raw_vbi_sav_rp[0];
96 u8 sav2 = cx->vbi.raw_decoder_sav_even_field; 113 u8 sav2 = raw_vbi_sav_rp[1];
97 u8 *q = buf; 114 u8 *q = buf;
98 u8 *p; 115 u8 *p;
99 int i; 116 int i;
@@ -115,15 +132,16 @@ static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
115/* Compressed VBI format, all found sliced blocks put next to one another 132/* Compressed VBI format, all found sliced blocks put next to one another
116 Returns new compressed size */ 133 Returns new compressed size */
117static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf, 134static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
118 u32 size, u8 sav) 135 u32 size, u8 eav)
119{ 136{
120 u32 line_size = cx->vbi.sliced_decoder_line_size;
121 struct v4l2_decode_vbi_line vbi; 137 struct v4l2_decode_vbi_line vbi;
122 int i; 138 int i;
139 u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz
140 : vbi_hblank_samples_50Hz;
123 141
124 /* find the first valid line */ 142 /* find the first valid line */
125 for (i = 0; i < size; i++, buf++) { 143 for (i = 0; i < size; i++, buf++) {
126 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav) 144 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == eav)
127 break; 145 break;
128 } 146 }
129 147
@@ -133,8 +151,8 @@ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
133 for (i = 0; i < size / line_size; i++) { 151 for (i = 0; i < size / line_size; i++) {
134 u8 *p = buf + i * line_size; 152 u8 *p = buf + i * line_size;
135 153
136 /* Look for SAV code */ 154 /* Look for EAV code */
137 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) 155 if (p[0] != 0xff || p[1] || p[2] || p[3] != eav)
138 continue; 156 continue;
139 vbi.p = p + 4; 157 vbi.p = p + 4;
140 cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi); 158 cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
@@ -159,6 +177,12 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
159 if (streamtype != CX18_ENC_STREAM_TYPE_VBI) 177 if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
160 return; 178 return;
161 179
180 /*
181 * Note the CX23418 provides a 12 byte header, in it's raw VBI
182 * buffers to us, that we currently throw away:
183 * 0x3fffffff [4 bytes of something] [4 byte timestamp]
184 */
185
162 /* Raw VBI data */ 186 /* Raw VBI data */
163 if (cx18_raw_vbi(cx)) { 187 if (cx18_raw_vbi(cx)) {
164 u8 type; 188 u8 type;
@@ -173,7 +197,7 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
173 size = buf->bytesused = compress_raw_buf(cx, p, size); 197 size = buf->bytesused = compress_raw_buf(cx, p, size);
174 198
175 /* second field of the frame? */ 199 /* second field of the frame? */
176 if (type == cx->vbi.raw_decoder_sav_even_field) { 200 if (type == raw_vbi_sav_rp[1]) {
177 /* Dirty hack needed for backwards 201 /* Dirty hack needed for backwards
178 compatibility of old VBI software. */ 202 compatibility of old VBI software. */
179 p += size - 4; 203 p += size - 4;
@@ -187,14 +211,14 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
187 cx18_buf_swap(buf); 211 cx18_buf_swap(buf);
188 212
189 /* first field */ 213 /* first field */
190 lines = compress_sliced_buf(cx, 0, p, size / 2, 214 /* compress_sliced_buf() will skip the 12 bytes of header */
191 cx->vbi.sliced_decoder_sav_odd_field); 215 lines = compress_sliced_buf(cx, 0, p, size / 2, sliced_vbi_eav_rp[0]);
192 /* second field */ 216 /* second field */
193 /* experimentation shows that the second half does not always 217 /* experimentation shows that the second half does not always
194 begin at the exact address. So start a bit earlier 218 begin at the exact address. So start a bit earlier
195 (hence 32). */ 219 (hence 32). */
196 lines = compress_sliced_buf(cx, lines, p + size / 2 - 32, 220 lines = compress_sliced_buf(cx, lines, p + size / 2 - 32,
197 size / 2 + 32, cx->vbi.sliced_decoder_sav_even_field); 221 size / 2 + 32, sliced_vbi_eav_rp[1]);
198 /* always return at least one empty line */ 222 /* always return at least one empty line */
199 if (lines == 0) { 223 if (lines == 0) {
200 cx->vbi.sliced_data[0].id = 0; 224 cx->vbi.sliced_data[0].id = 0;