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