xref: /netbsd-src/sys/arch/mips/ralink/ralink_i2c.c (revision 9fb66d812c00ebfb445c0b47dea128f32aa6fe96)
1 /*	$NetBSD: ralink_i2c.c,v 1.4 2019/12/22 23:23:31 thorpej Exp $	*/
2 /*-
3  * Copyright (c) 2011 CradlePoint Technology, Inc.
4  * All rights reserved.
5  *
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  *
16  * THIS SOFTWARE IS PROVIDED BY CRADLEPOINT TECHNOLOGY, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /* ra_i2c.c - Ralink i2c 3052 driver */
30 
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: ralink_i2c.c,v 1.4 2019/12/22 23:23:31 thorpej Exp $");
33 
34 #include <sys/param.h>
35 #include <sys/bus.h>
36 #include <sys/device.h>
37 #include <sys/errno.h>
38 #include <sys/kernel.h>
39 #include <sys/malloc.h>
40 #include <sys/proc.h>
41 #include <sys/systm.h>
42 
43 #include <dev/i2c/i2cvar.h>
44 
45 #include <mips/ralink/ralink_var.h>
46 #include <mips/ralink/ralink_reg.h>
47 
48 #if 0
49 /*
50  * Defined for the Ralink 3050, w/320MHz CPU:  milage may vary.
51  * Set the I2C clock to 100K bps (low speed) transfer rate.
52  * Value is based upon the forms defined in the Ralink reference document
53  * for RT3050, page 53.  JCL.
54  */
55 #define CLKDIV_VALUE 533
56 #endif
57 
58 /*
59  * Slow the I2C bus clock to 12.5 KHz to work around the misbehavior
60  * of the TI part.
61  */
62 #define CLKDIV_VALUE 4264
63 
64 #define i2c_busy_loop		(clkdiv*30)
65 #define max_ee_busy_loop	(clkdiv*25)
66 
67 
68 typedef struct ra_i2c_softc {
69 	device_t		sc_dev;
70 	struct i2c_controller	sc_i2c;
71 	bus_space_tag_t		sc_memt;
72 	bus_space_handle_t	sc_i2c_memh;
73 	bus_space_handle_t	sc_sy_memh;
74 } ra_i2c_softc_t;
75 
76 
77 static int  ra_i2c_match(device_t, cfdata_t, void *);
78 static void ra_i2c_attach(device_t, device_t, void *);
79 
80 /* RT3052 I2C functions */
81 static int  i2c_write(ra_i2c_softc_t *, u_long, const u_char *, u_long);
82 static int  i2c_read(ra_i2c_softc_t *, u_long, u_char *, u_long);
83 #ifdef NOTYET
84 static void i2c_write_stop(ra_i2c_softc_t *, u_long, u_char *);
85 static void i2c_read_stop(ra_i2c_softc_t *, u_long, u_char *);
86 #endif
87 
88 /* i2c driver functions */
89 int  ra_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t,
90 	void *, size_t, int);
91 void ra_i2c_reset(ra_i2c_softc_t *);
92 
93 CFATTACH_DECL_NEW(ri2c, sizeof(struct ra_i2c_softc),
94 	ra_i2c_match, ra_i2c_attach, NULL, NULL);
95 
96 unsigned int clkdiv = CLKDIV_VALUE;
97 
98 static inline void
99 ra_i2c_busy_wait(ra_i2c_softc_t *sc)
100 {
101 	for (int i=0; i < i2c_busy_loop; i++) {
102 		uint32_t r;
103 		r = bus_space_read_4(sc->sc_memt, sc->sc_i2c_memh,
104 			RA_I2C_STATUS);
105 		if ((r & I2C_STATUS_BUSY) == 0)
106 			break;
107 	}
108 }
109 
110 int
111 ra_i2c_match(device_t parent, cfdata_t cf, void *aux)
112 {
113 	return 1;
114 }
115 
116 
117 void
118 ra_i2c_attach(device_t parent, device_t self, void *aux)
119 {
120 	ra_i2c_softc_t * const sc = device_private(self);
121 	const struct mainbus_attach_args *ma = aux;
122 	struct i2cbus_attach_args iba;
123 	uint32_t r;
124 	int error;
125 
126 	aprint_naive(": Ralink I2C controller\n");
127 	aprint_normal(": Ralink I2C controller\n");
128 
129 	/* save out bus space tag */
130 	sc->sc_memt = ma->ma_memt;
131 
132 	/* Map Sysctl registers */
133 	if ((error = bus_space_map(ma->ma_memt, RA_SYSCTL_BASE, 0x10000,
134 	    0, &sc->sc_sy_memh)) != 0) {
135 		aprint_error_dev(self, "unable to map Sysctl registers, "
136 			"error=%d\n", error);
137 		return;
138 	}
139 
140 	/* map the I2C registers */
141 	if ((error = bus_space_map(sc->sc_memt, RA_I2C_BASE, 0x100,
142 	    0, &sc->sc_i2c_memh)) != 0) {
143 		aprint_error_dev(self, "unable to map registers, "
144 			"error=%d\n", error);
145 		bus_space_unmap(ma->ma_memt, sc->sc_sy_memh, 0x10000);
146 		return;
147 	}
148 
149 	/*  Enable I2C block */
150 	r = bus_space_read_4(sc->sc_memt, sc->sc_sy_memh,
151 		RA_SYSCTL_GPIOMODE);
152 	r &= ~GPIOMODE_I2C;
153 	bus_space_write_4(sc->sc_memt, sc->sc_sy_memh,
154 		RA_SYSCTL_GPIOMODE, r);
155 
156 	iic_tag_init(&sc->sc_i2c);
157 	sc->sc_i2c.ic_cookie = sc;
158 	sc->sc_i2c.ic_exec = ra_i2c_exec;
159 
160 	memset(&iba, 0, sizeof(iba));
161 	iba.iba_tag = &sc->sc_i2c;
162 	config_found(self, &iba, iicbus_print);
163 }
164 
165 
166 
167 /*
168  * I2C API
169  */
170 
171 int
172 ra_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf,
173 	size_t cmdlen, void *buf, size_t len, int flags)
174 {
175 	ra_i2c_softc_t * const sc = cookie;
176 
177 	/*
178 	 * Make sure we only pass a seven-bit device address,
179 	 * as per I2C standard.
180 	 */
181 	KASSERT(addr <= 127);
182 	if (addr > 127)
183 		return -1;
184 
185 	bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_DEVADDR,
186 		addr);
187 
188 	ra_i2c_reset(sc);
189 
190 	/*
191 	 * Process the requested operation.
192 	 * There are four I2C operations of interest:
193 	 *   - Write
194 	 *   - Write with stop
195 	 *   - Read
196 	 *   - Read with stop
197 	 * Because the I2C block on the Ralink part generates stop markers
198 	 * at approprite places, based upon the byte count, the read and write
199 	 * with stop operations will rarely be needed.  They are included here
200 	 * as placeholders, but haven't been implemented or tested.
201 	 */
202 	switch(op) {
203 	case  I2C_OP_WRITE:
204 		return i2c_write(sc, addr, cmdbuf, cmdlen);
205 		break;
206 	case I2C_OP_READ:
207 		return i2c_read(sc, addr, buf, len);
208 		break;
209 #ifdef NOTYET
210 	case I2C_OP_WRITE_WITH_STOP:
211 		i2c_write_stop(sc, addr, buf);
212 		break;
213 	case I2C_OP_READ_WITH_STOP:
214 		i2c_read_stop(sc, addr, buf);
215 		break;
216 #endif
217 	default:
218 		return -1;  /* Illegal operation, error return. */
219 	}
220 
221 	return 0;
222 }
223 
224 static int
225 i2c_write(ra_i2c_softc_t *sc, u_long addr, const u_char *data,
226 	u_long nbytes)
227 {
228 	uint32_t r;
229 	int i, j;
230 
231 	bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_DEVADDR,
232 		addr);
233 	bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_BYTECNT,
234 		nbytes - 1);
235 	bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_STARTXFR,
236 		I2C_OP_WRITE);
237 
238 	for (i=0; i < nbytes; i++) {
239 		for (j=0; j < max_ee_busy_loop; j++) {
240 			r = bus_space_read_4(sc->sc_memt, sc->sc_i2c_memh,
241 				RA_I2C_STATUS);
242 			if ((r & I2C_STATUS_SDOEMPTY) != 0) {
243 				bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh,
244 					RA_I2C_DATAOUT, data[i]);
245 				break;
246 			}
247 		}
248 #if 0
249 		if ((r & I2C_STATUS_ACKERR) != 0) {
250 			aprint_error_dev(sc->sc_dev, "ACK error in %s\n",
251 				__func__);
252 			return EAGAIN;
253 		}
254 #endif
255 		if (j == max_ee_busy_loop) {
256 			aprint_error_dev(sc->sc_dev, "timeout error in %s\n",
257 				__func__);
258 			return EAGAIN;
259 		}
260 	}
261 
262 	ra_i2c_busy_wait(sc);
263 
264 	return 0;
265 }
266 
267 
268 static int
269 i2c_read(ra_i2c_softc_t *sc, u_long addr, u_char *data, u_long nbytes)
270 {
271 	bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_DEVADDR,
272 		addr);
273 	bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_BYTECNT,
274 		nbytes - 1);
275 	bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_STARTXFR,
276 		I2C_OP_READ);
277 
278 	for (u_int i = 0; i < nbytes; i++) {
279 		u_long j;
280 		uint32_t r;
281 
282 		for (j=0; j < max_ee_busy_loop; j++) {
283 			r = bus_space_read_4(sc->sc_memt, sc->sc_i2c_memh,
284 				RA_I2C_STATUS);
285 			if ((r & I2C_STATUS_DATARDY) != 0) {
286 				data[i] = bus_space_read_4(
287 						sc->sc_memt, sc->sc_i2c_memh,
288 						RA_I2C_DATAIN);
289 				break;
290 			}
291 		}
292 #if 0
293 		if ((r & I2C_STATUS_ACKERR) != 0) {
294 			aprint_error_dev(sc->sc_dev, "ACK error in %s\n",
295 				__func__);
296 			return EAGAIN;
297 		}
298 #endif
299 		if (j == max_ee_busy_loop) {
300 			aprint_error_dev(sc->sc_dev, "timeout error in %s\n",
301 				__func__);
302 			return EAGAIN;
303 		}
304 	}
305 
306 	ra_i2c_busy_wait(sc);
307 
308 	return 0;
309 
310 }
311 
312 
313 #ifdef NOTYET
314 static void
315 i2c_write_stop(ra_i2c_softc_t *sc, u_long address, u_char *data)
316 {
317 	/* unimplemented */
318 }
319 
320 static void
321 i2c_read_stop(ra_i2c_softc_t *sc, u_long address, u_char *data)
322 {
323 	/* unimplemented */
324 }
325 #endif
326 
327 void
328 ra_i2c_reset(ra_i2c_softc_t *sc)
329 {
330 	uint32_t r;
331 
332 	/* reset i2c block */
333 	r = bus_space_read_4(sc->sc_memt, sc->sc_sy_memh, RA_SYSCTL_RST);
334 	bus_space_write_4(sc->sc_memt, sc->sc_sy_memh, RA_SYSCTL_RST,
335 		r | RST_I2C);
336 	bus_space_write_4(sc->sc_memt, sc->sc_sy_memh, RA_SYSCTL_RST, r);
337 
338 	r = I2C_CONFIG_ADDRLEN(I2C_CONFIG_ADDRLEN_8) |
339 	    I2C_CONFIG_DEVADLEN(I2C_CONFIG_DEVADLEN_7) |
340 	    I2C_CONFIG_ADDRDIS;
341 	bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_CONFIG, r);
342 
343 	/*
344 	 * Set the I2C clock divider.  Appears to be set to 200,000,
345 	 * which is strange, as I2C is 100K/400K/3.?M bps.
346 	 */
347 	bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_CLKDIV,
348 		clkdiv);
349 }
350