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