Skip to content
This repository was archived by the owner on Sep 18, 2022. It is now read-only.

Commit c52d3e9

Browse files
committed
Input: synaptics-rmi4 - add support for F1A
RMI4 F1A supports the simple capacitive buttons function, it's used for example on embedded devices such as smartphones for capacitive Android back and recents buttons.
1 parent c52ba49 commit c52d3e9

File tree

5 files changed

+193
-0
lines changed

5 files changed

+193
-0
lines changed

drivers/input/rmi4/Kconfig

+8
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ config RMI4_F12
8282
touchpads. For sensors that support relative pointing, F12 also
8383
provides mouse input.
8484

85+
config RMI4_F1A
86+
bool "RMI4 Function 1A (Simple capacitive buttons)"
87+
depends on OF
88+
help
89+
Say Y here if you want to add support for RMI4 function 1A.
90+
91+
Function 1A provides GPIO capacitive button support for RMI4 devices.
92+
8593
config RMI4_F30
8694
bool "RMI4 Function 30 (GPIO LED)"
8795
help

drivers/input/rmi4/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
88
rmi_core-$(CONFIG_RMI4_F03) += rmi_f03.o
99
rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
1010
rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
11+
rmi_core-$(CONFIG_RMI4_F1A) += rmi_f1a.o
1112
rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
1213
rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
1314
rmi_core-$(CONFIG_RMI4_F3A) += rmi_f3a.o

drivers/input/rmi4/rmi_bus.c

+3
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,9 @@ static struct rmi_function_handler *fn_handlers[] = {
359359
#ifdef CONFIG_RMI4_F12
360360
&rmi_f12_handler,
361361
#endif
362+
#ifdef CONFIG_RMI4_F1A
363+
&rmi_f1a_handler,
364+
#endif
362365
#ifdef CONFIG_RMI4_F30
363366
&rmi_f30_handler,
364367
#endif

drivers/input/rmi4/rmi_driver.h

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ extern struct rmi_function_handler rmi_f01_handler;
133133
extern struct rmi_function_handler rmi_f03_handler;
134134
extern struct rmi_function_handler rmi_f11_handler;
135135
extern struct rmi_function_handler rmi_f12_handler;
136+
extern struct rmi_function_handler rmi_f1a_handler;
136137
extern struct rmi_function_handler rmi_f30_handler;
137138
extern struct rmi_function_handler rmi_f34_handler;
138139
extern struct rmi_function_handler rmi_f3a_handler;

drivers/input/rmi4/rmi_f1a.c

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
// FIXME: Too much stuff is hardcoded in currently!
2+
#include <linux/input.h>
3+
#include <linux/rmi.h>
4+
#include <linux/of.h>
5+
#include "rmi_driver.h"
6+
7+
/* Query 1 */
8+
//#define F1A_BUTTONS_COUNT 0b00011111 /* BIT(1) */
9+
10+
#define MAX_NAME_LEN 256
11+
#define F1A_MAX_BUTTONS 8
12+
13+
struct f1a_data {
14+
struct rmi_function *fn;
15+
16+
unsigned char button_count;
17+
u32 button_map[F1A_MAX_BUTTONS];
18+
struct input_dev *input;
19+
char input_name[MAX_NAME_LEN];
20+
char input_phys[MAX_NAME_LEN];
21+
u8 button_data_buffer;
22+
};
23+
24+
static int rmi_f1a_initialize(struct f1a_data *f1a)
25+
{
26+
struct rmi_function *fn = f1a->fn;
27+
struct device *dev = &fn->dev;
28+
//u8 query[2];
29+
int error;
30+
31+
/*error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr, query, 2);
32+
if (error) {
33+
dev_err(dev, "Failed to read query register (%d).\n", error);
34+
return error;
35+
}
36+
printk("%s: query0: 0x%x, query1: 0x%x\n", __func__, query[0], query[1]);*/
37+
38+
error = of_property_read_variable_u32_array(dev_of_node(dev),
39+
"syna,codes", f1a->button_map, 1, F1A_MAX_BUTTONS);
40+
if (error < 0) {
41+
dev_err(dev, "Failed to parse syna,codes from OF device tree (%d).\n", error);
42+
return error;
43+
}
44+
// FIXME: button_count = query[1] & F1A_BUTTONS_COUNT;
45+
f1a->button_count = 0;
46+
for (f1a->button_count = 0; f1a->button_count < F1A_MAX_BUTTONS; f1a->button_count++)
47+
if (f1a->button_map[f1a->button_count] == 0)
48+
break;
49+
rmi_dbg(RMI_DEBUG_FN, dev, "%s: %d button codes defined\n", __func__, f1a->button_count);
50+
51+
return 0;
52+
}
53+
54+
static int rmi_f1a_register_device(struct f1a_data *f1a)
55+
{
56+
struct rmi_function *fn = f1a->fn;
57+
struct device *dev = &fn->dev;
58+
struct rmi_device *rmi_dev = fn->rmi_dev;
59+
struct input_dev *input_dev;
60+
int i, rc;
61+
62+
input_dev = input_allocate_device();
63+
if (!input_dev) {
64+
dev_err(dev, "Failed to allocate input device.\n");
65+
return -ENOMEM;
66+
}
67+
68+
f1a->input = input_dev;
69+
snprintf(f1a->input_name, MAX_NAME_LEN, "%s.fn%02x",
70+
dev_name(&rmi_dev->dev), fn->fd.function_number);
71+
input_dev->name = f1a->input_name;
72+
snprintf(f1a->input_phys, MAX_NAME_LEN, "%s/input0", input_dev->name);
73+
input_dev->phys = f1a->input_phys;
74+
input_dev->dev.parent = &rmi_dev->dev;
75+
input_set_drvdata(input_dev, f1a);
76+
77+
/* set up any input events */
78+
set_bit(EV_SYN, input_dev->evbit);
79+
set_bit(EV_KEY, input_dev->evbit);
80+
81+
/* manage button map using input subsystem */
82+
input_dev->keycode = f1a->button_map;
83+
input_dev->keycodesize = sizeof(f1a->button_map); /* f1a->button_count */
84+
input_dev->keycodemax = f1a->button_count;
85+
86+
/* set bits for each button */
87+
for (i = 0; i < f1a->button_count; i++) {
88+
set_bit(f1a->button_map[i], input_dev->keybit);
89+
input_set_capability(input_dev, EV_KEY, f1a->button_map[i]);
90+
}
91+
92+
rc = input_register_device(input_dev);
93+
if (rc < 0) {
94+
dev_err(dev, "Failed to register input device.\n");
95+
goto error_free_device;
96+
}
97+
98+
return 0;
99+
100+
error_free_device:
101+
input_free_device(input_dev);
102+
return rc;
103+
}
104+
105+
static int rmi_f1a_probe(struct rmi_function *fn)
106+
{
107+
struct device *dev = &fn->dev;
108+
struct f1a_data *f1a;
109+
int error;
110+
111+
rmi_dbg(RMI_DEBUG_FN, dev, "%s\n", __func__);
112+
113+
f1a = devm_kzalloc(dev, sizeof(struct f1a_data), GFP_KERNEL);
114+
if (!f1a)
115+
return -ENOMEM;
116+
117+
f1a->fn = fn;
118+
119+
error = rmi_f1a_initialize(f1a);
120+
if (error < 0)
121+
return error;
122+
123+
error = rmi_f1a_register_device(f1a);
124+
if (error < 0)
125+
return error;
126+
127+
dev_set_drvdata(dev, f1a);
128+
return 0;
129+
}
130+
131+
static int rmi_f1a_config(struct rmi_function *fn)
132+
{
133+
fn->rmi_dev->driver->set_irq_bits(fn->rmi_dev, fn->irq_mask);
134+
return 0;
135+
}
136+
137+
static irqreturn_t rmi_f1a_attention(int irq, void *ctx)
138+
{
139+
struct rmi_function *fn = ctx;
140+
struct device *dev = &fn->dev;
141+
struct rmi_device *rmi_dev = fn->rmi_dev;
142+
struct f1a_data *f1a = dev_get_drvdata(dev);
143+
int error, button;
144+
145+
// TODO: use rmi_read_block() to accomodate up to 8 buttons?
146+
error = rmi_read(rmi_dev, fn->fd.data_base_addr, &(f1a->button_data_buffer));
147+
if (error < 0) {
148+
dev_err(dev, "Failed to read button data registers (%d).\n", error);
149+
return error;
150+
}
151+
/*rmi_dbg(RMI_DEBUG_FN, dev, "%s: button_data=0x%x\n", __func__, f1a->button_data_buffer);*/
152+
153+
/* generate events for buttons that change state */
154+
// TODO: Implement button_data_buffer as array + button_reg = button / 8
155+
for (button = 0; button < f1a->button_count; button++) {
156+
int button_shift;
157+
bool button_status;
158+
/* bit shift to get button's status */
159+
button_shift = button % 8;
160+
button_status = ((f1a->button_data_buffer >> button_shift) & 0x01) != 0;
161+
162+
rmi_dbg(RMI_DEBUG_FN, dev, "button %d (code %d) -> %d\n",
163+
button, f1a->button_map[button], button_status);
164+
/* generate an event here */
165+
input_report_key(f1a->input, f1a->button_map[button], button_status);
166+
}
167+
input_sync(f1a->input); /* sync after groups of events */
168+
169+
return IRQ_HANDLED;
170+
}
171+
172+
struct rmi_function_handler rmi_f1a_handler = {
173+
.driver = {
174+
.name = "rmi4_f1a",
175+
},
176+
.func = 0x1a,
177+
.probe = rmi_f1a_probe,
178+
.config = rmi_f1a_config,
179+
.attention = rmi_f1a_attention,
180+
};

0 commit comments

Comments
 (0)