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/param.h> 32 #include <sys/systm.h> 33 #include <sys/bus.h> 34 #include <sys/kernel.h> 35 #include <sys/lock.h> 36 #include <sys/module.h> 37 #include <sys/mutex.h> 38 #include <sys/rman.h> 39 40 #include <machine/bus.h> 41 42 #include <dev/iicbus/iicbus.h> 43 #include <dev/iicbus/iiconf.h> 44 45 #include "iicbus_if.h" 46 #include "iicoc.h" 47 48 DRIVER_MODULE(iicbus, iicoc, iicbus_driver, 0, 0); 49 50 static void 51 iicoc_dev_write(device_t dev, int reg, int value) 52 { 53 struct iicoc_softc *sc; 54 55 sc = device_get_softc(dev); 56 bus_write_1(sc->mem_res, reg<<sc->reg_shift, value); 57 } 58 59 static int 60 iicoc_dev_read(device_t dev, int reg) 61 { 62 uint8_t val; 63 struct iicoc_softc *sc; 64 65 sc = device_get_softc(dev); 66 val = bus_read_1(sc->mem_res, reg<<sc->reg_shift); 67 return (val); 68 } 69 70 static int 71 iicoc_wait_on_status(device_t dev, uint8_t bit) 72 { 73 int tries = I2C_TIMEOUT; 74 uint8_t status; 75 76 do { 77 status = iicoc_dev_read(dev, OC_I2C_STATUS_REG); 78 } while ((status & bit) != 0 && --tries > 0); 79 80 return (tries == 0 ? -1: 0); 81 } 82 83 static int 84 iicoc_rd_cmd(device_t dev, uint8_t cmd) 85 { 86 uint8_t data; 87 88 iicoc_dev_write(dev, OC_I2C_CMD_REG, cmd); 89 if (iicoc_wait_on_status(dev, OC_STATUS_TIP) < 0) { 90 device_printf(dev, "read: Timeout waiting for TIP clear.\n"); 91 return (-1); 92 } 93 data = iicoc_dev_read(dev, OC_I2C_DATA_REG); 94 return (data); 95 } 96 97 static int 98 iicoc_wr_cmd(device_t dev, uint8_t data, uint8_t cmd) 99 { 100 101 iicoc_dev_write(dev, OC_I2C_DATA_REG, data); 102 iicoc_dev_write(dev, OC_I2C_CMD_REG, cmd); 103 if (iicoc_wait_on_status(dev, OC_STATUS_TIP) < 0) { 104 device_printf(dev, "write: Timeout waiting for TIP clear.\n"); 105 return (-1); 106 } 107 return (0); 108 } 109 110 static int 111 iicoc_wr_ack_cmd(device_t dev, uint8_t data, uint8_t cmd) 112 { 113 114 if (iicoc_wr_cmd(dev, data, cmd) < 0) 115 return (-1); 116 117 if (iicoc_dev_read(dev, OC_I2C_STATUS_REG) & OC_STATUS_NACK) { 118 device_printf(dev, "write: I2C command ACK Error.\n"); 119 return (IIC_ENOACK); 120 } 121 return (0); 122 } 123 124 int 125 iicoc_init(device_t dev) 126 { 127 struct iicoc_softc *sc; 128 int value; 129 130 sc = device_get_softc(dev); 131 value = iicoc_dev_read(dev, OC_I2C_CTRL_REG); 132 iicoc_dev_write(dev, OC_I2C_CTRL_REG, 133 value & ~(OC_CONTROL_EN | OC_CONTROL_IEN)); 134 value = (sc->clockfreq/(5 * sc->i2cfreq)) - 1; 135 iicoc_dev_write(dev, OC_I2C_PRESCALE_LO_REG, value & 0xff); 136 iicoc_dev_write(dev, OC_I2C_PRESCALE_HI_REG, value >> 8); 137 value = iicoc_dev_read(dev, OC_I2C_CTRL_REG); 138 iicoc_dev_write(dev, OC_I2C_CTRL_REG, value | OC_CONTROL_EN); 139 140 value = iicoc_dev_read(dev, OC_I2C_CTRL_REG); 141 /* return 0 on success, 1 on error */ 142 return ((value & OC_CONTROL_EN) == 0); 143 } 144 145 static int 146 iicoc_iicbus_start_common(device_t dev, u_char slave, int timeout, bool repeat) 147 { 148 int error = IIC_EBUSERR; 149 struct iicoc_softc *sc; 150 151 sc = device_get_softc(dev); 152 mtx_lock(&sc->sc_mtx); 153 sc->i2cdev_addr = (slave >> 1); 154 155 /* Verify the bus is idle */ 156 if (!repeat && iicoc_wait_on_status(dev, OC_STATUS_BUSY) < 0) 157 goto i2c_stx_error; 158 159 /* Write Slave Address */ 160 if (iicoc_wr_ack_cmd(dev, slave, OC_COMMAND_START)) { 161 device_printf(dev, 162 "I2C write slave address [0x%x] failed.\n", slave); 163 error = IIC_ENOACK; 164 goto i2c_stx_error; 165 } 166 167 /* Verify Arbitration is not Lost */ 168 if (iicoc_dev_read(dev, OC_I2C_STATUS_REG) & OC_STATUS_AL) { 169 device_printf(dev, "I2C Bus Arbitration Lost, Aborting.\n"); 170 error = IIC_EBUSERR; 171 goto i2c_stx_error; 172 } 173 error = IIC_NOERR; 174 mtx_unlock(&sc->sc_mtx); 175 return (error); 176 177 i2c_stx_error: 178 iicoc_dev_write(dev, OC_I2C_CMD_REG, OC_COMMAND_STOP); 179 iicoc_wait_on_status(dev, OC_STATUS_BUSY); /* wait for idle */ 180 mtx_unlock(&sc->sc_mtx); 181 return (error); 182 } 183 184 int 185 iicoc_iicbus_start(device_t dev, u_char slave, int timeout) 186 { 187 188 return (iicoc_iicbus_start_common(dev, slave, timeout, false)); 189 } 190 191 int 192 iicoc_iicbus_repeated_start(device_t dev, u_char slave, int timeout) 193 { 194 195 return (iicoc_iicbus_start_common(dev, slave, timeout, true)); 196 } 197 198 int 199 iicoc_iicbus_stop(device_t dev) 200 { 201 int error = 0; 202 struct iicoc_softc *sc; 203 204 sc = device_get_softc(dev); 205 mtx_lock(&sc->sc_mtx); 206 iicoc_dev_write(dev, OC_I2C_CMD_REG, OC_COMMAND_STOP); 207 iicoc_wait_on_status(dev, OC_STATUS_BUSY); /* wait for idle */ 208 mtx_unlock(&sc->sc_mtx); 209 return (error); 210 } 211 212 int 213 iicoc_iicbus_write(device_t dev, const char *buf, int len, int *sent, 214 int timeout) 215 { 216 uint8_t value; 217 int i; 218 219 value = buf[0]; 220 /* Write Slave Offset */ 221 if (iicoc_wr_ack_cmd(dev, value, OC_COMMAND_WRITE)) { 222 device_printf(dev, "I2C write slave offset failed.\n"); 223 goto i2c_tx_error; 224 } 225 226 for (i = 1; i < len; i++) { 227 /* Write data byte */ 228 value = buf[i]; 229 if (iicoc_wr_cmd(dev, value, OC_COMMAND_WRITE)) { 230 device_printf(dev, "I2C write data byte %d failed.\n", 231 i); 232 goto i2c_tx_error; 233 } 234 } 235 *sent = len; 236 return (IIC_NOERR); 237 238 i2c_tx_error: 239 return (IIC_EBUSERR); 240 } 241 242 int 243 iicoc_iicbus_read(device_t dev, char *buf, int len, int *read, int last, 244 int delay) 245 { 246 int data, i; 247 uint8_t cmd; 248 249 for (i = 0; i < len; i++) { 250 /* Read data byte */ 251 cmd = (i == len - 1) ? OC_COMMAND_RDNACK : OC_COMMAND_READ; 252 data = iicoc_rd_cmd(dev, cmd); 253 if (data < 0) { 254 device_printf(dev, 255 "I2C read data byte %d failed.\n", i); 256 goto i2c_rx_error; 257 } 258 buf[i] = (uint8_t)data; 259 } 260 261 *read = len; 262 return (IIC_NOERR); 263 264 i2c_rx_error: 265 return (IIC_EBUSERR); 266 } 267 268 int 269 iicoc_iicbus_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) 270 { 271 int error; 272 struct iicoc_softc *sc; 273 274 sc = device_get_softc(dev); 275 mtx_lock(&sc->sc_mtx); 276 error = iicoc_init(dev); 277 mtx_unlock(&sc->sc_mtx); 278 return (error); 279 } 280