aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-bcm63xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-bcm63xx.c')
-rw-r--r--drivers/spi/spi-bcm63xx.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
index 6e25ef1bce91..a9f4049c6769 100644
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -47,6 +47,8 @@ struct bcm63xx_spi {
47 /* Platform data */ 47 /* Platform data */
48 u32 speed_hz; 48 u32 speed_hz;
49 unsigned fifo_size; 49 unsigned fifo_size;
50 unsigned int msg_type_shift;
51 unsigned int msg_ctl_width;
50 52
51 /* Data buffers */ 53 /* Data buffers */
52 const unsigned char *tx_ptr; 54 const unsigned char *tx_ptr;
@@ -221,13 +223,20 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
221 msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); 223 msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
222 224
223 if (t->rx_buf && t->tx_buf) 225 if (t->rx_buf && t->tx_buf)
224 msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT); 226 msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
225 else if (t->rx_buf) 227 else if (t->rx_buf)
226 msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT); 228 msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
227 else if (t->tx_buf) 229 else if (t->tx_buf)
228 msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT); 230 msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
229 231
230 bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); 232 switch (bs->msg_ctl_width) {
233 case 8:
234 bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL);
235 break;
236 case 16:
237 bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
238 break;
239 }
231 240
232 /* Issue the transfer */ 241 /* Issue the transfer */
233 cmd = SPI_CMD_START_IMMEDIATE; 242 cmd = SPI_CMD_START_IMMEDIATE;
@@ -406,9 +415,21 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)
406 master->transfer_one_message = bcm63xx_spi_transfer_one; 415 master->transfer_one_message = bcm63xx_spi_transfer_one;
407 master->mode_bits = MODEBITS; 416 master->mode_bits = MODEBITS;
408 bs->speed_hz = pdata->speed_hz; 417 bs->speed_hz = pdata->speed_hz;
418 bs->msg_type_shift = pdata->msg_type_shift;
419 bs->msg_ctl_width = pdata->msg_ctl_width;
409 bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); 420 bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
410 bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); 421 bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
411 422
423 switch (bs->msg_ctl_width) {
424 case 8:
425 case 16:
426 break;
427 default:
428 dev_err(dev, "unsupported MSG_CTL width: %d\n",
429 bs->msg_ctl_width);
430 goto out_clk_disable;
431 }
432
412 /* Initialize hardware */ 433 /* Initialize hardware */
413 clk_enable(bs->clk); 434 clk_enable(bs->clk);
414 bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); 435 bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
@@ -438,7 +459,7 @@ out:
438 459
439static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) 460static int __devexit bcm63xx_spi_remove(struct platform_device *pdev)
440{ 461{
441 struct spi_master *master = platform_get_drvdata(pdev); 462 struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
442 struct bcm63xx_spi *bs = spi_master_get_devdata(master); 463 struct bcm63xx_spi *bs = spi_master_get_devdata(master);
443 464
444 spi_unregister_master(master); 465 spi_unregister_master(master);
@@ -452,6 +473,8 @@ static int __devexit bcm63xx_spi_remove(struct platform_device *pdev)
452 473
453 platform_set_drvdata(pdev, 0); 474 platform_set_drvdata(pdev, 0);
454 475
476 spi_master_put(master);
477
455 return 0; 478 return 0;
456} 479}
457 480