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