summaryrefslogtreecommitdiff
path: root/drivers/input/rmi4/rmi_f54.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/rmi4/rmi_f54.c')
-rw-r--r--drivers/input/rmi4/rmi_f54.c98
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 = {