aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-01-30 12:10:14 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-02-05 15:20:06 -0500
commit1888e4a9742087df22ba64ea2e0e1064edeb8785 (patch)
tree6bca46be80986eee37d5fec34ec28afff69da755 /drivers/media
parent11d379395291609f95cf1e102f9f23892b83a493 (diff)
[media] bw-qcam: convert to videobuf2
I know, nobody really cares about this black-and-white webcam anymore, but it was fun to do. Tested with an actual webcam. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/parport/Kconfig1
-rw-r--r--drivers/media/parport/bw-qcam.c157
2 files changed, 112 insertions, 46 deletions
diff --git a/drivers/media/parport/Kconfig b/drivers/media/parport/Kconfig
index ece13dcff07d..948c981d9f05 100644
--- a/drivers/media/parport/Kconfig
+++ b/drivers/media/parport/Kconfig
@@ -9,6 +9,7 @@ if MEDIA_PARPORT_SUPPORT
9config VIDEO_BWQCAM 9config VIDEO_BWQCAM
10 tristate "Quickcam BW Video For Linux" 10 tristate "Quickcam BW Video For Linux"
11 depends on PARPORT && VIDEO_V4L2 11 depends on PARPORT && VIDEO_V4L2
12 select VIDEOBUF2_VMALLOC
12 help 13 help
13 Say Y have if you the black and white version of the QuickCam 14 Say Y have if you the black and white version of the QuickCam
14 camera. See the next option for the color version. 15 camera. See the next option for the color version.
diff --git a/drivers/media/parport/bw-qcam.c b/drivers/media/parport/bw-qcam.c
index 497b342b0f72..d3fe34f14c0d 100644
--- a/drivers/media/parport/bw-qcam.c
+++ b/drivers/media/parport/bw-qcam.c
@@ -80,6 +80,7 @@ OTHER DEALINGS IN THE SOFTWARE.
80#include <media/v4l2-fh.h> 80#include <media/v4l2-fh.h>
81#include <media/v4l2-ctrls.h> 81#include <media/v4l2-ctrls.h>
82#include <media/v4l2-event.h> 82#include <media/v4l2-event.h>
83#include <media/videobuf2-vmalloc.h>
83 84
84/* One from column A... */ 85/* One from column A... */
85#define QC_NOTSET 0 86#define QC_NOTSET 0
@@ -107,9 +108,11 @@ struct qcam {
107 struct v4l2_device v4l2_dev; 108 struct v4l2_device v4l2_dev;
108 struct video_device vdev; 109 struct video_device vdev;
109 struct v4l2_ctrl_handler hdl; 110 struct v4l2_ctrl_handler hdl;
111 struct vb2_queue vb_vidq;
110 struct pardevice *pdev; 112 struct pardevice *pdev;
111 struct parport *pport; 113 struct parport *pport;
112 struct mutex lock; 114 struct mutex lock;
115 struct mutex queue_lock;
113 int width, height; 116 int width, height;
114 int bpp; 117 int bpp;
115 int mode; 118 int mode;
@@ -558,7 +561,7 @@ static inline int qc_readbytes(struct qcam *q, char buffer[])
558 * n=2^(bit depth)-1. Ask me for more details if you don't understand 561 * n=2^(bit depth)-1. Ask me for more details if you don't understand
559 * this. */ 562 * this. */
560 563
561static long qc_capture(struct qcam *q, char __user *buf, unsigned long len) 564static long qc_capture(struct qcam *q, u8 *buf, unsigned long len)
562{ 565{
563 int i, j, k, yield; 566 int i, j, k, yield;
564 int bytes; 567 int bytes;
@@ -609,7 +612,7 @@ static long qc_capture(struct qcam *q, char __user *buf, unsigned long len)
609 if (o < len) { 612 if (o < len) {
610 u8 ch = invert - buffer[k]; 613 u8 ch = invert - buffer[k];
611 got++; 614 got++;
612 put_user(ch << shift, buf + o); 615 buf[o] = ch << shift;
613 } 616 }
614 } 617 }
615 pixels_read += bytes; 618 pixels_read += bytes;
@@ -639,6 +642,67 @@ static long qc_capture(struct qcam *q, char __user *buf, unsigned long len)
639 return len; 642 return len;
640} 643}
641 644
645/* ------------------------------------------------------------------
646 Videobuf operations
647 ------------------------------------------------------------------*/
648static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
649 unsigned int *nbuffers, unsigned int *nplanes,
650 unsigned int sizes[], void *alloc_ctxs[])
651{
652 struct qcam *dev = vb2_get_drv_priv(vq);
653
654 if (0 == *nbuffers)
655 *nbuffers = 3;
656 *nplanes = 1;
657 mutex_lock(&dev->lock);
658 if (fmt)
659 sizes[0] = fmt->fmt.pix.width * fmt->fmt.pix.height;
660 else
661 sizes[0] = (dev->width / dev->transfer_scale) *
662 (dev->height / dev->transfer_scale);
663 mutex_unlock(&dev->lock);
664 return 0;
665}
666
667static void buffer_queue(struct vb2_buffer *vb)
668{
669 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
670}
671
672static int buffer_finish(struct vb2_buffer *vb)
673{
674 struct qcam *qcam = vb2_get_drv_priv(vb->vb2_queue);
675 void *vbuf = vb2_plane_vaddr(vb, 0);
676 int size = vb->vb2_queue->plane_sizes[0];
677 int len;
678
679 mutex_lock(&qcam->lock);
680 parport_claim_or_block(qcam->pdev);
681
682 qc_reset(qcam);
683
684 /* Update the camera parameters if we need to */
685 if (qcam->status & QC_PARAM_CHANGE)
686 qc_set(qcam);
687
688 len = qc_capture(qcam, vbuf, size);
689
690 parport_release(qcam->pdev);
691 mutex_unlock(&qcam->lock);
692 if (len != size)
693 vb->state = VB2_BUF_STATE_ERROR;
694 vb2_set_plane_payload(vb, 0, len);
695 return 0;
696}
697
698static struct vb2_ops qcam_video_qops = {
699 .queue_setup = queue_setup,
700 .buf_queue = buffer_queue,
701 .buf_finish = buffer_finish,
702 .wait_prepare = vb2_ops_wait_prepare,
703 .wait_finish = vb2_ops_wait_finish,
704};
705
642/* 706/*
643 * Video4linux interfacing 707 * Video4linux interfacing
644 */ 708 */
@@ -651,7 +715,8 @@ static int qcam_querycap(struct file *file, void *priv,
651 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); 715 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
652 strlcpy(vcap->card, "Connectix B&W Quickcam", sizeof(vcap->card)); 716 strlcpy(vcap->card, "Connectix B&W Quickcam", sizeof(vcap->card));
653 strlcpy(vcap->bus_info, qcam->pport->name, sizeof(vcap->bus_info)); 717 strlcpy(vcap->bus_info, qcam->pport->name, sizeof(vcap->bus_info));
654 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; 718 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
719 V4L2_CAP_STREAMING;
655 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS; 720 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
656 return 0; 721 return 0;
657} 722}
@@ -731,6 +796,8 @@ static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
731 796
732 if (ret) 797 if (ret)
733 return ret; 798 return ret;
799 if (vb2_is_busy(&qcam->vb_vidq))
800 return -EBUSY;
734 qcam->width = 320; 801 qcam->width = 320;
735 qcam->height = 240; 802 qcam->height = 240;
736 if (pix->height == 60) 803 if (pix->height == 60)
@@ -744,12 +811,10 @@ static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
744 else 811 else
745 qcam->bpp = 4; 812 qcam->bpp = 4;
746 813
747 mutex_lock(&qcam->lock);
748 qc_setscanmode(qcam); 814 qc_setscanmode(qcam);
749 /* We must update the camera before we grab. We could 815 /* We must update the camera before we grab. We could
750 just have changed the grab size */ 816 just have changed the grab size */
751 qcam->status |= QC_PARAM_CHANGE; 817 qcam->status |= QC_PARAM_CHANGE;
752 mutex_unlock(&qcam->lock);
753 return 0; 818 return 0;
754} 819}
755 820
@@ -794,41 +859,12 @@ static int qcam_enum_framesizes(struct file *file, void *fh,
794 return 0; 859 return 0;
795} 860}
796 861
797static ssize_t qcam_read(struct file *file, char __user *buf,
798 size_t count, loff_t *ppos)
799{
800 struct qcam *qcam = video_drvdata(file);
801 int len;
802 parport_claim_or_block(qcam->pdev);
803
804 mutex_lock(&qcam->lock);
805
806 qc_reset(qcam);
807
808 /* Update the camera parameters if we need to */
809 if (qcam->status & QC_PARAM_CHANGE)
810 qc_set(qcam);
811
812 len = qc_capture(qcam, buf, count);
813
814 mutex_unlock(&qcam->lock);
815
816 parport_release(qcam->pdev);
817 return len;
818}
819
820static unsigned int qcam_poll(struct file *filp, poll_table *wait)
821{
822 return v4l2_ctrl_poll(filp, wait) | POLLIN | POLLRDNORM;
823}
824
825static int qcam_s_ctrl(struct v4l2_ctrl *ctrl) 862static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
826{ 863{
827 struct qcam *qcam = 864 struct qcam *qcam =
828 container_of(ctrl->handler, struct qcam, hdl); 865 container_of(ctrl->handler, struct qcam, hdl);
829 int ret = 0; 866 int ret = 0;
830 867
831 mutex_lock(&qcam->lock);
832 switch (ctrl->id) { 868 switch (ctrl->id) {
833 case V4L2_CID_BRIGHTNESS: 869 case V4L2_CID_BRIGHTNESS:
834 qcam->brightness = ctrl->val; 870 qcam->brightness = ctrl->val;
@@ -847,17 +883,17 @@ static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
847 qc_setscanmode(qcam); 883 qc_setscanmode(qcam);
848 qcam->status |= QC_PARAM_CHANGE; 884 qcam->status |= QC_PARAM_CHANGE;
849 } 885 }
850 mutex_unlock(&qcam->lock);
851 return ret; 886 return ret;
852} 887}
853 888
854static const struct v4l2_file_operations qcam_fops = { 889static const struct v4l2_file_operations qcam_fops = {
855 .owner = THIS_MODULE, 890 .owner = THIS_MODULE,
856 .open = v4l2_fh_open, 891 .open = v4l2_fh_open,
857 .release = v4l2_fh_release, 892 .release = vb2_fop_release,
858 .poll = qcam_poll, 893 .poll = vb2_fop_poll,
859 .unlocked_ioctl = video_ioctl2, 894 .unlocked_ioctl = video_ioctl2,
860 .read = qcam_read, 895 .read = vb2_fop_read,
896 .mmap = vb2_fop_mmap,
861}; 897};
862 898
863static const struct v4l2_ioctl_ops qcam_ioctl_ops = { 899static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
@@ -870,6 +906,14 @@ static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
870 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, 906 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
871 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, 907 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
872 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, 908 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
909 .vidioc_reqbufs = vb2_ioctl_reqbufs,
910 .vidioc_create_bufs = vb2_ioctl_create_bufs,
911 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
912 .vidioc_querybuf = vb2_ioctl_querybuf,
913 .vidioc_qbuf = vb2_ioctl_qbuf,
914 .vidioc_dqbuf = vb2_ioctl_dqbuf,
915 .vidioc_streamon = vb2_ioctl_streamon,
916 .vidioc_streamoff = vb2_ioctl_streamoff,
873 .vidioc_log_status = v4l2_ctrl_log_status, 917 .vidioc_log_status = v4l2_ctrl_log_status,
874 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 918 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
875 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 919 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
@@ -886,6 +930,8 @@ static struct qcam *qcam_init(struct parport *port)
886{ 930{
887 struct qcam *qcam; 931 struct qcam *qcam;
888 struct v4l2_device *v4l2_dev; 932 struct v4l2_device *v4l2_dev;
933 struct vb2_queue *q;
934 int err;
889 935
890 qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL); 936 qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL);
891 if (qcam == NULL) 937 if (qcam == NULL)
@@ -909,31 +955,45 @@ static struct qcam *qcam_init(struct parport *port)
909 V4L2_CID_GAMMA, 0, 255, 1, 105); 955 V4L2_CID_GAMMA, 0, 255, 1, 105);
910 if (qcam->hdl.error) { 956 if (qcam->hdl.error) {
911 v4l2_err(v4l2_dev, "couldn't register controls\n"); 957 v4l2_err(v4l2_dev, "couldn't register controls\n");
912 v4l2_ctrl_handler_free(&qcam->hdl); 958 goto exit;
913 kfree(qcam); 959 }
914 return NULL; 960
961 mutex_init(&qcam->lock);
962 mutex_init(&qcam->queue_lock);
963
964 /* initialize queue */
965 q = &qcam->vb_vidq;
966 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
967 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
968 q->drv_priv = qcam;
969 q->ops = &qcam_video_qops;
970 q->mem_ops = &vb2_vmalloc_memops;
971 err = vb2_queue_init(q);
972 if (err < 0) {
973 v4l2_err(v4l2_dev, "couldn't init vb2_queue for %s.\n", port->name);
974 goto exit;
915 } 975 }
976 qcam->vdev.queue = q;
977 qcam->vdev.queue->lock = &qcam->queue_lock;
978
916 qcam->pport = port; 979 qcam->pport = port;
917 qcam->pdev = parport_register_device(port, v4l2_dev->name, NULL, NULL, 980 qcam->pdev = parport_register_device(port, v4l2_dev->name, NULL, NULL,
918 NULL, 0, NULL); 981 NULL, 0, NULL);
919 if (qcam->pdev == NULL) { 982 if (qcam->pdev == NULL) {
920 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); 983 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
921 v4l2_ctrl_handler_free(&qcam->hdl); 984 goto exit;
922 kfree(qcam);
923 return NULL;
924 } 985 }
925 986
926 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name)); 987 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
927 qcam->vdev.v4l2_dev = v4l2_dev; 988 qcam->vdev.v4l2_dev = v4l2_dev;
928 qcam->vdev.ctrl_handler = &qcam->hdl; 989 qcam->vdev.ctrl_handler = &qcam->hdl;
929 qcam->vdev.fops = &qcam_fops; 990 qcam->vdev.fops = &qcam_fops;
991 qcam->vdev.lock = &qcam->lock;
930 qcam->vdev.ioctl_ops = &qcam_ioctl_ops; 992 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
931 set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags); 993 set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
932 qcam->vdev.release = video_device_release_empty; 994 qcam->vdev.release = video_device_release_empty;
933 video_set_drvdata(&qcam->vdev, qcam); 995 video_set_drvdata(&qcam->vdev, qcam);
934 996
935 mutex_init(&qcam->lock);
936
937 qcam->port_mode = (QC_ANY | QC_NOTSET); 997 qcam->port_mode = (QC_ANY | QC_NOTSET);
938 qcam->width = 320; 998 qcam->width = 320;
939 qcam->height = 240; 999 qcam->height = 240;
@@ -947,6 +1007,11 @@ static struct qcam *qcam_init(struct parport *port)
947 qcam->mode = -1; 1007 qcam->mode = -1;
948 qcam->status = QC_PARAM_CHANGE; 1008 qcam->status = QC_PARAM_CHANGE;
949 return qcam; 1009 return qcam;
1010
1011exit:
1012 v4l2_ctrl_handler_free(&qcam->hdl);
1013 kfree(qcam);
1014 return NULL;
950} 1015}
951 1016
952static int qc_calibrate(struct qcam *q) 1017static int qc_calibrate(struct qcam *q)