aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@brturbo.com.br>2005-11-09 00:38:43 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:56:30 -0500
commiteac94356c8f9f7d3854ed0290a406b13bfe8df4c (patch)
tree5dd31d7ecbb1d0d857972478a322ccb838dd668c
parentc3d931929f1d11f9d198567850247ae1754dfc06 (diff)
[PATCH] V4L: 907: em28xx cleanups and fixes
- Em28xx cleanups and fixes. - Some cleanups and audio amux adjust. - em28xx will allways try, by default, the biggest size alt. - Fixes audio mux code. - Fixes some logs. - Adds support for digital output for WinTV USB2 board. Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c15
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c17
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c107
-rw-r--r--drivers/media/video/msp3400.c142
-rw-r--r--include/linux/videodev2.h1
5 files changed, 201 insertions, 81 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 49107fd0c0d3..57779e63f35d 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -128,7 +128,7 @@ struct em28xx_board em28xx_boards[] = {
128 .input = {{ 128 .input = {{
129 .type = EM28XX_VMUX_TELEVISION, 129 .type = EM28XX_VMUX_TELEVISION,
130 .vmux = 0, 130 .vmux = 0,
131 .amux = 0, 131 .amux = 6,
132 },{ 132 },{
133 .type = EM28XX_VMUX_SVIDEO, 133 .type = EM28XX_VMUX_SVIDEO,
134 .vmux = 2, 134 .vmux = 2,
@@ -261,9 +261,11 @@ void em28xx_card_setup(struct em28xx *dev)
261 /* request some modules */ 261 /* request some modules */
262 if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) { 262 if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
263 struct tveeprom tv; 263 struct tveeprom tv;
264 struct v4l2_audioout ao;
264#ifdef CONFIG_MODULES 265#ifdef CONFIG_MODULES
265 request_module("tveeprom"); 266 request_module("tveeprom");
266 request_module("ir-kbd-i2c"); 267 request_module("ir-kbd-i2c");
268 request_module("msp3400");
267#endif 269#endif
268 /* Call first TVeeprom */ 270 /* Call first TVeeprom */
269 271
@@ -273,10 +275,13 @@ void em28xx_card_setup(struct em28xx *dev)
273 dev->tuner_type= tv.tuner_type; 275 dev->tuner_type= tv.tuner_type;
274 if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { 276 if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
275 dev->has_msp34xx=1; 277 dev->has_msp34xx=1;
276 } else dev->has_msp34xx=0; 278 memset (&ao,0,sizeof(ao));
277 em28xx_write_regs_req(dev,0x06,0x00,"\x40",1);// Serial Bus Frequency Select Register 279
278 em28xx_write_regs_req(dev,0x0f,0x00,"\x87",1);// XCLK Frequency Select Register 280 ao.index=2;
279 em28xx_write_regs_req(dev,0x88,0x0d,"\xd0",1); 281 ao.mode=V4L2_AUDMODE_32BITS;
282 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao);
283 } else
284 dev->has_msp34xx=0;
280 } 285 }
281} 286}
282 287
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 045547e17656..5cc850666fd7 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -797,20 +797,9 @@ int em28xx_set_alternate(struct em28xx *dev)
797 dev->alt = alt; 797 dev->alt = alt;
798 if (dev->alt == 0) { 798 if (dev->alt == 0) {
799 int i; 799 int i;
800 if(dev->is_em2800){ /* always use the max packet size for em2800 based devices */ 800 for(i=0;i< EM28XX_MAX_ALT; i++)
801 for(i=0;i< EM28XX_MAX_ALT; i++) 801 if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
802 if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt]) 802 dev->alt=i;
803 dev->alt=i;
804 }else{
805 unsigned int min_pkt_size = dev->field_size / 137; /* FIXME: empiric magic number */
806 em28xx_coredbg("minimum isoc packet size: %u", min_pkt_size);
807 dev->alt = 7;
808 for (i = 1; i < EM28XX_MAX_ALT; i += 2) /* FIXME: skip even alternate: why do they not work? */
809 if (dev->alt_max_pkt_size[i] >= min_pkt_size) {
810 dev->alt = i;
811 break;
812 }
813 }
814 } 803 }
815 804
816 if (dev->alt != prev_alt) { 805 if (dev->alt != prev_alt) {
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 54f21242ccbf..0bbfce03172d 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -277,6 +277,35 @@ static void em28xx_empty_framequeues(struct em28xx *dev)
277 } 277 }
278} 278}
279 279
280static void video_mux(struct em28xx *dev, int index)
281{
282 int input, ainput;
283
284 input = INPUT(index)->vmux;
285 dev->ctl_input = index;
286 dev->ctl_ainput = INPUT(index)->amux;
287
288 em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input);
289
290
291 em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
292
293 if (dev->has_msp34xx) {
294 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
295 ainput = EM28XX_AUDIO_SRC_TUNER;
296 em28xx_audio_source(dev, ainput);
297 } else {
298 switch (dev->ctl_ainput) {
299 case 0:
300 ainput = EM28XX_AUDIO_SRC_TUNER;
301 break;
302 default:
303 ainput = EM28XX_AUDIO_SRC_LINE;
304 }
305 em28xx_audio_source(dev, ainput);
306 }
307}
308
280/* 309/*
281 * em28xx_v4l2_open() 310 * em28xx_v4l2_open()
282 * inits the device and starts isoc transfer 311 * inits the device and starts isoc transfer
@@ -298,7 +327,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
298 filp->private_data=dev; 327 filp->private_data=dev;
299 328
300 329
301 em28xx_videodbg("users=%d", dev->users); 330 em28xx_videodbg("users=%d\n", dev->users);
302 331
303 if (!down_read_trylock(&em28xx_disconnect)) 332 if (!down_read_trylock(&em28xx_disconnect))
304 return -ERESTARTSYS; 333 return -ERESTARTSYS;
@@ -352,6 +381,8 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
352 381
353 dev->state |= DEV_INITIALIZED; 382 dev->state |= DEV_INITIALIZED;
354 383
384 video_mux(dev, 0);
385
355 err: 386 err:
356 up(&dev->lock); 387 up(&dev->lock);
357 up_read(&em28xx_disconnect); 388 up_read(&em28xx_disconnect);
@@ -386,7 +417,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
386 int errCode; 417 int errCode;
387 struct em28xx *dev=filp->private_data; 418 struct em28xx *dev=filp->private_data;
388 419
389 em28xx_videodbg("users=%d", dev->users); 420 em28xx_videodbg("users=%d\n", dev->users);
390 421
391 down(&dev->lock); 422 down(&dev->lock);
392 423
@@ -404,7 +435,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
404 435
405 /* set alternate 0 */ 436 /* set alternate 0 */
406 dev->alt = 0; 437 dev->alt = 0;
407 em28xx_videodbg("setting alternate 0"); 438 em28xx_videodbg("setting alternate 0\n");
408 errCode = usb_set_interface(dev->udev, 0, 0); 439 errCode = usb_set_interface(dev->udev, 0, 0);
409 if (errCode < 0) { 440 if (errCode < 0) {
410 em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n", 441 em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n",
@@ -434,20 +465,20 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
434 return -ERESTARTSYS; 465 return -ERESTARTSYS;
435 466
436 if (dev->state & DEV_DISCONNECTED) { 467 if (dev->state & DEV_DISCONNECTED) {
437 em28xx_videodbg("device not present"); 468 em28xx_videodbg("device not present\n");
438 up(&dev->fileop_lock); 469 up(&dev->fileop_lock);
439 return -ENODEV; 470 return -ENODEV;
440 } 471 }
441 472
442 if (dev->state & DEV_MISCONFIGURED) { 473 if (dev->state & DEV_MISCONFIGURED) {
443 em28xx_videodbg("device misconfigured; close and open it again"); 474 em28xx_videodbg("device misconfigured; close and open it again\n");
444 up(&dev->fileop_lock); 475 up(&dev->fileop_lock);
445 return -EIO; 476 return -EIO;
446 } 477 }
447 478
448 if (dev->io == IO_MMAP) { 479 if (dev->io == IO_MMAP) {
449 em28xx_videodbg ("IO method is set to mmap; close and open" 480 em28xx_videodbg ("IO method is set to mmap; close and open"
450 " the device again to choose the read method"); 481 " the device again to choose the read method\n");
451 up(&dev->fileop_lock); 482 up(&dev->fileop_lock);
452 return -EINVAL; 483 return -EINVAL;
453 } 484 }
@@ -524,9 +555,9 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
524 return POLLERR; 555 return POLLERR;
525 556
526 if (dev->state & DEV_DISCONNECTED) { 557 if (dev->state & DEV_DISCONNECTED) {
527 em28xx_videodbg("device not present"); 558 em28xx_videodbg("device not present\n");
528 } else if (dev->state & DEV_MISCONFIGURED) { 559 } else if (dev->state & DEV_MISCONFIGURED) {
529 em28xx_videodbg("device is misconfigured; close and open it again"); 560 em28xx_videodbg("device is misconfigured; close and open it again\n");
530 } else { 561 } else {
531 if (dev->io == IO_NONE) { 562 if (dev->io == IO_NONE) {
532 if (!em28xx_request_buffers 563 if (!em28xx_request_buffers
@@ -595,14 +626,14 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
595 return -ERESTARTSYS; 626 return -ERESTARTSYS;
596 627
597 if (dev->state & DEV_DISCONNECTED) { 628 if (dev->state & DEV_DISCONNECTED) {
598 em28xx_videodbg("mmap: device not present"); 629 em28xx_videodbg("mmap: device not present\n");
599 up(&dev->fileop_lock); 630 up(&dev->fileop_lock);
600 return -ENODEV; 631 return -ENODEV;
601 } 632 }
602 633
603 if (dev->state & DEV_MISCONFIGURED) { 634 if (dev->state & DEV_MISCONFIGURED) {
604 em28xx_videodbg ("mmap: Device is misconfigured; close and " 635 em28xx_videodbg ("mmap: Device is misconfigured; close and "
605 "open it again"); 636 "open it again\n");
606 up(&dev->fileop_lock); 637 up(&dev->fileop_lock);
607 return -EIO; 638 return -EIO;
608 } 639 }
@@ -618,7 +649,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
618 break; 649 break;
619 } 650 }
620 if (i == dev->num_frames) { 651 if (i == dev->num_frames) {
621 em28xx_videodbg("mmap: user supplied mapping address is out of range"); 652 em28xx_videodbg("mmap: user supplied mapping address is out of range\n");
622 up(&dev->fileop_lock); 653 up(&dev->fileop_lock);
623 return -EINVAL; 654 return -EINVAL;
624 } 655 }
@@ -632,7 +663,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
632 page = vmalloc_to_pfn((void *)pos); 663 page = vmalloc_to_pfn((void *)pos);
633 if (remap_pfn_range(vma, start, page, PAGE_SIZE, 664 if (remap_pfn_range(vma, start, page, PAGE_SIZE,
634 vma->vm_page_prot)) { 665 vma->vm_page_prot)) {
635 em28xx_videodbg("mmap: rename page map failed"); 666 em28xx_videodbg("mmap: rename page map failed\n");
636 up(&dev->fileop_lock); 667 up(&dev->fileop_lock);
637 return -EAGAIN; 668 return -EAGAIN;
638 } 669 }
@@ -749,7 +780,7 @@ static int em28xx_stream_interrupt(struct em28xx *dev)
749 else if (ret) { 780 else if (ret) {
750 dev->state |= DEV_MISCONFIGURED; 781 dev->state |= DEV_MISCONFIGURED;
751 em28xx_videodbg("device is misconfigured; close and " 782 em28xx_videodbg("device is misconfigured; close and "
752 "open /dev/video%d again", dev->vdev->minor); 783 "open /dev/video%d again\n", dev->vdev->minor);
753 return ret; 784 return ret;
754 } 785 }
755 786
@@ -800,28 +831,6 @@ static int em28xx_set_norm(struct em28xx *dev, int width, int height)
800 return 0; 831 return 0;
801} 832}
802 833
803static void video_mux(struct em28xx *dev, int index)
804{
805 int input, ainput;
806
807 input = INPUT(index)->vmux;
808 dev->ctl_input = index;
809
810 em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input);
811
812 dev->ctl_ainput = INPUT(index)->amux;
813
814 switch (dev->ctl_ainput) {
815 case 0:
816 ainput = EM28XX_AUDIO_SRC_TUNER;
817 break;
818 default:
819 ainput = EM28XX_AUDIO_SRC_LINE;
820 }
821
822 em28xx_audio_source(dev, ainput);
823}
824
825/* 834/*
826 * em28xx_v4l2_do_ioctl() 835 * em28xx_v4l2_do_ioctl()
827 * This function is _not_ called directly, but from 836 * This function is _not_ called directly, but from
@@ -1062,7 +1071,7 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
1062 t->signal = 1071 t->signal =
1063 (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; 1072 (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
1064 1073
1065 em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x", t->signal, 1074 em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal,
1066 t->afc); 1075 t->afc);
1067 return 0; 1076 return 0;
1068 } 1077 }
@@ -1146,7 +1155,7 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
1146 1155
1147 dev->stream = STREAM_ON; /* FIXME: Start video capture here? */ 1156 dev->stream = STREAM_ON; /* FIXME: Start video capture here? */
1148 1157
1149 em28xx_videodbg("VIDIOC_STREAMON: starting stream"); 1158 em28xx_videodbg("VIDIOC_STREAMON: starting stream\n");
1150 1159
1151 return 0; 1160 return 0;
1152 } 1161 }
@@ -1160,7 +1169,7 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
1160 return -EINVAL; 1169 return -EINVAL;
1161 1170
1162 if (dev->stream == STREAM_ON) { 1171 if (dev->stream == STREAM_ON) {
1163 em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream"); 1172 em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n");
1164 if ((ret = em28xx_stream_interrupt(dev))) 1173 if ((ret = em28xx_stream_interrupt(dev)))
1165 return ret; 1174 return ret;
1166 } 1175 }
@@ -1234,7 +1243,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1234 { 1243 {
1235 struct v4l2_format *format = arg; 1244 struct v4l2_format *format = arg;
1236 1245
1237 em28xx_videodbg("VIDIOC_G_FMT: type=%s", 1246 em28xx_videodbg("VIDIOC_G_FMT: type=%s\n",
1238 format->type == 1247 format->type ==
1239 V4L2_BUF_TYPE_VIDEO_CAPTURE ? 1248 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
1240 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type == 1249 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
@@ -1253,7 +1262,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1253 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 1262 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1254 format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ 1263 format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
1255 1264
1256 em28xx_videodbg("VIDIOC_G_FMT: %dx%d", dev->width, 1265 em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width,
1257 dev->height); 1266 dev->height);
1258 return 0; 1267 return 0;
1259 } 1268 }
@@ -1274,7 +1283,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1274 1283
1275/* int both_fields; */ 1284/* int both_fields; */
1276 1285
1277 em28xx_videodbg("%s: type=%s", 1286 em28xx_videodbg("%s: type=%s\n",
1278 cmd == 1287 cmd ==
1279 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : 1288 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1280 "VIDIOC_S_FMT", 1289 "VIDIOC_S_FMT",
@@ -1288,7 +1297,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1288 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1297 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1289 return -EINVAL; 1298 return -EINVAL;
1290 1299
1291 em28xx_videodbg("%s: requested %dx%d", 1300 em28xx_videodbg("%s: requested %dx%d\n",
1292 cmd == 1301 cmd ==
1293 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : 1302 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1294 "VIDIOC_S_FMT", format->fmt.pix.width, 1303 "VIDIOC_S_FMT", format->fmt.pix.width,
@@ -1347,7 +1356,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1347 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 1356 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1348 format->fmt.pix.field = V4L2_FIELD_INTERLACED; 1357 format->fmt.pix.field = V4L2_FIELD_INTERLACED;
1349 1358
1350 em28xx_videodbg("%s: returned %dx%d (%d, %d)", 1359 em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
1351 cmd == 1360 cmd ==
1352 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : 1361 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1353 "VIDIOC_S_FMT", format->fmt.pix.width, 1362 "VIDIOC_S_FMT", format->fmt.pix.width,
@@ -1359,13 +1368,13 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1359 for (i = 0; i < dev->num_frames; i++) 1368 for (i = 0; i < dev->num_frames; i++)
1360 if (dev->frame[i].vma_use_count) { 1369 if (dev->frame[i].vma_use_count) {
1361 em28xx_videodbg("VIDIOC_S_FMT failed. " 1370 em28xx_videodbg("VIDIOC_S_FMT failed. "
1362 "Unmap the buffers first."); 1371 "Unmap the buffers first.\n");
1363 return -EINVAL; 1372 return -EINVAL;
1364 } 1373 }
1365 1374
1366 /* stop io in case it is already in progress */ 1375 /* stop io in case it is already in progress */
1367 if (dev->stream == STREAM_ON) { 1376 if (dev->stream == STREAM_ON) {
1368 em28xx_videodbg("VIDIOC_SET_FMT: interupting stream"); 1377 em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
1369 if ((ret = em28xx_stream_interrupt(dev))) 1378 if ((ret = em28xx_stream_interrupt(dev)))
1370 return ret; 1379 return ret;
1371 } 1380 }
@@ -1405,18 +1414,18 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1405 if (dev->io == IO_READ) { 1414 if (dev->io == IO_READ) {
1406 em28xx_videodbg ("method is set to read;" 1415 em28xx_videodbg ("method is set to read;"
1407 " close and open the device again to" 1416 " close and open the device again to"
1408 " choose the mmap I/O method"); 1417 " choose the mmap I/O method\n");
1409 return -EINVAL; 1418 return -EINVAL;
1410 } 1419 }
1411 1420
1412 for (i = 0; i < dev->num_frames; i++) 1421 for (i = 0; i < dev->num_frames; i++)
1413 if (dev->frame[i].vma_use_count) { 1422 if (dev->frame[i].vma_use_count) {
1414 em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped"); 1423 em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n");
1415 return -EINVAL; 1424 return -EINVAL;
1416 } 1425 }
1417 1426
1418 if (dev->stream == STREAM_ON) { 1427 if (dev->stream == STREAM_ON) {
1419 em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream"); 1428 em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n");
1420 if ((ret = em28xx_stream_interrupt(dev))) 1429 if ((ret = em28xx_stream_interrupt(dev)))
1421 return ret; 1430 return ret;
1422 } 1431 }
@@ -1430,7 +1439,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1430 1439
1431 dev->frame_current = NULL; 1440 dev->frame_current = NULL;
1432 1441
1433 em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i", 1442 em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n",
1434 rb->count); 1443 rb->count);
1435 dev->io = rb->count ? IO_MMAP : IO_NONE; 1444 dev->io = rb->count ? IO_MMAP : IO_NONE;
1436 return 0; 1445 return 0;
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index d603229c9f2f..b599f0554fb7 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -90,6 +90,8 @@ struct msp3400c {
90 int stereo; 90 int stereo;
91 int nicam_on; 91 int nicam_on;
92 int acb; 92 int acb;
93 int in_scart;
94 int i2s_mode;
93 int main, second; /* sound carrier */ 95 int main, second; /* sound carrier */
94 int input; 96 int input;
95 int source; /* see msp34xxg_set_source */ 97 int source; /* see msp34xxg_set_source */
@@ -364,12 +366,40 @@ static struct CARRIER_DETECT carrier_detect_65[] = {
364 366
365#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) 367#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
366 368
367/* ----------------------------------------------------------------------- */ 369/* ----------------------------------------------------------------------- *
370 * bits 9 8 5 - SCART DSP input Select:
371 * 0 0 0 - SCART 1 to DSP input (reset position)
372 * 0 1 0 - MONO to DSP input
373 * 1 0 0 - SCART 2 to DSP input
374 * 1 1 1 - Mute DSP input
375 *
376 * bits 11 10 6 - SCART 1 Output Select:
377 * 0 0 0 - undefined (reset position)
378 * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
379 * 1 0 0 - MONO input to SCART 1 Output
380 * 1 1 0 - SCART 1 DA to SCART 1 Output
381 * 0 0 1 - SCART 2 DA to SCART 1 Output
382 * 0 1 1 - SCART 1 Input to SCART 1 Output
383 * 1 1 1 - Mute SCART 1 Output
384 *
385 * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART):
386 * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position)
387 * 0 1 0 - SCART 1 Input to SCART 2 Output
388 * 1 0 0 - MONO input to SCART 2 Output
389 * 0 0 1 - SCART 2 DA to SCART 2 Output
390 * 0 1 1 - SCART 2 Input to SCART 2 Output
391 * 1 1 0 - Mute SCART 2 Output
392 *
393 * Bits 4 to 0 should be zero.
394 * ----------------------------------------------------------------------- */
368 395
369static int scarts[3][9] = { 396static int scarts[3][9] = {
370 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ 397 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
398 /* SCART DSP Input select */
371 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, 399 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
400 /* SCART1 Output select */
372 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, 401 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
402 /* SCART2 Output select */
373 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, 403 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
374}; 404};
375 405
@@ -381,13 +411,23 @@ static void msp3400c_set_scart(struct i2c_client *client, int in, int out)
381{ 411{
382 struct msp3400c *msp = i2c_get_clientdata(client); 412 struct msp3400c *msp = i2c_get_clientdata(client);
383 413
384 if (-1 == scarts[out][in]) 414 msp->in_scart=in;
385 return; 415
416 if (in<=2) {
417 if (-1 == scarts[out][in])
418 return;
419
420 msp->acb &= ~scarts[out][SCART_MASK];
421 msp->acb |= scarts[out][in];
422 } else
423 msp->acb = 0xf60; /* Mute Input and SCART 1 Output */
424
425 dprintk("msp34xx: scart switch: %s => %d (ACB=0x%04x)\n",
426 scart_names[in], out, msp->acb);
427 msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb);
386 428
387 dprintk("msp34xx: scart switch: %s => %d\n", scart_names[in], out); 429 /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
388 msp->acb &= ~scarts[out][SCART_MASK]; 430 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
389 msp->acb |= scarts[out][in];
390 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb);
391} 431}
392 432
393/* ------------------------------------------------------------------------ */ 433/* ------------------------------------------------------------------------ */
@@ -1235,7 +1275,8 @@ static int msp3410d_thread(void *data)
1235 msp3400c_setbass(client, msp->bass); 1275 msp3400c_setbass(client, msp->bass);
1236 msp3400c_settreble(client, msp->treble); 1276 msp3400c_settreble(client, msp->treble);
1237 msp3400c_setvolume(client, msp->muted, msp->left, msp->right); 1277 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1238 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb); 1278 msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb);
1279 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1239 msp3400c_restore_dfp(client); 1280 msp3400c_restore_dfp(client);
1240 1281
1241 /* monitor tv audio mode */ 1282 /* monitor tv audio mode */
@@ -1275,6 +1316,8 @@ static int msp34xxg_reset(struct i2c_client *client)
1275 0x0f20 /* mute DSP input, mute SCART 1 */)) 1316 0x0f20 /* mute DSP input, mute SCART 1 */))
1276 return -1; 1317 return -1;
1277 1318
1319 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1320
1278 /* step-by-step initialisation, as described in the manual */ 1321 /* step-by-step initialisation, as described in the manual */
1279 modus = msp34xx_modus(msp->norm); 1322 modus = msp34xx_modus(msp->norm);
1280 std = msp34xx_standard(msp->norm); 1323 std = msp34xx_standard(msp->norm);
@@ -1371,6 +1414,8 @@ static int msp34xxg_thread(void *data)
1371 0x13, /* ACB */ 1414 0x13, /* ACB */
1372 msp->acb)) 1415 msp->acb))
1373 return -1; 1416 return -1;
1417
1418 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1374 } 1419 }
1375 dprintk("msp34xxg: thread: exit\n"); 1420 dprintk("msp34xxg: thread: exit\n");
1376 return 0; 1421 return 0;
@@ -1539,6 +1584,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1539 msp->treble = 32768; 1584 msp->treble = 32768;
1540 msp->input = -1; 1585 msp->input = -1;
1541 msp->muted = 0; 1586 msp->muted = 0;
1587 msp->i2s_mode = 0;
1542 for (i = 0; i < DFP_COUNT; i++) 1588 for (i = 0; i < DFP_COUNT; i++)
1543 msp->dfp_regs[i] = -1; 1589 msp->dfp_regs[i] = -1;
1544 1590
@@ -1735,6 +1781,7 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1735 } 1781 }
1736} 1782}
1737 1783
1784
1738static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) 1785static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1739{ 1786{
1740 struct msp3400c *msp = i2c_get_clientdata(client); 1787 struct msp3400c *msp = i2c_get_clientdata(client);
@@ -1745,6 +1792,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1745 1792
1746 case AUDC_SET_INPUT: 1793 case AUDC_SET_INPUT:
1747 dprintk("msp34xx: AUDC_SET_INPUT(%d)\n",*sarg); 1794 dprintk("msp34xx: AUDC_SET_INPUT(%d)\n",*sarg);
1795
1748 if (*sarg == msp->input) 1796 if (*sarg == msp->input)
1749 break; 1797 break;
1750 msp->input = *sarg; 1798 msp->input = *sarg;
@@ -1923,6 +1971,16 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1923 break; 1971 break;
1924 } 1972 }
1925 1973
1974 /* msp34xx specific */
1975 case MSP_SET_MATRIX:
1976 {
1977 struct msp_matrix *mspm = arg;
1978
1979 dprintk("msp34xx: MSP_SET_MATRIX\n");
1980 msp3400c_set_scart(client, mspm->input, mspm->output);
1981 break;
1982 }
1983
1926 /* --- v4l2 ioctls --- */ 1984 /* --- v4l2 ioctls --- */
1927 case VIDIOC_S_STD: 1985 case VIDIOC_S_STD:
1928 { 1986 {
@@ -1941,6 +1999,33 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1941 return 0; 1999 return 0;
1942 } 2000 }
1943 2001
2002 case VIDIOC_ENUMINPUT:
2003 {
2004 struct v4l2_input *i = arg;
2005
2006 if (i->index != 0)
2007 return -EINVAL;
2008
2009 i->type = V4L2_INPUT_TYPE_TUNER;
2010 switch (i->index) {
2011 case AUDIO_RADIO:
2012 strcpy(i->name,"Radio");
2013 break;
2014 case AUDIO_EXTERN_1:
2015 strcpy(i->name,"Extern 1");
2016 break;
2017 case AUDIO_EXTERN_2:
2018 strcpy(i->name,"Extern 2");
2019 break;
2020 case AUDIO_TUNER:
2021 strcpy(i->name,"Television");
2022 break;
2023 default:
2024 return -EINVAL;
2025 }
2026 return 0;
2027 }
2028
1944 case VIDIOC_G_AUDIO: 2029 case VIDIOC_G_AUDIO:
1945 { 2030 {
1946 struct v4l2_audio *a = arg; 2031 struct v4l2_audio *a = arg;
@@ -2032,13 +2117,44 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
2032 break; 2117 break;
2033 } 2118 }
2034 2119
2035 /* msp34xx specific */ 2120 case VIDIOC_G_AUDOUT:
2036 case MSP_SET_MATRIX:
2037 { 2121 {
2038 struct msp_matrix *mspm = arg; 2122 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2123
2124 memset(a,0,sizeof(*a));
2125
2126 switch (a->index) {
2127 case 0:
2128 strcpy(a->name,"Scart1 Out");
2129 break;
2130 case 1:
2131 strcpy(a->name,"Scart2 Out");
2132 break;
2133 case 2:
2134 strcpy(a->name,"I2S Out");
2135 break;
2136 default:
2137 return -EINVAL;
2138 }
2139 break;
2140
2141 }
2142 case VIDIOC_S_AUDOUT:
2143 {
2144 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2145
2146 if (a->index<0||a->index>2)
2147 return -EINVAL;
2148
2149 if (a->index==2) {
2150 if (a->mode == V4L2_AUDMODE_32BITS)
2151 msp->i2s_mode=1;
2152 else
2153 msp->i2s_mode=0;
2154 }
2155printk("Setting audio out on msp34xx to input %i, mode %i\n",a->index,msp->i2s_mode);
2156 msp3400c_set_scart(client,msp->in_scart,a->index);
2039 2157
2040 dprintk("msp34xx: MSP_SET_MATRIX\n");
2041 msp3400c_set_scart(client, mspm->input, mspm->output);
2042 break; 2158 break;
2043 } 2159 }
2044 2160
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index e8a0d22df54f..67c61b4bf2e7 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -885,6 +885,7 @@ struct v4l2_audio
885 885
886/* Flags for the 'mode' field */ 886/* Flags for the 'mode' field */
887#define V4L2_AUDMODE_AVL 0x00001 887#define V4L2_AUDMODE_AVL 0x00001
888#define V4L2_AUDMODE_32BITS 0x00002
888 889
889struct v4l2_audioout 890struct v4l2_audioout
890{ 891{