1 /* saa711x - Philips SAA711x video decoder driver
2 * This driver can work with saa7111, saa7111a, saa7113, saa7114,
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>
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-common.h>
48 #include <media/saa7115.h>
49 #include <asm/div64.h>
51 MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
52 MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
53 "Hans Verkuil, Mauro Carvalho Chehab");
54 MODULE_LICENSE("GPL");
57 module_param(debug
, bool, 0644);
59 MODULE_PARM_DESC(debug
, "Debug level (0-1)");
61 static unsigned short normal_i2c
[] = {
62 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
63 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
69 struct saa711x_state
{
78 enum v4l2_chip_ident ident
;
86 /* ----------------------------------------------------------------------- */
88 static inline int saa711x_write(struct i2c_client
*client
, u8 reg
, u8 value
)
90 return i2c_smbus_write_byte_data(client
, reg
, value
);
93 /* Sanity routine to check if a register is present */
94 static int saa711x_has_reg(const int id
, const u8 reg
)
97 case V4L2_IDENT_SAA7111
:
98 if (reg
>0x1f || reg
==1 || reg
==0x0f || reg
==0x14 || reg
==0x18
99 || reg
==0x19 || reg
==0x1d || reg
==0x1e)
101 case V4L2_IDENT_SAA7113
:
102 if (reg
>0x62 || reg
==0x14 || (reg
>=0x18 && reg
<=0x1e) ||
103 (reg
>=0x20 && reg
<=0x3f) ||reg
==0x5f )
105 case V4L2_IDENT_SAA7114
:
106 if (reg
>=0xf0 || (reg
>=0x1a && reg
<=0x1e) ||
107 (reg
>=0x20 && reg
<=0x2f) ||
108 (reg
>=0x63 && reg
<=0x7f) )
110 case V4L2_IDENT_SAA7115
:
111 if ((reg
>=0x20 && reg
<=0x2f) || (reg
==0x5c) ||
112 (reg
>=0xfc && reg
<=0xfe) )
114 case V4L2_IDENT_SAA7118
:
115 if (reg
>=0xf0 || (reg
>=0x1a && reg
<=0x1d) ||
116 (reg
>=0x63 && reg
<=0x6f) )
120 /* Those registers are reserved for all family */
121 if (unlikely((reg
>=0x20 && reg
<=0x22) ||
122 (reg
>=0x26 && reg
<=0x28) ||
123 (reg
>=0x3b && reg
<=0x3f) || (reg
==0x5f) ||
124 (reg
>=0x63 && reg
<=0x6f) ) )
130 static int saa711x_writeregs(struct i2c_client
*client
, const unsigned char *regs
)
132 struct saa711x_state
*state
= i2c_get_clientdata(client
);
133 unsigned char reg
, data
;
135 while (*regs
!= 0x00) {
139 /* According with datasheets, reserved regs should be
140 filled with 0 - seems better not to touch on they */
141 if (saa711x_has_reg(state
->ident
,reg
)) {
142 if (saa711x_write(client
, reg
, data
) < 0)
149 static inline int saa711x_read(struct i2c_client
*client
, u8 reg
)
151 return i2c_smbus_read_byte_data(client
, reg
);
154 /* ----------------------------------------------------------------------- */
156 /* SAA7111 initialization table */
157 static const unsigned char saa7111_init_auto_input
[] = {
158 R_01_INC_DELAY
, 0x00, /* reserved */
161 R_02_INPUT_CNTL_1
, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */
162 R_03_INPUT_CNTL_2
, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
163 * GAFIX=0, GAI1=256, GAI2=256 */
164 R_04_INPUT_CNTL_3
, 0x00, /* GAI1=256 */
165 R_05_INPUT_CNTL_4
, 0x00, /* GAI2=256 */
168 R_06_H_SYNC_START
, 0xf3, /* HSB at 13(50Hz) / 17(60Hz)
169 * pixels after end of last line */
170 R_07_H_SYNC_STOP
, 0xe8, /* HSS seems to be needed to
171 * work with NTSC, too */
172 R_08_SYNC_CNTL
, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0,
173 * VTRC=1, HPLL=0, VNOI=0 */
174 R_09_LUMA_CNTL
, 0x01, /* BYPS=0, PREF=0, BPSS=0,
175 * VBLB=0, UPTCV=0, APER=1 */
176 R_0A_LUMA_BRIGHT_CNTL
, 0x80,
177 R_0B_LUMA_CONTRAST_CNTL
, 0x47, /* 0b - CONT=1.109 */
178 R_0C_CHROMA_SAT_CNTL
, 0x40,
179 R_0D_CHROMA_HUE_CNTL
, 0x00,
180 R_0E_CHROMA_CNTL_1
, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
182 R_0F_CHROMA_GAIN_CNTL
, 0x00, /* reserved */
183 R_10_CHROMA_CNTL_2
, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
184 R_11_MODE_DELAY_CNTL
, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
185 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
186 R_12_RT_SIGNAL_CNTL
, 0x00, /* 12 - output control 2 */
187 R_13_RT_X_PORT_OUT_CNTL
, 0x00, /* 13 - output control 3 */
188 R_14_ANAL_ADC_COMPAT_CNTL
, 0x00,
189 R_15_VGATE_START_FID_CHG
, 0x00,
190 R_16_VGATE_STOP
, 0x00,
191 R_17_MISC_VGATE_CONF_AND_MSB
, 0x00,
196 /* SAA7113 init codes */
197 static const unsigned char saa7113_init_auto_input
[] = {
198 R_01_INC_DELAY
, 0x08,
199 R_02_INPUT_CNTL_1
, 0xc2,
200 R_03_INPUT_CNTL_2
, 0x30,
201 R_04_INPUT_CNTL_3
, 0x00,
202 R_05_INPUT_CNTL_4
, 0x00,
203 R_06_H_SYNC_START
, 0x89,
204 R_07_H_SYNC_STOP
, 0x0d,
205 R_08_SYNC_CNTL
, 0x88,
206 R_09_LUMA_CNTL
, 0x01,
207 R_0A_LUMA_BRIGHT_CNTL
, 0x80,
208 R_0B_LUMA_CONTRAST_CNTL
, 0x47,
209 R_0C_CHROMA_SAT_CNTL
, 0x40,
210 R_0D_CHROMA_HUE_CNTL
, 0x00,
211 R_0E_CHROMA_CNTL_1
, 0x01,
212 R_0F_CHROMA_GAIN_CNTL
, 0x2a,
213 R_10_CHROMA_CNTL_2
, 0x08,
214 R_11_MODE_DELAY_CNTL
, 0x0c,
215 R_12_RT_SIGNAL_CNTL
, 0x07,
216 R_13_RT_X_PORT_OUT_CNTL
, 0x00,
217 R_14_ANAL_ADC_COMPAT_CNTL
, 0x00,
218 R_15_VGATE_START_FID_CHG
, 0x00,
219 R_16_VGATE_STOP
, 0x00,
220 R_17_MISC_VGATE_CONF_AND_MSB
, 0x00,
225 /* If a value differs from the Hauppauge driver values, then the comment starts with
226 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
227 Hauppauge driver sets. */
229 /* SAA7114 and SAA7115 initialization table */
230 static const unsigned char saa7115_init_auto_input
[] = {
232 R_01_INC_DELAY
, 0x48, /* white peak control disabled */
233 R_03_INPUT_CNTL_2
, 0x20, /* was 0x30. 0x20: long vertical blanking */
234 R_04_INPUT_CNTL_3
, 0x90, /* analog gain set to 0 */
235 R_05_INPUT_CNTL_4
, 0x90, /* analog gain set to 0 */
237 R_06_H_SYNC_START
, 0xeb, /* horiz sync begin = -21 */
238 R_07_H_SYNC_STOP
, 0xe0, /* horiz sync stop = -17 */
239 R_0A_LUMA_BRIGHT_CNTL
, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
240 R_0B_LUMA_CONTRAST_CNTL
, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
241 R_0C_CHROMA_SAT_CNTL
, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
242 R_0D_CHROMA_HUE_CNTL
, 0x00,
243 R_0F_CHROMA_GAIN_CNTL
, 0x00, /* use automatic gain */
244 R_10_CHROMA_CNTL_2
, 0x06, /* chroma: active adaptive combfilter */
245 R_11_MODE_DELAY_CNTL
, 0x00,
246 R_12_RT_SIGNAL_CNTL
, 0x9d, /* RTS0 output control: VGATE */
247 R_13_RT_X_PORT_OUT_CNTL
, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */
248 R_14_ANAL_ADC_COMPAT_CNTL
, 0x00,
249 R_18_RAW_DATA_GAIN_CNTL
, 0x40, /* gain 0x00 = nominal */
250 R_19_RAW_DATA_OFF_CNTL
, 0x80,
251 R_1A_COLOR_KILL_LVL_CNTL
, 0x77, /* recommended value */
252 R_1B_MISC_TVVCRDET
, 0x42, /* recommended value */
253 R_1C_ENHAN_COMB_CTRL1
, 0xa9, /* recommended value */
254 R_1D_ENHAN_COMB_CTRL2
, 0x01, /* recommended value */
256 /* Power Device Control */
257 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset device */
258 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* set device programmed, all in operational mode */
262 /* Used to reset saa7113, saa7114 and saa7115 */
263 static const unsigned char saa7115_cfg_reset_scaler
[] = {
264 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x00, /* disable I-port output */
265 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
266 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
267 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* enable I-port output */
271 /* ============== SAA7715 VIDEO templates ============= */
273 static const unsigned char saa7115_cfg_60hz_video
[] = {
274 R_80_GLOBAL_CNTL_1
, 0x00, /* reset tasks */
275 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
277 R_15_VGATE_START_FID_CHG
, 0x03,
278 R_16_VGATE_STOP
, 0x11,
279 R_17_MISC_VGATE_CONF_AND_MSB
, 0x9c,
281 R_08_SYNC_CNTL
, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
282 R_0E_CHROMA_CNTL_1
, 0x07, /* video autodetection is on */
284 R_5A_V_OFF_FOR_SLICER
, 0x06, /* standard 60hz value for ITU656 line counting */
287 R_90_A_TASK_HANDLING_CNTL
, 0x80,
288 R_91_A_X_PORT_FORMATS_AND_CONF
, 0x48,
289 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL
, 0x40,
290 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF
, 0x84,
292 /* hoffset low (input), 0x0002 is minimum */
293 R_94_A_HORIZ_INPUT_WINDOW_START
, 0x01,
294 R_95_A_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
296 /* hsize low (input), 0x02d0 = 720 */
297 R_96_A_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
298 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
300 R_98_A_VERT_INPUT_WINDOW_START
, 0x05,
301 R_99_A_VERT_INPUT_WINDOW_START_MSB
, 0x00,
303 R_9A_A_VERT_INPUT_WINDOW_LENGTH
, 0x0c,
304 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB
, 0x00,
306 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xa0,
307 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x05,
309 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH
, 0x0c,
310 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB
, 0x00,
313 R_C0_B_TASK_HANDLING_CNTL
, 0x00,
314 R_C1_B_X_PORT_FORMATS_AND_CONF
, 0x08,
315 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION
, 0x00,
316 R_C3_B_I_PORT_FORMATS_AND_CONF
, 0x80,
318 /* 0x0002 is minimum */
319 R_C4_B_HORIZ_INPUT_WINDOW_START
, 0x02,
320 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
323 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
324 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
326 /* vwindow start 0x12 = 18 */
327 R_C8_B_VERT_INPUT_WINDOW_START
, 0x12,
328 R_C9_B_VERT_INPUT_WINDOW_START_MSB
, 0x00,
330 /* vwindow length 0xf8 = 248 */
331 R_CA_B_VERT_INPUT_WINDOW_LENGTH
, 0xf8,
332 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB
, 0x00,
334 /* hwindow 0x02d0 = 720 */
335 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xd0,
336 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x02,
338 R_F0_LFCO_PER_LINE
, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
339 R_F1_P_I_PARAM_SELECT
, 0x05, /* low bit with 0xF0 */
340 R_F5_PULSGEN_LINE_LENGTH
, 0xad,
341 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG
, 0x01,
343 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x00, /* Disable I-port output */
344 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
345 R_80_GLOBAL_CNTL_1
, 0x20, /* Activate only task "B", continuous mode (was 0xA0) */
346 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
347 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* Enable I-port output */
351 static const unsigned char saa7115_cfg_50hz_video
[] = {
352 R_80_GLOBAL_CNTL_1
, 0x00,
353 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
355 R_15_VGATE_START_FID_CHG
, 0x37, /* VGATE start */
356 R_16_VGATE_STOP
, 0x16,
357 R_17_MISC_VGATE_CONF_AND_MSB
, 0x99,
359 R_08_SYNC_CNTL
, 0x28, /* 0x28 = PAL */
360 R_0E_CHROMA_CNTL_1
, 0x07,
362 R_5A_V_OFF_FOR_SLICER
, 0x03, /* standard 50hz value */
365 R_90_A_TASK_HANDLING_CNTL
, 0x81,
366 R_91_A_X_PORT_FORMATS_AND_CONF
, 0x48,
367 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL
, 0x40,
368 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF
, 0x84,
370 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
371 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
372 /* hoffset low (input), 0x0002 is minimum */
373 R_94_A_HORIZ_INPUT_WINDOW_START
, 0x00,
374 R_95_A_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
376 /* hsize low (input), 0x02d0 = 720 */
377 R_96_A_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
378 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
380 R_98_A_VERT_INPUT_WINDOW_START
, 0x03,
381 R_99_A_VERT_INPUT_WINDOW_START_MSB
, 0x00,
383 /* vsize 0x12 = 18 */
384 R_9A_A_VERT_INPUT_WINDOW_LENGTH
, 0x12,
385 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB
, 0x00,
387 /* hsize 0x05a0 = 1440 */
388 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xa0,
389 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x05, /* hsize hi (output) */
390 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH
, 0x12, /* vsize low (output), 0x12 = 18 */
391 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB
, 0x00, /* vsize hi (output) */
394 R_C0_B_TASK_HANDLING_CNTL
, 0x00,
395 R_C1_B_X_PORT_FORMATS_AND_CONF
, 0x08,
396 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION
, 0x00,
397 R_C3_B_I_PORT_FORMATS_AND_CONF
, 0x80,
399 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
400 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
401 /* hoffset low (input), 0x0002 is minimum. See comment above. */
402 R_C4_B_HORIZ_INPUT_WINDOW_START
, 0x00,
403 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
405 /* hsize 0x02d0 = 720 */
406 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
407 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
409 /* voffset 0x16 = 22 */
410 R_C8_B_VERT_INPUT_WINDOW_START
, 0x16,
411 R_C9_B_VERT_INPUT_WINDOW_START_MSB
, 0x00,
413 /* vsize 0x0120 = 288 */
414 R_CA_B_VERT_INPUT_WINDOW_LENGTH
, 0x20,
415 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB
, 0x01,
417 /* hsize 0x02d0 = 720 */
418 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xd0,
419 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x02,
421 /* vsize 0x0120 = 288 */
422 R_CE_B_VERT_OUTPUT_WINDOW_LENGTH
, 0x20,
423 R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB
, 0x01,
425 R_F0_LFCO_PER_LINE
, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
426 R_F1_P_I_PARAM_SELECT
, 0x05, /* low bit with 0xF0, (was 0x05) */
427 R_F5_PULSGEN_LINE_LENGTH
, 0xb0,
428 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG
, 0x01,
430 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x00, /* Disable I-port output */
431 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler (was 0xD0) */
432 R_80_GLOBAL_CNTL_1
, 0x20, /* Activate only task "B" */
433 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
434 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* Enable I-port output */
439 /* ============== SAA7715 VIDEO templates (end) ======= */
441 static const unsigned char saa7115_cfg_vbi_on
[] = {
442 R_80_GLOBAL_CNTL_1
, 0x00, /* reset tasks */
443 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
444 R_80_GLOBAL_CNTL_1
, 0x30, /* Activate both tasks */
445 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
446 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* Enable I-port output */
451 static const unsigned char saa7115_cfg_vbi_off
[] = {
452 R_80_GLOBAL_CNTL_1
, 0x00, /* reset tasks */
453 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
454 R_80_GLOBAL_CNTL_1
, 0x20, /* Activate only task "B" */
455 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
456 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* Enable I-port output */
462 static const unsigned char saa7115_init_misc
[] = {
463 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F
, 0x01,
464 0x82, 0x00, /* Reserved register - value should be zero*/
465 R_83_X_PORT_I_O_ENA_AND_OUT_CLK
, 0x01,
466 R_84_I_PORT_SIGNAL_DEF
, 0x20,
467 R_85_I_PORT_SIGNAL_POLAR
, 0x21,
468 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT
, 0xc5,
469 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01,
472 R_A0_A_HORIZ_PRESCALING
, 0x01,
473 R_A1_A_ACCUMULATION_LENGTH
, 0x00,
474 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER
, 0x00,
476 /* Configure controls at nominal value*/
477 R_A4_A_LUMA_BRIGHTNESS_CNTL
, 0x80,
478 R_A5_A_LUMA_CONTRAST_CNTL
, 0x40,
479 R_A6_A_CHROMA_SATURATION_CNTL
, 0x40,
481 /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
482 R_A8_A_HORIZ_LUMA_SCALING_INC
, 0x00,
483 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB
, 0x02,
485 R_AA_A_HORIZ_LUMA_PHASE_OFF
, 0x00,
487 /* must be horiz lum scaling / 2 */
488 R_AC_A_HORIZ_CHROMA_SCALING_INC
, 0x00,
489 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB
, 0x01,
491 /* must be offset luma / 2 */
492 R_AE_A_HORIZ_CHROMA_PHASE_OFF
, 0x00,
494 R_B0_A_VERT_LUMA_SCALING_INC
, 0x00,
495 R_B1_A_VERT_LUMA_SCALING_INC_MSB
, 0x04,
497 R_B2_A_VERT_CHROMA_SCALING_INC
, 0x00,
498 R_B3_A_VERT_CHROMA_SCALING_INC_MSB
, 0x04,
500 R_B4_A_VERT_SCALING_MODE_CNTL
, 0x01,
502 R_B8_A_VERT_CHROMA_PHASE_OFF_00
, 0x00,
503 R_B9_A_VERT_CHROMA_PHASE_OFF_01
, 0x00,
504 R_BA_A_VERT_CHROMA_PHASE_OFF_10
, 0x00,
505 R_BB_A_VERT_CHROMA_PHASE_OFF_11
, 0x00,
507 R_BC_A_VERT_LUMA_PHASE_OFF_00
, 0x00,
508 R_BD_A_VERT_LUMA_PHASE_OFF_01
, 0x00,
509 R_BE_A_VERT_LUMA_PHASE_OFF_10
, 0x00,
510 R_BF_A_VERT_LUMA_PHASE_OFF_11
, 0x00,
513 R_D0_B_HORIZ_PRESCALING
, 0x01,
514 R_D1_B_ACCUMULATION_LENGTH
, 0x00,
515 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER
, 0x00,
517 /* Configure controls at nominal value*/
518 R_D4_B_LUMA_BRIGHTNESS_CNTL
, 0x80,
519 R_D5_B_LUMA_CONTRAST_CNTL
, 0x40,
520 R_D6_B_CHROMA_SATURATION_CNTL
, 0x40,
522 /* hor lum scaling 0x0400 = 1 */
523 R_D8_B_HORIZ_LUMA_SCALING_INC
, 0x00,
524 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB
, 0x04,
526 R_DA_B_HORIZ_LUMA_PHASE_OFF
, 0x00,
528 /* must be hor lum scaling / 2 */
529 R_DC_B_HORIZ_CHROMA_SCALING
, 0x00,
530 R_DD_B_HORIZ_CHROMA_SCALING_MSB
, 0x02,
532 /* must be offset luma / 2 */
533 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA
, 0x00,
535 R_E0_B_VERT_LUMA_SCALING_INC
, 0x00,
536 R_E1_B_VERT_LUMA_SCALING_INC_MSB
, 0x04,
538 R_E2_B_VERT_CHROMA_SCALING_INC
, 0x00,
539 R_E3_B_VERT_CHROMA_SCALING_INC_MSB
, 0x04,
541 R_E4_B_VERT_SCALING_MODE_CNTL
, 0x01,
543 R_E8_B_VERT_CHROMA_PHASE_OFF_00
, 0x00,
544 R_E9_B_VERT_CHROMA_PHASE_OFF_01
, 0x00,
545 R_EA_B_VERT_CHROMA_PHASE_OFF_10
, 0x00,
546 R_EB_B_VERT_CHROMA_PHASE_OFF_11
, 0x00,
548 R_EC_B_VERT_LUMA_PHASE_OFF_00
, 0x00,
549 R_ED_B_VERT_LUMA_PHASE_OFF_01
, 0x00,
550 R_EE_B_VERT_LUMA_PHASE_OFF_10
, 0x00,
551 R_EF_B_VERT_LUMA_PHASE_OFF_11
, 0x00,
553 R_F2_NOMINAL_PLL2_DTO
, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
554 R_F3_PLL_INCREMENT
, 0x46,
555 R_F4_PLL2_STATUS
, 0x00,
556 R_F7_PULSE_A_POS_MSB
, 0x4b, /* not the recommended settings! */
557 R_F8_PULSE_B_POS
, 0x00,
558 R_F9_PULSE_B_POS_MSB
, 0x4b,
559 R_FA_PULSE_C_POS
, 0x00,
560 R_FB_PULSE_C_POS_MSB
, 0x4b,
562 /* PLL2 lock detection settings: 71 lines 50% phase error */
563 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES
, 0x88,
566 R_40_SLICER_CNTL_1
, 0x20, /* No framing code errors allowed. */
568 R_41_LCR_BASE
+1, 0xff,
569 R_41_LCR_BASE
+2, 0xff,
570 R_41_LCR_BASE
+3, 0xff,
571 R_41_LCR_BASE
+4, 0xff,
572 R_41_LCR_BASE
+5, 0xff,
573 R_41_LCR_BASE
+6, 0xff,
574 R_41_LCR_BASE
+7, 0xff,
575 R_41_LCR_BASE
+8, 0xff,
576 R_41_LCR_BASE
+9, 0xff,
577 R_41_LCR_BASE
+10, 0xff,
578 R_41_LCR_BASE
+11, 0xff,
579 R_41_LCR_BASE
+12, 0xff,
580 R_41_LCR_BASE
+13, 0xff,
581 R_41_LCR_BASE
+14, 0xff,
582 R_41_LCR_BASE
+15, 0xff,
583 R_41_LCR_BASE
+16, 0xff,
584 R_41_LCR_BASE
+17, 0xff,
585 R_41_LCR_BASE
+18, 0xff,
586 R_41_LCR_BASE
+19, 0xff,
587 R_41_LCR_BASE
+20, 0xff,
588 R_41_LCR_BASE
+21, 0xff,
589 R_41_LCR_BASE
+22, 0xff,
590 R_58_PROGRAM_FRAMING_CODE
, 0x40,
591 R_59_H_OFF_FOR_SLICER
, 0x47,
592 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF
, 0x83,
596 R_02_INPUT_CNTL_1
, 0x84, /* input tuner -> input 4, amplifier active */
597 R_09_LUMA_CNTL
, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
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,
605 static int saa711x_odd_parity(u8 c
)
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,
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);
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
;
670 for (i
= 0; i
< 16; i
++) {
671 int b1
= wss_bits
[p
[i
] & 7];
672 int b2
= wss_bits
[(p
[i
] >> 3) & 7];
679 parity
^= parity
>> 2;
680 parity
^= parity
>> 1;
688 static int saa711x_set_audio_clock_freq(struct i2c_client
*client
, u32 freq
)
690 struct saa711x_state
*state
= i2c_get_clientdata(client
);
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
))
701 v4l_dbg(1, debug
, client
, "set audio clock freq: %d\n", freq
);
704 if (freq
< 32000 || freq
> 48000)
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 */
716 do_div(f
, state
->crystal_freq
);
719 acpf
= acpf
* state
->cgcdiv
/ 16;
720 acni
= acni
* state
->cgcdiv
/ 16;
722 if (state
->cgcdiv
== 3)
728 saa711x_write(client
, R_38_CLK_RATIO_AMXCLK_TO_ASCLK
, 0x03);
729 saa711x_write(client
, R_39_CLK_RATIO_ASCLK_TO_ALRCLK
, 0x10);
730 saa711x_write(client
, R_3A_AUD_CLK_GEN_BASIC_SETUP
, acc
);
732 saa711x_write(client
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
, acpf
& 0xff);
733 saa711x_write(client
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
+1,
735 saa711x_write(client
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
+2,
736 (acpf
>> 16) & 0x03);
738 saa711x_write(client
, R_34_AUD_MAST_CLK_NOMINAL_INC
, acni
& 0xff);
739 saa711x_write(client
, R_34_AUD_MAST_CLK_NOMINAL_INC
+1, (acni
>> 8) & 0xff);
740 saa711x_write(client
, R_34_AUD_MAST_CLK_NOMINAL_INC
+2, (acni
>> 16) & 0x3f);
741 state
->audclk_freq
= freq
;
745 static int saa711x_set_v4lctrl(struct i2c_client
*client
, struct v4l2_control
*ctrl
)
747 struct saa711x_state
*state
= i2c_get_clientdata(client
);
750 case V4L2_CID_BRIGHTNESS
:
751 if (ctrl
->value
< 0 || ctrl
->value
> 255) {
752 v4l_err(client
, "invalid brightness setting %d\n", ctrl
->value
);
756 state
->bright
= ctrl
->value
;
757 saa711x_write(client
, R_0A_LUMA_BRIGHT_CNTL
, state
->bright
);
760 case V4L2_CID_CONTRAST
:
761 if (ctrl
->value
< 0 || ctrl
->value
> 127) {
762 v4l_err(client
, "invalid contrast setting %d\n", ctrl
->value
);
766 state
->contrast
= ctrl
->value
;
767 saa711x_write(client
, R_0B_LUMA_CONTRAST_CNTL
, state
->contrast
);
770 case V4L2_CID_SATURATION
:
771 if (ctrl
->value
< 0 || ctrl
->value
> 127) {
772 v4l_err(client
, "invalid saturation setting %d\n", ctrl
->value
);
776 state
->sat
= ctrl
->value
;
777 saa711x_write(client
, R_0C_CHROMA_SAT_CNTL
, state
->sat
);
781 if (ctrl
->value
< -127 || ctrl
->value
> 127) {
782 v4l_err(client
, "invalid hue setting %d\n", ctrl
->value
);
786 state
->hue
= ctrl
->value
;
787 saa711x_write(client
, R_0D_CHROMA_HUE_CNTL
, state
->hue
);
797 static int saa711x_get_v4lctrl(struct i2c_client
*client
, struct v4l2_control
*ctrl
)
799 struct saa711x_state
*state
= i2c_get_clientdata(client
);
802 case V4L2_CID_BRIGHTNESS
:
803 ctrl
->value
= state
->bright
;
805 case V4L2_CID_CONTRAST
:
806 ctrl
->value
= state
->contrast
;
808 case V4L2_CID_SATURATION
:
809 ctrl
->value
= state
->sat
;
812 ctrl
->value
= state
->hue
;
821 static void saa711x_set_v4lstd(struct i2c_client
*client
, v4l2_std_id std
)
823 struct saa711x_state
*state
= i2c_get_clientdata(client
);
825 /* Prevent unnecessary standard changes. During a standard
826 change the I-Port is temporarily disabled. Any devices
827 reading from that port can get confused.
828 Note that VIDIOC_S_STD is also used to switch from
829 radio to TV mode, so if a VIDIOC_S_STD is broadcast to
830 all I2C devices then you do not want to have an unwanted
832 if (std
== state
->std
)
835 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
836 if (std
& V4L2_STD_525_60
) {
837 v4l_dbg(1, debug
, client
, "decoder set standard 60 Hz\n");
838 saa711x_writeregs(client
, saa7115_cfg_60hz_video
);
840 v4l_dbg(1, debug
, client
, "decoder set standard 50 Hz\n");
841 saa711x_writeregs(client
, saa7115_cfg_50hz_video
);
844 /* Register 0E - Bits D6-D4 on NO-AUTO mode
845 (SAA7111 and SAA7113 doesn't have auto mode)
846 50 Hz / 625 lines 60 Hz / 525 lines
847 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz)
848 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz)
849 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
850 011 NTSC N (3.58MHz) PAL M (3.58MHz)
851 100 reserved NTSC-Japan (3.58MHz)
855 if (state
->ident
== V4L2_IDENT_SAA7111
||
856 state
->ident
== V4L2_IDENT_SAA7113
) {
857 u8 reg
= saa711x_read(client
, R_0E_CHROMA_CNTL_1
) & 0x8f;
859 if (std
== V4L2_STD_PAL_M
) {
861 } else if (std
== V4L2_STD_PAL_N
) {
863 } else if (std
== V4L2_STD_PAL_60
) {
865 } else if (std
== V4L2_STD_NTSC_M_JP
) {
868 saa711x_write(client
, R_0E_CHROMA_CNTL_1
, reg
);
870 /* restart task B if needed */
871 int taskb
= saa711x_read(client
, R_80_GLOBAL_CNTL_1
) & 0x10;
873 if (taskb
&& state
->ident
== V4L2_IDENT_SAA7114
) {
874 saa711x_writeregs(client
, saa7115_cfg_vbi_on
);
877 /* switch audio mode too! */
878 saa711x_set_audio_clock_freq(client
, state
->audclk_freq
);
882 static v4l2_std_id
saa711x_get_v4lstd(struct i2c_client
*client
)
884 struct saa711x_state
*state
= i2c_get_clientdata(client
);
889 static void saa711x_log_status(struct i2c_client
*client
)
891 struct saa711x_state
*state
= i2c_get_clientdata(client
);
896 v4l_info(client
, "Audio frequency: %d Hz\n", state
->audclk_freq
);
897 if (state
->ident
!= V4L2_IDENT_SAA7115
) {
898 /* status for the saa7114 */
899 reg1f
= saa711x_read(client
, R_1F_STATUS_BYTE_2_VD_DEC
);
900 signalOk
= (reg1f
& 0xc1) == 0x81;
901 v4l_info(client
, "Video signal: %s\n", signalOk
? "ok" : "bad");
902 v4l_info(client
, "Frequency: %s\n", (reg1f
& 0x20) ? "60 Hz" : "50 Hz");
906 /* status for the saa7115 */
907 reg1e
= saa711x_read(client
, R_1E_STATUS_BYTE_1_VD_DEC
);
908 reg1f
= saa711x_read(client
, R_1F_STATUS_BYTE_2_VD_DEC
);
910 signalOk
= (reg1f
& 0xc1) == 0x81 && (reg1e
& 0xc0) == 0x80;
911 vcr
= !(reg1f
& 0x10);
913 if (state
->input
>= 6) {
914 v4l_info(client
, "Input: S-Video %d\n", state
->input
- 6);
916 v4l_info(client
, "Input: Composite %d\n", state
->input
);
918 v4l_info(client
, "Video signal: %s\n", signalOk
? (vcr
? "VCR" : "broadcast/DVD") : "bad");
919 v4l_info(client
, "Frequency: %s\n", (reg1f
& 0x20) ? "60 Hz" : "50 Hz");
921 switch (reg1e
& 0x03) {
923 v4l_info(client
, "Detected format: NTSC\n");
926 v4l_info(client
, "Detected format: PAL\n");
929 v4l_info(client
, "Detected format: SECAM\n");
932 v4l_info(client
, "Detected format: BW/No color\n");
937 /* setup the sliced VBI lcr registers according to the sliced VBI format */
938 static void saa711x_set_lcr(struct i2c_client
*client
, struct v4l2_sliced_vbi_format
*fmt
)
940 struct saa711x_state
*state
= i2c_get_clientdata(client
);
941 int is_50hz
= (state
->std
& V4L2_STD_625_50
);
946 /* saa7113/7114/7118 VBI support are experimental */
947 if (!saa711x_has_reg(state
->ident
,R_41_LCR_BASE
))
951 /* SAA7113 and SAA7118 also should support VBI - Need testing */
952 if (state
->ident
!= V4L2_IDENT_SAA7115
)
956 for (i
= 0; i
<= 23; i
++)
959 if (fmt
->service_set
== 0) {
962 for (i
= 6; i
<= 23; i
++)
965 for (i
= 10; i
<= 21; i
++)
969 /* first clear lines that cannot be captured */
971 for (i
= 0; i
<= 5; i
++)
972 fmt
->service_lines
[0][i
] =
973 fmt
->service_lines
[1][i
] = 0;
976 for (i
= 0; i
<= 9; i
++)
977 fmt
->service_lines
[0][i
] =
978 fmt
->service_lines
[1][i
] = 0;
979 for (i
= 22; i
<= 23; i
++)
980 fmt
->service_lines
[0][i
] =
981 fmt
->service_lines
[1][i
] = 0;
984 /* Now set the lcr values according to the specified service */
985 for (i
= 6; i
<= 23; i
++) {
987 for (x
= 0; x
<= 1; x
++) {
988 switch (fmt
->service_lines
[1-x
][i
]) {
990 lcr
[i
] |= 0xf << (4 * x
);
992 case V4L2_SLICED_TELETEXT_B
:
993 lcr
[i
] |= 1 << (4 * x
);
995 case V4L2_SLICED_CAPTION_525
:
996 lcr
[i
] |= 4 << (4 * x
);
998 case V4L2_SLICED_WSS_625
:
999 lcr
[i
] |= 5 << (4 * x
);
1001 case V4L2_SLICED_VPS
:
1002 lcr
[i
] |= 7 << (4 * x
);
1009 /* write the lcr registers */
1010 for (i
= 2; i
<= 23; i
++) {
1011 saa711x_write(client
, i
- 2 + R_41_LCR_BASE
, lcr
[i
]);
1014 /* enable/disable raw VBI capturing */
1015 saa711x_writeregs(client
, fmt
->service_set
== 0 ?
1016 saa7115_cfg_vbi_on
:
1017 saa7115_cfg_vbi_off
);
1020 static int saa711x_get_v4lfmt(struct i2c_client
*client
, struct v4l2_format
*fmt
)
1022 static u16 lcr2vbi
[] = {
1023 0, V4L2_SLICED_TELETEXT_B
, 0, /* 1 */
1024 0, V4L2_SLICED_CAPTION_525
, /* 4 */
1025 V4L2_SLICED_WSS_625
, 0, /* 5 */
1026 V4L2_SLICED_VPS
, 0, 0, 0, 0, /* 7 */
1029 struct v4l2_sliced_vbi_format
*sliced
= &fmt
->fmt
.sliced
;
1032 if (fmt
->type
!= V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
)
1034 memset(sliced
, 0, sizeof(*sliced
));
1035 /* done if using raw VBI */
1036 if (saa711x_read(client
, R_80_GLOBAL_CNTL_1
) & 0x10)
1038 for (i
= 2; i
<= 23; i
++) {
1039 u8 v
= saa711x_read(client
, i
- 2 + R_41_LCR_BASE
);
1041 sliced
->service_lines
[0][i
] = lcr2vbi
[v
>> 4];
1042 sliced
->service_lines
[1][i
] = lcr2vbi
[v
& 0xf];
1043 sliced
->service_set
|=
1044 sliced
->service_lines
[0][i
] | sliced
->service_lines
[1][i
];
1049 static int saa711x_set_size(struct i2c_client
*client
, int width
, int height
)
1051 struct saa711x_state
*state
= i2c_get_clientdata(client
);
1055 int is_50hz
= state
->std
& V4L2_STD_625_50
;
1056 int Vsrc
= is_50hz
? 576 : 480;
1058 v4l_dbg(1, debug
, client
, "decoder set size to %ix%i\n",width
,height
);
1060 /* FIXME need better bounds checking here */
1061 if ((width
< 1) || (width
> 1440))
1063 if ((height
< 1) || (height
> 960))
1066 if (!saa711x_has_reg(state
->ident
,R_D0_B_HORIZ_PRESCALING
)) {
1067 /* Decoder only supports 720 columns and 480 or 576 lines */
1073 if (!saa711x_has_reg(state
->ident
,R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
))
1076 /* probably have a valid size, let's set it */
1077 /* Set output width/height */
1080 saa711x_write(client
, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
,
1081 (u8
) (width
& 0xff));
1082 saa711x_write(client
, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
,
1083 (u8
) ((width
>> 8) & 0xff));
1085 if (height
== Vsrc
) {
1086 /*FIXME: This code seems weird, however, this is how it is
1096 saa711x_write(client
, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH
,
1098 saa711x_write(client
, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB
,
1102 /* Scaling settings */
1103 /* Hprescaler is floor(inres/outres) */
1104 HPSC
= (int)(720 / width
);
1105 /* 0 is not allowed (div. by zero) */
1106 HPSC
= HPSC
? HPSC
: 1;
1107 HFSC
= (int)((1024 * 720) / (HPSC
* width
));
1108 /* FIXME hardcodes to "Task B"
1109 * write H prescaler integer */
1110 saa711x_write(client
, R_D0_B_HORIZ_PRESCALING
,
1111 (u8
) (HPSC
& 0x3f));
1113 v4l_dbg(1, debug
, client
, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC
, HFSC
);
1114 /* write H fine-scaling (luminance) */
1115 saa711x_write(client
, R_D8_B_HORIZ_LUMA_SCALING_INC
,
1116 (u8
) (HFSC
& 0xff));
1117 saa711x_write(client
, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB
,
1118 (u8
) ((HFSC
>> 8) & 0xff));
1119 /* write H fine-scaling (chrominance)
1120 * must be lum/2, so i'll just bitshift :) */
1121 saa711x_write(client
, R_DC_B_HORIZ_CHROMA_SCALING
,
1122 (u8
) ((HFSC
>> 1) & 0xff));
1123 saa711x_write(client
, R_DD_B_HORIZ_CHROMA_SCALING_MSB
,
1124 (u8
) ((HFSC
>> 9) & 0xff));
1126 VSCY
= (int)((1024 * Vsrc
) / height
);
1127 v4l_dbg(1, debug
, client
, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc
, VSCY
);
1129 /* Correct Contrast and Luminance */
1130 saa711x_write(client
, R_D5_B_LUMA_CONTRAST_CNTL
,
1131 (u8
) (64 * 1024 / VSCY
));
1132 saa711x_write(client
, R_D6_B_CHROMA_SATURATION_CNTL
,
1133 (u8
) (64 * 1024 / VSCY
));
1135 /* write V fine-scaling (luminance) */
1136 saa711x_write(client
, R_E0_B_VERT_LUMA_SCALING_INC
,
1137 (u8
) (VSCY
& 0xff));
1138 saa711x_write(client
, R_E1_B_VERT_LUMA_SCALING_INC_MSB
,
1139 (u8
) ((VSCY
>> 8) & 0xff));
1140 /* write V fine-scaling (chrominance) */
1141 saa711x_write(client
, R_E2_B_VERT_CHROMA_SCALING_INC
,
1142 (u8
) (VSCY
& 0xff));
1143 saa711x_write(client
, R_E3_B_VERT_CHROMA_SCALING_INC_MSB
,
1144 (u8
) ((VSCY
>> 8) & 0xff));
1146 saa711x_writeregs(client
, saa7115_cfg_reset_scaler
);
1151 static int saa711x_set_v4lfmt(struct i2c_client
*client
, struct v4l2_format
*fmt
)
1153 if (fmt
->type
== V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
) {
1154 saa711x_set_lcr(client
, &fmt
->fmt
.sliced
);
1157 if (fmt
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1160 return saa711x_set_size(client
,fmt
->fmt
.pix
.width
,fmt
->fmt
.pix
.height
);
1163 /* Decode the sliced VBI data stream as created by the saa7115.
1164 The format is described in the saa7115 datasheet in Tables 25 and 26
1166 The current implementation uses SAV/EAV codes and not the ancillary data
1167 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1169 static void saa711x_decode_vbi_line(struct i2c_client
*client
,
1170 struct v4l2_decode_vbi_line
*vbi
)
1172 static const char vbi_no_data_pattern
[] = {
1173 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1175 struct saa711x_state
*state
= i2c_get_clientdata(client
);
1178 int id1
, id2
; /* the ID1 and ID2 bytes from the internal header */
1180 vbi
->type
= 0; /* mark result as a failure */
1183 /* Note: the field bit is inverted for 60 Hz video */
1184 if (state
->std
& V4L2_STD_525_60
)
1187 /* Skip internal header, p now points to the start of the payload */
1191 /* calculate field and line number of the VBI packet (1-23) */
1192 vbi
->is_second_field
= ((id1
& 0x40) != 0);
1193 vbi
->line
= (id1
& 0x3f) << 3;
1194 vbi
->line
|= (id2
& 0x70) >> 4;
1196 /* Obtain data type */
1199 /* If the VBI slicer does not detect any signal it will fill up
1200 the payload buffer with 0xa0 bytes. */
1201 if (!memcmp(p
, vbi_no_data_pattern
, sizeof(vbi_no_data_pattern
)))
1204 /* decode payloads */
1207 vbi
->type
= V4L2_SLICED_TELETEXT_B
;
1210 if (!saa711x_odd_parity(p
[0]) || !saa711x_odd_parity(p
[1]))
1212 vbi
->type
= V4L2_SLICED_CAPTION_525
;
1215 wss
= saa711x_decode_wss(p
);
1220 vbi
->type
= V4L2_SLICED_WSS_625
;
1223 if (saa711x_decode_vps(p
, p
) != 0)
1225 vbi
->type
= V4L2_SLICED_VPS
;
1232 /* ============ SAA7115 AUDIO settings (end) ============= */
1234 static int saa711x_command(struct i2c_client
*client
, unsigned int cmd
, void *arg
)
1236 struct saa711x_state
*state
= i2c_get_clientdata(client
);
1239 /* ioctls to allow direct access to the saa7115 registers for testing */
1242 return saa711x_set_v4lfmt(client
, (struct v4l2_format
*)arg
);
1245 return saa711x_get_v4lfmt(client
, (struct v4l2_format
*)arg
);
1247 case VIDIOC_INT_AUDIO_CLOCK_FREQ
:
1248 return saa711x_set_audio_clock_freq(client
, *(u32
*)arg
);
1250 case VIDIOC_G_TUNER
:
1252 struct v4l2_tuner
*vt
= arg
;
1257 status
= saa711x_read(client
, R_1F_STATUS_BYTE_2_VD_DEC
);
1259 v4l_dbg(1, debug
, client
, "status: 0x%02x\n", status
);
1260 vt
->signal
= ((status
& (1 << 6)) == 0) ? 0xffff : 0x0;
1264 case VIDIOC_LOG_STATUS
:
1265 saa711x_log_status(client
);
1269 return saa711x_get_v4lctrl(client
, (struct v4l2_control
*)arg
);
1272 return saa711x_set_v4lctrl(client
, (struct v4l2_control
*)arg
);
1274 case VIDIOC_QUERYCTRL
:
1276 struct v4l2_queryctrl
*qc
= arg
;
1279 case V4L2_CID_BRIGHTNESS
:
1280 case V4L2_CID_CONTRAST
:
1281 case V4L2_CID_SATURATION
:
1283 return v4l2_ctrl_query_fill_std(qc
);
1290 *(v4l2_std_id
*)arg
= saa711x_get_v4lstd(client
);
1295 saa711x_set_v4lstd(client
, *(v4l2_std_id
*)arg
);
1298 case AUDC_SET_RADIO
:
1302 case VIDIOC_INT_G_VIDEO_ROUTING
:
1304 struct v4l2_routing
*route
= arg
;
1306 route
->input
= state
->input
;
1311 case VIDIOC_INT_S_VIDEO_ROUTING
:
1313 struct v4l2_routing
*route
= arg
;
1315 v4l_dbg(1, debug
, client
, "decoder set input %d\n", route
->input
);
1316 /* saa7113 does not have these inputs */
1317 if (state
->ident
== V4L2_IDENT_SAA7113
&&
1318 (route
->input
== SAA7115_COMPOSITE4
||
1319 route
->input
== SAA7115_COMPOSITE5
)) {
1322 if (route
->input
> SAA7115_SVIDEO3
)
1324 if (state
->input
== route
->input
)
1326 v4l_dbg(1, debug
, client
, "now setting %s input\n",
1327 (route
->input
>= SAA7115_SVIDEO0
) ? "S-Video" : "Composite");
1328 state
->input
= route
->input
;
1331 saa711x_write(client
, R_02_INPUT_CNTL_1
,
1332 (saa711x_read(client
, R_02_INPUT_CNTL_1
) & 0xf0) |
1335 /* bypass chrominance trap for S-Video modes */
1336 saa711x_write(client
, R_09_LUMA_CNTL
,
1337 (saa711x_read(client
, R_09_LUMA_CNTL
) & 0x7f) |
1338 (state
->input
>= SAA7115_SVIDEO0
? 0x80 : 0x0));
1342 case VIDIOC_STREAMON
:
1343 case VIDIOC_STREAMOFF
:
1344 v4l_dbg(1, debug
, client
, "%s output\n",
1345 (cmd
== VIDIOC_STREAMON
) ? "enable" : "disable");
1347 if (state
->enable
!= (cmd
== VIDIOC_STREAMON
)) {
1348 state
->enable
= (cmd
== VIDIOC_STREAMON
);
1349 saa711x_write(client
,
1350 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
,
1355 case VIDIOC_INT_S_CRYSTAL_FREQ
:
1357 struct v4l2_crystal_freq
*freq
= arg
;
1359 if (freq
->freq
!= SAA7115_FREQ_32_11_MHZ
&&
1360 freq
->freq
!= SAA7115_FREQ_24_576_MHZ
)
1362 state
->crystal_freq
= freq
->freq
;
1363 state
->cgcdiv
= (freq
->flags
& SAA7115_FREQ_FL_CGCDIV
) ? 3 : 4;
1364 state
->ucgc
= (freq
->flags
& SAA7115_FREQ_FL_UCGC
) ? 1 : 0;
1365 state
->apll
= (freq
->flags
& SAA7115_FREQ_FL_APLL
) ? 1 : 0;
1366 saa711x_set_audio_clock_freq(client
, state
->audclk_freq
);
1370 case VIDIOC_INT_DECODE_VBI_LINE
:
1371 saa711x_decode_vbi_line(client
, arg
);
1374 case VIDIOC_INT_RESET
:
1375 v4l_dbg(1, debug
, client
, "decoder RESET\n");
1376 saa711x_writeregs(client
, saa7115_cfg_reset_scaler
);
1379 case VIDIOC_INT_G_VBI_DATA
:
1381 struct v4l2_sliced_vbi_data
*data
= arg
;
1384 case V4L2_SLICED_WSS_625
:
1385 if (saa711x_read(client
, 0x6b) & 0xc0)
1387 data
->data
[0] = saa711x_read(client
, 0x6c);
1388 data
->data
[1] = saa711x_read(client
, 0x6d);
1390 case V4L2_SLICED_CAPTION_525
:
1391 if (data
->field
== 0) {
1393 if (saa711x_read(client
, 0x66) & 0xc0)
1395 data
->data
[0] = saa711x_read(client
, 0x67);
1396 data
->data
[1] = saa711x_read(client
, 0x68);
1400 if (saa711x_read(client
, 0x66) & 0x30)
1402 data
->data
[0] = saa711x_read(client
, 0x69);
1403 data
->data
[1] = saa711x_read(client
, 0x6a);
1411 #ifdef CONFIG_VIDEO_ADV_DEBUG
1412 case VIDIOC_INT_G_REGISTER
:
1414 struct v4l2_register
*reg
= arg
;
1416 if (reg
->i2c_id
!= I2C_DRIVERID_SAA711X
)
1418 reg
->val
= saa711x_read(client
, reg
->reg
& 0xff);
1422 case VIDIOC_INT_S_REGISTER
:
1424 struct v4l2_register
*reg
= arg
;
1426 if (reg
->i2c_id
!= I2C_DRIVERID_SAA711X
)
1428 if (!capable(CAP_SYS_ADMIN
))
1430 saa711x_write(client
, reg
->reg
& 0xff, reg
->val
& 0xff);
1435 case VIDIOC_INT_G_CHIP_IDENT
:
1436 *iarg
= state
->ident
;
1446 /* ----------------------------------------------------------------------- */
1448 static struct i2c_driver i2c_driver_saa711x
;
1450 static int saa711x_attach(struct i2c_adapter
*adapter
, int address
, int kind
)
1452 struct i2c_client
*client
;
1453 struct saa711x_state
*state
;
1458 /* Check if the adapter supports the needed features */
1459 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_BYTE_DATA
))
1462 client
= kzalloc(sizeof(struct i2c_client
), GFP_KERNEL
);
1465 client
->addr
= address
;
1466 client
->adapter
= adapter
;
1467 client
->driver
= &i2c_driver_saa711x
;
1468 snprintf(client
->name
, sizeof(client
->name
) - 1, "saa7115");
1470 v4l_dbg(1, debug
, client
, "detecting saa7115 client on address 0x%x\n", address
<< 1);
1472 for (i
=0;i
<0x0f;i
++) {
1473 saa711x_write(client
, 0, i
);
1474 name
[i
] = (saa711x_read(client
, 0) &0x0f) +'0';
1480 saa711x_write(client
, 0, 5);
1481 chip_id
= saa711x_read(client
, 0) & 0x0f;
1482 if (chip_id
< 3 && chip_id
> 5) {
1483 v4l_dbg(1, debug
, client
, "saa7115 not found\n");
1487 snprintf(client
->name
, sizeof(client
->name
) - 1, "saa711%d",chip_id
);
1488 v4l_info(client
, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id
, name
, address
<< 1, adapter
->name
);
1490 state
= kzalloc(sizeof(struct saa711x_state
), GFP_KERNEL
);
1491 i2c_set_clientdata(client
, state
);
1492 if (state
== NULL
) {
1499 state
->bright
= 128;
1500 state
->contrast
= 64;
1505 state
->ident
= V4L2_IDENT_SAA7111
;
1508 state
->ident
= V4L2_IDENT_SAA7113
;
1511 state
->ident
= V4L2_IDENT_SAA7114
;
1514 state
->ident
= V4L2_IDENT_SAA7115
;
1517 state
->ident
= V4L2_IDENT_SAA7118
;
1520 state
->ident
= V4L2_IDENT_SAA7111
;
1521 v4l_info(client
, "WARNING: Chip is not known - Falling back to saa7111\n");
1525 state
->audclk_freq
= 48000;
1527 v4l_dbg(1, debug
, client
, "writing init values\n");
1529 /* init to 60hz/48khz */
1530 if (state
->ident
== V4L2_IDENT_SAA7111
||
1531 state
->ident
== V4L2_IDENT_SAA7113
) {
1532 state
->crystal_freq
= SAA7115_FREQ_24_576_MHZ
;
1533 saa711x_writeregs(client
, saa7113_init_auto_input
);
1535 state
->crystal_freq
= SAA7115_FREQ_32_11_MHZ
;
1536 saa711x_writeregs(client
, saa7115_init_auto_input
);
1538 saa711x_writeregs(client
, saa7115_init_misc
);
1539 state
->std
= V4L2_STD_NTSC
;
1540 saa711x_set_size(client
, 720, 480);
1541 saa711x_writeregs(client
, saa7115_cfg_60hz_video
);
1542 saa711x_set_audio_clock_freq(client
, state
->audclk_freq
);
1543 saa711x_writeregs(client
, saa7115_cfg_reset_scaler
);
1545 i2c_attach_client(client
);
1547 v4l_dbg(1, debug
, client
, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1548 saa711x_read(client
, R_1E_STATUS_BYTE_1_VD_DEC
), saa711x_read(client
, R_1F_STATUS_BYTE_2_VD_DEC
));
1553 static int saa711x_probe(struct i2c_adapter
*adapter
)
1555 if (adapter
->class & I2C_CLASS_TV_ANALOG
)
1556 return i2c_probe(adapter
, &addr_data
, &saa711x_attach
);
1560 static int saa711x_detach(struct i2c_client
*client
)
1562 struct saa711x_state
*state
= i2c_get_clientdata(client
);
1565 err
= i2c_detach_client(client
);
1575 /* ----------------------------------------------------------------------- */
1577 /* i2c implementation */
1578 static struct i2c_driver i2c_driver_saa711x
= {
1582 .id
= I2C_DRIVERID_SAA711X
,
1583 .attach_adapter
= saa711x_probe
,
1584 .detach_client
= saa711x_detach
,
1585 .command
= saa711x_command
,
1589 static int __init
saa711x_init_module(void)
1591 return i2c_add_driver(&i2c_driver_saa711x
);
1594 static void __exit
saa711x_cleanup_module(void)
1596 i2c_del_driver(&i2c_driver_saa711x
);
1599 module_init(saa711x_init_module
);
1600 module_exit(saa711x_cleanup_module
);