diff options
author | Nick Dyer <nick@shmanahar.org> | 2016-08-22 05:28:23 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-08-23 15:34:29 -0400 |
commit | b497265266a8083547e9ca162ace72cbb41522f1 (patch) | |
tree | 934656cbd9115584d2db93f931c4be6be56f57f4 /drivers/input | |
parent | 3a762dbd5347514c3cb2ac756a92a3d1c7646a2d (diff) |
[media] Input: sur40 - use new V4L2 touch input type
Support both V4L2_TCH_FMT_TU08 and V4L2_PIX_FMT_GREY for backwards
compatibility.
Signed-off-by: Nick Dyer <nick@shmanahar.org>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/touchscreen/sur40.c | 124 |
1 files changed, 91 insertions, 33 deletions
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c index 4ea475775d58..3967d8c651cc 100644 --- a/drivers/input/touchscreen/sur40.c +++ b/drivers/input/touchscreen/sur40.c | |||
@@ -139,6 +139,27 @@ struct sur40_image_header { | |||
139 | #define SUR40_GET_STATE 0xc5 /* 4 bytes state (?) */ | 139 | #define SUR40_GET_STATE 0xc5 /* 4 bytes state (?) */ |
140 | #define SUR40_GET_SENSORS 0xb1 /* 8 bytes sensors */ | 140 | #define SUR40_GET_SENSORS 0xb1 /* 8 bytes sensors */ |
141 | 141 | ||
142 | static const struct v4l2_pix_format sur40_pix_format[] = { | ||
143 | { | ||
144 | .pixelformat = V4L2_TCH_FMT_TU08, | ||
145 | .width = SENSOR_RES_X / 2, | ||
146 | .height = SENSOR_RES_Y / 2, | ||
147 | .field = V4L2_FIELD_NONE, | ||
148 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
149 | .bytesperline = SENSOR_RES_X / 2, | ||
150 | .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2), | ||
151 | }, | ||
152 | { | ||
153 | .pixelformat = V4L2_PIX_FMT_GREY, | ||
154 | .width = SENSOR_RES_X / 2, | ||
155 | .height = SENSOR_RES_Y / 2, | ||
156 | .field = V4L2_FIELD_NONE, | ||
157 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
158 | .bytesperline = SENSOR_RES_X / 2, | ||
159 | .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2), | ||
160 | } | ||
161 | }; | ||
162 | |||
142 | /* master device state */ | 163 | /* master device state */ |
143 | struct sur40_state { | 164 | struct sur40_state { |
144 | 165 | ||
@@ -149,6 +170,7 @@ struct sur40_state { | |||
149 | struct v4l2_device v4l2; | 170 | struct v4l2_device v4l2; |
150 | struct video_device vdev; | 171 | struct video_device vdev; |
151 | struct mutex lock; | 172 | struct mutex lock; |
173 | struct v4l2_pix_format pix_fmt; | ||
152 | 174 | ||
153 | struct vb2_queue queue; | 175 | struct vb2_queue queue; |
154 | struct list_head buf_list; | 176 | struct list_head buf_list; |
@@ -169,7 +191,6 @@ struct sur40_buffer { | |||
169 | 191 | ||
170 | /* forward declarations */ | 192 | /* forward declarations */ |
171 | static const struct video_device sur40_video_device; | 193 | static const struct video_device sur40_video_device; |
172 | static const struct v4l2_pix_format sur40_video_format; | ||
173 | static const struct vb2_queue sur40_queue; | 194 | static const struct vb2_queue sur40_queue; |
174 | static void sur40_process_video(struct sur40_state *sur40); | 195 | static void sur40_process_video(struct sur40_state *sur40); |
175 | 196 | ||
@@ -420,7 +441,7 @@ static void sur40_process_video(struct sur40_state *sur40) | |||
420 | goto err_poll; | 441 | goto err_poll; |
421 | } | 442 | } |
422 | 443 | ||
423 | if (le32_to_cpu(img->size) != sur40_video_format.sizeimage) { | 444 | if (le32_to_cpu(img->size) != sur40->pix_fmt.sizeimage) { |
424 | dev_err(sur40->dev, "image size mismatch\n"); | 445 | dev_err(sur40->dev, "image size mismatch\n"); |
425 | goto err_poll; | 446 | goto err_poll; |
426 | } | 447 | } |
@@ -431,7 +452,7 @@ static void sur40_process_video(struct sur40_state *sur40) | |||
431 | 452 | ||
432 | result = usb_sg_init(&sgr, sur40->usbdev, | 453 | result = usb_sg_init(&sgr, sur40->usbdev, |
433 | usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT), 0, | 454 | usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT), 0, |
434 | sgt->sgl, sgt->nents, sur40_video_format.sizeimage, 0); | 455 | sgt->sgl, sgt->nents, sur40->pix_fmt.sizeimage, 0); |
435 | if (result < 0) { | 456 | if (result < 0) { |
436 | dev_err(sur40->dev, "error %d in usb_sg_init\n", result); | 457 | dev_err(sur40->dev, "error %d in usb_sg_init\n", result); |
437 | goto err_poll; | 458 | goto err_poll; |
@@ -586,13 +607,14 @@ static int sur40_probe(struct usb_interface *interface, | |||
586 | if (error) | 607 | if (error) |
587 | goto err_unreg_v4l2; | 608 | goto err_unreg_v4l2; |
588 | 609 | ||
610 | sur40->pix_fmt = sur40_pix_format[0]; | ||
589 | sur40->vdev = sur40_video_device; | 611 | sur40->vdev = sur40_video_device; |
590 | sur40->vdev.v4l2_dev = &sur40->v4l2; | 612 | sur40->vdev.v4l2_dev = &sur40->v4l2; |
591 | sur40->vdev.lock = &sur40->lock; | 613 | sur40->vdev.lock = &sur40->lock; |
592 | sur40->vdev.queue = &sur40->queue; | 614 | sur40->vdev.queue = &sur40->queue; |
593 | video_set_drvdata(&sur40->vdev, sur40); | 615 | video_set_drvdata(&sur40->vdev, sur40); |
594 | 616 | ||
595 | error = video_register_device(&sur40->vdev, VFL_TYPE_GRABBER, -1); | 617 | error = video_register_device(&sur40->vdev, VFL_TYPE_TOUCH, -1); |
596 | if (error) { | 618 | if (error) { |
597 | dev_err(&interface->dev, | 619 | dev_err(&interface->dev, |
598 | "Unable to register video subdevice."); | 620 | "Unable to register video subdevice."); |
@@ -647,14 +669,16 @@ static int sur40_queue_setup(struct vb2_queue *q, | |||
647 | unsigned int *nbuffers, unsigned int *nplanes, | 669 | unsigned int *nbuffers, unsigned int *nplanes, |
648 | unsigned int sizes[], struct device *alloc_devs[]) | 670 | unsigned int sizes[], struct device *alloc_devs[]) |
649 | { | 671 | { |
672 | struct sur40_state *sur40 = vb2_get_drv_priv(q); | ||
673 | |||
650 | if (q->num_buffers + *nbuffers < 3) | 674 | if (q->num_buffers + *nbuffers < 3) |
651 | *nbuffers = 3 - q->num_buffers; | 675 | *nbuffers = 3 - q->num_buffers; |
652 | 676 | ||
653 | if (*nplanes) | 677 | if (*nplanes) |
654 | return sizes[0] < sur40_video_format.sizeimage ? -EINVAL : 0; | 678 | return sizes[0] < sur40->pix_fmt.sizeimage ? -EINVAL : 0; |
655 | 679 | ||
656 | *nplanes = 1; | 680 | *nplanes = 1; |
657 | sizes[0] = sur40_video_format.sizeimage; | 681 | sizes[0] = sur40->pix_fmt.sizeimage; |
658 | 682 | ||
659 | return 0; | 683 | return 0; |
660 | } | 684 | } |
@@ -666,7 +690,7 @@ static int sur40_queue_setup(struct vb2_queue *q, | |||
666 | static int sur40_buffer_prepare(struct vb2_buffer *vb) | 690 | static int sur40_buffer_prepare(struct vb2_buffer *vb) |
667 | { | 691 | { |
668 | struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue); | 692 | struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue); |
669 | unsigned long size = sur40_video_format.sizeimage; | 693 | unsigned long size = sur40->pix_fmt.sizeimage; |
670 | 694 | ||
671 | if (vb2_plane_size(vb, 0) < size) { | 695 | if (vb2_plane_size(vb, 0) < size) { |
672 | dev_err(&sur40->usbdev->dev, "buffer too small (%lu < %lu)\n", | 696 | dev_err(&sur40->usbdev->dev, "buffer too small (%lu < %lu)\n", |
@@ -741,7 +765,7 @@ static int sur40_vidioc_querycap(struct file *file, void *priv, | |||
741 | strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver)); | 765 | strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver)); |
742 | strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card)); | 766 | strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card)); |
743 | usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info)); | 767 | usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info)); |
744 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | | 768 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TOUCH | |
745 | V4L2_CAP_READWRITE | | 769 | V4L2_CAP_READWRITE | |
746 | V4L2_CAP_STREAMING; | 770 | V4L2_CAP_STREAMING; |
747 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | 771 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
@@ -753,7 +777,7 @@ static int sur40_vidioc_enum_input(struct file *file, void *priv, | |||
753 | { | 777 | { |
754 | if (i->index != 0) | 778 | if (i->index != 0) |
755 | return -EINVAL; | 779 | return -EINVAL; |
756 | i->type = V4L2_INPUT_TYPE_CAMERA; | 780 | i->type = V4L2_INPUT_TYPE_TOUCH; |
757 | i->std = V4L2_STD_UNKNOWN; | 781 | i->std = V4L2_STD_UNKNOWN; |
758 | strlcpy(i->name, "In-Cell Sensor", sizeof(i->name)); | 782 | strlcpy(i->name, "In-Cell Sensor", sizeof(i->name)); |
759 | i->capabilities = 0; | 783 | i->capabilities = 0; |
@@ -771,19 +795,57 @@ static int sur40_vidioc_g_input(struct file *file, void *priv, unsigned int *i) | |||
771 | return 0; | 795 | return 0; |
772 | } | 796 | } |
773 | 797 | ||
774 | static int sur40_vidioc_fmt(struct file *file, void *priv, | 798 | static int sur40_vidioc_try_fmt(struct file *file, void *priv, |
799 | struct v4l2_format *f) | ||
800 | { | ||
801 | switch (f->fmt.pix.pixelformat) { | ||
802 | case V4L2_PIX_FMT_GREY: | ||
803 | f->fmt.pix = sur40_pix_format[1]; | ||
804 | break; | ||
805 | |||
806 | default: | ||
807 | f->fmt.pix = sur40_pix_format[0]; | ||
808 | break; | ||
809 | } | ||
810 | |||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | static int sur40_vidioc_s_fmt(struct file *file, void *priv, | ||
775 | struct v4l2_format *f) | 815 | struct v4l2_format *f) |
776 | { | 816 | { |
777 | f->fmt.pix = sur40_video_format; | 817 | struct sur40_state *sur40 = video_drvdata(file); |
818 | |||
819 | switch (f->fmt.pix.pixelformat) { | ||
820 | case V4L2_PIX_FMT_GREY: | ||
821 | sur40->pix_fmt = sur40_pix_format[1]; | ||
822 | break; | ||
823 | |||
824 | default: | ||
825 | sur40->pix_fmt = sur40_pix_format[0]; | ||
826 | break; | ||
827 | } | ||
828 | |||
829 | f->fmt.pix = sur40->pix_fmt; | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | static int sur40_vidioc_g_fmt(struct file *file, void *priv, | ||
834 | struct v4l2_format *f) | ||
835 | { | ||
836 | struct sur40_state *sur40 = video_drvdata(file); | ||
837 | |||
838 | f->fmt.pix = sur40->pix_fmt; | ||
778 | return 0; | 839 | return 0; |
779 | } | 840 | } |
780 | 841 | ||
781 | static int sur40_vidioc_enum_fmt(struct file *file, void *priv, | 842 | static int sur40_vidioc_enum_fmt(struct file *file, void *priv, |
782 | struct v4l2_fmtdesc *f) | 843 | struct v4l2_fmtdesc *f) |
783 | { | 844 | { |
784 | if (f->index != 0) | 845 | if (f->index >= ARRAY_SIZE(sur40_pix_format)) |
785 | return -EINVAL; | 846 | return -EINVAL; |
786 | f->pixelformat = V4L2_PIX_FMT_GREY; | 847 | |
848 | f->pixelformat = sur40_pix_format[f->index].pixelformat; | ||
787 | f->flags = 0; | 849 | f->flags = 0; |
788 | return 0; | 850 | return 0; |
789 | } | 851 | } |
@@ -791,22 +853,28 @@ static int sur40_vidioc_enum_fmt(struct file *file, void *priv, | |||
791 | static int sur40_vidioc_enum_framesizes(struct file *file, void *priv, | 853 | static int sur40_vidioc_enum_framesizes(struct file *file, void *priv, |
792 | struct v4l2_frmsizeenum *f) | 854 | struct v4l2_frmsizeenum *f) |
793 | { | 855 | { |
794 | if ((f->index != 0) || (f->pixel_format != V4L2_PIX_FMT_GREY)) | 856 | struct sur40_state *sur40 = video_drvdata(file); |
857 | |||
858 | if ((f->index != 0) || ((f->pixel_format != V4L2_TCH_FMT_TU08) | ||
859 | && (f->pixel_format != V4L2_PIX_FMT_GREY))) | ||
795 | return -EINVAL; | 860 | return -EINVAL; |
796 | 861 | ||
797 | f->type = V4L2_FRMSIZE_TYPE_DISCRETE; | 862 | f->type = V4L2_FRMSIZE_TYPE_DISCRETE; |
798 | f->discrete.width = sur40_video_format.width; | 863 | f->discrete.width = sur40->pix_fmt.width; |
799 | f->discrete.height = sur40_video_format.height; | 864 | f->discrete.height = sur40->pix_fmt.height; |
800 | return 0; | 865 | return 0; |
801 | } | 866 | } |
802 | 867 | ||
803 | static int sur40_vidioc_enum_frameintervals(struct file *file, void *priv, | 868 | static int sur40_vidioc_enum_frameintervals(struct file *file, void *priv, |
804 | struct v4l2_frmivalenum *f) | 869 | struct v4l2_frmivalenum *f) |
805 | { | 870 | { |
806 | if ((f->index > 1) || (f->pixel_format != V4L2_PIX_FMT_GREY) | 871 | struct sur40_state *sur40 = video_drvdata(file); |
807 | || (f->width != sur40_video_format.width) | 872 | |
808 | || (f->height != sur40_video_format.height)) | 873 | if ((f->index > 1) || ((f->pixel_format != V4L2_TCH_FMT_TU08) |
809 | return -EINVAL; | 874 | && (f->pixel_format != V4L2_PIX_FMT_GREY)) |
875 | || (f->width != sur40->pix_fmt.width) | ||
876 | || (f->height != sur40->pix_fmt.height)) | ||
877 | return -EINVAL; | ||
810 | 878 | ||
811 | f->type = V4L2_FRMIVAL_TYPE_DISCRETE; | 879 | f->type = V4L2_FRMIVAL_TYPE_DISCRETE; |
812 | f->discrete.denominator = 60/(f->index+1); | 880 | f->discrete.denominator = 60/(f->index+1); |
@@ -862,9 +930,9 @@ static const struct v4l2_ioctl_ops sur40_video_ioctl_ops = { | |||
862 | .vidioc_querycap = sur40_vidioc_querycap, | 930 | .vidioc_querycap = sur40_vidioc_querycap, |
863 | 931 | ||
864 | .vidioc_enum_fmt_vid_cap = sur40_vidioc_enum_fmt, | 932 | .vidioc_enum_fmt_vid_cap = sur40_vidioc_enum_fmt, |
865 | .vidioc_try_fmt_vid_cap = sur40_vidioc_fmt, | 933 | .vidioc_try_fmt_vid_cap = sur40_vidioc_try_fmt, |
866 | .vidioc_s_fmt_vid_cap = sur40_vidioc_fmt, | 934 | .vidioc_s_fmt_vid_cap = sur40_vidioc_s_fmt, |
867 | .vidioc_g_fmt_vid_cap = sur40_vidioc_fmt, | 935 | .vidioc_g_fmt_vid_cap = sur40_vidioc_g_fmt, |
868 | 936 | ||
869 | .vidioc_enum_framesizes = sur40_vidioc_enum_framesizes, | 937 | .vidioc_enum_framesizes = sur40_vidioc_enum_framesizes, |
870 | .vidioc_enum_frameintervals = sur40_vidioc_enum_frameintervals, | 938 | .vidioc_enum_frameintervals = sur40_vidioc_enum_frameintervals, |
@@ -891,16 +959,6 @@ static const struct video_device sur40_video_device = { | |||
891 | .release = video_device_release_empty, | 959 | .release = video_device_release_empty, |
892 | }; | 960 | }; |
893 | 961 | ||
894 | static const struct v4l2_pix_format sur40_video_format = { | ||
895 | .pixelformat = V4L2_PIX_FMT_GREY, | ||
896 | .width = SENSOR_RES_X / 2, | ||
897 | .height = SENSOR_RES_Y / 2, | ||
898 | .field = V4L2_FIELD_NONE, | ||
899 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
900 | .bytesperline = SENSOR_RES_X / 2, | ||
901 | .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2), | ||
902 | }; | ||
903 | |||
904 | /* USB-specific object needed to register this driver with the USB subsystem. */ | 962 | /* USB-specific object needed to register this driver with the USB subsystem. */ |
905 | static struct usb_driver sur40_driver = { | 963 | static struct usb_driver sur40_driver = { |
906 | .name = DRIVER_SHORT, | 964 | .name = DRIVER_SHORT, |