1262552Sbr/*-
2262552Sbr * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
3262552Sbr * All rights reserved.
4262552Sbr *
5262552Sbr * Redistribution and use in source and binary forms, with or without
6262552Sbr * modification, are permitted provided that the following conditions
7262552Sbr * are met:
8262552Sbr * 1. Redistributions of source code must retain the above copyright
9262552Sbr *    notice, this list of conditions and the following disclaimer.
10262552Sbr * 2. Redistributions in binary form must reproduce the above copyright
11262552Sbr *    notice, this list of conditions and the following disclaimer in the
12262552Sbr *    documentation and/or other materials provided with the distribution.
13262552Sbr *
14262552Sbr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15262552Sbr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16262552Sbr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17262552Sbr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18262552Sbr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19262552Sbr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20262552Sbr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21262552Sbr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22262552Sbr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23262552Sbr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24262552Sbr * SUCH DAMAGE.
25262552Sbr */
26262552Sbr
27262552Sbr/*
28262552Sbr * Vybrid Family Inter-Integrated Circuit (I2C)
29262552Sbr * Chapter 48, Vybrid Reference Manual, Rev. 5, 07/2013
30262552Sbr */
31262552Sbr
32262552Sbr/*
33273662Sian * This driver is based on the I2C driver for i.MX
34262552Sbr */
35262552Sbr
36262552Sbr#include <sys/cdefs.h>
37262552Sbr__FBSDID("$FreeBSD: releng/10.2/sys/arm/freescale/vybrid/vf_i2c.c 273662 2014-10-26 02:40:34Z ian $");
38262552Sbr
39262552Sbr#include <sys/param.h>
40262552Sbr#include <sys/systm.h>
41262552Sbr#include <sys/bus.h>
42262552Sbr#include <sys/kernel.h>
43262552Sbr#include <sys/module.h>
44262552Sbr#include <sys/malloc.h>
45262552Sbr#include <sys/rman.h>
46262552Sbr#include <sys/timeet.h>
47262552Sbr#include <sys/timetc.h>
48262552Sbr
49262552Sbr#include <dev/iicbus/iiconf.h>
50262552Sbr#include <dev/iicbus/iicbus.h>
51262552Sbr
52262552Sbr#include "iicbus_if.h"
53262552Sbr
54262552Sbr#include <dev/fdt/fdt_common.h>
55262552Sbr#include <dev/ofw/openfirm.h>
56262552Sbr#include <dev/ofw/ofw_bus.h>
57262552Sbr#include <dev/ofw/ofw_bus_subr.h>
58262552Sbr
59262552Sbr#include <machine/bus.h>
60262552Sbr#include <machine/fdt.h>
61262552Sbr#include <machine/cpu.h>
62262552Sbr#include <machine/intr.h>
63262552Sbr
64262552Sbr#include <arm/freescale/vybrid/vf_common.h>
65262552Sbr
66262552Sbr#define	I2C_IBAD	0x0	/* I2C Bus Address Register */
67262552Sbr#define	I2C_IBFD	0x1	/* I2C Bus Frequency Divider Register */
68262552Sbr#define	I2C_IBCR	0x2	/* I2C Bus Control Register */
69262552Sbr#define	 IBCR_MDIS		(1 << 7) /* Module disable. */
70262552Sbr#define	 IBCR_IBIE		(1 << 6) /* I-Bus Interrupt Enable. */
71262552Sbr#define	 IBCR_MSSL		(1 << 5) /* Master/Slave mode select. */
72262552Sbr#define	 IBCR_TXRX		(1 << 4) /* Transmit/Receive mode select. */
73262552Sbr#define	 IBCR_NOACK		(1 << 3) /* Data Acknowledge disable. */
74262552Sbr#define	 IBCR_RSTA		(1 << 2) /* Repeat Start. */
75262552Sbr#define	 IBCR_DMAEN		(1 << 1) /* DMA Enable. */
76262552Sbr#define	I2C_IBSR	0x3	/* I2C Bus Status Register */
77262552Sbr#define	 IBSR_TCF		(1 << 7) /* Transfer complete. */
78262552Sbr#define	 IBSR_IAAS		(1 << 6) /* Addressed as a slave. */
79262552Sbr#define	 IBSR_IBB		(1 << 5) /* Bus busy. */
80262552Sbr#define	 IBSR_IBAL		(1 << 4) /* Arbitration Lost. */
81262552Sbr#define	 IBSR_SRW		(1 << 2) /* Slave Read/Write. */
82262552Sbr#define	 IBSR_IBIF		(1 << 1) /* I-Bus Interrupt Flag. */
83262552Sbr#define	 IBSR_RXAK		(1 << 0) /* Received Acknowledge. */
84262552Sbr#define	I2C_IBDR	0x4	/* I2C Bus Data I/O Register */
85262552Sbr#define	I2C_IBIC	0x5	/* I2C Bus Interrupt Config Register */
86262552Sbr#define	 IBIC_BIIE		(1 << 7) /* Bus Idle Interrupt Enable bit. */
87262552Sbr#define	I2C_IBDBG	0x6	/* I2C Bus Debug Register */
88262552Sbr
89262552Sbr#ifdef DEBUG
90262552Sbr#define vf_i2c_dbg(_sc, fmt, args...) \
91262552Sbr	device_printf((_sc)->dev, fmt, ##args)
92262552Sbr#else
93262552Sbr#define vf_i2c_dbg(_sc, fmt, args...)
94262552Sbr#endif
95262552Sbr
96262552Sbrstatic int i2c_repeated_start(device_t, u_char, int);
97262552Sbrstatic int i2c_start(device_t, u_char, int);
98262552Sbrstatic int i2c_stop(device_t);
99262552Sbrstatic int i2c_reset(device_t, u_char, u_char, u_char *);
100262552Sbrstatic int i2c_read(device_t, char *, int, int *, int, int);
101262552Sbrstatic int i2c_write(device_t, const char *, int, int *, int);
102262552Sbr
103262552Sbrstruct i2c_softc {
104262552Sbr	struct resource		*res[2];
105262552Sbr	bus_space_tag_t		bst;
106262552Sbr	bus_space_handle_t	bsh;
107262552Sbr	device_t		dev;
108262552Sbr	device_t		iicbus;
109262552Sbr	struct mtx		mutex;
110262552Sbr};
111262552Sbr
112262552Sbrstatic struct resource_spec i2c_spec[] = {
113262552Sbr	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
114262552Sbr	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
115262552Sbr	{ -1, 0 }
116262552Sbr};
117262552Sbr
118262552Sbrstatic int
119262552Sbri2c_probe(device_t dev)
120262552Sbr{
121262552Sbr
122262552Sbr	if (!ofw_bus_status_okay(dev))
123262552Sbr		return (ENXIO);
124262552Sbr
125262552Sbr	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-i2c"))
126262552Sbr		return (ENXIO);
127262552Sbr
128262552Sbr	device_set_desc(dev, "Vybrid Family Inter-Integrated Circuit (I2C)");
129262552Sbr	return (BUS_PROBE_DEFAULT);
130262552Sbr}
131262552Sbr
132262552Sbrstatic int
133262552Sbri2c_attach(device_t dev)
134262552Sbr{
135262552Sbr	struct i2c_softc *sc;
136262552Sbr
137262552Sbr	sc = device_get_softc(dev);
138262552Sbr	sc->dev = dev;
139262552Sbr
140262552Sbr	mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);
141262552Sbr
142262552Sbr	if (bus_alloc_resources(dev, i2c_spec, sc->res)) {
143262552Sbr		device_printf(dev, "could not allocate resources\n");
144262552Sbr		return (ENXIO);
145262552Sbr	}
146262552Sbr
147262552Sbr	/* Memory interface */
148262552Sbr	sc->bst = rman_get_bustag(sc->res[0]);
149262552Sbr	sc->bsh = rman_get_bushandle(sc->res[0]);
150262552Sbr
151262552Sbr	WRITE1(sc, I2C_IBIC, IBIC_BIIE);
152262552Sbr
153262552Sbr	sc->iicbus = device_add_child(dev, "iicbus", -1);
154262552Sbr	if (sc->iicbus == NULL) {
155262552Sbr		device_printf(dev, "could not add iicbus child");
156262552Sbr		mtx_destroy(&sc->mutex);
157262552Sbr		return (ENXIO);
158262552Sbr	}
159262552Sbr
160262552Sbr	bus_generic_attach(dev);
161262552Sbr
162262552Sbr	return (0);
163262552Sbr}
164262552Sbr
165262552Sbr/* Wait for transfer interrupt flag */
166262552Sbrstatic int
167262552Sbrwait_for_iif(struct i2c_softc *sc)
168262552Sbr{
169262552Sbr	int retry;
170262552Sbr
171262552Sbr	retry = 1000;
172262552Sbr	while (retry --) {
173266207Sian		if (READ1(sc, I2C_IBSR) & IBSR_IBIF) {
174266207Sian			WRITE1(sc, I2C_IBSR, IBSR_IBIF);
175262552Sbr			return (IIC_NOERR);
176266207Sian		}
177262552Sbr		DELAY(10);
178262552Sbr	}
179262552Sbr
180262552Sbr	return (IIC_ETIMEOUT);
181262552Sbr}
182262552Sbr
183262552Sbr/* Wait for free bus */
184262552Sbrstatic int
185262552Sbrwait_for_nibb(struct i2c_softc *sc)
186262552Sbr{
187262552Sbr	int retry;
188262552Sbr
189262552Sbr	retry = 1000;
190262552Sbr	while (retry --) {
191262552Sbr		if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0)
192262552Sbr			return (IIC_NOERR);
193262552Sbr		DELAY(10);
194262552Sbr	}
195262552Sbr
196262552Sbr	return (IIC_ETIMEOUT);
197262552Sbr}
198262552Sbr
199262552Sbr/* Wait for transfer complete+interrupt flag */
200262552Sbrstatic int
201262552Sbrwait_for_icf(struct i2c_softc *sc)
202262552Sbr{
203262552Sbr	int retry;
204262552Sbr
205262552Sbr	retry = 1000;
206262552Sbr	while (retry --) {
207262552Sbr		if (READ1(sc, I2C_IBSR) & IBSR_TCF) {
208266207Sian			if (READ1(sc, I2C_IBSR) & IBSR_IBIF) {
209266207Sian				WRITE1(sc, I2C_IBSR, IBSR_IBIF);
210262552Sbr				return (IIC_NOERR);
211266207Sian			}
212262552Sbr		}
213262552Sbr		DELAY(10);
214262552Sbr	}
215262552Sbr
216262552Sbr	return (IIC_ETIMEOUT);
217262552Sbr}
218262552Sbr
219262552Sbrstatic int
220262552Sbri2c_repeated_start(device_t dev, u_char slave, int timeout)
221262552Sbr{
222262552Sbr	struct i2c_softc *sc;
223262552Sbr	int error;
224262552Sbr	int reg;
225262552Sbr
226262552Sbr	sc = device_get_softc(dev);
227262552Sbr
228262552Sbr	vf_i2c_dbg(sc, "i2c repeated start\n");
229262552Sbr
230262552Sbr	mtx_lock(&sc->mutex);
231262552Sbr
232262552Sbr	WRITE1(sc, I2C_IBAD, slave);
233262552Sbr
234262552Sbr	if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0) {
235262552Sbr		mtx_unlock(&sc->mutex);
236262552Sbr		return (IIC_EBUSBSY);
237262552Sbr	}
238262552Sbr
239262552Sbr	/* Set repeated start condition */
240262552Sbr	DELAY(10);
241262552Sbr
242262552Sbr	reg = READ1(sc, I2C_IBCR);
243262552Sbr	reg |= (IBCR_RSTA | IBCR_IBIE);
244262552Sbr	WRITE1(sc, I2C_IBCR, reg);
245262552Sbr
246262552Sbr	DELAY(10);
247262552Sbr
248262552Sbr	/* Write target address - LSB is R/W bit */
249262552Sbr	WRITE1(sc, I2C_IBDR, slave);
250262552Sbr
251262552Sbr	error = wait_for_iif(sc);
252262552Sbr
253262552Sbr	mtx_unlock(&sc->mutex);
254262552Sbr
255262552Sbr	if (error)
256262552Sbr		return (error);
257262552Sbr
258262552Sbr	return (IIC_NOERR);
259262552Sbr}
260262552Sbr
261262552Sbrstatic int
262262552Sbri2c_start(device_t dev, u_char slave, int timeout)
263262552Sbr{
264262552Sbr	struct i2c_softc *sc;
265262552Sbr	int error;
266262552Sbr	int reg;
267262552Sbr
268262552Sbr	sc = device_get_softc(dev);
269262552Sbr
270262552Sbr	vf_i2c_dbg(sc, "i2c start\n");
271262552Sbr
272262552Sbr	mtx_lock(&sc->mutex);
273262552Sbr
274262552Sbr	WRITE1(sc, I2C_IBAD, slave);
275262552Sbr
276262552Sbr	if (READ1(sc, I2C_IBSR) & IBSR_IBB) {
277262552Sbr		mtx_unlock(&sc->mutex);
278262552Sbr		vf_i2c_dbg(sc, "cant i2c start: IIC_EBUSBSY\n");
279262552Sbr		return (IIC_EBUSBSY);
280262552Sbr	}
281262552Sbr
282262552Sbr	/* Set start condition */
283262552Sbr	reg = (IBCR_MSSL | IBCR_NOACK | IBCR_IBIE);
284262552Sbr	WRITE1(sc, I2C_IBCR, reg);
285262552Sbr
286262552Sbr	DELAY(100);
287262552Sbr
288262552Sbr	reg |= (IBCR_TXRX);
289262552Sbr	WRITE1(sc, I2C_IBCR, reg);
290262552Sbr
291262552Sbr	/* Write target address - LSB is R/W bit */
292262552Sbr	WRITE1(sc, I2C_IBDR, slave);
293262552Sbr
294262552Sbr	error = wait_for_iif(sc);
295262552Sbr
296262552Sbr	mtx_unlock(&sc->mutex);
297262552Sbr	if (error) {
298262552Sbr		vf_i2c_dbg(sc, "cant i2c start: iif error\n");
299262552Sbr		return (error);
300262552Sbr	}
301262552Sbr
302262552Sbr	return (IIC_NOERR);
303262552Sbr}
304262552Sbr
305262552Sbrstatic int
306262552Sbri2c_stop(device_t dev)
307262552Sbr{
308262552Sbr	struct i2c_softc *sc;
309262552Sbr
310262552Sbr	sc = device_get_softc(dev);
311262552Sbr
312262552Sbr	vf_i2c_dbg(sc, "i2c stop\n");
313262552Sbr
314262552Sbr	mtx_lock(&sc->mutex);
315262552Sbr
316262552Sbr	WRITE1(sc, I2C_IBCR, IBCR_NOACK | IBCR_IBIE);
317262552Sbr
318262552Sbr	DELAY(100);
319262552Sbr
320262552Sbr	/* Reset controller if bus still busy after STOP */
321262552Sbr	if (wait_for_nibb(sc) == IIC_ETIMEOUT) {
322262552Sbr		WRITE1(sc, I2C_IBCR, IBCR_MDIS);
323262552Sbr		DELAY(1000);
324262552Sbr		WRITE1(sc, I2C_IBCR, IBCR_NOACK);
325262552Sbr	}
326262552Sbr	mtx_unlock(&sc->mutex);
327262552Sbr
328262552Sbr	return (IIC_NOERR);
329262552Sbr}
330262552Sbr
331262552Sbrstatic int
332262552Sbri2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
333262552Sbr{
334262552Sbr	struct i2c_softc *sc;
335262552Sbr
336262552Sbr	sc = device_get_softc(dev);
337262552Sbr
338262552Sbr	vf_i2c_dbg(sc, "i2c reset\n");
339262552Sbr
340262552Sbr	switch (speed) {
341262552Sbr	case IIC_FAST:
342262552Sbr	case IIC_SLOW:
343262552Sbr	case IIC_UNKNOWN:
344262552Sbr	case IIC_FASTEST:
345262552Sbr	default:
346262552Sbr		break;
347262552Sbr	}
348262552Sbr
349262552Sbr	mtx_lock(&sc->mutex);
350262552Sbr	WRITE1(sc, I2C_IBCR, IBCR_MDIS);
351262552Sbr
352262552Sbr	DELAY(1000);
353262552Sbr
354262552Sbr	WRITE1(sc, I2C_IBFD, 20);
355262552Sbr	WRITE1(sc, I2C_IBCR, 0x0); /* Enable i2c */
356262552Sbr
357262552Sbr	DELAY(1000);
358262552Sbr
359262552Sbr	mtx_unlock(&sc->mutex);
360262552Sbr
361262552Sbr	return (IIC_NOERR);
362262552Sbr}
363262552Sbr
364262552Sbrstatic int
365262552Sbri2c_read(device_t dev, char *buf, int len, int *read, int last, int delay)
366262552Sbr{
367262552Sbr	struct i2c_softc *sc;
368262552Sbr	int error;
369262552Sbr
370262552Sbr	sc = device_get_softc(dev);
371262552Sbr
372262552Sbr	vf_i2c_dbg(sc, "i2c read\n");
373262552Sbr
374262552Sbr	*read = 0;
375262552Sbr
376262552Sbr	mtx_lock(&sc->mutex);
377262552Sbr
378262552Sbr	if (len) {
379262552Sbr		if (len == 1)
380262552Sbr			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL |	\
381262552Sbr			    IBCR_NOACK);
382262552Sbr		else
383262552Sbr			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL);
384262552Sbr
385262552Sbr		/* dummy read */
386262552Sbr		READ1(sc, I2C_IBDR);
387262552Sbr		DELAY(1000);
388262552Sbr	}
389262552Sbr
390262552Sbr	while (*read < len) {
391262552Sbr		error = wait_for_icf(sc);
392262552Sbr		if (error) {
393262552Sbr			mtx_unlock(&sc->mutex);
394262552Sbr			return (error);
395262552Sbr		}
396262552Sbr
397262552Sbr		if ((*read == len - 2) && last) {
398262552Sbr			/* NO ACK on last byte */
399262552Sbr			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL |	\
400262552Sbr			    IBCR_NOACK);
401262552Sbr		}
402262552Sbr
403262552Sbr		if ((*read == len - 1) && last) {
404262552Sbr			/* Transfer done, remove master bit */
405262552Sbr			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_NOACK);
406262552Sbr		}
407262552Sbr
408262552Sbr		*buf++ = READ1(sc, I2C_IBDR);
409262552Sbr		(*read)++;
410262552Sbr	}
411262552Sbr	mtx_unlock(&sc->mutex);
412262552Sbr
413262552Sbr	return (IIC_NOERR);
414262552Sbr}
415262552Sbr
416262552Sbrstatic int
417262552Sbri2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
418262552Sbr{
419262552Sbr	struct i2c_softc *sc;
420262552Sbr	int error;
421262552Sbr
422262552Sbr	sc = device_get_softc(dev);
423262552Sbr
424262552Sbr	vf_i2c_dbg(sc, "i2c write\n");
425262552Sbr
426262552Sbr	*sent = 0;
427262552Sbr
428262552Sbr	mtx_lock(&sc->mutex);
429262552Sbr	while (*sent < len) {
430262552Sbr
431262552Sbr		WRITE1(sc, I2C_IBDR, *buf++);
432262552Sbr
433262552Sbr		error = wait_for_iif(sc);
434262552Sbr		if (error) {
435262552Sbr			mtx_unlock(&sc->mutex);
436262552Sbr			return (error);
437262552Sbr		}
438262552Sbr
439262552Sbr		(*sent)++;
440262552Sbr	}
441262552Sbr	mtx_unlock(&sc->mutex);
442262552Sbr
443262552Sbr	return (IIC_NOERR);
444262552Sbr}
445262552Sbr
446262552Sbrstatic device_method_t i2c_methods[] = {
447262552Sbr	DEVMETHOD(device_probe,		i2c_probe),
448262552Sbr	DEVMETHOD(device_attach,	i2c_attach),
449262552Sbr
450262552Sbr	DEVMETHOD(iicbus_callback,		iicbus_null_callback),
451262552Sbr	DEVMETHOD(iicbus_repeated_start,	i2c_repeated_start),
452262552Sbr	DEVMETHOD(iicbus_start,			i2c_start),
453262552Sbr	DEVMETHOD(iicbus_stop,			i2c_stop),
454262552Sbr	DEVMETHOD(iicbus_reset,			i2c_reset),
455262552Sbr	DEVMETHOD(iicbus_read,			i2c_read),
456262552Sbr	DEVMETHOD(iicbus_write,			i2c_write),
457262552Sbr	DEVMETHOD(iicbus_transfer,		iicbus_transfer_gen),
458262552Sbr
459262552Sbr	{ 0, 0 }
460262552Sbr};
461262552Sbr
462262552Sbrstatic driver_t i2c_driver = {
463262552Sbr	"i2c",
464262552Sbr	i2c_methods,
465262552Sbr	sizeof(struct i2c_softc),
466262552Sbr};
467262552Sbr
468262552Sbrstatic devclass_t i2c_devclass;
469262552Sbr
470262552SbrDRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0);
471262552SbrDRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0);
472