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