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