1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2012-2016 Synaptics Incorporated |
4 | */ |
5 | |
6 | #include <linux/kernel.h> |
7 | #include <linux/rmi.h> |
8 | #include <linux/input.h> |
9 | #include <linux/slab.h> |
10 | #include "rmi_driver.h" |
11 | |
12 | #define RMI_F30_QUERY_SIZE 2 |
13 | |
14 | /* Defs for Query 0 */ |
15 | #define RMI_F30_EXTENDED_PATTERNS 0x01 |
16 | #define RMI_F30_HAS_MAPPABLE_BUTTONS BIT(1) |
17 | #define RMI_F30_HAS_LED BIT(2) |
18 | #define RMI_F30_HAS_GPIO BIT(3) |
19 | #define RMI_F30_HAS_HAPTIC BIT(4) |
20 | #define RMI_F30_HAS_GPIO_DRV_CTL BIT(5) |
21 | #define RMI_F30_HAS_MECH_MOUSE_BTNS BIT(6) |
22 | |
23 | /* Defs for Query 1 */ |
24 | #define RMI_F30_GPIO_LED_COUNT 0x1F |
25 | |
26 | /* Defs for Control Registers */ |
27 | #define RMI_F30_CTRL_1_GPIO_DEBOUNCE 0x01 |
28 | #define RMI_F30_CTRL_1_HALT BIT(4) |
29 | #define RMI_F30_CTRL_1_HALTED BIT(5) |
30 | #define RMI_F30_CTRL_10_NUM_MECH_MOUSE_BTNS 0x03 |
31 | |
32 | #define RMI_F30_CTRL_MAX_REGS 32 |
33 | #define RMI_F30_CTRL_MAX_BYTES DIV_ROUND_UP(RMI_F30_CTRL_MAX_REGS, 8) |
34 | #define RMI_F30_CTRL_MAX_REG_BLOCKS 11 |
35 | |
36 | #define RMI_F30_CTRL_REGS_MAX_SIZE (RMI_F30_CTRL_MAX_BYTES \ |
37 | + 1 \ |
38 | + RMI_F30_CTRL_MAX_BYTES \ |
39 | + RMI_F30_CTRL_MAX_BYTES \ |
40 | + RMI_F30_CTRL_MAX_BYTES \ |
41 | + 6 \ |
42 | + RMI_F30_CTRL_MAX_REGS \ |
43 | + RMI_F30_CTRL_MAX_REGS \ |
44 | + RMI_F30_CTRL_MAX_BYTES \ |
45 | + 1 \ |
46 | + 1) |
47 | |
48 | #define TRACKSTICK_RANGE_START 3 |
49 | #define TRACKSTICK_RANGE_END 6 |
50 | |
51 | struct rmi_f30_ctrl_data { |
52 | int address; |
53 | int length; |
54 | u8 *regs; |
55 | }; |
56 | |
57 | struct f30_data { |
58 | /* Query Data */ |
59 | bool has_extended_pattern; |
60 | bool has_mappable_buttons; |
61 | bool has_led; |
62 | bool has_gpio; |
63 | bool has_haptic; |
64 | bool has_gpio_driver_control; |
65 | bool has_mech_mouse_btns; |
66 | u8 gpioled_count; |
67 | |
68 | u8 register_count; |
69 | |
70 | /* Control Register Data */ |
71 | struct rmi_f30_ctrl_data ctrl[RMI_F30_CTRL_MAX_REG_BLOCKS]; |
72 | u8 ctrl_regs[RMI_F30_CTRL_REGS_MAX_SIZE]; |
73 | u32 ctrl_regs_size; |
74 | |
75 | u8 data_regs[RMI_F30_CTRL_MAX_BYTES]; |
76 | u16 *gpioled_key_map; |
77 | |
78 | struct input_dev *input; |
79 | |
80 | struct rmi_function *f03; |
81 | bool trackstick_buttons; |
82 | }; |
83 | |
84 | static int rmi_f30_read_control_parameters(struct rmi_function *fn, |
85 | struct f30_data *f30) |
86 | { |
87 | int error; |
88 | |
89 | error = rmi_read_block(d: fn->rmi_dev, addr: fn->fd.control_base_addr, |
90 | buf: f30->ctrl_regs, len: f30->ctrl_regs_size); |
91 | if (error) { |
92 | dev_err(&fn->dev, |
93 | "%s: Could not read control registers at 0x%x: %d\n" , |
94 | __func__, fn->fd.control_base_addr, error); |
95 | return error; |
96 | } |
97 | |
98 | return 0; |
99 | } |
100 | |
101 | static void rmi_f30_report_button(struct rmi_function *fn, |
102 | struct f30_data *f30, unsigned int button) |
103 | { |
104 | unsigned int reg_num = button >> 3; |
105 | unsigned int bit_num = button & 0x07; |
106 | u16 key_code = f30->gpioled_key_map[button]; |
107 | bool key_down = !(f30->data_regs[reg_num] & BIT(bit_num)); |
108 | |
109 | if (f30->trackstick_buttons && |
110 | button >= TRACKSTICK_RANGE_START && |
111 | button <= TRACKSTICK_RANGE_END) { |
112 | rmi_f03_overwrite_button(fn: f30->f03, button: key_code, value: key_down); |
113 | } else { |
114 | rmi_dbg(RMI_DEBUG_FN, dev: &fn->dev, |
115 | fmt: "%s: call input report key (0x%04x) value (0x%02x)" , |
116 | __func__, key_code, key_down); |
117 | |
118 | input_report_key(dev: f30->input, code: key_code, value: key_down); |
119 | } |
120 | } |
121 | |
122 | static irqreturn_t rmi_f30_attention(int irq, void *ctx) |
123 | { |
124 | struct rmi_function *fn = ctx; |
125 | struct f30_data *f30 = dev_get_drvdata(dev: &fn->dev); |
126 | struct rmi_driver_data *drvdata = dev_get_drvdata(dev: &fn->rmi_dev->dev); |
127 | int error; |
128 | int i; |
129 | |
130 | /* Read the gpi led data. */ |
131 | if (drvdata->attn_data.data) { |
132 | if (drvdata->attn_data.size < f30->register_count) { |
133 | dev_warn(&fn->dev, |
134 | "F30 interrupted, but data is missing\n" ); |
135 | return IRQ_HANDLED; |
136 | } |
137 | memcpy(f30->data_regs, drvdata->attn_data.data, |
138 | f30->register_count); |
139 | drvdata->attn_data.data += f30->register_count; |
140 | drvdata->attn_data.size -= f30->register_count; |
141 | } else { |
142 | error = rmi_read_block(d: fn->rmi_dev, addr: fn->fd.data_base_addr, |
143 | buf: f30->data_regs, len: f30->register_count); |
144 | if (error) { |
145 | dev_err(&fn->dev, |
146 | "%s: Failed to read F30 data registers: %d\n" , |
147 | __func__, error); |
148 | return IRQ_RETVAL(error); |
149 | } |
150 | } |
151 | |
152 | if (f30->has_gpio) { |
153 | for (i = 0; i < f30->gpioled_count; i++) |
154 | if (f30->gpioled_key_map[i] != KEY_RESERVED) |
155 | rmi_f30_report_button(fn, f30, button: i); |
156 | if (f30->trackstick_buttons) |
157 | rmi_f03_commit_buttons(fn: f30->f03); |
158 | } |
159 | |
160 | return IRQ_HANDLED; |
161 | } |
162 | |
163 | static int rmi_f30_config(struct rmi_function *fn) |
164 | { |
165 | struct f30_data *f30 = dev_get_drvdata(dev: &fn->dev); |
166 | struct rmi_driver *drv = fn->rmi_dev->driver; |
167 | const struct rmi_device_platform_data *pdata = |
168 | rmi_get_platform_data(d: fn->rmi_dev); |
169 | int error; |
170 | |
171 | /* can happen if gpio_data.disable is set */ |
172 | if (!f30) |
173 | return 0; |
174 | |
175 | if (pdata->gpio_data.trackstick_buttons) { |
176 | /* Try [re-]establish link to F03. */ |
177 | f30->f03 = rmi_find_function(rmi_dev: fn->rmi_dev, number: 0x03); |
178 | f30->trackstick_buttons = f30->f03 != NULL; |
179 | } |
180 | |
181 | if (pdata->gpio_data.disable) { |
182 | drv->clear_irq_bits(fn->rmi_dev, fn->irq_mask); |
183 | } else { |
184 | /* Write Control Register values back to device */ |
185 | error = rmi_write_block(d: fn->rmi_dev, addr: fn->fd.control_base_addr, |
186 | buf: f30->ctrl_regs, len: f30->ctrl_regs_size); |
187 | if (error) { |
188 | dev_err(&fn->dev, |
189 | "%s: Could not write control registers at 0x%x: %d\n" , |
190 | __func__, fn->fd.control_base_addr, error); |
191 | return error; |
192 | } |
193 | |
194 | drv->set_irq_bits(fn->rmi_dev, fn->irq_mask); |
195 | } |
196 | |
197 | return 0; |
198 | } |
199 | |
200 | static void rmi_f30_set_ctrl_data(struct rmi_f30_ctrl_data *ctrl, |
201 | int *ctrl_addr, int len, u8 **reg) |
202 | { |
203 | ctrl->address = *ctrl_addr; |
204 | ctrl->length = len; |
205 | ctrl->regs = *reg; |
206 | *ctrl_addr += len; |
207 | *reg += len; |
208 | } |
209 | |
210 | static bool rmi_f30_is_valid_button(int button, struct rmi_f30_ctrl_data *ctrl) |
211 | { |
212 | int byte_position = button >> 3; |
213 | int bit_position = button & 0x07; |
214 | |
215 | /* |
216 | * ctrl2 -> dir == 0 -> input mode |
217 | * ctrl3 -> data == 1 -> actual button |
218 | */ |
219 | return !(ctrl[2].regs[byte_position] & BIT(bit_position)) && |
220 | (ctrl[3].regs[byte_position] & BIT(bit_position)); |
221 | } |
222 | |
223 | static int rmi_f30_map_gpios(struct rmi_function *fn, |
224 | struct f30_data *f30) |
225 | { |
226 | const struct rmi_device_platform_data *pdata = |
227 | rmi_get_platform_data(d: fn->rmi_dev); |
228 | struct input_dev *input = f30->input; |
229 | unsigned int button = BTN_LEFT; |
230 | unsigned int trackstick_button = BTN_LEFT; |
231 | bool button_mapped = false; |
232 | int i; |
233 | int button_count = min_t(u8, f30->gpioled_count, TRACKSTICK_RANGE_END); |
234 | |
235 | f30->gpioled_key_map = devm_kcalloc(dev: &fn->dev, |
236 | n: button_count, |
237 | size: sizeof(f30->gpioled_key_map[0]), |
238 | GFP_KERNEL); |
239 | if (!f30->gpioled_key_map) { |
240 | dev_err(&fn->dev, "Failed to allocate gpioled map memory.\n" ); |
241 | return -ENOMEM; |
242 | } |
243 | |
244 | for (i = 0; i < button_count; i++) { |
245 | if (!rmi_f30_is_valid_button(button: i, ctrl: f30->ctrl)) |
246 | continue; |
247 | |
248 | if (pdata->gpio_data.trackstick_buttons && |
249 | i >= TRACKSTICK_RANGE_START && i < TRACKSTICK_RANGE_END) { |
250 | f30->gpioled_key_map[i] = trackstick_button++; |
251 | } else if (!pdata->gpio_data.buttonpad || !button_mapped) { |
252 | f30->gpioled_key_map[i] = button; |
253 | input_set_capability(dev: input, EV_KEY, code: button++); |
254 | button_mapped = true; |
255 | } |
256 | } |
257 | |
258 | input->keycode = f30->gpioled_key_map; |
259 | input->keycodesize = sizeof(f30->gpioled_key_map[0]); |
260 | input->keycodemax = f30->gpioled_count; |
261 | |
262 | /* |
263 | * Buttonpad could be also inferred from f30->has_mech_mouse_btns, |
264 | * but I am not sure, so use only the pdata info and the number of |
265 | * mapped buttons. |
266 | */ |
267 | if (pdata->gpio_data.buttonpad || (button - BTN_LEFT == 1)) |
268 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); |
269 | |
270 | return 0; |
271 | } |
272 | |
273 | static int rmi_f30_initialize(struct rmi_function *fn, struct f30_data *f30) |
274 | { |
275 | u8 *ctrl_reg = f30->ctrl_regs; |
276 | int control_address = fn->fd.control_base_addr; |
277 | u8 buf[RMI_F30_QUERY_SIZE]; |
278 | int error; |
279 | |
280 | error = rmi_read_block(d: fn->rmi_dev, addr: fn->fd.query_base_addr, |
281 | buf, RMI_F30_QUERY_SIZE); |
282 | if (error) { |
283 | dev_err(&fn->dev, "Failed to read query register\n" ); |
284 | return error; |
285 | } |
286 | |
287 | f30->has_extended_pattern = buf[0] & RMI_F30_EXTENDED_PATTERNS; |
288 | f30->has_mappable_buttons = buf[0] & RMI_F30_HAS_MAPPABLE_BUTTONS; |
289 | f30->has_led = buf[0] & RMI_F30_HAS_LED; |
290 | f30->has_gpio = buf[0] & RMI_F30_HAS_GPIO; |
291 | f30->has_haptic = buf[0] & RMI_F30_HAS_HAPTIC; |
292 | f30->has_gpio_driver_control = buf[0] & RMI_F30_HAS_GPIO_DRV_CTL; |
293 | f30->has_mech_mouse_btns = buf[0] & RMI_F30_HAS_MECH_MOUSE_BTNS; |
294 | f30->gpioled_count = buf[1] & RMI_F30_GPIO_LED_COUNT; |
295 | |
296 | f30->register_count = DIV_ROUND_UP(f30->gpioled_count, 8); |
297 | |
298 | if (f30->has_gpio && f30->has_led) |
299 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[0], ctrl_addr: &control_address, |
300 | len: f30->register_count, reg: &ctrl_reg); |
301 | |
302 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[1], ctrl_addr: &control_address, |
303 | len: sizeof(u8), reg: &ctrl_reg); |
304 | |
305 | if (f30->has_gpio) { |
306 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[2], ctrl_addr: &control_address, |
307 | len: f30->register_count, reg: &ctrl_reg); |
308 | |
309 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[3], ctrl_addr: &control_address, |
310 | len: f30->register_count, reg: &ctrl_reg); |
311 | } |
312 | |
313 | if (f30->has_led) { |
314 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[4], ctrl_addr: &control_address, |
315 | len: f30->register_count, reg: &ctrl_reg); |
316 | |
317 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[5], ctrl_addr: &control_address, |
318 | len: f30->has_extended_pattern ? 6 : 2, |
319 | reg: &ctrl_reg); |
320 | } |
321 | |
322 | if (f30->has_led || f30->has_gpio_driver_control) { |
323 | /* control 6 uses a byte per gpio/led */ |
324 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[6], ctrl_addr: &control_address, |
325 | len: f30->gpioled_count, reg: &ctrl_reg); |
326 | } |
327 | |
328 | if (f30->has_mappable_buttons) { |
329 | /* control 7 uses a byte per gpio/led */ |
330 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[7], ctrl_addr: &control_address, |
331 | len: f30->gpioled_count, reg: &ctrl_reg); |
332 | } |
333 | |
334 | if (f30->has_haptic) { |
335 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[8], ctrl_addr: &control_address, |
336 | len: f30->register_count, reg: &ctrl_reg); |
337 | |
338 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[9], ctrl_addr: &control_address, |
339 | len: sizeof(u8), reg: &ctrl_reg); |
340 | } |
341 | |
342 | if (f30->has_mech_mouse_btns) |
343 | rmi_f30_set_ctrl_data(ctrl: &f30->ctrl[10], ctrl_addr: &control_address, |
344 | len: sizeof(u8), reg: &ctrl_reg); |
345 | |
346 | f30->ctrl_regs_size = ctrl_reg - |
347 | f30->ctrl_regs ?: RMI_F30_CTRL_REGS_MAX_SIZE; |
348 | |
349 | error = rmi_f30_read_control_parameters(fn, f30); |
350 | if (error) { |
351 | dev_err(&fn->dev, |
352 | "Failed to initialize F30 control params: %d\n" , |
353 | error); |
354 | return error; |
355 | } |
356 | |
357 | if (f30->has_gpio) { |
358 | error = rmi_f30_map_gpios(fn, f30); |
359 | if (error) |
360 | return error; |
361 | } |
362 | |
363 | return 0; |
364 | } |
365 | |
366 | static int rmi_f30_probe(struct rmi_function *fn) |
367 | { |
368 | struct rmi_device *rmi_dev = fn->rmi_dev; |
369 | const struct rmi_device_platform_data *pdata = |
370 | rmi_get_platform_data(d: rmi_dev); |
371 | struct rmi_driver_data *drv_data = dev_get_drvdata(dev: &rmi_dev->dev); |
372 | struct f30_data *f30; |
373 | int error; |
374 | |
375 | if (pdata->gpio_data.disable) |
376 | return 0; |
377 | |
378 | if (!drv_data->input) { |
379 | dev_info(&fn->dev, "F30: no input device found, ignoring\n" ); |
380 | return -ENXIO; |
381 | } |
382 | |
383 | f30 = devm_kzalloc(dev: &fn->dev, size: sizeof(*f30), GFP_KERNEL); |
384 | if (!f30) |
385 | return -ENOMEM; |
386 | |
387 | f30->input = drv_data->input; |
388 | |
389 | error = rmi_f30_initialize(fn, f30); |
390 | if (error) |
391 | return error; |
392 | |
393 | dev_set_drvdata(dev: &fn->dev, data: f30); |
394 | return 0; |
395 | } |
396 | |
397 | struct rmi_function_handler rmi_f30_handler = { |
398 | .driver = { |
399 | .name = "rmi4_f30" , |
400 | }, |
401 | .func = 0x30, |
402 | .probe = rmi_f30_probe, |
403 | .config = rmi_f30_config, |
404 | .attention = rmi_f30_attention, |
405 | }; |
406 | |