Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / dvb / ttpci / av7110_v4l.c
blobeb84fb08d95cdd0926c20758e5ec7de800604e88
1 /*
2 * av7110_v4l.c: av7110 video4linux interface for DVB and Siemens DVB-C analog module
4 * Copyright (C) 1999-2002 Ralph Metzler
5 * & Marcus Metzler for convergence integrated media GmbH
7 * originally based on code by:
8 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
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.
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.
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
25 * the project's page is at http://www.linuxtv.org/dvb/
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>
38 #include "av7110.h"
39 #include "av7110_hw.h"
40 #include "av7110_av.h"
42 int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
44 u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
45 struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg };
47 if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
48 dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
49 av7110->dvb_adapter->num, reg, val);
50 return -EIO;
52 return 0;
55 int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
57 u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
58 u8 msg2[2];
59 struct i2c_msg msgs[2] = {
60 { .flags = 0, .addr = 0x40, .len = 3, .buf = msg1 },
61 { .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 }
64 if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
65 dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
66 av7110->dvb_adapter->num, reg);
67 return -EIO;
69 *val = (msg2[0] << 8) | msg2[1];
70 return 0;
73 static struct v4l2_input inputs[2] = {
75 .index = 0,
76 .name = "DVB",
77 .type = V4L2_INPUT_TYPE_CAMERA,
78 .audioset = 1,
79 .tuner = 0, /* ignored */
80 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
81 .status = 0,
82 }, {
83 .index = 1,
84 .name = "Television",
85 .type = V4L2_INPUT_TYPE_TUNER,
86 .audioset = 2,
87 .tuner = 0,
88 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
89 .status = 0,
93 static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
95 u8 buf[] = { 0x00, reg, data };
96 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
98 dprintk(4, "dev: %p\n", dev);
100 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
101 return -1;
102 return 0;
105 static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
107 u8 buf [] = { reg, data };
108 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 };
110 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
111 return -1;
112 return 0;
116 static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
118 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
120 dprintk(4, "dev: %p\n", dev);
122 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
123 return -1;
124 return 0;
127 static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
129 u32 div;
130 u8 config;
131 u8 buf[4];
133 dprintk(4, "freq: 0x%08x\n", freq);
135 /* magic number: 614. tuning with the frequency given by v4l2
136 is always off by 614*62.5 = 38375 kHz...*/
137 div = freq + 614;
139 buf[0] = (div >> 8) & 0x7f;
140 buf[1] = div & 0xff;
141 buf[2] = 0x8e;
143 if (freq < (u32) (16 * 168.25))
144 config = 0xa0;
145 else if (freq < (u32) (16 * 447.25))
146 config = 0x90;
147 else
148 config = 0x30;
149 config &= ~0x02;
151 buf[3] = config;
153 return tuner_write(dev, 0x61, buf);
156 static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
158 u32 div;
159 u8 data[4];
161 div = (freq + 38900000 + 31250) / 62500;
163 data[0] = (div >> 8) & 0x7f;
164 data[1] = div & 0xff;
165 data[2] = 0xce;
167 if (freq < 45000000)
168 return -EINVAL;
169 else if (freq < 137000000)
170 data[3] = 0x01;
171 else if (freq < 403000000)
172 data[3] = 0x02;
173 else if (freq < 860000000)
174 data[3] = 0x04;
175 else
176 return -EINVAL;
178 stv0297_writereg(dev, 0x1C, 0x87, 0x78);
179 stv0297_writereg(dev, 0x1C, 0x86, 0xc8);
180 return tuner_write(dev, 0x63, data);
185 static struct saa7146_standard analog_standard[];
186 static struct saa7146_standard dvb_standard[];
187 static struct saa7146_standard standard[];
189 static struct v4l2_audio msp3400_v4l2_audio = {
190 .index = 0,
191 .name = "Television",
192 .capability = V4L2_AUDCAP_STEREO
195 static int av7110_dvb_c_switch(struct saa7146_fh *fh)
197 struct saa7146_dev *dev = fh->dev;
198 struct saa7146_vv *vv = dev->vv_data;
199 struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
200 u16 adswitch;
201 int source, sync, err;
203 dprintk(4, "%p\n", av7110);
205 if ((vv->video_status & STATUS_OVERLAY) != 0) {
206 vv->ov_suspend = vv->video_fh;
207 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
208 if (err != 0) {
209 dprintk(2, "suspending video failed\n");
210 vv->ov_suspend = NULL;
214 if (0 != av7110->current_input) {
215 adswitch = 1;
216 source = SAA7146_HPS_SOURCE_PORT_B;
217 sync = SAA7146_HPS_SYNC_PORT_B;
218 memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
219 dprintk(1, "switching to analog TV\n");
220 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
221 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
222 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
223 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
224 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
225 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
227 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
228 if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
229 dprintk(1, "setting band in demodulator failed.\n");
230 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
231 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
232 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
234 } else {
235 adswitch = 0;
236 source = SAA7146_HPS_SOURCE_PORT_A;
237 sync = SAA7146_HPS_SYNC_PORT_A;
238 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
239 dprintk(1, "switching DVB mode\n");
240 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
241 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
242 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
243 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
244 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
245 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
247 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
248 if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
249 dprintk(1, "setting band in demodulator failed.\n");
250 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
251 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
252 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
256 /* hmm, this does not do anything!? */
257 if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
258 dprintk(1, "ADSwitch error\n");
260 saa7146_set_hps_source_and_sync(dev, source, sync);
262 if (vv->ov_suspend != NULL) {
263 saa7146_start_preview(vv->ov_suspend);
264 vv->ov_suspend = NULL;
267 return 0;
270 static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
272 struct saa7146_dev *dev = fh->dev;
273 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
274 dprintk(4, "saa7146_dev: %p\n", dev);
276 switch (cmd) {
277 case VIDIOC_G_TUNER:
279 struct v4l2_tuner *t = arg;
280 u16 stereo_det;
281 s8 stereo;
283 dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
285 if (!av7110->analog_tuner_flags || t->index != 0)
286 return -EINVAL;
288 memset(t, 0, sizeof(*t));
289 strcpy(t->name, "Television");
291 t->type = V4L2_TUNER_ANALOG_TV;
292 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
293 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
294 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
295 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
296 /* FIXME: add the real signal strength here */
297 t->signal = 0xffff;
298 t->afc = 0;
300 // FIXME: standard / stereo detection is still broken
301 msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
302 dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
304 msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
305 dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
306 stereo = (s8)(stereo_det >> 8);
307 if (stereo > 0x10) {
308 /* stereo */
309 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
310 t->audmode = V4L2_TUNER_MODE_STEREO;
312 else if (stereo < -0x10) {
313 /* bilingual*/
314 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
315 t->audmode = V4L2_TUNER_MODE_LANG1;
317 else /* mono */
318 t->rxsubchans = V4L2_TUNER_SUB_MONO;
320 return 0;
322 case VIDIOC_S_TUNER:
324 struct v4l2_tuner *t = arg;
325 u16 fm_matrix, src;
326 dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
328 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
329 return -EINVAL;
331 switch (t->audmode) {
332 case V4L2_TUNER_MODE_STEREO:
333 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
334 fm_matrix = 0x3001; // stereo
335 src = 0x0020;
336 break;
337 case V4L2_TUNER_MODE_LANG1:
338 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
339 fm_matrix = 0x3000; // mono
340 src = 0x0000;
341 break;
342 case V4L2_TUNER_MODE_LANG2:
343 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
344 fm_matrix = 0x3000; // mono
345 src = 0x0010;
346 break;
347 default: /* case V4L2_TUNER_MODE_MONO: {*/
348 dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
349 fm_matrix = 0x3000; // mono
350 src = 0x0030;
351 break;
353 msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
354 msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
355 msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
356 msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
357 return 0;
359 case VIDIOC_G_FREQUENCY:
361 struct v4l2_frequency *f = arg;
363 dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
365 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
366 return -EINVAL;
368 memset(f, 0, sizeof(*f));
369 f->type = V4L2_TUNER_ANALOG_TV;
370 f->frequency = av7110->current_freq;
371 return 0;
373 case VIDIOC_S_FREQUENCY:
375 struct v4l2_frequency *f = arg;
377 dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
379 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
380 return -EINVAL;
382 if (V4L2_TUNER_ANALOG_TV != f->type)
383 return -EINVAL;
385 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
386 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
388 /* tune in desired frequency */
389 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
390 ves1820_set_tv_freq(dev, f->frequency);
391 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
392 stv0297_set_tv_freq(dev, f->frequency);
394 av7110->current_freq = f->frequency;
396 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
397 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
398 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
399 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
400 return 0;
402 case VIDIOC_ENUMINPUT:
404 struct v4l2_input *i = arg;
406 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
408 if (av7110->analog_tuner_flags) {
409 if (i->index < 0 || i->index >= 2)
410 return -EINVAL;
411 } else {
412 if (i->index != 0)
413 return -EINVAL;
416 memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
418 return 0;
420 case VIDIOC_G_INPUT:
422 int *input = (int *)arg;
423 *input = av7110->current_input;
424 dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
425 return 0;
427 case VIDIOC_S_INPUT:
429 int input = *(int *)arg;
431 dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
433 if (!av7110->analog_tuner_flags)
434 return 0;
436 if (input < 0 || input >= 2)
437 return -EINVAL;
439 /* FIXME: switch inputs here */
440 av7110->current_input = input;
441 return av7110_dvb_c_switch(fh);
443 case VIDIOC_G_AUDIO:
445 struct v4l2_audio *a = arg;
447 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
448 if (a->index != 0)
449 return -EINVAL;
450 memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
451 break;
453 case VIDIOC_S_AUDIO:
455 struct v4l2_audio *a = arg;
456 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
457 break;
459 default:
460 printk("no such ioctl\n");
461 return -ENOIOCTLCMD;
463 return 0;
467 /****************************************************************************
468 * INITIALIZATION
469 ****************************************************************************/
471 static struct saa7146_extension_ioctls ioctls[] = {
472 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
473 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
474 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
475 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
476 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
477 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
478 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
479 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
480 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
481 { 0, 0 }
484 static u8 saa7113_init_regs[] = {
485 0x02, 0xd0,
486 0x03, 0x23,
487 0x04, 0x00,
488 0x05, 0x00,
489 0x06, 0xe9,
490 0x07, 0x0d,
491 0x08, 0x98,
492 0x09, 0x02,
493 0x0a, 0x80,
494 0x0b, 0x40,
495 0x0c, 0x40,
496 0x0d, 0x00,
497 0x0e, 0x01,
498 0x0f, 0x7c,
499 0x10, 0x48,
500 0x11, 0x0c,
501 0x12, 0x8b,
502 0x13, 0x1a,
503 0x14, 0x00,
504 0x15, 0x00,
505 0x16, 0x00,
506 0x17, 0x00,
507 0x18, 0x00,
508 0x19, 0x00,
509 0x1a, 0x00,
510 0x1b, 0x00,
511 0x1c, 0x00,
512 0x1d, 0x00,
513 0x1e, 0x00,
515 0x41, 0x77,
516 0x42, 0x77,
517 0x43, 0x77,
518 0x44, 0x77,
519 0x45, 0x77,
520 0x46, 0x77,
521 0x47, 0x77,
522 0x48, 0x77,
523 0x49, 0x77,
524 0x4a, 0x77,
525 0x4b, 0x77,
526 0x4c, 0x77,
527 0x4d, 0x77,
528 0x4e, 0x77,
529 0x4f, 0x77,
530 0x50, 0x77,
531 0x51, 0x77,
532 0x52, 0x77,
533 0x53, 0x77,
534 0x54, 0x77,
535 0x55, 0x77,
536 0x56, 0x77,
537 0x57, 0xff,
539 0xff
543 static struct saa7146_ext_vv av7110_vv_data_st;
544 static struct saa7146_ext_vv av7110_vv_data_c;
546 int av7110_init_analog_module(struct av7110 *av7110)
548 u16 version1, version2;
550 if (i2c_writereg(av7110, 0x80, 0x0, 0x80) != 1
551 || i2c_writereg(av7110, 0x80, 0x0, 0) != 1)
552 return -ENODEV;
554 printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n",
555 av7110->dvb_adapter->num);
556 av7110->adac_type = DVB_ADAC_MSP;
557 msleep(100); // the probing above resets the msp...
558 msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
559 msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
560 dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n",
561 av7110->dvb_adapter->num, version1, version2);
562 msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
563 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
564 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
565 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
566 msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume
567 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
568 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
569 msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART
571 if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
572 INFO(("saa7113 not accessible.\n"));
573 } else {
574 u8 *i = saa7113_init_regs;
576 if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
577 /* Fujitsu/Siemens DVB-Cable */
578 av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
579 } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
580 /* Hauppauge/TT DVB-C premium */
581 av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
582 } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
583 /* Hauppauge/TT DVB-C premium */
584 av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
587 /* setup for DVB by default */
588 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
589 if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
590 dprintk(1, "setting band in demodulator failed.\n");
591 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
592 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
593 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
596 /* init the saa7113 */
597 while (*i != 0xff) {
598 if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
599 dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter->num);
600 break;
602 i += 2;
604 /* setup msp for analog sound: B/G Dual-FM */
605 msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV
606 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 3); // FIR1
607 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1
608 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1
609 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1
610 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1
611 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1
612 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 4); // FIR2
613 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2
614 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 0); // FIR2
615 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 3); // FIR2
616 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2
617 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2
618 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2
619 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2
620 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2
621 msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG
622 msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz
623 msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI
624 msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz
625 msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI
626 msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2
629 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
630 /* set dd1 stream a & b */
631 saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
632 saa7146_write(av7110->dev, DD1_INIT, 0x03000700);
633 saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
635 return 0;
638 int av7110_init_v4l(struct av7110 *av7110)
640 struct saa7146_dev* dev = av7110->dev;
641 int ret;
643 /* special case DVB-C: these cards have an analog tuner
644 plus need some special handling, so we have separate
645 saa7146_ext_vv data for these... */
646 if (av7110->analog_tuner_flags)
647 ret = saa7146_vv_init(dev, &av7110_vv_data_c);
648 else
649 ret = saa7146_vv_init(dev, &av7110_vv_data_st);
651 if (ret) {
652 ERR(("cannot init capture device. skipping.\n"));
653 return -ENODEV;
656 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
657 ERR(("cannot register capture device. skipping.\n"));
658 saa7146_vv_release(dev);
659 return -ENODEV;
661 if (av7110->analog_tuner_flags) {
662 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
663 ERR(("cannot register vbi v4l2 device. skipping.\n"));
664 } else {
665 av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
668 return 0;
671 int av7110_exit_v4l(struct av7110 *av7110)
673 saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
674 if (av7110->analog_tuner_flags & ANALOG_TUNER_VBI)
675 saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
676 return 0;
681 /* FIXME: these values are experimental values that look better than the
682 values from the latest "official" driver -- at least for me... (MiHu) */
683 static struct saa7146_standard standard[] = {
685 .name = "PAL", .id = V4L2_STD_PAL_BG,
686 .v_offset = 0x15, .v_field = 288,
687 .h_offset = 0x48, .h_pixels = 708,
688 .v_max_out = 576, .h_max_out = 768,
689 }, {
690 .name = "NTSC", .id = V4L2_STD_NTSC,
691 .v_offset = 0x10, .v_field = 244,
692 .h_offset = 0x40, .h_pixels = 708,
693 .v_max_out = 480, .h_max_out = 640,
697 static struct saa7146_standard analog_standard[] = {
699 .name = "PAL", .id = V4L2_STD_PAL_BG,
700 .v_offset = 0x1b, .v_field = 288,
701 .h_offset = 0x08, .h_pixels = 708,
702 .v_max_out = 576, .h_max_out = 768,
703 }, {
704 .name = "NTSC", .id = V4L2_STD_NTSC,
705 .v_offset = 0x10, .v_field = 244,
706 .h_offset = 0x40, .h_pixels = 708,
707 .v_max_out = 480, .h_max_out = 640,
711 static struct saa7146_standard dvb_standard[] = {
713 .name = "PAL", .id = V4L2_STD_PAL_BG,
714 .v_offset = 0x14, .v_field = 288,
715 .h_offset = 0x48, .h_pixels = 708,
716 .v_max_out = 576, .h_max_out = 768,
717 }, {
718 .name = "NTSC", .id = V4L2_STD_NTSC,
719 .v_offset = 0x10, .v_field = 244,
720 .h_offset = 0x40, .h_pixels = 708,
721 .v_max_out = 480, .h_max_out = 640,
725 static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
727 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
729 if (std->id == V4L2_STD_PAL) {
730 av7110->vidmode = VIDEO_MODE_PAL;
731 av7110_set_vidmode(av7110, av7110->vidmode);
733 else if (std->id == V4L2_STD_NTSC) {
734 av7110->vidmode = VIDEO_MODE_NTSC;
735 av7110_set_vidmode(av7110, av7110->vidmode);
737 else
738 return -1;
740 return 0;
744 static struct saa7146_ext_vv av7110_vv_data_st = {
745 .inputs = 1,
746 .audios = 1,
747 .capabilities = 0,
748 .flags = 0,
750 .stds = &standard[0],
751 .num_stds = ARRAY_SIZE(standard),
752 .std_callback = &std_callback,
754 .ioctls = &ioctls[0],
755 .ioctl = av7110_ioctl,
758 static struct saa7146_ext_vv av7110_vv_data_c = {
759 .inputs = 1,
760 .audios = 1,
761 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
762 .flags = SAA7146_USE_PORT_B_FOR_VBI,
764 .stds = &standard[0],
765 .num_stds = ARRAY_SIZE(standard),
766 .std_callback = &std_callback,
768 .ioctls = &ioctls[0],
769 .ioctl = av7110_ioctl,