Message ID | 1432817265-23891-6-git-send-email-irina.tirdea@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi, On Thu, May 28, 2015 at 01:47:41PM +0100, Irina Tirdea wrote: > After power on, it is recommended that the driver resets the device. > For reset the driver needs to control the interrupt and > reset gpio pins (configured through ACPI/device tree). Why is it necessary to mess with the GPIO the interrupts is wired up to? What exactly does the device expect at reset w.r.t. the interrupt line? > > Signed-off-by: Octavian Purdila <octavian.purdila@intel.com> > Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> > --- > .../bindings/input/touchscreen/goodix.txt | 5 ++ > drivers/input/touchscreen/goodix.c | 99 ++++++++++++++++++++++ > 2 files changed, 104 insertions(+) > > diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt > index 8ba98ee..7137881 100644 > --- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt > +++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt > @@ -12,6 +12,8 @@ Required properties: > - reg : I2C address of the chip. Should be 0x5d or 0x14 > - interrupt-parent : Interrupt controller to which the chip is connected > - interrupts : Interrupt to which the chip is connected > + - irq-gpio : GPIO pin used for IRQ > + - reset-gpio : GPIO pin used for reset > > Example: > > @@ -23,6 +25,9 @@ Example: > reg = <0x5d>; > interrupt-parent = <&gpio>; > interrupts = <0 0>; > + > + irq-gpio = <&gpio1 0 0>; > + reset-gpio = <&gpio1 1 0>; > }; > > /* ... */ > diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c > index 9e7d215..4405c55 100644 > --- a/drivers/input/touchscreen/goodix.c > +++ b/drivers/input/touchscreen/goodix.c > @@ -26,6 +26,7 @@ > #include <linux/acpi.h> > #include <linux/of.h> > #include <asm/unaligned.h> > +#include <linux/gpio.h> Nit: weird include ordering. Mark. -- 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
> -----Original Message----- > From: Mark Rutland [mailto:mark.rutland@arm.com] > Sent: 28 May, 2015 16:20 > To: Tirdea, Irina > Cc: Dmitry Torokhov; Bastien Nocera; linux-input@vger.kernel.org; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; > Purdila, Octavian > Subject: Re: [PATCH 5/9] input: goodix: reset device at init > > Hi, > Hi Mark, Thanks for your quick review! > On Thu, May 28, 2015 at 01:47:41PM +0100, Irina Tirdea wrote: > > After power on, it is recommended that the driver resets the device. > > For reset the driver needs to control the interrupt and > > reset gpio pins (configured through ACPI/device tree). > > Why is it necessary to mess with the GPIO the interrupts is wired up to? > What exactly does the device expect at reset w.r.t. the interrupt line? > The reset procedure is described in the Goodix documentation (https://drive.google.com/folderview?id=0BxCVOQS3ZymGfmJyY2RKbE5XbVlKNlktVTlwV0lxNEdxd2dzeWZER094cmJPVnMxN1F0Yzg&usp=sharing) and implemented in their reference driver. It is used at device init (before writing device configuration) and for power management (as described in chapter 7.1 of the documentation, when entering suspend the device must output low on the interrupt pin and when resuming it must output high on the interrupt pin). > > > > Signed-off-by: Octavian Purdila <octavian.purdila@intel.com> > > Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> > > --- > > .../bindings/input/touchscreen/goodix.txt | 5 ++ > > drivers/input/touchscreen/goodix.c | 99 ++++++++++++++++++++++ > > 2 files changed, 104 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt > b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt > > index 8ba98ee..7137881 100644 > > --- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt > > +++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt > > @@ -12,6 +12,8 @@ Required properties: > > - reg : I2C address of the chip. Should be 0x5d or 0x14 > > - interrupt-parent : Interrupt controller to which the chip is connected > > - interrupts : Interrupt to which the chip is connected > > + - irq-gpio : GPIO pin used for IRQ > > + - reset-gpio : GPIO pin used for reset > > > > Example: > > > > @@ -23,6 +25,9 @@ Example: > > reg = <0x5d>; > > interrupt-parent = <&gpio>; > > interrupts = <0 0>; > > + > > + irq-gpio = <&gpio1 0 0>; > > + reset-gpio = <&gpio1 1 0>; > > }; > > > > /* ... */ > > diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c > > index 9e7d215..4405c55 100644 > > --- a/drivers/input/touchscreen/goodix.c > > +++ b/drivers/input/touchscreen/goodix.c > > @@ -26,6 +26,7 @@ > > #include <linux/acpi.h> > > #include <linux/of.h> > > #include <asm/unaligned.h> > > +#include <linux/gpio.h> > > Nit: weird include ordering. Will fix this in v2. > > Mark. -- 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
diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt index 8ba98ee..7137881 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt @@ -12,6 +12,8 @@ Required properties: - reg : I2C address of the chip. Should be 0x5d or 0x14 - interrupt-parent : Interrupt controller to which the chip is connected - interrupts : Interrupt to which the chip is connected + - irq-gpio : GPIO pin used for IRQ + - reset-gpio : GPIO pin used for reset Example: @@ -23,6 +25,9 @@ Example: reg = <0x5d>; interrupt-parent = <&gpio>; interrupts = <0 0>; + + irq-gpio = <&gpio1 0 0>; + reset-gpio = <&gpio1 1 0>; }; /* ... */ diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 9e7d215..4405c55 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -26,6 +26,7 @@ #include <linux/acpi.h> #include <linux/of.h> #include <asm/unaligned.h> +#include <linux/gpio.h> struct goodix_ts_data { struct i2c_client *client; @@ -34,8 +35,12 @@ struct goodix_ts_data { int abs_y_max; unsigned int max_touch_num; unsigned int int_trigger_type; + struct gpio_desc *gpiod_int; + struct gpio_desc *gpiod_rst; }; +#define GOODIX_GPIO_INT_NAME "irq" +#define GOODIX_GPIO_RST_NAME "reset" #define GOODIX_MAX_HEIGHT 4096 #define GOODIX_MAX_WIDTH 4096 #define GOODIX_INT_TRIGGER 1 @@ -187,6 +192,89 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +static int goodix_int_sync(struct goodix_ts_data *ts) +{ + int ret; + + ret = gpiod_direction_output(ts->gpiod_int, 0); + if (ret) + return ret; + + return gpiod_direction_input(ts->gpiod_int); +} + +/** + * goodix_reset - Reset device during power on + * + * @ts: goodix_ts_data pointer + */ +static int goodix_reset(struct goodix_ts_data *ts) +{ + int ret; + + /* begin select I2C slave addr */ + ret = gpiod_direction_output(ts->gpiod_rst, 0); + if (ret) + return ret; + msleep(20); /* T2: > 10ms */ + /* HIGH: 0x28/0x29, LOW: 0xBA/0xBB */ + ret = gpiod_direction_output(ts->gpiod_int, ts->client->addr == 0x14); + if (ret) + return ret; + usleep_range(100, 2000); /* T3: > 100us */ + ret = gpiod_direction_output(ts->gpiod_rst, 1); + if (ret) + return ret; + usleep_range(6000, 10000); /* T4: > 5ms */ + /* end select I2C slave addr */ + ret = gpiod_direction_input(ts->gpiod_rst); + if (ret) + return ret; + ret = goodix_int_sync(ts); + if (ret) + return ret; + msleep(50); /* T5: 50ms */ + return 0; +} + +/** + * goodix_get_gpio_config - Get GPIO config from ACPI/DT + * + * @ts: goodix_ts_data pointer + */ +static int goodix_get_gpio_config(struct goodix_ts_data *ts) +{ + struct device *dev; + struct gpio_desc *gpiod; + int ret; + + if (!ts->client) + return -EINVAL; + dev = &ts->client->dev; + + /* Get interrupt GPIO pin number */ + gpiod = devm_gpiod_get(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN); + if (IS_ERR(gpiod)) { + ret = PTR_ERR(gpiod); + dev_err(dev, "Failed to get %s GPIO: %d\n", + GOODIX_GPIO_INT_NAME, ret); + return ret; + } + ts->gpiod_int = gpiod; + + /* Get the reset line GPIO pin number */ + gpiod = devm_gpiod_get(dev, GOODIX_GPIO_RST_NAME, GPIOD_IN); + if (IS_ERR(gpiod)) { + ret = PTR_ERR(gpiod); + dev_err(dev, "Failed to get %s GPIO: %d\n", + GOODIX_GPIO_RST_NAME, ret); + return ret; + } + ts->gpiod_rst = gpiod; + + return 0; +} + /** * goodix_read_config - Read the embedded configuration of the panel * @@ -366,6 +454,17 @@ static int goodix_ts_probe(struct i2c_client *client, return error; } + error = goodix_get_gpio_config(ts); + if (error) + return error; + + /* reset the controller */ + error = goodix_reset(ts); + if (error) { + dev_err(&client->dev, "Controller reset failed.\n"); + return error; + } + goodix_read_config(ts); error = goodix_request_input_dev(ts, version_info, id_info);