1 /* $NetBSD: pca9564.c,v 1.1 2010/04/09 10:09:50 nonaka Exp $ */ 2 3 /* 4 * Copyright (c) 2010 NONAKA Kimihiro <nonaka@netbsd.org> 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 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: pca9564.c,v 1.1 2010/04/09 10:09:50 nonaka Exp $"); 30 31 #include <sys/param.h> 32 #include <sys/device.h> 33 #include <sys/mutex.h> 34 #include <sys/bus.h> 35 36 #include <dev/i2c/i2cvar.h> 37 38 #include <dev/ic/pca9564reg.h> 39 #include <dev/ic/pca9564var.h> 40 41 #if defined(PCA9564_DEBUG) 42 int pca9564debug = 0; 43 #define DPRINTF(s) if (pca9564debug) printf s 44 #else 45 #define DPRINTF(s) 46 #endif 47 48 static int pca9564_acquire_bus(void *, int); 49 static void pca9564_release_bus(void *, int); 50 51 static int pca9564_send_start(void *, int); 52 static int pca9564_send_stop(void *, int); 53 static int pca9564_initiate_xfer(void *, uint16_t, int); 54 static int pca9564_read_byte(void *, uint8_t *, int); 55 static int pca9564_write_byte(void *, uint8_t, int); 56 57 static int pca9564_ack(void *, bool, int); 58 59 #define CSR_READ(sc, r) (*sc->sc_ios.read_byte)(sc->sc_dev, r) 60 #define CSR_WRITE(sc, r, v) (*sc->sc_ios.write_byte)(sc->sc_dev, r, v) 61 62 void 63 pca9564_attach(struct pca9564_softc *sc) 64 { 65 struct i2cbus_attach_args iba; 66 67 aprint_naive("\n"); 68 aprint_normal(": PCA9564 I2C Controller\n"); 69 70 mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE); 71 72 sc->sc_i2c.ic_cookie = sc; 73 sc->sc_i2c.ic_acquire_bus = pca9564_acquire_bus; 74 sc->sc_i2c.ic_release_bus = pca9564_release_bus; 75 sc->sc_i2c.ic_send_start = pca9564_send_start; 76 sc->sc_i2c.ic_send_stop = pca9564_send_stop; 77 sc->sc_i2c.ic_initiate_xfer = pca9564_initiate_xfer; 78 sc->sc_i2c.ic_read_byte = pca9564_read_byte; 79 sc->sc_i2c.ic_write_byte = pca9564_write_byte; 80 sc->sc_i2c.ic_exec = NULL; 81 82 /* set serial clock rate */ 83 switch (sc->sc_i2c_clock) { 84 case 330000: /* 330kHz */ 85 sc->sc_i2c_clock = I2CCON_CR_330KHZ; 86 break; 87 case 288000: /* 288kHz */ 88 sc->sc_i2c_clock = I2CCON_CR_288KHZ; 89 break; 90 case 217000: /* 217kHz */ 91 sc->sc_i2c_clock = I2CCON_CR_217KHZ; 92 break; 93 case 146000: /* 146kHz */ 94 sc->sc_i2c_clock = I2CCON_CR_146KHZ; 95 break; 96 case 88000: /* 88kHz */ 97 sc->sc_i2c_clock = I2CCON_CR_88KHZ; 98 break; 99 case 0: /* default */ 100 case 59000: /* 59kHz */ 101 sc->sc_i2c_clock = I2CCON_CR_59KHZ; 102 break; 103 case 44000: /* 44kHz */ 104 sc->sc_i2c_clock = I2CCON_CR_44KHZ; 105 break; 106 case 36000: /* 36kHz */ 107 sc->sc_i2c_clock = I2CCON_CR_36KHZ; 108 break; 109 default: 110 aprint_error_dev(sc->sc_dev, "unknown i2c clock %dHz\n", 111 sc->sc_i2c_clock); 112 sc->sc_i2c_clock = I2CCON_CR_59KHZ; 113 break; 114 } 115 116 iba.iba_tag = &sc->sc_i2c; 117 (void) config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print); 118 } 119 120 static int 121 pca9564_acquire_bus(void *cookie, int flags) 122 { 123 struct pca9564_softc *sc = cookie; 124 uint8_t control; 125 126 mutex_enter(&sc->sc_buslock); 127 128 /* Enable SIO and set clock */ 129 control = CSR_READ(sc, PCA9564_I2CCON); 130 control |= I2CCON_ENSIO; 131 control &= ~(I2CCON_STA|I2CCON_STO|I2CCON_SI|I2CCON_AA); 132 control &= ~I2CCON_CR_MASK; 133 control |= sc->sc_i2c_clock; 134 CSR_WRITE(sc, PCA9564_I2CCON, control); 135 delay(500); 136 137 return 0; 138 } 139 140 static void 141 pca9564_release_bus(void *cookie, int flags) 142 { 143 struct pca9564_softc *sc = cookie; 144 uint8_t control; 145 146 /* Disable SIO */ 147 control = CSR_READ(sc, PCA9564_I2CCON); 148 control &= ~I2CCON_ENSIO; 149 CSR_WRITE(sc, PCA9564_I2CCON, control); 150 151 mutex_exit(&sc->sc_buslock); 152 } 153 154 #define PCA9564_TIMEOUT 100 /* protocol timeout, in uSecs */ 155 156 static int 157 pca9564_wait(struct pca9564_softc *sc, int flags) 158 { 159 int timeout; 160 161 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 162 for (timeout = PCA9564_TIMEOUT; timeout > 0; timeout--) { 163 if (CSR_READ(sc, PCA9564_I2CCON) & I2CCON_SI) 164 break; 165 delay(1); 166 } 167 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 168 if (timeout == 0) { 169 aprint_error_dev(sc->sc_dev, "timeout\n"); 170 return ETIMEDOUT; 171 } 172 return 0; 173 } 174 175 static int 176 pca9564_send_start(void *cookie, int flags) 177 { 178 struct pca9564_softc *sc = cookie; 179 uint8_t control; 180 181 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 182 control = CSR_READ(sc, PCA9564_I2CCON); 183 control |= I2CCON_STA; 184 control &= ~(I2CCON_STO|I2CCON_SI); 185 CSR_WRITE(sc, PCA9564_I2CCON, control); 186 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 187 188 return pca9564_wait(sc, flags); 189 } 190 191 static int 192 pca9564_send_stop(void *cookie, int flags) 193 { 194 struct pca9564_softc *sc = cookie; 195 uint8_t control; 196 197 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 198 control = CSR_READ(sc, PCA9564_I2CCON); 199 control |= I2CCON_STO; 200 control &= ~(I2CCON_STA|I2CCON_SI); 201 CSR_WRITE(sc, PCA9564_I2CCON, control); 202 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 203 204 return 0; 205 } 206 207 static int 208 pca9564_initiate_xfer(void *cookie, uint16_t addr, int flags) 209 { 210 struct pca9564_softc *sc = cookie; 211 int error, rd_req = (flags & I2C_F_READ) != 0; 212 uint8_t data, control; 213 214 error = pca9564_send_start(sc, flags); 215 if (error) { 216 aprint_error_dev(sc->sc_dev, "failed to send start %s xfer\n", 217 rd_req ? "read" : "write"); 218 return error; 219 } 220 221 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 222 control = CSR_READ(sc, PCA9564_I2CCON); 223 224 data = (addr << 1) | (rd_req ? 1 : 0); 225 CSR_WRITE(sc, PCA9564_I2CDAT, data); 226 227 control &= ~(I2CCON_STO|I2CCON_STA|I2CCON_SI); 228 CSR_WRITE(sc, PCA9564_I2CCON, control); 229 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 230 231 error = pca9564_wait(sc, flags); 232 if (error) 233 aprint_error_dev(sc->sc_dev, "failed to initiate %s xfer\n", 234 rd_req ? "read" : "write"); 235 return error; 236 } 237 238 static int 239 pca9564_read_byte(void *cookie, uint8_t *bytep, int flags) 240 { 241 struct pca9564_softc *sc = cookie; 242 int send_stop = (flags & I2C_F_STOP) != 0; 243 int error; 244 245 error = pca9564_ack(sc, !send_stop, flags); 246 if (error) { 247 aprint_error_dev(sc->sc_dev, "failed to ack\n"); 248 return error; 249 } 250 251 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 252 *bytep = CSR_READ(sc, PCA9564_I2CDAT); 253 DPRINTF(("%s: status=%#x, byte=%#x\n", __func__, 254 CSR_READ(sc, PCA9564_I2CSTA), *bytep)); 255 256 if (send_stop) 257 pca9564_send_stop(sc, flags); 258 259 return 0; 260 } 261 262 static int 263 pca9564_write_byte(void *cookie, uint8_t byte, int flags) 264 { 265 struct pca9564_softc *sc = cookie; 266 int send_stop = (flags & I2C_F_STOP) != 0; 267 int error; 268 uint8_t control; 269 270 DPRINTF(("%s: status=%#x, byte=%#x\n", __func__, 271 CSR_READ(sc, PCA9564_I2CSTA), byte)); 272 control = CSR_READ(sc, PCA9564_I2CCON); 273 274 CSR_WRITE(sc, PCA9564_I2CDAT, byte); 275 276 control &= ~(I2CCON_STO|I2CCON_STA|I2CCON_SI); 277 CSR_WRITE(sc, PCA9564_I2CCON, control); 278 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 279 280 error = pca9564_wait(sc, flags); 281 if (error) 282 aprint_error_dev(sc->sc_dev, "write byte failed\n"); 283 284 if (send_stop) 285 pca9564_send_stop(sc, flags); 286 287 return error; 288 } 289 290 static int 291 pca9564_ack(void *cookie, bool ack, int flags) 292 { 293 struct pca9564_softc *sc = cookie; 294 uint8_t control; 295 296 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 297 control = CSR_READ(sc, PCA9564_I2CCON); 298 control &= ~(I2CCON_STO|I2CCON_STA|I2CCON_SI|I2CCON_AA); 299 if (ack) 300 control |= I2CCON_AA; 301 CSR_WRITE(sc, PCA9564_I2CCON, control); 302 DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA))); 303 304 return pca9564_wait(sc, flags); 305 } 306