aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-01-18 17:59:11 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:24 -0400
commitb960074fec573fb1b226d9e2686ce51be807cdf1 (patch)
treeda58b7afa37b0ccd1c06948ad6497cb801553335 /drivers/media/video
parentc9b8b04b267f9a7e472daa06cdf6d4963d503d1f (diff)
V4L/DVB (10271): saa7146: convert to video_ioctl2.
The conversion to video_ioctl2 is the first phase to converting this driver to the latest v4l2 framework. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/hexium_gemini.c292
-rw-r--r--drivers/media/video/hexium_orion.c103
-rw-r--r--drivers/media/video/mxb.c641
3 files changed, 504 insertions, 532 deletions
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 79393d1772e4..8e1463ee1b64 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -56,17 +56,6 @@ struct hexium_data
56 u8 byte; 56 u8 byte;
57}; 57};
58 58
59static struct saa7146_extension_ioctls ioctls[] = {
60 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
61 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
62 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
63 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
64 { VIDIOC_S_STD, SAA7146_AFTER },
65 { VIDIOC_G_CTRL, SAA7146_BEFORE },
66 { VIDIOC_S_CTRL, SAA7146_BEFORE },
67 { 0, 0 }
68};
69
70#define HEXIUM_CONTROLS 1 59#define HEXIUM_CONTROLS 1
71static struct v4l2_queryctrl hexium_controls[] = { 60static struct v4l2_queryctrl hexium_controls[] = {
72 { V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 }, 61 { V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
@@ -231,6 +220,132 @@ static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
231 return 0; 220 return 0;
232} 221}
233 222
223static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
224{
225 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
226
227 if (i->index < 0 || i->index >= HEXIUM_INPUTS)
228 return -EINVAL;
229
230 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
231
232 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
233 return 0;
234}
235
236static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
237{
238 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
239 struct hexium *hexium = (struct hexium *) dev->ext_priv;
240
241 *input = hexium->cur_input;
242
243 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
244 return 0;
245}
246
247static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
248{
249 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
250 struct hexium *hexium = (struct hexium *) dev->ext_priv;
251
252 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
253
254 if (input < 0 || input >= HEXIUM_INPUTS)
255 return -EINVAL;
256
257 hexium->cur_input = input;
258 hexium_set_input(hexium, input);
259 return 0;
260}
261
262/* the saa7146 provides some controls (brightness, contrast, saturation)
263 which gets registered *after* this function. because of this we have
264 to return with a value != 0 even if the function succeded.. */
265static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
266{
267 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
268 int i;
269
270 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
271 if (hexium_controls[i].id == qc->id) {
272 *qc = hexium_controls[i];
273 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
274 return 0;
275 }
276 }
277 return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
278}
279
280static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
281{
282 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
283 struct hexium *hexium = (struct hexium *) dev->ext_priv;
284 int i;
285
286 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
287 if (hexium_controls[i].id == vc->id)
288 break;
289 }
290
291 if (i < 0)
292 return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
293
294 if (vc->id == V4L2_CID_PRIVATE_BASE) {
295 vc->value = hexium->cur_bw;
296 DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
297 return 0;
298 }
299 return -EINVAL;
300}
301
302static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
303{
304 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
305 struct hexium *hexium = (struct hexium *) dev->ext_priv;
306 int i = 0;
307
308 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
309 if (hexium_controls[i].id == vc->id)
310 break;
311 }
312
313 if (i < 0)
314 return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
315
316 if (vc->id == V4L2_CID_PRIVATE_BASE)
317 hexium->cur_bw = vc->value;
318
319 DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
320
321 if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
322 hexium_set_standard(hexium, hexium_pal);
323 return 0;
324 }
325 if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
326 hexium_set_standard(hexium, hexium_ntsc);
327 return 0;
328 }
329 if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
330 hexium_set_standard(hexium, hexium_secam);
331 return 0;
332 }
333 if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
334 hexium_set_standard(hexium, hexium_pal_bw);
335 return 0;
336 }
337 if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
338 hexium_set_standard(hexium, hexium_ntsc_bw);
339 return 0;
340 }
341 if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std)
342 /* fixme: is there no bw secam mode? */
343 return -EINVAL;
344
345 return -EINVAL;
346}
347
348
234static struct saa7146_ext_vv vv_data; 349static struct saa7146_ext_vv vv_data;
235 350
236/* this function only gets called when the probing was successful */ 351/* this function only gets called when the probing was successful */
@@ -279,6 +394,12 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
279 hexium->cur_input = 0; 394 hexium->cur_input = 0;
280 395
281 saa7146_vv_init(dev, &vv_data); 396 saa7146_vv_init(dev, &vv_data);
397 vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
398 vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
399 vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
400 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
401 vv_data.ops.vidioc_g_input = vidioc_g_input;
402 vv_data.ops.vidioc_s_input = vidioc_s_input;
282 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) { 403 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
283 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n"); 404 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
284 return -1; 405 return -1;
@@ -306,153 +427,6 @@ static int hexium_detach(struct saa7146_dev *dev)
306 return 0; 427 return 0;
307} 428}
308 429
309static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
310{
311 struct saa7146_dev *dev = fh->dev;
312 struct hexium *hexium = (struct hexium *) dev->ext_priv;
313/*
314 struct saa7146_vv *vv = dev->vv_data;
315*/
316 switch (cmd) {
317 case VIDIOC_ENUMINPUT:
318 {
319 struct v4l2_input *i = arg;
320 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
321
322 if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
323 return -EINVAL;
324 }
325
326 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
327
328 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
329 return 0;
330 }
331 case VIDIOC_G_INPUT:
332 {
333 int *input = (int *) arg;
334 *input = hexium->cur_input;
335
336 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
337 return 0;
338 }
339 case VIDIOC_S_INPUT:
340 {
341 int input = *(int *) arg;
342
343 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
344
345 if (input < 0 || input >= HEXIUM_INPUTS) {
346 return -EINVAL;
347 }
348
349 hexium->cur_input = input;
350 hexium_set_input(hexium, input);
351
352 return 0;
353 }
354 /* the saa7146 provides some controls (brightness, contrast, saturation)
355 which gets registered *after* this function. because of this we have
356 to return with a value != 0 even if the function succeded.. */
357 case VIDIOC_QUERYCTRL:
358 {
359 struct v4l2_queryctrl *qc = arg;
360 int i;
361
362 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
363 if (hexium_controls[i].id == qc->id) {
364 *qc = hexium_controls[i];
365 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
366 return 0;
367 }
368 }
369 return -EAGAIN;
370 }
371 case VIDIOC_G_CTRL:
372 {
373 struct v4l2_control *vc = arg;
374 int i;
375
376 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
377 if (hexium_controls[i].id == vc->id) {
378 break;
379 }
380 }
381
382 if (i < 0) {
383 return -EAGAIN;
384 }
385
386 switch (vc->id) {
387 case V4L2_CID_PRIVATE_BASE:{
388 vc->value = hexium->cur_bw;
389 DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
390 return 0;
391 }
392 }
393 return -EINVAL;
394 }
395
396 case VIDIOC_S_CTRL:
397 {
398 struct v4l2_control *vc = arg;
399 int i = 0;
400
401 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
402 if (hexium_controls[i].id == vc->id) {
403 break;
404 }
405 }
406
407 if (i < 0) {
408 return -EAGAIN;
409 }
410
411 switch (vc->id) {
412 case V4L2_CID_PRIVATE_BASE:{
413 hexium->cur_bw = vc->value;
414 break;
415 }
416 }
417
418 DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
419
420 if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
421 hexium_set_standard(hexium, hexium_pal);
422 return 0;
423 }
424 if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
425 hexium_set_standard(hexium, hexium_ntsc);
426 return 0;
427 }
428 if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
429 hexium_set_standard(hexium, hexium_secam);
430 return 0;
431 }
432 if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
433 hexium_set_standard(hexium, hexium_pal_bw);
434 return 0;
435 }
436 if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
437 hexium_set_standard(hexium, hexium_ntsc_bw);
438 return 0;
439 }
440 if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
441 /* fixme: is there no bw secam mode? */
442 return -EINVAL;
443 }
444
445 return -EINVAL;
446 }
447 default:
448/*
449 DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
450*/
451 return -ENOIOCTLCMD;
452 }
453 return 0;
454}
455
456static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std) 430static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
457{ 431{
458 struct hexium *hexium = (struct hexium *) dev->ext_priv; 432 struct hexium *hexium = (struct hexium *) dev->ext_priv;
@@ -514,8 +488,6 @@ static struct saa7146_ext_vv vv_data = {
514 .stds = &hexium_standards[0], 488 .stds = &hexium_standards[0],
515 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard), 489 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
516 .std_callback = &std_callback, 490 .std_callback = &std_callback,
517 .ioctls = &ioctls[0],
518 .ioctl = hexium_ioctl,
519}; 491};
520 492
521static struct saa7146_extension hexium_extension = { 493static struct saa7146_extension hexium_extension = {
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 074bec711fe0..2bc39f628455 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -57,14 +57,6 @@ struct hexium_data
57 u8 byte; 57 u8 byte;
58}; 58};
59 59
60static struct saa7146_extension_ioctls ioctls[] = {
61 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
62 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
63 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
64 { VIDIOC_S_STD, SAA7146_AFTER },
65 { 0, 0 }
66};
67
68struct hexium 60struct hexium
69{ 61{
70 int type; 62 int type;
@@ -329,6 +321,44 @@ static int hexium_set_input(struct hexium *hexium, int input)
329 return 0; 321 return 0;
330} 322}
331 323
324static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
325{
326 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
327
328 if (i->index < 0 || i->index >= HEXIUM_INPUTS)
329 return -EINVAL;
330
331 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
332
333 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
334 return 0;
335}
336
337static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
338{
339 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
340 struct hexium *hexium = (struct hexium *) dev->ext_priv;
341
342 *input = hexium->cur_input;
343
344 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
345 return 0;
346}
347
348static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
349{
350 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
351 struct hexium *hexium = (struct hexium *) dev->ext_priv;
352
353 if (input < 0 || input >= HEXIUM_INPUTS)
354 return -EINVAL;
355
356 hexium->cur_input = input;
357 hexium_set_input(hexium, input);
358
359 return 0;
360}
361
332static struct saa7146_ext_vv vv_data; 362static struct saa7146_ext_vv vv_data;
333 363
334/* this function only gets called when the probing was successful */ 364/* this function only gets called when the probing was successful */
@@ -339,6 +369,9 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
339 DEB_EE((".\n")); 369 DEB_EE((".\n"));
340 370
341 saa7146_vv_init(dev, &vv_data); 371 saa7146_vv_init(dev, &vv_data);
372 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
373 vv_data.ops.vidioc_g_input = vidioc_g_input;
374 vv_data.ops.vidioc_s_input = vidioc_s_input;
342 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) { 375 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
343 printk("hexium_orion: cannot register capture v4l2 device. skipping.\n"); 376 printk("hexium_orion: cannot register capture v4l2 device. skipping.\n");
344 return -1; 377 return -1;
@@ -370,58 +403,6 @@ static int hexium_detach(struct saa7146_dev *dev)
370 return 0; 403 return 0;
371} 404}
372 405
373static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
374{
375 struct saa7146_dev *dev = fh->dev;
376 struct hexium *hexium = (struct hexium *) dev->ext_priv;
377/*
378 struct saa7146_vv *vv = dev->vv_data;
379*/
380 switch (cmd) {
381 case VIDIOC_ENUMINPUT:
382 {
383 struct v4l2_input *i = arg;
384 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
385
386 if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
387 return -EINVAL;
388 }
389
390 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
391
392 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
393 return 0;
394 }
395 case VIDIOC_G_INPUT:
396 {
397 int *input = (int *) arg;
398 *input = hexium->cur_input;
399
400 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
401 return 0;
402 }
403 case VIDIOC_S_INPUT:
404 {
405 int input = *(int *) arg;
406
407 if (input < 0 || input >= HEXIUM_INPUTS) {
408 return -EINVAL;
409 }
410
411 hexium->cur_input = input;
412 hexium_set_input(hexium, input);
413
414 return 0;
415 }
416 default:
417/*
418 DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
419*/
420 return -ENOIOCTLCMD;
421 }
422 return 0;
423}
424
425static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std) 406static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
426{ 407{
427 return 0; 408 return 0;
@@ -479,8 +460,6 @@ static struct saa7146_ext_vv vv_data = {
479 .stds = &hexium_standards[0], 460 .stds = &hexium_standards[0],
480 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard), 461 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
481 .std_callback = &std_callback, 462 .std_callback = &std_callback,
482 .ioctls = &ioctls[0],
483 .ioctl = hexium_ioctl,
484}; 463};
485 464
486static struct saa7146_extension extension = { 465static struct saa7146_extension extension = {
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index e3cbe14c349a..8ecda8dfbd04 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -110,26 +110,6 @@ static struct v4l2_queryctrl mxb_controls[] = {
110 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 }, 110 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
111}; 111};
112 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 },
126 { VIDIOC_DBG_G_REGISTER, SAA7146_EXCLUSIVE },
127 { VIDIOC_DBG_S_REGISTER, SAA7146_EXCLUSIVE },
128 { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
129 { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
130 { 0, 0 }
131};
132
133struct mxb 113struct mxb
134{ 114{
135 struct video_device *video_dev; 115 struct video_device *video_dev;
@@ -424,387 +404,430 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
424} 404}
425*/ 405*/
426 406
427static struct saa7146_ext_vv vv_data; 407static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
428
429/* this function only gets called when the probing was successful */
430static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
431{ 408{
432 struct mxb *mxb = (struct mxb *)dev->ext_priv; 409 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
410 int i;
433 411
434 DEB_EE(("dev:%p\n", dev)); 412 for (i = MAXCONTROLS - 1; i >= 0; i--) {
413 if (mxb_controls[i].id == qc->id) {
414 *qc = mxb_controls[i];
415 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
416 return 0;
417 }
418 }
419 return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
420}
435 421
436 /* checking for i2c-devices can be omitted here, because we 422static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
437 already did this in "mxb_vl42_probe" */ 423{
424 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
425 struct mxb *mxb = (struct mxb *)dev->ext_priv;
426 int i;
438 427
439 saa7146_vv_init(dev, &vv_data); 428 for (i = MAXCONTROLS - 1; i >= 0; i--) {
440 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { 429 if (mxb_controls[i].id == vc->id)
441 ERR(("cannot register capture v4l2 device. skipping.\n")); 430 break;
442 return -1;
443 } 431 }
444 432
445 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ 433 if (i < 0)
446 if (MXB_BOARD_CAN_DO_VBI(dev)) { 434 return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
447 if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
448 ERR(("cannot register vbi v4l2 device. skipping.\n"));
449 }
450 }
451 435
452 i2c_use_client(mxb->tea6420_1); 436 if (vc->id == V4L2_CID_AUDIO_MUTE) {
453 i2c_use_client(mxb->tea6420_2); 437 vc->value = mxb->cur_mute;
454 i2c_use_client(mxb->tea6415c); 438 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
455 i2c_use_client(mxb->tda9840); 439 return 0;
456 i2c_use_client(mxb->saa7111a); 440 }
457 i2c_use_client(mxb->tuner);
458
459 printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
460 441
461 mxb_num++; 442 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
462 mxb_init_done(dev);
463 return 0; 443 return 0;
464} 444}
465 445
466static int mxb_detach(struct saa7146_dev *dev) 446static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
467{ 447{
448 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
468 struct mxb *mxb = (struct mxb *)dev->ext_priv; 449 struct mxb *mxb = (struct mxb *)dev->ext_priv;
450 int i = 0;
469 451
470 DEB_EE(("dev:%p\n", dev)); 452 for (i = MAXCONTROLS - 1; i >= 0; i--) {
471 453 if (mxb_controls[i].id == vc->id)
472 i2c_release_client(mxb->tea6420_1); 454 break;
473 i2c_release_client(mxb->tea6420_2); 455 }
474 i2c_release_client(mxb->tea6415c);
475 i2c_release_client(mxb->tda9840);
476 i2c_release_client(mxb->saa7111a);
477 i2c_release_client(mxb->tuner);
478
479 saa7146_unregister_device(&mxb->video_dev,dev);
480 if (MXB_BOARD_CAN_DO_VBI(dev))
481 saa7146_unregister_device(&mxb->vbi_dev, dev);
482 saa7146_vv_release(dev);
483 456
484 mxb_num--; 457 if (i < 0)
458 return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
485 459
486 i2c_del_adapter(&mxb->i2c_adapter); 460 if (vc->id == V4L2_CID_AUDIO_MUTE) {
487 kfree(mxb); 461 mxb->cur_mute = vc->value;
462 if (!vc->value) {
463 /* switch the audio-source */
464 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
465 &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
466 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
467 &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
468 } else {
469 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
470 &TEA6420_line[6][0]);
471 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
472 &TEA6420_line[6][1]);
473 }
474 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
475 }
476 return 0;
477}
488 478
479static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
480{
481 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
482 if (i->index < 0 || i->index >= MXB_INPUTS)
483 return -EINVAL;
484 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
489 return 0; 485 return 0;
490} 486}
491 487
492static long mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 488static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
493{ 489{
494 struct saa7146_dev *dev = fh->dev; 490 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
495 struct mxb *mxb = (struct mxb *)dev->ext_priv; 491 struct mxb *mxb = (struct mxb *)dev->ext_priv;
496 struct saa7146_vv *vv = dev->vv_data; 492 *i = mxb->cur_input;
497 493
498 switch(cmd) { 494 DEB_EE(("VIDIOC_G_INPUT %d.\n", *i));
499 case VIDIOC_ENUMINPUT: 495 return 0;
500 { 496}
501 struct v4l2_input *i = arg;
502 497
503 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); 498static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
504 if (i->index < 0 || i->index >= MXB_INPUTS) 499{
505 return -EINVAL; 500 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
506 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); 501 struct mxb *mxb = (struct mxb *)dev->ext_priv;
507 return 0; 502 struct tea6415c_multiplex vm;
508 } 503 struct v4l2_routing route;
509 /* the saa7146 provides some controls (brightness, contrast, saturation) 504 int i = 0;
510 which gets registered *after* this function. because of this we have
511 to return with a value != 0 even if the function succeded.. */
512 case VIDIOC_QUERYCTRL:
513 {
514 struct v4l2_queryctrl *qc = arg;
515 int i;
516
517 for (i = MAXCONTROLS - 1; i >= 0; i--) {
518 if (mxb_controls[i].id == qc->id) {
519 *qc = mxb_controls[i];
520 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
521 return 0;
522 }
523 }
524 return -EAGAIN;
525 }
526 case VIDIOC_G_CTRL:
527 {
528 struct v4l2_control *vc = arg;
529 int i;
530 505
531 for (i = MAXCONTROLS - 1; i >= 0; i--) { 506 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
532 if (mxb_controls[i].id == vc->id)
533 break;
534 }
535 507
536 if (i < 0) 508 if (input < 0 || input >= MXB_INPUTS)
537 return -EAGAIN; 509 return -EINVAL;
538 510
539 if (vc->id == V4L2_CID_AUDIO_MUTE) { 511 mxb->cur_input = input;
540 vc->value = mxb->cur_mute;
541 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
542 return 0;
543 }
544 512
545 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value)); 513 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
546 return 0; 514 input_port_selection[input].hps_sync);
547 }
548 515
549 case VIDIOC_S_CTRL: 516 /* prepare switching of tea6415c and saa7111a;
550 { 517 have a look at the 'background'-file for further informations */
551 struct v4l2_control *vc = arg; 518 switch (input) {
552 int i = 0; 519 case TUNER:
520 i = SAA7115_COMPOSITE0;
521 vm.in = 3;
522 vm.out = 17;
553 523
554 for (i = MAXCONTROLS - 1; i >= 0; i--) { 524 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
555 if (mxb_controls[i].id == vc->id) 525 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
556 break; 526 return -EFAULT;
557 } 527 }
528 /* connect tuner-output always to multicable */
529 vm.in = 3;
530 vm.out = 13;
531 break;
532 case AUX3_YC:
533 /* nothing to be done here. aux3_yc is
534 directly connected to the saa711a */
535 i = SAA7115_SVIDEO1;
536 break;
537 case AUX3:
538 /* nothing to be done here. aux3 is
539 directly connected to the saa711a */
540 i = SAA7115_COMPOSITE1;
541 break;
542 case AUX1:
543 i = SAA7115_COMPOSITE0;
544 vm.in = 1;
545 vm.out = 17;
546 break;
547 }
558 548
559 if (i < 0) 549 /* switch video in tea6415c only if necessary */
560 return -EAGAIN; 550 switch (input) {
561 551 case TUNER:
562 if (vc->id == V4L2_CID_AUDIO_MUTE) { 552 case AUX1:
563 mxb->cur_mute = vc->value; 553 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
564 if (!vc->value) { 554 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
565 /* switch the audio-source */ 555 return -EFAULT;
566 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
567 &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
568 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
569 &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
570 } else {
571 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
572 &TEA6420_line[6][0]);
573 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
574 &TEA6420_line[6][1]);
575 }
576 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
577 } 556 }
578 return 0; 557 break;
558 default:
559 break;
579 } 560 }
580 case VIDIOC_G_INPUT:
581 {
582 int *input = (int *)arg;
583 *input = mxb->cur_input;
584 561
585 DEB_EE(("VIDIOC_G_INPUT %d.\n", *input)); 562 /* switch video in saa7111a */
586 return 0; 563 route.input = i;
564 route.output = 0;
565 if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
566 printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
567
568 /* switch the audio-source only if necessary */
569 if (0 == mxb->cur_mute) {
570 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
571 &TEA6420_line[video_audio_connect[input]][0]);
572 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
573 &TEA6420_line[video_audio_connect[input]][1]);
587 } 574 }
588 case VIDIOC_S_INPUT:
589 {
590 int input = *(int *)arg;
591 struct tea6415c_multiplex vm;
592 struct v4l2_routing route;
593 int i = 0;
594 575
595 DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); 576 return 0;
577}
596 578
597 if (input < 0 || input >= MXB_INPUTS) 579static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
598 return -EINVAL; 580{
581 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
582 struct mxb *mxb = (struct mxb *)dev->ext_priv;
599 583
600 mxb->cur_input = input; 584 if (t->index) {
585 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
586 return -EINVAL;
587 }
601 588
602 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, 589 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
603 input_port_selection[input].hps_sync);
604 590
605 /* prepare switching of tea6415c and saa7111a; 591 memset(t, 0, sizeof(*t));
606 have a look at the 'background'-file for further informations */ 592 i2c_clients_command(&mxb->i2c_adapter, VIDIOC_G_TUNER, t);
607 switch (input) {
608 case TUNER:
609 i = SAA7115_COMPOSITE0;
610 vm.in = 3;
611 vm.out = 17;
612 593
613 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) { 594 strlcpy(t->name, "TV Tuner", sizeof(t->name));
614 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n"); 595 t->type = V4L2_TUNER_ANALOG_TV;
615 return -EFAULT; 596 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
616 } 597 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
617 /* connect tuner-output always to multicable */ 598 t->audmode = mxb->cur_mode;
618 vm.in = 3; 599 return 0;
619 vm.out = 13; 600}
620 break;
621 case AUX3_YC:
622 /* nothing to be done here. aux3_yc is
623 directly connected to the saa711a */
624 i = SAA7115_SVIDEO1;
625 break;
626 case AUX3:
627 /* nothing to be done here. aux3 is
628 directly connected to the saa711a */
629 i = SAA7115_COMPOSITE1;
630 break;
631 case AUX1:
632 i = SAA7115_COMPOSITE0;
633 vm.in = 1;
634 vm.out = 17;
635 break;
636 }
637 601
638 /* switch video in tea6415c only if necessary */ 602static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
639 switch (input) { 603{
640 case TUNER: 604 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
641 case AUX1: 605 struct mxb *mxb = (struct mxb *)dev->ext_priv;
642 if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
643 printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
644 return -EFAULT;
645 }
646 break;
647 default:
648 break;
649 }
650 606
651 /* switch video in saa7111a */ 607 if (t->index) {
652 route.input = i; 608 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index));
653 route.output = 0; 609 return -EINVAL;
654 if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route)) 610 }
655 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
656 611
657 /* switch the audio-source only if necessary */ 612 mxb->cur_mode = t->audmode;
658 if( 0 == mxb->cur_mute ) { 613 i2c_clients_command(&mxb->i2c_adapter, VIDIOC_S_TUNER, t);
659 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, 614 return 0;
660 &TEA6420_line[video_audio_connect[input]][0]); 615}
661 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
662 &TEA6420_line[video_audio_connect[input]][1]);
663 }
664 616
665 return 0; 617static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
618{
619 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
620 struct mxb *mxb = (struct mxb *)dev->ext_priv;
621
622 if (mxb->cur_input) {
623 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
624 mxb->cur_input));
625 return -EINVAL;
666 } 626 }
667 case VIDIOC_G_TUNER:
668 {
669 struct v4l2_tuner *t = arg;
670 627
671 if (t->index) { 628 *f = mxb->cur_freq;
672 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
673 return -EINVAL;
674 }
675 629
676 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index)); 630 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
631 return 0;
632}
677 633
678 memset(t, 0, sizeof(*t)); 634static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
679 i2c_clients_command(&mxb->i2c_adapter, cmd, arg); 635{
636 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
637 struct mxb *mxb = (struct mxb *)dev->ext_priv;
638 struct saa7146_vv *vv = dev->vv_data;
680 639
681 strlcpy(t->name, "TV Tuner", sizeof(t->name)); 640 if (f->tuner)
682 t->type = V4L2_TUNER_ANALOG_TV; 641 return -EINVAL;
683 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \
684 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
685 t->audmode = mxb->cur_mode;
686 return 0;
687 }
688 case VIDIOC_S_TUNER:
689 {
690 struct v4l2_tuner *t = arg;
691 642
692 if (t->index) { 643 if (V4L2_TUNER_ANALOG_TV != f->type)
693 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index)); 644 return -EINVAL;
694 return -EINVAL;
695 }
696 645
697 mxb->cur_mode = t->audmode; 646 if (mxb->cur_input) {
698 i2c_clients_command(&mxb->i2c_adapter, cmd, arg); 647 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
699 return 0; 648 return -EINVAL;
700 } 649 }
701 case VIDIOC_G_FREQUENCY:
702 {
703 struct v4l2_frequency *f = arg;
704 650
705 if (mxb->cur_input) { 651 mxb->cur_freq = *f;
706 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n", 652 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
707 mxb->cur_input));
708 return -EINVAL;
709 }
710 653
711 *f = mxb->cur_freq; 654 /* tune in desired frequency */
655 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
712 656
713 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency)); 657 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
714 return 0; 658 spin_lock(&dev->slock);
659 vv->vbi_fieldcount = 0;
660 spin_unlock(&dev->slock);
661
662 return 0;
663}
664
665static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
666{
667 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
668 struct mxb *mxb = (struct mxb *)dev->ext_priv;
669
670 if (a->index < 0 || a->index > MXB_INPUTS) {
671 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
672 return -EINVAL;
715 } 673 }
716 case VIDIOC_S_FREQUENCY:
717 {
718 struct v4l2_frequency *f = arg;
719 674
720 if (f->tuner) 675 DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
721 return -EINVAL; 676 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
677 return 0;
678}
722 679
723 if (V4L2_TUNER_ANALOG_TV != f->type) 680static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
724 return -EINVAL; 681{
682 DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
683 return 0;
684}
725 685
726 if (mxb->cur_input) { 686#ifdef CONFIG_VIDEO_ADV_DEBUG
727 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input)); 687static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
728 return -EINVAL; 688{
729 } 689 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
690 struct mxb *mxb = (struct mxb *)dev->ext_priv;
730 691
731 mxb->cur_freq = *f; 692 i2c_clients_command(&mxb->i2c_adapter, VIDIOC_DBG_G_REGISTER, reg);
732 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency)); 693 return 0;
694}
733 695
734 /* tune in desired frequency */ 696static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
735 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq); 697{
698 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
699 struct mxb *mxb = (struct mxb *)dev->ext_priv;
736 700
737 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ 701 i2c_clients_command(&mxb->i2c_adapter, VIDIOC_DBG_S_REGISTER, reg);
738 spin_lock(&dev->slock); 702 return 0;
739 vv->vbi_fieldcount = 0; 703}
740 spin_unlock(&dev->slock); 704#endif
741 705
742 return 0; 706static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
743 } 707{
708 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
709 struct mxb *mxb = (struct mxb *)dev->ext_priv;
710
711 switch (cmd) {
744 case MXB_S_AUDIO_CD: 712 case MXB_S_AUDIO_CD:
745 { 713 {
746 int i = *(int*)arg; 714 int i = *(int *)arg;
747 715
748 if (i < 0 || i >= MXB_AUDIOS) { 716 if (i < 0 || i >= MXB_AUDIOS) {
749 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i)); 717 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n", i));
750 return -EINVAL; 718 return -EINVAL;
751 } 719 }
752 720
753 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i)); 721 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
754 722
755 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]); 723 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[i][0]);
756 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]); 724 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[i][1]);
757 725
758 return 0; 726 return 0;
759 } 727 }
760 case MXB_S_AUDIO_LINE: 728 case MXB_S_AUDIO_LINE:
761 { 729 {
762 int i = *(int*)arg; 730 int i = *(int *)arg;
763 731
764 if (i < 0 || i >= MXB_AUDIOS) { 732 if (i < 0 || i >= MXB_AUDIOS) {
765 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i)); 733 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n", i));
766 return -EINVAL; 734 return -EINVAL;
767 } 735 }
768 736
769 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i)); 737 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
770 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]); 738 mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[i][0]);
771 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]); 739 mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[i][1]);
772 740
773 return 0; 741 return 0;
774 } 742 }
775 case VIDIOC_G_AUDIO: 743 default:
776 { 744/*
777 struct v4l2_audio *a = arg; 745 DEB2(printk("does not handle this ioctl.\n"));
746*/
747 return -ENOIOCTLCMD;
748 }
749 return 0;
750}
778 751
779 if (a->index < 0 || a->index > MXB_INPUTS) { 752static struct saa7146_ext_vv vv_data;
780 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index)); 753
781 return -EINVAL; 754/* this function only gets called when the probing was successful */
782 } 755static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
756{
757 struct mxb *mxb = (struct mxb *)dev->ext_priv;
783 758
784 DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index)); 759 DEB_EE(("dev:%p\n", dev));
785 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
786 760
787 return 0; 761 /* checking for i2c-devices can be omitted here, because we
788 } 762 already did this in "mxb_vl42_probe" */
789 case VIDIOC_S_AUDIO:
790 {
791 struct v4l2_audio *a = arg;
792 763
793 DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index)); 764 saa7146_vv_init(dev, &vv_data);
794 return 0; 765 vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
795 } 766 vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
767 vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
768 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
769 vv_data.ops.vidioc_g_input = vidioc_g_input;
770 vv_data.ops.vidioc_s_input = vidioc_s_input;
771 vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
772 vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
773 vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
774 vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
775 vv_data.ops.vidioc_g_audio = vidioc_g_audio;
776 vv_data.ops.vidioc_s_audio = vidioc_s_audio;
796#ifdef CONFIG_VIDEO_ADV_DEBUG 777#ifdef CONFIG_VIDEO_ADV_DEBUG
797 case VIDIOC_DBG_S_REGISTER: 778 vv_data.ops.vidioc_g_register = vidioc_g_register;
798 case VIDIOC_DBG_G_REGISTER: 779 vv_data.ops.vidioc_s_register = vidioc_s_register;
799 i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
800 return 0;
801#endif 780#endif
802 default: 781 vv_data.ops.vidioc_default = vidioc_default;
803/* 782 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
804 DEB2(printk("does not handle this ioctl.\n")); 783 ERR(("cannot register capture v4l2 device. skipping.\n"));
805*/ 784 return -1;
806 return -ENOIOCTLCMD; 785 }
786
787 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
788 if (MXB_BOARD_CAN_DO_VBI(dev)) {
789 if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
790 ERR(("cannot register vbi v4l2 device. skipping.\n"));
791 }
807 } 792 }
793
794 i2c_use_client(mxb->tea6420_1);
795 i2c_use_client(mxb->tea6420_2);
796 i2c_use_client(mxb->tea6415c);
797 i2c_use_client(mxb->tda9840);
798 i2c_use_client(mxb->saa7111a);
799 i2c_use_client(mxb->tuner);
800
801 printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
802
803 mxb_num++;
804 mxb_init_done(dev);
805 return 0;
806}
807
808static int mxb_detach(struct saa7146_dev *dev)
809{
810 struct mxb *mxb = (struct mxb *)dev->ext_priv;
811
812 DEB_EE(("dev:%p\n", dev));
813
814 i2c_release_client(mxb->tea6420_1);
815 i2c_release_client(mxb->tea6420_2);
816 i2c_release_client(mxb->tea6415c);
817 i2c_release_client(mxb->tda9840);
818 i2c_release_client(mxb->saa7111a);
819 i2c_release_client(mxb->tuner);
820
821 saa7146_unregister_device(&mxb->video_dev,dev);
822 if (MXB_BOARD_CAN_DO_VBI(dev))
823 saa7146_unregister_device(&mxb->vbi_dev, dev);
824 saa7146_vv_release(dev);
825
826 mxb_num--;
827
828 i2c_del_adapter(&mxb->i2c_adapter);
829 kfree(mxb);
830
808 return 0; 831 return 0;
809} 832}
810 833
@@ -885,8 +908,6 @@ static struct saa7146_ext_vv vv_data = {
885 .stds = &standard[0], 908 .stds = &standard[0],
886 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), 909 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
887 .std_callback = &std_callback, 910 .std_callback = &std_callback,
888 .ioctls = &ioctls[0],
889 .ioctl = mxb_ioctl,
890}; 911};
891 912
892static struct saa7146_extension extension = { 913static struct saa7146_extension extension = {