// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) by Jaroslav Kysela <[email protected]> * Universal interface for Audio Codec '97 * * For more details look to AC '97 component specification revision 2.2 * by Intel Corporation (http://developer.intel.com) and to datasheets * for specific codecs. */ #include <linux/delay.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/mutex.h> #include <linux/export.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/control.h> #include <sound/ac97_codec.h> #include <sound/asoundef.h> #include "ac97_id.h" #include "ac97_local.h" /* * PCM support */ static const unsigned char rate_reg_tables[2][4][9] = …; /* FIXME: more various mappings for ADC? */ static const unsigned char rate_cregs[9] = …; static unsigned char get_slot_reg(struct ac97_pcm *pcm, unsigned short cidx, unsigned short slot, int dbl) { … } static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate) { … } /** * 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_PCM_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. * * Return: Zero if successful, or a negative error code on failure. */ int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate) { … } EXPORT_SYMBOL(…); static unsigned short get_pslots(struct snd_ac97 *ac97, unsigned char *rate_table, unsigned short *spdif_slots) { … } static unsigned short get_cslots(struct snd_ac97 *ac97) { … } static unsigned int get_rates(struct ac97_pcm *pcm, unsigned int cidx, unsigned short slots, int dbl) { … } /** * snd_ac97_pcm_assign - assign AC97 slots to given PCM streams * @bus: the ac97 bus instance * @pcms_count: count of PCMs to be assigned * @pcms: PCMs to be assigned * * It assigns available AC97 slots for given PCMs. If none or only * some slots are available, pcm->xxx.slots and pcm->xxx.rslots[] members * are reduced and might be zero. * * Return: Zero if successful, or a negative error code on failure. */ int snd_ac97_pcm_assign(struct snd_ac97_bus *bus, unsigned short pcms_count, const struct ac97_pcm *pcms) { … } EXPORT_SYMBOL(…); /** * snd_ac97_pcm_open - opens the given AC97 pcm * @pcm: the ac97 pcm instance * @rate: rate in Hz, if codec does not support VRA, this value must be 48000Hz * @cfg: output stream characteristics * @slots: a subset of allocated slots (snd_ac97_pcm_assign) for this pcm * * It locks the specified slots and sets the given rate to AC97 registers. * * Return: Zero if successful, or a negative error code on failure. */ int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate, enum ac97_pcm_cfg cfg, unsigned short slots) { … } EXPORT_SYMBOL(…); /** * snd_ac97_pcm_close - closes the given AC97 pcm * @pcm: the ac97 pcm instance * * It frees the locked AC97 slots. * * Return: Zero. */ int snd_ac97_pcm_close(struct ac97_pcm *pcm) { … } EXPORT_SYMBOL(…); static int double_rate_hw_constraint_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { … } static int double_rate_hw_constraint_channels(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { … } /** * snd_ac97_pcm_double_rate_rules - set double rate constraints * @runtime: the runtime of the ac97 front playback pcm * * Installs the hardware constraint rules to prevent using double rates and * more than two channels at the same time. * * Return: Zero if successful, or a negative error code on failure. */ int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime) { … } EXPORT_SYMBOL(…);