From: Christopher Heiny <cheiny@synaptics.com>
To: Courtney Cavin <courtney.cavin@sonymobile.com>,
linux-input@vger.kernel.org
Cc: dmitry.torokhov@gmail.com
Subject: Re: [PATCH 10/15] Input: synaptics-rmi4 - add devicetree support
Date: Tue, 4 Feb 2014 15:10:16 -0800 [thread overview]
Message-ID: <52F17358.6060704@synaptics.com> (raw)
In-Reply-To: <1390521623-6491-11-git-send-email-courtney.cavin@sonymobile.com>
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?
> Cc: Christopher Heiny <cheiny@synaptics.com>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Signed-off-by: Courtney Cavin <courtney.cavin@sonymobile.com>
> ---
> 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,
>
--
Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
next prev parent reply other threads:[~2014-02-04 23:10 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-24 0:00 [PATCH 00/15] Input: synaptics-rmi4 - cleanup and add DT support Courtney Cavin
2014-01-24 0:00 ` [PATCH 01/15] Input: synaptics-rmi4 - fix checkpatch.pl, sparse and GCC warnings Courtney Cavin
2014-01-24 0:00 ` [PATCH 02/15] Input: synaptics-rmi4 - don't kfree devm_ alloced memory Courtney Cavin
2014-01-24 0:00 ` [PATCH 03/15] Input: synaptics-rmi4 - don't free devices directly Courtney Cavin
2014-01-24 0:00 ` [PATCH 04/15] Input: synaptics-rmi4 - remove sensor name from platform data Courtney Cavin
2014-01-24 0:00 ` [PATCH 05/15] Input: synaptics-rmi4 - remove gpio handling and polling Courtney Cavin
2014-01-24 0:00 ` [PATCH 06/15] Input: synaptics-rmi4 - remove platform suspend callbacks Courtney Cavin
2014-01-24 0:00 ` [PATCH 07/15] Input: synaptics-rmi4 - remove remaining debugfs code Courtney Cavin
2014-01-24 0:00 ` [PATCH 08/15] Input: synaptics-rmi4 - cleanup platform data Courtney Cavin
2014-01-24 0:00 ` [PATCH 09/15] Input: synaptics-rmi4 - remove unused defines and variables Courtney Cavin
2014-01-24 0:00 ` [PATCH 10/15] Input: synaptics-rmi4 - add devicetree support Courtney Cavin
2014-01-24 0:00 ` [PATCH 11/15] Input: synaptics-rmi4 - add regulator support Courtney Cavin
2014-01-24 0:00 ` [PATCH 12/15] Input: synaptics-rmi4 - don't immediately set page on probe Courtney Cavin
2014-01-24 0:00 ` [PATCH 13/15] Input: synaptics-rmi4 - properly set F01 container on PDT scan Courtney Cavin
2014-01-24 0:00 ` [PATCH 14/15] Input: synaptics-rmi4 - ensure we have IRQs before reading status Courtney Cavin
2014-01-24 0:00 ` [PATCH 15/15] Input: synaptics-rmi4 - correct RMI4 spec url Courtney Cavin
2014-02-04 23:10 ` Christopher Heiny
2014-02-06 1:14 ` Dmitry Torokhov
2014-02-04 23:10 ` [PATCH 14/15] Input: synaptics-rmi4 - ensure we have IRQs before reading status Christopher Heiny
2014-02-05 2:40 ` Courtney Cavin
2014-02-04 23:10 ` [PATCH 13/15] Input: synaptics-rmi4 - properly set F01 container on PDT scan Christopher Heiny
2014-02-05 2:39 ` Courtney Cavin
2014-02-04 23:10 ` [PATCH 11/15] Input: synaptics-rmi4 - add regulator support Christopher Heiny
2014-02-05 2:38 ` Courtney Cavin
2014-02-04 23:10 ` Christopher Heiny [this message]
2014-02-05 2:37 ` [PATCH 10/15] Input: synaptics-rmi4 - add devicetree support Courtney Cavin
2014-02-04 23:10 ` [PATCH 09/15] Input: synaptics-rmi4 - remove unused defines and variables Christopher Heiny
2014-02-05 2:35 ` Courtney Cavin
2014-02-04 23:10 ` [PATCH 08/15] Input: synaptics-rmi4 - cleanup platform data Christopher Heiny
2014-02-05 2:34 ` Courtney Cavin
2014-02-04 23:09 ` [PATCH 07/15] Input: synaptics-rmi4 - remove remaining debugfs code Christopher Heiny
2014-02-05 2:33 ` Courtney Cavin
2014-02-04 23:09 ` [PATCH 06/15] Input: synaptics-rmi4 - remove platform suspend callbacks Christopher Heiny
2014-02-05 2:32 ` Courtney Cavin
2014-02-04 23:08 ` [PATCH 05/15] Input: synaptics-rmi4 - remove gpio handling and polling Christopher Heiny
2014-02-05 2:31 ` Courtney Cavin
2014-02-06 9:28 ` Linus Walleij
2014-02-06 20:05 ` Christopher Heiny
2014-02-07 1:45 ` Courtney Cavin
2014-02-06 20:05 ` Christopher Heiny
2014-02-07 1:47 ` Courtney Cavin
2014-02-04 23:08 ` [PATCH 04/15] Input: synaptics-rmi4 - remove sensor name from platform data Christopher Heiny
2014-02-05 2:30 ` Courtney Cavin
2014-02-04 23:08 ` [PATCH 03/15] Input: synaptics-rmi4 - don't free devices directly Christopher Heiny
2014-02-05 2:28 ` Courtney Cavin
2014-02-04 23:08 ` [PATCH 02/15] Input: synaptics-rmi4 - don't kfree devm_ alloced memory Christopher Heiny
2014-02-05 2:27 ` Courtney Cavin
2014-02-04 23:08 ` [PATCH 01/15] Input: synaptics-rmi4 - fix checkpatch.pl, sparse and GCC warnings Christopher Heiny
2014-02-05 2:26 ` Courtney Cavin
2014-02-06 1:09 ` Dmitry Torokhov
2014-02-06 1:36 ` Christopher Heiny
2014-02-13 6:36 ` Dmitry Torokhov
2014-02-13 18:56 ` Christopher Heiny
2014-02-13 19:10 ` Dmitry Torokhov
2014-02-13 19:12 ` Dmitry Torokhov
2014-02-13 19:25 ` Christopher Heiny
2014-01-24 0:06 ` [PATCH 00/15] Input: synaptics-rmi4 - cleanup and add DT support Courtney Cavin
2014-01-24 23:24 ` Christopher Heiny
2014-01-25 1:08 ` Courtney Cavin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52F17358.6060704@synaptics.com \
--to=cheiny@synaptics.com \
--cc=courtney.cavin@sonymobile.com \
--cc=dmitry.torokhov@gmail.com \
--cc=linux-input@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).