1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2003-2012 Broadcom Corporation 5 * All Rights Reserved 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 28 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/bus.h> 35 #include <sys/kernel.h> 36 #include <sys/lock.h> 37 #include <sys/module.h> 38 #include <sys/mutex.h> 39 #include <sys/rman.h> 40 41 #include <machine/bus.h> 42 43 #include <dev/iicbus/iicbus.h> 44 #include <dev/iicbus/iiconf.h> 45 46 #include "iicbus_if.h" 47 #include "iicoc.h" 48 49 DRIVER_MODULE(iicbus, iicoc, iicbus_driver, 0, 0); 50 51 static void 52 iicoc_dev_write(device_t dev, int reg, int value) 53 { 54 struct iicoc_softc *sc; 55 56 sc = device_get_softc(dev); 57 bus_write_1(sc->mem_res, reg<<sc->reg_shift, value); 58 } 59 60 static int 61 iicoc_dev_read(device_t dev, int reg) 62 { 63 uint8_t val; 64 struct iicoc_softc *sc; 65 66 sc = device_get_softc(dev); 67 val = bus_read_1(sc->mem_res, reg<<sc->reg_shift); 68 return (val); 69 } 70 71 static int 72 iicoc_wait_on_status(device_t dev, uint8_t bit) 73 { 74 int tries = I2C_TIMEOUT; 75 uint8_t status; 76 77 do { 78 status = iicoc_dev_read(dev, OC_I2C_STATUS_REG); 79 } while ((status & bit) != 0 && --tries > 0); 80 81 return (tries == 0 ? -1: 0); 82 } 83 84 static int 85 iicoc_rd_cmd(device_t dev, uint8_t cmd) 86 { 87 uint8_t data; 88 89 iicoc_dev_write(dev, OC_I2C_CMD_REG, cmd); 90 if (iicoc_wait_on_status(dev, OC_STATUS_TIP) < 0) { 91 device_printf(dev, "read: Timeout waiting for TIP clear.\n"); 92 return (-1); 93 } 94 data = iicoc_dev_read(dev, OC_I2C_DATA_REG); 95 return (data); 96 } 97 98 static int 99 iicoc_wr_cmd(device_t dev, uint8_t data, uint8_t cmd) 100 { 101 102 iicoc_dev_write(dev, OC_I2C_DATA_REG, data); 103 iicoc_dev_write(dev, OC_I2C_CMD_REG, cmd); 104 if (iicoc_wait_on_status(dev, OC_STATUS_TIP) < 0) { 105 device_printf(dev, "write: Timeout waiting for TIP clear.\n"); 106 return (-1); 107 } 108 return (0); 109 } 110 111 static int 112 iicoc_wr_ack_cmd(device_t dev, uint8_t data, uint8_t cmd) 113 { 114 115 if (iicoc_wr_cmd(dev, data, cmd) < 0) 116 return (-1); 117 118 if (iicoc_dev_read(dev, OC_I2C_STATUS_REG) & OC_STATUS_NACK) { 119 device_printf(dev, "write: I2C command ACK Error.\n"); 120 return (IIC_ENOACK); 121 } 122 return (0); 123 } 124 125 int 126 iicoc_init(device_t dev) 127 { 128 struct iicoc_softc *sc; 129 int value; 130 131 sc = device_get_softc(dev); 132 value = iicoc_dev_read(dev, OC_I2C_CTRL_REG); 133 iicoc_dev_write(dev, OC_I2C_CTRL_REG, 134 value & ~(OC_CONTROL_EN | OC_CONTROL_IEN)); 135 value = (sc->clockfreq/(5 * sc->i2cfreq)) - 1; 136 iicoc_dev_write(dev, OC_I2C_PRESCALE_LO_REG, value & 0xff); 137 iicoc_dev_write(dev, OC_I2C_PRESCALE_HI_REG, value >> 8); 138 value = iicoc_dev_read(dev, OC_I2C_CTRL_REG); 139 iicoc_dev_write(dev, OC_I2C_CTRL_REG, value | OC_CONTROL_EN); 140 141 value = iicoc_dev_read(dev, OC_I2C_CTRL_REG); 142 /* return 0 on success, 1 on error */ 143 return ((value & OC_CONTROL_EN) == 0); 144 } 145 146 static int 147 iicoc_iicbus_start_common(device_t dev, u_char slave, int timeout, bool repeat) 148 { 149 int error = IIC_EBUSERR; 150 struct iicoc_softc *sc; 151 152 sc = device_get_softc(dev); 153 mtx_lock(&sc->sc_mtx); 154 sc->i2cdev_addr = (slave >> 1); 155 156 /* Verify the bus is idle */ 157 if (!repeat && iicoc_wait_on_status(dev, OC_STATUS_BUSY) < 0) 158 goto i2c_stx_error; 159 160 /* Write Slave Address */ 161 if (iicoc_wr_ack_cmd(dev, slave, OC_COMMAND_START)) { 162 device_printf(dev, 163 "I2C write slave address [0x%x] failed.\n", slave); 164 error = IIC_ENOACK; 165 goto i2c_stx_error; 166 } 167 168 /* Verify Arbitration is not Lost */ 169 if (iicoc_dev_read(dev, OC_I2C_STATUS_REG) & OC_STATUS_AL) { 170 device_printf(dev, "I2C Bus Arbitration Lost, Aborting.\n"); 171 error = IIC_EBUSERR; 172 goto i2c_stx_error; 173 } 174 error = IIC_NOERR; 175 mtx_unlock(&sc->sc_mtx); 176 return (error); 177 178 i2c_stx_error: 179 iicoc_dev_write(dev, OC_I2C_CMD_REG, OC_COMMAND_STOP); 180 iicoc_wait_on_status(dev, OC_STATUS_BUSY); /* wait for idle */ 181 mtx_unlock(&sc->sc_mtx); 182 return (error); 183 } 184 185 int 186 iicoc_iicbus_start(device_t dev, u_char slave, int timeout) 187 { 188 189 return (iicoc_iicbus_start_common(dev, slave, timeout, false)); 190 } 191 192 int 193 iicoc_iicbus_repeated_start(device_t dev, u_char slave, int timeout) 194 { 195 196 return (iicoc_iicbus_start_common(dev, slave, timeout, true)); 197 } 198 199 int 200 iicoc_iicbus_stop(device_t dev) 201 { 202 int error = 0; 203 struct iicoc_softc *sc; 204 205 sc = device_get_softc(dev); 206 mtx_lock(&sc->sc_mtx); 207 iicoc_dev_write(dev, OC_I2C_CMD_REG, OC_COMMAND_STOP); 208 iicoc_wait_on_status(dev, OC_STATUS_BUSY); /* wait for idle */ 209 mtx_unlock(&sc->sc_mtx); 210 return (error); 211 } 212 213 int 214 iicoc_iicbus_write(device_t dev, const char *buf, int len, int *sent, 215 int timeout) 216 { 217 uint8_t value; 218 int i; 219 220 value = buf[0]; 221 /* Write Slave Offset */ 222 if (iicoc_wr_ack_cmd(dev, value, OC_COMMAND_WRITE)) { 223 device_printf(dev, "I2C write slave offset failed.\n"); 224 goto i2c_tx_error; 225 } 226 227 for (i = 1; i < len; i++) { 228 /* Write data byte */ 229 value = buf[i]; 230 if (iicoc_wr_cmd(dev, value, OC_COMMAND_WRITE)) { 231 device_printf(dev, "I2C write data byte %d failed.\n", 232 i); 233 goto i2c_tx_error; 234 } 235 } 236 *sent = len; 237 return (IIC_NOERR); 238 239 i2c_tx_error: 240 return (IIC_EBUSERR); 241 } 242 243 int 244 iicoc_iicbus_read(device_t dev, char *buf, int len, int *read, int last, 245 int delay) 246 { 247 int data, i; 248 uint8_t cmd; 249 250 for (i = 0; i < len; i++) { 251 /* Read data byte */ 252 cmd = (i == len - 1) ? OC_COMMAND_RDNACK : OC_COMMAND_READ; 253 data = iicoc_rd_cmd(dev, cmd); 254 if (data < 0) { 255 device_printf(dev, 256 "I2C read data byte %d failed.\n", i); 257 goto i2c_rx_error; 258 } 259 buf[i] = (uint8_t)data; 260 } 261 262 *read = len; 263 return (IIC_NOERR); 264 265 i2c_rx_error: 266 return (IIC_EBUSERR); 267 } 268 269 int 270 iicoc_iicbus_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) 271 { 272 int error; 273 struct iicoc_softc *sc; 274 275 sc = device_get_softc(dev); 276 mtx_lock(&sc->sc_mtx); 277 error = iicoc_init(dev); 278 mtx_unlock(&sc->sc_mtx); 279 return (error); 280 } 281