From: Denis Carikli <denis@eukrea.com> To: Rob Herring <rob.herring@calxeda.com> Cc: "Shawn Guo" <shawn.guo@linaro.org>, "Eric Bénard" <eric@eukrea.com>, "Sascha Hauer" <kernel@pengutronix.de>, linux-arm-kernel@lists.infradead.org, "Grant Likely" <grant.likely@secretlab.ca>, "Thierry Reding" <thierry.reding@gmail.com>, "Denis Carikli" <denis@eukrea.com>, "Pawel Moll" <pawel.moll@arm.com>, "Mark Rutland" <mark.rutland@arm.com>, "Stephen Warren" <swarren@wwwdotorg.org>, "Ian Campbell" <ijc+devicetree@hellion.org.uk>, devicetree@vger.kernel.org, "Dmitry Torokhov" <dmitry.torokhov@gmail.com>, linux-input@vger.kernel.org, "Lothar Waßmann" <LW@KARO-electronics.de> Subject: [PATCHv7][ 1/4] Input: tsc2007: Add device tree support. Date: Thu, 24 Oct 2013 14:42:13 +0200 [thread overview] Message-ID: <1382618536-25320-1-git-send-email-denis@eukrea.com> (raw) Cc: Rob Herring <rob.herring@calxeda.com> Cc: Pawel Moll <pawel.moll@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Stephen Warren <swarren@wwwdotorg.org> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk> Cc: devicetree@vger.kernel.org Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com> Cc: linux-input@vger.kernel.org Cc: Sascha Hauer <kernel@pengutronix.de> Cc: linux-arm-kernel@lists.infradead.org Cc: Lothar Waßmann <LW@KARO-electronics.de> Cc: Eric Bénard <eric@eukrea.com> Signed-off-by: Denis Carikli <denis@eukrea.com> --- ChangeLog v6->v7: - One small whitespace cleanup. - The properties specific to that driver are now prefixed with "ti,". - The ti,fuzzy property has now better documentation. --- .../bindings/input/touchscreen/tsc2007.txt | 45 +++++ drivers/input/touchscreen/tsc2007.c | 194 +++++++++++++++----- 2 files changed, 198 insertions(+), 41 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt new file mode 100644 index 0000000..516b63b --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt @@ -0,0 +1,45 @@ +* Texas Instruments tsc2007 touchscreen controller + +Required properties: +- compatible: must be "ti,tsc2007". +- reg: I2C address of the chip. +- ti,x-plate-ohms: X-plate resistance in ohms. + +Optional properties: +- gpios: the interrupt gpio the chip is connected to (trough the penirq pin) + (see GPIO binding[2] for more details). +- interrupt-parent: the phandle for the gpio controller + (see interrupt binding[1]). +- interrupts: (gpio) interrupt to which the chip is connected + (see interrupt binding[1]). +- pinctrl-0: Should specify pin control groups used for the gpio + (see pinctrl bindings[0]). +- pinctrl-names: Should contain only one value - "default" + (see pinctrl bindings[0]). +- ti,max-rt: maximum pressure. +- ti,fuzzy: specifies the absolute input fuzz value. + If set, it will permit noise in the data up to +- the value given to the fuzz + parameter, that is used to filter noise from the event stream. +- ti,poll-period: how much time to wait(in millisecond) before reading again the + values from the tsc2007. + +[0]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +[1]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +[2]: Documentation/devicetree/bindings/gpio/gpio.txt + +Example: + &i2c1 { + /* ... */ + tsc2007@49 { + compatible = "ti,tsc2007"; + reg = <0x49>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tsc2007_1>; + interrupt-parent = <&gpio4>; + interrupts = <0x0 0x8>; + gpios = <&gpio4 0 0>; + ti,x-plate-ohms = <180>; + }; + + /* ... */ + }; diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 0b67ba4..c50d64e 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -26,6 +26,9 @@ #include <linux/interrupt.h> #include <linux/i2c.h> #include <linux/i2c/tsc2007.h> +#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/of_gpio.h> #define TSC2007_MEASURE_TEMP0 (0x0 << 4) #define TSC2007_MEASURE_AUX (0x2 << 4) @@ -74,7 +77,10 @@ struct tsc2007 { u16 max_rt; unsigned long poll_delay; unsigned long poll_period; + int fuzzy; + char of; + unsigned gpio; int irq; wait_queue_head_t wait; @@ -84,6 +90,11 @@ struct tsc2007 { void (*clear_penirq)(void); }; +static int tsc2007_get_pendown_state_dt(struct tsc2007 *ts) +{ + return !gpio_get_value(ts->gpio); +} + static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd) { s32 data; @@ -142,6 +153,14 @@ static u32 tsc2007_calculate_pressure(struct tsc2007 *tsc, struct ts_event *tc) return rt; } +static bool tsc2007_is_pen_down_valid(struct tsc2007 *ts) +{ + if (ts->of) + return gpio_is_valid(ts->gpio); + else + return ts->get_pendown_state ? true : false; +} + static bool tsc2007_is_pen_down(struct tsc2007 *ts) { /* @@ -158,10 +177,13 @@ static bool tsc2007_is_pen_down(struct tsc2007 *ts) * to fall back on the pressure reading. */ - if (!ts->get_pendown_state) + if (!tsc2007_is_pen_down_valid(ts)) return true; - return ts->get_pendown_state(); + if (ts->of) + return tsc2007_get_pendown_state_dt(ts); + else + return ts->get_pendown_state(); } static irqreturn_t tsc2007_soft_irq(int irq, void *handle) @@ -178,7 +200,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle) rt = tsc2007_calculate_pressure(ts, &tc); - if (rt == 0 && !ts->get_pendown_state) { + if (!rt && !tsc2007_is_pen_down_valid(ts)) { /* * If pressure reported is 0 and we don't have * callback to check pendown state, we have to @@ -228,7 +250,7 @@ static irqreturn_t tsc2007_hard_irq(int irq, void *handle) { struct tsc2007 *ts = handle; - if (!ts->get_pendown_state || likely(ts->get_pendown_state())) + if (tsc2007_is_pen_down(ts)) return IRQ_WAKE_THREAD; if (ts->clear_penirq) @@ -273,34 +295,65 @@ static void tsc2007_close(struct input_dev *input_dev) tsc2007_stop(ts); } -static int tsc2007_probe(struct i2c_client *client, - const struct i2c_device_id *id) +#ifdef CONFIG_OF +static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts, + struct device_node *np) { - struct tsc2007 *ts; - struct tsc2007_platform_data *pdata = client->dev.platform_data; - struct input_dev *input_dev; - int err; - - if (!pdata) { - dev_err(&client->dev, "platform data is required!\n"); + int err = 0; + u32 val32; + u64 val64; + + if (!of_property_read_u32(np, "ti,max-rt", &val32)) + ts->max_rt = val32; + else + ts->max_rt = MAX_12BIT; + + if (!of_property_read_u32(np, "ti,fuzzy", &val32)) + ts->fuzzy = val32; + + if (!of_property_read_u64(np, "ti,poll-period", &val64)) + ts->poll_period = val64; + else + ts->poll_period = 1; + + if (!of_property_read_u32(np, "ti,x-plate-ohms", &val32)) { + ts->x_plate_ohms = val32; + } else { + dev_err(&client->dev, + "Error: lacking ti,x-plate-ohms devicetree property. (err %d).", + err); return -EINVAL; } - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_WORD_DATA)) - return -EIO; + ts->gpio = of_get_gpio(np, 0); + if (!gpio_is_valid(ts->gpio)) + dev_err(&client->dev, + "GPIO not found (of_get_gpio returned %d)\n", + ts->gpio); - ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!ts || !input_dev) { - err = -ENOMEM; - goto err_free_mem; - } + /* Used to detect if it is probed trough the device tree, + * in order to be able to use that information in the IRQ handler. + */ + ts->of = 1; - ts->client = client; - ts->irq = client->irq; - ts->input = input_dev; - init_waitqueue_head(&ts->wait); + return 0; +} +#else +static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts, + struct device_node *np) +{ + return -ENODEV; +} +#endif + +static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts, + struct tsc2007_platform_data *pdata, + const struct i2c_device_id *id) +{ + if (!pdata) { + dev_err(&client->dev, "platform data is required!\n"); + return -EINVAL; + } ts->model = pdata->model; ts->x_plate_ohms = pdata->x_plate_ohms; @@ -309,13 +362,57 @@ static int tsc2007_probe(struct i2c_client *client, ts->poll_period = pdata->poll_period ? : 1; ts->get_pendown_state = pdata->get_pendown_state; ts->clear_penirq = pdata->clear_penirq; + ts->fuzzy = pdata->fuzzy; if (pdata->x_plate_ohms == 0) { dev_err(&client->dev, "x_plate_ohms is not set up in platform data"); - err = -EINVAL; - goto err_free_mem; + return -EINVAL; } + /* Used to detect if it is probed trough the device tree, + * in order to be able to use that information in the IRQ handler. + */ + ts->of = 0; + + return 0; +} + +static int tsc2007_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device_node *np = client->dev.of_node; + struct tsc2007_platform_data *pdata = client->dev.platform_data; + struct tsc2007 *ts; + struct input_dev *input_dev; + int err = 0; + + ts = devm_kzalloc(&client->dev, sizeof(struct tsc2007), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + if (np) + err = tsc2007_probe_dt(client, ts, np); + else + err = tsc2007_probe_pdev(client, ts, pdata, id); + + if (err) + return err; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -EIO; + + input_dev = input_allocate_device(); + if (!input_dev) { + err = -ENOMEM; + goto err_free_input; + }; + + ts->client = client; + ts->irq = client->irq; + ts->input = input_dev; + init_waitqueue_head(&ts->wait); + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev)); @@ -331,19 +428,21 @@ static int tsc2007_probe(struct i2c_client *client, input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0); - input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0); + input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzy, 0); + input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, - pdata->fuzzz, 0); + ts->fuzzy, 0); - if (pdata->init_platform_hw) - pdata->init_platform_hw(); + if (!np) { + if (pdata->init_platform_hw) + pdata->init_platform_hw(); + } err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq, IRQF_ONESHOT, client->dev.driver->name, ts); if (err < 0) { dev_err(&client->dev, "irq %d busy?\n", ts->irq); - goto err_free_mem; + goto err_free_input; } tsc2007_stop(ts); @@ -358,23 +457,27 @@ static int tsc2007_probe(struct i2c_client *client, err_free_irq: free_irq(ts->irq, ts); - if (pdata->exit_platform_hw) - pdata->exit_platform_hw(); - err_free_mem: + if (!np) { + if (pdata->exit_platform_hw) + pdata->exit_platform_hw(); + } + err_free_input: input_free_device(input_dev); - kfree(ts); return err; } static int tsc2007_remove(struct i2c_client *client) { + struct device_node *np = client->dev.of_node; struct tsc2007 *ts = i2c_get_clientdata(client); struct tsc2007_platform_data *pdata = client->dev.platform_data; free_irq(ts->irq, ts); - if (pdata->exit_platform_hw) - pdata->exit_platform_hw(); + if (!np) { + if (pdata->exit_platform_hw) + pdata->exit_platform_hw(); + } input_unregister_device(ts->input); kfree(ts); @@ -389,10 +492,19 @@ static const struct i2c_device_id tsc2007_idtable[] = { MODULE_DEVICE_TABLE(i2c, tsc2007_idtable); +#ifdef CONFIG_OF +static const struct of_device_id tsc2007_of_match[] = { + { .compatible = "ti,tsc2007" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, tsc2007_of_match); +#endif + static struct i2c_driver tsc2007_driver = { .driver = { .owner = THIS_MODULE, - .name = "tsc2007" + .name = "tsc2007", + .of_match_table = of_match_ptr(tsc2007_of_match), }, .id_table = tsc2007_idtable, .probe = tsc2007_probe, -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
WARNING: multiple messages have this Message-ID (diff)
From: denis@eukrea.com (Denis Carikli) To: linux-arm-kernel@lists.infradead.org Subject: [PATCHv7][ 1/4] Input: tsc2007: Add device tree support. Date: Thu, 24 Oct 2013 14:42:13 +0200 [thread overview] Message-ID: <1382618536-25320-1-git-send-email-denis@eukrea.com> (raw) Cc: Rob Herring <rob.herring@calxeda.com> Cc: Pawel Moll <pawel.moll@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Stephen Warren <swarren@wwwdotorg.org> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk> Cc: devicetree at vger.kernel.org Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com> Cc: linux-input at vger.kernel.org Cc: Sascha Hauer <kernel@pengutronix.de> Cc: linux-arm-kernel at lists.infradead.org Cc: Lothar Wa?mann <LW@KARO-electronics.de> Cc: Eric B?nard <eric@eukrea.com> Signed-off-by: Denis Carikli <denis@eukrea.com> --- ChangeLog v6->v7: - One small whitespace cleanup. - The properties specific to that driver are now prefixed with "ti,". - The ti,fuzzy property has now better documentation. --- .../bindings/input/touchscreen/tsc2007.txt | 45 +++++ drivers/input/touchscreen/tsc2007.c | 194 +++++++++++++++----- 2 files changed, 198 insertions(+), 41 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt new file mode 100644 index 0000000..516b63b --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt @@ -0,0 +1,45 @@ +* Texas Instruments tsc2007 touchscreen controller + +Required properties: +- compatible: must be "ti,tsc2007". +- reg: I2C address of the chip. +- ti,x-plate-ohms: X-plate resistance in ohms. + +Optional properties: +- gpios: the interrupt gpio the chip is connected to (trough the penirq pin) + (see GPIO binding[2] for more details). +- interrupt-parent: the phandle for the gpio controller + (see interrupt binding[1]). +- interrupts: (gpio) interrupt to which the chip is connected + (see interrupt binding[1]). +- pinctrl-0: Should specify pin control groups used for the gpio + (see pinctrl bindings[0]). +- pinctrl-names: Should contain only one value - "default" + (see pinctrl bindings[0]). +- ti,max-rt: maximum pressure. +- ti,fuzzy: specifies the absolute input fuzz value. + If set, it will permit noise in the data up to +- the value given to the fuzz + parameter, that is used to filter noise from the event stream. +- ti,poll-period: how much time to wait(in millisecond) before reading again the + values from the tsc2007. + +[0]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +[1]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +[2]: Documentation/devicetree/bindings/gpio/gpio.txt + +Example: + &i2c1 { + /* ... */ + tsc2007 at 49 { + compatible = "ti,tsc2007"; + reg = <0x49>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tsc2007_1>; + interrupt-parent = <&gpio4>; + interrupts = <0x0 0x8>; + gpios = <&gpio4 0 0>; + ti,x-plate-ohms = <180>; + }; + + /* ... */ + }; diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 0b67ba4..c50d64e 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -26,6 +26,9 @@ #include <linux/interrupt.h> #include <linux/i2c.h> #include <linux/i2c/tsc2007.h> +#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/of_gpio.h> #define TSC2007_MEASURE_TEMP0 (0x0 << 4) #define TSC2007_MEASURE_AUX (0x2 << 4) @@ -74,7 +77,10 @@ struct tsc2007 { u16 max_rt; unsigned long poll_delay; unsigned long poll_period; + int fuzzy; + char of; + unsigned gpio; int irq; wait_queue_head_t wait; @@ -84,6 +90,11 @@ struct tsc2007 { void (*clear_penirq)(void); }; +static int tsc2007_get_pendown_state_dt(struct tsc2007 *ts) +{ + return !gpio_get_value(ts->gpio); +} + static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd) { s32 data; @@ -142,6 +153,14 @@ static u32 tsc2007_calculate_pressure(struct tsc2007 *tsc, struct ts_event *tc) return rt; } +static bool tsc2007_is_pen_down_valid(struct tsc2007 *ts) +{ + if (ts->of) + return gpio_is_valid(ts->gpio); + else + return ts->get_pendown_state ? true : false; +} + static bool tsc2007_is_pen_down(struct tsc2007 *ts) { /* @@ -158,10 +177,13 @@ static bool tsc2007_is_pen_down(struct tsc2007 *ts) * to fall back on the pressure reading. */ - if (!ts->get_pendown_state) + if (!tsc2007_is_pen_down_valid(ts)) return true; - return ts->get_pendown_state(); + if (ts->of) + return tsc2007_get_pendown_state_dt(ts); + else + return ts->get_pendown_state(); } static irqreturn_t tsc2007_soft_irq(int irq, void *handle) @@ -178,7 +200,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle) rt = tsc2007_calculate_pressure(ts, &tc); - if (rt == 0 && !ts->get_pendown_state) { + if (!rt && !tsc2007_is_pen_down_valid(ts)) { /* * If pressure reported is 0 and we don't have * callback to check pendown state, we have to @@ -228,7 +250,7 @@ static irqreturn_t tsc2007_hard_irq(int irq, void *handle) { struct tsc2007 *ts = handle; - if (!ts->get_pendown_state || likely(ts->get_pendown_state())) + if (tsc2007_is_pen_down(ts)) return IRQ_WAKE_THREAD; if (ts->clear_penirq) @@ -273,34 +295,65 @@ static void tsc2007_close(struct input_dev *input_dev) tsc2007_stop(ts); } -static int tsc2007_probe(struct i2c_client *client, - const struct i2c_device_id *id) +#ifdef CONFIG_OF +static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts, + struct device_node *np) { - struct tsc2007 *ts; - struct tsc2007_platform_data *pdata = client->dev.platform_data; - struct input_dev *input_dev; - int err; - - if (!pdata) { - dev_err(&client->dev, "platform data is required!\n"); + int err = 0; + u32 val32; + u64 val64; + + if (!of_property_read_u32(np, "ti,max-rt", &val32)) + ts->max_rt = val32; + else + ts->max_rt = MAX_12BIT; + + if (!of_property_read_u32(np, "ti,fuzzy", &val32)) + ts->fuzzy = val32; + + if (!of_property_read_u64(np, "ti,poll-period", &val64)) + ts->poll_period = val64; + else + ts->poll_period = 1; + + if (!of_property_read_u32(np, "ti,x-plate-ohms", &val32)) { + ts->x_plate_ohms = val32; + } else { + dev_err(&client->dev, + "Error: lacking ti,x-plate-ohms devicetree property. (err %d).", + err); return -EINVAL; } - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_WORD_DATA)) - return -EIO; + ts->gpio = of_get_gpio(np, 0); + if (!gpio_is_valid(ts->gpio)) + dev_err(&client->dev, + "GPIO not found (of_get_gpio returned %d)\n", + ts->gpio); - ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!ts || !input_dev) { - err = -ENOMEM; - goto err_free_mem; - } + /* Used to detect if it is probed trough the device tree, + * in order to be able to use that information in the IRQ handler. + */ + ts->of = 1; - ts->client = client; - ts->irq = client->irq; - ts->input = input_dev; - init_waitqueue_head(&ts->wait); + return 0; +} +#else +static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts, + struct device_node *np) +{ + return -ENODEV; +} +#endif + +static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts, + struct tsc2007_platform_data *pdata, + const struct i2c_device_id *id) +{ + if (!pdata) { + dev_err(&client->dev, "platform data is required!\n"); + return -EINVAL; + } ts->model = pdata->model; ts->x_plate_ohms = pdata->x_plate_ohms; @@ -309,13 +362,57 @@ static int tsc2007_probe(struct i2c_client *client, ts->poll_period = pdata->poll_period ? : 1; ts->get_pendown_state = pdata->get_pendown_state; ts->clear_penirq = pdata->clear_penirq; + ts->fuzzy = pdata->fuzzy; if (pdata->x_plate_ohms == 0) { dev_err(&client->dev, "x_plate_ohms is not set up in platform data"); - err = -EINVAL; - goto err_free_mem; + return -EINVAL; } + /* Used to detect if it is probed trough the device tree, + * in order to be able to use that information in the IRQ handler. + */ + ts->of = 0; + + return 0; +} + +static int tsc2007_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device_node *np = client->dev.of_node; + struct tsc2007_platform_data *pdata = client->dev.platform_data; + struct tsc2007 *ts; + struct input_dev *input_dev; + int err = 0; + + ts = devm_kzalloc(&client->dev, sizeof(struct tsc2007), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + if (np) + err = tsc2007_probe_dt(client, ts, np); + else + err = tsc2007_probe_pdev(client, ts, pdata, id); + + if (err) + return err; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -EIO; + + input_dev = input_allocate_device(); + if (!input_dev) { + err = -ENOMEM; + goto err_free_input; + }; + + ts->client = client; + ts->irq = client->irq; + ts->input = input_dev; + init_waitqueue_head(&ts->wait); + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev)); @@ -331,19 +428,21 @@ static int tsc2007_probe(struct i2c_client *client, input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0); - input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0); + input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzy, 0); + input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, - pdata->fuzzz, 0); + ts->fuzzy, 0); - if (pdata->init_platform_hw) - pdata->init_platform_hw(); + if (!np) { + if (pdata->init_platform_hw) + pdata->init_platform_hw(); + } err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq, IRQF_ONESHOT, client->dev.driver->name, ts); if (err < 0) { dev_err(&client->dev, "irq %d busy?\n", ts->irq); - goto err_free_mem; + goto err_free_input; } tsc2007_stop(ts); @@ -358,23 +457,27 @@ static int tsc2007_probe(struct i2c_client *client, err_free_irq: free_irq(ts->irq, ts); - if (pdata->exit_platform_hw) - pdata->exit_platform_hw(); - err_free_mem: + if (!np) { + if (pdata->exit_platform_hw) + pdata->exit_platform_hw(); + } + err_free_input: input_free_device(input_dev); - kfree(ts); return err; } static int tsc2007_remove(struct i2c_client *client) { + struct device_node *np = client->dev.of_node; struct tsc2007 *ts = i2c_get_clientdata(client); struct tsc2007_platform_data *pdata = client->dev.platform_data; free_irq(ts->irq, ts); - if (pdata->exit_platform_hw) - pdata->exit_platform_hw(); + if (!np) { + if (pdata->exit_platform_hw) + pdata->exit_platform_hw(); + } input_unregister_device(ts->input); kfree(ts); @@ -389,10 +492,19 @@ static const struct i2c_device_id tsc2007_idtable[] = { MODULE_DEVICE_TABLE(i2c, tsc2007_idtable); +#ifdef CONFIG_OF +static const struct of_device_id tsc2007_of_match[] = { + { .compatible = "ti,tsc2007" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, tsc2007_of_match); +#endif + static struct i2c_driver tsc2007_driver = { .driver = { .owner = THIS_MODULE, - .name = "tsc2007" + .name = "tsc2007", + .of_match_table = of_match_ptr(tsc2007_of_match), }, .id_table = tsc2007_idtable, .probe = tsc2007_probe, -- 1.7.9.5
next reply other threads:[~2013-10-24 12:42 UTC|newest] Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top 2013-10-24 12:42 Denis Carikli [this message] 2013-10-24 12:42 ` [PATCHv7][ 1/4] Input: tsc2007: Add device tree support Denis Carikli 2013-10-24 12:42 ` [PATCHv7][ 2/4] ARM: dts: cpuimx51 Add touchscreen support Denis Carikli 2013-10-24 12:42 ` Denis Carikli 2013-10-24 12:42 ` [PATCHv7][ 3/4] ARM: dts: cpuimx35 " Denis Carikli 2013-10-24 12:42 ` Denis Carikli 2013-10-24 12:42 ` [PATCHv7][ 4/4] ARM: imx_v6_v7_defconfig: Enable tsc2007 support Denis Carikli 2013-10-24 12:42 ` Denis Carikli 2013-10-24 15:17 ` [PATCHv7][ 1/4] Input: tsc2007: Add device tree support Thierry Reding 2013-10-24 15:17 ` Thierry Reding 2013-10-24 15:26 ` Eric Bénard 2013-10-24 15:26 ` Eric Bénard 2013-10-25 6:39 ` Lothar Waßmann 2013-10-25 6:39 ` Lothar Waßmann 2013-10-25 8:33 ` Thierry Reding 2013-10-25 8:33 ` Thierry Reding 2013-11-04 12:01 ` Linus Walleij 2013-11-04 12:01 ` Linus Walleij 2013-10-24 16:47 ` Grant Likely 2013-10-24 16:47 ` Grant Likely 2013-10-25 5:56 ` Lothar Waßmann 2013-10-25 5:56 ` Lothar Waßmann 2013-10-25 19:11 ` Grant Likely 2013-10-25 19:11 ` Grant Likely
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=1382618536-25320-1-git-send-email-denis@eukrea.com \ --to=denis@eukrea.com \ --cc=LW@KARO-electronics.de \ --cc=devicetree@vger.kernel.org \ --cc=dmitry.torokhov@gmail.com \ --cc=eric@eukrea.com \ --cc=grant.likely@secretlab.ca \ --cc=ijc+devicetree@hellion.org.uk \ --cc=kernel@pengutronix.de \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-input@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=pawel.moll@arm.com \ --cc=rob.herring@calxeda.com \ --cc=shawn.guo@linaro.org \ --cc=swarren@wwwdotorg.org \ --cc=thierry.reding@gmail.com \ /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: linkBe 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.