xref: /openbmc/u-boot/drivers/i2c/mv_i2c.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
268432c27SLei Wen /*
368432c27SLei Wen  * (C) Copyright 2000
468432c27SLei Wen  * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
568432c27SLei Wen  *
668432c27SLei Wen  * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
768432c27SLei Wen  * Marius Groeger <mgroeger@sysgo.de>
868432c27SLei Wen  *
968432c27SLei Wen  * (C) Copyright 2003 Pengutronix e.K.
1068432c27SLei Wen  * Robert Schwebel <r.schwebel@pengutronix.de>
1168432c27SLei Wen  *
123df619ecSLei Wen  * (C) Copyright 2011 Marvell Inc.
133df619ecSLei Wen  * Lei Wen <leiwen@marvell.com>
143df619ecSLei Wen  *
1568432c27SLei Wen  * Back ported to the 8xx platform (from the 8260 platform) by
1668432c27SLei Wen  * Murray.Jensen@cmst.csiro.au, 27-Jan-01.
1768432c27SLei Wen  */
1868432c27SLei Wen 
1968432c27SLei Wen #include <common.h>
200c0f719aSStefan Roese #include <dm.h>
2168432c27SLei Wen #include <i2c.h>
227b46ee52SStefan Roese #include <asm/io.h>
233df619ecSLei Wen #include "mv_i2c.h"
2468432c27SLei Wen 
2568432c27SLei Wen /* All transfers are described by this data structure */
26fffff726SSimon Glass struct mv_i2c_msg {
2768432c27SLei Wen 	u8 condition;
2868432c27SLei Wen 	u8 acknack;
2968432c27SLei Wen 	u8 direction;
3068432c27SLei Wen 	u8 data;
3168432c27SLei Wen };
3268432c27SLei Wen 
330c0f719aSStefan Roese #ifdef CONFIG_ARMADA_3700
340c0f719aSStefan Roese /* Armada 3700 has no padding between the registers */
350c0f719aSStefan Roese struct mv_i2c {
360c0f719aSStefan Roese 	u32 ibmr;
370c0f719aSStefan Roese 	u32 idbr;
380c0f719aSStefan Roese 	u32 icr;
390c0f719aSStefan Roese 	u32 isr;
400c0f719aSStefan Roese 	u32 isar;
410c0f719aSStefan Roese };
420c0f719aSStefan Roese #else
433df619ecSLei Wen struct mv_i2c {
443df619ecSLei Wen 	u32 ibmr;
453df619ecSLei Wen 	u32 pad0;
463df619ecSLei Wen 	u32 idbr;
473df619ecSLei Wen 	u32 pad1;
483df619ecSLei Wen 	u32 icr;
493df619ecSLei Wen 	u32 pad2;
503df619ecSLei Wen 	u32 isr;
513df619ecSLei Wen 	u32 pad3;
523df619ecSLei Wen 	u32 isar;
533df619ecSLei Wen };
540c0f719aSStefan Roese #endif
550c0f719aSStefan Roese 
560c0f719aSStefan Roese /*
570c0f719aSStefan Roese  * Dummy implementation that can be overwritten by a board
580c0f719aSStefan Roese  * specific function
590c0f719aSStefan Roese  */
i2c_clk_enable(void)600c0f719aSStefan Roese __weak void i2c_clk_enable(void)
610c0f719aSStefan Roese {
620c0f719aSStefan Roese }
633df619ecSLei Wen 
6468432c27SLei Wen /*
653df619ecSLei Wen  * i2c_reset: - reset the host controller
6668432c27SLei Wen  *
6768432c27SLei Wen  */
i2c_reset(struct mv_i2c * base)687b46ee52SStefan Roese static void i2c_reset(struct mv_i2c *base)
6968432c27SLei Wen {
709ad5a007SStefan Roese 	u32 icr_mode;
719ad5a007SStefan Roese 
729ad5a007SStefan Roese 	/* Save bus mode (standard or fast speed) for later use */
739ad5a007SStefan Roese 	icr_mode = readl(&base->icr) & ICR_MODE_MASK;
743df619ecSLei Wen 	writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
753df619ecSLei Wen 	writel(readl(&base->icr) | ICR_UR, &base->icr);	  /* reset the unit */
7668432c27SLei Wen 	udelay(100);
773df619ecSLei Wen 	writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
783df619ecSLei Wen 
793df619ecSLei Wen 	i2c_clk_enable();
803df619ecSLei Wen 
813df619ecSLei Wen 	writel(CONFIG_SYS_I2C_SLAVE, &base->isar); /* set our slave address */
829ad5a007SStefan Roese 	/* set control reg values */
839ad5a007SStefan Roese 	writel(I2C_ICR_INIT | icr_mode, &base->icr);
843df619ecSLei Wen 	writel(I2C_ISR_INIT, &base->isr); /* set clear interrupt bits */
853df619ecSLei Wen 	writel(readl(&base->icr) | ICR_IUE, &base->icr); /* enable unit */
8668432c27SLei Wen 	udelay(100);
8768432c27SLei Wen }
8868432c27SLei Wen 
8968432c27SLei Wen /*
9068432c27SLei Wen  * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
9168432c27SLei Wen  *	                  are set and cleared
9268432c27SLei Wen  *
9368432c27SLei Wen  * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
9468432c27SLei Wen  */
i2c_isr_set_cleared(struct mv_i2c * base,unsigned long set_mask,unsigned long cleared_mask)957b46ee52SStefan Roese static int i2c_isr_set_cleared(struct mv_i2c *base, unsigned long set_mask,
9668432c27SLei Wen 			       unsigned long cleared_mask)
9768432c27SLei Wen {
983df619ecSLei Wen 	int timeout = 1000, isr;
9968432c27SLei Wen 
1003df619ecSLei Wen 	do {
1013df619ecSLei Wen 		isr = readl(&base->isr);
10268432c27SLei Wen 		udelay(10);
10368432c27SLei Wen 		if (timeout-- < 0)
10468432c27SLei Wen 			return 0;
1053df619ecSLei Wen 	} while (((isr & set_mask) != set_mask)
1063df619ecSLei Wen 		|| ((isr & cleared_mask) != 0));
10768432c27SLei Wen 
10868432c27SLei Wen 	return 1;
10968432c27SLei Wen }
11068432c27SLei Wen 
11168432c27SLei Wen /*
11268432c27SLei Wen  * i2c_transfer: - Transfer one byte over the i2c bus
11368432c27SLei Wen  *
11468432c27SLei Wen  * This function can tranfer a byte over the i2c bus in both directions.
11568432c27SLei Wen  * It is used by the public API functions.
11668432c27SLei Wen  *
11768432c27SLei Wen  * @return:  0: transfer successful
11868432c27SLei Wen  *          -1: message is empty
11968432c27SLei Wen  *          -2: transmit timeout
12068432c27SLei Wen  *          -3: ACK missing
12168432c27SLei Wen  *          -4: receive timeout
12268432c27SLei Wen  *          -5: illegal parameters
12368432c27SLei Wen  *          -6: bus is busy and couldn't be aquired
12468432c27SLei Wen  */
i2c_transfer(struct mv_i2c * base,struct mv_i2c_msg * msg)1257b46ee52SStefan Roese static int i2c_transfer(struct mv_i2c *base, struct mv_i2c_msg *msg)
12668432c27SLei Wen {
12768432c27SLei Wen 	int ret;
12868432c27SLei Wen 
12968432c27SLei Wen 	if (!msg)
13068432c27SLei Wen 		goto transfer_error_msg_empty;
13168432c27SLei Wen 
13268432c27SLei Wen 	switch (msg->direction) {
13368432c27SLei Wen 	case I2C_WRITE:
13468432c27SLei Wen 		/* check if bus is not busy */
1357b46ee52SStefan Roese 		if (!i2c_isr_set_cleared(base, 0, ISR_IBB))
13668432c27SLei Wen 			goto transfer_error_bus_busy;
13768432c27SLei Wen 
13868432c27SLei Wen 		/* start transmission */
1393df619ecSLei Wen 		writel(readl(&base->icr) & ~ICR_START, &base->icr);
1403df619ecSLei Wen 		writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
1413df619ecSLei Wen 		writel(msg->data, &base->idbr);
14268432c27SLei Wen 		if (msg->condition == I2C_COND_START)
1433df619ecSLei Wen 			writel(readl(&base->icr) | ICR_START, &base->icr);
14468432c27SLei Wen 		if (msg->condition == I2C_COND_STOP)
1453df619ecSLei Wen 			writel(readl(&base->icr) | ICR_STOP, &base->icr);
14668432c27SLei Wen 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
1473df619ecSLei Wen 			writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
14868432c27SLei Wen 		if (msg->acknack == I2C_ACKNAK_SENDACK)
1493df619ecSLei Wen 			writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
1503df619ecSLei Wen 		writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
1513df619ecSLei Wen 		writel(readl(&base->icr) | ICR_TB, &base->icr);
15268432c27SLei Wen 
15368432c27SLei Wen 		/* transmit register empty? */
1547b46ee52SStefan Roese 		if (!i2c_isr_set_cleared(base, ISR_ITE, 0))
15568432c27SLei Wen 			goto transfer_error_transmit_timeout;
15668432c27SLei Wen 
15768432c27SLei Wen 		/* clear 'transmit empty' state */
1583df619ecSLei Wen 		writel(readl(&base->isr) | ISR_ITE, &base->isr);
15968432c27SLei Wen 
16068432c27SLei Wen 		/* wait for ACK from slave */
16168432c27SLei Wen 		if (msg->acknack == I2C_ACKNAK_WAITACK)
1627b46ee52SStefan Roese 			if (!i2c_isr_set_cleared(base, 0, ISR_ACKNAK))
16368432c27SLei Wen 				goto transfer_error_ack_missing;
16468432c27SLei Wen 		break;
16568432c27SLei Wen 
16668432c27SLei Wen 	case I2C_READ:
16768432c27SLei Wen 
16868432c27SLei Wen 		/* check if bus is not busy */
1697b46ee52SStefan Roese 		if (!i2c_isr_set_cleared(base, 0, ISR_IBB))
17068432c27SLei Wen 			goto transfer_error_bus_busy;
17168432c27SLei Wen 
17268432c27SLei Wen 		/* start receive */
1733df619ecSLei Wen 		writel(readl(&base->icr) & ~ICR_START, &base->icr);
1743df619ecSLei Wen 		writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
17568432c27SLei Wen 		if (msg->condition == I2C_COND_START)
1763df619ecSLei Wen 			writel(readl(&base->icr) | ICR_START, &base->icr);
17768432c27SLei Wen 		if (msg->condition == I2C_COND_STOP)
1783df619ecSLei Wen 			writel(readl(&base->icr) | ICR_STOP, &base->icr);
17968432c27SLei Wen 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
1803df619ecSLei Wen 			writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
18168432c27SLei Wen 		if (msg->acknack == I2C_ACKNAK_SENDACK)
1823df619ecSLei Wen 			writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
1833df619ecSLei Wen 		writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
1843df619ecSLei Wen 		writel(readl(&base->icr) | ICR_TB, &base->icr);
18568432c27SLei Wen 
18668432c27SLei Wen 		/* receive register full? */
1877b46ee52SStefan Roese 		if (!i2c_isr_set_cleared(base, ISR_IRF, 0))
18868432c27SLei Wen 			goto transfer_error_receive_timeout;
18968432c27SLei Wen 
1903df619ecSLei Wen 		msg->data = readl(&base->idbr);
19168432c27SLei Wen 
19268432c27SLei Wen 		/* clear 'receive empty' state */
1933df619ecSLei Wen 		writel(readl(&base->isr) | ISR_IRF, &base->isr);
19468432c27SLei Wen 		break;
19568432c27SLei Wen 	default:
19668432c27SLei Wen 		goto transfer_error_illegal_param;
19768432c27SLei Wen 	}
19868432c27SLei Wen 
19968432c27SLei Wen 	return 0;
20068432c27SLei Wen 
20168432c27SLei Wen transfer_error_msg_empty:
2028eff909aSStefan Roese 	debug("i2c_transfer: error: 'msg' is empty\n");
2038eff909aSStefan Roese 	ret = -1;
2048eff909aSStefan Roese 	goto i2c_transfer_finish;
20568432c27SLei Wen 
20668432c27SLei Wen transfer_error_transmit_timeout:
2078eff909aSStefan Roese 	debug("i2c_transfer: error: transmit timeout\n");
2088eff909aSStefan Roese 	ret = -2;
2098eff909aSStefan Roese 	goto i2c_transfer_finish;
21068432c27SLei Wen 
21168432c27SLei Wen transfer_error_ack_missing:
2128eff909aSStefan Roese 	debug("i2c_transfer: error: ACK missing\n");
2138eff909aSStefan Roese 	ret = -3;
2148eff909aSStefan Roese 	goto i2c_transfer_finish;
21568432c27SLei Wen 
21668432c27SLei Wen transfer_error_receive_timeout:
2178eff909aSStefan Roese 	debug("i2c_transfer: error: receive timeout\n");
2188eff909aSStefan Roese 	ret = -4;
2198eff909aSStefan Roese 	goto i2c_transfer_finish;
22068432c27SLei Wen 
22168432c27SLei Wen transfer_error_illegal_param:
2228eff909aSStefan Roese 	debug("i2c_transfer: error: illegal parameters\n");
2238eff909aSStefan Roese 	ret = -5;
2248eff909aSStefan Roese 	goto i2c_transfer_finish;
22568432c27SLei Wen 
22668432c27SLei Wen transfer_error_bus_busy:
2278eff909aSStefan Roese 	debug("i2c_transfer: error: bus is busy\n");
2288eff909aSStefan Roese 	ret = -6;
2298eff909aSStefan Roese 	goto i2c_transfer_finish;
23068432c27SLei Wen 
23168432c27SLei Wen i2c_transfer_finish:
2328eff909aSStefan Roese 	debug("i2c_transfer: ISR: 0x%04x\n", readl(&base->isr));
2337b46ee52SStefan Roese 	i2c_reset(base);
23468432c27SLei Wen 	return ret;
23568432c27SLei Wen }
23668432c27SLei Wen 
__i2c_read(struct mv_i2c * base,uchar chip,u8 * addr,int alen,uchar * buffer,int len)2370c0f719aSStefan Roese static int __i2c_read(struct mv_i2c *base, uchar chip, u8 *addr, int alen,
2387b46ee52SStefan Roese 		      uchar *buffer, int len)
23968432c27SLei Wen {
240fffff726SSimon Glass 	struct mv_i2c_msg msg;
24168432c27SLei Wen 
2428eff909aSStefan Roese 	debug("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
2430c0f719aSStefan Roese 	      "len=0x%02x)\n", chip, *addr, alen, len);
24468432c27SLei Wen 
24585f03f0eSjinghua 	if (len == 0) {
24685f03f0eSjinghua 		printf("reading zero byte is invalid\n");
24785f03f0eSjinghua 		return -EINVAL;
24885f03f0eSjinghua 	}
24985f03f0eSjinghua 
2507b46ee52SStefan Roese 	i2c_reset(base);
25168432c27SLei Wen 
25268432c27SLei Wen 	/* dummy chip address write */
2538eff909aSStefan Roese 	debug("i2c_read: dummy chip address write\n");
25468432c27SLei Wen 	msg.condition = I2C_COND_START;
25568432c27SLei Wen 	msg.acknack   = I2C_ACKNAK_WAITACK;
25668432c27SLei Wen 	msg.direction = I2C_WRITE;
25768432c27SLei Wen 	msg.data = (chip << 1);
25868432c27SLei Wen 	msg.data &= 0xFE;
2597b46ee52SStefan Roese 	if (i2c_transfer(base, &msg))
26068432c27SLei Wen 		return -1;
26168432c27SLei Wen 
26268432c27SLei Wen 	/*
26368432c27SLei Wen 	 * send memory address bytes;
26468432c27SLei Wen 	 * alen defines how much bytes we have to send.
26568432c27SLei Wen 	 */
26668432c27SLei Wen 	while (--alen >= 0) {
2670c0f719aSStefan Roese 		debug("i2c_read: send address byte %02x (alen=%d)\n",
2680c0f719aSStefan Roese 		      *addr, alen);
26968432c27SLei Wen 		msg.condition = I2C_COND_NORMAL;
27068432c27SLei Wen 		msg.acknack   = I2C_ACKNAK_WAITACK;
27168432c27SLei Wen 		msg.direction = I2C_WRITE;
27277466267SBradley Bolen 		msg.data      = addr[alen];
2737b46ee52SStefan Roese 		if (i2c_transfer(base, &msg))
27468432c27SLei Wen 			return -1;
27568432c27SLei Wen 	}
27668432c27SLei Wen 
27768432c27SLei Wen 	/* start read sequence */
2788eff909aSStefan Roese 	debug("i2c_read: start read sequence\n");
27968432c27SLei Wen 	msg.condition = I2C_COND_START;
28068432c27SLei Wen 	msg.acknack   = I2C_ACKNAK_WAITACK;
28168432c27SLei Wen 	msg.direction = I2C_WRITE;
28268432c27SLei Wen 	msg.data      = (chip << 1);
28368432c27SLei Wen 	msg.data     |= 0x01;
2847b46ee52SStefan Roese 	if (i2c_transfer(base, &msg))
28568432c27SLei Wen 		return -1;
28668432c27SLei Wen 
28768432c27SLei Wen 	/* read bytes; send NACK at last byte */
28868432c27SLei Wen 	while (len--) {
28968432c27SLei Wen 		if (len == 0) {
29068432c27SLei Wen 			msg.condition = I2C_COND_STOP;
29168432c27SLei Wen 			msg.acknack   = I2C_ACKNAK_SENDNAK;
29268432c27SLei Wen 		} else {
29368432c27SLei Wen 			msg.condition = I2C_COND_NORMAL;
29468432c27SLei Wen 			msg.acknack   = I2C_ACKNAK_SENDACK;
29568432c27SLei Wen 		}
29668432c27SLei Wen 
29768432c27SLei Wen 		msg.direction = I2C_READ;
29868432c27SLei Wen 		msg.data      = 0x00;
2997b46ee52SStefan Roese 		if (i2c_transfer(base, &msg))
30068432c27SLei Wen 			return -1;
30168432c27SLei Wen 
30268432c27SLei Wen 		*buffer = msg.data;
3030c0f719aSStefan Roese 		debug("i2c_read: reading byte (%p)=0x%02x\n",
3040c0f719aSStefan Roese 		      buffer, *buffer);
30568432c27SLei Wen 		buffer++;
30668432c27SLei Wen 	}
30768432c27SLei Wen 
3087b46ee52SStefan Roese 	i2c_reset(base);
30968432c27SLei Wen 
31068432c27SLei Wen 	return 0;
31168432c27SLei Wen }
31268432c27SLei Wen 
__i2c_write(struct mv_i2c * base,uchar chip,u8 * addr,int alen,uchar * buffer,int len)3130c0f719aSStefan Roese static int __i2c_write(struct mv_i2c *base, uchar chip, u8 *addr, int alen,
3147b46ee52SStefan Roese 		       uchar *buffer, int len)
31568432c27SLei Wen {
316fffff726SSimon Glass 	struct mv_i2c_msg msg;
31768432c27SLei Wen 
3188eff909aSStefan Roese 	debug("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
3190c0f719aSStefan Roese 	      "len=0x%02x)\n", chip, *addr, alen, len);
32068432c27SLei Wen 
3217b46ee52SStefan Roese 	i2c_reset(base);
32268432c27SLei Wen 
32368432c27SLei Wen 	/* chip address write */
3248eff909aSStefan Roese 	debug("i2c_write: chip address write\n");
32568432c27SLei Wen 	msg.condition = I2C_COND_START;
32668432c27SLei Wen 	msg.acknack   = I2C_ACKNAK_WAITACK;
32768432c27SLei Wen 	msg.direction = I2C_WRITE;
32868432c27SLei Wen 	msg.data = (chip << 1);
32968432c27SLei Wen 	msg.data &= 0xFE;
3307b46ee52SStefan Roese 	if (i2c_transfer(base, &msg))
33168432c27SLei Wen 		return -1;
33268432c27SLei Wen 
33368432c27SLei Wen 	/*
33468432c27SLei Wen 	 * send memory address bytes;
33568432c27SLei Wen 	 * alen defines how much bytes we have to send.
33668432c27SLei Wen 	 */
33768432c27SLei Wen 	while (--alen >= 0) {
3380c0f719aSStefan Roese 		debug("i2c_read: send address byte %02x (alen=%d)\n",
3390c0f719aSStefan Roese 		      *addr, alen);
34068432c27SLei Wen 		msg.condition = I2C_COND_NORMAL;
34168432c27SLei Wen 		msg.acknack   = I2C_ACKNAK_WAITACK;
34268432c27SLei Wen 		msg.direction = I2C_WRITE;
34377466267SBradley Bolen 		msg.data      = addr[alen];
3447b46ee52SStefan Roese 		if (i2c_transfer(base, &msg))
34568432c27SLei Wen 			return -1;
34668432c27SLei Wen 	}
34768432c27SLei Wen 
34868432c27SLei Wen 	/* write bytes; send NACK at last byte */
34968432c27SLei Wen 	while (len--) {
3500c0f719aSStefan Roese 		debug("i2c_write: writing byte (%p)=0x%02x\n",
3510c0f719aSStefan Roese 		      buffer, *buffer);
35268432c27SLei Wen 
35368432c27SLei Wen 		if (len == 0)
35468432c27SLei Wen 			msg.condition = I2C_COND_STOP;
35568432c27SLei Wen 		else
35668432c27SLei Wen 			msg.condition = I2C_COND_NORMAL;
35768432c27SLei Wen 
35868432c27SLei Wen 		msg.acknack   = I2C_ACKNAK_WAITACK;
35968432c27SLei Wen 		msg.direction = I2C_WRITE;
36068432c27SLei Wen 		msg.data      = *(buffer++);
36168432c27SLei Wen 
3627b46ee52SStefan Roese 		if (i2c_transfer(base, &msg))
36368432c27SLei Wen 			return -1;
36468432c27SLei Wen 	}
36568432c27SLei Wen 
3667b46ee52SStefan Roese 	i2c_reset(base);
36768432c27SLei Wen 
36868432c27SLei Wen 	return 0;
36968432c27SLei Wen }
3707b46ee52SStefan Roese 
3710c0f719aSStefan Roese #ifndef CONFIG_DM_I2C
3720c0f719aSStefan Roese 
3737b46ee52SStefan Roese static struct mv_i2c *base_glob;
3747b46ee52SStefan Roese 
i2c_board_init(struct mv_i2c * base)3757b46ee52SStefan Roese static void i2c_board_init(struct mv_i2c *base)
3767b46ee52SStefan Roese {
3777b46ee52SStefan Roese #ifdef CONFIG_SYS_I2C_INIT_BOARD
3787b46ee52SStefan Roese 	u32 icr;
3797b46ee52SStefan Roese 	/*
3807b46ee52SStefan Roese 	 * call board specific i2c bus reset routine before accessing the
3817b46ee52SStefan Roese 	 * environment, which might be in a chip on that bus. For details
3827b46ee52SStefan Roese 	 * about this problem see doc/I2C_Edge_Conditions.
3837b46ee52SStefan Roese 	 *
3847b46ee52SStefan Roese 	 * disable I2C controller first, otherwhise it thinks we want to
3857b46ee52SStefan Roese 	 * talk to the slave port...
3867b46ee52SStefan Roese 	 */
3877b46ee52SStefan Roese 	icr = readl(&base->icr);
3887b46ee52SStefan Roese 	writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr);
3897b46ee52SStefan Roese 
3907b46ee52SStefan Roese 	i2c_init_board();
3917b46ee52SStefan Roese 
3927b46ee52SStefan Roese 	writel(icr, &base->icr);
3937b46ee52SStefan Roese #endif
3947b46ee52SStefan Roese }
3957b46ee52SStefan Roese 
3967b46ee52SStefan Roese #ifdef CONFIG_I2C_MULTI_BUS
3977b46ee52SStefan Roese static unsigned long i2c_regs[CONFIG_MV_I2C_NUM] = CONFIG_MV_I2C_REG;
3987b46ee52SStefan Roese static unsigned int bus_initialized[CONFIG_MV_I2C_NUM];
3997b46ee52SStefan Roese static unsigned int current_bus;
4007b46ee52SStefan Roese 
i2c_set_bus_num(unsigned int bus)4017b46ee52SStefan Roese int i2c_set_bus_num(unsigned int bus)
4027b46ee52SStefan Roese {
4037b46ee52SStefan Roese 	if ((bus < 0) || (bus >= CONFIG_MV_I2C_NUM)) {
4047b46ee52SStefan Roese 		printf("Bad bus: %d\n", bus);
4057b46ee52SStefan Roese 		return -1;
4067b46ee52SStefan Roese 	}
4077b46ee52SStefan Roese 
4087b46ee52SStefan Roese 	base_glob = (struct mv_i2c *)i2c_regs[bus];
4097b46ee52SStefan Roese 	current_bus = bus;
4107b46ee52SStefan Roese 
4117b46ee52SStefan Roese 	if (!bus_initialized[current_bus]) {
4127b46ee52SStefan Roese 		i2c_board_init(base_glob);
4137b46ee52SStefan Roese 		bus_initialized[current_bus] = 1;
4147b46ee52SStefan Roese 	}
4157b46ee52SStefan Roese 
4167b46ee52SStefan Roese 	return 0;
4177b46ee52SStefan Roese }
4187b46ee52SStefan Roese 
i2c_get_bus_num(void)4197b46ee52SStefan Roese unsigned int i2c_get_bus_num(void)
4207b46ee52SStefan Roese {
4217b46ee52SStefan Roese 	return current_bus;
4227b46ee52SStefan Roese }
4237b46ee52SStefan Roese #endif
4247b46ee52SStefan Roese 
4257b46ee52SStefan Roese /* API Functions */
i2c_init(int speed,int slaveaddr)4267b46ee52SStefan Roese void i2c_init(int speed, int slaveaddr)
4277b46ee52SStefan Roese {
4289ad5a007SStefan Roese 	u32 val;
4299ad5a007SStefan Roese 
4307b46ee52SStefan Roese #ifdef CONFIG_I2C_MULTI_BUS
4317b46ee52SStefan Roese 	current_bus = 0;
4327b46ee52SStefan Roese 	base_glob = (struct mv_i2c *)i2c_regs[current_bus];
4337b46ee52SStefan Roese #else
4347b46ee52SStefan Roese 	base_glob = (struct mv_i2c *)CONFIG_MV_I2C_REG;
4357b46ee52SStefan Roese #endif
4367b46ee52SStefan Roese 
4379ad5a007SStefan Roese 	if (speed > 100000)
4389ad5a007SStefan Roese 		val = ICR_FM;
4399ad5a007SStefan Roese 	else
4409ad5a007SStefan Roese 		val = ICR_SM;
4419ad5a007SStefan Roese 	clrsetbits_le32(&base_glob->icr, ICR_MODE_MASK, val);
4429ad5a007SStefan Roese 
4437b46ee52SStefan Roese 	i2c_board_init(base_glob);
4447b46ee52SStefan Roese }
4457b46ee52SStefan Roese 
__i2c_probe_chip(struct mv_i2c * base,uchar chip)4460c0f719aSStefan Roese static int __i2c_probe_chip(struct mv_i2c *base, uchar chip)
4470c0f719aSStefan Roese {
4480c0f719aSStefan Roese 	struct mv_i2c_msg msg;
4490c0f719aSStefan Roese 
4500c0f719aSStefan Roese 	i2c_reset(base);
4510c0f719aSStefan Roese 
4520c0f719aSStefan Roese 	msg.condition = I2C_COND_START;
4530c0f719aSStefan Roese 	msg.acknack   = I2C_ACKNAK_WAITACK;
4540c0f719aSStefan Roese 	msg.direction = I2C_WRITE;
4550c0f719aSStefan Roese 	msg.data      = (chip << 1) + 1;
4560c0f719aSStefan Roese 	if (i2c_transfer(base, &msg))
4570c0f719aSStefan Roese 		return -1;
4580c0f719aSStefan Roese 
4590c0f719aSStefan Roese 	msg.condition = I2C_COND_STOP;
4600c0f719aSStefan Roese 	msg.acknack   = I2C_ACKNAK_SENDNAK;
4610c0f719aSStefan Roese 	msg.direction = I2C_READ;
4620c0f719aSStefan Roese 	msg.data      = 0x00;
4630c0f719aSStefan Roese 	if (i2c_transfer(base, &msg))
4640c0f719aSStefan Roese 		return -1;
4650c0f719aSStefan Roese 
4660c0f719aSStefan Roese 	return 0;
4670c0f719aSStefan Roese }
4680c0f719aSStefan Roese 
4697b46ee52SStefan Roese /*
4707b46ee52SStefan Roese  * i2c_probe: - Test if a chip answers for a given i2c address
4717b46ee52SStefan Roese  *
4727b46ee52SStefan Roese  * @chip:	address of the chip which is searched for
4737b46ee52SStefan Roese  * @return:	0 if a chip was found, -1 otherwhise
4747b46ee52SStefan Roese  */
i2c_probe(uchar chip)4757b46ee52SStefan Roese int i2c_probe(uchar chip)
4767b46ee52SStefan Roese {
4777b46ee52SStefan Roese 	return __i2c_probe_chip(base_glob, chip);
4787b46ee52SStefan Roese }
4797b46ee52SStefan Roese 
4807b46ee52SStefan Roese /*
4817b46ee52SStefan Roese  * i2c_read: - Read multiple bytes from an i2c device
4827b46ee52SStefan Roese  *
4837b46ee52SStefan Roese  * The higher level routines take into account that this function is only
4847b46ee52SStefan Roese  * called with len < page length of the device (see configuration file)
4857b46ee52SStefan Roese  *
4867b46ee52SStefan Roese  * @chip:      address of the chip which is to be read
4877b46ee52SStefan Roese  * @addr:      i2c data address within the chip
4887b46ee52SStefan Roese  * @alen:      length of the i2c data address (1..2 bytes)
4897b46ee52SStefan Roese  * @buffer:    where to write the data
4907b46ee52SStefan Roese  * @len:       how much byte do we want to read
4917b46ee52SStefan Roese  * @return:    0 in case of success
4927b46ee52SStefan Roese  */
i2c_read(uchar chip,uint addr,int alen,uchar * buffer,int len)4937b46ee52SStefan Roese int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
4947b46ee52SStefan Roese {
4950c0f719aSStefan Roese 	u8 addr_bytes[4];
4960c0f719aSStefan Roese 
4970c0f719aSStefan Roese 	addr_bytes[0] = (addr >> 0) & 0xFF;
4980c0f719aSStefan Roese 	addr_bytes[1] = (addr >> 8) & 0xFF;
4990c0f719aSStefan Roese 	addr_bytes[2] = (addr >> 16) & 0xFF;
5000c0f719aSStefan Roese 	addr_bytes[3] = (addr >> 24) & 0xFF;
5010c0f719aSStefan Roese 
5020c0f719aSStefan Roese 	return __i2c_read(base_glob, chip, addr_bytes, alen, buffer, len);
5037b46ee52SStefan Roese }
5047b46ee52SStefan Roese 
5057b46ee52SStefan Roese /*
5067b46ee52SStefan Roese  * i2c_write: -  Write multiple bytes to an i2c device
5077b46ee52SStefan Roese  *
5087b46ee52SStefan Roese  * The higher level routines take into account that this function is only
5097b46ee52SStefan Roese  * called with len < page length of the device (see configuration file)
5107b46ee52SStefan Roese  *
5117b46ee52SStefan Roese  * @chip:	address of the chip which is to be written
5127b46ee52SStefan Roese  * @addr:	i2c data address within the chip
5137b46ee52SStefan Roese  * @alen:	length of the i2c data address (1..2 bytes)
5147b46ee52SStefan Roese  * @buffer:	where to find the data to be written
5157b46ee52SStefan Roese  * @len:	how much byte do we want to read
5167b46ee52SStefan Roese  * @return:	0 in case of success
5177b46ee52SStefan Roese  */
i2c_write(uchar chip,uint addr,int alen,uchar * buffer,int len)5187b46ee52SStefan Roese int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
5197b46ee52SStefan Roese {
5200c0f719aSStefan Roese 	u8 addr_bytes[4];
5210c0f719aSStefan Roese 
5220c0f719aSStefan Roese 	addr_bytes[0] = (addr >> 0) & 0xFF;
5230c0f719aSStefan Roese 	addr_bytes[1] = (addr >> 8) & 0xFF;
5240c0f719aSStefan Roese 	addr_bytes[2] = (addr >> 16) & 0xFF;
5250c0f719aSStefan Roese 	addr_bytes[3] = (addr >> 24) & 0xFF;
5260c0f719aSStefan Roese 
5270c0f719aSStefan Roese 	return __i2c_write(base_glob, chip, addr_bytes, alen, buffer, len);
5287b46ee52SStefan Roese }
5290c0f719aSStefan Roese 
5300c0f719aSStefan Roese #else /* CONFIG_DM_I2C */
5310c0f719aSStefan Roese 
5320c0f719aSStefan Roese struct mv_i2c_priv {
5330c0f719aSStefan Roese 	struct mv_i2c *base;
5340c0f719aSStefan Roese };
5350c0f719aSStefan Roese 
mv_i2c_xfer(struct udevice * bus,struct i2c_msg * msg,int nmsgs)5360c0f719aSStefan Roese static int mv_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
5370c0f719aSStefan Roese {
5380c0f719aSStefan Roese 	struct mv_i2c_priv *i2c = dev_get_priv(bus);
5390c0f719aSStefan Roese 	struct i2c_msg *dmsg, *omsg, dummy;
5400c0f719aSStefan Roese 
5410c0f719aSStefan Roese 	memset(&dummy, 0, sizeof(struct i2c_msg));
5420c0f719aSStefan Roese 
5430c0f719aSStefan Roese 	/*
5440c0f719aSStefan Roese 	 * We expect either two messages (one with an offset and one with the
5450c0f719aSStefan Roese 	 * actual data) or one message (just data or offset/data combined)
5460c0f719aSStefan Roese 	 */
5470c0f719aSStefan Roese 	if (nmsgs > 2 || nmsgs == 0) {
5480c0f719aSStefan Roese 		debug("%s: Only one or two messages are supported.", __func__);
5490c0f719aSStefan Roese 		return -1;
5500c0f719aSStefan Roese 	}
5510c0f719aSStefan Roese 
5520c0f719aSStefan Roese 	omsg = nmsgs == 1 ? &dummy : msg;
5530c0f719aSStefan Roese 	dmsg = nmsgs == 1 ? msg : msg + 1;
5540c0f719aSStefan Roese 
5550c0f719aSStefan Roese 	if (dmsg->flags & I2C_M_RD)
5560c0f719aSStefan Roese 		return __i2c_read(i2c->base, dmsg->addr, omsg->buf,
5570c0f719aSStefan Roese 				  omsg->len, dmsg->buf, dmsg->len);
5580c0f719aSStefan Roese 	else
5590c0f719aSStefan Roese 		return __i2c_write(i2c->base, dmsg->addr, omsg->buf,
5600c0f719aSStefan Roese 				   omsg->len, dmsg->buf, dmsg->len);
5610c0f719aSStefan Roese }
5620c0f719aSStefan Roese 
mv_i2c_set_bus_speed(struct udevice * bus,unsigned int speed)5639ad5a007SStefan Roese static int mv_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
5649ad5a007SStefan Roese {
5659ad5a007SStefan Roese 	struct mv_i2c_priv *priv = dev_get_priv(bus);
5669ad5a007SStefan Roese 	u32 val;
5679ad5a007SStefan Roese 
5689ad5a007SStefan Roese 	if (speed > 100000)
5699ad5a007SStefan Roese 		val = ICR_FM;
5709ad5a007SStefan Roese 	else
5719ad5a007SStefan Roese 		val = ICR_SM;
5729ad5a007SStefan Roese 	clrsetbits_le32(&priv->base->icr, ICR_MODE_MASK, val);
5739ad5a007SStefan Roese 
5749ad5a007SStefan Roese 	return 0;
5759ad5a007SStefan Roese }
5769ad5a007SStefan Roese 
mv_i2c_probe(struct udevice * bus)5770c0f719aSStefan Roese static int mv_i2c_probe(struct udevice *bus)
5780c0f719aSStefan Roese {
5790c0f719aSStefan Roese 	struct mv_i2c_priv *priv = dev_get_priv(bus);
5800c0f719aSStefan Roese 
581a821c4afSSimon Glass 	priv->base = (void *)devfdt_get_addr_ptr(bus);
5820c0f719aSStefan Roese 
5830c0f719aSStefan Roese 	return 0;
5840c0f719aSStefan Roese }
5850c0f719aSStefan Roese 
5860c0f719aSStefan Roese static const struct dm_i2c_ops mv_i2c_ops = {
5870c0f719aSStefan Roese 	.xfer		= mv_i2c_xfer,
5889ad5a007SStefan Roese 	.set_bus_speed	= mv_i2c_set_bus_speed,
5890c0f719aSStefan Roese };
5900c0f719aSStefan Roese 
5910c0f719aSStefan Roese static const struct udevice_id mv_i2c_ids[] = {
5920c0f719aSStefan Roese 	{ .compatible = "marvell,armada-3700-i2c" },
5930c0f719aSStefan Roese 	{ }
5940c0f719aSStefan Roese };
5950c0f719aSStefan Roese 
5960c0f719aSStefan Roese U_BOOT_DRIVER(i2c_mv) = {
5970c0f719aSStefan Roese 	.name	= "i2c_mv",
5980c0f719aSStefan Roese 	.id	= UCLASS_I2C,
5990c0f719aSStefan Roese 	.of_match = mv_i2c_ids,
6000c0f719aSStefan Roese 	.probe	= mv_i2c_probe,
6010c0f719aSStefan Roese 	.priv_auto_alloc_size = sizeof(struct mv_i2c_priv),
6020c0f719aSStefan Roese 	.ops	= &mv_i2c_ops,
6030c0f719aSStefan Roese };
6040c0f719aSStefan Roese #endif /* CONFIG_DM_I2C */
605