Sunxi uses the same i2c controller, so re-use the existing code instead of
having our own duplicate code.

Signed-off-by: Hans de Goede <[email protected]>
---
 arch/arm/cpu/armv7/sunxi/board.c      |   1 +
 arch/arm/include/asm/arch-sunxi/i2c.h | 164 +--------------------
 board/sunxi/board.c                   |   7 +
 drivers/i2c/Makefile                  |   2 +-
 drivers/i2c/mvtwsi.c                  |  18 +++
 drivers/i2c/sunxi_i2c.c               | 260 ----------------------------------
 include/configs/sunxi-common.h        |   7 +-
 7 files changed, 36 insertions(+), 423 deletions(-)
 delete mode 100644 drivers/i2c/sunxi_i2c.c

diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index 8147a99..9e5aec2 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -106,6 +106,7 @@ void s_init(void)
        clock_init();
        timer_init();
        gpio_init();
+       i2c_init_board();
 
 #ifdef CONFIG_SPL_BUILD
        gd = &gdata;
diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h 
b/arch/arm/include/asm/arch-sunxi/i2c.h
index 74c2d18..dc5406b 100644
--- a/arch/arm/include/asm/arch-sunxi/i2c.h
+++ b/arch/arm/include/asm/arch-sunxi/i2c.h
@@ -1,169 +1,15 @@
 /*
- * (C) Copyright 2012 Henrik Nordstrom <[email protected]>
- *
- * Based on sun4i linux kernle i2c.h
- * (C) Copyright 2007-2012
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- * Tom Cubie <[email protected]>
- * Victor Wei <[email protected]>
+ * Copyright 2014 - Hans de Goede <[email protected]>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #ifndef _SUNXI_I2C_H_
 #define _SUNXI_I2C_H_
 
-struct i2c {
-       u32 saddr;      /*  31:8bit res,7-1bit for slave addr,0 bit for GCE */
-       u32 xsaddr;     /*  31:8bit res,7-0bit for second addr in 10bit addr */
-       u32 data;       /*  31:8bit res, 7-0bit send or receive data byte */
-       u32 ctl;        /*  INT_EN,BUS_EN,M_STA,INT_FLAG,A_ACK */
-       u32 status;     /*  28 interrupt types + 0xf8 normal type = 29  */
-       u32 clkr;       /*  31:7bit res,6-3bit,CLK_M,2-0bit CLK_N */
-       u32 reset;      /*  31:1bit res;0bit,write 1 to clear 0. */
-       u32 efr;        /*  31:2bit res,1:0 bit data byte follow read comand */
-       u32 lctl;       /*  31:6bits res 5:0bit for sda&scl control */
-};
-
-/* TWI address register */
-#define TWI_GCE_EN     (0x1 << 0)      /* gen call addr enable slave mode */
-#define TWI_ADDR_MASK  (0x7f << 1)     /* 7:1bits */
-#define TWI_XADDR_MASK 0xff            /* 7:0bits for extend slave address */
-
-#define TWI_DATA_MASK  0xff            /* 7:0bits for send or received */
-
-/* TWI Control Register Bit Fields */
-/* 1:0 bits reserved */
-/* set 1 to send A_ACK,then low level on SDA */
-#define TWI_CTL_ACK    (0x1 << 2)
-/* INT_FLAG,interrupt status flag: set '1' when interrupt coming */
-#define TWI_CTL_INTFLG (0x1 << 3)
-#define TWI_CTL_STP    (0x1 << 4)      /* M_STP,Automatic clear 0 */
-#define TWI_CTL_STA    (0x1 << 5)      /* M_STA,atutomatic clear 0 */
-#define TWI_CTL_BUSEN  (0x1 << 6)      /* BUS_EN, mastr mode should be set 1 */
-#define TWI_CTL_INTEN  (0x1 << 7)      /* INT_EN */
-/* 31:8 bit reserved */
-
-/*
- * TWI Clock Register Bit Fields & Masks,default value:0x0000_0000
- * Fin is APB CLOCK INPUT;
- * Fsample = F0 = Fin/2^CLK_N;
- *           F1 = F0/(CLK_M+1);
- *
- * Foscl = F1/10 = Fin/(2^CLK_N * (CLK_M+1)*10);
- * Foscl is clock SCL;standard mode:100KHz or fast mode:400KHz
- */
-
-#define TWI_CLK_DIV_M          (0xf << 3)      /* 6:3bit  */
-#define TWI_CLK_DIV_N          (0x7 << 0)      /* 2:0bit */
-#define TWI_CLK_DIV(N, M)      ((((N) & 0xf) << 3) | (((M) & 0x7) << 0))
-
-/* TWI Soft Reset Register Bit Fields & Masks  */
-/* write 1 to clear 0, when complete soft reset clear 0 */
-#define TWI_SRST_SRST          (0x1 << 0)
-
-/* TWI Enhance Feature Register Bit Fields & Masks  */
-/* default -- 0x0 */
-/* 00:no,01: 1byte, 10:2 bytes, 11: 3bytes */
-#define TWI_EFR_MASK           (0x3 << 0)
-#define TWI_EFR_WARC_0         (0x0 << 0)
-#define TWI_EFR_WARC_1         (0x1 << 0)
-#define TWI_EFR_WARC_2         (0x2 << 0)
-#define TWI_EFR_WARC_3         (0x3 << 0)
-
-/* twi line control register -default value: 0x0000_003a */
-/* SDA line state control enable ,1:enable;0:disable */
-#define TWI_LCR_SDA_EN         (0x01 << 0)
-/* SDA line state control bit, 1:high level;0:low level */
-#define TWI_LCR_SDA_CTL                (0x01 << 1)
-/* SCL line state control enable ,1:enable;0:disable */
-#define TWI_LCR_SCL_EN         (0x01 << 2)
-/* SCL line state control bit, 1:high level;0:low level */
-#define TWI_LCR_SCL_CTL                (0x01 << 3)
-/* current state of SDA,readonly bit */
-#define TWI_LCR_SDA_STATE_MASK (0x01 << 4)
-/* current state of SCL,readonly bit */
-#define TWI_LCR_SCL_STATE_MASK (0x01 << 5)
-/* 31:6bits reserved */
-#define TWI_LCR_IDLE_STATUS    0x3a
-
-/* TWI Status Register Bit Fields & Masks  */
-#define TWI_STAT_MASK          0xff
-/* 7:0 bits use only,default is 0xf8 */
-#define TWI_STAT_BUS_ERR       0x00    /* BUS ERROR */
-
-/* Master mode use only */
-#define TWI_STAT_TX_STA                0x08    /* START condition transmitted 
*/
-/* Repeated START condition transmitted */
-#define TWI_STAT_TX_RESTA      0x10
-/* Address+Write bit transmitted, ACK received */
-#define TWI_STAT_TX_AW_ACK     0x18
-/* Address+Write bit transmitted, ACK not received */
-#define TWI_STAT_TX_AW_NAK     0x20
-/* data byte transmitted in master mode,ack received */
-#define TWI_STAT_TXD_ACK       0x28
-/* data byte transmitted in master mode ,ack not received */
-#define TWI_STAT_TXD_NAK       0x30
-/* arbitration lost in address or data byte */
-#define TWI_STAT_ARBLOST       0x38
-/* Address+Read bit transmitted, ACK received */
-#define TWI_STAT_TX_AR_ACK     0x40
-/* Address+Read bit transmitted, ACK not received */
-#define TWI_STAT_TX_AR_NAK     0x48
-/* Second Address byte + Write bit transmitted, ACK received */
-#define TWI_STAT_TX_2AW_ACK    0xd0
-/* Second Address byte + Write bit transmitted, ACK received */
-#define TWI_STAT_TX_2AW_NAK    0xd8
-/* data byte received in master mode ,ack transmitted */
-#define TWI_STAT_RXD_ACK       0x50
-/* date byte received in master mode,not ack transmitted */
-#define TWI_STAT_RXD_NAK       0x58
-
-/* Slave mode use only */
-/* Slave address+Write bit received, ACK transmitted */
-#define TWI_STAT_RXWS_ACK      0x60
-/*
- * Arbitration lost in address as master, slave address + Write bit received,
- * ACK transmitted
- */
-#define TWI_STAT_ARBLOST_RXWS_ACK 0x68
-/* General Call address received, ACK transmitted */
-#define TWI_STAT_RXGCAS_ACK    0x70
-/*
- * Arbitration lost in address as master, General Call address received,
- * ACK transmitted
- */
-#define TWI_STAT_ARBLOST_RXGCAS_ACK 0x78
-/* Data byte received after slave address received, ACK transmitted */
-#define TWI_STAT_RXDS_ACK      0x80
-/* Data byte received after slave address received, not ACK transmitted */
-#define TWI_STAT_RXDS_NAK      0x88
-/* Data byte received after General Call received, ACK transmitted */
-#define TWI_STAT_RXDGCAS_ACK   0x90
-/* Data byte received after General Call received, not ACK transmitted */
-#define TWI_STAT_RXDGCAS_NAK   0x98
-/* STOP or repeated START condition received in slave  */
-#define TWI_STAT_RXSTPS_RXRESTAS 0xa0
-/* Slave address + Read bit received, ACK transmitted */
-#define TWI_STAT_RXRS_ACK      0xa8
-/*
- * Arbitration lost in address as master, slave address + Read bit received,
- * ACK transmitted
- */
-#define TWI_STAT_ARBLOST_SLAR_ACK 0xb0
-/* Data byte transmitted in slave mode, ACK received */
-#define TWI_STAT_TXDS_ACK      0xb8
-/* Data byte transmitted in slave mode, ACK not received */
-#define TWI_STAT_TXDS_NAK      0xc0
-/* Last byte transmitted in slave mode, ACK received */
-#define TWI_STAT_TXDSL_ACK     0xc8
-
-/* 10bit Address, second part of address */
-/* Second Address byte+Write bit transmitted,ACK received */
-#define TWI_STAT_TX_SAW_ACK    0xd0
-/* Second Address byte+Write bit transmitted,ACK not received */
-#define TWI_STAT_TX_SAW_NAK    0xd8
+#include <asm/arch/cpu.h>
 
-/* No relevant status infomation,INT_FLAG = 0 */
-#define TWI_STAT_IDLE          0xf8
+#define CONFIG_I2C_MVTWSI_BASE SUNXI_TWI0_BASE
+/* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */
+#define CONFIG_SYS_TCLK                24000000
 
 #endif
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 27feecc..c5487c7 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -136,6 +136,13 @@ int board_mmc_init(bd_t *bis)
 }
 #endif
 
+void i2c_init_board(void)
+{
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB0_TWI0);
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB0_TWI0);
+       clock_twi_onoff(0, 1);
+}
+
 #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I)
 void sunxi_board_init(void)
 {
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index ca89ac7..a8ccb52 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o
 obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
 obj-$(CONFIG_U8500_I2C) += u8500_i2c.o
 obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
-obj-$(CONFIG_SUNXI_I2C) += sunxi_i2c.o
 obj-$(CONFIG_SYS_I2C) += i2c_core.o
 obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o
 obj-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o
@@ -28,5 +27,6 @@ obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o
 obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o
 obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
 obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
+obj-$(CONFIG_SYS_I2C_SUNXI) += mvtwsi.o
 obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
 obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 5ba0e03..e670515 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -22,6 +22,8 @@
 #include <asm/arch/orion5x.h>
 #elif defined(CONFIG_KIRKWOOD)
 #include <asm/arch/kirkwood.h>
+#elif defined(CONFIG_SUNXI)
+#include <asm/arch/i2c.h>
 #else
 #error Driver mvtwsi not supported by SoC or board
 #endif
@@ -30,6 +32,20 @@
  * TWSI register structure
  */
 
+#ifdef CONFIG_SUNXI
+
+struct  mvtwsi_registers {
+       u32 slave_address;
+       u32 xtnd_slave_addr;
+       u32 data;
+       u32 control;
+       u32 status;
+       u32 baudrate;
+       u32 soft_reset;
+};
+
+#else
+
 struct  mvtwsi_registers {
        u32 slave_address;
        u32 data;
@@ -43,6 +59,8 @@ struct  mvtwsi_registers {
        u32 soft_reset;
 };
 
+#endif
+
 /*
  * Control register fields
  */
diff --git a/drivers/i2c/sunxi_i2c.c b/drivers/i2c/sunxi_i2c.c
deleted file mode 100644
index 43a19c4..0000000
--- a/drivers/i2c/sunxi_i2c.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * (C) Copyright 2012 Henrik Nordstrom <[email protected]>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <i2c.h>
-#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/gpio.h>
-#include <asm/arch/i2c.h>
-
-static struct i2c __attribute__ ((section(".data"))) *i2c_base =
-       (struct i2c *)SUNXI_TWI0_BASE;
-
-void i2c_init(int speed, int slaveaddr)
-{
-       int timeout = 0x2ff;
-
-       sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB0_TWI0);
-       sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB0_TWI0);
-       clock_twi_onoff(0, 1);
-
-       /* Enable the i2c bus */
-       writel(TWI_CTL_BUSEN, &i2c_base->ctl);
-
-       /* 400KHz operation M=2, N=1, 24MHz APB clock */
-       writel(TWI_CLK_DIV(2, 1), &i2c_base->clkr);
-       writel(TWI_SRST_SRST, &i2c_base->reset);
-
-       while ((readl(&i2c_base->reset) & TWI_SRST_SRST) && timeout--);
-}
-
-int i2c_probe(uchar chip)
-{
-       return -1;
-}
-
-static int i2c_wait_ctl(int mask, int state)
-{
-       int timeout = 0x2ff;
-       int value = state ? mask : 0;
-
-       debug("i2c_wait_ctl(%x == %x), ctl=%x, status=%x\n", mask, value,
-             i2c_base->ctl, i2c_base->status);
-
-       while (((readl(&i2c_base->ctl) & mask) != value) && timeout-- > 0);
-
-       debug("i2c_wait_ctl(), timeout=%d, ctl=%x, status=%x\n", timeout,
-             i2c_base->ctl, i2c_base->status);
-
-       if (timeout != 0)
-               return 0;
-       else
-               return -1;
-}
-
-static void i2c_clear_irq(void)
-{
-       writel(readl(&i2c_base->ctl) & ~TWI_CTL_INTFLG, &i2c_base->ctl);
-}
-
-static int i2c_wait_irq(void)
-{
-       return i2c_wait_ctl(TWI_CTL_INTFLG, 1);
-}
-
-static int i2c_wait_status(int status)
-{
-       int timeout = 0x2ff;
-
-       while (readl(&i2c_base->status) != status && timeout-- > 0);
-
-       if (timeout != 0)
-               return 0;
-       else
-               return -1;
-}
-
-static int i2c_wait_irq_status(int status)
-{
-       if (i2c_wait_irq() != 0)
-               return -1;
-
-       if (readl(&i2c_base->status) != status)
-               return -1;
-
-       return 0;
-}
-
-static int i2c_wait_bus_idle(void)
-{
-       int timeout = 0x2ff;
-
-       while (readl(&i2c_base->lctl) != 0x3a && timeout-- > 0);
-
-       if (timeout != 0)
-               return 0;
-       else
-               return -1;
-}
-
-static int i2c_stop(void)
-{
-       u32 ctl;
-
-       ctl = readl(&i2c_base->ctl) & 0xc0;
-       ctl |= TWI_CTL_STP;
-
-       writel(ctl, &i2c_base->ctl);
-
-       /* dummy to delay one I/O operation to make sure it's started */
-       (void)readl(&i2c_base->ctl);
-
-       if (i2c_wait_ctl(TWI_CTL_STP, 0) != 0)
-               return -1;
-       if (i2c_wait_status(TWI_STAT_IDLE))
-               return -1;
-       if (i2c_wait_bus_idle() != 0)
-               return -1;
-
-       return 0;
-}
-
-static int i2c_send_data(u8 data, u8 status)
-{
-       debug("i2c_write(%02x, %x), ctl=%x, status=%x\n", data, status,
-             i2c_base->ctl, i2c_base->status);
-
-       writel(data, &i2c_base->data);
-       i2c_clear_irq();
-
-       if (i2c_wait_irq_status(status) != 0)
-               return -1;
-
-       return 0;
-}
-
-static int i2c_start(int status)
-{
-       u32 ctl;
-
-       debug("i2c_start(%x), ctl=%x, status=%x\n", status, i2c_base->ctl,
-             i2c_base->status);
-       /* Check that the controller is idle */
-       if (status == TWI_STAT_TX_STA &&
-           readl(&i2c_base->status) != TWI_STAT_IDLE) {
-               return -1;
-       }
-
-       writel(0, &i2c_base->efr);
-
-       /* Send start */
-       ctl = readl(&i2c_base->ctl);
-       ctl |= TWI_CTL_STA;     /* Set start bit */
-       ctl &= ~TWI_CTL_INTFLG; /* Clear int flag */
-       writel(ctl, &i2c_base->ctl);
-
-       if (i2c_wait_ctl(TWI_CTL_STA, 0) != 0)
-               return -1;
-       if (i2c_wait_irq_status(status) != 0)
-               return -1;
-
-       return 0;
-}
-
-int i2c_do_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-       u32 status;
-       u32 ctl;
-
-       if (i2c_start(TWI_STAT_TX_STA) != 0)
-               return -1;
-
-       /* Send chip address */
-       if (i2c_send_data(chip << 1 | 0, TWI_STAT_TX_AW_ACK) != 0)
-               return -1;
-
-       /* Send data address */
-       if (i2c_send_data(addr, TWI_STAT_TXD_ACK) != 0)
-               return -1;
-
-       /* Send restart for read */
-       if (i2c_start(TWI_STAT_TX_RESTA) != 0)
-               return -1;
-
-       /* Send chip address */
-       if (i2c_send_data(chip << 1 | 1, TWI_STAT_TX_AR_ACK) != 0)
-               return -1;
-
-       /* Set ACK mode */
-       ctl = readl(&i2c_base->ctl);
-       ctl |= TWI_CTL_ACK;
-       writel(ctl, &i2c_base->ctl);
-       status = TWI_STAT_RXD_ACK;
-
-       /* Read data */
-       while (len > 0) {
-               if (len == 1) {
-                       /* Set NACK mode (last byte) */
-                       ctl = readl(&i2c_base->ctl);
-                       ctl &= ~TWI_CTL_ACK;
-                       writel(ctl, &i2c_base->ctl);
-                       status = TWI_STAT_RXD_NAK;
-               }
-
-               i2c_clear_irq();
-               if (i2c_wait_irq_status(status) != 0)
-                       return -1;
-
-               *buffer++ = readl(&i2c_base->data);
-               len--;
-       }
-
-       return 0;
-}
-
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-       int rc = i2c_do_read(chip, addr, alen, buffer, len);
-
-       i2c_stop();
-
-       return rc;
-}
-
-static int i2c_do_write(uchar chip, uint addr, int alen, uchar *buffer,
-                       int len)
-{
-       if (i2c_start(TWI_STAT_TX_STA) != 0)
-               return -1;
-
-       /* Send chip address */
-       if (i2c_send_data(chip << 1 | 0, TWI_STAT_TX_AW_ACK) != 0)
-               return -1;
-
-       /* Send data address */
-       if (i2c_send_data(addr, TWI_STAT_TXD_ACK) != 0)
-               return -1;
-
-       /* Send data */
-       while (len > 0) {
-               if (i2c_send_data(*buffer++, TWI_STAT_TXD_ACK) != 0)
-                       return -1;
-               len--;
-       }
-
-       return 0;
-}
-
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-       int rc = i2c_do_write(chip, addr, alen, buffer, len);
-
-       i2c_stop();
-
-       return rc;
-}
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 035bc60..e11c4ee 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -314,12 +314,13 @@
 #undef CONFIG_CMD_NFS
 
 /* I2C */
-#ifndef CONFIG_SUN6I
+#if !defined CONFIG_SUN6I && !defined CONFIG_SUN8I
 #define CONFIG_SPL_I2C_SUPPORT
 #endif
-#define CONFIG_SYS_I2C_SPEED           400000
+/* No CONFIG_SYS_I2C as we use the non converted mvtwsi driver */
 #define CONFIG_HARD_I2C
-#define CONFIG_SUNXI_I2C
+#define CONFIG_SYS_I2C_SUNXI
+#define CONFIG_SYS_I2C_SPEED           400000
 #define CONFIG_SYS_I2C_SLAVE           0x7f
 #define CONFIG_CMD_I2C
 
-- 
1.9.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to