aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Miao <eric.miao@linaro.org>2011-12-30 17:40:50 +0800
committerEric Miao <eric.miao@linaro.org>2012-01-11 21:39:41 +0800
commit925e814d9b46346af50dc3c7cf7a6106be5c9723 (patch)
tree0b88d74b7b2a704135fe9dd8393ecb51be54a036
parent072a583f8857d6bf194885c54836f10d28d8469e (diff)
input: add device tree support for eGalax touch
Signed-off-by: Eric Miao <eric.miao@linaro.org>
-rw-r--r--arch/arm/boot/dts/imx6q-sabrelite.dts13
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c3
-rw-r--r--drivers/input/touchscreen/egalax_ts.c48
3 files changed, 50 insertions, 14 deletions
diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts
index 4effcd8604e..e6d2cb73243 100644
--- a/arch/arm/boot/dts/imx6q-sabrelite.dts
+++ b/arch/arm/boot/dts/imx6q-sabrelite.dts
@@ -63,6 +63,19 @@
reg = <0x50>;
};
};
+
+ i2c@021a8000 { /* I2C3 */
+ status = "okay";
+ clock-frequency = <400000>;
+
+ egalax@04 {
+ compatible = "eeti,egalax";
+ reg = <0x04>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9>;
+ interrupt-gpio = <&gpio1 9 0>;
+ };
+ };
};
hdmi@0x00120000 { /* HDMI */
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index f5b31867953..3f46730ac06 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -67,6 +67,9 @@ static iomux_v3_cfg_t imx6q_sabrelite_pads[] = {
/* I2C2 */
MX6Q_PAD_KEY_COL3__I2C2_SCL,
MX6Q_PAD_KEY_ROW3__I2C2_SDA,
+ /* I2C3 */
+ MX6Q_PAD_GPIO_5__I2C3_SCL,
+ MX6Q_PAD_GPIO_16__I2C3_SDA,
/* GPIO */
MX6Q_PAD_NANDF_D0__GPIO_2_0,
MX6Q_PAD_EIM_D23__GPIO_3_23,
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c
index 58273b9e356..58184dad7a2 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -39,6 +39,9 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/bitops.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
#define REPORT_MODE_SINGLE 0x1
#define REPORT_MODE_VENDOR 0x3
@@ -68,6 +71,7 @@ struct egalax_ts {
struct i2c_client *client;
struct input_dev *input_dev;
struct egalax_pointer events[MAX_SUPPORT_POINTS];
+ int gpio_irq;
};
static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
@@ -91,7 +95,7 @@ retry:
dev_dbg(&client->dev, "recv ret:%d", ret);
for (i = 0; i < MAX_I2C_DATA_LEN; i++)
- printk(KERN_DEBUG " %x ", buf[i]);
+ dev_dbg(&client->dev, " %x ", buf[i]);
if (buf[0] != REPORT_MODE_VENDOR
&& buf[0] != REPORT_MODE_SINGLE
@@ -180,23 +184,24 @@ retry:
return IRQ_HANDLED;
}
-static int egalax_wake_up_device(struct i2c_client *client)
+static void egalax_wake_up_device(struct i2c_client *client)
{
- int gpio = irq_to_gpio(client->irq);
- int ret;
+ struct egalax_ts *data = i2c_get_clientdata(client);
+ int ret, gpio_irq = data->gpio_irq;
- ret = gpio_request(gpio, "egalax_irq");
+ if (!gpio_is_valid(gpio_irq))
+ return;
+
+ ret = gpio_request_one(gpio_irq, GPIOF_OUT_INIT_HIGH, "egalax_irq");
if (ret < 0) {
dev_err(&client->dev, "request gpio failed:%d\n", ret);
- return ret;
+ return;
}
/* wake up controller via an falling edge on IRQ. */
- gpio_direction_output(gpio, 0);
- gpio_set_value(gpio, 1);
+ gpio_set_value(gpio_irq, 0);
/* controller should be waken up, return irq. */
- gpio_direction_input(gpio);
- gpio_free(gpio);
- return 0;
+ gpio_direction_input(gpio_irq);
+ gpio_free(gpio_irq);
}
static int egalax_7200_firmware_version(struct i2c_client *client)
@@ -212,6 +217,7 @@ static int egalax_7200_firmware_version(struct i2c_client *client)
static int __devinit egalax_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device_node *n = client->dev.of_node;
struct egalax_ts *data;
struct input_dev *input_dev;
int ret;
@@ -231,6 +237,12 @@ static int __devinit egalax_ts_probe(struct i2c_client *client,
data->client = client;
data->input_dev = input_dev;
+ data->gpio_irq = of_get_named_gpio(n, "interrupt-gpio", 0);
+ if (!gpio_is_valid(data->gpio_irq))
+ dev_warn(&client->dev, "invalid interrupt GPIO\n");
+
+ i2c_set_clientdata(client, data);
+
egalax_wake_up_device(client);
ret = egalax_7200_firmware_version(client);
if (ret < 0) {
@@ -275,10 +287,9 @@ static int __devinit egalax_ts_probe(struct i2c_client *client,
goto err_free_dev;
}
- ret = input_register_device(data->input_dev);
+ return input_register_device(data->input_dev);
if (ret < 0)
goto err_free_irq;
- i2c_set_clientdata(client, data);
return 0;
err_free_irq:
@@ -324,15 +335,24 @@ static int egalax_ts_suspend(struct device *dev)
static int egalax_ts_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
- return egalax_wake_up_device(client);
+ egalax_wake_up_device(client);
+ return 0;
}
#endif
+static struct of_device_id egalax_dt_ids[] = {
+ { .compatible = "eeti,egalax" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_uart_dt_ids);
+
static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume);
+
static struct i2c_driver egalax_ts_driver = {
.driver = {
.name = "egalax_ts",
.pm = &egalax_ts_pm_ops,
+ .of_match_table = egalax_dt_ids,
},
.id_table = egalax_ts_id,
.probe = egalax_ts_probe,