Skip to content

Commit d8a8b3e

Browse files
aduggan-synadtor
authored andcommitted
Input: synaptics-rmi4 - add device tree support for RMI4 I2C devices
Add devicetree binding for I2C devices and add bindings for optional parameters in the function drivers. Parameters for function drivers are defined in child nodes for each of the functions. Signed-off-by: Andrew Duggan <[email protected]> Acked-by: Rob Herring <[email protected]> Tested-by: Benjamin Tissoires <[email protected]> Tested-by: Linus Walleij <[email protected]> Tested-by: Bjorn Andersson <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent fdf5160 commit d8a8b3e

File tree

8 files changed

+217
-5
lines changed

8 files changed

+217
-5
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Synaptics RMI4 F01 Device Binding
2+
3+
The Synaptics RMI4 core is able to support RMI4 devices using different
4+
transports and different functions. This file describes the device tree
5+
bindings for devices which contain Function 1. Complete documentation
6+
for transports and other functions can be found in:
7+
Documentation/devicetree/bindings/input/rmi4.
8+
9+
Additional documentation for F01 can be found at:
10+
http://www.synaptics.com/sites/default/files/511-000136-01-Rev-E-RMI4-Interfacing-Guide.pdf
11+
12+
Optional Properties:
13+
- syna,nosleep-mode: If set the device will run at full power without sleeping.
14+
nosleep has 3 modes, 0 will not change the default
15+
setting, 1 will disable nosleep (allow sleeping),
16+
and 2 will enable nosleep (disabling sleep).
17+
- syna,wakeup-threshold: Defines the amplitude of the disturbance to the
18+
background capacitance that will cause the
19+
device to wake from dozing.
20+
- syna,doze-holdoff-ms: The delay to wait after the last finger lift and the
21+
first doze cycle.
22+
- syna,doze-interval-ms: The time period that the device sleeps between finger
23+
activity.
24+
25+
26+
Example of a RMI4 I2C device with F01:
27+
Example:
28+
&i2c1 {
29+
rmi4-i2c-dev@2c {
30+
compatible = "syna,rmi4-i2c";
31+
32+
...
33+
34+
rmi4-f01@1 {
35+
reg = <0x1>;
36+
syna,nosleep-mode = <1>;
37+
};
38+
};
39+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
Synaptics RMI4 I2C Device Binding
2+
3+
The Synaptics RMI4 core is able to support RMI4 devices using different
4+
transports and different functions. This file describes the device tree
5+
bindings for devices using the I2C transport driver. Complete documentation
6+
for other transports and functions can be found in
7+
Documentation/devicetree/bindings/input/rmi4.
8+
9+
Required Properties:
10+
- compatible: syna,rmi4-i2c
11+
- reg: I2C address
12+
- #address-cells: Set to 1 to indicate that the function child nodes
13+
consist of only on uint32 value.
14+
- #size-cells: Set to 0 to indicate that the function child nodes do not
15+
have a size property.
16+
17+
Optional Properties:
18+
- interrupts: interrupt which the rmi device is connected to.
19+
- interrupt-parent: The interrupt controller.
20+
See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
21+
22+
- syna,reset-delay-ms: The number of milliseconds to wait after resetting the
23+
device.
24+
25+
Function Parameters:
26+
Parameters specific to RMI functions are contained in child nodes of the rmi device
27+
node. Documentation for the parameters of each function can be found in:
28+
Documentation/devicetree/bindings/input/rmi4/rmi_f*.txt.
29+
30+
31+
32+
Example:
33+
&i2c1 {
34+
rmi4-i2c-dev@2c {
35+
compatible = "syna,rmi4-i2c";
36+
reg = <0x2c>;
37+
#address-cells = <1>;
38+
#size-cells = <0>;
39+
interrupt-parent = <&gpio>;
40+
interrupts = <4 2>;
41+
42+
rmi4-f01@1 {
43+
reg = <0x1>;
44+
syna,nosleep-mode = <1>;
45+
};
46+
47+
rmi4-f11@11 {
48+
reg = <0x11>;
49+
touchscreen-inverted-y;
50+
syna,sensor-type = <2>;
51+
};
52+
};
53+
};

Documentation/devicetree/bindings/vendor-prefixes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ sprd Spreadtrum Communications Inc.
220220
st STMicroelectronics
221221
ste ST-Ericsson
222222
stericsson ST-Ericsson
223+
syna Synaptics Inc.
223224
synology Synology, Inc.
224225
tbs TBS Technologies
225226
tcl Toby Churchill Ltd.

drivers/input/rmi4/rmi_bus.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,30 @@ static int rmi_function_match(struct device *dev, struct device_driver *drv)
153153
return fn->fd.function_number == handler->func;
154154
}
155155

156+
#ifdef CONFIG_OF
157+
static void rmi_function_of_probe(struct rmi_function *fn)
158+
{
159+
char of_name[9];
160+
161+
snprintf(of_name, sizeof(of_name), "rmi4-f%02x",
162+
fn->fd.function_number);
163+
fn->dev.of_node = of_find_node_by_name(
164+
fn->rmi_dev->xport->dev->of_node, of_name);
165+
}
166+
#else
167+
static inline void rmi_function_of_probe(struct rmi_function *fn)
168+
{}
169+
#endif
170+
156171
static int rmi_function_probe(struct device *dev)
157172
{
158173
struct rmi_function *fn = to_rmi_function(dev);
159174
struct rmi_function_handler *handler =
160175
to_rmi_function_handler(dev->driver);
161176
int error;
162177

178+
rmi_function_of_probe(fn);
179+
163180
if (handler->probe) {
164181
error = handler->probe(fn);
165182
return error;
@@ -325,6 +342,24 @@ static int rmi_register_function_handlers(void)
325342
return ret;
326343
}
327344

345+
int rmi_of_property_read_u32(struct device *dev, u32 *result,
346+
const char *prop, bool optional)
347+
{
348+
int retval;
349+
u32 val = 0;
350+
351+
retval = of_property_read_u32(dev->of_node, prop, &val);
352+
if (retval && (!optional && retval == -EINVAL)) {
353+
dev_err(dev, "Failed to get %s value: %d\n",
354+
prop, retval);
355+
return retval;
356+
}
357+
*result = val;
358+
359+
return 0;
360+
}
361+
EXPORT_SYMBOL_GPL(rmi_of_property_read_u32);
362+
328363
static int __init rmi_bus_init(void)
329364
{
330365
int error;

drivers/input/rmi4/rmi_bus.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,6 @@ extern struct bus_type rmi_bus_type;
172172

173173
int rmi_of_property_read_u32(struct device *dev, u32 *result,
174174
const char *prop, bool optional);
175-
int rmi_of_property_read_u16(struct device *dev, u16 *result,
176-
const char *prop, bool optional);
177-
int rmi_of_property_read_u8(struct device *dev, u8 *result,
178-
const char *prop, bool optional);
179175

180176
#define RMI_DEBUG_CORE BIT(0)
181177
#define RMI_DEBUG_XPORT BIT(1)

drivers/input/rmi4/rmi_driver.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/kconfig.h>
2121
#include <linux/pm.h>
2222
#include <linux/slab.h>
23+
#include <linux/of.h>
2324
#include <uapi/linux/input.h>
2425
#include <linux/rmi.h>
2526
#include "rmi_bus.h"
@@ -821,6 +822,27 @@ static int rmi_driver_remove(struct device *dev)
821822
return 0;
822823
}
823824

825+
#ifdef CONFIG_OF
826+
static int rmi_driver_of_probe(struct device *dev,
827+
struct rmi_device_platform_data *pdata)
828+
{
829+
int retval;
830+
831+
retval = rmi_of_property_read_u32(dev, &pdata->reset_delay_ms,
832+
"syna,reset-delay-ms", 1);
833+
if (retval)
834+
return retval;
835+
836+
return 0;
837+
}
838+
#else
839+
static inline int rmi_driver_of_probe(struct device *dev,
840+
struct rmi_device_platform_data *pdata)
841+
{
842+
return -ENODEV;
843+
}
844+
#endif
845+
824846
static int rmi_driver_probe(struct device *dev)
825847
{
826848
struct rmi_driver *rmi_driver;
@@ -846,6 +868,12 @@ static int rmi_driver_probe(struct device *dev)
846868

847869
pdata = rmi_get_platform_data(rmi_dev);
848870

871+
if (rmi_dev->xport->dev->of_node) {
872+
retval = rmi_driver_of_probe(rmi_dev->xport->dev, pdata);
873+
if (retval)
874+
return retval;
875+
}
876+
849877
data = devm_kzalloc(dev, sizeof(struct rmi_driver_data), GFP_KERNEL);
850878
if (!data)
851879
return -ENOMEM;

drivers/input/rmi4/rmi_f01.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,50 @@ char *rmi_f01_get_product_ID(struct rmi_function *fn)
247247
return f01->properties.product_id;
248248
}
249249

250+
#ifdef CONFIG_OF
251+
static int rmi_f01_of_probe(struct device *dev,
252+
struct rmi_device_platform_data *pdata)
253+
{
254+
int retval;
255+
u32 val;
256+
257+
retval = rmi_of_property_read_u32(dev,
258+
(u32 *)&pdata->power_management.nosleep,
259+
"syna,nosleep-mode", 1);
260+
if (retval)
261+
return retval;
262+
263+
retval = rmi_of_property_read_u32(dev, &val,
264+
"syna,wakeup-threshold", 1);
265+
if (retval)
266+
return retval;
267+
268+
pdata->power_management.wakeup_threshold = val;
269+
270+
retval = rmi_of_property_read_u32(dev, &val,
271+
"syna,doze-holdoff-ms", 1);
272+
if (retval)
273+
return retval;
274+
275+
pdata->power_management.doze_holdoff = val * 100;
276+
277+
retval = rmi_of_property_read_u32(dev, &val,
278+
"syna,doze-interval-ms", 1);
279+
if (retval)
280+
return retval;
281+
282+
pdata->power_management.doze_interval = val / 10;
283+
284+
return 0;
285+
}
286+
#else
287+
static inline int rmi_f01_of_probe(struct device *dev,
288+
struct rmi_device_platform_data *pdata)
289+
{
290+
return -ENODEV;
291+
}
292+
#endif
293+
250294
static int rmi_f01_probe(struct rmi_function *fn)
251295
{
252296
struct rmi_device *rmi_dev = fn->rmi_dev;
@@ -258,6 +302,12 @@ static int rmi_f01_probe(struct rmi_function *fn)
258302
u8 device_status;
259303
u8 temp;
260304

305+
if (fn->dev.of_node) {
306+
error = rmi_f01_of_probe(&fn->dev, pdata);
307+
if (error)
308+
return error;
309+
}
310+
261311
f01 = devm_kzalloc(&fn->dev, sizeof(struct f01_data), GFP_KERNEL);
262312
if (!f01)
263313
return -ENOMEM;

drivers/input/rmi4/rmi_i2c.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/i2c.h>
1111
#include <linux/rmi.h>
1212
#include <linux/irq.h>
13+
#include <linux/of.h>
1314
#include "rmi_driver.h"
1415

1516
#define BUFFER_SIZE_INCREMENT 32
@@ -207,6 +208,14 @@ static int rmi_i2c_init_irq(struct i2c_client *client)
207208
return 0;
208209
}
209210

211+
#ifdef CONFIG_OF
212+
static const struct of_device_id rmi_i2c_of_match[] = {
213+
{ .compatible = "syna,rmi4-i2c" },
214+
{},
215+
};
216+
MODULE_DEVICE_TABLE(of, rmi_i2c_of_match);
217+
#endif
218+
210219
static int rmi_i2c_probe(struct i2c_client *client,
211220
const struct i2c_device_id *id)
212221
{
@@ -223,7 +232,7 @@ static int rmi_i2c_probe(struct i2c_client *client,
223232

224233
pdata = &rmi_i2c->xport.pdata;
225234

226-
if (client_pdata)
235+
if (!client->dev.of_node && client_pdata)
227236
*pdata = *client_pdata;
228237

229238
if (client->irq > 0)
@@ -372,6 +381,7 @@ static struct i2c_driver rmi_i2c_driver = {
372381
.driver = {
373382
.name = "rmi4_i2c",
374383
.pm = &rmi_i2c_pm,
384+
.of_match_table = of_match_ptr(rmi_i2c_of_match),
375385
},
376386
.id_table = rmi_id,
377387
.probe = rmi_i2c_probe,

0 commit comments

Comments
 (0)