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