diff options
Diffstat (limited to 'drivers/media/video/saa7134/saa7134-video.c')
-rw-r--r-- | drivers/media/video/saa7134/saa7134-video.c | 70 |
1 files changed, 46 insertions, 24 deletions
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index e97426bc85df..57a11e71d996 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -460,17 +460,17 @@ static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int | |||
460 | return 1; | 460 | return 1; |
461 | 461 | ||
462 | /* is it free? */ | 462 | /* is it free? */ |
463 | down(&dev->lock); | 463 | mutex_lock(&dev->lock); |
464 | if (dev->resources & bit) { | 464 | if (dev->resources & bit) { |
465 | /* no, someone else uses it */ | 465 | /* no, someone else uses it */ |
466 | up(&dev->lock); | 466 | mutex_unlock(&dev->lock); |
467 | return 0; | 467 | return 0; |
468 | } | 468 | } |
469 | /* it's free, grab it */ | 469 | /* it's free, grab it */ |
470 | fh->resources |= bit; | 470 | fh->resources |= bit; |
471 | dev->resources |= bit; | 471 | dev->resources |= bit; |
472 | dprintk("res: get %d\n",bit); | 472 | dprintk("res: get %d\n",bit); |
473 | up(&dev->lock); | 473 | mutex_unlock(&dev->lock); |
474 | return 1; | 474 | return 1; |
475 | } | 475 | } |
476 | 476 | ||
@@ -489,14 +489,13 @@ int res_locked(struct saa7134_dev *dev, unsigned int bit) | |||
489 | static | 489 | static |
490 | void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) | 490 | void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) |
491 | { | 491 | { |
492 | if ((fh->resources & bits) != bits) | 492 | BUG_ON((fh->resources & bits) != bits); |
493 | BUG(); | ||
494 | 493 | ||
495 | down(&dev->lock); | 494 | mutex_lock(&dev->lock); |
496 | fh->resources &= ~bits; | 495 | fh->resources &= ~bits; |
497 | dev->resources &= ~bits; | 496 | dev->resources &= ~bits; |
498 | dprintk("res: put %d\n",bits); | 497 | dprintk("res: put %d\n",bits); |
499 | up(&dev->lock); | 498 | mutex_unlock(&dev->lock); |
500 | } | 499 | } |
501 | 500 | ||
502 | /* ------------------------------------------------------------------ */ | 501 | /* ------------------------------------------------------------------ */ |
@@ -1340,21 +1339,21 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
1340 | if (!list_empty(&fh->cap.stream)) | 1339 | if (!list_empty(&fh->cap.stream)) |
1341 | buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); | 1340 | buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); |
1342 | } else { | 1341 | } else { |
1343 | down(&fh->cap.lock); | 1342 | mutex_lock(&fh->cap.lock); |
1344 | if (UNSET == fh->cap.read_off) { | 1343 | if (UNSET == fh->cap.read_off) { |
1345 | /* need to capture a new frame */ | 1344 | /* need to capture a new frame */ |
1346 | if (res_locked(fh->dev,RESOURCE_VIDEO)) { | 1345 | if (res_locked(fh->dev,RESOURCE_VIDEO)) { |
1347 | up(&fh->cap.lock); | 1346 | mutex_unlock(&fh->cap.lock); |
1348 | return POLLERR; | 1347 | return POLLERR; |
1349 | } | 1348 | } |
1350 | if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { | 1349 | if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { |
1351 | up(&fh->cap.lock); | 1350 | mutex_unlock(&fh->cap.lock); |
1352 | return POLLERR; | 1351 | return POLLERR; |
1353 | } | 1352 | } |
1354 | fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); | 1353 | fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); |
1355 | fh->cap.read_off = 0; | 1354 | fh->cap.read_off = 0; |
1356 | } | 1355 | } |
1357 | up(&fh->cap.lock); | 1356 | mutex_unlock(&fh->cap.lock); |
1358 | buf = fh->cap.read_buf; | 1357 | buf = fh->cap.read_buf; |
1359 | } | 1358 | } |
1360 | 1359 | ||
@@ -1463,6 +1462,10 @@ static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
1463 | f->fmt.pix.height * f->fmt.pix.bytesperline; | 1462 | f->fmt.pix.height * f->fmt.pix.bytesperline; |
1464 | return 0; | 1463 | return 0; |
1465 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1464 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1465 | if (saa7134_no_overlay > 0) { | ||
1466 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | ||
1467 | return -EINVAL; | ||
1468 | } | ||
1466 | f->fmt.win = fh->win; | 1469 | f->fmt.win = fh->win; |
1467 | return 0; | 1470 | return 0; |
1468 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 1471 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
@@ -1527,6 +1530,10 @@ static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
1527 | return 0; | 1530 | return 0; |
1528 | } | 1531 | } |
1529 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1532 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1533 | if (saa7134_no_overlay > 0) { | ||
1534 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | ||
1535 | return -EINVAL; | ||
1536 | } | ||
1530 | err = verify_preview(dev,&f->fmt.win); | 1537 | err = verify_preview(dev,&f->fmt.win); |
1531 | if (0 != err) | 1538 | if (0 != err) |
1532 | return err; | 1539 | return err; |
@@ -1557,18 +1564,22 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
1557 | fh->cap.field = f->fmt.pix.field; | 1564 | fh->cap.field = f->fmt.pix.field; |
1558 | return 0; | 1565 | return 0; |
1559 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1566 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1567 | if (saa7134_no_overlay > 0) { | ||
1568 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | ||
1569 | return -EINVAL; | ||
1570 | } | ||
1560 | err = verify_preview(dev,&f->fmt.win); | 1571 | err = verify_preview(dev,&f->fmt.win); |
1561 | if (0 != err) | 1572 | if (0 != err) |
1562 | return err; | 1573 | return err; |
1563 | 1574 | ||
1564 | down(&dev->lock); | 1575 | mutex_lock(&dev->lock); |
1565 | fh->win = f->fmt.win; | 1576 | fh->win = f->fmt.win; |
1566 | fh->nclips = f->fmt.win.clipcount; | 1577 | fh->nclips = f->fmt.win.clipcount; |
1567 | if (fh->nclips > 8) | 1578 | if (fh->nclips > 8) |
1568 | fh->nclips = 8; | 1579 | fh->nclips = 8; |
1569 | if (copy_from_user(fh->clips,f->fmt.win.clips, | 1580 | if (copy_from_user(fh->clips,f->fmt.win.clips, |
1570 | sizeof(struct v4l2_clip)*fh->nclips)) { | 1581 | sizeof(struct v4l2_clip)*fh->nclips)) { |
1571 | up(&dev->lock); | 1582 | mutex_unlock(&dev->lock); |
1572 | return -EFAULT; | 1583 | return -EFAULT; |
1573 | } | 1584 | } |
1574 | 1585 | ||
@@ -1578,7 +1589,7 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
1578 | start_preview(dev,fh); | 1589 | start_preview(dev,fh); |
1579 | spin_unlock_irqrestore(&dev->slock,flags); | 1590 | spin_unlock_irqrestore(&dev->slock,flags); |
1580 | } | 1591 | } |
1581 | up(&dev->lock); | 1592 | mutex_unlock(&dev->lock); |
1582 | return 0; | 1593 | return 0; |
1583 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 1594 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
1584 | saa7134_vbi_fmt(dev,f); | 1595 | saa7134_vbi_fmt(dev,f); |
@@ -1612,9 +1623,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev, | |||
1612 | return get_control(dev,arg); | 1623 | return get_control(dev,arg); |
1613 | case VIDIOC_S_CTRL: | 1624 | case VIDIOC_S_CTRL: |
1614 | { | 1625 | { |
1615 | down(&dev->lock); | 1626 | mutex_lock(&dev->lock); |
1616 | err = set_control(dev,NULL,arg); | 1627 | err = set_control(dev,NULL,arg); |
1617 | up(&dev->lock); | 1628 | mutex_unlock(&dev->lock); |
1618 | return err; | 1629 | return err; |
1619 | } | 1630 | } |
1620 | /* --- input switching --------------------------------------- */ | 1631 | /* --- input switching --------------------------------------- */ |
@@ -1664,9 +1675,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev, | |||
1664 | return -EINVAL; | 1675 | return -EINVAL; |
1665 | if (NULL == card_in(dev,*i).name) | 1676 | if (NULL == card_in(dev,*i).name) |
1666 | return -EINVAL; | 1677 | return -EINVAL; |
1667 | down(&dev->lock); | 1678 | mutex_lock(&dev->lock); |
1668 | video_mux(dev,*i); | 1679 | video_mux(dev,*i); |
1669 | up(&dev->lock); | 1680 | mutex_unlock(&dev->lock); |
1670 | return 0; | 1681 | return 0; |
1671 | } | 1682 | } |
1672 | 1683 | ||
@@ -1716,11 +1727,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1716 | cap->version = SAA7134_VERSION_CODE; | 1727 | cap->version = SAA7134_VERSION_CODE; |
1717 | cap->capabilities = | 1728 | cap->capabilities = |
1718 | V4L2_CAP_VIDEO_CAPTURE | | 1729 | V4L2_CAP_VIDEO_CAPTURE | |
1719 | V4L2_CAP_VIDEO_OVERLAY | | ||
1720 | V4L2_CAP_VBI_CAPTURE | | 1730 | V4L2_CAP_VBI_CAPTURE | |
1721 | V4L2_CAP_READWRITE | | 1731 | V4L2_CAP_READWRITE | |
1722 | V4L2_CAP_STREAMING | | 1732 | V4L2_CAP_STREAMING | |
1723 | V4L2_CAP_TUNER; | 1733 | V4L2_CAP_TUNER; |
1734 | if (saa7134_no_overlay <= 0) { | ||
1735 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; | ||
1736 | } | ||
1724 | 1737 | ||
1725 | if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) | 1738 | if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) |
1726 | cap->capabilities &= ~V4L2_CAP_TUNER; | 1739 | cap->capabilities &= ~V4L2_CAP_TUNER; |
@@ -1766,7 +1779,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1766 | if (i == TVNORMS) | 1779 | if (i == TVNORMS) |
1767 | return -EINVAL; | 1780 | return -EINVAL; |
1768 | 1781 | ||
1769 | down(&dev->lock); | 1782 | mutex_lock(&dev->lock); |
1770 | if (res_check(fh, RESOURCE_OVERLAY)) { | 1783 | if (res_check(fh, RESOURCE_OVERLAY)) { |
1771 | spin_lock_irqsave(&dev->slock,flags); | 1784 | spin_lock_irqsave(&dev->slock,flags); |
1772 | stop_preview(dev,fh); | 1785 | stop_preview(dev,fh); |
@@ -1776,7 +1789,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1776 | } else | 1789 | } else |
1777 | set_tvnorm(dev,&tvnorms[i]); | 1790 | set_tvnorm(dev,&tvnorms[i]); |
1778 | saa7134_tvaudio_do_scan(dev); | 1791 | saa7134_tvaudio_do_scan(dev); |
1779 | up(&dev->lock); | 1792 | mutex_unlock(&dev->lock); |
1780 | return 0; | 1793 | return 0; |
1781 | } | 1794 | } |
1782 | 1795 | ||
@@ -1909,13 +1922,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1909 | return -EINVAL; | 1922 | return -EINVAL; |
1910 | if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) | 1923 | if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) |
1911 | return -EINVAL; | 1924 | return -EINVAL; |
1912 | down(&dev->lock); | 1925 | mutex_lock(&dev->lock); |
1913 | dev->ctl_freq = f->frequency; | 1926 | dev->ctl_freq = f->frequency; |
1914 | 1927 | ||
1915 | saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); | 1928 | saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); |
1916 | 1929 | ||
1917 | saa7134_tvaudio_do_scan(dev); | 1930 | saa7134_tvaudio_do_scan(dev); |
1918 | up(&dev->lock); | 1931 | mutex_unlock(&dev->lock); |
1919 | return 0; | 1932 | return 0; |
1920 | } | 1933 | } |
1921 | 1934 | ||
@@ -1971,6 +1984,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1971 | switch (type) { | 1984 | switch (type) { |
1972 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1985 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1973 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1986 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1987 | if (saa7134_no_overlay > 0) { | ||
1988 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | ||
1989 | return -EINVAL; | ||
1990 | } | ||
1974 | if (index >= FORMATS) | 1991 | if (index >= FORMATS) |
1975 | return -EINVAL; | 1992 | return -EINVAL; |
1976 | if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY && | 1993 | if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY && |
@@ -2031,6 +2048,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
2031 | int *on = arg; | 2048 | int *on = arg; |
2032 | 2049 | ||
2033 | if (*on) { | 2050 | if (*on) { |
2051 | if (saa7134_no_overlay > 0) { | ||
2052 | printk ("no_overlay\n"); | ||
2053 | return -EINVAL; | ||
2054 | } | ||
2055 | |||
2034 | if (!res_get(dev,fh,RESOURCE_OVERLAY)) | 2056 | if (!res_get(dev,fh,RESOURCE_OVERLAY)) |
2035 | return -EBUSY; | 2057 | return -EBUSY; |
2036 | spin_lock_irqsave(&dev->slock,flags); | 2058 | spin_lock_irqsave(&dev->slock,flags); |
@@ -2282,7 +2304,7 @@ static struct file_operations radio_fops = | |||
2282 | struct video_device saa7134_video_template = | 2304 | struct video_device saa7134_video_template = |
2283 | { | 2305 | { |
2284 | .name = "saa7134-video", | 2306 | .name = "saa7134-video", |
2285 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| | 2307 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| |
2286 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, | 2308 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, |
2287 | .hardware = 0, | 2309 | .hardware = 0, |
2288 | .fops = &video_fops, | 2310 | .fops = &video_fops, |