aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi_bfin5xx.c
diff options
context:
space:
mode:
authorBryan Wu <bryan.wu@analog.com>2007-12-05 02:45:15 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-12-05 12:21:19 -0500
commita32c691d7cf5c37af753255ef4843b18a31935b9 (patch)
tree5b7f6cea2e1574dbe57fb8fd2a4ddce0726b85c7 /drivers/spi/spi_bfin5xx.c
parent2ed355165ff4ec834a75770f2a15dc87f5e06088 (diff)
spi: spi_bfin uses platform device resources
Update spi driver to support multi-ports by using platform resources; tested on STAMP537+SPI_MMC, other boards need more testing. Plus other minor updates. Signed-off-by: Bryan Wu <bryan.wu@analog.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/spi/spi_bfin5xx.c')
-rw-r--r--drivers/spi/spi_bfin5xx.c124
1 files changed, 83 insertions, 41 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 8e4ea8906dc7..a8311a83ae96 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -13,6 +13,8 @@
13 * March 10, 2006 bfin5xx_spi.c Created. (Luke Yang) 13 * March 10, 2006 bfin5xx_spi.c Created. (Luke Yang)
14 * August 7, 2006 added full duplex mode (Axel Weiss & Luke Yang) 14 * August 7, 2006 added full duplex mode (Axel Weiss & Luke Yang)
15 * July 17, 2007 add support for BF54x SPI0 controller (Bryan Wu) 15 * July 17, 2007 add support for BF54x SPI0 controller (Bryan Wu)
16 * July 30, 2007 add platfrom_resource interface to support multi-port
17 * SPI controller (Bryan Wu)
16 * 18 *
17 * Copyright 2004-2007 Analog Devices Inc. 19 * Copyright 2004-2007 Analog Devices Inc.
18 * 20 *
@@ -50,18 +52,25 @@
50#include <asm/portmux.h> 52#include <asm/portmux.h>
51#include <asm/bfin5xx_spi.h> 53#include <asm/bfin5xx_spi.h>
52 54
53MODULE_AUTHOR("Bryan Wu, Luke Yang"); 55#define DRV_NAME "bfin-spi"
54MODULE_DESCRIPTION("Blackfin BF5xx SPI Contoller Driver"); 56#define DRV_AUTHOR "Bryan Wu, Luke Yang"
57#define DRV_DESC "Blackfin BF5xx on-chip SPI Contoller Driver"
58#define DRV_VERSION "1.0"
59
60MODULE_AUTHOR(DRV_AUTHOR);
61MODULE_DESCRIPTION(DRV_DESC);
55MODULE_LICENSE("GPL"); 62MODULE_LICENSE("GPL");
56 63
57#define DRV_NAME "bfin-spi-master"
58#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) 64#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
59 65
66static u32 spi_dma_ch;
67static u32 spi_regs_base;
68
60#define DEFINE_SPI_REG(reg, off) \ 69#define DEFINE_SPI_REG(reg, off) \
61static inline u16 read_##reg(void) \ 70static inline u16 read_##reg(void) \
62 { return bfin_read16(SPI0_REGBASE + off); } \ 71 { return bfin_read16(spi_regs_base + off); } \
63static inline void write_##reg(u16 v) \ 72static inline void write_##reg(u16 v) \
64 {bfin_write16(SPI0_REGBASE + off, v); } 73 {bfin_write16(spi_regs_base + off, v); }
65 74
66DEFINE_SPI_REG(CTRL, 0x00) 75DEFINE_SPI_REG(CTRL, 0x00)
67DEFINE_SPI_REG(FLAG, 0x04) 76DEFINE_SPI_REG(FLAG, 0x04)
@@ -573,10 +582,10 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
573 struct chip_data *chip = drv_data->cur_chip; 582 struct chip_data *chip = drv_data->cur_chip;
574 583
575 dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n"); 584 dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n");
576 clear_dma_irqstat(CH_SPI); 585 clear_dma_irqstat(spi_dma_ch);
577 586
578 /* Wait for DMA to complete */ 587 /* Wait for DMA to complete */
579 while (get_dma_curr_irqstat(CH_SPI) & DMA_RUN) 588 while (get_dma_curr_irqstat(spi_dma_ch) & DMA_RUN)
580 continue; 589 continue;
581 590
582 /* 591 /*
@@ -586,12 +595,12 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
586 * register until it goes low for 2 successive reads 595 * register until it goes low for 2 successive reads
587 */ 596 */
588 if (drv_data->tx != NULL) { 597 if (drv_data->tx != NULL) {
589 while ((bfin_read_SPI_STAT() & TXS) || 598 while ((read_STAT() & TXS) ||
590 (bfin_read_SPI_STAT() & TXS)) 599 (read_STAT() & TXS))
591 continue; 600 continue;
592 } 601 }
593 602
594 while (!(bfin_read_SPI_STAT() & SPIF)) 603 while (!(read_STAT() & SPIF))
595 continue; 604 continue;
596 605
597 bfin_spi_disable(drv_data); 606 bfin_spi_disable(drv_data);
@@ -610,8 +619,8 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
610 /* free the irq handler before next transfer */ 619 /* free the irq handler before next transfer */
611 dev_dbg(&drv_data->pdev->dev, 620 dev_dbg(&drv_data->pdev->dev,
612 "disable dma channel irq%d\n", 621 "disable dma channel irq%d\n",
613 CH_SPI); 622 spi_dma_ch);
614 dma_disable_irq(CH_SPI); 623 dma_disable_irq(spi_dma_ch);
615 624
616 return IRQ_HANDLED; 625 return IRQ_HANDLED;
617} 626}
@@ -726,19 +735,19 @@ static void pump_transfers(unsigned long data)
726 if (drv_data->cur_chip->enable_dma && drv_data->len > 6) { 735 if (drv_data->cur_chip->enable_dma && drv_data->len > 6) {
727 736
728 write_STAT(BIT_STAT_CLR); 737 write_STAT(BIT_STAT_CLR);
729 disable_dma(CH_SPI); 738 disable_dma(spi_dma_ch);
730 clear_dma_irqstat(CH_SPI); 739 clear_dma_irqstat(spi_dma_ch);
731 bfin_spi_disable(drv_data); 740 bfin_spi_disable(drv_data);
732 741
733 /* config dma channel */ 742 /* config dma channel */
734 dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n"); 743 dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n");
735 if (width == CFG_SPI_WORDSIZE16) { 744 if (width == CFG_SPI_WORDSIZE16) {
736 set_dma_x_count(CH_SPI, drv_data->len); 745 set_dma_x_count(spi_dma_ch, drv_data->len);
737 set_dma_x_modify(CH_SPI, 2); 746 set_dma_x_modify(spi_dma_ch, 2);
738 dma_width = WDSIZE_16; 747 dma_width = WDSIZE_16;
739 } else { 748 } else {
740 set_dma_x_count(CH_SPI, drv_data->len); 749 set_dma_x_count(spi_dma_ch, drv_data->len);
741 set_dma_x_modify(CH_SPI, 1); 750 set_dma_x_modify(spi_dma_ch, 1);
742 dma_width = WDSIZE_8; 751 dma_width = WDSIZE_8;
743 } 752 }
744 753
@@ -753,9 +762,10 @@ static void pump_transfers(unsigned long data)
753 /* no irq in autobuffer mode */ 762 /* no irq in autobuffer mode */
754 dma_config = 763 dma_config =
755 (DMAFLOW_AUTO | RESTART | dma_width | DI_EN); 764 (DMAFLOW_AUTO | RESTART | dma_width | DI_EN);
756 set_dma_config(CH_SPI, dma_config); 765 set_dma_config(spi_dma_ch, dma_config);
757 set_dma_start_addr(CH_SPI, (unsigned long)drv_data->tx); 766 set_dma_start_addr(spi_dma_ch,
758 enable_dma(CH_SPI); 767 (unsigned long)drv_data->tx);
768 enable_dma(spi_dma_ch);
759 write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) | 769 write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
760 (CFG_SPI_ENABLE << 14)); 770 (CFG_SPI_ENABLE << 14));
761 771
@@ -776,14 +786,15 @@ static void pump_transfers(unsigned long data)
776 /* clear tx reg soformer data is not shifted out */ 786 /* clear tx reg soformer data is not shifted out */
777 write_TDBR(0xFF); 787 write_TDBR(0xFF);
778 788
779 set_dma_x_count(CH_SPI, drv_data->len); 789 set_dma_x_count(spi_dma_ch, drv_data->len);
780 790
781 /* start dma */ 791 /* start dma */
782 dma_enable_irq(CH_SPI); 792 dma_enable_irq(spi_dma_ch);
783 dma_config = (WNR | RESTART | dma_width | DI_EN); 793 dma_config = (WNR | RESTART | dma_width | DI_EN);
784 set_dma_config(CH_SPI, dma_config); 794 set_dma_config(spi_dma_ch, dma_config);
785 set_dma_start_addr(CH_SPI, (unsigned long)drv_data->rx); 795 set_dma_start_addr(spi_dma_ch,
786 enable_dma(CH_SPI); 796 (unsigned long)drv_data->rx);
797 enable_dma(spi_dma_ch);
787 798
788 cr |= 799 cr |=
789 CFG_SPI_DMAREAD | (width << 8) | (CFG_SPI_ENABLE << 800 CFG_SPI_DMAREAD | (width << 8) | (CFG_SPI_ENABLE <<
@@ -794,11 +805,12 @@ static void pump_transfers(unsigned long data)
794 dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n"); 805 dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");
795 806
796 /* start dma */ 807 /* start dma */
797 dma_enable_irq(CH_SPI); 808 dma_enable_irq(spi_dma_ch);
798 dma_config = (RESTART | dma_width | DI_EN); 809 dma_config = (RESTART | dma_width | DI_EN);
799 set_dma_config(CH_SPI, dma_config); 810 set_dma_config(spi_dma_ch, dma_config);
800 set_dma_start_addr(CH_SPI, (unsigned long)drv_data->tx); 811 set_dma_start_addr(spi_dma_ch,
801 enable_dma(CH_SPI); 812 (unsigned long)drv_data->tx);
813 enable_dma(spi_dma_ch);
802 814
803 write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) | 815 write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
804 (CFG_SPI_ENABLE << 14)); 816 (CFG_SPI_ENABLE << 14));
@@ -1034,17 +1046,17 @@ static int setup(struct spi_device *spi)
1034 */ 1046 */
1035 if (chip->enable_dma && !dma_requested) { 1047 if (chip->enable_dma && !dma_requested) {
1036 /* register dma irq handler */ 1048 /* register dma irq handler */
1037 if (request_dma(CH_SPI, "BF53x_SPI_DMA") < 0) { 1049 if (request_dma(spi_dma_ch, "BF53x_SPI_DMA") < 0) {
1038 dev_dbg(&spi->dev, 1050 dev_dbg(&spi->dev,
1039 "Unable to request BlackFin SPI DMA channel\n"); 1051 "Unable to request BlackFin SPI DMA channel\n");
1040 return -ENODEV; 1052 return -ENODEV;
1041 } 1053 }
1042 if (set_dma_callback(CH_SPI, (void *)dma_irq_handler, drv_data) 1054 if (set_dma_callback(spi_dma_ch, (void *)dma_irq_handler,
1043 < 0) { 1055 drv_data) < 0) {
1044 dev_dbg(&spi->dev, "Unable to set dma callback\n"); 1056 dev_dbg(&spi->dev, "Unable to set dma callback\n");
1045 return -EPERM; 1057 return -EPERM;
1046 } 1058 }
1047 dma_disable_irq(CH_SPI); 1059 dma_disable_irq(spi_dma_ch);
1048 dma_requested = 1; 1060 dma_requested = 1;
1049 } 1061 }
1050 1062
@@ -1215,6 +1227,7 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
1215 struct bfin5xx_spi_master *platform_info; 1227 struct bfin5xx_spi_master *platform_info;
1216 struct spi_master *master; 1228 struct spi_master *master;
1217 struct driver_data *drv_data = 0; 1229 struct driver_data *drv_data = 0;
1230 struct resource *res;
1218 int status = 0; 1231 int status = 0;
1219 1232
1220 platform_info = dev->platform_data; 1233 platform_info = dev->platform_data;
@@ -1242,15 +1255,38 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
1242 master->setup = setup; 1255 master->setup = setup;
1243 master->transfer = transfer; 1256 master->transfer = transfer;
1244 1257
1258 /* Find and map our resources */
1259 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1260 if (res == NULL) {
1261 dev_err(dev, "Cannot get IORESOURCE_MEM\n");
1262 status = -ENOENT;
1263 goto out_error_get_res;
1264 }
1265
1266 spi_regs_base = (u32) ioremap(res->start, (res->end - res->start)+1);
1267 if (!spi_regs_base) {
1268 dev_err(dev, "Cannot map IO\n");
1269 status = -ENXIO;
1270 goto out_error_ioremap;
1271 }
1272
1273 spi_dma_ch = platform_get_irq(pdev, 0);
1274 if (spi_dma_ch < 0) {
1275 dev_err(dev, "No DMA channel specified\n");
1276 status = -ENOENT;
1277 goto out_error_no_dma_ch;
1278 }
1279
1245 /* Initial and start queue */ 1280 /* Initial and start queue */
1246 status = init_queue(drv_data); 1281 status = init_queue(drv_data);
1247 if (status != 0) { 1282 if (status != 0) {
1248 dev_err(&pdev->dev, "problem initializing queue\n"); 1283 dev_err(dev, "problem initializing queue\n");
1249 goto out_error_queue_alloc; 1284 goto out_error_queue_alloc;
1250 } 1285 }
1286
1251 status = start_queue(drv_data); 1287 status = start_queue(drv_data);
1252 if (status != 0) { 1288 if (status != 0) {
1253 dev_err(&pdev->dev, "problem starting queue\n"); 1289 dev_err(dev, "problem starting queue\n");
1254 goto out_error_queue_alloc; 1290 goto out_error_queue_alloc;
1255 } 1291 }
1256 1292
@@ -1258,14 +1294,20 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
1258 platform_set_drvdata(pdev, drv_data); 1294 platform_set_drvdata(pdev, drv_data);
1259 status = spi_register_master(master); 1295 status = spi_register_master(master);
1260 if (status != 0) { 1296 if (status != 0) {
1261 dev_err(&pdev->dev, "problem registering spi master\n"); 1297 dev_err(dev, "problem registering spi master\n");
1262 goto out_error_queue_alloc; 1298 goto out_error_queue_alloc;
1263 } 1299 }
1264 dev_dbg(&pdev->dev, "controller probe successfully\n"); 1300
1301 dev_info(dev, "%s, Version %s, regs_base @ 0x%08x\n",
1302 DRV_DESC, DRV_VERSION, spi_regs_base);
1265 return status; 1303 return status;
1266 1304
1267out_error_queue_alloc: 1305out_error_queue_alloc:
1268 destroy_queue(drv_data); 1306 destroy_queue(drv_data);
1307out_error_no_dma_ch:
1308 iounmap((void *) spi_regs_base);
1309out_error_ioremap:
1310out_error_get_res:
1269out_error: 1311out_error:
1270 spi_master_put(master); 1312 spi_master_put(master);
1271 1313
@@ -1291,8 +1333,8 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
1291 1333
1292 /* Release DMA */ 1334 /* Release DMA */
1293 if (drv_data->master_info->enable_dma) { 1335 if (drv_data->master_info->enable_dma) {
1294 if (dma_channel_active(CH_SPI)) 1336 if (dma_channel_active(spi_dma_ch))
1295 free_dma(CH_SPI); 1337 free_dma(spi_dma_ch);
1296 } 1338 }
1297 1339
1298 /* Disconnect from the SPI framework */ 1340 /* Disconnect from the SPI framework */
@@ -1347,7 +1389,7 @@ static int bfin5xx_spi_resume(struct platform_device *pdev)
1347MODULE_ALIAS("bfin-spi-master"); /* for platform bus hotplug */ 1389MODULE_ALIAS("bfin-spi-master"); /* for platform bus hotplug */
1348static struct platform_driver bfin5xx_spi_driver = { 1390static struct platform_driver bfin5xx_spi_driver = {
1349 .driver = { 1391 .driver = {
1350 .name = "bfin-spi-master", 1392 .name = DRV_NAME,
1351 .owner = THIS_MODULE, 1393 .owner = THIS_MODULE,
1352 }, 1394 },
1353 .suspend = bfin5xx_spi_suspend, 1395 .suspend = bfin5xx_spi_suspend,