xen: make CPU hotplug functions static
[safe/jmp/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-i2c.h"
22 #include "ivtv-ioctl.h"
23 #include "ivtv-queue.h"
24 #include "ivtv-vbi.h"
25
26 static void ivtv_set_vps(struct ivtv *itv, int enabled)
27 {
28         struct v4l2_sliced_vbi_data data;
29
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);
41 }
42
43 static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
44 {
45         struct v4l2_sliced_vbi_data data;
46
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);
60 }
61
62 static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
63 {
64         struct v4l2_sliced_vbi_data data;
65
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 */
76         }
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);
83 }
84
85 static int odd_parity(u8 c)
86 {
87         c ^= (c >> 4);
88         c ^= (c >> 2);
89         c ^= (c >> 1);
90
91         return c & 1;
92 }
93
94 void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt)
95 {
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;
100
101         for (i = 0; i < cnt; i++) {
102                 const struct v4l2_sliced_vbi_data *d = sliced + i;
103
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];
111                         }
112                         found_cc = 1;
113                 }
114                 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
115                         struct vbi_vps vps;
116
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);
125                         }
126                 }
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;
129
130                         if (vi->wss_payload != wss) {
131                                 vi->wss_payload = wss;
132                                 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
133                         }
134                 }
135         }
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);
139         }
140 }
141
142 static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
143 {
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
153         };
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];
157
158         for (i = 0; i < lines; i++) {
159                 int f, l;
160
161                 if (itv->vbi.sliced_data[i].id == 0)
162                         continue;
163
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] =
173                         ivtv_service2vbi(itv->vbi.sliced_data[i].id);
174                 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
175                 line++;
176         }
177         memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
178         if (line == 36) {
179                 /* All lines are used, so there is no space for the linemask
180                    (the max size of the VBI data is 36 * 43 + 4 bytes).
181                    So in this case we use the magic number 'ITV0'. */
182                 memcpy(dst + sd, "ITV0", 4);
183                 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
184                 size = 4 + ((43 * line + 3) & ~3);
185         } else {
186                 memcpy(dst + sd, "itv0", 4);
187                 memcpy(dst + sd + 4, &linemask[0], 8);
188                 size = 12 + ((43 * line + 3) & ~3);
189         }
190         dst[4+16] = (size + 10) >> 8;
191         dst[5+16] = (size + 10) & 0xff;
192         dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
193         dst[10+16] = (pts_stamp >> 22) & 0xff;
194         dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
195         dst[12+16] = (pts_stamp >> 7) & 0xff;
196         dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
197         itv->vbi.sliced_mpeg_size[idx] = sd + size;
198 }
199
200 static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
201 {
202         u32 linemask[2];
203         int i, l, id2;
204         int line = 0;
205
206         if (!memcmp(p, "itv0", 4)) {
207                 memcpy(linemask, p + 4, 8);
208                 p += 12;
209         } else if (!memcmp(p, "ITV0", 4)) {
210                 linemask[0] = 0xffffffff;
211                 linemask[1] = 0xf;
212                 p += 4;
213         } else {
214                 /* unknown VBI data, convert to empty VBI frame */
215                 linemask[0] = linemask[1] = 0;
216         }
217         for (i = 0; i < 36; i++) {
218                 int err = 0;
219
220                 if (i < 32 && !(linemask[0] & (1 << i)))
221                         continue;
222                 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
223                         continue;
224                 id2 = *p & 0xf;
225                 switch (id2) {
226                 case IVTV_SLICED_TYPE_TELETEXT_B:
227                         id2 = V4L2_SLICED_TELETEXT_B;
228                         break;
229                 case IVTV_SLICED_TYPE_CAPTION_525:
230                         id2 = V4L2_SLICED_CAPTION_525;
231                         err = !odd_parity(p[1]) || !odd_parity(p[2]);
232                         break;
233                 case IVTV_SLICED_TYPE_VPS:
234                         id2 = V4L2_SLICED_VPS;
235                         break;
236                 case IVTV_SLICED_TYPE_WSS_625:
237                         id2 = V4L2_SLICED_WSS_625;
238                         break;
239                 default:
240                         id2 = 0;
241                         break;
242                 }
243                 if (err == 0) {
244                         l = (i < 18) ? i + 6 : i - 18 + 6;
245                         itv->vbi.sliced_dec_data[line].line = l;
246                         itv->vbi.sliced_dec_data[line].field = i >= 18;
247                         itv->vbi.sliced_dec_data[line].id = id2;
248                         memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
249                         line++;
250                 }
251                 p += 43;
252         }
253         while (line < 36) {
254                 itv->vbi.sliced_dec_data[line].id = 0;
255                 itv->vbi.sliced_dec_data[line].line = 0;
256                 itv->vbi.sliced_dec_data[line].field = 0;
257                 line++;
258         }
259         return line * sizeof(itv->vbi.sliced_dec_data[0]);
260 }
261
262 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
263    field.
264    Returns new compressed size. */
265 static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
266 {
267         u32 line_size = itv->vbi.raw_decoder_line_size;
268         u32 lines = itv->vbi.count;
269         u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
270         u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
271         u8 *q = buf;
272         u8 *p;
273         int i;
274
275         for (i = 0; i < lines; i++) {
276                 p = buf + i * line_size;
277
278                 /* Look for SAV code */
279                 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
280                         break;
281                 }
282                 memcpy(q, p + 4, line_size - 4);
283                 q += line_size - 4;
284         }
285         return lines * (line_size - 4);
286 }
287
288
289 /* Compressed VBI format, all found sliced blocks put next to one another
290    Returns new compressed size */
291 static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
292 {
293         u32 line_size = itv->vbi.sliced_decoder_line_size;
294         struct v4l2_decode_vbi_line vbi;
295         int i;
296
297         /* find the first valid line */
298         for (i = 0; i < size; i++, buf++) {
299                 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
300                         break;
301         }
302
303         size -= i;
304         if (size < line_size) {
305                 return line;
306         }
307         for (i = 0; i < size / line_size; i++) {
308                 u8 *p = buf + i * line_size;
309
310                 /* Look for SAV code  */
311                 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
312                         continue;
313                 }
314                 vbi.p = p + 4;
315                 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
316                 if (vbi.type) {
317                         itv->vbi.sliced_data[line].id = vbi.type;
318                         itv->vbi.sliced_data[line].field = vbi.is_second_field;
319                         itv->vbi.sliced_data[line].line = vbi.line;
320                         memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
321                         line++;
322                 }
323         }
324         return line;
325 }
326
327 void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
328                            u64 pts_stamp, int streamtype)
329 {
330         u8 *p = (u8 *) buf->buf;
331         u32 size = buf->bytesused;
332         int y;
333
334         /* Raw VBI data */
335         if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
336                 u8 type;
337
338                 ivtv_buf_swap(buf);
339
340                 type = p[3];
341
342                 size = buf->bytesused = compress_raw_buf(itv, p, size);
343
344                 /* second field of the frame? */
345                 if (type == itv->vbi.raw_decoder_sav_even_field) {
346                         /* Dirty hack needed for backwards
347                            compatibility of old VBI software. */
348                         p += size - 4;
349                         memcpy(p, &itv->vbi.frame, 4);
350                         itv->vbi.frame++;
351                 }
352                 return;
353         }
354
355         /* Sliced VBI data with data insertion */
356         if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
357                 int lines;
358
359                 ivtv_buf_swap(buf);
360
361                 /* first field */
362                 lines = compress_sliced_buf(itv, 0, p, size / 2,
363                         itv->vbi.sliced_decoder_sav_odd_field);
364                 /* second field */
365                 /* experimentation shows that the second half does not always begin
366                    at the exact address. So start a bit earlier (hence 32). */
367                 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
368                         itv->vbi.sliced_decoder_sav_even_field);
369                 /* always return at least one empty line */
370                 if (lines == 0) {
371                         itv->vbi.sliced_data[0].id = 0;
372                         itv->vbi.sliced_data[0].line = 0;
373                         itv->vbi.sliced_data[0].field = 0;
374                         lines = 1;
375                 }
376                 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
377                 memcpy(p, &itv->vbi.sliced_data[0], size);
378
379                 if (itv->vbi.insert_mpeg) {
380                         copy_vbi_data(itv, lines, pts_stamp);
381                 }
382                 itv->vbi.frame++;
383                 return;
384         }
385
386         /* Sliced VBI re-inserted from an MPEG stream */
387         if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
388                 /* If the size is not 4-byte aligned, then the starting address
389                    for the swapping is also shifted. After swapping the data the
390                    real start address of the VBI data is exactly 4 bytes after the
391                    original start. It's a bit fiddly but it works like a charm.
392                    Non-4-byte alignment happens when an lseek is done on the input
393                    mpeg file to a non-4-byte aligned position. So on arrival here
394                    the VBI data is also non-4-byte aligned. */
395                 int offset = size & 3;
396                 int cnt;
397
398                 if (offset) {
399                         p += 4 - offset;
400                 }
401                 /* Swap Buffer */
402                 for (y = 0; y < size; y += 4) {
403                        swab32s((u32 *)(p + y));
404                 }
405
406                 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
407                 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
408                 buf->bytesused = cnt;
409
410                 ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
411                                cnt / sizeof(itv->vbi.sliced_dec_data[0]));
412                 return;
413         }
414 }
415
416 void ivtv_disable_cc(struct ivtv *itv)
417 {
418         struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
419
420         clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
421         ivtv_set_cc(itv, 0, &cc);
422         itv->vbi.cc_payload_idx = 0;
423 }
424
425
426 void ivtv_vbi_work_handler(struct ivtv *itv)
427 {
428         struct vbi_info *vi = &itv->vbi;
429         struct v4l2_sliced_vbi_data data;
430         struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
431
432         /* Lock */
433         if (itv->output_mode == OUT_PASSTHROUGH) {
434                 if (itv->is_50hz) {
435                         data.id = V4L2_SLICED_WSS_625;
436                         data.field = 0;
437
438                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
439                                 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
440                                 vi->wss_missing_cnt = 0;
441                         } else if (vi->wss_missing_cnt == 4) {
442                                 ivtv_set_wss(itv, 1, 0x8);  /* 4x3 full format */
443                         } else {
444                                 vi->wss_missing_cnt++;
445                         }
446                 }
447                 else {
448                         int mode = 0;
449
450                         data.id = V4L2_SLICED_CAPTION_525;
451                         data.field = 0;
452                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
453                                 mode |= 1;
454                                 cc.odd[0] = data.data[0];
455                                 cc.odd[1] = data.data[1];
456                         }
457                         data.field = 1;
458                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
459                                 mode |= 2;
460                                 cc.even[0] = data.data[0];
461                                 cc.even[1] = data.data[1];
462                         }
463                         if (mode) {
464                                 vi->cc_missing_cnt = 0;
465                                 ivtv_set_cc(itv, mode, &cc);
466                         } else if (vi->cc_missing_cnt == 4) {
467                                 ivtv_set_cc(itv, 0, &cc);
468                         } else {
469                                 vi->cc_missing_cnt++;
470                         }
471                 }
472                 return;
473         }
474
475         if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
476                 ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
477         }
478
479         if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
480                 if (vi->cc_payload_idx == 0) {
481                         clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
482                         ivtv_set_cc(itv, 3, &cc);
483                 }
484                 while (vi->cc_payload_idx) {
485                         cc = vi->cc_payload[0];
486
487                         memcpy(vi->cc_payload, vi->cc_payload + 1,
488                                         sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
489                         vi->cc_payload_idx--;
490                         if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
491                                 continue;
492
493                         ivtv_set_cc(itv, 3, &cc);
494                         break;
495                 }
496         }
497
498         if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
499                 ivtv_set_vps(itv, 1);
500         }
501 }