From patchwork Fri Jun 22 04:12:18 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Troy Kisky X-Patchwork-Id: 166498 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 083AEB6EE7 for ; Fri, 22 Jun 2012 14:34:24 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2E61D280EB; Fri, 22 Jun 2012 06:33:56 +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 sIRjfmAU6xre; Fri, 22 Jun 2012 06:33:55 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 97F7528113; Fri, 22 Jun 2012 06:33:39 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5550628106 for ; Fri, 22 Jun 2012 06:33:35 +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 RPZMJ5GMVECx for ; Fri, 22 Jun 2012 06:33:33 +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 5C9C4280E8 for ; Fri, 22 Jun 2012 06:33:17 +0200 (CEST) Received: by mail-pb0-f44.google.com with SMTP id wy7so2936966pbc.3 for ; Thu, 21 Jun 2012 21:33:16 -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=VlwOccoyqM205l19RQVR6YVsbgRf/xmyWueOBwDGONY=; b=cJdbZILWUsu+dVTcEx/lkBOYoiDqs+SwInzfovfx7FDgac+vxjqwip1P9sqhghcxCM iixLGL8dVmmhBImF4a/ncKSRyMz9EnedPpiDUW8bxBHwqQjG0rgKCzqCK1e2VdvqzROA hOQotT+aTRbJWVdbw3YRJUI9KbNHWuQJZrhgFkbb8T+Pv/4mxtBcIDDAZqvR/cLyJ14a 8wgpZrJ1raTB4g+8AnxJ4ISQQvv4WcCD9WDUQEA2+b2wijMJSFAgRYED+lpjpc2jTHZJ hujmaKX+A1pTLcE8eaFd7TIPypYBrw3aYnSOf581sXD4b7aj57qlkzIQipAZrokTBQwA L7Bw== Received: by 10.68.224.233 with SMTP id rf9mr5432422pbc.141.1340339596877; Thu, 21 Jun 2012 21:33:16 -0700 (PDT) Received: from officeserver-2 ([70.96.116.236]) by mx.google.com with ESMTPS id vc6sm37748481pbc.6.2012.06.21.21.33.15 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 21 Jun 2012 21:33:16 -0700 (PDT) Received: from tkisky by officeserver-2 with local (Exim 4.76) (envelope-from ) id 1ShvEN-00033L-7M; Thu, 21 Jun 2012 21:12:23 -0700 From: Troy Kisky To: hs@denx.de, sbabic@denx.de Date: Thu, 21 Jun 2012 21:12:18 -0700 Message-Id: <1340338339-11626-23-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: ALoCoQm8yah+PYAMTOm+r1G8wgVvxbvfZOwgetAsNmz2QhzSpJ6XyJIBRZQor1gc0PjBMt7kE6yb Cc: u-boot@lists.denx.de, r49496@freescale.com, jason.hui@linaro.org Subject: [U-Boot] [PATCH 23/24] imx-common: add i2c.c for bus recovery 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 --- arch/arm/cpu/armv7/imx-common/Makefile | 4 +- arch/arm/cpu/armv7/imx-common/i2c.c | 79 +++++++++++++++++++++++++++++ arch/arm/cpu/armv7/mx5/clock.c | 19 +++++++ arch/arm/cpu/armv7/mx6/clock.c | 19 +++++++ arch/arm/include/asm/arch-mx5/clock.h | 1 + arch/arm/include/asm/arch-mx6/clock.h | 1 + arch/arm/include/asm/imx-common/mxc_i2c.h | 46 +++++++++++++++++ 7 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/imx-common/i2c.c create mode 100644 arch/arm/include/asm/imx-common/mxc_i2c.h diff --git a/arch/arm/cpu/armv7/imx-common/Makefile b/arch/arm/cpu/armv7/imx-common/Makefile index 53296fa..bf36be5 100644 --- a/arch/arm/cpu/armv7/imx-common/Makefile +++ b/arch/arm/cpu/armv7/imx-common/Makefile @@ -27,7 +27,9 @@ include $(TOPDIR)/config.mk LIB = $(obj)libimx-common.o -COBJS = iomux-v3.o timer.o cpu.o speed.o +COBJS-y = iomux-v3.o timer.o cpu.o speed.o +COBJS-$(CONFIG_I2C_MXC) += i2c.o +COBJS := $(sort $(COBJS-y)) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/arm/cpu/armv7/imx-common/i2c.c b/arch/arm/cpu/armv7/imx-common/i2c.c new file mode 100644 index 0000000..a57d393 --- /dev/null +++ b/arch/arm/cpu/armv7/imx-common/i2c.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2012 Boundary Devices Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include + +static void toggle_scl(void *priv) +{ + struct i2c_pads_info *p = (struct i2c_pads_info *)priv; + int i; + gpio_direction_input(p->sda.gp); + gpio_direction_input(p->scl.gp); + + imx_iomux_v3_setup_pad(p->sda.gpio_mode); + imx_iomux_v3_setup_pad(p->scl.gpio_mode); + + printf("%s sda=%i scl=%i sda.gp=0x%x scl.gp=0x%x\n", __func__, + gpio_get_value(p->sda.gp), gpio_get_value(p->scl.gp), + p->sda.gp, p->scl.gp); + /* Send high and low on the SCL line */ + for (i = 0; i < 9; i++) { + gpio_direction_output(p->scl.gp, 0); + udelay(50); + gpio_direction_input(p->scl.gp); + udelay(50); + printf("%s sda=%i scl=%i\n", __func__, + gpio_get_value(p->sda.gp), gpio_get_value(p->scl.gp)); + udelay(50); + } + imx_iomux_v3_setup_pad(p->sda.i2c_mode); + imx_iomux_v3_setup_pad(p->scl.i2c_mode); +} + +static const unsigned i2c_bases[] = { + I2C1_BASE_ADDR, + I2C2_BASE_ADDR, +#ifdef I2C3_BASE_ADDR + I2C3_BASE_ADDR, +#endif +}; + +/* i2c_index can be from 0 - 2 */ +void setup_i2c(unsigned i2c_index, int speed, int slave_addr, + struct i2c_pads_info *p) +{ + unsigned reg; + + if (i2c_index >= ARRAY_SIZE(i2c_bases)) + return; + imx_iomux_v3_setup_pad(p->sda.i2c_mode); + imx_iomux_v3_setup_pad(p->scl.i2c_mode); + /* Enable i2c clock */ + enable_i2c_clock(1, i2c_index); + bus_i2c_init(i2c_bases[i2c_index], speed, slave_addr, toggle_scl, p); +} diff --git a/arch/arm/cpu/armv7/mx5/clock.c b/arch/arm/cpu/armv7/mx5/clock.c index e92f106..b5d2794 100644 --- a/arch/arm/cpu/armv7/mx5/clock.c +++ b/arch/arm/cpu/armv7/mx5/clock.c @@ -80,6 +80,25 @@ void enable_usboh3_clk(unsigned char enable) writel(reg, &mxc_ccm->CCGR2); } +#ifdef CONFIG_I2C_MXC +/* i2c_num can be from 0 - 2 */ +int enable_i2c_clock(unsigned char enable, unsigned i2c_num) +{ + u32 reg; + u32 mask; + + if (i2c_num > 2) + return; + mask = MXC_CCM_CCGR_CG_MASK << ((i2c_num + 9) << 1); + reg = __raw_readl(&mxc_ccm->CCGR1); + if (enable) + reg |= mask; + else + reg &= ~mask; + __raw_writel(reg, &mxc_ccm->CCGR1); +} +#endif + void set_usb_phy1_clk(void) { unsigned int reg; diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c index ef98563..d31777b 100644 --- a/arch/arm/cpu/armv7/mx6/clock.c +++ b/arch/arm/cpu/armv7/mx6/clock.c @@ -49,6 +49,25 @@ void enable_usboh3_clk(unsigned char enable) } +#ifdef CONFIG_I2C_MXC +/* i2c_num can be from 0 - 2 */ +int enable_i2c_clock(unsigned char enable, unsigned i2c_num) +{ + u32 reg; + u32 mask; + + if (i2c_num > 2) + return; + mask = MXC_CCM_CCGR_CG_MASK << ((i2c_num + 3) << 1); + reg = __raw_readl(&imx_ccm->CCGR2); + if (enable) + reg |= mask; + else + reg &= ~mask; + __raw_writel(reg, &imx_ccm->CCGR2); +} +#endif + static u32 decode_pll(enum pll_clocks pll, u32 infreq) { u32 div; diff --git a/arch/arm/include/asm/arch-mx5/clock.h b/arch/arm/include/asm/arch-mx5/clock.h index ea972a3..da604bf 100644 --- a/arch/arm/include/asm/arch-mx5/clock.h +++ b/arch/arm/include/asm/arch-mx5/clock.h @@ -44,5 +44,6 @@ void set_usb_phy2_clk(void); void enable_usb_phy2_clk(unsigned char enable); void set_usboh3_clk(void); void enable_usboh3_clk(unsigned char enable); +int enable_i2c_clk(unsigned char enable, unsigned i2c_num); #endif /* __ASM_ARCH_CLOCK_H */ diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h index 613809b..04daf36 100644 --- a/arch/arm/include/asm/arch-mx6/clock.h +++ b/arch/arm/include/asm/arch-mx6/clock.h @@ -47,5 +47,6 @@ u32 imx_get_uartclk(void); u32 imx_get_fecclk(void); unsigned int mxc_get_clock(enum mxc_clock clk); void enable_usboh3_clk(unsigned char enable); +int enable_i2c_clk(unsigned char enable, unsigned i2c_num); #endif /* __ASM_ARCH_CLOCK_H */ diff --git a/arch/arm/include/asm/imx-common/mxc_i2c.h b/arch/arm/include/asm/imx-common/mxc_i2c.h new file mode 100644 index 0000000..2a8f729 --- /dev/null +++ b/arch/arm/include/asm/imx-common/mxc_i2c.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef __ASM_ARCH_MXC_MXC_I2C_H__ +#define __ASM_ARCH_MXC_MXC_I2C_H__ +#include + +typedef void (*toggle_i2c_fn)(void *p); +struct mxc_i2c_regs; + + +struct i2c_pin_ctrl { + iomux_v3_cfg_t i2c_mode; + iomux_v3_cfg_t gpio_mode; + unsigned char gp; + unsigned char spare; +}; + +struct i2c_pads_info { + struct i2c_pin_ctrl scl; + struct i2c_pin_ctrl sda; +}; + +void setup_i2c(unsigned i2c_index, int speed, int slave_addr, + struct i2c_pads_info *p); +void bus_i2c_init(void *base, int speed, int slave_addr, toggle_i2c_fn tog, + void *p); +int bus_i2c_read(void *base, 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); +#endif