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

source code of linux/drivers/staging/media/av7110/av7110_v4l.c