Message ID | 20221128214408.165726-2-hdegoede@redhat.com (mailing list archive) |
---|---|
State | Superseded |
Headers |
Received: from vger.kernel.org ([23.128.96.18]) by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from <linux-media-owner@vger.kernel.org>) id 1ozlwD-000E5W-Nh; Mon, 28 Nov 2022 21:45:17 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233214AbiK1VpN (ORCPT <rfc822;mkrufky@linuxtv.org> + 1 other); Mon, 28 Nov 2022 16:45:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38912 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232801AbiK1VpM (ORCPT <rfc822;linux-media@vger.kernel.org>); Mon, 28 Nov 2022 16:45:12 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A77411DF25 for <linux-media@vger.kernel.org>; Mon, 28 Nov 2022 13:44:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1669671858; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HYgpL2606mVfO+98npo7eaosHXY5I8deinLTWhiViEE=; b=SozgTE4t+V2EvkMHIkAe+Nu6s/pDrW+MJ5WoSWW4GQOACsmp8PX4tQZzufBOeSKAmwVsSX lmS9rmXYJ6gP6L3gsAJTu5upA1BqCSREw60krIBSFQq5ZeqPV/k60JCVCYMaFKQV11BRFa fsg3gXgGGPc3CAVZwMTUeI/G+F+U0ak= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-197-XIfB4YCLNIye0mUOA4KgEA-1; Mon, 28 Nov 2022 16:44:15 -0500 X-MC-Unique: XIfB4YCLNIye0mUOA4KgEA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id AD33286C177; Mon, 28 Nov 2022 21:44:14 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.192.115]) by smtp.corp.redhat.com (Postfix) with ESMTP id 23AFD40C6EC2; Mon, 28 Nov 2022 21:44:13 +0000 (UTC) From: Hans de Goede <hdegoede@redhat.com> To: Mark Gross <markgross@kernel.org>, Andy Shevchenko <andy@kernel.org>, Bartosz Golaszewski <bgolaszewski@baylibre.com>, Linus Walleij <linus.walleij@linaro.org>, Daniel Scally <djrscally@gmail.com>, Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Hans de Goede <hdegoede@redhat.com>, platform-driver-x86@vger.kernel.org, linux-gpio@vger.kernel.org, Sakari Ailus <sakari.ailus@linux.intel.com>, Kate Hsuan <hpa@redhat.com>, linux-media@vger.kernel.org Subject: [PATCH 1/5] gpio: tps68470: Fix tps68470_gpio_get() reading from the wrong register Date: Mon, 28 Nov 2022 22:44:04 +0100 Message-Id: <20221128214408.165726-2-hdegoede@redhat.com> In-Reply-To: <20221128214408.165726-1-hdegoede@redhat.com> References: <20221128214408.165726-1-hdegoede@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-media.vger.kernel.org> X-Mailing-List: linux-media@vger.kernel.org X-LSpam-Score: -2.5 (--) X-LSpam-Report: No, score=-2.5 required=5.0 tests=BAYES_00=-1.9,DKIMWL_WL_HIGH=0.001,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1 autolearn=ham autolearn_force=no |
Series |
gpio/media/int3472: Add support for tps68470 privacy-LED output
|
|
Commit Message
Hans de Goede
Nov. 28, 2022, 9:44 p.m. UTC
For the regular GPIO pins the value should be read from TPS68470_REG_GPDI,
so that the actual value of the pin is read, rather then the value the pin
would output when put in output mode.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/gpio/gpio-tps68470.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Comments
On Mon, Nov 28, 2022 at 11:44 PM Hans de Goede <hdegoede@redhat.com> wrote: > > For the regular GPIO pins the value should be read from TPS68470_REG_GPDI, > so that the actual value of the pin is read, rather then the value the pin than > would output when put in output mode. I don't see it here and haven't checked the context, but the idea is to check the direction and return either input (if pin is in input mode) or [cached] output.If it's the case, the patch looks good to me. > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > --- > drivers/gpio/gpio-tps68470.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpio/gpio-tps68470.c b/drivers/gpio/gpio-tps68470.c > index aaddcabe9b35..778a72cf800c 100644 > --- a/drivers/gpio/gpio-tps68470.c > +++ b/drivers/gpio/gpio-tps68470.c > @@ -30,7 +30,7 @@ static int tps68470_gpio_get(struct gpio_chip *gc, unsigned int offset) > { > struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); > struct regmap *regmap = tps68470_gpio->tps68470_regmap; > - unsigned int reg = TPS68470_REG_GPDO; > + unsigned int reg = TPS68470_REG_GPDI; > int val, ret; > > if (offset >= TPS68470_N_REGULAR_GPIO) { > -- > 2.38.1 >
Hi, On 11/29/22 11:22, Andy Shevchenko wrote: > On Mon, Nov 28, 2022 at 11:44 PM Hans de Goede <hdegoede@redhat.com> wrote: >> >> For the regular GPIO pins the value should be read from TPS68470_REG_GPDI, >> so that the actual value of the pin is read, rather then the value the pin > > than Ack. >> would output when put in output mode. > > I don't see it here and haven't checked the context, but the idea is > to check the direction and return either input (if pin is in input > mode) or [cached] output.If it's the case, the patch looks good to me. No the idea is to always actually use the input register when reading the pins, independent of the input/output mode. Instead of always reading the [cached] output register value. The input buffer will still work when the device is in output mode and if somehow an external force is pushing the pin low/high against the output value then the input buffer will correctly reflect this (assuming the output is current limited and thus the magic smoke stays inside the chip). Regards, Hans > >> Signed-off-by: Hans de Goede <hdegoede@redhat.com> >> --- >> drivers/gpio/gpio-tps68470.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/gpio/gpio-tps68470.c b/drivers/gpio/gpio-tps68470.c >> index aaddcabe9b35..778a72cf800c 100644 >> --- a/drivers/gpio/gpio-tps68470.c >> +++ b/drivers/gpio/gpio-tps68470.c >> @@ -30,7 +30,7 @@ static int tps68470_gpio_get(struct gpio_chip *gc, unsigned int offset) >> { >> struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); >> struct regmap *regmap = tps68470_gpio->tps68470_regmap; >> - unsigned int reg = TPS68470_REG_GPDO; >> + unsigned int reg = TPS68470_REG_GPDI; >> int val, ret; >> >> if (offset >= TPS68470_N_REGULAR_GPIO) { >> -- >> 2.38.1 >> > >
On Tue, Nov 29, 2022 at 1:27 PM Hans de Goede <hdegoede@redhat.com> wrote: > On 11/29/22 11:22, Andy Shevchenko wrote: > > On Mon, Nov 28, 2022 at 11:44 PM Hans de Goede <hdegoede@redhat.com> wrote: > >> > >> For the regular GPIO pins the value should be read from TPS68470_REG_GPDI, > >> so that the actual value of the pin is read, rather then the value the pin > > > > than > > Ack. > > >> would output when put in output mode. > > > > I don't see it here and haven't checked the context, but the idea is > > to check the direction and return either input (if pin is in input > > mode) or [cached] output.If it's the case, the patch looks good to me. > > No the idea is to always actually use the input register when reading > the pins, independent of the input/output mode. Instead of always > reading the [cached] output register value. But why? This makes a little sense to me. > The input buffer will still work when the device is in output mode Does this hardware support HiZ? > and if somehow an external force is pushing the pin low/high against > the output value then the input buffer will correctly reflect this > (assuming the output is current limited and thus the magic smoke > stays inside the chip). Exactly, when smoke comes out, the hardware is broken and code, whatever is it, makes no difference at all.
Hi, On 11/29/22 12:56, Andy Shevchenko wrote: > On Tue, Nov 29, 2022 at 1:27 PM Hans de Goede <hdegoede@redhat.com> wrote: >> On 11/29/22 11:22, Andy Shevchenko wrote: >>> On Mon, Nov 28, 2022 at 11:44 PM Hans de Goede <hdegoede@redhat.com> wrote: >>>> >>>> For the regular GPIO pins the value should be read from TPS68470_REG_GPDI, >>>> so that the actual value of the pin is read, rather then the value the pin >>> >>> than >> >> Ack. >> >>>> would output when put in output mode. >>> >>> I don't see it here and haven't checked the context, but the idea is >>> to check the direction and return either input (if pin is in input >>> mode) or [cached] output.If it's the case, the patch looks good to me. >> >> No the idea is to always actually use the input register when reading >> the pins, independent of the input/output mode. Instead of always >> reading the [cached] output register value. > > But why? This makes a little sense to me. I don't understand what your problem is with this patch ? This is standard behavior for GPIO drivers, the get() callback always reads the actual pin values when there is a registers to get the actual pin-values. AFAIK this is no different from what countless other GPIO drivers do ? >> The input buffer will still work when the device is in output mode > > Does this hardware support HiZ? Yes the 7 standard GPIO pins can be put in input mode, aka HiZ mode. >> and if somehow an external force is pushing the pin low/high against >> the output value then the input buffer will correctly reflect this >> (assuming the output is current limited and thus the magic smoke >> stays inside the chip). > > Exactly, when smoke comes out, the hardware is broken and code, > whatever is it, makes no difference at all. The GPIO part of the TPS68470 supports open-drain outputs, to correctly get the actual value on the pin from the get() callback, the GPDI register must be used. And being able to detect some outside chip forcing the line low in open-drain mode is important to be able to e.g. implement a software I2C master. As I mentioned above actually using the input buffer value in the get() method is standard behavior for GPIO drivers, exactly for reasons like allowing a sw I2C master implementation to detect clock stretching or conflicts (in the multi master case). I really don't understand what is so controversial about this patch? Note the datasheet describes the GPDO / GPDI bit 0 values as: GPDO bit 0: "Control of the GPIO0 output" GPDI bit 0: "State of the GPIO0 input" So clearly GPDI is the correct register to use for the get() callback, which is what this patch is doing. Regards, Hans
On Tue, Nov 29, 2022 at 01:19:57PM +0100, Hans de Goede wrote: > On 11/29/22 12:56, Andy Shevchenko wrote: > > On Tue, Nov 29, 2022 at 1:27 PM Hans de Goede <hdegoede@redhat.com> wrote: > >> On 11/29/22 11:22, Andy Shevchenko wrote: > >>> On Mon, Nov 28, 2022 at 11:44 PM Hans de Goede <hdegoede@redhat.com> wrote: > >>>> > >>>> For the regular GPIO pins the value should be read from TPS68470_REG_GPDI, > >>>> so that the actual value of the pin is read, rather then the value the pin > >>> > >>> than > >> > >> Ack. > >> > >>>> would output when put in output mode. > >>> > >>> I don't see it here and haven't checked the context, but the idea is > >>> to check the direction and return either input (if pin is in input > >>> mode) or [cached] output.If it's the case, the patch looks good to me. > >> > >> No the idea is to always actually use the input register when reading > >> the pins, independent of the input/output mode. Instead of always > >> reading the [cached] output register value. > > > > But why? This makes a little sense to me. > > I don't understand what your problem is with this patch ? > > This is standard behavior for GPIO drivers, the get() callback > always reads the actual pin values when there is a registers > to get the actual pin-values. AFAIK this is no different from what > countless other GPIO drivers do ? If the GPIO is requested is output and the pin in the HiZ mode, what value should you return? > >> The input buffer will still work when the device is in output mode > > > > Does this hardware support HiZ? > > Yes the 7 standard GPIO pins can be put in input mode, aka HiZ mode. No, input and HiZ are two different states. If the hardware doesn't support the latter, then your patch doesn't make any difference indeed, except involving "in" buffer for "out" value. Which I consider an unneeded step instead of reading [cached] "out" value. [cached] here is used in a broader sense: either SW cache, or read back value from the GPIO out register (not all hardware support that). > >> and if somehow an external force is pushing the pin low/high against > >> the output value then the input buffer will correctly reflect this > >> (assuming the output is current limited and thus the magic smoke > >> stays inside the chip). > > > > Exactly, when smoke comes out, the hardware is broken and code, > > whatever is it, makes no difference at all. > > The GPIO part of the TPS68470 supports open-drain outputs, to correctly > get the actual value on the pin from the get() callback, the GPDI > register must be used. And being able to detect some outside chip > forcing the line low in open-drain mode is important to be able to > e.g. implement a software I2C master. Right, but for push-pull mode this is not needed, correct? > As I mentioned above actually using the input buffer value in > the get() method is standard behavior for GPIO drivers, exactly > for reasons like allowing a sw I2C master implementation to > detect clock stretching or conflicts (in the multi master case). > I really don't understand what is so controversial about this > patch? There are couple of remarks above: 1) what to read at the real HiZ mode ("in" and "out" buffers are disconnected from the pin) in case hardware supports it; 2) why to read "out" value via "in" buffer in case of push-pull mode. > Note the datasheet describes the GPDO / GPDI bit 0 values as: > > GPDO bit 0: "Control of the GPIO0 output" > GPDI bit 0: "State of the GPIO0 input" > > So clearly GPDI is the correct register to use for the get() > callback, which is what this patch is doing.
Hi, On 11/29/22 13:34, Andy Shevchenko wrote: > On Tue, Nov 29, 2022 at 01:19:57PM +0100, Hans de Goede wrote: >> On 11/29/22 12:56, Andy Shevchenko wrote: >>> On Tue, Nov 29, 2022 at 1:27 PM Hans de Goede <hdegoede@redhat.com> wrote: >>>> On 11/29/22 11:22, Andy Shevchenko wrote: >>>>> On Mon, Nov 28, 2022 at 11:44 PM Hans de Goede <hdegoede@redhat.com> wrote: >>>>>> >>>>>> For the regular GPIO pins the value should be read from TPS68470_REG_GPDI, >>>>>> so that the actual value of the pin is read, rather then the value the pin >>>>> >>>>> than >>>> >>>> Ack. >>>> >>>>>> would output when put in output mode. >>>>> >>>>> I don't see it here and haven't checked the context, but the idea is >>>>> to check the direction and return either input (if pin is in input >>>>> mode) or [cached] output.If it's the case, the patch looks good to me. >>>> >>>> No the idea is to always actually use the input register when reading >>>> the pins, independent of the input/output mode. Instead of always >>>> reading the [cached] output register value. >>> >>> But why? This makes a little sense to me. >> >> I don't understand what your problem is with this patch ? >> >> This is standard behavior for GPIO drivers, the get() callback >> always reads the actual pin values when there is a registers >> to get the actual pin-values. AFAIK this is no different from what >> countless other GPIO drivers do ? > > If the GPIO is requested is output and the pin in the HiZ mode, what value > should you return? The actual value measured on the pin. The only output + HiZ mode is the GPDO register saying the pin should be high while it is configured as an open-drain pin and then get() should return the actual value on the pin which might be high (pulled-up) or low, because of being pulled down by another open-drain output on the same bus (e.g. I2C) and presumably the caller wants to know the actual pin value to detect e.g. clock stretching with I2C. > >>>> The input buffer will still work when the device is in output mode >>> >>> Does this hardware support HiZ? >> >> Yes the 7 standard GPIO pins can be put in input mode, aka HiZ mode. > > No, input and HiZ are two different states. If the hardware doesn't > support the latter, then your patch doesn't make any difference indeed, except > involving "in" buffer for "out" value. Which I consider an unneeded > step instead of reading [cached] "out" value. See above. > [cached] here is used in a broader sense: either SW cache, or read back value > from the GPIO out register (not all hardware support that). > >>>> and if somehow an external force is pushing the pin low/high against >>>> the output value then the input buffer will correctly reflect this >>>> (assuming the output is current limited and thus the magic smoke >>>> stays inside the chip). >>> >>> Exactly, when smoke comes out, the hardware is broken and code, >>> whatever is it, makes no difference at all. >> >> The GPIO part of the TPS68470 supports open-drain outputs, to correctly >> get the actual value on the pin from the get() callback, the GPDI >> register must be used. And being able to detect some outside chip >> forcing the line low in open-drain mode is important to be able to >> e.g. implement a software I2C master. > > Right, but for push-pull mode this is not needed, correct? > >> As I mentioned above actually using the input buffer value in >> the get() method is standard behavior for GPIO drivers, exactly >> for reasons like allowing a sw I2C master implementation to >> detect clock stretching or conflicts (in the multi master case). > >> I really don't understand what is so controversial about this >> patch? > > There are couple of remarks above: > 1) what to read at the real HiZ mode ("in" and "out" buffers are disconnected > from the pin) in case hardware supports it; If your definition of real HiZ mode is the input buffer also being disconnected from the pin, then AFAICT from the datasheet this hw does not support real (see above for what I consider HiZ mode). > 2) why to read "out" value via "in" buffer in case of push-pull mode. Because it keeps the code KISS, because even then the bus might be short-circuited to ground? A better question is why would a GPIO API user ever call get() on a pin in push-pull mode. The only answer I can come up with is to get *the actual pin value* to e.g. detect a short-circuit on the bus to gnd / Vdd. >> Note the datasheet describes the GPDO / GPDI bit 0 values as: >> >> GPDO bit 0: "Control of the GPIO0 output" >> GPDI bit 0: "State of the GPIO0 input" >> >> So clearly GPDI is the correct register to use for the get() >> callback, which is what this patch is doing. > Regards, Hans
Hi Hans On 28/11/2022 21:44, Hans de Goede wrote: > For the regular GPIO pins the value should be read from TPS68470_REG_GPDI, > so that the actual value of the pin is read, rather then the value the pin > would output when put in output mode. > > Signed-off-by: Hans de Goede <hdegoede@redhat.com> Good spot: Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Just building the series to test it too > --- > drivers/gpio/gpio-tps68470.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpio/gpio-tps68470.c b/drivers/gpio/gpio-tps68470.c > index aaddcabe9b35..778a72cf800c 100644 > --- a/drivers/gpio/gpio-tps68470.c > +++ b/drivers/gpio/gpio-tps68470.c > @@ -30,7 +30,7 @@ static int tps68470_gpio_get(struct gpio_chip *gc, unsigned int offset) > { > struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); > struct regmap *regmap = tps68470_gpio->tps68470_regmap; > - unsigned int reg = TPS68470_REG_GPDO; > + unsigned int reg = TPS68470_REG_GPDI; > int val, ret; > > if (offset >= TPS68470_N_REGULAR_GPIO) {
diff --git a/drivers/gpio/gpio-tps68470.c b/drivers/gpio/gpio-tps68470.c index aaddcabe9b35..778a72cf800c 100644 --- a/drivers/gpio/gpio-tps68470.c +++ b/drivers/gpio/gpio-tps68470.c @@ -30,7 +30,7 @@ static int tps68470_gpio_get(struct gpio_chip *gc, unsigned int offset) { struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); struct regmap *regmap = tps68470_gpio->tps68470_regmap; - unsigned int reg = TPS68470_REG_GPDO; + unsigned int reg = TPS68470_REG_GPDI; int val, ret; if (offset >= TPS68470_N_REGULAR_GPIO) {