Commit b4972652 authored by Nick Dyer's avatar Nick Dyer Committed by Mauro Carvalho Chehab

[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: default avatarNick Dyer <nick@shmanahar.org>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
Acked-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 3a762dbd
...@@ -139,6 +139,27 @@ struct sur40_image_header { ...@@ -139,6 +139,27 @@ struct sur40_image_header {
#define SUR40_GET_STATE 0xc5 /* 4 bytes state (?) */ #define SUR40_GET_STATE 0xc5 /* 4 bytes state (?) */
#define SUR40_GET_SENSORS 0xb1 /* 8 bytes sensors */ #define SUR40_GET_SENSORS 0xb1 /* 8 bytes sensors */
static const struct v4l2_pix_format sur40_pix_format[] = {
{
.pixelformat = V4L2_TCH_FMT_TU08,
.width = SENSOR_RES_X / 2,
.height = SENSOR_RES_Y / 2,
.field = V4L2_FIELD_NONE,
.colorspace = V4L2_COLORSPACE_SRGB,
.bytesperline = SENSOR_RES_X / 2,
.sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
},
{
.pixelformat = V4L2_PIX_FMT_GREY,
.width = SENSOR_RES_X / 2,
.height = SENSOR_RES_Y / 2,
.field = V4L2_FIELD_NONE,
.colorspace = V4L2_COLORSPACE_SRGB,
.bytesperline = SENSOR_RES_X / 2,
.sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
}
};
/* master device state */ /* master device state */
struct sur40_state { struct sur40_state {
...@@ -149,6 +170,7 @@ struct sur40_state { ...@@ -149,6 +170,7 @@ struct sur40_state {
struct v4l2_device v4l2; struct v4l2_device v4l2;
struct video_device vdev; struct video_device vdev;
struct mutex lock; struct mutex lock;
struct v4l2_pix_format pix_fmt;
struct vb2_queue queue; struct vb2_queue queue;
struct list_head buf_list; struct list_head buf_list;
...@@ -169,7 +191,6 @@ struct sur40_buffer { ...@@ -169,7 +191,6 @@ struct sur40_buffer {
/* forward declarations */ /* forward declarations */
static const struct video_device sur40_video_device; static const struct video_device sur40_video_device;
static const struct v4l2_pix_format sur40_video_format;
static const struct vb2_queue sur40_queue; static const struct vb2_queue sur40_queue;
static void sur40_process_video(struct sur40_state *sur40); static void sur40_process_video(struct sur40_state *sur40);
...@@ -420,7 +441,7 @@ static void sur40_process_video(struct sur40_state *sur40) ...@@ -420,7 +441,7 @@ static void sur40_process_video(struct sur40_state *sur40)
goto err_poll; goto err_poll;
} }
if (le32_to_cpu(img->size) != sur40_video_format.sizeimage) { if (le32_to_cpu(img->size) != sur40->pix_fmt.sizeimage) {
dev_err(sur40->dev, "image size mismatch\n"); dev_err(sur40->dev, "image size mismatch\n");
goto err_poll; goto err_poll;
} }
...@@ -431,7 +452,7 @@ static void sur40_process_video(struct sur40_state *sur40) ...@@ -431,7 +452,7 @@ static void sur40_process_video(struct sur40_state *sur40)
result = usb_sg_init(&sgr, sur40->usbdev, result = usb_sg_init(&sgr, sur40->usbdev,
usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT), 0, usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT), 0,
sgt->sgl, sgt->nents, sur40_video_format.sizeimage, 0); sgt->sgl, sgt->nents, sur40->pix_fmt.sizeimage, 0);
if (result < 0) { if (result < 0) {
dev_err(sur40->dev, "error %d in usb_sg_init\n", result); dev_err(sur40->dev, "error %d in usb_sg_init\n", result);
goto err_poll; goto err_poll;
...@@ -586,13 +607,14 @@ static int sur40_probe(struct usb_interface *interface, ...@@ -586,13 +607,14 @@ static int sur40_probe(struct usb_interface *interface,
if (error) if (error)
goto err_unreg_v4l2; goto err_unreg_v4l2;
sur40->pix_fmt = sur40_pix_format[0];
sur40->vdev = sur40_video_device; sur40->vdev = sur40_video_device;
sur40->vdev.v4l2_dev = &sur40->v4l2; sur40->vdev.v4l2_dev = &sur40->v4l2;
sur40->vdev.lock = &sur40->lock; sur40->vdev.lock = &sur40->lock;
sur40->vdev.queue = &sur40->queue; sur40->vdev.queue = &sur40->queue;
video_set_drvdata(&sur40->vdev, sur40); video_set_drvdata(&sur40->vdev, sur40);
error = video_register_device(&sur40->vdev, VFL_TYPE_GRABBER, -1); error = video_register_device(&sur40->vdev, VFL_TYPE_TOUCH, -1);
if (error) { if (error) {
dev_err(&interface->dev, dev_err(&interface->dev,
"Unable to register video subdevice."); "Unable to register video subdevice.");
...@@ -647,14 +669,16 @@ static int sur40_queue_setup(struct vb2_queue *q, ...@@ -647,14 +669,16 @@ static int sur40_queue_setup(struct vb2_queue *q,
unsigned int *nbuffers, unsigned int *nplanes, unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], struct device *alloc_devs[]) unsigned int sizes[], struct device *alloc_devs[])
{ {
struct sur40_state *sur40 = vb2_get_drv_priv(q);
if (q->num_buffers + *nbuffers < 3) if (q->num_buffers + *nbuffers < 3)
*nbuffers = 3 - q->num_buffers; *nbuffers = 3 - q->num_buffers;
if (*nplanes) if (*nplanes)
return sizes[0] < sur40_video_format.sizeimage ? -EINVAL : 0; return sizes[0] < sur40->pix_fmt.sizeimage ? -EINVAL : 0;
*nplanes = 1; *nplanes = 1;
sizes[0] = sur40_video_format.sizeimage; sizes[0] = sur40->pix_fmt.sizeimage;
return 0; return 0;
} }
...@@ -666,7 +690,7 @@ static int sur40_queue_setup(struct vb2_queue *q, ...@@ -666,7 +690,7 @@ static int sur40_queue_setup(struct vb2_queue *q,
static int sur40_buffer_prepare(struct vb2_buffer *vb) static int sur40_buffer_prepare(struct vb2_buffer *vb)
{ {
struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue); struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue);
unsigned long size = sur40_video_format.sizeimage; unsigned long size = sur40->pix_fmt.sizeimage;
if (vb2_plane_size(vb, 0) < size) { if (vb2_plane_size(vb, 0) < size) {
dev_err(&sur40->usbdev->dev, "buffer too small (%lu < %lu)\n", 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,7 +765,7 @@ static int sur40_vidioc_querycap(struct file *file, void *priv,
strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver)); strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver));
strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card)); strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card));
usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info)); usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info));
cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TOUCH |
V4L2_CAP_READWRITE | V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING; V4L2_CAP_STREAMING;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; 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,7 +777,7 @@ static int sur40_vidioc_enum_input(struct file *file, void *priv,
{ {
if (i->index != 0) if (i->index != 0)
return -EINVAL; return -EINVAL;
i->type = V4L2_INPUT_TYPE_CAMERA; i->type = V4L2_INPUT_TYPE_TOUCH;
i->std = V4L2_STD_UNKNOWN; i->std = V4L2_STD_UNKNOWN;
strlcpy(i->name, "In-Cell Sensor", sizeof(i->name)); strlcpy(i->name, "In-Cell Sensor", sizeof(i->name));
i->capabilities = 0; i->capabilities = 0;
...@@ -771,19 +795,57 @@ static int sur40_vidioc_g_input(struct file *file, void *priv, unsigned int *i) ...@@ -771,19 +795,57 @@ static int sur40_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
return 0; return 0;
} }
static int sur40_vidioc_fmt(struct file *file, void *priv, static int sur40_vidioc_try_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
switch (f->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_GREY:
f->fmt.pix = sur40_pix_format[1];
break;
default:
f->fmt.pix = sur40_pix_format[0];
break;
}
return 0;
}
static int sur40_vidioc_s_fmt(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
f->fmt.pix = sur40_video_format; struct sur40_state *sur40 = video_drvdata(file);
switch (f->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_GREY:
sur40->pix_fmt = sur40_pix_format[1];
break;
default:
sur40->pix_fmt = sur40_pix_format[0];
break;
}
f->fmt.pix = sur40->pix_fmt;
return 0;
}
static int sur40_vidioc_g_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
struct sur40_state *sur40 = video_drvdata(file);
f->fmt.pix = sur40->pix_fmt;
return 0; return 0;
} }
static int sur40_vidioc_enum_fmt(struct file *file, void *priv, static int sur40_vidioc_enum_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *f) struct v4l2_fmtdesc *f)
{ {
if (f->index != 0) if (f->index >= ARRAY_SIZE(sur40_pix_format))
return -EINVAL; return -EINVAL;
f->pixelformat = V4L2_PIX_FMT_GREY;
f->pixelformat = sur40_pix_format[f->index].pixelformat;
f->flags = 0; f->flags = 0;
return 0; return 0;
} }
...@@ -791,22 +853,28 @@ static int sur40_vidioc_enum_fmt(struct file *file, void *priv, ...@@ -791,22 +853,28 @@ static int sur40_vidioc_enum_fmt(struct file *file, void *priv,
static int sur40_vidioc_enum_framesizes(struct file *file, void *priv, static int sur40_vidioc_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *f) struct v4l2_frmsizeenum *f)
{ {
if ((f->index != 0) || (f->pixel_format != V4L2_PIX_FMT_GREY)) struct sur40_state *sur40 = video_drvdata(file);
if ((f->index != 0) || ((f->pixel_format != V4L2_TCH_FMT_TU08)
&& (f->pixel_format != V4L2_PIX_FMT_GREY)))
return -EINVAL; return -EINVAL;
f->type = V4L2_FRMSIZE_TYPE_DISCRETE; f->type = V4L2_FRMSIZE_TYPE_DISCRETE;
f->discrete.width = sur40_video_format.width; f->discrete.width = sur40->pix_fmt.width;
f->discrete.height = sur40_video_format.height; f->discrete.height = sur40->pix_fmt.height;
return 0; return 0;
} }
static int sur40_vidioc_enum_frameintervals(struct file *file, void *priv, static int sur40_vidioc_enum_frameintervals(struct file *file, void *priv,
struct v4l2_frmivalenum *f) struct v4l2_frmivalenum *f)
{ {
if ((f->index > 1) || (f->pixel_format != V4L2_PIX_FMT_GREY) struct sur40_state *sur40 = video_drvdata(file);
|| (f->width != sur40_video_format.width)
|| (f->height != sur40_video_format.height)) if ((f->index > 1) || ((f->pixel_format != V4L2_TCH_FMT_TU08)
return -EINVAL; && (f->pixel_format != V4L2_PIX_FMT_GREY))
|| (f->width != sur40->pix_fmt.width)
|| (f->height != sur40->pix_fmt.height))
return -EINVAL;
f->type = V4L2_FRMIVAL_TYPE_DISCRETE; f->type = V4L2_FRMIVAL_TYPE_DISCRETE;
f->discrete.denominator = 60/(f->index+1); f->discrete.denominator = 60/(f->index+1);
...@@ -862,9 +930,9 @@ static const struct v4l2_ioctl_ops sur40_video_ioctl_ops = { ...@@ -862,9 +930,9 @@ static const struct v4l2_ioctl_ops sur40_video_ioctl_ops = {
.vidioc_querycap = sur40_vidioc_querycap, .vidioc_querycap = sur40_vidioc_querycap,
.vidioc_enum_fmt_vid_cap = sur40_vidioc_enum_fmt, .vidioc_enum_fmt_vid_cap = sur40_vidioc_enum_fmt,
.vidioc_try_fmt_vid_cap = sur40_vidioc_fmt, .vidioc_try_fmt_vid_cap = sur40_vidioc_try_fmt,
.vidioc_s_fmt_vid_cap = sur40_vidioc_fmt, .vidioc_s_fmt_vid_cap = sur40_vidioc_s_fmt,
.vidioc_g_fmt_vid_cap = sur40_vidioc_fmt, .vidioc_g_fmt_vid_cap = sur40_vidioc_g_fmt,
.vidioc_enum_framesizes = sur40_vidioc_enum_framesizes, .vidioc_enum_framesizes = sur40_vidioc_enum_framesizes,
.vidioc_enum_frameintervals = sur40_vidioc_enum_frameintervals, .vidioc_enum_frameintervals = sur40_vidioc_enum_frameintervals,
...@@ -891,16 +959,6 @@ static const struct video_device sur40_video_device = { ...@@ -891,16 +959,6 @@ static const struct video_device sur40_video_device = {
.release = video_device_release_empty, .release = video_device_release_empty,
}; };
static const struct v4l2_pix_format sur40_video_format = {
.pixelformat = V4L2_PIX_FMT_GREY,
.width = SENSOR_RES_X / 2,
.height = SENSOR_RES_Y / 2,
.field = V4L2_FIELD_NONE,
.colorspace = V4L2_COLORSPACE_SRGB,
.bytesperline = SENSOR_RES_X / 2,
.sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
};
/* USB-specific object needed to register this driver with the USB subsystem. */ /* USB-specific object needed to register this driver with the USB subsystem. */
static struct usb_driver sur40_driver = { static struct usb_driver sur40_driver = {
.name = DRIVER_SHORT, .name = DRIVER_SHORT,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment