-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
hartleys
authored and
Grant Likely
committed
May 25, 2010
1 parent
cf64197
commit 415c476
Showing
8 changed files
with
99 additions
and
112 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,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 6e27388f1bd60b55e0b1a83d14233e6c7ad33700 | ||
refs/heads/master: 41c4221ca6b9db8ea63d2c2323c0e7a8865eba6e |
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 |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
* Mix this utility code with some glue code to get one of several types of | ||
* simple SPI master driver. Two do polled word-at-a-time I/O: | ||
* | ||
* - GPIO/parport bitbangers. Provide chipselect() and txrx_word[](), | ||
* expanding the per-word routines from the inline templates below. | ||
* | ||
* - Drivers for controllers resembling bare shift registers. Provide | ||
* chipselect() and txrx_word[](), with custom setup()/cleanup() methods | ||
* that use your controller's clock and chipselect registers. | ||
* | ||
* Some hardware works well with requests at spi_transfer scope: | ||
* | ||
* - Drivers leveraging smarter hardware, with fifos or DMA; or for half | ||
* duplex (MicroWire) controllers. Provide chipselect() and txrx_bufs(), | ||
* and custom setup()/cleanup() methods. | ||
*/ | ||
|
||
/* | ||
* The code that knows what GPIO pins do what should have declared four | ||
* functions, ideally as inlines, before including this header: | ||
* | ||
* void setsck(struct spi_device *, int is_on); | ||
* void setmosi(struct spi_device *, int is_on); | ||
* int getmiso(struct spi_device *); | ||
* void spidelay(unsigned); | ||
* | ||
* setsck()'s is_on parameter is a zero/nonzero boolean. | ||
* | ||
* setmosi()'s is_on parameter is a zero/nonzero boolean. | ||
* | ||
* getmiso() is required to return 0 or 1 only. Any other value is invalid | ||
* and will result in improper operation. | ||
* | ||
* A non-inlined routine would call bitbang_txrx_*() routines. The | ||
* main loop could easily compile down to a handful of instructions, | ||
* especially if the delay is a NOP (to run at peak speed). | ||
* | ||
* Since this is software, the timings may not be exactly what your board's | ||
* chips need ... there may be several reasons you'd need to tweak timings | ||
* in these routines, not just make to make it faster or slower to match a | ||
* particular CPU clock rate. | ||
*/ | ||
|
||
static inline u32 | ||
bitbang_txrx_be_cpha0(struct spi_device *spi, | ||
unsigned nsecs, unsigned cpol, | ||
u32 word, u8 bits) | ||
{ | ||
/* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ | ||
|
||
/* clock starts at inactive polarity */ | ||
for (word <<= (32 - bits); likely(bits); bits--) { | ||
|
||
/* setup MSB (to slave) on trailing edge */ | ||
setmosi(spi, word & (1 << 31)); | ||
spidelay(nsecs); /* T(setup) */ | ||
|
||
setsck(spi, !cpol); | ||
spidelay(nsecs); | ||
|
||
/* sample MSB (from slave) on leading edge */ | ||
word <<= 1; | ||
word |= getmiso(spi); | ||
setsck(spi, cpol); | ||
} | ||
return word; | ||
} | ||
|
||
static inline u32 | ||
bitbang_txrx_be_cpha1(struct spi_device *spi, | ||
unsigned nsecs, unsigned cpol, | ||
u32 word, u8 bits) | ||
{ | ||
/* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ | ||
|
||
/* clock starts at inactive polarity */ | ||
for (word <<= (32 - bits); likely(bits); bits--) { | ||
|
||
/* setup MSB (to slave) on leading edge */ | ||
setsck(spi, !cpol); | ||
setmosi(spi, word & (1 << 31)); | ||
spidelay(nsecs); /* T(setup) */ | ||
|
||
setsck(spi, cpol); | ||
spidelay(nsecs); | ||
|
||
/* sample MSB (from slave) on trailing edge */ | ||
word <<= 1; | ||
word |= getmiso(spi); | ||
} | ||
return word; | ||
} |
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
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