ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / media / dvb / ttpci / av7110_v4l.c
1 /*
2  * av7110_v4l.c: av7110 video4linux interface for DVB and Siemens DVB-C analog module
3  *
4  * Copyright (C) 1999-2002 Ralph  Metzler
5  *                       & Marcus Metzler for convergence integrated media GmbH
6  *
7  * originally based on code by:
8  * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
24  *
25  * the project's page is at http://www.linuxtv.org/dvb/
26  */
27
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/types.h>
31 #include <linux/delay.h>
32 #include <linux/fs.h>
33 #include <linux/timer.h>
34 #include <linux/poll.h>
35 #include <linux/byteorder/swabb.h>
36 #include <linux/smp_lock.h>
37
38 #define DEBUG_VARIABLE av7110_debug
39 extern int av7110_debug;
40
41 #include "dvb_i2c.h"
42 #include "av7110.h"
43 #include "av7110_hw.h"
44 #include "av7110_av.h"
45 #include "dvb_functions.h"
46
47
48 int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
49 {
50         u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
51         struct dvb_i2c_bus *i2c = av7110->i2c_bus;
52         struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg };
53
54         if (i2c->xfer(i2c, &msgs, 1) != 1) {
55                 printk("av7110(%d): %s(%u = %u) failed\n",
56                        av7110->dvb_adapter->num, __FUNCTION__, reg, val);
57                 return -EIO;
58         }
59         return 0;
60 }
61
62 int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
63 {
64         u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
65         u8 msg2[2];
66         struct dvb_i2c_bus *i2c = av7110->i2c_bus;
67         struct i2c_msg msgs[2] = {
68                 { .flags = 0,        .addr = 0x40, .len = 3, .buf = msg1 },
69                 { .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 }
70         };
71
72         if (i2c->xfer(i2c, msgs, 2) != 2) {
73                 printk("av7110(%d): %s(%u) failed\n",
74                        av7110->dvb_adapter->num, __FUNCTION__, reg);
75                 return -EIO;
76         }
77         *val = (msg2[0] << 8) | msg2[1];
78         return 0;
79 }
80
81
82
83 static struct v4l2_input inputs[2] = {
84         {
85                 .index          = 0,
86                 .name           = "DVB",
87                 .type           = V4L2_INPUT_TYPE_CAMERA,
88                 .audioset       = 1,
89                 .tuner          = 0, /* ignored */
90                 .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
91                 .status         = 0,
92         }, {
93                 .index          = 1,
94                 .name           = "Television",
95                 .type           = V4L2_INPUT_TYPE_TUNER,
96                 .audioset       = 2,
97                 .tuner          = 0,
98                 .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
99                 .status         = 0,
100         }
101 };
102
103 /* for Siemens DVB-C analog module: (taken from ves1820.c) */
104 static int ves1820_writereg(struct saa7146_dev *dev, u8 reg, u8 data)
105 {
106         u8 addr = 0x09;
107         u8 buf[] = { 0x00, reg, data };
108         struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
109
110         DEB_EE(("av7710: dev: %p\n", dev));
111
112         if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
113                 return -1;
114         return 0;
115 }
116
117 static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
118 {
119         struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
120
121         DEB_EE(("av7710: dev: %p\n", dev));
122
123         if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
124                 return -1;
125         return 0;
126 }
127
128
129 /**
130  *   set up the downconverter frequency divisor for a
131  *   reference clock comparision frequency of 62.5 kHz.
132  */
133 static int tuner_set_tv_freq(struct saa7146_dev *dev, u32 freq)
134 {
135         u32 div;
136         u8 config;
137         u8 buf[4];
138
139         DEB_EE(("av7710: freq: 0x%08x\n", freq));
140
141         /* magic number: 614. tuning with the frequency given by v4l2
142            is always off by 614*62.5 = 38375 kHz...*/
143         div = freq + 614;
144
145         buf[0] = (div >> 8) & 0x7f;
146         buf[1] = div & 0xff;
147         buf[2] = 0x8e;
148
149         if (freq < (u32) (16 * 168.25))
150                 config = 0xa0;
151         else if (freq < (u32) (16 * 447.25))
152                 config = 0x90;
153         else
154                 config = 0x30;
155         config &= ~0x02;
156
157         buf[3] = config;
158
159         return tuner_write(dev, 0x61, buf);
160 }
161
162
163 static struct saa7146_standard analog_standard[];
164 static struct saa7146_standard dvb_standard[];
165 static struct saa7146_standard standard[];
166
167 static struct v4l2_audio msp3400_v4l2_audio = {
168         .index = 0,
169         .name = "Television",
170         .capability = V4L2_AUDCAP_STEREO
171 };
172
173 int av7110_dvb_c_switch(struct saa7146_fh *fh)
174 {
175         struct saa7146_dev *dev = fh->dev;
176         struct saa7146_vv *vv = dev->vv_data;
177         struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
178         u16 adswitch;
179         u8 band = 0;
180         int source, sync, err;
181
182         DEB_EE(("av7110: %p\n", av7110));
183
184         if ((vv->video_status & STATUS_OVERLAY) != 0) {
185                 vv->ov_suspend = vv->video_fh;
186                 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
187                 if (err != 0) {
188                         DEB_D(("warning: suspending video failed\n"));
189                         vv->ov_suspend = NULL;
190                 }
191         }
192
193         if (0 != av7110->current_input) {
194                 adswitch = 1;
195                 band = 0x60; /* analog band */
196                 source = SAA7146_HPS_SOURCE_PORT_B;
197                 sync = SAA7146_HPS_SYNC_PORT_B;
198                 memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
199                 printk("av7110: switching to analog TV\n");
200                 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
201                 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
202                 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
203                 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
204                 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
205                 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
206         } else {
207                 adswitch = 0;
208                 band = 0x20; /* digital band */
209                 source = SAA7146_HPS_SOURCE_PORT_A;
210                 sync = SAA7146_HPS_SYNC_PORT_A;
211                 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
212                 printk("av7110: switching DVB mode\n");
213                 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
214                 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
215                 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
216                 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
217                 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
218                 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
219         }
220
221         /* hmm, this does not do anything!? */
222         if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
223                 printk("ADSwitch error\n");
224
225         if (ves1820_writereg(dev, 0x0f, band))
226                 printk("setting band in demodulator failed.\n");
227         saa7146_set_hps_source_and_sync(dev, source, sync);
228
229         if (vv->ov_suspend != NULL) {
230                 saa7146_start_preview(vv->ov_suspend);
231                 vv->ov_suspend = NULL;
232         }
233
234         return 0;
235 }
236
237 int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
238 {
239         struct saa7146_dev *dev = fh->dev;
240         struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
241         DEB_EE(("saa7146_dev: %p\n", dev));
242
243         switch (cmd) {
244         case VIDIOC_G_TUNER:
245         {
246                 struct v4l2_tuner *t = arg;
247                 u16 stereo_det;
248                 s8 stereo;
249
250                 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
251
252                 if (!av7110->has_analog_tuner || t->index != 0)
253                         return -EINVAL;
254
255                 memset(t, 0, sizeof(*t));
256                 strcpy(t->name, "Television");
257
258                 t->type = V4L2_TUNER_ANALOG_TV;
259                 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
260                         V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
261                 t->rangelow = 772;      /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
262                 t->rangehigh = 13684;   /* 855.25 MHz / 62.5 kHz = 13684 */
263                 /* FIXME: add the real signal strength here */
264                 t->signal = 0xffff;
265                 t->afc = 0;
266
267                 // FIXME: standard / stereo detection is still broken
268                 msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
269 printk("VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
270
271                 msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
272                 printk("VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
273                 stereo = (s8)(stereo_det >> 8);
274                 if (stereo > 0x10) {
275                         /* stereo */
276                         t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
277                         t->audmode = V4L2_TUNER_MODE_STEREO;
278                 }
279                 else if (stereo < -0x10) {
280                         /* bilingual*/
281                         t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
282                         t->audmode = V4L2_TUNER_MODE_LANG1;
283                 }
284                 else /* mono */
285                         t->rxsubchans = V4L2_TUNER_SUB_MONO;
286
287                 return 0;
288         }
289         case VIDIOC_S_TUNER:
290         {
291                 struct v4l2_tuner *t = arg;
292                 u16 fm_matrix, src;
293                 DEB_EE(("VIDIOC_S_TUNER: %d\n", t->index));
294
295                 if (!av7110->has_analog_tuner || av7110->current_input != 1)
296                         return -EINVAL;
297
298                 switch (t->audmode) {
299                 case V4L2_TUNER_MODE_STEREO:
300                         DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
301                         fm_matrix = 0x3001; // stereo
302                         src = 0x0020;
303                         break;
304                 case V4L2_TUNER_MODE_LANG1:
305                         DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
306                         fm_matrix = 0x3000; // mono
307                         src = 0x0000;
308                         break;
309                 case V4L2_TUNER_MODE_LANG2:
310                         DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
311                         fm_matrix = 0x3000; // mono
312                         src = 0x0010;
313                         break;
314                 default: /* case V4L2_TUNER_MODE_MONO: {*/
315                         DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
316                         fm_matrix = 0x3000; // mono
317                         src = 0x0030;
318                         break;
319                 }
320                 msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
321                 msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
322                 msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
323                 msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
324                 return 0;
325         }
326         case VIDIOC_G_FREQUENCY:
327         {
328                 struct v4l2_frequency *f = arg;
329
330                 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency));
331
332                 if (!av7110->has_analog_tuner || av7110->current_input != 1)
333                         return -EINVAL;
334
335                 memset(f, 0, sizeof(*f));
336                 f->type = V4L2_TUNER_ANALOG_TV;
337                 f->frequency =  av7110->current_freq;
338                 return 0;
339         }
340         case VIDIOC_S_FREQUENCY:
341         {
342                 struct v4l2_frequency *f = arg;
343
344                 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency));
345
346                 if (!av7110->has_analog_tuner || av7110->current_input != 1)
347                         return -EINVAL;
348
349                 if (V4L2_TUNER_ANALOG_TV != f->type)
350                         return -EINVAL;
351
352                 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
353                 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
354
355                 /* tune in desired frequency */
356                 tuner_set_tv_freq(dev, f->frequency);
357                 av7110->current_freq = f->frequency;
358
359                 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
360                 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
361                 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
362                 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
363                 return 0;
364         }
365         case VIDIOC_ENUMINPUT:
366         {
367                 struct v4l2_input *i = arg;
368
369                 DEB_EE(("VIDIOC_ENUMINPUT: %d\n", i->index));
370
371                 if (av7110->has_analog_tuner ) {
372                         if (i->index < 0 || i->index >= 2)
373                                 return -EINVAL;
374                 } else {
375                         if (i->index != 0)
376                                 return -EINVAL;
377                 }
378
379                 memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
380
381                 return 0;
382         }
383         case VIDIOC_G_INPUT:
384         {
385                 int *input = (int *)arg;
386                 *input = av7110->current_input;
387                 DEB_EE(("VIDIOC_G_INPUT: %d\n", *input));
388                 return 0;
389         }
390         case VIDIOC_S_INPUT:
391         {
392                 int input = *(int *)arg;
393
394                 DEB_EE(("VIDIOC_S_INPUT: %d\n", input));
395
396                 if (!av7110->has_analog_tuner )
397                         return 0;
398
399                 if (input < 0 || input >= 2)
400                         return -EINVAL;
401
402                 /* FIXME: switch inputs here */
403                 av7110->current_input = input;
404                 return av7110_dvb_c_switch(fh);
405         }
406         case VIDIOC_G_AUDIO:
407         {
408                 struct v4l2_audio *a = arg;
409
410                 DEB_EE(("VIDIOC_G_AUDIO: %d\n", a->index));
411                 if (a->index != 0)
412                         return -EINVAL;
413                 memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
414                 break;
415         }
416         case VIDIOC_S_AUDIO:
417         {
418                 struct v4l2_audio *a = arg;
419                 DEB_EE(("VIDIOC_S_AUDIO: %d\n", a->index));
420                 break;
421         }
422         default:
423                 printk("no such ioctl\n");
424                 return -ENOIOCTLCMD;
425         }
426         return 0;
427 }
428
429
430 /****************************************************************************
431  * INITIALIZATION
432  ****************************************************************************/
433
434 struct saa7146_extension_ioctls ioctls[] = {
435         { VIDIOC_ENUMINPUT,     SAA7146_EXCLUSIVE },
436         { VIDIOC_G_INPUT,       SAA7146_EXCLUSIVE },
437         { VIDIOC_S_INPUT,       SAA7146_EXCLUSIVE },
438         { VIDIOC_G_FREQUENCY,   SAA7146_EXCLUSIVE },
439         { VIDIOC_S_FREQUENCY,   SAA7146_EXCLUSIVE },
440         { VIDIOC_G_TUNER,       SAA7146_EXCLUSIVE },
441         { VIDIOC_S_TUNER,       SAA7146_EXCLUSIVE },
442         { VIDIOC_G_AUDIO,       SAA7146_EXCLUSIVE },
443         { VIDIOC_S_AUDIO,       SAA7146_EXCLUSIVE },
444         { 0, 0 }
445 };
446
447 static u8 saa7113_init_regs[] = {
448         0x02, 0xd0,
449         0x03, 0x23,
450         0x04, 0x00,
451         0x05, 0x00,
452         0x06, 0xe9,
453         0x07, 0x0d,
454         0x08, 0x98,
455         0x09, 0x02,
456         0x0a, 0x80,
457         0x0b, 0x40,
458         0x0c, 0x40,
459         0x0d, 0x00,
460         0x0e, 0x01,
461         0x0f, 0x7c,
462         0x10, 0x48,
463         0x11, 0x0c,
464         0x12, 0x8b,
465         0x13, 0x1a,
466         0x14, 0x00,
467         0x15, 0x00,
468         0x16, 0x00,
469         0x17, 0x00,
470         0x18, 0x00,
471         0x19, 0x00,
472         0x1a, 0x00,
473         0x1b, 0x00,
474         0x1c, 0x00,
475         0x1d, 0x00,
476         0x1e, 0x00,
477
478         0x41, 0x77,
479         0x42, 0x77,
480         0x43, 0x77,
481         0x44, 0x77,
482         0x45, 0x77,
483         0x46, 0x77,
484         0x47, 0x77,
485         0x48, 0x77,
486         0x49, 0x77,
487         0x4a, 0x77,
488         0x4b, 0x77,
489         0x4c, 0x77,
490         0x4d, 0x77,
491         0x4e, 0x77,
492         0x4f, 0x77,
493         0x50, 0x77,
494         0x51, 0x77,
495         0x52, 0x77,
496         0x53, 0x77,
497         0x54, 0x77,
498         0x55, 0x77,
499         0x56, 0x77,
500         0x57, 0xff,
501
502         0xff
503 };
504
505
506 static struct saa7146_ext_vv av7110_vv_data_st;
507 static struct saa7146_ext_vv av7110_vv_data_c;
508
509 int av7110_init_analog_module(struct av7110 *av7110)
510 {
511         u16 version1, version2;
512
513         if (i2c_writereg(av7110, 0x80, 0x0, 0x80) != 1
514             || i2c_writereg(av7110, 0x80, 0x0, 0) != 1)
515                 return -ENODEV;
516
517         printk("av7110(%d): DVB-C analog module detected, initializing MSP3400\n",
518                 av7110->dvb_adapter->num);
519         av7110->adac_type = DVB_ADAC_MSP;
520         dvb_delay(100); // the probing above resets the msp...
521         msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
522         msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
523         printk("av7110(%d): MSP3400 version 0x%04x 0x%04x\n",
524                 av7110->dvb_adapter->num, version1, version2);
525         msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
526         msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
527         msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
528         msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
529         msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume
530         msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
531         msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
532         msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART
533
534         if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
535                 INFO(("saa7113 not accessible.\n"));
536         } else {
537                 u8 *i = saa7113_init_regs;
538                 av7110->has_analog_tuner = 1;
539                 /* init the saa7113 */
540                 while (*i != 0xff) {
541                         if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
542                                 printk("av7110(%d): saa7113 initialization failed",
543                                                 av7110->dvb_adapter->num);
544                                 break;
545                         }
546                         i += 2;
547                 }
548                 /* setup msp for analog sound: B/G Dual-FM */
549                 msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV
550                 msp_writereg(av7110, MSP_WR_DEM, 0x0001,  3); // FIR1
551                 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1
552                 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1
553                 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1
554                 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1
555                 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1
556                 msp_writereg(av7110, MSP_WR_DEM, 0x0005,  4); // FIR2
557                 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2
558                 msp_writereg(av7110, MSP_WR_DEM, 0x0005,  0); // FIR2
559                 msp_writereg(av7110, MSP_WR_DEM, 0x0005,  3); // FIR2
560                 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2
561                 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2
562                 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2
563                 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2
564                 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2
565                 msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG
566                 msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz
567                 msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI
568                 msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz
569                 msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI
570                 msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2
571         }
572
573         memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
574         /* set dd1 stream a & b */
575         saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
576         saa7146_write(av7110->dev, DD1_INIT, 0x03000700);
577         saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
578
579         return 0;
580 }
581
582 int av7110_init_v4l(struct av7110 *av7110)
583 {
584         struct saa7146_dev* dev = av7110->dev;
585         int ret;
586
587         /* special case DVB-C: these cards have an analog tuner
588            plus need some special handling, so we have separate
589            saa7146_ext_vv data for these... */
590         if (av7110->has_analog_tuner)
591                 ret = saa7146_vv_init(dev, &av7110_vv_data_c);
592         else
593                 ret = saa7146_vv_init(dev, &av7110_vv_data_st);
594
595         if (ret) {
596                 ERR(("cannot init capture device. skipping.\n"));
597                 return -ENODEV;
598         }
599
600         if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
601                 ERR(("cannot register capture device. skipping.\n"));
602                 saa7146_vv_release(dev);
603                 return -ENODEV;
604         }
605         if (av7110->has_analog_tuner) {
606                 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
607                         ERR(("cannot register vbi v4l2 device. skipping.\n"));
608                 } else
609                         /* we use this to remember that this dvb-c card can do vbi */
610                         av7110->has_analog_tuner = 2;
611         }
612         return 0;
613 }
614
615 int av7110_exit_v4l(struct av7110 *av7110)
616 {
617         saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
618         if (2 == av7110->has_analog_tuner)
619                 saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
620         return 0;
621 }
622
623
624
625 /* FIXME: these values are experimental values that look better than the
626    values from the latest "official" driver -- at least for me... (MiHu) */
627 static struct saa7146_standard standard[] = {
628         {
629                 .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
630                 .v_offset       = 0x15, .v_field        = 288,
631                 .h_offset       = 0x48, .h_pixels       = 708,
632                 .v_max_out      = 576,  .h_max_out      = 768,
633         }, {
634                 .name   = "NTSC",       .id             = V4L2_STD_NTSC,
635                 .v_offset       = 0x10, .v_field        = 244,
636                 .h_offset       = 0x40, .h_pixels       = 708,
637                 .v_max_out      = 480,  .h_max_out      = 640,
638         }
639 };
640
641 static struct saa7146_standard analog_standard[] = {
642         {
643                 .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
644                 .v_offset       = 0x1b, .v_field        = 288,
645                 .h_offset       = 0x08, .h_pixels       = 708,
646                 .v_max_out      = 576,  .h_max_out      = 768,
647         }, {
648                 .name   = "NTSC",       .id             = V4L2_STD_NTSC,
649                 .v_offset       = 0x10, .v_field        = 244,
650                 .h_offset       = 0x40, .h_pixels       = 708,
651                 .v_max_out      = 480,  .h_max_out      = 640,
652         }
653 };
654
655 static struct saa7146_standard dvb_standard[] = {
656         {
657                 .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
658                 .v_offset       = 0x14, .v_field        = 288,
659                 .h_offset       = 0x48, .h_pixels       = 708,
660                 .v_max_out      = 576,  .h_max_out      = 768,
661         }, {
662                 .name   = "NTSC",       .id             = V4L2_STD_NTSC,
663                 .v_offset       = 0x10, .v_field        = 244,
664                 .h_offset       = 0x40, .h_pixels       = 708,
665                 .v_max_out      = 480,  .h_max_out      = 640,
666         }
667 };
668
669 static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
670 {
671         struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
672
673         if (std->id == V4L2_STD_PAL) {
674                 av7110->vidmode = VIDEO_MODE_PAL;
675                 av7110_set_vidmode(av7110, av7110->vidmode);
676         }
677         else if (std->id == V4L2_STD_NTSC) {
678                 av7110->vidmode = VIDEO_MODE_NTSC;
679                 av7110_set_vidmode(av7110, av7110->vidmode);
680         }
681         else
682                 return -1;
683
684         return 0;
685 }
686
687
688 static struct saa7146_ext_vv av7110_vv_data_st = {
689         .inputs         = 1,
690         .audios         = 1,
691         .capabilities   = 0,
692         .flags          = 0,
693
694         .stds           = &standard[0],
695         .num_stds       = sizeof(standard) / sizeof(struct saa7146_standard),
696         .std_callback   = &std_callback,
697
698         .ioctls         = &ioctls[0],
699         .ioctl          = av7110_ioctl,
700 };
701
702 static struct saa7146_ext_vv av7110_vv_data_c = {
703         .inputs         = 1,
704         .audios         = 1,
705         .capabilities   = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
706         .flags          = SAA7146_USE_PORT_B_FOR_VBI,
707
708         .stds           = &standard[0],
709         .num_stds       = sizeof(standard) / sizeof(struct saa7146_standard),
710         .std_callback   = &std_callback,
711
712         .ioctls         = &ioctls[0],
713         .ioctl          = av7110_ioctl,
714 };
715