aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorFlorian Echtler <floe@butterbrot.org>2015-03-16 05:48:23 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-02 20:16:03 -0400
commite831cd251fb91d6c25352d322743db0d17ea11dd (patch)
tree5135234ea9f93644e21e1b4574b4feffa8c6b9a5 /drivers/input/touchscreen
parent5f853487328ba4d9d99d5be4900d804b1fdf1f15 (diff)
[media] add raw video stream support for Samsung SUR40
This patch adds raw video support for the Samsung SUR40 using vbuf2-dma-sg. All tests from v4l2-compliance pass. Support for VB2_USERPTR is currently disabled due to unexpected interference with dma-sg buffer sizes. Signed-off-by: Florian Echtler <floe@butterbrot.org> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> [hans.verkuil@cisco.com: fix compile warning: %ld -> %zd] Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/Kconfig2
-rw-r--r--drivers/input/touchscreen/sur40.c429
2 files changed, 419 insertions, 12 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 58917525126e..f8d16f15c1d1 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -953,7 +953,9 @@ config TOUCHSCREEN_SUN4I
953config TOUCHSCREEN_SUR40 953config TOUCHSCREEN_SUR40
954 tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen" 954 tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen"
955 depends on USB 955 depends on USB
956 depends on MEDIA_USB_SUPPORT
956 select INPUT_POLLDEV 957 select INPUT_POLLDEV
958 select VIDEOBUF2_DMA_SG
957 help 959 help
958 Say Y here if you want support for the Samsung SUR40 touchscreen 960 Say Y here if you want support for the Samsung SUR40 touchscreen
959 (also known as Microsoft Surface 2.0 or Microsoft PixelSense). 961 (also known as Microsoft Surface 2.0 or Microsoft PixelSense).
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index f1cb05148b46..b295e1744ea1 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Surface2.0/SUR40/PixelSense input driver 2 * Surface2.0/SUR40/PixelSense input driver
3 * 3 *
4 * Copyright (c) 2013 by Florian 'floe' Echtler <floe@butterbrot.org> 4 * Copyright (c) 2014 by Florian 'floe' Echtler <floe@butterbrot.org>
5 * 5 *
6 * Derived from the USB Skeleton driver 1.1, 6 * Derived from the USB Skeleton driver 1.1,
7 * Copyright (c) 2003 Greg Kroah-Hartman (greg@kroah.com) 7 * Copyright (c) 2003 Greg Kroah-Hartman (greg@kroah.com)
@@ -12,6 +12,9 @@
12 * and from the generic hid-multitouch driver, 12 * and from the generic hid-multitouch driver,
13 * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr> 13 * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
14 * 14 *
15 * and from the v4l2-pci-skeleton driver,
16 * Copyright (c) Copyright 2014 Cisco Systems, Inc.
17 *
15 * This program is free software; you can redistribute it and/or 18 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as 19 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of 20 * published by the Free Software Foundation; either version 2 of
@@ -31,6 +34,11 @@
31#include <linux/input-polldev.h> 34#include <linux/input-polldev.h>
32#include <linux/input/mt.h> 35#include <linux/input/mt.h>
33#include <linux/usb/input.h> 36#include <linux/usb/input.h>
37#include <linux/videodev2.h>
38#include <media/v4l2-device.h>
39#include <media/v4l2-dev.h>
40#include <media/v4l2-ioctl.h>
41#include <media/videobuf2-dma-sg.h>
34 42
35/* read 512 bytes from endpoint 0x86 -> get header + blobs */ 43/* read 512 bytes from endpoint 0x86 -> get header + blobs */
36struct sur40_header { 44struct sur40_header {
@@ -82,9 +90,19 @@ struct sur40_data {
82 struct sur40_blob blobs[]; 90 struct sur40_blob blobs[];
83} __packed; 91} __packed;
84 92
93/* read 512 bytes from endpoint 0x82 -> get header below
94 * continue reading 16k blocks until header.size bytes read */
95struct sur40_image_header {
96 __le32 magic; /* "SUBF" */
97 __le32 packet_id;
98 __le32 size; /* always 0x0007e900 = 960x540 */
99 __le32 timestamp; /* milliseconds (increases by 16 or 17 each frame) */
100 __le32 unknown; /* "epoch?" always 02/03 00 00 00 */
101} __packed;
85 102
86/* version information */ 103/* version information */
87#define DRIVER_SHORT "sur40" 104#define DRIVER_SHORT "sur40"
105#define DRIVER_LONG "Samsung SUR40"
88#define DRIVER_AUTHOR "Florian 'floe' Echtler <floe@butterbrot.org>" 106#define DRIVER_AUTHOR "Florian 'floe' Echtler <floe@butterbrot.org>"
89#define DRIVER_DESC "Surface2.0/SUR40/PixelSense input driver" 107#define DRIVER_DESC "Surface2.0/SUR40/PixelSense input driver"
90 108
@@ -99,6 +117,13 @@ struct sur40_data {
99/* touch data endpoint */ 117/* touch data endpoint */
100#define TOUCH_ENDPOINT 0x86 118#define TOUCH_ENDPOINT 0x86
101 119
120/* video data endpoint */
121#define VIDEO_ENDPOINT 0x82
122
123/* video header fields */
124#define VIDEO_HEADER_MAGIC 0x46425553
125#define VIDEO_PACKET_SIZE 16384
126
102/* polling interval (ms) */ 127/* polling interval (ms) */
103#define POLL_INTERVAL 10 128#define POLL_INTERVAL 10
104 129
@@ -113,21 +138,23 @@ struct sur40_data {
113#define SUR40_GET_STATE 0xc5 /* 4 bytes state (?) */ 138#define SUR40_GET_STATE 0xc5 /* 4 bytes state (?) */
114#define SUR40_GET_SENSORS 0xb1 /* 8 bytes sensors */ 139#define SUR40_GET_SENSORS 0xb1 /* 8 bytes sensors */
115 140
116/* 141/* master device state */
117 * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
118 * here by mistake which is very likely to have corrupted the firmware EEPROM
119 * on two separate SUR40 devices. Thanks to Alan Stern who spotted this bug.
120 * Should you ever run into a similar problem, the background story to this
121 * incident and instructions on how to fix the corrupted EEPROM are available
122 * at https://floe.butterbrot.org/matrix/hacking/surface/brick.html
123*/
124
125struct sur40_state { 142struct sur40_state {
126 143
127 struct usb_device *usbdev; 144 struct usb_device *usbdev;
128 struct device *dev; 145 struct device *dev;
129 struct input_polled_dev *input; 146 struct input_polled_dev *input;
130 147
148 struct v4l2_device v4l2;
149 struct video_device vdev;
150 struct mutex lock;
151
152 struct vb2_queue queue;
153 struct vb2_alloc_ctx *alloc_ctx;
154 struct list_head buf_list;
155 spinlock_t qlock;
156 int sequence;
157
131 struct sur40_data *bulk_in_buffer; 158 struct sur40_data *bulk_in_buffer;
132 size_t bulk_in_size; 159 size_t bulk_in_size;
133 u8 bulk_in_epaddr; 160 u8 bulk_in_epaddr;
@@ -135,6 +162,27 @@ struct sur40_state {
135 char phys[64]; 162 char phys[64];
136}; 163};
137 164
165struct sur40_buffer {
166 struct vb2_buffer vb;
167 struct list_head list;
168};
169
170/* forward declarations */
171static const struct video_device sur40_video_device;
172static const struct v4l2_pix_format sur40_video_format;
173static const struct vb2_queue sur40_queue;
174static void sur40_process_video(struct sur40_state *sur40);
175
176/*
177 * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
178 * here by mistake which is very likely to have corrupted the firmware EEPROM
179 * on two separate SUR40 devices. Thanks to Alan Stern who spotted this bug.
180 * Should you ever run into a similar problem, the background story to this
181 * incident and instructions on how to fix the corrupted EEPROM are available
182 * at https://floe.butterbrot.org/matrix/hacking/surface/brick.html
183*/
184
185/* command wrapper */
138static int sur40_command(struct sur40_state *dev, 186static int sur40_command(struct sur40_state *dev,
139 u8 command, u16 index, void *buffer, u16 size) 187 u8 command, u16 index, void *buffer, u16 size)
140{ 188{
@@ -247,7 +295,6 @@ static void sur40_report_blob(struct sur40_blob *blob, struct input_dev *input)
247/* core function: poll for new input data */ 295/* core function: poll for new input data */
248static void sur40_poll(struct input_polled_dev *polldev) 296static void sur40_poll(struct input_polled_dev *polldev)
249{ 297{
250
251 struct sur40_state *sur40 = polldev->private; 298 struct sur40_state *sur40 = polldev->private;
252 struct input_dev *input = polldev->input; 299 struct input_dev *input = polldev->input;
253 int result, bulk_read, need_blobs, packet_blobs, i; 300 int result, bulk_read, need_blobs, packet_blobs, i;
@@ -314,6 +361,81 @@ static void sur40_poll(struct input_polled_dev *polldev)
314 361
315 input_mt_sync_frame(input); 362 input_mt_sync_frame(input);
316 input_sync(input); 363 input_sync(input);
364
365 sur40_process_video(sur40);
366}
367
368/* deal with video data */
369static void sur40_process_video(struct sur40_state *sur40)
370{
371
372 struct sur40_image_header *img = (void *)(sur40->bulk_in_buffer);
373 struct sur40_buffer *new_buf;
374 struct usb_sg_request sgr;
375 struct sg_table *sgt;
376 int result, bulk_read;
377
378 if (!vb2_start_streaming_called(&sur40->queue))
379 return;
380
381 /* get a new buffer from the list */
382 spin_lock(&sur40->qlock);
383 new_buf = list_entry(sur40->buf_list.next, struct sur40_buffer, list);
384 list_del(&new_buf->list);
385 spin_unlock(&sur40->qlock);
386
387 /* retrieve data via bulk read */
388 result = usb_bulk_msg(sur40->usbdev,
389 usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT),
390 sur40->bulk_in_buffer, sur40->bulk_in_size,
391 &bulk_read, 1000);
392
393 if (result < 0) {
394 dev_err(sur40->dev, "error in usb_bulk_read\n");
395 goto err_poll;
396 }
397
398 if (bulk_read != sizeof(struct sur40_image_header)) {
399 dev_err(sur40->dev, "received %d bytes (%zd expected)\n",
400 bulk_read, sizeof(struct sur40_image_header));
401 goto err_poll;
402 }
403
404 if (le32_to_cpu(img->magic) != VIDEO_HEADER_MAGIC) {
405 dev_err(sur40->dev, "image magic mismatch\n");
406 goto err_poll;
407 }
408
409 if (le32_to_cpu(img->size) != sur40_video_format.sizeimage) {
410 dev_err(sur40->dev, "image size mismatch\n");
411 goto err_poll;
412 }
413
414 sgt = vb2_dma_sg_plane_desc(&new_buf->vb, 0);
415
416 result = usb_sg_init(&sgr, sur40->usbdev,
417 usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT), 0,
418 sgt->sgl, sgt->nents, sur40_video_format.sizeimage, 0);
419 if (result < 0) {
420 dev_err(sur40->dev, "error %d in usb_sg_init\n", result);
421 goto err_poll;
422 }
423
424 usb_sg_wait(&sgr);
425 if (sgr.status < 0) {
426 dev_err(sur40->dev, "error %d in usb_sg_wait\n", sgr.status);
427 goto err_poll;
428 }
429
430 /* mark as finished */
431 v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp);
432 new_buf->vb.v4l2_buf.sequence = sur40->sequence++;
433 new_buf->vb.v4l2_buf.field = V4L2_FIELD_NONE;
434 vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE);
435 return;
436
437err_poll:
438 vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_ERROR);
317} 439}
318 440
319/* Initialize input device parameters. */ 441/* Initialize input device parameters. */
@@ -377,6 +499,11 @@ static int sur40_probe(struct usb_interface *interface,
377 goto err_free_dev; 499 goto err_free_dev;
378 } 500 }
379 501
502 /* initialize locks/lists */
503 INIT_LIST_HEAD(&sur40->buf_list);
504 spin_lock_init(&sur40->qlock);
505 mutex_init(&sur40->lock);
506
380 /* Set up polled input device control structure */ 507 /* Set up polled input device control structure */
381 poll_dev->private = sur40; 508 poll_dev->private = sur40;
382 poll_dev->poll_interval = POLL_INTERVAL; 509 poll_dev->poll_interval = POLL_INTERVAL;
@@ -387,7 +514,7 @@ static int sur40_probe(struct usb_interface *interface,
387 /* Set up regular input device structure */ 514 /* Set up regular input device structure */
388 sur40_input_setup(poll_dev->input); 515 sur40_input_setup(poll_dev->input);
389 516
390 poll_dev->input->name = "Samsung SUR40"; 517 poll_dev->input->name = DRIVER_LONG;
391 usb_to_input_id(usbdev, &poll_dev->input->id); 518 usb_to_input_id(usbdev, &poll_dev->input->id);
392 usb_make_path(usbdev, sur40->phys, sizeof(sur40->phys)); 519 usb_make_path(usbdev, sur40->phys, sizeof(sur40->phys));
393 strlcat(sur40->phys, "/input0", sizeof(sur40->phys)); 520 strlcat(sur40->phys, "/input0", sizeof(sur40->phys));
@@ -408,6 +535,7 @@ static int sur40_probe(struct usb_interface *interface,
408 goto err_free_polldev; 535 goto err_free_polldev;
409 } 536 }
410 537
538 /* register the polled input device */
411 error = input_register_polled_device(poll_dev); 539 error = input_register_polled_device(poll_dev);
412 if (error) { 540 if (error) {
413 dev_err(&interface->dev, 541 dev_err(&interface->dev,
@@ -415,12 +543,54 @@ static int sur40_probe(struct usb_interface *interface,
415 goto err_free_buffer; 543 goto err_free_buffer;
416 } 544 }
417 545
546 /* register the video master device */
547 snprintf(sur40->v4l2.name, sizeof(sur40->v4l2.name), "%s", DRIVER_LONG);
548 error = v4l2_device_register(sur40->dev, &sur40->v4l2);
549 if (error) {
550 dev_err(&interface->dev,
551 "Unable to register video master device.");
552 goto err_unreg_v4l2;
553 }
554
555 /* initialize the lock and subdevice */
556 sur40->queue = sur40_queue;
557 sur40->queue.drv_priv = sur40;
558 sur40->queue.lock = &sur40->lock;
559
560 /* initialize the queue */
561 error = vb2_queue_init(&sur40->queue);
562 if (error)
563 goto err_unreg_v4l2;
564
565 sur40->alloc_ctx = vb2_dma_sg_init_ctx(sur40->dev);
566 if (IS_ERR(sur40->alloc_ctx)) {
567 dev_err(sur40->dev, "Can't allocate buffer context");
568 goto err_unreg_v4l2;
569 }
570
571 sur40->vdev = sur40_video_device;
572 sur40->vdev.v4l2_dev = &sur40->v4l2;
573 sur40->vdev.lock = &sur40->lock;
574 sur40->vdev.queue = &sur40->queue;
575 video_set_drvdata(&sur40->vdev, sur40);
576
577 error = video_register_device(&sur40->vdev, VFL_TYPE_GRABBER, -1);
578 if (error) {
579 dev_err(&interface->dev,
580 "Unable to register video subdevice.");
581 goto err_unreg_video;
582 }
583
418 /* we can register the device now, as it is ready */ 584 /* we can register the device now, as it is ready */
419 usb_set_intfdata(interface, sur40); 585 usb_set_intfdata(interface, sur40);
420 dev_dbg(&interface->dev, "%s is now attached\n", DRIVER_DESC); 586 dev_dbg(&interface->dev, "%s is now attached\n", DRIVER_DESC);
421 587
422 return 0; 588 return 0;
423 589
590err_unreg_video:
591 video_unregister_device(&sur40->vdev);
592err_unreg_v4l2:
593 v4l2_device_unregister(&sur40->v4l2);
424err_free_buffer: 594err_free_buffer:
425 kfree(sur40->bulk_in_buffer); 595 kfree(sur40->bulk_in_buffer);
426err_free_polldev: 596err_free_polldev:
@@ -436,6 +606,10 @@ static void sur40_disconnect(struct usb_interface *interface)
436{ 606{
437 struct sur40_state *sur40 = usb_get_intfdata(interface); 607 struct sur40_state *sur40 = usb_get_intfdata(interface);
438 608
609 video_unregister_device(&sur40->vdev);
610 v4l2_device_unregister(&sur40->v4l2);
611 vb2_dma_sg_cleanup_ctx(sur40->alloc_ctx);
612
439 input_unregister_polled_device(sur40->input); 613 input_unregister_polled_device(sur40->input);
440 input_free_polled_device(sur40->input); 614 input_free_polled_device(sur40->input);
441 kfree(sur40->bulk_in_buffer); 615 kfree(sur40->bulk_in_buffer);
@@ -445,12 +619,243 @@ static void sur40_disconnect(struct usb_interface *interface)
445 dev_dbg(&interface->dev, "%s is now disconnected\n", DRIVER_DESC); 619 dev_dbg(&interface->dev, "%s is now disconnected\n", DRIVER_DESC);
446} 620}
447 621
622/*
623 * Setup the constraints of the queue: besides setting the number of planes
624 * per buffer and the size and allocation context of each plane, it also
625 * checks if sufficient buffers have been allocated. Usually 3 is a good
626 * minimum number: many DMA engines need a minimum of 2 buffers in the
627 * queue and you need to have another available for userspace processing.
628 */
629static int sur40_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
630 unsigned int *nbuffers, unsigned int *nplanes,
631 unsigned int sizes[], void *alloc_ctxs[])
632{
633 struct sur40_state *sur40 = vb2_get_drv_priv(q);
634
635 if (q->num_buffers + *nbuffers < 3)
636 *nbuffers = 3 - q->num_buffers;
637
638 if (fmt && fmt->fmt.pix.sizeimage < sur40_video_format.sizeimage)
639 return -EINVAL;
640
641 *nplanes = 1;
642 sizes[0] = fmt ? fmt->fmt.pix.sizeimage : sur40_video_format.sizeimage;
643 alloc_ctxs[0] = sur40->alloc_ctx;
644
645 return 0;
646}
647
648/*
649 * Prepare the buffer for queueing to the DMA engine: check and set the
650 * payload size.
651 */
652static int sur40_buffer_prepare(struct vb2_buffer *vb)
653{
654 struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue);
655 unsigned long size = sur40_video_format.sizeimage;
656
657 if (vb2_plane_size(vb, 0) < size) {
658 dev_err(&sur40->usbdev->dev, "buffer too small (%lu < %lu)\n",
659 vb2_plane_size(vb, 0), size);
660 return -EINVAL;
661 }
662
663 vb2_set_plane_payload(vb, 0, size);
664 return 0;
665}
666
667/*
668 * Queue this buffer to the DMA engine.
669 */
670static void sur40_buffer_queue(struct vb2_buffer *vb)
671{
672 struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue);
673 struct sur40_buffer *buf = (struct sur40_buffer *)vb;
674
675 spin_lock(&sur40->qlock);
676 list_add_tail(&buf->list, &sur40->buf_list);
677 spin_unlock(&sur40->qlock);
678}
679
680static void return_all_buffers(struct sur40_state *sur40,
681 enum vb2_buffer_state state)
682{
683 struct sur40_buffer *buf, *node;
684
685 spin_lock(&sur40->qlock);
686 list_for_each_entry_safe(buf, node, &sur40->buf_list, list) {
687 vb2_buffer_done(&buf->vb, state);
688 list_del(&buf->list);
689 }
690 spin_unlock(&sur40->qlock);
691}
692
693/*
694 * Start streaming. First check if the minimum number of buffers have been
695 * queued. If not, then return -ENOBUFS and the vb2 framework will call
696 * this function again the next time a buffer has been queued until enough
697 * buffers are available to actually start the DMA engine.
698 */
699static int sur40_start_streaming(struct vb2_queue *vq, unsigned int count)
700{
701 struct sur40_state *sur40 = vb2_get_drv_priv(vq);
702
703 sur40->sequence = 0;
704 return 0;
705}
706
707/*
708 * Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued
709 * and passed on to the vb2 framework marked as STATE_ERROR.
710 */
711static void sur40_stop_streaming(struct vb2_queue *vq)
712{
713 struct sur40_state *sur40 = vb2_get_drv_priv(vq);
714
715 /* Release all active buffers */
716 return_all_buffers(sur40, VB2_BUF_STATE_ERROR);
717}
718
719/* V4L ioctl */
720static int sur40_vidioc_querycap(struct file *file, void *priv,
721 struct v4l2_capability *cap)
722{
723 struct sur40_state *sur40 = video_drvdata(file);
724
725 strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver));
726 strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card));
727 usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info));
728 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
729 V4L2_CAP_READWRITE |
730 V4L2_CAP_STREAMING;
731 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
732 return 0;
733}
734
735static int sur40_vidioc_enum_input(struct file *file, void *priv,
736 struct v4l2_input *i)
737{
738 if (i->index != 0)
739 return -EINVAL;
740 i->type = V4L2_INPUT_TYPE_CAMERA;
741 i->std = V4L2_STD_UNKNOWN;
742 strlcpy(i->name, "In-Cell Sensor", sizeof(i->name));
743 i->capabilities = 0;
744 return 0;
745}
746
747static int sur40_vidioc_s_input(struct file *file, void *priv, unsigned int i)
748{
749 return (i == 0) ? 0 : -EINVAL;
750}
751
752static int sur40_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
753{
754 *i = 0;
755 return 0;
756}
757
758static int sur40_vidioc_fmt(struct file *file, void *priv,
759 struct v4l2_format *f)
760{
761 f->fmt.pix = sur40_video_format;
762 return 0;
763}
764
765static int sur40_vidioc_enum_fmt(struct file *file, void *priv,
766 struct v4l2_fmtdesc *f)
767{
768 if (f->index != 0)
769 return -EINVAL;
770 strlcpy(f->description, "8-bit greyscale", sizeof(f->description));
771 f->pixelformat = V4L2_PIX_FMT_GREY;
772 f->flags = 0;
773 return 0;
774}
775
448static const struct usb_device_id sur40_table[] = { 776static const struct usb_device_id sur40_table[] = {
449 { USB_DEVICE(ID_MICROSOFT, ID_SUR40) }, /* Samsung SUR40 */ 777 { USB_DEVICE(ID_MICROSOFT, ID_SUR40) }, /* Samsung SUR40 */
450 { } /* terminating null entry */ 778 { } /* terminating null entry */
451}; 779};
452MODULE_DEVICE_TABLE(usb, sur40_table); 780MODULE_DEVICE_TABLE(usb, sur40_table);
453 781
782/* V4L2 structures */
783static const struct vb2_ops sur40_queue_ops = {
784 .queue_setup = sur40_queue_setup,
785 .buf_prepare = sur40_buffer_prepare,
786 .buf_queue = sur40_buffer_queue,
787 .start_streaming = sur40_start_streaming,
788 .stop_streaming = sur40_stop_streaming,
789 .wait_prepare = vb2_ops_wait_prepare,
790 .wait_finish = vb2_ops_wait_finish,
791};
792
793static const struct vb2_queue sur40_queue = {
794 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
795 /*
796 * VB2_USERPTR in currently not enabled: passing a user pointer to
797 * dma-sg will result in segment sizes that are not a multiple of
798 * 512 bytes, which is required by the host controller.
799 */
800 .io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF,
801 .buf_struct_size = sizeof(struct sur40_buffer),
802 .ops = &sur40_queue_ops,
803 .mem_ops = &vb2_dma_sg_memops,
804 .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
805 .min_buffers_needed = 3,
806};
807
808static const struct v4l2_file_operations sur40_video_fops = {
809 .owner = THIS_MODULE,
810 .open = v4l2_fh_open,
811 .release = vb2_fop_release,
812 .unlocked_ioctl = video_ioctl2,
813 .read = vb2_fop_read,
814 .mmap = vb2_fop_mmap,
815 .poll = vb2_fop_poll,
816};
817
818static const struct v4l2_ioctl_ops sur40_video_ioctl_ops = {
819
820 .vidioc_querycap = sur40_vidioc_querycap,
821
822 .vidioc_enum_fmt_vid_cap = sur40_vidioc_enum_fmt,
823 .vidioc_try_fmt_vid_cap = sur40_vidioc_fmt,
824 .vidioc_s_fmt_vid_cap = sur40_vidioc_fmt,
825 .vidioc_g_fmt_vid_cap = sur40_vidioc_fmt,
826
827 .vidioc_enum_input = sur40_vidioc_enum_input,
828 .vidioc_g_input = sur40_vidioc_g_input,
829 .vidioc_s_input = sur40_vidioc_s_input,
830
831 .vidioc_reqbufs = vb2_ioctl_reqbufs,
832 .vidioc_create_bufs = vb2_ioctl_create_bufs,
833 .vidioc_querybuf = vb2_ioctl_querybuf,
834 .vidioc_qbuf = vb2_ioctl_qbuf,
835 .vidioc_dqbuf = vb2_ioctl_dqbuf,
836 .vidioc_expbuf = vb2_ioctl_expbuf,
837
838 .vidioc_streamon = vb2_ioctl_streamon,
839 .vidioc_streamoff = vb2_ioctl_streamoff,
840};
841
842static const struct video_device sur40_video_device = {
843 .name = DRIVER_LONG,
844 .fops = &sur40_video_fops,
845 .ioctl_ops = &sur40_video_ioctl_ops,
846 .release = video_device_release_empty,
847};
848
849static const struct v4l2_pix_format sur40_video_format = {
850 .pixelformat = V4L2_PIX_FMT_GREY,
851 .width = SENSOR_RES_X / 2,
852 .height = SENSOR_RES_Y / 2,
853 .field = V4L2_FIELD_NONE,
854 .colorspace = V4L2_COLORSPACE_SRGB,
855 .bytesperline = SENSOR_RES_X / 2,
856 .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
857};
858
454/* USB-specific object needed to register this driver with the USB subsystem. */ 859/* USB-specific object needed to register this driver with the USB subsystem. */
455static struct usb_driver sur40_driver = { 860static struct usb_driver sur40_driver = {
456 .name = DRIVER_SHORT, 861 .name = DRIVER_SHORT,