diff mbox

[v2,4/8] input: goodix: reset device at init

Message ID 1433774273-23103-5-git-send-email-irina.tirdea@intel.com
State Needs Review / ACK, archived
Headers show

Checks

Context Check Description
robh/checkpatch warning total: 1 errors, 0 warnings, 0 lines checked
robh/patch-applied success

Commit Message

Irina Tirdea June 8, 2015, 2:37 p.m. UTC
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.

This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).

For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI 5.1/device tree).
For ACPI, the pins can be specified using ACPI 5.1:

Device (STAC)
{
    Name (_HID, "GDIX1001")
    ...

    Method (_CRS, 0, Serialized)
    {
        Name (RBUF, ResourceTemplate ()
        {
            I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
                AddressingMode7Bit, "\\I2C0",
                0x00, ResourceConsumer, ,
                )

            GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
                "\\I2C0", 0x00, ResourceConsumer, ,
                 )
                 {   // Pin list
                     0
                 }

            GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
                IoRestrictionOutputOnly, "\\I2C0", 0x00,
                ResourceConsumer, ,
                )
                {
                     1
                }
        })
        Return (RBUF)
    }

    Name (_DSD,  Package ()
    {
        ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
        Package ()
        {
            Package (2) {"irq-gpio", Package() {^STAC, 0, 0, 0 }},
            Package (2) {"reset-gpio", Package() {^STAC, 1, 0, 0 }},
            ...
        }
    }

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                 | 100 +++++++++++++++++++++
 2 files changed, 105 insertions(+)

Comments

Bastien Nocera June 9, 2015, 3:34 p.m. UTC | #1
On Mon, 2015-06-08 at 17:37 +0300, Irina Tirdea wrote:
> After power on, it is recommended that the driver resets the device.
> The reset procedure timing is described in the datasheet and is used
> at device init (before writing device configuration) and
> for power management. It is a sequence of setting the interrupt
> and reset pins high/low at specific timing intervals. This procedure
> also includes setting the slave address to the one specified in the
> ACPI/device tree.

This breaks the touchscreen on my Onda v975w:
[  239.732858] Goodix-TS i2c-GDIX1001:00: ID 9271, version: 1020
[  239.732977] Goodix-TS i2c-GDIX1001:00: Failed to get reset GPIO: -16
[  239.736071] Goodix-TS: probe of i2c-GDIX1001:00 failed with error -16

This is the DSDT for that device:
https://bugzilla.kernel.org/attachment.cgi?id=149331
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bastien Nocera June 9, 2015, 3:53 p.m. UTC | #2
On Tue, 2015-06-09 at 17:34 +0200, Bastien Nocera wrote:
> On Mon, 2015-06-08 at 17:37 +0300, Irina Tirdea wrote:
> > After power on, it is recommended that the driver resets the 
> > device.
> > The reset procedure timing is described in the datasheet and is 
> > used
> > at device init (before writing device configuration) and
> > for power management. It is a sequence of setting the interrupt
> > and reset pins high/low at specific timing intervals. This 
> > procedure
> > also includes setting the slave address to the one specified in the
> > ACPI/device tree.
> 
> This breaks the touchscreen on my Onda v975w:
> [  239.732858] Goodix-TS i2c-GDIX1001:00: ID 9271, version: 1020
> [  239.732977] Goodix-TS i2c-GDIX1001:00: Failed to get reset GPIO: 
> -16
> [  239.736071] Goodix-TS: probe of i2c-GDIX1001:00 failed with error 
> -16
> 
> This is the DSDT for that device:
> https://bugzilla.kernel.org/attachment.cgi?id=149331

(Note that this means that I haven't been able to test any following
patches in that series than 4/8).
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Torokhov June 9, 2015, 5:57 p.m. UTC | #3
Hi Irina,

On Mon, Jun 08, 2015 at 05:37:49PM +0300, Irina Tirdea wrote:
> +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);

You need to handle -EPROBE_DEFER (suppress error) and especially -ENOENT error
codes, otherwise, as Bastien mentioned, you will break existing DTS.

Thanks.
Irina Tirdea June 23, 2015, 1:20 p.m. UTC | #4
> -----Original Message-----
> From: linux-input-owner@vger.kernel.org [mailto:linux-input-owner@vger.kernel.org] On Behalf Of Dmitry Torokhov
> Sent: 09 June, 2015 20:58
> To: Tirdea, Irina
> Cc: Bastien Nocera; Mark Rutland; linux-input@vger.kernel.org; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; Rob
> Herring; Pawel Moll; Ian Campbell; Kumar Gala; Purdila, Octavian
> Subject: Re: [PATCH v2 4/8] input: goodix: reset device at init
> 
> Hi Irina,
> 
> On Mon, Jun 08, 2015 at 05:37:49PM +0300, Irina Tirdea wrote:
> > +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);
> 
> You need to handle -EPROBE_DEFER (suppress error) and especially -ENOENT error
> codes, otherwise, as Bastien mentioned, you will break existing DTS.
> 

Yes, I will handle the -EPROBE_DEFER and -ENOENT for devices that might not have these
gpio pins connected or declared in ACPI/DTS. Since the following patches depend on these
pins, I will bypass the functionality for these devices (suspend/resume, esd, writing config
will not be available if gpio pins are not found).

Thanks,
Irina

> Thanks.
> 
> --
> Dmitry
> --
> 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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Irina Tirdea June 23, 2015, 1:23 p.m. UTC | #5
> -----Original Message-----

> From: linux-input-owner@vger.kernel.org [mailto:linux-input-owner@vger.kernel.org] On Behalf Of Bastien Nocera

> Sent: 09 June, 2015 18:53

> To: Tirdea, Irina

> Cc: Dmitry Torokhov; Mark Rutland; linux-input@vger.kernel.org; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; Rob

> Herring; Pawel Moll; Ian Campbell; Kumar Gala; Purdila, Octavian

> Subject: Re: [PATCH v2 4/8] input: goodix: reset device at init

> 

> On Tue, 2015-06-09 at 17:34 +0200, Bastien Nocera wrote:

> > On Mon, 2015-06-08 at 17:37 +0300, Irina Tirdea wrote:

> > > After power on, it is recommended that the driver resets the

> > > device.

> > > The reset procedure timing is described in the datasheet and is

> > > used

> > > at device init (before writing device configuration) and

> > > for power management. It is a sequence of setting the interrupt

> > > and reset pins high/low at specific timing intervals. This

> > > procedure

> > > also includes setting the slave address to the one specified in the

> > > ACPI/device tree.

> >

> > This breaks the touchscreen on my Onda v975w:

> > [  239.732858] Goodix-TS i2c-GDIX1001:00: ID 9271, version: 1020

> > [  239.732977] Goodix-TS i2c-GDIX1001:00: Failed to get reset GPIO:

> > -16

> > [  239.736071] Goodix-TS: probe of i2c-GDIX1001:00 failed with error

> > -16

> >

> > This is the DSDT for that device:

> > https://bugzilla.kernel.org/attachment.cgi?id=149331

> 


Oops. That's right - I am using named interrupts which are available only for ACPI 5.1, so 
devices already out there will not work.

The problem here is that handling -ENOENT will not help. The gpio pins are declared in the
ACPI DSDT, but are not named. The devm_gpiod_get API will look for the named interrupt
first and fallback to searching by index if not found. Index will be 0 in both cases, this is why
the first call will succeed and the second will fail with -EBUSY.

One way to handle this would be to use indexed gpio pins instead of named gpio pins:
e.g. consider the first gpio pin to be the reset pin and the second to be the interrupt pin.
This is used in other drivers as well, e.g. zforce_ts. The problem with this approach is that
any devices that declare the gpio pins in reversed order in the DSDT will not work and give
no warning (the pins will be requested successfully, but some of the functionality will not
work). The DSDT mentioned in https://bugzilla.kernel.org/attachment.cgi?id=149331 lists
the reset pin first, while I am working on some devices that declare the interrupt gpio pin
first.

Another way to handle this is to treat -EBUSY like -ENOENT and not use any functionality
that depends on the gpio pins. Unfortunately, this means we will not have suspend, esd and
custom configs even if the pins are connected on the board and available in ACPI(just not
named).

I would go with the first approach and document the order requested for the pins, but I would
like to hear what you think first. Is there a better way to do this?

> (Note that this means that I haven't been able to test any following

> patches in that series than 4/8).


Sure, that makes sense. The following patches depend on the gpio pins so they would not have
worked either.

Thanks,
Irina

> --

> 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
Bastien Nocera June 23, 2015, 2:12 p.m. UTC | #6
On Tue, 2015-06-23 at 13:23 +0000, Tirdea, Irina wrote:
> 
> > -----Original Message-----
> > From: linux-input-owner@vger.kernel.org [mailto:
> > linux-input-owner@vger.kernel.org] On Behalf Of Bastien Nocera
> > Sent: 09 June, 2015 18:53
> > To: Tirdea, Irina
> > Cc: Dmitry Torokhov; Mark Rutland; linux-input@vger.kernel.org; 
> > devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; Rob
> > Herring; Pawel Moll; Ian Campbell; Kumar Gala; Purdila, Octavian
> > Subject: Re: [PATCH v2 4/8] input: goodix: reset device at init
> > 
> > On Tue, 2015-06-09 at 17:34 +0200, Bastien Nocera wrote:
> > > On Mon, 2015-06-08 at 17:37 +0300, Irina Tirdea wrote:
> > > > After power on, it is recommended that the driver resets the
> > > > device.
> > > > The reset procedure timing is described in the datasheet and is
> > > > used
> > > > at device init (before writing device configuration) and
> > > > for power management. It is a sequence of setting the interrupt
> > > > and reset pins high/low at specific timing intervals. This
> > > > procedure
> > > > also includes setting the slave address to the one specified in 
> > > > the
> > > > ACPI/device tree.
> > > 
> > > This breaks the touchscreen on my Onda v975w:
> > > [  239.732858] Goodix-TS i2c-GDIX1001:00: ID 9271, version: 1020
> > > [  239.732977] Goodix-TS i2c-GDIX1001:00: Failed to get reset 
> > > GPIO:
> > > -16
> > > [  239.736071] Goodix-TS: probe of i2c-GDIX1001:00 failed with 
> > > error
> > > -16
> > > 
> > > This is the DSDT for that device:
> > > https://bugzilla.kernel.org/attachment.cgi?id=149331
> > 
> 
> Oops. That's right - I am using named interrupts which are available 
> only for ACPI 5.1, so 
> devices already out there will not work.
> 
> The problem here is that handling -ENOENT will not help. The gpio 
> pins are declared in the
> ACPI DSDT, but are not named. The devm_gpiod_get API will look for 
> the named interrupt
> first and fallback to searching by index if not found. Index will be 
> 0 in both cases, this is why
> the first call will succeed and the second will fail with -EBUSY.
> 
> One way to handle this would be to use indexed gpio pins instead of 
> named gpio pins:
> e.g. consider the first gpio pin to be the reset pin and the second 
> to be the interrupt pin.
> This is used in other drivers as well, e.g. zforce_ts. The problem 
> with this approach is that
> any devices that declare the gpio pins in reversed order in the DSDT 
> will not work and give
> no warning (the pins will be requested successfully, but some of the 
> functionality will not
> work). The DSDT mentioned in 
> https://bugzilla.kernel.org/attachment.cgi?id=149331 lists
> the reset pin first, while I am working on some devices that declare 
> the interrupt gpio pin
> first.
> 
> Another way to handle this is to treat -EBUSY like -ENOENT and not 
> use any functionality
> that depends on the gpio pins. Unfortunately, this means we will not 
> have suspend, esd and
> custom configs even if the pins are connected on the board and 
> available in ACPI(just not
> named).
> 
> I would go with the first approach and document the order requested 
> for the pins, but I would
> like to hear what you think first. Is there a better way to do this?
> 
> > (Note that this means that I haven't been able to test any 
> > following
> > patches in that series than 4/8).
> 
> Sure, that makes sense. The following patches depend on the gpio pins 
> so they would not have
> worked either.

We can apply quirks based on DMI information, so that devices with ACPI
in different orders will work after applying a quirk (as long as
there's a way to detect that it's in the wrong order, obviously).

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Octavian Purdila June 23, 2015, 2:50 p.m. UTC | #7
On Tue, Jun 23, 2015 at 5:12 PM, Bastien Nocera <hadess@hadess.net> wrote:
>
> On Tue, 2015-06-23 at 13:23 +0000, Tirdea, Irina wrote:
> >
> > > -----Original Message-----
> > > From: linux-input-owner@vger.kernel.org [mailto:
> > > linux-input-owner@vger.kernel.org] On Behalf Of Bastien Nocera
> > > Sent: 09 June, 2015 18:53
> > > To: Tirdea, Irina
> > > Cc: Dmitry Torokhov; Mark Rutland; linux-input@vger.kernel.org;
> > > devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; Rob
> > > Herring; Pawel Moll; Ian Campbell; Kumar Gala; Purdila, Octavian
> > > Subject: Re: [PATCH v2 4/8] input: goodix: reset device at init
> > >
> > > On Tue, 2015-06-09 at 17:34 +0200, Bastien Nocera wrote:
> > > > On Mon, 2015-06-08 at 17:37 +0300, Irina Tirdea wrote:
> > > > > After power on, it is recommended that the driver resets the
> > > > > device.
> > > > > The reset procedure timing is described in the datasheet and is
> > > > > used
> > > > > at device init (before writing device configuration) and
> > > > > for power management. It is a sequence of setting the interrupt
> > > > > and reset pins high/low at specific timing intervals. This
> > > > > procedure
> > > > > also includes setting the slave address to the one specified in
> > > > > the
> > > > > ACPI/device tree.
> > > >
> > > > This breaks the touchscreen on my Onda v975w:
> > > > [  239.732858] Goodix-TS i2c-GDIX1001:00: ID 9271, version: 1020
> > > > [  239.732977] Goodix-TS i2c-GDIX1001:00: Failed to get reset
> > > > GPIO:
> > > > -16
> > > > [  239.736071] Goodix-TS: probe of i2c-GDIX1001:00 failed with
> > > > error
> > > > -16
> > > >
> > > > This is the DSDT for that device:
> > > > https://bugzilla.kernel.org/attachment.cgi?id=149331
> > >
> >
> > Oops. That's right - I am using named interrupts which are available
> > only for ACPI 5.1, so
> > devices already out there will not work.
> >
> > The problem here is that handling -ENOENT will not help. The gpio
> > pins are declared in the
> > ACPI DSDT, but are not named. The devm_gpiod_get API will look for
> > the named interrupt
> > first and fallback to searching by index if not found. Index will be
> > 0 in both cases, this is why
> > the first call will succeed and the second will fail with -EBUSY.
> >
> > One way to handle this would be to use indexed gpio pins instead of
> > named gpio pins:
> > e.g. consider the first gpio pin to be the reset pin and the second
> > to be the interrupt pin.
> > This is used in other drivers as well, e.g. zforce_ts. The problem
> > with this approach is that
> > any devices that declare the gpio pins in reversed order in the DSDT
> > will not work and give
> > no warning (the pins will be requested successfully, but some of the
> > functionality will not
> > work). The DSDT mentioned in
> > https://bugzilla.kernel.org/attachment.cgi?id=149331 lists
> > the reset pin first, while I am working on some devices that declare
> > the interrupt gpio pin
> > first.
> >
> > Another way to handle this is to treat -EBUSY like -ENOENT and not
> > use any functionality
> > that depends on the gpio pins. Unfortunately, this means we will not
> > have suspend, esd and
> > custom configs even if the pins are connected on the board and
> > available in ACPI(just not
> > named).
> >
> > I would go with the first approach and document the order requested
> > for the pins, but I would
> > like to hear what you think first. Is there a better way to do this?
> >
> > > (Note that this means that I haven't been able to test any
> > > following
> > > patches in that series than 4/8).
> >
> > Sure, that makes sense. The following patches depend on the gpio pins
> > so they would not have
> > worked either.
>
> We can apply quirks based on DMI information, so that devices with ACPI
> in different orders will work after applying a quirk (as long as
> there's a way to detect that it's in the wrong order, obviously).
>

I think even using the ACPI id (_HID) should be enough (at least in
the cases we know so far) to make the difference in how the pins are
used.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Irina Tirdea June 29, 2015, 4:04 p.m. UTC | #8
> -----Original Message-----

> From: Octavian Purdila [mailto:octavian.purdila@intel.com]

> Sent: 23 June, 2015 17:51

> To: Bastien Nocera

> Cc: Tirdea, Irina; Dmitry Torokhov; Mark Rutland; linux-input@vger.kernel.org; devicetree@vger.kernel.org; linux-

> kernel@vger.kernel.org; Rob Herring; Pawel Moll; Ian Campbell; Kumar Gala

> Subject: Re: [PATCH v2 4/8] input: goodix: reset device at init

> 

> On Tue, Jun 23, 2015 at 5:12 PM, Bastien Nocera <hadess@hadess.net> wrote:

> >

> > On Tue, 2015-06-23 at 13:23 +0000, Tirdea, Irina wrote:

> > >

> > > > -----Original Message-----

> > > > From: linux-input-owner@vger.kernel.org [mailto:

> > > > linux-input-owner@vger.kernel.org] On Behalf Of Bastien Nocera

> > > > Sent: 09 June, 2015 18:53

> > > > To: Tirdea, Irina

> > > > Cc: Dmitry Torokhov; Mark Rutland; linux-input@vger.kernel.org;

> > > > devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; Rob

> > > > Herring; Pawel Moll; Ian Campbell; Kumar Gala; Purdila, Octavian

> > > > Subject: Re: [PATCH v2 4/8] input: goodix: reset device at init

> > > >

> > > > On Tue, 2015-06-09 at 17:34 +0200, Bastien Nocera wrote:

> > > > > On Mon, 2015-06-08 at 17:37 +0300, Irina Tirdea wrote:

> > > > > > After power on, it is recommended that the driver resets the

> > > > > > device.

> > > > > > The reset procedure timing is described in the datasheet and is

> > > > > > used

> > > > > > at device init (before writing device configuration) and

> > > > > > for power management. It is a sequence of setting the interrupt

> > > > > > and reset pins high/low at specific timing intervals. This

> > > > > > procedure

> > > > > > also includes setting the slave address to the one specified in

> > > > > > the

> > > > > > ACPI/device tree.

> > > > >

> > > > > This breaks the touchscreen on my Onda v975w:

> > > > > [  239.732858] Goodix-TS i2c-GDIX1001:00: ID 9271, version: 1020

> > > > > [  239.732977] Goodix-TS i2c-GDIX1001:00: Failed to get reset

> > > > > GPIO:

> > > > > -16

> > > > > [  239.736071] Goodix-TS: probe of i2c-GDIX1001:00 failed with

> > > > > error

> > > > > -16

> > > > >

> > > > > This is the DSDT for that device:

> > > > > https://bugzilla.kernel.org/attachment.cgi?id=149331

> > > >

> > >

> > > Oops. That's right - I am using named interrupts which are available

> > > only for ACPI 5.1, so

> > > devices already out there will not work.

> > >

> > > The problem here is that handling -ENOENT will not help. The gpio

> > > pins are declared in the

> > > ACPI DSDT, but are not named. The devm_gpiod_get API will look for

> > > the named interrupt

> > > first and fallback to searching by index if not found. Index will be

> > > 0 in both cases, this is why

> > > the first call will succeed and the second will fail with -EBUSY.

> > >

> > > One way to handle this would be to use indexed gpio pins instead of

> > > named gpio pins:

> > > e.g. consider the first gpio pin to be the reset pin and the second

> > > to be the interrupt pin.

> > > This is used in other drivers as well, e.g. zforce_ts. The problem

> > > with this approach is that

> > > any devices that declare the gpio pins in reversed order in the DSDT

> > > will not work and give

> > > no warning (the pins will be requested successfully, but some of the

> > > functionality will not

> > > work). The DSDT mentioned in

> > > https://bugzilla.kernel.org/attachment.cgi?id=149331 lists

> > > the reset pin first, while I am working on some devices that declare

> > > the interrupt gpio pin

> > > first.

> > >

> > > Another way to handle this is to treat -EBUSY like -ENOENT and not

> > > use any functionality

> > > that depends on the gpio pins. Unfortunately, this means we will not

> > > have suspend, esd and

> > > custom configs even if the pins are connected on the board and

> > > available in ACPI(just not

> > > named).

> > >

> > > I would go with the first approach and document the order requested

> > > for the pins, but I would

> > > like to hear what you think first. Is there a better way to do this?

> > >

> > > > (Note that this means that I haven't been able to test any

> > > > following

> > > > patches in that series than 4/8).

> > >

> > > Sure, that makes sense. The following patches depend on the gpio pins

> > > so they would not have

> > > worked either.

> >

> > We can apply quirks based on DMI information, so that devices with ACPI

> > in different orders will work after applying a quirk (as long as

> > there's a way to detect that it's in the wrong order, obviously).

> >

> 

> I think even using the ACPI id (_HID) should be enough (at least in

> the cases we know so far) to make the difference in how the pins are

> used.


Thanks for the suggestions Bastien and Octavian!
I will use the ACPI ID in v3 considering the ACPI table Bastien has mentioned [1].

Thanks,
Irina

[1] https://bugzilla.kernel.org/attachment.cgi?id=149331
diff mbox

Patch

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 7cd3780..c345eb7 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -24,6 +24,7 @@ 
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
+#include <linux/gpio.h>
 #include <linux/of.h>
 #include <asm/unaligned.h>
 
@@ -34,8 +35,13 @@  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
@@ -186,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
  *
@@ -365,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);