input: add device tree support for eGalax touch

Signed-off-by: Eric Miao <eric.miao@linaro.org>
diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts
index 4effcd8..e6d2cb7 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 f5b3186..3f46730 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -67,6 +67,9 @@
 	/* 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 58273b9..58184da 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 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 @@
 
 	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 @@
 	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 __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 @@
 
 	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 @@
 		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_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,