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