]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/saa7115.c
V4L/DVB (4551): Added register aliases for saa711x registers, instead of using reg...
[linux-2.6-omap-h63xx.git] / drivers / media / video / saa7115.c
1 /* saa7115 - Philips SAA7113/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  * SAA7113 support by Mauro Carvalho Chehab <mchehab@infradead.org>
20  *
21  * This program is free software; you can redistribute it and/or
22  * modify it under the terms of the GNU General Public License
23  * as published by the Free Software Foundation; either version 2
24  * of the License, or (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  *
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, write to the Free Software
33  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
34  */
35
36 #include "saa711x_regs.h"
37
38 #include <linux/kernel.h>
39 #include <linux/module.h>
40 #include <linux/slab.h>
41 #include <linux/i2c.h>
42 #include <linux/videodev2.h>
43 #include <media/v4l2-common.h>
44 #include <media/saa7115.h>
45 #include <asm/div64.h>
46
47 MODULE_DESCRIPTION("Philips SAA7113/SAA7114/SAA7115 video decoder driver");
48 MODULE_AUTHOR(  "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
49                 "Hans Verkuil, Mauro Carvalho Chehab");
50 MODULE_LICENSE("GPL");
51
52 static int debug = 0;
53 module_param(debug, bool, 0644);
54
55 MODULE_PARM_DESC(debug, "Debug level (0-1)");
56
57 static unsigned short normal_i2c[] = {
58                 0x4a >> 1, 0x48 >> 1,   /* SAA7113 */
59                 0x42 >> 1, 0x40 >> 1,   /* SAA7114 and SAA7115 */
60                 I2C_CLIENT_END };
61
62
63 I2C_CLIENT_INSMOD;
64
65 struct saa7115_state {
66         v4l2_std_id std;
67         int input;
68         int enable;
69         int radio;
70         int bright;
71         int contrast;
72         int hue;
73         int sat;
74         enum v4l2_chip_ident ident;
75         u32 audclk_freq;
76         u32 crystal_freq;
77         u8 ucgc;
78         u8 cgcdiv;
79         u8 apll;
80 };
81
82 /* ----------------------------------------------------------------------- */
83
84 static inline int saa7115_write(struct i2c_client *client, u8 reg, u8 value)
85 {
86         return i2c_smbus_write_byte_data(client, reg, value);
87 }
88
89 static int saa7115_writeregs(struct i2c_client *client, const unsigned char *regs)
90 {
91         unsigned char reg, data;
92
93         while (*regs != 0x00) {
94                 reg = *(regs++);
95                 data = *(regs++);
96                 if (saa7115_write(client, reg, data) < 0)
97                         return -1;
98         }
99         return 0;
100 }
101
102 static inline int saa7115_read(struct i2c_client *client, u8 reg)
103 {
104         return i2c_smbus_read_byte_data(client, reg);
105 }
106
107 /* ----------------------------------------------------------------------- */
108
109 /* If a value differs from the Hauppauge driver values, then the comment starts with
110    'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
111    Hauppauge driver sets. */
112
113 static const unsigned char saa7115_init_auto_input[] = {
114                 /* Front-End Part */
115         R_01_INC_DELAY, 0x48,                   /* white peak control disabled */
116         R_03_INPUT_CNTL_2, 0x20,                /* was 0x30. 0x20: long vertical blanking */
117         R_04_INPUT_CNTL_3, 0x90,                /* analog gain set to 0 */
118         R_05_INPUT_CNTL_4, 0x90,                /* analog gain set to 0 */
119                 /* Decoder Part */
120         R_06_H_SYNC_START, 0xeb,                /* horiz sync begin = -21 */
121         R_07_H_SYNC_STOP, 0xe0,                 /* horiz sync stop = -17 */
122         R_0A_LUMA_BRIGHT_CNTL, 0x80,            /* was 0x88. decoder brightness, 0x80 is itu standard */
123         R_0B_LUMA_CONTRAST_CNTL, 0x44,          /* was 0x48. decoder contrast, 0x44 is itu standard */
124         R_0C_CHROMA_SAT_CNTL, 0x40,             /* was 0x47. decoder saturation, 0x40 is itu standard */
125         R_0D_CHROMA_HUE_CNTL, 0x00,
126         R_0F_CHROMA_GAIN_CNTL, 0x00,            /* use automatic gain  */
127         R_10_CHROMA_CNTL_2, 0x06,               /* chroma: active adaptive combfilter */
128         R_11_MODE_DELAY_CNTL, 0x00,
129         R_12_RT_SIGNAL_CNTL, 0x9d,              /* RTS0 output control: VGATE */
130         R_13_RT_X_PORT_OUT_CNTL, 0x80,          /* ITU656 standard mode, RTCO output enable RTCE */
131         R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
132         R_18_RAW_DATA_GAIN_CNTL, 0x40,          /* gain 0x00 = nominal */
133         R_19_RAW_DATA_OFF_CNTL, 0x80,
134         R_1A_COLOR_KILL_LVL_CNTL, 0x77,         /* recommended value */
135         R_1B_MISC_TVVCRDET, 0x42,               /* recommended value */
136         R_1C_ENHAN_COMB_CTRL1, 0xa9,            /* recommended value */
137         R_1D_ENHAN_COMB_CTRL2, 0x01,            /* recommended value */
138
139                 /* Power Device Control */
140         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,    /* reset device */
141         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,    /* set device programmed, all in operational mode */
142         0x00, 0x00
143 };
144
145 static const unsigned char saa7115_cfg_reset_scaler[] = {
146         R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00,    /* disable I-port output */
147         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
148         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,            /* activate scaler */
149         R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 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         /* hsize = 0x2d0 = 720 */
157         R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
158         R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
159
160         /* Why not in 60hz-Land, too? */
161         R_D0_B_HORIZ_PRESCALING, 0x01,          /* downscale = 1 */
162         /* hor lum scaling 0x0400 = 1 */
163         R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
164         R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
165
166         /* must be hor lum scaling / 2 */
167         R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
168         R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
169
170         0x00, 0x00
171 };
172
173 static const unsigned char saa7115_cfg_60hz_fullres_y[] = {
174         /* output window size = 248 (but 60hz is 240?) */
175         R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 0xf8,
176         R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
177
178         /* Why not in 60hz-Land, too? */
179         R_D5_B_LUMA_CONTRAST_CNTL, 0x40,                /* Lum contrast, nominal value = 0x40 */
180         R_D6_B_CHROMA_SATURATION_CNTL, 0x40,            /* Chroma satur. nominal value = 0x80 */
181
182         R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
183         R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
184
185         R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
186         R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
187
188         0x00, 0x00
189 };
190
191 static const unsigned char saa7115_cfg_60hz_video[] = {
192         R_80_GLOBAL_CNTL_1, 0x00,                       /* reset tasks */
193         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
194
195         R_15_VGATE_START_FID_CHG, 0x03,
196         R_16_VGATE_STOP, 0x11,
197         R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
198
199         R_08_SYNC_CNTL, 0x68,                   /* 0xBO: auto detection, 0x68 = NTSC */
200         R_0E_CHROMA_CNTL_1, 0x07,               /* video autodetection is on */
201
202         R_5A_V_OFF_FOR_SLICER, 0x06,            /* standard 60hz value for ITU656 line counting */
203
204         /* Task A */
205         R_90_A_TASK_HANDLING_CNTL, 0x80,
206         R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
207         R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
208         R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
209
210         /* hoffset low (input), 0x0002 is minimum */
211         R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
212         R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
213
214         /* hsize low (input), 0x02d0 = 720 */
215         R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
216         R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
217
218         R_98_A_VERT_INPUT_WINDOW_START, 0x05,
219         R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
220
221         R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
222         R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
223
224         R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
225         R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
226
227         R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
228         R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
229
230         /* Task B */
231         R_C0_B_TASK_HANDLING_CNTL, 0x00,
232         R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
233         R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
234         R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
235
236         /* 0x0002 is minimum */
237         R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
238         R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
239
240         /* 0x02d0 = 720 */
241         R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
242         R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
243
244         /* vwindow start 0x12 = 18 */
245         R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
246         R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
247
248         /* vwindow length 0xf8 = 248 */
249         R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0xf8,
250         R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
251
252         /* hwindow 0x02d0 = 720 */
253         R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
254         R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
255
256         R_F0_LFCO_PER_LINE, 0xad,               /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
257         R_F1_P_I_PARAM_SELECT, 0x05,            /* low bit with 0xF0 */
258         R_F5_PULSGEN_LINE_LENGTH, 0xad,
259         R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
260
261         R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00,    /* Disable I-port output */
262         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
263         R_80_GLOBAL_CNTL_1, 0x20,                       /* Activate only task "B", continuous mode (was 0xA0) */
264         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,            /* activate scaler */
265         R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,    /* Enable I-port output */
266         0x00, 0x00
267 };
268
269 static const unsigned char saa7115_cfg_50hz_fullres_x[] = {
270         /* hsize low (output), 720 same as 60hz */
271         R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
272         R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
273
274         R_D0_B_HORIZ_PRESCALING, 0x01,          /* down scale = 1 */
275         R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,    /* hor lum scaling 0x0400 = 1 */
276         R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
277
278         /* must be hor lum scaling / 2 */
279         R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
280         R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
281
282         0x00, 0x00
283 };
284 static const unsigned char saa7115_cfg_50hz_fullres_y[] = {
285         /* vsize low (output), 0x0120 = 288 */
286         R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 0x20,
287         R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x01,
288
289         R_D5_B_LUMA_CONTRAST_CNTL, 0x40,        /* Lum contrast, nominal value = 0x40 */
290         R_D6_B_CHROMA_SATURATION_CNTL, 0x40,    /* Chroma satur. nominal value = 0x80 */
291
292         R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
293         R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
294
295         R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
296         R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
297
298         0x00, 0x00
299 };
300
301 static const unsigned char saa7115_cfg_50hz_video[] = {
302         R_80_GLOBAL_CNTL_1, 0x00,
303         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,    /* reset scaler */
304
305         R_15_VGATE_START_FID_CHG, 0x37,         /* VGATE start */
306         R_16_VGATE_STOP, 0x16,
307         R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
308
309         R_08_SYNC_CNTL, 0x28,                   /* 0x28 = PAL */
310         R_0E_CHROMA_CNTL_1, 0x07,
311
312         R_5A_V_OFF_FOR_SLICER, 0x03,            /* standard 50hz value */
313
314         /* Task A */
315         R_90_A_TASK_HANDLING_CNTL, 0x81,
316         R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
317         R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
318         R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
319
320         /* This is weird: the datasheet says that you should use 2 as the minimum value, */
321         /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
322         /* hoffset low (input), 0x0002 is minimum */
323         R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
324         R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
325
326         /* hsize low (input), 0x02d0 = 720 */
327         R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
328         R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
329
330         R_98_A_VERT_INPUT_WINDOW_START, 0x03,
331         R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
332
333         /* vsize 0x12 = 18 */
334         R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
335         R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
336
337         /* hsize 0x05a0 = 1440 */
338         R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
339         R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,    /* hsize hi (output) */
340         R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12,         /* vsize low (output), 0x12 = 18 */
341         R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,     /* vsize hi (output) */
342
343         /* Task B */
344         R_C0_B_TASK_HANDLING_CNTL, 0x00,
345         R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
346         R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
347         R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
348
349         /* This is weird: the datasheet says that you should use 2 as the minimum value, */
350         /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
351         /* hoffset low (input), 0x0002 is minimum. See comment above. */
352         R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
353         R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
354
355         /* hsize 0x02d0 = 720 */
356         R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
357         R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
358
359         /* voffset 0x16 = 22 */
360         R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
361         R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
362
363         /* vsize 0x0120 = 288 */
364         R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
365         R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
366
367         /* hsize 0x02d0 = 720 */
368         R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
369         R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
370
371         /* vsize 0x0120 = 288 */
372         R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 0x20,
373         R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x01,
374
375         R_F0_LFCO_PER_LINE, 0xb0,               /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
376         R_F1_P_I_PARAM_SELECT, 0x05,            /* low bit with 0xF0, (was 0x05) */
377         R_F5_PULSGEN_LINE_LENGTH, 0xb0,
378         R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
379
380         R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00,    /* Disable I-port output */
381         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler (was 0xD0) */
382         R_80_GLOBAL_CNTL_1, 0x20,                       /* Activate only task "B" */
383         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,            /* activate scaler */
384         R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,    /* Enable I-port output */
385
386         0x00, 0x00
387 };
388
389 /* ============== SAA7715 VIDEO templates (end) =======  */
390
391 static const unsigned char saa7115_cfg_vbi_on[] = {
392         R_80_GLOBAL_CNTL_1, 0x00,                       /* reset tasks */
393         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
394         R_80_GLOBAL_CNTL_1, 0x30,                       /* Activate both tasks */
395         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,            /* activate scaler */
396         R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,    /* Enable I-port output */
397
398         0x00, 0x00
399 };
400
401 static const unsigned char saa7115_cfg_vbi_off[] = {
402         R_80_GLOBAL_CNTL_1, 0x00,                       /* reset tasks */
403         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,            /* reset scaler */
404         R_80_GLOBAL_CNTL_1, 0x20,                       /* Activate only task "B" */
405         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,            /* activate scaler */
406         R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,    /* Enable I-port output */
407
408         0x00, 0x00
409 };
410
411 static const unsigned char saa7113_init_auto_input[] = {
412         R_01_INC_DELAY, 0x08,
413         R_02_INPUT_CNTL_1, 0xc2,
414         R_03_INPUT_CNTL_2, 0x30,
415         R_04_INPUT_CNTL_3, 0x00,
416         R_05_INPUT_CNTL_4, 0x00,
417         R_06_H_SYNC_START, 0x89,
418         R_07_H_SYNC_STOP, 0x0d,
419         R_08_SYNC_CNTL, 0x88,
420         R_09_LUMA_CNTL, 0x01,
421         R_0A_LUMA_BRIGHT_CNTL, 0x80,
422         R_0B_LUMA_CONTRAST_CNTL, 0x47,
423         R_0C_CHROMA_SAT_CNTL, 0x40,
424         R_0D_CHROMA_HUE_CNTL, 0x00,
425         R_0E_CHROMA_CNTL_1, 0x01,
426         R_0F_CHROMA_GAIN_CNTL, 0x2a,
427         R_10_CHROMA_CNTL_2, 0x08,
428         R_11_MODE_DELAY_CNTL, 0x0c,
429         R_12_RT_SIGNAL_CNTL, 0x07,
430         R_13_RT_X_PORT_OUT_CNTL, 0x00,
431         R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
432         R_15_VGATE_START_FID_CHG, 0x00,
433         R_16_VGATE_STOP, 0x00,
434         R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
435
436         0x00, 0x00
437 };
438
439 static const unsigned char saa7115_init_misc[] = {
440         R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
441         0x82, 0x00,             /* Reserved register - value should be zero*/
442         R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
443         R_84_I_PORT_SIGNAL_DEF, 0x20,
444         R_85_I_PORT_SIGNAL_POLAR, 0x21,
445         R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
446         R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
447
448         /* Task A */
449         R_A0_A_HORIZ_PRESCALING, 0x01,
450         R_A1_A_ACCUMULATION_LENGTH, 0x00,
451         R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
452
453         /* Configure controls at nominal value*/
454         R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
455         R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
456         R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
457
458         /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
459         R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
460         R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
461
462         R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
463
464         /* must be horiz lum scaling / 2 */
465         R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
466         R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
467
468         /* must be offset luma / 2 */
469         R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
470
471         R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
472         R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
473
474         R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
475         R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
476
477         R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
478
479         R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
480         R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
481         R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
482         R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
483
484         R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
485         R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
486         R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
487         R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
488
489         /* Task B */
490         R_D0_B_HORIZ_PRESCALING, 0x01,
491         R_D1_B_ACCUMULATION_LENGTH, 0x00,
492         R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
493
494         /* Configure controls at nominal value*/
495         R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
496         R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
497         R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
498
499         /* hor lum scaling 0x0400 = 1 */
500         R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
501         R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
502
503         R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
504
505         /* must be hor lum scaling / 2 */
506         R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
507         R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
508
509         /* must be offset luma / 2 */
510         R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
511
512         R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
513         R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
514
515         R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
516         R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
517
518         R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
519
520         R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
521         R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
522         R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
523         R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
524
525         R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
526         R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
527         R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
528         R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
529
530         R_F2_NOMINAL_PLL2_DTO, 0x50,            /* crystal clock = 24.576 MHz, target = 27MHz */
531         R_F3_PLL_INCREMENT, 0x46,
532         R_F4_PLL2_STATUS, 0x00,
533         R_F7_PULSE_A_POS_MSB, 0x4b,             /* not the recommended settings! */
534         R_F8_PULSE_B_POS, 0x00,
535         R_F9_PULSE_B_POS_MSB, 0x4b,
536         R_FA_PULSE_C_POS, 0x00,
537         R_FB_PULSE_C_POS_MSB, 0x4b,
538
539         /* PLL2 lock detection settings: 71 lines 50% phase error */
540         R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
541
542         /* Turn off VBI */
543         R_40_SLICER_CNTL_1, 0x20,             /* No framing code errors allowed. */
544         R_41_LCR_BASE, 0xff,
545         R_41_LCR_BASE+1, 0xff,
546         R_41_LCR_BASE+2, 0xff,
547         R_41_LCR_BASE+3, 0xff,
548         R_41_LCR_BASE+4, 0xff,
549         R_41_LCR_BASE+5, 0xff,
550         R_41_LCR_BASE+6, 0xff,
551         R_41_LCR_BASE+7, 0xff,
552         R_41_LCR_BASE+8, 0xff,
553         R_41_LCR_BASE+9, 0xff,
554         R_41_LCR_BASE+10, 0xff,
555         R_41_LCR_BASE+11, 0xff,
556         R_41_LCR_BASE+12, 0xff,
557         R_41_LCR_BASE+13, 0xff,
558         R_41_LCR_BASE+14, 0xff,
559         R_41_LCR_BASE+15, 0xff,
560         R_41_LCR_BASE+16, 0xff,
561         R_41_LCR_BASE+17, 0xff,
562         R_41_LCR_BASE+18, 0xff,
563         R_41_LCR_BASE+19, 0xff,
564         R_41_LCR_BASE+20, 0xff,
565         R_41_LCR_BASE+21, 0xff,
566         R_41_LCR_BASE+22, 0xff,
567         R_58_PROGRAM_FRAMING_CODE, 0x40,
568         R_59_H_OFF_FOR_SLICER, 0x47,
569         R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
570         R_5D_DID, 0xbd,
571         R_5E_SDID, 0x35,
572
573         R_02_INPUT_CNTL_1, 0x84,                /* input tuner -> input 4, amplifier active */
574         R_09_LUMA_CNTL, 0x53,                   /* 0x53, was 0x56 for 60hz. luminance control */
575
576         R_80_GLOBAL_CNTL_1, 0x20,               /* enable task B */
577         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
578         R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
579         0x00, 0x00
580 };
581
582 static int saa7115_odd_parity(u8 c)
583 {
584         c ^= (c >> 4);
585         c ^= (c >> 2);
586         c ^= (c >> 1);
587
588         return c & 1;
589 }
590
591 static int saa7115_decode_vps(u8 * dst, u8 * p)
592 {
593         static const u8 biphase_tbl[] = {
594                 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
595                 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
596                 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
597                 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
598                 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
599                 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
600                 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
601                 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
602                 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
603                 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
604                 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
605                 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
606                 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
607                 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
608                 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
609                 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
610                 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
611                 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
612                 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
613                 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
614                 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
615                 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
616                 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
617                 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
618                 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
619                 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
620                 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
621                 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
622                 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
623                 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
624                 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
625                 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
626         };
627         int i;
628         u8 c, err = 0;
629
630         for (i = 0; i < 2 * 13; i += 2) {
631                 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
632                 c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
633                 dst[i / 2] = c;
634         }
635         return err & 0xf0;
636 }
637
638 static int saa7115_decode_wss(u8 * p)
639 {
640         static const int wss_bits[8] = {
641                 0, 0, 0, 1, 0, 1, 1, 1
642         };
643         unsigned char parity;
644         int wss = 0;
645         int i;
646
647         for (i = 0; i < 16; i++) {
648                 int b1 = wss_bits[p[i] & 7];
649                 int b2 = wss_bits[(p[i] >> 3) & 7];
650
651                 if (b1 == b2)
652                         return -1;
653                 wss |= b2 << i;
654         }
655         parity = wss & 15;
656         parity ^= parity >> 2;
657         parity ^= parity >> 1;
658
659         if (!(parity & 1))
660                 return -1;
661
662         return wss;
663 }
664
665
666 static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
667 {
668         struct saa7115_state *state = i2c_get_clientdata(client);
669         u32 acpf;
670         u32 acni;
671         u32 hz;
672         u64 f;
673         u8 acc = 0;     /* reg 0x3a, audio clock control */
674
675         v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq);
676
677         /* sanity check */
678         if (freq < 32000 || freq > 48000)
679                 return -EINVAL;
680
681         /* The saa7113 has no audio clock */
682         if (state->ident == V4L2_IDENT_SAA7113)
683                 return 0;
684
685         /* hz is the refresh rate times 100 */
686         hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
687         /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
688         acpf = (25600 * freq) / hz;
689         /* acni = (256 * freq * 2^23) / crystal_frequency =
690                   (freq * 2^(8+23)) / crystal_frequency =
691                   (freq << 31) / crystal_frequency */
692         f = freq;
693         f = f << 31;
694         do_div(f, state->crystal_freq);
695         acni = f;
696         if (state->ucgc) {
697                 acpf = acpf * state->cgcdiv / 16;
698                 acni = acni * state->cgcdiv / 16;
699                 acc = 0x80;
700                 if (state->cgcdiv == 3)
701                         acc |= 0x40;
702         }
703         if (state->apll)
704                 acc |= 0x08;
705
706         saa7115_write(client, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
707         saa7115_write(client, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
708         saa7115_write(client, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
709
710         saa7115_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
711         saa7115_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
712                                                         (acpf >> 8) & 0xff);
713         saa7115_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
714                                                         (acpf >> 16) & 0x03);
715
716         saa7115_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
717         saa7115_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
718         saa7115_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
719         state->audclk_freq = freq;
720         return 0;
721 }
722
723 static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
724 {
725         struct saa7115_state *state = i2c_get_clientdata(client);
726
727         switch (ctrl->id) {
728         case V4L2_CID_BRIGHTNESS:
729                 if (ctrl->value < 0 || ctrl->value > 255) {
730                         v4l_err(client, "invalid brightness setting %d\n", ctrl->value);
731                         return -ERANGE;
732                 }
733
734                 state->bright = ctrl->value;
735                 saa7115_write(client, R_0A_LUMA_BRIGHT_CNTL, state->bright);
736                 break;
737
738         case V4L2_CID_CONTRAST:
739                 if (ctrl->value < 0 || ctrl->value > 127) {
740                         v4l_err(client, "invalid contrast setting %d\n", ctrl->value);
741                         return -ERANGE;
742                 }
743
744                 state->contrast = ctrl->value;
745                 saa7115_write(client, R_0B_LUMA_CONTRAST_CNTL, state->contrast);
746                 break;
747
748         case V4L2_CID_SATURATION:
749                 if (ctrl->value < 0 || ctrl->value > 127) {
750                         v4l_err(client, "invalid saturation setting %d\n", ctrl->value);
751                         return -ERANGE;
752                 }
753
754                 state->sat = ctrl->value;
755                 saa7115_write(client, R_0C_CHROMA_SAT_CNTL, state->sat);
756                 break;
757
758         case V4L2_CID_HUE:
759                 if (ctrl->value < -127 || ctrl->value > 127) {
760                         v4l_err(client, "invalid hue setting %d\n", ctrl->value);
761                         return -ERANGE;
762                 }
763
764                 state->hue = ctrl->value;
765                 saa7115_write(client, R_0D_CHROMA_HUE_CNTL, state->hue);
766                 break;
767
768         default:
769                 return -EINVAL;
770         }
771
772         return 0;
773 }
774
775 static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
776 {
777         struct saa7115_state *state = i2c_get_clientdata(client);
778
779         switch (ctrl->id) {
780         case V4L2_CID_BRIGHTNESS:
781                 ctrl->value = state->bright;
782                 break;
783         case V4L2_CID_CONTRAST:
784                 ctrl->value = state->contrast;
785                 break;
786         case V4L2_CID_SATURATION:
787                 ctrl->value = state->sat;
788                 break;
789         case V4L2_CID_HUE:
790                 ctrl->value = state->hue;
791                 break;
792         default:
793                 return -EINVAL;
794         }
795
796         return 0;
797 }
798
799 static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
800 {
801         struct saa7115_state *state = i2c_get_clientdata(client);
802         int taskb = saa7115_read(client, R_80_GLOBAL_CNTL_1) & 0x10;
803
804         /* Prevent unnecessary standard changes. During a standard
805            change the I-Port is temporarily disabled. Any devices
806            reading from that port can get confused.
807            Note that VIDIOC_S_STD is also used to switch from
808            radio to TV mode, so if a VIDIOC_S_STD is broadcast to
809            all I2C devices then you do not want to have an unwanted
810            side-effect here. */
811         if (std == state->std)
812                 return;
813
814         // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
815         if (std & V4L2_STD_525_60) {
816                 v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n");
817                 saa7115_writeregs(client, saa7115_cfg_60hz_video);
818         } else {
819                 v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n");
820                 saa7115_writeregs(client, saa7115_cfg_50hz_video);
821         }
822
823         /* Register 0E - Bits D6-D4 on NO-AUTO mode
824                 (SAA7113 doesn't have auto mode)
825             50 Hz / 625 lines           60 Hz / 525 lines
826         000 PAL BGDHI (4.43Mhz)         NTSC M (3.58MHz)
827         001 NTSC 4.43 (50 Hz)           PAL 4.43 (60 Hz)
828         010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
829         011 NTSC N (3.58MHz)            PAL M (3.58MHz)
830         100 reserved                    NTSC-Japan (3.58MHz)
831         */
832         if (state->ident == V4L2_IDENT_SAA7113) {
833                 u8 reg = saa7115_read(client, R_0E_CHROMA_CNTL_1) & 0x8f;
834
835                 if (std == V4L2_STD_PAL_M) {
836                         reg |= 0x30;
837                 } else if (std == V4L2_STD_PAL_N) {
838                         reg |= 0x20;
839                 } else if (std == V4L2_STD_PAL_60) {
840                         reg |= 0x10;
841                 } else if (std == V4L2_STD_NTSC_M_JP) {
842                         reg |= 0x40;
843                 }
844                 saa7115_write(client, R_0E_CHROMA_CNTL_1, reg);
845         }
846
847
848         state->std = std;
849
850         /* restart task B if needed */
851         if (taskb && state->ident != V4L2_IDENT_SAA7115) {
852                 saa7115_writeregs(client, saa7115_cfg_vbi_on);
853         }
854
855         /* switch audio mode too! */
856         saa7115_set_audio_clock_freq(client, state->audclk_freq);
857 }
858
859 static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client)
860 {
861         struct saa7115_state *state = i2c_get_clientdata(client);
862
863         return state->std;
864 }
865
866 static void saa7115_log_status(struct i2c_client *client)
867 {
868         struct saa7115_state *state = i2c_get_clientdata(client);
869         int reg1e, reg1f;
870         int signalOk;
871         int vcr;
872
873         v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
874         if (state->ident != V4L2_IDENT_SAA7115) {
875                 /* status for the saa7114 */
876                 reg1f = saa7115_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
877                 signalOk = (reg1f & 0xc1) == 0x81;
878                 v4l_info(client, "Video signal:    %s\n", signalOk ? "ok" : "bad");
879                 v4l_info(client, "Frequency:       %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
880                 return;
881         }
882
883         /* status for the saa7115 */
884         reg1e = saa7115_read(client, R_1E_STATUS_BYTE_1_VD_DEC);
885         reg1f = saa7115_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
886
887         signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
888         vcr = !(reg1f & 0x10);
889
890         if (state->input >= 6) {
891                 v4l_info(client, "Input:           S-Video %d\n", state->input - 6);
892         } else {
893                 v4l_info(client, "Input:           Composite %d\n", state->input);
894         }
895         v4l_info(client, "Video signal:    %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
896         v4l_info(client, "Frequency:       %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
897
898         switch (reg1e & 0x03) {
899                 case 1:
900                         v4l_info(client, "Detected format: NTSC\n");
901                         break;
902                 case 2:
903                         v4l_info(client, "Detected format: PAL\n");
904                         break;
905                 case 3:
906                         v4l_info(client, "Detected format: SECAM\n");
907                         break;
908                 default:
909                         v4l_info(client, "Detected format: BW/No color\n");
910                         break;
911         }
912 }
913
914 /* setup the sliced VBI lcr registers according to the sliced VBI format */
915 static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
916 {
917         struct saa7115_state *state = i2c_get_clientdata(client);
918         int is_50hz = (state->std & V4L2_STD_625_50);
919         u8 lcr[24];
920         int i, x;
921
922         /* saa7113/7114 doesn't yet support VBI */
923         if (state->ident != V4L2_IDENT_SAA7115)
924                 return;
925
926         for (i = 0; i <= 23; i++)
927                 lcr[i] = 0xff;
928
929         if (fmt->service_set == 0) {
930                 /* raw VBI */
931                 if (is_50hz)
932                         for (i = 6; i <= 23; i++)
933                                 lcr[i] = 0xdd;
934                 else
935                         for (i = 10; i <= 21; i++)
936                                 lcr[i] = 0xdd;
937         } else {
938                 /* sliced VBI */
939                 /* first clear lines that cannot be captured */
940                 if (is_50hz) {
941                         for (i = 0; i <= 5; i++)
942                                 fmt->service_lines[0][i] =
943                                         fmt->service_lines[1][i] = 0;
944                 }
945                 else {
946                         for (i = 0; i <= 9; i++)
947                                 fmt->service_lines[0][i] =
948                                         fmt->service_lines[1][i] = 0;
949                         for (i = 22; i <= 23; i++)
950                                 fmt->service_lines[0][i] =
951                                         fmt->service_lines[1][i] = 0;
952                 }
953
954                 /* Now set the lcr values according to the specified service */
955                 for (i = 6; i <= 23; i++) {
956                         lcr[i] = 0;
957                         for (x = 0; x <= 1; x++) {
958                                 switch (fmt->service_lines[1-x][i]) {
959                                         case 0:
960                                                 lcr[i] |= 0xf << (4 * x);
961                                                 break;
962                                         case V4L2_SLICED_TELETEXT_B:
963                                                 lcr[i] |= 1 << (4 * x);
964                                                 break;
965                                         case V4L2_SLICED_CAPTION_525:
966                                                 lcr[i] |= 4 << (4 * x);
967                                                 break;
968                                         case V4L2_SLICED_WSS_625:
969                                                 lcr[i] |= 5 << (4 * x);
970                                                 break;
971                                         case V4L2_SLICED_VPS:
972                                                 lcr[i] |= 7 << (4 * x);
973                                                 break;
974                                 }
975                         }
976                 }
977         }
978
979         /* write the lcr registers */
980         for (i = 2; i <= 23; i++) {
981                 saa7115_write(client, i - 2 + R_41_LCR_BASE, lcr[i]);
982         }
983
984         /* enable/disable raw VBI capturing */
985         saa7115_writeregs(client, fmt->service_set == 0 ?
986                                 saa7115_cfg_vbi_on :
987                                 saa7115_cfg_vbi_off);
988 }
989
990 static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
991 {
992         static u16 lcr2vbi[] = {
993                 0, V4L2_SLICED_TELETEXT_B, 0,   /* 1 */
994                 0, V4L2_SLICED_CAPTION_525,     /* 4 */
995                 V4L2_SLICED_WSS_625, 0,         /* 5 */
996                 V4L2_SLICED_VPS, 0, 0, 0, 0,    /* 7 */
997                 0, 0, 0, 0
998         };
999         struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;
1000         int i;
1001
1002         if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
1003                 return -EINVAL;
1004         memset(sliced, 0, sizeof(*sliced));
1005         /* done if using raw VBI */
1006         if (saa7115_read(client, R_80_GLOBAL_CNTL_1) & 0x10)
1007                 return 0;
1008         for (i = 2; i <= 23; i++) {
1009                 u8 v = saa7115_read(client, i - 2 + R_41_LCR_BASE);
1010
1011                 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
1012                 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
1013                 sliced->service_set |=
1014                         sliced->service_lines[0][i] | sliced->service_lines[1][i];
1015         }
1016         return 0;
1017 }
1018
1019 static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
1020 {
1021         struct saa7115_state *state = i2c_get_clientdata(client);
1022         struct v4l2_pix_format *pix;
1023         int HPSC, HFSC;
1024         int VSCY, Vsrc;
1025         int is_50hz = state->std & V4L2_STD_625_50;
1026
1027         if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1028                 saa7115_set_lcr(client, &fmt->fmt.sliced);
1029                 return 0;
1030         }
1031         if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1032                 return -EINVAL;
1033
1034         pix = &(fmt->fmt.pix);
1035
1036         v4l_dbg(1, debug, client, "decoder set size\n");
1037
1038         /* FIXME need better bounds checking here */
1039         if ((pix->width < 1) || (pix->width > 1440))
1040                 return -EINVAL;
1041         if ((pix->height < 1) || (pix->height > 960))
1042                 return -EINVAL;
1043
1044         /* probably have a valid size, let's set it */
1045         /* Set output width/height */
1046         /* width */
1047         saa7115_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
1048                                 (u8) (pix->width & 0xff));
1049         saa7115_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
1050                                 (u8) ((pix->width >> 8) & 0xff));
1051         /* height */
1052         saa7115_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
1053                                 (u8) (pix->height & 0xff));
1054         saa7115_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
1055                                 (u8) ((pix->height >> 8) & 0xff));
1056
1057         /* Scaling settings */
1058         /* Hprescaler is floor(inres/outres) */
1059         /* FIXME hardcoding input res */
1060         if (pix->width != 720) {
1061                 HPSC = (int)(720 / pix->width);
1062                 /* 0 is not allowed (div. by zero) */
1063                 HPSC = HPSC ? HPSC : 1;
1064                 HFSC = (int)((1024 * 720) / (HPSC * pix->width));
1065
1066                 v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
1067                 /* FIXME hardcodes to "Task B"
1068                  * write H prescaler integer */
1069                 saa7115_write(client, R_D0_B_HORIZ_PRESCALING,
1070                                         (u8) (HPSC & 0x3f));
1071
1072                 /* write H fine-scaling (luminance) */
1073                 saa7115_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC,
1074                                         (u8) (HFSC & 0xff));
1075                 saa7115_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
1076                                         (u8) ((HFSC >> 8) & 0xff));
1077                 /* write H fine-scaling (chrominance)
1078                  * must be lum/2, so i'll just bitshift :) */
1079                 saa7115_write(client, R_DC_B_HORIZ_CHROMA_SCALING,
1080                                         (u8) ((HFSC >> 1) & 0xff));
1081                 saa7115_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
1082                                         (u8) ((HFSC >> 9) & 0xff));
1083         } else {
1084                 if (is_50hz) {
1085                         v4l_dbg(1, debug, client, "Setting full 50hz width\n");
1086                         saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x);
1087                 } else {
1088                         v4l_dbg(1, debug, client, "Setting full 60hz width\n");
1089                         saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
1090                 }
1091         }
1092
1093         Vsrc = is_50hz ? 576 : 480;
1094
1095         if (pix->height != Vsrc) {
1096                 VSCY = (int)((1024 * Vsrc) / pix->height);
1097                 v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
1098
1099                 /* Correct Contrast and Luminance */
1100                 saa7115_write(client, R_D5_B_LUMA_CONTRAST_CNTL,
1101                                         (u8) (64 * 1024 / VSCY));
1102                 saa7115_write(client, R_D6_B_CHROMA_SATURATION_CNTL,
1103                                         (u8) (64 * 1024 / VSCY));
1104
1105                 /* write V fine-scaling (luminance) */
1106                 saa7115_write(client, R_E0_B_VERT_LUMA_SCALING_INC,
1107                                         (u8) (VSCY & 0xff));
1108                 saa7115_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
1109                                         (u8) ((VSCY >> 8) & 0xff));
1110                 /* write V fine-scaling (chrominance) */
1111                 saa7115_write(client, R_E2_B_VERT_CHROMA_SCALING_INC,
1112                                         (u8) (VSCY & 0xff));
1113                 saa7115_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
1114                                         (u8) ((VSCY >> 8) & 0xff));
1115         } else {
1116                 if (is_50hz) {
1117                         v4l_dbg(1, debug, client, "Setting full 50Hz height\n");
1118                         saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y);
1119                 } else {
1120                         v4l_dbg(1, debug, client, "Setting full 60hz height\n");
1121                         saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
1122                 }
1123         }
1124
1125         saa7115_writeregs(client, saa7115_cfg_reset_scaler);
1126         return 0;
1127 }
1128
1129 /* Decode the sliced VBI data stream as created by the saa7115.
1130    The format is described in the saa7115 datasheet in Tables 25 and 26
1131    and in Figure 33.
1132    The current implementation uses SAV/EAV codes and not the ancillary data
1133    headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1134    code. */
1135 static void saa7115_decode_vbi_line(struct i2c_client *client,
1136                                     struct v4l2_decode_vbi_line *vbi)
1137 {
1138         static const char vbi_no_data_pattern[] = {
1139                 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1140         };
1141         struct saa7115_state *state = i2c_get_clientdata(client);
1142         u8 *p = vbi->p;
1143         u32 wss;
1144         int id1, id2;   /* the ID1 and ID2 bytes from the internal header */
1145
1146         vbi->type = 0;  /* mark result as a failure */
1147         id1 = p[2];
1148         id2 = p[3];
1149         /* Note: the field bit is inverted for 60 Hz video */
1150         if (state->std & V4L2_STD_525_60)
1151                 id1 ^= 0x40;
1152
1153         /* Skip internal header, p now points to the start of the payload */
1154         p += 4;
1155         vbi->p = p;
1156
1157         /* calculate field and line number of the VBI packet (1-23) */
1158         vbi->is_second_field = ((id1 & 0x40) != 0);
1159         vbi->line = (id1 & 0x3f) << 3;
1160         vbi->line |= (id2 & 0x70) >> 4;
1161
1162         /* Obtain data type */
1163         id2 &= 0xf;
1164
1165         /* If the VBI slicer does not detect any signal it will fill up
1166            the payload buffer with 0xa0 bytes. */
1167         if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
1168                 return;
1169
1170         /* decode payloads */
1171         switch (id2) {
1172         case 1:
1173                 vbi->type = V4L2_SLICED_TELETEXT_B;
1174                 break;
1175         case 4:
1176                 if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1]))
1177                         return;
1178                 vbi->type = V4L2_SLICED_CAPTION_525;
1179                 break;
1180         case 5:
1181                 wss = saa7115_decode_wss(p);
1182                 if (wss == -1)
1183                         return;
1184                 p[0] = wss & 0xff;
1185                 p[1] = wss >> 8;
1186                 vbi->type = V4L2_SLICED_WSS_625;
1187                 break;
1188         case 7:
1189                 if (saa7115_decode_vps(p, p) != 0)
1190                         return;
1191                 vbi->type = V4L2_SLICED_VPS;
1192                 break;
1193         default:
1194                 return;
1195         }
1196 }
1197
1198 /* ============ SAA7115 AUDIO settings (end) ============= */
1199
1200 static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg)
1201 {
1202         struct saa7115_state *state = i2c_get_clientdata(client);
1203         int *iarg = arg;
1204
1205         /* ioctls to allow direct access to the saa7115 registers for testing */
1206         switch (cmd) {
1207         case VIDIOC_S_FMT:
1208                 return saa7115_set_v4lfmt(client, (struct v4l2_format *)arg);
1209
1210         case VIDIOC_G_FMT:
1211                 return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg);
1212
1213         case VIDIOC_INT_AUDIO_CLOCK_FREQ:
1214                 return saa7115_set_audio_clock_freq(client, *(u32 *)arg);
1215
1216         case VIDIOC_G_TUNER:
1217         {
1218                 struct v4l2_tuner *vt = arg;
1219                 int status;
1220
1221                 if (state->radio)
1222                         break;
1223                 status = saa7115_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1224
1225                 v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
1226                 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1227                 break;
1228         }
1229
1230         case VIDIOC_LOG_STATUS:
1231                 saa7115_log_status(client);
1232                 break;
1233
1234         case VIDIOC_G_CTRL:
1235                 return saa7115_get_v4lctrl(client, (struct v4l2_control *)arg);
1236
1237         case VIDIOC_S_CTRL:
1238                 return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg);
1239
1240         case VIDIOC_QUERYCTRL:
1241         {
1242                 struct v4l2_queryctrl *qc = arg;
1243
1244                 switch (qc->id) {
1245                         case V4L2_CID_BRIGHTNESS:
1246                         case V4L2_CID_CONTRAST:
1247                         case V4L2_CID_SATURATION:
1248                         case V4L2_CID_HUE:
1249                                 return v4l2_ctrl_query_fill_std(qc);
1250                         default:
1251                                 return -EINVAL;
1252                 }
1253         }
1254
1255         case VIDIOC_G_STD:
1256                 *(v4l2_std_id *)arg = saa7115_get_v4lstd(client);
1257                 break;
1258
1259         case VIDIOC_S_STD:
1260                 state->radio = 0;
1261                 saa7115_set_v4lstd(client, *(v4l2_std_id *)arg);
1262                 break;
1263
1264         case AUDC_SET_RADIO:
1265                 state->radio = 1;
1266                 break;
1267
1268         case VIDIOC_INT_G_VIDEO_ROUTING:
1269         {
1270                 struct v4l2_routing *route = arg;
1271
1272                 route->input = state->input;
1273                 route->output = 0;
1274                 break;
1275         }
1276
1277         case VIDIOC_INT_S_VIDEO_ROUTING:
1278         {
1279                 struct v4l2_routing *route = arg;
1280
1281                 v4l_dbg(1, debug, client, "decoder set input %d\n", route->input);
1282                 /* saa7113 does not have these inputs */
1283                 if (state->ident == V4L2_IDENT_SAA7113 &&
1284                     (route->input == SAA7115_COMPOSITE4 ||
1285                      route->input == SAA7115_COMPOSITE5)) {
1286                         return -EINVAL;
1287                 }
1288                 if (route->input > SAA7115_SVIDEO3)
1289                         return -EINVAL;
1290                 if (state->input == route->input)
1291                         break;
1292                 v4l_dbg(1, debug, client, "now setting %s input\n",
1293                         (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite");
1294                 state->input = route->input;
1295
1296                 /* select mode */
1297                 saa7115_write(client, R_02_INPUT_CNTL_1,
1298                               (saa7115_read(client, R_02_INPUT_CNTL_1) & 0xf0) |
1299                                state->input);
1300
1301                 /* bypass chrominance trap for S-Video modes */
1302                 saa7115_write(client, R_09_LUMA_CNTL,
1303                               (saa7115_read(client, R_09_LUMA_CNTL) & 0x7f) |
1304                                (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1305                 break;
1306         }
1307
1308         case VIDIOC_STREAMON:
1309         case VIDIOC_STREAMOFF:
1310                 v4l_dbg(1, debug, client, "%s output\n",
1311                         (cmd == VIDIOC_STREAMON) ? "enable" : "disable");
1312
1313                 if (state->enable != (cmd == VIDIOC_STREAMON)) {
1314                         state->enable = (cmd == VIDIOC_STREAMON);
1315                         saa7115_write(client,
1316                                 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
1317                                 state->enable);
1318                 }
1319                 break;
1320
1321         case VIDIOC_INT_S_CRYSTAL_FREQ:
1322         {
1323                 struct v4l2_crystal_freq *freq = arg;
1324
1325                 if (freq->freq != SAA7115_FREQ_32_11_MHZ &&
1326                     freq->freq != SAA7115_FREQ_24_576_MHZ)
1327                         return -EINVAL;
1328                 state->crystal_freq = freq->freq;
1329                 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1330                 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1331                 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1332                 saa7115_set_audio_clock_freq(client, state->audclk_freq);
1333                 break;
1334         }
1335
1336         case VIDIOC_INT_DECODE_VBI_LINE:
1337                 saa7115_decode_vbi_line(client, arg);
1338                 break;
1339
1340         case VIDIOC_INT_RESET:
1341                 v4l_dbg(1, debug, client, "decoder RESET\n");
1342                 saa7115_writeregs(client, saa7115_cfg_reset_scaler);
1343                 break;
1344
1345         case VIDIOC_INT_G_VBI_DATA:
1346         {
1347                 struct v4l2_sliced_vbi_data *data = arg;
1348
1349                 switch (data->id) {
1350                 case V4L2_SLICED_WSS_625:
1351                         if (saa7115_read(client, 0x6b) & 0xc0)
1352                                 return -EIO;
1353                         data->data[0] = saa7115_read(client, 0x6c);
1354                         data->data[1] = saa7115_read(client, 0x6d);
1355                         return 0;
1356                 case V4L2_SLICED_CAPTION_525:
1357                         if (data->field == 0) {
1358                                 /* CC */
1359                                 if (saa7115_read(client, 0x66) & 0xc0)
1360                                         return -EIO;
1361                                 data->data[0] = saa7115_read(client, 0x67);
1362                                 data->data[1] = saa7115_read(client, 0x68);
1363                                 return 0;
1364                         }
1365                         /* XDS */
1366                         if (saa7115_read(client, 0x66) & 0x30)
1367                                 return -EIO;
1368                         data->data[0] = saa7115_read(client, 0x69);
1369                         data->data[1] = saa7115_read(client, 0x6a);
1370                         return 0;
1371                 default:
1372                         return -EINVAL;
1373                 }
1374                 break;
1375         }
1376
1377 #ifdef CONFIG_VIDEO_ADV_DEBUG
1378         case VIDIOC_INT_G_REGISTER:
1379         {
1380                 struct v4l2_register *reg = arg;
1381
1382                 if (reg->i2c_id != I2C_DRIVERID_SAA711X)
1383                         return -EINVAL;
1384                 reg->val = saa7115_read(client, reg->reg & 0xff);
1385                 break;
1386         }
1387
1388         case VIDIOC_INT_S_REGISTER:
1389         {
1390                 struct v4l2_register *reg = arg;
1391
1392                 if (reg->i2c_id != I2C_DRIVERID_SAA711X)
1393                         return -EINVAL;
1394                 if (!capable(CAP_SYS_ADMIN))
1395                         return -EPERM;
1396                 saa7115_write(client, reg->reg & 0xff, reg->val & 0xff);
1397                 break;
1398         }
1399 #endif
1400
1401         case VIDIOC_INT_G_CHIP_IDENT:
1402                 *iarg = state->ident;
1403                 break;
1404
1405         default:
1406                 return -EINVAL;
1407         }
1408
1409         return 0;
1410 }
1411
1412 /* ----------------------------------------------------------------------- */
1413
1414 static struct i2c_driver i2c_driver_saa7115;
1415
1416 static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1417 {
1418         struct i2c_client *client;
1419         struct saa7115_state *state;
1420         int     i;
1421         char    name[17];
1422         u8 chip_id;
1423
1424         /* Check if the adapter supports the needed features */
1425         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1426                 return 0;
1427
1428         client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
1429         if (client == 0)
1430                 return -ENOMEM;
1431         client->addr = address;
1432         client->adapter = adapter;
1433         client->driver = &i2c_driver_saa7115;
1434         snprintf(client->name, sizeof(client->name) - 1, "saa7115");
1435
1436         v4l_dbg(1, debug, client, "detecting saa7115 client on address 0x%x\n", address << 1);
1437
1438         for (i=0;i<0x0f;i++) {
1439                 saa7115_write(client, 0, i);
1440                 name[i] = (saa7115_read(client, 0) &0x0f) +'0';
1441                 if (name[i]>'9')
1442                         name[i]+='a'-'9'-1;
1443         }
1444         name[i]='\0';
1445
1446         saa7115_write(client, 0, 5);
1447         chip_id = saa7115_read(client, 0) & 0x0f;
1448         if (chip_id < 3 && chip_id > 5) {
1449                 v4l_dbg(1, debug, client, "saa7115 not found\n");
1450                 kfree(client);
1451                 return 0;
1452         }
1453         snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id);
1454         v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, address << 1, adapter->name);
1455
1456         state = kzalloc(sizeof(struct saa7115_state), GFP_KERNEL);
1457         i2c_set_clientdata(client, state);
1458         if (state == NULL) {
1459                 kfree(client);
1460                 return -ENOMEM;
1461         }
1462         state->std = V4L2_STD_NTSC;
1463         state->input = -1;
1464         state->enable = 1;
1465         state->radio = 0;
1466         state->bright = 128;
1467         state->contrast = 64;
1468         state->hue = 0;
1469         state->sat = 64;
1470         switch (chip_id) {
1471         case 3:
1472                 state->ident = V4L2_IDENT_SAA7113;
1473                 break;
1474         case 4:
1475                 state->ident = V4L2_IDENT_SAA7114;
1476                 break;
1477         default:
1478                 state->ident = V4L2_IDENT_SAA7115;
1479                 break;
1480         }
1481
1482         state->audclk_freq = 48000;
1483
1484         v4l_dbg(1, debug, client, "writing init values\n");
1485
1486         /* init to 60hz/48khz */
1487         if (state->ident == V4L2_IDENT_SAA7113) {
1488                 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1489                 saa7115_writeregs(client, saa7113_init_auto_input);
1490         } else {
1491                 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1492                 saa7115_writeregs(client, saa7115_init_auto_input);
1493         }
1494         saa7115_writeregs(client, saa7115_init_misc);
1495         saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
1496         saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
1497         saa7115_writeregs(client, saa7115_cfg_60hz_video);
1498         saa7115_set_audio_clock_freq(client, state->audclk_freq);
1499         saa7115_writeregs(client, saa7115_cfg_reset_scaler);
1500
1501         i2c_attach_client(client);
1502
1503         v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1504                 saa7115_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa7115_read(client, R_1F_STATUS_BYTE_2_VD_DEC));
1505
1506         return 0;
1507 }
1508
1509 static int saa7115_probe(struct i2c_adapter *adapter)
1510 {
1511         if (adapter->class & I2C_CLASS_TV_ANALOG)
1512                 return i2c_probe(adapter, &addr_data, &saa7115_attach);
1513         return 0;
1514 }
1515
1516 static int saa7115_detach(struct i2c_client *client)
1517 {
1518         struct saa7115_state *state = i2c_get_clientdata(client);
1519         int err;
1520
1521         err = i2c_detach_client(client);
1522         if (err) {
1523                 return err;
1524         }
1525
1526         kfree(state);
1527         kfree(client);
1528         return 0;
1529 }
1530
1531 /* ----------------------------------------------------------------------- */
1532
1533 /* i2c implementation */
1534 static struct i2c_driver i2c_driver_saa7115 = {
1535         .driver = {
1536                 .name = "saa7115",
1537         },
1538         .id = I2C_DRIVERID_SAA711X,
1539         .attach_adapter = saa7115_probe,
1540         .detach_client = saa7115_detach,
1541         .command = saa7115_command,
1542 };
1543
1544
1545 static int __init saa7115_init_module(void)
1546 {
1547         return i2c_add_driver(&i2c_driver_saa7115);
1548 }
1549
1550 static void __exit saa7115_cleanup_module(void)
1551 {
1552         i2c_del_driver(&i2c_driver_saa7115);
1553 }
1554
1555 module_init(saa7115_init_module);
1556 module_exit(saa7115_cleanup_module);