182c29810SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 212bb5b78SClemens Ladisch /* Analog Devices 1889 audio driver 312bb5b78SClemens Ladisch * 412bb5b78SClemens Ladisch * This is a driver for the AD1889 PCI audio chipset found 512bb5b78SClemens Ladisch * on the HP PA-RISC [BCJ]-xxx0 workstations. 612bb5b78SClemens Ladisch * 712bb5b78SClemens Ladisch * Copyright (C) 2004-2005, Kyle McMartin <kyle@parisc-linux.org> 812bb5b78SClemens Ladisch * Copyright (C) 2005, Thibaut Varene <varenet@parisc-linux.org> 912bb5b78SClemens Ladisch * Based on the OSS AD1889 driver by Randolph Chung <tausq@debian.org> 1012bb5b78SClemens Ladisch * 1112bb5b78SClemens Ladisch * TODO: 1212bb5b78SClemens Ladisch * Do we need to take care of CCS register? 1312bb5b78SClemens Ladisch * Maybe we could use finer grained locking (separate locks for pb/cap)? 1412bb5b78SClemens Ladisch * Wishlist: 1512bb5b78SClemens Ladisch * Control Interface (mixer) support 1612bb5b78SClemens Ladisch * Better AC97 support (VSR...)? 1712bb5b78SClemens Ladisch * PM support 1812bb5b78SClemens Ladisch * MIDI support 1912bb5b78SClemens Ladisch * Game Port support 2012bb5b78SClemens Ladisch * SG DMA support (this will need *a lot* of work) 2112bb5b78SClemens Ladisch */ 2212bb5b78SClemens Ladisch 2312bb5b78SClemens Ladisch #include <linux/init.h> 2412bb5b78SClemens Ladisch #include <linux/pci.h> 259d2f928dSTobias Klauser #include <linux/dma-mapping.h> 2612bb5b78SClemens Ladisch #include <linux/slab.h> 2712bb5b78SClemens Ladisch #include <linux/interrupt.h> 2812bb5b78SClemens Ladisch #include <linux/compiler.h> 2912bb5b78SClemens Ladisch #include <linux/delay.h> 30da155d5bSPaul Gortmaker #include <linux/module.h> 316cbbfe1cSTakashi Iwai #include <linux/io.h> 3212bb5b78SClemens Ladisch 3312bb5b78SClemens Ladisch #include <sound/core.h> 3412bb5b78SClemens Ladisch #include <sound/pcm.h> 3512bb5b78SClemens Ladisch #include <sound/initval.h> 3612bb5b78SClemens Ladisch #include <sound/ac97_codec.h> 3712bb5b78SClemens Ladisch 3812bb5b78SClemens Ladisch #include "ad1889.h" 3912bb5b78SClemens Ladisch #include "ac97/ac97_id.h" 4012bb5b78SClemens Ladisch 41c6f43290SJaroslav Kysela #define AD1889_DRVVER "Version: 1.7" 4212bb5b78SClemens Ladisch 4312bb5b78SClemens Ladisch MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>"); 4412bb5b78SClemens Ladisch MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver"); 4512bb5b78SClemens Ladisch MODULE_LICENSE("GPL"); 4612bb5b78SClemens Ladisch 4712bb5b78SClemens Ladisch static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 4812bb5b78SClemens Ladisch module_param_array(index, int, NULL, 0444); 4912bb5b78SClemens Ladisch MODULE_PARM_DESC(index, "Index value for the AD1889 soundcard."); 5012bb5b78SClemens Ladisch 5112bb5b78SClemens Ladisch static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 5212bb5b78SClemens Ladisch module_param_array(id, charp, NULL, 0444); 5312bb5b78SClemens Ladisch MODULE_PARM_DESC(id, "ID string for the AD1889 soundcard."); 5412bb5b78SClemens Ladisch 55a67ff6a5SRusty Russell static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 5612bb5b78SClemens Ladisch module_param_array(enable, bool, NULL, 0444); 5712bb5b78SClemens Ladisch MODULE_PARM_DESC(enable, "Enable AD1889 soundcard."); 5812bb5b78SClemens Ladisch 5912bb5b78SClemens Ladisch static char *ac97_quirk[SNDRV_CARDS]; 6012bb5b78SClemens Ladisch module_param_array(ac97_quirk, charp, NULL, 0444); 6112bb5b78SClemens Ladisch MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); 6212bb5b78SClemens Ladisch 6312bb5b78SClemens Ladisch #define DEVNAME "ad1889" 6412bb5b78SClemens Ladisch #define PFX DEVNAME ": " 6512bb5b78SClemens Ladisch 6612bb5b78SClemens Ladisch /* keep track of some hw registers */ 6712bb5b78SClemens Ladisch struct ad1889_register_state { 6812bb5b78SClemens Ladisch u16 reg; /* reg setup */ 6912bb5b78SClemens Ladisch u32 addr; /* dma base address */ 7012bb5b78SClemens Ladisch unsigned long size; /* DMA buffer size */ 7112bb5b78SClemens Ladisch }; 7212bb5b78SClemens Ladisch 7312bb5b78SClemens Ladisch struct snd_ad1889 { 7402c2de69STakashi Iwai struct snd_card *card; 7512bb5b78SClemens Ladisch struct pci_dev *pci; 7612bb5b78SClemens Ladisch 7712bb5b78SClemens Ladisch int irq; 7812bb5b78SClemens Ladisch unsigned long bar; 7912bb5b78SClemens Ladisch void __iomem *iobase; 8012bb5b78SClemens Ladisch 8102c2de69STakashi Iwai struct snd_ac97 *ac97; 8202c2de69STakashi Iwai struct snd_ac97_bus *ac97_bus; 8302c2de69STakashi Iwai struct snd_pcm *pcm; 8402c2de69STakashi Iwai struct snd_info_entry *proc; 8512bb5b78SClemens Ladisch 8602c2de69STakashi Iwai struct snd_pcm_substream *psubs; 8702c2de69STakashi Iwai struct snd_pcm_substream *csubs; 8812bb5b78SClemens Ladisch 8912bb5b78SClemens Ladisch /* playback register state */ 9012bb5b78SClemens Ladisch struct ad1889_register_state wave; 9112bb5b78SClemens Ladisch struct ad1889_register_state ramc; 9212bb5b78SClemens Ladisch 9312bb5b78SClemens Ladisch spinlock_t lock; 9412bb5b78SClemens Ladisch }; 9512bb5b78SClemens Ladisch 9612bb5b78SClemens Ladisch static inline u16 9712bb5b78SClemens Ladisch ad1889_readw(struct snd_ad1889 *chip, unsigned reg) 9812bb5b78SClemens Ladisch { 9912bb5b78SClemens Ladisch return readw(chip->iobase + reg); 10012bb5b78SClemens Ladisch } 10112bb5b78SClemens Ladisch 10212bb5b78SClemens Ladisch static inline void 10312bb5b78SClemens Ladisch ad1889_writew(struct snd_ad1889 *chip, unsigned reg, u16 val) 10412bb5b78SClemens Ladisch { 10512bb5b78SClemens Ladisch writew(val, chip->iobase + reg); 10612bb5b78SClemens Ladisch } 10712bb5b78SClemens Ladisch 10812bb5b78SClemens Ladisch static inline u32 10912bb5b78SClemens Ladisch ad1889_readl(struct snd_ad1889 *chip, unsigned reg) 11012bb5b78SClemens Ladisch { 11112bb5b78SClemens Ladisch return readl(chip->iobase + reg); 11212bb5b78SClemens Ladisch } 11312bb5b78SClemens Ladisch 11412bb5b78SClemens Ladisch static inline void 11512bb5b78SClemens Ladisch ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val) 11612bb5b78SClemens Ladisch { 11712bb5b78SClemens Ladisch writel(val, chip->iobase + reg); 11812bb5b78SClemens Ladisch } 11912bb5b78SClemens Ladisch 12012bb5b78SClemens Ladisch static inline void 12112bb5b78SClemens Ladisch ad1889_unmute(struct snd_ad1889 *chip) 12212bb5b78SClemens Ladisch { 12312bb5b78SClemens Ladisch u16 st; 12412bb5b78SClemens Ladisch st = ad1889_readw(chip, AD_DS_WADA) & 12512bb5b78SClemens Ladisch ~(AD_DS_WADA_RWAM | AD_DS_WADA_LWAM); 12612bb5b78SClemens Ladisch ad1889_writew(chip, AD_DS_WADA, st); 12712bb5b78SClemens Ladisch ad1889_readw(chip, AD_DS_WADA); 12812bb5b78SClemens Ladisch } 12912bb5b78SClemens Ladisch 13012bb5b78SClemens Ladisch static inline void 13112bb5b78SClemens Ladisch ad1889_mute(struct snd_ad1889 *chip) 13212bb5b78SClemens Ladisch { 13312bb5b78SClemens Ladisch u16 st; 13412bb5b78SClemens Ladisch st = ad1889_readw(chip, AD_DS_WADA) | AD_DS_WADA_RWAM | AD_DS_WADA_LWAM; 13512bb5b78SClemens Ladisch ad1889_writew(chip, AD_DS_WADA, st); 13612bb5b78SClemens Ladisch ad1889_readw(chip, AD_DS_WADA); 13712bb5b78SClemens Ladisch } 13812bb5b78SClemens Ladisch 13912bb5b78SClemens Ladisch static inline void 14012bb5b78SClemens Ladisch ad1889_load_adc_buffer_address(struct snd_ad1889 *chip, u32 address) 14112bb5b78SClemens Ladisch { 14212bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_ADCBA, address); 14312bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_ADCCA, address); 14412bb5b78SClemens Ladisch } 14512bb5b78SClemens Ladisch 14612bb5b78SClemens Ladisch static inline void 14712bb5b78SClemens Ladisch ad1889_load_adc_buffer_count(struct snd_ad1889 *chip, u32 count) 14812bb5b78SClemens Ladisch { 14912bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_ADCBC, count); 15012bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_ADCCC, count); 15112bb5b78SClemens Ladisch } 15212bb5b78SClemens Ladisch 15312bb5b78SClemens Ladisch static inline void 15412bb5b78SClemens Ladisch ad1889_load_adc_interrupt_count(struct snd_ad1889 *chip, u32 count) 15512bb5b78SClemens Ladisch { 15612bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_ADCIB, count); 15712bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_ADCIC, count); 15812bb5b78SClemens Ladisch } 15912bb5b78SClemens Ladisch 16012bb5b78SClemens Ladisch static inline void 16112bb5b78SClemens Ladisch ad1889_load_wave_buffer_address(struct snd_ad1889 *chip, u32 address) 16212bb5b78SClemens Ladisch { 16312bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_WAVBA, address); 16412bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_WAVCA, address); 16512bb5b78SClemens Ladisch } 16612bb5b78SClemens Ladisch 16712bb5b78SClemens Ladisch static inline void 16812bb5b78SClemens Ladisch ad1889_load_wave_buffer_count(struct snd_ad1889 *chip, u32 count) 16912bb5b78SClemens Ladisch { 17012bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_WAVBC, count); 17112bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_WAVCC, count); 17212bb5b78SClemens Ladisch } 17312bb5b78SClemens Ladisch 17412bb5b78SClemens Ladisch static inline void 17512bb5b78SClemens Ladisch ad1889_load_wave_interrupt_count(struct snd_ad1889 *chip, u32 count) 17612bb5b78SClemens Ladisch { 17712bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_WAVIB, count); 17812bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_WAVIC, count); 17912bb5b78SClemens Ladisch } 18012bb5b78SClemens Ladisch 18112bb5b78SClemens Ladisch static void 18212bb5b78SClemens Ladisch ad1889_channel_reset(struct snd_ad1889 *chip, unsigned int channel) 18312bb5b78SClemens Ladisch { 18412bb5b78SClemens Ladisch u16 reg; 18512bb5b78SClemens Ladisch 18612bb5b78SClemens Ladisch if (channel & AD_CHAN_WAV) { 18712bb5b78SClemens Ladisch /* Disable wave channel */ 18812bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DS_WSMC) & ~AD_DS_WSMC_WAEN; 18912bb5b78SClemens Ladisch ad1889_writew(chip, AD_DS_WSMC, reg); 19012bb5b78SClemens Ladisch chip->wave.reg = reg; 19112bb5b78SClemens Ladisch 19212bb5b78SClemens Ladisch /* disable IRQs */ 19312bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DMA_WAV); 19412bb5b78SClemens Ladisch reg &= AD_DMA_IM_DIS; 19512bb5b78SClemens Ladisch reg &= ~AD_DMA_LOOP; 19612bb5b78SClemens Ladisch ad1889_writew(chip, AD_DMA_WAV, reg); 19712bb5b78SClemens Ladisch 19812bb5b78SClemens Ladisch /* clear IRQ and address counters and pointers */ 19912bb5b78SClemens Ladisch ad1889_load_wave_buffer_address(chip, 0x0); 20012bb5b78SClemens Ladisch ad1889_load_wave_buffer_count(chip, 0x0); 20112bb5b78SClemens Ladisch ad1889_load_wave_interrupt_count(chip, 0x0); 20212bb5b78SClemens Ladisch 20312bb5b78SClemens Ladisch /* flush */ 20412bb5b78SClemens Ladisch ad1889_readw(chip, AD_DMA_WAV); 20512bb5b78SClemens Ladisch } 20612bb5b78SClemens Ladisch 20712bb5b78SClemens Ladisch if (channel & AD_CHAN_ADC) { 20812bb5b78SClemens Ladisch /* Disable ADC channel */ 20912bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DS_RAMC) & ~AD_DS_RAMC_ADEN; 21012bb5b78SClemens Ladisch ad1889_writew(chip, AD_DS_RAMC, reg); 21112bb5b78SClemens Ladisch chip->ramc.reg = reg; 21212bb5b78SClemens Ladisch 21312bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DMA_ADC); 21412bb5b78SClemens Ladisch reg &= AD_DMA_IM_DIS; 21512bb5b78SClemens Ladisch reg &= ~AD_DMA_LOOP; 21612bb5b78SClemens Ladisch ad1889_writew(chip, AD_DMA_ADC, reg); 21712bb5b78SClemens Ladisch 21812bb5b78SClemens Ladisch ad1889_load_adc_buffer_address(chip, 0x0); 21912bb5b78SClemens Ladisch ad1889_load_adc_buffer_count(chip, 0x0); 22012bb5b78SClemens Ladisch ad1889_load_adc_interrupt_count(chip, 0x0); 22112bb5b78SClemens Ladisch 22212bb5b78SClemens Ladisch /* flush */ 22312bb5b78SClemens Ladisch ad1889_readw(chip, AD_DMA_ADC); 22412bb5b78SClemens Ladisch } 22512bb5b78SClemens Ladisch } 22612bb5b78SClemens Ladisch 227f40b6890STakashi Iwai static u16 22802c2de69STakashi Iwai snd_ad1889_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 22912bb5b78SClemens Ladisch { 23012bb5b78SClemens Ladisch struct snd_ad1889 *chip = ac97->private_data; 23112bb5b78SClemens Ladisch return ad1889_readw(chip, AD_AC97_BASE + reg); 23212bb5b78SClemens Ladisch } 23312bb5b78SClemens Ladisch 234f40b6890STakashi Iwai static void 23502c2de69STakashi Iwai snd_ad1889_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 23612bb5b78SClemens Ladisch { 23712bb5b78SClemens Ladisch struct snd_ad1889 *chip = ac97->private_data; 23812bb5b78SClemens Ladisch ad1889_writew(chip, AD_AC97_BASE + reg, val); 23912bb5b78SClemens Ladisch } 24012bb5b78SClemens Ladisch 24112bb5b78SClemens Ladisch static int 24212bb5b78SClemens Ladisch snd_ad1889_ac97_ready(struct snd_ad1889 *chip) 24312bb5b78SClemens Ladisch { 24412bb5b78SClemens Ladisch int retry = 400; /* average needs 352 msec */ 24512bb5b78SClemens Ladisch 24612bb5b78SClemens Ladisch while (!(ad1889_readw(chip, AD_AC97_ACIC) & AD_AC97_ACIC_ACRDY) 24712bb5b78SClemens Ladisch && --retry) 2481fa350b6SJia-Ju Bai usleep_range(1000, 2000); 24912bb5b78SClemens Ladisch if (!retry) { 25029633004STakashi Iwai dev_err(chip->card->dev, "[%s] Link is not ready.\n", 2519bf8e7ddSHarvey Harrison __func__); 25212bb5b78SClemens Ladisch return -EIO; 25312bb5b78SClemens Ladisch } 25429633004STakashi Iwai dev_dbg(chip->card->dev, "[%s] ready after %d ms\n", __func__, 400 - retry); 25512bb5b78SClemens Ladisch 25612bb5b78SClemens Ladisch return 0; 25712bb5b78SClemens Ladisch } 25812bb5b78SClemens Ladisch 259dee49895SBhumika Goyal static const struct snd_pcm_hardware snd_ad1889_playback_hw = { 26012bb5b78SClemens Ladisch .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 26112bb5b78SClemens Ladisch SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, 26212bb5b78SClemens Ladisch .formats = SNDRV_PCM_FMTBIT_S16_LE, 26312bb5b78SClemens Ladisch .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 26412bb5b78SClemens Ladisch .rate_min = 8000, /* docs say 7000, but we're lazy */ 26512bb5b78SClemens Ladisch .rate_max = 48000, 26612bb5b78SClemens Ladisch .channels_min = 1, 26712bb5b78SClemens Ladisch .channels_max = 2, 26812bb5b78SClemens Ladisch .buffer_bytes_max = BUFFER_BYTES_MAX, 26912bb5b78SClemens Ladisch .period_bytes_min = PERIOD_BYTES_MIN, 27012bb5b78SClemens Ladisch .period_bytes_max = PERIOD_BYTES_MAX, 27112bb5b78SClemens Ladisch .periods_min = PERIODS_MIN, 27212bb5b78SClemens Ladisch .periods_max = PERIODS_MAX, 27312bb5b78SClemens Ladisch /*.fifo_size = 0,*/ 27412bb5b78SClemens Ladisch }; 27512bb5b78SClemens Ladisch 276dee49895SBhumika Goyal static const struct snd_pcm_hardware snd_ad1889_capture_hw = { 27712bb5b78SClemens Ladisch .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 27812bb5b78SClemens Ladisch SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, 27912bb5b78SClemens Ladisch .formats = SNDRV_PCM_FMTBIT_S16_LE, 28012bb5b78SClemens Ladisch .rates = SNDRV_PCM_RATE_48000, 28112bb5b78SClemens Ladisch .rate_min = 48000, /* docs say we could to VSR, but we're lazy */ 28212bb5b78SClemens Ladisch .rate_max = 48000, 28312bb5b78SClemens Ladisch .channels_min = 1, 28412bb5b78SClemens Ladisch .channels_max = 2, 28512bb5b78SClemens Ladisch .buffer_bytes_max = BUFFER_BYTES_MAX, 28612bb5b78SClemens Ladisch .period_bytes_min = PERIOD_BYTES_MIN, 28712bb5b78SClemens Ladisch .period_bytes_max = PERIOD_BYTES_MAX, 28812bb5b78SClemens Ladisch .periods_min = PERIODS_MIN, 28912bb5b78SClemens Ladisch .periods_max = PERIODS_MAX, 29012bb5b78SClemens Ladisch /*.fifo_size = 0,*/ 29112bb5b78SClemens Ladisch }; 29212bb5b78SClemens Ladisch 29312bb5b78SClemens Ladisch static int 29402c2de69STakashi Iwai snd_ad1889_playback_open(struct snd_pcm_substream *ss) 29512bb5b78SClemens Ladisch { 29612bb5b78SClemens Ladisch struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); 29702c2de69STakashi Iwai struct snd_pcm_runtime *rt = ss->runtime; 29812bb5b78SClemens Ladisch 29912bb5b78SClemens Ladisch chip->psubs = ss; 30012bb5b78SClemens Ladisch rt->hw = snd_ad1889_playback_hw; 30112bb5b78SClemens Ladisch 30212bb5b78SClemens Ladisch return 0; 30312bb5b78SClemens Ladisch } 30412bb5b78SClemens Ladisch 30512bb5b78SClemens Ladisch static int 30602c2de69STakashi Iwai snd_ad1889_capture_open(struct snd_pcm_substream *ss) 30712bb5b78SClemens Ladisch { 30812bb5b78SClemens Ladisch struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); 30902c2de69STakashi Iwai struct snd_pcm_runtime *rt = ss->runtime; 31012bb5b78SClemens Ladisch 31112bb5b78SClemens Ladisch chip->csubs = ss; 31212bb5b78SClemens Ladisch rt->hw = snd_ad1889_capture_hw; 31312bb5b78SClemens Ladisch 31412bb5b78SClemens Ladisch return 0; 31512bb5b78SClemens Ladisch } 31612bb5b78SClemens Ladisch 31712bb5b78SClemens Ladisch static int 31802c2de69STakashi Iwai snd_ad1889_playback_close(struct snd_pcm_substream *ss) 31912bb5b78SClemens Ladisch { 32012bb5b78SClemens Ladisch struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); 32112bb5b78SClemens Ladisch chip->psubs = NULL; 32212bb5b78SClemens Ladisch return 0; 32312bb5b78SClemens Ladisch } 32412bb5b78SClemens Ladisch 32512bb5b78SClemens Ladisch static int 32602c2de69STakashi Iwai snd_ad1889_capture_close(struct snd_pcm_substream *ss) 32712bb5b78SClemens Ladisch { 32812bb5b78SClemens Ladisch struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); 32912bb5b78SClemens Ladisch chip->csubs = NULL; 33012bb5b78SClemens Ladisch return 0; 33112bb5b78SClemens Ladisch } 33212bb5b78SClemens Ladisch 33312bb5b78SClemens Ladisch static int 33402c2de69STakashi Iwai snd_ad1889_playback_prepare(struct snd_pcm_substream *ss) 33512bb5b78SClemens Ladisch { 33612bb5b78SClemens Ladisch struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); 33702c2de69STakashi Iwai struct snd_pcm_runtime *rt = ss->runtime; 33812bb5b78SClemens Ladisch unsigned int size = snd_pcm_lib_buffer_bytes(ss); 33912bb5b78SClemens Ladisch unsigned int count = snd_pcm_lib_period_bytes(ss); 34012bb5b78SClemens Ladisch u16 reg; 34112bb5b78SClemens Ladisch 34212bb5b78SClemens Ladisch ad1889_channel_reset(chip, AD_CHAN_WAV); 34312bb5b78SClemens Ladisch 34412bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DS_WSMC); 34512bb5b78SClemens Ladisch 34612bb5b78SClemens Ladisch /* Mask out 16-bit / Stereo */ 34712bb5b78SClemens Ladisch reg &= ~(AD_DS_WSMC_WA16 | AD_DS_WSMC_WAST); 34812bb5b78SClemens Ladisch 34912bb5b78SClemens Ladisch if (snd_pcm_format_width(rt->format) == 16) 35012bb5b78SClemens Ladisch reg |= AD_DS_WSMC_WA16; 35112bb5b78SClemens Ladisch 35212bb5b78SClemens Ladisch if (rt->channels > 1) 35312bb5b78SClemens Ladisch reg |= AD_DS_WSMC_WAST; 35412bb5b78SClemens Ladisch 35512bb5b78SClemens Ladisch /* let's make sure we don't clobber ourselves */ 35612bb5b78SClemens Ladisch spin_lock_irq(&chip->lock); 35712bb5b78SClemens Ladisch 35812bb5b78SClemens Ladisch chip->wave.size = size; 35912bb5b78SClemens Ladisch chip->wave.reg = reg; 36012bb5b78SClemens Ladisch chip->wave.addr = rt->dma_addr; 36112bb5b78SClemens Ladisch 36212bb5b78SClemens Ladisch ad1889_writew(chip, AD_DS_WSMC, chip->wave.reg); 36312bb5b78SClemens Ladisch 36412bb5b78SClemens Ladisch /* Set sample rates on the codec */ 36512bb5b78SClemens Ladisch ad1889_writew(chip, AD_DS_WAS, rt->rate); 36612bb5b78SClemens Ladisch 36712bb5b78SClemens Ladisch /* Set up DMA */ 36812bb5b78SClemens Ladisch ad1889_load_wave_buffer_address(chip, chip->wave.addr); 36912bb5b78SClemens Ladisch ad1889_load_wave_buffer_count(chip, size); 37012bb5b78SClemens Ladisch ad1889_load_wave_interrupt_count(chip, count); 37112bb5b78SClemens Ladisch 37212bb5b78SClemens Ladisch /* writes flush */ 37312bb5b78SClemens Ladisch ad1889_readw(chip, AD_DS_WSMC); 37412bb5b78SClemens Ladisch 37512bb5b78SClemens Ladisch spin_unlock_irq(&chip->lock); 37612bb5b78SClemens Ladisch 37729633004STakashi Iwai dev_dbg(chip->card->dev, 37829633004STakashi Iwai "prepare playback: addr = 0x%x, count = %u, size = %u, reg = 0x%x, rate = %u\n", 37929633004STakashi Iwai chip->wave.addr, count, size, reg, rt->rate); 38012bb5b78SClemens Ladisch return 0; 38112bb5b78SClemens Ladisch } 38212bb5b78SClemens Ladisch 38312bb5b78SClemens Ladisch static int 38402c2de69STakashi Iwai snd_ad1889_capture_prepare(struct snd_pcm_substream *ss) 38512bb5b78SClemens Ladisch { 38612bb5b78SClemens Ladisch struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); 38702c2de69STakashi Iwai struct snd_pcm_runtime *rt = ss->runtime; 38812bb5b78SClemens Ladisch unsigned int size = snd_pcm_lib_buffer_bytes(ss); 38912bb5b78SClemens Ladisch unsigned int count = snd_pcm_lib_period_bytes(ss); 39012bb5b78SClemens Ladisch u16 reg; 39112bb5b78SClemens Ladisch 39212bb5b78SClemens Ladisch ad1889_channel_reset(chip, AD_CHAN_ADC); 39312bb5b78SClemens Ladisch 39412bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DS_RAMC); 39512bb5b78SClemens Ladisch 39612bb5b78SClemens Ladisch /* Mask out 16-bit / Stereo */ 39712bb5b78SClemens Ladisch reg &= ~(AD_DS_RAMC_AD16 | AD_DS_RAMC_ADST); 39812bb5b78SClemens Ladisch 39912bb5b78SClemens Ladisch if (snd_pcm_format_width(rt->format) == 16) 40012bb5b78SClemens Ladisch reg |= AD_DS_RAMC_AD16; 40112bb5b78SClemens Ladisch 40212bb5b78SClemens Ladisch if (rt->channels > 1) 40312bb5b78SClemens Ladisch reg |= AD_DS_RAMC_ADST; 40412bb5b78SClemens Ladisch 40512bb5b78SClemens Ladisch /* let's make sure we don't clobber ourselves */ 40612bb5b78SClemens Ladisch spin_lock_irq(&chip->lock); 40712bb5b78SClemens Ladisch 40812bb5b78SClemens Ladisch chip->ramc.size = size; 40912bb5b78SClemens Ladisch chip->ramc.reg = reg; 41012bb5b78SClemens Ladisch chip->ramc.addr = rt->dma_addr; 41112bb5b78SClemens Ladisch 41212bb5b78SClemens Ladisch ad1889_writew(chip, AD_DS_RAMC, chip->ramc.reg); 41312bb5b78SClemens Ladisch 41412bb5b78SClemens Ladisch /* Set up DMA */ 41512bb5b78SClemens Ladisch ad1889_load_adc_buffer_address(chip, chip->ramc.addr); 41612bb5b78SClemens Ladisch ad1889_load_adc_buffer_count(chip, size); 41712bb5b78SClemens Ladisch ad1889_load_adc_interrupt_count(chip, count); 41812bb5b78SClemens Ladisch 41912bb5b78SClemens Ladisch /* writes flush */ 42012bb5b78SClemens Ladisch ad1889_readw(chip, AD_DS_RAMC); 42112bb5b78SClemens Ladisch 42212bb5b78SClemens Ladisch spin_unlock_irq(&chip->lock); 42312bb5b78SClemens Ladisch 42429633004STakashi Iwai dev_dbg(chip->card->dev, 42529633004STakashi Iwai "prepare capture: addr = 0x%x, count = %u, size = %u, reg = 0x%x, rate = %u\n", 42629633004STakashi Iwai chip->ramc.addr, count, size, reg, rt->rate); 42712bb5b78SClemens Ladisch return 0; 42812bb5b78SClemens Ladisch } 42912bb5b78SClemens Ladisch 43012bb5b78SClemens Ladisch /* this is called in atomic context with IRQ disabled. 43112bb5b78SClemens Ladisch Must be as fast as possible and not sleep. 43212bb5b78SClemens Ladisch DMA should be *triggered* by this call. 43312bb5b78SClemens Ladisch The WSMC "WAEN" bit triggers DMA Wave On/Off */ 43412bb5b78SClemens Ladisch static int 43502c2de69STakashi Iwai snd_ad1889_playback_trigger(struct snd_pcm_substream *ss, int cmd) 43612bb5b78SClemens Ladisch { 43712bb5b78SClemens Ladisch u16 wsmc; 43812bb5b78SClemens Ladisch struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); 43912bb5b78SClemens Ladisch 44012bb5b78SClemens Ladisch wsmc = ad1889_readw(chip, AD_DS_WSMC); 44112bb5b78SClemens Ladisch 44212bb5b78SClemens Ladisch switch (cmd) { 44312bb5b78SClemens Ladisch case SNDRV_PCM_TRIGGER_START: 44412bb5b78SClemens Ladisch /* enable DMA loop & interrupts */ 44512bb5b78SClemens Ladisch ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT); 44612bb5b78SClemens Ladisch wsmc |= AD_DS_WSMC_WAEN; 44712bb5b78SClemens Ladisch /* 1 to clear CHSS bit */ 44812bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS); 44912bb5b78SClemens Ladisch ad1889_unmute(chip); 45012bb5b78SClemens Ladisch break; 45112bb5b78SClemens Ladisch case SNDRV_PCM_TRIGGER_STOP: 45212bb5b78SClemens Ladisch ad1889_mute(chip); 45312bb5b78SClemens Ladisch wsmc &= ~AD_DS_WSMC_WAEN; 45412bb5b78SClemens Ladisch break; 45512bb5b78SClemens Ladisch default: 45612bb5b78SClemens Ladisch snd_BUG(); 45712bb5b78SClemens Ladisch return -EINVAL; 45812bb5b78SClemens Ladisch } 45912bb5b78SClemens Ladisch 46012bb5b78SClemens Ladisch chip->wave.reg = wsmc; 46112bb5b78SClemens Ladisch ad1889_writew(chip, AD_DS_WSMC, wsmc); 46212bb5b78SClemens Ladisch ad1889_readw(chip, AD_DS_WSMC); /* flush */ 46312bb5b78SClemens Ladisch 46412bb5b78SClemens Ladisch /* reset the chip when STOP - will disable IRQs */ 46512bb5b78SClemens Ladisch if (cmd == SNDRV_PCM_TRIGGER_STOP) 46612bb5b78SClemens Ladisch ad1889_channel_reset(chip, AD_CHAN_WAV); 46712bb5b78SClemens Ladisch 46812bb5b78SClemens Ladisch return 0; 46912bb5b78SClemens Ladisch } 47012bb5b78SClemens Ladisch 47112bb5b78SClemens Ladisch /* this is called in atomic context with IRQ disabled. 47212bb5b78SClemens Ladisch Must be as fast as possible and not sleep. 47312bb5b78SClemens Ladisch DMA should be *triggered* by this call. 47412bb5b78SClemens Ladisch The RAMC "ADEN" bit triggers DMA ADC On/Off */ 47512bb5b78SClemens Ladisch static int 47602c2de69STakashi Iwai snd_ad1889_capture_trigger(struct snd_pcm_substream *ss, int cmd) 47712bb5b78SClemens Ladisch { 47812bb5b78SClemens Ladisch u16 ramc; 47912bb5b78SClemens Ladisch struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); 48012bb5b78SClemens Ladisch 48112bb5b78SClemens Ladisch ramc = ad1889_readw(chip, AD_DS_RAMC); 48212bb5b78SClemens Ladisch 48312bb5b78SClemens Ladisch switch (cmd) { 48412bb5b78SClemens Ladisch case SNDRV_PCM_TRIGGER_START: 48512bb5b78SClemens Ladisch /* enable DMA loop & interrupts */ 48612bb5b78SClemens Ladisch ad1889_writew(chip, AD_DMA_ADC, AD_DMA_LOOP | AD_DMA_IM_CNT); 48712bb5b78SClemens Ladisch ramc |= AD_DS_RAMC_ADEN; 48812bb5b78SClemens Ladisch /* 1 to clear CHSS bit */ 48912bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_ADCS); 49012bb5b78SClemens Ladisch break; 49112bb5b78SClemens Ladisch case SNDRV_PCM_TRIGGER_STOP: 49212bb5b78SClemens Ladisch ramc &= ~AD_DS_RAMC_ADEN; 49312bb5b78SClemens Ladisch break; 49412bb5b78SClemens Ladisch default: 49512bb5b78SClemens Ladisch return -EINVAL; 49612bb5b78SClemens Ladisch } 49712bb5b78SClemens Ladisch 49812bb5b78SClemens Ladisch chip->ramc.reg = ramc; 49912bb5b78SClemens Ladisch ad1889_writew(chip, AD_DS_RAMC, ramc); 50012bb5b78SClemens Ladisch ad1889_readw(chip, AD_DS_RAMC); /* flush */ 50112bb5b78SClemens Ladisch 50212bb5b78SClemens Ladisch /* reset the chip when STOP - will disable IRQs */ 50312bb5b78SClemens Ladisch if (cmd == SNDRV_PCM_TRIGGER_STOP) 50412bb5b78SClemens Ladisch ad1889_channel_reset(chip, AD_CHAN_ADC); 50512bb5b78SClemens Ladisch 50612bb5b78SClemens Ladisch return 0; 50712bb5b78SClemens Ladisch } 50812bb5b78SClemens Ladisch 50912bb5b78SClemens Ladisch /* Called in atomic context with IRQ disabled */ 51012bb5b78SClemens Ladisch static snd_pcm_uframes_t 51102c2de69STakashi Iwai snd_ad1889_playback_pointer(struct snd_pcm_substream *ss) 51212bb5b78SClemens Ladisch { 51312bb5b78SClemens Ladisch size_t ptr = 0; 51412bb5b78SClemens Ladisch struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); 51512bb5b78SClemens Ladisch 51612bb5b78SClemens Ladisch if (unlikely(!(chip->wave.reg & AD_DS_WSMC_WAEN))) 51712bb5b78SClemens Ladisch return 0; 51812bb5b78SClemens Ladisch 51912bb5b78SClemens Ladisch ptr = ad1889_readl(chip, AD_DMA_WAVCA); 52012bb5b78SClemens Ladisch ptr -= chip->wave.addr; 52112bb5b78SClemens Ladisch 522da3cec35STakashi Iwai if (snd_BUG_ON(ptr >= chip->wave.size)) 523da3cec35STakashi Iwai return 0; 52412bb5b78SClemens Ladisch 52512bb5b78SClemens Ladisch return bytes_to_frames(ss->runtime, ptr); 52612bb5b78SClemens Ladisch } 52712bb5b78SClemens Ladisch 52812bb5b78SClemens Ladisch /* Called in atomic context with IRQ disabled */ 52912bb5b78SClemens Ladisch static snd_pcm_uframes_t 53002c2de69STakashi Iwai snd_ad1889_capture_pointer(struct snd_pcm_substream *ss) 53112bb5b78SClemens Ladisch { 53212bb5b78SClemens Ladisch size_t ptr = 0; 53312bb5b78SClemens Ladisch struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); 53412bb5b78SClemens Ladisch 53512bb5b78SClemens Ladisch if (unlikely(!(chip->ramc.reg & AD_DS_RAMC_ADEN))) 53612bb5b78SClemens Ladisch return 0; 53712bb5b78SClemens Ladisch 53812bb5b78SClemens Ladisch ptr = ad1889_readl(chip, AD_DMA_ADCCA); 53912bb5b78SClemens Ladisch ptr -= chip->ramc.addr; 54012bb5b78SClemens Ladisch 541da3cec35STakashi Iwai if (snd_BUG_ON(ptr >= chip->ramc.size)) 542da3cec35STakashi Iwai return 0; 54312bb5b78SClemens Ladisch 54412bb5b78SClemens Ladisch return bytes_to_frames(ss->runtime, ptr); 54512bb5b78SClemens Ladisch } 54612bb5b78SClemens Ladisch 547d602efcaSJulia Lawall static const struct snd_pcm_ops snd_ad1889_playback_ops = { 54812bb5b78SClemens Ladisch .open = snd_ad1889_playback_open, 54912bb5b78SClemens Ladisch .close = snd_ad1889_playback_close, 55012bb5b78SClemens Ladisch .prepare = snd_ad1889_playback_prepare, 55112bb5b78SClemens Ladisch .trigger = snd_ad1889_playback_trigger, 55212bb5b78SClemens Ladisch .pointer = snd_ad1889_playback_pointer, 55312bb5b78SClemens Ladisch }; 55412bb5b78SClemens Ladisch 555d602efcaSJulia Lawall static const struct snd_pcm_ops snd_ad1889_capture_ops = { 55612bb5b78SClemens Ladisch .open = snd_ad1889_capture_open, 55712bb5b78SClemens Ladisch .close = snd_ad1889_capture_close, 55812bb5b78SClemens Ladisch .prepare = snd_ad1889_capture_prepare, 55912bb5b78SClemens Ladisch .trigger = snd_ad1889_capture_trigger, 56012bb5b78SClemens Ladisch .pointer = snd_ad1889_capture_pointer, 56112bb5b78SClemens Ladisch }; 56212bb5b78SClemens Ladisch 56312bb5b78SClemens Ladisch static irqreturn_t 5647d12e780SDavid Howells snd_ad1889_interrupt(int irq, void *dev_id) 56512bb5b78SClemens Ladisch { 56612bb5b78SClemens Ladisch unsigned long st; 56712bb5b78SClemens Ladisch struct snd_ad1889 *chip = dev_id; 56812bb5b78SClemens Ladisch 56912bb5b78SClemens Ladisch st = ad1889_readl(chip, AD_DMA_DISR); 57012bb5b78SClemens Ladisch 57112bb5b78SClemens Ladisch /* clear ISR */ 57212bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_DISR, st); 57312bb5b78SClemens Ladisch 57412bb5b78SClemens Ladisch st &= AD_INTR_MASK; 57512bb5b78SClemens Ladisch 57612bb5b78SClemens Ladisch if (unlikely(!st)) 57712bb5b78SClemens Ladisch return IRQ_NONE; 57812bb5b78SClemens Ladisch 57912bb5b78SClemens Ladisch if (st & (AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI)) 58029633004STakashi Iwai dev_dbg(chip->card->dev, 58129633004STakashi Iwai "Unexpected master or target abort interrupt!\n"); 58212bb5b78SClemens Ladisch 58312bb5b78SClemens Ladisch if ((st & AD_DMA_DISR_WAVI) && chip->psubs) 58412bb5b78SClemens Ladisch snd_pcm_period_elapsed(chip->psubs); 58512bb5b78SClemens Ladisch if ((st & AD_DMA_DISR_ADCI) && chip->csubs) 58612bb5b78SClemens Ladisch snd_pcm_period_elapsed(chip->csubs); 58712bb5b78SClemens Ladisch 58812bb5b78SClemens Ladisch return IRQ_HANDLED; 58912bb5b78SClemens Ladisch } 59012bb5b78SClemens Ladisch 5912f5c1302SBill Pemberton static int 592a0880094SLars-Peter Clausen snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device) 59312bb5b78SClemens Ladisch { 59412bb5b78SClemens Ladisch int err; 59502c2de69STakashi Iwai struct snd_pcm *pcm; 59612bb5b78SClemens Ladisch 59712bb5b78SClemens Ladisch err = snd_pcm_new(chip->card, chip->card->driver, device, 1, 1, &pcm); 59812bb5b78SClemens Ladisch if (err < 0) 59912bb5b78SClemens Ladisch return err; 60012bb5b78SClemens Ladisch 60112bb5b78SClemens Ladisch snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 60212bb5b78SClemens Ladisch &snd_ad1889_playback_ops); 60312bb5b78SClemens Ladisch snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 60412bb5b78SClemens Ladisch &snd_ad1889_capture_ops); 60512bb5b78SClemens Ladisch 60612bb5b78SClemens Ladisch pcm->private_data = chip; 60712bb5b78SClemens Ladisch pcm->info_flags = 0; 60812bb5b78SClemens Ladisch strcpy(pcm->name, chip->card->shortname); 60912bb5b78SClemens Ladisch 61012bb5b78SClemens Ladisch chip->pcm = pcm; 61112bb5b78SClemens Ladisch chip->psubs = NULL; 61212bb5b78SClemens Ladisch chip->csubs = NULL; 61312bb5b78SClemens Ladisch 61493d6487fSTakashi Iwai snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &chip->pci->dev, 61593d6487fSTakashi Iwai BUFFER_BYTES_MAX / 2, BUFFER_BYTES_MAX); 61612bb5b78SClemens Ladisch 61712bb5b78SClemens Ladisch return 0; 61812bb5b78SClemens Ladisch } 61912bb5b78SClemens Ladisch 62012bb5b78SClemens Ladisch static void 62102c2de69STakashi Iwai snd_ad1889_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 62212bb5b78SClemens Ladisch { 62312bb5b78SClemens Ladisch struct snd_ad1889 *chip = entry->private_data; 62412bb5b78SClemens Ladisch u16 reg; 62512bb5b78SClemens Ladisch int tmp; 62612bb5b78SClemens Ladisch 62712bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DS_WSMC); 62812bb5b78SClemens Ladisch snd_iprintf(buffer, "Wave output: %s\n", 62912bb5b78SClemens Ladisch (reg & AD_DS_WSMC_WAEN) ? "enabled" : "disabled"); 63012bb5b78SClemens Ladisch snd_iprintf(buffer, "Wave Channels: %s\n", 63112bb5b78SClemens Ladisch (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); 63212bb5b78SClemens Ladisch snd_iprintf(buffer, "Wave Quality: %d-bit linear\n", 63312bb5b78SClemens Ladisch (reg & AD_DS_WSMC_WA16) ? 16 : 8); 63412bb5b78SClemens Ladisch 63512bb5b78SClemens Ladisch /* WARQ is at offset 12 */ 63612bb5b78SClemens Ladisch tmp = (reg & AD_DS_WSMC_WARQ) ? 637ccbec5eaSJoe Perches ((((reg & AD_DS_WSMC_WARQ) >> 12) & 0x01) ? 12 : 18) : 4; 63812bb5b78SClemens Ladisch tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1; 63912bb5b78SClemens Ladisch 64012bb5b78SClemens Ladisch snd_iprintf(buffer, "Wave FIFO: %d %s words\n\n", tmp, 64112bb5b78SClemens Ladisch (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); 64212bb5b78SClemens Ladisch 64312bb5b78SClemens Ladisch 64412bb5b78SClemens Ladisch snd_iprintf(buffer, "Synthesis output: %s\n", 64512bb5b78SClemens Ladisch reg & AD_DS_WSMC_SYEN ? "enabled" : "disabled"); 64612bb5b78SClemens Ladisch 64712bb5b78SClemens Ladisch /* SYRQ is at offset 4 */ 64812bb5b78SClemens Ladisch tmp = (reg & AD_DS_WSMC_SYRQ) ? 649ccbec5eaSJoe Perches ((((reg & AD_DS_WSMC_SYRQ) >> 4) & 0x01) ? 12 : 18) : 4; 65012bb5b78SClemens Ladisch tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1; 65112bb5b78SClemens Ladisch 65212bb5b78SClemens Ladisch snd_iprintf(buffer, "Synthesis FIFO: %d %s words\n\n", tmp, 65312bb5b78SClemens Ladisch (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); 65412bb5b78SClemens Ladisch 65512bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DS_RAMC); 65612bb5b78SClemens Ladisch snd_iprintf(buffer, "ADC input: %s\n", 65712bb5b78SClemens Ladisch (reg & AD_DS_RAMC_ADEN) ? "enabled" : "disabled"); 65812bb5b78SClemens Ladisch snd_iprintf(buffer, "ADC Channels: %s\n", 65912bb5b78SClemens Ladisch (reg & AD_DS_RAMC_ADST) ? "stereo" : "mono"); 66012bb5b78SClemens Ladisch snd_iprintf(buffer, "ADC Quality: %d-bit linear\n", 66112bb5b78SClemens Ladisch (reg & AD_DS_RAMC_AD16) ? 16 : 8); 66212bb5b78SClemens Ladisch 66312bb5b78SClemens Ladisch /* ACRQ is at offset 4 */ 66412bb5b78SClemens Ladisch tmp = (reg & AD_DS_RAMC_ACRQ) ? 665ccbec5eaSJoe Perches ((((reg & AD_DS_RAMC_ACRQ) >> 4) & 0x01) ? 12 : 18) : 4; 66612bb5b78SClemens Ladisch tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1; 66712bb5b78SClemens Ladisch 66812bb5b78SClemens Ladisch snd_iprintf(buffer, "ADC FIFO: %d %s words\n\n", tmp, 66912bb5b78SClemens Ladisch (reg & AD_DS_RAMC_ADST) ? "stereo" : "mono"); 67012bb5b78SClemens Ladisch 67112bb5b78SClemens Ladisch snd_iprintf(buffer, "Resampler input: %s\n", 67212bb5b78SClemens Ladisch reg & AD_DS_RAMC_REEN ? "enabled" : "disabled"); 67312bb5b78SClemens Ladisch 67412bb5b78SClemens Ladisch /* RERQ is at offset 12 */ 67512bb5b78SClemens Ladisch tmp = (reg & AD_DS_RAMC_RERQ) ? 676ccbec5eaSJoe Perches ((((reg & AD_DS_RAMC_RERQ) >> 12) & 0x01) ? 12 : 18) : 4; 67712bb5b78SClemens Ladisch tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1; 67812bb5b78SClemens Ladisch 67912bb5b78SClemens Ladisch snd_iprintf(buffer, "Resampler FIFO: %d %s words\n\n", tmp, 68012bb5b78SClemens Ladisch (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); 68112bb5b78SClemens Ladisch 68212bb5b78SClemens Ladisch 68312bb5b78SClemens Ladisch /* doc says LSB represents -1.5dB, but the max value (-94.5dB) 68412bb5b78SClemens Ladisch suggests that LSB is -3dB, which is more coherent with the logarithmic 68512bb5b78SClemens Ladisch nature of the dB scale */ 68612bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DS_WADA); 68712bb5b78SClemens Ladisch snd_iprintf(buffer, "Left: %s, -%d dB\n", 68812bb5b78SClemens Ladisch (reg & AD_DS_WADA_LWAM) ? "mute" : "unmute", 68912bb5b78SClemens Ladisch ((reg & AD_DS_WADA_LWAA) >> 8) * 3); 69012bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DS_WADA); 69112bb5b78SClemens Ladisch snd_iprintf(buffer, "Right: %s, -%d dB\n", 69212bb5b78SClemens Ladisch (reg & AD_DS_WADA_RWAM) ? "mute" : "unmute", 6939bd0f5c0STakashi Iwai (reg & AD_DS_WADA_RWAA) * 3); 69412bb5b78SClemens Ladisch 69512bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DS_WAS); 69612bb5b78SClemens Ladisch snd_iprintf(buffer, "Wave samplerate: %u Hz\n", reg); 69712bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_DS_RES); 69812bb5b78SClemens Ladisch snd_iprintf(buffer, "Resampler samplerate: %u Hz\n", reg); 69912bb5b78SClemens Ladisch } 70012bb5b78SClemens Ladisch 7012f5c1302SBill Pemberton static void 70212bb5b78SClemens Ladisch snd_ad1889_proc_init(struct snd_ad1889 *chip) 70312bb5b78SClemens Ladisch { 70447f2769bSTakashi Iwai snd_card_ro_proc_new(chip->card, chip->card->driver, 70547f2769bSTakashi Iwai chip, snd_ad1889_proc_read); 70612bb5b78SClemens Ladisch } 70712bb5b78SClemens Ladisch 708eab0fbfaSJoe Perches static const struct ac97_quirk ac97_quirks[] = { 70912bb5b78SClemens Ladisch { 71012bb5b78SClemens Ladisch .subvendor = 0x11d4, /* AD */ 71112bb5b78SClemens Ladisch .subdevice = 0x1889, /* AD1889 */ 71212bb5b78SClemens Ladisch .codec_id = AC97_ID_AD1819, 71312bb5b78SClemens Ladisch .name = "AD1889", 71412bb5b78SClemens Ladisch .type = AC97_TUNE_HP_ONLY 71512bb5b78SClemens Ladisch }, 71612bb5b78SClemens Ladisch { } /* terminator */ 71712bb5b78SClemens Ladisch }; 71812bb5b78SClemens Ladisch 7192f5c1302SBill Pemberton static void 72012bb5b78SClemens Ladisch snd_ad1889_ac97_xinit(struct snd_ad1889 *chip) 72112bb5b78SClemens Ladisch { 72212bb5b78SClemens Ladisch u16 reg; 72312bb5b78SClemens Ladisch 72412bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_AC97_ACIC); 72512bb5b78SClemens Ladisch reg |= AD_AC97_ACIC_ACRD; /* Reset Disable */ 72612bb5b78SClemens Ladisch ad1889_writew(chip, AD_AC97_ACIC, reg); 72712bb5b78SClemens Ladisch ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */ 72812bb5b78SClemens Ladisch udelay(10); 72912bb5b78SClemens Ladisch /* Interface Enable */ 73012bb5b78SClemens Ladisch reg |= AD_AC97_ACIC_ACIE; 73112bb5b78SClemens Ladisch ad1889_writew(chip, AD_AC97_ACIC, reg); 73212bb5b78SClemens Ladisch 73312bb5b78SClemens Ladisch snd_ad1889_ac97_ready(chip); 73412bb5b78SClemens Ladisch 73512bb5b78SClemens Ladisch /* Audio Stream Output | Variable Sample Rate Mode */ 73612bb5b78SClemens Ladisch reg = ad1889_readw(chip, AD_AC97_ACIC); 73712bb5b78SClemens Ladisch reg |= AD_AC97_ACIC_ASOE | AD_AC97_ACIC_VSRM; 73812bb5b78SClemens Ladisch ad1889_writew(chip, AD_AC97_ACIC, reg); 73912bb5b78SClemens Ladisch ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */ 74012bb5b78SClemens Ladisch 74112bb5b78SClemens Ladisch } 74212bb5b78SClemens Ladisch 7432f5c1302SBill Pemberton static int 74412bb5b78SClemens Ladisch snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override) 74512bb5b78SClemens Ladisch { 74612bb5b78SClemens Ladisch int err; 74702c2de69STakashi Iwai struct snd_ac97_template ac97; 74851055da5STakashi Iwai static const struct snd_ac97_bus_ops ops = { 74912bb5b78SClemens Ladisch .write = snd_ad1889_ac97_write, 75012bb5b78SClemens Ladisch .read = snd_ad1889_ac97_read, 75112bb5b78SClemens Ladisch }; 75212bb5b78SClemens Ladisch 75312bb5b78SClemens Ladisch /* doing that here, it works. */ 75412bb5b78SClemens Ladisch snd_ad1889_ac97_xinit(chip); 75512bb5b78SClemens Ladisch 75612bb5b78SClemens Ladisch err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus); 75712bb5b78SClemens Ladisch if (err < 0) 75812bb5b78SClemens Ladisch return err; 75912bb5b78SClemens Ladisch 76012bb5b78SClemens Ladisch memset(&ac97, 0, sizeof(ac97)); 76112bb5b78SClemens Ladisch ac97.private_data = chip; 76212bb5b78SClemens Ladisch ac97.pci = chip->pci; 76312bb5b78SClemens Ladisch 76412bb5b78SClemens Ladisch err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97); 76512bb5b78SClemens Ladisch if (err < 0) 76612bb5b78SClemens Ladisch return err; 76712bb5b78SClemens Ladisch 76812bb5b78SClemens Ladisch snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override); 76912bb5b78SClemens Ladisch 77012bb5b78SClemens Ladisch return 0; 77112bb5b78SClemens Ladisch } 77212bb5b78SClemens Ladisch 773*567f5875STakashi Iwai static void 774*567f5875STakashi Iwai snd_ad1889_free(struct snd_card *card) 77512bb5b78SClemens Ladisch { 776*567f5875STakashi Iwai struct snd_ad1889 *chip = card->private_data; 77712bb5b78SClemens Ladisch 77812bb5b78SClemens Ladisch spin_lock_irq(&chip->lock); 77912bb5b78SClemens Ladisch 78012bb5b78SClemens Ladisch ad1889_mute(chip); 78112bb5b78SClemens Ladisch 78212bb5b78SClemens Ladisch /* Turn off interrupt on count and zero DMA registers */ 78312bb5b78SClemens Ladisch ad1889_channel_reset(chip, AD_CHAN_WAV | AD_CHAN_ADC); 78412bb5b78SClemens Ladisch 78512bb5b78SClemens Ladisch /* clear DISR. If we don't, we'd better jump off the Eiffel Tower */ 78612bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PTAI | AD_DMA_DISR_PMAI); 78712bb5b78SClemens Ladisch ad1889_readl(chip, AD_DMA_DISR); /* flush, dammit! */ 78812bb5b78SClemens Ladisch 78912bb5b78SClemens Ladisch spin_unlock_irq(&chip->lock); 79012bb5b78SClemens Ladisch } 79112bb5b78SClemens Ladisch 792f40b6890STakashi Iwai static int 793*567f5875STakashi Iwai snd_ad1889_create(struct snd_card *card, struct pci_dev *pci) 79412bb5b78SClemens Ladisch { 795*567f5875STakashi Iwai struct snd_ad1889 *chip = card->private_data; 796*567f5875STakashi Iwai int err; 797*567f5875STakashi Iwai 798*567f5875STakashi Iwai err = pcim_enable_device(pci); 799*567f5875STakashi Iwai if (err < 0) 800*567f5875STakashi Iwai return err; 801*567f5875STakashi Iwai 802*567f5875STakashi Iwai /* check PCI availability (32bit DMA) */ 803*567f5875STakashi Iwai if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { 804*567f5875STakashi Iwai dev_err(card->dev, "error setting 32-bit DMA mask.\n"); 805*567f5875STakashi Iwai return -ENXIO; 80612bb5b78SClemens Ladisch } 80712bb5b78SClemens Ladisch 808*567f5875STakashi Iwai chip->card = card; 809*567f5875STakashi Iwai chip->pci = pci; 810*567f5875STakashi Iwai chip->irq = -1; 811*567f5875STakashi Iwai 812*567f5875STakashi Iwai /* (1) PCI resource allocation */ 813*567f5875STakashi Iwai err = pcim_iomap_regions(pci, 1 << 0, card->driver); 814*567f5875STakashi Iwai if (err < 0) 815*567f5875STakashi Iwai return err; 816*567f5875STakashi Iwai 817*567f5875STakashi Iwai chip->bar = pci_resource_start(pci, 0); 818*567f5875STakashi Iwai chip->iobase = pcim_iomap_table(pci)[0]; 819*567f5875STakashi Iwai 820*567f5875STakashi Iwai pci_set_master(pci); 821*567f5875STakashi Iwai 822*567f5875STakashi Iwai spin_lock_init(&chip->lock); /* only now can we call ad1889_free */ 823*567f5875STakashi Iwai 824*567f5875STakashi Iwai if (devm_request_irq(&pci->dev, pci->irq, snd_ad1889_interrupt, 825*567f5875STakashi Iwai IRQF_SHARED, KBUILD_MODNAME, chip)) { 826*567f5875STakashi Iwai dev_err(card->dev, "cannot obtain IRQ %d\n", pci->irq); 827*567f5875STakashi Iwai return -EBUSY; 828*567f5875STakashi Iwai } 829*567f5875STakashi Iwai 830*567f5875STakashi Iwai chip->irq = pci->irq; 831*567f5875STakashi Iwai card->sync_irq = chip->irq; 832*567f5875STakashi Iwai card->private_free = snd_ad1889_free; 833*567f5875STakashi Iwai 834*567f5875STakashi Iwai /* (2) initialization of the chip hardware */ 83512bb5b78SClemens Ladisch ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */ 83612bb5b78SClemens Ladisch ad1889_readw(chip, AD_DS_CCS); /* flush posted write */ 83712bb5b78SClemens Ladisch 838621fdf60SJia-Ju Bai usleep_range(10000, 11000); 83912bb5b78SClemens Ladisch 84012bb5b78SClemens Ladisch /* enable Master and Target abort interrupts */ 84112bb5b78SClemens Ladisch ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PMAE | AD_DMA_DISR_PTAE); 84212bb5b78SClemens Ladisch 84312bb5b78SClemens Ladisch return 0; 84412bb5b78SClemens Ladisch } 84512bb5b78SClemens Ladisch 8462f5c1302SBill Pemberton static int 84712bb5b78SClemens Ladisch snd_ad1889_probe(struct pci_dev *pci, 84812bb5b78SClemens Ladisch const struct pci_device_id *pci_id) 84912bb5b78SClemens Ladisch { 85012bb5b78SClemens Ladisch int err; 85112bb5b78SClemens Ladisch static int devno; 85202c2de69STakashi Iwai struct snd_card *card; 85312bb5b78SClemens Ladisch struct snd_ad1889 *chip; 85412bb5b78SClemens Ladisch 85512bb5b78SClemens Ladisch /* (1) */ 85612bb5b78SClemens Ladisch if (devno >= SNDRV_CARDS) 85712bb5b78SClemens Ladisch return -ENODEV; 85812bb5b78SClemens Ladisch if (!enable[devno]) { 85912bb5b78SClemens Ladisch devno++; 86012bb5b78SClemens Ladisch return -ENOENT; 86112bb5b78SClemens Ladisch } 86212bb5b78SClemens Ladisch 86312bb5b78SClemens Ladisch /* (2) */ 864*567f5875STakashi Iwai err = snd_devm_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE, 865*567f5875STakashi Iwai sizeof(*chip), &card); 866e58de7baSTakashi Iwai if (err < 0) 867e58de7baSTakashi Iwai return err; 868*567f5875STakashi Iwai chip = card->private_data; 86912bb5b78SClemens Ladisch 87012bb5b78SClemens Ladisch strcpy(card->driver, "AD1889"); 87112bb5b78SClemens Ladisch strcpy(card->shortname, "Analog Devices AD1889"); 87212bb5b78SClemens Ladisch 87312bb5b78SClemens Ladisch /* (3) */ 874*567f5875STakashi Iwai err = snd_ad1889_create(card, pci); 87512bb5b78SClemens Ladisch if (err < 0) 876*567f5875STakashi Iwai return err; 87712bb5b78SClemens Ladisch 87812bb5b78SClemens Ladisch /* (4) */ 87912bb5b78SClemens Ladisch sprintf(card->longname, "%s at 0x%lx irq %i", 88012bb5b78SClemens Ladisch card->shortname, chip->bar, chip->irq); 88112bb5b78SClemens Ladisch 88212bb5b78SClemens Ladisch /* (5) */ 88312bb5b78SClemens Ladisch /* register AC97 mixer */ 88412bb5b78SClemens Ladisch err = snd_ad1889_ac97_init(chip, ac97_quirk[devno]); 88512bb5b78SClemens Ladisch if (err < 0) 886*567f5875STakashi Iwai return err; 88712bb5b78SClemens Ladisch 888a0880094SLars-Peter Clausen err = snd_ad1889_pcm_init(chip, 0); 88912bb5b78SClemens Ladisch if (err < 0) 890*567f5875STakashi Iwai return err; 89112bb5b78SClemens Ladisch 89212bb5b78SClemens Ladisch /* register proc interface */ 89312bb5b78SClemens Ladisch snd_ad1889_proc_init(chip); 89412bb5b78SClemens Ladisch 89512bb5b78SClemens Ladisch /* (6) */ 89612bb5b78SClemens Ladisch err = snd_card_register(card); 89712bb5b78SClemens Ladisch if (err < 0) 898*567f5875STakashi Iwai return err; 89912bb5b78SClemens Ladisch 90012bb5b78SClemens Ladisch /* (7) */ 90112bb5b78SClemens Ladisch pci_set_drvdata(pci, card); 90212bb5b78SClemens Ladisch 90312bb5b78SClemens Ladisch devno++; 90412bb5b78SClemens Ladisch return 0; 90512bb5b78SClemens Ladisch } 90612bb5b78SClemens Ladisch 9079baa3c34SBenoit Taine static const struct pci_device_id snd_ad1889_ids[] = { 90812bb5b78SClemens Ladisch { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) }, 90912bb5b78SClemens Ladisch { 0, }, 91012bb5b78SClemens Ladisch }; 91112bb5b78SClemens Ladisch MODULE_DEVICE_TABLE(pci, snd_ad1889_ids); 91212bb5b78SClemens Ladisch 913e4d76815SRandy Dunlap static struct pci_driver ad1889_pci_driver = { 9143733e424STakashi Iwai .name = KBUILD_MODNAME, 91512bb5b78SClemens Ladisch .id_table = snd_ad1889_ids, 91612bb5b78SClemens Ladisch .probe = snd_ad1889_probe, 91712bb5b78SClemens Ladisch }; 91812bb5b78SClemens Ladisch 919e9f66d9bSTakashi Iwai module_pci_driver(ad1889_pci_driver); 920