[media] v4l2: add const to argument of write-only s_frequency ioctl
[deliverable/linux.git] / drivers / media / pci / ttpci / av7110_v4l.c
CommitLineData
1da177e4
LT
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 *
631dd1a8 25 * the project's page is at http://www.linuxtv.org/
1da177e4
LT
26 */
27
44d0b80e
JP
28#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29
1da177e4 30#include <linux/kernel.h>
1da177e4
LT
31#include <linux/types.h>
32#include <linux/delay.h>
33#include <linux/fs.h>
34#include <linux/timer.h>
35#include <linux/poll.h>
1da177e4
LT
36
37#include "av7110.h"
38#include "av7110_hw.h"
39#include "av7110_av.h"
40
41int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
42{
43 u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
61391e04
TK
44 struct i2c_msg msgs = { .flags = 0, .len = 5, .buf = msg };
45
46 switch (av7110->adac_type) {
47 case DVB_ADAC_MSP34x0:
48 msgs.addr = 0x40;
49 break;
50 case DVB_ADAC_MSP34x5:
51 msgs.addr = 0x42;
52 break;
53 default:
54 return 0;
55 }
1da177e4
LT
56
57 if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
58 dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
fdc53a6d 59 av7110->dvb_adapter.num, reg, val);
1da177e4
LT
60 return -EIO;
61 }
62 return 0;
63}
64
d91b730d 65static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
1da177e4
LT
66{
67 u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
68 u8 msg2[2];
69 struct i2c_msg msgs[2] = {
61391e04
TK
70 { .flags = 0 , .len = 3, .buf = msg1 },
71 { .flags = I2C_M_RD, .len = 2, .buf = msg2 }
1da177e4
LT
72 };
73
61391e04
TK
74 switch (av7110->adac_type) {
75 case DVB_ADAC_MSP34x0:
76 msgs[0].addr = 0x40;
77 msgs[1].addr = 0x40;
78 break;
79 case DVB_ADAC_MSP34x5:
80 msgs[0].addr = 0x42;
81 msgs[1].addr = 0x42;
82 break;
83 default:
84 return 0;
85 }
86
1da177e4
LT
87 if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
88 dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
fdc53a6d 89 av7110->dvb_adapter.num, reg);
1da177e4
LT
90 return -EIO;
91 }
92 *val = (msg2[0] << 8) | msg2[1];
93 return 0;
94}
95
f63f5346 96static struct v4l2_input inputs[4] = {
1da177e4
LT
97 {
98 .index = 0,
99 .name = "DVB",
100 .type = V4L2_INPUT_TYPE_CAMERA,
101 .audioset = 1,
102 .tuner = 0, /* ignored */
103 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
104 .status = 0,
657f2271 105 .capabilities = V4L2_IN_CAP_STD,
1da177e4
LT
106 }, {
107 .index = 1,
108 .name = "Television",
109 .type = V4L2_INPUT_TYPE_TUNER,
a299e407 110 .audioset = 1,
1da177e4
LT
111 .tuner = 0,
112 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
113 .status = 0,
657f2271 114 .capabilities = V4L2_IN_CAP_STD,
f63f5346 115 }, {
116 .index = 2,
117 .name = "Video",
118 .type = V4L2_INPUT_TYPE_CAMERA,
119 .audioset = 0,
120 .tuner = 0,
121 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
122 .status = 0,
657f2271 123 .capabilities = V4L2_IN_CAP_STD,
f63f5346 124 }, {
125 .index = 3,
126 .name = "Y/C",
127 .type = V4L2_INPUT_TYPE_CAMERA,
128 .audioset = 0,
129 .tuner = 0,
130 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
131 .status = 0,
657f2271 132 .capabilities = V4L2_IN_CAP_STD,
1da177e4
LT
133 }
134};
135
136static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
137{
36c15f8e 138 struct av7110 *av7110 = dev->ext_priv;
1da177e4
LT
139 u8 buf[] = { 0x00, reg, data };
140 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
141
142 dprintk(4, "dev: %p\n", dev);
143
36c15f8e 144 if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1))
1da177e4
LT
145 return -1;
146 return 0;
147}
148
1da177e4
LT
149static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
150{
36c15f8e 151 struct av7110 *av7110 = dev->ext_priv;
1da177e4
LT
152 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
153
154 dprintk(4, "dev: %p\n", dev);
155
36c15f8e 156 if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1))
1da177e4
LT
157 return -1;
158 return 0;
159}
160
161static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
162{
163 u32 div;
164 u8 config;
165 u8 buf[4];
166
167 dprintk(4, "freq: 0x%08x\n", freq);
168
169 /* magic number: 614. tuning with the frequency given by v4l2
170 is always off by 614*62.5 = 38375 kHz...*/
171 div = freq + 614;
172
173 buf[0] = (div >> 8) & 0x7f;
174 buf[1] = div & 0xff;
175 buf[2] = 0x8e;
176
177 if (freq < (u32) (16 * 168.25))
178 config = 0xa0;
179 else if (freq < (u32) (16 * 447.25))
180 config = 0x90;
181 else
182 config = 0x30;
183 config &= ~0x02;
184
185 buf[3] = config;
186
187 return tuner_write(dev, 0x61, buf);
188}
189
190static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
191{
89e4d59f 192 struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
1da177e4
LT
193 u32 div;
194 u8 data[4];
195
196 div = (freq + 38900000 + 31250) / 62500;
197
198 data[0] = (div >> 8) & 0x7f;
199 data[1] = div & 0xff;
200 data[2] = 0xce;
201
202 if (freq < 45000000)
203 return -EINVAL;
204 else if (freq < 137000000)
205 data[3] = 0x01;
206 else if (freq < 403000000)
207 data[3] = 0x02;
208 else if (freq < 860000000)
209 data[3] = 0x04;
210 else
211 return -EINVAL;
212
89e4d59f
MS
213 if (av7110->fe->ops.i2c_gate_ctrl)
214 av7110->fe->ops.i2c_gate_ctrl(av7110->fe, 1);
1da177e4
LT
215 return tuner_write(dev, 0x63, data);
216}
217
218
219
220static struct saa7146_standard analog_standard[];
221static struct saa7146_standard dvb_standard[];
222static struct saa7146_standard standard[];
223
224static struct v4l2_audio msp3400_v4l2_audio = {
225 .index = 0,
226 .name = "Television",
227 .capability = V4L2_AUDCAP_STEREO
228};
229
230static int av7110_dvb_c_switch(struct saa7146_fh *fh)
231{
232 struct saa7146_dev *dev = fh->dev;
233 struct saa7146_vv *vv = dev->vv_data;
234 struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
235 u16 adswitch;
236 int source, sync, err;
237
238 dprintk(4, "%p\n", av7110);
239
240 if ((vv->video_status & STATUS_OVERLAY) != 0) {
241 vv->ov_suspend = vv->video_fh;
242 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
243 if (err != 0) {
244 dprintk(2, "suspending video failed\n");
245 vv->ov_suspend = NULL;
246 }
247 }
248
249 if (0 != av7110->current_input) {
f63f5346 250 dprintk(1, "switching to analog TV:\n");
1da177e4
LT
251 adswitch = 1;
252 source = SAA7146_HPS_SOURCE_PORT_B;
253 sync = SAA7146_HPS_SYNC_PORT_B;
254 memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
1da177e4 255
f63f5346 256 switch (av7110->current_input) {
257 case 1:
44d0b80e 258 dprintk(1, "switching SAA7113 to Analog Tuner Input\n");
f63f5346 259 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
260 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
261 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
262 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
263 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
264 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
265
266 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
267 if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
44d0b80e 268 dprintk(1, "setting band in demodulator failed\n");
f63f5346 269 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
6a857747
MS
270 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9819 pin9(STD)
271 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9819 pin30(VIF)
f63f5346 272 }
273 if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1)
274 dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
275 break;
276 case 2:
44d0b80e 277 dprintk(1, "switching SAA7113 to Video AV CVBS Input\n");
f63f5346 278 if (i2c_writereg(av7110, 0x48, 0x02, 0xd2) != 1)
279 dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
280 break;
281 case 3:
44d0b80e 282 dprintk(1, "switching SAA7113 to Video AV Y/C Input\n");
f63f5346 283 if (i2c_writereg(av7110, 0x48, 0x02, 0xd9) != 1)
284 dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
285 break;
286 default:
44d0b80e 287 dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input\n");
1da177e4
LT
288 }
289 } else {
290 adswitch = 0;
291 source = SAA7146_HPS_SOURCE_PORT_A;
292 sync = SAA7146_HPS_SYNC_PORT_A;
293 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
294 dprintk(1, "switching DVB mode\n");
295 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
296 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
297 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
298 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
299 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
300 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
301
302 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
303 if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
44d0b80e 304 dprintk(1, "setting band in demodulator failed\n");
1da177e4 305 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
6a857747
MS
306 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD)
307 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF)
1da177e4
LT
308 }
309 }
310
311 /* hmm, this does not do anything!? */
312 if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
313 dprintk(1, "ADSwitch error\n");
314
315 saa7146_set_hps_source_and_sync(dev, source, sync);
316
317 if (vv->ov_suspend != NULL) {
318 saa7146_start_preview(vv->ov_suspend);
319 vv->ov_suspend = NULL;
320 }
321
322 return 0;
323}
324
b960074f 325static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
1da177e4 326{
b960074f
HV
327 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
328 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
329 u16 stereo_det;
330 s8 stereo;
1da177e4 331
b960074f 332 dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
1da177e4 333
b960074f
HV
334 if (!av7110->analog_tuner_flags || t->index != 0)
335 return -EINVAL;
1da177e4 336
b960074f
HV
337 memset(t, 0, sizeof(*t));
338 strcpy((char *)t->name, "Television");
339
340 t->type = V4L2_TUNER_ANALOG_TV;
341 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
342 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
343 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
344 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
345 /* FIXME: add the real signal strength here */
346 t->signal = 0xffff;
347 t->afc = 0;
348
349 /* FIXME: standard / stereo detection is still broken */
350 msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
351 dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
352 msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
353 dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
354 stereo = (s8)(stereo_det >> 8);
355 if (stereo > 0x10) {
356 /* stereo */
357 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
358 t->audmode = V4L2_TUNER_MODE_STEREO;
359 } else if (stereo < -0x10) {
360 /* bilingual */
361 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
362 t->audmode = V4L2_TUNER_MODE_LANG1;
363 } else /* mono */
364 t->rxsubchans = V4L2_TUNER_SUB_MONO;
1da177e4 365
b960074f
HV
366 return 0;
367}
1da177e4 368
b960074f
HV
369static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
370{
371 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
372 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
373 u16 fm_matrix, src;
374 dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
1da177e4 375
b960074f
HV
376 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
377 return -EINVAL;
1da177e4 378
b960074f
HV
379 switch (t->audmode) {
380 case V4L2_TUNER_MODE_STEREO:
381 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
382 fm_matrix = 0x3001; /* stereo */
383 src = 0x0020;
384 break;
385 case V4L2_TUNER_MODE_LANG1_LANG2:
386 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
387 fm_matrix = 0x3000; /* bilingual */
388 src = 0x0020;
389 break;
390 case V4L2_TUNER_MODE_LANG1:
391 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
392 fm_matrix = 0x3000; /* mono */
393 src = 0x0000;
394 break;
395 case V4L2_TUNER_MODE_LANG2:
396 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
397 fm_matrix = 0x3000; /* mono */
398 src = 0x0010;
399 break;
400 default: /* case V4L2_TUNER_MODE_MONO: */
401 dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
402 fm_matrix = 0x3000; /* mono */
403 src = 0x0030;
404 break;
1da177e4 405 }
b960074f
HV
406 msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
407 msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
408 msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
409 msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
410 return 0;
411}
412
413static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
414{
415 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
416 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
1da177e4 417
44d0b80e 418 dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x\n", f->frequency);
1da177e4 419
b960074f
HV
420 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
421 return -EINVAL;
1da177e4 422
b960074f
HV
423 memset(f, 0, sizeof(*f));
424 f->type = V4L2_TUNER_ANALOG_TV;
425 f->frequency = av7110->current_freq;
426 return 0;
427}
1da177e4 428
b530a447 429static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *f)
b960074f
HV
430{
431 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
432 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
1da177e4 433
44d0b80e 434 dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x\n", f->frequency);
1da177e4 435
b960074f
HV
436 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
437 return -EINVAL;
1da177e4 438
b960074f
HV
439 if (V4L2_TUNER_ANALOG_TV != f->type)
440 return -EINVAL;
1da177e4 441
b960074f
HV
442 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */
443 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
1da177e4 444
b960074f
HV
445 /* tune in desired frequency */
446 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820)
447 ves1820_set_tv_freq(dev, f->frequency);
448 else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297)
449 stv0297_set_tv_freq(dev, f->frequency);
450 av7110->current_freq = f->frequency;
1da177e4 451
b960074f
HV
452 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); /* start stereo detection */
453 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
454 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); /* loudspeaker + headphone */
455 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); /* SCART 1 volume */
456 return 0;
457}
1da177e4 458
b960074f
HV
459static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
460{
461 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
462 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
1da177e4 463
b960074f 464 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
1da177e4 465
b960074f 466 if (av7110->analog_tuner_flags) {
223ffe5f 467 if (i->index >= 4)
b960074f
HV
468 return -EINVAL;
469 } else {
470 if (i->index != 0)
471 return -EINVAL;
1da177e4 472 }
b960074f
HV
473
474 memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
475
476 return 0;
477}
478
479static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
480{
481 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
482 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
483
484 *input = av7110->current_input;
485 dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
486 return 0;
487}
488
489static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
490{
491 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
492 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
493
494 dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
495
496 if (!av7110->analog_tuner_flags)
a299e407 497 return input ? -EINVAL : 0;
1da177e4 498
de81c3c3 499 if (input >= 4)
b960074f 500 return -EINVAL;
1da177e4 501
b960074f
HV
502 av7110->current_input = input;
503 return av7110_dvb_c_switch(fh);
504}
1da177e4 505
a299e407
HV
506static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
507{
508 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
509 if (a->index != 0)
510 return -EINVAL;
511 *a = msp3400_v4l2_audio;
512 return 0;
513}
514
b960074f
HV
515static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
516{
a299e407
HV
517 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
518 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
519
b960074f
HV
520 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
521 if (a->index != 0)
522 return -EINVAL;
a299e407
HV
523 if (av7110->current_input >= 2)
524 return -EINVAL;
525 *a = msp3400_v4l2_audio;
b960074f
HV
526 return 0;
527}
1da177e4 528
0e8025b9 529static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
b960074f 530{
a299e407
HV
531 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
532 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
533
b960074f 534 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
a299e407
HV
535 if (av7110->current_input >= 2)
536 return -EINVAL;
537 return a->index ? -EINVAL : 0;
b960074f 538}
1da177e4 539
b960074f
HV
540static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
541 struct v4l2_sliced_vbi_cap *cap)
542{
543 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
544 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
545
546 dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
f97d2074
HV
547 if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
548 return -EINVAL;
b960074f
HV
549 if (FW_VERSION(av7110->arm_app) >= 0x2623) {
550 cap->service_set = V4L2_SLICED_WSS_625;
551 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
5b0fa4ff 552 }
b960074f
HV
553 return 0;
554}
555
556static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
557 struct v4l2_format *f)
558{
559 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
560 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
561
562 dprintk(2, "VIDIOC_G_FMT:\n");
563 if (FW_VERSION(av7110->arm_app) < 0x2623)
564 return -EINVAL;
565 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
566 if (av7110->wssMode) {
567 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
568 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
569 f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
5b0fa4ff 570 }
b960074f
HV
571 return 0;
572}
573
574static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
575 struct v4l2_format *f)
576{
577 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
578 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
579
580 dprintk(2, "VIDIOC_S_FMT\n");
581 if (FW_VERSION(av7110->arm_app) < 0x2623)
582 return -EINVAL;
583 if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
584 f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
585 memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
586 /* WSS controlled by firmware */
587 av7110->wssMode = 0;
588 av7110->wssData = 0;
589 return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
590 SetWSSConfig, 1, 0);
591 } else {
592 memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
593 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
594 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
595 f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
596 /* WSS controlled by userspace */
597 av7110->wssMode = 1;
598 av7110->wssData = 0;
1da177e4
LT
599 }
600 return 0;
601}
602
bec43661 603static int av7110_vbi_reset(struct file *file)
5b0fa4ff
OE
604{
605 struct saa7146_fh *fh = file->private_data;
606 struct saa7146_dev *dev = fh->dev;
607 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
608
3ca7fc84 609 dprintk(2, "%s\n", __func__);
5b0fa4ff
OE
610 av7110->wssMode = 0;
611 av7110->wssData = 0;
612 if (FW_VERSION(av7110->arm_app) < 0x2623)
613 return 0;
614 else
615 return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
616}
617
618static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
619{
620 struct saa7146_fh *fh = file->private_data;
621 struct saa7146_dev *dev = fh->dev;
622 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
623 struct v4l2_sliced_vbi_data d;
624 int rc;
625
3ca7fc84 626 dprintk(2, "%s\n", __func__);
5b0fa4ff
OE
627 if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d)
628 return -EINVAL;
629 if (copy_from_user(&d, data, count))
630 return -EFAULT;
631 if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23)
632 return -EINVAL;
4caba426 633 if (d.id)
5b0fa4ff 634 av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0];
4caba426
OE
635 else
636 av7110->wssData = 0x8000;
637 rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 1, av7110->wssData);
5b0fa4ff
OE
638 return (rc < 0) ? rc : count;
639}
1da177e4
LT
640
641/****************************************************************************
642 * INITIALIZATION
643 ****************************************************************************/
644
1da177e4
LT
645static u8 saa7113_init_regs[] = {
646 0x02, 0xd0,
647 0x03, 0x23,
648 0x04, 0x00,
649 0x05, 0x00,
650 0x06, 0xe9,
651 0x07, 0x0d,
652 0x08, 0x98,
653 0x09, 0x02,
654 0x0a, 0x80,
655 0x0b, 0x40,
656 0x0c, 0x40,
657 0x0d, 0x00,
658 0x0e, 0x01,
659 0x0f, 0x7c,
660 0x10, 0x48,
661 0x11, 0x0c,
662 0x12, 0x8b,
663 0x13, 0x1a,
664 0x14, 0x00,
665 0x15, 0x00,
666 0x16, 0x00,
667 0x17, 0x00,
668 0x18, 0x00,
669 0x19, 0x00,
670 0x1a, 0x00,
671 0x1b, 0x00,
672 0x1c, 0x00,
673 0x1d, 0x00,
674 0x1e, 0x00,
675
676 0x41, 0x77,
677 0x42, 0x77,
678 0x43, 0x77,
679 0x44, 0x77,
680 0x45, 0x77,
681 0x46, 0x77,
682 0x47, 0x77,
683 0x48, 0x77,
684 0x49, 0x77,
685 0x4a, 0x77,
686 0x4b, 0x77,
687 0x4c, 0x77,
688 0x4d, 0x77,
689 0x4e, 0x77,
690 0x4f, 0x77,
691 0x50, 0x77,
692 0x51, 0x77,
693 0x52, 0x77,
694 0x53, 0x77,
695 0x54, 0x77,
696 0x55, 0x77,
697 0x56, 0x77,
698 0x57, 0xff,
699
700 0xff
701};
702
703
704static struct saa7146_ext_vv av7110_vv_data_st;
705static struct saa7146_ext_vv av7110_vv_data_c;
706
707int av7110_init_analog_module(struct av7110 *av7110)
708{
709 u16 version1, version2;
710
61391e04
TK
711 if (i2c_writereg(av7110, 0x80, 0x0, 0x80) == 1 &&
712 i2c_writereg(av7110, 0x80, 0x0, 0) == 1) {
44d0b80e 713 pr_info("DVB-C analog module @ card %d detected, initializing MSP3400\n",
61391e04
TK
714 av7110->dvb_adapter.num);
715 av7110->adac_type = DVB_ADAC_MSP34x0;
716 } else if (i2c_writereg(av7110, 0x84, 0x0, 0x80) == 1 &&
717 i2c_writereg(av7110, 0x84, 0x0, 0) == 1) {
44d0b80e 718 pr_info("DVB-C analog module @ card %d detected, initializing MSP3415\n",
61391e04
TK
719 av7110->dvb_adapter.num);
720 av7110->adac_type = DVB_ADAC_MSP34x5;
721 } else
1da177e4
LT
722 return -ENODEV;
723
1da177e4
LT
724 msleep(100); // the probing above resets the msp...
725 msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
726 msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
61391e04 727 dprintk(1, "dvb-ttpci: @ card %d MSP34xx version 0x%04x 0x%04x\n",
fdc53a6d 728 av7110->dvb_adapter.num, version1, version2);
1da177e4
LT
729 msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
730 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
731 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
732 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
733 msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume
734 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
735 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
61391e04 736 msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x1900); // prescale SCART
1da177e4
LT
737
738 if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
44d0b80e 739 pr_info("saa7113 not accessible\n");
1da177e4
LT
740 } else {
741 u8 *i = saa7113_init_regs;
742
743 if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
744 /* Fujitsu/Siemens DVB-Cable */
745 av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
746 } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
747 /* Hauppauge/TT DVB-C premium */
748 av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
749 } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
750 /* Hauppauge/TT DVB-C premium */
751 av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
752 }
753
754 /* setup for DVB by default */
755 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
756 if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
44d0b80e 757 dprintk(1, "setting band in demodulator failed\n");
1da177e4 758 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
6a857747
MS
759 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD)
760 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF)
1da177e4
LT
761 }
762
763 /* init the saa7113 */
764 while (*i != 0xff) {
765 if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
fdc53a6d 766 dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter.num);
1da177e4
LT
767 break;
768 }
769 i += 2;
770 }
771 /* setup msp for analog sound: B/G Dual-FM */
772 msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV
773 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 3); // FIR1
774 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1
775 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1
776 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1
777 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1
778 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1
779 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 4); // FIR2
780 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2
781 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 0); // FIR2
782 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 3); // FIR2
783 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2
784 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2
785 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2
786 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2
787 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2
788 msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG
789 msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz
790 msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI
791 msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz
792 msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI
793 msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2
794 }
795
796 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
797 /* set dd1 stream a & b */
798 saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
799 saa7146_write(av7110->dev, DD1_INIT, 0x03000700);
800 saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
801
802 return 0;
803}
804
805int av7110_init_v4l(struct av7110 *av7110)
806{
807 struct saa7146_dev* dev = av7110->dev;
b960074f 808 struct saa7146_ext_vv *vv_data;
1da177e4
LT
809 int ret;
810
811 /* special case DVB-C: these cards have an analog tuner
812 plus need some special handling, so we have separate
813 saa7146_ext_vv data for these... */
814 if (av7110->analog_tuner_flags)
b960074f 815 vv_data = &av7110_vv_data_c;
1da177e4 816 else
b960074f
HV
817 vv_data = &av7110_vv_data_st;
818 ret = saa7146_vv_init(dev, vv_data);
1da177e4
LT
819
820 if (ret) {
44d0b80e 821 ERR("cannot init capture device. skipping\n");
1da177e4
LT
822 return -ENODEV;
823 }
ab49ae0f
HV
824 vv_data->vid_ops.vidioc_enum_input = vidioc_enum_input;
825 vv_data->vid_ops.vidioc_g_input = vidioc_g_input;
826 vv_data->vid_ops.vidioc_s_input = vidioc_s_input;
827 vv_data->vid_ops.vidioc_g_tuner = vidioc_g_tuner;
828 vv_data->vid_ops.vidioc_s_tuner = vidioc_s_tuner;
829 vv_data->vid_ops.vidioc_g_frequency = vidioc_g_frequency;
830 vv_data->vid_ops.vidioc_s_frequency = vidioc_s_frequency;
a299e407 831 vv_data->vid_ops.vidioc_enumaudio = vidioc_enumaudio;
ab49ae0f
HV
832 vv_data->vid_ops.vidioc_g_audio = vidioc_g_audio;
833 vv_data->vid_ops.vidioc_s_audio = vidioc_s_audio;
a299e407 834 vv_data->vid_ops.vidioc_g_fmt_vbi_cap = NULL;
313fce75 835
313fce75
HV
836 vv_data->vbi_ops.vidioc_g_tuner = vidioc_g_tuner;
837 vv_data->vbi_ops.vidioc_s_tuner = vidioc_s_tuner;
838 vv_data->vbi_ops.vidioc_g_frequency = vidioc_g_frequency;
839 vv_data->vbi_ops.vidioc_s_frequency = vidioc_s_frequency;
a299e407 840 vv_data->vbi_ops.vidioc_g_fmt_vbi_cap = NULL;
ab49ae0f
HV
841 vv_data->vbi_ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
842 vv_data->vbi_ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
843 vv_data->vbi_ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
1da177e4 844
a299e407
HV
845 if (FW_VERSION(av7110->arm_app) < 0x2623)
846 vv_data->capabilities &= ~V4L2_CAP_SLICED_VBI_OUTPUT;
847
1da177e4 848 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
44d0b80e 849 ERR("cannot register capture device. skipping\n");
1da177e4
LT
850 saa7146_vv_release(dev);
851 return -ENODEV;
852 }
a299e407
HV
853 if (FW_VERSION(av7110->arm_app) >= 0x2623) {
854 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI))
855 ERR("cannot register vbi v4l2 device. skipping\n");
856 }
1da177e4
LT
857 return 0;
858}
859
860int av7110_exit_v4l(struct av7110 *av7110)
861{
e19c55ff
MS
862 struct saa7146_dev* dev = av7110->dev;
863
1da177e4 864 saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
7857735b 865 saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
e19c55ff
MS
866
867 saa7146_vv_release(dev);
868
1da177e4
LT
869 return 0;
870}
871
872
873
874/* FIXME: these values are experimental values that look better than the
875 values from the latest "official" driver -- at least for me... (MiHu) */
876static struct saa7146_standard standard[] = {
877 {
878 .name = "PAL", .id = V4L2_STD_PAL_BG,
879 .v_offset = 0x15, .v_field = 288,
880 .h_offset = 0x48, .h_pixels = 708,
881 .v_max_out = 576, .h_max_out = 768,
882 }, {
883 .name = "NTSC", .id = V4L2_STD_NTSC,
884 .v_offset = 0x10, .v_field = 244,
885 .h_offset = 0x40, .h_pixels = 708,
886 .v_max_out = 480, .h_max_out = 640,
887 }
888};
889
890static struct saa7146_standard analog_standard[] = {
891 {
892 .name = "PAL", .id = V4L2_STD_PAL_BG,
893 .v_offset = 0x1b, .v_field = 288,
894 .h_offset = 0x08, .h_pixels = 708,
895 .v_max_out = 576, .h_max_out = 768,
896 }, {
897 .name = "NTSC", .id = V4L2_STD_NTSC,
898 .v_offset = 0x10, .v_field = 244,
899 .h_offset = 0x40, .h_pixels = 708,
900 .v_max_out = 480, .h_max_out = 640,
901 }
902};
903
904static struct saa7146_standard dvb_standard[] = {
905 {
906 .name = "PAL", .id = V4L2_STD_PAL_BG,
907 .v_offset = 0x14, .v_field = 288,
908 .h_offset = 0x48, .h_pixels = 708,
909 .v_max_out = 576, .h_max_out = 768,
910 }, {
911 .name = "NTSC", .id = V4L2_STD_NTSC,
912 .v_offset = 0x10, .v_field = 244,
913 .h_offset = 0x40, .h_pixels = 708,
914 .v_max_out = 480, .h_max_out = 640,
915 }
916};
917
918static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
919{
920 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
921
4ab3f08b 922 if (std->id & V4L2_STD_PAL) {
58a44040 923 av7110->vidmode = AV7110_VIDEO_MODE_PAL;
1da177e4
LT
924 av7110_set_vidmode(av7110, av7110->vidmode);
925 }
4ab3f08b 926 else if (std->id & V4L2_STD_NTSC) {
58a44040 927 av7110->vidmode = AV7110_VIDEO_MODE_NTSC;
1da177e4
LT
928 av7110_set_vidmode(av7110, av7110->vidmode);
929 }
930 else
931 return -1;
932
933 return 0;
934}
935
936
937static struct saa7146_ext_vv av7110_vv_data_st = {
938 .inputs = 1,
939 .audios = 1,
a299e407 940 .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO,
1da177e4
LT
941 .flags = 0,
942
943 .stds = &standard[0],
944 .num_stds = ARRAY_SIZE(standard),
945 .std_callback = &std_callback,
946
5b0fa4ff
OE
947 .vbi_fops.open = av7110_vbi_reset,
948 .vbi_fops.release = av7110_vbi_reset,
949 .vbi_fops.write = av7110_vbi_write,
1da177e4
LT
950};
951
952static struct saa7146_ext_vv av7110_vv_data_c = {
953 .inputs = 1,
954 .audios = 1,
a299e407 955 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO,
1da177e4
LT
956 .flags = SAA7146_USE_PORT_B_FOR_VBI,
957
958 .stds = &standard[0],
959 .num_stds = ARRAY_SIZE(standard),
960 .std_callback = &std_callback,
961
5b0fa4ff
OE
962 .vbi_fops.open = av7110_vbi_reset,
963 .vbi_fops.release = av7110_vbi_reset,
964 .vbi_fops.write = av7110_vbi_write,
1da177e4
LT
965};
966
This page took 0.755154 seconds and 5 git commands to generate.