1248557Sray/*- 2248557Sray * Copyright (C) 2008-2009 Semihalf, Michal Hajduk 3250357Sray * Copyright (c) 2012, 2013 The FreeBSD Foundation 4248557Sray * All rights reserved. 5248557Sray * 6248557Sray * Portions of this software were developed by Oleksandr Rybalko 7248557Sray * under sponsorship from the FreeBSD Foundation. 8248557Sray * 9248557Sray * Redistribution and use in source and binary forms, with or without 10248557Sray * modification, are permitted provided that the following conditions 11248557Sray * are met: 12248557Sray * 1. Redistributions of source code must retain the above copyright 13248557Sray * notice, this list of conditions and the following disclaimer. 14248557Sray * 2. Redistributions in binary form must reproduce the above copyright 15248557Sray * notice, this list of conditions and the following disclaimer in the 16248557Sray * documentation and/or other materials provided with the distribution. 17248557Sray * 18248557Sray * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19248557Sray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20248557Sray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21248557Sray * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 22248557Sray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23248557Sray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24248557Sray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25248557Sray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26248557Sray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27248557Sray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28248557Sray * SUCH DAMAGE. 29248557Sray */ 30248557Sray 31248557Sray#include <sys/cdefs.h> 32248557Sray__FBSDID("$FreeBSD$"); 33248557Sray 34248557Sray#include <sys/param.h> 35248557Sray#include <sys/systm.h> 36248557Sray#include <sys/bus.h> 37248557Sray#include <sys/kernel.h> 38248557Sray#include <sys/module.h> 39248557Sray#include <sys/resource.h> 40248557Sray 41248557Sray#include <machine/bus.h> 42248557Sray#include <machine/resource.h> 43248557Sray#include <sys/rman.h> 44248557Sray 45248557Sray#include <sys/lock.h> 46248557Sray#include <sys/mutex.h> 47248557Sray 48248557Sray#include <dev/iicbus/iiconf.h> 49248557Sray#include <dev/iicbus/iicbus.h> 50248557Sray#include "iicbus_if.h" 51248557Sray 52248557Sray#include <dev/fdt/fdt_common.h> 53248557Sray#include <dev/ofw/openfirm.h> 54248557Sray#include <dev/ofw/ofw_bus.h> 55248557Sray#include <dev/ofw/ofw_bus_subr.h> 56248557Sray 57248557Sray#define I2C_ADDR_REG 0x00 /* I2C slave address register */ 58248557Sray#define I2C_FDR_REG 0x04 /* I2C frequency divider register */ 59248557Sray#define I2C_CONTROL_REG 0x08 /* I2C control register */ 60248557Sray#define I2C_STATUS_REG 0x0C /* I2C status register */ 61248557Sray#define I2C_DATA_REG 0x10 /* I2C data register */ 62248557Sray#define I2C_DFSRR_REG 0x14 /* I2C Digital Filter Sampling rate */ 63248557Sray 64248557Sray#define I2CCR_MEN (1 << 7) /* Module enable */ 65248557Sray#define I2CCR_MSTA (1 << 5) /* Master/slave mode */ 66248557Sray#define I2CCR_MTX (1 << 4) /* Transmit/receive mode */ 67248557Sray#define I2CCR_TXAK (1 << 3) /* Transfer acknowledge */ 68248557Sray#define I2CCR_RSTA (1 << 2) /* Repeated START */ 69248557Sray 70248557Sray#define I2CSR_MCF (1 << 7) /* Data transfer */ 71248557Sray#define I2CSR_MASS (1 << 6) /* Addressed as a slave */ 72248557Sray#define I2CSR_MBB (1 << 5) /* Bus busy */ 73248557Sray#define I2CSR_MAL (1 << 4) /* Arbitration lost */ 74248557Sray#define I2CSR_SRW (1 << 2) /* Slave read/write */ 75248557Sray#define I2CSR_MIF (1 << 1) /* Module interrupt */ 76248557Sray#define I2CSR_RXAK (1 << 0) /* Received acknowledge */ 77248557Sray 78248557Sray#define I2C_BAUD_RATE_FAST 0x31 79248557Sray#define I2C_BAUD_RATE_DEF 0x3F 80248557Sray#define I2C_DFSSR_DIV 0x10 81248557Sray 82248557Sray#ifdef DEBUG 83248557Sray#define debugf(fmt, args...) do { printf("%s(): ", __func__); \ 84248557Sray printf(fmt,##args); } while (0) 85248557Sray#else 86248557Sray#define debugf(fmt, args...) 87248557Sray#endif 88248557Sray 89248557Sraystruct i2c_softc { 90248557Sray device_t dev; 91248557Sray device_t iicbus; 92248557Sray struct resource *res; 93248557Sray struct mtx mutex; 94248557Sray int rid; 95248557Sray bus_space_handle_t bsh; 96248557Sray bus_space_tag_t bst; 97248557Sray}; 98248557Sray 99248557Sraystatic phandle_t i2c_get_node(device_t, device_t); 100248557Sraystatic int i2c_probe(device_t); 101248557Sraystatic int i2c_attach(device_t); 102248557Sray 103248557Sraystatic int i2c_repeated_start(device_t, u_char, int); 104248557Sraystatic int i2c_start(device_t, u_char, int); 105248557Sraystatic int i2c_stop(device_t); 106248557Sraystatic int i2c_reset(device_t, u_char, u_char, u_char *); 107248557Sraystatic int i2c_read(device_t, char *, int, int *, int, int); 108248557Sraystatic int i2c_write(device_t, const char *, int, int *, int); 109248557Sray 110248557Sraystatic device_method_t i2c_methods[] = { 111248557Sray DEVMETHOD(device_probe, i2c_probe), 112248557Sray DEVMETHOD(device_attach, i2c_attach), 113248557Sray 114248557Sray /* OFW methods */ 115248557Sray DEVMETHOD(ofw_bus_get_node, i2c_get_node), 116248557Sray 117248557Sray DEVMETHOD(iicbus_callback, iicbus_null_callback), 118248557Sray DEVMETHOD(iicbus_repeated_start, i2c_repeated_start), 119248557Sray DEVMETHOD(iicbus_start, i2c_start), 120248557Sray DEVMETHOD(iicbus_stop, i2c_stop), 121248557Sray DEVMETHOD(iicbus_reset, i2c_reset), 122248557Sray DEVMETHOD(iicbus_read, i2c_read), 123248557Sray DEVMETHOD(iicbus_write, i2c_write), 124248557Sray DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), 125248557Sray 126248557Sray { 0, 0 } 127248557Sray}; 128248557Sray 129248557Sraystatic driver_t i2c_driver = { 130248557Sray "iichb", 131248557Sray i2c_methods, 132248557Sray sizeof(struct i2c_softc), 133248557Sray}; 134248557Sraystatic devclass_t i2c_devclass; 135248557Sray 136248557SrayDRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0); 137248557SrayDRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0); 138248557Sray 139248557Sraystatic phandle_t 140248557Srayi2c_get_node(device_t bus, device_t dev) 141248557Sray{ 142248557Sray /* 143248557Sray * Share controller node with iicbus device 144248557Sray */ 145248557Sray return ofw_bus_get_node(bus); 146248557Sray} 147248557Sray 148248557Sraystatic __inline void 149248557Srayi2c_write_reg(struct i2c_softc *sc, bus_size_t off, uint8_t val) 150248557Sray{ 151248557Sray 152248557Sray bus_space_write_1(sc->bst, sc->bsh, off, val); 153248557Sray} 154248557Sray 155248557Sraystatic __inline uint8_t 156248557Srayi2c_read_reg(struct i2c_softc *sc, bus_size_t off) 157248557Sray{ 158248557Sray 159248557Sray return (bus_space_read_1(sc->bst, sc->bsh, off)); 160248557Sray} 161248557Sray 162248557Sraystatic __inline void 163248557Srayi2c_flag_set(struct i2c_softc *sc, bus_size_t off, uint8_t mask) 164248557Sray{ 165248557Sray uint8_t status; 166248557Sray 167248557Sray status = i2c_read_reg(sc, off); 168248557Sray status |= mask; 169248557Sray i2c_write_reg(sc, off, status); 170248557Sray} 171248557Sray 172248557Sray/* Wait for transfer interrupt flag */ 173248557Sraystatic int 174248557Sraywait_for_iif(struct i2c_softc *sc) 175248557Sray{ 176248557Sray int retry; 177248557Sray 178248557Sray retry = 1000; 179248557Sray while (retry --) { 180248557Sray if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MIF) 181248557Sray return (IIC_NOERR); 182248557Sray DELAY(10); 183248557Sray } 184248557Sray 185248557Sray return (IIC_ETIMEOUT); 186248557Sray} 187248557Sray 188248557Sray/* Wait for free bus */ 189248557Sraystatic int 190248557Sraywait_for_nibb(struct i2c_softc *sc) 191248557Sray{ 192248557Sray int retry; 193248557Sray 194248557Sray retry = 1000; 195248557Sray while (retry --) { 196248557Sray if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0) 197248557Sray return (IIC_NOERR); 198248557Sray DELAY(10); 199248557Sray } 200248557Sray 201248557Sray return (IIC_ETIMEOUT); 202248557Sray} 203248557Sray 204248557Sray/* Wait for transfer complete+interrupt flag */ 205248557Sraystatic int 206248557Sraywait_for_icf(struct i2c_softc *sc) 207248557Sray{ 208248557Sray int retry; 209248557Sray 210248557Sray retry = 1000; 211248557Sray while (retry --) { 212248557Sray 213248557Sray if ((i2c_read_reg(sc, I2C_STATUS_REG) & 214248557Sray (I2CSR_MCF|I2CSR_MIF)) == (I2CSR_MCF|I2CSR_MIF)) 215248557Sray return (IIC_NOERR); 216248557Sray DELAY(10); 217248557Sray } 218248557Sray 219248557Sray return (IIC_ETIMEOUT); 220248557Sray} 221248557Sray 222248557Sraystatic int 223248557Srayi2c_probe(device_t dev) 224248557Sray{ 225248557Sray struct i2c_softc *sc; 226248557Sray 227248557Sray if (!ofw_bus_is_compatible(dev, "fsl,imx-i2c")) 228248557Sray return (ENXIO); 229248557Sray 230248557Sray sc = device_get_softc(dev); 231248557Sray sc->rid = 0; 232248557Sray 233248557Sray sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, 234248557Sray RF_ACTIVE); 235248557Sray if (sc->res == NULL) { 236248557Sray device_printf(dev, "could not allocate resources\n"); 237248557Sray return (ENXIO); 238248557Sray } 239248557Sray 240248557Sray sc->bst = rman_get_bustag(sc->res); 241248557Sray sc->bsh = rman_get_bushandle(sc->res); 242248557Sray 243248557Sray /* Enable I2C */ 244248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN); 245248557Sray bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res); 246248557Sray device_set_desc(dev, "I2C bus controller"); 247248557Sray 248248557Sray return (BUS_PROBE_DEFAULT); 249248557Sray} 250248557Sray 251248557Sraystatic int 252248557Srayi2c_attach(device_t dev) 253248557Sray{ 254248557Sray struct i2c_softc *sc; 255248557Sray 256248557Sray sc = device_get_softc(dev); 257248557Sray sc->dev = dev; 258248557Sray sc->rid = 0; 259248557Sray 260248557Sray mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF); 261248557Sray 262248557Sray sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, 263248557Sray RF_ACTIVE); 264248557Sray if (sc->res == NULL) { 265248557Sray device_printf(dev, "could not allocate resources"); 266248557Sray mtx_destroy(&sc->mutex); 267248557Sray return (ENXIO); 268248557Sray } 269248557Sray 270248557Sray sc->bst = rman_get_bustag(sc->res); 271248557Sray sc->bsh = rman_get_bushandle(sc->res); 272248557Sray 273248557Sray sc->iicbus = device_add_child(dev, "iicbus", -1); 274248557Sray if (sc->iicbus == NULL) { 275248557Sray device_printf(dev, "could not add iicbus child"); 276248557Sray mtx_destroy(&sc->mutex); 277248557Sray return (ENXIO); 278248557Sray } 279248557Sray 280248557Sray bus_generic_attach(dev); 281248557Sray return (IIC_NOERR); 282248557Sray} 283248557Sray 284248557Sraystatic int 285248557Srayi2c_repeated_start(device_t dev, u_char slave, int timeout) 286248557Sray{ 287248557Sray struct i2c_softc *sc; 288248557Sray int error; 289248557Sray 290248557Sray sc = device_get_softc(dev); 291248557Sray 292248557Sray mtx_lock(&sc->mutex); 293248557Sray 294248557Sray i2c_write_reg(sc, I2C_ADDR_REG, slave); 295248557Sray if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0) { 296248557Sray mtx_unlock(&sc->mutex); 297248557Sray return (IIC_EBUSBSY); 298248557Sray } 299248557Sray 300248557Sray /* Set repeated start condition */ 301248557Sray DELAY(10); 302248557Sray i2c_flag_set(sc, I2C_CONTROL_REG, I2CCR_RSTA); 303248557Sray DELAY(10); 304248557Sray /* Clear status */ 305248557Sray i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 306248557Sray /* Write target address - LSB is R/W bit */ 307248557Sray i2c_write_reg(sc, I2C_DATA_REG, slave); 308248557Sray 309248557Sray error = wait_for_iif(sc); 310248557Sray 311248557Sray /* Clear status */ 312248557Sray i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 313248557Sray 314248557Sray mtx_unlock(&sc->mutex); 315248557Sray 316248557Sray if (error) 317248557Sray return (error); 318248557Sray 319248557Sray return (IIC_NOERR); 320248557Sray} 321248557Sray 322248557Sraystatic int 323248557Srayi2c_start(device_t dev, u_char slave, int timeout) 324248557Sray{ 325248557Sray struct i2c_softc *sc; 326248557Sray int error; 327248557Sray 328248557Sray sc = device_get_softc(dev); 329248557Sray 330248557Sray mtx_lock(&sc->mutex); 331248557Sray i2c_write_reg(sc, I2C_ADDR_REG, slave); 332248557Sray if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) { 333248557Sray mtx_unlock(&sc->mutex); 334248557Sray return (IIC_EBUSBSY); 335248557Sray } 336248557Sray 337248557Sray /* Set start condition */ 338248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, 339248557Sray I2CCR_MEN | I2CCR_MSTA | I2CCR_TXAK); 340248557Sray DELAY(100); 341248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, 342248557Sray I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX | I2CCR_TXAK); 343248557Sray /* Clear status */ 344248557Sray i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 345248557Sray /* Write target address - LSB is R/W bit */ 346248557Sray i2c_write_reg(sc, I2C_DATA_REG, slave); 347248557Sray 348248557Sray error = wait_for_iif(sc); 349248557Sray 350248557Sray mtx_unlock(&sc->mutex); 351248557Sray if (error) 352248557Sray return (error); 353248557Sray 354248557Sray return (IIC_NOERR); 355248557Sray} 356248557Sray 357248557Sray 358248557Sraystatic int 359248557Srayi2c_stop(device_t dev) 360248557Sray{ 361248557Sray struct i2c_softc *sc; 362248557Sray 363248557Sray sc = device_get_softc(dev); 364248557Sray mtx_lock(&sc->mutex); 365248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK); 366248557Sray DELAY(100); 367248557Sray /* Reset controller if bus still busy after STOP */ 368248557Sray if (wait_for_nibb(sc) == IIC_ETIMEOUT) { 369248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, 0); 370248557Sray DELAY(1000); 371248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK); 372248557Sray 373248557Sray i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 374248557Sray } 375248557Sray mtx_unlock(&sc->mutex); 376248557Sray 377248557Sray return (IIC_NOERR); 378248557Sray} 379248557Sray 380248557Sraystatic int 381248557Srayi2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) 382248557Sray{ 383248557Sray struct i2c_softc *sc; 384248557Sray uint8_t baud_rate; 385248557Sray 386248557Sray sc = device_get_softc(dev); 387248557Sray 388248557Sray switch (speed) { 389248557Sray case IIC_FAST: 390248557Sray baud_rate = I2C_BAUD_RATE_FAST; 391248557Sray break; 392248557Sray case IIC_SLOW: 393248557Sray case IIC_UNKNOWN: 394248557Sray case IIC_FASTEST: 395248557Sray default: 396248557Sray baud_rate = I2C_BAUD_RATE_DEF; 397248557Sray break; 398248557Sray } 399248557Sray 400248557Sray mtx_lock(&sc->mutex); 401248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, 0x0); 402248557Sray i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 403248557Sray DELAY(1000); 404248557Sray 405248557Sray i2c_write_reg(sc, I2C_FDR_REG, 20); 406248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN); 407248557Sray DELAY(1000); 408248557Sray i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 409248557Sray mtx_unlock(&sc->mutex); 410248557Sray 411248557Sray return (IIC_NOERR); 412248557Sray} 413248557Sray 414248557Sraystatic int 415248557Srayi2c_read(device_t dev, char *buf, int len, int *read, int last, int delay) 416248557Sray{ 417248557Sray struct i2c_softc *sc; 418248557Sray int error, reg; 419248557Sray 420248557Sray sc = device_get_softc(dev); 421248557Sray *read = 0; 422248557Sray 423248557Sray mtx_lock(&sc->mutex); 424248557Sray 425248557Sray if (len) { 426248557Sray if (len == 1) 427248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 428248557Sray I2CCR_MSTA | I2CCR_TXAK); 429248557Sray 430248557Sray else 431248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 432248557Sray I2CCR_MSTA); 433248557Sray 434248557Sray /* dummy read */ 435248557Sray i2c_read_reg(sc, I2C_DATA_REG); 436248557Sray DELAY(1000); 437248557Sray } 438248557Sray 439248557Sray while (*read < len) { 440248557Sray error = wait_for_icf(sc); 441248557Sray if (error) { 442248557Sray mtx_unlock(&sc->mutex); 443248557Sray return (error); 444248557Sray } 445248557Sray i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 446248557Sray if ((*read == len - 2) && last) { 447248557Sray /* NO ACK on last byte */ 448248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 449248557Sray I2CCR_MSTA | I2CCR_TXAK); 450248557Sray } 451248557Sray 452248557Sray if ((*read == len - 1) && last) { 453248557Sray /* Transfer done, remove master bit */ 454248557Sray i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 455248557Sray I2CCR_TXAK); 456248557Sray } 457248557Sray 458248557Sray reg = i2c_read_reg(sc, I2C_DATA_REG); 459248557Sray *buf++ = reg; 460248557Sray (*read)++; 461248557Sray } 462248557Sray mtx_unlock(&sc->mutex); 463248557Sray 464248557Sray return (IIC_NOERR); 465248557Sray} 466248557Sray 467248557Sraystatic int 468248557Srayi2c_write(device_t dev, const char *buf, int len, int *sent, int timeout) 469248557Sray{ 470248557Sray struct i2c_softc *sc; 471248557Sray int error; 472248557Sray 473248557Sray sc = device_get_softc(dev); 474248557Sray *sent = 0; 475248557Sray 476248557Sray mtx_lock(&sc->mutex); 477248557Sray while (*sent < len) { 478248557Sray i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 479248557Sray i2c_write_reg(sc, I2C_DATA_REG, *buf++); 480248557Sray 481248557Sray error = wait_for_iif(sc); 482248557Sray if (error) { 483248557Sray mtx_unlock(&sc->mutex); 484248557Sray return (error); 485248557Sray } 486248557Sray 487248557Sray (*sent)++; 488248557Sray } 489248557Sray mtx_unlock(&sc->mutex); 490248557Sray 491248557Sray return (IIC_NOERR); 492248557Sray} 493