Esempio n. 1
0
static void altera_spi_chipsel(struct spi_device *spi, int value)
{
    struct altera_spi *hw = altera_spi_to_hw(spi);

    if (spi->mode & SPI_CS_HIGH) {
        switch (value) {
        case BITBANG_CS_INACTIVE:
            writel(1 << spi->chip_select,
                   hw->base + ALTERA_SPI_SLAVE_SEL);
            hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
            writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
            break;

        case BITBANG_CS_ACTIVE:
            hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
            writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
            writel(0, hw->base + ALTERA_SPI_SLAVE_SEL);
            break;
        }
    } else {
        switch (value) {
        case BITBANG_CS_INACTIVE:
            hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
            writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
            break;

        case BITBANG_CS_ACTIVE:
            writel(1 << spi->chip_select,
                   hw->base + ALTERA_SPI_SLAVE_SEL);
            hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
            writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
            break;
        }
    }
}
Esempio n. 2
0
static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
{
	struct altera_spi *hw = altera_spi_to_hw(spi);

	hw->tx = t->tx_buf;
	hw->rx = t->rx_buf;
	hw->count = 0;
	hw->bytes_per_word = (t->bits_per_word ? : spi->bits_per_word) / 8;
	hw->len = t->len / hw->bytes_per_word;

	if (hw->irq >= 0) {
		/* enable receive interrupt */
		hw->imr |= ALTERA_SPI_CONTROL_IRRDY_MSK;
		writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);

		/* send the first byte */
		writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA);

		wait_for_completion(&hw->done);
		/* disable receive interrupt */
		hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
		writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
	} else {
		/* send the first byte */
		writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA);

		while (1) {
			unsigned int rxd;

			while (!(readl(hw->base + ALTERA_SPI_STATUS) &
				 ALTERA_SPI_STATUS_RRDY_MSK))
				cpu_relax();

			rxd = readl(hw->base + ALTERA_SPI_RXDATA);
			if (hw->rx) {
				switch (hw->bytes_per_word) {
				case 1:
					hw->rx[hw->count] = rxd;
					break;
				case 2:
					hw->rx[hw->count * 2] = rxd;
					hw->rx[hw->count * 2 + 1] = rxd >> 8;
					break;
				}
			}

			hw->count++;

			if (hw->count < hw->len)
				writel(hw_txbyte(hw, hw->count),
				       hw->base + ALTERA_SPI_TXDATA);
			else
				break;
		}

	}

	return hw->count * hw->bytes_per_word;
}