All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.