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