]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/video/mxb.c
Merge branch 'next-i2c' of git://aeryn.fluff.org.uk/bjdooks/linux
[mirror_ubuntu-artful-kernel.git] / drivers / media / video / mxb.c
CommitLineData
1da177e4
LT
1/*
2 mxb - v4l2 driver for the Multimedia eXtension Board
a8733ca5 3
6acaba8e 4 Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
1da177e4
LT
5
6 Visit http://www.mihu.de/linux/saa7146/mxb/
7 for further details about this card.
a8733ca5 8
1da177e4
LT
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>
5e453dc7 28#include <media/v4l2-common.h>
707ecf46 29#include <media/saa7115.h>
1da177e4
LT
30
31#include "mxb.h"
32#include "tea6415c.h"
33#include "tea6420.h"
1da177e4 34
1b8dac15
HV
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
1da177e4 42
a8733ca5 43#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
1da177e4
LT
44
45/* global variable */
ff699e6b 46static int mxb_num;
1da177e4 47
a8733ca5 48/* initial frequence the tuner will be tuned to.
1da177e4
LT
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
ff699e6b 55static int debug;
1da177e4
LT
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] = {
a8733ca5 63 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
1da177e4
LT
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;
a8733ca5 74} input_port_selection[MXB_INPUTS] = {
1da177e4
LT
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
5325b427
HV
86struct mxb_routing {
87 u32 input;
88 u32 output;
89};
90
1b8dac15
HV
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. */
5325b427 93static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
1b8dac15
HV
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. */
5325b427 105static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
1b8dac15
HV
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};
1da177e4
LT
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
1da177e4
LT
120struct mxb
121{
122 struct video_device *video_dev;
123 struct video_device *vbi_dev;
124
a8733ca5 125 struct i2c_adapter i2c_adapter;
1da177e4 126
1b8dac15
HV
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;
1da177e4
LT
133
134 int cur_mode; /* current audio mode (mono, stereo, ...) */
135 int cur_input; /* current input */
1da177e4 136 int cur_mute; /* current mute status */
9d2599d9 137 struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */
1da177e4
LT
138};
139
1b8dac15
HV
140#define saa7111a_call(mxb, o, f, args...) \
141 v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
1b8dac15
HV
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)
961f80f9 150
5325b427
HV
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
1b8dac15 167static struct saa7146_extension extension;
961f80f9 168
1b8dac15 169static int mxb_probe(struct saa7146_dev *dev)
1da177e4 170{
1b8dac15 171 struct mxb *mxb = NULL;
1da177e4 172
7408187d 173 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
1b8dac15 174 if (mxb == NULL) {
1da177e4
LT
175 DEB_D(("not enough kernel memory.\n"));
176 return -ENOMEM;
177 }
1da177e4 178
9ebeae56
HV
179 snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
180
1da177e4 181 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
1b8dac15 182 if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
1da177e4
LT
183 DEB_S(("cannot register i2c-device. skipping.\n"));
184 kfree(mxb);
185 return -EFAULT;
186 }
187
e6574f2f
HV
188 mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
189 "saa7115", "saa7111", I2C_SAA7111A);
190 mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
191 "tea6420", "tea6420", I2C_TEA6420_1);
192 mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
193 "tea6420", "tea6420", I2C_TEA6420_2);
194 mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
195 "tea6415c", "tea6415c", I2C_TEA6415C);
196 mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
197 "tda9840", "tda9840", I2C_TDA9840);
198 mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
199 "tuner", "tuner", I2C_TUNER);
200 if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
201 "saa5246a", "saa5246a", I2C_SAA5246A)) {
1b8dac15
HV
202 printk(KERN_INFO "mxb: found teletext decoder\n");
203 }
1da177e4
LT
204
205 /* check if all devices are present */
5fa1247a
AV
206 if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
207 !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
1da177e4
LT
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
a8733ca5 214 /* all devices are present, probe was successful */
1da177e4
LT
215
216 /* we store the pointer in our private data field */
217 dev->ext_priv = mxb;
218
219 return 0;
220}
221
a8733ca5 222/* some init data for the saa7740, the so-called 'sound arena module'.
1da177e4
LT
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 } },
2633812f 275 {-1, { 0 } }
1da177e4
LT
276};
277
1da177e4
LT
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;
1da177e4 285 struct i2c_msg msg;
85369df3 286 struct tuner_setup tun_setup;
6acaba8e 287 v4l2_std_id std = V4L2_STD_PAL_BG;
1da177e4
LT
288
289 int i = 0, err = 0;
1da177e4
LT
290
291 /* select video mode in saa7111a */
f41737ec 292 saa7111a_call(mxb, core, s_std, std);
1da177e4
LT
293
294 /* select tuner-output on saa7111a */
295 i = 0;
5325b427
HV
296 saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
297 SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS, 0);
1da177e4
LT
298
299 /* select a tuner type */
85369df3
MCC
300 tun_setup.mode_mask = T_ANALOG_TV;
301 tun_setup.addr = ADDR_UNSET;
9d2599d9 302 tun_setup.type = TUNER_PHILIPS_PAL;
1b8dac15 303 tuner_call(mxb, tuner, s_type_addr, &tun_setup);
9d2599d9
MH
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;
1b8dac15 308 tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
9d2599d9 309
6acaba8e 310 /* set a default video standard */
f41737ec 311 tuner_call(mxb, core, s_std, std);
6acaba8e 312
1da177e4 313 /* mute audio on tea6420s */
5325b427
HV
314 tea6420_route_line(mxb, 6);
315 tea6420_route_cd(mxb, 6);
1da177e4 316
1b8dac15 317 /* switch to tuner-channel on tea6415c */
5325b427 318 tea6415c_call(mxb, video, s_routing, 3, 17, 0);
1da177e4 319
1b8dac15 320 /* select tuner-output on multicable on tea6415c */
5325b427 321 tea6415c_call(mxb, video, s_routing, 3, 13, 0);
a8733ca5 322
1da177e4
LT
323 /* the rest for mxb */
324 mxb->cur_input = 0;
1da177e4
LT
325 mxb->cur_mute = 1;
326
327 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
a8733ca5 328
1da177e4 329 /* check if the saa7740 (aka 'sound arena module') is present
a8733ca5 330 on the mxb. if so, we must initialize it. due to lack of
1da177e4
LT
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
2633812f
HV
338 err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
339 if (err == 1) {
1da177e4
LT
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;
2633812f
HV
346 for (i = 1; ; i++) {
347 if (-1 == mxb_saa7740_init[i].length)
1da177e4 348 break;
1da177e4 349
a8733ca5 350 msg.len = mxb_saa7740_init[i].length;
1da177e4 351 msg.buf = &mxb_saa7740_init[i].data[0];
2633812f
HV
352 err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
353 if (err != 1) {
1da177e4
LT
354 DEB_D(("failed to initialize 'sound arena module'.\n"));
355 goto err;
356 }
357 }
358 INFO(("'sound arena module' detected.\n"));
359 }
a8733ca5 360err:
1da177e4
LT
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 */
a8733ca5 365
1da177e4 366 /* some stuff is done via variables */
2633812f
HV
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);
1da177e4
LT
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... */
a8733ca5 374 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
1da177e4
LT
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
b960074f 390static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
1da177e4 391{
b960074f
HV
392 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
393 int i;
a8733ca5 394
b960074f
HV
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}
1da177e4 404
b960074f
HV
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;
1da177e4 410
b960074f
HV
411 for (i = MAXCONTROLS - 1; i >= 0; i--) {
412 if (mxb_controls[i].id == vc->id)
413 break;
1da177e4 414 }
a8733ca5 415
b960074f
HV
416 if (i < 0)
417 return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
1da177e4 418
b960074f
HV
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 }
1da177e4 424
b960074f 425 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
1da177e4
LT
426 return 0;
427}
428
b960074f 429static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
1da177e4 430{
b960074f 431 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
2633812f 432 struct mxb *mxb = (struct mxb *)dev->ext_priv;
b960074f 433 int i = 0;
1da177e4 434
b960074f
HV
435 for (i = MAXCONTROLS - 1; i >= 0; i--) {
436 if (mxb_controls[i].id == vc->id)
437 break;
438 }
1da177e4 439
b960074f
HV
440 if (i < 0)
441 return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
1da177e4 442
b960074f
HV
443 if (vc->id == V4L2_CID_AUDIO_MUTE) {
444 mxb->cur_mute = vc->value;
5325b427
HV
445 /* switch the audio-source */
446 tea6420_route_line(mxb, vc->value ? 6 :
447 video_audio_connect[mxb->cur_input]);
b960074f
HV
448 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
449 }
450 return 0;
451}
1da177e4 452
b960074f
HV
453static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
454{
455 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
223ffe5f 456 if (i->index >= MXB_INPUTS)
b960074f
HV
457 return -EINVAL;
458 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
1da177e4
LT
459 return 0;
460}
461
b960074f 462static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1da177e4 463{
b960074f 464 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
2633812f 465 struct mxb *mxb = (struct mxb *)dev->ext_priv;
b960074f 466 *i = mxb->cur_input;
a8733ca5 467
b960074f
HV
468 DEB_EE(("VIDIOC_G_INPUT %d.\n", *i));
469 return 0;
470}
a8733ca5 471
b960074f
HV
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;
5325b427 476 int err = 0;
b960074f 477 int i = 0;
1da177e4 478
b960074f 479 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
a8733ca5 480
b960074f
HV
481 if (input < 0 || input >= MXB_INPUTS)
482 return -EINVAL;
a8733ca5 483
b960074f 484 mxb->cur_input = input;
a8733ca5 485
b960074f
HV
486 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
487 input_port_selection[input].hps_sync);
1da177e4 488
b960074f
HV
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;
a8733ca5 494
5325b427
HV
495 err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
496
b960074f 497 /* connect tuner-output always to multicable */
5325b427
HV
498 if (!err)
499 err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
b960074f
HV
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;
5325b427 513 err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
b960074f
HV
514 break;
515 }
a8733ca5 516
5325b427
HV
517 if (err)
518 return err;
1da177e4 519
b960074f 520 /* switch video in saa7111a */
5325b427 521 if (saa7111a_call(mxb, video, s_routing, i, 0, 0))
b960074f
HV
522 printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
523
524 /* switch the audio-source only if necessary */
5325b427
HV
525 if (0 == mxb->cur_mute)
526 tea6420_route_line(mxb, video_audio_connect[input]);
1da177e4 527
b960074f
HV
528 return 0;
529}
1da177e4 530
b960074f
HV
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;
a8733ca5 535
b960074f
HV
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 }
a8733ca5 540
b960074f 541 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
a8733ca5 542
b960074f 543 memset(t, 0, sizeof(*t));
b960074f
HV
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;
1b8dac15 549 return call_all(dev, tuner, g_tuner, t);
b960074f 550}
1da177e4 551
b960074f
HV
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;
a8733ca5 556
b960074f
HV
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 }
1da177e4 561
b960074f 562 mxb->cur_mode = t->audmode;
1b8dac15 563 return call_all(dev, tuner, s_tuner, t);
b960074f 564}
1da177e4 565
b960074f
HV
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;
1da177e4 575 }
1da177e4 576
b960074f 577 *f = mxb->cur_freq;
1da177e4 578
b960074f
HV
579 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
580 return 0;
581}
1da177e4 582
b960074f
HV
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;
1da177e4 588
b960074f
HV
589 if (f->tuner)
590 return -EINVAL;
a8733ca5 591
b960074f
HV
592 if (V4L2_TUNER_ANALOG_TV != f->type)
593 return -EINVAL;
a8733ca5 594
b960074f
HV
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;
1da177e4 598 }
1da177e4 599
b960074f
HV
600 mxb->cur_freq = *f;
601 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
1da177e4 602
b960074f 603 /* tune in desired frequency */
1b8dac15 604 tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
1da177e4 605
b960074f
HV
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
223ffe5f 619 if (a->index > MXB_INPUTS) {
b960074f
HV
620 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
621 return -EINVAL;
1da177e4 622 }
1da177e4 623
b960074f
HV
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}
1da177e4 628
b960074f
HV
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}
a8733ca5 634
b960074f
HV
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;
1da177e4 639
1b8dac15 640 return call_all(dev, core, g_register, reg);
b960074f 641}
1da177e4 642
b960074f
HV
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;
1da177e4 646
1b8dac15 647 return call_all(dev, core, s_register, reg);
b960074f
HV
648}
649#endif
1da177e4 650
b960074f
HV
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) {
1da177e4
LT
657 case MXB_S_AUDIO_CD:
658 {
b960074f 659 int i = *(int *)arg;
a8733ca5 660
2633812f 661 if (i < 0 || i >= MXB_AUDIOS) {
b960074f 662 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n", i));
1da177e4
LT
663 return -EINVAL;
664 }
a8733ca5 665
b960074f 666 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
1da177e4 667
5325b427 668 tea6420_route_cd(mxb, i);
1da177e4
LT
669 return 0;
670 }
671 case MXB_S_AUDIO_LINE:
672 {
b960074f 673 int i = *(int *)arg;
a8733ca5 674
2633812f 675 if (i < 0 || i >= MXB_AUDIOS) {
b960074f 676 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n", i));
1da177e4
LT
677 return -EINVAL;
678 }
a8733ca5 679
b960074f 680 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
5325b427 681 tea6420_route_line(mxb, i);
1da177e4
LT
682 return 0;
683 }
b960074f
HV
684 default:
685/*
686 DEB2(printk("does not handle this ioctl.\n"));
687*/
688 return -ENOIOCTLCMD;
689 }
690 return 0;
691}
1da177e4 692
b960074f
HV
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 = (struct mxb *)dev->ext_priv;
a8733ca5 699
b960074f 700 DEB_EE(("dev:%p\n", dev));
a8733ca5 701
b960074f
HV
702 /* checking for i2c-devices can be omitted here, because we
703 already did this in "mxb_vl42_probe" */
2633812f 704
b960074f
HV
705 saa7146_vv_init(dev, &vv_data);
706 vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
707 vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
708 vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
709 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
710 vv_data.ops.vidioc_g_input = vidioc_g_input;
711 vv_data.ops.vidioc_s_input = vidioc_s_input;
712 vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
713 vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
714 vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
715 vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
716 vv_data.ops.vidioc_g_audio = vidioc_g_audio;
717 vv_data.ops.vidioc_s_audio = vidioc_s_audio;
2633812f 718#ifdef CONFIG_VIDEO_ADV_DEBUG
b960074f
HV
719 vv_data.ops.vidioc_g_register = vidioc_g_register;
720 vv_data.ops.vidioc_s_register = vidioc_s_register;
2633812f 721#endif
b960074f
HV
722 vv_data.ops.vidioc_default = vidioc_default;
723 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
724 ERR(("cannot register capture v4l2 device. skipping.\n"));
725 return -1;
726 }
727
728 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
729 if (MXB_BOARD_CAN_DO_VBI(dev)) {
730 if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
731 ERR(("cannot register vbi v4l2 device. skipping.\n"));
732 }
1da177e4 733 }
b960074f 734
b960074f
HV
735 printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
736
737 mxb_num++;
738 mxb_init_done(dev);
739 return 0;
740}
741
742static int mxb_detach(struct saa7146_dev *dev)
743{
744 struct mxb *mxb = (struct mxb *)dev->ext_priv;
745
746 DEB_EE(("dev:%p\n", dev));
747
b960074f
HV
748 saa7146_unregister_device(&mxb->video_dev,dev);
749 if (MXB_BOARD_CAN_DO_VBI(dev))
750 saa7146_unregister_device(&mxb->vbi_dev, dev);
751 saa7146_vv_release(dev);
752
753 mxb_num--;
754
755 i2c_del_adapter(&mxb->i2c_adapter);
756 kfree(mxb);
757
1da177e4
LT
758 return 0;
759}
760
c6eb8eaf 761static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
1da177e4 762{
c6eb8eaf 763 struct mxb *mxb = (struct mxb *)dev->ext_priv;
1da177e4 764
c6eb8eaf 765 if (V4L2_STD_PAL_I == standard->id) {
6acaba8e 766 v4l2_std_id std = V4L2_STD_PAL_I;
c6eb8eaf 767
1da177e4
LT
768 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
769 /* set the 7146 gpio register -- I don't know what this does exactly */
a8733ca5 770 saa7146_write(dev, GPIO_CTRL, 0x00404050);
1da177e4 771 /* unset the 7111 gpio register -- I don't know what this does exactly */
1b8dac15 772 saa7111a_call(mxb, core, s_gpio, 0);
f41737ec 773 tuner_call(mxb, core, s_std, std);
1da177e4 774 } else {
6acaba8e 775 v4l2_std_id std = V4L2_STD_PAL_BG;
c6eb8eaf 776
1da177e4
LT
777 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
778 /* set the 7146 gpio register -- I don't know what this does exactly */
a8733ca5 779 saa7146_write(dev, GPIO_CTRL, 0x00404050);
1da177e4 780 /* set the 7111 gpio register -- I don't know what this does exactly */
1b8dac15 781 saa7111a_call(mxb, core, s_gpio, 1);
f41737ec 782 tuner_call(mxb, core, s_std, std);
1da177e4
LT
783 }
784 return 0;
785}
786
787static struct saa7146_standard standard[] = {
788 {
789 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
790 .v_offset = 0x17, .v_field = 288,
791 .h_offset = 0x14, .h_pixels = 680,
792 .v_max_out = 576, .h_max_out = 768,
793 }, {
794 .name = "PAL-I", .id = V4L2_STD_PAL_I,
795 .v_offset = 0x17, .v_field = 288,
796 .h_offset = 0x14, .h_pixels = 680,
797 .v_max_out = 576, .h_max_out = 768,
798 }, {
799 .name = "NTSC", .id = V4L2_STD_NTSC,
800 .v_offset = 0x16, .v_field = 240,
801 .h_offset = 0x06, .h_pixels = 708,
802 .v_max_out = 480, .h_max_out = 640,
803 }, {
804 .name = "SECAM", .id = V4L2_STD_SECAM,
805 .v_offset = 0x14, .v_field = 288,
806 .h_offset = 0x14, .h_pixels = 720,
807 .v_max_out = 576, .h_max_out = 768,
808 }
809};
810
811static struct saa7146_pci_extension_data mxb = {
a8733ca5
MCC
812 .ext_priv = "Multimedia eXtension Board",
813 .ext = &extension,
1da177e4
LT
814};
815
816static struct pci_device_id pci_tbl[] = {
817 {
818 .vendor = PCI_VENDOR_ID_PHILIPS,
819 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
820 .subvendor = 0x0000,
821 .subdevice = 0x0000,
822 .driver_data = (unsigned long)&mxb,
823 }, {
824 .vendor = 0,
825 }
826};
827
828MODULE_DEVICE_TABLE(pci, pci_tbl);
829
830static struct saa7146_ext_vv vv_data = {
831 .inputs = MXB_INPUTS,
832 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
833 .stds = &standard[0],
834 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
a8733ca5 835 .std_callback = &std_callback,
1da177e4
LT
836};
837
838static struct saa7146_extension extension = {
839 .name = MXB_IDENTIFIER,
840 .flags = SAA7146_USE_I2C_IRQ,
a8733ca5 841
1da177e4
LT
842 .pci_tbl = &pci_tbl[0],
843 .module = THIS_MODULE,
844
845 .probe = mxb_probe,
846 .attach = mxb_attach,
847 .detach = mxb_detach,
848
849 .irq_mask = 0,
850 .irq_func = NULL,
a8733ca5 851};
1da177e4
LT
852
853static int __init mxb_init_module(void)
854{
2633812f 855 if (saa7146_register_extension(&extension)) {
1da177e4
LT
856 DEB_S(("failed to register extension.\n"));
857 return -ENODEV;
858 }
a8733ca5 859
1da177e4
LT
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");