aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-bcm2835aux.c57
1 files changed, 41 insertions, 16 deletions
diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c
index e1b2fec1db63..a6e25c6c66ca 100644
--- a/drivers/spi/spi-bcm2835aux.c
+++ b/drivers/spi/spi-bcm2835aux.c
@@ -218,9 +218,9 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
218 BCM2835_AUX_SPI_CNTL1_IDLE); 218 BCM2835_AUX_SPI_CNTL1_IDLE);
219 } 219 }
220 220
221 /* and if rx_len is 0 then wake up completion and disable spi */ 221 /* and if rx_len is 0 then disable interrupts and wake up completion */
222 if (!bs->rx_len) { 222 if (!bs->rx_len) {
223 bcm2835aux_spi_reset_hw(bs); 223 bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
224 complete(&master->xfer_completion); 224 complete(&master->xfer_completion);
225 } 225 }
226 226
@@ -313,9 +313,6 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
313 } 313 }
314 } 314 }
315 315
316 /* Transfer complete - reset SPI HW */
317 bcm2835aux_spi_reset_hw(bs);
318
319 /* and return without waiting for completion */ 316 /* and return without waiting for completion */
320 return 0; 317 return 0;
321} 318}
@@ -336,10 +333,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
336 * resulting (potentially) in more interrupts when transferring 333 * resulting (potentially) in more interrupts when transferring
337 * more than 12 bytes 334 * more than 12 bytes
338 */ 335 */
339 bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE |
340 BCM2835_AUX_SPI_CNTL0_VAR_WIDTH |
341 BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
342 bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN;
343 336
344 /* set clock */ 337 /* set clock */
345 spi_hz = tfr->speed_hz; 338 spi_hz = tfr->speed_hz;
@@ -354,17 +347,13 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
354 } else { /* the slowest we can go */ 347 } else { /* the slowest we can go */
355 speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX; 348 speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX;
356 } 349 }
350 /* mask out old speed from previous spi_transfer */
351 bs->cntl[0] &= ~(BCM2835_AUX_SPI_CNTL0_SPEED);
352 /* set the new speed */
357 bs->cntl[0] |= speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT; 353 bs->cntl[0] |= speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT;
358 354
359 spi_used_hz = clk_hz / (2 * (speed + 1)); 355 spi_used_hz = clk_hz / (2 * (speed + 1));
360 356
361 /* handle all the modes */
362 if (spi->mode & SPI_CPOL)
363 bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL;
364 if (spi->mode & SPI_CPHA)
365 bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT |
366 BCM2835_AUX_SPI_CNTL0_CPHA_IN;
367
368 /* set transmit buffers and length */ 357 /* set transmit buffers and length */
369 bs->tx_buf = tfr->tx_buf; 358 bs->tx_buf = tfr->tx_buf;
370 bs->rx_buf = tfr->rx_buf; 359 bs->rx_buf = tfr->rx_buf;
@@ -388,6 +377,40 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
388 return bcm2835aux_spi_transfer_one_irq(master, spi, tfr); 377 return bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
389} 378}
390 379
380static int bcm2835aux_spi_prepare_message(struct spi_master *master,
381 struct spi_message *msg)
382{
383 struct spi_device *spi = msg->spi;
384 struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
385
386 bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE |
387 BCM2835_AUX_SPI_CNTL0_VAR_WIDTH |
388 BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
389 bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN;
390
391 /* handle all the modes */
392 if (spi->mode & SPI_CPOL)
393 bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL;
394 if (spi->mode & SPI_CPHA)
395 bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT |
396 BCM2835_AUX_SPI_CNTL0_CPHA_IN;
397
398 bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
399 bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]);
400
401 return 0;
402}
403
404static int bcm2835aux_spi_unprepare_message(struct spi_master *master,
405 struct spi_message *msg)
406{
407 struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
408
409 bcm2835aux_spi_reset_hw(bs);
410
411 return 0;
412}
413
391static void bcm2835aux_spi_handle_err(struct spi_master *master, 414static void bcm2835aux_spi_handle_err(struct spi_master *master,
392 struct spi_message *msg) 415 struct spi_message *msg)
393{ 416{
@@ -416,6 +439,8 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
416 master->num_chipselect = -1; 439 master->num_chipselect = -1;
417 master->transfer_one = bcm2835aux_spi_transfer_one; 440 master->transfer_one = bcm2835aux_spi_transfer_one;
418 master->handle_err = bcm2835aux_spi_handle_err; 441 master->handle_err = bcm2835aux_spi_handle_err;
442 master->prepare_message = bcm2835aux_spi_prepare_message;
443 master->unprepare_message = bcm2835aux_spi_unprepare_message;
419 master->dev.of_node = pdev->dev.of_node; 444 master->dev.of_node = pdev->dev.of_node;
420 445
421 bs = spi_master_get_devdata(master); 446 bs = spi_master_get_devdata(master);