-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from bradjc/updates
Updated with newest version of rasbian
- Loading branch information
Showing
7 changed files
with
69 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
*.cmd | ||
*.ko.cmd | ||
*.mod.c | ||
*.mod.o | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,7 @@ | |
#include "debug.h" | ||
|
||
#define DRIVER_AUTHOR "Andrew Robinson <[email protected]>" | ||
#define DRIVER_DESC "A driver for the CC2520 radio. Be afraid." | ||
#define DRIVER_DESC "A driver for the CC2520 radio." | ||
#define DRIVER_VERSION "0.5" | ||
|
||
uint8_t debug_print; | ||
|
@@ -58,7 +58,7 @@ int init_module() | |
|
||
memset(&state, 0, sizeof(struct cc2520_state)); | ||
|
||
INFO((KERN_INFO "loading CC2520 Kernel Module v%s...\n", DRIVER_VERSION)); | ||
INFO((KERN_INFO "[CC2520] - Loading kernel module v%s\n", DRIVER_VERSION)); | ||
|
||
err = cc2520_plat_gpio_init(); | ||
if (err) { | ||
|
@@ -127,7 +127,7 @@ int init_module() | |
error6: | ||
cc2520_plat_gpio_free(); | ||
error7: | ||
return 1; | ||
return -1; | ||
} | ||
|
||
void cleanup_module() | ||
|
@@ -136,7 +136,7 @@ void cleanup_module() | |
cc2520_interface_free(); | ||
cc2520_plat_gpio_free(); | ||
cc2520_plat_spi_free(); | ||
INFO((KERN_INFO "Unloading CC2520 Kernel Module...\n")); | ||
INFO((KERN_INFO "[cc2520] - Unloading kernel module\n")); | ||
} | ||
|
||
MODULE_LICENSE("GPL"); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c | ||
index 088cbaa..661a4cb 100644 | ||
index 1744c1e..b648ab4 100644 | ||
--- a/drivers/spi/spi-bcm2708.c | ||
+++ b/drivers/spi/spi-bcm2708.c | ||
@@ -1,7 +1,7 @@ | ||
|
@@ -11,7 +11,7 @@ index 088cbaa..661a4cb 100644 | |
* | ||
* This driver is inspired by: | ||
* spi-ath79.c, Copyright (C) 2009-2011 Gabor Juhos <[email protected]> | ||
@@ -35,6 +35,14 @@ | ||
@@ -35,6 +35,15 @@ | ||
#include <linux/log2.h> | ||
#include <linux/sched.h> | ||
#include <linux/wait.h> | ||
|
@@ -23,10 +23,11 @@ index 088cbaa..661a4cb 100644 | |
+static short processmode=1; | ||
+module_param(processmode,short,0); | ||
+MODULE_PARM_DESC(processmode,"Processing mode: 0=polling, 1=interrupt driven, 2=dma"); | ||
+ | ||
|
||
/* SPI register offsets */ | ||
#define SPI_CS 0x00 | ||
@@ -74,6 +82,37 @@ | ||
@@ -74,6 +83,37 @@ | ||
|
||
#define DRV_NAME "bcm2708_spi" | ||
|
||
|
@@ -64,7 +65,7 @@ index 088cbaa..661a4cb 100644 | |
struct bcm2708_spi { | ||
spinlock_t lock; | ||
void __iomem *base; | ||
@@ -81,14 +120,24 @@ struct bcm2708_spi { | ||
@@ -81,14 +121,24 @@ struct bcm2708_spi { | ||
struct clk *clk; | ||
bool stopping; | ||
|
||
|
@@ -95,7 +96,7 @@ index 088cbaa..661a4cb 100644 | |
}; | ||
|
||
struct bcm2708_spi_state { | ||
@@ -132,75 +181,9 @@ static inline void bcm2708_wr(struct bcm2708_spi *bs, unsigned reg, u32 val) | ||
@@ -132,96 +182,9 @@ static inline void bcm2708_wr(struct bcm2708_spi *bs, unsigned reg, u32 val) | ||
writel(val, bs->base + reg); | ||
} | ||
|
||
|
@@ -113,10 +114,31 @@ index 088cbaa..661a4cb 100644 | |
-static inline void bcm2708_wr_fifo(struct bcm2708_spi *bs, int len) | ||
-{ | ||
- u8 byte; | ||
- u16 val; | ||
- | ||
- if (len > bs->len) | ||
- len = bs->len; | ||
- | ||
- if (unlikely(bcm2708_rd(bs, SPI_CS) & SPI_CS_LEN)) { | ||
- /* LoSSI mode */ | ||
- if (unlikely(len % 2)) { | ||
- printk(KERN_ERR"bcm2708_wr_fifo: length must be even, skipping.\n"); | ||
- bs->len = 0; | ||
- return; | ||
- } | ||
- while (len) { | ||
- if (bs->tx_buf) { | ||
- val = *(const u16 *)bs->tx_buf; | ||
- bs->tx_buf += 2; | ||
- } else | ||
- val = 0; | ||
- bcm2708_wr(bs, SPI_FIFO, val); | ||
- bs->len -= 2; | ||
- len -= 2; | ||
- } | ||
- return; | ||
- } | ||
- | ||
- while (len--) { | ||
- byte = bs->tx_buf ? *bs->tx_buf++ : 0; | ||
- bcm2708_wr(bs, SPI_FIFO, byte); | ||
|
@@ -173,7 +195,7 @@ index 088cbaa..661a4cb 100644 | |
{ | ||
struct bcm2708_spi *bs = spi_master_get_devdata(master); | ||
int cdiv; | ||
@@ -259,96 +242,468 @@ static int bcm2708_setup_state(struct spi_master *master, | ||
@@ -284,97 +247,468 @@ static int bcm2708_setup_state(struct spi_master *master, | ||
if (state) { | ||
state->cs = cs; | ||
state->cdiv = cdiv; | ||
|
@@ -228,7 +250,8 @@ index 088cbaa..661a4cb 100644 | |
- ret = bcm2708_setup_state(spi->master, &spi->dev, &state, | ||
- xfer->speed_hz ? xfer->speed_hz : spi->max_speed_hz, | ||
- spi->chip_select, spi->mode, | ||
- spi->bits_per_word); | ||
- xfer->bits_per_word ? xfer->bits_per_word : | ||
- spi->bits_per_word); | ||
- if (ret) | ||
- return ret; | ||
+static int bcm2708_register_dmabuffer(struct platform_device *pdev, | ||
|
@@ -286,8 +309,7 @@ index 088cbaa..661a4cb 100644 | |
+ /* return IRQ handled */ | ||
+ return IRQ_HANDLED; | ||
+} | ||
|
||
- cs = stp->cs | SPI_CS_INTR | SPI_CS_INTD | SPI_CS_TA; | ||
+ | ||
+/* We could improve on DMA options, by chaining individual xfer messages | ||
+ into a more complex CB chain that takes care of all the transfers in one "go" | ||
+ resulting in only one interrupt getting delivered at the end of the sequence. | ||
|
@@ -344,7 +366,8 @@ index 088cbaa..661a4cb 100644 | |
+ } | ||
+ /* auto deselect CS if it is the last */ | ||
+ if (flags&FLAGS_LAST_TRANSFER) { cs|=SPI_CS_ADCS; } | ||
+ | ||
|
||
- cs = stp->cs | SPI_CS_INTR | SPI_CS_INTD | SPI_CS_TA; | ||
+ /* store data for interrupts and more */ | ||
+ bs->rx_buf=xfer->rx_buf; | ||
+ bs->tx_buf=xfer->tx_buf; | ||
|
@@ -461,7 +484,9 @@ index 088cbaa..661a4cb 100644 | |
+ (bs->rx_len)--; | ||
+ } | ||
+ spin_unlock(&bs->lock); | ||
+ | ||
|
||
- if (xfer->delay_usecs) | ||
- udelay(xfer->delay_usecs); | ||
+ /* and if we have rx_len as 0 then wakeup the process */ | ||
+ if (bs->rx_len==0) { | ||
+ /* clean the transfers including all interrupts */ | ||
|
@@ -470,9 +495,7 @@ index 088cbaa..661a4cb 100644 | |
+ /* and wake up the thread to continue its work */ | ||
+ complete(&bs->done); | ||
+ } | ||
|
||
- if (xfer->delay_usecs) | ||
- udelay(xfer->delay_usecs); | ||
+ | ||
+ /* return IRQ handled */ | ||
+ return IRQ_HANDLED; | ||
+} | ||
|
@@ -566,7 +589,10 @@ index 088cbaa..661a4cb 100644 | |
- spin_unlock_irqrestore(&bs->lock, flags); | ||
+ /* increment type counter */ | ||
+ bs->transfers_polling++; | ||
+ | ||
|
||
- list_for_each_entry(xfer, &msg->transfers, transfer_list) { | ||
- status = bcm2708_process_transfer(bs, msg, xfer); | ||
- if (status) | ||
+ /* start by setting up the SPI controller */ | ||
+ cs=stp->cs|SPI_CS_TA; | ||
+ bcm2708_wr(bs, SPI_CLK, stp->cdiv); | ||
|
@@ -597,10 +623,7 @@ index 088cbaa..661a4cb 100644 | |
+ /* and return OK */ | ||
+ return 0; | ||
+} | ||
|
||
- list_for_each_entry(xfer, &msg->transfers, transfer_list) { | ||
- status = bcm2708_process_transfer(bs, msg, xfer); | ||
- if (status) | ||
+ | ||
+/* this one sends a message */ | ||
+static int bcm2708_transfer_one_message(struct spi_master *master, | ||
+ struct spi_message* msg) { | ||
|
@@ -701,7 +724,7 @@ index 088cbaa..661a4cb 100644 | |
} | ||
|
||
static int bcm2708_spi_setup(struct spi_device *spi) | ||
@@ -357,11 +712,13 @@ static int bcm2708_spi_setup(struct spi_device *spi) | ||
@@ -383,11 +717,13 @@ static int bcm2708_spi_setup(struct spi_device *spi) | ||
struct bcm2708_spi_state *state; | ||
int ret; | ||
|
||
|
@@ -716,7 +739,7 @@ index 088cbaa..661a4cb 100644 | |
dev_dbg(&spi->dev, | ||
"setup: invalid chipselect %u (%u defined)\n", | ||
spi->chip_select, spi->master->num_chipselect); | ||
@@ -378,12 +735,11 @@ static int bcm2708_spi_setup(struct spi_device *spi) | ||
@@ -404,12 +740,11 @@ static int bcm2708_spi_setup(struct spi_device *spi) | ||
} | ||
|
||
ret = bcm2708_setup_state(spi->master, &spi->dev, state, | ||
|
@@ -731,7 +754,7 @@ index 088cbaa..661a4cb 100644 | |
} | ||
|
||
dev_dbg(&spi->dev, | ||
@@ -394,48 +750,6 @@ static int bcm2708_spi_setup(struct spi_device *spi) | ||
@@ -420,48 +755,6 @@ static int bcm2708_spi_setup(struct spi_device *spi) | ||
return 0; | ||
} | ||
|
||
|
@@ -780,15 +803,15 @@ index 088cbaa..661a4cb 100644 | |
static void bcm2708_spi_cleanup(struct spi_device *spi) | ||
{ | ||
if (spi->controller_state) { | ||
@@ -451,6 +765,7 @@ static int __devinit bcm2708_spi_probe(struct platform_device *pdev) | ||
@@ -477,6 +770,7 @@ static int __devinit bcm2708_spi_probe(struct platform_device *pdev) | ||
struct clk *clk; | ||
struct spi_master *master; | ||
struct bcm2708_spi *bs; | ||
+ const char* mode; | ||
|
||
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
if (!regs) { | ||
@@ -484,40 +799,75 @@ static int __devinit bcm2708_spi_probe(struct platform_device *pdev) | ||
@@ -510,16 +804,25 @@ static int __devinit bcm2708_spi_probe(struct platform_device *pdev) | ||
master->bus_num = pdev->id; | ||
master->num_chipselect = 3; | ||
master->setup = bcm2708_spi_setup; | ||
|
@@ -802,23 +825,23 @@ index 088cbaa..661a4cb 100644 | |
+ | ||
platform_set_drvdata(pdev, master); | ||
|
||
- bs = spi_master_get_devdata(master); | ||
|
||
+ bs = spi_master_get_devdata(master); | ||
bs = spi_master_get_devdata(master); | ||
- | ||
spin_lock_init(&bs->lock); | ||
- INIT_LIST_HEAD(&bs->queue); | ||
init_completion(&bs->done); | ||
- INIT_WORK(&bs->work, bcm2708_work); | ||
+ | ||
+ /* set counters */ | ||
+ bs->transfers_polling=0; | ||
+ bs->transfers_irqdriven=0; | ||
+ bs->transfers_dmadriven=0; | ||
+ | ||
+ /* get Register Map */ | ||
|
||
bs->base = ioremap(regs->start, resource_size(regs)); | ||
if (!bs->base) { | ||
dev_err(&pdev->dev, "could not remap memory\n"); | ||
@@ -527,21 +830,46 @@ static int __devinit bcm2708_spi_probe(struct platform_device *pdev) | ||
goto out_master_put; | ||
} | ||
|
||
|
@@ -872,11 +895,8 @@ index 088cbaa..661a4cb 100644 | |
+ goto out_free_dma_tx; | ||
} | ||
|
||
+ | ||
/* initialise the hardware */ | ||
clk_enable(clk); | ||
bcm2708_wr(bs, SPI_CS, SPI_CS_REN | SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX); | ||
@@ -525,18 +875,35 @@ static int __devinit bcm2708_spi_probe(struct platform_device *pdev) | ||
@@ -551,18 +879,36 @@ static int __devinit bcm2708_spi_probe(struct platform_device *pdev) | ||
err = spi_register_master(master); | ||
if (err) { | ||
dev_err(&pdev->dev, "could not register SPI master: %d\n", err); | ||
|
@@ -900,7 +920,7 @@ index 088cbaa..661a4cb 100644 | |
+ } | ||
+ dev_info(&pdev->dev, "SPI Controller running in %s mode\n",mode); | ||
return 0; | ||
- | ||
+out_free_dma_irq: | ||
+ free_irq(bs->dma_rx.irq, master); | ||
+out_free_dma_tx: | ||
|
@@ -916,7 +936,7 @@ index 088cbaa..661a4cb 100644 | |
out_iounmap: | ||
iounmap(bs->base); | ||
out_master_put: | ||
@@ -551,19 +918,29 @@ static int __devexit bcm2708_spi_remove(struct platform_device *pdev) | ||
@@ -577,19 +923,29 @@ static int __devexit bcm2708_spi_remove(struct platform_device *pdev) | ||
struct spi_master *master = platform_get_drvdata(pdev); | ||
struct bcm2708_spi *bs = spi_master_get_devdata(master); | ||
|
||
|
@@ -950,18 +970,18 @@ index 088cbaa..661a4cb 100644 | |
spi_unregister_master(master); | ||
|
||
return 0; | ||
@@ -581,6 +958,10 @@ static struct platform_driver bcm2708_spi_driver = { | ||
@@ -607,6 +963,10 @@ static struct platform_driver bcm2708_spi_driver = { | ||
|
||
static int __init bcm2708_spi_init(void) | ||
{ | ||
+ /* range check for processmode */ | ||
+ if ((processmode<0) || (processmode>3)) { | ||
+ processmode=1; | ||
+ /* range check for processmode */ | ||
+ if ((processmode<0) || (processmode>3)) { | ||
+ processmode=1; | ||
+ } | ||
return platform_driver_probe(&bcm2708_spi_driver, bcm2708_spi_probe); | ||
} | ||
module_init(bcm2708_spi_init); | ||
@@ -591,10 +972,9 @@ static void __exit bcm2708_spi_exit(void) | ||
@@ -617,10 +977,9 @@ static void __exit bcm2708_spi_exit(void) | ||
} | ||
module_exit(bcm2708_spi_exit); | ||
|
||
|