From owner-svn-src-head@FreeBSD.ORG Fri Oct 24 22:06:22 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C4509A67; Fri, 24 Oct 2014 22:06:22 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AFDE95F1; Fri, 24 Oct 2014 22:06:22 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s9OM6M1b075385; Fri, 24 Oct 2014 22:06:22 GMT (envelope-from loos@FreeBSD.org) Received: (from loos@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s9OM6MxU075383; Fri, 24 Oct 2014 22:06:22 GMT (envelope-from loos@FreeBSD.org) Message-Id: <201410242206.s9OM6MxU075383@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: loos set sender to loos@FreeBSD.org using -f From: Luiz Otavio O Souza Date: Fri, 24 Oct 2014 22:06:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r273610 - head/sys/arm/broadcom/bcm2835 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Oct 2014 22:06:23 -0000 Author: loos Date: Fri Oct 24 22:06:21 2014 New Revision: 273610 URL: https://svnweb.freebsd.org/changeset/base/273610 Log: Add an iicbus_reset() method to bcm2835_bsc. While it is generally not used for kernel devices it is used by i2c(8). This fix the 'error: Device not configured' when i2c(8) tries to reset the controller, as an example: # i2c -r Resetting I2C controller on /dev/iic0: error: Device not configured For now use conservative settings for default i2c speeds. MFC after: 1 week Modified: head/sys/arm/broadcom/bcm2835/bcm2835_bsc.c head/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h Modified: head/sys/arm/broadcom/bcm2835/bcm2835_bsc.c ============================================================================== --- head/sys/arm/broadcom/bcm2835/bcm2835_bsc.c Fri Oct 24 22:00:25 2014 (r273609) +++ head/sys/arm/broadcom/bcm2835/bcm2835_bsc.c Fri Oct 24 22:06:21 2014 (r273610) @@ -210,6 +210,8 @@ static void bcm_bsc_reset(struct bcm_bsc_softc *sc) { + /* Enable the BSC Controller, disable interrupts. */ + BCM_BSC_WRITE(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_I2CEN); /* Clear pending interrupts. */ BCM_BSC_WRITE(sc, BCM_BSC_STATUS, BCM_BSC_STATUS_CLKT | BCM_BSC_STATUS_ERR | BCM_BSC_STATUS_DONE); @@ -302,7 +304,6 @@ bcm_bsc_attach(device_t dev) /* Enable the BSC controller. Flush the FIFO. */ BCM_BSC_LOCK(sc); - BCM_BSC_WRITE(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_I2CEN); bcm_bsc_reset(sc); BCM_BSC_UNLOCK(sc); @@ -351,9 +352,8 @@ bcm_bsc_intr(void *arg) /* Check for errors. */ if (status & (BCM_BSC_STATUS_CLKT | BCM_BSC_STATUS_ERR)) { /* Disable interrupts. */ - BCM_BSC_WRITE(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_I2CEN); - sc->sc_flags |= BCM_I2C_ERROR; bcm_bsc_reset(sc); + sc->sc_flags |= BCM_I2C_ERROR; wakeup(sc->sc_dev); BCM_BSC_UNLOCK(sc); return; @@ -375,7 +375,6 @@ bcm_bsc_intr(void *arg) if (status & BCM_BSC_STATUS_DONE) { /* Disable interrupts. */ - BCM_BSC_WRITE(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_I2CEN); bcm_bsc_reset(sc); wakeup(sc->sc_dev); } @@ -459,6 +458,38 @@ bcm_bsc_transfer(device_t dev, struct ii return (err); } +static int +bcm_bsc_iicbus_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) +{ + struct bcm_bsc_softc *sc; + uint32_t freq; + + sc = device_get_softc(dev); + BCM_BSC_LOCK(sc); + bcm_bsc_reset(sc); + freq = 0; + switch (speed) { + case IIC_SLOW: + freq = BCM_BSC_SLOW; + break; + case IIC_FAST: + freq = BCM_BSC_FAST; + break; + case IIC_FASTEST: + freq = BCM_BSC_FASTEST; + break; + case IIC_UNKNOWN: + default: + /* Reuse last frequency. */ + break; + } + if (freq != 0) + BCM_BSC_WRITE(sc, BCM_BSC_CLOCK, BCM_BSC_CORE_CLK / freq); + BCM_BSC_UNLOCK(sc); + + return (IIC_ENOADDR); +} + static phandle_t bcm_bsc_get_node(device_t bus, device_t dev) { @@ -474,6 +505,7 @@ static device_method_t bcm_bsc_methods[] DEVMETHOD(device_detach, bcm_bsc_detach), /* iicbus interface */ + DEVMETHOD(iicbus_reset, bcm_bsc_iicbus_reset), DEVMETHOD(iicbus_callback, iicbus_null_callback), DEVMETHOD(iicbus_transfer, bcm_bsc_transfer), Modified: head/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h ============================================================================== --- head/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h Fri Oct 24 22:00:25 2014 (r273609) +++ head/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h Fri Oct 24 22:06:21 2014 (r273610) @@ -56,6 +56,10 @@ struct bcm_bsc_softc { #define BCM_I2C_READ 0x02 #define BCM_I2C_ERROR 0x04 +#define BCM_BSC_SLOW 10000 /* 10 kHz. */ +#define BCM_BSC_FAST 50000 /* 50 kHz. */ +#define BCM_BSC_FASTEST 100000 /* 100 kHz. */ + #define BCM_BSC_WRITE(_sc, _off, _val) \ bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val) #define BCM_BSC_READ(_sc, _off) \