iwlwifi: introduce host commands callbacks
[linux/fpc-iii.git] / drivers / media / video / ivtv / ivtv-vbi.c
blobc151bcf5519ae92be2fd189b8f3856f593c04e74
1 /*
2 Vertical Blank Interval support functions
3 Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
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.
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.
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
20 #include "ivtv-driver.h"
21 #include "ivtv-i2c.h"
22 #include "ivtv-ioctl.h"
23 #include "ivtv-queue.h"
24 #include "ivtv-vbi.h"
26 static void ivtv_set_vps(struct ivtv *itv, int enabled)
28 struct v4l2_sliced_vbi_data data;
30 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
31 return;
32 data.id = V4L2_SLICED_VPS;
33 data.field = 0;
34 data.line = enabled ? 16 : 0;
35 data.data[2] = itv->vbi.vps_payload.data[0];
36 data.data[8] = itv->vbi.vps_payload.data[1];
37 data.data[9] = itv->vbi.vps_payload.data[2];
38 data.data[10] = itv->vbi.vps_payload.data[3];
39 data.data[11] = itv->vbi.vps_payload.data[4];
40 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
43 static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
45 struct v4l2_sliced_vbi_data data;
47 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
48 return;
49 data.id = V4L2_SLICED_CAPTION_525;
50 data.field = 0;
51 data.line = (mode & 1) ? 21 : 0;
52 data.data[0] = cc->odd[0];
53 data.data[1] = cc->odd[1];
54 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
55 data.field = 1;
56 data.line = (mode & 2) ? 21 : 0;
57 data.data[0] = cc->even[0];
58 data.data[1] = cc->even[1];
59 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
62 static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
64 struct v4l2_sliced_vbi_data data;
66 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
67 return;
68 /* When using a 50 Hz system, always turn on the
69 wide screen signal with 4x3 ratio as the default.
70 Turning this signal on and off can confuse certain
71 TVs. As far as I can tell there is no reason not to
72 transmit this signal. */
73 if ((itv->std & V4L2_STD_625_50) && !enabled) {
74 enabled = 1;
75 mode = 0x08; /* 4x3 full format */
77 data.id = V4L2_SLICED_WSS_625;
78 data.field = 0;
79 data.line = enabled ? 23 : 0;
80 data.data[0] = mode & 0xff;
81 data.data[1] = (mode >> 8) & 0xff;
82 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
85 static int odd_parity(u8 c)
87 c ^= (c >> 4);
88 c ^= (c >> 2);
89 c ^= (c >> 1);
91 return c & 1;
94 void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt)
96 struct vbi_info *vi = &itv->vbi;
97 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
98 int found_cc = 0;
99 size_t i;
101 for (i = 0; i < cnt; i++) {
102 const struct v4l2_sliced_vbi_data *d = sliced + i;
104 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
105 if (d->field) {
106 cc.even[0] = d->data[0];
107 cc.even[1] = d->data[1];
108 } else {
109 cc.odd[0] = d->data[0];
110 cc.odd[1] = d->data[1];
112 found_cc = 1;
114 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
115 struct vbi_vps vps;
117 vps.data[0] = d->data[2];
118 vps.data[1] = d->data[8];
119 vps.data[2] = d->data[9];
120 vps.data[3] = d->data[10];
121 vps.data[4] = d->data[11];
122 if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
123 vi->vps_payload = vps;
124 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
127 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
128 int wss = d->data[0] | d->data[1] << 8;
130 if (vi->wss_payload != wss) {
131 vi->wss_payload = wss;
132 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
136 if (found_cc && vi->cc_payload_idx < sizeof(vi->cc_payload)) {
137 vi->cc_payload[vi->cc_payload_idx++] = cc;
138 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
142 static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
144 int line = 0;
145 int i;
146 u32 linemask[2] = { 0, 0 };
147 unsigned short size;
148 static const u8 mpeg_hdr_data[] = {
149 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
150 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
151 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
152 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
154 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
155 int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
156 u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
158 for (i = 0; i < lines; i++) {
159 int f, l;
161 if (itv->vbi.sliced_data[i].id == 0)
162 continue;
164 l = itv->vbi.sliced_data[i].line - 6;
165 f = itv->vbi.sliced_data[i].field;
166 if (f)
167 l += 18;
168 if (l < 32)
169 linemask[0] |= (1 << l);
170 else
171 linemask[1] |= (1 << (l - 32));
172 dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id);
173 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
174 line++;
176 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
177 if (line == 36) {
178 /* All lines are used, so there is no space for the linemask
179 (the max size of the VBI data is 36 * 43 + 4 bytes).
180 So in this case we use the magic number 'ITV0'. */
181 memcpy(dst + sd, "ITV0", 4);
182 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
183 size = 4 + ((43 * line + 3) & ~3);
184 } else {
185 memcpy(dst + sd, "itv0", 4);
186 memcpy(dst + sd + 4, &linemask[0], 8);
187 size = 12 + ((43 * line + 3) & ~3);
189 dst[4+16] = (size + 10) >> 8;
190 dst[5+16] = (size + 10) & 0xff;
191 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
192 dst[10+16] = (pts_stamp >> 22) & 0xff;
193 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
194 dst[12+16] = (pts_stamp >> 7) & 0xff;
195 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
196 itv->vbi.sliced_mpeg_size[idx] = sd + size;
199 static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
201 u32 linemask[2];
202 int i, l, id2;
203 int line = 0;
205 if (!memcmp(p, "itv0", 4)) {
206 memcpy(linemask, p + 4, 8);
207 p += 12;
208 } else if (!memcmp(p, "ITV0", 4)) {
209 linemask[0] = 0xffffffff;
210 linemask[1] = 0xf;
211 p += 4;
212 } else {
213 /* unknown VBI data, convert to empty VBI frame */
214 linemask[0] = linemask[1] = 0;
216 for (i = 0; i < 36; i++) {
217 int err = 0;
219 if (i < 32 && !(linemask[0] & (1 << i)))
220 continue;
221 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
222 continue;
223 id2 = *p & 0xf;
224 switch (id2) {
225 case IVTV_SLICED_TYPE_TELETEXT_B:
226 id2 = V4L2_SLICED_TELETEXT_B;
227 break;
228 case IVTV_SLICED_TYPE_CAPTION_525:
229 id2 = V4L2_SLICED_CAPTION_525;
230 err = !odd_parity(p[1]) || !odd_parity(p[2]);
231 break;
232 case IVTV_SLICED_TYPE_VPS:
233 id2 = V4L2_SLICED_VPS;
234 break;
235 case IVTV_SLICED_TYPE_WSS_625:
236 id2 = V4L2_SLICED_WSS_625;
237 break;
238 default:
239 id2 = 0;
240 break;
242 if (err == 0) {
243 l = (i < 18) ? i + 6 : i - 18 + 6;
244 itv->vbi.sliced_dec_data[line].line = l;
245 itv->vbi.sliced_dec_data[line].field = i >= 18;
246 itv->vbi.sliced_dec_data[line].id = id2;
247 memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
248 line++;
250 p += 43;
252 while (line < 36) {
253 itv->vbi.sliced_dec_data[line].id = 0;
254 itv->vbi.sliced_dec_data[line].line = 0;
255 itv->vbi.sliced_dec_data[line].field = 0;
256 line++;
258 return line * sizeof(itv->vbi.sliced_dec_data[0]);
261 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
262 field.
263 Returns new compressed size. */
264 static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
266 u32 line_size = itv->vbi.raw_decoder_line_size;
267 u32 lines = itv->vbi.count;
268 u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
269 u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
270 u8 *q = buf;
271 u8 *p;
272 int i;
274 for (i = 0; i < lines; i++) {
275 p = buf + i * line_size;
277 /* Look for SAV code */
278 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
279 break;
281 memcpy(q, p + 4, line_size - 4);
282 q += line_size - 4;
284 return lines * (line_size - 4);
288 /* Compressed VBI format, all found sliced blocks put next to one another
289 Returns new compressed size */
290 static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
292 u32 line_size = itv->vbi.sliced_decoder_line_size;
293 struct v4l2_decode_vbi_line vbi;
294 int i;
296 /* find the first valid line */
297 for (i = 0; i < size; i++, buf++) {
298 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
299 break;
302 size -= i;
303 if (size < line_size) {
304 return line;
306 for (i = 0; i < size / line_size; i++) {
307 u8 *p = buf + i * line_size;
309 /* Look for SAV code */
310 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
311 continue;
313 vbi.p = p + 4;
314 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
315 if (vbi.type) {
316 itv->vbi.sliced_data[line].id = vbi.type;
317 itv->vbi.sliced_data[line].field = vbi.is_second_field;
318 itv->vbi.sliced_data[line].line = vbi.line;
319 memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
320 line++;
323 return line;
326 void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
327 u64 pts_stamp, int streamtype)
329 u8 *p = (u8 *) buf->buf;
330 u32 size = buf->bytesused;
331 int y;
333 /* Raw VBI data */
334 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
335 u8 type;
337 ivtv_buf_swap(buf);
339 type = p[3];
341 size = buf->bytesused = compress_raw_buf(itv, p, size);
343 /* second field of the frame? */
344 if (type == itv->vbi.raw_decoder_sav_even_field) {
345 /* Dirty hack needed for backwards
346 compatibility of old VBI software. */
347 p += size - 4;
348 memcpy(p, &itv->vbi.frame, 4);
349 itv->vbi.frame++;
351 return;
354 /* Sliced VBI data with data insertion */
355 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
356 int lines;
358 ivtv_buf_swap(buf);
360 /* first field */
361 lines = compress_sliced_buf(itv, 0, p, size / 2,
362 itv->vbi.sliced_decoder_sav_odd_field);
363 /* second field */
364 /* experimentation shows that the second half does not always begin
365 at the exact address. So start a bit earlier (hence 32). */
366 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
367 itv->vbi.sliced_decoder_sav_even_field);
368 /* always return at least one empty line */
369 if (lines == 0) {
370 itv->vbi.sliced_data[0].id = 0;
371 itv->vbi.sliced_data[0].line = 0;
372 itv->vbi.sliced_data[0].field = 0;
373 lines = 1;
375 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
376 memcpy(p, &itv->vbi.sliced_data[0], size);
378 if (itv->vbi.insert_mpeg) {
379 copy_vbi_data(itv, lines, pts_stamp);
381 itv->vbi.frame++;
382 return;
385 /* Sliced VBI re-inserted from an MPEG stream */
386 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
387 /* If the size is not 4-byte aligned, then the starting address
388 for the swapping is also shifted. After swapping the data the
389 real start address of the VBI data is exactly 4 bytes after the
390 original start. It's a bit fiddly but it works like a charm.
391 Non-4-byte alignment happens when an lseek is done on the input
392 mpeg file to a non-4-byte aligned position. So on arrival here
393 the VBI data is also non-4-byte aligned. */
394 int offset = size & 3;
395 int cnt;
397 if (offset) {
398 p += 4 - offset;
400 /* Swap Buffer */
401 for (y = 0; y < size; y += 4) {
402 swab32s((u32 *)(p + y));
405 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
406 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
407 buf->bytesused = cnt;
409 ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
410 cnt / sizeof(itv->vbi.sliced_dec_data[0]));
411 return;
415 void ivtv_disable_cc(struct ivtv *itv)
417 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
419 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
420 ivtv_set_cc(itv, 0, &cc);
421 itv->vbi.cc_payload_idx = 0;
425 void ivtv_vbi_work_handler(struct ivtv *itv)
427 struct vbi_info *vi = &itv->vbi;
428 struct v4l2_sliced_vbi_data data;
429 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
431 /* Lock */
432 if (itv->output_mode == OUT_PASSTHROUGH) {
433 if (itv->is_50hz) {
434 data.id = V4L2_SLICED_WSS_625;
435 data.field = 0;
437 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
438 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
439 vi->wss_missing_cnt = 0;
440 } else if (vi->wss_missing_cnt == 4) {
441 ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
442 } else {
443 vi->wss_missing_cnt++;
446 else {
447 int mode = 0;
449 data.id = V4L2_SLICED_CAPTION_525;
450 data.field = 0;
451 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
452 mode |= 1;
453 cc.odd[0] = data.data[0];
454 cc.odd[1] = data.data[1];
456 data.field = 1;
457 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
458 mode |= 2;
459 cc.even[0] = data.data[0];
460 cc.even[1] = data.data[1];
462 if (mode) {
463 vi->cc_missing_cnt = 0;
464 ivtv_set_cc(itv, mode, &cc);
465 } else if (vi->cc_missing_cnt == 4) {
466 ivtv_set_cc(itv, 0, &cc);
467 } else {
468 vi->cc_missing_cnt++;
471 return;
474 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
475 ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
478 if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
479 if (vi->cc_payload_idx == 0) {
480 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
481 ivtv_set_cc(itv, 3, &cc);
483 while (vi->cc_payload_idx) {
484 cc = vi->cc_payload[0];
486 memcpy(vi->cc_payload, vi->cc_payload + 1,
487 sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
488 vi->cc_payload_idx--;
489 if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
490 continue;
492 ivtv_set_cc(itv, 3, &cc);
493 break;
497 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
498 ivtv_set_vps(itv, 1);