From patchwork Fri Jun 22 04:12:11 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Troy Kisky X-Patchwork-Id: 166492 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 8FFDDB6FA4 for ; Fri, 22 Jun 2012 14:33:19 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3EE85280E3; Fri, 22 Jun 2012 06:33:13 +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 vf+uzo9Tw0yJ; Fri, 22 Jun 2012 06:33:12 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 651ED280C0; Fri, 22 Jun 2012 06:33:03 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 85ACC280A7 for ; Fri, 22 Jun 2012 06:33: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 aDpiw329lGAQ for ; Fri, 22 Jun 2012 06:33:00 +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 8ADB4280A5 for ; Fri, 22 Jun 2012 06:32:52 +0200 (CEST) Received: by pbcwy7 with SMTP id wy7so2936966pbc.3 for ; Thu, 21 Jun 2012 21:32:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=oCgd4Oo+ai91E0Asiga/+LbHunncAG7/cICGmJnWdbo=; b=W/7rt9bTKFnECXkK9jfSaQLUtFNIhnq7r+fCVD43BJpvAzoBWHJIp7qC7a5XDtPXBs i+ZSMxL7m/x+j+6e8qcOp+XJwy5ACD8YcMKbORw7SoYzhjeEtRKWEvY9k6g+v6xd917T 3W4NovyC6nKanWzi83XGk7eJuAWUKsC+jOAdhCNkG5dmXWc17lf6IR1U5Yj5ZGOV8rIf GB/a5Yr+oHshajGDduz7zVEkxCajv/TqVKHGilTge7UDXjZ0xzTXtaMmdpqDmzfanSHR VlQlYz6sOljAOIDg88v+hd2pun5eo12nFmcDBOGT2A+xcVYMrOhfLC5QdMSHzyqdSSqd fmWg== Received: by 10.68.226.168 with SMTP id rt8mr6203752pbc.23.1340339570334; Thu, 21 Jun 2012 21:32:50 -0700 (PDT) Received: from officeserver-2 ([70.96.116.236]) by mx.google.com with ESMTPS id tq4sm15513945pbc.11.2012.06.21.21.32.48 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 21 Jun 2012 21:32:49 -0700 (PDT) Received: from tkisky by officeserver-2 with local (Exim 4.76) (envelope-from ) id 1ShvEM-00032y-Hg; Thu, 21 Jun 2012 21:12:22 -0700 From: Troy Kisky To: hs@denx.de, sbabic@denx.de Date: Thu, 21 Jun 2012 21:12:11 -0700 Message-Id: <1340338339-11626-16-git-send-email-troy.kisky@boundarydevices.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1340338339-11626-1-git-send-email-troy.kisky@boundarydevices.com> References: <1340338339-11626-1-git-send-email-troy.kisky@boundarydevices.com> X-Gm-Message-State: ALoCoQnVzF03+fS/lGwItrhtrKj7uh3SrFmJRKdxUDeT4li75uA1go4d+TNdcgex2suHPZAzA8DK Cc: u-boot@lists.denx.de, r49496@freescale.com, jason.hui@linaro.org Subject: [U-Boot] [PATCH 16/24] mxc_i2c: prep work for multiple busses support 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 Signed-off-by: Troy Kisky --- drivers/i2c/mxc_i2c.c | 121 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 100 insertions(+), 21 deletions(-) diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index cb061f7..ec05798 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -58,9 +58,7 @@ struct mxc_i2c_regs { #define I2SR_IIF (1 << 1) #define I2SR_RX_NO_AK (1 << 0) -#ifdef CONFIG_SYS_I2C_BASE -#define I2C_BASE CONFIG_SYS_I2C_BASE -#else +#if defined(CONFIG_HARD_I2C) && !defined(CONFIG_SYS_I2C_BASE) #error "define CONFIG_SYS_I2C_BASE to use the mxc_i2c driver" #endif @@ -114,11 +112,11 @@ static uint8_t i2c_imx_get_clk(unsigned int rate) } /* - * Init I2C Bus + * Set I2C Bus speed */ -void i2c_init(int speed, int unused) +int bus_i2c_set_bus_speed(void *base, int speed) { - struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base; u8 clk_idx = i2c_imx_get_clk(speed); u8 idx = i2c_clk_div[clk_idx][1]; @@ -128,23 +126,15 @@ void i2c_init(int speed, int unused) /* Reset module */ writeb(0, &i2c_regs->i2cr); writeb(0, &i2c_regs->i2sr); -} - -/* - * Set I2C Speed - */ -int i2c_set_bus_speed(unsigned int speed) -{ - i2c_init(speed, 0); return 0; } /* * Get I2C Speed */ -unsigned int i2c_get_bus_speed(void) +unsigned int bus_i2c_get_bus_speed(void *base) { - struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base; u8 clk_idx = readb(&i2c_regs->ifdr); u8 clk_div; @@ -282,12 +272,13 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, /* * Read data from I2C device */ -int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) +int bus_i2c_read(void *base, uchar chip, uint addr, int alen, uchar *buf, + int len) { - struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; int ret; unsigned int temp; int i; + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base; ret = i2c_init_transfer(i2c_regs, chip, addr, alen); if (ret) @@ -338,11 +329,12 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) /* * Write data to I2C device */ -int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) +int bus_i2c_write(void *base, uchar chip, uint addr, int alen, uchar *buf, + int len) { - struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; int ret; int i; + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base; ret = i2c_init_transfer(i2c_regs, chip, addr, alen); if (ret) @@ -359,10 +351,97 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) return ret; } +typedef void (*toggle_i2c_fn)(void *p); + +#ifdef CONFIG_I2C_MULTI_BUS +static unsigned g_bus; +#else +#define g_bus 0 +#endif + +struct i2c_parms { + void *base; + void *toggle_data; + toggle_i2c_fn toggle_fn; +}; + +struct i2c_parms g_parms[3]; + +void *get_base(void) +{ +#ifndef CONFIG_SYS_I2C_BASE + return g_parms[g_bus].base; +#elif defined(CONFIG_I2C_MULTI_BUS) + void *ret = g_parms[g_bus].base; + if (!ret) + ret = (void *)CONFIG_SYS_I2C_BASE; + return ret; +#else + return (void *)CONFIG_SYS_I2C_BASE; +#endif +} + +int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) +{ + return bus_i2c_read(get_base(), chip, addr, alen, buf, len); +} + +int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) +{ + return bus_i2c_write(get_base(), chip, addr, alen, buf, len); +} /* * Try if a chip add given address responds (probe the chip) */ int i2c_probe(uchar chip) { - return i2c_write(chip, 0, 0, NULL, 0); + return bus_i2c_write(get_base(), chip, 0, 0, NULL, 0); +} + +void bus_i2c_init(void *base, int speed, int unused, + toggle_i2c_fn toggle_fn, void *toggle_data) +{ + int i = 0; + struct i2c_parms *p = g_parms; + if (!base) + return; + for (;;) { + if (!p->base || (p->base == base)) { + p->base = base; + if (toggle_data) { + p->toggle_data = toggle_data; + p->toggle_fn = toggle_fn; + } + break; + } + p++; + i++; + if (i >= ARRAY_SIZE(g_parms)) + return; + } + bus_i2c_set_bus_speed(base, speed); +} + +/* + * Init I2C Bus + */ +void i2c_init(int speed, int unused) +{ + bus_i2c_init(get_base(), speed, unused, NULL, NULL); +} + +/* + * Set I2C Speed + */ +int i2c_set_bus_speed(unsigned int speed) +{ + return bus_i2c_set_bus_speed(get_base(), speed); +} + +/* + * Get I2C Speed + */ +unsigned int i2c_get_bus_speed(void) +{ + return bus_i2c_get_bus_speed(get_base()); }