1757cb6dbSRafal Jaworowski /*- 2757cb6dbSRafal Jaworowski * Copyright (C) 2008-2009 Semihalf, Michal Hajduk 3757cb6dbSRafal Jaworowski * All rights reserved. 4757cb6dbSRafal Jaworowski * 5757cb6dbSRafal Jaworowski * Redistribution and use in source and binary forms, with or without 6757cb6dbSRafal Jaworowski * modification, are permitted provided that the following conditions 7757cb6dbSRafal Jaworowski * are met: 8757cb6dbSRafal Jaworowski * 1. Redistributions of source code must retain the above copyright 9757cb6dbSRafal Jaworowski * notice, this list of conditions and the following disclaimer. 10757cb6dbSRafal Jaworowski * 2. Redistributions in binary form must reproduce the above copyright 11757cb6dbSRafal Jaworowski * notice, this list of conditions and the following disclaimer in the 12757cb6dbSRafal Jaworowski * documentation and/or other materials provided with the distribution. 13757cb6dbSRafal Jaworowski * 14757cb6dbSRafal Jaworowski * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15757cb6dbSRafal Jaworowski * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16757cb6dbSRafal Jaworowski * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17757cb6dbSRafal Jaworowski * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18757cb6dbSRafal Jaworowski * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19757cb6dbSRafal Jaworowski * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20757cb6dbSRafal Jaworowski * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21757cb6dbSRafal Jaworowski * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22757cb6dbSRafal Jaworowski * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23757cb6dbSRafal Jaworowski * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24757cb6dbSRafal Jaworowski * SUCH DAMAGE. 25757cb6dbSRafal Jaworowski */ 26757cb6dbSRafal Jaworowski 27757cb6dbSRafal Jaworowski #include <sys/cdefs.h> 28757cb6dbSRafal Jaworowski __FBSDID("$FreeBSD$"); 29757cb6dbSRafal Jaworowski 30757cb6dbSRafal Jaworowski #include <sys/param.h> 31757cb6dbSRafal Jaworowski #include <sys/systm.h> 32757cb6dbSRafal Jaworowski #include <sys/bus.h> 33757cb6dbSRafal Jaworowski #include <sys/kernel.h> 34757cb6dbSRafal Jaworowski #include <sys/module.h> 35757cb6dbSRafal Jaworowski #include <sys/resource.h> 36757cb6dbSRafal Jaworowski 37757cb6dbSRafal Jaworowski #include <machine/bus.h> 38757cb6dbSRafal Jaworowski #include <machine/resource.h> 39757cb6dbSRafal Jaworowski #include <sys/rman.h> 40757cb6dbSRafal Jaworowski 41757cb6dbSRafal Jaworowski #include <sys/lock.h> 42757cb6dbSRafal Jaworowski #include <sys/mutex.h> 43757cb6dbSRafal Jaworowski 44757cb6dbSRafal Jaworowski #include <dev/iicbus/iiconf.h> 45757cb6dbSRafal Jaworowski #include <dev/iicbus/iicbus.h> 46757cb6dbSRafal Jaworowski #include "iicbus_if.h" 47757cb6dbSRafal Jaworowski 48d1d3233eSRafal Jaworowski #include <dev/ofw/ofw_bus.h> 49d1d3233eSRafal Jaworowski #include <dev/ofw/ofw_bus_subr.h> 50757cb6dbSRafal Jaworowski 51757cb6dbSRafal Jaworowski #define I2C_ADDR_REG 0x00 /* I2C slave address register */ 52757cb6dbSRafal Jaworowski #define I2C_FDR_REG 0x04 /* I2C frequency divider register */ 53757cb6dbSRafal Jaworowski #define I2C_CONTROL_REG 0x08 /* I2C control register */ 54757cb6dbSRafal Jaworowski #define I2C_STATUS_REG 0x0C /* I2C status register */ 55757cb6dbSRafal Jaworowski #define I2C_DATA_REG 0x10 /* I2C data register */ 56757cb6dbSRafal Jaworowski #define I2C_DFSRR_REG 0x14 /* I2C Digital Filter Sampling rate */ 57757cb6dbSRafal Jaworowski #define I2C_ENABLE 0x80 /* Module enable - interrupt disable */ 58757cb6dbSRafal Jaworowski #define I2CSR_RXAK 0x01 /* Received acknowledge */ 59757cb6dbSRafal Jaworowski #define I2CSR_MCF (1<<7) /* Data transfer */ 60757cb6dbSRafal Jaworowski #define I2CSR_MASS (1<<6) /* Addressed as a slave */ 61757cb6dbSRafal Jaworowski #define I2CSR_MBB (1<<5) /* Bus busy */ 62757cb6dbSRafal Jaworowski #define I2CSR_MAL (1<<4) /* Arbitration lost */ 63757cb6dbSRafal Jaworowski #define I2CSR_SRW (1<<2) /* Slave read/write */ 64757cb6dbSRafal Jaworowski #define I2CSR_MIF (1<<1) /* Module interrupt */ 65757cb6dbSRafal Jaworowski #define I2CCR_MEN (1<<7) /* Module enable */ 66757cb6dbSRafal Jaworowski #define I2CCR_MSTA (1<<5) /* Master/slave mode */ 67757cb6dbSRafal Jaworowski #define I2CCR_MTX (1<<4) /* Transmit/receive mode */ 68757cb6dbSRafal Jaworowski #define I2CCR_TXAK (1<<3) /* Transfer acknowledge */ 69757cb6dbSRafal Jaworowski #define I2CCR_RSTA (1<<2) /* Repeated START */ 70757cb6dbSRafal Jaworowski 71757cb6dbSRafal Jaworowski #define I2C_BAUD_RATE_FAST 0x31 72757cb6dbSRafal Jaworowski #define I2C_BAUD_RATE_DEF 0x3F 73757cb6dbSRafal Jaworowski #define I2C_DFSSR_DIV 0x10 74757cb6dbSRafal Jaworowski 75757cb6dbSRafal Jaworowski #ifdef DEBUG 76757cb6dbSRafal Jaworowski #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0) 77757cb6dbSRafal Jaworowski #else 78757cb6dbSRafal Jaworowski #define debugf(fmt, args...) 79757cb6dbSRafal Jaworowski #endif 80757cb6dbSRafal Jaworowski 81757cb6dbSRafal Jaworowski struct i2c_softc { 82757cb6dbSRafal Jaworowski device_t dev; 83757cb6dbSRafal Jaworowski device_t iicbus; 84757cb6dbSRafal Jaworowski struct resource *res; 85757cb6dbSRafal Jaworowski struct mtx mutex; 86757cb6dbSRafal Jaworowski int rid; 87757cb6dbSRafal Jaworowski bus_space_handle_t bsh; 88757cb6dbSRafal Jaworowski bus_space_tag_t bst; 89757cb6dbSRafal Jaworowski }; 90757cb6dbSRafal Jaworowski 91757cb6dbSRafal Jaworowski static int i2c_probe(device_t); 92757cb6dbSRafal Jaworowski static int i2c_attach(device_t); 93757cb6dbSRafal Jaworowski 94757cb6dbSRafal Jaworowski static int i2c_repeated_start(device_t dev, u_char slave, int timeout); 95757cb6dbSRafal Jaworowski static int i2c_start(device_t dev, u_char slave, int timeout); 96757cb6dbSRafal Jaworowski static int i2c_stop(device_t dev); 97757cb6dbSRafal Jaworowski static int i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr); 98757cb6dbSRafal Jaworowski static int i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay); 99757cb6dbSRafal Jaworowski static int i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout); 100*2db664d7SJustin Hibbits static phandle_t i2c_get_node(device_t bus, device_t dev); 101757cb6dbSRafal Jaworowski 102757cb6dbSRafal Jaworowski static device_method_t i2c_methods[] = { 103757cb6dbSRafal Jaworowski DEVMETHOD(device_probe, i2c_probe), 104757cb6dbSRafal Jaworowski DEVMETHOD(device_attach, i2c_attach), 105757cb6dbSRafal Jaworowski 106757cb6dbSRafal Jaworowski DEVMETHOD(iicbus_callback, iicbus_null_callback), 107757cb6dbSRafal Jaworowski DEVMETHOD(iicbus_repeated_start, i2c_repeated_start), 108757cb6dbSRafal Jaworowski DEVMETHOD(iicbus_start, i2c_start), 109757cb6dbSRafal Jaworowski DEVMETHOD(iicbus_stop, i2c_stop), 110757cb6dbSRafal Jaworowski DEVMETHOD(iicbus_reset, i2c_reset), 111757cb6dbSRafal Jaworowski DEVMETHOD(iicbus_read, i2c_read), 112757cb6dbSRafal Jaworowski DEVMETHOD(iicbus_write, i2c_write), 113757cb6dbSRafal Jaworowski DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), 114*2db664d7SJustin Hibbits DEVMETHOD(ofw_bus_get_node, i2c_get_node), 115757cb6dbSRafal Jaworowski 116757cb6dbSRafal Jaworowski { 0, 0 } 117757cb6dbSRafal Jaworowski }; 118757cb6dbSRafal Jaworowski 119757cb6dbSRafal Jaworowski static driver_t i2c_driver = { 120*2db664d7SJustin Hibbits "iichb", 121757cb6dbSRafal Jaworowski i2c_methods, 122757cb6dbSRafal Jaworowski sizeof(struct i2c_softc), 123757cb6dbSRafal Jaworowski }; 124757cb6dbSRafal Jaworowski static devclass_t i2c_devclass; 125757cb6dbSRafal Jaworowski 126d1d3233eSRafal Jaworowski DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0); 127757cb6dbSRafal Jaworowski DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0); 128757cb6dbSRafal Jaworowski 129757cb6dbSRafal Jaworowski static __inline void 130757cb6dbSRafal Jaworowski i2c_write_reg(struct i2c_softc *sc, bus_size_t off, uint8_t val) 131757cb6dbSRafal Jaworowski { 132757cb6dbSRafal Jaworowski 133757cb6dbSRafal Jaworowski bus_space_write_1(sc->bst, sc->bsh, off, val); 134757cb6dbSRafal Jaworowski } 135757cb6dbSRafal Jaworowski 136757cb6dbSRafal Jaworowski static __inline uint8_t 137757cb6dbSRafal Jaworowski i2c_read_reg(struct i2c_softc *sc, bus_size_t off) 138757cb6dbSRafal Jaworowski { 139757cb6dbSRafal Jaworowski 140757cb6dbSRafal Jaworowski return (bus_space_read_1(sc->bst, sc->bsh, off)); 141757cb6dbSRafal Jaworowski } 142757cb6dbSRafal Jaworowski 143757cb6dbSRafal Jaworowski static __inline void 144757cb6dbSRafal Jaworowski i2c_flag_set(struct i2c_softc *sc, bus_size_t off, uint8_t mask) 145757cb6dbSRafal Jaworowski { 146757cb6dbSRafal Jaworowski uint8_t status; 147757cb6dbSRafal Jaworowski 148757cb6dbSRafal Jaworowski status = i2c_read_reg(sc, off); 149757cb6dbSRafal Jaworowski status |= mask; 150757cb6dbSRafal Jaworowski i2c_write_reg(sc, off, status); 151757cb6dbSRafal Jaworowski } 152757cb6dbSRafal Jaworowski 153757cb6dbSRafal Jaworowski static int 154757cb6dbSRafal Jaworowski i2c_do_wait(device_t dev, struct i2c_softc *sc, int write, int start) 155757cb6dbSRafal Jaworowski { 156757cb6dbSRafal Jaworowski int err; 157757cb6dbSRafal Jaworowski uint8_t status; 158757cb6dbSRafal Jaworowski 159757cb6dbSRafal Jaworowski status = i2c_read_reg(sc, I2C_STATUS_REG); 160757cb6dbSRafal Jaworowski if (status & I2CSR_MIF) { 161757cb6dbSRafal Jaworowski if (write && start && (status & I2CSR_RXAK)) { 162757cb6dbSRafal Jaworowski debugf("no ack %s", start ? 163757cb6dbSRafal Jaworowski "after sending slave address" : ""); 164757cb6dbSRafal Jaworowski err = IIC_ENOACK; 165757cb6dbSRafal Jaworowski goto error; 166757cb6dbSRafal Jaworowski } 167757cb6dbSRafal Jaworowski if (status & I2CSR_MAL) { 168757cb6dbSRafal Jaworowski debugf("arbitration lost"); 169757cb6dbSRafal Jaworowski err = IIC_EBUSERR; 170757cb6dbSRafal Jaworowski goto error; 171757cb6dbSRafal Jaworowski } 172757cb6dbSRafal Jaworowski if (!write && !(status & I2CSR_MCF)) { 173757cb6dbSRafal Jaworowski debugf("transfer unfinished"); 174757cb6dbSRafal Jaworowski err = IIC_EBUSERR; 175757cb6dbSRafal Jaworowski goto error; 176757cb6dbSRafal Jaworowski } 177757cb6dbSRafal Jaworowski } 178757cb6dbSRafal Jaworowski 179757cb6dbSRafal Jaworowski return (IIC_NOERR); 180757cb6dbSRafal Jaworowski 181757cb6dbSRafal Jaworowski error: 182757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 183757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK); 184757cb6dbSRafal Jaworowski return (err); 185757cb6dbSRafal Jaworowski } 186757cb6dbSRafal Jaworowski 187757cb6dbSRafal Jaworowski static int 188757cb6dbSRafal Jaworowski i2c_probe(device_t dev) 189757cb6dbSRafal Jaworowski { 190757cb6dbSRafal Jaworowski struct i2c_softc *sc; 191757cb6dbSRafal Jaworowski 192d1d3233eSRafal Jaworowski if (!ofw_bus_is_compatible(dev, "fsl-i2c")) 193757cb6dbSRafal Jaworowski return (ENXIO); 194757cb6dbSRafal Jaworowski 195757cb6dbSRafal Jaworowski sc = device_get_softc(dev); 196757cb6dbSRafal Jaworowski sc->rid = 0; 197757cb6dbSRafal Jaworowski 198757cb6dbSRafal Jaworowski sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, 199757cb6dbSRafal Jaworowski RF_ACTIVE); 200757cb6dbSRafal Jaworowski if (sc->res == NULL) { 201d1d3233eSRafal Jaworowski device_printf(dev, "could not allocate resources\n"); 202757cb6dbSRafal Jaworowski return (ENXIO); 203757cb6dbSRafal Jaworowski } 204757cb6dbSRafal Jaworowski 205757cb6dbSRafal Jaworowski sc->bst = rman_get_bustag(sc->res); 206757cb6dbSRafal Jaworowski sc->bsh = rman_get_bushandle(sc->res); 207757cb6dbSRafal Jaworowski 208757cb6dbSRafal Jaworowski /* Enable I2C */ 209757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_CONTROL_REG, I2C_ENABLE); 210757cb6dbSRafal Jaworowski bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res); 211757cb6dbSRafal Jaworowski device_set_desc(dev, "I2C bus controller"); 212757cb6dbSRafal Jaworowski 213757cb6dbSRafal Jaworowski return (BUS_PROBE_DEFAULT); 214757cb6dbSRafal Jaworowski } 215757cb6dbSRafal Jaworowski 216757cb6dbSRafal Jaworowski static int 217757cb6dbSRafal Jaworowski i2c_attach(device_t dev) 218757cb6dbSRafal Jaworowski { 219757cb6dbSRafal Jaworowski struct i2c_softc *sc; 220757cb6dbSRafal Jaworowski sc = device_get_softc(dev); 221757cb6dbSRafal Jaworowski 222757cb6dbSRafal Jaworowski sc->dev = dev; 223757cb6dbSRafal Jaworowski sc->rid = 0; 224757cb6dbSRafal Jaworowski 225757cb6dbSRafal Jaworowski mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF); 226757cb6dbSRafal Jaworowski 227757cb6dbSRafal Jaworowski sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, 228757cb6dbSRafal Jaworowski RF_ACTIVE); 229757cb6dbSRafal Jaworowski if (sc->res == NULL) { 230757cb6dbSRafal Jaworowski device_printf(dev, "could not allocate resources"); 231757cb6dbSRafal Jaworowski mtx_destroy(&sc->mutex); 232757cb6dbSRafal Jaworowski return (ENXIO); 233757cb6dbSRafal Jaworowski } 234757cb6dbSRafal Jaworowski 235757cb6dbSRafal Jaworowski sc->bst = rman_get_bustag(sc->res); 236757cb6dbSRafal Jaworowski sc->bsh = rman_get_bushandle(sc->res); 237757cb6dbSRafal Jaworowski 238757cb6dbSRafal Jaworowski sc->iicbus = device_add_child(dev, "iicbus", -1); 239757cb6dbSRafal Jaworowski if (sc->iicbus == NULL) { 240757cb6dbSRafal Jaworowski device_printf(dev, "could not add iicbus child"); 241757cb6dbSRafal Jaworowski mtx_destroy(&sc->mutex); 242757cb6dbSRafal Jaworowski return (ENXIO); 243757cb6dbSRafal Jaworowski } 244757cb6dbSRafal Jaworowski 245757cb6dbSRafal Jaworowski bus_generic_attach(dev); 246757cb6dbSRafal Jaworowski return (IIC_NOERR); 247757cb6dbSRafal Jaworowski } 248757cb6dbSRafal Jaworowski static int 249757cb6dbSRafal Jaworowski i2c_repeated_start(device_t dev, u_char slave, int timeout) 250757cb6dbSRafal Jaworowski { 251757cb6dbSRafal Jaworowski struct i2c_softc *sc; 252757cb6dbSRafal Jaworowski int error; 253757cb6dbSRafal Jaworowski 254757cb6dbSRafal Jaworowski sc = device_get_softc(dev); 255757cb6dbSRafal Jaworowski 256757cb6dbSRafal Jaworowski mtx_lock(&sc->mutex); 257757cb6dbSRafal Jaworowski /* Set repeated start condition */ 258757cb6dbSRafal Jaworowski i2c_flag_set(sc, I2C_CONTROL_REG ,I2CCR_RSTA); 259757cb6dbSRafal Jaworowski /* Write target address - LSB is R/W bit */ 260757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_DATA_REG, slave); 261757cb6dbSRafal Jaworowski DELAY(1250); 262757cb6dbSRafal Jaworowski 263757cb6dbSRafal Jaworowski error = i2c_do_wait(dev, sc, 1, 1); 264757cb6dbSRafal Jaworowski mtx_unlock(&sc->mutex); 265757cb6dbSRafal Jaworowski 266757cb6dbSRafal Jaworowski if (error) 267757cb6dbSRafal Jaworowski return (error); 268757cb6dbSRafal Jaworowski 269757cb6dbSRafal Jaworowski return (IIC_NOERR); 270757cb6dbSRafal Jaworowski } 271757cb6dbSRafal Jaworowski 272757cb6dbSRafal Jaworowski static int 273757cb6dbSRafal Jaworowski i2c_start(device_t dev, u_char slave, int timeout) 274757cb6dbSRafal Jaworowski { 275757cb6dbSRafal Jaworowski struct i2c_softc *sc; 276757cb6dbSRafal Jaworowski uint8_t status; 277757cb6dbSRafal Jaworowski int error; 278757cb6dbSRafal Jaworowski 279757cb6dbSRafal Jaworowski sc = device_get_softc(dev); 280757cb6dbSRafal Jaworowski DELAY(1000); 281757cb6dbSRafal Jaworowski 282757cb6dbSRafal Jaworowski mtx_lock(&sc->mutex); 283757cb6dbSRafal Jaworowski status = i2c_read_reg(sc, I2C_STATUS_REG); 284757cb6dbSRafal Jaworowski /* Check if bus is idle or busy */ 285757cb6dbSRafal Jaworowski if (status & I2CSR_MBB) { 286757cb6dbSRafal Jaworowski debugf("bus busy"); 287757cb6dbSRafal Jaworowski mtx_unlock(&sc->mutex); 288757cb6dbSRafal Jaworowski i2c_stop(dev); 289d1e99670SIan Lepore return (IIC_EBUSERR); 290757cb6dbSRafal Jaworowski } 291757cb6dbSRafal Jaworowski 292757cb6dbSRafal Jaworowski /* Set start condition */ 293757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX); 294757cb6dbSRafal Jaworowski /* Write target address - LSB is R/W bit */ 295757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_DATA_REG, slave); 296757cb6dbSRafal Jaworowski DELAY(1250); 297757cb6dbSRafal Jaworowski 298757cb6dbSRafal Jaworowski error = i2c_do_wait(dev, sc, 1, 1); 299757cb6dbSRafal Jaworowski 300757cb6dbSRafal Jaworowski mtx_unlock(&sc->mutex); 301757cb6dbSRafal Jaworowski if (error) 302757cb6dbSRafal Jaworowski return (error); 303757cb6dbSRafal Jaworowski 304757cb6dbSRafal Jaworowski return (IIC_NOERR); 305757cb6dbSRafal Jaworowski } 306757cb6dbSRafal Jaworowski 307757cb6dbSRafal Jaworowski static int 308757cb6dbSRafal Jaworowski i2c_stop(device_t dev) 309757cb6dbSRafal Jaworowski { 310757cb6dbSRafal Jaworowski struct i2c_softc *sc; 311757cb6dbSRafal Jaworowski 312757cb6dbSRafal Jaworowski sc = device_get_softc(dev); 313757cb6dbSRafal Jaworowski mtx_lock(&sc->mutex); 314757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK); 315757cb6dbSRafal Jaworowski DELAY(1000); 316757cb6dbSRafal Jaworowski mtx_unlock(&sc->mutex); 317757cb6dbSRafal Jaworowski 318757cb6dbSRafal Jaworowski return (IIC_NOERR); 319757cb6dbSRafal Jaworowski } 320757cb6dbSRafal Jaworowski 321757cb6dbSRafal Jaworowski static int 322757cb6dbSRafal Jaworowski i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) 323757cb6dbSRafal Jaworowski { 324757cb6dbSRafal Jaworowski struct i2c_softc *sc; 325757cb6dbSRafal Jaworowski uint8_t baud_rate; 326757cb6dbSRafal Jaworowski 327757cb6dbSRafal Jaworowski sc = device_get_softc(dev); 328757cb6dbSRafal Jaworowski 329757cb6dbSRafal Jaworowski switch (speed) { 330757cb6dbSRafal Jaworowski case IIC_FAST: 331757cb6dbSRafal Jaworowski baud_rate = I2C_BAUD_RATE_FAST; 332757cb6dbSRafal Jaworowski break; 333757cb6dbSRafal Jaworowski case IIC_SLOW: 334757cb6dbSRafal Jaworowski case IIC_UNKNOWN: 335757cb6dbSRafal Jaworowski case IIC_FASTEST: 336757cb6dbSRafal Jaworowski default: 337757cb6dbSRafal Jaworowski baud_rate = I2C_BAUD_RATE_DEF; 338757cb6dbSRafal Jaworowski break; 339757cb6dbSRafal Jaworowski } 340757cb6dbSRafal Jaworowski 341757cb6dbSRafal Jaworowski mtx_lock(&sc->mutex); 342757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_CONTROL_REG, 0x0); 343757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 344757cb6dbSRafal Jaworowski DELAY(1000); 345757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_FDR_REG, baud_rate); 346757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_DFSRR_REG, I2C_DFSSR_DIV); 347757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_CONTROL_REG, I2C_ENABLE); 348757cb6dbSRafal Jaworowski DELAY(1000); 349757cb6dbSRafal Jaworowski mtx_unlock(&sc->mutex); 350757cb6dbSRafal Jaworowski 351757cb6dbSRafal Jaworowski return (IIC_NOERR); 352757cb6dbSRafal Jaworowski } 353757cb6dbSRafal Jaworowski 354757cb6dbSRafal Jaworowski static int 355757cb6dbSRafal Jaworowski i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay) 356757cb6dbSRafal Jaworowski { 357757cb6dbSRafal Jaworowski struct i2c_softc *sc; 358757cb6dbSRafal Jaworowski int error; 359757cb6dbSRafal Jaworowski 360757cb6dbSRafal Jaworowski sc = device_get_softc(dev); 361757cb6dbSRafal Jaworowski *read = 0; 362757cb6dbSRafal Jaworowski 363757cb6dbSRafal Jaworowski mtx_lock(&sc->mutex); 364757cb6dbSRafal Jaworowski if (len) { 365757cb6dbSRafal Jaworowski if (len == 1) 366757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 367757cb6dbSRafal Jaworowski I2CCR_MSTA | I2CCR_TXAK); 368757cb6dbSRafal Jaworowski 369757cb6dbSRafal Jaworowski else 370757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 371757cb6dbSRafal Jaworowski I2CCR_MSTA); 372757cb6dbSRafal Jaworowski 373757cb6dbSRafal Jaworowski /* dummy read */ 374757cb6dbSRafal Jaworowski i2c_read_reg(sc, I2C_DATA_REG); 375757cb6dbSRafal Jaworowski DELAY(1000); 376757cb6dbSRafal Jaworowski } 377757cb6dbSRafal Jaworowski 378757cb6dbSRafal Jaworowski while (*read < len) { 379757cb6dbSRafal Jaworowski DELAY(1000); 380757cb6dbSRafal Jaworowski error = i2c_do_wait(dev, sc, 0, 0); 381757cb6dbSRafal Jaworowski if (error) { 382757cb6dbSRafal Jaworowski mtx_unlock(&sc->mutex); 383757cb6dbSRafal Jaworowski return (error); 384757cb6dbSRafal Jaworowski } 385757cb6dbSRafal Jaworowski if ((*read == len - 2) && last) { 386757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 387757cb6dbSRafal Jaworowski I2CCR_MSTA | I2CCR_TXAK); 388757cb6dbSRafal Jaworowski } 389757cb6dbSRafal Jaworowski 390757cb6dbSRafal Jaworowski if ((*read == len - 1) && last) { 391757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 392757cb6dbSRafal Jaworowski I2CCR_TXAK); 393757cb6dbSRafal Jaworowski } 394757cb6dbSRafal Jaworowski 395757cb6dbSRafal Jaworowski *buf++ = i2c_read_reg(sc, I2C_DATA_REG); 396757cb6dbSRafal Jaworowski (*read)++; 397757cb6dbSRafal Jaworowski DELAY(1250); 398757cb6dbSRafal Jaworowski } 399757cb6dbSRafal Jaworowski mtx_unlock(&sc->mutex); 400757cb6dbSRafal Jaworowski 401757cb6dbSRafal Jaworowski return (IIC_NOERR); 402757cb6dbSRafal Jaworowski } 403757cb6dbSRafal Jaworowski 404757cb6dbSRafal Jaworowski static int 405757cb6dbSRafal Jaworowski i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout) 406757cb6dbSRafal Jaworowski { 407757cb6dbSRafal Jaworowski struct i2c_softc *sc; 408757cb6dbSRafal Jaworowski int error; 409757cb6dbSRafal Jaworowski 410757cb6dbSRafal Jaworowski sc = device_get_softc(dev); 411757cb6dbSRafal Jaworowski *sent = 0; 412757cb6dbSRafal Jaworowski 413757cb6dbSRafal Jaworowski mtx_lock(&sc->mutex); 414757cb6dbSRafal Jaworowski while (*sent < len) { 415757cb6dbSRafal Jaworowski i2c_write_reg(sc, I2C_DATA_REG, *buf++); 416757cb6dbSRafal Jaworowski DELAY(1250); 417757cb6dbSRafal Jaworowski 418757cb6dbSRafal Jaworowski error = i2c_do_wait(dev, sc, 1, 0); 419757cb6dbSRafal Jaworowski if (error) { 420757cb6dbSRafal Jaworowski mtx_unlock(&sc->mutex); 421757cb6dbSRafal Jaworowski return (error); 422757cb6dbSRafal Jaworowski } 423757cb6dbSRafal Jaworowski 424757cb6dbSRafal Jaworowski (*sent)++; 425757cb6dbSRafal Jaworowski } 426757cb6dbSRafal Jaworowski mtx_unlock(&sc->mutex); 427757cb6dbSRafal Jaworowski 428757cb6dbSRafal Jaworowski return (IIC_NOERR); 429757cb6dbSRafal Jaworowski } 430*2db664d7SJustin Hibbits 431*2db664d7SJustin Hibbits static phandle_t 432*2db664d7SJustin Hibbits i2c_get_node(device_t bus, device_t dev) 433*2db664d7SJustin Hibbits { 434*2db664d7SJustin Hibbits 435*2db664d7SJustin Hibbits /* Share controller node with iibus device. */ 436*2db664d7SJustin Hibbits return (ofw_bus_get_node(bus)); 437*2db664d7SJustin Hibbits } 438