#include <linux/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/info.h>
#include <sound/ac97_codec.h>
#include <sound/initval.h>
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
static int index = …;
static char *id = …;
static int ac97_clock = …;
static char *ac97_quirk;
static bool spdif_aclink = …;
static int ac97_codec = …;
module_param(index, int, 0444);
MODULE_PARM_DESC(…) …;
module_param(id, charp, 0444);
MODULE_PARM_DESC(…) …;
module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(…) …;
module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(…) …;
module_param(ac97_codec, int, 0444);
MODULE_PARM_DESC(…) …;
module_param(spdif_aclink, bool, 0444);
MODULE_PARM_DESC(…) …;
static bool enable;
module_param(enable, bool, 0444);
#define ATI_REG_ISR …
#define ATI_REG_ISR_IN_XRUN …
#define ATI_REG_ISR_IN_STATUS …
#define ATI_REG_ISR_OUT_XRUN …
#define ATI_REG_ISR_OUT_STATUS …
#define ATI_REG_ISR_SPDF_XRUN …
#define ATI_REG_ISR_SPDF_STATUS …
#define ATI_REG_ISR_PHYS_INTR …
#define ATI_REG_ISR_PHYS_MISMATCH …
#define ATI_REG_ISR_CODEC0_NOT_READY …
#define ATI_REG_ISR_CODEC1_NOT_READY …
#define ATI_REG_ISR_CODEC2_NOT_READY …
#define ATI_REG_ISR_NEW_FRAME …
#define ATI_REG_IER …
#define ATI_REG_IER_IN_XRUN_EN …
#define ATI_REG_IER_IO_STATUS_EN …
#define ATI_REG_IER_OUT_XRUN_EN …
#define ATI_REG_IER_OUT_XRUN_COND …
#define ATI_REG_IER_SPDF_XRUN_EN …
#define ATI_REG_IER_SPDF_STATUS_EN …
#define ATI_REG_IER_PHYS_INTR_EN …
#define ATI_REG_IER_PHYS_MISMATCH_EN …
#define ATI_REG_IER_CODEC0_INTR_EN …
#define ATI_REG_IER_CODEC1_INTR_EN …
#define ATI_REG_IER_CODEC2_INTR_EN …
#define ATI_REG_IER_NEW_FRAME_EN …
#define ATI_REG_IER_SET_BUS_BUSY …
#define ATI_REG_CMD …
#define ATI_REG_CMD_POWERDOWN …
#define ATI_REG_CMD_RECEIVE_EN …
#define ATI_REG_CMD_SEND_EN …
#define ATI_REG_CMD_STATUS_MEM …
#define ATI_REG_CMD_SPDF_OUT_EN …
#define ATI_REG_CMD_SPDF_STATUS_MEM …
#define ATI_REG_CMD_SPDF_THRESHOLD …
#define ATI_REG_CMD_SPDF_THRESHOLD_SHIFT …
#define ATI_REG_CMD_IN_DMA_EN …
#define ATI_REG_CMD_OUT_DMA_EN …
#define ATI_REG_CMD_SPDF_DMA_EN …
#define ATI_REG_CMD_SPDF_OUT_STOPPED …
#define ATI_REG_CMD_SPDF_CONFIG_MASK …
#define ATI_REG_CMD_SPDF_CONFIG_34 …
#define ATI_REG_CMD_SPDF_CONFIG_78 …
#define ATI_REG_CMD_SPDF_CONFIG_69 …
#define ATI_REG_CMD_SPDF_CONFIG_01 …
#define ATI_REG_CMD_INTERLEAVE_SPDF …
#define ATI_REG_CMD_AUDIO_PRESENT …
#define ATI_REG_CMD_INTERLEAVE_IN …
#define ATI_REG_CMD_INTERLEAVE_OUT …
#define ATI_REG_CMD_LOOPBACK_EN …
#define ATI_REG_CMD_PACKED_DIS …
#define ATI_REG_CMD_BURST_EN …
#define ATI_REG_CMD_PANIC_EN …
#define ATI_REG_CMD_MODEM_PRESENT …
#define ATI_REG_CMD_ACLINK_ACTIVE …
#define ATI_REG_CMD_AC_SOFT_RESET …
#define ATI_REG_CMD_AC_SYNC …
#define ATI_REG_CMD_AC_RESET …
#define ATI_REG_PHYS_OUT_ADDR …
#define ATI_REG_PHYS_OUT_CODEC_MASK …
#define ATI_REG_PHYS_OUT_RW …
#define ATI_REG_PHYS_OUT_ADDR_EN …
#define ATI_REG_PHYS_OUT_ADDR_SHIFT …
#define ATI_REG_PHYS_OUT_DATA_SHIFT …
#define ATI_REG_PHYS_IN_ADDR …
#define ATI_REG_PHYS_IN_READ_FLAG …
#define ATI_REG_PHYS_IN_ADDR_SHIFT …
#define ATI_REG_PHYS_IN_DATA_SHIFT …
#define ATI_REG_SLOTREQ …
#define ATI_REG_COUNTER …
#define ATI_REG_COUNTER_SLOT …
#define ATI_REG_COUNTER_BITCLOCK …
#define ATI_REG_IN_FIFO_THRESHOLD …
#define ATI_REG_IN_DMA_LINKPTR …
#define ATI_REG_IN_DMA_DT_START …
#define ATI_REG_IN_DMA_DT_NEXT …
#define ATI_REG_IN_DMA_DT_CUR …
#define ATI_REG_IN_DMA_DT_SIZE …
#define ATI_REG_OUT_DMA_SLOT …
#define ATI_REG_OUT_DMA_SLOT_BIT(x) …
#define ATI_REG_OUT_DMA_SLOT_MASK …
#define ATI_REG_OUT_DMA_THRESHOLD_MASK …
#define ATI_REG_OUT_DMA_THRESHOLD_SHIFT …
#define ATI_REG_OUT_DMA_LINKPTR …
#define ATI_REG_OUT_DMA_DT_START …
#define ATI_REG_OUT_DMA_DT_NEXT …
#define ATI_REG_OUT_DMA_DT_CUR …
#define ATI_REG_OUT_DMA_DT_SIZE …
#define ATI_REG_SPDF_CMD …
#define ATI_REG_SPDF_CMD_LFSR …
#define ATI_REG_SPDF_CMD_SINGLE_CH …
#define ATI_REG_SPDF_CMD_LFSR_ACC …
#define ATI_REG_SPDF_DMA_LINKPTR …
#define ATI_REG_SPDF_DMA_DT_START …
#define ATI_REG_SPDF_DMA_DT_NEXT …
#define ATI_REG_SPDF_DMA_DT_CUR …
#define ATI_REG_SPDF_DMA_DT_SIZE …
#define ATI_REG_MODEM_MIRROR …
#define ATI_REG_AUDIO_MIRROR …
#define ATI_REG_6CH_REORDER …
#define ATI_REG_6CH_REORDER_EN …
#define ATI_REG_FIFO_FLUSH …
#define ATI_REG_FIFO_OUT_FLUSH …
#define ATI_REG_FIFO_IN_FLUSH …
#define ATI_REG_LINKPTR_EN …
#define ATI_REG_DMA_DT_SIZE …
#define ATI_REG_DMA_FIFO_USED …
#define ATI_REG_DMA_FIFO_FREE …
#define ATI_REG_DMA_STATE …
#define ATI_MAX_DESCRIPTORS …
struct atiixp;
struct atiixp_dma_desc { … };
enum { … };
enum { … };
enum { … };
#define NUM_ATI_CODECS …
struct atiixp_dma_ops { … };
struct atiixp_dma { … };
struct atiixp { … };
static const struct pci_device_id snd_atiixp_ids[] = …;
MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);
static const struct snd_pci_quirk atiixp_quirks[] = …;
static int snd_atiixp_update_bits(struct atiixp *chip, unsigned int reg,
unsigned int mask, unsigned int value)
{ … }
#define atiixp_write(chip,reg,value) …
#define atiixp_read(chip,reg) …
#define atiixp_update(chip,reg,mask,val) …
#define ATI_DESC_LIST_SIZE …
static int atiixp_build_dma_packets(struct atiixp *chip, struct atiixp_dma *dma,
struct snd_pcm_substream *substream,
unsigned int periods,
unsigned int period_bytes)
{ … }
static void atiixp_clear_dma_packets(struct atiixp *chip, struct atiixp_dma *dma,
struct snd_pcm_substream *substream)
{ … }
static int snd_atiixp_acquire_codec(struct atiixp *chip)
{ … }
static unsigned short snd_atiixp_codec_read(struct atiixp *chip, unsigned short codec, unsigned short reg)
{ … }
static void snd_atiixp_codec_write(struct atiixp *chip, unsigned short codec,
unsigned short reg, unsigned short val)
{ … }
static unsigned short snd_atiixp_ac97_read(struct snd_ac97 *ac97,
unsigned short reg)
{ … }
static void snd_atiixp_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
unsigned short val)
{ … }
static int snd_atiixp_aclink_reset(struct atiixp *chip)
{ … }
static int snd_atiixp_aclink_down(struct atiixp *chip)
{ … }
#define ALL_CODEC_NOT_READY …
#define CODEC_CHECK_BITS …
static int ac97_probing_bugs(struct pci_dev *pci)
{ … }
static int snd_atiixp_codec_detect(struct atiixp *chip)
{ … }
static int snd_atiixp_chip_start(struct atiixp *chip)
{ … }
static int snd_atiixp_chip_stop(struct atiixp *chip)
{ … }
static snd_pcm_uframes_t snd_atiixp_pcm_pointer(struct snd_pcm_substream *substream)
{ … }
static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma)
{ … }
static void snd_atiixp_update_dma(struct atiixp *chip, struct atiixp_dma *dma)
{ … }
static void snd_atiixp_check_bus_busy(struct atiixp *chip)
{ … }
static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{ … }
static void atiixp_out_flush_dma(struct atiixp *chip)
{ … }
static void atiixp_out_enable_dma(struct atiixp *chip, int on)
{ … }
static void atiixp_out_enable_transfer(struct atiixp *chip, int on)
{ … }
static void atiixp_in_enable_dma(struct atiixp *chip, int on)
{ … }
static void atiixp_in_enable_transfer(struct atiixp *chip, int on)
{ … }
static void atiixp_in_flush_dma(struct atiixp *chip)
{ … }
static void atiixp_spdif_enable_dma(struct atiixp *chip, int on)
{ … }
static void atiixp_spdif_enable_transfer(struct atiixp *chip, int on)
{ … }
static void atiixp_spdif_flush_dma(struct atiixp *chip)
{ … }
static int snd_atiixp_spdif_prepare(struct snd_pcm_substream *substream)
{ … }
static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream)
{ … }
static int snd_atiixp_capture_prepare(struct snd_pcm_substream *substream)
{ … }
static int snd_atiixp_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{ … }
static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream)
{ … }
static const struct snd_pcm_hardware snd_atiixp_pcm_hw = …;
static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
struct atiixp_dma *dma, int pcm_type)
{ … }
static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
struct atiixp_dma *dma)
{ … }
static int snd_atiixp_playback_open(struct snd_pcm_substream *substream)
{ … }
static int snd_atiixp_playback_close(struct snd_pcm_substream *substream)
{ … }
static int snd_atiixp_capture_open(struct snd_pcm_substream *substream)
{ … }
static int snd_atiixp_capture_close(struct snd_pcm_substream *substream)
{ … }
static int snd_atiixp_spdif_open(struct snd_pcm_substream *substream)
{ … }
static int snd_atiixp_spdif_close(struct snd_pcm_substream *substream)
{ … }
static const struct snd_pcm_ops snd_atiixp_playback_ops = …;
static const struct snd_pcm_ops snd_atiixp_capture_ops = …;
static const struct snd_pcm_ops snd_atiixp_spdif_ops = …;
static const struct ac97_pcm atiixp_pcm_defs[] = …;
static const struct atiixp_dma_ops snd_atiixp_playback_dma_ops = …;
static const struct atiixp_dma_ops snd_atiixp_capture_dma_ops = …;
static const struct atiixp_dma_ops snd_atiixp_spdif_dma_ops = …;
static int snd_atiixp_pcm_new(struct atiixp *chip)
{ … }
static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id)
{ … }
static const struct ac97_quirk ac97_quirks[] = …;
static int snd_atiixp_mixer_new(struct atiixp *chip, int clock,
const char *quirk_override)
{ … }
static int snd_atiixp_suspend(struct device *dev)
{ … }
static int snd_atiixp_resume(struct device *dev)
{ … }
static DEFINE_SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume);
static void snd_atiixp_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{ … }
static void snd_atiixp_proc_init(struct atiixp *chip)
{ … }
static void snd_atiixp_free(struct snd_card *card)
{ … }
static int snd_atiixp_init(struct snd_card *card, struct pci_dev *pci)
{ … }
static int __snd_atiixp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{ … }
static int snd_atiixp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{ … }
static struct pci_driver atiixp_driver = …;
module_pci_driver(…) …;