mv_twsi.c revision 295622
1/*-
2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
3 * All rights reserved.
4 *
5 * Developed by Semihalf.
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 * 3. Neither the name of MARVELL nor the names of contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * Driver for the TWSI (aka I2C, aka IIC) bus controller found on Marvell
34 * SoCs. Supports master operation only, and works in polling mode.
35 *
36 * Calls to DELAY() are needed per Application Note AN-179 "TWSI Software
37 * Guidelines for Discovery(TM), Horizon (TM) and Feroceon(TM) Devices".
38 */
39
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: head/sys/dev/iicbus/twsi/twsi.c 295622 2016-02-14 23:51:13Z andrew $");
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/bus.h>
46#include <sys/kernel.h>
47#include <sys/module.h>
48#include <sys/resource.h>
49
50#include <machine/_inttypes.h>
51#include <machine/bus.h>
52#include <machine/resource.h>
53
54#include <sys/rman.h>
55
56#include <sys/lock.h>
57#include <sys/mutex.h>
58
59#include <dev/iicbus/iiconf.h>
60#include <dev/iicbus/iicbus.h>
61#include <dev/fdt/fdt_common.h>
62#include <dev/ofw/ofw_bus.h>
63#include <dev/ofw/ofw_bus_subr.h>
64
65#include <arm/mv/mvvar.h>
66
67#include "iicbus_if.h"
68
69#define MV_TWSI_NAME		"twsi"
70#define	IICBUS_DEVNAME		"iicbus"
71
72#define TWSI_SLAVE_ADDR		0x00
73#define TWSI_EXT_SLAVE_ADDR	0x10
74#define TWSI_DATA		0x04
75
76#define TWSI_CONTROL		0x08
77#define TWSI_CONTROL_ACK	(1 << 2)
78#define TWSI_CONTROL_IFLG	(1 << 3)
79#define TWSI_CONTROL_STOP	(1 << 4)
80#define TWSI_CONTROL_START	(1 << 5)
81#define TWSI_CONTROL_TWSIEN	(1 << 6)
82#define TWSI_CONTROL_INTEN	(1 << 7)
83
84#define TWSI_STATUS			0x0c
85#define TWSI_STATUS_START		0x08
86#define TWSI_STATUS_RPTD_START		0x10
87#define TWSI_STATUS_ADDR_W_ACK		0x18
88#define TWSI_STATUS_DATA_WR_ACK		0x28
89#define TWSI_STATUS_ADDR_R_ACK		0x40
90#define TWSI_STATUS_DATA_RD_ACK		0x50
91#define TWSI_STATUS_DATA_RD_NOACK	0x58
92
93#define TWSI_BAUD_RATE		0x0c
94#define	TWSI_BAUD_RATE_PARAM(M,N)	((((M) << 3) | ((N) & 0x7)) & 0x7f)
95#define	TWSI_BAUD_RATE_RAW(C,M,N)	((C)/((10*(M+1))<<(N+1)))
96#define	TWSI_BAUD_RATE_SLOW		50000	/* 50kHz */
97#define	TWSI_BAUD_RATE_FAST		100000	/* 100kHz */
98
99#define TWSI_SOFT_RESET		0x1c
100
101#define TWSI_DEBUG
102#undef TWSI_DEBUG
103
104#ifdef  TWSI_DEBUG
105#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0)
106#else
107#define debugf(fmt, args...)
108#endif
109
110struct mv_twsi_softc {
111	device_t	dev;
112	struct resource	*res[1];	/* SYS_RES_MEMORY */
113	struct mtx	mutex;
114	device_t	iicbus;
115};
116
117static struct mv_twsi_baud_rate {
118	uint32_t	raw;
119	int		param;
120	int		m;
121	int		n;
122} baud_rate[IIC_FASTEST + 1];
123
124static int mv_twsi_probe(device_t);
125static int mv_twsi_attach(device_t);
126static int mv_twsi_detach(device_t);
127
128static int mv_twsi_reset(device_t dev, u_char speed, u_char addr,
129    u_char *oldaddr);
130static int mv_twsi_repeated_start(device_t dev, u_char slave, int timeout);
131static int mv_twsi_start(device_t dev, u_char slave, int timeout);
132static int mv_twsi_stop(device_t dev);
133static int mv_twsi_read(device_t dev, char *buf, int len, int *read, int last,
134    int delay);
135static int mv_twsi_write(device_t dev, const char *buf, int len, int *sent,
136    int timeout);
137
138static struct resource_spec res_spec[] = {
139	{ SYS_RES_MEMORY, 0, RF_ACTIVE },
140	{ -1, 0 }
141};
142
143static struct ofw_compat_data compat_data[] = {
144	{ "mrvl,twsi",			true },
145	{ "marvell,mv64xxx-i2c",	true },
146	{ NULL,				false }
147};
148
149static device_method_t mv_twsi_methods[] = {
150	/* device interface */
151	DEVMETHOD(device_probe,		mv_twsi_probe),
152	DEVMETHOD(device_attach,	mv_twsi_attach),
153	DEVMETHOD(device_detach,	mv_twsi_detach),
154
155	/* iicbus interface */
156	DEVMETHOD(iicbus_callback, iicbus_null_callback),
157	DEVMETHOD(iicbus_repeated_start, mv_twsi_repeated_start),
158	DEVMETHOD(iicbus_start,		mv_twsi_start),
159	DEVMETHOD(iicbus_stop,		mv_twsi_stop),
160	DEVMETHOD(iicbus_write,		mv_twsi_write),
161	DEVMETHOD(iicbus_read,		mv_twsi_read),
162	DEVMETHOD(iicbus_reset,		mv_twsi_reset),
163	DEVMETHOD(iicbus_transfer,	iicbus_transfer_gen),
164	{ 0, 0 }
165};
166
167static devclass_t mv_twsi_devclass;
168
169static driver_t mv_twsi_driver = {
170	MV_TWSI_NAME,
171	mv_twsi_methods,
172	sizeof(struct mv_twsi_softc),
173};
174
175DRIVER_MODULE(twsi, simplebus, mv_twsi_driver, mv_twsi_devclass, 0, 0);
176DRIVER_MODULE(iicbus, twsi, iicbus_driver, iicbus_devclass, 0, 0);
177MODULE_DEPEND(twsi, iicbus, 1, 1, 1);
178
179static __inline uint32_t
180TWSI_READ(struct mv_twsi_softc *sc, bus_size_t off)
181{
182
183	return (bus_read_4(sc->res[0], off));
184}
185
186static __inline void
187TWSI_WRITE(struct mv_twsi_softc *sc, bus_size_t off, uint32_t val)
188{
189
190	bus_write_4(sc->res[0], off, val);
191}
192
193static __inline void
194twsi_control_clear(struct mv_twsi_softc *sc, uint32_t mask)
195{
196	uint32_t val;
197
198	val = TWSI_READ(sc, TWSI_CONTROL);
199	val &= ~mask;
200	TWSI_WRITE(sc, TWSI_CONTROL, val);
201}
202
203static __inline void
204twsi_control_set(struct mv_twsi_softc *sc, uint32_t mask)
205{
206	uint32_t val;
207
208	val = TWSI_READ(sc, TWSI_CONTROL);
209	val |= mask;
210	TWSI_WRITE(sc, TWSI_CONTROL, val);
211}
212
213static __inline void
214twsi_clear_iflg(struct mv_twsi_softc *sc)
215{
216
217	DELAY(1000);
218	twsi_control_clear(sc, TWSI_CONTROL_IFLG);
219	DELAY(1000);
220}
221
222
223/*
224 * timeout given in us
225 * returns
226 *   0 on sucessfull mask change
227 *   non-zero on timeout
228 */
229static int
230twsi_poll_ctrl(struct mv_twsi_softc *sc, int timeout, uint32_t mask)
231{
232
233	timeout /= 10;
234	while (!(TWSI_READ(sc, TWSI_CONTROL) & mask)) {
235		DELAY(10);
236		if (--timeout < 0)
237			return (timeout);
238	}
239	return (0);
240}
241
242
243/*
244 * 'timeout' is given in us. Note also that timeout handling is not exact --
245 * twsi_locked_start() total wait can be more than 2 x timeout
246 * (twsi_poll_ctrl() is called twice). 'mask' can be either TWSI_STATUS_START
247 * or TWSI_STATUS_RPTD_START
248 */
249static int
250twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask,
251    u_char slave, int timeout)
252{
253	int read_access, iflg_set = 0;
254	uint32_t status;
255
256	mtx_assert(&sc->mutex, MA_OWNED);
257
258	if (mask == TWSI_STATUS_RPTD_START)
259		/* read IFLG to know if it should be cleared later; from NBSD */
260		iflg_set = TWSI_READ(sc, TWSI_CONTROL) & TWSI_CONTROL_IFLG;
261
262	twsi_control_set(sc, TWSI_CONTROL_START);
263
264	if (mask == TWSI_STATUS_RPTD_START && iflg_set) {
265		debugf("IFLG set, clearing\n");
266		twsi_clear_iflg(sc);
267	}
268
269	/*
270	 * Without this delay we timeout checking IFLG if the timeout is 0.
271	 * NBSD driver always waits here too.
272	 */
273	DELAY(1000);
274
275	if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
276		debugf("timeout sending %sSTART condition\n",
277		    mask == TWSI_STATUS_START ? "" : "repeated ");
278		return (IIC_ETIMEOUT);
279	}
280
281	status = TWSI_READ(sc, TWSI_STATUS);
282	if (status != mask) {
283		debugf("wrong status (%02x) after sending %sSTART condition\n",
284		    status, mask == TWSI_STATUS_START ? "" : "repeated ");
285		return (IIC_ESTATUS);
286	}
287
288	TWSI_WRITE(sc, TWSI_DATA, slave);
289	DELAY(1000);
290	twsi_clear_iflg(sc);
291
292	if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
293		debugf("timeout sending slave address\n");
294		return (IIC_ETIMEOUT);
295	}
296
297	read_access = (slave & 0x1) ? 1 : 0;
298	status = TWSI_READ(sc, TWSI_STATUS);
299	if (status != (read_access ?
300	    TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) {
301		debugf("no ACK (status: %02x) after sending slave address\n",
302		    status);
303		return (IIC_ENOACK);
304	}
305
306	return (IIC_NOERR);
307}
308
309static int
310mv_twsi_probe(device_t dev)
311{
312
313	if (!ofw_bus_status_okay(dev))
314		return (ENXIO);
315
316	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
317		return (ENXIO);
318
319	device_set_desc(dev, "Marvell Integrated I2C Bus Controller");
320	return (BUS_PROBE_DEFAULT);
321}
322
323#define	ABSSUB(a,b)	(((a) > (b)) ? (a) - (b) : (b) - (a))
324static void
325mv_twsi_cal_baud_rate(const uint32_t target, struct mv_twsi_baud_rate *rate)
326{
327	uint32_t clk, cur, diff, diff0;
328	int m, n, m0, n0;
329
330	/* Calculate baud rate. */
331	m0 = n0 = 4;	/* Default values on reset */
332	diff0 = 0xffffffff;
333	clk = get_tclk();
334
335	for (n = 0; n < 8; n++) {
336		for (m = 0; m < 16; m++) {
337			cur = TWSI_BAUD_RATE_RAW(clk,m,n);
338			diff = ABSSUB(target, cur);
339			if (diff < diff0) {
340				m0 = m;
341				n0 = n;
342				diff0 = diff;
343			}
344		}
345	}
346	rate->raw = TWSI_BAUD_RATE_RAW(clk, m0, n0);
347	rate->param = TWSI_BAUD_RATE_PARAM(m0, n0);
348	rate->m = m0;
349	rate->n = n0;
350}
351
352static int
353mv_twsi_attach(device_t dev)
354{
355	struct mv_twsi_softc *sc;
356	phandle_t child, iicbusnode;
357	device_t childdev;
358	struct iicbus_ivar *devi;
359	char dname[32];	/* 32 is taken from struct u_device */
360	uint32_t paddr;
361	int len, error;
362
363	sc = device_get_softc(dev);
364	sc->dev = dev;
365	bzero(baud_rate, sizeof(baud_rate));
366
367	mtx_init(&sc->mutex, device_get_nameunit(dev), MV_TWSI_NAME, MTX_DEF);
368
369	/* Allocate IO resources */
370	if (bus_alloc_resources(dev, res_spec, sc->res)) {
371		device_printf(dev, "could not allocate resources\n");
372		mv_twsi_detach(dev);
373		return (ENXIO);
374	}
375
376	mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_SLOW, &baud_rate[IIC_SLOW]);
377	mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_FAST, &baud_rate[IIC_FAST]);
378	if (bootverbose)
379		device_printf(dev, "calculated baud rates are:\n"
380		    " %" PRIu32 " kHz (M=%d, N=%d) for slow,\n"
381		    " %" PRIu32 " kHz (M=%d, N=%d) for fast.\n",
382		    baud_rate[IIC_SLOW].raw / 1000,
383		    baud_rate[IIC_SLOW].m,
384		    baud_rate[IIC_SLOW].n,
385		    baud_rate[IIC_FAST].raw / 1000,
386		    baud_rate[IIC_FAST].m,
387		    baud_rate[IIC_FAST].n);
388
389	sc->iicbus = device_add_child(dev, IICBUS_DEVNAME, -1);
390	if (sc->iicbus == NULL) {
391		device_printf(dev, "could not add iicbus child\n");
392		mv_twsi_detach(dev);
393		return (ENXIO);
394	}
395	/* Attach iicbus. */
396	bus_generic_attach(dev);
397
398	iicbusnode = 0;
399	/* Find iicbus as the child devices in the device tree. */
400	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
401	    child = OF_peer(child)) {
402		len = OF_getproplen(child, "model");
403		if (len <= 0 || len > sizeof(dname))
404			continue;
405		error = OF_getprop(child, "model", &dname, len);
406		if (error == -1)
407			continue;
408		len = strlen(dname);
409		if (len == strlen(IICBUS_DEVNAME) &&
410		    strncasecmp(dname, IICBUS_DEVNAME, len) == 0) {
411			iicbusnode = child;
412			break;
413		}
414	}
415	if (iicbusnode == 0)
416		goto attach_end;
417
418	/* Attach child devices onto iicbus. */
419	for (child = OF_child(iicbusnode); child != 0; child = OF_peer(child)) {
420		/* Get slave address. */
421		error = OF_getprop(child, "i2c-address", &paddr, sizeof(paddr));
422		if (error == -1)
423			error = OF_getprop(child, "reg", &paddr, sizeof(paddr));
424		if (error == -1)
425			continue;
426
427		/* Get device driver name. */
428		len = OF_getproplen(child, "model");
429		if (len <= 0 || len > sizeof(dname))
430			continue;
431		OF_getprop(child, "model", &dname, len);
432
433		if (bootverbose)
434			device_printf(dev, "adding a device %s at %d.\n",
435			    dname, fdt32_to_cpu(paddr));
436		childdev = BUS_ADD_CHILD(sc->iicbus, 0, dname, -1);
437		devi = IICBUS_IVAR(childdev);
438		devi->addr = fdt32_to_cpu(paddr);
439	}
440
441attach_end:
442	bus_generic_attach(sc->iicbus);
443
444	return (0);
445}
446
447static int
448mv_twsi_detach(device_t dev)
449{
450	struct mv_twsi_softc *sc;
451	int rv;
452
453	sc = device_get_softc(dev);
454
455	if ((rv = bus_generic_detach(dev)) != 0)
456		return (rv);
457
458	if (sc->iicbus != NULL)
459		if ((rv = device_delete_child(dev, sc->iicbus)) != 0)
460			return (rv);
461
462	bus_release_resources(dev, res_spec, sc->res);
463
464	mtx_destroy(&sc->mutex);
465	return (0);
466}
467
468/*
469 * Only slave mode supported, disregard [old]addr
470 */
471static int
472mv_twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
473{
474	struct mv_twsi_softc *sc;
475	uint32_t param;
476
477	sc = device_get_softc(dev);
478
479	switch (speed) {
480	case IIC_SLOW:
481	case IIC_FAST:
482		param = baud_rate[speed].param;
483		break;
484	case IIC_FASTEST:
485	case IIC_UNKNOWN:
486	default:
487		param = baud_rate[IIC_FAST].param;
488		break;
489	}
490
491	mtx_lock(&sc->mutex);
492	TWSI_WRITE(sc, TWSI_SOFT_RESET, 0x0);
493	DELAY(2000);
494	TWSI_WRITE(sc, TWSI_BAUD_RATE, param);
495	TWSI_WRITE(sc, TWSI_CONTROL, TWSI_CONTROL_TWSIEN | TWSI_CONTROL_ACK);
496	DELAY(1000);
497	mtx_unlock(&sc->mutex);
498
499	return (0);
500}
501
502/*
503 * timeout is given in us
504 */
505static int
506mv_twsi_repeated_start(device_t dev, u_char slave, int timeout)
507{
508	struct mv_twsi_softc *sc;
509	int rv;
510
511	sc = device_get_softc(dev);
512
513	mtx_lock(&sc->mutex);
514	rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave,
515	    timeout);
516	mtx_unlock(&sc->mutex);
517
518	if (rv) {
519		mv_twsi_stop(dev);
520		return (rv);
521	} else
522		return (IIC_NOERR);
523}
524
525/*
526 * timeout is given in us
527 */
528static int
529mv_twsi_start(device_t dev, u_char slave, int timeout)
530{
531	struct mv_twsi_softc *sc;
532	int rv;
533
534	sc = device_get_softc(dev);
535
536	mtx_lock(&sc->mutex);
537	rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout);
538	mtx_unlock(&sc->mutex);
539
540	if (rv) {
541		mv_twsi_stop(dev);
542		return (rv);
543	} else
544		return (IIC_NOERR);
545}
546
547static int
548mv_twsi_stop(device_t dev)
549{
550	struct mv_twsi_softc *sc;
551
552	sc = device_get_softc(dev);
553
554	mtx_lock(&sc->mutex);
555	twsi_control_set(sc, TWSI_CONTROL_STOP);
556	DELAY(1000);
557	twsi_clear_iflg(sc);
558	mtx_unlock(&sc->mutex);
559
560	return (IIC_NOERR);
561}
562
563static int
564mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay)
565{
566	struct mv_twsi_softc *sc;
567	uint32_t status;
568	int last_byte, rv;
569
570	sc = device_get_softc(dev);
571
572	mtx_lock(&sc->mutex);
573	*read = 0;
574	while (*read < len) {
575		/*
576		 * Check if we are reading last byte of the last buffer,
577		 * do not send ACK then, per I2C specs
578		 */
579		last_byte = ((*read == len - 1) && last) ? 1 : 0;
580		if (last_byte)
581			twsi_control_clear(sc, TWSI_CONTROL_ACK);
582		else
583			twsi_control_set(sc, TWSI_CONTROL_ACK);
584
585		DELAY (1000);
586		twsi_clear_iflg(sc);
587
588		if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) {
589			debugf("timeout reading data\n");
590			rv = IIC_ETIMEOUT;
591			goto out;
592		}
593
594		status = TWSI_READ(sc, TWSI_STATUS);
595		if (status != (last_byte ?
596		    TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) {
597			debugf("wrong status (%02x) while reading\n", status);
598			rv = IIC_ESTATUS;
599			goto out;
600		}
601
602		*buf++ = TWSI_READ(sc, TWSI_DATA);
603		(*read)++;
604	}
605	rv = IIC_NOERR;
606out:
607	mtx_unlock(&sc->mutex);
608	return (rv);
609}
610
611static int
612mv_twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout)
613{
614	struct mv_twsi_softc *sc;
615	uint32_t status;
616	int rv;
617
618	sc = device_get_softc(dev);
619
620	mtx_lock(&sc->mutex);
621	*sent = 0;
622	while (*sent < len) {
623		TWSI_WRITE(sc, TWSI_DATA, *buf++);
624
625		twsi_clear_iflg(sc);
626		if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
627			debugf("timeout writing data\n");
628			rv = IIC_ETIMEOUT;
629			goto out;
630		}
631
632		status = TWSI_READ(sc, TWSI_STATUS);
633		if (status != TWSI_STATUS_DATA_WR_ACK) {
634			debugf("wrong status (%02x) while writing\n", status);
635			rv = IIC_ESTATUS;
636			goto out;
637		}
638		(*sent)++;
639	}
640	rv = IIC_NOERR;
641out:
642	mtx_unlock(&sc->mutex);
643	return (rv);
644}
645