• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/media/video/
1/*
2    mxb - v4l2 driver for the Multimedia eXtension Board
3
4    Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
5
6    Visit http://www.mihu.de/linux/saa7146/mxb/
7    for further details about this card.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24#define DEBUG_VARIABLE debug
25
26#include <media/saa7146_vv.h>
27#include <media/tuner.h>
28#include <media/v4l2-common.h>
29#include <media/saa7115.h>
30
31#include "mxb.h"
32#include "tea6415c.h"
33#include "tea6420.h"
34
35#define	I2C_SAA5246A  0x11
36#define I2C_SAA7111A  0x24
37#define	I2C_TDA9840   0x42
38#define	I2C_TEA6415C  0x43
39#define	I2C_TEA6420_1 0x4c
40#define	I2C_TEA6420_2 0x4d
41#define	I2C_TUNER     0x60
42
43#define MXB_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0)
44
45/* global variable */
46static int mxb_num;
47
48/* initial frequence the tuner will be tuned to.
49   in verden (lower saxony, germany) 4148 is a
50   channel called "phoenix" */
51static int freq = 4148;
52module_param(freq, int, 0644);
53MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
54
55static int debug;
56module_param(debug, int, 0644);
57MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
58
59#define MXB_INPUTS 4
60enum { TUNER, AUX1, AUX3, AUX3_YC };
61
62static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
63	{ TUNER,	"Tuner",		V4L2_INPUT_TYPE_TUNER,	1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
64	{ AUX1,		"AUX1",			V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
65	{ AUX3,		"AUX3 Composite",	V4L2_INPUT_TYPE_CAMERA,	4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
66	{ AUX3_YC,	"AUX3 S-Video",		V4L2_INPUT_TYPE_CAMERA,	4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
67};
68
69/* this array holds the information, which port of the saa7146 each
70   input actually uses. the mxb uses port 0 for every input */
71static struct {
72	int hps_source;
73	int hps_sync;
74} input_port_selection[MXB_INPUTS] = {
75	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
76	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
77	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
78	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
79};
80
81/* this array holds the information of the audio source (mxb_audios),
82   which has to be switched corresponding to the video source (mxb_channels) */
83static int video_audio_connect[MXB_INPUTS] =
84	{ 0, 1, 3, 3 };
85
86struct mxb_routing {
87	u32 input;
88	u32 output;
89};
90
91/* These are the necessary input-output-pins for bringing one audio source
92   (see above) to the CD-output. Note that gain is set to 0 in this table. */
93static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
94	{ { 1, 1 }, { 1, 1 } },	/* Tuner */
95	{ { 5, 1 }, { 6, 1 } },	/* AUX 1 */
96	{ { 4, 1 }, { 6, 1 } },	/* AUX 2 */
97	{ { 3, 1 }, { 6, 1 } },	/* AUX 3 */
98	{ { 1, 1 }, { 3, 1 } },	/* Radio */
99	{ { 1, 1 }, { 2, 1 } },	/* CD-Rom */
100	{ { 6, 1 }, { 6, 1 } }	/* Mute */
101};
102
103/* These are the necessary input-output-pins for bringing one audio source
104   (see above) to the line-output. Note that gain is set to 0 in this table. */
105static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
106	{ { 2, 3 }, { 1, 2 } },
107	{ { 5, 3 }, { 6, 2 } },
108	{ { 4, 3 }, { 6, 2 } },
109	{ { 3, 3 }, { 6, 2 } },
110	{ { 2, 3 }, { 3, 2 } },
111	{ { 2, 3 }, { 2, 2 } },
112	{ { 6, 3 }, { 6, 2 } }	/* Mute */
113};
114
115#define MAXCONTROLS	1
116static struct v4l2_queryctrl mxb_controls[] = {
117	{ V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
118};
119
120struct mxb
121{
122	struct video_device	*video_dev;
123	struct video_device	*vbi_dev;
124
125	struct i2c_adapter	i2c_adapter;
126
127	struct v4l2_subdev	*saa7111a;
128	struct v4l2_subdev	*tda9840;
129	struct v4l2_subdev	*tea6415c;
130	struct v4l2_subdev	*tuner;
131	struct v4l2_subdev	*tea6420_1;
132	struct v4l2_subdev	*tea6420_2;
133
134	int	cur_mode;	/* current audio mode (mono, stereo, ...) */
135	int	cur_input;	/* current input */
136	int	cur_mute;	/* current mute status */
137	struct v4l2_frequency	cur_freq;	/* current frequency the tuner is tuned to */
138};
139
140#define saa7111a_call(mxb, o, f, args...) \
141	v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
142#define tda9840_call(mxb, o, f, args...) \
143	v4l2_subdev_call(mxb->tda9840, o, f, ##args)
144#define tea6415c_call(mxb, o, f, args...) \
145	v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
146#define tuner_call(mxb, o, f, args...) \
147	v4l2_subdev_call(mxb->tuner, o, f, ##args)
148#define call_all(dev, o, f, args...) \
149	v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
150
151static inline void tea6420_route_cd(struct mxb *mxb, int idx)
152{
153	v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
154		TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
155	v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
156		TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
157}
158
159static inline void tea6420_route_line(struct mxb *mxb, int idx)
160{
161	v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
162		TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
163	v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
164		TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0);
165}
166
167static struct saa7146_extension extension;
168
169static int mxb_probe(struct saa7146_dev *dev)
170{
171	struct mxb *mxb = NULL;
172
173	mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
174	if (mxb == NULL) {
175		DEB_D(("not enough kernel memory.\n"));
176		return -ENOMEM;
177	}
178
179	snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
180
181	saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
182	if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
183		DEB_S(("cannot register i2c-device. skipping.\n"));
184		kfree(mxb);
185		return -EFAULT;
186	}
187
188	mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
189			"saa7115", "saa7111", I2C_SAA7111A, NULL);
190	mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
191			"tea6420", "tea6420", I2C_TEA6420_1, NULL);
192	mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
193			"tea6420", "tea6420", I2C_TEA6420_2, NULL);
194	mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
195			"tea6415c", "tea6415c", I2C_TEA6415C, NULL);
196	mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
197			"tda9840", "tda9840", I2C_TDA9840, NULL);
198	mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
199			"tuner", "tuner", I2C_TUNER, NULL);
200	if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
201			"saa5246a", "saa5246a", I2C_SAA5246A, NULL)) {
202		printk(KERN_INFO "mxb: found teletext decoder\n");
203	}
204
205	/* check if all devices are present */
206	if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
207	    !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
208		printk("mxb: did not find all i2c devices. aborting\n");
209		i2c_del_adapter(&mxb->i2c_adapter);
210		kfree(mxb);
211		return -ENODEV;
212	}
213
214	/* all devices are present, probe was successful */
215
216	/* we store the pointer in our private data field */
217	dev->ext_priv = mxb;
218
219	return 0;
220}
221
222/* some init data for the saa7740, the so-called 'sound arena module'.
223   there are no specs available, so we simply use some init values */
224static struct {
225	int	length;
226	char	data[9];
227} mxb_saa7740_init[] = {
228	{ 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
229	{ 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
230	{ 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
231	{ 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
232	{ 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
233	{ 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
234	{ 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
235	{ 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
236	{ 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
237	{ 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
238	{ 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
239	{ 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
240	{ 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
241	{ 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
242	{ 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
243	{ 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
244	{ 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
245	{ 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
246	{ 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
247	{ 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
248	{ 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
249	{ 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
250	{ 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
251	{ 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
252	{ 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
253	{ 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
254	{ 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
255	{ 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
256	{ 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
257	{ 3, { 0x48, 0x00, 0x01 } },
258	{ 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
259	{ 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
260	{ 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
261	{ 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
262	{ 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
263	{ 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
264	{ 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
265	{ 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
266	{ 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
267	{ 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
268	{ 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
269	{ 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
270	{ 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
271	{ 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
272	{ 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
273	{ 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
274	{ 3, { 0x80, 0xb3, 0x0a } },
275	{-1, { 0 } }
276};
277
278/* bring hardware to a sane state. this has to be done, just in case someone
279   wants to capture from this device before it has been properly initialized.
280   the capture engine would badly fail, because no valid signal arrives on the
281   saa7146, thus leading to timeouts and stuff. */
282static int mxb_init_done(struct saa7146_dev* dev)
283{
284	struct mxb* mxb = (struct mxb*)dev->ext_priv;
285	struct i2c_msg msg;
286	struct tuner_setup tun_setup;
287	v4l2_std_id std = V4L2_STD_PAL_BG;
288
289	int i = 0, err = 0;
290
291	/* select video mode in saa7111a */
292	saa7111a_call(mxb, core, s_std, std);
293
294	/* select tuner-output on saa7111a */
295	i = 0;
296	saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
297		SAA7111_FMT_CCIR, 0);
298
299	/* select a tuner type */
300	tun_setup.mode_mask = T_ANALOG_TV;
301	tun_setup.addr = ADDR_UNSET;
302	tun_setup.type = TUNER_PHILIPS_PAL;
303	tuner_call(mxb, tuner, s_type_addr, &tun_setup);
304	/* tune in some frequency on tuner */
305	mxb->cur_freq.tuner = 0;
306	mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
307	mxb->cur_freq.frequency = freq;
308	tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
309
310	/* set a default video standard */
311	tuner_call(mxb, core, s_std, std);
312
313	/* mute audio on tea6420s */
314	tea6420_route_line(mxb, 6);
315	tea6420_route_cd(mxb, 6);
316
317	/* switch to tuner-channel on tea6415c */
318	tea6415c_call(mxb, video, s_routing, 3, 17, 0);
319
320	/* select tuner-output on multicable on tea6415c */
321	tea6415c_call(mxb, video, s_routing, 3, 13, 0);
322
323	/* the rest for mxb */
324	mxb->cur_input = 0;
325	mxb->cur_mute = 1;
326
327	mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
328
329	/* check if the saa7740 (aka 'sound arena module') is present
330	   on the mxb. if so, we must initialize it. due to lack of
331	   informations about the saa7740, the values were reverse
332	   engineered. */
333	msg.addr = 0x1b;
334	msg.flags = 0;
335	msg.len = mxb_saa7740_init[0].length;
336	msg.buf = &mxb_saa7740_init[0].data[0];
337
338	err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
339	if (err == 1) {
340		/* the sound arena module is a pos, that's probably the reason
341		   philips refuses to hand out a datasheet for the saa7740...
342		   it seems to screw up the i2c bus, so we disable fast irq
343		   based i2c transactions here and rely on the slow and safe
344		   polling method ... */
345		extension.flags &= ~SAA7146_USE_I2C_IRQ;
346		for (i = 1; ; i++) {
347			if (-1 == mxb_saa7740_init[i].length)
348				break;
349
350			msg.len = mxb_saa7740_init[i].length;
351			msg.buf = &mxb_saa7740_init[i].data[0];
352			err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
353			if (err != 1) {
354				DEB_D(("failed to initialize 'sound arena module'.\n"));
355				goto err;
356			}
357		}
358		INFO(("'sound arena module' detected.\n"));
359	}
360err:
361	/* the rest for saa7146: you should definitely set some basic values
362	   for the input-port handling of the saa7146. */
363
364	/* ext->saa has been filled by the core driver */
365
366	/* some stuff is done via variables */
367	saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source,
368			input_port_selection[mxb->cur_input].hps_sync);
369
370	/* some stuff is done via direct write to the registers */
371
372	/* this is ugly, but because of the fact that this is completely
373	   hardware dependend, it should be done directly... */
374	saa7146_write(dev, DD1_STREAM_B,	0x00000000);
375	saa7146_write(dev, DD1_INIT,		0x02000200);
376	saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
377
378	return 0;
379}
380
381/* interrupt-handler. this gets called when irq_mask is != 0.
382   it must clear the interrupt-bits in irq_mask it has handled */
383/*
384void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
385{
386	struct mxb* mxb = (struct mxb*)dev->ext_priv;
387}
388*/
389
390static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
391{
392	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
393	int i;
394
395	for (i = MAXCONTROLS - 1; i >= 0; i--) {
396		if (mxb_controls[i].id == qc->id) {
397			*qc = mxb_controls[i];
398			DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
399			return 0;
400		}
401	}
402	return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
403}
404
405static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
406{
407	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
408	struct mxb *mxb = (struct mxb *)dev->ext_priv;
409	int i;
410
411	for (i = MAXCONTROLS - 1; i >= 0; i--) {
412		if (mxb_controls[i].id == vc->id)
413			break;
414	}
415
416	if (i < 0)
417		return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
418
419	if (vc->id == V4L2_CID_AUDIO_MUTE) {
420		vc->value = mxb->cur_mute;
421		DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
422		return 0;
423	}
424
425	DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
426	return 0;
427}
428
429static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
430{
431	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
432	struct mxb *mxb = (struct mxb *)dev->ext_priv;
433	int i = 0;
434
435	for (i = MAXCONTROLS - 1; i >= 0; i--) {
436		if (mxb_controls[i].id == vc->id)
437			break;
438	}
439
440	if (i < 0)
441		return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
442
443	if (vc->id == V4L2_CID_AUDIO_MUTE) {
444		mxb->cur_mute = vc->value;
445		/* switch the audio-source */
446		tea6420_route_line(mxb, vc->value ? 6 :
447				video_audio_connect[mxb->cur_input]);
448		DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
449	}
450	return 0;
451}
452
453static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
454{
455	DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
456	if (i->index >= MXB_INPUTS)
457		return -EINVAL;
458	memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
459	return 0;
460}
461
462static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
463{
464	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
465	struct mxb *mxb = (struct mxb *)dev->ext_priv;
466	*i = mxb->cur_input;
467
468	DEB_EE(("VIDIOC_G_INPUT %d.\n", *i));
469	return 0;
470}
471
472static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
473{
474	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
475	struct mxb *mxb = (struct mxb *)dev->ext_priv;
476	int err = 0;
477	int i = 0;
478
479	DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
480
481	if (input >= MXB_INPUTS)
482		return -EINVAL;
483
484	mxb->cur_input = input;
485
486	saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
487			input_port_selection[input].hps_sync);
488
489	/* prepare switching of tea6415c and saa7111a;
490	   have a look at the 'background'-file for further informations  */
491	switch (input) {
492	case TUNER:
493		i = SAA7115_COMPOSITE0;
494
495		err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
496
497		/* connect tuner-output always to multicable */
498		if (!err)
499			err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
500		break;
501	case AUX3_YC:
502		/* nothing to be done here. aux3_yc is
503		   directly connected to the saa711a */
504		i = SAA7115_SVIDEO1;
505		break;
506	case AUX3:
507		/* nothing to be done here. aux3 is
508		   directly connected to the saa711a */
509		i = SAA7115_COMPOSITE1;
510		break;
511	case AUX1:
512		i = SAA7115_COMPOSITE0;
513		err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
514		break;
515	}
516
517	if (err)
518		return err;
519
520	/* switch video in saa7111a */
521	if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0))
522		printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a.\n");
523
524	/* switch the audio-source only if necessary */
525	if (0 == mxb->cur_mute)
526		tea6420_route_line(mxb, video_audio_connect[input]);
527
528	return 0;
529}
530
531static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
532{
533	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
534	struct mxb *mxb = (struct mxb *)dev->ext_priv;
535
536	if (t->index) {
537		DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
538		return -EINVAL;
539	}
540
541	DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
542
543	memset(t, 0, sizeof(*t));
544	strlcpy(t->name, "TV Tuner", sizeof(t->name));
545	t->type = V4L2_TUNER_ANALOG_TV;
546	t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
547			V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
548	t->audmode = mxb->cur_mode;
549	return call_all(dev, tuner, g_tuner, t);
550}
551
552static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
553{
554	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
555	struct mxb *mxb = (struct mxb *)dev->ext_priv;
556
557	if (t->index) {
558		DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index));
559		return -EINVAL;
560	}
561
562	mxb->cur_mode = t->audmode;
563	return call_all(dev, tuner, s_tuner, t);
564}
565
566static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
567{
568	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
569	struct mxb *mxb = (struct mxb *)dev->ext_priv;
570
571	if (mxb->cur_input) {
572		DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
573					mxb->cur_input));
574		return -EINVAL;
575	}
576
577	*f = mxb->cur_freq;
578
579	DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
580	return 0;
581}
582
583static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
584{
585	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
586	struct mxb *mxb = (struct mxb *)dev->ext_priv;
587	struct saa7146_vv *vv = dev->vv_data;
588
589	if (f->tuner)
590		return -EINVAL;
591
592	if (V4L2_TUNER_ANALOG_TV != f->type)
593		return -EINVAL;
594
595	if (mxb->cur_input) {
596		DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
597		return -EINVAL;
598	}
599
600	mxb->cur_freq = *f;
601	DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
602
603	/* tune in desired frequency */
604	tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
605
606	/* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
607	spin_lock(&dev->slock);
608	vv->vbi_fieldcount = 0;
609	spin_unlock(&dev->slock);
610
611	return 0;
612}
613
614static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
615{
616	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
617	struct mxb *mxb = (struct mxb *)dev->ext_priv;
618
619	if (a->index > MXB_INPUTS) {
620		DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
621		return -EINVAL;
622	}
623
624	DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
625	memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
626	return 0;
627}
628
629static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
630{
631	DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
632	return 0;
633}
634
635#ifdef CONFIG_VIDEO_ADV_DEBUG
636static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
637{
638	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
639
640	return call_all(dev, core, g_register, reg);
641}
642
643static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
644{
645	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
646
647	return call_all(dev, core, s_register, reg);
648}
649#endif
650
651static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
652{
653	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
654	struct mxb *mxb = (struct mxb *)dev->ext_priv;
655
656	switch (cmd) {
657	case MXB_S_AUDIO_CD:
658	{
659		int i = *(int *)arg;
660
661		if (i < 0 || i >= MXB_AUDIOS) {
662			DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n", i));
663			return -EINVAL;
664		}
665
666		DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
667
668		tea6420_route_cd(mxb, i);
669		return 0;
670	}
671	case MXB_S_AUDIO_LINE:
672	{
673		int i = *(int *)arg;
674
675		if (i < 0 || i >= MXB_AUDIOS) {
676			DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n", i));
677			return -EINVAL;
678		}
679
680		DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
681		tea6420_route_line(mxb, i);
682		return 0;
683	}
684	default:
685/*
686		DEB2(printk("does not handle this ioctl.\n"));
687*/
688		return -ENOIOCTLCMD;
689	}
690	return 0;
691}
692
693static struct saa7146_ext_vv vv_data;
694
695/* this function only gets called when the probing was successful */
696static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
697{
698	struct mxb *mxb;
699
700	DEB_EE(("dev:%p\n", dev));
701
702	saa7146_vv_init(dev, &vv_data);
703	if (mxb_probe(dev)) {
704		saa7146_vv_release(dev);
705		return -1;
706	}
707	mxb = (struct mxb *)dev->ext_priv;
708
709	vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
710	vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
711	vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
712	vv_data.ops.vidioc_enum_input = vidioc_enum_input;
713	vv_data.ops.vidioc_g_input = vidioc_g_input;
714	vv_data.ops.vidioc_s_input = vidioc_s_input;
715	vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
716	vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
717	vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
718	vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
719	vv_data.ops.vidioc_g_audio = vidioc_g_audio;
720	vv_data.ops.vidioc_s_audio = vidioc_s_audio;
721#ifdef CONFIG_VIDEO_ADV_DEBUG
722	vv_data.ops.vidioc_g_register = vidioc_g_register;
723	vv_data.ops.vidioc_s_register = vidioc_s_register;
724#endif
725	vv_data.ops.vidioc_default = vidioc_default;
726	if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
727		ERR(("cannot register capture v4l2 device. skipping.\n"));
728		saa7146_vv_release(dev);
729		return -1;
730	}
731
732	/* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
733	if (MXB_BOARD_CAN_DO_VBI(dev)) {
734		if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
735			ERR(("cannot register vbi v4l2 device. skipping.\n"));
736		}
737	}
738
739	printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
740
741	mxb_num++;
742	mxb_init_done(dev);
743	return 0;
744}
745
746static int mxb_detach(struct saa7146_dev *dev)
747{
748	struct mxb *mxb = (struct mxb *)dev->ext_priv;
749
750	DEB_EE(("dev:%p\n", dev));
751
752	saa7146_unregister_device(&mxb->video_dev,dev);
753	if (MXB_BOARD_CAN_DO_VBI(dev))
754		saa7146_unregister_device(&mxb->vbi_dev, dev);
755	saa7146_vv_release(dev);
756
757	mxb_num--;
758
759	i2c_del_adapter(&mxb->i2c_adapter);
760	kfree(mxb);
761
762	return 0;
763}
764
765static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
766{
767	struct mxb *mxb = (struct mxb *)dev->ext_priv;
768
769	if (V4L2_STD_PAL_I == standard->id) {
770		v4l2_std_id std = V4L2_STD_PAL_I;
771
772		DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
773		/* set the 7146 gpio register -- I don't know what this does exactly */
774		saa7146_write(dev, GPIO_CTRL, 0x00404050);
775		/* unset the 7111 gpio register -- I don't know what this does exactly */
776		saa7111a_call(mxb, core, s_gpio, 0);
777		tuner_call(mxb, core, s_std, std);
778	} else {
779		v4l2_std_id std = V4L2_STD_PAL_BG;
780
781		DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
782		/* set the 7146 gpio register -- I don't know what this does exactly */
783		saa7146_write(dev, GPIO_CTRL, 0x00404050);
784		/* set the 7111 gpio register -- I don't know what this does exactly */
785		saa7111a_call(mxb, core, s_gpio, 1);
786		tuner_call(mxb, core, s_std, std);
787	}
788	return 0;
789}
790
791static struct saa7146_standard standard[] = {
792	{
793		.name	= "PAL-BG", 	.id	= V4L2_STD_PAL_BG,
794		.v_offset	= 0x17,	.v_field 	= 288,
795		.h_offset	= 0x14,	.h_pixels 	= 680,
796		.v_max_out	= 576,	.h_max_out	= 768,
797	}, {
798		.name	= "PAL-I", 	.id	= V4L2_STD_PAL_I,
799		.v_offset	= 0x17,	.v_field 	= 288,
800		.h_offset	= 0x14,	.h_pixels 	= 680,
801		.v_max_out	= 576,	.h_max_out	= 768,
802	}, {
803		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
804		.v_offset	= 0x16,	.v_field 	= 240,
805		.h_offset	= 0x06,	.h_pixels 	= 708,
806		.v_max_out	= 480,	.h_max_out	= 640,
807	}, {
808		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,
809		.v_offset	= 0x14,	.v_field 	= 288,
810		.h_offset	= 0x14,	.h_pixels 	= 720,
811		.v_max_out	= 576,	.h_max_out	= 768,
812	}
813};
814
815static struct saa7146_pci_extension_data mxb = {
816	.ext_priv = "Multimedia eXtension Board",
817	.ext = &extension,
818};
819
820static struct pci_device_id pci_tbl[] = {
821	{
822		.vendor    = PCI_VENDOR_ID_PHILIPS,
823		.device	   = PCI_DEVICE_ID_PHILIPS_SAA7146,
824		.subvendor = 0x0000,
825		.subdevice = 0x0000,
826		.driver_data = (unsigned long)&mxb,
827	}, {
828		.vendor	= 0,
829	}
830};
831
832MODULE_DEVICE_TABLE(pci, pci_tbl);
833
834static struct saa7146_ext_vv vv_data = {
835	.inputs		= MXB_INPUTS,
836	.capabilities	= V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
837	.stds		= &standard[0],
838	.num_stds	= sizeof(standard)/sizeof(struct saa7146_standard),
839	.std_callback	= &std_callback,
840};
841
842static struct saa7146_extension extension = {
843	.name		= MXB_IDENTIFIER,
844	.flags		= SAA7146_USE_I2C_IRQ,
845
846	.pci_tbl	= &pci_tbl[0],
847	.module		= THIS_MODULE,
848
849	.attach		= mxb_attach,
850	.detach		= mxb_detach,
851
852	.irq_mask	= 0,
853	.irq_func	= NULL,
854};
855
856static int __init mxb_init_module(void)
857{
858	if (saa7146_register_extension(&extension)) {
859		DEB_S(("failed to register extension.\n"));
860		return -ENODEV;
861	}
862
863	return 0;
864}
865
866static void __exit mxb_cleanup_module(void)
867{
868	saa7146_unregister_extension(&extension);
869}
870
871module_init(mxb_init_module);
872module_exit(mxb_cleanup_module);
873
874MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
875MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
876MODULE_LICENSE("GPL");
877