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