diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/spi-imx31.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/spi-imx31.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c new file mode 100644 index 0000000000..7d6e8efd22 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (c) 2007 Will Robertson | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "cpu.h" | ||
20 | #include "spi-imx31.h" | ||
21 | #include "debug.h" | ||
22 | #include "kernel.h" | ||
23 | |||
24 | /* This is all based on communicating with the MC13783 PMU which is on | ||
25 | * CSPI2 with the chip select at 0. The LCD controller resides on | ||
26 | * CSPI3 cs1, but we have no idea how to communicate to it */ | ||
27 | |||
28 | void spi_init(void) { | ||
29 | CSPI_CONREG2 |= (2 << 20); // Burst will be triggered at SPI_RDY low | ||
30 | CSPI_CONREG2 |= (2 << 16); // Clock = IPG_CLK/16 - we want about 20mhz | ||
31 | CSPI_CONREG2 |= (31 << 8); // All 32 bits are to be transferred | ||
32 | CSPI_CONREG2 |= (1 << 3); // Start burst on TXFIFO write. | ||
33 | CSPI_CONREG2 |= (1 << 1); // Master mode. | ||
34 | CSPI_CONREG2 |= 1; // Enable CSPI2; | ||
35 | } | ||
36 | |||
37 | static int spi_transfer(int address, long data, long* buffer, bool read) { | ||
38 | unsigned long packet = 0; | ||
39 | if(!read) { | ||
40 | /* Set the appropriate bit in the packet to indicate a write */ | ||
41 | packet |= (1<<31); | ||
42 | } | ||
43 | /* Set the address of the packet */ | ||
44 | packet |= (address << 25); | ||
45 | |||
46 | /* Ensure data only occupies 24 bits, then mash the data into the packet */ | ||
47 | data &= ~(DATAMASK); | ||
48 | packet |= data; | ||
49 | |||
50 | /* Wait for some room in TXFIFO */ | ||
51 | while(CSPI_STATREG2 & (1<<2)); | ||
52 | |||
53 | /* Send the packet */ | ||
54 | CSPI_TXDATA2 = packet; | ||
55 | |||
56 | /* Poll the XCH bit to wait for the end of the transfer, with | ||
57 | * a one second timeout */ | ||
58 | int newtick = current_tick + HZ; | ||
59 | while((CSPI_CONREG2 & (1<<2)) && (current_tick < newtick)); | ||
60 | |||
61 | if(newtick > current_tick) { | ||
62 | *buffer = CSPI_RXDATA2; | ||
63 | return 0; | ||
64 | } else { | ||
65 | /* Indicate the fact that the transfer timed out */ | ||
66 | return -1; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | void spi_send(int address, unsigned long data) { | ||
71 | long dummy; | ||
72 | if(spi_transfer(address, data, &dummy, false)) { | ||
73 | DEBUGF("SPI Send timed out"); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | void spi_read(int address, unsigned long* buffer) { | ||
78 | if(spi_transfer(address, 0, buffer, true)) { | ||
79 | DEBUGF("SPI read timed out"); | ||
80 | } | ||
81 | } | ||