diff options
author | Douglas Schilling Landgraf <dougsland@gmail.com> | 2007-12-07 15:09:53 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:03:15 -0500 |
commit | 8f61ae2f4ff698c7cd83b1f17b1ca2ecfc7f0696 (patch) | |
tree | a945be99e61cbb7959135f82448335c2e649c869 | |
parent | 863c86dd7e014e645207fd16f4e06bc223567984 (diff) |
V4L/DVB (6734): Converted saa7134-video to use video_ioctl2
Signed-off-by: Douglas Schilling Landgraf <dougsland@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/video/saa7134/saa7134-video.c | 1212 |
1 files changed, 610 insertions, 602 deletions
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 9c160b2bca3d..954542e5c99f 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -1119,8 +1119,11 @@ static struct videobuf_queue_ops video_qops = { | |||
1119 | 1119 | ||
1120 | /* ------------------------------------------------------------------ */ | 1120 | /* ------------------------------------------------------------------ */ |
1121 | 1121 | ||
1122 | static int get_control(struct saa7134_dev *dev, struct v4l2_control *c) | 1122 | static int vidioc_g_ctrl(struct file *file, void *priv, |
1123 | struct v4l2_control *c) | ||
1123 | { | 1124 | { |
1125 | struct saa7134_fh *fh = priv; | ||
1126 | struct saa7134_dev *dev = fh->dev; | ||
1124 | const struct v4l2_queryctrl* ctrl; | 1127 | const struct v4l2_queryctrl* ctrl; |
1125 | 1128 | ||
1126 | ctrl = ctrl_by_id(c->id); | 1129 | ctrl = ctrl_by_id(c->id); |
@@ -1166,13 +1169,16 @@ static int get_control(struct saa7134_dev *dev, struct v4l2_control *c) | |||
1166 | return 0; | 1169 | return 0; |
1167 | } | 1170 | } |
1168 | 1171 | ||
1169 | static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh, | 1172 | static int vidioc_s_ctrl(struct file *file, void *f, |
1170 | struct v4l2_control *c) | 1173 | struct v4l2_control *c) |
1171 | { | 1174 | { |
1172 | const struct v4l2_queryctrl* ctrl; | 1175 | const struct v4l2_queryctrl* ctrl; |
1176 | struct saa7134_fh *fh = f; | ||
1177 | struct saa7134_dev *dev = fh->dev; | ||
1173 | unsigned long flags; | 1178 | unsigned long flags; |
1174 | int restart_overlay = 0; | 1179 | int restart_overlay = 0; |
1175 | 1180 | ||
1181 | mutex_lock(&dev->lock); | ||
1176 | ctrl = ctrl_by_id(c->id); | 1182 | ctrl = ctrl_by_id(c->id); |
1177 | if (NULL == ctrl) | 1183 | if (NULL == ctrl) |
1178 | return -EINVAL; | 1184 | return -EINVAL; |
@@ -1255,6 +1261,7 @@ static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
1255 | break; | 1261 | break; |
1256 | } | 1262 | } |
1257 | default: | 1263 | default: |
1264 | mutex_unlock(&dev->lock); | ||
1258 | return -EINVAL; | 1265 | return -EINVAL; |
1259 | } | 1266 | } |
1260 | if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) { | 1267 | if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) { |
@@ -1263,6 +1270,7 @@ static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
1263 | start_preview(dev,fh); | 1270 | start_preview(dev,fh); |
1264 | spin_unlock_irqrestore(&dev->slock,flags); | 1271 | spin_unlock_irqrestore(&dev->slock,flags); |
1265 | } | 1272 | } |
1273 | mutex_unlock(&dev->lock); | ||
1266 | return 0; | 1274 | return 0; |
1267 | } | 1275 | } |
1268 | 1276 | ||
@@ -1502,9 +1510,12 @@ static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f) | |||
1502 | 1510 | ||
1503 | } | 1511 | } |
1504 | 1512 | ||
1505 | static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | 1513 | static int vidioc_g_fmt_cap(struct file *file, void *priv, |
1506 | struct v4l2_format *f) | 1514 | struct v4l2_format *f) |
1507 | { | 1515 | { |
1516 | struct saa7134_fh *fh = priv; | ||
1517 | struct saa7134_dev *dev = fh->dev; | ||
1518 | |||
1508 | switch (f->type) { | 1519 | switch (f->type) { |
1509 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1520 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1510 | memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); | 1521 | memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); |
@@ -1532,9 +1543,11 @@ static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
1532 | } | 1543 | } |
1533 | } | 1544 | } |
1534 | 1545 | ||
1535 | static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | 1546 | static int vidioc_try_fmt_cap(struct file *file, void *priv, |
1536 | struct v4l2_format *f) | 1547 | struct v4l2_format *f) |
1537 | { | 1548 | { |
1549 | struct saa7134_fh *fh = priv; | ||
1550 | struct saa7134_dev *dev = fh->dev; | ||
1538 | int err; | 1551 | int err; |
1539 | 1552 | ||
1540 | switch (f->type) { | 1553 | switch (f->type) { |
@@ -1602,15 +1615,17 @@ static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
1602 | } | 1615 | } |
1603 | } | 1616 | } |
1604 | 1617 | ||
1605 | static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | 1618 | static int vidioc_s_fmt_cap(struct file *file, void *priv, |
1606 | struct v4l2_format *f) | 1619 | struct v4l2_format *f) |
1607 | { | 1620 | { |
1621 | struct saa7134_fh *fh = priv; | ||
1622 | struct saa7134_dev *dev = fh->dev; | ||
1608 | unsigned long flags; | 1623 | unsigned long flags; |
1609 | int err; | 1624 | int err; |
1610 | 1625 | ||
1611 | switch (f->type) { | 1626 | switch (f->type) { |
1612 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1627 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1613 | err = saa7134_try_fmt(dev,fh,f); | 1628 | err = vidioc_try_fmt_cap(file, priv, f); |
1614 | if (0 != err) | 1629 | if (0 != err) |
1615 | return err; | 1630 | return err; |
1616 | 1631 | ||
@@ -1655,682 +1670,625 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, | |||
1655 | } | 1670 | } |
1656 | } | 1671 | } |
1657 | 1672 | ||
1658 | int saa7134_common_ioctl(struct saa7134_dev *dev, | 1673 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) |
1659 | unsigned int cmd, void *arg) | ||
1660 | { | 1674 | { |
1661 | int err; | 1675 | struct saa7134_fh *fh = priv; |
1676 | struct saa7134_dev *dev = fh->dev; | ||
1662 | 1677 | ||
1663 | switch (cmd) { | 1678 | *i = dev->ctl_input; |
1664 | case VIDIOC_QUERYCTRL: | 1679 | return 0; |
1665 | { | 1680 | } |
1666 | const struct v4l2_queryctrl *ctrl; | ||
1667 | struct v4l2_queryctrl *c = arg; | ||
1668 | 1681 | ||
1669 | if ((c->id < V4L2_CID_BASE || | 1682 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) |
1670 | c->id >= V4L2_CID_LASTP1) && | 1683 | { |
1671 | (c->id < V4L2_CID_PRIVATE_BASE || | 1684 | struct saa7134_fh *fh = priv; |
1672 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | 1685 | struct saa7134_dev *dev = fh->dev; |
1673 | return -EINVAL; | ||
1674 | ctrl = ctrl_by_id(c->id); | ||
1675 | *c = (NULL != ctrl) ? *ctrl : no_ctrl; | ||
1676 | return 0; | ||
1677 | } | ||
1678 | case VIDIOC_G_CTRL: | ||
1679 | return get_control(dev,arg); | ||
1680 | case VIDIOC_S_CTRL: | ||
1681 | { | ||
1682 | mutex_lock(&dev->lock); | ||
1683 | err = set_control(dev,NULL,arg); | ||
1684 | mutex_unlock(&dev->lock); | ||
1685 | return err; | ||
1686 | } | ||
1687 | /* --- input switching --------------------------------------- */ | ||
1688 | case VIDIOC_ENUMINPUT: | ||
1689 | { | ||
1690 | struct v4l2_input *i = arg; | ||
1691 | unsigned int n; | ||
1692 | 1686 | ||
1693 | n = i->index; | 1687 | if (i < 0 || i >= SAA7134_INPUT_MAX) |
1694 | if (n >= SAA7134_INPUT_MAX) | 1688 | return -EINVAL; |
1695 | return -EINVAL; | 1689 | if (NULL == card_in(dev, i).name) |
1696 | if (NULL == card_in(dev,i->index).name) | 1690 | return -EINVAL; |
1697 | return -EINVAL; | 1691 | mutex_lock(&dev->lock); |
1698 | memset(i,0,sizeof(*i)); | 1692 | video_mux(dev, i); |
1699 | i->index = n; | 1693 | mutex_unlock(&dev->lock); |
1700 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1694 | return 0; |
1701 | strcpy(i->name,card_in(dev,n).name); | 1695 | } |
1702 | if (card_in(dev,n).tv) | ||
1703 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
1704 | i->audioset = 1; | ||
1705 | if (n == dev->ctl_input) { | ||
1706 | int v1 = saa_readb(SAA7134_STATUS_VIDEO1); | ||
1707 | int v2 = saa_readb(SAA7134_STATUS_VIDEO2); | ||
1708 | |||
1709 | if (0 != (v1 & 0x40)) | ||
1710 | i->status |= V4L2_IN_ST_NO_H_LOCK; | ||
1711 | if (0 != (v2 & 0x40)) | ||
1712 | i->status |= V4L2_IN_ST_NO_SYNC; | ||
1713 | if (0 != (v2 & 0x0e)) | ||
1714 | i->status |= V4L2_IN_ST_MACROVISION; | ||
1715 | } | ||
1716 | for (n = 0; n < TVNORMS; n++) | ||
1717 | i->std |= tvnorms[n].id; | ||
1718 | return 0; | ||
1719 | } | ||
1720 | case VIDIOC_G_INPUT: | ||
1721 | { | ||
1722 | int *i = arg; | ||
1723 | *i = dev->ctl_input; | ||
1724 | return 0; | ||
1725 | } | ||
1726 | case VIDIOC_S_INPUT: | ||
1727 | { | ||
1728 | int *i = arg; | ||
1729 | 1696 | ||
1730 | if (*i < 0 || *i >= SAA7134_INPUT_MAX) | 1697 | static int vidioc_queryctrl(struct file *file, void *priv, |
1731 | return -EINVAL; | 1698 | struct v4l2_queryctrl *c) |
1732 | if (NULL == card_in(dev,*i).name) | 1699 | { |
1733 | return -EINVAL; | 1700 | const struct v4l2_queryctrl *ctrl; |
1734 | mutex_lock(&dev->lock); | ||
1735 | video_mux(dev,*i); | ||
1736 | mutex_unlock(&dev->lock); | ||
1737 | return 0; | ||
1738 | } | ||
1739 | 1701 | ||
1740 | } | 1702 | if ((c->id < V4L2_CID_BASE || |
1703 | c->id >= V4L2_CID_LASTP1) && | ||
1704 | (c->id < V4L2_CID_PRIVATE_BASE || | ||
1705 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | ||
1706 | return -EINVAL; | ||
1707 | ctrl = ctrl_by_id(c->id); | ||
1708 | *c = (NULL != ctrl) ? *ctrl : no_ctrl; | ||
1741 | return 0; | 1709 | return 0; |
1742 | } | 1710 | } |
1743 | EXPORT_SYMBOL(saa7134_common_ioctl); | ||
1744 | 1711 | ||
1745 | /* | 1712 | static int vidioc_enum_input(struct file *file, void *priv, |
1746 | * This function is _not_ called directly, but from | 1713 | struct v4l2_input *i) |
1747 | * video_generic_ioctl (and maybe others). userspace | ||
1748 | * copying is done already, arg is a kernel pointer. | ||
1749 | */ | ||
1750 | static int video_do_ioctl(struct inode *inode, struct file *file, | ||
1751 | unsigned int cmd, void *arg) | ||
1752 | { | 1714 | { |
1753 | struct saa7134_fh *fh = file->private_data; | 1715 | struct saa7134_fh *fh = priv; |
1754 | struct saa7134_dev *dev = fh->dev; | 1716 | struct saa7134_dev *dev = fh->dev; |
1755 | unsigned long flags; | 1717 | unsigned int n; |
1756 | int err; | ||
1757 | 1718 | ||
1758 | if (video_debug > 1) | 1719 | n = i->index; |
1759 | v4l_print_ioctl(dev->name,cmd); | 1720 | if (n >= SAA7134_INPUT_MAX) |
1721 | return -EINVAL; | ||
1722 | if (NULL == card_in(dev, i->index).name) | ||
1723 | return -EINVAL; | ||
1724 | memset(i, 0, sizeof(*i)); | ||
1725 | i->index = n; | ||
1726 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
1727 | strcpy(i->name, card_in(dev, n).name); | ||
1728 | if (card_in(dev, n).tv) | ||
1729 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
1730 | i->audioset = 1; | ||
1731 | if (n == dev->ctl_input) { | ||
1732 | int v1 = saa_readb(SAA7134_STATUS_VIDEO1); | ||
1733 | int v2 = saa_readb(SAA7134_STATUS_VIDEO2); | ||
1734 | |||
1735 | if (0 != (v1 & 0x40)) | ||
1736 | i->status |= V4L2_IN_ST_NO_H_LOCK; | ||
1737 | if (0 != (v2 & 0x40)) | ||
1738 | i->status |= V4L2_IN_ST_NO_SYNC; | ||
1739 | if (0 != (v2 & 0x0e)) | ||
1740 | i->status |= V4L2_IN_ST_MACROVISION; | ||
1741 | } | ||
1742 | for (n = 0; n < TVNORMS; n++) | ||
1743 | i->std |= tvnorms[n].id; | ||
1744 | return 0; | ||
1745 | } | ||
1760 | 1746 | ||
1761 | switch (cmd) { | 1747 | static int vidioc_querycap(struct file *file, void *priv, |
1762 | case VIDIOC_S_CTRL: | 1748 | struct v4l2_capability *cap) |
1763 | case VIDIOC_S_STD: | 1749 | { |
1764 | case VIDIOC_S_INPUT: | 1750 | struct saa7134_fh *fh = priv; |
1765 | case VIDIOC_S_TUNER: | 1751 | struct saa7134_dev *dev = fh->dev; |
1766 | case VIDIOC_S_FREQUENCY: | ||
1767 | err = v4l2_prio_check(&dev->prio,&fh->prio); | ||
1768 | if (0 != err) | ||
1769 | return err; | ||
1770 | } | ||
1771 | 1752 | ||
1772 | switch (cmd) { | 1753 | unsigned int tuner_type = dev->tuner_type; |
1773 | case VIDIOC_QUERYCAP: | 1754 | |
1774 | { | 1755 | memset(cap, 0, sizeof(*cap)); |
1775 | struct v4l2_capability *cap = arg; | 1756 | strcpy(cap->driver, "saa7134"); |
1776 | unsigned int tuner_type = dev->tuner_type; | 1757 | strlcpy(cap->card, saa7134_boards[dev->board].name, |
1777 | 1758 | sizeof(cap->card)); | |
1778 | memset(cap,0,sizeof(*cap)); | 1759 | sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); |
1779 | strcpy(cap->driver, "saa7134"); | 1760 | cap->version = SAA7134_VERSION_CODE; |
1780 | strlcpy(cap->card, saa7134_boards[dev->board].name, | 1761 | cap->capabilities = |
1781 | sizeof(cap->card)); | 1762 | V4L2_CAP_VIDEO_CAPTURE | |
1782 | sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); | 1763 | V4L2_CAP_VBI_CAPTURE | |
1783 | cap->version = SAA7134_VERSION_CODE; | 1764 | V4L2_CAP_READWRITE | |
1784 | cap->capabilities = | 1765 | V4L2_CAP_STREAMING | |
1785 | V4L2_CAP_VIDEO_CAPTURE | | 1766 | V4L2_CAP_TUNER; |
1786 | V4L2_CAP_VBI_CAPTURE | | 1767 | if (saa7134_no_overlay <= 0) |
1787 | V4L2_CAP_READWRITE | | 1768 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; |
1788 | V4L2_CAP_STREAMING | | 1769 | |
1789 | V4L2_CAP_TUNER; | 1770 | if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) |
1790 | if (saa7134_no_overlay <= 0) { | 1771 | cap->capabilities &= ~V4L2_CAP_TUNER; |
1791 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; | 1772 | return 0; |
1792 | } | 1773 | } |
1793 | 1774 | ||
1794 | if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) | 1775 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * id) |
1795 | cap->capabilities &= ~V4L2_CAP_TUNER; | 1776 | { |
1777 | struct saa7134_fh *fh = priv; | ||
1778 | struct saa7134_dev *dev = fh->dev; | ||
1779 | unsigned long flags; | ||
1780 | unsigned int i; | ||
1781 | v4l2_std_id fixup; | ||
1796 | 1782 | ||
1797 | return 0; | 1783 | for (i = 0; i < TVNORMS; i++) |
1784 | if (*id == tvnorms[i].id) | ||
1785 | break; | ||
1786 | if (i == TVNORMS) | ||
1787 | for (i = 0; i < TVNORMS; i++) | ||
1788 | if (*id & tvnorms[i].id) | ||
1789 | break; | ||
1790 | if (i == TVNORMS) | ||
1791 | return -EINVAL; | ||
1792 | if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) { | ||
1793 | if (secam[0] == 'L' || secam[0] == 'l') { | ||
1794 | if (secam[1] == 'C' || secam[1] == 'c') | ||
1795 | fixup = V4L2_STD_SECAM_LC; | ||
1796 | else | ||
1797 | fixup = V4L2_STD_SECAM_L; | ||
1798 | } else { | ||
1799 | if (secam[0] == 'D' || secam[0] == 'd') | ||
1800 | fixup = V4L2_STD_SECAM_DK; | ||
1801 | else | ||
1802 | fixup = V4L2_STD_SECAM; | ||
1803 | } | ||
1804 | for (i = 0; i < TVNORMS; i++) | ||
1805 | if (fixup == tvnorms[i].id) | ||
1806 | break; | ||
1798 | } | 1807 | } |
1808 | mutex_lock(&dev->lock); | ||
1809 | if (res_check(fh, RESOURCE_OVERLAY)) { | ||
1810 | spin_lock_irqsave(&dev->slock, flags); | ||
1811 | stop_preview(dev, fh); | ||
1812 | spin_unlock_irqrestore(&dev->slock, flags); | ||
1813 | |||
1814 | set_tvnorm(dev, &tvnorms[i]); | ||
1815 | |||
1816 | spin_lock_irqsave(&dev->slock, flags); | ||
1817 | start_preview(dev, fh); | ||
1818 | spin_unlock_irqrestore(&dev->slock, flags); | ||
1819 | } else | ||
1820 | set_tvnorm(dev, &tvnorms[i]); | ||
1821 | saa7134_tvaudio_do_scan(dev); | ||
1822 | mutex_unlock(&dev->lock); | ||
1823 | return 0; | ||
1824 | } | ||
1799 | 1825 | ||
1800 | /* --- tv standards ------------------------------------------ */ | 1826 | static int vidioc_cropcap(struct file *file, void *priv, |
1801 | case VIDIOC_ENUMSTD: | 1827 | struct v4l2_cropcap *cap) |
1802 | { | 1828 | { |
1803 | struct v4l2_standard *e = arg; | 1829 | struct saa7134_fh *fh = priv; |
1804 | unsigned int i; | 1830 | struct saa7134_dev *dev = fh->dev; |
1805 | 1831 | ||
1806 | i = e->index; | 1832 | if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && |
1807 | if (i >= TVNORMS) | 1833 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
1808 | return -EINVAL; | 1834 | return -EINVAL; |
1809 | err = v4l2_video_std_construct(e, tvnorms[e->index].id, | 1835 | cap->bounds = dev->crop_bounds; |
1810 | tvnorms[e->index].name); | 1836 | cap->defrect = dev->crop_defrect; |
1811 | e->index = i; | 1837 | cap->pixelaspect.numerator = 1; |
1812 | if (err < 0) | 1838 | cap->pixelaspect.denominator = 1; |
1813 | return err; | 1839 | if (dev->tvnorm->id & V4L2_STD_525_60) { |
1814 | return 0; | 1840 | cap->pixelaspect.numerator = 11; |
1841 | cap->pixelaspect.denominator = 10; | ||
1842 | } | ||
1843 | if (dev->tvnorm->id & V4L2_STD_625_50) { | ||
1844 | cap->pixelaspect.numerator = 54; | ||
1845 | cap->pixelaspect.denominator = 59; | ||
1815 | } | 1846 | } |
1816 | case VIDIOC_G_STD: | 1847 | return 0; |
1817 | { | 1848 | } |
1818 | v4l2_std_id *id = arg; | ||
1819 | 1849 | ||
1820 | *id = dev->tvnorm->id; | 1850 | static int vidioc_g_tuner(struct file *file, void *priv, |
1821 | return 0; | 1851 | struct v4l2_tuner *t) |
1822 | } | 1852 | { |
1823 | case VIDIOC_S_STD: | 1853 | struct saa7134_fh *fh = priv; |
1824 | { | 1854 | struct saa7134_dev *dev = fh->dev; |
1825 | v4l2_std_id *id = arg; | 1855 | int n; |
1826 | unsigned int i; | ||
1827 | v4l2_std_id fixup; | ||
1828 | 1856 | ||
1829 | for (i = 0; i < TVNORMS; i++) | 1857 | if (0 != t->index) |
1830 | if (*id == tvnorms[i].id) | 1858 | return -EINVAL; |
1831 | break; | 1859 | memset(t, 0, sizeof(*t)); |
1832 | if (i == TVNORMS) | 1860 | for (n = 0; n < SAA7134_INPUT_MAX; n++) |
1833 | for (i = 0; i < TVNORMS; i++) | 1861 | if (card_in(dev, n).tv) |
1834 | if (*id & tvnorms[i].id) | 1862 | break; |
1835 | break; | 1863 | if (NULL != card_in(dev, n).name) { |
1836 | if (i == TVNORMS) | 1864 | strcpy(t->name, "Television"); |
1837 | return -EINVAL; | 1865 | t->type = V4L2_TUNER_ANALOG_TV; |
1838 | if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) { | 1866 | t->capability = V4L2_TUNER_CAP_NORM | |
1839 | if (secam[0] == 'L' || secam[0] == 'l') { | 1867 | V4L2_TUNER_CAP_STEREO | |
1840 | if (secam[1] == 'C' || secam[1] == 'c') | 1868 | V4L2_TUNER_CAP_LANG1 | |
1841 | fixup = V4L2_STD_SECAM_LC; | 1869 | V4L2_TUNER_CAP_LANG2; |
1842 | else | 1870 | t->rangehigh = 0xffffffffUL; |
1843 | fixup = V4L2_STD_SECAM_L; | 1871 | t->rxsubchans = saa7134_tvaudio_getstereo(dev); |
1844 | } else { | 1872 | t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans); |
1845 | if (secam[0] == 'D' || secam[0] == 'd') | 1873 | } |
1846 | fixup = V4L2_STD_SECAM_DK; | 1874 | if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03)) |
1847 | else | 1875 | t->signal = 0xffff; |
1848 | fixup = V4L2_STD_SECAM; | 1876 | return 0; |
1849 | } | 1877 | } |
1850 | for (i = 0; i < TVNORMS; i++) | ||
1851 | if (fixup == tvnorms[i].id) | ||
1852 | break; | ||
1853 | } | ||
1854 | mutex_lock(&dev->lock); | ||
1855 | if (res_check(fh, RESOURCE_OVERLAY)) { | ||
1856 | spin_lock_irqsave(&dev->slock,flags); | ||
1857 | stop_preview(dev,fh); | ||
1858 | spin_unlock_irqrestore(&dev->slock, flags); | ||
1859 | 1878 | ||
1860 | set_tvnorm(dev,&tvnorms[i]); | 1879 | static int vidioc_s_tuner(struct file *file, void *priv, |
1880 | struct v4l2_tuner *t) | ||
1881 | { | ||
1882 | struct saa7134_fh *fh = priv; | ||
1883 | struct saa7134_dev *dev = fh->dev; | ||
1884 | int rx, mode; | ||
1861 | 1885 | ||
1862 | spin_lock_irqsave(&dev->slock, flags); | 1886 | mode = dev->thread.mode; |
1863 | start_preview(dev,fh); | 1887 | if (UNSET == mode) { |
1864 | spin_unlock_irqrestore(&dev->slock,flags); | 1888 | rx = saa7134_tvaudio_getstereo(dev); |
1865 | } else | 1889 | mode = saa7134_tvaudio_rx2mode(t->rxsubchans); |
1866 | set_tvnorm(dev,&tvnorms[i]); | ||
1867 | saa7134_tvaudio_do_scan(dev); | ||
1868 | mutex_unlock(&dev->lock); | ||
1869 | return 0; | ||
1870 | } | 1890 | } |
1891 | if (mode != t->audmode) | ||
1892 | dev->thread.mode = t->audmode; | ||
1893 | return 0; | ||
1894 | } | ||
1871 | 1895 | ||
1872 | case VIDIOC_CROPCAP: | 1896 | static int vidioc_g_frequency(struct file *file, void *priv, |
1873 | { | 1897 | struct v4l2_frequency *f) |
1874 | struct v4l2_cropcap *cap = arg; | 1898 | { |
1899 | struct saa7134_fh *fh = priv; | ||
1900 | struct saa7134_dev *dev = fh->dev; | ||
1875 | 1901 | ||
1876 | if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | 1902 | memset(f, 0, sizeof(*f)); |
1877 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 1903 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
1878 | return -EINVAL; | 1904 | f->frequency = dev->ctl_freq; |
1879 | cap->bounds = dev->crop_bounds; | 1905 | return 0; |
1880 | cap->defrect = dev->crop_defrect; | 1906 | } |
1881 | cap->pixelaspect.numerator = 1; | ||
1882 | cap->pixelaspect.denominator = 1; | ||
1883 | if (dev->tvnorm->id & V4L2_STD_525_60) { | ||
1884 | cap->pixelaspect.numerator = 11; | ||
1885 | cap->pixelaspect.denominator = 10; | ||
1886 | } | ||
1887 | if (dev->tvnorm->id & V4L2_STD_625_50) { | ||
1888 | cap->pixelaspect.numerator = 54; | ||
1889 | cap->pixelaspect.denominator = 59; | ||
1890 | } | ||
1891 | return 0; | ||
1892 | } | ||
1893 | 1907 | ||
1894 | case VIDIOC_G_CROP: | 1908 | static int vidioc_s_frequency(struct file *file, void *priv, |
1895 | { | 1909 | struct v4l2_frequency *f) |
1896 | struct v4l2_crop * crop = arg; | 1910 | { |
1911 | struct saa7134_fh *fh = priv; | ||
1912 | struct saa7134_dev *dev = fh->dev; | ||
1897 | 1913 | ||
1898 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | 1914 | if (0 != f->tuner) |
1899 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 1915 | return -EINVAL; |
1900 | return -EINVAL; | 1916 | if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type) |
1901 | crop->c = dev->crop_current; | 1917 | return -EINVAL; |
1902 | return 0; | 1918 | if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) |
1903 | } | 1919 | return -EINVAL; |
1904 | case VIDIOC_S_CROP: | 1920 | mutex_lock(&dev->lock); |
1905 | { | 1921 | dev->ctl_freq = f->frequency; |
1906 | struct v4l2_crop *crop = arg; | ||
1907 | struct v4l2_rect *b = &dev->crop_bounds; | ||
1908 | 1922 | ||
1909 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | 1923 | saa7134_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); |
1910 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | ||
1911 | return -EINVAL; | ||
1912 | if (crop->c.height < 0) | ||
1913 | return -EINVAL; | ||
1914 | if (crop->c.width < 0) | ||
1915 | return -EINVAL; | ||
1916 | 1924 | ||
1917 | if (res_locked(fh->dev,RESOURCE_OVERLAY)) | 1925 | saa7134_tvaudio_do_scan(dev); |
1918 | return -EBUSY; | 1926 | mutex_unlock(&dev->lock); |
1919 | if (res_locked(fh->dev,RESOURCE_VIDEO)) | 1927 | return 0; |
1920 | return -EBUSY; | 1928 | } |
1921 | 1929 | ||
1922 | if (crop->c.top < b->top) | 1930 | static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) |
1923 | crop->c.top = b->top; | 1931 | { |
1924 | if (crop->c.top > b->top + b->height) | 1932 | memset(a, 0, sizeof(*a)); |
1925 | crop->c.top = b->top + b->height; | 1933 | strcpy(a->name, "audio"); |
1926 | if (crop->c.height > b->top - crop->c.top + b->height) | 1934 | return 0; |
1927 | crop->c.height = b->top - crop->c.top + b->height; | 1935 | } |
1928 | |||
1929 | if (crop->c.left < b->left) | ||
1930 | crop->c.left = b->left; | ||
1931 | if (crop->c.left > b->left + b->width) | ||
1932 | crop->c.left = b->left + b->width; | ||
1933 | if (crop->c.width > b->left - crop->c.left + b->width) | ||
1934 | crop->c.width = b->left - crop->c.left + b->width; | ||
1935 | |||
1936 | dev->crop_current = crop->c; | ||
1937 | return 0; | ||
1938 | } | ||
1939 | 1936 | ||
1940 | /* --- tuner ioctls ------------------------------------------ */ | 1937 | static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) |
1941 | case VIDIOC_G_TUNER: | 1938 | { |
1942 | { | 1939 | return 0; |
1943 | struct v4l2_tuner *t = arg; | 1940 | } |
1944 | int n; | ||
1945 | 1941 | ||
1946 | if (0 != t->index) | 1942 | static int vidioc_streamon(struct file *file, void *priv, |
1947 | return -EINVAL; | 1943 | enum v4l2_buf_type type) |
1948 | memset(t,0,sizeof(*t)); | 1944 | { |
1949 | for (n = 0; n < SAA7134_INPUT_MAX; n++) | 1945 | struct saa7134_fh *fh = priv; |
1950 | if (card_in(dev,n).tv) | 1946 | struct saa7134_dev *dev = fh->dev; |
1951 | break; | 1947 | int res = saa7134_resource(fh); |
1952 | if (NULL != card_in(dev,n).name) { | ||
1953 | strcpy(t->name, "Television"); | ||
1954 | t->type = V4L2_TUNER_ANALOG_TV; | ||
1955 | t->capability = V4L2_TUNER_CAP_NORM | | ||
1956 | V4L2_TUNER_CAP_STEREO | | ||
1957 | V4L2_TUNER_CAP_LANG1 | | ||
1958 | V4L2_TUNER_CAP_LANG2; | ||
1959 | t->rangehigh = 0xffffffffUL; | ||
1960 | t->rxsubchans = saa7134_tvaudio_getstereo(dev); | ||
1961 | t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans); | ||
1962 | } | ||
1963 | if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03)) | ||
1964 | t->signal = 0xffff; | ||
1965 | return 0; | ||
1966 | } | ||
1967 | case VIDIOC_S_TUNER: | ||
1968 | { | ||
1969 | struct v4l2_tuner *t = arg; | ||
1970 | int rx,mode; | ||
1971 | 1948 | ||
1972 | mode = dev->thread.mode; | 1949 | if (!res_get(dev, fh, res)) |
1973 | if (UNSET == mode) { | 1950 | return -EBUSY; |
1974 | rx = saa7134_tvaudio_getstereo(dev); | ||
1975 | mode = saa7134_tvaudio_rx2mode(t->rxsubchans); | ||
1976 | } | ||
1977 | if (mode != t->audmode) { | ||
1978 | dev->thread.mode = t->audmode; | ||
1979 | } | ||
1980 | return 0; | ||
1981 | } | ||
1982 | case VIDIOC_G_FREQUENCY: | ||
1983 | { | ||
1984 | struct v4l2_frequency *f = arg; | ||
1985 | 1951 | ||
1986 | memset(f,0,sizeof(*f)); | 1952 | return videobuf_streamon(saa7134_queue(fh)); |
1987 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1953 | } |
1988 | f->frequency = dev->ctl_freq; | ||
1989 | return 0; | ||
1990 | } | ||
1991 | case VIDIOC_S_FREQUENCY: | ||
1992 | { | ||
1993 | struct v4l2_frequency *f = arg; | ||
1994 | 1954 | ||
1995 | if (0 != f->tuner) | 1955 | static int vidioc_streamoff(struct file *file, void *priv, |
1996 | return -EINVAL; | 1956 | enum v4l2_buf_type type) |
1997 | if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type) | 1957 | { |
1998 | return -EINVAL; | 1958 | int err; |
1999 | if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) | 1959 | struct saa7134_fh *fh = priv; |
2000 | return -EINVAL; | 1960 | struct saa7134_dev *dev = fh->dev; |
2001 | mutex_lock(&dev->lock); | 1961 | int res = saa7134_resource(fh); |
2002 | dev->ctl_freq = f->frequency; | ||
2003 | 1962 | ||
2004 | saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); | 1963 | err = videobuf_streamoff(saa7134_queue(fh)); |
1964 | if (err < 0) | ||
1965 | return err; | ||
1966 | res_free(dev, fh, res); | ||
1967 | return 0; | ||
1968 | } | ||
2005 | 1969 | ||
2006 | saa7134_tvaudio_do_scan(dev); | 1970 | static int vidioc_reqbufs(struct file *file, void *priv, |
2007 | mutex_unlock(&dev->lock); | 1971 | struct v4l2_requestbuffers *p) |
2008 | return 0; | 1972 | { |
2009 | } | 1973 | struct saa7134_fh *fh = priv; |
1974 | return videobuf_reqbufs(saa7134_queue(fh), p); | ||
1975 | } | ||
2010 | 1976 | ||
2011 | /* --- control ioctls ---------------------------------------- */ | 1977 | static int vidioc_s_crop(struct file *file, void *f, struct v4l2_crop *crop) |
2012 | case VIDIOC_ENUMINPUT: | 1978 | { |
2013 | case VIDIOC_G_INPUT: | 1979 | struct saa7134_fh *fh = f; |
2014 | case VIDIOC_S_INPUT: | 1980 | struct saa7134_dev *dev = fh->dev; |
2015 | case VIDIOC_QUERYCTRL: | 1981 | struct v4l2_rect *b = &dev->crop_bounds; |
2016 | case VIDIOC_G_CTRL: | ||
2017 | case VIDIOC_S_CTRL: | ||
2018 | return saa7134_common_ioctl(dev, cmd, arg); | ||
2019 | 1982 | ||
2020 | case VIDIOC_G_AUDIO: | 1983 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && |
2021 | { | 1984 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
2022 | struct v4l2_audio *a = arg; | 1985 | return -EINVAL; |
1986 | if (crop->c.height < 0) | ||
1987 | return -EINVAL; | ||
1988 | if (crop->c.width < 0) | ||
1989 | return -EINVAL; | ||
2023 | 1990 | ||
2024 | memset(a,0,sizeof(*a)); | 1991 | if (res_locked(fh->dev, RESOURCE_OVERLAY)) |
2025 | strcpy(a->name,"audio"); | 1992 | return -EBUSY; |
2026 | return 0; | 1993 | if (res_locked(fh->dev, RESOURCE_VIDEO)) |
2027 | } | 1994 | return -EBUSY; |
2028 | case VIDIOC_S_AUDIO: | 1995 | |
2029 | return 0; | 1996 | if (crop->c.top < b->top) |
2030 | case VIDIOC_G_PARM: | 1997 | crop->c.top = b->top; |
2031 | { | 1998 | if (crop->c.top > b->top + b->height) |
2032 | struct v4l2_captureparm *parm = arg; | 1999 | crop->c.top = b->top + b->height; |
2033 | memset(parm,0,sizeof(*parm)); | 2000 | if (crop->c.height > b->top - crop->c.top + b->height) |
2034 | return 0; | 2001 | crop->c.height = b->top - crop->c.top + b->height; |
2035 | } | 2002 | |
2003 | if (crop->c.left < b->left) | ||
2004 | crop->c.left = b->left; | ||
2005 | if (crop->c.left > b->left + b->width) | ||
2006 | crop->c.left = b->left + b->width; | ||
2007 | if (crop->c.width > b->left - crop->c.left + b->width) | ||
2008 | crop->c.width = b->left - crop->c.left + b->width; | ||
2009 | |||
2010 | dev->crop_current = crop->c; | ||
2011 | return 0; | ||
2012 | } | ||
2036 | 2013 | ||
2037 | case VIDIOC_G_PRIORITY: | 2014 | static int vidioc_g_crop(struct file *file, void *f, struct v4l2_crop *crop) |
2038 | { | 2015 | { |
2039 | enum v4l2_priority *p = arg; | 2016 | struct saa7134_fh *fh = f; |
2017 | struct saa7134_dev *dev = fh->dev; | ||
2040 | 2018 | ||
2041 | *p = v4l2_prio_max(&dev->prio); | 2019 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && |
2042 | return 0; | 2020 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
2043 | } | 2021 | return -EINVAL; |
2044 | case VIDIOC_S_PRIORITY: | 2022 | crop->c = dev->crop_current; |
2045 | { | 2023 | return 0; |
2046 | enum v4l2_priority *prio = arg; | 2024 | } |
2047 | 2025 | ||
2048 | return v4l2_prio_change(&dev->prio, &fh->prio, *prio); | 2026 | static int vidioc_g_parm(struct file *file, void *fh, |
2049 | } | 2027 | struct v4l2_streamparm *parm) |
2028 | { | ||
2029 | memset(parm, 0, sizeof(*parm)); | ||
2030 | return 0; | ||
2031 | } | ||
2050 | 2032 | ||
2051 | /* --- preview ioctls ---------------------------------------- */ | 2033 | static int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p) |
2052 | case VIDIOC_ENUM_FMT: | 2034 | { |
2053 | { | 2035 | struct saa7134_fh *fh = f; |
2054 | struct v4l2_fmtdesc *f = arg; | 2036 | struct saa7134_dev *dev = fh->dev; |
2055 | enum v4l2_buf_type type; | ||
2056 | unsigned int index; | ||
2057 | |||
2058 | index = f->index; | ||
2059 | type = f->type; | ||
2060 | switch (type) { | ||
2061 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
2062 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
2063 | if (saa7134_no_overlay > 0) { | ||
2064 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | ||
2065 | return -EINVAL; | ||
2066 | } | ||
2067 | if (index >= FORMATS) | ||
2068 | return -EINVAL; | ||
2069 | if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY && | ||
2070 | formats[index].planar) | ||
2071 | return -EINVAL; | ||
2072 | memset(f,0,sizeof(*f)); | ||
2073 | f->index = index; | ||
2074 | f->type = type; | ||
2075 | strlcpy(f->description,formats[index].name,sizeof(f->description)); | ||
2076 | f->pixelformat = formats[index].fourcc; | ||
2077 | break; | ||
2078 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
2079 | if (0 != index) | ||
2080 | return -EINVAL; | ||
2081 | memset(f,0,sizeof(*f)); | ||
2082 | f->index = index; | ||
2083 | f->type = type; | ||
2084 | f->pixelformat = V4L2_PIX_FMT_GREY; | ||
2085 | strcpy(f->description,"vbi data"); | ||
2086 | break; | ||
2087 | default: | ||
2088 | return -EINVAL; | ||
2089 | } | ||
2090 | return 0; | ||
2091 | } | ||
2092 | case VIDIOC_G_FBUF: | ||
2093 | { | ||
2094 | struct v4l2_framebuffer *fb = arg; | ||
2095 | 2037 | ||
2096 | *fb = dev->ovbuf; | 2038 | *p = v4l2_prio_max(&dev->prio); |
2097 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; | 2039 | return 0; |
2098 | return 0; | 2040 | } |
2099 | } | ||
2100 | case VIDIOC_S_FBUF: | ||
2101 | { | ||
2102 | struct v4l2_framebuffer *fb = arg; | ||
2103 | struct saa7134_format *fmt; | ||
2104 | 2041 | ||
2105 | if(!capable(CAP_SYS_ADMIN) && | 2042 | static int vidioc_s_priority(struct file *file, void *f, |
2106 | !capable(CAP_SYS_RAWIO)) | 2043 | enum v4l2_priority prio) |
2107 | return -EPERM; | 2044 | { |
2045 | struct saa7134_fh *fh = f; | ||
2046 | struct saa7134_dev *dev = fh->dev; | ||
2108 | 2047 | ||
2109 | /* check args */ | 2048 | return v4l2_prio_change(&dev->prio, &fh->prio, prio); |
2110 | fmt = format_by_fourcc(fb->fmt.pixelformat); | 2049 | } |
2111 | if (NULL == fmt) | ||
2112 | return -EINVAL; | ||
2113 | 2050 | ||
2114 | /* ok, accept it */ | 2051 | static int vidioc_g_fbuf(struct file *file, void *f, |
2115 | dev->ovbuf = *fb; | 2052 | struct v4l2_framebuffer *fb) |
2116 | dev->ovfmt = fmt; | 2053 | { |
2117 | if (0 == dev->ovbuf.fmt.bytesperline) | 2054 | struct saa7134_fh *fh = f; |
2118 | dev->ovbuf.fmt.bytesperline = | 2055 | struct saa7134_dev *dev = fh->dev; |
2119 | dev->ovbuf.fmt.width*fmt->depth/8; | ||
2120 | return 0; | ||
2121 | } | ||
2122 | case VIDIOC_OVERLAY: | ||
2123 | { | ||
2124 | int *on = arg; | ||
2125 | 2056 | ||
2126 | if (*on) { | 2057 | *fb = dev->ovbuf; |
2127 | if (saa7134_no_overlay > 0) { | 2058 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; |
2128 | printk ("no_overlay\n"); | ||
2129 | return -EINVAL; | ||
2130 | } | ||
2131 | 2059 | ||
2132 | if (!res_get(dev,fh,RESOURCE_OVERLAY)) | 2060 | return 0; |
2133 | return -EBUSY; | 2061 | } |
2134 | spin_lock_irqsave(&dev->slock,flags); | ||
2135 | start_preview(dev,fh); | ||
2136 | spin_unlock_irqrestore(&dev->slock,flags); | ||
2137 | } | ||
2138 | if (!*on) { | ||
2139 | if (!res_check(fh, RESOURCE_OVERLAY)) | ||
2140 | return -EINVAL; | ||
2141 | spin_lock_irqsave(&dev->slock,flags); | ||
2142 | stop_preview(dev,fh); | ||
2143 | spin_unlock_irqrestore(&dev->slock,flags); | ||
2144 | res_free(dev,fh,RESOURCE_OVERLAY); | ||
2145 | } | ||
2146 | return 0; | ||
2147 | } | ||
2148 | 2062 | ||
2149 | /* --- capture ioctls ---------------------------------------- */ | 2063 | static int vidioc_s_fbuf(struct file *file, void *f, |
2150 | case VIDIOC_G_FMT: | 2064 | struct v4l2_framebuffer *fb) |
2151 | { | 2065 | { |
2152 | struct v4l2_format *f = arg; | 2066 | struct saa7134_fh *fh = f; |
2153 | return saa7134_g_fmt(dev,fh,f); | 2067 | struct saa7134_dev *dev = fh->dev; |
2154 | } | 2068 | struct saa7134_format *fmt; |
2155 | case VIDIOC_S_FMT: | 2069 | |
2156 | { | 2070 | if (!capable(CAP_SYS_ADMIN) && |
2157 | struct v4l2_format *f = arg; | 2071 | !capable(CAP_SYS_RAWIO)) |
2158 | return saa7134_s_fmt(dev,fh,f); | 2072 | return -EPERM; |
2159 | } | ||
2160 | case VIDIOC_TRY_FMT: | ||
2161 | { | ||
2162 | struct v4l2_format *f = arg; | ||
2163 | return saa7134_try_fmt(dev,fh,f); | ||
2164 | } | ||
2165 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
2166 | case VIDIOCGMBUF: | ||
2167 | return videobuf_cgmbuf(saa7134_queue(fh), arg, gbuffers); | ||
2168 | #endif | ||
2169 | case VIDIOC_REQBUFS: | ||
2170 | return videobuf_reqbufs(saa7134_queue(fh),arg); | ||
2171 | 2073 | ||
2172 | case VIDIOC_QUERYBUF: | 2074 | /* check args */ |
2173 | return videobuf_querybuf(saa7134_queue(fh),arg); | 2075 | fmt = format_by_fourcc(fb->fmt.pixelformat); |
2076 | if (NULL == fmt) | ||
2077 | return -EINVAL; | ||
2174 | 2078 | ||
2175 | case VIDIOC_QBUF: | 2079 | /* ok, accept it */ |
2176 | return videobuf_qbuf(saa7134_queue(fh),arg); | 2080 | dev->ovbuf = *fb; |
2081 | dev->ovfmt = fmt; | ||
2082 | if (0 == dev->ovbuf.fmt.bytesperline) | ||
2083 | dev->ovbuf.fmt.bytesperline = | ||
2084 | dev->ovbuf.fmt.width*fmt->depth/8; | ||
2085 | return 0; | ||
2086 | } | ||
2177 | 2087 | ||
2178 | case VIDIOC_DQBUF: | 2088 | static int vidioc_querybuf(struct file *file, void *priv, |
2179 | return videobuf_dqbuf(saa7134_queue(fh),arg, | 2089 | struct v4l2_buffer *b) |
2180 | file->f_flags & O_NONBLOCK); | 2090 | { |
2091 | struct saa7134_fh *fh = priv; | ||
2092 | return videobuf_querybuf(saa7134_queue(fh), b); | ||
2093 | } | ||
2181 | 2094 | ||
2182 | case VIDIOC_STREAMON: | 2095 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) |
2183 | { | 2096 | { |
2184 | int res = saa7134_resource(fh); | 2097 | struct saa7134_fh *fh = priv; |
2098 | return videobuf_qbuf(saa7134_queue(fh), b); | ||
2099 | } | ||
2100 | |||
2101 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | ||
2102 | { | ||
2103 | struct saa7134_fh *fh = priv; | ||
2104 | return videobuf_dqbuf(saa7134_queue(fh), b, | ||
2105 | file->f_flags & O_NONBLOCK); | ||
2106 | } | ||
2107 | |||
2108 | static int vidioc_overlay(struct file *file, void *f, unsigned int on) | ||
2109 | { | ||
2110 | struct saa7134_fh *fh = f; | ||
2111 | struct saa7134_dev *dev = fh->dev; | ||
2112 | unsigned long flags; | ||
2185 | 2113 | ||
2186 | if (!res_get(dev,fh,res)) | 2114 | if (on) { |
2115 | if (saa7134_no_overlay > 0) { | ||
2116 | dprintk("no_overlay\n"); | ||
2117 | return -EINVAL; | ||
2118 | } | ||
2119 | |||
2120 | if (!res_get(dev, fh, RESOURCE_OVERLAY)) | ||
2187 | return -EBUSY; | 2121 | return -EBUSY; |
2188 | return videobuf_streamon(saa7134_queue(fh)); | 2122 | spin_lock_irqsave(&dev->slock, flags); |
2123 | start_preview(dev, fh); | ||
2124 | spin_unlock_irqrestore(&dev->slock, flags); | ||
2189 | } | 2125 | } |
2190 | case VIDIOC_STREAMOFF: | 2126 | if (!on) { |
2191 | { | 2127 | if (!res_check(fh, RESOURCE_OVERLAY)) |
2192 | int res = saa7134_resource(fh); | 2128 | return -EINVAL; |
2193 | 2129 | spin_lock_irqsave(&dev->slock, flags); | |
2194 | err = videobuf_streamoff(saa7134_queue(fh)); | 2130 | stop_preview(dev, fh); |
2195 | if (err < 0) | 2131 | spin_unlock_irqrestore(&dev->slock, flags); |
2196 | return err; | 2132 | res_free(dev, fh, RESOURCE_OVERLAY); |
2197 | res_free(dev,fh,res); | ||
2198 | return 0; | ||
2199 | } | 2133 | } |
2134 | return 0; | ||
2135 | } | ||
2136 | |||
2137 | static int vidioc_enum_fmt_cap(struct file *file, void *priv, | ||
2138 | struct v4l2_fmtdesc *f) | ||
2139 | { | ||
2140 | enum v4l2_buf_type type; | ||
2141 | unsigned int index; | ||
2200 | 2142 | ||
2143 | index = f->index; | ||
2144 | type = f->type; | ||
2145 | switch (type) { | ||
2146 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
2147 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
2148 | if (saa7134_no_overlay > 0) | ||
2149 | return -EINVAL; | ||
2150 | |||
2151 | if (index >= FORMATS) | ||
2152 | return -EINVAL; | ||
2153 | |||
2154 | if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY && | ||
2155 | formats[index].planar) | ||
2156 | return -EINVAL; | ||
2157 | memset(f, 0, sizeof(*f)); | ||
2158 | f->index = index; | ||
2159 | f->type = type; | ||
2160 | strlcpy(f->description, formats[index].name, | ||
2161 | sizeof(f->description)); | ||
2162 | f->pixelformat = formats[index].fourcc; | ||
2163 | break; | ||
2164 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
2165 | if (0 != index) | ||
2166 | return -EINVAL; | ||
2167 | memset(f, 0, sizeof(*f)); | ||
2168 | f->index = index; | ||
2169 | f->type = type; | ||
2170 | f->pixelformat = V4L2_PIX_FMT_GREY; | ||
2171 | strcpy(f->description, "vbi data"); | ||
2172 | break; | ||
2201 | default: | 2173 | default: |
2202 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | 2174 | return -EINVAL; |
2203 | video_do_ioctl); | ||
2204 | } | 2175 | } |
2205 | return 0; | 2176 | return 0; |
2206 | } | 2177 | } |
2207 | 2178 | ||
2208 | static int video_ioctl(struct inode *inode, struct file *file, | 2179 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
2209 | unsigned int cmd, unsigned long arg) | 2180 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) |
2210 | { | 2181 | { |
2211 | return video_usercopy(inode, file, cmd, arg, video_do_ioctl); | 2182 | struct saa7134_fh *fh = file->private_data; |
2183 | return videobuf_cgmbuf(saa7134_queue(fh), mbuf, 8); | ||
2212 | } | 2184 | } |
2185 | #endif | ||
2213 | 2186 | ||
2214 | static int radio_do_ioctl(struct inode *inode, struct file *file, | 2187 | static int radio_querycap(struct file *file, void *priv, |
2215 | unsigned int cmd, void *arg) | 2188 | struct v4l2_capability *cap) |
2216 | { | 2189 | { |
2217 | struct saa7134_fh *fh = file->private_data; | 2190 | struct saa7134_fh *fh = file->private_data; |
2218 | struct saa7134_dev *dev = fh->dev; | 2191 | struct saa7134_dev *dev = fh->dev; |
2219 | 2192 | ||
2220 | if (video_debug > 1) | 2193 | memset(cap, 0, sizeof(*cap)); |
2221 | v4l_print_ioctl(dev->name,cmd); | 2194 | strcpy(cap->driver, "saa7134"); |
2222 | switch (cmd) { | 2195 | strlcpy(cap->card, saa7134_boards[dev->board].name, sizeof(cap->card)); |
2223 | case VIDIOC_QUERYCAP: | 2196 | sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); |
2224 | { | 2197 | cap->version = SAA7134_VERSION_CODE; |
2225 | struct v4l2_capability *cap = arg; | 2198 | cap->capabilities = V4L2_CAP_TUNER; |
2226 | 2199 | return 0; | |
2227 | memset(cap,0,sizeof(*cap)); | 2200 | } |
2228 | strcpy(cap->driver, "saa7134"); | ||
2229 | strlcpy(cap->card, saa7134_boards[dev->board].name, | ||
2230 | sizeof(cap->card)); | ||
2231 | sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); | ||
2232 | cap->version = SAA7134_VERSION_CODE; | ||
2233 | cap->capabilities = V4L2_CAP_TUNER; | ||
2234 | return 0; | ||
2235 | } | ||
2236 | case VIDIOC_G_TUNER: | ||
2237 | { | ||
2238 | struct v4l2_tuner *t = arg; | ||
2239 | 2201 | ||
2240 | if (0 != t->index) | 2202 | static int radio_g_tuner(struct file *file, void *priv, |
2241 | return -EINVAL; | 2203 | struct v4l2_tuner *t) |
2204 | { | ||
2205 | struct saa7134_fh *fh = file->private_data; | ||
2206 | struct saa7134_dev *dev = fh->dev; | ||
2242 | 2207 | ||
2243 | memset(t,0,sizeof(*t)); | 2208 | if (0 != t->index) |
2244 | strcpy(t->name, "Radio"); | 2209 | return -EINVAL; |
2245 | t->type = V4L2_TUNER_RADIO; | ||
2246 | 2210 | ||
2247 | saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); | 2211 | memset(t, 0, sizeof(*t)); |
2248 | if (dev->input->amux == TV) { | 2212 | strcpy(t->name, "Radio"); |
2249 | t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11); | 2213 | t->type = V4L2_TUNER_RADIO; |
2250 | t->rxsubchans = (saa_readb(0x529) & 0x08) ? | 2214 | |
2251 | V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; | 2215 | saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); |
2252 | } | 2216 | if (dev->input->amux == TV) { |
2253 | return 0; | 2217 | t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11); |
2218 | t->rxsubchans = (saa_readb(0x529) & 0x08) ? | ||
2219 | V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; | ||
2254 | } | 2220 | } |
2255 | case VIDIOC_S_TUNER: | 2221 | return 0; |
2256 | { | 2222 | } |
2257 | struct v4l2_tuner *t = arg; | 2223 | static int radio_s_tuner(struct file *file, void *priv, |
2224 | struct v4l2_tuner *t) | ||
2225 | { | ||
2226 | struct saa7134_fh *fh = file->private_data; | ||
2227 | struct saa7134_dev *dev = fh->dev; | ||
2258 | 2228 | ||
2259 | if (0 != t->index) | 2229 | if (0 != t->index) |
2260 | return -EINVAL; | 2230 | return -EINVAL; |
2231 | |||
2232 | saa7134_i2c_call_clients(dev, VIDIOC_S_TUNER, t); | ||
2233 | return 0; | ||
2234 | } | ||
2261 | 2235 | ||
2262 | saa7134_i2c_call_clients(dev,VIDIOC_S_TUNER,t); | 2236 | static int radio_enum_input(struct file *file, void *priv, |
2237 | struct v4l2_input *i) | ||
2238 | { | ||
2239 | if (i->index != 0) | ||
2240 | return -EINVAL; | ||
2263 | 2241 | ||
2264 | return 0; | 2242 | strcpy(i->name, "Radio"); |
2265 | } | 2243 | i->type = V4L2_INPUT_TYPE_TUNER; |
2266 | case VIDIOC_ENUMINPUT: | ||
2267 | { | ||
2268 | struct v4l2_input *i = arg; | ||
2269 | 2244 | ||
2270 | if (i->index != 0) | 2245 | return 0; |
2271 | return -EINVAL; | 2246 | } |
2272 | strcpy(i->name,"Radio"); | ||
2273 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
2274 | return 0; | ||
2275 | } | ||
2276 | case VIDIOC_G_INPUT: | ||
2277 | { | ||
2278 | int *i = arg; | ||
2279 | *i = 0; | ||
2280 | return 0; | ||
2281 | } | ||
2282 | case VIDIOC_G_AUDIO: | ||
2283 | { | ||
2284 | struct v4l2_audio *a = arg; | ||
2285 | 2247 | ||
2286 | memset(a,0,sizeof(*a)); | 2248 | static int radio_g_input(struct file *filp, void *priv, unsigned int *i) |
2287 | strcpy(a->name,"Radio"); | 2249 | { |
2288 | return 0; | 2250 | *i = 0; |
2289 | } | 2251 | return 0; |
2290 | case VIDIOC_G_STD: | 2252 | } |
2291 | { | ||
2292 | v4l2_std_id *id = arg; | ||
2293 | *id = 0; | ||
2294 | return 0; | ||
2295 | } | ||
2296 | case VIDIOC_S_AUDIO: | ||
2297 | case VIDIOC_S_INPUT: | ||
2298 | case VIDIOC_S_STD: | ||
2299 | return 0; | ||
2300 | 2253 | ||
2301 | case VIDIOC_QUERYCTRL: | 2254 | static int radio_g_audio(struct file *file, void *priv, |
2302 | { | 2255 | struct v4l2_audio *a) |
2303 | const struct v4l2_queryctrl *ctrl; | 2256 | { |
2304 | struct v4l2_queryctrl *c = arg; | 2257 | memset(a, 0, sizeof(*a)); |
2258 | strcpy(a->name, "Radio"); | ||
2259 | return 0; | ||
2260 | } | ||
2305 | 2261 | ||
2306 | if (c->id < V4L2_CID_BASE || | 2262 | static int radio_s_audio(struct file *file, void *priv, |
2307 | c->id >= V4L2_CID_LASTP1) | 2263 | struct v4l2_audio *a) |
2308 | return -EINVAL; | 2264 | { |
2309 | if (c->id == V4L2_CID_AUDIO_MUTE) { | 2265 | return 0; |
2310 | ctrl = ctrl_by_id(c->id); | 2266 | } |
2311 | *c = *ctrl; | ||
2312 | } else | ||
2313 | *c = no_ctrl; | ||
2314 | return 0; | ||
2315 | } | ||
2316 | 2267 | ||
2317 | case VIDIOC_G_CTRL: | 2268 | static int radio_s_input(struct file *filp, void *priv, unsigned int i) |
2318 | case VIDIOC_S_CTRL: | 2269 | { |
2319 | case VIDIOC_G_FREQUENCY: | 2270 | return 0; |
2320 | case VIDIOC_S_FREQUENCY: | 2271 | } |
2321 | return video_do_ioctl(inode,file,cmd,arg); | ||
2322 | 2272 | ||
2323 | default: | 2273 | static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm) |
2324 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | 2274 | { |
2325 | radio_do_ioctl); | ||
2326 | } | ||
2327 | return 0; | 2275 | return 0; |
2328 | } | 2276 | } |
2329 | 2277 | ||
2330 | static int radio_ioctl(struct inode *inode, struct file *file, | 2278 | static int radio_queryctrl(struct file *file, void *priv, |
2331 | unsigned int cmd, unsigned long arg) | 2279 | struct v4l2_queryctrl *c) |
2332 | { | 2280 | { |
2333 | return video_usercopy(inode, file, cmd, arg, radio_do_ioctl); | 2281 | const struct v4l2_queryctrl *ctrl; |
2282 | |||
2283 | if (c->id < V4L2_CID_BASE || | ||
2284 | c->id >= V4L2_CID_LASTP1) | ||
2285 | return -EINVAL; | ||
2286 | if (c->id == V4L2_CID_AUDIO_MUTE) { | ||
2287 | ctrl = ctrl_by_id(c->id); | ||
2288 | *c = *ctrl; | ||
2289 | } else | ||
2290 | *c = no_ctrl; | ||
2291 | return 0; | ||
2334 | } | 2292 | } |
2335 | 2293 | ||
2336 | static const struct file_operations video_fops = | 2294 | static const struct file_operations video_fops = |
@@ -2341,7 +2299,7 @@ static const struct file_operations video_fops = | |||
2341 | .read = video_read, | 2299 | .read = video_read, |
2342 | .poll = video_poll, | 2300 | .poll = video_poll, |
2343 | .mmap = video_mmap, | 2301 | .mmap = video_mmap, |
2344 | .ioctl = video_ioctl, | 2302 | .ioctl = video_ioctl2, |
2345 | .compat_ioctl = v4l_compat_ioctl32, | 2303 | .compat_ioctl = v4l_compat_ioctl32, |
2346 | .llseek = no_llseek, | 2304 | .llseek = no_llseek, |
2347 | }; | 2305 | }; |
@@ -2351,7 +2309,7 @@ static const struct file_operations radio_fops = | |||
2351 | .owner = THIS_MODULE, | 2309 | .owner = THIS_MODULE, |
2352 | .open = video_open, | 2310 | .open = video_open, |
2353 | .release = video_release, | 2311 | .release = video_release, |
2354 | .ioctl = radio_ioctl, | 2312 | .ioctl = video_ioctl2, |
2355 | .compat_ioctl = v4l_compat_ioctl32, | 2313 | .compat_ioctl = v4l_compat_ioctl32, |
2356 | .llseek = no_llseek, | 2314 | .llseek = no_llseek, |
2357 | }; | 2315 | }; |
@@ -2361,11 +2319,47 @@ static const struct file_operations radio_fops = | |||
2361 | 2319 | ||
2362 | struct video_device saa7134_video_template = | 2320 | struct video_device saa7134_video_template = |
2363 | { | 2321 | { |
2364 | .name = "saa7134-video", | 2322 | .name = "saa7134-video", |
2365 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| | 2323 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER | |
2366 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, | 2324 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, |
2367 | .fops = &video_fops, | 2325 | .fops = &video_fops, |
2368 | .minor = -1, | 2326 | .minor = -1, |
2327 | .vidioc_querycap = vidioc_querycap, | ||
2328 | .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, | ||
2329 | .vidioc_g_fmt_cap = vidioc_g_fmt_cap, | ||
2330 | .vidioc_try_fmt_cap = vidioc_try_fmt_cap, | ||
2331 | .vidioc_s_fmt_cap = vidioc_s_fmt_cap, | ||
2332 | .vidioc_g_audio = vidioc_g_audio, | ||
2333 | .vidioc_s_audio = vidioc_s_audio, | ||
2334 | .vidioc_cropcap = vidioc_cropcap, | ||
2335 | .vidioc_reqbufs = vidioc_reqbufs, | ||
2336 | .vidioc_querybuf = vidioc_querybuf, | ||
2337 | .vidioc_qbuf = vidioc_qbuf, | ||
2338 | .vidioc_dqbuf = vidioc_dqbuf, | ||
2339 | .vidioc_s_std = vidioc_s_std, | ||
2340 | .vidioc_enum_input = vidioc_enum_input, | ||
2341 | .vidioc_g_input = vidioc_g_input, | ||
2342 | .vidioc_s_input = vidioc_s_input, | ||
2343 | .vidioc_queryctrl = vidioc_queryctrl, | ||
2344 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
2345 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
2346 | .vidioc_streamon = vidioc_streamon, | ||
2347 | .vidioc_streamoff = vidioc_streamoff, | ||
2348 | .vidioc_g_tuner = vidioc_g_tuner, | ||
2349 | .vidioc_s_tuner = vidioc_s_tuner, | ||
2350 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
2351 | .vidiocgmbuf = vidiocgmbuf, | ||
2352 | #endif | ||
2353 | .vidioc_g_crop = vidioc_g_crop, | ||
2354 | .vidioc_s_crop = vidioc_s_crop, | ||
2355 | .vidioc_g_fbuf = vidioc_g_fbuf, | ||
2356 | .vidioc_s_fbuf = vidioc_s_fbuf, | ||
2357 | .vidioc_overlay = vidioc_overlay, | ||
2358 | .vidioc_g_priority = vidioc_g_priority, | ||
2359 | .vidioc_s_priority = vidioc_s_priority, | ||
2360 | .vidioc_g_parm = vidioc_g_parm, | ||
2361 | .vidioc_g_frequency = vidioc_g_frequency, | ||
2362 | .vidioc_s_frequency = vidioc_s_frequency, | ||
2369 | }; | 2363 | }; |
2370 | 2364 | ||
2371 | struct video_device saa7134_vbi_template = | 2365 | struct video_device saa7134_vbi_template = |
@@ -2382,6 +2376,20 @@ struct video_device saa7134_radio_template = | |||
2382 | .type = VID_TYPE_TUNER, | 2376 | .type = VID_TYPE_TUNER, |
2383 | .fops = &radio_fops, | 2377 | .fops = &radio_fops, |
2384 | .minor = -1, | 2378 | .minor = -1, |
2379 | .vidioc_querycap = radio_querycap, | ||
2380 | .vidioc_g_tuner = radio_g_tuner, | ||
2381 | .vidioc_enum_input = radio_enum_input, | ||
2382 | .vidioc_g_audio = radio_g_audio, | ||
2383 | .vidioc_s_tuner = radio_s_tuner, | ||
2384 | .vidioc_s_audio = radio_s_audio, | ||
2385 | .vidioc_s_input = radio_s_input, | ||
2386 | .vidioc_s_std = radio_s_std, | ||
2387 | .vidioc_queryctrl = radio_queryctrl, | ||
2388 | .vidioc_g_input = radio_g_input, | ||
2389 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
2390 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
2391 | .vidioc_g_frequency = vidioc_g_frequency, | ||
2392 | .vidioc_s_frequency = vidioc_s_frequency, | ||
2385 | }; | 2393 | }; |
2386 | 2394 | ||
2387 | int saa7134_video_init1(struct saa7134_dev *dev) | 2395 | int saa7134_video_init1(struct saa7134_dev *dev) |