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