1/* saa711x - Philips SAA711x video decoder driver 2 * This driver can work with saa7111, saa7111a, saa7113, saa7114, 3 * saa7115 and saa7118. 4 * 5 * Based on saa7114 driver by Maxim Yevtyushkin, which is based on 6 * the saa7111 driver by Dave Perks. 7 * 8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net> 9 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com> 10 * 11 * Slight changes for video timing and attachment output by 12 * Wolfgang Scherr <scherr@net4you.net> 13 * 14 * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003) 15 * by Ronald Bultje <rbultje@ronald.bitfreak.net> 16 * 17 * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com> 18 * (2/17/2003) 19 * 20 * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl> 21 * 22 * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> 23 * SAA7111, SAA7113 and SAA7118 support 24 * 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. 29 * 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. 34 * 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. 38 */ 39 40#include "saa711x_regs.h" 41 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/v4l2-chip-ident.h> 49#include <media/saa7115.h> 50#include <asm/div64.h> 51 52#define VRES_60HZ (480+16) 53 54MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver"); 55MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, " 56 "Hans Verkuil, Mauro Carvalho Chehab"); 57MODULE_LICENSE("GPL"); 58 59static int debug = 0; 60module_param(debug, bool, 0644); 61 62MODULE_PARM_DESC(debug, "Debug level (0-1)"); 63 64static unsigned short normal_i2c[] = { 65 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */ 66 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */ 67 I2C_CLIENT_END }; 68 69 70I2C_CLIENT_INSMOD; 71 72struct saa711x_state { 73 v4l2_std_id std; 74 int input; 75 int output; 76 int enable; 77 int radio; 78 int bright; 79 int contrast; 80 int hue; 81 int sat; 82 int width; 83 int height; 84 u32 ident; 85 u32 audclk_freq; 86 u32 crystal_freq; 87 u8 ucgc; 88 u8 cgcdiv; 89 u8 apll; 90}; 91 92/* ----------------------------------------------------------------------- */ 93 94static inline int saa711x_write(struct i2c_client *client, u8 reg, u8 value) 95{ 96 return i2c_smbus_write_byte_data(client, reg, value); 97} 98 99/* Sanity routine to check if a register is present */ 100static int saa711x_has_reg(const int id, const u8 reg) 101{ 102 if (id == V4L2_IDENT_SAA7111) 103 return reg < 0x20 && reg != 0x01 && reg != 0x0f && 104 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e; 105 106 /* common for saa7113/4/5/8 */ 107 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f || 108 reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) || 109 reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) || 110 reg == 0x82 || (reg >= 0x89 && reg <= 0x8e))) 111 return 0; 112 113 switch (id) { 114 case V4L2_IDENT_SAA7113: 115 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) && 116 reg != 0x5d && reg < 0x63; 117 case V4L2_IDENT_SAA7114: 118 return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) && 119 (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 && 120 reg != 0x81 && reg < 0xf0; 121 case V4L2_IDENT_SAA7115: 122 return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe); 123 case V4L2_IDENT_SAA7118: 124 return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) && 125 (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 && 126 (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0; 127 } 128 return 1; 129} 130 131static int saa711x_writeregs(struct i2c_client *client, const unsigned char *regs) 132{ 133 struct saa711x_state *state = i2c_get_clientdata(client); 134 unsigned char reg, data; 135 136 while (*regs != 0x00) { 137 reg = *(regs++); 138 data = *(regs++); 139 140 /* According with datasheets, reserved regs should be 141 filled with 0 - seems better not to touch on they */ 142 if (saa711x_has_reg(state->ident,reg)) { 143 if (saa711x_write(client, reg, data) < 0) 144 return -1; 145 } else { 146 v4l_dbg(1, debug, client, "tried to access reserved reg 0x%02x\n", reg); 147 } 148 } 149 return 0; 150} 151 152static inline int saa711x_read(struct i2c_client *client, u8 reg) 153{ 154 return i2c_smbus_read_byte_data(client, reg); 155} 156 157/* ----------------------------------------------------------------------- */ 158 159/* SAA7111 initialization table */ 160static const unsigned char saa7111_init[] = { 161 R_01_INC_DELAY, 0x00, /* reserved */ 162 163 /*front end */ 164 R_02_INPUT_CNTL_1, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */ 165 R_03_INPUT_CNTL_2, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, 166 * GAFIX=0, GAI1=256, GAI2=256 */ 167 R_04_INPUT_CNTL_3, 0x00, /* GAI1=256 */ 168 R_05_INPUT_CNTL_4, 0x00, /* GAI2=256 */ 169 170 /* decoder */ 171 R_06_H_SYNC_START, 0xf3, /* HSB at 13(50Hz) / 17(60Hz) 172 * pixels after end of last line */ 173 R_07_H_SYNC_STOP, 0xe8, /* HSS seems to be needed to 174 * work with NTSC, too */ 175 R_08_SYNC_CNTL, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0, 176 * VTRC=1, HPLL=0, VNOI=0 */ 177 R_09_LUMA_CNTL, 0x01, /* BYPS=0, PREF=0, BPSS=0, 178 * VBLB=0, UPTCV=0, APER=1 */ 179 R_0A_LUMA_BRIGHT_CNTL, 0x80, 180 R_0B_LUMA_CONTRAST_CNTL, 0x47, /* 0b - CONT=1.109 */ 181 R_0C_CHROMA_SAT_CNTL, 0x40, 182 R_0D_CHROMA_HUE_CNTL, 0x00, 183 R_0E_CHROMA_CNTL_1, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, 184 * FCTC=0, CHBW=1 */ 185 R_0F_CHROMA_GAIN_CNTL, 0x00, /* reserved */ 186 R_10_CHROMA_CNTL_2, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */ 187 R_11_MODE_DELAY_CNTL, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, 188 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */ 189 R_12_RT_SIGNAL_CNTL, 0x00, /* 12 - output control 2 */ 190 R_13_RT_X_PORT_OUT_CNTL, 0x00, /* 13 - output control 3 */ 191 R_14_ANAL_ADC_COMPAT_CNTL, 0x00, 192 R_15_VGATE_START_FID_CHG, 0x00, 193 R_16_VGATE_STOP, 0x00, 194 R_17_MISC_VGATE_CONF_AND_MSB, 0x00, 195 196 0x00, 0x00 197}; 198 199/* SAA7113 init codes */ 200static const unsigned char saa7113_init[] = { 201 R_01_INC_DELAY, 0x08, 202 R_02_INPUT_CNTL_1, 0xc2, 203 R_03_INPUT_CNTL_2, 0x30, 204 R_04_INPUT_CNTL_3, 0x00, 205 R_05_INPUT_CNTL_4, 0x00, 206 R_06_H_SYNC_START, 0x89, 207 R_07_H_SYNC_STOP, 0x0d, 208 R_08_SYNC_CNTL, 0x88, 209 R_09_LUMA_CNTL, 0x01, 210 R_0A_LUMA_BRIGHT_CNTL, 0x80, 211 R_0B_LUMA_CONTRAST_CNTL, 0x47, 212 R_0C_CHROMA_SAT_CNTL, 0x40, 213 R_0D_CHROMA_HUE_CNTL, 0x00, 214 R_0E_CHROMA_CNTL_1, 0x01, 215 R_0F_CHROMA_GAIN_CNTL, 0x2a, 216 R_10_CHROMA_CNTL_2, 0x08, 217 R_11_MODE_DELAY_CNTL, 0x0c, 218 R_12_RT_SIGNAL_CNTL, 0x07, 219 R_13_RT_X_PORT_OUT_CNTL, 0x00, 220 R_14_ANAL_ADC_COMPAT_CNTL, 0x00, 221 R_15_VGATE_START_FID_CHG, 0x00, 222 R_16_VGATE_STOP, 0x00, 223 R_17_MISC_VGATE_CONF_AND_MSB, 0x00, 224 225 0x00, 0x00 226}; 227 228/* If a value differs from the Hauppauge driver values, then the comment starts with 229 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the 230 Hauppauge driver sets. */ 231 232/* SAA7114 and SAA7115 initialization table */ 233static const unsigned char saa7115_init_auto_input[] = { 234 /* Front-End Part */ 235 R_01_INC_DELAY, 0x48, /* white peak control disabled */ 236 R_03_INPUT_CNTL_2, 0x20, /* was 0x30. 0x20: long vertical blanking */ 237 R_04_INPUT_CNTL_3, 0x90, /* analog gain set to 0 */ 238 R_05_INPUT_CNTL_4, 0x90, /* analog gain set to 0 */ 239 /* Decoder Part */ 240 R_06_H_SYNC_START, 0xeb, /* horiz sync begin = -21 */ 241 R_07_H_SYNC_STOP, 0xe0, /* horiz sync stop = -17 */ 242 R_09_LUMA_CNTL, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */ 243 R_0A_LUMA_BRIGHT_CNTL, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */ 244 R_0B_LUMA_CONTRAST_CNTL, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */ 245 R_0C_CHROMA_SAT_CNTL, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */ 246 R_0D_CHROMA_HUE_CNTL, 0x00, 247 R_0F_CHROMA_GAIN_CNTL, 0x00, /* use automatic gain */ 248 R_10_CHROMA_CNTL_2, 0x06, /* chroma: active adaptive combfilter */ 249 R_11_MODE_DELAY_CNTL, 0x00, 250 R_12_RT_SIGNAL_CNTL, 0x9d, /* RTS0 output control: VGATE */ 251 R_13_RT_X_PORT_OUT_CNTL, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */ 252 R_14_ANAL_ADC_COMPAT_CNTL, 0x00, 253 R_18_RAW_DATA_GAIN_CNTL, 0x40, /* gain 0x00 = nominal */ 254 R_19_RAW_DATA_OFF_CNTL, 0x80, 255 R_1A_COLOR_KILL_LVL_CNTL, 0x77, /* recommended value */ 256 R_1B_MISC_TVVCRDET, 0x42, /* recommended value */ 257 R_1C_ENHAN_COMB_CTRL1, 0xa9, /* recommended value */ 258 R_1D_ENHAN_COMB_CTRL2, 0x01, /* recommended value */ 259 260 261 R_80_GLOBAL_CNTL_1, 0x0, /* No tasks enabled at init */ 262 263 /* Power Device Control */ 264 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset device */ 265 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* set device programmed, all in operational mode */ 266 0x00, 0x00 267}; 268 269/* Used to reset saa7113, saa7114 and saa7115 */ 270static const unsigned char saa7115_cfg_reset_scaler[] = { 271 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00, /* disable I-port output */ 272 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */ 273 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */ 274 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* enable I-port output */ 275 0x00, 0x00 276}; 277 278/* ============== SAA7715 VIDEO templates ============= */ 279 280static const unsigned char saa7115_cfg_60hz_video[] = { 281 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */ 282 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */ 283 284 R_15_VGATE_START_FID_CHG, 0x03, 285 R_16_VGATE_STOP, 0x11, 286 R_17_MISC_VGATE_CONF_AND_MSB, 0x9c, 287 288 R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */ 289 R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */ 290 291 R_5A_V_OFF_FOR_SLICER, 0x06, /* standard 60hz value for ITU656 line counting */ 292 293 /* Task A */ 294 R_90_A_TASK_HANDLING_CNTL, 0x80, 295 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48, 296 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40, 297 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84, 298 299 /* hoffset low (input), 0x0002 is minimum */ 300 R_94_A_HORIZ_INPUT_WINDOW_START, 0x01, 301 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00, 302 303 /* hsize low (input), 0x02d0 = 720 */ 304 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0, 305 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02, 306 307 R_98_A_VERT_INPUT_WINDOW_START, 0x05, 308 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00, 309 310 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c, 311 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00, 312 313 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0, 314 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05, 315 316 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c, 317 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00, 318 319 /* Task B */ 320 R_C0_B_TASK_HANDLING_CNTL, 0x00, 321 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08, 322 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00, 323 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80, 324 325 /* 0x0002 is minimum */ 326 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02, 327 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00, 328 329 /* 0x02d0 = 720 */ 330 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0, 331 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02, 332 333 /* vwindow start 0x12 = 18 */ 334 R_C8_B_VERT_INPUT_WINDOW_START, 0x12, 335 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00, 336 337 /* vwindow length 0xf8 = 248 */ 338 R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1, 339 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9, 340 341 /* hwindow 0x02d0 = 720 */ 342 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0, 343 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02, 344 345 R_F0_LFCO_PER_LINE, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */ 346 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0 */ 347 R_F5_PULSGEN_LINE_LENGTH, 0xad, 348 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01, 349 350 0x00, 0x00 351}; 352 353static const unsigned char saa7115_cfg_50hz_video[] = { 354 R_80_GLOBAL_CNTL_1, 0x00, 355 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */ 356 357 R_15_VGATE_START_FID_CHG, 0x37, /* VGATE start */ 358 R_16_VGATE_STOP, 0x16, 359 R_17_MISC_VGATE_CONF_AND_MSB, 0x99, 360 361 R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */ 362 R_0E_CHROMA_CNTL_1, 0x07, 363 364 R_5A_V_OFF_FOR_SLICER, 0x03, /* standard 50hz value */ 365 366 /* Task A */ 367 R_90_A_TASK_HANDLING_CNTL, 0x81, 368 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48, 369 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40, 370 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84, 371 372 /* This is weird: the datasheet says that you should use 2 as the minimum value, */ 373 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */ 374 /* hoffset low (input), 0x0002 is minimum */ 375 R_94_A_HORIZ_INPUT_WINDOW_START, 0x00, 376 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00, 377 378 /* hsize low (input), 0x02d0 = 720 */ 379 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0, 380 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02, 381 382 R_98_A_VERT_INPUT_WINDOW_START, 0x03, 383 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00, 384 385 /* vsize 0x12 = 18 */ 386 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12, 387 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00, 388 389 /* hsize 0x05a0 = 1440 */ 390 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0, 391 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05, /* hsize hi (output) */ 392 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12, /* vsize low (output), 0x12 = 18 */ 393 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00, /* vsize hi (output) */ 394 395 /* Task B */ 396 R_C0_B_TASK_HANDLING_CNTL, 0x00, 397 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08, 398 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00, 399 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80, 400 401 /* This is weird: the datasheet says that you should use 2 as the minimum value, */ 402 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */ 403 /* hoffset low (input), 0x0002 is minimum. See comment above. */ 404 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00, 405 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00, 406 407 /* hsize 0x02d0 = 720 */ 408 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0, 409 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02, 410 411 /* voffset 0x16 = 22 */ 412 R_C8_B_VERT_INPUT_WINDOW_START, 0x16, 413 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00, 414 415 /* vsize 0x0120 = 288 */ 416 R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20, 417 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01, 418 419 /* hsize 0x02d0 = 720 */ 420 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0, 421 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02, 422 423 R_F0_LFCO_PER_LINE, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */ 424 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0, (was 0x05) */ 425 R_F5_PULSGEN_LINE_LENGTH, 0xb0, 426 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01, 427 428 0x00, 0x00 429}; 430 431/* ============== SAA7715 VIDEO templates (end) ======= */ 432 433static const unsigned char saa7115_cfg_vbi_on[] = { 434 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */ 435 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */ 436 R_80_GLOBAL_CNTL_1, 0x30, /* Activate both tasks */ 437 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */ 438 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */ 439 440 0x00, 0x00 441}; 442 443static const unsigned char saa7115_cfg_vbi_off[] = { 444 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */ 445 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */ 446 R_80_GLOBAL_CNTL_1, 0x20, /* Activate only task "B" */ 447 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */ 448 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */ 449 450 0x00, 0x00 451}; 452 453 454static const unsigned char saa7115_init_misc[] = { 455 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01, 456 R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01, 457 R_84_I_PORT_SIGNAL_DEF, 0x20, 458 R_85_I_PORT_SIGNAL_POLAR, 0x21, 459 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5, 460 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, 461 462 /* Task A */ 463 R_A0_A_HORIZ_PRESCALING, 0x01, 464 R_A1_A_ACCUMULATION_LENGTH, 0x00, 465 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00, 466 467 /* Configure controls at nominal value*/ 468 R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80, 469 R_A5_A_LUMA_CONTRAST_CNTL, 0x40, 470 R_A6_A_CHROMA_SATURATION_CNTL, 0x40, 471 472 /* note: 2 x zoom ensures that VBI lines have same length as video lines. */ 473 R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00, 474 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02, 475 476 R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00, 477 478 /* must be horiz lum scaling / 2 */ 479 R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00, 480 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01, 481 482 /* must be offset luma / 2 */ 483 R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00, 484 485 R_B0_A_VERT_LUMA_SCALING_INC, 0x00, 486 R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04, 487 488 R_B2_A_VERT_CHROMA_SCALING_INC, 0x00, 489 R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04, 490 491 R_B4_A_VERT_SCALING_MODE_CNTL, 0x01, 492 493 R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00, 494 R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00, 495 R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00, 496 R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00, 497 498 R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00, 499 R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00, 500 R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00, 501 R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00, 502 503 /* Task B */ 504 R_D0_B_HORIZ_PRESCALING, 0x01, 505 R_D1_B_ACCUMULATION_LENGTH, 0x00, 506 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00, 507 508 /* Configure controls at nominal value*/ 509 R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80, 510 R_D5_B_LUMA_CONTRAST_CNTL, 0x40, 511 R_D6_B_CHROMA_SATURATION_CNTL, 0x40, 512 513 /* hor lum scaling 0x0400 = 1 */ 514 R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00, 515 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04, 516 517 R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00, 518 519 /* must be hor lum scaling / 2 */ 520 R_DC_B_HORIZ_CHROMA_SCALING, 0x00, 521 R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02, 522 523 /* must be offset luma / 2 */ 524 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00, 525 526 R_E0_B_VERT_LUMA_SCALING_INC, 0x00, 527 R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04, 528 529 R_E2_B_VERT_CHROMA_SCALING_INC, 0x00, 530 R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04, 531 532 R_E4_B_VERT_SCALING_MODE_CNTL, 0x01, 533 534 R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00, 535 R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00, 536 R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00, 537 R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00, 538 539 R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00, 540 R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00, 541 R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00, 542 R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00, 543 544 R_F2_NOMINAL_PLL2_DTO, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */ 545 R_F3_PLL_INCREMENT, 0x46, 546 R_F4_PLL2_STATUS, 0x00, 547 R_F7_PULSE_A_POS_MSB, 0x4b, /* not the recommended settings! */ 548 R_F8_PULSE_B_POS, 0x00, 549 R_F9_PULSE_B_POS_MSB, 0x4b, 550 R_FA_PULSE_C_POS, 0x00, 551 R_FB_PULSE_C_POS_MSB, 0x4b, 552 553 /* PLL2 lock detection settings: 71 lines 50% phase error */ 554 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88, 555 556 /* Turn off VBI */ 557 R_40_SLICER_CNTL_1, 0x20, /* No framing code errors allowed. */ 558 R_41_LCR_BASE, 0xff, 559 R_41_LCR_BASE+1, 0xff, 560 R_41_LCR_BASE+2, 0xff, 561 R_41_LCR_BASE+3, 0xff, 562 R_41_LCR_BASE+4, 0xff, 563 R_41_LCR_BASE+5, 0xff, 564 R_41_LCR_BASE+6, 0xff, 565 R_41_LCR_BASE+7, 0xff, 566 R_41_LCR_BASE+8, 0xff, 567 R_41_LCR_BASE+9, 0xff, 568 R_41_LCR_BASE+10, 0xff, 569 R_41_LCR_BASE+11, 0xff, 570 R_41_LCR_BASE+12, 0xff, 571 R_41_LCR_BASE+13, 0xff, 572 R_41_LCR_BASE+14, 0xff, 573 R_41_LCR_BASE+15, 0xff, 574 R_41_LCR_BASE+16, 0xff, 575 R_41_LCR_BASE+17, 0xff, 576 R_41_LCR_BASE+18, 0xff, 577 R_41_LCR_BASE+19, 0xff, 578 R_41_LCR_BASE+20, 0xff, 579 R_41_LCR_BASE+21, 0xff, 580 R_41_LCR_BASE+22, 0xff, 581 R_58_PROGRAM_FRAMING_CODE, 0x40, 582 R_59_H_OFF_FOR_SLICER, 0x47, 583 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83, 584 R_5D_DID, 0xbd, 585 R_5E_SDID, 0x35, 586 587 R_02_INPUT_CNTL_1, 0x84, /* input tuner -> input 4, amplifier active */ 588 589 R_80_GLOBAL_CNTL_1, 0x20, /* enable task B */ 590 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, 591 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, 592 0x00, 0x00 593}; 594 595static int saa711x_odd_parity(u8 c) 596{ 597 c ^= (c >> 4); 598 c ^= (c >> 2); 599 c ^= (c >> 1); 600 601 return c & 1; 602} 603 604static int saa711x_decode_vps(u8 * dst, u8 * p) 605{ 606 static const u8 biphase_tbl[] = { 607 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, 608 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, 609 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96, 610 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2, 611 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94, 612 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0, 613 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, 614 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, 615 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5, 616 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1, 617 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87, 618 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3, 619 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85, 620 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1, 621 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5, 622 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1, 623 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4, 624 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0, 625 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86, 626 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2, 627 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84, 628 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0, 629 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4, 630 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0, 631 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, 632 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, 633 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96, 634 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2, 635 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94, 636 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0, 637 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, 638 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, 639 }; 640 int i; 641 u8 c, err = 0; 642 643 for (i = 0; i < 2 * 13; i += 2) { 644 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]]; 645 c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4); 646 dst[i / 2] = c; 647 } 648 return err & 0xf0; 649} 650 651static int saa711x_decode_wss(u8 * p) 652{ 653 static const int wss_bits[8] = { 654 0, 0, 0, 1, 0, 1, 1, 1 655 }; 656 unsigned char parity; 657 int wss = 0; 658 int i; 659 660 for (i = 0; i < 16; i++) { 661 int b1 = wss_bits[p[i] & 7]; 662 int b2 = wss_bits[(p[i] >> 3) & 7]; 663 664 if (b1 == b2) 665 return -1; 666 wss |= b2 << i; 667 } 668 parity = wss & 15; 669 parity ^= parity >> 2; 670 parity ^= parity >> 1; 671 672 if (!(parity & 1)) 673 return -1; 674 675 return wss; 676} 677 678static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq) 679{ 680 struct saa711x_state *state = i2c_get_clientdata(client); 681 u32 acpf; 682 u32 acni; 683 u32 hz; 684 u64 f; 685 u8 acc = 0; /* reg 0x3a, audio clock control */ 686 687 /* Checks for chips that don't have audio clock (saa7111, saa7113) */ 688 if (!saa711x_has_reg(state->ident,R_30_AUD_MAST_CLK_CYCLES_PER_FIELD)) 689 return 0; 690 691 v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq); 692 693 /* sanity check */ 694 if (freq < 32000 || freq > 48000) 695 return -EINVAL; 696 697 /* hz is the refresh rate times 100 */ 698 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000; 699 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */ 700 acpf = (25600 * freq) / hz; 701 /* acni = (256 * freq * 2^23) / crystal_frequency = 702 (freq * 2^(8+23)) / crystal_frequency = 703 (freq << 31) / crystal_frequency */ 704 f = freq; 705 f = f << 31; 706 do_div(f, state->crystal_freq); 707 acni = f; 708 if (state->ucgc) { 709 acpf = acpf * state->cgcdiv / 16; 710 acni = acni * state->cgcdiv / 16; 711 acc = 0x80; 712 if (state->cgcdiv == 3) 713 acc |= 0x40; 714 } 715 if (state->apll) 716 acc |= 0x08; 717 718 saa711x_write(client, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03); 719 saa711x_write(client, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10); 720 saa711x_write(client, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc); 721 722 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff); 723 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1, 724 (acpf >> 8) & 0xff); 725 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2, 726 (acpf >> 16) & 0x03); 727 728 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff); 729 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff); 730 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f); 731 state->audclk_freq = freq; 732 return 0; 733} 734 735static int saa711x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 736{ 737 struct saa711x_state *state = i2c_get_clientdata(client); 738 739 switch (ctrl->id) { 740 case V4L2_CID_BRIGHTNESS: 741 if (ctrl->value < 0 || ctrl->value > 255) { 742 v4l_err(client, "invalid brightness setting %d\n", ctrl->value); 743 return -ERANGE; 744 } 745 746 state->bright = ctrl->value; 747 saa711x_write(client, R_0A_LUMA_BRIGHT_CNTL, state->bright); 748 break; 749 750 case V4L2_CID_CONTRAST: 751 if (ctrl->value < 0 || ctrl->value > 127) { 752 v4l_err(client, "invalid contrast setting %d\n", ctrl->value); 753 return -ERANGE; 754 } 755 756 state->contrast = ctrl->value; 757 saa711x_write(client, R_0B_LUMA_CONTRAST_CNTL, state->contrast); 758 break; 759 760 case V4L2_CID_SATURATION: 761 if (ctrl->value < 0 || ctrl->value > 127) { 762 v4l_err(client, "invalid saturation setting %d\n", ctrl->value); 763 return -ERANGE; 764 } 765 766 state->sat = ctrl->value; 767 saa711x_write(client, R_0C_CHROMA_SAT_CNTL, state->sat); 768 break; 769 770 case V4L2_CID_HUE: 771 if (ctrl->value < -127 || ctrl->value > 127) { 772 v4l_err(client, "invalid hue setting %d\n", ctrl->value); 773 return -ERANGE; 774 } 775 776 state->hue = ctrl->value; 777 saa711x_write(client, R_0D_CHROMA_HUE_CNTL, state->hue); 778 break; 779 780 default: 781 return -EINVAL; 782 } 783 784 return 0; 785} 786 787static int saa711x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 788{ 789 struct saa711x_state *state = i2c_get_clientdata(client); 790 791 switch (ctrl->id) { 792 case V4L2_CID_BRIGHTNESS: 793 ctrl->value = state->bright; 794 break; 795 case V4L2_CID_CONTRAST: 796 ctrl->value = state->contrast; 797 break; 798 case V4L2_CID_SATURATION: 799 ctrl->value = state->sat; 800 break; 801 case V4L2_CID_HUE: 802 ctrl->value = state->hue; 803 break; 804 default: 805 return -EINVAL; 806 } 807 808 return 0; 809} 810 811static int saa711x_set_size(struct i2c_client *client, int width, int height) 812{ 813 struct saa711x_state *state = i2c_get_clientdata(client); 814 int HPSC, HFSC; 815 int VSCY; 816 int res; 817 int is_50hz = state->std & V4L2_STD_625_50; 818 int Vsrc = is_50hz ? 576 : 480; 819 820 v4l_dbg(1, debug, client, "decoder set size to %ix%i\n",width,height); 821 822 if ((width < 1) || (width > 1440)) 823 return -EINVAL; 824 if ((height < 1) || (height > Vsrc)) 825 return -EINVAL; 826 827 if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) { 828 /* Decoder only supports 720 columns and 480 or 576 lines */ 829 if (width != 720) 830 return -EINVAL; 831 if (height != Vsrc) 832 return -EINVAL; 833 } 834 835 state->width = width; 836 state->height = height; 837 838 if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH)) 839 return 0; 840 841 /* probably have a valid size, let's set it */ 842 /* Set output width/height */ 843 /* width */ 844 845 saa711x_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 846 (u8) (width & 0xff)); 847 saa711x_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 848 (u8) ((width >> 8) & 0xff)); 849 850 /* Vertical Scaling uses height/2 */ 851 res=height/2; 852 853 /* On 60Hz, it is using a higher Vertical Output Size */ 854 if (!is_50hz) 855 res += (VRES_60HZ - 480) >> 1; 856 857 /* height */ 858 saa711x_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 859 (u8) (res & 0xff)); 860 saa711x_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 861 (u8) ((res >> 8) & 0xff)); 862 863 /* Scaling settings */ 864 /* Hprescaler is floor(inres/outres) */ 865 HPSC = (int)(720 / width); 866 /* 0 is not allowed (div. by zero) */ 867 HPSC = HPSC ? HPSC : 1; 868 HFSC = (int)((1024 * 720) / (HPSC * width)); 869 saa711x_write(client, R_D0_B_HORIZ_PRESCALING, 870 (u8) (HPSC & 0x3f)); 871 872 v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC); 873 /* write H fine-scaling (luminance) */ 874 saa711x_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC, 875 (u8) (HFSC & 0xff)); 876 saa711x_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 877 (u8) ((HFSC >> 8) & 0xff)); 878 /* write H fine-scaling (chrominance) 879 * must be lum/2, so i'll just bitshift :) */ 880 saa711x_write(client, R_DC_B_HORIZ_CHROMA_SCALING, 881 (u8) ((HFSC >> 1) & 0xff)); 882 saa711x_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB, 883 (u8) ((HFSC >> 9) & 0xff)); 884 885 VSCY = (int)((1024 * Vsrc) / height); 886 v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY); 887 888 /* Correct Contrast and Luminance */ 889 saa711x_write(client, R_D5_B_LUMA_CONTRAST_CNTL, 890 (u8) (64 * 1024 / VSCY)); 891 saa711x_write(client, R_D6_B_CHROMA_SATURATION_CNTL, 892 (u8) (64 * 1024 / VSCY)); 893 894 /* write V fine-scaling (luminance) */ 895 saa711x_write(client, R_E0_B_VERT_LUMA_SCALING_INC, 896 (u8) (VSCY & 0xff)); 897 saa711x_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB, 898 (u8) ((VSCY >> 8) & 0xff)); 899 /* write V fine-scaling (chrominance) */ 900 saa711x_write(client, R_E2_B_VERT_CHROMA_SCALING_INC, 901 (u8) (VSCY & 0xff)); 902 saa711x_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 903 (u8) ((VSCY >> 8) & 0xff)); 904 905 saa711x_writeregs(client, saa7115_cfg_reset_scaler); 906 907 /* Activates task "B" */ 908 saa711x_write(client, R_80_GLOBAL_CNTL_1, 909 saa711x_read(client,R_80_GLOBAL_CNTL_1) | 0x20); 910 911 return 0; 912} 913 914static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std) 915{ 916 struct saa711x_state *state = i2c_get_clientdata(client); 917 918 /* Prevent unnecessary standard changes. During a standard 919 change the I-Port is temporarily disabled. Any devices 920 reading from that port can get confused. 921 Note that VIDIOC_S_STD is also used to switch from 922 radio to TV mode, so if a VIDIOC_S_STD is broadcast to 923 all I2C devices then you do not want to have an unwanted 924 side-effect here. */ 925 if (std == state->std) 926 return; 927 928 state->std = std; 929 930 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants. 931 if (std & V4L2_STD_525_60) { 932 v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n"); 933 saa711x_writeregs(client, saa7115_cfg_60hz_video); 934 saa711x_set_size(client, 720, 480); 935 } else { 936 v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n"); 937 saa711x_writeregs(client, saa7115_cfg_50hz_video); 938 saa711x_set_size(client, 720, 576); 939 } 940 941 /* Register 0E - Bits D6-D4 on NO-AUTO mode 942 (SAA7111 and SAA7113 doesn't have auto mode) 943 50 Hz / 625 lines 60 Hz / 525 lines 944 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz) 945 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz) 946 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz) 947 011 NTSC N (3.58MHz) PAL M (3.58MHz) 948 100 reserved NTSC-Japan (3.58MHz) 949 */ 950 if (state->ident == V4L2_IDENT_SAA7111 || 951 state->ident == V4L2_IDENT_SAA7113) { 952 u8 reg = saa711x_read(client, R_0E_CHROMA_CNTL_1) & 0x8f; 953 954 if (std == V4L2_STD_PAL_M) { 955 reg |= 0x30; 956 } else if (std == V4L2_STD_PAL_N) { 957 reg |= 0x20; 958 } else if (std == V4L2_STD_PAL_60) { 959 reg |= 0x10; 960 } else if (std == V4L2_STD_NTSC_M_JP) { 961 reg |= 0x40; 962 } else if (std & V4L2_STD_SECAM) { 963 reg |= 0x50; 964 } 965 saa711x_write(client, R_0E_CHROMA_CNTL_1, reg); 966 } else { 967 /* restart task B if needed */ 968 int taskb = saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10; 969 970 if (taskb && state->ident == V4L2_IDENT_SAA7114) { 971 saa711x_writeregs(client, saa7115_cfg_vbi_on); 972 } 973 974 /* switch audio mode too! */ 975 saa711x_set_audio_clock_freq(client, state->audclk_freq); 976 } 977} 978 979static v4l2_std_id saa711x_get_v4lstd(struct i2c_client *client) 980{ 981 struct saa711x_state *state = i2c_get_clientdata(client); 982 983 return state->std; 984} 985 986static void saa711x_log_status(struct i2c_client *client) 987{ 988 struct saa711x_state *state = i2c_get_clientdata(client); 989 int reg1e, reg1f; 990 int signalOk; 991 int vcr; 992 993 v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq); 994 if (state->ident != V4L2_IDENT_SAA7115) { 995 /* status for the saa7114 */ 996 reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC); 997 signalOk = (reg1f & 0xc1) == 0x81; 998 v4l_info(client, "Video signal: %s\n", signalOk ? "ok" : "bad"); 999 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz"); 1000 return; 1001 } 1002 1003 /* status for the saa7115 */ 1004 reg1e = saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC); 1005 reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC); 1006 1007 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80; 1008 vcr = !(reg1f & 0x10); 1009 1010 if (state->input >= 6) { 1011 v4l_info(client, "Input: S-Video %d\n", state->input - 6); 1012 } else { 1013 v4l_info(client, "Input: Composite %d\n", state->input); 1014 } 1015 v4l_info(client, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad"); 1016 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz"); 1017 1018 switch (reg1e & 0x03) { 1019 case 1: 1020 v4l_info(client, "Detected format: NTSC\n"); 1021 break; 1022 case 2: 1023 v4l_info(client, "Detected format: PAL\n"); 1024 break; 1025 case 3: 1026 v4l_info(client, "Detected format: SECAM\n"); 1027 break; 1028 default: 1029 v4l_info(client, "Detected format: BW/No color\n"); 1030 break; 1031 } 1032 v4l_info(client, "Width, Height: %d, %d\n", state->width, state->height); 1033} 1034 1035/* setup the sliced VBI lcr registers according to the sliced VBI format */ 1036static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt) 1037{ 1038 struct saa711x_state *state = i2c_get_clientdata(client); 1039 int is_50hz = (state->std & V4L2_STD_625_50); 1040 u8 lcr[24]; 1041 int i, x; 1042 1043 /* saa7113/7114/7118 VBI support are experimental */ 1044 if (!saa711x_has_reg(state->ident,R_41_LCR_BASE)) 1045 return; 1046 1047 1048 for (i = 0; i <= 23; i++) 1049 lcr[i] = 0xff; 1050 1051 if (fmt->service_set == 0) { 1052 /* raw VBI */ 1053 if (is_50hz) 1054 for (i = 6; i <= 23; i++) 1055 lcr[i] = 0xdd; 1056 else 1057 for (i = 10; i <= 21; i++) 1058 lcr[i] = 0xdd; 1059 } else { 1060 /* sliced VBI */ 1061 /* first clear lines that cannot be captured */ 1062 if (is_50hz) { 1063 for (i = 0; i <= 5; i++) 1064 fmt->service_lines[0][i] = 1065 fmt->service_lines[1][i] = 0; 1066 } 1067 else { 1068 for (i = 0; i <= 9; i++) 1069 fmt->service_lines[0][i] = 1070 fmt->service_lines[1][i] = 0; 1071 for (i = 22; i <= 23; i++) 1072 fmt->service_lines[0][i] = 1073 fmt->service_lines[1][i] = 0; 1074 } 1075 1076 /* Now set the lcr values according to the specified service */ 1077 for (i = 6; i <= 23; i++) { 1078 lcr[i] = 0; 1079 for (x = 0; x <= 1; x++) { 1080 switch (fmt->service_lines[1-x][i]) { 1081 case 0: 1082 lcr[i] |= 0xf << (4 * x); 1083 break; 1084 case V4L2_SLICED_TELETEXT_B: 1085 lcr[i] |= 1 << (4 * x); 1086 break; 1087 case V4L2_SLICED_CAPTION_525: 1088 lcr[i] |= 4 << (4 * x); 1089 break; 1090 case V4L2_SLICED_WSS_625: 1091 lcr[i] |= 5 << (4 * x); 1092 break; 1093 case V4L2_SLICED_VPS: 1094 lcr[i] |= 7 << (4 * x); 1095 break; 1096 } 1097 } 1098 } 1099 } 1100 1101 /* write the lcr registers */ 1102 for (i = 2; i <= 23; i++) { 1103 saa711x_write(client, i - 2 + R_41_LCR_BASE, lcr[i]); 1104 } 1105 1106 /* enable/disable raw VBI capturing */ 1107 saa711x_writeregs(client, fmt->service_set == 0 ? 1108 saa7115_cfg_vbi_on : 1109 saa7115_cfg_vbi_off); 1110} 1111 1112static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 1113{ 1114 static u16 lcr2vbi[] = { 1115 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 1116 0, V4L2_SLICED_CAPTION_525, /* 4 */ 1117 V4L2_SLICED_WSS_625, 0, /* 5 */ 1118 V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */ 1119 0, 0, 0, 0 1120 }; 1121 struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced; 1122 int i; 1123 1124 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) 1125 return -EINVAL; 1126 memset(sliced, 0, sizeof(*sliced)); 1127 /* done if using raw VBI */ 1128 if (saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10) 1129 return 0; 1130 for (i = 2; i <= 23; i++) { 1131 u8 v = saa711x_read(client, i - 2 + R_41_LCR_BASE); 1132 1133 sliced->service_lines[0][i] = lcr2vbi[v >> 4]; 1134 sliced->service_lines[1][i] = lcr2vbi[v & 0xf]; 1135 sliced->service_set |= 1136 sliced->service_lines[0][i] | sliced->service_lines[1][i]; 1137 } 1138 return 0; 1139} 1140 1141static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 1142{ 1143 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { 1144 saa711x_set_lcr(client, &fmt->fmt.sliced); 1145 return 0; 1146 } 1147 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1148 return -EINVAL; 1149 1150 return saa711x_set_size(client,fmt->fmt.pix.width,fmt->fmt.pix.height); 1151} 1152 1153/* Decode the sliced VBI data stream as created by the saa7115. 1154 The format is described in the saa7115 datasheet in Tables 25 and 26 1155 and in Figure 33. 1156 The current implementation uses SAV/EAV codes and not the ancillary data 1157 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV 1158 code. */ 1159static void saa711x_decode_vbi_line(struct i2c_client *client, 1160 struct v4l2_decode_vbi_line *vbi) 1161{ 1162 static const char vbi_no_data_pattern[] = { 1163 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0 1164 }; 1165 struct saa711x_state *state = i2c_get_clientdata(client); 1166 u8 *p = vbi->p; 1167 u32 wss; 1168 int id1, id2; /* the ID1 and ID2 bytes from the internal header */ 1169 1170 vbi->type = 0; /* mark result as a failure */ 1171 id1 = p[2]; 1172 id2 = p[3]; 1173 /* Note: the field bit is inverted for 60 Hz video */ 1174 if (state->std & V4L2_STD_525_60) 1175 id1 ^= 0x40; 1176 1177 /* Skip internal header, p now points to the start of the payload */ 1178 p += 4; 1179 vbi->p = p; 1180 1181 /* calculate field and line number of the VBI packet (1-23) */ 1182 vbi->is_second_field = ((id1 & 0x40) != 0); 1183 vbi->line = (id1 & 0x3f) << 3; 1184 vbi->line |= (id2 & 0x70) >> 4; 1185 1186 /* Obtain data type */ 1187 id2 &= 0xf; 1188 1189 /* If the VBI slicer does not detect any signal it will fill up 1190 the payload buffer with 0xa0 bytes. */ 1191 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern))) 1192 return; 1193 1194 /* decode payloads */ 1195 switch (id2) { 1196 case 1: 1197 vbi->type = V4L2_SLICED_TELETEXT_B; 1198 break; 1199 case 4: 1200 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1])) 1201 return; 1202 vbi->type = V4L2_SLICED_CAPTION_525; 1203 break; 1204 case 5: 1205 wss = saa711x_decode_wss(p); 1206 if (wss == -1) 1207 return; 1208 p[0] = wss & 0xff; 1209 p[1] = wss >> 8; 1210 vbi->type = V4L2_SLICED_WSS_625; 1211 break; 1212 case 7: 1213 if (saa711x_decode_vps(p, p) != 0) 1214 return; 1215 vbi->type = V4L2_SLICED_VPS; 1216 break; 1217 default: 1218 return; 1219 } 1220} 1221 1222/* ============ SAA7115 AUDIO settings (end) ============= */ 1223 1224static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *arg) 1225{ 1226 struct saa711x_state *state = i2c_get_clientdata(client); 1227 1228 /* ioctls to allow direct access to the saa7115 registers for testing */ 1229 switch (cmd) { 1230 case VIDIOC_S_FMT: 1231 return saa711x_set_v4lfmt(client, (struct v4l2_format *)arg); 1232 1233 case VIDIOC_G_FMT: 1234 return saa711x_get_v4lfmt(client, (struct v4l2_format *)arg); 1235 1236 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 1237 return saa711x_set_audio_clock_freq(client, *(u32 *)arg); 1238 1239 case VIDIOC_G_TUNER: 1240 { 1241 struct v4l2_tuner *vt = arg; 1242 int status; 1243 1244 if (state->radio) 1245 break; 1246 status = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC); 1247 1248 v4l_dbg(1, debug, client, "status: 0x%02x\n", status); 1249 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0; 1250 break; 1251 } 1252 1253 case VIDIOC_LOG_STATUS: 1254 saa711x_log_status(client); 1255 break; 1256 1257 case VIDIOC_G_CTRL: 1258 return saa711x_get_v4lctrl(client, (struct v4l2_control *)arg); 1259 1260 case VIDIOC_S_CTRL: 1261 return saa711x_set_v4lctrl(client, (struct v4l2_control *)arg); 1262 1263 case VIDIOC_QUERYCTRL: 1264 { 1265 struct v4l2_queryctrl *qc = arg; 1266 1267 switch (qc->id) { 1268 case V4L2_CID_BRIGHTNESS: 1269 case V4L2_CID_CONTRAST: 1270 case V4L2_CID_SATURATION: 1271 case V4L2_CID_HUE: 1272 return v4l2_ctrl_query_fill_std(qc); 1273 default: 1274 return -EINVAL; 1275 } 1276 } 1277 1278 case VIDIOC_G_STD: 1279 *(v4l2_std_id *)arg = saa711x_get_v4lstd(client); 1280 break; 1281 1282 case VIDIOC_S_STD: 1283 state->radio = 0; 1284 saa711x_set_v4lstd(client, *(v4l2_std_id *)arg); 1285 break; 1286 1287 case AUDC_SET_RADIO: 1288 state->radio = 1; 1289 break; 1290 1291 case VIDIOC_INT_G_VIDEO_ROUTING: 1292 { 1293 struct v4l2_routing *route = arg; 1294 1295 route->input = state->input; 1296 route->output = state->output; 1297 break; 1298 } 1299 1300 case VIDIOC_INT_S_VIDEO_ROUTING: 1301 { 1302 struct v4l2_routing *route = arg; 1303 1304 v4l_dbg(1, debug, client, "decoder set input %d output %d\n", route->input, route->output); 1305 /* saa7113 does not have these inputs */ 1306 if (state->ident == V4L2_IDENT_SAA7113 && 1307 (route->input == SAA7115_COMPOSITE4 || 1308 route->input == SAA7115_COMPOSITE5)) { 1309 return -EINVAL; 1310 } 1311 if (route->input > SAA7115_SVIDEO3) 1312 return -EINVAL; 1313 if (route->output > SAA7115_IPORT_ON) 1314 return -EINVAL; 1315 if (state->input == route->input && state->output == route->output) 1316 break; 1317 v4l_dbg(1, debug, client, "now setting %s input %s output\n", 1318 (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite", (route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off"); 1319 state->input = route->input; 1320 1321 /* select mode */ 1322 saa711x_write(client, R_02_INPUT_CNTL_1, 1323 (saa711x_read(client, R_02_INPUT_CNTL_1) & 0xf0) | 1324 state->input); 1325 1326 /* bypass chrominance trap for S-Video modes */ 1327 saa711x_write(client, R_09_LUMA_CNTL, 1328 (saa711x_read(client, R_09_LUMA_CNTL) & 0x7f) | 1329 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0)); 1330 1331 state->output = route->output; 1332 if (state->ident == V4L2_IDENT_SAA7114 || 1333 state->ident == V4L2_IDENT_SAA7115) { 1334 saa711x_write(client, R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 1335 (saa711x_read(client, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) | 1336 (state->output & 0x01)); 1337 } 1338 break; 1339 } 1340 1341 case VIDIOC_STREAMON: 1342 case VIDIOC_STREAMOFF: 1343 v4l_dbg(1, debug, client, "%s output\n", 1344 (cmd == VIDIOC_STREAMON) ? "enable" : "disable"); 1345 1346 if (state->enable != (cmd == VIDIOC_STREAMON)) { 1347 state->enable = (cmd == VIDIOC_STREAMON); 1348 saa711x_write(client, 1349 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 1350 state->enable); 1351 } 1352 break; 1353 1354 case VIDIOC_INT_S_CRYSTAL_FREQ: 1355 { 1356 struct v4l2_crystal_freq *freq = arg; 1357 1358 if (freq->freq != SAA7115_FREQ_32_11_MHZ && 1359 freq->freq != SAA7115_FREQ_24_576_MHZ) 1360 return -EINVAL; 1361 state->crystal_freq = freq->freq; 1362 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4; 1363 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0; 1364 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0; 1365 saa711x_set_audio_clock_freq(client, state->audclk_freq); 1366 break; 1367 } 1368 1369 case VIDIOC_INT_DECODE_VBI_LINE: 1370 saa711x_decode_vbi_line(client, arg); 1371 break; 1372 1373 case VIDIOC_INT_RESET: 1374 v4l_dbg(1, debug, client, "decoder RESET\n"); 1375 saa711x_writeregs(client, saa7115_cfg_reset_scaler); 1376 break; 1377 1378 case VIDIOC_INT_G_VBI_DATA: 1379 { 1380 struct v4l2_sliced_vbi_data *data = arg; 1381 1382 /* Note: the internal field ID is inverted for NTSC, 1383 so data->field 0 maps to the saa7115 even field, 1384 whereas for PAL it maps to the saa7115 odd field. */ 1385 switch (data->id) { 1386 case V4L2_SLICED_WSS_625: 1387 if (saa711x_read(client, 0x6b) & 0xc0) 1388 return -EIO; 1389 data->data[0] = saa711x_read(client, 0x6c); 1390 data->data[1] = saa711x_read(client, 0x6d); 1391 return 0; 1392 case V4L2_SLICED_CAPTION_525: 1393 if (data->field == 0) { 1394 /* CC */ 1395 if (saa711x_read(client, 0x66) & 0x30) 1396 return -EIO; 1397 data->data[0] = saa711x_read(client, 0x69); 1398 data->data[1] = saa711x_read(client, 0x6a); 1399 return 0; 1400 } 1401 /* XDS */ 1402 if (saa711x_read(client, 0x66) & 0xc0) 1403 return -EIO; 1404 data->data[0] = saa711x_read(client, 0x67); 1405 data->data[1] = saa711x_read(client, 0x68); 1406 return 0; 1407 default: 1408 return -EINVAL; 1409 } 1410 break; 1411 } 1412 1413#ifdef CONFIG_VIDEO_ADV_DEBUG 1414 case VIDIOC_DBG_G_REGISTER: 1415 case VIDIOC_DBG_S_REGISTER: 1416 { 1417 struct v4l2_register *reg = arg; 1418 1419 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) 1420 return -EINVAL; 1421 if (!capable(CAP_SYS_ADMIN)) 1422 return -EPERM; 1423 if (cmd == VIDIOC_DBG_G_REGISTER) 1424 reg->val = saa711x_read(client, reg->reg & 0xff); 1425 else 1426 saa711x_write(client, reg->reg & 0xff, reg->val & 0xff); 1427 break; 1428 } 1429#endif 1430 1431 case VIDIOC_G_CHIP_IDENT: 1432 return v4l2_chip_ident_i2c_client(client, arg, state->ident, 0); 1433 1434 default: 1435 return -EINVAL; 1436 } 1437 1438 return 0; 1439} 1440 1441/* ----------------------------------------------------------------------- */ 1442 1443static struct i2c_driver i2c_driver_saa711x; 1444 1445static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind) 1446{ 1447 struct i2c_client *client; 1448 struct saa711x_state *state; 1449 int i; 1450 char name[17]; 1451 u8 chip_id; 1452 1453 /* Check if the adapter supports the needed features */ 1454 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1455 return 0; 1456 1457 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 1458 if (client == 0) 1459 return -ENOMEM; 1460 client->addr = address; 1461 client->adapter = adapter; 1462 client->driver = &i2c_driver_saa711x; 1463 snprintf(client->name, sizeof(client->name) - 1, "saa7115"); 1464 1465 for (i = 0; i < 0x0f; i++) { 1466 saa711x_write(client, 0, i); 1467 name[i] = (saa711x_read(client, 0) & 0x0f) + '0'; 1468 if (name[i] > '9') 1469 name[i] += 'a' - '9' - 1; 1470 } 1471 name[i] = '\0'; 1472 1473 saa711x_write(client, 0, 5); 1474 chip_id = saa711x_read(client, 0) & 0x0f; 1475 1476 /* Check whether this chip is part of the saa711x series */ 1477 if (memcmp(name, "1f711", 5)) { 1478 v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n", 1479 address << 1, name); 1480 kfree(client); 1481 return 0; 1482 } 1483 1484 snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id); 1485 v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, address << 1, adapter->name); 1486 1487 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL); 1488 i2c_set_clientdata(client, state); 1489 if (state == NULL) { 1490 kfree(client); 1491 return -ENOMEM; 1492 } 1493 state->input = -1; 1494 state->output = SAA7115_IPORT_ON; 1495 state->enable = 1; 1496 state->radio = 0; 1497 state->bright = 128; 1498 state->contrast = 64; 1499 state->hue = 0; 1500 state->sat = 64; 1501 switch (chip_id) { 1502 case 1: 1503 state->ident = V4L2_IDENT_SAA7111; 1504 break; 1505 case 3: 1506 state->ident = V4L2_IDENT_SAA7113; 1507 break; 1508 case 4: 1509 state->ident = V4L2_IDENT_SAA7114; 1510 break; 1511 case 5: 1512 state->ident = V4L2_IDENT_SAA7115; 1513 break; 1514 case 8: 1515 state->ident = V4L2_IDENT_SAA7118; 1516 break; 1517 default: 1518 state->ident = V4L2_IDENT_SAA7111; 1519 v4l_info(client, "WARNING: Chip is not known - Falling back to saa7111\n"); 1520 1521 } 1522 1523 state->audclk_freq = 48000; 1524 1525 v4l_dbg(1, debug, client, "writing init values\n"); 1526 1527 /* init to 60hz/48khz */ 1528 state->crystal_freq = SAA7115_FREQ_24_576_MHZ; 1529 switch (state->ident) { 1530 case V4L2_IDENT_SAA7111: 1531 saa711x_writeregs(client, saa7111_init); 1532 break; 1533 case V4L2_IDENT_SAA7113: 1534 saa711x_writeregs(client, saa7113_init); 1535 break; 1536 default: 1537 state->crystal_freq = SAA7115_FREQ_32_11_MHZ; 1538 saa711x_writeregs(client, saa7115_init_auto_input); 1539 } 1540 saa711x_writeregs(client, saa7115_init_misc); 1541 saa711x_set_v4lstd(client, V4L2_STD_NTSC); 1542 1543 i2c_attach_client(client); 1544 1545 v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n", 1546 saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC)); 1547 1548 return 0; 1549} 1550 1551static int saa711x_probe(struct i2c_adapter *adapter) 1552{ 1553 if (adapter->class & I2C_CLASS_TV_ANALOG || adapter->class & I2C_CLASS_TV_DIGITAL) 1554 return i2c_probe(adapter, &addr_data, &saa711x_attach); 1555 return 0; 1556} 1557 1558static int saa711x_detach(struct i2c_client *client) 1559{ 1560 struct saa711x_state *state = i2c_get_clientdata(client); 1561 int err; 1562 1563 err = i2c_detach_client(client); 1564 if (err) { 1565 return err; 1566 } 1567 1568 kfree(state); 1569 kfree(client); 1570 return 0; 1571} 1572 1573/* ----------------------------------------------------------------------- */ 1574 1575/* i2c implementation */ 1576static struct i2c_driver i2c_driver_saa711x = { 1577 .driver = { 1578 .name = "saa7115", 1579 }, 1580 .id = I2C_DRIVERID_SAA711X, 1581 .attach_adapter = saa711x_probe, 1582 .detach_client = saa711x_detach, 1583 .command = saa711x_command, 1584}; 1585 1586 1587static int __init saa711x_init_module(void) 1588{ 1589 return i2c_add_driver(&i2c_driver_saa711x); 1590} 1591 1592static void __exit saa711x_cleanup_module(void) 1593{ 1594 i2c_del_driver(&i2c_driver_saa711x); 1595} 1596 1597module_init(saa711x_init_module); 1598module_exit(saa711x_cleanup_module); 1599