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