xref: /freebsd/sys/arm/freescale/imx/imx_i2c.c (revision 484b4fd46c4e4061901114babeec89e5bcdc75a7)
1*484b4fd4SRuslan Bukin /*-
2*484b4fd4SRuslan Bukin  * Copyright (C) 2008-2009 Semihalf, Michal Hajduk
3*484b4fd4SRuslan Bukin  * Copyright (c) 2012, 2013 The FreeBSD Foundation
4*484b4fd4SRuslan Bukin  * All rights reserved.
5*484b4fd4SRuslan Bukin  *
6*484b4fd4SRuslan Bukin  * Portions of this software were developed by Oleksandr Rybalko
7*484b4fd4SRuslan Bukin  * under sponsorship from the FreeBSD Foundation.
8*484b4fd4SRuslan Bukin  *
9*484b4fd4SRuslan Bukin  * Redistribution and use in source and binary forms, with or without
10*484b4fd4SRuslan Bukin  * modification, are permitted provided that the following conditions
11*484b4fd4SRuslan Bukin  * are met:
12*484b4fd4SRuslan Bukin  * 1. Redistributions of source code must retain the above copyright
13*484b4fd4SRuslan Bukin  *    notice, this list of conditions and the following disclaimer.
14*484b4fd4SRuslan Bukin  * 2. Redistributions in binary form must reproduce the above copyright
15*484b4fd4SRuslan Bukin  *    notice, this list of conditions and the following disclaimer in the
16*484b4fd4SRuslan Bukin  *    documentation and/or other materials provided with the distribution.
17*484b4fd4SRuslan Bukin  *
18*484b4fd4SRuslan Bukin  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19*484b4fd4SRuslan Bukin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*484b4fd4SRuslan Bukin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*484b4fd4SRuslan Bukin  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22*484b4fd4SRuslan Bukin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23*484b4fd4SRuslan Bukin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24*484b4fd4SRuslan Bukin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25*484b4fd4SRuslan Bukin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26*484b4fd4SRuslan Bukin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27*484b4fd4SRuslan Bukin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28*484b4fd4SRuslan Bukin  * SUCH DAMAGE.
29*484b4fd4SRuslan Bukin  */
30*484b4fd4SRuslan Bukin 
31*484b4fd4SRuslan Bukin #include <sys/cdefs.h>
32*484b4fd4SRuslan Bukin __FBSDID("$FreeBSD$");
33*484b4fd4SRuslan Bukin 
34*484b4fd4SRuslan Bukin #include <sys/param.h>
35*484b4fd4SRuslan Bukin #include <sys/systm.h>
36*484b4fd4SRuslan Bukin #include <sys/bus.h>
37*484b4fd4SRuslan Bukin #include <sys/kernel.h>
38*484b4fd4SRuslan Bukin #include <sys/module.h>
39*484b4fd4SRuslan Bukin #include <sys/resource.h>
40*484b4fd4SRuslan Bukin 
41*484b4fd4SRuslan Bukin #include <machine/bus.h>
42*484b4fd4SRuslan Bukin #include <machine/resource.h>
43*484b4fd4SRuslan Bukin #include <sys/rman.h>
44*484b4fd4SRuslan Bukin 
45*484b4fd4SRuslan Bukin #include <sys/lock.h>
46*484b4fd4SRuslan Bukin #include <sys/mutex.h>
47*484b4fd4SRuslan Bukin 
48*484b4fd4SRuslan Bukin #include <dev/iicbus/iiconf.h>
49*484b4fd4SRuslan Bukin #include <dev/iicbus/iicbus.h>
50*484b4fd4SRuslan Bukin #include "iicbus_if.h"
51*484b4fd4SRuslan Bukin 
52*484b4fd4SRuslan Bukin #include <dev/fdt/fdt_common.h>
53*484b4fd4SRuslan Bukin #include <dev/ofw/openfirm.h>
54*484b4fd4SRuslan Bukin #include <dev/ofw/ofw_bus.h>
55*484b4fd4SRuslan Bukin #include <dev/ofw/ofw_bus_subr.h>
56*484b4fd4SRuslan Bukin 
57*484b4fd4SRuslan Bukin #define I2C_ADDR_REG		0x00 /* I2C slave address register */
58*484b4fd4SRuslan Bukin #define I2C_FDR_REG		0x04 /* I2C frequency divider register */
59*484b4fd4SRuslan Bukin #define I2C_CONTROL_REG		0x08 /* I2C control register */
60*484b4fd4SRuslan Bukin #define I2C_STATUS_REG		0x0C /* I2C status register */
61*484b4fd4SRuslan Bukin #define I2C_DATA_REG		0x10 /* I2C data register */
62*484b4fd4SRuslan Bukin #define I2C_DFSRR_REG		0x14 /* I2C Digital Filter Sampling rate */
63*484b4fd4SRuslan Bukin 
64*484b4fd4SRuslan Bukin #define I2CCR_MEN		(1 << 7) /* Module enable */
65*484b4fd4SRuslan Bukin #define I2CCR_MSTA		(1 << 5) /* Master/slave mode */
66*484b4fd4SRuslan Bukin #define I2CCR_MTX		(1 << 4) /* Transmit/receive mode */
67*484b4fd4SRuslan Bukin #define I2CCR_TXAK		(1 << 3) /* Transfer acknowledge */
68*484b4fd4SRuslan Bukin #define I2CCR_RSTA		(1 << 2) /* Repeated START */
69*484b4fd4SRuslan Bukin 
70*484b4fd4SRuslan Bukin #define I2CSR_MCF		(1 << 7) /* Data transfer */
71*484b4fd4SRuslan Bukin #define I2CSR_MASS		(1 << 6) /* Addressed as a slave */
72*484b4fd4SRuslan Bukin #define I2CSR_MBB		(1 << 5) /* Bus busy */
73*484b4fd4SRuslan Bukin #define I2CSR_MAL		(1 << 4) /* Arbitration lost */
74*484b4fd4SRuslan Bukin #define I2CSR_SRW		(1 << 2) /* Slave read/write */
75*484b4fd4SRuslan Bukin #define I2CSR_MIF		(1 << 1) /* Module interrupt */
76*484b4fd4SRuslan Bukin #define I2CSR_RXAK		(1 << 0) /* Received acknowledge */
77*484b4fd4SRuslan Bukin 
78*484b4fd4SRuslan Bukin #define I2C_BAUD_RATE_FAST	0x31
79*484b4fd4SRuslan Bukin #define I2C_BAUD_RATE_DEF	0x3F
80*484b4fd4SRuslan Bukin #define I2C_DFSSR_DIV		0x10
81*484b4fd4SRuslan Bukin 
82*484b4fd4SRuslan Bukin #ifdef  DEBUG
83*484b4fd4SRuslan Bukin #define debugf(fmt, args...) do { printf("%s(): ", __func__);		\
84*484b4fd4SRuslan Bukin 		printf(fmt,##args); } while (0)
85*484b4fd4SRuslan Bukin #else
86*484b4fd4SRuslan Bukin #define debugf(fmt, args...)
87*484b4fd4SRuslan Bukin #endif
88*484b4fd4SRuslan Bukin 
89*484b4fd4SRuslan Bukin struct i2c_softc {
90*484b4fd4SRuslan Bukin 	device_t		dev;
91*484b4fd4SRuslan Bukin 	device_t		iicbus;
92*484b4fd4SRuslan Bukin 	struct resource		*res;
93*484b4fd4SRuslan Bukin 	struct mtx		mutex;
94*484b4fd4SRuslan Bukin 	int			rid;
95*484b4fd4SRuslan Bukin 	bus_space_handle_t	bsh;
96*484b4fd4SRuslan Bukin 	bus_space_tag_t		bst;
97*484b4fd4SRuslan Bukin };
98*484b4fd4SRuslan Bukin 
99*484b4fd4SRuslan Bukin static phandle_t i2c_get_node(device_t, device_t);
100*484b4fd4SRuslan Bukin static int i2c_probe(device_t);
101*484b4fd4SRuslan Bukin static int i2c_attach(device_t);
102*484b4fd4SRuslan Bukin 
103*484b4fd4SRuslan Bukin static int i2c_repeated_start(device_t, u_char, int);
104*484b4fd4SRuslan Bukin static int i2c_start(device_t, u_char, int);
105*484b4fd4SRuslan Bukin static int i2c_stop(device_t);
106*484b4fd4SRuslan Bukin static int i2c_reset(device_t, u_char, u_char, u_char *);
107*484b4fd4SRuslan Bukin static int i2c_read(device_t, char *, int, int *, int, int);
108*484b4fd4SRuslan Bukin static int i2c_write(device_t, const char *, int, int *, int);
109*484b4fd4SRuslan Bukin 
110*484b4fd4SRuslan Bukin static device_method_t i2c_methods[] = {
111*484b4fd4SRuslan Bukin 	DEVMETHOD(device_probe,			i2c_probe),
112*484b4fd4SRuslan Bukin 	DEVMETHOD(device_attach,		i2c_attach),
113*484b4fd4SRuslan Bukin 
114*484b4fd4SRuslan Bukin 	/* OFW methods */
115*484b4fd4SRuslan Bukin 	DEVMETHOD(ofw_bus_get_node,		i2c_get_node),
116*484b4fd4SRuslan Bukin 
117*484b4fd4SRuslan Bukin 	DEVMETHOD(iicbus_callback,		iicbus_null_callback),
118*484b4fd4SRuslan Bukin 	DEVMETHOD(iicbus_repeated_start,	i2c_repeated_start),
119*484b4fd4SRuslan Bukin 	DEVMETHOD(iicbus_start,			i2c_start),
120*484b4fd4SRuslan Bukin 	DEVMETHOD(iicbus_stop,			i2c_stop),
121*484b4fd4SRuslan Bukin 	DEVMETHOD(iicbus_reset,			i2c_reset),
122*484b4fd4SRuslan Bukin 	DEVMETHOD(iicbus_read,			i2c_read),
123*484b4fd4SRuslan Bukin 	DEVMETHOD(iicbus_write,			i2c_write),
124*484b4fd4SRuslan Bukin 	DEVMETHOD(iicbus_transfer,		iicbus_transfer_gen),
125*484b4fd4SRuslan Bukin 
126*484b4fd4SRuslan Bukin 	{ 0, 0 }
127*484b4fd4SRuslan Bukin };
128*484b4fd4SRuslan Bukin 
129*484b4fd4SRuslan Bukin static driver_t i2c_driver = {
130*484b4fd4SRuslan Bukin 	"iichb",
131*484b4fd4SRuslan Bukin 	i2c_methods,
132*484b4fd4SRuslan Bukin 	sizeof(struct i2c_softc),
133*484b4fd4SRuslan Bukin };
134*484b4fd4SRuslan Bukin static devclass_t  i2c_devclass;
135*484b4fd4SRuslan Bukin 
136*484b4fd4SRuslan Bukin DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0);
137*484b4fd4SRuslan Bukin DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0);
138*484b4fd4SRuslan Bukin 
139*484b4fd4SRuslan Bukin static phandle_t
140*484b4fd4SRuslan Bukin i2c_get_node(device_t bus, device_t dev)
141*484b4fd4SRuslan Bukin {
142*484b4fd4SRuslan Bukin 	/*
143*484b4fd4SRuslan Bukin 	 * Share controller node with iicbus device
144*484b4fd4SRuslan Bukin 	 */
145*484b4fd4SRuslan Bukin 	return ofw_bus_get_node(bus);
146*484b4fd4SRuslan Bukin }
147*484b4fd4SRuslan Bukin 
148*484b4fd4SRuslan Bukin static __inline void
149*484b4fd4SRuslan Bukin i2c_write_reg(struct i2c_softc *sc, bus_size_t off, uint8_t val)
150*484b4fd4SRuslan Bukin {
151*484b4fd4SRuslan Bukin 
152*484b4fd4SRuslan Bukin 	bus_space_write_1(sc->bst, sc->bsh, off, val);
153*484b4fd4SRuslan Bukin }
154*484b4fd4SRuslan Bukin 
155*484b4fd4SRuslan Bukin static __inline uint8_t
156*484b4fd4SRuslan Bukin i2c_read_reg(struct i2c_softc *sc, bus_size_t off)
157*484b4fd4SRuslan Bukin {
158*484b4fd4SRuslan Bukin 
159*484b4fd4SRuslan Bukin 	return (bus_space_read_1(sc->bst, sc->bsh, off));
160*484b4fd4SRuslan Bukin }
161*484b4fd4SRuslan Bukin 
162*484b4fd4SRuslan Bukin static __inline void
163*484b4fd4SRuslan Bukin i2c_flag_set(struct i2c_softc *sc, bus_size_t off, uint8_t mask)
164*484b4fd4SRuslan Bukin {
165*484b4fd4SRuslan Bukin 	uint8_t status;
166*484b4fd4SRuslan Bukin 
167*484b4fd4SRuslan Bukin 	status = i2c_read_reg(sc, off);
168*484b4fd4SRuslan Bukin 	status |= mask;
169*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, off, status);
170*484b4fd4SRuslan Bukin }
171*484b4fd4SRuslan Bukin 
172*484b4fd4SRuslan Bukin /* Wait for transfer interrupt flag */
173*484b4fd4SRuslan Bukin static int
174*484b4fd4SRuslan Bukin wait_for_iif(struct i2c_softc *sc)
175*484b4fd4SRuslan Bukin {
176*484b4fd4SRuslan Bukin 	int retry;
177*484b4fd4SRuslan Bukin 
178*484b4fd4SRuslan Bukin 	retry = 1000;
179*484b4fd4SRuslan Bukin 	while (retry --) {
180*484b4fd4SRuslan Bukin 		if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MIF)
181*484b4fd4SRuslan Bukin 			return (IIC_NOERR);
182*484b4fd4SRuslan Bukin 		DELAY(10);
183*484b4fd4SRuslan Bukin 	}
184*484b4fd4SRuslan Bukin 
185*484b4fd4SRuslan Bukin 	return (IIC_ETIMEOUT);
186*484b4fd4SRuslan Bukin }
187*484b4fd4SRuslan Bukin 
188*484b4fd4SRuslan Bukin /* Wait for free bus */
189*484b4fd4SRuslan Bukin static int
190*484b4fd4SRuslan Bukin wait_for_nibb(struct i2c_softc *sc)
191*484b4fd4SRuslan Bukin {
192*484b4fd4SRuslan Bukin 	int retry;
193*484b4fd4SRuslan Bukin 
194*484b4fd4SRuslan Bukin 	retry = 1000;
195*484b4fd4SRuslan Bukin 	while (retry --) {
196*484b4fd4SRuslan Bukin 		if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0)
197*484b4fd4SRuslan Bukin 			return (IIC_NOERR);
198*484b4fd4SRuslan Bukin 		DELAY(10);
199*484b4fd4SRuslan Bukin 	}
200*484b4fd4SRuslan Bukin 
201*484b4fd4SRuslan Bukin 	return (IIC_ETIMEOUT);
202*484b4fd4SRuslan Bukin }
203*484b4fd4SRuslan Bukin 
204*484b4fd4SRuslan Bukin /* Wait for transfer complete+interrupt flag */
205*484b4fd4SRuslan Bukin static int
206*484b4fd4SRuslan Bukin wait_for_icf(struct i2c_softc *sc)
207*484b4fd4SRuslan Bukin {
208*484b4fd4SRuslan Bukin 	int retry;
209*484b4fd4SRuslan Bukin 
210*484b4fd4SRuslan Bukin 	retry = 1000;
211*484b4fd4SRuslan Bukin 	while (retry --) {
212*484b4fd4SRuslan Bukin 
213*484b4fd4SRuslan Bukin 		if ((i2c_read_reg(sc, I2C_STATUS_REG) &
214*484b4fd4SRuslan Bukin 		    (I2CSR_MCF|I2CSR_MIF)) == (I2CSR_MCF|I2CSR_MIF))
215*484b4fd4SRuslan Bukin 			return (IIC_NOERR);
216*484b4fd4SRuslan Bukin 		DELAY(10);
217*484b4fd4SRuslan Bukin 	}
218*484b4fd4SRuslan Bukin 
219*484b4fd4SRuslan Bukin 	return (IIC_ETIMEOUT);
220*484b4fd4SRuslan Bukin }
221*484b4fd4SRuslan Bukin 
222*484b4fd4SRuslan Bukin static int
223*484b4fd4SRuslan Bukin i2c_probe(device_t dev)
224*484b4fd4SRuslan Bukin {
225*484b4fd4SRuslan Bukin 	struct i2c_softc *sc;
226*484b4fd4SRuslan Bukin 
227*484b4fd4SRuslan Bukin 	if (!ofw_bus_status_okay(dev))
228*484b4fd4SRuslan Bukin 		return (ENXIO);
229*484b4fd4SRuslan Bukin 
230*484b4fd4SRuslan Bukin 	if (!ofw_bus_is_compatible(dev, "fsl,imx-i2c"))
231*484b4fd4SRuslan Bukin 		return (ENXIO);
232*484b4fd4SRuslan Bukin 
233*484b4fd4SRuslan Bukin 	sc = device_get_softc(dev);
234*484b4fd4SRuslan Bukin 	sc->rid = 0;
235*484b4fd4SRuslan Bukin 
236*484b4fd4SRuslan Bukin 	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
237*484b4fd4SRuslan Bukin 	    RF_ACTIVE);
238*484b4fd4SRuslan Bukin 	if (sc->res == NULL) {
239*484b4fd4SRuslan Bukin 		device_printf(dev, "could not allocate resources\n");
240*484b4fd4SRuslan Bukin 		return (ENXIO);
241*484b4fd4SRuslan Bukin 	}
242*484b4fd4SRuslan Bukin 
243*484b4fd4SRuslan Bukin 	sc->bst = rman_get_bustag(sc->res);
244*484b4fd4SRuslan Bukin 	sc->bsh = rman_get_bushandle(sc->res);
245*484b4fd4SRuslan Bukin 
246*484b4fd4SRuslan Bukin 	/* Enable I2C */
247*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN);
248*484b4fd4SRuslan Bukin 	bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res);
249*484b4fd4SRuslan Bukin 	device_set_desc(dev, "I2C bus controller");
250*484b4fd4SRuslan Bukin 
251*484b4fd4SRuslan Bukin 	return (BUS_PROBE_DEFAULT);
252*484b4fd4SRuslan Bukin }
253*484b4fd4SRuslan Bukin 
254*484b4fd4SRuslan Bukin static int
255*484b4fd4SRuslan Bukin i2c_attach(device_t dev)
256*484b4fd4SRuslan Bukin {
257*484b4fd4SRuslan Bukin 	struct i2c_softc *sc;
258*484b4fd4SRuslan Bukin 
259*484b4fd4SRuslan Bukin 	sc = device_get_softc(dev);
260*484b4fd4SRuslan Bukin 	sc->dev = dev;
261*484b4fd4SRuslan Bukin 	sc->rid = 0;
262*484b4fd4SRuslan Bukin 
263*484b4fd4SRuslan Bukin 	mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);
264*484b4fd4SRuslan Bukin 
265*484b4fd4SRuslan Bukin 	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
266*484b4fd4SRuslan Bukin 	    RF_ACTIVE);
267*484b4fd4SRuslan Bukin 	if (sc->res == NULL) {
268*484b4fd4SRuslan Bukin 		device_printf(dev, "could not allocate resources");
269*484b4fd4SRuslan Bukin 		mtx_destroy(&sc->mutex);
270*484b4fd4SRuslan Bukin 		return (ENXIO);
271*484b4fd4SRuslan Bukin 	}
272*484b4fd4SRuslan Bukin 
273*484b4fd4SRuslan Bukin 	sc->bst = rman_get_bustag(sc->res);
274*484b4fd4SRuslan Bukin 	sc->bsh = rman_get_bushandle(sc->res);
275*484b4fd4SRuslan Bukin 
276*484b4fd4SRuslan Bukin 	sc->iicbus = device_add_child(dev, "iicbus", -1);
277*484b4fd4SRuslan Bukin 	if (sc->iicbus == NULL) {
278*484b4fd4SRuslan Bukin 		device_printf(dev, "could not add iicbus child");
279*484b4fd4SRuslan Bukin 		mtx_destroy(&sc->mutex);
280*484b4fd4SRuslan Bukin 		return (ENXIO);
281*484b4fd4SRuslan Bukin 	}
282*484b4fd4SRuslan Bukin 
283*484b4fd4SRuslan Bukin 	bus_generic_attach(dev);
284*484b4fd4SRuslan Bukin 	return (IIC_NOERR);
285*484b4fd4SRuslan Bukin }
286*484b4fd4SRuslan Bukin 
287*484b4fd4SRuslan Bukin static int
288*484b4fd4SRuslan Bukin i2c_repeated_start(device_t dev, u_char slave, int timeout)
289*484b4fd4SRuslan Bukin {
290*484b4fd4SRuslan Bukin 	struct i2c_softc *sc;
291*484b4fd4SRuslan Bukin 	int error;
292*484b4fd4SRuslan Bukin 
293*484b4fd4SRuslan Bukin 	sc = device_get_softc(dev);
294*484b4fd4SRuslan Bukin 
295*484b4fd4SRuslan Bukin 	mtx_lock(&sc->mutex);
296*484b4fd4SRuslan Bukin 
297*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_ADDR_REG, slave);
298*484b4fd4SRuslan Bukin 	if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0) {
299*484b4fd4SRuslan Bukin 		mtx_unlock(&sc->mutex);
300*484b4fd4SRuslan Bukin 		return (IIC_EBUSBSY);
301*484b4fd4SRuslan Bukin 	}
302*484b4fd4SRuslan Bukin 
303*484b4fd4SRuslan Bukin 	/* Set repeated start condition */
304*484b4fd4SRuslan Bukin 	DELAY(10);
305*484b4fd4SRuslan Bukin 	i2c_flag_set(sc, I2C_CONTROL_REG, I2CCR_RSTA);
306*484b4fd4SRuslan Bukin 	DELAY(10);
307*484b4fd4SRuslan Bukin 	/* Clear status */
308*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
309*484b4fd4SRuslan Bukin 	/* Write target address - LSB is R/W bit */
310*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_DATA_REG, slave);
311*484b4fd4SRuslan Bukin 
312*484b4fd4SRuslan Bukin 	error = wait_for_iif(sc);
313*484b4fd4SRuslan Bukin 
314*484b4fd4SRuslan Bukin 	/* Clear status */
315*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
316*484b4fd4SRuslan Bukin 
317*484b4fd4SRuslan Bukin 	mtx_unlock(&sc->mutex);
318*484b4fd4SRuslan Bukin 
319*484b4fd4SRuslan Bukin 	if (error)
320*484b4fd4SRuslan Bukin 		return (error);
321*484b4fd4SRuslan Bukin 
322*484b4fd4SRuslan Bukin 	return (IIC_NOERR);
323*484b4fd4SRuslan Bukin }
324*484b4fd4SRuslan Bukin 
325*484b4fd4SRuslan Bukin static int
326*484b4fd4SRuslan Bukin i2c_start(device_t dev, u_char slave, int timeout)
327*484b4fd4SRuslan Bukin {
328*484b4fd4SRuslan Bukin 	struct i2c_softc *sc;
329*484b4fd4SRuslan Bukin 	int error;
330*484b4fd4SRuslan Bukin 
331*484b4fd4SRuslan Bukin 	sc = device_get_softc(dev);
332*484b4fd4SRuslan Bukin 
333*484b4fd4SRuslan Bukin 	mtx_lock(&sc->mutex);
334*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_ADDR_REG, slave);
335*484b4fd4SRuslan Bukin 	if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) {
336*484b4fd4SRuslan Bukin 		mtx_unlock(&sc->mutex);
337*484b4fd4SRuslan Bukin 		return (IIC_EBUSBSY);
338*484b4fd4SRuslan Bukin 	}
339*484b4fd4SRuslan Bukin 
340*484b4fd4SRuslan Bukin 	/* Set start condition */
341*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_CONTROL_REG,
342*484b4fd4SRuslan Bukin 	    I2CCR_MEN | I2CCR_MSTA | I2CCR_TXAK);
343*484b4fd4SRuslan Bukin 	DELAY(100);
344*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_CONTROL_REG,
345*484b4fd4SRuslan Bukin 	    I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX | I2CCR_TXAK);
346*484b4fd4SRuslan Bukin 	/* Clear status */
347*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
348*484b4fd4SRuslan Bukin 	/* Write target address - LSB is R/W bit */
349*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_DATA_REG, slave);
350*484b4fd4SRuslan Bukin 
351*484b4fd4SRuslan Bukin 	error = wait_for_iif(sc);
352*484b4fd4SRuslan Bukin 
353*484b4fd4SRuslan Bukin 	mtx_unlock(&sc->mutex);
354*484b4fd4SRuslan Bukin 	if (error)
355*484b4fd4SRuslan Bukin 		return (error);
356*484b4fd4SRuslan Bukin 
357*484b4fd4SRuslan Bukin 	return (IIC_NOERR);
358*484b4fd4SRuslan Bukin }
359*484b4fd4SRuslan Bukin 
360*484b4fd4SRuslan Bukin 
361*484b4fd4SRuslan Bukin static int
362*484b4fd4SRuslan Bukin i2c_stop(device_t dev)
363*484b4fd4SRuslan Bukin {
364*484b4fd4SRuslan Bukin 	struct i2c_softc *sc;
365*484b4fd4SRuslan Bukin 
366*484b4fd4SRuslan Bukin 	sc = device_get_softc(dev);
367*484b4fd4SRuslan Bukin 	mtx_lock(&sc->mutex);
368*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK);
369*484b4fd4SRuslan Bukin 	DELAY(100);
370*484b4fd4SRuslan Bukin 	/* Reset controller if bus still busy after STOP */
371*484b4fd4SRuslan Bukin 	if (wait_for_nibb(sc) == IIC_ETIMEOUT) {
372*484b4fd4SRuslan Bukin 		i2c_write_reg(sc, I2C_CONTROL_REG, 0);
373*484b4fd4SRuslan Bukin 		DELAY(1000);
374*484b4fd4SRuslan Bukin 		i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK);
375*484b4fd4SRuslan Bukin 
376*484b4fd4SRuslan Bukin 		i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
377*484b4fd4SRuslan Bukin 	}
378*484b4fd4SRuslan Bukin 	mtx_unlock(&sc->mutex);
379*484b4fd4SRuslan Bukin 
380*484b4fd4SRuslan Bukin 	return (IIC_NOERR);
381*484b4fd4SRuslan Bukin }
382*484b4fd4SRuslan Bukin 
383*484b4fd4SRuslan Bukin static int
384*484b4fd4SRuslan Bukin i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
385*484b4fd4SRuslan Bukin {
386*484b4fd4SRuslan Bukin 	struct i2c_softc *sc;
387*484b4fd4SRuslan Bukin 	uint8_t baud_rate;
388*484b4fd4SRuslan Bukin 
389*484b4fd4SRuslan Bukin 	sc = device_get_softc(dev);
390*484b4fd4SRuslan Bukin 
391*484b4fd4SRuslan Bukin 	switch (speed) {
392*484b4fd4SRuslan Bukin 	case IIC_FAST:
393*484b4fd4SRuslan Bukin 		baud_rate = I2C_BAUD_RATE_FAST;
394*484b4fd4SRuslan Bukin 		break;
395*484b4fd4SRuslan Bukin 	case IIC_SLOW:
396*484b4fd4SRuslan Bukin 	case IIC_UNKNOWN:
397*484b4fd4SRuslan Bukin 	case IIC_FASTEST:
398*484b4fd4SRuslan Bukin 	default:
399*484b4fd4SRuslan Bukin 		baud_rate = I2C_BAUD_RATE_DEF;
400*484b4fd4SRuslan Bukin 		break;
401*484b4fd4SRuslan Bukin 	}
402*484b4fd4SRuslan Bukin 
403*484b4fd4SRuslan Bukin 	mtx_lock(&sc->mutex);
404*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_CONTROL_REG, 0x0);
405*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
406*484b4fd4SRuslan Bukin 	DELAY(1000);
407*484b4fd4SRuslan Bukin 
408*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_FDR_REG, 20);
409*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN);
410*484b4fd4SRuslan Bukin 	DELAY(1000);
411*484b4fd4SRuslan Bukin 	i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
412*484b4fd4SRuslan Bukin 	mtx_unlock(&sc->mutex);
413*484b4fd4SRuslan Bukin 
414*484b4fd4SRuslan Bukin 	return (IIC_NOERR);
415*484b4fd4SRuslan Bukin }
416*484b4fd4SRuslan Bukin 
417*484b4fd4SRuslan Bukin static int
418*484b4fd4SRuslan Bukin i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay)
419*484b4fd4SRuslan Bukin {
420*484b4fd4SRuslan Bukin 	struct i2c_softc *sc;
421*484b4fd4SRuslan Bukin 	int error, reg;
422*484b4fd4SRuslan Bukin 
423*484b4fd4SRuslan Bukin 	sc = device_get_softc(dev);
424*484b4fd4SRuslan Bukin 	*read = 0;
425*484b4fd4SRuslan Bukin 
426*484b4fd4SRuslan Bukin 	mtx_lock(&sc->mutex);
427*484b4fd4SRuslan Bukin 
428*484b4fd4SRuslan Bukin 	if (len) {
429*484b4fd4SRuslan Bukin 		if (len == 1)
430*484b4fd4SRuslan Bukin 			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
431*484b4fd4SRuslan Bukin 			    I2CCR_MSTA | I2CCR_TXAK);
432*484b4fd4SRuslan Bukin 
433*484b4fd4SRuslan Bukin 		else
434*484b4fd4SRuslan Bukin 			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
435*484b4fd4SRuslan Bukin 			    I2CCR_MSTA);
436*484b4fd4SRuslan Bukin 
437*484b4fd4SRuslan Bukin 		/* dummy read */
438*484b4fd4SRuslan Bukin 		i2c_read_reg(sc, I2C_DATA_REG);
439*484b4fd4SRuslan Bukin 		DELAY(1000);
440*484b4fd4SRuslan Bukin 	}
441*484b4fd4SRuslan Bukin 
442*484b4fd4SRuslan Bukin 	while (*read < len) {
443*484b4fd4SRuslan Bukin 		error = wait_for_icf(sc);
444*484b4fd4SRuslan Bukin 		if (error) {
445*484b4fd4SRuslan Bukin 			mtx_unlock(&sc->mutex);
446*484b4fd4SRuslan Bukin 			return (error);
447*484b4fd4SRuslan Bukin 		}
448*484b4fd4SRuslan Bukin 		i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
449*484b4fd4SRuslan Bukin 		if ((*read == len - 2) && last) {
450*484b4fd4SRuslan Bukin 			/* NO ACK on last byte */
451*484b4fd4SRuslan Bukin 			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
452*484b4fd4SRuslan Bukin 			    I2CCR_MSTA | I2CCR_TXAK);
453*484b4fd4SRuslan Bukin 		}
454*484b4fd4SRuslan Bukin 
455*484b4fd4SRuslan Bukin 		if ((*read == len - 1) && last) {
456*484b4fd4SRuslan Bukin 			/* Transfer done, remove master bit */
457*484b4fd4SRuslan Bukin 			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
458*484b4fd4SRuslan Bukin 			    I2CCR_TXAK);
459*484b4fd4SRuslan Bukin 		}
460*484b4fd4SRuslan Bukin 
461*484b4fd4SRuslan Bukin 		reg = i2c_read_reg(sc, I2C_DATA_REG);
462*484b4fd4SRuslan Bukin 		*buf++ = reg;
463*484b4fd4SRuslan Bukin 		(*read)++;
464*484b4fd4SRuslan Bukin 	}
465*484b4fd4SRuslan Bukin 	mtx_unlock(&sc->mutex);
466*484b4fd4SRuslan Bukin 
467*484b4fd4SRuslan Bukin 	return (IIC_NOERR);
468*484b4fd4SRuslan Bukin }
469*484b4fd4SRuslan Bukin 
470*484b4fd4SRuslan Bukin static int
471*484b4fd4SRuslan Bukin i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
472*484b4fd4SRuslan Bukin {
473*484b4fd4SRuslan Bukin 	struct i2c_softc *sc;
474*484b4fd4SRuslan Bukin 	int error;
475*484b4fd4SRuslan Bukin 
476*484b4fd4SRuslan Bukin 	sc = device_get_softc(dev);
477*484b4fd4SRuslan Bukin 	*sent = 0;
478*484b4fd4SRuslan Bukin 
479*484b4fd4SRuslan Bukin 	mtx_lock(&sc->mutex);
480*484b4fd4SRuslan Bukin 	while (*sent < len) {
481*484b4fd4SRuslan Bukin 		i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
482*484b4fd4SRuslan Bukin 		i2c_write_reg(sc, I2C_DATA_REG, *buf++);
483*484b4fd4SRuslan Bukin 
484*484b4fd4SRuslan Bukin 		error = wait_for_iif(sc);
485*484b4fd4SRuslan Bukin 		if (error) {
486*484b4fd4SRuslan Bukin 			mtx_unlock(&sc->mutex);
487*484b4fd4SRuslan Bukin 			return (error);
488*484b4fd4SRuslan Bukin 		}
489*484b4fd4SRuslan Bukin 
490*484b4fd4SRuslan Bukin 		(*sent)++;
491*484b4fd4SRuslan Bukin 	}
492*484b4fd4SRuslan Bukin 	mtx_unlock(&sc->mutex);
493*484b4fd4SRuslan Bukin 
494*484b4fd4SRuslan Bukin 	return (IIC_NOERR);
495*484b4fd4SRuslan Bukin }
496