Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[pandora-kernel.git] / 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_g_fmt(struct cx18 *cx, struct v4l2_format *fmt)
133 {
134         struct cx18_av_state *state = &cx->av_state;
135         struct v4l2_sliced_vbi_format *svbi;
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         if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
147                 return -EINVAL;
148         svbi = &fmt->fmt.sliced;
149         memset(svbi, 0, sizeof(*svbi));
150         /* we're done if raw VBI is active */
151         if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
152                 return 0;
153
154         if (is_pal) {
155                 for (i = 7; i <= 23; i++) {
156                         u8 v = cx18_av_read(cx, 0x424 + i - 7);
157
158                         svbi->service_lines[0][i] = lcr2vbi[v >> 4];
159                         svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
160                         svbi->service_set |= svbi->service_lines[0][i] |
161                                 svbi->service_lines[1][i];
162                 }
163         } else {
164                 for (i = 10; i <= 21; i++) {
165                         u8 v = cx18_av_read(cx, 0x424 + i - 10);
166
167                         svbi->service_lines[0][i] = lcr2vbi[v >> 4];
168                         svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
169                         svbi->service_set |= svbi->service_lines[0][i] |
170                                 svbi->service_lines[1][i];
171                 }
172         }
173         return 0;
174 }
175
176 int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt)
177 {
178         struct cx18_av_state *state = &cx->av_state;
179         struct v4l2_sliced_vbi_format *svbi;
180         int is_pal = !(state->std & V4L2_STD_525_60);
181         int i, x;
182         u8 lcr[24];
183
184         if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
185                         fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
186                 return -EINVAL;
187         svbi = &fmt->fmt.sliced;
188         if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
189                 /* raw VBI */
190                 memset(svbi, 0, sizeof(*svbi));
191
192                 /* Setup standard */
193                 cx18_av_std_setup(cx);
194
195                 /* VBI Offset */
196                 cx18_av_write(cx, 0x47f, state->slicer_line_delay);
197                 cx18_av_write(cx, 0x404, 0x2e);
198                 return 0;
199         }
200
201         for (x = 0; x <= 23; x++)
202                 lcr[x] = 0x00;
203
204         /* Setup standard */
205         cx18_av_std_setup(cx);
206
207         /* Sliced VBI */
208         cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
209         cx18_av_write(cx, 0x406, 0x13);
210         cx18_av_write(cx, 0x47f, state->slicer_line_delay);
211
212         /* Force impossible lines to 0 */
213         if (is_pal) {
214                 for (i = 0; i <= 6; i++)
215                         svbi->service_lines[0][i] =
216                                 svbi->service_lines[1][i] = 0;
217         } else {
218                 for (i = 0; i <= 9; i++)
219                         svbi->service_lines[0][i] =
220                                 svbi->service_lines[1][i] = 0;
221
222                 for (i = 22; i <= 23; i++)
223                         svbi->service_lines[0][i] =
224                                 svbi->service_lines[1][i] = 0;
225         }
226
227         /* Build register values for requested service lines */
228         for (i = 7; i <= 23; i++) {
229                 for (x = 0; x <= 1; x++) {
230                         switch (svbi->service_lines[1-x][i]) {
231                         case V4L2_SLICED_TELETEXT_B:
232                                 lcr[i] |= 1 << (4 * x);
233                                 break;
234                         case V4L2_SLICED_WSS_625:
235                                 lcr[i] |= 4 << (4 * x);
236                                 break;
237                         case V4L2_SLICED_CAPTION_525:
238                                 lcr[i] |= 6 << (4 * x);
239                                 break;
240                         case V4L2_SLICED_VPS:
241                                 lcr[i] |= 9 << (4 * x);
242                                 break;
243                         }
244                 }
245         }
246
247         if (is_pal) {
248                 for (x = 1, i = 0x424; i <= 0x434; i++, x++)
249                         cx18_av_write(cx, i, lcr[6 + x]);
250         } else {
251                 for (x = 1, i = 0x424; i <= 0x430; i++, x++)
252                         cx18_av_write(cx, i, lcr[9 + x]);
253                 for (i = 0x431; i <= 0x434; i++)
254                         cx18_av_write(cx, i, 0);
255         }
256
257         cx18_av_write(cx, 0x43c, 0x16);
258         /* FIXME - should match vblank set in cx18_av_std_setup() */
259         cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
260         return 0;
261 }
262
263 int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
264                                    struct v4l2_decode_vbi_line *vbi)
265 {
266         struct cx18 *cx = v4l2_get_subdevdata(sd);
267         struct cx18_av_state *state = &cx->av_state;
268         struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p;
269         u8 *p;
270         int did, sdid, l, err = 0;
271
272         /*
273          * Check for the ancillary data header for sliced VBI
274          */
275         if (anc->preamble[0] ||
276                         anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
277                         (anc->did != sliced_vbi_did[0] &&
278                          anc->did != sliced_vbi_did[1])) {
279                 vbi->line = vbi->type = 0;
280                 return 0;
281         }
282
283         did = anc->did;
284         sdid = anc->sdid & 0xf;
285         l = anc->idid[0] & 0x3f;
286         l += state->slicer_line_offset;
287         p = anc->payload;
288
289         /* Decode the SDID set by the slicer */
290         switch (sdid) {
291         case 1:
292                 sdid = V4L2_SLICED_TELETEXT_B;
293                 break;
294         case 4:
295                 sdid = V4L2_SLICED_WSS_625;
296                 break;
297         case 6:
298                 sdid = V4L2_SLICED_CAPTION_525;
299                 err = !odd_parity(p[0]) || !odd_parity(p[1]);
300                 break;
301         case 9:
302                 sdid = V4L2_SLICED_VPS;
303                 if (decode_vps(p, p) != 0)
304                         err = 1;
305                 break;
306         default:
307                 sdid = 0;
308                 err = 1;
309                 break;
310         }
311
312         vbi->type = err ? 0 : sdid;
313         vbi->line = err ? 0 : l;
314         vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
315         vbi->p = p;
316         return 0;
317 }