2 **********************************************************************
3 * cardwi.c - PCM input HAL for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
6 **********************************************************************
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
12 **********************************************************************
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.
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.
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,
29 **********************************************************************
32 #include <linux/poll.h>
40 * query_format - returns a valid sound format
42 * This function will return a valid sound format as close
43 * to the requested one as possible.
45 static void query_format(int recsrc, struct wave_format *wave_fmt)
51 if ((wave_fmt->channels != 1) && (wave_fmt->channels != 2))
52 wave_fmt->channels = 2;
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;
69 wave_fmt->samplingrate = 0x1F40;
71 switch (wave_fmt->id) {
73 wave_fmt->bitsperchannel = 16;
76 wave_fmt->bitsperchannel = 8;
79 wave_fmt->id = AFMT_S16_LE;
80 wave_fmt->bitsperchannel = 16;
86 /* these can't be changed from the original values */
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;
102 static int alloc_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
104 buffer->addr = pci_alloc_consistent(card->pci_dev, buffer->size * buffer->cov,
105 &buffer->dma_handle);
106 if (buffer->addr == NULL)
112 static void free_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
114 if (buffer->addr != NULL)
115 pci_free_consistent(card->pci_dev, buffer->size * buffer->cov,
116 buffer->addr, buffer->dma_handle);
119 int emu10k1_wavein_open(struct emu10k1_wavedevice *wave_dev)
121 struct emu10k1_card *card = wave_dev->card;
122 struct wiinst *wiinst = wave_dev->wiinst;
123 struct wiinst **wiinst_tmp = NULL;
127 DPF(2, "emu10k1_wavein_open()\n");
129 switch (wiinst->recsrc) {
130 case WAVERECORD_AC97:
131 wiinst_tmp = &card->wavein.ac97;
134 wiinst_tmp = &card->wavein.mic;
137 wiinst_tmp = &card->wavein.fx;
144 spin_lock_irqsave(&card->lock, flags);
145 if (*wiinst_tmp != NULL) {
146 spin_unlock_irqrestore(&card->lock, flags);
150 *wiinst_tmp = wiinst;
151 spin_unlock_irqrestore(&card->lock, flags);
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;
159 wiinst->buffer.sizeregval += 4;
161 wiinst->buffer.cov = 2;
163 wiinst->buffer.cov = 1;
165 if (alloc_buffer(card, &wiinst->buffer) < 0) {
170 emu10k1_set_record_src(card, wiinst);
172 emu10k1_reset_record(card, &wiinst->buffer);
174 wiinst->buffer.hw_pos = 0;
175 wiinst->buffer.pos = 0;
176 wiinst->buffer.bytestocopy = 0;
178 delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
180 emu10k1_timer_install(card, &wiinst->timer, delay / 2);
182 wiinst->state = WAVE_STATE_OPEN;
187 void emu10k1_wavein_close(struct emu10k1_wavedevice *wave_dev)
189 struct emu10k1_card *card = wave_dev->card;
190 struct wiinst *wiinst = wave_dev->wiinst;
193 DPF(2, "emu10k1_wavein_close()\n");
195 emu10k1_wavein_stop(wave_dev);
197 emu10k1_timer_uninstall(card, &wiinst->timer);
199 free_buffer(card, &wiinst->buffer);
201 spin_lock_irqsave(&card->lock, flags);
202 switch (wave_dev->wiinst->recsrc) {
203 case WAVERECORD_AC97:
204 card->wavein.ac97 = NULL;
207 card->wavein.mic = NULL;
210 card->wavein.fx = NULL;
216 spin_unlock_irqrestore(&card->lock, flags);
218 wiinst->state = WAVE_STATE_CLOSED;
221 void emu10k1_wavein_start(struct emu10k1_wavedevice *wave_dev)
223 struct emu10k1_card *card = wave_dev->card;
224 struct wiinst *wiinst = wave_dev->wiinst;
226 DPF(2, "emu10k1_wavein_start()\n");
228 emu10k1_start_record(card, &wiinst->buffer);
229 emu10k1_timer_enable(wave_dev->card, &wiinst->timer);
231 wiinst->state |= WAVE_STATE_STARTED;
234 void emu10k1_wavein_stop(struct emu10k1_wavedevice *wave_dev)
236 struct emu10k1_card *card = wave_dev->card;
237 struct wiinst *wiinst = wave_dev->wiinst;
239 DPF(2, "emu10k1_wavein_stop()\n");
241 if (!(wiinst->state & WAVE_STATE_STARTED))
244 emu10k1_timer_disable(card, &wiinst->timer);
245 emu10k1_stop_record(card, &wiinst->buffer);
247 wiinst->state &= ~WAVE_STATE_STARTED;
250 int emu10k1_wavein_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_format *format)
252 struct emu10k1_card *card = wave_dev->card;
253 struct wiinst *wiinst = wave_dev->wiinst;
256 DPF(2, "emu10k1_wavein_setformat()\n");
258 if (wiinst->state & WAVE_STATE_STARTED)
261 query_format(wiinst->recsrc, format);
263 if ((wiinst->format.samplingrate != format->samplingrate)
264 || (wiinst->format.bitsperchannel != format->bitsperchannel)
265 || (wiinst->format.channels != format->channels)) {
267 wiinst->format = *format;
269 if (wiinst->state == WAVE_STATE_CLOSED)
272 wiinst->buffer.size *= wiinst->buffer.cov;
274 if (wiinst->format.bytesperchannel == 1) {
275 wiinst->buffer.cov = 2;
276 wiinst->buffer.size /= wiinst->buffer.cov;
278 wiinst->buffer.cov = 1;
280 emu10k1_timer_uninstall(card, &wiinst->timer);
282 delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
284 emu10k1_timer_install(card, &wiinst->timer, delay / 2);
290 void emu10k1_wavein_getxfersize(struct wiinst *wiinst, u32 * size)
292 struct wavein_buffer *buffer = &wiinst->buffer;
294 *size = buffer->bytestocopy;
299 if (*size > buffer->size) {
300 *size = buffer->size;
301 buffer->pos = buffer->hw_pos;
302 buffer->bytestocopy = buffer->size;
303 DPF(1, "buffer overrun\n");
307 static int copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov)
310 if (__copy_to_user(dst, src + str, len))
318 for (i = 0; i < len; i++) {
319 byte = src[2 * i] ^ 0x80;
320 if (__copy_to_user(dst + i, &byte, 1))
328 int emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size)
330 struct wavein_buffer *buffer = &wiinst->buffer;
331 u32 sizetocopy, sizetocopy_now, start;
335 sizetocopy = min_t(u32, buffer->size, *size);
341 spin_lock_irqsave(&wiinst->lock, flags);
343 buffer->pos += sizetocopy;
344 buffer->pos %= buffer->size;
345 buffer->bytestocopy -= sizetocopy;
346 sizetocopy_now = buffer->size - start;
348 spin_unlock_irqrestore(&wiinst->lock, flags);
350 if (sizetocopy > sizetocopy_now) {
351 sizetocopy -= sizetocopy_now;
353 ret = copy_block(data, buffer->addr, start, sizetocopy_now,
356 ret = copy_block(data + sizetocopy_now, buffer->addr, 0,
357 sizetocopy, buffer->cov);
359 ret = copy_block(data, buffer->addr, start, sizetocopy,
366 void emu10k1_wavein_update(struct emu10k1_card *card, struct wiinst *wiinst)
371 /* There is no actual start yet */
372 if (!(wiinst->state & WAVE_STATE_STARTED)) {
373 hw_pos = wiinst->buffer.hw_pos;
375 /* hw_pos in byte units */
376 hw_pos = sblive_readptr(card, wiinst->buffer.idxreg, 0) / wiinst->buffer.cov;
379 diff = (wiinst->buffer.size + hw_pos - wiinst->buffer.hw_pos) % wiinst->buffer.size;
380 wiinst->total_recorded += diff;
381 wiinst->buffer.bytestocopy += diff;
383 wiinst->buffer.hw_pos = hw_pos;