aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx/em28xx-video.c
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 /drivers/media/video/em28xx/em28xx-video.c
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>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-video.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c107
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
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;