cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mxb.c (26136B)


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