diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/s5l8702/spi-s5l8702.c | 112 | ||||
-rw-r--r-- | firmware/target/arm/s5l8702/spi-s5l8702.h | 32 |
2 files changed, 144 insertions, 0 deletions
diff --git a/firmware/target/arm/s5l8702/spi-s5l8702.c b/firmware/target/arm/s5l8702/spi-s5l8702.c new file mode 100644 index 0000000000..581c0818d3 --- /dev/null +++ b/firmware/target/arm/s5l8702/spi-s5l8702.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: | ||
9 | * | ||
10 | * Copyright © 2009 Michael Sparmann | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include <stdint.h> | ||
22 | #include <stdbool.h> | ||
23 | |||
24 | #include "config.h" | ||
25 | #include "s5l8702.h" | ||
26 | #include "clocking-s5l8702.h" | ||
27 | #include "spi-s5l8702.h" | ||
28 | |||
29 | #define SPI_N_PORT 3 | ||
30 | |||
31 | static int clkdiv[SPI_N_PORT] = {4, 4, 4}; | ||
32 | |||
33 | /* configure SPI clock, speed is PClk/(div+1) (TBC) */ | ||
34 | void spi_clkdiv(int port, int div) | ||
35 | { | ||
36 | clkdiv[port] = div; | ||
37 | } | ||
38 | |||
39 | /* state: 1 -> route GPIO ports to SPI controller | ||
40 | * 0 -> set GPIO to lowest power consumption | ||
41 | */ | ||
42 | void spi_init(int port, bool state) | ||
43 | { | ||
44 | uint32_t val = state ? 0x2222 : 0xEEEF; | ||
45 | switch (port) | ||
46 | { | ||
47 | case 0: | ||
48 | PCON0 = (PCON0 & ~0xffff) | val; | ||
49 | break; | ||
50 | case 1: | ||
51 | PCON6 = (PCON6 & ~0xffff0000) | (val << 16); | ||
52 | break; | ||
53 | case 2: | ||
54 | PCONE = (PCONE & ~0xff000000) | (val << 24); | ||
55 | PCONF = (PCONF & ~0xff) | (val >> 8); | ||
56 | break; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | /* nSS pin: output LOW -> external device SLAVE | ||
61 | * output HIGH -> deactivate external SLAVE device | ||
62 | * input LOW -> SLAVE condition (external MASTER device) | ||
63 | */ | ||
64 | void spi_ce(int port, bool state) | ||
65 | { | ||
66 | uint32_t level = state ? 0 : 1; | ||
67 | switch (port) | ||
68 | { | ||
69 | case 0: GPIOCMD = 0x0000e | level; break; | ||
70 | case 1: GPIOCMD = 0x6040e | level; break; | ||
71 | case 2: GPIOCMD = 0xe060e | level; break; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | void spi_prepare(int port) | ||
76 | { | ||
77 | clockgate_enable(SPICLKGATE(port), true); | ||
78 | SPISTATUS(port) = 0xf; | ||
79 | SPICTRL(port) |= 0xc; | ||
80 | SPICLKDIV(port) = clkdiv[port]; | ||
81 | SPIPIN(port) = 6; | ||
82 | SPISETUP(port) = 0x10618; | ||
83 | SPICTRL(port) |= 0xc; | ||
84 | SPICTRL(port) = 1; | ||
85 | } | ||
86 | |||
87 | void spi_release(int port) | ||
88 | { | ||
89 | clockgate_enable(SPICLKGATE(port), false); | ||
90 | } | ||
91 | |||
92 | uint32_t spi_write(int port, uint32_t data) | ||
93 | { | ||
94 | SPIRXLIMIT(port) = 1; | ||
95 | while ((SPISTATUS(port) & 0x1f0) == 0x100); | ||
96 | SPITXDATA(port) = data; | ||
97 | while (!(SPISTATUS(port) & 0x3e00)); | ||
98 | return SPIRXDATA(port); | ||
99 | } | ||
100 | |||
101 | void spi_read(int port, uint32_t size, void* buf) | ||
102 | { | ||
103 | uint8_t* buffer = (uint8_t*)buf; | ||
104 | SPIRXLIMIT(port) = size; | ||
105 | SPISETUP(port) |= 1; | ||
106 | while (size--) | ||
107 | { | ||
108 | while (!(SPISTATUS(port) & 0x3e00)); | ||
109 | *buffer++ = SPIRXDATA(port); | ||
110 | } | ||
111 | SPISETUP(port) &= ~1; | ||
112 | } | ||
diff --git a/firmware/target/arm/s5l8702/spi-s5l8702.h b/firmware/target/arm/s5l8702/spi-s5l8702.h new file mode 100644 index 0000000000..98235c1840 --- /dev/null +++ b/firmware/target/arm/s5l8702/spi-s5l8702.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: | ||
9 | * | ||
10 | * Copyright © 2009 Michael Sparmann | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef __SPI_S5L8702_H__ | ||
22 | #define __SPI_S5L8702_H__ | ||
23 | |||
24 | void spi_init(int port, bool state); | ||
25 | void spi_ce(int port, bool state); | ||
26 | void spi_prepare(int port); | ||
27 | void spi_release(int port); | ||
28 | void spi_read(int port, uint32_t size, void* buf); | ||
29 | uint32_t spi_write(int port, uint32_t data); | ||
30 | void spi_clkdiv(int port, int div); | ||
31 | |||
32 | #endif /* __SPI_S5L8702_H__ */ | ||