Linux Audio

Check our new training course

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