diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-04-13 07:38:14 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-16 17:04:12 -0400 |
commit | f8d7ee70919d44ef4f01f3c9bc49af54fdc433bc (patch) | |
tree | 391df2bfea624e994e8feb00cd9423c697d05927 /drivers/media/pci | |
parent | 467870ca26c01cb0ac84e969a78160f8164919cc (diff) |
[media] cx25821: 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/pci')
-rw-r--r-- | drivers/media/pci/cx25821/cx25821-core.c | 5 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821-video.c | 210 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821.h | 10 |
3 files changed, 41 insertions, 184 deletions
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index f3a48a17c4c3..bf6c1812dd8c 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c | |||
@@ -880,8 +880,11 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) | |||
880 | 880 | ||
881 | /* Apply a sensible clock frequency for the PCIe bridge */ | 881 | /* Apply a sensible clock frequency for the PCIe bridge */ |
882 | dev->clk_freq = 28000000; | 882 | dev->clk_freq = 28000000; |
883 | for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) | 883 | for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) { |
884 | dev->channels[i].dev = dev; | ||
885 | dev->channels[i].id = i; | ||
884 | dev->channels[i].sram_channels = &cx25821_sram_channels[i]; | 886 | dev->channels[i].sram_channels = &cx25821_sram_channels[i]; |
887 | } | ||
885 | 888 | ||
886 | if (dev->nr > 1) | 889 | if (dev->nr > 1) |
887 | CX25821_INFO("dev->nr > 1!"); | 890 | CX25821_INFO("dev->nr > 1!"); |
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 41e3475efec3..0c11f314c62e 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c | |||
@@ -1188,192 +1188,29 @@ int cx25821_vidioc_s_register(struct file *file, void *fh, | |||
1188 | 1188 | ||
1189 | #endif | 1189 | #endif |
1190 | 1190 | ||
1191 | /*****************************************************************************/ | 1191 | static int cx25821_s_ctrl(struct v4l2_ctrl *ctrl) |
1192 | static const struct v4l2_queryctrl no_ctl = { | ||
1193 | .name = "42", | ||
1194 | .flags = V4L2_CTRL_FLAG_DISABLED, | ||
1195 | }; | ||
1196 | |||
1197 | static struct v4l2_queryctrl cx25821_ctls[] = { | ||
1198 | /* --- video --- */ | ||
1199 | { | ||
1200 | .id = V4L2_CID_BRIGHTNESS, | ||
1201 | .name = "Brightness", | ||
1202 | .minimum = 0, | ||
1203 | .maximum = 10000, | ||
1204 | .step = 1, | ||
1205 | .default_value = 6200, | ||
1206 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1207 | }, { | ||
1208 | .id = V4L2_CID_CONTRAST, | ||
1209 | .name = "Contrast", | ||
1210 | .minimum = 0, | ||
1211 | .maximum = 10000, | ||
1212 | .step = 1, | ||
1213 | .default_value = 5000, | ||
1214 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1215 | }, { | ||
1216 | .id = V4L2_CID_SATURATION, | ||
1217 | .name = "Saturation", | ||
1218 | .minimum = 0, | ||
1219 | .maximum = 10000, | ||
1220 | .step = 1, | ||
1221 | .default_value = 5000, | ||
1222 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1223 | }, { | ||
1224 | .id = V4L2_CID_HUE, | ||
1225 | .name = "Hue", | ||
1226 | .minimum = 0, | ||
1227 | .maximum = 10000, | ||
1228 | .step = 1, | ||
1229 | .default_value = 5000, | ||
1230 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1231 | } | ||
1232 | }; | ||
1233 | static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls); | ||
1234 | |||
1235 | static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl) | ||
1236 | { | ||
1237 | int i; | ||
1238 | |||
1239 | if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1) | ||
1240 | return -EINVAL; | ||
1241 | for (i = 0; i < CX25821_CTLS; i++) | ||
1242 | if (cx25821_ctls[i].id == qctrl->id) | ||
1243 | break; | ||
1244 | if (i == CX25821_CTLS) { | ||
1245 | *qctrl = no_ctl; | ||
1246 | return 0; | ||
1247 | } | ||
1248 | *qctrl = cx25821_ctls[i]; | ||
1249 | return 0; | ||
1250 | } | ||
1251 | |||
1252 | static int cx25821_vidioc_queryctrl(struct file *file, void *priv, | ||
1253 | struct v4l2_queryctrl *qctrl) | ||
1254 | { | ||
1255 | return cx25821_ctrl_query(qctrl); | ||
1256 | } | ||
1257 | |||
1258 | /* ------------------------------------------------------------------ */ | ||
1259 | /* VIDEO CTRL IOCTLS */ | ||
1260 | |||
1261 | static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id) | ||
1262 | { | 1192 | { |
1263 | unsigned int i; | 1193 | struct cx25821_channel *chan = |
1194 | container_of(ctrl->handler, struct cx25821_channel, hdl); | ||
1195 | struct cx25821_dev *dev = chan->dev; | ||
1264 | 1196 | ||
1265 | for (i = 0; i < CX25821_CTLS; i++) | 1197 | switch (ctrl->id) { |
1266 | if (cx25821_ctls[i].id == id) | ||
1267 | return cx25821_ctls + i; | ||
1268 | return NULL; | ||
1269 | } | ||
1270 | |||
1271 | static int cx25821_vidioc_g_ctrl(struct file *file, void *priv, | ||
1272 | struct v4l2_control *ctl) | ||
1273 | { | ||
1274 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1275 | struct cx25821_fh *fh = priv; | ||
1276 | |||
1277 | const struct v4l2_queryctrl *ctrl; | ||
1278 | |||
1279 | ctrl = ctrl_by_id(ctl->id); | ||
1280 | |||
1281 | if (NULL == ctrl) | ||
1282 | return -EINVAL; | ||
1283 | switch (ctl->id) { | ||
1284 | case V4L2_CID_BRIGHTNESS: | 1198 | case V4L2_CID_BRIGHTNESS: |
1285 | ctl->value = dev->channels[fh->channel_id].ctl_bright; | 1199 | medusa_set_brightness(dev, ctrl->val, chan->id); |
1286 | break; | 1200 | break; |
1287 | case V4L2_CID_HUE: | 1201 | case V4L2_CID_HUE: |
1288 | ctl->value = dev->channels[fh->channel_id].ctl_hue; | 1202 | medusa_set_hue(dev, ctrl->val, chan->id); |
1289 | break; | 1203 | break; |
1290 | case V4L2_CID_CONTRAST: | 1204 | case V4L2_CID_CONTRAST: |
1291 | ctl->value = dev->channels[fh->channel_id].ctl_contrast; | 1205 | medusa_set_contrast(dev, ctrl->val, chan->id); |
1292 | break; | 1206 | break; |
1293 | case V4L2_CID_SATURATION: | 1207 | case V4L2_CID_SATURATION: |
1294 | ctl->value = dev->channels[fh->channel_id].ctl_saturation; | 1208 | medusa_set_saturation(dev, ctrl->val, chan->id); |
1295 | break; | ||
1296 | } | ||
1297 | return 0; | ||
1298 | } | ||
1299 | |||
1300 | static int cx25821_set_control(struct cx25821_dev *dev, | ||
1301 | struct v4l2_control *ctl, int chan_num) | ||
1302 | { | ||
1303 | int err; | ||
1304 | const struct v4l2_queryctrl *ctrl; | ||
1305 | |||
1306 | err = -EINVAL; | ||
1307 | |||
1308 | ctrl = ctrl_by_id(ctl->id); | ||
1309 | |||
1310 | if (NULL == ctrl) | ||
1311 | return err; | ||
1312 | |||
1313 | switch (ctrl->type) { | ||
1314 | case V4L2_CTRL_TYPE_BOOLEAN: | ||
1315 | case V4L2_CTRL_TYPE_MENU: | ||
1316 | case V4L2_CTRL_TYPE_INTEGER: | ||
1317 | if (ctl->value < ctrl->minimum) | ||
1318 | ctl->value = ctrl->minimum; | ||
1319 | if (ctl->value > ctrl->maximum) | ||
1320 | ctl->value = ctrl->maximum; | ||
1321 | break; | 1209 | break; |
1322 | default: | 1210 | default: |
1323 | /* nothing */ ; | 1211 | return -EINVAL; |
1324 | } | ||
1325 | |||
1326 | switch (ctl->id) { | ||
1327 | case V4L2_CID_BRIGHTNESS: | ||
1328 | dev->channels[chan_num].ctl_bright = ctl->value; | ||
1329 | medusa_set_brightness(dev, ctl->value, chan_num); | ||
1330 | break; | ||
1331 | case V4L2_CID_HUE: | ||
1332 | dev->channels[chan_num].ctl_hue = ctl->value; | ||
1333 | medusa_set_hue(dev, ctl->value, chan_num); | ||
1334 | break; | ||
1335 | case V4L2_CID_CONTRAST: | ||
1336 | dev->channels[chan_num].ctl_contrast = ctl->value; | ||
1337 | medusa_set_contrast(dev, ctl->value, chan_num); | ||
1338 | break; | ||
1339 | case V4L2_CID_SATURATION: | ||
1340 | dev->channels[chan_num].ctl_saturation = ctl->value; | ||
1341 | medusa_set_saturation(dev, ctl->value, chan_num); | ||
1342 | break; | ||
1343 | } | ||
1344 | |||
1345 | err = 0; | ||
1346 | |||
1347 | return err; | ||
1348 | } | ||
1349 | |||
1350 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
1351 | struct v4l2_control *ctl) | ||
1352 | { | ||
1353 | struct cx25821_fh *fh = priv; | ||
1354 | struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; | ||
1355 | int err; | ||
1356 | |||
1357 | if (fh) { | ||
1358 | err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, | ||
1359 | fh->prio); | ||
1360 | if (0 != err) | ||
1361 | return err; | ||
1362 | } | ||
1363 | |||
1364 | return cx25821_set_control(dev, ctl, fh->channel_id); | ||
1365 | } | ||
1366 | |||
1367 | static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num) | ||
1368 | { | ||
1369 | struct v4l2_control ctrl; | ||
1370 | int i; | ||
1371 | for (i = 0; i < CX25821_CTLS; i++) { | ||
1372 | ctrl.id = cx25821_ctls[i].id; | ||
1373 | ctrl.value = cx25821_ctls[i].default_value; | ||
1374 | |||
1375 | cx25821_set_control(dev, &ctrl, chan_num); | ||
1376 | } | 1212 | } |
1213 | return 0; | ||
1377 | } | 1214 | } |
1378 | 1215 | ||
1379 | static long video_ioctl_upstream9(struct file *file, unsigned int cmd, | 1216 | static long video_ioctl_upstream9(struct file *file, unsigned int cmd, |
@@ -1629,7 +1466,10 @@ static long cx25821_video_ioctl(struct file *file, | |||
1629 | return video_ioctl2(file, cmd, arg); | 1466 | return video_ioctl2(file, cmd, arg); |
1630 | } | 1467 | } |
1631 | 1468 | ||
1632 | /* exported stuff */ | 1469 | static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { |
1470 | .s_ctrl = cx25821_s_ctrl, | ||
1471 | }; | ||
1472 | |||
1633 | static const struct v4l2_file_operations video_fops = { | 1473 | static const struct v4l2_file_operations video_fops = { |
1634 | .owner = THIS_MODULE, | 1474 | .owner = THIS_MODULE, |
1635 | .open = video_open, | 1475 | .open = video_open, |
@@ -1655,9 +1495,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1655 | .vidioc_enum_input = cx25821_vidioc_enum_input, | 1495 | .vidioc_enum_input = cx25821_vidioc_enum_input, |
1656 | .vidioc_g_input = cx25821_vidioc_g_input, | 1496 | .vidioc_g_input = cx25821_vidioc_g_input, |
1657 | .vidioc_s_input = cx25821_vidioc_s_input, | 1497 | .vidioc_s_input = cx25821_vidioc_s_input, |
1658 | .vidioc_g_ctrl = cx25821_vidioc_g_ctrl, | ||
1659 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1660 | .vidioc_queryctrl = cx25821_vidioc_queryctrl, | ||
1661 | .vidioc_streamon = vidioc_streamon, | 1498 | .vidioc_streamon = vidioc_streamon, |
1662 | .vidioc_streamoff = vidioc_streamoff, | 1499 | .vidioc_streamoff = vidioc_streamoff, |
1663 | .vidioc_log_status = vidioc_log_status, | 1500 | .vidioc_log_status = vidioc_log_status, |
@@ -1684,6 +1521,7 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) | |||
1684 | 1521 | ||
1685 | if (video_is_registered(&dev->channels[chan_num].vdev)) { | 1522 | if (video_is_registered(&dev->channels[chan_num].vdev)) { |
1686 | video_unregister_device(&dev->channels[chan_num].vdev); | 1523 | video_unregister_device(&dev->channels[chan_num].vdev); |
1524 | v4l2_ctrl_handler_free(&dev->channels[chan_num].hdl); | ||
1687 | 1525 | ||
1688 | btcx_riscmem_free(dev->pci, | 1526 | btcx_riscmem_free(dev->pci, |
1689 | &dev->channels[chan_num].vidq.stopper); | 1527 | &dev->channels[chan_num].vidq.stopper); |
@@ -1699,11 +1537,24 @@ int cx25821_video_register(struct cx25821_dev *dev) | |||
1699 | 1537 | ||
1700 | for (i = 0; i < VID_CHANNEL_NUM; ++i) { | 1538 | for (i = 0; i < VID_CHANNEL_NUM; ++i) { |
1701 | struct video_device *vdev = &dev->channels[i].vdev; | 1539 | struct video_device *vdev = &dev->channels[i].vdev; |
1540 | struct v4l2_ctrl_handler *hdl = &dev->channels[i].hdl; | ||
1702 | 1541 | ||
1703 | if (i == SRAM_CH08) /* audio channel */ | 1542 | if (i == SRAM_CH08) /* audio channel */ |
1704 | continue; | 1543 | continue; |
1705 | 1544 | ||
1706 | cx25821_init_controls(dev, i); | 1545 | v4l2_ctrl_handler_init(hdl, 4); |
1546 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, | ||
1547 | V4L2_CID_BRIGHTNESS, 0, 10000, 1, 6200); | ||
1548 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, | ||
1549 | V4L2_CID_CONTRAST, 0, 10000, 1, 5000); | ||
1550 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, | ||
1551 | V4L2_CID_SATURATION, 0, 10000, 1, 5000); | ||
1552 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, | ||
1553 | V4L2_CID_HUE, 0, 10000, 1, 5000); | ||
1554 | if (hdl->error) { | ||
1555 | err = hdl->error; | ||
1556 | goto fail_unreg; | ||
1557 | } | ||
1707 | 1558 | ||
1708 | cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, | 1559 | cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, |
1709 | dev->channels[i].sram_channels->dma_ctl, 0x11, 0); | 1560 | dev->channels[i].sram_channels->dma_ctl, 0x11, 0); |
@@ -1727,6 +1578,7 @@ int cx25821_video_register(struct cx25821_dev *dev) | |||
1727 | /* register v4l devices */ | 1578 | /* register v4l devices */ |
1728 | *vdev = cx25821_video_device; | 1579 | *vdev = cx25821_video_device; |
1729 | vdev->v4l2_dev = &dev->v4l2_dev; | 1580 | vdev->v4l2_dev = &dev->v4l2_dev; |
1581 | vdev->ctrl_handler = hdl; | ||
1730 | snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); | 1582 | snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); |
1731 | video_set_drvdata(vdev, dev); | 1583 | video_set_drvdata(vdev, dev); |
1732 | 1584 | ||
diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index df2ea22563e5..c63f7f571614 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include <media/v4l2-common.h> | 34 | #include <media/v4l2-common.h> |
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include <media/v4l2-ctrls.h> | ||
36 | #include <media/videobuf-dma-sg.h> | 37 | #include <media/videobuf-dma-sg.h> |
37 | 38 | ||
38 | #include "btcx-risc.h" | 39 | #include "btcx-risc.h" |
@@ -208,13 +209,14 @@ struct cx25821_data { | |||
208 | const struct sram_channel *channel; | 209 | const struct sram_channel *channel; |
209 | }; | 210 | }; |
210 | 211 | ||
212 | struct cx25821_dev; | ||
213 | |||
211 | struct cx25821_channel { | 214 | struct cx25821_channel { |
215 | unsigned id; | ||
216 | struct cx25821_dev *dev; | ||
212 | struct v4l2_prio_state prio; | 217 | struct v4l2_prio_state prio; |
213 | 218 | ||
214 | int ctl_bright; | 219 | struct v4l2_ctrl_handler hdl; |
215 | int ctl_contrast; | ||
216 | int ctl_hue; | ||
217 | int ctl_saturation; | ||
218 | struct cx25821_data timeout_data; | 220 | struct cx25821_data timeout_data; |
219 | 221 | ||
220 | struct video_device vdev; | 222 | struct video_device vdev; |