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