diff options
author | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 2005-11-09 00:38:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-09 10:56:30 -0500 |
commit | eac94356c8f9f7d3854ed0290a406b13bfe8df4c (patch) | |
tree | 5dd31d7ecbb1d0d857972478a322ccb838dd668c /drivers/media | |
parent | c3d931929f1d11f9d198567850247ae1754dfc06 (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>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 15 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 17 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 107 | ||||
-rw-r--r-- | drivers/media/video/msp3400.c | 142 |
4 files changed, 200 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 | ||
280 | static 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 | ||
803 | static 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 | ||
369 | static int scarts[3][9] = { | 396 | static 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 | |||
1738 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | 1785 | static 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 | } | ||
2155 | printk("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 | ||