Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Apple Peripheral System Controller (PSC) | |
3 | * | |
4 | * The PSC is used on the AV Macs to control IO functions not handled | |
5 | * by the VIAs (Ethernet, DSP, SCC, Sound). This includes nine DMA | |
6 | * channels. | |
7 | * | |
8 | * The first seven DMA channels appear to be "one-shot" and are actually | |
9 | * sets of two channels; one member is active while the other is being | |
10 | * configured, and then you flip the active member and start all over again. | |
11 | * The one-shot channels are grouped together and are: | |
12 | * | |
13 | * 1. SCSI | |
14 | * 2. Ethernet Read | |
15 | * 3. Ethernet Write | |
16 | * 4. Floppy Disk Controller | |
17 | * 5. SCC Channel A Receive | |
18 | * 6. SCC Channel B Receive | |
19 | * 7. SCC Channel A Transmit | |
20 | * | |
21 | * The remaining two channels are handled somewhat differently. They appear | |
22 | * to be closely tied and share one set of registers. They also seem to run | |
23 | * continuously, although how you keep the buffer filled in this scenario is | |
24 | * not understood as there seems to be only one input and one output buffer | |
25 | * pointer. | |
26 | * | |
27 | * Much of this was extrapolated from what was known about the Ethernet | |
28 | * registers and subsequently confirmed using MacsBug (ie by pinging the | |
29 | * machine with easy-to-find patterns and looking for them in the DMA | |
30 | * buffers, or by sending a file over the serial ports and finding the | |
31 | * file in the buffers.) | |
32 | * | |
33 | * 1999-05-25 (jmt) | |
34 | */ | |
35 | ||
36 | #define PSC_BASE (0x50F31000) | |
37 | ||
38 | /* | |
39 | * The IER/IFR registers work like the VIA, except that it has 4 | |
40 | * of them each on different interrupt levels, and each register | |
41 | * set only seems to handle four interrupts instead of seven. | |
42 | * | |
43 | * To access a particular set of registers, add 0xn0 to the base | |
44 | * where n = 3,4,5 or 6. | |
45 | */ | |
46 | ||
47 | #define pIFRbase 0x100 | |
48 | #define pIERbase 0x104 | |
49 | ||
50 | /* | |
51 | * One-shot DMA control registers | |
52 | */ | |
53 | ||
54 | #define PSC_MYSTERY 0x804 | |
55 | ||
56 | #define PSC_CTL_BASE 0xC00 | |
57 | ||
58 | #define PSC_SCSI_CTL 0xC00 | |
59 | #define PSC_ENETRD_CTL 0xC10 | |
60 | #define PSC_ENETWR_CTL 0xC20 | |
61 | #define PSC_FDC_CTL 0xC30 | |
62 | #define PSC_SCCA_CTL 0xC40 | |
63 | #define PSC_SCCB_CTL 0xC50 | |
64 | #define PSC_SCCATX_CTL 0xC60 | |
65 | ||
66 | /* | |
67 | * DMA channels. Add +0x10 for the second channel in the set. | |
68 | * You're supposed to use one channel while the other runs and | |
69 | * then flip channels and do the whole thing again. | |
70 | */ | |
71 | ||
72 | #define PSC_ADDR_BASE 0x1000 | |
73 | #define PSC_LEN_BASE 0x1004 | |
74 | #define PSC_CMD_BASE 0x1008 | |
75 | ||
76 | #define PSC_SET0 0x00 | |
77 | #define PSC_SET1 0x10 | |
78 | ||
79 | #define PSC_SCSI_ADDR 0x1000 /* confirmed */ | |
80 | #define PSC_SCSI_LEN 0x1004 /* confirmed */ | |
81 | #define PSC_SCSI_CMD 0x1008 /* confirmed */ | |
82 | #define PSC_ENETRD_ADDR 0x1020 /* confirmed */ | |
83 | #define PSC_ENETRD_LEN 0x1024 /* confirmed */ | |
84 | #define PSC_ENETRD_CMD 0x1028 /* confirmed */ | |
85 | #define PSC_ENETWR_ADDR 0x1040 /* confirmed */ | |
86 | #define PSC_ENETWR_LEN 0x1044 /* confirmed */ | |
87 | #define PSC_ENETWR_CMD 0x1048 /* confirmed */ | |
88 | #define PSC_FDC_ADDR 0x1060 /* strongly suspected */ | |
89 | #define PSC_FDC_LEN 0x1064 /* strongly suspected */ | |
90 | #define PSC_FDC_CMD 0x1068 /* strongly suspected */ | |
91 | #define PSC_SCCA_ADDR 0x1080 /* confirmed */ | |
92 | #define PSC_SCCA_LEN 0x1084 /* confirmed */ | |
93 | #define PSC_SCCA_CMD 0x1088 /* confirmed */ | |
94 | #define PSC_SCCB_ADDR 0x10A0 /* confirmed */ | |
95 | #define PSC_SCCB_LEN 0x10A4 /* confirmed */ | |
96 | #define PSC_SCCB_CMD 0x10A8 /* confirmed */ | |
97 | #define PSC_SCCATX_ADDR 0x10C0 /* confirmed */ | |
98 | #define PSC_SCCATX_LEN 0x10C4 /* confirmed */ | |
99 | #define PSC_SCCATX_CMD 0x10C8 /* confirmed */ | |
100 | ||
101 | /* | |
102 | * Free-running DMA registers. The only part known for sure are the bits in | |
103 | * the control register, the buffer addresses and the buffer length. Everything | |
104 | * else is anybody's guess. | |
105 | * | |
106 | * These registers seem to be mirrored every thirty-two bytes up until offset | |
107 | * 0x300. It's safe to assume then that a new set of registers starts there. | |
108 | */ | |
109 | ||
110 | #define PSC_SND_CTL 0x200 /* | |
111 | * [ 16-bit ] | |
112 | * Sound (Singer?) control register. | |
113 | * | |
114 | * bit 0 : ???? | |
115 | * bit 1 : ???? | |
116 | * bit 2 : Set to one to enable sound | |
117 | * output. Possibly a mute flag. | |
118 | * bit 3 : ???? | |
119 | * bit 4 : ???? | |
120 | * bit 5 : ???? | |
121 | * bit 6 : Set to one to enable pass-thru | |
122 | * audio. In this mode the audio data | |
123 | * seems to appear in both the input | |
124 | * buffer and the output buffer. | |
125 | * bit 7 : Set to one to activate the | |
126 | * sound input DMA or zero to | |
127 | * disable it. | |
128 | * bit 8 : Set to one to activate the | |
129 | * sound output DMA or zero to | |
130 | * disable it. | |
131 | * bit 9 : \ | |
132 | * bit 11 : | | |
133 | * These two bits control the sample | |
134 | * rate. Usually set to binary 10 and | |
135 | * MacOS 8.0 says I'm at 48 KHz. Using | |
136 | * a binary value of 01 makes things | |
137 | * sound about 1/2 speed (24 KHz?) and | |
138 | * binary 00 is slower still (22 KHz?) | |
139 | * | |
140 | * Setting this to 0x0000 is a good way to | |
141 | * kill all DMA at boot time so that the | |
142 | * PSC won't overwrite the kernel image | |
143 | * with sound data. | |
144 | */ | |
145 | ||
146 | /* | |
147 | * 0x0202 - 0x0203 is unused. Writing there | |
148 | * seems to clobber the control register. | |
149 | */ | |
150 | ||
151 | #define PSC_SND_SOURCE 0x204 /* | |
152 | * [ 32-bit ] | |
153 | * Controls input source and volume: | |
154 | * | |
155 | * bits 12-15 : input source volume, 0 - F | |
156 | * bits 16-19 : unknown, always 0x5 | |
157 | * bits 20-23 : input source selection: | |
158 | * 0x3 = CD Audio | |
159 | * 0x4 = External Audio | |
160 | * | |
161 | * The volume is definitely not the general | |
162 | * output volume as it doesn't affect the | |
163 | * alert sound volume. | |
164 | */ | |
165 | #define PSC_SND_STATUS1 0x208 /* | |
166 | * [ 32-bit ] | |
167 | * Appears to be a read-only status register. | |
168 | * The usual value is 0x00400002. | |
169 | */ | |
170 | #define PSC_SND_HUH3 0x20C /* | |
171 | * [ 16-bit ] | |
172 | * Unknown 16-bit value, always 0x0000. | |
173 | */ | |
174 | #define PSC_SND_BITS2GO 0x20E /* | |
175 | * [ 16-bit ] | |
176 | * Counts down to zero from some constant | |
177 | * value. The value appears to be the | |
178 | * number of _bits_ remaining before the | |
179 | * buffer is full, which would make sense | |
180 | * since Apple's docs say the sound DMA | |
181 | * channels are 1 bit wide. | |
182 | */ | |
183 | #define PSC_SND_INADDR 0x210 /* | |
184 | * [ 32-bit ] | |
185 | * Address of the sound input DMA buffer | |
186 | */ | |
187 | #define PSC_SND_OUTADDR 0x214 /* | |
188 | * [ 32-bit ] | |
189 | * Address of the sound output DMA buffer | |
190 | */ | |
191 | #define PSC_SND_LEN 0x218 /* | |
192 | * [ 16-bit ] | |
193 | * Length of both buffers in eight-byte units. | |
194 | */ | |
195 | #define PSC_SND_HUH4 0x21A /* | |
196 | * [ 16-bit ] | |
197 | * Unknown, always 0x0000. | |
198 | */ | |
199 | #define PSC_SND_STATUS2 0x21C /* | |
200 | * [ 16-bit ] | |
201 | * Appears to e a read-only status register. | |
202 | * The usual value is 0x0200. | |
203 | */ | |
204 | #define PSC_SND_HUH5 0x21E /* | |
205 | * [ 16-bit ] | |
206 | * Unknown, always 0x0000. | |
207 | */ | |
208 | ||
209 | #ifndef __ASSEMBLY__ | |
210 | ||
211 | extern volatile __u8 *psc; | |
212 | extern int psc_present; | |
213 | ||
214 | /* | |
215 | * Access functions | |
216 | */ | |
217 | ||
218 | static inline void psc_write_byte(int offset, __u8 data) | |
219 | { | |
220 | *((volatile __u8 *)(psc + offset)) = data; | |
221 | } | |
222 | ||
223 | static inline void psc_write_word(int offset, __u16 data) | |
224 | { | |
225 | *((volatile __u16 *)(psc + offset)) = data; | |
226 | } | |
227 | ||
228 | static inline void psc_write_long(int offset, __u32 data) | |
229 | { | |
230 | *((volatile __u32 *)(psc + offset)) = data; | |
231 | } | |
232 | ||
233 | static inline u8 psc_read_byte(int offset) | |
234 | { | |
235 | return *((volatile __u8 *)(psc + offset)); | |
236 | } | |
237 | ||
238 | static inline u16 psc_read_word(int offset) | |
239 | { | |
240 | return *((volatile __u16 *)(psc + offset)); | |
241 | } | |
242 | ||
243 | static inline u32 psc_read_long(int offset) | |
244 | { | |
245 | return *((volatile __u32 *)(psc + offset)); | |
246 | } | |
247 | ||
248 | #endif /* __ASSEMBLY__ */ |