~ubuntu-branches/ubuntu/maverick/linux-backports-modules-2.6.32/maverick

« back to all changes in this revision

Viewing changes to updates/alsa-driver/alsa-kernel/isa/msnd/msnd_pinnacle.c

  • Committer: Bazaar Package Importer
  • Author(s): Andy Whitcroft, Andy Whitcroft
  • Date: 2010-02-04 23:15:51 UTC
  • Revision ID: james.westby@ubuntu.com-20100204231551-vjz5pkvxclukjxm1
Tags: 2.6.32-12.1
[ Andy Whitcroft ]

* initial LBM for lucid
* drop generated files
* printchanges -- rebase tree does not have stable tags use changelog
* printenv -- add revisions to printenv output
* formally rename compat-wireless to linux-backports-modules-wireless
* Update to compat-wireless-2.6.33-rc5
* update nouveau to mainline 2.6.33-rc4
* add new LBM package for nouveau
* nouveau -- fix major numbers and proc entry names
* fix up firmware installs for -wireless
* clean up UPDATE-NOVEAU
* update Nouveau to v2.6.33-rc6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*********************************************************************
 
2
 *
 
3
 * Linux multisound pinnacle/fiji driver for ALSA.
 
4
 *
 
5
 * 2002/06/30 Karsten Wiese:
 
6
 *      for now this is only used to build a pinnacle / fiji driver.
 
7
 *      the OSS parent of this code is designed to also support
 
8
 *      the multisound classic via the file msnd_classic.c.
 
9
 *      to make it easier for some brave heart to implemt classic
 
10
 *      support in alsa, i left all the MSND_CLASSIC tokens in this file.
 
11
 *      but for now this untested & undone.
 
12
 *
 
13
 *
 
14
 * ripped from linux kernel 2.4.18 by Karsten Wiese.
 
15
 *
 
16
 * the following is a copy of the 2.4.18 OSS FREE file-heading comment:
 
17
 *
 
18
 * Turtle Beach MultiSound Sound Card Driver for Linux
 
19
 * msnd_pinnacle.c / msnd_classic.c
 
20
 *
 
21
 * -- If MSND_CLASSIC is defined:
 
22
 *
 
23
 *     -> driver for Turtle Beach Classic/Monterey/Tahiti
 
24
 *
 
25
 * -- Else
 
26
 *
 
27
 *     -> driver for Turtle Beach Pinnacle/Fiji
 
28
 *
 
29
 * 12-3-2000  Modified IO port validation  Steve Sycamore
 
30
 *
 
31
 * Copyright (C) 1998 Andrew Veliath
 
32
 *
 
33
 * This program is free software; you can redistribute it and/or modify
 
34
 * it under the terms of the GNU General Public License as published by
 
35
 * the Free Software Foundation; either version 2 of the License, or
 
36
 * (at your option) any later version.
 
37
 *
 
38
 * This program is distributed in the hope that it will be useful,
 
39
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
40
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
41
 * GNU General Public License for more details.
 
42
 *
 
43
 * You should have received a copy of the GNU General Public License
 
44
 * along with this program; if not, write to the Free Software
 
45
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
46
 *
 
47
 ********************************************************************/
 
48
 
 
49
#include <linux/kernel.h>
 
50
#include <linux/module.h>
 
51
#include <linux/interrupt.h>
 
52
#include <linux/types.h>
 
53
#include <linux/delay.h>
 
54
#include <linux/ioport.h>
 
55
#include <linux/firmware.h>
 
56
#include <linux/isa.h>
 
57
#include <linux/isapnp.h>
 
58
#include <linux/irq.h>
 
59
#include <linux/io.h>
 
60
 
 
61
#include <sound/core.h>
 
62
#include <sound/initval.h>
 
63
#include <sound/asound.h>
 
64
#include <sound/pcm.h>
 
65
#include <sound/mpu401.h>
 
66
 
 
67
#ifdef MSND_CLASSIC
 
68
# ifndef __alpha__
 
69
#  define SLOWIO
 
70
# endif
 
71
#endif
 
72
#include "msnd.h"
 
73
#ifdef MSND_CLASSIC
 
74
#  include "msnd_classic.h"
 
75
#  define LOGNAME                       "msnd_classic"
 
76
#else
 
77
#  include "msnd_pinnacle.h"
 
78
#  define LOGNAME                       "snd_msnd_pinnacle"
 
79
#endif
 
80
 
 
81
static void __devinit set_default_audio_parameters(struct snd_msnd *chip)
 
82
{
 
83
        chip->play_sample_size = DEFSAMPLESIZE;
 
84
        chip->play_sample_rate = DEFSAMPLERATE;
 
85
        chip->play_channels = DEFCHANNELS;
 
86
        chip->capture_sample_size = DEFSAMPLESIZE;
 
87
        chip->capture_sample_rate = DEFSAMPLERATE;
 
88
        chip->capture_channels = DEFCHANNELS;
 
89
}
 
90
 
 
91
static void snd_msnd_eval_dsp_msg(struct snd_msnd *chip, u16 wMessage)
 
92
{
 
93
        switch (HIBYTE(wMessage)) {
 
94
        case HIMT_PLAY_DONE: {
 
95
                if (chip->banksPlayed < 3)
 
96
                        snd_printdd("%08X: HIMT_PLAY_DONE: %i\n",
 
97
                                (unsigned)jiffies, LOBYTE(wMessage));
 
98
 
 
99
                if (chip->last_playbank == LOBYTE(wMessage)) {
 
100
                        snd_printdd("chip.last_playbank == LOBYTE(wMessage)\n");
 
101
                        break;
 
102
                }
 
103
                chip->banksPlayed++;
 
104
 
 
105
                if (test_bit(F_WRITING, &chip->flags))
 
106
                        snd_msnd_DAPQ(chip, 0);
 
107
 
 
108
                chip->last_playbank = LOBYTE(wMessage);
 
109
                chip->playDMAPos += chip->play_period_bytes;
 
110
                if (chip->playDMAPos > chip->playLimit)
 
111
                        chip->playDMAPos = 0;
 
112
                snd_pcm_period_elapsed(chip->playback_substream);
 
113
 
 
114
                break;
 
115
        }
 
116
        case HIMT_RECORD_DONE:
 
117
                if (chip->last_recbank == LOBYTE(wMessage))
 
118
                        break;
 
119
                chip->last_recbank = LOBYTE(wMessage);
 
120
                chip->captureDMAPos += chip->capturePeriodBytes;
 
121
                if (chip->captureDMAPos > (chip->captureLimit))
 
122
                        chip->captureDMAPos = 0;
 
123
 
 
124
                if (test_bit(F_READING, &chip->flags))
 
125
                        snd_msnd_DARQ(chip, chip->last_recbank);
 
126
 
 
127
                snd_pcm_period_elapsed(chip->capture_substream);
 
128
                break;
 
129
 
 
130
        case HIMT_DSP:
 
131
                switch (LOBYTE(wMessage)) {
 
132
#ifndef MSND_CLASSIC
 
133
                case HIDSP_PLAY_UNDER:
 
134
#endif
 
135
                case HIDSP_INT_PLAY_UNDER:
 
136
                        snd_printd(KERN_WARNING LOGNAME ": Play underflow %i\n",
 
137
                                chip->banksPlayed);
 
138
                        if (chip->banksPlayed > 2)
 
139
                                clear_bit(F_WRITING, &chip->flags);
 
140
                        break;
 
141
 
 
142
                case HIDSP_INT_RECORD_OVER:
 
143
                        snd_printd(KERN_WARNING LOGNAME ": Record overflow\n");
 
144
                        clear_bit(F_READING, &chip->flags);
 
145
                        break;
 
146
 
 
147
                default:
 
148
                        snd_printd(KERN_WARNING LOGNAME
 
149
                                   ": DSP message %d 0x%02x\n",
 
150
                                   LOBYTE(wMessage), LOBYTE(wMessage));
 
151
                        break;
 
152
                }
 
153
                break;
 
154
 
 
155
        case HIMT_MIDI_IN_UCHAR:
 
156
                if (chip->msndmidi_mpu)
 
157
                        snd_msndmidi_input_read(chip->msndmidi_mpu);
 
158
                break;
 
159
 
 
160
        default:
 
161
                snd_printd(KERN_WARNING LOGNAME ": HIMT message %d 0x%02x\n",
 
162
                           HIBYTE(wMessage), HIBYTE(wMessage));
 
163
                break;
 
164
        }
 
165
}
 
166
 
 
167
static irqreturn_t snd_msnd_interrupt(int irq, void *dev_id)
 
168
{
 
169
        struct snd_msnd *chip = dev_id;
 
170
        void *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF;
 
171
 
 
172
        /* Send ack to DSP */
 
173
        /* inb(chip->io + HP_RXL); */
 
174
 
 
175
        /* Evaluate queued DSP messages */
 
176
        while (readw(chip->DSPQ + JQS_wTail) != readw(chip->DSPQ + JQS_wHead)) {
 
177
                u16 wTmp;
 
178
 
 
179
                snd_msnd_eval_dsp_msg(chip,
 
180
                        readw(pwDSPQData + 2 * readw(chip->DSPQ + JQS_wHead)));
 
181
 
 
182
                wTmp = readw(chip->DSPQ + JQS_wHead) + 1;
 
183
                if (wTmp > readw(chip->DSPQ + JQS_wSize))
 
184
                        writew(0, chip->DSPQ + JQS_wHead);
 
185
                else
 
186
                        writew(wTmp, chip->DSPQ + JQS_wHead);
 
187
        }
 
188
        /* Send ack to DSP */
 
189
        inb(chip->io + HP_RXL);
 
190
        return IRQ_HANDLED;
 
191
}
 
192
 
 
193
 
 
194
static int snd_msnd_reset_dsp(long io, unsigned char *info)
 
195
{
 
196
        int timeout = 100;
 
197
 
 
198
        outb(HPDSPRESET_ON, io + HP_DSPR);
 
199
        msleep(1);
 
200
#ifndef MSND_CLASSIC
 
201
        if (info)
 
202
                *info = inb(io + HP_INFO);
 
203
#endif
 
204
        outb(HPDSPRESET_OFF, io + HP_DSPR);
 
205
        msleep(1);
 
206
        while (timeout-- > 0) {
 
207
                if (inb(io + HP_CVR) == HP_CVR_DEF)
 
208
                        return 0;
 
209
                msleep(1);
 
210
        }
 
211
        snd_printk(KERN_ERR LOGNAME ": Cannot reset DSP\n");
 
212
 
 
213
        return -EIO;
 
214
}
 
215
 
 
216
static int __devinit snd_msnd_probe(struct snd_card *card)
 
217
{
 
218
        struct snd_msnd *chip = card->private_data;
 
219
        unsigned char info;
 
220
#ifndef MSND_CLASSIC
 
221
        char *xv, *rev = NULL;
 
222
        char *pin = "TB Pinnacle", *fiji = "TB Fiji";
 
223
        char *pinfiji = "TB Pinnacle/Fiji";
 
224
#endif
 
225
 
 
226
        if (!request_region(chip->io, DSP_NUMIO, "probing")) {
 
227
                snd_printk(KERN_ERR LOGNAME ": I/O port conflict\n");
 
228
                return -ENODEV;
 
229
        }
 
230
 
 
231
        if (snd_msnd_reset_dsp(chip->io, &info) < 0) {
 
232
                release_region(chip->io, DSP_NUMIO);
 
233
                return -ENODEV;
 
234
        }
 
235
 
 
236
#ifdef MSND_CLASSIC
 
237
        strcpy(card->shortname, "Classic/Tahiti/Monterey");
 
238
        strcpy(card->longname, "Turtle Beach Multisound");
 
239
        printk(KERN_INFO LOGNAME ": %s, "
 
240
               "I/O 0x%lx-0x%lx, IRQ %d, memory mapped to 0x%lX-0x%lX\n",
 
241
               card->shortname,
 
242
               chip->io, chip->io + DSP_NUMIO - 1,
 
243
               chip->irq,
 
244
               chip->base, chip->base + 0x7fff);
 
245
#else
 
246
        switch (info >> 4) {
 
247
        case 0xf:
 
248
                xv = "<= 1.15";
 
249
                break;
 
250
        case 0x1:
 
251
                xv = "1.18/1.2";
 
252
                break;
 
253
        case 0x2:
 
254
                xv = "1.3";
 
255
                break;
 
256
        case 0x3:
 
257
                xv = "1.4";
 
258
                break;
 
259
        default:
 
260
                xv = "unknown";
 
261
                break;
 
262
        }
 
263
 
 
264
        switch (info & 0x7) {
 
265
        case 0x0:
 
266
                rev = "I";
 
267
                strcpy(card->shortname, pin);
 
268
                break;
 
269
        case 0x1:
 
270
                rev = "F";
 
271
                strcpy(card->shortname, pin);
 
272
                break;
 
273
        case 0x2:
 
274
                rev = "G";
 
275
                strcpy(card->shortname, pin);
 
276
                break;
 
277
        case 0x3:
 
278
                rev = "H";
 
279
                strcpy(card->shortname, pin);
 
280
                break;
 
281
        case 0x4:
 
282
                rev = "E";
 
283
                strcpy(card->shortname, fiji);
 
284
                break;
 
285
        case 0x5:
 
286
                rev = "C";
 
287
                strcpy(card->shortname, fiji);
 
288
                break;
 
289
        case 0x6:
 
290
                rev = "D";
 
291
                strcpy(card->shortname, fiji);
 
292
                break;
 
293
        case 0x7:
 
294
                rev = "A-B (Fiji) or A-E (Pinnacle)";
 
295
                strcpy(card->shortname, pinfiji);
 
296
                break;
 
297
        }
 
298
        strcpy(card->longname, "Turtle Beach Multisound Pinnacle");
 
299
        printk(KERN_INFO LOGNAME ": %s revision %s, Xilinx version %s, "
 
300
               "I/O 0x%lx-0x%lx, IRQ %d, memory mapped to 0x%lX-0x%lX\n",
 
301
               card->shortname,
 
302
               rev, xv,
 
303
               chip->io, chip->io + DSP_NUMIO - 1,
 
304
               chip->irq,
 
305
               chip->base, chip->base + 0x7fff);
 
306
#endif
 
307
 
 
308
        release_region(chip->io, DSP_NUMIO);
 
309
        return 0;
 
310
}
 
311
 
 
312
static int snd_msnd_init_sma(struct snd_msnd *chip)
 
313
{
 
314
        static int initted;
 
315
        u16 mastVolLeft, mastVolRight;
 
316
        unsigned long flags;
 
317
 
 
318
#ifdef MSND_CLASSIC
 
319
        outb(chip->memid, chip->io + HP_MEMM);
 
320
#endif
 
321
        outb(HPBLKSEL_0, chip->io + HP_BLKS);
 
322
        /* Motorola 56k shared memory base */
 
323
        chip->SMA = chip->mappedbase + SMA_STRUCT_START;
 
324
 
 
325
        if (initted) {
 
326
                mastVolLeft = readw(chip->SMA + SMA_wCurrMastVolLeft);
 
327
                mastVolRight = readw(chip->SMA + SMA_wCurrMastVolRight);
 
328
        } else
 
329
                mastVolLeft = mastVolRight = 0;
 
330
        memset_io(chip->mappedbase, 0, 0x8000);
 
331
 
 
332
        /* Critical section: bank 1 access */
 
333
        spin_lock_irqsave(&chip->lock, flags);
 
334
        outb(HPBLKSEL_1, chip->io + HP_BLKS);
 
335
        memset_io(chip->mappedbase, 0, 0x8000);
 
336
        outb(HPBLKSEL_0, chip->io + HP_BLKS);
 
337
        spin_unlock_irqrestore(&chip->lock, flags);
 
338
 
 
339
        /* Digital audio play queue */
 
340
        chip->DAPQ = chip->mappedbase + DAPQ_OFFSET;
 
341
        snd_msnd_init_queue(chip->DAPQ, DAPQ_DATA_BUFF, DAPQ_BUFF_SIZE);
 
342
 
 
343
        /* Digital audio record queue */
 
344
        chip->DARQ = chip->mappedbase + DARQ_OFFSET;
 
345
        snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE);
 
346
 
 
347
        /* MIDI out queue */
 
348
        chip->MODQ = chip->mappedbase + MODQ_OFFSET;
 
349
        snd_msnd_init_queue(chip->MODQ, MODQ_DATA_BUFF, MODQ_BUFF_SIZE);
 
350
 
 
351
        /* MIDI in queue */
 
352
        chip->MIDQ = chip->mappedbase + MIDQ_OFFSET;
 
353
        snd_msnd_init_queue(chip->MIDQ, MIDQ_DATA_BUFF, MIDQ_BUFF_SIZE);
 
354
 
 
355
        /* DSP -> host message queue */
 
356
        chip->DSPQ = chip->mappedbase + DSPQ_OFFSET;
 
357
        snd_msnd_init_queue(chip->DSPQ, DSPQ_DATA_BUFF, DSPQ_BUFF_SIZE);
 
358
 
 
359
        /* Setup some DSP values */
 
360
#ifndef MSND_CLASSIC
 
361
        writew(1, chip->SMA + SMA_wCurrPlayFormat);
 
362
        writew(chip->play_sample_size, chip->SMA + SMA_wCurrPlaySampleSize);
 
363
        writew(chip->play_channels, chip->SMA + SMA_wCurrPlayChannels);
 
364
        writew(chip->play_sample_rate, chip->SMA + SMA_wCurrPlaySampleRate);
 
365
#endif
 
366
        writew(chip->play_sample_rate, chip->SMA + SMA_wCalFreqAtoD);
 
367
        writew(mastVolLeft, chip->SMA + SMA_wCurrMastVolLeft);
 
368
        writew(mastVolRight, chip->SMA + SMA_wCurrMastVolRight);
 
369
#ifndef MSND_CLASSIC
 
370
        writel(0x00010000, chip->SMA + SMA_dwCurrPlayPitch);
 
371
        writel(0x00000001, chip->SMA + SMA_dwCurrPlayRate);
 
372
#endif
 
373
        writew(0x303, chip->SMA + SMA_wCurrInputTagBits);
 
374
 
 
375
        initted = 1;
 
376
 
 
377
        return 0;
 
378
}
 
379
 
 
380
 
 
381
static int upload_dsp_code(struct snd_card *card)
 
382
{
 
383
        struct snd_msnd *chip = card->private_data;
 
384
        const struct firmware *init_fw = NULL, *perm_fw = NULL;
 
385
        int err;
 
386
 
 
387
        outb(HPBLKSEL_0, chip->io + HP_BLKS);
 
388
 
 
389
        err = request_firmware(&init_fw, INITCODEFILE, card->dev);
 
390
        if (err < 0) {
 
391
                printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE);
 
392
                goto cleanup1;
 
393
        }
 
394
        err = request_firmware(&perm_fw, PERMCODEFILE, card->dev);
 
395
        if (err < 0) {
 
396
                printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE);
 
397
                goto cleanup;
 
398
        }
 
399
 
 
400
        memcpy_toio(chip->mappedbase, perm_fw->data, perm_fw->size);
 
401
        if (snd_msnd_upload_host(chip, init_fw->data, init_fw->size) < 0) {
 
402
                printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n");
 
403
                err = -ENODEV;
 
404
                goto cleanup;
 
405
        }
 
406
        printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n");
 
407
        err = 0;
 
408
 
 
409
cleanup:
 
410
        release_firmware(perm_fw);
 
411
cleanup1:
 
412
        release_firmware(init_fw);
 
413
        return err;
 
414
}
 
415
 
 
416
#ifdef MSND_CLASSIC
 
417
static void reset_proteus(struct snd_msnd *chip)
 
418
{
 
419
        outb(HPPRORESET_ON, chip->io + HP_PROR);
 
420
        msleep(TIME_PRO_RESET);
 
421
        outb(HPPRORESET_OFF, chip->io + HP_PROR);
 
422
        msleep(TIME_PRO_RESET_DONE);
 
423
}
 
424
#endif
 
425
 
 
426
static int snd_msnd_initialize(struct snd_card *card)
 
427
{
 
428
        struct snd_msnd *chip = card->private_data;
 
429
        int err, timeout;
 
430
 
 
431
#ifdef MSND_CLASSIC
 
432
        outb(HPWAITSTATE_0, chip->io + HP_WAIT);
 
433
        outb(HPBITMODE_16, chip->io + HP_BITM);
 
434
 
 
435
        reset_proteus(chip);
 
436
#endif
 
437
        err = snd_msnd_init_sma(chip);
 
438
        if (err < 0) {
 
439
                printk(KERN_WARNING LOGNAME ": Cannot initialize SMA\n");
 
440
                return err;
 
441
        }
 
442
 
 
443
        err = snd_msnd_reset_dsp(chip->io, NULL);
 
444
        if (err < 0)
 
445
                return err;
 
446
 
 
447
        err = upload_dsp_code(card);
 
448
        if (err < 0) {
 
449
                printk(KERN_WARNING LOGNAME ": Cannot upload DSP code\n");
 
450
                return err;
 
451
        }
 
452
 
 
453
        timeout = 200;
 
454
 
 
455
        while (readw(chip->mappedbase)) {
 
456
                msleep(1);
 
457
                if (!timeout--) {
 
458
                        snd_printd(KERN_ERR LOGNAME ": DSP reset timeout\n");
 
459
                        return -EIO;
 
460
                }
 
461
        }
 
462
 
 
463
        snd_msndmix_setup(chip);
 
464
        return 0;
 
465
}
 
466
 
 
467
static int snd_msnd_dsp_full_reset(struct snd_card *card)
 
468
{
 
469
        struct snd_msnd *chip = card->private_data;
 
470
        int rv;
 
471
 
 
472
        if (test_bit(F_RESETTING, &chip->flags) || ++chip->nresets > 10)
 
473
                return 0;
 
474
 
 
475
        set_bit(F_RESETTING, &chip->flags);
 
476
        snd_msnd_dsp_halt(chip, NULL);  /* Unconditionally halt */
 
477
 
 
478
        rv = snd_msnd_initialize(card);
 
479
        if (rv)
 
480
                printk(KERN_WARNING LOGNAME ": DSP reset failed\n");
 
481
        snd_msndmix_force_recsrc(chip, 0);
 
482
        clear_bit(F_RESETTING, &chip->flags);
 
483
        return rv;
 
484
}
 
485
 
 
486
static int snd_msnd_dev_free(struct snd_device *device)
 
487
{
 
488
        snd_printdd("snd_msnd_chip_free()\n");
 
489
        return 0;
 
490
}
 
491
 
 
492
static int snd_msnd_send_dsp_cmd_chk(struct snd_msnd *chip, u8 cmd)
 
493
{
 
494
        if (snd_msnd_send_dsp_cmd(chip, cmd) == 0)
 
495
                return 0;
 
496
        snd_msnd_dsp_full_reset(chip->card);
 
497
        return snd_msnd_send_dsp_cmd(chip, cmd);
 
498
}
 
499
 
 
500
static int __devinit snd_msnd_calibrate_adc(struct snd_msnd *chip, u16 srate)
 
501
{
 
502
        snd_printdd("snd_msnd_calibrate_adc(%i)\n", srate);
 
503
        writew(srate, chip->SMA + SMA_wCalFreqAtoD);
 
504
        if (chip->calibrate_signal == 0)
 
505
                writew(readw(chip->SMA + SMA_wCurrHostStatusFlags)
 
506
                       | 0x0001, chip->SMA + SMA_wCurrHostStatusFlags);
 
507
        else
 
508
                writew(readw(chip->SMA + SMA_wCurrHostStatusFlags)
 
509
                       & ~0x0001, chip->SMA + SMA_wCurrHostStatusFlags);
 
510
        if (snd_msnd_send_word(chip, 0, 0, HDEXAR_CAL_A_TO_D) == 0 &&
 
511
            snd_msnd_send_dsp_cmd_chk(chip, HDEX_AUX_REQ) == 0) {
 
512
                schedule_timeout_interruptible(msecs_to_jiffies(333));
 
513
                return 0;
 
514
        }
 
515
        printk(KERN_WARNING LOGNAME ": ADC calibration failed\n");
 
516
        return -EIO;
 
517
}
 
518
 
 
519
/*
 
520
 * ALSA callback function, called when attempting to open the MIDI device.
 
521
 */
 
522
static int snd_msnd_mpu401_open(struct snd_mpu401 *mpu)
 
523
{
 
524
        snd_msnd_enable_irq(mpu->private_data);
 
525
        snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_START);
 
526
        return 0;
 
527
}
 
528
 
 
529
static void snd_msnd_mpu401_close(struct snd_mpu401 *mpu)
 
530
{
 
531
        snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_STOP);
 
532
        snd_msnd_disable_irq(mpu->private_data);
 
533
}
 
534
 
 
535
static long mpu_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 
536
static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 
537
 
 
538
static int __devinit snd_msnd_attach(struct snd_card *card)
 
539
{
 
540
        struct snd_msnd *chip = card->private_data;
 
541
        int err;
 
542
        static struct snd_device_ops ops = {
 
543
                .dev_free =      snd_msnd_dev_free,
 
544
                };
 
545
 
 
546
        err = request_irq(chip->irq, snd_msnd_interrupt, 0, card->shortname,
 
547
                          chip);
 
548
        if (err < 0) {
 
549
                printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", chip->irq);
 
550
                return err;
 
551
        }
 
552
        request_region(chip->io, DSP_NUMIO, card->shortname);
 
553
 
 
554
        if (!request_mem_region(chip->base, BUFFSIZE, card->shortname)) {
 
555
                printk(KERN_ERR LOGNAME
 
556
                        ": unable to grab memory region 0x%lx-0x%lx\n",
 
557
                        chip->base, chip->base + BUFFSIZE - 1);
 
558
                release_region(chip->io, DSP_NUMIO);
 
559
                free_irq(chip->irq, chip);
 
560
                return -EBUSY;
 
561
        }
 
562
        chip->mappedbase = ioremap_nocache(chip->base, 0x8000);
 
563
        if (!chip->mappedbase) {
 
564
                printk(KERN_ERR LOGNAME
 
565
                        ": unable to map memory region 0x%lx-0x%lx\n",
 
566
                        chip->base, chip->base + BUFFSIZE - 1);
 
567
                err = -EIO;
 
568
                goto err_release_region;
 
569
        }
 
570
 
 
571
        err = snd_msnd_dsp_full_reset(card);
 
572
        if (err < 0)
 
573
                goto err_release_region;
 
574
 
 
575
        /* Register device */
 
576
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
 
577
        if (err < 0)
 
578
                goto err_release_region;
 
579
 
 
580
        err = snd_msnd_pcm(card, 0, NULL);
 
581
        if (err < 0) {
 
582
                printk(KERN_ERR LOGNAME ": error creating new PCM device\n");
 
583
                goto err_release_region;
 
584
        }
 
585
 
 
586
        err = snd_msndmix_new(card);
 
587
        if (err < 0) {
 
588
                printk(KERN_ERR LOGNAME ": error creating new Mixer device\n");
 
589
                goto err_release_region;
 
590
        }
 
591
 
 
592
 
 
593
        if (mpu_io[0] != SNDRV_AUTO_PORT) {
 
594
                struct snd_mpu401 *mpu;
 
595
 
 
596
                err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
 
597
                                          mpu_io[0],
 
598
                                          MPU401_MODE_INPUT |
 
599
                                          MPU401_MODE_OUTPUT,
 
600
                                          mpu_irq[0], IRQF_DISABLED,
 
601
                                          &chip->rmidi);
 
602
                if (err < 0) {
 
603
                        printk(KERN_ERR LOGNAME
 
604
                                ": error creating new Midi device\n");
 
605
                        goto err_release_region;
 
606
                }
 
607
                mpu = chip->rmidi->private_data;
 
608
 
 
609
                mpu->open_input = snd_msnd_mpu401_open;
 
610
                mpu->close_input = snd_msnd_mpu401_close;
 
611
                mpu->private_data = chip;
 
612
        }
 
613
 
 
614
        disable_irq(chip->irq);
 
615
        snd_msnd_calibrate_adc(chip, chip->play_sample_rate);
 
616
        snd_msndmix_force_recsrc(chip, 0);
 
617
 
 
618
        err = snd_card_register(card);
 
619
        if (err < 0)
 
620
                goto err_release_region;
 
621
 
 
622
        return 0;
 
623
 
 
624
err_release_region:
 
625
        if (chip->mappedbase)
 
626
                iounmap(chip->mappedbase);
 
627
        release_mem_region(chip->base, BUFFSIZE);
 
628
        release_region(chip->io, DSP_NUMIO);
 
629
        free_irq(chip->irq, chip);
 
630
        return err;
 
631
}
 
632
 
 
633
 
 
634
static void __devexit snd_msnd_unload(struct snd_card *card)
 
635
{
 
636
        struct snd_msnd *chip = card->private_data;
 
637
 
 
638
        iounmap(chip->mappedbase);
 
639
        release_mem_region(chip->base, BUFFSIZE);
 
640
        release_region(chip->io, DSP_NUMIO);
 
641
        free_irq(chip->irq, chip);
 
642
        snd_card_free(card);
 
643
}
 
644
 
 
645
#ifndef MSND_CLASSIC
 
646
 
 
647
/* Pinnacle/Fiji Logical Device Configuration */
 
648
 
 
649
static int __devinit snd_msnd_write_cfg(int cfg, int reg, int value)
 
650
{
 
651
        outb(reg, cfg);
 
652
        outb(value, cfg + 1);
 
653
        if (value != inb(cfg + 1)) {
 
654
                printk(KERN_ERR LOGNAME ": snd_msnd_write_cfg: I/O error\n");
 
655
                return -EIO;
 
656
        }
 
657
        return 0;
 
658
}
 
659
 
 
660
static int __devinit snd_msnd_write_cfg_io0(int cfg, int num, u16 io)
 
661
{
 
662
        if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 
663
                return -EIO;
 
664
        if (snd_msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io)))
 
665
                return -EIO;
 
666
        if (snd_msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io)))
 
667
                return -EIO;
 
668
        return 0;
 
669
}
 
670
 
 
671
static int __devinit snd_msnd_write_cfg_io1(int cfg, int num, u16 io)
 
672
{
 
673
        if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 
674
                return -EIO;
 
675
        if (snd_msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io)))
 
676
                return -EIO;
 
677
        if (snd_msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io)))
 
678
                return -EIO;
 
679
        return 0;
 
680
}
 
681
 
 
682
static int __devinit snd_msnd_write_cfg_irq(int cfg, int num, u16 irq)
 
683
{
 
684
        if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 
685
                return -EIO;
 
686
        if (snd_msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
 
687
                return -EIO;
 
688
        if (snd_msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
 
689
                return -EIO;
 
690
        return 0;
 
691
}
 
692
 
 
693
static int __devinit snd_msnd_write_cfg_mem(int cfg, int num, int mem)
 
694
{
 
695
        u16 wmem;
 
696
 
 
697
        mem >>= 8;
 
698
        wmem = (u16)(mem & 0xfff);
 
699
        if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 
700
                return -EIO;
 
701
        if (snd_msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
 
702
                return -EIO;
 
703
        if (snd_msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem)))
 
704
                return -EIO;
 
705
        if (wmem && snd_msnd_write_cfg(cfg, IREG_MEMCONTROL,
 
706
                                       MEMTYPE_HIADDR | MEMTYPE_16BIT))
 
707
                return -EIO;
 
708
        return 0;
 
709
}
 
710
 
 
711
static int __devinit snd_msnd_activate_logical(int cfg, int num)
 
712
{
 
713
        if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 
714
                return -EIO;
 
715
        if (snd_msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE))
 
716
                return -EIO;
 
717
        return 0;
 
718
}
 
719
 
 
720
static int __devinit snd_msnd_write_cfg_logical(int cfg, int num, u16 io0,
 
721
                                                u16 io1, u16 irq, int mem)
 
722
{
 
723
        if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 
724
                return -EIO;
 
725
        if (snd_msnd_write_cfg_io0(cfg, num, io0))
 
726
                return -EIO;
 
727
        if (snd_msnd_write_cfg_io1(cfg, num, io1))
 
728
                return -EIO;
 
729
        if (snd_msnd_write_cfg_irq(cfg, num, irq))
 
730
                return -EIO;
 
731
        if (snd_msnd_write_cfg_mem(cfg, num, mem))
 
732
                return -EIO;
 
733
        if (snd_msnd_activate_logical(cfg, num))
 
734
                return -EIO;
 
735
        return 0;
 
736
}
 
737
 
 
738
static int __devinit snd_msnd_pinnacle_cfg_reset(int cfg)
 
739
{
 
740
        int i;
 
741
 
 
742
        /* Reset devices if told to */
 
743
        printk(KERN_INFO LOGNAME ": Resetting all devices\n");
 
744
        for (i = 0; i < 4; ++i)
 
745
                if (snd_msnd_write_cfg_logical(cfg, i, 0, 0, 0, 0))
 
746
                        return -EIO;
 
747
 
 
748
        return 0;
 
749
}
 
750
#endif
 
751
 
 
752
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* Index 0-MAX */
 
753
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
 
754
 
 
755
module_param_array(index, int, NULL, S_IRUGO);
 
756
MODULE_PARM_DESC(index, "Index value for msnd_pinnacle soundcard.");
 
757
module_param_array(id, charp, NULL, S_IRUGO);
 
758
MODULE_PARM_DESC(id, "ID string for msnd_pinnacle soundcard.");
 
759
 
 
760
static long io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 
761
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 
762
static long mem[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 
763
 
 
764
static long cfg[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 
765
 
 
766
#ifndef MSND_CLASSIC
 
767
/* Extra Peripheral Configuration (Default: Disable) */
 
768
static long ide_io0[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 
769
static long ide_io1[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 
770
static int ide_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 
771
 
 
772
static long joystick_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 
773
/* If we have the digital daugherboard... */
 
774
static int digital[SNDRV_CARDS];
 
775
 
 
776
/* Extra Peripheral Configuration */
 
777
static int reset[SNDRV_CARDS];
 
778
#endif
 
779
 
 
780
static int write_ndelay[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 };
 
781
 
 
782
static int calibrate_signal;
 
783
 
 
784
#ifdef CONFIG_PNP
 
785
static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 
786
module_param_array(isapnp, bool, NULL, 0444);
 
787
MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
 
788
#define has_isapnp(x) isapnp[x]
 
789
#else
 
790
#define has_isapnp(x) 0
 
791
#endif
 
792
 
 
793
MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
 
794
MODULE_DESCRIPTION("Turtle Beach " LONGNAME " Linux Driver");
 
795
MODULE_LICENSE("GPL");
 
796
MODULE_FIRMWARE(INITCODEFILE);
 
797
MODULE_FIRMWARE(PERMCODEFILE);
 
798
 
 
799
module_param_array(io, long, NULL, S_IRUGO);
 
800
MODULE_PARM_DESC(io, "IO port #");
 
801
module_param_array(irq, int, NULL, S_IRUGO);
 
802
module_param_array(mem, long, NULL, S_IRUGO);
 
803
module_param_array(write_ndelay, int, NULL, S_IRUGO);
 
804
module_param(calibrate_signal, int, S_IRUGO);
 
805
#ifndef MSND_CLASSIC
 
806
module_param_array(digital, int, NULL, S_IRUGO);
 
807
module_param_array(cfg, long, NULL, S_IRUGO);
 
808
module_param_array(reset, int, 0, S_IRUGO);
 
809
module_param_array(mpu_io, long, NULL, S_IRUGO);
 
810
module_param_array(mpu_irq, int, NULL, S_IRUGO);
 
811
module_param_array(ide_io0, long, NULL, S_IRUGO);
 
812
module_param_array(ide_io1, long, NULL, S_IRUGO);
 
813
module_param_array(ide_irq, int, NULL, S_IRUGO);
 
814
module_param_array(joystick_io, long, NULL, S_IRUGO);
 
815
#endif
 
816
 
 
817
 
 
818
static int __devinit snd_msnd_isa_match(struct device *pdev, unsigned int i)
 
819
{
 
820
        if (io[i] == SNDRV_AUTO_PORT)
 
821
                return 0;
 
822
 
 
823
        if (irq[i] == SNDRV_AUTO_PORT || mem[i] == SNDRV_AUTO_PORT) {
 
824
                printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n");
 
825
                return 0;
 
826
        }
 
827
 
 
828
#ifdef MSND_CLASSIC
 
829
        if (!(io[i] == 0x290 ||
 
830
              io[i] == 0x260 ||
 
831
              io[i] == 0x250 ||
 
832
              io[i] == 0x240 ||
 
833
              io[i] == 0x230 ||
 
834
              io[i] == 0x220 ||
 
835
              io[i] == 0x210 ||
 
836
              io[i] == 0x3e0)) {
 
837
                printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set "
 
838
                        " to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, "
 
839
                        "or 0x3E0\n");
 
840
                return 0;
 
841
        }
 
842
#else
 
843
        if (io[i] < 0x100 || io[i] > 0x3e0 || (io[i] % 0x10) != 0) {
 
844
                printk(KERN_ERR LOGNAME
 
845
                        ": \"io\" - DSP I/O base must within the range 0x100 "
 
846
                        "to 0x3E0 and must be evenly divisible by 0x10\n");
 
847
                return 0;
 
848
        }
 
849
#endif /* MSND_CLASSIC */
 
850
 
 
851
        if (!(irq[i] == 5 ||
 
852
              irq[i] == 7 ||
 
853
              irq[i] == 9 ||
 
854
              irq[i] == 10 ||
 
855
              irq[i] == 11 ||
 
856
              irq[i] == 12)) {
 
857
                printk(KERN_ERR LOGNAME
 
858
                        ": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n");
 
859
                return 0;
 
860
        }
 
861
 
 
862
        if (!(mem[i] == 0xb0000 ||
 
863
              mem[i] == 0xc8000 ||
 
864
              mem[i] == 0xd0000 ||
 
865
              mem[i] == 0xd8000 ||
 
866
              mem[i] == 0xe0000 ||
 
867
              mem[i] == 0xe8000)) {
 
868
                printk(KERN_ERR LOGNAME ": \"mem\" - must be set to "
 
869
                       "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or "
 
870
                       "0xe8000\n");
 
871
                return 0;
 
872
        }
 
873
 
 
874
#ifndef MSND_CLASSIC
 
875
        if (cfg[i] == SNDRV_AUTO_PORT) {
 
876
                printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
 
877
        } else if (cfg[i] != 0x250 && cfg[i] != 0x260 && cfg[i] != 0x270) {
 
878
                printk(KERN_INFO LOGNAME
 
879
                        ": Config port must be 0x250, 0x260 or 0x270 "
 
880
                        "(or unspecified for PnP mode)\n");
 
881
                return 0;
 
882
        }
 
883
#endif /* MSND_CLASSIC */
 
884
 
 
885
        return 1;
 
886
}
 
887
 
 
888
static int __devinit snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
 
889
{
 
890
        int err;
 
891
        struct snd_card *card;
 
892
        struct snd_msnd *chip;
 
893
 
 
894
        if (has_isapnp(idx) || cfg[idx] == SNDRV_AUTO_PORT) {
 
895
                printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
 
896
                return -ENODEV;
 
897
        }
 
898
 
 
899
        err = snd_card_create(index[idx], id[idx], THIS_MODULE,
 
900
                              sizeof(struct snd_msnd), &card);
 
901
        if (err < 0)
 
902
                return err;
 
903
 
 
904
        snd_card_set_dev(card, pdev);
 
905
        chip = card->private_data;
 
906
        chip->card = card;
 
907
 
 
908
#ifdef MSND_CLASSIC
 
909
        switch (irq[idx]) {
 
910
        case 5:
 
911
                chip->irqid = HPIRQ_5; break;
 
912
        case 7:
 
913
                chip->irqid = HPIRQ_7; break;
 
914
        case 9:
 
915
                chip->irqid = HPIRQ_9; break;
 
916
        case 10:
 
917
                chip->irqid = HPIRQ_10; break;
 
918
        case 11:
 
919
                chip->irqid = HPIRQ_11; break;
 
920
        case 12:
 
921
                chip->irqid = HPIRQ_12; break;
 
922
        }
 
923
 
 
924
        switch (mem[idx]) {
 
925
        case 0xb0000:
 
926
                chip->memid = HPMEM_B000; break;
 
927
        case 0xc8000:
 
928
                chip->memid = HPMEM_C800; break;
 
929
        case 0xd0000:
 
930
                chip->memid = HPMEM_D000; break;
 
931
        case 0xd8000:
 
932
                chip->memid = HPMEM_D800; break;
 
933
        case 0xe0000:
 
934
                chip->memid = HPMEM_E000; break;
 
935
        case 0xe8000:
 
936
                chip->memid = HPMEM_E800; break;
 
937
        }
 
938
#else
 
939
        printk(KERN_INFO LOGNAME ": Non-PnP mode: configuring at port 0x%lx\n",
 
940
                        cfg[idx]);
 
941
 
 
942
        if (!request_region(cfg[idx], 2, "Pinnacle/Fiji Config")) {
 
943
                printk(KERN_ERR LOGNAME ": Config port 0x%lx conflict\n",
 
944
                           cfg[idx]);
 
945
                snd_card_free(card);
 
946
                return -EIO;
 
947
        }
 
948
        if (reset[idx])
 
949
                if (snd_msnd_pinnacle_cfg_reset(cfg[idx])) {
 
950
                        err = -EIO;
 
951
                        goto cfg_error;
 
952
                }
 
953
 
 
954
        /* DSP */
 
955
        err = snd_msnd_write_cfg_logical(cfg[idx], 0,
 
956
                                         io[idx], 0,
 
957
                                         irq[idx], mem[idx]);
 
958
 
 
959
        if (err)
 
960
                goto cfg_error;
 
961
 
 
962
        /* The following are Pinnacle specific */
 
963
 
 
964
        /* MPU */
 
965
        if (mpu_io[idx] != SNDRV_AUTO_PORT
 
966
            && mpu_irq[idx] != SNDRV_AUTO_IRQ) {
 
967
                printk(KERN_INFO LOGNAME
 
968
                       ": Configuring MPU to I/O 0x%lx IRQ %d\n",
 
969
                       mpu_io[idx], mpu_irq[idx]);
 
970
                err = snd_msnd_write_cfg_logical(cfg[idx], 1,
 
971
                                                 mpu_io[idx], 0,
 
972
                                                 mpu_irq[idx], 0);
 
973
 
 
974
                if (err)
 
975
                        goto cfg_error;
 
976
        }
 
977
 
 
978
        /* IDE */
 
979
        if (ide_io0[idx] != SNDRV_AUTO_PORT
 
980
            && ide_io1[idx] != SNDRV_AUTO_PORT
 
981
            && ide_irq[idx] != SNDRV_AUTO_IRQ) {
 
982
                printk(KERN_INFO LOGNAME
 
983
                       ": Configuring IDE to I/O 0x%lx, 0x%lx IRQ %d\n",
 
984
                       ide_io0[idx], ide_io1[idx], ide_irq[idx]);
 
985
                err = snd_msnd_write_cfg_logical(cfg[idx], 2,
 
986
                                                 ide_io0[idx], ide_io1[idx],
 
987
                                                 ide_irq[idx], 0);
 
988
 
 
989
                if (err)
 
990
                        goto cfg_error;
 
991
        }
 
992
 
 
993
        /* Joystick */
 
994
        if (joystick_io[idx] != SNDRV_AUTO_PORT) {
 
995
                printk(KERN_INFO LOGNAME
 
996
                       ": Configuring joystick to I/O 0x%lx\n",
 
997
                       joystick_io[idx]);
 
998
                err = snd_msnd_write_cfg_logical(cfg[idx], 3,
 
999
                                                 joystick_io[idx], 0,
 
1000
                                                 0, 0);
 
1001
 
 
1002
                if (err)
 
1003
                        goto cfg_error;
 
1004
        }
 
1005
        release_region(cfg[idx], 2);
 
1006
 
 
1007
#endif /* MSND_CLASSIC */
 
1008
 
 
1009
        set_default_audio_parameters(chip);
 
1010
#ifdef MSND_CLASSIC
 
1011
        chip->type = msndClassic;
 
1012
#else
 
1013
        chip->type = msndPinnacle;
 
1014
#endif
 
1015
        chip->io = io[idx];
 
1016
        chip->irq = irq[idx];
 
1017
        chip->base = mem[idx];
 
1018
 
 
1019
        chip->calibrate_signal = calibrate_signal ? 1 : 0;
 
1020
        chip->recsrc = 0;
 
1021
        chip->dspq_data_buff = DSPQ_DATA_BUFF;
 
1022
        chip->dspq_buff_size = DSPQ_BUFF_SIZE;
 
1023
        if (write_ndelay[idx])
 
1024
                clear_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
 
1025
        else
 
1026
                set_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
 
1027
#ifndef MSND_CLASSIC
 
1028
        if (digital[idx])
 
1029
                set_bit(F_HAVEDIGITAL, &chip->flags);
 
1030
#endif
 
1031
        spin_lock_init(&chip->lock);
 
1032
        err = snd_msnd_probe(card);
 
1033
        if (err < 0) {
 
1034
                printk(KERN_ERR LOGNAME ": Probe failed\n");
 
1035
                snd_card_free(card);
 
1036
                return err;
 
1037
        }
 
1038
 
 
1039
        err = snd_msnd_attach(card);
 
1040
        if (err < 0) {
 
1041
                printk(KERN_ERR LOGNAME ": Attach failed\n");
 
1042
                snd_card_free(card);
 
1043
                return err;
 
1044
        }
 
1045
        dev_set_drvdata(pdev, card);
 
1046
 
 
1047
        return 0;
 
1048
 
 
1049
#ifndef MSND_CLASSIC
 
1050
cfg_error:
 
1051
        release_region(cfg[idx], 2);
 
1052
        snd_card_free(card);
 
1053
        return err;
 
1054
#endif
 
1055
}
 
1056
 
 
1057
static int __devexit snd_msnd_isa_remove(struct device *pdev, unsigned int dev)
 
1058
{
 
1059
        snd_msnd_unload(dev_get_drvdata(pdev));
 
1060
        dev_set_drvdata(pdev, NULL);
 
1061
        return 0;
 
1062
}
 
1063
 
 
1064
#define DEV_NAME "msnd-pinnacle"
 
1065
 
 
1066
static struct isa_driver snd_msnd_driver = {
 
1067
        .match          = snd_msnd_isa_match,
 
1068
        .probe          = snd_msnd_isa_probe,
 
1069
        .remove         = __devexit_p(snd_msnd_isa_remove),
 
1070
        /* FIXME: suspend, resume */
 
1071
        .driver         = {
 
1072
                .name   = DEV_NAME
 
1073
        },
 
1074
};
 
1075
 
 
1076
#ifdef CONFIG_PNP
 
1077
static int __devinit snd_msnd_pnp_detect(struct pnp_card_link *pcard,
 
1078
                                         const struct pnp_card_device_id *pid)
 
1079
{
 
1080
        static int idx;
 
1081
        struct pnp_dev *pnp_dev;
 
1082
        struct pnp_dev *mpu_dev;
 
1083
        struct snd_card *card;
 
1084
        struct snd_msnd *chip;
 
1085
        int ret;
 
1086
 
 
1087
        for ( ; idx < SNDRV_CARDS; idx++) {
 
1088
                if (has_isapnp(idx))
 
1089
                        break;
 
1090
        }
 
1091
        if (idx >= SNDRV_CARDS)
 
1092
                return -ENODEV;
 
1093
 
 
1094
        /*
 
1095
         * Check that we still have room for another sound card ...
 
1096
         */
 
1097
        pnp_dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
 
1098
        if (!pnp_dev)
 
1099
                return -ENODEV;
 
1100
 
 
1101
        mpu_dev = pnp_request_card_device(pcard, pid->devs[1].id, NULL);
 
1102
        if (!mpu_dev)
 
1103
                return -ENODEV;
 
1104
 
 
1105
        if (!pnp_is_active(pnp_dev) && pnp_activate_dev(pnp_dev) < 0) {
 
1106
                printk(KERN_INFO "msnd_pinnacle: device is inactive\n");
 
1107
                return -EBUSY;
 
1108
        }
 
1109
 
 
1110
        if (!pnp_is_active(mpu_dev) && pnp_activate_dev(mpu_dev) < 0) {
 
1111
                printk(KERN_INFO "msnd_pinnacle: MPU device is inactive\n");
 
1112
                return -EBUSY;
 
1113
        }
 
1114
 
 
1115
        /*
 
1116
         * Create a new ALSA sound card entry, in anticipation
 
1117
         * of detecting our hardware ...
 
1118
         */
 
1119
        ret = snd_card_create(index[idx], id[idx], THIS_MODULE,
 
1120
                              sizeof(struct snd_msnd), &card);
 
1121
        if (ret < 0)
 
1122
                return ret;
 
1123
 
 
1124
        chip = card->private_data;
 
1125
        chip->card = card;
 
1126
        snd_card_set_dev(card, &pcard->card->dev);
 
1127
 
 
1128
        /*
 
1129
         * Read the correct parameters off the ISA PnP bus ...
 
1130
         */
 
1131
        io[idx] = pnp_port_start(pnp_dev, 0);
 
1132
        irq[idx] = pnp_irq(pnp_dev, 0);
 
1133
        mem[idx] = pnp_mem_start(pnp_dev, 0);
 
1134
        mpu_io[idx] = pnp_port_start(mpu_dev, 0);
 
1135
        mpu_irq[idx] = pnp_irq(mpu_dev, 0);
 
1136
 
 
1137
        set_default_audio_parameters(chip);
 
1138
#ifdef MSND_CLASSIC
 
1139
        chip->type = msndClassic;
 
1140
#else
 
1141
        chip->type = msndPinnacle;
 
1142
#endif
 
1143
        chip->io = io[idx];
 
1144
        chip->irq = irq[idx];
 
1145
        chip->base = mem[idx];
 
1146
 
 
1147
        chip->calibrate_signal = calibrate_signal ? 1 : 0;
 
1148
        chip->recsrc = 0;
 
1149
        chip->dspq_data_buff = DSPQ_DATA_BUFF;
 
1150
        chip->dspq_buff_size = DSPQ_BUFF_SIZE;
 
1151
        if (write_ndelay[idx])
 
1152
                clear_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
 
1153
        else
 
1154
                set_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
 
1155
#ifndef MSND_CLASSIC
 
1156
        if (digital[idx])
 
1157
                set_bit(F_HAVEDIGITAL, &chip->flags);
 
1158
#endif
 
1159
        spin_lock_init(&chip->lock);
 
1160
        ret = snd_msnd_probe(card);
 
1161
        if (ret < 0) {
 
1162
                printk(KERN_ERR LOGNAME ": Probe failed\n");
 
1163
                goto _release_card;
 
1164
        }
 
1165
 
 
1166
        ret = snd_msnd_attach(card);
 
1167
        if (ret < 0) {
 
1168
                printk(KERN_ERR LOGNAME ": Attach failed\n");
 
1169
                goto _release_card;
 
1170
        }
 
1171
 
 
1172
        pnp_set_card_drvdata(pcard, card);
 
1173
        ++idx;
 
1174
        return 0;
 
1175
 
 
1176
_release_card:
 
1177
        snd_card_free(card);
 
1178
        return ret;
 
1179
}
 
1180
 
 
1181
static void __devexit snd_msnd_pnp_remove(struct pnp_card_link *pcard)
 
1182
{
 
1183
        snd_msnd_unload(pnp_get_card_drvdata(pcard));
 
1184
        pnp_set_card_drvdata(pcard, NULL);
 
1185
}
 
1186
 
 
1187
static int isa_registered;
 
1188
static int pnp_registered;
 
1189
 
 
1190
static struct pnp_card_device_id msnd_pnpids[] = {
 
1191
        /* Pinnacle PnP */
 
1192
        { .id = "BVJ0440", .devs = { { "TBS0000" }, { "TBS0001" } } },
 
1193
        { .id = "" }    /* end */
 
1194
};
 
1195
 
 
1196
MODULE_DEVICE_TABLE(pnp_card, msnd_pnpids);
 
1197
 
 
1198
static struct pnp_card_driver msnd_pnpc_driver = {
 
1199
        .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
 
1200
        .name = "msnd_pinnacle",
 
1201
        .id_table = msnd_pnpids,
 
1202
        .probe = snd_msnd_pnp_detect,
 
1203
        .remove = __devexit_p(snd_msnd_pnp_remove),
 
1204
};
 
1205
#endif /* CONFIG_PNP */
 
1206
 
 
1207
static int __init snd_msnd_init(void)
 
1208
{
 
1209
        int err;
 
1210
 
 
1211
        err = isa_register_driver(&snd_msnd_driver, SNDRV_CARDS);
 
1212
#ifdef CONFIG_PNP
 
1213
        if (!err)
 
1214
                isa_registered = 1;
 
1215
 
 
1216
        err = pnp_register_card_driver(&msnd_pnpc_driver);
 
1217
        if (!err)
 
1218
                pnp_registered = 1;
 
1219
 
 
1220
        if (isa_registered)
 
1221
                err = 0;
 
1222
#endif
 
1223
        return err;
 
1224
}
 
1225
 
 
1226
static void __exit snd_msnd_exit(void)
 
1227
{
 
1228
#ifdef CONFIG_PNP
 
1229
        if (pnp_registered)
 
1230
                pnp_unregister_card_driver(&msnd_pnpc_driver);
 
1231
        if (isa_registered)
 
1232
#endif
 
1233
                isa_unregister_driver(&snd_msnd_driver);
 
1234
}
 
1235
 
 
1236
module_init(snd_msnd_init);
 
1237
module_exit(snd_msnd_exit);
 
1238