From 356d15ebb2b0bb2adde2ca4fe4cccb87f75531a0 Mon Sep 17 00:00:00 2001 From: "Karicheri, Muralidharan" Date: Fri, 4 Apr 2014 13:16:51 -0400 Subject: i2c, davinci: move i2c_defs.h to the drivers/i2c directory This patch moves the davinci i2c_defs.h file to drivers.i2c directory. It will allow to reuse the davinci_i2c driver for TI Keystone2 SOCs. Not used "git mv" command to move the file because small part of it with definitions specific for Davinci SOCs has to remain in the arch/arm/include/asm/arch-davinci. Signed-off-by: Vitaly Andrianov Signed-off-by: Murali Karicheri Acked-by: Tom Rini --- drivers/i2c/davinci_i2c.c | 1 + drivers/i2c/davinci_i2c.h | 75 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 drivers/i2c/davinci_i2c.h (limited to 'drivers/i2c') diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c index e56fe75..6e5260c 100644 --- a/drivers/i2c/davinci_i2c.c +++ b/drivers/i2c/davinci_i2c.c @@ -12,6 +12,7 @@ #include #include #include +#include "davinci_i2c.h" #define CHECK_NACK() \ do {\ diff --git a/drivers/i2c/davinci_i2c.h b/drivers/i2c/davinci_i2c.h new file mode 100644 index 0000000..79ff7a3 --- /dev/null +++ b/drivers/i2c/davinci_i2c.h @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2004-2014 + * Texas Instruments, + * + * Some changes copyright (C) 2007 Sergey Kubushyn + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _DAVINCI_I2C_H_ +#define _DAVINCI_I2C_H_ + +#define I2C_WRITE 0 +#define I2C_READ 1 + +#define I2C_OA (I2C_BASE + 0x00) +#define I2C_IE (I2C_BASE + 0x04) +#define I2C_STAT (I2C_BASE + 0x08) +#define I2C_SCLL (I2C_BASE + 0x0c) +#define I2C_SCLH (I2C_BASE + 0x10) +#define I2C_CNT (I2C_BASE + 0x14) +#define I2C_DRR (I2C_BASE + 0x18) +#define I2C_SA (I2C_BASE + 0x1c) +#define I2C_DXR (I2C_BASE + 0x20) +#define I2C_CON (I2C_BASE + 0x24) +#define I2C_IV (I2C_BASE + 0x28) +#define I2C_PSC (I2C_BASE + 0x30) + +/* I2C masks */ + +/* I2C Interrupt Enable Register (I2C_IE): */ +#define I2C_IE_SCD_IE (1 << 5) /* Stop condition detect interrupt enable */ +#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */ +#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */ +#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */ +#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */ +#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */ + +/* I2C Status Register (I2C_STAT): */ + +#define I2C_STAT_BB (1 << 12) /* Bus busy */ +#define I2C_STAT_ROVR (1 << 11) /* Receive overrun */ +#define I2C_STAT_XUDF (1 << 10) /* Transmit underflow */ +#define I2C_STAT_AAS (1 << 9) /* Address as slave */ +#define I2C_STAT_SCD (1 << 5) /* Stop condition detect */ +#define I2C_STAT_XRDY (1 << 4) /* Transmit data ready */ +#define I2C_STAT_RRDY (1 << 3) /* Receive data ready */ +#define I2C_STAT_ARDY (1 << 2) /* Register access ready */ +#define I2C_STAT_NACK (1 << 1) /* No acknowledgment interrupt enable */ +#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */ + +/* I2C Interrupt Code Register (I2C_INTCODE): */ + +#define I2C_INTCODE_MASK 7 +#define I2C_INTCODE_NONE 0 +#define I2C_INTCODE_AL 1 /* Arbitration lost */ +#define I2C_INTCODE_NAK 2 /* No acknowledgement/general call */ +#define I2C_INTCODE_ARDY 3 /* Register access ready */ +#define I2C_INTCODE_RRDY 4 /* Rcv data ready */ +#define I2C_INTCODE_XRDY 5 /* Xmit data ready */ +#define I2C_INTCODE_SCD 6 /* Stop condition detect */ + +/* I2C Configuration Register (I2C_CON): */ + +#define I2C_CON_EN (1 << 5) /* I2C module enable */ +#define I2C_CON_STB (1 << 4) /* Start byte mode (master mode only) */ +#define I2C_CON_MST (1 << 10) /* Master/slave mode */ +#define I2C_CON_TRX (1 << 9) /* Tx/Rx mode (master mode only) */ +#define I2C_CON_XA (1 << 8) /* Expand address */ +#define I2C_CON_STP (1 << 11) /* Stop condition (master mode only) */ +#define I2C_CON_STT (1 << 13) /* Start condition (master mode only) */ +#define I2C_CON_FREE (1 << 14) /* Free run on emulation */ + +#define I2C_TIMEOUT 0xffff0000 /* Timeout mask for poll_i2c_irq() */ + +#endif -- cgit v1.1 From e8459dcc33c3f3fc5a98b7b69bb3ddd7ad77f632 Mon Sep 17 00:00:00 2001 From: Vitaly Andrianov Date: Fri, 4 Apr 2014 13:16:52 -0400 Subject: i2c, davinci: convert driver to new mutlibus/mutliadapter framework - add davinci driver to new multibus/multiadpater support - adapted all config files, which uses this driver Signed-off-by: Vitaly Andrianov Signed-off-by: Murali Karicheri Acked-by: Heiko Schocher --- drivers/i2c/Makefile | 2 +- drivers/i2c/davinci_i2c.c | 401 +++++++++++++++++++++++++++------------------- drivers/i2c/davinci_i2c.h | 27 ++-- 3 files changed, 250 insertions(+), 180 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 36d5e5f..e33586d 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -6,7 +6,6 @@ # obj-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o -obj-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o obj-$(CONFIG_DW_I2C) += designware_i2c.o obj-$(CONFIG_I2C_MVTWSI) += mvtwsi.o obj-$(CONFIG_I2C_MV) += mv_i2c.o @@ -16,6 +15,7 @@ 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_SYS_I2C) += i2c_core.o +obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o obj-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c index 6e5260c..9ca99c4 100644 --- a/drivers/i2c/davinci_i2c.c +++ b/drivers/i2c/davinci_i2c.c @@ -1,8 +1,9 @@ /* * TI DaVinci (TMS320DM644x) I2C driver. * - * Copyright (C) 2007 Sergey Kubushyn - * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * (C) Copyright 2007 Sergey Kubushyn * -------------------------------------------------------- * * SPDX-License-Identifier: GPL-2.0+ @@ -12,306 +13,372 @@ #include #include #include +#include #include "davinci_i2c.h" #define CHECK_NACK() \ do {\ if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\ - REG(I2C_CON) = 0;\ - return(1);\ - }\ + REG(&(i2c_base->i2c_con)) = 0;\ + return 1;\ + } \ } while (0) +static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap); -static int wait_for_bus(void) +static int wait_for_bus(struct i2c_adapter *adap) { + struct i2c_regs *i2c_base = davinci_get_base(adap); int stat, timeout; - REG(I2C_STAT) = 0xffff; + REG(&(i2c_base->i2c_stat)) = 0xffff; for (timeout = 0; timeout < 10; timeout++) { - if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) { - REG(I2C_STAT) = 0xffff; - return(0); + stat = REG(&(i2c_base->i2c_stat)); + if (!((stat) & I2C_STAT_BB)) { + REG(&(i2c_base->i2c_stat)) = 0xffff; + return 0; } - REG(I2C_STAT) = stat; + REG(&(i2c_base->i2c_stat)) = stat; udelay(50000); } - REG(I2C_STAT) = 0xffff; - return(1); + REG(&(i2c_base->i2c_stat)) = 0xffff; + return 1; } -static int poll_i2c_irq(int mask) +static int poll_i2c_irq(struct i2c_adapter *adap, int mask) { + struct i2c_regs *i2c_base = davinci_get_base(adap); int stat, timeout; for (timeout = 0; timeout < 10; timeout++) { udelay(1000); - stat = REG(I2C_STAT); - if (stat & mask) { - return(stat); - } + stat = REG(&(i2c_base->i2c_stat)); + if (stat & mask) + return stat; } - REG(I2C_STAT) = 0xffff; - return(stat | I2C_TIMEOUT); + REG(&(i2c_base->i2c_stat)) = 0xffff; + return stat | I2C_TIMEOUT; } - -void flush_rx(void) +static void flush_rx(struct i2c_adapter *adap) { + struct i2c_regs *i2c_base = davinci_get_base(adap); + while (1) { - if (!(REG(I2C_STAT) & I2C_STAT_RRDY)) + if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY)) break; - REG(I2C_DRR); - REG(I2C_STAT) = I2C_STAT_RRDY; + REG(&(i2c_base->i2c_drr)); + REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY; udelay(1000); } } +static uint davinci_i2c_setspeed(struct i2c_adapter *adap, uint speed) +{ + struct i2c_regs *i2c_base = davinci_get_base(adap); + uint32_t div, psc; + + psc = 2; + /* SCLL + SCLH */ + div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10; + REG(&(i2c_base->i2c_psc)) = psc; /* 27MHz / (2 + 1) = 9MHz */ + REG(&(i2c_base->i2c_scll)) = (div * 50) / 100; /* 50% Duty */ + REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll)); + + adap->speed = speed; + return 0; +} -void i2c_init(int speed, int slaveadd) +static void davinci_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) { - u_int32_t div, psc; + struct i2c_regs *i2c_base = davinci_get_base(adap); - if (REG(I2C_CON) & I2C_CON_EN) { - REG(I2C_CON) = 0; - udelay (50000); + if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) { + REG(&(i2c_base->i2c_con)) = 0; + udelay(50000); } - psc = 2; - div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10; /* SCLL + SCLH */ - REG(I2C_PSC) = psc; /* 27MHz / (2 + 1) = 9MHz */ - REG(I2C_SCLL) = (div * 50) / 100; /* 50% Duty */ - REG(I2C_SCLH) = div - REG(I2C_SCLL); + davinci_i2c_setspeed(adap, speed); - REG(I2C_OA) = slaveadd; - REG(I2C_CNT) = 0; + REG(&(i2c_base->i2c_oa)) = slaveadd; + REG(&(i2c_base->i2c_cnt)) = 0; /* Interrupts must be enabled or I2C module won't work */ - REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE | + REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE; /* Now enable I2C controller (get it out of reset) */ - REG(I2C_CON) = I2C_CON_EN; + REG(&(i2c_base->i2c_con)) = I2C_CON_EN; udelay(1000); } -int i2c_set_bus_speed(unsigned int speed) -{ - i2c_init(speed, CONFIG_SYS_I2C_SLAVE); - return 0; -} - -int i2c_probe(u_int8_t chip) +static int davinci_i2c_probe(struct i2c_adapter *adap, uint8_t chip) { + struct i2c_regs *i2c_base = davinci_get_base(adap); int rc = 1; - if (chip == REG(I2C_OA)) { - return(rc); - } + if (chip == REG(&(i2c_base->i2c_oa))) + return rc; - REG(I2C_CON) = 0; - if (wait_for_bus()) {return(1);} + REG(&(i2c_base->i2c_con)) = 0; + if (wait_for_bus(adap)) + return 1; /* try to read one byte from current (or only) address */ - REG(I2C_CNT) = 1; - REG(I2C_SA) = chip; - REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP); - udelay (50000); + REG(&(i2c_base->i2c_cnt)) = 1; + REG(&(i2c_base->i2c_sa)) = chip; + REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | + I2C_CON_STP); + udelay(50000); - if (!(REG(I2C_STAT) & I2C_STAT_NACK)) { + if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) { rc = 0; - flush_rx(); - REG(I2C_STAT) = 0xffff; + flush_rx(adap); + REG(&(i2c_base->i2c_stat)) = 0xffff; } else { - REG(I2C_STAT) = 0xffff; - REG(I2C_CON) |= I2C_CON_STP; + REG(&(i2c_base->i2c_stat)) = 0xffff; + REG(&(i2c_base->i2c_con)) |= I2C_CON_STP; udelay(20000); - if (wait_for_bus()) {return(1);} + if (wait_for_bus(adap)) + return 1; } - flush_rx(); - REG(I2C_STAT) = 0xffff; - REG(I2C_CNT) = 0; - return(rc); + flush_rx(adap); + REG(&(i2c_base->i2c_stat)) = 0xffff; + REG(&(i2c_base->i2c_cnt)) = 0; + return rc; } - -int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len) +static int davinci_i2c_read(struct i2c_adapter *adap, uint8_t chip, + uint32_t addr, int alen, uint8_t *buf, int len) { - u_int32_t tmp; + struct i2c_regs *i2c_base = davinci_get_base(adap); + uint32_t tmp; int i; if ((alen < 0) || (alen > 2)) { - printf("%s(): bogus address length %x\n", __FUNCTION__, alen); - return(1); + printf("%s(): bogus address length %x\n", __func__, alen); + return 1; } - if (wait_for_bus()) {return(1);} + if (wait_for_bus(adap)) + return 1; if (alen != 0) { /* Start address phase */ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX; - REG(I2C_CNT) = alen; - REG(I2C_SA) = chip; - REG(I2C_CON) = tmp; + REG(&(i2c_base->i2c_cnt)) = alen; + REG(&(i2c_base->i2c_sa)) = chip; + REG(&(i2c_base->i2c_con)) = tmp; - tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK); + tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); CHECK_NACK(); switch (alen) { - case 2: - /* Send address MSByte */ - if (tmp & I2C_STAT_XRDY) { - REG(I2C_DXR) = (addr >> 8) & 0xff; - } else { - REG(I2C_CON) = 0; - return(1); - } - - tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK); - - CHECK_NACK(); - /* No break, fall through */ - case 1: - /* Send address LSByte */ - if (tmp & I2C_STAT_XRDY) { - REG(I2C_DXR) = addr & 0xff; - } else { - REG(I2C_CON) = 0; - return(1); - } - - tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY); - - CHECK_NACK(); - - if (!(tmp & I2C_STAT_ARDY)) { - REG(I2C_CON) = 0; - return(1); - } + case 2: + /* Send address MSByte */ + if (tmp & I2C_STAT_XRDY) { + REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff; + } else { + REG(&(i2c_base->i2c_con)) = 0; + return 1; + } + + tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); + + CHECK_NACK(); + /* No break, fall through */ + case 1: + /* Send address LSByte */ + if (tmp & I2C_STAT_XRDY) { + REG(&(i2c_base->i2c_dxr)) = addr & 0xff; + } else { + REG(&(i2c_base->i2c_con)) = 0; + return 1; + } + + tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | + I2C_STAT_NACK | I2C_STAT_ARDY); + + CHECK_NACK(); + + if (!(tmp & I2C_STAT_ARDY)) { + REG(&(i2c_base->i2c_con)) = 0; + return 1; + } } } /* Address phase is over, now read 'len' bytes and stop */ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP; - REG(I2C_CNT) = len & 0xffff; - REG(I2C_SA) = chip; - REG(I2C_CON) = tmp; + REG(&(i2c_base->i2c_cnt)) = len & 0xffff; + REG(&(i2c_base->i2c_sa)) = chip; + REG(&(i2c_base->i2c_con)) = tmp; for (i = 0; i < len; i++) { - tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR); + tmp = poll_i2c_irq(adap, I2C_STAT_RRDY | I2C_STAT_NACK | + I2C_STAT_ROVR); CHECK_NACK(); if (tmp & I2C_STAT_RRDY) { - buf[i] = REG(I2C_DRR); + buf[i] = REG(&(i2c_base->i2c_drr)); } else { - REG(I2C_CON) = 0; - return(1); + REG(&(i2c_base->i2c_con)) = 0; + return 1; } } - tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK); + tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK); CHECK_NACK(); if (!(tmp & I2C_STAT_SCD)) { - REG(I2C_CON) = 0; - return(1); + REG(&(i2c_base->i2c_con)) = 0; + return 1; } - flush_rx(); - REG(I2C_STAT) = 0xffff; - REG(I2C_CNT) = 0; - REG(I2C_CON) = 0; + flush_rx(adap); + REG(&(i2c_base->i2c_stat)) = 0xffff; + REG(&(i2c_base->i2c_cnt)) = 0; + REG(&(i2c_base->i2c_con)) = 0; - return(0); + return 0; } - -int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len) +static int davinci_i2c_write(struct i2c_adapter *adap, uint8_t chip, + uint32_t addr, int alen, uint8_t *buf, int len) { - u_int32_t tmp; + struct i2c_regs *i2c_base = davinci_get_base(adap); + uint32_t tmp; int i; if ((alen < 0) || (alen > 2)) { - printf("%s(): bogus address length %x\n", __FUNCTION__, alen); - return(1); + printf("%s(): bogus address length %x\n", __func__, alen); + return 1; } if (len < 0) { - printf("%s(): bogus length %x\n", __FUNCTION__, len); - return(1); + printf("%s(): bogus length %x\n", __func__, len); + return 1; } - if (wait_for_bus()) {return(1);} + if (wait_for_bus(adap)) + return 1; /* Start address phase */ - tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP; - REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen; - REG(I2C_SA) = chip; - REG(I2C_CON) = tmp; + tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | + I2C_CON_TRX | I2C_CON_STP; + REG(&(i2c_base->i2c_cnt)) = (alen == 0) ? + len & 0xffff : (len & 0xffff) + alen; + REG(&(i2c_base->i2c_sa)) = chip; + REG(&(i2c_base->i2c_con)) = tmp; switch (alen) { - case 2: - /* Send address MSByte */ - tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK); + case 2: + /* Send address MSByte */ + tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); - CHECK_NACK(); + CHECK_NACK(); - if (tmp & I2C_STAT_XRDY) { - REG(I2C_DXR) = (addr >> 8) & 0xff; - } else { - REG(I2C_CON) = 0; - return(1); - } - /* No break, fall through */ - case 1: - /* Send address LSByte */ - tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK); + if (tmp & I2C_STAT_XRDY) { + REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff; + } else { + REG(&(i2c_base->i2c_con)) = 0; + return 1; + } + /* No break, fall through */ + case 1: + /* Send address LSByte */ + tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); - CHECK_NACK(); + CHECK_NACK(); - if (tmp & I2C_STAT_XRDY) { - REG(I2C_DXR) = addr & 0xff; - } else { - REG(I2C_CON) = 0; - return(1); - } + if (tmp & I2C_STAT_XRDY) { + REG(&(i2c_base->i2c_dxr)) = addr & 0xff; + } else { + REG(&(i2c_base->i2c_con)) = 0; + return 1; + } } for (i = 0; i < len; i++) { - tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK); + tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); CHECK_NACK(); - if (tmp & I2C_STAT_XRDY) { - REG(I2C_DXR) = buf[i]; - } else { - return(1); - } + if (tmp & I2C_STAT_XRDY) + REG(&(i2c_base->i2c_dxr)) = buf[i]; + else + return 1; } - tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK); + tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK); CHECK_NACK(); if (!(tmp & I2C_STAT_SCD)) { - REG(I2C_CON) = 0; - return(1); + REG(&(i2c_base->i2c_con)) = 0; + return 1; } - flush_rx(); - REG(I2C_STAT) = 0xffff; - REG(I2C_CNT) = 0; - REG(I2C_CON) = 0; + flush_rx(adap); + REG(&(i2c_base->i2c_stat)) = 0xffff; + REG(&(i2c_base->i2c_cnt)) = 0; + REG(&(i2c_base->i2c_con)) = 0; + + return 0; +} + +static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap) +{ + switch (adap->hwadapnr) { +#if I2C_BUS_MAX >= 3 + case 2: + return (struct i2c_regs *)I2C2_BASE; +#endif +#if I2C_BUS_MAX >= 2 + case 1: + return (struct i2c_regs *)I2C1_BASE; +#endif + case 0: + return (struct i2c_regs *)I2C_BASE; + + default: + printf("wrong hwadapnr: %d\n", adap->hwadapnr); + } - return(0); + return NULL; } + +U_BOOT_I2C_ADAP_COMPLETE(davinci_0, davinci_i2c_init, davinci_i2c_probe, + davinci_i2c_read, davinci_i2c_write, + davinci_i2c_setspeed, + CONFIG_SYS_DAVINCI_I2C_SPEED, + CONFIG_SYS_DAVINCI_I2C_SLAVE, + 0) + +#if I2C_BUS_MAX >= 2 +U_BOOT_I2C_ADAP_COMPLETE(davinci_1, davinci_i2c_init, davinci_i2c_probe, + davinci_i2c_read, davinci_i2c_write, + davinci_i2c_setspeed, + CONFIG_SYS_DAVINCI_I2C_SPEED1, + CONFIG_SYS_DAVINCI_I2C_SLAVE1, + 1) +#endif + +#if I2C_BUS_MAX >= 3 +U_BOOT_I2C_ADAP_COMPLETE(davinci_2, davinci_i2c_init, davinci_i2c_probe, + davinci_i2c_read, davinci_i2c_write, + davinci_i2c_setspeed, + CONFIG_SYS_DAVINCI_I2C_SPEED2, + CONFIG_SYS_DAVINCI_I2C_SLAVE2, + 2) +#endif diff --git a/drivers/i2c/davinci_i2c.h b/drivers/i2c/davinci_i2c.h index 79ff7a3..20d4342 100644 --- a/drivers/i2c/davinci_i2c.h +++ b/drivers/i2c/davinci_i2c.h @@ -12,18 +12,21 @@ #define I2C_WRITE 0 #define I2C_READ 1 -#define I2C_OA (I2C_BASE + 0x00) -#define I2C_IE (I2C_BASE + 0x04) -#define I2C_STAT (I2C_BASE + 0x08) -#define I2C_SCLL (I2C_BASE + 0x0c) -#define I2C_SCLH (I2C_BASE + 0x10) -#define I2C_CNT (I2C_BASE + 0x14) -#define I2C_DRR (I2C_BASE + 0x18) -#define I2C_SA (I2C_BASE + 0x1c) -#define I2C_DXR (I2C_BASE + 0x20) -#define I2C_CON (I2C_BASE + 0x24) -#define I2C_IV (I2C_BASE + 0x28) -#define I2C_PSC (I2C_BASE + 0x30) +struct i2c_regs { + u32 i2c_oa; + u32 i2c_ie; + u32 i2c_stat; + u32 i2c_scll; + u32 i2c_sclh; + u32 i2c_cnt; + u32 i2c_drr; + u32 i2c_sa; + u32 i2c_dxr; + u32 i2c_con; + u32 i2c_iv; + u32 res_2c; + u32 i2c_psc; +}; /* I2C masks */ -- cgit v1.1 From 5146fc2b37a3098f0973b2f2339e069adfc7d272 Mon Sep 17 00:00:00 2001 From: "Jesper B. Christensen" Date: Fri, 25 Apr 2014 15:46:17 +0200 Subject: i2c: zynq: Fixed compilation errors when using DEBUG Signed-off-by: Jesper B. Christensen Signed-off-by: Michal Simek --- drivers/i2c/zynq_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/zynq_i2c.c b/drivers/i2c/zynq_i2c.c index f1f6513..b3264af 100644 --- a/drivers/i2c/zynq_i2c.c +++ b/drivers/i2c/zynq_i2c.c @@ -142,7 +142,7 @@ static u32 zynq_i2c_wait(struct zynq_i2c_registers *zynq_i2c, u32 mask) break; } #ifdef DEBUG - zynq_i2c_debug_status(zynq_i2c)); + zynq_i2c_debug_status(zynq_i2c); #endif /* Clear interrupt status flags */ writel(int_status & mask, &zynq_i2c->interrupt_status); @@ -235,7 +235,7 @@ static int zynq_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD); #ifdef DEBUG - zynq_i2c_debug_status(); + zynq_i2c_debug_status(zynq_i2c); #endif return 0; } -- cgit v1.1 From fab356a0b87d57d474d6e87408f1ede98a503150 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 3 May 2014 17:46:26 +0200 Subject: mvtwsi: Fix clock programming The TWSI_FREQUENCY macro was wrong in 2 ways: 1) It was casting the result of the calculations to an u8, while i2c clk rates are often >= 100Khz which won't fit in a u8, drop the cast. 2) It had an extra factor of 2 in the divider which neither the datasheet nor the Linux driver have. The comment for the default value was wrongly saying that m lives in bits 4-7, while in reality it is in bits 3-6, as can be seen from the correct shift by 3 used in i2c_init(). While at it remove the unused twsi_actual_speed variable. Signed-off-by: Hans de Goede --- drivers/i2c/mvtwsi.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 90c8387..b449443 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -216,7 +216,7 @@ static int twsi_stop(int status) */ #define TWSI_FREQUENCY(m, n) \ - ((u8) (CONFIG_SYS_TCLK / (10 * (m + 1) * 2 * (1 << n)))) + (CONFIG_SYS_TCLK / (10 * (m + 1) * (1 << n))) /* * These are required to be reprogrammed before enabling the controller @@ -225,10 +225,8 @@ static int twsi_stop(int status) * twsi_slave_address left uninitialized lest checkpatch.pl complains. */ -/* Baudrate generator: m (bits 7..4) =4, n (bits 3..0) =4 */ +/* Baudrate generator: m (bits 6..3) = 8, n (bits 2..0) = 4 */ static u8 twsi_baud_rate = 0x44; /* baudrate at controller reset */ -/* Default frequency corresponding to default m=4, n=4 */ -static u8 twsi_actual_speed = TWSI_FREQUENCY(4, 4); /* Default slave address is 0 (so is an uninitialized static) */ static u8 twsi_slave_address; @@ -279,7 +277,6 @@ void i2c_init(int requested_speed, int slaveadd) } /* save baud rate and slave for later calls to twsi_reset */ twsi_baud_rate = baud; - twsi_actual_speed = highest_speed; twsi_slave_address = slaveadd; /* reset controller */ twsi_reset(); -- cgit v1.1 From 2072e7262965bb48d7fffb1e283101e6ed8b21a8 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 3 May 2014 17:46:27 +0200 Subject: mvtwsi: Remove unnecessary twsi_baud_rate and twsi_slave_address globals These are used only once, so their is no need to have them global. This also stops mvtwsi from using any bss vars making it easier to use before dram init (to talk to the pmic to set the dram voltage). Signed-off-by: Hans de Goede --- drivers/i2c/mvtwsi.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index b449443..5ba0e03 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -219,24 +219,12 @@ static int twsi_stop(int status) (CONFIG_SYS_TCLK / (10 * (m + 1) * (1 << n))) /* - * These are required to be reprogrammed before enabling the controller - * because a reset loses them. - * Default values come from the spec, but a twsi_reset will change them. - * twsi_slave_address left uninitialized lest checkpatch.pl complains. - */ - -/* Baudrate generator: m (bits 6..3) = 8, n (bits 2..0) = 4 */ -static u8 twsi_baud_rate = 0x44; /* baudrate at controller reset */ -/* Default slave address is 0 (so is an uninitialized static) */ -static u8 twsi_slave_address; - -/* * Reset controller. * Called at end of i2c_init unsuccessful i2c transactions. * Controller reset also resets the baud rate and slave address, so * re-establish them. */ -static void twsi_reset(void) +static void twsi_reset(u8 baud_rate, u8 slave_address) { /* ensure controller will be enabled by any twsi*() function */ twsi_control_flags = MVTWSI_CONTROL_TWSIEN; @@ -245,9 +233,9 @@ static void twsi_reset(void) /* wait 2 ms -- this is what the Marvell LSP does */ udelay(20000); /* set baud rate */ - writel(twsi_baud_rate, &twsi->baudrate); + writel(baud_rate, &twsi->baudrate); /* set slave address even though we don't use it */ - writel(twsi_slave_address, &twsi->slave_address); + writel(slave_address, &twsi->slave_address); writel(0, &twsi->xtnd_slave_addr); /* assert STOP but don't care for the result */ (void) twsi_stop(0); @@ -275,11 +263,8 @@ void i2c_init(int requested_speed, int slaveadd) } } } - /* save baud rate and slave for later calls to twsi_reset */ - twsi_baud_rate = baud; - twsi_slave_address = slaveadd; /* reset controller */ - twsi_reset(); + twsi_reset(baud, slaveadd); } /* -- cgit v1.1