Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
[linux-2.6] / drivers / media / video / saa7115.c
1 /* saa7115 - Philips SAA7114/SAA7115 video decoder driver
2  *
3  * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
4  * the saa7111 driver by Dave Perks.
5  *
6  * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
7  * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
8  *
9  * Slight changes for video timing and attachment output by
10  * Wolfgang Scherr <scherr@net4you.net>
11  *
12  * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
13  * by Ronald Bultje <rbultje@ronald.bitfreak.net>
14  *
15  * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
16  * (2/17/2003)
17  *
18  * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
19  *
20  * This program is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU General Public License
22  * as published by the Free Software Foundation; either version 2
23  * of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28  * GNU General Public License for more details.
29  *
30  * You should have received a copy of the GNU General Public License
31  * along with this program; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
33  */
34
35
36 #include <linux/kernel.h>
37 #include <linux/module.h>
38 #include <linux/slab.h>
39 #include <linux/i2c.h>
40 #include <linux/videodev2.h>
41 #include <media/v4l2-common.h>
42 #include <media/audiochip.h>
43 #include <asm/div64.h>
44
45 MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver");
46 MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil");
47 MODULE_LICENSE("GPL");
48
49 static int debug = 0;
50 module_param(debug, bool, 0644);
51
52 MODULE_PARM_DESC(debug, "Debug level (0-1)");
53
54 static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
55
56
57 I2C_CLIENT_INSMOD;
58
59 struct saa7115_state {
60         v4l2_std_id std;
61         int input;
62         int enable;
63         int radio;
64         int bright;
65         int contrast;
66         int hue;
67         int sat;
68         enum v4l2_chip_ident ident;
69         u32 audclk_freq;
70 };
71
72 /* ----------------------------------------------------------------------- */
73
74 static inline int saa7115_write(struct i2c_client *client, u8 reg, u8 value)
75 {
76         return i2c_smbus_write_byte_data(client, reg, value);
77 }
78
79 static int saa7115_writeregs(struct i2c_client *client, const unsigned char *regs)
80 {
81         unsigned char reg, data;
82
83         while (*regs != 0x00) {
84                 reg = *(regs++);
85                 data = *(regs++);
86                 if (saa7115_write(client, reg, data) < 0)
87                         return -1;
88         }
89         return 0;
90 }
91
92 static inline int saa7115_read(struct i2c_client *client, u8 reg)
93 {
94         return i2c_smbus_read_byte_data(client, reg);
95 }
96
97 /* ----------------------------------------------------------------------- */
98
99 /* If a value differs from the Hauppauge driver values, then the comment starts with
100    'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
101    Hauppauge driver sets. */
102
103 static const unsigned char saa7115_init_auto_input[] = {
104         0x01, 0x48,             /* white peak control disabled */
105         0x03, 0x20,             /* was 0x30. 0x20: long vertical blanking */
106         0x04, 0x90,             /* analog gain set to 0 */
107         0x05, 0x90,             /* analog gain set to 0 */
108         0x06, 0xeb,             /* horiz sync begin = -21 */
109         0x07, 0xe0,             /* horiz sync stop = -17 */
110         0x0a, 0x80,             /* was 0x88. decoder brightness, 0x80 is itu standard */
111         0x0b, 0x44,             /* was 0x48. decoder contrast, 0x44 is itu standard */
112         0x0c, 0x40,             /* was 0x47. decoder saturation, 0x40 is itu standard */
113         0x0d, 0x00,             /* chrominance hue control */
114         0x0f, 0x00,             /* chrominance gain control: use automicatic mode */
115         0x10, 0x06,             /* chrominance/luminance control: active adaptive combfilter */
116         0x11, 0x00,             /* delay control */
117         0x12, 0x9d,             /* RTS0 output control: VGATE */
118         0x13, 0x80,             /* X-port output control: ITU656 standard mode, RTCO output enable RTCE */
119         0x14, 0x00,             /* analog/ADC/auto compatibility control */
120         0x18, 0x40,             /* raw data gain 0x00 = nominal */
121         0x19, 0x80,             /* raw data offset 0x80 = 0 LSB */
122         0x1a, 0x77,             /* color killer level control 0x77 = recommended */
123         0x1b, 0x42,             /* misc chroma control 0x42 = recommended */
124         0x1c, 0xa9,             /* combfilter control 0xA9 = recommended */
125         0x1d, 0x01,             /* combfilter control 0x01 = recommended */
126         0x88, 0xd0,             /* reset device */
127         0x88, 0xf0,             /* set device programmed, all in operational mode */
128         0x00, 0x00
129 };
130
131 static const unsigned char saa7115_cfg_reset_scaler[] = {
132         0x87, 0x00,             /* disable I-port output */
133         0x88, 0xd0,             /* reset scaler */
134         0x88, 0xf0,             /* activate scaler */
135         0x87, 0x01,             /* enable I-port output */
136         0x00, 0x00
137 };
138
139 /* ============== SAA7715 VIDEO templates =============  */
140
141 static const unsigned char saa7115_cfg_60hz_fullres_x[] = {
142         0xcc, 0xd0,             /* hsize low (output), hor. output window size = 0x2d0 = 720 */
143         0xcd, 0x02,             /* hsize hi (output) */
144
145         /* Why not in 60hz-Land, too? */
146         0xd0, 0x01,             /* downscale = 1 */
147         0xd8, 0x00,             /* hor lum scaling 0x0400 = 1 */
148         0xd9, 0x04,
149         0xdc, 0x00,             /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
150         0xdd, 0x02,             /* H-scaling incr chroma */
151
152         0x00, 0x00
153 };
154 static const unsigned char saa7115_cfg_60hz_fullres_y[] = {
155         0xce, 0xf8,             /* vsize low (output), ver. output window size = 248 (but 60hz is 240?) */
156         0xcf, 0x00,             /* vsize hi (output) */
157
158         /* Why not in 60hz-Land, too? */
159         0xd5, 0x40,             /* Lum contrast, nominal value = 0x40 */
160         0xd6, 0x40,             /* Chroma satur. nominal value = 0x80 */
161
162         0xe0, 0x00,             /* V-scaling incr luma low */
163         0xe1, 0x04,             /* " hi */
164         0xe2, 0x00,             /* V-scaling incr chroma low */
165         0xe3, 0x04,             /* " hi */
166
167         0x00, 0x00
168 };
169
170 static const unsigned char saa7115_cfg_60hz_video[] = {
171         0x80, 0x00,             /* reset tasks */
172         0x88, 0xd0,             /* reset scaler */
173
174         0x15, 0x03,             /* VGATE pulse start */
175         0x16, 0x11,             /* VGATE pulse stop */
176         0x17, 0x9c,             /* VGATE MSB and other values */
177
178         0x08, 0x68,             /* 0xBO: auto detection, 0x68 = NTSC */
179         0x0e, 0x07,             /* lots of different stuff... video autodetection is on */
180
181         0x5a, 0x06,             /* Vertical offset, standard 60hz value for ITU656 line counting */
182
183         /* Task A */
184         0x90, 0x80,             /* Task Handling Control */
185         0x91, 0x48,             /* X-port formats/config */
186         0x92, 0x40,             /* Input Ref. signal Def. */
187         0x93, 0x84,             /* I-port config */
188         0x94, 0x01,             /* hoffset low (input), 0x0002 is minimum */
189         0x95, 0x00,             /* hoffset hi (input) */
190         0x96, 0xd0,             /* hsize low (input), 0x02d0 = 720 */
191         0x97, 0x02,             /* hsize hi (input) */
192         0x98, 0x05,             /* voffset low (input) */
193         0x99, 0x00,             /* voffset hi (input) */
194         0x9a, 0x0c,             /* vsize low (input), 0x0c = 12 */
195         0x9b, 0x00,             /* vsize hi (input) */
196         0x9c, 0xa0,             /* hsize low (output), 0x05a0 = 1440 */
197         0x9d, 0x05,             /* hsize hi (output) */
198         0x9e, 0x0c,             /* vsize low (output), 0x0c = 12 */
199         0x9f, 0x00,             /* vsize hi (output) */
200
201         /* Task B */
202         0xc0, 0x00,             /* Task Handling Control */
203         0xc1, 0x08,             /* X-port formats/config */
204         0xc2, 0x00,             /* Input Ref. signal Def. */
205         0xc3, 0x80,             /* I-port config */
206         0xc4, 0x02,             /* hoffset low (input), 0x0002 is minimum */
207         0xc5, 0x00,             /* hoffset hi (input) */
208         0xc6, 0xd0,             /* hsize low (input), 0x02d0 = 720 */
209         0xc7, 0x02,             /* hsize hi (input) */
210         0xc8, 0x12,             /* voffset low (input), 0x12 = 18 */
211         0xc9, 0x00,             /* voffset hi (input) */
212         0xca, 0xf8,             /* vsize low (input), 0xf8 = 248 */
213         0xcb, 0x00,             /* vsize hi (input) */
214         0xcc, 0xd0,             /* hsize low (output), 0x02d0 = 720 */
215         0xcd, 0x02,             /* hsize hi (output) */
216
217         0xf0, 0xad,             /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
218         0xf1, 0x05,             /* low bit with 0xF0 */
219         0xf5, 0xad,             /* Set pulse generator register */
220         0xf6, 0x01,
221
222         0x87, 0x00,             /* Disable I-port output */
223         0x88, 0xd0,             /* reset scaler */
224         0x80, 0x20,             /* Activate only task "B", continuous mode (was 0xA0) */
225         0x88, 0xf0,             /* activate scaler */
226         0x87, 0x01,             /* Enable I-port output */
227         0x00, 0x00
228 };
229
230 static const unsigned char saa7115_cfg_50hz_fullres_x[] = {
231         0xcc, 0xd0,             /* hsize low (output), 720 same as 60hz */
232         0xcd, 0x02,             /* hsize hi (output) */
233
234         0xd0, 0x01,             /* down scale = 1 */
235         0xd8, 0x00,             /* hor lum scaling 0x0400 = 1 */
236         0xd9, 0x04,
237         0xdc, 0x00,             /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
238         0xdd, 0x02,             /* H-scaling incr chroma */
239
240         0x00, 0x00
241 };
242 static const unsigned char saa7115_cfg_50hz_fullres_y[] = {
243         0xce, 0x20,             /* vsize low (output), 0x0120 = 288 */
244         0xcf, 0x01,             /* vsize hi (output) */
245
246         0xd5, 0x40,             /* Lum contrast, nominal value = 0x40 */
247         0xd6, 0x40,             /* Chroma satur. nominal value = 0x80 */
248
249         0xe0, 0x00,             /* V-scaling incr luma low */
250         0xe1, 0x04,             /* " hi */
251         0xe2, 0x00,             /* V-scaling incr chroma low */
252         0xe3, 0x04,             /* " hi */
253
254         0x00, 0x00
255 };
256
257 static const unsigned char saa7115_cfg_50hz_video[] = {
258         0x80, 0x00,             /* reset tasks */
259         0x88, 0xd0,             /* reset scaler */
260
261         0x15, 0x37,             /* VGATE start */
262         0x16, 0x16,             /* VGATE stop */
263         0x17, 0x99,             /* VGATE MSB and other values */
264
265         0x08, 0x28,             /* 0x28 = PAL */
266         0x0e, 0x07,             /* chrominance control 1 */
267
268         0x5a, 0x03,             /* Vertical offset, standard 50hz value */
269
270         /* Task A */
271         0x90, 0x81,             /* Task Handling Control */
272         0x91, 0x48,             /* X-port formats/config */
273         0x92, 0x40,             /* Input Ref. signal Def. */
274         0x93, 0x84,             /* I-port config */
275         /* This is weird: the datasheet says that you should use 2 as the minimum value, */
276         /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
277         0x94, 0x00,             /* hoffset low (input), 0x0002 is minimum */
278         0x95, 0x00,             /* hoffset hi (input) */
279         0x96, 0xd0,             /* hsize low (input), 0x02d0 = 720 */
280         0x97, 0x02,             /* hsize hi (input) */
281         0x98, 0x03,             /* voffset low (input) */
282         0x99, 0x00,             /* voffset hi (input) */
283         0x9a, 0x12,             /* vsize low (input), 0x12 = 18 */
284         0x9b, 0x00,             /* vsize hi (input) */
285         0x9c, 0xa0,             /* hsize low (output), 0x05a0 = 1440 */
286         0x9d, 0x05,             /* hsize hi (output) */
287         0x9e, 0x12,             /* vsize low (output), 0x12 = 18 */
288         0x9f, 0x00,             /* vsize hi (output) */
289
290         /* Task B */
291         0xc0, 0x00,             /* Task Handling Control */
292         0xc1, 0x08,             /* X-port formats/config */
293         0xc2, 0x00,             /* Input Ref. signal Def. */
294         0xc3, 0x80,             /* I-port config */
295         0xc4, 0x00,             /* hoffset low (input), 0x0002 is minimum. See comment at 0x94 above. */
296         0xc5, 0x00,             /* hoffset hi (input) */
297         0xc6, 0xd0,             /* hsize low (input), 0x02d0 = 720 */
298         0xc7, 0x02,             /* hsize hi (input) */
299         0xc8, 0x16,             /* voffset low (input), 0x16 = 22 */
300         0xc9, 0x00,             /* voffset hi (input) */
301         0xca, 0x20,             /* vsize low (input), 0x0120 = 288 */
302         0xcb, 0x01,             /* vsize hi (input) */
303         0xcc, 0xd0,             /* hsize low (output), 0x02d0 = 720 */
304         0xcd, 0x02,             /* hsize hi (output) */
305         0xce, 0x20,             /* vsize low (output), 0x0120 = 288 */
306         0xcf, 0x01,             /* vsize hi (output) */
307
308         0xf0, 0xb0,             /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
309         0xf1, 0x05,             /* low bit with 0xF0, (was 0x05) */
310         0xf5, 0xb0,             /* Set pulse generator register */
311         0xf6, 0x01,
312
313         0x87, 0x00,             /* Disable I-port output */
314         0x88, 0xd0,             /* reset scaler (was 0xD0) */
315         0x80, 0x20,             /* Activate only task "B" */
316         0x88, 0xf0,             /* activate scaler */
317         0x87, 0x01,             /* Enable I-port output */
318         0x00, 0x00
319 };
320
321 /* ============== SAA7715 VIDEO templates (end) =======  */
322
323 static const unsigned char saa7115_cfg_vbi_on[] = {
324         0x80, 0x00,             /* reset tasks */
325         0x88, 0xd0,             /* reset scaler */
326         0x80, 0x30,             /* Activate both tasks */
327         0x88, 0xf0,             /* activate scaler */
328         0x87, 0x01,             /* Enable I-port output */
329         0x00, 0x00
330 };
331
332 static const unsigned char saa7115_cfg_vbi_off[] = {
333         0x80, 0x00,             /* reset tasks */
334         0x88, 0xd0,             /* reset scaler */
335         0x80, 0x20,             /* Activate only task "B" */
336         0x88, 0xf0,             /* activate scaler */
337         0x87, 0x01,             /* Enable I-port output */
338         0x00, 0x00
339 };
340
341 static const unsigned char saa7115_init_misc[] = {
342         0x38, 0x03,             /* audio stuff */
343         0x39, 0x10,
344         0x3a, 0x08,
345
346         0x81, 0x01,             /* reg 0x15,0x16 define blanking window */
347         0x82, 0x00,
348         0x83, 0x01,             /* I port settings */
349         0x84, 0x20,
350         0x85, 0x21,
351         0x86, 0xc5,
352         0x87, 0x01,
353
354         /* Task A */
355         0xa0, 0x01,             /* down scale = 1 */
356         0xa1, 0x00,             /* prescale accumulation length = 1 */
357         0xa2, 0x00,             /* dc gain and fir prefilter control */
358         0xa4, 0x80,             /* Lum Brightness, nominal value = 0x80 */
359         0xa5, 0x40,             /* Lum contrast, nominal value = 0x40 */
360         0xa6, 0x40,             /* Chroma satur. nominal value = 0x80 */
361         0xa8, 0x00,             /* hor lum scaling 0x0200 = 2 zoom */
362         0xa9, 0x02,             /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
363         0xaa, 0x00,             /* H-phase offset Luma = 0 */
364         0xac, 0x00,             /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
365         0xad, 0x01,             /* H-scaling incr chroma */
366         0xae, 0x00,             /* H-phase offset chroma. must be offset luma / 2 */
367
368         0xb0, 0x00,             /* V-scaling incr luma low */
369         0xb1, 0x04,             /* " hi */
370         0xb2, 0x00,             /* V-scaling incr chroma low */
371         0xb3, 0x04,             /* " hi */
372         0xb4, 0x01,             /* V-scaling mode control */
373         0xb8, 0x00,             /* V-phase offset chroma 00 */
374         0xb9, 0x00,             /* V-phase offset chroma 01 */
375         0xba, 0x00,             /* V-phase offset chroma 10 */
376         0xbb, 0x00,             /* V-phase offset chroma 11 */
377         0xbc, 0x00,             /* V-phase offset luma 00 */
378         0xbd, 0x00,             /* V-phase offset luma 01 */
379         0xbe, 0x00,             /* V-phase offset luma 10 */
380         0xbf, 0x00,             /* V-phase offset luma 11 */
381
382         /* Task B */
383         0xd0, 0x01,             /* down scale = 1 */
384         0xd1, 0x00,             /* prescale accumulation length = 1 */
385         0xd2, 0x00,             /* dc gain and fir prefilter control */
386         0xd4, 0x80,             /* Lum Brightness, nominal value = 0x80 */
387         0xd5, 0x40,             /* Lum contrast, nominal value = 0x40 */
388         0xd6, 0x40,             /* Chroma satur. nominal value = 0x80 */
389         0xd8, 0x00,             /* hor lum scaling 0x0400 = 1 */
390         0xd9, 0x04,
391         0xda, 0x00,             /* H-phase offset Luma = 0 */
392         0xdc, 0x00,             /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
393         0xdd, 0x02,             /* H-scaling incr chroma */
394         0xde, 0x00,             /* H-phase offset chroma. must be offset luma / 2 */
395
396         0xe0, 0x00,             /* V-scaling incr luma low */
397         0xe1, 0x04,             /* " hi */
398         0xe2, 0x00,             /* V-scaling incr chroma low */
399         0xe3, 0x04,             /* " hi */
400         0xe4, 0x01,             /* V-scaling mode control */
401         0xe8, 0x00,             /* V-phase offset chroma 00 */
402         0xe9, 0x00,             /* V-phase offset chroma 01 */
403         0xea, 0x00,             /* V-phase offset chroma 10 */
404         0xeb, 0x00,             /* V-phase offset chroma 11 */
405         0xec, 0x00,             /* V-phase offset luma 00 */
406         0xed, 0x00,             /* V-phase offset luma 01 */
407         0xee, 0x00,             /* V-phase offset luma 10 */
408         0xef, 0x00,             /* V-phase offset luma 11 */
409
410         0xf2, 0x50,             /* crystal clock = 24.576 MHz, target = 27MHz */
411         0xf3, 0x46,
412         0xf4, 0x00,
413         0xf7, 0x4b,             /* not the recommended settings! */
414         0xf8, 0x00,
415         0xf9, 0x4b,
416         0xfa, 0x00,
417         0xfb, 0x4b,
418         0xff, 0x88,             /* PLL2 lock detection settings: 71 lines 50% phase error */
419
420         /* Turn off VBI */
421         0x40, 0x20,             /* No framing code errors allowed. */
422         0x41, 0xff,
423         0x42, 0xff,
424         0x43, 0xff,
425         0x44, 0xff,
426         0x45, 0xff,
427         0x46, 0xff,
428         0x47, 0xff,
429         0x48, 0xff,
430         0x49, 0xff,
431         0x4a, 0xff,
432         0x4b, 0xff,
433         0x4c, 0xff,
434         0x4d, 0xff,
435         0x4e, 0xff,
436         0x4f, 0xff,
437         0x50, 0xff,
438         0x51, 0xff,
439         0x52, 0xff,
440         0x53, 0xff,
441         0x54, 0xff,
442         0x55, 0xff,
443         0x56, 0xff,
444         0x57, 0xff,
445         0x58, 0x40,
446         0x59, 0x47,
447         0x5b, 0x83,
448         0x5d, 0xbd,
449         0x5e, 0x35,
450
451         0x02, 0x84,             /* input tuner -> input 4, amplifier active */
452         0x09, 0x53,             /* 0x53, was 0x56 for 60hz. luminance control */
453
454         0x80, 0x20,             /* enable task B */
455         0x88, 0xd0,
456         0x88, 0xf0,
457         0x00, 0x00
458 };
459
460 static int saa7115_odd_parity(u8 c)
461 {
462         c ^= (c >> 4);
463         c ^= (c >> 2);
464         c ^= (c >> 1);
465
466         return c & 1;
467 }
468
469 static int saa7115_decode_vps(u8 * dst, u8 * p)
470 {
471         static const u8 biphase_tbl[] = {
472                 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
473                 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
474                 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
475                 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
476                 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
477                 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
478                 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
479                 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
480                 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
481                 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
482                 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
483                 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
484                 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
485                 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
486                 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
487                 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
488                 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
489                 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
490                 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
491                 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
492                 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
493                 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
494                 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
495                 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
496                 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
497                 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
498                 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
499                 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
500                 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
501                 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
502                 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
503                 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
504         };
505         int i;
506         u8 c, err = 0;
507
508         for (i = 0; i < 2 * 13; i += 2) {
509                 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
510                 c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
511                 dst[i / 2] = c;
512         }
513         return err & 0xf0;
514 }
515
516 static int saa7115_decode_wss(u8 * p)
517 {
518         static const int wss_bits[8] = {
519                 0, 0, 0, 1, 0, 1, 1, 1
520         };
521         unsigned char parity;
522         int wss = 0;
523         int i;
524
525         for (i = 0; i < 16; i++) {
526                 int b1 = wss_bits[p[i] & 7];
527                 int b2 = wss_bits[(p[i] >> 3) & 7];
528
529                 if (b1 == b2)
530                         return -1;
531                 wss |= b2 << i;
532         }
533         parity = wss & 15;
534         parity ^= parity >> 2;
535         parity ^= parity >> 1;
536
537         if (!(parity & 1))
538                 return -1;
539
540         return wss;
541 }
542
543
544 static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
545 {
546         struct saa7115_state *state = i2c_get_clientdata(client);
547         u32 acpf;
548         u32 acni;
549         u32 hz;
550         u64 f;
551
552         v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq);
553
554         /* sanity check */
555         if (freq < 32000 || freq > 48000)
556                 return -EINVAL;
557
558         /* hz is the refresh rate times 100 */
559         hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
560         /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
561         acpf = (25600 * freq) / hz;
562         /* acni = (256 * freq * 2^23) / crystal_frequency =
563                   (freq * 2^(8+23)) / crystal_frequency =
564                   (freq << 31) / 32.11 MHz */
565         f = freq;
566         f = f << 31;
567         do_div(f, 32110000);
568         acni = f;
569
570         saa7115_write(client, 0x30, acpf & 0xff);
571         saa7115_write(client, 0x31, (acpf >> 8) & 0xff);
572         saa7115_write(client, 0x32, (acpf >> 16) & 0x03);
573         saa7115_write(client, 0x34, acni & 0xff);
574         saa7115_write(client, 0x35, (acni >> 8) & 0xff);
575         saa7115_write(client, 0x36, (acni >> 16) & 0x3f);
576         state->audclk_freq = freq;
577         return 0;
578 }
579
580 static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
581 {
582         struct saa7115_state *state = i2c_get_clientdata(client);
583
584         switch (ctrl->id) {
585         case V4L2_CID_BRIGHTNESS:
586                 if (ctrl->value < 0 || ctrl->value > 255) {
587                         v4l_err(client, "invalid brightness setting %d\n", ctrl->value);
588                         return -ERANGE;
589                 }
590
591                 state->bright = ctrl->value;
592                 saa7115_write(client, 0x0a, state->bright);
593                 break;
594
595         case V4L2_CID_CONTRAST:
596                 if (ctrl->value < 0 || ctrl->value > 127) {
597                         v4l_err(client, "invalid contrast setting %d\n", ctrl->value);
598                         return -ERANGE;
599                 }
600
601                 state->contrast = ctrl->value;
602                 saa7115_write(client, 0x0b, state->contrast);
603                 break;
604
605         case V4L2_CID_SATURATION:
606                 if (ctrl->value < 0 || ctrl->value > 127) {
607                         v4l_err(client, "invalid saturation setting %d\n", ctrl->value);
608                         return -ERANGE;
609                 }
610
611                 state->sat = ctrl->value;
612                 saa7115_write(client, 0x0c, state->sat);
613                 break;
614
615         case V4L2_CID_HUE:
616                 if (ctrl->value < -127 || ctrl->value > 127) {
617                         v4l_err(client, "invalid hue setting %d\n", ctrl->value);
618                         return -ERANGE;
619                 }
620
621                 state->hue = ctrl->value;
622                 saa7115_write(client, 0x0d, state->hue);
623                 break;
624
625         default:
626                 return -EINVAL;
627         }
628
629         return 0;
630 }
631
632 static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
633 {
634         struct saa7115_state *state = i2c_get_clientdata(client);
635
636         switch (ctrl->id) {
637         case V4L2_CID_BRIGHTNESS:
638                 ctrl->value = state->bright;
639                 break;
640         case V4L2_CID_CONTRAST:
641                 ctrl->value = state->contrast;
642                 break;
643         case V4L2_CID_SATURATION:
644                 ctrl->value = state->sat;
645                 break;
646         case V4L2_CID_HUE:
647                 ctrl->value = state->hue;
648                 break;
649         default:
650                 return -EINVAL;
651         }
652
653         return 0;
654 }
655
656 static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
657 {
658         struct saa7115_state *state = i2c_get_clientdata(client);
659         int taskb = saa7115_read(client, 0x80) & 0x10;
660
661         /* Prevent unnecessary standard changes. During a standard
662            change the I-Port is temporarily disabled. Any devices
663            reading from that port can get confused.
664            Note that VIDIOC_S_STD is also used to switch from
665            radio to TV mode, so if a VIDIOC_S_STD is broadcast to
666            all I2C devices then you do not want to have an unwanted
667            side-effect here. */
668         if (std == state->std)
669                 return;
670
671         // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
672         if (std & V4L2_STD_525_60) {
673                 v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n");
674                 saa7115_writeregs(client, saa7115_cfg_60hz_video);
675         } else {
676                 v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n");
677                 saa7115_writeregs(client, saa7115_cfg_50hz_video);
678         }
679
680         state->std = std;
681
682         /* restart task B if needed */
683         if (taskb && state->ident == V4L2_IDENT_SAA7114) {
684                 saa7115_writeregs(client, saa7115_cfg_vbi_on);
685         }
686
687         /* switch audio mode too! */
688         saa7115_set_audio_clock_freq(client, state->audclk_freq);
689 }
690
691 static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client)
692 {
693         struct saa7115_state *state = i2c_get_clientdata(client);
694
695         return state->std;
696 }
697
698 static void saa7115_log_status(struct i2c_client *client)
699 {
700         struct saa7115_state *state = i2c_get_clientdata(client);
701         int reg1e, reg1f;
702         int signalOk;
703         int vcr;
704
705         v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
706         if (client->name[6] == '4') {
707                 /* status for the saa7114 */
708                 reg1f = saa7115_read(client, 0x1f);
709                 signalOk = (reg1f & 0xc1) == 0x81;
710                 v4l_info(client, "Video signal:    %s\n", signalOk ? "ok" : "bad");
711                 v4l_info(client, "Frequency:       %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
712                 return;
713         }
714
715         /* status for the saa7115 */
716         reg1e = saa7115_read(client, 0x1e);
717         reg1f = saa7115_read(client, 0x1f);
718
719         signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
720         vcr = !(reg1f & 0x10);
721
722         if (state->input >= 6) {
723                 v4l_info(client, "Input:           S-Video %d\n", state->input - 6);
724         } else {
725                 v4l_info(client, "Input:           Composite %d\n", state->input);
726         }
727         v4l_info(client, "Video signal:    %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
728         v4l_info(client, "Frequency:       %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
729
730         switch (reg1e & 0x03) {
731                 case 1:
732                         v4l_info(client, "Detected format: NTSC\n");
733                         break;
734                 case 2:
735                         v4l_info(client, "Detected format: PAL\n");
736                         break;
737                 case 3:
738                         v4l_info(client, "Detected format: SECAM\n");
739                         break;
740                 default:
741                         v4l_info(client, "Detected format: BW/No color\n");
742                         break;
743         }
744 }
745
746 /* setup the sliced VBI lcr registers according to the sliced VBI format */
747 static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
748 {
749         struct saa7115_state *state = i2c_get_clientdata(client);
750         int is_50hz = (state->std & V4L2_STD_625_50);
751         u8 lcr[24];
752         int i, x;
753
754         /* saa7114 doesn't yet support VBI */
755         if (state->ident == V4L2_IDENT_SAA7114)
756                 return;
757
758         for (i = 0; i <= 23; i++)
759                 lcr[i] = 0xff;
760
761         if (fmt->service_set == 0) {
762                 /* raw VBI */
763                 if (is_50hz)
764                         for (i = 6; i <= 23; i++)
765                                 lcr[i] = 0xdd;
766                 else
767                         for (i = 10; i <= 21; i++)
768                                 lcr[i] = 0xdd;
769         } else {
770                 /* sliced VBI */
771                 /* first clear lines that cannot be captured */
772                 if (is_50hz) {
773                         for (i = 0; i <= 5; i++)
774                                 fmt->service_lines[0][i] =
775                                         fmt->service_lines[1][i] = 0;
776                 }
777                 else {
778                         for (i = 0; i <= 9; i++)
779                                 fmt->service_lines[0][i] =
780                                         fmt->service_lines[1][i] = 0;
781                         for (i = 22; i <= 23; i++)
782                                 fmt->service_lines[0][i] =
783                                         fmt->service_lines[1][i] = 0;
784                 }
785
786                 /* Now set the lcr values according to the specified service */
787                 for (i = 6; i <= 23; i++) {
788                         lcr[i] = 0;
789                         for (x = 0; x <= 1; x++) {
790                                 switch (fmt->service_lines[1-x][i]) {
791                                         case 0:
792                                                 lcr[i] |= 0xf << (4 * x);
793                                                 break;
794                                         case V4L2_SLICED_TELETEXT_B:
795                                                 lcr[i] |= 1 << (4 * x);
796                                                 break;
797                                         case V4L2_SLICED_CAPTION_525:
798                                                 lcr[i] |= 4 << (4 * x);
799                                                 break;
800                                         case V4L2_SLICED_WSS_625:
801                                                 lcr[i] |= 5 << (4 * x);
802                                                 break;
803                                         case V4L2_SLICED_VPS:
804                                                 lcr[i] |= 7 << (4 * x);
805                                                 break;
806                                 }
807                         }
808                 }
809         }
810
811         /* write the lcr registers */
812         for (i = 2; i <= 23; i++) {
813                 saa7115_write(client, i - 2 + 0x41, lcr[i]);
814         }
815
816         /* enable/disable raw VBI capturing */
817         saa7115_writeregs(client, fmt->service_set == 0 ? saa7115_cfg_vbi_on : saa7115_cfg_vbi_off);
818 }
819
820 static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
821 {
822         static u16 lcr2vbi[] = {
823                 0, V4L2_SLICED_TELETEXT_B, 0,   /* 1 */
824                 0, V4L2_SLICED_CAPTION_525,     /* 4 */
825                 V4L2_SLICED_WSS_625, 0,         /* 5 */
826                 V4L2_SLICED_VPS, 0, 0, 0, 0,    /* 7 */
827                 0, 0, 0, 0
828         };
829         struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;
830         int i;
831
832         if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
833                 return -EINVAL;
834         memset(sliced, 0, sizeof(*sliced));
835         /* done if using raw VBI */
836         if (saa7115_read(client, 0x80) & 0x10)
837                 return 0;
838         for (i = 2; i <= 23; i++) {
839                 u8 v = saa7115_read(client, i - 2 + 0x41);
840
841                 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
842                 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
843                 sliced->service_set |=
844                         sliced->service_lines[0][i] | sliced->service_lines[1][i];
845         }
846         return 0;
847 }
848
849 static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
850 {
851         struct saa7115_state *state = i2c_get_clientdata(client);
852         struct v4l2_pix_format *pix;
853         int HPSC, HFSC;
854         int VSCY, Vsrc;
855         int is_50hz = state->std & V4L2_STD_625_50;
856
857         if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
858                 saa7115_set_lcr(client, &fmt->fmt.sliced);
859                 return 0;
860         }
861         if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
862                 return -EINVAL;
863
864         pix = &(fmt->fmt.pix);
865
866         v4l_dbg(1, debug, client, "decoder set size\n");
867
868         /* FIXME need better bounds checking here */
869         if ((pix->width < 1) || (pix->width > 1440))
870                 return -EINVAL;
871         if ((pix->height < 1) || (pix->height > 960))
872                 return -EINVAL;
873
874         /* probably have a valid size, let's set it */
875         /* Set output width/height */
876         /* width */
877         saa7115_write(client, 0xcc, (u8) (pix->width & 0xff));
878         saa7115_write(client, 0xcd, (u8) ((pix->width >> 8) & 0xff));
879         /* height */
880         saa7115_write(client, 0xce, (u8) (pix->height & 0xff));
881         saa7115_write(client, 0xcf, (u8) ((pix->height >> 8) & 0xff));
882
883         /* Scaling settings */
884         /* Hprescaler is floor(inres/outres) */
885         /* FIXME hardcoding input res */
886         if (pix->width != 720) {
887                 HPSC = (int)(720 / pix->width);
888                 /* 0 is not allowed (div. by zero) */
889                 HPSC = HPSC ? HPSC : 1;
890                 HFSC = (int)((1024 * 720) / (HPSC * pix->width));
891
892                 v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
893                 /* FIXME hardcodes to "Task B"
894                  * write H prescaler integer */
895                 saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f));
896
897                 /* write H fine-scaling (luminance) */
898                 saa7115_write(client, 0xd8, (u8) (HFSC & 0xff));
899                 saa7115_write(client, 0xd9, (u8) ((HFSC >> 8) & 0xff));
900                 /* write H fine-scaling (chrominance)
901                  * must be lum/2, so i'll just bitshift :) */
902                 saa7115_write(client, 0xDC, (u8) ((HFSC >> 1) & 0xff));
903                 saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff));
904         } else {
905                 if (is_50hz) {
906                         v4l_dbg(1, debug, client, "Setting full 50hz width\n");
907                         saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x);
908                 } else {
909                         v4l_dbg(1, debug, client, "Setting full 60hz width\n");
910                         saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
911                 }
912         }
913
914         Vsrc = is_50hz ? 576 : 480;
915
916         if (pix->height != Vsrc) {
917                 VSCY = (int)((1024 * Vsrc) / pix->height);
918                 v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
919
920                 /* Correct Contrast and Luminance */
921                 saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY));
922                 saa7115_write(client, 0xd6, (u8) (64 * 1024 / VSCY));
923
924                 /* write V fine-scaling (luminance) */
925                 saa7115_write(client, 0xe0, (u8) (VSCY & 0xff));
926                 saa7115_write(client, 0xe1, (u8) ((VSCY >> 8) & 0xff));
927                 /* write V fine-scaling (chrominance) */
928                 saa7115_write(client, 0xe2, (u8) (VSCY & 0xff));
929                 saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff));
930         } else {
931                 if (is_50hz) {
932                         v4l_dbg(1, debug, client, "Setting full 50Hz height\n");
933                         saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y);
934                 } else {
935                         v4l_dbg(1, debug, client, "Setting full 60hz height\n");
936                         saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
937                 }
938         }
939
940         saa7115_writeregs(client, saa7115_cfg_reset_scaler);
941         return 0;
942 }
943
944 /* Decode the sliced VBI data stream as created by the saa7115.
945    The format is described in the saa7115 datasheet in Tables 25 and 26
946    and in Figure 33.
947    The current implementation uses SAV/EAV codes and not the ancillary data
948    headers. The vbi->p pointer points to the SDID byte right after the SAV
949    code. */
950 static void saa7115_decode_vbi_line(struct i2c_client *client,
951                                     struct v4l2_decode_vbi_line *vbi)
952 {
953         static const char vbi_no_data_pattern[] = {
954                 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
955         };
956         struct saa7115_state *state = i2c_get_clientdata(client);
957         u8 *p = vbi->p;
958         u32 wss;
959         int id1, id2;   /* the ID1 and ID2 bytes from the internal header */
960
961         vbi->type = 0;  /* mark result as a failure */
962         id1 = p[2];
963         id2 = p[3];
964         /* Note: the field bit is inverted for 60 Hz video */
965         if (state->std & V4L2_STD_525_60)
966                 id1 ^= 0x40;
967
968         /* Skip internal header, p now points to the start of the payload */
969         p += 4;
970         vbi->p = p;
971
972         /* calculate field and line number of the VBI packet (1-23) */
973         vbi->is_second_field = ((id1 & 0x40) != 0);
974         vbi->line = (id1 & 0x3f) << 3;
975         vbi->line |= (id2 & 0x70) >> 4;
976
977         /* Obtain data type */
978         id2 &= 0xf;
979
980         /* If the VBI slicer does not detect any signal it will fill up
981            the payload buffer with 0xa0 bytes. */
982         if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
983                 return;
984
985         /* decode payloads */
986         switch (id2) {
987         case 1:
988                 vbi->type = V4L2_SLICED_TELETEXT_B;
989                 break;
990         case 4:
991                 if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1]))
992                         return;
993                 vbi->type = V4L2_SLICED_CAPTION_525;
994                 break;
995         case 5:
996                 wss = saa7115_decode_wss(p);
997                 if (wss == -1)
998                         return;
999                 p[0] = wss & 0xff;
1000                 p[1] = wss >> 8;
1001                 vbi->type = V4L2_SLICED_WSS_625;
1002                 break;
1003         case 7:
1004                 if (saa7115_decode_vps(p, p) != 0)
1005                         return;
1006                 vbi->type = V4L2_SLICED_VPS;
1007                 break;
1008         default:
1009                 return;
1010         }
1011 }
1012
1013 /* ============ SAA7115 AUDIO settings (end) ============= */
1014
1015 static struct v4l2_queryctrl saa7115_qctrl[] = {
1016         {
1017                 .id            = V4L2_CID_BRIGHTNESS,
1018                 .type          = V4L2_CTRL_TYPE_INTEGER,
1019                 .name          = "Brightness",
1020                 .minimum       = 0,
1021                 .maximum       = 255,
1022                 .step          = 1,
1023                 .default_value = 128,
1024                 .flags         = 0,
1025         }, {
1026                 .id            = V4L2_CID_CONTRAST,
1027                 .type          = V4L2_CTRL_TYPE_INTEGER,
1028                 .name          = "Contrast",
1029                 .minimum       = 0,
1030                 .maximum       = 255,
1031                 .step          = 1,
1032                 .default_value = 64,
1033                 .flags         = 0,
1034         }, {
1035                 .id            = V4L2_CID_SATURATION,
1036                 .type          = V4L2_CTRL_TYPE_INTEGER,
1037                 .name          = "Saturation",
1038                 .minimum       = 0,
1039                 .maximum       = 255,
1040                 .step          = 1,
1041                 .default_value = 64,
1042                 .flags         = 0,
1043         }, {
1044                 .id            = V4L2_CID_HUE,
1045                 .type          = V4L2_CTRL_TYPE_INTEGER,
1046                 .name          = "Hue",
1047                 .minimum       = -128,
1048                 .maximum       = 127,
1049                 .step          = 1,
1050                 .default_value = 0,
1051                 .flags         = 0,
1052         },
1053 };
1054
1055 /* ----------------------------------------------------------------------- */
1056
1057 static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg)
1058 {
1059         struct saa7115_state *state = i2c_get_clientdata(client);
1060         int *iarg = arg;
1061
1062         /* ioctls to allow direct access to the saa7115 registers for testing */
1063         switch (cmd) {
1064         case VIDIOC_S_FMT:
1065                 return saa7115_set_v4lfmt(client, (struct v4l2_format *)arg);
1066
1067         case VIDIOC_G_FMT:
1068                 return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg);
1069
1070         case VIDIOC_INT_AUDIO_CLOCK_FREQ:
1071                 return saa7115_set_audio_clock_freq(client, *(u32 *)arg);
1072
1073         case VIDIOC_G_TUNER:
1074         {
1075                 struct v4l2_tuner *vt = arg;
1076                 int status;
1077
1078                 if (state->radio)
1079                         break;
1080                 status = saa7115_read(client, 0x1f);
1081
1082                 v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
1083                 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1084                 break;
1085         }
1086
1087         case VIDIOC_LOG_STATUS:
1088                 saa7115_log_status(client);
1089                 break;
1090
1091         case VIDIOC_G_CTRL:
1092                 return saa7115_get_v4lctrl(client, (struct v4l2_control *)arg);
1093
1094         case VIDIOC_S_CTRL:
1095                 return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg);
1096
1097         case VIDIOC_QUERYCTRL:
1098         {
1099                 struct v4l2_queryctrl *qc = arg;
1100                 int i;
1101
1102                 for (i = 0; i < ARRAY_SIZE(saa7115_qctrl); i++)
1103                         if (qc->id && qc->id == saa7115_qctrl[i].id) {
1104                                 memcpy(qc, &saa7115_qctrl[i], sizeof(*qc));
1105                                 return 0;
1106                         }
1107                 return -EINVAL;
1108         }
1109
1110         case VIDIOC_G_STD:
1111                 *(v4l2_std_id *)arg = saa7115_get_v4lstd(client);
1112                 break;
1113
1114         case VIDIOC_S_STD:
1115                 state->radio = 0;
1116                 saa7115_set_v4lstd(client, *(v4l2_std_id *)arg);
1117                 break;
1118
1119         case AUDC_SET_RADIO:
1120                 state->radio = 1;
1121                 break;
1122
1123         case VIDIOC_G_INPUT:
1124                 *(int *)arg = state->input;
1125                 break;
1126
1127         case VIDIOC_S_INPUT:
1128                 v4l_dbg(1, debug, client, "decoder set input %d\n", *iarg);
1129                 /* inputs from 0-9 are available */
1130                 if (*iarg < 0 || *iarg > 9) {
1131                         return -EINVAL;
1132                 }
1133
1134                 if (state->input == *iarg)
1135                         break;
1136                 v4l_dbg(1, debug, client, "now setting %s input\n",
1137                         *iarg >= 6 ? "S-Video" : "Composite");
1138                 state->input = *iarg;
1139
1140                 /* select mode */
1141                 saa7115_write(client, 0x02,
1142                               (saa7115_read(client, 0x02) & 0xf0) |
1143                                state->input);
1144
1145                 /* bypass chrominance trap for modes 6..9 */
1146                 saa7115_write(client, 0x09,
1147                               (saa7115_read(client, 0x09) & 0x7f) |
1148                                (state->input < 6 ? 0x0 : 0x80));
1149                 break;
1150
1151         case VIDIOC_STREAMON:
1152         case VIDIOC_STREAMOFF:
1153                 v4l_dbg(1, debug, client, "%s output\n",
1154                         (cmd == VIDIOC_STREAMON) ? "enable" : "disable");
1155
1156                 if (state->enable != (cmd == VIDIOC_STREAMON)) {
1157                         state->enable = (cmd == VIDIOC_STREAMON);
1158                         saa7115_write(client, 0x87, state->enable);
1159                 }
1160                 break;
1161
1162         case VIDIOC_INT_DECODE_VBI_LINE:
1163                 saa7115_decode_vbi_line(client, arg);
1164                 break;
1165
1166         case VIDIOC_INT_RESET:
1167                 v4l_dbg(1, debug, client, "decoder RESET\n");
1168                 saa7115_writeregs(client, saa7115_cfg_reset_scaler);
1169                 break;
1170
1171         case VIDIOC_INT_G_VBI_DATA:
1172         {
1173                 struct v4l2_sliced_vbi_data *data = arg;
1174
1175                 switch (data->id) {
1176                 case V4L2_SLICED_WSS_625:
1177                         if (saa7115_read(client, 0x6b) & 0xc0)
1178                                 return -EIO;
1179                         data->data[0] = saa7115_read(client, 0x6c);
1180                         data->data[1] = saa7115_read(client, 0x6d);
1181                         return 0;
1182                 case V4L2_SLICED_CAPTION_525:
1183                         if (data->field == 0) {
1184                                 /* CC */
1185                                 if (saa7115_read(client, 0x66) & 0xc0)
1186                                         return -EIO;
1187                                 data->data[0] = saa7115_read(client, 0x67);
1188                                 data->data[1] = saa7115_read(client, 0x68);
1189                                 return 0;
1190                         }
1191                         /* XDS */
1192                         if (saa7115_read(client, 0x66) & 0x30)
1193                                 return -EIO;
1194                         data->data[0] = saa7115_read(client, 0x69);
1195                         data->data[1] = saa7115_read(client, 0x6a);
1196                         return 0;
1197                 default:
1198                         return -EINVAL;
1199                 }
1200                 break;
1201         }
1202
1203 #ifdef CONFIG_VIDEO_ADV_DEBUG
1204         case VIDIOC_INT_G_REGISTER:
1205         {
1206                 struct v4l2_register *reg = arg;
1207
1208                 if (reg->i2c_id != I2C_DRIVERID_SAA711X)
1209                         return -EINVAL;
1210                 reg->val = saa7115_read(client, reg->reg & 0xff);
1211                 break;
1212         }
1213
1214         case VIDIOC_INT_S_REGISTER:
1215         {
1216                 struct v4l2_register *reg = arg;
1217
1218                 if (reg->i2c_id != I2C_DRIVERID_SAA711X)
1219                         return -EINVAL;
1220                 if (!capable(CAP_SYS_ADMIN))
1221                         return -EPERM;
1222                 saa7115_write(client, reg->reg & 0xff, reg->val & 0xff);
1223                 break;
1224         }
1225 #endif
1226
1227         case VIDIOC_INT_G_CHIP_IDENT:
1228                 *iarg = state->ident;
1229                 break;
1230
1231         default:
1232                 return -EINVAL;
1233         }
1234
1235         return 0;
1236 }
1237
1238 /* ----------------------------------------------------------------------- */
1239
1240 static struct i2c_driver i2c_driver_saa7115;
1241
1242 static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1243 {
1244         struct i2c_client *client;
1245         struct saa7115_state *state;
1246         u8 chip_id;
1247
1248         /* Check if the adapter supports the needed features */
1249         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1250                 return 0;
1251
1252         client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
1253         if (client == 0)
1254                 return -ENOMEM;
1255         client->addr = address;
1256         client->adapter = adapter;
1257         client->driver = &i2c_driver_saa7115;
1258         snprintf(client->name, sizeof(client->name) - 1, "saa7115");
1259
1260         v4l_dbg(1, debug, client, "detecting saa7115 client on address 0x%x\n", address << 1);
1261
1262         saa7115_write(client, 0, 5);
1263         chip_id = saa7115_read(client, 0) & 0x0f;
1264         if (chip_id != 4 && chip_id != 5) {
1265                 v4l_dbg(1, debug, client, "saa7115 not found\n");
1266                 kfree(client);
1267                 return 0;
1268         }
1269         if (chip_id == 4) {
1270                 snprintf(client->name, sizeof(client->name) - 1, "saa7114");
1271         }
1272         v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name);
1273
1274         state = kzalloc(sizeof(struct saa7115_state), GFP_KERNEL);
1275         i2c_set_clientdata(client, state);
1276         if (state == NULL) {
1277                 kfree(client);
1278                 return -ENOMEM;
1279         }
1280         state->std = V4L2_STD_NTSC;
1281         state->input = -1;
1282         state->enable = 1;
1283         state->radio = 0;
1284         state->bright = 128;
1285         state->contrast = 64;
1286         state->hue = 0;
1287         state->sat = 64;
1288         state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115;
1289         state->audclk_freq = 48000;
1290
1291         v4l_dbg(1, debug, client, "writing init values\n");
1292
1293         /* init to 60hz/48khz */
1294         saa7115_writeregs(client, saa7115_init_auto_input);
1295         saa7115_writeregs(client, saa7115_init_misc);
1296         saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
1297         saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
1298         saa7115_writeregs(client, saa7115_cfg_60hz_video);
1299         saa7115_set_audio_clock_freq(client, state->audclk_freq);
1300         saa7115_writeregs(client, saa7115_cfg_reset_scaler);
1301
1302         i2c_attach_client(client);
1303
1304         v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1305                 saa7115_read(client, 0x1e), saa7115_read(client, 0x1f));
1306
1307         return 0;
1308 }
1309
1310 static int saa7115_probe(struct i2c_adapter *adapter)
1311 {
1312         if (adapter->class & I2C_CLASS_TV_ANALOG)
1313                 return i2c_probe(adapter, &addr_data, &saa7115_attach);
1314         return 0;
1315 }
1316
1317 static int saa7115_detach(struct i2c_client *client)
1318 {
1319         struct saa7115_state *state = i2c_get_clientdata(client);
1320         int err;
1321
1322         err = i2c_detach_client(client);
1323         if (err) {
1324                 return err;
1325         }
1326
1327         kfree(state);
1328         kfree(client);
1329         return 0;
1330 }
1331
1332 /* ----------------------------------------------------------------------- */
1333
1334 /* i2c implementation */
1335 static struct i2c_driver i2c_driver_saa7115 = {
1336         .driver = {
1337                 .name = "saa7115",
1338         },
1339         .id = I2C_DRIVERID_SAA711X,
1340         .attach_adapter = saa7115_probe,
1341         .detach_client = saa7115_detach,
1342         .command = saa7115_command,
1343 };
1344
1345
1346 static int __init saa7115_init_module(void)
1347 {
1348         return i2c_add_driver(&i2c_driver_saa7115);
1349 }
1350
1351 static void __exit saa7115_cleanup_module(void)
1352 {
1353         i2c_del_driver(&i2c_driver_saa7115);
1354 }
1355
1356 module_init(saa7115_init_module);
1357 module_exit(saa7115_cleanup_module);