OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [sound/] [isa/] [sb/] [sb16_main.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.