diff --git a/fthd_drv.h b/fthd_drv.h index 5675a76..f967cf1 100644 --- a/fthd_drv.h +++ b/fthd_drv.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "fthd_reg.h" #include "fthd_ringbuf.h" #include "fthd_buffer.h" @@ -133,6 +134,7 @@ struct fthd_private { struct vb2_alloc_ctx *alloc_ctx; struct h2t_buf_ctx h2t_bufs[FTHD_BUFFERS]; + struct v4l2_ctrl_handler v4l2_ctrl_handler; int frametime; }; diff --git a/fthd_v4l2.c b/fthd_v4l2.c index 5ab033c..6c8461f 100644 --- a/fthd_v4l2.c +++ b/fthd_v4l2.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "fthd_drv.h" #include "fthd_hw.h" @@ -596,6 +597,46 @@ static struct v4l2_ioctl_ops fthd_ioctl_ops = { .vidioc_enum_frameintervals = fthd_v4l2_ioctl_enum_frameintervals, }; +static int fthd_g_volatile_ctrl(struct v4l2_ctrl *ctrl) +{ + pr_debug("id = %x\n", ctrl->id); + return -EINVAL; +} + +static int fthd_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct fthd_private *dev_priv = container_of(ctrl->handler, struct fthd_private, v4l2_ctrl_handler); + int ret = -EINVAL; + + pr_info("id = %x, val = %d\n", ctrl->id, ctrl->val); + + switch(ctrl->id) { + case V4L2_CID_CONTRAST: + ret = fthd_isp_cmd_channel_contrast_set(dev_priv, 0, ctrl->val); + break; + case V4L2_CID_BRIGHTNESS: + ret = fthd_isp_cmd_channel_brightness_set(dev_priv, 0, ctrl->val); + break; + case V4L2_CID_SATURATION: + ret = fthd_isp_cmd_channel_saturation_set(dev_priv, 0, ctrl->val); + break; + case V4L2_CID_HUE: + ret = fthd_isp_cmd_channel_hue_set(dev_priv, 0, ctrl->val); + break; + + default: + break; + + } + pr_debug("ret = %d\n", ret); + return ret; +} + +static const struct v4l2_ctrl_ops fthd_ctrl_ops = { + .g_volatile_ctrl = fthd_g_volatile_ctrl, + .s_ctrl = fthd_s_ctrl, +}; + int fthd_v4l2_register(struct fthd_private *dev_priv) { struct v4l2_device *v4l2_dev = &dev_priv->v4l2_dev; @@ -631,6 +672,21 @@ int fthd_v4l2_register(struct fthd_private *dev_priv) if (ret) goto fail; + v4l2_ctrl_handler_init(&dev_priv->v4l2_ctrl_handler, 4); + v4l2_ctrl_new_std(&dev_priv->v4l2_ctrl_handler, &fthd_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x80); + v4l2_ctrl_new_std(&dev_priv->v4l2_ctrl_handler, &fthd_ctrl_ops, + V4L2_CID_CONTRAST, 0, 0xff, 1, 0x80); + v4l2_ctrl_new_std(&dev_priv->v4l2_ctrl_handler, &fthd_ctrl_ops, + V4L2_CID_SATURATION, 0, 0xff, 1, 0x80); + v4l2_ctrl_new_std(&dev_priv->v4l2_ctrl_handler, &fthd_ctrl_ops, + V4L2_CID_HUE, 0, 0xff, 1, 0x80); + + if (dev_priv->v4l2_ctrl_handler.error) { + pr_err("failed to setup control handlers\n"); + v4l2_ctrl_handler_free(&dev_priv->v4l2_ctrl_handler); + goto fail; + } dev_priv->alloc_ctx = vb2_dma_sg_init_ctx(&dev_priv->pdev->dev); vdev->v4l2_dev = v4l2_dev; strcpy(vdev->name, "Apple Facetime HD"); // XXX: Length? @@ -639,19 +695,22 @@ int fthd_v4l2_register(struct fthd_private *dev_priv) vdev->ioctl_ops = &fthd_ioctl_ops; vdev->queue = q; vdev->release = video_device_release; - + vdev->ctrl_handler = &dev_priv->v4l2_ctrl_handler; video_set_drvdata(vdev, dev_priv); ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (ret) { video_device_release(vdev); - goto fail; + goto fail_vdev; } dev_priv->fmt.fmt.sizeimage = 1280 * 720 * 2; dev_priv->fmt.fmt.pixelformat = V4L2_PIX_FMT_YUYV; dev_priv->fmt.fmt.width = 1280; dev_priv->fmt.fmt.height = 720; + return 0; +fail_vdev: + v4l2_ctrl_handler_free(&dev_priv->v4l2_ctrl_handler); fail: v4l2_device_unregister(&dev_priv->v4l2_dev); return ret; @@ -660,6 +719,7 @@ fail: void fthd_v4l2_unregister(struct fthd_private *dev_priv) { + v4l2_ctrl_handler_free(&dev_priv->v4l2_ctrl_handler); vb2_dma_sg_cleanup_ctx(dev_priv->alloc_ctx); video_unregister_device(dev_priv->videodev); v4l2_device_unregister(&dev_priv->v4l2_dev);