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