xref: /rk3399_rockchip-uboot/drivers/i2c/mvtwsi.c (revision dfc3958cd3cce33e16cefec36f670d6202e50e4f)
101ec99d9SAlbert Aribaud /*
2306563a7SAlbert Aribaud  * Driver for the TWSI (i2c) controller found on the Marvell
3306563a7SAlbert Aribaud  * orion5x and kirkwood SoC families.
401ec99d9SAlbert Aribaud  *
557b4bce9SAlbert ARIBAUD  * Author: Albert Aribaud <albert.u.boot@aribaud.net>
6306563a7SAlbert Aribaud  * Copyright (c) 2010 Albert Aribaud.
701ec99d9SAlbert Aribaud  *
81a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
901ec99d9SAlbert Aribaud  */
10306563a7SAlbert Aribaud 
1101ec99d9SAlbert Aribaud #include <common.h>
1201ec99d9SAlbert Aribaud #include <i2c.h>
1301ec99d9SAlbert Aribaud #include <asm/errno.h>
1401ec99d9SAlbert Aribaud #include <asm/io.h>
1501ec99d9SAlbert Aribaud 
16306563a7SAlbert Aribaud /*
17dd82242bSPaul Kocialkowski  * include a file that will provide CONFIG_I2C_MVTWSI_BASE*
18306563a7SAlbert Aribaud  * and possibly other settings
19306563a7SAlbert Aribaud  */
2001ec99d9SAlbert Aribaud 
21306563a7SAlbert Aribaud #if defined(CONFIG_ORION5X)
22306563a7SAlbert Aribaud #include <asm/arch/orion5x.h>
2381e33f4bSStefan Roese #elif (defined(CONFIG_KIRKWOOD) || defined(CONFIG_ARCH_MVEBU))
243dc23f78SStefan Roese #include <asm/arch/soc.h>
256620377eSHans de Goede #elif defined(CONFIG_SUNXI)
266620377eSHans de Goede #include <asm/arch/i2c.h>
27306563a7SAlbert Aribaud #else
28306563a7SAlbert Aribaud #error Driver mvtwsi not supported by SoC or board
2901ec99d9SAlbert Aribaud #endif
3001ec99d9SAlbert Aribaud 
3101ec99d9SAlbert Aribaud /*
32306563a7SAlbert Aribaud  * TWSI register structure
3301ec99d9SAlbert Aribaud  */
3401ec99d9SAlbert Aribaud 
356620377eSHans de Goede #ifdef CONFIG_SUNXI
366620377eSHans de Goede 
376620377eSHans de Goede struct  mvtwsi_registers {
386620377eSHans de Goede 	u32 slave_address;
396620377eSHans de Goede 	u32 xtnd_slave_addr;
406620377eSHans de Goede 	u32 data;
416620377eSHans de Goede 	u32 control;
426620377eSHans de Goede 	u32 status;
436620377eSHans de Goede 	u32 baudrate;
446620377eSHans de Goede 	u32 soft_reset;
456620377eSHans de Goede };
466620377eSHans de Goede 
476620377eSHans de Goede #else
486620377eSHans de Goede 
49306563a7SAlbert Aribaud struct  mvtwsi_registers {
50306563a7SAlbert Aribaud 	u32 slave_address;
51306563a7SAlbert Aribaud 	u32 data;
52306563a7SAlbert Aribaud 	u32 control;
53306563a7SAlbert Aribaud 	union {
54306563a7SAlbert Aribaud 		u32 status;	/* when reading */
55306563a7SAlbert Aribaud 		u32 baudrate;	/* when writing */
56306563a7SAlbert Aribaud 	};
57306563a7SAlbert Aribaud 	u32 xtnd_slave_addr;
58306563a7SAlbert Aribaud 	u32 reserved[2];
59306563a7SAlbert Aribaud 	u32 soft_reset;
60306563a7SAlbert Aribaud };
61306563a7SAlbert Aribaud 
626620377eSHans de Goede #endif
636620377eSHans de Goede 
64306563a7SAlbert Aribaud /*
65*dfc3958cSmario.six@gdsys.cc  * enum mvtwsi_ctrl_register_fields - Bit masks for flags in the control
66*dfc3958cSmario.six@gdsys.cc  * register
67306563a7SAlbert Aribaud  */
68*dfc3958cSmario.six@gdsys.cc enum mvtwsi_ctrl_register_fields {
69*dfc3958cSmario.six@gdsys.cc 	/* Acknowledge bit */
70*dfc3958cSmario.six@gdsys.cc 	MVTWSI_CONTROL_ACK	= 0x00000004,
71*dfc3958cSmario.six@gdsys.cc 	/* Interrupt flag */
72*dfc3958cSmario.six@gdsys.cc 	MVTWSI_CONTROL_IFLG	= 0x00000008,
73*dfc3958cSmario.six@gdsys.cc 	/* Stop bit */
74*dfc3958cSmario.six@gdsys.cc 	MVTWSI_CONTROL_STOP	= 0x00000010,
75*dfc3958cSmario.six@gdsys.cc 	/* Start bit */
76*dfc3958cSmario.six@gdsys.cc 	MVTWSI_CONTROL_START	= 0x00000020,
77*dfc3958cSmario.six@gdsys.cc 	/* I2C enable */
78*dfc3958cSmario.six@gdsys.cc 	MVTWSI_CONTROL_TWSIEN	= 0x00000040,
79*dfc3958cSmario.six@gdsys.cc 	/* Interrupt enable */
80*dfc3958cSmario.six@gdsys.cc 	MVTWSI_CONTROL_INTEN	= 0x00000080,
81*dfc3958cSmario.six@gdsys.cc };
82306563a7SAlbert Aribaud 
83306563a7SAlbert Aribaud /*
84904dfbfdSHans de Goede  * On sun6i and newer IFLG is a write-clear bit which is cleared by writing 1,
85904dfbfdSHans de Goede  * on other platforms it is a normal r/w bit which is cleared by writing 0.
86904dfbfdSHans de Goede  */
87904dfbfdSHans de Goede 
88904dfbfdSHans de Goede #ifdef CONFIG_SUNXI_GEN_SUN6I
89904dfbfdSHans de Goede #define	MVTWSI_CONTROL_CLEAR_IFLG	0x00000008
90904dfbfdSHans de Goede #else
91904dfbfdSHans de Goede #define	MVTWSI_CONTROL_CLEAR_IFLG	0x00000000
92904dfbfdSHans de Goede #endif
93904dfbfdSHans de Goede 
94904dfbfdSHans de Goede /*
95*dfc3958cSmario.six@gdsys.cc  * enum mvstwsi_status_values - Possible values of I2C controller's status
96*dfc3958cSmario.six@gdsys.cc  * register
97*dfc3958cSmario.six@gdsys.cc  *
98*dfc3958cSmario.six@gdsys.cc  * Only those statuses expected in normal master operation on
99*dfc3958cSmario.six@gdsys.cc  * non-10-bit-address devices are specified.
100*dfc3958cSmario.six@gdsys.cc  *
101*dfc3958cSmario.six@gdsys.cc  * Every status that's unexpected during normal operation (bus errors,
102*dfc3958cSmario.six@gdsys.cc  * arbitration losses, missing ACKs...) is passed back to the caller as an error
103306563a7SAlbert Aribaud  * code.
104306563a7SAlbert Aribaud  */
105*dfc3958cSmario.six@gdsys.cc enum mvstwsi_status_values {
106*dfc3958cSmario.six@gdsys.cc 	/* START condition transmitted */
107*dfc3958cSmario.six@gdsys.cc 	MVTWSI_STATUS_START		= 0x08,
108*dfc3958cSmario.six@gdsys.cc 	/* Repeated START condition transmitted */
109*dfc3958cSmario.six@gdsys.cc 	MVTWSI_STATUS_REPEATED_START	= 0x10,
110*dfc3958cSmario.six@gdsys.cc 	/* Address + write bit transmitted, ACK received */
111*dfc3958cSmario.six@gdsys.cc 	MVTWSI_STATUS_ADDR_W_ACK	= 0x18,
112*dfc3958cSmario.six@gdsys.cc 	/* Data transmitted, ACK received */
113*dfc3958cSmario.six@gdsys.cc 	MVTWSI_STATUS_DATA_W_ACK	= 0x28,
114*dfc3958cSmario.six@gdsys.cc 	/* Address + read bit transmitted, ACK received */
115*dfc3958cSmario.six@gdsys.cc 	MVTWSI_STATUS_ADDR_R_ACK	= 0x40,
116*dfc3958cSmario.six@gdsys.cc 	/* Address + read bit transmitted, ACK not received */
117*dfc3958cSmario.six@gdsys.cc 	MVTWSI_STATUS_ADDR_R_NAK	= 0x48,
118*dfc3958cSmario.six@gdsys.cc 	/* Data received, ACK transmitted */
119*dfc3958cSmario.six@gdsys.cc 	MVTWSI_STATUS_DATA_R_ACK	= 0x50,
120*dfc3958cSmario.six@gdsys.cc 	/* Data received, ACK not transmitted */
121*dfc3958cSmario.six@gdsys.cc 	MVTWSI_STATUS_DATA_R_NAK	= 0x58,
122*dfc3958cSmario.six@gdsys.cc 	/* No relevant status */
123*dfc3958cSmario.six@gdsys.cc 	MVTWSI_STATUS_IDLE		= 0xF8,
124*dfc3958cSmario.six@gdsys.cc };
125306563a7SAlbert Aribaud 
126306563a7SAlbert Aribaud /*
127dd82242bSPaul Kocialkowski  * MVTWSI controller base
128306563a7SAlbert Aribaud  */
129306563a7SAlbert Aribaud 
130dd82242bSPaul Kocialkowski static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap)
131dd82242bSPaul Kocialkowski {
132dd82242bSPaul Kocialkowski 	switch (adap->hwadapnr) {
133dd82242bSPaul Kocialkowski #ifdef CONFIG_I2C_MVTWSI_BASE0
134dd82242bSPaul Kocialkowski 	case 0:
135dd82242bSPaul Kocialkowski 		return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE0;
136dd82242bSPaul Kocialkowski #endif
137dd82242bSPaul Kocialkowski #ifdef CONFIG_I2C_MVTWSI_BASE1
138dd82242bSPaul Kocialkowski 	case 1:
139dd82242bSPaul Kocialkowski 		return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE1;
140dd82242bSPaul Kocialkowski #endif
141dd82242bSPaul Kocialkowski #ifdef CONFIG_I2C_MVTWSI_BASE2
142dd82242bSPaul Kocialkowski 	case 2:
143dd82242bSPaul Kocialkowski 		return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE2;
144dd82242bSPaul Kocialkowski #endif
145dd82242bSPaul Kocialkowski #ifdef CONFIG_I2C_MVTWSI_BASE3
146dd82242bSPaul Kocialkowski 	case 3:
147dd82242bSPaul Kocialkowski 		return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE3;
148dd82242bSPaul Kocialkowski #endif
149dd82242bSPaul Kocialkowski #ifdef CONFIG_I2C_MVTWSI_BASE4
150dd82242bSPaul Kocialkowski 	case 4:
151dd82242bSPaul Kocialkowski 		return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE4;
152dd82242bSPaul Kocialkowski #endif
1539d082687SJelle van der Waa #ifdef CONFIG_I2C_MVTWSI_BASE5
1549d082687SJelle van der Waa 	case 5:
1559d082687SJelle van der Waa 		return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE5;
1569d082687SJelle van der Waa #endif
157dd82242bSPaul Kocialkowski 	default:
158dd82242bSPaul Kocialkowski 		printf("Missing mvtwsi controller %d base\n", adap->hwadapnr);
159dd82242bSPaul Kocialkowski 		break;
160dd82242bSPaul Kocialkowski 	}
161dd82242bSPaul Kocialkowski 
162dd82242bSPaul Kocialkowski 	return NULL;
163dd82242bSPaul Kocialkowski }
164306563a7SAlbert Aribaud 
165306563a7SAlbert Aribaud /*
166*dfc3958cSmario.six@gdsys.cc  * enum mvtwsi_error_class - types of I2C errors
167306563a7SAlbert Aribaud  */
168*dfc3958cSmario.six@gdsys.cc enum mvtwsi_error_class {
169*dfc3958cSmario.six@gdsys.cc 	/* The controller returned a different status than expected */
170*dfc3958cSmario.six@gdsys.cc 	MVTWSI_ERROR_WRONG_STATUS       = 0x01,
171*dfc3958cSmario.six@gdsys.cc 	/* The controller timed out */
172*dfc3958cSmario.six@gdsys.cc 	MVTWSI_ERROR_TIMEOUT            = 0x02,
173*dfc3958cSmario.six@gdsys.cc };
174306563a7SAlbert Aribaud 
175*dfc3958cSmario.six@gdsys.cc /*
176*dfc3958cSmario.six@gdsys.cc  * mvtwsi_error() - Build I2C return code from error information
177*dfc3958cSmario.six@gdsys.cc  *
178*dfc3958cSmario.six@gdsys.cc  * For debugging purposes, this function packs some information of an occurred
179*dfc3958cSmario.six@gdsys.cc  * error into a return code. These error codes are returned from I2C API
180*dfc3958cSmario.six@gdsys.cc  * functions (i2c_{read,write}, dm_i2c_{read,write}, etc.).
181*dfc3958cSmario.six@gdsys.cc  *
182*dfc3958cSmario.six@gdsys.cc  * @ec:		The error class of the error (enum mvtwsi_error_class).
183*dfc3958cSmario.six@gdsys.cc  * @lc:		The last value of the control register.
184*dfc3958cSmario.six@gdsys.cc  * @ls:		The last value of the status register.
185*dfc3958cSmario.six@gdsys.cc  * @es:		The expected value of the status register.
186*dfc3958cSmario.six@gdsys.cc  * @return The generated error code.
187*dfc3958cSmario.six@gdsys.cc  */
188*dfc3958cSmario.six@gdsys.cc inline uint mvtwsi_error(uint ec, uint lc, uint ls, uint es)
189*dfc3958cSmario.six@gdsys.cc {
190*dfc3958cSmario.six@gdsys.cc 	return ((ec << 24) & 0xFF000000)
191*dfc3958cSmario.six@gdsys.cc 	       | ((lc << 16) & 0x00FF0000)
192*dfc3958cSmario.six@gdsys.cc 	       | ((ls << 8) & 0x0000FF00)
193*dfc3958cSmario.six@gdsys.cc 	       | (es & 0xFF);
194*dfc3958cSmario.six@gdsys.cc }
195306563a7SAlbert Aribaud 
196306563a7SAlbert Aribaud /*
197306563a7SAlbert Aribaud  * Wait for IFLG to raise, or return 'timeout'; then if status is as expected,
198306563a7SAlbert Aribaud  * return 0 (ok) or return 'wrong status'.
199306563a7SAlbert Aribaud  */
200dd82242bSPaul Kocialkowski static int twsi_wait(struct i2c_adapter *adap, int expected_status)
20101ec99d9SAlbert Aribaud {
202dd82242bSPaul Kocialkowski 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
203306563a7SAlbert Aribaud 	int control, status;
204306563a7SAlbert Aribaud 	int timeout = 1000;
205306563a7SAlbert Aribaud 
206306563a7SAlbert Aribaud 	do {
207306563a7SAlbert Aribaud 		control = readl(&twsi->control);
208306563a7SAlbert Aribaud 		if (control & MVTWSI_CONTROL_IFLG) {
209306563a7SAlbert Aribaud 			status = readl(&twsi->status);
210306563a7SAlbert Aribaud 			if (status == expected_status)
211306563a7SAlbert Aribaud 				return 0;
21201ec99d9SAlbert Aribaud 			else
213*dfc3958cSmario.six@gdsys.cc 				return mvtwsi_error(
214306563a7SAlbert Aribaud 					MVTWSI_ERROR_WRONG_STATUS,
215306563a7SAlbert Aribaud 					control, status, expected_status);
216306563a7SAlbert Aribaud 		}
217306563a7SAlbert Aribaud 		udelay(10); /* one clock cycle at 100 kHz */
218306563a7SAlbert Aribaud 	} while (timeout--);
219306563a7SAlbert Aribaud 	status = readl(&twsi->status);
220*dfc3958cSmario.six@gdsys.cc 	return mvtwsi_error(MVTWSI_ERROR_TIMEOUT, control, status,
221*dfc3958cSmario.six@gdsys.cc 			    expected_status);
22201ec99d9SAlbert Aribaud }
22301ec99d9SAlbert Aribaud 
224306563a7SAlbert Aribaud /*
225306563a7SAlbert Aribaud  * Assert the START condition, either in a single I2C transaction
226306563a7SAlbert Aribaud  * or inside back-to-back ones (repeated starts).
227306563a7SAlbert Aribaud  */
228d6b7757eSChris Packham static int twsi_start(struct i2c_adapter *adap, int expected_status, u8 *flags)
229306563a7SAlbert Aribaud {
230dd82242bSPaul Kocialkowski 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
231dd82242bSPaul Kocialkowski 
232306563a7SAlbert Aribaud 	/* globally set TWSIEN in case it was not */
233d6b7757eSChris Packham 	*flags |= MVTWSI_CONTROL_TWSIEN;
234306563a7SAlbert Aribaud 	/* assert START */
235d6b7757eSChris Packham 	writel(*flags | MVTWSI_CONTROL_START |
2362ca02995SHans de Goede 				    MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
237306563a7SAlbert Aribaud 	/* wait for controller to process START */
238dd82242bSPaul Kocialkowski 	return twsi_wait(adap, expected_status);
239306563a7SAlbert Aribaud }
240306563a7SAlbert Aribaud 
241306563a7SAlbert Aribaud /*
242306563a7SAlbert Aribaud  * Send a byte (i2c address or data).
243306563a7SAlbert Aribaud  */
244d6b7757eSChris Packham static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status,
245d6b7757eSChris Packham 		     u8 *flags)
246306563a7SAlbert Aribaud {
247dd82242bSPaul Kocialkowski 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
248dd82242bSPaul Kocialkowski 
249306563a7SAlbert Aribaud 	/* put byte in data register for sending */
250306563a7SAlbert Aribaud 	writel(byte, &twsi->data);
251306563a7SAlbert Aribaud 	/* clear any pending interrupt -- that'll cause sending */
252d6b7757eSChris Packham 	writel(*flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
253306563a7SAlbert Aribaud 	/* wait for controller to receive byte and check ACK */
254dd82242bSPaul Kocialkowski 	return twsi_wait(adap, expected_status);
255306563a7SAlbert Aribaud }
256306563a7SAlbert Aribaud 
257306563a7SAlbert Aribaud /*
258306563a7SAlbert Aribaud  * Receive a byte.
259306563a7SAlbert Aribaud  * Global mvtwsi_control_flags variable says if we should ack or nak.
260306563a7SAlbert Aribaud  */
261d6b7757eSChris Packham static int twsi_recv(struct i2c_adapter *adap, u8 *byte, u8 *flags)
262306563a7SAlbert Aribaud {
263dd82242bSPaul Kocialkowski 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
264306563a7SAlbert Aribaud 	int expected_status, status;
265306563a7SAlbert Aribaud 
266306563a7SAlbert Aribaud 	/* compute expected status based on ACK bit in global control flags */
267d6b7757eSChris Packham 	if (*flags & MVTWSI_CONTROL_ACK)
268306563a7SAlbert Aribaud 		expected_status = MVTWSI_STATUS_DATA_R_ACK;
269306563a7SAlbert Aribaud 	else
270306563a7SAlbert Aribaud 		expected_status = MVTWSI_STATUS_DATA_R_NAK;
271306563a7SAlbert Aribaud 	/* acknowledge *previous state* and launch receive */
272d6b7757eSChris Packham 	writel(*flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
273306563a7SAlbert Aribaud 	/* wait for controller to receive byte and assert ACK or NAK */
274dd82242bSPaul Kocialkowski 	status = twsi_wait(adap, expected_status);
275306563a7SAlbert Aribaud 	/* if we did receive expected byte then store it */
276306563a7SAlbert Aribaud 	if (status == 0)
277306563a7SAlbert Aribaud 		*byte = readl(&twsi->data);
278306563a7SAlbert Aribaud 	/* return status */
279306563a7SAlbert Aribaud 	return status;
280306563a7SAlbert Aribaud }
281306563a7SAlbert Aribaud 
282306563a7SAlbert Aribaud /*
283306563a7SAlbert Aribaud  * Assert the STOP condition.
284306563a7SAlbert Aribaud  * This is also used to force the bus back in idle (SDA=SCL=1).
285306563a7SAlbert Aribaud  */
286dd82242bSPaul Kocialkowski static int twsi_stop(struct i2c_adapter *adap, int status)
287306563a7SAlbert Aribaud {
288dd82242bSPaul Kocialkowski 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
289306563a7SAlbert Aribaud 	int control, stop_status;
290306563a7SAlbert Aribaud 	int timeout = 1000;
291306563a7SAlbert Aribaud 
292306563a7SAlbert Aribaud 	/* assert STOP */
293306563a7SAlbert Aribaud 	control = MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_STOP;
294904dfbfdSHans de Goede 	writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
295306563a7SAlbert Aribaud 	/* wait for IDLE; IFLG won't rise so twsi_wait() is no use. */
296306563a7SAlbert Aribaud 	do {
297306563a7SAlbert Aribaud 		stop_status = readl(&twsi->status);
298306563a7SAlbert Aribaud 		if (stop_status == MVTWSI_STATUS_IDLE)
299306563a7SAlbert Aribaud 			break;
300306563a7SAlbert Aribaud 		udelay(10); /* one clock cycle at 100 kHz */
301306563a7SAlbert Aribaud 	} while (timeout--);
302306563a7SAlbert Aribaud 	control = readl(&twsi->control);
303306563a7SAlbert Aribaud 	if (stop_status != MVTWSI_STATUS_IDLE)
304306563a7SAlbert Aribaud 		if (status == 0)
305*dfc3958cSmario.six@gdsys.cc 			status = mvtwsi_error(
306306563a7SAlbert Aribaud 				MVTWSI_ERROR_TIMEOUT,
307306563a7SAlbert Aribaud 				control, status, MVTWSI_STATUS_IDLE);
308306563a7SAlbert Aribaud 	return status;
309306563a7SAlbert Aribaud }
310306563a7SAlbert Aribaud 
311f582a158SStefan Roese static unsigned int twsi_calc_freq(const int n, const int m)
312f582a158SStefan Roese {
313f582a158SStefan Roese #ifdef CONFIG_SUNXI
314f582a158SStefan Roese 	return CONFIG_SYS_TCLK / (10 * (m + 1) * (1 << n));
315f582a158SStefan Roese #else
316f582a158SStefan Roese 	return CONFIG_SYS_TCLK / (10 * (m + 1) * (2 << n));
317f582a158SStefan Roese #endif
318f582a158SStefan Roese }
319306563a7SAlbert Aribaud 
320306563a7SAlbert Aribaud /*
321306563a7SAlbert Aribaud  * Reset controller.
322306563a7SAlbert Aribaud  * Controller reset also resets the baud rate and slave address, so
3230db2bbdcSHans de Goede  * they must be re-established afterwards.
324306563a7SAlbert Aribaud  */
3250db2bbdcSHans de Goede static void twsi_reset(struct i2c_adapter *adap)
326306563a7SAlbert Aribaud {
327dd82242bSPaul Kocialkowski 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
328d6b7757eSChris Packham 
329306563a7SAlbert Aribaud 	/* reset controller */
330306563a7SAlbert Aribaud 	writel(0, &twsi->soft_reset);
331306563a7SAlbert Aribaud 	/* wait 2 ms -- this is what the Marvell LSP does */
332306563a7SAlbert Aribaud 	udelay(20000);
333306563a7SAlbert Aribaud }
334306563a7SAlbert Aribaud 
335306563a7SAlbert Aribaud /*
336306563a7SAlbert Aribaud  * I2C init called by cmd_i2c when doing 'i2c reset'.
337306563a7SAlbert Aribaud  * Sets baud to the highest possible value not exceeding requested one.
338306563a7SAlbert Aribaud  */
3390db2bbdcSHans de Goede static unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap,
3400db2bbdcSHans de Goede 					   unsigned int requested_speed)
341306563a7SAlbert Aribaud {
342dd82242bSPaul Kocialkowski 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
3430db2bbdcSHans de Goede 	unsigned int tmp_speed, highest_speed, n, m;
3440db2bbdcSHans de Goede 	unsigned int baud = 0x44; /* baudrate at controller reset */
345306563a7SAlbert Aribaud 
346306563a7SAlbert Aribaud 	/* use actual speed to collect progressively higher values */
347306563a7SAlbert Aribaud 	highest_speed = 0;
348306563a7SAlbert Aribaud 	/* compute m, n setting for highest speed not above requested speed */
34901ec99d9SAlbert Aribaud 	for (n = 0; n < 8; n++) {
35001ec99d9SAlbert Aribaud 		for (m = 0; m < 16; m++) {
351f582a158SStefan Roese 			tmp_speed = twsi_calc_freq(n, m);
3529ec43b0cSmario.six@gdsys.cc 			if ((tmp_speed <= requested_speed) &&
3539ec43b0cSmario.six@gdsys.cc 			    (tmp_speed > highest_speed)) {
354306563a7SAlbert Aribaud 				highest_speed = tmp_speed;
355306563a7SAlbert Aribaud 				baud = (m << 3) | n;
35601ec99d9SAlbert Aribaud 			}
35701ec99d9SAlbert Aribaud 		}
35801ec99d9SAlbert Aribaud 	}
3590db2bbdcSHans de Goede 	writel(baud, &twsi->baudrate);
3600db2bbdcSHans de Goede 	return 0;
3610db2bbdcSHans de Goede }
3620db2bbdcSHans de Goede 
3630db2bbdcSHans de Goede static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
3640db2bbdcSHans de Goede {
365dd82242bSPaul Kocialkowski 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
366dd82242bSPaul Kocialkowski 
367306563a7SAlbert Aribaud 	/* reset controller */
3680db2bbdcSHans de Goede 	twsi_reset(adap);
3690db2bbdcSHans de Goede 	/* set speed */
3700db2bbdcSHans de Goede 	twsi_i2c_set_bus_speed(adap, speed);
3710db2bbdcSHans de Goede 	/* set slave address even though we don't use it */
3720db2bbdcSHans de Goede 	writel(slaveadd, &twsi->slave_address);
3730db2bbdcSHans de Goede 	writel(0, &twsi->xtnd_slave_addr);
3740db2bbdcSHans de Goede 	/* assert STOP but don't care for the result */
375dd82242bSPaul Kocialkowski 	(void) twsi_stop(adap, 0);
37601ec99d9SAlbert Aribaud }
37701ec99d9SAlbert Aribaud 
37801ec99d9SAlbert Aribaud /*
379306563a7SAlbert Aribaud  * Begin I2C transaction with expected start status, at given address.
380306563a7SAlbert Aribaud  * Common to i2c_probe, i2c_read and i2c_write.
381306563a7SAlbert Aribaud  * Expected address status will derive from direction bit (bit 0) in addr.
38201ec99d9SAlbert Aribaud  */
383dd82242bSPaul Kocialkowski static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
384d6b7757eSChris Packham 		     u8 addr, u8 *flags)
38501ec99d9SAlbert Aribaud {
386306563a7SAlbert Aribaud 	int status, expected_addr_status;
38701ec99d9SAlbert Aribaud 
388306563a7SAlbert Aribaud 	/* compute expected address status from direction bit in addr */
389306563a7SAlbert Aribaud 	if (addr & 1) /* reading */
390306563a7SAlbert Aribaud 		expected_addr_status = MVTWSI_STATUS_ADDR_R_ACK;
391306563a7SAlbert Aribaud 	else /* writing */
392306563a7SAlbert Aribaud 		expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
393306563a7SAlbert Aribaud 	/* assert START */
394d6b7757eSChris Packham 	status = twsi_start(adap, expected_start_status, flags);
395306563a7SAlbert Aribaud 	/* send out the address if the start went well */
396306563a7SAlbert Aribaud 	if (status == 0)
397d6b7757eSChris Packham 		status = twsi_send(adap, addr, expected_addr_status,
398d6b7757eSChris Packham 				   flags);
399306563a7SAlbert Aribaud 	/* return ok or status of first failure to caller */
400306563a7SAlbert Aribaud 	return status;
40101ec99d9SAlbert Aribaud }
40201ec99d9SAlbert Aribaud 
403306563a7SAlbert Aribaud /*
404306563a7SAlbert Aribaud  * I2C probe called by cmd_i2c when doing 'i2c probe'.
405306563a7SAlbert Aribaud  * Begin read, nak data byte, end.
406306563a7SAlbert Aribaud  */
4070db2bbdcSHans de Goede static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip)
40801ec99d9SAlbert Aribaud {
409306563a7SAlbert Aribaud 	u8 dummy_byte;
410d6b7757eSChris Packham 	u8 flags = 0;
411306563a7SAlbert Aribaud 	int status;
41201ec99d9SAlbert Aribaud 
413306563a7SAlbert Aribaud 	/* begin i2c read */
414d6b7757eSChris Packham 	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1, &flags);
415306563a7SAlbert Aribaud 	/* dummy read was accepted: receive byte but NAK it. */
416306563a7SAlbert Aribaud 	if (status == 0)
417d6b7757eSChris Packham 		status = twsi_recv(adap, &dummy_byte, &flags);
418306563a7SAlbert Aribaud 	/* Stop transaction */
419dd82242bSPaul Kocialkowski 	twsi_stop(adap, 0);
420306563a7SAlbert Aribaud 	/* return 0 or status of first failure */
421306563a7SAlbert Aribaud 	return status;
42201ec99d9SAlbert Aribaud }
42301ec99d9SAlbert Aribaud 
424306563a7SAlbert Aribaud /*
425306563a7SAlbert Aribaud  * I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c
426306563a7SAlbert Aribaud  * Begin write, send address byte(s), begin read, receive data bytes, end.
427306563a7SAlbert Aribaud  *
428306563a7SAlbert Aribaud  * NOTE: some EEPROMS want a stop right before the second start, while
429306563a7SAlbert Aribaud  * some will choke if it is there. Deciding which we should do is eeprom
430306563a7SAlbert Aribaud  * stuff, not i2c, but at the moment the APIs won't let us put it in
431306563a7SAlbert Aribaud  * cmd_eeprom, so we have to choose here, and for the moment that'll be
432306563a7SAlbert Aribaud  * a repeated start without a preceding stop.
433306563a7SAlbert Aribaud  */
4340db2bbdcSHans de Goede static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
4350db2bbdcSHans de Goede 			int alen, uchar *data, int length)
43601ec99d9SAlbert Aribaud {
437306563a7SAlbert Aribaud 	int status;
438d6b7757eSChris Packham 	u8 flags = 0;
43901ec99d9SAlbert Aribaud 
440306563a7SAlbert Aribaud 	/* begin i2c write to send the address bytes */
441d6b7757eSChris Packham 	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1), &flags);
442306563a7SAlbert Aribaud 	/* send addr bytes */
443306563a7SAlbert Aribaud 	while ((status == 0) && alen--)
444dd82242bSPaul Kocialkowski 		status = twsi_send(adap, addr >> (8*alen),
445d6b7757eSChris Packham 			MVTWSI_STATUS_DATA_W_ACK, &flags);
446306563a7SAlbert Aribaud 	/* begin i2c read to receive eeprom data bytes */
447306563a7SAlbert Aribaud 	if (status == 0)
448dd82242bSPaul Kocialkowski 		status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START,
449d6b7757eSChris Packham 				   (chip << 1) | 1, &flags);
450306563a7SAlbert Aribaud 	/* prepare ACK if at least one byte must be received */
451306563a7SAlbert Aribaud 	if (length > 0)
452d6b7757eSChris Packham 		flags |= MVTWSI_CONTROL_ACK;
453306563a7SAlbert Aribaud 	/* now receive actual bytes */
454306563a7SAlbert Aribaud 	while ((status == 0) && length--) {
455306563a7SAlbert Aribaud 		/* reset NAK if we if no more to read now */
456306563a7SAlbert Aribaud 		if (length == 0)
457d6b7757eSChris Packham 			flags &= ~MVTWSI_CONTROL_ACK;
458306563a7SAlbert Aribaud 		/* read current byte */
459d6b7757eSChris Packham 		status = twsi_recv(adap, data++, &flags);
46001ec99d9SAlbert Aribaud 	}
461306563a7SAlbert Aribaud 	/* Stop transaction */
462dd82242bSPaul Kocialkowski 	status = twsi_stop(adap, status);
463306563a7SAlbert Aribaud 	/* return 0 or status of first failure */
464306563a7SAlbert Aribaud 	return status;
46501ec99d9SAlbert Aribaud }
46601ec99d9SAlbert Aribaud 
467306563a7SAlbert Aribaud /*
468306563a7SAlbert Aribaud  * I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c
469306563a7SAlbert Aribaud  * Begin write, send address byte(s), send data bytes, end.
470306563a7SAlbert Aribaud  */
4710db2bbdcSHans de Goede static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
4720db2bbdcSHans de Goede 			int alen, uchar *data, int length)
47301ec99d9SAlbert Aribaud {
474306563a7SAlbert Aribaud 	int status;
475d6b7757eSChris Packham 	u8 flags = 0;
47601ec99d9SAlbert Aribaud 
477306563a7SAlbert Aribaud 	/* begin i2c write to send the eeprom adress bytes then data bytes */
478d6b7757eSChris Packham 	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1), &flags);
479306563a7SAlbert Aribaud 	/* send addr bytes */
480306563a7SAlbert Aribaud 	while ((status == 0) && alen--)
481dd82242bSPaul Kocialkowski 		status = twsi_send(adap, addr >> (8*alen),
482d6b7757eSChris Packham 			MVTWSI_STATUS_DATA_W_ACK, &flags);
483306563a7SAlbert Aribaud 	/* send data bytes */
484306563a7SAlbert Aribaud 	while ((status == 0) && (length-- > 0))
485d6b7757eSChris Packham 		status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK,
486d6b7757eSChris Packham 				   &flags);
487306563a7SAlbert Aribaud 	/* Stop transaction */
488dd82242bSPaul Kocialkowski 	status = twsi_stop(adap, status);
489306563a7SAlbert Aribaud 	/* return 0 or status of first failure */
490306563a7SAlbert Aribaud 	return status;
49101ec99d9SAlbert Aribaud }
49201ec99d9SAlbert Aribaud 
493dd82242bSPaul Kocialkowski #ifdef CONFIG_I2C_MVTWSI_BASE0
4940db2bbdcSHans de Goede U_BOOT_I2C_ADAP_COMPLETE(twsi0, twsi_i2c_init, twsi_i2c_probe,
4950db2bbdcSHans de Goede 			 twsi_i2c_read, twsi_i2c_write,
4960db2bbdcSHans de Goede 			 twsi_i2c_set_bus_speed,
4970db2bbdcSHans de Goede 			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 0)
498dd82242bSPaul Kocialkowski #endif
499dd82242bSPaul Kocialkowski #ifdef CONFIG_I2C_MVTWSI_BASE1
500dd82242bSPaul Kocialkowski U_BOOT_I2C_ADAP_COMPLETE(twsi1, twsi_i2c_init, twsi_i2c_probe,
501dd82242bSPaul Kocialkowski 			 twsi_i2c_read, twsi_i2c_write,
502dd82242bSPaul Kocialkowski 			 twsi_i2c_set_bus_speed,
503dd82242bSPaul Kocialkowski 			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 1)
504dd82242bSPaul Kocialkowski 
505dd82242bSPaul Kocialkowski #endif
506dd82242bSPaul Kocialkowski #ifdef CONFIG_I2C_MVTWSI_BASE2
507dd82242bSPaul Kocialkowski U_BOOT_I2C_ADAP_COMPLETE(twsi2, twsi_i2c_init, twsi_i2c_probe,
508dd82242bSPaul Kocialkowski 			 twsi_i2c_read, twsi_i2c_write,
509dd82242bSPaul Kocialkowski 			 twsi_i2c_set_bus_speed,
510dd82242bSPaul Kocialkowski 			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 2)
511dd82242bSPaul Kocialkowski 
512dd82242bSPaul Kocialkowski #endif
513dd82242bSPaul Kocialkowski #ifdef CONFIG_I2C_MVTWSI_BASE3
514dd82242bSPaul Kocialkowski U_BOOT_I2C_ADAP_COMPLETE(twsi3, twsi_i2c_init, twsi_i2c_probe,
515dd82242bSPaul Kocialkowski 			 twsi_i2c_read, twsi_i2c_write,
516dd82242bSPaul Kocialkowski 			 twsi_i2c_set_bus_speed,
517dd82242bSPaul Kocialkowski 			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 3)
518dd82242bSPaul Kocialkowski 
519dd82242bSPaul Kocialkowski #endif
520dd82242bSPaul Kocialkowski #ifdef CONFIG_I2C_MVTWSI_BASE4
521dd82242bSPaul Kocialkowski U_BOOT_I2C_ADAP_COMPLETE(twsi4, twsi_i2c_init, twsi_i2c_probe,
522dd82242bSPaul Kocialkowski 			 twsi_i2c_read, twsi_i2c_write,
523dd82242bSPaul Kocialkowski 			 twsi_i2c_set_bus_speed,
524dd82242bSPaul Kocialkowski 			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 4)
525dd82242bSPaul Kocialkowski 
526dd82242bSPaul Kocialkowski #endif
5279d082687SJelle van der Waa #ifdef CONFIG_I2C_MVTWSI_BASE5
5289d082687SJelle van der Waa U_BOOT_I2C_ADAP_COMPLETE(twsi5, twsi_i2c_init, twsi_i2c_probe,
5299d082687SJelle van der Waa 			 twsi_i2c_read, twsi_i2c_write,
5309d082687SJelle van der Waa 			 twsi_i2c_set_bus_speed,
5319d082687SJelle van der Waa 			 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 5)
5329d082687SJelle van der Waa 
5339d082687SJelle van der Waa #endif
534