xref: /freebsd/sys/powerpc/mpc85xx/i2c.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
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 	{ 0, 0 }
118 };
119 
120 static driver_t i2c_driver = {
121 	"iichb",
122 	i2c_methods,
123 	sizeof(struct i2c_softc),
124 };
125 
126 DRIVER_MODULE(i2c, simplebus, i2c_driver, 0, 0);
127 DRIVER_MODULE(iicbus, i2c, iicbus_driver, 0, 0);
128 
129 static __inline void
130 i2c_write_reg(struct i2c_softc *sc, bus_size_t off, uint8_t val)
131 {
132 
133 	bus_space_write_1(sc->bst, sc->bsh, off, val);
134 }
135 
136 static __inline uint8_t
137 i2c_read_reg(struct i2c_softc *sc, bus_size_t off)
138 {
139 
140 	return (bus_space_read_1(sc->bst, sc->bsh, off));
141 }
142 
143 static __inline void
144 i2c_flag_set(struct i2c_softc *sc, bus_size_t off, uint8_t mask)
145 {
146 	uint8_t status;
147 
148 	status = i2c_read_reg(sc, off);
149 	status |= mask;
150 	i2c_write_reg(sc, off, status);
151 }
152 
153 static int
154 i2c_do_wait(device_t dev, struct i2c_softc *sc, int write, int start)
155 {
156 	int err;
157 	uint8_t status;
158 
159 	status = i2c_read_reg(sc, I2C_STATUS_REG);
160 	if (status & I2CSR_MIF) {
161 		if (write && start && (status & I2CSR_RXAK)) {
162 			debugf("no ack %s", start ?
163 			    "after sending slave address" : "");
164 			err = IIC_ENOACK;
165 			goto error;
166 		}
167 		if (status & I2CSR_MAL) {
168 			debugf("arbitration lost");
169 			err = IIC_EBUSERR;
170 			goto error;
171 		}
172 		if (!write && !(status & I2CSR_MCF)) {
173 			debugf("transfer unfinished");
174 			err = IIC_EBUSERR;
175 			goto error;
176 		}
177 	}
178 
179 	return (IIC_NOERR);
180 
181 error:
182 	i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
183 	i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK);
184 	return (err);
185 }
186 
187 static int
188 i2c_probe(device_t dev)
189 {
190 	struct i2c_softc *sc;
191 
192 	if (!ofw_bus_is_compatible(dev, "fsl-i2c"))
193 		return (ENXIO);
194 
195 	sc = device_get_softc(dev);
196 	sc->rid = 0;
197 
198 	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
199 	    RF_ACTIVE);
200 	if (sc->res == NULL) {
201 		device_printf(dev, "could not allocate resources\n");
202 		return (ENXIO);
203 	}
204 
205 	sc->bst = rman_get_bustag(sc->res);
206 	sc->bsh = rman_get_bushandle(sc->res);
207 
208 	/* Enable I2C */
209 	i2c_write_reg(sc, I2C_CONTROL_REG, I2C_ENABLE);
210 	bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res);
211 	device_set_desc(dev, "I2C bus controller");
212 
213 	return (BUS_PROBE_DEFAULT);
214 }
215 
216 static int
217 i2c_attach(device_t dev)
218 {
219 	struct i2c_softc *sc;
220 	sc = device_get_softc(dev);
221 
222 	sc->dev = dev;
223 	sc->rid = 0;
224 
225 	mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);
226 
227 	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
228 	    RF_ACTIVE);
229 	if (sc->res == NULL) {
230 		device_printf(dev, "could not allocate resources");
231 		mtx_destroy(&sc->mutex);
232 		return (ENXIO);
233 	}
234 
235 	sc->bst = rman_get_bustag(sc->res);
236 	sc->bsh = rman_get_bushandle(sc->res);
237 
238 	sc->iicbus = device_add_child(dev, "iicbus", -1);
239 	if (sc->iicbus == NULL) {
240 		device_printf(dev, "could not add iicbus child");
241 		mtx_destroy(&sc->mutex);
242 		return (ENXIO);
243 	}
244 
245 	bus_generic_attach(dev);
246 	return (IIC_NOERR);
247 }
248 static int
249 i2c_repeated_start(device_t dev, u_char slave, int timeout)
250 {
251 	struct i2c_softc *sc;
252 	int error;
253 
254 	sc = device_get_softc(dev);
255 
256 	mtx_lock(&sc->mutex);
257 	/* Set repeated start condition */
258 	i2c_flag_set(sc, I2C_CONTROL_REG ,I2CCR_RSTA);
259 	/* Write target address - LSB is R/W bit */
260 	i2c_write_reg(sc, I2C_DATA_REG, slave);
261 	DELAY(1250);
262 
263 	error = i2c_do_wait(dev, sc, 1, 1);
264 	mtx_unlock(&sc->mutex);
265 
266 	if (error)
267 		return (error);
268 
269 	return (IIC_NOERR);
270 }
271 
272 static int
273 i2c_start(device_t dev, u_char slave, int timeout)
274 {
275 	struct i2c_softc *sc;
276 	uint8_t status;
277 	int error;
278 
279 	sc = device_get_softc(dev);
280 	DELAY(1000);
281 
282 	mtx_lock(&sc->mutex);
283 	status = i2c_read_reg(sc, I2C_STATUS_REG);
284 	/* Check if bus is idle or busy */
285 	if (status & I2CSR_MBB) {
286 		debugf("bus busy");
287 		mtx_unlock(&sc->mutex);
288 		i2c_stop(dev);
289 		return (IIC_EBUSERR);
290 	}
291 
292 	/* Set start condition */
293 	i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX);
294 	/* Write target address - LSB is R/W bit */
295 	i2c_write_reg(sc, I2C_DATA_REG, slave);
296 	DELAY(1250);
297 
298 	error = i2c_do_wait(dev, sc, 1, 1);
299 
300 	mtx_unlock(&sc->mutex);
301 	if (error)
302 		return (error);
303 
304 	return (IIC_NOERR);
305 }
306 
307 static int
308 i2c_stop(device_t dev)
309 {
310 	struct i2c_softc *sc;
311 
312 	sc = device_get_softc(dev);
313 	mtx_lock(&sc->mutex);
314 	i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK);
315 	DELAY(1000);
316 	mtx_unlock(&sc->mutex);
317 
318 	return (IIC_NOERR);
319 }
320 
321 static int
322 i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
323 {
324 	struct i2c_softc *sc;
325 	uint8_t baud_rate;
326 
327 	sc = device_get_softc(dev);
328 
329 	switch (speed) {
330 	case IIC_FAST:
331 		baud_rate = I2C_BAUD_RATE_FAST;
332 		break;
333 	case IIC_SLOW:
334 	case IIC_UNKNOWN:
335 	case IIC_FASTEST:
336 	default:
337 		baud_rate = I2C_BAUD_RATE_DEF;
338 		break;
339 	}
340 
341 	mtx_lock(&sc->mutex);
342 	i2c_write_reg(sc, I2C_CONTROL_REG, 0x0);
343 	i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
344 	DELAY(1000);
345 	i2c_write_reg(sc, I2C_FDR_REG, baud_rate);
346 	i2c_write_reg(sc, I2C_DFSRR_REG, I2C_DFSSR_DIV);
347 	i2c_write_reg(sc, I2C_CONTROL_REG, I2C_ENABLE);
348 	DELAY(1000);
349 	mtx_unlock(&sc->mutex);
350 
351 	return (IIC_NOERR);
352 }
353 
354 static int
355 i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay)
356 {
357 	struct i2c_softc *sc;
358 	int error;
359 
360 	sc = device_get_softc(dev);
361 	*read = 0;
362 
363 	mtx_lock(&sc->mutex);
364 	if (len) {
365 		if (len == 1)
366 			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
367 			    I2CCR_MSTA | I2CCR_TXAK);
368 
369 		else
370 			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
371 			    I2CCR_MSTA);
372 
373 		/* dummy read */
374 		i2c_read_reg(sc, I2C_DATA_REG);
375 		DELAY(1000);
376 	}
377 
378 	while (*read < len) {
379 		DELAY(1000);
380 		error = i2c_do_wait(dev, sc, 0, 0);
381 		if (error) {
382 			mtx_unlock(&sc->mutex);
383 			return (error);
384 		}
385 		if ((*read == len - 2) && last) {
386 			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
387 			    I2CCR_MSTA | I2CCR_TXAK);
388 		}
389 
390 		if ((*read == len - 1) && last) {
391 			i2c_write_reg(sc, I2C_CONTROL_REG,  I2CCR_MEN |
392 			    I2CCR_TXAK);
393 		}
394 
395 		*buf++ = i2c_read_reg(sc, I2C_DATA_REG);
396 		(*read)++;
397 		DELAY(1250);
398 	}
399 	mtx_unlock(&sc->mutex);
400 
401 	return (IIC_NOERR);
402 }
403 
404 static int
405 i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
406 {
407 	struct i2c_softc *sc;
408 	int error;
409 
410 	sc = device_get_softc(dev);
411 	*sent = 0;
412 
413 	mtx_lock(&sc->mutex);
414 	while (*sent < len) {
415 		i2c_write_reg(sc, I2C_DATA_REG, *buf++);
416 		DELAY(1250);
417 
418 		error = i2c_do_wait(dev, sc, 1, 0);
419 		if (error) {
420 			mtx_unlock(&sc->mutex);
421 			return (error);
422 		}
423 
424 		(*sent)++;
425 	}
426 	mtx_unlock(&sc->mutex);
427 
428 	return (IIC_NOERR);
429 }
430 
431 static phandle_t
432 i2c_get_node(device_t bus, device_t dev)
433 {
434 
435 	/* Share controller node with iibus device. */
436 	return (ofw_bus_get_node(bus));
437 }
438