diff options
Diffstat (limited to 'drivers/input/touchscreen/rmi4/rmi_f19.c')
-rw-r--r-- | drivers/input/touchscreen/rmi4/rmi_f19.c | 1419 |
1 files changed, 1419 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/rmi4/rmi_f19.c b/drivers/input/touchscreen/rmi4/rmi_f19.c new file mode 100644 index 00000000000..9ff9ff99f91 --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_f19.c | |||
@@ -0,0 +1,1419 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/rmi.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | #define QUERY_BASE_INDEX 1 | ||
25 | #define MAX_LEN 256 | ||
26 | |||
27 | struct f19_0d_query { | ||
28 | union { | ||
29 | struct { | ||
30 | u8 configurable:1; | ||
31 | u8 has_sensitivity_adjust:1; | ||
32 | u8 has_hysteresis_threshold:1; | ||
33 | }; | ||
34 | u8 f19_0d_query0; | ||
35 | }; | ||
36 | u8 f19_0d_query1:5; | ||
37 | }; | ||
38 | |||
39 | struct f19_0d_control_0 { | ||
40 | union { | ||
41 | struct { | ||
42 | u8 button_usage:2; | ||
43 | u8 filter_mode:2; | ||
44 | }; | ||
45 | u8 f19_0d_control0; | ||
46 | }; | ||
47 | }; | ||
48 | |||
49 | struct f19_0d_control_1 { | ||
50 | u8 int_enabled_button; | ||
51 | }; | ||
52 | |||
53 | struct f19_0d_control_2 { | ||
54 | u8 single_button; | ||
55 | }; | ||
56 | |||
57 | struct f19_0d_control_3_4 { | ||
58 | u8 sensor_map_button:7; | ||
59 | /*u8 sensitivity_button;*/ | ||
60 | }; | ||
61 | |||
62 | struct f19_0d_control_5 { | ||
63 | u8 sensitivity_adj; | ||
64 | }; | ||
65 | struct f19_0d_control_6 { | ||
66 | u8 hysteresis_threshold; | ||
67 | }; | ||
68 | |||
69 | struct f19_0d_control { | ||
70 | struct f19_0d_control_0 *general_control; | ||
71 | struct f19_0d_control_1 *button_int_enable; | ||
72 | struct f19_0d_control_2 *single_button_participation; | ||
73 | struct f19_0d_control_3_4 *sensor_map; | ||
74 | struct f19_0d_control_5 *all_button_sensitivity_adj; | ||
75 | struct f19_0d_control_6 *all_button_hysteresis_threshold; | ||
76 | }; | ||
77 | /* data specific to fn $19 that needs to be kept around */ | ||
78 | struct f19_data { | ||
79 | struct f19_0d_control *button_control; | ||
80 | struct f19_0d_query button_query; | ||
81 | u8 button_rezero; | ||
82 | bool *button_down; | ||
83 | unsigned char button_count; | ||
84 | unsigned char button_data_buffer_size; | ||
85 | unsigned char *button_data_buffer; | ||
86 | unsigned char *button_map; | ||
87 | char input_name[MAX_LEN]; | ||
88 | char input_phys[MAX_LEN]; | ||
89 | struct input_dev *input; | ||
90 | }; | ||
91 | |||
92 | static ssize_t rmi_f19_button_count_show(struct device *dev, | ||
93 | struct device_attribute *attr, | ||
94 | char *buf); | ||
95 | |||
96 | static ssize_t rmi_f19_button_map_show(struct device *dev, | ||
97 | struct device_attribute *attr, char *buf); | ||
98 | |||
99 | static ssize_t rmi_f19_button_map_store(struct device *dev, | ||
100 | struct device_attribute *attr, | ||
101 | const char *buf, size_t count); | ||
102 | static ssize_t rmi_f19_rezero_show(struct device *dev, | ||
103 | struct device_attribute *attr, | ||
104 | char *buf); | ||
105 | static ssize_t rmi_f19_rezero_store(struct device *dev, | ||
106 | struct device_attribute *attr, | ||
107 | const char *buf, size_t count); | ||
108 | static ssize_t rmi_f19_has_hysteresis_threshold_show(struct device *dev, | ||
109 | struct device_attribute *attr, char *buf); | ||
110 | static ssize_t rmi_f19_has_sensitivity_adjust_show(struct device *dev, | ||
111 | struct device_attribute *attr, char *buf); | ||
112 | static ssize_t rmi_f19_configurable_show(struct device *dev, | ||
113 | struct device_attribute *attr, char *buf); | ||
114 | static ssize_t rmi_f19_filter_mode_show(struct device *dev, | ||
115 | struct device_attribute *attr, | ||
116 | char *buf); | ||
117 | static ssize_t rmi_f19_filter_mode_store(struct device *dev, | ||
118 | struct device_attribute *attr, | ||
119 | const char *buf, size_t count); | ||
120 | static ssize_t rmi_f19_button_usage_show(struct device *dev, | ||
121 | struct device_attribute *attr, | ||
122 | char *buf); | ||
123 | static ssize_t rmi_f19_button_usage_store(struct device *dev, | ||
124 | struct device_attribute *attr, | ||
125 | const char *buf, size_t count); | ||
126 | static ssize_t rmi_f19_interrupt_enable_button_show(struct device *dev, | ||
127 | struct device_attribute *attr, | ||
128 | char *buf); | ||
129 | static ssize_t rmi_f19_interrupt_enable_button_store(struct device *dev, | ||
130 | struct device_attribute *attr, | ||
131 | const char *buf, size_t count); | ||
132 | static ssize_t rmi_f19_single_button_show(struct device *dev, | ||
133 | struct device_attribute *attr, | ||
134 | char *buf); | ||
135 | static ssize_t rmi_f19_single_button_store(struct device *dev, | ||
136 | struct device_attribute *attr, | ||
137 | const char *buf, size_t count); | ||
138 | static ssize_t rmi_f19_sensor_map_show(struct device *dev, | ||
139 | struct device_attribute *attr, | ||
140 | char *buf); | ||
141 | static ssize_t rmi_f19_sensor_map_store(struct device *dev, | ||
142 | struct device_attribute *attr, | ||
143 | const char *buf, size_t count); | ||
144 | static ssize_t rmi_f19_sensitivity_adjust_show(struct device *dev, | ||
145 | struct device_attribute *attr, | ||
146 | char *buf); | ||
147 | static ssize_t rmi_f19_sensitivity_adjust_store(struct device *dev, | ||
148 | struct device_attribute *attr, | ||
149 | const char *buf, size_t count); | ||
150 | static ssize_t rmi_f19_hysteresis_threshold_show(struct device *dev, | ||
151 | struct device_attribute *attr, | ||
152 | char *buf); | ||
153 | static ssize_t rmi_f19_hysteresis_threshold_store(struct device *dev, | ||
154 | struct device_attribute *attr, | ||
155 | const char *buf, size_t count); | ||
156 | |||
157 | |||
158 | static struct device_attribute attrs[] = { | ||
159 | __ATTR(button_count, RMI_RO_ATTR, | ||
160 | rmi_f19_button_count_show, rmi_store_error), | ||
161 | __ATTR(button_map, RMI_RW_ATTR, | ||
162 | rmi_f19_button_map_show, rmi_f19_button_map_store), | ||
163 | __ATTR(rezero, RMI_RW_ATTR, | ||
164 | rmi_f19_rezero_show, rmi_f19_rezero_store), | ||
165 | __ATTR(has_hysteresis_threshold, RMI_RO_ATTR, | ||
166 | rmi_f19_has_hysteresis_threshold_show, rmi_store_error), | ||
167 | __ATTR(has_sensitivity_adjust, RMI_RO_ATTR, | ||
168 | rmi_f19_has_sensitivity_adjust_show, rmi_store_error), | ||
169 | __ATTR(configurable, RMI_RO_ATTR, | ||
170 | rmi_f19_configurable_show, rmi_store_error), | ||
171 | __ATTR(filter_mode, RMI_RW_ATTR, | ||
172 | rmi_f19_filter_mode_show, rmi_f19_filter_mode_store), | ||
173 | __ATTR(button_usage, RMI_RW_ATTR, | ||
174 | rmi_f19_button_usage_show, rmi_f19_button_usage_store), | ||
175 | __ATTR(interrupt_enable_button, RMI_RW_ATTR, | ||
176 | rmi_f19_interrupt_enable_button_show, | ||
177 | rmi_f19_interrupt_enable_button_store), | ||
178 | __ATTR(single_button, RMI_RW_ATTR, | ||
179 | rmi_f19_single_button_show, rmi_f19_single_button_store), | ||
180 | __ATTR(sensor_map, RMI_RW_ATTR, | ||
181 | rmi_f19_sensor_map_show, rmi_f19_sensor_map_store), | ||
182 | __ATTR(sensitivity_adjust, RMI_RW_ATTR, | ||
183 | rmi_f19_sensitivity_adjust_show, | ||
184 | rmi_f19_sensitivity_adjust_store), | ||
185 | __ATTR(hysteresis_threshold, RMI_RW_ATTR, | ||
186 | rmi_f19_hysteresis_threshold_show, | ||
187 | rmi_f19_hysteresis_threshold_store) | ||
188 | }; | ||
189 | |||
190 | |||
191 | int rmi_f19_read_control_parameters(struct rmi_device *rmi_dev, | ||
192 | struct f19_0d_control *button_control, | ||
193 | unsigned char button_count, | ||
194 | unsigned char int_button_enabled_count, | ||
195 | u8 ctrl_base_addr) | ||
196 | { | ||
197 | int error = 0; | ||
198 | int i; | ||
199 | |||
200 | if (button_control->general_control) { | ||
201 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
202 | (u8 *)button_control->general_control, | ||
203 | sizeof(struct f19_0d_control_0)); | ||
204 | if (error < 0) { | ||
205 | dev_err(&rmi_dev->dev, | ||
206 | "Failed to read f19_0d_control_0, code:" | ||
207 | " %d.\n", error); | ||
208 | return error; | ||
209 | } | ||
210 | ctrl_base_addr = ctrl_base_addr + | ||
211 | sizeof(struct f19_0d_control_0); | ||
212 | } | ||
213 | |||
214 | if (button_control->button_int_enable) { | ||
215 | for (i = 0; i < int_button_enabled_count; i++) { | ||
216 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
217 | (u8 *)&button_control->button_int_enable[i], | ||
218 | sizeof(struct f19_0d_control_1)); | ||
219 | if (error < 0) { | ||
220 | dev_err(&rmi_dev->dev, | ||
221 | "Failed to read f19_0d_control_2," | ||
222 | " code: %d.\n", error); | ||
223 | return error; | ||
224 | } | ||
225 | ctrl_base_addr = ctrl_base_addr + | ||
226 | sizeof(struct f19_0d_control_1); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | if (button_control->single_button_participation) { | ||
231 | for (i = 0; i < int_button_enabled_count; i++) { | ||
232 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
233 | (u8 *)&button_control-> | ||
234 | single_button_participation[i], | ||
235 | sizeof(struct f19_0d_control_2)); | ||
236 | if (error < 0) { | ||
237 | dev_err(&rmi_dev->dev, | ||
238 | "Failed to read f19_0d_control_2," | ||
239 | " code: %d.\n", error); | ||
240 | return error; | ||
241 | } | ||
242 | ctrl_base_addr = ctrl_base_addr + | ||
243 | sizeof(struct f19_0d_control_2); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | if (button_control->sensor_map) { | ||
248 | for (i = 0; i < button_count; i++) { | ||
249 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
250 | (u8 *)&button_control->sensor_map[i], | ||
251 | sizeof(struct f19_0d_control_3_4)); | ||
252 | if (error < 0) { | ||
253 | dev_err(&rmi_dev->dev, | ||
254 | "Failed to read f19_0d_control_3_4," | ||
255 | " code: %d.\n", error); | ||
256 | return error; | ||
257 | } | ||
258 | ctrl_base_addr = ctrl_base_addr + | ||
259 | sizeof(struct f19_0d_control_3_4); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | if (button_control->all_button_sensitivity_adj) { | ||
264 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
265 | (u8 *)button_control-> | ||
266 | all_button_sensitivity_adj, | ||
267 | sizeof(struct f19_0d_control_5)); | ||
268 | if (error < 0) { | ||
269 | dev_err(&rmi_dev->dev, | ||
270 | "Failed to read f19_0d_control_5," | ||
271 | " code: %d.\n", error); | ||
272 | return error; | ||
273 | } | ||
274 | ctrl_base_addr = ctrl_base_addr + | ||
275 | sizeof(struct f19_0d_control_5); | ||
276 | } | ||
277 | |||
278 | if (button_control->all_button_hysteresis_threshold) { | ||
279 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
280 | (u8 *)button_control-> | ||
281 | all_button_hysteresis_threshold, | ||
282 | sizeof(struct f19_0d_control_6)); | ||
283 | if (error < 0) { | ||
284 | dev_err(&rmi_dev->dev, | ||
285 | "Failed to read f19_0d_control_6," | ||
286 | " code: %d.\n", error); | ||
287 | return error; | ||
288 | } | ||
289 | ctrl_base_addr = ctrl_base_addr + | ||
290 | sizeof(struct f19_0d_control_6); | ||
291 | } | ||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | |||
296 | int rmi_f19_initialize_control_parameters(struct rmi_device *rmi_dev, | ||
297 | struct f19_0d_control *button_control, | ||
298 | unsigned char button_count, | ||
299 | unsigned char int_button_enabled_count, | ||
300 | int control_base_addr) | ||
301 | { | ||
302 | int error = 0; | ||
303 | |||
304 | button_control->general_control = | ||
305 | kzalloc(sizeof(struct f19_0d_control_0), GFP_KERNEL); | ||
306 | if (!button_control->general_control) { | ||
307 | dev_err(&rmi_dev->dev, "Failed to allocate" | ||
308 | " f19_0d_control_0.\n"); | ||
309 | error = -ENOMEM; | ||
310 | goto error_exit; | ||
311 | } | ||
312 | |||
313 | button_control->button_int_enable = | ||
314 | kzalloc(int_button_enabled_count * | ||
315 | sizeof(struct f19_0d_control_2), GFP_KERNEL); | ||
316 | if (!button_control->button_int_enable) { | ||
317 | dev_err(&rmi_dev->dev, "Failed to allocate f19_0d_control_1.\n"); | ||
318 | error = -ENOMEM; | ||
319 | goto error_exit; | ||
320 | } | ||
321 | |||
322 | button_control->single_button_participation = | ||
323 | kzalloc(int_button_enabled_count * | ||
324 | sizeof(struct f19_0d_control_2), GFP_KERNEL); | ||
325 | if (!button_control->single_button_participation) { | ||
326 | dev_err(&rmi_dev->dev, "Failed to allocate" | ||
327 | " f19_0d_control_2.\n"); | ||
328 | error = -ENOMEM; | ||
329 | goto error_exit; | ||
330 | } | ||
331 | |||
332 | button_control->sensor_map = | ||
333 | kzalloc(button_count * | ||
334 | sizeof(struct f19_0d_control_3_4), GFP_KERNEL); | ||
335 | if (!button_control->sensor_map) { | ||
336 | dev_err(&rmi_dev->dev, "Failed to allocate" | ||
337 | " f19_0d_control_3_4.\n"); | ||
338 | error = -ENOMEM; | ||
339 | goto error_exit; | ||
340 | } | ||
341 | |||
342 | button_control->all_button_sensitivity_adj = | ||
343 | kzalloc(sizeof(struct f19_0d_control_5), GFP_KERNEL); | ||
344 | if (!button_control->all_button_sensitivity_adj) { | ||
345 | dev_err(&rmi_dev->dev, "Failed to allocate" | ||
346 | " f19_0d_control_5.\n"); | ||
347 | error = -ENOMEM; | ||
348 | goto error_exit; | ||
349 | } | ||
350 | |||
351 | button_control->all_button_hysteresis_threshold = | ||
352 | kzalloc(sizeof(struct f19_0d_control_6), GFP_KERNEL); | ||
353 | if (!button_control->all_button_hysteresis_threshold) { | ||
354 | dev_err(&rmi_dev->dev, "Failed to allocate" | ||
355 | " f19_0d_control_6.\n"); | ||
356 | error = -ENOMEM; | ||
357 | goto error_exit; | ||
358 | } | ||
359 | return rmi_f19_read_control_parameters(rmi_dev, button_control, | ||
360 | button_count, int_button_enabled_count, control_base_addr); | ||
361 | |||
362 | error_exit: | ||
363 | kfree(button_control->general_control); | ||
364 | kfree(button_control->button_int_enable); | ||
365 | kfree(button_control->single_button_participation); | ||
366 | kfree(button_control->sensor_map); | ||
367 | kfree(button_control->all_button_sensitivity_adj); | ||
368 | kfree(button_control->all_button_hysteresis_threshold); | ||
369 | return error; | ||
370 | } | ||
371 | |||
372 | static int rmi_f19_init(struct rmi_function_container *fc) | ||
373 | { | ||
374 | struct rmi_device *rmi_dev = fc->rmi_dev; | ||
375 | struct rmi_device_platform_data *pdata; | ||
376 | struct f19_data *f19; | ||
377 | struct input_dev *input_dev; | ||
378 | u8 query_base_addr; | ||
379 | int rc; | ||
380 | int i; | ||
381 | int attr_count = 0; | ||
382 | |||
383 | dev_info(&fc->dev, "Intializing F19 values."); | ||
384 | |||
385 | f19 = kzalloc(sizeof(struct f19_data), GFP_KERNEL); | ||
386 | if (!f19) { | ||
387 | dev_err(&fc->dev, "Failed to allocate function data.\n"); | ||
388 | return -ENOMEM; | ||
389 | } | ||
390 | pdata = to_rmi_platform_data(rmi_dev); | ||
391 | query_base_addr = fc->fd.query_base_addr; | ||
392 | |||
393 | /* initial all default values for f19 data here */ | ||
394 | rc = rmi_read(rmi_dev, fc->fd.command_base_addr, | ||
395 | (u8 *)&f19->button_rezero); | ||
396 | if (rc < 0) { | ||
397 | dev_err(&fc->dev, "Failed to read command register.\n"); | ||
398 | goto err_free_data; | ||
399 | } | ||
400 | |||
401 | f19->button_rezero = f19->button_rezero & 1; | ||
402 | |||
403 | rc = rmi_read_block(rmi_dev, query_base_addr, (u8 *)&f19->button_query, | ||
404 | sizeof(struct f19_0d_query)); | ||
405 | f19->button_count = f19->button_query.f19_0d_query1; | ||
406 | |||
407 | if (rc < 0) { | ||
408 | dev_err(&fc->dev, "Failed to read query register.\n"); | ||
409 | goto err_free_data; | ||
410 | } | ||
411 | |||
412 | |||
413 | /* Figure out just how much data we'll need to read. */ | ||
414 | f19->button_down = kcalloc(f19->button_count, | ||
415 | sizeof(bool), GFP_KERNEL); | ||
416 | if (!f19->button_down) { | ||
417 | dev_err(&fc->dev, "Failed to allocate button state buffer.\n"); | ||
418 | rc = -ENOMEM; | ||
419 | goto err_free_data; | ||
420 | } | ||
421 | |||
422 | f19->button_data_buffer_size = (f19->button_count + 7) / 8; | ||
423 | f19->button_data_buffer = | ||
424 | kcalloc(f19->button_data_buffer_size, | ||
425 | sizeof(unsigned char), GFP_KERNEL); | ||
426 | if (!f19->button_data_buffer) { | ||
427 | dev_err(&fc->dev, "Failed to allocate button data buffer.\n"); | ||
428 | rc = -ENOMEM; | ||
429 | goto err_free_data; | ||
430 | } | ||
431 | |||
432 | f19->button_map = kcalloc(f19->button_count, | ||
433 | sizeof(unsigned char), GFP_KERNEL); | ||
434 | if (!f19->button_map) { | ||
435 | dev_err(&fc->dev, "Failed to allocate button map.\n"); | ||
436 | rc = -ENOMEM; | ||
437 | goto err_free_data; | ||
438 | } | ||
439 | |||
440 | if (pdata) { | ||
441 | if (pdata->button_map->nbuttons != f19->button_count) { | ||
442 | dev_warn(&fc->dev, | ||
443 | "Platformdata button map size (%d) != number " | ||
444 | "of buttons on device (%d) - ignored.\n", | ||
445 | pdata->button_map->nbuttons, | ||
446 | f19->button_count); | ||
447 | } else if (!pdata->button_map->map) { | ||
448 | dev_warn(&fc->dev, | ||
449 | "Platformdata button map is missing!\n"); | ||
450 | } else { | ||
451 | for (i = 0; i < pdata->button_map->nbuttons; i++) | ||
452 | f19->button_map[i] = pdata->button_map->map[i]; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | f19->button_control = kzalloc(sizeof(struct f19_0d_control), | ||
457 | GFP_KERNEL); | ||
458 | |||
459 | rc = rmi_f19_initialize_control_parameters(fc->rmi_dev, | ||
460 | f19->button_control, f19->button_count, | ||
461 | f19->button_data_buffer_size, fc->fd.control_base_addr); | ||
462 | if (rc < 0) { | ||
463 | dev_err(&fc->dev, | ||
464 | "Failed to initialize F19 control params.\n"); | ||
465 | goto err_free_data; | ||
466 | } | ||
467 | |||
468 | input_dev = input_allocate_device(); | ||
469 | if (!input_dev) { | ||
470 | dev_err(&fc->dev, "Failed to allocate input device.\n"); | ||
471 | rc = -ENOMEM; | ||
472 | goto err_free_data; | ||
473 | } | ||
474 | |||
475 | f19->input = input_dev; | ||
476 | snprintf(f19->input_name, MAX_LEN, "%sfn%02x", dev_name(&rmi_dev->dev), | ||
477 | fc->fd.function_number); | ||
478 | input_dev->name = f19->input_name; | ||
479 | snprintf(f19->input_phys, MAX_LEN, "%s/input0", input_dev->name); | ||
480 | input_dev->phys = f19->input_phys; | ||
481 | input_dev->dev.parent = &rmi_dev->dev; | ||
482 | input_set_drvdata(input_dev, f19); | ||
483 | |||
484 | /* Set up any input events. */ | ||
485 | set_bit(EV_SYN, input_dev->evbit); | ||
486 | set_bit(EV_KEY, input_dev->evbit); | ||
487 | /* set bits for each button... */ | ||
488 | for (i = 0; i < f19->button_count; i++) | ||
489 | set_bit(f19->button_map[i], input_dev->keybit); | ||
490 | rc = input_register_device(input_dev); | ||
491 | if (rc < 0) { | ||
492 | dev_err(&fc->dev, "Failed to register input device.\n"); | ||
493 | goto err_free_input; | ||
494 | } | ||
495 | |||
496 | dev_dbg(&fc->dev, "Creating sysfs files.\n"); | ||
497 | /* Set up sysfs device attributes. */ | ||
498 | for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { | ||
499 | if (sysfs_create_file | ||
500 | (&fc->dev.kobj, &attrs[attr_count].attr) < 0) { | ||
501 | dev_err(&fc->dev, | ||
502 | "Failed to create sysfs file for %s.", | ||
503 | attrs[attr_count].attr.name); | ||
504 | rc = -ENODEV; | ||
505 | goto err_free_data; | ||
506 | } | ||
507 | } | ||
508 | fc->data = f19; | ||
509 | return 0; | ||
510 | |||
511 | err_free_input: | ||
512 | input_free_device(f19->input); | ||
513 | |||
514 | err_free_data: | ||
515 | if (f19) { | ||
516 | kfree(f19->button_down); | ||
517 | kfree(f19->button_data_buffer); | ||
518 | kfree(f19->button_map); | ||
519 | } | ||
520 | kfree(f19); | ||
521 | for (attr_count--; attr_count >= 0; attr_count--) | ||
522 | sysfs_remove_file(&fc->dev.kobj, | ||
523 | &attrs[attr_count].attr); | ||
524 | return rc; | ||
525 | } | ||
526 | |||
527 | int rmi_f19_attention(struct rmi_function_container *fc, u8 *irq_bits) | ||
528 | { | ||
529 | struct rmi_device *rmi_dev = fc->rmi_dev; | ||
530 | struct f19_data *f19 = fc->data; | ||
531 | u8 data_base_addr = fc->fd.data_base_addr; | ||
532 | int error; | ||
533 | int button; | ||
534 | |||
535 | /* Read the button data. */ | ||
536 | |||
537 | error = rmi_read_block(rmi_dev, data_base_addr, f19->button_data_buffer, | ||
538 | f19->button_data_buffer_size); | ||
539 | if (error < 0) { | ||
540 | dev_err(&fc->dev, "%s: Failed to read button data registers.\n", | ||
541 | __func__); | ||
542 | return error; | ||
543 | } | ||
544 | |||
545 | /* Generate events for buttons that change state. */ | ||
546 | for (button = 0; button < f19->button_count; | ||
547 | button++) { | ||
548 | int button_reg; | ||
549 | int button_shift; | ||
550 | bool button_status; | ||
551 | |||
552 | /* determine which data byte the button status is in */ | ||
553 | button_reg = button / 7; | ||
554 | /* bit shift to get button's status */ | ||
555 | button_shift = button % 8; | ||
556 | button_status = | ||
557 | ((f19->button_data_buffer[button_reg] >> button_shift) | ||
558 | & 0x01) != 0; | ||
559 | |||
560 | /* if the button state changed from the last time report it | ||
561 | * and store the new state */ | ||
562 | if (button_status != f19->button_down[button]) { | ||
563 | dev_dbg(&fc->dev, "%s: Button %d (code %d) -> %d.\n", | ||
564 | __func__, button, f19->button_map[button], | ||
565 | button_status); | ||
566 | /* Generate an event here. */ | ||
567 | input_report_key(f19->input, f19->button_map[button], | ||
568 | button_status); | ||
569 | f19->button_down[button] = button_status; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | input_sync(f19->input); /* sync after groups of events */ | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static void rmi_f19_remove(struct rmi_function_container *fc) | ||
578 | { | ||
579 | struct f19_data *data = fc->data; | ||
580 | if (data) { | ||
581 | kfree(data->button_down); | ||
582 | kfree(data->button_data_buffer); | ||
583 | kfree(data->button_map); | ||
584 | input_unregister_device(data->input); | ||
585 | if (data->button_control) { | ||
586 | kfree(data->button_control->general_control); | ||
587 | kfree(data->button_control->button_int_enable); | ||
588 | kfree(data->button_control-> | ||
589 | single_button_participation); | ||
590 | kfree(data->button_control->sensor_map); | ||
591 | kfree(data->button_control-> | ||
592 | all_button_sensitivity_adj); | ||
593 | kfree(data->button_control-> | ||
594 | all_button_hysteresis_threshold); | ||
595 | } | ||
596 | kfree(data->button_control); | ||
597 | } | ||
598 | kfree(fc->data); | ||
599 | } | ||
600 | |||
601 | static struct rmi_function_handler function_handler = { | ||
602 | .func = 0x19, | ||
603 | .init = rmi_f19_init, | ||
604 | .attention = rmi_f19_attention, | ||
605 | .remove = rmi_f19_remove | ||
606 | }; | ||
607 | |||
608 | static int __init rmi_f19_module_init(void) | ||
609 | { | ||
610 | int error; | ||
611 | |||
612 | error = rmi_register_function_driver(&function_handler); | ||
613 | if (error < 0) { | ||
614 | pr_err("%s: register failed!\n", __func__); | ||
615 | return error; | ||
616 | } | ||
617 | |||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | static void rmi_f19_module_exit(void) | ||
622 | { | ||
623 | rmi_unregister_function_driver(&function_handler); | ||
624 | } | ||
625 | |||
626 | static ssize_t rmi_f19_filter_mode_show(struct device *dev, | ||
627 | struct device_attribute *attr, | ||
628 | char *buf) | ||
629 | { | ||
630 | struct rmi_function_container *fc; | ||
631 | struct f19_data *data; | ||
632 | |||
633 | fc = to_rmi_function_container(dev); | ||
634 | data = fc->data; | ||
635 | |||
636 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
637 | data->button_control->general_control->filter_mode); | ||
638 | |||
639 | } | ||
640 | |||
641 | static ssize_t rmi_f19_filter_mode_store(struct device *dev, | ||
642 | struct device_attribute *attr, | ||
643 | const char *buf, size_t count) | ||
644 | { | ||
645 | struct rmi_function_container *fc; | ||
646 | struct f19_data *data; | ||
647 | unsigned int new_value; | ||
648 | int result; | ||
649 | |||
650 | fc = to_rmi_function_container(dev); | ||
651 | data = fc->data; | ||
652 | if (sscanf(buf, "%u", &new_value) != 1) { | ||
653 | dev_err(dev, | ||
654 | "%s: Error - filter_mode_store has an " | ||
655 | "invalid len.\n", | ||
656 | __func__); | ||
657 | return -EINVAL; | ||
658 | } | ||
659 | |||
660 | if (new_value < 0 || new_value > 4) { | ||
661 | dev_err(dev, "%s: Error - filter_mode_store has an " | ||
662 | "invalid value %d.\n", | ||
663 | __func__, new_value); | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | data->button_control->general_control->filter_mode = new_value; | ||
667 | result = rmi_write_block(fc->rmi_dev, fc->fd.control_base_addr, | ||
668 | (u8 *)data->button_control->general_control, | ||
669 | sizeof(struct f19_0d_control_0)); | ||
670 | if (result < 0) { | ||
671 | dev_err(dev, "%s : Could not write filter_mode_store to 0x%x\n", | ||
672 | __func__, fc->fd.control_base_addr); | ||
673 | return result; | ||
674 | } | ||
675 | |||
676 | return count; | ||
677 | } | ||
678 | |||
679 | static ssize_t rmi_f19_button_usage_show(struct device *dev, | ||
680 | struct device_attribute *attr, | ||
681 | char *buf) | ||
682 | { | ||
683 | struct rmi_function_container *fc; | ||
684 | struct f19_data *data; | ||
685 | |||
686 | fc = to_rmi_function_container(dev); | ||
687 | data = fc->data; | ||
688 | |||
689 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
690 | data->button_control->general_control->button_usage); | ||
691 | |||
692 | } | ||
693 | |||
694 | static ssize_t rmi_f19_button_usage_store(struct device *dev, | ||
695 | struct device_attribute *attr, | ||
696 | const char *buf, size_t count) | ||
697 | { | ||
698 | struct rmi_function_container *fc; | ||
699 | struct f19_data *data; | ||
700 | unsigned int new_value; | ||
701 | int result; | ||
702 | |||
703 | fc = to_rmi_function_container(dev); | ||
704 | data = fc->data; | ||
705 | if (sscanf(buf, "%u", &new_value) != 1) { | ||
706 | dev_err(dev, | ||
707 | "%s: Error - button_usage_store has an " | ||
708 | "invalid len.\n", | ||
709 | __func__); | ||
710 | return -EINVAL; | ||
711 | } | ||
712 | |||
713 | if (new_value < 0 || new_value > 4) { | ||
714 | dev_err(dev, "%s: Error - button_usage_store has an " | ||
715 | "invalid value %d.\n", | ||
716 | __func__, new_value); | ||
717 | return -EINVAL; | ||
718 | } | ||
719 | data->button_control->general_control->button_usage = new_value; | ||
720 | result = rmi_write_block(fc->rmi_dev, fc->fd.control_base_addr, | ||
721 | (u8 *)data->button_control->general_control, | ||
722 | sizeof(struct f19_0d_control_0)); | ||
723 | if (result < 0) { | ||
724 | dev_err(dev, "%s : Could not write button_usage_store to 0x%x\n", | ||
725 | __func__, fc->fd.control_base_addr); | ||
726 | return result; | ||
727 | } | ||
728 | |||
729 | return count; | ||
730 | |||
731 | } | ||
732 | |||
733 | static ssize_t rmi_f19_interrupt_enable_button_show(struct device *dev, | ||
734 | struct device_attribute *attr, | ||
735 | char *buf) | ||
736 | { | ||
737 | struct rmi_function_container *fc; | ||
738 | struct f19_data *data; | ||
739 | int i, len, total_len = 0; | ||
740 | char *current_buf = buf; | ||
741 | |||
742 | fc = to_rmi_function_container(dev); | ||
743 | data = fc->data; | ||
744 | /* loop through each button map value and copy its | ||
745 | * string representation into buf */ | ||
746 | for (i = 0; i < data->button_count; i++) { | ||
747 | int button_reg; | ||
748 | int button_shift; | ||
749 | int interrupt_button; | ||
750 | |||
751 | button_reg = i / 7; | ||
752 | button_shift = i % 8; | ||
753 | interrupt_button = | ||
754 | ((data->button_control-> | ||
755 | button_int_enable[button_reg].int_enabled_button >> | ||
756 | button_shift) & 0x01); | ||
757 | |||
758 | /* get next button mapping value and write it to buf */ | ||
759 | len = snprintf(current_buf, PAGE_SIZE - total_len, | ||
760 | "%u ", interrupt_button); | ||
761 | /* bump up ptr to next location in buf if the | ||
762 | * snprintf was valid. Otherwise issue an error | ||
763 | * and return. */ | ||
764 | if (len > 0) { | ||
765 | current_buf += len; | ||
766 | total_len += len; | ||
767 | } else { | ||
768 | dev_err(dev, "%s: Failed to build interrupt button" | ||
769 | " buffer, code = %d.\n", __func__, len); | ||
770 | return snprintf(buf, PAGE_SIZE, "unknown\n"); | ||
771 | } | ||
772 | } | ||
773 | len = snprintf(current_buf, PAGE_SIZE - total_len, "\n"); | ||
774 | if (len > 0) | ||
775 | total_len += len; | ||
776 | else | ||
777 | dev_warn(dev, "%s: Failed to append carriage return.\n", | ||
778 | __func__); | ||
779 | return total_len; | ||
780 | |||
781 | } | ||
782 | |||
783 | static ssize_t rmi_f19_interrupt_enable_button_store(struct device *dev, | ||
784 | struct device_attribute *attr, | ||
785 | const char *buf, size_t count) | ||
786 | { | ||
787 | struct rmi_function_container *fc; | ||
788 | struct f19_data *data; | ||
789 | int i; | ||
790 | int button_count = 0; | ||
791 | int retval = count; | ||
792 | int button_reg = 0; | ||
793 | int ctrl_bass_addr; | ||
794 | |||
795 | fc = to_rmi_function_container(dev); | ||
796 | data = fc->data; | ||
797 | for (i = 0; i < data->button_count && *buf != 0; | ||
798 | i++) { | ||
799 | int button_shift; | ||
800 | int button; | ||
801 | |||
802 | button_reg = i / 7; | ||
803 | button_shift = i % 8; | ||
804 | /* get next button mapping value and store and bump up to | ||
805 | * point to next item in buf */ | ||
806 | sscanf(buf, "%u", &button); | ||
807 | |||
808 | if (button != 0 && button != 1) { | ||
809 | dev_err(dev, | ||
810 | "%s: Error - interrupt enable button for" | ||
811 | " button %d is not a valid value 0x%x.\n", | ||
812 | __func__, i, button); | ||
813 | return -EINVAL; | ||
814 | } | ||
815 | |||
816 | if (button_shift == 0) | ||
817 | data->button_control->button_int_enable[button_reg]. | ||
818 | int_enabled_button = 0; | ||
819 | data->button_control->button_int_enable[button_reg]. | ||
820 | int_enabled_button |= (button << button_shift); | ||
821 | button_count++; | ||
822 | /* bump up buf to point to next item to read */ | ||
823 | while (*buf != 0) { | ||
824 | buf++; | ||
825 | if (*(buf - 1) == ' ') | ||
826 | break; | ||
827 | } | ||
828 | } | ||
829 | |||
830 | /* Make sure the button count matches */ | ||
831 | if (button_count != data->button_count) { | ||
832 | dev_err(dev, | ||
833 | "%s: Error - interrupt enable button count of %d" | ||
834 | " doesn't match device button count of %d.\n", | ||
835 | __func__, button_count, data->button_count); | ||
836 | return -EINVAL; | ||
837 | } | ||
838 | |||
839 | /* write back to the control register */ | ||
840 | ctrl_bass_addr = fc->fd.control_base_addr + | ||
841 | sizeof(struct f19_0d_control_0); | ||
842 | retval = rmi_write_block(fc->rmi_dev, ctrl_bass_addr, | ||
843 | (u8 *)data->button_control->button_int_enable, | ||
844 | sizeof(struct f19_0d_control_1)*(button_reg + 1)); | ||
845 | if (retval < 0) { | ||
846 | dev_err(dev, "%s : Could not write interrupt_enable_store" | ||
847 | " to 0x%x\n", __func__, ctrl_bass_addr); | ||
848 | return retval; | ||
849 | } | ||
850 | |||
851 | return count; | ||
852 | } | ||
853 | |||
854 | static ssize_t rmi_f19_single_button_show(struct device *dev, | ||
855 | struct device_attribute *attr, | ||
856 | char *buf) | ||
857 | { | ||
858 | struct rmi_function_container *fc; | ||
859 | struct f19_data *data; | ||
860 | int i, len, total_len = 0; | ||
861 | char *current_buf = buf; | ||
862 | |||
863 | fc = to_rmi_function_container(dev); | ||
864 | data = fc->data; | ||
865 | /* loop through each button map value and copy its | ||
866 | * string representation into buf */ | ||
867 | for (i = 0; i < data->button_count; i++) { | ||
868 | int button_reg; | ||
869 | int button_shift; | ||
870 | int single_button; | ||
871 | |||
872 | button_reg = i / 7; | ||
873 | button_shift = i % 8; | ||
874 | single_button = ((data->button_control-> | ||
875 | single_button_participation[button_reg].single_button | ||
876 | >> button_shift) & 0x01); | ||
877 | |||
878 | /* get next button mapping value and write it to buf */ | ||
879 | len = snprintf(current_buf, PAGE_SIZE - total_len, | ||
880 | "%u ", single_button); | ||
881 | /* bump up ptr to next location in buf if the | ||
882 | * snprintf was valid. Otherwise issue an error | ||
883 | * and return. */ | ||
884 | if (len > 0) { | ||
885 | current_buf += len; | ||
886 | total_len += len; | ||
887 | } else { | ||
888 | dev_err(dev, "%s: Failed to build signle button buffer" | ||
889 | ", code = %d.\n", __func__, len); | ||
890 | return snprintf(buf, PAGE_SIZE, "unknown\n"); | ||
891 | } | ||
892 | } | ||
893 | len = snprintf(current_buf, PAGE_SIZE - total_len, "\n"); | ||
894 | if (len > 0) | ||
895 | total_len += len; | ||
896 | else | ||
897 | dev_warn(dev, "%s: Failed to append carriage return.\n", | ||
898 | __func__); | ||
899 | |||
900 | return total_len; | ||
901 | |||
902 | } | ||
903 | |||
904 | static ssize_t rmi_f19_single_button_store(struct device *dev, | ||
905 | struct device_attribute *attr, | ||
906 | const char *buf, size_t count) | ||
907 | { | ||
908 | struct rmi_function_container *fc; | ||
909 | struct f19_data *data; | ||
910 | int i; | ||
911 | int button_count = 0; | ||
912 | int retval = count; | ||
913 | int ctrl_bass_addr; | ||
914 | int button_reg = 0; | ||
915 | |||
916 | fc = to_rmi_function_container(dev); | ||
917 | data = fc->data; | ||
918 | for (i = 0; i < data->button_count && *buf != 0; | ||
919 | i++) { | ||
920 | int button_shift; | ||
921 | int button; | ||
922 | |||
923 | button_reg = i / 7; | ||
924 | button_shift = i % 8; | ||
925 | /* get next button mapping value and store and bump up to | ||
926 | * point to next item in buf */ | ||
927 | sscanf(buf, "%u", &button); | ||
928 | |||
929 | if (button != 0 && button != 1) { | ||
930 | dev_err(dev, | ||
931 | "%s: Error - single button for button %d" | ||
932 | " is not a valid value 0x%x.\n", | ||
933 | __func__, i, button); | ||
934 | return -EINVAL; | ||
935 | } | ||
936 | if (button_shift == 0) | ||
937 | data->button_control-> | ||
938 | single_button_participation[button_reg]. | ||
939 | single_button = 0; | ||
940 | data->button_control->single_button_participation[button_reg]. | ||
941 | single_button |= (button << button_shift); | ||
942 | button_count++; | ||
943 | /* bump up buf to point to next item to read */ | ||
944 | while (*buf != 0) { | ||
945 | buf++; | ||
946 | if (*(buf - 1) == ' ') | ||
947 | break; | ||
948 | } | ||
949 | } | ||
950 | |||
951 | /* Make sure the button count matches */ | ||
952 | if (button_count != data->button_count) { | ||
953 | dev_err(dev, | ||
954 | "%s: Error - single button count of %d doesn't match" | ||
955 | " device button count of %d.\n", __func__, button_count, | ||
956 | data->button_count); | ||
957 | return -EINVAL; | ||
958 | } | ||
959 | /* write back to the control register */ | ||
960 | ctrl_bass_addr = fc->fd.control_base_addr + | ||
961 | sizeof(struct f19_0d_control_0) + | ||
962 | sizeof(struct f19_0d_control_2)*(button_reg + 1); | ||
963 | retval = rmi_write_block(fc->rmi_dev, ctrl_bass_addr, | ||
964 | (u8 *)data->button_control->single_button_participation, | ||
965 | sizeof(struct f19_0d_control_2)*(button_reg + 1)); | ||
966 | if (retval < 0) { | ||
967 | dev_err(dev, "%s : Could not write interrupt_enable_store to" | ||
968 | " 0x%x\n", __func__, ctrl_bass_addr); | ||
969 | return -EINVAL; | ||
970 | } | ||
971 | return count; | ||
972 | } | ||
973 | |||
974 | static ssize_t rmi_f19_sensor_map_show(struct device *dev, | ||
975 | struct device_attribute *attr, | ||
976 | char *buf) | ||
977 | { | ||
978 | struct rmi_function_container *fc; | ||
979 | struct f19_data *data; | ||
980 | int i, len, total_len = 0; | ||
981 | char *current_buf = buf; | ||
982 | |||
983 | fc = to_rmi_function_container(dev); | ||
984 | data = fc->data; | ||
985 | |||
986 | for (i = 0; i < data->button_count; i++) { | ||
987 | len = snprintf(current_buf, PAGE_SIZE - total_len, | ||
988 | "%u ", data->button_control->sensor_map[i]. | ||
989 | sensor_map_button); | ||
990 | /* bump up ptr to next location in buf if the | ||
991 | * snprintf was valid. Otherwise issue an error | ||
992 | * and return. */ | ||
993 | if (len > 0) { | ||
994 | current_buf += len; | ||
995 | total_len += len; | ||
996 | } else { | ||
997 | dev_err(dev, "%s: Failed to build sensor map buffer, " | ||
998 | "code = %d.\n", __func__, len); | ||
999 | return snprintf(buf, PAGE_SIZE, "unknown\n"); | ||
1000 | } | ||
1001 | } | ||
1002 | len = snprintf(current_buf, PAGE_SIZE - total_len, "\n"); | ||
1003 | if (len > 0) | ||
1004 | total_len += len; | ||
1005 | else | ||
1006 | dev_warn(dev, "%s: Failed to append carriage return.\n", | ||
1007 | __func__); | ||
1008 | return total_len; | ||
1009 | |||
1010 | |||
1011 | } | ||
1012 | |||
1013 | static ssize_t rmi_f19_sensor_map_store(struct device *dev, | ||
1014 | struct device_attribute *attr, | ||
1015 | const char *buf, size_t count) | ||
1016 | { | ||
1017 | struct rmi_function_container *fc; | ||
1018 | struct f19_data *data; | ||
1019 | int sensor_map; | ||
1020 | int i; | ||
1021 | int retval = count; | ||
1022 | int button_count = 0; | ||
1023 | int ctrl_bass_addr; | ||
1024 | int button_reg; | ||
1025 | fc = to_rmi_function_container(dev); | ||
1026 | data = fc->data; | ||
1027 | |||
1028 | if (data->button_query.configurable == 0) { | ||
1029 | dev_err(dev, | ||
1030 | "%s: Error - sensor map is not configuralbe at" | ||
1031 | " run-time", __func__); | ||
1032 | return -EINVAL; | ||
1033 | } | ||
1034 | |||
1035 | for (i = 0; i < data->button_count && *buf != 0; i++) { | ||
1036 | /* get next button mapping value and store and bump up to | ||
1037 | * point to next item in buf */ | ||
1038 | sscanf(buf, "%u", &sensor_map); | ||
1039 | |||
1040 | /* Make sure the key is a valid key */ | ||
1041 | if (sensor_map < 0 || sensor_map > 127) { | ||
1042 | dev_err(dev, | ||
1043 | "%s: Error - sensor map for button %d is" | ||
1044 | " not a valid value 0x%x.\n", | ||
1045 | __func__, i, sensor_map); | ||
1046 | return -EINVAL; | ||
1047 | } | ||
1048 | |||
1049 | data->button_control->sensor_map[i].sensor_map_button = | ||
1050 | sensor_map; | ||
1051 | button_count++; | ||
1052 | |||
1053 | /* bump up buf to point to next item to read */ | ||
1054 | while (*buf != 0) { | ||
1055 | buf++; | ||
1056 | if (*(buf - 1) == ' ') | ||
1057 | break; | ||
1058 | } | ||
1059 | } | ||
1060 | |||
1061 | if (button_count != data->button_count) { | ||
1062 | dev_err(dev, | ||
1063 | "%s: Error - button map count of %d doesn't match device " | ||
1064 | "button count of %d.\n", __func__, button_count, | ||
1065 | data->button_count); | ||
1066 | return -EINVAL; | ||
1067 | } | ||
1068 | |||
1069 | /* write back to the control register */ | ||
1070 | button_reg = (button_count / 7) + 1; | ||
1071 | ctrl_bass_addr = fc->fd.control_base_addr + | ||
1072 | sizeof(struct f19_0d_control_0) + | ||
1073 | sizeof(struct f19_0d_control_1)*button_reg + | ||
1074 | sizeof(struct f19_0d_control_2)*button_reg; | ||
1075 | retval = rmi_write_block(fc->rmi_dev, ctrl_bass_addr, | ||
1076 | (u8 *)data->button_control->sensor_map, | ||
1077 | sizeof(struct f19_0d_control_3_4)*button_count); | ||
1078 | if (retval < 0) { | ||
1079 | dev_err(dev, "%s : Could not sensor_map_store to 0x%x\n", | ||
1080 | __func__, ctrl_bass_addr); | ||
1081 | return -EINVAL; | ||
1082 | } | ||
1083 | return count; | ||
1084 | } | ||
1085 | |||
1086 | static ssize_t rmi_f19_sensitivity_adjust_show(struct device *dev, | ||
1087 | struct device_attribute *attr, | ||
1088 | char *buf) | ||
1089 | { | ||
1090 | struct rmi_function_container *fc; | ||
1091 | struct f19_data *data; | ||
1092 | |||
1093 | fc = to_rmi_function_container(dev); | ||
1094 | data = fc->data; | ||
1095 | |||
1096 | return snprintf(buf, PAGE_SIZE, "%u\n", data->button_control-> | ||
1097 | all_button_sensitivity_adj->sensitivity_adj); | ||
1098 | |||
1099 | } | ||
1100 | |||
1101 | static ssize_t rmi_f19_sensitivity_adjust_store(struct device *dev, | ||
1102 | struct device_attribute *attr, | ||
1103 | const char *buf, size_t count) | ||
1104 | { | ||
1105 | struct rmi_function_container *fc; | ||
1106 | struct f19_data *data; | ||
1107 | unsigned int new_value; | ||
1108 | int len; | ||
1109 | int ctrl_bass_addr; | ||
1110 | int button_reg; | ||
1111 | |||
1112 | fc = to_rmi_function_container(dev); | ||
1113 | |||
1114 | data = fc->data; | ||
1115 | |||
1116 | if (data->button_query.configurable == 0) { | ||
1117 | dev_err(dev, | ||
1118 | "%s: Error - sensitivity_adjust is not" | ||
1119 | " configuralbe at run-time", __func__); | ||
1120 | return -EINVAL; | ||
1121 | } | ||
1122 | |||
1123 | len = sscanf(buf, "%u", &new_value); | ||
1124 | if (new_value < 0 || new_value > 31) | ||
1125 | return -EINVAL; | ||
1126 | |||
1127 | data->button_control->all_button_sensitivity_adj->sensitivity_adj = | ||
1128 | new_value; | ||
1129 | /* write back to the control register */ | ||
1130 | button_reg = (data->button_count / 7) + 1; | ||
1131 | ctrl_bass_addr = fc->fd.control_base_addr + | ||
1132 | sizeof(struct f19_0d_control_0) + | ||
1133 | sizeof(struct f19_0d_control_1)*button_reg + | ||
1134 | sizeof(struct f19_0d_control_2)*button_reg + | ||
1135 | sizeof(struct f19_0d_control_3_4)*data->button_count; | ||
1136 | len = rmi_write_block(fc->rmi_dev, ctrl_bass_addr, | ||
1137 | (u8 *)data->button_control->all_button_sensitivity_adj, | ||
1138 | sizeof(struct f19_0d_control_5)); | ||
1139 | if (len < 0) { | ||
1140 | dev_err(dev, "%s : Could not sensitivity_adjust_store to" | ||
1141 | " 0x%x\n", __func__, ctrl_bass_addr); | ||
1142 | return len; | ||
1143 | } | ||
1144 | |||
1145 | return len; | ||
1146 | } | ||
1147 | |||
1148 | static ssize_t rmi_f19_hysteresis_threshold_show(struct device *dev, | ||
1149 | struct device_attribute *attr, | ||
1150 | char *buf) | ||
1151 | { | ||
1152 | struct rmi_function_container *fc; | ||
1153 | struct f19_data *data; | ||
1154 | |||
1155 | fc = to_rmi_function_container(dev); | ||
1156 | data = fc->data; | ||
1157 | |||
1158 | return snprintf(buf, PAGE_SIZE, "%u\n", data->button_control-> | ||
1159 | all_button_hysteresis_threshold->hysteresis_threshold); | ||
1160 | |||
1161 | } | ||
1162 | static ssize_t rmi_f19_hysteresis_threshold_store(struct device *dev, | ||
1163 | struct device_attribute *attr, | ||
1164 | const char *buf, size_t count) | ||
1165 | { | ||
1166 | struct rmi_function_container *fc; | ||
1167 | struct f19_data *data; | ||
1168 | unsigned int new_value; | ||
1169 | int len; | ||
1170 | int ctrl_bass_addr; | ||
1171 | int button_reg; | ||
1172 | |||
1173 | fc = to_rmi_function_container(dev); | ||
1174 | data = fc->data; | ||
1175 | len = sscanf(buf, "%u", &new_value); | ||
1176 | if (new_value < 0 || new_value > 15) { | ||
1177 | dev_err(dev, "%s: Error - hysteresis_threshold_store has an " | ||
1178 | "invalid value %d.\n", | ||
1179 | __func__, new_value); | ||
1180 | return -EINVAL; | ||
1181 | } | ||
1182 | data->button_control->all_button_hysteresis_threshold-> | ||
1183 | hysteresis_threshold = new_value; | ||
1184 | /* write back to the control register */ | ||
1185 | button_reg = (data->button_count / 7) + 1; | ||
1186 | ctrl_bass_addr = fc->fd.control_base_addr + | ||
1187 | sizeof(struct f19_0d_control_0) + | ||
1188 | sizeof(struct f19_0d_control_1)*button_reg + | ||
1189 | sizeof(struct f19_0d_control_2)*button_reg + | ||
1190 | sizeof(struct f19_0d_control_3_4)*data->button_count+ | ||
1191 | sizeof(struct f19_0d_control_5); | ||
1192 | len = rmi_write_block(fc->rmi_dev, ctrl_bass_addr, | ||
1193 | (u8 *)data->button_control->all_button_sensitivity_adj, | ||
1194 | sizeof(struct f19_0d_control_6)); | ||
1195 | if (len < 0) { | ||
1196 | dev_err(dev, "%s : Could not write all_button hysteresis " | ||
1197 | "threshold to 0x%x\n", __func__, ctrl_bass_addr); | ||
1198 | return -EINVAL; | ||
1199 | } | ||
1200 | |||
1201 | return count; | ||
1202 | } | ||
1203 | |||
1204 | static ssize_t rmi_f19_has_hysteresis_threshold_show(struct device *dev, | ||
1205 | struct device_attribute *attr, char *buf) | ||
1206 | { | ||
1207 | struct rmi_function_container *fc; | ||
1208 | struct f19_data *data; | ||
1209 | |||
1210 | fc = to_rmi_function_container(dev); | ||
1211 | data = fc->data; | ||
1212 | |||
1213 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1214 | data->button_query.has_hysteresis_threshold); | ||
1215 | } | ||
1216 | |||
1217 | static ssize_t rmi_f19_has_sensitivity_adjust_show(struct device *dev, | ||
1218 | struct device_attribute *attr, char *buf) | ||
1219 | { | ||
1220 | struct rmi_function_container *fc; | ||
1221 | struct f19_data *data; | ||
1222 | |||
1223 | fc = to_rmi_function_container(dev); | ||
1224 | data = fc->data; | ||
1225 | |||
1226 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1227 | data->button_query.has_sensitivity_adjust); | ||
1228 | } | ||
1229 | |||
1230 | static ssize_t rmi_f19_configurable_show(struct device *dev, | ||
1231 | struct device_attribute *attr, char *buf) | ||
1232 | { | ||
1233 | struct rmi_function_container *fc; | ||
1234 | struct f19_data *data; | ||
1235 | |||
1236 | fc = to_rmi_function_container(dev); | ||
1237 | data = fc->data; | ||
1238 | |||
1239 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1240 | data->button_query.configurable); | ||
1241 | } | ||
1242 | |||
1243 | static ssize_t rmi_f19_rezero_show(struct device *dev, | ||
1244 | struct device_attribute *attr, | ||
1245 | char *buf) | ||
1246 | { | ||
1247 | struct rmi_function_container *fc; | ||
1248 | struct f19_data *data; | ||
1249 | |||
1250 | fc = to_rmi_function_container(dev); | ||
1251 | data = fc->data; | ||
1252 | |||
1253 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1254 | data->button_rezero); | ||
1255 | |||
1256 | } | ||
1257 | |||
1258 | static ssize_t rmi_f19_rezero_store(struct device *dev, | ||
1259 | struct device_attribute *attr, | ||
1260 | const char *buf, | ||
1261 | size_t count) | ||
1262 | { | ||
1263 | struct rmi_function_container *fc; | ||
1264 | struct f19_data *data; | ||
1265 | unsigned int new_value; | ||
1266 | int len; | ||
1267 | |||
1268 | fc = to_rmi_function_container(dev); | ||
1269 | data = fc->data; | ||
1270 | len = sscanf(buf, "%u", &new_value); | ||
1271 | if (new_value != 0 && new_value != 1) { | ||
1272 | dev_err(dev, | ||
1273 | "%s: Error - rezero is not a " | ||
1274 | "valid value 0x%x.\n", | ||
1275 | __func__, new_value); | ||
1276 | return -EINVAL; | ||
1277 | } | ||
1278 | data->button_rezero = new_value & 1; | ||
1279 | len = rmi_write(fc->rmi_dev, fc->fd.command_base_addr, | ||
1280 | data->button_rezero); | ||
1281 | |||
1282 | if (len < 0) { | ||
1283 | dev_err(dev, "%s : Could not write rezero to 0x%x\n", | ||
1284 | __func__, fc->fd.command_base_addr); | ||
1285 | return -EINVAL; | ||
1286 | } | ||
1287 | return count; | ||
1288 | } | ||
1289 | |||
1290 | static ssize_t rmi_f19_button_count_show(struct device *dev, | ||
1291 | struct device_attribute *attr, | ||
1292 | char *buf) | ||
1293 | { | ||
1294 | struct rmi_function_container *fc; | ||
1295 | struct f19_data *data; | ||
1296 | |||
1297 | fc = to_rmi_function_container(dev); | ||
1298 | data = fc->data; | ||
1299 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1300 | data->button_count); | ||
1301 | } | ||
1302 | |||
1303 | static ssize_t rmi_f19_button_map_show(struct device *dev, | ||
1304 | struct device_attribute *attr, | ||
1305 | char *buf) | ||
1306 | { | ||
1307 | |||
1308 | struct rmi_function_container *fc; | ||
1309 | struct f19_data *data; | ||
1310 | int i, len, total_len = 0; | ||
1311 | char *current_buf = buf; | ||
1312 | |||
1313 | fc = to_rmi_function_container(dev); | ||
1314 | data = fc->data; | ||
1315 | /* loop through each button map value and copy its | ||
1316 | * string representation into buf */ | ||
1317 | for (i = 0; i < data->button_count; i++) { | ||
1318 | /* get next button mapping value and write it to buf */ | ||
1319 | len = snprintf(current_buf, PAGE_SIZE - total_len, | ||
1320 | "%u ", data->button_map[i]); | ||
1321 | /* bump up ptr to next location in buf if the | ||
1322 | * snprintf was valid. Otherwise issue an error | ||
1323 | * and return. */ | ||
1324 | if (len > 0) { | ||
1325 | current_buf += len; | ||
1326 | total_len += len; | ||
1327 | } else { | ||
1328 | dev_err(dev, "%s: Failed to build button map buffer, " | ||
1329 | "code = %d.\n", __func__, len); | ||
1330 | return snprintf(buf, PAGE_SIZE, "unknown\n"); | ||
1331 | } | ||
1332 | } | ||
1333 | len = snprintf(current_buf, PAGE_SIZE - total_len, "\n"); | ||
1334 | if (len > 0) | ||
1335 | total_len += len; | ||
1336 | else | ||
1337 | dev_warn(dev, "%s: Failed to append carriage return.\n", | ||
1338 | __func__); | ||
1339 | return total_len; | ||
1340 | } | ||
1341 | |||
1342 | static ssize_t rmi_f19_button_map_store(struct device *dev, | ||
1343 | struct device_attribute *attr, | ||
1344 | const char *buf, | ||
1345 | size_t count) | ||
1346 | { | ||
1347 | struct rmi_function_container *fc; | ||
1348 | struct f19_data *data; | ||
1349 | unsigned int button; | ||
1350 | int i; | ||
1351 | int retval = count; | ||
1352 | int button_count = 0; | ||
1353 | unsigned char temp_button_map[KEY_MAX]; | ||
1354 | |||
1355 | fc = to_rmi_function_container(dev); | ||
1356 | data = fc->data; | ||
1357 | |||
1358 | /* Do validation on the button map data passed in. Store button | ||
1359 | * mappings into a temp buffer and then verify button count and | ||
1360 | * data prior to clearing out old button mappings and storing the | ||
1361 | * new ones. */ | ||
1362 | for (i = 0; i < data->button_count && *buf != 0; | ||
1363 | i++) { | ||
1364 | /* get next button mapping value and store and bump up to | ||
1365 | * point to next item in buf */ | ||
1366 | sscanf(buf, "%u", &button); | ||
1367 | |||
1368 | /* Make sure the key is a valid key */ | ||
1369 | if (button > KEY_MAX) { | ||
1370 | dev_err(dev, | ||
1371 | "%s: Error - button map for button %d is not a" | ||
1372 | " valid value 0x%x.\n", __func__, i, button); | ||
1373 | retval = -EINVAL; | ||
1374 | goto err_ret; | ||
1375 | } | ||
1376 | |||
1377 | temp_button_map[i] = button; | ||
1378 | button_count++; | ||
1379 | |||
1380 | /* bump up buf to point to next item to read */ | ||
1381 | while (*buf != 0) { | ||
1382 | buf++; | ||
1383 | if (*(buf - 1) == ' ') | ||
1384 | break; | ||
1385 | } | ||
1386 | } | ||
1387 | |||
1388 | /* Make sure the button count matches */ | ||
1389 | if (button_count != data->button_count) { | ||
1390 | dev_err(dev, | ||
1391 | "%s: Error - button map count of %d doesn't match device " | ||
1392 | "button count of %d.\n", __func__, button_count, | ||
1393 | data->button_count); | ||
1394 | retval = -EINVAL; | ||
1395 | goto err_ret; | ||
1396 | } | ||
1397 | |||
1398 | /* Clear the key bits for the old button map. */ | ||
1399 | for (i = 0; i < button_count; i++) | ||
1400 | clear_bit(data->button_map[i], data->input->keybit); | ||
1401 | |||
1402 | /* Switch to the new map. */ | ||
1403 | memcpy(data->button_map, temp_button_map, | ||
1404 | data->button_count); | ||
1405 | |||
1406 | /* Loop through the key map and set the key bit for the new mapping. */ | ||
1407 | for (i = 0; i < button_count; i++) | ||
1408 | set_bit(data->button_map[i], data->input->keybit); | ||
1409 | |||
1410 | err_ret: | ||
1411 | return retval; | ||
1412 | } | ||
1413 | |||
1414 | module_init(rmi_f19_module_init); | ||
1415 | module_exit(rmi_f19_module_exit); | ||
1416 | |||
1417 | MODULE_AUTHOR("Vivian Ly <vly@synaptics.com>"); | ||
1418 | MODULE_DESCRIPTION("RMI F19 module"); | ||
1419 | MODULE_LICENSE("GPL"); | ||