blob: 486234d41b5669353375d1fa62a6fa2ae918ed6c [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 mxb - v4l2 driver for the Multimedia eXtension Board
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6 Visit http://www.mihu.de/linux/saa7146/mxb/
7 for further details about this card.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24#define DEBUG_VARIABLE debug
25
26#include <media/saa7146_vv.h>
27#include <media/tuner.h>
28#include <linux/video_decoder.h>
29
30#include "mxb.h"
31#include "tea6415c.h"
32#include "tea6420.h"
33#include "tda9840.h"
34
35#define I2C_SAA7111 0x24
36
37#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
38
39/* global variable */
40static int mxb_num = 0;
41
42/* initial frequence the tuner will be tuned to.
43 in verden (lower saxony, germany) 4148 is a
44 channel called "phoenix" */
45static int freq = 4148;
46module_param(freq, int, 0644);
47MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
48
49static int debug = 0;
50module_param(debug, int, 0644);
51MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
52
53#define MXB_INPUTS 4
54enum { TUNER, AUX1, AUX3, AUX3_YC };
55
56static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
57 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
58 { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
59 { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
60 { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
61};
62
63/* this array holds the information, which port of the saa7146 each
64 input actually uses. the mxb uses port 0 for every input */
65static struct {
66 int hps_source;
67 int hps_sync;
68} input_port_selection[MXB_INPUTS] = {
69 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
70 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
71 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
72 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
73};
74
75/* this array holds the information of the audio source (mxb_audios),
76 which has to be switched corresponding to the video source (mxb_channels) */
77static int video_audio_connect[MXB_INPUTS] =
78 { 0, 1, 3, 3 };
79
80/* these are the necessary input-output-pins for bringing one audio source
81(see above) to the CD-output */
82static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] =
83 {
84 {{1,1,0},{1,1,0}}, /* Tuner */
85 {{5,1,0},{6,1,0}}, /* AUX 1 */
86 {{4,1,0},{6,1,0}}, /* AUX 2 */
87 {{3,1,0},{6,1,0}}, /* AUX 3 */
88 {{1,1,0},{3,1,0}}, /* Radio */
89 {{1,1,0},{2,1,0}}, /* CD-Rom */
90 {{6,1,0},{6,1,0}} /* Mute */
91 };
92
93/* these are the necessary input-output-pins for bringing one audio source
94(see above) to the line-output */
95static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] =
96 {
97 {{2,3,0},{1,2,0}},
98 {{5,3,0},{6,2,0}},
99 {{4,3,0},{6,2,0}},
100 {{3,3,0},{6,2,0}},
101 {{2,3,0},{3,2,0}},
102 {{2,3,0},{2,2,0}},
103 {{6,3,0},{6,2,0}} /* Mute */
104 };
105
106#define MAXCONTROLS 1
107static struct v4l2_queryctrl mxb_controls[] = {
108 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
109};
110
111static struct saa7146_extension_ioctls ioctls[] = {
112 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
113 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
114 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
115 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
116 { VIDIOC_G_CTRL, SAA7146_BEFORE },
117 { VIDIOC_S_CTRL, SAA7146_BEFORE },
118 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
119 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
120 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
121 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
122 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
123 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
124 { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
125 { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
126 { 0, 0 }
127};
128
129struct mxb
130{
131 struct video_device *video_dev;
132 struct video_device *vbi_dev;
133
134 struct i2c_adapter i2c_adapter;
135
136 struct i2c_client* saa7111a;
137 struct i2c_client* tda9840;
138 struct i2c_client* tea6415c;
139 struct i2c_client* tuner;
140 struct i2c_client* tea6420_1;
141 struct i2c_client* tea6420_2;
142
143 int cur_mode; /* current audio mode (mono, stereo, ...) */
144 int cur_input; /* current input */
145 int cur_freq; /* current frequency the tuner is tuned to */
146 int cur_mute; /* current mute status */
147};
148
149static struct saa7146_extension extension;
150
151static int mxb_probe(struct saa7146_dev* dev)
152{
153 struct mxb* mxb = NULL;
154 struct i2c_client *client;
155 struct list_head *item;
156 int result;
157
158 if ((result = request_module("saa7111")) < 0) {
159 printk("mxb: saa7111 i2c module not available.\n");
160 return -ENODEV;
161 }
162 if ((result = request_module("tuner")) < 0) {
163 printk("mxb: tuner i2c module not available.\n");
164 return -ENODEV;
165 }
166 if ((result = request_module("tea6420")) < 0) {
167 printk("mxb: tea6420 i2c module not available.\n");
168 return -ENODEV;
169 }
170 if ((result = request_module("tea6415c")) < 0) {
171 printk("mxb: tea6415c i2c module not available.\n");
172 return -ENODEV;
173 }
174 if ((result = request_module("tda9840")) < 0) {
175 printk("mxb: tda9840 i2c module not available.\n");
176 return -ENODEV;
177 }
178
179 mxb = (struct mxb*)kmalloc(sizeof(struct mxb), GFP_KERNEL);
180 if( NULL == mxb ) {
181 DEB_D(("not enough kernel memory.\n"));
182 return -ENOMEM;
183 }
184 memset(mxb, 0x0, sizeof(struct mxb));
185
186 mxb->i2c_adapter = (struct i2c_adapter) {
187 .class = I2C_CLASS_TV_ANALOG,
188 .name = "mxb",
189 };
190
191 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
192 if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
193 DEB_S(("cannot register i2c-device. skipping.\n"));
194 kfree(mxb);
195 return -EFAULT;
196 }
197
198 /* loop through all i2c-devices on the bus and look who is there */
199 list_for_each(item,&mxb->i2c_adapter.clients) {
200 client = list_entry(item, struct i2c_client, list);
201 if( I2C_TEA6420_1 == client->addr )
202 mxb->tea6420_1 = client;
203 if( I2C_TEA6420_2 == client->addr )
204 mxb->tea6420_2 = client;
205 if( I2C_TEA6415C_2 == client->addr )
206 mxb->tea6415c = client;
207 if( I2C_TDA9840 == client->addr )
208 mxb->tda9840 = client;
209 if( I2C_SAA7111 == client->addr )
210 mxb->saa7111a = client;
211 if( 0x60 == client->addr )
212 mxb->tuner = client;
213 }
214
215 /* check if all devices are present */
216 if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c
217 || 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) {
218
219 printk("mxb: did not find all i2c devices. aborting\n");
220 i2c_del_adapter(&mxb->i2c_adapter);
221 kfree(mxb);
222 return -ENODEV;
223 }
224
225 /* all devices are present, probe was successful */
226
227 /* we store the pointer in our private data field */
228 dev->ext_priv = mxb;
229
230 return 0;
231}
232
233/* some init data for the saa7740, the so-called 'sound arena module'.
234 there are no specs available, so we simply use some init values */
235static struct {
236 int length;
237 char data[9];
238} mxb_saa7740_init[] = {
239 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
240 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
241 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
242 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
243 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
244 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
245 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
246 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
247 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
248 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
249 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
250 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
251 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
252 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
253 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
254 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
255 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
256 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
257 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
258 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
259 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
260 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
261 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
262 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
263 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
264 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
265 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
266 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
267 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
268 { 3, { 0x48, 0x00, 0x01 } },
269 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
270 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
271 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
272 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
273 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
274 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
275 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
276 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
277 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
278 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
279 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
280 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
281 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
282 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
283 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
284 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
285 { 3, { 0x80, 0xb3, 0x0a } },
286 {-1, { 0} }
287};
288
289static const unsigned char mxb_saa7111_init[] = {
290 0x00, 0x00, /* 00 - ID byte */
291 0x01, 0x00, /* 01 - reserved */
292
293 /*front end */
294 0x02, 0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */
295 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
296 0x04, 0x00, /* 04 - GAI1=256 */
297 0x05, 0x00, /* 05 - GAI2=256 */
298
299 /* decoder */
300 0x06, 0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */
301 0x07, 0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */
302 0x08, 0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */
303 0x09, 0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */
304 0x0a, 0x80, /* 0a - BRIG=128 */
305 0x0b, 0x47, /* 0b - CONT=1.109 */
306 0x0c, 0x40, /* 0c - SATN=1.0 */
307 0x0d, 0x00, /* 0d - HUE=0 */
308 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
309 0x0f, 0x00, /* 0f - reserved */
310 0x10, 0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */
311 0x11, 0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
312 0x12, 0x80, /* 12 - xx output control 2 */
313 0x13, 0x30, /* 13 - xx output control 3 */
314 0x14, 0x00, /* 14 - reserved */
315 0x15, 0x15, /* 15 - VBI */
316 0x16, 0x04, /* 16 - VBI */
317 0x17, 0x00, /* 17 - VBI */
318};
319
320/* bring hardware to a sane state. this has to be done, just in case someone
321 wants to capture from this device before it has been properly initialized.
322 the capture engine would badly fail, because no valid signal arrives on the
323 saa7146, thus leading to timeouts and stuff. */
324static int mxb_init_done(struct saa7146_dev* dev)
325{
326 struct mxb* mxb = (struct mxb*)dev->ext_priv;
327 struct video_decoder_init init;
328 struct i2c_msg msg;
Mauro Carvalho Chehab85369df2005-07-12 13:58:59 -0700329 struct tuner_setup tun_setup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330
331 int i = 0, err = 0;
332 struct tea6415c_multiplex vm;
333
334 /* select video mode in saa7111a */
335 i = VIDEO_MODE_PAL;
336 /* fixme: currently pointless: gets overwritten by configuration below */
337 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
338
339 /* write configuration to saa7111a */
340 init.data = mxb_saa7111_init;
341 init.len = sizeof(mxb_saa7111_init);
342 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init);
343
344 /* select tuner-output on saa7111a */
345 i = 0;
346 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);
347
348 /* enable vbi bypass */
349 i = 1;
350 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
351
352 /* select a tuner type */
Mauro Carvalho Chehab85369df2005-07-12 13:58:59 -0700353 tun_setup.mode_mask = T_ANALOG_TV;
354 tun_setup.addr = ADDR_UNSET;
355 tun_setup.type = 5;
356 mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE_ADDR, &tun_setup);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
358 /* mute audio on tea6420s */
359 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
360 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
361 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]);
362 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]);
363
364 /* switch to tuner-channel on tea6415c*/
365 vm.out = 17;
366 vm.in = 3;
367 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
368
369 /* select tuner-output on multicable on tea6415c*/
370 vm.in = 3;
371 vm.out = 13;
372 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
373
374 /* tune in some frequency on tuner */
375 mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &freq);
376
377 /* the rest for mxb */
378 mxb->cur_input = 0;
379 mxb->cur_freq = freq;
380 mxb->cur_mute = 1;
381
382 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
383 mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
384
385 /* check if the saa7740 (aka 'sound arena module') is present
386 on the mxb. if so, we must initialize it. due to lack of
387 informations about the saa7740, the values were reverse
388 engineered. */
389 msg.addr = 0x1b;
390 msg.flags = 0;
391 msg.len = mxb_saa7740_init[0].length;
392 msg.buf = &mxb_saa7740_init[0].data[0];
393
394 if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
395 /* the sound arena module is a pos, that's probably the reason
396 philips refuses to hand out a datasheet for the saa7740...
397 it seems to screw up the i2c bus, so we disable fast irq
398 based i2c transactions here and rely on the slow and safe
399 polling method ... */
400 extension.flags &= ~SAA7146_USE_I2C_IRQ;
401 for(i = 1;;i++) {
402 if( -1 == mxb_saa7740_init[i].length ) {
403 break;
404 }
405
406 msg.len = mxb_saa7740_init[i].length;
407 msg.buf = &mxb_saa7740_init[i].data[0];
408 if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
409 DEB_D(("failed to initialize 'sound arena module'.\n"));
410 goto err;
411 }
412 }
413 INFO(("'sound arena module' detected.\n"));
414 }
415err:
416 /* the rest for saa7146: you should definitely set some basic values
417 for the input-port handling of the saa7146. */
418
419 /* ext->saa has been filled by the core driver */
420
421 /* some stuff is done via variables */
422 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);
423
424 /* some stuff is done via direct write to the registers */
425
426 /* this is ugly, but because of the fact that this is completely
427 hardware dependend, it should be done directly... */
428 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
429 saa7146_write(dev, DD1_INIT, 0x02000200);
430 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
431
432 return 0;
433}
434
435/* interrupt-handler. this gets called when irq_mask is != 0.
436 it must clear the interrupt-bits in irq_mask it has handled */
437/*
438void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
439{
440 struct mxb* mxb = (struct mxb*)dev->ext_priv;
441}
442*/
443
444static struct saa7146_ext_vv vv_data;
445
446/* this function only gets called when the probing was successful */
447static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
448{
449 struct mxb* mxb = (struct mxb*)dev->ext_priv;
450
451 DEB_EE(("dev:%p\n",dev));
452
453 /* checking for i2c-devices can be omitted here, because we
454 already did this in "mxb_vl42_probe" */
455
456 saa7146_vv_init(dev,&vv_data);
457 if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
458 ERR(("cannot register capture v4l2 device. skipping.\n"));
459 return -1;
460 }
461
462 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
463 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
464 if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
465 ERR(("cannot register vbi v4l2 device. skipping.\n"));
466 }
467 }
468
469 i2c_use_client(mxb->tea6420_1);
470 i2c_use_client(mxb->tea6420_2);
471 i2c_use_client(mxb->tea6415c);
472 i2c_use_client(mxb->tda9840);
473 i2c_use_client(mxb->saa7111a);
474 i2c_use_client(mxb->tuner);
475
476 printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);
477
478 mxb_num++;
479 mxb_init_done(dev);
480 return 0;
481}
482
483static int mxb_detach(struct saa7146_dev* dev)
484{
485 struct mxb* mxb = (struct mxb*)dev->ext_priv;
486
487 DEB_EE(("dev:%p\n",dev));
488
489 i2c_release_client(mxb->tea6420_1);
490 i2c_release_client(mxb->tea6420_2);
491 i2c_release_client(mxb->tea6415c);
492 i2c_release_client(mxb->tda9840);
493 i2c_release_client(mxb->saa7111a);
494 i2c_release_client(mxb->tuner);
495
496 saa7146_unregister_device(&mxb->video_dev,dev);
497 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
498 saa7146_unregister_device(&mxb->vbi_dev,dev);
499 }
500 saa7146_vv_release(dev);
501
502 mxb_num--;
503
504 i2c_del_adapter(&mxb->i2c_adapter);
505 kfree(mxb);
506
507 return 0;
508}
509
510static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
511{
512 struct saa7146_dev *dev = fh->dev;
513 struct mxb* mxb = (struct mxb*)dev->ext_priv;
514 struct saa7146_vv *vv = dev->vv_data;
515
516 switch(cmd) {
517 case VIDIOC_ENUMINPUT:
518 {
519 struct v4l2_input *i = arg;
520
521 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
522 if( i->index < 0 || i->index >= MXB_INPUTS) {
523 return -EINVAL;
524 }
525 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
526
527 return 0;
528 }
529 /* the saa7146 provides some controls (brightness, contrast, saturation)
530 which gets registered *after* this function. because of this we have
531 to return with a value != 0 even if the function succeded.. */
532 case VIDIOC_QUERYCTRL:
533 {
534 struct v4l2_queryctrl *qc = arg;
535 int i;
536
537 for (i = MAXCONTROLS - 1; i >= 0; i--) {
538 if (mxb_controls[i].id == qc->id) {
539 *qc = mxb_controls[i];
540 DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));
541 return 0;
542 }
543 }
544 return -EAGAIN;
545 }
546 case VIDIOC_G_CTRL:
547 {
548 struct v4l2_control *vc = arg;
549 int i;
550
551 for (i = MAXCONTROLS - 1; i >= 0; i--) {
552 if (mxb_controls[i].id == vc->id) {
553 break;
554 }
555 }
556
557 if( i < 0 ) {
558 return -EAGAIN;
559 }
560
561 switch (vc->id ) {
562 case V4L2_CID_AUDIO_MUTE: {
563 vc->value = mxb->cur_mute;
564 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
565 return 0;
566 }
567 }
568
569 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
570 return 0;
571 }
572
573 case VIDIOC_S_CTRL:
574 {
575 struct v4l2_control *vc = arg;
576 int i = 0;
577
578 for (i = MAXCONTROLS - 1; i >= 0; i--) {
579 if (mxb_controls[i].id == vc->id) {
580 break;
581 }
582 }
583
584 if( i < 0 ) {
585 return -EAGAIN;
586 }
587
588 switch (vc->id ) {
589 case V4L2_CID_AUDIO_MUTE: {
590 mxb->cur_mute = vc->value;
591 if( 0 == vc->value ) {
592 /* switch the audio-source */
593 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
594 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
595 } else {
596 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
597 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
598 }
599 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
600 break;
601 }
602 }
603 return 0;
604 }
605 case VIDIOC_G_INPUT:
606 {
607 int *input = (int *)arg;
608 *input = mxb->cur_input;
609
610 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
611 return 0;
612 }
613 case VIDIOC_S_INPUT:
614 {
615 int input = *(int *)arg;
616 struct tea6415c_multiplex vm;
617 int i = 0;
618
619 DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
620
621 if (input < 0 || input >= MXB_INPUTS) {
622 return -EINVAL;
623 }
624
625 /* fixme: locke das setzen des inputs mit hilfe des mutexes
626 down(&dev->lock);
627 video_mux(dev,*i);
628 up(&dev->lock);
629 */
630
631 /* fixme: check if streaming capture
632 if ( 0 != dev->streaming ) {
633 DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
634 return -EPERM;
635 }
636 */
637
638 mxb->cur_input = input;
639
640 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
641
642 /* prepare switching of tea6415c and saa7111a;
643 have a look at the 'background'-file for further informations */
644 switch( input ) {
645
646 case TUNER:
647 {
648 i = 0;
649 vm.in = 3;
650 vm.out = 17;
651
652 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
653 printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
654 return -EFAULT;
655 }
656 /* connect tuner-output always to multicable */
657 vm.in = 3;
658 vm.out = 13;
659 break;
660 }
661 case AUX3_YC:
662 {
663 /* nothing to be done here. aux3_yc is
664 directly connected to the saa711a */
665 i = 5;
666 break;
667 }
668 case AUX3:
669 {
670 /* nothing to be done here. aux3 is
671 directly connected to the saa711a */
672 i = 1;
673 break;
674 }
675 case AUX1:
676 {
677 i = 0;
678 vm.in = 1;
679 vm.out = 17;
680 break;
681 }
682 }
683
684 /* switch video in tea6415c only if necessary */
685 switch( input ) {
686 case TUNER:
687 case AUX1:
688 {
689 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
690 printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");
691 return -EFAULT;
692 }
693 break;
694 }
695 default:
696 {
697 break;
698 }
699 }
700
701 /* switch video in saa7111a */
702 if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
703 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
704 }
705
706 /* switch the audio-source only if necessary */
707 if( 0 == mxb->cur_mute ) {
708 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);
709 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);
710 }
711
712 return 0;
713 }
714 case VIDIOC_G_TUNER:
715 {
716 struct v4l2_tuner *t = arg;
717 int byte = 0;
718
719 if( 0 != t->index ) {
720 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
721 return -EINVAL;
722 }
723
724 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
725
726 memset(t,0,sizeof(*t));
727 strcpy(t->name, "Television");
728
729 t->type = V4L2_TUNER_ANALOG_TV;
730 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
731 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
732 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
733 /* FIXME: add the real signal strength here */
734 t->signal = 0xffff;
735 t->afc = 0;
736
737 mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);
738 t->audmode = mxb->cur_mode;
739
740 if( byte < 0 ) {
741 t->rxsubchans = V4L2_TUNER_SUB_MONO;
742 } else {
743 switch(byte) {
744 case TDA9840_MONO_DETECT: {
745 t->rxsubchans = V4L2_TUNER_SUB_MONO;
746 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));
747 break;
748 }
749 case TDA9840_DUAL_DETECT: {
750 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
751 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));
752 break;
753 }
754 case TDA9840_STEREO_DETECT: {
755 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
756 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));
757 break;
758 }
759 default: { /* TDA9840_INCORRECT_DETECT */
760 t->rxsubchans = V4L2_TUNER_MODE_MONO;
761 DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));
762 break;
763 }
764 }
765 }
766
767 return 0;
768 }
769 case VIDIOC_S_TUNER:
770 {
771 struct v4l2_tuner *t = arg;
772 int result = 0;
773 int byte = 0;
774
775 if( 0 != t->index ) {
776 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
777 return -EINVAL;
778 }
779
780 switch(t->audmode) {
781 case V4L2_TUNER_MODE_STEREO: {
782 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
783 byte = TDA9840_SET_STEREO;
784 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
785 break;
786 }
787 case V4L2_TUNER_MODE_LANG1: {
788 mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
789 byte = TDA9840_SET_LANG1;
790 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
791 break;
792 }
793 case V4L2_TUNER_MODE_LANG2: {
794 mxb->cur_mode = V4L2_TUNER_MODE_LANG2;
795 byte = TDA9840_SET_LANG2;
796 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
797 break;
798 }
799 default: { /* case V4L2_TUNER_MODE_MONO: {*/
800 mxb->cur_mode = V4L2_TUNER_MODE_MONO;
801 byte = TDA9840_SET_MONO;
802 DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
803 break;
804 }
805 }
806
807 if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
808 printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
809 }
810
811 return 0;
812 }
813 case VIDIOC_G_FREQUENCY:
814 {
815 struct v4l2_frequency *f = arg;
816
817 if(0 != mxb->cur_input) {
818 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
819 return -EINVAL;
820 }
821
822 memset(f,0,sizeof(*f));
823 f->type = V4L2_TUNER_ANALOG_TV;
824 f->frequency = mxb->cur_freq;
825
826 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq));
827 return 0;
828 }
829 case VIDIOC_S_FREQUENCY:
830 {
831 struct v4l2_frequency *f = arg;
832 int t_locked = 0;
833 int v_byte = 0;
834
835 if (0 != f->tuner)
836 return -EINVAL;
837
838 if (V4L2_TUNER_ANALOG_TV != f->type)
839 return -EINVAL;
840
841 if(0 != mxb->cur_input) {
842 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
843 return -EINVAL;
844 }
845
846 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency));
847
848 mxb->cur_freq = f->frequency;
849
850 /* tune in desired frequency */
851 mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &mxb->cur_freq);
852
853 /* check if pll of tuner & saa7111a is locked */
854// mxb->tuner->driver->command(mxb->tuner,TUNER_IS_LOCKED, &t_locked);
855 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_GET_STATUS, &v_byte);
856
857 /* not locked -- anything to do here ? */
858 if( 0 == t_locked || 0 == (v_byte & DECODER_STATUS_GOOD)) {
859 }
860
861 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
862 spin_lock(&dev->slock);
863 vv->vbi_fieldcount = 0;
864 spin_unlock(&dev->slock);
865
866 return 0;
867 }
868 case MXB_S_AUDIO_CD:
869 {
870 int i = *(int*)arg;
871
872 if( i < 0 || i >= MXB_AUDIOS ) {
873 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
874 return -EINVAL;
875 }
876
877 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
878
879 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
880 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
881
882 return 0;
883 }
884 case MXB_S_AUDIO_LINE:
885 {
886 int i = *(int*)arg;
887
888 if( i < 0 || i >= MXB_AUDIOS ) {
889 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
890 return -EINVAL;
891 }
892
893 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
894 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
895 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
896
897 return 0;
898 }
899 case VIDIOC_G_AUDIO:
900 {
901 struct v4l2_audio *a = arg;
902
903 if( a->index < 0 || a->index > MXB_INPUTS ) {
904 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
905 return -EINVAL;
906 }
907
908 DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
909 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
910
911 return 0;
912 }
913 case VIDIOC_S_AUDIO:
914 {
915 struct v4l2_audio *a = arg;
916 DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
917 return 0;
918 }
919 default:
920/*
921 DEB2(printk("does not handle this ioctl.\n"));
922*/
923 return -ENOIOCTLCMD;
924 }
925 return 0;
926}
927
928static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
929{
930 struct mxb* mxb = (struct mxb*)dev->ext_priv;
931 int zero = 0;
932 int one = 1;
933
934 if(V4L2_STD_PAL_I == std->id ) {
935 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
936 /* set the 7146 gpio register -- I don't know what this does exactly */
937 saa7146_write(dev, GPIO_CTRL, 0x00404050);
938 /* unset the 7111 gpio register -- I don't know what this does exactly */
939 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
940 } else {
941 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
942 /* set the 7146 gpio register -- I don't know what this does exactly */
943 saa7146_write(dev, GPIO_CTRL, 0x00404050);
944 /* set the 7111 gpio register -- I don't know what this does exactly */
945 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
946 }
947 return 0;
948}
949
950static struct saa7146_standard standard[] = {
951 {
952 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
953 .v_offset = 0x17, .v_field = 288,
954 .h_offset = 0x14, .h_pixels = 680,
955 .v_max_out = 576, .h_max_out = 768,
956 }, {
957 .name = "PAL-I", .id = V4L2_STD_PAL_I,
958 .v_offset = 0x17, .v_field = 288,
959 .h_offset = 0x14, .h_pixels = 680,
960 .v_max_out = 576, .h_max_out = 768,
961 }, {
962 .name = "NTSC", .id = V4L2_STD_NTSC,
963 .v_offset = 0x16, .v_field = 240,
964 .h_offset = 0x06, .h_pixels = 708,
965 .v_max_out = 480, .h_max_out = 640,
966 }, {
967 .name = "SECAM", .id = V4L2_STD_SECAM,
968 .v_offset = 0x14, .v_field = 288,
969 .h_offset = 0x14, .h_pixels = 720,
970 .v_max_out = 576, .h_max_out = 768,
971 }
972};
973
974static struct saa7146_pci_extension_data mxb = {
975 .ext_priv = "Multimedia eXtension Board",
976 .ext = &extension,
977};
978
979static struct pci_device_id pci_tbl[] = {
980 {
981 .vendor = PCI_VENDOR_ID_PHILIPS,
982 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
983 .subvendor = 0x0000,
984 .subdevice = 0x0000,
985 .driver_data = (unsigned long)&mxb,
986 }, {
987 .vendor = 0,
988 }
989};
990
991MODULE_DEVICE_TABLE(pci, pci_tbl);
992
993static struct saa7146_ext_vv vv_data = {
994 .inputs = MXB_INPUTS,
995 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
996 .stds = &standard[0],
997 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
998 .std_callback = &std_callback,
999 .ioctls = &ioctls[0],
1000 .ioctl = mxb_ioctl,
1001};
1002
1003static struct saa7146_extension extension = {
1004 .name = MXB_IDENTIFIER,
1005 .flags = SAA7146_USE_I2C_IRQ,
1006
1007 .pci_tbl = &pci_tbl[0],
1008 .module = THIS_MODULE,
1009
1010 .probe = mxb_probe,
1011 .attach = mxb_attach,
1012 .detach = mxb_detach,
1013
1014 .irq_mask = 0,
1015 .irq_func = NULL,
1016};
1017
1018static int __init mxb_init_module(void)
1019{
1020 if( 0 != saa7146_register_extension(&extension)) {
1021 DEB_S(("failed to register extension.\n"));
1022 return -ENODEV;
1023 }
1024
1025 return 0;
1026}
1027
1028static void __exit mxb_cleanup_module(void)
1029{
1030 saa7146_unregister_extension(&extension);
1031}
1032
1033module_init(mxb_init_module);
1034module_exit(mxb_cleanup_module);
1035
1036MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
1037MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
1038MODULE_LICENSE("GPL");