From mboxrd@z Thu Jan 1 00:00:00 1970 From: Rajeshwari Birje Date: Tue, 19 Jun 2012 11:08:28 +0530 Subject: [U-Boot] [PATCH 6/8 V2] I2C: Modify the I2C driver for EXYNOS5 In-Reply-To: References: <1339049394-4816-1-git-send-email-rajeshwari.s@samsung.com> <1339049394-4816-7-git-send-email-rajeshwari.s@samsung.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Joonyoung Shim, Thank you for comments. On Fri, Jun 15, 2012 at 12:40 PM, Joonyoung Shim wrote: > Hi, > > 2012/6/7 Rajeshwari Shinde : >> This patch modifies the S3C I2C driver to suppport EXYNOS5. >> The cahnges made to driver are as follows: >> ? ? ? ?- I2C base address is passed as a parameter to many >> ? ? ? ?functions to avoid multiple #ifdef >> ? ? ? ?- I2C init for Exynos5 is made as different function. >> ? ? ? ?- Channel initialisation is moved to a commom funation >> ? ? ? ?as it is required by both the i2c_init. >> ? ? ? ?- Separate functions written to get I2C base address, >> ? ? ? ?peripheral id for pinmux support. >> ? ? ? ?- Hardcoding for I2CCON_ACKGEN removed. >> ? ? ? ?- Replaced printf with debug. >> ? ? ? ?- Checkpatch issues resolved. >> >> Signed-off-by: Alim Akhtar >> Signed-off-by: Doug Anderson >> Signed-off-by: Rajeshwari Shinde >> Acked-by: Simon Glass >> --- >> Changes in V2: >> ? ? ? ?- Removed #define for I2C cahnnels from hearder file except for I2C0. >> ? ? ? ?- Incorporated review comments from Simon Glass. >> ?drivers/i2c/s3c24x0_i2c.c | ?254 ++++++++++++++++++++++++++++++++------------- >> ?drivers/i2c/s3c24x0_i2c.h | ? ?3 + >> ?2 files changed, 184 insertions(+), 73 deletions(-) >> >> diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c >> index ba6f39b..a71f147 100644 >> --- a/drivers/i2c/s3c24x0_i2c.c >> +++ b/drivers/i2c/s3c24x0_i2c.c >> @@ -27,10 +27,17 @@ >> ?*/ >> >> ?#include >> +#ifdef CONFIG_EXYNOS5 >> +#include >> +#include >> +#include >> +#include >> +#else >> ?#include >> - >> +#endif >> ?#include >> ?#include >> +#include "s3c24x0_i2c.h" >> >> ?#ifdef CONFIG_HARD_I2C >> >> @@ -45,6 +52,7 @@ >> >> ?#define I2CSTAT_BSY ? ?0x20 ? ?/* Busy bit */ >> ?#define I2CSTAT_NACK ? 0x01 ? ?/* Nack bit */ >> +#define I2CCON_ACKGEN ?0x80 ? ?/* Acknowledge generation */ >> ?#define I2CCON_IRPND ? 0x10 ? ?/* Interrupt pending bit */ >> ?#define I2C_MODE_MT ? ?0xC0 ? ?/* Master Transmit Mode */ >> ?#define I2C_MODE_MR ? ?0x80 ? ?/* Master Receive Mode */ >> @@ -53,6 +61,44 @@ >> >> ?#define I2C_TIMEOUT 1 ? ? ? ? ?/* 1 second */ >> >> +#ifdef CONFIG_EXYNOS5 >> +static unsigned int g_current_bus; ? ? /* Stores Current I2C Bus */ >> + >> +/* We should not rely on any particular ordering of these IDs */ >> +static enum periph_id periph_for_dev[] = { >> + ? ? ? PERIPH_ID_I2C0, >> + ? ? ? PERIPH_ID_I2C1, >> + ? ? ? PERIPH_ID_I2C2, >> + ? ? ? PERIPH_ID_I2C3, >> + ? ? ? PERIPH_ID_I2C4, >> + ? ? ? PERIPH_ID_I2C5, >> + ? ? ? PERIPH_ID_I2C6, >> + ? ? ? PERIPH_ID_I2C7, >> +}; >> + >> +static enum periph_id i2c_get_periph_id(unsigned dev_index) >> +{ >> + ? ? ? if (dev_index < ARRAY_SIZE(periph_for_dev)) >> + ? ? ? ? ? ? ? return periph_for_dev[dev_index]; >> + >> + ? ? ? debug("%s: invalid bus %d", __func__, dev_index); >> + >> + ? ? ? return PERIPH_ID_NONE; >> +} >> + >> +static struct s3c24x0_i2c *get_base_i2c(int bus_idx) >> +{ >> + ? ? ? struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)samsung_get_base_i2c(); >> + >> + ? ? ? return &i2c[bus_idx]; >> +} > > This function can use in the s3c24xx adding #ifdef in this fuction, then > you can reduce #ifdef. -- Will do this. > >> + >> +static inline struct exynos5_gpio_part1 *exynos_get_base_gpio1(void) >> +{ >> + ? ? ? return (struct exynos5_gpio_part1 *)(EXYNOS5_GPIO_PART1_BASE); >> +} >> + >> +#else >> ?static int GetI2CSDA(void) >> ?{ >> ? ? ? ?struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); >> @@ -77,16 +123,17 @@ static void SetI2CSCL(int x) >> ? ? ? ?struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); >> >> ?#ifdef CONFIG_S3C2410 >> - ? ? ? writel((readl(&gpio->gpedat) & ~0x4000) | (x & 1) << 14, &gpio->gpedat); >> + ? ? ? writel((readl(&gpio->gpedat) & ~0x4000) | >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (x & 1) << 14, &gpio->gpedat); >> ?#endif >> ?#ifdef CONFIG_S3C2400 >> ? ? ? ?writel((readl(&gpio->pgdat) & ~0x0040) | (x & 1) << 6, &gpio->pgdat); >> ?#endif >> ?} >> +#endif >> >> -static int WaitForXfer(void) >> +static int WaitForXfer(struct s3c24x0_i2c *i2c) >> ?{ >> - ? ? ? struct s3c24x0_i2c *i2c = s3c24x0_get_base_i2c(); >> ? ? ? ?int i; >> >> ? ? ? ?i = I2C_TIMEOUT * 10000; >> @@ -98,25 +145,84 @@ static int WaitForXfer(void) >> ? ? ? ?return (readl(&i2c->iiccon) & I2CCON_IRPND) ? I2C_OK : I2C_NOK_TOUT; >> ?} >> >> -static int IsACK(void) >> +static int IsACK(struct s3c24x0_i2c *i2c) >> ?{ >> - ? ? ? struct s3c24x0_i2c *i2c = s3c24x0_get_base_i2c(); >> - >> ? ? ? ?return !(readl(&i2c->iicstat) & I2CSTAT_NACK); >> ?} >> >> -static void ReadWriteByte(void) >> +static void ReadWriteByte(struct s3c24x0_i2c *i2c) >> ?{ >> - ? ? ? struct s3c24x0_i2c *i2c = s3c24x0_get_base_i2c(); >> - >> ? ? ? ?writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); >> ?} >> >> +static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) >> +{ >> + ? ? ? ulong freq, pres = 16, div; >> +#ifdef CONFIG_EXYNOS5 >> + ? ? ? freq = get_i2c_clk(); >> +#else >> + ? ? ? freq = get_PCLK(); >> +#endif >> + ? ? ? /* calculate prescaler and divisor values */ >> + ? ? ? if ((freq / pres / (16 + 1)) > speed) >> + ? ? ? ? ? ? ? /* set prescaler to 512 */ >> + ? ? ? ? ? ? ? pres = 512; >> + >> + ? ? ? div = 0; >> + ? ? ? while ((freq / pres / (div + 1)) > speed) >> + ? ? ? ? ? ? ? div++; >> + >> + ? ? ? /* set prescaler, divisor according to freq, also set ACKGEN, IRQ */ >> + ? ? ? writel((div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0), &i2c->iiccon); >> + >> + ? ? ? /* init to SLAVE REVEIVE and set slaveaddr */ >> + ? ? ? writel(0, &i2c->iicstat); >> + ? ? ? writel(slaveadd, &i2c->iicadd); >> + ? ? ? /* program Master Transmit (and implicit STOP) */ >> + ? ? ? writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat); >> +} >> + >> +static void i2c_bus_init(struct s3c24x0_i2c *i2c, unsigned int bus) >> +{ >> + ? ? ? int periph_id = i2c_get_periph_id(bus); >> + >> + ? ? ? exynos_pinmux_config(periph_id, 0); >> + >> + ? ? ? i2c_ch_init(i2c, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); >> +} > > This function is used only in EXYNOS5. -- This will be used in Multi bus also which other boards can use. > >> + >> +#ifdef CONFIG_EXYNOS5 >> +void i2c_init(int speed, int slaveadd) >> +{ >> + ? ? ? struct s3c24x0_i2c *i2c; >> + ? ? ? struct exynos5_gpio_part1 *gpio; >> + ? ? ? int i; >> + >> + ? ? ? /* By default i2c channel 0 is the current bus */ >> + ? ? ? g_current_bus = I2C0; >> + >> + ? ? ? i2c = get_base_i2c(g_current_bus); >> + >> + ? ? ? i2c_bus_init(i2c, g_current_bus); >> + >> + ? ? ? /* wait for some time to give previous transfer a chance to finish */ >> + ? ? ? i = I2C_TIMEOUT * 1000; >> + ? ? ? while ((readl(&i2c->iicstat) & I2CSTAT_BSY) && (i > 0)) { >> + ? ? ? ? ? ? ? udelay(1000); >> + ? ? ? ? ? ? ? i--; >> + ? ? ? } >> + >> + ? ? ? gpio = exynos_get_base_gpio1(); >> + ? ? ? writel((readl(&gpio->b3.con) & ~0x00FF) | 0x0022, &gpio->b3.con); > > This doesn't need to do because of i2c_bus_init(). -- Will correct this. > >> + >> + ? ? ? i2c_ch_init(i2c, speed, slaveadd); > > The i2c_bus_init() calls i2c_ch_init() already. > -- You are right. Will correct this. >> +} >> + >> +#else >> ?void i2c_init(int speed, int slaveadd) >> ?{ >> ? ? ? ?struct s3c24x0_i2c *i2c = s3c24x0_get_base_i2c(); >> ? ? ? ?struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); >> - ? ? ? ulong freq, pres = 16, div; >> ? ? ? ?int i; >> >> ? ? ? ?/* wait for some time to give previous transfer a chance to finish */ >> @@ -171,27 +277,9 @@ void i2c_init(int speed, int slaveadd) >> ?#endif >> ? ? ? ?} >> >> - ? ? ? /* calculate prescaler and divisor values */ >> - ? ? ? freq = get_PCLK(); >> - ? ? ? if ((freq / pres / (16 + 1)) > speed) >> - ? ? ? ? ? ? ? /* set prescaler to 512 */ >> - ? ? ? ? ? ? ? pres = 512; >> - >> - ? ? ? div = 0; >> - ? ? ? while ((freq / pres / (div + 1)) > speed) >> - ? ? ? ? ? ? ? div++; >> - >> - ? ? ? /* set prescaler, divisor according to freq, also set >> - ? ? ? ?* ACKGEN, IRQ */ >> - ? ? ? writel((div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0), &i2c->iiccon); >> - >> - ? ? ? /* init to SLAVE REVEIVE and set slaveaddr */ >> - ? ? ? writel(0, &i2c->iicstat); >> - ? ? ? writel(slaveadd, &i2c->iicadd); >> - ? ? ? /* program Master Transmit (and implicit STOP) */ >> - ? ? ? writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat); >> - >> + ? ? ? i2c_ch_init(i2c, speed, slaveadd); >> ?} >> +#endif >> >> ?/* >> ?* cmd_type is 0 for write, 1 for read. >> @@ -200,19 +288,19 @@ void i2c_init(int speed, int slaveadd) >> ?* by the char, we could make it larger if needed. If it is >> ?* 0 we skip the address write cycle. >> ?*/ >> -static >> -int i2c_transfer(unsigned char cmd_type, >> - ? ? ? ? ? ? ? ?unsigned char chip, >> - ? ? ? ? ? ? ? ?unsigned char addr[], >> - ? ? ? ? ? ? ? ?unsigned char addr_len, >> - ? ? ? ? ? ? ? ?unsigned char data[], unsigned short data_len) >> +static int i2c_transfer(struct s3c24x0_i2c *i2c, >> + ? ? ? ? ? ? ? ? ? ? ? unsigned char cmd_type, >> + ? ? ? ? ? ? ? ? ? ? ? unsigned char chip, >> + ? ? ? ? ? ? ? ? ? ? ? unsigned char addr[], >> + ? ? ? ? ? ? ? ? ? ? ? unsigned char addr_len, >> + ? ? ? ? ? ? ? ? ? ? ? unsigned char data[], >> + ? ? ? ? ? ? ? ? ? ? ? unsigned short data_len) >> ?{ >> - ? ? ? struct s3c24x0_i2c *i2c = s3c24x0_get_base_i2c(); >> ? ? ? ?int i, result; >> >> ? ? ? ?if (data == 0 || data_len == 0) { >> ? ? ? ? ? ? ? ?/*Don't support data transfer of no length or to address 0 */ >> - ? ? ? ? ? ? ? printf("i2c_transfer: bad call\n"); >> + ? ? ? ? ? ? ? debug("i2c_transfer: bad call\n"); >> ? ? ? ? ? ? ? ?return I2C_NOK; >> ? ? ? ?} >> >> @@ -226,7 +314,7 @@ int i2c_transfer(unsigned char cmd_type, >> ? ? ? ?if (readl(&i2c->iicstat) & I2CSTAT_BSY) >> ? ? ? ? ? ? ? ?return I2C_NOK_TOUT; >> >> - ? ? ? writel(readl(&i2c->iiccon) | 0x80, &i2c->iiccon); >> + ? ? ? writel(readl(&i2c->iiccon) | I2CCON_ACKGEN, &i2c->iiccon); >> ? ? ? ?result = I2C_OK; >> >> ? ? ? ?switch (cmd_type) { >> @@ -238,16 +326,16 @@ int i2c_transfer(unsigned char cmd_type, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &i2c->iicstat); >> ? ? ? ? ? ? ? ? ? ? ? ?i = 0; >> ? ? ? ? ? ? ? ? ? ? ? ?while ((i < addr_len) && (result == I2C_OK)) { >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(i2c); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?writel(addr[i], &i2c->iicds); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(i2c); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?i++; >> ? ? ? ? ? ? ? ? ? ? ? ?} >> ? ? ? ? ? ? ? ? ? ? ? ?i = 0; >> ? ? ? ? ? ? ? ? ? ? ? ?while ((i < data_len) && (result == I2C_OK)) { >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(i2c); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?writel(data[i], &i2c->iicds); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(i2c); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?i++; >> ? ? ? ? ? ? ? ? ? ? ? ?} >> ? ? ? ? ? ? ? ?} else { >> @@ -257,19 +345,19 @@ int i2c_transfer(unsigned char cmd_type, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &i2c->iicstat); >> ? ? ? ? ? ? ? ? ? ? ? ?i = 0; >> ? ? ? ? ? ? ? ? ? ? ? ?while ((i < data_len) && (result = I2C_OK)) { >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(i2c); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?writel(data[i], &i2c->iicds); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(i2c); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?i++; >> ? ? ? ? ? ? ? ? ? ? ? ?} >> ? ? ? ? ? ? ? ?} >> >> ? ? ? ? ? ? ? ?if (result == I2C_OK) >> - ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(); >> + ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(i2c); >> >> ? ? ? ? ? ? ? ?/* send STOP */ >> ? ? ? ? ? ? ? ?writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat); >> - ? ? ? ? ? ? ? ReadWriteByte(); >> + ? ? ? ? ? ? ? ReadWriteByte(i2c); >> ? ? ? ? ? ? ? ?break; >> >> ? ? ? ?case I2C_READ: >> @@ -279,13 +367,13 @@ int i2c_transfer(unsigned char cmd_type, >> ? ? ? ? ? ? ? ? ? ? ? ?/* send START */ >> ? ? ? ? ? ? ? ? ? ? ? ?writel(readl(&i2c->iicstat) | I2C_START_STOP, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &i2c->iicstat); >> - ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(); >> - ? ? ? ? ? ? ? ? ? ? ? if (IsACK()) { >> + ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(i2c); >> + ? ? ? ? ? ? ? ? ? ? ? if (IsACK(i2c)) { >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?i = 0; >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?while ((i < addr_len) && (result == I2C_OK)) { >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?writel(addr[i], &i2c->iicds); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(i2c); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(i2c); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?i++; >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} >> >> @@ -293,16 +381,17 @@ int i2c_transfer(unsigned char cmd_type, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* resend START */ >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?writel(I2C_MODE_MR | I2C_TXRX_ENA | >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? I2C_START_STOP, &i2c->iicstat); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(); >> + ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(i2c); >> + ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(i2c); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?i = 0; >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?while ((i < data_len) && (result == I2C_OK)) { >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* disable ACK for final READ */ >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (i == data_len - 1) >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?writel(readl(&i2c->iiccon) >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?& ~0x80, &i2c->iiccon); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? & ~I2CCON_ACKGEN, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &i2c->iiccon); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(i2c); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(i2c); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?data[i] = readl(&i2c->iicds); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?i++; >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} >> @@ -316,17 +405,18 @@ int i2c_transfer(unsigned char cmd_type, >> ? ? ? ? ? ? ? ? ? ? ? ?/* send START */ >> ? ? ? ? ? ? ? ? ? ? ? ?writel(readl(&i2c->iicstat) | I2C_START_STOP, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &i2c->iicstat); >> - ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(); >> + ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(i2c); >> >> - ? ? ? ? ? ? ? ? ? ? ? if (IsACK()) { >> + ? ? ? ? ? ? ? ? ? ? ? if (IsACK(i2c)) { >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?i = 0; >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?while ((i < data_len) && (result == I2C_OK)) { >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* disable ACK for final READ */ >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (i == data_len - 1) >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?writel(readl(&i2c->iiccon) & >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?~0x80, &i2c->iiccon); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(); >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ~I2CCON_ACKGEN, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &i2c->iiccon); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReadWriteByte(i2c); >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result = WaitForXfer(i2c); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?data[i] = readl(&i2c->iicds); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?i++; >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} >> @@ -337,22 +427,28 @@ int i2c_transfer(unsigned char cmd_type, >> >> ? ? ? ? ? ? ? ?/* send STOP */ >> ? ? ? ? ? ? ? ?writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat); >> - ? ? ? ? ? ? ? ReadWriteByte(); >> + ? ? ? ? ? ? ? ReadWriteByte(i2c); >> ? ? ? ? ? ? ? ?break; >> >> ? ? ? ?default: >> - ? ? ? ? ? ? ? printf("i2c_transfer: bad call\n"); >> + ? ? ? ? ? ? ? debug("i2c_transfer: bad call\n"); >> ? ? ? ? ? ? ? ?result = I2C_NOK; >> ? ? ? ? ? ? ? ?break; >> ? ? ? ?} >> >> - ? ? ? return (result); >> + ? ? ? return result; >> ?} >> >> ?int i2c_probe(uchar chip) >> ?{ >> + ? ? ? struct s3c24x0_i2c *i2c; >> ? ? ? ?uchar buf[1]; >> >> +#ifdef CONFIG_EXYNOS5 >> + ? ? ? i2c = get_base_i2c(g_current_bus); >> +#else >> + ? ? ? i2c = s3c24x0_get_base_i2c(); >> +#endif >> ? ? ? ?buf[0] = 0; >> >> ? ? ? ?/* >> @@ -360,16 +456,17 @@ int i2c_probe(uchar chip) >> ? ? ? ? * address was ed (i.e. there was a chip at that address which >> ? ? ? ? * drove the data line low). >> ? ? ? ? */ >> - ? ? ? return i2c_transfer(I2C_READ, chip << 1, 0, 0, buf, 1) != I2C_OK; >> + ? ? ? return i2c_transfer(i2c, I2C_READ, chip << 1, 0, 0, buf, 1) != I2C_OK; >> ?} >> >> ?int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) >> ?{ >> + ? ? ? struct s3c24x0_i2c *i2c; >> ? ? ? ?uchar xaddr[4]; >> ? ? ? ?int ret; >> >> ? ? ? ?if (alen > 4) { >> - ? ? ? ? ? ? ? printf("I2C read: addr len %d not supported\n", alen); >> + ? ? ? ? ? ? ? debug("I2C read: addr len %d not supported\n", alen); >> ? ? ? ? ? ? ? ?return 1; >> ? ? ? ?} >> >> @@ -396,10 +493,15 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) >> ? ? ? ? ? ? ? ?chip |= ((addr >> (alen * 8)) & >> ? ? ? ? ? ? ? ? ? ? ? ? CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); >> ?#endif >> - ? ? ? if ((ret = >> - ? ? ? ? ? ?i2c_transfer(I2C_READ, chip << 1, &xaddr[4 - alen], alen, >> - ? ? ? ? ? ? ? ? ? ? ? ? buffer, len)) != 0) { >> - ? ? ? ? ? ? ? printf("I2c read: failed %d\n", ret); >> +#ifdef CONFIG_EXYNOS5 >> + ? ? ? i2c = get_base_i2c(g_current_bus); >> +#else >> + ? ? ? i2c = s3c24x0_get_base_i2c(); >> +#endif >> + ? ? ? ret = i2c_transfer(i2c, I2C_READ, chip << 1, &xaddr[4 - alen], alen, >> + ? ? ? ? ? ? ? ? ? ? ? buffer, len); >> + ? ? ? if (ret != 0) { >> + ? ? ? ? ? ? ? debug("I2c read: failed %d\n", ret); >> ? ? ? ? ? ? ? ?return 1; >> ? ? ? ?} >> ? ? ? ?return 0; >> @@ -407,10 +509,11 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) >> >> ?int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) >> ?{ >> + ? ? ? struct s3c24x0_i2c *i2c; >> ? ? ? ?uchar xaddr[4]; >> >> ? ? ? ?if (alen > 4) { >> - ? ? ? ? ? ? ? printf("I2C write: addr len %d not supported\n", alen); >> + ? ? ? ? ? ? ? debug("I2C write: addr len %d not supported\n", alen); >> ? ? ? ? ? ? ? ?return 1; >> ? ? ? ?} >> >> @@ -436,8 +539,13 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) >> ? ? ? ? ? ? ? ?chip |= ((addr >> (alen * 8)) & >> ? ? ? ? ? ? ? ? ? ? ? ? CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); >> ?#endif >> +#ifdef CONFIG_EXYNOS5 >> + ? ? ? i2c = get_base_i2c(g_current_bus); >> +#else >> + ? ? ? i2c = s3c24x0_get_base_i2c(); >> +#endif >> ? ? ? ?return (i2c_transfer >> - ? ? ? ? ? ? ? (I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer, >> + ? ? ? ? ? ? ? (i2c, I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer, >> ? ? ? ? ? ? ? ? len) != 0); >> ?} >> ?#endif /* CONFIG_HARD_I2C */ >> diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h >> index d357a0a..57aafb1 100644 >> --- a/drivers/i2c/s3c24x0_i2c.h >> +++ b/drivers/i2c/s3c24x0_i2c.h >> @@ -23,6 +23,9 @@ >> ?#ifndef _S3C24X0_I2C_H >> ?#define _S3C24X0_I2C_H >> >> +/* I2C channels exynos5 has 8 i2c channel */ >> +#define I2C0 ? ? ? ? ? 0 >> + >> ?struct s3c24x0_i2c { >> ? ? ? ?u32 ? ? iiccon; >> ? ? ? ?u32 ? ? iicstat; >> -- >> 1.7.4.4 >> >> _______________________________________________ >> U-Boot mailing list >> U-Boot at lists.denx.de >> http://lists.denx.de/mailman/listinfo/u-boot > > Thanks. > > -- Regards Rajeshwari Shinde > - Joonyoung Shim > _______________________________________________ > U-Boot mailing list > U-Boot at lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot