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