1262552Sbr/*- 2262552Sbr * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> 3262552Sbr * All rights reserved. 4262552Sbr * 5262552Sbr * Redistribution and use in source and binary forms, with or without 6262552Sbr * modification, are permitted provided that the following conditions 7262552Sbr * are met: 8262552Sbr * 1. Redistributions of source code must retain the above copyright 9262552Sbr * notice, this list of conditions and the following disclaimer. 10262552Sbr * 2. Redistributions in binary form must reproduce the above copyright 11262552Sbr * notice, this list of conditions and the following disclaimer in the 12262552Sbr * documentation and/or other materials provided with the distribution. 13262552Sbr * 14262552Sbr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15262552Sbr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16262552Sbr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17262552Sbr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18262552Sbr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19262552Sbr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20262552Sbr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21262552Sbr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22262552Sbr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23262552Sbr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24262552Sbr * SUCH DAMAGE. 25262552Sbr */ 26262552Sbr 27262552Sbr/* 28262552Sbr * Vybrid Family Inter-Integrated Circuit (I2C) 29262552Sbr * Chapter 48, Vybrid Reference Manual, Rev. 5, 07/2013 30262552Sbr */ 31262552Sbr 32262552Sbr/* 33273662Sian * This driver is based on the I2C driver for i.MX 34262552Sbr */ 35262552Sbr 36262552Sbr#include <sys/cdefs.h> 37262552Sbr__FBSDID("$FreeBSD: releng/10.2/sys/arm/freescale/vybrid/vf_i2c.c 273662 2014-10-26 02:40:34Z ian $"); 38262552Sbr 39262552Sbr#include <sys/param.h> 40262552Sbr#include <sys/systm.h> 41262552Sbr#include <sys/bus.h> 42262552Sbr#include <sys/kernel.h> 43262552Sbr#include <sys/module.h> 44262552Sbr#include <sys/malloc.h> 45262552Sbr#include <sys/rman.h> 46262552Sbr#include <sys/timeet.h> 47262552Sbr#include <sys/timetc.h> 48262552Sbr 49262552Sbr#include <dev/iicbus/iiconf.h> 50262552Sbr#include <dev/iicbus/iicbus.h> 51262552Sbr 52262552Sbr#include "iicbus_if.h" 53262552Sbr 54262552Sbr#include <dev/fdt/fdt_common.h> 55262552Sbr#include <dev/ofw/openfirm.h> 56262552Sbr#include <dev/ofw/ofw_bus.h> 57262552Sbr#include <dev/ofw/ofw_bus_subr.h> 58262552Sbr 59262552Sbr#include <machine/bus.h> 60262552Sbr#include <machine/fdt.h> 61262552Sbr#include <machine/cpu.h> 62262552Sbr#include <machine/intr.h> 63262552Sbr 64262552Sbr#include <arm/freescale/vybrid/vf_common.h> 65262552Sbr 66262552Sbr#define I2C_IBAD 0x0 /* I2C Bus Address Register */ 67262552Sbr#define I2C_IBFD 0x1 /* I2C Bus Frequency Divider Register */ 68262552Sbr#define I2C_IBCR 0x2 /* I2C Bus Control Register */ 69262552Sbr#define IBCR_MDIS (1 << 7) /* Module disable. */ 70262552Sbr#define IBCR_IBIE (1 << 6) /* I-Bus Interrupt Enable. */ 71262552Sbr#define IBCR_MSSL (1 << 5) /* Master/Slave mode select. */ 72262552Sbr#define IBCR_TXRX (1 << 4) /* Transmit/Receive mode select. */ 73262552Sbr#define IBCR_NOACK (1 << 3) /* Data Acknowledge disable. */ 74262552Sbr#define IBCR_RSTA (1 << 2) /* Repeat Start. */ 75262552Sbr#define IBCR_DMAEN (1 << 1) /* DMA Enable. */ 76262552Sbr#define I2C_IBSR 0x3 /* I2C Bus Status Register */ 77262552Sbr#define IBSR_TCF (1 << 7) /* Transfer complete. */ 78262552Sbr#define IBSR_IAAS (1 << 6) /* Addressed as a slave. */ 79262552Sbr#define IBSR_IBB (1 << 5) /* Bus busy. */ 80262552Sbr#define IBSR_IBAL (1 << 4) /* Arbitration Lost. */ 81262552Sbr#define IBSR_SRW (1 << 2) /* Slave Read/Write. */ 82262552Sbr#define IBSR_IBIF (1 << 1) /* I-Bus Interrupt Flag. */ 83262552Sbr#define IBSR_RXAK (1 << 0) /* Received Acknowledge. */ 84262552Sbr#define I2C_IBDR 0x4 /* I2C Bus Data I/O Register */ 85262552Sbr#define I2C_IBIC 0x5 /* I2C Bus Interrupt Config Register */ 86262552Sbr#define IBIC_BIIE (1 << 7) /* Bus Idle Interrupt Enable bit. */ 87262552Sbr#define I2C_IBDBG 0x6 /* I2C Bus Debug Register */ 88262552Sbr 89262552Sbr#ifdef DEBUG 90262552Sbr#define vf_i2c_dbg(_sc, fmt, args...) \ 91262552Sbr device_printf((_sc)->dev, fmt, ##args) 92262552Sbr#else 93262552Sbr#define vf_i2c_dbg(_sc, fmt, args...) 94262552Sbr#endif 95262552Sbr 96262552Sbrstatic int i2c_repeated_start(device_t, u_char, int); 97262552Sbrstatic int i2c_start(device_t, u_char, int); 98262552Sbrstatic int i2c_stop(device_t); 99262552Sbrstatic int i2c_reset(device_t, u_char, u_char, u_char *); 100262552Sbrstatic int i2c_read(device_t, char *, int, int *, int, int); 101262552Sbrstatic int i2c_write(device_t, const char *, int, int *, int); 102262552Sbr 103262552Sbrstruct i2c_softc { 104262552Sbr struct resource *res[2]; 105262552Sbr bus_space_tag_t bst; 106262552Sbr bus_space_handle_t bsh; 107262552Sbr device_t dev; 108262552Sbr device_t iicbus; 109262552Sbr struct mtx mutex; 110262552Sbr}; 111262552Sbr 112262552Sbrstatic struct resource_spec i2c_spec[] = { 113262552Sbr { SYS_RES_MEMORY, 0, RF_ACTIVE }, 114262552Sbr { SYS_RES_IRQ, 0, RF_ACTIVE }, 115262552Sbr { -1, 0 } 116262552Sbr}; 117262552Sbr 118262552Sbrstatic int 119262552Sbri2c_probe(device_t dev) 120262552Sbr{ 121262552Sbr 122262552Sbr if (!ofw_bus_status_okay(dev)) 123262552Sbr return (ENXIO); 124262552Sbr 125262552Sbr if (!ofw_bus_is_compatible(dev, "fsl,mvf600-i2c")) 126262552Sbr return (ENXIO); 127262552Sbr 128262552Sbr device_set_desc(dev, "Vybrid Family Inter-Integrated Circuit (I2C)"); 129262552Sbr return (BUS_PROBE_DEFAULT); 130262552Sbr} 131262552Sbr 132262552Sbrstatic int 133262552Sbri2c_attach(device_t dev) 134262552Sbr{ 135262552Sbr struct i2c_softc *sc; 136262552Sbr 137262552Sbr sc = device_get_softc(dev); 138262552Sbr sc->dev = dev; 139262552Sbr 140262552Sbr mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF); 141262552Sbr 142262552Sbr if (bus_alloc_resources(dev, i2c_spec, sc->res)) { 143262552Sbr device_printf(dev, "could not allocate resources\n"); 144262552Sbr return (ENXIO); 145262552Sbr } 146262552Sbr 147262552Sbr /* Memory interface */ 148262552Sbr sc->bst = rman_get_bustag(sc->res[0]); 149262552Sbr sc->bsh = rman_get_bushandle(sc->res[0]); 150262552Sbr 151262552Sbr WRITE1(sc, I2C_IBIC, IBIC_BIIE); 152262552Sbr 153262552Sbr sc->iicbus = device_add_child(dev, "iicbus", -1); 154262552Sbr if (sc->iicbus == NULL) { 155262552Sbr device_printf(dev, "could not add iicbus child"); 156262552Sbr mtx_destroy(&sc->mutex); 157262552Sbr return (ENXIO); 158262552Sbr } 159262552Sbr 160262552Sbr bus_generic_attach(dev); 161262552Sbr 162262552Sbr return (0); 163262552Sbr} 164262552Sbr 165262552Sbr/* Wait for transfer interrupt flag */ 166262552Sbrstatic int 167262552Sbrwait_for_iif(struct i2c_softc *sc) 168262552Sbr{ 169262552Sbr int retry; 170262552Sbr 171262552Sbr retry = 1000; 172262552Sbr while (retry --) { 173266207Sian if (READ1(sc, I2C_IBSR) & IBSR_IBIF) { 174266207Sian WRITE1(sc, I2C_IBSR, IBSR_IBIF); 175262552Sbr return (IIC_NOERR); 176266207Sian } 177262552Sbr DELAY(10); 178262552Sbr } 179262552Sbr 180262552Sbr return (IIC_ETIMEOUT); 181262552Sbr} 182262552Sbr 183262552Sbr/* Wait for free bus */ 184262552Sbrstatic int 185262552Sbrwait_for_nibb(struct i2c_softc *sc) 186262552Sbr{ 187262552Sbr int retry; 188262552Sbr 189262552Sbr retry = 1000; 190262552Sbr while (retry --) { 191262552Sbr if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0) 192262552Sbr return (IIC_NOERR); 193262552Sbr DELAY(10); 194262552Sbr } 195262552Sbr 196262552Sbr return (IIC_ETIMEOUT); 197262552Sbr} 198262552Sbr 199262552Sbr/* Wait for transfer complete+interrupt flag */ 200262552Sbrstatic int 201262552Sbrwait_for_icf(struct i2c_softc *sc) 202262552Sbr{ 203262552Sbr int retry; 204262552Sbr 205262552Sbr retry = 1000; 206262552Sbr while (retry --) { 207262552Sbr if (READ1(sc, I2C_IBSR) & IBSR_TCF) { 208266207Sian if (READ1(sc, I2C_IBSR) & IBSR_IBIF) { 209266207Sian WRITE1(sc, I2C_IBSR, IBSR_IBIF); 210262552Sbr return (IIC_NOERR); 211266207Sian } 212262552Sbr } 213262552Sbr DELAY(10); 214262552Sbr } 215262552Sbr 216262552Sbr return (IIC_ETIMEOUT); 217262552Sbr} 218262552Sbr 219262552Sbrstatic int 220262552Sbri2c_repeated_start(device_t dev, u_char slave, int timeout) 221262552Sbr{ 222262552Sbr struct i2c_softc *sc; 223262552Sbr int error; 224262552Sbr int reg; 225262552Sbr 226262552Sbr sc = device_get_softc(dev); 227262552Sbr 228262552Sbr vf_i2c_dbg(sc, "i2c repeated start\n"); 229262552Sbr 230262552Sbr mtx_lock(&sc->mutex); 231262552Sbr 232262552Sbr WRITE1(sc, I2C_IBAD, slave); 233262552Sbr 234262552Sbr if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0) { 235262552Sbr mtx_unlock(&sc->mutex); 236262552Sbr return (IIC_EBUSBSY); 237262552Sbr } 238262552Sbr 239262552Sbr /* Set repeated start condition */ 240262552Sbr DELAY(10); 241262552Sbr 242262552Sbr reg = READ1(sc, I2C_IBCR); 243262552Sbr reg |= (IBCR_RSTA | IBCR_IBIE); 244262552Sbr WRITE1(sc, I2C_IBCR, reg); 245262552Sbr 246262552Sbr DELAY(10); 247262552Sbr 248262552Sbr /* Write target address - LSB is R/W bit */ 249262552Sbr WRITE1(sc, I2C_IBDR, slave); 250262552Sbr 251262552Sbr error = wait_for_iif(sc); 252262552Sbr 253262552Sbr mtx_unlock(&sc->mutex); 254262552Sbr 255262552Sbr if (error) 256262552Sbr return (error); 257262552Sbr 258262552Sbr return (IIC_NOERR); 259262552Sbr} 260262552Sbr 261262552Sbrstatic int 262262552Sbri2c_start(device_t dev, u_char slave, int timeout) 263262552Sbr{ 264262552Sbr struct i2c_softc *sc; 265262552Sbr int error; 266262552Sbr int reg; 267262552Sbr 268262552Sbr sc = device_get_softc(dev); 269262552Sbr 270262552Sbr vf_i2c_dbg(sc, "i2c start\n"); 271262552Sbr 272262552Sbr mtx_lock(&sc->mutex); 273262552Sbr 274262552Sbr WRITE1(sc, I2C_IBAD, slave); 275262552Sbr 276262552Sbr if (READ1(sc, I2C_IBSR) & IBSR_IBB) { 277262552Sbr mtx_unlock(&sc->mutex); 278262552Sbr vf_i2c_dbg(sc, "cant i2c start: IIC_EBUSBSY\n"); 279262552Sbr return (IIC_EBUSBSY); 280262552Sbr } 281262552Sbr 282262552Sbr /* Set start condition */ 283262552Sbr reg = (IBCR_MSSL | IBCR_NOACK | IBCR_IBIE); 284262552Sbr WRITE1(sc, I2C_IBCR, reg); 285262552Sbr 286262552Sbr DELAY(100); 287262552Sbr 288262552Sbr reg |= (IBCR_TXRX); 289262552Sbr WRITE1(sc, I2C_IBCR, reg); 290262552Sbr 291262552Sbr /* Write target address - LSB is R/W bit */ 292262552Sbr WRITE1(sc, I2C_IBDR, slave); 293262552Sbr 294262552Sbr error = wait_for_iif(sc); 295262552Sbr 296262552Sbr mtx_unlock(&sc->mutex); 297262552Sbr if (error) { 298262552Sbr vf_i2c_dbg(sc, "cant i2c start: iif error\n"); 299262552Sbr return (error); 300262552Sbr } 301262552Sbr 302262552Sbr return (IIC_NOERR); 303262552Sbr} 304262552Sbr 305262552Sbrstatic int 306262552Sbri2c_stop(device_t dev) 307262552Sbr{ 308262552Sbr struct i2c_softc *sc; 309262552Sbr 310262552Sbr sc = device_get_softc(dev); 311262552Sbr 312262552Sbr vf_i2c_dbg(sc, "i2c stop\n"); 313262552Sbr 314262552Sbr mtx_lock(&sc->mutex); 315262552Sbr 316262552Sbr WRITE1(sc, I2C_IBCR, IBCR_NOACK | IBCR_IBIE); 317262552Sbr 318262552Sbr DELAY(100); 319262552Sbr 320262552Sbr /* Reset controller if bus still busy after STOP */ 321262552Sbr if (wait_for_nibb(sc) == IIC_ETIMEOUT) { 322262552Sbr WRITE1(sc, I2C_IBCR, IBCR_MDIS); 323262552Sbr DELAY(1000); 324262552Sbr WRITE1(sc, I2C_IBCR, IBCR_NOACK); 325262552Sbr } 326262552Sbr mtx_unlock(&sc->mutex); 327262552Sbr 328262552Sbr return (IIC_NOERR); 329262552Sbr} 330262552Sbr 331262552Sbrstatic int 332262552Sbri2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) 333262552Sbr{ 334262552Sbr struct i2c_softc *sc; 335262552Sbr 336262552Sbr sc = device_get_softc(dev); 337262552Sbr 338262552Sbr vf_i2c_dbg(sc, "i2c reset\n"); 339262552Sbr 340262552Sbr switch (speed) { 341262552Sbr case IIC_FAST: 342262552Sbr case IIC_SLOW: 343262552Sbr case IIC_UNKNOWN: 344262552Sbr case IIC_FASTEST: 345262552Sbr default: 346262552Sbr break; 347262552Sbr } 348262552Sbr 349262552Sbr mtx_lock(&sc->mutex); 350262552Sbr WRITE1(sc, I2C_IBCR, IBCR_MDIS); 351262552Sbr 352262552Sbr DELAY(1000); 353262552Sbr 354262552Sbr WRITE1(sc, I2C_IBFD, 20); 355262552Sbr WRITE1(sc, I2C_IBCR, 0x0); /* Enable i2c */ 356262552Sbr 357262552Sbr DELAY(1000); 358262552Sbr 359262552Sbr mtx_unlock(&sc->mutex); 360262552Sbr 361262552Sbr return (IIC_NOERR); 362262552Sbr} 363262552Sbr 364262552Sbrstatic int 365262552Sbri2c_read(device_t dev, char *buf, int len, int *read, int last, int delay) 366262552Sbr{ 367262552Sbr struct i2c_softc *sc; 368262552Sbr int error; 369262552Sbr 370262552Sbr sc = device_get_softc(dev); 371262552Sbr 372262552Sbr vf_i2c_dbg(sc, "i2c read\n"); 373262552Sbr 374262552Sbr *read = 0; 375262552Sbr 376262552Sbr mtx_lock(&sc->mutex); 377262552Sbr 378262552Sbr if (len) { 379262552Sbr if (len == 1) 380262552Sbr WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL | \ 381262552Sbr IBCR_NOACK); 382262552Sbr else 383262552Sbr WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL); 384262552Sbr 385262552Sbr /* dummy read */ 386262552Sbr READ1(sc, I2C_IBDR); 387262552Sbr DELAY(1000); 388262552Sbr } 389262552Sbr 390262552Sbr while (*read < len) { 391262552Sbr error = wait_for_icf(sc); 392262552Sbr if (error) { 393262552Sbr mtx_unlock(&sc->mutex); 394262552Sbr return (error); 395262552Sbr } 396262552Sbr 397262552Sbr if ((*read == len - 2) && last) { 398262552Sbr /* NO ACK on last byte */ 399262552Sbr WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL | \ 400262552Sbr IBCR_NOACK); 401262552Sbr } 402262552Sbr 403262552Sbr if ((*read == len - 1) && last) { 404262552Sbr /* Transfer done, remove master bit */ 405262552Sbr WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_NOACK); 406262552Sbr } 407262552Sbr 408262552Sbr *buf++ = READ1(sc, I2C_IBDR); 409262552Sbr (*read)++; 410262552Sbr } 411262552Sbr mtx_unlock(&sc->mutex); 412262552Sbr 413262552Sbr return (IIC_NOERR); 414262552Sbr} 415262552Sbr 416262552Sbrstatic int 417262552Sbri2c_write(device_t dev, const char *buf, int len, int *sent, int timeout) 418262552Sbr{ 419262552Sbr struct i2c_softc *sc; 420262552Sbr int error; 421262552Sbr 422262552Sbr sc = device_get_softc(dev); 423262552Sbr 424262552Sbr vf_i2c_dbg(sc, "i2c write\n"); 425262552Sbr 426262552Sbr *sent = 0; 427262552Sbr 428262552Sbr mtx_lock(&sc->mutex); 429262552Sbr while (*sent < len) { 430262552Sbr 431262552Sbr WRITE1(sc, I2C_IBDR, *buf++); 432262552Sbr 433262552Sbr error = wait_for_iif(sc); 434262552Sbr if (error) { 435262552Sbr mtx_unlock(&sc->mutex); 436262552Sbr return (error); 437262552Sbr } 438262552Sbr 439262552Sbr (*sent)++; 440262552Sbr } 441262552Sbr mtx_unlock(&sc->mutex); 442262552Sbr 443262552Sbr return (IIC_NOERR); 444262552Sbr} 445262552Sbr 446262552Sbrstatic device_method_t i2c_methods[] = { 447262552Sbr DEVMETHOD(device_probe, i2c_probe), 448262552Sbr DEVMETHOD(device_attach, i2c_attach), 449262552Sbr 450262552Sbr DEVMETHOD(iicbus_callback, iicbus_null_callback), 451262552Sbr DEVMETHOD(iicbus_repeated_start, i2c_repeated_start), 452262552Sbr DEVMETHOD(iicbus_start, i2c_start), 453262552Sbr DEVMETHOD(iicbus_stop, i2c_stop), 454262552Sbr DEVMETHOD(iicbus_reset, i2c_reset), 455262552Sbr DEVMETHOD(iicbus_read, i2c_read), 456262552Sbr DEVMETHOD(iicbus_write, i2c_write), 457262552Sbr DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), 458262552Sbr 459262552Sbr { 0, 0 } 460262552Sbr}; 461262552Sbr 462262552Sbrstatic driver_t i2c_driver = { 463262552Sbr "i2c", 464262552Sbr i2c_methods, 465262552Sbr sizeof(struct i2c_softc), 466262552Sbr}; 467262552Sbr 468262552Sbrstatic devclass_t i2c_devclass; 469262552Sbr 470262552SbrDRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0); 471262552SbrDRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0); 472