On Wed, Feb 05, 2014 at 12:10:16AM +0100, Christopher Heiny wrote: > On 01/23/2014 04:00 PM, Courtney Cavin wrote: > > This is pretty interesting, and looks potentially useful. I'm not very > familiar with OF/DT structures, though. What happens if there are two > different RMI4 devices in the system, each of which has its own platform > settings? > OF support will be required for most newer platforms as well as for multi-platform support. In order to support multiple devices, you just need a DT node for each device. The following is an example of two devices on the same I2C bus, with the devices called "sensor_A" and "sensor_B" at the addresses 0x2c and 0x2e respectively. i2c@0 { ... /* I2C adapter settings */ sensor_A@2c { compatible = "syn,rmi_i2c"; reg = <0x2c>; interrupts = <61 IRQ_TYPE_EDGE_FALLING>; ... /* sensor A settings */ }; sensor_B@2e { compatible = "syn,rmi_i2c"; reg = <0x2e>; interrupts = <62 IRQ_TYPE_EDGE_RISING>; ... /* sensor B settings */ } }; > > Cc: Christopher Heiny <cheiny@xxxxxxxxxxxxx> > > Cc: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx> > > Signed-off-by: Courtney Cavin <courtney.cavin@xxxxxxxxxxxxxx> > > --- > > Documentation/devicetree/bindings/input/rmi4.txt | 107 +++++++++++++++++ > > .../devicetree/bindings/vendor-prefixes.txt | 1 + > > drivers/input/rmi4/rmi_bus.c | 12 +- > > drivers/input/rmi4/rmi_bus.h | 3 +- > > drivers/input/rmi4/rmi_driver.c | 44 +++++-- > > drivers/input/rmi4/rmi_f01.c | 107 +++++++++++++++-- > > drivers/input/rmi4/rmi_f11.c | 133 ++++++++++++++++++++- > > drivers/input/rmi4/rmi_i2c.c | 19 +-- > > 8 files changed, 388 insertions(+), 38 deletions(-) > > create mode 100644 Documentation/devicetree/bindings/input/rmi4.txt > > > > diff --git a/Documentation/devicetree/bindings/input/rmi4.txt b/Documentation/devicetree/bindings/input/rmi4.txt > > new file mode 100644 > > index 0000000..fff9db7 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/input/rmi4.txt > > @@ -0,0 +1,107 @@ > > +Synaptics RMI4-based input device binding > > + > > +PROPERTIES > > + > > +compatible: > > + Usage: required > > + Type: string, must be "syn,rmi_i2c" > > + > > +interrupts: > > + Usage: required > > + Type: <prop-encoded-array> > > + Desc: See devicetree/bindings/interrupt-controller/interrupts.txt; > > + Trigger sense required in mask > > + > > +syn,reset-delay: > > + Usage: optional (default: 100) > > + Type: u32, milliseconds > > + Desc: Delay after issuing a reset > > + > > +syn,power-no-sleep: > > + Usage: optional, mutually exclusive with syn,power-sleep > > + (default: chip-specific) > > + Type: boolean > > + Desc: Disable sleep mode > > + > > +syn,power-sleep: > > + Usage: optional, mutually exclusive with syn,power-no-sleep > > + (default: chip-specific) > > + Type: boolean > > + Desc: Enable sleep mode > > + > > +syn,power-wakeup-thresh: > > + Usage: optional (default: chip-specific) > > + Type: u32, chip-specific unit [0-255] > > + Desc: Capacitance threshold at which device should wake > > + > > +syn,power-doze-holdoff: > > + Usage: optional (default: chip-specific) > > + Type: u32, milliseconds [0-25500] > > + Desc: Idle delay before entering sleep mode > > + > > +syn,power-doze-interval: > > + Usage: optional (default: chip-specific) > > + Type: u32, milliseconds [0-2550] > > + Desc: Interval between checks for idle > > + > > +syn,2d-rezero-wait: > > + Usage: optional (default: no re-zeroing) > > + Type: u32, milliseconds [0-65535] > > + Desc: Delay after resume to re-zero sensor > > + > > +syn,2d-axis-swap: > > + Usage: optional (default: false) > > + Type: boolean > > + Desc: Swap X and Y axis > > + > > +syn,2d-flip-x: > > + Usage: optional (default: false) > > + Type: boolean > > + Desc: Invert X axis > > + > > +syn,2d-flip-y: > > + Usage: optional (default: false) > > + Type: boolean > > + Desc: Invert Y axis > > + > > +syn,2d-clip-range: > > + Usage: optional (default: clip disabled) > > + Type: u32 array (<top left bottom right>) [0-65535] > > + Usage: Clip values outside this range > > + > > +syn,2d-offset: > > + Usage: optional (default: offset disabled) > > + Type: u32 array (<X-offset Y-offset>) [0-65535] > > + Usage: Add offset values to reported events > > + > > +syn,2d-delta-thresh: > > + Usage: optional (default: chip-specific) > > + Type: u32 array (<X-delta Y-delta>) [0-255] > > + Usage: Minimum delta before event is reported > > + > > +syn,2d-sensor-type: > > + Usage: optional (default: chip-specific) > > + Type: string, "indirect" or "direct" > > + Usage: Set screen type for event reporting > > + > > +syn,2d-type-a: > > + Usage: optional (default: false) > > + Type: boolean > > + Usage: Sensor supports only Multifinger Type A protocol > > + > > +EXAMPLE > > + > > +i2c@0 { > > + compatible = "..."; > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + synaptics_rmi4@2c { > > + compatible = "syn,rmi_i2c"; > > + reg = <0x2c>; > > + > > + interrupts = <61 IRQ_TYPE_EDGE_FALLING>; > > + > > + syn,2d-clip-range = <0 0 1919 1079>; > > + }; > > +}; > > diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt > > index edbb8d8..3388986 100644 > > --- a/Documentation/devicetree/bindings/vendor-prefixes.txt > > +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt > > @@ -72,6 +72,7 @@ snps Synopsys, Inc. > > st STMicroelectronics > > ste ST-Ericsson > > stericsson ST-Ericsson > > +syn Synaptics, Inc. > > ti Texas Instruments > > toshiba Toshiba Corporation > > toumaz Toumaz > > diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c > > index a51e6b4..57de579 100644 > > --- a/drivers/input/rmi4/rmi_bus.c > > +++ b/drivers/input/rmi4/rmi_bus.c > > @@ -52,14 +52,11 @@ bool rmi_is_physical_device(struct device *dev) > > int rmi_register_transport_device(struct rmi_transport_dev *xport) > > { > > static atomic_t transport_device_count = ATOMIC_INIT(0); > > - struct rmi_device_platform_data *pdata = xport->dev->platform_data; > > struct rmi_device *rmi_dev; > > int error; > > > > - if (!pdata) { > > - dev_err(xport->dev, "no platform data!\n"); > > - return -EINVAL; > > - } > > + if (unlikely(!rmi_bus_type.p)) > > + return -EPROBE_DEFER; > > > > rmi_dev = kzalloc(sizeof(struct rmi_device), GFP_KERNEL); > > if (!rmi_dev) > > @@ -70,8 +67,10 @@ int rmi_register_transport_device(struct rmi_transport_dev *xport) > > > > dev_set_name(&rmi_dev->dev, "sensor%02d", rmi_dev->number); > > > > + rmi_dev->dev.parent = xport->dev; > > rmi_dev->dev.bus = &rmi_bus_type; > > rmi_dev->dev.type = &rmi_device_type; > > + rmi_dev->dev.of_node = xport->dev->of_node; > > > > xport->rmi_dev = rmi_dev; > > > > @@ -206,6 +205,9 @@ int __rmi_register_function_handler(struct rmi_function_handler *handler, > > struct device_driver *driver = &handler->driver; > > int error; > > > > + if (WARN_ON(unlikely(!rmi_bus_type.p))) > > + return -EAGAIN; > > + > > driver->bus = &rmi_bus_type; > > driver->owner = owner; > > driver->mod_name = mod_name; > > diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h > > index a21e4c4..51f9372 100644 > > --- a/drivers/input/rmi4/rmi_bus.h > > +++ b/drivers/input/rmi4/rmi_bus.h > > @@ -212,7 +212,8 @@ struct rmi_device { > > }; > > > > #define to_rmi_device(d) container_of(d, struct rmi_device, dev) > > -#define to_rmi_platform_data(d) ((d)->xport->dev->platform_data) > > +#define to_rmi_xport_device(d) ((d)->xport->dev) > > +#define to_rmi_platform_data(d) (dev_get_platdata(to_rmi_xport_device(d))) > > > > bool rmi_is_physical_device(struct device *dev); > > > > diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c > > index 9ec7b93..92415ce 100644 > > --- a/drivers/input/rmi4/rmi_driver.c > > +++ b/drivers/input/rmi4/rmi_driver.c > > @@ -26,6 +26,8 @@ > > #include <linux/rmi.h> > > #include <linux/slab.h> > > #include <linux/uaccess.h> > > +#include <linux/of_irq.h> > > +#include <linux/of.h> > > #include <uapi/linux/input.h> > > #include "rmi_bus.h" > > #include "rmi_driver.h" > > @@ -498,7 +500,7 @@ static int create_function(struct rmi_device *rmi_dev, > > * We have to do this before actually building the PDT because the reflash > > * updates (if any) might cause various registers to move around. > > */ > > -static int rmi_initial_reset(struct rmi_device *rmi_dev) > > +static int rmi_initial_reset(struct rmi_device *rmi_dev, u32 reset_delay) > > { > > struct pdt_entry pdt_entry; > > int page; > > @@ -507,8 +509,6 @@ static int rmi_initial_reset(struct rmi_device *rmi_dev) > > bool has_f01 = false; > > int i; > > int retval; > > - const struct rmi_device_platform_data *pdata = > > - to_rmi_platform_data(rmi_dev); > > > > dev_dbg(dev, "Initial reset.\n"); > > > > @@ -538,7 +538,7 @@ static int rmi_initial_reset(struct rmi_device *rmi_dev) > > retval); > > return retval; > > } > > - mdelay(pdata->reset_delay_ms); > > + mdelay(reset_delay); > > done = true; > > has_f01 = true; > > break; > > @@ -648,6 +648,8 @@ static int rmi_driver_probe(struct device *dev) > > struct rmi_device_platform_data *pdata; > > int retval = 0; > > struct rmi_device *rmi_dev; > > + unsigned int irq; > > + u32 reset_delay; > > > > dev_dbg(dev, "%s: Starting probe.\n", __func__); > > > > @@ -661,6 +663,28 @@ static int rmi_driver_probe(struct device *dev) > > rmi_dev->driver = rmi_driver; > > > > pdata = to_rmi_platform_data(rmi_dev); > > + if (pdata == NULL) { > > +#ifdef CONFIG_OF > > + const char *p; > > + > > + p = "syn,reset-delay"; > > + retval = of_property_read_u32(dev->of_node, p, &reset_delay); > > + if (retval && retval != -EINVAL) { > > + dev_err(dev, "Invalid '%s' property\n", p); > > + return -EINVAL; > > + } > > + if (retval == -EINVAL) > > + reset_delay = 0; > > + > > + irq = irq_of_parse_and_map(dev->of_node, 0); > > +#else > > + dev_err(dev, "No pdata\n"); > > + return -EINVAL; > > +#endif > > + } else { > > + reset_delay = pdata->reset_delay_ms; > > + irq = pdata->irq; > > + } > > > > data = devm_kzalloc(dev, sizeof(struct rmi_driver_data), GFP_KERNEL); > > if (!data) { > > @@ -688,9 +712,9 @@ static int rmi_driver_probe(struct device *dev) > > * and leave the customer's device unusable. So we warn them, and > > * continue processing. > > */ > > - if (!pdata->reset_delay_ms) > > - pdata->reset_delay_ms = DEFAULT_RESET_DELAY_MS; > > - retval = rmi_initial_reset(rmi_dev); > > + if (!reset_delay) > > + reset_delay = DEFAULT_RESET_DELAY_MS; > > + retval = rmi_initial_reset(rmi_dev, reset_delay); > > if (retval) > > dev_warn(dev, "RMI initial reset failed! Continuing in spite of this.\n"); > > > > @@ -762,10 +786,10 @@ static int rmi_driver_probe(struct device *dev) > > goto err_free_data; > > } > > > > - data->irq = pdata->irq; > > - if (data->irq < 0) { > > + data->irq = irq; > > + if (data->irq < 0 || data->irq == NO_IRQ) { > > dev_err(dev, "Failed to get attn IRQ.\n"); > > - retval = data->irq; > > + retval = -EINVAL; > > goto err_free_data; > > > > } > > diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c > > index 4cb9fcb..22b57f2 100644 > > --- a/drivers/input/rmi4/rmi_f01.c > > +++ b/drivers/input/rmi4/rmi_f01.c > > @@ -12,6 +12,7 @@ > > #include <linux/rmi.h> > > #include <linux/slab.h> > > #include <linux/uaccess.h> > > +#include <linux/of.h> > > #include "rmi_driver.h" > > > > #define RMI_PRODUCT_ID_LENGTH 10 > > @@ -169,15 +170,104 @@ static int rmi_f01_read_properties(struct rmi_device *rmi_dev, > > return 0; > > } > > > > +#ifdef CONFIG_OF > > +static int rmi_f01_of_parse(struct device *dev, > > + struct rmi_f01_power_management *cdata) > > +{ > > + bool sleep, nosleep; > > + const char *p; > > + u32 val; > > + int rc; > > + > > + if (dev->of_node == NULL) > > + return -EINVAL; > > + > > + memset(cdata, 0, sizeof(*cdata)); > > + > > + sleep = of_property_read_bool(dev->of_node, "syn,power-sleep"); > > + nosleep = of_property_read_bool(dev->of_node, "syn,power-nosleep"); > > + if (sleep && nosleep) { > > + dev_err(dev, "'syn,power-sleep' and 'syn,power-nosleep' are mutually exclusive\n"); > > + return -EINVAL; > > + } > > + if (sleep) > > + cdata->nosleep = RMI_F01_NOSLEEP_OFF; > > + else if (nosleep) > > + cdata->nosleep = RMI_F01_NOSLEEP_ON; > > + > > + p = "syn,power-wakeup-thresh"; > > + rc = of_property_read_u32(dev->of_node, p, &val); > > + if (rc && rc != -EINVAL) { > > + dev_err(dev, "Invalid '%s' property\n", p); > > + return rc; > > + } > > + if (rc != -EINVAL) { > > + if (val & ~0xff) { > > + dev_err(dev, "'%s' out of range [0-255]\n", p); > > + return -EINVAL; > > + } > > + cdata->wakeup_threshold = val; > > + } > > + > > + p = "syn,power-doze-holdoff"; > > + rc = of_property_read_u32(dev->of_node, p, &val); > > + if (rc && rc != -EINVAL) { > > + dev_err(dev, "Invalid '%s' property\n", p); > > + return rc; > > + } > > + if (rc != -EINVAL) { > > + if (val > 25500) { > > + dev_err(dev, "'%s' out of range [0-25500]ms\n", p); > > + return -EINVAL; > > + } > > + cdata->doze_holdoff = (val + 50) / 100; > > + } > > + > > + p = "syn,power-doze-interval"; > > + rc = of_property_read_u32(dev->of_node, p, &val); > > + if (rc && rc != -EINVAL) { > > + dev_err(dev, "Invalid '%s' property\n", p); > > + return rc; > > + } > > + if (rc != -EINVAL) { > > + if (val > 2550) { > > + dev_err(dev, "'%s' out of range [0-2550]ms\n", p); > > + return -EINVAL; > > + } > > + cdata->doze_interval = (val + 5) / 10; > > + } > > + > > + return 0; > > +} > > +#else > > +static int rmi_f01_of_parse(struct device *dev, > > + struct rmi_f01_power_management *cdata) > > +{ > > + return -EINVAL; > > +} > > +#endif > > + > > static int rmi_f01_initialize(struct rmi_function *fn) > > { > > u8 temp; > > int error; > > u16 ctrl_base_addr; > > + struct rmi_f01_power_management cdata; > > struct rmi_device *rmi_dev = fn->rmi_dev; > > + struct device *dev = to_rmi_xport_device(rmi_dev); > > struct rmi_driver_data *driver_data = dev_get_drvdata(&rmi_dev->dev); > > struct f01_data *data = fn->data; > > - struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev); > > + struct rmi_device_platform_data *pdata = dev_get_platdata(dev); > > + > > + if (pdata != NULL) { > > + cdata = pdata->power_management; > > + } else { > > + error = rmi_f01_of_parse(dev, &cdata); > > + if (error) { > > + dev_err(dev, "Unable to parse DT data\n"); > > + return error; > > + } > > + } > > > > /* > > * Set the configured bit and (optionally) other important stuff > > @@ -191,7 +281,7 @@ static int rmi_f01_initialize(struct rmi_function *fn) > > dev_err(&fn->dev, "Failed to read F01 control.\n"); > > return error; > > } > > - switch (pdata->power_management.nosleep) { > > + switch (cdata.nosleep) { > > case RMI_F01_NOSLEEP_DEFAULT: > > break; > > case RMI_F01_NOSLEEP_OFF: > > @@ -262,9 +352,9 @@ static int rmi_f01_initialize(struct rmi_function *fn) > > data->doze_interval_addr = ctrl_base_addr; > > ctrl_base_addr++; > > > > - if (pdata->power_management.doze_interval) { > > + if (cdata.doze_interval) { > > data->device_control.doze_interval = > > - pdata->power_management.doze_interval; > > + cdata.doze_interval; > > error = rmi_write(rmi_dev, data->doze_interval_addr, > > data->device_control.doze_interval); > > if (error < 0) { > > @@ -283,9 +373,9 @@ static int rmi_f01_initialize(struct rmi_function *fn) > > data->wakeup_threshold_addr = ctrl_base_addr; > > ctrl_base_addr++; > > > > - if (pdata->power_management.wakeup_threshold) { > > + if (cdata.wakeup_threshold) { > > data->device_control.wakeup_threshold = > > - pdata->power_management.wakeup_threshold; > > + cdata.wakeup_threshold; > > error = rmi_write(rmi_dev, data->wakeup_threshold_addr, > > data->device_control.wakeup_threshold); > > if (error < 0) { > > @@ -306,9 +396,8 @@ static int rmi_f01_initialize(struct rmi_function *fn) > > data->doze_holdoff_addr = ctrl_base_addr; > > ctrl_base_addr++; > > > > - if (pdata->power_management.doze_holdoff) { > > - data->device_control.doze_holdoff = > > - pdata->power_management.doze_holdoff; > > + if (cdata.doze_holdoff) { > > + data->device_control.doze_holdoff = cdata.doze_holdoff; > > error = rmi_write(rmi_dev, data->doze_holdoff_addr, > > data->device_control.doze_holdoff); > > if (error < 0) { > > diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c > > index b114f25..837b6e7 100644 > > --- a/drivers/input/rmi4/rmi_f11.c > > +++ b/drivers/input/rmi4/rmi_f11.c > > @@ -13,6 +13,7 @@ > > #include <linux/input.h> > > #include <linux/input/mt.h> > > #include <linux/kconfig.h> > > +#include <linux/of.h> > > #include <linux/rmi.h> > > #include <linux/slab.h> > > #include "rmi_driver.h" > > @@ -794,9 +795,120 @@ static void f11_set_abs_params(struct rmi_function *fn) > > 0, MT_TOOL_FINGER, 0, 0); > > } > > > > +#ifdef CONFIG_OF > > +static int rmi_f11_of_parse(struct device *dev, > > + struct rmi_f11_sensor_data *cdata) > > +{ > > + const char *type; > > + const char *p; > > + u32 a[4]; > > + int rc; > > + > > + if (dev->of_node == NULL) > > + return -EINVAL; > > + > > + memset(cdata, 0, sizeof(*cdata)); > > + > > + p = "syn,2d-rezero-wait"; > > + rc = of_property_read_u32(dev->of_node, p, &a[0]); > > + if (rc && rc != -EINVAL) { > > + dev_err(dev, "Invalid '%s' property\n", p); > > + return rc; > > + } > > + if (rc != -EINVAL) { > > + if (a[0] & ~0xffff) { > > + dev_err(dev, "'%s' value out of range [0-65535]\n", p); > > + return -EINVAL; > > + } > > + cdata->rezero_wait = a[0]; > > + } > > + > > + cdata->type_a = of_property_read_bool(dev->of_node, "syn,2d-type-a"); > > + cdata->axis_align.swap_axes = of_property_read_bool(dev->of_node, > > + "syn,2d-axis-swap"); > > + cdata->axis_align.flip_x = of_property_read_bool(dev->of_node, > > + "syn,2d-flip-x"); > > + cdata->axis_align.flip_y = of_property_read_bool(dev->of_node, > > + "syn,2d-flip-y"); > > + > > + p = "syn-2d-clip-range"; > > + rc = of_property_read_u32_array(dev->of_node, p, a, 4); > > + if (rc && rc != -EINVAL) { > > + dev_err(dev, "Invalid '%s' property\n", p); > > + return rc; > > + } > > + if (rc != -EINVAL) { > > + if ((a[0] | a[1] | a[2] | a[3]) & ~0xffff) { > > + dev_err(dev, "'%s' values out of range [0-65535]\n", p); > > + return -EINVAL; > > + } > > + cdata->axis_align.clip_x_low = a[0]; > > + cdata->axis_align.clip_y_low = a[1]; > > + cdata->axis_align.clip_x_high = a[2]; > > + cdata->axis_align.clip_y_high = a[3]; > > + } > > + > > + p = "syn-2d-offset"; > > + rc = of_property_read_u32_array(dev->of_node, p, a, 2); > > + if (rc && rc != -EINVAL) { > > + dev_err(dev, "Invalid '%s' property\n", p); > > + return rc; > > + } > > + if (rc != -EINVAL) { > > + if ((a[0] | a[1]) & ~0xffff) { > > + dev_err(dev, "'%s' values out of range [0-65535]\n", p); > > + return -EINVAL; > > + } > > + cdata->axis_align.offset_x = a[0]; > > + cdata->axis_align.offset_y = a[1]; > > + } > > + > > + p = "syn,2d-delta-thresh"; > > + rc = of_property_read_u32_array(dev->of_node, p, a, 2); > > + if (rc && rc != -EINVAL) { > > + dev_err(dev, "Invalid '%s' property\n", p); > > + return rc; > > + } > > + if (rc != -EINVAL) { > > + if ((a[0] | a[1]) & ~0xff) { > > + dev_err(dev, "'%s' values out of range [0-255]\n", p); > > + return -EINVAL; > > + } > > + cdata->axis_align.delta_x_threshold = a[0]; > > + cdata->axis_align.delta_y_threshold = a[1]; > > + } > > + > > + p = "syn,2d-sensor-type"; > > + rc = of_property_read_string(dev->of_node, p, &type); > > + if (rc && rc != -EINVAL) { > > + dev_err(dev, "Invalid '%s' property\n", p); > > + return rc; > > + } > > + if (rc != -EINVAL) { > > + if (!strcmp(type, "direct")) { > > + cdata->sensor_type = RMI_F11_SENSOR_DIRECT; > > + } else if (!strcmp(type, "indirect")) { > > + cdata->sensor_type = RMI_F11_SENSOR_INDIRECT; > > + } else { > > + dev_err(dev, "'%s' must be one of: \"indirect\", \"direct\"\n", p); > > + return -EINVAL; > > + } > > + } > > + > > + return 0; > > +} > > +#else > > +static int rmi_f11_of_parse(struct device *dev, > > + struct rmi_f11_sensor_data *cdata) > > +{ > > + return -EINVAL; > > +} > > +#endif > > + > > static int rmi_f11_initialize(struct rmi_function *fn) > > { > > struct rmi_device *rmi_dev = fn->rmi_dev; > > + struct device *dev = to_rmi_xport_device(rmi_dev); > > struct f11_data *f11; > > struct f11_2d_ctrl *ctrl; > > u8 query_offset; > > @@ -804,12 +916,23 @@ static int rmi_f11_initialize(struct rmi_function *fn) > > u16 control_base_addr; > > u16 max_x_pos, max_y_pos, temp; > > int rc; > > - struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev); > > + struct rmi_device_platform_data *pdata = dev_get_platdata(dev); > > + struct rmi_f11_sensor_data cdata; > > struct f11_2d_sensor *sensor; > > u8 buf; > > > > dev_dbg(&fn->dev, "Initializing F11 values.\n"); > > > > + if (pdata != NULL) { > > + cdata = pdata->f11_sensor_data; > > + } else { > > + rc = rmi_f11_of_parse(dev, &cdata); > > + if (rc) { > > + dev_err(dev, "Unable to parse DT data\n"); > > + return rc; > > + } > > + } > > + > > /* > > ** init instance data, fill in values and create any sysfs files > > */ > > @@ -818,7 +941,7 @@ static int rmi_f11_initialize(struct rmi_function *fn) > > return -ENOMEM; > > > > fn->data = f11; > > - f11->rezero_wait_ms = pdata->f11_sensor_data.rezero_wait; > > + f11->rezero_wait_ms = cdata.rezero_wait; > > > > query_base_addr = fn->fd.query_base_addr; > > control_base_addr = fn->fd.control_base_addr; > > @@ -851,9 +974,9 @@ static int rmi_f11_initialize(struct rmi_function *fn) > > return rc; > > } > > > > - sensor->axis_align = pdata->f11_sensor_data.axis_align; > > - sensor->type_a = pdata->f11_sensor_data.type_a; > > - sensor->sensor_type = pdata->f11_sensor_data.sensor_type; > > + sensor->axis_align = cdata.axis_align; > > + sensor->type_a = cdata.type_a; > > + sensor->sensor_type = cdata.sensor_type; > > > > rc = rmi_read_block(rmi_dev, > > control_base_addr + F11_CTRL_SENSOR_MAX_X_POS_OFFSET, > > diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c > > index aebf974..377d4cc 100644 > > --- a/drivers/input/rmi4/rmi_i2c.c > > +++ b/drivers/input/rmi4/rmi_i2c.c > > @@ -186,16 +186,9 @@ static const struct rmi_transport_ops rmi_i2c_ops = { > > static int rmi_i2c_probe(struct i2c_client *client, > > const struct i2c_device_id *id) > > { > > - const struct rmi_device_platform_data *pdata = > > - dev_get_platdata(&client->dev); > > struct rmi_i2c_xport *rmi_i2c; > > int retval; > > > > - if (!pdata) { > > - dev_err(&client->dev, "no platform data\n"); > > - return -EINVAL; > > - } > > - > > dev_dbg(&client->dev, "Probing %#02x.\n", client->addr); > > > > if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { > > @@ -258,10 +251,20 @@ static const struct i2c_device_id rmi_id[] = { > > }; > > MODULE_DEVICE_TABLE(i2c, rmi_id); > > > > +#ifdef CONFIG_OF > > +static struct of_device_id rmi_match_table[] = { > > + { .compatible = "syn,rmi_i2c", }, > > + { }, > > +}; > > +#else > > +#define rmi_match_table NULL > > +#endif > > + > > static struct i2c_driver rmi_i2c_driver = { > > .driver = { > > .owner = THIS_MODULE, > > - .name = "rmi_i2c" > > + .name = "rmi_i2c", > > + .of_match_table = rmi_match_table, > > }, > > .id_table = rmi_id, > > .probe = rmi_i2c_probe, > > -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html