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