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