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