V4L/DVB (8944): saa5249: convert i2c driver for new i2c API
[deliverable/linux.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 139
2633812f
HV
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;
1da177e4
LT
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{
2633812f 157 struct mxb *mxb = data;
961f80f9
JD
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 } },
2633812f 301 {-1, { 0 } }
1da177e4
LT
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;
2633812f 317 struct tea6415c_multiplex vm;
1da177e4
LT
318
319 /* select video mode in saa7111a */
707ecf46 320 mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_S_STD, &std);
1da177e4
LT
321
322 /* select tuner-output on saa7111a */
323 i = 0;
707ecf46
HV
324 route.input = SAA7115_COMPOSITE0;
325 route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS;
326 mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route);
1da177e4
LT
327
328 /* select a tuner type */
85369df3
MCC
329 tun_setup.mode_mask = T_ANALOG_TV;
330 tun_setup.addr = ADDR_UNSET;
9d2599d9 331 tun_setup.type = TUNER_PHILIPS_PAL;
707ecf46 332 mxb->tuner->driver->command(mxb->tuner, TUNER_SET_TYPE_ADDR, &tun_setup);
9d2599d9
MH
333 /* tune in some frequency on tuner */
334 mxb->cur_freq.tuner = 0;
335 mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
336 mxb->cur_freq.frequency = freq;
337 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
338 &mxb->cur_freq);
339
6acaba8e
MH
340 /* set a default video standard */
341 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
342
1da177e4 343 /* mute audio on tea6420s */
2633812f
HV
344 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[6][0]);
345 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[6][1]);
346 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[6][0]);
347 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[6][1]);
1da177e4
LT
348
349 /* switch to tuner-channel on tea6415c*/
350 vm.out = 17;
351 vm.in = 3;
2633812f 352 mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
1da177e4
LT
353
354 /* select tuner-output on multicable on tea6415c*/
355 vm.in = 3;
356 vm.out = 13;
2633812f 357 mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
a8733ca5 358
1da177e4
LT
359 /* the rest for mxb */
360 mxb->cur_input = 0;
1da177e4
LT
361 mxb->cur_mute = 1;
362
363 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
a8733ca5 364
1da177e4 365 /* check if the saa7740 (aka 'sound arena module') is present
a8733ca5 366 on the mxb. if so, we must initialize it. due to lack of
1da177e4
LT
367 informations about the saa7740, the values were reverse
368 engineered. */
369 msg.addr = 0x1b;
370 msg.flags = 0;
371 msg.len = mxb_saa7740_init[0].length;
372 msg.buf = &mxb_saa7740_init[0].data[0];
373
2633812f
HV
374 err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
375 if (err == 1) {
1da177e4
LT
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;
2633812f
HV
382 for (i = 1; ; i++) {
383 if (-1 == mxb_saa7740_init[i].length)
1da177e4 384 break;
1da177e4 385
a8733ca5 386 msg.len = mxb_saa7740_init[i].length;
1da177e4 387 msg.buf = &mxb_saa7740_init[i].data[0];
2633812f
HV
388 err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
389 if (err != 1) {
1da177e4
LT
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 402 /* some stuff is done via variables */
2633812f
HV
403 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source,
404 input_port_selection[mxb->cur_input].hps_sync);
1da177e4
LT
405
406 /* some stuff is done via direct write to the registers */
407
408 /* this is ugly, but because of the fact that this is completely
409 hardware dependend, it should be done directly... */
a8733ca5 410 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
1da177e4
LT
411 saa7146_write(dev, DD1_INIT, 0x02000200);
412 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
413
414 return 0;
415}
416
417/* interrupt-handler. this gets called when irq_mask is != 0.
418 it must clear the interrupt-bits in irq_mask it has handled */
419/*
420void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
421{
422 struct mxb* mxb = (struct mxb*)dev->ext_priv;
423}
424*/
425
426static struct saa7146_ext_vv vv_data;
427
428/* this function only gets called when the probing was successful */
2633812f 429static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1da177e4 430{
2633812f 431 struct mxb *mxb = (struct mxb *)dev->ext_priv;
a8733ca5 432
2633812f 433 DEB_EE(("dev:%p\n", dev));
1da177e4
LT
434
435 /* checking for i2c-devices can be omitted here, because we
436 already did this in "mxb_vl42_probe" */
437
a832781c
HV
438 saa7146_vv_init(dev, &vv_data);
439 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
1da177e4
LT
440 ERR(("cannot register capture v4l2 device. skipping.\n"));
441 return -1;
442 }
a8733ca5 443
1da177e4 444 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
a832781c
HV
445 if (MXB_BOARD_CAN_DO_VBI(dev)) {
446 if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
1da177e4
LT
447 ERR(("cannot register vbi v4l2 device. skipping.\n"));
448 }
449 }
450
451 i2c_use_client(mxb->tea6420_1);
452 i2c_use_client(mxb->tea6420_2);
453 i2c_use_client(mxb->tea6415c);
454 i2c_use_client(mxb->tda9840);
455 i2c_use_client(mxb->saa7111a);
456 i2c_use_client(mxb->tuner);
457
a832781c 458 printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
1da177e4
LT
459
460 mxb_num++;
461 mxb_init_done(dev);
462 return 0;
463}
464
2633812f 465static int mxb_detach(struct saa7146_dev *dev)
1da177e4 466{
2633812f 467 struct mxb *mxb = (struct mxb *)dev->ext_priv;
1da177e4 468
2633812f 469 DEB_EE(("dev:%p\n", dev));
1da177e4
LT
470
471 i2c_release_client(mxb->tea6420_1);
472 i2c_release_client(mxb->tea6420_2);
473 i2c_release_client(mxb->tea6415c);
474 i2c_release_client(mxb->tda9840);
475 i2c_release_client(mxb->saa7111a);
476 i2c_release_client(mxb->tuner);
477
478 saa7146_unregister_device(&mxb->video_dev,dev);
2633812f
HV
479 if (MXB_BOARD_CAN_DO_VBI(dev))
480 saa7146_unregister_device(&mxb->vbi_dev, dev);
1da177e4
LT
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;
2633812f 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 502 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
2633812f 503 if (i->index < 0 || i->index >= MXB_INPUTS)
1da177e4 504 return -EINVAL;
1da177e4 505 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
1da177e4
LT
506 return 0;
507 }
508 /* the saa7146 provides some controls (brightness, contrast, saturation)
509 which gets registered *after* this function. because of this we have
510 to return with a value != 0 even if the function succeded.. */
511 case VIDIOC_QUERYCTRL:
512 {
513 struct v4l2_queryctrl *qc = arg;
514 int i;
515
516 for (i = MAXCONTROLS - 1; i >= 0; i--) {
517 if (mxb_controls[i].id == qc->id) {
518 *qc = mxb_controls[i];
2633812f 519 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
1da177e4
LT
520 return 0;
521 }
522 }
523 return -EAGAIN;
524 }
525 case VIDIOC_G_CTRL:
526 {
527 struct v4l2_control *vc = arg;
528 int i;
529
530 for (i = MAXCONTROLS - 1; i >= 0; i--) {
2633812f 531 if (mxb_controls[i].id == vc->id)
1da177e4 532 break;
1da177e4 533 }
a8733ca5 534
2633812f 535 if (i < 0)
1da177e4 536 return -EAGAIN;
a8733ca5 537
2633812f
HV
538 if (vc->id == V4L2_CID_AUDIO_MUTE) {
539 vc->value = mxb->cur_mute;
540 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
541 return 0;
1da177e4 542 }
a8733ca5 543
2633812f 544 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
1da177e4
LT
545 return 0;
546 }
547
548 case VIDIOC_S_CTRL:
549 {
2633812f 550 struct v4l2_control *vc = arg;
1da177e4 551 int i = 0;
a8733ca5 552
1da177e4 553 for (i = MAXCONTROLS - 1; i >= 0; i--) {
2633812f 554 if (mxb_controls[i].id == vc->id)
1da177e4 555 break;
1da177e4 556 }
a8733ca5 557
2633812f 558 if (i < 0)
1da177e4 559 return -EAGAIN;
a8733ca5 560
2633812f
HV
561 if (vc->id == V4L2_CID_AUDIO_MUTE) {
562 mxb->cur_mute = vc->value;
563 if (!vc->value) {
564 /* switch the audio-source */
565 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
566 &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
567 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
568 &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
569 } else {
570 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
571 &TEA6420_line[6][0]);
572 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
573 &TEA6420_line[6][1]);
1da177e4 574 }
2633812f 575 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
1da177e4
LT
576 }
577 return 0;
578 }
579 case VIDIOC_G_INPUT:
580 {
581 int *input = (int *)arg;
582 *input = mxb->cur_input;
583
2633812f 584 DEB_EE(("VIDIOC_G_INPUT %d.\n", *input));
a8733ca5
MCC
585 return 0;
586 }
1da177e4
LT
587 case VIDIOC_S_INPUT:
588 {
589 int input = *(int *)arg;
707ecf46
HV
590 struct tea6415c_multiplex vm;
591 struct v4l2_routing route;
1da177e4
LT
592 int i = 0;
593
2633812f 594 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
1da177e4 595
2633812f 596 if (input < 0 || input >= MXB_INPUTS)
1da177e4 597 return -EINVAL;
a8733ca5 598
1da177e4 599 mxb->cur_input = input;
a8733ca5 600
2633812f
HV
601 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
602 input_port_selection[input].hps_sync);
a8733ca5 603
1da177e4
LT
604 /* prepare switching of tea6415c and saa7111a;
605 have a look at the 'background'-file for further informations */
2633812f
HV
606 switch (input) {
607 case TUNER:
608 i = SAA7115_COMPOSITE0;
609 vm.in = 3;
610 vm.out = 17;
611
612 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
613 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
614 return -EFAULT;
1da177e4 615 }
2633812f
HV
616 /* connect tuner-output always to multicable */
617 vm.in = 3;
618 vm.out = 13;
619 break;
620 case AUX3_YC:
621 /* nothing to be done here. aux3_yc is
622 directly connected to the saa711a */
623 i = SAA7115_SVIDEO1;
624 break;
625 case AUX3:
626 /* nothing to be done here. aux3 is
627 directly connected to the saa711a */
628 i = SAA7115_COMPOSITE1;
629 break;
630 case AUX1:
631 i = SAA7115_COMPOSITE0;
632 vm.in = 1;
633 vm.out = 17;
634 break;
1da177e4
LT
635 }
636
637 /* switch video in tea6415c only if necessary */
2633812f
HV
638 switch (input) {
639 case TUNER:
640 case AUX1:
641 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
642 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
643 return -EFAULT;
1da177e4 644 }
2633812f
HV
645 break;
646 default:
647 break;
1da177e4 648 }
a8733ca5 649
1da177e4 650 /* switch video in saa7111a */
707ecf46
HV
651 route.input = i;
652 route.output = 0;
653 if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
1da177e4 654 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
1da177e4
LT
655
656 /* switch the audio-source only if necessary */
657 if( 0 == mxb->cur_mute ) {
2633812f
HV
658 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
659 &TEA6420_line[video_audio_connect[input]][0]);
660 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
661 &TEA6420_line[video_audio_connect[input]][1]);
1da177e4
LT
662 }
663
664 return 0;
665 }
666 case VIDIOC_G_TUNER:
667 {
668 struct v4l2_tuner *t = arg;
1da177e4 669
707ecf46 670 if (t->index) {
1da177e4
LT
671 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
672 return -EINVAL;
673 }
674
675 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
676
707ecf46
HV
677 memset(t, 0, sizeof(*t));
678 i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
1da177e4 679
707ecf46 680 strlcpy(t->name, "TV Tuner", sizeof(t->name));
1da177e4 681 t->type = V4L2_TUNER_ANALOG_TV;
707ecf46
HV
682 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \
683 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
1da177e4 684 t->audmode = mxb->cur_mode;
1da177e4
LT
685 return 0;
686 }
687 case VIDIOC_S_TUNER:
688 {
689 struct v4l2_tuner *t = arg;
a8733ca5 690
707ecf46 691 if (t->index) {
1da177e4
LT
692 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
693 return -EINVAL;
694 }
a8733ca5 695
707ecf46
HV
696 mxb->cur_mode = t->audmode;
697 i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
1da177e4
LT
698 return 0;
699 }
700 case VIDIOC_G_FREQUENCY:
701 {
702 struct v4l2_frequency *f = arg;
703
2633812f
HV
704 if (mxb->cur_input) {
705 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
706 mxb->cur_input));
1da177e4
LT
707 return -EINVAL;
708 }
709
9d2599d9 710 *f = mxb->cur_freq;
1da177e4 711
9d2599d9 712 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
1da177e4
LT
713 return 0;
714 }
715 case VIDIOC_S_FREQUENCY:
716 {
717 struct v4l2_frequency *f = arg;
1da177e4 718
2633812f 719 if (f->tuner)
1da177e4
LT
720 return -EINVAL;
721
722 if (V4L2_TUNER_ANALOG_TV != f->type)
723 return -EINVAL;
a8733ca5 724
707ecf46
HV
725 if (mxb->cur_input) {
726 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
1da177e4
LT
727 return -EINVAL;
728 }
729
9d2599d9
MH
730 mxb->cur_freq = *f;
731 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
1da177e4 732
a8733ca5 733 /* tune in desired frequency */
9d2599d9 734 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
1da177e4
LT
735
736 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
737 spin_lock(&dev->slock);
738 vv->vbi_fieldcount = 0;
739 spin_unlock(&dev->slock);
740
741 return 0;
742 }
743 case MXB_S_AUDIO_CD:
744 {
745 int i = *(int*)arg;
a8733ca5 746
2633812f 747 if (i < 0 || i >= MXB_AUDIOS) {
1da177e4
LT
748 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
749 return -EINVAL;
750 }
a8733ca5 751
1da177e4
LT
752 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
753
754 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
755 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
756
757 return 0;
758 }
759 case MXB_S_AUDIO_LINE:
760 {
761 int i = *(int*)arg;
a8733ca5 762
2633812f 763 if (i < 0 || i >= MXB_AUDIOS) {
1da177e4
LT
764 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
765 return -EINVAL;
766 }
a8733ca5 767
1da177e4
LT
768 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
769 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
770 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
771
772 return 0;
773 }
774 case VIDIOC_G_AUDIO:
775 {
776 struct v4l2_audio *a = arg;
777
2633812f
HV
778 if (a->index < 0 || a->index > MXB_INPUTS) {
779 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
1da177e4
LT
780 return -EINVAL;
781 }
a8733ca5 782
2633812f 783 DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
1da177e4 784 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
a8733ca5 785
1da177e4
LT
786 return 0;
787 }
788 case VIDIOC_S_AUDIO:
789 {
790 struct v4l2_audio *a = arg;
2633812f
HV
791
792 DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
1da177e4 793 return 0;
a8733ca5 794 }
2633812f 795#ifdef CONFIG_VIDEO_ADV_DEBUG
707ecf46
HV
796 case VIDIOC_DBG_S_REGISTER:
797 case VIDIOC_DBG_G_REGISTER:
798 i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
2633812f
HV
799 return 0;
800#endif
1da177e4
LT
801 default:
802/*
803 DEB2(printk("does not handle this ioctl.\n"));
804*/
805 return -ENOIOCTLCMD;
806 }
807 return 0;
808}
809
c6eb8eaf 810static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
1da177e4 811{
c6eb8eaf 812 struct mxb *mxb = (struct mxb *)dev->ext_priv;
1da177e4
LT
813 int zero = 0;
814 int one = 1;
815
c6eb8eaf 816 if (V4L2_STD_PAL_I == standard->id) {
6acaba8e 817 v4l2_std_id std = V4L2_STD_PAL_I;
c6eb8eaf 818
1da177e4
LT
819 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
820 /* set the 7146 gpio register -- I don't know what this does exactly */
a8733ca5 821 saa7146_write(dev, GPIO_CTRL, 0x00404050);
1da177e4 822 /* unset the 7111 gpio register -- I don't know what this does exactly */
707ecf46 823 mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &zero);
6acaba8e 824 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
1da177e4 825 } else {
6acaba8e 826 v4l2_std_id std = V4L2_STD_PAL_BG;
c6eb8eaf 827
1da177e4
LT
828 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
829 /* set the 7146 gpio register -- I don't know what this does exactly */
a8733ca5 830 saa7146_write(dev, GPIO_CTRL, 0x00404050);
1da177e4 831 /* set the 7111 gpio register -- I don't know what this does exactly */
707ecf46 832 mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &one);
6acaba8e 833 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
1da177e4
LT
834 }
835 return 0;
836}
837
838static struct saa7146_standard standard[] = {
839 {
840 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
841 .v_offset = 0x17, .v_field = 288,
842 .h_offset = 0x14, .h_pixels = 680,
843 .v_max_out = 576, .h_max_out = 768,
844 }, {
845 .name = "PAL-I", .id = V4L2_STD_PAL_I,
846 .v_offset = 0x17, .v_field = 288,
847 .h_offset = 0x14, .h_pixels = 680,
848 .v_max_out = 576, .h_max_out = 768,
849 }, {
850 .name = "NTSC", .id = V4L2_STD_NTSC,
851 .v_offset = 0x16, .v_field = 240,
852 .h_offset = 0x06, .h_pixels = 708,
853 .v_max_out = 480, .h_max_out = 640,
854 }, {
855 .name = "SECAM", .id = V4L2_STD_SECAM,
856 .v_offset = 0x14, .v_field = 288,
857 .h_offset = 0x14, .h_pixels = 720,
858 .v_max_out = 576, .h_max_out = 768,
859 }
860};
861
862static struct saa7146_pci_extension_data mxb = {
a8733ca5
MCC
863 .ext_priv = "Multimedia eXtension Board",
864 .ext = &extension,
1da177e4
LT
865};
866
867static struct pci_device_id pci_tbl[] = {
868 {
869 .vendor = PCI_VENDOR_ID_PHILIPS,
870 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
871 .subvendor = 0x0000,
872 .subdevice = 0x0000,
873 .driver_data = (unsigned long)&mxb,
874 }, {
875 .vendor = 0,
876 }
877};
878
879MODULE_DEVICE_TABLE(pci, pci_tbl);
880
881static struct saa7146_ext_vv vv_data = {
882 .inputs = MXB_INPUTS,
883 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
884 .stds = &standard[0],
885 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
a8733ca5 886 .std_callback = &std_callback,
1da177e4
LT
887 .ioctls = &ioctls[0],
888 .ioctl = mxb_ioctl,
889};
890
891static struct saa7146_extension extension = {
892 .name = MXB_IDENTIFIER,
893 .flags = SAA7146_USE_I2C_IRQ,
a8733ca5 894
1da177e4
LT
895 .pci_tbl = &pci_tbl[0],
896 .module = THIS_MODULE,
897
898 .probe = mxb_probe,
899 .attach = mxb_attach,
900 .detach = mxb_detach,
901
902 .irq_mask = 0,
903 .irq_func = NULL,
a8733ca5 904};
1da177e4
LT
905
906static int __init mxb_init_module(void)
907{
2633812f 908 if (saa7146_register_extension(&extension)) {
1da177e4
LT
909 DEB_S(("failed to register extension.\n"));
910 return -ENODEV;
911 }
a8733ca5 912
1da177e4
LT
913 return 0;
914}
915
916static void __exit mxb_cleanup_module(void)
917{
918 saa7146_unregister_extension(&extension);
919}
920
921module_init(mxb_init_module);
922module_exit(mxb_cleanup_module);
923
924MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
925MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
926MODULE_LICENSE("GPL");
This page took 0.7823 seconds and 5 git commands to generate.