diff options
author | Andy Walls <awalls@radix.net> | 2009-01-30 22:33:02 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:38 -0400 |
commit | 302df9702192a68578916ef922c33370cbba350d (patch) | |
tree | eab3173a4b82ec26c89b82c50e9bfb0fe2477953 /drivers/media/video/cx18/cx18-av-vbi.c | |
parent | 4325dff220918c2ced82d16c3475d9a5afb1cab3 (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/media/video/cx18/cx18-av-vbi.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-av-vbi.c | 92 |
1 files changed, 72 insertions, 20 deletions
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c index 1527ea4f6b0..72325d774a6 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 | */ | ||
58 | static const u8 sliced_vbi_did[2] = { 0x91, 0x55 }; | ||
59 | |||
60 | struct 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 | |||
27 | static int odd_parity(u8 c) | 73 | static 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 | } |