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-ctrls.h>
49 #include <media/saa7115.h>
50 #include <asm/div64.h>
52 #define VRES_60HZ (480+16)
54 MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
55 MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
56 "Hans Verkuil, Mauro Carvalho Chehab");
57 MODULE_LICENSE("GPL");
60 module_param(debug
, bool, 0644);
62 MODULE_PARM_DESC(debug
, "Debug level (0-1)");
75 struct saa711x_state
{
76 struct v4l2_subdev sd
;
77 struct v4l2_ctrl_handler hdl
;
80 /* chroma gain control cluster */
81 struct v4l2_ctrl
*agc
;
82 struct v4l2_ctrl
*gain
;
92 enum saa711x_model ident
;
101 static inline struct saa711x_state
*to_state(struct v4l2_subdev
*sd
)
103 return container_of(sd
, struct saa711x_state
, sd
);
106 static inline struct v4l2_subdev
*to_sd(struct v4l2_ctrl
*ctrl
)
108 return &container_of(ctrl
->handler
, struct saa711x_state
, hdl
)->sd
;
111 /* ----------------------------------------------------------------------- */
113 static inline int saa711x_write(struct v4l2_subdev
*sd
, u8 reg
, u8 value
)
115 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
117 return i2c_smbus_write_byte_data(client
, reg
, value
);
120 /* Sanity routine to check if a register is present */
121 static int saa711x_has_reg(const int id
, const u8 reg
)
124 return reg
< 0x20 && reg
!= 0x01 && reg
!= 0x0f &&
125 (reg
< 0x13 || reg
> 0x19) && reg
!= 0x1d && reg
!= 0x1e;
127 return reg
< 0x20 && reg
!= 0x01 && reg
!= 0x0f &&
128 reg
!= 0x14 && reg
!= 0x18 && reg
!= 0x19 &&
129 reg
!= 0x1d && reg
!= 0x1e;
131 /* common for saa7113/4/5/8 */
132 if (unlikely((reg
>= 0x3b && reg
<= 0x3f) || reg
== 0x5c || reg
== 0x5f ||
133 reg
== 0xa3 || reg
== 0xa7 || reg
== 0xab || reg
== 0xaf || (reg
>= 0xb5 && reg
<= 0xb7) ||
134 reg
== 0xd3 || reg
== 0xd7 || reg
== 0xdb || reg
== 0xdf || (reg
>= 0xe5 && reg
<= 0xe7) ||
135 reg
== 0x82 || (reg
>= 0x89 && reg
<= 0x8e)))
140 return reg
!= 0x14 && (reg
< 0x18 || reg
> 0x1e) && reg
< 0x20;
142 return reg
!= 0x14 && (reg
< 0x18 || reg
> 0x1e) && (reg
< 0x20 || reg
> 0x3f) &&
143 reg
!= 0x5d && reg
< 0x63;
145 return (reg
< 0x1a || reg
> 0x1e) && (reg
< 0x20 || reg
> 0x2f) &&
146 (reg
< 0x63 || reg
> 0x7f) && reg
!= 0x33 && reg
!= 0x37 &&
147 reg
!= 0x81 && reg
< 0xf0;
149 return (reg
< 0x20 || reg
> 0x2f) && reg
!= 0x65 && (reg
< 0xfc || reg
> 0xfe);
151 return (reg
< 0x1a || reg
> 0x1d) && (reg
< 0x20 || reg
> 0x22) &&
152 (reg
< 0x26 || reg
> 0x28) && reg
!= 0x33 && reg
!= 0x37 &&
153 (reg
< 0x63 || reg
> 0x7f) && reg
!= 0x81 && reg
< 0xf0;
158 static int saa711x_writeregs(struct v4l2_subdev
*sd
, const unsigned char *regs
)
160 struct saa711x_state
*state
= to_state(sd
);
161 unsigned char reg
, data
;
163 while (*regs
!= 0x00) {
167 /* According with datasheets, reserved regs should be
168 filled with 0 - seems better not to touch on they */
169 if (saa711x_has_reg(state
->ident
, reg
)) {
170 if (saa711x_write(sd
, reg
, data
) < 0)
173 v4l2_dbg(1, debug
, sd
, "tried to access reserved reg 0x%02x\n", reg
);
179 static inline int saa711x_read(struct v4l2_subdev
*sd
, u8 reg
)
181 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
183 return i2c_smbus_read_byte_data(client
, reg
);
186 /* ----------------------------------------------------------------------- */
188 /* SAA7111 initialization table */
189 static const unsigned char saa7111_init
[] = {
190 R_01_INC_DELAY
, 0x00, /* reserved */
193 R_02_INPUT_CNTL_1
, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */
194 R_03_INPUT_CNTL_2
, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
195 * GAFIX=0, GAI1=256, GAI2=256 */
196 R_04_INPUT_CNTL_3
, 0x00, /* GAI1=256 */
197 R_05_INPUT_CNTL_4
, 0x00, /* GAI2=256 */
200 R_06_H_SYNC_START
, 0xf3, /* HSB at 13(50Hz) / 17(60Hz)
201 * pixels after end of last line */
202 R_07_H_SYNC_STOP
, 0xe8, /* HSS seems to be needed to
203 * work with NTSC, too */
204 R_08_SYNC_CNTL
, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0,
205 * VTRC=1, HPLL=0, VNOI=0 */
206 R_09_LUMA_CNTL
, 0x01, /* BYPS=0, PREF=0, BPSS=0,
207 * VBLB=0, UPTCV=0, APER=1 */
208 R_0A_LUMA_BRIGHT_CNTL
, 0x80,
209 R_0B_LUMA_CONTRAST_CNTL
, 0x47, /* 0b - CONT=1.109 */
210 R_0C_CHROMA_SAT_CNTL
, 0x40,
211 R_0D_CHROMA_HUE_CNTL
, 0x00,
212 R_0E_CHROMA_CNTL_1
, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
214 R_0F_CHROMA_GAIN_CNTL
, 0x00, /* reserved */
215 R_10_CHROMA_CNTL_2
, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
216 R_11_MODE_DELAY_CNTL
, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
217 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
218 R_12_RT_SIGNAL_CNTL
, 0x00, /* 12 - output control 2 */
219 R_13_RT_X_PORT_OUT_CNTL
, 0x00, /* 13 - output control 3 */
220 R_14_ANAL_ADC_COMPAT_CNTL
, 0x00,
221 R_15_VGATE_START_FID_CHG
, 0x00,
222 R_16_VGATE_STOP
, 0x00,
223 R_17_MISC_VGATE_CONF_AND_MSB
, 0x00,
229 * This table has one illegal value, and some values that are not
230 * correct according to the datasheet initialization table.
232 * If you need a table with legal/default values tell the driver in
233 * i2c_board_info.platform_data, and you will get the gm7113c_init
237 /* SAA7113 Init codes */
238 static const unsigned char saa7113_init
[] = {
239 R_01_INC_DELAY
, 0x08,
240 R_02_INPUT_CNTL_1
, 0xc2,
241 R_03_INPUT_CNTL_2
, 0x30,
242 R_04_INPUT_CNTL_3
, 0x00,
243 R_05_INPUT_CNTL_4
, 0x00,
244 R_06_H_SYNC_START
, 0x89, /* Illegal value -119,
245 * min. value = -108 (0x94) */
246 R_07_H_SYNC_STOP
, 0x0d,
247 R_08_SYNC_CNTL
, 0x88, /* Not datasheet default.
248 * HTC = VTR mode, should be 0x98 */
249 R_09_LUMA_CNTL
, 0x01,
250 R_0A_LUMA_BRIGHT_CNTL
, 0x80,
251 R_0B_LUMA_CONTRAST_CNTL
, 0x47,
252 R_0C_CHROMA_SAT_CNTL
, 0x40,
253 R_0D_CHROMA_HUE_CNTL
, 0x00,
254 R_0E_CHROMA_CNTL_1
, 0x01,
255 R_0F_CHROMA_GAIN_CNTL
, 0x2a,
256 R_10_CHROMA_CNTL_2
, 0x08, /* Not datsheet default.
257 * VRLN enabled, should be 0x00 */
258 R_11_MODE_DELAY_CNTL
, 0x0c,
259 R_12_RT_SIGNAL_CNTL
, 0x07, /* Not datasheet default,
261 R_13_RT_X_PORT_OUT_CNTL
, 0x00,
262 R_14_ANAL_ADC_COMPAT_CNTL
, 0x00,
263 R_15_VGATE_START_FID_CHG
, 0x00,
264 R_16_VGATE_STOP
, 0x00,
265 R_17_MISC_VGATE_CONF_AND_MSB
, 0x00,
271 * GM7113C is a clone of the SAA7113 chip
272 * This init table is copied out of the saa7113 datasheet.
273 * In R_08 we enable "Automatic Field Detection" [AUFD],
274 * this is disabled when saa711x_set_v4lstd is called.
276 static const unsigned char gm7113c_init
[] = {
277 R_01_INC_DELAY
, 0x08,
278 R_02_INPUT_CNTL_1
, 0xc0,
279 R_03_INPUT_CNTL_2
, 0x33,
280 R_04_INPUT_CNTL_3
, 0x00,
281 R_05_INPUT_CNTL_4
, 0x00,
282 R_06_H_SYNC_START
, 0xe9,
283 R_07_H_SYNC_STOP
, 0x0d,
284 R_08_SYNC_CNTL
, 0x98,
285 R_09_LUMA_CNTL
, 0x01,
286 R_0A_LUMA_BRIGHT_CNTL
, 0x80,
287 R_0B_LUMA_CONTRAST_CNTL
, 0x47,
288 R_0C_CHROMA_SAT_CNTL
, 0x40,
289 R_0D_CHROMA_HUE_CNTL
, 0x00,
290 R_0E_CHROMA_CNTL_1
, 0x01,
291 R_0F_CHROMA_GAIN_CNTL
, 0x2a,
292 R_10_CHROMA_CNTL_2
, 0x00,
293 R_11_MODE_DELAY_CNTL
, 0x0c,
294 R_12_RT_SIGNAL_CNTL
, 0x01,
295 R_13_RT_X_PORT_OUT_CNTL
, 0x00,
296 R_14_ANAL_ADC_COMPAT_CNTL
, 0x00,
297 R_15_VGATE_START_FID_CHG
, 0x00,
298 R_16_VGATE_STOP
, 0x00,
299 R_17_MISC_VGATE_CONF_AND_MSB
, 0x00,
304 /* If a value differs from the Hauppauge driver values, then the comment starts with
305 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
306 Hauppauge driver sets. */
308 /* SAA7114 and SAA7115 initialization table */
309 static const unsigned char saa7115_init_auto_input
[] = {
311 R_01_INC_DELAY
, 0x48, /* white peak control disabled */
312 R_03_INPUT_CNTL_2
, 0x20, /* was 0x30. 0x20: long vertical blanking */
313 R_04_INPUT_CNTL_3
, 0x90, /* analog gain set to 0 */
314 R_05_INPUT_CNTL_4
, 0x90, /* analog gain set to 0 */
316 R_06_H_SYNC_START
, 0xeb, /* horiz sync begin = -21 */
317 R_07_H_SYNC_STOP
, 0xe0, /* horiz sync stop = -17 */
318 R_09_LUMA_CNTL
, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
319 R_0A_LUMA_BRIGHT_CNTL
, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
320 R_0B_LUMA_CONTRAST_CNTL
, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
321 R_0C_CHROMA_SAT_CNTL
, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
322 R_0D_CHROMA_HUE_CNTL
, 0x00,
323 R_0F_CHROMA_GAIN_CNTL
, 0x00, /* use automatic gain */
324 R_10_CHROMA_CNTL_2
, 0x06, /* chroma: active adaptive combfilter */
325 R_11_MODE_DELAY_CNTL
, 0x00,
326 R_12_RT_SIGNAL_CNTL
, 0x9d, /* RTS0 output control: VGATE */
327 R_13_RT_X_PORT_OUT_CNTL
, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */
328 R_14_ANAL_ADC_COMPAT_CNTL
, 0x00,
329 R_18_RAW_DATA_GAIN_CNTL
, 0x40, /* gain 0x00 = nominal */
330 R_19_RAW_DATA_OFF_CNTL
, 0x80,
331 R_1A_COLOR_KILL_LVL_CNTL
, 0x77, /* recommended value */
332 R_1B_MISC_TVVCRDET
, 0x42, /* recommended value */
333 R_1C_ENHAN_COMB_CTRL1
, 0xa9, /* recommended value */
334 R_1D_ENHAN_COMB_CTRL2
, 0x01, /* recommended value */
337 R_80_GLOBAL_CNTL_1
, 0x0, /* No tasks enabled at init */
339 /* Power Device Control */
340 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset device */
341 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* set device programmed, all in operational mode */
345 /* Used to reset saa7113, saa7114 and saa7115 */
346 static const unsigned char saa7115_cfg_reset_scaler
[] = {
347 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x00, /* disable I-port output */
348 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
349 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
350 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* enable I-port output */
354 /* ============== SAA7715 VIDEO templates ============= */
356 static const unsigned char saa7115_cfg_60hz_video
[] = {
357 R_80_GLOBAL_CNTL_1
, 0x00, /* reset tasks */
358 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
360 R_15_VGATE_START_FID_CHG
, 0x03,
361 R_16_VGATE_STOP
, 0x11,
362 R_17_MISC_VGATE_CONF_AND_MSB
, 0x9c,
364 R_08_SYNC_CNTL
, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
365 R_0E_CHROMA_CNTL_1
, 0x07, /* video autodetection is on */
367 R_5A_V_OFF_FOR_SLICER
, 0x06, /* standard 60hz value for ITU656 line counting */
370 R_90_A_TASK_HANDLING_CNTL
, 0x80,
371 R_91_A_X_PORT_FORMATS_AND_CONF
, 0x48,
372 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL
, 0x40,
373 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF
, 0x84,
375 /* hoffset low (input), 0x0002 is minimum */
376 R_94_A_HORIZ_INPUT_WINDOW_START
, 0x01,
377 R_95_A_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
379 /* hsize low (input), 0x02d0 = 720 */
380 R_96_A_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
381 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
383 R_98_A_VERT_INPUT_WINDOW_START
, 0x05,
384 R_99_A_VERT_INPUT_WINDOW_START_MSB
, 0x00,
386 R_9A_A_VERT_INPUT_WINDOW_LENGTH
, 0x0c,
387 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB
, 0x00,
389 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xa0,
390 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x05,
392 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH
, 0x0c,
393 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB
, 0x00,
396 R_C0_B_TASK_HANDLING_CNTL
, 0x00,
397 R_C1_B_X_PORT_FORMATS_AND_CONF
, 0x08,
398 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION
, 0x00,
399 R_C3_B_I_PORT_FORMATS_AND_CONF
, 0x80,
401 /* 0x0002 is minimum */
402 R_C4_B_HORIZ_INPUT_WINDOW_START
, 0x02,
403 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
406 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
407 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
409 /* vwindow start 0x12 = 18 */
410 R_C8_B_VERT_INPUT_WINDOW_START
, 0x12,
411 R_C9_B_VERT_INPUT_WINDOW_START_MSB
, 0x00,
413 /* vwindow length 0xf8 = 248 */
414 R_CA_B_VERT_INPUT_WINDOW_LENGTH
, VRES_60HZ
>>1,
415 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB
, VRES_60HZ
>>9,
417 /* hwindow 0x02d0 = 720 */
418 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xd0,
419 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x02,
421 R_F0_LFCO_PER_LINE
, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
422 R_F1_P_I_PARAM_SELECT
, 0x05, /* low bit with 0xF0 */
423 R_F5_PULSGEN_LINE_LENGTH
, 0xad,
424 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG
, 0x01,
429 static const unsigned char saa7115_cfg_50hz_video
[] = {
430 R_80_GLOBAL_CNTL_1
, 0x00,
431 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
433 R_15_VGATE_START_FID_CHG
, 0x37, /* VGATE start */
434 R_16_VGATE_STOP
, 0x16,
435 R_17_MISC_VGATE_CONF_AND_MSB
, 0x99,
437 R_08_SYNC_CNTL
, 0x28, /* 0x28 = PAL */
438 R_0E_CHROMA_CNTL_1
, 0x07,
440 R_5A_V_OFF_FOR_SLICER
, 0x03, /* standard 50hz value */
443 R_90_A_TASK_HANDLING_CNTL
, 0x81,
444 R_91_A_X_PORT_FORMATS_AND_CONF
, 0x48,
445 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL
, 0x40,
446 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF
, 0x84,
448 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
449 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
450 /* hoffset low (input), 0x0002 is minimum */
451 R_94_A_HORIZ_INPUT_WINDOW_START
, 0x00,
452 R_95_A_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
454 /* hsize low (input), 0x02d0 = 720 */
455 R_96_A_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
456 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
458 R_98_A_VERT_INPUT_WINDOW_START
, 0x03,
459 R_99_A_VERT_INPUT_WINDOW_START_MSB
, 0x00,
461 /* vsize 0x12 = 18 */
462 R_9A_A_VERT_INPUT_WINDOW_LENGTH
, 0x12,
463 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB
, 0x00,
465 /* hsize 0x05a0 = 1440 */
466 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xa0,
467 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x05, /* hsize hi (output) */
468 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH
, 0x12, /* vsize low (output), 0x12 = 18 */
469 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB
, 0x00, /* vsize hi (output) */
472 R_C0_B_TASK_HANDLING_CNTL
, 0x00,
473 R_C1_B_X_PORT_FORMATS_AND_CONF
, 0x08,
474 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION
, 0x00,
475 R_C3_B_I_PORT_FORMATS_AND_CONF
, 0x80,
477 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
478 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
479 /* hoffset low (input), 0x0002 is minimum. See comment above. */
480 R_C4_B_HORIZ_INPUT_WINDOW_START
, 0x00,
481 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB
, 0x00,
483 /* hsize 0x02d0 = 720 */
484 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH
, 0xd0,
485 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB
, 0x02,
487 /* voffset 0x16 = 22 */
488 R_C8_B_VERT_INPUT_WINDOW_START
, 0x16,
489 R_C9_B_VERT_INPUT_WINDOW_START_MSB
, 0x00,
491 /* vsize 0x0120 = 288 */
492 R_CA_B_VERT_INPUT_WINDOW_LENGTH
, 0x20,
493 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB
, 0x01,
495 /* hsize 0x02d0 = 720 */
496 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
, 0xd0,
497 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
, 0x02,
499 R_F0_LFCO_PER_LINE
, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
500 R_F1_P_I_PARAM_SELECT
, 0x05, /* low bit with 0xF0, (was 0x05) */
501 R_F5_PULSGEN_LINE_LENGTH
, 0xb0,
502 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG
, 0x01,
507 /* ============== SAA7715 VIDEO templates (end) ======= */
509 static const unsigned char saa7115_cfg_vbi_on
[] = {
510 R_80_GLOBAL_CNTL_1
, 0x00, /* reset tasks */
511 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
512 R_80_GLOBAL_CNTL_1
, 0x30, /* Activate both tasks */
513 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
514 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* Enable I-port output */
519 static const unsigned char saa7115_cfg_vbi_off
[] = {
520 R_80_GLOBAL_CNTL_1
, 0x00, /* reset tasks */
521 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0, /* reset scaler */
522 R_80_GLOBAL_CNTL_1
, 0x20, /* Activate only task "B" */
523 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0, /* activate scaler */
524 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01, /* Enable I-port output */
530 static const unsigned char saa7115_init_misc
[] = {
531 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F
, 0x01,
532 R_83_X_PORT_I_O_ENA_AND_OUT_CLK
, 0x01,
533 R_84_I_PORT_SIGNAL_DEF
, 0x20,
534 R_85_I_PORT_SIGNAL_POLAR
, 0x21,
535 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT
, 0xc5,
536 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, 0x01,
539 R_A0_A_HORIZ_PRESCALING
, 0x01,
540 R_A1_A_ACCUMULATION_LENGTH
, 0x00,
541 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER
, 0x00,
543 /* Configure controls at nominal value*/
544 R_A4_A_LUMA_BRIGHTNESS_CNTL
, 0x80,
545 R_A5_A_LUMA_CONTRAST_CNTL
, 0x40,
546 R_A6_A_CHROMA_SATURATION_CNTL
, 0x40,
548 /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
549 R_A8_A_HORIZ_LUMA_SCALING_INC
, 0x00,
550 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB
, 0x02,
552 R_AA_A_HORIZ_LUMA_PHASE_OFF
, 0x00,
554 /* must be horiz lum scaling / 2 */
555 R_AC_A_HORIZ_CHROMA_SCALING_INC
, 0x00,
556 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB
, 0x01,
558 /* must be offset luma / 2 */
559 R_AE_A_HORIZ_CHROMA_PHASE_OFF
, 0x00,
561 R_B0_A_VERT_LUMA_SCALING_INC
, 0x00,
562 R_B1_A_VERT_LUMA_SCALING_INC_MSB
, 0x04,
564 R_B2_A_VERT_CHROMA_SCALING_INC
, 0x00,
565 R_B3_A_VERT_CHROMA_SCALING_INC_MSB
, 0x04,
567 R_B4_A_VERT_SCALING_MODE_CNTL
, 0x01,
569 R_B8_A_VERT_CHROMA_PHASE_OFF_00
, 0x00,
570 R_B9_A_VERT_CHROMA_PHASE_OFF_01
, 0x00,
571 R_BA_A_VERT_CHROMA_PHASE_OFF_10
, 0x00,
572 R_BB_A_VERT_CHROMA_PHASE_OFF_11
, 0x00,
574 R_BC_A_VERT_LUMA_PHASE_OFF_00
, 0x00,
575 R_BD_A_VERT_LUMA_PHASE_OFF_01
, 0x00,
576 R_BE_A_VERT_LUMA_PHASE_OFF_10
, 0x00,
577 R_BF_A_VERT_LUMA_PHASE_OFF_11
, 0x00,
580 R_D0_B_HORIZ_PRESCALING
, 0x01,
581 R_D1_B_ACCUMULATION_LENGTH
, 0x00,
582 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER
, 0x00,
584 /* Configure controls at nominal value*/
585 R_D4_B_LUMA_BRIGHTNESS_CNTL
, 0x80,
586 R_D5_B_LUMA_CONTRAST_CNTL
, 0x40,
587 R_D6_B_CHROMA_SATURATION_CNTL
, 0x40,
589 /* hor lum scaling 0x0400 = 1 */
590 R_D8_B_HORIZ_LUMA_SCALING_INC
, 0x00,
591 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB
, 0x04,
593 R_DA_B_HORIZ_LUMA_PHASE_OFF
, 0x00,
595 /* must be hor lum scaling / 2 */
596 R_DC_B_HORIZ_CHROMA_SCALING
, 0x00,
597 R_DD_B_HORIZ_CHROMA_SCALING_MSB
, 0x02,
599 /* must be offset luma / 2 */
600 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA
, 0x00,
602 R_E0_B_VERT_LUMA_SCALING_INC
, 0x00,
603 R_E1_B_VERT_LUMA_SCALING_INC_MSB
, 0x04,
605 R_E2_B_VERT_CHROMA_SCALING_INC
, 0x00,
606 R_E3_B_VERT_CHROMA_SCALING_INC_MSB
, 0x04,
608 R_E4_B_VERT_SCALING_MODE_CNTL
, 0x01,
610 R_E8_B_VERT_CHROMA_PHASE_OFF_00
, 0x00,
611 R_E9_B_VERT_CHROMA_PHASE_OFF_01
, 0x00,
612 R_EA_B_VERT_CHROMA_PHASE_OFF_10
, 0x00,
613 R_EB_B_VERT_CHROMA_PHASE_OFF_11
, 0x00,
615 R_EC_B_VERT_LUMA_PHASE_OFF_00
, 0x00,
616 R_ED_B_VERT_LUMA_PHASE_OFF_01
, 0x00,
617 R_EE_B_VERT_LUMA_PHASE_OFF_10
, 0x00,
618 R_EF_B_VERT_LUMA_PHASE_OFF_11
, 0x00,
620 R_F2_NOMINAL_PLL2_DTO
, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
621 R_F3_PLL_INCREMENT
, 0x46,
622 R_F4_PLL2_STATUS
, 0x00,
623 R_F7_PULSE_A_POS_MSB
, 0x4b, /* not the recommended settings! */
624 R_F8_PULSE_B_POS
, 0x00,
625 R_F9_PULSE_B_POS_MSB
, 0x4b,
626 R_FA_PULSE_C_POS
, 0x00,
627 R_FB_PULSE_C_POS_MSB
, 0x4b,
629 /* PLL2 lock detection settings: 71 lines 50% phase error */
630 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES
, 0x88,
633 R_40_SLICER_CNTL_1
, 0x20, /* No framing code errors allowed. */
635 R_41_LCR_BASE
+1, 0xff,
636 R_41_LCR_BASE
+2, 0xff,
637 R_41_LCR_BASE
+3, 0xff,
638 R_41_LCR_BASE
+4, 0xff,
639 R_41_LCR_BASE
+5, 0xff,
640 R_41_LCR_BASE
+6, 0xff,
641 R_41_LCR_BASE
+7, 0xff,
642 R_41_LCR_BASE
+8, 0xff,
643 R_41_LCR_BASE
+9, 0xff,
644 R_41_LCR_BASE
+10, 0xff,
645 R_41_LCR_BASE
+11, 0xff,
646 R_41_LCR_BASE
+12, 0xff,
647 R_41_LCR_BASE
+13, 0xff,
648 R_41_LCR_BASE
+14, 0xff,
649 R_41_LCR_BASE
+15, 0xff,
650 R_41_LCR_BASE
+16, 0xff,
651 R_41_LCR_BASE
+17, 0xff,
652 R_41_LCR_BASE
+18, 0xff,
653 R_41_LCR_BASE
+19, 0xff,
654 R_41_LCR_BASE
+20, 0xff,
655 R_41_LCR_BASE
+21, 0xff,
656 R_41_LCR_BASE
+22, 0xff,
657 R_58_PROGRAM_FRAMING_CODE
, 0x40,
658 R_59_H_OFF_FOR_SLICER
, 0x47,
659 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF
, 0x83,
663 R_02_INPUT_CNTL_1
, 0xc4, /* input tuner -> input 4, amplifier active */
665 R_80_GLOBAL_CNTL_1
, 0x20, /* enable task B */
666 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xd0,
667 R_88_POWER_SAVE_ADC_PORT_CNTL
, 0xf0,
671 static int saa711x_odd_parity(u8 c
)
680 static int saa711x_decode_vps(u8
*dst
, u8
*p
)
682 static const u8 biphase_tbl
[] = {
683 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
684 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
685 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
686 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
687 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
688 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
689 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
690 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
691 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
692 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
693 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
694 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
695 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
696 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
697 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
698 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
699 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
700 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
701 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
702 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
703 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
704 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
705 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
706 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
707 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
708 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
709 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
710 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
711 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
712 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
713 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
714 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
719 for (i
= 0; i
< 2 * 13; i
+= 2) {
720 err
|= biphase_tbl
[p
[i
]] | biphase_tbl
[p
[i
+ 1]];
721 c
= (biphase_tbl
[p
[i
+ 1]] & 0xf) | ((biphase_tbl
[p
[i
]] & 0xf) << 4);
727 static int saa711x_decode_wss(u8
*p
)
729 static const int wss_bits
[8] = {
730 0, 0, 0, 1, 0, 1, 1, 1
732 unsigned char parity
;
736 for (i
= 0; i
< 16; i
++) {
737 int b1
= wss_bits
[p
[i
] & 7];
738 int b2
= wss_bits
[(p
[i
] >> 3) & 7];
745 parity
^= parity
>> 2;
746 parity
^= parity
>> 1;
754 static int saa711x_s_clock_freq(struct v4l2_subdev
*sd
, u32 freq
)
756 struct saa711x_state
*state
= to_state(sd
);
761 u8 acc
= 0; /* reg 0x3a, audio clock control */
763 /* Checks for chips that don't have audio clock (saa7111, saa7113) */
764 if (!saa711x_has_reg(state
->ident
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
))
767 v4l2_dbg(1, debug
, sd
, "set audio clock freq: %d\n", freq
);
770 if (freq
< 32000 || freq
> 48000)
773 /* hz is the refresh rate times 100 */
774 hz
= (state
->std
& V4L2_STD_525_60
) ? 5994 : 5000;
775 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
776 acpf
= (25600 * freq
) / hz
;
777 /* acni = (256 * freq * 2^23) / crystal_frequency =
778 (freq * 2^(8+23)) / crystal_frequency =
779 (freq << 31) / crystal_frequency */
782 do_div(f
, state
->crystal_freq
);
785 acpf
= acpf
* state
->cgcdiv
/ 16;
786 acni
= acni
* state
->cgcdiv
/ 16;
788 if (state
->cgcdiv
== 3)
794 if (state
->double_asclk
) {
798 saa711x_write(sd
, R_38_CLK_RATIO_AMXCLK_TO_ASCLK
, 0x03);
799 saa711x_write(sd
, R_39_CLK_RATIO_ASCLK_TO_ALRCLK
, 0x10 << state
->double_asclk
);
800 saa711x_write(sd
, R_3A_AUD_CLK_GEN_BASIC_SETUP
, acc
);
802 saa711x_write(sd
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
, acpf
& 0xff);
803 saa711x_write(sd
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
+1,
805 saa711x_write(sd
, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD
+2,
806 (acpf
>> 16) & 0x03);
808 saa711x_write(sd
, R_34_AUD_MAST_CLK_NOMINAL_INC
, acni
& 0xff);
809 saa711x_write(sd
, R_34_AUD_MAST_CLK_NOMINAL_INC
+1, (acni
>> 8) & 0xff);
810 saa711x_write(sd
, R_34_AUD_MAST_CLK_NOMINAL_INC
+2, (acni
>> 16) & 0x3f);
811 state
->audclk_freq
= freq
;
815 static int saa711x_g_volatile_ctrl(struct v4l2_ctrl
*ctrl
)
817 struct v4l2_subdev
*sd
= to_sd(ctrl
);
818 struct saa711x_state
*state
= to_state(sd
);
821 case V4L2_CID_CHROMA_AGC
:
822 /* chroma gain cluster */
825 saa711x_read(sd
, R_0F_CHROMA_GAIN_CNTL
) & 0x7f;
831 static int saa711x_s_ctrl(struct v4l2_ctrl
*ctrl
)
833 struct v4l2_subdev
*sd
= to_sd(ctrl
);
834 struct saa711x_state
*state
= to_state(sd
);
837 case V4L2_CID_BRIGHTNESS
:
838 saa711x_write(sd
, R_0A_LUMA_BRIGHT_CNTL
, ctrl
->val
);
841 case V4L2_CID_CONTRAST
:
842 saa711x_write(sd
, R_0B_LUMA_CONTRAST_CNTL
, ctrl
->val
);
845 case V4L2_CID_SATURATION
:
846 saa711x_write(sd
, R_0C_CHROMA_SAT_CNTL
, ctrl
->val
);
850 saa711x_write(sd
, R_0D_CHROMA_HUE_CNTL
, ctrl
->val
);
853 case V4L2_CID_CHROMA_AGC
:
854 /* chroma gain cluster */
856 saa711x_write(sd
, R_0F_CHROMA_GAIN_CNTL
, state
->gain
->val
);
858 saa711x_write(sd
, R_0F_CHROMA_GAIN_CNTL
, state
->gain
->val
| 0x80);
868 static int saa711x_set_size(struct v4l2_subdev
*sd
, int width
, int height
)
870 struct saa711x_state
*state
= to_state(sd
);
874 int is_50hz
= state
->std
& V4L2_STD_625_50
;
875 int Vsrc
= is_50hz
? 576 : 480;
877 v4l2_dbg(1, debug
, sd
, "decoder set size to %ix%i\n", width
, height
);
879 /* FIXME need better bounds checking here */
880 if ((width
< 1) || (width
> 1440))
882 if ((height
< 1) || (height
> Vsrc
))
885 if (!saa711x_has_reg(state
->ident
, R_D0_B_HORIZ_PRESCALING
)) {
886 /* Decoder only supports 720 columns and 480 or 576 lines */
893 state
->width
= width
;
894 state
->height
= height
;
896 if (!saa711x_has_reg(state
->ident
, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
))
899 /* probably have a valid size, let's set it */
900 /* Set output width/height */
903 saa711x_write(sd
, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH
,
904 (u8
) (width
& 0xff));
905 saa711x_write(sd
, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB
,
906 (u8
) ((width
>> 8) & 0xff));
908 /* Vertical Scaling uses height/2 */
911 /* On 60Hz, it is using a higher Vertical Output Size */
913 res
+= (VRES_60HZ
- 480) >> 1;
916 saa711x_write(sd
, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH
,
918 saa711x_write(sd
, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB
,
919 (u8
) ((res
>> 8) & 0xff));
921 /* Scaling settings */
922 /* Hprescaler is floor(inres/outres) */
923 HPSC
= (int)(720 / width
);
924 /* 0 is not allowed (div. by zero) */
925 HPSC
= HPSC
? HPSC
: 1;
926 HFSC
= (int)((1024 * 720) / (HPSC
* width
));
927 /* FIXME hardcodes to "Task B"
928 * write H prescaler integer */
929 saa711x_write(sd
, R_D0_B_HORIZ_PRESCALING
,
932 v4l2_dbg(1, debug
, sd
, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC
, HFSC
);
933 /* write H fine-scaling (luminance) */
934 saa711x_write(sd
, R_D8_B_HORIZ_LUMA_SCALING_INC
,
936 saa711x_write(sd
, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB
,
937 (u8
) ((HFSC
>> 8) & 0xff));
938 /* write H fine-scaling (chrominance)
939 * must be lum/2, so i'll just bitshift :) */
940 saa711x_write(sd
, R_DC_B_HORIZ_CHROMA_SCALING
,
941 (u8
) ((HFSC
>> 1) & 0xff));
942 saa711x_write(sd
, R_DD_B_HORIZ_CHROMA_SCALING_MSB
,
943 (u8
) ((HFSC
>> 9) & 0xff));
945 VSCY
= (int)((1024 * Vsrc
) / height
);
946 v4l2_dbg(1, debug
, sd
, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc
, VSCY
);
948 /* Correct Contrast and Luminance */
949 saa711x_write(sd
, R_D5_B_LUMA_CONTRAST_CNTL
,
950 (u8
) (64 * 1024 / VSCY
));
951 saa711x_write(sd
, R_D6_B_CHROMA_SATURATION_CNTL
,
952 (u8
) (64 * 1024 / VSCY
));
954 /* write V fine-scaling (luminance) */
955 saa711x_write(sd
, R_E0_B_VERT_LUMA_SCALING_INC
,
957 saa711x_write(sd
, R_E1_B_VERT_LUMA_SCALING_INC_MSB
,
958 (u8
) ((VSCY
>> 8) & 0xff));
959 /* write V fine-scaling (chrominance) */
960 saa711x_write(sd
, R_E2_B_VERT_CHROMA_SCALING_INC
,
962 saa711x_write(sd
, R_E3_B_VERT_CHROMA_SCALING_INC_MSB
,
963 (u8
) ((VSCY
>> 8) & 0xff));
965 saa711x_writeregs(sd
, saa7115_cfg_reset_scaler
);
967 /* Activates task "B" */
968 saa711x_write(sd
, R_80_GLOBAL_CNTL_1
,
969 saa711x_read(sd
, R_80_GLOBAL_CNTL_1
) | 0x20);
974 static void saa711x_set_v4lstd(struct v4l2_subdev
*sd
, v4l2_std_id std
)
976 struct saa711x_state
*state
= to_state(sd
);
978 /* Prevent unnecessary standard changes. During a standard
979 change the I-Port is temporarily disabled. Any devices
980 reading from that port can get confused.
981 Note that s_std is also used to switch from
982 radio to TV mode, so if a s_std is broadcast to
983 all I2C devices then you do not want to have an unwanted
985 if (std
== state
->std
)
990 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
991 if (std
& V4L2_STD_525_60
) {
992 v4l2_dbg(1, debug
, sd
, "decoder set standard 60 Hz\n");
993 if (state
->ident
== GM7113C
) {
994 u8 reg
= saa711x_read(sd
, R_08_SYNC_CNTL
);
995 reg
&= ~(SAA7113_R_08_FSEL
| SAA7113_R_08_AUFD
);
996 reg
|= SAA7113_R_08_FSEL
;
997 saa711x_write(sd
, R_08_SYNC_CNTL
, reg
);
999 saa711x_writeregs(sd
, saa7115_cfg_60hz_video
);
1001 saa711x_set_size(sd
, 720, 480);
1003 v4l2_dbg(1, debug
, sd
, "decoder set standard 50 Hz\n");
1004 if (state
->ident
== GM7113C
) {
1005 u8 reg
= saa711x_read(sd
, R_08_SYNC_CNTL
);
1006 reg
&= ~(SAA7113_R_08_FSEL
| SAA7113_R_08_AUFD
);
1007 saa711x_write(sd
, R_08_SYNC_CNTL
, reg
);
1009 saa711x_writeregs(sd
, saa7115_cfg_50hz_video
);
1011 saa711x_set_size(sd
, 720, 576);
1014 /* Register 0E - Bits D6-D4 on NO-AUTO mode
1015 (SAA7111 and SAA7113 doesn't have auto mode)
1016 50 Hz / 625 lines 60 Hz / 525 lines
1017 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz)
1018 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz)
1019 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
1020 011 NTSC N (3.58MHz) PAL M (3.58MHz)
1021 100 reserved NTSC-Japan (3.58MHz)
1023 if (state
->ident
<= SAA7113
||
1024 state
->ident
== GM7113C
) {
1025 u8 reg
= saa711x_read(sd
, R_0E_CHROMA_CNTL_1
) & 0x8f;
1027 if (std
== V4L2_STD_PAL_M
) {
1029 } else if (std
== V4L2_STD_PAL_Nc
) {
1031 } else if (std
== V4L2_STD_PAL_60
) {
1033 } else if (std
== V4L2_STD_NTSC_M_JP
) {
1035 } else if (std
& V4L2_STD_SECAM
) {
1038 saa711x_write(sd
, R_0E_CHROMA_CNTL_1
, reg
);
1040 /* restart task B if needed */
1041 int taskb
= saa711x_read(sd
, R_80_GLOBAL_CNTL_1
) & 0x10;
1043 if (taskb
&& state
->ident
== SAA7114
)
1044 saa711x_writeregs(sd
, saa7115_cfg_vbi_on
);
1046 /* switch audio mode too! */
1047 saa711x_s_clock_freq(sd
, state
->audclk_freq
);
1051 /* setup the sliced VBI lcr registers according to the sliced VBI format */
1052 static void saa711x_set_lcr(struct v4l2_subdev
*sd
, struct v4l2_sliced_vbi_format
*fmt
)
1054 struct saa711x_state
*state
= to_state(sd
);
1055 int is_50hz
= (state
->std
& V4L2_STD_625_50
);
1060 /* saa7113/7114/7118 VBI support are experimental */
1061 if (!saa711x_has_reg(state
->ident
, R_41_LCR_BASE
))
1065 /* SAA7113 and SAA7118 also should support VBI - Need testing */
1066 if (state
->ident
!= SAA7115
)
1070 for (i
= 0; i
<= 23; i
++)
1076 for (i
= 6; i
<= 23; i
++)
1079 for (i
= 10; i
<= 21; i
++)
1083 /* first clear lines that cannot be captured */
1085 for (i
= 0; i
<= 5; i
++)
1086 fmt
->service_lines
[0][i
] =
1087 fmt
->service_lines
[1][i
] = 0;
1090 for (i
= 0; i
<= 9; i
++)
1091 fmt
->service_lines
[0][i
] =
1092 fmt
->service_lines
[1][i
] = 0;
1093 for (i
= 22; i
<= 23; i
++)
1094 fmt
->service_lines
[0][i
] =
1095 fmt
->service_lines
[1][i
] = 0;
1098 /* Now set the lcr values according to the specified service */
1099 for (i
= 6; i
<= 23; i
++) {
1101 for (x
= 0; x
<= 1; x
++) {
1102 switch (fmt
->service_lines
[1-x
][i
]) {
1104 lcr
[i
] |= 0xf << (4 * x
);
1106 case V4L2_SLICED_TELETEXT_B
:
1107 lcr
[i
] |= 1 << (4 * x
);
1109 case V4L2_SLICED_CAPTION_525
:
1110 lcr
[i
] |= 4 << (4 * x
);
1112 case V4L2_SLICED_WSS_625
:
1113 lcr
[i
] |= 5 << (4 * x
);
1115 case V4L2_SLICED_VPS
:
1116 lcr
[i
] |= 7 << (4 * x
);
1123 /* write the lcr registers */
1124 for (i
= 2; i
<= 23; i
++) {
1125 saa711x_write(sd
, i
- 2 + R_41_LCR_BASE
, lcr
[i
]);
1128 /* enable/disable raw VBI capturing */
1129 saa711x_writeregs(sd
, fmt
== NULL
?
1130 saa7115_cfg_vbi_on
:
1131 saa7115_cfg_vbi_off
);
1134 static int saa711x_g_sliced_fmt(struct v4l2_subdev
*sd
, struct v4l2_sliced_vbi_format
*sliced
)
1136 static u16 lcr2vbi
[] = {
1137 0, V4L2_SLICED_TELETEXT_B
, 0, /* 1 */
1138 0, V4L2_SLICED_CAPTION_525
, /* 4 */
1139 V4L2_SLICED_WSS_625
, 0, /* 5 */
1140 V4L2_SLICED_VPS
, 0, 0, 0, 0, /* 7 */
1145 memset(sliced
->service_lines
, 0, sizeof(sliced
->service_lines
));
1146 sliced
->service_set
= 0;
1147 /* done if using raw VBI */
1148 if (saa711x_read(sd
, R_80_GLOBAL_CNTL_1
) & 0x10)
1150 for (i
= 2; i
<= 23; i
++) {
1151 u8 v
= saa711x_read(sd
, i
- 2 + R_41_LCR_BASE
);
1153 sliced
->service_lines
[0][i
] = lcr2vbi
[v
>> 4];
1154 sliced
->service_lines
[1][i
] = lcr2vbi
[v
& 0xf];
1155 sliced
->service_set
|=
1156 sliced
->service_lines
[0][i
] | sliced
->service_lines
[1][i
];
1161 static int saa711x_s_raw_fmt(struct v4l2_subdev
*sd
, struct v4l2_vbi_format
*fmt
)
1163 saa711x_set_lcr(sd
, NULL
);
1167 static int saa711x_s_sliced_fmt(struct v4l2_subdev
*sd
, struct v4l2_sliced_vbi_format
*fmt
)
1169 saa711x_set_lcr(sd
, fmt
);
1173 static int saa711x_s_mbus_fmt(struct v4l2_subdev
*sd
, struct v4l2_mbus_framefmt
*fmt
)
1175 if (fmt
->code
!= V4L2_MBUS_FMT_FIXED
)
1177 fmt
->field
= V4L2_FIELD_INTERLACED
;
1178 fmt
->colorspace
= V4L2_COLORSPACE_SMPTE170M
;
1179 return saa711x_set_size(sd
, fmt
->width
, fmt
->height
);
1182 /* Decode the sliced VBI data stream as created by the saa7115.
1183 The format is described in the saa7115 datasheet in Tables 25 and 26
1185 The current implementation uses SAV/EAV codes and not the ancillary data
1186 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1188 static int saa711x_decode_vbi_line(struct v4l2_subdev
*sd
, struct v4l2_decode_vbi_line
*vbi
)
1190 struct saa711x_state
*state
= to_state(sd
);
1191 static const char vbi_no_data_pattern
[] = {
1192 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1196 int id1
, id2
; /* the ID1 and ID2 bytes from the internal header */
1198 vbi
->type
= 0; /* mark result as a failure */
1201 /* Note: the field bit is inverted for 60 Hz video */
1202 if (state
->std
& V4L2_STD_525_60
)
1205 /* Skip internal header, p now points to the start of the payload */
1209 /* calculate field and line number of the VBI packet (1-23) */
1210 vbi
->is_second_field
= ((id1
& 0x40) != 0);
1211 vbi
->line
= (id1
& 0x3f) << 3;
1212 vbi
->line
|= (id2
& 0x70) >> 4;
1214 /* Obtain data type */
1217 /* If the VBI slicer does not detect any signal it will fill up
1218 the payload buffer with 0xa0 bytes. */
1219 if (!memcmp(p
, vbi_no_data_pattern
, sizeof(vbi_no_data_pattern
)))
1222 /* decode payloads */
1225 vbi
->type
= V4L2_SLICED_TELETEXT_B
;
1228 if (!saa711x_odd_parity(p
[0]) || !saa711x_odd_parity(p
[1]))
1230 vbi
->type
= V4L2_SLICED_CAPTION_525
;
1233 wss
= saa711x_decode_wss(p
);
1238 vbi
->type
= V4L2_SLICED_WSS_625
;
1241 if (saa711x_decode_vps(p
, p
) != 0)
1243 vbi
->type
= V4L2_SLICED_VPS
;
1251 /* ============ SAA7115 AUDIO settings (end) ============= */
1253 static int saa711x_g_tuner(struct v4l2_subdev
*sd
, struct v4l2_tuner
*vt
)
1255 struct saa711x_state
*state
= to_state(sd
);
1260 status
= saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
);
1262 v4l2_dbg(1, debug
, sd
, "status: 0x%02x\n", status
);
1263 vt
->signal
= ((status
& (1 << 6)) == 0) ? 0xffff : 0x0;
1267 static int saa711x_s_std(struct v4l2_subdev
*sd
, v4l2_std_id std
)
1269 struct saa711x_state
*state
= to_state(sd
);
1272 saa711x_set_v4lstd(sd
, std
);
1276 static int saa711x_s_radio(struct v4l2_subdev
*sd
)
1278 struct saa711x_state
*state
= to_state(sd
);
1284 static int saa711x_s_routing(struct v4l2_subdev
*sd
,
1285 u32 input
, u32 output
, u32 config
)
1287 struct saa711x_state
*state
= to_state(sd
);
1288 u8 mask
= (state
->ident
<= SAA7111A
) ? 0xf8 : 0xf0;
1290 v4l2_dbg(1, debug
, sd
, "decoder set input %d output %d\n",
1293 /* saa7111/3 does not have these inputs */
1294 if ((state
->ident
<= SAA7113
||
1295 state
->ident
== GM7113C
) &&
1296 (input
== SAA7115_COMPOSITE4
||
1297 input
== SAA7115_COMPOSITE5
)) {
1300 if (input
> SAA7115_SVIDEO3
)
1302 if (state
->input
== input
&& state
->output
== output
)
1304 v4l2_dbg(1, debug
, sd
, "now setting %s input %s output\n",
1305 (input
>= SAA7115_SVIDEO0
) ? "S-Video" : "Composite",
1306 (output
== SAA7115_IPORT_ON
) ? "iport on" : "iport off");
1307 state
->input
= input
;
1309 /* saa7111 has slightly different input numbering */
1310 if (state
->ident
<= SAA7111A
) {
1311 if (input
>= SAA7115_COMPOSITE4
)
1313 /* saa7111 specific */
1314 saa711x_write(sd
, R_10_CHROMA_CNTL_2
,
1315 (saa711x_read(sd
, R_10_CHROMA_CNTL_2
) & 0x3f) |
1316 ((output
& 0xc0) ^ 0x40));
1317 saa711x_write(sd
, R_13_RT_X_PORT_OUT_CNTL
,
1318 (saa711x_read(sd
, R_13_RT_X_PORT_OUT_CNTL
) & 0xf0) |
1319 ((output
& 2) ? 0x0a : 0));
1323 saa711x_write(sd
, R_02_INPUT_CNTL_1
,
1324 (saa711x_read(sd
, R_02_INPUT_CNTL_1
) & mask
) |
1327 /* bypass chrominance trap for S-Video modes */
1328 saa711x_write(sd
, R_09_LUMA_CNTL
,
1329 (saa711x_read(sd
, R_09_LUMA_CNTL
) & 0x7f) |
1330 (state
->input
>= SAA7115_SVIDEO0
? 0x80 : 0x0));
1332 state
->output
= output
;
1333 if (state
->ident
== SAA7114
||
1334 state
->ident
== SAA7115
) {
1335 saa711x_write(sd
, R_83_X_PORT_I_O_ENA_AND_OUT_CLK
,
1336 (saa711x_read(sd
, R_83_X_PORT_I_O_ENA_AND_OUT_CLK
) & 0xfe) |
1337 (state
->output
& 0x01));
1339 if (state
->ident
> SAA7111A
) {
1340 if (config
& SAA7115_IDQ_IS_DEFAULT
)
1341 saa711x_write(sd
, R_85_I_PORT_SIGNAL_POLAR
, 0x20);
1343 saa711x_write(sd
, R_85_I_PORT_SIGNAL_POLAR
, 0x21);
1348 static int saa711x_s_gpio(struct v4l2_subdev
*sd
, u32 val
)
1350 struct saa711x_state
*state
= to_state(sd
);
1352 if (state
->ident
> SAA7111A
)
1354 saa711x_write(sd
, 0x11, (saa711x_read(sd
, 0x11) & 0x7f) |
1359 static int saa711x_s_stream(struct v4l2_subdev
*sd
, int enable
)
1361 struct saa711x_state
*state
= to_state(sd
);
1363 v4l2_dbg(1, debug
, sd
, "%s output\n",
1364 enable
? "enable" : "disable");
1366 if (state
->enable
== enable
)
1368 state
->enable
= enable
;
1369 if (!saa711x_has_reg(state
->ident
, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
))
1371 saa711x_write(sd
, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED
, state
->enable
);
1375 static int saa711x_s_crystal_freq(struct v4l2_subdev
*sd
, u32 freq
, u32 flags
)
1377 struct saa711x_state
*state
= to_state(sd
);
1379 if (freq
!= SAA7115_FREQ_32_11_MHZ
&& freq
!= SAA7115_FREQ_24_576_MHZ
)
1381 state
->crystal_freq
= freq
;
1382 state
->double_asclk
= flags
& SAA7115_FREQ_FL_DOUBLE_ASCLK
;
1383 state
->cgcdiv
= (flags
& SAA7115_FREQ_FL_CGCDIV
) ? 3 : 4;
1384 state
->ucgc
= flags
& SAA7115_FREQ_FL_UCGC
;
1385 state
->apll
= flags
& SAA7115_FREQ_FL_APLL
;
1386 saa711x_s_clock_freq(sd
, state
->audclk_freq
);
1390 static int saa711x_reset(struct v4l2_subdev
*sd
, u32 val
)
1392 v4l2_dbg(1, debug
, sd
, "decoder RESET\n");
1393 saa711x_writeregs(sd
, saa7115_cfg_reset_scaler
);
1397 static int saa711x_g_vbi_data(struct v4l2_subdev
*sd
, struct v4l2_sliced_vbi_data
*data
)
1399 /* Note: the internal field ID is inverted for NTSC,
1400 so data->field 0 maps to the saa7115 even field,
1401 whereas for PAL it maps to the saa7115 odd field. */
1403 case V4L2_SLICED_WSS_625
:
1404 if (saa711x_read(sd
, 0x6b) & 0xc0)
1406 data
->data
[0] = saa711x_read(sd
, 0x6c);
1407 data
->data
[1] = saa711x_read(sd
, 0x6d);
1409 case V4L2_SLICED_CAPTION_525
:
1410 if (data
->field
== 0) {
1412 if (saa711x_read(sd
, 0x66) & 0x30)
1414 data
->data
[0] = saa711x_read(sd
, 0x69);
1415 data
->data
[1] = saa711x_read(sd
, 0x6a);
1419 if (saa711x_read(sd
, 0x66) & 0xc0)
1421 data
->data
[0] = saa711x_read(sd
, 0x67);
1422 data
->data
[1] = saa711x_read(sd
, 0x68);
1429 static int saa711x_querystd(struct v4l2_subdev
*sd
, v4l2_std_id
*std
)
1431 struct saa711x_state
*state
= to_state(sd
);
1435 * The V4L2 core already initializes std with all supported
1436 * Standards. All driver needs to do is to mask it, to remove
1437 * standards that don't apply from the mask
1440 reg1f
= saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
);
1442 if (state
->ident
== SAA7115
) {
1443 reg1e
= saa711x_read(sd
, R_1E_STATUS_BYTE_1_VD_DEC
);
1445 v4l2_dbg(1, debug
, sd
, "Status byte 1 (0x1e)=0x%02x\n", reg1e
);
1447 switch (reg1e
& 0x03) {
1449 *std
&= V4L2_STD_NTSC
;
1453 * V4L2_STD_PAL just cover the european PAL standards.
1454 * This is wrong, as the device could also be using an
1455 * other PAL standard.
1457 *std
&= V4L2_STD_PAL
| V4L2_STD_PAL_N
| V4L2_STD_PAL_Nc
|
1458 V4L2_STD_PAL_M
| V4L2_STD_PAL_60
;
1461 *std
&= V4L2_STD_SECAM
;
1464 *std
= V4L2_STD_UNKNOWN
;
1465 /* Can't detect anything */
1470 v4l2_dbg(1, debug
, sd
, "Status byte 2 (0x1f)=0x%02x\n", reg1f
);
1472 /* horizontal/vertical not locked */
1474 *std
= V4L2_STD_UNKNOWN
;
1479 *std
&= V4L2_STD_525_60
;
1481 *std
&= V4L2_STD_625_50
;
1484 v4l2_dbg(1, debug
, sd
, "detected std mask = %08Lx\n", *std
);
1489 static int saa711x_g_input_status(struct v4l2_subdev
*sd
, u32
*status
)
1491 struct saa711x_state
*state
= to_state(sd
);
1495 *status
= V4L2_IN_ST_NO_SIGNAL
;
1496 if (state
->ident
== SAA7115
)
1497 reg1e
= saa711x_read(sd
, R_1E_STATUS_BYTE_1_VD_DEC
);
1498 reg1f
= saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
);
1499 if ((reg1f
& 0xc1) == 0x81 && (reg1e
& 0xc0) == 0x80)
1504 #ifdef CONFIG_VIDEO_ADV_DEBUG
1505 static int saa711x_g_register(struct v4l2_subdev
*sd
, struct v4l2_dbg_register
*reg
)
1507 reg
->val
= saa711x_read(sd
, reg
->reg
& 0xff);
1512 static int saa711x_s_register(struct v4l2_subdev
*sd
, const struct v4l2_dbg_register
*reg
)
1514 saa711x_write(sd
, reg
->reg
& 0xff, reg
->val
& 0xff);
1519 static int saa711x_log_status(struct v4l2_subdev
*sd
)
1521 struct saa711x_state
*state
= to_state(sd
);
1526 v4l2_info(sd
, "Audio frequency: %d Hz\n", state
->audclk_freq
);
1527 if (state
->ident
!= SAA7115
) {
1528 /* status for the saa7114 */
1529 reg1f
= saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
);
1530 signalOk
= (reg1f
& 0xc1) == 0x81;
1531 v4l2_info(sd
, "Video signal: %s\n", signalOk
? "ok" : "bad");
1532 v4l2_info(sd
, "Frequency: %s\n", (reg1f
& 0x20) ? "60 Hz" : "50 Hz");
1536 /* status for the saa7115 */
1537 reg1e
= saa711x_read(sd
, R_1E_STATUS_BYTE_1_VD_DEC
);
1538 reg1f
= saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
);
1540 signalOk
= (reg1f
& 0xc1) == 0x81 && (reg1e
& 0xc0) == 0x80;
1541 vcr
= !(reg1f
& 0x10);
1543 if (state
->input
>= 6)
1544 v4l2_info(sd
, "Input: S-Video %d\n", state
->input
- 6);
1546 v4l2_info(sd
, "Input: Composite %d\n", state
->input
);
1547 v4l2_info(sd
, "Video signal: %s\n", signalOk
? (vcr
? "VCR" : "broadcast/DVD") : "bad");
1548 v4l2_info(sd
, "Frequency: %s\n", (reg1f
& 0x20) ? "60 Hz" : "50 Hz");
1550 switch (reg1e
& 0x03) {
1552 v4l2_info(sd
, "Detected format: NTSC\n");
1555 v4l2_info(sd
, "Detected format: PAL\n");
1558 v4l2_info(sd
, "Detected format: SECAM\n");
1561 v4l2_info(sd
, "Detected format: BW/No color\n");
1564 v4l2_info(sd
, "Width, Height: %d, %d\n", state
->width
, state
->height
);
1565 v4l2_ctrl_handler_log_status(&state
->hdl
, sd
->name
);
1569 /* ----------------------------------------------------------------------- */
1571 static const struct v4l2_ctrl_ops saa711x_ctrl_ops
= {
1572 .s_ctrl
= saa711x_s_ctrl
,
1573 .g_volatile_ctrl
= saa711x_g_volatile_ctrl
,
1576 static const struct v4l2_subdev_core_ops saa711x_core_ops
= {
1577 .log_status
= saa711x_log_status
,
1578 .g_ext_ctrls
= v4l2_subdev_g_ext_ctrls
,
1579 .try_ext_ctrls
= v4l2_subdev_try_ext_ctrls
,
1580 .s_ext_ctrls
= v4l2_subdev_s_ext_ctrls
,
1581 .g_ctrl
= v4l2_subdev_g_ctrl
,
1582 .s_ctrl
= v4l2_subdev_s_ctrl
,
1583 .queryctrl
= v4l2_subdev_queryctrl
,
1584 .querymenu
= v4l2_subdev_querymenu
,
1585 .reset
= saa711x_reset
,
1586 .s_gpio
= saa711x_s_gpio
,
1587 #ifdef CONFIG_VIDEO_ADV_DEBUG
1588 .g_register
= saa711x_g_register
,
1589 .s_register
= saa711x_s_register
,
1593 static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops
= {
1594 .s_radio
= saa711x_s_radio
,
1595 .g_tuner
= saa711x_g_tuner
,
1598 static const struct v4l2_subdev_audio_ops saa711x_audio_ops
= {
1599 .s_clock_freq
= saa711x_s_clock_freq
,
1602 static const struct v4l2_subdev_video_ops saa711x_video_ops
= {
1603 .s_std
= saa711x_s_std
,
1604 .s_routing
= saa711x_s_routing
,
1605 .s_crystal_freq
= saa711x_s_crystal_freq
,
1606 .s_mbus_fmt
= saa711x_s_mbus_fmt
,
1607 .s_stream
= saa711x_s_stream
,
1608 .querystd
= saa711x_querystd
,
1609 .g_input_status
= saa711x_g_input_status
,
1612 static const struct v4l2_subdev_vbi_ops saa711x_vbi_ops
= {
1613 .g_vbi_data
= saa711x_g_vbi_data
,
1614 .decode_vbi_line
= saa711x_decode_vbi_line
,
1615 .g_sliced_fmt
= saa711x_g_sliced_fmt
,
1616 .s_sliced_fmt
= saa711x_s_sliced_fmt
,
1617 .s_raw_fmt
= saa711x_s_raw_fmt
,
1620 static const struct v4l2_subdev_ops saa711x_ops
= {
1621 .core
= &saa711x_core_ops
,
1622 .tuner
= &saa711x_tuner_ops
,
1623 .audio
= &saa711x_audio_ops
,
1624 .video
= &saa711x_video_ops
,
1625 .vbi
= &saa711x_vbi_ops
,
1628 #define CHIP_VER_SIZE 16
1630 /* ----------------------------------------------------------------------- */
1632 static void saa711x_write_platform_data(struct saa711x_state
*state
,
1633 struct saa7115_platform_data
*data
)
1635 struct v4l2_subdev
*sd
= &state
->sd
;
1638 if (state
->ident
!= GM7113C
&&
1639 state
->ident
!= SAA7113
)
1642 if (data
->saa7113_r08_htc
) {
1643 work
= saa711x_read(sd
, R_08_SYNC_CNTL
);
1644 work
&= ~SAA7113_R_08_HTC_MASK
;
1645 work
|= ((*data
->saa7113_r08_htc
) << SAA7113_R_08_HTC_OFFSET
);
1646 saa711x_write(sd
, R_08_SYNC_CNTL
, work
);
1649 if (data
->saa7113_r10_vrln
) {
1650 work
= saa711x_read(sd
, R_10_CHROMA_CNTL_2
);
1651 work
&= ~SAA7113_R_10_VRLN_MASK
;
1652 if (*data
->saa7113_r10_vrln
)
1653 work
|= (1 << SAA7113_R_10_VRLN_OFFSET
);
1654 saa711x_write(sd
, R_10_CHROMA_CNTL_2
, work
);
1657 if (data
->saa7113_r10_ofts
) {
1658 work
= saa711x_read(sd
, R_10_CHROMA_CNTL_2
);
1659 work
&= ~SAA7113_R_10_OFTS_MASK
;
1660 work
|= (*data
->saa7113_r10_ofts
<< SAA7113_R_10_OFTS_OFFSET
);
1661 saa711x_write(sd
, R_10_CHROMA_CNTL_2
, work
);
1664 if (data
->saa7113_r12_rts0
) {
1665 work
= saa711x_read(sd
, R_12_RT_SIGNAL_CNTL
);
1666 work
&= ~SAA7113_R_12_RTS0_MASK
;
1667 work
|= (*data
->saa7113_r12_rts0
<< SAA7113_R_12_RTS0_OFFSET
);
1669 /* According to the datasheet,
1670 * SAA7113_RTS_DOT_IN should only be used on RTS1 */
1671 WARN_ON(*data
->saa7113_r12_rts0
== SAA7113_RTS_DOT_IN
);
1672 saa711x_write(sd
, R_12_RT_SIGNAL_CNTL
, work
);
1675 if (data
->saa7113_r12_rts1
) {
1676 work
= saa711x_read(sd
, R_12_RT_SIGNAL_CNTL
);
1677 work
&= ~SAA7113_R_12_RTS1_MASK
;
1678 work
|= (*data
->saa7113_r12_rts1
<< SAA7113_R_12_RTS1_OFFSET
);
1679 saa711x_write(sd
, R_12_RT_SIGNAL_CNTL
, work
);
1682 if (data
->saa7113_r13_adlsb
) {
1683 work
= saa711x_read(sd
, R_13_RT_X_PORT_OUT_CNTL
);
1684 work
&= ~SAA7113_R_13_ADLSB_MASK
;
1685 if (*data
->saa7113_r13_adlsb
)
1686 work
|= (1 << SAA7113_R_13_ADLSB_OFFSET
);
1687 saa711x_write(sd
, R_13_RT_X_PORT_OUT_CNTL
, work
);
1692 * saa711x_detect_chip - Detects the saa711x (or clone) variant
1693 * @client: I2C client structure.
1694 * @id: I2C device ID structure.
1695 * @name: Name of the device to be filled.
1697 * Detects the Philips/NXP saa711x chip, or some clone of it.
1698 * if 'id' is NULL or id->driver_data is equal to 1, it auto-probes
1700 * If the tuner is not found, it returns -ENODEV.
1701 * If auto-detection is disabled and the tuner doesn't match what it was
1702 * required, it returns -EINVAL and fills 'name'.
1703 * If the chip is found, it returns the chip ID and fills 'name'.
1705 static int saa711x_detect_chip(struct i2c_client
*client
,
1706 const struct i2c_device_id
*id
,
1709 char chip_ver
[CHIP_VER_SIZE
];
1714 autodetect
= !id
|| id
->driver_data
== 1;
1716 /* Read the chip version register */
1717 for (i
= 0; i
< CHIP_VER_SIZE
; i
++) {
1718 i2c_smbus_write_byte_data(client
, 0, i
);
1719 chip_ver
[i
] = i2c_smbus_read_byte_data(client
, 0);
1720 name
[i
] = (chip_ver
[i
] & 0x0f) + '0';
1722 name
[i
] += 'a' - '9' - 1;
1726 /* Check if it is a Philips/NXP chip */
1727 if (!memcmp(name
+ 1, "f711", 4)) {
1729 snprintf(name
, CHIP_VER_SIZE
, "saa711%c", chip_id
);
1731 if (!autodetect
&& strcmp(name
, id
->name
))
1736 if (chip_ver
[0] & 0xf0) {
1737 snprintf(name
, CHIP_VER_SIZE
, "saa711%ca", chip_id
);
1738 v4l_info(client
, "saa7111a variant found\n");
1752 "WARNING: Philips/NXP chip unknown - Falling back to saa7111\n");
1757 /* Check if it is a gm7113c */
1758 if (!memcmp(name
, "0000", 4)) {
1760 for (i
= 0; i
< 4; i
++) {
1761 chip_id
= chip_id
<< 1;
1762 chip_id
|= (chip_ver
[i
] & 0x80) ? 1 : 0;
1766 * Note: From the datasheet, only versions 1 and 2
1767 * exists. However, tests on a device labeled as:
1768 * "GM7113C 1145" returned "10" on all 16 chip
1769 * version (reg 0x00) reads. So, we need to also
1770 * accept at least verion 0. For now, let's just
1771 * assume that a device that returns "0000" for
1772 * the lower nibble is a gm7113c.
1775 strlcpy(name
, "gm7113c", CHIP_VER_SIZE
);
1777 if (!autodetect
&& strcmp(name
, id
->name
))
1780 v4l_dbg(1, debug
, client
,
1781 "It seems to be a %s chip (%*ph) @ 0x%x.\n",
1782 name
, 16, chip_ver
, client
->addr
<< 1);
1787 /* Chip was not discovered. Return its ID and don't bind */
1788 v4l_dbg(1, debug
, client
, "chip %*ph @ 0x%x is unknown.\n",
1789 16, chip_ver
, client
->addr
<< 1);
1793 static int saa711x_probe(struct i2c_client
*client
,
1794 const struct i2c_device_id
*id
)
1796 struct saa711x_state
*state
;
1797 struct v4l2_subdev
*sd
;
1798 struct v4l2_ctrl_handler
*hdl
;
1799 struct saa7115_platform_data
*pdata
;
1801 char name
[CHIP_VER_SIZE
+ 1];
1803 /* Check if the adapter supports the needed features */
1804 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_SMBUS_BYTE_DATA
))
1807 ident
= saa711x_detect_chip(client
, id
, name
);
1808 if (ident
== -EINVAL
) {
1809 /* Chip exists, but doesn't match */
1810 v4l_warn(client
, "found %s while %s was expected\n",
1817 strlcpy(client
->name
, name
, sizeof(client
->name
));
1819 state
= devm_kzalloc(&client
->dev
, sizeof(*state
), GFP_KERNEL
);
1823 v4l2_i2c_subdev_init(sd
, client
, &saa711x_ops
);
1825 v4l_info(client
, "%s found @ 0x%x (%s)\n", name
,
1826 client
->addr
<< 1, client
->adapter
->name
);
1828 v4l2_ctrl_handler_init(hdl
, 6);
1829 /* add in ascending ID order */
1830 v4l2_ctrl_new_std(hdl
, &saa711x_ctrl_ops
,
1831 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 128);
1832 v4l2_ctrl_new_std(hdl
, &saa711x_ctrl_ops
,
1833 V4L2_CID_CONTRAST
, 0, 127, 1, 64);
1834 v4l2_ctrl_new_std(hdl
, &saa711x_ctrl_ops
,
1835 V4L2_CID_SATURATION
, 0, 127, 1, 64);
1836 v4l2_ctrl_new_std(hdl
, &saa711x_ctrl_ops
,
1837 V4L2_CID_HUE
, -128, 127, 1, 0);
1838 state
->agc
= v4l2_ctrl_new_std(hdl
, &saa711x_ctrl_ops
,
1839 V4L2_CID_CHROMA_AGC
, 0, 1, 1, 1);
1840 state
->gain
= v4l2_ctrl_new_std(hdl
, &saa711x_ctrl_ops
,
1841 V4L2_CID_CHROMA_GAIN
, 0, 127, 1, 40);
1842 sd
->ctrl_handler
= hdl
;
1844 int err
= hdl
->error
;
1846 v4l2_ctrl_handler_free(hdl
);
1849 v4l2_ctrl_auto_cluster(2, &state
->agc
, 0, true);
1852 state
->output
= SAA7115_IPORT_ON
;
1855 state
->ident
= ident
;
1857 state
->audclk_freq
= 48000;
1859 v4l2_dbg(1, debug
, sd
, "writing init values\n");
1861 /* init to 60hz/48khz */
1862 state
->crystal_freq
= SAA7115_FREQ_24_576_MHZ
;
1863 pdata
= client
->dev
.platform_data
;
1864 switch (state
->ident
) {
1867 saa711x_writeregs(sd
, saa7111_init
);
1870 saa711x_writeregs(sd
, gm7113c_init
);
1873 if (pdata
&& pdata
->saa7113_force_gm7113c_init
)
1874 saa711x_writeregs(sd
, gm7113c_init
);
1876 saa711x_writeregs(sd
, saa7113_init
);
1879 state
->crystal_freq
= SAA7115_FREQ_32_11_MHZ
;
1880 saa711x_writeregs(sd
, saa7115_init_auto_input
);
1882 if (state
->ident
> SAA7111A
&& state
->ident
!= GM7113C
)
1883 saa711x_writeregs(sd
, saa7115_init_misc
);
1886 saa711x_write_platform_data(state
, pdata
);
1888 saa711x_set_v4lstd(sd
, V4L2_STD_NTSC
);
1889 v4l2_ctrl_handler_setup(hdl
);
1891 v4l2_dbg(1, debug
, sd
, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1892 saa711x_read(sd
, R_1E_STATUS_BYTE_1_VD_DEC
),
1893 saa711x_read(sd
, R_1F_STATUS_BYTE_2_VD_DEC
));
1897 /* ----------------------------------------------------------------------- */
1899 static int saa711x_remove(struct i2c_client
*client
)
1901 struct v4l2_subdev
*sd
= i2c_get_clientdata(client
);
1903 v4l2_device_unregister_subdev(sd
);
1904 v4l2_ctrl_handler_free(sd
->ctrl_handler
);
1908 static const struct i2c_device_id saa711x_id
[] = {
1909 { "saa7115_auto", 1 }, /* autodetect */
1918 MODULE_DEVICE_TABLE(i2c
, saa711x_id
);
1920 static struct i2c_driver saa711x_driver
= {
1922 .owner
= THIS_MODULE
,
1925 .probe
= saa711x_probe
,
1926 .remove
= saa711x_remove
,
1927 .id_table
= saa711x_id
,
1930 module_i2c_driver(saa711x_driver
);