1/*	$NetBSD: ralink_i2c.c,v 1.1.2.1 2011/07/01 05:45:45 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.1.2.1 2011/07/01 05:45:45 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
68typedef 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
77static int  ra_i2c_match(struct device *, cfdata_t, void *);
78static void ra_i2c_attach(struct device *, struct device *, void *);
79
80/* RT3052 I2C functions */
81static int  i2c_write(ra_i2c_softc_t *, u_long, const u_char *, u_long);
82static int  i2c_read(ra_i2c_softc_t *, u_long, u_char *, u_long);
83#ifdef NOTYET
84static void i2c_write_stop(ra_i2c_softc_t *, u_long, u_char *);
85static void i2c_read_stop(ra_i2c_softc_t *, u_long, u_char *);
86#endif
87
88/* i2c driver functions */
89int  ra_i2c_acquire_bus(void *, int);
90void ra_i2c_release_bus(void *, int);
91int  ra_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t,
92	void *, size_t, int);
93void ra_i2c_reset(ra_i2c_softc_t *);
94
95CFATTACH_DECL_NEW(ri2c, sizeof(struct ra_i2c_softc),
96	ra_i2c_match, ra_i2c_attach, NULL, NULL);
97
98unsigned int clkdiv = CLKDIV_VALUE;
99
100static inline void
101ra_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
112int
113ra_i2c_match(device_t parent, cfdata_t cf, void *aux)
114{
115	return 1;
116}
117
118
119void
120ra_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. */
176int
177ra_i2c_acquire_bus(void *cookie, int flags)
178{
179	/* nothing */
180	return 0;
181}
182
183
184
185/* Might not be needed.  JCL. */
186void
187ra_i2c_release_bus(void *cookie, int flags)
188{
189	/* nothing */
190}
191
192int
193ra_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
245static int
246i2c_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
289static int
290i2c_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
335static void
336i2c_write_stop(ra_i2c_softc_t *sc, u_long address, u_char *data)
337{
338	/* unimplemented */
339}
340
341static void
342i2c_read_stop(ra_i2c_softc_t *sc, u_long address, u_char *data)
343{
344	/* unimplemented */
345}
346#endif
347
348void
349ra_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