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