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