1*484b4fd4SRuslan Bukin /*- 2*484b4fd4SRuslan Bukin * Copyright (C) 2008-2009 Semihalf, Michal Hajduk 3*484b4fd4SRuslan Bukin * Copyright (c) 2012, 2013 The FreeBSD Foundation 4*484b4fd4SRuslan Bukin * All rights reserved. 5*484b4fd4SRuslan Bukin * 6*484b4fd4SRuslan Bukin * Portions of this software were developed by Oleksandr Rybalko 7*484b4fd4SRuslan Bukin * under sponsorship from the FreeBSD Foundation. 8*484b4fd4SRuslan Bukin * 9*484b4fd4SRuslan Bukin * Redistribution and use in source and binary forms, with or without 10*484b4fd4SRuslan Bukin * modification, are permitted provided that the following conditions 11*484b4fd4SRuslan Bukin * are met: 12*484b4fd4SRuslan Bukin * 1. Redistributions of source code must retain the above copyright 13*484b4fd4SRuslan Bukin * notice, this list of conditions and the following disclaimer. 14*484b4fd4SRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright 15*484b4fd4SRuslan Bukin * notice, this list of conditions and the following disclaimer in the 16*484b4fd4SRuslan Bukin * documentation and/or other materials provided with the distribution. 17*484b4fd4SRuslan Bukin * 18*484b4fd4SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19*484b4fd4SRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*484b4fd4SRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*484b4fd4SRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 22*484b4fd4SRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23*484b4fd4SRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24*484b4fd4SRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25*484b4fd4SRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26*484b4fd4SRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27*484b4fd4SRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28*484b4fd4SRuslan Bukin * SUCH DAMAGE. 29*484b4fd4SRuslan Bukin */ 30*484b4fd4SRuslan Bukin 31*484b4fd4SRuslan Bukin #include <sys/cdefs.h> 32*484b4fd4SRuslan Bukin __FBSDID("$FreeBSD$"); 33*484b4fd4SRuslan Bukin 34*484b4fd4SRuslan Bukin #include <sys/param.h> 35*484b4fd4SRuslan Bukin #include <sys/systm.h> 36*484b4fd4SRuslan Bukin #include <sys/bus.h> 37*484b4fd4SRuslan Bukin #include <sys/kernel.h> 38*484b4fd4SRuslan Bukin #include <sys/module.h> 39*484b4fd4SRuslan Bukin #include <sys/resource.h> 40*484b4fd4SRuslan Bukin 41*484b4fd4SRuslan Bukin #include <machine/bus.h> 42*484b4fd4SRuslan Bukin #include <machine/resource.h> 43*484b4fd4SRuslan Bukin #include <sys/rman.h> 44*484b4fd4SRuslan Bukin 45*484b4fd4SRuslan Bukin #include <sys/lock.h> 46*484b4fd4SRuslan Bukin #include <sys/mutex.h> 47*484b4fd4SRuslan Bukin 48*484b4fd4SRuslan Bukin #include <dev/iicbus/iiconf.h> 49*484b4fd4SRuslan Bukin #include <dev/iicbus/iicbus.h> 50*484b4fd4SRuslan Bukin #include "iicbus_if.h" 51*484b4fd4SRuslan Bukin 52*484b4fd4SRuslan Bukin #include <dev/fdt/fdt_common.h> 53*484b4fd4SRuslan Bukin #include <dev/ofw/openfirm.h> 54*484b4fd4SRuslan Bukin #include <dev/ofw/ofw_bus.h> 55*484b4fd4SRuslan Bukin #include <dev/ofw/ofw_bus_subr.h> 56*484b4fd4SRuslan Bukin 57*484b4fd4SRuslan Bukin #define I2C_ADDR_REG 0x00 /* I2C slave address register */ 58*484b4fd4SRuslan Bukin #define I2C_FDR_REG 0x04 /* I2C frequency divider register */ 59*484b4fd4SRuslan Bukin #define I2C_CONTROL_REG 0x08 /* I2C control register */ 60*484b4fd4SRuslan Bukin #define I2C_STATUS_REG 0x0C /* I2C status register */ 61*484b4fd4SRuslan Bukin #define I2C_DATA_REG 0x10 /* I2C data register */ 62*484b4fd4SRuslan Bukin #define I2C_DFSRR_REG 0x14 /* I2C Digital Filter Sampling rate */ 63*484b4fd4SRuslan Bukin 64*484b4fd4SRuslan Bukin #define I2CCR_MEN (1 << 7) /* Module enable */ 65*484b4fd4SRuslan Bukin #define I2CCR_MSTA (1 << 5) /* Master/slave mode */ 66*484b4fd4SRuslan Bukin #define I2CCR_MTX (1 << 4) /* Transmit/receive mode */ 67*484b4fd4SRuslan Bukin #define I2CCR_TXAK (1 << 3) /* Transfer acknowledge */ 68*484b4fd4SRuslan Bukin #define I2CCR_RSTA (1 << 2) /* Repeated START */ 69*484b4fd4SRuslan Bukin 70*484b4fd4SRuslan Bukin #define I2CSR_MCF (1 << 7) /* Data transfer */ 71*484b4fd4SRuslan Bukin #define I2CSR_MASS (1 << 6) /* Addressed as a slave */ 72*484b4fd4SRuslan Bukin #define I2CSR_MBB (1 << 5) /* Bus busy */ 73*484b4fd4SRuslan Bukin #define I2CSR_MAL (1 << 4) /* Arbitration lost */ 74*484b4fd4SRuslan Bukin #define I2CSR_SRW (1 << 2) /* Slave read/write */ 75*484b4fd4SRuslan Bukin #define I2CSR_MIF (1 << 1) /* Module interrupt */ 76*484b4fd4SRuslan Bukin #define I2CSR_RXAK (1 << 0) /* Received acknowledge */ 77*484b4fd4SRuslan Bukin 78*484b4fd4SRuslan Bukin #define I2C_BAUD_RATE_FAST 0x31 79*484b4fd4SRuslan Bukin #define I2C_BAUD_RATE_DEF 0x3F 80*484b4fd4SRuslan Bukin #define I2C_DFSSR_DIV 0x10 81*484b4fd4SRuslan Bukin 82*484b4fd4SRuslan Bukin #ifdef DEBUG 83*484b4fd4SRuslan Bukin #define debugf(fmt, args...) do { printf("%s(): ", __func__); \ 84*484b4fd4SRuslan Bukin printf(fmt,##args); } while (0) 85*484b4fd4SRuslan Bukin #else 86*484b4fd4SRuslan Bukin #define debugf(fmt, args...) 87*484b4fd4SRuslan Bukin #endif 88*484b4fd4SRuslan Bukin 89*484b4fd4SRuslan Bukin struct i2c_softc { 90*484b4fd4SRuslan Bukin device_t dev; 91*484b4fd4SRuslan Bukin device_t iicbus; 92*484b4fd4SRuslan Bukin struct resource *res; 93*484b4fd4SRuslan Bukin struct mtx mutex; 94*484b4fd4SRuslan Bukin int rid; 95*484b4fd4SRuslan Bukin bus_space_handle_t bsh; 96*484b4fd4SRuslan Bukin bus_space_tag_t bst; 97*484b4fd4SRuslan Bukin }; 98*484b4fd4SRuslan Bukin 99*484b4fd4SRuslan Bukin static phandle_t i2c_get_node(device_t, device_t); 100*484b4fd4SRuslan Bukin static int i2c_probe(device_t); 101*484b4fd4SRuslan Bukin static int i2c_attach(device_t); 102*484b4fd4SRuslan Bukin 103*484b4fd4SRuslan Bukin static int i2c_repeated_start(device_t, u_char, int); 104*484b4fd4SRuslan Bukin static int i2c_start(device_t, u_char, int); 105*484b4fd4SRuslan Bukin static int i2c_stop(device_t); 106*484b4fd4SRuslan Bukin static int i2c_reset(device_t, u_char, u_char, u_char *); 107*484b4fd4SRuslan Bukin static int i2c_read(device_t, char *, int, int *, int, int); 108*484b4fd4SRuslan Bukin static int i2c_write(device_t, const char *, int, int *, int); 109*484b4fd4SRuslan Bukin 110*484b4fd4SRuslan Bukin static device_method_t i2c_methods[] = { 111*484b4fd4SRuslan Bukin DEVMETHOD(device_probe, i2c_probe), 112*484b4fd4SRuslan Bukin DEVMETHOD(device_attach, i2c_attach), 113*484b4fd4SRuslan Bukin 114*484b4fd4SRuslan Bukin /* OFW methods */ 115*484b4fd4SRuslan Bukin DEVMETHOD(ofw_bus_get_node, i2c_get_node), 116*484b4fd4SRuslan Bukin 117*484b4fd4SRuslan Bukin DEVMETHOD(iicbus_callback, iicbus_null_callback), 118*484b4fd4SRuslan Bukin DEVMETHOD(iicbus_repeated_start, i2c_repeated_start), 119*484b4fd4SRuslan Bukin DEVMETHOD(iicbus_start, i2c_start), 120*484b4fd4SRuslan Bukin DEVMETHOD(iicbus_stop, i2c_stop), 121*484b4fd4SRuslan Bukin DEVMETHOD(iicbus_reset, i2c_reset), 122*484b4fd4SRuslan Bukin DEVMETHOD(iicbus_read, i2c_read), 123*484b4fd4SRuslan Bukin DEVMETHOD(iicbus_write, i2c_write), 124*484b4fd4SRuslan Bukin DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), 125*484b4fd4SRuslan Bukin 126*484b4fd4SRuslan Bukin { 0, 0 } 127*484b4fd4SRuslan Bukin }; 128*484b4fd4SRuslan Bukin 129*484b4fd4SRuslan Bukin static driver_t i2c_driver = { 130*484b4fd4SRuslan Bukin "iichb", 131*484b4fd4SRuslan Bukin i2c_methods, 132*484b4fd4SRuslan Bukin sizeof(struct i2c_softc), 133*484b4fd4SRuslan Bukin }; 134*484b4fd4SRuslan Bukin static devclass_t i2c_devclass; 135*484b4fd4SRuslan Bukin 136*484b4fd4SRuslan Bukin DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0); 137*484b4fd4SRuslan Bukin DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0); 138*484b4fd4SRuslan Bukin 139*484b4fd4SRuslan Bukin static phandle_t 140*484b4fd4SRuslan Bukin i2c_get_node(device_t bus, device_t dev) 141*484b4fd4SRuslan Bukin { 142*484b4fd4SRuslan Bukin /* 143*484b4fd4SRuslan Bukin * Share controller node with iicbus device 144*484b4fd4SRuslan Bukin */ 145*484b4fd4SRuslan Bukin return ofw_bus_get_node(bus); 146*484b4fd4SRuslan Bukin } 147*484b4fd4SRuslan Bukin 148*484b4fd4SRuslan Bukin static __inline void 149*484b4fd4SRuslan Bukin i2c_write_reg(struct i2c_softc *sc, bus_size_t off, uint8_t val) 150*484b4fd4SRuslan Bukin { 151*484b4fd4SRuslan Bukin 152*484b4fd4SRuslan Bukin bus_space_write_1(sc->bst, sc->bsh, off, val); 153*484b4fd4SRuslan Bukin } 154*484b4fd4SRuslan Bukin 155*484b4fd4SRuslan Bukin static __inline uint8_t 156*484b4fd4SRuslan Bukin i2c_read_reg(struct i2c_softc *sc, bus_size_t off) 157*484b4fd4SRuslan Bukin { 158*484b4fd4SRuslan Bukin 159*484b4fd4SRuslan Bukin return (bus_space_read_1(sc->bst, sc->bsh, off)); 160*484b4fd4SRuslan Bukin } 161*484b4fd4SRuslan Bukin 162*484b4fd4SRuslan Bukin static __inline void 163*484b4fd4SRuslan Bukin i2c_flag_set(struct i2c_softc *sc, bus_size_t off, uint8_t mask) 164*484b4fd4SRuslan Bukin { 165*484b4fd4SRuslan Bukin uint8_t status; 166*484b4fd4SRuslan Bukin 167*484b4fd4SRuslan Bukin status = i2c_read_reg(sc, off); 168*484b4fd4SRuslan Bukin status |= mask; 169*484b4fd4SRuslan Bukin i2c_write_reg(sc, off, status); 170*484b4fd4SRuslan Bukin } 171*484b4fd4SRuslan Bukin 172*484b4fd4SRuslan Bukin /* Wait for transfer interrupt flag */ 173*484b4fd4SRuslan Bukin static int 174*484b4fd4SRuslan Bukin wait_for_iif(struct i2c_softc *sc) 175*484b4fd4SRuslan Bukin { 176*484b4fd4SRuslan Bukin int retry; 177*484b4fd4SRuslan Bukin 178*484b4fd4SRuslan Bukin retry = 1000; 179*484b4fd4SRuslan Bukin while (retry --) { 180*484b4fd4SRuslan Bukin if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MIF) 181*484b4fd4SRuslan Bukin return (IIC_NOERR); 182*484b4fd4SRuslan Bukin DELAY(10); 183*484b4fd4SRuslan Bukin } 184*484b4fd4SRuslan Bukin 185*484b4fd4SRuslan Bukin return (IIC_ETIMEOUT); 186*484b4fd4SRuslan Bukin } 187*484b4fd4SRuslan Bukin 188*484b4fd4SRuslan Bukin /* Wait for free bus */ 189*484b4fd4SRuslan Bukin static int 190*484b4fd4SRuslan Bukin wait_for_nibb(struct i2c_softc *sc) 191*484b4fd4SRuslan Bukin { 192*484b4fd4SRuslan Bukin int retry; 193*484b4fd4SRuslan Bukin 194*484b4fd4SRuslan Bukin retry = 1000; 195*484b4fd4SRuslan Bukin while (retry --) { 196*484b4fd4SRuslan Bukin if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0) 197*484b4fd4SRuslan Bukin return (IIC_NOERR); 198*484b4fd4SRuslan Bukin DELAY(10); 199*484b4fd4SRuslan Bukin } 200*484b4fd4SRuslan Bukin 201*484b4fd4SRuslan Bukin return (IIC_ETIMEOUT); 202*484b4fd4SRuslan Bukin } 203*484b4fd4SRuslan Bukin 204*484b4fd4SRuslan Bukin /* Wait for transfer complete+interrupt flag */ 205*484b4fd4SRuslan Bukin static int 206*484b4fd4SRuslan Bukin wait_for_icf(struct i2c_softc *sc) 207*484b4fd4SRuslan Bukin { 208*484b4fd4SRuslan Bukin int retry; 209*484b4fd4SRuslan Bukin 210*484b4fd4SRuslan Bukin retry = 1000; 211*484b4fd4SRuslan Bukin while (retry --) { 212*484b4fd4SRuslan Bukin 213*484b4fd4SRuslan Bukin if ((i2c_read_reg(sc, I2C_STATUS_REG) & 214*484b4fd4SRuslan Bukin (I2CSR_MCF|I2CSR_MIF)) == (I2CSR_MCF|I2CSR_MIF)) 215*484b4fd4SRuslan Bukin return (IIC_NOERR); 216*484b4fd4SRuslan Bukin DELAY(10); 217*484b4fd4SRuslan Bukin } 218*484b4fd4SRuslan Bukin 219*484b4fd4SRuslan Bukin return (IIC_ETIMEOUT); 220*484b4fd4SRuslan Bukin } 221*484b4fd4SRuslan Bukin 222*484b4fd4SRuslan Bukin static int 223*484b4fd4SRuslan Bukin i2c_probe(device_t dev) 224*484b4fd4SRuslan Bukin { 225*484b4fd4SRuslan Bukin struct i2c_softc *sc; 226*484b4fd4SRuslan Bukin 227*484b4fd4SRuslan Bukin if (!ofw_bus_status_okay(dev)) 228*484b4fd4SRuslan Bukin return (ENXIO); 229*484b4fd4SRuslan Bukin 230*484b4fd4SRuslan Bukin if (!ofw_bus_is_compatible(dev, "fsl,imx-i2c")) 231*484b4fd4SRuslan Bukin return (ENXIO); 232*484b4fd4SRuslan Bukin 233*484b4fd4SRuslan Bukin sc = device_get_softc(dev); 234*484b4fd4SRuslan Bukin sc->rid = 0; 235*484b4fd4SRuslan Bukin 236*484b4fd4SRuslan Bukin sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, 237*484b4fd4SRuslan Bukin RF_ACTIVE); 238*484b4fd4SRuslan Bukin if (sc->res == NULL) { 239*484b4fd4SRuslan Bukin device_printf(dev, "could not allocate resources\n"); 240*484b4fd4SRuslan Bukin return (ENXIO); 241*484b4fd4SRuslan Bukin } 242*484b4fd4SRuslan Bukin 243*484b4fd4SRuslan Bukin sc->bst = rman_get_bustag(sc->res); 244*484b4fd4SRuslan Bukin sc->bsh = rman_get_bushandle(sc->res); 245*484b4fd4SRuslan Bukin 246*484b4fd4SRuslan Bukin /* Enable I2C */ 247*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN); 248*484b4fd4SRuslan Bukin bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res); 249*484b4fd4SRuslan Bukin device_set_desc(dev, "I2C bus controller"); 250*484b4fd4SRuslan Bukin 251*484b4fd4SRuslan Bukin return (BUS_PROBE_DEFAULT); 252*484b4fd4SRuslan Bukin } 253*484b4fd4SRuslan Bukin 254*484b4fd4SRuslan Bukin static int 255*484b4fd4SRuslan Bukin i2c_attach(device_t dev) 256*484b4fd4SRuslan Bukin { 257*484b4fd4SRuslan Bukin struct i2c_softc *sc; 258*484b4fd4SRuslan Bukin 259*484b4fd4SRuslan Bukin sc = device_get_softc(dev); 260*484b4fd4SRuslan Bukin sc->dev = dev; 261*484b4fd4SRuslan Bukin sc->rid = 0; 262*484b4fd4SRuslan Bukin 263*484b4fd4SRuslan Bukin mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF); 264*484b4fd4SRuslan Bukin 265*484b4fd4SRuslan Bukin sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, 266*484b4fd4SRuslan Bukin RF_ACTIVE); 267*484b4fd4SRuslan Bukin if (sc->res == NULL) { 268*484b4fd4SRuslan Bukin device_printf(dev, "could not allocate resources"); 269*484b4fd4SRuslan Bukin mtx_destroy(&sc->mutex); 270*484b4fd4SRuslan Bukin return (ENXIO); 271*484b4fd4SRuslan Bukin } 272*484b4fd4SRuslan Bukin 273*484b4fd4SRuslan Bukin sc->bst = rman_get_bustag(sc->res); 274*484b4fd4SRuslan Bukin sc->bsh = rman_get_bushandle(sc->res); 275*484b4fd4SRuslan Bukin 276*484b4fd4SRuslan Bukin sc->iicbus = device_add_child(dev, "iicbus", -1); 277*484b4fd4SRuslan Bukin if (sc->iicbus == NULL) { 278*484b4fd4SRuslan Bukin device_printf(dev, "could not add iicbus child"); 279*484b4fd4SRuslan Bukin mtx_destroy(&sc->mutex); 280*484b4fd4SRuslan Bukin return (ENXIO); 281*484b4fd4SRuslan Bukin } 282*484b4fd4SRuslan Bukin 283*484b4fd4SRuslan Bukin bus_generic_attach(dev); 284*484b4fd4SRuslan Bukin return (IIC_NOERR); 285*484b4fd4SRuslan Bukin } 286*484b4fd4SRuslan Bukin 287*484b4fd4SRuslan Bukin static int 288*484b4fd4SRuslan Bukin i2c_repeated_start(device_t dev, u_char slave, int timeout) 289*484b4fd4SRuslan Bukin { 290*484b4fd4SRuslan Bukin struct i2c_softc *sc; 291*484b4fd4SRuslan Bukin int error; 292*484b4fd4SRuslan Bukin 293*484b4fd4SRuslan Bukin sc = device_get_softc(dev); 294*484b4fd4SRuslan Bukin 295*484b4fd4SRuslan Bukin mtx_lock(&sc->mutex); 296*484b4fd4SRuslan Bukin 297*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_ADDR_REG, slave); 298*484b4fd4SRuslan Bukin if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0) { 299*484b4fd4SRuslan Bukin mtx_unlock(&sc->mutex); 300*484b4fd4SRuslan Bukin return (IIC_EBUSBSY); 301*484b4fd4SRuslan Bukin } 302*484b4fd4SRuslan Bukin 303*484b4fd4SRuslan Bukin /* Set repeated start condition */ 304*484b4fd4SRuslan Bukin DELAY(10); 305*484b4fd4SRuslan Bukin i2c_flag_set(sc, I2C_CONTROL_REG, I2CCR_RSTA); 306*484b4fd4SRuslan Bukin DELAY(10); 307*484b4fd4SRuslan Bukin /* Clear status */ 308*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 309*484b4fd4SRuslan Bukin /* Write target address - LSB is R/W bit */ 310*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_DATA_REG, slave); 311*484b4fd4SRuslan Bukin 312*484b4fd4SRuslan Bukin error = wait_for_iif(sc); 313*484b4fd4SRuslan Bukin 314*484b4fd4SRuslan Bukin /* Clear status */ 315*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 316*484b4fd4SRuslan Bukin 317*484b4fd4SRuslan Bukin mtx_unlock(&sc->mutex); 318*484b4fd4SRuslan Bukin 319*484b4fd4SRuslan Bukin if (error) 320*484b4fd4SRuslan Bukin return (error); 321*484b4fd4SRuslan Bukin 322*484b4fd4SRuslan Bukin return (IIC_NOERR); 323*484b4fd4SRuslan Bukin } 324*484b4fd4SRuslan Bukin 325*484b4fd4SRuslan Bukin static int 326*484b4fd4SRuslan Bukin i2c_start(device_t dev, u_char slave, int timeout) 327*484b4fd4SRuslan Bukin { 328*484b4fd4SRuslan Bukin struct i2c_softc *sc; 329*484b4fd4SRuslan Bukin int error; 330*484b4fd4SRuslan Bukin 331*484b4fd4SRuslan Bukin sc = device_get_softc(dev); 332*484b4fd4SRuslan Bukin 333*484b4fd4SRuslan Bukin mtx_lock(&sc->mutex); 334*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_ADDR_REG, slave); 335*484b4fd4SRuslan Bukin if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) { 336*484b4fd4SRuslan Bukin mtx_unlock(&sc->mutex); 337*484b4fd4SRuslan Bukin return (IIC_EBUSBSY); 338*484b4fd4SRuslan Bukin } 339*484b4fd4SRuslan Bukin 340*484b4fd4SRuslan Bukin /* Set start condition */ 341*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, 342*484b4fd4SRuslan Bukin I2CCR_MEN | I2CCR_MSTA | I2CCR_TXAK); 343*484b4fd4SRuslan Bukin DELAY(100); 344*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, 345*484b4fd4SRuslan Bukin I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX | I2CCR_TXAK); 346*484b4fd4SRuslan Bukin /* Clear status */ 347*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 348*484b4fd4SRuslan Bukin /* Write target address - LSB is R/W bit */ 349*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_DATA_REG, slave); 350*484b4fd4SRuslan Bukin 351*484b4fd4SRuslan Bukin error = wait_for_iif(sc); 352*484b4fd4SRuslan Bukin 353*484b4fd4SRuslan Bukin mtx_unlock(&sc->mutex); 354*484b4fd4SRuslan Bukin if (error) 355*484b4fd4SRuslan Bukin return (error); 356*484b4fd4SRuslan Bukin 357*484b4fd4SRuslan Bukin return (IIC_NOERR); 358*484b4fd4SRuslan Bukin } 359*484b4fd4SRuslan Bukin 360*484b4fd4SRuslan Bukin 361*484b4fd4SRuslan Bukin static int 362*484b4fd4SRuslan Bukin i2c_stop(device_t dev) 363*484b4fd4SRuslan Bukin { 364*484b4fd4SRuslan Bukin struct i2c_softc *sc; 365*484b4fd4SRuslan Bukin 366*484b4fd4SRuslan Bukin sc = device_get_softc(dev); 367*484b4fd4SRuslan Bukin mtx_lock(&sc->mutex); 368*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK); 369*484b4fd4SRuslan Bukin DELAY(100); 370*484b4fd4SRuslan Bukin /* Reset controller if bus still busy after STOP */ 371*484b4fd4SRuslan Bukin if (wait_for_nibb(sc) == IIC_ETIMEOUT) { 372*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, 0); 373*484b4fd4SRuslan Bukin DELAY(1000); 374*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK); 375*484b4fd4SRuslan Bukin 376*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 377*484b4fd4SRuslan Bukin } 378*484b4fd4SRuslan Bukin mtx_unlock(&sc->mutex); 379*484b4fd4SRuslan Bukin 380*484b4fd4SRuslan Bukin return (IIC_NOERR); 381*484b4fd4SRuslan Bukin } 382*484b4fd4SRuslan Bukin 383*484b4fd4SRuslan Bukin static int 384*484b4fd4SRuslan Bukin i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) 385*484b4fd4SRuslan Bukin { 386*484b4fd4SRuslan Bukin struct i2c_softc *sc; 387*484b4fd4SRuslan Bukin uint8_t baud_rate; 388*484b4fd4SRuslan Bukin 389*484b4fd4SRuslan Bukin sc = device_get_softc(dev); 390*484b4fd4SRuslan Bukin 391*484b4fd4SRuslan Bukin switch (speed) { 392*484b4fd4SRuslan Bukin case IIC_FAST: 393*484b4fd4SRuslan Bukin baud_rate = I2C_BAUD_RATE_FAST; 394*484b4fd4SRuslan Bukin break; 395*484b4fd4SRuslan Bukin case IIC_SLOW: 396*484b4fd4SRuslan Bukin case IIC_UNKNOWN: 397*484b4fd4SRuslan Bukin case IIC_FASTEST: 398*484b4fd4SRuslan Bukin default: 399*484b4fd4SRuslan Bukin baud_rate = I2C_BAUD_RATE_DEF; 400*484b4fd4SRuslan Bukin break; 401*484b4fd4SRuslan Bukin } 402*484b4fd4SRuslan Bukin 403*484b4fd4SRuslan Bukin mtx_lock(&sc->mutex); 404*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, 0x0); 405*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 406*484b4fd4SRuslan Bukin DELAY(1000); 407*484b4fd4SRuslan Bukin 408*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_FDR_REG, 20); 409*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN); 410*484b4fd4SRuslan Bukin DELAY(1000); 411*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 412*484b4fd4SRuslan Bukin mtx_unlock(&sc->mutex); 413*484b4fd4SRuslan Bukin 414*484b4fd4SRuslan Bukin return (IIC_NOERR); 415*484b4fd4SRuslan Bukin } 416*484b4fd4SRuslan Bukin 417*484b4fd4SRuslan Bukin static int 418*484b4fd4SRuslan Bukin i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay) 419*484b4fd4SRuslan Bukin { 420*484b4fd4SRuslan Bukin struct i2c_softc *sc; 421*484b4fd4SRuslan Bukin int error, reg; 422*484b4fd4SRuslan Bukin 423*484b4fd4SRuslan Bukin sc = device_get_softc(dev); 424*484b4fd4SRuslan Bukin *read = 0; 425*484b4fd4SRuslan Bukin 426*484b4fd4SRuslan Bukin mtx_lock(&sc->mutex); 427*484b4fd4SRuslan Bukin 428*484b4fd4SRuslan Bukin if (len) { 429*484b4fd4SRuslan Bukin if (len == 1) 430*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 431*484b4fd4SRuslan Bukin I2CCR_MSTA | I2CCR_TXAK); 432*484b4fd4SRuslan Bukin 433*484b4fd4SRuslan Bukin else 434*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 435*484b4fd4SRuslan Bukin I2CCR_MSTA); 436*484b4fd4SRuslan Bukin 437*484b4fd4SRuslan Bukin /* dummy read */ 438*484b4fd4SRuslan Bukin i2c_read_reg(sc, I2C_DATA_REG); 439*484b4fd4SRuslan Bukin DELAY(1000); 440*484b4fd4SRuslan Bukin } 441*484b4fd4SRuslan Bukin 442*484b4fd4SRuslan Bukin while (*read < len) { 443*484b4fd4SRuslan Bukin error = wait_for_icf(sc); 444*484b4fd4SRuslan Bukin if (error) { 445*484b4fd4SRuslan Bukin mtx_unlock(&sc->mutex); 446*484b4fd4SRuslan Bukin return (error); 447*484b4fd4SRuslan Bukin } 448*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 449*484b4fd4SRuslan Bukin if ((*read == len - 2) && last) { 450*484b4fd4SRuslan Bukin /* NO ACK on last byte */ 451*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 452*484b4fd4SRuslan Bukin I2CCR_MSTA | I2CCR_TXAK); 453*484b4fd4SRuslan Bukin } 454*484b4fd4SRuslan Bukin 455*484b4fd4SRuslan Bukin if ((*read == len - 1) && last) { 456*484b4fd4SRuslan Bukin /* Transfer done, remove master bit */ 457*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | 458*484b4fd4SRuslan Bukin I2CCR_TXAK); 459*484b4fd4SRuslan Bukin } 460*484b4fd4SRuslan Bukin 461*484b4fd4SRuslan Bukin reg = i2c_read_reg(sc, I2C_DATA_REG); 462*484b4fd4SRuslan Bukin *buf++ = reg; 463*484b4fd4SRuslan Bukin (*read)++; 464*484b4fd4SRuslan Bukin } 465*484b4fd4SRuslan Bukin mtx_unlock(&sc->mutex); 466*484b4fd4SRuslan Bukin 467*484b4fd4SRuslan Bukin return (IIC_NOERR); 468*484b4fd4SRuslan Bukin } 469*484b4fd4SRuslan Bukin 470*484b4fd4SRuslan Bukin static int 471*484b4fd4SRuslan Bukin i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout) 472*484b4fd4SRuslan Bukin { 473*484b4fd4SRuslan Bukin struct i2c_softc *sc; 474*484b4fd4SRuslan Bukin int error; 475*484b4fd4SRuslan Bukin 476*484b4fd4SRuslan Bukin sc = device_get_softc(dev); 477*484b4fd4SRuslan Bukin *sent = 0; 478*484b4fd4SRuslan Bukin 479*484b4fd4SRuslan Bukin mtx_lock(&sc->mutex); 480*484b4fd4SRuslan Bukin while (*sent < len) { 481*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_STATUS_REG, 0x0); 482*484b4fd4SRuslan Bukin i2c_write_reg(sc, I2C_DATA_REG, *buf++); 483*484b4fd4SRuslan Bukin 484*484b4fd4SRuslan Bukin error = wait_for_iif(sc); 485*484b4fd4SRuslan Bukin if (error) { 486*484b4fd4SRuslan Bukin mtx_unlock(&sc->mutex); 487*484b4fd4SRuslan Bukin return (error); 488*484b4fd4SRuslan Bukin } 489*484b4fd4SRuslan Bukin 490*484b4fd4SRuslan Bukin (*sent)++; 491*484b4fd4SRuslan Bukin } 492*484b4fd4SRuslan Bukin mtx_unlock(&sc->mutex); 493*484b4fd4SRuslan Bukin 494*484b4fd4SRuslan Bukin return (IIC_NOERR); 495*484b4fd4SRuslan Bukin } 496