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