[ARM] Support register switch in nommu mode
[linux-2.6/verdex.git] / drivers / media / dvb / ttpci / av7110_v4l.c
blob94cf38c7e8a809f8f5cf5ce2bba99c9f160aea0d
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 static 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[4] = {
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,
90 }, {
91 .index = 2,
92 .name = "Video",
93 .type = V4L2_INPUT_TYPE_CAMERA,
94 .audioset = 0,
95 .tuner = 0,
96 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
97 .status = 0,
98 }, {
99 .index = 3,
100 .name = "Y/C",
101 .type = V4L2_INPUT_TYPE_CAMERA,
102 .audioset = 0,
103 .tuner = 0,
104 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
105 .status = 0,
109 static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
111 u8 buf[] = { 0x00, reg, data };
112 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
114 dprintk(4, "dev: %p\n", dev);
116 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
117 return -1;
118 return 0;
121 static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
123 u8 buf [] = { reg, data };
124 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 };
126 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
127 return -1;
128 return 0;
132 static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
134 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
136 dprintk(4, "dev: %p\n", dev);
138 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
139 return -1;
140 return 0;
143 static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
145 u32 div;
146 u8 config;
147 u8 buf[4];
149 dprintk(4, "freq: 0x%08x\n", freq);
151 /* magic number: 614. tuning with the frequency given by v4l2
152 is always off by 614*62.5 = 38375 kHz...*/
153 div = freq + 614;
155 buf[0] = (div >> 8) & 0x7f;
156 buf[1] = div & 0xff;
157 buf[2] = 0x8e;
159 if (freq < (u32) (16 * 168.25))
160 config = 0xa0;
161 else if (freq < (u32) (16 * 447.25))
162 config = 0x90;
163 else
164 config = 0x30;
165 config &= ~0x02;
167 buf[3] = config;
169 return tuner_write(dev, 0x61, buf);
172 static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
174 u32 div;
175 u8 data[4];
177 div = (freq + 38900000 + 31250) / 62500;
179 data[0] = (div >> 8) & 0x7f;
180 data[1] = div & 0xff;
181 data[2] = 0xce;
183 if (freq < 45000000)
184 return -EINVAL;
185 else if (freq < 137000000)
186 data[3] = 0x01;
187 else if (freq < 403000000)
188 data[3] = 0x02;
189 else if (freq < 860000000)
190 data[3] = 0x04;
191 else
192 return -EINVAL;
194 stv0297_writereg(dev, 0x1C, 0x87, 0x78);
195 stv0297_writereg(dev, 0x1C, 0x86, 0xc8);
196 return tuner_write(dev, 0x63, data);
201 static struct saa7146_standard analog_standard[];
202 static struct saa7146_standard dvb_standard[];
203 static struct saa7146_standard standard[];
205 static struct v4l2_audio msp3400_v4l2_audio = {
206 .index = 0,
207 .name = "Television",
208 .capability = V4L2_AUDCAP_STEREO
211 static int av7110_dvb_c_switch(struct saa7146_fh *fh)
213 struct saa7146_dev *dev = fh->dev;
214 struct saa7146_vv *vv = dev->vv_data;
215 struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
216 u16 adswitch;
217 int source, sync, err;
219 dprintk(4, "%p\n", av7110);
221 if ((vv->video_status & STATUS_OVERLAY) != 0) {
222 vv->ov_suspend = vv->video_fh;
223 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
224 if (err != 0) {
225 dprintk(2, "suspending video failed\n");
226 vv->ov_suspend = NULL;
230 if (0 != av7110->current_input) {
231 dprintk(1, "switching to analog TV:\n");
232 adswitch = 1;
233 source = SAA7146_HPS_SOURCE_PORT_B;
234 sync = SAA7146_HPS_SYNC_PORT_B;
235 memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
237 switch (av7110->current_input) {
238 case 1:
239 dprintk(1, "switching SAA7113 to Analog Tuner Input.\n");
240 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
241 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
242 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
243 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
244 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
245 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
247 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
248 if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
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_OUTHI); // TDA9198 pin9(STD)
252 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
254 if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1)
255 dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
256 break;
257 case 2:
258 dprintk(1, "switching SAA7113 to Video AV CVBS Input.\n");
259 if (i2c_writereg(av7110, 0x48, 0x02, 0xd2) != 1)
260 dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
261 break;
262 case 3:
263 dprintk(1, "switching SAA7113 to Video AV Y/C Input.\n");
264 if (i2c_writereg(av7110, 0x48, 0x02, 0xd9) != 1)
265 dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
266 break;
267 default:
268 dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input.\n");
270 } else {
271 adswitch = 0;
272 source = SAA7146_HPS_SOURCE_PORT_A;
273 sync = SAA7146_HPS_SYNC_PORT_A;
274 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
275 dprintk(1, "switching DVB mode\n");
276 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
277 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
278 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
279 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
280 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
281 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
283 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
284 if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
285 dprintk(1, "setting band in demodulator failed.\n");
286 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
287 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
288 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
292 /* hmm, this does not do anything!? */
293 if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
294 dprintk(1, "ADSwitch error\n");
296 saa7146_set_hps_source_and_sync(dev, source, sync);
298 if (vv->ov_suspend != NULL) {
299 saa7146_start_preview(vv->ov_suspend);
300 vv->ov_suspend = NULL;
303 return 0;
306 static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
308 struct saa7146_dev *dev = fh->dev;
309 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
310 dprintk(4, "saa7146_dev: %p\n", dev);
312 switch (cmd) {
313 case VIDIOC_G_TUNER:
315 struct v4l2_tuner *t = arg;
316 u16 stereo_det;
317 s8 stereo;
319 dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
321 if (!av7110->analog_tuner_flags || t->index != 0)
322 return -EINVAL;
324 memset(t, 0, sizeof(*t));
325 strcpy(t->name, "Television");
327 t->type = V4L2_TUNER_ANALOG_TV;
328 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
329 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
330 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
331 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
332 /* FIXME: add the real signal strength here */
333 t->signal = 0xffff;
334 t->afc = 0;
336 // FIXME: standard / stereo detection is still broken
337 msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
338 dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
339 msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
340 dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
341 stereo = (s8)(stereo_det >> 8);
342 if (stereo > 0x10) {
343 /* stereo */
344 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
345 t->audmode = V4L2_TUNER_MODE_STEREO;
347 else if (stereo < -0x10) {
348 /* bilingual */
349 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
350 t->audmode = V4L2_TUNER_MODE_LANG1;
352 else /* mono */
353 t->rxsubchans = V4L2_TUNER_SUB_MONO;
355 return 0;
357 case VIDIOC_S_TUNER:
359 struct v4l2_tuner *t = arg;
360 u16 fm_matrix, src;
361 dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
363 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
364 return -EINVAL;
366 switch (t->audmode) {
367 case V4L2_TUNER_MODE_STEREO:
368 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
369 fm_matrix = 0x3001; // stereo
370 src = 0x0020;
371 break;
372 case V4L2_TUNER_MODE_LANG1:
373 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
374 fm_matrix = 0x3000; // mono
375 src = 0x0000;
376 break;
377 case V4L2_TUNER_MODE_LANG2:
378 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
379 fm_matrix = 0x3000; // mono
380 src = 0x0010;
381 break;
382 default: /* case V4L2_TUNER_MODE_MONO: */
383 dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
384 fm_matrix = 0x3000; // mono
385 src = 0x0030;
386 break;
388 msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
389 msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
390 msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
391 msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
392 return 0;
394 case VIDIOC_G_FREQUENCY:
396 struct v4l2_frequency *f = arg;
398 dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
400 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
401 return -EINVAL;
403 memset(f, 0, sizeof(*f));
404 f->type = V4L2_TUNER_ANALOG_TV;
405 f->frequency = av7110->current_freq;
406 return 0;
408 case VIDIOC_S_FREQUENCY:
410 struct v4l2_frequency *f = arg;
412 dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
414 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
415 return -EINVAL;
417 if (V4L2_TUNER_ANALOG_TV != f->type)
418 return -EINVAL;
420 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
421 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
423 /* tune in desired frequency */
424 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
425 ves1820_set_tv_freq(dev, f->frequency);
426 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
427 stv0297_set_tv_freq(dev, f->frequency);
429 av7110->current_freq = f->frequency;
431 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
432 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
433 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
434 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
435 return 0;
437 case VIDIOC_ENUMINPUT:
439 struct v4l2_input *i = arg;
441 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
443 if (av7110->analog_tuner_flags) {
444 if (i->index < 0 || i->index >= 4)
445 return -EINVAL;
446 } else {
447 if (i->index != 0)
448 return -EINVAL;
451 memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
453 return 0;
455 case VIDIOC_G_INPUT:
457 int *input = (int *)arg;
458 *input = av7110->current_input;
459 dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
460 return 0;
462 case VIDIOC_S_INPUT:
464 int input = *(int *)arg;
466 dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
468 if (!av7110->analog_tuner_flags)
469 return 0;
471 if (input < 0 || input >= 4)
472 return -EINVAL;
474 av7110->current_input = input;
475 return av7110_dvb_c_switch(fh);
477 case VIDIOC_G_AUDIO:
479 struct v4l2_audio *a = arg;
481 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
482 if (a->index != 0)
483 return -EINVAL;
484 memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
485 break;
487 case VIDIOC_S_AUDIO:
489 struct v4l2_audio *a = arg;
490 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
491 break;
493 case VIDIOC_G_SLICED_VBI_CAP:
495 struct v4l2_sliced_vbi_cap *cap = arg;
496 dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
497 memset(cap, 0, sizeof *cap);
498 if (FW_VERSION(av7110->arm_app) >= 0x2623) {
499 cap->service_set = V4L2_SLICED_WSS_625;
500 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
502 break;
504 case VIDIOC_G_FMT:
506 struct v4l2_format *f = arg;
507 dprintk(2, "VIDIOC_G_FMT:\n");
508 if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
509 FW_VERSION(av7110->arm_app) < 0x2623)
510 return -EAGAIN; /* handled by core driver */
511 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
512 if (av7110->wssMode) {
513 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
514 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
515 f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
517 break;
519 case VIDIOC_S_FMT:
521 struct v4l2_format *f = arg;
522 dprintk(2, "VIDIOC_S_FMT\n");
523 if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
524 FW_VERSION(av7110->arm_app) < 0x2623)
525 return -EAGAIN; /* handled by core driver */
526 if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
527 f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
528 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
529 /* WSS controlled by firmware */
530 av7110->wssMode = 0;
531 av7110->wssData = 0;
532 return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
533 SetWSSConfig, 1, 0);
534 } else {
535 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
536 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
537 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
538 f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
539 /* WSS controlled by userspace */
540 av7110->wssMode = 1;
541 av7110->wssData = 0;
543 break;
545 default:
546 printk("no such ioctl\n");
547 return -ENOIOCTLCMD;
549 return 0;
552 static int av7110_vbi_reset(struct inode *inode, struct file *file)
554 struct saa7146_fh *fh = file->private_data;
555 struct saa7146_dev *dev = fh->dev;
556 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
558 dprintk(2, "%s\n", __FUNCTION__);
559 av7110->wssMode = 0;
560 av7110->wssData = 0;
561 if (FW_VERSION(av7110->arm_app) < 0x2623)
562 return 0;
563 else
564 return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
567 static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
569 struct saa7146_fh *fh = file->private_data;
570 struct saa7146_dev *dev = fh->dev;
571 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
572 struct v4l2_sliced_vbi_data d;
573 int rc;
575 dprintk(2, "%s\n", __FUNCTION__);
576 if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d)
577 return -EINVAL;
578 if (copy_from_user(&d, data, count))
579 return -EFAULT;
580 if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23)
581 return -EINVAL;
582 if (d.id) {
583 av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0];
584 rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig,
585 2, 1, av7110->wssData);
586 } else {
587 av7110->wssData = 0;
588 rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
590 return (rc < 0) ? rc : count;
593 /****************************************************************************
594 * INITIALIZATION
595 ****************************************************************************/
597 static struct saa7146_extension_ioctls ioctls[] = {
598 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
599 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
600 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
601 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
602 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
603 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
604 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
605 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
606 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
607 { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE },
608 { VIDIOC_G_FMT, SAA7146_BEFORE },
609 { VIDIOC_S_FMT, SAA7146_BEFORE },
610 { 0, 0 }
613 static u8 saa7113_init_regs[] = {
614 0x02, 0xd0,
615 0x03, 0x23,
616 0x04, 0x00,
617 0x05, 0x00,
618 0x06, 0xe9,
619 0x07, 0x0d,
620 0x08, 0x98,
621 0x09, 0x02,
622 0x0a, 0x80,
623 0x0b, 0x40,
624 0x0c, 0x40,
625 0x0d, 0x00,
626 0x0e, 0x01,
627 0x0f, 0x7c,
628 0x10, 0x48,
629 0x11, 0x0c,
630 0x12, 0x8b,
631 0x13, 0x1a,
632 0x14, 0x00,
633 0x15, 0x00,
634 0x16, 0x00,
635 0x17, 0x00,
636 0x18, 0x00,
637 0x19, 0x00,
638 0x1a, 0x00,
639 0x1b, 0x00,
640 0x1c, 0x00,
641 0x1d, 0x00,
642 0x1e, 0x00,
644 0x41, 0x77,
645 0x42, 0x77,
646 0x43, 0x77,
647 0x44, 0x77,
648 0x45, 0x77,
649 0x46, 0x77,
650 0x47, 0x77,
651 0x48, 0x77,
652 0x49, 0x77,
653 0x4a, 0x77,
654 0x4b, 0x77,
655 0x4c, 0x77,
656 0x4d, 0x77,
657 0x4e, 0x77,
658 0x4f, 0x77,
659 0x50, 0x77,
660 0x51, 0x77,
661 0x52, 0x77,
662 0x53, 0x77,
663 0x54, 0x77,
664 0x55, 0x77,
665 0x56, 0x77,
666 0x57, 0xff,
668 0xff
672 static struct saa7146_ext_vv av7110_vv_data_st;
673 static struct saa7146_ext_vv av7110_vv_data_c;
675 int av7110_init_analog_module(struct av7110 *av7110)
677 u16 version1, version2;
679 if (i2c_writereg(av7110, 0x80, 0x0, 0x80) != 1
680 || i2c_writereg(av7110, 0x80, 0x0, 0) != 1)
681 return -ENODEV;
683 printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n",
684 av7110->dvb_adapter.num);
685 av7110->adac_type = DVB_ADAC_MSP34x0;
686 msleep(100); // the probing above resets the msp...
687 msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
688 msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
689 dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n",
690 av7110->dvb_adapter.num, version1, version2);
691 msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
692 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
693 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
694 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
695 msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume
696 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
697 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
698 msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART
700 if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
701 INFO(("saa7113 not accessible.\n"));
702 } else {
703 u8 *i = saa7113_init_regs;
705 if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
706 /* Fujitsu/Siemens DVB-Cable */
707 av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
708 } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
709 /* Hauppauge/TT DVB-C premium */
710 av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
711 } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
712 /* Hauppauge/TT DVB-C premium */
713 av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
716 /* setup for DVB by default */
717 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
718 if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
719 dprintk(1, "setting band in demodulator failed.\n");
720 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
721 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
722 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
725 /* init the saa7113 */
726 while (*i != 0xff) {
727 if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
728 dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter.num);
729 break;
731 i += 2;
733 /* setup msp for analog sound: B/G Dual-FM */
734 msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV
735 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 3); // FIR1
736 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1
737 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1
738 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1
739 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1
740 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1
741 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 4); // FIR2
742 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2
743 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 0); // FIR2
744 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 3); // FIR2
745 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2
746 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2
747 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2
748 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2
749 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2
750 msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG
751 msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz
752 msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI
753 msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz
754 msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI
755 msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2
758 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
759 /* set dd1 stream a & b */
760 saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
761 saa7146_write(av7110->dev, DD1_INIT, 0x03000700);
762 saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
764 return 0;
767 int av7110_init_v4l(struct av7110 *av7110)
769 struct saa7146_dev* dev = av7110->dev;
770 int ret;
772 /* special case DVB-C: these cards have an analog tuner
773 plus need some special handling, so we have separate
774 saa7146_ext_vv data for these... */
775 if (av7110->analog_tuner_flags)
776 ret = saa7146_vv_init(dev, &av7110_vv_data_c);
777 else
778 ret = saa7146_vv_init(dev, &av7110_vv_data_st);
780 if (ret) {
781 ERR(("cannot init capture device. skipping.\n"));
782 return -ENODEV;
785 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
786 ERR(("cannot register capture device. skipping.\n"));
787 saa7146_vv_release(dev);
788 return -ENODEV;
790 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
791 ERR(("cannot register vbi v4l2 device. skipping.\n"));
792 } else {
793 if (av7110->analog_tuner_flags)
794 av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
796 return 0;
799 int av7110_exit_v4l(struct av7110 *av7110)
801 saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
802 if (av7110->analog_tuner_flags & ANALOG_TUNER_VBI)
803 saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
804 return 0;
809 /* FIXME: these values are experimental values that look better than the
810 values from the latest "official" driver -- at least for me... (MiHu) */
811 static struct saa7146_standard standard[] = {
813 .name = "PAL", .id = V4L2_STD_PAL_BG,
814 .v_offset = 0x15, .v_field = 288,
815 .h_offset = 0x48, .h_pixels = 708,
816 .v_max_out = 576, .h_max_out = 768,
817 }, {
818 .name = "NTSC", .id = V4L2_STD_NTSC,
819 .v_offset = 0x10, .v_field = 244,
820 .h_offset = 0x40, .h_pixels = 708,
821 .v_max_out = 480, .h_max_out = 640,
825 static struct saa7146_standard analog_standard[] = {
827 .name = "PAL", .id = V4L2_STD_PAL_BG,
828 .v_offset = 0x1b, .v_field = 288,
829 .h_offset = 0x08, .h_pixels = 708,
830 .v_max_out = 576, .h_max_out = 768,
831 }, {
832 .name = "NTSC", .id = V4L2_STD_NTSC,
833 .v_offset = 0x10, .v_field = 244,
834 .h_offset = 0x40, .h_pixels = 708,
835 .v_max_out = 480, .h_max_out = 640,
839 static struct saa7146_standard dvb_standard[] = {
841 .name = "PAL", .id = V4L2_STD_PAL_BG,
842 .v_offset = 0x14, .v_field = 288,
843 .h_offset = 0x48, .h_pixels = 708,
844 .v_max_out = 576, .h_max_out = 768,
845 }, {
846 .name = "NTSC", .id = V4L2_STD_NTSC,
847 .v_offset = 0x10, .v_field = 244,
848 .h_offset = 0x40, .h_pixels = 708,
849 .v_max_out = 480, .h_max_out = 640,
853 static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
855 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
857 if (std->id & V4L2_STD_PAL) {
858 av7110->vidmode = VIDEO_MODE_PAL;
859 av7110_set_vidmode(av7110, av7110->vidmode);
861 else if (std->id & V4L2_STD_NTSC) {
862 av7110->vidmode = VIDEO_MODE_NTSC;
863 av7110_set_vidmode(av7110, av7110->vidmode);
865 else
866 return -1;
868 return 0;
872 static struct saa7146_ext_vv av7110_vv_data_st = {
873 .inputs = 1,
874 .audios = 1,
875 .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT,
876 .flags = 0,
878 .stds = &standard[0],
879 .num_stds = ARRAY_SIZE(standard),
880 .std_callback = &std_callback,
882 .ioctls = &ioctls[0],
883 .ioctl = av7110_ioctl,
885 .vbi_fops.open = av7110_vbi_reset,
886 .vbi_fops.release = av7110_vbi_reset,
887 .vbi_fops.write = av7110_vbi_write,
890 static struct saa7146_ext_vv av7110_vv_data_c = {
891 .inputs = 1,
892 .audios = 1,
893 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT,
894 .flags = SAA7146_USE_PORT_B_FOR_VBI,
896 .stds = &standard[0],
897 .num_stds = ARRAY_SIZE(standard),
898 .std_callback = &std_callback,
900 .ioctls = &ioctls[0],
901 .ioctl = av7110_ioctl,
903 .vbi_fops.open = av7110_vbi_reset,
904 .vbi_fops.release = av7110_vbi_reset,
905 .vbi_fops.write = av7110_vbi_write,