blob: 7275f2d6597e666e53f8cec6f4c2f491f35f9a8d [file] [log] [blame]
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001/*
2 Vertical Blank Interval support functions
3 Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "ivtv-driver.h"
Hans Verkuil33c0fca2007-08-23 06:32:46 -030021#include "ivtv-i2c.h"
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030022#include "ivtv-ioctl.h"
23#include "ivtv-queue.h"
Hans Verkuil67ec09f2008-11-29 19:38:23 -030024#include "ivtv-cards.h"
Hans Verkuil33c0fca2007-08-23 06:32:46 -030025#include "ivtv-vbi.h"
26
Hans Verkuil2f3a9892007-08-25 14:11:23 -030027static void ivtv_set_vps(struct ivtv *itv, int enabled)
Hans Verkuil33c0fca2007-08-23 06:32:46 -030028{
29 struct v4l2_sliced_vbi_data data;
30
31 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
32 return;
33 data.id = V4L2_SLICED_VPS;
34 data.field = 0;
35 data.line = enabled ? 16 : 0;
Hans Verkuil2f3a9892007-08-25 14:11:23 -030036 data.data[2] = itv->vbi.vps_payload.data[0];
37 data.data[8] = itv->vbi.vps_payload.data[1];
38 data.data[9] = itv->vbi.vps_payload.data[2];
39 data.data[10] = itv->vbi.vps_payload.data[3];
40 data.data[11] = itv->vbi.vps_payload.data[4];
Hans Verkuil32cd5272010-03-14 09:57:30 -030041 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
Hans Verkuil33c0fca2007-08-23 06:32:46 -030042}
43
Hans Verkuil2f3a9892007-08-25 14:11:23 -030044static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
Hans Verkuil33c0fca2007-08-23 06:32:46 -030045{
46 struct v4l2_sliced_vbi_data data;
47
48 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
49 return;
50 data.id = V4L2_SLICED_CAPTION_525;
51 data.field = 0;
52 data.line = (mode & 1) ? 21 : 0;
Hans Verkuil2f3a9892007-08-25 14:11:23 -030053 data.data[0] = cc->odd[0];
54 data.data[1] = cc->odd[1];
Hans Verkuil32cd5272010-03-14 09:57:30 -030055 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
Hans Verkuil33c0fca2007-08-23 06:32:46 -030056 data.field = 1;
57 data.line = (mode & 2) ? 21 : 0;
Hans Verkuil2f3a9892007-08-25 14:11:23 -030058 data.data[0] = cc->even[0];
59 data.data[1] = cc->even[1];
Hans Verkuil32cd5272010-03-14 09:57:30 -030060 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
Hans Verkuil33c0fca2007-08-23 06:32:46 -030061}
62
63static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
64{
65 struct v4l2_sliced_vbi_data data;
66
67 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
68 return;
69 /* When using a 50 Hz system, always turn on the
70 wide screen signal with 4x3 ratio as the default.
71 Turning this signal on and off can confuse certain
72 TVs. As far as I can tell there is no reason not to
73 transmit this signal. */
74 if ((itv->std & V4L2_STD_625_50) && !enabled) {
75 enabled = 1;
76 mode = 0x08; /* 4x3 full format */
77 }
78 data.id = V4L2_SLICED_WSS_625;
79 data.field = 0;
80 data.line = enabled ? 23 : 0;
81 data.data[0] = mode & 0xff;
82 data.data[1] = (mode >> 8) & 0xff;
Hans Verkuil32cd5272010-03-14 09:57:30 -030083 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
Hans Verkuil33c0fca2007-08-23 06:32:46 -030084}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030085
86static int odd_parity(u8 c)
87{
88 c ^= (c >> 4);
89 c ^= (c >> 2);
90 c ^= (c >> 1);
91
92 return c & 1;
93}
94
Andy Wallsb0c45682010-12-18 10:48:17 -030095static void ivtv_write_vbi_line(struct ivtv *itv,
96 const struct v4l2_sliced_vbi_data *d,
97 struct vbi_cc *cc, int *found_cc)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030098{
Hans Verkuil2f3a9892007-08-25 14:11:23 -030099 struct vbi_info *vi = &itv->vbi;
Andy Wallsb0c45682010-12-18 10:48:17 -0300100
101 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
102 if (d->field) {
103 cc->even[0] = d->data[0];
104 cc->even[1] = d->data[1];
105 } else {
106 cc->odd[0] = d->data[0];
107 cc->odd[1] = d->data[1];
108 }
109 *found_cc = 1;
110 } else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
111 struct vbi_vps vps;
112
113 vps.data[0] = d->data[2];
114 vps.data[1] = d->data[8];
115 vps.data[2] = d->data[9];
116 vps.data[3] = d->data[10];
117 vps.data[4] = d->data[11];
118 if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
119 vi->vps_payload = vps;
120 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
121 }
122 } else if (d->id == V4L2_SLICED_WSS_625 &&
123 d->line == 23 && d->field == 0) {
124 int wss = d->data[0] | d->data[1] << 8;
125
126 if (vi->wss_payload != wss) {
127 vi->wss_payload = wss;
128 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
129 }
130 }
131}
132
133static void ivtv_write_vbi_cc_lines(struct ivtv *itv, const struct vbi_cc *cc)
134{
135 struct vbi_info *vi = &itv->vbi;
136
137 if (vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
138 memcpy(&vi->cc_payload[vi->cc_payload_idx], cc,
139 sizeof(struct vbi_cc));
140 vi->cc_payload_idx++;
141 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
142 }
143}
144
145static void ivtv_write_vbi(struct ivtv *itv,
146 const struct v4l2_sliced_vbi_data *sliced,
147 size_t cnt)
148{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300149 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300150 int found_cc = 0;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300151 size_t i;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300152
Andy Wallsb0c45682010-12-18 10:48:17 -0300153 for (i = 0; i < cnt; i++)
154 ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
155
156 if (found_cc)
157 ivtv_write_vbi_cc_lines(itv, &cc);
158}
159
160void ivtv_write_vbi_from_user(struct ivtv *itv,
161 const struct v4l2_sliced_vbi_data __user *sliced,
162 size_t cnt)
163{
164 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
165 int found_cc = 0;
166 size_t i;
167 struct v4l2_sliced_vbi_data d;
168
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300169 for (i = 0; i < cnt; i++) {
Andy Wallsb0c45682010-12-18 10:48:17 -0300170 if (copy_from_user(&d, sliced + i,
171 sizeof(struct v4l2_sliced_vbi_data)))
172 break;
173 ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300174 }
Andy Wallsb0c45682010-12-18 10:48:17 -0300175
176 if (found_cc)
177 ivtv_write_vbi_cc_lines(itv, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300178}
179
180static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
181{
182 int line = 0;
183 int i;
184 u32 linemask[2] = { 0, 0 };
185 unsigned short size;
186 static const u8 mpeg_hdr_data[] = {
187 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
188 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
189 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
190 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
191 };
192 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
193 int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
194 u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
195
196 for (i = 0; i < lines; i++) {
197 int f, l;
198
199 if (itv->vbi.sliced_data[i].id == 0)
200 continue;
201
202 l = itv->vbi.sliced_data[i].line - 6;
203 f = itv->vbi.sliced_data[i].field;
204 if (f)
205 l += 18;
206 if (l < 32)
207 linemask[0] |= (1 << l);
208 else
209 linemask[1] |= (1 << (l - 32));
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300210 dst[sd + 12 + line * 43] =
211 ivtv_service2vbi(itv->vbi.sliced_data[i].id);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300212 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
213 line++;
214 }
215 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
216 if (line == 36) {
217 /* All lines are used, so there is no space for the linemask
218 (the max size of the VBI data is 36 * 43 + 4 bytes).
219 So in this case we use the magic number 'ITV0'. */
220 memcpy(dst + sd, "ITV0", 4);
221 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
222 size = 4 + ((43 * line + 3) & ~3);
223 } else {
224 memcpy(dst + sd, "itv0", 4);
Andy Walls6e1a63722009-03-14 20:03:26 -0300225 cpu_to_le32s(&linemask[0]);
226 cpu_to_le32s(&linemask[1]);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300227 memcpy(dst + sd + 4, &linemask[0], 8);
228 size = 12 + ((43 * line + 3) & ~3);
229 }
230 dst[4+16] = (size + 10) >> 8;
231 dst[5+16] = (size + 10) & 0xff;
232 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
233 dst[10+16] = (pts_stamp >> 22) & 0xff;
234 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
235 dst[12+16] = (pts_stamp >> 7) & 0xff;
236 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
237 itv->vbi.sliced_mpeg_size[idx] = sd + size;
238}
239
240static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
241{
242 u32 linemask[2];
243 int i, l, id2;
244 int line = 0;
245
246 if (!memcmp(p, "itv0", 4)) {
247 memcpy(linemask, p + 4, 8);
248 p += 12;
249 } else if (!memcmp(p, "ITV0", 4)) {
250 linemask[0] = 0xffffffff;
251 linemask[1] = 0xf;
252 p += 4;
253 } else {
Hans Verkuil51a99c02007-08-18 15:16:00 -0300254 /* unknown VBI data, convert to empty VBI frame */
255 linemask[0] = linemask[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300256 }
257 for (i = 0; i < 36; i++) {
258 int err = 0;
259
260 if (i < 32 && !(linemask[0] & (1 << i)))
261 continue;
262 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
263 continue;
264 id2 = *p & 0xf;
265 switch (id2) {
266 case IVTV_SLICED_TYPE_TELETEXT_B:
267 id2 = V4L2_SLICED_TELETEXT_B;
268 break;
269 case IVTV_SLICED_TYPE_CAPTION_525:
270 id2 = V4L2_SLICED_CAPTION_525;
271 err = !odd_parity(p[1]) || !odd_parity(p[2]);
272 break;
273 case IVTV_SLICED_TYPE_VPS:
274 id2 = V4L2_SLICED_VPS;
275 break;
276 case IVTV_SLICED_TYPE_WSS_625:
277 id2 = V4L2_SLICED_WSS_625;
278 break;
279 default:
280 id2 = 0;
281 break;
282 }
283 if (err == 0) {
284 l = (i < 18) ? i + 6 : i - 18 + 6;
285 itv->vbi.sliced_dec_data[line].line = l;
286 itv->vbi.sliced_dec_data[line].field = i >= 18;
287 itv->vbi.sliced_dec_data[line].id = id2;
288 memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
289 line++;
290 }
291 p += 43;
292 }
293 while (line < 36) {
294 itv->vbi.sliced_dec_data[line].id = 0;
295 itv->vbi.sliced_dec_data[line].line = 0;
296 itv->vbi.sliced_dec_data[line].field = 0;
297 line++;
298 }
299 return line * sizeof(itv->vbi.sliced_dec_data[0]);
300}
301
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300302/* Compress raw VBI format, removes leading SAV codes and surplus space after the
303 field.
304 Returns new compressed size. */
305static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
306{
307 u32 line_size = itv->vbi.raw_decoder_line_size;
308 u32 lines = itv->vbi.count;
309 u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
310 u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
311 u8 *q = buf;
312 u8 *p;
313 int i;
314
315 for (i = 0; i < lines; i++) {
316 p = buf + i * line_size;
317
318 /* Look for SAV code */
319 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
320 break;
321 }
322 memcpy(q, p + 4, line_size - 4);
323 q += line_size - 4;
324 }
325 return lines * (line_size - 4);
326}
327
328
329/* Compressed VBI format, all found sliced blocks put next to one another
330 Returns new compressed size */
331static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
332{
333 u32 line_size = itv->vbi.sliced_decoder_line_size;
334 struct v4l2_decode_vbi_line vbi;
335 int i;
Hans Verkuild526afe2008-09-03 16:47:14 -0300336 unsigned lines = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300337
338 /* find the first valid line */
339 for (i = 0; i < size; i++, buf++) {
340 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
341 break;
342 }
343
344 size -= i;
345 if (size < line_size) {
346 return line;
347 }
348 for (i = 0; i < size / line_size; i++) {
349 u8 *p = buf + i * line_size;
350
351 /* Look for SAV code */
352 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
353 continue;
354 }
355 vbi.p = p + 4;
Hans Verkuil32cd5272010-03-14 09:57:30 -0300356 v4l2_subdev_call(itv->sd_video, vbi, decode_vbi_line, &vbi);
Hans Verkuild526afe2008-09-03 16:47:14 -0300357 if (vbi.type && !(lines & (1 << vbi.line))) {
358 lines |= 1 << vbi.line;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300359 itv->vbi.sliced_data[line].id = vbi.type;
360 itv->vbi.sliced_data[line].field = vbi.is_second_field;
361 itv->vbi.sliced_data[line].line = vbi.line;
362 memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
363 line++;
364 }
365 }
366 return line;
367}
368
369void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
370 u64 pts_stamp, int streamtype)
371{
372 u8 *p = (u8 *) buf->buf;
373 u32 size = buf->bytesused;
374 int y;
375
376 /* Raw VBI data */
Hans Verkuila8b86432008-10-04 08:05:30 -0300377 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300378 u8 type;
379
380 ivtv_buf_swap(buf);
381
382 type = p[3];
383
384 size = buf->bytesused = compress_raw_buf(itv, p, size);
385
386 /* second field of the frame? */
387 if (type == itv->vbi.raw_decoder_sav_even_field) {
388 /* Dirty hack needed for backwards
389 compatibility of old VBI software. */
390 p += size - 4;
391 memcpy(p, &itv->vbi.frame, 4);
392 itv->vbi.frame++;
393 }
394 return;
395 }
396
397 /* Sliced VBI data with data insertion */
398 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
399 int lines;
400
401 ivtv_buf_swap(buf);
402
403 /* first field */
404 lines = compress_sliced_buf(itv, 0, p, size / 2,
405 itv->vbi.sliced_decoder_sav_odd_field);
406 /* second field */
407 /* experimentation shows that the second half does not always begin
408 at the exact address. So start a bit earlier (hence 32). */
409 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
410 itv->vbi.sliced_decoder_sav_even_field);
411 /* always return at least one empty line */
412 if (lines == 0) {
413 itv->vbi.sliced_data[0].id = 0;
414 itv->vbi.sliced_data[0].line = 0;
415 itv->vbi.sliced_data[0].field = 0;
416 lines = 1;
417 }
418 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
419 memcpy(p, &itv->vbi.sliced_data[0], size);
420
421 if (itv->vbi.insert_mpeg) {
422 copy_vbi_data(itv, lines, pts_stamp);
423 }
424 itv->vbi.frame++;
425 return;
426 }
427
428 /* Sliced VBI re-inserted from an MPEG stream */
429 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
430 /* If the size is not 4-byte aligned, then the starting address
431 for the swapping is also shifted. After swapping the data the
432 real start address of the VBI data is exactly 4 bytes after the
433 original start. It's a bit fiddly but it works like a charm.
434 Non-4-byte alignment happens when an lseek is done on the input
435 mpeg file to a non-4-byte aligned position. So on arrival here
436 the VBI data is also non-4-byte aligned. */
437 int offset = size & 3;
438 int cnt;
439
440 if (offset) {
441 p += 4 - offset;
442 }
443 /* Swap Buffer */
444 for (y = 0; y < size; y += 4) {
445 swab32s((u32 *)(p + y));
446 }
447
448 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
449 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
450 buf->bytesused = cnt;
451
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300452 ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
453 cnt / sizeof(itv->vbi.sliced_dec_data[0]));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300454 return;
455 }
456}
457
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300458void ivtv_disable_cc(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300459{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300460 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
461
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300462 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300463 ivtv_set_cc(itv, 0, &cc);
464 itv->vbi.cc_payload_idx = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300465}
466
Hans Verkuil1e13f9e2007-03-10 06:52:02 -0300467
Hans Verkuildc02d502007-05-19 14:07:16 -0300468void ivtv_vbi_work_handler(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300469{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300470 struct vbi_info *vi = &itv->vbi;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300471 struct v4l2_sliced_vbi_data data;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300472 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300473
474 /* Lock */
475 if (itv->output_mode == OUT_PASSTHROUGH) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300476 if (itv->is_50hz) {
477 data.id = V4L2_SLICED_WSS_625;
478 data.field = 0;
479
Hans Verkuil32cd5272010-03-14 09:57:30 -0300480 if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300481 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300482 vi->wss_missing_cnt = 0;
483 } else if (vi->wss_missing_cnt == 4) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300484 ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
485 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300486 vi->wss_missing_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300487 }
488 }
489 else {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300490 int mode = 0;
491
492 data.id = V4L2_SLICED_CAPTION_525;
493 data.field = 0;
Hans Verkuil32cd5272010-03-14 09:57:30 -0300494 if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300495 mode |= 1;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300496 cc.odd[0] = data.data[0];
497 cc.odd[1] = data.data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300498 }
499 data.field = 1;
Hans Verkuil32cd5272010-03-14 09:57:30 -0300500 if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300501 mode |= 2;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300502 cc.even[0] = data.data[0];
503 cc.even[1] = data.data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300504 }
505 if (mode) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300506 vi->cc_missing_cnt = 0;
507 ivtv_set_cc(itv, mode, &cc);
508 } else if (vi->cc_missing_cnt == 4) {
509 ivtv_set_cc(itv, 0, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300510 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300511 vi->cc_missing_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300512 }
513 }
514 return;
515 }
516
517 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300518 ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300519 }
520
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300521 if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
522 if (vi->cc_payload_idx == 0) {
523 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
524 ivtv_set_cc(itv, 3, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300525 }
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300526 while (vi->cc_payload_idx) {
527 cc = vi->cc_payload[0];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300528
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300529 memcpy(vi->cc_payload, vi->cc_payload + 1,
530 sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
531 vi->cc_payload_idx--;
532 if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300533 continue;
534
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300535 ivtv_set_cc(itv, 3, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300536 break;
537 }
538 }
539
540 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300541 ivtv_set_vps(itv, 1);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300542 }
543}