linux/drivers/input/touchscreen/sur40.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Surface2.0/SUR40/PixelSense input driver
 *
 * Copyright (c) 2014 by Florian 'floe' Echtler <[email protected]>
 *
 * Derived from the USB Skeleton driver 1.1,
 * Copyright (c) 2003 Greg Kroah-Hartman ([email protected])
 *
 * and from the Apple USB BCM5974 multitouch driver,
 * Copyright (c) 2008 Henrik Rydberg ([email protected])
 *
 * and from the generic hid-multitouch driver,
 * Copyright (c) 2010-2012 Stephane Chatty <[email protected]>
 *
 * and from the v4l2-pci-skeleton driver,
 * Copyright (c) Copyright 2014 Cisco Systems, Inc.
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/completion.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/printk.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/usb/input.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-sg.h>

/* read 512 bytes from endpoint 0x86 -> get header + blobs */
struct sur40_header {} __packed;

struct sur40_blob {} __packed;

/* combined header/blob data */
struct sur40_data {} __packed;

/* read 512 bytes from endpoint 0x82 -> get header below
 * continue reading 16k blocks until header.size bytes read */
struct sur40_image_header {} __packed;

/* version information */
#define DRIVER_SHORT
#define DRIVER_LONG
#define DRIVER_AUTHOR
#define DRIVER_DESC

/* vendor and device IDs */
#define ID_MICROSOFT
#define ID_SUR40

/* sensor resolution */
#define SENSOR_RES_X
#define SENSOR_RES_Y

/* touch data endpoint */
#define TOUCH_ENDPOINT

/* video data endpoint */
#define VIDEO_ENDPOINT

/* video header fields */
#define VIDEO_HEADER_MAGIC
#define VIDEO_PACKET_SIZE

/* polling interval (ms) */
#define POLL_INTERVAL

/* maximum number of contacts FIXME: this is a guess? */
#define MAX_CONTACTS

/* control commands */
#define SUR40_GET_VERSION
#define SUR40_ACCEL_CAPS
#define SUR40_SENSOR_CAPS

#define SUR40_POKE
#define SUR40_PEEK

#define SUR40_GET_STATE
#define SUR40_GET_SENSORS

#define SUR40_BLOB
#define SUR40_TOUCH
#define SUR40_TAG

/* video controls */
#define SUR40_BRIGHTNESS_MAX
#define SUR40_BRIGHTNESS_MIN
#define SUR40_BRIGHTNESS_DEF

#define SUR40_CONTRAST_MAX
#define SUR40_CONTRAST_MIN
#define SUR40_CONTRAST_DEF

#define SUR40_GAIN_MAX
#define SUR40_GAIN_MIN
#define SUR40_GAIN_DEF

#define SUR40_BACKLIGHT_MAX
#define SUR40_BACKLIGHT_MIN
#define SUR40_BACKLIGHT_DEF

#define sur40_str(s)
#define SUR40_PARAM_RANGE(lo, hi)

/* module parameters */
static uint brightness =;
module_param(brightness, uint, 0644);
MODULE_PARM_DESC();
static uint contrast =;
module_param(contrast, uint, 0644);
MODULE_PARM_DESC();
static uint gain =;
module_param(gain, uint, 0644);
MODULE_PARM_DESC();

static const struct v4l2_pix_format sur40_pix_format[] =;

/* master device state */
struct sur40_state {};

struct sur40_buffer {};

/* forward declarations */
static const struct video_device sur40_video_device;
static const struct vb2_queue sur40_queue;
static void sur40_process_video(struct sur40_state *sur40);
static int sur40_s_ctrl(struct v4l2_ctrl *ctrl);

static const struct v4l2_ctrl_ops sur40_ctrl_ops =;

/*
 * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
 * here by mistake which is very likely to have corrupted the firmware EEPROM
 * on two separate SUR40 devices. Thanks to Alan Stern who spotted this bug.
 * Should you ever run into a similar problem, the background story to this
 * incident and instructions on how to fix the corrupted EEPROM are available
 * at https://floe.butterbrot.org/matrix/hacking/surface/brick.html
*/

/* command wrapper */
static int sur40_command(struct sur40_state *dev,
			 u8 command, u16 index, void *buffer, u16 size)
{}

/* poke a byte in the panel register space */
static int sur40_poke(struct sur40_state *dev, u8 offset, u8 value)
{}

static int sur40_set_preprocessor(struct sur40_state *dev, u8 value)
{}

static void sur40_set_vsvideo(struct sur40_state *handle, u8 value)
{}

static void sur40_set_irlevel(struct sur40_state *handle, u8 value)
{}

/* Initialization routine, called from sur40_open */
static int sur40_init(struct sur40_state *dev)
{}

/*
 * Callback routines from input_dev
 */

/* Enable the device, polling will now start. */
static int sur40_open(struct input_dev *input)
{}

/* Disable device, polling has stopped. */
static void sur40_close(struct input_dev *input)
{}

/*
 * This function is called when a whole contact has been processed,
 * so that it can assign it to a slot and store the data there.
 */
static void sur40_report_blob(struct sur40_blob *blob, struct input_dev *input)
{}

/* core function: poll for new input data */
static void sur40_poll(struct input_dev *input)
{}

/* deal with video data */
static void sur40_process_video(struct sur40_state *sur40)
{}

/* Initialize input device parameters. */
static int sur40_input_setup_events(struct input_dev *input_dev)
{}

/* Check candidate USB interface. */
static int sur40_probe(struct usb_interface *interface,
		       const struct usb_device_id *id)
{}

/* Unregister device & clean up. */
static void sur40_disconnect(struct usb_interface *interface)
{}

/*
 * Setup the constraints of the queue: besides setting the number of planes
 * per buffer and the size and allocation context of each plane, it also
 * checks if sufficient buffers have been allocated. Usually 3 is a good
 * minimum number: many DMA engines need a minimum of 2 buffers in the
 * queue and you need to have another available for userspace processing.
 */
static int sur40_queue_setup(struct vb2_queue *q,
		       unsigned int *nbuffers, unsigned int *nplanes,
		       unsigned int sizes[], struct device *alloc_devs[])
{}

/*
 * Prepare the buffer for queueing to the DMA engine: check and set the
 * payload size.
 */
static int sur40_buffer_prepare(struct vb2_buffer *vb)
{}

/*
 * Queue this buffer to the DMA engine.
 */
static void sur40_buffer_queue(struct vb2_buffer *vb)
{}

static void return_all_buffers(struct sur40_state *sur40,
			       enum vb2_buffer_state state)
{}

/*
 * Start streaming. First check if the minimum number of buffers have been
 * queued. If not, then return -ENOBUFS and the vb2 framework will call
 * this function again the next time a buffer has been queued until enough
 * buffers are available to actually start the DMA engine.
 */
static int sur40_start_streaming(struct vb2_queue *vq, unsigned int count)
{}

/*
 * Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued
 * and passed on to the vb2 framework marked as STATE_ERROR.
 */
static void sur40_stop_streaming(struct vb2_queue *vq)
{}

/* V4L ioctl */
static int sur40_vidioc_querycap(struct file *file, void *priv,
				 struct v4l2_capability *cap)
{}

static int sur40_vidioc_enum_input(struct file *file, void *priv,
				   struct v4l2_input *i)
{}

static int sur40_vidioc_s_input(struct file *file, void *priv, unsigned int i)
{}

static int sur40_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{}

static int sur40_vidioc_try_fmt(struct file *file, void *priv,
			    struct v4l2_format *f)
{}

static int sur40_vidioc_s_fmt(struct file *file, void *priv,
			    struct v4l2_format *f)
{}

static int sur40_vidioc_g_fmt(struct file *file, void *priv,
			    struct v4l2_format *f)
{}

static int sur40_s_ctrl(struct v4l2_ctrl *ctrl)
{}

static int sur40_ioctl_parm(struct file *file, void *priv,
			    struct v4l2_streamparm *p)
{}

static int sur40_vidioc_enum_fmt(struct file *file, void *priv,
				 struct v4l2_fmtdesc *f)
{}

static int sur40_vidioc_enum_framesizes(struct file *file, void *priv,
					struct v4l2_frmsizeenum *f)
{}

static int sur40_vidioc_enum_frameintervals(struct file *file, void *priv,
					    struct v4l2_frmivalenum *f)
{}


static const struct usb_device_id sur40_table[] =;
MODULE_DEVICE_TABLE(usb, sur40_table);

/* V4L2 structures */
static const struct vb2_ops sur40_queue_ops =;

static const struct vb2_queue sur40_queue =;

static const struct v4l2_file_operations sur40_video_fops =;

static const struct v4l2_ioctl_ops sur40_video_ioctl_ops =;

static const struct video_device sur40_video_device =;

/* USB-specific object needed to register this driver with the USB subsystem. */
static struct usb_driver sur40_driver =;

module_usb_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();