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
67typedef 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
76static int  ra_i2c_match(device_t, cfdata_t, void *);
77static void ra_i2c_attach(device_t, device_t, void *);
78
79/* RT3052 I2C functions */
80static int  i2c_write(ra_i2c_softc_t *, u_long, const u_char *, u_long);
81static int  i2c_read(ra_i2c_softc_t *, u_long, u_char *, u_long);
82#ifdef NOTYET
83static void i2c_write_stop(ra_i2c_softc_t *, u_long, u_char *);
84static void i2c_read_stop(ra_i2c_softc_t *, u_long, u_char *);
85#endif
86
87/* i2c driver functions */
88int  ra_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t,
89	void *, size_t, int);
90void ra_i2c_reset(ra_i2c_softc_t *);
91
92CFATTACH_DECL_NEW(ri2c, sizeof(struct ra_i2c_softc),
93	ra_i2c_match, ra_i2c_attach, NULL, NULL);
94
95unsigned int clkdiv = CLKDIV_VALUE;
96
97static inline void
98ra_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
109int
110ra_i2c_match(device_t parent, cfdata_t cf, void *aux)
111{
112	return 1;
113}
114
115
116void
117ra_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
170int
171ra_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
223static int
224i2c_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
267static int
268i2c_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
313static void
314i2c_write_stop(ra_i2c_softc_t *sc, u_long address, u_char *data)
315{
316	/* unimplemented */
317}
318
319static void
320i2c_read_stop(ra_i2c_softc_t *sc, u_long address, u_char *data)
321{
322	/* unimplemented */
323}
324#endif
325
326void
327ra_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