diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /sound/oss/nm256.h |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'sound/oss/nm256.h')
-rw-r--r-- | sound/oss/nm256.h | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/sound/oss/nm256.h b/sound/oss/nm256.h new file mode 100644 index 000000000000..eae7d99d6826 --- /dev/null +++ b/sound/oss/nm256.h | |||
@@ -0,0 +1,295 @@ | |||
1 | #ifndef _NM256_H_ | ||
2 | #define _NM256_H_ | ||
3 | |||
4 | #include <linux/spinlock.h> | ||
5 | #include <linux/interrupt.h> | ||
6 | |||
7 | #include "ac97.h" | ||
8 | |||
9 | /* The revisions that we currently handle. */ | ||
10 | enum nm256rev { | ||
11 | REV_NM256AV, REV_NM256ZX | ||
12 | }; | ||
13 | |||
14 | /* Per-card structure. */ | ||
15 | struct nm256_info | ||
16 | { | ||
17 | /* Magic number used to verify that this struct is valid. */ | ||
18 | #define NM_MAGIC_SIG 0x55aa00ff | ||
19 | int magsig; | ||
20 | |||
21 | /* Revision number */ | ||
22 | enum nm256rev rev; | ||
23 | |||
24 | struct ac97_hwint mdev; | ||
25 | |||
26 | /* Our audio device numbers. */ | ||
27 | int dev[2]; | ||
28 | |||
29 | /* The # of times each device has been opened. (Should only be | ||
30 | 0 or 1). */ | ||
31 | int opencnt[2]; | ||
32 | |||
33 | /* We use two devices, because we can do simultaneous play and record. | ||
34 | This keeps track of which device is being used for what purpose; | ||
35 | these are the actual device numbers. */ | ||
36 | int dev_for_play; | ||
37 | int dev_for_record; | ||
38 | |||
39 | spinlock_t lock; | ||
40 | |||
41 | /* The mixer device. */ | ||
42 | int mixer_oss_dev; | ||
43 | |||
44 | /* | ||
45 | * Can only be opened once for each operation. These aren't set | ||
46 | * until an actual I/O operation is performed; this allows one | ||
47 | * device to be open for read/write without inhibiting I/O to | ||
48 | * the other device. | ||
49 | */ | ||
50 | int is_open_play; | ||
51 | int is_open_record; | ||
52 | |||
53 | /* Non-zero if we're currently playing a sample. */ | ||
54 | int playing; | ||
55 | /* Ditto for recording a sample. */ | ||
56 | int recording; | ||
57 | |||
58 | /* The two memory ports. */ | ||
59 | struct nm256_ports { | ||
60 | /* Physical address of the port. */ | ||
61 | u32 physaddr; | ||
62 | /* Our mapped-in pointer. */ | ||
63 | char __iomem *ptr; | ||
64 | /* PTR's offset within the physical port. */ | ||
65 | u32 start_offset; | ||
66 | /* And the offset of the end of the buffer. */ | ||
67 | u32 end_offset; | ||
68 | } port[2]; | ||
69 | |||
70 | /* The following are offsets within memory port 1. */ | ||
71 | u32 coeffBuf; | ||
72 | u32 allCoeffBuf; | ||
73 | |||
74 | /* Record and playback buffers. */ | ||
75 | u32 abuf1, abuf2; | ||
76 | |||
77 | /* Offset of the AC97 mixer in memory port 2. */ | ||
78 | u32 mixer; | ||
79 | |||
80 | /* Offset of the mixer status register in memory port 2. */ | ||
81 | u32 mixer_status_offset; | ||
82 | |||
83 | /* Non-zero if we have written initial values to the mixer. */ | ||
84 | u8 mixer_values_init; | ||
85 | |||
86 | /* | ||
87 | * Status mask bit; (*mixer_status_loc & mixer_status_mask) == 0 means | ||
88 | * it's ready. | ||
89 | */ | ||
90 | u16 mixer_status_mask; | ||
91 | |||
92 | /* The sizes of the playback and record ring buffers. */ | ||
93 | u32 playbackBufferSize; | ||
94 | u32 recordBufferSize; | ||
95 | |||
96 | /* Are the coefficient values in the memory cache current? */ | ||
97 | u8 coeffsCurrent; | ||
98 | |||
99 | /* For writes, the amount we last wrote. */ | ||
100 | u32 requested_amt; | ||
101 | /* The start of the block currently playing. */ | ||
102 | u32 curPlayPos; | ||
103 | |||
104 | /* The amount of data we were requested to record. */ | ||
105 | u32 requestedRecAmt; | ||
106 | /* The offset of the currently-recording block. */ | ||
107 | u32 curRecPos; | ||
108 | /* The destination buffer. */ | ||
109 | char *recBuf; | ||
110 | |||
111 | /* Our IRQ number. */ | ||
112 | int irq; | ||
113 | |||
114 | /* A flag indicating how many times we've grabbed the IRQ. */ | ||
115 | int has_irq; | ||
116 | |||
117 | /* The card interrupt service routine. */ | ||
118 | irqreturn_t (*introutine) (int, void *, struct pt_regs *); | ||
119 | |||
120 | /* Current audio config, cached. */ | ||
121 | struct sinfo { | ||
122 | u32 samplerate; | ||
123 | u8 bits; | ||
124 | u8 stereo; | ||
125 | } sinfo[2]; /* goes with each device */ | ||
126 | |||
127 | /* The cards are stored in a chain; this is the next card. */ | ||
128 | struct nm256_info *next_card; | ||
129 | }; | ||
130 | |||
131 | /* Debug flag--bigger numbers mean more output. */ | ||
132 | extern int nm256_debug; | ||
133 | |||
134 | /* The BIOS signature. */ | ||
135 | #define NM_SIGNATURE 0x4e4d0000 | ||
136 | /* Signature mask. */ | ||
137 | #define NM_SIG_MASK 0xffff0000 | ||
138 | |||
139 | /* Size of the second memory area. */ | ||
140 | #define NM_PORT2_SIZE 4096 | ||
141 | |||
142 | /* The base offset of the mixer in the second memory area. */ | ||
143 | #define NM_MIXER_OFFSET 0x600 | ||
144 | |||
145 | /* The maximum size of a coefficient entry. */ | ||
146 | #define NM_MAX_COEFFICIENT 0x5000 | ||
147 | |||
148 | /* The interrupt register. */ | ||
149 | #define NM_INT_REG 0xa04 | ||
150 | /* And its bits. */ | ||
151 | #define NM_PLAYBACK_INT 0x40 | ||
152 | #define NM_RECORD_INT 0x100 | ||
153 | #define NM_MISC_INT_1 0x4000 | ||
154 | #define NM_MISC_INT_2 0x1 | ||
155 | #define NM_ACK_INT(CARD, X) nm256_writePort16((CARD), 2, NM_INT_REG, (X) << 1) | ||
156 | |||
157 | /* The AV's "mixer ready" status bit and location. */ | ||
158 | #define NM_MIXER_STATUS_OFFSET 0xa04 | ||
159 | #define NM_MIXER_READY_MASK 0x0800 | ||
160 | #define NM_MIXER_PRESENCE 0xa06 | ||
161 | #define NM_PRESENCE_MASK 0x0050 | ||
162 | #define NM_PRESENCE_VALUE 0x0040 | ||
163 | |||
164 | /* | ||
165 | * For the ZX. It uses the same interrupt register, but it holds 32 | ||
166 | * bits instead of 16. | ||
167 | */ | ||
168 | #define NM2_PLAYBACK_INT 0x10000 | ||
169 | #define NM2_RECORD_INT 0x80000 | ||
170 | #define NM2_MISC_INT_1 0x8 | ||
171 | #define NM2_MISC_INT_2 0x2 | ||
172 | #define NM2_ACK_INT(CARD, X) nm256_writePort32((CARD), 2, NM_INT_REG, (X)) | ||
173 | |||
174 | /* The ZX's "mixer ready" status bit and location. */ | ||
175 | #define NM2_MIXER_STATUS_OFFSET 0xa06 | ||
176 | #define NM2_MIXER_READY_MASK 0x0800 | ||
177 | |||
178 | /* The playback registers start from here. */ | ||
179 | #define NM_PLAYBACK_REG_OFFSET 0x0 | ||
180 | /* The record registers start from here. */ | ||
181 | #define NM_RECORD_REG_OFFSET 0x200 | ||
182 | |||
183 | /* The rate register is located 2 bytes from the start of the register area. */ | ||
184 | #define NM_RATE_REG_OFFSET 2 | ||
185 | |||
186 | /* Mono/stereo flag, number of bits on playback, and rate mask. */ | ||
187 | #define NM_RATE_STEREO 1 | ||
188 | #define NM_RATE_BITS_16 2 | ||
189 | #define NM_RATE_MASK 0xf0 | ||
190 | |||
191 | /* Playback enable register. */ | ||
192 | #define NM_PLAYBACK_ENABLE_REG (NM_PLAYBACK_REG_OFFSET + 0x1) | ||
193 | #define NM_PLAYBACK_ENABLE_FLAG 1 | ||
194 | #define NM_PLAYBACK_ONESHOT 2 | ||
195 | #define NM_PLAYBACK_FREERUN 4 | ||
196 | |||
197 | /* Mutes the audio output. */ | ||
198 | #define NM_AUDIO_MUTE_REG (NM_PLAYBACK_REG_OFFSET + 0x18) | ||
199 | #define NM_AUDIO_MUTE_LEFT 0x8000 | ||
200 | #define NM_AUDIO_MUTE_RIGHT 0x0080 | ||
201 | |||
202 | /* Recording enable register. */ | ||
203 | #define NM_RECORD_ENABLE_REG (NM_RECORD_REG_OFFSET + 0) | ||
204 | #define NM_RECORD_ENABLE_FLAG 1 | ||
205 | #define NM_RECORD_FREERUN 2 | ||
206 | |||
207 | #define NM_RBUFFER_START (NM_RECORD_REG_OFFSET + 0x4) | ||
208 | #define NM_RBUFFER_END (NM_RECORD_REG_OFFSET + 0x10) | ||
209 | #define NM_RBUFFER_WMARK (NM_RECORD_REG_OFFSET + 0xc) | ||
210 | #define NM_RBUFFER_CURRP (NM_RECORD_REG_OFFSET + 0x8) | ||
211 | |||
212 | #define NM_PBUFFER_START (NM_PLAYBACK_REG_OFFSET + 0x4) | ||
213 | #define NM_PBUFFER_END (NM_PLAYBACK_REG_OFFSET + 0x14) | ||
214 | #define NM_PBUFFER_WMARK (NM_PLAYBACK_REG_OFFSET + 0xc) | ||
215 | #define NM_PBUFFER_CURRP (NM_PLAYBACK_REG_OFFSET + 0x8) | ||
216 | |||
217 | /* A few trivial routines to make it easier to work with the registers | ||
218 | on the chip. */ | ||
219 | |||
220 | /* This is a common code portion used to fix up the port offsets. */ | ||
221 | #define NM_FIX_PORT \ | ||
222 | if (port < 1 || port > 2 || card == NULL) \ | ||
223 | return -1; \ | ||
224 | \ | ||
225 | if (offset < card->port[port - 1].start_offset \ | ||
226 | || offset >= card->port[port - 1].end_offset) { \ | ||
227 | printk (KERN_ERR "Bad access: port %d, offset 0x%x\n", port, offset); \ | ||
228 | return -1; \ | ||
229 | } \ | ||
230 | offset -= card->port[port - 1].start_offset; | ||
231 | |||
232 | #define DEFwritePortX(X, func) \ | ||
233 | static inline int nm256_writePort##X (struct nm256_info *card,\ | ||
234 | int port, int offset, int value)\ | ||
235 | {\ | ||
236 | u##X __iomem *addr;\ | ||
237 | \ | ||
238 | if (nm256_debug > 1)\ | ||
239 | printk (KERN_DEBUG "Writing 0x%x to %d:0x%x\n", value, port, offset);\ | ||
240 | \ | ||
241 | NM_FIX_PORT;\ | ||
242 | \ | ||
243 | addr = (u##X __iomem *)(card->port[port - 1].ptr + offset);\ | ||
244 | func (value, addr);\ | ||
245 | return 0;\ | ||
246 | } | ||
247 | |||
248 | DEFwritePortX (8, writeb) | ||
249 | DEFwritePortX (16, writew) | ||
250 | DEFwritePortX (32, writel) | ||
251 | |||
252 | #define DEFreadPortX(X, func) \ | ||
253 | static inline u##X nm256_readPort##X (struct nm256_info *card,\ | ||
254 | int port, int offset)\ | ||
255 | {\ | ||
256 | u##X __iomem *addr;\ | ||
257 | \ | ||
258 | NM_FIX_PORT\ | ||
259 | \ | ||
260 | addr = (u##X __iomem *)(card->port[port - 1].ptr + offset);\ | ||
261 | return func(addr);\ | ||
262 | } | ||
263 | |||
264 | DEFreadPortX (8, readb) | ||
265 | DEFreadPortX (16, readw) | ||
266 | DEFreadPortX (32, readl) | ||
267 | |||
268 | static inline int | ||
269 | nm256_writeBuffer8 (struct nm256_info *card, u8 *src, int port, int offset, | ||
270 | int amt) | ||
271 | { | ||
272 | NM_FIX_PORT; | ||
273 | memcpy_toio (card->port[port - 1].ptr + offset, src, amt); | ||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | static inline int | ||
278 | nm256_readBuffer8 (struct nm256_info *card, u8 *dst, int port, int offset, | ||
279 | int amt) | ||
280 | { | ||
281 | NM_FIX_PORT; | ||
282 | memcpy_fromio (dst, card->port[port - 1].ptr + offset, amt); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | /* Returns a non-zero value if we should use the coefficient cache. */ | ||
287 | extern int nm256_cachedCoefficients (struct nm256_info *card); | ||
288 | |||
289 | #endif | ||
290 | |||
291 | /* | ||
292 | * Local variables: | ||
293 | * c-basic-offset: 4 | ||
294 | * End: | ||
295 | */ | ||