From patchwork Wed Jan 22 08:46:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 313168 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 C60C02C00AC for ; Wed, 22 Jan 2014 19:46:48 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id F41144B5B9; Wed, 22 Jan 2014 09:46:43 +0100 (CET) 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 JDBbswgkStHc; Wed, 22 Jan 2014 09:46:43 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7AFBD4B5BE; Wed, 22 Jan 2014 09:46:33 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 283154B5A9 for ; Wed, 22 Jan 2014 09:46:26 +0100 (CET) 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 mFB2T45ujo60 for ; Wed, 22 Jan 2014 09:46:23 +0100 (CET) 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-ea0-f176.google.com (mail-ea0-f176.google.com [209.85.215.176]) by theia.denx.de (Postfix) with ESMTPS id 253AC4B5AA for ; Wed, 22 Jan 2014 09:46:16 +0100 (CET) Received: by mail-ea0-f176.google.com with SMTP id h14so4264508eaj.21 for ; Wed, 22 Jan 2014 00:46:14 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:in-reply-to:references:content-type; bh=dOdvIjQpcN6DnsKtog8/9wDlR8M0f9zfMBy8X7MheVM=; b=mDYJpVwsR7LuBXynbwUEth/tJ7XagQLCHCkJXyifLuYMyovrkMBAiobzhBqWuqa5oM s++Nemyjhi7VLBaRXZG43U4xplWFp3qD7KTGMnBzF774+4fsHMeEJ1caEx9fArlidCWY 8A88+/VoxUx7t/WjCBAWBT7ACHTj3Kz8Vz5WhOECRc8GzNau0a3ea2yaP2T2bLPz0PFi +ejBMl7FLnBtiN7VNL3zfsnd4oC4lBFepCcynxi/pChO1ue2ZStsvIWOHPxx0hAgpgfI BWH1PRgLG9EZbzaUELt2pHzSh8NSNOHh0/4e0O9jXcsYVJ83as9rHnxuN3SnPxhtcm67 Bo3g== X-Gm-Message-State: ALoCoQn++RQoZZruVcnX2eBp+JnU6u5Gwqds0zY6O3xr6Oh92Cv9+m29xkLr2Ss97qjmCRaFzJcZ X-Received: by 10.14.113.199 with SMTP id a47mr234652eeh.41.1390380374851; Wed, 22 Jan 2014 00:46:14 -0800 (PST) Received: from localhost (nat-63.starnet.cz. [178.255.168.63]) by mx.google.com with ESMTPSA id v7sm24438881eel.2.2014.01.22.00.46.11 for (version=TLSv1.1 cipher=RC4-SHA bits=128/128); Wed, 22 Jan 2014 00:46:13 -0800 (PST) From: Michal Simek To: Michal Simek , u-boot@lists.denx.de, Heiko Schocher Date: Wed, 22 Jan 2014 09:46:08 +0100 Message-Id: X-Mailer: git-send-email 1.8.2.3 In-Reply-To: <91aa2703a9aa115669abd6fce8c7761d2695f476.1390380363.git.michal.simek@xilinx.com> References: <91aa2703a9aa115669abd6fce8c7761d2695f476.1390380363.git.michal.simek@xilinx.com> In-Reply-To: <91aa2703a9aa115669abd6fce8c7761d2695f476.1390380363.git.michal.simek@xilinx.com> References: <91aa2703a9aa115669abd6fce8c7761d2695f476.1390380363.git.michal.simek@xilinx.com> Cc: Michael Burr Subject: [U-Boot] [PATCH v2 2/2] i2c: zynq: Add support for the second i2c controller 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 From: Michael Burr Initialize the second i2c controller. Signed-off-by: Michael Burr Signed-off-by: Michal Simek --- Changes in v2: None Changes in v1: - Based on original thread from Michael Burr http://lists.denx.de/pipermail/u-boot/2013-October/165017.html Heiko did some changes in this mainline patch "i2c, zynq: convert zynq i2c driver to new multibus/multiadapter framework" (sha1: 0bdffe71fddeaa46768a39305797e4512dee0f15) - MS rebase on latest&greatest drivers/i2c/zynq_i2c.c | 44 ++++++++++++++++++++++++++----------------- include/configs/zynq-common.h | 6 +++--- 2 files changed, 30 insertions(+), 20 deletions(-) -- 1.8.2.3 diff --git a/drivers/i2c/zynq_i2c.c b/drivers/i2c/zynq_i2c.c index 11ef0f8..f1f6513 100644 --- a/drivers/i2c/zynq_i2c.c +++ b/drivers/i2c/zynq_i2c.c @@ -64,19 +64,21 @@ struct zynq_i2c_registers { #define ZYNQ_I2C_FIFO_DEPTH 16 #define ZYNQ_I2C_TRANSFERT_SIZE_MAX 255 /* Controller transfer limit */ -#if defined(CONFIG_ZYNQ_I2C0) -# define ZYNQ_I2C_BASE ZYNQ_I2C_BASEADDR0 -#else -# define ZYNQ_I2C_BASE ZYNQ_I2C_BASEADDR1 -#endif - -static struct zynq_i2c_registers *zynq_i2c = - (struct zynq_i2c_registers *)ZYNQ_I2C_BASE; +static struct zynq_i2c_registers *i2c_select(struct i2c_adapter *adap) +{ + return adap->hwadapnr ? + /* Zynq PS I2C1 */ + (struct zynq_i2c_registers *)ZYNQ_I2C_BASEADDR1 : + /* Zynq PS I2C0 */ + (struct zynq_i2c_registers *)ZYNQ_I2C_BASEADDR0; +} /* I2C init called by cmd_i2c when doing 'i2c reset'. */ static void zynq_i2c_init(struct i2c_adapter *adap, int requested_speed, int slaveadd) { + struct zynq_i2c_registers *zynq_i2c = i2c_select(adap); + /* 111MHz / ( (3 * 17) * 22 ) = ~100KHz */ writel((16 << ZYNQ_I2C_CONTROL_DIV_B_SHIFT) | (2 << ZYNQ_I2C_CONTROL_DIV_A_SHIFT), &zynq_i2c->control); @@ -87,7 +89,7 @@ static void zynq_i2c_init(struct i2c_adapter *adap, int requested_speed, } #ifdef DEBUG -static void zynq_i2c_debug_status(void) +static void zynq_i2c_debug_status(struct zynq_i2c_registers *zynq_i2c) { int int_status; int status; @@ -129,7 +131,7 @@ static void zynq_i2c_debug_status(void) #endif /* Wait for an interrupt */ -static u32 zynq_i2c_wait(u32 mask) +static u32 zynq_i2c_wait(struct zynq_i2c_registers *zynq_i2c, u32 mask) { int timeout, int_status; @@ -140,7 +142,7 @@ static u32 zynq_i2c_wait(u32 mask) break; } #ifdef DEBUG - zynq_i2c_debug_status(); + zynq_i2c_debug_status(zynq_i2c)); #endif /* Clear interrupt status flags */ writel(int_status & mask, &zynq_i2c->interrupt_status); @@ -154,6 +156,8 @@ static u32 zynq_i2c_wait(u32 mask) */ static int zynq_i2c_probe(struct i2c_adapter *adap, u8 dev) { + struct zynq_i2c_registers *zynq_i2c = i2c_select(adap); + /* Attempt to read a byte */ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO | ZYNQ_I2C_CONTROL_RW); @@ -162,7 +166,7 @@ static int zynq_i2c_probe(struct i2c_adapter *adap, u8 dev) writel(dev, &zynq_i2c->address); writel(1, &zynq_i2c->transfer_size); - return (zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP | + return (zynq_i2c_wait(zynq_i2c, ZYNQ_I2C_INTERRUPT_COMP | ZYNQ_I2C_INTERRUPT_NACK) & ZYNQ_I2C_INTERRUPT_COMP) ? 0 : -ETIMEDOUT; } @@ -177,6 +181,7 @@ static int zynq_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, u32 status; u32 i = 0; u8 *cur_data = data; + struct zynq_i2c_registers *zynq_i2c = i2c_select(adap); /* Check the hardware can handle the requested bytes */ if ((length < 0) || (length > ZYNQ_I2C_TRANSFERT_SIZE_MAX)) @@ -198,7 +203,7 @@ static int zynq_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, writel(addr >> (8 * alen), &zynq_i2c->data); /* Wait for the address to be sent */ - if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) { + if (!zynq_i2c_wait(zynq_i2c, ZYNQ_I2C_INTERRUPT_COMP)) { /* Release the bus */ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); return -ETIMEDOUT; @@ -214,7 +219,7 @@ static int zynq_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, /* Wait for data */ do { - status = zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP | + status = zynq_i2c_wait(zynq_i2c, ZYNQ_I2C_INTERRUPT_COMP | ZYNQ_I2C_INTERRUPT_DATA); if (!status) { /* Release the bus */ @@ -243,6 +248,7 @@ static int zynq_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr, int alen, u8 *data, int length) { u8 *cur_data = data; + struct zynq_i2c_registers *zynq_i2c = i2c_select(adap); /* Write the register address */ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO | @@ -254,7 +260,7 @@ static int zynq_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr, while (alen--) writel(addr >> (8 * alen), &zynq_i2c->data); /* Start the tranfer */ - if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) { + if (!zynq_i2c_wait(zynq_i2c, ZYNQ_I2C_INTERRUPT_COMP)) { /* Release the bus */ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); return -ETIMEDOUT; @@ -265,7 +271,7 @@ static int zynq_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr, while (length--) { writel(*(cur_data++), &zynq_i2c->data); if (readl(&zynq_i2c->transfer_size) == ZYNQ_I2C_FIFO_DEPTH) { - if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) { + if (!zynq_i2c_wait(zynq_i2c, ZYNQ_I2C_INTERRUPT_COMP)) { /* Release the bus */ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); @@ -277,7 +283,7 @@ static int zynq_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr, /* All done... release the bus */ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); /* Wait for the address and data to be sent */ - if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) + if (!zynq_i2c_wait(zynq_i2c, ZYNQ_I2C_INTERRUPT_COMP)) return -ETIMEDOUT; return 0; } @@ -295,3 +301,7 @@ U_BOOT_I2C_ADAP_COMPLETE(zynq_0, zynq_i2c_init, zynq_i2c_probe, zynq_i2c_read, zynq_i2c_write, zynq_i2c_set_bus_speed, CONFIG_SYS_I2C_ZYNQ_SPEED, CONFIG_SYS_I2C_ZYNQ_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE(zynq_1, zynq_i2c_init, zynq_i2c_probe, zynq_i2c_read, + zynq_i2c_write, zynq_i2c_set_bus_speed, + CONFIG_SYS_I2C_ZYNQ_SPEED, CONFIG_SYS_I2C_ZYNQ_SLAVE, + 1) diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index e7a8e9f..04ea81f 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -104,13 +104,13 @@ # define CONFIG_DOS_PARTITION #endif +#define CONFIG_SYS_I2C_ZYNQ /* I2C */ -#if defined(CONFIG_ZYNQ_I2C0) || defined(CONFIG_ZYNQ_I2C1) +#if defined(CONFIG_SYS_I2C_ZYNQ) # define CONFIG_CMD_I2C # define CONFIG_SYS_I2C -# define CONFIG_SYS_I2C_ZYNQ # define CONFIG_SYS_I2C_ZYNQ_SPEED 100000 -# define CONFIG_SYS_I2C_ZYNQ_SLAVE 1 +# define CONFIG_SYS_I2C_ZYNQ_SLAVE 0 #endif /* EEPROM */