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