0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include "saa711x_regs.h"
0027
0028 #include <linux/kernel.h>
0029 #include <linux/module.h>
0030 #include <linux/slab.h>
0031 #include <linux/i2c.h>
0032 #include <linux/videodev2.h>
0033 #include <media/v4l2-device.h>
0034 #include <media/v4l2-ctrls.h>
0035 #include <media/v4l2-mc.h>
0036 #include <media/i2c/saa7115.h>
0037 #include <asm/div64.h>
0038
0039 #define VRES_60HZ (480+16)
0040
0041 MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
0042 MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
0043 "Hans Verkuil, Mauro Carvalho Chehab");
0044 MODULE_LICENSE("GPL");
0045
0046 static bool debug;
0047 module_param(debug, bool, 0644);
0048
0049 MODULE_PARM_DESC(debug, "Debug level (0-1)");
0050
0051
0052 enum saa711x_model {
0053 SAA7111A,
0054 SAA7111,
0055 SAA7113,
0056 GM7113C,
0057 SAA7114,
0058 SAA7115,
0059 SAA7118,
0060 };
0061
0062 enum saa711x_pads {
0063 SAA711X_PAD_IF_INPUT,
0064 SAA711X_PAD_VID_OUT,
0065 SAA711X_NUM_PADS
0066 };
0067
0068 struct saa711x_state {
0069 struct v4l2_subdev sd;
0070 #ifdef CONFIG_MEDIA_CONTROLLER
0071 struct media_pad pads[SAA711X_NUM_PADS];
0072 #endif
0073 struct v4l2_ctrl_handler hdl;
0074
0075 struct {
0076
0077 struct v4l2_ctrl *agc;
0078 struct v4l2_ctrl *gain;
0079 };
0080
0081 v4l2_std_id std;
0082 int input;
0083 int output;
0084 int enable;
0085 int radio;
0086 int width;
0087 int height;
0088 enum saa711x_model ident;
0089 u32 audclk_freq;
0090 u32 crystal_freq;
0091 bool ucgc;
0092 u8 cgcdiv;
0093 bool apll;
0094 bool double_asclk;
0095 };
0096
0097 static inline struct saa711x_state *to_state(struct v4l2_subdev *sd)
0098 {
0099 return container_of(sd, struct saa711x_state, sd);
0100 }
0101
0102 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
0103 {
0104 return &container_of(ctrl->handler, struct saa711x_state, hdl)->sd;
0105 }
0106
0107
0108
0109 static inline int saa711x_write(struct v4l2_subdev *sd, u8 reg, u8 value)
0110 {
0111 struct i2c_client *client = v4l2_get_subdevdata(sd);
0112
0113 return i2c_smbus_write_byte_data(client, reg, value);
0114 }
0115
0116
0117 static int saa711x_has_reg(const int id, const u8 reg)
0118 {
0119 if (id == SAA7111)
0120 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
0121 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
0122 if (id == SAA7111A)
0123 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
0124 reg != 0x14 && reg != 0x18 && reg != 0x19 &&
0125 reg != 0x1d && reg != 0x1e;
0126
0127
0128 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
0129 reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
0130 reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
0131 reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
0132 return 0;
0133
0134 switch (id) {
0135 case GM7113C:
0136 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && reg < 0x20;
0137 case SAA7113:
0138 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
0139 reg != 0x5d && reg < 0x63;
0140 case SAA7114:
0141 return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
0142 (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
0143 reg != 0x81 && reg < 0xf0;
0144 case SAA7115:
0145 return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
0146 case SAA7118:
0147 return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
0148 (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
0149 (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
0150 }
0151 return 1;
0152 }
0153
0154 static int saa711x_writeregs(struct v4l2_subdev *sd, const unsigned char *regs)
0155 {
0156 struct saa711x_state *state = to_state(sd);
0157 unsigned char reg, data;
0158
0159 while (*regs != 0x00) {
0160 reg = *(regs++);
0161 data = *(regs++);
0162
0163
0164
0165 if (saa711x_has_reg(state->ident, reg)) {
0166 if (saa711x_write(sd, reg, data) < 0)
0167 return -1;
0168 } else {
0169 v4l2_dbg(1, debug, sd, "tried to access reserved reg 0x%02x\n", reg);
0170 }
0171 }
0172 return 0;
0173 }
0174
0175 static inline int saa711x_read(struct v4l2_subdev *sd, u8 reg)
0176 {
0177 struct i2c_client *client = v4l2_get_subdevdata(sd);
0178
0179 return i2c_smbus_read_byte_data(client, reg);
0180 }
0181
0182
0183
0184
0185 static const unsigned char saa7111_init[] = {
0186 R_01_INC_DELAY, 0x00,
0187
0188
0189 R_02_INPUT_CNTL_1, 0xd0,
0190 R_03_INPUT_CNTL_2, 0x23,
0191
0192 R_04_INPUT_CNTL_3, 0x00,
0193 R_05_INPUT_CNTL_4, 0x00,
0194
0195
0196 R_06_H_SYNC_START, 0xf3,
0197
0198 R_07_H_SYNC_STOP, 0xe8,
0199
0200 R_08_SYNC_CNTL, 0xc8,
0201
0202 R_09_LUMA_CNTL, 0x01,
0203
0204 R_0A_LUMA_BRIGHT_CNTL, 0x80,
0205 R_0B_LUMA_CONTRAST_CNTL, 0x47,
0206 R_0C_CHROMA_SAT_CNTL, 0x40,
0207 R_0D_CHROMA_HUE_CNTL, 0x00,
0208 R_0E_CHROMA_CNTL_1, 0x01,
0209
0210 R_0F_CHROMA_GAIN_CNTL, 0x00,
0211 R_10_CHROMA_CNTL_2, 0x48,
0212 R_11_MODE_DELAY_CNTL, 0x1c,
0213
0214 R_12_RT_SIGNAL_CNTL, 0x00,
0215 R_13_RT_X_PORT_OUT_CNTL, 0x00,
0216 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
0217 R_15_VGATE_START_FID_CHG, 0x00,
0218 R_16_VGATE_STOP, 0x00,
0219 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
0220
0221 0x00, 0x00
0222 };
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 static const unsigned char saa7113_init[] = {
0235 R_01_INC_DELAY, 0x08,
0236 R_02_INPUT_CNTL_1, 0xc2,
0237 R_03_INPUT_CNTL_2, 0x30,
0238 R_04_INPUT_CNTL_3, 0x00,
0239 R_05_INPUT_CNTL_4, 0x00,
0240 R_06_H_SYNC_START, 0x89,
0241
0242 R_07_H_SYNC_STOP, 0x0d,
0243 R_08_SYNC_CNTL, 0x88,
0244
0245 R_09_LUMA_CNTL, 0x01,
0246 R_0A_LUMA_BRIGHT_CNTL, 0x80,
0247 R_0B_LUMA_CONTRAST_CNTL, 0x47,
0248 R_0C_CHROMA_SAT_CNTL, 0x40,
0249 R_0D_CHROMA_HUE_CNTL, 0x00,
0250 R_0E_CHROMA_CNTL_1, 0x01,
0251 R_0F_CHROMA_GAIN_CNTL, 0x2a,
0252 R_10_CHROMA_CNTL_2, 0x08,
0253
0254 R_11_MODE_DELAY_CNTL, 0x0c,
0255 R_12_RT_SIGNAL_CNTL, 0x07,
0256
0257 R_13_RT_X_PORT_OUT_CNTL, 0x00,
0258 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
0259 R_15_VGATE_START_FID_CHG, 0x00,
0260 R_16_VGATE_STOP, 0x00,
0261 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
0262
0263 0x00, 0x00
0264 };
0265
0266
0267
0268
0269
0270
0271
0272 static const unsigned char gm7113c_init[] = {
0273 R_01_INC_DELAY, 0x08,
0274 R_02_INPUT_CNTL_1, 0xc0,
0275 R_03_INPUT_CNTL_2, 0x33,
0276 R_04_INPUT_CNTL_3, 0x00,
0277 R_05_INPUT_CNTL_4, 0x00,
0278 R_06_H_SYNC_START, 0xe9,
0279 R_07_H_SYNC_STOP, 0x0d,
0280 R_08_SYNC_CNTL, 0x98,
0281 R_09_LUMA_CNTL, 0x01,
0282 R_0A_LUMA_BRIGHT_CNTL, 0x80,
0283 R_0B_LUMA_CONTRAST_CNTL, 0x47,
0284 R_0C_CHROMA_SAT_CNTL, 0x40,
0285 R_0D_CHROMA_HUE_CNTL, 0x00,
0286 R_0E_CHROMA_CNTL_1, 0x01,
0287 R_0F_CHROMA_GAIN_CNTL, 0x2a,
0288 R_10_CHROMA_CNTL_2, 0x00,
0289 R_11_MODE_DELAY_CNTL, 0x0c,
0290 R_12_RT_SIGNAL_CNTL, 0x01,
0291 R_13_RT_X_PORT_OUT_CNTL, 0x00,
0292 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
0293 R_15_VGATE_START_FID_CHG, 0x00,
0294 R_16_VGATE_STOP, 0x00,
0295 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
0296
0297 0x00, 0x00
0298 };
0299
0300
0301
0302
0303
0304
0305 static const unsigned char saa7115_init_auto_input[] = {
0306
0307 R_01_INC_DELAY, 0x48,
0308 R_03_INPUT_CNTL_2, 0x20,
0309 R_04_INPUT_CNTL_3, 0x90,
0310 R_05_INPUT_CNTL_4, 0x90,
0311
0312 R_06_H_SYNC_START, 0xeb,
0313 R_07_H_SYNC_STOP, 0xe0,
0314 R_09_LUMA_CNTL, 0x53,
0315 R_0A_LUMA_BRIGHT_CNTL, 0x80,
0316 R_0B_LUMA_CONTRAST_CNTL, 0x44,
0317 R_0C_CHROMA_SAT_CNTL, 0x40,
0318 R_0D_CHROMA_HUE_CNTL, 0x00,
0319 R_0F_CHROMA_GAIN_CNTL, 0x00,
0320 R_10_CHROMA_CNTL_2, 0x06,
0321 R_11_MODE_DELAY_CNTL, 0x00,
0322 R_12_RT_SIGNAL_CNTL, 0x9d,
0323 R_13_RT_X_PORT_OUT_CNTL, 0x80,
0324 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
0325 R_18_RAW_DATA_GAIN_CNTL, 0x40,
0326 R_19_RAW_DATA_OFF_CNTL, 0x80,
0327 R_1A_COLOR_KILL_LVL_CNTL, 0x77,
0328 R_1B_MISC_TVVCRDET, 0x42,
0329 R_1C_ENHAN_COMB_CTRL1, 0xa9,
0330 R_1D_ENHAN_COMB_CTRL2, 0x01,
0331
0332
0333 R_80_GLOBAL_CNTL_1, 0x0,
0334
0335
0336 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
0337 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
0338 0x00, 0x00
0339 };
0340
0341
0342 static const unsigned char saa7115_cfg_reset_scaler[] = {
0343 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00,
0344 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
0345 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
0346 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
0347 0x00, 0x00
0348 };
0349
0350
0351
0352 static const unsigned char saa7115_cfg_60hz_video[] = {
0353 R_80_GLOBAL_CNTL_1, 0x00,
0354 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
0355
0356 R_15_VGATE_START_FID_CHG, 0x03,
0357 R_16_VGATE_STOP, 0x11,
0358 R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
0359
0360 R_08_SYNC_CNTL, 0x68,
0361 R_0E_CHROMA_CNTL_1, 0x07,
0362
0363 R_5A_V_OFF_FOR_SLICER, 0x06,
0364
0365
0366 R_90_A_TASK_HANDLING_CNTL, 0x80,
0367 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
0368 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
0369 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
0370
0371
0372 R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
0373 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
0374
0375
0376 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
0377 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
0378
0379 R_98_A_VERT_INPUT_WINDOW_START, 0x05,
0380 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
0381
0382 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
0383 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
0384
0385 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
0386 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
0387
0388 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
0389 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
0390
0391
0392 R_C0_B_TASK_HANDLING_CNTL, 0x00,
0393 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
0394 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
0395 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
0396
0397
0398 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
0399 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
0400
0401
0402 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
0403 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
0404
0405
0406 R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
0407 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
0408
0409
0410 R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
0411 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
0412
0413
0414 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
0415 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
0416
0417 R_F0_LFCO_PER_LINE, 0xad,
0418 R_F1_P_I_PARAM_SELECT, 0x05,
0419 R_F5_PULSGEN_LINE_LENGTH, 0xad,
0420 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
0421
0422 0x00, 0x00
0423 };
0424
0425 static const unsigned char saa7115_cfg_50hz_video[] = {
0426 R_80_GLOBAL_CNTL_1, 0x00,
0427 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
0428
0429 R_15_VGATE_START_FID_CHG, 0x37,
0430 R_16_VGATE_STOP, 0x16,
0431 R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
0432
0433 R_08_SYNC_CNTL, 0x28,
0434 R_0E_CHROMA_CNTL_1, 0x07,
0435
0436 R_5A_V_OFF_FOR_SLICER, 0x03,
0437
0438
0439 R_90_A_TASK_HANDLING_CNTL, 0x81,
0440 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
0441 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
0442 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
0443
0444
0445
0446
0447 R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
0448 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
0449
0450
0451 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
0452 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
0453
0454 R_98_A_VERT_INPUT_WINDOW_START, 0x03,
0455 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
0456
0457
0458 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
0459 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
0460
0461
0462 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
0463 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
0464 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12,
0465 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
0466
0467
0468 R_C0_B_TASK_HANDLING_CNTL, 0x00,
0469 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
0470 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
0471 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
0472
0473
0474
0475
0476 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
0477 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
0478
0479
0480 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
0481 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
0482
0483
0484 R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
0485 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
0486
0487
0488 R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
0489 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
0490
0491
0492 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
0493 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
0494
0495 R_F0_LFCO_PER_LINE, 0xb0,
0496 R_F1_P_I_PARAM_SELECT, 0x05,
0497 R_F5_PULSGEN_LINE_LENGTH, 0xb0,
0498 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
0499
0500 0x00, 0x00
0501 };
0502
0503
0504
0505 static const unsigned char saa7115_cfg_vbi_on[] = {
0506 R_80_GLOBAL_CNTL_1, 0x00,
0507 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
0508 R_80_GLOBAL_CNTL_1, 0x30,
0509 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
0510 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
0511
0512 0x00, 0x00
0513 };
0514
0515 static const unsigned char saa7115_cfg_vbi_off[] = {
0516 R_80_GLOBAL_CNTL_1, 0x00,
0517 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
0518 R_80_GLOBAL_CNTL_1, 0x20,
0519 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
0520 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
0521
0522 0x00, 0x00
0523 };
0524
0525
0526 static const unsigned char saa7115_init_misc[] = {
0527 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
0528 R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
0529 R_84_I_PORT_SIGNAL_DEF, 0x20,
0530 R_85_I_PORT_SIGNAL_POLAR, 0x21,
0531 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
0532 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
0533
0534
0535 R_A0_A_HORIZ_PRESCALING, 0x01,
0536 R_A1_A_ACCUMULATION_LENGTH, 0x00,
0537 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
0538
0539
0540 R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
0541 R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
0542 R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
0543
0544
0545 R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
0546 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
0547
0548 R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
0549
0550
0551 R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
0552 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
0553
0554
0555 R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
0556
0557 R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
0558 R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
0559
0560 R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
0561 R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
0562
0563 R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
0564
0565 R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
0566 R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
0567 R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
0568 R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
0569
0570 R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
0571 R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
0572 R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
0573 R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
0574
0575
0576 R_D0_B_HORIZ_PRESCALING, 0x01,
0577 R_D1_B_ACCUMULATION_LENGTH, 0x00,
0578 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
0579
0580
0581 R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
0582 R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
0583 R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
0584
0585
0586 R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
0587 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
0588
0589 R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
0590
0591
0592 R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
0593 R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
0594
0595
0596 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
0597
0598 R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
0599 R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
0600
0601 R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
0602 R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
0603
0604 R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
0605
0606 R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
0607 R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
0608 R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
0609 R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
0610
0611 R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
0612 R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
0613 R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
0614 R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
0615
0616 R_F2_NOMINAL_PLL2_DTO, 0x50,
0617 R_F3_PLL_INCREMENT, 0x46,
0618 R_F4_PLL2_STATUS, 0x00,
0619 R_F7_PULSE_A_POS_MSB, 0x4b,
0620 R_F8_PULSE_B_POS, 0x00,
0621 R_F9_PULSE_B_POS_MSB, 0x4b,
0622 R_FA_PULSE_C_POS, 0x00,
0623 R_FB_PULSE_C_POS_MSB, 0x4b,
0624
0625
0626 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
0627
0628
0629 R_40_SLICER_CNTL_1, 0x20,
0630 R_41_LCR_BASE, 0xff,
0631 R_41_LCR_BASE+1, 0xff,
0632 R_41_LCR_BASE+2, 0xff,
0633 R_41_LCR_BASE+3, 0xff,
0634 R_41_LCR_BASE+4, 0xff,
0635 R_41_LCR_BASE+5, 0xff,
0636 R_41_LCR_BASE+6, 0xff,
0637 R_41_LCR_BASE+7, 0xff,
0638 R_41_LCR_BASE+8, 0xff,
0639 R_41_LCR_BASE+9, 0xff,
0640 R_41_LCR_BASE+10, 0xff,
0641 R_41_LCR_BASE+11, 0xff,
0642 R_41_LCR_BASE+12, 0xff,
0643 R_41_LCR_BASE+13, 0xff,
0644 R_41_LCR_BASE+14, 0xff,
0645 R_41_LCR_BASE+15, 0xff,
0646 R_41_LCR_BASE+16, 0xff,
0647 R_41_LCR_BASE+17, 0xff,
0648 R_41_LCR_BASE+18, 0xff,
0649 R_41_LCR_BASE+19, 0xff,
0650 R_41_LCR_BASE+20, 0xff,
0651 R_41_LCR_BASE+21, 0xff,
0652 R_41_LCR_BASE+22, 0xff,
0653 R_58_PROGRAM_FRAMING_CODE, 0x40,
0654 R_59_H_OFF_FOR_SLICER, 0x47,
0655 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
0656 R_5D_DID, 0xbd,
0657 R_5E_SDID, 0x35,
0658
0659 R_02_INPUT_CNTL_1, 0xc4,
0660
0661 R_80_GLOBAL_CNTL_1, 0x20,
0662 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
0663 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
0664 0x00, 0x00
0665 };
0666
0667 static int saa711x_odd_parity(u8 c)
0668 {
0669 c ^= (c >> 4);
0670 c ^= (c >> 2);
0671 c ^= (c >> 1);
0672
0673 return c & 1;
0674 }
0675
0676 static int saa711x_decode_vps(u8 *dst, u8 *p)
0677 {
0678 static const u8 biphase_tbl[] = {
0679 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
0680 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
0681 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
0682 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
0683 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
0684 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
0685 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
0686 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
0687 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
0688 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
0689 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
0690 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
0691 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
0692 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
0693 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
0694 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
0695 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
0696 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
0697 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
0698 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
0699 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
0700 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
0701 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
0702 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
0703 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
0704 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
0705 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
0706 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
0707 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
0708 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
0709 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
0710 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
0711 };
0712 int i;
0713 u8 c, err = 0;
0714
0715 for (i = 0; i < 2 * 13; i += 2) {
0716 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
0717 c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
0718 dst[i / 2] = c;
0719 }
0720 return err & 0xf0;
0721 }
0722
0723 static int saa711x_decode_wss(u8 *p)
0724 {
0725 static const int wss_bits[8] = {
0726 0, 0, 0, 1, 0, 1, 1, 1
0727 };
0728 unsigned char parity;
0729 int wss = 0;
0730 int i;
0731
0732 for (i = 0; i < 16; i++) {
0733 int b1 = wss_bits[p[i] & 7];
0734 int b2 = wss_bits[(p[i] >> 3) & 7];
0735
0736 if (b1 == b2)
0737 return -1;
0738 wss |= b2 << i;
0739 }
0740 parity = wss & 15;
0741 parity ^= parity >> 2;
0742 parity ^= parity >> 1;
0743
0744 if (!(parity & 1))
0745 return -1;
0746
0747 return wss;
0748 }
0749
0750 static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
0751 {
0752 struct saa711x_state *state = to_state(sd);
0753 u32 acpf;
0754 u32 acni;
0755 u32 hz;
0756 u64 f;
0757 u8 acc = 0;
0758
0759
0760 if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
0761 return 0;
0762
0763 v4l2_dbg(1, debug, sd, "set audio clock freq: %d\n", freq);
0764
0765
0766 if (freq < 32000 || freq > 48000)
0767 return -EINVAL;
0768
0769
0770 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
0771
0772 acpf = (25600 * freq) / hz;
0773
0774
0775
0776 f = freq;
0777 f = f << 31;
0778 do_div(f, state->crystal_freq);
0779 acni = f;
0780 if (state->ucgc) {
0781 acpf = acpf * state->cgcdiv / 16;
0782 acni = acni * state->cgcdiv / 16;
0783 acc = 0x80;
0784 if (state->cgcdiv == 3)
0785 acc |= 0x40;
0786 }
0787 if (state->apll)
0788 acc |= 0x08;
0789
0790 if (state->double_asclk) {
0791 acpf <<= 1;
0792 acni <<= 1;
0793 }
0794 saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
0795 saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10 << state->double_asclk);
0796 saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
0797
0798 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
0799 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
0800 (acpf >> 8) & 0xff);
0801 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
0802 (acpf >> 16) & 0x03);
0803
0804 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
0805 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
0806 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
0807 state->audclk_freq = freq;
0808 return 0;
0809 }
0810
0811 static int saa711x_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
0812 {
0813 struct v4l2_subdev *sd = to_sd(ctrl);
0814 struct saa711x_state *state = to_state(sd);
0815
0816 switch (ctrl->id) {
0817 case V4L2_CID_CHROMA_AGC:
0818
0819 if (state->agc->val)
0820 state->gain->val =
0821 saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL) & 0x7f;
0822 break;
0823 }
0824 return 0;
0825 }
0826
0827 static int saa711x_s_ctrl(struct v4l2_ctrl *ctrl)
0828 {
0829 struct v4l2_subdev *sd = to_sd(ctrl);
0830 struct saa711x_state *state = to_state(sd);
0831
0832 switch (ctrl->id) {
0833 case V4L2_CID_BRIGHTNESS:
0834 saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, ctrl->val);
0835 break;
0836
0837 case V4L2_CID_CONTRAST:
0838 saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, ctrl->val);
0839 break;
0840
0841 case V4L2_CID_SATURATION:
0842 saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, ctrl->val);
0843 break;
0844
0845 case V4L2_CID_HUE:
0846 saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, ctrl->val);
0847 break;
0848
0849 case V4L2_CID_CHROMA_AGC:
0850
0851 if (state->agc->val)
0852 saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val);
0853 else
0854 saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val | 0x80);
0855 break;
0856
0857 default:
0858 return -EINVAL;
0859 }
0860
0861 return 0;
0862 }
0863
0864 static int saa711x_set_size(struct v4l2_subdev *sd, int width, int height)
0865 {
0866 struct saa711x_state *state = to_state(sd);
0867 int HPSC, HFSC;
0868 int VSCY;
0869 int res;
0870 int is_50hz = state->std & V4L2_STD_625_50;
0871 int Vsrc = is_50hz ? 576 : 480;
0872
0873 v4l2_dbg(1, debug, sd, "decoder set size to %ix%i\n", width, height);
0874
0875
0876 if ((width < 1) || (width > 1440))
0877 return -EINVAL;
0878 if ((height < 1) || (height > Vsrc))
0879 return -EINVAL;
0880
0881 if (!saa711x_has_reg(state->ident, R_D0_B_HORIZ_PRESCALING)) {
0882
0883 if (width != 720)
0884 return -EINVAL;
0885 if (height != Vsrc)
0886 return -EINVAL;
0887 }
0888
0889 state->width = width;
0890 state->height = height;
0891
0892 if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
0893 return 0;
0894
0895
0896
0897
0898
0899 saa711x_write(sd, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
0900 (u8) (width & 0xff));
0901 saa711x_write(sd, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
0902 (u8) ((width >> 8) & 0xff));
0903
0904
0905 res = height / 2;
0906
0907
0908 if (!is_50hz)
0909 res += (VRES_60HZ - 480) >> 1;
0910
0911
0912 saa711x_write(sd, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
0913 (u8) (res & 0xff));
0914 saa711x_write(sd, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
0915 (u8) ((res >> 8) & 0xff));
0916
0917
0918
0919 HPSC = (int)(720 / width);
0920
0921 HPSC = HPSC ? HPSC : 1;
0922 HFSC = (int)((1024 * 720) / (HPSC * width));
0923
0924
0925 saa711x_write(sd, R_D0_B_HORIZ_PRESCALING,
0926 (u8) (HPSC & 0x3f));
0927
0928 v4l2_dbg(1, debug, sd, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
0929
0930 saa711x_write(sd, R_D8_B_HORIZ_LUMA_SCALING_INC,
0931 (u8) (HFSC & 0xff));
0932 saa711x_write(sd, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
0933 (u8) ((HFSC >> 8) & 0xff));
0934
0935
0936 saa711x_write(sd, R_DC_B_HORIZ_CHROMA_SCALING,
0937 (u8) ((HFSC >> 1) & 0xff));
0938 saa711x_write(sd, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
0939 (u8) ((HFSC >> 9) & 0xff));
0940
0941 VSCY = (int)((1024 * Vsrc) / height);
0942 v4l2_dbg(1, debug, sd, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
0943
0944
0945 saa711x_write(sd, R_D5_B_LUMA_CONTRAST_CNTL,
0946 (u8) (64 * 1024 / VSCY));
0947 saa711x_write(sd, R_D6_B_CHROMA_SATURATION_CNTL,
0948 (u8) (64 * 1024 / VSCY));
0949
0950
0951 saa711x_write(sd, R_E0_B_VERT_LUMA_SCALING_INC,
0952 (u8) (VSCY & 0xff));
0953 saa711x_write(sd, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
0954 (u8) ((VSCY >> 8) & 0xff));
0955
0956 saa711x_write(sd, R_E2_B_VERT_CHROMA_SCALING_INC,
0957 (u8) (VSCY & 0xff));
0958 saa711x_write(sd, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
0959 (u8) ((VSCY >> 8) & 0xff));
0960
0961 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
0962
0963
0964 saa711x_write(sd, R_80_GLOBAL_CNTL_1,
0965 saa711x_read(sd, R_80_GLOBAL_CNTL_1) | 0x20);
0966
0967 return 0;
0968 }
0969
0970 static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
0971 {
0972 struct saa711x_state *state = to_state(sd);
0973
0974
0975
0976
0977
0978
0979
0980
0981 if (std == state->std)
0982 return;
0983
0984 state->std = std;
0985
0986
0987 if (std & V4L2_STD_525_60) {
0988 v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
0989 if (state->ident == GM7113C) {
0990 u8 reg = saa711x_read(sd, R_08_SYNC_CNTL);
0991 reg &= ~(SAA7113_R_08_FSEL | SAA7113_R_08_AUFD);
0992 reg |= SAA7113_R_08_FSEL;
0993 saa711x_write(sd, R_08_SYNC_CNTL, reg);
0994 } else {
0995 saa711x_writeregs(sd, saa7115_cfg_60hz_video);
0996 }
0997 saa711x_set_size(sd, 720, 480);
0998 } else {
0999 v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
1000 if (state->ident == GM7113C) {
1001 u8 reg = saa711x_read(sd, R_08_SYNC_CNTL);
1002 reg &= ~(SAA7113_R_08_FSEL | SAA7113_R_08_AUFD);
1003 saa711x_write(sd, R_08_SYNC_CNTL, reg);
1004 } else {
1005 saa711x_writeregs(sd, saa7115_cfg_50hz_video);
1006 }
1007 saa711x_set_size(sd, 720, 576);
1008 }
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019 if (state->ident <= SAA7113 ||
1020 state->ident == GM7113C) {
1021 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
1022
1023 if (std == V4L2_STD_PAL_M) {
1024 reg |= 0x30;
1025 } else if (std == V4L2_STD_PAL_Nc) {
1026 reg |= 0x20;
1027 } else if (std == V4L2_STD_PAL_60) {
1028 reg |= 0x10;
1029 } else if (std == V4L2_STD_NTSC_M_JP) {
1030 reg |= 0x40;
1031 } else if (std & V4L2_STD_SECAM) {
1032 reg |= 0x50;
1033 }
1034 saa711x_write(sd, R_0E_CHROMA_CNTL_1, reg);
1035 } else {
1036
1037 int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
1038
1039 if (taskb && state->ident == SAA7114)
1040 saa711x_writeregs(sd, saa7115_cfg_vbi_on);
1041
1042
1043 saa711x_s_clock_freq(sd, state->audclk_freq);
1044 }
1045 }
1046
1047
1048 static void saa711x_set_lcr(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
1049 {
1050 struct saa711x_state *state = to_state(sd);
1051 int is_50hz = (state->std & V4L2_STD_625_50);
1052 u8 lcr[24];
1053 int i, x;
1054
1055 #if 1
1056
1057 if (!saa711x_has_reg(state->ident, R_41_LCR_BASE))
1058 return;
1059
1060 #else
1061
1062 if (state->ident != SAA7115)
1063 return;
1064 #endif
1065
1066 for (i = 0; i <= 23; i++)
1067 lcr[i] = 0xff;
1068
1069 if (fmt == NULL) {
1070
1071 if (is_50hz)
1072 for (i = 6; i <= 23; i++)
1073 lcr[i] = 0xdd;
1074 else
1075 for (i = 10; i <= 21; i++)
1076 lcr[i] = 0xdd;
1077 } else {
1078
1079
1080 if (is_50hz) {
1081 for (i = 0; i <= 5; i++)
1082 fmt->service_lines[0][i] =
1083 fmt->service_lines[1][i] = 0;
1084 }
1085 else {
1086 for (i = 0; i <= 9; i++)
1087 fmt->service_lines[0][i] =
1088 fmt->service_lines[1][i] = 0;
1089 for (i = 22; i <= 23; i++)
1090 fmt->service_lines[0][i] =
1091 fmt->service_lines[1][i] = 0;
1092 }
1093
1094
1095 for (i = 6; i <= 23; i++) {
1096 lcr[i] = 0;
1097 for (x = 0; x <= 1; x++) {
1098 switch (fmt->service_lines[1-x][i]) {
1099 case 0:
1100 lcr[i] |= 0xf << (4 * x);
1101 break;
1102 case V4L2_SLICED_TELETEXT_B:
1103 lcr[i] |= 1 << (4 * x);
1104 break;
1105 case V4L2_SLICED_CAPTION_525:
1106 lcr[i] |= 4 << (4 * x);
1107 break;
1108 case V4L2_SLICED_WSS_625:
1109 lcr[i] |= 5 << (4 * x);
1110 break;
1111 case V4L2_SLICED_VPS:
1112 lcr[i] |= 7 << (4 * x);
1113 break;
1114 }
1115 }
1116 }
1117 }
1118
1119
1120 for (i = 2; i <= 23; i++) {
1121 saa711x_write(sd, i - 2 + R_41_LCR_BASE, lcr[i]);
1122 }
1123
1124
1125 saa711x_writeregs(sd, fmt == NULL ?
1126 saa7115_cfg_vbi_on :
1127 saa7115_cfg_vbi_off);
1128 }
1129
1130 static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *sliced)
1131 {
1132 static const u16 lcr2vbi[] = {
1133 0, V4L2_SLICED_TELETEXT_B, 0,
1134 0, V4L2_SLICED_CAPTION_525,
1135 V4L2_SLICED_WSS_625, 0,
1136 V4L2_SLICED_VPS, 0, 0, 0, 0,
1137 0, 0, 0, 0
1138 };
1139 int i;
1140
1141 memset(sliced->service_lines, 0, sizeof(sliced->service_lines));
1142 sliced->service_set = 0;
1143
1144 if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
1145 return 0;
1146 for (i = 2; i <= 23; i++) {
1147 u8 v = saa711x_read(sd, i - 2 + R_41_LCR_BASE);
1148
1149 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
1150 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
1151 sliced->service_set |=
1152 sliced->service_lines[0][i] | sliced->service_lines[1][i];
1153 }
1154 return 0;
1155 }
1156
1157 static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
1158 {
1159 saa711x_set_lcr(sd, NULL);
1160 return 0;
1161 }
1162
1163 static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
1164 {
1165 saa711x_set_lcr(sd, fmt);
1166 return 0;
1167 }
1168
1169 static int saa711x_set_fmt(struct v4l2_subdev *sd,
1170 struct v4l2_subdev_state *sd_state,
1171 struct v4l2_subdev_format *format)
1172 {
1173 struct v4l2_mbus_framefmt *fmt = &format->format;
1174
1175 if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED)
1176 return -EINVAL;
1177 fmt->field = V4L2_FIELD_INTERLACED;
1178 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
1179 if (format->which == V4L2_SUBDEV_FORMAT_TRY)
1180 return 0;
1181 return saa711x_set_size(sd, fmt->width, fmt->height);
1182 }
1183
1184
1185
1186
1187
1188
1189
1190 static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
1191 {
1192 struct saa711x_state *state = to_state(sd);
1193 static const char vbi_no_data_pattern[] = {
1194 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1195 };
1196 u8 *p = vbi->p;
1197 u32 wss;
1198 int id1, id2;
1199
1200 vbi->type = 0;
1201 id1 = p[2];
1202 id2 = p[3];
1203
1204 if (state->std & V4L2_STD_525_60)
1205 id1 ^= 0x40;
1206
1207
1208 p += 4;
1209 vbi->p = p;
1210
1211
1212 vbi->is_second_field = ((id1 & 0x40) != 0);
1213 vbi->line = (id1 & 0x3f) << 3;
1214 vbi->line |= (id2 & 0x70) >> 4;
1215
1216
1217 id2 &= 0xf;
1218
1219
1220
1221 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
1222 return 0;
1223
1224
1225 switch (id2) {
1226 case 1:
1227 vbi->type = V4L2_SLICED_TELETEXT_B;
1228 break;
1229 case 4:
1230 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1231 return 0;
1232 vbi->type = V4L2_SLICED_CAPTION_525;
1233 break;
1234 case 5:
1235 wss = saa711x_decode_wss(p);
1236 if (wss == -1)
1237 return 0;
1238 p[0] = wss & 0xff;
1239 p[1] = wss >> 8;
1240 vbi->type = V4L2_SLICED_WSS_625;
1241 break;
1242 case 7:
1243 if (saa711x_decode_vps(p, p) != 0)
1244 return 0;
1245 vbi->type = V4L2_SLICED_VPS;
1246 break;
1247 default:
1248 break;
1249 }
1250 return 0;
1251 }
1252
1253
1254
1255 static int saa711x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1256 {
1257 struct saa711x_state *state = to_state(sd);
1258 int status;
1259
1260 if (state->radio)
1261 return 0;
1262 status = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1263
1264 v4l2_dbg(1, debug, sd, "status: 0x%02x\n", status);
1265 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1266 return 0;
1267 }
1268
1269 static int saa711x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1270 {
1271 struct saa711x_state *state = to_state(sd);
1272
1273 state->radio = 0;
1274 saa711x_set_v4lstd(sd, std);
1275 return 0;
1276 }
1277
1278 static int saa711x_s_radio(struct v4l2_subdev *sd)
1279 {
1280 struct saa711x_state *state = to_state(sd);
1281
1282 state->radio = 1;
1283 return 0;
1284 }
1285
1286 static int saa711x_s_routing(struct v4l2_subdev *sd,
1287 u32 input, u32 output, u32 config)
1288 {
1289 struct saa711x_state *state = to_state(sd);
1290 u8 mask = (state->ident <= SAA7111A) ? 0xf8 : 0xf0;
1291
1292 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
1293 input, output);
1294
1295
1296 if ((state->ident <= SAA7113 ||
1297 state->ident == GM7113C) &&
1298 (input == SAA7115_COMPOSITE4 ||
1299 input == SAA7115_COMPOSITE5)) {
1300 return -EINVAL;
1301 }
1302 if (input > SAA7115_SVIDEO3)
1303 return -EINVAL;
1304 if (state->input == input && state->output == output)
1305 return 0;
1306 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
1307 (input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
1308 (output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
1309 state->input = input;
1310
1311
1312 if (state->ident <= SAA7111A) {
1313 if (input >= SAA7115_COMPOSITE4)
1314 input -= 2;
1315
1316 saa711x_write(sd, R_10_CHROMA_CNTL_2,
1317 (saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
1318 ((output & 0xc0) ^ 0x40));
1319 saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
1320 (saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
1321 ((output & 2) ? 0x0a : 0));
1322 }
1323
1324
1325 saa711x_write(sd, R_02_INPUT_CNTL_1,
1326 (saa711x_read(sd, R_02_INPUT_CNTL_1) & mask) |
1327 input);
1328
1329
1330 saa711x_write(sd, R_09_LUMA_CNTL,
1331 (saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
1332 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1333
1334 state->output = output;
1335 if (state->ident == SAA7114 ||
1336 state->ident == SAA7115) {
1337 saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
1338 (saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
1339 (state->output & 0x01));
1340 }
1341 if (state->ident > SAA7111A) {
1342 if (config & SAA7115_IDQ_IS_DEFAULT)
1343 saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x20);
1344 else
1345 saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x21);
1346 }
1347 return 0;
1348 }
1349
1350 static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
1351 {
1352 struct saa711x_state *state = to_state(sd);
1353
1354 if (state->ident > SAA7111A)
1355 return -EINVAL;
1356 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
1357 (val ? 0x80 : 0));
1358 return 0;
1359 }
1360
1361 static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
1362 {
1363 struct saa711x_state *state = to_state(sd);
1364
1365 v4l2_dbg(1, debug, sd, "%s output\n",
1366 enable ? "enable" : "disable");
1367
1368 if (state->enable == enable)
1369 return 0;
1370 state->enable = enable;
1371 if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED))
1372 return 0;
1373 saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable);
1374 return 0;
1375 }
1376
1377 static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, u32 freq, u32 flags)
1378 {
1379 struct saa711x_state *state = to_state(sd);
1380
1381 if (freq != SAA7115_FREQ_32_11_MHZ && freq != SAA7115_FREQ_24_576_MHZ)
1382 return -EINVAL;
1383 state->crystal_freq = freq;
1384 state->double_asclk = flags & SAA7115_FREQ_FL_DOUBLE_ASCLK;
1385 state->cgcdiv = (flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1386 state->ucgc = flags & SAA7115_FREQ_FL_UCGC;
1387 state->apll = flags & SAA7115_FREQ_FL_APLL;
1388 saa711x_s_clock_freq(sd, state->audclk_freq);
1389 return 0;
1390 }
1391
1392 static int saa711x_reset(struct v4l2_subdev *sd, u32 val)
1393 {
1394 v4l2_dbg(1, debug, sd, "decoder RESET\n");
1395 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
1396 return 0;
1397 }
1398
1399 static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *data)
1400 {
1401
1402
1403
1404 switch (data->id) {
1405 case V4L2_SLICED_WSS_625:
1406 if (saa711x_read(sd, 0x6b) & 0xc0)
1407 return -EIO;
1408 data->data[0] = saa711x_read(sd, 0x6c);
1409 data->data[1] = saa711x_read(sd, 0x6d);
1410 return 0;
1411 case V4L2_SLICED_CAPTION_525:
1412 if (data->field == 0) {
1413
1414 if (saa711x_read(sd, 0x66) & 0x30)
1415 return -EIO;
1416 data->data[0] = saa711x_read(sd, 0x69);
1417 data->data[1] = saa711x_read(sd, 0x6a);
1418 return 0;
1419 }
1420
1421 if (saa711x_read(sd, 0x66) & 0xc0)
1422 return -EIO;
1423 data->data[0] = saa711x_read(sd, 0x67);
1424 data->data[1] = saa711x_read(sd, 0x68);
1425 return 0;
1426 default:
1427 return -EINVAL;
1428 }
1429 }
1430
1431 static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
1432 {
1433 struct saa711x_state *state = to_state(sd);
1434 int reg1f, reg1e;
1435
1436
1437
1438
1439
1440
1441
1442 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1443
1444 if (state->ident == SAA7115) {
1445 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1446
1447 v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e);
1448
1449 switch (reg1e & 0x03) {
1450 case 1:
1451 *std &= V4L2_STD_NTSC;
1452 break;
1453 case 2:
1454
1455
1456
1457
1458
1459 *std &= V4L2_STD_PAL | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc |
1460 V4L2_STD_PAL_M | V4L2_STD_PAL_60;
1461 break;
1462 case 3:
1463 *std &= V4L2_STD_SECAM;
1464 break;
1465 default:
1466 *std = V4L2_STD_UNKNOWN;
1467
1468 break;
1469 }
1470 }
1471
1472 v4l2_dbg(1, debug, sd, "Status byte 2 (0x1f)=0x%02x\n", reg1f);
1473
1474
1475 if (reg1f & 0x40) {
1476 *std = V4L2_STD_UNKNOWN;
1477 goto ret;
1478 }
1479
1480 if (reg1f & 0x20)
1481 *std &= V4L2_STD_525_60;
1482 else
1483 *std &= V4L2_STD_625_50;
1484
1485 ret:
1486 v4l2_dbg(1, debug, sd, "detected std mask = %08Lx\n", *std);
1487
1488 return 0;
1489 }
1490
1491 static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status)
1492 {
1493 struct saa711x_state *state = to_state(sd);
1494 int reg1e = 0x80;
1495 int reg1f;
1496
1497 *status = V4L2_IN_ST_NO_SIGNAL;
1498 if (state->ident == SAA7115)
1499 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1500 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1501 if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
1502 *status = 0;
1503 return 0;
1504 }
1505
1506 #ifdef CONFIG_VIDEO_ADV_DEBUG
1507 static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
1508 {
1509 reg->val = saa711x_read(sd, reg->reg & 0xff);
1510 reg->size = 1;
1511 return 0;
1512 }
1513
1514 static int saa711x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
1515 {
1516 saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
1517 return 0;
1518 }
1519 #endif
1520
1521 static int saa711x_log_status(struct v4l2_subdev *sd)
1522 {
1523 struct saa711x_state *state = to_state(sd);
1524 int reg1e, reg1f;
1525 int signalOk;
1526 int vcr;
1527
1528 v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
1529 if (state->ident != SAA7115) {
1530
1531 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1532 signalOk = (reg1f & 0xc1) == 0x81;
1533 v4l2_info(sd, "Video signal: %s\n", signalOk ? "ok" : "bad");
1534 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1535 return 0;
1536 }
1537
1538
1539 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1540 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1541
1542 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1543 vcr = !(reg1f & 0x10);
1544
1545 if (state->input >= 6)
1546 v4l2_info(sd, "Input: S-Video %d\n", state->input - 6);
1547 else
1548 v4l2_info(sd, "Input: Composite %d\n", state->input);
1549 v4l2_info(sd, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1550 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1551
1552 switch (reg1e & 0x03) {
1553 case 1:
1554 v4l2_info(sd, "Detected format: NTSC\n");
1555 break;
1556 case 2:
1557 v4l2_info(sd, "Detected format: PAL\n");
1558 break;
1559 case 3:
1560 v4l2_info(sd, "Detected format: SECAM\n");
1561 break;
1562 default:
1563 v4l2_info(sd, "Detected format: BW/No color\n");
1564 break;
1565 }
1566 v4l2_info(sd, "Width, Height: %d, %d\n", state->width, state->height);
1567 v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
1568 return 0;
1569 }
1570
1571
1572
1573 static const struct v4l2_ctrl_ops saa711x_ctrl_ops = {
1574 .s_ctrl = saa711x_s_ctrl,
1575 .g_volatile_ctrl = saa711x_g_volatile_ctrl,
1576 };
1577
1578 static const struct v4l2_subdev_core_ops saa711x_core_ops = {
1579 .log_status = saa711x_log_status,
1580 .reset = saa711x_reset,
1581 .s_gpio = saa711x_s_gpio,
1582 #ifdef CONFIG_VIDEO_ADV_DEBUG
1583 .g_register = saa711x_g_register,
1584 .s_register = saa711x_s_register,
1585 #endif
1586 };
1587
1588 static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops = {
1589 .s_radio = saa711x_s_radio,
1590 .g_tuner = saa711x_g_tuner,
1591 };
1592
1593 static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
1594 .s_clock_freq = saa711x_s_clock_freq,
1595 };
1596
1597 static const struct v4l2_subdev_video_ops saa711x_video_ops = {
1598 .s_std = saa711x_s_std,
1599 .s_routing = saa711x_s_routing,
1600 .s_crystal_freq = saa711x_s_crystal_freq,
1601 .s_stream = saa711x_s_stream,
1602 .querystd = saa711x_querystd,
1603 .g_input_status = saa711x_g_input_status,
1604 };
1605
1606 static const struct v4l2_subdev_vbi_ops saa711x_vbi_ops = {
1607 .g_vbi_data = saa711x_g_vbi_data,
1608 .decode_vbi_line = saa711x_decode_vbi_line,
1609 .g_sliced_fmt = saa711x_g_sliced_fmt,
1610 .s_sliced_fmt = saa711x_s_sliced_fmt,
1611 .s_raw_fmt = saa711x_s_raw_fmt,
1612 };
1613
1614 static const struct v4l2_subdev_pad_ops saa711x_pad_ops = {
1615 .set_fmt = saa711x_set_fmt,
1616 };
1617
1618 static const struct v4l2_subdev_ops saa711x_ops = {
1619 .core = &saa711x_core_ops,
1620 .tuner = &saa711x_tuner_ops,
1621 .audio = &saa711x_audio_ops,
1622 .video = &saa711x_video_ops,
1623 .vbi = &saa711x_vbi_ops,
1624 .pad = &saa711x_pad_ops,
1625 };
1626
1627 #define CHIP_VER_SIZE 16
1628
1629
1630
1631 static void saa711x_write_platform_data(struct saa711x_state *state,
1632 struct saa7115_platform_data *data)
1633 {
1634 struct v4l2_subdev *sd = &state->sd;
1635 u8 work;
1636
1637 if (state->ident != GM7113C &&
1638 state->ident != SAA7113)
1639 return;
1640
1641 if (data->saa7113_r08_htc) {
1642 work = saa711x_read(sd, R_08_SYNC_CNTL);
1643 work &= ~SAA7113_R_08_HTC_MASK;
1644 work |= ((*data->saa7113_r08_htc) << SAA7113_R_08_HTC_OFFSET);
1645 saa711x_write(sd, R_08_SYNC_CNTL, work);
1646 }
1647
1648 if (data->saa7113_r10_vrln) {
1649 work = saa711x_read(sd, R_10_CHROMA_CNTL_2);
1650 work &= ~SAA7113_R_10_VRLN_MASK;
1651 if (*data->saa7113_r10_vrln)
1652 work |= (1 << SAA7113_R_10_VRLN_OFFSET);
1653 saa711x_write(sd, R_10_CHROMA_CNTL_2, work);
1654 }
1655
1656 if (data->saa7113_r10_ofts) {
1657 work = saa711x_read(sd, R_10_CHROMA_CNTL_2);
1658 work &= ~SAA7113_R_10_OFTS_MASK;
1659 work |= (*data->saa7113_r10_ofts << SAA7113_R_10_OFTS_OFFSET);
1660 saa711x_write(sd, R_10_CHROMA_CNTL_2, work);
1661 }
1662
1663 if (data->saa7113_r12_rts0) {
1664 work = saa711x_read(sd, R_12_RT_SIGNAL_CNTL);
1665 work &= ~SAA7113_R_12_RTS0_MASK;
1666 work |= (*data->saa7113_r12_rts0 << SAA7113_R_12_RTS0_OFFSET);
1667
1668
1669
1670 WARN_ON(*data->saa7113_r12_rts0 == SAA7113_RTS_DOT_IN);
1671 saa711x_write(sd, R_12_RT_SIGNAL_CNTL, work);
1672 }
1673
1674 if (data->saa7113_r12_rts1) {
1675 work = saa711x_read(sd, R_12_RT_SIGNAL_CNTL);
1676 work &= ~SAA7113_R_12_RTS1_MASK;
1677 work |= (*data->saa7113_r12_rts1 << SAA7113_R_12_RTS1_OFFSET);
1678 saa711x_write(sd, R_12_RT_SIGNAL_CNTL, work);
1679 }
1680
1681 if (data->saa7113_r13_adlsb) {
1682 work = saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL);
1683 work &= ~SAA7113_R_13_ADLSB_MASK;
1684 if (*data->saa7113_r13_adlsb)
1685 work |= (1 << SAA7113_R_13_ADLSB_OFFSET);
1686 saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL, work);
1687 }
1688 }
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704 static int saa711x_detect_chip(struct i2c_client *client,
1705 const struct i2c_device_id *id,
1706 char *name)
1707 {
1708 char chip_ver[CHIP_VER_SIZE];
1709 char chip_id;
1710 int i;
1711 int autodetect;
1712
1713 autodetect = !id || id->driver_data == 1;
1714
1715
1716 for (i = 0; i < CHIP_VER_SIZE; i++) {
1717 i2c_smbus_write_byte_data(client, 0, i);
1718 chip_ver[i] = i2c_smbus_read_byte_data(client, 0);
1719 name[i] = (chip_ver[i] & 0x0f) + '0';
1720 if (name[i] > '9')
1721 name[i] += 'a' - '9' - 1;
1722 }
1723 name[i] = '\0';
1724
1725
1726 if (!memcmp(name + 1, "f711", 4)) {
1727 chip_id = name[5];
1728 snprintf(name, CHIP_VER_SIZE, "saa711%c", chip_id);
1729
1730 if (!autodetect && strcmp(name, id->name))
1731 return -EINVAL;
1732
1733 switch (chip_id) {
1734 case '1':
1735 if (chip_ver[0] & 0xf0) {
1736 snprintf(name, CHIP_VER_SIZE, "saa711%ca", chip_id);
1737 v4l_info(client, "saa7111a variant found\n");
1738 return SAA7111A;
1739 }
1740 return SAA7111;
1741 case '3':
1742 return SAA7113;
1743 case '4':
1744 return SAA7114;
1745 case '5':
1746 return SAA7115;
1747 case '8':
1748 return SAA7118;
1749 default:
1750 v4l2_info(client,
1751 "WARNING: Philips/NXP chip unknown - Falling back to saa7111\n");
1752 return SAA7111;
1753 }
1754 }
1755
1756
1757 if (!memcmp(name, "0000", 4)) {
1758 chip_id = 0;
1759 for (i = 0; i < 4; i++) {
1760 chip_id = chip_id << 1;
1761 chip_id |= (chip_ver[i] & 0x80) ? 1 : 0;
1762 }
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774 strscpy(name, "gm7113c", CHIP_VER_SIZE);
1775
1776 if (!autodetect && strcmp(name, id->name))
1777 return -EINVAL;
1778
1779 v4l_dbg(1, debug, client,
1780 "It seems to be a %s chip (%*ph) @ 0x%x.\n",
1781 name, 16, chip_ver, client->addr << 1);
1782
1783 return GM7113C;
1784 }
1785
1786
1787 if (!memcmp(name, "1111111111111111", CHIP_VER_SIZE)) {
1788 strscpy(name, "cjc7113", CHIP_VER_SIZE);
1789
1790 if (!autodetect && strcmp(name, id->name))
1791 return -EINVAL;
1792
1793 v4l_dbg(1, debug, client,
1794 "It seems to be a %s chip (%*ph) @ 0x%x.\n",
1795 name, 16, chip_ver, client->addr << 1);
1796
1797
1798 return SAA7113;
1799 }
1800
1801
1802 v4l_dbg(1, debug, client, "chip %*ph @ 0x%x is unknown.\n",
1803 16, chip_ver, client->addr << 1);
1804 return -ENODEV;
1805 }
1806
1807 static int saa711x_probe(struct i2c_client *client,
1808 const struct i2c_device_id *id)
1809 {
1810 struct saa711x_state *state;
1811 struct v4l2_subdev *sd;
1812 struct v4l2_ctrl_handler *hdl;
1813 struct saa7115_platform_data *pdata;
1814 int ident;
1815 char name[CHIP_VER_SIZE + 1];
1816 #if defined(CONFIG_MEDIA_CONTROLLER)
1817 int ret;
1818 #endif
1819
1820
1821 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1822 return -EIO;
1823
1824 ident = saa711x_detect_chip(client, id, name);
1825 if (ident == -EINVAL) {
1826
1827 v4l_warn(client, "found %s while %s was expected\n",
1828 name, id->name);
1829 return -ENODEV;
1830 }
1831 if (ident < 0)
1832 return ident;
1833
1834 strscpy(client->name, name, sizeof(client->name));
1835
1836 state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
1837 if (state == NULL)
1838 return -ENOMEM;
1839 sd = &state->sd;
1840 v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
1841
1842 #if defined(CONFIG_MEDIA_CONTROLLER)
1843 state->pads[SAA711X_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
1844 state->pads[SAA711X_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
1845 state->pads[SAA711X_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
1846 state->pads[SAA711X_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV;
1847
1848 sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
1849
1850 ret = media_entity_pads_init(&sd->entity, SAA711X_NUM_PADS,
1851 state->pads);
1852 if (ret < 0)
1853 return ret;
1854 #endif
1855
1856 v4l_info(client, "%s found @ 0x%x (%s)\n", name,
1857 client->addr << 1, client->adapter->name);
1858 hdl = &state->hdl;
1859 v4l2_ctrl_handler_init(hdl, 6);
1860
1861 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1862 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1863 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1864 V4L2_CID_CONTRAST, 0, 127, 1, 64);
1865 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1866 V4L2_CID_SATURATION, 0, 127, 1, 64);
1867 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1868 V4L2_CID_HUE, -128, 127, 1, 0);
1869 state->agc = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1870 V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
1871 state->gain = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1872 V4L2_CID_CHROMA_GAIN, 0, 127, 1, 40);
1873 sd->ctrl_handler = hdl;
1874 if (hdl->error) {
1875 int err = hdl->error;
1876
1877 v4l2_ctrl_handler_free(hdl);
1878 return err;
1879 }
1880 v4l2_ctrl_auto_cluster(2, &state->agc, 0, true);
1881
1882 state->input = -1;
1883 state->output = SAA7115_IPORT_ON;
1884 state->enable = 1;
1885 state->radio = 0;
1886 state->ident = ident;
1887
1888 state->audclk_freq = 48000;
1889
1890 v4l2_dbg(1, debug, sd, "writing init values\n");
1891
1892
1893 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1894 pdata = client->dev.platform_data;
1895 switch (state->ident) {
1896 case SAA7111:
1897 case SAA7111A:
1898 saa711x_writeregs(sd, saa7111_init);
1899 break;
1900 case GM7113C:
1901 saa711x_writeregs(sd, gm7113c_init);
1902 break;
1903 case SAA7113:
1904 if (pdata && pdata->saa7113_force_gm7113c_init)
1905 saa711x_writeregs(sd, gm7113c_init);
1906 else
1907 saa711x_writeregs(sd, saa7113_init);
1908 break;
1909 default:
1910 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1911 saa711x_writeregs(sd, saa7115_init_auto_input);
1912 }
1913 if (state->ident > SAA7111A && state->ident != GM7113C)
1914 saa711x_writeregs(sd, saa7115_init_misc);
1915
1916 if (pdata)
1917 saa711x_write_platform_data(state, pdata);
1918
1919 saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
1920 v4l2_ctrl_handler_setup(hdl);
1921
1922 v4l2_dbg(1, debug, sd, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1923 saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC),
1924 saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC));
1925 return 0;
1926 }
1927
1928
1929
1930 static int saa711x_remove(struct i2c_client *client)
1931 {
1932 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1933
1934 v4l2_device_unregister_subdev(sd);
1935 v4l2_ctrl_handler_free(sd->ctrl_handler);
1936 return 0;
1937 }
1938
1939 static const struct i2c_device_id saa711x_id[] = {
1940 { "saa7115_auto", 1 },
1941 { "saa7111", 0 },
1942 { "saa7113", 0 },
1943 { "saa7114", 0 },
1944 { "saa7115", 0 },
1945 { "saa7118", 0 },
1946 { "gm7113c", 0 },
1947 { }
1948 };
1949 MODULE_DEVICE_TABLE(i2c, saa711x_id);
1950
1951 static struct i2c_driver saa711x_driver = {
1952 .driver = {
1953 .name = "saa7115",
1954 },
1955 .probe = saa711x_probe,
1956 .remove = saa711x_remove,
1957 .id_table = saa711x_id,
1958 };
1959
1960 module_i2c_driver(saa711x_driver);