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/video/em28xx/em28xx-video.c | |
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/video/em28xx/em28xx-video.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 107 |
1 files changed, 58 insertions, 49 deletions
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; |