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-device.h>
48 #include <media/v4l2-chip-ident.h>
49 #include <media/v4l2-i2c-drv.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");
61 module_param(debug
, bool, 0644);
63 MODULE_PARM_DESC(debug
, "Debug level (0-1)");
66 struct saa711x_state
{
67 struct v4l2_subdev sd
;
87 static inline struct saa711x_state
*to_state(struct v4l2_subdev
*sd
)
89 return container_of(sd
, struct saa711x_state
, sd
);
92 /* ----------------------------------------------------------------------- */
94 static inline int saa711x_write(struct v4l2_subdev
*sd
, u8 reg
, u8 value
)
96 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
98 return i2c_smbus_write_byte_data(client
, reg
, value
);
101 /* Sanity routine to check if a register is present */
102 static int saa711x_has_reg(const int id
, const u8 reg
)
104 if (id
== V4L2_IDENT_SAA7111
)
105 return reg
< 0x20 && reg
!= 0x01 && reg
!= 0x0f &&
106 (reg
< 0x13 || reg
> 0x19) && reg
!= 0x1d && reg
!= 0x1e;
108 /* common for saa7113/4/5/8 */
109 if (unlikely((reg
>= 0x3b && reg
<= 0x3f) || reg
== 0x5c || reg
== 0x5f ||
110 reg
== 0xa3 || reg
== 0xa7 || reg
== 0xab || reg
== 0xaf || (reg
>= 0xb5 && reg
<= 0xb7) ||
111 reg
== 0xd3 || reg
== 0xd7 || reg
== 0xdb || reg
== 0xdf || (reg
>= 0xe5 && reg
<= 0xe7) ||
112 reg
== 0x82 || (reg
>= 0x89 && reg
<= 0x8e)))
116 case V4L2_IDENT_SAA7113
:
117 return reg
!= 0x14 && (reg
< 0x18 || reg
> 0x1e) && (reg
< 0x20 || reg
> 0x3f) &&
118 reg
!= 0x5d && reg
< 0x63;
119 case V4L2_IDENT_SAA7114
:
120 return (reg
< 0x1a || reg
> 0x1e) && (reg
< 0x20 || reg
> 0x2f) &&
121 (reg
< 0x63 || reg
> 0x7f) && reg
!= 0x33 && reg
!= 0x37 &&
122 reg
!= 0x81 && reg
< 0xf0;
123 case V4L2_IDENT_SAA7115
:
124 return (reg
< 0x20 || reg
> 0x2f) && reg
!= 0x65 && (reg
< 0xfc || reg
> 0xfe);
125 case V4L2_IDENT_SAA7118
:
126 return (reg
< 0x1a || reg
> 0x1d) && (reg
< 0x20 || reg
> 0x22) &&
127 (reg
< 0x26 || reg
> 0x28) && reg
!= 0x33 && reg
!= 0x37 &&
128 (reg
< 0x63 || reg
> 0x7f) && reg
!= 0x81 && reg
< 0xf0;
133 static int saa711x_writeregs(struct v4l2_subdev
*sd
, const unsigned char *regs
)
135 struct saa711x_state
*state
= to_state(sd
);
136 unsigned char reg
, data
;
138 while (*regs
!= 0x00) {
142 /* According with datasheets, reserved regs should be
143 filled with 0 - seems better not to touch on they */
144 if (saa711x_has_reg(state
->ident
, reg
)) {
145 if (saa711x_write(sd
, reg
, data
) < 0)
148 v4l2_dbg(1, debug
, sd
, "tried to access reserved reg 0x%02x\n", reg
);
154 static inline int saa711x_read(struct v4l2_subdev
*sd
, u8 reg
)
156 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
158 return i2c_smbus_read_byte_data(client
, reg
);
161 /* ----------------------------------------------------------------------- */
163 /* SAA7111 initialization table */
164 static const unsigned char saa7111_init
[] = {
165 R_01_INC_DELAY
, 0x00, /* reserved */
168 R_02_INPUT_CNTL_1
, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */
169 R_03_INPUT_CNTL_2
, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
170 * GAFIX=0, GAI1=256, GAI2=256 */
171 R_04_INPUT_CNTL_3
, 0x00, /* GAI1=256 */
172 R_05_INPUT_CNTL_4
, 0x00, /* GAI2=256 */
175 R_06_H_SYNC_START
, 0xf3, /* HSB at 13(50Hz) / 17(60Hz)
176 * pixels after end of last line */
177 R_07_H_SYNC_STOP
, 0xe8, /* HSS seems to be needed to
178 * work with NTSC, too */
179 R_08_SYNC_CNTL
, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0,
180 * VTRC=1, HPLL=0, VNOI=0 */
181 R_09_LUMA_CNTL
, 0x01, /* BYPS=0, PREF=0, BPSS=0,
182 * VBLB=0, UPTCV=0, APER=1 */
183 R_0A_LUMA_BRIGHT_CNTL
, 0x80,
184 R_0B_LUMA_CONTRAST_CNTL
, 0x47, /* 0b - CONT=1.109 */
185 R_0C_CHROMA_SAT_CNTL
, 0x40,
186 R_0D_CHROMA_HUE_CNTL
, 0x00,
187 R_0E_CHROMA_CNTL_1
, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
189 R_0F_CHROMA_GAIN_CNTL
, 0x00, /* reserved */
190 R_10_CHROMA_CNTL_2
, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
191 R_11_MODE_DELAY_CNTL
, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
192 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
193 R_12_RT_SIGNAL_CNTL
, 0x00, /* 12 - output control 2 */
194 R_13_RT_X_PORT_OUT_CNTL
, 0x00, /* 13 - output control 3 */
195 R_14_ANAL_ADC_COMPAT_CNTL
, 0x00,
196 R_15_VGATE_START_FID_CHG
, 0x00,
197 R_16_VGATE_STOP
, 0x00,
198 R_17_MISC_VGATE_CONF_AND_MSB
, 0x00,
203 /* SAA7113 init codes */
204 static const unsigned char saa7113_init
[] = {
205 R_01_INC_DELAY
, 0x08,
206 R_02_INPUT_CNTL_1
, 0xc2,
207 R_03_INPUT_CNTL_2
, 0x30,
208 R_04_INPUT_CNTL_3
, 0x00,
209 R_05_INPUT_CNTL_4
, 0x00,
210 R_06_H_SYNC_START
, 0x89,
211 R_07_H_SYNC_STOP
, 0x0d,
212 R_08_SYNC_CNTL
, 0x88,
213 R_09_LUMA_CNTL
, 0x01,
214 R_0A_LUMA_BRIGHT_CNTL
, 0x80,
215 R_0B_LUMA_CONTRAST_CNTL
, 0x47,
216 R_0C_CHROMA_SAT_CNTL
, 0x40,
217 R_0D_CHROMA_HUE_CNTL
, 0x00,
218 R_0E_CHROMA_CNTL_1
, 0x01,
219 R_0F_CHROMA_GAIN_CNTL
, 0x2a,
220 R_10_CHROMA_CNTL_2
, 0x08,
221 R_11_MODE_DELAY_CNTL
, 0x0c,
222 R_12_RT_SIGNAL_CNTL
, 0x07,
223 R_13_RT_X_PORT_OUT_CNTL
, 0x00,
224 R_14_ANAL_ADC_COMPAT_CNTL
, 0x00,
225 R_15_VGATE_START_FID_CHG
, 0x00,
226 R_16_VGATE_STOP
, 0x00,
227 R_17_MISC_VGATE_CONF_AND_MSB
, 0x00,
232 /* If a value differs from the Hauppauge driver values, then the comment starts with
233 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
234 Hauppauge driver sets. */
236 /* SAA7114 and SAA7115 initialization table */
237 static const unsigned char saa7115_init_auto_input
[] = {
239 R_01_INC_DELAY
, 0x48, /* white peak control disabled */
240 R_03_INPUT_CNTL_2
, 0x20, /* was 0x30. 0x20: long vertical blanking */
241 R_04_INPUT_CNTL_3
, 0x90, /* analog gain set to 0 */
242 R_05_INPUT_CNTL_4
, 0x90, /* analog gain set to 0 */
244 R_06_H_SYNC_START
, 0xeb, /* horiz sync begin = -21 */
245 R_07_H_SYNC_STOP
, 0xe0, /* horiz sync stop = -17 */
246 R_09_LUMA_CNTL
, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
247 R_0A_LUMA_BRIGHT_CNTL
, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
248 R_0B_LUMA_CONTRAST_CNTL
, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
249 R_0C_CHROMA_SAT_CNTL
, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
250 R_0D_CHROMA_HUE_CNTL
, 0x00,
251 R_0F_CHROMA_GAIN_CNTL
, 0x00, /* use automatic gain */
252 R_10_CHROMA_CNTL_2
, 0x06, /* chroma: active adaptive combfilter */
253 R_11_MODE_DELAY_CNTL
, 0x00,
254 R_12_RT_SIGNAL_CNTL
, 0x9d, /* RTS0 output control: VGATE */
255 R_13_RT_X_PORT_OUT_CNTL
, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */
256 R_14_ANAL_ADC_COMPAT_CNTL
, 0x00,
257 R_18_RAW_DATA_GAIN_CNTL
, 0x40, /* gain 0x00 = nominal */
258 R_19_RAW_DATA_OFF_CNTL
, 0x80,
259 R_1A_COLOR_KILL_LVL_CNTL
, 0x77, /* recommended value */
260 R_1B_MISC_TVVCRDET
, 0x42, /* recommended value */
261 R_1C_ENHAN_COMB_CTRL1
, 0xa9, /* recommended value */
262 R_1D_ENHAN_COMB_CTRL2
, 0x01, /* recommended value */
265 R_80_GLOBAL_CNTL_1
, 0x0, /* No tasks enabled at init */
267 /* Power Device Control */
268 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset device */
269 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* set device programmed, all in operational mode */
273 /* Used to reset saa7113, saa7114 and saa7115 */
274 static const unsigned char saa7115_cfg_reset_scaler
[] = {
275 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x00, /* disable I-port output */
276 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
277 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
278 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* enable I-port output */
282 /* ============== SAA7715 VIDEO templates ============= */
284 static const unsigned char saa7115_cfg_60hz_video
[] = {
285 R_80_GLOBAL_CNTL_1
, 0x00, /* reset tasks */
286 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
288 R_15_VGATE_START_FID_CHG
, 0x03,
289 R_16_VGATE_STOP
, 0x11,
290 R_17_MISC_VGATE_CONF_AND_MSB
, 0x9c,
292 R_08_SYNC_CNTL
, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
293 R_0E_CHROMA_CNTL_1
, 0x07, /* video autodetection is on */
295 R_5A_V_OFF_FOR_SLICER
, 0x06, /* standard 60hz value for ITU656 line counting */
298 R_90_A_TASK_HANDLING_CNTL
, 0x80,
299 R_91_A_X_PORT_FORMATS_AND_CONF
, 0x48,
300 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL
, 0x40,
301 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF
, 0x84,
303 /* hoffset low (input), 0x0002 is minimum */
304 R_94_A_HORIZ_INPUT_WINDOW_START
, 0x01,
305 R_95_A_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
307 /* hsize low (input), 0x02d0 = 720 */
308 R_96_A_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
309 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
311 R_98_A_VERT_INPUT_WINDOW_START
, 0x05,
312 R_99_A_VERT_INPUT_WINDOW_START_MSB
, 0x00,
314 R_9A_A_VERT_INPUT_WINDOW_LENGTH
, 0x0c,
315 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB
, 0x00,
317 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xa0,
318 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x05,
320 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH
, 0x0c,
321 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB
, 0x00,
324 R_C0_B_TASK_HANDLING_CNTL
, 0x00,
325 R_C1_B_X_PORT_FORMATS_AND_CONF
, 0x08,
326 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION
, 0x00,
327 R_C3_B_I_PORT_FORMATS_AND_CONF
, 0x80,
329 /* 0x0002 is minimum */
330 R_C4_B_HORIZ_INPUT_WINDOW_START
, 0x02,
331 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
334 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
335 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
337 /* vwindow start 0x12 = 18 */
338 R_C8_B_VERT_INPUT_WINDOW_START
, 0x12,
339 R_C9_B_VERT_INPUT_WINDOW_START_MSB
, 0x00,
341 /* vwindow length 0xf8 = 248 */
342 R_CA_B_VERT_INPUT_WINDOW_LENGTH
, VRES_60HZ
>>1,
343 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB
, VRES_60HZ
>>9,
345 /* hwindow 0x02d0 = 720 */
346 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xd0,
347 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x02,
349 R_F0_LFCO_PER_LINE
, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
350 R_F1_P_I_PARAM_SELECT
, 0x05, /* low bit with 0xF0 */
351 R_F5_PULSGEN_LINE_LENGTH
, 0xad,
352 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG
, 0x01,
357 static const unsigned char saa7115_cfg_50hz_video
[] = {
358 R_80_GLOBAL_CNTL_1
, 0x00,
359 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
361 R_15_VGATE_START_FID_CHG
, 0x37, /* VGATE start */
362 R_16_VGATE_STOP
, 0x16,
363 R_17_MISC_VGATE_CONF_AND_MSB
, 0x99,
365 R_08_SYNC_CNTL
, 0x28, /* 0x28 = PAL */
366 R_0E_CHROMA_CNTL_1
, 0x07,
368 R_5A_V_OFF_FOR_SLICER
, 0x03, /* standard 50hz value */
371 R_90_A_TASK_HANDLING_CNTL
, 0x81,
372 R_91_A_X_PORT_FORMATS_AND_CONF
, 0x48,
373 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL
, 0x40,
374 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF
, 0x84,
376 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
377 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
378 /* hoffset low (input), 0x0002 is minimum */
379 R_94_A_HORIZ_INPUT_WINDOW_START
, 0x00,
380 R_95_A_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
382 /* hsize low (input), 0x02d0 = 720 */
383 R_96_A_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
384 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
386 R_98_A_VERT_INPUT_WINDOW_START
, 0x03,
387 R_99_A_VERT_INPUT_WINDOW_START_MSB
, 0x00,
389 /* vsize 0x12 = 18 */
390 R_9A_A_VERT_INPUT_WINDOW_LENGTH
, 0x12,
391 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB
, 0x00,
393 /* hsize 0x05a0 = 1440 */
394 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xa0,
395 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x05, /* hsize hi (output) */
396 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH
, 0x12, /* vsize low (output), 0x12 = 18 */
397 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB
, 0x00, /* vsize hi (output) */
400 R_C0_B_TASK_HANDLING_CNTL
, 0x00,
401 R_C1_B_X_PORT_FORMATS_AND_CONF
, 0x08,
402 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION
, 0x00,
403 R_C3_B_I_PORT_FORMATS_AND_CONF
, 0x80,
405 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
406 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
407 /* hoffset low (input), 0x0002 is minimum. See comment above. */
408 R_C4_B_HORIZ_INPUT_WINDOW_START
, 0x00,
409 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
411 /* hsize 0x02d0 = 720 */
412 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
413 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
415 /* voffset 0x16 = 22 */
416 R_C8_B_VERT_INPUT_WINDOW_START
, 0x16,
417 R_C9_B_VERT_INPUT_WINDOW_START_MSB
, 0x00,
419 /* vsize 0x0120 = 288 */
420 R_CA_B_VERT_INPUT_WINDOW_LENGTH
, 0x20,
421 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB
, 0x01,
423 /* hsize 0x02d0 = 720 */
424 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xd0,
425 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x02,
427 R_F0_LFCO_PER_LINE
, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
428 R_F1_P_I_PARAM_SELECT
, 0x05, /* low bit with 0xF0, (was 0x05) */
429 R_F5_PULSGEN_LINE_LENGTH
, 0xb0,
430 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG
, 0x01,
435 /* ============== SAA7715 VIDEO templates (end) ======= */
437 static const unsigned char saa7115_cfg_vbi_on
[] = {
438 R_80_GLOBAL_CNTL_1
, 0x00, /* reset tasks */
439 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
440 R_80_GLOBAL_CNTL_1
, 0x30, /* Activate both tasks */
441 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
442 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* Enable I-port output */
447 static const unsigned char saa7115_cfg_vbi_off
[] = {
448 R_80_GLOBAL_CNTL_1
, 0x00, /* reset tasks */
449 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
450 R_80_GLOBAL_CNTL_1
, 0x20, /* Activate only task "B" */
451 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
452 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* Enable I-port output */
458 static const unsigned char saa7115_init_misc
[] = {
459 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F
, 0x01,
460 R_83_X_PORT_I_O_ENA_AND_OUT_CLK
, 0x01,
461 R_84_I_PORT_SIGNAL_DEF
, 0x20,
462 R_85_I_PORT_SIGNAL_POLAR
, 0x21,
463 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT
, 0xc5,
464 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01,
467 R_A0_A_HORIZ_PRESCALING
, 0x01,
468 R_A1_A_ACCUMULATION_LENGTH
, 0x00,
469 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER
, 0x00,
471 /* Configure controls at nominal value*/
472 R_A4_A_LUMA_BRIGHTNESS_CNTL
, 0x80,
473 R_A5_A_LUMA_CONTRAST_CNTL
, 0x40,
474 R_A6_A_CHROMA_SATURATION_CNTL
, 0x40,
476 /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
477 R_A8_A_HORIZ_LUMA_SCALING_INC
, 0x00,
478 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB
, 0x02,
480 R_AA_A_HORIZ_LUMA_PHASE_OFF
, 0x00,
482 /* must be horiz lum scaling / 2 */
483 R_AC_A_HORIZ_CHROMA_SCALING_INC
, 0x00,
484 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB
, 0x01,
486 /* must be offset luma / 2 */
487 R_AE_A_HORIZ_CHROMA_PHASE_OFF
, 0x00,
489 R_B0_A_VERT_LUMA_SCALING_INC
, 0x00,
490 R_B1_A_VERT_LUMA_SCALING_INC_MSB
, 0x04,
492 R_B2_A_VERT_CHROMA_SCALING_INC
, 0x00,
493 R_B3_A_VERT_CHROMA_SCALING_INC_MSB
, 0x04,
495 R_B4_A_VERT_SCALING_MODE_CNTL
, 0x01,
497 R_B8_A_VERT_CHROMA_PHASE_OFF_00
, 0x00,
498 R_B9_A_VERT_CHROMA_PHASE_OFF_01
, 0x00,
499 R_BA_A_VERT_CHROMA_PHASE_OFF_10
, 0x00,
500 R_BB_A_VERT_CHROMA_PHASE_OFF_11
, 0x00,
502 R_BC_A_VERT_LUMA_PHASE_OFF_00
, 0x00,
503 R_BD_A_VERT_LUMA_PHASE_OFF_01
, 0x00,
504 R_BE_A_VERT_LUMA_PHASE_OFF_10
, 0x00,
505 R_BF_A_VERT_LUMA_PHASE_OFF_11
, 0x00,
508 R_D0_B_HORIZ_PRESCALING
, 0x01,
509 R_D1_B_ACCUMULATION_LENGTH
, 0x00,
510 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER
, 0x00,
512 /* Configure controls at nominal value*/
513 R_D4_B_LUMA_BRIGHTNESS_CNTL
, 0x80,
514 R_D5_B_LUMA_CONTRAST_CNTL
, 0x40,
515 R_D6_B_CHROMA_SATURATION_CNTL
, 0x40,
517 /* hor lum scaling 0x0400 = 1 */
518 R_D8_B_HORIZ_LUMA_SCALING_INC
, 0x00,
519 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB
, 0x04,
521 R_DA_B_HORIZ_LUMA_PHASE_OFF
, 0x00,
523 /* must be hor lum scaling / 2 */
524 R_DC_B_HORIZ_CHROMA_SCALING
, 0x00,
525 R_DD_B_HORIZ_CHROMA_SCALING_MSB
, 0x02,
527 /* must be offset luma / 2 */
528 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA
, 0x00,
530 R_E0_B_VERT_LUMA_SCALING_INC
, 0x00,
531 R_E1_B_VERT_LUMA_SCALING_INC_MSB
, 0x04,
533 R_E2_B_VERT_CHROMA_SCALING_INC
, 0x00,
534 R_E3_B_VERT_CHROMA_SCALING_INC_MSB
, 0x04,
536 R_E4_B_VERT_SCALING_MODE_CNTL
, 0x01,
538 R_E8_B_VERT_CHROMA_PHASE_OFF_00
, 0x00,
539 R_E9_B_VERT_CHROMA_PHASE_OFF_01
, 0x00,
540 R_EA_B_VERT_CHROMA_PHASE_OFF_10
, 0x00,
541 R_EB_B_VERT_CHROMA_PHASE_OFF_11
, 0x00,
543 R_EC_B_VERT_LUMA_PHASE_OFF_00
, 0x00,
544 R_ED_B_VERT_LUMA_PHASE_OFF_01
, 0x00,
545 R_EE_B_VERT_LUMA_PHASE_OFF_10
, 0x00,
546 R_EF_B_VERT_LUMA_PHASE_OFF_11
, 0x00,
548 R_F2_NOMINAL_PLL2_DTO
, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
549 R_F3_PLL_INCREMENT
, 0x46,
550 R_F4_PLL2_STATUS
, 0x00,
551 R_F7_PULSE_A_POS_MSB
, 0x4b, /* not the recommended settings! */
552 R_F8_PULSE_B_POS
, 0x00,
553 R_F9_PULSE_B_POS_MSB
, 0x4b,
554 R_FA_PULSE_C_POS
, 0x00,
555 R_FB_PULSE_C_POS_MSB
, 0x4b,
557 /* PLL2 lock detection settings: 71 lines 50% phase error */
558 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES
, 0x88,
561 R_40_SLICER_CNTL_1
, 0x20, /* No framing code errors allowed. */
563 R_41_LCR_BASE
+1, 0xff,
564 R_41_LCR_BASE
+2, 0xff,
565 R_41_LCR_BASE
+3, 0xff,
566 R_41_LCR_BASE
+4, 0xff,
567 R_41_LCR_BASE
+5, 0xff,
568 R_41_LCR_BASE
+6, 0xff,
569 R_41_LCR_BASE
+7, 0xff,
570 R_41_LCR_BASE
+8, 0xff,
571 R_41_LCR_BASE
+9, 0xff,
572 R_41_LCR_BASE
+10, 0xff,
573 R_41_LCR_BASE
+11, 0xff,
574 R_41_LCR_BASE
+12, 0xff,
575 R_41_LCR_BASE
+13, 0xff,
576 R_41_LCR_BASE
+14, 0xff,
577 R_41_LCR_BASE
+15, 0xff,
578 R_41_LCR_BASE
+16, 0xff,
579 R_41_LCR_BASE
+17, 0xff,
580 R_41_LCR_BASE
+18, 0xff,
581 R_41_LCR_BASE
+19, 0xff,
582 R_41_LCR_BASE
+20, 0xff,
583 R_41_LCR_BASE
+21, 0xff,
584 R_41_LCR_BASE
+22, 0xff,
585 R_58_PROGRAM_FRAMING_CODE
, 0x40,
586 R_59_H_OFF_FOR_SLICER
, 0x47,
587 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF
, 0x83,
591 R_02_INPUT_CNTL_1
, 0x84, /* input tuner -> input 4, amplifier active */
593 R_80_GLOBAL_CNTL_1
, 0x20, /* enable task B */
594 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0,
595 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0,
599 static int saa711x_odd_parity(u8 c
)
608 static int saa711x_decode_vps(u8
*dst
, u8
*p
)
610 static const u8 biphase_tbl
[] = {
611 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
612 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
613 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
614 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
615 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
616 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
617 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
618 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
619 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
620 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
621 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
622 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
623 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
624 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
625 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
626 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
627 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
628 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
629 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
630 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
631 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
632 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
633 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
634 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
635 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
636 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
637 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
638 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
639 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
640 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
641 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
642 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
647 for (i
= 0; i
< 2 * 13; i
+= 2) {
648 err
|= biphase_tbl
[p
[i
]] | biphase_tbl
[p
[i
+ 1]];
649 c
= (biphase_tbl
[p
[i
+ 1]] & 0xf) | ((biphase_tbl
[p
[i
]] & 0xf) << 4);
655 static int saa711x_decode_wss(u8
*p
)
657 static const int wss_bits
[8] = {
658 0, 0, 0, 1, 0, 1, 1, 1
660 unsigned char parity
;
664 for (i
= 0; i
< 16; i
++) {
665 int b1
= wss_bits
[p
[i
] & 7];
666 int b2
= wss_bits
[(p
[i
] >> 3) & 7];
673 parity
^= parity
>> 2;
674 parity
^= parity
>> 1;
682 static int saa711x_s_clock_freq(struct v4l2_subdev
*sd
, u32 freq
)
684 struct saa711x_state
*state
= to_state(sd
);
689 u8 acc
= 0; /* reg 0x3a, audio clock control */
691 /* Checks for chips that don't have audio clock (saa7111, saa7113) */
692 if (!saa711x_has_reg(state
->ident
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
))
695 v4l2_dbg(1, debug
, sd
, "set audio clock freq: %d\n", freq
);
698 if (freq
< 32000 || freq
> 48000)
701 /* hz is the refresh rate times 100 */
702 hz
= (state
->std
& V4L2_STD_525_60
) ? 5994 : 5000;
703 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
704 acpf
= (25600 * freq
) / hz
;
705 /* acni = (256 * freq * 2^23) / crystal_frequency =
706 (freq * 2^(8+23)) / crystal_frequency =
707 (freq << 31) / crystal_frequency */
710 do_div(f
, state
->crystal_freq
);
713 acpf
= acpf
* state
->cgcdiv
/ 16;
714 acni
= acni
* state
->cgcdiv
/ 16;
716 if (state
->cgcdiv
== 3)
722 saa711x_write(sd
, R_38_CLK_RATIO_AMXCLK_TO_ASCLK
, 0x03);
723 saa711x_write(sd
, R_39_CLK_RATIO_ASCLK_TO_ALRCLK
, 0x10);
724 saa711x_write(sd
, R_3A_AUD_CLK_GEN_BASIC_SETUP
, acc
);
726 saa711x_write(sd
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
, acpf
& 0xff);
727 saa711x_write(sd
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
+1,
729 saa711x_write(sd
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
+2,
730 (acpf
>> 16) & 0x03);
732 saa711x_write(sd
, R_34_AUD_MAST_CLK_NOMINAL_INC
, acni
& 0xff);
733 saa711x_write(sd
, R_34_AUD_MAST_CLK_NOMINAL_INC
+1, (acni
>> 8) & 0xff);
734 saa711x_write(sd
, R_34_AUD_MAST_CLK_NOMINAL_INC
+2, (acni
>> 16) & 0x3f);
735 state
->audclk_freq
= freq
;
739 static int saa711x_s_ctrl(struct v4l2_subdev
*sd
, struct v4l2_control
*ctrl
)
741 struct saa711x_state
*state
= to_state(sd
);
744 case V4L2_CID_BRIGHTNESS
:
745 if (ctrl
->value
< 0 || ctrl
->value
> 255) {
746 v4l2_err(sd
, "invalid brightness setting %d\n", ctrl
->value
);
750 state
->bright
= ctrl
->value
;
751 saa711x_write(sd
, R_0A_LUMA_BRIGHT_CNTL
, state
->bright
);
754 case V4L2_CID_CONTRAST
:
755 if (ctrl
->value
< 0 || ctrl
->value
> 127) {
756 v4l2_err(sd
, "invalid contrast setting %d\n", ctrl
->value
);
760 state
->contrast
= ctrl
->value
;
761 saa711x_write(sd
, R_0B_LUMA_CONTRAST_CNTL
, state
->contrast
);
764 case V4L2_CID_SATURATION
:
765 if (ctrl
->value
< 0 || ctrl
->value
> 127) {
766 v4l2_err(sd
, "invalid saturation setting %d\n", ctrl
->value
);
770 state
->sat
= ctrl
->value
;
771 saa711x_write(sd
, R_0C_CHROMA_SAT_CNTL
, state
->sat
);
775 if (ctrl
->value
< -128 || ctrl
->value
> 127) {
776 v4l2_err(sd
, "invalid hue setting %d\n", ctrl
->value
);
780 state
->hue
= ctrl
->value
;
781 saa711x_write(sd
, R_0D_CHROMA_HUE_CNTL
, state
->hue
);
791 static int saa711x_g_ctrl(struct v4l2_subdev
*sd
, struct v4l2_control
*ctrl
)
793 struct saa711x_state
*state
= to_state(sd
);
796 case V4L2_CID_BRIGHTNESS
:
797 ctrl
->value
= state
->bright
;
799 case V4L2_CID_CONTRAST
:
800 ctrl
->value
= state
->contrast
;
802 case V4L2_CID_SATURATION
:
803 ctrl
->value
= state
->sat
;
806 ctrl
->value
= state
->hue
;
815 static int saa711x_set_size(struct v4l2_subdev
*sd
, int width
, int height
)
817 struct saa711x_state
*state
= to_state(sd
);
821 int is_50hz
= state
->std
& V4L2_STD_625_50
;
822 int Vsrc
= is_50hz
? 576 : 480;
824 v4l2_dbg(1, debug
, sd
, "decoder set size to %ix%i\n", width
, height
);
826 /* FIXME need better bounds checking here */
827 if ((width
< 1) || (width
> 1440))
829 if ((height
< 1) || (height
> Vsrc
))
832 if (!saa711x_has_reg(state
->ident
, R_D0_B_HORIZ_PRESCALING
)) {
833 /* Decoder only supports 720 columns and 480 or 576 lines */
840 state
->width
= width
;
841 state
->height
= height
;
843 if (!saa711x_has_reg(state
->ident
, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
))
846 /* probably have a valid size, let's set it */
847 /* Set output width/height */
850 saa711x_write(sd
, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
,
851 (u8
) (width
& 0xff));
852 saa711x_write(sd
, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
,
853 (u8
) ((width
>> 8) & 0xff));
855 /* Vertical Scaling uses height/2 */
858 /* On 60Hz, it is using a higher Vertical Output Size */
860 res
+= (VRES_60HZ
- 480) >> 1;
863 saa711x_write(sd
, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH
,
865 saa711x_write(sd
, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB
,
866 (u8
) ((res
>> 8) & 0xff));
868 /* Scaling settings */
869 /* Hprescaler is floor(inres/outres) */
870 HPSC
= (int)(720 / width
);
871 /* 0 is not allowed (div. by zero) */
872 HPSC
= HPSC
? HPSC
: 1;
873 HFSC
= (int)((1024 * 720) / (HPSC
* width
));
874 /* FIXME hardcodes to "Task B"
875 * write H prescaler integer */
876 saa711x_write(sd
, R_D0_B_HORIZ_PRESCALING
,
879 v4l2_dbg(1, debug
, sd
, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC
, HFSC
);
880 /* write H fine-scaling (luminance) */
881 saa711x_write(sd
, R_D8_B_HORIZ_LUMA_SCALING_INC
,
883 saa711x_write(sd
, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB
,
884 (u8
) ((HFSC
>> 8) & 0xff));
885 /* write H fine-scaling (chrominance)
886 * must be lum/2, so i'll just bitshift :) */
887 saa711x_write(sd
, R_DC_B_HORIZ_CHROMA_SCALING
,
888 (u8
) ((HFSC
>> 1) & 0xff));
889 saa711x_write(sd
, R_DD_B_HORIZ_CHROMA_SCALING_MSB
,
890 (u8
) ((HFSC
>> 9) & 0xff));
892 VSCY
= (int)((1024 * Vsrc
) / height
);
893 v4l2_dbg(1, debug
, sd
, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc
, VSCY
);
895 /* Correct Contrast and Luminance */
896 saa711x_write(sd
, R_D5_B_LUMA_CONTRAST_CNTL
,
897 (u8
) (64 * 1024 / VSCY
));
898 saa711x_write(sd
, R_D6_B_CHROMA_SATURATION_CNTL
,
899 (u8
) (64 * 1024 / VSCY
));
901 /* write V fine-scaling (luminance) */
902 saa711x_write(sd
, R_E0_B_VERT_LUMA_SCALING_INC
,
904 saa711x_write(sd
, R_E1_B_VERT_LUMA_SCALING_INC_MSB
,
905 (u8
) ((VSCY
>> 8) & 0xff));
906 /* write V fine-scaling (chrominance) */
907 saa711x_write(sd
, R_E2_B_VERT_CHROMA_SCALING_INC
,
909 saa711x_write(sd
, R_E3_B_VERT_CHROMA_SCALING_INC_MSB
,
910 (u8
) ((VSCY
>> 8) & 0xff));
912 saa711x_writeregs(sd
, saa7115_cfg_reset_scaler
);
914 /* Activates task "B" */
915 saa711x_write(sd
, R_80_GLOBAL_CNTL_1
,
916 saa711x_read(sd
, R_80_GLOBAL_CNTL_1
) | 0x20);
921 static void saa711x_set_v4lstd(struct v4l2_subdev
*sd
, v4l2_std_id std
)
923 struct saa711x_state
*state
= to_state(sd
);
925 /* Prevent unnecessary standard changes. During a standard
926 change the I-Port is temporarily disabled. Any devices
927 reading from that port can get confused.
928 Note that s_std is also used to switch from
929 radio to TV mode, so if a s_std is broadcast to
930 all I2C devices then you do not want to have an unwanted
932 if (std
== state
->std
)
937 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
938 if (std
& V4L2_STD_525_60
) {
939 v4l2_dbg(1, debug
, sd
, "decoder set standard 60 Hz\n");
940 saa711x_writeregs(sd
, saa7115_cfg_60hz_video
);
941 saa711x_set_size(sd
, 720, 480);
943 v4l2_dbg(1, debug
, sd
, "decoder set standard 50 Hz\n");
944 saa711x_writeregs(sd
, saa7115_cfg_50hz_video
);
945 saa711x_set_size(sd
, 720, 576);
948 /* Register 0E - Bits D6-D4 on NO-AUTO mode
949 (SAA7111 and SAA7113 doesn't have auto mode)
950 50 Hz / 625 lines 60 Hz / 525 lines
951 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz)
952 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz)
953 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
954 011 NTSC N (3.58MHz) PAL M (3.58MHz)
955 100 reserved NTSC-Japan (3.58MHz)
957 if (state
->ident
== V4L2_IDENT_SAA7111
||
958 state
->ident
== V4L2_IDENT_SAA7113
) {
959 u8 reg
= saa711x_read(sd
, R_0E_CHROMA_CNTL_1
) & 0x8f;
961 if (std
== V4L2_STD_PAL_M
) {
963 } else if (std
== V4L2_STD_PAL_Nc
) {
965 } else if (std
== V4L2_STD_PAL_60
) {
967 } else if (std
== V4L2_STD_NTSC_M_JP
) {
969 } else if (std
& V4L2_STD_SECAM
) {
972 saa711x_write(sd
, R_0E_CHROMA_CNTL_1
, reg
);
974 /* restart task B if needed */
975 int taskb
= saa711x_read(sd
, R_80_GLOBAL_CNTL_1
) & 0x10;
977 if (taskb
&& state
->ident
== V4L2_IDENT_SAA7114
) {
978 saa711x_writeregs(sd
, saa7115_cfg_vbi_on
);
981 /* switch audio mode too! */
982 saa711x_s_clock_freq(sd
, state
->audclk_freq
);
986 /* setup the sliced VBI lcr registers according to the sliced VBI format */
987 static void saa711x_set_lcr(struct v4l2_subdev
*sd
, struct v4l2_sliced_vbi_format
*fmt
)
989 struct saa711x_state
*state
= to_state(sd
);
990 int is_50hz
= (state
->std
& V4L2_STD_625_50
);
995 /* saa7113/7114/7118 VBI support are experimental */
996 if (!saa711x_has_reg(state
->ident
, R_41_LCR_BASE
))
1000 /* SAA7113 and SAA7118 also should support VBI - Need testing */
1001 if (state
->ident
!= V4L2_IDENT_SAA7115
)
1005 for (i
= 0; i
<= 23; i
++)
1011 for (i
= 6; i
<= 23; i
++)
1014 for (i
= 10; i
<= 21; i
++)
1018 /* first clear lines that cannot be captured */
1020 for (i
= 0; i
<= 5; i
++)
1021 fmt
->service_lines
[0][i
] =
1022 fmt
->service_lines
[1][i
] = 0;
1025 for (i
= 0; i
<= 9; i
++)
1026 fmt
->service_lines
[0][i
] =
1027 fmt
->service_lines
[1][i
] = 0;
1028 for (i
= 22; i
<= 23; i
++)
1029 fmt
->service_lines
[0][i
] =
1030 fmt
->service_lines
[1][i
] = 0;
1033 /* Now set the lcr values according to the specified service */
1034 for (i
= 6; i
<= 23; i
++) {
1036 for (x
= 0; x
<= 1; x
++) {
1037 switch (fmt
->service_lines
[1-x
][i
]) {
1039 lcr
[i
] |= 0xf << (4 * x
);
1041 case V4L2_SLICED_TELETEXT_B
:
1042 lcr
[i
] |= 1 << (4 * x
);
1044 case V4L2_SLICED_CAPTION_525
:
1045 lcr
[i
] |= 4 << (4 * x
);
1047 case V4L2_SLICED_WSS_625
:
1048 lcr
[i
] |= 5 << (4 * x
);
1050 case V4L2_SLICED_VPS
:
1051 lcr
[i
] |= 7 << (4 * x
);
1058 /* write the lcr registers */
1059 for (i
= 2; i
<= 23; i
++) {
1060 saa711x_write(sd
, i
- 2 + R_41_LCR_BASE
, lcr
[i
]);
1063 /* enable/disable raw VBI capturing */
1064 saa711x_writeregs(sd
, fmt
== NULL
?
1065 saa7115_cfg_vbi_on
:
1066 saa7115_cfg_vbi_off
);
1069 static int saa711x_g_fmt(struct v4l2_subdev
*sd
, struct v4l2_format
*fmt
)
1071 static u16 lcr2vbi
[] = {
1072 0, V4L2_SLICED_TELETEXT_B
, 0, /* 1 */
1073 0, V4L2_SLICED_CAPTION_525
, /* 4 */
1074 V4L2_SLICED_WSS_625
, 0, /* 5 */
1075 V4L2_SLICED_VPS
, 0, 0, 0, 0, /* 7 */
1078 struct v4l2_sliced_vbi_format
*sliced
= &fmt
->fmt
.sliced
;
1081 if (fmt
->type
!= V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
)
1083 memset(sliced
, 0, sizeof(*sliced
));
1084 /* done if using raw VBI */
1085 if (saa711x_read(sd
, R_80_GLOBAL_CNTL_1
) & 0x10)
1087 for (i
= 2; i
<= 23; i
++) {
1088 u8 v
= saa711x_read(sd
, i
- 2 + R_41_LCR_BASE
);
1090 sliced
->service_lines
[0][i
] = lcr2vbi
[v
>> 4];
1091 sliced
->service_lines
[1][i
] = lcr2vbi
[v
& 0xf];
1092 sliced
->service_set
|=
1093 sliced
->service_lines
[0][i
] | sliced
->service_lines
[1][i
];
1098 static int saa711x_s_fmt(struct v4l2_subdev
*sd
, struct v4l2_format
*fmt
)
1100 if (fmt
->type
== V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
) {
1101 saa711x_set_lcr(sd
, &fmt
->fmt
.sliced
);
1104 if (fmt
->type
== V4L2_BUF_TYPE_VBI_CAPTURE
) {
1105 saa711x_set_lcr(sd
, NULL
);
1108 if (fmt
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1111 return saa711x_set_size(sd
, fmt
->fmt
.pix
.width
, fmt
->fmt
.pix
.height
);
1114 /* Decode the sliced VBI data stream as created by the saa7115.
1115 The format is described in the saa7115 datasheet in Tables 25 and 26
1117 The current implementation uses SAV/EAV codes and not the ancillary data
1118 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1120 static int saa711x_decode_vbi_line(struct v4l2_subdev
*sd
, struct v4l2_decode_vbi_line
*vbi
)
1122 struct saa711x_state
*state
= to_state(sd
);
1123 static const char vbi_no_data_pattern
[] = {
1124 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1128 int id1
, id2
; /* the ID1 and ID2 bytes from the internal header */
1130 vbi
->type
= 0; /* mark result as a failure */
1133 /* Note: the field bit is inverted for 60 Hz video */
1134 if (state
->std
& V4L2_STD_525_60
)
1137 /* Skip internal header, p now points to the start of the payload */
1141 /* calculate field and line number of the VBI packet (1-23) */
1142 vbi
->is_second_field
= ((id1
& 0x40) != 0);
1143 vbi
->line
= (id1
& 0x3f) << 3;
1144 vbi
->line
|= (id2
& 0x70) >> 4;
1146 /* Obtain data type */
1149 /* If the VBI slicer does not detect any signal it will fill up
1150 the payload buffer with 0xa0 bytes. */
1151 if (!memcmp(p
, vbi_no_data_pattern
, sizeof(vbi_no_data_pattern
)))
1154 /* decode payloads */
1157 vbi
->type
= V4L2_SLICED_TELETEXT_B
;
1160 if (!saa711x_odd_parity(p
[0]) || !saa711x_odd_parity(p
[1]))
1162 vbi
->type
= V4L2_SLICED_CAPTION_525
;
1165 wss
= saa711x_decode_wss(p
);
1170 vbi
->type
= V4L2_SLICED_WSS_625
;
1173 if (saa711x_decode_vps(p
, p
) != 0)
1175 vbi
->type
= V4L2_SLICED_VPS
;
1183 /* ============ SAA7115 AUDIO settings (end) ============= */
1185 static int saa711x_g_tuner(struct v4l2_subdev
*sd
, struct v4l2_tuner
*vt
)
1187 struct saa711x_state
*state
= to_state(sd
);
1192 status
= saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
);
1194 v4l2_dbg(1, debug
, sd
, "status: 0x%02x\n", status
);
1195 vt
->signal
= ((status
& (1 << 6)) == 0) ? 0xffff : 0x0;
1199 static int saa711x_queryctrl(struct v4l2_subdev
*sd
, struct v4l2_queryctrl
*qc
)
1202 case V4L2_CID_BRIGHTNESS
:
1203 return v4l2_ctrl_query_fill(qc
, 0, 255, 1, 128);
1204 case V4L2_CID_CONTRAST
:
1205 case V4L2_CID_SATURATION
:
1206 return v4l2_ctrl_query_fill(qc
, 0, 127, 1, 64);
1208 return v4l2_ctrl_query_fill(qc
, -128, 127, 1, 0);
1214 static int saa711x_s_std(struct v4l2_subdev
*sd
, v4l2_std_id std
)
1216 struct saa711x_state
*state
= to_state(sd
);
1219 saa711x_set_v4lstd(sd
, std
);
1223 static int saa711x_s_radio(struct v4l2_subdev
*sd
)
1225 struct saa711x_state
*state
= to_state(sd
);
1231 static int saa711x_s_routing(struct v4l2_subdev
*sd
,
1232 u32 input
, u32 output
, u32 config
)
1234 struct saa711x_state
*state
= to_state(sd
);
1235 u8 mask
= (state
->ident
== V4L2_IDENT_SAA7111
) ? 0xf8 : 0xf0;
1237 v4l2_dbg(1, debug
, sd
, "decoder set input %d output %d\n",
1240 /* saa7111/3 does not have these inputs */
1241 if ((state
->ident
== V4L2_IDENT_SAA7113
||
1242 state
->ident
== V4L2_IDENT_SAA7111
) &&
1243 (input
== SAA7115_COMPOSITE4
||
1244 input
== SAA7115_COMPOSITE5
)) {
1247 if (input
> SAA7115_SVIDEO3
)
1249 if (output
> SAA7115_IPORT_ON
)
1251 if (state
->input
== input
&& state
->output
== output
)
1253 v4l2_dbg(1, debug
, sd
, "now setting %s input %s output\n",
1254 (input
>= SAA7115_SVIDEO0
) ? "S-Video" : "Composite",
1255 (output
== SAA7115_IPORT_ON
) ? "iport on" : "iport off");
1256 state
->input
= input
;
1258 /* saa7111 has slightly different input numbering */
1259 if (state
->ident
== V4L2_IDENT_SAA7111
) {
1260 if (input
>= SAA7115_COMPOSITE4
)
1262 /* saa7111 specific */
1263 saa711x_write(sd
, R_10_CHROMA_CNTL_2
,
1264 (saa711x_read(sd
, R_10_CHROMA_CNTL_2
) & 0x3f) |
1265 ((output
& 0xc0) ^ 0x40));
1266 saa711x_write(sd
, R_13_RT_X_PORT_OUT_CNTL
,
1267 (saa711x_read(sd
, R_13_RT_X_PORT_OUT_CNTL
) & 0xf0) |
1268 ((output
& 2) ? 0x0a : 0));
1272 saa711x_write(sd
, R_02_INPUT_CNTL_1
,
1273 (saa711x_read(sd
, R_02_INPUT_CNTL_1
) & mask
) |
1276 /* bypass chrominance trap for S-Video modes */
1277 saa711x_write(sd
, R_09_LUMA_CNTL
,
1278 (saa711x_read(sd
, R_09_LUMA_CNTL
) & 0x7f) |
1279 (state
->input
>= SAA7115_SVIDEO0
? 0x80 : 0x0));
1281 state
->output
= output
;
1282 if (state
->ident
== V4L2_IDENT_SAA7114
||
1283 state
->ident
== V4L2_IDENT_SAA7115
) {
1284 saa711x_write(sd
, R_83_X_PORT_I_O_ENA_AND_OUT_CLK
,
1285 (saa711x_read(sd
, R_83_X_PORT_I_O_ENA_AND_OUT_CLK
) & 0xfe) |
1286 (state
->output
& 0x01));
1291 static int saa711x_s_gpio(struct v4l2_subdev
*sd
, u32 val
)
1293 struct saa711x_state
*state
= to_state(sd
);
1295 if (state
->ident
!= V4L2_IDENT_SAA7111
)
1297 saa711x_write(sd
, 0x11, (saa711x_read(sd
, 0x11) & 0x7f) |
1302 static int saa711x_s_stream(struct v4l2_subdev
*sd
, int enable
)
1304 struct saa711x_state
*state
= to_state(sd
);
1306 v4l2_dbg(1, debug
, sd
, "%s output\n",
1307 enable
? "enable" : "disable");
1309 if (state
->enable
== enable
)
1311 state
->enable
= enable
;
1312 if (!saa711x_has_reg(state
->ident
, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
))
1314 saa711x_write(sd
, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, state
->enable
);
1318 static int saa711x_s_crystal_freq(struct v4l2_subdev
*sd
, u32 freq
, u32 flags
)
1320 struct saa711x_state
*state
= to_state(sd
);
1322 if (freq
!= SAA7115_FREQ_32_11_MHZ
&& freq
!= SAA7115_FREQ_24_576_MHZ
)
1324 state
->crystal_freq
= freq
;
1325 state
->cgcdiv
= (flags
& SAA7115_FREQ_FL_CGCDIV
) ? 3 : 4;
1326 state
->ucgc
= (flags
& SAA7115_FREQ_FL_UCGC
) ? 1 : 0;
1327 state
->apll
= (flags
& SAA7115_FREQ_FL_APLL
) ? 1 : 0;
1328 saa711x_s_clock_freq(sd
, state
->audclk_freq
);
1332 static int saa711x_reset(struct v4l2_subdev
*sd
, u32 val
)
1334 v4l2_dbg(1, debug
, sd
, "decoder RESET\n");
1335 saa711x_writeregs(sd
, saa7115_cfg_reset_scaler
);
1339 static int saa711x_g_vbi_data(struct v4l2_subdev
*sd
, struct v4l2_sliced_vbi_data
*data
)
1341 /* Note: the internal field ID is inverted for NTSC,
1342 so data->field 0 maps to the saa7115 even field,
1343 whereas for PAL it maps to the saa7115 odd field. */
1345 case V4L2_SLICED_WSS_625
:
1346 if (saa711x_read(sd
, 0x6b) & 0xc0)
1348 data
->data
[0] = saa711x_read(sd
, 0x6c);
1349 data
->data
[1] = saa711x_read(sd
, 0x6d);
1351 case V4L2_SLICED_CAPTION_525
:
1352 if (data
->field
== 0) {
1354 if (saa711x_read(sd
, 0x66) & 0x30)
1356 data
->data
[0] = saa711x_read(sd
, 0x69);
1357 data
->data
[1] = saa711x_read(sd
, 0x6a);
1361 if (saa711x_read(sd
, 0x66) & 0xc0)
1363 data
->data
[0] = saa711x_read(sd
, 0x67);
1364 data
->data
[1] = saa711x_read(sd
, 0x68);
1371 static int saa711x_querystd(struct v4l2_subdev
*sd
, v4l2_std_id
*std
)
1373 struct saa711x_state
*state
= to_state(sd
);
1376 *std
= V4L2_STD_ALL
;
1377 if (state
->ident
!= V4L2_IDENT_SAA7115
)
1379 reg1e
= saa711x_read(sd
, R_1E_STATUS_BYTE_1_VD_DEC
);
1381 switch (reg1e
& 0x03) {
1383 *std
= V4L2_STD_NTSC
;
1386 *std
= V4L2_STD_PAL
;
1389 *std
= V4L2_STD_SECAM
;
1397 static int saa711x_g_input_status(struct v4l2_subdev
*sd
, u32
*status
)
1399 struct saa711x_state
*state
= to_state(sd
);
1403 *status
= V4L2_IN_ST_NO_SIGNAL
;
1404 if (state
->ident
== V4L2_IDENT_SAA7115
)
1405 reg1e
= saa711x_read(sd
, R_1E_STATUS_BYTE_1_VD_DEC
);
1406 reg1f
= saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
);
1407 if ((reg1f
& 0xc1) == 0x81 && (reg1e
& 0xc0) == 0x80)
1412 #ifdef CONFIG_VIDEO_ADV_DEBUG
1413 static int saa711x_g_register(struct v4l2_subdev
*sd
, struct v4l2_dbg_register
*reg
)
1415 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
1417 if (!v4l2_chip_match_i2c_client(client
, ®
->match
))
1419 if (!capable(CAP_SYS_ADMIN
))
1421 reg
->val
= saa711x_read(sd
, reg
->reg
& 0xff);
1426 static int saa711x_s_register(struct v4l2_subdev
*sd
, struct v4l2_dbg_register
*reg
)
1428 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
1430 if (!v4l2_chip_match_i2c_client(client
, ®
->match
))
1432 if (!capable(CAP_SYS_ADMIN
))
1434 saa711x_write(sd
, reg
->reg
& 0xff, reg
->val
& 0xff);
1439 static int saa711x_g_chip_ident(struct v4l2_subdev
*sd
, struct v4l2_dbg_chip_ident
*chip
)
1441 struct saa711x_state
*state
= to_state(sd
);
1442 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
1444 return v4l2_chip_ident_i2c_client(client
, chip
, state
->ident
, 0);
1447 static int saa711x_log_status(struct v4l2_subdev
*sd
)
1449 struct saa711x_state
*state
= to_state(sd
);
1454 v4l2_info(sd
, "Audio frequency: %d Hz\n", state
->audclk_freq
);
1455 if (state
->ident
!= V4L2_IDENT_SAA7115
) {
1456 /* status for the saa7114 */
1457 reg1f
= saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
);
1458 signalOk
= (reg1f
& 0xc1) == 0x81;
1459 v4l2_info(sd
, "Video signal: %s\n", signalOk
? "ok" : "bad");
1460 v4l2_info(sd
, "Frequency: %s\n", (reg1f
& 0x20) ? "60 Hz" : "50 Hz");
1464 /* status for the saa7115 */
1465 reg1e
= saa711x_read(sd
, R_1E_STATUS_BYTE_1_VD_DEC
);
1466 reg1f
= saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
);
1468 signalOk
= (reg1f
& 0xc1) == 0x81 && (reg1e
& 0xc0) == 0x80;
1469 vcr
= !(reg1f
& 0x10);
1471 if (state
->input
>= 6)
1472 v4l2_info(sd
, "Input: S-Video %d\n", state
->input
- 6);
1474 v4l2_info(sd
, "Input: Composite %d\n", state
->input
);
1475 v4l2_info(sd
, "Video signal: %s\n", signalOk
? (vcr
? "VCR" : "broadcast/DVD") : "bad");
1476 v4l2_info(sd
, "Frequency: %s\n", (reg1f
& 0x20) ? "60 Hz" : "50 Hz");
1478 switch (reg1e
& 0x03) {
1480 v4l2_info(sd
, "Detected format: NTSC\n");
1483 v4l2_info(sd
, "Detected format: PAL\n");
1486 v4l2_info(sd
, "Detected format: SECAM\n");
1489 v4l2_info(sd
, "Detected format: BW/No color\n");
1492 v4l2_info(sd
, "Width, Height: %d, %d\n", state
->width
, state
->height
);
1496 /* ----------------------------------------------------------------------- */
1498 static const struct v4l2_subdev_core_ops saa711x_core_ops
= {
1499 .log_status
= saa711x_log_status
,
1500 .g_chip_ident
= saa711x_g_chip_ident
,
1501 .g_ctrl
= saa711x_g_ctrl
,
1502 .s_ctrl
= saa711x_s_ctrl
,
1503 .queryctrl
= saa711x_queryctrl
,
1504 .s_std
= saa711x_s_std
,
1505 .reset
= saa711x_reset
,
1506 .s_gpio
= saa711x_s_gpio
,
1507 #ifdef CONFIG_VIDEO_ADV_DEBUG
1508 .g_register
= saa711x_g_register
,
1509 .s_register
= saa711x_s_register
,
1513 static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops
= {
1514 .s_radio
= saa711x_s_radio
,
1515 .g_tuner
= saa711x_g_tuner
,
1518 static const struct v4l2_subdev_audio_ops saa711x_audio_ops
= {
1519 .s_clock_freq
= saa711x_s_clock_freq
,
1522 static const struct v4l2_subdev_video_ops saa711x_video_ops
= {
1523 .s_routing
= saa711x_s_routing
,
1524 .s_crystal_freq
= saa711x_s_crystal_freq
,
1525 .g_fmt
= saa711x_g_fmt
,
1526 .s_fmt
= saa711x_s_fmt
,
1527 .g_vbi_data
= saa711x_g_vbi_data
,
1528 .decode_vbi_line
= saa711x_decode_vbi_line
,
1529 .s_stream
= saa711x_s_stream
,
1530 .querystd
= saa711x_querystd
,
1531 .g_input_status
= saa711x_g_input_status
,
1534 static const struct v4l2_subdev_ops saa711x_ops
= {
1535 .core
= &saa711x_core_ops
,
1536 .tuner
= &saa711x_tuner_ops
,
1537 .audio
= &saa711x_audio_ops
,
1538 .video
= &saa711x_video_ops
,
1541 /* ----------------------------------------------------------------------- */
1543 static int saa711x_probe(struct i2c_client
*client
,
1544 const struct i2c_device_id
*id
)
1546 struct saa711x_state
*state
;
1547 struct v4l2_subdev
*sd
;
1551 int autodetect
= !id
|| id
->driver_data
== 1;
1553 /* Check if the adapter supports the needed features */
1554 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_SMBUS_BYTE_DATA
))
1557 for (i
= 0; i
< 0x0f; i
++) {
1558 i2c_smbus_write_byte_data(client
, 0, i
);
1559 name
[i
] = (i2c_smbus_read_byte_data(client
, 0) & 0x0f) + '0';
1561 name
[i
] += 'a' - '9' - 1;
1567 /* Check whether this chip is part of the saa711x series */
1568 if (memcmp(name
, "1f711", 5)) {
1569 v4l_dbg(1, debug
, client
, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
1570 client
->addr
<< 1, name
);
1575 if (!autodetect
&& id
->name
[6] != chip_id
) {
1576 v4l_warn(client
, "found saa711%c while %s was expected\n",
1579 snprintf(client
->name
, sizeof(client
->name
), "saa711%c", chip_id
);
1580 v4l_info(client
, "saa711%c found (%s) @ 0x%x (%s)\n", chip_id
, name
,
1581 client
->addr
<< 1, client
->adapter
->name
);
1583 state
= kzalloc(sizeof(struct saa711x_state
), GFP_KERNEL
);
1587 v4l2_i2c_subdev_init(sd
, client
, &saa711x_ops
);
1589 state
->output
= SAA7115_IPORT_ON
;
1592 state
->bright
= 128;
1593 state
->contrast
= 64;
1598 state
->ident
= V4L2_IDENT_SAA7111
;
1601 state
->ident
= V4L2_IDENT_SAA7113
;
1604 state
->ident
= V4L2_IDENT_SAA7114
;
1607 state
->ident
= V4L2_IDENT_SAA7115
;
1610 state
->ident
= V4L2_IDENT_SAA7118
;
1613 state
->ident
= V4L2_IDENT_SAA7111
;
1614 v4l2_info(sd
, "WARNING: Chip is not known - Falling back to saa7111\n");
1618 state
->audclk_freq
= 48000;
1620 v4l2_dbg(1, debug
, sd
, "writing init values\n");
1622 /* init to 60hz/48khz */
1623 state
->crystal_freq
= SAA7115_FREQ_24_576_MHZ
;
1624 switch (state
->ident
) {
1625 case V4L2_IDENT_SAA7111
:
1626 saa711x_writeregs(sd
, saa7111_init
);
1628 case V4L2_IDENT_SAA7113
:
1629 saa711x_writeregs(sd
, saa7113_init
);
1632 state
->crystal_freq
= SAA7115_FREQ_32_11_MHZ
;
1633 saa711x_writeregs(sd
, saa7115_init_auto_input
);
1635 if (state
->ident
!= V4L2_IDENT_SAA7111
)
1636 saa711x_writeregs(sd
, saa7115_init_misc
);
1637 saa711x_set_v4lstd(sd
, V4L2_STD_NTSC
);
1639 v4l2_dbg(1, debug
, sd
, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1640 saa711x_read(sd
, R_1E_STATUS_BYTE_1_VD_DEC
),
1641 saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
));
1645 /* ----------------------------------------------------------------------- */
1647 static int saa711x_remove(struct i2c_client
*client
)
1649 struct v4l2_subdev
*sd
= i2c_get_clientdata(client
);
1651 v4l2_device_unregister_subdev(sd
);
1652 kfree(to_state(sd
));
1656 static const struct i2c_device_id saa7115_id
[] = {
1657 { "saa7115_auto", 1 }, /* autodetect */
1665 MODULE_DEVICE_TABLE(i2c
, saa7115_id
);
1667 static struct v4l2_i2c_driver_data v4l2_i2c_data
= {
1669 .probe
= saa711x_probe
,
1670 .remove
= saa711x_remove
,
1671 .id_table
= saa7115_id
,