xref: /linux/drivers/input/rmi4/rmi_f30.c (revision 2da68a77)
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(fn->rmi_dev, fn->fd.control_base_addr,
90 			       f30->ctrl_regs, 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(f30->f03, key_code, key_down);
113 	} else {
114 		rmi_dbg(RMI_DEBUG_FN, &fn->dev,
115 			"%s: call input report key (0x%04x) value (0x%02x)",
116 			__func__, key_code, key_down);
117 
118 		input_report_key(f30->input, key_code, 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(&fn->dev);
126 	struct rmi_driver_data *drvdata = dev_get_drvdata(&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(fn->rmi_dev, fn->fd.data_base_addr,
143 				       f30->data_regs, 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, i);
156 		if (f30->trackstick_buttons)
157 			rmi_f03_commit_buttons(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(&fn->dev);
166 	struct rmi_driver *drv = fn->rmi_dev->driver;
167 	const struct rmi_device_platform_data *pdata =
168 				rmi_get_platform_data(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(fn->rmi_dev, 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(fn->rmi_dev, fn->fd.control_base_addr,
186 					f30->ctrl_regs, 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(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(&fn->dev,
236 					    button_count,
237 					    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(i, 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(input, EV_KEY, 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(fn->rmi_dev, 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(&f30->ctrl[0], &control_address,
300 				      f30->register_count, &ctrl_reg);
301 
302 	rmi_f30_set_ctrl_data(&f30->ctrl[1], &control_address,
303 			      sizeof(u8), &ctrl_reg);
304 
305 	if (f30->has_gpio) {
306 		rmi_f30_set_ctrl_data(&f30->ctrl[2], &control_address,
307 				      f30->register_count, &ctrl_reg);
308 
309 		rmi_f30_set_ctrl_data(&f30->ctrl[3], &control_address,
310 				      f30->register_count, &ctrl_reg);
311 	}
312 
313 	if (f30->has_led) {
314 		rmi_f30_set_ctrl_data(&f30->ctrl[4], &control_address,
315 				      f30->register_count, &ctrl_reg);
316 
317 		rmi_f30_set_ctrl_data(&f30->ctrl[5], &control_address,
318 				      f30->has_extended_pattern ? 6 : 2,
319 				      &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(&f30->ctrl[6], &control_address,
325 				      f30->gpioled_count, &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(&f30->ctrl[7], &control_address,
331 				      f30->gpioled_count, &ctrl_reg);
332 	}
333 
334 	if (f30->has_haptic) {
335 		rmi_f30_set_ctrl_data(&f30->ctrl[8], &control_address,
336 				      f30->register_count, &ctrl_reg);
337 
338 		rmi_f30_set_ctrl_data(&f30->ctrl[9], &control_address,
339 				      sizeof(u8), &ctrl_reg);
340 	}
341 
342 	if (f30->has_mech_mouse_btns)
343 		rmi_f30_set_ctrl_data(&f30->ctrl[10], &control_address,
344 				      sizeof(u8), &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(rmi_dev);
371 	struct rmi_driver_data *drv_data = dev_get_drvdata(&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(&fn->dev, 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(&fn->dev, 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