Lines Matching +full:cs +full:- +full:setup
1 /*-
64 #define AW_SPI_TCR_SS_LEVEL (1 << 7) /* 1 == CS High */
126 { "allwinner,sun8i-h3-spi", 1 },
133 { -1, 0 }
156 #define AW_SPI_LOCK(sc) mtx_lock(&(sc)->mtx)
157 #define AW_SPI_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
158 #define AW_SPI_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED)
159 #define AW_SPI_READ_1(sc, reg) bus_read_1((sc)->res[0], (reg))
160 #define AW_SPI_WRITE_1(sc, reg, val) bus_write_1((sc)->res[0], (reg), (val))
161 #define AW_SPI_READ_4(sc, reg) bus_read_4((sc)->res[0], (reg))
162 #define AW_SPI_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val))
175 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) in aw_spi_probe()
189 sc->dev = dev; in aw_spi_attach()
191 mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); in aw_spi_attach()
193 if (bus_alloc_resources(dev, aw_spi_spec, sc->res) != 0) { in aw_spi_attach()
199 if (bus_setup_intr(dev, sc->res[1], in aw_spi_attach()
201 &sc->intrhand)) { in aw_spi_attach()
202 bus_release_resources(dev, aw_spi_spec, sc->res); in aw_spi_attach()
203 device_printf(dev, "cannot setup interrupt handler\n"); in aw_spi_attach()
207 /* De-assert reset */ in aw_spi_attach()
208 if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst_ahb) == 0) { in aw_spi_attach()
209 error = hwreset_deassert(sc->rst_ahb); in aw_spi_attach()
211 device_printf(dev, "cannot de-assert reset\n"); in aw_spi_attach()
217 error = clk_get_by_ofw_name(dev, 0, "ahb", &sc->clk_ahb); in aw_spi_attach()
222 error = clk_get_by_ofw_name(dev, 0, "mod", &sc->clk_mod); in aw_spi_attach()
227 error = clk_enable(sc->clk_ahb); in aw_spi_attach()
232 error = clk_enable(sc->clk_mod); in aw_spi_attach()
238 sc->spibus = device_add_child(dev, "spibus", DEVICE_UNIT_ANY); in aw_spi_attach()
255 bus_generic_detach(sc->dev); in aw_spi_detach()
257 if (sc->clk_mod != NULL) in aw_spi_detach()
258 clk_release(sc->clk_mod); in aw_spi_detach()
259 if (sc->clk_ahb) in aw_spi_detach()
260 clk_release(sc->clk_ahb); in aw_spi_detach()
261 if (sc->rst_ahb) in aw_spi_detach()
262 hwreset_assert(sc->rst_ahb); in aw_spi_detach()
264 if (sc->intrhand != NULL) in aw_spi_detach()
265 bus_teardown_intr(sc->dev, sc->res[1], sc->intrhand); in aw_spi_detach()
267 bus_release_resources(dev, aw_spi_spec, sc->res); in aw_spi_detach()
268 mtx_destroy(&sc->mtx); in aw_spi_detach()
290 /* Setup the modes */ in aw_spi_setup_mode()
301 aw_spi_setup_cs(struct aw_spi_softc *sc, uint32_t cs, bool low) in aw_spi_setup_cs() argument
305 /* Setup CS */ in aw_spi_setup_cs()
308 reg |= cs << AW_SPI_TCR_SSSEL_SHIFT; in aw_spi_setup_cs()
326 cur = sc->mod_freq / (1 << i); in aw_spi_clock_test_cdr1()
327 if ((clock - cur) < (clock - best)) { in aw_spi_clock_test_cdr1()
345 cur = sc->mod_freq / (2 * i + 1); in aw_spi_clock_test_cdr2()
346 if ((clock - cur) < (clock - best)) { in aw_spi_clock_test_cdr2()
370 if ((clock - best_ccr1) < (clock - best_ccr2)) in aw_spi_setup_clock()
385 if (sc->txcnt == sc->txlen) in aw_spi_fill_txfifo()
392 for (i = 0; i < (AW_SPI_FIFO_SIZE - txcnt); i++) { in aw_spi_fill_txfifo()
393 AW_SPI_WRITE_1(sc, AW_SPI_TXD, sc->txbuf[sc->txcnt++]); in aw_spi_fill_txfifo()
394 if (sc->txcnt == sc->txlen) in aw_spi_fill_txfifo()
408 if (sc->rxcnt == sc->rxlen) in aw_spi_read_rxfifo()
416 if (sc->rxcnt < sc->rxlen) in aw_spi_read_rxfifo()
417 sc->rxbuf[sc->rxcnt++] = val; in aw_spi_read_rxfifo()
441 if (sc->txcnt == sc->txlen) in aw_spi_intr()
452 sc->transfer = 0; in aw_spi_intr()
467 sc->rxbuf = rxbuf; in aw_spi_xfer()
468 sc->rxcnt = 0; in aw_spi_xfer()
469 sc->txbuf = txbuf; in aw_spi_xfer()
470 sc->txcnt = 0; in aw_spi_xfer()
471 sc->txlen = txlen; in aw_spi_xfer()
472 sc->rxlen = rxlen; in aw_spi_xfer()
477 for (timeout = 1000; timeout > 0; timeout--) { in aw_spi_xfer()
483 device_printf(sc->dev, "Cannot reset the FIFOs\n"); in aw_spi_xfer()
488 * Set the TX FIFO threshold to 3/4-th the size and in aw_spi_xfer()
489 * the RX FIFO one to 1/4-th. in aw_spi_xfer()
517 sc->transfer = 1; in aw_spi_xfer()
519 while (error == 0 && sc->transfer != 0) in aw_spi_xfer()
520 error = msleep(sc, &sc->mtx, 0, "aw_spi", 10 * hz); in aw_spi_xfer()
529 uint32_t cs, mode, clock, reg; in aw_spi_transfer() local
534 spibus_get_cs(child, &cs); in aw_spi_transfer()
539 clk_set_freq(sc->clk_mod, 2 * clock, CLK_SET_ROUND_DOWN); in aw_spi_transfer()
540 clk_get_freq(sc->clk_mod, &sc->mod_freq); in aw_spi_transfer()
541 if (cs >= AW_SPI_MAX_CS) { in aw_spi_transfer()
542 device_printf(dev, "Invalid cs %d\n", cs); in aw_spi_transfer()
546 mtx_lock(&sc->mtx); in aw_spi_transfer()
553 /* Setup clock, CS and mode */ in aw_spi_transfer()
556 if (cs & SPIBUS_CS_HIGH) in aw_spi_transfer()
557 aw_spi_setup_cs(sc, cs, false); in aw_spi_transfer()
559 aw_spi_setup_cs(sc, cs, true); in aw_spi_transfer()
563 if (cmd->tx_cmd_sz > 0) in aw_spi_transfer()
564 err = aw_spi_xfer(sc, cmd->rx_cmd, cmd->tx_cmd, in aw_spi_transfer()
565 cmd->tx_cmd_sz, cmd->rx_cmd_sz); in aw_spi_transfer()
566 if (cmd->tx_data_sz > 0 && err == 0) in aw_spi_transfer()
567 err = aw_spi_xfer(sc, cmd->rx_data, cmd->tx_data, in aw_spi_transfer()
568 cmd->tx_data_sz, cmd->rx_data_sz); in aw_spi_transfer()
570 if (cs & SPIBUS_CS_HIGH) in aw_spi_transfer()
571 aw_spi_setup_cs(sc, cs, true); in aw_spi_transfer()
573 aw_spi_setup_cs(sc, cs, false); in aw_spi_transfer()
580 mtx_unlock(&sc->mtx); in aw_spi_transfer()