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