?? korg1212.c
字號:
/* * Driver for the Korg 1212 IO PCI card * * Copyright (c) 2001 Haroldo Gamal <gamal@alternex.com.br> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#include <sound/driver.h>#include <linux/delay.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/slab.h>#include <linux/wait.h>#include <linux/moduleparam.h>#include <sound/core.h>#include <sound/info.h>#include <sound/control.h>#include <sound/pcm.h>#include <sound/pcm_params.h>#include <sound/initval.h>#include <asm/io.h>// ----------------------------------------------------------------------------// Debug Stuff// ----------------------------------------------------------------------------#define K1212_DEBUG_LEVEL 0#define K1212_DEBUG_PRINTK printk//#define K1212_DEBUG_PRINTK(x...) printk("<0>" x)// ----------------------------------------------------------------------------// Record/Play Buffer Allocation Method. If K1212_LARGEALLOC is defined all // buffers are alocated as a large piece inside KorgSharedBuffer.// ----------------------------------------------------------------------------//#define K1212_LARGEALLOC 1// ----------------------------------------------------------------------------// Valid states of the Korg 1212 I/O card.// ----------------------------------------------------------------------------typedef enum { K1212_STATE_NONEXISTENT, // there is no card here K1212_STATE_UNINITIALIZED, // the card is awaiting DSP download K1212_STATE_DSP_IN_PROCESS, // the card is currently downloading its DSP code K1212_STATE_DSP_COMPLETE, // the card has finished the DSP download K1212_STATE_READY, // the card can be opened by an application. Any application // requests prior to this state should fail. Only an open // request can be made at this state. K1212_STATE_OPEN, // an application has opened the card K1212_STATE_SETUP, // the card has been setup for play K1212_STATE_PLAYING, // the card is playing K1212_STATE_MONITOR, // the card is in the monitor mode K1212_STATE_CALIBRATING, // the card is currently calibrating K1212_STATE_ERRORSTOP, // the card has stopped itself because of an error and we // are in the process of cleaning things up. K1212_STATE_MAX_STATE // state values of this and beyond are invalid} CardState;// ----------------------------------------------------------------------------// The following enumeration defines the constants written to the card's// host-to-card doorbell to initiate a command.// ----------------------------------------------------------------------------typedef enum { K1212_DB_RequestForData = 0, // sent by the card to request a buffer fill. K1212_DB_TriggerPlay = 1, // starts playback/record on the card. K1212_DB_SelectPlayMode = 2, // select monitor, playback setup, or stop. K1212_DB_ConfigureBufferMemory = 3, // tells card where the host audio buffers are. K1212_DB_RequestAdatTimecode = 4, // asks the card for the latest ADAT timecode value. K1212_DB_SetClockSourceRate = 5, // sets the clock source and rate for the card. K1212_DB_ConfigureMiscMemory = 6, // tells card where other buffers are. K1212_DB_TriggerFromAdat = 7, // tells card to trigger from Adat at a specific // timecode value. K1212_DB_DMAERROR = 0x80, // DMA Error - the PCI bus is congestioned. K1212_DB_CARDSTOPPED = 0x81, // Card has stopped by user request. K1212_DB_RebootCard = 0xA0, // instructs the card to reboot. K1212_DB_BootFromDSPPage4 = 0xA4, // instructs the card to boot from the DSP microcode // on page 4 (local page to card). K1212_DB_DSPDownloadDone = 0xAE, // sent by the card to indicate the download has // completed. K1212_DB_StartDSPDownload = 0xAF // tells the card to download its DSP firmware.} korg1212_dbcnst_t;// ----------------------------------------------------------------------------// The following enumeration defines return codes // to the Korg 1212 I/O driver.// ----------------------------------------------------------------------------typedef enum { K1212_CMDRET_Success = 0, // command was successfully placed K1212_CMDRET_DIOCFailure, // the DeviceIoControl call failed K1212_CMDRET_PMFailure, // the protected mode call failed K1212_CMDRET_FailUnspecified, // unspecified failure K1212_CMDRET_FailBadState, // the specified command can not be given in // the card's current state. (or the wave device's // state) K1212_CMDRET_CardUninitialized, // the card is uninitialized and cannot be used K1212_CMDRET_BadIndex, // an out of range card index was specified K1212_CMDRET_BadHandle, // an invalid card handle was specified K1212_CMDRET_NoFillRoutine, // a play request has been made before a fill routine set K1212_CMDRET_FillRoutineInUse, // can't set a new fill routine while one is in use K1212_CMDRET_NoAckFromCard, // the card never acknowledged a command K1212_CMDRET_BadParams, // bad parameters were provided by the caller K1212_CMDRET_BadDevice, // the specified wave device was out of range K1212_CMDRET_BadFormat // the specified wave format is unsupported} snd_korg1212rc;// ----------------------------------------------------------------------------// The following enumeration defines the constants used to select the play// mode for the card in the SelectPlayMode command.// ----------------------------------------------------------------------------typedef enum { K1212_MODE_SetupPlay = 0x00000001, // provides card with pre-play information K1212_MODE_MonitorOn = 0x00000002, // tells card to turn on monitor mode K1212_MODE_MonitorOff = 0x00000004, // tells card to turn off monitor mode K1212_MODE_StopPlay = 0x00000008 // stops playback on the card} PlayModeSelector;// ----------------------------------------------------------------------------// The following enumeration defines the constants used to select the monitor// mode for the card in the SetMonitorMode command.// ----------------------------------------------------------------------------typedef enum { K1212_MONMODE_Off = 0, // tells card to turn off monitor mode K1212_MONMODE_On // tells card to turn on monitor mode} MonitorModeSelector;#define MAILBOX0_OFFSET 0x40 // location of mailbox 0 relative to base address#define MAILBOX1_OFFSET 0x44 // location of mailbox 1 relative to base address#define MAILBOX2_OFFSET 0x48 // location of mailbox 2 relative to base address#define MAILBOX3_OFFSET 0x4c // location of mailbox 3 relative to base address#define OUT_DOORBELL_OFFSET 0x60 // location of PCI to local doorbell#define IN_DOORBELL_OFFSET 0x64 // location of local to PCI doorbell#define STATUS_REG_OFFSET 0x68 // location of interrupt control/status register#define PCI_CONTROL_OFFSET 0x6c // location of the EEPROM, PCI, User I/O, init control // register#define SENS_CONTROL_OFFSET 0x6e // location of the input sensitivity setting register. // this is the upper word of the PCI control reg.#define DEV_VEND_ID_OFFSET 0x70 // location of the device and vendor ID register#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement // from the card after sending a command.#define INTERCOMMAND_DELAY 40#define MAX_COMMAND_RETRIES 5 // maximum number of times the driver will attempt // to send a command before giving up.#define COMMAND_ACK_MASK 0x8000 // the MSB is set in the command acknowledgment from // the card.#define DOORBELL_VAL_MASK 0x00FF // the doorbell value is one byte#define CARD_BOOT_DELAY_IN_MS 10#define CARD_BOOT_TIMEOUT 10#define DSP_BOOT_DELAY_IN_MS 200#define kNumBuffers 8#define k1212MaxCards 4#define k1212NumWaveDevices 6#define k16BitChannels 10#define k32BitChannels 2#define kAudioChannels (k16BitChannels + k32BitChannels)#define kPlayBufferFrames 1024#define K1212_ANALOG_CHANNELS 2#define K1212_SPDIF_CHANNELS 2#define K1212_ADAT_CHANNELS 8#define K1212_CHANNELS (K1212_ADAT_CHANNELS + K1212_ANALOG_CHANNELS)#define K1212_MIN_CHANNELS 1#define K1212_MAX_CHANNELS K1212_CHANNELS#define K1212_FRAME_SIZE (sizeof(KorgAudioFrame))#define K1212_MAX_SAMPLES (kPlayBufferFrames*kNumBuffers)#define K1212_PERIODS (kNumBuffers)#define K1212_PERIOD_BYTES (K1212_FRAME_SIZE*kPlayBufferFrames)#define K1212_BUF_SIZE (K1212_PERIOD_BYTES*kNumBuffers)#define K1212_ANALOG_BUF_SIZE (K1212_ANALOG_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)#define K1212_SPDIF_BUF_SIZE (K1212_SPDIF_CHANNELS * 3 * kPlayBufferFrames * kNumBuffers)#define K1212_ADAT_BUF_SIZE (K1212_ADAT_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)#define K1212_MAX_BUF_SIZE (K1212_ANALOG_BUF_SIZE + K1212_ADAT_BUF_SIZE)#define k1212MinADCSens 0x7f#define k1212MaxADCSens 0x00#define k1212MaxVolume 0x7fff#define k1212MaxWaveVolume 0xffff#define k1212MinVolume 0x0000#define k1212MaxVolInverted 0x8000// -----------------------------------------------------------------// the following bits are used for controlling interrupts in the// interrupt control/status reg// -----------------------------------------------------------------#define PCI_INT_ENABLE_BIT 0x00000100#define PCI_DOORBELL_INT_ENABLE_BIT 0x00000200#define LOCAL_INT_ENABLE_BIT 0x00010000#define LOCAL_DOORBELL_INT_ENABLE_BIT 0x00020000#define LOCAL_DMA1_INT_ENABLE_BIT 0x00080000// -----------------------------------------------------------------// the following bits are defined for the PCI command register// -----------------------------------------------------------------#define PCI_CMD_MEM_SPACE_ENABLE_BIT 0x0002#define PCI_CMD_IO_SPACE_ENABLE_BIT 0x0001#define PCI_CMD_BUS_MASTER_ENABLE_BIT 0x0004// -----------------------------------------------------------------// the following bits are defined for the PCI status register// -----------------------------------------------------------------#define PCI_STAT_PARITY_ERROR_BIT 0x8000#define PCI_STAT_SYSTEM_ERROR_BIT 0x4000#define PCI_STAT_MASTER_ABORT_RCVD_BIT 0x2000#define PCI_STAT_TARGET_ABORT_RCVD_BIT 0x1000#define PCI_STAT_TARGET_ABORT_SENT_BIT 0x0800// ------------------------------------------------------------------------// the following constants are used in setting the 1212 I/O card's input// sensitivity.// ------------------------------------------------------------------------#define SET_SENS_LOCALINIT_BITPOS 15#define SET_SENS_DATA_BITPOS 10#define SET_SENS_CLOCK_BITPOS 8#define SET_SENS_LOADSHIFT_BITPOS 0#define SET_SENS_LEFTCHANID 0x00#define SET_SENS_RIGHTCHANID 0x01#define K1212SENSUPDATE_DELAY_IN_MS 50// --------------------------------------------------------------------------// WaitRTCTicks//// This function waits the specified number of real time clock ticks.// According to the DDK, each tick is ~0.8 microseconds.// The defines following the function declaration can be used for the// numTicksToWait parameter.// --------------------------------------------------------------------------#define ONE_RTC_TICK 1#define SENSCLKPULSE_WIDTH 4#define LOADSHIFT_DELAY 4#define INTERCOMMAND_DELAY 40#define STOPCARD_DELAY 300 // max # RTC ticks for the card to stop once we write // the command register. (could be up to 180 us)#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement // from the card after sending a command.#include "korg1212-firmware.h"typedef struct _snd_korg1212 korg1212_t;typedef u16 K1212Sample; // channels 0-9 use 16 bit samplestypedef u32 K1212SpdifSample; // channels 10-11 use 32 bits - only 20 are sent // across S/PDIF.typedef u32 K1212TimeCodeSample; // holds the ADAT timecode valuetypedef enum { K1212_CLKIDX_AdatAt44_1K = 0, // selects source as ADAT at 44.1 kHz K1212_CLKIDX_AdatAt48K, // selects source as ADAT at 48 kHz K1212_CLKIDX_WordAt44_1K, // selects source as S/PDIF at 44.1 kHz K1212_CLKIDX_WordAt48K, // selects source as S/PDIF at 48 kHz K1212_CLKIDX_LocalAt44_1K, // selects source as local clock at 44.1 kHz K1212_CLKIDX_LocalAt48K, // selects source as local clock at 48 kHz K1212_CLKIDX_Invalid // used to check validity of the index} ClockSourceIndex;typedef enum { K1212_CLKIDX_Adat = 0, // selects source as ADAT K1212_CLKIDX_Word, // selects source as S/PDIF K1212_CLKIDX_Local // selects source as local clock} ClockSourceType;typedef struct KorgAudioFrame { K1212Sample frameData16[k16BitChannels]; K1212SpdifSample frameData32[k32BitChannels]; K1212TimeCodeSample timeCodeVal;} KorgAudioFrame;typedef struct KorgAudioBuffer { KorgAudioFrame bufferData[kPlayBufferFrames]; /* buffer definition */} KorgAudioBuffer;typedef struct KorgSharedBuffer {#ifdef K1212_LARGEALLOC KorgAudioBuffer playDataBufs[kNumBuffers]; KorgAudioBuffer recordDataBufs[kNumBuffers];#endif short volumeData[kAudioChannels]; u32 cardCommand; u16 routeData [kAudioChannels]; u32 AdatTimeCode; // ADAT timecode value} KorgSharedBuffer;typedef struct SensBits { union { struct { unsigned int leftChanVal:8; unsigned int leftChanId:8; } v; u16 leftSensBits; } l; union { struct { unsigned int rightChanVal:8; unsigned int rightChanId:8; } v; u16 rightSensBits; } r;} SensBits;struct _snd_korg1212 { snd_card_t *card; struct pci_dev *pci; snd_pcm_t *pcm; int irq; spinlock_t lock; struct semaphore open_mutex; struct timer_list timer; /* timer callback for checking ack of stop request */ int stop_pending_cnt; /* counter for stop pending check */ wait_queue_head_t wait; unsigned long iomem; unsigned long ioport; unsigned long iomem2; unsigned long irqcount; unsigned long inIRQ; void __iomem *iobase; struct snd_dma_buffer dma_dsp; struct snd_dma_buffer dma_play; struct snd_dma_buffer dma_rec; struct snd_dma_buffer dma_shared; u32 dspCodeSize; u32 DataBufsSize; KorgAudioBuffer * playDataBufsPtr; KorgAudioBuffer * recordDataBufsPtr; KorgSharedBuffer * sharedBufferPtr;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -