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> 21*0c0f719aSStefan 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 34*0c0f719aSStefan Roese #ifdef CONFIG_ARMADA_3700 35*0c0f719aSStefan Roese /* Armada 3700 has no padding between the registers */ 36*0c0f719aSStefan Roese struct mv_i2c { 37*0c0f719aSStefan Roese u32 ibmr; 38*0c0f719aSStefan Roese u32 idbr; 39*0c0f719aSStefan Roese u32 icr; 40*0c0f719aSStefan Roese u32 isr; 41*0c0f719aSStefan Roese u32 isar; 42*0c0f719aSStefan Roese }; 43*0c0f719aSStefan 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 }; 55*0c0f719aSStefan Roese #endif 56*0c0f719aSStefan Roese 57*0c0f719aSStefan Roese /* 58*0c0f719aSStefan Roese * Dummy implementation that can be overwritten by a board 59*0c0f719aSStefan Roese * specific function 60*0c0f719aSStefan Roese */ 61*0c0f719aSStefan Roese __weak void i2c_clk_enable(void) 62*0c0f719aSStefan Roese { 63*0c0f719aSStefan 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 { 713df619ecSLei Wen writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */ 723df619ecSLei Wen writel(readl(&base->icr) | ICR_UR, &base->icr); /* reset the unit */ 7368432c27SLei Wen udelay(100); 743df619ecSLei Wen writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */ 753df619ecSLei Wen 763df619ecSLei Wen i2c_clk_enable(); 773df619ecSLei Wen 783df619ecSLei Wen writel(CONFIG_SYS_I2C_SLAVE, &base->isar); /* set our slave address */ 793df619ecSLei Wen writel(I2C_ICR_INIT, &base->icr); /* set control reg values */ 803df619ecSLei Wen writel(I2C_ISR_INIT, &base->isr); /* set clear interrupt bits */ 813df619ecSLei Wen writel(readl(&base->icr) | ICR_IUE, &base->icr); /* enable unit */ 8268432c27SLei Wen udelay(100); 8368432c27SLei Wen } 8468432c27SLei Wen 8568432c27SLei Wen /* 8668432c27SLei Wen * i2c_isr_set_cleared: - wait until certain bits of the I2C status register 8768432c27SLei Wen * are set and cleared 8868432c27SLei Wen * 8968432c27SLei Wen * @return: 1 in case of success, 0 means timeout (no match within 10 ms). 9068432c27SLei Wen */ 917b46ee52SStefan Roese static int i2c_isr_set_cleared(struct mv_i2c *base, unsigned long set_mask, 9268432c27SLei Wen unsigned long cleared_mask) 9368432c27SLei Wen { 943df619ecSLei Wen int timeout = 1000, isr; 9568432c27SLei Wen 963df619ecSLei Wen do { 973df619ecSLei Wen isr = readl(&base->isr); 9868432c27SLei Wen udelay(10); 9968432c27SLei Wen if (timeout-- < 0) 10068432c27SLei Wen return 0; 1013df619ecSLei Wen } while (((isr & set_mask) != set_mask) 1023df619ecSLei Wen || ((isr & cleared_mask) != 0)); 10368432c27SLei Wen 10468432c27SLei Wen return 1; 10568432c27SLei Wen } 10668432c27SLei Wen 10768432c27SLei Wen /* 10868432c27SLei Wen * i2c_transfer: - Transfer one byte over the i2c bus 10968432c27SLei Wen * 11068432c27SLei Wen * This function can tranfer a byte over the i2c bus in both directions. 11168432c27SLei Wen * It is used by the public API functions. 11268432c27SLei Wen * 11368432c27SLei Wen * @return: 0: transfer successful 11468432c27SLei Wen * -1: message is empty 11568432c27SLei Wen * -2: transmit timeout 11668432c27SLei Wen * -3: ACK missing 11768432c27SLei Wen * -4: receive timeout 11868432c27SLei Wen * -5: illegal parameters 11968432c27SLei Wen * -6: bus is busy and couldn't be aquired 12068432c27SLei Wen */ 1217b46ee52SStefan Roese static int i2c_transfer(struct mv_i2c *base, struct mv_i2c_msg *msg) 12268432c27SLei Wen { 12368432c27SLei Wen int ret; 12468432c27SLei Wen 12568432c27SLei Wen if (!msg) 12668432c27SLei Wen goto transfer_error_msg_empty; 12768432c27SLei Wen 12868432c27SLei Wen switch (msg->direction) { 12968432c27SLei Wen case I2C_WRITE: 13068432c27SLei Wen /* check if bus is not busy */ 1317b46ee52SStefan Roese if (!i2c_isr_set_cleared(base, 0, ISR_IBB)) 13268432c27SLei Wen goto transfer_error_bus_busy; 13368432c27SLei Wen 13468432c27SLei Wen /* start transmission */ 1353df619ecSLei Wen writel(readl(&base->icr) & ~ICR_START, &base->icr); 1363df619ecSLei Wen writel(readl(&base->icr) & ~ICR_STOP, &base->icr); 1373df619ecSLei Wen writel(msg->data, &base->idbr); 13868432c27SLei Wen if (msg->condition == I2C_COND_START) 1393df619ecSLei Wen writel(readl(&base->icr) | ICR_START, &base->icr); 14068432c27SLei Wen if (msg->condition == I2C_COND_STOP) 1413df619ecSLei Wen writel(readl(&base->icr) | ICR_STOP, &base->icr); 14268432c27SLei Wen if (msg->acknack == I2C_ACKNAK_SENDNAK) 1433df619ecSLei Wen writel(readl(&base->icr) | ICR_ACKNAK, &base->icr); 14468432c27SLei Wen if (msg->acknack == I2C_ACKNAK_SENDACK) 1453df619ecSLei Wen writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr); 1463df619ecSLei Wen writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr); 1473df619ecSLei Wen writel(readl(&base->icr) | ICR_TB, &base->icr); 14868432c27SLei Wen 14968432c27SLei Wen /* transmit register empty? */ 1507b46ee52SStefan Roese if (!i2c_isr_set_cleared(base, ISR_ITE, 0)) 15168432c27SLei Wen goto transfer_error_transmit_timeout; 15268432c27SLei Wen 15368432c27SLei Wen /* clear 'transmit empty' state */ 1543df619ecSLei Wen writel(readl(&base->isr) | ISR_ITE, &base->isr); 15568432c27SLei Wen 15668432c27SLei Wen /* wait for ACK from slave */ 15768432c27SLei Wen if (msg->acknack == I2C_ACKNAK_WAITACK) 1587b46ee52SStefan Roese if (!i2c_isr_set_cleared(base, 0, ISR_ACKNAK)) 15968432c27SLei Wen goto transfer_error_ack_missing; 16068432c27SLei Wen break; 16168432c27SLei Wen 16268432c27SLei Wen case I2C_READ: 16368432c27SLei Wen 16468432c27SLei Wen /* check if bus is not busy */ 1657b46ee52SStefan Roese if (!i2c_isr_set_cleared(base, 0, ISR_IBB)) 16668432c27SLei Wen goto transfer_error_bus_busy; 16768432c27SLei Wen 16868432c27SLei Wen /* start receive */ 1693df619ecSLei Wen writel(readl(&base->icr) & ~ICR_START, &base->icr); 1703df619ecSLei Wen writel(readl(&base->icr) & ~ICR_STOP, &base->icr); 17168432c27SLei Wen if (msg->condition == I2C_COND_START) 1723df619ecSLei Wen writel(readl(&base->icr) | ICR_START, &base->icr); 17368432c27SLei Wen if (msg->condition == I2C_COND_STOP) 1743df619ecSLei Wen writel(readl(&base->icr) | ICR_STOP, &base->icr); 17568432c27SLei Wen if (msg->acknack == I2C_ACKNAK_SENDNAK) 1763df619ecSLei Wen writel(readl(&base->icr) | ICR_ACKNAK, &base->icr); 17768432c27SLei Wen if (msg->acknack == I2C_ACKNAK_SENDACK) 1783df619ecSLei Wen writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr); 1793df619ecSLei Wen writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr); 1803df619ecSLei Wen writel(readl(&base->icr) | ICR_TB, &base->icr); 18168432c27SLei Wen 18268432c27SLei Wen /* receive register full? */ 1837b46ee52SStefan Roese if (!i2c_isr_set_cleared(base, ISR_IRF, 0)) 18468432c27SLei Wen goto transfer_error_receive_timeout; 18568432c27SLei Wen 1863df619ecSLei Wen msg->data = readl(&base->idbr); 18768432c27SLei Wen 18868432c27SLei Wen /* clear 'receive empty' state */ 1893df619ecSLei Wen writel(readl(&base->isr) | ISR_IRF, &base->isr); 19068432c27SLei Wen break; 19168432c27SLei Wen default: 19268432c27SLei Wen goto transfer_error_illegal_param; 19368432c27SLei Wen } 19468432c27SLei Wen 19568432c27SLei Wen return 0; 19668432c27SLei Wen 19768432c27SLei Wen transfer_error_msg_empty: 1988eff909aSStefan Roese debug("i2c_transfer: error: 'msg' is empty\n"); 1998eff909aSStefan Roese ret = -1; 2008eff909aSStefan Roese goto i2c_transfer_finish; 20168432c27SLei Wen 20268432c27SLei Wen transfer_error_transmit_timeout: 2038eff909aSStefan Roese debug("i2c_transfer: error: transmit timeout\n"); 2048eff909aSStefan Roese ret = -2; 2058eff909aSStefan Roese goto i2c_transfer_finish; 20668432c27SLei Wen 20768432c27SLei Wen transfer_error_ack_missing: 2088eff909aSStefan Roese debug("i2c_transfer: error: ACK missing\n"); 2098eff909aSStefan Roese ret = -3; 2108eff909aSStefan Roese goto i2c_transfer_finish; 21168432c27SLei Wen 21268432c27SLei Wen transfer_error_receive_timeout: 2138eff909aSStefan Roese debug("i2c_transfer: error: receive timeout\n"); 2148eff909aSStefan Roese ret = -4; 2158eff909aSStefan Roese goto i2c_transfer_finish; 21668432c27SLei Wen 21768432c27SLei Wen transfer_error_illegal_param: 2188eff909aSStefan Roese debug("i2c_transfer: error: illegal parameters\n"); 2198eff909aSStefan Roese ret = -5; 2208eff909aSStefan Roese goto i2c_transfer_finish; 22168432c27SLei Wen 22268432c27SLei Wen transfer_error_bus_busy: 2238eff909aSStefan Roese debug("i2c_transfer: error: bus is busy\n"); 2248eff909aSStefan Roese ret = -6; 2258eff909aSStefan Roese goto i2c_transfer_finish; 22668432c27SLei Wen 22768432c27SLei Wen i2c_transfer_finish: 2288eff909aSStefan Roese debug("i2c_transfer: ISR: 0x%04x\n", readl(&base->isr)); 2297b46ee52SStefan Roese i2c_reset(base); 23068432c27SLei Wen return ret; 23168432c27SLei Wen } 23268432c27SLei Wen 233*0c0f719aSStefan Roese static int __i2c_read(struct mv_i2c *base, uchar chip, u8 *addr, int alen, 2347b46ee52SStefan Roese uchar *buffer, int len) 23568432c27SLei Wen { 236fffff726SSimon Glass struct mv_i2c_msg msg; 23768432c27SLei Wen 2388eff909aSStefan Roese debug("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, " 239*0c0f719aSStefan Roese "len=0x%02x)\n", chip, *addr, alen, len); 24068432c27SLei Wen 2417b46ee52SStefan Roese i2c_reset(base); 24268432c27SLei Wen 24368432c27SLei Wen /* dummy chip address write */ 2448eff909aSStefan Roese debug("i2c_read: dummy chip address write\n"); 24568432c27SLei Wen msg.condition = I2C_COND_START; 24668432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 24768432c27SLei Wen msg.direction = I2C_WRITE; 24868432c27SLei Wen msg.data = (chip << 1); 24968432c27SLei Wen msg.data &= 0xFE; 2507b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 25168432c27SLei Wen return -1; 25268432c27SLei Wen 25368432c27SLei Wen /* 25468432c27SLei Wen * send memory address bytes; 25568432c27SLei Wen * alen defines how much bytes we have to send. 25668432c27SLei Wen */ 25768432c27SLei Wen while (--alen >= 0) { 258*0c0f719aSStefan Roese debug("i2c_read: send address byte %02x (alen=%d)\n", 259*0c0f719aSStefan Roese *addr, alen); 26068432c27SLei Wen msg.condition = I2C_COND_NORMAL; 26168432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 26268432c27SLei Wen msg.direction = I2C_WRITE; 263*0c0f719aSStefan Roese msg.data = *(addr++); 2647b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 26568432c27SLei Wen return -1; 26668432c27SLei Wen } 26768432c27SLei Wen 26868432c27SLei Wen /* start read sequence */ 2698eff909aSStefan Roese debug("i2c_read: start read sequence\n"); 27068432c27SLei Wen msg.condition = I2C_COND_START; 27168432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 27268432c27SLei Wen msg.direction = I2C_WRITE; 27368432c27SLei Wen msg.data = (chip << 1); 27468432c27SLei Wen msg.data |= 0x01; 2757b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 27668432c27SLei Wen return -1; 27768432c27SLei Wen 27868432c27SLei Wen /* read bytes; send NACK at last byte */ 27968432c27SLei Wen while (len--) { 28068432c27SLei Wen if (len == 0) { 28168432c27SLei Wen msg.condition = I2C_COND_STOP; 28268432c27SLei Wen msg.acknack = I2C_ACKNAK_SENDNAK; 28368432c27SLei Wen } else { 28468432c27SLei Wen msg.condition = I2C_COND_NORMAL; 28568432c27SLei Wen msg.acknack = I2C_ACKNAK_SENDACK; 28668432c27SLei Wen } 28768432c27SLei Wen 28868432c27SLei Wen msg.direction = I2C_READ; 28968432c27SLei Wen msg.data = 0x00; 2907b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 29168432c27SLei Wen return -1; 29268432c27SLei Wen 29368432c27SLei Wen *buffer = msg.data; 294*0c0f719aSStefan Roese debug("i2c_read: reading byte (%p)=0x%02x\n", 295*0c0f719aSStefan Roese buffer, *buffer); 29668432c27SLei Wen buffer++; 29768432c27SLei Wen } 29868432c27SLei Wen 2997b46ee52SStefan Roese i2c_reset(base); 30068432c27SLei Wen 30168432c27SLei Wen return 0; 30268432c27SLei Wen } 30368432c27SLei Wen 304*0c0f719aSStefan Roese static int __i2c_write(struct mv_i2c *base, uchar chip, u8 *addr, int alen, 3057b46ee52SStefan Roese uchar *buffer, int len) 30668432c27SLei Wen { 307fffff726SSimon Glass struct mv_i2c_msg msg; 30868432c27SLei Wen 3098eff909aSStefan Roese debug("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, " 310*0c0f719aSStefan Roese "len=0x%02x)\n", chip, *addr, alen, len); 31168432c27SLei Wen 3127b46ee52SStefan Roese i2c_reset(base); 31368432c27SLei Wen 31468432c27SLei Wen /* chip address write */ 3158eff909aSStefan Roese debug("i2c_write: chip address write\n"); 31668432c27SLei Wen msg.condition = I2C_COND_START; 31768432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 31868432c27SLei Wen msg.direction = I2C_WRITE; 31968432c27SLei Wen msg.data = (chip << 1); 32068432c27SLei Wen msg.data &= 0xFE; 3217b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 32268432c27SLei Wen return -1; 32368432c27SLei Wen 32468432c27SLei Wen /* 32568432c27SLei Wen * send memory address bytes; 32668432c27SLei Wen * alen defines how much bytes we have to send. 32768432c27SLei Wen */ 32868432c27SLei Wen while (--alen >= 0) { 329*0c0f719aSStefan Roese debug("i2c_read: send address byte %02x (alen=%d)\n", 330*0c0f719aSStefan Roese *addr, alen); 33168432c27SLei Wen msg.condition = I2C_COND_NORMAL; 33268432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 33368432c27SLei Wen msg.direction = I2C_WRITE; 334*0c0f719aSStefan Roese msg.data = *(addr++); 3357b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 33668432c27SLei Wen return -1; 33768432c27SLei Wen } 33868432c27SLei Wen 33968432c27SLei Wen /* write bytes; send NACK at last byte */ 34068432c27SLei Wen while (len--) { 341*0c0f719aSStefan Roese debug("i2c_write: writing byte (%p)=0x%02x\n", 342*0c0f719aSStefan Roese buffer, *buffer); 34368432c27SLei Wen 34468432c27SLei Wen if (len == 0) 34568432c27SLei Wen msg.condition = I2C_COND_STOP; 34668432c27SLei Wen else 34768432c27SLei Wen msg.condition = I2C_COND_NORMAL; 34868432c27SLei Wen 34968432c27SLei Wen msg.acknack = I2C_ACKNAK_WAITACK; 35068432c27SLei Wen msg.direction = I2C_WRITE; 35168432c27SLei Wen msg.data = *(buffer++); 35268432c27SLei Wen 3537b46ee52SStefan Roese if (i2c_transfer(base, &msg)) 35468432c27SLei Wen return -1; 35568432c27SLei Wen } 35668432c27SLei Wen 3577b46ee52SStefan Roese i2c_reset(base); 35868432c27SLei Wen 35968432c27SLei Wen return 0; 36068432c27SLei Wen } 3617b46ee52SStefan Roese 362*0c0f719aSStefan Roese #ifndef CONFIG_DM_I2C 363*0c0f719aSStefan Roese 3647b46ee52SStefan Roese static struct mv_i2c *base_glob; 3657b46ee52SStefan Roese 3667b46ee52SStefan Roese static void i2c_board_init(struct mv_i2c *base) 3677b46ee52SStefan Roese { 3687b46ee52SStefan Roese #ifdef CONFIG_SYS_I2C_INIT_BOARD 3697b46ee52SStefan Roese u32 icr; 3707b46ee52SStefan Roese /* 3717b46ee52SStefan Roese * call board specific i2c bus reset routine before accessing the 3727b46ee52SStefan Roese * environment, which might be in a chip on that bus. For details 3737b46ee52SStefan Roese * about this problem see doc/I2C_Edge_Conditions. 3747b46ee52SStefan Roese * 3757b46ee52SStefan Roese * disable I2C controller first, otherwhise it thinks we want to 3767b46ee52SStefan Roese * talk to the slave port... 3777b46ee52SStefan Roese */ 3787b46ee52SStefan Roese icr = readl(&base->icr); 3797b46ee52SStefan Roese writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr); 3807b46ee52SStefan Roese 3817b46ee52SStefan Roese i2c_init_board(); 3827b46ee52SStefan Roese 3837b46ee52SStefan Roese writel(icr, &base->icr); 3847b46ee52SStefan Roese #endif 3857b46ee52SStefan Roese } 3867b46ee52SStefan Roese 3877b46ee52SStefan Roese #ifdef CONFIG_I2C_MULTI_BUS 3887b46ee52SStefan Roese static unsigned long i2c_regs[CONFIG_MV_I2C_NUM] = CONFIG_MV_I2C_REG; 3897b46ee52SStefan Roese static unsigned int bus_initialized[CONFIG_MV_I2C_NUM]; 3907b46ee52SStefan Roese static unsigned int current_bus; 3917b46ee52SStefan Roese 3927b46ee52SStefan Roese int i2c_set_bus_num(unsigned int bus) 3937b46ee52SStefan Roese { 3947b46ee52SStefan Roese if ((bus < 0) || (bus >= CONFIG_MV_I2C_NUM)) { 3957b46ee52SStefan Roese printf("Bad bus: %d\n", bus); 3967b46ee52SStefan Roese return -1; 3977b46ee52SStefan Roese } 3987b46ee52SStefan Roese 3997b46ee52SStefan Roese base_glob = (struct mv_i2c *)i2c_regs[bus]; 4007b46ee52SStefan Roese current_bus = bus; 4017b46ee52SStefan Roese 4027b46ee52SStefan Roese if (!bus_initialized[current_bus]) { 4037b46ee52SStefan Roese i2c_board_init(base_glob); 4047b46ee52SStefan Roese bus_initialized[current_bus] = 1; 4057b46ee52SStefan Roese } 4067b46ee52SStefan Roese 4077b46ee52SStefan Roese return 0; 4087b46ee52SStefan Roese } 4097b46ee52SStefan Roese 4107b46ee52SStefan Roese unsigned int i2c_get_bus_num(void) 4117b46ee52SStefan Roese { 4127b46ee52SStefan Roese return current_bus; 4137b46ee52SStefan Roese } 4147b46ee52SStefan Roese #endif 4157b46ee52SStefan Roese 4167b46ee52SStefan Roese /* API Functions */ 4177b46ee52SStefan Roese void i2c_init(int speed, int slaveaddr) 4187b46ee52SStefan Roese { 4197b46ee52SStefan Roese #ifdef CONFIG_I2C_MULTI_BUS 4207b46ee52SStefan Roese current_bus = 0; 4217b46ee52SStefan Roese base_glob = (struct mv_i2c *)i2c_regs[current_bus]; 4227b46ee52SStefan Roese #else 4237b46ee52SStefan Roese base_glob = (struct mv_i2c *)CONFIG_MV_I2C_REG; 4247b46ee52SStefan Roese #endif 4257b46ee52SStefan Roese 4267b46ee52SStefan Roese i2c_board_init(base_glob); 4277b46ee52SStefan Roese } 4287b46ee52SStefan Roese 429*0c0f719aSStefan Roese static int __i2c_probe_chip(struct mv_i2c *base, uchar chip) 430*0c0f719aSStefan Roese { 431*0c0f719aSStefan Roese struct mv_i2c_msg msg; 432*0c0f719aSStefan Roese 433*0c0f719aSStefan Roese i2c_reset(base); 434*0c0f719aSStefan Roese 435*0c0f719aSStefan Roese msg.condition = I2C_COND_START; 436*0c0f719aSStefan Roese msg.acknack = I2C_ACKNAK_WAITACK; 437*0c0f719aSStefan Roese msg.direction = I2C_WRITE; 438*0c0f719aSStefan Roese msg.data = (chip << 1) + 1; 439*0c0f719aSStefan Roese if (i2c_transfer(base, &msg)) 440*0c0f719aSStefan Roese return -1; 441*0c0f719aSStefan Roese 442*0c0f719aSStefan Roese msg.condition = I2C_COND_STOP; 443*0c0f719aSStefan Roese msg.acknack = I2C_ACKNAK_SENDNAK; 444*0c0f719aSStefan Roese msg.direction = I2C_READ; 445*0c0f719aSStefan Roese msg.data = 0x00; 446*0c0f719aSStefan Roese if (i2c_transfer(base, &msg)) 447*0c0f719aSStefan Roese return -1; 448*0c0f719aSStefan Roese 449*0c0f719aSStefan Roese return 0; 450*0c0f719aSStefan Roese } 451*0c0f719aSStefan Roese 4527b46ee52SStefan Roese /* 4537b46ee52SStefan Roese * i2c_probe: - Test if a chip answers for a given i2c address 4547b46ee52SStefan Roese * 4557b46ee52SStefan Roese * @chip: address of the chip which is searched for 4567b46ee52SStefan Roese * @return: 0 if a chip was found, -1 otherwhise 4577b46ee52SStefan Roese */ 4587b46ee52SStefan Roese int i2c_probe(uchar chip) 4597b46ee52SStefan Roese { 4607b46ee52SStefan Roese return __i2c_probe_chip(base_glob, chip); 4617b46ee52SStefan Roese } 4627b46ee52SStefan Roese 4637b46ee52SStefan Roese /* 4647b46ee52SStefan Roese * i2c_read: - Read multiple bytes from an i2c device 4657b46ee52SStefan Roese * 4667b46ee52SStefan Roese * The higher level routines take into account that this function is only 4677b46ee52SStefan Roese * called with len < page length of the device (see configuration file) 4687b46ee52SStefan Roese * 4697b46ee52SStefan Roese * @chip: address of the chip which is to be read 4707b46ee52SStefan Roese * @addr: i2c data address within the chip 4717b46ee52SStefan Roese * @alen: length of the i2c data address (1..2 bytes) 4727b46ee52SStefan Roese * @buffer: where to write the data 4737b46ee52SStefan Roese * @len: how much byte do we want to read 4747b46ee52SStefan Roese * @return: 0 in case of success 4757b46ee52SStefan Roese */ 4767b46ee52SStefan Roese int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) 4777b46ee52SStefan Roese { 478*0c0f719aSStefan Roese u8 addr_bytes[4]; 479*0c0f719aSStefan Roese 480*0c0f719aSStefan Roese addr_bytes[0] = (addr >> 0) & 0xFF; 481*0c0f719aSStefan Roese addr_bytes[1] = (addr >> 8) & 0xFF; 482*0c0f719aSStefan Roese addr_bytes[2] = (addr >> 16) & 0xFF; 483*0c0f719aSStefan Roese addr_bytes[3] = (addr >> 24) & 0xFF; 484*0c0f719aSStefan Roese 485*0c0f719aSStefan Roese return __i2c_read(base_glob, chip, addr_bytes, alen, buffer, len); 4867b46ee52SStefan Roese } 4877b46ee52SStefan Roese 4887b46ee52SStefan Roese /* 4897b46ee52SStefan Roese * i2c_write: - Write multiple bytes to an i2c device 4907b46ee52SStefan Roese * 4917b46ee52SStefan Roese * The higher level routines take into account that this function is only 4927b46ee52SStefan Roese * called with len < page length of the device (see configuration file) 4937b46ee52SStefan Roese * 4947b46ee52SStefan Roese * @chip: address of the chip which is to be written 4957b46ee52SStefan Roese * @addr: i2c data address within the chip 4967b46ee52SStefan Roese * @alen: length of the i2c data address (1..2 bytes) 4977b46ee52SStefan Roese * @buffer: where to find the data to be written 4987b46ee52SStefan Roese * @len: how much byte do we want to read 4997b46ee52SStefan Roese * @return: 0 in case of success 5007b46ee52SStefan Roese */ 5017b46ee52SStefan Roese int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) 5027b46ee52SStefan Roese { 503*0c0f719aSStefan Roese u8 addr_bytes[4]; 504*0c0f719aSStefan Roese 505*0c0f719aSStefan Roese addr_bytes[0] = (addr >> 0) & 0xFF; 506*0c0f719aSStefan Roese addr_bytes[1] = (addr >> 8) & 0xFF; 507*0c0f719aSStefan Roese addr_bytes[2] = (addr >> 16) & 0xFF; 508*0c0f719aSStefan Roese addr_bytes[3] = (addr >> 24) & 0xFF; 509*0c0f719aSStefan Roese 510*0c0f719aSStefan Roese return __i2c_write(base_glob, chip, addr_bytes, alen, buffer, len); 5117b46ee52SStefan Roese } 512*0c0f719aSStefan Roese 513*0c0f719aSStefan Roese #else /* CONFIG_DM_I2C */ 514*0c0f719aSStefan Roese 515*0c0f719aSStefan Roese struct mv_i2c_priv { 516*0c0f719aSStefan Roese struct mv_i2c *base; 517*0c0f719aSStefan Roese }; 518*0c0f719aSStefan Roese 519*0c0f719aSStefan Roese static int mv_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) 520*0c0f719aSStefan Roese { 521*0c0f719aSStefan Roese struct mv_i2c_priv *i2c = dev_get_priv(bus); 522*0c0f719aSStefan Roese struct i2c_msg *dmsg, *omsg, dummy; 523*0c0f719aSStefan Roese 524*0c0f719aSStefan Roese memset(&dummy, 0, sizeof(struct i2c_msg)); 525*0c0f719aSStefan Roese 526*0c0f719aSStefan Roese /* 527*0c0f719aSStefan Roese * We expect either two messages (one with an offset and one with the 528*0c0f719aSStefan Roese * actual data) or one message (just data or offset/data combined) 529*0c0f719aSStefan Roese */ 530*0c0f719aSStefan Roese if (nmsgs > 2 || nmsgs == 0) { 531*0c0f719aSStefan Roese debug("%s: Only one or two messages are supported.", __func__); 532*0c0f719aSStefan Roese return -1; 533*0c0f719aSStefan Roese } 534*0c0f719aSStefan Roese 535*0c0f719aSStefan Roese omsg = nmsgs == 1 ? &dummy : msg; 536*0c0f719aSStefan Roese dmsg = nmsgs == 1 ? msg : msg + 1; 537*0c0f719aSStefan Roese 538*0c0f719aSStefan Roese if (dmsg->flags & I2C_M_RD) 539*0c0f719aSStefan Roese return __i2c_read(i2c->base, dmsg->addr, omsg->buf, 540*0c0f719aSStefan Roese omsg->len, dmsg->buf, dmsg->len); 541*0c0f719aSStefan Roese else 542*0c0f719aSStefan Roese return __i2c_write(i2c->base, dmsg->addr, omsg->buf, 543*0c0f719aSStefan Roese omsg->len, dmsg->buf, dmsg->len); 544*0c0f719aSStefan Roese } 545*0c0f719aSStefan Roese 546*0c0f719aSStefan Roese static int mv_i2c_probe(struct udevice *bus) 547*0c0f719aSStefan Roese { 548*0c0f719aSStefan Roese struct mv_i2c_priv *priv = dev_get_priv(bus); 549*0c0f719aSStefan Roese 550*0c0f719aSStefan Roese priv->base = (void *)dev_get_addr_ptr(bus); 551*0c0f719aSStefan Roese 552*0c0f719aSStefan Roese return 0; 553*0c0f719aSStefan Roese } 554*0c0f719aSStefan Roese 555*0c0f719aSStefan Roese static const struct dm_i2c_ops mv_i2c_ops = { 556*0c0f719aSStefan Roese .xfer = mv_i2c_xfer, 557*0c0f719aSStefan Roese }; 558*0c0f719aSStefan Roese 559*0c0f719aSStefan Roese static const struct udevice_id mv_i2c_ids[] = { 560*0c0f719aSStefan Roese { .compatible = "marvell,armada-3700-i2c" }, 561*0c0f719aSStefan Roese { } 562*0c0f719aSStefan Roese }; 563*0c0f719aSStefan Roese 564*0c0f719aSStefan Roese U_BOOT_DRIVER(i2c_mv) = { 565*0c0f719aSStefan Roese .name = "i2c_mv", 566*0c0f719aSStefan Roese .id = UCLASS_I2C, 567*0c0f719aSStefan Roese .of_match = mv_i2c_ids, 568*0c0f719aSStefan Roese .probe = mv_i2c_probe, 569*0c0f719aSStefan Roese .priv_auto_alloc_size = sizeof(struct mv_i2c_priv), 570*0c0f719aSStefan Roese .ops = &mv_i2c_ops, 571*0c0f719aSStefan Roese }; 572*0c0f719aSStefan Roese #endif /* CONFIG_DM_I2C */ 573