From patchwork Mon May 21 16:46:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Rini X-Patchwork-Id: 160389 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 6ABACB6F86 for ; Tue, 22 May 2012 02:47:10 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9AF16280D9; Mon, 21 May 2012 18:47:00 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id crdjjXr0RsHO; Mon, 21 May 2012 18:47:00 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0DB4E280DB; Mon, 21 May 2012 18:46:52 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id AE2D5280C0 for ; Mon, 21 May 2012 18:46:48 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Mk7z0EdX-7ug for ; Mon, 21 May 2012 18:46:47 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pb0-f44.google.com (mail-pb0-f44.google.com [209.85.160.44]) by theia.denx.de (Postfix) with ESMTPS id 0A5FF280B6 for ; Mon, 21 May 2012 18:46:44 +0200 (CEST) Received: by pbcwy7 with SMTP id wy7so6507839pbc.3 for ; Mon, 21 May 2012 09:46:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=mNR5ON2sT/lhVSKq6Frv8nwsJ3kJcTLEuKUFvShmG2Q=; b=BHhWM8EO8Q2fhGToQXV5jkosrGI+Zk1mdNgDa7iNtasBzAMdFOpzwKOzLWxTwV9y17 xCXbB7MzX3899vB7qB4yKLfGJdepzNrtTdh4jUCM2JCOH6wxPicuZXqoQE73MzJnA8Ex 90Sx2icE9RSI35T6QFcSkiUfCss5XbwITRl4F+/4pv0emz86cLF2mlnNvmfL3W4tLnil EFs+cKF7SpGHVxnTfSjUK/SOBPw8DskY/GHJAeyaWvgXOqD3nzgVT0cUakSUQ2oho7Od Y2Zv6cm6EgPrxsws1F1kLoU3plEgOCEK+BoFXMq+dvjv5UQVu+qgdGsbps+lJhm1Mt1D Zj5w== Received: by 10.68.225.230 with SMTP id rn6mr12246689pbc.70.1337618802019; Mon, 21 May 2012 09:46:42 -0700 (PDT) Received: from bill-the-cat.ph.cox.net (ip68-230-54-74.ph.ph.cox.net. [68.230.54.74]) by mx.google.com with ESMTPS id in7sm14952395pbc.23.2012.05.21.09.46.40 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 21 May 2012 09:46:41 -0700 (PDT) From: Tom Rini To: u-boot@lists.denx.de Date: Mon, 21 May 2012 09:46:29 -0700 Message-Id: <1337618793-13934-2-git-send-email-trini@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1337618793-13934-1-git-send-email-trini@ti.com> References: <1337618793-13934-1-git-send-email-trini@ti.com> Cc: Heiko Schocher Subject: [U-Boot] [PATCH 1/5] Revert "I2C: OMAP: detect more devices when probing an i2c bus" X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This reverts commit 0e57968a215d1b9d271f3fa5bebeddeaea0c8075. The short version of the original commit is that some i2c devices cannot be probed via read as they NAK the first cycle, so try and probe via a write that we abort before it writes to the device. This however is not allowed by the TRM for any of these parts. The section on I2C_CON (table 17-35 I2C_CON for am/dm37x for example) says you must not change the register while STT has been set. On these parts, the unpredictable behavior that the chip exhibits is not problematic. On OMAP4 however it results in the chip being in a bad state: Panda # i2c probe Valid chip addresses: 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F Panda # i2c md 50 0 timed out in wait_for_pin: I2C_STAT=0 I2C read: I/O error Error reading the chip. We must revert the original behavior to bring probe back into line with the TRM. Cc: Nick Thompson Cc: Heiko Schocher Signed-off-by: Tom Rini Acked-by: Heiko Schocher --- drivers/i2c/omap24xx_i2c.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index a7ffd95..3a50417 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -255,23 +255,43 @@ int i2c_probe(uchar chip) /* wait until bus not busy */ wait_for_bb(); - /* try to write one byte */ + /* try to read one byte */ writew(1, &i2c_base->cnt); /* set slave address */ writew(chip, &i2c_base->sa); /* stop bit needed here */ - writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | - I2C_CON_STP, &i2c_base->con); - - status = wait_for_pin(); + writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, &i2c_base->con); - /* check for ACK (!NAK) */ - if (!(status & I2C_STAT_NACK)) - res = 0; - - /* abort transfer (force idle state) */ - writew(0, &i2c_base->con); + while (1) { + status = wait_for_pin(); + if (status == 0 || status & I2C_STAT_AL) { + res = 1; + goto probe_exit; + } + if (status & I2C_STAT_NACK) { + res = 1; + writew(0xff, &i2c_base->stat); + writew (readw (&i2c_base->con) | I2C_CON_STP, &i2c_base->con); + wait_for_bb (); + break; + } + if (status & I2C_STAT_ARDY) { + writew(I2C_STAT_ARDY, &i2c_base->stat); + break; + } + if (status & I2C_STAT_RRDY) { + res = 0; +#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \ + defined(CONFIG_OMAP44XX) + readb(&i2c_base->data); +#else + readw(&i2c_base->data); +#endif + writew(I2C_STAT_RRDY, &i2c_base->stat); + } + } +probe_exit: flush_fifo(); /* don't allow any more data in... we don't want it. */ writew(0, &i2c_base->cnt);