This source file includes following definitions.
- audio_open
- audio_release
- translate_bytes
- translate_bytes
- audio_write
- audio_read
- audio_ioctl
- audio_init
- audio_read
- audio_write
- audio_open
- audio_release
- audio_ioctl
- audio_lseek
- audio_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include "sound_config.h"
31
32 #ifdef CONFIGURE_SOUNDCARD
33 #ifndef EXCLUDE_AUDIO
34
35 #include "ulaw.h"
36
37 #define ON 1
38 #define OFF 0
39
40 static int wr_buff_no[MAX_DSP_DEV];
41
42
43 static int wr_buff_size[MAX_DSP_DEV], wr_buff_ptr[MAX_DSP_DEV];
44
45 static int audio_mode[MAX_DSP_DEV];
46
47 #define AM_NONE 0
48 #define AM_WRITE 1
49 #define AM_READ 2
50
51 static char *wr_dma_buf[MAX_DSP_DEV];
52
53 int
54 audio_open (int dev, struct fileinfo *file)
55 {
56 int ret;
57 int bits;
58 int dev_type = dev & 0x0f;
59 int mode = file->mode & O_ACCMODE;
60
61 dev = dev >> 4;
62
63 if (dev_type == SND_DEV_DSP16)
64 bits = 16;
65 else
66 bits = 8;
67
68 if ((ret = DMAbuf_open (dev, mode)) < 0)
69 return ret;
70
71 if (DMAbuf_ioctl (dev, SNDCTL_DSP_SAMPLESIZE, bits, 1) != bits)
72 {
73 audio_release (dev, file);
74 return RET_ERROR (ENXIO);
75 }
76
77 wr_buff_no[dev] = -1;
78 audio_mode[dev] = AM_NONE;
79
80 return ret;
81 }
82
83 void
84 audio_release (int dev, struct fileinfo *file)
85 {
86 int mode;
87
88 dev = dev >> 4;
89 mode = file->mode & O_ACCMODE;
90
91 if (wr_buff_no[dev] >= 0)
92 {
93 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
94
95 wr_buff_no[dev] = -1;
96 }
97
98 DMAbuf_release (dev, mode);
99 }
100
101 #ifdef NO_INLINE_ASM
102 static void
103 translate_bytes (const unsigned char *table, unsigned char *buff, unsigned long n)
104 {
105 unsigned long i;
106
107 for (i = 0; i < n; ++i)
108 buff[i] = table[buff[i]];
109 }
110
111 #else
112 extern inline void
113 translate_bytes (const void *table, void *buff, unsigned long n)
114 {
115 __asm__ ("cld\n"
116 "1:\tlodsb\n\t"
117 "xlatb\n\t"
118 "stosb\n\t"
119 "loop 1b\n\t":
120 :"b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
121 :"bx", "cx", "di", "si", "ax");
122 }
123
124 #endif
125
126 int
127 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
128 {
129 int c, p, l;
130 int err;
131 int dev_type = dev & 0x0f;
132
133 dev = dev >> 4;
134
135 p = 0;
136 c = count;
137
138 if (audio_mode[dev] == AM_READ)
139 {
140 wr_buff_no[dev] = -1;
141 }
142
143 audio_mode[dev] = AM_WRITE;
144
145 if (!count)
146 {
147 if (wr_buff_no[dev] >= 0)
148 {
149 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
150
151 wr_buff_no[dev] = -1;
152 }
153 return 0;
154 }
155
156 while (c)
157 {
158 if (wr_buff_no[dev] < 0)
159 {
160 if ((wr_buff_no[dev] = DMAbuf_getwrbuffer (dev, &wr_dma_buf[dev], &wr_buff_size[dev])) < 0)
161 return wr_buff_no[dev];
162 wr_buff_ptr[dev] = 0;
163 }
164
165 l = c;
166 if (l > (wr_buff_size[dev] - wr_buff_ptr[dev]))
167 l = (wr_buff_size[dev] - wr_buff_ptr[dev]);
168
169 if (!dsp_devs[dev]->copy_from_user)
170 {
171 COPY_FROM_USER (&wr_dma_buf[dev][wr_buff_ptr[dev]], buf, p, l);
172 }
173 else
174 dsp_devs[dev]->copy_from_user (dev,
175 wr_dma_buf[dev], wr_buff_ptr[dev], buf, p, l);
176
177
178
179
180 if (dev_type == SND_DEV_AUDIO)
181 {
182 #ifdef linux
183
184 __asm__ ("sti");
185 #endif
186 translate_bytes (ulaw_dsp, (unsigned char *) &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
187 }
188
189 c -= l;
190 p += l;
191 wr_buff_ptr[dev] += l;
192
193 if (wr_buff_ptr[dev] >= wr_buff_size[dev])
194 {
195 if ((err = DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev])) < 0)
196 return err;
197
198 wr_buff_no[dev] = -1;
199 }
200
201 }
202
203 return count;
204 }
205
206 int
207 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
208 {
209 int c, p, l;
210 char *dmabuf;
211 int buff_no;
212 int dev_type = dev & 0x0f;
213
214 dev = dev >> 4;
215 p = 0;
216 c = count;
217
218 if (audio_mode[dev] == AM_WRITE)
219 {
220 if (wr_buff_no[dev] >= 0)
221 {
222 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
223
224 wr_buff_no[dev] = -1;
225 }
226 }
227
228 audio_mode[dev] = AM_READ;
229
230 while (c)
231 {
232 if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &l)) < 0)
233 return buff_no;
234
235 if (l > c)
236 l = c;
237
238
239
240 if (dev_type == SND_DEV_AUDIO)
241 {
242 #ifdef linux
243
244 __asm__ ("sti");
245 #endif
246
247 translate_bytes (dsp_ulaw, (unsigned char *) dmabuf, l);
248 }
249
250 COPY_TO_USER (buf, p, dmabuf, l);
251
252 DMAbuf_rmchars (dev, buff_no, l);
253
254 p += l;
255 c -= l;
256 }
257
258 return count - c;
259 }
260
261 int
262 audio_ioctl (int dev, struct fileinfo *file,
263 unsigned int cmd, unsigned int arg)
264 {
265 int dev_type = dev & 0x0f;
266
267 dev = dev >> 4;
268
269 switch (cmd)
270 {
271 case SNDCTL_DSP_SYNC:
272 if (wr_buff_no[dev] >= 0)
273 {
274 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
275
276 wr_buff_no[dev] = -1;
277 }
278 return DMAbuf_ioctl (dev, cmd, arg, 0);
279 break;
280
281 case SNDCTL_DSP_POST:
282 if (wr_buff_no[dev] >= 0)
283 {
284 DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
285
286 wr_buff_no[dev] = -1;
287 }
288 return 0;
289 break;
290
291 case SNDCTL_DSP_RESET:
292 wr_buff_no[dev] = -1;
293 return DMAbuf_ioctl (dev, cmd, arg, 0);
294 break;
295
296 default:
297 if (dev_type == SND_DEV_AUDIO)
298 return RET_ERROR (EIO);
299
300 return DMAbuf_ioctl (dev, cmd, arg, 0);
301 }
302 }
303
304 long
305 audio_init (long mem_start)
306 {
307 return mem_start;
308 }
309
310 #else
311
312
313 int
314 audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
315 {
316 return RET_ERROR (EIO);
317 }
318
319 int
320 audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
321 {
322 return RET_ERROR (EIO);
323 }
324
325 int
326 audio_open (int dev, struct fileinfo *file)
327 {
328 return RET_ERROR (ENXIO);
329 }
330
331 void
332 audio_release (int dev, struct fileinfo *file)
333 {
334 };
335 int
336 audio_ioctl (int dev, struct fileinfo *file,
337 unsigned int cmd, unsigned int arg)
338 {
339 return RET_ERROR (EIO);
340 }
341
342 int
343 audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
344 {
345 return RET_ERROR (EIO);
346 }
347
348 long
349 audio_init (long mem_start)
350 {
351 return mem_start;
352 }
353
354 #endif
355
356 #endif