1 /* saa711x - Philips SAA711x video decoder driver
2 * This driver can work with saa7111, saa7111a, saa7113, saa7114,
5 * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
6 * the saa7111 driver by Dave Perks.
8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
11 * Slight changes for video timing and attachment output by
12 * Wolfgang Scherr <scherr@net4you.net>
14 * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
15 * by Ronald Bultje <rbultje@ronald.bitfreak.net>
17 * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
20 * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
22 * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
23 * SAA7111, SAA7113 and SAA7118 support
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version 2
28 * of the License, or (at your option) any later version.
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
40 #include "saa711x_regs.h"
42 #include <linux/kernel.h>
43 #include <linux/module.h>
44 #include <linux/slab.h>
45 #include <linux/i2c.h>
46 #include <linux/videodev2.h>
47 #include <media/v4l2-common.h>
48 #include <media/saa7115.h>
49 #include <asm/div64.h>
51 #define VRES_60HZ (480+16)
53 MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
54 MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
55 "Hans Verkuil, Mauro Carvalho Chehab");
56 MODULE_LICENSE("GPL");
59 module_param(debug, bool, 0644);
61 MODULE_PARM_DESC(debug, "Debug level (0-1)");
63 static unsigned short normal_i2c[] = {
64 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
65 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
71 struct saa711x_state {
82 enum v4l2_chip_ident ident;
90 /* ----------------------------------------------------------------------- */
92 static inline int saa711x_write(struct i2c_client *client, u8 reg, u8 value)
94 return i2c_smbus_write_byte_data(client, reg, value);
97 /* Sanity routine to check if a register is present */
98 static int saa711x_has_reg(const int id, const u8 reg)
100 if (id == V4L2_IDENT_SAA7111)
101 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
102 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
104 /* common for saa7113/4/5/8 */
105 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
106 reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
107 reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
108 reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
112 case V4L2_IDENT_SAA7113:
113 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
114 reg != 0x5d && reg < 0x63;
115 case V4L2_IDENT_SAA7114:
116 return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
117 (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
118 reg != 0x81 && reg < 0xf0;
119 case V4L2_IDENT_SAA7115:
120 return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
121 case V4L2_IDENT_SAA7118:
122 return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
123 (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
124 (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
129 static int saa711x_writeregs(struct i2c_client *client, const unsigned char *regs)
131 struct saa711x_state *state = i2c_get_clientdata(client);
132 unsigned char reg, data;
134 while (*regs != 0x00) {
138 /* According with datasheets, reserved regs should be
139 filled with 0 - seems better not to touch on they */
140 if (saa711x_has_reg(state->ident,reg)) {
141 if (saa711x_write(client, reg, data) < 0)
144 v4l_dbg(1, debug, client, "tried to access reserved reg 0x%02x\n", reg);
150 static inline int saa711x_read(struct i2c_client *client, u8 reg)
152 return i2c_smbus_read_byte_data(client, reg);
155 /* ----------------------------------------------------------------------- */
157 /* SAA7111 initialization table */
158 static const unsigned char saa7111_init[] = {
159 R_01_INC_DELAY, 0x00, /* reserved */
162 R_02_INPUT_CNTL_1, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */
163 R_03_INPUT_CNTL_2, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
164 * GAFIX=0, GAI1=256, GAI2=256 */
165 R_04_INPUT_CNTL_3, 0x00, /* GAI1=256 */
166 R_05_INPUT_CNTL_4, 0x00, /* GAI2=256 */
169 R_06_H_SYNC_START, 0xf3, /* HSB at 13(50Hz) / 17(60Hz)
170 * pixels after end of last line */
171 R_07_H_SYNC_STOP, 0xe8, /* HSS seems to be needed to
172 * work with NTSC, too */
173 R_08_SYNC_CNTL, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0,
174 * VTRC=1, HPLL=0, VNOI=0 */
175 R_09_LUMA_CNTL, 0x01, /* BYPS=0, PREF=0, BPSS=0,
176 * VBLB=0, UPTCV=0, APER=1 */
177 R_0A_LUMA_BRIGHT_CNTL, 0x80,
178 R_0B_LUMA_CONTRAST_CNTL, 0x47, /* 0b - CONT=1.109 */
179 R_0C_CHROMA_SAT_CNTL, 0x40,
180 R_0D_CHROMA_HUE_CNTL, 0x00,
181 R_0E_CHROMA_CNTL_1, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
183 R_0F_CHROMA_GAIN_CNTL, 0x00, /* reserved */
184 R_10_CHROMA_CNTL_2, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
185 R_11_MODE_DELAY_CNTL, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
186 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
187 R_12_RT_SIGNAL_CNTL, 0x00, /* 12 - output control 2 */
188 R_13_RT_X_PORT_OUT_CNTL, 0x00, /* 13 - output control 3 */
189 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
190 R_15_VGATE_START_FID_CHG, 0x00,
191 R_16_VGATE_STOP, 0x00,
192 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
197 /* SAA7113 init codes */
198 static const unsigned char saa7113_init[] = {
199 R_01_INC_DELAY, 0x08,
200 R_02_INPUT_CNTL_1, 0xc2,
201 R_03_INPUT_CNTL_2, 0x30,
202 R_04_INPUT_CNTL_3, 0x00,
203 R_05_INPUT_CNTL_4, 0x00,
204 R_06_H_SYNC_START, 0x89,
205 R_07_H_SYNC_STOP, 0x0d,
206 R_08_SYNC_CNTL, 0x88,
207 R_09_LUMA_CNTL, 0x01,
208 R_0A_LUMA_BRIGHT_CNTL, 0x80,
209 R_0B_LUMA_CONTRAST_CNTL, 0x47,
210 R_0C_CHROMA_SAT_CNTL, 0x40,
211 R_0D_CHROMA_HUE_CNTL, 0x00,
212 R_0E_CHROMA_CNTL_1, 0x01,
213 R_0F_CHROMA_GAIN_CNTL, 0x2a,
214 R_10_CHROMA_CNTL_2, 0x08,
215 R_11_MODE_DELAY_CNTL, 0x0c,
216 R_12_RT_SIGNAL_CNTL, 0x07,
217 R_13_RT_X_PORT_OUT_CNTL, 0x00,
218 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
219 R_15_VGATE_START_FID_CHG, 0x00,
220 R_16_VGATE_STOP, 0x00,
221 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
226 /* If a value differs from the Hauppauge driver values, then the comment starts with
227 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
228 Hauppauge driver sets. */
230 /* SAA7114 and SAA7115 initialization table */
231 static const unsigned char saa7115_init_auto_input[] = {
233 R_01_INC_DELAY, 0x48, /* white peak control disabled */
234 R_03_INPUT_CNTL_2, 0x20, /* was 0x30. 0x20: long vertical blanking */
235 R_04_INPUT_CNTL_3, 0x90, /* analog gain set to 0 */
236 R_05_INPUT_CNTL_4, 0x90, /* analog gain set to 0 */
238 R_06_H_SYNC_START, 0xeb, /* horiz sync begin = -21 */
239 R_07_H_SYNC_STOP, 0xe0, /* horiz sync stop = -17 */
240 R_09_LUMA_CNTL, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
241 R_0A_LUMA_BRIGHT_CNTL, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
242 R_0B_LUMA_CONTRAST_CNTL, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
243 R_0C_CHROMA_SAT_CNTL, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
244 R_0D_CHROMA_HUE_CNTL, 0x00,
245 R_0F_CHROMA_GAIN_CNTL, 0x00, /* use automatic gain */
246 R_10_CHROMA_CNTL_2, 0x06, /* chroma: active adaptive combfilter */
247 R_11_MODE_DELAY_CNTL, 0x00,
248 R_12_RT_SIGNAL_CNTL, 0x9d, /* RTS0 output control: VGATE */
249 R_13_RT_X_PORT_OUT_CNTL, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */
250 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
251 R_18_RAW_DATA_GAIN_CNTL, 0x40, /* gain 0x00 = nominal */
252 R_19_RAW_DATA_OFF_CNTL, 0x80,
253 R_1A_COLOR_KILL_LVL_CNTL, 0x77, /* recommended value */
254 R_1B_MISC_TVVCRDET, 0x42, /* recommended value */
255 R_1C_ENHAN_COMB_CTRL1, 0xa9, /* recommended value */
256 R_1D_ENHAN_COMB_CTRL2, 0x01, /* recommended value */
259 R_80_GLOBAL_CNTL_1, 0x0, /* No tasks enabled at init */
261 /* Power Device Control */
262 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset device */
263 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* set device programmed, all in operational mode */
267 /* Used to reset saa7113, saa7114 and saa7115 */
268 static const unsigned char saa7115_cfg_reset_scaler[] = {
269 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00, /* disable I-port output */
270 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
271 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
272 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* enable I-port output */
276 /* ============== SAA7715 VIDEO templates ============= */
278 static const unsigned char saa7115_cfg_60hz_video[] = {
279 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
280 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
282 R_15_VGATE_START_FID_CHG, 0x03,
283 R_16_VGATE_STOP, 0x11,
284 R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
286 R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
287 R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */
289 R_5A_V_OFF_FOR_SLICER, 0x06, /* standard 60hz value for ITU656 line counting */
292 R_90_A_TASK_HANDLING_CNTL, 0x80,
293 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
294 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
295 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
297 /* hoffset low (input), 0x0002 is minimum */
298 R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
299 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
301 /* hsize low (input), 0x02d0 = 720 */
302 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
303 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
305 R_98_A_VERT_INPUT_WINDOW_START, 0x05,
306 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
308 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
309 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
311 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
312 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
314 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
315 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
318 R_C0_B_TASK_HANDLING_CNTL, 0x00,
319 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
320 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
321 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
323 /* 0x0002 is minimum */
324 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
325 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
328 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
329 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
331 /* vwindow start 0x12 = 18 */
332 R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
333 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
335 /* vwindow length 0xf8 = 248 */
336 R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
337 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
339 /* hwindow 0x02d0 = 720 */
340 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
341 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
343 R_F0_LFCO_PER_LINE, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
344 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0 */
345 R_F5_PULSGEN_LINE_LENGTH, 0xad,
346 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
351 static const unsigned char saa7115_cfg_50hz_video[] = {
352 R_80_GLOBAL_CNTL_1, 0x00,
353 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
355 R_15_VGATE_START_FID_CHG, 0x37, /* VGATE start */
356 R_16_VGATE_STOP, 0x16,
357 R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
359 R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */
360 R_0E_CHROMA_CNTL_1, 0x07,
362 R_5A_V_OFF_FOR_SLICER, 0x03, /* standard 50hz value */
365 R_90_A_TASK_HANDLING_CNTL, 0x81,
366 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
367 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
368 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
370 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
371 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
372 /* hoffset low (input), 0x0002 is minimum */
373 R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
374 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
376 /* hsize low (input), 0x02d0 = 720 */
377 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
378 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
380 R_98_A_VERT_INPUT_WINDOW_START, 0x03,
381 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
383 /* vsize 0x12 = 18 */
384 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
385 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
387 /* hsize 0x05a0 = 1440 */
388 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
389 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05, /* hsize hi (output) */
390 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12, /* vsize low (output), 0x12 = 18 */
391 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00, /* vsize hi (output) */
394 R_C0_B_TASK_HANDLING_CNTL, 0x00,
395 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
396 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
397 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
399 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
400 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
401 /* hoffset low (input), 0x0002 is minimum. See comment above. */
402 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
403 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
405 /* hsize 0x02d0 = 720 */
406 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
407 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
409 /* voffset 0x16 = 22 */
410 R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
411 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
413 /* vsize 0x0120 = 288 */
414 R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
415 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
417 /* hsize 0x02d0 = 720 */
418 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
419 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
421 R_F0_LFCO_PER_LINE, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
422 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0, (was 0x05) */
423 R_F5_PULSGEN_LINE_LENGTH, 0xb0,
424 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
429 /* ============== SAA7715 VIDEO templates (end) ======= */
431 static const unsigned char saa7115_cfg_vbi_on[] = {
432 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
433 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
434 R_80_GLOBAL_CNTL_1, 0x30, /* Activate both tasks */
435 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
436 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
441 static const unsigned char saa7115_cfg_vbi_off[] = {
442 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
443 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
444 R_80_GLOBAL_CNTL_1, 0x20, /* Activate only task "B" */
445 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
446 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
452 static const unsigned char saa7115_init_misc[] = {
453 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
454 R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
455 R_84_I_PORT_SIGNAL_DEF, 0x20,
456 R_85_I_PORT_SIGNAL_POLAR, 0x21,
457 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
458 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
461 R_A0_A_HORIZ_PRESCALING, 0x01,
462 R_A1_A_ACCUMULATION_LENGTH, 0x00,
463 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
465 /* Configure controls at nominal value*/
466 R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
467 R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
468 R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
470 /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
471 R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
472 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
474 R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
476 /* must be horiz lum scaling / 2 */
477 R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
478 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
480 /* must be offset luma / 2 */
481 R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
483 R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
484 R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
486 R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
487 R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
489 R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
491 R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
492 R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
493 R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
494 R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
496 R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
497 R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
498 R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
499 R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
502 R_D0_B_HORIZ_PRESCALING, 0x01,
503 R_D1_B_ACCUMULATION_LENGTH, 0x00,
504 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
506 /* Configure controls at nominal value*/
507 R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
508 R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
509 R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
511 /* hor lum scaling 0x0400 = 1 */
512 R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
513 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
515 R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
517 /* must be hor lum scaling / 2 */
518 R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
519 R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
521 /* must be offset luma / 2 */
522 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
524 R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
525 R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
527 R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
528 R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
530 R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
532 R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
533 R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
534 R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
535 R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
537 R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
538 R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
539 R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
540 R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
542 R_F2_NOMINAL_PLL2_DTO, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
543 R_F3_PLL_INCREMENT, 0x46,
544 R_F4_PLL2_STATUS, 0x00,
545 R_F7_PULSE_A_POS_MSB, 0x4b, /* not the recommended settings! */
546 R_F8_PULSE_B_POS, 0x00,
547 R_F9_PULSE_B_POS_MSB, 0x4b,
548 R_FA_PULSE_C_POS, 0x00,
549 R_FB_PULSE_C_POS_MSB, 0x4b,
551 /* PLL2 lock detection settings: 71 lines 50% phase error */
552 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
555 R_40_SLICER_CNTL_1, 0x20, /* No framing code errors allowed. */
557 R_41_LCR_BASE+1, 0xff,
558 R_41_LCR_BASE+2, 0xff,
559 R_41_LCR_BASE+3, 0xff,
560 R_41_LCR_BASE+4, 0xff,
561 R_41_LCR_BASE+5, 0xff,
562 R_41_LCR_BASE+6, 0xff,
563 R_41_LCR_BASE+7, 0xff,
564 R_41_LCR_BASE+8, 0xff,
565 R_41_LCR_BASE+9, 0xff,
566 R_41_LCR_BASE+10, 0xff,
567 R_41_LCR_BASE+11, 0xff,
568 R_41_LCR_BASE+12, 0xff,
569 R_41_LCR_BASE+13, 0xff,
570 R_41_LCR_BASE+14, 0xff,
571 R_41_LCR_BASE+15, 0xff,
572 R_41_LCR_BASE+16, 0xff,
573 R_41_LCR_BASE+17, 0xff,
574 R_41_LCR_BASE+18, 0xff,
575 R_41_LCR_BASE+19, 0xff,
576 R_41_LCR_BASE+20, 0xff,
577 R_41_LCR_BASE+21, 0xff,
578 R_41_LCR_BASE+22, 0xff,
579 R_58_PROGRAM_FRAMING_CODE, 0x40,
580 R_59_H_OFF_FOR_SLICER, 0x47,
581 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
585 R_02_INPUT_CNTL_1, 0x84, /* input tuner -> input 4, amplifier active */
587 R_80_GLOBAL_CNTL_1, 0x20, /* enable task B */
588 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
589 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
593 static int saa711x_odd_parity(u8 c)
602 static int saa711x_decode_vps(u8 * dst, u8 * p)
604 static const u8 biphase_tbl[] = {
605 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
606 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
607 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
608 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
609 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
610 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
611 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
612 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
613 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
614 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
615 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
616 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
617 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
618 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
619 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
620 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
621 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
622 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
623 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
624 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
625 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
626 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
627 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
628 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
629 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
630 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
631 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
632 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
633 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
634 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
635 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
636 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
641 for (i = 0; i < 2 * 13; i += 2) {
642 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
643 c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
649 static int saa711x_decode_wss(u8 * p)
651 static const int wss_bits[8] = {
652 0, 0, 0, 1, 0, 1, 1, 1
654 unsigned char parity;
658 for (i = 0; i < 16; i++) {
659 int b1 = wss_bits[p[i] & 7];
660 int b2 = wss_bits[(p[i] >> 3) & 7];
667 parity ^= parity >> 2;
668 parity ^= parity >> 1;
676 static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
678 struct saa711x_state *state = i2c_get_clientdata(client);
683 u8 acc = 0; /* reg 0x3a, audio clock control */
685 /* Checks for chips that don't have audio clock (saa7111, saa7113) */
686 if (!saa711x_has_reg(state->ident,R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
689 v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq);
692 if (freq < 32000 || freq > 48000)
695 /* hz is the refresh rate times 100 */
696 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
697 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
698 acpf = (25600 * freq) / hz;
699 /* acni = (256 * freq * 2^23) / crystal_frequency =
700 (freq * 2^(8+23)) / crystal_frequency =
701 (freq << 31) / crystal_frequency */
704 do_div(f, state->crystal_freq);
707 acpf = acpf * state->cgcdiv / 16;
708 acni = acni * state->cgcdiv / 16;
710 if (state->cgcdiv == 3)
716 saa711x_write(client, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
717 saa711x_write(client, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
718 saa711x_write(client, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
720 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
721 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
723 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
724 (acpf >> 16) & 0x03);
726 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
727 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
728 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
729 state->audclk_freq = freq;
733 static int saa711x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
735 struct saa711x_state *state = i2c_get_clientdata(client);
738 case V4L2_CID_BRIGHTNESS:
739 if (ctrl->value < 0 || ctrl->value > 255) {
740 v4l_err(client, "invalid brightness setting %d\n", ctrl->value);
744 state->bright = ctrl->value;
745 saa711x_write(client, R_0A_LUMA_BRIGHT_CNTL, state->bright);
748 case V4L2_CID_CONTRAST:
749 if (ctrl->value < 0 || ctrl->value > 127) {
750 v4l_err(client, "invalid contrast setting %d\n", ctrl->value);
754 state->contrast = ctrl->value;
755 saa711x_write(client, R_0B_LUMA_CONTRAST_CNTL, state->contrast);
758 case V4L2_CID_SATURATION:
759 if (ctrl->value < 0 || ctrl->value > 127) {
760 v4l_err(client, "invalid saturation setting %d\n", ctrl->value);
764 state->sat = ctrl->value;
765 saa711x_write(client, R_0C_CHROMA_SAT_CNTL, state->sat);
769 if (ctrl->value < -127 || ctrl->value > 127) {
770 v4l_err(client, "invalid hue setting %d\n", ctrl->value);
774 state->hue = ctrl->value;
775 saa711x_write(client, R_0D_CHROMA_HUE_CNTL, state->hue);
785 static int saa711x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
787 struct saa711x_state *state = i2c_get_clientdata(client);
790 case V4L2_CID_BRIGHTNESS:
791 ctrl->value = state->bright;
793 case V4L2_CID_CONTRAST:
794 ctrl->value = state->contrast;
796 case V4L2_CID_SATURATION:
797 ctrl->value = state->sat;
800 ctrl->value = state->hue;
809 static int saa711x_set_size(struct i2c_client *client, int width, int height)
811 struct saa711x_state *state = i2c_get_clientdata(client);
815 int is_50hz = state->std & V4L2_STD_625_50;
816 int Vsrc = is_50hz ? 576 : 480;
818 v4l_dbg(1, debug, client, "decoder set size to %ix%i\n",width,height);
820 /* FIXME need better bounds checking here */
821 if ((width < 1) || (width > 1440))
823 if ((height < 1) || (height > Vsrc))
826 if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) {
827 /* Decoder only supports 720 columns and 480 or 576 lines */
834 state->width = width;
835 state->height = height;
837 if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
840 /* probably have a valid size, let's set it */
841 /* Set output width/height */
844 saa711x_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
845 (u8) (width & 0xff));
846 saa711x_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
847 (u8) ((width >> 8) & 0xff));
849 /* Vertical Scaling uses height/2 */
852 /* On 60Hz, it is using a higher Vertical Output Size */
854 res+=(VRES_60HZ-480)>>1;
857 saa711x_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
859 saa711x_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
860 (u8) ((res >> 8) & 0xff));
862 /* Scaling settings */
863 /* Hprescaler is floor(inres/outres) */
864 HPSC = (int)(720 / width);
865 /* 0 is not allowed (div. by zero) */
866 HPSC = HPSC ? HPSC : 1;
867 HFSC = (int)((1024 * 720) / (HPSC * width));
868 /* FIXME hardcodes to "Task B"
869 * write H prescaler integer */
870 saa711x_write(client, R_D0_B_HORIZ_PRESCALING,
873 v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
874 /* write H fine-scaling (luminance) */
875 saa711x_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC,
877 saa711x_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
878 (u8) ((HFSC >> 8) & 0xff));
879 /* write H fine-scaling (chrominance)
880 * must be lum/2, so i'll just bitshift :) */
881 saa711x_write(client, R_DC_B_HORIZ_CHROMA_SCALING,
882 (u8) ((HFSC >> 1) & 0xff));
883 saa711x_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
884 (u8) ((HFSC >> 9) & 0xff));
886 VSCY = (int)((1024 * Vsrc) / height);
887 v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
889 /* Correct Contrast and Luminance */
890 saa711x_write(client, R_D5_B_LUMA_CONTRAST_CNTL,
891 (u8) (64 * 1024 / VSCY));
892 saa711x_write(client, R_D6_B_CHROMA_SATURATION_CNTL,
893 (u8) (64 * 1024 / VSCY));
895 /* write V fine-scaling (luminance) */
896 saa711x_write(client, R_E0_B_VERT_LUMA_SCALING_INC,
898 saa711x_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
899 (u8) ((VSCY >> 8) & 0xff));
900 /* write V fine-scaling (chrominance) */
901 saa711x_write(client, R_E2_B_VERT_CHROMA_SCALING_INC,
903 saa711x_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
904 (u8) ((VSCY >> 8) & 0xff));
906 saa711x_writeregs(client, saa7115_cfg_reset_scaler);
908 /* Activates task "B" */
909 saa711x_write(client, R_80_GLOBAL_CNTL_1,
910 saa711x_read(client,R_80_GLOBAL_CNTL_1)|0x20);
915 static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
917 struct saa711x_state *state = i2c_get_clientdata(client);
919 /* Prevent unnecessary standard changes. During a standard
920 change the I-Port is temporarily disabled. Any devices
921 reading from that port can get confused.
922 Note that VIDIOC_S_STD is also used to switch from
923 radio to TV mode, so if a VIDIOC_S_STD is broadcast to
924 all I2C devices then you do not want to have an unwanted
926 if (std == state->std)
931 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
932 if (std & V4L2_STD_525_60) {
933 v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n");
934 saa711x_writeregs(client, saa7115_cfg_60hz_video);
935 saa711x_set_size(client,720,480);
937 v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n");
938 saa711x_writeregs(client, saa7115_cfg_50hz_video);
939 saa711x_set_size(client,720,576);
942 /* Register 0E - Bits D6-D4 on NO-AUTO mode
943 (SAA7111 and SAA7113 doesn't have auto mode)
944 50 Hz / 625 lines 60 Hz / 525 lines
945 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz)
946 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz)
947 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
948 011 NTSC N (3.58MHz) PAL M (3.58MHz)
949 100 reserved NTSC-Japan (3.58MHz)
951 if (state->ident == V4L2_IDENT_SAA7111 ||
952 state->ident == V4L2_IDENT_SAA7113) {
953 u8 reg = saa711x_read(client, R_0E_CHROMA_CNTL_1) & 0x8f;
955 if (std == V4L2_STD_PAL_M) {
957 } else if (std == V4L2_STD_PAL_N) {
959 } else if (std == V4L2_STD_PAL_60) {
961 } else if (std == V4L2_STD_NTSC_M_JP) {
964 saa711x_write(client, R_0E_CHROMA_CNTL_1, reg);
966 /* restart task B if needed */
967 int taskb = saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10;
969 if (taskb && state->ident == V4L2_IDENT_SAA7114) {
970 saa711x_writeregs(client, saa7115_cfg_vbi_on);
973 /* switch audio mode too! */
974 saa711x_set_audio_clock_freq(client, state->audclk_freq);
978 static v4l2_std_id saa711x_get_v4lstd(struct i2c_client *client)
980 struct saa711x_state *state = i2c_get_clientdata(client);
985 static void saa711x_log_status(struct i2c_client *client)
987 struct saa711x_state *state = i2c_get_clientdata(client);
992 v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
993 if (state->ident != V4L2_IDENT_SAA7115) {
994 /* status for the saa7114 */
995 reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
996 signalOk = (reg1f & 0xc1) == 0x81;
997 v4l_info(client, "Video signal: %s\n", signalOk ? "ok" : "bad");
998 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1002 /* status for the saa7115 */
1003 reg1e = saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC);
1004 reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1006 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1007 vcr = !(reg1f & 0x10);
1009 if (state->input >= 6) {
1010 v4l_info(client, "Input: S-Video %d\n", state->input - 6);
1012 v4l_info(client, "Input: Composite %d\n", state->input);
1014 v4l_info(client, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1015 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1017 switch (reg1e & 0x03) {
1019 v4l_info(client, "Detected format: NTSC\n");
1022 v4l_info(client, "Detected format: PAL\n");
1025 v4l_info(client, "Detected format: SECAM\n");
1028 v4l_info(client, "Detected format: BW/No color\n");
1031 v4l_info(client, "Width, Height: %d, %d\n", state->width, state->height);
1034 /* setup the sliced VBI lcr registers according to the sliced VBI format */
1035 static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
1037 struct saa711x_state *state = i2c_get_clientdata(client);
1038 int is_50hz = (state->std & V4L2_STD_625_50);
1043 /* saa7113/7114/7118 VBI support are experimental */
1044 if (!saa711x_has_reg(state->ident,R_41_LCR_BASE))
1048 /* SAA7113 and SAA7118 also should support VBI - Need testing */
1049 if (state->ident != V4L2_IDENT_SAA7115)
1053 for (i = 0; i <= 23; i++)
1056 if (fmt->service_set == 0) {
1059 for (i = 6; i <= 23; i++)
1062 for (i = 10; i <= 21; i++)
1066 /* first clear lines that cannot be captured */
1068 for (i = 0; i <= 5; i++)
1069 fmt->service_lines[0][i] =
1070 fmt->service_lines[1][i] = 0;
1073 for (i = 0; i <= 9; i++)
1074 fmt->service_lines[0][i] =
1075 fmt->service_lines[1][i] = 0;
1076 for (i = 22; i <= 23; i++)
1077 fmt->service_lines[0][i] =
1078 fmt->service_lines[1][i] = 0;
1081 /* Now set the lcr values according to the specified service */
1082 for (i = 6; i <= 23; i++) {
1084 for (x = 0; x <= 1; x++) {
1085 switch (fmt->service_lines[1-x][i]) {
1087 lcr[i] |= 0xf << (4 * x);
1089 case V4L2_SLICED_TELETEXT_B:
1090 lcr[i] |= 1 << (4 * x);
1092 case V4L2_SLICED_CAPTION_525:
1093 lcr[i] |= 4 << (4 * x);
1095 case V4L2_SLICED_WSS_625:
1096 lcr[i] |= 5 << (4 * x);
1098 case V4L2_SLICED_VPS:
1099 lcr[i] |= 7 << (4 * x);
1106 /* write the lcr registers */
1107 for (i = 2; i <= 23; i++) {
1108 saa711x_write(client, i - 2 + R_41_LCR_BASE, lcr[i]);
1111 /* enable/disable raw VBI capturing */
1112 saa711x_writeregs(client, fmt->service_set == 0 ?
1113 saa7115_cfg_vbi_on :
1114 saa7115_cfg_vbi_off);
1117 static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
1119 static u16 lcr2vbi[] = {
1120 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
1121 0, V4L2_SLICED_CAPTION_525, /* 4 */
1122 V4L2_SLICED_WSS_625, 0, /* 5 */
1123 V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */
1126 struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;
1129 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
1131 memset(sliced, 0, sizeof(*sliced));
1132 /* done if using raw VBI */
1133 if (saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10)
1135 for (i = 2; i <= 23; i++) {
1136 u8 v = saa711x_read(client, i - 2 + R_41_LCR_BASE);
1138 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
1139 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
1140 sliced->service_set |=
1141 sliced->service_lines[0][i] | sliced->service_lines[1][i];
1146 static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
1148 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1149 saa711x_set_lcr(client, &fmt->fmt.sliced);
1152 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1155 return saa711x_set_size(client,fmt->fmt.pix.width,fmt->fmt.pix.height);
1158 /* Decode the sliced VBI data stream as created by the saa7115.
1159 The format is described in the saa7115 datasheet in Tables 25 and 26
1161 The current implementation uses SAV/EAV codes and not the ancillary data
1162 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1164 static void saa711x_decode_vbi_line(struct i2c_client *client,
1165 struct v4l2_decode_vbi_line *vbi)
1167 static const char vbi_no_data_pattern[] = {
1168 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1170 struct saa711x_state *state = i2c_get_clientdata(client);
1173 int id1, id2; /* the ID1 and ID2 bytes from the internal header */
1175 vbi->type = 0; /* mark result as a failure */
1178 /* Note: the field bit is inverted for 60 Hz video */
1179 if (state->std & V4L2_STD_525_60)
1182 /* Skip internal header, p now points to the start of the payload */
1186 /* calculate field and line number of the VBI packet (1-23) */
1187 vbi->is_second_field = ((id1 & 0x40) != 0);
1188 vbi->line = (id1 & 0x3f) << 3;
1189 vbi->line |= (id2 & 0x70) >> 4;
1191 /* Obtain data type */
1194 /* If the VBI slicer does not detect any signal it will fill up
1195 the payload buffer with 0xa0 bytes. */
1196 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
1199 /* decode payloads */
1202 vbi->type = V4L2_SLICED_TELETEXT_B;
1205 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1207 vbi->type = V4L2_SLICED_CAPTION_525;
1210 wss = saa711x_decode_wss(p);
1215 vbi->type = V4L2_SLICED_WSS_625;
1218 if (saa711x_decode_vps(p, p) != 0)
1220 vbi->type = V4L2_SLICED_VPS;
1227 /* ============ SAA7115 AUDIO settings (end) ============= */
1229 static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *arg)
1231 struct saa711x_state *state = i2c_get_clientdata(client);
1234 /* ioctls to allow direct access to the saa7115 registers for testing */
1237 return saa711x_set_v4lfmt(client, (struct v4l2_format *)arg);
1240 return saa711x_get_v4lfmt(client, (struct v4l2_format *)arg);
1242 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
1243 return saa711x_set_audio_clock_freq(client, *(u32 *)arg);
1245 case VIDIOC_G_TUNER:
1247 struct v4l2_tuner *vt = arg;
1252 status = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1254 v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
1255 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1259 case VIDIOC_LOG_STATUS:
1260 saa711x_log_status(client);
1264 return saa711x_get_v4lctrl(client, (struct v4l2_control *)arg);
1267 return saa711x_set_v4lctrl(client, (struct v4l2_control *)arg);
1269 case VIDIOC_QUERYCTRL:
1271 struct v4l2_queryctrl *qc = arg;
1274 case V4L2_CID_BRIGHTNESS:
1275 case V4L2_CID_CONTRAST:
1276 case V4L2_CID_SATURATION:
1278 return v4l2_ctrl_query_fill_std(qc);
1285 *(v4l2_std_id *)arg = saa711x_get_v4lstd(client);
1290 saa711x_set_v4lstd(client, *(v4l2_std_id *)arg);
1293 case AUDC_SET_RADIO:
1297 case VIDIOC_INT_G_VIDEO_ROUTING:
1299 struct v4l2_routing *route = arg;
1301 route->input = state->input;
1306 case VIDIOC_INT_S_VIDEO_ROUTING:
1308 struct v4l2_routing *route = arg;
1310 v4l_dbg(1, debug, client, "decoder set input %d\n", route->input);
1311 /* saa7113 does not have these inputs */
1312 if (state->ident == V4L2_IDENT_SAA7113 &&
1313 (route->input == SAA7115_COMPOSITE4 ||
1314 route->input == SAA7115_COMPOSITE5)) {
1317 if (route->input > SAA7115_SVIDEO3)
1319 if (state->input == route->input)
1321 v4l_dbg(1, debug, client, "now setting %s input\n",
1322 (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite");
1323 state->input = route->input;
1326 saa711x_write(client, R_02_INPUT_CNTL_1,
1327 (saa711x_read(client, R_02_INPUT_CNTL_1) & 0xf0) |
1330 /* bypass chrominance trap for S-Video modes */
1331 saa711x_write(client, R_09_LUMA_CNTL,
1332 (saa711x_read(client, R_09_LUMA_CNTL) & 0x7f) |
1333 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1337 case VIDIOC_STREAMON:
1338 case VIDIOC_STREAMOFF:
1339 v4l_dbg(1, debug, client, "%s output\n",
1340 (cmd == VIDIOC_STREAMON) ? "enable" : "disable");
1342 if (state->enable != (cmd == VIDIOC_STREAMON)) {
1343 state->enable = (cmd == VIDIOC_STREAMON);
1344 saa711x_write(client,
1345 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
1350 case VIDIOC_INT_S_CRYSTAL_FREQ:
1352 struct v4l2_crystal_freq *freq = arg;
1354 if (freq->freq != SAA7115_FREQ_32_11_MHZ &&
1355 freq->freq != SAA7115_FREQ_24_576_MHZ)
1357 state->crystal_freq = freq->freq;
1358 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1359 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1360 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1361 saa711x_set_audio_clock_freq(client, state->audclk_freq);
1365 case VIDIOC_INT_DECODE_VBI_LINE:
1366 saa711x_decode_vbi_line(client, arg);
1369 case VIDIOC_INT_RESET:
1370 v4l_dbg(1, debug, client, "decoder RESET\n");
1371 saa711x_writeregs(client, saa7115_cfg_reset_scaler);
1374 case VIDIOC_INT_G_VBI_DATA:
1376 struct v4l2_sliced_vbi_data *data = arg;
1379 case V4L2_SLICED_WSS_625:
1380 if (saa711x_read(client, 0x6b) & 0xc0)
1382 data->data[0] = saa711x_read(client, 0x6c);
1383 data->data[1] = saa711x_read(client, 0x6d);
1385 case V4L2_SLICED_CAPTION_525:
1386 if (data->field == 0) {
1388 if (saa711x_read(client, 0x66) & 0xc0)
1390 data->data[0] = saa711x_read(client, 0x67);
1391 data->data[1] = saa711x_read(client, 0x68);
1395 if (saa711x_read(client, 0x66) & 0x30)
1397 data->data[0] = saa711x_read(client, 0x69);
1398 data->data[1] = saa711x_read(client, 0x6a);
1406 #ifdef CONFIG_VIDEO_ADV_DEBUG
1407 case VIDIOC_INT_G_REGISTER:
1409 struct v4l2_register *reg = arg;
1411 if (reg->i2c_id != I2C_DRIVERID_SAA711X)
1413 reg->val = saa711x_read(client, reg->reg & 0xff);
1417 case VIDIOC_INT_S_REGISTER:
1419 struct v4l2_register *reg = arg;
1421 if (reg->i2c_id != I2C_DRIVERID_SAA711X)
1423 if (!capable(CAP_SYS_ADMIN))
1425 saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
1430 case VIDIOC_INT_G_CHIP_IDENT:
1431 *iarg = state->ident;
1441 /* ----------------------------------------------------------------------- */
1443 static struct i2c_driver i2c_driver_saa711x;
1445 static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind)
1447 struct i2c_client *client;
1448 struct saa711x_state *state;
1453 /* Check if the adapter supports the needed features */
1454 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1457 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
1460 client->addr = address;
1461 client->adapter = adapter;
1462 client->driver = &i2c_driver_saa711x;
1463 snprintf(client->name, sizeof(client->name) - 1, "saa7115");
1465 v4l_dbg(1, debug, client, "detecting saa7115 client on address 0x%x\n", address << 1);
1467 for (i=0;i<0x0f;i++) {
1468 saa711x_write(client, 0, i);
1469 name[i] = (saa711x_read(client, 0) &0x0f) +'0';
1475 saa711x_write(client, 0, 5);
1476 chip_id = saa711x_read(client, 0) & 0x0f;
1478 snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id);
1479 v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, address << 1, adapter->name);
1481 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
1482 i2c_set_clientdata(client, state);
1483 if (state == NULL) {
1490 state->bright = 128;
1491 state->contrast = 64;
1496 state->ident = V4L2_IDENT_SAA7111;
1499 state->ident = V4L2_IDENT_SAA7113;
1502 state->ident = V4L2_IDENT_SAA7114;
1505 state->ident = V4L2_IDENT_SAA7115;
1508 state->ident = V4L2_IDENT_SAA7118;
1511 state->ident = V4L2_IDENT_SAA7111;
1512 v4l_info(client, "WARNING: Chip is not known - Falling back to saa7111\n");
1516 state->audclk_freq = 48000;
1518 v4l_dbg(1, debug, client, "writing init values\n");
1520 /* init to 60hz/48khz */
1521 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1522 switch (state->ident) {
1523 case V4L2_IDENT_SAA7111:
1524 saa711x_writeregs(client, saa7111_init);
1526 case V4L2_IDENT_SAA7113:
1527 saa711x_writeregs(client, saa7113_init);
1530 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1531 saa711x_writeregs(client, saa7115_init_auto_input);
1533 saa711x_writeregs(client, saa7115_init_misc);
1534 saa711x_set_v4lstd(client, V4L2_STD_NTSC);
1536 i2c_attach_client(client);
1538 v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1539 saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC));
1544 static int saa711x_probe(struct i2c_adapter *adapter)
1546 if (adapter->class & I2C_CLASS_TV_ANALOG)
1547 return i2c_probe(adapter, &addr_data, &saa711x_attach);
1551 static int saa711x_detach(struct i2c_client *client)
1553 struct saa711x_state *state = i2c_get_clientdata(client);
1556 err = i2c_detach_client(client);
1566 /* ----------------------------------------------------------------------- */
1568 /* i2c implementation */
1569 static struct i2c_driver i2c_driver_saa711x = {
1573 .id = I2C_DRIVERID_SAA711X,
1574 .attach_adapter = saa711x_probe,
1575 .detach_client = saa711x_detach,
1576 .command = saa711x_command,
1580 static int __init saa711x_init_module(void)
1582 return i2c_add_driver(&i2c_driver_saa711x);
1585 static void __exit saa711x_cleanup_module(void)
1587 i2c_del_driver(&i2c_driver_saa711x);
1590 module_init(saa711x_init_module);
1591 module_exit(saa711x_cleanup_module);