1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include "saa711x_regs.h"
37
38#include <linux/kernel.h>
39#include <linux/module.h>
40#include <linux/slab.h>
41#include <linux/i2c.h>
42#include <linux/videodev2.h>
43#include <media/v4l2-device.h>
44#include <media/v4l2-ctrls.h>
45#include <media/v4l2-mc.h>
46#include <media/i2c/saa7115.h>
47#include <asm/div64.h>
48
49#define VRES_60HZ (480+16)
50
51MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
52MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
53 "Hans Verkuil, Mauro Carvalho Chehab");
54MODULE_LICENSE("GPL");
55
56static bool debug;
57module_param(debug, bool, 0644);
58
59MODULE_PARM_DESC(debug, "Debug level (0-1)");
60
61
62enum saa711x_model {
63 SAA7111A,
64 SAA7111,
65 SAA7113,
66 GM7113C,
67 SAA7114,
68 SAA7115,
69 SAA7118,
70};
71
72struct saa711x_state {
73 struct v4l2_subdev sd;
74#ifdef CONFIG_MEDIA_CONTROLLER
75 struct media_pad pads[DEMOD_NUM_PADS];
76#endif
77 struct v4l2_ctrl_handler hdl;
78
79 struct {
80
81 struct v4l2_ctrl *agc;
82 struct v4l2_ctrl *gain;
83 };
84
85 v4l2_std_id std;
86 int input;
87 int output;
88 int enable;
89 int radio;
90 int width;
91 int height;
92 enum saa711x_model ident;
93 u32 audclk_freq;
94 u32 crystal_freq;
95 bool ucgc;
96 u8 cgcdiv;
97 bool apll;
98 bool double_asclk;
99};
100
101static inline struct saa711x_state *to_state(struct v4l2_subdev *sd)
102{
103 return container_of(sd, struct saa711x_state, sd);
104}
105
106static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
107{
108 return &container_of(ctrl->handler, struct saa711x_state, hdl)->sd;
109}
110
111
112
113static inline int saa711x_write(struct v4l2_subdev *sd, u8 reg, u8 value)
114{
115 struct i2c_client *client = v4l2_get_subdevdata(sd);
116
117 return i2c_smbus_write_byte_data(client, reg, value);
118}
119
120
121static int saa711x_has_reg(const int id, const u8 reg)
122{
123 if (id == SAA7111)
124 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
125 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
126 if (id == SAA7111A)
127 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
128 reg != 0x14 && reg != 0x18 && reg != 0x19 &&
129 reg != 0x1d && reg != 0x1e;
130
131
132 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
133 reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
134 reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
135 reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
136 return 0;
137
138 switch (id) {
139 case GM7113C:
140 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && reg < 0x20;
141 case SAA7113:
142 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
143 reg != 0x5d && reg < 0x63;
144 case SAA7114:
145 return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
146 (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
147 reg != 0x81 && reg < 0xf0;
148 case SAA7115:
149 return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
150 case SAA7118:
151 return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
152 (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
153 (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
154 }
155 return 1;
156}
157
158static int saa711x_writeregs(struct v4l2_subdev *sd, const unsigned char *regs)
159{
160 struct saa711x_state *state = to_state(sd);
161 unsigned char reg, data;
162
163 while (*regs != 0x00) {
164 reg = *(regs++);
165 data = *(regs++);
166
167
168
169 if (saa711x_has_reg(state->ident, reg)) {
170 if (saa711x_write(sd, reg, data) < 0)
171 return -1;
172 } else {
173 v4l2_dbg(1, debug, sd, "tried to access reserved reg 0x%02x\n", reg);
174 }
175 }
176 return 0;
177}
178
179static inline int saa711x_read(struct v4l2_subdev *sd, u8 reg)
180{
181 struct i2c_client *client = v4l2_get_subdevdata(sd);
182
183 return i2c_smbus_read_byte_data(client, reg);
184}
185
186
187
188
189static const unsigned char saa7111_init[] = {
190 R_01_INC_DELAY, 0x00,
191
192
193 R_02_INPUT_CNTL_1, 0xd0,
194 R_03_INPUT_CNTL_2, 0x23,
195
196 R_04_INPUT_CNTL_3, 0x00,
197 R_05_INPUT_CNTL_4, 0x00,
198
199
200 R_06_H_SYNC_START, 0xf3,
201
202 R_07_H_SYNC_STOP, 0xe8,
203
204 R_08_SYNC_CNTL, 0xc8,
205
206 R_09_LUMA_CNTL, 0x01,
207
208 R_0A_LUMA_BRIGHT_CNTL, 0x80,
209 R_0B_LUMA_CONTRAST_CNTL, 0x47,
210 R_0C_CHROMA_SAT_CNTL, 0x40,
211 R_0D_CHROMA_HUE_CNTL, 0x00,
212 R_0E_CHROMA_CNTL_1, 0x01,
213
214 R_0F_CHROMA_GAIN_CNTL, 0x00,
215 R_10_CHROMA_CNTL_2, 0x48,
216 R_11_MODE_DELAY_CNTL, 0x1c,
217
218 R_12_RT_SIGNAL_CNTL, 0x00,
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
229
230
231
232
233
234
235
236
237
238static const unsigned char saa7113_init[] = {
239 R_01_INC_DELAY, 0x08,
240 R_02_INPUT_CNTL_1, 0xc2,
241 R_03_INPUT_CNTL_2, 0x30,
242 R_04_INPUT_CNTL_3, 0x00,
243 R_05_INPUT_CNTL_4, 0x00,
244 R_06_H_SYNC_START, 0x89,
245
246 R_07_H_SYNC_STOP, 0x0d,
247 R_08_SYNC_CNTL, 0x88,
248
249 R_09_LUMA_CNTL, 0x01,
250 R_0A_LUMA_BRIGHT_CNTL, 0x80,
251 R_0B_LUMA_CONTRAST_CNTL, 0x47,
252 R_0C_CHROMA_SAT_CNTL, 0x40,
253 R_0D_CHROMA_HUE_CNTL, 0x00,
254 R_0E_CHROMA_CNTL_1, 0x01,
255 R_0F_CHROMA_GAIN_CNTL, 0x2a,
256 R_10_CHROMA_CNTL_2, 0x08,
257
258 R_11_MODE_DELAY_CNTL, 0x0c,
259 R_12_RT_SIGNAL_CNTL, 0x07,
260
261 R_13_RT_X_PORT_OUT_CNTL, 0x00,
262 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
263 R_15_VGATE_START_FID_CHG, 0x00,
264 R_16_VGATE_STOP, 0x00,
265 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
266
267 0x00, 0x00
268};
269
270
271
272
273
274
275
276static const unsigned char gm7113c_init[] = {
277 R_01_INC_DELAY, 0x08,
278 R_02_INPUT_CNTL_1, 0xc0,
279 R_03_INPUT_CNTL_2, 0x33,
280 R_04_INPUT_CNTL_3, 0x00,
281 R_05_INPUT_CNTL_4, 0x00,
282 R_06_H_SYNC_START, 0xe9,
283 R_07_H_SYNC_STOP, 0x0d,
284 R_08_SYNC_CNTL, 0x98,
285 R_09_LUMA_CNTL, 0x01,
286 R_0A_LUMA_BRIGHT_CNTL, 0x80,
287 R_0B_LUMA_CONTRAST_CNTL, 0x47,
288 R_0C_CHROMA_SAT_CNTL, 0x40,
289 R_0D_CHROMA_HUE_CNTL, 0x00,
290 R_0E_CHROMA_CNTL_1, 0x01,
291 R_0F_CHROMA_GAIN_CNTL, 0x2a,
292 R_10_CHROMA_CNTL_2, 0x00,
293 R_11_MODE_DELAY_CNTL, 0x0c,
294 R_12_RT_SIGNAL_CNTL, 0x01,
295 R_13_RT_X_PORT_OUT_CNTL, 0x00,
296 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
297 R_15_VGATE_START_FID_CHG, 0x00,
298 R_16_VGATE_STOP, 0x00,
299 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
300
301 0x00, 0x00
302};
303
304
305
306
307
308
309static const unsigned char saa7115_init_auto_input[] = {
310
311 R_01_INC_DELAY, 0x48,
312 R_03_INPUT_CNTL_2, 0x20,
313 R_04_INPUT_CNTL_3, 0x90,
314 R_05_INPUT_CNTL_4, 0x90,
315
316 R_06_H_SYNC_START, 0xeb,
317 R_07_H_SYNC_STOP, 0xe0,
318 R_09_LUMA_CNTL, 0x53,
319 R_0A_LUMA_BRIGHT_CNTL, 0x80,
320 R_0B_LUMA_CONTRAST_CNTL, 0x44,
321 R_0C_CHROMA_SAT_CNTL, 0x40,
322 R_0D_CHROMA_HUE_CNTL, 0x00,
323 R_0F_CHROMA_GAIN_CNTL, 0x00,
324 R_10_CHROMA_CNTL_2, 0x06,
325 R_11_MODE_DELAY_CNTL, 0x00,
326 R_12_RT_SIGNAL_CNTL, 0x9d,
327 R_13_RT_X_PORT_OUT_CNTL, 0x80,
328 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
329 R_18_RAW_DATA_GAIN_CNTL, 0x40,
330 R_19_RAW_DATA_OFF_CNTL, 0x80,
331 R_1A_COLOR_KILL_LVL_CNTL, 0x77,
332 R_1B_MISC_TVVCRDET, 0x42,
333 R_1C_ENHAN_COMB_CTRL1, 0xa9,
334 R_1D_ENHAN_COMB_CTRL2, 0x01,
335
336
337 R_80_GLOBAL_CNTL_1, 0x0,
338
339
340 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
341 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
342 0x00, 0x00
343};
344
345
346static const unsigned char saa7115_cfg_reset_scaler[] = {
347 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00,
348 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
349 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
350 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
351 0x00, 0x00
352};
353
354
355
356static const unsigned char saa7115_cfg_60hz_video[] = {
357 R_80_GLOBAL_CNTL_1, 0x00,
358 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
359
360 R_15_VGATE_START_FID_CHG, 0x03,
361 R_16_VGATE_STOP, 0x11,
362 R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
363
364 R_08_SYNC_CNTL, 0x68,
365 R_0E_CHROMA_CNTL_1, 0x07,
366
367 R_5A_V_OFF_FOR_SLICER, 0x06,
368
369
370 R_90_A_TASK_HANDLING_CNTL, 0x80,
371 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
372 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
373 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
374
375
376 R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
377 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
378
379
380 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
381 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
382
383 R_98_A_VERT_INPUT_WINDOW_START, 0x05,
384 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
385
386 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
387 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
388
389 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
390 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
391
392 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
393 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
394
395
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
402 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
403 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
404
405
406 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
407 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
408
409
410 R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
411 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
412
413
414 R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
415 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
416
417
418 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
419 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
420
421 R_F0_LFCO_PER_LINE, 0xad,
422 R_F1_P_I_PARAM_SELECT, 0x05,
423 R_F5_PULSGEN_LINE_LENGTH, 0xad,
424 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
425
426 0x00, 0x00
427};
428
429static const unsigned char saa7115_cfg_50hz_video[] = {
430 R_80_GLOBAL_CNTL_1, 0x00,
431 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
432
433 R_15_VGATE_START_FID_CHG, 0x37,
434 R_16_VGATE_STOP, 0x16,
435 R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
436
437 R_08_SYNC_CNTL, 0x28,
438 R_0E_CHROMA_CNTL_1, 0x07,
439
440 R_5A_V_OFF_FOR_SLICER, 0x03,
441
442
443 R_90_A_TASK_HANDLING_CNTL, 0x81,
444 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
445 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
446 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
447
448
449
450
451 R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
452 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
453
454
455 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
456 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
457
458 R_98_A_VERT_INPUT_WINDOW_START, 0x03,
459 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
460
461
462 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
463 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
464
465
466 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
467 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
468 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12,
469 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
470
471
472 R_C0_B_TASK_HANDLING_CNTL, 0x00,
473 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
474 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
475 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
476
477
478
479
480 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
481 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
482
483
484 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
485 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
486
487
488 R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
489 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
490
491
492 R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
493 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
494
495
496 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
497 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
498
499 R_F0_LFCO_PER_LINE, 0xb0,
500 R_F1_P_I_PARAM_SELECT, 0x05,
501 R_F5_PULSGEN_LINE_LENGTH, 0xb0,
502 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
503
504 0x00, 0x00
505};
506
507
508
509static const unsigned char saa7115_cfg_vbi_on[] = {
510 R_80_GLOBAL_CNTL_1, 0x00,
511 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
512 R_80_GLOBAL_CNTL_1, 0x30,
513 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
514 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
515
516 0x00, 0x00
517};
518
519static const unsigned char saa7115_cfg_vbi_off[] = {
520 R_80_GLOBAL_CNTL_1, 0x00,
521 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
522 R_80_GLOBAL_CNTL_1, 0x20,
523 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
524 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
525
526 0x00, 0x00
527};
528
529
530static const unsigned char saa7115_init_misc[] = {
531 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
532 R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
533 R_84_I_PORT_SIGNAL_DEF, 0x20,
534 R_85_I_PORT_SIGNAL_POLAR, 0x21,
535 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
536 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
537
538
539 R_A0_A_HORIZ_PRESCALING, 0x01,
540 R_A1_A_ACCUMULATION_LENGTH, 0x00,
541 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
542
543
544 R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
545 R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
546 R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
547
548
549 R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
550 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
551
552 R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
553
554
555 R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
556 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
557
558
559 R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
560
561 R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
562 R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
563
564 R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
565 R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
566
567 R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
568
569 R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
570 R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
571 R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
572 R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
573
574 R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
575 R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
576 R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
577 R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
578
579
580 R_D0_B_HORIZ_PRESCALING, 0x01,
581 R_D1_B_ACCUMULATION_LENGTH, 0x00,
582 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
583
584
585 R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
586 R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
587 R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
588
589
590 R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
591 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
592
593 R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
594
595
596 R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
597 R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
598
599
600 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
601
602 R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
603 R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
604
605 R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
606 R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
607
608 R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
609
610 R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
611 R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
612 R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
613 R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
614
615 R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
616 R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
617 R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
618 R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
619
620 R_F2_NOMINAL_PLL2_DTO, 0x50,
621 R_F3_PLL_INCREMENT, 0x46,
622 R_F4_PLL2_STATUS, 0x00,
623 R_F7_PULSE_A_POS_MSB, 0x4b,
624 R_F8_PULSE_B_POS, 0x00,
625 R_F9_PULSE_B_POS_MSB, 0x4b,
626 R_FA_PULSE_C_POS, 0x00,
627 R_FB_PULSE_C_POS_MSB, 0x4b,
628
629
630 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
631
632
633 R_40_SLICER_CNTL_1, 0x20,
634 R_41_LCR_BASE, 0xff,
635 R_41_LCR_BASE+1, 0xff,
636 R_41_LCR_BASE+2, 0xff,
637 R_41_LCR_BASE+3, 0xff,
638 R_41_LCR_BASE+4, 0xff,
639 R_41_LCR_BASE+5, 0xff,
640 R_41_LCR_BASE+6, 0xff,
641 R_41_LCR_BASE+7, 0xff,
642 R_41_LCR_BASE+8, 0xff,
643 R_41_LCR_BASE+9, 0xff,
644 R_41_LCR_BASE+10, 0xff,
645 R_41_LCR_BASE+11, 0xff,
646 R_41_LCR_BASE+12, 0xff,
647 R_41_LCR_BASE+13, 0xff,
648 R_41_LCR_BASE+14, 0xff,
649 R_41_LCR_BASE+15, 0xff,
650 R_41_LCR_BASE+16, 0xff,
651 R_41_LCR_BASE+17, 0xff,
652 R_41_LCR_BASE+18, 0xff,
653 R_41_LCR_BASE+19, 0xff,
654 R_41_LCR_BASE+20, 0xff,
655 R_41_LCR_BASE+21, 0xff,
656 R_41_LCR_BASE+22, 0xff,
657 R_58_PROGRAM_FRAMING_CODE, 0x40,
658 R_59_H_OFF_FOR_SLICER, 0x47,
659 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
660 R_5D_DID, 0xbd,
661 R_5E_SDID, 0x35,
662
663 R_02_INPUT_CNTL_1, 0xc4,
664
665 R_80_GLOBAL_CNTL_1, 0x20,
666 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
667 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
668 0x00, 0x00
669};
670
671static int saa711x_odd_parity(u8 c)
672{
673 c ^= (c >> 4);
674 c ^= (c >> 2);
675 c ^= (c >> 1);
676
677 return c & 1;
678}
679
680static int saa711x_decode_vps(u8 *dst, u8 *p)
681{
682 static const u8 biphase_tbl[] = {
683 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
684 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
685 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
686 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
687 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
688 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
689 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
690 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
691 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
692 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
693 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
694 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
695 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
696 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
697 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
698 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
699 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
700 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
701 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
702 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
703 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
704 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
705 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
706 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
707 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
708 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
709 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
710 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
711 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
712 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
713 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
714 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
715 };
716 int i;
717 u8 c, err = 0;
718
719 for (i = 0; i < 2 * 13; i += 2) {
720 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
721 c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
722 dst[i / 2] = c;
723 }
724 return err & 0xf0;
725}
726
727static int saa711x_decode_wss(u8 *p)
728{
729 static const int wss_bits[8] = {
730 0, 0, 0, 1, 0, 1, 1, 1
731 };
732 unsigned char parity;
733 int wss = 0;
734 int i;
735
736 for (i = 0; i < 16; i++) {
737 int b1 = wss_bits[p[i] & 7];
738 int b2 = wss_bits[(p[i] >> 3) & 7];
739
740 if (b1 == b2)
741 return -1;
742 wss |= b2 << i;
743 }
744 parity = wss & 15;
745 parity ^= parity >> 2;
746 parity ^= parity >> 1;
747
748 if (!(parity & 1))
749 return -1;
750
751 return wss;
752}
753
754static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
755{
756 struct saa711x_state *state = to_state(sd);
757 u32 acpf;
758 u32 acni;
759 u32 hz;
760 u64 f;
761 u8 acc = 0;
762
763
764 if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
765 return 0;
766
767 v4l2_dbg(1, debug, sd, "set audio clock freq: %d\n", freq);
768
769
770 if (freq < 32000 || freq > 48000)
771 return -EINVAL;
772
773
774 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
775
776 acpf = (25600 * freq) / hz;
777
778
779
780 f = freq;
781 f = f << 31;
782 do_div(f, state->crystal_freq);
783 acni = f;
784 if (state->ucgc) {
785 acpf = acpf * state->cgcdiv / 16;
786 acni = acni * state->cgcdiv / 16;
787 acc = 0x80;
788 if (state->cgcdiv == 3)
789 acc |= 0x40;
790 }
791 if (state->apll)
792 acc |= 0x08;
793
794 if (state->double_asclk) {
795 acpf <<= 1;
796 acni <<= 1;
797 }
798 saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
799 saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10 << state->double_asclk);
800 saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
801
802 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
803 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
804 (acpf >> 8) & 0xff);
805 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
806 (acpf >> 16) & 0x03);
807
808 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
809 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
810 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
811 state->audclk_freq = freq;
812 return 0;
813}
814
815static int saa711x_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
816{
817 struct v4l2_subdev *sd = to_sd(ctrl);
818 struct saa711x_state *state = to_state(sd);
819
820 switch (ctrl->id) {
821 case V4L2_CID_CHROMA_AGC:
822
823 if (state->agc->val)
824 state->gain->val =
825 saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL) & 0x7f;
826 break;
827 }
828 return 0;
829}
830
831static int saa711x_s_ctrl(struct v4l2_ctrl *ctrl)
832{
833 struct v4l2_subdev *sd = to_sd(ctrl);
834 struct saa711x_state *state = to_state(sd);
835
836 switch (ctrl->id) {
837 case V4L2_CID_BRIGHTNESS:
838 saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, ctrl->val);
839 break;
840
841 case V4L2_CID_CONTRAST:
842 saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, ctrl->val);
843 break;
844
845 case V4L2_CID_SATURATION:
846 saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, ctrl->val);
847 break;
848
849 case V4L2_CID_HUE:
850 saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, ctrl->val);
851 break;
852
853 case V4L2_CID_CHROMA_AGC:
854
855 if (state->agc->val)
856 saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val);
857 else
858 saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val | 0x80);
859 break;
860
861 default:
862 return -EINVAL;
863 }
864
865 return 0;
866}
867
868static int saa711x_set_size(struct v4l2_subdev *sd, int width, int height)
869{
870 struct saa711x_state *state = to_state(sd);
871 int HPSC, HFSC;
872 int VSCY;
873 int res;
874 int is_50hz = state->std & V4L2_STD_625_50;
875 int Vsrc = is_50hz ? 576 : 480;
876
877 v4l2_dbg(1, debug, sd, "decoder set size to %ix%i\n", width, height);
878
879
880 if ((width < 1) || (width > 1440))
881 return -EINVAL;
882 if ((height < 1) || (height > Vsrc))
883 return -EINVAL;
884
885 if (!saa711x_has_reg(state->ident, R_D0_B_HORIZ_PRESCALING)) {
886
887 if (width != 720)
888 return -EINVAL;
889 if (height != Vsrc)
890 return -EINVAL;
891 }
892
893 state->width = width;
894 state->height = height;
895
896 if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
897 return 0;
898
899
900
901
902
903 saa711x_write(sd, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
904 (u8) (width & 0xff));
905 saa711x_write(sd, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
906 (u8) ((width >> 8) & 0xff));
907
908
909 res = height / 2;
910
911
912 if (!is_50hz)
913 res += (VRES_60HZ - 480) >> 1;
914
915
916 saa711x_write(sd, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
917 (u8) (res & 0xff));
918 saa711x_write(sd, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
919 (u8) ((res >> 8) & 0xff));
920
921
922
923 HPSC = (int)(720 / width);
924
925 HPSC = HPSC ? HPSC : 1;
926 HFSC = (int)((1024 * 720) / (HPSC * width));
927
928
929 saa711x_write(sd, R_D0_B_HORIZ_PRESCALING,
930 (u8) (HPSC & 0x3f));
931
932 v4l2_dbg(1, debug, sd, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
933
934 saa711x_write(sd, R_D8_B_HORIZ_LUMA_SCALING_INC,
935 (u8) (HFSC & 0xff));
936 saa711x_write(sd, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
937 (u8) ((HFSC >> 8) & 0xff));
938
939
940 saa711x_write(sd, R_DC_B_HORIZ_CHROMA_SCALING,
941 (u8) ((HFSC >> 1) & 0xff));
942 saa711x_write(sd, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
943 (u8) ((HFSC >> 9) & 0xff));
944
945 VSCY = (int)((1024 * Vsrc) / height);
946 v4l2_dbg(1, debug, sd, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
947
948
949 saa711x_write(sd, R_D5_B_LUMA_CONTRAST_CNTL,
950 (u8) (64 * 1024 / VSCY));
951 saa711x_write(sd, R_D6_B_CHROMA_SATURATION_CNTL,
952 (u8) (64 * 1024 / VSCY));
953
954
955 saa711x_write(sd, R_E0_B_VERT_LUMA_SCALING_INC,
956 (u8) (VSCY & 0xff));
957 saa711x_write(sd, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
958 (u8) ((VSCY >> 8) & 0xff));
959
960 saa711x_write(sd, R_E2_B_VERT_CHROMA_SCALING_INC,
961 (u8) (VSCY & 0xff));
962 saa711x_write(sd, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
963 (u8) ((VSCY >> 8) & 0xff));
964
965 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
966
967
968 saa711x_write(sd, R_80_GLOBAL_CNTL_1,
969 saa711x_read(sd, R_80_GLOBAL_CNTL_1) | 0x20);
970
971 return 0;
972}
973
974static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
975{
976 struct saa711x_state *state = to_state(sd);
977
978
979
980
981
982
983
984
985 if (std == state->std)
986 return;
987
988 state->std = std;
989
990
991 if (std & V4L2_STD_525_60) {
992 v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
993 if (state->ident == GM7113C) {
994 u8 reg = saa711x_read(sd, R_08_SYNC_CNTL);
995 reg &= ~(SAA7113_R_08_FSEL | SAA7113_R_08_AUFD);
996 reg |= SAA7113_R_08_FSEL;
997 saa711x_write(sd, R_08_SYNC_CNTL, reg);
998 } else {
999 saa711x_writeregs(sd, saa7115_cfg_60hz_video);
1000 }
1001 saa711x_set_size(sd, 720, 480);
1002 } else {
1003 v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
1004 if (state->ident == GM7113C) {
1005 u8 reg = saa711x_read(sd, R_08_SYNC_CNTL);
1006 reg &= ~(SAA7113_R_08_FSEL | SAA7113_R_08_AUFD);
1007 saa711x_write(sd, R_08_SYNC_CNTL, reg);
1008 } else {
1009 saa711x_writeregs(sd, saa7115_cfg_50hz_video);
1010 }
1011 saa711x_set_size(sd, 720, 576);
1012 }
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023 if (state->ident <= SAA7113 ||
1024 state->ident == GM7113C) {
1025 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
1026
1027 if (std == V4L2_STD_PAL_M) {
1028 reg |= 0x30;
1029 } else if (std == V4L2_STD_PAL_Nc) {
1030 reg |= 0x20;
1031 } else if (std == V4L2_STD_PAL_60) {
1032 reg |= 0x10;
1033 } else if (std == V4L2_STD_NTSC_M_JP) {
1034 reg |= 0x40;
1035 } else if (std & V4L2_STD_SECAM) {
1036 reg |= 0x50;
1037 }
1038 saa711x_write(sd, R_0E_CHROMA_CNTL_1, reg);
1039 } else {
1040
1041 int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
1042
1043 if (taskb && state->ident == SAA7114)
1044 saa711x_writeregs(sd, saa7115_cfg_vbi_on);
1045
1046
1047 saa711x_s_clock_freq(sd, state->audclk_freq);
1048 }
1049}
1050
1051
1052static void saa711x_set_lcr(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
1053{
1054 struct saa711x_state *state = to_state(sd);
1055 int is_50hz = (state->std & V4L2_STD_625_50);
1056 u8 lcr[24];
1057 int i, x;
1058
1059#if 1
1060
1061 if (!saa711x_has_reg(state->ident, R_41_LCR_BASE))
1062 return;
1063
1064#else
1065
1066 if (state->ident != SAA7115)
1067 return;
1068#endif
1069
1070 for (i = 0; i <= 23; i++)
1071 lcr[i] = 0xff;
1072
1073 if (fmt == NULL) {
1074
1075 if (is_50hz)
1076 for (i = 6; i <= 23; i++)
1077 lcr[i] = 0xdd;
1078 else
1079 for (i = 10; i <= 21; i++)
1080 lcr[i] = 0xdd;
1081 } else {
1082
1083
1084 if (is_50hz) {
1085 for (i = 0; i <= 5; i++)
1086 fmt->service_lines[0][i] =
1087 fmt->service_lines[1][i] = 0;
1088 }
1089 else {
1090 for (i = 0; i <= 9; i++)
1091 fmt->service_lines[0][i] =
1092 fmt->service_lines[1][i] = 0;
1093 for (i = 22; i <= 23; i++)
1094 fmt->service_lines[0][i] =
1095 fmt->service_lines[1][i] = 0;
1096 }
1097
1098
1099 for (i = 6; i <= 23; i++) {
1100 lcr[i] = 0;
1101 for (x = 0; x <= 1; x++) {
1102 switch (fmt->service_lines[1-x][i]) {
1103 case 0:
1104 lcr[i] |= 0xf << (4 * x);
1105 break;
1106 case V4L2_SLICED_TELETEXT_B:
1107 lcr[i] |= 1 << (4 * x);
1108 break;
1109 case V4L2_SLICED_CAPTION_525:
1110 lcr[i] |= 4 << (4 * x);
1111 break;
1112 case V4L2_SLICED_WSS_625:
1113 lcr[i] |= 5 << (4 * x);
1114 break;
1115 case V4L2_SLICED_VPS:
1116 lcr[i] |= 7 << (4 * x);
1117 break;
1118 }
1119 }
1120 }
1121 }
1122
1123
1124 for (i = 2; i <= 23; i++) {
1125 saa711x_write(sd, i - 2 + R_41_LCR_BASE, lcr[i]);
1126 }
1127
1128
1129 saa711x_writeregs(sd, fmt == NULL ?
1130 saa7115_cfg_vbi_on :
1131 saa7115_cfg_vbi_off);
1132}
1133
1134static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *sliced)
1135{
1136 static u16 lcr2vbi[] = {
1137 0, V4L2_SLICED_TELETEXT_B, 0,
1138 0, V4L2_SLICED_CAPTION_525,
1139 V4L2_SLICED_WSS_625, 0,
1140 V4L2_SLICED_VPS, 0, 0, 0, 0,
1141 0, 0, 0, 0
1142 };
1143 int i;
1144
1145 memset(sliced->service_lines, 0, sizeof(sliced->service_lines));
1146 sliced->service_set = 0;
1147
1148 if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
1149 return 0;
1150 for (i = 2; i <= 23; i++) {
1151 u8 v = saa711x_read(sd, i - 2 + R_41_LCR_BASE);
1152
1153 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
1154 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
1155 sliced->service_set |=
1156 sliced->service_lines[0][i] | sliced->service_lines[1][i];
1157 }
1158 return 0;
1159}
1160
1161static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
1162{
1163 saa711x_set_lcr(sd, NULL);
1164 return 0;
1165}
1166
1167static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
1168{
1169 saa711x_set_lcr(sd, fmt);
1170 return 0;
1171}
1172
1173static int saa711x_set_fmt(struct v4l2_subdev *sd,
1174 struct v4l2_subdev_pad_config *cfg,
1175 struct v4l2_subdev_format *format)
1176{
1177 struct v4l2_mbus_framefmt *fmt = &format->format;
1178
1179 if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED)
1180 return -EINVAL;
1181 fmt->field = V4L2_FIELD_INTERLACED;
1182 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
1183 if (format->which == V4L2_SUBDEV_FORMAT_TRY)
1184 return 0;
1185 return saa711x_set_size(sd, fmt->width, fmt->height);
1186}
1187
1188
1189
1190
1191
1192
1193
1194static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
1195{
1196 struct saa711x_state *state = to_state(sd);
1197 static const char vbi_no_data_pattern[] = {
1198 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1199 };
1200 u8 *p = vbi->p;
1201 u32 wss;
1202 int id1, id2;
1203
1204 vbi->type = 0;
1205 id1 = p[2];
1206 id2 = p[3];
1207
1208 if (state->std & V4L2_STD_525_60)
1209 id1 ^= 0x40;
1210
1211
1212 p += 4;
1213 vbi->p = p;
1214
1215
1216 vbi->is_second_field = ((id1 & 0x40) != 0);
1217 vbi->line = (id1 & 0x3f) << 3;
1218 vbi->line |= (id2 & 0x70) >> 4;
1219
1220
1221 id2 &= 0xf;
1222
1223
1224
1225 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
1226 return 0;
1227
1228
1229 switch (id2) {
1230 case 1:
1231 vbi->type = V4L2_SLICED_TELETEXT_B;
1232 break;
1233 case 4:
1234 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1235 return 0;
1236 vbi->type = V4L2_SLICED_CAPTION_525;
1237 break;
1238 case 5:
1239 wss = saa711x_decode_wss(p);
1240 if (wss == -1)
1241 return 0;
1242 p[0] = wss & 0xff;
1243 p[1] = wss >> 8;
1244 vbi->type = V4L2_SLICED_WSS_625;
1245 break;
1246 case 7:
1247 if (saa711x_decode_vps(p, p) != 0)
1248 return 0;
1249 vbi->type = V4L2_SLICED_VPS;
1250 break;
1251 default:
1252 break;
1253 }
1254 return 0;
1255}
1256
1257
1258
1259static int saa711x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1260{
1261 struct saa711x_state *state = to_state(sd);
1262 int status;
1263
1264 if (state->radio)
1265 return 0;
1266 status = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1267
1268 v4l2_dbg(1, debug, sd, "status: 0x%02x\n", status);
1269 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1270 return 0;
1271}
1272
1273static int saa711x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1274{
1275 struct saa711x_state *state = to_state(sd);
1276
1277 state->radio = 0;
1278 saa711x_set_v4lstd(sd, std);
1279 return 0;
1280}
1281
1282static int saa711x_s_radio(struct v4l2_subdev *sd)
1283{
1284 struct saa711x_state *state = to_state(sd);
1285
1286 state->radio = 1;
1287 return 0;
1288}
1289
1290static int saa711x_s_routing(struct v4l2_subdev *sd,
1291 u32 input, u32 output, u32 config)
1292{
1293 struct saa711x_state *state = to_state(sd);
1294 u8 mask = (state->ident <= SAA7111A) ? 0xf8 : 0xf0;
1295
1296 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
1297 input, output);
1298
1299
1300 if ((state->ident <= SAA7113 ||
1301 state->ident == GM7113C) &&
1302 (input == SAA7115_COMPOSITE4 ||
1303 input == SAA7115_COMPOSITE5)) {
1304 return -EINVAL;
1305 }
1306 if (input > SAA7115_SVIDEO3)
1307 return -EINVAL;
1308 if (state->input == input && state->output == output)
1309 return 0;
1310 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
1311 (input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
1312 (output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
1313 state->input = input;
1314
1315
1316 if (state->ident <= SAA7111A) {
1317 if (input >= SAA7115_COMPOSITE4)
1318 input -= 2;
1319
1320 saa711x_write(sd, R_10_CHROMA_CNTL_2,
1321 (saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
1322 ((output & 0xc0) ^ 0x40));
1323 saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
1324 (saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
1325 ((output & 2) ? 0x0a : 0));
1326 }
1327
1328
1329 saa711x_write(sd, R_02_INPUT_CNTL_1,
1330 (saa711x_read(sd, R_02_INPUT_CNTL_1) & mask) |
1331 input);
1332
1333
1334 saa711x_write(sd, R_09_LUMA_CNTL,
1335 (saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
1336 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1337
1338 state->output = output;
1339 if (state->ident == SAA7114 ||
1340 state->ident == SAA7115) {
1341 saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
1342 (saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
1343 (state->output & 0x01));
1344 }
1345 if (state->ident > SAA7111A) {
1346 if (config & SAA7115_IDQ_IS_DEFAULT)
1347 saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x20);
1348 else
1349 saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x21);
1350 }
1351 return 0;
1352}
1353
1354static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
1355{
1356 struct saa711x_state *state = to_state(sd);
1357
1358 if (state->ident > SAA7111A)
1359 return -EINVAL;
1360 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
1361 (val ? 0x80 : 0));
1362 return 0;
1363}
1364
1365static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
1366{
1367 struct saa711x_state *state = to_state(sd);
1368
1369 v4l2_dbg(1, debug, sd, "%s output\n",
1370 enable ? "enable" : "disable");
1371
1372 if (state->enable == enable)
1373 return 0;
1374 state->enable = enable;
1375 if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED))
1376 return 0;
1377 saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable);
1378 return 0;
1379}
1380
1381static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, u32 freq, u32 flags)
1382{
1383 struct saa711x_state *state = to_state(sd);
1384
1385 if (freq != SAA7115_FREQ_32_11_MHZ && freq != SAA7115_FREQ_24_576_MHZ)
1386 return -EINVAL;
1387 state->crystal_freq = freq;
1388 state->double_asclk = flags & SAA7115_FREQ_FL_DOUBLE_ASCLK;
1389 state->cgcdiv = (flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1390 state->ucgc = flags & SAA7115_FREQ_FL_UCGC;
1391 state->apll = flags & SAA7115_FREQ_FL_APLL;
1392 saa711x_s_clock_freq(sd, state->audclk_freq);
1393 return 0;
1394}
1395
1396static int saa711x_reset(struct v4l2_subdev *sd, u32 val)
1397{
1398 v4l2_dbg(1, debug, sd, "decoder RESET\n");
1399 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
1400 return 0;
1401}
1402
1403static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *data)
1404{
1405
1406
1407
1408 switch (data->id) {
1409 case V4L2_SLICED_WSS_625:
1410 if (saa711x_read(sd, 0x6b) & 0xc0)
1411 return -EIO;
1412 data->data[0] = saa711x_read(sd, 0x6c);
1413 data->data[1] = saa711x_read(sd, 0x6d);
1414 return 0;
1415 case V4L2_SLICED_CAPTION_525:
1416 if (data->field == 0) {
1417
1418 if (saa711x_read(sd, 0x66) & 0x30)
1419 return -EIO;
1420 data->data[0] = saa711x_read(sd, 0x69);
1421 data->data[1] = saa711x_read(sd, 0x6a);
1422 return 0;
1423 }
1424
1425 if (saa711x_read(sd, 0x66) & 0xc0)
1426 return -EIO;
1427 data->data[0] = saa711x_read(sd, 0x67);
1428 data->data[1] = saa711x_read(sd, 0x68);
1429 return 0;
1430 default:
1431 return -EINVAL;
1432 }
1433}
1434
1435static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
1436{
1437 struct saa711x_state *state = to_state(sd);
1438 int reg1f, reg1e;
1439
1440
1441
1442
1443
1444
1445
1446 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1447
1448 if (state->ident == SAA7115) {
1449 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1450
1451 v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e);
1452
1453 switch (reg1e & 0x03) {
1454 case 1:
1455 *std &= V4L2_STD_NTSC;
1456 break;
1457 case 2:
1458
1459
1460
1461
1462
1463 *std &= V4L2_STD_PAL | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc |
1464 V4L2_STD_PAL_M | V4L2_STD_PAL_60;
1465 break;
1466 case 3:
1467 *std &= V4L2_STD_SECAM;
1468 break;
1469 default:
1470 *std = V4L2_STD_UNKNOWN;
1471
1472 break;
1473 }
1474 }
1475
1476 v4l2_dbg(1, debug, sd, "Status byte 2 (0x1f)=0x%02x\n", reg1f);
1477
1478
1479 if (reg1f & 0x40) {
1480 *std = V4L2_STD_UNKNOWN;
1481 goto ret;
1482 }
1483
1484 if (reg1f & 0x20)
1485 *std &= V4L2_STD_525_60;
1486 else
1487 *std &= V4L2_STD_625_50;
1488
1489ret:
1490 v4l2_dbg(1, debug, sd, "detected std mask = %08Lx\n", *std);
1491
1492 return 0;
1493}
1494
1495static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status)
1496{
1497 struct saa711x_state *state = to_state(sd);
1498 int reg1e = 0x80;
1499 int reg1f;
1500
1501 *status = V4L2_IN_ST_NO_SIGNAL;
1502 if (state->ident == SAA7115)
1503 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1504 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1505 if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
1506 *status = 0;
1507 return 0;
1508}
1509
1510#ifdef CONFIG_VIDEO_ADV_DEBUG
1511static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
1512{
1513 reg->val = saa711x_read(sd, reg->reg & 0xff);
1514 reg->size = 1;
1515 return 0;
1516}
1517
1518static int saa711x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
1519{
1520 saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
1521 return 0;
1522}
1523#endif
1524
1525static int saa711x_log_status(struct v4l2_subdev *sd)
1526{
1527 struct saa711x_state *state = to_state(sd);
1528 int reg1e, reg1f;
1529 int signalOk;
1530 int vcr;
1531
1532 v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
1533 if (state->ident != SAA7115) {
1534
1535 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1536 signalOk = (reg1f & 0xc1) == 0x81;
1537 v4l2_info(sd, "Video signal: %s\n", signalOk ? "ok" : "bad");
1538 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1539 return 0;
1540 }
1541
1542
1543 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1544 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1545
1546 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1547 vcr = !(reg1f & 0x10);
1548
1549 if (state->input >= 6)
1550 v4l2_info(sd, "Input: S-Video %d\n", state->input - 6);
1551 else
1552 v4l2_info(sd, "Input: Composite %d\n", state->input);
1553 v4l2_info(sd, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1554 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1555
1556 switch (reg1e & 0x03) {
1557 case 1:
1558 v4l2_info(sd, "Detected format: NTSC\n");
1559 break;
1560 case 2:
1561 v4l2_info(sd, "Detected format: PAL\n");
1562 break;
1563 case 3:
1564 v4l2_info(sd, "Detected format: SECAM\n");
1565 break;
1566 default:
1567 v4l2_info(sd, "Detected format: BW/No color\n");
1568 break;
1569 }
1570 v4l2_info(sd, "Width, Height: %d, %d\n", state->width, state->height);
1571 v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
1572 return 0;
1573}
1574
1575
1576
1577static const struct v4l2_ctrl_ops saa711x_ctrl_ops = {
1578 .s_ctrl = saa711x_s_ctrl,
1579 .g_volatile_ctrl = saa711x_g_volatile_ctrl,
1580};
1581
1582static const struct v4l2_subdev_core_ops saa711x_core_ops = {
1583 .log_status = saa711x_log_status,
1584 .reset = saa711x_reset,
1585 .s_gpio = saa711x_s_gpio,
1586#ifdef CONFIG_VIDEO_ADV_DEBUG
1587 .g_register = saa711x_g_register,
1588 .s_register = saa711x_s_register,
1589#endif
1590};
1591
1592static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops = {
1593 .s_radio = saa711x_s_radio,
1594 .g_tuner = saa711x_g_tuner,
1595};
1596
1597static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
1598 .s_clock_freq = saa711x_s_clock_freq,
1599};
1600
1601static const struct v4l2_subdev_video_ops saa711x_video_ops = {
1602 .s_std = saa711x_s_std,
1603 .s_routing = saa711x_s_routing,
1604 .s_crystal_freq = saa711x_s_crystal_freq,
1605 .s_stream = saa711x_s_stream,
1606 .querystd = saa711x_querystd,
1607 .g_input_status = saa711x_g_input_status,
1608};
1609
1610static const struct v4l2_subdev_vbi_ops saa711x_vbi_ops = {
1611 .g_vbi_data = saa711x_g_vbi_data,
1612 .decode_vbi_line = saa711x_decode_vbi_line,
1613 .g_sliced_fmt = saa711x_g_sliced_fmt,
1614 .s_sliced_fmt = saa711x_s_sliced_fmt,
1615 .s_raw_fmt = saa711x_s_raw_fmt,
1616};
1617
1618static const struct v4l2_subdev_pad_ops saa711x_pad_ops = {
1619 .set_fmt = saa711x_set_fmt,
1620};
1621
1622static const struct v4l2_subdev_ops saa711x_ops = {
1623 .core = &saa711x_core_ops,
1624 .tuner = &saa711x_tuner_ops,
1625 .audio = &saa711x_audio_ops,
1626 .video = &saa711x_video_ops,
1627 .vbi = &saa711x_vbi_ops,
1628 .pad = &saa711x_pad_ops,
1629};
1630
1631#define CHIP_VER_SIZE 16
1632
1633
1634
1635static void saa711x_write_platform_data(struct saa711x_state *state,
1636 struct saa7115_platform_data *data)
1637{
1638 struct v4l2_subdev *sd = &state->sd;
1639 u8 work;
1640
1641 if (state->ident != GM7113C &&
1642 state->ident != SAA7113)
1643 return;
1644
1645 if (data->saa7113_r08_htc) {
1646 work = saa711x_read(sd, R_08_SYNC_CNTL);
1647 work &= ~SAA7113_R_08_HTC_MASK;
1648 work |= ((*data->saa7113_r08_htc) << SAA7113_R_08_HTC_OFFSET);
1649 saa711x_write(sd, R_08_SYNC_CNTL, work);
1650 }
1651
1652 if (data->saa7113_r10_vrln) {
1653 work = saa711x_read(sd, R_10_CHROMA_CNTL_2);
1654 work &= ~SAA7113_R_10_VRLN_MASK;
1655 if (*data->saa7113_r10_vrln)
1656 work |= (1 << SAA7113_R_10_VRLN_OFFSET);
1657 saa711x_write(sd, R_10_CHROMA_CNTL_2, work);
1658 }
1659
1660 if (data->saa7113_r10_ofts) {
1661 work = saa711x_read(sd, R_10_CHROMA_CNTL_2);
1662 work &= ~SAA7113_R_10_OFTS_MASK;
1663 work |= (*data->saa7113_r10_ofts << SAA7113_R_10_OFTS_OFFSET);
1664 saa711x_write(sd, R_10_CHROMA_CNTL_2, work);
1665 }
1666
1667 if (data->saa7113_r12_rts0) {
1668 work = saa711x_read(sd, R_12_RT_SIGNAL_CNTL);
1669 work &= ~SAA7113_R_12_RTS0_MASK;
1670 work |= (*data->saa7113_r12_rts0 << SAA7113_R_12_RTS0_OFFSET);
1671
1672
1673
1674 WARN_ON(*data->saa7113_r12_rts0 == SAA7113_RTS_DOT_IN);
1675 saa711x_write(sd, R_12_RT_SIGNAL_CNTL, work);
1676 }
1677
1678 if (data->saa7113_r12_rts1) {
1679 work = saa711x_read(sd, R_12_RT_SIGNAL_CNTL);
1680 work &= ~SAA7113_R_12_RTS1_MASK;
1681 work |= (*data->saa7113_r12_rts1 << SAA7113_R_12_RTS1_OFFSET);
1682 saa711x_write(sd, R_12_RT_SIGNAL_CNTL, work);
1683 }
1684
1685 if (data->saa7113_r13_adlsb) {
1686 work = saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL);
1687 work &= ~SAA7113_R_13_ADLSB_MASK;
1688 if (*data->saa7113_r13_adlsb)
1689 work |= (1 << SAA7113_R_13_ADLSB_OFFSET);
1690 saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL, work);
1691 }
1692}
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708static int saa711x_detect_chip(struct i2c_client *client,
1709 const struct i2c_device_id *id,
1710 char *name)
1711{
1712 char chip_ver[CHIP_VER_SIZE];
1713 char chip_id;
1714 int i;
1715 int autodetect;
1716
1717 autodetect = !id || id->driver_data == 1;
1718
1719
1720 for (i = 0; i < CHIP_VER_SIZE; i++) {
1721 i2c_smbus_write_byte_data(client, 0, i);
1722 chip_ver[i] = i2c_smbus_read_byte_data(client, 0);
1723 name[i] = (chip_ver[i] & 0x0f) + '0';
1724 if (name[i] > '9')
1725 name[i] += 'a' - '9' - 1;
1726 }
1727 name[i] = '\0';
1728
1729
1730 if (!memcmp(name + 1, "f711", 4)) {
1731 chip_id = name[5];
1732 snprintf(name, CHIP_VER_SIZE, "saa711%c", chip_id);
1733
1734 if (!autodetect && strcmp(name, id->name))
1735 return -EINVAL;
1736
1737 switch (chip_id) {
1738 case '1':
1739 if (chip_ver[0] & 0xf0) {
1740 snprintf(name, CHIP_VER_SIZE, "saa711%ca", chip_id);
1741 v4l_info(client, "saa7111a variant found\n");
1742 return SAA7111A;
1743 }
1744 return SAA7111;
1745 case '3':
1746 return SAA7113;
1747 case '4':
1748 return SAA7114;
1749 case '5':
1750 return SAA7115;
1751 case '8':
1752 return SAA7118;
1753 default:
1754 v4l2_info(client,
1755 "WARNING: Philips/NXP chip unknown - Falling back to saa7111\n");
1756 return SAA7111;
1757 }
1758 }
1759
1760
1761 if (!memcmp(name, "0000", 4)) {
1762 chip_id = 0;
1763 for (i = 0; i < 4; i++) {
1764 chip_id = chip_id << 1;
1765 chip_id |= (chip_ver[i] & 0x80) ? 1 : 0;
1766 }
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778 strlcpy(name, "gm7113c", CHIP_VER_SIZE);
1779
1780 if (!autodetect && strcmp(name, id->name))
1781 return -EINVAL;
1782
1783 v4l_dbg(1, debug, client,
1784 "It seems to be a %s chip (%*ph) @ 0x%x.\n",
1785 name, 16, chip_ver, client->addr << 1);
1786
1787 return GM7113C;
1788 }
1789
1790
1791 if (!memcmp(name, "1111111111111111", CHIP_VER_SIZE)) {
1792 strlcpy(name, "cjc7113", CHIP_VER_SIZE);
1793
1794 if (!autodetect && strcmp(name, id->name))
1795 return -EINVAL;
1796
1797 v4l_dbg(1, debug, client,
1798 "It seems to be a %s chip (%*ph) @ 0x%x.\n",
1799 name, 16, chip_ver, client->addr << 1);
1800
1801
1802 return SAA7113;
1803 }
1804
1805
1806 v4l_dbg(1, debug, client, "chip %*ph @ 0x%x is unknown.\n",
1807 16, chip_ver, client->addr << 1);
1808 return -ENODEV;
1809}
1810
1811static int saa711x_probe(struct i2c_client *client,
1812 const struct i2c_device_id *id)
1813{
1814 struct saa711x_state *state;
1815 struct v4l2_subdev *sd;
1816 struct v4l2_ctrl_handler *hdl;
1817 struct saa7115_platform_data *pdata;
1818 int ident;
1819 char name[CHIP_VER_SIZE + 1];
1820#if defined(CONFIG_MEDIA_CONTROLLER)
1821 int ret;
1822#endif
1823
1824
1825 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1826 return -EIO;
1827
1828 ident = saa711x_detect_chip(client, id, name);
1829 if (ident == -EINVAL) {
1830
1831 v4l_warn(client, "found %s while %s was expected\n",
1832 name, id->name);
1833 return -ENODEV;
1834 }
1835 if (ident < 0)
1836 return ident;
1837
1838 strlcpy(client->name, name, sizeof(client->name));
1839
1840 state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
1841 if (state == NULL)
1842 return -ENOMEM;
1843 sd = &state->sd;
1844 v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
1845
1846#if defined(CONFIG_MEDIA_CONTROLLER)
1847 state->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
1848 state->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
1849 state->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
1850
1851 sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
1852
1853 ret = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, state->pads);
1854 if (ret < 0)
1855 return ret;
1856#endif
1857
1858 v4l_info(client, "%s found @ 0x%x (%s)\n", name,
1859 client->addr << 1, client->adapter->name);
1860 hdl = &state->hdl;
1861 v4l2_ctrl_handler_init(hdl, 6);
1862
1863 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1864 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1865 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1866 V4L2_CID_CONTRAST, 0, 127, 1, 64);
1867 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1868 V4L2_CID_SATURATION, 0, 127, 1, 64);
1869 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1870 V4L2_CID_HUE, -128, 127, 1, 0);
1871 state->agc = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1872 V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
1873 state->gain = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1874 V4L2_CID_CHROMA_GAIN, 0, 127, 1, 40);
1875 sd->ctrl_handler = hdl;
1876 if (hdl->error) {
1877 int err = hdl->error;
1878
1879 v4l2_ctrl_handler_free(hdl);
1880 return err;
1881 }
1882 v4l2_ctrl_auto_cluster(2, &state->agc, 0, true);
1883
1884 state->input = -1;
1885 state->output = SAA7115_IPORT_ON;
1886 state->enable = 1;
1887 state->radio = 0;
1888 state->ident = ident;
1889
1890 state->audclk_freq = 48000;
1891
1892 v4l2_dbg(1, debug, sd, "writing init values\n");
1893
1894
1895 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1896 pdata = client->dev.platform_data;
1897 switch (state->ident) {
1898 case SAA7111:
1899 case SAA7111A:
1900 saa711x_writeregs(sd, saa7111_init);
1901 break;
1902 case GM7113C:
1903 saa711x_writeregs(sd, gm7113c_init);
1904 break;
1905 case SAA7113:
1906 if (pdata && pdata->saa7113_force_gm7113c_init)
1907 saa711x_writeregs(sd, gm7113c_init);
1908 else
1909 saa711x_writeregs(sd, saa7113_init);
1910 break;
1911 default:
1912 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1913 saa711x_writeregs(sd, saa7115_init_auto_input);
1914 }
1915 if (state->ident > SAA7111A && state->ident != GM7113C)
1916 saa711x_writeregs(sd, saa7115_init_misc);
1917
1918 if (pdata)
1919 saa711x_write_platform_data(state, pdata);
1920
1921 saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
1922 v4l2_ctrl_handler_setup(hdl);
1923
1924 v4l2_dbg(1, debug, sd, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1925 saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC),
1926 saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC));
1927 return 0;
1928}
1929
1930
1931
1932static int saa711x_remove(struct i2c_client *client)
1933{
1934 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1935
1936 v4l2_device_unregister_subdev(sd);
1937 v4l2_ctrl_handler_free(sd->ctrl_handler);
1938 return 0;
1939}
1940
1941static const struct i2c_device_id saa711x_id[] = {
1942 { "saa7115_auto", 1 },
1943 { "saa7111", 0 },
1944 { "saa7113", 0 },
1945 { "saa7114", 0 },
1946 { "saa7115", 0 },
1947 { "saa7118", 0 },
1948 { "gm7113c", 0 },
1949 { }
1950};
1951MODULE_DEVICE_TABLE(i2c, saa711x_id);
1952
1953static struct i2c_driver saa711x_driver = {
1954 .driver = {
1955 .name = "saa7115",
1956 },
1957 .probe = saa711x_probe,
1958 .remove = saa711x_remove,
1959 .id_table = saa711x_id,
1960};
1961
1962module_i2c_driver(saa711x_driver);
1963