Lines Matching +full:cs +full:- +full:to +full:- +full:clk

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 {"broadcom,bcm2835-spi", 1},
59 {"brcm,bcm2835-spi", 1},
74 device_printf(dev, "CS=%b\n", reg, in bcm_spi_printr()
81 reg--; in bcm_spi_printr()
84 device_printf(dev, "CLK=%uMhz/%d=%luhz\n", in bcm_spi_printr()
105 mtx_assert(&sc->sc_mtx, MA_OWNED); in bcm_spi_modifyreg()
116 uint32_t clk; in bcm_spi_clock_proc() local
122 clk = BCM_SPI_READ(sc, SPI_CLK); in bcm_spi_clock_proc()
124 clk &= 0xffff; in bcm_spi_clock_proc()
125 if (clk == 0) in bcm_spi_clock_proc()
126 clk = 65536; in bcm_spi_clock_proc()
127 clk = SPI_CORE_CLK / clk; in bcm_spi_clock_proc()
129 error = sysctl_handle_int(oidp, &clk, sizeof(clk), req); in bcm_spi_clock_proc()
130 if (error != 0 || req->newptr == NULL) in bcm_spi_clock_proc()
150 if (error != 0 || req->newptr == NULL) in bcm_spi_cs_bit_proc()
201 ctx = device_get_sysctl_ctx(sc->sc_dev); in bcm_spi_sysctl_init()
202 tree_node = device_get_sysctl_tree(sc->sc_dev); in bcm_spi_sysctl_init()
231 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) in bcm_spi_probe()
251 sc->sc_dev = dev; in bcm_spi_attach()
254 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, in bcm_spi_attach()
256 if (!sc->sc_mem_res) { in bcm_spi_attach()
261 sc->sc_bst = rman_get_bustag(sc->sc_mem_res); in bcm_spi_attach()
262 sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); in bcm_spi_attach()
265 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in bcm_spi_attach()
267 if (!sc->sc_irq_res) { in bcm_spi_attach()
268 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); in bcm_spi_attach()
274 if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, in bcm_spi_attach()
275 NULL, bcm_spi_intr, sc, &sc->sc_intrhand)) { in bcm_spi_attach()
276 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); in bcm_spi_attach()
277 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); in bcm_spi_attach()
282 mtx_init(&sc->sc_mtx, "bcm_spi", NULL, MTX_DEF); in bcm_spi_attach()
293 * Defaults to SPI mode 0. in bcm_spi_attach()
315 mtx_destroy(&sc->sc_mtx); in bcm_spi_detach()
316 if (sc->sc_intrhand) in bcm_spi_detach()
317 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); in bcm_spi_detach()
318 if (sc->sc_irq_res) in bcm_spi_detach()
319 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); in bcm_spi_detach()
320 if (sc->sc_mem_res) in bcm_spi_detach()
321 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); in bcm_spi_detach()
330 uint32_t cs, written; in bcm_spi_fill_fifo() local
333 cmd = sc->sc_cmd; in bcm_spi_fill_fifo()
334 cs = BCM_SPI_READ(sc, SPI_CS) & (SPI_CS_TA | SPI_CS_TXD); in bcm_spi_fill_fifo()
335 while (sc->sc_written < sc->sc_len && in bcm_spi_fill_fifo()
336 cs == (SPI_CS_TA | SPI_CS_TXD)) { in bcm_spi_fill_fifo()
337 data = (uint8_t *)cmd->tx_cmd; in bcm_spi_fill_fifo()
338 written = sc->sc_written++; in bcm_spi_fill_fifo()
339 if (written >= cmd->tx_cmd_sz) { in bcm_spi_fill_fifo()
340 data = (uint8_t *)cmd->tx_data; in bcm_spi_fill_fifo()
341 written -= cmd->tx_cmd_sz; in bcm_spi_fill_fifo()
344 cs = BCM_SPI_READ(sc, SPI_CS) & (SPI_CS_TA | SPI_CS_TXD); in bcm_spi_fill_fifo()
352 uint32_t cs, read; in bcm_spi_drain_fifo() local
355 cmd = sc->sc_cmd; in bcm_spi_drain_fifo()
356 cs = BCM_SPI_READ(sc, SPI_CS) & SPI_CS_RXD; in bcm_spi_drain_fifo()
357 while (sc->sc_read < sc->sc_len && cs == SPI_CS_RXD) { in bcm_spi_drain_fifo()
358 data = (uint8_t *)cmd->rx_cmd; in bcm_spi_drain_fifo()
359 read = sc->sc_read++; in bcm_spi_drain_fifo()
360 if (read >= cmd->rx_cmd_sz) { in bcm_spi_drain_fifo()
361 data = (uint8_t *)cmd->rx_data; in bcm_spi_drain_fifo()
362 read -= cmd->rx_cmd_sz; in bcm_spi_drain_fifo()
365 cs = BCM_SPI_READ(sc, SPI_CS) & SPI_CS_RXD; in bcm_spi_drain_fifo()
378 if ((sc->sc_flags & BCM_SPI_BUSY) == 0) { in bcm_spi_intr()
383 /* TX - Fill up the FIFO. */ in bcm_spi_intr()
386 /* RX - Drain the FIFO. */ in bcm_spi_intr()
390 if (sc->sc_written == sc->sc_len && sc->sc_read == sc->sc_len) { in bcm_spi_intr()
392 if ((sc->sc_flags & BCM_SPI_KEEP_CS) == 0) { in bcm_spi_intr()
396 wakeup(sc->sc_dev); in bcm_spi_intr()
406 uint32_t cs, mode, clock; in bcm_spi_transfer() local
411 KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, in bcm_spi_transfer()
413 KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, in bcm_spi_transfer()
418 spibus_get_cs(child, &cs); in bcm_spi_transfer()
419 if ((cs & (~SPIBUS_CS_HIGH)) > 2) { in bcm_spi_transfer()
421 "Invalid chip select %u requested by %s\n", cs, in bcm_spi_transfer()
444 if (sc->sc_thread != curthread) in bcm_spi_transfer()
445 while (sc->sc_flags & BCM_SPI_BUSY) in bcm_spi_transfer()
446 mtx_sleep(dev, &sc->sc_mtx, 0, "bcm_spi", 0); in bcm_spi_transfer()
449 sc->sc_flags = BCM_SPI_BUSY; in bcm_spi_transfer()
451 if ((cmd->flags & SPI_FLAG_KEEP_CS) != 0) in bcm_spi_transfer()
452 sc->sc_flags |= BCM_SPI_KEEP_CS; in bcm_spi_transfer()
455 if (sc->sc_thread != curthread) in bcm_spi_transfer()
460 sc->sc_thread = curthread; in bcm_spi_transfer()
462 /* Save a pointer to the SPI command. */ in bcm_spi_transfer()
463 sc->sc_cmd = cmd; in bcm_spi_transfer()
464 sc->sc_read = 0; in bcm_spi_transfer()
465 sc->sc_written = 0; in bcm_spi_transfer()
466 sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz; in bcm_spi_transfer()
470 * Assign CS polarity first, while the CS indicates 'inactive'. in bcm_spi_transfer()
471 * This will need to set the correct polarity bit based on the 'cs', and in bcm_spi_transfer()
475 if((cs & ~SPIBUS_CS_HIGH) == 0) { in bcm_spi_transfer()
478 ((cs & (SPIBUS_CS_HIGH)) ? SPI_CS_CSPOL0 : 0)); in bcm_spi_transfer()
480 else if((cs & ~SPIBUS_CS_HIGH) == 1) { in bcm_spi_transfer()
483 ((cs & (SPIBUS_CS_HIGH)) ? SPI_CS_CSPOL1 : 0)); in bcm_spi_transfer()
485 else if((cs & ~SPIBUS_CS_HIGH) == 2) { in bcm_spi_transfer()
488 ((cs & (SPIBUS_CS_HIGH)) ? SPI_CS_CSPOL2 : 0)); in bcm_spi_transfer()
494 * This must happen before CS output pin is active. in bcm_spi_transfer()
503 * Set the clock divider in 'SPI_CLK - see 'bcm_spi_clock_proc()'. in bcm_spi_transfer()
511 clock--; in bcm_spi_transfer()
518 * Set the CS for this transaction, enable interrupts and announce in bcm_spi_transfer()
519 * we're ready to tx. This will kick off the first interrupt. in bcm_spi_transfer()
523 (cs & (~SPIBUS_CS_HIGH)) | /* cs is the lower 2 bits of the reg */ in bcm_spi_transfer()
526 /* Wait for the transaction to complete. */ in bcm_spi_transfer()
527 err = mtx_sleep(dev, &sc->sc_mtx, 0, "bcm_spi", hz * 2); in bcm_spi_transfer()
530 if (!(cmd->flags & SPI_FLAG_KEEP_CS)) { in bcm_spi_transfer()
533 sc->sc_thread = 0; in bcm_spi_transfer()
537 sc->sc_flags &= ~BCM_SPI_BUSY; in bcm_spi_transfer()
546 device_printf(sc->sc_dev, "SPI error (timeout)\n"); in bcm_spi_transfer()