aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Duggan <aduggan@synaptics.com>2016-03-10 18:55:29 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2016-03-10 19:04:06 -0500
commitb43d2c1e9353814ce1716fff03d9223f40fa73b5 (patch)
treef97125db3487d4f61c633ee8080d2167637c898b
parentaaa27982b3bcc3cce6a1d835673adccd75903a2e (diff)
Input: synaptics-rmi4 - add support for F12
Function 12 implements 2D touch position sensor for newer Synaptics touch devices. It replaces F11 and no device will contain both functions. 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/Kconfig11
-rw-r--r--drivers/input/rmi4/Makefile1
-rw-r--r--drivers/input/rmi4/rmi_bus.c3
-rw-r--r--drivers/input/rmi4/rmi_driver.h1
-rw-r--r--drivers/input/rmi4/rmi_f12.c457
5 files changed, 473 insertions, 0 deletions
diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index dc7de6bbb8e6..aabb8542a55d 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -32,3 +32,14 @@ config RMI4_F11
32 Function 11 provides 2D multifinger pointing for touchscreens and 32 Function 11 provides 2D multifinger pointing for touchscreens and
33 touchpads. For sensors that support relative pointing, F11 also 33 touchpads. For sensors that support relative pointing, F11 also
34 provides mouse input. 34 provides mouse input.
35
36config RMI4_F12
37 bool "RMI4 Function 12 (2D pointing)"
38 select RMI4_2D_SENSOR
39 depends on RMI4_CORE
40 help
41 Say Y here if you want to add support for RMI4 function 12.
42
43 Function 12 provides 2D multifinger pointing for touchscreens and
44 touchpads. For sensors that support relative pointing, F12 also
45 provides mouse input.
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 9e7424ae1c72..d01e703304c3 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -5,6 +5,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
5 5
6# Function drivers 6# Function drivers
7rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o 7rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
8rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
8 9
9# Transports 10# Transports
10obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o 11obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index 2e3878343961..a3d766118b61 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -309,6 +309,9 @@ static struct rmi_function_handler *fn_handlers[] = {
309#ifdef CONFIG_RMI4_F11 309#ifdef CONFIG_RMI4_F11
310 &rmi_f11_handler, 310 &rmi_f11_handler,
311#endif 311#endif
312#ifdef CONFIG_RMI4_F12
313 &rmi_f12_handler,
314#endif
312}; 315};
313 316
314static void __rmi_unregister_function_handlers(int start_idx) 317static 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 09d2aa7f11d4..ed9127daf5a2 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -100,4 +100,5 @@ char *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;
102extern struct rmi_function_handler rmi_f11_handler; 102extern struct rmi_function_handler rmi_f11_handler;
103extern struct rmi_function_handler rmi_f12_handler;
103#endif 104#endif
diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c
new file mode 100644
index 000000000000..8dd3fb5e1f94
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f12.c
@@ -0,0 +1,457 @@
1/*
2 * Copyright (c) 2012-2016 Synaptics Incorporated
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 */
8#include <linux/input.h>
9#include <linux/input/mt.h>
10#include <linux/rmi.h>
11#include "rmi_driver.h"
12#include "rmi_2d_sensor.h"
13
14enum rmi_f12_object_type {
15 RMI_F12_OBJECT_NONE = 0x00,
16 RMI_F12_OBJECT_FINGER = 0x01,
17 RMI_F12_OBJECT_STYLUS = 0x02,
18 RMI_F12_OBJECT_PALM = 0x03,
19 RMI_F12_OBJECT_UNCLASSIFIED = 0x04,
20 RMI_F12_OBJECT_GLOVED_FINGER = 0x06,
21 RMI_F12_OBJECT_NARROW_OBJECT = 0x07,
22 RMI_F12_OBJECT_HAND_EDGE = 0x08,
23 RMI_F12_OBJECT_COVER = 0x0A,
24 RMI_F12_OBJECT_STYLUS_2 = 0x0B,
25 RMI_F12_OBJECT_ERASER = 0x0C,
26 RMI_F12_OBJECT_SMALL_OBJECT = 0x0D,
27};
28
29struct f12_data {
30 struct rmi_function *fn;
31 struct rmi_2d_sensor sensor;
32 struct rmi_2d_sensor_platform_data sensor_pdata;
33
34 u16 data_addr;
35
36 struct rmi_register_descriptor query_reg_desc;
37 struct rmi_register_descriptor control_reg_desc;
38 struct rmi_register_descriptor data_reg_desc;
39
40 /* F12 Data1 describes sensed objects */
41 const struct rmi_register_desc_item *data1;
42 u16 data1_offset;
43
44 /* F12 Data5 describes finger ACM */
45 const struct rmi_register_desc_item *data5;
46 u16 data5_offset;
47
48 /* F12 Data5 describes Pen */
49 const struct rmi_register_desc_item *data6;
50 u16 data6_offset;
51
52
53 /* F12 Data9 reports relative data */
54 const struct rmi_register_desc_item *data9;
55 u16 data9_offset;
56
57 const struct rmi_register_desc_item *data15;
58 u16 data15_offset;
59};
60
61static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
62{
63 const struct rmi_register_desc_item *item;
64 struct rmi_2d_sensor *sensor = &f12->sensor;
65 struct rmi_function *fn = sensor->fn;
66 struct rmi_device *rmi_dev = fn->rmi_dev;
67 int ret;
68 int offset;
69 u8 buf[14];
70 int pitch_x = 0;
71 int pitch_y = 0;
72 int clip_x_low = 0;
73 int clip_x_high = 0;
74 int clip_y_low = 0;
75 int clip_y_high = 0;
76 int rx_receivers = 0;
77 int tx_receivers = 0;
78 int sensor_flags = 0;
79
80 item = rmi_get_register_desc_item(&f12->control_reg_desc, 8);
81 if (!item) {
82 dev_err(&fn->dev,
83 "F12 does not have the sensor tuning control register\n");
84 return -ENODEV;
85 }
86
87 offset = rmi_register_desc_calc_reg_offset(&f12->control_reg_desc, 8);
88
89 if (item->reg_size > 14) {
90 dev_err(&fn->dev, "F12 control8 should be 14 bytes, not: %ld\n",
91 item->reg_size);
92 return -ENODEV;
93 }
94
95 ret = rmi_read_block(rmi_dev, fn->fd.control_base_addr + offset, buf,
96 item->reg_size);
97 if (ret)
98 return ret;
99
100 offset = 0;
101 if (rmi_register_desc_has_subpacket(item, 0)) {
102 sensor->max_x = (buf[offset + 1] << 8) | buf[offset];
103 sensor->max_y = (buf[offset + 3] << 8) | buf[offset + 2];
104 offset += 4;
105 }
106
107 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: max_x: %d max_y: %d\n", __func__,
108 sensor->max_x, sensor->max_y);
109
110 if (rmi_register_desc_has_subpacket(item, 1)) {
111 pitch_x = (buf[offset + 1] << 8) | buf[offset];
112 pitch_y = (buf[offset + 3] << 8) | buf[offset + 2];
113 offset += 4;
114 }
115
116 if (rmi_register_desc_has_subpacket(item, 2)) {
117 sensor->axis_align.clip_x_low = buf[offset];
118 sensor->axis_align.clip_x_high = sensor->max_x
119 - buf[offset + 1];
120 sensor->axis_align.clip_y_low = buf[offset + 2];
121 sensor->axis_align.clip_y_high = sensor->max_y
122 - buf[offset + 3];
123 offset += 4;
124 }
125
126 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: x low: %d x high: %d y low: %d y high: %d\n",
127 __func__, clip_x_low, clip_x_high, clip_y_low, clip_y_high);
128
129 if (rmi_register_desc_has_subpacket(item, 3)) {
130 rx_receivers = buf[offset];
131 tx_receivers = buf[offset + 1];
132 offset += 2;
133 }
134
135 if (rmi_register_desc_has_subpacket(item, 4)) {
136 sensor_flags = buf[offset];
137 offset += 1;
138 }
139
140 sensor->x_mm = (pitch_x * rx_receivers) >> 12;
141 sensor->y_mm = (pitch_y * tx_receivers) >> 12;
142
143 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: x_mm: %d y_mm: %d\n", __func__,
144 sensor->x_mm, sensor->y_mm);
145
146 return 0;
147}
148
149static void rmi_f12_process_objects(struct f12_data *f12, u8 *data1)
150{
151 int i;
152 struct rmi_2d_sensor *sensor = &f12->sensor;
153
154 for (i = 0; i < f12->data1->num_subpackets; i++) {
155 struct rmi_2d_sensor_abs_object *obj = &sensor->objs[i];
156
157 obj->type = RMI_2D_OBJECT_NONE;
158 obj->mt_tool = MT_TOOL_FINGER;
159
160 switch (data1[0]) {
161 case RMI_F12_OBJECT_FINGER:
162 obj->type = RMI_2D_OBJECT_FINGER;
163 break;
164 case RMI_F12_OBJECT_STYLUS:
165 obj->type = RMI_2D_OBJECT_STYLUS;
166 obj->mt_tool = MT_TOOL_PEN;
167 break;
168 case RMI_F12_OBJECT_PALM:
169 obj->type = RMI_2D_OBJECT_PALM;
170 obj->mt_tool = MT_TOOL_PALM;
171 break;
172 case RMI_F12_OBJECT_UNCLASSIFIED:
173 obj->type = RMI_2D_OBJECT_UNCLASSIFIED;
174 break;
175 }
176
177 obj->x = (data1[2] << 8) | data1[1];
178 obj->y = (data1[4] << 8) | data1[3];
179 obj->z = data1[5];
180 obj->wx = data1[6];
181 obj->wy = data1[7];
182
183 rmi_2d_sensor_abs_process(sensor, obj, i);
184
185 data1 += 8;
186 }
187
188 if (sensor->kernel_tracking)
189 input_mt_assign_slots(sensor->input,
190 sensor->tracking_slots,
191 sensor->tracking_pos,
192 sensor->nbr_fingers,
193 sensor->dmax);
194
195 for (i = 0; i < sensor->nbr_fingers; i++)
196 rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i);
197}
198
199static int rmi_f12_attention(struct rmi_function *fn,
200 unsigned long *irq_nr_regs)
201{
202 int retval;
203 struct rmi_device *rmi_dev = fn->rmi_dev;
204 struct f12_data *f12 = dev_get_drvdata(&fn->dev);
205 struct rmi_2d_sensor *sensor = &f12->sensor;
206
207 if (rmi_dev->xport->attn_data) {
208 memcpy(sensor->data_pkt, rmi_dev->xport->attn_data,
209 sensor->attn_size);
210 rmi_dev->xport->attn_data += sensor->attn_size;
211 rmi_dev->xport->attn_size -= sensor->attn_size;
212 } else {
213 retval = rmi_read_block(rmi_dev, f12->data_addr,
214 sensor->data_pkt, sensor->pkt_size);
215 if (retval < 0) {
216 dev_err(&fn->dev, "Failed to read object data. Code: %d.\n",
217 retval);
218 return retval;
219 }
220 }
221
222 if (f12->data1)
223 rmi_f12_process_objects(f12,
224 &sensor->data_pkt[f12->data1_offset]);
225
226 input_mt_sync_frame(sensor->input);
227
228 return 0;
229}
230
231static int rmi_f12_config(struct rmi_function *fn)
232{
233 struct rmi_driver *drv = fn->rmi_dev->driver;
234
235 drv->set_irq_bits(fn->rmi_dev, fn->irq_mask);
236
237 return 0;
238}
239
240static int rmi_f12_probe(struct rmi_function *fn)
241{
242 struct f12_data *f12;
243 int ret;
244 struct rmi_device *rmi_dev = fn->rmi_dev;
245 char buf;
246 u16 query_addr = fn->fd.query_base_addr;
247 const struct rmi_register_desc_item *item;
248 struct rmi_2d_sensor *sensor;
249 struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
250 struct rmi_transport_dev *xport = rmi_dev->xport;
251 u16 data_offset = 0;
252
253 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s\n", __func__);
254
255 ret = rmi_read(fn->rmi_dev, query_addr, &buf);
256 if (ret < 0) {
257 dev_err(&fn->dev, "Failed to read general info register: %d\n",
258 ret);
259 return -ENODEV;
260 }
261 ++query_addr;
262
263 if (!(buf & 0x1)) {
264 dev_err(&fn->dev,
265 "Behavior of F12 without register descriptors is undefined.\n");
266 return -ENODEV;
267 }
268
269 f12 = devm_kzalloc(&fn->dev, sizeof(struct f12_data), GFP_KERNEL);
270 if (!f12)
271 return -ENOMEM;
272
273 if (fn->dev.of_node) {
274 ret = rmi_2d_sensor_of_probe(&fn->dev, &f12->sensor_pdata);
275 if (ret)
276 return ret;
277 } else if (pdata->sensor_pdata) {
278 f12->sensor_pdata = *pdata->sensor_pdata;
279 }
280
281 ret = rmi_read_register_desc(rmi_dev, query_addr,
282 &f12->query_reg_desc);
283 if (ret) {
284 dev_err(&fn->dev,
285 "Failed to read the Query Register Descriptor: %d\n",
286 ret);
287 return ret;
288 }
289 query_addr += 3;
290
291 ret = rmi_read_register_desc(rmi_dev, query_addr,
292 &f12->control_reg_desc);
293 if (ret) {
294 dev_err(&fn->dev,
295 "Failed to read the Control Register Descriptor: %d\n",
296 ret);
297 return ret;
298 }
299 query_addr += 3;
300
301 ret = rmi_read_register_desc(rmi_dev, query_addr,
302 &f12->data_reg_desc);
303 if (ret) {
304 dev_err(&fn->dev,
305 "Failed to read the Data Register Descriptor: %d\n",
306 ret);
307 return ret;
308 }
309 query_addr += 3;
310
311 sensor = &f12->sensor;
312 sensor->fn = fn;
313 f12->data_addr = fn->fd.data_base_addr;
314 sensor->pkt_size = rmi_register_desc_calc_size(&f12->data_reg_desc);
315
316 sensor->axis_align =
317 f12->sensor_pdata.axis_align;
318
319 sensor->x_mm = f12->sensor_pdata.x_mm;
320 sensor->y_mm = f12->sensor_pdata.y_mm;
321
322 if (sensor->sensor_type == rmi_sensor_default)
323 sensor->sensor_type =
324 f12->sensor_pdata.sensor_type;
325
326 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: data packet size: %d\n", __func__,
327 sensor->pkt_size);
328 sensor->data_pkt = devm_kzalloc(&fn->dev, sensor->pkt_size, GFP_KERNEL);
329 if (!sensor->data_pkt)
330 return -ENOMEM;
331
332 dev_set_drvdata(&fn->dev, f12);
333
334 ret = rmi_f12_read_sensor_tuning(f12);
335 if (ret)
336 return ret;
337
338 /*
339 * Figure out what data is contained in the data registers. HID devices
340 * may have registers defined, but their data is not reported in the
341 * HID attention report. Registers which are not reported in the HID
342 * attention report check to see if the device is receiving data from
343 * HID attention reports.
344 */
345 item = rmi_get_register_desc_item(&f12->data_reg_desc, 0);
346 if (item && !xport->attn_data)
347 data_offset += item->reg_size;
348
349 item = rmi_get_register_desc_item(&f12->data_reg_desc, 1);
350 if (item) {
351 f12->data1 = item;
352 f12->data1_offset = data_offset;
353 data_offset += item->reg_size;
354 sensor->nbr_fingers = item->num_subpackets;
355 sensor->report_abs = 1;
356 sensor->attn_size += item->reg_size;
357 }
358
359 item = rmi_get_register_desc_item(&f12->data_reg_desc, 2);
360 if (item && !xport->attn_data)
361 data_offset += item->reg_size;
362
363 item = rmi_get_register_desc_item(&f12->data_reg_desc, 3);
364 if (item && !xport->attn_data)
365 data_offset += item->reg_size;
366
367 item = rmi_get_register_desc_item(&f12->data_reg_desc, 4);
368 if (item && !xport->attn_data)
369 data_offset += item->reg_size;
370
371 item = rmi_get_register_desc_item(&f12->data_reg_desc, 5);
372 if (item) {
373 f12->data5 = item;
374 f12->data5_offset = data_offset;
375 data_offset += item->reg_size;
376 sensor->attn_size += item->reg_size;
377 }
378
379 item = rmi_get_register_desc_item(&f12->data_reg_desc, 6);
380 if (item && !xport->attn_data) {
381 f12->data6 = item;
382 f12->data6_offset = data_offset;
383 data_offset += item->reg_size;
384 }
385
386 item = rmi_get_register_desc_item(&f12->data_reg_desc, 7);
387 if (item && !xport->attn_data)
388 data_offset += item->reg_size;
389
390 item = rmi_get_register_desc_item(&f12->data_reg_desc, 8);
391 if (item && !xport->attn_data)
392 data_offset += item->reg_size;
393
394 item = rmi_get_register_desc_item(&f12->data_reg_desc, 9);
395 if (item && !xport->attn_data) {
396 f12->data9 = item;
397 f12->data9_offset = data_offset;
398 data_offset += item->reg_size;
399 if (!sensor->report_abs)
400 sensor->report_rel = 1;
401 }
402
403 item = rmi_get_register_desc_item(&f12->data_reg_desc, 10);
404 if (item && !xport->attn_data)
405 data_offset += item->reg_size;
406
407 item = rmi_get_register_desc_item(&f12->data_reg_desc, 11);
408 if (item && !xport->attn_data)
409 data_offset += item->reg_size;
410
411 item = rmi_get_register_desc_item(&f12->data_reg_desc, 12);
412 if (item && !xport->attn_data)
413 data_offset += item->reg_size;
414
415 item = rmi_get_register_desc_item(&f12->data_reg_desc, 13);
416 if (item && !xport->attn_data)
417 data_offset += item->reg_size;
418
419 item = rmi_get_register_desc_item(&f12->data_reg_desc, 14);
420 if (item && !xport->attn_data)
421 data_offset += item->reg_size;
422
423 item = rmi_get_register_desc_item(&f12->data_reg_desc, 15);
424 if (item && !xport->attn_data) {
425 f12->data15 = item;
426 f12->data15_offset = data_offset;
427 data_offset += item->reg_size;
428 }
429
430 /* allocate the in-kernel tracking buffers */
431 sensor->tracking_pos = devm_kzalloc(&fn->dev,
432 sizeof(struct input_mt_pos) * sensor->nbr_fingers,
433 GFP_KERNEL);
434 sensor->tracking_slots = devm_kzalloc(&fn->dev,
435 sizeof(int) * sensor->nbr_fingers, GFP_KERNEL);
436 sensor->objs = devm_kzalloc(&fn->dev,
437 sizeof(struct rmi_2d_sensor_abs_object)
438 * sensor->nbr_fingers, GFP_KERNEL);
439 if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs)
440 return -ENOMEM;
441
442 ret = rmi_2d_sensor_configure_input(fn, sensor);
443 if (ret)
444 return ret;
445
446 return 0;
447}
448
449struct rmi_function_handler rmi_f12_handler = {
450 .driver = {
451 .name = "rmi4_f12",
452 },
453 .func = 0x12,
454 .probe = rmi_f12_probe,
455 .config = rmi_f12_config,
456 .attention = rmi_f12_attention,
457};