1 1.5 jdc /* $NetBSD: fire_i2c.c,v 1.5 2026/09/25 07:16:27 jdc Exp $ */ 2 1.1 jdc 3 1.1 jdc /*- 4 1.1 jdc * Copyright (c) 2026 The NetBSD Foundation, Inc. 5 1.1 jdc * All rights reserved. 6 1.1 jdc * 7 1.1 jdc * This code is derived from software contributed to The NetBSD Foundation 8 1.1 jdc * by Julian Coleman. 9 1.1 jdc * 10 1.1 jdc * Redistribution and use in source and binary forms, with or without 11 1.1 jdc * modification, are permitted provided that the following conditions 12 1.1 jdc * are met: 13 1.1 jdc * 1. Redistributions of source code must retain the above copyright 14 1.1 jdc * notice, this list of conditions and the following disclaimer. 15 1.1 jdc * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 jdc * notice, this list of conditions and the following disclaimer in the 17 1.1 jdc * documentation and/or other materials provided with the distribution. 18 1.1 jdc * 19 1.1 jdc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 jdc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 jdc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 jdc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 jdc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 jdc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 jdc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 jdc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 jdc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 jdc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 jdc * POSSIBILITY OF SUCH DAMAGE. 30 1.1 jdc */ 31 1.1 jdc 32 1.1 jdc #include <sys/cdefs.h> 33 1.5 jdc __KERNEL_RCSID(0, "$NetBSD: fire_i2c.c,v 1.5 2026/09/25 07:16:27 jdc Exp $"); 34 1.1 jdc 35 1.1 jdc #include <sys/param.h> 36 1.1 jdc #include <sys/condvar.h> 37 1.1 jdc #include <sys/device.h> 38 1.1 jdc #include <sys/intr.h> 39 1.5 jdc #include <sys/kernel.h> 40 1.1 jdc #include <sys/mutex.h> 41 1.1 jdc 42 1.1 jdc #include <machine/autoconf.h> 43 1.1 jdc #include <machine/openfirm.h> 44 1.1 jdc 45 1.5 jdc #include <dev/pci/pcivar.h> 46 1.5 jdc 47 1.1 jdc #include <dev/i2c/i2cvar.h> 48 1.5 jdc #include <sparc64/dev/fire_i2creg.h> 49 1.5 jdc #include <sparc64/dev/iommureg.h> 50 1.5 jdc #include <sparc64/dev/iommuvar.h> 51 1.5 jdc #include <sparc64/dev/pyrovar.h> 52 1.5 jdc 53 1.5 jdc #include "ioconf.h" 54 1.1 jdc 55 1.1 jdc #define FIREI2C_DEBUG 0 56 1.1 jdc #if FIREI2C_DEBUG > 0 57 1.5 jdc int dlvl = 1; /* Set to 2 for verbose i2c ops output */ 58 1.5 jdc #define DPRINTF(n) if (dlvl >= n) printf 59 1.1 jdc #else 60 1.5 jdc #define DPRINTF(n) if (0) printf 61 1.1 jdc #endif 62 1.1 jdc 63 1.5 jdc #define FIREI2C_SCL_FREQ 100000 /* Target i2c clock frequency */ 64 1.5 jdc #define FIREI2C_OWN_ADDR 0x08 /* Our i2c slave address */ 65 1.1 jdc 66 1.5 jdc /* i2c clocks to match possible system clock frequencies (1/1, 1/2, 1/32) */ 67 1.1 jdc #define FIREI2C_CLK_FULL 0 68 1.1 jdc #define FIREI2C_CLK_HALF 1 69 1.1 jdc #define FIREI2C_CLK_TT 2 70 1.1 jdc #define FIREI2C_CLK_LEN 3 71 1.1 jdc 72 1.5 jdc /* i2c operations */ 73 1.5 jdc #define FIREI2C_OP_READ 0x01 74 1.5 jdc #define FIREI2C_OP_WRITE 0x02 75 1.5 jdc #define FIREI2C_OP_WR_RD 0x04 76 1.5 jdc 77 1.5 jdc /* i2c stages */ 78 1.5 jdc #define FIREI2C_STAGE_IDLE 0x00 79 1.5 jdc #define FIREI2C_STAGE_START 0x01 80 1.5 jdc #define FIREI2C_STAGE_WR_ADDR 0x02 81 1.5 jdc #define FIREI2C_STAGE_RE_ADDR 0x04 82 1.5 jdc #define FIREI2C_STAGE_WRITE 0x08 83 1.5 jdc #define FIREI2C_STAGE_REPSTART 0x10 84 1.5 jdc #define FIREI2C_STAGE_READ 0x20 85 1.5 jdc #define FIREI2C_STAGE_STOP 0x40 86 1.5 jdc 87 1.5 jdc /* mainbus intr map/mask are only used for i2c interrupts, so put them here. */ 88 1.5 jdc struct mainbus_interrupt_map { 89 1.5 jdc uint64_t paddr; /* phys addr mask */ 90 1.5 jdc uint32_t intr; /* interrupt mask */ 91 1.5 jdc int32_t cnode; /* child node */ 92 1.5 jdc uint32_t cintr; /* child interrupt */ 93 1.5 jdc } __packed; 94 1.5 jdc 95 1.5 jdc struct mainbus_interrupt_map_mask { 96 1.5 jdc uint64_t paddr; /* phys addr mask */ 97 1.5 jdc uint32_t intr; /* interrupt */ 98 1.5 jdc } __packed; 99 1.5 jdc 100 1.1 jdc struct firei2c_softc { 101 1.1 jdc device_t sc_dev; 102 1.1 jdc bus_space_tag_t sc_bustag; 103 1.1 jdc bus_space_handle_t sc_regh; 104 1.1 jdc int sc_node; 105 1.1 jdc void *sc_inth; 106 1.5 jdc 107 1.5 jdc uint8_t sc_i2c_clks[FIREI2C_CLK_LEN]; /* Clocks for sys bus speeds */ 108 1.5 jdc 109 1.1 jdc struct i2c_controller sc_i2c; 110 1.5 jdc 111 1.5 jdc kmutex_t sc_mutex; /* Interrupt mutex ... */ 112 1.5 jdc kcondvar_t sc_cv; /* ... and condvar */ 113 1.5 jdc 114 1.5 jdc int sc_op; /* Operation to run */ 115 1.5 jdc int sc_stage; /* Exec stage */ 116 1.5 jdc i2c_addr_t sc_target; /* Saved exec args */ 117 1.5 jdc const u_int8_t *sc_cmdbuf; /* ... */ 118 1.5 jdc size_t sc_cmdlen; /* ... */ 119 1.5 jdc u_int8_t *sc_buf; /* ... */ 120 1.5 jdc size_t sc_buflen; /* ... */ 121 1.5 jdc int sc_i; /* How far through buf */ 122 1.5 jdc int sc_err; /* Error during transaction */ 123 1.5 jdc 124 1.1 jdc }; 125 1.1 jdc 126 1.1 jdc static int firei2c_match(device_t, cfdata_t, void *); 127 1.1 jdc static void firei2c_attach(device_t, device_t, void *); 128 1.5 jdc static void firei2c_intr_establish(struct firei2c_softc *, 129 1.5 jdc struct mainbus_attach_args *); 130 1.1 jdc static uint8_t firei2c_clock(int); 131 1.1 jdc static int firei2c_stop(struct firei2c_softc *); 132 1.1 jdc static int firei2c_wait(struct firei2c_softc *, int); 133 1.1 jdc int firei2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, 134 1.1 jdc size_t, void *, size_t, int); 135 1.1 jdc static int firei2c_write(struct firei2c_softc *, const uint8_t *, size_t, 136 1.5 jdc uint8_t *, size_t, int); 137 1.5 jdc static int firei2c_read(struct firei2c_softc *, uint8_t *, size_t, int); 138 1.1 jdc int firei2c_intr(void *); 139 1.1 jdc static uint8_t firei2c_reg_read(struct firei2c_softc *, bus_size_t); 140 1.1 jdc static void firei2c_reg_write(struct firei2c_softc *, bus_size_t, uint8_t); 141 1.1 jdc 142 1.1 jdc CFATTACH_DECL_NEW(firei2c, sizeof(struct firei2c_softc), 143 1.1 jdc firei2c_match, firei2c_attach, NULL, NULL); 144 1.1 jdc 145 1.1 jdc static int 146 1.1 jdc firei2c_match(device_t parent, cfdata_t cf, void *aux) 147 1.1 jdc { 148 1.1 jdc struct mainbus_attach_args *ma = aux; 149 1.1 jdc char *compat; 150 1.1 jdc 151 1.1 jdc if (strcmp(ma->ma_name, "i2c")) 152 1.1 jdc return 0; 153 1.1 jdc 154 1.1 jdc compat = prom_getpropstring(ma->ma_node, "compatible"); 155 1.1 jdc if (!strcmp(compat, "fire-i2c")) 156 1.1 jdc return 1; 157 1.1 jdc 158 1.1 jdc return 0; 159 1.1 jdc } 160 1.1 jdc 161 1.1 jdc static void 162 1.1 jdc firei2c_attach(device_t parent, device_t self, void *aux) 163 1.1 jdc { 164 1.1 jdc struct firei2c_softc *sc = device_private(self); 165 1.1 jdc struct mainbus_attach_args *ma = aux; 166 1.1 jdc int sysclk; 167 1.1 jdc 168 1.1 jdc sc->sc_bustag = ma->ma_bustag; 169 1.1 jdc sc->sc_node = ma->ma_node; 170 1.1 jdc sc->sc_dev = self; 171 1.1 jdc 172 1.1 jdc if (ma->ma_nreg != 1) { 173 1.1 jdc aprint_error(": register count error (%d != 1)\n", 174 1.1 jdc ma->ma_nreg); 175 1.1 jdc return; 176 1.1 jdc } 177 1.1 jdc if (ma->ma_reg[0].ur_len < FIREI2C_SRST) { 178 1.4 nakayama aprint_error(": register length error (%" PRId64 " < %d\n", 179 1.4 nakayama ma->ma_reg[0].ur_len, FIREI2C_SRST); 180 1.1 jdc return; 181 1.1 jdc } 182 1.1 jdc 183 1.1 jdc if (bus_space_map(sc->sc_bustag, ma->ma_reg[0].ur_paddr, 184 1.1 jdc ma->ma_reg[0].ur_len, 0, &sc->sc_regh)) { 185 1.1 jdc aprint_error(": failed to map registers\n"); 186 1.1 jdc return; 187 1.1 jdc } 188 1.1 jdc 189 1.1 jdc aprint_normal(": addr %" PRIx64 ": Fire/MI2C i2c controller\n", 190 1.1 jdc ma->ma_reg[0].ur_paddr); 191 1.1 jdc 192 1.5 jdc firei2c_intr_establish(sc, ma); 193 1.5 jdc 194 1.5 jdc /* Calculate clock, software reset, set our address */ 195 1.1 jdc sysclk = prom_getpropint(findroot(), "clock-frequency", 0); 196 1.1 jdc sc->sc_i2c_clks[FIREI2C_CLK_FULL] = firei2c_clock(sysclk); 197 1.1 jdc sc->sc_i2c_clks[FIREI2C_CLK_HALF] = firei2c_clock(sysclk / 2); 198 1.1 jdc sc->sc_i2c_clks[FIREI2C_CLK_TT] = firei2c_clock(sysclk / 32); 199 1.1 jdc firei2c_reg_write(sc, FIREI2C_SRST, FIREI2C_SRST_RST); 200 1.1 jdc delay(1000); 201 1.1 jdc firei2c_reg_write(sc, FIREI2C_CCR, sc->sc_i2c_clks[FIREI2C_CLK_FULL]); 202 1.1 jdc firei2c_reg_write(sc, FIREI2C_ADDR, 203 1.1 jdc FIREI2C_OWN_ADDR << FIREI2C_ADDR_SHIFT); 204 1.1 jdc 205 1.1 jdc /* i2c setup */ 206 1.1 jdc iic_tag_init(&sc->sc_i2c); 207 1.1 jdc sc->sc_i2c.ic_cookie = sc; 208 1.1 jdc sc->sc_i2c.ic_exec = firei2c_exec; 209 1.1 jdc 210 1.1 jdc /* Synchronisation between exec and intr */ 211 1.1 jdc mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM); 212 1.1 jdc cv_init(&sc->sc_cv, "firei2c"); 213 1.5 jdc sc->sc_stage = FIREI2C_STAGE_IDLE; 214 1.1 jdc 215 1.1 jdc iicbus_attach(sc->sc_dev, &sc->sc_i2c); 216 1.1 jdc return; 217 1.1 jdc } 218 1.1 jdc 219 1.1 jdc /* 220 1.5 jdc * Use the mainbus (root) interrupt map/mask to find our interrupt number 221 1.5 jdc * (ino 60 or 61) and pyro leaf. 222 1.5 jdc * Both i2c interrupts must go to the same pyro leaf, but we assume that 223 1.5 jdc * OFW has set up the ino and the leaf mapping for us. 224 1.5 jdc */ 225 1.5 jdc #define IMASK_LEN 3 226 1.5 jdc #define IMAP_LEN 10 227 1.5 jdc static void 228 1.5 jdc firei2c_intr_establish(struct firei2c_softc *sc, 229 1.5 jdc struct mainbus_attach_args *ma) 230 1.5 jdc { 231 1.5 jdc struct mainbus_interrupt_map *mb_imap; 232 1.5 jdc struct mainbus_interrupt_map_mask *mb_imask; 233 1.5 jdc struct pyro_softc *psc = NULL; 234 1.5 jdc int64_t paddr; 235 1.5 jdc u_int intr; 236 1.5 jdc int ihandle, root, size, i; 237 1.5 jdc 238 1.5 jdc sc->sc_inth = NULL; /* Default */ 239 1.5 jdc ihandle = 0; 240 1.5 jdc 241 1.5 jdc /* Find our mapped interrupt number */ 242 1.5 jdc root = findroot(); 243 1.5 jdc mb_imask = NULL; 244 1.5 jdc if (prom_getprop(root, "interrupt-map-mask", 245 1.5 jdc sizeof(int32_t), &size, (void **) &mb_imask) || 246 1.5 jdc size != IMASK_LEN) { 247 1.5 jdc aprint_error(": no interrupt-map-mask\n"); 248 1.5 jdc return; 249 1.5 jdc } 250 1.5 jdc 251 1.5 jdc mb_imap = NULL; 252 1.5 jdc if (prom_getprop(root, "interrupt-map", 253 1.5 jdc sizeof(int32_t), &size, (void **) &mb_imap) || 254 1.5 jdc size != IMAP_LEN) { 255 1.5 jdc aprint_error(": no interrupt-map\n"); 256 1.5 jdc return; 257 1.5 jdc } 258 1.5 jdc 259 1.5 jdc intr = ma->ma_interrupts[0] && mb_imask->intr; 260 1.5 jdc DPRINTF(1)("%s: intr %x masked to %x\n", 261 1.5 jdc device_xname(sc->sc_dev), ma->ma_interrupts[0], intr); 262 1.5 jdc paddr = ma->ma_reg[0].ur_paddr & mb_imask->paddr; 263 1.5 jdc DPRINTF(1)("%s: reg 0x%" PRIx64 " masked to 0x%" PRIx64 "\n", 264 1.5 jdc device_xname(sc->sc_dev), ma->ma_reg[0].ur_paddr, paddr); 265 1.5 jdc for (i = 0; i < 2; i++) { 266 1.5 jdc DPRINTF(1)("%s: checking paddr 0x%" PRIx64 ", intr %x\n", 267 1.5 jdc device_xname(sc->sc_dev), mb_imap->paddr, mb_imap->intr); 268 1.5 jdc if (paddr == mb_imap->paddr && intr == mb_imap->intr) { 269 1.5 jdc ihandle = mb_imap->cintr; 270 1.5 jdc DPRINTF(1)("%s: found cintr %d, cnode 0x%x\n", 271 1.5 jdc device_xname(sc->sc_dev), ihandle, mb_imap->cnode); 272 1.5 jdc break; 273 1.5 jdc } 274 1.5 jdc mb_imap++; 275 1.5 jdc } 276 1.5 jdc if (ihandle == 0) { 277 1.5 jdc aprint_error(": failed to match interrupt\n"); 278 1.5 jdc return; 279 1.5 jdc } 280 1.5 jdc 281 1.5 jdc /* Find the pyro leaf with the matching cnode ) */ 282 1.5 jdc for (i = 0; i < pyro_cd.cd_ndevs; i++) { 283 1.5 jdc device_t dt = device_lookup(&pyro_cd, i); 284 1.5 jdc psc = device_private(dt); 285 1.5 jdc if (psc && psc->sc_node == mb_imap->cnode) { 286 1.5 jdc DPRINTF(1)("%s: matched pyro %d (0x%x)\n", 287 1.5 jdc device_xname(sc->sc_dev), i, psc->sc_node); 288 1.5 jdc ihandle |= psc->sc_ign; 289 1.5 jdc break; 290 1.5 jdc } 291 1.5 jdc } 292 1.5 jdc if (psc == NULL) { 293 1.5 jdc aprint_error(": failed to match pyro leaf\n"); 294 1.5 jdc return; 295 1.5 jdc } 296 1.5 jdc 297 1.5 jdc sc->sc_inth = psc->intr_establish_sc(psc, 298 1.5 jdc ihandle, IPL_BIO, firei2c_intr, sc, NULL); 299 1.5 jdc 300 1.5 jdc if (sc->sc_inth != NULL) { 301 1.5 jdc aprint_normal_dev(sc->sc_dev, 302 1.5 jdc "interrupting at ivec %x on pyro%d\n", ihandle, i); 303 1.5 jdc } 304 1.5 jdc 305 1.5 jdc return; 306 1.5 jdc } 307 1.5 jdc 308 1.5 jdc /* 309 1.1 jdc * Sampling frequency: input clock divided by 2^N (N is bits 0:2) 310 1.1 jdc * SCL frequency: sampling frequency divided by (M + 1) * 10 (bits 3:6) 311 1.1 jdc * i2c SCL is max 100kHz, so find the closest frequency at or below that. 312 1.1 jdc * 313 1.1 jdc * If the system (JBus) clock frequency changes, we must change our clock. 314 1.1 jdc * If increasing: after the JBus change, if decreasing: before the change. 315 1.1 jdc * This is to avoid running the i2c clock faster than the specification. 316 1.1 jdc */ 317 1.1 jdc static uint8_t 318 1.1 jdc firei2c_clock(int sysclk) 319 1.1 jdc { 320 1.1 jdc int p, f, best_p, best_f; 321 1.1 jdc uint32_t sample, scl; 322 1.1 jdc uint32_t min = FIREI2C_SCL_FREQ; 323 1.1 jdc uint8_t clkval; 324 1.1 jdc 325 1.1 jdc best_p = 0; 326 1.1 jdc best_f = 0; 327 1.1 jdc for (p = 0; p <= FIREI2C_CCR_POW2_MAX; p++) { 328 1.1 jdc if (p) 329 1.1 jdc sample = sysclk / (2 << (p - 1)); 330 1.1 jdc else 331 1.1 jdc sample = sysclk; 332 1.1 jdc for (f = 0; f <= FIREI2C_CCR_FACT_MAX; f++) { 333 1.1 jdc scl = sample / ((f + 1) * 10); 334 1.1 jdc if (scl <= FIREI2C_SCL_FREQ) { 335 1.1 jdc if (FIREI2C_SCL_FREQ - scl < min) { 336 1.1 jdc best_p = p; 337 1.1 jdc best_f = f; 338 1.1 jdc min = FIREI2C_SCL_FREQ - scl; 339 1.1 jdc } 340 1.1 jdc break; /* Already at or below SCL_FREQ */ 341 1.1 jdc } 342 1.1 jdc } 343 1.1 jdc if (!min) /* Exactly SCL_FREQ */ 344 1.1 jdc break; 345 1.1 jdc } 346 1.1 jdc clkval = best_p + (best_f << FIREI2C_CCR_FACT_SHIFT); 347 1.1 jdc return clkval; 348 1.1 jdc } 349 1.1 jdc 350 1.1 jdc /* No interrupts for stop, so wait for idle */ 351 1.1 jdc static int 352 1.1 jdc firei2c_stop(struct firei2c_softc *sc) 353 1.1 jdc { 354 1.1 jdc int i; 355 1.1 jdc uint8_t ctrl, val; 356 1.1 jdc 357 1.1 jdc ctrl = FIREI2C_CTRL_ENAB | FIREI2C_CTRL_STP; 358 1.1 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 359 1.1 jdc for (i = 0; i < 500; i++) { 360 1.1 jdc val = firei2c_reg_read(sc, FIREI2C_STAT); 361 1.5 jdc if (val == FIREI2C_STAT_IDLE) { 362 1.5 jdc mutex_enter(&sc->sc_mutex); 363 1.5 jdc sc->sc_stage = FIREI2C_STAGE_IDLE; 364 1.5 jdc mutex_exit(&sc->sc_mutex); 365 1.1 jdc return 0; 366 1.5 jdc } 367 1.1 jdc delay(1000); 368 1.1 jdc } 369 1.1 jdc /* Clear the interrupt flag if we timed out */ 370 1.1 jdc ctrl = FIREI2C_CTRL_ENAB; 371 1.1 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 372 1.5 jdc /* Set the stage to idle, even for timeout */ 373 1.5 jdc mutex_enter(&sc->sc_mutex); 374 1.5 jdc sc->sc_stage = FIREI2C_STAGE_IDLE; 375 1.5 jdc mutex_exit(&sc->sc_mutex); 376 1.1 jdc return 1; 377 1.1 jdc } 378 1.1 jdc 379 1.1 jdc 380 1.1 jdc static int 381 1.1 jdc firei2c_wait(struct firei2c_softc *sc, int flags) 382 1.1 jdc { 383 1.1 jdc volatile uint8_t ctrl; 384 1.1 jdc int i; 385 1.1 jdc 386 1.5 jdc for (i = 0; i < 500; i++) { 387 1.5 jdc ctrl = firei2c_reg_read(sc, FIREI2C_CTRL); 388 1.5 jdc if (ctrl & FIREI2C_CTRL_IFLG) 389 1.5 jdc return 0; 390 1.5 jdc delay(1000); 391 1.1 jdc } 392 1.5 jdc return 1; 393 1.1 jdc } 394 1.1 jdc 395 1.1 jdc /* 396 1.1 jdc * Flow for a "simple" read/write: 397 1.1 jdc * 1. Send start 398 1.1 jdc * 2. Send addr + R or W 399 1.1 jdc * 3. Receive ACK 400 1.1 jdc * 4. (nothing) 401 1.1 jdc * 5. (nothing) 402 1.1 jdc * 6R. Receive data 6W. Send data 403 1.1 jdc * 7R. Send ACK or NAK 7W. Receive ACK or NAK 404 1.1 jdc * either receive more (6R) or either write more (6W) or 405 1.1 jdc * 8. Send stop 406 1.5 jdc * 407 1.1 jdc * Flow for read/write following a "register" write: 408 1.1 jdc * 1. Send start 409 1.1 jdc * 2. Send addr + W 410 1.1 jdc * 3. Receive ACK 411 1.1 jdc * 4. Send register 412 1.1 jdc * 5R. Send repeat start + addr + R 5W. (nothing to do) 413 1.1 jdc * 6R. Receive data 6W. Send data 414 1.1 jdc * 7R. Send ACK or NAK 7W. Receive ACK or NAK 415 1.1 jdc * either receive more (6R) or either write more (6W) or 416 1.1 jdc * 8. Send stop 417 1.1 jdc * 418 1.1 jdc * After each step, we receive an interrupt notifying us of the result. 419 1.5 jdc * We clear the interrupt flag, check the status, and set up the next step. 420 1.5 jdc * If we're polling, we check the flag in a loop instead. 421 1.1 jdc */ 422 1.1 jdc int 423 1.1 jdc firei2c_exec(void *arg, i2c_op_t op, i2c_addr_t addr, const void *cmd, 424 1.1 jdc size_t cmdlen, void *vbuf, size_t buflen, int flags) 425 1.1 jdc { 426 1.1 jdc struct firei2c_softc *sc = arg; 427 1.5 jdc const uint8_t *cmdbuf = cmd; 428 1.1 jdc uint8_t *buf = vbuf; 429 1.1 jdc uint8_t ctrl, val, ack, nack; 430 1.5 jdc unsigned deadline, rem; 431 1.1 jdc int err; 432 1.1 jdc 433 1.5 jdc DPRINTF(1)("%s: exec op: %d addr: 0x%x " 434 1.5 jdc "cmdlen: %d buflen: %d flags 0x%x, intr %s, poll %s\n", 435 1.1 jdc device_xname(sc->sc_dev), op, addr, 436 1.5 jdc (int) cmdlen, (int) buflen, flags, 437 1.5 jdc sc->sc_inth == NULL ? "no" : "yes", 438 1.5 jdc flags & I2C_F_POLL ? "yes" : "no"); 439 1.1 jdc val = firei2c_reg_read(sc, FIREI2C_STAT); 440 1.1 jdc if (val != FIREI2C_STAT_IDLE) { 441 1.1 jdc /* Try sending stop */ 442 1.5 jdc DPRINTF(1)("%s: not idle, sending stop\n", 443 1.1 jdc device_xname(sc->sc_dev)); 444 1.1 jdc err = firei2c_stop(sc); 445 1.1 jdc if (err) { 446 1.1 jdc printf("%s: not idle (0x%02x)\n", 447 1.1 jdc device_xname(sc->sc_dev), val); 448 1.1 jdc return 1; 449 1.1 jdc } 450 1.1 jdc } 451 1.1 jdc 452 1.5 jdc /* Control defaults - bus enabled, interrupts enabled */ 453 1.5 jdc ctrl = FIREI2C_CTRL_ENAB; 454 1.5 jdc if (sc->sc_inth != NULL && !(flags & I2C_F_POLL)) { 455 1.5 jdc ctrl |= FIREI2C_CTRL_IEN; 456 1.5 jdc sc->sc_target = addr; 457 1.5 jdc sc->sc_cmdbuf = cmdbuf; 458 1.5 jdc sc->sc_cmdlen = cmdlen; 459 1.5 jdc sc->sc_buf = buf; 460 1.5 jdc sc->sc_buflen = buflen; 461 1.5 jdc sc->sc_i = 0; 462 1.5 jdc sc->sc_err = 0; 463 1.5 jdc if (I2C_OP_READ_P(op)) 464 1.5 jdc if (cmdlen > 0) 465 1.5 jdc sc->sc_op = FIREI2C_OP_WR_RD; 466 1.5 jdc else 467 1.5 jdc sc->sc_op = FIREI2C_OP_READ; 468 1.5 jdc else 469 1.5 jdc sc->sc_op = FIREI2C_OP_WRITE; 470 1.5 jdc mutex_enter(&sc->sc_mutex); 471 1.5 jdc sc->sc_stage = FIREI2C_STAGE_START; 472 1.5 jdc mutex_exit(&sc->sc_mutex); 473 1.5 jdc } 474 1.5 jdc 475 1.1 jdc /* Send start */ 476 1.5 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl | FIREI2C_CTRL_STA); 477 1.5 jdc 478 1.5 jdc /* Interrupt-driven */ 479 1.5 jdc if (sc->sc_inth != NULL && !(flags & I2C_F_POLL)) { 480 1.5 jdc /* Wait for the transfer to complete (stop). */ 481 1.5 jdc deadline = getticks() + 482 1.5 jdc /*timeout*/ hz / 10 + 10 * (cmdlen + buflen); 483 1.5 jdc mutex_enter(&sc->sc_mutex); 484 1.5 jdc while (sc->sc_stage != FIREI2C_STAGE_STOP) { 485 1.5 jdc rem = deadline - getticks(); 486 1.5 jdc if (!rem || rem >= INT_MAX) { 487 1.5 jdc printf("%s: intr timeout\n", 488 1.5 jdc device_xname(sc->sc_dev)); 489 1.5 jdc sc->sc_stage = FIREI2C_STAGE_STOP; 490 1.5 jdc err = sc->sc_err | 1; 491 1.5 jdc break; 492 1.5 jdc } 493 1.5 jdc cv_timedwait(&sc->sc_cv, &sc->sc_mutex, rem); 494 1.5 jdc } 495 1.5 jdc mutex_exit(&sc->sc_mutex); 496 1.5 jdc err = sc->sc_err; 497 1.5 jdc goto stop; 498 1.5 jdc } 499 1.5 jdc 500 1.5 jdc /* 501 1.5 jdc * If we are writing, write addr, cmd, buf. 502 1.5 jdc * If we are reading, either: 503 1.5 jdc * write addr, cmd, repeat-start, then read addr to buf, or: 504 1.5 jdc * read addr to buf. 505 1.5 jdc * Send stop 506 1.5 jdc */ 507 1.1 jdc err = firei2c_wait(sc, flags); 508 1.1 jdc val = firei2c_reg_read(sc, FIREI2C_STAT); 509 1.1 jdc if (err) { 510 1.1 jdc printf("%s: start timeout 0x%x\n", 511 1.1 jdc device_xname(sc->sc_dev), val); 512 1.1 jdc goto stop; 513 1.1 jdc } 514 1.1 jdc if (val != FIREI2C_STAT_STA) { 515 1.1 jdc printf("%s: start error 0x%x\n", 516 1.1 jdc device_xname(sc->sc_dev), val); 517 1.1 jdc err = 1; 518 1.1 jdc goto stop; 519 1.1 jdc } 520 1.1 jdc 521 1.5 jdc /* Address + r/w in data, then send ctrl */ 522 1.5 jdc val = addr << FIREI2C_DATA_SHIFT; 523 1.1 jdc if (I2C_OP_WRITE_P(op) || cmdlen > 0) { 524 1.1 jdc ack = FIREI2C_STAT_AWR_ACK; 525 1.1 jdc nack = FIREI2C_STAT_AWR_NAK; 526 1.1 jdc } else { 527 1.1 jdc val |= 0x01; 528 1.1 jdc ack = FIREI2C_STAT_ARE_ACK; 529 1.1 jdc nack = FIREI2C_STAT_ARE_NAK; 530 1.1 jdc } 531 1.1 jdc firei2c_reg_write(sc, FIREI2C_DATA, val); 532 1.1 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 533 1.1 jdc err = firei2c_wait(sc, flags); 534 1.1 jdc val = firei2c_reg_read(sc, FIREI2C_STAT); 535 1.1 jdc if (err) { 536 1.1 jdc printf("%s: addr timeout 0x%x\n", 537 1.1 jdc device_xname(sc->sc_dev), val); 538 1.1 jdc goto stop; 539 1.1 jdc } 540 1.1 jdc if (val != ack) { 541 1.1 jdc if (val != nack) /* Don't print for NACK */ 542 1.1 jdc printf("%s: addr error 0x%x\n", 543 1.1 jdc device_xname(sc->sc_dev), val); 544 1.1 jdc err = 1; 545 1.1 jdc goto stop; 546 1.1 jdc } 547 1.1 jdc 548 1.1 jdc err = 0; 549 1.1 jdc if (I2C_OP_READ_P(op)) { 550 1.1 jdc if (cmdlen > 0) { 551 1.1 jdc /* Write register */ 552 1.1 jdc err = firei2c_write(sc, cmd, cmdlen, 553 1.5 jdc NULL, 0, flags); 554 1.1 jdc if (err) 555 1.1 jdc goto stop; 556 1.1 jdc 557 1.1 jdc /* Send repeat start */ 558 1.5 jdc firei2c_reg_write(sc, FIREI2C_CTRL, 559 1.5 jdc ctrl | FIREI2C_CTRL_STA); 560 1.1 jdc err = firei2c_wait(sc, flags); 561 1.1 jdc val = firei2c_reg_read(sc, FIREI2C_STAT); 562 1.1 jdc if (err) { 563 1.1 jdc printf("%s: repeat start timeout 0x%x\n", 564 1.1 jdc device_xname(sc->sc_dev), val); 565 1.1 jdc goto stop; 566 1.1 jdc } 567 1.1 jdc if (val != FIREI2C_STAT_REPSTA) { 568 1.1 jdc printf("%s: repeat start error 0x%x\n", 569 1.1 jdc device_xname(sc->sc_dev), val); 570 1.1 jdc err = 1; 571 1.1 jdc goto stop; 572 1.1 jdc } 573 1.1 jdc 574 1.5 jdc /* Address + r in data, then send ctrl */ 575 1.5 jdc val = addr << FIREI2C_DATA_SHIFT; 576 1.1 jdc val |= 0x01; 577 1.1 jdc ack = FIREI2C_STAT_ARE_ACK; 578 1.1 jdc nack = FIREI2C_STAT_ARE_NAK; 579 1.1 jdc firei2c_reg_write(sc, FIREI2C_DATA, val); 580 1.1 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 581 1.1 jdc err = firei2c_wait(sc, flags); 582 1.1 jdc val = firei2c_reg_read(sc, FIREI2C_STAT); 583 1.1 jdc if (err) { 584 1.1 jdc printf("%s: addr timeout 0x%x\n", 585 1.1 jdc device_xname(sc->sc_dev), val); 586 1.1 jdc goto stop; 587 1.1 jdc } 588 1.1 jdc if (val != ack) { 589 1.1 jdc if (val != nack) 590 1.1 jdc printf("%s: addr error 0x%x\n", 591 1.1 jdc device_xname(sc->sc_dev), val); 592 1.1 jdc err = 1; 593 1.1 jdc goto stop; 594 1.1 jdc } 595 1.1 jdc } 596 1.1 jdc 597 1.1 jdc /* Read data */ 598 1.5 jdc err = firei2c_read(sc, buf, buflen, flags); 599 1.1 jdc } else 600 1.1 jdc /* Write data or register + data */ 601 1.5 jdc err = firei2c_write(sc, cmd, cmdlen, buf, buflen, flags); 602 1.1 jdc 603 1.1 jdc stop: 604 1.1 jdc err |= firei2c_stop(sc); 605 1.1 jdc 606 1.1 jdc return err; 607 1.1 jdc } 608 1.1 jdc 609 1.1 jdc static int 610 1.1 jdc firei2c_write(struct firei2c_softc *sc, const uint8_t *cmd, size_t cmdlen, 611 1.5 jdc uint8_t *buf, size_t buflen, int flags) 612 1.1 jdc { 613 1.5 jdc uint8_t ctrl, val; 614 1.1 jdc int i, err; 615 1.1 jdc 616 1.5 jdc DPRINTF(2)("%s: write %ld\n", 617 1.5 jdc device_xname(sc->sc_dev), cmdlen + buflen); 618 1.5 jdc ctrl = FIREI2C_CTRL_ENAB; 619 1.1 jdc for (i = 0; i < cmdlen + buflen; i++) { 620 1.5 jdc /* Bytes in data, then send ctrl */ 621 1.1 jdc if (i < cmdlen) 622 1.1 jdc val = cmd[i]; 623 1.1 jdc else 624 1.1 jdc val = buf[i - cmdlen]; 625 1.1 jdc firei2c_reg_write(sc, FIREI2C_DATA, val); 626 1.1 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 627 1.1 jdc err = firei2c_wait(sc, flags); 628 1.1 jdc val = firei2c_reg_read(sc, FIREI2C_STAT); 629 1.1 jdc if (err) { 630 1.1 jdc printf("%s: write timeout 0x%x\n", 631 1.1 jdc device_xname(sc->sc_dev), val); 632 1.1 jdc return 1; 633 1.1 jdc } 634 1.1 jdc if (val != FIREI2C_STAT_DAT_ACK) { 635 1.1 jdc if (val != FIREI2C_STAT_DAT_NAK) 636 1.1 jdc printf("%s: write error 0x%x\n", 637 1.1 jdc device_xname(sc->sc_dev), val); 638 1.1 jdc return 1; 639 1.1 jdc } 640 1.1 jdc 641 1.1 jdc } 642 1.1 jdc return 0; 643 1.1 jdc } 644 1.1 jdc 645 1.1 jdc static int 646 1.5 jdc firei2c_read(struct firei2c_softc *sc, uint8_t *buf, size_t buflen, int flags) 647 1.1 jdc { 648 1.5 jdc uint8_t ctrl, val, ack; 649 1.1 jdc int i, err; 650 1.1 jdc 651 1.5 jdc DPRINTF(2)("%s: read %ld\n", device_xname(sc->sc_dev), buflen); 652 1.1 jdc for (i = 0; i < buflen; i++) { 653 1.1 jdc /* Send ACK on all but last byte */ 654 1.1 jdc if (i < buflen - 1) { 655 1.5 jdc ctrl = FIREI2C_CTRL_ENAB | FIREI2C_CTRL_AAK; 656 1.1 jdc ack = FIREI2C_STAT_MDAT_ACK; 657 1.1 jdc } else { 658 1.5 jdc ctrl = FIREI2C_CTRL_ENAB; 659 1.1 jdc ack = FIREI2C_STAT_MDAT_NAK; 660 1.1 jdc } 661 1.5 jdc /* Send ctrl, then bytes in data */ 662 1.5 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 663 1.1 jdc err = firei2c_wait(sc, flags); 664 1.1 jdc val = firei2c_reg_read(sc, FIREI2C_STAT); 665 1.1 jdc if (err) { 666 1.1 jdc printf("%s: read timeout 0x%x\n", 667 1.1 jdc device_xname(sc->sc_dev), val); 668 1.1 jdc return 1; 669 1.1 jdc } 670 1.1 jdc if (val != ack) { 671 1.1 jdc printf("%s: read error 0x%x\n", 672 1.1 jdc device_xname(sc->sc_dev), val); 673 1.1 jdc return 1; 674 1.1 jdc } 675 1.1 jdc buf[i] = firei2c_reg_read(sc, FIREI2C_DATA); 676 1.1 jdc } 677 1.1 jdc return 0; 678 1.1 jdc } 679 1.1 jdc 680 1.5 jdc /* 681 1.5 jdc * When we receive an interrupt, check the status versus the step 682 1.5 jdc * and set up the next stage. 683 1.5 jdc * See the comments before firei2c_exec() for the list of steps. 684 1.5 jdc */ 685 1.1 jdc int 686 1.1 jdc firei2c_intr(void *arg) 687 1.1 jdc { 688 1.1 jdc struct firei2c_softc *sc = arg; 689 1.5 jdc uint8_t ctrl, val; 690 1.1 jdc 691 1.1 jdc mutex_enter(&sc->sc_mutex); 692 1.1 jdc ctrl = firei2c_reg_read(sc, FIREI2C_CTRL); 693 1.1 jdc if (ctrl & FIREI2C_CTRL_IFLG) { 694 1.1 jdc /* Disable interrupts */ 695 1.1 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl & ~FIREI2C_CTRL_IEN); 696 1.5 jdc } 697 1.5 jdc 698 1.5 jdc if (sc->sc_stage == FIREI2C_STAGE_IDLE) { 699 1.5 jdc DPRINTF(1)("%s: intr and idle\n", device_xname(sc->sc_dev)); 700 1.5 jdc mutex_exit(&sc->sc_mutex); 701 1.5 jdc return 0; 702 1.5 jdc } 703 1.5 jdc 704 1.5 jdc ctrl = FIREI2C_CTRL_ENAB | FIREI2C_CTRL_IEN; 705 1.5 jdc val = firei2c_reg_read(sc, FIREI2C_STAT); 706 1.5 jdc 707 1.5 jdc switch (sc->sc_stage) { 708 1.5 jdc case FIREI2C_STAGE_START: 709 1.5 jdc DPRINTF(2)("%s: intr start, op %x\n", 710 1.5 jdc device_xname(sc->sc_dev), sc->sc_op); 711 1.5 jdc if (val != FIREI2C_STAT_STA) { 712 1.5 jdc printf("%s: intr start error 0x%02x\n", 713 1.5 jdc device_xname(sc->sc_dev), val); 714 1.5 jdc sc->sc_err = 1; 715 1.5 jdc sc->sc_stage = FIREI2C_STAGE_STOP; 716 1.5 jdc break; 717 1.5 jdc } 718 1.5 jdc 719 1.5 jdc /* Address + r/w in data, then send ctrl */ 720 1.5 jdc val = sc->sc_target << FIREI2C_DATA_SHIFT; 721 1.5 jdc if (sc->sc_op == FIREI2C_OP_READ) { 722 1.5 jdc val |= 0x01; 723 1.5 jdc sc->sc_stage = FIREI2C_STAGE_RE_ADDR; 724 1.5 jdc } else 725 1.5 jdc sc->sc_stage = FIREI2C_STAGE_WR_ADDR; 726 1.5 jdc firei2c_reg_write(sc, FIREI2C_DATA, val); 727 1.5 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 728 1.5 jdc break; 729 1.5 jdc 730 1.5 jdc case FIREI2C_STAGE_WR_ADDR: 731 1.5 jdc DPRINTF(2)("%s: intr addr(w) 0x%02x = 0x%02x\n", 732 1.5 jdc device_xname(sc->sc_dev), sc->sc_target, val); 733 1.5 jdc if (val != FIREI2C_STAT_AWR_ACK) { 734 1.5 jdc if (val != FIREI2C_STAT_AWR_NAK) 735 1.5 jdc printf("%s: intr addr(w) error 0x%02x\n", 736 1.5 jdc device_xname(sc->sc_dev), val); 737 1.5 jdc sc->sc_err = 1; 738 1.5 jdc sc->sc_stage = FIREI2C_STAGE_STOP; 739 1.5 jdc break; 740 1.5 jdc } 741 1.5 jdc 742 1.5 jdc sc->sc_stage = FIREI2C_STAGE_WRITE; 743 1.5 jdc val = FIREI2C_STAT_DAT_ACK; /* For write */ 744 1.5 jdc /* Fallthrough */ 745 1.5 jdc 746 1.5 jdc case FIREI2C_STAGE_WRITE: 747 1.5 jdc DPRINTF(2)("%s: intr write 0x%02x = 0x%02x\n", 748 1.5 jdc device_xname(sc->sc_dev), sc->sc_target, val); 749 1.5 jdc if (val != FIREI2C_STAT_DAT_ACK) { 750 1.5 jdc if (val != FIREI2C_STAT_DAT_NAK) 751 1.5 jdc printf("%s: intr write error 0x%02x\n", 752 1.5 jdc device_xname(sc->sc_dev), val); 753 1.5 jdc sc->sc_err = 1; 754 1.5 jdc sc->sc_stage = FIREI2C_STAGE_STOP; 755 1.5 jdc break; 756 1.5 jdc } 757 1.5 jdc 758 1.5 jdc /* Start the write from cmd */ 759 1.5 jdc if (sc->sc_i < sc->sc_cmdlen) { 760 1.5 jdc firei2c_reg_write(sc, FIREI2C_DATA, 761 1.5 jdc sc->sc_cmdbuf[sc->sc_i]); 762 1.5 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 763 1.5 jdc sc->sc_i++; 764 1.5 jdc break; 765 1.5 jdc } 766 1.5 jdc 767 1.5 jdc /* If a read OP, switch with repeat start after writing cmd */ 768 1.5 jdc if (sc->sc_op == FIREI2C_OP_WR_RD) { 769 1.5 jdc sc->sc_i = 0; 770 1.5 jdc sc->sc_stage = FIREI2C_STAGE_REPSTART; 771 1.5 jdc ctrl |= FIREI2C_CTRL_STA; 772 1.5 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 773 1.5 jdc break; 774 1.5 jdc } 775 1.5 jdc 776 1.5 jdc /* If a write OP, continue the write, now from buf */ 777 1.5 jdc if (sc->sc_i < sc->sc_cmdlen + sc->sc_buflen) { 778 1.5 jdc firei2c_reg_write(sc, FIREI2C_DATA, 779 1.5 jdc sc->sc_buf[sc->sc_i - sc->sc_cmdlen]); 780 1.5 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 781 1.5 jdc sc->sc_i++; 782 1.5 jdc } else { 783 1.5 jdc sc->sc_stage = FIREI2C_STAGE_STOP; 784 1.5 jdc } 785 1.5 jdc break; 786 1.5 jdc 787 1.5 jdc case FIREI2C_STAGE_REPSTART: 788 1.5 jdc DPRINTF(2)("%s: intr repstart 0x%02x = 0x%02x\n", 789 1.5 jdc device_xname(sc->sc_dev), sc->sc_target, val); 790 1.5 jdc if (val != FIREI2C_STAT_REPSTA) { 791 1.5 jdc printf("%s: intr repstart error 0x%02x\n", 792 1.5 jdc device_xname(sc->sc_dev), val); 793 1.5 jdc sc->sc_err = 1; 794 1.5 jdc sc->sc_stage = FIREI2C_STAGE_STOP; 795 1.5 jdc break; 796 1.5 jdc } 797 1.5 jdc 798 1.5 jdc /* Address + r in data, then send ctrl */ 799 1.5 jdc val = (sc->sc_target << FIREI2C_DATA_SHIFT) | 0x01; 800 1.5 jdc sc->sc_stage = FIREI2C_STAGE_RE_ADDR; 801 1.5 jdc firei2c_reg_write(sc, FIREI2C_DATA, val); 802 1.5 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 803 1.5 jdc break; 804 1.5 jdc 805 1.5 jdc case FIREI2C_STAGE_RE_ADDR: 806 1.5 jdc DPRINTF(2)("%s: intr addr(r) 0x%02x = 0x%02x\n", 807 1.5 jdc device_xname(sc->sc_dev), sc->sc_target, val); 808 1.5 jdc if (val != FIREI2C_STAT_ARE_ACK) { 809 1.5 jdc if (val != FIREI2C_STAT_ARE_NAK) 810 1.5 jdc printf("%s: intr addr(r) error 0x%02x\n", 811 1.5 jdc device_xname(sc->sc_dev), val); 812 1.5 jdc sc->sc_err = 1; 813 1.5 jdc sc->sc_stage = FIREI2C_STAGE_STOP; 814 1.5 jdc break; 815 1.5 jdc } 816 1.5 jdc 817 1.5 jdc sc->sc_stage = FIREI2C_STAGE_READ; 818 1.5 jdc val = FIREI2C_STAT_MDAT_NAK; /* For read */ 819 1.5 jdc /* Fallthrough */ 820 1.5 jdc 821 1.5 jdc case FIREI2C_STAGE_READ: 822 1.5 jdc DPRINTF(2)("%s: intr read 0x%02x = 0x%02x\n", 823 1.5 jdc device_xname(sc->sc_dev), sc->sc_target, val); 824 1.5 jdc if (sc->sc_i > 0 && sc->sc_i < sc->sc_buflen) { 825 1.5 jdc if (val != FIREI2C_STAT_MDAT_ACK) { 826 1.5 jdc printf("%s: intr read error 0x%02x\n", 827 1.5 jdc device_xname(sc->sc_dev), val); 828 1.5 jdc sc->sc_err = 1; 829 1.5 jdc sc->sc_stage = FIREI2C_STAGE_STOP; 830 1.5 jdc break; 831 1.5 jdc } 832 1.5 jdc } else { 833 1.5 jdc if (val != FIREI2C_STAT_MDAT_NAK) { 834 1.5 jdc printf("%s: intr read error 0x%02x\n", 835 1.5 jdc device_xname(sc->sc_dev), val); 836 1.5 jdc sc->sc_err = 1; 837 1.5 jdc sc->sc_stage = FIREI2C_STAGE_STOP; 838 1.5 jdc break; 839 1.5 jdc } 840 1.5 jdc } 841 1.5 jdc 842 1.5 jdc /* Data read is 1 cycle behind ctrl */ 843 1.5 jdc if (sc->sc_i > 0 && sc->sc_i <= sc->sc_buflen) { 844 1.5 jdc sc->sc_buf[sc->sc_i - 1] = 845 1.5 jdc firei2c_reg_read(sc, FIREI2C_DATA); 846 1.5 jdc } 847 1.5 jdc 848 1.5 jdc if (sc->sc_i == sc->sc_buflen) { 849 1.5 jdc /* Last data was read */ 850 1.5 jdc sc->sc_stage = FIREI2C_STAGE_STOP; 851 1.5 jdc } else { 852 1.5 jdc /* Send ACK on all but last byte */ 853 1.5 jdc if (sc->sc_i < sc->sc_buflen - 1) 854 1.5 jdc ctrl |= FIREI2C_CTRL_AAK; 855 1.5 jdc firei2c_reg_write(sc, FIREI2C_CTRL, ctrl); 856 1.5 jdc sc->sc_i++; 857 1.5 jdc } 858 1.5 jdc break; 859 1.5 jdc } 860 1.5 jdc 861 1.5 jdc if (sc->sc_stage == FIREI2C_STAGE_STOP) { 862 1.5 jdc DPRINTF(2)("%s: intr stop (err=%d)\n", 863 1.5 jdc device_xname(sc->sc_dev), sc->sc_err); 864 1.1 jdc cv_signal(&sc->sc_cv); 865 1.1 jdc } 866 1.5 jdc 867 1.1 jdc mutex_exit(&sc->sc_mutex); 868 1.5 jdc 869 1.5 jdc return 1; 870 1.5 jdc 871 1.1 jdc } 872 1.1 jdc 873 1.1 jdc static uint8_t 874 1.1 jdc firei2c_reg_read(struct firei2c_softc *sc, bus_size_t reg) 875 1.1 jdc { 876 1.1 jdc uint32_t val; 877 1.1 jdc bus_space_barrier(sc->sc_bustag, sc->sc_regh, reg, 8, 878 1.1 jdc BUS_SPACE_BARRIER_READ); 879 1.1 jdc val = bus_space_read_8(sc->sc_bustag, sc->sc_regh, reg); 880 1.1 jdc return val & 0xff; 881 1.1 jdc } 882 1.1 jdc 883 1.1 jdc static void 884 1.1 jdc firei2c_reg_write(struct firei2c_softc *sc, bus_size_t reg, uint8_t val) 885 1.1 jdc { 886 1.1 jdc bus_space_write_8(sc->sc_bustag, sc->sc_regh, reg, val); 887 1.1 jdc bus_space_barrier(sc->sc_bustag, sc->sc_regh, reg, 8, 888 1.1 jdc BUS_SPACE_BARRIER_WRITE); 889 1.1 jdc } 890