diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-01-31 06:23:01 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-02-05 15:30:43 -0500 |
commit | 9f7473592bd2c8d73657dcc1644de4ab610b0d90 (patch) | |
tree | e5cbdc6fee127b844dc217d2465bcfdca743d3fc /drivers | |
parent | 2c2a053626cb712d6006cb10f2760a6018a65631 (diff) |
[media] tm6000: 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')
-rw-r--r-- | drivers/media/usb/tm6000/tm6000-video.c | 232 | ||||
-rw-r--r-- | drivers/media/usb/tm6000/tm6000.h | 3 |
2 files changed, 68 insertions, 167 deletions
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index 7a653b263678..4329fbcf2de2 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c | |||
@@ -63,71 +63,6 @@ static bool keep_urb; /* keep urb buffers allocated */ | |||
63 | int tm6000_debug; | 63 | int tm6000_debug; |
64 | EXPORT_SYMBOL_GPL(tm6000_debug); | 64 | EXPORT_SYMBOL_GPL(tm6000_debug); |
65 | 65 | ||
66 | static const struct v4l2_queryctrl no_ctrl = { | ||
67 | .name = "42", | ||
68 | .flags = V4L2_CTRL_FLAG_DISABLED, | ||
69 | }; | ||
70 | |||
71 | /* supported controls */ | ||
72 | static struct v4l2_queryctrl tm6000_qctrl[] = { | ||
73 | { | ||
74 | .id = V4L2_CID_BRIGHTNESS, | ||
75 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
76 | .name = "Brightness", | ||
77 | .minimum = 0, | ||
78 | .maximum = 255, | ||
79 | .step = 1, | ||
80 | .default_value = 54, | ||
81 | .flags = 0, | ||
82 | }, { | ||
83 | .id = V4L2_CID_CONTRAST, | ||
84 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
85 | .name = "Contrast", | ||
86 | .minimum = 0, | ||
87 | .maximum = 255, | ||
88 | .step = 0x1, | ||
89 | .default_value = 119, | ||
90 | .flags = 0, | ||
91 | }, { | ||
92 | .id = V4L2_CID_SATURATION, | ||
93 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
94 | .name = "Saturation", | ||
95 | .minimum = 0, | ||
96 | .maximum = 255, | ||
97 | .step = 0x1, | ||
98 | .default_value = 112, | ||
99 | .flags = 0, | ||
100 | }, { | ||
101 | .id = V4L2_CID_HUE, | ||
102 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
103 | .name = "Hue", | ||
104 | .minimum = -128, | ||
105 | .maximum = 127, | ||
106 | .step = 0x1, | ||
107 | .default_value = 0, | ||
108 | .flags = 0, | ||
109 | }, | ||
110 | /* --- audio --- */ | ||
111 | { | ||
112 | .id = V4L2_CID_AUDIO_MUTE, | ||
113 | .name = "Mute", | ||
114 | .minimum = 0, | ||
115 | .maximum = 1, | ||
116 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
117 | }, { | ||
118 | .id = V4L2_CID_AUDIO_VOLUME, | ||
119 | .name = "Volume", | ||
120 | .minimum = -15, | ||
121 | .maximum = 15, | ||
122 | .step = 1, | ||
123 | .default_value = 0, | ||
124 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
125 | } | ||
126 | }; | ||
127 | |||
128 | static const unsigned int CTRLS = ARRAY_SIZE(tm6000_qctrl); | ||
129 | static int qctl_regs[ARRAY_SIZE(tm6000_qctrl)]; | ||
130 | |||
131 | static struct tm6000_fmt format[] = { | 66 | static struct tm6000_fmt format[] = { |
132 | { | 67 | { |
133 | .name = "4:2:2, packed, YVY2", | 68 | .name = "4:2:2, packed, YVY2", |
@@ -144,16 +79,6 @@ static struct tm6000_fmt format[] = { | |||
144 | } | 79 | } |
145 | }; | 80 | }; |
146 | 81 | ||
147 | static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id) | ||
148 | { | ||
149 | unsigned int i; | ||
150 | |||
151 | for (i = 0; i < CTRLS; i++) | ||
152 | if (tm6000_qctrl[i].id == id) | ||
153 | return tm6000_qctrl+i; | ||
154 | return NULL; | ||
155 | } | ||
156 | |||
157 | /* ------------------------------------------------------------------ | 82 | /* ------------------------------------------------------------------ |
158 | * DMA and thread functions | 83 | * DMA and thread functions |
159 | * ------------------------------------------------------------------ | 84 | * ------------------------------------------------------------------ |
@@ -1215,79 +1140,40 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | |||
1215 | } | 1140 | } |
1216 | 1141 | ||
1217 | /* --- controls ---------------------------------------------- */ | 1142 | /* --- controls ---------------------------------------------- */ |
1218 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
1219 | struct v4l2_queryctrl *qc) | ||
1220 | { | ||
1221 | int i; | ||
1222 | |||
1223 | for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++) | ||
1224 | if (qc->id && qc->id == tm6000_qctrl[i].id) { | ||
1225 | memcpy(qc, &(tm6000_qctrl[i]), | ||
1226 | sizeof(*qc)); | ||
1227 | return 0; | ||
1228 | } | ||
1229 | |||
1230 | return -EINVAL; | ||
1231 | } | ||
1232 | 1143 | ||
1233 | static int vidioc_g_ctrl(struct file *file, void *priv, | 1144 | static int tm6000_s_ctrl(struct v4l2_ctrl *ctrl) |
1234 | struct v4l2_control *ctrl) | ||
1235 | { | 1145 | { |
1236 | struct tm6000_fh *fh = priv; | 1146 | struct tm6000_core *dev = container_of(ctrl->handler, struct tm6000_core, ctrl_handler); |
1237 | struct tm6000_core *dev = fh->dev; | 1147 | u8 val = ctrl->val; |
1238 | int val; | ||
1239 | 1148 | ||
1240 | /* FIXME: Probably, those won't work! Maybe we need shadow regs */ | ||
1241 | switch (ctrl->id) { | 1149 | switch (ctrl->id) { |
1242 | case V4L2_CID_CONTRAST: | 1150 | case V4L2_CID_CONTRAST: |
1243 | val = tm6000_get_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0); | 1151 | tm6000_set_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, val); |
1244 | break; | 1152 | return 0; |
1245 | case V4L2_CID_BRIGHTNESS: | 1153 | case V4L2_CID_BRIGHTNESS: |
1246 | val = tm6000_get_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0); | 1154 | tm6000_set_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, val); |
1247 | return 0; | 1155 | return 0; |
1248 | case V4L2_CID_SATURATION: | 1156 | case V4L2_CID_SATURATION: |
1249 | val = tm6000_get_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0); | 1157 | tm6000_set_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, val); |
1250 | return 0; | 1158 | return 0; |
1251 | case V4L2_CID_HUE: | 1159 | case V4L2_CID_HUE: |
1252 | val = tm6000_get_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, 0); | 1160 | tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val); |
1253 | return 0; | ||
1254 | case V4L2_CID_AUDIO_MUTE: | ||
1255 | val = dev->ctl_mute; | ||
1256 | return 0; | ||
1257 | case V4L2_CID_AUDIO_VOLUME: | ||
1258 | val = dev->ctl_volume; | ||
1259 | return 0; | 1161 | return 0; |
1260 | default: | ||
1261 | return -EINVAL; | ||
1262 | } | 1162 | } |
1163 | return -EINVAL; | ||
1164 | } | ||
1263 | 1165 | ||
1264 | if (val < 0) | 1166 | static const struct v4l2_ctrl_ops tm6000_ctrl_ops = { |
1265 | return val; | 1167 | .s_ctrl = tm6000_s_ctrl, |
1266 | 1168 | }; | |
1267 | ctrl->value = val; | ||
1268 | 1169 | ||
1269 | return 0; | 1170 | static int tm6000_radio_s_ctrl(struct v4l2_ctrl *ctrl) |
1270 | } | ||
1271 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
1272 | struct v4l2_control *ctrl) | ||
1273 | { | 1171 | { |
1274 | struct tm6000_fh *fh = priv; | 1172 | struct tm6000_core *dev = container_of(ctrl->handler, |
1275 | struct tm6000_core *dev = fh->dev; | 1173 | struct tm6000_core, radio_ctrl_handler); |
1276 | u8 val = ctrl->value; | 1174 | u8 val = ctrl->val; |
1277 | 1175 | ||
1278 | switch (ctrl->id) { | 1176 | switch (ctrl->id) { |
1279 | case V4L2_CID_CONTRAST: | ||
1280 | tm6000_set_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, val); | ||
1281 | return 0; | ||
1282 | case V4L2_CID_BRIGHTNESS: | ||
1283 | tm6000_set_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, val); | ||
1284 | return 0; | ||
1285 | case V4L2_CID_SATURATION: | ||
1286 | tm6000_set_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, val); | ||
1287 | return 0; | ||
1288 | case V4L2_CID_HUE: | ||
1289 | tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val); | ||
1290 | return 0; | ||
1291 | case V4L2_CID_AUDIO_MUTE: | 1177 | case V4L2_CID_AUDIO_MUTE: |
1292 | dev->ctl_mute = val; | 1178 | dev->ctl_mute = val; |
1293 | tm6000_tvaudio_set_mute(dev, val); | 1179 | tm6000_tvaudio_set_mute(dev, val); |
@@ -1300,6 +1186,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1300 | return -EINVAL; | 1186 | return -EINVAL; |
1301 | } | 1187 | } |
1302 | 1188 | ||
1189 | static const struct v4l2_ctrl_ops tm6000_radio_ctrl_ops = { | ||
1190 | .s_ctrl = tm6000_radio_s_ctrl, | ||
1191 | }; | ||
1192 | |||
1303 | static int vidioc_g_tuner(struct file *file, void *priv, | 1193 | static int vidioc_g_tuner(struct file *file, void *priv, |
1304 | struct v4l2_tuner *t) | 1194 | struct v4l2_tuner *t) |
1305 | { | 1195 | { |
@@ -1418,23 +1308,6 @@ static int radio_s_tuner(struct file *file, void *priv, | |||
1418 | return 0; | 1308 | return 0; |
1419 | } | 1309 | } |
1420 | 1310 | ||
1421 | static int radio_queryctrl(struct file *file, void *priv, | ||
1422 | struct v4l2_queryctrl *c) | ||
1423 | { | ||
1424 | const struct v4l2_queryctrl *ctrl; | ||
1425 | |||
1426 | if (c->id < V4L2_CID_BASE || | ||
1427 | c->id >= V4L2_CID_LASTP1) | ||
1428 | return -EINVAL; | ||
1429 | if (c->id == V4L2_CID_AUDIO_MUTE) { | ||
1430 | ctrl = ctrl_by_id(c->id); | ||
1431 | *c = *ctrl; | ||
1432 | } else | ||
1433 | *c = no_ctrl; | ||
1434 | |||
1435 | return 0; | ||
1436 | } | ||
1437 | |||
1438 | /* ------------------------------------------------------------------ | 1311 | /* ------------------------------------------------------------------ |
1439 | File operations for the device | 1312 | File operations for the device |
1440 | ------------------------------------------------------------------*/ | 1313 | ------------------------------------------------------------------*/ |
@@ -1445,7 +1318,7 @@ static int __tm6000_open(struct file *file) | |||
1445 | struct tm6000_core *dev = video_drvdata(file); | 1318 | struct tm6000_core *dev = video_drvdata(file); |
1446 | struct tm6000_fh *fh; | 1319 | struct tm6000_fh *fh; |
1447 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1320 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1448 | int i, rc; | 1321 | int rc; |
1449 | int radio = 0; | 1322 | int radio = 0; |
1450 | 1323 | ||
1451 | dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n", | 1324 | dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n", |
@@ -1505,13 +1378,7 @@ static int __tm6000_open(struct file *file) | |||
1505 | if (rc < 0) | 1378 | if (rc < 0) |
1506 | return rc; | 1379 | return rc; |
1507 | 1380 | ||
1508 | if (dev->mode != TM6000_MODE_ANALOG) { | 1381 | dev->mode = TM6000_MODE_ANALOG; |
1509 | /* Put all controls at a sane state */ | ||
1510 | for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++) | ||
1511 | qctl_regs[i] = tm6000_qctrl[i].default_value; | ||
1512 | |||
1513 | dev->mode = TM6000_MODE_ANALOG; | ||
1514 | } | ||
1515 | 1382 | ||
1516 | if (!fh->radio) { | 1383 | if (!fh->radio) { |
1517 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &tm6000_video_qops, | 1384 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &tm6000_video_qops, |
@@ -1678,9 +1545,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1678 | .vidioc_enum_input = vidioc_enum_input, | 1545 | .vidioc_enum_input = vidioc_enum_input, |
1679 | .vidioc_g_input = vidioc_g_input, | 1546 | .vidioc_g_input = vidioc_g_input, |
1680 | .vidioc_s_input = vidioc_s_input, | 1547 | .vidioc_s_input = vidioc_s_input, |
1681 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1682 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1683 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1684 | .vidioc_g_tuner = vidioc_g_tuner, | 1548 | .vidioc_g_tuner = vidioc_g_tuner, |
1685 | .vidioc_s_tuner = vidioc_s_tuner, | 1549 | .vidioc_s_tuner = vidioc_s_tuner, |
1686 | .vidioc_g_frequency = vidioc_g_frequency, | 1550 | .vidioc_g_frequency = vidioc_g_frequency, |
@@ -1713,9 +1577,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { | |||
1713 | .vidioc_querycap = vidioc_querycap, | 1577 | .vidioc_querycap = vidioc_querycap, |
1714 | .vidioc_g_tuner = radio_g_tuner, | 1578 | .vidioc_g_tuner = radio_g_tuner, |
1715 | .vidioc_s_tuner = radio_s_tuner, | 1579 | .vidioc_s_tuner = radio_s_tuner, |
1716 | .vidioc_queryctrl = radio_queryctrl, | ||
1717 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1718 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1719 | .vidioc_g_frequency = vidioc_g_frequency, | 1580 | .vidioc_g_frequency = vidioc_g_frequency, |
1720 | .vidioc_s_frequency = vidioc_s_frequency, | 1581 | .vidioc_s_frequency = vidioc_s_frequency, |
1721 | }; | 1582 | }; |
@@ -1755,15 +1616,41 @@ static struct video_device *vdev_init(struct tm6000_core *dev, | |||
1755 | 1616 | ||
1756 | int tm6000_v4l2_register(struct tm6000_core *dev) | 1617 | int tm6000_v4l2_register(struct tm6000_core *dev) |
1757 | { | 1618 | { |
1758 | int ret = -1; | 1619 | int ret = 0; |
1620 | |||
1621 | v4l2_ctrl_handler_init(&dev->ctrl_handler, 6); | ||
1622 | v4l2_ctrl_handler_init(&dev->radio_ctrl_handler, 2); | ||
1623 | v4l2_ctrl_new_std(&dev->radio_ctrl_handler, &tm6000_radio_ctrl_ops, | ||
1624 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); | ||
1625 | v4l2_ctrl_new_std(&dev->radio_ctrl_handler, &tm6000_radio_ctrl_ops, | ||
1626 | V4L2_CID_AUDIO_VOLUME, -15, 15, 1, 0); | ||
1627 | v4l2_ctrl_new_std(&dev->ctrl_handler, &tm6000_ctrl_ops, | ||
1628 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 54); | ||
1629 | v4l2_ctrl_new_std(&dev->ctrl_handler, &tm6000_ctrl_ops, | ||
1630 | V4L2_CID_CONTRAST, 0, 255, 1, 119); | ||
1631 | v4l2_ctrl_new_std(&dev->ctrl_handler, &tm6000_ctrl_ops, | ||
1632 | V4L2_CID_SATURATION, 0, 255, 1, 112); | ||
1633 | v4l2_ctrl_new_std(&dev->ctrl_handler, &tm6000_ctrl_ops, | ||
1634 | V4L2_CID_HUE, -128, 127, 1, 0); | ||
1635 | v4l2_ctrl_add_handler(&dev->ctrl_handler, | ||
1636 | &dev->radio_ctrl_handler, NULL); | ||
1637 | |||
1638 | if (dev->radio_ctrl_handler.error) | ||
1639 | ret = dev->radio_ctrl_handler.error; | ||
1640 | if (!ret && dev->ctrl_handler.error) | ||
1641 | ret = dev->ctrl_handler.error; | ||
1642 | if (ret) | ||
1643 | goto free_ctrl; | ||
1759 | 1644 | ||
1760 | dev->vfd = vdev_init(dev, &tm6000_template, "video"); | 1645 | dev->vfd = vdev_init(dev, &tm6000_template, "video"); |
1761 | 1646 | ||
1762 | if (!dev->vfd) { | 1647 | if (!dev->vfd) { |
1763 | printk(KERN_INFO "%s: can't register video device\n", | 1648 | printk(KERN_INFO "%s: can't register video device\n", |
1764 | dev->name); | 1649 | dev->name); |
1765 | return -ENOMEM; | 1650 | ret = -ENOMEM; |
1651 | goto free_ctrl; | ||
1766 | } | 1652 | } |
1653 | dev->vfd->ctrl_handler = &dev->ctrl_handler; | ||
1767 | 1654 | ||
1768 | /* init video dma queues */ | 1655 | /* init video dma queues */ |
1769 | INIT_LIST_HEAD(&dev->vidq.active); | 1656 | INIT_LIST_HEAD(&dev->vidq.active); |
@@ -1774,7 +1661,9 @@ int tm6000_v4l2_register(struct tm6000_core *dev) | |||
1774 | if (ret < 0) { | 1661 | if (ret < 0) { |
1775 | printk(KERN_INFO "%s: can't register video device\n", | 1662 | printk(KERN_INFO "%s: can't register video device\n", |
1776 | dev->name); | 1663 | dev->name); |
1777 | return ret; | 1664 | video_device_release(dev->vfd); |
1665 | dev->vfd = NULL; | ||
1666 | goto free_ctrl; | ||
1778 | } | 1667 | } |
1779 | 1668 | ||
1780 | printk(KERN_INFO "%s: registered device %s\n", | 1669 | printk(KERN_INFO "%s: registered device %s\n", |
@@ -1787,15 +1676,17 @@ int tm6000_v4l2_register(struct tm6000_core *dev) | |||
1787 | printk(KERN_INFO "%s: can't register radio device\n", | 1676 | printk(KERN_INFO "%s: can't register radio device\n", |
1788 | dev->name); | 1677 | dev->name); |
1789 | ret = -ENXIO; | 1678 | ret = -ENXIO; |
1790 | return ret; /* FIXME release resource */ | 1679 | goto unreg_video; |
1791 | } | 1680 | } |
1792 | 1681 | ||
1682 | dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; | ||
1793 | ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, | 1683 | ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, |
1794 | radio_nr); | 1684 | radio_nr); |
1795 | if (ret < 0) { | 1685 | if (ret < 0) { |
1796 | printk(KERN_INFO "%s: can't register radio device\n", | 1686 | printk(KERN_INFO "%s: can't register radio device\n", |
1797 | dev->name); | 1687 | dev->name); |
1798 | return ret; /* FIXME release resource */ | 1688 | video_device_release(dev->radio_dev); |
1689 | goto unreg_video; | ||
1799 | } | 1690 | } |
1800 | 1691 | ||
1801 | printk(KERN_INFO "%s: registered device %s\n", | 1692 | printk(KERN_INFO "%s: registered device %s\n", |
@@ -1804,6 +1695,13 @@ int tm6000_v4l2_register(struct tm6000_core *dev) | |||
1804 | 1695 | ||
1805 | printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret); | 1696 | printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret); |
1806 | return ret; | 1697 | return ret; |
1698 | |||
1699 | unreg_video: | ||
1700 | video_unregister_device(dev->vfd); | ||
1701 | free_ctrl: | ||
1702 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | ||
1703 | v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); | ||
1704 | return ret; | ||
1807 | } | 1705 | } |
1808 | 1706 | ||
1809 | int tm6000_v4l2_unregister(struct tm6000_core *dev) | 1707 | int tm6000_v4l2_unregister(struct tm6000_core *dev) |
diff --git a/drivers/media/usb/tm6000/tm6000.h b/drivers/media/usb/tm6000/tm6000.h index 173dcd7a7284..a9ac262fcc93 100644 --- a/drivers/media/usb/tm6000/tm6000.h +++ b/drivers/media/usb/tm6000/tm6000.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
29 | #include <media/v4l2-device.h> | 29 | #include <media/v4l2-device.h> |
30 | #include <media/v4l2-ctrls.h> | ||
30 | 31 | ||
31 | #include <linux/dvb/frontend.h> | 32 | #include <linux/dvb/frontend.h> |
32 | #include "dvb_demux.h" | 33 | #include "dvb_demux.h" |
@@ -222,6 +223,8 @@ struct tm6000_core { | |||
222 | struct video_device *radio_dev; | 223 | struct video_device *radio_dev; |
223 | struct tm6000_dmaqueue vidq; | 224 | struct tm6000_dmaqueue vidq; |
224 | struct v4l2_device v4l2_dev; | 225 | struct v4l2_device v4l2_dev; |
226 | struct v4l2_ctrl_handler ctrl_handler; | ||
227 | struct v4l2_ctrl_handler radio_ctrl_handler; | ||
225 | 228 | ||
226 | int input; | 229 | int input; |
227 | struct tm6000_input vinput[3]; /* video input */ | 230 | struct tm6000_input vinput[3]; /* video input */ |