aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bw-qcam.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/bw-qcam.c')
-rw-r--r--drivers/media/video/bw-qcam.c132
1 files changed, 62 insertions, 70 deletions
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index f09df9dffaae..2520219f01ba 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -77,6 +77,9 @@ OTHER DEALINGS IN THE SOFTWARE.
77#include <media/v4l2-common.h> 77#include <media/v4l2-common.h>
78#include <media/v4l2-ioctl.h> 78#include <media/v4l2-ioctl.h>
79#include <media/v4l2-device.h> 79#include <media/v4l2-device.h>
80#include <media/v4l2-fh.h>
81#include <media/v4l2-ctrls.h>
82#include <media/v4l2-event.h>
80 83
81/* One from column A... */ 84/* One from column A... */
82#define QC_NOTSET 0 85#define QC_NOTSET 0
@@ -103,6 +106,7 @@ OTHER DEALINGS IN THE SOFTWARE.
103struct qcam { 106struct qcam {
104 struct v4l2_device v4l2_dev; 107 struct v4l2_device v4l2_dev;
105 struct video_device vdev; 108 struct video_device vdev;
109 struct v4l2_ctrl_handler hdl;
106 struct pardevice *pdev; 110 struct pardevice *pdev;
107 struct parport *pport; 111 struct parport *pport;
108 struct mutex lock; 112 struct mutex lock;
@@ -646,7 +650,8 @@ static int qcam_querycap(struct file *file, void *priv,
646 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); 650 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
647 strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card)); 651 strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card));
648 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); 652 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
649 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; 653 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
654 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
650 return 0; 655 return 0;
651} 656}
652 657
@@ -674,72 +679,6 @@ static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
674 return (inp > 0) ? -EINVAL : 0; 679 return (inp > 0) ? -EINVAL : 0;
675} 680}
676 681
677static int qcam_queryctrl(struct file *file, void *priv,
678 struct v4l2_queryctrl *qc)
679{
680 switch (qc->id) {
681 case V4L2_CID_BRIGHTNESS:
682 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 180);
683 case V4L2_CID_CONTRAST:
684 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
685 case V4L2_CID_GAMMA:
686 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 105);
687 }
688 return -EINVAL;
689}
690
691static int qcam_g_ctrl(struct file *file, void *priv,
692 struct v4l2_control *ctrl)
693{
694 struct qcam *qcam = video_drvdata(file);
695 int ret = 0;
696
697 switch (ctrl->id) {
698 case V4L2_CID_BRIGHTNESS:
699 ctrl->value = qcam->brightness;
700 break;
701 case V4L2_CID_CONTRAST:
702 ctrl->value = qcam->contrast;
703 break;
704 case V4L2_CID_GAMMA:
705 ctrl->value = qcam->whitebal;
706 break;
707 default:
708 ret = -EINVAL;
709 break;
710 }
711 return ret;
712}
713
714static int qcam_s_ctrl(struct file *file, void *priv,
715 struct v4l2_control *ctrl)
716{
717 struct qcam *qcam = video_drvdata(file);
718 int ret = 0;
719
720 mutex_lock(&qcam->lock);
721 switch (ctrl->id) {
722 case V4L2_CID_BRIGHTNESS:
723 qcam->brightness = ctrl->value;
724 break;
725 case V4L2_CID_CONTRAST:
726 qcam->contrast = ctrl->value;
727 break;
728 case V4L2_CID_GAMMA:
729 qcam->whitebal = ctrl->value;
730 break;
731 default:
732 ret = -EINVAL;
733 break;
734 }
735 if (ret == 0) {
736 qc_setscanmode(qcam);
737 qcam->status |= QC_PARAM_CHANGE;
738 }
739 mutex_unlock(&qcam->lock);
740 return ret;
741}
742
743static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 682static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
744{ 683{
745 struct qcam *qcam = video_drvdata(file); 684 struct qcam *qcam = video_drvdata(file);
@@ -856,8 +795,40 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
856 return len; 795 return len;
857} 796}
858 797
798static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
799{
800 struct qcam *qcam =
801 container_of(ctrl->handler, struct qcam, hdl);
802 int ret = 0;
803
804 mutex_lock(&qcam->lock);
805 switch (ctrl->id) {
806 case V4L2_CID_BRIGHTNESS:
807 qcam->brightness = ctrl->val;
808 break;
809 case V4L2_CID_CONTRAST:
810 qcam->contrast = ctrl->val;
811 break;
812 case V4L2_CID_GAMMA:
813 qcam->whitebal = ctrl->val;
814 break;
815 default:
816 ret = -EINVAL;
817 break;
818 }
819 if (ret == 0) {
820 qc_setscanmode(qcam);
821 qcam->status |= QC_PARAM_CHANGE;
822 }
823 mutex_unlock(&qcam->lock);
824 return ret;
825}
826
859static const struct v4l2_file_operations qcam_fops = { 827static const struct v4l2_file_operations qcam_fops = {
860 .owner = THIS_MODULE, 828 .owner = THIS_MODULE,
829 .open = v4l2_fh_open,
830 .release = v4l2_fh_release,
831 .poll = v4l2_ctrl_poll,
861 .unlocked_ioctl = video_ioctl2, 832 .unlocked_ioctl = video_ioctl2,
862 .read = qcam_read, 833 .read = qcam_read,
863}; 834};
@@ -867,13 +838,17 @@ static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
867 .vidioc_g_input = qcam_g_input, 838 .vidioc_g_input = qcam_g_input,
868 .vidioc_s_input = qcam_s_input, 839 .vidioc_s_input = qcam_s_input,
869 .vidioc_enum_input = qcam_enum_input, 840 .vidioc_enum_input = qcam_enum_input,
870 .vidioc_queryctrl = qcam_queryctrl,
871 .vidioc_g_ctrl = qcam_g_ctrl,
872 .vidioc_s_ctrl = qcam_s_ctrl,
873 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, 841 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
874 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, 842 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
875 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, 843 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
876 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, 844 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
845 .vidioc_log_status = v4l2_ctrl_log_status,
846 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
847 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
848};
849
850static const struct v4l2_ctrl_ops qcam_ctrl_ops = {
851 .s_ctrl = qcam_s_ctrl,
877}; 852};
878 853
879/* Initialize the QuickCam driver control structure. This is where 854/* Initialize the QuickCam driver control structure. This is where
@@ -897,19 +872,35 @@ static struct qcam *qcam_init(struct parport *port)
897 return NULL; 872 return NULL;
898 } 873 }
899 874
875 v4l2_ctrl_handler_init(&qcam->hdl, 3);
876 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
877 V4L2_CID_BRIGHTNESS, 0, 255, 1, 180);
878 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
879 V4L2_CID_CONTRAST, 0, 255, 1, 192);
880 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
881 V4L2_CID_GAMMA, 0, 255, 1, 105);
882 if (qcam->hdl.error) {
883 v4l2_err(v4l2_dev, "couldn't register controls\n");
884 v4l2_ctrl_handler_free(&qcam->hdl);
885 kfree(qcam);
886 return NULL;
887 }
900 qcam->pport = port; 888 qcam->pport = port;
901 qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, 889 qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
902 NULL, 0, NULL); 890 NULL, 0, NULL);
903 if (qcam->pdev == NULL) { 891 if (qcam->pdev == NULL) {
904 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); 892 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
893 v4l2_ctrl_handler_free(&qcam->hdl);
905 kfree(qcam); 894 kfree(qcam);
906 return NULL; 895 return NULL;
907 } 896 }
908 897
909 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name)); 898 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
910 qcam->vdev.v4l2_dev = v4l2_dev; 899 qcam->vdev.v4l2_dev = v4l2_dev;
900 qcam->vdev.ctrl_handler = &qcam->hdl;
911 qcam->vdev.fops = &qcam_fops; 901 qcam->vdev.fops = &qcam_fops;
912 qcam->vdev.ioctl_ops = &qcam_ioctl_ops; 902 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
903 set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
913 qcam->vdev.release = video_device_release_empty; 904 qcam->vdev.release = video_device_release_empty;
914 video_set_drvdata(&qcam->vdev, qcam); 905 video_set_drvdata(&qcam->vdev, qcam);
915 906
@@ -1003,6 +994,7 @@ static int init_bwqcam(struct parport *port)
1003static void close_bwqcam(struct qcam *qcam) 994static void close_bwqcam(struct qcam *qcam)
1004{ 995{
1005 video_unregister_device(&qcam->vdev); 996 video_unregister_device(&qcam->vdev);
997 v4l2_ctrl_handler_free(&qcam->hdl);
1006 parport_unregister_device(qcam->pdev); 998 parport_unregister_device(qcam->pdev);
1007 kfree(qcam); 999 kfree(qcam);
1008} 1000}