2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
5 * Developed by Semihalf.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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 * 3. Neither the name of MARVELL nor the names of contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * Driver for the TWSI (aka I2C, aka IIC) bus controller found on Marvell
34 * SoCs. Supports master operation only, and works in polling mode.
36 * Calls to DELAY() are needed per Application Note AN-179 "TWSI Software
37 * Guidelines for Discovery(TM), Horizon (TM) and Feroceon(TM) Devices".
40 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD$");
43 #include <sys/param.h>
44 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/module.h>
48 #include <sys/resource.h>
50 #include <machine/bus.h>
51 #include <machine/resource.h>
56 #include <sys/mutex.h>
58 #include <dev/iicbus/iiconf.h>
59 #include <dev/iicbus/iicbus.h>
60 #include <dev/ofw/ofw_bus.h>
61 #include <dev/ofw/ofw_bus_subr.h>
63 #include "iicbus_if.h"
65 #define MV_TWSI_NAME "twsi"
67 #define TWSI_SLAVE_ADDR 0x00
68 #define TWSI_EXT_SLAVE_ADDR 0x10
69 #define TWSI_DATA 0x04
71 #define TWSI_CONTROL 0x08
72 #define TWSI_CONTROL_ACK (1 << 2)
73 #define TWSI_CONTROL_IFLG (1 << 3)
74 #define TWSI_CONTROL_STOP (1 << 4)
75 #define TWSI_CONTROL_START (1 << 5)
76 #define TWSI_CONTROL_TWSIEN (1 << 6)
77 #define TWSI_CONTROL_INTEN (1 << 7)
79 #define TWSI_STATUS 0x0c
80 #define TWSI_STATUS_START 0x08
81 #define TWSI_STATUS_RPTD_START 0x10
82 #define TWSI_STATUS_ADDR_W_ACK 0x18
83 #define TWSI_STATUS_DATA_WR_ACK 0x28
84 #define TWSI_STATUS_ADDR_R_ACK 0x40
85 #define TWSI_STATUS_DATA_RD_ACK 0x50
86 #define TWSI_STATUS_DATA_RD_NOACK 0x58
88 #define TWSI_BAUD_RATE 0x0c
89 #define TWSI_BAUD_RATE_94DOT3 0x53 /* N=3, M=10 */
90 #define TWSI_BAUD_RATE_74DOT1 0x6b /* N=3, M=13 */
91 #define TWSI_BAUD_RATE_51DOT8 0x4c /* N=4, M=9 */
92 #define TWSI_BAUD_RATE_99DOT7 0x66 /* N=6, M=12 */
94 #define TWSI_SOFT_RESET 0x1c
100 #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0)
102 #define debugf(fmt, args...)
105 struct mv_twsi_softc {
107 struct resource *res[1]; /* SYS_RES_MEMORY */
112 static int mv_twsi_probe(device_t);
113 static int mv_twsi_attach(device_t);
114 static int mv_twsi_detach(device_t);
116 static int mv_twsi_reset(device_t dev, u_char speed, u_char addr,
118 static int mv_twsi_repeated_start(device_t dev, u_char slave, int timeout);
119 static int mv_twsi_start(device_t dev, u_char slave, int timeout);
120 static int mv_twsi_stop(device_t dev);
121 static int mv_twsi_read(device_t dev, char *buf, int len, int *read, int last,
123 static int mv_twsi_write(device_t dev, const char *buf, int len, int *sent,
126 static struct resource_spec res_spec[] = {
127 { SYS_RES_MEMORY, 0, RF_ACTIVE },
131 static device_method_t mv_twsi_methods[] = {
132 /* device interface */
133 DEVMETHOD(device_probe, mv_twsi_probe),
134 DEVMETHOD(device_attach, mv_twsi_attach),
135 DEVMETHOD(device_detach, mv_twsi_detach),
137 /* iicbus interface */
138 DEVMETHOD(iicbus_callback, iicbus_null_callback),
139 DEVMETHOD(iicbus_repeated_start, mv_twsi_repeated_start),
140 DEVMETHOD(iicbus_start, mv_twsi_start),
141 DEVMETHOD(iicbus_stop, mv_twsi_stop),
142 DEVMETHOD(iicbus_write, mv_twsi_write),
143 DEVMETHOD(iicbus_read, mv_twsi_read),
144 DEVMETHOD(iicbus_reset, mv_twsi_reset),
145 DEVMETHOD(iicbus_transfer, iicbus_transfer_gen),
149 static devclass_t mv_twsi_devclass;
151 static driver_t mv_twsi_driver = {
154 sizeof(struct mv_twsi_softc),
157 DRIVER_MODULE(twsi, simplebus, mv_twsi_driver, mv_twsi_devclass, 0, 0);
158 DRIVER_MODULE(iicbus, twsi, iicbus_driver, iicbus_devclass, 0, 0);
159 MODULE_DEPEND(twsi, iicbus, 1, 1, 1);
161 static __inline uint32_t
162 TWSI_READ(struct mv_twsi_softc *sc, bus_size_t off)
165 return (bus_read_4(sc->res[0], off));
169 TWSI_WRITE(struct mv_twsi_softc *sc, bus_size_t off, uint32_t val)
172 bus_write_4(sc->res[0], off, val);
176 twsi_control_clear(struct mv_twsi_softc *sc, uint32_t mask)
180 val = TWSI_READ(sc, TWSI_CONTROL);
182 TWSI_WRITE(sc, TWSI_CONTROL, val);
186 twsi_control_set(struct mv_twsi_softc *sc, uint32_t mask)
190 val = TWSI_READ(sc, TWSI_CONTROL);
192 TWSI_WRITE(sc, TWSI_CONTROL, val);
196 twsi_clear_iflg(struct mv_twsi_softc *sc)
200 twsi_control_clear(sc, TWSI_CONTROL_IFLG);
206 * timeout given in us
208 * 0 on sucessfull mask change
209 * non-zero on timeout
212 twsi_poll_ctrl(struct mv_twsi_softc *sc, int timeout, uint32_t mask)
216 while (!(TWSI_READ(sc, TWSI_CONTROL) & mask)) {
226 * 'timeout' is given in us. Note also that timeout handling is not exact --
227 * twsi_locked_start() total wait can be more than 2 x timeout
228 * (twsi_poll_ctrl() is called twice). 'mask' can be either TWSI_STATUS_START
229 * or TWSI_STATUS_RPTD_START
232 twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask,
233 u_char slave, int timeout)
235 int read_access, iflg_set = 0;
238 mtx_assert(&sc->mutex, MA_OWNED);
240 if (mask == TWSI_STATUS_RPTD_START)
241 /* read IFLG to know if it should be cleared later; from NBSD */
242 iflg_set = TWSI_READ(sc, TWSI_CONTROL) & TWSI_CONTROL_IFLG;
244 twsi_control_set(sc, TWSI_CONTROL_START);
246 if (mask == TWSI_STATUS_RPTD_START && iflg_set) {
247 debugf("IFLG set, clearing\n");
252 * Without this delay we timeout checking IFLG if the timeout is 0.
253 * NBSD driver always waits here too.
257 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
258 debugf("timeout sending %sSTART condition\n",
259 mask == TWSI_STATUS_START ? "" : "repeated ");
260 return (IIC_ETIMEOUT);
263 status = TWSI_READ(sc, TWSI_STATUS);
264 if (status != mask) {
265 debugf("wrong status (%02x) after sending %sSTART condition\n",
266 status, mask == TWSI_STATUS_START ? "" : "repeated ");
267 return (IIC_ESTATUS);
270 TWSI_WRITE(sc, TWSI_DATA, slave);
274 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
275 debugf("timeout sending slave address\n");
276 return (IIC_ETIMEOUT);
279 read_access = (slave & 0x1) ? 1 : 0;
280 status = TWSI_READ(sc, TWSI_STATUS);
281 if (status != (read_access ?
282 TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) {
283 debugf("no ACK (status: %02x) after sending slave address\n",
292 mv_twsi_probe(device_t dev)
295 if (!ofw_bus_is_compatible(dev, "mrvl,twsi"))
298 device_set_desc(dev, "Marvell Integrated I2C Bus Controller");
299 return (BUS_PROBE_DEFAULT);
303 mv_twsi_attach(device_t dev)
305 struct mv_twsi_softc *sc;
307 sc = device_get_softc(dev);
310 mtx_init(&sc->mutex, device_get_nameunit(dev), MV_TWSI_NAME, MTX_DEF);
312 /* Allocate IO resources */
313 if (bus_alloc_resources(dev, res_spec, sc->res)) {
314 device_printf(dev, "could not allocate resources\n");
319 sc->iicbus = device_add_child(dev, "iicbus", -1);
320 if (sc->iicbus == NULL) {
321 device_printf(dev, "could not add iicbus child\n");
326 bus_generic_attach(dev);
331 mv_twsi_detach(device_t dev)
333 struct mv_twsi_softc *sc;
336 sc = device_get_softc(dev);
338 if ((rv = bus_generic_detach(dev)) != 0)
341 if (sc->iicbus != NULL)
342 if ((rv = device_delete_child(dev, sc->iicbus)) != 0)
345 bus_release_resources(dev, res_spec, sc->res);
347 mtx_destroy(&sc->mutex);
352 * Only slave mode supported, disregard [old]addr
355 mv_twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
357 struct mv_twsi_softc *sc;
360 sc = device_get_softc(dev);
364 baud_rate = TWSI_BAUD_RATE_51DOT8;
367 baud_rate = TWSI_BAUD_RATE_51DOT8;
372 baud_rate = TWSI_BAUD_RATE_99DOT7;
376 mtx_lock(&sc->mutex);
377 TWSI_WRITE(sc, TWSI_SOFT_RESET, 0x0);
379 TWSI_WRITE(sc, TWSI_BAUD_RATE, baud_rate);
380 TWSI_WRITE(sc, TWSI_CONTROL, TWSI_CONTROL_TWSIEN | TWSI_CONTROL_ACK);
382 mtx_unlock(&sc->mutex);
388 * timeout is given in us
391 mv_twsi_repeated_start(device_t dev, u_char slave, int timeout)
393 struct mv_twsi_softc *sc;
396 sc = device_get_softc(dev);
398 mtx_lock(&sc->mutex);
399 rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave,
401 mtx_unlock(&sc->mutex);
411 * timeout is given in us
414 mv_twsi_start(device_t dev, u_char slave, int timeout)
416 struct mv_twsi_softc *sc;
419 sc = device_get_softc(dev);
421 mtx_lock(&sc->mutex);
422 rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout);
423 mtx_unlock(&sc->mutex);
433 mv_twsi_stop(device_t dev)
435 struct mv_twsi_softc *sc;
437 sc = device_get_softc(dev);
439 mtx_lock(&sc->mutex);
440 twsi_control_set(sc, TWSI_CONTROL_STOP);
443 mtx_unlock(&sc->mutex);
449 mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay)
451 struct mv_twsi_softc *sc;
455 sc = device_get_softc(dev);
457 mtx_lock(&sc->mutex);
459 while (*read < len) {
461 * Check if we are reading last byte of the last buffer,
462 * do not send ACK then, per I2C specs
464 last_byte = ((*read == len - 1) && last) ? 1 : 0;
466 twsi_control_clear(sc, TWSI_CONTROL_ACK);
468 twsi_control_set(sc, TWSI_CONTROL_ACK);
473 if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) {
474 debugf("timeout reading data\n");
479 status = TWSI_READ(sc, TWSI_STATUS);
480 if (status != (last_byte ?
481 TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) {
482 debugf("wrong status (%02x) while reading\n", status);
487 *buf++ = TWSI_READ(sc, TWSI_DATA);
492 mtx_unlock(&sc->mutex);
497 mv_twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout)
499 struct mv_twsi_softc *sc;
503 sc = device_get_softc(dev);
505 mtx_lock(&sc->mutex);
507 while (*sent < len) {
508 TWSI_WRITE(sc, TWSI_DATA, *buf++);
511 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
512 debugf("timeout writing data\n");
517 status = TWSI_READ(sc, TWSI_STATUS);
518 if (status != TWSI_STATUS_DATA_WR_ACK) {
519 debugf("wrong status (%02x) while writing\n", status);
527 mtx_unlock(&sc->mutex);