⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 korg1212.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *   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// ----------------------------------------------------------------------------// the following enum defines the 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_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;#define K1212_ISRCODE_DMAERROR      0x80#define K1212_ISRCODE_CARDSTOPPED   0x81// ----------------------------------------------------------------------------// The following enumeration defines return codes for DeviceIoControl() calls// 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   // --------------------------------------------------------------   // the following return errors are specific to the wave device   // driver interface.  These will not be encountered by users of   // the 32 bit DIOC interface (a.k.a. custom or native API).   // --------------------------------------------------------------   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 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;        unsigned long iobase;	struct resource *res_iomem;	struct resource *res_ioport;	struct resource *res_iomem2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -