static int lpc_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) { struct lpc_spi_softc *sc = device_get_softc(dev); struct spibus_ivar *devi = SPIBUS_IVAR(child); uint8_t *in_buf, *out_buf; int i; /* Set CS active */ lpc_gpio_set_state(child, devi->cs, 0); /* Wait for FIFO to be ready */ while ((lpc_spi_read_4(sc, LPC_SSP_SR) & LPC_SSP_SR_TNF) == 0); /* Command */ in_buf = cmd->rx_cmd; out_buf = cmd->tx_cmd; for (i = 0; i < cmd->tx_cmd_sz; i++) { lpc_spi_write_4(sc, LPC_SSP_DR, out_buf[i]); in_buf[i] = lpc_spi_read_4(sc, LPC_SSP_DR); } /* Data */ in_buf = cmd->rx_data; out_buf = cmd->tx_data; for (i = 0; i < cmd->tx_data_sz; i++) { lpc_spi_write_4(sc, LPC_SSP_DR, out_buf[i]); in_buf[i] = lpc_spi_read_4(sc, LPC_SSP_DR); } /* Set CS inactive */ lpc_gpio_set_state(child, devi->cs, 1); return (0); }
static int spibus_child_location_str(device_t bus, device_t child, char *buf, size_t buflen) { struct spibus_ivar *devi = SPIBUS_IVAR(child); snprintf(buf, buflen, "cs=%d", devi->cs); return (0); }
static void spibus_probe_nomatch(device_t bus, device_t child) { struct spibus_ivar *devi = SPIBUS_IVAR(child); device_printf(bus, "<unknown card>"); printf(" at cs %d\n", devi->cs); return; }
static void spibus_hinted_child(device_t bus, const char *dname, int dunit) { device_t child; struct spibus_ivar *devi; child = BUS_ADD_CHILD(bus, 0, dname, dunit); devi = SPIBUS_IVAR(child); resource_int_value(dname, dunit, "cs", &devi->cs); }
static int spibus_print_child(device_t dev, device_t child) { struct spibus_ivar *devi = SPIBUS_IVAR(child); int retval = 0; retval += bus_print_child_header(dev, child); retval += printf(" at cs %d", devi->cs); retval += bus_print_child_footer(dev, child); return (retval); }
static int spibus_read_ivar(device_t bus, device_t child, int which, uintptr_t *result) { struct spibus_ivar *devi = SPIBUS_IVAR(child); switch (which) { default: return (EINVAL); case SPIBUS_IVAR_CS: *(uint32_t *)result = devi->cs; break; } return (0); }
static int ar71xx_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) { struct ar71xx_spi_softc *sc; uint8_t *buf_in, *buf_out; struct spibus_ivar *devi = SPIBUS_IVAR(child); int i; sc = device_get_softc(dev); ar71xx_spi_chip_activate(sc, devi->cs); KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, ("TX/RX command sizes should be equal")); KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, ("TX/RX data sizes should be equal")); /* * Transfer command */ buf_out = (uint8_t *)cmd->tx_cmd; buf_in = (uint8_t *)cmd->rx_cmd; for (i = 0; i < cmd->tx_cmd_sz; i++) buf_in[i] = ar71xx_spi_txrx(sc, devi->cs, buf_out[i]); /* * Receive/transmit data (depends on command) */ buf_out = (uint8_t *)cmd->tx_data; buf_in = (uint8_t *)cmd->rx_data; for (i = 0; i < cmd->tx_data_sz; i++) buf_in[i] = ar71xx_spi_txrx(sc, devi->cs, buf_out[i]); ar71xx_spi_chip_deactivate(sc, devi->cs); return (0); }