Commit b64836a5 authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Mark Brown

spi: altera: Consolidate TX/RX data register access

The patterns for accessing the TX/RX data registers is the same for the IRQ
and non-IRQ paths. Consolidate the duplicated code into shared helper
functions.
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent e19b63cd
...@@ -76,18 +76,43 @@ static void altera_spi_set_cs(struct spi_device *spi, bool is_high) ...@@ -76,18 +76,43 @@ static void altera_spi_set_cs(struct spi_device *spi, bool is_high)
} }
} }
static inline unsigned int hw_txbyte(struct altera_spi *hw, int count) static void altera_spi_tx_word(struct altera_spi *hw)
{ {
unsigned int txd = 0;
if (hw->tx) { if (hw->tx) {
switch (hw->bytes_per_word) { switch (hw->bytes_per_word) {
case 1: case 1:
return hw->tx[count]; txd = hw->tx[hw->count];
break;
case 2: case 2:
return (hw->tx[count * 2] txd = (hw->tx[hw->count * 2]
| (hw->tx[count * 2 + 1] << 8)); | (hw->tx[hw->count * 2 + 1] << 8));
break;
} }
} }
return 0;
writel(txd, hw->base + ALTERA_SPI_TXDATA);
}
static void altera_spi_rx_word(struct altera_spi *hw)
{
unsigned int rxd;
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++;
} }
static int altera_spi_txrx(struct spi_master *master, static int altera_spi_txrx(struct spi_master *master,
...@@ -107,32 +132,16 @@ static int altera_spi_txrx(struct spi_master *master, ...@@ -107,32 +132,16 @@ static int altera_spi_txrx(struct spi_master *master,
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
/* send the first byte */ /* send the first byte */
writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA); altera_spi_tx_word(hw);
} else { } else {
while (hw->count < hw->len) { while (hw->count < hw->len) {
unsigned int rxd; altera_spi_tx_word(hw);
writel(hw_txbyte(hw, hw->count),
hw->base + ALTERA_SPI_TXDATA);
while (!(readl(hw->base + ALTERA_SPI_STATUS) & while (!(readl(hw->base + ALTERA_SPI_STATUS) &
ALTERA_SPI_STATUS_RRDY_MSK)) ALTERA_SPI_STATUS_RRDY_MSK))
cpu_relax(); cpu_relax();
rxd = readl(hw->base + ALTERA_SPI_RXDATA); altera_spi_rx_word(hw);
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++;
} }
spi_finalize_current_transfer(master); spi_finalize_current_transfer(master);
} }
...@@ -144,25 +153,11 @@ static irqreturn_t altera_spi_irq(int irq, void *dev) ...@@ -144,25 +153,11 @@ static irqreturn_t altera_spi_irq(int irq, void *dev)
{ {
struct spi_master *master = dev; struct spi_master *master = dev;
struct altera_spi *hw = spi_master_get_devdata(master); struct altera_spi *hw = spi_master_get_devdata(master);
unsigned int rxd;
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++; altera_spi_rx_word(hw);
if (hw->count < hw->len) { if (hw->count < hw->len) {
writel(hw_txbyte(hw, hw->count), hw->base + ALTERA_SPI_TXDATA); altera_spi_tx_word(hw);
} else { } else {
/* disable receive interrupt */ /* disable receive interrupt */
hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK; hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment