static void mpcsa_leds_timer(void *aux) { int n, s; struct mpcsa_leds_softc *sc = aux; u_int16_t pins; callout_schedule(&sc->sc_c, mstohz(LEDS_UPDATE_INTERVAL)); s = splserial(); if (!(sc->sc_spi_transfer.st_flags & SPI_F_DONE)) { splx(s); return; } pins = be16toh(sc->sc_pinstate); for (n = 0; n < MPCSA_LEDS_NPINS; n++) { switch (sc->sc_leds[n].l_mode) { default: continue; case LMODE_COMM: if (sc->sc_leds[n].l_comm_cnt > 0) { if (sc->sc_leds[n].l_comm_cnt < INFINITE_BLINK) sc->sc_leds[n].l_comm_cnt--; else sc->sc_leds[n].l_comm_cnt ^= 1; } if ((sc->sc_leds[n].l_conn_cnt > 0) ^ (sc->sc_leds[n].l_comm_cnt & 1)) pins &= ~(1U << n); else pins |= (1U << n); break; case LMODE_BLINK: if (--sc->sc_leds[n].l_blink_cnt <= 0) { pins ^= (1U << n); sc->sc_leds[n].l_blink_cnt = sc->sc_leds[n].l_blink_int; } break; } } HTOBE16(pins); sc->sc_pinstate = pins; splx(s); spi_transfer_init(&sc->sc_spi_transfer); spi_chunk_init(&sc->sc_spi_chunk, 2, (const void *)&sc->sc_pinstate, NULL); spi_transfer_add(&sc->sc_spi_transfer, &sc->sc_spi_chunk); if (spi_transfer(sc->sc_sh, &sc->sc_spi_transfer) != 0) { /* an error occurred! */ } }
int spi_send(struct spi_handle *sh, int cnt, const uint8_t *data) { struct spi_transfer trans; struct spi_chunk chunk; spi_transfer_init(&trans); spi_chunk_init(&chunk, cnt, data, NULL); spi_transfer_add(&trans, &chunk); /* enqueue it and wait for it to complete */ spi_transfer(sh, &trans); spi_wait(&trans); if (trans.st_flags & SPI_F_ERROR) return trans.st_errno; return 0; }
int spi_send_recv(struct spi_handle *sh, int scnt, const uint8_t *snd, int rcnt, uint8_t *rcv) { struct spi_transfer trans; struct spi_chunk chunk1, chunk2; spi_transfer_init(&trans); spi_chunk_init(&chunk1, scnt, snd, NULL); spi_chunk_init(&chunk2, rcnt, NULL, rcv); spi_transfer_add(&trans, &chunk1); spi_transfer_add(&trans, &chunk2); /* enqueue it and wait for it to complete */ spi_transfer(sh, &trans); spi_wait(&trans); if (trans.st_flags & SPI_F_ERROR) return trans.st_errno; return 0; }