added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / drivers / media / video / saa7115.c
blob46c796c3fec887010d1da38810fdeac0d1ef2158
1 /* saa711x - Philips SAA711x video decoder driver
2 * This driver can work with saa7111, saa7111a, saa7113, saa7114,
3 * saa7115 and saa7118.
5 * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
6 * the saa7111 driver by Dave Perks.
8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
11 * Slight changes for video timing and attachment output by
12 * Wolfgang Scherr <scherr@net4you.net>
14 * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
15 * by Ronald Bultje <rbultje@ronald.bitfreak.net>
17 * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
18 * (2/17/2003)
20 * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
22 * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
23 * SAA7111, SAA7113 and SAA7118 support
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version 2
28 * of the License, or (at your option) any later version.
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
40 #include "saa711x_regs.h"
42 #include <linux/kernel.h>
43 #include <linux/module.h>
44 #include <linux/slab.h>
45 #include <linux/i2c.h>
46 #include <linux/videodev2.h>
47 #include <media/v4l2-device.h>
48 #include <media/v4l2-chip-ident.h>
49 #include <media/v4l2-i2c-drv-legacy.h>
50 #include <media/saa7115.h>
51 #include <asm/div64.h>
53 #define VRES_60HZ (480+16)
55 MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
56 MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
57 "Hans Verkuil, Mauro Carvalho Chehab");
58 MODULE_LICENSE("GPL");
60 static int debug;
61 module_param(debug, bool, 0644);
63 MODULE_PARM_DESC(debug, "Debug level (0-1)");
65 static unsigned short normal_i2c[] = {
66 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
67 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
68 I2C_CLIENT_END };
70 I2C_CLIENT_INSMOD;
72 struct saa711x_state {
73 struct v4l2_subdev sd;
74 v4l2_std_id std;
75 int input;
76 int output;
77 int enable;
78 int radio;
79 int bright;
80 int contrast;
81 int hue;
82 int sat;
83 int width;
84 int height;
85 u32 ident;
86 u32 audclk_freq;
87 u32 crystal_freq;
88 u8 ucgc;
89 u8 cgcdiv;
90 u8 apll;
93 static inline struct saa711x_state *to_state(struct v4l2_subdev *sd)
95 return container_of(sd, struct saa711x_state, sd);
98 /* ----------------------------------------------------------------------- */
100 static inline int saa711x_write(struct v4l2_subdev *sd, u8 reg, u8 value)
102 struct i2c_client *client = v4l2_get_subdevdata(sd);
104 return i2c_smbus_write_byte_data(client, reg, value);
107 /* Sanity routine to check if a register is present */
108 static int saa711x_has_reg(const int id, const u8 reg)
110 if (id == V4L2_IDENT_SAA7111)
111 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
112 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
114 /* common for saa7113/4/5/8 */
115 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
116 reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
117 reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
118 reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
119 return 0;
121 switch (id) {
122 case V4L2_IDENT_SAA7113:
123 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
124 reg != 0x5d && reg < 0x63;
125 case V4L2_IDENT_SAA7114:
126 return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
127 (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
128 reg != 0x81 && reg < 0xf0;
129 case V4L2_IDENT_SAA7115:
130 return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
131 case V4L2_IDENT_SAA7118:
132 return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
133 (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
134 (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
136 return 1;
139 static int saa711x_writeregs(struct v4l2_subdev *sd, const unsigned char *regs)
141 struct saa711x_state *state = to_state(sd);
142 unsigned char reg, data;
144 while (*regs != 0x00) {
145 reg = *(regs++);
146 data = *(regs++);
148 /* According with datasheets, reserved regs should be
149 filled with 0 - seems better not to touch on they */
150 if (saa711x_has_reg(state->ident, reg)) {
151 if (saa711x_write(sd, reg, data) < 0)
152 return -1;
153 } else {
154 v4l2_dbg(1, debug, sd, "tried to access reserved reg 0x%02x\n", reg);
157 return 0;
160 static inline int saa711x_read(struct v4l2_subdev *sd, u8 reg)
162 struct i2c_client *client = v4l2_get_subdevdata(sd);
164 return i2c_smbus_read_byte_data(client, reg);
167 /* ----------------------------------------------------------------------- */
169 /* SAA7111 initialization table */
170 static const unsigned char saa7111_init[] = {
171 R_01_INC_DELAY, 0x00, /* reserved */
173 /*front end */
174 R_02_INPUT_CNTL_1, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */
175 R_03_INPUT_CNTL_2, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
176 * GAFIX=0, GAI1=256, GAI2=256 */
177 R_04_INPUT_CNTL_3, 0x00, /* GAI1=256 */
178 R_05_INPUT_CNTL_4, 0x00, /* GAI2=256 */
180 /* decoder */
181 R_06_H_SYNC_START, 0xf3, /* HSB at 13(50Hz) / 17(60Hz)
182 * pixels after end of last line */
183 R_07_H_SYNC_STOP, 0xe8, /* HSS seems to be needed to
184 * work with NTSC, too */
185 R_08_SYNC_CNTL, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0,
186 * VTRC=1, HPLL=0, VNOI=0 */
187 R_09_LUMA_CNTL, 0x01, /* BYPS=0, PREF=0, BPSS=0,
188 * VBLB=0, UPTCV=0, APER=1 */
189 R_0A_LUMA_BRIGHT_CNTL, 0x80,
190 R_0B_LUMA_CONTRAST_CNTL, 0x47, /* 0b - CONT=1.109 */
191 R_0C_CHROMA_SAT_CNTL, 0x40,
192 R_0D_CHROMA_HUE_CNTL, 0x00,
193 R_0E_CHROMA_CNTL_1, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
194 * FCTC=0, CHBW=1 */
195 R_0F_CHROMA_GAIN_CNTL, 0x00, /* reserved */
196 R_10_CHROMA_CNTL_2, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
197 R_11_MODE_DELAY_CNTL, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
198 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
199 R_12_RT_SIGNAL_CNTL, 0x00, /* 12 - output control 2 */
200 R_13_RT_X_PORT_OUT_CNTL, 0x00, /* 13 - output control 3 */
201 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
202 R_15_VGATE_START_FID_CHG, 0x00,
203 R_16_VGATE_STOP, 0x00,
204 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
206 0x00, 0x00
209 /* SAA7113 init codes */
210 static const unsigned char saa7113_init[] = {
211 R_01_INC_DELAY, 0x08,
212 R_02_INPUT_CNTL_1, 0xc2,
213 R_03_INPUT_CNTL_2, 0x30,
214 R_04_INPUT_CNTL_3, 0x00,
215 R_05_INPUT_CNTL_4, 0x00,
216 R_06_H_SYNC_START, 0x89,
217 R_07_H_SYNC_STOP, 0x0d,
218 R_08_SYNC_CNTL, 0x88,
219 R_09_LUMA_CNTL, 0x01,
220 R_0A_LUMA_BRIGHT_CNTL, 0x80,
221 R_0B_LUMA_CONTRAST_CNTL, 0x47,
222 R_0C_CHROMA_SAT_CNTL, 0x40,
223 R_0D_CHROMA_HUE_CNTL, 0x00,
224 R_0E_CHROMA_CNTL_1, 0x01,
225 R_0F_CHROMA_GAIN_CNTL, 0x2a,
226 R_10_CHROMA_CNTL_2, 0x08,
227 R_11_MODE_DELAY_CNTL, 0x0c,
228 R_12_RT_SIGNAL_CNTL, 0x07,
229 R_13_RT_X_PORT_OUT_CNTL, 0x00,
230 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
231 R_15_VGATE_START_FID_CHG, 0x00,
232 R_16_VGATE_STOP, 0x00,
233 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
235 0x00, 0x00
238 /* If a value differs from the Hauppauge driver values, then the comment starts with
239 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
240 Hauppauge driver sets. */
242 /* SAA7114 and SAA7115 initialization table */
243 static const unsigned char saa7115_init_auto_input[] = {
244 /* Front-End Part */
245 R_01_INC_DELAY, 0x48, /* white peak control disabled */
246 R_03_INPUT_CNTL_2, 0x20, /* was 0x30. 0x20: long vertical blanking */
247 R_04_INPUT_CNTL_3, 0x90, /* analog gain set to 0 */
248 R_05_INPUT_CNTL_4, 0x90, /* analog gain set to 0 */
249 /* Decoder Part */
250 R_06_H_SYNC_START, 0xeb, /* horiz sync begin = -21 */
251 R_07_H_SYNC_STOP, 0xe0, /* horiz sync stop = -17 */
252 R_09_LUMA_CNTL, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
253 R_0A_LUMA_BRIGHT_CNTL, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
254 R_0B_LUMA_CONTRAST_CNTL, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
255 R_0C_CHROMA_SAT_CNTL, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
256 R_0D_CHROMA_HUE_CNTL, 0x00,
257 R_0F_CHROMA_GAIN_CNTL, 0x00, /* use automatic gain */
258 R_10_CHROMA_CNTL_2, 0x06, /* chroma: active adaptive combfilter */
259 R_11_MODE_DELAY_CNTL, 0x00,
260 R_12_RT_SIGNAL_CNTL, 0x9d, /* RTS0 output control: VGATE */
261 R_13_RT_X_PORT_OUT_CNTL, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */
262 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
263 R_18_RAW_DATA_GAIN_CNTL, 0x40, /* gain 0x00 = nominal */
264 R_19_RAW_DATA_OFF_CNTL, 0x80,
265 R_1A_COLOR_KILL_LVL_CNTL, 0x77, /* recommended value */
266 R_1B_MISC_TVVCRDET, 0x42, /* recommended value */
267 R_1C_ENHAN_COMB_CTRL1, 0xa9, /* recommended value */
268 R_1D_ENHAN_COMB_CTRL2, 0x01, /* recommended value */
271 R_80_GLOBAL_CNTL_1, 0x0, /* No tasks enabled at init */
273 /* Power Device Control */
274 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset device */
275 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* set device programmed, all in operational mode */
276 0x00, 0x00
279 /* Used to reset saa7113, saa7114 and saa7115 */
280 static const unsigned char saa7115_cfg_reset_scaler[] = {
281 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00, /* disable I-port output */
282 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
283 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
284 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* enable I-port output */
285 0x00, 0x00
288 /* ============== SAA7715 VIDEO templates ============= */
290 static const unsigned char saa7115_cfg_60hz_video[] = {
291 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
292 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
294 R_15_VGATE_START_FID_CHG, 0x03,
295 R_16_VGATE_STOP, 0x11,
296 R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
298 R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
299 R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */
301 R_5A_V_OFF_FOR_SLICER, 0x06, /* standard 60hz value for ITU656 line counting */
303 /* Task A */
304 R_90_A_TASK_HANDLING_CNTL, 0x80,
305 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
306 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
307 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
309 /* hoffset low (input), 0x0002 is minimum */
310 R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
311 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
313 /* hsize low (input), 0x02d0 = 720 */
314 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
315 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
317 R_98_A_VERT_INPUT_WINDOW_START, 0x05,
318 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
320 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
321 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
323 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
324 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
326 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
327 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
329 /* Task B */
330 R_C0_B_TASK_HANDLING_CNTL, 0x00,
331 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
332 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
333 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
335 /* 0x0002 is minimum */
336 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
337 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
339 /* 0x02d0 = 720 */
340 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
341 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
343 /* vwindow start 0x12 = 18 */
344 R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
345 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
347 /* vwindow length 0xf8 = 248 */
348 R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
349 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
351 /* hwindow 0x02d0 = 720 */
352 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
353 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
355 R_F0_LFCO_PER_LINE, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
356 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0 */
357 R_F5_PULSGEN_LINE_LENGTH, 0xad,
358 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
360 0x00, 0x00
363 static const unsigned char saa7115_cfg_50hz_video[] = {
364 R_80_GLOBAL_CNTL_1, 0x00,
365 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
367 R_15_VGATE_START_FID_CHG, 0x37, /* VGATE start */
368 R_16_VGATE_STOP, 0x16,
369 R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
371 R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */
372 R_0E_CHROMA_CNTL_1, 0x07,
374 R_5A_V_OFF_FOR_SLICER, 0x03, /* standard 50hz value */
376 /* Task A */
377 R_90_A_TASK_HANDLING_CNTL, 0x81,
378 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
379 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
380 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
382 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
383 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
384 /* hoffset low (input), 0x0002 is minimum */
385 R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
386 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
388 /* hsize low (input), 0x02d0 = 720 */
389 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
390 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
392 R_98_A_VERT_INPUT_WINDOW_START, 0x03,
393 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
395 /* vsize 0x12 = 18 */
396 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
397 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
399 /* hsize 0x05a0 = 1440 */
400 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
401 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05, /* hsize hi (output) */
402 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12, /* vsize low (output), 0x12 = 18 */
403 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00, /* vsize hi (output) */
405 /* Task B */
406 R_C0_B_TASK_HANDLING_CNTL, 0x00,
407 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
408 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
409 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
411 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
412 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
413 /* hoffset low (input), 0x0002 is minimum. See comment above. */
414 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
415 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
417 /* hsize 0x02d0 = 720 */
418 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
419 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
421 /* voffset 0x16 = 22 */
422 R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
423 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
425 /* vsize 0x0120 = 288 */
426 R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
427 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
429 /* hsize 0x02d0 = 720 */
430 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
431 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
433 R_F0_LFCO_PER_LINE, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
434 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0, (was 0x05) */
435 R_F5_PULSGEN_LINE_LENGTH, 0xb0,
436 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
438 0x00, 0x00
441 /* ============== SAA7715 VIDEO templates (end) ======= */
443 static const unsigned char saa7115_cfg_vbi_on[] = {
444 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
445 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
446 R_80_GLOBAL_CNTL_1, 0x30, /* Activate both tasks */
447 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
448 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
450 0x00, 0x00
453 static const unsigned char saa7115_cfg_vbi_off[] = {
454 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
455 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
456 R_80_GLOBAL_CNTL_1, 0x20, /* Activate only task "B" */
457 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
458 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
460 0x00, 0x00
464 static const unsigned char saa7115_init_misc[] = {
465 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
466 R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
467 R_84_I_PORT_SIGNAL_DEF, 0x20,
468 R_85_I_PORT_SIGNAL_POLAR, 0x21,
469 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
470 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
472 /* Task A */
473 R_A0_A_HORIZ_PRESCALING, 0x01,
474 R_A1_A_ACCUMULATION_LENGTH, 0x00,
475 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
477 /* Configure controls at nominal value*/
478 R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
479 R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
480 R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
482 /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
483 R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
484 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
486 R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
488 /* must be horiz lum scaling / 2 */
489 R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
490 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
492 /* must be offset luma / 2 */
493 R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
495 R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
496 R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
498 R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
499 R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
501 R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
503 R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
504 R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
505 R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
506 R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
508 R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
509 R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
510 R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
511 R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
513 /* Task B */
514 R_D0_B_HORIZ_PRESCALING, 0x01,
515 R_D1_B_ACCUMULATION_LENGTH, 0x00,
516 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
518 /* Configure controls at nominal value*/
519 R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
520 R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
521 R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
523 /* hor lum scaling 0x0400 = 1 */
524 R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
525 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
527 R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
529 /* must be hor lum scaling / 2 */
530 R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
531 R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
533 /* must be offset luma / 2 */
534 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
536 R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
537 R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
539 R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
540 R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
542 R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
544 R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
545 R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
546 R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
547 R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
549 R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
550 R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
551 R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
552 R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
554 R_F2_NOMINAL_PLL2_DTO, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
555 R_F3_PLL_INCREMENT, 0x46,
556 R_F4_PLL2_STATUS, 0x00,
557 R_F7_PULSE_A_POS_MSB, 0x4b, /* not the recommended settings! */
558 R_F8_PULSE_B_POS, 0x00,
559 R_F9_PULSE_B_POS_MSB, 0x4b,
560 R_FA_PULSE_C_POS, 0x00,
561 R_FB_PULSE_C_POS_MSB, 0x4b,
563 /* PLL2 lock detection settings: 71 lines 50% phase error */
564 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
566 /* Turn off VBI */
567 R_40_SLICER_CNTL_1, 0x20, /* No framing code errors allowed. */
568 R_41_LCR_BASE, 0xff,
569 R_41_LCR_BASE+1, 0xff,
570 R_41_LCR_BASE+2, 0xff,
571 R_41_LCR_BASE+3, 0xff,
572 R_41_LCR_BASE+4, 0xff,
573 R_41_LCR_BASE+5, 0xff,
574 R_41_LCR_BASE+6, 0xff,
575 R_41_LCR_BASE+7, 0xff,
576 R_41_LCR_BASE+8, 0xff,
577 R_41_LCR_BASE+9, 0xff,
578 R_41_LCR_BASE+10, 0xff,
579 R_41_LCR_BASE+11, 0xff,
580 R_41_LCR_BASE+12, 0xff,
581 R_41_LCR_BASE+13, 0xff,
582 R_41_LCR_BASE+14, 0xff,
583 R_41_LCR_BASE+15, 0xff,
584 R_41_LCR_BASE+16, 0xff,
585 R_41_LCR_BASE+17, 0xff,
586 R_41_LCR_BASE+18, 0xff,
587 R_41_LCR_BASE+19, 0xff,
588 R_41_LCR_BASE+20, 0xff,
589 R_41_LCR_BASE+21, 0xff,
590 R_41_LCR_BASE+22, 0xff,
591 R_58_PROGRAM_FRAMING_CODE, 0x40,
592 R_59_H_OFF_FOR_SLICER, 0x47,
593 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
594 R_5D_DID, 0xbd,
595 R_5E_SDID, 0x35,
597 R_02_INPUT_CNTL_1, 0x84, /* input tuner -> input 4, amplifier active */
599 R_80_GLOBAL_CNTL_1, 0x20, /* enable task B */
600 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
601 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
602 0x00, 0x00
605 static int saa711x_odd_parity(u8 c)
607 c ^= (c >> 4);
608 c ^= (c >> 2);
609 c ^= (c >> 1);
611 return c & 1;
614 static int saa711x_decode_vps(u8 *dst, u8 *p)
616 static const u8 biphase_tbl[] = {
617 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
618 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
619 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
620 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
621 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
622 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
623 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
624 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
625 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
626 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
627 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
628 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
629 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
630 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
631 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
632 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
633 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
634 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
635 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
636 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
637 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
638 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
639 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
640 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
641 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
642 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
643 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
644 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
645 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
646 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
647 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
648 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
650 int i;
651 u8 c, err = 0;
653 for (i = 0; i < 2 * 13; i += 2) {
654 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
655 c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
656 dst[i / 2] = c;
658 return err & 0xf0;
661 static int saa711x_decode_wss(u8 *p)
663 static const int wss_bits[8] = {
664 0, 0, 0, 1, 0, 1, 1, 1
666 unsigned char parity;
667 int wss = 0;
668 int i;
670 for (i = 0; i < 16; i++) {
671 int b1 = wss_bits[p[i] & 7];
672 int b2 = wss_bits[(p[i] >> 3) & 7];
674 if (b1 == b2)
675 return -1;
676 wss |= b2 << i;
678 parity = wss & 15;
679 parity ^= parity >> 2;
680 parity ^= parity >> 1;
682 if (!(parity & 1))
683 return -1;
685 return wss;
688 static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
690 struct saa711x_state *state = to_state(sd);
691 u32 acpf;
692 u32 acni;
693 u32 hz;
694 u64 f;
695 u8 acc = 0; /* reg 0x3a, audio clock control */
697 /* Checks for chips that don't have audio clock (saa7111, saa7113) */
698 if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
699 return 0;
701 v4l2_dbg(1, debug, sd, "set audio clock freq: %d\n", freq);
703 /* sanity check */
704 if (freq < 32000 || freq > 48000)
705 return -EINVAL;
707 /* hz is the refresh rate times 100 */
708 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
709 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
710 acpf = (25600 * freq) / hz;
711 /* acni = (256 * freq * 2^23) / crystal_frequency =
712 (freq * 2^(8+23)) / crystal_frequency =
713 (freq << 31) / crystal_frequency */
714 f = freq;
715 f = f << 31;
716 do_div(f, state->crystal_freq);
717 acni = f;
718 if (state->ucgc) {
719 acpf = acpf * state->cgcdiv / 16;
720 acni = acni * state->cgcdiv / 16;
721 acc = 0x80;
722 if (state->cgcdiv == 3)
723 acc |= 0x40;
725 if (state->apll)
726 acc |= 0x08;
728 saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
729 saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
730 saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
732 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
733 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
734 (acpf >> 8) & 0xff);
735 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
736 (acpf >> 16) & 0x03);
738 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
739 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
740 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
741 state->audclk_freq = freq;
742 return 0;
745 static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
747 struct saa711x_state *state = to_state(sd);
749 switch (ctrl->id) {
750 case V4L2_CID_BRIGHTNESS:
751 if (ctrl->value < 0 || ctrl->value > 255) {
752 v4l2_err(sd, "invalid brightness setting %d\n", ctrl->value);
753 return -ERANGE;
756 state->bright = ctrl->value;
757 saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, state->bright);
758 break;
760 case V4L2_CID_CONTRAST:
761 if (ctrl->value < 0 || ctrl->value > 127) {
762 v4l2_err(sd, "invalid contrast setting %d\n", ctrl->value);
763 return -ERANGE;
766 state->contrast = ctrl->value;
767 saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, state->contrast);
768 break;
770 case V4L2_CID_SATURATION:
771 if (ctrl->value < 0 || ctrl->value > 127) {
772 v4l2_err(sd, "invalid saturation setting %d\n", ctrl->value);
773 return -ERANGE;
776 state->sat = ctrl->value;
777 saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, state->sat);
778 break;
780 case V4L2_CID_HUE:
781 if (ctrl->value < -127 || ctrl->value > 127) {
782 v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
783 return -ERANGE;
786 state->hue = ctrl->value;
787 saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, state->hue);
788 break;
790 default:
791 return -EINVAL;
794 return 0;
797 static int saa711x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
799 struct saa711x_state *state = to_state(sd);
801 switch (ctrl->id) {
802 case V4L2_CID_BRIGHTNESS:
803 ctrl->value = state->bright;
804 break;
805 case V4L2_CID_CONTRAST:
806 ctrl->value = state->contrast;
807 break;
808 case V4L2_CID_SATURATION:
809 ctrl->value = state->sat;
810 break;
811 case V4L2_CID_HUE:
812 ctrl->value = state->hue;
813 break;
814 default:
815 return -EINVAL;
818 return 0;
821 static int saa711x_set_size(struct v4l2_subdev *sd, int width, int height)
823 struct saa711x_state *state = to_state(sd);
824 int HPSC, HFSC;
825 int VSCY;
826 int res;
827 int is_50hz = state->std & V4L2_STD_625_50;
828 int Vsrc = is_50hz ? 576 : 480;
830 v4l2_dbg(1, debug, sd, "decoder set size to %ix%i\n", width, height);
832 /* FIXME need better bounds checking here */
833 if ((width < 1) || (width > 1440))
834 return -EINVAL;
835 if ((height < 1) || (height > Vsrc))
836 return -EINVAL;
838 if (!saa711x_has_reg(state->ident, R_D0_B_HORIZ_PRESCALING)) {
839 /* Decoder only supports 720 columns and 480 or 576 lines */
840 if (width != 720)
841 return -EINVAL;
842 if (height != Vsrc)
843 return -EINVAL;
846 state->width = width;
847 state->height = height;
849 if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
850 return 0;
852 /* probably have a valid size, let's set it */
853 /* Set output width/height */
854 /* width */
856 saa711x_write(sd, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
857 (u8) (width & 0xff));
858 saa711x_write(sd, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
859 (u8) ((width >> 8) & 0xff));
861 /* Vertical Scaling uses height/2 */
862 res = height / 2;
864 /* On 60Hz, it is using a higher Vertical Output Size */
865 if (!is_50hz)
866 res += (VRES_60HZ - 480) >> 1;
868 /* height */
869 saa711x_write(sd, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
870 (u8) (res & 0xff));
871 saa711x_write(sd, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
872 (u8) ((res >> 8) & 0xff));
874 /* Scaling settings */
875 /* Hprescaler is floor(inres/outres) */
876 HPSC = (int)(720 / width);
877 /* 0 is not allowed (div. by zero) */
878 HPSC = HPSC ? HPSC : 1;
879 HFSC = (int)((1024 * 720) / (HPSC * width));
880 /* FIXME hardcodes to "Task B"
881 * write H prescaler integer */
882 saa711x_write(sd, R_D0_B_HORIZ_PRESCALING,
883 (u8) (HPSC & 0x3f));
885 v4l2_dbg(1, debug, sd, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
886 /* write H fine-scaling (luminance) */
887 saa711x_write(sd, R_D8_B_HORIZ_LUMA_SCALING_INC,
888 (u8) (HFSC & 0xff));
889 saa711x_write(sd, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
890 (u8) ((HFSC >> 8) & 0xff));
891 /* write H fine-scaling (chrominance)
892 * must be lum/2, so i'll just bitshift :) */
893 saa711x_write(sd, R_DC_B_HORIZ_CHROMA_SCALING,
894 (u8) ((HFSC >> 1) & 0xff));
895 saa711x_write(sd, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
896 (u8) ((HFSC >> 9) & 0xff));
898 VSCY = (int)((1024 * Vsrc) / height);
899 v4l2_dbg(1, debug, sd, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
901 /* Correct Contrast and Luminance */
902 saa711x_write(sd, R_D5_B_LUMA_CONTRAST_CNTL,
903 (u8) (64 * 1024 / VSCY));
904 saa711x_write(sd, R_D6_B_CHROMA_SATURATION_CNTL,
905 (u8) (64 * 1024 / VSCY));
907 /* write V fine-scaling (luminance) */
908 saa711x_write(sd, R_E0_B_VERT_LUMA_SCALING_INC,
909 (u8) (VSCY & 0xff));
910 saa711x_write(sd, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
911 (u8) ((VSCY >> 8) & 0xff));
912 /* write V fine-scaling (chrominance) */
913 saa711x_write(sd, R_E2_B_VERT_CHROMA_SCALING_INC,
914 (u8) (VSCY & 0xff));
915 saa711x_write(sd, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
916 (u8) ((VSCY >> 8) & 0xff));
918 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
920 /* Activates task "B" */
921 saa711x_write(sd, R_80_GLOBAL_CNTL_1,
922 saa711x_read(sd, R_80_GLOBAL_CNTL_1) | 0x20);
924 return 0;
927 static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
929 struct saa711x_state *state = to_state(sd);
931 /* Prevent unnecessary standard changes. During a standard
932 change the I-Port is temporarily disabled. Any devices
933 reading from that port can get confused.
934 Note that VIDIOC_S_STD is also used to switch from
935 radio to TV mode, so if a VIDIOC_S_STD is broadcast to
936 all I2C devices then you do not want to have an unwanted
937 side-effect here. */
938 if (std == state->std)
939 return;
941 state->std = std;
943 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
944 if (std & V4L2_STD_525_60) {
945 v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
946 saa711x_writeregs(sd, saa7115_cfg_60hz_video);
947 saa711x_set_size(sd, 720, 480);
948 } else {
949 v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
950 saa711x_writeregs(sd, saa7115_cfg_50hz_video);
951 saa711x_set_size(sd, 720, 576);
954 /* Register 0E - Bits D6-D4 on NO-AUTO mode
955 (SAA7111 and SAA7113 doesn't have auto mode)
956 50 Hz / 625 lines 60 Hz / 525 lines
957 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz)
958 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz)
959 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
960 011 NTSC N (3.58MHz) PAL M (3.58MHz)
961 100 reserved NTSC-Japan (3.58MHz)
963 if (state->ident == V4L2_IDENT_SAA7111 ||
964 state->ident == V4L2_IDENT_SAA7113) {
965 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
967 if (std == V4L2_STD_PAL_M) {
968 reg |= 0x30;
969 } else if (std == V4L2_STD_PAL_Nc) {
970 reg |= 0x20;
971 } else if (std == V4L2_STD_PAL_60) {
972 reg |= 0x10;
973 } else if (std == V4L2_STD_NTSC_M_JP) {
974 reg |= 0x40;
975 } else if (std & V4L2_STD_SECAM) {
976 reg |= 0x50;
978 saa711x_write(sd, R_0E_CHROMA_CNTL_1, reg);
979 } else {
980 /* restart task B if needed */
981 int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
983 if (taskb && state->ident == V4L2_IDENT_SAA7114) {
984 saa711x_writeregs(sd, saa7115_cfg_vbi_on);
987 /* switch audio mode too! */
988 saa711x_s_clock_freq(sd, state->audclk_freq);
992 /* setup the sliced VBI lcr registers according to the sliced VBI format */
993 static void saa711x_set_lcr(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
995 struct saa711x_state *state = to_state(sd);
996 int is_50hz = (state->std & V4L2_STD_625_50);
997 u8 lcr[24];
998 int i, x;
1000 #if 1
1001 /* saa7113/7114/7118 VBI support are experimental */
1002 if (!saa711x_has_reg(state->ident, R_41_LCR_BASE))
1003 return;
1005 #else
1006 /* SAA7113 and SAA7118 also should support VBI - Need testing */
1007 if (state->ident != V4L2_IDENT_SAA7115)
1008 return;
1009 #endif
1011 for (i = 0; i <= 23; i++)
1012 lcr[i] = 0xff;
1014 if (fmt == NULL) {
1015 /* raw VBI */
1016 if (is_50hz)
1017 for (i = 6; i <= 23; i++)
1018 lcr[i] = 0xdd;
1019 else
1020 for (i = 10; i <= 21; i++)
1021 lcr[i] = 0xdd;
1022 } else {
1023 /* sliced VBI */
1024 /* first clear lines that cannot be captured */
1025 if (is_50hz) {
1026 for (i = 0; i <= 5; i++)
1027 fmt->service_lines[0][i] =
1028 fmt->service_lines[1][i] = 0;
1030 else {
1031 for (i = 0; i <= 9; i++)
1032 fmt->service_lines[0][i] =
1033 fmt->service_lines[1][i] = 0;
1034 for (i = 22; i <= 23; i++)
1035 fmt->service_lines[0][i] =
1036 fmt->service_lines[1][i] = 0;
1039 /* Now set the lcr values according to the specified service */
1040 for (i = 6; i <= 23; i++) {
1041 lcr[i] = 0;
1042 for (x = 0; x <= 1; x++) {
1043 switch (fmt->service_lines[1-x][i]) {
1044 case 0:
1045 lcr[i] |= 0xf << (4 * x);
1046 break;
1047 case V4L2_SLICED_TELETEXT_B:
1048 lcr[i] |= 1 << (4 * x);
1049 break;
1050 case V4L2_SLICED_CAPTION_525:
1051 lcr[i] |= 4 << (4 * x);
1052 break;
1053 case V4L2_SLICED_WSS_625:
1054 lcr[i] |= 5 << (4 * x);
1055 break;
1056 case V4L2_SLICED_VPS:
1057 lcr[i] |= 7 << (4 * x);
1058 break;
1064 /* write the lcr registers */
1065 for (i = 2; i <= 23; i++) {
1066 saa711x_write(sd, i - 2 + R_41_LCR_BASE, lcr[i]);
1069 /* enable/disable raw VBI capturing */
1070 saa711x_writeregs(sd, fmt == NULL ?
1071 saa7115_cfg_vbi_on :
1072 saa7115_cfg_vbi_off);
1075 static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1077 static u16 lcr2vbi[] = {
1078 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
1079 0, V4L2_SLICED_CAPTION_525, /* 4 */
1080 V4L2_SLICED_WSS_625, 0, /* 5 */
1081 V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */
1082 0, 0, 0, 0
1084 struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;
1085 int i;
1087 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
1088 return -EINVAL;
1089 memset(sliced, 0, sizeof(*sliced));
1090 /* done if using raw VBI */
1091 if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
1092 return 0;
1093 for (i = 2; i <= 23; i++) {
1094 u8 v = saa711x_read(sd, i - 2 + R_41_LCR_BASE);
1096 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
1097 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
1098 sliced->service_set |=
1099 sliced->service_lines[0][i] | sliced->service_lines[1][i];
1101 return 0;
1104 static int saa711x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1106 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1107 saa711x_set_lcr(sd, &fmt->fmt.sliced);
1108 return 0;
1110 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1111 saa711x_set_lcr(sd, NULL);
1112 return 0;
1114 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1115 return -EINVAL;
1117 return saa711x_set_size(sd, fmt->fmt.pix.width, fmt->fmt.pix.height);
1120 /* Decode the sliced VBI data stream as created by the saa7115.
1121 The format is described in the saa7115 datasheet in Tables 25 and 26
1122 and in Figure 33.
1123 The current implementation uses SAV/EAV codes and not the ancillary data
1124 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1125 code. */
1126 static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
1128 struct saa711x_state *state = to_state(sd);
1129 static const char vbi_no_data_pattern[] = {
1130 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1132 u8 *p = vbi->p;
1133 u32 wss;
1134 int id1, id2; /* the ID1 and ID2 bytes from the internal header */
1136 vbi->type = 0; /* mark result as a failure */
1137 id1 = p[2];
1138 id2 = p[3];
1139 /* Note: the field bit is inverted for 60 Hz video */
1140 if (state->std & V4L2_STD_525_60)
1141 id1 ^= 0x40;
1143 /* Skip internal header, p now points to the start of the payload */
1144 p += 4;
1145 vbi->p = p;
1147 /* calculate field and line number of the VBI packet (1-23) */
1148 vbi->is_second_field = ((id1 & 0x40) != 0);
1149 vbi->line = (id1 & 0x3f) << 3;
1150 vbi->line |= (id2 & 0x70) >> 4;
1152 /* Obtain data type */
1153 id2 &= 0xf;
1155 /* If the VBI slicer does not detect any signal it will fill up
1156 the payload buffer with 0xa0 bytes. */
1157 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
1158 return 0;
1160 /* decode payloads */
1161 switch (id2) {
1162 case 1:
1163 vbi->type = V4L2_SLICED_TELETEXT_B;
1164 break;
1165 case 4:
1166 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1167 return 0;
1168 vbi->type = V4L2_SLICED_CAPTION_525;
1169 break;
1170 case 5:
1171 wss = saa711x_decode_wss(p);
1172 if (wss == -1)
1173 return 0;
1174 p[0] = wss & 0xff;
1175 p[1] = wss >> 8;
1176 vbi->type = V4L2_SLICED_WSS_625;
1177 break;
1178 case 7:
1179 if (saa711x_decode_vps(p, p) != 0)
1180 return 0;
1181 vbi->type = V4L2_SLICED_VPS;
1182 break;
1183 default:
1184 break;
1186 return 0;
1189 /* ============ SAA7115 AUDIO settings (end) ============= */
1191 static int saa711x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1193 struct saa711x_state *state = to_state(sd);
1194 int status;
1196 if (state->radio)
1197 return 0;
1198 status = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1200 v4l2_dbg(1, debug, sd, "status: 0x%02x\n", status);
1201 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1202 return 0;
1205 static int saa711x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1207 switch (qc->id) {
1208 case V4L2_CID_BRIGHTNESS:
1209 case V4L2_CID_CONTRAST:
1210 case V4L2_CID_SATURATION:
1211 case V4L2_CID_HUE:
1212 return v4l2_ctrl_query_fill_std(qc);
1213 default:
1214 return -EINVAL;
1218 static int saa711x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1220 struct saa711x_state *state = to_state(sd);
1222 state->radio = 0;
1223 saa711x_set_v4lstd(sd, std);
1224 return 0;
1227 static int saa711x_s_radio(struct v4l2_subdev *sd)
1229 struct saa711x_state *state = to_state(sd);
1231 state->radio = 1;
1232 return 0;
1235 static int saa711x_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1237 struct saa711x_state *state = to_state(sd);
1238 u32 input = route->input;
1239 u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0;
1241 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n", route->input, route->output);
1242 /* saa7111/3 does not have these inputs */
1243 if ((state->ident == V4L2_IDENT_SAA7113 ||
1244 state->ident == V4L2_IDENT_SAA7111) &&
1245 (route->input == SAA7115_COMPOSITE4 ||
1246 route->input == SAA7115_COMPOSITE5)) {
1247 return -EINVAL;
1249 if (route->input > SAA7115_SVIDEO3)
1250 return -EINVAL;
1251 if (route->output > SAA7115_IPORT_ON)
1252 return -EINVAL;
1253 if (state->input == route->input && state->output == route->output)
1254 return 0;
1255 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
1256 (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
1257 (route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
1258 state->input = route->input;
1260 /* saa7111 has slightly different input numbering */
1261 if (state->ident == V4L2_IDENT_SAA7111) {
1262 if (input >= SAA7115_COMPOSITE4)
1263 input -= 2;
1264 /* saa7111 specific */
1265 saa711x_write(sd, R_10_CHROMA_CNTL_2,
1266 (saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
1267 ((route->output & 0xc0) ^ 0x40));
1268 saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
1269 (saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
1270 ((route->output & 2) ? 0x0a : 0));
1273 /* select mode */
1274 saa711x_write(sd, R_02_INPUT_CNTL_1,
1275 (saa711x_read(sd, R_02_INPUT_CNTL_1) & mask) |
1276 input);
1278 /* bypass chrominance trap for S-Video modes */
1279 saa711x_write(sd, R_09_LUMA_CNTL,
1280 (saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
1281 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1283 state->output = route->output;
1284 if (state->ident == V4L2_IDENT_SAA7114 ||
1285 state->ident == V4L2_IDENT_SAA7115) {
1286 saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
1287 (saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
1288 (state->output & 0x01));
1290 return 0;
1293 static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
1295 struct saa711x_state *state = to_state(sd);
1297 if (state->ident != V4L2_IDENT_SAA7111)
1298 return -EINVAL;
1299 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
1300 (val ? 0x80 : 0));
1301 return 0;
1304 static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
1306 struct saa711x_state *state = to_state(sd);
1308 v4l2_dbg(1, debug, sd, "%s output\n",
1309 enable ? "enable" : "disable");
1311 if (state->enable != enable) {
1312 state->enable = enable;
1313 saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
1314 state->enable);
1316 return 0;
1319 static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, struct v4l2_crystal_freq *freq)
1321 struct saa711x_state *state = to_state(sd);
1323 if (freq->freq != SAA7115_FREQ_32_11_MHZ &&
1324 freq->freq != SAA7115_FREQ_24_576_MHZ)
1325 return -EINVAL;
1326 state->crystal_freq = freq->freq;
1327 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1328 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1329 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1330 saa711x_s_clock_freq(sd, state->audclk_freq);
1331 return 0;
1334 static int saa711x_reset(struct v4l2_subdev *sd, u32 val)
1336 v4l2_dbg(1, debug, sd, "decoder RESET\n");
1337 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
1338 return 0;
1341 static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *data)
1343 /* Note: the internal field ID is inverted for NTSC,
1344 so data->field 0 maps to the saa7115 even field,
1345 whereas for PAL it maps to the saa7115 odd field. */
1346 switch (data->id) {
1347 case V4L2_SLICED_WSS_625:
1348 if (saa711x_read(sd, 0x6b) & 0xc0)
1349 return -EIO;
1350 data->data[0] = saa711x_read(sd, 0x6c);
1351 data->data[1] = saa711x_read(sd, 0x6d);
1352 return 0;
1353 case V4L2_SLICED_CAPTION_525:
1354 if (data->field == 0) {
1355 /* CC */
1356 if (saa711x_read(sd, 0x66) & 0x30)
1357 return -EIO;
1358 data->data[0] = saa711x_read(sd, 0x69);
1359 data->data[1] = saa711x_read(sd, 0x6a);
1360 return 0;
1362 /* XDS */
1363 if (saa711x_read(sd, 0x66) & 0xc0)
1364 return -EIO;
1365 data->data[0] = saa711x_read(sd, 0x67);
1366 data->data[1] = saa711x_read(sd, 0x68);
1367 return 0;
1368 default:
1369 return -EINVAL;
1373 #ifdef CONFIG_VIDEO_ADV_DEBUG
1374 static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
1376 struct i2c_client *client = v4l2_get_subdevdata(sd);
1378 if (!v4l2_chip_match_i2c_client(client, &reg->match))
1379 return -EINVAL;
1380 if (!capable(CAP_SYS_ADMIN))
1381 return -EPERM;
1382 reg->val = saa711x_read(sd, reg->reg & 0xff);
1383 reg->size = 1;
1384 return 0;
1387 static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
1389 struct i2c_client *client = v4l2_get_subdevdata(sd);
1391 if (!v4l2_chip_match_i2c_client(client, &reg->match))
1392 return -EINVAL;
1393 if (!capable(CAP_SYS_ADMIN))
1394 return -EPERM;
1395 saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
1396 return 0;
1398 #endif
1400 static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
1402 struct saa711x_state *state = to_state(sd);
1403 struct i2c_client *client = v4l2_get_subdevdata(sd);
1405 return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
1408 static int saa711x_log_status(struct v4l2_subdev *sd)
1410 struct saa711x_state *state = to_state(sd);
1411 int reg1e, reg1f;
1412 int signalOk;
1413 int vcr;
1415 v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
1416 if (state->ident != V4L2_IDENT_SAA7115) {
1417 /* status for the saa7114 */
1418 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1419 signalOk = (reg1f & 0xc1) == 0x81;
1420 v4l2_info(sd, "Video signal: %s\n", signalOk ? "ok" : "bad");
1421 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1422 return 0;
1425 /* status for the saa7115 */
1426 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1427 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1429 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1430 vcr = !(reg1f & 0x10);
1432 if (state->input >= 6)
1433 v4l2_info(sd, "Input: S-Video %d\n", state->input - 6);
1434 else
1435 v4l2_info(sd, "Input: Composite %d\n", state->input);
1436 v4l2_info(sd, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1437 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1439 switch (reg1e & 0x03) {
1440 case 1:
1441 v4l2_info(sd, "Detected format: NTSC\n");
1442 break;
1443 case 2:
1444 v4l2_info(sd, "Detected format: PAL\n");
1445 break;
1446 case 3:
1447 v4l2_info(sd, "Detected format: SECAM\n");
1448 break;
1449 default:
1450 v4l2_info(sd, "Detected format: BW/No color\n");
1451 break;
1453 v4l2_info(sd, "Width, Height: %d, %d\n", state->width, state->height);
1454 return 0;
1457 static int saa711x_command(struct i2c_client *client, unsigned cmd, void *arg)
1459 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
1462 /* ----------------------------------------------------------------------- */
1464 static const struct v4l2_subdev_core_ops saa711x_core_ops = {
1465 .log_status = saa711x_log_status,
1466 .g_chip_ident = saa711x_g_chip_ident,
1467 .g_ctrl = saa711x_g_ctrl,
1468 .s_ctrl = saa711x_s_ctrl,
1469 .queryctrl = saa711x_queryctrl,
1470 .reset = saa711x_reset,
1471 .s_gpio = saa711x_s_gpio,
1472 #ifdef CONFIG_VIDEO_ADV_DEBUG
1473 .g_register = saa711x_g_register,
1474 .s_register = saa711x_s_register,
1475 #endif
1478 static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops = {
1479 .s_std = saa711x_s_std,
1480 .s_radio = saa711x_s_radio,
1481 .g_tuner = saa711x_g_tuner,
1484 static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
1485 .s_clock_freq = saa711x_s_clock_freq,
1488 static const struct v4l2_subdev_video_ops saa711x_video_ops = {
1489 .s_routing = saa711x_s_routing,
1490 .s_crystal_freq = saa711x_s_crystal_freq,
1491 .g_fmt = saa711x_g_fmt,
1492 .s_fmt = saa711x_s_fmt,
1493 .g_vbi_data = saa711x_g_vbi_data,
1494 .decode_vbi_line = saa711x_decode_vbi_line,
1495 .s_stream = saa711x_s_stream,
1498 static const struct v4l2_subdev_ops saa711x_ops = {
1499 .core = &saa711x_core_ops,
1500 .tuner = &saa711x_tuner_ops,
1501 .audio = &saa711x_audio_ops,
1502 .video = &saa711x_video_ops,
1505 /* ----------------------------------------------------------------------- */
1507 static int saa711x_probe(struct i2c_client *client,
1508 const struct i2c_device_id *id)
1510 struct saa711x_state *state;
1511 struct v4l2_subdev *sd;
1512 int i;
1513 char name[17];
1514 char chip_id;
1515 int autodetect = !id || id->driver_data == 1;
1517 /* Check if the adapter supports the needed features */
1518 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1519 return -EIO;
1521 for (i = 0; i < 0x0f; i++) {
1522 i2c_smbus_write_byte_data(client, 0, i);
1523 name[i] = (i2c_smbus_read_byte_data(client, 0) & 0x0f) + '0';
1524 if (name[i] > '9')
1525 name[i] += 'a' - '9' - 1;
1527 name[i] = '\0';
1529 chip_id = name[5];
1531 /* Check whether this chip is part of the saa711x series */
1532 if (memcmp(name, "1f711", 5)) {
1533 v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
1534 client->addr << 1, name);
1535 return -ENODEV;
1538 /* Safety check */
1539 if (!autodetect && id->name[6] != chip_id) {
1540 v4l_warn(client, "found saa711%c while %s was expected\n",
1541 chip_id, id->name);
1543 snprintf(client->name, sizeof(client->name), "saa711%c", chip_id);
1544 v4l_info(client, "saa711%c found (%s) @ 0x%x (%s)\n", chip_id, name,
1545 client->addr << 1, client->adapter->name);
1547 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
1548 if (state == NULL)
1549 return -ENOMEM;
1550 sd = &state->sd;
1551 v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
1552 state->input = -1;
1553 state->output = SAA7115_IPORT_ON;
1554 state->enable = 1;
1555 state->radio = 0;
1556 state->bright = 128;
1557 state->contrast = 64;
1558 state->hue = 0;
1559 state->sat = 64;
1560 switch (chip_id) {
1561 case '1':
1562 state->ident = V4L2_IDENT_SAA7111;
1563 break;
1564 case '3':
1565 state->ident = V4L2_IDENT_SAA7113;
1566 break;
1567 case '4':
1568 state->ident = V4L2_IDENT_SAA7114;
1569 break;
1570 case '5':
1571 state->ident = V4L2_IDENT_SAA7115;
1572 break;
1573 case '8':
1574 state->ident = V4L2_IDENT_SAA7118;
1575 break;
1576 default:
1577 state->ident = V4L2_IDENT_SAA7111;
1578 v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
1582 state->audclk_freq = 48000;
1584 v4l2_dbg(1, debug, sd, "writing init values\n");
1586 /* init to 60hz/48khz */
1587 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1588 switch (state->ident) {
1589 case V4L2_IDENT_SAA7111:
1590 saa711x_writeregs(sd, saa7111_init);
1591 break;
1592 case V4L2_IDENT_SAA7113:
1593 saa711x_writeregs(sd, saa7113_init);
1594 break;
1595 default:
1596 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1597 saa711x_writeregs(sd, saa7115_init_auto_input);
1599 if (state->ident != V4L2_IDENT_SAA7111)
1600 saa711x_writeregs(sd, saa7115_init_misc);
1601 saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
1603 v4l2_dbg(1, debug, sd, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1604 saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC),
1605 saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC));
1606 return 0;
1609 /* ----------------------------------------------------------------------- */
1611 static int saa711x_remove(struct i2c_client *client)
1613 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1615 v4l2_device_unregister_subdev(sd);
1616 kfree(to_state(sd));
1617 return 0;
1620 static const struct i2c_device_id saa7115_id[] = {
1621 { "saa7115_auto", 1 }, /* autodetect */
1622 { "saa7111", 0 },
1623 { "saa7113", 0 },
1624 { "saa7114", 0 },
1625 { "saa7115", 0 },
1626 { "saa7118", 0 },
1629 MODULE_DEVICE_TABLE(i2c, saa7115_id);
1631 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1632 .name = "saa7115",
1633 .driverid = I2C_DRIVERID_SAA711X,
1634 .command = saa711x_command,
1635 .probe = saa711x_probe,
1636 .remove = saa711x_remove,
1637 .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
1638 .id_table = saa7115_id,