Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <aduggan@synaptics.com>
Acked-by: Rob Herring <robh@kernel.org>
Tested-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Andrew Duggan and committed by
Dmitry Torokhov
d8a8b3ed fdf51604

+217 -5
+39
Documentation/devicetree/bindings/input/rmi4/rmi_f01.txt
··· 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 + };
+53
Documentation/devicetree/bindings/input/rmi4/rmi_i2c.txt
··· 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 + };
+1
Documentation/devicetree/bindings/vendor-prefixes.txt
··· 220 220 st STMicroelectronics 221 221 ste ST-Ericsson 222 222 stericsson ST-Ericsson 223 + syna Synaptics Inc. 223 224 synology Synology, Inc. 224 225 tbs TBS Technologies 225 226 tcl Toby Churchill Ltd.
+35
drivers/input/rmi4/rmi_bus.c
··· 153 153 return fn->fd.function_number == handler->func; 154 154 } 155 155 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 + 156 171 static int rmi_function_probe(struct device *dev) 157 172 { 158 173 struct rmi_function *fn = to_rmi_function(dev); 159 174 struct rmi_function_handler *handler = 160 175 to_rmi_function_handler(dev->driver); 161 176 int error; 177 + 178 + rmi_function_of_probe(fn); 162 179 163 180 if (handler->probe) { 164 181 error = handler->probe(fn); ··· 341 324 __rmi_unregister_function_handlers(i - 1); 342 325 return ret; 343 326 } 327 + 328 + int rmi_of_property_read_u32(struct device *dev, u32 *result, 329 + const char *prop, bool optional) 330 + { 331 + int retval; 332 + u32 val = 0; 333 + 334 + retval = of_property_read_u32(dev->of_node, prop, &val); 335 + if (retval && (!optional && retval == -EINVAL)) { 336 + dev_err(dev, "Failed to get %s value: %d\n", 337 + prop, retval); 338 + return retval; 339 + } 340 + *result = val; 341 + 342 + return 0; 343 + } 344 + EXPORT_SYMBOL_GPL(rmi_of_property_read_u32); 344 345 345 346 static int __init rmi_bus_init(void) 346 347 {
-4
drivers/input/rmi4/rmi_bus.h
··· 172 172 173 173 int rmi_of_property_read_u32(struct device *dev, u32 *result, 174 174 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); 179 175 180 176 #define RMI_DEBUG_CORE BIT(0) 181 177 #define RMI_DEBUG_XPORT BIT(1)
+28
drivers/input/rmi4/rmi_driver.c
··· 20 20 #include <linux/kconfig.h> 21 21 #include <linux/pm.h> 22 22 #include <linux/slab.h> 23 + #include <linux/of.h> 23 24 #include <uapi/linux/input.h> 24 25 #include <linux/rmi.h> 25 26 #include "rmi_bus.h" ··· 822 821 return 0; 823 822 } 824 823 824 + #ifdef CONFIG_OF 825 + static int rmi_driver_of_probe(struct device *dev, 826 + struct rmi_device_platform_data *pdata) 827 + { 828 + int retval; 829 + 830 + retval = rmi_of_property_read_u32(dev, &pdata->reset_delay_ms, 831 + "syna,reset-delay-ms", 1); 832 + if (retval) 833 + return retval; 834 + 835 + return 0; 836 + } 837 + #else 838 + static inline int rmi_driver_of_probe(struct device *dev, 839 + struct rmi_device_platform_data *pdata) 840 + { 841 + return -ENODEV; 842 + } 843 + #endif 844 + 825 845 static int rmi_driver_probe(struct device *dev) 826 846 { 827 847 struct rmi_driver *rmi_driver; ··· 867 845 rmi_dev->driver = rmi_driver; 868 846 869 847 pdata = rmi_get_platform_data(rmi_dev); 848 + 849 + if (rmi_dev->xport->dev->of_node) { 850 + retval = rmi_driver_of_probe(rmi_dev->xport->dev, pdata); 851 + if (retval) 852 + return retval; 853 + } 870 854 871 855 data = devm_kzalloc(dev, sizeof(struct rmi_driver_data), GFP_KERNEL); 872 856 if (!data)
+50
drivers/input/rmi4/rmi_f01.c
··· 247 247 return f01->properties.product_id; 248 248 } 249 249 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 + 250 294 static int rmi_f01_probe(struct rmi_function *fn) 251 295 { 252 296 struct rmi_device *rmi_dev = fn->rmi_dev; ··· 301 257 u16 ctrl_base_addr = fn->fd.control_base_addr; 302 258 u8 device_status; 303 259 u8 temp; 260 + 261 + if (fn->dev.of_node) { 262 + error = rmi_f01_of_probe(&fn->dev, pdata); 263 + if (error) 264 + return error; 265 + } 304 266 305 267 f01 = devm_kzalloc(&fn->dev, sizeof(struct f01_data), GFP_KERNEL); 306 268 if (!f01)
+11 -1
drivers/input/rmi4/rmi_i2c.c
··· 10 10 #include <linux/i2c.h> 11 11 #include <linux/rmi.h> 12 12 #include <linux/irq.h> 13 + #include <linux/of.h> 13 14 #include "rmi_driver.h" 14 15 15 16 #define BUFFER_SIZE_INCREMENT 32 ··· 208 207 return 0; 209 208 } 210 209 210 + #ifdef CONFIG_OF 211 + static const struct of_device_id rmi_i2c_of_match[] = { 212 + { .compatible = "syna,rmi4-i2c" }, 213 + {}, 214 + }; 215 + MODULE_DEVICE_TABLE(of, rmi_i2c_of_match); 216 + #endif 217 + 211 218 static int rmi_i2c_probe(struct i2c_client *client, 212 219 const struct i2c_device_id *id) 213 220 { ··· 232 223 233 224 pdata = &rmi_i2c->xport.pdata; 234 225 235 - if (client_pdata) 226 + if (!client->dev.of_node && client_pdata) 236 227 *pdata = *client_pdata; 237 228 238 229 if (client->irq > 0) ··· 381 372 .driver = { 382 373 .name = "rmi4_i2c", 383 374 .pm = &rmi_i2c_pm, 375 + .of_match_table = of_match_ptr(rmi_i2c_of_match), 384 376 }, 385 377 .id_table = rmi_id, 386 378 .probe = rmi_i2c_probe,