diff options
Diffstat (limited to 'drivers/input/rmi4/rmi_f54.c')
| -rw-r--r-- | drivers/input/rmi4/rmi_f54.c | 98 |
1 files changed, 49 insertions, 49 deletions
diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c index a6f515bcab22..ac4041a69fcd 100644 --- a/drivers/input/rmi4/rmi_f54.c +++ b/drivers/input/rmi4/rmi_f54.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2015 Synaptics Incorporated * Copyright (C) 2016 Zodiac Inflight Innovations - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. */ #include <linux/kernel.h> @@ -27,6 +24,12 @@ #define F54_NUM_TX_OFFSET 1 #define F54_NUM_RX_OFFSET 0 +/* + * The smbus protocol can read only 32 bytes max at a time. + * But this should be fine for i2c/spi as well. + */ +#define F54_REPORT_DATA_SIZE 32 + /* F54 commands */ #define F54_GET_REPORT 1 #define F54_FORCE_CAL 2 @@ -39,6 +42,8 @@ /** * enum rmi_f54_report_type - RMI4 F54 report types * + * @F54_REPORT_NONE: No Image Report. + * * @F54_8BIT_IMAGE: Normalized 8-Bit Image Report. The capacitance variance * from baseline for each pixel. * @@ -61,6 +66,10 @@ * Report. Set Low reference to its minimum value and high * references to its maximum value, then report the raw * capacitance for each pixel. + * + * @F54_MAX_REPORT_TYPE: + * Maximum number of Report Types. Used for sanity + * checking. */ enum rmi_f54_report_type { F54_REPORT_NONE = 0, @@ -84,11 +93,6 @@ static const char * const rmi_f54_report_type_names[] = { = "Full Raw Capacitance RX Offset Removed", }; -struct rmi_f54_reports { - int start; - int size; -}; - struct f54_data { struct rmi_function *fn; @@ -101,7 +105,6 @@ struct f54_data { enum rmi_f54_report_type report_type; u8 *report_data; int report_size; - struct rmi_f54_reports standard_report[2]; bool is_busy; struct mutex status_mutex; @@ -119,6 +122,7 @@ struct f54_data { struct video_device vdev; struct vb2_queue queue; struct mutex lock; + u32 sequence; int input; enum rmi_f54_report_type inputs[F54_MAX_REPORT_TYPE]; }; @@ -293,6 +297,7 @@ static int rmi_f54_queue_setup(struct vb2_queue *q, unsigned int *nbuffers, static void rmi_f54_buffer_queue(struct vb2_buffer *vb) { + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct f54_data *f54 = vb2_get_drv_priv(vb->vb2_queue); u16 *ptr; enum vb2_buffer_state state; @@ -301,6 +306,7 @@ static void rmi_f54_buffer_queue(struct vb2_buffer *vb) mutex_lock(&f54->status_mutex); + vb2_set_plane_payload(vb, 0, 0); reptype = rmi_f54_get_reptype(f54, f54->input); if (reptype == F54_REPORT_NONE) { state = VB2_BUF_STATE_ERROR; @@ -347,26 +353,34 @@ static void rmi_f54_buffer_queue(struct vb2_buffer *vb) data_done: mutex_unlock(&f54->data_mutex); done: + vb->timestamp = ktime_get_ns(); + vbuf->field = V4L2_FIELD_NONE; + vbuf->sequence = f54->sequence++; vb2_buffer_done(vb, state); mutex_unlock(&f54->status_mutex); } +static void rmi_f54_stop_streaming(struct vb2_queue *q) +{ + struct f54_data *f54 = vb2_get_drv_priv(q); + + f54->sequence = 0; +} + /* V4L2 structures */ static const struct vb2_ops rmi_f54_queue_ops = { .queue_setup = rmi_f54_queue_setup, .buf_queue = rmi_f54_buffer_queue, - .wait_prepare = vb2_ops_wait_prepare, - .wait_finish = vb2_ops_wait_finish, + .stop_streaming = rmi_f54_stop_streaming, }; static const struct vb2_queue rmi_f54_queue = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ, - .buf_struct_size = sizeof(struct vb2_buffer), + .buf_struct_size = sizeof(struct vb2_v4l2_buffer), .ops = &rmi_f54_queue_ops, .mem_ops = &vb2_vmalloc_memops, .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC, - .min_buffers_needed = 1, }; static int rmi_f54_vidioc_querycap(struct file *file, void *priv, @@ -374,8 +388,8 @@ static int rmi_f54_vidioc_querycap(struct file *file, void *priv, { struct f54_data *f54 = video_drvdata(file); - strlcpy(cap->driver, F54_NAME, sizeof(cap->driver)); - strlcpy(cap->card, SYNAPTICS_INPUT_DEVICE_NAME, sizeof(cap->card)); + strscpy(cap->driver, F54_NAME, sizeof(cap->driver)); + strscpy(cap->card, SYNAPTICS_INPUT_DEVICE_NAME, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "rmi4:%s", dev_name(&f54->fn->dev)); @@ -394,7 +408,7 @@ static int rmi_f54_vidioc_enum_input(struct file *file, void *priv, i->type = V4L2_INPUT_TYPE_TOUCH; - strlcpy(i->name, rmi_f54_report_type_names[reptype], sizeof(i->name)); + strscpy(i->name, rmi_f54_report_type_names[reptype], sizeof(i->name)); return 0; } @@ -456,25 +470,15 @@ static int rmi_f54_vidioc_fmt(struct file *file, void *priv, static int rmi_f54_vidioc_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *fmt) { + struct f54_data *f54 = video_drvdata(file); + if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - switch (fmt->index) { - case 0: - fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16; - break; - - case 1: - fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD08; - break; - - case 2: - fmt->pixelformat = V4L2_TCH_FMT_TU16; - break; - - default: + if (fmt->index) return -EINVAL; - } + + fmt->pixelformat = f54->format.pixelformat; return 0; } @@ -529,13 +533,11 @@ static void rmi_f54_work(struct work_struct *work) struct f54_data *f54 = container_of(work, struct f54_data, work.work); struct rmi_function *fn = f54->fn; u8 fifo[2]; - struct rmi_f54_reports *report; int report_size; u8 command; - u8 *data; int error; + int i; - data = f54->report_data; report_size = rmi_f54_get_report_size(f54); if (report_size == 0) { dev_err(&fn->dev, "Bad report size, report type=%d\n", @@ -543,8 +545,6 @@ static void rmi_f54_work(struct work_struct *work) error = -EINVAL; goto error; /* retry won't help */ } - f54->standard_report[0].size = report_size; - report = f54->standard_report; mutex_lock(&f54->data_mutex); @@ -569,10 +569,11 @@ static void rmi_f54_work(struct work_struct *work) rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Get report command completed, reading data\n"); - report_size = 0; - for (; report->size; report++) { - fifo[0] = report->start & 0xff; - fifo[1] = (report->start >> 8) & 0xff; + for (i = 0; i < report_size; i += F54_REPORT_DATA_SIZE) { + int size = min(F54_REPORT_DATA_SIZE, report_size - i); + + fifo[0] = i & 0xff; + fifo[1] = i >> 8; error = rmi_write_block(fn->rmi_dev, fn->fd.data_base_addr + F54_FIFO_OFFSET, fifo, sizeof(fifo)); @@ -582,15 +583,13 @@ static void rmi_f54_work(struct work_struct *work) } error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr + - F54_REPORT_DATA_OFFSET, data, - report->size); + F54_REPORT_DATA_OFFSET, + f54->report_data + i, size); if (error) { dev_err(&fn->dev, "%s: read [%d bytes] returned %d\n", - __func__, report->size, error); + __func__, size, error); goto abort; } - data += report->size; - report_size += report->size; } abort: @@ -614,7 +613,7 @@ static int rmi_f54_config(struct rmi_function *fn) { struct rmi_driver *drv = fn->rmi_dev->driver; - drv->set_irq_bits(fn->rmi_dev, fn->irq_mask); + drv->clear_irq_bits(fn->rmi_dev, fn->irq_mask); return 0; } @@ -692,9 +691,10 @@ static int rmi_f54_probe(struct rmi_function *fn) return -ENOMEM; rmi_f54_create_input_map(f54); + rmi_f54_set_input(f54, 0); /* register video device */ - strlcpy(f54->v4l2.name, F54_NAME, sizeof(f54->v4l2.name)); + strscpy(f54->v4l2.name, F54_NAME, sizeof(f54->v4l2.name)); ret = v4l2_device_register(&fn->dev, &f54->v4l2); if (ret) { dev_err(&fn->dev, "Unable to register video dev.\n"); @@ -731,7 +731,6 @@ remove_v4l2: v4l2_device_unregister(&f54->v4l2); remove_wq: cancel_delayed_work_sync(&f54->work); - flush_workqueue(f54->workqueue); destroy_workqueue(f54->workqueue); return ret; } @@ -742,6 +741,7 @@ static void rmi_f54_remove(struct rmi_function *fn) video_unregister_device(&f54->vdev); v4l2_device_unregister(&f54->v4l2); + destroy_workqueue(f54->workqueue); } struct rmi_function_handler rmi_f54_handler = { |
