📄 main.c
字号:
goto err_out3; } return 0;err_out3: kfree(card->mpuin);err_out2: kfree(card->mpuout);err_out1: return ret;}static void emu10k1_midi_cleanup(struct emu10k1_card *card){ tasklet_kill(&card->mpuout->tasklet); kfree(card->mpuout); tasklet_kill(&card->mpuin->tasklet); kfree(card->mpuin);}static void __devinit voice_init(struct emu10k1_card *card){ int i; for (i = 0; i < NUM_G; i++) card->voicetable[i] = VOICE_USAGE_FREE;}static void __devinit timer_init(struct emu10k1_card *card){ INIT_LIST_HEAD(&card->timers); card->timer_delay = TIMER_STOPPED; spin_lock_init(&card->timer_lock);}static void __devinit addxmgr_init(struct emu10k1_card *card){ u32 count; for (count = 0; count < MAXPAGES; count++) card->emupagetable[count] = 0; /* Mark first page as used */ /* This page is reserved by the driver */ card->emupagetable[0] = 0x8001; card->emupagetable[1] = MAXPAGES - 1;}static void fx_cleanup(struct patch_manager *mgr){ int i; for(i = 0; i < mgr->current_pages; i++) free_page((unsigned long) mgr->patch[i]);}static int __devinit fx_init(struct emu10k1_card *card){ struct patch_manager *mgr = &card->mgr; struct dsp_patch *patch; struct dsp_rpatch *rpatch; s32 left, right; int i; u32 pc = 0; u32 patch_n=0; struct emu_efx_info_t emu_efx_info[2]= {{ 20, 10, 0x400, 0x100, 0x20 }, { 24, 12, 0x600, 0x400, 0x60 }, }; for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { mgr->ctrl_gpr[i][0] = -1; mgr->ctrl_gpr[i][1] = -1; } if (card->is_audigy) mgr->current_pages = (2 + PATCHES_PER_PAGE - 1) / PATCHES_PER_PAGE; else /* !! The number below must equal the number of patches, currently 11 !! */ mgr->current_pages = (11 + PATCHES_PER_PAGE - 1) / PATCHES_PER_PAGE; for (i = 0; i < mgr->current_pages; i++) { mgr->patch[i] = (void *)__get_free_page(GFP_KERNEL); if (mgr->patch[i] == NULL) { mgr->current_pages = i; fx_cleanup(mgr); return -ENOMEM; } memset(mgr->patch[i], 0, PAGE_SIZE); } if (card->is_audigy) { for (i = 0; i < 1024; i++) OP(0xf, 0x0c0, 0x0c0, 0x0cf, 0x0c0); for (i = 0; i < 512 ; i++) sblive_writeptr(card, A_GPR_BASE+i,0,0); pc=0; //Pcm input volume OP(0, 0x402, 0x0c0, 0x406, 0x000); OP(0, 0x403, 0x0c0, 0x407, 0x001); //CD-Digital input Volume OP(0, 0x404, 0x0c0, 0x40d, 0x42); OP(0, 0x405, 0x0c0, 0x40f, 0x43); // CD + PCM OP(6, 0x400, 0x0c0, 0x402, 0x404); OP(6, 0x401, 0x0c0, 0x403, 0x405); // Front Output + Master Volume OP(0, 0x68, 0x0c0, 0x408, 0x400); OP(0, 0x69, 0x0c0, 0x409, 0x401); // Add-in analog inputs for other speakers OP(6, 0x400, 0x40, 0x400, 0xc0); OP(6, 0x401, 0x41, 0x401, 0xc0); // Digital Front + Master Volume OP(0, 0x60, 0x0c0, 0x408, 0x400); OP(0, 0x61, 0x0c0, 0x409, 0x401); // Rear Output + Rear Volume OP(0, 0x06e, 0x0c0, 0x419, 0x400); OP(0, 0x06f, 0x0c0, 0x41a, 0x401); // Digital Rear Output + Rear Volume OP(0, 0x066, 0x0c0, 0x419, 0x400); OP(0, 0x067, 0x0c0, 0x41a, 0x401); // Audigy Drive, Headphone out OP(6, 0x64, 0x0c0, 0x0c0, 0x400); OP(6, 0x65, 0x0c0, 0x0c0, 0x401); // ac97 Recording OP(6, 0x76, 0x0c0, 0x0c0, 0x40); OP(6, 0x77, 0x0c0, 0x0c0, 0x41); // Center = sub = Left/2 + Right/2 OP(0xe, 0x400, 0x401, 0xcd, 0x400); // center/sub Volume (master) OP(0, 0x06a, 0x0c0, 0x408, 0x400); OP(0, 0x06b, 0x0c0, 0x409, 0x400); // Digital center/sub Volume (master) OP(0, 0x062, 0x0c0, 0x408, 0x400); OP(0, 0x063, 0x0c0, 0x409, 0x400); ROUTING_PATCH_START(rpatch, "Routing"); ROUTING_PATCH_END(rpatch); /* delimiter patch */ patch = PATCH(mgr, patch_n); patch->code_size = 0; sblive_writeptr(card, 0x53, 0, 0); } else { for (i = 0; i < 512 ; i++) OP(6, 0x40, 0x40, 0x40, 0x40); for (i = 0; i < 256; i++) sblive_writeptr_tag(card, 0, FXGPREGBASE + i, 0, TANKMEMADDRREGBASE + i, 0, TAGLIST_END); pc = 0; //first free GPR = 0x11b /* FX volume correction and Volume control*/ INPUT_PATCH_START(patch, "Pcm L vol", 0x0, 0); GET_OUTPUT_GPR(patch, 0x100, 0x0); GET_CONTROL_GPR(patch, 0x106, "Vol", 0, 0x7fffffff); GET_DYNAMIC_GPR(patch, 0x112); OP(4, 0x112, 0x40, PCM_IN_L, 0x44); //*4 OP(0, 0x100, 0x040, 0x112, 0x106); //*vol INPUT_PATCH_END(patch); INPUT_PATCH_START(patch, "Pcm R vol", 0x1, 0); GET_OUTPUT_GPR(patch, 0x101, 0x1); GET_CONTROL_GPR(patch, 0x107, "Vol", 0, 0x7fffffff); GET_DYNAMIC_GPR(patch, 0x112); OP(4, 0x112, 0x40, PCM_IN_R, 0x44); OP(0, 0x101, 0x040, 0x112, 0x107); INPUT_PATCH_END(patch); // CD-Digital In Volume control INPUT_PATCH_START(patch, "CD-Digital Vol L", 0x12, 0); GET_OUTPUT_GPR(patch, 0x10c, 0x12); GET_CONTROL_GPR(patch, 0x10d, "Vol", 0, 0x7fffffff); OP(0, 0x10c, 0x040, SPDIF_CD_L, 0x10d); INPUT_PATCH_END(patch); INPUT_PATCH_START(patch, "CD-Digital Vol R", 0x13, 0); GET_OUTPUT_GPR(patch, 0x10e, 0x13); GET_CONTROL_GPR(patch, 0x10f, "Vol", 0, 0x7fffffff); OP(0, 0x10e, 0x040, SPDIF_CD_R, 0x10f); INPUT_PATCH_END(patch); //Volume Correction for Multi-channel Inputs INPUT_PATCH_START(patch, "Multi-Channel Gain", 0x08, 0); patch->input=patch->output=0x3F00; GET_OUTPUT_GPR(patch, 0x113, MULTI_FRONT_L); GET_OUTPUT_GPR(patch, 0x114, MULTI_FRONT_R); GET_OUTPUT_GPR(patch, 0x115, MULTI_REAR_L); GET_OUTPUT_GPR(patch, 0x116, MULTI_REAR_R); GET_OUTPUT_GPR(patch, 0x117, MULTI_CENTER); GET_OUTPUT_GPR(patch, 0x118, MULTI_LFE); OP(4, 0x113, 0x40, MULTI_FRONT_L, 0x44); OP(4, 0x114, 0x40, MULTI_FRONT_R, 0x44); OP(4, 0x115, 0x40, MULTI_REAR_L, 0x44); OP(4, 0x116, 0x40, MULTI_REAR_R, 0x44); OP(4, 0x117, 0x40, MULTI_CENTER, 0x44); OP(4, 0x118, 0x40, MULTI_LFE, 0x44); INPUT_PATCH_END(patch); //Routing patch start ROUTING_PATCH_START(rpatch, "Routing"); GET_INPUT_GPR(rpatch, 0x100, 0x0); GET_INPUT_GPR(rpatch, 0x101, 0x1); GET_INPUT_GPR(rpatch, 0x10c, 0x12); GET_INPUT_GPR(rpatch, 0x10e, 0x13); GET_INPUT_GPR(rpatch, 0x113, MULTI_FRONT_L); GET_INPUT_GPR(rpatch, 0x114, MULTI_FRONT_R); GET_INPUT_GPR(rpatch, 0x115, MULTI_REAR_L); GET_INPUT_GPR(rpatch, 0x116, MULTI_REAR_R); GET_INPUT_GPR(rpatch, 0x117, MULTI_CENTER); GET_INPUT_GPR(rpatch, 0x118, MULTI_LFE); GET_DYNAMIC_GPR(rpatch, 0x102); GET_DYNAMIC_GPR(rpatch, 0x103); GET_OUTPUT_GPR(rpatch, 0x104, 0x8); GET_OUTPUT_GPR(rpatch, 0x105, 0x9); GET_OUTPUT_GPR(rpatch, 0x10a, 0x2); GET_OUTPUT_GPR(rpatch, 0x10b, 0x3); /* input buffer */ OP(6, 0x102, AC97_IN_L, 0x40, 0x40); OP(6, 0x103, AC97_IN_R, 0x40, 0x40); /* Digital In + PCM + MULTI_FRONT-> AC97 out (front speakers)*/ OP(6, AC97_FRONT_L, 0x100, 0x10c, 0x113); CONNECT(MULTI_FRONT_L, AC97_FRONT_L); CONNECT(PCM_IN_L, AC97_FRONT_L); CONNECT(SPDIF_CD_L, AC97_FRONT_L); OP(6, AC97_FRONT_R, 0x101, 0x10e, 0x114); CONNECT(MULTI_FRONT_R, AC97_FRONT_R); CONNECT(PCM_IN_R, AC97_FRONT_R); CONNECT(SPDIF_CD_R, AC97_FRONT_R); /* Digital In + PCM + AC97 In + PCM1 + MULTI_REAR --> Rear Channel */ OP(6, 0x104, PCM1_IN_L, 0x100, 0x115); OP(6, 0x104, 0x104, 0x10c, 0x102); CONNECT(MULTI_REAR_L, ANALOG_REAR_L); CONNECT(AC97_IN_L, ANALOG_REAR_L); CONNECT(PCM_IN_L, ANALOG_REAR_L); CONNECT(SPDIF_CD_L, ANALOG_REAR_L); CONNECT(PCM1_IN_L, ANALOG_REAR_L); OP(6, 0x105, PCM1_IN_R, 0x101, 0x116); OP(6, 0x105, 0x105, 0x10e, 0x103); CONNECT(MULTI_REAR_R, ANALOG_REAR_R); CONNECT(AC97_IN_R, ANALOG_REAR_R); CONNECT(PCM_IN_R, ANALOG_REAR_R); CONNECT(SPDIF_CD_R, ANALOG_REAR_R); CONNECT(PCM1_IN_R, ANALOG_REAR_R); /* Digital In + PCM + AC97 In + MULTI_FRONT --> Digital out */ OP(6, 0x10b, 0x100, 0x102, 0x10c); OP(6, 0x10b, 0x10b, 0x113, 0x40); CONNECT(MULTI_FRONT_L, DIGITAL_OUT_L); CONNECT(PCM_IN_L, DIGITAL_OUT_L); CONNECT(AC97_IN_L, DIGITAL_OUT_L); CONNECT(SPDIF_CD_L, DIGITAL_OUT_L); OP(6, 0x10a, 0x101, 0x103, 0x10e); OP(6, 0x10b, 0x10b, 0x114, 0x40); CONNECT(MULTI_FRONT_R, DIGITAL_OUT_R); CONNECT(PCM_IN_R, DIGITAL_OUT_R); CONNECT(AC97_IN_R, DIGITAL_OUT_R); CONNECT(SPDIF_CD_R, DIGITAL_OUT_R); /* AC97 In --> ADC Recording Buffer */ OP(6, ADC_REC_L, 0x102, 0x40, 0x40); CONNECT(AC97_IN_L, ADC_REC_L); OP(6, ADC_REC_R, 0x103, 0x40, 0x40); CONNECT(AC97_IN_R, ADC_REC_R); /* fx12:Analog-Center */ OP(6, ANALOG_CENTER, 0x117, 0x40, 0x40); CONNECT(MULTI_CENTER, ANALOG_CENTER); /* fx11:Analog-LFE */ OP(6, ANALOG_LFE, 0x118, 0x40, 0x40); CONNECT(MULTI_LFE, ANALOG_LFE); /* fx12:Digital-Center */ OP(6, DIGITAL_CENTER, 0x117, 0x40, 0x40); CONNECT(MULTI_CENTER, DIGITAL_CENTER); /* fx11:Analog-LFE */ OP(6, DIGITAL_LFE, 0x118, 0x40, 0x40); CONNECT(MULTI_LFE, DIGITAL_LFE); ROUTING_PATCH_END(rpatch); // Rear volume control OUTPUT_PATCH_START(patch, "Vol Rear L", 0x8, 0); GET_INPUT_GPR(patch, 0x104, 0x8); GET_CONTROL_GPR(patch, 0x119, "Vol", 0, 0x7fffffff); OP(0, ANALOG_REAR_L, 0x040, 0x104, 0x119); OUTPUT_PATCH_END(patch); OUTPUT_PATCH_START(patch, "Vol Rear R", 0x9, 0); GET_INPUT_GPR(patch, 0x105, 0x9); GET_CONTROL_GPR(patch, 0x11a, "Vol", 0, 0x7fffffff); OP(0, ANALOG_REAR_R, 0x040, 0x105, 0x11a); OUTPUT_PATCH_END(patch); //Master volume control on front-digital OUTPUT_PATCH_START(patch, "Vol Master L", 0x2, 1); GET_INPUT_GPR(patch, 0x10a, 0x2); GET_CONTROL_GPR(patch, 0x108, "Vol", 0, 0x7fffffff); OP(0, DIGITAL_OUT_L, 0x040, 0x10a, 0x108); OUTPUT_PATCH_END(patch); OUTPUT_PATCH_START(patch, "Vol Master R", 0x3, 1); GET_INPUT_GPR(patch, 0x10b, 0x3); GET_CONTROL_GPR(patch, 0x109, "Vol", 0, 0x7fffffff); OP(0, DIGITAL_OUT_R, 0x040, 0x10b, 0x109); OUTPUT_PATCH_END(patch); /* delimiter patch */ patch = PATCH(mgr, patch_n); patch->code_size = 0; sblive_writeptr(card, DBG, 0, 0); } spin_lock_init(&mgr->lock); // Set up Volume controls, try to keep this the same for both Audigy and Live //Master volume mgr->ctrl_gpr[SOUND_MIXER_VOLUME][0] = 8; mgr->ctrl_gpr[SOUND_MIXER_VOLUME][1] = 9; left = card->ac97->mixer_state[SOUND_MIXER_VOLUME] & 0xff; right = (card->ac97->mixer_state[SOUND_MIXER_VOLUME] >> 8) & 0xff; emu10k1_set_volume_gpr(card, 8, left, 1 << card->ac97->bit_resolution); emu10k1_set_volume_gpr(card, 9, right, 1 << card->ac97->bit_resolution); //Rear volume mgr->ctrl_gpr[ SOUND_MIXER_OGAIN ][0] = 0x19; mgr->ctrl_gpr[ SOUND_MIXER_OGAIN ][1] = 0x1a; left = right = 67; card->ac97->mixer_state[SOUND_MIXER_OGAIN] = (right << 8) | left; card->ac97->supported_mixers |= SOUND_MASK_OGAIN; card->ac97->stereo_mixers |= SOUND_MASK_OGAIN; emu10k1_set_volume_gpr(card, 0x19, left, VOL_5BIT); emu10k1_set_volume_gpr(card, 0x1a, right, VOL_5BIT); //PCM Volume mgr->ctrl_gpr[SOUND_MIXER_PCM][0] = 6; mgr->ctrl_gpr[SOUND_MIXER_PCM][1] = 7; left = card->ac97->mixer_state[SOUND_MIXER_PCM] & 0xff; right = (card->ac97->mixer_state[SOUND_MIXER_PCM] >> 8) & 0xff; emu10k1_set_volume_gpr(card, 6, left, VOL_5BIT); emu10k1_set_volume_gpr(card, 7, right, VOL_5BIT); //CD-Digital Volume mgr->ctrl_gpr[SOUND_MIXER_DIGITAL1][0] = 0xd; mgr->ctrl_gpr[SOUND_MIXER_DIGITAL1][1] = 0xf; left = right = 67; card->ac97->mixer_state[SOUND_MIXER_DIGITAL1] = (right << 8) | left; card->ac97->supported_mixers |= SOUND_MASK_DIGITAL1; card->ac97->stereo_mixers |= SOUND_MASK_DIGITAL1; emu10k1_set_volume_gpr(card, 0xd, left, VOL_5BIT); emu10k1_set_volume_gpr(card, 0xf, right, VOL_5BIT); //hard wire the ac97's pcm, pcm volume is done above using dsp code. if (card->is_audigy) //for Audigy, we mute it and use the philips 6 channel DAC instead emu10k1_ac97_write(card->ac97, 0x18, 0x8000); else //For the Live we hardwire it to full volume emu10k1_ac97_write(card->ac97, 0x18, 0x0); //remove it from the ac97_codec's control card->ac97_supported_mixers &= ~SOUND_MASK_PCM; card->ac97_stereo_mixers &= ~SOUND_MASK_PCM; //set Igain to 0dB by default, maybe consider hardwiring it here. emu10k1_ac97_write(card->ac97, AC97_RECORD_GAIN, 0x0000); card->ac97->mixer_state[SOUND_MIXER_IGAIN] = 0x101; return 0;}static int __devinit hw_init(struct emu10k1_card *card){ int nCh; u32 pagecount; /* tmp */ int ret; /* Disable audio and lock cache */ emu10k1_writefn0(card, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE); /* Reset recording buffers */ sblive_writeptr_tag(card, 0, MICBS, ADCBS_BUFSIZE_NONE, MICBA, 0, FXBS, ADCBS_BUFSIZE_NONE, FXBA, 0, ADCBS, ADCBS_BUFSIZE_NONE, ADCBA, 0, TAGLIST_END); /* Disable channel interrupt */ emu10k1_writefn0(card, INTE, 0); sblive_writeptr_tag(card, 0, CLIEL, 0, CLIEH, 0, SOLEL, 0, SOLEH, 0, TAGLIST_END); if (card->is_audigy) { sblive_writeptr_tag(card,0, 0x5e,0xf00, 0x5f,0x3, TAGLIST_END); } /* Init envelope engine */ for (nCh = 0; nCh < NUM_G; nCh++) { sblive_writeptr_tag(card, nCh, DCYSUSV, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -