1 /*
2 **********************************************************************
3 * cardwi.c - PCM input HAL for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
5 *
6 **********************************************************************
7 *
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 *
12 **********************************************************************
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the Free
26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27 * USA.
28 *
29 **********************************************************************
30 */
31
32 #include <linux/poll.h>
33 #include "hwaccess.h"
34 #include "timer.h"
35 #include "recmgr.h"
36 #include "audio.h"
37 #include "cardwi.h"
38
39 /**
40 * query_format - returns a valid sound format
41 *
42 * This function will return a valid sound format as close
43 * to the requested one as possible.
44 */
query_format(int recsrc,struct wave_format * wave_fmt)45 void query_format(int recsrc, struct wave_format *wave_fmt)
46 {
47
48 switch (recsrc) {
49 case WAVERECORD_AC97:
50
51 if ((wave_fmt->channels != 1) && (wave_fmt->channels != 2))
52 wave_fmt->channels = 2;
53
54 if (wave_fmt->samplingrate >= (0xBB80 + 0xAC44) / 2)
55 wave_fmt->samplingrate = 0xBB80;
56 else if (wave_fmt->samplingrate >= (0xAC44 + 0x7D00) / 2)
57 wave_fmt->samplingrate = 0xAC44;
58 else if (wave_fmt->samplingrate >= (0x7D00 + 0x5DC0) / 2)
59 wave_fmt->samplingrate = 0x7D00;
60 else if (wave_fmt->samplingrate >= (0x5DC0 + 0x5622) / 2)
61 wave_fmt->samplingrate = 0x5DC0;
62 else if (wave_fmt->samplingrate >= (0x5622 + 0x3E80) / 2)
63 wave_fmt->samplingrate = 0x5622;
64 else if (wave_fmt->samplingrate >= (0x3E80 + 0x2B11) / 2)
65 wave_fmt->samplingrate = 0x3E80;
66 else if (wave_fmt->samplingrate >= (0x2B11 + 0x1F40) / 2)
67 wave_fmt->samplingrate = 0x2B11;
68 else
69 wave_fmt->samplingrate = 0x1F40;
70
71 switch (wave_fmt->id) {
72 case AFMT_S16_LE:
73 wave_fmt->bitsperchannel = 16;
74 break;
75 case AFMT_U8:
76 wave_fmt->bitsperchannel = 8;
77 break;
78 default:
79 wave_fmt->id = AFMT_S16_LE;
80 wave_fmt->bitsperchannel = 16;
81 break;
82 }
83
84 break;
85
86 /* these can't be changed from the original values */
87 case WAVERECORD_MIC:
88 case WAVERECORD_FX:
89 break;
90
91 default:
92 BUG();
93 break;
94 }
95
96 wave_fmt->bytesperchannel = wave_fmt->bitsperchannel >> 3;
97 wave_fmt->bytespersample = wave_fmt->channels * wave_fmt->bytesperchannel;
98 wave_fmt->bytespersec = wave_fmt->bytespersample * wave_fmt->samplingrate;
99 wave_fmt->bytespervoicesample = wave_fmt->bytespersample;
100 }
101
alloc_buffer(struct emu10k1_card * card,struct wavein_buffer * buffer)102 static int alloc_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
103 {
104 buffer->addr = pci_alloc_consistent(card->pci_dev, buffer->size * buffer->cov,
105 &buffer->dma_handle);
106 if (buffer->addr == NULL)
107 return -1;
108
109 return 0;
110 }
111
free_buffer(struct emu10k1_card * card,struct wavein_buffer * buffer)112 static void free_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
113 {
114 if (buffer->addr != NULL)
115 pci_free_consistent(card->pci_dev, buffer->size * buffer->cov,
116 buffer->addr, buffer->dma_handle);
117 }
118
emu10k1_wavein_open(struct emu10k1_wavedevice * wave_dev)119 int emu10k1_wavein_open(struct emu10k1_wavedevice *wave_dev)
120 {
121 struct emu10k1_card *card = wave_dev->card;
122 struct wiinst *wiinst = wave_dev->wiinst;
123 struct wiinst **wiinst_tmp = NULL;
124 u16 delay;
125 unsigned long flags;
126
127 DPF(2, "emu10k1_wavein_open()\n");
128
129 switch (wiinst->recsrc) {
130 case WAVERECORD_AC97:
131 wiinst_tmp = &card->wavein.ac97;
132 break;
133 case WAVERECORD_MIC:
134 wiinst_tmp = &card->wavein.mic;
135 break;
136 case WAVERECORD_FX:
137 wiinst_tmp = &card->wavein.fx;
138 break;
139 default:
140 BUG();
141 break;
142 }
143
144 spin_lock_irqsave(&card->lock, flags);
145 if (*wiinst_tmp != NULL) {
146 spin_unlock_irqrestore(&card->lock, flags);
147 return -1;
148 }
149
150 *wiinst_tmp = wiinst;
151 spin_unlock_irqrestore(&card->lock, flags);
152
153 /* handle 8 bit recording */
154 if (wiinst->format.bytesperchannel == 1) {
155 if (wiinst->buffer.size > 0x8000) {
156 wiinst->buffer.size = 0x8000;
157 wiinst->buffer.sizeregval = 0x1f;
158 } else
159 wiinst->buffer.sizeregval += 4;
160
161 wiinst->buffer.cov = 2;
162 } else
163 wiinst->buffer.cov = 1;
164
165 if (alloc_buffer(card, &wiinst->buffer) < 0) {
166 ERROR();
167 emu10k1_wavein_close(wave_dev);
168 return -1;
169 }
170
171 emu10k1_set_record_src(card, wiinst);
172
173 emu10k1_reset_record(card, &wiinst->buffer);
174
175 wiinst->buffer.hw_pos = 0;
176 wiinst->buffer.pos = 0;
177 wiinst->buffer.bytestocopy = 0;
178
179 delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
180
181 emu10k1_timer_install(card, &wiinst->timer, delay / 2);
182
183 wiinst->state = WAVE_STATE_OPEN;
184
185 return 0;
186 }
187
emu10k1_wavein_close(struct emu10k1_wavedevice * wave_dev)188 void emu10k1_wavein_close(struct emu10k1_wavedevice *wave_dev)
189 {
190 struct emu10k1_card *card = wave_dev->card;
191 struct wiinst *wiinst = wave_dev->wiinst;
192 unsigned long flags;
193
194 DPF(2, "emu10k1_wavein_close()\n");
195
196 emu10k1_wavein_stop(wave_dev);
197
198 emu10k1_timer_uninstall(card, &wiinst->timer);
199
200 free_buffer(card, &wiinst->buffer);
201
202 spin_lock_irqsave(&card->lock, flags);
203 switch (wave_dev->wiinst->recsrc) {
204 case WAVERECORD_AC97:
205 card->wavein.ac97 = NULL;
206 break;
207 case WAVERECORD_MIC:
208 card->wavein.mic = NULL;
209 break;
210 case WAVERECORD_FX:
211 card->wavein.fx = NULL;
212 break;
213 default:
214 BUG();
215 break;
216 }
217 spin_unlock_irqrestore(&card->lock, flags);
218
219 wiinst->state = WAVE_STATE_CLOSED;
220 }
221
emu10k1_wavein_start(struct emu10k1_wavedevice * wave_dev)222 void emu10k1_wavein_start(struct emu10k1_wavedevice *wave_dev)
223 {
224 struct emu10k1_card *card = wave_dev->card;
225 struct wiinst *wiinst = wave_dev->wiinst;
226
227 DPF(2, "emu10k1_wavein_start()\n");
228
229 emu10k1_start_record(card, &wiinst->buffer);
230 emu10k1_timer_enable(wave_dev->card, &wiinst->timer);
231
232 wiinst->state |= WAVE_STATE_STARTED;
233 }
234
emu10k1_wavein_stop(struct emu10k1_wavedevice * wave_dev)235 void emu10k1_wavein_stop(struct emu10k1_wavedevice *wave_dev)
236 {
237 struct emu10k1_card *card = wave_dev->card;
238 struct wiinst *wiinst = wave_dev->wiinst;
239
240 DPF(2, "emu10k1_wavein_stop()\n");
241
242 if (!(wiinst->state & WAVE_STATE_STARTED))
243 return;
244
245 emu10k1_timer_disable(card, &wiinst->timer);
246 emu10k1_stop_record(card, &wiinst->buffer);
247
248 wiinst->state &= ~WAVE_STATE_STARTED;
249 }
250
emu10k1_wavein_setformat(struct emu10k1_wavedevice * wave_dev,struct wave_format * format)251 int emu10k1_wavein_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_format *format)
252 {
253 struct emu10k1_card *card = wave_dev->card;
254 struct wiinst *wiinst = wave_dev->wiinst;
255 u16 delay;
256
257 DPF(2, "emu10k1_wavein_setformat()\n");
258
259 if (wiinst->state & WAVE_STATE_STARTED)
260 return -1;
261
262 query_format(wiinst->recsrc, format);
263
264 if ((wiinst->format.samplingrate != format->samplingrate)
265 || (wiinst->format.bitsperchannel != format->bitsperchannel)
266 || (wiinst->format.channels != format->channels)) {
267
268 wiinst->format = *format;
269
270 if (wiinst->state == WAVE_STATE_CLOSED)
271 return 0;
272
273 wiinst->buffer.size *= wiinst->buffer.cov;
274
275 if (wiinst->format.bytesperchannel == 1) {
276 wiinst->buffer.cov = 2;
277 wiinst->buffer.size /= wiinst->buffer.cov;
278 } else
279 wiinst->buffer.cov = 1;
280
281 emu10k1_timer_uninstall(card, &wiinst->timer);
282
283 delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
284
285 emu10k1_timer_install(card, &wiinst->timer, delay / 2);
286 }
287
288 return 0;
289 }
290
emu10k1_wavein_getxfersize(struct wiinst * wiinst,u32 * size)291 void emu10k1_wavein_getxfersize(struct wiinst *wiinst, u32 * size)
292 {
293 struct wavein_buffer *buffer = &wiinst->buffer;
294
295 *size = buffer->bytestocopy;
296
297 if (wiinst->mmapped)
298 return;
299
300 if (*size > buffer->size) {
301 *size = buffer->size;
302 buffer->pos = buffer->hw_pos;
303 buffer->bytestocopy = buffer->size;
304 DPF(1, "buffer overrun\n");
305 }
306 }
307
copy_block(u8 * dst,u8 * src,u32 str,u32 len,u8 cov)308 static void copy_block(u8 *dst, u8 * src, u32 str, u32 len, u8 cov)
309 {
310 if (cov == 1)
311 __copy_to_user(dst, src + str, len);
312 else {
313 u8 byte;
314 u32 i;
315
316 src += 1 + 2 * str;
317
318 for (i = 0; i < len; i++) {
319 byte = src[2 * i] ^ 0x80;
320 __copy_to_user(dst + i, &byte, 1);
321 }
322 }
323 }
324
emu10k1_wavein_xferdata(struct wiinst * wiinst,u8 * data,u32 * size)325 void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 * data, u32 * size)
326 {
327 struct wavein_buffer *buffer = &wiinst->buffer;
328 u32 sizetocopy, sizetocopy_now, start;
329 unsigned long flags;
330
331 sizetocopy = min_t(u32, buffer->size, *size);
332 *size = sizetocopy;
333
334 if (!sizetocopy)
335 return;
336
337 spin_lock_irqsave(&wiinst->lock, flags);
338 start = buffer->pos;
339 buffer->pos += sizetocopy;
340 buffer->pos %= buffer->size;
341 buffer->bytestocopy -= sizetocopy;
342 sizetocopy_now = buffer->size - start;
343
344 spin_unlock_irqrestore(&wiinst->lock, flags);
345
346 if (sizetocopy > sizetocopy_now) {
347 sizetocopy -= sizetocopy_now;
348
349 copy_block(data, buffer->addr, start, sizetocopy_now, buffer->cov);
350 copy_block(data + sizetocopy_now, buffer->addr, 0, sizetocopy, buffer->cov);
351 } else {
352 copy_block(data, buffer->addr, start, sizetocopy, buffer->cov);
353 }
354 }
355
emu10k1_wavein_update(struct emu10k1_card * card,struct wiinst * wiinst)356 void emu10k1_wavein_update(struct emu10k1_card *card, struct wiinst *wiinst)
357 {
358 u32 hw_pos;
359 u32 diff;
360
361 /* There is no actual start yet */
362 if (!(wiinst->state & WAVE_STATE_STARTED)) {
363 hw_pos = wiinst->buffer.hw_pos;
364 } else {
365 /* hw_pos in byte units */
366 hw_pos = sblive_readptr(card, wiinst->buffer.idxreg, 0) / wiinst->buffer.cov;
367 }
368
369 diff = (wiinst->buffer.size + hw_pos - wiinst->buffer.hw_pos) % wiinst->buffer.size;
370 wiinst->total_recorded += diff;
371 wiinst->buffer.bytestocopy += diff;
372
373 wiinst->buffer.hw_pos = hw_pos;
374 }
375