File Index
Files and directories
Sign in
FILE

av7110_v4l.c

File preview with syntax highlighting.

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