Merge remote-tracking branches 'spi/topic/acpi', 'spi/topic/axi-engine', 'spi/topic/bcm2835' and 'spi/topic/bcm2835aux' into spi-next
This commit is contained in:
@@ -64,9 +64,9 @@
|
||||
#define BCM2835_AUX_SPI_CNTL0_VAR_WIDTH 0x00004000
|
||||
#define BCM2835_AUX_SPI_CNTL0_DOUTHOLD 0x00003000
|
||||
#define BCM2835_AUX_SPI_CNTL0_ENABLE 0x00000800
|
||||
#define BCM2835_AUX_SPI_CNTL0_CPHA_IN 0x00000400
|
||||
#define BCM2835_AUX_SPI_CNTL0_IN_RISING 0x00000400
|
||||
#define BCM2835_AUX_SPI_CNTL0_CLEARFIFO 0x00000200
|
||||
#define BCM2835_AUX_SPI_CNTL0_CPHA_OUT 0x00000100
|
||||
#define BCM2835_AUX_SPI_CNTL0_OUT_RISING 0x00000100
|
||||
#define BCM2835_AUX_SPI_CNTL0_CPOL 0x00000080
|
||||
#define BCM2835_AUX_SPI_CNTL0_MSBF_OUT 0x00000040
|
||||
#define BCM2835_AUX_SPI_CNTL0_SHIFTLEN 0x0000003F
|
||||
@@ -92,9 +92,6 @@
|
||||
#define BCM2835_AUX_SPI_POLLING_LIMIT_US 30
|
||||
#define BCM2835_AUX_SPI_POLLING_JIFFIES 2
|
||||
|
||||
#define BCM2835_AUX_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
|
||||
| SPI_NO_CS)
|
||||
|
||||
struct bcm2835aux_spi {
|
||||
void __iomem *regs;
|
||||
struct clk *clk;
|
||||
@@ -212,9 +209,15 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* and if rx_len is 0 then wake up completion and disable spi */
|
||||
if (!bs->tx_len) {
|
||||
/* disable tx fifo empty interrupt */
|
||||
bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1] |
|
||||
BCM2835_AUX_SPI_CNTL1_IDLE);
|
||||
}
|
||||
|
||||
/* and if rx_len is 0 then disable interrupts and wake up completion */
|
||||
if (!bs->rx_len) {
|
||||
bcm2835aux_spi_reset_hw(bs);
|
||||
bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
|
||||
complete(&master->xfer_completion);
|
||||
}
|
||||
|
||||
@@ -307,9 +310,6 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer complete - reset SPI HW */
|
||||
bcm2835aux_spi_reset_hw(bs);
|
||||
|
||||
/* and return without waiting for completion */
|
||||
return 0;
|
||||
}
|
||||
@@ -330,10 +330,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
|
||||
* resulting (potentially) in more interrupts when transferring
|
||||
* more than 12 bytes
|
||||
*/
|
||||
bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE |
|
||||
BCM2835_AUX_SPI_CNTL0_VAR_WIDTH |
|
||||
BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
|
||||
bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN;
|
||||
|
||||
/* set clock */
|
||||
spi_hz = tfr->speed_hz;
|
||||
@@ -348,17 +344,13 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
|
||||
} else { /* the slowest we can go */
|
||||
speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX;
|
||||
}
|
||||
/* mask out old speed from previous spi_transfer */
|
||||
bs->cntl[0] &= ~(BCM2835_AUX_SPI_CNTL0_SPEED);
|
||||
/* set the new speed */
|
||||
bs->cntl[0] |= speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT;
|
||||
|
||||
spi_used_hz = clk_hz / (2 * (speed + 1));
|
||||
|
||||
/* handle all the modes */
|
||||
if (spi->mode & SPI_CPOL)
|
||||
bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL;
|
||||
if (spi->mode & SPI_CPHA)
|
||||
bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT |
|
||||
BCM2835_AUX_SPI_CNTL0_CPHA_IN;
|
||||
|
||||
/* set transmit buffers and length */
|
||||
bs->tx_buf = tfr->tx_buf;
|
||||
bs->rx_buf = tfr->rx_buf;
|
||||
@@ -382,6 +374,40 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
|
||||
return bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
|
||||
}
|
||||
|
||||
static int bcm2835aux_spi_prepare_message(struct spi_master *master,
|
||||
struct spi_message *msg)
|
||||
{
|
||||
struct spi_device *spi = msg->spi;
|
||||
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
|
||||
|
||||
bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE |
|
||||
BCM2835_AUX_SPI_CNTL0_VAR_WIDTH |
|
||||
BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
|
||||
bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN;
|
||||
|
||||
/* handle all the modes */
|
||||
if (spi->mode & SPI_CPOL) {
|
||||
bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL;
|
||||
bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_OUT_RISING;
|
||||
} else {
|
||||
bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_IN_RISING;
|
||||
}
|
||||
bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
|
||||
bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm2835aux_spi_unprepare_message(struct spi_master *master,
|
||||
struct spi_message *msg)
|
||||
{
|
||||
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
|
||||
|
||||
bcm2835aux_spi_reset_hw(bs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bcm2835aux_spi_handle_err(struct spi_master *master,
|
||||
struct spi_message *msg)
|
||||
{
|
||||
@@ -405,11 +431,13 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, master);
|
||||
master->mode_bits = BCM2835_AUX_SPI_MODE_BITS;
|
||||
master->mode_bits = (SPI_CPOL | SPI_CS_HIGH | SPI_NO_CS);
|
||||
master->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
master->num_chipselect = -1;
|
||||
master->transfer_one = bcm2835aux_spi_transfer_one;
|
||||
master->handle_err = bcm2835aux_spi_handle_err;
|
||||
master->prepare_message = bcm2835aux_spi_prepare_message;
|
||||
master->unprepare_message = bcm2835aux_spi_unprepare_message;
|
||||
master->dev.of_node = pdev->dev.of_node;
|
||||
|
||||
bs = spi_master_get_devdata(master);
|
||||
|
Reference in New Issue
Block a user