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