summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoen Hirschberg <marcoen@gmail.com>2007-05-11 16:42:53 +0000
committerMarcoen Hirschberg <marcoen@gmail.com>2007-05-11 16:42:53 +0000
commit685001f0d41c84ed123b8946b45397bf4e8a097e (patch)
tree4d53be7e5b3126784d163fd266c8addcc56ba7c0
parentd92e09556fdec3fbd65e153c6f41c31cb1e04c42 (diff)
downloadrockbox-685001f0d41c84ed123b8946b45397bf4e8a097e.tar.gz
rockbox-685001f0d41c84ed123b8946b45397bf4e8a097e.zip
revert the last changes because they prevent some Gigabeats from shutting down
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13372 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c201
1 files changed, 111 insertions, 90 deletions
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c
index c207e310d9..e69eab432a 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c
@@ -1,5 +1,6 @@
1#include "config.h" 1#include "config.h"
2#include "cpu.h" 2#include "cpu.h"
3#include <stdbool.h>
3#include "kernel.h" 4#include "kernel.h"
4#include "system.h" 5#include "system.h"
5#include "logf.h" 6#include "logf.h"
@@ -8,132 +9,147 @@
8 9
9#define SLAVE_ADDRESS 0xCC 10#define SLAVE_ADDRESS 0xCC
10 11
11#define USE_ASM 12#define SDA_LO (GPHDAT &= ~(1 << 9))
12 13#define SDA_HI (GPHDAT |= (1 << 9))
13/* This I2C driver tristates the outputs instead of driving logic high's */ 14#define SDA_INPUT (GPHCON &= ~(3 << 18))
15#define SDA_OUTPUT (GPHCON |= (1 << 18))
14#define SDA (GPHDAT & (1 << 9)) 16#define SDA (GPHDAT & (1 << 9))
15#define SDA_LO_OUT (GPHCON |= (1 << 18));(GPHDAT &= ~(1 << 9));
16#define SDA_HI_IN (GPHCON &= ~(3 << 18))
17 17
18#define SCL_LO (GPHDAT &= ~(1 << 10))
19#define SCL_HI (GPHDAT |= (1 << 10))
20#define SCL_INPUT (GPHCON &= ~(3 << 20))
21#define SCL_OUTPUT (GPHCON |= (1 << 20))
18#define SCL (GPHDAT & (1 << 10)) 22#define SCL (GPHDAT & (1 << 10))
19#define SCL_LO_OUT (GPHCON |= (1 << 20));(GPHDAT &= ~(1 << 10)); 23
20#define SCL_HI_IN (GPHCON &= ~(3 << 20));while(!SCL); 24#define SCL_SDA_HI (GPHDAT |= (3 << 9))
21 25
22/* The SC606 can clock at 400KHz: 26/* The SC606 can clock at 400KHz: */
23 * Clock period high is 600nS and low is 1300nS 27/* Clock period high is 600nS and low is 1300nS */
24 * The high and low times are different enough to need different timings 28/* The high and low times are different enough to need different timings */
25 * cycles delayed = 2 + 4 * loops 29/* cycles delayed = 30 + 7 * loops */
26 * 100MHz = 10nS per cycle: LO:1300nS=130:33 HI:600nS=60:15 30/* 100MHz = 10nS per cycle: LO:1300nS=130:14 HI:600nS=60:9 */
27 * 300MHz = 3.33nS per cycle: 31/* 300MHz = 3.36nS per cycle: LO:1300nS=387:51 HI:600nS=179:21 */
28 * LO:1300nS=394:99 32#define DELAY_LO do{int x;for(x=51;x;x--);} while (0)
29 * HI:600nS=182:21 33#define DELAY do{int x;for(x=35;x;x--);} while (0)
30 * MID(50/50):950(1900/2)ns=288:72 34#define DELAY_HI do{int x;for(x=21;x;x--);} while (0)
31 */ 35
32 36
33#ifdef USE_ASM
34
35#define DELAY_LO 99
36#define DELAY_MID 72
37#define DELAY_HI 46
38/* This delay loop takes 4 cycles/loop to execute plus 2 for setup */
39#define DELAY(dly) \
40 asm volatile( "mov r0,%0 \n" \
41 "1: \n" \
42 "subs r0,r0,#1 \n" \
43 "bhi 1b \n" \
44 : : "r"((dly)) : "r0" );
45
46#else
47
48#define DELAY_LO 51
49#define DELAY_MID 35
50#define DELAY_HI 21
51#define DELAY(dly) do{int x;for(x=(dly);x;x--);} while (0)
52
53#endif
54 37
55static void sc606_i2c_start(void) 38static void sc606_i2c_start(void)
56{ 39{
57 SDA_HI_IN; 40 SCL_SDA_HI;
58 SCL_HI_IN; 41 DELAY;
59 DELAY(DELAY_MID); 42 SDA_LO;
60 SDA_LO_OUT; 43 DELAY;
61 DELAY(DELAY_MID); 44 SCL_LO;
62 SCL_LO_OUT; 45}
46
47static void sc606_i2c_restart(void)
48{
49 SCL_SDA_HI;
50 DELAY;
51 SDA_LO;
52 DELAY;
53 SCL_LO;
63} 54}
64 55
65static void sc606_i2c_stop(void) 56static void sc606_i2c_stop(void)
66{ 57{
67 SDA_LO_OUT; 58 SDA_LO;
68 SCL_HI_IN; 59 SCL_HI;
69 DELAY(DELAY_HI); 60 DELAY_HI;
70 SDA_HI_IN; 61 SDA_HI;
71} 62}
72 63
73static void sc606_i2c_ack(void) 64static void sc606_i2c_ack(void)
74{ 65{
75 SDA_HI_IN;
76 SCL_HI_IN;
77 66
78 DELAY(DELAY_HI); 67 SDA_LO;
79 SCL_LO_OUT; 68 SCL_HI;
69 DELAY_HI;
70 SCL_LO;
80} 71}
81 72
82static bool sc606_i2c_getack(void) 73
74
75static int sc606_i2c_getack(void)
83{ 76{
84 bool ret; 77 int ret;
78
79 /* Don't need a delay since follows a data bit with a delay on the end */
80 SDA_INPUT; /* And set to input */
81 DELAY;
82 SCL_HI;
85 83
86 SDA_HI_IN; 84 ret = (SDA != 0); /* ack failed if SDA is not low */
87 DELAY(DELAY_MID); 85 DELAY_HI;
88 SCL_HI_IN;
89 86
90 ret = !SDA; 87 SCL_LO;
88 DELAY_LO;
91 89
92 SCL_LO_OUT; 90 SDA_HI;
93 DELAY(DELAY_LO); 91 SDA_OUTPUT;
92 DELAY_LO;
94 93
95 return ret; 94 return ret;
96} 95}
97 96
97
98
98static void sc606_i2c_outb(unsigned char byte) 99static void sc606_i2c_outb(unsigned char byte)
99{ 100{
100 int i; 101 int i;
101 102
102 /* clock out each bit, MSB first */ 103 /* clock out each bit, MSB first */
103 for ( i=0x80; i; i>>=1 ) 104 for (i = 0x80; i; i >>= 1)
104 { 105 {
105 if ( i & byte ) 106 if (i & byte)
106 SDA_HI_IN; 107 {
108 SDA_HI;
109 }
107 else 110 else
108 SDA_LO_OUT; 111 {
109 DELAY(DELAY_MID); 112 SDA_LO;
110 SCL_HI_IN; 113 }
111 DELAY(DELAY_HI); 114 DELAY;
112 SCL_LO_OUT; 115
116 SCL_HI;
117 DELAY_HI;
118
119 SCL_LO;
120 DELAY_LO;
113 } 121 }
122
123 SDA_HI;
124
114} 125}
115 126
127
128
116static unsigned char sc606_i2c_inb(void) 129static unsigned char sc606_i2c_inb(void)
117{ 130{
118 int i; 131 int i;
119 unsigned char byte = 0; 132 unsigned char byte = 0;
120 133
121 /* clock in each bit, MSB first */ 134 SDA_INPUT; /* And set to input */
122 SDA_HI_IN; 135 /* clock in each bit, MSB first */
123 for ( i=0x80; i; i>>=1 ) 136 for (i = 0x80; i; i >>= 1) {
124 { 137 SCL_HI;
125 SCL_HI_IN; 138
126 DELAY(DELAY_HI); 139 if (SDA)
127 if ( SDA ) 140 byte |= i;
128 byte |= i;
129 SCL_LO_OUT;
130 DELAY(DELAY_LO);
131 }
132 141
133 sc606_i2c_ack(); 142 SCL_LO;
134 return byte; 143 }
144 SDA_OUTPUT;
145
146 sc606_i2c_ack();
147
148 return byte;
135} 149}
136 150
151
152
137/* returns number of acks that were bad */ 153/* returns number of acks that were bad */
138int sc606_write(unsigned char reg, unsigned char data) 154int sc606_write(unsigned char reg, unsigned char data)
139{ 155{
@@ -147,7 +163,7 @@ int sc606_write(unsigned char reg, unsigned char data)
147 sc606_i2c_outb(reg); 163 sc606_i2c_outb(reg);
148 x += sc606_i2c_getack(); 164 x += sc606_i2c_getack();
149 165
150 sc606_i2c_start(); 166 sc606_i2c_restart();
151 167
152 sc606_i2c_outb(SLAVE_ADDRESS); 168 sc606_i2c_outb(SLAVE_ADDRESS);
153 x += sc606_i2c_getack(); 169 x += sc606_i2c_getack();
@@ -160,6 +176,8 @@ int sc606_write(unsigned char reg, unsigned char data)
160 return x; 176 return x;
161} 177}
162 178
179
180
163int sc606_read(unsigned char reg, unsigned char* data) 181int sc606_read(unsigned char reg, unsigned char* data)
164{ 182{
165 int x; 183 int x;
@@ -171,7 +189,7 @@ int sc606_read(unsigned char reg, unsigned char* data)
171 sc606_i2c_outb(reg); 189 sc606_i2c_outb(reg);
172 x += sc606_i2c_getack(); 190 x += sc606_i2c_getack();
173 191
174 sc606_i2c_start(); 192 sc606_i2c_restart();
175 sc606_i2c_outb(SLAVE_ADDRESS | 1); 193 sc606_i2c_outb(SLAVE_ADDRESS | 1);
176 x += sc606_i2c_getack(); 194 x += sc606_i2c_getack();
177 195
@@ -181,6 +199,8 @@ int sc606_read(unsigned char reg, unsigned char* data)
181 return x; 199 return x;
182} 200}
183 201
202
203
184void sc606_init(void) 204void sc606_init(void)
185{ 205{
186 volatile int i; 206 volatile int i;
@@ -194,11 +214,12 @@ void sc606_init(void)
194 214
195 /* About 400us - needs 350us */ 215 /* About 400us - needs 350us */
196 for (i = 200; i; i--) 216 for (i = 200; i; i--)
197 DELAY(DELAY_LO); 217 {
218 DELAY_LO;
219 }
198 220
199 /* Set GPH9 (SDA) and GPH10 (SCL) to 1 */ 221 /* Set GPH9 (SDA) and GPH10 (SCL) to 1 */
200 GPHUP &= ~(3<<9); 222 GPHUP &= ~(3<<9);
201 SCL_HI_IN; 223 GPHCON = (GPHCON & ~(0xF<<18)) | 5<<18;
202 SDA_HI_IN;
203} 224}
204 225