diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-02-15 03:51:21 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-05 13:34:24 -0500 |
commit | 192f1e78cb9cbc1a2cee866f5e03a52857e648b6 (patch) | |
tree | b7ab43660d93b06b054210ad2f3a12b23c8b8be6 /drivers/media/usb/s2255 | |
parent | 4ca286610f664acf3153634f3930acd2de993a9f (diff) |
[media] s2255: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/s2255')
-rw-r--r-- | drivers/media/usb/s2255/s2255drv.c | 172 |
1 files changed, 55 insertions, 117 deletions
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 498c57ea5d32..2dcb29b647f0 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <media/v4l2-common.h> | 47 | #include <media/v4l2-common.h> |
48 | #include <media/v4l2-device.h> | 48 | #include <media/v4l2-device.h> |
49 | #include <media/v4l2-ioctl.h> | 49 | #include <media/v4l2-ioctl.h> |
50 | #include <media/v4l2-ctrls.h> | ||
50 | #include <linux/vmalloc.h> | 51 | #include <linux/vmalloc.h> |
51 | #include <linux/usb.h> | 52 | #include <linux/usb.h> |
52 | 53 | ||
@@ -217,6 +218,7 @@ struct s2255_dev; | |||
217 | 218 | ||
218 | struct s2255_channel { | 219 | struct s2255_channel { |
219 | struct video_device vdev; | 220 | struct video_device vdev; |
221 | struct v4l2_ctrl_handler hdl; | ||
220 | int resources; | 222 | int resources; |
221 | struct s2255_dmaqueue vidq; | 223 | struct s2255_dmaqueue vidq; |
222 | struct s2255_bufferi buffer; | 224 | struct s2255_bufferi buffer; |
@@ -336,7 +338,7 @@ struct s2255_fh { | |||
336 | */ | 338 | */ |
337 | #define S2255_V4L2_YC_ON 1 | 339 | #define S2255_V4L2_YC_ON 1 |
338 | #define S2255_V4L2_YC_OFF 0 | 340 | #define S2255_V4L2_YC_OFF 0 |
339 | #define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0) | 341 | #define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0) |
340 | 342 | ||
341 | /* frame prefix size (sent once every frame) */ | 343 | /* frame prefix size (sent once every frame) */ |
342 | #define PREFIX_SIZE 512 | 344 | #define PREFIX_SIZE 512 |
@@ -810,28 +812,6 @@ static void res_free(struct s2255_fh *fh) | |||
810 | dprintk(1, "res: put\n"); | 812 | dprintk(1, "res: put\n"); |
811 | } | 813 | } |
812 | 814 | ||
813 | static int vidioc_querymenu(struct file *file, void *priv, | ||
814 | struct v4l2_querymenu *qmenu) | ||
815 | { | ||
816 | static const char *colorfilter[] = { | ||
817 | "Off", | ||
818 | "On", | ||
819 | NULL | ||
820 | }; | ||
821 | if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) { | ||
822 | int i; | ||
823 | const char **menu_items = colorfilter; | ||
824 | for (i = 0; i < qmenu->index && menu_items[i]; i++) | ||
825 | ; /* do nothing (from v4l2-common.c) */ | ||
826 | if (menu_items[i] == NULL || menu_items[i][0] == '\0') | ||
827 | return -EINVAL; | ||
828 | strlcpy(qmenu->name, menu_items[qmenu->index], | ||
829 | sizeof(qmenu->name)); | ||
830 | return 0; | ||
831 | } | ||
832 | return v4l2_ctrl_query_menu(qmenu, NULL, NULL); | ||
833 | } | ||
834 | |||
835 | static int vidioc_querycap(struct file *file, void *priv, | 815 | static int vidioc_querycap(struct file *file, void *priv, |
836 | struct v4l2_capability *cap) | 816 | struct v4l2_capability *cap) |
837 | { | 817 | { |
@@ -1427,109 +1407,32 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | |||
1427 | return 0; | 1407 | return 0; |
1428 | } | 1408 | } |
1429 | 1409 | ||
1430 | /* --- controls ---------------------------------------------- */ | 1410 | static int s2255_s_ctrl(struct v4l2_ctrl *ctrl) |
1431 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
1432 | struct v4l2_queryctrl *qc) | ||
1433 | { | 1411 | { |
1434 | struct s2255_fh *fh = priv; | 1412 | struct s2255_channel *channel = |
1435 | struct s2255_channel *channel = fh->channel; | 1413 | container_of(ctrl->handler, struct s2255_channel, hdl); |
1436 | struct s2255_dev *dev = fh->dev; | ||
1437 | switch (qc->id) { | ||
1438 | case V4L2_CID_BRIGHTNESS: | ||
1439 | v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT); | ||
1440 | break; | ||
1441 | case V4L2_CID_CONTRAST: | ||
1442 | v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST); | ||
1443 | break; | ||
1444 | case V4L2_CID_SATURATION: | ||
1445 | v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION); | ||
1446 | break; | ||
1447 | case V4L2_CID_HUE: | ||
1448 | v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE); | ||
1449 | break; | ||
1450 | case V4L2_CID_PRIVATE_COLORFILTER: | ||
1451 | if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) | ||
1452 | return -EINVAL; | ||
1453 | if ((dev->pid == 0x2257) && (channel->idx > 1)) | ||
1454 | return -EINVAL; | ||
1455 | strlcpy(qc->name, "Color Filter", sizeof(qc->name)); | ||
1456 | qc->type = V4L2_CTRL_TYPE_MENU; | ||
1457 | qc->minimum = 0; | ||
1458 | qc->maximum = 1; | ||
1459 | qc->step = 1; | ||
1460 | qc->default_value = 1; | ||
1461 | qc->flags = 0; | ||
1462 | break; | ||
1463 | default: | ||
1464 | return -EINVAL; | ||
1465 | } | ||
1466 | dprintk(4, "%s, id %d\n", __func__, qc->id); | ||
1467 | return 0; | ||
1468 | } | ||
1469 | |||
1470 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
1471 | struct v4l2_control *ctrl) | ||
1472 | { | ||
1473 | struct s2255_fh *fh = priv; | ||
1474 | struct s2255_dev *dev = fh->dev; | ||
1475 | struct s2255_channel *channel = fh->channel; | ||
1476 | switch (ctrl->id) { | ||
1477 | case V4L2_CID_BRIGHTNESS: | ||
1478 | ctrl->value = channel->mode.bright; | ||
1479 | break; | ||
1480 | case V4L2_CID_CONTRAST: | ||
1481 | ctrl->value = channel->mode.contrast; | ||
1482 | break; | ||
1483 | case V4L2_CID_SATURATION: | ||
1484 | ctrl->value = channel->mode.saturation; | ||
1485 | break; | ||
1486 | case V4L2_CID_HUE: | ||
1487 | ctrl->value = channel->mode.hue; | ||
1488 | break; | ||
1489 | case V4L2_CID_PRIVATE_COLORFILTER: | ||
1490 | if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) | ||
1491 | return -EINVAL; | ||
1492 | if ((dev->pid == 0x2257) && (channel->idx > 1)) | ||
1493 | return -EINVAL; | ||
1494 | ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16); | ||
1495 | break; | ||
1496 | default: | ||
1497 | return -EINVAL; | ||
1498 | } | ||
1499 | dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value); | ||
1500 | return 0; | ||
1501 | } | ||
1502 | |||
1503 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
1504 | struct v4l2_control *ctrl) | ||
1505 | { | ||
1506 | struct s2255_fh *fh = priv; | ||
1507 | struct s2255_channel *channel = fh->channel; | ||
1508 | struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); | ||
1509 | struct s2255_mode mode; | 1414 | struct s2255_mode mode; |
1415 | |||
1510 | mode = channel->mode; | 1416 | mode = channel->mode; |
1511 | dprintk(4, "%s\n", __func__); | 1417 | dprintk(4, "%s\n", __func__); |
1418 | |||
1512 | /* update the mode to the corresponding value */ | 1419 | /* update the mode to the corresponding value */ |
1513 | switch (ctrl->id) { | 1420 | switch (ctrl->id) { |
1514 | case V4L2_CID_BRIGHTNESS: | 1421 | case V4L2_CID_BRIGHTNESS: |
1515 | mode.bright = ctrl->value; | 1422 | mode.bright = ctrl->val; |
1516 | break; | 1423 | break; |
1517 | case V4L2_CID_CONTRAST: | 1424 | case V4L2_CID_CONTRAST: |
1518 | mode.contrast = ctrl->value; | 1425 | mode.contrast = ctrl->val; |
1519 | break; | 1426 | break; |
1520 | case V4L2_CID_HUE: | 1427 | case V4L2_CID_HUE: |
1521 | mode.hue = ctrl->value; | 1428 | mode.hue = ctrl->val; |
1522 | break; | 1429 | break; |
1523 | case V4L2_CID_SATURATION: | 1430 | case V4L2_CID_SATURATION: |
1524 | mode.saturation = ctrl->value; | 1431 | mode.saturation = ctrl->val; |
1525 | break; | 1432 | break; |
1526 | case V4L2_CID_PRIVATE_COLORFILTER: | 1433 | case V4L2_CID_S2255_COLORFILTER: |
1527 | if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) | ||
1528 | return -EINVAL; | ||
1529 | if ((dev->pid == 0x2257) && (channel->idx > 1)) | ||
1530 | return -EINVAL; | ||
1531 | mode.color &= ~MASK_INPUT_TYPE; | 1434 | mode.color &= ~MASK_INPUT_TYPE; |
1532 | mode.color |= ((ctrl->value ? 0 : 1) << 16); | 1435 | mode.color |= !ctrl->val << 16; |
1533 | break; | 1436 | break; |
1534 | default: | 1437 | default: |
1535 | return -EINVAL; | 1438 | return -EINVAL; |
@@ -1539,7 +1442,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1539 | some V4L programs restart stream unnecessarily | 1442 | some V4L programs restart stream unnecessarily |
1540 | after a s_crtl. | 1443 | after a s_crtl. |
1541 | */ | 1444 | */ |
1542 | s2255_set_mode(fh->channel, &mode); | 1445 | s2255_set_mode(channel, &mode); |
1543 | return 0; | 1446 | return 0; |
1544 | } | 1447 | } |
1545 | 1448 | ||
@@ -1886,7 +1789,6 @@ static const struct v4l2_file_operations s2255_fops_v4l = { | |||
1886 | }; | 1789 | }; |
1887 | 1790 | ||
1888 | static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | 1791 | static const struct v4l2_ioctl_ops s2255_ioctl_ops = { |
1889 | .vidioc_querymenu = vidioc_querymenu, | ||
1890 | .vidioc_querycap = vidioc_querycap, | 1792 | .vidioc_querycap = vidioc_querycap, |
1891 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | 1793 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, |
1892 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | 1794 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, |
@@ -1900,9 +1802,6 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | |||
1900 | .vidioc_enum_input = vidioc_enum_input, | 1802 | .vidioc_enum_input = vidioc_enum_input, |
1901 | .vidioc_g_input = vidioc_g_input, | 1803 | .vidioc_g_input = vidioc_g_input, |
1902 | .vidioc_s_input = vidioc_s_input, | 1804 | .vidioc_s_input = vidioc_s_input, |
1903 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1904 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1905 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1906 | .vidioc_streamon = vidioc_streamon, | 1805 | .vidioc_streamon = vidioc_streamon, |
1907 | .vidioc_streamoff = vidioc_streamoff, | 1806 | .vidioc_streamoff = vidioc_streamoff, |
1908 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, | 1807 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, |
@@ -1915,8 +1814,13 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | |||
1915 | static void s2255_video_device_release(struct video_device *vdev) | 1814 | static void s2255_video_device_release(struct video_device *vdev) |
1916 | { | 1815 | { |
1917 | struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev); | 1816 | struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev); |
1918 | dprintk(4, "%s, chnls: %d \n", __func__, | 1817 | struct s2255_channel *channel = |
1818 | container_of(vdev, struct s2255_channel, vdev); | ||
1819 | |||
1820 | v4l2_ctrl_handler_free(&channel->hdl); | ||
1821 | dprintk(4, "%s, chnls: %d\n", __func__, | ||
1919 | atomic_read(&dev->num_channels)); | 1822 | atomic_read(&dev->num_channels)); |
1823 | |||
1920 | if (atomic_dec_and_test(&dev->num_channels)) | 1824 | if (atomic_dec_and_test(&dev->num_channels)) |
1921 | s2255_destroy(dev); | 1825 | s2255_destroy(dev); |
1922 | return; | 1826 | return; |
@@ -1931,6 +1835,20 @@ static struct video_device template = { | |||
1931 | .current_norm = V4L2_STD_NTSC_M, | 1835 | .current_norm = V4L2_STD_NTSC_M, |
1932 | }; | 1836 | }; |
1933 | 1837 | ||
1838 | static const struct v4l2_ctrl_ops s2255_ctrl_ops = { | ||
1839 | .s_ctrl = s2255_s_ctrl, | ||
1840 | }; | ||
1841 | |||
1842 | static const struct v4l2_ctrl_config color_filter_ctrl = { | ||
1843 | .ops = &s2255_ctrl_ops, | ||
1844 | .name = "Color Filter", | ||
1845 | .id = V4L2_CID_S2255_COLORFILTER, | ||
1846 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1847 | .max = 1, | ||
1848 | .step = 1, | ||
1849 | .def = 1, | ||
1850 | }; | ||
1851 | |||
1934 | static int s2255_probe_v4l(struct s2255_dev *dev) | 1852 | static int s2255_probe_v4l(struct s2255_dev *dev) |
1935 | { | 1853 | { |
1936 | int ret; | 1854 | int ret; |
@@ -1945,9 +1863,29 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1945 | for (i = 0; i < MAX_CHANNELS; i++) { | 1863 | for (i = 0; i < MAX_CHANNELS; i++) { |
1946 | channel = &dev->channel[i]; | 1864 | channel = &dev->channel[i]; |
1947 | INIT_LIST_HEAD(&channel->vidq.active); | 1865 | INIT_LIST_HEAD(&channel->vidq.active); |
1866 | |||
1867 | v4l2_ctrl_handler_init(&channel->hdl, 5); | ||
1868 | v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, | ||
1869 | V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT); | ||
1870 | v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, | ||
1871 | V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST); | ||
1872 | v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, | ||
1873 | V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION); | ||
1874 | v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, | ||
1875 | V4L2_CID_HUE, 0, 255, 1, DEF_HUE); | ||
1876 | if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER && | ||
1877 | (dev->pid != 0x2257 || channel->idx <= 1)) | ||
1878 | v4l2_ctrl_new_custom(&channel->hdl, &color_filter_ctrl, NULL); | ||
1879 | if (channel->hdl.error) { | ||
1880 | ret = channel->hdl.error; | ||
1881 | v4l2_ctrl_handler_free(&channel->hdl); | ||
1882 | dev_err(&dev->udev->dev, "couldn't register control\n"); | ||
1883 | break; | ||
1884 | } | ||
1948 | channel->vidq.dev = dev; | 1885 | channel->vidq.dev = dev; |
1949 | /* register 4 video devices */ | 1886 | /* register 4 video devices */ |
1950 | channel->vdev = template; | 1887 | channel->vdev = template; |
1888 | channel->vdev.ctrl_handler = &channel->hdl; | ||
1951 | channel->vdev.lock = &dev->lock; | 1889 | channel->vdev.lock = &dev->lock; |
1952 | channel->vdev.v4l2_dev = &dev->v4l2_dev; | 1890 | channel->vdev.v4l2_dev = &dev->v4l2_dev; |
1953 | video_set_drvdata(&channel->vdev, channel); | 1891 | video_set_drvdata(&channel->vdev, channel); |