/** * snd_ac97_set_rate - change the rate of the given input/output. * @ac97: the ac97 instance * @reg: the register to change * @rate: the sample rate to set * * Changes the rate of the given input/output on the codec. * If the codec doesn't support VAR, the rate must be 48000 (except * for SPDIF). * * The valid registers are AC97_PMC_MIC_ADC_RATE, * AC97_PCM_FRONT_DAC_RATE, AC97_PCM_LR_ADC_RATE. * AC97_PCM_SURR_DAC_RATE and AC97_PCM_LFE_DAC_RATE are accepted * if the codec supports them. * AC97_SPDIF is accepted as a pseudo register to modify the SPDIF * status bits. * * Returns zero if successful, or a negative error code on failure. */ int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate) { int dbl; unsigned int tmp; dbl = rate > 48000; if (dbl) { if (!(ac97->flags & AC97_DOUBLE_RATE)) return -EINVAL; if (reg != AC97_PCM_FRONT_DAC_RATE) return -EINVAL; } switch (reg) { case AC97_PCM_MIC_ADC_RATE: if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRM) == 0) /* MIC VRA */ if (rate != 48000) return -EINVAL; break; case AC97_PCM_FRONT_DAC_RATE: case AC97_PCM_LR_ADC_RATE: if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRA) == 0) /* VRA */ if (rate != 48000 && rate != 96000) return -EINVAL; break; case AC97_PCM_SURR_DAC_RATE: if (! (ac97->scaps & AC97_SCAP_SURROUND_DAC)) return -EINVAL; break; case AC97_PCM_LFE_DAC_RATE: if (! (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)) return -EINVAL; break; case AC97_SPDIF: /* special case */ return set_spdif_rate(ac97, rate); default: return -EINVAL; } if (dbl) rate /= 2; tmp = (rate * ac97->bus->clock) / 48000; if (tmp > 65535) return -EINVAL; if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE) snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_DRA, dbl ? AC97_EA_DRA : 0); snd_ac97_update(ac97, reg, tmp & 0xffff); snd_ac97_read(ac97, reg); if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE) { /* Intel controllers require double rate data to be put in * slots 7+8 */ snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, dbl ? AC97_GP_DRSS_78 : 0); snd_ac97_read(ac97, AC97_GENERAL_PURPOSE); } return 0; }
static int fsl_asoc_card_late_probe(struct snd_soc_card *card) { struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card); struct snd_soc_pcm_runtime *rtd = list_first_entry( &card->rtd_list, struct snd_soc_pcm_runtime, list); struct snd_soc_dai *codec_dai = rtd->codec_dai; struct codec_priv *codec_priv = &priv->codec_priv; struct device *dev = card->dev; int ret; if (fsl_asoc_card_is_ac97(priv)) { #if IS_ENABLED(CONFIG_SND_AC97_CODEC) struct snd_soc_codec *codec = rtd->codec; struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); /* * Use slots 3/4 for S/PDIF so SSI won't try to enable * other slots and send some samples there * due to SLOTREQ bits for S/PDIF received from codec */ snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPSA_SLOT_MASK, AC97_EA_SPSA_3_4); #endif return 0; } ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id, codec_priv->mclk_freq, SND_SOC_CLOCK_IN); if (ret) { dev_err(dev, "failed to set sysclk in %s\n", __func__); return ret; } return 0; }
static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate) { unsigned short old, bits, reg, mask; unsigned int sbits; if (! (ac97->ext_id & AC97_EI_SPDIF)) return -ENODEV; /* TODO: double rate support */ if (ac97->flags & AC97_CS_SPDIF) { switch (rate) { case 48000: bits = 0; break; case 44100: bits = 1 << AC97_SC_SPSR_SHIFT; break; default: /* invalid - disable output */ snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); return -EINVAL; } reg = AC97_CSR_SPDIF; mask = 1 << AC97_SC_SPSR_SHIFT; } else { if (ac97->id == AC97_ID_CM9739 && rate != 48000) { snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); return -EINVAL; } switch (rate) { case 44100: bits = AC97_SC_SPSR_44K; break; case 48000: bits = AC97_SC_SPSR_48K; break; case 32000: bits = AC97_SC_SPSR_32K; break; default: /* invalid - disable output */ snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); return -EINVAL; } reg = AC97_SPDIF; mask = AC97_SC_SPSR_MASK; } mutex_lock(&ac97->reg_mutex); old = snd_ac97_read(ac97, reg) & mask; if (old != bits) { snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); snd_ac97_update_bits_nolock(ac97, reg, mask, bits); /* update the internal spdif bits */ sbits = ac97->spdif_status; if (sbits & IEC958_AES0_PROFESSIONAL) { sbits &= ~IEC958_AES0_PRO_FS; switch (rate) { case 44100: sbits |= IEC958_AES0_PRO_FS_44100; break; case 48000: sbits |= IEC958_AES0_PRO_FS_48000; break; case 32000: sbits |= IEC958_AES0_PRO_FS_32000; break; } } else { sbits &= ~(IEC958_AES3_CON_FS << 24); switch (rate) { case 44100: sbits |= IEC958_AES3_CON_FS_44100<<24; break; case 48000: sbits |= IEC958_AES3_CON_FS_48000<<24; break; case 32000: sbits |= IEC958_AES3_CON_FS_32000<<24; break; } } ac97->spdif_status = sbits; } snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); mutex_unlock(&ac97->reg_mutex); return 0; }
static int __devinit snd_atiixp_pcm_new(atiixp_t *chip) { snd_pcm_t *pcm; ac97_bus_t *pbus = chip->ac97_bus; int err, i, num_pcms; /* initialize constants */ chip->dmas[ATI_DMA_PLAYBACK].ops = &snd_atiixp_playback_dma_ops; chip->dmas[ATI_DMA_CAPTURE].ops = &snd_atiixp_capture_dma_ops; if (! chip->spdif_over_aclink) chip->dmas[ATI_DMA_SPDIF].ops = &snd_atiixp_spdif_dma_ops; /* assign AC97 pcm */ if (chip->spdif_over_aclink) num_pcms = 3; else num_pcms = 2; err = snd_ac97_pcm_assign(pbus, num_pcms, atiixp_pcm_defs); if (err < 0) return err; for (i = 0; i < num_pcms; i++) chip->pcms[i] = &pbus->pcms[i]; chip->max_channels = 2; if (pbus->pcms[ATI_PCM_OUT].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) { if (pbus->pcms[ATI_PCM_OUT].r[0].slots & (1 << AC97_SLOT_LFE)) chip->max_channels = 6; else chip->max_channels = 4; } /* PCM #0: analog I/O */ err = snd_pcm_new(chip->card, "ATI IXP AC97", ATI_PCMDEV_ANALOG, 1, 1, &pcm); if (err < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops); pcm->private_data = chip; strcpy(pcm->name, "ATI IXP AC97"); chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 64*1024, 128*1024); /* no SPDIF support on codec? */ if (chip->pcms[ATI_PCM_SPDIF] && ! chip->pcms[ATI_PCM_SPDIF]->rates) return 0; /* FIXME: non-48k sample rate doesn't work on my test machine with AD1888 */ if (chip->pcms[ATI_PCM_SPDIF]) chip->pcms[ATI_PCM_SPDIF]->rates = SNDRV_PCM_RATE_48000; /* PCM #1: spdif playback */ err = snd_pcm_new(chip->card, "ATI IXP IEC958", ATI_PCMDEV_DIGITAL, 1, 0, &pcm); if (err < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_spdif_ops); pcm->private_data = chip; if (chip->spdif_over_aclink) strcpy(pcm->name, "ATI IXP IEC958 (AC97)"); else strcpy(pcm->name, "ATI IXP IEC958 (Direct)"); chip->pcmdevs[ATI_PCMDEV_DIGITAL] = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 64*1024, 128*1024); /* pre-select AC97 SPDIF slots 10/11 */ for (i = 0; i < NUM_ATI_CODECS; i++) { if (chip->ac97[i]) snd_ac97_update_bits(chip->ac97[i], AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4); } return 0; }