xref: /openbsd-src/sys/dev/fdt/sxitwi.c (revision f763167468dba5339ed4b14b7ecaca2a397ab0f6)
1 /* $OpenBSD: sxitwi.c,v 1.2 2017/09/13 20:26:26 patrick Exp $ */
2 /*	$NetBSD: gttwsi_core.c,v 1.2 2014/11/23 13:37:27 jmcneill Exp $	*/
3 /*
4  * Copyright (c) 2008 Eiji Kawauchi.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed for the NetBSD Project by
18  *      Eiji Kawauchi.
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 /*
34  * Copyright (c) 2005 Brocade Communcations, inc.
35  * All rights reserved.
36  *
37  * Written by Matt Thomas for Brocade Communcations, Inc.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in the
46  *    documentation and/or other materials provided with the distribution.
47  * 3. The name of Brocade Communications, Inc. may not be used to endorse
48  *    or promote products derived from this software without specific prior
49  *    written permission.
50  *
51  * THIS SOFTWARE IS PROVIDED BY BROCADE COMMUNICATIONS, INC. ``AS IS'' AND
52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54  * ARE DISCLAIMED.  IN NO EVENT SHALL EITHER BROCADE COMMUNICATIONS, INC. BE
55  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
56  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
57  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
58  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
59  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61  * OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63 
64 /*
65  * Marvell Two-Wire Serial Interface (aka I2C) master driver
66  */
67 
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/device.h>
71 #include <sys/kernel.h>
72 #include <sys/rwlock.h>
73 
74 #include <sys/param.h>
75 #include <sys/device.h>
76 #include <sys/systm.h>
77 
78 #define	_I2C_PRIVATE
79 #include <dev/i2c/i2cvar.h>
80 
81 #include <machine/bus.h>
82 #include <machine/fdt.h>
83 
84 #include <dev/ofw/openfirm.h>
85 #include <dev/ofw/ofw_clock.h>
86 #include <dev/ofw/ofw_pinctrl.h>
87 #include <dev/ofw/fdt.h>
88 
89 #define	TWI_CCR_REG		0x14
90 #define	TWI_CCR_CLK_M		(0x0f << 3)
91 #define	TWI_CCR_CLK_N		(0x07 << 0)
92 
93 #define	TWSI_SLAVEADDR		0x00
94 #define	TWSI_EXTEND_SLAVEADDR	0x04
95 #define	TWSI_DATA		0x08
96 #define	TWSI_CONTROL		0x0c
97 #define	TWSI_STATUS		0x10
98 #define	TWSI_BAUDRATE		0x14
99 #define	TWSI_SOFTRESET		0x18
100 
101 #define	SLAVEADDR_GCE_MASK	0x01
102 #define	SLAVEADDR_SADDR_MASK	0xfe
103 
104 #define	EXTEND_SLAVEADDR_MASK	0xff
105 
106 #define	DATA_MASK		0xff
107 
108 #define	CONTROL_ACK		(1 << 2)
109 #define	CONTROL_IFLG		(1 << 3)
110 #define	CONTROL_STOP		(1 << 4)
111 #define	CONTROL_START		(1 << 5)
112 #define	CONTROL_TWSIEN		(1 << 6)
113 #define	CONTROL_INTEN		(1 << 7)
114 
115 #define	STAT_BE		0x00	/* Bus Error */
116 #define	STAT_SCT	0x08	/* Start condition transmitted */
117 #define	STAT_RSCT	0x10	/* Repeated start condition transmitted */
118 #define	STAT_AWBT_AR	0x18	/* Address + write bit transd, ack recvd */
119 #define	STAT_AWBT_ANR	0x20	/* Address + write bit transd, ack not recvd */
120 #define	STAT_MTDB_AR	0x28	/* Master transd data byte, ack recvd */
121 #define	STAT_MTDB_ANR	0x30	/* Master transd data byte, ack not recvd */
122 #define	STAT_MLADADT	0x38	/* Master lost arbitr during addr or data tx */
123 #define	STAT_ARBT_AR	0x40	/* Address + read bit transd, ack recvd */
124 #define	STAT_ARBT_ANR	0x48	/* Address + read bit transd, ack not recvd */
125 #define	STAT_MRRD_AT	0x50	/* Master received read data, ack transd */
126 #define	STAT_MRRD_ANT	0x58	/* Master received read data, ack not transd */
127 #define	STAT_SAWBT_AR	0xd0	/* Second addr + write bit transd, ack recvd */
128 #define	STAT_SAWBT_ANR	0xd8	/* S addr + write bit transd, ack not recvd */
129 #define	STAT_SARBT_AR	0xe0	/* Second addr + read bit transd, ack recvd */
130 #define	STAT_SARBT_ANR	0xe8	/* S addr + read bit transd, ack not recvd */
131 #define	STAT_NRS	0xf8	/* No relevant status */
132 
133 #define	SOFTRESET_VAL		0		/* reset value */
134 
135 #define	TWSI_RETRY_COUNT	1000		/* retry loop count */
136 #define	TWSI_RETRY_DELAY	1		/* retry delay */
137 #define	TWSI_STAT_DELAY		1		/* poll status delay */
138 #define	TWSI_READ_DELAY		2		/* read delay */
139 #define	TWSI_WRITE_DELAY	2		/* write delay */
140 
141 struct sxitwi_softc {
142 	struct device		 sc_dev;
143 	bus_space_tag_t		 sc_iot;
144 	bus_space_handle_t	 sc_ioh;
145 	int			 sc_node;
146 	u_int			 sc_started;
147 	struct i2c_controller	 sc_ic;
148 	struct rwlock		 sc_buslock;
149 	void			*sc_ih;
150 };
151 
152 void	sxitwi_attach(struct device *, struct device *, void *);
153 int	sxitwi_match(struct device *, void *, void *);
154 void	sxitwi_bus_scan(struct device *, struct i2cbus_attach_args *, void *);
155 
156 int	sxitwi_intr(void *);
157 int	sxitwi_acquire_bus(void *, int);
158 void	sxitwi_release_bus(void *, int);
159 int	sxitwi_send_start(void *, int);
160 int	sxitwi_send_stop(void *, int);
161 int	sxitwi_initiate_xfer(void *, i2c_addr_t, int);
162 int	sxitwi_read_byte(void *, uint8_t *, int);
163 int	sxitwi_write_byte(void *, uint8_t, int);
164 int	sxitwi_wait(struct sxitwi_softc *, u_int, u_int, int);
165 static inline u_int sxitwi_read_4(struct sxitwi_softc *, u_int);
166 static inline void sxitwi_write_4(struct sxitwi_softc *, u_int, u_int);
167 
168 struct cfdriver sxitwi_cd = {
169 	NULL, "sxitwi", DV_DULL
170 };
171 
172 struct cfattach sxitwi_ca = {
173 	sizeof(struct sxitwi_softc), sxitwi_match, sxitwi_attach
174 };
175 
176 int
177 sxitwi_match(struct device *parent, void *match, void *aux)
178 {
179 	struct fdt_attach_args *faa = aux;
180 
181 	return (OF_is_compatible(faa->fa_node, "allwinner,sun4i-a10-i2c") ||
182 	    OF_is_compatible(faa->fa_node, "allwinner,sun7i-a20-i2c"));
183 }
184 
185 void
186 sxitwi_attach(struct device *parent, struct device *self, void *aux)
187 {
188 	struct sxitwi_softc *sc = (struct sxitwi_softc *)self;
189 	struct fdt_attach_args *faa = aux;
190 	struct i2cbus_attach_args iba;
191 
192 	if (faa->fa_nreg < 1) {
193 		printf(": no registers\n");
194 		return;
195 	}
196 
197 	sc->sc_node = faa->fa_node;
198 	sc->sc_iot = faa->fa_iot;
199 
200 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
201 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
202 		printf(": can't map registers\n");
203 		return;
204 	}
205 
206 	rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname);
207 
208 	sc->sc_started = 0;
209 	sc->sc_ic.ic_cookie = sc;
210 	sc->sc_ic.ic_acquire_bus = sxitwi_acquire_bus;
211 	sc->sc_ic.ic_release_bus = sxitwi_release_bus;
212 	sc->sc_ic.ic_exec = NULL;
213 	sc->sc_ic.ic_send_start = sxitwi_send_start;
214 	sc->sc_ic.ic_send_stop = sxitwi_send_stop;
215 	sc->sc_ic.ic_initiate_xfer = sxitwi_initiate_xfer;
216 	sc->sc_ic.ic_read_byte = sxitwi_read_byte;
217 	sc->sc_ic.ic_write_byte = sxitwi_write_byte;
218 
219 	pinctrl_byname(faa->fa_node, "default");
220 
221 	/* Enable clock */
222 	clock_enable(faa->fa_node, NULL);
223 
224 	/*
225 	 * Set clock rate to 100kHz. From the datasheet:
226 	 *   For 100Khz standard speed 2Wire, CLK_N=2, CLK_M=11
227 	 *   F0=48M/2^2=12Mhz, F1=F0/(10*(11+1)) = 0.1Mhz
228 	 */
229 	sxitwi_write_4(sc, TWI_CCR_REG, (11 << 3) | (2 << 0));
230 
231 	/* Put the controller into Soft Reset. */
232 	sxitwi_write_4(sc, TWSI_SOFTRESET, SOFTRESET_VAL);
233 
234 	/* Establish interrupt */
235 	sc->sc_ih = arm_intr_establish_fdt(faa->fa_node, IPL_BIO,
236 	    sxitwi_intr, sc, sc->sc_dev.dv_xname);
237 	if (sc->sc_ih == NULL) {
238 		printf(": can't to establish interrupt\n");
239 		return;
240 	}
241 
242 	printf("\n");
243 
244 	/* Configure its children */
245 	memset(&iba, 0, sizeof(iba));
246 	iba.iba_name = "iic";
247 	iba.iba_tag = &sc->sc_ic;
248 	iba.iba_bus_scan = sxitwi_bus_scan;
249 	iba.iba_bus_scan_arg = &sc->sc_node;
250 
251 	config_found(&sc->sc_dev, &iba, iicbus_print);
252 }
253 
254 void
255 sxitwi_bus_scan(struct device *self, struct i2cbus_attach_args *iba, void *arg)
256 {
257 	int iba_node = *(int *)arg;
258 	struct i2c_attach_args ia;
259 	char name[32];
260 	uint32_t reg[1];
261 	int node;
262 
263 	for (node = OF_child(iba_node); node; node = OF_peer(node)) {
264 		memset(name, 0, sizeof(name));
265 		memset(reg, 0, sizeof(reg));
266 
267 		if (OF_getprop(node, "compatible", name, sizeof(name)) == -1)
268 			continue;
269 		if (name[0] == '\0')
270 			continue;
271 
272 		if (OF_getprop(node, "reg", &reg, sizeof(reg)) != sizeof(reg))
273 			continue;
274 
275 		memset(&ia, 0, sizeof(ia));
276 		ia.ia_tag = iba->iba_tag;
277 		ia.ia_addr = bemtoh32(&reg[0]);
278 		ia.ia_name = name;
279 		ia.ia_cookie = &node;
280 		config_found(self, &ia, iic_print);
281 	}
282 }
283 
284 u_int
285 sxitwi_read_4(struct sxitwi_softc *sc, u_int reg)
286 {
287 	u_int val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg);
288 
289 	delay(TWSI_READ_DELAY);
290 
291 	return val;
292 }
293 
294 void
295 sxitwi_write_4(struct sxitwi_softc *sc, u_int reg, u_int val)
296 {
297 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, val);
298 
299 	delay(TWSI_WRITE_DELAY);
300 
301 	return;
302 }
303 
304 int
305 sxitwi_intr(void *arg)
306 {
307 	struct sxitwi_softc *sc = arg;
308 	u_int val;
309 
310 	val = sxitwi_read_4(sc, TWSI_CONTROL);
311 	if (val & CONTROL_IFLG) {
312 		sxitwi_write_4(sc, TWSI_CONTROL, val & ~CONTROL_INTEN);
313 		wakeup(&sc->sc_dev);
314 		return 1;
315 	}
316 	return 0;
317 }
318 
319 int
320 sxitwi_acquire_bus(void *arg, int flags)
321 {
322 	struct sxitwi_softc *sc = arg;
323 
324 	if (flags & I2C_F_POLL)
325 		return 0;
326 
327 	return rw_enter(&sc->sc_buslock, RW_WRITE);
328 }
329 
330 void
331 sxitwi_release_bus(void *arg, int flags)
332 {
333 	struct sxitwi_softc *sc = arg;
334 
335 	if (flags & I2C_F_POLL)
336 		return;
337 
338 	rw_exit(&sc->sc_buslock);
339 }
340 
341 int
342 sxitwi_send_start(void *v, int flags)
343 {
344 	struct sxitwi_softc *sc = v;
345 	int expect;
346 
347 	if (sc->sc_started)
348 		expect = STAT_RSCT;
349 	else
350 		expect = STAT_SCT;
351 	sc->sc_started = 1;
352 
353 	return sxitwi_wait(sc, CONTROL_START, expect, flags);
354 }
355 
356 int
357 sxitwi_send_stop(void *v, int flags)
358 {
359 	struct sxitwi_softc *sc = v;
360 	int retry = TWSI_RETRY_COUNT;
361 	u_int control;
362 
363 	sc->sc_started = 0;
364 
365 	/* Interrupt is not generated for STAT_NRS. */
366 	control = CONTROL_STOP | CONTROL_TWSIEN;
367 	sxitwi_write_4(sc, TWSI_CONTROL, control);
368 	while (--retry > 0) {
369 		if (sxitwi_read_4(sc, TWSI_STATUS) == STAT_NRS)
370 			return 0;
371 		delay(TWSI_STAT_DELAY);
372 	}
373 
374 	return -1;
375 }
376 
377 int
378 sxitwi_initiate_xfer(void *v, i2c_addr_t addr, int flags)
379 {
380 	struct sxitwi_softc *sc = v;
381 	u_int data, expect;
382 	int error, read;
383 
384 	sxitwi_send_start(v, flags);
385 
386 	read = (flags & I2C_F_READ) != 0;
387 	if (read)
388 		expect = STAT_ARBT_AR;
389 	else
390 		expect = STAT_AWBT_AR;
391 
392 	/*
393 	 * First byte contains whether this xfer is a read or write.
394 	 */
395 	data = read;
396 	if (addr > 0x7f) {
397 		/*
398 		 * If this is a 10bit request, the first address byte is
399 		 * 0b11110<b9><b8><r/w>.
400 		 */
401 		data |= 0xf0 | ((addr & 0x300) >> 7);
402 		sxitwi_write_4(sc, TWSI_DATA, data);
403 		error = sxitwi_wait(sc, 0, expect, flags);
404 		if (error)
405 			return error;
406 		/*
407 		 * The first address byte has been sent, now to send
408 		 * the second one.
409 		 */
410 		if (read)
411 			expect = STAT_SARBT_AR;
412 		else
413 			expect = STAT_SAWBT_AR;
414 		data = (uint8_t)addr;
415 	} else
416 		data |= (addr << 1);
417 
418 	sxitwi_write_4(sc, TWSI_DATA, data);
419 	return sxitwi_wait(sc, 0, expect, flags);
420 }
421 
422 int
423 sxitwi_read_byte(void *v, uint8_t *valp, int flags)
424 {
425 	struct sxitwi_softc *sc = v;
426 	int error;
427 
428 	if (flags & I2C_F_LAST)
429 		error = sxitwi_wait(sc, 0, STAT_MRRD_ANT, flags);
430 	else
431 		error = sxitwi_wait(sc, CONTROL_ACK, STAT_MRRD_AT, flags);
432 	if (!error)
433 		*valp = sxitwi_read_4(sc, TWSI_DATA);
434 	if ((flags & (I2C_F_LAST | I2C_F_STOP)) == (I2C_F_LAST | I2C_F_STOP))
435 		error = sxitwi_send_stop(sc, flags);
436 	return error;
437 }
438 
439 int
440 sxitwi_write_byte(void *v, uint8_t val, int flags)
441 {
442 	struct sxitwi_softc *sc = v;
443 	int error;
444 
445 	sxitwi_write_4(sc, TWSI_DATA, val);
446 	error = sxitwi_wait(sc, 0, STAT_MTDB_AR, flags);
447 	if (flags & I2C_F_STOP)
448 		sxitwi_send_stop(sc, flags);
449 	return error;
450 }
451 
452 int
453 sxitwi_wait(struct sxitwi_softc *sc, u_int control, u_int expect, int flags)
454 {
455 	u_int status;
456 	int timo, error = 0;
457 
458 	delay(5);
459 	if (!(flags & I2C_F_POLL))
460 		control |= CONTROL_INTEN;
461 	sxitwi_write_4(sc, TWSI_CONTROL, control | CONTROL_TWSIEN);
462 
463 	timo = 0;
464 	do {
465 		control = sxitwi_read_4(sc, TWSI_CONTROL);
466 		if (control & CONTROL_IFLG)
467 			break;
468 		if (flags & I2C_F_POLL)
469 			delay(TWSI_RETRY_DELAY);
470 		else {
471 			error = tsleep(&sc->sc_dev, PWAIT, "sxitwi", 100);
472 			if (error)
473 				return error;
474 		}
475 	} while (++timo < 1000000);
476 
477 	status = sxitwi_read_4(sc, TWSI_STATUS);
478 	if (status != expect)
479 		return EIO;
480 
481 	return error;
482 }
483