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

📄 korg1212.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        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;        struct snd_pcm_substream *playback_substream;        struct snd_pcm_substream *capture_substream;	pid_t capture_pid;	pid_t playback_pid; 	enum 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.        enum ClockSourceIndex clkSrcRate; // sample rate and clock source        enum 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[] __devinitdata = {	{		.vendor	   = 0x10b5,		.device	   = 0x906d,		.subvendor = PCI_ANY_ID,		.subdevice = PCI_ANY_ID,	},	{ 0, },};MODULE_DEVICE_TABLE(pci, snd_korg1212_ids);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};union swap_u32 { unsigned char c[4]; u32 i; };#ifdef SNDRV_BIG_ENDIANstatic u32 LowerWordSwap(u32 swappee)#elsestatic u32 UpperWordSwap(u32 swappee)#endif{   union 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{   union 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;}#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 int snd_korg1212_Send1212Command(struct snd_korg1212 *korg1212,					enum korg1212_dbcnst doorbellVal,					u32 mailBox0Val, u32 mailBox1Val,					u32 mailBox2Val, u32 mailBox3Val){        u32 retryCount;        u16 mailBox3Lo;	int rc = K1212_CMDRET_Success;        if (!korg1212->outDoorbellPtr) {		K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: CardUninitialized\n");                return K1212_CMDRET_CardUninitialized;	}	K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- 0x%08x 0x%08x [%s]\n",			   doorbellVal, mailBox0Val, stateName[korg1212->cardState]);        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)) {				K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Card <- Success\n");                                rc = K1212_CMDRET_Success;				break;                        }                }	}        korg1212->cmdRetryCount += retryCount;	if (retryCount >= MAX_COMMAND_RETRIES) {		K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Card <- NoAckFromCard\n");        	rc = K1212_CMDRET_NoAckFromCard;	}	return rc;}/* spinlock already held */static void snd_korg1212_SendStop(struct snd_korg1212 *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(struct snd_korg1212 *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){        struct snd_korg1212 *korg1212 = (struct snd_korg1212 *) data;	unsigned long flags;		spin_lock_irqsave(&korg1212->lock, flags);	if (korg1212->sharedBufferPtr->cardCommand == 0) {		/* ack'ed */		korg1212->stop_pending_cnt = 0;		korg1212->dsp_stop_is_processed = 1;		wake_up(&korg1212->wait);		K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Stop ack'ed [%s]\n",					   stateName[korg1212->cardState]);	} 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);			K1212_DEBUG_PRINTK("K1212_DEBUG: Stop timeout [%s]\n",					   stateName[korg1212->cardState]);		}	}	spin_unlock_irqrestore(&korg1212->lock, flags);}static int snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 *korg1212){	unsigned long flags;	int rc;        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);	return rc;}static void snd_korg1212_TurnOffIdleMonitor(struct snd_korg1212 *korg1212){        if (korg1212->idleMonitorOn) {		snd_korg1212_SendStopAndWait(korg1212);                korg1212->idleMonitorOn = 0;        }}static inline void snd_korg1212_setCardState(struct snd_korg1212 * korg1212, enum CardState csState){        korg1212->cardState = csState;}static int snd_korg1212_OpenCard(struct snd_korg1212 * korg1212){	K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n",			   stateName[korg1212->cardState], korg1212->opencnt);	mutex_lock(&korg1212->open_mutex);        if (korg1212->opencnt++ == 0) {		snd_korg1212_TurnOffIdleMonitor(korg1212);		snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);	}	mutex_unlock(&korg1212->open_mutex);        return 1;}static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212){	K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n",			   stateName[korg1212->cardState], korg1212->opencnt);	mutex_lock(&korg1212->open_mutex);	if (--(korg1212->opencnt)) {		mutex_unlock(&korg1212->open_mutex);		return 0;	}        if (korg1212->cardState == K1212_STATE_SETUP) {                int rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,                                K1212_MODE_StopPlay, 0, 0, 0);		if (rc)			K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard - RC = %d [%s]\n",					   rc, stateName[korg1212->cardState]);		if (rc != K1212_CMDRET_Success) {			mutex_unlock(&korg1212->open_mutex);                        return 0;		}        } else if (korg1212->cardState > K1212_STATE_SETUP) {		snd_korg1212_SendStopAndWait(korg1212);        }        if (korg1212->cardState > K1212_STATE_READY) {		snd_korg1212_TurnOnIdleMonitor(korg1212);                snd_korg1212_setCardState(korg1212, K1212_STATE_READY);	}	mutex_unlock(&korg1212->open_mutex);        return 0;}/* spinlock already held */static int snd_korg1212_SetupForPlay(struct snd_korg1212 * korg1212){	int rc;	K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay [%s] %d\n",			   stateName[korg1212->cardState], korg1212->setcnt);        if (korg1212->setcnt++)		return 0;

⌨️ 快捷键说明

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