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