aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Duggan <aduggan@synaptics.com>2016-03-10 18:47:28 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2016-03-10 19:04:03 -0500
commitff8f83708b3e36c050dc3fd7e2f04ea7f1752599 (patch)
treed7b6603c447a1cb36af8452e541ed9b4cf6659f9
parentd8a8b3edfd922e3886684a3434bd2b752167ff29 (diff)
Input: synaptics-rmi4 - add support for 2D sensors and F11
RMI4 currently defines two functions for reporting data for 2D sensors (F11 and F12). This patch adds the common functionality which is shared by devices with 2D reporting along with implementing functionality for F11. Signed-off-by: Andrew Duggan <aduggan@synaptics.com> Signed-off-by: Christopher Heiny <cheiny@synaptics.com> Tested-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Tested-by: Linus Walleij <linus.walleij@linaro.org> Tested-by: Bjorn Andersson <bjorn.andersson@linaro.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/rmi4/Kconfig15
-rw-r--r--drivers/input/rmi4/Makefile5
-rw-r--r--drivers/input/rmi4/rmi_2d_sensor.c221
-rw-r--r--drivers/input/rmi4/rmi_2d_sensor.h84
-rw-r--r--drivers/input/rmi4/rmi_bus.c3
-rw-r--r--drivers/input/rmi4/rmi_driver.h2
-rw-r--r--drivers/input/rmi4/rmi_f11.c1312
-rw-r--r--include/linux/rmi.h83
8 files changed, 1724 insertions, 1 deletions
diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index cc3f7c508c19..dc7de6bbb8e6 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -17,3 +17,18 @@ config RMI4_I2C
17 bus. 17 bus.
18 18
19 If unsure, say Y. 19 If unsure, say Y.
20
21config RMI4_2D_SENSOR
22 bool
23 depends on RMI4_CORE
24
25config RMI4_F11
26 bool "RMI4 Function 11 (2D pointing)"
27 select RMI4_2D_SENSOR
28 depends on RMI4_CORE
29 help
30 Say Y here if you want to add support for RMI4 function 11.
31
32 Function 11 provides 2D multifinger pointing for touchscreens and
33 touchpads. For sensors that support relative pointing, F11 also
34 provides mouse input.
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 5539494aecd1..9e7424ae1c72 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -1,5 +1,10 @@
1obj-$(CONFIG_RMI4_CORE) += rmi_core.o 1obj-$(CONFIG_RMI4_CORE) += rmi_core.o
2rmi_core-y := rmi_bus.o rmi_driver.o rmi_f01.o 2rmi_core-y := rmi_bus.o rmi_driver.o rmi_f01.o
3 3
4rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
5
6# Function drivers
7rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
8
4# Transports 9# Transports
5obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o 10obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
diff --git a/drivers/input/rmi4/rmi_2d_sensor.c b/drivers/input/rmi4/rmi_2d_sensor.c
new file mode 100644
index 000000000000..8f48647ca5b0
--- /dev/null
+++ b/drivers/input/rmi4/rmi_2d_sensor.c
@@ -0,0 +1,221 @@
1/*
2 * Copyright (c) 2011-2016 Synaptics Incorporated
3 * Copyright (c) 2011 Unixphere
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 */
9
10#include <linux/kernel.h>
11#include <linux/device.h>
12#include <linux/of.h>
13#include <linux/input.h>
14#include <linux/input/mt.h>
15#include <linux/rmi.h>
16#include "rmi_driver.h"
17#include "rmi_2d_sensor.h"
18
19#define RMI_2D_REL_POS_MIN -128
20#define RMI_2D_REL_POS_MAX 127
21
22/* maximum ABS_MT_POSITION displacement (in mm) */
23#define DMAX 10
24
25void rmi_2d_sensor_abs_process(struct rmi_2d_sensor *sensor,
26 struct rmi_2d_sensor_abs_object *obj,
27 int slot)
28{
29 struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
30
31 /* we keep the previous values if the finger is released */
32 if (obj->type == RMI_2D_OBJECT_NONE)
33 return;
34
35 if (axis_align->swap_axes)
36 swap(obj->x, obj->y);
37
38 if (axis_align->flip_x)
39 obj->x = sensor->max_x - obj->x;
40
41 if (axis_align->flip_y)
42 obj->y = sensor->max_y - obj->y;
43
44 /*
45 * Here checking if X offset or y offset are specified is
46 * redundant. We just add the offsets or clip the values.
47 *
48 * Note: offsets need to be applied before clipping occurs,
49 * or we could get funny values that are outside of
50 * clipping boundaries.
51 */
52 obj->x += axis_align->offset_x;
53 obj->y += axis_align->offset_y;
54
55 obj->x = max(axis_align->clip_x_low, obj->x);
56 obj->y = max(axis_align->clip_y_low, obj->y);
57
58 if (axis_align->clip_x_high)
59 obj->x = min(sensor->max_x, obj->x);
60
61 if (axis_align->clip_y_high)
62 obj->y = min(sensor->max_y, obj->y);
63
64 sensor->tracking_pos[slot].x = obj->x;
65 sensor->tracking_pos[slot].y = obj->y;
66}
67EXPORT_SYMBOL_GPL(rmi_2d_sensor_abs_process);
68
69void rmi_2d_sensor_abs_report(struct rmi_2d_sensor *sensor,
70 struct rmi_2d_sensor_abs_object *obj,
71 int slot)
72{
73 struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
74 struct input_dev *input = sensor->input;
75 int wide, major, minor;
76
77 if (sensor->kernel_tracking)
78 input_mt_slot(input, sensor->tracking_slots[slot]);
79 else
80 input_mt_slot(input, slot);
81
82 input_mt_report_slot_state(input, obj->mt_tool,
83 obj->type != RMI_2D_OBJECT_NONE);
84
85 if (obj->type != RMI_2D_OBJECT_NONE) {
86 obj->x = sensor->tracking_pos[slot].x;
87 obj->y = sensor->tracking_pos[slot].y;
88
89 if (axis_align->swap_axes)
90 swap(obj->wx, obj->wy);
91
92 wide = (obj->wx > obj->wy);
93 major = max(obj->wx, obj->wy);
94 minor = min(obj->wx, obj->wy);
95
96 if (obj->type == RMI_2D_OBJECT_STYLUS) {
97 major = max(1, major);
98 minor = max(1, minor);
99 }
100
101 input_event(sensor->input, EV_ABS, ABS_MT_POSITION_X, obj->x);
102 input_event(sensor->input, EV_ABS, ABS_MT_POSITION_Y, obj->y);
103 input_event(sensor->input, EV_ABS, ABS_MT_ORIENTATION, wide);
104 input_event(sensor->input, EV_ABS, ABS_MT_PRESSURE, obj->z);
105 input_event(sensor->input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
106 input_event(sensor->input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
107
108 rmi_dbg(RMI_DEBUG_2D_SENSOR, &sensor->input->dev,
109 "%s: obj[%d]: type: 0x%02x X: %d Y: %d Z: %d WX: %d WY: %d\n",
110 __func__, slot, obj->type, obj->x, obj->y, obj->z,
111 obj->wx, obj->wy);
112 }
113}
114EXPORT_SYMBOL_GPL(rmi_2d_sensor_abs_report);
115
116void rmi_2d_sensor_rel_report(struct rmi_2d_sensor *sensor, int x, int y)
117{
118 struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
119
120 x = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)x));
121 y = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)y));
122
123 if (axis_align->swap_axes)
124 swap(x, y);
125
126 if (axis_align->flip_x)
127 x = min(RMI_2D_REL_POS_MAX, -x);
128
129 if (axis_align->flip_y)
130 y = min(RMI_2D_REL_POS_MAX, -y);
131
132 if (x || y) {
133 input_report_rel(sensor->input, REL_X, x);
134 input_report_rel(sensor->input, REL_Y, y);
135 }
136}
137EXPORT_SYMBOL_GPL(rmi_2d_sensor_rel_report);
138
139static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
140{
141 struct input_dev *input = sensor->input;
142 int res_x;
143 int res_y;
144 int input_flags = 0;
145
146 if (sensor->report_abs) {
147 if (sensor->axis_align.swap_axes)
148 swap(sensor->max_x, sensor->max_y);
149
150 sensor->min_x = sensor->axis_align.clip_x_low;
151 if (sensor->axis_align.clip_x_high)
152 sensor->max_x = min(sensor->max_x,
153 sensor->axis_align.clip_x_high);
154
155 sensor->min_y = sensor->axis_align.clip_y_low;
156 if (sensor->axis_align.clip_y_high)
157 sensor->max_y = min(sensor->max_y,
158 sensor->axis_align.clip_y_high);
159
160 set_bit(EV_ABS, input->evbit);
161 input_set_abs_params(input, ABS_MT_POSITION_X, 0, sensor->max_x,
162 0, 0);
163 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, sensor->max_y,
164 0, 0);
165
166 if (sensor->x_mm && sensor->y_mm) {
167 res_x = (sensor->max_x - sensor->min_x) / sensor->x_mm;
168 res_y = (sensor->max_y - sensor->min_y) / sensor->y_mm;
169
170 input_abs_set_res(input, ABS_X, res_x);
171 input_abs_set_res(input, ABS_Y, res_y);
172
173 input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
174 input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
175
176 if (!sensor->dmax)
177 sensor->dmax = DMAX * res_x;
178 }
179
180 input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xff, 0, 0);
181 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0);
182 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0);
183 input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0);
184
185 if (sensor->sensor_type == rmi_sensor_touchpad)
186 input_flags = INPUT_MT_POINTER;
187 else
188 input_flags = INPUT_MT_DIRECT;
189
190 if (sensor->kernel_tracking)
191 input_flags |= INPUT_MT_TRACK;
192
193 input_mt_init_slots(input, sensor->nbr_fingers, input_flags);
194 }
195
196 if (sensor->report_rel) {
197 set_bit(EV_REL, input->evbit);
198 set_bit(REL_X, input->relbit);
199 set_bit(REL_Y, input->relbit);
200 }
201
202 if (sensor->topbuttonpad)
203 set_bit(INPUT_PROP_TOPBUTTONPAD, input->propbit);
204}
205EXPORT_SYMBOL_GPL(rmi_2d_sensor_set_input_params);
206
207int rmi_2d_sensor_configure_input(struct rmi_function *fn,
208 struct rmi_2d_sensor *sensor)
209{
210 struct rmi_device *rmi_dev = fn->rmi_dev;
211 struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
212
213 if (!drv_data->input)
214 return -ENODEV;
215
216 sensor->input = drv_data->input;
217 rmi_2d_sensor_set_input_params(sensor);
218
219 return 0;
220}
221EXPORT_SYMBOL_GPL(rmi_2d_sensor_configure_input);
diff --git a/drivers/input/rmi4/rmi_2d_sensor.h b/drivers/input/rmi4/rmi_2d_sensor.h
new file mode 100644
index 000000000000..6a715d392ec2
--- /dev/null
+++ b/drivers/input/rmi4/rmi_2d_sensor.h
@@ -0,0 +1,84 @@
1/*
2 * Copyright (c) 2011-2016 Synaptics Incorporated
3 * Copyright (c) 2011 Unixphere
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 */
9
10#ifndef _RMI_2D_SENSOR_H
11#define _RMI_2D_SENSOR_H
12
13enum rmi_2d_sensor_object_type {
14 RMI_2D_OBJECT_NONE,
15 RMI_2D_OBJECT_FINGER,
16 RMI_2D_OBJECT_STYLUS,
17 RMI_2D_OBJECT_PALM,
18 RMI_2D_OBJECT_UNCLASSIFIED,
19};
20
21struct rmi_2d_sensor_abs_object {
22 enum rmi_2d_sensor_object_type type;
23 int mt_tool;
24 u16 x;
25 u16 y;
26 u8 z;
27 u8 wx;
28 u8 wy;
29};
30
31/**
32 * @axis_align - controls parameters that are useful in system prototyping
33 * and bring up.
34 * @max_x - The maximum X coordinate that will be reported by this sensor.
35 * @max_y - The maximum Y coordinate that will be reported by this sensor.
36 * @nbr_fingers - How many fingers can this sensor report?
37 * @data_pkt - buffer for data reported by this sensor.
38 * @pkt_size - number of bytes in that buffer.
39 * @attn_size - Size of the HID attention report (only contains abs data).
40 * position when two fingers are on the device. When this is true, we
41 * assume we have one of those sensors and report events appropriately.
42 * @sensor_type - indicates whether we're touchscreen or touchpad.
43 * @input - input device for absolute pointing stream
44 * @input_phys - buffer for the absolute phys name for this sensor.
45 */
46struct rmi_2d_sensor {
47 struct rmi_2d_axis_alignment axis_align;
48 struct input_mt_pos *tracking_pos;
49 int *tracking_slots;
50 bool kernel_tracking;
51 struct rmi_2d_sensor_abs_object *objs;
52 int dmax;
53 u16 min_x;
54 u16 max_x;
55 u16 min_y;
56 u16 max_y;
57 u8 nbr_fingers;
58 u8 *data_pkt;
59 int pkt_size;
60 int attn_size;
61 bool topbuttonpad;
62 enum rmi_sensor_type sensor_type;
63 struct input_dev *input;
64 struct rmi_function *fn;
65 char input_phys[32];
66 u8 report_abs;
67 u8 report_rel;
68 u8 x_mm;
69 u8 y_mm;
70};
71
72void rmi_2d_sensor_abs_process(struct rmi_2d_sensor *sensor,
73 struct rmi_2d_sensor_abs_object *obj,
74 int slot);
75
76void rmi_2d_sensor_abs_report(struct rmi_2d_sensor *sensor,
77 struct rmi_2d_sensor_abs_object *obj,
78 int slot);
79
80void rmi_2d_sensor_rel_report(struct rmi_2d_sensor *sensor, int x, int y);
81
82int rmi_2d_sensor_configure_input(struct rmi_function *fn,
83 struct rmi_2d_sensor *sensor);
84#endif /* _RMI_2D_SENSOR_H */
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index 434477ea0c4e..2e3878343961 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -306,6 +306,9 @@ struct bus_type rmi_bus_type = {
306 306
307static struct rmi_function_handler *fn_handlers[] = { 307static struct rmi_function_handler *fn_handlers[] = {
308 &rmi_f01_handler, 308 &rmi_f01_handler,
309#ifdef CONFIG_RMI4_F11
310 &rmi_f11_handler,
311#endif
309}; 312};
310 313
311static void __rmi_unregister_function_handlers(int start_idx) 314static void __rmi_unregister_function_handlers(int start_idx)
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index 3ab3f1a8078f..09d2aa7f11d4 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -99,5 +99,5 @@ void rmi_unregister_physical_driver(void);
99char *rmi_f01_get_product_ID(struct rmi_function *fn); 99char *rmi_f01_get_product_ID(struct rmi_function *fn);
100 100
101extern struct rmi_function_handler rmi_f01_handler; 101extern struct rmi_function_handler rmi_f01_handler;
102 102extern struct rmi_function_handler rmi_f11_handler;
103#endif 103#endif
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
new file mode 100644
index 000000000000..948a360b6261
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -0,0 +1,1312 @@
1/*
2 * Copyright (c) 2011-2015 Synaptics Incorporated
3 * Copyright (c) 2011 Unixphere
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 */
9
10#include <linux/kernel.h>
11#include <linux/delay.h>
12#include <linux/device.h>
13#include <linux/input.h>
14#include <linux/input/mt.h>
15#include <linux/kconfig.h>
16#include <linux/rmi.h>
17#include <linux/slab.h>
18#include <linux/of.h>
19#include "rmi_driver.h"
20#include "rmi_2d_sensor.h"
21
22#define F11_MAX_NUM_OF_FINGERS 10
23#define F11_MAX_NUM_OF_TOUCH_SHAPES 16
24
25#define FINGER_STATE_MASK 0x03
26
27#define F11_CTRL_SENSOR_MAX_X_POS_OFFSET 6
28#define F11_CTRL_SENSOR_MAX_Y_POS_OFFSET 8
29
30#define DEFAULT_XY_MAX 9999
31#define DEFAULT_MAX_ABS_MT_PRESSURE 255
32#define DEFAULT_MAX_ABS_MT_TOUCH 15
33#define DEFAULT_MAX_ABS_MT_ORIENTATION 1
34#define DEFAULT_MIN_ABS_MT_TRACKING_ID 1
35#define DEFAULT_MAX_ABS_MT_TRACKING_ID 10
36
37/** A note about RMI4 F11 register structure.
38 *
39 * The properties for
40 * a given sensor are described by its query registers. The number of query
41 * registers and the layout of their contents are described by the F11 device
42 * queries as well as the sensor query information.
43 *
44 * Similarly, each sensor has control registers that govern its behavior. The
45 * size and layout of the control registers for a given sensor can be determined
46 * by parsing that sensors query registers.
47 *
48 * And in a likewise fashion, each sensor has data registers where it reports
49 * its touch data and other interesting stuff. The size and layout of a
50 * sensors data registers must be determined by parsing its query registers.
51 *
52 * The short story is that we need to read and parse a lot of query
53 * registers in order to determine the attributes of a sensor. Then
54 * we need to use that data to compute the size of the control and data
55 * registers for sensor.
56 *
57 * The end result is that we have a number of structs that aren't used to
58 * directly generate the input events, but their size, location and contents
59 * are critical to determining where the data we are interested in lives.
60 *
61 * At this time, the driver does not yet comprehend all possible F11
62 * configuration options, but it should be sufficient to cover 99% of RMI4 F11
63 * devices currently in the field.
64 */
65
66/* maximum ABS_MT_POSITION displacement (in mm) */
67#define DMAX 10
68
69/**
70 * @rezero - writing this to the F11 command register will cause the sensor to
71 * calibrate to the current capacitive state.
72 */
73#define RMI_F11_REZERO 0x01
74
75#define RMI_F11_HAS_QUERY9 (1 << 3)
76#define RMI_F11_HAS_QUERY11 (1 << 4)
77#define RMI_F11_HAS_QUERY12 (1 << 5)
78#define RMI_F11_HAS_QUERY27 (1 << 6)
79#define RMI_F11_HAS_QUERY28 (1 << 7)
80
81/** Defs for Query 1 */
82
83#define RMI_F11_NR_FINGERS_MASK 0x07
84#define RMI_F11_HAS_REL (1 << 3)
85#define RMI_F11_HAS_ABS (1 << 4)
86#define RMI_F11_HAS_GESTURES (1 << 5)
87#define RMI_F11_HAS_SENSITIVITY_ADJ (1 << 6)
88#define RMI_F11_CONFIGURABLE (1 << 7)
89
90/** Defs for Query 2, 3, and 4. */
91#define RMI_F11_NR_ELECTRODES_MASK 0x7F
92
93/** Defs for Query 5 */
94
95#define RMI_F11_ABS_DATA_SIZE_MASK 0x03
96#define RMI_F11_HAS_ANCHORED_FINGER (1 << 2)
97#define RMI_F11_HAS_ADJ_HYST (1 << 3)
98#define RMI_F11_HAS_DRIBBLE (1 << 4)
99#define RMI_F11_HAS_BENDING_CORRECTION (1 << 5)
100#define RMI_F11_HAS_LARGE_OBJECT_SUPPRESSION (1 << 6)
101#define RMI_F11_HAS_JITTER_FILTER (1 << 7)
102
103/** Defs for Query 7 */
104#define RMI_F11_HAS_SINGLE_TAP (1 << 0)
105#define RMI_F11_HAS_TAP_AND_HOLD (1 << 1)
106#define RMI_F11_HAS_DOUBLE_TAP (1 << 2)
107#define RMI_F11_HAS_EARLY_TAP (1 << 3)
108#define RMI_F11_HAS_FLICK (1 << 4)
109#define RMI_F11_HAS_PRESS (1 << 5)
110#define RMI_F11_HAS_PINCH (1 << 6)
111#define RMI_F11_HAS_CHIRAL (1 << 7)
112
113/** Defs for Query 8 */
114#define RMI_F11_HAS_PALM_DET (1 << 0)
115#define RMI_F11_HAS_ROTATE (1 << 1)
116#define RMI_F11_HAS_TOUCH_SHAPES (1 << 2)
117#define RMI_F11_HAS_SCROLL_ZONES (1 << 3)
118#define RMI_F11_HAS_INDIVIDUAL_SCROLL_ZONES (1 << 4)
119#define RMI_F11_HAS_MF_SCROLL (1 << 5)
120#define RMI_F11_HAS_MF_EDGE_MOTION (1 << 6)
121#define RMI_F11_HAS_MF_SCROLL_INERTIA (1 << 7)
122
123/** Defs for Query 9. */
124#define RMI_F11_HAS_PEN (1 << 0)
125#define RMI_F11_HAS_PROXIMITY (1 << 1)
126#define RMI_F11_HAS_PALM_DET_SENSITIVITY (1 << 2)
127#define RMI_F11_HAS_SUPPRESS_ON_PALM_DETECT (1 << 3)
128#define RMI_F11_HAS_TWO_PEN_THRESHOLDS (1 << 4)
129#define RMI_F11_HAS_CONTACT_GEOMETRY (1 << 5)
130#define RMI_F11_HAS_PEN_HOVER_DISCRIMINATION (1 << 6)
131#define RMI_F11_HAS_PEN_FILTERS (1 << 7)
132
133/** Defs for Query 10. */
134#define RMI_F11_NR_TOUCH_SHAPES_MASK 0x1F
135
136/** Defs for Query 11 */
137
138#define RMI_F11_HAS_Z_TUNING (1 << 0)
139#define RMI_F11_HAS_ALGORITHM_SELECTION (1 << 1)
140#define RMI_F11_HAS_W_TUNING (1 << 2)
141#define RMI_F11_HAS_PITCH_INFO (1 << 3)
142#define RMI_F11_HAS_FINGER_SIZE (1 << 4)
143#define RMI_F11_HAS_SEGMENTATION_AGGRESSIVENESS (1 << 5)
144#define RMI_F11_HAS_XY_CLIP (1 << 6)
145#define RMI_F11_HAS_DRUMMING_FILTER (1 << 7)
146
147/** Defs for Query 12. */
148
149#define RMI_F11_HAS_GAPLESS_FINGER (1 << 0)
150#define RMI_F11_HAS_GAPLESS_FINGER_TUNING (1 << 1)
151#define RMI_F11_HAS_8BIT_W (1 << 2)
152#define RMI_F11_HAS_ADJUSTABLE_MAPPING (1 << 3)
153#define RMI_F11_HAS_INFO2 (1 << 4)
154#define RMI_F11_HAS_PHYSICAL_PROPS (1 << 5)
155#define RMI_F11_HAS_FINGER_LIMIT (1 << 6)
156#define RMI_F11_HAS_LINEAR_COEFF (1 << 7)
157
158/** Defs for Query 13. */
159
160#define RMI_F11_JITTER_WINDOW_MASK 0x1F
161#define RMI_F11_JITTER_FILTER_MASK 0x60
162#define RMI_F11_JITTER_FILTER_SHIFT 5
163
164/** Defs for Query 14. */
165#define RMI_F11_LIGHT_CONTROL_MASK 0x03
166#define RMI_F11_IS_CLEAR (1 << 2)
167#define RMI_F11_CLICKPAD_PROPS_MASK 0x18
168#define RMI_F11_CLICKPAD_PROPS_SHIFT 3
169#define RMI_F11_MOUSE_BUTTONS_MASK 0x60
170#define RMI_F11_MOUSE_BUTTONS_SHIFT 5
171#define RMI_F11_HAS_ADVANCED_GESTURES (1 << 7)
172
173#define RMI_F11_QUERY_SIZE 4
174#define RMI_F11_QUERY_GESTURE_SIZE 2
175
176#define F11_LIGHT_CTL_NONE 0x00
177#define F11_LUXPAD 0x01
178#define F11_DUAL_MODE 0x02
179
180#define F11_NOT_CLICKPAD 0x00
181#define F11_HINGED_CLICKPAD 0x01
182#define F11_UNIFORM_CLICKPAD 0x02
183
184/**
185 * Query registers 1 through 4 are always present.
186 *
187 * @nr_fingers - describes the maximum number of fingers the 2-D sensor
188 * supports.
189 * @has_rel - the sensor supports relative motion reporting.
190 * @has_abs - the sensor supports absolute poition reporting.
191 * @has_gestures - the sensor supports gesture reporting.
192 * @has_sensitivity_adjust - the sensor supports a global sensitivity
193 * adjustment.
194 * @configurable - the sensor supports various configuration options.
195 * @num_of_x_electrodes - the maximum number of electrodes the 2-D sensor
196 * supports on the X axis.
197 * @num_of_y_electrodes - the maximum number of electrodes the 2-D sensor
198 * supports on the Y axis.
199 * @max_electrodes - the total number of X and Y electrodes that may be
200 * configured.
201 *
202 * Query 5 is present if the has_abs bit is set.
203 *
204 * @abs_data_size - describes the format of data reported by the absolute
205 * data source. Only one format (the kind used here) is supported at this
206 * time.
207 * @has_anchored_finger - then the sensor supports the high-precision second
208 * finger tracking provided by the manual tracking and motion sensitivity
209 * options.
210 * @has_adjust_hyst - the difference between the finger release threshold and
211 * the touch threshold.
212 * @has_dribble - the sensor supports the generation of dribble interrupts,
213 * which may be enabled or disabled with the dribble control bit.
214 * @has_bending_correction - Bending related data registers 28 and 36, and
215 * control register 52..57 are present.
216 * @has_large_object_suppression - control register 58 and data register 28
217 * exist.
218 * @has_jitter_filter - query 13 and control 73..76 exist.
219 *
220 * Gesture information queries 7 and 8 are present if has_gestures bit is set.
221 *
222 * @has_single_tap - a basic single-tap gesture is supported.
223 * @has_tap_n_hold - tap-and-hold gesture is supported.
224 * @has_double_tap - double-tap gesture is supported.
225 * @has_early_tap - early tap is supported and reported as soon as the finger
226 * lifts for any tap event that could be interpreted as either a single tap
227 * or as the first tap of a double-tap or tap-and-hold gesture.
228 * @has_flick - flick detection is supported.
229 * @has_press - press gesture reporting is supported.
230 * @has_pinch - pinch gesture detection is supported.
231 * @has_palm_det - the 2-D sensor notifies the host whenever a large conductive
232 * object such as a palm or a cheek touches the 2-D sensor.
233 * @has_rotate - rotation gesture detection is supported.
234 * @has_touch_shapes - TouchShapes are supported. A TouchShape is a fixed
235 * rectangular area on the sensor that behaves like a capacitive button.
236 * @has_scroll_zones - scrolling areas near the sensor edges are supported.
237 * @has_individual_scroll_zones - if 1, then 4 scroll zones are supported;
238 * if 0, then only two are supported.
239 * @has_mf_scroll - the multifinger_scrolling bit will be set when
240 * more than one finger is involved in a scrolling action.
241 *
242 * Convenience for checking bytes in the gesture info registers. This is done
243 * often enough that we put it here to declutter the conditionals
244 *
245 * @query7_nonzero - true if none of the query 7 bits are set
246 * @query8_nonzero - true if none of the query 8 bits are set
247 *
248 * Query 9 is present if the has_query9 is set.
249 *
250 * @has_pen - detection of a stylus is supported and registers F11_2D_Ctrl20
251 * and F11_2D_Ctrl21 exist.
252 * @has_proximity - detection of fingers near the sensor is supported and
253 * registers F11_2D_Ctrl22 through F11_2D_Ctrl26 exist.
254 * @has_palm_det_sensitivity - the sensor supports the palm detect sensitivity
255 * feature and register F11_2D_Ctrl27 exists.
256 * @has_two_pen_thresholds - is has_pen is also set, then F11_2D_Ctrl35 exists.
257 * @has_contact_geometry - the sensor supports the use of contact geometry to
258 * map absolute X and Y target positions and registers F11_2D_Data18
259 * through F11_2D_Data27 exist.
260 *
261 * Touch shape info (query 10) is present if has_touch_shapes is set.
262 *
263 * @nr_touch_shapes - the total number of touch shapes supported.
264 *
265 * Query 11 is present if the has_query11 bit is set in query 0.
266 *
267 * @has_z_tuning - if set, the sensor supports Z tuning and registers
268 * F11_2D_Ctrl29 through F11_2D_Ctrl33 exist.
269 * @has_algorithm_selection - controls choice of noise suppression algorithm
270 * @has_w_tuning - the sensor supports Wx and Wy scaling and registers
271 * F11_2D_Ctrl36 through F11_2D_Ctrl39 exist.
272 * @has_pitch_info - the X and Y pitches of the sensor electrodes can be
273 * configured and registers F11_2D_Ctrl40 and F11_2D_Ctrl41 exist.
274 * @has_finger_size - the default finger width settings for the
275 * sensor can be configured and registers F11_2D_Ctrl42 through F11_2D_Ctrl44
276 * exist.
277 * @has_segmentation_aggressiveness - the sensor’s ability to distinguish
278 * multiple objects close together can be configured and register F11_2D_Ctrl45
279 * exists.
280 * @has_XY_clip - the inactive outside borders of the sensor can be
281 * configured and registers F11_2D_Ctrl46 through F11_2D_Ctrl49 exist.
282 * @has_drumming_filter - the sensor can be configured to distinguish
283 * between a fast flick and a quick drumming movement and registers
284 * F11_2D_Ctrl50 and F11_2D_Ctrl51 exist.
285 *
286 * Query 12 is present if hasQuery12 bit is set.
287 *
288 * @has_gapless_finger - control registers relating to gapless finger are
289 * present.
290 * @has_gapless_finger_tuning - additional control and data registers relating
291 * to gapless finger are present.
292 * @has_8bit_w - larger W value reporting is supported.
293 * @has_adjustable_mapping - TBD
294 * @has_info2 - the general info query14 is present
295 * @has_physical_props - additional queries describing the physical properties
296 * of the sensor are present.
297 * @has_finger_limit - indicates that F11 Ctrl 80 exists.
298 * @has_linear_coeff - indicates that F11 Ctrl 81 exists.
299 *
300 * Query 13 is present if Query 5's has_jitter_filter bit is set.
301 * @jitter_window_size - used by Design Studio 4.
302 * @jitter_filter_type - used by Design Studio 4.
303 *
304 * Query 14 is present if query 12's has_general_info2 flag is set.
305 *
306 * @light_control - Indicates what light/led control features are present, if
307 * any.
308 * @is_clear - if set, this is a clear sensor (indicating direct pointing
309 * application), otherwise it's opaque (indicating indirect pointing).
310 * @clickpad_props - specifies if this is a clickpad, and if so what sort of
311 * mechanism it uses
312 * @mouse_buttons - specifies the number of mouse buttons present (if any).
313 * @has_advanced_gestures - advanced driver gestures are supported.
314 */
315struct f11_2d_sensor_queries {
316 /* query1 */
317 u8 nr_fingers;
318 bool has_rel;
319 bool has_abs;
320 bool has_gestures;
321 bool has_sensitivity_adjust;
322 bool configurable;
323
324 /* query2 */
325 u8 nr_x_electrodes;
326
327 /* query3 */
328 u8 nr_y_electrodes;
329
330 /* query4 */
331 u8 max_electrodes;
332
333 /* query5 */
334 u8 abs_data_size;
335 bool has_anchored_finger;
336 bool has_adj_hyst;
337 bool has_dribble;
338 bool has_bending_correction;
339 bool has_large_object_suppression;
340 bool has_jitter_filter;
341
342 u8 f11_2d_query6;
343
344 /* query 7 */
345 bool has_single_tap;
346 bool has_tap_n_hold;
347 bool has_double_tap;
348 bool has_early_tap;
349 bool has_flick;
350 bool has_press;
351 bool has_pinch;
352 bool has_chiral;
353
354 bool query7_nonzero;
355
356 /* query 8 */
357 bool has_palm_det;
358 bool has_rotate;
359 bool has_touch_shapes;
360 bool has_scroll_zones;
361 bool has_individual_scroll_zones;
362 bool has_mf_scroll;
363 bool has_mf_edge_motion;
364 bool has_mf_scroll_inertia;
365
366 bool query8_nonzero;
367
368 /* Query 9 */
369 bool has_pen;
370 bool has_proximity;
371 bool has_palm_det_sensitivity;
372 bool has_suppress_on_palm_detect;
373 bool has_two_pen_thresholds;
374 bool has_contact_geometry;
375 bool has_pen_hover_discrimination;
376 bool has_pen_filters;
377
378 /* Query 10 */
379 u8 nr_touch_shapes;
380
381 /* Query 11. */
382 bool has_z_tuning;
383 bool has_algorithm_selection;
384 bool has_w_tuning;
385 bool has_pitch_info;
386 bool has_finger_size;
387 bool has_segmentation_aggressiveness;
388 bool has_XY_clip;
389 bool has_drumming_filter;
390
391 /* Query 12 */
392 bool has_gapless_finger;
393 bool has_gapless_finger_tuning;
394 bool has_8bit_w;
395 bool has_adjustable_mapping;
396 bool has_info2;
397 bool has_physical_props;
398 bool has_finger_limit;
399 bool has_linear_coeff_2;
400
401 /* Query 13 */
402 u8 jitter_window_size;
403 u8 jitter_filter_type;
404
405 /* Query 14 */
406 u8 light_control;
407 bool is_clear;
408 u8 clickpad_props;
409 u8 mouse_buttons;
410 bool has_advanced_gestures;
411
412 /* Query 15 - 18 */
413 u16 x_sensor_size_mm;
414 u16 y_sensor_size_mm;
415};
416
417/* Defs for Ctrl0. */
418#define RMI_F11_REPORT_MODE_MASK 0x07
419#define RMI_F11_ABS_POS_FILT (1 << 3)
420#define RMI_F11_REL_POS_FILT (1 << 4)
421#define RMI_F11_REL_BALLISTICS (1 << 5)
422#define RMI_F11_DRIBBLE (1 << 6)
423#define RMI_F11_REPORT_BEYOND_CLIP (1 << 7)
424
425/* Defs for Ctrl1. */
426#define RMI_F11_PALM_DETECT_THRESH_MASK 0x0F
427#define RMI_F11_MOTION_SENSITIVITY_MASK 0x30
428#define RMI_F11_MANUAL_TRACKING (1 << 6)
429#define RMI_F11_MANUAL_TRACKED_FINGER (1 << 7)
430
431#define RMI_F11_DELTA_X_THRESHOLD 2
432#define RMI_F11_DELTA_Y_THRESHOLD 3
433
434#define RMI_F11_CTRL_REG_COUNT 12
435
436struct f11_2d_ctrl {
437 u8 ctrl0_11[RMI_F11_CTRL_REG_COUNT];
438 u16 ctrl0_11_address;
439};
440
441#define RMI_F11_ABS_BYTES 5
442#define RMI_F11_REL_BYTES 2
443
444/* Defs for Data 8 */
445
446#define RMI_F11_SINGLE_TAP (1 << 0)
447#define RMI_F11_TAP_AND_HOLD (1 << 1)
448#define RMI_F11_DOUBLE_TAP (1 << 2)
449#define RMI_F11_EARLY_TAP (1 << 3)
450#define RMI_F11_FLICK (1 << 4)
451#define RMI_F11_PRESS (1 << 5)
452#define RMI_F11_PINCH (1 << 6)
453
454/* Defs for Data 9 */
455
456#define RMI_F11_PALM_DETECT (1 << 0)
457#define RMI_F11_ROTATE (1 << 1)
458#define RMI_F11_SHAPE (1 << 2)
459#define RMI_F11_SCROLLZONE (1 << 3)
460#define RMI_F11_GESTURE_FINGER_COUNT_MASK 0x70
461
462/** Handy pointers into our data buffer.
463 *
464 * @f_state - start of finger state registers.
465 * @abs_pos - start of absolute position registers (if present).
466 * @rel_pos - start of relative data registers (if present).
467 * @gest_1 - gesture flags (if present).
468 * @gest_2 - gesture flags & finger count (if present).
469 * @pinch - pinch motion register (if present).
470 * @flick - flick distance X & Y, flick time (if present).
471 * @rotate - rotate motion and finger separation.
472 * @multi_scroll - chiral deltas for X and Y (if present).
473 * @scroll_zones - scroll deltas for 4 regions (if present).
474 */
475struct f11_2d_data {
476 u8 *f_state;
477 u8 *abs_pos;
478 s8 *rel_pos;
479 u8 *gest_1;
480 u8 *gest_2;
481 s8 *pinch;
482 u8 *flick;
483 u8 *rotate;
484 u8 *shapes;
485 s8 *multi_scroll;
486 s8 *scroll_zones;
487};
488
489/** Data pertaining to F11 in general. For per-sensor data, see struct
490 * f11_2d_sensor.
491 *
492 * @dev_query - F11 device specific query registers.
493 * @dev_controls - F11 device specific control registers.
494 * @dev_controls_mutex - lock for the control registers.
495 * @rezero_wait_ms - if nonzero, upon resume we will wait this many
496 * milliseconds before rezeroing the sensor(s). This is useful in systems with
497 * poor electrical behavior on resume, where the initial calibration of the
498 * sensor(s) coming out of sleep state may be bogus.
499 * @sensors - per sensor data structures.
500 */
501struct f11_data {
502 bool has_query9;
503 bool has_query11;
504 bool has_query12;
505 bool has_query27;
506 bool has_query28;
507 bool has_acm;
508 struct f11_2d_ctrl dev_controls;
509 struct mutex dev_controls_mutex;
510 u16 rezero_wait_ms;
511 struct rmi_2d_sensor sensor;
512 struct f11_2d_sensor_queries sens_query;
513 struct f11_2d_data data;
514 struct rmi_2d_sensor_platform_data sensor_pdata;
515 unsigned long *abs_mask;
516 unsigned long *rel_mask;
517 unsigned long *result_bits;
518};
519
520enum f11_finger_state {
521 F11_NO_FINGER = 0x00,
522 F11_PRESENT = 0x01,
523 F11_INACCURATE = 0x02,
524 F11_RESERVED = 0x03
525};
526
527static void rmi_f11_rel_pos_report(struct f11_data *f11, u8 n_finger)
528{
529 struct rmi_2d_sensor *sensor = &f11->sensor;
530 struct f11_2d_data *data = &f11->data;
531 s8 x, y;
532
533 x = data->rel_pos[n_finger * 2];
534 y = data->rel_pos[n_finger * 2 + 1];
535
536 rmi_2d_sensor_rel_report(sensor, x, y);
537}
538
539static void rmi_f11_abs_pos_process(struct f11_data *f11,
540 struct rmi_2d_sensor *sensor,
541 struct rmi_2d_sensor_abs_object *obj,
542 enum f11_finger_state finger_state,
543 u8 n_finger)
544{
545 struct f11_2d_data *data = &f11->data;
546 u8 *pos_data = &data->abs_pos[n_finger * RMI_F11_ABS_BYTES];
547 int tool_type = MT_TOOL_FINGER;
548
549 switch (finger_state) {
550 case F11_PRESENT:
551 obj->type = RMI_2D_OBJECT_FINGER;
552 break;
553 default:
554 obj->type = RMI_2D_OBJECT_NONE;
555 }
556
557 obj->mt_tool = tool_type;
558 obj->x = (pos_data[0] << 4) | (pos_data[2] & 0x0F);
559 obj->y = (pos_data[1] << 4) | (pos_data[2] >> 4);
560 obj->z = pos_data[4];
561 obj->wx = pos_data[3] & 0x0f;
562 obj->wy = pos_data[3] >> 4;
563
564 rmi_2d_sensor_abs_process(sensor, obj, n_finger);
565}
566
567static inline u8 rmi_f11_parse_finger_state(const u8 *f_state, u8 n_finger)
568{
569 return (f_state[n_finger / 4] >> (2 * (n_finger % 4))) &
570 FINGER_STATE_MASK;
571}
572
573static void rmi_f11_finger_handler(struct f11_data *f11,
574 struct rmi_2d_sensor *sensor,
575 unsigned long *irq_bits, int num_irq_regs)
576{
577 const u8 *f_state = f11->data.f_state;
578 u8 finger_state;
579 u8 i;
580
581 int abs_bits = bitmap_and(f11->result_bits, irq_bits, f11->abs_mask,
582 num_irq_regs * 8);
583 int rel_bits = bitmap_and(f11->result_bits, irq_bits, f11->rel_mask,
584 num_irq_regs * 8);
585
586 for (i = 0; i < sensor->nbr_fingers; i++) {
587 /* Possible of having 4 fingers per f_statet register */
588 finger_state = rmi_f11_parse_finger_state(f_state, i);
589 if (finger_state == F11_RESERVED) {
590 pr_err("Invalid finger state[%d]: 0x%02x", i,
591 finger_state);
592 continue;
593 }
594
595 if (abs_bits)
596 rmi_f11_abs_pos_process(f11, sensor, &sensor->objs[i],
597 finger_state, i);
598
599 if (rel_bits)
600 rmi_f11_rel_pos_report(f11, i);
601 }
602
603 if (abs_bits) {
604 /*
605 * the absolute part is made in 2 parts to allow the kernel
606 * tracking to take place.
607 */
608 if (sensor->kernel_tracking)
609 input_mt_assign_slots(sensor->input,
610 sensor->tracking_slots,
611 sensor->tracking_pos,
612 sensor->nbr_fingers,
613 sensor->dmax);
614
615 for (i = 0; i < sensor->nbr_fingers; i++) {
616 finger_state = rmi_f11_parse_finger_state(f_state, i);
617 if (finger_state == F11_RESERVED)
618 /* no need to send twice the error */
619 continue;
620
621 rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i);
622 }
623
624 input_mt_sync_frame(sensor->input);
625 }
626}
627
628static int f11_2d_construct_data(struct f11_data *f11)
629{
630 struct rmi_2d_sensor *sensor = &f11->sensor;
631 struct f11_2d_sensor_queries *query = &f11->sens_query;
632 struct f11_2d_data *data = &f11->data;
633 int i;
634
635 sensor->nbr_fingers = (query->nr_fingers == 5 ? 10 :
636 query->nr_fingers + 1);
637
638 sensor->pkt_size = DIV_ROUND_UP(sensor->nbr_fingers, 4);
639
640 if (query->has_abs) {
641 sensor->pkt_size += (sensor->nbr_fingers * 5);
642 sensor->attn_size = sensor->pkt_size;
643 }
644
645 if (query->has_rel)
646 sensor->pkt_size += (sensor->nbr_fingers * 2);
647
648 /* Check if F11_2D_Query7 is non-zero */
649 if (query->query7_nonzero)
650 sensor->pkt_size += sizeof(u8);
651
652 /* Check if F11_2D_Query7 or F11_2D_Query8 is non-zero */
653 if (query->query7_nonzero || query->query8_nonzero)
654 sensor->pkt_size += sizeof(u8);
655
656 if (query->has_pinch || query->has_flick || query->has_rotate) {
657 sensor->pkt_size += 3;
658 if (!query->has_flick)
659 sensor->pkt_size--;
660 if (!query->has_rotate)
661 sensor->pkt_size--;
662 }
663
664 if (query->has_touch_shapes)
665 sensor->pkt_size +=
666 DIV_ROUND_UP(query->nr_touch_shapes + 1, 8);
667
668 sensor->data_pkt = devm_kzalloc(&sensor->fn->dev, sensor->pkt_size,
669 GFP_KERNEL);
670 if (!sensor->data_pkt)
671 return -ENOMEM;
672
673 data->f_state = sensor->data_pkt;
674 i = DIV_ROUND_UP(sensor->nbr_fingers, 4);
675
676 if (query->has_abs) {
677 data->abs_pos = &sensor->data_pkt[i];
678 i += (sensor->nbr_fingers * RMI_F11_ABS_BYTES);
679 }
680
681 if (query->has_rel) {
682 data->rel_pos = &sensor->data_pkt[i];
683 i += (sensor->nbr_fingers * RMI_F11_REL_BYTES);
684 }
685
686 if (query->query7_nonzero) {
687 data->gest_1 = &sensor->data_pkt[i];
688 i++;
689 }
690
691 if (query->query7_nonzero || query->query8_nonzero) {
692 data->gest_2 = &sensor->data_pkt[i];
693 i++;
694 }
695
696 if (query->has_pinch) {
697 data->pinch = &sensor->data_pkt[i];
698 i++;
699 }
700
701 if (query->has_flick) {
702 if (query->has_pinch) {
703 data->flick = data->pinch;
704 i += 2;
705 } else {
706 data->flick = &sensor->data_pkt[i];
707 i += 3;
708 }
709 }
710
711 if (query->has_rotate) {
712 if (query->has_flick) {
713 data->rotate = data->flick + 1;
714 } else {
715 data->rotate = &sensor->data_pkt[i];
716 i += 2;
717 }
718 }
719
720 if (query->has_touch_shapes)
721 data->shapes = &sensor->data_pkt[i];
722
723 return 0;
724}
725
726static int f11_read_control_regs(struct rmi_function *fn,
727 struct f11_2d_ctrl *ctrl, u16 ctrl_base_addr) {
728 struct rmi_device *rmi_dev = fn->rmi_dev;
729 int error = 0;
730
731 ctrl->ctrl0_11_address = ctrl_base_addr;
732 error = rmi_read_block(rmi_dev, ctrl_base_addr, ctrl->ctrl0_11,
733 RMI_F11_CTRL_REG_COUNT);
734 if (error < 0) {
735 dev_err(&fn->dev, "Failed to read ctrl0, code: %d.\n", error);
736 return error;
737 }
738
739 return 0;
740}
741
742static int f11_write_control_regs(struct rmi_function *fn,
743 struct f11_2d_sensor_queries *query,
744 struct f11_2d_ctrl *ctrl,
745 u16 ctrl_base_addr)
746{
747 struct rmi_device *rmi_dev = fn->rmi_dev;
748 int error;
749
750 error = rmi_write_block(rmi_dev, ctrl_base_addr, ctrl->ctrl0_11,
751 RMI_F11_CTRL_REG_COUNT);
752 if (error < 0)
753 return error;
754
755 return 0;
756}
757
758static int rmi_f11_get_query_parameters(struct rmi_device *rmi_dev,
759 struct f11_data *f11,
760 struct f11_2d_sensor_queries *sensor_query,
761 u16 query_base_addr)
762{
763 int query_size;
764 int rc;
765 u8 query_buf[RMI_F11_QUERY_SIZE];
766 bool has_query36 = false;
767
768 rc = rmi_read_block(rmi_dev, query_base_addr, query_buf,
769 RMI_F11_QUERY_SIZE);
770 if (rc < 0)
771 return rc;
772
773 sensor_query->nr_fingers = query_buf[0] & RMI_F11_NR_FINGERS_MASK;
774 sensor_query->has_rel = !!(query_buf[0] & RMI_F11_HAS_REL);
775 sensor_query->has_abs = !!(query_buf[0] & RMI_F11_HAS_ABS);
776 sensor_query->has_gestures = !!(query_buf[0] & RMI_F11_HAS_GESTURES);
777 sensor_query->has_sensitivity_adjust =
778 !!(query_buf[0] && RMI_F11_HAS_SENSITIVITY_ADJ);
779 sensor_query->configurable = !!(query_buf[0] & RMI_F11_CONFIGURABLE);
780
781 sensor_query->nr_x_electrodes =
782 query_buf[1] & RMI_F11_NR_ELECTRODES_MASK;
783 sensor_query->nr_y_electrodes =
784 query_buf[2] & RMI_F11_NR_ELECTRODES_MASK;
785 sensor_query->max_electrodes =
786 query_buf[3] & RMI_F11_NR_ELECTRODES_MASK;
787
788 query_size = RMI_F11_QUERY_SIZE;
789
790 if (sensor_query->has_abs) {
791 rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
792 if (rc < 0)
793 return rc;
794
795 sensor_query->abs_data_size =
796 query_buf[0] & RMI_F11_ABS_DATA_SIZE_MASK;
797 sensor_query->has_anchored_finger =
798 !!(query_buf[0] & RMI_F11_HAS_ANCHORED_FINGER);
799 sensor_query->has_adj_hyst =
800 !!(query_buf[0] & RMI_F11_HAS_ADJ_HYST);
801 sensor_query->has_dribble =
802 !!(query_buf[0] & RMI_F11_HAS_DRIBBLE);
803 sensor_query->has_bending_correction =
804 !!(query_buf[0] & RMI_F11_HAS_BENDING_CORRECTION);
805 sensor_query->has_large_object_suppression =
806 !!(query_buf[0] && RMI_F11_HAS_LARGE_OBJECT_SUPPRESSION);
807 sensor_query->has_jitter_filter =
808 !!(query_buf[0] & RMI_F11_HAS_JITTER_FILTER);
809 query_size++;
810 }
811
812 if (sensor_query->has_rel) {
813 rc = rmi_read(rmi_dev, query_base_addr + query_size,
814 &sensor_query->f11_2d_query6);
815 if (rc < 0)
816 return rc;
817 query_size++;
818 }
819
820 if (sensor_query->has_gestures) {
821 rc = rmi_read_block(rmi_dev, query_base_addr + query_size,
822 query_buf, RMI_F11_QUERY_GESTURE_SIZE);
823 if (rc < 0)
824 return rc;
825
826 sensor_query->has_single_tap =
827 !!(query_buf[0] & RMI_F11_HAS_SINGLE_TAP);
828 sensor_query->has_tap_n_hold =
829 !!(query_buf[0] & RMI_F11_HAS_TAP_AND_HOLD);
830 sensor_query->has_double_tap =
831 !!(query_buf[0] & RMI_F11_HAS_DOUBLE_TAP);
832 sensor_query->has_early_tap =
833 !!(query_buf[0] & RMI_F11_HAS_EARLY_TAP);
834 sensor_query->has_flick =
835 !!(query_buf[0] & RMI_F11_HAS_FLICK);
836 sensor_query->has_press =
837 !!(query_buf[0] & RMI_F11_HAS_PRESS);
838 sensor_query->has_pinch =
839 !!(query_buf[0] & RMI_F11_HAS_PINCH);
840 sensor_query->has_chiral =
841 !!(query_buf[0] & RMI_F11_HAS_CHIRAL);
842
843 /* query 8 */
844 sensor_query->has_palm_det =
845 !!(query_buf[1] & RMI_F11_HAS_PALM_DET);
846 sensor_query->has_rotate =
847 !!(query_buf[1] & RMI_F11_HAS_ROTATE);
848 sensor_query->has_touch_shapes =
849 !!(query_buf[1] & RMI_F11_HAS_TOUCH_SHAPES);
850 sensor_query->has_scroll_zones =
851 !!(query_buf[1] & RMI_F11_HAS_SCROLL_ZONES);
852 sensor_query->has_individual_scroll_zones =
853 !!(query_buf[1] & RMI_F11_HAS_INDIVIDUAL_SCROLL_ZONES);
854 sensor_query->has_mf_scroll =
855 !!(query_buf[1] & RMI_F11_HAS_MF_SCROLL);
856 sensor_query->has_mf_edge_motion =
857 !!(query_buf[1] & RMI_F11_HAS_MF_EDGE_MOTION);
858 sensor_query->has_mf_scroll_inertia =
859 !!(query_buf[1] & RMI_F11_HAS_MF_SCROLL_INERTIA);
860
861 sensor_query->query7_nonzero = !!(query_buf[0]);
862 sensor_query->query8_nonzero = !!(query_buf[1]);
863
864 query_size += 2;
865 }
866
867 if (f11->has_query9) {
868 rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
869 if (rc < 0)
870 return rc;
871
872 sensor_query->has_pen =
873 !!(query_buf[0] & RMI_F11_HAS_PEN);
874 sensor_query->has_proximity =
875 !!(query_buf[0] & RMI_F11_HAS_PROXIMITY);
876 sensor_query->has_palm_det_sensitivity =
877 !!(query_buf[0] & RMI_F11_HAS_PALM_DET_SENSITIVITY);
878 sensor_query->has_suppress_on_palm_detect =
879 !!(query_buf[0] & RMI_F11_HAS_SUPPRESS_ON_PALM_DETECT);
880 sensor_query->has_two_pen_thresholds =
881 !!(query_buf[0] & RMI_F11_HAS_TWO_PEN_THRESHOLDS);
882 sensor_query->has_contact_geometry =
883 !!(query_buf[0] & RMI_F11_HAS_CONTACT_GEOMETRY);
884 sensor_query->has_pen_hover_discrimination =
885 !!(query_buf[0] & RMI_F11_HAS_PEN_HOVER_DISCRIMINATION);
886 sensor_query->has_pen_filters =
887 !!(query_buf[0] & RMI_F11_HAS_PEN_FILTERS);
888
889 query_size++;
890 }
891
892 if (sensor_query->has_touch_shapes) {
893 rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
894 if (rc < 0)
895 return rc;
896
897 sensor_query->nr_touch_shapes = query_buf[0] &
898 RMI_F11_NR_TOUCH_SHAPES_MASK;
899
900 query_size++;
901 }
902
903 if (f11->has_query11) {
904 rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
905 if (rc < 0)
906 return rc;
907
908 sensor_query->has_z_tuning =
909 !!(query_buf[0] & RMI_F11_HAS_Z_TUNING);
910 sensor_query->has_algorithm_selection =
911 !!(query_buf[0] & RMI_F11_HAS_ALGORITHM_SELECTION);
912 sensor_query->has_w_tuning =
913 !!(query_buf[0] & RMI_F11_HAS_W_TUNING);
914 sensor_query->has_pitch_info =
915 !!(query_buf[0] & RMI_F11_HAS_PITCH_INFO);
916 sensor_query->has_finger_size =
917 !!(query_buf[0] & RMI_F11_HAS_FINGER_SIZE);
918 sensor_query->has_segmentation_aggressiveness =
919 !!(query_buf[0] &
920 RMI_F11_HAS_SEGMENTATION_AGGRESSIVENESS);
921 sensor_query->has_XY_clip =
922 !!(query_buf[0] & RMI_F11_HAS_XY_CLIP);
923 sensor_query->has_drumming_filter =
924 !!(query_buf[0] & RMI_F11_HAS_DRUMMING_FILTER);
925
926 query_size++;
927 }
928
929 if (f11->has_query12) {
930 rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
931 if (rc < 0)
932 return rc;
933
934 sensor_query->has_gapless_finger =
935 !!(query_buf[0] & RMI_F11_HAS_GAPLESS_FINGER);
936 sensor_query->has_gapless_finger_tuning =
937 !!(query_buf[0] & RMI_F11_HAS_GAPLESS_FINGER_TUNING);
938 sensor_query->has_8bit_w =
939 !!(query_buf[0] & RMI_F11_HAS_8BIT_W);
940 sensor_query->has_adjustable_mapping =
941 !!(query_buf[0] & RMI_F11_HAS_ADJUSTABLE_MAPPING);
942 sensor_query->has_info2 =
943 !!(query_buf[0] & RMI_F11_HAS_INFO2);
944 sensor_query->has_physical_props =
945 !!(query_buf[0] & RMI_F11_HAS_PHYSICAL_PROPS);
946 sensor_query->has_finger_limit =
947 !!(query_buf[0] & RMI_F11_HAS_FINGER_LIMIT);
948 sensor_query->has_linear_coeff_2 =
949 !!(query_buf[0] & RMI_F11_HAS_LINEAR_COEFF);
950
951 query_size++;
952 }
953
954 if (sensor_query->has_jitter_filter) {
955 rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
956 if (rc < 0)
957 return rc;
958
959 sensor_query->jitter_window_size = query_buf[0] &
960 RMI_F11_JITTER_WINDOW_MASK;
961 sensor_query->jitter_filter_type = (query_buf[0] &
962 RMI_F11_JITTER_FILTER_MASK) >>
963 RMI_F11_JITTER_FILTER_SHIFT;
964
965 query_size++;
966 }
967
968 if (sensor_query->has_info2) {
969 rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
970 if (rc < 0)
971 return rc;
972
973 sensor_query->light_control =
974 query_buf[0] & RMI_F11_LIGHT_CONTROL_MASK;
975 sensor_query->is_clear =
976 !!(query_buf[0] & RMI_F11_IS_CLEAR);
977 sensor_query->clickpad_props =
978 (query_buf[0] & RMI_F11_CLICKPAD_PROPS_MASK) >>
979 RMI_F11_CLICKPAD_PROPS_SHIFT;
980 sensor_query->mouse_buttons =
981 (query_buf[0] & RMI_F11_MOUSE_BUTTONS_MASK) >>
982 RMI_F11_MOUSE_BUTTONS_SHIFT;
983 sensor_query->has_advanced_gestures =
984 !!(query_buf[0] & RMI_F11_HAS_ADVANCED_GESTURES);
985
986 query_size++;
987 }
988
989 if (sensor_query->has_physical_props) {
990 rc = rmi_read_block(rmi_dev, query_base_addr
991 + query_size, query_buf, 4);
992 if (rc < 0)
993 return rc;
994
995 sensor_query->x_sensor_size_mm =
996 (query_buf[0] | (query_buf[1] << 8)) / 10;
997 sensor_query->y_sensor_size_mm =
998 (query_buf[2] | (query_buf[3] << 8)) / 10;
999
1000 /*
1001 * query 15 - 18 contain the size of the sensor
1002 * and query 19 - 26 contain bezel dimensions
1003 */
1004 query_size += 12;
1005 }
1006
1007 if (f11->has_query27)
1008 ++query_size;
1009
1010 if (f11->has_query28) {
1011 rc = rmi_read(rmi_dev, query_base_addr + query_size,
1012 query_buf);
1013 if (rc < 0)
1014 return rc;
1015
1016 has_query36 = !!(query_buf[0] & BIT(6));
1017 }
1018
1019 if (has_query36) {
1020 query_size += 2;
1021 rc = rmi_read(rmi_dev, query_base_addr + query_size,
1022 query_buf);
1023 if (rc < 0)
1024 return rc;
1025
1026 if (!!(query_buf[0] & BIT(5)))
1027 f11->has_acm = true;
1028 }
1029
1030 return query_size;
1031}
1032
1033static int rmi_f11_initialize(struct rmi_function *fn)
1034{
1035 struct rmi_device *rmi_dev = fn->rmi_dev;
1036 struct f11_data *f11;
1037 struct f11_2d_ctrl *ctrl;
1038 u8 query_offset;
1039 u16 query_base_addr;
1040 u16 control_base_addr;
1041 u16 max_x_pos, max_y_pos;
1042 int rc;
1043 const struct rmi_device_platform_data *pdata =
1044 rmi_get_platform_data(rmi_dev);
1045 struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
1046 struct rmi_2d_sensor *sensor;
1047 u8 buf;
1048 int mask_size;
1049
1050 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Initializing F11 values.\n");
1051
1052 mask_size = BITS_TO_LONGS(drvdata->irq_count) * sizeof(unsigned long);
1053
1054 /*
1055 ** init instance data, fill in values and create any sysfs files
1056 */
1057 f11 = devm_kzalloc(&fn->dev, sizeof(struct f11_data) + mask_size * 3,
1058 GFP_KERNEL);
1059 if (!f11)
1060 return -ENOMEM;
1061
1062 if (pdata->sensor_pdata)
1063 f11->sensor_pdata = *pdata->sensor_pdata;
1064
1065 f11->rezero_wait_ms = f11->sensor_pdata.rezero_wait;
1066
1067 f11->abs_mask = (unsigned long *)((char *)f11
1068 + sizeof(struct f11_data));
1069 f11->rel_mask = (unsigned long *)((char *)f11
1070 + sizeof(struct f11_data) + mask_size);
1071 f11->result_bits = (unsigned long *)((char *)f11
1072 + sizeof(struct f11_data) + mask_size * 2);
1073
1074 set_bit(fn->irq_pos, f11->abs_mask);
1075 set_bit(fn->irq_pos + 1, f11->rel_mask);
1076
1077 query_base_addr = fn->fd.query_base_addr;
1078 control_base_addr = fn->fd.control_base_addr;
1079
1080 rc = rmi_read(rmi_dev, query_base_addr, &buf);
1081 if (rc < 0)
1082 return rc;
1083
1084 f11->has_query9 = !!(buf & RMI_F11_HAS_QUERY9);
1085 f11->has_query11 = !!(buf & RMI_F11_HAS_QUERY11);
1086 f11->has_query12 = !!(buf & RMI_F11_HAS_QUERY12);
1087 f11->has_query27 = !!(buf & RMI_F11_HAS_QUERY27);
1088 f11->has_query28 = !!(buf & RMI_F11_HAS_QUERY28);
1089
1090 query_offset = (query_base_addr + 1);
1091 sensor = &f11->sensor;
1092 sensor->fn = fn;
1093
1094 rc = rmi_f11_get_query_parameters(rmi_dev, f11,
1095 &f11->sens_query, query_offset);
1096 if (rc < 0)
1097 return rc;
1098 query_offset += rc;
1099
1100 rc = f11_read_control_regs(fn, &f11->dev_controls,
1101 control_base_addr);
1102 if (rc < 0) {
1103 dev_err(&fn->dev,
1104 "Failed to read F11 control params.\n");
1105 return rc;
1106 }
1107
1108 if (f11->sens_query.has_info2) {
1109 if (f11->sens_query.is_clear)
1110 f11->sensor.sensor_type = rmi_sensor_touchscreen;
1111 else
1112 f11->sensor.sensor_type = rmi_sensor_touchpad;
1113 }
1114
1115 sensor->report_abs = f11->sens_query.has_abs;
1116
1117 sensor->axis_align =
1118 f11->sensor_pdata.axis_align;
1119
1120 sensor->topbuttonpad = f11->sensor_pdata.topbuttonpad;
1121 sensor->kernel_tracking = f11->sensor_pdata.kernel_tracking;
1122 sensor->dmax = f11->sensor_pdata.dmax;
1123
1124 if (f11->sens_query.has_physical_props) {
1125 sensor->x_mm = f11->sens_query.x_sensor_size_mm;
1126 sensor->y_mm = f11->sens_query.y_sensor_size_mm;
1127 } else {
1128 sensor->x_mm = f11->sensor_pdata.x_mm;
1129 sensor->y_mm = f11->sensor_pdata.y_mm;
1130 }
1131
1132 if (sensor->sensor_type == rmi_sensor_default)
1133 sensor->sensor_type =
1134 f11->sensor_pdata.sensor_type;
1135
1136 sensor->report_abs = sensor->report_abs
1137 && !(f11->sensor_pdata.disable_report_mask
1138 & RMI_F11_DISABLE_ABS_REPORT);
1139
1140 if (!sensor->report_abs)
1141 /*
1142 * If device doesn't have abs or if it has been disables
1143 * fallback to reporting rel data.
1144 */
1145 sensor->report_rel = f11->sens_query.has_rel;
1146
1147 rc = rmi_read_block(rmi_dev,
1148 control_base_addr + F11_CTRL_SENSOR_MAX_X_POS_OFFSET,
1149 (u8 *)&max_x_pos, sizeof(max_x_pos));
1150 if (rc < 0)
1151 return rc;
1152
1153 rc = rmi_read_block(rmi_dev,
1154 control_base_addr + F11_CTRL_SENSOR_MAX_Y_POS_OFFSET,
1155 (u8 *)&max_y_pos, sizeof(max_y_pos));
1156 if (rc < 0)
1157 return rc;
1158
1159 sensor->max_x = max_x_pos;
1160 sensor->max_y = max_y_pos;
1161
1162 rc = f11_2d_construct_data(f11);
1163 if (rc < 0)
1164 return rc;
1165
1166 if (f11->has_acm)
1167 f11->sensor.attn_size += f11->sensor.nbr_fingers * 2;
1168
1169 /* allocate the in-kernel tracking buffers */
1170 sensor->tracking_pos = devm_kzalloc(&fn->dev,
1171 sizeof(struct input_mt_pos) * sensor->nbr_fingers,
1172 GFP_KERNEL);
1173 sensor->tracking_slots = devm_kzalloc(&fn->dev,
1174 sizeof(int) * sensor->nbr_fingers, GFP_KERNEL);
1175 sensor->objs = devm_kzalloc(&fn->dev,
1176 sizeof(struct rmi_2d_sensor_abs_object)
1177 * sensor->nbr_fingers, GFP_KERNEL);
1178 if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs)
1179 return -ENOMEM;
1180
1181 ctrl = &f11->dev_controls;
1182 if (sensor->axis_align.delta_x_threshold)
1183 ctrl->ctrl0_11[RMI_F11_DELTA_X_THRESHOLD] =
1184 sensor->axis_align.delta_x_threshold;
1185
1186 if (sensor->axis_align.delta_y_threshold)
1187 ctrl->ctrl0_11[RMI_F11_DELTA_Y_THRESHOLD] =
1188 sensor->axis_align.delta_y_threshold;
1189
1190 if (f11->sens_query.has_dribble)
1191 ctrl->ctrl0_11[0] = ctrl->ctrl0_11[0] & ~BIT(6);
1192
1193 if (f11->sens_query.has_palm_det)
1194 ctrl->ctrl0_11[11] = ctrl->ctrl0_11[11] & ~BIT(0);
1195
1196 rc = f11_write_control_regs(fn, &f11->sens_query,
1197 &f11->dev_controls, fn->fd.query_base_addr);
1198 if (rc)
1199 dev_warn(&fn->dev, "Failed to write control registers\n");
1200
1201 mutex_init(&f11->dev_controls_mutex);
1202
1203 dev_set_drvdata(&fn->dev, f11);
1204
1205 return 0;
1206}
1207
1208static int rmi_f11_config(struct rmi_function *fn)
1209{
1210 struct f11_data *f11 = dev_get_drvdata(&fn->dev);
1211 struct rmi_driver *drv = fn->rmi_dev->driver;
1212 struct rmi_2d_sensor *sensor = &f11->sensor;
1213 int rc;
1214
1215 if (!sensor->report_abs)
1216 drv->clear_irq_bits(fn->rmi_dev, f11->abs_mask);
1217 else
1218 drv->set_irq_bits(fn->rmi_dev, f11->abs_mask);
1219
1220 if (!sensor->report_rel)
1221 drv->clear_irq_bits(fn->rmi_dev, f11->rel_mask);
1222 else
1223 drv->set_irq_bits(fn->rmi_dev, f11->rel_mask);
1224
1225 rc = f11_write_control_regs(fn, &f11->sens_query,
1226 &f11->dev_controls, fn->fd.query_base_addr);
1227 if (rc < 0)
1228 return rc;
1229
1230 return 0;
1231}
1232
1233static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
1234{
1235 struct rmi_device *rmi_dev = fn->rmi_dev;
1236 struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
1237 struct f11_data *f11 = dev_get_drvdata(&fn->dev);
1238 u16 data_base_addr = fn->fd.data_base_addr;
1239 u16 data_base_addr_offset = 0;
1240 int error;
1241
1242 if (rmi_dev->xport->attn_data) {
1243 memcpy(f11->sensor.data_pkt, rmi_dev->xport->attn_data,
1244 f11->sensor.attn_size);
1245 rmi_dev->xport->attn_data += f11->sensor.attn_size;
1246 rmi_dev->xport->attn_size -= f11->sensor.attn_size;
1247 } else {
1248 error = rmi_read_block(rmi_dev,
1249 data_base_addr + data_base_addr_offset,
1250 f11->sensor.data_pkt,
1251 f11->sensor.pkt_size);
1252 if (error < 0)
1253 return error;
1254 }
1255
1256 rmi_f11_finger_handler(f11, &f11->sensor, irq_bits,
1257 drvdata->num_of_irq_regs);
1258 data_base_addr_offset += f11->sensor.pkt_size;
1259
1260 return 0;
1261}
1262
1263static int rmi_f11_resume(struct rmi_function *fn)
1264{
1265 struct f11_data *f11 = dev_get_drvdata(&fn->dev);
1266 int error;
1267
1268 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Resuming...\n");
1269 if (!f11->rezero_wait_ms)
1270 return 0;
1271
1272 mdelay(f11->rezero_wait_ms);
1273
1274 error = rmi_write(fn->rmi_dev, fn->fd.command_base_addr,
1275 RMI_F11_REZERO);
1276 if (error) {
1277 dev_err(&fn->dev,
1278 "%s: failed to issue rezero command, error = %d.",
1279 __func__, error);
1280 return error;
1281 }
1282
1283 return 0;
1284}
1285
1286static int rmi_f11_probe(struct rmi_function *fn)
1287{
1288 int error;
1289 struct f11_data *f11;
1290
1291 error = rmi_f11_initialize(fn);
1292 if (error)
1293 return error;
1294
1295 f11 = dev_get_drvdata(&fn->dev);
1296 error = rmi_2d_sensor_configure_input(fn, &f11->sensor);
1297 if (error)
1298 return error;
1299
1300 return 0;
1301}
1302
1303struct rmi_function_handler rmi_f11_handler = {
1304 .driver = {
1305 .name = "rmi4_f11",
1306 },
1307 .func = 0x11,
1308 .probe = rmi_f11_probe,
1309 .config = rmi_f11_config,
1310 .attention = rmi_f11_attention,
1311 .resume = rmi_f11_resume,
1312};
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index c748fa302067..b527064bac47 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -20,6 +20,88 @@
20#define NAME_BUFFER_SIZE 256 20#define NAME_BUFFER_SIZE 256
21 21
22/** 22/**
23 * struct rmi_2d_axis_alignment - target axis alignment
24 * @swap_axes: set to TRUE if desired to swap x- and y-axis
25 * @flip_x: set to TRUE if desired to flip direction on x-axis
26 * @flip_y: set to TRUE if desired to flip direction on y-axis
27 * @clip_x_low - reported X coordinates below this setting will be clipped to
28 * the specified value
29 * @clip_x_high - reported X coordinates above this setting will be clipped to
30 * the specified value
31 * @clip_y_low - reported Y coordinates below this setting will be clipped to
32 * the specified value
33 * @clip_y_high - reported Y coordinates above this setting will be clipped to
34 * the specified value
35 * @offset_x - this value will be added to all reported X coordinates
36 * @offset_y - this value will be added to all reported Y coordinates
37 * @rel_report_enabled - if set to true, the relative reporting will be
38 * automatically enabled for this sensor.
39 */
40struct rmi_2d_axis_alignment {
41 bool swap_axes;
42 bool flip_x;
43 bool flip_y;
44 u16 clip_x_low;
45 u16 clip_y_low;
46 u16 clip_x_high;
47 u16 clip_y_high;
48 u16 offset_x;
49 u16 offset_y;
50 u8 delta_x_threshold;
51 u8 delta_y_threshold;
52};
53
54/** This is used to override any hints an F11 2D sensor might have provided
55 * as to what type of sensor it is.
56 *
57 * @rmi_f11_sensor_default - do not override, determine from F11_2D_QUERY14 if
58 * available.
59 * @rmi_f11_sensor_touchscreen - treat the sensor as a touchscreen (direct
60 * pointing).
61 * @rmi_f11_sensor_touchpad - thread the sensor as a touchpad (indirect
62 * pointing).
63 */
64enum rmi_sensor_type {
65 rmi_sensor_default = 0,
66 rmi_sensor_touchscreen,
67 rmi_sensor_touchpad
68};
69
70#define RMI_F11_DISABLE_ABS_REPORT BIT(0)
71
72/**
73 * struct rmi_2d_sensor_data - overrides defaults for a 2D sensor.
74 * @axis_align - provides axis alignment overrides (see above).
75 * @sensor_type - Forces the driver to treat the sensor as an indirect
76 * pointing device (touchpad) rather than a direct pointing device
77 * (touchscreen). This is useful when F11_2D_QUERY14 register is not
78 * available.
79 * @disable_report_mask - Force data to not be reported even if it is supported
80 * by the firware.
81 * @topbuttonpad - Used with the "5 buttons touchpads" found on the Lenovo 40
82 * series
83 * @kernel_tracking - most moderns RMI f11 firmwares implement Multifinger
84 * Type B protocol. However, there are some corner cases where the user
85 * triggers some jumps by tapping with two fingers on the touchpad.
86 * Use this setting and dmax to filter out these jumps.
87 * Also, when using an old sensor using MF Type A behavior, set to true to
88 * report an actual MT protocol B.
89 * @dmax - the maximum distance (in sensor units) the kernel tracking allows two
90 * distincts fingers to be considered the same.
91 */
92struct rmi_2d_sensor_platform_data {
93 struct rmi_2d_axis_alignment axis_align;
94 enum rmi_sensor_type sensor_type;
95 int x_mm;
96 int y_mm;
97 int disable_report_mask;
98 u16 rezero_wait;
99 bool topbuttonpad;
100 bool kernel_tracking;
101 int dmax;
102};
103
104/**
23 * struct rmi_f01_power - override default power management settings. 105 * struct rmi_f01_power - override default power management settings.
24 * 106 *
25 */ 107 */
@@ -63,6 +145,7 @@ struct rmi_device_platform_data {
63 int reset_delay_ms; 145 int reset_delay_ms;
64 146
65 /* function handler pdata */ 147 /* function handler pdata */
148 struct rmi_2d_sensor_platform_data *sensor_pdata;
66 struct rmi_f01_power_management power_management; 149 struct rmi_f01_power_management power_management;
67}; 150};
68 151