📄 ens1370.c
字号:
#ifdef CHIP1370 ensoniq->u.es1370.pclkdiv_lock &= ~ES_MODE_CAPTURE;#endif ensoniq->mode &= ~ES_MODE_CAPTURE; spin_unlock_irq(&ensoniq->reg_lock); return 0;}static snd_pcm_ops_t snd_ensoniq_playback1_ops = { .open = snd_ensoniq_playback1_open, .close = snd_ensoniq_playback1_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ensoniq_hw_params, .hw_free = snd_ensoniq_hw_free, .prepare = snd_ensoniq_playback1_prepare, .trigger = snd_ensoniq_trigger, .pointer = snd_ensoniq_playback1_pointer,};static snd_pcm_ops_t snd_ensoniq_playback2_ops = { .open = snd_ensoniq_playback2_open, .close = snd_ensoniq_playback2_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ensoniq_hw_params, .hw_free = snd_ensoniq_hw_free, .prepare = snd_ensoniq_playback2_prepare, .trigger = snd_ensoniq_trigger, .pointer = snd_ensoniq_playback2_pointer,};static snd_pcm_ops_t snd_ensoniq_capture_ops = { .open = snd_ensoniq_capture_open, .close = snd_ensoniq_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ensoniq_hw_params, .hw_free = snd_ensoniq_hw_free, .prepare = snd_ensoniq_capture_prepare, .trigger = snd_ensoniq_trigger, .pointer = snd_ensoniq_capture_pointer,};static void snd_ensoniq_pcm_free(snd_pcm_t *pcm){ ensoniq_t *ensoniq = pcm->private_data; ensoniq->pcm1 = NULL; snd_pcm_lib_preallocate_free_for_all(pcm);}static int __devinit snd_ensoniq_pcm(ensoniq_t * ensoniq, int device, snd_pcm_t ** rpcm){ snd_pcm_t *pcm; int err; if (rpcm) *rpcm = NULL;#ifdef CHIP1370 err = snd_pcm_new(ensoniq->card, "ES1370/1", device, 1, 1, &pcm);#else err = snd_pcm_new(ensoniq->card, "ES1371/1", device, 1, 1, &pcm);#endif if (err < 0) return err;#ifdef CHIP1370 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops);#else snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops);#endif snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ensoniq_capture_ops); pcm->private_data = ensoniq; pcm->private_free = snd_ensoniq_pcm_free; pcm->info_flags = 0;#ifdef CHIP1370 strcpy(pcm->name, "ES1370 DAC2/ADC");#else strcpy(pcm->name, "ES1371 DAC2/ADC");#endif ensoniq->pcm1 = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024); if (rpcm) *rpcm = pcm; return 0;}static void snd_ensoniq_pcm_free2(snd_pcm_t *pcm){ ensoniq_t *ensoniq = pcm->private_data; ensoniq->pcm2 = NULL; snd_pcm_lib_preallocate_free_for_all(pcm);}static int __devinit snd_ensoniq_pcm2(ensoniq_t * ensoniq, int device, snd_pcm_t ** rpcm){ snd_pcm_t *pcm; int err; if (rpcm) *rpcm = NULL;#ifdef CHIP1370 err = snd_pcm_new(ensoniq->card, "ES1370/2", device, 1, 0, &pcm);#else err = snd_pcm_new(ensoniq->card, "ES1371/2", device, 1, 0, &pcm);#endif if (err < 0) return err;#ifdef CHIP1370 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops);#else snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops);#endif pcm->private_data = ensoniq; pcm->private_free = snd_ensoniq_pcm_free2; pcm->info_flags = 0;#ifdef CHIP1370 strcpy(pcm->name, "ES1370 DAC1");#else strcpy(pcm->name, "ES1371 DAC1");#endif ensoniq->pcm2 = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024); if (rpcm) *rpcm = pcm; return 0;}/* * Mixer section *//* * ENS1371 mixer (including SPDIF interface) */#ifdef CHIP1371static int snd_ens1373_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0;}static int snd_ens1373_spdif_default_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); spin_lock_irq(&ensoniq->reg_lock); ucontrol->value.iec958.status[0] = (ensoniq->spdif_default >> 0) & 0xff; ucontrol->value.iec958.status[1] = (ensoniq->spdif_default >> 8) & 0xff; ucontrol->value.iec958.status[2] = (ensoniq->spdif_default >> 16) & 0xff; ucontrol->value.iec958.status[3] = (ensoniq->spdif_default >> 24) & 0xff; spin_unlock_irq(&ensoniq->reg_lock); return 0;}static int snd_ens1373_spdif_default_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); unsigned int val; int change; val = ((u32)ucontrol->value.iec958.status[0] << 0) | ((u32)ucontrol->value.iec958.status[1] << 8) | ((u32)ucontrol->value.iec958.status[2] << 16) | ((u32)ucontrol->value.iec958.status[3] << 24); spin_lock_irq(&ensoniq->reg_lock); change = ensoniq->spdif_default != val; ensoniq->spdif_default = val; if (change && ensoniq->playback1_substream == NULL && ensoniq->playback2_substream == NULL) outl(val, ES_REG(ensoniq, CHANNEL_STATUS)); spin_unlock_irq(&ensoniq->reg_lock); return change;}static int snd_ens1373_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ucontrol->value.iec958.status[0] = 0xff; ucontrol->value.iec958.status[1] = 0xff; ucontrol->value.iec958.status[2] = 0xff; ucontrol->value.iec958.status[3] = 0xff; return 0;}static int snd_ens1373_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); spin_lock_irq(&ensoniq->reg_lock); ucontrol->value.iec958.status[0] = (ensoniq->spdif_stream >> 0) & 0xff; ucontrol->value.iec958.status[1] = (ensoniq->spdif_stream >> 8) & 0xff; ucontrol->value.iec958.status[2] = (ensoniq->spdif_stream >> 16) & 0xff; ucontrol->value.iec958.status[3] = (ensoniq->spdif_stream >> 24) & 0xff; spin_unlock_irq(&ensoniq->reg_lock); return 0;}static int snd_ens1373_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); unsigned int val; int change; val = ((u32)ucontrol->value.iec958.status[0] << 0) | ((u32)ucontrol->value.iec958.status[1] << 8) | ((u32)ucontrol->value.iec958.status[2] << 16) | ((u32)ucontrol->value.iec958.status[3] << 24); spin_lock_irq(&ensoniq->reg_lock); change = ensoniq->spdif_stream != val; ensoniq->spdif_stream = val; if (change && (ensoniq->playback1_substream != NULL || ensoniq->playback2_substream != NULL)) outl(val, ES_REG(ensoniq, CHANNEL_STATUS)); spin_unlock_irq(&ensoniq->reg_lock); return change;}#define ES1371_SPDIF(xname) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_es1371_spdif_info, \ .get = snd_es1371_spdif_get, .put = snd_es1371_spdif_put }static int snd_es1371_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0;}static int snd_es1371_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); spin_lock_irq(&ensoniq->reg_lock); ucontrol->value.integer.value[0] = ensoniq->ctrl & ES_1373_SPDIF_THRU ? 1 : 0; spin_unlock_irq(&ensoniq->reg_lock); return 0;}static int snd_es1371_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); unsigned int nval1, nval2; int change; nval1 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_THRU : 0; nval2 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_EN : 0; spin_lock_irq(&ensoniq->reg_lock); change = (ensoniq->ctrl & ES_1373_SPDIF_THRU) != nval1; ensoniq->ctrl &= ~ES_1373_SPDIF_THRU; ensoniq->ctrl |= nval1; ensoniq->cssr &= ~ES_1373_SPDIF_EN; ensoniq->cssr |= nval2; outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); spin_unlock_irq(&ensoniq->reg_lock); return change;}/* spdif controls */static snd_kcontrol_new_t snd_es1371_mixer_spdif[] __devinitdata = { ES1371_SPDIF("IEC958 Playback Switch"), { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .info = snd_ens1373_spdif_info, .get = snd_ens1373_spdif_default_get, .put = snd_ens1373_spdif_default_put, }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), .info = snd_ens1373_spdif_info, .get = snd_ens1373_spdif_mask_get }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), .info = snd_ens1373_spdif_info, .get = snd_ens1373_spdif_stream_get, .put = snd_ens1373_spdif_stream_put },};static int snd_es1373_rear_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0;}static int snd_es1373_rear_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); int val = 0; spin_lock_irq(&ensoniq->reg_lock); if ((ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) == ES_1373_REAR_BIT26) val = 1; ucontrol->value.integer.value[0] = val; spin_unlock_irq(&ensoniq->reg_lock); return 0;}static int snd_es1373_rear_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); unsigned int nval1; int change; nval1 = ucontrol->value.integer.value[0] ? ES_1373_REAR_BIT26 : (ES_1373_REAR_BIT27|ES_1373_REAR_BIT24); spin_lock_irq(&ensoniq->reg_lock); change = (ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) != nval1; ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24); ensoniq->cssr |= nval1; outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); spin_unlock_irq(&ensoniq->reg_lock); return change;}static snd_kcontrol_new_t snd_ens1373_rear __devinitdata ={ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "AC97 2ch->4ch Copy Switch", .info = snd_es1373_rear_info, .get = snd_es1373_rear_get, .put = snd_es1373_rear_put,};static int snd_es1373_line_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0;}static int snd_es1373_line_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); int val = 0; spin_lock_irq(&ensoniq->reg_lock); if ((ensoniq->ctrl & ES_1371_GPIO_OUTM) >= 4) val = 1; ucontrol->value.integer.value[0] = val; spin_unlock_irq(&ensoniq->reg_lock); return 0;}static int snd_es1373_line_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); int changed; unsigned int ctrl; spin_lock_irq(&ensoniq->reg_lock); ctrl = ensoniq->ctrl; if (ucontrol->value.integer.value[0]) ensoniq->ctrl |= ES_1371_GPIO_OUT(4); /* switch line-in -> rear out */ else ensoniq->ctrl &= ~ES_1371_GPIO_OUT(4); changed = (ctrl != ensoniq->ctrl); if (changed) outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); spin_unlock_irq(&ensoniq->reg_lock); return changed;}static snd_kcontrol_new_t snd_ens1373_line __devinitdata ={ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -