From owner-svn-src-all@freebsd.org Tue Jul 21 07:35:04 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id BD31837A5AF; Tue, 21 Jul 2020 07:35:04 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4B9r3D4bMyz4G0M; Tue, 21 Jul 2020 07:35:04 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 819241AC11; Tue, 21 Jul 2020 07:35:04 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 06L7Z41A057414; Tue, 21 Jul 2020 07:35:04 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 06L7Z4HM057413; Tue, 21 Jul 2020 07:35:04 GMT (envelope-from avg@FreeBSD.org) Message-Id: <202007210735.06L7Z4HM057413@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Tue, 21 Jul 2020 07:35:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r363382 - head/sys/dev/gpio X-SVN-Group: head X-SVN-Commit-Author: avg X-SVN-Commit-Paths: head/sys/dev/gpio X-SVN-Commit-Revision: 363382 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Jul 2020 07:35:04 -0000 Author: avg Date: Tue Jul 21 07:35:03 2020 New Revision: 363382 URL: https://svnweb.freebsd.org/changeset/base/363382 Log: gpioiic: never drive lines active high I2C communication is done by a combination of driving a line low or letting it float, so that it is either pulled up or driven low by another party. r355276 besides the stated goal of the change -- using the new GPIO API -- also changed the logic, so that active state is signaled by actively driving a line. That worked with iicbb prior to r362042, but stopped working after that commit on at least some hardware. My guess that the breakage was related to getting an ACK bit. A device expected to be able to drive SDA actively low, but controller was actively driving it high for some time. Anyway, this change seems to fix the problem. Tested using gpioiic on Orange Pi PC Plus with HTU21 sensor. Reported by: Nick Kostirya Reviewed by: manu MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D25684 Modified: head/sys/dev/gpio/gpioiic.c Modified: head/sys/dev/gpio/gpioiic.c ============================================================================== --- head/sys/dev/gpio/gpioiic.c Mon Jul 20 23:57:53 2020 (r363381) +++ head/sys/dev/gpio/gpioiic.c Tue Jul 21 07:35:03 2020 (r363382) @@ -191,16 +191,14 @@ static void gpioiic_setsda(device_t dev, int val) { struct gpioiic_softc *sc = device_get_softc(dev); - int err; - /* - * Some controllers cannot set an output value while a pin is in input - * mode; in that case we set the pin again after changing mode. - */ - err = gpio_pin_set_active(sc->sdapin, val); - gpio_pin_setflags(sc->sdapin, GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN); - if (err != 0) - gpio_pin_set_active(sc->sdapin, val); + if (val) { + gpio_pin_setflags(sc->sdapin, GPIO_PIN_INPUT); + } else { + gpio_pin_setflags(sc->sdapin, + GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN); + gpio_pin_set_active(sc->sdapin, 0); + } } static void @@ -208,8 +206,13 @@ gpioiic_setscl(device_t dev, int val) { struct gpioiic_softc *sc = device_get_softc(dev); - gpio_pin_setflags(sc->sclpin, GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN); - gpio_pin_set_active(sc->sclpin, val); + if (val) { + gpio_pin_setflags(sc->sclpin, GPIO_PIN_INPUT); + } else { + gpio_pin_setflags(sc->sclpin, + GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN); + gpio_pin_set_active(sc->sclpin, 0); + } } static int