[PATCHv9][ 1/3] Input: tsc2007: Add device tree support.
Dmitry Torokhov
dmitry.torokhov at gmail.com
Tue Nov 19 16:11:02 EST 2013
Hi Denis,
On Fri, Nov 08, 2013 at 02:17:37PM +0100, Denis Carikli wrote:
> Cc: Rob Herring <rob.herring at calxeda.com>
> Cc: Pawel Moll <pawel.moll at arm.com>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Stephen Warren <swarren at wwwdotorg.org>
> Cc: Ian Campbell <ijc+devicetree at hellion.org.uk>
> Cc: Grant Likely <grant.likely at linaro.org>
> Cc: devicetree at vger.kernel.org
> Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
> Cc: linux-input at vger.kernel.org
> Cc: Sascha Hauer <kernel at pengutronix.de>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: Lothar Waßmann <LW at KARO-electronics.de>
> Cc: Shawn Guo <shawn.guo at linaro.org>
> Cc: Eric Bénard <eric at eukrea.com>
> Signed-off-by: Denis Carikli <denis at eukrea.com>
> ---
> ChangeLog v8->v9:
> - Added Grant Likely in the Cc list.
> - Removed the mention of the pinctrl properties in the documentation.
>
> ChangeLog v7->v8:
> - Fixed the lack of x and z fuzz properties.
> - The pendown gpio is better documented.
> - Added Shawn Guo in the cc list.
Does the device still work if you drop the patch below on top of yours?
Thanks!
--
Dmitry
Input: tsc2007 misc fixes
From: Dmitry Torokhov <dmitry.torokhov at gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>
---
arch/arm/mach-imx/mach-cpuimx35.c | 2 -
arch/arm/mach-imx/mach-cpuimx51sd.c | 2 -
arch/sh/boards/mach-ecovec24/setup.c | 2 -
drivers/input/touchscreen/tsc2007.c | 126 +++++++++++++---------------------
include/linux/i2c/tsc2007.h | 6 +-
5 files changed, 55 insertions(+), 83 deletions(-)
diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c
index 771362d..65e4c53 100644
--- a/arch/arm/mach-imx/mach-cpuimx35.c
+++ b/arch/arm/mach-imx/mach-cpuimx35.c
@@ -53,7 +53,7 @@ static const struct imxi2c_platform_data
};
#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2)
-static int tsc2007_get_pendown_state(void)
+static int tsc2007_get_pendown_state(struct device *dev)
{
return !gpio_get_value(TSC2007_IRQGPIO);
}
diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c
index 9b5ddf5..1fba2b8 100644
--- a/arch/arm/mach-imx/mach-cpuimx51sd.c
+++ b/arch/arm/mach-imx/mach-cpuimx51sd.c
@@ -121,7 +121,7 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static int tsc2007_get_pendown_state(void)
+static int tsc2007_get_pendown_state(struct device *dev)
{
if (mx51_revision() < IMX_CHIP_REVISION_3_0)
return !gpio_get_value(TSC2007_IRQGPIO_REV2);
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 1fa8be4..23d7e45 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -501,7 +501,7 @@ static struct platform_device keysc_device = {
/* TouchScreen */
#define IRQ0 evt2irq(0x600)
-static int ts_get_pendown_state(void)
+static int ts_get_pendown_state(struct device *dev)
{
int val = 0;
gpio_free(GPIO_FN_INTC_IRQ0);
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index 3168a99..390148c 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -88,15 +88,10 @@ struct tsc2007 {
wait_queue_head_t wait;
bool stopped;
- int (*get_pendown_state)(void);
+ int (*get_pendown_state)(struct device *);
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;
@@ -155,14 +150,6 @@ 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)
{
/*
@@ -179,13 +166,10 @@ static bool tsc2007_is_pen_down(struct tsc2007 *ts)
* to fall back on the pressure reading.
*/
- if (!tsc2007_is_pen_down_valid(ts))
+ if (!ts->get_pendown_state)
return true;
- if (ts->of)
- return tsc2007_get_pendown_state_dt(ts);
- else
- return ts->get_pendown_state();
+ return ts->get_pendown_state(&ts->client->dev);
}
static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
@@ -202,7 +186,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
rt = tsc2007_calculate_pressure(ts, &tc);
- if (!rt && !tsc2007_is_pen_down_valid(ts)) {
+ if (!rt && !ts->get_pendown_state) {
/*
* If pressure reported is 0 and we don't have
* callback to check pendown state, we have to
@@ -298,13 +282,25 @@ static void tsc2007_close(struct input_dev *input_dev)
}
#ifdef CONFIG_OF
-static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts,
- struct device_node *np)
+static int tsc2007_get_pendown_state_gpio(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct tsc2007 *ts = i2c_get_clientdata(client);
+
+ return !gpio_get_value(ts->gpio);
+}
+
+static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
{
- int err = 0;
+ struct device_node *np = client->dev.of_node;
u32 val32;
u64 val64;
+ if (!np) {
+ dev_err(&client->dev, "missing device tree data\n");
+ return -EINVAL;
+ }
+
if (!of_property_read_u32(np, "ti,max-rt", &val32))
ts->max_rt = val32;
else
@@ -327,42 +323,32 @@ static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts,
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);
+ dev_err(&client->dev, "missing ti,x-plate-ohms devicetree property.");
return -EINVAL;
}
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);
-
- /* 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;
+ if (gpio_is_valid(ts->gpio))
+ ts->get_pendown_state = tsc2007_get_pendown_state_gpio;
+ else
+ dev_warn(&client->dev,
+ "GPIO not specified in DT (of_get_gpio returned %d)\n",
+ ts->gpio);
return 0;
}
#else
-static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts,
- struct device_node *np)
+static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
{
- return -ENODEV;
+ dev_err(&client->dev, "platform data is required!\n");
+ return -EINVAL;
}
#endif
static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,
- struct tsc2007_platform_data *pdata,
+ const 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;
ts->max_rt = pdata->max_rt ? : MAX_12BIT;
@@ -379,45 +365,40 @@ static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,
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;
+ const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);
struct tsc2007 *ts;
struct input_dev *input_dev;
- int err = 0;
+ int err;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_WORD_DATA))
+ return -EIO;
ts = devm_kzalloc(&client->dev, sizeof(struct tsc2007), GFP_KERNEL);
if (!ts)
return -ENOMEM;
- if (np)
- err = tsc2007_probe_dt(client, ts, np);
- else
+ if (pdata)
err = tsc2007_probe_pdev(client, ts, pdata, id);
-
+ else
+ err = tsc2007_probe_dt(client, ts);
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;
};
+ i2c_set_clientdata(client, ts);
+
ts->client = client;
ts->irq = client->irq;
ts->input = input_dev;
@@ -443,10 +424,8 @@ static int tsc2007_probe(struct i2c_client *client,
input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
ts->fuzzz, 0);
- if (!np) {
- if (pdata->init_platform_hw)
- pdata->init_platform_hw();
- }
+ if (pdata && 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);
@@ -461,16 +440,12 @@ static int tsc2007_probe(struct i2c_client *client,
if (err)
goto err_free_irq;
- i2c_set_clientdata(client, ts);
-
return 0;
err_free_irq:
free_irq(ts->irq, ts);
- if (!np) {
- if (pdata->exit_platform_hw)
- pdata->exit_platform_hw();
- }
+ if (pdata && pdata->exit_platform_hw)
+ pdata->exit_platform_hw();
err_free_input:
input_free_device(input_dev);
return err;
@@ -478,16 +453,13 @@ static int tsc2007_probe(struct i2c_client *client,
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;
+ const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);
+ struct tsc2007 *ts = i2c_get_clientdata(client);
free_irq(ts->irq, ts);
- if (!np) {
- if (pdata->exit_platform_hw)
- pdata->exit_platform_hw();
- }
+ if (pdata && pdata->exit_platform_hw)
+ pdata->exit_platform_hw();
input_unregister_device(ts->input);
kfree(ts);
diff --git a/include/linux/i2c/tsc2007.h b/include/linux/i2c/tsc2007.h
index 506a9f7..041c8e8 100644
--- a/include/linux/i2c/tsc2007.h
+++ b/include/linux/i2c/tsc2007.h
@@ -14,9 +14,9 @@ struct tsc2007_platform_data {
int fuzzy;
int fuzzz;
- int (*get_pendown_state)(void);
- void (*clear_penirq)(void); /* If needed, clear 2nd level
- interrupt source */
+ int (*get_pendown_state)(struct device *);
+ /* If needed, clear 2nd level interrupt source */
+ void (*clear_penirq)(void);
int (*init_platform_hw)(void);
void (*exit_platform_hw)(void);
};
More information about the linux-arm-kernel
mailing list