From patchwork Fri Apr 11 08:41:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shaveta Leekha X-Patchwork-Id: 338427 X-Patchwork-Delegate: hs@denx.de 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 A201714008A for ; Fri, 11 Apr 2014 18:42:20 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9559C4B788; Fri, 11 Apr 2014 10:42:18 +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 jTCC579x1+2h; Fri, 11 Apr 2014 10:42:18 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C9BF34B779; Fri, 11 Apr 2014 10:42:15 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 54E334B779 for ; Fri, 11 Apr 2014 10:42:11 +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 qgZuZ2EImPii for ; Fri, 11 Apr 2014 10:42:08 +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 co9outboundpool.messaging.microsoft.com (co9ehsobe004.messaging.microsoft.com [207.46.163.27]) by theia.denx.de (Postfix) with ESMTPS id 4BEFF4B778 for ; Fri, 11 Apr 2014 10:42:05 +0200 (CEST) Received: from mail68-co9-R.bigfish.com (10.236.132.252) by CO9EHSOBE006.bigfish.com (10.236.130.69) with Microsoft SMTP Server id 14.1.225.22; Fri, 11 Apr 2014 08:41:37 +0000 Received: from mail68-co9 (localhost [127.0.0.1]) by mail68-co9-R.bigfish.com (Postfix) with ESMTP id 1E4C9200E6 for ; Fri, 11 Apr 2014 08:41:37 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 1 X-BigFish: VS1(zzd799hzz1f42h2148h1ee6h1de0h1fdah21bdh2073h2146h1202h1e76h2189h1d1ah1d2ah1fc6h208chzz1de098h8275bh1de097hz2dh87h2a8h839hd24he5bhf0ah107ah11b5h121eh1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h14afh1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1b2fh2222h224fh1fb3h1d0ch1d2eh1d3fh1dc1h1dfeh1dffh1e1dh1e23h1fe8h1ff5h2218h2216h226dh22d0h24afh2327h2336h2438h2461h2487h24d7h2516h2545h255eh25cch25f6h2605h268bh26d3h2388i1151h1155h) X-FB-DOMAIN-IP-MATCH: fail Received: from mail68-co9 (localhost.localdomain [127.0.0.1]) by mail68-co9 (MessageSwitch) id 1397205694542331_3447; Fri, 11 Apr 2014 08:41:34 +0000 (UTC) Received: from CO9EHSMHS032.bigfish.com (unknown [10.236.132.242]) by mail68-co9.bigfish.com (Postfix) with ESMTP id 74F8C160047; Fri, 11 Apr 2014 08:41:34 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CO9EHSMHS032.bigfish.com (10.236.130.42) with Microsoft SMTP Server (TLS) id 14.16.227.3; Fri, 11 Apr 2014 08:41:34 +0000 Received: from az84smr01.freescale.net (10.64.34.197) by 039-SN1MMR1-004.039d.mgd.msft.net (10.84.1.14) with Microsoft SMTP Server (TLS) id 14.3.174.2; Fri, 11 Apr 2014 08:41:59 +0000 Received: from nmglablinux22.freescale.com (nmglablinux22.zin33.ap.freescale.net [10.232.20.244]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id s3B8ftbP027817; Fri, 11 Apr 2014 01:41:57 -0700 Received: by nmglablinux22.freescale.com (Postfix, from userid 65007187) id A85555DC8B; Fri, 11 Apr 2014 14:11:54 +0530 (IST) From: Shaveta Leekha To: Date: Fri, 11 Apr 2014 14:11:53 +0530 Message-ID: <1397205713-14076-1-git-send-email-shaveta@freescale.com> X-Mailer: git-send-email 1.7.6.GIT MIME-Version: 1.0 X-OriginatorOrg: sigmatel.com X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% X-FOPE-CONNECTOR: Id%0$Dn%FREESCALE.MAIL.ONMICROSOFT.COM$RO%1$TLS%0$FQDN%$TlsDn% Cc: Poonam@theia.denx.de Subject: [U-Boot] [PATCH] drivers/i2c/fsl_i2c: modify i2c_read to handle multi-byte write 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: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Most of the I2C slaves support accesses in the typical style that is : read/write series of bytes at particular address offset. These transactions look like:" (1) START:Address:Tx:Offset:RESTART:Address[0..4]:Tx/Rx:data[0..n]:STOP" However there are certain devices which support accesses in terms of the transactions as follows: (2) "START:Address:Tx:Txdata[0..n1]:Clock_stretching: RESTART:Address:Rx:data[0..n2]" Here Txdata is typically a command and some associated data, similarly Rxdata could be command status plus some data received as a response to the command sent. Type (1) transactions are currently supportd in the i2c driver using i2c_read and i2c_write APIs. I2C EEPROMs, RTC, etc fall in this category. To handle type (2) along with type (1) transactions, i2c_read() function has been modified. Signed-off-by: Shaveta Leekha Signed-off-by: Poonam Aggrwal --- drivers/i2c/fsl_i2c.c | 41 ++++++++++++++++++++++++++++++++++------- 1 files changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c index 291ad94..aa159f8 100644 --- a/drivers/i2c/fsl_i2c.c +++ b/drivers/i2c/fsl_i2c.c @@ -423,18 +423,45 @@ fsl_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, int alen, u8 *data, struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr]; int i = -1; /* signal error */ u8 *a = (u8*)&addr; + int len = alen * -1; if (i2c_wait4bus(adap) < 0) return -1; - if ((!length || alen > 0) - && i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0 - && __i2c_write(adap, &a[4 - alen], alen) == alen) - i = 0; /* No error so far */ + /* To handle the need of I2C devices that require to write few bytes + * (more than 4 bytes of address as in the case of else part) + * of data before reading, Negative equivalent of length(bytes to write) + * is passed, but used the +ve part of len for writing data + */ + if (alen < 0) { + /* Generate a START and send the Address and + * the Tx Bytes to the slave. + * "START: Address: Write bytes data[len]" + * IF part supports writing any number of bytes in contrast + * to the else part, which supports writing address offset + * of upto 4 bytes only. + * bytes that need to be written are passed in + * "data", which will eventually keep the data READ, + * after writing the len bytes out of it + */ + if (i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0) + i = __i2c_write(adap, data, len); + + if (i != len) + return -1; - if (length && - i2c_write_addr(adap, dev, I2C_READ_BIT, alen ? 1 : 0) != 0) - i = __i2c_read(adap, data, length); + if (length && i2c_write_addr(adap, dev, I2C_READ_BIT, 1) != 0) + i = __i2c_read(adap, data, length); + } else { + if ((!length || alen > 0) && + i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0 && + __i2c_write(adap, &a[4 - alen], alen) == alen) + i = 0; /* No error so far */ + + if (length && + i2c_write_addr(adap, dev, I2C_READ_BIT, alen ? 1 : 0) != 0) + i = __i2c_read(adap, data, length); + } writeb(I2C_CR_MEN, &device->cr);