V4L/DVB (10700): saa7115: don't access reg 0x87 if it is not present.
[linux-2.6] / drivers / media / video / cx18 / cx18-av-vbi.c
1 /*
2  *  cx18 ADEC VBI functions
3  *
4  *  Derived from cx25840-vbi.c
5  *
6  *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
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 */
63         u8 preamble[3];
64         u8 did;
65         u8 sdid;
66         u8 data_count;
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
132 int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
133 {
134         struct cx18_av_state *state = &cx->av_state;
135         struct v4l2_format *fmt;
136         struct v4l2_sliced_vbi_format *svbi;
137
138         switch (cmd) {
139         case VIDIOC_G_FMT:
140         {
141                 static u16 lcr2vbi[] = {
142                         0, V4L2_SLICED_TELETEXT_B, 0,   /* 1 */
143                         0, V4L2_SLICED_WSS_625, 0,      /* 4 */
144                         V4L2_SLICED_CAPTION_525,        /* 6 */
145                         V4L2_SLICED_VPS, 0, 0, 0, 0,    /* 7 - unlike cx25840 */
146                         0, 0, 0, 0
147                 };
148                 int is_pal = !(state->std & V4L2_STD_525_60);
149                 int i;
150
151                 fmt = arg;
152                 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
153                         return -EINVAL;
154                 svbi = &fmt->fmt.sliced;
155                 memset(svbi, 0, sizeof(*svbi));
156                 /* we're done if raw VBI is active */
157                 if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
158                         break;
159
160                 if (is_pal) {
161                         for (i = 7; i <= 23; i++) {
162                                 u8 v = cx18_av_read(cx, 0x424 + i - 7);
163
164                                 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
165                                 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
166                                 svbi->service_set |= svbi->service_lines[0][i] |
167                                         svbi->service_lines[1][i];
168                         }
169                 } else {
170                         for (i = 10; i <= 21; i++) {
171                                 u8 v = cx18_av_read(cx, 0x424 + i - 10);
172
173                                 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
174                                 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
175                                 svbi->service_set |= svbi->service_lines[0][i] |
176                                         svbi->service_lines[1][i];
177                         }
178                 }
179                 break;
180         }
181
182         case VIDIOC_S_FMT:
183         {
184                 int is_pal = !(state->std & V4L2_STD_525_60);
185                 int i, x;
186                 u8 lcr[24];
187
188                 fmt = arg;
189                 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
190                     fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
191                         return -EINVAL;
192                 svbi = &fmt->fmt.sliced;
193                 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
194                         /* raw VBI */
195                         memset(svbi, 0, sizeof(*svbi));
196
197                         /* Setup standard */
198                         cx18_av_std_setup(cx);
199
200                         /* VBI Offset */
201                         cx18_av_write(cx, 0x47f, state->slicer_line_delay);
202                         cx18_av_write(cx, 0x404, 0x2e);
203                         break;
204                 }
205
206                 for (x = 0; x <= 23; x++)
207                         lcr[x] = 0x00;
208
209                 /* Setup standard */
210                 cx18_av_std_setup(cx);
211
212                 /* Sliced VBI */
213                 cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
214                 cx18_av_write(cx, 0x406, 0x13);
215                 cx18_av_write(cx, 0x47f, state->slicer_line_delay);
216
217                 /* Force impossible lines to 0 */
218                 if (is_pal) {
219                         for (i = 0; i <= 6; i++)
220                                 svbi->service_lines[0][i] =
221                                         svbi->service_lines[1][i] = 0;
222                 } else {
223                         for (i = 0; i <= 9; i++)
224                                 svbi->service_lines[0][i] =
225                                         svbi->service_lines[1][i] = 0;
226
227                         for (i = 22; i <= 23; i++)
228                                 svbi->service_lines[0][i] =
229                                         svbi->service_lines[1][i] = 0;
230                 }
231
232                 /* Build register values for requested service lines */
233                 for (i = 7; i <= 23; i++) {
234                         for (x = 0; x <= 1; x++) {
235                                 switch (svbi->service_lines[1-x][i]) {
236                                 case V4L2_SLICED_TELETEXT_B:
237                                         lcr[i] |= 1 << (4 * x);
238                                         break;
239                                 case V4L2_SLICED_WSS_625:
240                                         lcr[i] |= 4 << (4 * x);
241                                         break;
242                                 case V4L2_SLICED_CAPTION_525:
243                                         lcr[i] |= 6 << (4 * x);
244                                         break;
245                                 case V4L2_SLICED_VPS:
246                                         lcr[i] |= 7 << (4 * x); /*'840 differs*/
247                                         break;
248                                 }
249                         }
250                 }
251
252                 if (is_pal) {
253                         for (x = 1, i = 0x424; i <= 0x434; i++, x++)
254                                 cx18_av_write(cx, i, lcr[6 + x]);
255                 } else {
256                         for (x = 1, i = 0x424; i <= 0x430; i++, x++)
257                                 cx18_av_write(cx, i, lcr[9 + x]);
258                         for (i = 0x431; i <= 0x434; i++)
259                                 cx18_av_write(cx, i, 0);
260                 }
261
262                 cx18_av_write(cx, 0x43c, 0x16);
263                 /* FIXME - should match vblank set in cx18_av_std_setup() */
264                 cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
265                 break;
266         }
267
268         case VIDIOC_INT_DECODE_VBI_LINE:
269         {
270                 struct v4l2_decode_vbi_line *vbi = arg;
271                 u8 *p;
272                 struct vbi_anc_data *anc = (struct vbi_anc_data *) vbi->p;
273                 int did, sdid, l, err = 0;
274
275                 /*
276                  * Check for the ancillary data header for sliced VBI
277                  */
278                 if (anc->preamble[0] ||
279                     anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
280                     (anc->did != sliced_vbi_did[0] &&
281                      anc->did != sliced_vbi_did[1])) {
282                         vbi->line = vbi->type = 0;
283                         break;
284                 }
285
286                 did = anc->did;
287                 sdid = anc->sdid & 0xf;
288                 l = anc->idid[0] & 0x3f;
289                 l += state->slicer_line_offset;
290                 p = anc->payload;
291
292                 /* Decode the SDID set by the slicer */
293                 switch (sdid) {
294                 case 1:
295                         sdid = V4L2_SLICED_TELETEXT_B;
296                         break;
297                 case 4:
298                         sdid = V4L2_SLICED_WSS_625;
299                         break;
300                 case 6:
301                         sdid = V4L2_SLICED_CAPTION_525;
302                         err = !odd_parity(p[0]) || !odd_parity(p[1]);
303                         break;
304                 case 7: /* Differs from cx25840 */
305                         sdid = V4L2_SLICED_VPS;
306                         if (decode_vps(p, p) != 0)
307                                 err = 1;
308                         break;
309                 default:
310                         sdid = 0;
311                         err = 1;
312                         break;
313                 }
314
315                 vbi->type = err ? 0 : sdid;
316                 vbi->line = err ? 0 : l;
317                 vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
318                 vbi->p = p;
319                 break;
320         }
321         }
322
323         return 0;
324 }