V4L/DVB (10441): cx18: Fix VBI ioctl() handling and Raw/Sliced VBI state management
[linux-2.6/kvm.git] / drivers / media / video / cx18 / cx18-av-vbi.c
blobb5763372a316c766c0e317d30310ee16a0c22042
1 /*
2 * cx18 ADEC VBI functions
4 * Derived from cx25840-vbi.c
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
25 #include "cx18-driver.h"
28 * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode,
29 * NN counts 1 byte Dwords, an IDID with the VBI line # in it.
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: VBI-line-# 0x80
39 * NN data bytes
40 * 1 byte checksum
41 * Fill bytes needed to fil out to 4*NN bytes of payload
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)
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)
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)
58 static const u8 sliced_vbi_did[2] = { 0x91, 0x55 };
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]; /* data_count of payload */
69 /* u8 checksum; */
70 /* u8 fill[]; Variable number of fill bytes */
73 static int odd_parity(u8 c)
75 c ^= (c >> 4);
76 c ^= (c >> 2);
77 c ^= (c >> 1);
79 return c & 1;
82 static int decode_vps(u8 *dst, u8 *p)
84 static const u8 biphase_tbl[] = {
85 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
86 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
87 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
88 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
89 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
90 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
91 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
92 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
93 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
94 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
95 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
96 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
97 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
98 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
99 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
100 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
101 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
102 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
103 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
104 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
105 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
106 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
107 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
108 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
109 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
110 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
111 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
112 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
113 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
114 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
115 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
116 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
119 u8 c, err = 0;
120 int i;
122 for (i = 0; i < 2 * 13; i += 2) {
123 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
124 c = (biphase_tbl[p[i + 1]] & 0xf) |
125 ((biphase_tbl[p[i]] & 0xf) << 4);
126 dst[i / 2] = c;
129 return err & 0xf0;
132 int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
134 struct cx18_av_state *state = &cx->av_state;
135 struct v4l2_format *fmt;
136 struct v4l2_sliced_vbi_format *svbi;
138 switch (cmd) {
139 case VIDIOC_G_FMT:
141 static u16 lcr2vbi[] = {
142 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
143 0, V4L2_SLICED_WSS_625, 0, /* 4 */
144 V4L2_SLICED_CAPTION_525, /* 6 */
145 V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 - unlike cx25840 */
146 0, 0, 0, 0
148 int is_pal = !(state->std & V4L2_STD_525_60);
149 int i;
151 fmt = arg;
152 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
153 return -EINVAL;
154 svbi = &fmt->fmt.sliced;
155 memset(svbi, 0, sizeof(*svbi));
156 /* we're done if raw VBI is active */
157 if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
158 break;
160 if (is_pal) {
161 for (i = 7; i <= 23; i++) {
162 u8 v = cx18_av_read(cx, 0x424 + i - 7);
164 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
165 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
166 svbi->service_set |= svbi->service_lines[0][i] |
167 svbi->service_lines[1][i];
169 } else {
170 for (i = 10; i <= 21; i++) {
171 u8 v = cx18_av_read(cx, 0x424 + i - 10);
173 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
174 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
175 svbi->service_set |= svbi->service_lines[0][i] |
176 svbi->service_lines[1][i];
179 break;
182 case VIDIOC_S_FMT:
184 int is_pal = !(state->std & V4L2_STD_525_60);
185 int vbi_offset = is_pal ? 1 : 0;
186 int i, x;
187 u8 lcr[24];
189 fmt = arg;
190 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
191 fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
192 return -EINVAL;
193 svbi = &fmt->fmt.sliced;
194 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
195 /* raw VBI */
196 memset(svbi, 0, sizeof(*svbi));
198 /* Setup standard */
199 cx18_av_std_setup(cx);
201 /* VBI Offset */
202 cx18_av_write(cx, 0x47f, vbi_offset);
203 cx18_av_write(cx, 0x404, 0x2e);
204 break;
207 for (x = 0; x <= 23; x++)
208 lcr[x] = 0x00;
210 /* Setup standard */
211 cx18_av_std_setup(cx);
213 /* Sliced VBI */
214 cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
215 cx18_av_write(cx, 0x406, 0x13);
216 cx18_av_write(cx, 0x47f, vbi_offset);
218 /* Force impossible lines to 0 */
219 if (is_pal) {
220 for (i = 0; i <= 6; i++)
221 svbi->service_lines[0][i] =
222 svbi->service_lines[1][i] = 0;
223 } else {
224 for (i = 0; i <= 9; i++)
225 svbi->service_lines[0][i] =
226 svbi->service_lines[1][i] = 0;
228 for (i = 22; i <= 23; i++)
229 svbi->service_lines[0][i] =
230 svbi->service_lines[1][i] = 0;
233 /* Build register values for requested service lines */
234 for (i = 7; i <= 23; i++) {
235 for (x = 0; x <= 1; x++) {
236 switch (svbi->service_lines[1-x][i]) {
237 case V4L2_SLICED_TELETEXT_B:
238 lcr[i] |= 1 << (4 * x);
239 break;
240 case V4L2_SLICED_WSS_625:
241 lcr[i] |= 4 << (4 * x);
242 break;
243 case V4L2_SLICED_CAPTION_525:
244 lcr[i] |= 6 << (4 * x);
245 break;
246 case V4L2_SLICED_VPS:
247 lcr[i] |= 7 << (4 * x); /*'840 differs*/
248 break;
253 if (is_pal) {
254 for (x = 1, i = 0x424; i <= 0x434; i++, x++)
255 cx18_av_write(cx, i, lcr[6 + x]);
256 } else {
257 for (x = 1, i = 0x424; i <= 0x430; i++, x++)
258 cx18_av_write(cx, i, lcr[9 + x]);
259 for (i = 0x431; i <= 0x434; i++)
260 cx18_av_write(cx, i, 0);
263 cx18_av_write(cx, 0x43c, 0x16);
264 cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22);
265 break;
268 case VIDIOC_INT_DECODE_VBI_LINE:
270 struct v4l2_decode_vbi_line *vbi = arg;
271 u8 *p;
272 struct vbi_anc_data *anc = (struct vbi_anc_data *) vbi->p;
273 int did, sdid, l, err = 0;
276 * Check for the ancillary data header for sliced VBI
278 if (anc->preamble[0] ||
279 anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
280 (anc->did != sliced_vbi_did[0] &&
281 anc->did != sliced_vbi_did[1])) {
282 vbi->line = vbi->type = 0;
283 break;
286 did = anc->did;
287 sdid = anc->sdid & 0xf;
288 l = anc->idid[0] & 0x3f;
289 l += state->vbi_line_offset;
290 p = anc->payload;
292 /* Decode the SDID set by the slicer */
293 switch (sdid) {
294 case 1:
295 sdid = V4L2_SLICED_TELETEXT_B;
296 break;
297 case 4:
298 sdid = V4L2_SLICED_WSS_625;
299 break;
300 case 6:
301 sdid = V4L2_SLICED_CAPTION_525;
302 err = !odd_parity(p[0]) || !odd_parity(p[1]);
303 break;
304 case 7: /* Differs from cx25840 */
305 sdid = V4L2_SLICED_VPS;
306 if (decode_vps(p, p) != 0)
307 err = 1;
308 break;
309 default:
310 sdid = 0;
311 err = 1;
312 break;
315 vbi->type = err ? 0 : sdid;
316 vbi->line = err ? 0 : l;
317 vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
318 vbi->p = p;
319 break;
323 return 0;