1/*- 2 * Copyright (c) 2018 Emmanuel Vadot <manu@FreeBSD.org> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 18 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 20 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * 25 * $FreeBSD$ 26 */ 27 28#include <sys/cdefs.h> 29__FBSDID("$FreeBSD$"); 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/bus.h> 34#include <sys/kernel.h> 35#include <sys/module.h> 36#include <sys/rman.h> 37#include <sys/resource.h> 38#include <machine/bus.h> 39 40#include <dev/ofw/ofw_bus.h> 41#include <dev/ofw/ofw_bus_subr.h> 42 43#include <dev/spibus/spi.h> 44#include <dev/spibus/spibusvar.h> 45 46#include <dev/extres/clk/clk.h> 47#include <dev/extres/hwreset/hwreset.h> 48 49#include "spibus_if.h" 50 51#define AW_SPI_GCR 0x04 /* Global Control Register */ 52#define AW_SPI_GCR_EN (1 << 0) /* ENable */ 53#define AW_SPI_GCR_MODE_MASTER (1 << 1) /* 1 = Master, 0 = Slave */ 54#define AW_SPI_GCR_TP_EN (1 << 7) /* 1 = Stop transmit when FIFO is full */ 55#define AW_SPI_GCR_SRST (1 << 31) /* Soft Reset */ 56 57#define AW_SPI_TCR 0x08 /* Transfer Control register */ 58#define AW_SPI_TCR_XCH (1 << 31) /* Initiate transfer */ 59#define AW_SPI_TCR_SDDM (1 << 14) /* Sending Delay Data Mode */ 60#define AW_SPI_TCR_SDM (1 << 13) /* Master Sample Data Mode */ 61#define AW_SPI_TCR_FBS (1 << 12) /* First Transmit Bit Select (1 == LSB) */ 62#define AW_SPI_TCR_SDC (1 << 11) /* Master Sample Data Control */ 63#define AW_SPI_TCR_RPSM (1 << 10) /* Rapid Mode Select */ 64#define AW_SPI_TCR_DDB (1 << 9) /* Dummy Burst Type */ 65#define AW_SPI_TCR_SSSEL_MASK 0x30 /* Chip select */ 66#define AW_SPI_TCR_SSSEL_SHIFT 4 67#define AW_SPI_TCR_SS_LEVEL (1 << 7) /* 1 == CS High */ 68#define AW_SPI_TCR_SS_OWNER (1 << 6) /* 1 == Software controlled */ 69#define AW_SPI_TCR_SPOL (1 << 2) /* 1 == Active low */ 70#define AW_SPI_TCR_CPOL (1 << 1) /* 1 == Active low */ 71#define AW_SPI_TCR_CPHA (1 << 0) /* 1 == Phase 1 */ 72 73#define AW_SPI_IER 0x10 /* Interrupt Control Register */ 74#define AW_SPI_IER_SS (1 << 13) /* Chip select went from valid to invalid */ 75#define AW_SPI_IER_TC (1 << 12) /* Transfer complete */ 76#define AW_SPI_IER_TF_UDR (1 << 11) /* TXFIFO underrun */ 77#define AW_SPI_IER_TF_OVF (1 << 10) /* TXFIFO overrun */ 78#define AW_SPI_IER_RF_UDR (1 << 9) /* RXFIFO underrun */ 79#define AW_SPI_IER_RF_OVF (1 << 8) /* RXFIFO overrun */ 80#define AW_SPI_IER_TF_FULL (1 << 6) /* TXFIFO Full */ 81#define AW_SPI_IER_TF_EMP (1 << 5) /* TXFIFO Empty */ 82#define AW_SPI_IER_TF_ERQ (1 << 4) /* TXFIFO Empty Request */ 83#define AW_SPI_IER_RF_FULL (1 << 2) /* RXFIFO Full */ 84#define AW_SPI_IER_RF_EMP (1 << 1) /* RXFIFO Empty */ 85#define AW_SPI_IER_RF_ERQ (1 << 0) /* RXFIFO Empty Request */ 86 87#define AW_SPI_ISR 0x14 /* Interrupt Status Register */ 88 89#define AW_SPI_FCR 0x18 /* FIFO Control Register */ 90#define AW_SPI_FCR_TX_RST (1 << 31) /* Reset TX FIFO */ 91#define AW_SPI_FCR_TX_TRIG_MASK 0xFF0000 /* TX FIFO Trigger level */ 92#define AW_SPI_FCR_TX_TRIG_SHIFT 16 93#define AW_SPI_FCR_RX_RST (1 << 15) /* Reset RX FIFO */ 94#define AW_SPI_FCR_RX_TRIG_MASK 0xFF /* RX FIFO Trigger level */ 95#define AW_SPI_FCR_RX_TRIG_SHIFT 0 96 97#define AW_SPI_FSR 0x1C /* FIFO Status Register */ 98#define AW_SPI_FSR_TB_WR (1 << 31) 99#define AW_SPI_FSR_TB_CNT_MASK 0x70000000 100#define AW_SPI_FSR_TB_CNT_SHIFT 28 101#define AW_SPI_FSR_TF_CNT_MASK 0xFF0000 102#define AW_SPI_FSR_TF_CNT_SHIFT 16 103#define AW_SPI_FSR_RB_WR (1 << 15) 104#define AW_SPI_FSR_RB_CNT_MASK 0x7000 105#define AW_SPI_FSR_RB_CNT_SHIFT 12 106#define AW_SPI_FSR_RF_CNT_MASK 0xFF 107#define AW_SPI_FSR_RF_CNT_SHIFT 0 108 109#define AW_SPI_WCR 0x20 /* Wait Clock Counter Register */ 110 111#define AW_SPI_CCR 0x24 /* Clock Rate Control Register */ 112#define AW_SPI_CCR_DRS (1 << 12) /* Clock divider select */ 113#define AW_SPI_CCR_CDR1_MASK 0xF00 114#define AW_SPI_CCR_CDR1_SHIFT 8 115#define AW_SPI_CCR_CDR2_MASK 0xFF 116#define AW_SPI_CCR_CDR2_SHIFT 0 117 118#define AW_SPI_MBC 0x30 /* Burst Counter Register */ 119#define AW_SPI_MTC 0x34 /* Transmit Counter Register */ 120#define AW_SPI_BCC 0x38 /* Burst Control Register */ 121#define AW_SPI_MDMA_CTL 0x88 /* Normal DMA Control Register */ 122#define AW_SPI_TXD 0x200 /* TX Data Register */ 123#define AW_SPI_RDX 0x300 /* RX Data Register */ 124 125#define AW_SPI_MAX_CS 4 126#define AW_SPI_FIFO_SIZE 64 127 128static struct ofw_compat_data compat_data[] = { 129 { "allwinner,sun8i-h3-spi", 1 }, 130 { NULL, 0 } 131}; 132 133static struct resource_spec aw_spi_spec[] = { 134 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 135 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 136 { -1, 0 } 137}; 138 139struct aw_spi_softc { 140 device_t dev; 141 device_t spibus; 142 struct resource *res[2]; 143 struct mtx mtx; 144 clk_t clk_ahb; 145 clk_t clk_mod; 146 uint64_t mod_freq; 147 hwreset_t rst_ahb; 148 void * intrhand; 149 int transfer; 150 151 uint8_t *rxbuf; 152 uint32_t rxcnt; 153 uint8_t *txbuf; 154 uint32_t txcnt; 155 uint32_t txlen; 156 uint32_t rxlen; 157}; 158 159#define AW_SPI_LOCK(sc) mtx_lock(&(sc)->mtx) 160#define AW_SPI_UNLOCK(sc) mtx_unlock(&(sc)->mtx) 161#define AW_SPI_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED) 162#define AW_SPI_READ_1(sc, reg) bus_read_1((sc)->res[0], (reg)) 163#define AW_SPI_WRITE_1(sc, reg, val) bus_write_1((sc)->res[0], (reg), (val)) 164#define AW_SPI_READ_4(sc, reg) bus_read_4((sc)->res[0], (reg)) 165#define AW_SPI_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val)) 166 167static int aw_spi_probe(device_t dev); 168static int aw_spi_attach(device_t dev); 169static int aw_spi_detach(device_t dev); 170static void aw_spi_intr(void *arg); 171 172static int 173aw_spi_probe(device_t dev) 174{ 175 if (!ofw_bus_status_okay(dev)) 176 return (ENXIO); 177 178 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) 179 return (ENXIO); 180 181 device_set_desc(dev, "Allwinner SPI"); 182 return (BUS_PROBE_DEFAULT); 183} 184 185static int 186aw_spi_attach(device_t dev) 187{ 188 struct aw_spi_softc *sc; 189 int error; 190 191 sc = device_get_softc(dev); 192 sc->dev = dev; 193 194 mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); 195 196 if (bus_alloc_resources(dev, aw_spi_spec, sc->res) != 0) { 197 device_printf(dev, "cannot allocate resources for device\n"); 198 error = ENXIO; 199 goto fail; 200 } 201 202 if (bus_setup_intr(dev, sc->res[1], 203 INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_spi_intr, sc, 204 &sc->intrhand)) { 205 bus_release_resources(dev, aw_spi_spec, sc->res); 206 device_printf(dev, "cannot setup interrupt handler\n"); 207 return (ENXIO); 208 } 209 210 /* De-assert reset */ 211 if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst_ahb) == 0) { 212 error = hwreset_deassert(sc->rst_ahb); 213 if (error != 0) { 214 device_printf(dev, "cannot de-assert reset\n"); 215 goto fail; 216 } 217 } 218 219 /* Activate the module clock. */ 220 error = clk_get_by_ofw_name(dev, 0, "ahb", &sc->clk_ahb); 221 if (error != 0) { 222 device_printf(dev, "cannot get ahb clock\n"); 223 goto fail; 224 } 225 error = clk_get_by_ofw_name(dev, 0, "mod", &sc->clk_mod); 226 if (error != 0) { 227 device_printf(dev, "cannot get mod clock\n"); 228 goto fail; 229 } 230 error = clk_enable(sc->clk_ahb); 231 if (error != 0) { 232 device_printf(dev, "cannot enable ahb clock\n"); 233 goto fail; 234 } 235 error = clk_enable(sc->clk_mod); 236 if (error != 0) { 237 device_printf(dev, "cannot enable mod clock\n"); 238 goto fail; 239 } 240 241 sc->spibus = device_add_child(dev, "spibus", -1); 242 243 return (bus_generic_attach(dev)); 244 245fail: 246 aw_spi_detach(dev); 247 return (error); 248} 249 250static int 251aw_spi_detach(device_t dev) 252{ 253 struct aw_spi_softc *sc; 254 255 sc = device_get_softc(dev); 256 257 bus_generic_detach(sc->dev); 258 if (sc->spibus != NULL) 259 device_delete_child(dev, sc->spibus); 260 261 if (sc->clk_mod != NULL) 262 clk_release(sc->clk_mod); 263 if (sc->clk_ahb) 264 clk_release(sc->clk_ahb); 265 if (sc->rst_ahb) 266 hwreset_assert(sc->rst_ahb); 267 268 if (sc->intrhand != NULL) 269 bus_teardown_intr(sc->dev, sc->res[1], sc->intrhand); 270 271 bus_release_resources(dev, aw_spi_spec, sc->res); 272 mtx_destroy(&sc->mtx); 273 274 return (0); 275} 276 277static phandle_t 278aw_spi_get_node(device_t bus, device_t dev) 279{ 280 281 return ofw_bus_get_node(bus); 282} 283 284static void 285aw_spi_setup_mode(struct aw_spi_softc *sc, uint32_t mode) 286{ 287 uint32_t reg; 288 289 /* We only support master mode */ 290 reg = AW_SPI_READ_4(sc, AW_SPI_GCR); 291 reg |= AW_SPI_GCR_MODE_MASTER; 292 AW_SPI_WRITE_4(sc, AW_SPI_GCR, reg); 293 294 /* Setup the modes */ 295 reg = AW_SPI_READ_4(sc, AW_SPI_TCR); 296 if (mode & SPIBUS_MODE_CPHA) 297 reg |= AW_SPI_TCR_CPHA; 298 if (mode & SPIBUS_MODE_CPOL) 299 reg |= AW_SPI_TCR_CPOL; 300 301 AW_SPI_WRITE_4(sc, AW_SPI_TCR, reg); 302} 303 304static void 305aw_spi_setup_cs(struct aw_spi_softc *sc, uint32_t cs, bool low) 306{ 307 uint32_t reg; 308 309 /* Setup CS */ 310 reg = AW_SPI_READ_4(sc, AW_SPI_TCR); 311 reg &= ~(AW_SPI_TCR_SSSEL_MASK); 312 reg |= cs << AW_SPI_TCR_SSSEL_SHIFT; 313 reg |= AW_SPI_TCR_SS_OWNER; 314 if (low) 315 reg &= ~(AW_SPI_TCR_SS_LEVEL); 316 else 317 reg |= AW_SPI_TCR_SS_LEVEL; 318 319 AW_SPI_WRITE_4(sc, AW_SPI_TCR, reg); 320} 321 322static uint64_t 323aw_spi_clock_test_cdr1(struct aw_spi_softc *sc, uint64_t clock, uint32_t *ccr) 324{ 325 uint64_t cur, best = 0; 326 int i, max, best_div; 327 328 max = AW_SPI_CCR_CDR1_MASK >> AW_SPI_CCR_CDR1_SHIFT; 329 for (i = 0; i < max; i++) { 330 cur = sc->mod_freq / (1 << i); 331 if ((clock - cur) < (clock - best)) { 332 best = cur; 333 best_div = i; 334 } 335 } 336 337 *ccr = (best_div << AW_SPI_CCR_CDR1_SHIFT); 338 return (best); 339} 340 341static uint64_t 342aw_spi_clock_test_cdr2(struct aw_spi_softc *sc, uint64_t clock, uint32_t *ccr) 343{ 344 uint64_t cur, best = 0; 345 int i, max, best_div; 346 347 max = ((AW_SPI_CCR_CDR2_MASK) >> AW_SPI_CCR_CDR2_SHIFT); 348 for (i = 0; i < max; i++) { 349 cur = sc->mod_freq / (2 * i + 1); 350 if ((clock - cur) < (clock - best)) { 351 best = cur; 352 best_div = i; 353 } 354 } 355 356 *ccr = AW_SPI_CCR_DRS | (best_div << AW_SPI_CCR_CDR2_SHIFT); 357 return (best); 358} 359 360static void 361aw_spi_setup_clock(struct aw_spi_softc *sc, uint64_t clock) 362{ 363 uint64_t best_ccr1, best_ccr2; 364 uint32_t ccr, ccr1, ccr2; 365 366 best_ccr1 = aw_spi_clock_test_cdr1(sc, clock, &ccr1); 367 best_ccr2 = aw_spi_clock_test_cdr2(sc, clock, &ccr2); 368 369 if (best_ccr1 == clock) { 370 ccr = ccr1; 371 } else if (best_ccr2 == clock) { 372 ccr = ccr2; 373 } else { 374 if ((clock - best_ccr1) < (clock - best_ccr2)) 375 ccr = ccr1; 376 else 377 ccr = ccr2; 378 } 379 380 AW_SPI_WRITE_4(sc, AW_SPI_CCR, ccr); 381} 382 383static inline void 384aw_spi_fill_txfifo(struct aw_spi_softc *sc) 385{ 386 uint32_t reg, txcnt; 387 int i; 388 389 if (sc->txcnt == sc->txlen) 390 return; 391 392 reg = AW_SPI_READ_4(sc, AW_SPI_FSR); 393 reg &= AW_SPI_FSR_TF_CNT_MASK; 394 txcnt = reg >> AW_SPI_FSR_TF_CNT_SHIFT; 395 396 for (i = 0; i < (AW_SPI_FIFO_SIZE - txcnt); i++) { 397 AW_SPI_WRITE_1(sc, AW_SPI_TXD, sc->txbuf[sc->txcnt++]); 398 if (sc->txcnt == sc->txlen) 399 break; 400 } 401 402 return; 403} 404 405static inline void 406aw_spi_read_rxfifo(struct aw_spi_softc *sc) 407{ 408 uint32_t reg; 409 uint8_t val; 410 int i; 411 412 if (sc->rxcnt == sc->rxlen) 413 return; 414 415 reg = AW_SPI_READ_4(sc, AW_SPI_FSR); 416 reg = (reg & AW_SPI_FSR_RF_CNT_MASK) >> AW_SPI_FSR_RF_CNT_SHIFT; 417 418 for (i = 0; i < reg; i++) { 419 val = AW_SPI_READ_1(sc, AW_SPI_RDX); 420 if (sc->rxcnt < sc->rxlen) 421 sc->rxbuf[sc->rxcnt++] = val; 422 } 423} 424 425static void 426aw_spi_intr(void *arg) 427{ 428 struct aw_spi_softc *sc; 429 uint32_t intr; 430 431 sc = (struct aw_spi_softc *)arg; 432 433 intr = AW_SPI_READ_4(sc, AW_SPI_ISR); 434 435 if (intr & AW_SPI_IER_RF_FULL) 436 aw_spi_read_rxfifo(sc); 437 438 if (intr & AW_SPI_IER_TF_EMP) { 439 aw_spi_fill_txfifo(sc); 440 /* 441 * If we don't have anything else to write 442 * disable TXFifo interrupts 443 */ 444 if (sc->txcnt == sc->txlen) 445 AW_SPI_WRITE_4(sc, AW_SPI_IER, AW_SPI_IER_TC | 446 AW_SPI_IER_RF_FULL); 447 } 448 449 if (intr & AW_SPI_IER_TC) { 450 /* read the rest of the data from the fifo */ 451 aw_spi_read_rxfifo(sc); 452 453 /* Disable the interrupts */ 454 AW_SPI_WRITE_4(sc, AW_SPI_IER, 0); 455 sc->transfer = 0; 456 wakeup(sc); 457 } 458 459 /* Clear Interrupts */ 460 AW_SPI_WRITE_4(sc, AW_SPI_ISR, intr); 461} 462 463static int 464aw_spi_xfer(struct aw_spi_softc *sc, void *rxbuf, void *txbuf, uint32_t txlen, uint32_t rxlen) 465{ 466 uint32_t reg; 467 int error = 0, timeout; 468 469 sc->rxbuf = rxbuf; 470 sc->rxcnt = 0; 471 sc->txbuf = txbuf; 472 sc->txcnt = 0; 473 sc->txlen = txlen; 474 sc->rxlen = rxlen; 475 476 /* Reset the FIFOs */ 477 AW_SPI_WRITE_4(sc, AW_SPI_FCR, AW_SPI_FCR_TX_RST | AW_SPI_FCR_RX_RST); 478 479 for (timeout = 1000; timeout > 0; timeout--) { 480 reg = AW_SPI_READ_4(sc, AW_SPI_FCR); 481 if (reg == 0) 482 break; 483 } 484 if (timeout == 0) { 485 device_printf(sc->dev, "Cannot reset the FIFOs\n"); 486 return (EIO); 487 } 488 489 /* Write the counters */ 490 AW_SPI_WRITE_4(sc, AW_SPI_MBC, txlen); 491 AW_SPI_WRITE_4(sc, AW_SPI_MTC, txlen); 492 AW_SPI_WRITE_4(sc, AW_SPI_BCC, txlen); 493 494 /* First fill */ 495 aw_spi_fill_txfifo(sc); 496 497 /* Start transmit */ 498 reg = AW_SPI_READ_4(sc, AW_SPI_TCR); 499 reg |= AW_SPI_TCR_XCH; 500 AW_SPI_WRITE_4(sc, AW_SPI_TCR, reg); 501 502 /* 503 * Enable interrupts for : 504 * Transmit complete 505 * TX Fifo empty 506 * RX Fifo full 507 */ 508 AW_SPI_WRITE_4(sc, AW_SPI_IER, AW_SPI_IER_TC | 509 AW_SPI_IER_TF_EMP | AW_SPI_IER_RF_FULL); 510 511 sc->transfer = 1; 512 513 while (error == 0 && sc->transfer != 0) 514 error = msleep(sc, &sc->mtx, 0, "aw_spi", 10 * hz); 515 516 return (0); 517} 518 519static int 520aw_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) 521{ 522 struct aw_spi_softc *sc; 523 uint32_t cs, mode, clock, reg; 524 int err = 0; 525 526 sc = device_get_softc(dev); 527 528 spibus_get_cs(child, &cs); 529 spibus_get_clock(child, &clock); 530 spibus_get_mode(child, &mode); 531 532 /* The minimum divider is 2 so set the clock at twice the needed speed */ 533 clk_set_freq(sc->clk_mod, 2 * clock, CLK_SET_ROUND_DOWN); 534 clk_get_freq(sc->clk_mod, &sc->mod_freq); 535 if (cs >= AW_SPI_MAX_CS) { 536 device_printf(dev, "Invalid cs %d\n", cs); 537 return (EINVAL); 538 } 539 540 mtx_lock(&sc->mtx); 541 542 /* Enable and reset the module */ 543 reg = AW_SPI_READ_4(sc, AW_SPI_GCR); 544 reg |= AW_SPI_GCR_EN | AW_SPI_GCR_SRST; 545 AW_SPI_WRITE_4(sc, AW_SPI_GCR, reg); 546 547 /* Setup clock, CS and mode */ 548 aw_spi_setup_clock(sc, clock); 549 aw_spi_setup_mode(sc, mode); 550 if (cs & SPIBUS_CS_HIGH) 551 aw_spi_setup_cs(sc, cs, false); 552 else 553 aw_spi_setup_cs(sc, cs, true); 554 555 /* xfer */ 556 err = 0; 557 if (cmd->tx_cmd_sz > 0) 558 err = aw_spi_xfer(sc, cmd->rx_cmd, cmd->tx_cmd, 559 cmd->tx_cmd_sz, cmd->rx_cmd_sz); 560 if (cmd->tx_data_sz > 0 && err == 0) 561 err = aw_spi_xfer(sc, cmd->rx_data, cmd->tx_data, 562 cmd->tx_data_sz, cmd->rx_data_sz); 563 564 if (cs & SPIBUS_CS_HIGH) 565 aw_spi_setup_cs(sc, cs, true); 566 else 567 aw_spi_setup_cs(sc, cs, false); 568 569 /* Disable the module */ 570 reg = AW_SPI_READ_4(sc, AW_SPI_GCR); 571 reg &= ~AW_SPI_GCR_EN; 572 AW_SPI_WRITE_4(sc, AW_SPI_GCR, reg); 573 574 mtx_unlock(&sc->mtx); 575 576 return (err); 577} 578 579static device_method_t aw_spi_methods[] = { 580 /* Device interface */ 581 DEVMETHOD(device_probe, aw_spi_probe), 582 DEVMETHOD(device_attach, aw_spi_attach), 583 DEVMETHOD(device_detach, aw_spi_detach), 584 585 /* spibus_if */ 586 DEVMETHOD(spibus_transfer, aw_spi_transfer), 587 588 /* ofw_bus_if */ 589 DEVMETHOD(ofw_bus_get_node, aw_spi_get_node), 590 591 DEVMETHOD_END 592}; 593 594static driver_t aw_spi_driver = { 595 "aw_spi", 596 aw_spi_methods, 597 sizeof(struct aw_spi_softc), 598}; 599 600static devclass_t aw_spi_devclass; 601 602DRIVER_MODULE(aw_spi, simplebus, aw_spi_driver, aw_spi_devclass, 0, 0); 603DRIVER_MODULE(ofw_spibus, aw_spi, ofw_spibus_driver, ofw_spibus_devclass, 0, 0); 604MODULE_DEPEND(aw_spi, ofw_spibus, 1, 1, 1); 605SIMPLEBUS_PNP_INFO(compat_data); 606