xref: /openbmc/linux/sound/pci/ad1889.c (revision da155d5b)
112bb5b78SClemens Ladisch /* Analog Devices 1889 audio driver
212bb5b78SClemens Ladisch  *
312bb5b78SClemens Ladisch  * This is a driver for the AD1889 PCI audio chipset found
412bb5b78SClemens Ladisch  * on the HP PA-RISC [BCJ]-xxx0 workstations.
512bb5b78SClemens Ladisch  *
612bb5b78SClemens Ladisch  * Copyright (C) 2004-2005, Kyle McMartin <kyle@parisc-linux.org>
712bb5b78SClemens Ladisch  * Copyright (C) 2005, Thibaut Varene <varenet@parisc-linux.org>
812bb5b78SClemens Ladisch  *   Based on the OSS AD1889 driver by Randolph Chung <tausq@debian.org>
912bb5b78SClemens Ladisch  *
1012bb5b78SClemens Ladisch  * This program is free software; you can redistribute it and/or modify
1112bb5b78SClemens Ladisch  * it under the terms of the GNU General Public License, version 2, as
1212bb5b78SClemens Ladisch  * published by the Free Software Foundation.
1312bb5b78SClemens Ladisch  *
1412bb5b78SClemens Ladisch  * This program is distributed in the hope that it will be useful,
1512bb5b78SClemens Ladisch  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1612bb5b78SClemens Ladisch  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
1712bb5b78SClemens Ladisch  * GNU General Public License for more details.
1812bb5b78SClemens Ladisch  *
1912bb5b78SClemens Ladisch  * You should have received a copy of the GNU General Public License
2012bb5b78SClemens Ladisch  * along with this program; if not, write to the Free Software
2112bb5b78SClemens Ladisch  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2212bb5b78SClemens Ladisch  *
2312bb5b78SClemens Ladisch  * TODO:
2412bb5b78SClemens Ladisch  *	Do we need to take care of CCS register?
2512bb5b78SClemens Ladisch  *	Maybe we could use finer grained locking (separate locks for pb/cap)?
2612bb5b78SClemens Ladisch  * Wishlist:
2712bb5b78SClemens Ladisch  *	Control Interface (mixer) support
2812bb5b78SClemens Ladisch  *	Better AC97 support (VSR...)?
2912bb5b78SClemens Ladisch  *	PM support
3012bb5b78SClemens Ladisch  *	MIDI support
3112bb5b78SClemens Ladisch  *	Game Port support
3212bb5b78SClemens Ladisch  *	SG DMA support (this will need *a lot* of work)
3312bb5b78SClemens Ladisch  */
3412bb5b78SClemens Ladisch 
3512bb5b78SClemens Ladisch #include <linux/init.h>
3612bb5b78SClemens Ladisch #include <linux/pci.h>
379d2f928dSTobias Klauser #include <linux/dma-mapping.h>
3812bb5b78SClemens Ladisch #include <linux/slab.h>
3912bb5b78SClemens Ladisch #include <linux/interrupt.h>
4012bb5b78SClemens Ladisch #include <linux/compiler.h>
4112bb5b78SClemens Ladisch #include <linux/delay.h>
42da155d5bSPaul Gortmaker #include <linux/module.h>
4312bb5b78SClemens Ladisch 
4412bb5b78SClemens Ladisch #include <sound/core.h>
4512bb5b78SClemens Ladisch #include <sound/pcm.h>
4612bb5b78SClemens Ladisch #include <sound/initval.h>
4712bb5b78SClemens Ladisch #include <sound/ac97_codec.h>
4812bb5b78SClemens Ladisch 
4912bb5b78SClemens Ladisch #include <asm/io.h>
5012bb5b78SClemens Ladisch 
5112bb5b78SClemens Ladisch #include "ad1889.h"
5212bb5b78SClemens Ladisch #include "ac97/ac97_id.h"
5312bb5b78SClemens Ladisch 
54c6f43290SJaroslav Kysela #define	AD1889_DRVVER	"Version: 1.7"
5512bb5b78SClemens Ladisch 
5612bb5b78SClemens Ladisch MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>");
5712bb5b78SClemens Ladisch MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
5812bb5b78SClemens Ladisch MODULE_LICENSE("GPL");
5912bb5b78SClemens Ladisch MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1889}}");
6012bb5b78SClemens Ladisch 
6112bb5b78SClemens Ladisch static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
6212bb5b78SClemens Ladisch module_param_array(index, int, NULL, 0444);
6312bb5b78SClemens Ladisch MODULE_PARM_DESC(index, "Index value for the AD1889 soundcard.");
6412bb5b78SClemens Ladisch 
6512bb5b78SClemens Ladisch static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
6612bb5b78SClemens Ladisch module_param_array(id, charp, NULL, 0444);
6712bb5b78SClemens Ladisch MODULE_PARM_DESC(id, "ID string for the AD1889 soundcard.");
6812bb5b78SClemens Ladisch 
6912bb5b78SClemens Ladisch static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
7012bb5b78SClemens Ladisch module_param_array(enable, bool, NULL, 0444);
7112bb5b78SClemens Ladisch MODULE_PARM_DESC(enable, "Enable AD1889 soundcard.");
7212bb5b78SClemens Ladisch 
7312bb5b78SClemens Ladisch static char *ac97_quirk[SNDRV_CARDS];
7412bb5b78SClemens Ladisch module_param_array(ac97_quirk, charp, NULL, 0444);
7512bb5b78SClemens Ladisch MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
7612bb5b78SClemens Ladisch 
7712bb5b78SClemens Ladisch #define DEVNAME "ad1889"
7812bb5b78SClemens Ladisch #define PFX	DEVNAME ": "
7912bb5b78SClemens Ladisch 
8012bb5b78SClemens Ladisch /* let's use the global sound debug interfaces */
8112bb5b78SClemens Ladisch #define ad1889_debug(fmt, arg...) snd_printd(KERN_DEBUG fmt, ## arg)
8212bb5b78SClemens Ladisch 
8312bb5b78SClemens Ladisch /* keep track of some hw registers */
8412bb5b78SClemens Ladisch struct ad1889_register_state {
8512bb5b78SClemens Ladisch 	u16 reg;	/* reg setup */
8612bb5b78SClemens Ladisch 	u32 addr;	/* dma base address */
8712bb5b78SClemens Ladisch 	unsigned long size;	/* DMA buffer size */
8812bb5b78SClemens Ladisch };
8912bb5b78SClemens Ladisch 
9012bb5b78SClemens Ladisch struct snd_ad1889 {
9102c2de69STakashi Iwai 	struct snd_card *card;
9212bb5b78SClemens Ladisch 	struct pci_dev *pci;
9312bb5b78SClemens Ladisch 
9412bb5b78SClemens Ladisch 	int irq;
9512bb5b78SClemens Ladisch 	unsigned long bar;
9612bb5b78SClemens Ladisch 	void __iomem *iobase;
9712bb5b78SClemens Ladisch 
9802c2de69STakashi Iwai 	struct snd_ac97 *ac97;
9902c2de69STakashi Iwai 	struct snd_ac97_bus *ac97_bus;
10002c2de69STakashi Iwai 	struct snd_pcm *pcm;
10102c2de69STakashi Iwai 	struct snd_info_entry *proc;
10212bb5b78SClemens Ladisch 
10302c2de69STakashi Iwai 	struct snd_pcm_substream *psubs;
10402c2de69STakashi Iwai 	struct snd_pcm_substream *csubs;
10512bb5b78SClemens Ladisch 
10612bb5b78SClemens Ladisch 	/* playback register state */
10712bb5b78SClemens Ladisch 	struct ad1889_register_state wave;
10812bb5b78SClemens Ladisch 	struct ad1889_register_state ramc;
10912bb5b78SClemens Ladisch 
11012bb5b78SClemens Ladisch 	spinlock_t lock;
11112bb5b78SClemens Ladisch };
11212bb5b78SClemens Ladisch 
11312bb5b78SClemens Ladisch static inline u16
11412bb5b78SClemens Ladisch ad1889_readw(struct snd_ad1889 *chip, unsigned reg)
11512bb5b78SClemens Ladisch {
11612bb5b78SClemens Ladisch 	return readw(chip->iobase + reg);
11712bb5b78SClemens Ladisch }
11812bb5b78SClemens Ladisch 
11912bb5b78SClemens Ladisch static inline void
12012bb5b78SClemens Ladisch ad1889_writew(struct snd_ad1889 *chip, unsigned reg, u16 val)
12112bb5b78SClemens Ladisch {
12212bb5b78SClemens Ladisch 	writew(val, chip->iobase + reg);
12312bb5b78SClemens Ladisch }
12412bb5b78SClemens Ladisch 
12512bb5b78SClemens Ladisch static inline u32
12612bb5b78SClemens Ladisch ad1889_readl(struct snd_ad1889 *chip, unsigned reg)
12712bb5b78SClemens Ladisch {
12812bb5b78SClemens Ladisch 	return readl(chip->iobase + reg);
12912bb5b78SClemens Ladisch }
13012bb5b78SClemens Ladisch 
13112bb5b78SClemens Ladisch static inline void
13212bb5b78SClemens Ladisch ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val)
13312bb5b78SClemens Ladisch {
13412bb5b78SClemens Ladisch 	writel(val, chip->iobase + reg);
13512bb5b78SClemens Ladisch }
13612bb5b78SClemens Ladisch 
13712bb5b78SClemens Ladisch static inline void
13812bb5b78SClemens Ladisch ad1889_unmute(struct snd_ad1889 *chip)
13912bb5b78SClemens Ladisch {
14012bb5b78SClemens Ladisch 	u16 st;
14112bb5b78SClemens Ladisch 	st = ad1889_readw(chip, AD_DS_WADA) &
14212bb5b78SClemens Ladisch 		~(AD_DS_WADA_RWAM | AD_DS_WADA_LWAM);
14312bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_DS_WADA, st);
14412bb5b78SClemens Ladisch 	ad1889_readw(chip, AD_DS_WADA);
14512bb5b78SClemens Ladisch }
14612bb5b78SClemens Ladisch 
14712bb5b78SClemens Ladisch static inline void
14812bb5b78SClemens Ladisch ad1889_mute(struct snd_ad1889 *chip)
14912bb5b78SClemens Ladisch {
15012bb5b78SClemens Ladisch 	u16 st;
15112bb5b78SClemens Ladisch 	st = ad1889_readw(chip, AD_DS_WADA) | AD_DS_WADA_RWAM | AD_DS_WADA_LWAM;
15212bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_DS_WADA, st);
15312bb5b78SClemens Ladisch 	ad1889_readw(chip, AD_DS_WADA);
15412bb5b78SClemens Ladisch }
15512bb5b78SClemens Ladisch 
15612bb5b78SClemens Ladisch static inline void
15712bb5b78SClemens Ladisch ad1889_load_adc_buffer_address(struct snd_ad1889 *chip, u32 address)
15812bb5b78SClemens Ladisch {
15912bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_ADCBA, address);
16012bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_ADCCA, address);
16112bb5b78SClemens Ladisch }
16212bb5b78SClemens Ladisch 
16312bb5b78SClemens Ladisch static inline void
16412bb5b78SClemens Ladisch ad1889_load_adc_buffer_count(struct snd_ad1889 *chip, u32 count)
16512bb5b78SClemens Ladisch {
16612bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_ADCBC, count);
16712bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_ADCCC, count);
16812bb5b78SClemens Ladisch }
16912bb5b78SClemens Ladisch 
17012bb5b78SClemens Ladisch static inline void
17112bb5b78SClemens Ladisch ad1889_load_adc_interrupt_count(struct snd_ad1889 *chip, u32 count)
17212bb5b78SClemens Ladisch {
17312bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_ADCIB, count);
17412bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_ADCIC, count);
17512bb5b78SClemens Ladisch }
17612bb5b78SClemens Ladisch 
17712bb5b78SClemens Ladisch static inline void
17812bb5b78SClemens Ladisch ad1889_load_wave_buffer_address(struct snd_ad1889 *chip, u32 address)
17912bb5b78SClemens Ladisch {
18012bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_WAVBA, address);
18112bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_WAVCA, address);
18212bb5b78SClemens Ladisch }
18312bb5b78SClemens Ladisch 
18412bb5b78SClemens Ladisch static inline void
18512bb5b78SClemens Ladisch ad1889_load_wave_buffer_count(struct snd_ad1889 *chip, u32 count)
18612bb5b78SClemens Ladisch {
18712bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_WAVBC, count);
18812bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_WAVCC, count);
18912bb5b78SClemens Ladisch }
19012bb5b78SClemens Ladisch 
19112bb5b78SClemens Ladisch static inline void
19212bb5b78SClemens Ladisch ad1889_load_wave_interrupt_count(struct snd_ad1889 *chip, u32 count)
19312bb5b78SClemens Ladisch {
19412bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_WAVIB, count);
19512bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_WAVIC, count);
19612bb5b78SClemens Ladisch }
19712bb5b78SClemens Ladisch 
19812bb5b78SClemens Ladisch static void
19912bb5b78SClemens Ladisch ad1889_channel_reset(struct snd_ad1889 *chip, unsigned int channel)
20012bb5b78SClemens Ladisch {
20112bb5b78SClemens Ladisch 	u16 reg;
20212bb5b78SClemens Ladisch 
20312bb5b78SClemens Ladisch 	if (channel & AD_CHAN_WAV) {
20412bb5b78SClemens Ladisch 		/* Disable wave channel */
20512bb5b78SClemens Ladisch 		reg = ad1889_readw(chip, AD_DS_WSMC) & ~AD_DS_WSMC_WAEN;
20612bb5b78SClemens Ladisch 		ad1889_writew(chip, AD_DS_WSMC, reg);
20712bb5b78SClemens Ladisch 		chip->wave.reg = reg;
20812bb5b78SClemens Ladisch 
20912bb5b78SClemens Ladisch 		/* disable IRQs */
21012bb5b78SClemens Ladisch 		reg = ad1889_readw(chip, AD_DMA_WAV);
21112bb5b78SClemens Ladisch 		reg &= AD_DMA_IM_DIS;
21212bb5b78SClemens Ladisch 		reg &= ~AD_DMA_LOOP;
21312bb5b78SClemens Ladisch 		ad1889_writew(chip, AD_DMA_WAV, reg);
21412bb5b78SClemens Ladisch 
21512bb5b78SClemens Ladisch 		/* clear IRQ and address counters and pointers */
21612bb5b78SClemens Ladisch 		ad1889_load_wave_buffer_address(chip, 0x0);
21712bb5b78SClemens Ladisch 		ad1889_load_wave_buffer_count(chip, 0x0);
21812bb5b78SClemens Ladisch 		ad1889_load_wave_interrupt_count(chip, 0x0);
21912bb5b78SClemens Ladisch 
22012bb5b78SClemens Ladisch 		/* flush */
22112bb5b78SClemens Ladisch 		ad1889_readw(chip, AD_DMA_WAV);
22212bb5b78SClemens Ladisch 	}
22312bb5b78SClemens Ladisch 
22412bb5b78SClemens Ladisch 	if (channel & AD_CHAN_ADC) {
22512bb5b78SClemens Ladisch 		/* Disable ADC channel */
22612bb5b78SClemens Ladisch 		reg = ad1889_readw(chip, AD_DS_RAMC) & ~AD_DS_RAMC_ADEN;
22712bb5b78SClemens Ladisch 		ad1889_writew(chip, AD_DS_RAMC, reg);
22812bb5b78SClemens Ladisch 		chip->ramc.reg = reg;
22912bb5b78SClemens Ladisch 
23012bb5b78SClemens Ladisch 		reg = ad1889_readw(chip, AD_DMA_ADC);
23112bb5b78SClemens Ladisch 		reg &= AD_DMA_IM_DIS;
23212bb5b78SClemens Ladisch 		reg &= ~AD_DMA_LOOP;
23312bb5b78SClemens Ladisch 		ad1889_writew(chip, AD_DMA_ADC, reg);
23412bb5b78SClemens Ladisch 
23512bb5b78SClemens Ladisch 		ad1889_load_adc_buffer_address(chip, 0x0);
23612bb5b78SClemens Ladisch 		ad1889_load_adc_buffer_count(chip, 0x0);
23712bb5b78SClemens Ladisch 		ad1889_load_adc_interrupt_count(chip, 0x0);
23812bb5b78SClemens Ladisch 
23912bb5b78SClemens Ladisch 		/* flush */
24012bb5b78SClemens Ladisch 		ad1889_readw(chip, AD_DMA_ADC);
24112bb5b78SClemens Ladisch 	}
24212bb5b78SClemens Ladisch }
24312bb5b78SClemens Ladisch 
244f40b6890STakashi Iwai static u16
24502c2de69STakashi Iwai snd_ad1889_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
24612bb5b78SClemens Ladisch {
24712bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = ac97->private_data;
24812bb5b78SClemens Ladisch 	return ad1889_readw(chip, AD_AC97_BASE + reg);
24912bb5b78SClemens Ladisch }
25012bb5b78SClemens Ladisch 
251f40b6890STakashi Iwai static void
25202c2de69STakashi Iwai snd_ad1889_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
25312bb5b78SClemens Ladisch {
25412bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = ac97->private_data;
25512bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_AC97_BASE + reg, val);
25612bb5b78SClemens Ladisch }
25712bb5b78SClemens Ladisch 
25812bb5b78SClemens Ladisch static int
25912bb5b78SClemens Ladisch snd_ad1889_ac97_ready(struct snd_ad1889 *chip)
26012bb5b78SClemens Ladisch {
26112bb5b78SClemens Ladisch 	int retry = 400; /* average needs 352 msec */
26212bb5b78SClemens Ladisch 
26312bb5b78SClemens Ladisch 	while (!(ad1889_readw(chip, AD_AC97_ACIC) & AD_AC97_ACIC_ACRDY)
26412bb5b78SClemens Ladisch 			&& --retry)
26512bb5b78SClemens Ladisch 		mdelay(1);
26612bb5b78SClemens Ladisch 	if (!retry) {
26712bb5b78SClemens Ladisch 		snd_printk(KERN_ERR PFX "[%s] Link is not ready.\n",
2689bf8e7ddSHarvey Harrison 		       __func__);
26912bb5b78SClemens Ladisch 		return -EIO;
27012bb5b78SClemens Ladisch 	}
2719bf8e7ddSHarvey Harrison 	ad1889_debug("[%s] ready after %d ms\n", __func__, 400 - retry);
27212bb5b78SClemens Ladisch 
27312bb5b78SClemens Ladisch 	return 0;
27412bb5b78SClemens Ladisch }
27512bb5b78SClemens Ladisch 
27612bb5b78SClemens Ladisch static int
27702c2de69STakashi Iwai snd_ad1889_hw_params(struct snd_pcm_substream *substream,
27802c2de69STakashi Iwai 			struct snd_pcm_hw_params *hw_params)
27912bb5b78SClemens Ladisch {
28012bb5b78SClemens Ladisch 	return snd_pcm_lib_malloc_pages(substream,
28112bb5b78SClemens Ladisch 					params_buffer_bytes(hw_params));
28212bb5b78SClemens Ladisch }
28312bb5b78SClemens Ladisch 
28412bb5b78SClemens Ladisch static int
28502c2de69STakashi Iwai snd_ad1889_hw_free(struct snd_pcm_substream *substream)
28612bb5b78SClemens Ladisch {
28712bb5b78SClemens Ladisch 	return snd_pcm_lib_free_pages(substream);
28812bb5b78SClemens Ladisch }
28912bb5b78SClemens Ladisch 
29002c2de69STakashi Iwai static struct snd_pcm_hardware snd_ad1889_playback_hw = {
29112bb5b78SClemens Ladisch 	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
29212bb5b78SClemens Ladisch 		SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
29312bb5b78SClemens Ladisch 	.formats = SNDRV_PCM_FMTBIT_S16_LE,
29412bb5b78SClemens Ladisch 	.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
29512bb5b78SClemens Ladisch 	.rate_min = 8000,	/* docs say 7000, but we're lazy */
29612bb5b78SClemens Ladisch 	.rate_max = 48000,
29712bb5b78SClemens Ladisch 	.channels_min = 1,
29812bb5b78SClemens Ladisch 	.channels_max = 2,
29912bb5b78SClemens Ladisch 	.buffer_bytes_max = BUFFER_BYTES_MAX,
30012bb5b78SClemens Ladisch 	.period_bytes_min = PERIOD_BYTES_MIN,
30112bb5b78SClemens Ladisch 	.period_bytes_max = PERIOD_BYTES_MAX,
30212bb5b78SClemens Ladisch 	.periods_min = PERIODS_MIN,
30312bb5b78SClemens Ladisch 	.periods_max = PERIODS_MAX,
30412bb5b78SClemens Ladisch 	/*.fifo_size = 0,*/
30512bb5b78SClemens Ladisch };
30612bb5b78SClemens Ladisch 
30702c2de69STakashi Iwai static struct snd_pcm_hardware snd_ad1889_capture_hw = {
30812bb5b78SClemens Ladisch 	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
30912bb5b78SClemens Ladisch 		SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
31012bb5b78SClemens Ladisch 	.formats = SNDRV_PCM_FMTBIT_S16_LE,
31112bb5b78SClemens Ladisch 	.rates = SNDRV_PCM_RATE_48000,
31212bb5b78SClemens Ladisch 	.rate_min = 48000,	/* docs say we could to VSR, but we're lazy */
31312bb5b78SClemens Ladisch 	.rate_max = 48000,
31412bb5b78SClemens Ladisch 	.channels_min = 1,
31512bb5b78SClemens Ladisch 	.channels_max = 2,
31612bb5b78SClemens Ladisch 	.buffer_bytes_max = BUFFER_BYTES_MAX,
31712bb5b78SClemens Ladisch 	.period_bytes_min = PERIOD_BYTES_MIN,
31812bb5b78SClemens Ladisch 	.period_bytes_max = PERIOD_BYTES_MAX,
31912bb5b78SClemens Ladisch 	.periods_min = PERIODS_MIN,
32012bb5b78SClemens Ladisch 	.periods_max = PERIODS_MAX,
32112bb5b78SClemens Ladisch 	/*.fifo_size = 0,*/
32212bb5b78SClemens Ladisch };
32312bb5b78SClemens Ladisch 
32412bb5b78SClemens Ladisch static int
32502c2de69STakashi Iwai snd_ad1889_playback_open(struct snd_pcm_substream *ss)
32612bb5b78SClemens Ladisch {
32712bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
32802c2de69STakashi Iwai 	struct snd_pcm_runtime *rt = ss->runtime;
32912bb5b78SClemens Ladisch 
33012bb5b78SClemens Ladisch 	chip->psubs = ss;
33112bb5b78SClemens Ladisch 	rt->hw = snd_ad1889_playback_hw;
33212bb5b78SClemens Ladisch 
33312bb5b78SClemens Ladisch 	return 0;
33412bb5b78SClemens Ladisch }
33512bb5b78SClemens Ladisch 
33612bb5b78SClemens Ladisch static int
33702c2de69STakashi Iwai snd_ad1889_capture_open(struct snd_pcm_substream *ss)
33812bb5b78SClemens Ladisch {
33912bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
34002c2de69STakashi Iwai 	struct snd_pcm_runtime *rt = ss->runtime;
34112bb5b78SClemens Ladisch 
34212bb5b78SClemens Ladisch 	chip->csubs = ss;
34312bb5b78SClemens Ladisch 	rt->hw = snd_ad1889_capture_hw;
34412bb5b78SClemens Ladisch 
34512bb5b78SClemens Ladisch 	return 0;
34612bb5b78SClemens Ladisch }
34712bb5b78SClemens Ladisch 
34812bb5b78SClemens Ladisch static int
34902c2de69STakashi Iwai snd_ad1889_playback_close(struct snd_pcm_substream *ss)
35012bb5b78SClemens Ladisch {
35112bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
35212bb5b78SClemens Ladisch 	chip->psubs = NULL;
35312bb5b78SClemens Ladisch 	return 0;
35412bb5b78SClemens Ladisch }
35512bb5b78SClemens Ladisch 
35612bb5b78SClemens Ladisch static int
35702c2de69STakashi Iwai snd_ad1889_capture_close(struct snd_pcm_substream *ss)
35812bb5b78SClemens Ladisch {
35912bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
36012bb5b78SClemens Ladisch 	chip->csubs = NULL;
36112bb5b78SClemens Ladisch 	return 0;
36212bb5b78SClemens Ladisch }
36312bb5b78SClemens Ladisch 
36412bb5b78SClemens Ladisch static int
36502c2de69STakashi Iwai snd_ad1889_playback_prepare(struct snd_pcm_substream *ss)
36612bb5b78SClemens Ladisch {
36712bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
36802c2de69STakashi Iwai 	struct snd_pcm_runtime *rt = ss->runtime;
36912bb5b78SClemens Ladisch 	unsigned int size = snd_pcm_lib_buffer_bytes(ss);
37012bb5b78SClemens Ladisch 	unsigned int count = snd_pcm_lib_period_bytes(ss);
37112bb5b78SClemens Ladisch 	u16 reg;
37212bb5b78SClemens Ladisch 
37312bb5b78SClemens Ladisch 	ad1889_channel_reset(chip, AD_CHAN_WAV);
37412bb5b78SClemens Ladisch 
37512bb5b78SClemens Ladisch 	reg = ad1889_readw(chip, AD_DS_WSMC);
37612bb5b78SClemens Ladisch 
37712bb5b78SClemens Ladisch 	/* Mask out 16-bit / Stereo */
37812bb5b78SClemens Ladisch 	reg &= ~(AD_DS_WSMC_WA16 | AD_DS_WSMC_WAST);
37912bb5b78SClemens Ladisch 
38012bb5b78SClemens Ladisch 	if (snd_pcm_format_width(rt->format) == 16)
38112bb5b78SClemens Ladisch 		reg |= AD_DS_WSMC_WA16;
38212bb5b78SClemens Ladisch 
38312bb5b78SClemens Ladisch 	if (rt->channels > 1)
38412bb5b78SClemens Ladisch 		reg |= AD_DS_WSMC_WAST;
38512bb5b78SClemens Ladisch 
38612bb5b78SClemens Ladisch 	/* let's make sure we don't clobber ourselves */
38712bb5b78SClemens Ladisch 	spin_lock_irq(&chip->lock);
38812bb5b78SClemens Ladisch 
38912bb5b78SClemens Ladisch 	chip->wave.size = size;
39012bb5b78SClemens Ladisch 	chip->wave.reg = reg;
39112bb5b78SClemens Ladisch 	chip->wave.addr = rt->dma_addr;
39212bb5b78SClemens Ladisch 
39312bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_DS_WSMC, chip->wave.reg);
39412bb5b78SClemens Ladisch 
39512bb5b78SClemens Ladisch 	/* Set sample rates on the codec */
39612bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_DS_WAS, rt->rate);
39712bb5b78SClemens Ladisch 
39812bb5b78SClemens Ladisch 	/* Set up DMA */
39912bb5b78SClemens Ladisch 	ad1889_load_wave_buffer_address(chip, chip->wave.addr);
40012bb5b78SClemens Ladisch 	ad1889_load_wave_buffer_count(chip, size);
40112bb5b78SClemens Ladisch 	ad1889_load_wave_interrupt_count(chip, count);
40212bb5b78SClemens Ladisch 
40312bb5b78SClemens Ladisch 	/* writes flush */
40412bb5b78SClemens Ladisch 	ad1889_readw(chip, AD_DS_WSMC);
40512bb5b78SClemens Ladisch 
40612bb5b78SClemens Ladisch 	spin_unlock_irq(&chip->lock);
40712bb5b78SClemens Ladisch 
40812bb5b78SClemens Ladisch 	ad1889_debug("prepare playback: addr = 0x%x, count = %u, "
40912bb5b78SClemens Ladisch 			"size = %u, reg = 0x%x, rate = %u\n", chip->wave.addr,
41012bb5b78SClemens Ladisch 			count, size, reg, rt->rate);
41112bb5b78SClemens Ladisch 	return 0;
41212bb5b78SClemens Ladisch }
41312bb5b78SClemens Ladisch 
41412bb5b78SClemens Ladisch static int
41502c2de69STakashi Iwai snd_ad1889_capture_prepare(struct snd_pcm_substream *ss)
41612bb5b78SClemens Ladisch {
41712bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
41802c2de69STakashi Iwai 	struct snd_pcm_runtime *rt = ss->runtime;
41912bb5b78SClemens Ladisch 	unsigned int size = snd_pcm_lib_buffer_bytes(ss);
42012bb5b78SClemens Ladisch 	unsigned int count = snd_pcm_lib_period_bytes(ss);
42112bb5b78SClemens Ladisch 	u16 reg;
42212bb5b78SClemens Ladisch 
42312bb5b78SClemens Ladisch 	ad1889_channel_reset(chip, AD_CHAN_ADC);
42412bb5b78SClemens Ladisch 
42512bb5b78SClemens Ladisch 	reg = ad1889_readw(chip, AD_DS_RAMC);
42612bb5b78SClemens Ladisch 
42712bb5b78SClemens Ladisch 	/* Mask out 16-bit / Stereo */
42812bb5b78SClemens Ladisch 	reg &= ~(AD_DS_RAMC_AD16 | AD_DS_RAMC_ADST);
42912bb5b78SClemens Ladisch 
43012bb5b78SClemens Ladisch 	if (snd_pcm_format_width(rt->format) == 16)
43112bb5b78SClemens Ladisch 		reg |= AD_DS_RAMC_AD16;
43212bb5b78SClemens Ladisch 
43312bb5b78SClemens Ladisch 	if (rt->channels > 1)
43412bb5b78SClemens Ladisch 		reg |= AD_DS_RAMC_ADST;
43512bb5b78SClemens Ladisch 
43612bb5b78SClemens Ladisch 	/* let's make sure we don't clobber ourselves */
43712bb5b78SClemens Ladisch 	spin_lock_irq(&chip->lock);
43812bb5b78SClemens Ladisch 
43912bb5b78SClemens Ladisch 	chip->ramc.size = size;
44012bb5b78SClemens Ladisch 	chip->ramc.reg = reg;
44112bb5b78SClemens Ladisch 	chip->ramc.addr = rt->dma_addr;
44212bb5b78SClemens Ladisch 
44312bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_DS_RAMC, chip->ramc.reg);
44412bb5b78SClemens Ladisch 
44512bb5b78SClemens Ladisch 	/* Set up DMA */
44612bb5b78SClemens Ladisch 	ad1889_load_adc_buffer_address(chip, chip->ramc.addr);
44712bb5b78SClemens Ladisch 	ad1889_load_adc_buffer_count(chip, size);
44812bb5b78SClemens Ladisch 	ad1889_load_adc_interrupt_count(chip, count);
44912bb5b78SClemens Ladisch 
45012bb5b78SClemens Ladisch 	/* writes flush */
45112bb5b78SClemens Ladisch 	ad1889_readw(chip, AD_DS_RAMC);
45212bb5b78SClemens Ladisch 
45312bb5b78SClemens Ladisch 	spin_unlock_irq(&chip->lock);
45412bb5b78SClemens Ladisch 
45512bb5b78SClemens Ladisch 	ad1889_debug("prepare capture: addr = 0x%x, count = %u, "
45612bb5b78SClemens Ladisch 			"size = %u, reg = 0x%x, rate = %u\n", chip->ramc.addr,
45712bb5b78SClemens Ladisch 			count, size, reg, rt->rate);
45812bb5b78SClemens Ladisch 	return 0;
45912bb5b78SClemens Ladisch }
46012bb5b78SClemens Ladisch 
46112bb5b78SClemens Ladisch /* this is called in atomic context with IRQ disabled.
46212bb5b78SClemens Ladisch    Must be as fast as possible and not sleep.
46312bb5b78SClemens Ladisch    DMA should be *triggered* by this call.
46412bb5b78SClemens Ladisch    The WSMC "WAEN" bit triggers DMA Wave On/Off */
46512bb5b78SClemens Ladisch static int
46602c2de69STakashi Iwai snd_ad1889_playback_trigger(struct snd_pcm_substream *ss, int cmd)
46712bb5b78SClemens Ladisch {
46812bb5b78SClemens Ladisch 	u16 wsmc;
46912bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
47012bb5b78SClemens Ladisch 
47112bb5b78SClemens Ladisch 	wsmc = ad1889_readw(chip, AD_DS_WSMC);
47212bb5b78SClemens Ladisch 
47312bb5b78SClemens Ladisch 	switch (cmd) {
47412bb5b78SClemens Ladisch 	case SNDRV_PCM_TRIGGER_START:
47512bb5b78SClemens Ladisch 		/* enable DMA loop & interrupts */
47612bb5b78SClemens Ladisch 		ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT);
47712bb5b78SClemens Ladisch 		wsmc |= AD_DS_WSMC_WAEN;
47812bb5b78SClemens Ladisch 		/* 1 to clear CHSS bit */
47912bb5b78SClemens Ladisch 		ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS);
48012bb5b78SClemens Ladisch 		ad1889_unmute(chip);
48112bb5b78SClemens Ladisch 		break;
48212bb5b78SClemens Ladisch 	case SNDRV_PCM_TRIGGER_STOP:
48312bb5b78SClemens Ladisch 		ad1889_mute(chip);
48412bb5b78SClemens Ladisch 		wsmc &= ~AD_DS_WSMC_WAEN;
48512bb5b78SClemens Ladisch 		break;
48612bb5b78SClemens Ladisch 	default:
48712bb5b78SClemens Ladisch 		snd_BUG();
48812bb5b78SClemens Ladisch 		return -EINVAL;
48912bb5b78SClemens Ladisch 	}
49012bb5b78SClemens Ladisch 
49112bb5b78SClemens Ladisch 	chip->wave.reg = wsmc;
49212bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_DS_WSMC, wsmc);
49312bb5b78SClemens Ladisch 	ad1889_readw(chip, AD_DS_WSMC);	/* flush */
49412bb5b78SClemens Ladisch 
49512bb5b78SClemens Ladisch 	/* reset the chip when STOP - will disable IRQs */
49612bb5b78SClemens Ladisch 	if (cmd == SNDRV_PCM_TRIGGER_STOP)
49712bb5b78SClemens Ladisch 		ad1889_channel_reset(chip, AD_CHAN_WAV);
49812bb5b78SClemens Ladisch 
49912bb5b78SClemens Ladisch 	return 0;
50012bb5b78SClemens Ladisch }
50112bb5b78SClemens Ladisch 
50212bb5b78SClemens Ladisch /* this is called in atomic context with IRQ disabled.
50312bb5b78SClemens Ladisch    Must be as fast as possible and not sleep.
50412bb5b78SClemens Ladisch    DMA should be *triggered* by this call.
50512bb5b78SClemens Ladisch    The RAMC "ADEN" bit triggers DMA ADC On/Off */
50612bb5b78SClemens Ladisch static int
50702c2de69STakashi Iwai snd_ad1889_capture_trigger(struct snd_pcm_substream *ss, int cmd)
50812bb5b78SClemens Ladisch {
50912bb5b78SClemens Ladisch 	u16 ramc;
51012bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
51112bb5b78SClemens Ladisch 
51212bb5b78SClemens Ladisch 	ramc = ad1889_readw(chip, AD_DS_RAMC);
51312bb5b78SClemens Ladisch 
51412bb5b78SClemens Ladisch 	switch (cmd) {
51512bb5b78SClemens Ladisch 	case SNDRV_PCM_TRIGGER_START:
51612bb5b78SClemens Ladisch 		/* enable DMA loop & interrupts */
51712bb5b78SClemens Ladisch 		ad1889_writew(chip, AD_DMA_ADC, AD_DMA_LOOP | AD_DMA_IM_CNT);
51812bb5b78SClemens Ladisch 		ramc |= AD_DS_RAMC_ADEN;
51912bb5b78SClemens Ladisch 		/* 1 to clear CHSS bit */
52012bb5b78SClemens Ladisch 		ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_ADCS);
52112bb5b78SClemens Ladisch 		break;
52212bb5b78SClemens Ladisch 	case SNDRV_PCM_TRIGGER_STOP:
52312bb5b78SClemens Ladisch 		ramc &= ~AD_DS_RAMC_ADEN;
52412bb5b78SClemens Ladisch 		break;
52512bb5b78SClemens Ladisch 	default:
52612bb5b78SClemens Ladisch 		return -EINVAL;
52712bb5b78SClemens Ladisch 	}
52812bb5b78SClemens Ladisch 
52912bb5b78SClemens Ladisch 	chip->ramc.reg = ramc;
53012bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_DS_RAMC, ramc);
53112bb5b78SClemens Ladisch 	ad1889_readw(chip, AD_DS_RAMC);	/* flush */
53212bb5b78SClemens Ladisch 
53312bb5b78SClemens Ladisch 	/* reset the chip when STOP - will disable IRQs */
53412bb5b78SClemens Ladisch 	if (cmd == SNDRV_PCM_TRIGGER_STOP)
53512bb5b78SClemens Ladisch 		ad1889_channel_reset(chip, AD_CHAN_ADC);
53612bb5b78SClemens Ladisch 
53712bb5b78SClemens Ladisch 	return 0;
53812bb5b78SClemens Ladisch }
53912bb5b78SClemens Ladisch 
54012bb5b78SClemens Ladisch /* Called in atomic context with IRQ disabled */
54112bb5b78SClemens Ladisch static snd_pcm_uframes_t
54202c2de69STakashi Iwai snd_ad1889_playback_pointer(struct snd_pcm_substream *ss)
54312bb5b78SClemens Ladisch {
54412bb5b78SClemens Ladisch 	size_t ptr = 0;
54512bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
54612bb5b78SClemens Ladisch 
54712bb5b78SClemens Ladisch 	if (unlikely(!(chip->wave.reg & AD_DS_WSMC_WAEN)))
54812bb5b78SClemens Ladisch 		return 0;
54912bb5b78SClemens Ladisch 
55012bb5b78SClemens Ladisch 	ptr = ad1889_readl(chip, AD_DMA_WAVCA);
55112bb5b78SClemens Ladisch 	ptr -= chip->wave.addr;
55212bb5b78SClemens Ladisch 
553da3cec35STakashi Iwai 	if (snd_BUG_ON(ptr >= chip->wave.size))
554da3cec35STakashi Iwai 		return 0;
55512bb5b78SClemens Ladisch 
55612bb5b78SClemens Ladisch 	return bytes_to_frames(ss->runtime, ptr);
55712bb5b78SClemens Ladisch }
55812bb5b78SClemens Ladisch 
55912bb5b78SClemens Ladisch /* Called in atomic context with IRQ disabled */
56012bb5b78SClemens Ladisch static snd_pcm_uframes_t
56102c2de69STakashi Iwai snd_ad1889_capture_pointer(struct snd_pcm_substream *ss)
56212bb5b78SClemens Ladisch {
56312bb5b78SClemens Ladisch 	size_t ptr = 0;
56412bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
56512bb5b78SClemens Ladisch 
56612bb5b78SClemens Ladisch 	if (unlikely(!(chip->ramc.reg & AD_DS_RAMC_ADEN)))
56712bb5b78SClemens Ladisch 		return 0;
56812bb5b78SClemens Ladisch 
56912bb5b78SClemens Ladisch 	ptr = ad1889_readl(chip, AD_DMA_ADCCA);
57012bb5b78SClemens Ladisch 	ptr -= chip->ramc.addr;
57112bb5b78SClemens Ladisch 
572da3cec35STakashi Iwai 	if (snd_BUG_ON(ptr >= chip->ramc.size))
573da3cec35STakashi Iwai 		return 0;
57412bb5b78SClemens Ladisch 
57512bb5b78SClemens Ladisch 	return bytes_to_frames(ss->runtime, ptr);
57612bb5b78SClemens Ladisch }
57712bb5b78SClemens Ladisch 
57802c2de69STakashi Iwai static struct snd_pcm_ops snd_ad1889_playback_ops = {
57912bb5b78SClemens Ladisch 	.open = snd_ad1889_playback_open,
58012bb5b78SClemens Ladisch 	.close = snd_ad1889_playback_close,
58112bb5b78SClemens Ladisch 	.ioctl = snd_pcm_lib_ioctl,
58212bb5b78SClemens Ladisch 	.hw_params = snd_ad1889_hw_params,
58312bb5b78SClemens Ladisch 	.hw_free = snd_ad1889_hw_free,
58412bb5b78SClemens Ladisch 	.prepare = snd_ad1889_playback_prepare,
58512bb5b78SClemens Ladisch 	.trigger = snd_ad1889_playback_trigger,
58612bb5b78SClemens Ladisch 	.pointer = snd_ad1889_playback_pointer,
58712bb5b78SClemens Ladisch };
58812bb5b78SClemens Ladisch 
58902c2de69STakashi Iwai static struct snd_pcm_ops snd_ad1889_capture_ops = {
59012bb5b78SClemens Ladisch 	.open = snd_ad1889_capture_open,
59112bb5b78SClemens Ladisch 	.close = snd_ad1889_capture_close,
59212bb5b78SClemens Ladisch 	.ioctl = snd_pcm_lib_ioctl,
59312bb5b78SClemens Ladisch 	.hw_params = snd_ad1889_hw_params,
59412bb5b78SClemens Ladisch 	.hw_free = snd_ad1889_hw_free,
59512bb5b78SClemens Ladisch 	.prepare = snd_ad1889_capture_prepare,
59612bb5b78SClemens Ladisch 	.trigger = snd_ad1889_capture_trigger,
59712bb5b78SClemens Ladisch 	.pointer = snd_ad1889_capture_pointer,
59812bb5b78SClemens Ladisch };
59912bb5b78SClemens Ladisch 
60012bb5b78SClemens Ladisch static irqreturn_t
6017d12e780SDavid Howells snd_ad1889_interrupt(int irq, void *dev_id)
60212bb5b78SClemens Ladisch {
60312bb5b78SClemens Ladisch 	unsigned long st;
60412bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = dev_id;
60512bb5b78SClemens Ladisch 
60612bb5b78SClemens Ladisch 	st = ad1889_readl(chip, AD_DMA_DISR);
60712bb5b78SClemens Ladisch 
60812bb5b78SClemens Ladisch 	/* clear ISR */
60912bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_DISR, st);
61012bb5b78SClemens Ladisch 
61112bb5b78SClemens Ladisch 	st &= AD_INTR_MASK;
61212bb5b78SClemens Ladisch 
61312bb5b78SClemens Ladisch 	if (unlikely(!st))
61412bb5b78SClemens Ladisch 		return IRQ_NONE;
61512bb5b78SClemens Ladisch 
61612bb5b78SClemens Ladisch 	if (st & (AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI))
61712bb5b78SClemens Ladisch 		ad1889_debug("Unexpected master or target abort interrupt!\n");
61812bb5b78SClemens Ladisch 
61912bb5b78SClemens Ladisch 	if ((st & AD_DMA_DISR_WAVI) && chip->psubs)
62012bb5b78SClemens Ladisch 		snd_pcm_period_elapsed(chip->psubs);
62112bb5b78SClemens Ladisch 	if ((st & AD_DMA_DISR_ADCI) && chip->csubs)
62212bb5b78SClemens Ladisch 		snd_pcm_period_elapsed(chip->csubs);
62312bb5b78SClemens Ladisch 
62412bb5b78SClemens Ladisch 	return IRQ_HANDLED;
62512bb5b78SClemens Ladisch }
62612bb5b78SClemens Ladisch 
62712bb5b78SClemens Ladisch static int __devinit
62802c2de69STakashi Iwai snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, struct snd_pcm **rpcm)
62912bb5b78SClemens Ladisch {
63012bb5b78SClemens Ladisch 	int err;
63102c2de69STakashi Iwai 	struct snd_pcm *pcm;
63212bb5b78SClemens Ladisch 
63312bb5b78SClemens Ladisch 	if (rpcm)
63412bb5b78SClemens Ladisch 		*rpcm = NULL;
63512bb5b78SClemens Ladisch 
63612bb5b78SClemens Ladisch 	err = snd_pcm_new(chip->card, chip->card->driver, device, 1, 1, &pcm);
63712bb5b78SClemens Ladisch 	if (err < 0)
63812bb5b78SClemens Ladisch 		return err;
63912bb5b78SClemens Ladisch 
64012bb5b78SClemens Ladisch 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
64112bb5b78SClemens Ladisch 			&snd_ad1889_playback_ops);
64212bb5b78SClemens Ladisch 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
64312bb5b78SClemens Ladisch 			&snd_ad1889_capture_ops);
64412bb5b78SClemens Ladisch 
64512bb5b78SClemens Ladisch 	pcm->private_data = chip;
64612bb5b78SClemens Ladisch 	pcm->info_flags = 0;
64712bb5b78SClemens Ladisch 	strcpy(pcm->name, chip->card->shortname);
64812bb5b78SClemens Ladisch 
64912bb5b78SClemens Ladisch 	chip->pcm = pcm;
65012bb5b78SClemens Ladisch 	chip->psubs = NULL;
65112bb5b78SClemens Ladisch 	chip->csubs = NULL;
65212bb5b78SClemens Ladisch 
65312bb5b78SClemens Ladisch 	err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
65412bb5b78SClemens Ladisch 						snd_dma_pci_data(chip->pci),
65512bb5b78SClemens Ladisch 						BUFFER_BYTES_MAX / 2,
65612bb5b78SClemens Ladisch 						BUFFER_BYTES_MAX);
65712bb5b78SClemens Ladisch 
65812bb5b78SClemens Ladisch 	if (err < 0) {
65912bb5b78SClemens Ladisch 		snd_printk(KERN_ERR PFX "buffer allocation error: %d\n", err);
66012bb5b78SClemens Ladisch 		return err;
66112bb5b78SClemens Ladisch 	}
66212bb5b78SClemens Ladisch 
66312bb5b78SClemens Ladisch 	if (rpcm)
66412bb5b78SClemens Ladisch 		*rpcm = pcm;
66512bb5b78SClemens Ladisch 
66612bb5b78SClemens Ladisch 	return 0;
66712bb5b78SClemens Ladisch }
66812bb5b78SClemens Ladisch 
66912bb5b78SClemens Ladisch static void
67002c2de69STakashi Iwai snd_ad1889_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
67112bb5b78SClemens Ladisch {
67212bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = entry->private_data;
67312bb5b78SClemens Ladisch 	u16 reg;
67412bb5b78SClemens Ladisch 	int tmp;
67512bb5b78SClemens Ladisch 
67612bb5b78SClemens Ladisch 	reg = ad1889_readw(chip, AD_DS_WSMC);
67712bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Wave output: %s\n",
67812bb5b78SClemens Ladisch 			(reg & AD_DS_WSMC_WAEN) ? "enabled" : "disabled");
67912bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Wave Channels: %s\n",
68012bb5b78SClemens Ladisch 			(reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
68112bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Wave Quality: %d-bit linear\n",
68212bb5b78SClemens Ladisch 			(reg & AD_DS_WSMC_WA16) ? 16 : 8);
68312bb5b78SClemens Ladisch 
68412bb5b78SClemens Ladisch 	/* WARQ is at offset 12 */
68512bb5b78SClemens Ladisch 	tmp = (reg & AD_DS_WSMC_WARQ) ?
68612bb5b78SClemens Ladisch 			(((reg & AD_DS_WSMC_WARQ >> 12) & 0x01) ? 12 : 18) : 4;
68712bb5b78SClemens Ladisch 	tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1;
68812bb5b78SClemens Ladisch 
68912bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Wave FIFO: %d %s words\n\n", tmp,
69012bb5b78SClemens Ladisch 			(reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
69112bb5b78SClemens Ladisch 
69212bb5b78SClemens Ladisch 
69312bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Synthesis output: %s\n",
69412bb5b78SClemens Ladisch 			reg & AD_DS_WSMC_SYEN ? "enabled" : "disabled");
69512bb5b78SClemens Ladisch 
69612bb5b78SClemens Ladisch 	/* SYRQ is at offset 4 */
69712bb5b78SClemens Ladisch 	tmp = (reg & AD_DS_WSMC_SYRQ) ?
69812bb5b78SClemens Ladisch 			(((reg & AD_DS_WSMC_SYRQ >> 4) & 0x01) ? 12 : 18) : 4;
69912bb5b78SClemens Ladisch 	tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1;
70012bb5b78SClemens Ladisch 
70112bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Synthesis FIFO: %d %s words\n\n", tmp,
70212bb5b78SClemens Ladisch 			(reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
70312bb5b78SClemens Ladisch 
70412bb5b78SClemens Ladisch 	reg = ad1889_readw(chip, AD_DS_RAMC);
70512bb5b78SClemens Ladisch 	snd_iprintf(buffer, "ADC input: %s\n",
70612bb5b78SClemens Ladisch 			(reg & AD_DS_RAMC_ADEN) ? "enabled" : "disabled");
70712bb5b78SClemens Ladisch 	snd_iprintf(buffer, "ADC Channels: %s\n",
70812bb5b78SClemens Ladisch 			(reg & AD_DS_RAMC_ADST) ? "stereo" : "mono");
70912bb5b78SClemens Ladisch 	snd_iprintf(buffer, "ADC Quality: %d-bit linear\n",
71012bb5b78SClemens Ladisch 			(reg & AD_DS_RAMC_AD16) ? 16 : 8);
71112bb5b78SClemens Ladisch 
71212bb5b78SClemens Ladisch 	/* ACRQ is at offset 4 */
71312bb5b78SClemens Ladisch 	tmp = (reg & AD_DS_RAMC_ACRQ) ?
71412bb5b78SClemens Ladisch 			(((reg & AD_DS_RAMC_ACRQ >> 4) & 0x01) ? 12 : 18) : 4;
71512bb5b78SClemens Ladisch 	tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1;
71612bb5b78SClemens Ladisch 
71712bb5b78SClemens Ladisch 	snd_iprintf(buffer, "ADC FIFO: %d %s words\n\n", tmp,
71812bb5b78SClemens Ladisch 			(reg & AD_DS_RAMC_ADST) ? "stereo" : "mono");
71912bb5b78SClemens Ladisch 
72012bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Resampler input: %s\n",
72112bb5b78SClemens Ladisch 			reg & AD_DS_RAMC_REEN ? "enabled" : "disabled");
72212bb5b78SClemens Ladisch 
72312bb5b78SClemens Ladisch 	/* RERQ is at offset 12 */
72412bb5b78SClemens Ladisch 	tmp = (reg & AD_DS_RAMC_RERQ) ?
72512bb5b78SClemens Ladisch 			(((reg & AD_DS_RAMC_RERQ >> 12) & 0x01) ? 12 : 18) : 4;
72612bb5b78SClemens Ladisch 	tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1;
72712bb5b78SClemens Ladisch 
72812bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Resampler FIFO: %d %s words\n\n", tmp,
72912bb5b78SClemens Ladisch 			(reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
73012bb5b78SClemens Ladisch 
73112bb5b78SClemens Ladisch 
73212bb5b78SClemens Ladisch 	/* doc says LSB represents -1.5dB, but the max value (-94.5dB)
73312bb5b78SClemens Ladisch 	suggests that LSB is -3dB, which is more coherent with the logarithmic
73412bb5b78SClemens Ladisch 	nature of the dB scale */
73512bb5b78SClemens Ladisch 	reg = ad1889_readw(chip, AD_DS_WADA);
73612bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Left: %s, -%d dB\n",
73712bb5b78SClemens Ladisch 			(reg & AD_DS_WADA_LWAM) ? "mute" : "unmute",
73812bb5b78SClemens Ladisch 			((reg & AD_DS_WADA_LWAA) >> 8) * 3);
73912bb5b78SClemens Ladisch 	reg = ad1889_readw(chip, AD_DS_WADA);
74012bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Right: %s, -%d dB\n",
74112bb5b78SClemens Ladisch 			(reg & AD_DS_WADA_RWAM) ? "mute" : "unmute",
74212bb5b78SClemens Ladisch 			((reg & AD_DS_WADA_RWAA) >> 8) * 3);
74312bb5b78SClemens Ladisch 
74412bb5b78SClemens Ladisch 	reg = ad1889_readw(chip, AD_DS_WAS);
74512bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Wave samplerate: %u Hz\n", reg);
74612bb5b78SClemens Ladisch 	reg = ad1889_readw(chip, AD_DS_RES);
74712bb5b78SClemens Ladisch 	snd_iprintf(buffer, "Resampler samplerate: %u Hz\n", reg);
74812bb5b78SClemens Ladisch }
74912bb5b78SClemens Ladisch 
75012bb5b78SClemens Ladisch static void __devinit
75112bb5b78SClemens Ladisch snd_ad1889_proc_init(struct snd_ad1889 *chip)
75212bb5b78SClemens Ladisch {
75302c2de69STakashi Iwai 	struct snd_info_entry *entry;
75412bb5b78SClemens Ladisch 
75512bb5b78SClemens Ladisch 	if (!snd_card_proc_new(chip->card, chip->card->driver, &entry))
756bf850204STakashi Iwai 		snd_info_set_text_ops(entry, chip, snd_ad1889_proc_read);
75712bb5b78SClemens Ladisch }
75812bb5b78SClemens Ladisch 
75912bb5b78SClemens Ladisch static struct ac97_quirk ac97_quirks[] = {
76012bb5b78SClemens Ladisch 	{
76112bb5b78SClemens Ladisch 		.subvendor = 0x11d4,	/* AD */
76212bb5b78SClemens Ladisch 		.subdevice = 0x1889,	/* AD1889 */
76312bb5b78SClemens Ladisch 		.codec_id = AC97_ID_AD1819,
76412bb5b78SClemens Ladisch 		.name = "AD1889",
76512bb5b78SClemens Ladisch 		.type = AC97_TUNE_HP_ONLY
76612bb5b78SClemens Ladisch 	},
76712bb5b78SClemens Ladisch 	{ } /* terminator */
76812bb5b78SClemens Ladisch };
76912bb5b78SClemens Ladisch 
77012bb5b78SClemens Ladisch static void __devinit
77112bb5b78SClemens Ladisch snd_ad1889_ac97_xinit(struct snd_ad1889 *chip)
77212bb5b78SClemens Ladisch {
77312bb5b78SClemens Ladisch 	u16 reg;
77412bb5b78SClemens Ladisch 
77512bb5b78SClemens Ladisch 	reg = ad1889_readw(chip, AD_AC97_ACIC);
77612bb5b78SClemens Ladisch 	reg |= AD_AC97_ACIC_ACRD;		/* Reset Disable */
77712bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_AC97_ACIC, reg);
77812bb5b78SClemens Ladisch 	ad1889_readw(chip, AD_AC97_ACIC);	/* flush posted write */
77912bb5b78SClemens Ladisch 	udelay(10);
78012bb5b78SClemens Ladisch 	/* Interface Enable */
78112bb5b78SClemens Ladisch 	reg |= AD_AC97_ACIC_ACIE;
78212bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_AC97_ACIC, reg);
78312bb5b78SClemens Ladisch 
78412bb5b78SClemens Ladisch 	snd_ad1889_ac97_ready(chip);
78512bb5b78SClemens Ladisch 
78612bb5b78SClemens Ladisch 	/* Audio Stream Output | Variable Sample Rate Mode */
78712bb5b78SClemens Ladisch 	reg = ad1889_readw(chip, AD_AC97_ACIC);
78812bb5b78SClemens Ladisch 	reg |= AD_AC97_ACIC_ASOE | AD_AC97_ACIC_VSRM;
78912bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_AC97_ACIC, reg);
79012bb5b78SClemens Ladisch 	ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */
79112bb5b78SClemens Ladisch 
79212bb5b78SClemens Ladisch }
79312bb5b78SClemens Ladisch 
79412bb5b78SClemens Ladisch static void
79502c2de69STakashi Iwai snd_ad1889_ac97_bus_free(struct snd_ac97_bus *bus)
79612bb5b78SClemens Ladisch {
79712bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = bus->private_data;
79812bb5b78SClemens Ladisch 	chip->ac97_bus = NULL;
79912bb5b78SClemens Ladisch }
80012bb5b78SClemens Ladisch 
80112bb5b78SClemens Ladisch static void
80202c2de69STakashi Iwai snd_ad1889_ac97_free(struct snd_ac97 *ac97)
80312bb5b78SClemens Ladisch {
80412bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = ac97->private_data;
80512bb5b78SClemens Ladisch 	chip->ac97 = NULL;
80612bb5b78SClemens Ladisch }
80712bb5b78SClemens Ladisch 
80812bb5b78SClemens Ladisch static int __devinit
80912bb5b78SClemens Ladisch snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override)
81012bb5b78SClemens Ladisch {
81112bb5b78SClemens Ladisch 	int err;
81202c2de69STakashi Iwai 	struct snd_ac97_template ac97;
81302c2de69STakashi Iwai 	static struct snd_ac97_bus_ops ops = {
81412bb5b78SClemens Ladisch 		.write = snd_ad1889_ac97_write,
81512bb5b78SClemens Ladisch 		.read = snd_ad1889_ac97_read,
81612bb5b78SClemens Ladisch 	};
81712bb5b78SClemens Ladisch 
81812bb5b78SClemens Ladisch 	/* doing that here, it works. */
81912bb5b78SClemens Ladisch 	snd_ad1889_ac97_xinit(chip);
82012bb5b78SClemens Ladisch 
82112bb5b78SClemens Ladisch 	err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus);
82212bb5b78SClemens Ladisch 	if (err < 0)
82312bb5b78SClemens Ladisch 		return err;
82412bb5b78SClemens Ladisch 
82512bb5b78SClemens Ladisch 	chip->ac97_bus->private_free = snd_ad1889_ac97_bus_free;
82612bb5b78SClemens Ladisch 
82712bb5b78SClemens Ladisch 	memset(&ac97, 0, sizeof(ac97));
82812bb5b78SClemens Ladisch 	ac97.private_data = chip;
82912bb5b78SClemens Ladisch 	ac97.private_free = snd_ad1889_ac97_free;
83012bb5b78SClemens Ladisch 	ac97.pci = chip->pci;
83112bb5b78SClemens Ladisch 
83212bb5b78SClemens Ladisch 	err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
83312bb5b78SClemens Ladisch 	if (err < 0)
83412bb5b78SClemens Ladisch 		return err;
83512bb5b78SClemens Ladisch 
83612bb5b78SClemens Ladisch 	snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override);
83712bb5b78SClemens Ladisch 
83812bb5b78SClemens Ladisch 	return 0;
83912bb5b78SClemens Ladisch }
84012bb5b78SClemens Ladisch 
84112bb5b78SClemens Ladisch static int
84212bb5b78SClemens Ladisch snd_ad1889_free(struct snd_ad1889 *chip)
84312bb5b78SClemens Ladisch {
84412bb5b78SClemens Ladisch 	if (chip->irq < 0)
84512bb5b78SClemens Ladisch 		goto skip_hw;
84612bb5b78SClemens Ladisch 
84712bb5b78SClemens Ladisch 	spin_lock_irq(&chip->lock);
84812bb5b78SClemens Ladisch 
84912bb5b78SClemens Ladisch 	ad1889_mute(chip);
85012bb5b78SClemens Ladisch 
85112bb5b78SClemens Ladisch 	/* Turn off interrupt on count and zero DMA registers */
85212bb5b78SClemens Ladisch 	ad1889_channel_reset(chip, AD_CHAN_WAV | AD_CHAN_ADC);
85312bb5b78SClemens Ladisch 
85412bb5b78SClemens Ladisch 	/* clear DISR. If we don't, we'd better jump off the Eiffel Tower */
85512bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PTAI | AD_DMA_DISR_PMAI);
85612bb5b78SClemens Ladisch 	ad1889_readl(chip, AD_DMA_DISR);	/* flush, dammit! */
85712bb5b78SClemens Ladisch 
85812bb5b78SClemens Ladisch 	spin_unlock_irq(&chip->lock);
85912bb5b78SClemens Ladisch 
86012bb5b78SClemens Ladisch 	if (chip->irq >= 0)
861437a5a46STakashi Iwai 		free_irq(chip->irq, chip);
86212bb5b78SClemens Ladisch 
86312bb5b78SClemens Ladisch skip_hw:
86412bb5b78SClemens Ladisch 	if (chip->iobase)
86512bb5b78SClemens Ladisch 		iounmap(chip->iobase);
86612bb5b78SClemens Ladisch 
86712bb5b78SClemens Ladisch 	pci_release_regions(chip->pci);
86812bb5b78SClemens Ladisch 	pci_disable_device(chip->pci);
86912bb5b78SClemens Ladisch 
87012bb5b78SClemens Ladisch 	kfree(chip);
87112bb5b78SClemens Ladisch 	return 0;
87212bb5b78SClemens Ladisch }
87312bb5b78SClemens Ladisch 
874f40b6890STakashi Iwai static int
87502c2de69STakashi Iwai snd_ad1889_dev_free(struct snd_device *device)
87612bb5b78SClemens Ladisch {
87712bb5b78SClemens Ladisch 	struct snd_ad1889 *chip = device->device_data;
87812bb5b78SClemens Ladisch 	return snd_ad1889_free(chip);
87912bb5b78SClemens Ladisch }
88012bb5b78SClemens Ladisch 
88112bb5b78SClemens Ladisch static int __devinit
88212bb5b78SClemens Ladisch snd_ad1889_init(struct snd_ad1889 *chip)
88312bb5b78SClemens Ladisch {
88412bb5b78SClemens Ladisch 	ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */
88512bb5b78SClemens Ladisch 	ad1889_readw(chip, AD_DS_CCS);	/* flush posted write */
88612bb5b78SClemens Ladisch 
88712bb5b78SClemens Ladisch 	mdelay(10);
88812bb5b78SClemens Ladisch 
88912bb5b78SClemens Ladisch 	/* enable Master and Target abort interrupts */
89012bb5b78SClemens Ladisch 	ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PMAE | AD_DMA_DISR_PTAE);
89112bb5b78SClemens Ladisch 
89212bb5b78SClemens Ladisch 	return 0;
89312bb5b78SClemens Ladisch }
89412bb5b78SClemens Ladisch 
89512bb5b78SClemens Ladisch static int __devinit
89602c2de69STakashi Iwai snd_ad1889_create(struct snd_card *card,
89712bb5b78SClemens Ladisch 		  struct pci_dev *pci,
89812bb5b78SClemens Ladisch 		  struct snd_ad1889 **rchip)
89912bb5b78SClemens Ladisch {
90012bb5b78SClemens Ladisch 	int err;
90112bb5b78SClemens Ladisch 
90212bb5b78SClemens Ladisch 	struct snd_ad1889 *chip;
90302c2de69STakashi Iwai 	static struct snd_device_ops ops = {
90412bb5b78SClemens Ladisch 		.dev_free = snd_ad1889_dev_free,
90512bb5b78SClemens Ladisch 	};
90612bb5b78SClemens Ladisch 
90712bb5b78SClemens Ladisch 	*rchip = NULL;
90812bb5b78SClemens Ladisch 
90912bb5b78SClemens Ladisch 	if ((err = pci_enable_device(pci)) < 0)
91012bb5b78SClemens Ladisch 		return err;
91112bb5b78SClemens Ladisch 
91212bb5b78SClemens Ladisch 	/* check PCI availability (32bit DMA) */
913284901a9SYang Hongyang 	if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 ||
914284901a9SYang Hongyang 	    pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
91512bb5b78SClemens Ladisch 		printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n");
91612bb5b78SClemens Ladisch 		pci_disable_device(pci);
91712bb5b78SClemens Ladisch 		return -ENXIO;
91812bb5b78SClemens Ladisch 	}
91912bb5b78SClemens Ladisch 
92012bb5b78SClemens Ladisch 	/* allocate chip specific data with zero-filled memory */
921e560d8d8STakashi Iwai 	if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
92212bb5b78SClemens Ladisch 		pci_disable_device(pci);
92312bb5b78SClemens Ladisch 		return -ENOMEM;
92412bb5b78SClemens Ladisch 	}
92512bb5b78SClemens Ladisch 
92612bb5b78SClemens Ladisch 	chip->card = card;
92712bb5b78SClemens Ladisch 	card->private_data = chip;
92812bb5b78SClemens Ladisch 	chip->pci = pci;
92912bb5b78SClemens Ladisch 	chip->irq = -1;
93012bb5b78SClemens Ladisch 
93112bb5b78SClemens Ladisch 	/* (1) PCI resource allocation */
93212bb5b78SClemens Ladisch 	if ((err = pci_request_regions(pci, card->driver)) < 0)
93312bb5b78SClemens Ladisch 		goto free_and_ret;
93412bb5b78SClemens Ladisch 
93512bb5b78SClemens Ladisch 	chip->bar = pci_resource_start(pci, 0);
9362f5ad54eSArjan van de Ven 	chip->iobase = pci_ioremap_bar(pci, 0);
93712bb5b78SClemens Ladisch 	if (chip->iobase == NULL) {
93812bb5b78SClemens Ladisch 		printk(KERN_ERR PFX "unable to reserve region.\n");
93912bb5b78SClemens Ladisch 		err = -EBUSY;
94012bb5b78SClemens Ladisch 		goto free_and_ret;
94112bb5b78SClemens Ladisch 	}
94212bb5b78SClemens Ladisch 
94312bb5b78SClemens Ladisch 	pci_set_master(pci);
94412bb5b78SClemens Ladisch 
94512bb5b78SClemens Ladisch 	spin_lock_init(&chip->lock);	/* only now can we call ad1889_free */
94612bb5b78SClemens Ladisch 
94712bb5b78SClemens Ladisch 	if (request_irq(pci->irq, snd_ad1889_interrupt,
948934c2b6dSTakashi Iwai 			IRQF_SHARED, KBUILD_MODNAME, chip)) {
94912bb5b78SClemens Ladisch 		printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
95012bb5b78SClemens Ladisch 		snd_ad1889_free(chip);
95112bb5b78SClemens Ladisch 		return -EBUSY;
95212bb5b78SClemens Ladisch 	}
95312bb5b78SClemens Ladisch 
95412bb5b78SClemens Ladisch 	chip->irq = pci->irq;
95512bb5b78SClemens Ladisch 	synchronize_irq(chip->irq);
95612bb5b78SClemens Ladisch 
95712bb5b78SClemens Ladisch 	/* (2) initialization of the chip hardware */
95812bb5b78SClemens Ladisch 	if ((err = snd_ad1889_init(chip)) < 0) {
95912bb5b78SClemens Ladisch 		snd_ad1889_free(chip);
96012bb5b78SClemens Ladisch 		return err;
96112bb5b78SClemens Ladisch 	}
96212bb5b78SClemens Ladisch 
96312bb5b78SClemens Ladisch 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
96412bb5b78SClemens Ladisch 		snd_ad1889_free(chip);
96512bb5b78SClemens Ladisch 		return err;
96612bb5b78SClemens Ladisch 	}
96712bb5b78SClemens Ladisch 
96812bb5b78SClemens Ladisch 	snd_card_set_dev(card, &pci->dev);
96912bb5b78SClemens Ladisch 
97012bb5b78SClemens Ladisch 	*rchip = chip;
97112bb5b78SClemens Ladisch 
97212bb5b78SClemens Ladisch 	return 0;
97312bb5b78SClemens Ladisch 
97412bb5b78SClemens Ladisch free_and_ret:
97512bb5b78SClemens Ladisch 	kfree(chip);
97612bb5b78SClemens Ladisch 	pci_disable_device(pci);
97712bb5b78SClemens Ladisch 
97812bb5b78SClemens Ladisch 	return err;
97912bb5b78SClemens Ladisch }
98012bb5b78SClemens Ladisch 
98112bb5b78SClemens Ladisch static int __devinit
98212bb5b78SClemens Ladisch snd_ad1889_probe(struct pci_dev *pci,
98312bb5b78SClemens Ladisch 		 const struct pci_device_id *pci_id)
98412bb5b78SClemens Ladisch {
98512bb5b78SClemens Ladisch 	int err;
98612bb5b78SClemens Ladisch 	static int devno;
98702c2de69STakashi Iwai 	struct snd_card *card;
98812bb5b78SClemens Ladisch 	struct snd_ad1889 *chip;
98912bb5b78SClemens Ladisch 
99012bb5b78SClemens Ladisch 	/* (1) */
99112bb5b78SClemens Ladisch 	if (devno >= SNDRV_CARDS)
99212bb5b78SClemens Ladisch 		return -ENODEV;
99312bb5b78SClemens Ladisch 	if (!enable[devno]) {
99412bb5b78SClemens Ladisch 		devno++;
99512bb5b78SClemens Ladisch 		return -ENOENT;
99612bb5b78SClemens Ladisch 	}
99712bb5b78SClemens Ladisch 
99812bb5b78SClemens Ladisch 	/* (2) */
999e58de7baSTakashi Iwai 	err = snd_card_create(index[devno], id[devno], THIS_MODULE, 0, &card);
100012bb5b78SClemens Ladisch 	/* XXX REVISIT: we can probably allocate chip in this call */
1001e58de7baSTakashi Iwai 	if (err < 0)
1002e58de7baSTakashi Iwai 		return err;
100312bb5b78SClemens Ladisch 
100412bb5b78SClemens Ladisch 	strcpy(card->driver, "AD1889");
100512bb5b78SClemens Ladisch 	strcpy(card->shortname, "Analog Devices AD1889");
100612bb5b78SClemens Ladisch 
100712bb5b78SClemens Ladisch 	/* (3) */
100812bb5b78SClemens Ladisch 	err = snd_ad1889_create(card, pci, &chip);
100912bb5b78SClemens Ladisch 	if (err < 0)
101012bb5b78SClemens Ladisch 		goto free_and_ret;
101112bb5b78SClemens Ladisch 
101212bb5b78SClemens Ladisch 	/* (4) */
101312bb5b78SClemens Ladisch 	sprintf(card->longname, "%s at 0x%lx irq %i",
101412bb5b78SClemens Ladisch 		card->shortname, chip->bar, chip->irq);
101512bb5b78SClemens Ladisch 
101612bb5b78SClemens Ladisch 	/* (5) */
101712bb5b78SClemens Ladisch 	/* register AC97 mixer */
101812bb5b78SClemens Ladisch 	err = snd_ad1889_ac97_init(chip, ac97_quirk[devno]);
101912bb5b78SClemens Ladisch 	if (err < 0)
102012bb5b78SClemens Ladisch 		goto free_and_ret;
102112bb5b78SClemens Ladisch 
102212bb5b78SClemens Ladisch 	err = snd_ad1889_pcm_init(chip, 0, NULL);
102312bb5b78SClemens Ladisch 	if (err < 0)
102412bb5b78SClemens Ladisch 		goto free_and_ret;
102512bb5b78SClemens Ladisch 
102612bb5b78SClemens Ladisch 	/* register proc interface */
102712bb5b78SClemens Ladisch 	snd_ad1889_proc_init(chip);
102812bb5b78SClemens Ladisch 
102912bb5b78SClemens Ladisch 	/* (6) */
103012bb5b78SClemens Ladisch 	err = snd_card_register(card);
103112bb5b78SClemens Ladisch 	if (err < 0)
103212bb5b78SClemens Ladisch 		goto free_and_ret;
103312bb5b78SClemens Ladisch 
103412bb5b78SClemens Ladisch 	/* (7) */
103512bb5b78SClemens Ladisch 	pci_set_drvdata(pci, card);
103612bb5b78SClemens Ladisch 
103712bb5b78SClemens Ladisch 	devno++;
103812bb5b78SClemens Ladisch 	return 0;
103912bb5b78SClemens Ladisch 
104012bb5b78SClemens Ladisch free_and_ret:
104112bb5b78SClemens Ladisch 	snd_card_free(card);
104212bb5b78SClemens Ladisch 	return err;
104312bb5b78SClemens Ladisch }
104412bb5b78SClemens Ladisch 
104512bb5b78SClemens Ladisch static void __devexit
104612bb5b78SClemens Ladisch snd_ad1889_remove(struct pci_dev *pci)
104712bb5b78SClemens Ladisch {
104812bb5b78SClemens Ladisch 	snd_card_free(pci_get_drvdata(pci));
104912bb5b78SClemens Ladisch 	pci_set_drvdata(pci, NULL);
105012bb5b78SClemens Ladisch }
105112bb5b78SClemens Ladisch 
1052cebe41d4SAlexey Dobriyan static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = {
105312bb5b78SClemens Ladisch 	{ PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
105412bb5b78SClemens Ladisch 	{ 0, },
105512bb5b78SClemens Ladisch };
105612bb5b78SClemens Ladisch MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
105712bb5b78SClemens Ladisch 
1058e4d76815SRandy Dunlap static struct pci_driver ad1889_pci_driver = {
10593733e424STakashi Iwai 	.name = KBUILD_MODNAME,
106012bb5b78SClemens Ladisch 	.id_table = snd_ad1889_ids,
106112bb5b78SClemens Ladisch 	.probe = snd_ad1889_probe,
106212bb5b78SClemens Ladisch 	.remove = __devexit_p(snd_ad1889_remove),
106312bb5b78SClemens Ladisch };
106412bb5b78SClemens Ladisch 
106512bb5b78SClemens Ladisch static int __init
106612bb5b78SClemens Ladisch alsa_ad1889_init(void)
106712bb5b78SClemens Ladisch {
1068e4d76815SRandy Dunlap 	return pci_register_driver(&ad1889_pci_driver);
106912bb5b78SClemens Ladisch }
107012bb5b78SClemens Ladisch 
107112bb5b78SClemens Ladisch static void __exit
107212bb5b78SClemens Ladisch alsa_ad1889_fini(void)
107312bb5b78SClemens Ladisch {
1074e4d76815SRandy Dunlap 	pci_unregister_driver(&ad1889_pci_driver);
107512bb5b78SClemens Ladisch }
107612bb5b78SClemens Ladisch 
107712bb5b78SClemens Ladisch module_init(alsa_ad1889_init);
107812bb5b78SClemens Ladisch module_exit(alsa_ad1889_fini);
1079