xref: /linux/drivers/input/rmi4/rmi_f1a.c (revision 0074281bb6316108e0cff094bd4db78ab3eee236)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2025 André Apitzsch <git@apitzsch.eu>
4  */
5 
6 #include <linux/input.h>
7 #include <linux/property.h>
8 #include "rmi_driver.h"
9 
10 struct f1a_data {
11 	struct input_dev *input;
12 
13 	u32 *keymap;
14 	unsigned int num_keys;
15 };
16 
rmi_f1a_parse_device_properties(struct rmi_function * fn,struct f1a_data * f1a)17 static int rmi_f1a_parse_device_properties(struct rmi_function *fn, struct f1a_data *f1a)
18 {
19 	static const char buttons_property[] = "linux,keycodes";
20 	struct device *dev = &fn->dev;
21 	u32 *buttonmap;
22 	int n_keys;
23 	int error;
24 
25 	if (!device_property_present(dev, buttons_property))
26 		return 0;
27 
28 	n_keys = device_property_count_u32(dev, buttons_property);
29 	if (n_keys <= 0) {
30 		error = n_keys < 0 ? n_keys : -EINVAL;
31 		dev_err(dev, "Invalid/malformed '%s' property: %d\n",
32 			buttons_property, error);
33 		return error;
34 	}
35 
36 	buttonmap = devm_kmalloc_array(dev, n_keys, sizeof(*buttonmap),
37 				       GFP_KERNEL);
38 	if (!buttonmap)
39 		return -ENOMEM;
40 
41 	error = device_property_read_u32_array(dev, buttons_property,
42 					       buttonmap, n_keys);
43 	if (error) {
44 		dev_err(dev, "Failed to parse '%s' property: %d\n",
45 			buttons_property, error);
46 		return error;
47 	}
48 
49 	f1a->keymap = buttonmap;
50 	f1a->num_keys = n_keys;
51 
52 	return 0;
53 }
54 
rmi_f1a_attention(int irq,void * ctx)55 static irqreturn_t rmi_f1a_attention(int irq, void *ctx)
56 {
57 	struct rmi_function *fn = ctx;
58 	struct f1a_data *f1a = dev_get_drvdata(&fn->dev);
59 	char button_bitmask;
60 	int key;
61 	int error;
62 
63 	error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr,
64 			       &button_bitmask, sizeof(button_bitmask));
65 	if (error) {
66 		dev_err(&fn->dev, "Failed to read object data. Code: %d.\n",
67 			error);
68 		return IRQ_RETVAL(error);
69 	}
70 
71 	for (key = 0; key < f1a->num_keys; key++)
72 		input_report_key(f1a->input, f1a->keymap[key],
73 				 button_bitmask & BIT(key));
74 
75 	return IRQ_HANDLED;
76 }
77 
rmi_f1a_config(struct rmi_function * fn)78 static int rmi_f1a_config(struct rmi_function *fn)
79 {
80 	struct f1a_data *f1a = dev_get_drvdata(&fn->dev);
81 	struct rmi_driver *drv = fn->rmi_dev->driver;
82 
83 	if (f1a->num_keys)
84 		drv->set_irq_bits(fn->rmi_dev, fn->irq_mask);
85 
86 	return 0;
87 }
88 
rmi_f1a_initialize(struct rmi_function * fn,struct f1a_data * f1a)89 static int rmi_f1a_initialize(struct rmi_function *fn, struct f1a_data *f1a)
90 {
91 	int error;
92 	int i;
93 
94 	error = rmi_f1a_parse_device_properties(fn, f1a);
95 	if (error)
96 		return error;
97 
98 	for (i = 0; i < f1a->num_keys; i++)
99 		input_set_capability(f1a->input, EV_KEY, f1a->keymap[i]);
100 
101 	f1a->input->keycode = f1a->keymap;
102 	f1a->input->keycodemax = f1a->num_keys;
103 	f1a->input->keycodesize = sizeof(f1a->keymap[0]);
104 
105 	return 0;
106 }
107 
rmi_f1a_probe(struct rmi_function * fn)108 static int rmi_f1a_probe(struct rmi_function *fn)
109 {
110 	struct rmi_device *rmi_dev = fn->rmi_dev;
111 	struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
112 	struct f1a_data *f1a;
113 	int error;
114 
115 	if (!drv_data->input) {
116 		dev_info(&fn->dev, "F1A: no input device found, ignoring\n");
117 		return -ENXIO;
118 	}
119 
120 	f1a = devm_kzalloc(&fn->dev, sizeof(*f1a), GFP_KERNEL);
121 	if (!f1a)
122 		return -ENOMEM;
123 
124 	f1a->input = drv_data->input;
125 
126 	error = rmi_f1a_initialize(fn, f1a);
127 	if (error)
128 		return error;
129 
130 	dev_set_drvdata(&fn->dev, f1a);
131 
132 	return 0;
133 }
134 
135 struct rmi_function_handler rmi_f1a_handler = {
136 	.driver = {
137 		.name = "rmi4_f1a",
138 	},
139 	.func = 0x1a,
140 	.probe = rmi_f1a_probe,
141 	.config = rmi_f1a_config,
142 	.attention = rmi_f1a_attention,
143 };
144