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