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

📄 korg1212.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	u32 RecDataPhy;	u32 PlayDataPhy;	unsigned long sharedBufferPhy;	u32 VolumeTablePhy;	u32 RoutingTablePhy;	u32 AdatTimeCodePhy;        u32 __iomem * statusRegPtr;	     // address of the interrupt status/control register        u32 __iomem * outDoorbellPtr;	     // address of the host->card doorbell register        u32 __iomem * inDoorbellPtr;	     // address of the card->host doorbell register        u32 __iomem * mailbox0Ptr;	     // address of mailbox 0 on the card        u32 __iomem * mailbox1Ptr;	     // address of mailbox 1 on the card        u32 __iomem * mailbox2Ptr;	     // address of mailbox 2 on the card        u32 __iomem * mailbox3Ptr;	     // address of mailbox 3 on the card        u32 __iomem * controlRegPtr;	     // address of the EEPROM, PCI, I/O, Init ctrl reg        u16 __iomem * sensRegPtr;	     // address of the sensitivity setting register        u32 __iomem * idRegPtr;		     // address of the device and vendor ID registers        size_t periodsize;	int channels;        int currentBuffer;        snd_pcm_substream_t *playback_substream;        snd_pcm_substream_t *capture_substream;	pid_t capture_pid;	pid_t playback_pid; 	CardState cardState;        int running;        int idleMonitorOn;           // indicates whether the card is in idle monitor mode.        u32 cmdRetryCount;           // tracks how many times we have retried sending to the card.        ClockSourceIndex clkSrcRate; // sample rate and clock source        ClockSourceType clkSource;   // clock source        int clkRate;                 // clock rate        int volumePhase[kAudioChannels];        u16 leftADCInSens;           // ADC left channel input sensitivity        u16 rightADCInSens;          // ADC right channel input sensitivity	int opencnt;		     // Open/Close count	int setcnt;		     // SetupForPlay count	int playcnt;		     // TriggerPlay count	int errorcnt;		     // Error Count	unsigned long totalerrorcnt; // Total Error Count	int dsp_is_loaded;	int dsp_stop_is_processed;};MODULE_DESCRIPTION("korg1212");MODULE_LICENSE("GPL");MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}");static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	   /* ID for this card */static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */module_param_array(index, int, NULL, 0444);MODULE_PARM_DESC(index, "Index value for Korg 1212 soundcard.");module_param_array(id, charp, NULL, 0444);MODULE_PARM_DESC(id, "ID string for Korg 1212 soundcard.");module_param_array(enable, bool, NULL, 0444);MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard.");MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");static struct pci_device_id snd_korg1212_ids[] = {	{		.vendor	   = 0x10b5,		.device	   = 0x906d,		.subvendor = PCI_ANY_ID,		.subdevice = PCI_ANY_ID,	},	{ 0, },};static char* stateName[] = {		        "Non-existent",                        "Uninitialized",                        "DSP download in process",                        "DSP download complete",                        "Ready",                        "Open",                        "Setup for play",                        "Playing",                        "Monitor mode on",			"Calibrating",                        "Invalid"};static char* clockSourceTypeName[] = { "ADAT", "S/PDIF", "local" };static char* clockSourceName[] = {                        "ADAT at 44.1 kHz",                        "ADAT at 48 kHz",                        "S/PDIF at 44.1 kHz",                        "S/PDIF at 48 kHz",                        "local clock at 44.1 kHz",                        "local clock at 48 kHz"};static char* channelName[] = {                        "ADAT-1",                        "ADAT-2",                        "ADAT-3",                        "ADAT-4",                        "ADAT-5",                        "ADAT-6",                        "ADAT-7",                        "ADAT-8",                        "Analog-L",                        "Analog-R",                        "SPDIF-L",                        "SPDIF-R",};static u16 ClockSourceSelector[] =                            {0x8000,   // selects source as ADAT at 44.1 kHz                             0x0000,   // selects source as ADAT at 48 kHz                             0x8001,   // selects source as S/PDIF at 44.1 kHz                             0x0001,   // selects source as S/PDIF at 48 kHz                             0x8002,   // selects source as local clock at 44.1 kHz                             0x0002    // selects source as local clock at 48 kHz                            };static snd_korg1212rc rc;MODULE_DEVICE_TABLE(pci, snd_korg1212_ids);typedef union swap_u32 { unsigned char c[4]; u32 i; } swap_u32;#ifdef SNDRV_BIG_ENDIANstatic u32 LowerWordSwap(u32 swappee)#elsestatic u32 UpperWordSwap(u32 swappee)#endif{   swap_u32 retVal, swapper;   swapper.i = swappee;   retVal.c[2] = swapper.c[3];   retVal.c[3] = swapper.c[2];   retVal.c[1] = swapper.c[1];   retVal.c[0] = swapper.c[0];   return retVal.i;}#ifdef SNDRV_BIG_ENDIANstatic u32 UpperWordSwap(u32 swappee)#elsestatic u32 LowerWordSwap(u32 swappee)#endif{   swap_u32 retVal, swapper;   swapper.i = swappee;   retVal.c[2] = swapper.c[2];   retVal.c[3] = swapper.c[3];   retVal.c[1] = swapper.c[0];   retVal.c[0] = swapper.c[1];   return retVal.i;}#if 0 /* not used */static u32 EndianSwap(u32 swappee){   swap_u32 retVal, swapper;   swapper.i = swappee;   retVal.c[0] = swapper.c[3];   retVal.c[1] = swapper.c[2];   retVal.c[2] = swapper.c[1];   retVal.c[3] = swapper.c[0];   return retVal.i;}#endif /* not used */#define SetBitInWord(theWord,bitPosition)       (*theWord) |= (0x0001 << bitPosition)#define SetBitInDWord(theWord,bitPosition)      (*theWord) |= (0x00000001 << bitPosition)#define ClearBitInWord(theWord,bitPosition)     (*theWord) &= ~(0x0001 << bitPosition)#define ClearBitInDWord(theWord,bitPosition)    (*theWord) &= ~(0x00000001 << bitPosition)static snd_korg1212rc snd_korg1212_Send1212Command(korg1212_t *korg1212, korg1212_dbcnst_t doorbellVal,                            u32 mailBox0Val, u32 mailBox1Val, u32 mailBox2Val, u32 mailBox3Val){        u32 retryCount;        u16 mailBox3Lo;	snd_korg1212rc rc = K1212_CMDRET_Success;        if (!korg1212->outDoorbellPtr) {#if K1212_DEBUG_LEVEL > 1		K1212_DEBUG_PRINTK("K1212_DEBUG: CardUninitialized\n");#endif                return K1212_CMDRET_CardUninitialized;	}#if K1212_DEBUG_LEVEL > 0	K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- 0x%08x 0x%08x [%s]\n", doorbellVal, mailBox0Val, stateName[korg1212->cardState]);#endif        for (retryCount = 0; retryCount < MAX_COMMAND_RETRIES; retryCount++) {		writel(mailBox3Val, korg1212->mailbox3Ptr);                writel(mailBox2Val, korg1212->mailbox2Ptr);                writel(mailBox1Val, korg1212->mailbox1Ptr);                writel(mailBox0Val, korg1212->mailbox0Ptr);                writel(doorbellVal, korg1212->outDoorbellPtr);  // interrupt the card                // --------------------------------------------------------------                // the reboot command will not give an acknowledgement.                // --------------------------------------------------------------                if ( doorbellVal == K1212_DB_RebootCard ||                	doorbellVal == K1212_DB_BootFromDSPPage4 ||                        doorbellVal == K1212_DB_StartDSPDownload ) {                        rc = K1212_CMDRET_Success;                        break;                }                // --------------------------------------------------------------                // See if the card acknowledged the command.  Wait a bit, then                // read in the low word of mailbox3.  If the MSB is set and the                // low byte is equal to the doorbell value, then it ack'd.                // --------------------------------------------------------------                udelay(COMMAND_ACK_DELAY);                mailBox3Lo = readl(korg1212->mailbox3Ptr);                if (mailBox3Lo & COMMAND_ACK_MASK) {                	if ((mailBox3Lo & DOORBELL_VAL_MASK) == (doorbellVal & DOORBELL_VAL_MASK)) {#if K1212_DEBUG_LEVEL > 1				K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- Success\n");#endif                                rc = K1212_CMDRET_Success;				break;                        }                }	}        korg1212->cmdRetryCount += retryCount;	if (retryCount >= MAX_COMMAND_RETRIES) {#if K1212_DEBUG_LEVEL > 1		K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- NoAckFromCard\n");#endif        	rc = K1212_CMDRET_NoAckFromCard;	}	return rc;}/* spinlock already held */static void snd_korg1212_SendStop(korg1212_t *korg1212){	if (! korg1212->stop_pending_cnt) {		korg1212->sharedBufferPtr->cardCommand = 0xffffffff;		/* program the timer */		korg1212->stop_pending_cnt = HZ;		korg1212->timer.expires = jiffies + 1;		add_timer(&korg1212->timer);	}}static void snd_korg1212_SendStopAndWait(korg1212_t *korg1212){	unsigned long flags;	spin_lock_irqsave(&korg1212->lock, flags);	korg1212->dsp_stop_is_processed = 0;	snd_korg1212_SendStop(korg1212);	spin_unlock_irqrestore(&korg1212->lock, flags);	wait_event_timeout(korg1212->wait, korg1212->dsp_stop_is_processed, (HZ * 3) / 2);}/* timer callback for checking the ack of stop request */static void snd_korg1212_timer_func(unsigned long data){        korg1212_t *korg1212 = (korg1212_t *) data;		spin_lock(&korg1212->lock);	if (korg1212->sharedBufferPtr->cardCommand == 0) {		/* ack'ed */		korg1212->stop_pending_cnt = 0;		korg1212->dsp_stop_is_processed = 1;		wake_up(&korg1212->wait);#if K1212_DEBUG_LEVEL > 1		K1212_DEBUG_PRINTK("K1212_DEBUG: Stop ack'ed [%s]\n", stateName[korg1212->cardState]);#endif	} else {		if (--korg1212->stop_pending_cnt > 0) {			/* reprogram timer */			korg1212->timer.expires = jiffies + 1;			add_timer(&korg1212->timer);		} else {			snd_printd("korg1212_timer_func timeout\n");			korg1212->sharedBufferPtr->cardCommand = 0;			korg1212->dsp_stop_is_processed = 1;			wake_up(&korg1212->wait);#if K1212_DEBUG_LEVEL > 0			K1212_DEBUG_PRINTK("K1212_DEBUG: Stop timeout [%s]\n", stateName[korg1212->cardState]);#endif		}	}	spin_unlock(&korg1212->lock);}static void snd_korg1212_TurnOnIdleMonitor(korg1212_t *korg1212){	unsigned long flags;        udelay(INTERCOMMAND_DELAY);	spin_lock_irqsave(&korg1212->lock, flags);        korg1212->idleMonitorOn = 1;        rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,					  K1212_MODE_MonitorOn, 0, 0, 0);        spin_unlock_irqrestore(&korg1212->lock, flags);}static void snd_korg1212_TurnOffIdleMonitor(korg1212_t *korg1212){        if (korg1212->idleMonitorOn) {		snd_korg1212_SendStopAndWait(korg1212);                korg1212->idleMonitorOn = 0;        }}static inline void snd_korg1212_setCardState(korg1212_t * korg1212, CardState csState){        korg1212->cardState = csState;}static int snd_korg1212_OpenCard(korg1212_t * korg1212){#if K1212_DEBUG_LEVEL > 0	K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n", stateName[korg1212->cardState], korg1212->opencnt);#endif	down(&korg1212->open_mutex);        if (korg1212->opencnt++ == 0) {		snd_korg1212_TurnOffIdleMonitor(korg1212);		snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);	}	up(&korg1212->open_mutex);        return 1;}static int snd_korg1212_CloseCard(korg1212_t * korg1212){#if K1212_DEBUG_LEVEL > 0	K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n", stateName[korg1212->cardState], korg1212->opencnt);

⌨️ 快捷键说明

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