ens1370.c
来自「linux 内核源代码」· C语言 代码 · 共 1,967 行 · 第 1/5 页
C
1,967 行
}static int snd_ensoniq_playback2_close(struct snd_pcm_substream *substream){ struct ensoniq *ensoniq = snd_pcm_substream_chip(substream); ensoniq->playback2_substream = NULL; spin_lock_irq(&ensoniq->reg_lock);#ifdef CHIP1370 ensoniq->u.es1370.pclkdiv_lock &= ~ES_MODE_PLAY2;#endif ensoniq->mode &= ~ES_MODE_PLAY2; spin_unlock_irq(&ensoniq->reg_lock); return 0;}static int snd_ensoniq_capture_close(struct snd_pcm_substream *substream){ struct ensoniq *ensoniq = snd_pcm_substream_chip(substream); ensoniq->capture_substream = NULL; spin_lock_irq(&ensoniq->reg_lock);#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 struct snd_pcm_ops 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 struct snd_pcm_ops 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 struct snd_pcm_ops 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 int __devinit snd_ensoniq_pcm(struct ensoniq * ensoniq, int device, struct snd_pcm ** rpcm){ struct snd_pcm *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->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 int __devinit snd_ensoniq_pcm2(struct ensoniq * ensoniq, int device, struct snd_pcm ** rpcm){ struct snd_pcm *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->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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0;}static int snd_ens1373_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct ensoniq *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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct ensoniq *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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct ensoniq *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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct ensoniq *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 }#define snd_es1371_spdif_info snd_ctl_boolean_mono_infostatic int snd_es1371_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct ensoniq *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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct ensoniq *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 struct snd_kcontrol_new snd_es1371_mixer_spdif[] __devinitdata = { ES1371_SPDIF(SNDRV_CTL_NAME_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 },};#define snd_es1373_rear_info snd_ctl_boolean_mono_infostatic int snd_es1373_rear_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct ensoniq *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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct ensoniq *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 struct snd_kcontrol_new 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,};#define snd_es1373_line_info snd_ctl_boolean_mono_infostatic int snd_es1373_line_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct ensoniq *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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct ensoniq *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 struct snd_kcontrol_new snd_ens1373_line __devinitdata ={ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Line In->Rear Out Switch", .info = snd_es1373_line_info, .get = snd_es1373_line_get, .put = snd_es1373_line_put,};static void snd_ensoniq_mixer_free_ac97(struct snd_ac97 *ac97){ struct ensoniq *ensoniq = ac97->private_data;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?