ralink_i2c.c revision 1.2 1 /* $NetBSD: ralink_i2c.c,v 1.2 2011/07/28 15:38:49 matt 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.2 2011/07/28 15:38:49 matt 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(struct device *, cfdata_t, void *);
78 static void ra_i2c_attach(struct device *, struct device *, 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_acquire_bus(void *, int);
90 void ra_i2c_release_bus(void *, int);
91 int ra_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t,
92 void *, size_t, int);
93 void ra_i2c_reset(ra_i2c_softc_t *);
94
95 CFATTACH_DECL_NEW(ri2c, sizeof(struct ra_i2c_softc),
96 ra_i2c_match, ra_i2c_attach, NULL, NULL);
97
98 unsigned int clkdiv = CLKDIV_VALUE;
99
100 static inline void
101 ra_i2c_busy_wait(ra_i2c_softc_t *sc)
102 {
103 for (int i=0; i < i2c_busy_loop; i++) {
104 uint32_t r;
105 r = bus_space_read_4(sc->sc_memt, sc->sc_i2c_memh,
106 RA_I2C_STATUS);
107 if ((r & I2C_STATUS_BUSY) == 0)
108 break;
109 }
110 }
111
112 int
113 ra_i2c_match(device_t parent, cfdata_t cf, void *aux)
114 {
115 return 1;
116 }
117
118
119 void
120 ra_i2c_attach(device_t parent, device_t self, void *aux)
121 {
122 ra_i2c_softc_t * const sc = device_private(self);
123 const struct mainbus_attach_args *ma = aux;
124 struct i2cbus_attach_args iba;
125 uint32_t r;
126 int error;
127
128 aprint_naive(": Ralink I2C controller\n");
129 aprint_normal(": Ralink I2C controller\n");
130
131 /* save out bus space tag */
132 sc->sc_memt = ma->ma_memt;
133
134 /* Map Sysctl registers */
135 if ((error = bus_space_map(ma->ma_memt, RA_SYSCTL_BASE, 0x10000,
136 0, &sc->sc_sy_memh)) != 0) {
137 aprint_error_dev(self, "unable to map Sysctl registers, "
138 "error=%d\n", error);
139 return;
140 }
141
142 /* map the I2C registers */
143 if ((error = bus_space_map(sc->sc_memt, RA_I2C_BASE, 0x100,
144 0, &sc->sc_i2c_memh)) != 0) {
145 aprint_error_dev(self, "unable to map registers, "
146 "error=%d\n", error);
147 bus_space_unmap(ma->ma_memt, sc->sc_sy_memh, 0x10000);
148 return;
149 }
150
151 /* Enable I2C block */
152 r = bus_space_read_4(sc->sc_memt, sc->sc_sy_memh,
153 RA_SYSCTL_GPIOMODE);
154 r &= ~GPIOMODE_I2C;
155 bus_space_write_4(sc->sc_memt, sc->sc_sy_memh,
156 RA_SYSCTL_GPIOMODE, r);
157
158 sc->sc_i2c.ic_cookie = sc;
159 sc->sc_i2c.ic_acquire_bus = ra_i2c_acquire_bus;
160 sc->sc_i2c.ic_release_bus = ra_i2c_release_bus;
161 sc->sc_i2c.ic_exec = ra_i2c_exec;
162
163 memset(&iba, 0, sizeof(iba));
164 iba.iba_type = I2C_TYPE_SMBUS;
165 iba.iba_tag = &sc->sc_i2c;
166 config_found(self, &iba, iicbus_print);
167 }
168
169
170
171 /*
172 * I2C API
173 */
174
175 /* Might not be needed. JCL. */
176 int
177 ra_i2c_acquire_bus(void *cookie, int flags)
178 {
179 /* nothing */
180 return 0;
181 }
182
183
184
185 /* Might not be needed. JCL. */
186 void
187 ra_i2c_release_bus(void *cookie, int flags)
188 {
189 /* nothing */
190 }
191
192 int
193 ra_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf,
194 size_t cmdlen, void *buf, size_t len, int flags)
195 {
196 ra_i2c_softc_t * const sc = cookie;
197
198 /*
199 * Make sure we only pass a seven-bit device address,
200 * as per I2C standard.
201 */
202 KASSERT(addr <= 127);
203 if (addr > 127)
204 return -1;
205
206 bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_DEVADDR,
207 addr);
208
209 ra_i2c_reset(sc);
210
211 /*
212 * Process the requested operation.
213 * There are four I2C operations of interest:
214 * - Write
215 * - Write with stop
216 * - Read
217 * - Read with stop
218 * Because the I2C block on the Ralink part generates stop markers
219 * at approprite places, based upon the byte count, the read and write
220 * with stop operations will rarely be needed. They are included here
221 * as placeholders, but haven't been implemented or tested.
222 */
223 switch(op) {
224 case I2C_OP_WRITE:
225 return i2c_write(sc, addr, cmdbuf, cmdlen);
226 break;
227 case I2C_OP_READ:
228 return i2c_read(sc, addr, buf, len);
229 break;
230 #ifdef NOTYET
231 case I2C_OP_WRITE_WITH_STOP:
232 i2c_write_stop(sc, addr, buf);
233 break;
234 case I2C_OP_READ_WITH_STOP:
235 i2c_read_stop(sc, addr, buf);
236 break;
237 #endif
238 default:
239 return -1; /* Illegal operation, error return. */
240 }
241
242 return 0;
243 }
244
245 static int
246 i2c_write(ra_i2c_softc_t *sc, u_long addr, const u_char *data,
247 u_long nbytes)
248 {
249 uint32_t r;
250 int i, j;
251
252 bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_DEVADDR,
253 addr);
254 bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_BYTECNT,
255 nbytes - 1);
256 bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_STARTXFR,
257 I2C_OP_WRITE);
258
259 for (i=0; i < nbytes; i++) {
260 for (j=0; j < max_ee_busy_loop; j++) {
261 r = bus_space_read_4(sc->sc_memt, sc->sc_i2c_memh,
262 RA_I2C_STATUS);
263 if ((r & I2C_STATUS_SDOEMPTY) != 0) {
264 bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh,
265 RA_I2C_DATAOUT, data[i]);
266 break;
267 }
268 }
269 #if 0
270 if ((r & I2C_STATUS_ACKERR) != 0) {
271 aprint_error_dev(sc->sc_dev, "ACK error in %s\n",
272 __func__);
273 return EAGAIN;
274 }
275 #endif
276 if (j == max_ee_busy_loop) {
277 aprint_error_dev(sc->sc_dev, "timeout error in %s\n",
278 __func__);
279 return EAGAIN;
280 }
281 }
282
283 ra_i2c_busy_wait(sc);
284
285 return 0;
286 }
287
288
289 static int
290 i2c_read(ra_i2c_softc_t *sc, u_long addr, u_char *data, u_long nbytes)
291 {
292 bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_DEVADDR,
293 addr);
294 bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_BYTECNT,
295 nbytes - 1);
296 bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_STARTXFR,
297 I2C_OP_READ);
298
299 for (u_int i = 0; i < nbytes; i++) {
300 u_long j;
301 uint32_t r;
302
303 for (j=0; j < max_ee_busy_loop; j++) {
304 r = bus_space_read_4(sc->sc_memt, sc->sc_i2c_memh,
305 RA_I2C_STATUS);
306 if ((r & I2C_STATUS_DATARDY) != 0) {
307 data[i] = bus_space_read_4(
308 sc->sc_memt, sc->sc_i2c_memh,
309 RA_I2C_DATAIN);
310 break;
311 }
312 }
313 #if 0
314 if ((r & I2C_STATUS_ACKERR) != 0) {
315 aprint_error_dev(sc->sc_dev, "ACK error in %s\n",
316 __func__);
317 return EAGAIN;
318 }
319 #endif
320 if (j == max_ee_busy_loop) {
321 aprint_error_dev(sc->sc_dev, "timeout error in %s\n",
322 __func__);
323 return EAGAIN;
324 }
325 }
326
327 ra_i2c_busy_wait(sc);
328
329 return 0;
330
331 }
332
333
334 #ifdef NOTYET
335 static void
336 i2c_write_stop(ra_i2c_softc_t *sc, u_long address, u_char *data)
337 {
338 /* unimplemented */
339 }
340
341 static void
342 i2c_read_stop(ra_i2c_softc_t *sc, u_long address, u_char *data)
343 {
344 /* unimplemented */
345 }
346 #endif
347
348 void
349 ra_i2c_reset(ra_i2c_softc_t *sc)
350 {
351 uint32_t r;
352
353 /* reset i2c block */
354 r = bus_space_read_4(sc->sc_memt, sc->sc_sy_memh, RA_SYSCTL_RST);
355 bus_space_write_4(sc->sc_memt, sc->sc_sy_memh, RA_SYSCTL_RST,
356 r | RST_I2C);
357 bus_space_write_4(sc->sc_memt, sc->sc_sy_memh, RA_SYSCTL_RST, r);
358
359 r = I2C_CONFIG_ADDRLEN(I2C_CONFIG_ADDRLEN_8) |
360 I2C_CONFIG_DEVADLEN(I2C_CONFIG_DEVADLEN_7) |
361 I2C_CONFIG_ADDRDIS;
362 bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_CONFIG, r);
363
364 /*
365 * Set the I2C clock divider. Appears to be set to 200,000,
366 * which is strange, as I2C is 100K/400K/3.?M bps.
367 */
368 bus_space_write_4(sc->sc_memt, sc->sc_i2c_memh, RA_I2C_CLKDIV,
369 clkdiv);
370 }
371