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