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