📄 korg1212.c
字号:
snd_pcm_substream_t *playback_substream; snd_pcm_substream_t *capture_substream; snd_info_entry_t * proc_entry; 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};EXPORT_NO_SYMBOLS;MODULE_DESCRIPTION("korg1212");MODULE_LICENSE("GPL");MODULE_CLASSES("{sound}");MODULE_DEVICES("{{KORG,korg1212}}");static int snd_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_index, "Index value for Korg 1212 soundcard.");MODULE_PARM_SYNTAX(snd_index, SNDRV_INDEX_DESC);MODULE_PARM(snd_id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");MODULE_PARM_DESC(snd_id, "ID string for Korg 1212 soundcard.");MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC);MODULE_PARM(snd_enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_enable, "Enable Korg 1212 soundcard.");MODULE_PARM_SYNTAX(snd_enable, SNDRV_ENABLE_DESC);MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");static struct pci_device_id snd_korg1212_ids[] __devinitdata = { { 0x10b5, 0x906d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, { 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",};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 };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 */void TickDelay(int time){ udelay(time);}#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; if (korg1212->outDoorbellPtr) {#ifdef DEBUG PRINTK("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. // -------------------------------------------------------------- switch (doorbellVal) { case K1212_DB_RebootCard: case K1212_DB_BootFromDSPPage4: case K1212_DB_StartDSPDownload: return K1212_CMDRET_Success; default: 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. // -------------------------------------------------------------- TickDelay(COMMAND_ACK_DELAY); mailBox3Lo = readl(korg1212->mailbox3Ptr); if (mailBox3Lo & COMMAND_ACK_MASK) { if ((mailBox3Lo & DOORBELL_VAL_MASK) == (doorbellVal & DOORBELL_VAL_MASK)) { korg1212->cmdRetryCount += retryCount; return K1212_CMDRET_Success; } } } korg1212->cmdRetryCount += retryCount; return K1212_CMDRET_NoAckFromCard; } else { return K1212_CMDRET_CardUninitialized; }}static void snd_korg1212_WaitForCardStopAck(korg1212_t *korg1212){ unsigned long endtime = jiffies + 20 * HZ;#ifdef DEBUG PRINTK("DEBUG: WaitForCardStopAck [%s]\n", stateName[korg1212->cardState]);#endif // DEBUG if (korg1212->inIRQ) return; do { if (readl(&korg1212->sharedBufferPtr->cardCommand) == 0) return; if (!korg1212->inIRQ) schedule(); } while (jiffies < endtime); writel(0, &korg1212->sharedBufferPtr->cardCommand);}static void snd_korg1212_TurnOnIdleMonitor(korg1212_t *korg1212){ TickDelay(INTERCOMMAND_DELAY); korg1212->idleMonitorOn = 1; rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode, K1212_MODE_MonitorOn, 0, 0, 0);}static void snd_korg1212_TurnOffIdleMonitor(korg1212_t *korg1212){ if (korg1212->idleMonitorOn) { writel(0xffffffff, &korg1212->sharedBufferPtr->cardCommand); snd_korg1212_WaitForCardStopAck(korg1212); korg1212->idleMonitorOn = 0; }}static void snd_korg1212_setCardState(korg1212_t * korg1212, CardState csState){ switch (csState) { case K1212_STATE_READY: snd_korg1212_TurnOnIdleMonitor(korg1212); break; case K1212_STATE_OPEN: snd_korg1212_TurnOffIdleMonitor(korg1212); break; default: break; } korg1212->cardState = csState;}static int snd_korg1212_OpenCard(korg1212_t * korg1212){#ifdef DEBUG PRINTK("DEBUG: OpenCard [%s]\n", stateName[korg1212->cardState]);#endif snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN); return 1;}static int snd_korg1212_CloseCard(korg1212_t * korg1212){#ifdef DEBUG PRINTK("DEBUG: CloseCard [%s]\n", stateName[korg1212->cardState]);#endif if (korg1212->cardState == K1212_STATE_SETUP) { rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode, K1212_MODE_StopPlay, 0, 0, 0);#ifdef DEBUG if (rc) PRINTK("DEBUG: CloseCard - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);#endif if (rc != K1212_CMDRET_Success) return 0; } else if (korg1212->cardState > K1212_STATE_SETUP) { writel(0xffffffff, &korg1212->sharedBufferPtr->cardCommand); snd_korg1212_WaitForCardStopAck(korg1212); } if (korg1212->cardState > K1212_STATE_READY) snd_korg1212_setCardState(korg1212, K1212_STATE_READY); return 0;}static int snd_korg1212_SetupForPlay(korg1212_t * korg1212){#ifdef DEBUG PRINTK("DEBUG: SetupForPlay [%s]\n", stateName[korg1212->cardState]);#endif snd_korg1212_setCardState(korg1212, K1212_STATE_SETUP); rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode, K1212_MODE_SetupPlay, 0, 0, 0);#ifdef DEBUG if (rc) PRINTK("DEBUG: SetupForPlay - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);#endif if (rc != K1212_CMDRET_Success) { return 0; } return 1;}static int snd_korg1212_TriggerPlay(korg1212_t * korg1212){#ifdef DEBUG PRINTK("DEBUG: TriggerPlay [%s]\n", stateName[korg1212->cardState]);#endif snd_korg1212_setCardState(korg1212, K1212_STATE_PLAYING); rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_TriggerPlay, 0, 0, 0, 0);#ifdef DEBUG if (rc) PRINTK("DEBUG: TriggerPlay - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);#endif if (rc != K1212_CMDRET_Success) { return 0; } return 1;}static int snd_korg1212_StopPlay(korg1212_t * korg1212){#ifdef DEBUG PRINTK("DEBUG: StopPlay [%s]\n", stateName[korg1212->cardState]);#endif if (korg1212->cardState != K1212_STATE_ERRORSTOP) { writel(0xffffffff, &korg1212->sharedBufferPtr->cardCommand); snd_korg1212_WaitForCardStopAck(korg1212); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -