1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2b285192aSMauro Carvalho Chehab /*
3b285192aSMauro Carvalho Chehab * cx18 ADEC VBI functions
4b285192aSMauro Carvalho Chehab *
5b285192aSMauro Carvalho Chehab * Derived from cx25840-vbi.c
6b285192aSMauro Carvalho Chehab *
7b285192aSMauro Carvalho Chehab * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
8b285192aSMauro Carvalho Chehab */
9b285192aSMauro Carvalho Chehab
10b285192aSMauro Carvalho Chehab
11b285192aSMauro Carvalho Chehab #include "cx18-driver.h"
12b285192aSMauro Carvalho Chehab
13b285192aSMauro Carvalho Chehab /*
14b285192aSMauro Carvalho Chehab * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode,
15b285192aSMauro Carvalho Chehab * NN counts 1 byte Dwords, an IDID with the VBI line # in it.
16b285192aSMauro Carvalho Chehab * Thus, according to the VIP-2 Spec, our VBI ancillary data lines
17b285192aSMauro Carvalho Chehab * (should!) look like:
18b285192aSMauro Carvalho Chehab * 4 byte EAV code: 0xff 0x00 0x00 0xRP
19b285192aSMauro Carvalho Chehab * unknown number of possible idle bytes
20b285192aSMauro Carvalho Chehab * 3 byte Anc data preamble: 0x00 0xff 0xff
21b285192aSMauro Carvalho Chehab * 1 byte data identifier: ne010iii (parity bits, 010, DID bits)
22b285192aSMauro Carvalho Chehab * 1 byte secondary data id: nessssss (parity bits, SDID bits)
23b285192aSMauro Carvalho Chehab * 1 byte data word count: necccccc (parity bits, NN Dword count)
24b285192aSMauro Carvalho Chehab * 2 byte Internal DID: VBI-line-# 0x80
25b285192aSMauro Carvalho Chehab * NN data bytes
26b285192aSMauro Carvalho Chehab * 1 byte checksum
27b285192aSMauro Carvalho Chehab * Fill bytes needed to fil out to 4*NN bytes of payload
28b285192aSMauro Carvalho Chehab *
29b285192aSMauro Carvalho Chehab * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, &
30b285192aSMauro Carvalho Chehab * in the vertical blanking interval are:
31b285192aSMauro Carvalho Chehab * 0xb0 (Task 0 VerticalBlank HorizontalBlank 0 0 0 0)
32b285192aSMauro Carvalho Chehab * 0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0)
33b285192aSMauro Carvalho Chehab *
34b285192aSMauro Carvalho Chehab * Since the V bit is only allowed to toggle in the EAV RP code, just
35b285192aSMauro Carvalho Chehab * before the first active region line and for active lines, they are:
36b285192aSMauro Carvalho Chehab * 0x90 (Task 0 0 HorizontalBlank 0 0 0 0)
37b285192aSMauro Carvalho Chehab * 0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0)
38b285192aSMauro Carvalho Chehab *
39b285192aSMauro Carvalho Chehab * The user application DID bytes we care about are:
40b285192aSMauro Carvalho Chehab * 0x91 (1 0 010 0 !ActiveLine AncDataPresent)
41b285192aSMauro Carvalho Chehab * 0x55 (0 1 010 2ndField !ActiveLine AncDataPresent)
42b285192aSMauro Carvalho Chehab *
43b285192aSMauro Carvalho Chehab */
44b285192aSMauro Carvalho Chehab static const u8 sliced_vbi_did[2] = { 0x91, 0x55 };
45b285192aSMauro Carvalho Chehab
46b285192aSMauro Carvalho Chehab struct vbi_anc_data {
47b285192aSMauro Carvalho Chehab /* u8 eav[4]; */
48b285192aSMauro Carvalho Chehab /* u8 idle[]; Variable number of idle bytes */
49b285192aSMauro Carvalho Chehab u8 preamble[3];
50b285192aSMauro Carvalho Chehab u8 did;
51b285192aSMauro Carvalho Chehab u8 sdid;
52b285192aSMauro Carvalho Chehab u8 data_count;
53b285192aSMauro Carvalho Chehab u8 idid[2];
54*fe1b585cSGustavo A. R. Silva u8 payload[]; /* data_count of payload */
55b285192aSMauro Carvalho Chehab /* u8 checksum; */
56b285192aSMauro Carvalho Chehab /* u8 fill[]; Variable number of fill bytes */
57b285192aSMauro Carvalho Chehab };
58b285192aSMauro Carvalho Chehab
odd_parity(u8 c)59b285192aSMauro Carvalho Chehab static int odd_parity(u8 c)
60b285192aSMauro Carvalho Chehab {
61b285192aSMauro Carvalho Chehab c ^= (c >> 4);
62b285192aSMauro Carvalho Chehab c ^= (c >> 2);
63b285192aSMauro Carvalho Chehab c ^= (c >> 1);
64b285192aSMauro Carvalho Chehab
65b285192aSMauro Carvalho Chehab return c & 1;
66b285192aSMauro Carvalho Chehab }
67b285192aSMauro Carvalho Chehab
decode_vps(u8 * dst,u8 * p)68b285192aSMauro Carvalho Chehab static int decode_vps(u8 *dst, u8 *p)
69b285192aSMauro Carvalho Chehab {
70b285192aSMauro Carvalho Chehab static const u8 biphase_tbl[] = {
71b285192aSMauro Carvalho Chehab 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
72b285192aSMauro Carvalho Chehab 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
73b285192aSMauro Carvalho Chehab 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
74b285192aSMauro Carvalho Chehab 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
75b285192aSMauro Carvalho Chehab 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
76b285192aSMauro Carvalho Chehab 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
77b285192aSMauro Carvalho Chehab 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
78b285192aSMauro Carvalho Chehab 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
79b285192aSMauro Carvalho Chehab 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
80b285192aSMauro Carvalho Chehab 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
81b285192aSMauro Carvalho Chehab 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
82b285192aSMauro Carvalho Chehab 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
83b285192aSMauro Carvalho Chehab 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
84b285192aSMauro Carvalho Chehab 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
85b285192aSMauro Carvalho Chehab 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
86b285192aSMauro Carvalho Chehab 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
87b285192aSMauro Carvalho Chehab 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
88b285192aSMauro Carvalho Chehab 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
89b285192aSMauro Carvalho Chehab 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
90b285192aSMauro Carvalho Chehab 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
91b285192aSMauro Carvalho Chehab 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
92b285192aSMauro Carvalho Chehab 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
93b285192aSMauro Carvalho Chehab 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
94b285192aSMauro Carvalho Chehab 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
95b285192aSMauro Carvalho Chehab 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
96b285192aSMauro Carvalho Chehab 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
97b285192aSMauro Carvalho Chehab 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
98b285192aSMauro Carvalho Chehab 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
99b285192aSMauro Carvalho Chehab 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
100b285192aSMauro Carvalho Chehab 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
101b285192aSMauro Carvalho Chehab 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
102b285192aSMauro Carvalho Chehab 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
103b285192aSMauro Carvalho Chehab };
104b285192aSMauro Carvalho Chehab
105b285192aSMauro Carvalho Chehab u8 c, err = 0;
106b285192aSMauro Carvalho Chehab int i;
107b285192aSMauro Carvalho Chehab
108b285192aSMauro Carvalho Chehab for (i = 0; i < 2 * 13; i += 2) {
109b285192aSMauro Carvalho Chehab err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
110b285192aSMauro Carvalho Chehab c = (biphase_tbl[p[i + 1]] & 0xf) |
111b285192aSMauro Carvalho Chehab ((biphase_tbl[p[i]] & 0xf) << 4);
112b285192aSMauro Carvalho Chehab dst[i / 2] = c;
113b285192aSMauro Carvalho Chehab }
114b285192aSMauro Carvalho Chehab
115b285192aSMauro Carvalho Chehab return err & 0xf0;
116b285192aSMauro Carvalho Chehab }
117b285192aSMauro Carvalho Chehab
cx18_av_g_sliced_fmt(struct v4l2_subdev * sd,struct v4l2_sliced_vbi_format * svbi)118b285192aSMauro Carvalho Chehab int cx18_av_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
119b285192aSMauro Carvalho Chehab {
120b285192aSMauro Carvalho Chehab struct cx18 *cx = v4l2_get_subdevdata(sd);
121b285192aSMauro Carvalho Chehab struct cx18_av_state *state = &cx->av_state;
122b285192aSMauro Carvalho Chehab static const u16 lcr2vbi[] = {
123b285192aSMauro Carvalho Chehab 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
124b285192aSMauro Carvalho Chehab 0, V4L2_SLICED_WSS_625, 0, /* 4 */
125b285192aSMauro Carvalho Chehab V4L2_SLICED_CAPTION_525, /* 6 */
126b285192aSMauro Carvalho Chehab 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
127b285192aSMauro Carvalho Chehab 0, 0, 0, 0
128b285192aSMauro Carvalho Chehab };
129b285192aSMauro Carvalho Chehab int is_pal = !(state->std & V4L2_STD_525_60);
130b285192aSMauro Carvalho Chehab int i;
131b285192aSMauro Carvalho Chehab
13230634e8eSHans Verkuil memset(svbi->service_lines, 0, sizeof(svbi->service_lines));
13330634e8eSHans Verkuil svbi->service_set = 0;
13430634e8eSHans Verkuil
135b285192aSMauro Carvalho Chehab /* we're done if raw VBI is active */
136b285192aSMauro Carvalho Chehab if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
137b285192aSMauro Carvalho Chehab return 0;
138b285192aSMauro Carvalho Chehab
139b285192aSMauro Carvalho Chehab if (is_pal) {
140b285192aSMauro Carvalho Chehab for (i = 7; i <= 23; i++) {
141b285192aSMauro Carvalho Chehab u8 v = cx18_av_read(cx, 0x424 + i - 7);
142b285192aSMauro Carvalho Chehab
143b285192aSMauro Carvalho Chehab svbi->service_lines[0][i] = lcr2vbi[v >> 4];
144b285192aSMauro Carvalho Chehab svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
145b285192aSMauro Carvalho Chehab svbi->service_set |= svbi->service_lines[0][i] |
146b285192aSMauro Carvalho Chehab svbi->service_lines[1][i];
147b285192aSMauro Carvalho Chehab }
148b285192aSMauro Carvalho Chehab } else {
149b285192aSMauro Carvalho Chehab for (i = 10; i <= 21; i++) {
150b285192aSMauro Carvalho Chehab u8 v = cx18_av_read(cx, 0x424 + i - 10);
151b285192aSMauro Carvalho Chehab
152b285192aSMauro Carvalho Chehab svbi->service_lines[0][i] = lcr2vbi[v >> 4];
153b285192aSMauro Carvalho Chehab svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
154b285192aSMauro Carvalho Chehab svbi->service_set |= svbi->service_lines[0][i] |
155b285192aSMauro Carvalho Chehab svbi->service_lines[1][i];
156b285192aSMauro Carvalho Chehab }
157b285192aSMauro Carvalho Chehab }
158b285192aSMauro Carvalho Chehab return 0;
159b285192aSMauro Carvalho Chehab }
160b285192aSMauro Carvalho Chehab
cx18_av_s_raw_fmt(struct v4l2_subdev * sd,struct v4l2_vbi_format * fmt)161b285192aSMauro Carvalho Chehab int cx18_av_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
162b285192aSMauro Carvalho Chehab {
163b285192aSMauro Carvalho Chehab struct cx18 *cx = v4l2_get_subdevdata(sd);
164b285192aSMauro Carvalho Chehab struct cx18_av_state *state = &cx->av_state;
165b285192aSMauro Carvalho Chehab
166b285192aSMauro Carvalho Chehab /* Setup standard */
167b285192aSMauro Carvalho Chehab cx18_av_std_setup(cx);
168b285192aSMauro Carvalho Chehab
169b285192aSMauro Carvalho Chehab /* VBI Offset */
170b285192aSMauro Carvalho Chehab cx18_av_write(cx, 0x47f, state->slicer_line_delay);
171b285192aSMauro Carvalho Chehab cx18_av_write(cx, 0x404, 0x2e);
172b285192aSMauro Carvalho Chehab return 0;
173b285192aSMauro Carvalho Chehab }
174b285192aSMauro Carvalho Chehab
cx18_av_s_sliced_fmt(struct v4l2_subdev * sd,struct v4l2_sliced_vbi_format * svbi)175b285192aSMauro Carvalho Chehab int cx18_av_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
176b285192aSMauro Carvalho Chehab {
177b285192aSMauro Carvalho Chehab struct cx18 *cx = v4l2_get_subdevdata(sd);
178b285192aSMauro Carvalho Chehab struct cx18_av_state *state = &cx->av_state;
179b285192aSMauro Carvalho Chehab int is_pal = !(state->std & V4L2_STD_525_60);
180b285192aSMauro Carvalho Chehab int i, x;
181b285192aSMauro Carvalho Chehab u8 lcr[24];
182b285192aSMauro Carvalho Chehab
183b285192aSMauro Carvalho Chehab for (x = 0; x <= 23; x++)
184b285192aSMauro Carvalho Chehab lcr[x] = 0x00;
185b285192aSMauro Carvalho Chehab
186b285192aSMauro Carvalho Chehab /* Setup standard */
187b285192aSMauro Carvalho Chehab cx18_av_std_setup(cx);
188b285192aSMauro Carvalho Chehab
189b285192aSMauro Carvalho Chehab /* Sliced VBI */
190b285192aSMauro Carvalho Chehab cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
191b285192aSMauro Carvalho Chehab cx18_av_write(cx, 0x406, 0x13);
192b285192aSMauro Carvalho Chehab cx18_av_write(cx, 0x47f, state->slicer_line_delay);
193b285192aSMauro Carvalho Chehab
194b285192aSMauro Carvalho Chehab /* Force impossible lines to 0 */
195b285192aSMauro Carvalho Chehab if (is_pal) {
196b285192aSMauro Carvalho Chehab for (i = 0; i <= 6; i++)
197b285192aSMauro Carvalho Chehab svbi->service_lines[0][i] =
198b285192aSMauro Carvalho Chehab svbi->service_lines[1][i] = 0;
199b285192aSMauro Carvalho Chehab } else {
200b285192aSMauro Carvalho Chehab for (i = 0; i <= 9; i++)
201b285192aSMauro Carvalho Chehab svbi->service_lines[0][i] =
202b285192aSMauro Carvalho Chehab svbi->service_lines[1][i] = 0;
203b285192aSMauro Carvalho Chehab
204b285192aSMauro Carvalho Chehab for (i = 22; i <= 23; i++)
205b285192aSMauro Carvalho Chehab svbi->service_lines[0][i] =
206b285192aSMauro Carvalho Chehab svbi->service_lines[1][i] = 0;
207b285192aSMauro Carvalho Chehab }
208b285192aSMauro Carvalho Chehab
209b285192aSMauro Carvalho Chehab /* Build register values for requested service lines */
210b285192aSMauro Carvalho Chehab for (i = 7; i <= 23; i++) {
211b285192aSMauro Carvalho Chehab for (x = 0; x <= 1; x++) {
212b285192aSMauro Carvalho Chehab switch (svbi->service_lines[1-x][i]) {
213b285192aSMauro Carvalho Chehab case V4L2_SLICED_TELETEXT_B:
214b285192aSMauro Carvalho Chehab lcr[i] |= 1 << (4 * x);
215b285192aSMauro Carvalho Chehab break;
216b285192aSMauro Carvalho Chehab case V4L2_SLICED_WSS_625:
217b285192aSMauro Carvalho Chehab lcr[i] |= 4 << (4 * x);
218b285192aSMauro Carvalho Chehab break;
219b285192aSMauro Carvalho Chehab case V4L2_SLICED_CAPTION_525:
220b285192aSMauro Carvalho Chehab lcr[i] |= 6 << (4 * x);
221b285192aSMauro Carvalho Chehab break;
222b285192aSMauro Carvalho Chehab case V4L2_SLICED_VPS:
223b285192aSMauro Carvalho Chehab lcr[i] |= 9 << (4 * x);
224b285192aSMauro Carvalho Chehab break;
225b285192aSMauro Carvalho Chehab }
226b285192aSMauro Carvalho Chehab }
227b285192aSMauro Carvalho Chehab }
228b285192aSMauro Carvalho Chehab
229b285192aSMauro Carvalho Chehab if (is_pal) {
230b285192aSMauro Carvalho Chehab for (x = 1, i = 0x424; i <= 0x434; i++, x++)
231b285192aSMauro Carvalho Chehab cx18_av_write(cx, i, lcr[6 + x]);
232b285192aSMauro Carvalho Chehab } else {
233b285192aSMauro Carvalho Chehab for (x = 1, i = 0x424; i <= 0x430; i++, x++)
234b285192aSMauro Carvalho Chehab cx18_av_write(cx, i, lcr[9 + x]);
235b285192aSMauro Carvalho Chehab for (i = 0x431; i <= 0x434; i++)
236b285192aSMauro Carvalho Chehab cx18_av_write(cx, i, 0);
237b285192aSMauro Carvalho Chehab }
238b285192aSMauro Carvalho Chehab
239b285192aSMauro Carvalho Chehab cx18_av_write(cx, 0x43c, 0x16);
240b285192aSMauro Carvalho Chehab /* Should match vblank set in cx18_av_std_setup() */
241b285192aSMauro Carvalho Chehab cx18_av_write(cx, 0x474, is_pal ? 38 : 26);
242b285192aSMauro Carvalho Chehab return 0;
243b285192aSMauro Carvalho Chehab }
244b285192aSMauro Carvalho Chehab
cx18_av_decode_vbi_line(struct v4l2_subdev * sd,struct v4l2_decode_vbi_line * vbi)245b285192aSMauro Carvalho Chehab int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
246b285192aSMauro Carvalho Chehab struct v4l2_decode_vbi_line *vbi)
247b285192aSMauro Carvalho Chehab {
248b285192aSMauro Carvalho Chehab struct cx18 *cx = v4l2_get_subdevdata(sd);
249b285192aSMauro Carvalho Chehab struct cx18_av_state *state = &cx->av_state;
250b285192aSMauro Carvalho Chehab struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p;
251b285192aSMauro Carvalho Chehab u8 *p;
252b285192aSMauro Carvalho Chehab int did, sdid, l, err = 0;
253b285192aSMauro Carvalho Chehab
254b285192aSMauro Carvalho Chehab /*
255b285192aSMauro Carvalho Chehab * Check for the ancillary data header for sliced VBI
256b285192aSMauro Carvalho Chehab */
257b285192aSMauro Carvalho Chehab if (anc->preamble[0] ||
258b285192aSMauro Carvalho Chehab anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
259b285192aSMauro Carvalho Chehab (anc->did != sliced_vbi_did[0] &&
260b285192aSMauro Carvalho Chehab anc->did != sliced_vbi_did[1])) {
261b285192aSMauro Carvalho Chehab vbi->line = vbi->type = 0;
262b285192aSMauro Carvalho Chehab return 0;
263b285192aSMauro Carvalho Chehab }
264b285192aSMauro Carvalho Chehab
265b285192aSMauro Carvalho Chehab did = anc->did;
266b285192aSMauro Carvalho Chehab sdid = anc->sdid & 0xf;
267b285192aSMauro Carvalho Chehab l = anc->idid[0] & 0x3f;
268b285192aSMauro Carvalho Chehab l += state->slicer_line_offset;
269b285192aSMauro Carvalho Chehab p = anc->payload;
270b285192aSMauro Carvalho Chehab
271b285192aSMauro Carvalho Chehab /* Decode the SDID set by the slicer */
272b285192aSMauro Carvalho Chehab switch (sdid) {
273b285192aSMauro Carvalho Chehab case 1:
274b285192aSMauro Carvalho Chehab sdid = V4L2_SLICED_TELETEXT_B;
275b285192aSMauro Carvalho Chehab break;
276b285192aSMauro Carvalho Chehab case 4:
277b285192aSMauro Carvalho Chehab sdid = V4L2_SLICED_WSS_625;
278b285192aSMauro Carvalho Chehab break;
279b285192aSMauro Carvalho Chehab case 6:
280b285192aSMauro Carvalho Chehab sdid = V4L2_SLICED_CAPTION_525;
281b285192aSMauro Carvalho Chehab err = !odd_parity(p[0]) || !odd_parity(p[1]);
282b285192aSMauro Carvalho Chehab break;
283b285192aSMauro Carvalho Chehab case 9:
284b285192aSMauro Carvalho Chehab sdid = V4L2_SLICED_VPS;
285b285192aSMauro Carvalho Chehab if (decode_vps(p, p) != 0)
286b285192aSMauro Carvalho Chehab err = 1;
287b285192aSMauro Carvalho Chehab break;
288b285192aSMauro Carvalho Chehab default:
289b285192aSMauro Carvalho Chehab sdid = 0;
290b285192aSMauro Carvalho Chehab err = 1;
291b285192aSMauro Carvalho Chehab break;
292b285192aSMauro Carvalho Chehab }
293b285192aSMauro Carvalho Chehab
294b285192aSMauro Carvalho Chehab vbi->type = err ? 0 : sdid;
295b285192aSMauro Carvalho Chehab vbi->line = err ? 0 : l;
296b285192aSMauro Carvalho Chehab vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
297b285192aSMauro Carvalho Chehab vbi->p = p;
298b285192aSMauro Carvalho Chehab return 0;
299b285192aSMauro Carvalho Chehab }
300