aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/s2255
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-02-15 03:51:21 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-05 13:34:24 -0500
commit192f1e78cb9cbc1a2cee866f5e03a52857e648b6 (patch)
treeb7ab43660d93b06b054210ad2f3a12b23c8b8be6 /drivers/media/usb/s2255
parent4ca286610f664acf3153634f3930acd2de993a9f (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.c172
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
218struct s2255_channel { 219struct 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
813static 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
835static int vidioc_querycap(struct file *file, void *priv, 815static 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 ---------------------------------------------- */ 1410static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
1431static 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
1470static 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
1503static 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
1888static const struct v4l2_ioctl_ops s2255_ioctl_ops = { 1791static 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 = {
1915static void s2255_video_device_release(struct video_device *vdev) 1814static 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
1838static const struct v4l2_ctrl_ops s2255_ctrl_ops = {
1839 .s_ctrl = s2255_s_ctrl,
1840};
1841
1842static 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
1934static int s2255_probe_v4l(struct s2255_dev *dev) 1852static 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);