1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
4 | * Routines for control of 16-bit SoundBlaster cards and clones |
5 | * Note: This is very ugly hardware which uses one 8-bit DMA channel and |
6 | * second 16-bit DMA channel. Unfortunately 8-bit DMA channel can't |
7 | * transfer 16-bit samples and 16-bit DMA channels can't transfer |
8 | * 8-bit samples. This make full duplex more complicated than |
9 | * can be... People, don't buy these soundcards for full 16-bit |
10 | * duplex!!! |
11 | * Note: 16-bit wide is assigned to first direction which made request. |
12 | * With full duplex - playback is preferred with abstract layer. |
13 | * |
14 | * Note: Some chip revisions have hardware bug. Changing capture |
15 | * channel from full-duplex 8bit DMA to 16bit DMA will block |
16 | * 16bit DMA transfers from DSP chip (capture) until 8bit transfer |
17 | * to DSP chip (playback) starts. This bug can be avoided with |
18 | * "16bit DMA Allocation" setting set to Playback or Capture. |
19 | */ |
20 | |
21 | #include <linux/io.h> |
22 | #include <asm/dma.h> |
23 | #include <linux/init.h> |
24 | #include <linux/time.h> |
25 | #include <linux/module.h> |
26 | #include <sound/core.h> |
27 | #include <sound/sb.h> |
28 | #include <sound/sb16_csp.h> |
29 | #include <sound/mpu401.h> |
30 | #include <sound/control.h> |
31 | #include <sound/info.h> |
32 | |
33 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>" ); |
34 | MODULE_DESCRIPTION("Routines for control of 16-bit SoundBlaster cards and clones" ); |
35 | MODULE_LICENSE("GPL" ); |
36 | |
37 | #define runtime_format_bits(runtime) \ |
38 | ((unsigned int)pcm_format_to_bits((runtime)->format)) |
39 | |
40 | #ifdef CONFIG_SND_SB16_CSP |
41 | static void snd_sb16_csp_playback_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime) |
42 | { |
43 | if (chip->hardware == SB_HW_16CSP) { |
44 | struct snd_sb_csp *csp = chip->csp; |
45 | |
46 | if (csp->running & SNDRV_SB_CSP_ST_LOADED) { |
47 | /* manually loaded codec */ |
48 | if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) && |
49 | (runtime_format_bits(runtime) == csp->acc_format)) { |
50 | /* Supported runtime PCM format for playback */ |
51 | if (csp->ops.csp_use(csp) == 0) { |
52 | /* If CSP was successfully acquired */ |
53 | goto __start_CSP; |
54 | } |
55 | } else if ((csp->mode & SNDRV_SB_CSP_MODE_QSOUND) && (csp->q_enabled)) { |
56 | /* QSound decoder is loaded and enabled */ |
57 | if (runtime_format_bits(runtime) & (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | |
58 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE)) { |
59 | /* Only for simple PCM formats */ |
60 | if (csp->ops.csp_use(csp) == 0) { |
61 | /* If CSP was successfully acquired */ |
62 | goto __start_CSP; |
63 | } |
64 | } |
65 | } |
66 | } else if (csp->ops.csp_use(csp) == 0) { |
67 | /* Acquire CSP and try to autoload hardware codec */ |
68 | if (csp->ops.csp_autoload(csp, runtime->format, SNDRV_SB_CSP_MODE_DSP_WRITE)) { |
69 | /* Unsupported format, release CSP */ |
70 | csp->ops.csp_unuse(csp); |
71 | } else { |
72 | __start_CSP: |
73 | /* Try to start CSP */ |
74 | if (csp->ops.csp_start(csp, (chip->mode & SB_MODE_PLAYBACK_16) ? |
75 | SNDRV_SB_CSP_SAMPLE_16BIT : SNDRV_SB_CSP_SAMPLE_8BIT, |
76 | (runtime->channels > 1) ? |
77 | SNDRV_SB_CSP_STEREO : SNDRV_SB_CSP_MONO)) { |
78 | /* Failed, release CSP */ |
79 | csp->ops.csp_unuse(csp); |
80 | } else { |
81 | /* Success, CSP acquired and running */ |
82 | chip->open = SNDRV_SB_CSP_MODE_DSP_WRITE; |
83 | } |
84 | } |
85 | } |
86 | } |
87 | } |
88 | |
89 | static void snd_sb16_csp_capture_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime) |
90 | { |
91 | if (chip->hardware == SB_HW_16CSP) { |
92 | struct snd_sb_csp *csp = chip->csp; |
93 | |
94 | if (csp->running & SNDRV_SB_CSP_ST_LOADED) { |
95 | /* manually loaded codec */ |
96 | if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) && |
97 | (runtime_format_bits(runtime) == csp->acc_format)) { |
98 | /* Supported runtime PCM format for capture */ |
99 | if (csp->ops.csp_use(csp) == 0) { |
100 | /* If CSP was successfully acquired */ |
101 | goto __start_CSP; |
102 | } |
103 | } |
104 | } else if (csp->ops.csp_use(csp) == 0) { |
105 | /* Acquire CSP and try to autoload hardware codec */ |
106 | if (csp->ops.csp_autoload(csp, runtime->format, SNDRV_SB_CSP_MODE_DSP_READ)) { |
107 | /* Unsupported format, release CSP */ |
108 | csp->ops.csp_unuse(csp); |
109 | } else { |
110 | __start_CSP: |
111 | /* Try to start CSP */ |
112 | if (csp->ops.csp_start(csp, (chip->mode & SB_MODE_CAPTURE_16) ? |
113 | SNDRV_SB_CSP_SAMPLE_16BIT : SNDRV_SB_CSP_SAMPLE_8BIT, |
114 | (runtime->channels > 1) ? |
115 | SNDRV_SB_CSP_STEREO : SNDRV_SB_CSP_MONO)) { |
116 | /* Failed, release CSP */ |
117 | csp->ops.csp_unuse(csp); |
118 | } else { |
119 | /* Success, CSP acquired and running */ |
120 | chip->open = SNDRV_SB_CSP_MODE_DSP_READ; |
121 | } |
122 | } |
123 | } |
124 | } |
125 | } |
126 | |
127 | static void snd_sb16_csp_update(struct snd_sb *chip) |
128 | { |
129 | if (chip->hardware == SB_HW_16CSP) { |
130 | struct snd_sb_csp *csp = chip->csp; |
131 | |
132 | if (csp->qpos_changed) { |
133 | spin_lock(lock: &chip->reg_lock); |
134 | csp->ops.csp_qsound_transfer (csp); |
135 | spin_unlock(lock: &chip->reg_lock); |
136 | } |
137 | } |
138 | } |
139 | |
140 | static void snd_sb16_csp_playback_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime) |
141 | { |
142 | /* CSP decoders (QSound excluded) support only 16bit transfers */ |
143 | if (chip->hardware == SB_HW_16CSP) { |
144 | struct snd_sb_csp *csp = chip->csp; |
145 | |
146 | if (csp->running & SNDRV_SB_CSP_ST_LOADED) { |
147 | /* manually loaded codec */ |
148 | if (csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) { |
149 | runtime->hw.formats |= csp->acc_format; |
150 | } |
151 | } else { |
152 | /* autoloaded codecs */ |
153 | runtime->hw.formats |= SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | |
154 | SNDRV_PCM_FMTBIT_IMA_ADPCM; |
155 | } |
156 | } |
157 | } |
158 | |
159 | static void snd_sb16_csp_playback_close(struct snd_sb *chip) |
160 | { |
161 | if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_WRITE)) { |
162 | struct snd_sb_csp *csp = chip->csp; |
163 | |
164 | if (csp->ops.csp_stop(csp) == 0) { |
165 | csp->ops.csp_unuse(csp); |
166 | chip->open = 0; |
167 | } |
168 | } |
169 | } |
170 | |
171 | static void snd_sb16_csp_capture_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime) |
172 | { |
173 | /* CSP coders support only 16bit transfers */ |
174 | if (chip->hardware == SB_HW_16CSP) { |
175 | struct snd_sb_csp *csp = chip->csp; |
176 | |
177 | if (csp->running & SNDRV_SB_CSP_ST_LOADED) { |
178 | /* manually loaded codec */ |
179 | if (csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) { |
180 | runtime->hw.formats |= csp->acc_format; |
181 | } |
182 | } else { |
183 | /* autoloaded codecs */ |
184 | runtime->hw.formats |= SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | |
185 | SNDRV_PCM_FMTBIT_IMA_ADPCM; |
186 | } |
187 | } |
188 | } |
189 | |
190 | static void snd_sb16_csp_capture_close(struct snd_sb *chip) |
191 | { |
192 | if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_READ)) { |
193 | struct snd_sb_csp *csp = chip->csp; |
194 | |
195 | if (csp->ops.csp_stop(csp) == 0) { |
196 | csp->ops.csp_unuse(csp); |
197 | chip->open = 0; |
198 | } |
199 | } |
200 | } |
201 | #else |
202 | #define snd_sb16_csp_playback_prepare(chip, runtime) /*nop*/ |
203 | #define snd_sb16_csp_capture_prepare(chip, runtime) /*nop*/ |
204 | #define snd_sb16_csp_update(chip) /*nop*/ |
205 | #define snd_sb16_csp_playback_open(chip, runtime) /*nop*/ |
206 | #define snd_sb16_csp_playback_close(chip) /*nop*/ |
207 | #define snd_sb16_csp_capture_open(chip, runtime) /*nop*/ |
208 | #define snd_sb16_csp_capture_close(chip) /*nop*/ |
209 | #endif |
210 | |
211 | |
212 | static void snd_sb16_setup_rate(struct snd_sb *chip, |
213 | unsigned short rate, |
214 | int channel) |
215 | { |
216 | unsigned long flags; |
217 | |
218 | spin_lock_irqsave(&chip->reg_lock, flags); |
219 | if (chip->mode & (channel == SNDRV_PCM_STREAM_PLAYBACK ? SB_MODE_PLAYBACK_16 : SB_MODE_CAPTURE_16)) |
220 | snd_sb_ack_16bit(chip); |
221 | else |
222 | snd_sb_ack_8bit(chip); |
223 | if (!(chip->mode & SB_RATE_LOCK)) { |
224 | chip->locked_rate = rate; |
225 | snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_IN); |
226 | snd_sbdsp_command(chip, val: rate >> 8); |
227 | snd_sbdsp_command(chip, val: rate & 0xff); |
228 | snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_OUT); |
229 | snd_sbdsp_command(chip, val: rate >> 8); |
230 | snd_sbdsp_command(chip, val: rate & 0xff); |
231 | } |
232 | spin_unlock_irqrestore(lock: &chip->reg_lock, flags); |
233 | } |
234 | |
235 | static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream) |
236 | { |
237 | unsigned long flags; |
238 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
239 | struct snd_pcm_runtime *runtime = substream->runtime; |
240 | unsigned char format; |
241 | unsigned int size, count, dma; |
242 | |
243 | snd_sb16_csp_playback_prepare(chip, runtime); |
244 | if (snd_pcm_format_unsigned(format: runtime->format) > 0) { |
245 | format = runtime->channels > 1 ? SB_DSP4_MODE_UNS_STEREO : SB_DSP4_MODE_UNS_MONO; |
246 | } else { |
247 | format = runtime->channels > 1 ? SB_DSP4_MODE_SIGN_STEREO : SB_DSP4_MODE_SIGN_MONO; |
248 | } |
249 | |
250 | snd_sb16_setup_rate(chip, rate: runtime->rate, channel: SNDRV_PCM_STREAM_PLAYBACK); |
251 | size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); |
252 | dma = (chip->mode & SB_MODE_PLAYBACK_8) ? chip->dma8 : chip->dma16; |
253 | snd_dma_program(dma, addr: runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); |
254 | |
255 | count = snd_pcm_lib_period_bytes(substream); |
256 | spin_lock_irqsave(&chip->reg_lock, flags); |
257 | if (chip->mode & SB_MODE_PLAYBACK_16) { |
258 | count >>= 1; |
259 | count--; |
260 | snd_sbdsp_command(chip, SB_DSP4_OUT16_AI); |
261 | snd_sbdsp_command(chip, val: format); |
262 | snd_sbdsp_command(chip, val: count & 0xff); |
263 | snd_sbdsp_command(chip, val: count >> 8); |
264 | snd_sbdsp_command(chip, SB_DSP_DMA16_OFF); |
265 | } else { |
266 | count--; |
267 | snd_sbdsp_command(chip, SB_DSP4_OUT8_AI); |
268 | snd_sbdsp_command(chip, val: format); |
269 | snd_sbdsp_command(chip, val: count & 0xff); |
270 | snd_sbdsp_command(chip, val: count >> 8); |
271 | snd_sbdsp_command(chip, SB_DSP_DMA8_OFF); |
272 | } |
273 | spin_unlock_irqrestore(lock: &chip->reg_lock, flags); |
274 | return 0; |
275 | } |
276 | |
277 | static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream, |
278 | int cmd) |
279 | { |
280 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
281 | int result = 0; |
282 | |
283 | spin_lock(lock: &chip->reg_lock); |
284 | switch (cmd) { |
285 | case SNDRV_PCM_TRIGGER_START: |
286 | case SNDRV_PCM_TRIGGER_RESUME: |
287 | chip->mode |= SB_RATE_LOCK_PLAYBACK; |
288 | snd_sbdsp_command(chip, val: chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON); |
289 | break; |
290 | case SNDRV_PCM_TRIGGER_STOP: |
291 | case SNDRV_PCM_TRIGGER_SUSPEND: |
292 | snd_sbdsp_command(chip, val: chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF); |
293 | /* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */ |
294 | if (chip->mode & SB_RATE_LOCK_CAPTURE) |
295 | snd_sbdsp_command(chip, val: chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON); |
296 | chip->mode &= ~SB_RATE_LOCK_PLAYBACK; |
297 | break; |
298 | default: |
299 | result = -EINVAL; |
300 | } |
301 | spin_unlock(lock: &chip->reg_lock); |
302 | return result; |
303 | } |
304 | |
305 | static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream) |
306 | { |
307 | unsigned long flags; |
308 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
309 | struct snd_pcm_runtime *runtime = substream->runtime; |
310 | unsigned char format; |
311 | unsigned int size, count, dma; |
312 | |
313 | snd_sb16_csp_capture_prepare(chip, runtime); |
314 | if (snd_pcm_format_unsigned(format: runtime->format) > 0) { |
315 | format = runtime->channels > 1 ? SB_DSP4_MODE_UNS_STEREO : SB_DSP4_MODE_UNS_MONO; |
316 | } else { |
317 | format = runtime->channels > 1 ? SB_DSP4_MODE_SIGN_STEREO : SB_DSP4_MODE_SIGN_MONO; |
318 | } |
319 | snd_sb16_setup_rate(chip, rate: runtime->rate, channel: SNDRV_PCM_STREAM_CAPTURE); |
320 | size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); |
321 | dma = (chip->mode & SB_MODE_CAPTURE_8) ? chip->dma8 : chip->dma16; |
322 | snd_dma_program(dma, addr: runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); |
323 | |
324 | count = snd_pcm_lib_period_bytes(substream); |
325 | spin_lock_irqsave(&chip->reg_lock, flags); |
326 | if (chip->mode & SB_MODE_CAPTURE_16) { |
327 | count >>= 1; |
328 | count--; |
329 | snd_sbdsp_command(chip, SB_DSP4_IN16_AI); |
330 | snd_sbdsp_command(chip, val: format); |
331 | snd_sbdsp_command(chip, val: count & 0xff); |
332 | snd_sbdsp_command(chip, val: count >> 8); |
333 | snd_sbdsp_command(chip, SB_DSP_DMA16_OFF); |
334 | } else { |
335 | count--; |
336 | snd_sbdsp_command(chip, SB_DSP4_IN8_AI); |
337 | snd_sbdsp_command(chip, val: format); |
338 | snd_sbdsp_command(chip, val: count & 0xff); |
339 | snd_sbdsp_command(chip, val: count >> 8); |
340 | snd_sbdsp_command(chip, SB_DSP_DMA8_OFF); |
341 | } |
342 | spin_unlock_irqrestore(lock: &chip->reg_lock, flags); |
343 | return 0; |
344 | } |
345 | |
346 | static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream, |
347 | int cmd) |
348 | { |
349 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
350 | int result = 0; |
351 | |
352 | spin_lock(lock: &chip->reg_lock); |
353 | switch (cmd) { |
354 | case SNDRV_PCM_TRIGGER_START: |
355 | case SNDRV_PCM_TRIGGER_RESUME: |
356 | chip->mode |= SB_RATE_LOCK_CAPTURE; |
357 | snd_sbdsp_command(chip, val: chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON); |
358 | break; |
359 | case SNDRV_PCM_TRIGGER_STOP: |
360 | case SNDRV_PCM_TRIGGER_SUSPEND: |
361 | snd_sbdsp_command(chip, val: chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF); |
362 | /* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */ |
363 | if (chip->mode & SB_RATE_LOCK_PLAYBACK) |
364 | snd_sbdsp_command(chip, val: chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON); |
365 | chip->mode &= ~SB_RATE_LOCK_CAPTURE; |
366 | break; |
367 | default: |
368 | result = -EINVAL; |
369 | } |
370 | spin_unlock(lock: &chip->reg_lock); |
371 | return result; |
372 | } |
373 | |
374 | irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id) |
375 | { |
376 | struct snd_sb *chip = dev_id; |
377 | unsigned char status; |
378 | int ok; |
379 | |
380 | spin_lock(lock: &chip->mixer_lock); |
381 | status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS); |
382 | spin_unlock(lock: &chip->mixer_lock); |
383 | if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback) |
384 | chip->rmidi_callback(irq, chip->rmidi->private_data); |
385 | if (status & SB_IRQTYPE_8BIT) { |
386 | ok = 0; |
387 | if (chip->mode & SB_MODE_PLAYBACK_8) { |
388 | snd_pcm_period_elapsed(substream: chip->playback_substream); |
389 | snd_sb16_csp_update(chip); |
390 | ok++; |
391 | } |
392 | if (chip->mode & SB_MODE_CAPTURE_8) { |
393 | snd_pcm_period_elapsed(substream: chip->capture_substream); |
394 | ok++; |
395 | } |
396 | spin_lock(lock: &chip->reg_lock); |
397 | if (!ok) |
398 | snd_sbdsp_command(chip, SB_DSP_DMA8_OFF); |
399 | snd_sb_ack_8bit(chip); |
400 | spin_unlock(lock: &chip->reg_lock); |
401 | } |
402 | if (status & SB_IRQTYPE_16BIT) { |
403 | ok = 0; |
404 | if (chip->mode & SB_MODE_PLAYBACK_16) { |
405 | snd_pcm_period_elapsed(substream: chip->playback_substream); |
406 | snd_sb16_csp_update(chip); |
407 | ok++; |
408 | } |
409 | if (chip->mode & SB_MODE_CAPTURE_16) { |
410 | snd_pcm_period_elapsed(substream: chip->capture_substream); |
411 | ok++; |
412 | } |
413 | spin_lock(lock: &chip->reg_lock); |
414 | if (!ok) |
415 | snd_sbdsp_command(chip, SB_DSP_DMA16_OFF); |
416 | snd_sb_ack_16bit(chip); |
417 | spin_unlock(lock: &chip->reg_lock); |
418 | } |
419 | return IRQ_HANDLED; |
420 | } |
421 | |
422 | /* |
423 | |
424 | */ |
425 | |
426 | static snd_pcm_uframes_t snd_sb16_playback_pointer(struct snd_pcm_substream *substream) |
427 | { |
428 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
429 | unsigned int dma; |
430 | size_t ptr; |
431 | |
432 | dma = (chip->mode & SB_MODE_PLAYBACK_8) ? chip->dma8 : chip->dma16; |
433 | ptr = snd_dma_pointer(dma, size: chip->p_dma_size); |
434 | return bytes_to_frames(runtime: substream->runtime, size: ptr); |
435 | } |
436 | |
437 | static snd_pcm_uframes_t snd_sb16_capture_pointer(struct snd_pcm_substream *substream) |
438 | { |
439 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
440 | unsigned int dma; |
441 | size_t ptr; |
442 | |
443 | dma = (chip->mode & SB_MODE_CAPTURE_8) ? chip->dma8 : chip->dma16; |
444 | ptr = snd_dma_pointer(dma, size: chip->c_dma_size); |
445 | return bytes_to_frames(runtime: substream->runtime, size: ptr); |
446 | } |
447 | |
448 | /* |
449 | |
450 | */ |
451 | |
452 | static const struct snd_pcm_hardware snd_sb16_playback = |
453 | { |
454 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
455 | SNDRV_PCM_INFO_MMAP_VALID), |
456 | .formats = 0, |
457 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_44100, |
458 | .rate_min = 4000, |
459 | .rate_max = 44100, |
460 | .channels_min = 1, |
461 | .channels_max = 2, |
462 | .buffer_bytes_max = (128*1024), |
463 | .period_bytes_min = 64, |
464 | .period_bytes_max = (128*1024), |
465 | .periods_min = 1, |
466 | .periods_max = 1024, |
467 | .fifo_size = 0, |
468 | }; |
469 | |
470 | static const struct snd_pcm_hardware snd_sb16_capture = |
471 | { |
472 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
473 | SNDRV_PCM_INFO_MMAP_VALID), |
474 | .formats = 0, |
475 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_44100, |
476 | .rate_min = 4000, |
477 | .rate_max = 44100, |
478 | .channels_min = 1, |
479 | .channels_max = 2, |
480 | .buffer_bytes_max = (128*1024), |
481 | .period_bytes_min = 64, |
482 | .period_bytes_max = (128*1024), |
483 | .periods_min = 1, |
484 | .periods_max = 1024, |
485 | .fifo_size = 0, |
486 | }; |
487 | |
488 | /* |
489 | * open/close |
490 | */ |
491 | |
492 | static int snd_sb16_playback_open(struct snd_pcm_substream *substream) |
493 | { |
494 | unsigned long flags; |
495 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
496 | struct snd_pcm_runtime *runtime = substream->runtime; |
497 | |
498 | spin_lock_irqsave(&chip->open_lock, flags); |
499 | if (chip->mode & SB_MODE_PLAYBACK) { |
500 | spin_unlock_irqrestore(lock: &chip->open_lock, flags); |
501 | return -EAGAIN; |
502 | } |
503 | runtime->hw = snd_sb16_playback; |
504 | |
505 | /* skip if 16 bit DMA was reserved for capture */ |
506 | if (chip->force_mode16 & SB_MODE_CAPTURE_16) |
507 | goto __skip_16bit; |
508 | |
509 | if (chip->dma16 >= 0 && !(chip->mode & SB_MODE_CAPTURE_16)) { |
510 | chip->mode |= SB_MODE_PLAYBACK_16; |
511 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE; |
512 | /* Vibra16X hack */ |
513 | if (chip->dma16 <= 3) { |
514 | runtime->hw.buffer_bytes_max = |
515 | runtime->hw.period_bytes_max = 64 * 1024; |
516 | } else { |
517 | snd_sb16_csp_playback_open(chip, runtime); |
518 | } |
519 | goto __open_ok; |
520 | } |
521 | |
522 | __skip_16bit: |
523 | if (chip->dma8 >= 0 && !(chip->mode & SB_MODE_CAPTURE_8)) { |
524 | chip->mode |= SB_MODE_PLAYBACK_8; |
525 | /* DSP v 4.xx can transfer 16bit data through 8bit DMA channel, SBHWPG 2-7 */ |
526 | if (chip->dma16 < 0) { |
527 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE; |
528 | chip->mode |= SB_MODE_PLAYBACK_16; |
529 | } else { |
530 | runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8; |
531 | } |
532 | runtime->hw.buffer_bytes_max = |
533 | runtime->hw.period_bytes_max = 64 * 1024; |
534 | goto __open_ok; |
535 | } |
536 | spin_unlock_irqrestore(lock: &chip->open_lock, flags); |
537 | return -EAGAIN; |
538 | |
539 | __open_ok: |
540 | if (chip->hardware == SB_HW_ALS100) |
541 | runtime->hw.rate_max = 48000; |
542 | if (chip->hardware == SB_HW_CS5530) { |
543 | runtime->hw.buffer_bytes_max = 32 * 1024; |
544 | runtime->hw.periods_min = 2; |
545 | runtime->hw.rate_min = 44100; |
546 | } |
547 | if (chip->mode & SB_RATE_LOCK) |
548 | runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; |
549 | chip->playback_substream = substream; |
550 | spin_unlock_irqrestore(lock: &chip->open_lock, flags); |
551 | return 0; |
552 | } |
553 | |
554 | static int snd_sb16_playback_close(struct snd_pcm_substream *substream) |
555 | { |
556 | unsigned long flags; |
557 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
558 | |
559 | snd_sb16_csp_playback_close(chip); |
560 | spin_lock_irqsave(&chip->open_lock, flags); |
561 | chip->playback_substream = NULL; |
562 | chip->mode &= ~SB_MODE_PLAYBACK; |
563 | spin_unlock_irqrestore(lock: &chip->open_lock, flags); |
564 | return 0; |
565 | } |
566 | |
567 | static int snd_sb16_capture_open(struct snd_pcm_substream *substream) |
568 | { |
569 | unsigned long flags; |
570 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
571 | struct snd_pcm_runtime *runtime = substream->runtime; |
572 | |
573 | spin_lock_irqsave(&chip->open_lock, flags); |
574 | if (chip->mode & SB_MODE_CAPTURE) { |
575 | spin_unlock_irqrestore(lock: &chip->open_lock, flags); |
576 | return -EAGAIN; |
577 | } |
578 | runtime->hw = snd_sb16_capture; |
579 | |
580 | /* skip if 16 bit DMA was reserved for playback */ |
581 | if (chip->force_mode16 & SB_MODE_PLAYBACK_16) |
582 | goto __skip_16bit; |
583 | |
584 | if (chip->dma16 >= 0 && !(chip->mode & SB_MODE_PLAYBACK_16)) { |
585 | chip->mode |= SB_MODE_CAPTURE_16; |
586 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE; |
587 | /* Vibra16X hack */ |
588 | if (chip->dma16 <= 3) { |
589 | runtime->hw.buffer_bytes_max = |
590 | runtime->hw.period_bytes_max = 64 * 1024; |
591 | } else { |
592 | snd_sb16_csp_capture_open(chip, runtime); |
593 | } |
594 | goto __open_ok; |
595 | } |
596 | |
597 | __skip_16bit: |
598 | if (chip->dma8 >= 0 && !(chip->mode & SB_MODE_PLAYBACK_8)) { |
599 | chip->mode |= SB_MODE_CAPTURE_8; |
600 | /* DSP v 4.xx can transfer 16bit data through 8bit DMA channel, SBHWPG 2-7 */ |
601 | if (chip->dma16 < 0) { |
602 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE; |
603 | chip->mode |= SB_MODE_CAPTURE_16; |
604 | } else { |
605 | runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8; |
606 | } |
607 | runtime->hw.buffer_bytes_max = |
608 | runtime->hw.period_bytes_max = 64 * 1024; |
609 | goto __open_ok; |
610 | } |
611 | spin_unlock_irqrestore(lock: &chip->open_lock, flags); |
612 | return -EAGAIN; |
613 | |
614 | __open_ok: |
615 | if (chip->hardware == SB_HW_ALS100) |
616 | runtime->hw.rate_max = 48000; |
617 | if (chip->hardware == SB_HW_CS5530) { |
618 | runtime->hw.buffer_bytes_max = 32 * 1024; |
619 | runtime->hw.periods_min = 2; |
620 | runtime->hw.rate_min = 44100; |
621 | } |
622 | if (chip->mode & SB_RATE_LOCK) |
623 | runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; |
624 | chip->capture_substream = substream; |
625 | spin_unlock_irqrestore(lock: &chip->open_lock, flags); |
626 | return 0; |
627 | } |
628 | |
629 | static int snd_sb16_capture_close(struct snd_pcm_substream *substream) |
630 | { |
631 | unsigned long flags; |
632 | struct snd_sb *chip = snd_pcm_substream_chip(substream); |
633 | |
634 | snd_sb16_csp_capture_close(chip); |
635 | spin_lock_irqsave(&chip->open_lock, flags); |
636 | chip->capture_substream = NULL; |
637 | chip->mode &= ~SB_MODE_CAPTURE; |
638 | spin_unlock_irqrestore(lock: &chip->open_lock, flags); |
639 | return 0; |
640 | } |
641 | |
642 | /* |
643 | * DMA control interface |
644 | */ |
645 | |
646 | static int snd_sb16_set_dma_mode(struct snd_sb *chip, int what) |
647 | { |
648 | if (chip->dma8 < 0 || chip->dma16 < 0) { |
649 | if (snd_BUG_ON(what)) |
650 | return -EINVAL; |
651 | return 0; |
652 | } |
653 | if (what == 0) { |
654 | chip->force_mode16 = 0; |
655 | } else if (what == 1) { |
656 | chip->force_mode16 = SB_MODE_PLAYBACK_16; |
657 | } else if (what == 2) { |
658 | chip->force_mode16 = SB_MODE_CAPTURE_16; |
659 | } else { |
660 | return -EINVAL; |
661 | } |
662 | return 0; |
663 | } |
664 | |
665 | static int snd_sb16_get_dma_mode(struct snd_sb *chip) |
666 | { |
667 | if (chip->dma8 < 0 || chip->dma16 < 0) |
668 | return 0; |
669 | switch (chip->force_mode16) { |
670 | case SB_MODE_PLAYBACK_16: |
671 | return 1; |
672 | case SB_MODE_CAPTURE_16: |
673 | return 2; |
674 | default: |
675 | return 0; |
676 | } |
677 | } |
678 | |
679 | static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
680 | { |
681 | static const char * const texts[3] = { |
682 | "Auto" , "Playback" , "Capture" |
683 | }; |
684 | |
685 | return snd_ctl_enum_info(info: uinfo, channels: 1, items: 3, names: texts); |
686 | } |
687 | |
688 | static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
689 | { |
690 | struct snd_sb *chip = snd_kcontrol_chip(kcontrol); |
691 | unsigned long flags; |
692 | |
693 | spin_lock_irqsave(&chip->reg_lock, flags); |
694 | ucontrol->value.enumerated.item[0] = snd_sb16_get_dma_mode(chip); |
695 | spin_unlock_irqrestore(lock: &chip->reg_lock, flags); |
696 | return 0; |
697 | } |
698 | |
699 | static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
700 | { |
701 | struct snd_sb *chip = snd_kcontrol_chip(kcontrol); |
702 | unsigned long flags; |
703 | unsigned char nval, oval; |
704 | int change; |
705 | |
706 | nval = ucontrol->value.enumerated.item[0]; |
707 | if (nval > 2) |
708 | return -EINVAL; |
709 | spin_lock_irqsave(&chip->reg_lock, flags); |
710 | oval = snd_sb16_get_dma_mode(chip); |
711 | change = nval != oval; |
712 | snd_sb16_set_dma_mode(chip, what: nval); |
713 | spin_unlock_irqrestore(lock: &chip->reg_lock, flags); |
714 | return change; |
715 | } |
716 | |
717 | static const struct snd_kcontrol_new snd_sb16_dma_control = { |
718 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, |
719 | .name = "16-bit DMA Allocation" , |
720 | .info = snd_sb16_dma_control_info, |
721 | .get = snd_sb16_dma_control_get, |
722 | .put = snd_sb16_dma_control_put |
723 | }; |
724 | |
725 | /* |
726 | * Initialization part |
727 | */ |
728 | |
729 | int snd_sb16dsp_configure(struct snd_sb * chip) |
730 | { |
731 | unsigned long flags; |
732 | unsigned char irqreg = 0, dmareg = 0, mpureg; |
733 | unsigned char realirq, realdma, realmpureg; |
734 | /* note: mpu register should be present only on SB16 Vibra soundcards */ |
735 | |
736 | // printk(KERN_DEBUG "codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16); |
737 | spin_lock_irqsave(&chip->mixer_lock, flags); |
738 | mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06; |
739 | spin_unlock_irqrestore(lock: &chip->mixer_lock, flags); |
740 | switch (chip->irq) { |
741 | case 2: |
742 | case 9: |
743 | irqreg |= SB_IRQSETUP_IRQ9; |
744 | break; |
745 | case 5: |
746 | irqreg |= SB_IRQSETUP_IRQ5; |
747 | break; |
748 | case 7: |
749 | irqreg |= SB_IRQSETUP_IRQ7; |
750 | break; |
751 | case 10: |
752 | irqreg |= SB_IRQSETUP_IRQ10; |
753 | break; |
754 | default: |
755 | return -EINVAL; |
756 | } |
757 | if (chip->dma8 >= 0) { |
758 | switch (chip->dma8) { |
759 | case 0: |
760 | dmareg |= SB_DMASETUP_DMA0; |
761 | break; |
762 | case 1: |
763 | dmareg |= SB_DMASETUP_DMA1; |
764 | break; |
765 | case 3: |
766 | dmareg |= SB_DMASETUP_DMA3; |
767 | break; |
768 | default: |
769 | return -EINVAL; |
770 | } |
771 | } |
772 | if (chip->dma16 >= 0 && chip->dma16 != chip->dma8) { |
773 | switch (chip->dma16) { |
774 | case 5: |
775 | dmareg |= SB_DMASETUP_DMA5; |
776 | break; |
777 | case 6: |
778 | dmareg |= SB_DMASETUP_DMA6; |
779 | break; |
780 | case 7: |
781 | dmareg |= SB_DMASETUP_DMA7; |
782 | break; |
783 | default: |
784 | return -EINVAL; |
785 | } |
786 | } |
787 | switch (chip->mpu_port) { |
788 | case 0x300: |
789 | mpureg |= 0x04; |
790 | break; |
791 | case 0x330: |
792 | mpureg |= 0x00; |
793 | break; |
794 | default: |
795 | mpureg |= 0x02; /* disable MPU */ |
796 | } |
797 | spin_lock_irqsave(&chip->mixer_lock, flags); |
798 | |
799 | snd_sbmixer_write(chip, SB_DSP4_IRQSETUP, data: irqreg); |
800 | realirq = snd_sbmixer_read(chip, SB_DSP4_IRQSETUP); |
801 | |
802 | snd_sbmixer_write(chip, SB_DSP4_DMASETUP, data: dmareg); |
803 | realdma = snd_sbmixer_read(chip, SB_DSP4_DMASETUP); |
804 | |
805 | snd_sbmixer_write(chip, SB_DSP4_MPUSETUP, data: mpureg); |
806 | realmpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP); |
807 | |
808 | spin_unlock_irqrestore(lock: &chip->mixer_lock, flags); |
809 | if ((~realirq) & irqreg || (~realdma) & dmareg) { |
810 | snd_printk(KERN_ERR "SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n" , chip->port); |
811 | snd_printk(KERN_ERR "SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n" , chip->port, realirq, realdma, realmpureg); |
812 | snd_printk(KERN_ERR "SB16 [0x%lx]: got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n" , chip->port, irqreg, dmareg, mpureg); |
813 | return -ENODEV; |
814 | } |
815 | return 0; |
816 | } |
817 | |
818 | static const struct snd_pcm_ops snd_sb16_playback_ops = { |
819 | .open = snd_sb16_playback_open, |
820 | .close = snd_sb16_playback_close, |
821 | .prepare = snd_sb16_playback_prepare, |
822 | .trigger = snd_sb16_playback_trigger, |
823 | .pointer = snd_sb16_playback_pointer, |
824 | }; |
825 | |
826 | static const struct snd_pcm_ops snd_sb16_capture_ops = { |
827 | .open = snd_sb16_capture_open, |
828 | .close = snd_sb16_capture_close, |
829 | .prepare = snd_sb16_capture_prepare, |
830 | .trigger = snd_sb16_capture_trigger, |
831 | .pointer = snd_sb16_capture_pointer, |
832 | }; |
833 | |
834 | int snd_sb16dsp_pcm(struct snd_sb *chip, int device) |
835 | { |
836 | struct snd_card *card = chip->card; |
837 | struct snd_pcm *pcm; |
838 | int err; |
839 | |
840 | err = snd_pcm_new(card, id: "SB16 DSP" , device, playback_count: 1, capture_count: 1, rpcm: &pcm); |
841 | if (err < 0) |
842 | return err; |
843 | sprintf(buf: pcm->name, fmt: "DSP v%i.%i" , chip->version >> 8, chip->version & 0xff); |
844 | pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; |
845 | pcm->private_data = chip; |
846 | chip->pcm = pcm; |
847 | |
848 | snd_pcm_set_ops(pcm, direction: SNDRV_PCM_STREAM_PLAYBACK, ops: &snd_sb16_playback_ops); |
849 | snd_pcm_set_ops(pcm, direction: SNDRV_PCM_STREAM_CAPTURE, ops: &snd_sb16_capture_ops); |
850 | |
851 | if (chip->dma16 >= 0 && chip->dma8 != chip->dma16) |
852 | snd_ctl_add(card, kcontrol: snd_ctl_new1(kcontrolnew: &snd_sb16_dma_control, private_data: chip)); |
853 | else |
854 | pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; |
855 | |
856 | snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, |
857 | data: card->dev, size: 64*1024, max: 128*1024); |
858 | return 0; |
859 | } |
860 | |
861 | const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction) |
862 | { |
863 | return direction == SNDRV_PCM_STREAM_PLAYBACK ? |
864 | &snd_sb16_playback_ops : &snd_sb16_capture_ops; |
865 | } |
866 | |
867 | EXPORT_SYMBOL(snd_sb16dsp_pcm); |
868 | EXPORT_SYMBOL(snd_sb16dsp_get_pcm_ops); |
869 | EXPORT_SYMBOL(snd_sb16dsp_configure); |
870 | EXPORT_SYMBOL(snd_sb16dsp_interrupt); |
871 | |