xref: /openbmc/linux/drivers/media/i2c/saa717x.c (revision e3d786a3)
1 /*
2  * saa717x - Philips SAA717xHL video decoder driver
3  *
4  * Based on the saa7115 driver
5  *
6  * Changes by Ohta Kyuma <alpha292@bremen.or.jp>
7  *    - Apply to SAA717x,NEC uPD64031,uPD64083. (1/31/2004)
8  *
9  * Changes by T.Adachi (tadachi@tadachi-net.com)
10  *    - support audio, video scaler etc, and checked the initialize sequence.
11  *
12  * Cleaned up by Hans Verkuil <hverkuil@xs4all.nl>
13  *
14  * Note: this is a reversed engineered driver based on captures from
15  * the I2C bus under Windows. This chip is very similar to the saa7134,
16  * though. Unfortunately, this driver is currently only working for NTSC.
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  */
28 
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/slab.h>
32 #include <linux/sched.h>
33 
34 #include <linux/videodev2.h>
35 #include <linux/i2c.h>
36 #include <media/v4l2-device.h>
37 #include <media/v4l2-ctrls.h>
38 
39 MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver");
40 MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil");
41 MODULE_LICENSE("GPL");
42 
43 static int debug;
44 module_param(debug, int, 0644);
45 MODULE_PARM_DESC(debug, "Debug level (0-1)");
46 
47 /*
48  * Generic i2c probe
49  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
50  */
51 
52 struct saa717x_state {
53 	struct v4l2_subdev sd;
54 	struct v4l2_ctrl_handler hdl;
55 	v4l2_std_id std;
56 	int input;
57 	int enable;
58 	int radio;
59 	int playback;
60 	int audio;
61 	int tuner_audio_mode;
62 	int audio_main_mute;
63 	int audio_main_vol_r;
64 	int audio_main_vol_l;
65 	u16 audio_main_bass;
66 	u16 audio_main_treble;
67 	u16 audio_main_volume;
68 	u16 audio_main_balance;
69 	int audio_input;
70 };
71 
72 static inline struct saa717x_state *to_state(struct v4l2_subdev *sd)
73 {
74 	return container_of(sd, struct saa717x_state, sd);
75 }
76 
77 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
78 {
79 	return &container_of(ctrl->handler, struct saa717x_state, hdl)->sd;
80 }
81 
82 /* ----------------------------------------------------------------------- */
83 
84 /* for audio mode */
85 #define TUNER_AUDIO_MONO	0  /* LL */
86 #define TUNER_AUDIO_STEREO	1  /* LR */
87 #define TUNER_AUDIO_LANG1	2  /* LL */
88 #define TUNER_AUDIO_LANG2	3  /* RR */
89 
90 #define SAA717X_NTSC_WIDTH	(704)
91 #define SAA717X_NTSC_HEIGHT	(480)
92 
93 /* ----------------------------------------------------------------------- */
94 
95 static int saa717x_write(struct v4l2_subdev *sd, u32 reg, u32 value)
96 {
97 	struct i2c_client *client = v4l2_get_subdevdata(sd);
98 	struct i2c_adapter *adap = client->adapter;
99 	int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488;
100 	unsigned char mm1[6];
101 	struct i2c_msg msg;
102 
103 	msg.flags = 0;
104 	msg.addr = client->addr;
105 	mm1[0] = (reg >> 8) & 0xff;
106 	mm1[1] = reg & 0xff;
107 
108 	if (fw_addr) {
109 		mm1[4] = (value >> 16) & 0xff;
110 		mm1[3] = (value >> 8) & 0xff;
111 		mm1[2] = value & 0xff;
112 	} else {
113 		mm1[2] = value & 0xff;
114 	}
115 	msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */
116 	msg.buf = mm1;
117 	v4l2_dbg(2, debug, sd, "wrote:  reg 0x%03x=%08x\n", reg, value);
118 	return i2c_transfer(adap, &msg, 1) == 1;
119 }
120 
121 static void saa717x_write_regs(struct v4l2_subdev *sd, u32 *data)
122 {
123 	while (data[0] || data[1]) {
124 		saa717x_write(sd, data[0], data[1]);
125 		data += 2;
126 	}
127 }
128 
129 static u32 saa717x_read(struct v4l2_subdev *sd, u32 reg)
130 {
131 	struct i2c_client *client = v4l2_get_subdevdata(sd);
132 	struct i2c_adapter *adap = client->adapter;
133 	int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528;
134 	unsigned char mm1[2];
135 	unsigned char mm2[4] = { 0, 0, 0, 0 };
136 	struct i2c_msg msgs[2];
137 	u32 value;
138 
139 	msgs[0].flags = 0;
140 	msgs[1].flags = I2C_M_RD;
141 	msgs[0].addr = msgs[1].addr = client->addr;
142 	mm1[0] = (reg >> 8) & 0xff;
143 	mm1[1] = reg & 0xff;
144 	msgs[0].len = 2;
145 	msgs[0].buf = mm1;
146 	msgs[1].len = fw_addr ? 3 : 1; /* Multibyte Registers contains *only* 3 bytes */
147 	msgs[1].buf = mm2;
148 	i2c_transfer(adap, msgs, 2);
149 
150 	if (fw_addr)
151 		value = (mm2[2] << 16)  | (mm2[1] << 8) | mm2[0];
152 	else
153 		value = mm2[0];
154 
155 	v4l2_dbg(2, debug, sd, "read:  reg 0x%03x=0x%08x\n", reg, value);
156 	return value;
157 }
158 
159 /* ----------------------------------------------------------------------- */
160 
161 static u32 reg_init_initialize[] =
162 {
163 	/* from linux driver */
164 	0x101, 0x008, /* Increment delay */
165 
166 	0x103, 0x000, /* Analog input control 2 */
167 	0x104, 0x090, /* Analog input control 3 */
168 	0x105, 0x090, /* Analog input control 4 */
169 	0x106, 0x0eb, /* Horizontal sync start */
170 	0x107, 0x0e0, /* Horizontal sync stop */
171 	0x109, 0x055, /* Luminance control */
172 
173 	0x10f, 0x02a, /* Chroma gain control */
174 	0x110, 0x000, /* Chroma control 2 */
175 
176 	0x114, 0x045, /* analog/ADC */
177 
178 	0x118, 0x040, /* RAW data gain */
179 	0x119, 0x080, /* RAW data offset */
180 
181 	0x044, 0x000, /* VBI horizontal input window start (L) TASK A */
182 	0x045, 0x000, /* VBI horizontal input window start (H) TASK A */
183 	0x046, 0x0cf, /* VBI horizontal input window stop (L) TASK A */
184 	0x047, 0x002, /* VBI horizontal input window stop (H) TASK A */
185 
186 	0x049, 0x000, /* VBI vertical input window start (H) TASK A */
187 
188 	0x04c, 0x0d0, /* VBI horizontal output length (L) TASK A */
189 	0x04d, 0x002, /* VBI horizontal output length (H) TASK A */
190 
191 	0x064, 0x080, /* Lumina brightness TASK A */
192 	0x065, 0x040, /* Luminance contrast TASK A */
193 	0x066, 0x040, /* Chroma saturation TASK A */
194 	/* 067H: Reserved */
195 	0x068, 0x000, /* VBI horizontal scaling increment (L) TASK A */
196 	0x069, 0x004, /* VBI horizontal scaling increment (H) TASK A */
197 	0x06a, 0x000, /* VBI phase offset TASK A */
198 
199 	0x06e, 0x000, /* Horizontal phase offset Luma TASK A */
200 	0x06f, 0x000, /* Horizontal phase offset Chroma TASK A */
201 
202 	0x072, 0x000, /* Vertical filter mode TASK A */
203 
204 	0x084, 0x000, /* VBI horizontal input window start (L) TAKS B */
205 	0x085, 0x000, /* VBI horizontal input window start (H) TAKS B */
206 	0x086, 0x0cf, /* VBI horizontal input window stop (L) TAKS B */
207 	0x087, 0x002, /* VBI horizontal input window stop (H) TAKS B */
208 
209 	0x089, 0x000, /* VBI vertical input window start (H) TAKS B */
210 
211 	0x08c, 0x0d0, /* VBI horizontal output length (L) TASK B */
212 	0x08d, 0x002, /* VBI horizontal output length (H) TASK B */
213 
214 	0x0a4, 0x080, /* Lumina brightness TASK B */
215 	0x0a5, 0x040, /* Luminance contrast TASK B */
216 	0x0a6, 0x040, /* Chroma saturation TASK B */
217 	/* 0A7H reserved */
218 	0x0a8, 0x000, /* VBI horizontal scaling increment (L) TASK B */
219 	0x0a9, 0x004, /* VBI horizontal scaling increment (H) TASK B */
220 	0x0aa, 0x000, /* VBI phase offset TASK B */
221 
222 	0x0ae, 0x000, /* Horizontal phase offset Luma TASK B */
223 	0x0af, 0x000, /*Horizontal phase offset Chroma TASK B */
224 
225 	0x0b2, 0x000, /* Vertical filter mode TASK B */
226 
227 	0x00c, 0x000, /* Start point GREEN path */
228 	0x00d, 0x000, /* Start point BLUE path */
229 	0x00e, 0x000, /* Start point RED path */
230 
231 	0x010, 0x010, /* GREEN path gamma curve --- */
232 	0x011, 0x020,
233 	0x012, 0x030,
234 	0x013, 0x040,
235 	0x014, 0x050,
236 	0x015, 0x060,
237 	0x016, 0x070,
238 	0x017, 0x080,
239 	0x018, 0x090,
240 	0x019, 0x0a0,
241 	0x01a, 0x0b0,
242 	0x01b, 0x0c0,
243 	0x01c, 0x0d0,
244 	0x01d, 0x0e0,
245 	0x01e, 0x0f0,
246 	0x01f, 0x0ff, /* --- GREEN path gamma curve */
247 
248 	0x020, 0x010, /* BLUE path gamma curve --- */
249 	0x021, 0x020,
250 	0x022, 0x030,
251 	0x023, 0x040,
252 	0x024, 0x050,
253 	0x025, 0x060,
254 	0x026, 0x070,
255 	0x027, 0x080,
256 	0x028, 0x090,
257 	0x029, 0x0a0,
258 	0x02a, 0x0b0,
259 	0x02b, 0x0c0,
260 	0x02c, 0x0d0,
261 	0x02d, 0x0e0,
262 	0x02e, 0x0f0,
263 	0x02f, 0x0ff, /* --- BLUE path gamma curve */
264 
265 	0x030, 0x010, /* RED path gamma curve --- */
266 	0x031, 0x020,
267 	0x032, 0x030,
268 	0x033, 0x040,
269 	0x034, 0x050,
270 	0x035, 0x060,
271 	0x036, 0x070,
272 	0x037, 0x080,
273 	0x038, 0x090,
274 	0x039, 0x0a0,
275 	0x03a, 0x0b0,
276 	0x03b, 0x0c0,
277 	0x03c, 0x0d0,
278 	0x03d, 0x0e0,
279 	0x03e, 0x0f0,
280 	0x03f, 0x0ff, /* --- RED path gamma curve */
281 
282 	0x109, 0x085, /* Luminance control  */
283 
284 	/**** from app start ****/
285 	0x584, 0x000, /* AGC gain control */
286 	0x585, 0x000, /* Program count */
287 	0x586, 0x003, /* Status reset */
288 	0x588, 0x0ff, /* Number of audio samples (L) */
289 	0x589, 0x00f, /* Number of audio samples (M) */
290 	0x58a, 0x000, /* Number of audio samples (H) */
291 	0x58b, 0x000, /* Audio select */
292 	0x58c, 0x010, /* Audio channel assign1 */
293 	0x58d, 0x032, /* Audio channel assign2 */
294 	0x58e, 0x054, /* Audio channel assign3 */
295 	0x58f, 0x023, /* Audio format */
296 	0x590, 0x000, /* SIF control */
297 
298 	0x595, 0x000, /* ?? */
299 	0x596, 0x000, /* ?? */
300 	0x597, 0x000, /* ?? */
301 
302 	0x464, 0x00, /* Digital input crossbar1 */
303 
304 	0x46c, 0xbbbb10, /* Digital output selection1-3 */
305 	0x470, 0x101010, /* Digital output selection4-6 */
306 
307 	0x478, 0x00, /* Sound feature control */
308 
309 	0x474, 0x18, /* Softmute control */
310 
311 	0x454, 0x0425b9, /* Sound Easy programming(reset) */
312 	0x454, 0x042539, /* Sound Easy programming(reset) */
313 
314 
315 	/**** common setting( of DVD play, including scaler commands) ****/
316 	0x042, 0x003, /* Data path configuration for VBI (TASK A) */
317 
318 	0x082, 0x003, /* Data path configuration for VBI (TASK B) */
319 
320 	0x108, 0x0f8, /* Sync control */
321 	0x2a9, 0x0fd, /* ??? */
322 	0x102, 0x089, /* select video input "mode 9" */
323 	0x111, 0x000, /* Mode/delay control */
324 
325 	0x10e, 0x00a, /* Chroma control 1 */
326 
327 	0x594, 0x002, /* SIF, analog I/O select */
328 
329 	0x454, 0x0425b9, /* Sound  */
330 	0x454, 0x042539,
331 
332 	0x111, 0x000,
333 	0x10e, 0x00a,
334 	0x464, 0x000,
335 	0x300, 0x000,
336 	0x301, 0x006,
337 	0x302, 0x000,
338 	0x303, 0x006,
339 	0x308, 0x040,
340 	0x309, 0x000,
341 	0x30a, 0x000,
342 	0x30b, 0x000,
343 	0x000, 0x002,
344 	0x001, 0x000,
345 	0x002, 0x000,
346 	0x003, 0x000,
347 	0x004, 0x033,
348 	0x040, 0x01d,
349 	0x041, 0x001,
350 	0x042, 0x004,
351 	0x043, 0x000,
352 	0x080, 0x01e,
353 	0x081, 0x001,
354 	0x082, 0x004,
355 	0x083, 0x000,
356 	0x190, 0x018,
357 	0x115, 0x000,
358 	0x116, 0x012,
359 	0x117, 0x018,
360 	0x04a, 0x011,
361 	0x08a, 0x011,
362 	0x04b, 0x000,
363 	0x08b, 0x000,
364 	0x048, 0x000,
365 	0x088, 0x000,
366 	0x04e, 0x012,
367 	0x08e, 0x012,
368 	0x058, 0x012,
369 	0x098, 0x012,
370 	0x059, 0x000,
371 	0x099, 0x000,
372 	0x05a, 0x003,
373 	0x09a, 0x003,
374 	0x05b, 0x001,
375 	0x09b, 0x001,
376 	0x054, 0x008,
377 	0x094, 0x008,
378 	0x055, 0x000,
379 	0x095, 0x000,
380 	0x056, 0x0c7,
381 	0x096, 0x0c7,
382 	0x057, 0x002,
383 	0x097, 0x002,
384 	0x0ff, 0x0ff,
385 	0x060, 0x001,
386 	0x0a0, 0x001,
387 	0x061, 0x000,
388 	0x0a1, 0x000,
389 	0x062, 0x000,
390 	0x0a2, 0x000,
391 	0x063, 0x000,
392 	0x0a3, 0x000,
393 	0x070, 0x000,
394 	0x0b0, 0x000,
395 	0x071, 0x004,
396 	0x0b1, 0x004,
397 	0x06c, 0x0e9,
398 	0x0ac, 0x0e9,
399 	0x06d, 0x003,
400 	0x0ad, 0x003,
401 	0x05c, 0x0d0,
402 	0x09c, 0x0d0,
403 	0x05d, 0x002,
404 	0x09d, 0x002,
405 	0x05e, 0x0f2,
406 	0x09e, 0x0f2,
407 	0x05f, 0x000,
408 	0x09f, 0x000,
409 	0x074, 0x000,
410 	0x0b4, 0x000,
411 	0x075, 0x000,
412 	0x0b5, 0x000,
413 	0x076, 0x000,
414 	0x0b6, 0x000,
415 	0x077, 0x000,
416 	0x0b7, 0x000,
417 	0x195, 0x008,
418 	0x0ff, 0x0ff,
419 	0x108, 0x0f8,
420 	0x111, 0x000,
421 	0x10e, 0x00a,
422 	0x2a9, 0x0fd,
423 	0x464, 0x001,
424 	0x454, 0x042135,
425 	0x598, 0x0e7,
426 	0x599, 0x07d,
427 	0x59a, 0x018,
428 	0x59c, 0x066,
429 	0x59d, 0x090,
430 	0x59e, 0x001,
431 	0x584, 0x000,
432 	0x585, 0x000,
433 	0x586, 0x003,
434 	0x588, 0x0ff,
435 	0x589, 0x00f,
436 	0x58a, 0x000,
437 	0x58b, 0x000,
438 	0x58c, 0x010,
439 	0x58d, 0x032,
440 	0x58e, 0x054,
441 	0x58f, 0x023,
442 	0x590, 0x000,
443 	0x595, 0x000,
444 	0x596, 0x000,
445 	0x597, 0x000,
446 	0x464, 0x000,
447 	0x46c, 0xbbbb10,
448 	0x470, 0x101010,
449 
450 
451 	0x478, 0x000,
452 	0x474, 0x018,
453 	0x454, 0x042135,
454 	0x598, 0x0e7,
455 	0x599, 0x07d,
456 	0x59a, 0x018,
457 	0x59c, 0x066,
458 	0x59d, 0x090,
459 	0x59e, 0x001,
460 	0x584, 0x000,
461 	0x585, 0x000,
462 	0x586, 0x003,
463 	0x588, 0x0ff,
464 	0x589, 0x00f,
465 	0x58a, 0x000,
466 	0x58b, 0x000,
467 	0x58c, 0x010,
468 	0x58d, 0x032,
469 	0x58e, 0x054,
470 	0x58f, 0x023,
471 	0x590, 0x000,
472 	0x595, 0x000,
473 	0x596, 0x000,
474 	0x597, 0x000,
475 	0x464, 0x000,
476 	0x46c, 0xbbbb10,
477 	0x470, 0x101010,
478 
479 	0x478, 0x000,
480 	0x474, 0x018,
481 	0x454, 0x042135,
482 	0x598, 0x0e7,
483 	0x599, 0x07d,
484 	0x59a, 0x018,
485 	0x59c, 0x066,
486 	0x59d, 0x090,
487 	0x59e, 0x001,
488 	0x584, 0x000,
489 	0x585, 0x000,
490 	0x586, 0x003,
491 	0x588, 0x0ff,
492 	0x589, 0x00f,
493 	0x58a, 0x000,
494 	0x58b, 0x000,
495 	0x58c, 0x010,
496 	0x58d, 0x032,
497 	0x58e, 0x054,
498 	0x58f, 0x023,
499 	0x590, 0x000,
500 	0x595, 0x000,
501 	0x596, 0x000,
502 	0x597, 0x000,
503 	0x464, 0x000,
504 	0x46c, 0xbbbb10,
505 	0x470, 0x101010,
506 	0x478, 0x000,
507 	0x474, 0x018,
508 	0x454, 0x042135,
509 	0x193, 0x000,
510 	0x300, 0x000,
511 	0x301, 0x006,
512 	0x302, 0x000,
513 	0x303, 0x006,
514 	0x308, 0x040,
515 	0x309, 0x000,
516 	0x30a, 0x000,
517 	0x30b, 0x000,
518 	0x000, 0x002,
519 	0x001, 0x000,
520 	0x002, 0x000,
521 	0x003, 0x000,
522 	0x004, 0x033,
523 	0x040, 0x01d,
524 	0x041, 0x001,
525 	0x042, 0x004,
526 	0x043, 0x000,
527 	0x080, 0x01e,
528 	0x081, 0x001,
529 	0x082, 0x004,
530 	0x083, 0x000,
531 	0x190, 0x018,
532 	0x115, 0x000,
533 	0x116, 0x012,
534 	0x117, 0x018,
535 	0x04a, 0x011,
536 	0x08a, 0x011,
537 	0x04b, 0x000,
538 	0x08b, 0x000,
539 	0x048, 0x000,
540 	0x088, 0x000,
541 	0x04e, 0x012,
542 	0x08e, 0x012,
543 	0x058, 0x012,
544 	0x098, 0x012,
545 	0x059, 0x000,
546 	0x099, 0x000,
547 	0x05a, 0x003,
548 	0x09a, 0x003,
549 	0x05b, 0x001,
550 	0x09b, 0x001,
551 	0x054, 0x008,
552 	0x094, 0x008,
553 	0x055, 0x000,
554 	0x095, 0x000,
555 	0x056, 0x0c7,
556 	0x096, 0x0c7,
557 	0x057, 0x002,
558 	0x097, 0x002,
559 	0x060, 0x001,
560 	0x0a0, 0x001,
561 	0x061, 0x000,
562 	0x0a1, 0x000,
563 	0x062, 0x000,
564 	0x0a2, 0x000,
565 	0x063, 0x000,
566 	0x0a3, 0x000,
567 	0x070, 0x000,
568 	0x0b0, 0x000,
569 	0x071, 0x004,
570 	0x0b1, 0x004,
571 	0x06c, 0x0e9,
572 	0x0ac, 0x0e9,
573 	0x06d, 0x003,
574 	0x0ad, 0x003,
575 	0x05c, 0x0d0,
576 	0x09c, 0x0d0,
577 	0x05d, 0x002,
578 	0x09d, 0x002,
579 	0x05e, 0x0f2,
580 	0x09e, 0x0f2,
581 	0x05f, 0x000,
582 	0x09f, 0x000,
583 	0x074, 0x000,
584 	0x0b4, 0x000,
585 	0x075, 0x000,
586 	0x0b5, 0x000,
587 	0x076, 0x000,
588 	0x0b6, 0x000,
589 	0x077, 0x000,
590 	0x0b7, 0x000,
591 	0x195, 0x008,
592 	0x598, 0x0e7,
593 	0x599, 0x07d,
594 	0x59a, 0x018,
595 	0x59c, 0x066,
596 	0x59d, 0x090,
597 	0x59e, 0x001,
598 	0x584, 0x000,
599 	0x585, 0x000,
600 	0x586, 0x003,
601 	0x588, 0x0ff,
602 	0x589, 0x00f,
603 	0x58a, 0x000,
604 	0x58b, 0x000,
605 	0x58c, 0x010,
606 	0x58d, 0x032,
607 	0x58e, 0x054,
608 	0x58f, 0x023,
609 	0x590, 0x000,
610 	0x595, 0x000,
611 	0x596, 0x000,
612 	0x597, 0x000,
613 	0x464, 0x000,
614 	0x46c, 0xbbbb10,
615 	0x470, 0x101010,
616 	0x478, 0x000,
617 	0x474, 0x018,
618 	0x454, 0x042135,
619 	0x193, 0x0a6,
620 	0x108, 0x0f8,
621 	0x042, 0x003,
622 	0x082, 0x003,
623 	0x454, 0x0425b9,
624 	0x454, 0x042539,
625 	0x193, 0x000,
626 	0x193, 0x0a6,
627 	0x464, 0x000,
628 
629 	0, 0
630 };
631 
632 /* Tuner */
633 static u32 reg_init_tuner_input[] = {
634 	0x108, 0x0f8, /* Sync control */
635 	0x111, 0x000, /* Mode/delay control */
636 	0x10e, 0x00a, /* Chroma control 1 */
637 	0, 0
638 };
639 
640 /* Composite */
641 static u32 reg_init_composite_input[] = {
642 	0x108, 0x0e8, /* Sync control */
643 	0x111, 0x000, /* Mode/delay control */
644 	0x10e, 0x04a, /* Chroma control 1 */
645 	0, 0
646 };
647 
648 /* S-Video */
649 static u32 reg_init_svideo_input[] = {
650 	0x108, 0x0e8, /* Sync control */
651 	0x111, 0x000, /* Mode/delay control */
652 	0x10e, 0x04a, /* Chroma control 1 */
653 	0, 0
654 };
655 
656 static u32 reg_set_audio_template[4][2] =
657 {
658 	{ /* for MONO
659 		tadachi 6/29 DMA audio output select?
660 		Register 0x46c
661 		7-4: DMA2, 3-0: DMA1 ch. DMA4, DMA3 DMA2, DMA1
662 		0: MAIN left,  1: MAIN right
663 		2: AUX1 left,  3: AUX1 right
664 		4: AUX2 left,  5: AUX2 right
665 		6: DPL left,   7: DPL  right
666 		8: DPL center, 9: DPL surround
667 		A: monitor output, B: digital sense */
668 		0xbbbb00,
669 
670 		/* tadachi 6/29 DAC and I2S output select?
671 		   Register 0x470
672 		   7-4:DAC right ch. 3-0:DAC left ch.
673 		   I2S1 right,left  I2S2 right,left */
674 		0x00,
675 	},
676 	{ /* for STEREO */
677 		0xbbbb10, 0x101010,
678 	},
679 	{ /* for LANG1 */
680 		0xbbbb00, 0x00,
681 	},
682 	{ /* for LANG2/SAP */
683 		0xbbbb11, 0x111111,
684 	}
685 };
686 
687 
688 /* Get detected audio flags (from saa7134 driver) */
689 static void get_inf_dev_status(struct v4l2_subdev *sd,
690 		int *dual_flag, int *stereo_flag)
691 {
692 	u32 reg_data3;
693 
694 	static char *stdres[0x20] = {
695 		[0x00] = "no standard detected",
696 		[0x01] = "B/G (in progress)",
697 		[0x02] = "D/K (in progress)",
698 		[0x03] = "M (in progress)",
699 
700 		[0x04] = "B/G A2",
701 		[0x05] = "B/G NICAM",
702 		[0x06] = "D/K A2 (1)",
703 		[0x07] = "D/K A2 (2)",
704 		[0x08] = "D/K A2 (3)",
705 		[0x09] = "D/K NICAM",
706 		[0x0a] = "L NICAM",
707 		[0x0b] = "I NICAM",
708 
709 		[0x0c] = "M Korea",
710 		[0x0d] = "M BTSC ",
711 		[0x0e] = "M EIAJ",
712 
713 		[0x0f] = "FM radio / IF 10.7 / 50 deemp",
714 		[0x10] = "FM radio / IF 10.7 / 75 deemp",
715 		[0x11] = "FM radio / IF sel / 50 deemp",
716 		[0x12] = "FM radio / IF sel / 75 deemp",
717 
718 		[0x13 ... 0x1e] = "unknown",
719 		[0x1f] = "??? [in progress]",
720 	};
721 
722 
723 	*dual_flag = *stereo_flag = 0;
724 
725 	/* (demdec status: 0x528) */
726 
727 	/* read current status */
728 	reg_data3 = saa717x_read(sd, 0x0528);
729 
730 	v4l2_dbg(1, debug, sd, "tvaudio thread status: 0x%x [%s%s%s]\n",
731 		reg_data3, stdres[reg_data3 & 0x1f],
732 		(reg_data3 & 0x000020) ? ",stereo" : "",
733 		(reg_data3 & 0x000040) ? ",dual"   : "");
734 	v4l2_dbg(1, debug, sd, "detailed status: "
735 		"%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
736 		(reg_data3 & 0x000080) ? " A2/EIAJ pilot tone "     : "",
737 		(reg_data3 & 0x000100) ? " A2/EIAJ dual "           : "",
738 		(reg_data3 & 0x000200) ? " A2/EIAJ stereo "         : "",
739 		(reg_data3 & 0x000400) ? " A2/EIAJ noise mute "     : "",
740 
741 		(reg_data3 & 0x000800) ? " BTSC/FM radio pilot "    : "",
742 		(reg_data3 & 0x001000) ? " SAP carrier "            : "",
743 		(reg_data3 & 0x002000) ? " BTSC stereo noise mute " : "",
744 		(reg_data3 & 0x004000) ? " SAP noise mute "         : "",
745 		(reg_data3 & 0x008000) ? " VDSP "                   : "",
746 
747 		(reg_data3 & 0x010000) ? " NICST "                  : "",
748 		(reg_data3 & 0x020000) ? " NICDU "                  : "",
749 		(reg_data3 & 0x040000) ? " NICAM muted "            : "",
750 		(reg_data3 & 0x080000) ? " NICAM reserve sound "    : "",
751 
752 		(reg_data3 & 0x100000) ? " init done "              : "");
753 
754 	if (reg_data3 & 0x000220) {
755 		v4l2_dbg(1, debug, sd, "ST!!!\n");
756 		*stereo_flag = 1;
757 	}
758 
759 	if (reg_data3 & 0x000140) {
760 		v4l2_dbg(1, debug, sd, "DUAL!!!\n");
761 		*dual_flag = 1;
762 	}
763 }
764 
765 /* regs write to set audio mode */
766 static void set_audio_mode(struct v4l2_subdev *sd, int audio_mode)
767 {
768 	v4l2_dbg(1, debug, sd, "writing registers to set audio mode by set %d\n",
769 			audio_mode);
770 
771 	saa717x_write(sd, 0x46c, reg_set_audio_template[audio_mode][0]);
772 	saa717x_write(sd, 0x470, reg_set_audio_template[audio_mode][1]);
773 }
774 
775 /* write regs to set audio volume, bass and treble */
776 static int set_audio_regs(struct v4l2_subdev *sd,
777 		struct saa717x_state *decoder)
778 {
779 	u8 mute = 0xac; /* -84 dB */
780 	u32 val;
781 	unsigned int work_l, work_r;
782 
783 	/* set SIF analog I/O select */
784 	saa717x_write(sd, 0x0594, decoder->audio_input);
785 	v4l2_dbg(1, debug, sd, "set audio input %d\n",
786 			decoder->audio_input);
787 
788 	/* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */
789 	work_l = (min(65536 - decoder->audio_main_balance, 32768) * decoder->audio_main_volume) / 32768;
790 	work_r = (min(decoder->audio_main_balance, (u16)32768) * decoder->audio_main_volume) / 32768;
791 	decoder->audio_main_vol_l = (long)work_l * (24 - (-40)) / 65535 - 40;
792 	decoder->audio_main_vol_r = (long)work_r * (24 - (-40)) / 65535 - 40;
793 
794 	/* set main volume */
795 	/* main volume L[7-0],R[7-0],0x00  24=24dB,-83dB, -84(mute) */
796 	/*    def:0dB->6dB(MPG600GR) */
797 	/* if mute is on, set mute */
798 	if (decoder->audio_main_mute) {
799 		val = mute | (mute << 8);
800 	} else {
801 		val = (u8)decoder->audio_main_vol_l |
802 			((u8)decoder->audio_main_vol_r << 8);
803 	}
804 
805 	saa717x_write(sd, 0x480, val);
806 
807 	/* set bass and treble */
808 	val = decoder->audio_main_bass & 0x1f;
809 	val |= (decoder->audio_main_treble & 0x1f) << 5;
810 	saa717x_write(sd, 0x488, val);
811 	return 0;
812 }
813 
814 /********** scaling staff ***********/
815 static void set_h_prescale(struct v4l2_subdev *sd,
816 		int task, int prescale)
817 {
818 	static const struct {
819 		int xpsc;
820 		int xacl;
821 		int xc2_1;
822 		int xdcg;
823 		int vpfy;
824 	} vals[] = {
825 		/* XPSC XACL XC2_1 XDCG VPFY */
826 		{    1,   0,    0,    0,   0 },
827 		{    2,   2,    1,    2,   2 },
828 		{    3,   4,    1,    3,   2 },
829 		{    4,   8,    1,    4,   2 },
830 		{    5,   8,    1,    4,   2 },
831 		{    6,   8,    1,    4,   3 },
832 		{    7,   8,    1,    4,   3 },
833 		{    8,  15,    0,    4,   3 },
834 		{    9,  15,    0,    4,   3 },
835 		{   10,  16,    1,    5,   3 },
836 	};
837 	static const int count = ARRAY_SIZE(vals);
838 	int i, task_shift;
839 
840 	task_shift = task * 0x40;
841 	for (i = 0; i < count; i++)
842 		if (vals[i].xpsc == prescale)
843 			break;
844 	if (i == count)
845 		return;
846 
847 	/* horizonal prescaling */
848 	saa717x_write(sd, 0x60 + task_shift, vals[i].xpsc);
849 	/* accumulation length */
850 	saa717x_write(sd, 0x61 + task_shift, vals[i].xacl);
851 	/* level control */
852 	saa717x_write(sd, 0x62 + task_shift,
853 			(vals[i].xc2_1 << 3) | vals[i].xdcg);
854 	/*FIR prefilter control */
855 	saa717x_write(sd, 0x63 + task_shift,
856 			(vals[i].vpfy << 2) | vals[i].vpfy);
857 }
858 
859 /********** scaling staff ***********/
860 static void set_v_scale(struct v4l2_subdev *sd, int task, int yscale)
861 {
862 	int task_shift;
863 
864 	task_shift = task * 0x40;
865 	/* Vertical scaling ratio (LOW) */
866 	saa717x_write(sd, 0x70 + task_shift, yscale & 0xff);
867 	/* Vertical scaling ratio (HI) */
868 	saa717x_write(sd, 0x71 + task_shift, yscale >> 8);
869 }
870 
871 static int saa717x_s_ctrl(struct v4l2_ctrl *ctrl)
872 {
873 	struct v4l2_subdev *sd = to_sd(ctrl);
874 	struct saa717x_state *state = to_state(sd);
875 
876 	switch (ctrl->id) {
877 	case V4L2_CID_BRIGHTNESS:
878 		saa717x_write(sd, 0x10a, ctrl->val);
879 		return 0;
880 
881 	case V4L2_CID_CONTRAST:
882 		saa717x_write(sd, 0x10b, ctrl->val);
883 		return 0;
884 
885 	case V4L2_CID_SATURATION:
886 		saa717x_write(sd, 0x10c, ctrl->val);
887 		return 0;
888 
889 	case V4L2_CID_HUE:
890 		saa717x_write(sd, 0x10d, ctrl->val);
891 		return 0;
892 
893 	case V4L2_CID_AUDIO_MUTE:
894 		state->audio_main_mute = ctrl->val;
895 		break;
896 
897 	case V4L2_CID_AUDIO_VOLUME:
898 		state->audio_main_volume = ctrl->val;
899 		break;
900 
901 	case V4L2_CID_AUDIO_BALANCE:
902 		state->audio_main_balance = ctrl->val;
903 		break;
904 
905 	case V4L2_CID_AUDIO_TREBLE:
906 		state->audio_main_treble = ctrl->val;
907 		break;
908 
909 	case V4L2_CID_AUDIO_BASS:
910 		state->audio_main_bass = ctrl->val;
911 		break;
912 
913 	default:
914 		return 0;
915 	}
916 	set_audio_regs(sd, state);
917 	return 0;
918 }
919 
920 static int saa717x_s_video_routing(struct v4l2_subdev *sd,
921 				   u32 input, u32 output, u32 config)
922 {
923 	struct saa717x_state *decoder = to_state(sd);
924 	int is_tuner = input & 0x80;  /* tuner input flag */
925 
926 	input &= 0x7f;
927 
928 	v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input);
929 	/* inputs from 0-9 are available*/
930 	/* saa717x have mode0-mode9 but mode5 is reserved. */
931 	if (input > 9 || input == 5)
932 		return -EINVAL;
933 
934 	if (decoder->input != input) {
935 		int input_line = input;
936 
937 		decoder->input = input_line;
938 		v4l2_dbg(1, debug, sd,  "now setting %s input %d\n",
939 				input_line >= 6 ? "S-Video" : "Composite",
940 				input_line);
941 
942 		/* select mode */
943 		saa717x_write(sd, 0x102,
944 				(saa717x_read(sd, 0x102) & 0xf0) |
945 				input_line);
946 
947 		/* bypass chrominance trap for modes 6..9 */
948 		saa717x_write(sd, 0x109,
949 				(saa717x_read(sd, 0x109) & 0x7f) |
950 				(input_line < 6 ? 0x0 : 0x80));
951 
952 		/* change audio_mode */
953 		if (is_tuner) {
954 			/* tuner */
955 			set_audio_mode(sd, decoder->tuner_audio_mode);
956 		} else {
957 			/* Force to STEREO mode if Composite or
958 			 * S-Video were chosen */
959 			set_audio_mode(sd, TUNER_AUDIO_STEREO);
960 		}
961 		/* change initialize procedure (Composite/S-Video) */
962 		if (is_tuner)
963 			saa717x_write_regs(sd, reg_init_tuner_input);
964 		else if (input_line >= 6)
965 			saa717x_write_regs(sd, reg_init_svideo_input);
966 		else
967 			saa717x_write_regs(sd, reg_init_composite_input);
968 	}
969 
970 	return 0;
971 }
972 
973 #ifdef CONFIG_VIDEO_ADV_DEBUG
974 static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
975 {
976 	reg->val = saa717x_read(sd, reg->reg);
977 	reg->size = 1;
978 	return 0;
979 }
980 
981 static int saa717x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
982 {
983 	u16 addr = reg->reg & 0xffff;
984 	u8 val = reg->val & 0xff;
985 
986 	saa717x_write(sd, addr, val);
987 	return 0;
988 }
989 #endif
990 
991 static int saa717x_set_fmt(struct v4l2_subdev *sd,
992 		struct v4l2_subdev_pad_config *cfg,
993 		struct v4l2_subdev_format *format)
994 {
995 	struct v4l2_mbus_framefmt *fmt = &format->format;
996 	int prescale, h_scale, v_scale;
997 
998 	v4l2_dbg(1, debug, sd, "decoder set size\n");
999 
1000 	if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED)
1001 		return -EINVAL;
1002 
1003 	/* FIXME need better bounds checking here */
1004 	if (fmt->width < 1 || fmt->width > 1440)
1005 		return -EINVAL;
1006 	if (fmt->height < 1 || fmt->height > 960)
1007 		return -EINVAL;
1008 
1009 	fmt->field = V4L2_FIELD_INTERLACED;
1010 	fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
1011 
1012 	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
1013 		return 0;
1014 
1015 	/* scaling setting */
1016 	/* NTSC and interlace only */
1017 	prescale = SAA717X_NTSC_WIDTH / fmt->width;
1018 	if (prescale == 0)
1019 		prescale = 1;
1020 	h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / fmt->width;
1021 	/* interlace */
1022 	v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / fmt->height;
1023 
1024 	/* Horizontal prescaling etc */
1025 	set_h_prescale(sd, 0, prescale);
1026 	set_h_prescale(sd, 1, prescale);
1027 
1028 	/* Horizontal scaling increment */
1029 	/* TASK A */
1030 	saa717x_write(sd, 0x6C, (u8)(h_scale & 0xFF));
1031 	saa717x_write(sd, 0x6D, (u8)((h_scale >> 8) & 0xFF));
1032 	/* TASK B */
1033 	saa717x_write(sd, 0xAC, (u8)(h_scale & 0xFF));
1034 	saa717x_write(sd, 0xAD, (u8)((h_scale >> 8) & 0xFF));
1035 
1036 	/* Vertical prescaling etc */
1037 	set_v_scale(sd, 0, v_scale);
1038 	set_v_scale(sd, 1, v_scale);
1039 
1040 	/* set video output size */
1041 	/* video number of pixels at output */
1042 	/* TASK A */
1043 	saa717x_write(sd, 0x5C, (u8)(fmt->width & 0xFF));
1044 	saa717x_write(sd, 0x5D, (u8)((fmt->width >> 8) & 0xFF));
1045 	/* TASK B */
1046 	saa717x_write(sd, 0x9C, (u8)(fmt->width & 0xFF));
1047 	saa717x_write(sd, 0x9D, (u8)((fmt->width >> 8) & 0xFF));
1048 
1049 	/* video number of lines at output */
1050 	/* TASK A */
1051 	saa717x_write(sd, 0x5E, (u8)(fmt->height & 0xFF));
1052 	saa717x_write(sd, 0x5F, (u8)((fmt->height >> 8) & 0xFF));
1053 	/* TASK B */
1054 	saa717x_write(sd, 0x9E, (u8)(fmt->height & 0xFF));
1055 	saa717x_write(sd, 0x9F, (u8)((fmt->height >> 8) & 0xFF));
1056 	return 0;
1057 }
1058 
1059 static int saa717x_s_radio(struct v4l2_subdev *sd)
1060 {
1061 	struct saa717x_state *decoder = to_state(sd);
1062 
1063 	decoder->radio = 1;
1064 	return 0;
1065 }
1066 
1067 static int saa717x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1068 {
1069 	struct saa717x_state *decoder = to_state(sd);
1070 
1071 	v4l2_dbg(1, debug, sd, "decoder set norm ");
1072 	v4l2_dbg(1, debug, sd, "(not yet implemented)\n");
1073 
1074 	decoder->radio = 0;
1075 	decoder->std = std;
1076 	return 0;
1077 }
1078 
1079 static int saa717x_s_audio_routing(struct v4l2_subdev *sd,
1080 				   u32 input, u32 output, u32 config)
1081 {
1082 	struct saa717x_state *decoder = to_state(sd);
1083 
1084 	if (input < 3) { /* FIXME! --tadachi */
1085 		decoder->audio_input = input;
1086 		v4l2_dbg(1, debug, sd,
1087 				"set decoder audio input to %d\n",
1088 				decoder->audio_input);
1089 		set_audio_regs(sd, decoder);
1090 		return 0;
1091 	}
1092 	return -ERANGE;
1093 }
1094 
1095 static int saa717x_s_stream(struct v4l2_subdev *sd, int enable)
1096 {
1097 	struct saa717x_state *decoder = to_state(sd);
1098 
1099 	v4l2_dbg(1, debug, sd, "decoder %s output\n",
1100 			enable ? "enable" : "disable");
1101 	decoder->enable = enable;
1102 	saa717x_write(sd, 0x193, enable ? 0xa6 : 0x26);
1103 	return 0;
1104 }
1105 
1106 /* change audio mode */
1107 static int saa717x_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
1108 {
1109 	struct saa717x_state *decoder = to_state(sd);
1110 	int audio_mode;
1111 	char *mes[4] = {
1112 		"MONO", "STEREO", "LANG1", "LANG2/SAP"
1113 	};
1114 
1115 	audio_mode = TUNER_AUDIO_STEREO;
1116 
1117 	switch (vt->audmode) {
1118 		case V4L2_TUNER_MODE_MONO:
1119 			audio_mode = TUNER_AUDIO_MONO;
1120 			break;
1121 		case V4L2_TUNER_MODE_STEREO:
1122 			audio_mode = TUNER_AUDIO_STEREO;
1123 			break;
1124 		case V4L2_TUNER_MODE_LANG2:
1125 			audio_mode = TUNER_AUDIO_LANG2;
1126 			break;
1127 		case V4L2_TUNER_MODE_LANG1:
1128 			audio_mode = TUNER_AUDIO_LANG1;
1129 			break;
1130 	}
1131 
1132 	v4l2_dbg(1, debug, sd, "change audio mode to %s\n",
1133 			mes[audio_mode]);
1134 	decoder->tuner_audio_mode = audio_mode;
1135 	/* The registers are not changed here. */
1136 	/* See DECODER_ENABLE_OUTPUT section. */
1137 	set_audio_mode(sd, decoder->tuner_audio_mode);
1138 	return 0;
1139 }
1140 
1141 static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1142 {
1143 	struct saa717x_state *decoder = to_state(sd);
1144 	int dual_f, stereo_f;
1145 
1146 	if (decoder->radio)
1147 		return 0;
1148 	get_inf_dev_status(sd, &dual_f, &stereo_f);
1149 
1150 	v4l2_dbg(1, debug, sd, "DETECT==st:%d dual:%d\n",
1151 			stereo_f, dual_f);
1152 
1153 	/* mono */
1154 	if ((dual_f == 0) && (stereo_f == 0)) {
1155 		vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1156 		v4l2_dbg(1, debug, sd, "DETECT==MONO\n");
1157 	}
1158 
1159 	/* stereo */
1160 	if (stereo_f == 1) {
1161 		if (vt->audmode == V4L2_TUNER_MODE_STEREO ||
1162 				vt->audmode == V4L2_TUNER_MODE_LANG1) {
1163 			vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
1164 			v4l2_dbg(1, debug, sd, "DETECT==ST(ST)\n");
1165 		} else {
1166 			vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1167 			v4l2_dbg(1, debug, sd, "DETECT==ST(MONO)\n");
1168 		}
1169 	}
1170 
1171 	/* dual */
1172 	if (dual_f == 1) {
1173 		if (vt->audmode == V4L2_TUNER_MODE_LANG2) {
1174 			vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO;
1175 			v4l2_dbg(1, debug, sd, "DETECT==DUAL1\n");
1176 		} else {
1177 			vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO;
1178 			v4l2_dbg(1, debug, sd, "DETECT==DUAL2\n");
1179 		}
1180 	}
1181 	return 0;
1182 }
1183 
1184 static int saa717x_log_status(struct v4l2_subdev *sd)
1185 {
1186 	struct saa717x_state *state = to_state(sd);
1187 
1188 	v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
1189 	return 0;
1190 }
1191 
1192 /* ----------------------------------------------------------------------- */
1193 
1194 static const struct v4l2_ctrl_ops saa717x_ctrl_ops = {
1195 	.s_ctrl = saa717x_s_ctrl,
1196 };
1197 
1198 static const struct v4l2_subdev_core_ops saa717x_core_ops = {
1199 #ifdef CONFIG_VIDEO_ADV_DEBUG
1200 	.g_register = saa717x_g_register,
1201 	.s_register = saa717x_s_register,
1202 #endif
1203 	.log_status = saa717x_log_status,
1204 };
1205 
1206 static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
1207 	.g_tuner = saa717x_g_tuner,
1208 	.s_tuner = saa717x_s_tuner,
1209 	.s_radio = saa717x_s_radio,
1210 };
1211 
1212 static const struct v4l2_subdev_video_ops saa717x_video_ops = {
1213 	.s_std = saa717x_s_std,
1214 	.s_routing = saa717x_s_video_routing,
1215 	.s_stream = saa717x_s_stream,
1216 };
1217 
1218 static const struct v4l2_subdev_audio_ops saa717x_audio_ops = {
1219 	.s_routing = saa717x_s_audio_routing,
1220 };
1221 
1222 static const struct v4l2_subdev_pad_ops saa717x_pad_ops = {
1223 	.set_fmt = saa717x_set_fmt,
1224 };
1225 
1226 static const struct v4l2_subdev_ops saa717x_ops = {
1227 	.core = &saa717x_core_ops,
1228 	.tuner = &saa717x_tuner_ops,
1229 	.audio = &saa717x_audio_ops,
1230 	.video = &saa717x_video_ops,
1231 	.pad = &saa717x_pad_ops,
1232 };
1233 
1234 /* ----------------------------------------------------------------------- */
1235 
1236 
1237 /* i2c implementation */
1238 
1239 /* ----------------------------------------------------------------------- */
1240 static int saa717x_probe(struct i2c_client *client,
1241 			 const struct i2c_device_id *did)
1242 {
1243 	struct saa717x_state *decoder;
1244 	struct v4l2_ctrl_handler *hdl;
1245 	struct v4l2_subdev *sd;
1246 	u8 id = 0;
1247 	char *p = "";
1248 
1249 	/* Check if the adapter supports the needed features */
1250 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1251 		return -EIO;
1252 
1253 	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
1254 	if (decoder == NULL)
1255 		return -ENOMEM;
1256 
1257 	sd = &decoder->sd;
1258 	v4l2_i2c_subdev_init(sd, client, &saa717x_ops);
1259 
1260 	if (saa717x_write(sd, 0x5a4, 0xfe) &&
1261 			saa717x_write(sd, 0x5a5, 0x0f) &&
1262 			saa717x_write(sd, 0x5a6, 0x00) &&
1263 			saa717x_write(sd, 0x5a7, 0x01))
1264 		id = saa717x_read(sd, 0x5a0);
1265 	if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) {
1266 		v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id);
1267 		return -ENODEV;
1268 	}
1269 	if (id == 0xc2)
1270 		p = "saa7173";
1271 	else if (id == 0x32)
1272 		p = "saa7174A";
1273 	else if (id == 0x6c)
1274 		p = "saa7174HL";
1275 	else
1276 		p = "saa7171";
1277 	v4l2_info(sd, "%s found @ 0x%x (%s)\n", p,
1278 			client->addr << 1, client->adapter->name);
1279 
1280 	hdl = &decoder->hdl;
1281 	v4l2_ctrl_handler_init(hdl, 9);
1282 	/* add in ascending ID order */
1283 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1284 			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1285 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1286 			V4L2_CID_CONTRAST, 0, 255, 1, 68);
1287 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1288 			V4L2_CID_SATURATION, 0, 255, 1, 64);
1289 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1290 			V4L2_CID_HUE, -128, 127, 1, 0);
1291 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1292 			V4L2_CID_AUDIO_VOLUME, 0, 65535, 65535 / 100, 42000);
1293 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1294 			V4L2_CID_AUDIO_BALANCE, 0, 65535, 65535 / 100, 32768);
1295 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1296 			V4L2_CID_AUDIO_BASS, -16, 15, 1, 0);
1297 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1298 			V4L2_CID_AUDIO_TREBLE, -16, 15, 1, 0);
1299 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1300 			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
1301 	sd->ctrl_handler = hdl;
1302 	if (hdl->error) {
1303 		int err = hdl->error;
1304 
1305 		v4l2_ctrl_handler_free(hdl);
1306 		return err;
1307 	}
1308 
1309 	decoder->std = V4L2_STD_NTSC;
1310 	decoder->input = -1;
1311 	decoder->enable = 1;
1312 
1313 	/* FIXME!! */
1314 	decoder->playback = 0;	/* initially capture mode used */
1315 	decoder->audio = 1; /* DECODER_AUDIO_48_KHZ */
1316 
1317 	decoder->audio_input = 2; /* FIXME!! */
1318 
1319 	decoder->tuner_audio_mode = TUNER_AUDIO_STEREO;
1320 	/* set volume, bass and treble */
1321 	decoder->audio_main_vol_l = 6;
1322 	decoder->audio_main_vol_r = 6;
1323 
1324 	v4l2_dbg(1, debug, sd, "writing init values\n");
1325 
1326 	/* FIXME!! */
1327 	saa717x_write_regs(sd, reg_init_initialize);
1328 
1329 	v4l2_ctrl_handler_setup(hdl);
1330 
1331 	set_current_state(TASK_INTERRUPTIBLE);
1332 	schedule_timeout(2*HZ);
1333 	return 0;
1334 }
1335 
1336 static int saa717x_remove(struct i2c_client *client)
1337 {
1338 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1339 
1340 	v4l2_device_unregister_subdev(sd);
1341 	v4l2_ctrl_handler_free(sd->ctrl_handler);
1342 	return 0;
1343 }
1344 
1345 /* ----------------------------------------------------------------------- */
1346 
1347 static const struct i2c_device_id saa717x_id[] = {
1348 	{ "saa717x", 0 },
1349 	{ }
1350 };
1351 MODULE_DEVICE_TABLE(i2c, saa717x_id);
1352 
1353 static struct i2c_driver saa717x_driver = {
1354 	.driver = {
1355 		.name	= "saa717x",
1356 	},
1357 	.probe		= saa717x_probe,
1358 	.remove		= saa717x_remove,
1359 	.id_table	= saa717x_id,
1360 };
1361 
1362 module_i2c_driver(saa717x_driver);
1363