Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
b43d2c1e AD |
2 | /* |
3 | * Copyright (c) 2012-2016 Synaptics Incorporated | |
b43d2c1e AD |
4 | */ |
5 | #include <linux/input.h> | |
6 | #include <linux/input/mt.h> | |
7 | #include <linux/rmi.h> | |
8 | #include "rmi_driver.h" | |
9 | #include "rmi_2d_sensor.h" | |
10 | ||
11 | enum rmi_f12_object_type { | |
12 | RMI_F12_OBJECT_NONE = 0x00, | |
13 | RMI_F12_OBJECT_FINGER = 0x01, | |
14 | RMI_F12_OBJECT_STYLUS = 0x02, | |
15 | RMI_F12_OBJECT_PALM = 0x03, | |
16 | RMI_F12_OBJECT_UNCLASSIFIED = 0x04, | |
17 | RMI_F12_OBJECT_GLOVED_FINGER = 0x06, | |
18 | RMI_F12_OBJECT_NARROW_OBJECT = 0x07, | |
19 | RMI_F12_OBJECT_HAND_EDGE = 0x08, | |
20 | RMI_F12_OBJECT_COVER = 0x0A, | |
21 | RMI_F12_OBJECT_STYLUS_2 = 0x0B, | |
22 | RMI_F12_OBJECT_ERASER = 0x0C, | |
23 | RMI_F12_OBJECT_SMALL_OBJECT = 0x0D, | |
24 | }; | |
25 | ||
6d0dbeae AD |
26 | #define F12_DATA1_BYTES_PER_OBJ 8 |
27 | ||
b43d2c1e | 28 | struct f12_data { |
b43d2c1e AD |
29 | struct rmi_2d_sensor sensor; |
30 | struct rmi_2d_sensor_platform_data sensor_pdata; | |
24f63b1c | 31 | bool has_dribble; |
b43d2c1e AD |
32 | |
33 | u16 data_addr; | |
34 | ||
35 | struct rmi_register_descriptor query_reg_desc; | |
36 | struct rmi_register_descriptor control_reg_desc; | |
37 | struct rmi_register_descriptor data_reg_desc; | |
38 | ||
39 | /* F12 Data1 describes sensed objects */ | |
40 | const struct rmi_register_desc_item *data1; | |
41 | u16 data1_offset; | |
42 | ||
43 | /* F12 Data5 describes finger ACM */ | |
44 | const struct rmi_register_desc_item *data5; | |
45 | u16 data5_offset; | |
46 | ||
47 | /* F12 Data5 describes Pen */ | |
48 | const struct rmi_register_desc_item *data6; | |
49 | u16 data6_offset; | |
50 | ||
51 | ||
52 | /* F12 Data9 reports relative data */ | |
53 | const struct rmi_register_desc_item *data9; | |
54 | u16 data9_offset; | |
55 | ||
56 | const struct rmi_register_desc_item *data15; | |
57 | u16 data15_offset; | |
f6aabe1f AD |
58 | |
59 | unsigned long *abs_mask; | |
60 | unsigned long *rel_mask; | |
b43d2c1e AD |
61 | }; |
62 | ||
63 | static int rmi_f12_read_sensor_tuning(struct f12_data *f12) | |
64 | { | |
65 | const struct rmi_register_desc_item *item; | |
66 | struct rmi_2d_sensor *sensor = &f12->sensor; | |
67 | struct rmi_function *fn = sensor->fn; | |
68 | struct rmi_device *rmi_dev = fn->rmi_dev; | |
69 | int ret; | |
70 | int offset; | |
e4add7b6 | 71 | u8 buf[15]; |
b43d2c1e AD |
72 | int pitch_x = 0; |
73 | int pitch_y = 0; | |
b43d2c1e AD |
74 | int rx_receivers = 0; |
75 | int tx_receivers = 0; | |
b43d2c1e AD |
76 | |
77 | item = rmi_get_register_desc_item(&f12->control_reg_desc, 8); | |
78 | if (!item) { | |
79 | dev_err(&fn->dev, | |
80 | "F12 does not have the sensor tuning control register\n"); | |
81 | return -ENODEV; | |
82 | } | |
83 | ||
84 | offset = rmi_register_desc_calc_reg_offset(&f12->control_reg_desc, 8); | |
85 | ||
e4add7b6 AD |
86 | if (item->reg_size > sizeof(buf)) { |
87 | dev_err(&fn->dev, | |
88 | "F12 control8 should be no bigger than %zd bytes, not: %ld\n", | |
89 | sizeof(buf), item->reg_size); | |
b43d2c1e AD |
90 | return -ENODEV; |
91 | } | |
92 | ||
93 | ret = rmi_read_block(rmi_dev, fn->fd.control_base_addr + offset, buf, | |
94 | item->reg_size); | |
95 | if (ret) | |
96 | return ret; | |
97 | ||
98 | offset = 0; | |
99 | if (rmi_register_desc_has_subpacket(item, 0)) { | |
100 | sensor->max_x = (buf[offset + 1] << 8) | buf[offset]; | |
101 | sensor->max_y = (buf[offset + 3] << 8) | buf[offset + 2]; | |
102 | offset += 4; | |
103 | } | |
104 | ||
105 | rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: max_x: %d max_y: %d\n", __func__, | |
106 | sensor->max_x, sensor->max_y); | |
107 | ||
108 | if (rmi_register_desc_has_subpacket(item, 1)) { | |
109 | pitch_x = (buf[offset + 1] << 8) | buf[offset]; | |
110 | pitch_y = (buf[offset + 3] << 8) | buf[offset + 2]; | |
111 | offset += 4; | |
112 | } | |
113 | ||
114 | if (rmi_register_desc_has_subpacket(item, 2)) { | |
25670fb0 ND |
115 | /* Units 1/128 sensor pitch */ |
116 | rmi_dbg(RMI_DEBUG_FN, &fn->dev, | |
117 | "%s: Inactive Border xlo:%d xhi:%d ylo:%d yhi:%d\n", | |
118 | __func__, | |
119 | buf[offset], buf[offset + 1], | |
120 | buf[offset + 2], buf[offset + 3]); | |
121 | ||
b43d2c1e AD |
122 | offset += 4; |
123 | } | |
124 | ||
b43d2c1e AD |
125 | if (rmi_register_desc_has_subpacket(item, 3)) { |
126 | rx_receivers = buf[offset]; | |
127 | tx_receivers = buf[offset + 1]; | |
128 | offset += 2; | |
129 | } | |
130 | ||
b89a9f2f Y |
131 | /* Skip over sensor flags */ |
132 | if (rmi_register_desc_has_subpacket(item, 4)) | |
b43d2c1e | 133 | offset += 1; |
b43d2c1e AD |
134 | |
135 | sensor->x_mm = (pitch_x * rx_receivers) >> 12; | |
136 | sensor->y_mm = (pitch_y * tx_receivers) >> 12; | |
137 | ||
138 | rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: x_mm: %d y_mm: %d\n", __func__, | |
139 | sensor->x_mm, sensor->y_mm); | |
140 | ||
141 | return 0; | |
142 | } | |
143 | ||
6d0dbeae | 144 | static void rmi_f12_process_objects(struct f12_data *f12, u8 *data1, int size) |
b43d2c1e AD |
145 | { |
146 | int i; | |
147 | struct rmi_2d_sensor *sensor = &f12->sensor; | |
6d0dbeae AD |
148 | int objects = f12->data1->num_subpackets; |
149 | ||
150 | if ((f12->data1->num_subpackets * F12_DATA1_BYTES_PER_OBJ) > size) | |
151 | objects = size / F12_DATA1_BYTES_PER_OBJ; | |
b43d2c1e | 152 | |
6d0dbeae | 153 | for (i = 0; i < objects; i++) { |
b43d2c1e AD |
154 | struct rmi_2d_sensor_abs_object *obj = &sensor->objs[i]; |
155 | ||
156 | obj->type = RMI_2D_OBJECT_NONE; | |
157 | obj->mt_tool = MT_TOOL_FINGER; | |
158 | ||
159 | switch (data1[0]) { | |
160 | case RMI_F12_OBJECT_FINGER: | |
161 | obj->type = RMI_2D_OBJECT_FINGER; | |
162 | break; | |
163 | case RMI_F12_OBJECT_STYLUS: | |
164 | obj->type = RMI_2D_OBJECT_STYLUS; | |
165 | obj->mt_tool = MT_TOOL_PEN; | |
166 | break; | |
167 | case RMI_F12_OBJECT_PALM: | |
168 | obj->type = RMI_2D_OBJECT_PALM; | |
169 | obj->mt_tool = MT_TOOL_PALM; | |
170 | break; | |
171 | case RMI_F12_OBJECT_UNCLASSIFIED: | |
172 | obj->type = RMI_2D_OBJECT_UNCLASSIFIED; | |
173 | break; | |
174 | } | |
175 | ||
176 | obj->x = (data1[2] << 8) | data1[1]; | |
177 | obj->y = (data1[4] << 8) | data1[3]; | |
178 | obj->z = data1[5]; | |
179 | obj->wx = data1[6]; | |
180 | obj->wy = data1[7]; | |
181 | ||
182 | rmi_2d_sensor_abs_process(sensor, obj, i); | |
183 | ||
6d0dbeae | 184 | data1 += F12_DATA1_BYTES_PER_OBJ; |
b43d2c1e AD |
185 | } |
186 | ||
187 | if (sensor->kernel_tracking) | |
188 | input_mt_assign_slots(sensor->input, | |
189 | sensor->tracking_slots, | |
190 | sensor->tracking_pos, | |
191 | sensor->nbr_fingers, | |
192 | sensor->dmax); | |
193 | ||
6d0dbeae | 194 | for (i = 0; i < objects; i++) |
b43d2c1e AD |
195 | rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i); |
196 | } | |
197 | ||
24d28e4f | 198 | static irqreturn_t rmi_f12_attention(int irq, void *ctx) |
b43d2c1e AD |
199 | { |
200 | int retval; | |
24d28e4f | 201 | struct rmi_function *fn = ctx; |
b43d2c1e | 202 | struct rmi_device *rmi_dev = fn->rmi_dev; |
ae9979c3 | 203 | struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); |
b43d2c1e AD |
204 | struct f12_data *f12 = dev_get_drvdata(&fn->dev); |
205 | struct rmi_2d_sensor *sensor = &f12->sensor; | |
6d0dbeae | 206 | int valid_bytes = sensor->pkt_size; |
b43d2c1e | 207 | |
ae9979c3 BT |
208 | if (drvdata->attn_data.data) { |
209 | if (sensor->attn_size > drvdata->attn_data.size) | |
210 | valid_bytes = drvdata->attn_data.size; | |
6d0dbeae AD |
211 | else |
212 | valid_bytes = sensor->attn_size; | |
ae9979c3 | 213 | memcpy(sensor->data_pkt, drvdata->attn_data.data, |
6d0dbeae | 214 | valid_bytes); |
5d40d95e AD |
215 | drvdata->attn_data.data += valid_bytes; |
216 | drvdata->attn_data.size -= valid_bytes; | |
b43d2c1e AD |
217 | } else { |
218 | retval = rmi_read_block(rmi_dev, f12->data_addr, | |
219 | sensor->data_pkt, sensor->pkt_size); | |
220 | if (retval < 0) { | |
221 | dev_err(&fn->dev, "Failed to read object data. Code: %d.\n", | |
222 | retval); | |
24d28e4f | 223 | return IRQ_RETVAL(retval); |
b43d2c1e AD |
224 | } |
225 | } | |
226 | ||
227 | if (f12->data1) | |
228 | rmi_f12_process_objects(f12, | |
6d0dbeae | 229 | &sensor->data_pkt[f12->data1_offset], valid_bytes); |
b43d2c1e AD |
230 | |
231 | input_mt_sync_frame(sensor->input); | |
232 | ||
24d28e4f | 233 | return IRQ_HANDLED; |
b43d2c1e AD |
234 | } |
235 | ||
24f63b1c AD |
236 | static int rmi_f12_write_control_regs(struct rmi_function *fn) |
237 | { | |
238 | int ret; | |
239 | const struct rmi_register_desc_item *item; | |
240 | struct rmi_device *rmi_dev = fn->rmi_dev; | |
241 | struct f12_data *f12 = dev_get_drvdata(&fn->dev); | |
242 | int control_size; | |
243 | char buf[3]; | |
244 | u16 control_offset = 0; | |
245 | u8 subpacket_offset = 0; | |
246 | ||
247 | if (f12->has_dribble | |
248 | && (f12->sensor.dribble != RMI_REG_STATE_DEFAULT)) { | |
249 | item = rmi_get_register_desc_item(&f12->control_reg_desc, 20); | |
250 | if (item) { | |
251 | control_offset = rmi_register_desc_calc_reg_offset( | |
252 | &f12->control_reg_desc, 20); | |
253 | ||
254 | /* | |
255 | * The byte containing the EnableDribble bit will be | |
256 | * in either byte 0 or byte 2 of control 20. Depending | |
257 | * on the existence of subpacket 0. If control 20 is | |
258 | * larger then 3 bytes, just read the first 3. | |
259 | */ | |
260 | control_size = min(item->reg_size, 3UL); | |
261 | ||
262 | ret = rmi_read_block(rmi_dev, fn->fd.control_base_addr | |
263 | + control_offset, buf, control_size); | |
264 | if (ret) | |
265 | return ret; | |
266 | ||
267 | if (rmi_register_desc_has_subpacket(item, 0)) | |
268 | subpacket_offset += 1; | |
269 | ||
270 | switch (f12->sensor.dribble) { | |
271 | case RMI_REG_STATE_OFF: | |
272 | buf[subpacket_offset] &= ~BIT(2); | |
273 | break; | |
274 | case RMI_REG_STATE_ON: | |
275 | buf[subpacket_offset] |= BIT(2); | |
276 | break; | |
277 | case RMI_REG_STATE_DEFAULT: | |
278 | default: | |
279 | break; | |
280 | } | |
281 | ||
282 | ret = rmi_write_block(rmi_dev, | |
283 | fn->fd.control_base_addr + control_offset, | |
284 | buf, control_size); | |
285 | if (ret) | |
286 | return ret; | |
287 | } | |
288 | } | |
289 | ||
290 | return 0; | |
291 | ||
292 | } | |
293 | ||
b43d2c1e AD |
294 | static int rmi_f12_config(struct rmi_function *fn) |
295 | { | |
296 | struct rmi_driver *drv = fn->rmi_dev->driver; | |
f6aabe1f AD |
297 | struct f12_data *f12 = dev_get_drvdata(&fn->dev); |
298 | struct rmi_2d_sensor *sensor; | |
24f63b1c | 299 | int ret; |
b43d2c1e | 300 | |
f6aabe1f AD |
301 | sensor = &f12->sensor; |
302 | ||
303 | if (!sensor->report_abs) | |
304 | drv->clear_irq_bits(fn->rmi_dev, f12->abs_mask); | |
305 | else | |
306 | drv->set_irq_bits(fn->rmi_dev, f12->abs_mask); | |
307 | ||
308 | drv->clear_irq_bits(fn->rmi_dev, f12->rel_mask); | |
b43d2c1e | 309 | |
24f63b1c AD |
310 | ret = rmi_f12_write_control_regs(fn); |
311 | if (ret) | |
312 | dev_warn(&fn->dev, | |
313 | "Failed to write F12 control registers: %d\n", ret); | |
314 | ||
b43d2c1e AD |
315 | return 0; |
316 | } | |
317 | ||
318 | static int rmi_f12_probe(struct rmi_function *fn) | |
319 | { | |
320 | struct f12_data *f12; | |
321 | int ret; | |
322 | struct rmi_device *rmi_dev = fn->rmi_dev; | |
323 | char buf; | |
324 | u16 query_addr = fn->fd.query_base_addr; | |
325 | const struct rmi_register_desc_item *item; | |
326 | struct rmi_2d_sensor *sensor; | |
327 | struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); | |
ae9979c3 | 328 | struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); |
b43d2c1e | 329 | u16 data_offset = 0; |
f6aabe1f | 330 | int mask_size; |
b43d2c1e AD |
331 | |
332 | rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s\n", __func__); | |
333 | ||
f6aabe1f AD |
334 | mask_size = BITS_TO_LONGS(drvdata->irq_count) * sizeof(unsigned long); |
335 | ||
b43d2c1e AD |
336 | ret = rmi_read(fn->rmi_dev, query_addr, &buf); |
337 | if (ret < 0) { | |
338 | dev_err(&fn->dev, "Failed to read general info register: %d\n", | |
339 | ret); | |
340 | return -ENODEV; | |
341 | } | |
342 | ++query_addr; | |
343 | ||
24f63b1c | 344 | if (!(buf & BIT(0))) { |
b43d2c1e AD |
345 | dev_err(&fn->dev, |
346 | "Behavior of F12 without register descriptors is undefined.\n"); | |
347 | return -ENODEV; | |
348 | } | |
349 | ||
f6aabe1f AD |
350 | f12 = devm_kzalloc(&fn->dev, sizeof(struct f12_data) + mask_size * 2, |
351 | GFP_KERNEL); | |
b43d2c1e AD |
352 | if (!f12) |
353 | return -ENOMEM; | |
354 | ||
f6aabe1f AD |
355 | f12->abs_mask = (unsigned long *)((char *)f12 |
356 | + sizeof(struct f12_data)); | |
357 | f12->rel_mask = (unsigned long *)((char *)f12 | |
358 | + sizeof(struct f12_data) + mask_size); | |
359 | ||
360 | set_bit(fn->irq_pos, f12->abs_mask); | |
361 | set_bit(fn->irq_pos + 1, f12->rel_mask); | |
362 | ||
24f63b1c AD |
363 | f12->has_dribble = !!(buf & BIT(3)); |
364 | ||
b43d2c1e AD |
365 | if (fn->dev.of_node) { |
366 | ret = rmi_2d_sensor_of_probe(&fn->dev, &f12->sensor_pdata); | |
367 | if (ret) | |
368 | return ret; | |
0a135b88 BT |
369 | } else { |
370 | f12->sensor_pdata = pdata->sensor_pdata; | |
b43d2c1e AD |
371 | } |
372 | ||
373 | ret = rmi_read_register_desc(rmi_dev, query_addr, | |
374 | &f12->query_reg_desc); | |
375 | if (ret) { | |
376 | dev_err(&fn->dev, | |
377 | "Failed to read the Query Register Descriptor: %d\n", | |
378 | ret); | |
379 | return ret; | |
380 | } | |
381 | query_addr += 3; | |
382 | ||
383 | ret = rmi_read_register_desc(rmi_dev, query_addr, | |
384 | &f12->control_reg_desc); | |
385 | if (ret) { | |
386 | dev_err(&fn->dev, | |
387 | "Failed to read the Control Register Descriptor: %d\n", | |
388 | ret); | |
389 | return ret; | |
390 | } | |
391 | query_addr += 3; | |
392 | ||
393 | ret = rmi_read_register_desc(rmi_dev, query_addr, | |
394 | &f12->data_reg_desc); | |
395 | if (ret) { | |
396 | dev_err(&fn->dev, | |
397 | "Failed to read the Data Register Descriptor: %d\n", | |
398 | ret); | |
399 | return ret; | |
400 | } | |
401 | query_addr += 3; | |
402 | ||
403 | sensor = &f12->sensor; | |
404 | sensor->fn = fn; | |
405 | f12->data_addr = fn->fd.data_base_addr; | |
406 | sensor->pkt_size = rmi_register_desc_calc_size(&f12->data_reg_desc); | |
407 | ||
408 | sensor->axis_align = | |
409 | f12->sensor_pdata.axis_align; | |
410 | ||
411 | sensor->x_mm = f12->sensor_pdata.x_mm; | |
412 | sensor->y_mm = f12->sensor_pdata.y_mm; | |
24f63b1c | 413 | sensor->dribble = f12->sensor_pdata.dribble; |
b43d2c1e AD |
414 | |
415 | if (sensor->sensor_type == rmi_sensor_default) | |
416 | sensor->sensor_type = | |
417 | f12->sensor_pdata.sensor_type; | |
418 | ||
419 | rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: data packet size: %d\n", __func__, | |
420 | sensor->pkt_size); | |
421 | sensor->data_pkt = devm_kzalloc(&fn->dev, sensor->pkt_size, GFP_KERNEL); | |
422 | if (!sensor->data_pkt) | |
423 | return -ENOMEM; | |
424 | ||
425 | dev_set_drvdata(&fn->dev, f12); | |
426 | ||
427 | ret = rmi_f12_read_sensor_tuning(f12); | |
428 | if (ret) | |
429 | return ret; | |
430 | ||
431 | /* | |
432 | * Figure out what data is contained in the data registers. HID devices | |
433 | * may have registers defined, but their data is not reported in the | |
434 | * HID attention report. Registers which are not reported in the HID | |
435 | * attention report check to see if the device is receiving data from | |
436 | * HID attention reports. | |
437 | */ | |
438 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 0); | |
ae9979c3 | 439 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
440 | data_offset += item->reg_size; |
441 | ||
442 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 1); | |
443 | if (item) { | |
444 | f12->data1 = item; | |
445 | f12->data1_offset = data_offset; | |
446 | data_offset += item->reg_size; | |
447 | sensor->nbr_fingers = item->num_subpackets; | |
448 | sensor->report_abs = 1; | |
449 | sensor->attn_size += item->reg_size; | |
450 | } | |
451 | ||
452 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 2); | |
ae9979c3 | 453 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
454 | data_offset += item->reg_size; |
455 | ||
456 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 3); | |
ae9979c3 | 457 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
458 | data_offset += item->reg_size; |
459 | ||
460 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 4); | |
ae9979c3 | 461 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
462 | data_offset += item->reg_size; |
463 | ||
464 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 5); | |
465 | if (item) { | |
466 | f12->data5 = item; | |
467 | f12->data5_offset = data_offset; | |
468 | data_offset += item->reg_size; | |
469 | sensor->attn_size += item->reg_size; | |
470 | } | |
471 | ||
472 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 6); | |
ae9979c3 | 473 | if (item && !drvdata->attn_data.data) { |
b43d2c1e AD |
474 | f12->data6 = item; |
475 | f12->data6_offset = data_offset; | |
476 | data_offset += item->reg_size; | |
477 | } | |
478 | ||
479 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 7); | |
ae9979c3 | 480 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
481 | data_offset += item->reg_size; |
482 | ||
483 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 8); | |
ae9979c3 | 484 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
485 | data_offset += item->reg_size; |
486 | ||
487 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 9); | |
ae9979c3 | 488 | if (item && !drvdata->attn_data.data) { |
b43d2c1e AD |
489 | f12->data9 = item; |
490 | f12->data9_offset = data_offset; | |
491 | data_offset += item->reg_size; | |
492 | if (!sensor->report_abs) | |
493 | sensor->report_rel = 1; | |
494 | } | |
495 | ||
496 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 10); | |
ae9979c3 | 497 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
498 | data_offset += item->reg_size; |
499 | ||
500 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 11); | |
ae9979c3 | 501 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
502 | data_offset += item->reg_size; |
503 | ||
504 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 12); | |
ae9979c3 | 505 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
506 | data_offset += item->reg_size; |
507 | ||
508 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 13); | |
ae9979c3 | 509 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
510 | data_offset += item->reg_size; |
511 | ||
512 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 14); | |
ae9979c3 | 513 | if (item && !drvdata->attn_data.data) |
b43d2c1e AD |
514 | data_offset += item->reg_size; |
515 | ||
516 | item = rmi_get_register_desc_item(&f12->data_reg_desc, 15); | |
ae9979c3 | 517 | if (item && !drvdata->attn_data.data) { |
b43d2c1e AD |
518 | f12->data15 = item; |
519 | f12->data15_offset = data_offset; | |
520 | data_offset += item->reg_size; | |
521 | } | |
522 | ||
523 | /* allocate the in-kernel tracking buffers */ | |
a86854d0 KC |
524 | sensor->tracking_pos = devm_kcalloc(&fn->dev, |
525 | sensor->nbr_fingers, sizeof(struct input_mt_pos), | |
526 | GFP_KERNEL); | |
527 | sensor->tracking_slots = devm_kcalloc(&fn->dev, | |
528 | sensor->nbr_fingers, sizeof(int), GFP_KERNEL); | |
529 | sensor->objs = devm_kcalloc(&fn->dev, | |
530 | sensor->nbr_fingers, | |
531 | sizeof(struct rmi_2d_sensor_abs_object), | |
b43d2c1e | 532 | GFP_KERNEL); |
b43d2c1e AD |
533 | if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs) |
534 | return -ENOMEM; | |
535 | ||
536 | ret = rmi_2d_sensor_configure_input(fn, sensor); | |
537 | if (ret) | |
538 | return ret; | |
539 | ||
540 | return 0; | |
541 | } | |
542 | ||
543 | struct rmi_function_handler rmi_f12_handler = { | |
544 | .driver = { | |
545 | .name = "rmi4_f12", | |
546 | }, | |
547 | .func = 0x12, | |
548 | .probe = rmi_f12_probe, | |
549 | .config = rmi_f12_config, | |
550 | .attention = rmi_f12_attention, | |
551 | }; |