Pull acpi-debug into release branch
[linux-2.6] / drivers / media / video / ivtv / ivtv-vbi.c
1 /*
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"
21 #include "ivtv-video.h"
22 #include "ivtv-vbi.h"
23 #include "ivtv-ioctl.h"
24 #include "ivtv-queue.h"
25
26 static int odd_parity(u8 c)
27 {
28         c ^= (c >> 4);
29         c ^= (c >> 2);
30         c ^= (c >> 1);
31
32         return c & 1;
33 }
34
35 static void passthrough_vbi_data(struct ivtv *itv, int cnt)
36 {
37         int wss = 0;
38         u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 };
39         u8 vps[13];
40         int found_cc = 0;
41         int found_wss = 0;
42         int found_vps = 0;
43         int cc_pos = itv->vbi.cc_pos;
44         int i;
45
46         for (i = 0; i < cnt; i++) {
47                 struct v4l2_sliced_vbi_data *d = itv->vbi.sliced_dec_data + i;
48
49                 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
50                         found_cc = 1;
51                         if (d->field) {
52                                 cc[2] = d->data[0];
53                                 cc[3] = d->data[1];
54                         } else {
55                                 cc[0] = d->data[0];
56                                 cc[1] = d->data[1];
57                         }
58                 }
59                 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
60                         memcpy(vps, d->data, sizeof(vps));
61                         found_vps = 1;
62                 }
63                 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
64                         wss = d->data[0] | d->data[1] << 8;
65                         found_wss = 1;
66                 }
67         }
68
69         if (itv->vbi.wss_found != found_wss || itv->vbi.wss != wss) {
70                 itv->vbi.wss = wss;
71                 itv->vbi.wss_found = found_wss;
72                 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
73         }
74
75         if (found_vps || itv->vbi.vps_found) {
76                 itv->vbi.vps[0] = vps[2];
77                 itv->vbi.vps[1] = vps[8];
78                 itv->vbi.vps[2] = vps[9];
79                 itv->vbi.vps[3] = vps[10];
80                 itv->vbi.vps[4] = vps[11];
81                 itv->vbi.vps_found = found_vps;
82                 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
83         }
84
85         if (found_cc && cc_pos < sizeof(itv->vbi.cc_data_even)) {
86                 itv->vbi.cc_data_odd[cc_pos] = cc[0];
87                 itv->vbi.cc_data_odd[cc_pos + 1] = cc[1];
88                 itv->vbi.cc_data_even[cc_pos] = cc[2];
89                 itv->vbi.cc_data_even[cc_pos + 1] = cc[3];
90                 itv->vbi.cc_pos = cc_pos + 2;
91                 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
92         }
93 }
94
95 static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
96 {
97         int line = 0;
98         int i;
99         u32 linemask[2] = { 0, 0 };
100         unsigned short size;
101         static const u8 mpeg_hdr_data[] = {
102                 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
103                 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
104                 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
105                 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
106         };
107         const int sd = sizeof(mpeg_hdr_data);   /* start of vbi data */
108         int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
109         u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
110
111         for (i = 0; i < lines; i++) {
112                 int f, l;
113
114                 if (itv->vbi.sliced_data[i].id == 0)
115                         continue;
116
117                 l = itv->vbi.sliced_data[i].line - 6;
118                 f = itv->vbi.sliced_data[i].field;
119                 if (f)
120                         l += 18;
121                 if (l < 32)
122                         linemask[0] |= (1 << l);
123                 else
124                         linemask[1] |= (1 << (l - 32));
125                 dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id);
126                 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
127                 line++;
128         }
129         memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
130         if (line == 36) {
131                 /* All lines are used, so there is no space for the linemask
132                    (the max size of the VBI data is 36 * 43 + 4 bytes).
133                    So in this case we use the magic number 'ITV0'. */
134                 memcpy(dst + sd, "ITV0", 4);
135                 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
136                 size = 4 + ((43 * line + 3) & ~3);
137         } else {
138                 memcpy(dst + sd, "itv0", 4);
139                 memcpy(dst + sd + 4, &linemask[0], 8);
140                 size = 12 + ((43 * line + 3) & ~3);
141         }
142         dst[4+16] = (size + 10) >> 8;
143         dst[5+16] = (size + 10) & 0xff;
144         dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
145         dst[10+16] = (pts_stamp >> 22) & 0xff;
146         dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
147         dst[12+16] = (pts_stamp >> 7) & 0xff;
148         dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
149         itv->vbi.sliced_mpeg_size[idx] = sd + size;
150 }
151
152 static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
153 {
154         u32 linemask[2];
155         int i, l, id2;
156         int line = 0;
157
158         if (!memcmp(p, "itv0", 4)) {
159                 memcpy(linemask, p + 4, 8);
160                 p += 12;
161         } else if (!memcmp(p, "ITV0", 4)) {
162                 linemask[0] = 0xffffffff;
163                 linemask[1] = 0xf;
164                 p += 4;
165         } else {
166                 /* unknown VBI data stream */
167                 return 0;
168         }
169         for (i = 0; i < 36; i++) {
170                 int err = 0;
171
172                 if (i < 32 && !(linemask[0] & (1 << i)))
173                         continue;
174                 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
175                         continue;
176                 id2 = *p & 0xf;
177                 switch (id2) {
178                 case IVTV_SLICED_TYPE_TELETEXT_B:
179                         id2 = V4L2_SLICED_TELETEXT_B;
180                         break;
181                 case IVTV_SLICED_TYPE_CAPTION_525:
182                         id2 = V4L2_SLICED_CAPTION_525;
183                         err = !odd_parity(p[1]) || !odd_parity(p[2]);
184                         break;
185                 case IVTV_SLICED_TYPE_VPS:
186                         id2 = V4L2_SLICED_VPS;
187                         break;
188                 case IVTV_SLICED_TYPE_WSS_625:
189                         id2 = V4L2_SLICED_WSS_625;
190                         break;
191                 default:
192                         id2 = 0;
193                         break;
194                 }
195                 if (err == 0) {
196                         l = (i < 18) ? i + 6 : i - 18 + 6;
197                         itv->vbi.sliced_dec_data[line].line = l;
198                         itv->vbi.sliced_dec_data[line].field = i >= 18;
199                         itv->vbi.sliced_dec_data[line].id = id2;
200                         memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
201                         line++;
202                 }
203                 p += 43;
204         }
205         while (line < 36) {
206                 itv->vbi.sliced_dec_data[line].id = 0;
207                 itv->vbi.sliced_dec_data[line].line = 0;
208                 itv->vbi.sliced_dec_data[line].field = 0;
209                 line++;
210         }
211         return line * sizeof(itv->vbi.sliced_dec_data[0]);
212 }
213
214 ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count)
215 {
216         /* Should be a __user pointer, but sparse doesn't parse this bit correctly. */
217         const struct v4l2_sliced_vbi_data *p = (const struct v4l2_sliced_vbi_data *)ubuf;
218         u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 };
219         int found_cc = 0;
220         int cc_pos = itv->vbi.cc_pos;
221
222         while (count >= sizeof(struct v4l2_sliced_vbi_data)) {
223                 switch (p->id) {
224                 case V4L2_SLICED_CAPTION_525:
225                         if (p->line == 21) {
226                                 found_cc = 1;
227                                 if (p->field) {
228                                         cc[2] = p->data[0];
229                                         cc[3] = p->data[1];
230                                 } else {
231                                         cc[0] = p->data[0];
232                                         cc[1] = p->data[1];
233                                 }
234                         }
235                         break;
236
237                 case V4L2_SLICED_VPS:
238                         if (p->line == 16 && p->field == 0) {
239                                 itv->vbi.vps[0] = p->data[2];
240                                 itv->vbi.vps[1] = p->data[8];
241                                 itv->vbi.vps[2] = p->data[9];
242                                 itv->vbi.vps[3] = p->data[10];
243                                 itv->vbi.vps[4] = p->data[11];
244                                 itv->vbi.vps_found = 1;
245                                 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
246                         }
247                         break;
248
249                 case V4L2_SLICED_WSS_625:
250                         if (p->line == 23 && p->field == 0) {
251                                 /* No lock needed for WSS */
252                                 itv->vbi.wss = p->data[0] | (p->data[1] << 8);
253                                 itv->vbi.wss_found = 1;
254                                 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
255                         }
256                         break;
257
258                 default:
259                         break;
260                 }
261                 count -= sizeof(*p);
262                 p++;
263         }
264
265         if (found_cc && cc_pos < sizeof(itv->vbi.cc_data_even)) {
266                 itv->vbi.cc_data_odd[cc_pos] = cc[0];
267                 itv->vbi.cc_data_odd[cc_pos + 1] = cc[1];
268                 itv->vbi.cc_data_even[cc_pos] = cc[2];
269                 itv->vbi.cc_data_even[cc_pos + 1] = cc[3];
270                 itv->vbi.cc_pos = cc_pos + 2;
271                 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
272         }
273
274         return (const char __user *)p - ubuf;
275 }
276
277 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
278    field.
279    Returns new compressed size. */
280 static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
281 {
282         u32 line_size = itv->vbi.raw_decoder_line_size;
283         u32 lines = itv->vbi.count;
284         u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
285         u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
286         u8 *q = buf;
287         u8 *p;
288         int i;
289
290         for (i = 0; i < lines; i++) {
291                 p = buf + i * line_size;
292
293                 /* Look for SAV code */
294                 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
295                         break;
296                 }
297                 memcpy(q, p + 4, line_size - 4);
298                 q += line_size - 4;
299         }
300         return lines * (line_size - 4);
301 }
302
303
304 /* Compressed VBI format, all found sliced blocks put next to one another
305    Returns new compressed size */
306 static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
307 {
308         u32 line_size = itv->vbi.sliced_decoder_line_size;
309         struct v4l2_decode_vbi_line vbi;
310         int i;
311
312         /* find the first valid line */
313         for (i = 0; i < size; i++, buf++) {
314                 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
315                         break;
316         }
317
318         size -= i;
319         if (size < line_size) {
320                 return line;
321         }
322         for (i = 0; i < size / line_size; i++) {
323                 u8 *p = buf + i * line_size;
324
325                 /* Look for SAV code  */
326                 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
327                         continue;
328                 }
329                 vbi.p = p + 4;
330                 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
331                 if (vbi.type) {
332                         itv->vbi.sliced_data[line].id = vbi.type;
333                         itv->vbi.sliced_data[line].field = vbi.is_second_field;
334                         itv->vbi.sliced_data[line].line = vbi.line;
335                         memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
336                         line++;
337                 }
338         }
339         return line;
340 }
341
342 void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
343                            u64 pts_stamp, int streamtype)
344 {
345         u8 *p = (u8 *) buf->buf;
346         u32 size = buf->bytesused;
347         int y;
348
349         /* Raw VBI data */
350         if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
351                 u8 type;
352
353                 ivtv_buf_swap(buf);
354
355                 type = p[3];
356
357                 size = buf->bytesused = compress_raw_buf(itv, p, size);
358
359                 /* second field of the frame? */
360                 if (type == itv->vbi.raw_decoder_sav_even_field) {
361                         /* Dirty hack needed for backwards
362                            compatibility of old VBI software. */
363                         p += size - 4;
364                         memcpy(p, &itv->vbi.frame, 4);
365                         itv->vbi.frame++;
366                 }
367                 return;
368         }
369
370         /* Sliced VBI data with data insertion */
371         if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
372                 int lines;
373
374                 ivtv_buf_swap(buf);
375
376                 /* first field */
377                 lines = compress_sliced_buf(itv, 0, p, size / 2,
378                         itv->vbi.sliced_decoder_sav_odd_field);
379                 /* second field */
380                 /* experimentation shows that the second half does not always begin
381                    at the exact address. So start a bit earlier (hence 32). */
382                 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
383                         itv->vbi.sliced_decoder_sav_even_field);
384                 /* always return at least one empty line */
385                 if (lines == 0) {
386                         itv->vbi.sliced_data[0].id = 0;
387                         itv->vbi.sliced_data[0].line = 0;
388                         itv->vbi.sliced_data[0].field = 0;
389                         lines = 1;
390                 }
391                 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
392                 memcpy(p, &itv->vbi.sliced_data[0], size);
393
394                 if (itv->vbi.insert_mpeg) {
395                         copy_vbi_data(itv, lines, pts_stamp);
396                 }
397                 itv->vbi.frame++;
398                 return;
399         }
400
401         /* Sliced VBI re-inserted from an MPEG stream */
402         if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
403                 /* If the size is not 4-byte aligned, then the starting address
404                    for the swapping is also shifted. After swapping the data the
405                    real start address of the VBI data is exactly 4 bytes after the
406                    original start. It's a bit fiddly but it works like a charm.
407                    Non-4-byte alignment happens when an lseek is done on the input
408                    mpeg file to a non-4-byte aligned position. So on arrival here
409                    the VBI data is also non-4-byte aligned. */
410                 int offset = size & 3;
411                 int cnt;
412
413                 if (offset) {
414                         p += 4 - offset;
415                 }
416                 /* Swap Buffer */
417                 for (y = 0; y < size; y += 4) {
418                        swab32s((u32 *)(p + y));
419                 }
420
421                 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
422                 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
423                 buf->bytesused = cnt;
424
425                 passthrough_vbi_data(itv, cnt / sizeof(itv->vbi.sliced_dec_data[0]));
426                 return;
427         }
428 }
429
430 void ivtv_disable_vbi(struct ivtv *itv)
431 {
432         clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
433         clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
434         clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
435         ivtv_set_wss(itv, 0, 0);
436         ivtv_set_cc(itv, 0, 0, 0, 0, 0);
437         ivtv_set_vps(itv, 0, 0, 0, 0, 0, 0);
438         itv->vbi.vps_found = itv->vbi.wss_found = 0;
439         itv->vbi.wss = 0;
440         itv->vbi.cc_pos = 0;
441 }
442
443
444 void ivtv_vbi_work_handler(struct ivtv *itv)
445 {
446         struct v4l2_sliced_vbi_data data;
447
448         /* Lock */
449         if (itv->output_mode == OUT_PASSTHROUGH) {
450                 /* Note: currently only the saa7115 is used in a PVR350,
451                    so these commands are for now saa7115 specific. */
452                 if (itv->is_50hz) {
453                         data.id = V4L2_SLICED_WSS_625;
454                         data.field = 0;
455
456                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
457                                 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
458                                 itv->vbi.wss_no_update = 0;
459                         } else if (itv->vbi.wss_no_update == 4) {
460                                 ivtv_set_wss(itv, 1, 0x8);  /* 4x3 full format */
461                         } else {
462                                 itv->vbi.wss_no_update++;
463                         }
464                 }
465                 else {
466                         u8 c1 = 0, c2 = 0, c3 = 0, c4 = 0;
467                         int mode = 0;
468
469                         data.id = V4L2_SLICED_CAPTION_525;
470                         data.field = 0;
471                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
472                                 mode |= 1;
473                                 c1 = data.data[0];
474                                 c2 = data.data[1];
475                         }
476                         data.field = 1;
477                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
478                                 mode |= 2;
479                                 c3 = data.data[0];
480                                 c4 = data.data[1];
481                         }
482                         if (mode) {
483                                 itv->vbi.cc_no_update = 0;
484                                 ivtv_set_cc(itv, mode, c1, c2, c3, c4);
485                         } else if (itv->vbi.cc_no_update == 4) {
486                                 ivtv_set_cc(itv, 0, 0, 0, 0, 0);
487                         } else {
488                                 itv->vbi.cc_no_update++;
489                         }
490                 }
491                 return;
492         }
493
494         if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
495                 /* Lock */
496                 ivtv_set_wss(itv, itv->vbi.wss_found, itv->vbi.wss & 0xf);
497         }
498
499         if (test_and_clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
500                 if (itv->vbi.cc_pos == 0) {
501                         ivtv_set_cc(itv, 3, 0x80, 0x80, 0x80, 0x80);
502                 }
503                 while (itv->vbi.cc_pos) {
504                         u8 cc_odd0 = itv->vbi.cc_data_odd[0];
505                         u8 cc_odd1 = itv->vbi.cc_data_odd[1];
506                         u8 cc_even0 = itv->vbi.cc_data_even[0];
507                         u8 cc_even1 = itv->vbi.cc_data_even[1];
508
509                         memcpy(itv->vbi.cc_data_odd, itv->vbi.cc_data_odd + 2, sizeof(itv->vbi.cc_data_odd) - 2);
510                         memcpy(itv->vbi.cc_data_even, itv->vbi.cc_data_even + 2, sizeof(itv->vbi.cc_data_even) - 2);
511                         itv->vbi.cc_pos -= 2;
512                         if (itv->vbi.cc_pos && cc_odd0 == 0x80 && cc_odd1 == 0x80)
513                                 continue;
514
515                         /* Send to Saa7127 */
516                         ivtv_set_cc(itv, 3, cc_odd0, cc_odd1, cc_even0, cc_even1);
517                         if (itv->vbi.cc_pos == 0)
518                                 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
519                         break;
520                 }
521         }
522
523         if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
524                 /* Lock */
525                 ivtv_set_vps(itv, itv->vbi.vps_found,
526                         itv->vbi.vps[0], itv->vbi.vps[1],
527                         itv->vbi.vps[2], itv->vbi.vps[3], itv->vbi.vps[4]);
528         }
529 }