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