168432c27SLei Wen /* 268432c27SLei Wen * (C) Copyright 2000 368432c27SLei Wen * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it 468432c27SLei Wen * 568432c27SLei Wen * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com> 668432c27SLei Wen * Marius Groeger <mgroeger@sysgo.de> 768432c27SLei Wen * 868432c27SLei Wen * (C) Copyright 2003 Pengutronix e.K. 968432c27SLei Wen * Robert Schwebel <r.schwebel@pengutronix.de> 1068432c27SLei Wen * 113df619ecSLei Wen * (C) Copyright 2011 Marvell Inc. 123df619ecSLei Wen * Lei Wen <leiwen@marvell.com> 133df619ecSLei Wen * 141a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 1568432c27SLei Wen * 1668432c27SLei Wen * Back ported to the 8xx platform (from the 8260 platform) by 1768432c27SLei Wen * Murray.Jensen@cmst.csiro.au, 27-Jan-01. 1868432c27SLei Wen */ 1968432c27SLei Wen 2068432c27SLei Wen #include <common.h> 210c0f719aSStefan Roese #include <dm.h> 2268432c27SLei Wen #include <i2c.h> 237b46ee52SStefan Roese #include <asm/io.h> 243df619ecSLei Wen #include "mv_i2c.h" 2568432c27SLei Wen 2668432c27SLei Wen /* All transfers are described by this data structure */ 27fffff726SSimon Glass struct mv_i2c_msg { 2868432c27SLei Wen u8 condition; 2968432c27SLei Wen u8 acknack; 3068432c27SLei Wen u8 direction; 3168432c27SLei Wen u8 data; 3268432c27SLei Wen }; 3368432c27SLei Wen 340c0f719aSStefan Roese #ifdef CONFIG_ARMADA_3700 350c0f719aSStefan Roese /* Armada 3700 has no padding between the registers */ 360c0f719aSStefan Roese struct mv_i2c { 370c0f719aSStefan Roese u32 ibmr; 380c0f719aSStefan Roese u32 idbr; 390c0f719aSStefan Roese u32 icr; 400c0f719aSStefan Roese u32 isr; 410c0f719aSStefan Roese u32 isar; 420c0f719aSStefan Roese }; 430c0f719aSStefan Roese #else 443df619ecSLei Wen struct mv_i2c { 453df619ecSLei Wen u32 ibmr; 463df619ecSLei Wen u32 pad0; 473df619ecSLei Wen u32 idbr; 483df619ecSLei Wen u32 pad1; 493df619ecSLei Wen u32 icr; 503df619ecSLei Wen u32 pad2; 513df619ecSLei Wen u32 isr; 523df619ecSLei Wen u32 pad3; 533df619ecSLei Wen u32 isar; 543df619ecSLei Wen }; 550c0f719aSStefan Roese #endif 560c0f719aSStefan Roese 570c0f719aSStefan Roese /* 580c0f719aSStefan Roese * Dummy implementation that can be overwritten by a board 590c0f719aSStefan Roese * specific function 600c0f719aSStefan Roese */ 610c0f719aSStefan Roese __weak void i2c_clk_enable(void) 620c0f719aSStefan Roese { 630c0f719aSStefan Roese } 643df619ecSLei Wen 6568432c27SLei Wen /* 663df619ecSLei Wen * i2c_reset: - reset the host controller 6768432c27SLei Wen * 6868432c27SLei Wen */ 697b46ee52SStefan Roese static void i2c_reset(struct mv_i2c *base) 7068432c27SLei Wen { 719ad5a007SStefan Roese u32 icr_mode; 729ad5a007SStefan Roese 739ad5a007SStefan Roese /* Save bus mode (standard or fast speed) for later use */ 749ad5a007SStefan Roese icr_mode = readl(&base->icr) & ICR_MODE_MASK; 753df619ecSLei Wen writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */ 763df619ecSLei Wen writel(readl(&base->icr) | ICR_UR, &base->icr); /* reset the unit */ 7768432c27SLei Wen udelay(100); 783df619ecSLei Wen writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */ 793df619ecSLei Wen 803df619ecSLei Wen i2c_clk_enable(); 813df619ecSLei Wen 823df619ecSLei Wen writel(CONFIG_SYS_I2C_SLAVE, &base->isar); /* set our slave address */ 839ad5a007SStefan Roese /* set control reg values */ 849ad5a007SStefan Roese writel(I2C_ICR_INIT | icr_mode, &base->icr); 853df619ecSLei Wen writel(I2C_ISR_INIT, &base->isr); /* set clear interrupt bits */ 863df619ecSLei Wen writel(readl(&base->icr) | ICR_IUE, &base->icr); /* enable unit */ 8768432c27SLei Wen udelay(100); 8868432c27SLei Wen } 8968432c27SLei Wen 9068432c27SLei Wen /* 9168432c27SLei Wen * i2c_isr_set_cleared: - wait until certain bits of the I2C status register 9268432c27SLei Wen * are set and cleared 9368432c27SLei Wen * 9468432c27SLei Wen * @return: 1 in case of success, 0 means timeout (no match within 10 ms). 9568432c27SLei Wen */ 967b46ee52SStefan Roese static int i2c_isr_set_cleared(struct mv_i2c *base, unsigned long set_mask, 9768432c27SLei Wen unsigned long cleared_mask) 9868432c27SLei Wen { 993df619ecSLei Wen int timeout = 1000, isr; 10068432c27SLei Wen 1013df619ecSLei Wen do { 1023df619ecSLei Wen isr = readl(&base->isr); 10368432c27SLei Wen udelay(10); 10468432c27SLei Wen if (timeout-- < 0) 10568432c27SLei Wen return 0; 1063df619ecSLei Wen } while (((isr & set_mask) != set_mask) 1073df619ecSLei Wen || ((isr & cleared_mask) != 0)); 10868432c27SLei Wen 10968432c27SLei Wen return 1; 11068432c27SLei Wen } 11168432c27SLei Wen 11268432c27SLei Wen /* 11368432c27SLei Wen * i2c_transfer: - Transfer one byte over the i2c bus 11468432c27SLei Wen * 11568432c27SLei Wen * This function can tranfer a byte over the i2c bus in both directions. 11668432c27SLei Wen * It is used by the public API functions. 11768432c27SLei Wen * 11868432c27SLei Wen * @return: 0: transfer successful 11968432c27SLei Wen * -1: message is empty 12068432c27SLei Wen * -2: transmit timeout 12168432c27SLei Wen * -3: ACK missing 12268432c27SLei Wen * -4: receive timeout 12368432c27SLei Wen * -5: illegal parameters 12468432c27SLei Wen * -6: bus is busy and couldn't be aquired 12568432c27SLei Wen */ 1267b46ee52SStefan Roese static int i2c_transfer(struct mv_i2c *base, struct mv_i2c_msg *msg) 12768432c27SLei Wen { 12868432c27SLei Wen int ret; 12968432c27SLei Wen 13068432c27SLei Wen if (!msg) 13168432c27SLei Wen goto transfer_error_msg_empty; 13268432c27SLei Wen 13368432c27SLei Wen switch (msg->direction) { 13468432c27SLei Wen case I2C_WRITE: 13568432c27SLei Wen /* check if bus is not busy */ 1367b46ee52SStefan Roese if (!i2c_isr_set_cleared(base, 0, ISR_IBB)) 13768432c27SLei Wen goto transfer_error_bus_busy; 13868432c27SLei Wen 13968432c27SLei Wen /* start transmission */ 1403df619ecSLei Wen writel(readl(&base->icr) & ~ICR_START, &base->icr); 1413df619ecSLei Wen writel(readl(&base->icr) & ~ICR_STOP, &base->icr); 1423df619ecSLei Wen writel(msg->data, &base->idbr); 14368432c27SLei Wen if (msg->condition == I2C_COND_START) 1443df619ecSLei Wen writel(readl(&base->icr) | ICR_START, &base->icr); 14568432c27SLei Wen if (msg->condition == I2C_COND_STOP) 1463df619ecSLei Wen writel(readl(&base->icr) | ICR_STOP, &base->icr); 14768432c27SLei Wen if (msg->acknack == I2C_ACKNAK_SENDNAK) 1483df619ecSLei Wen writel(readl(&base->icr) | ICR_ACKNAK, &base->icr); 14968432c27SLei Wen if (msg->acknack == I2C_ACKNAK_SENDACK) 1503df619ecSLei Wen writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr); 1513df619ecSLei Wen writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr); 1523df619ecSLei Wen writel(readl(&base->icr) | ICR_TB, &base->icr); 15368432c27SLei Wen 15468432c27SLei Wen /* transmit register empty? */ 1557b46ee52SStefan Roese if (!i2c_isr_set_cleared(base, ISR_ITE, 0)) 15668432c27SLei Wen goto transfer_error_transmit_timeout; 15768432c27SLei Wen 15868432c27SLei Wen /* clear 'transmit empty' state */ 1593df619ecSLei Wen writel(readl(&base->isr) | ISR_ITE, &base->isr); 16068432c27SLei Wen 16168432c27SLei Wen /* wait for ACK from slave */ 16268432c27SLei Wen if (msg->acknack == I2C_ACKNAK_WAITACK) 1637b46ee52SStefan Roese if (!i2c_isr_set_cleared(base, 0, ISR_ACKNAK)) 16468432c27SLei Wen goto transfer_error_ack_missing; 16568432c27SLei Wen break; 16668432c27SLei Wen 16768432c27SLei Wen case I2C_READ: 16868432c27SLei Wen 16968432c27SLei Wen /* check if bus is not busy */ 1707b46ee52SStefan Roese if (!i2c_isr_set_cleared(base, 0, ISR_IBB)) 17168432c27SLei Wen goto transfer_error_bus_busy; 17268432c27SLei Wen 17368432c27SLei Wen /* start receive */ 1743df619ecSLei Wen writel(readl(&base->icr) & ~ICR_START, &base->icr); 1753df619ecSLei Wen writel(readl(&base->icr) & ~ICR_STOP, &base->icr); 17668432c27SLei Wen if (msg->condition == I2C_COND_START) 1773df619ecSLei Wen writel(readl(&base->icr) | ICR_START, &base->icr); 17868432c27SLei Wen if (msg->condition == I2C_COND_STOP) 1793df619ecSLei Wen writel(readl(&base->icr) | ICR_STOP, &base->icr); 18068432c27SLei Wen if (msg->acknack == I2C_ACKNAK_SENDNAK) 1813df619ecSLei Wen writel(readl(&base->icr) | ICR_ACKNAK, &base->icr); 18268432c27SLei Wen if (msg->acknack == I2C_ACKNAK_SENDACK) 1833df619ecSLei Wen writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr); 1843df619ecSLei Wen writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr); 1853df619ecSLei Wen writel(readl(&base->icr) | ICR_TB, &base->icr); 18668432c27SLei Wen 18768432c27SLei Wen /* receive register full? */ 1887b46ee52SStefan Roese if (!i2c_isr_set_cleared(base, ISR_IRF, 0)) 18968432c27SLei Wen goto transfer_error_receive_timeout; 19068432c27SLei Wen 1913df619ecSLei Wen msg->data = readl(&base->idbr); 19268432c27SLei Wen 19368432c27SLei Wen /* clear 'receive empty' state */ 1943df619ecSLei Wen writel(readl(&base->isr) | ISR_IRF, &base->isr); 19568432c27SLei Wen break; 19668432c27SLei Wen default: 19768432c27SLei Wen goto transfer_error_illegal_param; 19868432c27SLei Wen } 19968432c27SLei Wen 20068432c27SLei Wen return 0; 20168432c27SLei Wen 20268432c27SLei Wen transfer_error_msg_empty: 2038eff909aSStefan Roese debug("i2c_transfer: error: 'msg' is empty\n"); 2048eff909aSStefan Roese ret = -1; 2058eff909aSStefan Roese goto i2c_transfer_finish; 20668432c27SLei Wen 20768432c27SLei Wen transfer_error_transmit_timeout: 2088eff909aSStefan Roese debug("i2c_transfer: error: transmit timeout\n"); 2098eff909aSStefan Roese ret = -2; 2108eff909aSStefan Roese goto i2c_transfer_finish; 21168432c27SLei Wen 21268432c27SLei Wen transfer_error_ack_missing: 2138eff909aSStefan Roese debug("i2c_transfer: error: ACK missing\n"); 2148eff909aSStefan Roese ret = -3; 2158eff909aSStefan Roese goto i2c_transfer_finish; 21668432c27SLei Wen 21768432c27SLei Wen transfer_error_receive_timeout: 2188eff909aSStefan Roese debug("i2c_transfer: error: receive timeout\n"); 2198eff909aSStefan Roese ret = -4; 2208eff909aSStefan Roese goto i2c_transfer_finish; 22168432c27SLei Wen 22268432c27SLei Wen transfer_error_illegal_param: 2238eff909aSStefan Roese debug("i2c_transfer: error: illegal parameters\n"); 2248eff909aSStefan Roese ret = -5; 2258eff909aSStefan Roese goto i2c_transfer_finish; 22668432c27SLei Wen 22768432c27SLei Wen transfer_error_bus_busy: 2288eff909aSStefan Roese debug("i2c_transfer: error: bus is busy\n"); 2298eff909aSStefan Roese ret = -6; 2308eff909aSStefan Roese goto i2c_transfer_finish; 23168432c27SLei Wen 23268432c27SLei Wen i2c_transfer_finish: 2338eff909aSStefan Roese debug("i2c_transfer: ISR: 0x%04x\n", readl(&base->isr)); 2347b46ee52SStefan Roese i2c_reset(base); 23568432c27SLei Wen return ret; 23668432c27SLei Wen } 23768432c27SLei Wen 2380c0f719aSStefan Roese static int __i2c_read(struct mv_i2c *base, uchar chip, u8 *addr, int alen, 2397b46ee52SStefan Roese uchar *buffer, int len) 24068432c27SLei Wen { 241fffff726SSimon Glass struct mv_i2c_msg msg; 24268432c27SLei Wen 2438eff909aSStefan Roese debug("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, " 2440c0f719aSStefan Roese "len=0x%02x)\n", chip, *addr, alen, len); 24568432c27SLei Wen 246*85f03f0eSjinghua if (len == 0) { 247*85f03f0eSjinghua printf("reading zero byte is invalid\n"); 248*85f03f0eSjinghua return -EINVAL; 249*85f03f0eSjinghua } 250*85f03f0eSjinghua 2517b46ee52SStefan Roese i2c_reset(base); 25268432c27SLei Wen 25368432c27SLei Wen /* dummy chip address write */ 2548eff909aSStefan Roese debug("i2c_read: dummy chip address write\n"); 25568432c27SLei Wen msg.condition = I2C_COND_START; 25668432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 25768432c27SLei Wen msg.direction = I2C_WRITE; 25868432c27SLei Wen msg.data = (chip << 1); 25968432c27SLei Wen msg.data &= 0xFE; 2607b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 26168432c27SLei Wen return -1; 26268432c27SLei Wen 26368432c27SLei Wen /* 26468432c27SLei Wen * send memory address bytes; 26568432c27SLei Wen * alen defines how much bytes we have to send. 26668432c27SLei Wen */ 26768432c27SLei Wen while (--alen >= 0) { 2680c0f719aSStefan Roese debug("i2c_read: send address byte %02x (alen=%d)\n", 2690c0f719aSStefan Roese *addr, alen); 27068432c27SLei Wen msg.condition = I2C_COND_NORMAL; 27168432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 27268432c27SLei Wen msg.direction = I2C_WRITE; 2730c0f719aSStefan Roese msg.data = *(addr++); 2747b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 27568432c27SLei Wen return -1; 27668432c27SLei Wen } 27768432c27SLei Wen 27868432c27SLei Wen /* start read sequence */ 2798eff909aSStefan Roese debug("i2c_read: start read sequence\n"); 28068432c27SLei Wen msg.condition = I2C_COND_START; 28168432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 28268432c27SLei Wen msg.direction = I2C_WRITE; 28368432c27SLei Wen msg.data = (chip << 1); 28468432c27SLei Wen msg.data |= 0x01; 2857b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 28668432c27SLei Wen return -1; 28768432c27SLei Wen 28868432c27SLei Wen /* read bytes; send NACK at last byte */ 28968432c27SLei Wen while (len--) { 29068432c27SLei Wen if (len == 0) { 29168432c27SLei Wen msg.condition = I2C_COND_STOP; 29268432c27SLei Wen msg.acknack = I2C_ACKNAK_SENDNAK; 29368432c27SLei Wen } else { 29468432c27SLei Wen msg.condition = I2C_COND_NORMAL; 29568432c27SLei Wen msg.acknack = I2C_ACKNAK_SENDACK; 29668432c27SLei Wen } 29768432c27SLei Wen 29868432c27SLei Wen msg.direction = I2C_READ; 29968432c27SLei Wen msg.data = 0x00; 3007b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 30168432c27SLei Wen return -1; 30268432c27SLei Wen 30368432c27SLei Wen *buffer = msg.data; 3040c0f719aSStefan Roese debug("i2c_read: reading byte (%p)=0x%02x\n", 3050c0f719aSStefan Roese buffer, *buffer); 30668432c27SLei Wen buffer++; 30768432c27SLei Wen } 30868432c27SLei Wen 3097b46ee52SStefan Roese i2c_reset(base); 31068432c27SLei Wen 31168432c27SLei Wen return 0; 31268432c27SLei Wen } 31368432c27SLei Wen 3140c0f719aSStefan Roese static int __i2c_write(struct mv_i2c *base, uchar chip, u8 *addr, int alen, 3157b46ee52SStefan Roese uchar *buffer, int len) 31668432c27SLei Wen { 317fffff726SSimon Glass struct mv_i2c_msg msg; 31868432c27SLei Wen 3198eff909aSStefan Roese debug("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, " 3200c0f719aSStefan Roese "len=0x%02x)\n", chip, *addr, alen, len); 32168432c27SLei Wen 3227b46ee52SStefan Roese i2c_reset(base); 32368432c27SLei Wen 32468432c27SLei Wen /* chip address write */ 3258eff909aSStefan Roese debug("i2c_write: chip address write\n"); 32668432c27SLei Wen msg.condition = I2C_COND_START; 32768432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 32868432c27SLei Wen msg.direction = I2C_WRITE; 32968432c27SLei Wen msg.data = (chip << 1); 33068432c27SLei Wen msg.data &= 0xFE; 3317b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 33268432c27SLei Wen return -1; 33368432c27SLei Wen 33468432c27SLei Wen /* 33568432c27SLei Wen * send memory address bytes; 33668432c27SLei Wen * alen defines how much bytes we have to send. 33768432c27SLei Wen */ 33868432c27SLei Wen while (--alen >= 0) { 3390c0f719aSStefan Roese debug("i2c_read: send address byte %02x (alen=%d)\n", 3400c0f719aSStefan Roese *addr, alen); 34168432c27SLei Wen msg.condition = I2C_COND_NORMAL; 34268432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 34368432c27SLei Wen msg.direction = I2C_WRITE; 3440c0f719aSStefan Roese msg.data = *(addr++); 3457b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 34668432c27SLei Wen return -1; 34768432c27SLei Wen } 34868432c27SLei Wen 34968432c27SLei Wen /* write bytes; send NACK at last byte */ 35068432c27SLei Wen while (len--) { 3510c0f719aSStefan Roese debug("i2c_write: writing byte (%p)=0x%02x\n", 3520c0f719aSStefan Roese buffer, *buffer); 35368432c27SLei Wen 35468432c27SLei Wen if (len == 0) 35568432c27SLei Wen msg.condition = I2C_COND_STOP; 35668432c27SLei Wen else 35768432c27SLei Wen msg.condition = I2C_COND_NORMAL; 35868432c27SLei Wen 35968432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 36068432c27SLei Wen msg.direction = I2C_WRITE; 36168432c27SLei Wen msg.data = *(buffer++); 36268432c27SLei Wen 3637b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 36468432c27SLei Wen return -1; 36568432c27SLei Wen } 36668432c27SLei Wen 3677b46ee52SStefan Roese i2c_reset(base); 36868432c27SLei Wen 36968432c27SLei Wen return 0; 37068432c27SLei Wen } 3717b46ee52SStefan Roese 3720c0f719aSStefan Roese #ifndef CONFIG_DM_I2C 3730c0f719aSStefan Roese 3747b46ee52SStefan Roese static struct mv_i2c *base_glob; 3757b46ee52SStefan Roese 3767b46ee52SStefan Roese static void i2c_board_init(struct mv_i2c *base) 3777b46ee52SStefan Roese { 3787b46ee52SStefan Roese #ifdef CONFIG_SYS_I2C_INIT_BOARD 3797b46ee52SStefan Roese u32 icr; 3807b46ee52SStefan Roese /* 3817b46ee52SStefan Roese * call board specific i2c bus reset routine before accessing the 3827b46ee52SStefan Roese * environment, which might be in a chip on that bus. For details 3837b46ee52SStefan Roese * about this problem see doc/I2C_Edge_Conditions. 3847b46ee52SStefan Roese * 3857b46ee52SStefan Roese * disable I2C controller first, otherwhise it thinks we want to 3867b46ee52SStefan Roese * talk to the slave port... 3877b46ee52SStefan Roese */ 3887b46ee52SStefan Roese icr = readl(&base->icr); 3897b46ee52SStefan Roese writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr); 3907b46ee52SStefan Roese 3917b46ee52SStefan Roese i2c_init_board(); 3927b46ee52SStefan Roese 3937b46ee52SStefan Roese writel(icr, &base->icr); 3947b46ee52SStefan Roese #endif 3957b46ee52SStefan Roese } 3967b46ee52SStefan Roese 3977b46ee52SStefan Roese #ifdef CONFIG_I2C_MULTI_BUS 3987b46ee52SStefan Roese static unsigned long i2c_regs[CONFIG_MV_I2C_NUM] = CONFIG_MV_I2C_REG; 3997b46ee52SStefan Roese static unsigned int bus_initialized[CONFIG_MV_I2C_NUM]; 4007b46ee52SStefan Roese static unsigned int current_bus; 4017b46ee52SStefan Roese 4027b46ee52SStefan Roese int i2c_set_bus_num(unsigned int bus) 4037b46ee52SStefan Roese { 4047b46ee52SStefan Roese if ((bus < 0) || (bus >= CONFIG_MV_I2C_NUM)) { 4057b46ee52SStefan Roese printf("Bad bus: %d\n", bus); 4067b46ee52SStefan Roese return -1; 4077b46ee52SStefan Roese } 4087b46ee52SStefan Roese 4097b46ee52SStefan Roese base_glob = (struct mv_i2c *)i2c_regs[bus]; 4107b46ee52SStefan Roese current_bus = bus; 4117b46ee52SStefan Roese 4127b46ee52SStefan Roese if (!bus_initialized[current_bus]) { 4137b46ee52SStefan Roese i2c_board_init(base_glob); 4147b46ee52SStefan Roese bus_initialized[current_bus] = 1; 4157b46ee52SStefan Roese } 4167b46ee52SStefan Roese 4177b46ee52SStefan Roese return 0; 4187b46ee52SStefan Roese } 4197b46ee52SStefan Roese 4207b46ee52SStefan Roese unsigned int i2c_get_bus_num(void) 4217b46ee52SStefan Roese { 4227b46ee52SStefan Roese return current_bus; 4237b46ee52SStefan Roese } 4247b46ee52SStefan Roese #endif 4257b46ee52SStefan Roese 4267b46ee52SStefan Roese /* API Functions */ 4277b46ee52SStefan Roese void i2c_init(int speed, int slaveaddr) 4287b46ee52SStefan Roese { 4299ad5a007SStefan Roese u32 val; 4309ad5a007SStefan Roese 4317b46ee52SStefan Roese #ifdef CONFIG_I2C_MULTI_BUS 4327b46ee52SStefan Roese current_bus = 0; 4337b46ee52SStefan Roese base_glob = (struct mv_i2c *)i2c_regs[current_bus]; 4347b46ee52SStefan Roese #else 4357b46ee52SStefan Roese base_glob = (struct mv_i2c *)CONFIG_MV_I2C_REG; 4367b46ee52SStefan Roese #endif 4377b46ee52SStefan Roese 4389ad5a007SStefan Roese if (speed > 100000) 4399ad5a007SStefan Roese val = ICR_FM; 4409ad5a007SStefan Roese else 4419ad5a007SStefan Roese val = ICR_SM; 4429ad5a007SStefan Roese clrsetbits_le32(&base_glob->icr, ICR_MODE_MASK, val); 4439ad5a007SStefan Roese 4447b46ee52SStefan Roese i2c_board_init(base_glob); 4457b46ee52SStefan Roese } 4467b46ee52SStefan Roese 4470c0f719aSStefan Roese static int __i2c_probe_chip(struct mv_i2c *base, uchar chip) 4480c0f719aSStefan Roese { 4490c0f719aSStefan Roese struct mv_i2c_msg msg; 4500c0f719aSStefan Roese 4510c0f719aSStefan Roese i2c_reset(base); 4520c0f719aSStefan Roese 4530c0f719aSStefan Roese msg.condition = I2C_COND_START; 4540c0f719aSStefan Roese msg.acknack = I2C_ACKNAK_WAITACK; 4550c0f719aSStefan Roese msg.direction = I2C_WRITE; 4560c0f719aSStefan Roese msg.data = (chip << 1) + 1; 4570c0f719aSStefan Roese if (i2c_transfer(base, &msg)) 4580c0f719aSStefan Roese return -1; 4590c0f719aSStefan Roese 4600c0f719aSStefan Roese msg.condition = I2C_COND_STOP; 4610c0f719aSStefan Roese msg.acknack = I2C_ACKNAK_SENDNAK; 4620c0f719aSStefan Roese msg.direction = I2C_READ; 4630c0f719aSStefan Roese msg.data = 0x00; 4640c0f719aSStefan Roese if (i2c_transfer(base, &msg)) 4650c0f719aSStefan Roese return -1; 4660c0f719aSStefan Roese 4670c0f719aSStefan Roese return 0; 4680c0f719aSStefan Roese } 4690c0f719aSStefan Roese 4707b46ee52SStefan Roese /* 4717b46ee52SStefan Roese * i2c_probe: - Test if a chip answers for a given i2c address 4727b46ee52SStefan Roese * 4737b46ee52SStefan Roese * @chip: address of the chip which is searched for 4747b46ee52SStefan Roese * @return: 0 if a chip was found, -1 otherwhise 4757b46ee52SStefan Roese */ 4767b46ee52SStefan Roese int i2c_probe(uchar chip) 4777b46ee52SStefan Roese { 4787b46ee52SStefan Roese return __i2c_probe_chip(base_glob, chip); 4797b46ee52SStefan Roese } 4807b46ee52SStefan Roese 4817b46ee52SStefan Roese /* 4827b46ee52SStefan Roese * i2c_read: - Read multiple bytes from an i2c device 4837b46ee52SStefan Roese * 4847b46ee52SStefan Roese * The higher level routines take into account that this function is only 4857b46ee52SStefan Roese * called with len < page length of the device (see configuration file) 4867b46ee52SStefan Roese * 4877b46ee52SStefan Roese * @chip: address of the chip which is to be read 4887b46ee52SStefan Roese * @addr: i2c data address within the chip 4897b46ee52SStefan Roese * @alen: length of the i2c data address (1..2 bytes) 4907b46ee52SStefan Roese * @buffer: where to write the data 4917b46ee52SStefan Roese * @len: how much byte do we want to read 4927b46ee52SStefan Roese * @return: 0 in case of success 4937b46ee52SStefan Roese */ 4947b46ee52SStefan Roese int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) 4957b46ee52SStefan Roese { 4960c0f719aSStefan Roese u8 addr_bytes[4]; 4970c0f719aSStefan Roese 4980c0f719aSStefan Roese addr_bytes[0] = (addr >> 0) & 0xFF; 4990c0f719aSStefan Roese addr_bytes[1] = (addr >> 8) & 0xFF; 5000c0f719aSStefan Roese addr_bytes[2] = (addr >> 16) & 0xFF; 5010c0f719aSStefan Roese addr_bytes[3] = (addr >> 24) & 0xFF; 5020c0f719aSStefan Roese 5030c0f719aSStefan Roese return __i2c_read(base_glob, chip, addr_bytes, alen, buffer, len); 5047b46ee52SStefan Roese } 5057b46ee52SStefan Roese 5067b46ee52SStefan Roese /* 5077b46ee52SStefan Roese * i2c_write: - Write multiple bytes to an i2c device 5087b46ee52SStefan Roese * 5097b46ee52SStefan Roese * The higher level routines take into account that this function is only 5107b46ee52SStefan Roese * called with len < page length of the device (see configuration file) 5117b46ee52SStefan Roese * 5127b46ee52SStefan Roese * @chip: address of the chip which is to be written 5137b46ee52SStefan Roese * @addr: i2c data address within the chip 5147b46ee52SStefan Roese * @alen: length of the i2c data address (1..2 bytes) 5157b46ee52SStefan Roese * @buffer: where to find the data to be written 5167b46ee52SStefan Roese * @len: how much byte do we want to read 5177b46ee52SStefan Roese * @return: 0 in case of success 5187b46ee52SStefan Roese */ 5197b46ee52SStefan Roese int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) 5207b46ee52SStefan Roese { 5210c0f719aSStefan Roese u8 addr_bytes[4]; 5220c0f719aSStefan Roese 5230c0f719aSStefan Roese addr_bytes[0] = (addr >> 0) & 0xFF; 5240c0f719aSStefan Roese addr_bytes[1] = (addr >> 8) & 0xFF; 5250c0f719aSStefan Roese addr_bytes[2] = (addr >> 16) & 0xFF; 5260c0f719aSStefan Roese addr_bytes[3] = (addr >> 24) & 0xFF; 5270c0f719aSStefan Roese 5280c0f719aSStefan Roese return __i2c_write(base_glob, chip, addr_bytes, alen, buffer, len); 5297b46ee52SStefan Roese } 5300c0f719aSStefan Roese 5310c0f719aSStefan Roese #else /* CONFIG_DM_I2C */ 5320c0f719aSStefan Roese 5330c0f719aSStefan Roese struct mv_i2c_priv { 5340c0f719aSStefan Roese struct mv_i2c *base; 5350c0f719aSStefan Roese }; 5360c0f719aSStefan Roese 5370c0f719aSStefan Roese static int mv_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) 5380c0f719aSStefan Roese { 5390c0f719aSStefan Roese struct mv_i2c_priv *i2c = dev_get_priv(bus); 5400c0f719aSStefan Roese struct i2c_msg *dmsg, *omsg, dummy; 5410c0f719aSStefan Roese 5420c0f719aSStefan Roese memset(&dummy, 0, sizeof(struct i2c_msg)); 5430c0f719aSStefan Roese 5440c0f719aSStefan Roese /* 5450c0f719aSStefan Roese * We expect either two messages (one with an offset and one with the 5460c0f719aSStefan Roese * actual data) or one message (just data or offset/data combined) 5470c0f719aSStefan Roese */ 5480c0f719aSStefan Roese if (nmsgs > 2 || nmsgs == 0) { 5490c0f719aSStefan Roese debug("%s: Only one or two messages are supported.", __func__); 5500c0f719aSStefan Roese return -1; 5510c0f719aSStefan Roese } 5520c0f719aSStefan Roese 5530c0f719aSStefan Roese omsg = nmsgs == 1 ? &dummy : msg; 5540c0f719aSStefan Roese dmsg = nmsgs == 1 ? msg : msg + 1; 5550c0f719aSStefan Roese 5560c0f719aSStefan Roese if (dmsg->flags & I2C_M_RD) 5570c0f719aSStefan Roese return __i2c_read(i2c->base, dmsg->addr, omsg->buf, 5580c0f719aSStefan Roese omsg->len, dmsg->buf, dmsg->len); 5590c0f719aSStefan Roese else 5600c0f719aSStefan Roese return __i2c_write(i2c->base, dmsg->addr, omsg->buf, 5610c0f719aSStefan Roese omsg->len, dmsg->buf, dmsg->len); 5620c0f719aSStefan Roese } 5630c0f719aSStefan Roese 5649ad5a007SStefan Roese static int mv_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) 5659ad5a007SStefan Roese { 5669ad5a007SStefan Roese struct mv_i2c_priv *priv = dev_get_priv(bus); 5679ad5a007SStefan Roese u32 val; 5689ad5a007SStefan Roese 5699ad5a007SStefan Roese if (speed > 100000) 5709ad5a007SStefan Roese val = ICR_FM; 5719ad5a007SStefan Roese else 5729ad5a007SStefan Roese val = ICR_SM; 5739ad5a007SStefan Roese clrsetbits_le32(&priv->base->icr, ICR_MODE_MASK, val); 5749ad5a007SStefan Roese 5759ad5a007SStefan Roese return 0; 5769ad5a007SStefan Roese } 5779ad5a007SStefan Roese 5780c0f719aSStefan Roese static int mv_i2c_probe(struct udevice *bus) 5790c0f719aSStefan Roese { 5800c0f719aSStefan Roese struct mv_i2c_priv *priv = dev_get_priv(bus); 5810c0f719aSStefan Roese 5820c0f719aSStefan Roese priv->base = (void *)dev_get_addr_ptr(bus); 5830c0f719aSStefan Roese 5840c0f719aSStefan Roese return 0; 5850c0f719aSStefan Roese } 5860c0f719aSStefan Roese 5870c0f719aSStefan Roese static const struct dm_i2c_ops mv_i2c_ops = { 5880c0f719aSStefan Roese .xfer = mv_i2c_xfer, 5899ad5a007SStefan Roese .set_bus_speed = mv_i2c_set_bus_speed, 5900c0f719aSStefan Roese }; 5910c0f719aSStefan Roese 5920c0f719aSStefan Roese static const struct udevice_id mv_i2c_ids[] = { 5930c0f719aSStefan Roese { .compatible = "marvell,armada-3700-i2c" }, 5940c0f719aSStefan Roese { } 5950c0f719aSStefan Roese }; 5960c0f719aSStefan Roese 5970c0f719aSStefan Roese U_BOOT_DRIVER(i2c_mv) = { 5980c0f719aSStefan Roese .name = "i2c_mv", 5990c0f719aSStefan Roese .id = UCLASS_I2C, 6000c0f719aSStefan Roese .of_match = mv_i2c_ids, 6010c0f719aSStefan Roese .probe = mv_i2c_probe, 6020c0f719aSStefan Roese .priv_auto_alloc_size = sizeof(struct mv_i2c_priv), 6030c0f719aSStefan Roese .ops = &mv_i2c_ops, 6040c0f719aSStefan Roese }; 6050c0f719aSStefan Roese #endif /* CONFIG_DM_I2C */ 606