[media] reorganize the API core items
[linux-2.6/btrfs-unstable.git] / drivers / media / video / saa7115.c
blob2107336cd8369cd055e5d43362349fc936d4518e
1 /* saa711x - Philips SAA711x video decoder driver
2 * This driver can work with saa7111, saa7111a, saa7113, saa7114,
3 * saa7115 and saa7118.
5 * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
6 * the saa7111 driver by Dave Perks.
8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
11 * Slight changes for video timing and attachment output by
12 * Wolfgang Scherr <scherr@net4you.net>
14 * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
15 * by Ronald Bultje <rbultje@ronald.bitfreak.net>
17 * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
18 * (2/17/2003)
20 * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
22 * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
23 * SAA7111, SAA7113 and SAA7118 support
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version 2
28 * of the License, or (at your option) any later version.
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
40 #include "saa711x_regs.h"
42 #include <linux/kernel.h>
43 #include <linux/module.h>
44 #include <linux/slab.h>
45 #include <linux/i2c.h>
46 #include <linux/videodev2.h>
47 #include <media/v4l2-device.h>
48 #include <media/v4l2-ctrls.h>
49 #include <media/v4l2-chip-ident.h>
50 #include <media/saa7115.h>
51 #include <asm/div64.h>
53 #define VRES_60HZ (480+16)
55 MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
56 MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
57 "Hans Verkuil, Mauro Carvalho Chehab");
58 MODULE_LICENSE("GPL");
60 static bool debug;
61 module_param(debug, bool, 0644);
63 MODULE_PARM_DESC(debug, "Debug level (0-1)");
66 struct saa711x_state {
67 struct v4l2_subdev sd;
68 struct v4l2_ctrl_handler hdl;
70 struct {
71 /* chroma gain control cluster */
72 struct v4l2_ctrl *agc;
73 struct v4l2_ctrl *gain;
76 v4l2_std_id std;
77 int input;
78 int output;
79 int enable;
80 int radio;
81 int width;
82 int height;
83 u32 ident;
84 u32 audclk_freq;
85 u32 crystal_freq;
86 u8 ucgc;
87 u8 cgcdiv;
88 u8 apll;
91 static inline struct saa711x_state *to_state(struct v4l2_subdev *sd)
93 return container_of(sd, struct saa711x_state, sd);
96 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
98 return &container_of(ctrl->handler, struct saa711x_state, hdl)->sd;
101 /* ----------------------------------------------------------------------- */
103 static inline int saa711x_write(struct v4l2_subdev *sd, u8 reg, u8 value)
105 struct i2c_client *client = v4l2_get_subdevdata(sd);
107 return i2c_smbus_write_byte_data(client, reg, value);
110 /* Sanity routine to check if a register is present */
111 static int saa711x_has_reg(const int id, const u8 reg)
113 if (id == V4L2_IDENT_SAA7111)
114 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
115 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
116 if (id == V4L2_IDENT_SAA7111A)
117 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
118 reg != 0x14 && reg != 0x18 && reg != 0x19 &&
119 reg != 0x1d && reg != 0x1e;
121 /* common for saa7113/4/5/8 */
122 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
123 reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
124 reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
125 reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
126 return 0;
128 switch (id) {
129 case V4L2_IDENT_SAA7113:
130 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
131 reg != 0x5d && reg < 0x63;
132 case V4L2_IDENT_SAA7114:
133 return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
134 (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
135 reg != 0x81 && reg < 0xf0;
136 case V4L2_IDENT_SAA7115:
137 return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
138 case V4L2_IDENT_SAA7118:
139 return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
140 (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
141 (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
143 return 1;
146 static int saa711x_writeregs(struct v4l2_subdev *sd, const unsigned char *regs)
148 struct saa711x_state *state = to_state(sd);
149 unsigned char reg, data;
151 while (*regs != 0x00) {
152 reg = *(regs++);
153 data = *(regs++);
155 /* According with datasheets, reserved regs should be
156 filled with 0 - seems better not to touch on they */
157 if (saa711x_has_reg(state->ident, reg)) {
158 if (saa711x_write(sd, reg, data) < 0)
159 return -1;
160 } else {
161 v4l2_dbg(1, debug, sd, "tried to access reserved reg 0x%02x\n", reg);
164 return 0;
167 static inline int saa711x_read(struct v4l2_subdev *sd, u8 reg)
169 struct i2c_client *client = v4l2_get_subdevdata(sd);
171 return i2c_smbus_read_byte_data(client, reg);
174 /* ----------------------------------------------------------------------- */
176 /* SAA7111 initialization table */
177 static const unsigned char saa7111_init[] = {
178 R_01_INC_DELAY, 0x00, /* reserved */
180 /*front end */
181 R_02_INPUT_CNTL_1, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */
182 R_03_INPUT_CNTL_2, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
183 * GAFIX=0, GAI1=256, GAI2=256 */
184 R_04_INPUT_CNTL_3, 0x00, /* GAI1=256 */
185 R_05_INPUT_CNTL_4, 0x00, /* GAI2=256 */
187 /* decoder */
188 R_06_H_SYNC_START, 0xf3, /* HSB at 13(50Hz) / 17(60Hz)
189 * pixels after end of last line */
190 R_07_H_SYNC_STOP, 0xe8, /* HSS seems to be needed to
191 * work with NTSC, too */
192 R_08_SYNC_CNTL, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0,
193 * VTRC=1, HPLL=0, VNOI=0 */
194 R_09_LUMA_CNTL, 0x01, /* BYPS=0, PREF=0, BPSS=0,
195 * VBLB=0, UPTCV=0, APER=1 */
196 R_0A_LUMA_BRIGHT_CNTL, 0x80,
197 R_0B_LUMA_CONTRAST_CNTL, 0x47, /* 0b - CONT=1.109 */
198 R_0C_CHROMA_SAT_CNTL, 0x40,
199 R_0D_CHROMA_HUE_CNTL, 0x00,
200 R_0E_CHROMA_CNTL_1, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
201 * FCTC=0, CHBW=1 */
202 R_0F_CHROMA_GAIN_CNTL, 0x00, /* reserved */
203 R_10_CHROMA_CNTL_2, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
204 R_11_MODE_DELAY_CNTL, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
205 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
206 R_12_RT_SIGNAL_CNTL, 0x00, /* 12 - output control 2 */
207 R_13_RT_X_PORT_OUT_CNTL, 0x00, /* 13 - output control 3 */
208 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
209 R_15_VGATE_START_FID_CHG, 0x00,
210 R_16_VGATE_STOP, 0x00,
211 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
213 0x00, 0x00
216 /* SAA7113 init codes */
217 static const unsigned char saa7113_init[] = {
218 R_01_INC_DELAY, 0x08,
219 R_02_INPUT_CNTL_1, 0xc2,
220 R_03_INPUT_CNTL_2, 0x30,
221 R_04_INPUT_CNTL_3, 0x00,
222 R_05_INPUT_CNTL_4, 0x00,
223 R_06_H_SYNC_START, 0x89,
224 R_07_H_SYNC_STOP, 0x0d,
225 R_08_SYNC_CNTL, 0x88,
226 R_09_LUMA_CNTL, 0x01,
227 R_0A_LUMA_BRIGHT_CNTL, 0x80,
228 R_0B_LUMA_CONTRAST_CNTL, 0x47,
229 R_0C_CHROMA_SAT_CNTL, 0x40,
230 R_0D_CHROMA_HUE_CNTL, 0x00,
231 R_0E_CHROMA_CNTL_1, 0x01,
232 R_0F_CHROMA_GAIN_CNTL, 0x2a,
233 R_10_CHROMA_CNTL_2, 0x08,
234 R_11_MODE_DELAY_CNTL, 0x0c,
235 R_12_RT_SIGNAL_CNTL, 0x07,
236 R_13_RT_X_PORT_OUT_CNTL, 0x00,
237 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
238 R_15_VGATE_START_FID_CHG, 0x00,
239 R_16_VGATE_STOP, 0x00,
240 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
242 0x00, 0x00
245 /* If a value differs from the Hauppauge driver values, then the comment starts with
246 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
247 Hauppauge driver sets. */
249 /* SAA7114 and SAA7115 initialization table */
250 static const unsigned char saa7115_init_auto_input[] = {
251 /* Front-End Part */
252 R_01_INC_DELAY, 0x48, /* white peak control disabled */
253 R_03_INPUT_CNTL_2, 0x20, /* was 0x30. 0x20: long vertical blanking */
254 R_04_INPUT_CNTL_3, 0x90, /* analog gain set to 0 */
255 R_05_INPUT_CNTL_4, 0x90, /* analog gain set to 0 */
256 /* Decoder Part */
257 R_06_H_SYNC_START, 0xeb, /* horiz sync begin = -21 */
258 R_07_H_SYNC_STOP, 0xe0, /* horiz sync stop = -17 */
259 R_09_LUMA_CNTL, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
260 R_0A_LUMA_BRIGHT_CNTL, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
261 R_0B_LUMA_CONTRAST_CNTL, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
262 R_0C_CHROMA_SAT_CNTL, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
263 R_0D_CHROMA_HUE_CNTL, 0x00,
264 R_0F_CHROMA_GAIN_CNTL, 0x00, /* use automatic gain */
265 R_10_CHROMA_CNTL_2, 0x06, /* chroma: active adaptive combfilter */
266 R_11_MODE_DELAY_CNTL, 0x00,
267 R_12_RT_SIGNAL_CNTL, 0x9d, /* RTS0 output control: VGATE */
268 R_13_RT_X_PORT_OUT_CNTL, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */
269 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
270 R_18_RAW_DATA_GAIN_CNTL, 0x40, /* gain 0x00 = nominal */
271 R_19_RAW_DATA_OFF_CNTL, 0x80,
272 R_1A_COLOR_KILL_LVL_CNTL, 0x77, /* recommended value */
273 R_1B_MISC_TVVCRDET, 0x42, /* recommended value */
274 R_1C_ENHAN_COMB_CTRL1, 0xa9, /* recommended value */
275 R_1D_ENHAN_COMB_CTRL2, 0x01, /* recommended value */
278 R_80_GLOBAL_CNTL_1, 0x0, /* No tasks enabled at init */
280 /* Power Device Control */
281 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset device */
282 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* set device programmed, all in operational mode */
283 0x00, 0x00
286 /* Used to reset saa7113, saa7114 and saa7115 */
287 static const unsigned char saa7115_cfg_reset_scaler[] = {
288 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00, /* disable I-port output */
289 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
290 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
291 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* enable I-port output */
292 0x00, 0x00
295 /* ============== SAA7715 VIDEO templates ============= */
297 static const unsigned char saa7115_cfg_60hz_video[] = {
298 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
299 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
301 R_15_VGATE_START_FID_CHG, 0x03,
302 R_16_VGATE_STOP, 0x11,
303 R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
305 R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
306 R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */
308 R_5A_V_OFF_FOR_SLICER, 0x06, /* standard 60hz value for ITU656 line counting */
310 /* Task A */
311 R_90_A_TASK_HANDLING_CNTL, 0x80,
312 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
313 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
314 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
316 /* hoffset low (input), 0x0002 is minimum */
317 R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
318 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
320 /* hsize low (input), 0x02d0 = 720 */
321 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
322 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
324 R_98_A_VERT_INPUT_WINDOW_START, 0x05,
325 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
327 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
328 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
330 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
331 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
333 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
334 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
336 /* Task B */
337 R_C0_B_TASK_HANDLING_CNTL, 0x00,
338 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
339 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
340 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
342 /* 0x0002 is minimum */
343 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
344 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
346 /* 0x02d0 = 720 */
347 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
348 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
350 /* vwindow start 0x12 = 18 */
351 R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
352 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
354 /* vwindow length 0xf8 = 248 */
355 R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
356 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
358 /* hwindow 0x02d0 = 720 */
359 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
360 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
362 R_F0_LFCO_PER_LINE, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
363 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0 */
364 R_F5_PULSGEN_LINE_LENGTH, 0xad,
365 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
367 0x00, 0x00
370 static const unsigned char saa7115_cfg_50hz_video[] = {
371 R_80_GLOBAL_CNTL_1, 0x00,
372 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
374 R_15_VGATE_START_FID_CHG, 0x37, /* VGATE start */
375 R_16_VGATE_STOP, 0x16,
376 R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
378 R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */
379 R_0E_CHROMA_CNTL_1, 0x07,
381 R_5A_V_OFF_FOR_SLICER, 0x03, /* standard 50hz value */
383 /* Task A */
384 R_90_A_TASK_HANDLING_CNTL, 0x81,
385 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
386 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
387 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
389 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
390 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
391 /* hoffset low (input), 0x0002 is minimum */
392 R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
393 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
395 /* hsize low (input), 0x02d0 = 720 */
396 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
397 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
399 R_98_A_VERT_INPUT_WINDOW_START, 0x03,
400 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
402 /* vsize 0x12 = 18 */
403 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
404 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
406 /* hsize 0x05a0 = 1440 */
407 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
408 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05, /* hsize hi (output) */
409 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12, /* vsize low (output), 0x12 = 18 */
410 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00, /* vsize hi (output) */
412 /* Task B */
413 R_C0_B_TASK_HANDLING_CNTL, 0x00,
414 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
415 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
416 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
418 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
419 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
420 /* hoffset low (input), 0x0002 is minimum. See comment above. */
421 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
422 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
424 /* hsize 0x02d0 = 720 */
425 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
426 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
428 /* voffset 0x16 = 22 */
429 R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
430 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
432 /* vsize 0x0120 = 288 */
433 R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
434 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
436 /* hsize 0x02d0 = 720 */
437 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
438 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
440 R_F0_LFCO_PER_LINE, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
441 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0, (was 0x05) */
442 R_F5_PULSGEN_LINE_LENGTH, 0xb0,
443 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
445 0x00, 0x00
448 /* ============== SAA7715 VIDEO templates (end) ======= */
450 static const unsigned char saa7115_cfg_vbi_on[] = {
451 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
452 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
453 R_80_GLOBAL_CNTL_1, 0x30, /* Activate both tasks */
454 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
455 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
457 0x00, 0x00
460 static const unsigned char saa7115_cfg_vbi_off[] = {
461 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
462 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
463 R_80_GLOBAL_CNTL_1, 0x20, /* Activate only task "B" */
464 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
465 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
467 0x00, 0x00
471 static const unsigned char saa7115_init_misc[] = {
472 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
473 R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
474 R_84_I_PORT_SIGNAL_DEF, 0x20,
475 R_85_I_PORT_SIGNAL_POLAR, 0x21,
476 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
477 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
479 /* Task A */
480 R_A0_A_HORIZ_PRESCALING, 0x01,
481 R_A1_A_ACCUMULATION_LENGTH, 0x00,
482 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
484 /* Configure controls at nominal value*/
485 R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
486 R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
487 R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
489 /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
490 R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
491 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
493 R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
495 /* must be horiz lum scaling / 2 */
496 R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
497 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
499 /* must be offset luma / 2 */
500 R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
502 R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
503 R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
505 R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
506 R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
508 R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
510 R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
511 R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
512 R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
513 R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
515 R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
516 R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
517 R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
518 R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
520 /* Task B */
521 R_D0_B_HORIZ_PRESCALING, 0x01,
522 R_D1_B_ACCUMULATION_LENGTH, 0x00,
523 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
525 /* Configure controls at nominal value*/
526 R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
527 R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
528 R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
530 /* hor lum scaling 0x0400 = 1 */
531 R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
532 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
534 R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
536 /* must be hor lum scaling / 2 */
537 R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
538 R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
540 /* must be offset luma / 2 */
541 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
543 R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
544 R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
546 R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
547 R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
549 R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
551 R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
552 R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
553 R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
554 R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
556 R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
557 R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
558 R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
559 R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
561 R_F2_NOMINAL_PLL2_DTO, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
562 R_F3_PLL_INCREMENT, 0x46,
563 R_F4_PLL2_STATUS, 0x00,
564 R_F7_PULSE_A_POS_MSB, 0x4b, /* not the recommended settings! */
565 R_F8_PULSE_B_POS, 0x00,
566 R_F9_PULSE_B_POS_MSB, 0x4b,
567 R_FA_PULSE_C_POS, 0x00,
568 R_FB_PULSE_C_POS_MSB, 0x4b,
570 /* PLL2 lock detection settings: 71 lines 50% phase error */
571 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
573 /* Turn off VBI */
574 R_40_SLICER_CNTL_1, 0x20, /* No framing code errors allowed. */
575 R_41_LCR_BASE, 0xff,
576 R_41_LCR_BASE+1, 0xff,
577 R_41_LCR_BASE+2, 0xff,
578 R_41_LCR_BASE+3, 0xff,
579 R_41_LCR_BASE+4, 0xff,
580 R_41_LCR_BASE+5, 0xff,
581 R_41_LCR_BASE+6, 0xff,
582 R_41_LCR_BASE+7, 0xff,
583 R_41_LCR_BASE+8, 0xff,
584 R_41_LCR_BASE+9, 0xff,
585 R_41_LCR_BASE+10, 0xff,
586 R_41_LCR_BASE+11, 0xff,
587 R_41_LCR_BASE+12, 0xff,
588 R_41_LCR_BASE+13, 0xff,
589 R_41_LCR_BASE+14, 0xff,
590 R_41_LCR_BASE+15, 0xff,
591 R_41_LCR_BASE+16, 0xff,
592 R_41_LCR_BASE+17, 0xff,
593 R_41_LCR_BASE+18, 0xff,
594 R_41_LCR_BASE+19, 0xff,
595 R_41_LCR_BASE+20, 0xff,
596 R_41_LCR_BASE+21, 0xff,
597 R_41_LCR_BASE+22, 0xff,
598 R_58_PROGRAM_FRAMING_CODE, 0x40,
599 R_59_H_OFF_FOR_SLICER, 0x47,
600 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
601 R_5D_DID, 0xbd,
602 R_5E_SDID, 0x35,
604 R_02_INPUT_CNTL_1, 0xc4, /* input tuner -> input 4, amplifier active */
606 R_80_GLOBAL_CNTL_1, 0x20, /* enable task B */
607 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
608 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
609 0x00, 0x00
612 static int saa711x_odd_parity(u8 c)
614 c ^= (c >> 4);
615 c ^= (c >> 2);
616 c ^= (c >> 1);
618 return c & 1;
621 static int saa711x_decode_vps(u8 *dst, u8 *p)
623 static const u8 biphase_tbl[] = {
624 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
625 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
626 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
627 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
628 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
629 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
630 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
631 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
632 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
633 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
634 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
635 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
636 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
637 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
638 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
639 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
640 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
641 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
642 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
643 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
644 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
645 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
646 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
647 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
648 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
649 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
650 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
651 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
652 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
653 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
654 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
655 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
657 int i;
658 u8 c, err = 0;
660 for (i = 0; i < 2 * 13; i += 2) {
661 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
662 c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
663 dst[i / 2] = c;
665 return err & 0xf0;
668 static int saa711x_decode_wss(u8 *p)
670 static const int wss_bits[8] = {
671 0, 0, 0, 1, 0, 1, 1, 1
673 unsigned char parity;
674 int wss = 0;
675 int i;
677 for (i = 0; i < 16; i++) {
678 int b1 = wss_bits[p[i] & 7];
679 int b2 = wss_bits[(p[i] >> 3) & 7];
681 if (b1 == b2)
682 return -1;
683 wss |= b2 << i;
685 parity = wss & 15;
686 parity ^= parity >> 2;
687 parity ^= parity >> 1;
689 if (!(parity & 1))
690 return -1;
692 return wss;
695 static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
697 struct saa711x_state *state = to_state(sd);
698 u32 acpf;
699 u32 acni;
700 u32 hz;
701 u64 f;
702 u8 acc = 0; /* reg 0x3a, audio clock control */
704 /* Checks for chips that don't have audio clock (saa7111, saa7113) */
705 if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
706 return 0;
708 v4l2_dbg(1, debug, sd, "set audio clock freq: %d\n", freq);
710 /* sanity check */
711 if (freq < 32000 || freq > 48000)
712 return -EINVAL;
714 /* hz is the refresh rate times 100 */
715 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
716 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
717 acpf = (25600 * freq) / hz;
718 /* acni = (256 * freq * 2^23) / crystal_frequency =
719 (freq * 2^(8+23)) / crystal_frequency =
720 (freq << 31) / crystal_frequency */
721 f = freq;
722 f = f << 31;
723 do_div(f, state->crystal_freq);
724 acni = f;
725 if (state->ucgc) {
726 acpf = acpf * state->cgcdiv / 16;
727 acni = acni * state->cgcdiv / 16;
728 acc = 0x80;
729 if (state->cgcdiv == 3)
730 acc |= 0x40;
732 if (state->apll)
733 acc |= 0x08;
735 saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
736 saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
737 saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
739 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
740 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
741 (acpf >> 8) & 0xff);
742 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
743 (acpf >> 16) & 0x03);
745 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
746 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
747 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
748 state->audclk_freq = freq;
749 return 0;
752 static int saa711x_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
754 struct v4l2_subdev *sd = to_sd(ctrl);
755 struct saa711x_state *state = to_state(sd);
757 switch (ctrl->id) {
758 case V4L2_CID_CHROMA_AGC:
759 /* chroma gain cluster */
760 if (state->agc->val)
761 state->gain->val =
762 saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL) & 0x7f;
763 break;
765 return 0;
768 static int saa711x_s_ctrl(struct v4l2_ctrl *ctrl)
770 struct v4l2_subdev *sd = to_sd(ctrl);
771 struct saa711x_state *state = to_state(sd);
773 switch (ctrl->id) {
774 case V4L2_CID_BRIGHTNESS:
775 saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, ctrl->val);
776 break;
778 case V4L2_CID_CONTRAST:
779 saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, ctrl->val);
780 break;
782 case V4L2_CID_SATURATION:
783 saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, ctrl->val);
784 break;
786 case V4L2_CID_HUE:
787 saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, ctrl->val);
788 break;
790 case V4L2_CID_CHROMA_AGC:
791 /* chroma gain cluster */
792 if (state->agc->val)
793 saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val);
794 else
795 saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val | 0x80);
796 break;
798 default:
799 return -EINVAL;
802 return 0;
805 static int saa711x_set_size(struct v4l2_subdev *sd, int width, int height)
807 struct saa711x_state *state = to_state(sd);
808 int HPSC, HFSC;
809 int VSCY;
810 int res;
811 int is_50hz = state->std & V4L2_STD_625_50;
812 int Vsrc = is_50hz ? 576 : 480;
814 v4l2_dbg(1, debug, sd, "decoder set size to %ix%i\n", width, height);
816 /* FIXME need better bounds checking here */
817 if ((width < 1) || (width > 1440))
818 return -EINVAL;
819 if ((height < 1) || (height > Vsrc))
820 return -EINVAL;
822 if (!saa711x_has_reg(state->ident, R_D0_B_HORIZ_PRESCALING)) {
823 /* Decoder only supports 720 columns and 480 or 576 lines */
824 if (width != 720)
825 return -EINVAL;
826 if (height != Vsrc)
827 return -EINVAL;
830 state->width = width;
831 state->height = height;
833 if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
834 return 0;
836 /* probably have a valid size, let's set it */
837 /* Set output width/height */
838 /* width */
840 saa711x_write(sd, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
841 (u8) (width & 0xff));
842 saa711x_write(sd, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
843 (u8) ((width >> 8) & 0xff));
845 /* Vertical Scaling uses height/2 */
846 res = height / 2;
848 /* On 60Hz, it is using a higher Vertical Output Size */
849 if (!is_50hz)
850 res += (VRES_60HZ - 480) >> 1;
852 /* height */
853 saa711x_write(sd, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
854 (u8) (res & 0xff));
855 saa711x_write(sd, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
856 (u8) ((res >> 8) & 0xff));
858 /* Scaling settings */
859 /* Hprescaler is floor(inres/outres) */
860 HPSC = (int)(720 / width);
861 /* 0 is not allowed (div. by zero) */
862 HPSC = HPSC ? HPSC : 1;
863 HFSC = (int)((1024 * 720) / (HPSC * width));
864 /* FIXME hardcodes to "Task B"
865 * write H prescaler integer */
866 saa711x_write(sd, R_D0_B_HORIZ_PRESCALING,
867 (u8) (HPSC & 0x3f));
869 v4l2_dbg(1, debug, sd, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
870 /* write H fine-scaling (luminance) */
871 saa711x_write(sd, R_D8_B_HORIZ_LUMA_SCALING_INC,
872 (u8) (HFSC & 0xff));
873 saa711x_write(sd, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
874 (u8) ((HFSC >> 8) & 0xff));
875 /* write H fine-scaling (chrominance)
876 * must be lum/2, so i'll just bitshift :) */
877 saa711x_write(sd, R_DC_B_HORIZ_CHROMA_SCALING,
878 (u8) ((HFSC >> 1) & 0xff));
879 saa711x_write(sd, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
880 (u8) ((HFSC >> 9) & 0xff));
882 VSCY = (int)((1024 * Vsrc) / height);
883 v4l2_dbg(1, debug, sd, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
885 /* Correct Contrast and Luminance */
886 saa711x_write(sd, R_D5_B_LUMA_CONTRAST_CNTL,
887 (u8) (64 * 1024 / VSCY));
888 saa711x_write(sd, R_D6_B_CHROMA_SATURATION_CNTL,
889 (u8) (64 * 1024 / VSCY));
891 /* write V fine-scaling (luminance) */
892 saa711x_write(sd, R_E0_B_VERT_LUMA_SCALING_INC,
893 (u8) (VSCY & 0xff));
894 saa711x_write(sd, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
895 (u8) ((VSCY >> 8) & 0xff));
896 /* write V fine-scaling (chrominance) */
897 saa711x_write(sd, R_E2_B_VERT_CHROMA_SCALING_INC,
898 (u8) (VSCY & 0xff));
899 saa711x_write(sd, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
900 (u8) ((VSCY >> 8) & 0xff));
902 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
904 /* Activates task "B" */
905 saa711x_write(sd, R_80_GLOBAL_CNTL_1,
906 saa711x_read(sd, R_80_GLOBAL_CNTL_1) | 0x20);
908 return 0;
911 static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
913 struct saa711x_state *state = to_state(sd);
915 /* Prevent unnecessary standard changes. During a standard
916 change the I-Port is temporarily disabled. Any devices
917 reading from that port can get confused.
918 Note that s_std is also used to switch from
919 radio to TV mode, so if a s_std is broadcast to
920 all I2C devices then you do not want to have an unwanted
921 side-effect here. */
922 if (std == state->std)
923 return;
925 state->std = std;
927 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
928 if (std & V4L2_STD_525_60) {
929 v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
930 saa711x_writeregs(sd, saa7115_cfg_60hz_video);
931 saa711x_set_size(sd, 720, 480);
932 } else {
933 v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
934 saa711x_writeregs(sd, saa7115_cfg_50hz_video);
935 saa711x_set_size(sd, 720, 576);
938 /* Register 0E - Bits D6-D4 on NO-AUTO mode
939 (SAA7111 and SAA7113 doesn't have auto mode)
940 50 Hz / 625 lines 60 Hz / 525 lines
941 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz)
942 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz)
943 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
944 011 NTSC N (3.58MHz) PAL M (3.58MHz)
945 100 reserved NTSC-Japan (3.58MHz)
947 if (state->ident <= V4L2_IDENT_SAA7113) {
948 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
950 if (std == V4L2_STD_PAL_M) {
951 reg |= 0x30;
952 } else if (std == V4L2_STD_PAL_Nc) {
953 reg |= 0x20;
954 } else if (std == V4L2_STD_PAL_60) {
955 reg |= 0x10;
956 } else if (std == V4L2_STD_NTSC_M_JP) {
957 reg |= 0x40;
958 } else if (std & V4L2_STD_SECAM) {
959 reg |= 0x50;
961 saa711x_write(sd, R_0E_CHROMA_CNTL_1, reg);
962 } else {
963 /* restart task B if needed */
964 int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
966 if (taskb && state->ident == V4L2_IDENT_SAA7114) {
967 saa711x_writeregs(sd, saa7115_cfg_vbi_on);
970 /* switch audio mode too! */
971 saa711x_s_clock_freq(sd, state->audclk_freq);
975 /* setup the sliced VBI lcr registers according to the sliced VBI format */
976 static void saa711x_set_lcr(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
978 struct saa711x_state *state = to_state(sd);
979 int is_50hz = (state->std & V4L2_STD_625_50);
980 u8 lcr[24];
981 int i, x;
983 #if 1
984 /* saa7113/7114/7118 VBI support are experimental */
985 if (!saa711x_has_reg(state->ident, R_41_LCR_BASE))
986 return;
988 #else
989 /* SAA7113 and SAA7118 also should support VBI - Need testing */
990 if (state->ident != V4L2_IDENT_SAA7115)
991 return;
992 #endif
994 for (i = 0; i <= 23; i++)
995 lcr[i] = 0xff;
997 if (fmt == NULL) {
998 /* raw VBI */
999 if (is_50hz)
1000 for (i = 6; i <= 23; i++)
1001 lcr[i] = 0xdd;
1002 else
1003 for (i = 10; i <= 21; i++)
1004 lcr[i] = 0xdd;
1005 } else {
1006 /* sliced VBI */
1007 /* first clear lines that cannot be captured */
1008 if (is_50hz) {
1009 for (i = 0; i <= 5; i++)
1010 fmt->service_lines[0][i] =
1011 fmt->service_lines[1][i] = 0;
1013 else {
1014 for (i = 0; i <= 9; i++)
1015 fmt->service_lines[0][i] =
1016 fmt->service_lines[1][i] = 0;
1017 for (i = 22; i <= 23; i++)
1018 fmt->service_lines[0][i] =
1019 fmt->service_lines[1][i] = 0;
1022 /* Now set the lcr values according to the specified service */
1023 for (i = 6; i <= 23; i++) {
1024 lcr[i] = 0;
1025 for (x = 0; x <= 1; x++) {
1026 switch (fmt->service_lines[1-x][i]) {
1027 case 0:
1028 lcr[i] |= 0xf << (4 * x);
1029 break;
1030 case V4L2_SLICED_TELETEXT_B:
1031 lcr[i] |= 1 << (4 * x);
1032 break;
1033 case V4L2_SLICED_CAPTION_525:
1034 lcr[i] |= 4 << (4 * x);
1035 break;
1036 case V4L2_SLICED_WSS_625:
1037 lcr[i] |= 5 << (4 * x);
1038 break;
1039 case V4L2_SLICED_VPS:
1040 lcr[i] |= 7 << (4 * x);
1041 break;
1047 /* write the lcr registers */
1048 for (i = 2; i <= 23; i++) {
1049 saa711x_write(sd, i - 2 + R_41_LCR_BASE, lcr[i]);
1052 /* enable/disable raw VBI capturing */
1053 saa711x_writeregs(sd, fmt == NULL ?
1054 saa7115_cfg_vbi_on :
1055 saa7115_cfg_vbi_off);
1058 static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *sliced)
1060 static u16 lcr2vbi[] = {
1061 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
1062 0, V4L2_SLICED_CAPTION_525, /* 4 */
1063 V4L2_SLICED_WSS_625, 0, /* 5 */
1064 V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */
1065 0, 0, 0, 0
1067 int i;
1069 memset(sliced, 0, sizeof(*sliced));
1070 /* done if using raw VBI */
1071 if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
1072 return 0;
1073 for (i = 2; i <= 23; i++) {
1074 u8 v = saa711x_read(sd, i - 2 + R_41_LCR_BASE);
1076 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
1077 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
1078 sliced->service_set |=
1079 sliced->service_lines[0][i] | sliced->service_lines[1][i];
1081 return 0;
1084 static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
1086 saa711x_set_lcr(sd, NULL);
1087 return 0;
1090 static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
1092 saa711x_set_lcr(sd, fmt);
1093 return 0;
1096 static int saa711x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
1098 if (fmt->code != V4L2_MBUS_FMT_FIXED)
1099 return -EINVAL;
1100 fmt->field = V4L2_FIELD_INTERLACED;
1101 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
1102 return saa711x_set_size(sd, fmt->width, fmt->height);
1105 /* Decode the sliced VBI data stream as created by the saa7115.
1106 The format is described in the saa7115 datasheet in Tables 25 and 26
1107 and in Figure 33.
1108 The current implementation uses SAV/EAV codes and not the ancillary data
1109 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1110 code. */
1111 static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
1113 struct saa711x_state *state = to_state(sd);
1114 static const char vbi_no_data_pattern[] = {
1115 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1117 u8 *p = vbi->p;
1118 u32 wss;
1119 int id1, id2; /* the ID1 and ID2 bytes from the internal header */
1121 vbi->type = 0; /* mark result as a failure */
1122 id1 = p[2];
1123 id2 = p[3];
1124 /* Note: the field bit is inverted for 60 Hz video */
1125 if (state->std & V4L2_STD_525_60)
1126 id1 ^= 0x40;
1128 /* Skip internal header, p now points to the start of the payload */
1129 p += 4;
1130 vbi->p = p;
1132 /* calculate field and line number of the VBI packet (1-23) */
1133 vbi->is_second_field = ((id1 & 0x40) != 0);
1134 vbi->line = (id1 & 0x3f) << 3;
1135 vbi->line |= (id2 & 0x70) >> 4;
1137 /* Obtain data type */
1138 id2 &= 0xf;
1140 /* If the VBI slicer does not detect any signal it will fill up
1141 the payload buffer with 0xa0 bytes. */
1142 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
1143 return 0;
1145 /* decode payloads */
1146 switch (id2) {
1147 case 1:
1148 vbi->type = V4L2_SLICED_TELETEXT_B;
1149 break;
1150 case 4:
1151 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1152 return 0;
1153 vbi->type = V4L2_SLICED_CAPTION_525;
1154 break;
1155 case 5:
1156 wss = saa711x_decode_wss(p);
1157 if (wss == -1)
1158 return 0;
1159 p[0] = wss & 0xff;
1160 p[1] = wss >> 8;
1161 vbi->type = V4L2_SLICED_WSS_625;
1162 break;
1163 case 7:
1164 if (saa711x_decode_vps(p, p) != 0)
1165 return 0;
1166 vbi->type = V4L2_SLICED_VPS;
1167 break;
1168 default:
1169 break;
1171 return 0;
1174 /* ============ SAA7115 AUDIO settings (end) ============= */
1176 static int saa711x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1178 struct saa711x_state *state = to_state(sd);
1179 int status;
1181 if (state->radio)
1182 return 0;
1183 status = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1185 v4l2_dbg(1, debug, sd, "status: 0x%02x\n", status);
1186 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1187 return 0;
1190 static int saa711x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1192 struct saa711x_state *state = to_state(sd);
1194 state->radio = 0;
1195 saa711x_set_v4lstd(sd, std);
1196 return 0;
1199 static int saa711x_s_radio(struct v4l2_subdev *sd)
1201 struct saa711x_state *state = to_state(sd);
1203 state->radio = 1;
1204 return 0;
1207 static int saa711x_s_routing(struct v4l2_subdev *sd,
1208 u32 input, u32 output, u32 config)
1210 struct saa711x_state *state = to_state(sd);
1211 u8 mask = (state->ident <= V4L2_IDENT_SAA7111A) ? 0xf8 : 0xf0;
1213 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
1214 input, output);
1216 /* saa7111/3 does not have these inputs */
1217 if (state->ident <= V4L2_IDENT_SAA7113 &&
1218 (input == SAA7115_COMPOSITE4 ||
1219 input == SAA7115_COMPOSITE5)) {
1220 return -EINVAL;
1222 if (input > SAA7115_SVIDEO3)
1223 return -EINVAL;
1224 if (state->input == input && state->output == output)
1225 return 0;
1226 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
1227 (input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
1228 (output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
1229 state->input = input;
1231 /* saa7111 has slightly different input numbering */
1232 if (state->ident <= V4L2_IDENT_SAA7111A) {
1233 if (input >= SAA7115_COMPOSITE4)
1234 input -= 2;
1235 /* saa7111 specific */
1236 saa711x_write(sd, R_10_CHROMA_CNTL_2,
1237 (saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
1238 ((output & 0xc0) ^ 0x40));
1239 saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
1240 (saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
1241 ((output & 2) ? 0x0a : 0));
1244 /* select mode */
1245 saa711x_write(sd, R_02_INPUT_CNTL_1,
1246 (saa711x_read(sd, R_02_INPUT_CNTL_1) & mask) |
1247 input);
1249 /* bypass chrominance trap for S-Video modes */
1250 saa711x_write(sd, R_09_LUMA_CNTL,
1251 (saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
1252 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1254 state->output = output;
1255 if (state->ident == V4L2_IDENT_SAA7114 ||
1256 state->ident == V4L2_IDENT_SAA7115) {
1257 saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
1258 (saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
1259 (state->output & 0x01));
1261 return 0;
1264 static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
1266 struct saa711x_state *state = to_state(sd);
1268 if (state->ident > V4L2_IDENT_SAA7111A)
1269 return -EINVAL;
1270 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
1271 (val ? 0x80 : 0));
1272 return 0;
1275 static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
1277 struct saa711x_state *state = to_state(sd);
1279 v4l2_dbg(1, debug, sd, "%s output\n",
1280 enable ? "enable" : "disable");
1282 if (state->enable == enable)
1283 return 0;
1284 state->enable = enable;
1285 if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED))
1286 return 0;
1287 saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable);
1288 return 0;
1291 static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, u32 freq, u32 flags)
1293 struct saa711x_state *state = to_state(sd);
1295 if (freq != SAA7115_FREQ_32_11_MHZ && freq != SAA7115_FREQ_24_576_MHZ)
1296 return -EINVAL;
1297 state->crystal_freq = freq;
1298 state->cgcdiv = (flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1299 state->ucgc = (flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1300 state->apll = (flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1301 saa711x_s_clock_freq(sd, state->audclk_freq);
1302 return 0;
1305 static int saa711x_reset(struct v4l2_subdev *sd, u32 val)
1307 v4l2_dbg(1, debug, sd, "decoder RESET\n");
1308 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
1309 return 0;
1312 static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *data)
1314 /* Note: the internal field ID is inverted for NTSC,
1315 so data->field 0 maps to the saa7115 even field,
1316 whereas for PAL it maps to the saa7115 odd field. */
1317 switch (data->id) {
1318 case V4L2_SLICED_WSS_625:
1319 if (saa711x_read(sd, 0x6b) & 0xc0)
1320 return -EIO;
1321 data->data[0] = saa711x_read(sd, 0x6c);
1322 data->data[1] = saa711x_read(sd, 0x6d);
1323 return 0;
1324 case V4L2_SLICED_CAPTION_525:
1325 if (data->field == 0) {
1326 /* CC */
1327 if (saa711x_read(sd, 0x66) & 0x30)
1328 return -EIO;
1329 data->data[0] = saa711x_read(sd, 0x69);
1330 data->data[1] = saa711x_read(sd, 0x6a);
1331 return 0;
1333 /* XDS */
1334 if (saa711x_read(sd, 0x66) & 0xc0)
1335 return -EIO;
1336 data->data[0] = saa711x_read(sd, 0x67);
1337 data->data[1] = saa711x_read(sd, 0x68);
1338 return 0;
1339 default:
1340 return -EINVAL;
1344 static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
1346 struct saa711x_state *state = to_state(sd);
1347 int reg1f, reg1e;
1350 * The V4L2 core already initializes std with all supported
1351 * Standards. All driver needs to do is to mask it, to remove
1352 * standards that don't apply from the mask
1355 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1356 v4l2_dbg(1, debug, sd, "Status byte 2 (0x1f)=0x%02x\n", reg1f);
1358 /* horizontal/vertical not locked */
1359 if (reg1f & 0x40)
1360 goto ret;
1362 if (reg1f & 0x20)
1363 *std &= V4L2_STD_525_60;
1364 else
1365 *std &= V4L2_STD_625_50;
1367 if (state->ident != V4L2_IDENT_SAA7115)
1368 goto ret;
1370 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1372 switch (reg1e & 0x03) {
1373 case 1:
1374 *std &= V4L2_STD_NTSC;
1375 break;
1376 case 2:
1378 * V4L2_STD_PAL just cover the european PAL standards.
1379 * This is wrong, as the device could also be using an
1380 * other PAL standard.
1382 *std &= V4L2_STD_PAL | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc |
1383 V4L2_STD_PAL_M | V4L2_STD_PAL_60;
1384 break;
1385 case 3:
1386 *std &= V4L2_STD_SECAM;
1387 break;
1388 default:
1389 /* Can't detect anything */
1390 break;
1393 v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e);
1395 ret:
1396 v4l2_dbg(1, debug, sd, "detected std mask = %08Lx\n", *std);
1398 return 0;
1401 static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status)
1403 struct saa711x_state *state = to_state(sd);
1404 int reg1e = 0x80;
1405 int reg1f;
1407 *status = V4L2_IN_ST_NO_SIGNAL;
1408 if (state->ident == V4L2_IDENT_SAA7115)
1409 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1410 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1411 if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
1412 *status = 0;
1413 return 0;
1416 #ifdef CONFIG_VIDEO_ADV_DEBUG
1417 static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
1419 struct i2c_client *client = v4l2_get_subdevdata(sd);
1421 if (!v4l2_chip_match_i2c_client(client, &reg->match))
1422 return -EINVAL;
1423 if (!capable(CAP_SYS_ADMIN))
1424 return -EPERM;
1425 reg->val = saa711x_read(sd, reg->reg & 0xff);
1426 reg->size = 1;
1427 return 0;
1430 static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
1432 struct i2c_client *client = v4l2_get_subdevdata(sd);
1434 if (!v4l2_chip_match_i2c_client(client, &reg->match))
1435 return -EINVAL;
1436 if (!capable(CAP_SYS_ADMIN))
1437 return -EPERM;
1438 saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
1439 return 0;
1441 #endif
1443 static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
1445 struct saa711x_state *state = to_state(sd);
1446 struct i2c_client *client = v4l2_get_subdevdata(sd);
1448 return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
1451 static int saa711x_log_status(struct v4l2_subdev *sd)
1453 struct saa711x_state *state = to_state(sd);
1454 int reg1e, reg1f;
1455 int signalOk;
1456 int vcr;
1458 v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
1459 if (state->ident != V4L2_IDENT_SAA7115) {
1460 /* status for the saa7114 */
1461 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1462 signalOk = (reg1f & 0xc1) == 0x81;
1463 v4l2_info(sd, "Video signal: %s\n", signalOk ? "ok" : "bad");
1464 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1465 return 0;
1468 /* status for the saa7115 */
1469 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1470 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1472 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1473 vcr = !(reg1f & 0x10);
1475 if (state->input >= 6)
1476 v4l2_info(sd, "Input: S-Video %d\n", state->input - 6);
1477 else
1478 v4l2_info(sd, "Input: Composite %d\n", state->input);
1479 v4l2_info(sd, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1480 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1482 switch (reg1e & 0x03) {
1483 case 1:
1484 v4l2_info(sd, "Detected format: NTSC\n");
1485 break;
1486 case 2:
1487 v4l2_info(sd, "Detected format: PAL\n");
1488 break;
1489 case 3:
1490 v4l2_info(sd, "Detected format: SECAM\n");
1491 break;
1492 default:
1493 v4l2_info(sd, "Detected format: BW/No color\n");
1494 break;
1496 v4l2_info(sd, "Width, Height: %d, %d\n", state->width, state->height);
1497 v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
1498 return 0;
1501 /* ----------------------------------------------------------------------- */
1503 static const struct v4l2_ctrl_ops saa711x_ctrl_ops = {
1504 .s_ctrl = saa711x_s_ctrl,
1505 .g_volatile_ctrl = saa711x_g_volatile_ctrl,
1508 static const struct v4l2_subdev_core_ops saa711x_core_ops = {
1509 .log_status = saa711x_log_status,
1510 .g_chip_ident = saa711x_g_chip_ident,
1511 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
1512 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
1513 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
1514 .g_ctrl = v4l2_subdev_g_ctrl,
1515 .s_ctrl = v4l2_subdev_s_ctrl,
1516 .queryctrl = v4l2_subdev_queryctrl,
1517 .querymenu = v4l2_subdev_querymenu,
1518 .s_std = saa711x_s_std,
1519 .reset = saa711x_reset,
1520 .s_gpio = saa711x_s_gpio,
1521 #ifdef CONFIG_VIDEO_ADV_DEBUG
1522 .g_register = saa711x_g_register,
1523 .s_register = saa711x_s_register,
1524 #endif
1527 static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops = {
1528 .s_radio = saa711x_s_radio,
1529 .g_tuner = saa711x_g_tuner,
1532 static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
1533 .s_clock_freq = saa711x_s_clock_freq,
1536 static const struct v4l2_subdev_video_ops saa711x_video_ops = {
1537 .s_routing = saa711x_s_routing,
1538 .s_crystal_freq = saa711x_s_crystal_freq,
1539 .s_mbus_fmt = saa711x_s_mbus_fmt,
1540 .s_stream = saa711x_s_stream,
1541 .querystd = saa711x_querystd,
1542 .g_input_status = saa711x_g_input_status,
1545 static const struct v4l2_subdev_vbi_ops saa711x_vbi_ops = {
1546 .g_vbi_data = saa711x_g_vbi_data,
1547 .decode_vbi_line = saa711x_decode_vbi_line,
1548 .g_sliced_fmt = saa711x_g_sliced_fmt,
1549 .s_sliced_fmt = saa711x_s_sliced_fmt,
1550 .s_raw_fmt = saa711x_s_raw_fmt,
1553 static const struct v4l2_subdev_ops saa711x_ops = {
1554 .core = &saa711x_core_ops,
1555 .tuner = &saa711x_tuner_ops,
1556 .audio = &saa711x_audio_ops,
1557 .video = &saa711x_video_ops,
1558 .vbi = &saa711x_vbi_ops,
1561 /* ----------------------------------------------------------------------- */
1563 static int saa711x_probe(struct i2c_client *client,
1564 const struct i2c_device_id *id)
1566 struct saa711x_state *state;
1567 struct v4l2_subdev *sd;
1568 struct v4l2_ctrl_handler *hdl;
1569 int i;
1570 char name[17];
1571 char chip_id;
1572 int autodetect = !id || id->driver_data == 1;
1574 /* Check if the adapter supports the needed features */
1575 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1576 return -EIO;
1578 for (i = 0; i < 0x0f; i++) {
1579 i2c_smbus_write_byte_data(client, 0, i);
1580 name[i] = (i2c_smbus_read_byte_data(client, 0) & 0x0f) + '0';
1581 if (name[i] > '9')
1582 name[i] += 'a' - '9' - 1;
1584 name[i] = '\0';
1586 chip_id = name[5];
1588 /* Check whether this chip is part of the saa711x series */
1589 if (memcmp(name + 1, "f711", 4)) {
1590 v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
1591 client->addr << 1, name);
1592 return -ENODEV;
1595 /* Safety check */
1596 if (!autodetect && id->name[6] != chip_id) {
1597 v4l_warn(client, "found saa711%c while %s was expected\n",
1598 chip_id, id->name);
1600 snprintf(client->name, sizeof(client->name), "saa711%c", chip_id);
1601 v4l_info(client, "saa711%c found (%s) @ 0x%x (%s)\n", chip_id, name,
1602 client->addr << 1, client->adapter->name);
1604 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
1605 if (state == NULL)
1606 return -ENOMEM;
1607 sd = &state->sd;
1608 v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
1610 hdl = &state->hdl;
1611 v4l2_ctrl_handler_init(hdl, 6);
1612 /* add in ascending ID order */
1613 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1614 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1615 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1616 V4L2_CID_CONTRAST, 0, 127, 1, 64);
1617 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1618 V4L2_CID_SATURATION, 0, 127, 1, 64);
1619 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1620 V4L2_CID_HUE, -128, 127, 1, 0);
1621 state->agc = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1622 V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
1623 state->gain = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1624 V4L2_CID_CHROMA_GAIN, 0, 127, 1, 40);
1625 sd->ctrl_handler = hdl;
1626 if (hdl->error) {
1627 int err = hdl->error;
1629 v4l2_ctrl_handler_free(hdl);
1630 kfree(state);
1631 return err;
1633 v4l2_ctrl_auto_cluster(2, &state->agc, 0, true);
1635 state->input = -1;
1636 state->output = SAA7115_IPORT_ON;
1637 state->enable = 1;
1638 state->radio = 0;
1639 switch (chip_id) {
1640 case '1':
1641 state->ident = V4L2_IDENT_SAA7111;
1642 if (saa711x_read(sd, R_00_CHIP_VERSION) & 0xf0) {
1643 v4l_info(client, "saa7111a variant found\n");
1644 state->ident = V4L2_IDENT_SAA7111A;
1646 break;
1647 case '3':
1648 state->ident = V4L2_IDENT_SAA7113;
1649 break;
1650 case '4':
1651 state->ident = V4L2_IDENT_SAA7114;
1652 break;
1653 case '5':
1654 state->ident = V4L2_IDENT_SAA7115;
1655 break;
1656 case '8':
1657 state->ident = V4L2_IDENT_SAA7118;
1658 break;
1659 default:
1660 state->ident = V4L2_IDENT_SAA7111;
1661 v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
1662 break;
1665 state->audclk_freq = 48000;
1667 v4l2_dbg(1, debug, sd, "writing init values\n");
1669 /* init to 60hz/48khz */
1670 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1671 switch (state->ident) {
1672 case V4L2_IDENT_SAA7111:
1673 case V4L2_IDENT_SAA7111A:
1674 saa711x_writeregs(sd, saa7111_init);
1675 break;
1676 case V4L2_IDENT_SAA7113:
1677 saa711x_writeregs(sd, saa7113_init);
1678 break;
1679 default:
1680 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1681 saa711x_writeregs(sd, saa7115_init_auto_input);
1683 if (state->ident > V4L2_IDENT_SAA7111A)
1684 saa711x_writeregs(sd, saa7115_init_misc);
1685 saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
1686 v4l2_ctrl_handler_setup(hdl);
1688 v4l2_dbg(1, debug, sd, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1689 saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC),
1690 saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC));
1691 return 0;
1694 /* ----------------------------------------------------------------------- */
1696 static int saa711x_remove(struct i2c_client *client)
1698 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1700 v4l2_device_unregister_subdev(sd);
1701 v4l2_ctrl_handler_free(sd->ctrl_handler);
1702 kfree(to_state(sd));
1703 return 0;
1706 static const struct i2c_device_id saa711x_id[] = {
1707 { "saa7115_auto", 1 }, /* autodetect */
1708 { "saa7111", 0 },
1709 { "saa7113", 0 },
1710 { "saa7114", 0 },
1711 { "saa7115", 0 },
1712 { "saa7118", 0 },
1715 MODULE_DEVICE_TABLE(i2c, saa711x_id);
1717 static struct i2c_driver saa711x_driver = {
1718 .driver = {
1719 .owner = THIS_MODULE,
1720 .name = "saa7115",
1722 .probe = saa711x_probe,
1723 .remove = saa711x_remove,
1724 .id_table = saa711x_id,
1727 module_i2c_driver(saa711x_driver);