* [PATCH 0/3] Freescale I2C driver
@ 2012-08-22 15:08 Renaud Barbier
2012-08-22 15:08 ` [PATCH 1/3] mpc85xx: i2c frequency Renaud Barbier
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Renaud Barbier @ 2012-08-22 15:08 UTC (permalink / raw)
To: barebox
This patch set introduces the Freescale I2C driver. It is tested on the
P2020RDB board using i2c devices(8-bit and 16-bit) found on both SOC buses.
A function is also added to the mpc85xx architecture to return the system
frequency used to calculate the i2c frequency bus divider.
Renaud Barbier (3):
mpc85xx: i2c frequency
Freescale I2C driver
ppc: p2020rdb i2c support
arch/ppc/boards/freescale-p2020rdb/p2020rdb.c | 20 ++-
arch/ppc/configs/p2020rdb_defconfig | 3 +
arch/ppc/include/asm/fsl_i2c.h | 80 +++----
arch/ppc/mach-mpc85xx/include/mach/clocks.h | 1 +
arch/ppc/mach-mpc85xx/speed.c | 9 +
drivers/i2c/busses/Kconfig | 4 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-fsl.c | 356 +++++++++++++++++++++++++
8 files changed, 425 insertions(+), 49 deletions(-)
create mode 100644 drivers/i2c/busses/i2c-fsl.c
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] mpc85xx: i2c frequency
2012-08-22 15:08 [PATCH 0/3] Freescale I2C driver Renaud Barbier
@ 2012-08-22 15:08 ` Renaud Barbier
2012-08-22 15:08 ` [PATCH 2/3] Freescale I2C driver Renaud Barbier
2012-08-22 15:08 ` [PATCH 3/3] ppc: p2020rdb i2c support Renaud Barbier
2 siblings, 0 replies; 7+ messages in thread
From: Renaud Barbier @ 2012-08-22 15:08 UTC (permalink / raw)
To: barebox
To prepare for the introduction of the Freescale I2C driver, a function
that returns the system bus frequency used to compute the i2c bus frequency
is added.
Signed-off-by: Renaud Barbier <renaud.barbier@ge.com>
---
arch/ppc/mach-mpc85xx/include/mach/clocks.h | 1 +
arch/ppc/mach-mpc85xx/speed.c | 9 +++++++++
2 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/arch/ppc/mach-mpc85xx/include/mach/clocks.h b/arch/ppc/mach-mpc85xx/include/mach/clocks.h
index 2ab367b..e20d685 100644
--- a/arch/ppc/mach-mpc85xx/include/mach/clocks.h
+++ b/arch/ppc/mach-mpc85xx/include/mach/clocks.h
@@ -12,5 +12,6 @@ struct sys_info {
unsigned long fsl_get_bus_freq(ulong dummy);
unsigned long fsl_get_timebase_clock(void);
+unsigned long fsl_get_i2c_freq(void);
void fsl_get_sys_info(struct sys_info *sysInfo);
#endif /* __ASM_ARCH_CLOCKS_H */
diff --git a/arch/ppc/mach-mpc85xx/speed.c b/arch/ppc/mach-mpc85xx/speed.c
index 40d3664..fff2d22 100644
--- a/arch/ppc/mach-mpc85xx/speed.c
+++ b/arch/ppc/mach-mpc85xx/speed.c
@@ -102,3 +102,12 @@ unsigned long fsl_get_timebase_clock(void)
return (sysinfo.freqSystemBus + 4UL)/8UL;
}
+
+unsigned long fsl_get_i2c_freq(void)
+{
+ struct sys_info sysinfo;
+
+ fsl_get_sys_info(&sysinfo);
+
+ return sysinfo.freqSystemBus / 2;
+}
--
1.7.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] Freescale I2C driver
2012-08-22 15:08 [PATCH 0/3] Freescale I2C driver Renaud Barbier
2012-08-22 15:08 ` [PATCH 1/3] mpc85xx: i2c frequency Renaud Barbier
@ 2012-08-22 15:08 ` Renaud Barbier
2012-08-28 9:19 ` Sascha Hauer
2012-08-22 15:08 ` [PATCH 3/3] ppc: p2020rdb i2c support Renaud Barbier
2 siblings, 1 reply; 7+ messages in thread
From: Renaud Barbier @ 2012-08-22 15:08 UTC (permalink / raw)
To: barebox
This patch introduces the Freescale I2C driver along with its configuration
and build files.
The header file asm/fsl_i2c.h is updated with register offsets and the
structure mapping the i2c registers is removed.
Signed-off-by: Renaud Barbier <renaud.barbier@ge.com>
---
arch/ppc/include/asm/fsl_i2c.h | 80 ++++------
drivers/i2c/busses/Kconfig | 4 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-fsl.c | 356 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 393 insertions(+), 48 deletions(-)
create mode 100644 drivers/i2c/busses/i2c-fsl.c
diff --git a/arch/ppc/include/asm/fsl_i2c.h b/arch/ppc/include/asm/fsl_i2c.h
index 4f71341..62b077d 100644
--- a/arch/ppc/include/asm/fsl_i2c.h
+++ b/arch/ppc/include/asm/fsl_i2c.h
@@ -1,6 +1,7 @@
/*
* Freescale I2C Controller
*
+ * Copyright 2012 GE Intelligent Platform, Inc.
* Copyright 2006 Freescale Semiconductor, Inc.
*
* Based on earlier versions by Gleb Natapov <gnatapov@mrv.com>,
@@ -32,55 +33,38 @@
#include <asm/types.h>
-typedef struct fsl_i2c {
+#define I2C1_BASE_ADDR (CFG_IMMR + 0x3000)
+#define I2C2_BASE_ADDR (CFG_IMMR + 0x3100)
- u8 adr; /* I2C slave address */
- u8 res0[3];
-#define I2C_ADR 0xFE
-#define I2C_ADR_SHIFT 1
-#define I2C_ADR_RES ~(I2C_ADR)
+#define FSL_I2C_ADR 0x00
+#define FSL_I2C_FDR 0x04
+#define FSL_I2C_CR 0x08
+#define I2C_CR_MEN 0x80
+#define I2C_CR_MIEN 0x40
+#define I2C_CR_MSTA 0x20
+#define I2C_CR_MTX 0x10
+#define I2C_CR_TXAK 0x08
+#define I2C_CR_RSTA 0x04
+#define I2C_CR_BCST 0x01
+#define FSL_I2C_SR 0x0C
+#define I2C_SR_MCF 0x80
+#define I2C_SR_MAAS 0x40
+#define I2C_SR_MBB 0x20
+#define I2C_SR_MAL 0x10
+#define I2C_SR_BCSTM 0x08
+#define I2C_SR_SRW 0x04
+#define I2C_SR_MIF 0x02
+#define I2C_SR_RXAK 0x01
+#define FSL_I2C_DR 0x10
+#define FSL_I2C_DFSRR 0x14
- u8 fdr; /* I2C frequency divider register */
- u8 res1[3];
-#define IC2_FDR 0x3F
-#define IC2_FDR_SHIFT 0
-#define IC2_FDR_RES ~(IC2_FDR)
-
- u8 cr; /* I2C control redister */
- u8 res2[3];
-#define I2C_CR_MEN 0x80
-#define I2C_CR_MIEN 0x40
-#define I2C_CR_MSTA 0x20
-#define I2C_CR_MTX 0x10
-#define I2C_CR_TXAK 0x08
-#define I2C_CR_RSTA 0x04
-#define I2C_CR_BCST 0x01
-
- u8 sr; /* I2C status register */
- u8 res3[3];
-#define I2C_SR_MCF 0x80
-#define I2C_SR_MAAS 0x40
-#define I2C_SR_MBB 0x20
-#define I2C_SR_MAL 0x10
-#define I2C_SR_BCSTM 0x08
-#define I2C_SR_SRW 0x04
-#define I2C_SR_MIF 0x02
-#define I2C_SR_RXAK 0x01
-
- u8 dr; /* I2C data register */
- u8 res4[3];
-#define I2C_DR 0xFF
-#define I2C_DR_SHIFT 0
-#define I2C_DR_RES ~(I2C_DR)
-
- u8 dfsrr; /* I2C digital filter sampling rate register */
- u8 res5[3];
-#define I2C_DFSRR 0x3F
-#define I2C_DFSRR_SHIFT 0
-#define I2C_DFSRR_RES ~(I2C_DR)
-
- /* Fill out the reserved block */
- u8 res6[0xE8];
-} fsl_i2c_t;
+/*
+ * Platform data
+ */
+struct fsl_i2c_plat {
+ int bus_num;
+ int slaveaddr;
+ int speed;
+};
#endif /* _ASM_I2C_H_ */
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 1ce5c00..d8d677a 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -12,4 +12,8 @@ config I2C_OMAP
bool "OMAP I2C Master driver"
depends on ARCH_OMAP
+config I2C_FSL
+ bool "FSL I2C Master driver"
+ depends on ARCH_MPC85XX
+
endmenu
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index e4c5125..dd4b88d 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_I2C_IMX) += i2c-imx.o
obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
+obj-$(CONFIG_I2C_FSL) += i2c-fsl.o
diff --git a/drivers/i2c/busses/i2c-fsl.c b/drivers/i2c/busses/i2c-fsl.c
new file mode 100644
index 0000000..17ac7da
--- /dev/null
+++ b/drivers/i2c/busses/i2c-fsl.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2012 GE Intelligent Platforms, Inc.
+ * Copyright 2006,2009 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ * This I2C driver is derived from U-boot. It different from the original
+ * code as it does byte-write so that page boundary can be crossed.
+ * A version closer to the Linux driver should be developed.
+ */
+
+#include <common.h>
+#include <clock.h>
+#include <config.h>
+#include <driver.h>
+#include <init.h>
+#include <malloc.h>
+#include <command.h>
+#include <i2c/i2c.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <asm/fsl_i2c.h>
+#include <mach/clocks.h>
+
+#define I2C_READ_BIT 1
+#define I2C_WRITE_BIT 0
+
+struct fsl_i2c_dev {
+ int bus_num;
+ int slaveaddr;
+ int speed;
+ void __iomem *regs;
+ struct i2c_adapter adapter;
+};
+#define to_fsl_i2c_struct(a) container_of(a, struct fsl_i2c_dev, adapter)
+
+/*
+ * Set the I2C bus speed for a given I2C device
+ *
+ * param dev: the I2C device
+ * i2c_clk: I2C bus clock frequency
+ * speed: the desired speed of the bus
+ *
+ * The I2C device must be stopped before calling this function.
+ *
+ * The return value is the actual bus speed that is set.
+ */
+static unsigned int fsl_set_i2c_bus_speed(const void __iomem *dev,
+ unsigned int i2c_clk, unsigned int speed)
+{
+ unsigned short divider = min((unsigned short)(i2c_clk / speed),
+ (unsigned short) -1);
+
+ /*
+ * We want to choose an FDR/DFSR that generates an I2C bus speed that
+ * is equal to or lower than the requested speed. That means that we
+ * want the first divider that is equal to or greater than the
+ * calculated divider.
+ */
+ u8 dfsr, fdr = 0x31; /* Default if no FDR found */
+ /* a, b and dfsr matches identifiers A,B and C respectively in AN2919 */
+ unsigned short a, b, ga, gb;
+ unsigned long c_div, est_div;
+
+ /*
+ * Condition 1: dfsr <= 50ns/T (T=period of I2C source clock in ns).
+ * or (dfsr * T) <= 50ns.
+ * Translate to dfsr = 5 * Frequency / 100,000,000
+ */
+ dfsr = (5 * (i2c_clk / 1000)) / 100000;
+ debug("Requested speed:%d, i3c_clk:%d\n", speed, i2c_clk);
+ if (!dfsr)
+ dfsr = 1;
+
+ est_div = ~0;
+ for (ga = 0x4, a = 10; a <= 30; ga++, a += 2) {
+ for (gb = 0; gb < 8; gb++) {
+ b = 16 << gb;
+ c_div = b * (a + ((3*dfsr)/b)*2);
+ if ((c_div > divider) && (c_div < est_div)) {
+ unsigned short bin_gb, bin_ga;
+
+ est_div = c_div;
+ bin_gb = gb << 2;
+ bin_ga = (ga & 0x3) | ((ga & 0x4) << 3);
+ fdr = bin_gb | bin_ga;
+ speed = i2c_clk / est_div;
+ debug("FDR:0x%.2x, div:%ld, ga:0x%x, gb:0x%x, "
+ "a:%d, b:%d, speed:%d\n",
+ fdr, est_div, ga, gb, a, b, speed);
+ /* Condition 2 not accounted for */
+ debug("Tr <= %d ns\n",
+ (b - 3 * dfsr) * 1000000 /
+ (i2c_clk / 1000));
+ }
+ }
+ if (a == 20)
+ a += 2;
+ if (a == 24)
+ a += 4;
+ }
+ debug("divider:%d, est_div:%ld, DFSR:%d\n", divider, est_div, dfsr);
+ debug("FDR:0x%.2x, speed:%d\n", fdr, speed);
+ writeb(dfsr, dev + FSL_I2C_DFSRR); /* set default filter */
+ writeb(fdr, dev + FSL_I2C_FDR); /* set bus speed */
+
+ return speed;
+}
+
+static void fsl_i2c_init(struct fsl_i2c_dev *i2c_dev)
+{
+ void __iomem *dev = i2c_dev->regs;
+ unsigned int i2c_clk;
+
+ i2c_clk = fsl_get_i2c_freq();
+
+ writeb(0, dev + FSL_I2C_CR); /* stop I2C controller */
+ udelay(5);
+ fsl_set_i2c_bus_speed(dev, i2c_clk, i2c_dev->speed);
+ writeb(i2c_dev->slaveaddr << 1, dev + FSL_I2C_ADR);
+ writeb(0x0, dev + FSL_I2C_SR); /* clear status register */
+ writeb(I2C_CR_MEN, dev + FSL_I2C_CR); /* start I2C controller */
+}
+
+static int i2c_wait4bus(void __iomem *i2c)
+{
+ uint64_t start;
+
+ start = get_time_ns();
+ while (readb(i2c + FSL_I2C_SR) & I2C_SR_MBB) {
+ if (is_timeout(start, 100 * MSECOND)) {
+ debug("i2c_wait4bus timeout for I2C bus\n");
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+static inline int i2c_wait(void __iomem *i2c, int write)
+{
+ int csr;
+ uint64_t start;
+
+ start = get_time_ns();
+ while (1) {
+ if (is_timeout(start, 100 * MSECOND)) {
+ debug("timeout waiting for I2C bus\n");
+ return -EIO;
+ }
+
+ csr = readb(i2c + FSL_I2C_SR);
+ if (!(csr & I2C_SR_MIF))
+ continue;
+ /* Read again to allow register to stabilise */
+ csr = readb(i2c + FSL_I2C_SR);
+ writeb(0x0, i2c + FSL_I2C_SR);
+
+ if (csr & I2C_SR_MAL) {
+ debug("i2c_wait: MAL\n");
+ return -EIO;
+ }
+
+ if (!(csr & I2C_SR_MCF)) {
+ debug("i2c_wait: unfinished\n");
+ return -EIO;
+ }
+
+ if (write == I2C_WRITE_BIT && (csr & I2C_SR_RXAK)) {
+ debug("i2c_wait: No RXACK\n");
+ return -EIO;
+ }
+
+ return 0;
+ }
+
+ return -EIO;
+}
+
+static inline int i2c_write_addr(void __iomem *i2c, u8 dev, u8 dir, int rsta)
+{
+ writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
+ | (rsta ? I2C_CR_RSTA : 0), i2c + FSL_I2C_CR);
+
+ writeb((dev << 1) | dir, i2c + FSL_I2C_DR);
+
+ if (i2c_wait(i2c, I2C_WRITE_BIT) < 0) {
+ debug("i2c_write_addr failed i2c_wait\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+static inline int __i2c_write(void __iomem *i2c, u8 *data, int length)
+{
+ int i;
+
+ for (i = 0; i < length; i++) {
+ writeb(data[i], i2c + FSL_I2C_DR);
+
+ if (i2c_wait(i2c, I2C_WRITE_BIT) < 0)
+ break;
+ }
+
+ return i;
+}
+
+static inline int __i2c_read(void __iomem *i2c, u8 *data, int length)
+{
+ int i;
+
+ writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
+ i2c + FSL_I2C_CR);
+
+ /* dummy read */
+ readb(i2c + FSL_I2C_DR);
+
+ for (i = 0; i < length; i++) {
+ if (i2c_wait(i2c, I2C_READ_BIT) < 0)
+ break;
+
+ /* Generate ack on last next to last byte */
+ if (i == (length - 2))
+ writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
+ i2c + FSL_I2C_CR);
+
+ /* Do not generate stop on last byte */
+ if (i == (length - 1))
+ writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
+ i2c + FSL_I2C_CR);
+
+ data[i] = readb(i2c + FSL_I2C_DR);
+ }
+
+ return i;
+}
+
+static inline void fsl_i2c_stop(void __iomem *i2c)
+{
+ writeb(I2C_CR_MEN, i2c + FSL_I2C_CR);
+}
+
+static int fsl_i2c_read(void __iomem *i2c, u8 dev, u8 *data, int len, int rsta)
+{
+ int l = 0;
+
+ if (i2c_write_addr(i2c, dev, I2C_READ_BIT, rsta) != 0)
+ l = __i2c_read(i2c, data, len);
+
+ if (l == len)
+ return 0;
+
+ return -EIO;
+}
+
+static int fsl_i2c_write(void __iomem *i2c, u8 dev, u8 *data, int len, int rsta)
+{
+ if ((i2c_wait4bus(i2c) >= 0) &&
+ (i2c_write_addr(i2c, dev, I2C_WRITE_BIT, rsta) != 0) &&
+ (__i2c_write(i2c, data, len) == len)) {
+ return 0;
+ } else
+ return -EIO;
+}
+
+static int fsl_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ struct fsl_i2c_dev *i2cdev = to_fsl_i2c_struct(adap);
+ void __iomem *i2c = i2cdev->regs;
+ struct i2c_msg *pmsg;
+ int ix;
+ int ret = 0;
+
+ for (ix = 0; ret >= 0 && ix < num; ix++) {
+ pmsg = &msgs[ix];
+
+ debug("%s %d bytes to 0x%02x - %d of %d messages\n",
+ pmsg->flags & I2C_M_RD ? "Read" : "Write",
+ pmsg->len, pmsg->addr, ix + 1, num);
+
+ if (pmsg->len == 0)
+ return -EINVAL;
+
+ if (pmsg->flags & I2C_M_RD)
+ ret = fsl_i2c_read(i2c, pmsg->addr, pmsg->buf,
+ pmsg->len, ix);
+ else
+ ret = fsl_i2c_write(i2c, pmsg->addr, pmsg->buf,
+ pmsg->len, ix);
+ }
+
+ fsl_i2c_stop(i2c);
+
+ return (ret < 0) ? ret : num;
+}
+
+static int fsl_i2c_probe(struct device_d *pdev)
+{
+ struct fsl_i2c_dev *i2cdev;
+ struct fsl_i2c_plat *pdata = (struct fsl_i2c_plat *)pdev->platform_data;
+ int ret = 0;
+
+ i2cdev = kzalloc(sizeof(struct fsl_i2c_dev), GFP_KERNEL);
+ if (!i2cdev)
+ return -ENOMEM;
+
+ i2cdev->bus_num = pdata->bus_num;
+ i2cdev->regs = dev_request_mem_region(pdev, 0);
+ i2cdev->speed = pdata->speed;
+ i2cdev->slaveaddr = pdata->slaveaddr;
+
+ debug(pdev, "bus %d at %d Hz\n", i2cdev->bus_num, i2cdev->speed);
+
+ fsl_i2c_init(i2cdev);
+
+ i2cdev->adapter.master_xfer = fsl_i2c_xfer,
+ i2cdev->adapter.nr = i2cdev->bus_num;
+ i2cdev->adapter.dev = pdev;
+
+ /* Add I2C adapter */
+ ret = i2c_add_numbered_adapter(&i2cdev->adapter);
+ if (ret < 0) {
+ dev_err(pdev, "registration failed\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ kfree(i2cdev);
+ return ret;
+}
+
+static struct driver_d i2c_fsl_driver = {
+ .probe = fsl_i2c_probe,
+ .name = "fsl_i2c",
+};
+
+static int __init fsl_i2c_init_driver(void)
+{
+ return register_driver(&i2c_fsl_driver);
+}
+
+device_initcall(fsl_i2c_init_driver);
--
1.7.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] ppc: p2020rdb i2c support
2012-08-22 15:08 [PATCH 0/3] Freescale I2C driver Renaud Barbier
2012-08-22 15:08 ` [PATCH 1/3] mpc85xx: i2c frequency Renaud Barbier
2012-08-22 15:08 ` [PATCH 2/3] Freescale I2C driver Renaud Barbier
@ 2012-08-22 15:08 ` Renaud Barbier
2 siblings, 0 replies; 7+ messages in thread
From: Renaud Barbier @ 2012-08-22 15:08 UTC (permalink / raw)
To: barebox
Support for both i2c busses on the p2020rdb board is added and the
configuration file is updated to add the I2C driver and commands.
Signed-off-by: Renaud Barbier <renaud.barbier@ge.com>
---
arch/ppc/boards/freescale-p2020rdb/p2020rdb.c | 20 +++++++++++++++++++-
arch/ppc/configs/p2020rdb_defconfig | 3 +++
2 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/boards/freescale-p2020rdb/p2020rdb.c b/arch/ppc/boards/freescale-p2020rdb/p2020rdb.c
index 734fef9..f9bc946 100644
--- a/arch/ppc/boards/freescale-p2020rdb/p2020rdb.c
+++ b/arch/ppc/boards/freescale-p2020rdb/p2020rdb.c
@@ -29,6 +29,7 @@
#include <partition.h>
#include <memory.h>
#include <asm/cache.h>
+#include <asm/fsl_i2c.h>
#include <asm/fsl_ddr_sdram.h>
#include <asm/fsl_law.h>
#include <mach/mpc85xx.h>
@@ -62,6 +63,19 @@
#define SYSCLK_50 50000000
#define SYSCLK_100 100000000
+/* I2C busses. */
+static struct fsl_i2c_plat i2c1plat = {
+ .bus_num = 0,
+ .slaveaddr = 0x7f,
+ .speed = 400000,
+};
+
+static struct fsl_i2c_plat i2c2plat = {
+ .bus_num = 1,
+ .slaveaddr = 0x7f,
+ .speed = 400000,
+};
+
/* Ethernet. Use eTSEC3 */
static struct gfar_info_struct gfar_info[] = {
{
@@ -71,11 +85,15 @@ static struct gfar_info_struct gfar_info[] = {
},
};
-
static int devices_init(void)
{
add_cfi_flash_device(DEVICE_ID_DYNAMIC, CFG_FLASH_BASE, 16 << 20, 0);
+ add_generic_device("fsl_i2c", DEVICE_ID_DYNAMIC, NULL, I2C1_BASE_ADDR,
+ 0x100, IORESOURCE_MEM, &i2c1plat);
+ add_generic_device("fsl_i2c", DEVICE_ID_DYNAMIC, NULL, I2C2_BASE_ADDR,
+ 0x100, IORESOURCE_MEM, &i2c2plat);
+
/* eTSEC3 */
fsl_eth_init(3, &gfar_info[0]);
diff --git a/arch/ppc/configs/p2020rdb_defconfig b/arch/ppc/configs/p2020rdb_defconfig
index d025a40..4a1a61f 100644
--- a/arch/ppc/configs/p2020rdb_defconfig
+++ b/arch/ppc/configs/p2020rdb_defconfig
@@ -27,3 +27,6 @@ CONFIG_NET_PING=y
CONFIG_NET_TFTP=y
CONFIG_PING=y
CONFIG_TFTP=y
+CONFIG_I2C=y
+CONFIG_I2C_FSL=y
+CONFIG_CMD_I2C=y
--
1.7.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] Freescale I2C driver
2012-08-22 15:08 ` [PATCH 2/3] Freescale I2C driver Renaud Barbier
@ 2012-08-28 9:19 ` Sascha Hauer
2012-08-29 13:59 ` Renaud Barbier
0 siblings, 1 reply; 7+ messages in thread
From: Sascha Hauer @ 2012-08-28 9:19 UTC (permalink / raw)
To: Renaud Barbier; +Cc: barebox
On Wed, Aug 22, 2012 at 04:08:52PM +0100, Renaud Barbier wrote:
> This patch introduces the Freescale I2C driver along with its configuration
> and build files.
> The header file asm/fsl_i2c.h is updated with register offsets and the
> structure mapping the i2c registers is removed.
>
> Signed-off-by: Renaud Barbier <renaud.barbier@ge.com>
> ---
> arch/ppc/include/asm/fsl_i2c.h | 80 ++++------
> drivers/i2c/busses/Kconfig | 4 +
> drivers/i2c/busses/Makefile | 1 +
> drivers/i2c/busses/i2c-fsl.c | 356 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 393 insertions(+), 48 deletions(-)
> create mode 100644 drivers/i2c/busses/i2c-fsl.c
>
> diff --git a/arch/ppc/include/asm/fsl_i2c.h b/arch/ppc/include/asm/fsl_i2c.h
Please remove this file completely. The i2c registers should be defined in the
driver.
> index 4f71341..62b077d 100644
> --- a/arch/ppc/include/asm/fsl_i2c.h
> +++ b/arch/ppc/include/asm/fsl_i2c.h
> @@ -1,6 +1,7 @@
> /*
> * Freescale I2C Controller
> *
> + * Copyright 2012 GE Intelligent Platform, Inc.
> * Copyright 2006 Freescale Semiconductor, Inc.
> *
> * Based on earlier versions by Gleb Natapov <gnatapov@mrv.com>,
> @@ -32,55 +33,38 @@
>
> #include <asm/types.h>
>
> -typedef struct fsl_i2c {
> +#define I2C1_BASE_ADDR (CFG_IMMR + 0x3000)
> +#define I2C2_BASE_ADDR (CFG_IMMR + 0x3100)
>
> - u8 adr; /* I2C slave address */
> - u8 res0[3];
> -#define I2C_ADR 0xFE
> -#define I2C_ADR_SHIFT 1
> -#define I2C_ADR_RES ~(I2C_ADR)
> +#define FSL_I2C_ADR 0x00
> +#define FSL_I2C_FDR 0x04
> +#define FSL_I2C_CR 0x08
> +#define I2C_CR_MEN 0x80
> +#define I2C_CR_MIEN 0x40
> +#define I2C_CR_MSTA 0x20
> +#define I2C_CR_MTX 0x10
> +#define I2C_CR_TXAK 0x08
> +#define I2C_CR_RSTA 0x04
> +#define I2C_CR_BCST 0x01
> +#define FSL_I2C_SR 0x0C
> +#define I2C_SR_MCF 0x80
> +#define I2C_SR_MAAS 0x40
> +#define I2C_SR_MBB 0x20
> +#define I2C_SR_MAL 0x10
> +#define I2C_SR_BCSTM 0x08
> +#define I2C_SR_SRW 0x04
> +#define I2C_SR_MIF 0x02
> +#define I2C_SR_RXAK 0x01
> +#define FSL_I2C_DR 0x10
> +#define FSL_I2C_DFSRR 0x14
These defines look awfully familiar. Can we use
drivers/i2c/busses/i2c-imx.c instead of adding a new driver?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] Freescale I2C driver
2012-08-28 9:19 ` Sascha Hauer
@ 2012-08-29 13:59 ` Renaud Barbier
2012-08-29 14:01 ` Sascha Hauer
0 siblings, 1 reply; 7+ messages in thread
From: Renaud Barbier @ 2012-08-29 13:59 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 28/08/12 10:19, Sascha Hauer wrote:
>
> These defines look awfully familiar. Can we use
> drivers/i2c/busses/i2c-imx.c instead of adding a new driver?
It indeed does work on the ppc P2020rdb after setting the clock.
Question: is the included header <gpio.h> necessary in the imx I2C driver?
>
> Sascha
>
>
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] Freescale I2C driver
2012-08-29 13:59 ` Renaud Barbier
@ 2012-08-29 14:01 ` Sascha Hauer
0 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2012-08-29 14:01 UTC (permalink / raw)
To: Renaud Barbier; +Cc: barebox
On Wed, Aug 29, 2012 at 02:59:50PM +0100, Renaud Barbier wrote:
> On 28/08/12 10:19, Sascha Hauer wrote:
>
> >
> > These defines look awfully familiar. Can we use
> > drivers/i2c/busses/i2c-imx.c instead of adding a new driver?
> It indeed does work on the ppc P2020rdb after setting the clock.
nice :)
>
> Question: is the included header <gpio.h> necessary in the imx I2C driver?
No, it doesn't seem so
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-08-29 14:01 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-22 15:08 [PATCH 0/3] Freescale I2C driver Renaud Barbier
2012-08-22 15:08 ` [PATCH 1/3] mpc85xx: i2c frequency Renaud Barbier
2012-08-22 15:08 ` [PATCH 2/3] Freescale I2C driver Renaud Barbier
2012-08-28 9:19 ` Sascha Hauer
2012-08-29 13:59 ` Renaud Barbier
2012-08-29 14:01 ` Sascha Hauer
2012-08-22 15:08 ` [PATCH 3/3] ppc: p2020rdb i2c support Renaud Barbier
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.