static int spi_st_transfer_one(struct spi_master *master, struct spi_device *spi, struct spi_transfer *t) { struct spi_st *spi_st = spi_master_get_devdata(master); uint32_t ctl = 0; /* Setup transfer */ spi_st->tx_ptr = t->tx_buf; spi_st->rx_ptr = t->rx_buf; if (spi->bits_per_word > 8) { /* * Anything greater than 8 bits-per-word requires 2 * bytes-per-word in the RX/TX buffers */ spi_st->bytes_per_word = 2; spi_st->words_remaining = t->len / 2; } else if (spi->bits_per_word == 8 && !(t->len & 0x1)) { /* * If transfer is even-length, and 8 bits-per-word, then * implement as half-length 16 bits-per-word transfer */ spi_st->bytes_per_word = 2; spi_st->words_remaining = t->len / 2; /* Set SSC_CTL to 16 bits-per-word */ ctl = readl_relaxed(spi_st->base + SSC_CTL); writel_relaxed((ctl | 0xf), spi_st->base + SSC_CTL); readl_relaxed(spi_st->base + SSC_RBUF); } else { spi_st->bytes_per_word = 1; spi_st->words_remaining = t->len; } reinit_completion(&spi_st->done); /* Start transfer by writing to the TX FIFO */ ssc_write_tx_fifo(spi_st); writel_relaxed(SSC_IEN_TEEN, spi_st->base + SSC_IEN); /* Wait for transfer to complete */ wait_for_completion(&spi_st->done); /* Restore SSC_CTL if necessary */ if (ctl) writel_relaxed(ctl, spi_st->base + SSC_CTL); spi_finalize_current_transfer(spi->master); return t->len; }
static int spi_stm_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) { struct spi_stm *spi_stm; uint32_t ctl = 0; spi_stm = spi_master_get_devdata(spi->master); /* Setup transfer */ spi_stm->tx_ptr = t->tx_buf; spi_stm->rx_ptr = t->rx_buf; if (spi_stm->bits_per_word > 8) { /* Anything greater than 8 bits-per-word requires 2 * bytes-per-word in the RX/TX buffers */ spi_stm->bytes_per_word = 2; spi_stm->words_remaining = t->len/2; } else if (spi_stm->bits_per_word == 8 && ((t->len & 0x1) == 0)) { /* If transfer is even-length, and 8 bits-per-word, then * implement as half-length 16 bits-per-word transfer */ spi_stm->bytes_per_word = 2; spi_stm->words_remaining = t->len/2; /* Set SSC_CTL to 16 bits-per-word */ ctl = ssc_load32(spi_stm, SSC_CTL); ssc_store32(spi_stm, SSC_CTL, (ctl | 0xf)); ssc_load32(spi_stm, SSC_RBUF); } else { spi_stm->bytes_per_word = 1; spi_stm->words_remaining = t->len; } INIT_COMPLETION(spi_stm->done); /* Start transfer by writing to the TX FIFO */ ssc_write_tx_fifo(spi_stm); ssc_store32(spi_stm, SSC_IEN, SSC_IEN_TEEN); /* Wait for transfer to complete */ wait_for_completion(&spi_stm->done); /* Restore SSC_CTL if necessary */ if (ctl) ssc_store32(spi_stm, SSC_CTL, ctl); return t->len; }
/* Interrupt fired when TX shift register becomes empty */ static irqreturn_t spi_stm_irq(int irq, void *dev_id) { struct spi_stm *spi_stm = (struct spi_stm *)dev_id; /* Read RX FIFO */ ssc_read_rx_fifo(spi_stm); /* Fill TX FIFO */ if (spi_stm->words_remaining) { ssc_write_tx_fifo(spi_stm); } else { /* TX/RX complete */ ssc_store32(spi_stm, SSC_IEN, 0x0); complete(&spi_stm->done); } return IRQ_HANDLED; }
/* Interrupt fired when TX shift register becomes empty */ static irqreturn_t spi_st_irq(int irq, void *dev_id) { struct spi_st *spi_st = (struct spi_st *)dev_id; /* Read RX FIFO */ ssc_read_rx_fifo(spi_st); /* Fill TX FIFO */ if (spi_st->words_remaining) { ssc_write_tx_fifo(spi_st); } else { /* TX/RX complete */ writel_relaxed(0x0, spi_st->base + SSC_IEN); /* * read SSC_IEN to ensure that this bit is set * before re-enabling interrupt */ readl(spi_st->base + SSC_IEN); complete(&spi_st->done); } return IRQ_HANDLED; }