diff options
author | Douglas Schilling Landgraf <dougsland@gmail.com> | 2007-12-27 20:20:58 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:04:20 -0500 |
commit | 402aa76aa5e57801b4db5ccf8c7beea9f580bb1b (patch) | |
tree | e6575fc05013a8ad0560911d07d678570b063137 /drivers/media/video/bt8xx | |
parent | 4041f1a58774249f5f26163e68b844521ece1fb4 (diff) |
V4L/DVB (6911): Converted bttv to use video_ioctl2
Signed-off-by: Douglas Schilling Landgraf <dougsland@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/bt8xx')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-driver.c | 1971 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-vbi.c | 52 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttvp.h | 11 |
3 files changed, 1103 insertions, 931 deletions
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index e04113f0b7e..d6a305ddc53 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -476,7 +476,7 @@ static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); | |||
476 | /* ----------------------------------------------------------------------- */ | 476 | /* ----------------------------------------------------------------------- */ |
477 | /* bttv format list | 477 | /* bttv format list |
478 | packed pixel formats must come first */ | 478 | packed pixel formats must come first */ |
479 | static const struct bttv_format bttv_formats[] = { | 479 | static const struct bttv_format formats[] = { |
480 | { | 480 | { |
481 | .name = "8 bpp, gray", | 481 | .name = "8 bpp, gray", |
482 | .fourcc = V4L2_PIX_FMT_GREY, | 482 | .fourcc = V4L2_PIX_FMT_GREY, |
@@ -609,7 +609,7 @@ static const struct bttv_format bttv_formats[] = { | |||
609 | .flags = FORMAT_FLAGS_RAW, | 609 | .flags = FORMAT_FLAGS_RAW, |
610 | } | 610 | } |
611 | }; | 611 | }; |
612 | static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats); | 612 | static const unsigned int FORMATS = ARRAY_SIZE(formats); |
613 | 613 | ||
614 | /* ----------------------------------------------------------------------- */ | 614 | /* ----------------------------------------------------------------------- */ |
615 | 615 | ||
@@ -787,6 +787,16 @@ static const struct v4l2_queryctrl bttv_ctls[] = { | |||
787 | }; | 787 | }; |
788 | static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls); | 788 | static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls); |
789 | 789 | ||
790 | static const struct v4l2_queryctrl *ctrl_by_id(int id) | ||
791 | { | ||
792 | int i; | ||
793 | |||
794 | for (i = 0; i < BTTV_CTLS; i++) | ||
795 | if (bttv_ctls[i].id == id) | ||
796 | return bttv_ctls+i; | ||
797 | return NULL; | ||
798 | } | ||
799 | |||
790 | /* ----------------------------------------------------------------------- */ | 800 | /* ----------------------------------------------------------------------- */ |
791 | /* resource management */ | 801 | /* resource management */ |
792 | 802 | ||
@@ -1432,157 +1442,6 @@ static void bttv_reinit_bt848(struct bttv *btv) | |||
1432 | set_input(btv, btv->input, btv->tvnorm); | 1442 | set_input(btv, btv->input, btv->tvnorm); |
1433 | } | 1443 | } |
1434 | 1444 | ||
1435 | static int get_control(struct bttv *btv, struct v4l2_control *c) | ||
1436 | { | ||
1437 | switch (c->id) { | ||
1438 | case V4L2_CID_BRIGHTNESS: | ||
1439 | c->value = btv->bright; | ||
1440 | break; | ||
1441 | case V4L2_CID_HUE: | ||
1442 | c->value = btv->hue; | ||
1443 | break; | ||
1444 | case V4L2_CID_CONTRAST: | ||
1445 | c->value = btv->contrast; | ||
1446 | break; | ||
1447 | case V4L2_CID_SATURATION: | ||
1448 | c->value = btv->saturation; | ||
1449 | break; | ||
1450 | |||
1451 | case V4L2_CID_AUDIO_MUTE: | ||
1452 | case V4L2_CID_AUDIO_VOLUME: | ||
1453 | case V4L2_CID_AUDIO_BALANCE: | ||
1454 | case V4L2_CID_AUDIO_BASS: | ||
1455 | case V4L2_CID_AUDIO_TREBLE: | ||
1456 | bttv_call_i2c_clients(btv,VIDIOC_G_CTRL,c); | ||
1457 | break; | ||
1458 | |||
1459 | case V4L2_CID_PRIVATE_CHROMA_AGC: | ||
1460 | c->value = btv->opt_chroma_agc; | ||
1461 | break; | ||
1462 | case V4L2_CID_PRIVATE_COMBFILTER: | ||
1463 | c->value = btv->opt_combfilter; | ||
1464 | break; | ||
1465 | case V4L2_CID_PRIVATE_LUMAFILTER: | ||
1466 | c->value = btv->opt_lumafilter; | ||
1467 | break; | ||
1468 | case V4L2_CID_PRIVATE_AUTOMUTE: | ||
1469 | c->value = btv->opt_automute; | ||
1470 | break; | ||
1471 | case V4L2_CID_PRIVATE_AGC_CRUSH: | ||
1472 | c->value = btv->opt_adc_crush; | ||
1473 | break; | ||
1474 | case V4L2_CID_PRIVATE_VCR_HACK: | ||
1475 | c->value = btv->opt_vcr_hack; | ||
1476 | break; | ||
1477 | case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: | ||
1478 | c->value = btv->opt_whitecrush_upper; | ||
1479 | break; | ||
1480 | case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: | ||
1481 | c->value = btv->opt_whitecrush_lower; | ||
1482 | break; | ||
1483 | case V4L2_CID_PRIVATE_UV_RATIO: | ||
1484 | c->value = btv->opt_uv_ratio; | ||
1485 | break; | ||
1486 | case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: | ||
1487 | c->value = btv->opt_full_luma_range; | ||
1488 | break; | ||
1489 | case V4L2_CID_PRIVATE_CORING: | ||
1490 | c->value = btv->opt_coring; | ||
1491 | break; | ||
1492 | default: | ||
1493 | return -EINVAL; | ||
1494 | } | ||
1495 | return 0; | ||
1496 | } | ||
1497 | |||
1498 | static int set_control(struct bttv *btv, struct v4l2_control *c) | ||
1499 | { | ||
1500 | int val; | ||
1501 | |||
1502 | switch (c->id) { | ||
1503 | case V4L2_CID_BRIGHTNESS: | ||
1504 | bt848_bright(btv,c->value); | ||
1505 | break; | ||
1506 | case V4L2_CID_HUE: | ||
1507 | bt848_hue(btv,c->value); | ||
1508 | break; | ||
1509 | case V4L2_CID_CONTRAST: | ||
1510 | bt848_contrast(btv,c->value); | ||
1511 | break; | ||
1512 | case V4L2_CID_SATURATION: | ||
1513 | bt848_sat(btv,c->value); | ||
1514 | break; | ||
1515 | case V4L2_CID_AUDIO_MUTE: | ||
1516 | audio_mute(btv, c->value); | ||
1517 | /* fall through */ | ||
1518 | case V4L2_CID_AUDIO_VOLUME: | ||
1519 | if (btv->volume_gpio) { | ||
1520 | btv->volume_gpio (btv, c->value); | ||
1521 | } | ||
1522 | bttv_call_i2c_clients(btv,VIDIOC_S_CTRL,c); | ||
1523 | break; | ||
1524 | case V4L2_CID_AUDIO_BALANCE: | ||
1525 | case V4L2_CID_AUDIO_BASS: | ||
1526 | case V4L2_CID_AUDIO_TREBLE: | ||
1527 | bttv_call_i2c_clients(btv,VIDIOC_S_CTRL,c); | ||
1528 | break; | ||
1529 | |||
1530 | case V4L2_CID_PRIVATE_CHROMA_AGC: | ||
1531 | btv->opt_chroma_agc = c->value; | ||
1532 | val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; | ||
1533 | btwrite(val, BT848_E_SCLOOP); | ||
1534 | btwrite(val, BT848_O_SCLOOP); | ||
1535 | break; | ||
1536 | case V4L2_CID_PRIVATE_COMBFILTER: | ||
1537 | btv->opt_combfilter = c->value; | ||
1538 | break; | ||
1539 | case V4L2_CID_PRIVATE_LUMAFILTER: | ||
1540 | btv->opt_lumafilter = c->value; | ||
1541 | if (btv->opt_lumafilter) { | ||
1542 | btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL); | ||
1543 | btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL); | ||
1544 | } else { | ||
1545 | btor(BT848_CONTROL_LDEC, BT848_E_CONTROL); | ||
1546 | btor(BT848_CONTROL_LDEC, BT848_O_CONTROL); | ||
1547 | } | ||
1548 | break; | ||
1549 | case V4L2_CID_PRIVATE_AUTOMUTE: | ||
1550 | btv->opt_automute = c->value; | ||
1551 | break; | ||
1552 | case V4L2_CID_PRIVATE_AGC_CRUSH: | ||
1553 | btv->opt_adc_crush = c->value; | ||
1554 | btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), | ||
1555 | BT848_ADC); | ||
1556 | break; | ||
1557 | case V4L2_CID_PRIVATE_VCR_HACK: | ||
1558 | btv->opt_vcr_hack = c->value; | ||
1559 | break; | ||
1560 | case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: | ||
1561 | btv->opt_whitecrush_upper = c->value; | ||
1562 | btwrite(c->value, BT848_WC_UP); | ||
1563 | break; | ||
1564 | case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: | ||
1565 | btv->opt_whitecrush_lower = c->value; | ||
1566 | btwrite(c->value, BT848_WC_DOWN); | ||
1567 | break; | ||
1568 | case V4L2_CID_PRIVATE_UV_RATIO: | ||
1569 | btv->opt_uv_ratio = c->value; | ||
1570 | bt848_sat(btv, btv->saturation); | ||
1571 | break; | ||
1572 | case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: | ||
1573 | btv->opt_full_luma_range = c->value; | ||
1574 | btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM); | ||
1575 | break; | ||
1576 | case V4L2_CID_PRIVATE_CORING: | ||
1577 | btv->opt_coring = c->value; | ||
1578 | btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM); | ||
1579 | break; | ||
1580 | default: | ||
1581 | return -EINVAL; | ||
1582 | } | ||
1583 | return 0; | ||
1584 | } | ||
1585 | |||
1586 | /* ----------------------------------------------------------------------- */ | 1445 | /* ----------------------------------------------------------------------- */ |
1587 | 1446 | ||
1588 | void bttv_gpio_tracking(struct bttv *btv, char *comment) | 1447 | void bttv_gpio_tracking(struct bttv *btv, char *comment) |
@@ -1616,11 +1475,11 @@ format_by_fourcc(int fourcc) | |||
1616 | { | 1475 | { |
1617 | unsigned int i; | 1476 | unsigned int i; |
1618 | 1477 | ||
1619 | for (i = 0; i < BTTV_FORMATS; i++) { | 1478 | for (i = 0; i < FORMATS; i++) { |
1620 | if (-1 == bttv_formats[i].fourcc) | 1479 | if (-1 == formats[i].fourcc) |
1621 | continue; | 1480 | continue; |
1622 | if (bttv_formats[i].fourcc == fourcc) | 1481 | if (formats[i].fourcc == fourcc) |
1623 | return bttv_formats+i; | 1482 | return formats+i; |
1624 | } | 1483 | } |
1625 | return NULL; | 1484 | return NULL; |
1626 | } | 1485 | } |
@@ -1821,183 +1680,398 @@ static struct videobuf_queue_ops bttv_video_qops = { | |||
1821 | .buf_release = buffer_release, | 1680 | .buf_release = buffer_release, |
1822 | }; | 1681 | }; |
1823 | 1682 | ||
1824 | static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | 1683 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) |
1825 | { | 1684 | { |
1826 | switch (cmd) { | 1685 | struct bttv_fh *fh = priv; |
1827 | case VIDIOC_ENUMSTD: | 1686 | struct bttv *btv = fh->btv; |
1828 | { | 1687 | unsigned int i; |
1829 | struct v4l2_standard *e = arg; | 1688 | int err; |
1830 | unsigned int index = e->index; | ||
1831 | 1689 | ||
1832 | if (index >= BTTV_TVNORMS) | 1690 | err = v4l2_prio_check(&btv->prio, &fh->prio); |
1833 | return -EINVAL; | 1691 | if (0 != err) |
1834 | v4l2_video_std_construct(e, bttv_tvnorms[e->index].v4l2_id, | 1692 | return err; |
1835 | bttv_tvnorms[e->index].name); | 1693 | |
1836 | e->index = index; | 1694 | for (i = 0; i < BTTV_TVNORMS; i++) |
1837 | return 0; | 1695 | if (*id & bttv_tvnorms[i].v4l2_id) |
1696 | break; | ||
1697 | if (i == BTTV_TVNORMS) | ||
1698 | return -EINVAL; | ||
1699 | |||
1700 | mutex_lock(&btv->lock); | ||
1701 | set_tvnorm(btv, i); | ||
1702 | mutex_unlock(&btv->lock); | ||
1703 | |||
1704 | return 0; | ||
1705 | } | ||
1706 | |||
1707 | static int vidioc_querystd(struct file *file, void *f, v4l2_std_id *id) | ||
1708 | { | ||
1709 | struct bttv_fh *fh = f; | ||
1710 | struct bttv *btv = fh->btv; | ||
1711 | |||
1712 | if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML) | ||
1713 | *id = V4L2_STD_625_50; | ||
1714 | else | ||
1715 | *id = V4L2_STD_525_60; | ||
1716 | return 0; | ||
1717 | } | ||
1718 | |||
1719 | static int vidioc_enum_input(struct file *file, void *priv, | ||
1720 | struct v4l2_input *i) | ||
1721 | { | ||
1722 | struct bttv_fh *fh = priv; | ||
1723 | struct bttv *btv = fh->btv; | ||
1724 | unsigned int n; | ||
1725 | |||
1726 | n = i->index; | ||
1727 | |||
1728 | if (n >= bttv_tvcards[btv->c.type].video_inputs) | ||
1729 | return -EINVAL; | ||
1730 | |||
1731 | memset(i, 0, sizeof(*i)); | ||
1732 | |||
1733 | i->index = n; | ||
1734 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
1735 | i->audioset = 1; | ||
1736 | |||
1737 | if (i->index == bttv_tvcards[btv->c.type].tuner) { | ||
1738 | sprintf(i->name, "Television"); | ||
1739 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
1740 | i->tuner = 0; | ||
1741 | } else if (i->index == btv->svhs) { | ||
1742 | sprintf(i->name, "S-Video"); | ||
1743 | } else { | ||
1744 | sprintf(i->name, "Composite%d", i->index); | ||
1838 | } | 1745 | } |
1839 | case VIDIOC_G_STD: | 1746 | |
1840 | { | 1747 | if (i->index == btv->input) { |
1841 | v4l2_std_id *id = arg; | 1748 | __u32 dstatus = btread(BT848_DSTATUS); |
1842 | *id = bttv_tvnorms[btv->tvnorm].v4l2_id; | 1749 | if (0 == (dstatus & BT848_DSTATUS_PRES)) |
1843 | return 0; | 1750 | i->status |= V4L2_IN_ST_NO_SIGNAL; |
1751 | if (0 == (dstatus & BT848_DSTATUS_HLOC)) | ||
1752 | i->status |= V4L2_IN_ST_NO_H_LOCK; | ||
1844 | } | 1753 | } |
1845 | case VIDIOC_S_STD: | ||
1846 | { | ||
1847 | v4l2_std_id *id = arg; | ||
1848 | unsigned int i; | ||
1849 | 1754 | ||
1850 | for (i = 0; i < BTTV_TVNORMS; i++) | 1755 | for (n = 0; n < BTTV_TVNORMS; n++) |
1851 | if (*id & bttv_tvnorms[i].v4l2_id) | 1756 | i->std |= bttv_tvnorms[n].v4l2_id; |
1852 | break; | ||
1853 | if (i == BTTV_TVNORMS) | ||
1854 | return -EINVAL; | ||
1855 | 1757 | ||
1856 | mutex_lock(&btv->lock); | 1758 | return 0; |
1857 | set_tvnorm(btv,i); | 1759 | } |
1858 | mutex_unlock(&btv->lock); | ||
1859 | return 0; | ||
1860 | } | ||
1861 | case VIDIOC_QUERYSTD: | ||
1862 | { | ||
1863 | v4l2_std_id *id = arg; | ||
1864 | 1760 | ||
1865 | if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML) | 1761 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) |
1866 | *id = V4L2_STD_625_50; | 1762 | { |
1867 | else | 1763 | struct bttv_fh *fh = priv; |
1868 | *id = V4L2_STD_525_60; | 1764 | struct bttv *btv = fh->btv; |
1869 | return 0; | 1765 | |
1766 | *i = btv->input; | ||
1767 | return 0; | ||
1768 | } | ||
1769 | |||
1770 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | ||
1771 | { | ||
1772 | struct bttv_fh *fh = priv; | ||
1773 | struct bttv *btv = fh->btv; | ||
1774 | |||
1775 | int err; | ||
1776 | |||
1777 | err = v4l2_prio_check(&btv->prio, &fh->prio); | ||
1778 | if (0 != err) | ||
1779 | return err; | ||
1780 | |||
1781 | if (i > bttv_tvcards[btv->c.type].video_inputs) | ||
1782 | return -EINVAL; | ||
1783 | |||
1784 | mutex_lock(&btv->lock); | ||
1785 | set_input(btv, i, btv->tvnorm); | ||
1786 | mutex_unlock(&btv->lock); | ||
1787 | return 0; | ||
1788 | } | ||
1789 | |||
1790 | static int vidioc_s_tuner(struct file *file, void *priv, | ||
1791 | struct v4l2_tuner *t) | ||
1792 | { | ||
1793 | struct bttv_fh *fh = priv; | ||
1794 | struct bttv *btv = fh->btv; | ||
1795 | int err; | ||
1796 | |||
1797 | err = v4l2_prio_check(&btv->prio, &fh->prio); | ||
1798 | if (0 != err) | ||
1799 | return err; | ||
1800 | |||
1801 | if (UNSET == bttv_tvcards[btv->c.type].tuner) | ||
1802 | return -EINVAL; | ||
1803 | |||
1804 | if (0 != t->index) | ||
1805 | return -EINVAL; | ||
1806 | |||
1807 | mutex_lock(&btv->lock); | ||
1808 | bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t); | ||
1809 | |||
1810 | if (btv->audio_mode_gpio) | ||
1811 | btv->audio_mode_gpio(btv, t, 1); | ||
1812 | |||
1813 | mutex_unlock(&btv->lock); | ||
1814 | |||
1815 | return 0; | ||
1816 | } | ||
1817 | |||
1818 | static int vidioc_g_frequency(struct file *file, void *priv, | ||
1819 | struct v4l2_frequency *f) | ||
1820 | { | ||
1821 | struct bttv_fh *fh = priv; | ||
1822 | struct bttv *btv = fh->btv; | ||
1823 | int err; | ||
1824 | |||
1825 | err = v4l2_prio_check(&btv->prio, &fh->prio); | ||
1826 | if (0 != err) | ||
1827 | return err; | ||
1828 | |||
1829 | f->type = V4L2_TUNER_ANALOG_TV; | ||
1830 | f->frequency = btv->freq; | ||
1831 | |||
1832 | return 0; | ||
1833 | } | ||
1834 | |||
1835 | static int vidioc_s_frequency(struct file *file, void *priv, | ||
1836 | struct v4l2_frequency *f) | ||
1837 | { | ||
1838 | struct bttv_fh *fh = priv; | ||
1839 | struct bttv *btv = fh->btv; | ||
1840 | int err; | ||
1841 | |||
1842 | err = v4l2_prio_check(&btv->prio, &fh->prio); | ||
1843 | if (0 != err) | ||
1844 | return err; | ||
1845 | |||
1846 | if (unlikely(f->tuner != 0)) | ||
1847 | return -EINVAL; | ||
1848 | if (unlikely(f->type != V4L2_TUNER_ANALOG_TV)) | ||
1849 | return -EINVAL; | ||
1850 | mutex_lock(&btv->lock); | ||
1851 | btv->freq = f->frequency; | ||
1852 | bttv_call_i2c_clients(btv, VIDIOC_S_FREQUENCY, f); | ||
1853 | if (btv->has_matchbox && btv->radio_user) | ||
1854 | tea5757_set_freq(btv, btv->freq); | ||
1855 | mutex_unlock(&btv->lock); | ||
1856 | return 0; | ||
1857 | } | ||
1858 | |||
1859 | static int vidioc_log_status(struct file *file, void *f) | ||
1860 | { | ||
1861 | struct bttv_fh *fh = f; | ||
1862 | struct bttv *btv = fh->btv; | ||
1863 | |||
1864 | printk(KERN_INFO "bttv%d: ======== START STATUS CARD #%d ========\n", | ||
1865 | btv->c.nr, btv->c.nr); | ||
1866 | bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL); | ||
1867 | printk(KERN_INFO "bttv%d: ======== END STATUS CARD #%d ========\n", | ||
1868 | btv->c.nr, btv->c.nr); | ||
1869 | return 0; | ||
1870 | } | ||
1871 | |||
1872 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
1873 | struct v4l2_control *c) | ||
1874 | { | ||
1875 | struct bttv_fh *fh = priv; | ||
1876 | struct bttv *btv = fh->btv; | ||
1877 | |||
1878 | switch (c->id) { | ||
1879 | case V4L2_CID_BRIGHTNESS: | ||
1880 | c->value = btv->bright; | ||
1881 | break; | ||
1882 | case V4L2_CID_HUE: | ||
1883 | c->value = btv->hue; | ||
1884 | break; | ||
1885 | case V4L2_CID_CONTRAST: | ||
1886 | c->value = btv->contrast; | ||
1887 | break; | ||
1888 | case V4L2_CID_SATURATION: | ||
1889 | c->value = btv->saturation; | ||
1890 | break; | ||
1891 | |||
1892 | case V4L2_CID_AUDIO_MUTE: | ||
1893 | case V4L2_CID_AUDIO_VOLUME: | ||
1894 | case V4L2_CID_AUDIO_BALANCE: | ||
1895 | case V4L2_CID_AUDIO_BASS: | ||
1896 | case V4L2_CID_AUDIO_TREBLE: | ||
1897 | bttv_call_i2c_clients(btv, VIDIOC_G_CTRL, c); | ||
1898 | break; | ||
1899 | |||
1900 | case V4L2_CID_PRIVATE_CHROMA_AGC: | ||
1901 | c->value = btv->opt_chroma_agc; | ||
1902 | break; | ||
1903 | case V4L2_CID_PRIVATE_COMBFILTER: | ||
1904 | c->value = btv->opt_combfilter; | ||
1905 | break; | ||
1906 | case V4L2_CID_PRIVATE_LUMAFILTER: | ||
1907 | c->value = btv->opt_lumafilter; | ||
1908 | break; | ||
1909 | case V4L2_CID_PRIVATE_AUTOMUTE: | ||
1910 | c->value = btv->opt_automute; | ||
1911 | break; | ||
1912 | case V4L2_CID_PRIVATE_AGC_CRUSH: | ||
1913 | c->value = btv->opt_adc_crush; | ||
1914 | break; | ||
1915 | case V4L2_CID_PRIVATE_VCR_HACK: | ||
1916 | c->value = btv->opt_vcr_hack; | ||
1917 | break; | ||
1918 | case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: | ||
1919 | c->value = btv->opt_whitecrush_upper; | ||
1920 | break; | ||
1921 | case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: | ||
1922 | c->value = btv->opt_whitecrush_lower; | ||
1923 | break; | ||
1924 | case V4L2_CID_PRIVATE_UV_RATIO: | ||
1925 | c->value = btv->opt_uv_ratio; | ||
1926 | break; | ||
1927 | case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: | ||
1928 | c->value = btv->opt_full_luma_range; | ||
1929 | break; | ||
1930 | case V4L2_CID_PRIVATE_CORING: | ||
1931 | c->value = btv->opt_coring; | ||
1932 | break; | ||
1933 | default: | ||
1934 | return -EINVAL; | ||
1870 | } | 1935 | } |
1936 | return 0; | ||
1937 | } | ||
1871 | 1938 | ||
1872 | case VIDIOC_ENUMINPUT: | 1939 | static int vidioc_s_ctrl(struct file *file, void *f, |
1873 | { | 1940 | struct v4l2_control *c) |
1874 | struct v4l2_input *i = arg; | 1941 | { |
1875 | unsigned int n; | 1942 | int err; |
1943 | int val; | ||
1944 | struct bttv_fh *fh = f; | ||
1945 | struct bttv *btv = fh->btv; | ||
1876 | 1946 | ||
1877 | n = i->index; | 1947 | err = v4l2_prio_check(&btv->prio, &fh->prio); |
1878 | if (n >= bttv_tvcards[btv->c.type].video_inputs) | 1948 | if (0 != err) |
1879 | return -EINVAL; | 1949 | return err; |
1880 | memset(i,0,sizeof(*i)); | 1950 | |
1881 | i->index = n; | 1951 | switch (c->id) { |
1882 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1952 | case V4L2_CID_BRIGHTNESS: |
1883 | i->audioset = 1; | 1953 | bt848_bright(btv, c->value); |
1884 | if (i->index == bttv_tvcards[btv->c.type].tuner) { | 1954 | break; |
1885 | sprintf(i->name, "Television"); | 1955 | case V4L2_CID_HUE: |
1886 | i->type = V4L2_INPUT_TYPE_TUNER; | 1956 | bt848_hue(btv, c->value); |
1887 | i->tuner = 0; | 1957 | break; |
1888 | } else if (i->index == btv->svhs) { | 1958 | case V4L2_CID_CONTRAST: |
1889 | sprintf(i->name, "S-Video"); | 1959 | bt848_contrast(btv, c->value); |
1960 | break; | ||
1961 | case V4L2_CID_SATURATION: | ||
1962 | bt848_sat(btv, c->value); | ||
1963 | break; | ||
1964 | case V4L2_CID_AUDIO_MUTE: | ||
1965 | audio_mute(btv, c->value); | ||
1966 | /* fall through */ | ||
1967 | case V4L2_CID_AUDIO_VOLUME: | ||
1968 | if (btv->volume_gpio) | ||
1969 | btv->volume_gpio(btv, c->value); | ||
1970 | |||
1971 | bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c); | ||
1972 | break; | ||
1973 | case V4L2_CID_AUDIO_BALANCE: | ||
1974 | case V4L2_CID_AUDIO_BASS: | ||
1975 | case V4L2_CID_AUDIO_TREBLE: | ||
1976 | bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c); | ||
1977 | break; | ||
1978 | |||
1979 | case V4L2_CID_PRIVATE_CHROMA_AGC: | ||
1980 | btv->opt_chroma_agc = c->value; | ||
1981 | val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; | ||
1982 | btwrite(val, BT848_E_SCLOOP); | ||
1983 | btwrite(val, BT848_O_SCLOOP); | ||
1984 | break; | ||
1985 | case V4L2_CID_PRIVATE_COMBFILTER: | ||
1986 | btv->opt_combfilter = c->value; | ||
1987 | break; | ||
1988 | case V4L2_CID_PRIVATE_LUMAFILTER: | ||
1989 | btv->opt_lumafilter = c->value; | ||
1990 | if (btv->opt_lumafilter) { | ||
1991 | btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL); | ||
1992 | btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL); | ||
1890 | } else { | 1993 | } else { |
1891 | sprintf(i->name,"Composite%d",i->index); | 1994 | btor(BT848_CONTROL_LDEC, BT848_E_CONTROL); |
1892 | } | 1995 | btor(BT848_CONTROL_LDEC, BT848_O_CONTROL); |
1893 | if (i->index == btv->input) { | ||
1894 | __u32 dstatus = btread(BT848_DSTATUS); | ||
1895 | if (0 == (dstatus & BT848_DSTATUS_PRES)) | ||
1896 | i->status |= V4L2_IN_ST_NO_SIGNAL; | ||
1897 | if (0 == (dstatus & BT848_DSTATUS_HLOC)) | ||
1898 | i->status |= V4L2_IN_ST_NO_H_LOCK; | ||
1899 | } | 1996 | } |
1900 | for (n = 0; n < BTTV_TVNORMS; n++) | 1997 | break; |
1901 | i->std |= bttv_tvnorms[n].v4l2_id; | 1998 | case V4L2_CID_PRIVATE_AUTOMUTE: |
1902 | return 0; | 1999 | btv->opt_automute = c->value; |
1903 | } | 2000 | break; |
1904 | case VIDIOC_G_INPUT: | 2001 | case V4L2_CID_PRIVATE_AGC_CRUSH: |
1905 | { | 2002 | btv->opt_adc_crush = c->value; |
1906 | int *i = arg; | 2003 | btwrite(BT848_ADC_RESERVED | |
1907 | *i = btv->input; | 2004 | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), |
1908 | return 0; | 2005 | BT848_ADC); |
2006 | break; | ||
2007 | case V4L2_CID_PRIVATE_VCR_HACK: | ||
2008 | btv->opt_vcr_hack = c->value; | ||
2009 | break; | ||
2010 | case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: | ||
2011 | btv->opt_whitecrush_upper = c->value; | ||
2012 | btwrite(c->value, BT848_WC_UP); | ||
2013 | break; | ||
2014 | case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: | ||
2015 | btv->opt_whitecrush_lower = c->value; | ||
2016 | btwrite(c->value, BT848_WC_DOWN); | ||
2017 | break; | ||
2018 | case V4L2_CID_PRIVATE_UV_RATIO: | ||
2019 | btv->opt_uv_ratio = c->value; | ||
2020 | bt848_sat(btv, btv->saturation); | ||
2021 | break; | ||
2022 | case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: | ||
2023 | btv->opt_full_luma_range = c->value; | ||
2024 | btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM); | ||
2025 | break; | ||
2026 | case V4L2_CID_PRIVATE_CORING: | ||
2027 | btv->opt_coring = c->value; | ||
2028 | btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM); | ||
2029 | break; | ||
2030 | default: | ||
2031 | return -EINVAL; | ||
1909 | } | 2032 | } |
1910 | case VIDIOC_S_INPUT: | 2033 | return 0; |
1911 | { | 2034 | } |
1912 | unsigned int *i = arg; | ||
1913 | 2035 | ||
1914 | if (*i > bttv_tvcards[btv->c.type].video_inputs) | 2036 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1915 | return -EINVAL; | 2037 | static int vidioc_g_register(struct file *file, void *f, |
1916 | mutex_lock(&btv->lock); | 2038 | struct v4l2_register *reg) |
1917 | set_input(btv, *i, btv->tvnorm); | 2039 | { |
1918 | mutex_unlock(&btv->lock); | 2040 | struct bttv_fh *fh = f; |
1919 | return 0; | 2041 | struct bttv *btv = fh->btv; |
1920 | } | ||
1921 | 2042 | ||
1922 | case VIDIOC_S_TUNER: | 2043 | if (!capable(CAP_SYS_ADMIN)) |
1923 | { | 2044 | return -EPERM; |
1924 | struct v4l2_tuner *t = arg; | ||
1925 | 2045 | ||
1926 | if (UNSET == bttv_tvcards[btv->c.type].tuner) | 2046 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) |
1927 | return -EINVAL; | 2047 | return -EINVAL; |
1928 | if (0 != t->index) | ||
1929 | return -EINVAL; | ||
1930 | mutex_lock(&btv->lock); | ||
1931 | bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t); | ||
1932 | 2048 | ||
1933 | if (btv->audio_mode_gpio) { | 2049 | /* bt848 has a 12-bit register space */ |
1934 | btv->audio_mode_gpio (btv,t,1); | 2050 | reg->reg &= 0xfff; |
1935 | } | 2051 | reg->val = btread(reg->reg); |
1936 | mutex_unlock(&btv->lock); | ||
1937 | return 0; | ||
1938 | } | ||
1939 | 2052 | ||
1940 | case VIDIOC_G_FREQUENCY: | 2053 | return 0; |
1941 | { | 2054 | } |
1942 | struct v4l2_frequency *f = arg; | ||
1943 | 2055 | ||
1944 | memset(f,0,sizeof(*f)); | 2056 | static int vidioc_s_register(struct file *file, void *f, |
1945 | f->type = V4L2_TUNER_ANALOG_TV; | 2057 | struct v4l2_register *reg) |
1946 | f->frequency = btv->freq; | 2058 | { |
1947 | return 0; | 2059 | struct bttv_fh *fh = f; |
1948 | } | 2060 | struct bttv *btv = fh->btv; |
1949 | case VIDIOC_S_FREQUENCY: | ||
1950 | { | ||
1951 | struct v4l2_frequency *f = arg; | ||
1952 | 2061 | ||
1953 | if (unlikely(f->tuner != 0)) | 2062 | if (!capable(CAP_SYS_ADMIN)) |
1954 | return -EINVAL; | 2063 | return -EPERM; |
1955 | if (unlikely (f->type != V4L2_TUNER_ANALOG_TV)) | ||
1956 | return -EINVAL; | ||
1957 | mutex_lock(&btv->lock); | ||
1958 | btv->freq = f->frequency; | ||
1959 | bttv_call_i2c_clients(btv,VIDIOC_S_FREQUENCY,f); | ||
1960 | if (btv->has_matchbox && btv->radio_user) | ||
1961 | tea5757_set_freq(btv,btv->freq); | ||
1962 | mutex_unlock(&btv->lock); | ||
1963 | return 0; | ||
1964 | } | ||
1965 | case VIDIOC_LOG_STATUS: | ||
1966 | { | ||
1967 | printk(KERN_INFO "bttv%d: ================= START STATUS CARD #%d =================\n", btv->c.nr, btv->c.nr); | ||
1968 | bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL); | ||
1969 | printk(KERN_INFO "bttv%d: ================== END STATUS CARD #%d ==================\n", btv->c.nr, btv->c.nr); | ||
1970 | return 0; | ||
1971 | } | ||
1972 | case VIDIOC_G_CTRL: | ||
1973 | return get_control(btv,arg); | ||
1974 | case VIDIOC_S_CTRL: | ||
1975 | return set_control(btv,arg); | ||
1976 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1977 | case VIDIOC_DBG_G_REGISTER: | ||
1978 | case VIDIOC_DBG_S_REGISTER: | ||
1979 | { | ||
1980 | struct v4l2_register *reg = arg; | ||
1981 | if (!capable(CAP_SYS_ADMIN)) | ||
1982 | return -EPERM; | ||
1983 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | ||
1984 | return -EINVAL; | ||
1985 | /* bt848 has a 12-bit register space */ | ||
1986 | reg->reg &= 0xfff; | ||
1987 | if (cmd == VIDIOC_DBG_G_REGISTER) | ||
1988 | reg->val = btread(reg->reg); | ||
1989 | else | ||
1990 | btwrite(reg->val, reg->reg); | ||
1991 | return 0; | ||
1992 | } | ||
1993 | #endif | ||
1994 | 2064 | ||
1995 | default: | 2065 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) |
1996 | return -ENOIOCTLCMD; | 2066 | return -EINVAL; |
2067 | |||
2068 | /* bt848 has a 12-bit register space */ | ||
2069 | reg->reg &= 0xfff; | ||
2070 | btwrite(reg->val, reg->reg); | ||
1997 | 2071 | ||
1998 | } | ||
1999 | return 0; | 2072 | return 0; |
2000 | } | 2073 | } |
2074 | #endif | ||
2001 | 2075 | ||
2002 | /* Given cropping boundaries b and the scaled width and height of a | 2076 | /* Given cropping boundaries b and the scaled width and height of a |
2003 | single field or frame, which must not exceed hardware limits, this | 2077 | single field or frame, which must not exceed hardware limits, this |
@@ -2373,652 +2447,633 @@ pix_format_set_size (struct v4l2_pix_format * f, | |||
2373 | } | 2447 | } |
2374 | } | 2448 | } |
2375 | 2449 | ||
2376 | static int bttv_g_fmt(struct bttv_fh *fh, struct v4l2_format *f) | 2450 | static int vidioc_g_fmt_cap(struct file *file, void *priv, |
2451 | struct v4l2_format *f) | ||
2377 | { | 2452 | { |
2378 | switch (f->type) { | 2453 | struct bttv_fh *fh = priv; |
2379 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 2454 | |
2380 | memset(&f->fmt.pix,0,sizeof(struct v4l2_pix_format)); | 2455 | pix_format_set_size(&f->fmt.pix, fh->fmt, |
2381 | pix_format_set_size (&f->fmt.pix, fh->fmt, | 2456 | fh->width, fh->height); |
2382 | fh->width, fh->height); | 2457 | f->fmt.pix.field = fh->cap.field; |
2383 | f->fmt.pix.field = fh->cap.field; | 2458 | f->fmt.pix.pixelformat = fh->fmt->fourcc; |
2384 | f->fmt.pix.pixelformat = fh->fmt->fourcc; | 2459 | |
2385 | return 0; | 2460 | return 0; |
2386 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
2387 | memset(&f->fmt.win,0,sizeof(struct v4l2_window)); | ||
2388 | f->fmt.win.w = fh->ov.w; | ||
2389 | f->fmt.win.field = fh->ov.field; | ||
2390 | return 0; | ||
2391 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
2392 | bttv_vbi_get_fmt(fh, &f->fmt.vbi); | ||
2393 | return 0; | ||
2394 | default: | ||
2395 | return -EINVAL; | ||
2396 | } | ||
2397 | } | 2461 | } |
2398 | 2462 | ||
2399 | static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv, | 2463 | static int vidioc_g_fmt_overlay(struct file *file, void *priv, |
2400 | struct v4l2_format *f, int adjust_crop) | 2464 | struct v4l2_format *f) |
2401 | { | 2465 | { |
2402 | switch (f->type) { | 2466 | struct bttv_fh *fh = priv; |
2403 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
2404 | { | ||
2405 | const struct bttv_format *fmt; | ||
2406 | enum v4l2_field field; | ||
2407 | __s32 width, height; | ||
2408 | int rc; | ||
2409 | 2467 | ||
2410 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 2468 | f->fmt.win.w = fh->ov.w; |
2411 | if (NULL == fmt) | 2469 | f->fmt.win.field = fh->ov.field; |
2412 | return -EINVAL; | ||
2413 | 2470 | ||
2414 | field = f->fmt.pix.field; | 2471 | return 0; |
2415 | if (V4L2_FIELD_ANY == field) { | 2472 | } |
2416 | __s32 height2; | ||
2417 | 2473 | ||
2418 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; | 2474 | static int vidioc_try_fmt_cap(struct file *file, void *priv, |
2419 | field = (f->fmt.pix.height > height2) | 2475 | struct v4l2_format *f) |
2420 | ? V4L2_FIELD_INTERLACED | 2476 | { |
2421 | : V4L2_FIELD_BOTTOM; | 2477 | const struct bttv_format *fmt; |
2422 | } | 2478 | struct bttv_fh *fh = priv; |
2423 | if (V4L2_FIELD_SEQ_BT == field) | 2479 | struct bttv *btv = fh->btv; |
2424 | field = V4L2_FIELD_SEQ_TB; | 2480 | enum v4l2_field field; |
2425 | switch (field) { | 2481 | __s32 width, height; |
2426 | case V4L2_FIELD_TOP: | ||
2427 | case V4L2_FIELD_BOTTOM: | ||
2428 | case V4L2_FIELD_ALTERNATE: | ||
2429 | case V4L2_FIELD_INTERLACED: | ||
2430 | break; | ||
2431 | case V4L2_FIELD_SEQ_TB: | ||
2432 | if (fmt->flags & FORMAT_FLAGS_PLANAR) | ||
2433 | return -EINVAL; | ||
2434 | break; | ||
2435 | default: | ||
2436 | return -EINVAL; | ||
2437 | } | ||
2438 | 2482 | ||
2439 | width = f->fmt.pix.width; | 2483 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
2440 | height = f->fmt.pix.height; | 2484 | if (NULL == fmt) |
2485 | return -EINVAL; | ||
2441 | 2486 | ||
2442 | rc = limit_scaled_size(fh, &width, &height, field, | 2487 | field = f->fmt.pix.field; |
2443 | /* width_mask: 4 pixels */ ~3, | ||
2444 | /* width_bias: nearest */ 2, | ||
2445 | /* adjust_size */ 1, | ||
2446 | adjust_crop); | ||
2447 | if (0 != rc) | ||
2448 | return rc; | ||
2449 | 2488 | ||
2450 | /* update data for the application */ | 2489 | if (V4L2_FIELD_ANY == field) { |
2451 | f->fmt.pix.field = field; | 2490 | __s32 height2; |
2452 | pix_format_set_size(&f->fmt.pix, fmt, width, height); | ||
2453 | 2491 | ||
2454 | return 0; | 2492 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; |
2493 | field = (f->fmt.pix.height > height2) | ||
2494 | ? V4L2_FIELD_INTERLACED | ||
2495 | : V4L2_FIELD_BOTTOM; | ||
2455 | } | 2496 | } |
2456 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 2497 | |
2457 | return verify_window(fh, &f->fmt.win, | 2498 | if (V4L2_FIELD_SEQ_BT == field) |
2458 | /* adjust_size */ 1, | 2499 | field = V4L2_FIELD_SEQ_TB; |
2459 | /* adjust_crop */ 0); | 2500 | |
2460 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 2501 | switch (field) { |
2461 | return bttv_vbi_try_fmt(fh, &f->fmt.vbi); | 2502 | case V4L2_FIELD_TOP: |
2503 | case V4L2_FIELD_BOTTOM: | ||
2504 | case V4L2_FIELD_ALTERNATE: | ||
2505 | case V4L2_FIELD_INTERLACED: | ||
2506 | break; | ||
2507 | case V4L2_FIELD_SEQ_TB: | ||
2508 | if (fmt->flags & FORMAT_FLAGS_PLANAR) | ||
2509 | return -EINVAL; | ||
2510 | break; | ||
2462 | default: | 2511 | default: |
2463 | return -EINVAL; | 2512 | return -EINVAL; |
2464 | } | 2513 | } |
2514 | |||
2515 | width = f->fmt.pix.width; | ||
2516 | height = f->fmt.pix.height; | ||
2517 | |||
2518 | /* update data for the application */ | ||
2519 | f->fmt.pix.field = field; | ||
2520 | pix_format_set_size(&f->fmt.pix, fmt, width, height); | ||
2521 | |||
2522 | return 0; | ||
2523 | } | ||
2524 | |||
2525 | static int vidioc_try_fmt_overlay(struct file *file, void *priv, | ||
2526 | struct v4l2_format *f) | ||
2527 | { | ||
2528 | struct bttv_fh *fh = priv; | ||
2529 | |||
2530 | return verify_window(fh, &f->fmt.win, | ||
2531 | /* adjust_size */ 1, | ||
2532 | /* adjust_crop */ 0); | ||
2465 | } | 2533 | } |
2466 | 2534 | ||
2467 | static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv, | 2535 | static int vidioc_s_fmt_cap(struct file *file, void *priv, |
2468 | struct v4l2_format *f) | 2536 | struct v4l2_format *f) |
2469 | { | 2537 | { |
2470 | int retval; | 2538 | int retval; |
2539 | const struct bttv_format *fmt; | ||
2540 | struct bttv_fh *fh = priv; | ||
2541 | struct bttv *btv = fh->btv; | ||
2471 | 2542 | ||
2472 | switch (f->type) { | 2543 | retval = bttv_switch_type(fh, f->type); |
2473 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 2544 | if (0 != retval) |
2474 | { | 2545 | return retval; |
2475 | const struct bttv_format *fmt; | ||
2476 | 2546 | ||
2477 | retval = bttv_switch_type(fh,f->type); | 2547 | retval = vidioc_try_fmt_cap(file, priv, f); |
2478 | if (0 != retval) | 2548 | if (0 != retval) |
2479 | return retval; | 2549 | return retval; |
2480 | retval = bttv_try_fmt(fh,btv,f, /* adjust_crop */ 1); | ||
2481 | if (0 != retval) | ||
2482 | return retval; | ||
2483 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | ||
2484 | 2550 | ||
2485 | /* update our state informations */ | 2551 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
2486 | mutex_lock(&fh->cap.lock); | ||
2487 | fh->fmt = fmt; | ||
2488 | fh->cap.field = f->fmt.pix.field; | ||
2489 | fh->cap.last = V4L2_FIELD_NONE; | ||
2490 | fh->width = f->fmt.pix.width; | ||
2491 | fh->height = f->fmt.pix.height; | ||
2492 | btv->init.fmt = fmt; | ||
2493 | btv->init.width = f->fmt.pix.width; | ||
2494 | btv->init.height = f->fmt.pix.height; | ||
2495 | mutex_unlock(&fh->cap.lock); | ||
2496 | 2552 | ||
2497 | return 0; | 2553 | /* update our state informations */ |
2498 | } | 2554 | mutex_lock(&fh->cap.lock); |
2499 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 2555 | fh->fmt = fmt; |
2500 | if (no_overlay > 0) { | 2556 | fh->cap.field = f->fmt.pix.field; |
2501 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | 2557 | fh->cap.last = V4L2_FIELD_NONE; |
2502 | return -EINVAL; | 2558 | fh->width = f->fmt.pix.width; |
2503 | } | 2559 | fh->height = f->fmt.pix.height; |
2504 | return setup_window(fh, btv, &f->fmt.win, 1); | 2560 | btv->init.fmt = fmt; |
2505 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 2561 | btv->init.width = f->fmt.pix.width; |
2506 | retval = bttv_switch_type(fh,f->type); | 2562 | btv->init.height = f->fmt.pix.height; |
2507 | if (0 != retval) | 2563 | mutex_unlock(&fh->cap.lock); |
2508 | return retval; | 2564 | |
2509 | return bttv_vbi_set_fmt(fh, &f->fmt.vbi); | 2565 | return 0; |
2510 | default: | 2566 | } |
2567 | |||
2568 | static int vidioc_s_fmt_overlay(struct file *file, void *priv, | ||
2569 | struct v4l2_format *f) | ||
2570 | { | ||
2571 | struct bttv_fh *fh = priv; | ||
2572 | struct bttv *btv = fh->btv; | ||
2573 | |||
2574 | if (no_overlay > 0) | ||
2511 | return -EINVAL; | 2575 | return -EINVAL; |
2576 | |||
2577 | return setup_window(fh, btv, &f->fmt.win, 1); | ||
2578 | } | ||
2579 | |||
2580 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
2581 | static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | ||
2582 | { | ||
2583 | int retval; | ||
2584 | unsigned int i; | ||
2585 | struct bttv_fh *fh = priv; | ||
2586 | |||
2587 | mutex_lock(&fh->cap.lock); | ||
2588 | retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, | ||
2589 | V4L2_MEMORY_MMAP); | ||
2590 | if (retval < 0) { | ||
2591 | mutex_unlock(&fh->cap.lock); | ||
2592 | return retval; | ||
2512 | } | 2593 | } |
2594 | |||
2595 | gbuffers = retval; | ||
2596 | memset(mbuf, 0, sizeof(*mbuf)); | ||
2597 | mbuf->frames = gbuffers; | ||
2598 | mbuf->size = gbuffers * gbufsize; | ||
2599 | |||
2600 | for (i = 0; i < gbuffers; i++) | ||
2601 | mbuf->offsets[i] = i * gbufsize; | ||
2602 | |||
2603 | mutex_unlock(&fh->cap.lock); | ||
2604 | return 0; | ||
2513 | } | 2605 | } |
2606 | #endif | ||
2514 | 2607 | ||
2515 | static int bttv_do_ioctl(struct inode *inode, struct file *file, | 2608 | static int vidioc_querycap(struct file *file, void *priv, |
2516 | unsigned int cmd, void *arg) | 2609 | struct v4l2_capability *cap) |
2517 | { | 2610 | { |
2518 | struct bttv_fh *fh = file->private_data; | 2611 | struct bttv_fh *fh = priv; |
2519 | struct bttv *btv = fh->btv; | 2612 | struct bttv *btv = fh->btv; |
2520 | int retval = 0; | ||
2521 | 2613 | ||
2522 | if (bttv_debug > 1) | 2614 | if (0 == v4l2) |
2523 | v4l_print_ioctl(btv->c.name, cmd); | 2615 | return -EINVAL; |
2524 | 2616 | ||
2525 | if (btv->errors) | 2617 | strlcpy(cap->driver, "bttv", sizeof(cap->driver)); |
2526 | bttv_reinit_bt848(btv); | 2618 | strlcpy(cap->card, btv->video_dev->name, sizeof(cap->card)); |
2619 | snprintf(cap->bus_info, sizeof(cap->bus_info), | ||
2620 | "PCI:%s", pci_name(btv->c.pci)); | ||
2621 | cap->version = BTTV_VERSION_CODE; | ||
2622 | cap->capabilities = | ||
2623 | V4L2_CAP_VIDEO_CAPTURE | | ||
2624 | V4L2_CAP_VBI_CAPTURE | | ||
2625 | V4L2_CAP_READWRITE | | ||
2626 | V4L2_CAP_STREAMING; | ||
2627 | if (no_overlay <= 0) | ||
2628 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; | ||
2629 | |||
2630 | if (bttv_tvcards[btv->c.type].tuner != UNSET && | ||
2631 | bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT) | ||
2632 | cap->capabilities |= V4L2_CAP_TUNER; | ||
2633 | return 0; | ||
2634 | } | ||
2527 | 2635 | ||
2528 | switch (cmd) { | 2636 | static int vidioc_enum_fmt_cap(struct file *file, void *priv, |
2529 | case VIDIOC_S_CTRL: | 2637 | struct v4l2_fmtdesc *f) |
2530 | case VIDIOC_S_STD: | 2638 | { |
2531 | case VIDIOC_S_INPUT: | 2639 | if (f->index >= FORMATS) |
2532 | case VIDIOC_S_TUNER: | 2640 | return -EINVAL; |
2533 | case VIDIOC_S_FREQUENCY: | ||
2534 | retval = v4l2_prio_check(&btv->prio,&fh->prio); | ||
2535 | if (0 != retval) | ||
2536 | return retval; | ||
2537 | }; | ||
2538 | 2641 | ||
2539 | switch (cmd) { | 2642 | strlcpy(f->description, formats[f->index].name, sizeof(f->description)); |
2540 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 2643 | f->pixelformat = formats[f->index].fourcc; |
2541 | case VIDIOCGMBUF: | ||
2542 | { | ||
2543 | struct video_mbuf *mbuf = arg; | ||
2544 | unsigned int i; | ||
2545 | 2644 | ||
2546 | retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize, | 2645 | return 0; |
2547 | V4L2_MEMORY_MMAP); | 2646 | } |
2548 | if (retval < 0) | ||
2549 | return retval; | ||
2550 | 2647 | ||
2551 | gbuffers = retval; | 2648 | static int vidioc_enum_fmt_overlay(struct file *file, void *priv, |
2552 | memset(mbuf,0,sizeof(*mbuf)); | 2649 | struct v4l2_fmtdesc *f) |
2553 | mbuf->frames = gbuffers; | 2650 | { |
2554 | mbuf->size = gbuffers * gbufsize; | 2651 | if (no_overlay > 0) { |
2555 | for (i = 0; i < gbuffers; i++) | 2652 | printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); |
2556 | mbuf->offsets[i] = i * gbufsize; | 2653 | return -EINVAL; |
2557 | return 0; | ||
2558 | } | 2654 | } |
2559 | #endif | ||
2560 | 2655 | ||
2561 | /* *** v4l2 *** ************************************************ */ | 2656 | if (f->index >= FORMATS) |
2562 | case VIDIOC_QUERYCAP: | 2657 | return -EINVAL; |
2563 | { | ||
2564 | struct v4l2_capability *cap = arg; | ||
2565 | 2658 | ||
2566 | if (0 == v4l2) | 2659 | strlcpy(f->description, formats[f->index].name, |
2567 | return -EINVAL; | 2660 | sizeof(f->description)); |
2568 | memset(cap, 0, sizeof (*cap)); | ||
2569 | strlcpy(cap->driver, "bttv", sizeof (cap->driver)); | ||
2570 | strlcpy(cap->card, btv->video_dev->name, sizeof (cap->card)); | ||
2571 | snprintf(cap->bus_info, sizeof (cap->bus_info), | ||
2572 | "PCI:%s", pci_name(btv->c.pci)); | ||
2573 | cap->version = BTTV_VERSION_CODE; | ||
2574 | cap->capabilities = | ||
2575 | V4L2_CAP_VIDEO_CAPTURE | | ||
2576 | V4L2_CAP_VBI_CAPTURE | | ||
2577 | V4L2_CAP_READWRITE | | ||
2578 | V4L2_CAP_STREAMING; | ||
2579 | if (no_overlay <= 0) | ||
2580 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; | ||
2581 | |||
2582 | if (bttv_tvcards[btv->c.type].tuner != UNSET && | ||
2583 | bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT) | ||
2584 | cap->capabilities |= V4L2_CAP_TUNER; | ||
2585 | return 0; | ||
2586 | } | ||
2587 | case VIDIOC_ENUM_FMT: | ||
2588 | { | ||
2589 | struct v4l2_fmtdesc *f = arg; | ||
2590 | enum v4l2_buf_type type; | ||
2591 | unsigned int i; | ||
2592 | int index; | ||
2593 | |||
2594 | type = f->type; | ||
2595 | if (V4L2_BUF_TYPE_VBI_CAPTURE == type) { | ||
2596 | /* vbi */ | ||
2597 | index = f->index; | ||
2598 | if (0 != index) | ||
2599 | return -EINVAL; | ||
2600 | memset(f,0,sizeof(*f)); | ||
2601 | f->index = index; | ||
2602 | f->type = type; | ||
2603 | f->pixelformat = V4L2_PIX_FMT_GREY; | ||
2604 | strcpy(f->description,"vbi data"); | ||
2605 | return 0; | ||
2606 | } | ||
2607 | 2661 | ||
2608 | /* video capture + overlay */ | 2662 | f->pixelformat = formats[f->index].fourcc; |
2609 | index = -1; | ||
2610 | for (i = 0; i < BTTV_FORMATS; i++) { | ||
2611 | if (bttv_formats[i].fourcc != -1) | ||
2612 | index++; | ||
2613 | if ((unsigned int)index == f->index) | ||
2614 | break; | ||
2615 | } | ||
2616 | if (BTTV_FORMATS == i) | ||
2617 | return -EINVAL; | ||
2618 | 2663 | ||
2619 | switch (f->type) { | 2664 | return 0; |
2620 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 2665 | } |
2621 | break; | 2666 | |
2622 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 2667 | static int vidioc_enum_fmt_vbi(struct file *file, void *priv, |
2623 | if (!(bttv_formats[i].flags & FORMAT_FLAGS_PACKED)) | 2668 | struct v4l2_fmtdesc *f) |
2624 | return -EINVAL; | 2669 | { |
2625 | break; | 2670 | if (0 != f->index) |
2626 | default: | 2671 | return -EINVAL; |
2672 | |||
2673 | f->pixelformat = V4L2_PIX_FMT_GREY; | ||
2674 | strcpy(f->description, "vbi data"); | ||
2675 | |||
2676 | return 0; | ||
2677 | } | ||
2678 | |||
2679 | static int vidioc_g_fbuf(struct file *file, void *f, | ||
2680 | struct v4l2_framebuffer *fb) | ||
2681 | { | ||
2682 | struct bttv_fh *fh = f; | ||
2683 | struct bttv *btv = fh->btv; | ||
2684 | |||
2685 | *fb = btv->fbuf; | ||
2686 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; | ||
2687 | if (fh->ovfmt) | ||
2688 | fb->fmt.pixelformat = fh->ovfmt->fourcc; | ||
2689 | return 0; | ||
2690 | } | ||
2691 | |||
2692 | static int vidioc_overlay(struct file *file, void *f, unsigned int on) | ||
2693 | { | ||
2694 | struct bttv_fh *fh = f; | ||
2695 | struct bttv *btv = fh->btv; | ||
2696 | struct bttv_buffer *new; | ||
2697 | int retval; | ||
2698 | |||
2699 | if (on) { | ||
2700 | /* verify args */ | ||
2701 | if (NULL == btv->fbuf.base) | ||
2702 | return -EINVAL; | ||
2703 | if (!fh->ov.setup_ok) { | ||
2704 | dprintk("bttv%d: overlay: !setup_ok\n", btv->c.nr); | ||
2627 | return -EINVAL; | 2705 | return -EINVAL; |
2628 | } | 2706 | } |
2629 | memset(f,0,sizeof(*f)); | ||
2630 | f->index = index; | ||
2631 | f->type = type; | ||
2632 | f->pixelformat = bttv_formats[i].fourcc; | ||
2633 | strlcpy(f->description,bttv_formats[i].name,sizeof(f->description)); | ||
2634 | return 0; | ||
2635 | } | 2707 | } |
2636 | case VIDIOC_TRY_FMT: | 2708 | |
2637 | { | 2709 | if (!check_alloc_btres(btv, fh, RESOURCE_OVERLAY)) |
2638 | struct v4l2_format *f = arg; | 2710 | return -EBUSY; |
2639 | return bttv_try_fmt(fh,btv,f, /* adjust_crop */ 0); | 2711 | |
2640 | } | 2712 | mutex_lock(&fh->cap.lock); |
2641 | case VIDIOC_G_FMT: | 2713 | if (on) { |
2642 | { | 2714 | fh->ov.tvnorm = btv->tvnorm; |
2643 | struct v4l2_format *f = arg; | 2715 | new = videobuf_pci_alloc(sizeof(*new)); |
2644 | return bttv_g_fmt(fh,f); | 2716 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); |
2645 | } | 2717 | } else { |
2646 | case VIDIOC_S_FMT: | 2718 | new = NULL; |
2647 | { | ||
2648 | struct v4l2_format *f = arg; | ||
2649 | return bttv_s_fmt(fh,btv,f); | ||
2650 | } | 2719 | } |
2651 | 2720 | ||
2652 | case VIDIOC_G_FBUF: | 2721 | /* switch over */ |
2653 | { | 2722 | retval = bttv_switch_overlay(btv, fh, new); |
2654 | struct v4l2_framebuffer *fb = arg; | 2723 | mutex_unlock(&fh->cap.lock); |
2724 | return retval; | ||
2725 | } | ||
2655 | 2726 | ||
2656 | *fb = btv->fbuf; | 2727 | static int vidioc_s_fbuf(struct file *file, void *f, |
2657 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; | 2728 | struct v4l2_framebuffer *fb) |
2658 | if (fh->ovfmt) | 2729 | { |
2659 | fb->fmt.pixelformat = fh->ovfmt->fourcc; | 2730 | struct bttv_fh *fh = f; |
2660 | return 0; | 2731 | struct bttv *btv = fh->btv; |
2732 | const struct bttv_format *fmt; | ||
2733 | int retval; | ||
2734 | |||
2735 | if (!capable(CAP_SYS_ADMIN) && | ||
2736 | !capable(CAP_SYS_RAWIO)) | ||
2737 | return -EPERM; | ||
2738 | |||
2739 | /* check args */ | ||
2740 | fmt = format_by_fourcc(fb->fmt.pixelformat); | ||
2741 | if (NULL == fmt) | ||
2742 | return -EINVAL; | ||
2743 | if (0 == (fmt->flags & FORMAT_FLAGS_PACKED)) | ||
2744 | return -EINVAL; | ||
2745 | |||
2746 | retval = -EINVAL; | ||
2747 | if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { | ||
2748 | __s32 width = fb->fmt.width; | ||
2749 | __s32 height = fb->fmt.height; | ||
2750 | |||
2751 | retval = limit_scaled_size(fh, &width, &height, | ||
2752 | V4L2_FIELD_INTERLACED, | ||
2753 | /* width_mask */ ~3, | ||
2754 | /* width_bias */ 2, | ||
2755 | /* adjust_size */ 0, | ||
2756 | /* adjust_crop */ 0); | ||
2757 | if (0 != retval) | ||
2758 | return retval; | ||
2661 | } | 2759 | } |
2662 | case VIDIOC_OVERLAY: | ||
2663 | { | ||
2664 | struct bttv_buffer *new; | ||
2665 | int *on = arg; | ||
2666 | 2760 | ||
2667 | if (*on) { | 2761 | /* ok, accept it */ |
2668 | /* verify args */ | 2762 | mutex_lock(&fh->cap.lock); |
2669 | if (NULL == btv->fbuf.base) | 2763 | btv->fbuf.base = fb->base; |
2670 | return -EINVAL; | 2764 | btv->fbuf.fmt.width = fb->fmt.width; |
2671 | if (!fh->ov.setup_ok) { | 2765 | btv->fbuf.fmt.height = fb->fmt.height; |
2672 | dprintk("bttv%d: overlay: !setup_ok\n",btv->c.nr); | 2766 | if (0 != fb->fmt.bytesperline) |
2673 | return -EINVAL; | 2767 | btv->fbuf.fmt.bytesperline = fb->fmt.bytesperline; |
2674 | } | 2768 | else |
2675 | } | 2769 | btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fmt->depth/8; |
2676 | 2770 | ||
2677 | if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY)) | 2771 | retval = 0; |
2678 | return -EBUSY; | 2772 | fh->ovfmt = fmt; |
2773 | btv->init.ovfmt = fmt; | ||
2774 | if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { | ||
2775 | fh->ov.w.left = 0; | ||
2776 | fh->ov.w.top = 0; | ||
2777 | fh->ov.w.width = fb->fmt.width; | ||
2778 | fh->ov.w.height = fb->fmt.height; | ||
2779 | btv->init.ov.w.width = fb->fmt.width; | ||
2780 | btv->init.ov.w.height = fb->fmt.height; | ||
2781 | kfree(fh->ov.clips); | ||
2782 | fh->ov.clips = NULL; | ||
2783 | fh->ov.nclips = 0; | ||
2784 | |||
2785 | if (check_btres(fh, RESOURCE_OVERLAY)) { | ||
2786 | struct bttv_buffer *new; | ||
2679 | 2787 | ||
2680 | mutex_lock(&fh->cap.lock); | ||
2681 | if (*on) { | ||
2682 | fh->ov.tvnorm = btv->tvnorm; | ||
2683 | new = videobuf_pci_alloc(sizeof(*new)); | 2788 | new = videobuf_pci_alloc(sizeof(*new)); |
2789 | new->crop = btv->crop[!!fh->do_crop].rect; | ||
2684 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); | 2790 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); |
2685 | } else { | 2791 | retval = bttv_switch_overlay(btv, fh, new); |
2686 | new = NULL; | ||
2687 | } | 2792 | } |
2688 | |||
2689 | /* switch over */ | ||
2690 | retval = bttv_switch_overlay(btv,fh,new); | ||
2691 | mutex_unlock(&fh->cap.lock); | ||
2692 | return retval; | ||
2693 | } | 2793 | } |
2694 | case VIDIOC_S_FBUF: | 2794 | mutex_unlock(&fh->cap.lock); |
2695 | { | 2795 | return retval; |
2696 | struct v4l2_framebuffer *fb = arg; | 2796 | } |
2697 | const struct bttv_format *fmt; | ||
2698 | 2797 | ||
2699 | if(!capable(CAP_SYS_ADMIN) && | 2798 | static int vidioc_reqbufs(struct file *file, void *priv, |
2700 | !capable(CAP_SYS_RAWIO)) | 2799 | struct v4l2_requestbuffers *p) |
2701 | return -EPERM; | 2800 | { |
2801 | struct bttv_fh *fh = priv; | ||
2802 | return videobuf_reqbufs(bttv_queue(fh), p); | ||
2803 | } | ||
2702 | 2804 | ||
2703 | /* check args */ | 2805 | static int vidioc_querybuf(struct file *file, void *priv, |
2704 | fmt = format_by_fourcc(fb->fmt.pixelformat); | 2806 | struct v4l2_buffer *b) |
2705 | if (NULL == fmt) | 2807 | { |
2706 | return -EINVAL; | 2808 | struct bttv_fh *fh = priv; |
2707 | if (0 == (fmt->flags & FORMAT_FLAGS_PACKED)) | 2809 | return videobuf_querybuf(bttv_queue(fh), b); |
2708 | return -EINVAL; | 2810 | } |
2709 | 2811 | ||
2710 | retval = -EINVAL; | 2812 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) |
2711 | if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { | 2813 | { |
2712 | __s32 width = fb->fmt.width; | 2814 | struct bttv_fh *fh = priv; |
2713 | __s32 height = fb->fmt.height; | 2815 | struct bttv *btv = fh->btv; |
2714 | 2816 | int res = bttv_resource(fh); | |
2715 | retval = limit_scaled_size(fh, &width, &height, | ||
2716 | V4L2_FIELD_INTERLACED, | ||
2717 | /* width_mask */ ~3, | ||
2718 | /* width_bias */ 2, | ||
2719 | /* adjust_size */ 0, | ||
2720 | /* adjust_crop */ 0); | ||
2721 | if (0 != retval) | ||
2722 | return retval; | ||
2723 | } | ||
2724 | 2817 | ||
2725 | /* ok, accept it */ | 2818 | if (!check_alloc_btres(btv, fh, res)) |
2726 | mutex_lock(&fh->cap.lock); | 2819 | return -EBUSY; |
2727 | btv->fbuf.base = fb->base; | ||
2728 | btv->fbuf.fmt.width = fb->fmt.width; | ||
2729 | btv->fbuf.fmt.height = fb->fmt.height; | ||
2730 | if (0 != fb->fmt.bytesperline) | ||
2731 | btv->fbuf.fmt.bytesperline = fb->fmt.bytesperline; | ||
2732 | else | ||
2733 | btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fmt->depth/8; | ||
2734 | |||
2735 | retval = 0; | ||
2736 | fh->ovfmt = fmt; | ||
2737 | btv->init.ovfmt = fmt; | ||
2738 | if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { | ||
2739 | fh->ov.w.left = 0; | ||
2740 | fh->ov.w.top = 0; | ||
2741 | fh->ov.w.width = fb->fmt.width; | ||
2742 | fh->ov.w.height = fb->fmt.height; | ||
2743 | btv->init.ov.w.width = fb->fmt.width; | ||
2744 | btv->init.ov.w.height = fb->fmt.height; | ||
2745 | kfree(fh->ov.clips); | ||
2746 | fh->ov.clips = NULL; | ||
2747 | fh->ov.nclips = 0; | ||
2748 | |||
2749 | if (check_btres(fh, RESOURCE_OVERLAY)) { | ||
2750 | struct bttv_buffer *new; | ||
2751 | |||
2752 | new = videobuf_pci_alloc(sizeof(*new)); | ||
2753 | new->crop = btv->crop[!!fh->do_crop].rect; | ||
2754 | bttv_overlay_risc(btv,&fh->ov,fh->ovfmt,new); | ||
2755 | retval = bttv_switch_overlay(btv,fh,new); | ||
2756 | } | ||
2757 | } | ||
2758 | mutex_unlock(&fh->cap.lock); | ||
2759 | return retval; | ||
2760 | } | ||
2761 | case VIDIOC_REQBUFS: | ||
2762 | return videobuf_reqbufs(bttv_queue(fh),arg); | ||
2763 | case VIDIOC_QUERYBUF: | ||
2764 | return videobuf_querybuf(bttv_queue(fh),arg); | ||
2765 | case VIDIOC_QBUF: | ||
2766 | { | ||
2767 | int res = bttv_resource(fh); | ||
2768 | 2820 | ||
2769 | if (!check_alloc_btres(btv, fh, res)) | 2821 | return videobuf_qbuf(bttv_queue(fh), b); |
2770 | return -EBUSY; | 2822 | } |
2771 | return videobuf_qbuf(bttv_queue(fh),arg); | ||
2772 | } | ||
2773 | case VIDIOC_DQBUF: | ||
2774 | return videobuf_dqbuf(bttv_queue(fh),arg, | ||
2775 | file->f_flags & O_NONBLOCK); | ||
2776 | case VIDIOC_STREAMON: | ||
2777 | { | ||
2778 | int res = bttv_resource(fh); | ||
2779 | 2823 | ||
2780 | if (!check_alloc_btres(btv,fh,res)) | 2824 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) |
2781 | return -EBUSY; | 2825 | { |
2782 | return videobuf_streamon(bttv_queue(fh)); | 2826 | struct bttv_fh *fh = priv; |
2783 | } | 2827 | return videobuf_dqbuf(bttv_queue(fh), b, |
2784 | case VIDIOC_STREAMOFF: | 2828 | file->f_flags & O_NONBLOCK); |
2785 | { | 2829 | } |
2786 | int res = bttv_resource(fh); | ||
2787 | 2830 | ||
2788 | retval = videobuf_streamoff(bttv_queue(fh)); | 2831 | static int vidioc_streamon(struct file *file, void *priv, |
2789 | if (retval < 0) | 2832 | enum v4l2_buf_type type) |
2790 | return retval; | 2833 | { |
2791 | free_btres(btv,fh,res); | 2834 | struct bttv_fh *fh = priv; |
2792 | return 0; | 2835 | struct bttv *btv = fh->btv; |
2793 | } | 2836 | int res = bttv_resource(fh); |
2794 | 2837 | ||
2795 | case VIDIOC_QUERYCTRL: | 2838 | if (!check_alloc_btres(btv, fh, res)) |
2796 | { | 2839 | return -EBUSY; |
2797 | struct v4l2_queryctrl *c = arg; | 2840 | return videobuf_streamon(bttv_queue(fh)); |
2798 | int i; | 2841 | } |
2799 | 2842 | ||
2800 | if ((c->id < V4L2_CID_BASE || | ||
2801 | c->id >= V4L2_CID_LASTP1) && | ||
2802 | (c->id < V4L2_CID_PRIVATE_BASE || | ||
2803 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | ||
2804 | return -EINVAL; | ||
2805 | for (i = 0; i < BTTV_CTLS; i++) | ||
2806 | if (bttv_ctls[i].id == c->id) | ||
2807 | break; | ||
2808 | if (i == BTTV_CTLS) { | ||
2809 | *c = no_ctl; | ||
2810 | return 0; | ||
2811 | } | ||
2812 | *c = bttv_ctls[i]; | ||
2813 | 2843 | ||
2814 | if (!btv->volume_gpio && | 2844 | static int vidioc_streamoff(struct file *file, void *priv, |
2815 | (bttv_ctls[i].id == V4L2_CID_AUDIO_VOLUME)) | 2845 | enum v4l2_buf_type type) |
2816 | *c = no_ctl; | 2846 | { |
2847 | struct bttv_fh *fh = priv; | ||
2848 | struct bttv *btv = fh->btv; | ||
2849 | int retval; | ||
2850 | int res = bttv_resource(fh); | ||
2817 | 2851 | ||
2818 | return 0; | ||
2819 | } | ||
2820 | case VIDIOC_G_PARM: | ||
2821 | { | ||
2822 | struct v4l2_streamparm *parm = arg; | ||
2823 | struct v4l2_standard s; | ||
2824 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
2825 | return -EINVAL; | ||
2826 | memset(parm,0,sizeof(*parm)); | ||
2827 | v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id, | ||
2828 | bttv_tvnorms[btv->tvnorm].name); | ||
2829 | parm->parm.capture.timeperframe = s.frameperiod; | ||
2830 | return 0; | ||
2831 | } | ||
2832 | case VIDIOC_G_TUNER: | ||
2833 | { | ||
2834 | struct v4l2_tuner *t = arg; | ||
2835 | 2852 | ||
2836 | if (UNSET == bttv_tvcards[btv->c.type].tuner) | 2853 | retval = videobuf_streamoff(bttv_queue(fh)); |
2837 | return -EINVAL; | 2854 | if (retval < 0) |
2838 | if (0 != t->index) | 2855 | return retval; |
2839 | return -EINVAL; | 2856 | free_btres(btv, fh, res); |
2840 | mutex_lock(&btv->lock); | 2857 | return 0; |
2841 | memset(t,0,sizeof(*t)); | 2858 | } |
2842 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
2843 | bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); | ||
2844 | strcpy(t->name, "Television"); | ||
2845 | t->capability = V4L2_TUNER_CAP_NORM; | ||
2846 | t->type = V4L2_TUNER_ANALOG_TV; | ||
2847 | if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) | ||
2848 | t->signal = 0xffff; | ||
2849 | |||
2850 | if (btv->audio_mode_gpio) { | ||
2851 | btv->audio_mode_gpio (btv,t,0); | ||
2852 | } | ||
2853 | 2859 | ||
2854 | mutex_unlock(&btv->lock); | 2860 | static int vidioc_queryctrl(struct file *file, void *priv, |
2855 | return 0; | 2861 | struct v4l2_queryctrl *c) |
2856 | } | 2862 | { |
2863 | struct bttv_fh *fh = priv; | ||
2864 | struct bttv *btv = fh->btv; | ||
2865 | const struct v4l2_queryctrl *ctrl; | ||
2857 | 2866 | ||
2858 | case VIDIOC_G_PRIORITY: | 2867 | if ((c->id < V4L2_CID_BASE || |
2859 | { | 2868 | c->id >= V4L2_CID_LASTP1) && |
2860 | enum v4l2_priority *p = arg; | 2869 | (c->id < V4L2_CID_PRIVATE_BASE || |
2870 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | ||
2871 | return -EINVAL; | ||
2861 | 2872 | ||
2862 | *p = v4l2_prio_max(&btv->prio); | 2873 | ctrl = ctrl_by_id(c->id); |
2863 | return 0; | 2874 | *c = (NULL != ctrl) ? *ctrl : no_ctl; |
2864 | } | ||
2865 | case VIDIOC_S_PRIORITY: | ||
2866 | { | ||
2867 | enum v4l2_priority *prio = arg; | ||
2868 | 2875 | ||
2869 | return v4l2_prio_change(&btv->prio, &fh->prio, *prio); | 2876 | if (!btv->volume_gpio && |
2870 | } | 2877 | (ctrl->id == V4L2_CID_AUDIO_VOLUME)) |
2878 | * c = no_ctl; | ||
2871 | 2879 | ||
2872 | case VIDIOC_CROPCAP: | 2880 | return 0; |
2873 | { | 2881 | } |
2874 | struct v4l2_cropcap *cap = arg; | ||
2875 | enum v4l2_buf_type type; | ||
2876 | 2882 | ||
2877 | type = cap->type; | 2883 | static int vidioc_g_parm(struct file *file, void *f, |
2884 | struct v4l2_streamparm *parm) | ||
2885 | { | ||
2886 | struct bttv_fh *fh = f; | ||
2887 | struct bttv *btv = fh->btv; | ||
2888 | struct v4l2_standard s; | ||
2878 | 2889 | ||
2879 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | 2890 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
2880 | type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 2891 | return -EINVAL; |
2881 | return -EINVAL; | 2892 | v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id, |
2893 | bttv_tvnorms[btv->tvnorm].name); | ||
2894 | parm->parm.capture.timeperframe = s.frameperiod; | ||
2895 | return 0; | ||
2896 | } | ||
2882 | 2897 | ||
2883 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; | 2898 | static int vidioc_g_tuner(struct file *file, void *priv, |
2884 | cap->type = type; | 2899 | struct v4l2_tuner *t) |
2900 | { | ||
2901 | struct bttv_fh *fh = priv; | ||
2902 | struct bttv *btv = fh->btv; | ||
2885 | 2903 | ||
2886 | return 0; | 2904 | if (UNSET == bttv_tvcards[btv->c.type].tuner) |
2887 | } | 2905 | return -EINVAL; |
2888 | case VIDIOC_G_CROP: | 2906 | if (0 != t->index) |
2889 | { | 2907 | return -EINVAL; |
2890 | struct v4l2_crop * crop = arg; | ||
2891 | 2908 | ||
2892 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | 2909 | mutex_lock(&btv->lock); |
2893 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 2910 | memset(t, 0, sizeof(*t)); |
2894 | return -EINVAL; | 2911 | t->rxsubchans = V4L2_TUNER_SUB_MONO; |
2912 | bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); | ||
2913 | strcpy(t->name, "Television"); | ||
2914 | t->capability = V4L2_TUNER_CAP_NORM; | ||
2915 | t->type = V4L2_TUNER_ANALOG_TV; | ||
2916 | if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) | ||
2917 | t->signal = 0xffff; | ||
2918 | |||
2919 | if (btv->audio_mode_gpio) | ||
2920 | btv->audio_mode_gpio(btv, t, 0); | ||
2895 | 2921 | ||
2896 | /* No fh->do_crop = 1; because btv->crop[1] may be | 2922 | mutex_unlock(&btv->lock); |
2897 | inconsistent with fh->width or fh->height and apps | 2923 | return 0; |
2898 | do not expect a change here. */ | 2924 | } |
2899 | 2925 | ||
2900 | crop->c = btv->crop[!!fh->do_crop].rect; | 2926 | static int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p) |
2927 | { | ||
2928 | struct bttv_fh *fh = f; | ||
2929 | struct bttv *btv = fh->btv; | ||
2901 | 2930 | ||
2902 | return 0; | 2931 | *p = v4l2_prio_max(&btv->prio); |
2903 | } | ||
2904 | case VIDIOC_S_CROP: | ||
2905 | { | ||
2906 | struct v4l2_crop *crop = arg; | ||
2907 | const struct v4l2_rect *b; | ||
2908 | struct bttv_crop c; | ||
2909 | __s32 b_left; | ||
2910 | __s32 b_top; | ||
2911 | __s32 b_right; | ||
2912 | __s32 b_bottom; | ||
2913 | |||
2914 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
2915 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | ||
2916 | return -EINVAL; | ||
2917 | 2932 | ||
2918 | retval = v4l2_prio_check(&btv->prio,&fh->prio); | 2933 | return 0; |
2919 | if (0 != retval) | 2934 | } |
2920 | return retval; | ||
2921 | 2935 | ||
2922 | /* Make sure tvnorm, vbi_end and the current cropping | 2936 | static int vidioc_s_priority(struct file *file, void *f, |
2923 | parameters remain consistent until we're done. Note | 2937 | enum v4l2_priority prio) |
2924 | read() may change vbi_end in check_alloc_btres(). */ | 2938 | { |
2925 | mutex_lock(&btv->lock); | 2939 | struct bttv_fh *fh = f; |
2940 | struct bttv *btv = fh->btv; | ||
2941 | |||
2942 | return v4l2_prio_change(&btv->prio, &fh->prio, prio); | ||
2943 | } | ||
2944 | |||
2945 | static int vidioc_cropcap(struct file *file, void *priv, | ||
2946 | struct v4l2_cropcap *cap) | ||
2947 | { | ||
2948 | struct bttv_fh *fh = priv; | ||
2949 | struct bttv *btv = fh->btv; | ||
2950 | |||
2951 | if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
2952 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | ||
2953 | return -EINVAL; | ||
2954 | |||
2955 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; | ||
2956 | |||
2957 | return 0; | ||
2958 | } | ||
2959 | |||
2960 | static int vidioc_g_crop(struct file *file, void *f, struct v4l2_crop *crop) | ||
2961 | { | ||
2962 | struct bttv_fh *fh = f; | ||
2963 | struct bttv *btv = fh->btv; | ||
2926 | 2964 | ||
2927 | retval = -EBUSY; | 2965 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && |
2966 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | ||
2967 | return -EINVAL; | ||
2928 | 2968 | ||
2929 | if (locked_btres(fh->btv, VIDEO_RESOURCES)) | 2969 | /* No fh->do_crop = 1; because btv->crop[1] may be |
2930 | goto btv_unlock_and_return; | 2970 | inconsistent with fh->width or fh->height and apps |
2971 | do not expect a change here. */ | ||
2931 | 2972 | ||
2932 | b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; | 2973 | crop->c = btv->crop[!!fh->do_crop].rect; |
2933 | 2974 | ||
2934 | b_left = b->left; | 2975 | return 0; |
2935 | b_right = b_left + b->width; | 2976 | } |
2936 | b_bottom = b->top + b->height; | 2977 | |
2978 | static int vidioc_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | ||
2979 | { | ||
2980 | struct bttv_fh *fh = f; | ||
2981 | struct bttv *btv = fh->btv; | ||
2982 | const struct v4l2_rect *b; | ||
2983 | int retval; | ||
2984 | struct bttv_crop c; | ||
2985 | __s32 b_left; | ||
2986 | __s32 b_top; | ||
2987 | __s32 b_right; | ||
2988 | __s32 b_bottom; | ||
2937 | 2989 | ||
2938 | b_top = max(b->top, btv->vbi_end); | 2990 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && |
2939 | if (b_top + 32 >= b_bottom) | 2991 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
2940 | goto btv_unlock_and_return; | 2992 | return -EINVAL; |
2941 | 2993 | ||
2942 | /* Min. scaled size 48 x 32. */ | 2994 | retval = v4l2_prio_check(&btv->prio, &fh->prio); |
2943 | c.rect.left = clamp(crop->c.left, b_left, b_right - 48); | 2995 | if (0 != retval) |
2944 | c.rect.left = min(c.rect.left, (__s32) MAX_HDELAY); | 2996 | return retval; |
2945 | 2997 | ||
2946 | c.rect.width = clamp(crop->c.width, | 2998 | /* Make sure tvnorm, vbi_end and the current cropping |
2947 | 48, b_right - c.rect.left); | 2999 | parameters remain consistent until we're done. Note |
3000 | read() may change vbi_end in check_alloc_btres(). */ | ||
3001 | mutex_lock(&btv->lock); | ||
2948 | 3002 | ||
2949 | c.rect.top = clamp(crop->c.top, b_top, b_bottom - 32); | 3003 | retval = -EBUSY; |
2950 | /* Top and height must be a multiple of two. */ | ||
2951 | c.rect.top = (c.rect.top + 1) & ~1; | ||
2952 | 3004 | ||
2953 | c.rect.height = clamp(crop->c.height, | 3005 | if (locked_btres(fh->btv, VIDEO_RESOURCES)) { |
2954 | 32, b_bottom - c.rect.top); | 3006 | mutex_unlock(&btv->lock); |
2955 | c.rect.height = (c.rect.height + 1) & ~1; | 3007 | return retval; |
3008 | } | ||
2956 | 3009 | ||
2957 | bttv_crop_calc_limits(&c); | 3010 | b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; |
2958 | 3011 | ||
2959 | btv->crop[1] = c; | 3012 | b_left = b->left; |
3013 | b_right = b_left + b->width; | ||
3014 | b_bottom = b->top + b->height; | ||
2960 | 3015 | ||
3016 | b_top = max(b->top, btv->vbi_end); | ||
3017 | if (b_top + 32 >= b_bottom) { | ||
2961 | mutex_unlock(&btv->lock); | 3018 | mutex_unlock(&btv->lock); |
3019 | return retval; | ||
3020 | } | ||
2962 | 3021 | ||
2963 | fh->do_crop = 1; | 3022 | /* Min. scaled size 48 x 32. */ |
3023 | c.rect.left = clamp(crop->c.left, b_left, b_right - 48); | ||
3024 | c.rect.left = min(c.rect.left, (__s32) MAX_HDELAY); | ||
2964 | 3025 | ||
2965 | mutex_lock(&fh->cap.lock); | 3026 | c.rect.width = clamp(crop->c.width, |
3027 | 48, b_right - c.rect.left); | ||
2966 | 3028 | ||
2967 | if (fh->width < c.min_scaled_width) { | 3029 | c.rect.top = clamp(crop->c.top, b_top, b_bottom - 32); |
2968 | fh->width = c.min_scaled_width; | 3030 | /* Top and height must be a multiple of two. */ |
2969 | btv->init.width = c.min_scaled_width; | 3031 | c.rect.top = (c.rect.top + 1) & ~1; |
2970 | } else if (fh->width > c.max_scaled_width) { | ||
2971 | fh->width = c.max_scaled_width; | ||
2972 | btv->init.width = c.max_scaled_width; | ||
2973 | } | ||
2974 | 3032 | ||
2975 | if (fh->height < c.min_scaled_height) { | 3033 | c.rect.height = clamp(crop->c.height, |
2976 | fh->height = c.min_scaled_height; | 3034 | 32, b_bottom - c.rect.top); |
2977 | btv->init.height = c.min_scaled_height; | 3035 | c.rect.height = (c.rect.height + 1) & ~1; |
2978 | } else if (fh->height > c.max_scaled_height) { | ||
2979 | fh->height = c.max_scaled_height; | ||
2980 | btv->init.height = c.max_scaled_height; | ||
2981 | } | ||
2982 | 3036 | ||
2983 | mutex_unlock(&fh->cap.lock); | 3037 | bttv_crop_calc_limits(&c); |
2984 | 3038 | ||
2985 | return 0; | 3039 | btv->crop[1] = c; |
3040 | |||
3041 | mutex_unlock(&btv->lock); | ||
3042 | |||
3043 | fh->do_crop = 1; | ||
3044 | |||
3045 | mutex_lock(&fh->cap.lock); | ||
3046 | |||
3047 | if (fh->width < c.min_scaled_width) { | ||
3048 | fh->width = c.min_scaled_width; | ||
3049 | btv->init.width = c.min_scaled_width; | ||
3050 | } else if (fh->width > c.max_scaled_width) { | ||
3051 | fh->width = c.max_scaled_width; | ||
3052 | btv->init.width = c.max_scaled_width; | ||
2986 | } | 3053 | } |
2987 | 3054 | ||
2988 | case VIDIOC_ENUMSTD: | 3055 | if (fh->height < c.min_scaled_height) { |
2989 | case VIDIOC_G_STD: | 3056 | fh->height = c.min_scaled_height; |
2990 | case VIDIOC_S_STD: | 3057 | btv->init.height = c.min_scaled_height; |
2991 | case VIDIOC_ENUMINPUT: | 3058 | } else if (fh->height > c.max_scaled_height) { |
2992 | case VIDIOC_G_INPUT: | 3059 | fh->height = c.max_scaled_height; |
2993 | case VIDIOC_S_INPUT: | 3060 | btv->init.height = c.max_scaled_height; |
2994 | case VIDIOC_S_TUNER: | ||
2995 | case VIDIOC_G_FREQUENCY: | ||
2996 | case VIDIOC_S_FREQUENCY: | ||
2997 | case VIDIOC_LOG_STATUS: | ||
2998 | case VIDIOC_G_CTRL: | ||
2999 | case VIDIOC_S_CTRL: | ||
3000 | case VIDIOC_DBG_G_REGISTER: | ||
3001 | case VIDIOC_DBG_S_REGISTER: | ||
3002 | return bttv_common_ioctls(btv,cmd,arg); | ||
3003 | default: | ||
3004 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | ||
3005 | bttv_do_ioctl); | ||
3006 | } | 3061 | } |
3007 | return 0; | ||
3008 | 3062 | ||
3009 | fh_unlock_and_return: | ||
3010 | mutex_unlock(&fh->cap.lock); | 3063 | mutex_unlock(&fh->cap.lock); |
3011 | return retval; | ||
3012 | 3064 | ||
3013 | btv_unlock_and_return: | 3065 | return 0; |
3014 | mutex_unlock(&btv->lock); | ||
3015 | return retval; | ||
3016 | } | 3066 | } |
3017 | 3067 | ||
3018 | static int bttv_ioctl(struct inode *inode, struct file *file, | 3068 | static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) |
3019 | unsigned int cmd, unsigned long arg) | ||
3020 | { | 3069 | { |
3021 | return video_usercopy(inode, file, cmd, arg, bttv_do_ioctl); | 3070 | strcpy(a->name, "audio"); |
3071 | return 0; | ||
3072 | } | ||
3073 | |||
3074 | static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) | ||
3075 | { | ||
3076 | return 0; | ||
3022 | } | 3077 | } |
3023 | 3078 | ||
3024 | static ssize_t bttv_read(struct file *file, char __user *data, | 3079 | static ssize_t bttv_read(struct file *file, char __user *data, |
@@ -3240,7 +3295,7 @@ static const struct file_operations bttv_fops = | |||
3240 | .owner = THIS_MODULE, | 3295 | .owner = THIS_MODULE, |
3241 | .open = bttv_open, | 3296 | .open = bttv_open, |
3242 | .release = bttv_release, | 3297 | .release = bttv_release, |
3243 | .ioctl = bttv_ioctl, | 3298 | .ioctl = video_ioctl2, |
3244 | .compat_ioctl = v4l_compat_ioctl32, | 3299 | .compat_ioctl = v4l_compat_ioctl32, |
3245 | .llseek = no_llseek, | 3300 | .llseek = no_llseek, |
3246 | .read = bttv_read, | 3301 | .read = bttv_read, |
@@ -3255,6 +3310,57 @@ static struct video_device bttv_video_template = | |||
3255 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, | 3310 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, |
3256 | .fops = &bttv_fops, | 3311 | .fops = &bttv_fops, |
3257 | .minor = -1, | 3312 | .minor = -1, |
3313 | .vidioc_querycap = vidioc_querycap, | ||
3314 | .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, | ||
3315 | .vidioc_g_fmt_cap = vidioc_g_fmt_cap, | ||
3316 | .vidioc_try_fmt_cap = vidioc_try_fmt_cap, | ||
3317 | .vidioc_s_fmt_cap = vidioc_s_fmt_cap, | ||
3318 | .vidioc_enum_fmt_overlay = vidioc_enum_fmt_overlay, | ||
3319 | .vidioc_g_fmt_overlay = vidioc_g_fmt_overlay, | ||
3320 | .vidioc_try_fmt_overlay = vidioc_try_fmt_overlay, | ||
3321 | .vidioc_s_fmt_overlay = vidioc_s_fmt_overlay, | ||
3322 | .vidioc_enum_fmt_vbi = vidioc_enum_fmt_vbi, | ||
3323 | .vidioc_g_fmt_vbi = vidioc_g_fmt_vbi, | ||
3324 | .vidioc_try_fmt_vbi = vidioc_try_fmt_vbi, | ||
3325 | .vidioc_s_fmt_vbi = vidioc_s_fmt_vbi, | ||
3326 | .vidioc_g_audio = vidioc_g_audio, | ||
3327 | .vidioc_s_audio = vidioc_s_audio, | ||
3328 | .vidioc_cropcap = vidioc_cropcap, | ||
3329 | .vidioc_reqbufs = vidioc_reqbufs, | ||
3330 | .vidioc_querybuf = vidioc_querybuf, | ||
3331 | .vidioc_qbuf = vidioc_qbuf, | ||
3332 | .vidioc_dqbuf = vidioc_dqbuf, | ||
3333 | .vidioc_s_std = vidioc_s_std, | ||
3334 | .vidioc_enum_input = vidioc_enum_input, | ||
3335 | .vidioc_g_input = vidioc_g_input, | ||
3336 | .vidioc_s_input = vidioc_s_input, | ||
3337 | .vidioc_queryctrl = vidioc_queryctrl, | ||
3338 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
3339 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
3340 | .vidioc_streamon = vidioc_streamon, | ||
3341 | .vidioc_streamoff = vidioc_streamoff, | ||
3342 | .vidioc_g_tuner = vidioc_g_tuner, | ||
3343 | .vidioc_s_tuner = vidioc_s_tuner, | ||
3344 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
3345 | .vidiocgmbuf = vidiocgmbuf, | ||
3346 | #endif | ||
3347 | .vidioc_g_crop = vidioc_g_crop, | ||
3348 | .vidioc_g_crop = vidioc_g_crop, | ||
3349 | .vidioc_s_crop = vidioc_s_crop, | ||
3350 | .vidioc_g_fbuf = vidioc_g_fbuf, | ||
3351 | .vidioc_s_fbuf = vidioc_s_fbuf, | ||
3352 | .vidioc_overlay = vidioc_overlay, | ||
3353 | .vidioc_g_priority = vidioc_g_priority, | ||
3354 | .vidioc_s_priority = vidioc_s_priority, | ||
3355 | .vidioc_g_parm = vidioc_g_parm, | ||
3356 | .vidioc_g_frequency = vidioc_g_frequency, | ||
3357 | .vidioc_s_frequency = vidioc_s_frequency, | ||
3358 | .vidioc_log_status = vidioc_log_status, | ||
3359 | .vidioc_querystd = vidioc_querystd, | ||
3360 | .vidioc_g_register = vidioc_g_register, | ||
3361 | .vidioc_s_register = vidioc_s_register, | ||
3362 | .tvnorms = BTTV_NORMS, | ||
3363 | .current_norm = V4L2_STD_PAL, | ||
3258 | }; | 3364 | }; |
3259 | 3365 | ||
3260 | static struct video_device bttv_vbi_template = | 3366 | static struct video_device bttv_vbi_template = |
@@ -3301,7 +3407,7 @@ static int radio_open(struct inode *inode, struct file *file) | |||
3301 | 3407 | ||
3302 | static int radio_release(struct inode *inode, struct file *file) | 3408 | static int radio_release(struct inode *inode, struct file *file) |
3303 | { | 3409 | { |
3304 | struct bttv *btv = file->private_data; | 3410 | struct bttv *btv = file->private_data; |
3305 | struct rds_command cmd; | 3411 | struct rds_command cmd; |
3306 | 3412 | ||
3307 | btv->radio_user--; | 3413 | btv->radio_user--; |
@@ -3311,67 +3417,116 @@ static int radio_release(struct inode *inode, struct file *file) | |||
3311 | return 0; | 3417 | return 0; |
3312 | } | 3418 | } |
3313 | 3419 | ||
3314 | static int radio_do_ioctl(struct inode *inode, struct file *file, | 3420 | static int radio_querycap(struct file *file, void *priv, |
3315 | unsigned int cmd, void *arg) | 3421 | struct v4l2_capability *cap) |
3316 | { | 3422 | { |
3317 | struct bttv *btv = file->private_data; | 3423 | struct bttv_fh *fh = priv; |
3424 | struct bttv *btv = fh->btv; | ||
3318 | 3425 | ||
3319 | switch (cmd) { | 3426 | strcpy(cap->driver, "bttv"); |
3320 | case VIDIOC_QUERYCAP: | 3427 | strlcpy(cap->card, btv->radio_dev->name, sizeof(cap->card)); |
3321 | { | 3428 | sprintf(cap->bus_info, "PCI:%s", pci_name(btv->c.pci)); |
3322 | struct v4l2_capability *cap = arg; | 3429 | cap->version = BTTV_VERSION_CODE; |
3323 | 3430 | cap->capabilities = V4L2_CAP_TUNER; | |
3324 | memset(cap,0,sizeof(*cap)); | ||
3325 | strcpy(cap->driver, "bttv"); | ||
3326 | strlcpy(cap->card, btv->radio_dev->name,sizeof(cap->card)); | ||
3327 | sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci)); | ||
3328 | cap->version = BTTV_VERSION_CODE; | ||
3329 | cap->capabilities = V4L2_CAP_TUNER; | ||
3330 | return 0; | ||
3331 | } | ||
3332 | case VIDIOC_G_TUNER: | ||
3333 | { | ||
3334 | struct v4l2_tuner *t = arg; | ||
3335 | 3431 | ||
3336 | if (UNSET == bttv_tvcards[btv->c.type].tuner) | 3432 | return 0; |
3337 | return -EINVAL; | 3433 | } |
3338 | if (0 != t->index) | ||
3339 | return -EINVAL; | ||
3340 | mutex_lock(&btv->lock); | ||
3341 | memset(t,0,sizeof(*t)); | ||
3342 | strcpy(t->name, "Radio"); | ||
3343 | t->type = V4L2_TUNER_RADIO; | ||
3344 | 3434 | ||
3345 | bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); | 3435 | static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) |
3436 | { | ||
3437 | struct bttv_fh *fh = priv; | ||
3438 | struct bttv *btv = fh->btv; | ||
3346 | 3439 | ||
3347 | if (btv->audio_mode_gpio) { | 3440 | if (UNSET == bttv_tvcards[btv->c.type].tuner) |
3348 | btv->audio_mode_gpio (btv,t,0); | 3441 | return -EINVAL; |
3349 | } | 3442 | if (0 != t->index) |
3443 | return -EINVAL; | ||
3444 | mutex_lock(&btv->lock); | ||
3445 | memset(t, 0, sizeof(*t)); | ||
3446 | strcpy(t->name, "Radio"); | ||
3447 | t->type = V4L2_TUNER_RADIO; | ||
3350 | 3448 | ||
3351 | mutex_unlock(&btv->lock); | 3449 | bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); |
3450 | |||
3451 | if (btv->audio_mode_gpio) | ||
3452 | btv->audio_mode_gpio(btv, t, 0); | ||
3453 | |||
3454 | mutex_unlock(&btv->lock); | ||
3352 | 3455 | ||
3353 | return 0; | ||
3354 | } | ||
3355 | case VIDIOC_S_TUNER: | ||
3356 | case VIDIOC_G_FREQUENCY: | ||
3357 | case VIDIOC_S_FREQUENCY: | ||
3358 | case VIDIOC_G_CTRL: | ||
3359 | case VIDIOC_S_CTRL: | ||
3360 | case VIDIOC_LOG_STATUS: | ||
3361 | case VIDIOC_DBG_G_REGISTER: | ||
3362 | case VIDIOC_DBG_S_REGISTER: | ||
3363 | return bttv_common_ioctls(btv,cmd,arg); | ||
3364 | default: | ||
3365 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | ||
3366 | radio_do_ioctl); | ||
3367 | } | ||
3368 | return 0; | 3456 | return 0; |
3369 | } | 3457 | } |
3370 | 3458 | ||
3371 | static int radio_ioctl(struct inode *inode, struct file *file, | 3459 | static int radio_enum_input(struct file *file, void *priv, |
3372 | unsigned int cmd, unsigned long arg) | 3460 | struct v4l2_input *i) |
3373 | { | 3461 | { |
3374 | return video_usercopy(inode, file, cmd, arg, radio_do_ioctl); | 3462 | if (i->index != 0) |
3463 | return -EINVAL; | ||
3464 | |||
3465 | strcpy(i->name, "Radio"); | ||
3466 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
3467 | |||
3468 | return 0; | ||
3469 | } | ||
3470 | |||
3471 | static int radio_g_audio(struct file *file, void *priv, | ||
3472 | struct v4l2_audio *a) | ||
3473 | { | ||
3474 | memset(a, 0, sizeof(*a)); | ||
3475 | strcpy(a->name, "Radio"); | ||
3476 | return 0; | ||
3477 | } | ||
3478 | |||
3479 | static int radio_s_tuner(struct file *file, void *priv, | ||
3480 | struct v4l2_tuner *t) | ||
3481 | { | ||
3482 | struct bttv_fh *fh = priv; | ||
3483 | struct bttv *btv = fh->btv; | ||
3484 | |||
3485 | if (0 != t->index) | ||
3486 | return -EINVAL; | ||
3487 | |||
3488 | bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); | ||
3489 | return 0; | ||
3490 | } | ||
3491 | |||
3492 | static int radio_s_audio(struct file *file, void *priv, | ||
3493 | struct v4l2_audio *a) | ||
3494 | { | ||
3495 | return 0; | ||
3496 | } | ||
3497 | |||
3498 | static int radio_s_input(struct file *filp, void *priv, unsigned int i) | ||
3499 | { | ||
3500 | return 0; | ||
3501 | } | ||
3502 | |||
3503 | static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm) | ||
3504 | { | ||
3505 | return 0; | ||
3506 | } | ||
3507 | |||
3508 | static int radio_queryctrl(struct file *file, void *priv, | ||
3509 | struct v4l2_queryctrl *c) | ||
3510 | { | ||
3511 | const struct v4l2_queryctrl *ctrl; | ||
3512 | |||
3513 | if (c->id < V4L2_CID_BASE || | ||
3514 | c->id >= V4L2_CID_LASTP1) | ||
3515 | return -EINVAL; | ||
3516 | |||
3517 | if (c->id == V4L2_CID_AUDIO_MUTE) { | ||
3518 | ctrl = ctrl_by_id(c->id); | ||
3519 | *c = *ctrl; | ||
3520 | } else | ||
3521 | *c = no_ctl; | ||
3522 | |||
3523 | return 0; | ||
3524 | } | ||
3525 | |||
3526 | static int radio_g_input(struct file *filp, void *priv, unsigned int *i) | ||
3527 | { | ||
3528 | *i = 0; | ||
3529 | return 0; | ||
3375 | } | 3530 | } |
3376 | 3531 | ||
3377 | static ssize_t radio_read(struct file *file, char __user *data, | 3532 | static ssize_t radio_read(struct file *file, char __user *data, |
@@ -3407,7 +3562,7 @@ static const struct file_operations radio_fops = | |||
3407 | .open = radio_open, | 3562 | .open = radio_open, |
3408 | .read = radio_read, | 3563 | .read = radio_read, |
3409 | .release = radio_release, | 3564 | .release = radio_release, |
3410 | .ioctl = radio_ioctl, | 3565 | .ioctl = video_ioctl2, |
3411 | .llseek = no_llseek, | 3566 | .llseek = no_llseek, |
3412 | .poll = radio_poll, | 3567 | .poll = radio_poll, |
3413 | }; | 3568 | }; |
@@ -3418,6 +3573,20 @@ static struct video_device radio_template = | |||
3418 | .type = VID_TYPE_TUNER, | 3573 | .type = VID_TYPE_TUNER, |
3419 | .fops = &radio_fops, | 3574 | .fops = &radio_fops, |
3420 | .minor = -1, | 3575 | .minor = -1, |
3576 | .vidioc_querycap = radio_querycap, | ||
3577 | .vidioc_g_tuner = radio_g_tuner, | ||
3578 | .vidioc_enum_input = radio_enum_input, | ||
3579 | .vidioc_g_audio = radio_g_audio, | ||
3580 | .vidioc_s_tuner = radio_s_tuner, | ||
3581 | .vidioc_s_audio = radio_s_audio, | ||
3582 | .vidioc_s_input = radio_s_input, | ||
3583 | .vidioc_s_std = radio_s_std, | ||
3584 | .vidioc_queryctrl = radio_queryctrl, | ||
3585 | .vidioc_g_input = radio_g_input, | ||
3586 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
3587 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
3588 | .vidioc_g_frequency = vidioc_g_frequency, | ||
3589 | .vidioc_s_frequency = vidioc_s_frequency, | ||
3421 | }; | 3590 | }; |
3422 | 3591 | ||
3423 | /* ----------------------------------------------------------------------- */ | 3592 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c index b924f05e3b7..da2708176aa 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bt8xx/bttv-vbi.c | |||
@@ -236,10 +236,8 @@ struct videobuf_queue_ops bttv_vbi_qops = { | |||
236 | 236 | ||
237 | /* ----------------------------------------------------------------------- */ | 237 | /* ----------------------------------------------------------------------- */ |
238 | 238 | ||
239 | static int | 239 | static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm, |
240 | try_fmt (struct v4l2_vbi_format * f, | 240 | __s32 crop_start) |
241 | const struct bttv_tvnorm * tvnorm, | ||
242 | __s32 crop_start) | ||
243 | { | 241 | { |
244 | __s32 min_start, max_start, max_end, f2_offset; | 242 | __s32 min_start, max_start, max_end, f2_offset; |
245 | unsigned int i; | 243 | unsigned int i; |
@@ -305,10 +303,9 @@ try_fmt (struct v4l2_vbi_format * f, | |||
305 | return 0; | 303 | return 0; |
306 | } | 304 | } |
307 | 305 | ||
308 | int | 306 | int vidioc_try_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt) |
309 | bttv_vbi_try_fmt (struct bttv_fh * fh, | ||
310 | struct v4l2_vbi_format * f) | ||
311 | { | 307 | { |
308 | struct bttv_fh *fh = f; | ||
312 | struct bttv *btv = fh->btv; | 309 | struct bttv *btv = fh->btv; |
313 | const struct bttv_tvnorm *tvnorm; | 310 | const struct bttv_tvnorm *tvnorm; |
314 | __s32 crop_start; | 311 | __s32 crop_start; |
@@ -320,13 +317,13 @@ bttv_vbi_try_fmt (struct bttv_fh * fh, | |||
320 | 317 | ||
321 | mutex_unlock(&btv->lock); | 318 | mutex_unlock(&btv->lock); |
322 | 319 | ||
323 | return try_fmt(f, tvnorm, crop_start); | 320 | return try_fmt(&frt->fmt.vbi, tvnorm, crop_start); |
324 | } | 321 | } |
325 | 322 | ||
326 | int | 323 | |
327 | bttv_vbi_set_fmt (struct bttv_fh * fh, | 324 | int vidioc_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt) |
328 | struct v4l2_vbi_format * f) | ||
329 | { | 325 | { |
326 | struct bttv_fh *fh = f; | ||
330 | struct bttv *btv = fh->btv; | 327 | struct bttv *btv = fh->btv; |
331 | const struct bttv_tvnorm *tvnorm; | 328 | const struct bttv_tvnorm *tvnorm; |
332 | __s32 start1, end; | 329 | __s32 start1, end; |
@@ -340,11 +337,12 @@ bttv_vbi_set_fmt (struct bttv_fh * fh, | |||
340 | 337 | ||
341 | tvnorm = &bttv_tvnorms[btv->tvnorm]; | 338 | tvnorm = &bttv_tvnorms[btv->tvnorm]; |
342 | 339 | ||
343 | rc = try_fmt(f, tvnorm, btv->crop_start); | 340 | rc = try_fmt(&frt->fmt.vbi, tvnorm, btv->crop_start); |
344 | if (0 != rc) | 341 | if (0 != rc) |
345 | goto fail; | 342 | goto fail; |
346 | 343 | ||
347 | start1 = f->start[1] - tvnorm->vbistart[1] + tvnorm->vbistart[0]; | 344 | start1 = frt->fmt.vbi.start[1] - tvnorm->vbistart[1] + |
345 | tvnorm->vbistart[0]; | ||
348 | 346 | ||
349 | /* First possible line of video capturing. Should be | 347 | /* First possible line of video capturing. Should be |
350 | max(f->start[0] + f->count[0], start1 + f->count[1]) * 2 | 348 | max(f->start[0] + f->count[0], start1 + f->count[1]) * 2 |
@@ -352,11 +350,11 @@ bttv_vbi_set_fmt (struct bttv_fh * fh, | |||
352 | pretend the VBI and video capture window may overlap, | 350 | pretend the VBI and video capture window may overlap, |
353 | so end = start + 1, the lowest possible value, times two | 351 | so end = start + 1, the lowest possible value, times two |
354 | because vbi_fmt.end counts field lines times two. */ | 352 | because vbi_fmt.end counts field lines times two. */ |
355 | end = max(f->start[0], start1) * 2 + 2; | 353 | end = max(frt->fmt.vbi.start[0], start1) * 2 + 2; |
356 | 354 | ||
357 | mutex_lock(&fh->vbi.lock); | 355 | mutex_lock(&fh->vbi.lock); |
358 | 356 | ||
359 | fh->vbi_fmt.fmt = *f; | 357 | fh->vbi_fmt.fmt = frt->fmt.vbi; |
360 | fh->vbi_fmt.tvnorm = tvnorm; | 358 | fh->vbi_fmt.tvnorm = tvnorm; |
361 | fh->vbi_fmt.end = end; | 359 | fh->vbi_fmt.end = end; |
362 | 360 | ||
@@ -370,13 +368,13 @@ bttv_vbi_set_fmt (struct bttv_fh * fh, | |||
370 | return rc; | 368 | return rc; |
371 | } | 369 | } |
372 | 370 | ||
373 | void | 371 | |
374 | bttv_vbi_get_fmt (struct bttv_fh * fh, | 372 | int vidioc_g_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt) |
375 | struct v4l2_vbi_format * f) | ||
376 | { | 373 | { |
374 | struct bttv_fh *fh = f; | ||
377 | const struct bttv_tvnorm *tvnorm; | 375 | const struct bttv_tvnorm *tvnorm; |
378 | 376 | ||
379 | *f = fh->vbi_fmt.fmt; | 377 | frt->fmt.vbi = fh->vbi_fmt.fmt; |
380 | 378 | ||
381 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; | 379 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; |
382 | 380 | ||
@@ -391,28 +389,28 @@ bttv_vbi_get_fmt (struct bttv_fh * fh, | |||
391 | max_end = (tvnorm->cropcap.bounds.top | 389 | max_end = (tvnorm->cropcap.bounds.top |
392 | + tvnorm->cropcap.bounds.height) >> 1; | 390 | + tvnorm->cropcap.bounds.height) >> 1; |
393 | 391 | ||
394 | f->sampling_rate = tvnorm->Fsc; | 392 | frt->fmt.vbi.sampling_rate = tvnorm->Fsc; |
395 | 393 | ||
396 | for (i = 0; i < 2; ++i) { | 394 | for (i = 0; i < 2; ++i) { |
397 | __s32 new_start; | 395 | __s32 new_start; |
398 | 396 | ||
399 | new_start = f->start[i] | 397 | new_start = frt->fmt.vbi.start[i] |
400 | + tvnorm->vbistart[i] | 398 | + tvnorm->vbistart[i] |
401 | - fh->vbi_fmt.tvnorm->vbistart[i]; | 399 | - fh->vbi_fmt.tvnorm->vbistart[i]; |
402 | 400 | ||
403 | f->start[i] = min(new_start, max_end - 1); | 401 | frt->fmt.vbi.start[i] = min(new_start, max_end - 1); |
404 | f->count[i] = min((__s32) f->count[i], | 402 | frt->fmt.vbi.count[i] = |
405 | max_end - f->start[i]); | 403 | min((__s32) frt->fmt.vbi.count[i], |
404 | max_end - frt->fmt.vbi.start[i]); | ||
406 | 405 | ||
407 | max_end += tvnorm->vbistart[1] | 406 | max_end += tvnorm->vbistart[1] |
408 | - tvnorm->vbistart[0]; | 407 | - tvnorm->vbistart[0]; |
409 | } | 408 | } |
410 | } | 409 | } |
410 | return 0; | ||
411 | } | 411 | } |
412 | 412 | ||
413 | void | 413 | void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm) |
414 | bttv_vbi_fmt_reset (struct bttv_vbi_fmt * f, | ||
415 | int norm) | ||
416 | { | 414 | { |
417 | const struct bttv_tvnorm *tvnorm; | 415 | const struct bttv_tvnorm *tvnorm; |
418 | unsigned int real_samples_per_line; | 416 | unsigned int real_samples_per_line; |
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index 4a02f0a8a46..260303065c1 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h | |||
@@ -84,6 +84,11 @@ | |||
84 | 84 | ||
85 | #define clamp(x, low, high) min (max (low, x), high) | 85 | #define clamp(x, low, high) min (max (low, x), high) |
86 | 86 | ||
87 | #define BTTV_NORMS (\ | ||
88 | V4L2_STD_PAL | V4L2_STD_PAL_N | \ | ||
89 | V4L2_STD_PAL_Nc | V4L2_STD_SECAM | \ | ||
90 | V4L2_STD_NTSC | V4L2_STD_PAL_M | \ | ||
91 | V4L2_STD_PAL_60) | ||
87 | /* ---------------------------------------------------------- */ | 92 | /* ---------------------------------------------------------- */ |
88 | 93 | ||
89 | struct bttv_tvnorm { | 94 | struct bttv_tvnorm { |
@@ -252,9 +257,9 @@ int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, | |||
252 | /* ---------------------------------------------------------- */ | 257 | /* ---------------------------------------------------------- */ |
253 | /* bttv-vbi.c */ | 258 | /* bttv-vbi.c */ |
254 | 259 | ||
255 | int bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f); | 260 | int vidioc_try_fmt_vbi(struct file *file, void *fh, struct v4l2_format *f); |
256 | void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f); | 261 | int vidioc_g_fmt_vbi(struct file *file, void *fh, struct v4l2_format *f); |
257 | int bttv_vbi_set_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f); | 262 | int vidioc_s_fmt_vbi(struct file *file, void *fh, struct v4l2_format *f); |
258 | 263 | ||
259 | extern struct videobuf_queue_ops bttv_vbi_qops; | 264 | extern struct videobuf_queue_ops bttv_vbi_qops; |
260 | 265 | ||