diff options
Diffstat (limited to 'sound/pci/ad1889.c')
-rw-r--r-- | sound/pci/ad1889.c | 1089 |
1 files changed, 1089 insertions, 0 deletions
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c new file mode 100644 index 000000000000..37e8df24711c --- /dev/null +++ b/sound/pci/ad1889.c | |||
@@ -0,0 +1,1089 @@ | |||
1 | /* Analog Devices 1889 audio driver | ||
2 | * | ||
3 | * This is a driver for the AD1889 PCI audio chipset found | ||
4 | * on the HP PA-RISC [BCJ]-xxx0 workstations. | ||
5 | * | ||
6 | * Copyright (C) 2004-2005, Kyle McMartin <kyle@parisc-linux.org> | ||
7 | * Copyright (C) 2005, Thibaut Varene <varenet@parisc-linux.org> | ||
8 | * Based on the OSS AD1889 driver by Randolph Chung <tausq@debian.org> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License, version 2, as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | * TODO: | ||
24 | * Do we need to take care of CCS register? | ||
25 | * Maybe we could use finer grained locking (separate locks for pb/cap)? | ||
26 | * Wishlist: | ||
27 | * Control Interface (mixer) support | ||
28 | * Better AC97 support (VSR...)? | ||
29 | * PM support | ||
30 | * MIDI support | ||
31 | * Game Port support | ||
32 | * SG DMA support (this will need *alot* of work) | ||
33 | */ | ||
34 | |||
35 | #include <linux/init.h> | ||
36 | #include <linux/pci.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/interrupt.h> | ||
39 | #include <linux/compiler.h> | ||
40 | #include <linux/delay.h> | ||
41 | |||
42 | #include <sound/driver.h> | ||
43 | #include <sound/core.h> | ||
44 | #include <sound/pcm.h> | ||
45 | #include <sound/initval.h> | ||
46 | #include <sound/ac97_codec.h> | ||
47 | |||
48 | #include <asm/io.h> | ||
49 | |||
50 | #include "ad1889.h" | ||
51 | #include "ac97/ac97_id.h" | ||
52 | |||
53 | #define AD1889_DRVVER "$Revision: 1.1 $" | ||
54 | |||
55 | MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>"); | ||
56 | MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver"); | ||
57 | MODULE_LICENSE("GPL"); | ||
58 | MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1889}}"); | ||
59 | |||
60 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
61 | module_param_array(index, int, NULL, 0444); | ||
62 | MODULE_PARM_DESC(index, "Index value for the AD1889 soundcard."); | ||
63 | |||
64 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
65 | module_param_array(id, charp, NULL, 0444); | ||
66 | MODULE_PARM_DESC(id, "ID string for the AD1889 soundcard."); | ||
67 | |||
68 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
69 | module_param_array(enable, bool, NULL, 0444); | ||
70 | MODULE_PARM_DESC(enable, "Enable AD1889 soundcard."); | ||
71 | |||
72 | static char *ac97_quirk[SNDRV_CARDS]; | ||
73 | module_param_array(ac97_quirk, charp, NULL, 0444); | ||
74 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); | ||
75 | |||
76 | #define DEVNAME "ad1889" | ||
77 | #define PFX DEVNAME ": " | ||
78 | |||
79 | /* let's use the global sound debug interfaces */ | ||
80 | #define ad1889_debug(fmt, arg...) snd_printd(KERN_DEBUG fmt, ## arg) | ||
81 | |||
82 | /* keep track of some hw registers */ | ||
83 | struct ad1889_register_state { | ||
84 | u16 reg; /* reg setup */ | ||
85 | u32 addr; /* dma base address */ | ||
86 | unsigned long size; /* DMA buffer size */ | ||
87 | }; | ||
88 | |||
89 | struct snd_ad1889 { | ||
90 | snd_card_t *card; | ||
91 | struct pci_dev *pci; | ||
92 | |||
93 | int irq; | ||
94 | unsigned long bar; | ||
95 | void __iomem *iobase; | ||
96 | |||
97 | ac97_t *ac97; | ||
98 | ac97_bus_t *ac97_bus; | ||
99 | snd_pcm_t *pcm; | ||
100 | snd_info_entry_t *proc; | ||
101 | |||
102 | snd_pcm_substream_t *psubs; | ||
103 | snd_pcm_substream_t *csubs; | ||
104 | |||
105 | /* playback register state */ | ||
106 | struct ad1889_register_state wave; | ||
107 | struct ad1889_register_state ramc; | ||
108 | |||
109 | spinlock_t lock; | ||
110 | }; | ||
111 | |||
112 | static inline u16 | ||
113 | ad1889_readw(struct snd_ad1889 *chip, unsigned reg) | ||
114 | { | ||
115 | return readw(chip->iobase + reg); | ||
116 | } | ||
117 | |||
118 | static inline void | ||
119 | ad1889_writew(struct snd_ad1889 *chip, unsigned reg, u16 val) | ||
120 | { | ||
121 | writew(val, chip->iobase + reg); | ||
122 | } | ||
123 | |||
124 | static inline u32 | ||
125 | ad1889_readl(struct snd_ad1889 *chip, unsigned reg) | ||
126 | { | ||
127 | return readl(chip->iobase + reg); | ||
128 | } | ||
129 | |||
130 | static inline void | ||
131 | ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val) | ||
132 | { | ||
133 | writel(val, chip->iobase + reg); | ||
134 | } | ||
135 | |||
136 | static inline void | ||
137 | ad1889_unmute(struct snd_ad1889 *chip) | ||
138 | { | ||
139 | u16 st; | ||
140 | st = ad1889_readw(chip, AD_DS_WADA) & | ||
141 | ~(AD_DS_WADA_RWAM | AD_DS_WADA_LWAM); | ||
142 | ad1889_writew(chip, AD_DS_WADA, st); | ||
143 | ad1889_readw(chip, AD_DS_WADA); | ||
144 | } | ||
145 | |||
146 | static inline void | ||
147 | ad1889_mute(struct snd_ad1889 *chip) | ||
148 | { | ||
149 | u16 st; | ||
150 | st = ad1889_readw(chip, AD_DS_WADA) | AD_DS_WADA_RWAM | AD_DS_WADA_LWAM; | ||
151 | ad1889_writew(chip, AD_DS_WADA, st); | ||
152 | ad1889_readw(chip, AD_DS_WADA); | ||
153 | } | ||
154 | |||
155 | static inline void | ||
156 | ad1889_load_adc_buffer_address(struct snd_ad1889 *chip, u32 address) | ||
157 | { | ||
158 | ad1889_writel(chip, AD_DMA_ADCBA, address); | ||
159 | ad1889_writel(chip, AD_DMA_ADCCA, address); | ||
160 | } | ||
161 | |||
162 | static inline void | ||
163 | ad1889_load_adc_buffer_count(struct snd_ad1889 *chip, u32 count) | ||
164 | { | ||
165 | ad1889_writel(chip, AD_DMA_ADCBC, count); | ||
166 | ad1889_writel(chip, AD_DMA_ADCCC, count); | ||
167 | } | ||
168 | |||
169 | static inline void | ||
170 | ad1889_load_adc_interrupt_count(struct snd_ad1889 *chip, u32 count) | ||
171 | { | ||
172 | ad1889_writel(chip, AD_DMA_ADCIB, count); | ||
173 | ad1889_writel(chip, AD_DMA_ADCIC, count); | ||
174 | } | ||
175 | |||
176 | static inline void | ||
177 | ad1889_load_wave_buffer_address(struct snd_ad1889 *chip, u32 address) | ||
178 | { | ||
179 | ad1889_writel(chip, AD_DMA_WAVBA, address); | ||
180 | ad1889_writel(chip, AD_DMA_WAVCA, address); | ||
181 | } | ||
182 | |||
183 | static inline void | ||
184 | ad1889_load_wave_buffer_count(struct snd_ad1889 *chip, u32 count) | ||
185 | { | ||
186 | ad1889_writel(chip, AD_DMA_WAVBC, count); | ||
187 | ad1889_writel(chip, AD_DMA_WAVCC, count); | ||
188 | } | ||
189 | |||
190 | static inline void | ||
191 | ad1889_load_wave_interrupt_count(struct snd_ad1889 *chip, u32 count) | ||
192 | { | ||
193 | ad1889_writel(chip, AD_DMA_WAVIB, count); | ||
194 | ad1889_writel(chip, AD_DMA_WAVIC, count); | ||
195 | } | ||
196 | |||
197 | static void | ||
198 | ad1889_channel_reset(struct snd_ad1889 *chip, unsigned int channel) | ||
199 | { | ||
200 | u16 reg; | ||
201 | |||
202 | if (channel & AD_CHAN_WAV) { | ||
203 | /* Disable wave channel */ | ||
204 | reg = ad1889_readw(chip, AD_DS_WSMC) & ~AD_DS_WSMC_WAEN; | ||
205 | ad1889_writew(chip, AD_DS_WSMC, reg); | ||
206 | chip->wave.reg = reg; | ||
207 | |||
208 | /* disable IRQs */ | ||
209 | reg = ad1889_readw(chip, AD_DMA_WAV); | ||
210 | reg &= AD_DMA_IM_DIS; | ||
211 | reg &= ~AD_DMA_LOOP; | ||
212 | ad1889_writew(chip, AD_DMA_WAV, reg); | ||
213 | |||
214 | /* clear IRQ and address counters and pointers */ | ||
215 | ad1889_load_wave_buffer_address(chip, 0x0); | ||
216 | ad1889_load_wave_buffer_count(chip, 0x0); | ||
217 | ad1889_load_wave_interrupt_count(chip, 0x0); | ||
218 | |||
219 | /* flush */ | ||
220 | ad1889_readw(chip, AD_DMA_WAV); | ||
221 | } | ||
222 | |||
223 | if (channel & AD_CHAN_ADC) { | ||
224 | /* Disable ADC channel */ | ||
225 | reg = ad1889_readw(chip, AD_DS_RAMC) & ~AD_DS_RAMC_ADEN; | ||
226 | ad1889_writew(chip, AD_DS_RAMC, reg); | ||
227 | chip->ramc.reg = reg; | ||
228 | |||
229 | reg = ad1889_readw(chip, AD_DMA_ADC); | ||
230 | reg &= AD_DMA_IM_DIS; | ||
231 | reg &= ~AD_DMA_LOOP; | ||
232 | ad1889_writew(chip, AD_DMA_ADC, reg); | ||
233 | |||
234 | ad1889_load_adc_buffer_address(chip, 0x0); | ||
235 | ad1889_load_adc_buffer_count(chip, 0x0); | ||
236 | ad1889_load_adc_interrupt_count(chip, 0x0); | ||
237 | |||
238 | /* flush */ | ||
239 | ad1889_readw(chip, AD_DMA_ADC); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | static inline u16 | ||
244 | snd_ad1889_ac97_read(ac97_t *ac97, unsigned short reg) | ||
245 | { | ||
246 | struct snd_ad1889 *chip = ac97->private_data; | ||
247 | return ad1889_readw(chip, AD_AC97_BASE + reg); | ||
248 | } | ||
249 | |||
250 | static inline void | ||
251 | snd_ad1889_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val) | ||
252 | { | ||
253 | struct snd_ad1889 *chip = ac97->private_data; | ||
254 | ad1889_writew(chip, AD_AC97_BASE + reg, val); | ||
255 | } | ||
256 | |||
257 | static int | ||
258 | snd_ad1889_ac97_ready(struct snd_ad1889 *chip) | ||
259 | { | ||
260 | int retry = 400; /* average needs 352 msec */ | ||
261 | |||
262 | while (!(ad1889_readw(chip, AD_AC97_ACIC) & AD_AC97_ACIC_ACRDY) | ||
263 | && --retry) | ||
264 | mdelay(1); | ||
265 | if (!retry) { | ||
266 | snd_printk(KERN_ERR PFX "[%s] Link is not ready.\n", | ||
267 | __FUNCTION__); | ||
268 | return -EIO; | ||
269 | } | ||
270 | ad1889_debug("[%s] ready after %d ms\n", __FUNCTION__, 400 - retry); | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static int | ||
276 | snd_ad1889_hw_params(snd_pcm_substream_t *substream, | ||
277 | snd_pcm_hw_params_t *hw_params) | ||
278 | { | ||
279 | return snd_pcm_lib_malloc_pages(substream, | ||
280 | params_buffer_bytes(hw_params)); | ||
281 | } | ||
282 | |||
283 | static int | ||
284 | snd_ad1889_hw_free(snd_pcm_substream_t *substream) | ||
285 | { | ||
286 | return snd_pcm_lib_free_pages(substream); | ||
287 | } | ||
288 | |||
289 | static snd_pcm_hardware_t snd_ad1889_playback_hw = { | ||
290 | .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | ||
291 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, | ||
292 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
293 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | ||
294 | .rate_min = 8000, /* docs say 7000, but we're lazy */ | ||
295 | .rate_max = 48000, | ||
296 | .channels_min = 1, | ||
297 | .channels_max = 2, | ||
298 | .buffer_bytes_max = BUFFER_BYTES_MAX, | ||
299 | .period_bytes_min = PERIOD_BYTES_MIN, | ||
300 | .period_bytes_max = PERIOD_BYTES_MAX, | ||
301 | .periods_min = PERIODS_MIN, | ||
302 | .periods_max = PERIODS_MAX, | ||
303 | /*.fifo_size = 0,*/ | ||
304 | }; | ||
305 | |||
306 | static snd_pcm_hardware_t snd_ad1889_capture_hw = { | ||
307 | .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | ||
308 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, | ||
309 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
310 | .rates = SNDRV_PCM_RATE_48000, | ||
311 | .rate_min = 48000, /* docs say we could to VSR, but we're lazy */ | ||
312 | .rate_max = 48000, | ||
313 | .channels_min = 1, | ||
314 | .channels_max = 2, | ||
315 | .buffer_bytes_max = BUFFER_BYTES_MAX, | ||
316 | .period_bytes_min = PERIOD_BYTES_MIN, | ||
317 | .period_bytes_max = PERIOD_BYTES_MAX, | ||
318 | .periods_min = PERIODS_MIN, | ||
319 | .periods_max = PERIODS_MAX, | ||
320 | /*.fifo_size = 0,*/ | ||
321 | }; | ||
322 | |||
323 | static int | ||
324 | snd_ad1889_playback_open(snd_pcm_substream_t *ss) | ||
325 | { | ||
326 | struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); | ||
327 | snd_pcm_runtime_t *rt = ss->runtime; | ||
328 | |||
329 | chip->psubs = ss; | ||
330 | rt->hw = snd_ad1889_playback_hw; | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int | ||
336 | snd_ad1889_capture_open(snd_pcm_substream_t *ss) | ||
337 | { | ||
338 | struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); | ||
339 | snd_pcm_runtime_t *rt = ss->runtime; | ||
340 | |||
341 | chip->csubs = ss; | ||
342 | rt->hw = snd_ad1889_capture_hw; | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | static int | ||
348 | snd_ad1889_playback_close(snd_pcm_substream_t *ss) | ||
349 | { | ||
350 | struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); | ||
351 | chip->psubs = NULL; | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static int | ||
356 | snd_ad1889_capture_close(snd_pcm_substream_t *ss) | ||
357 | { | ||
358 | struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); | ||
359 | chip->csubs = NULL; | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static int | ||
364 | snd_ad1889_playback_prepare(snd_pcm_substream_t *ss) | ||
365 | { | ||
366 | struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); | ||
367 | snd_pcm_runtime_t *rt = ss->runtime; | ||
368 | unsigned int size = snd_pcm_lib_buffer_bytes(ss); | ||
369 | unsigned int count = snd_pcm_lib_period_bytes(ss); | ||
370 | u16 reg; | ||
371 | |||
372 | ad1889_channel_reset(chip, AD_CHAN_WAV); | ||
373 | |||
374 | reg = ad1889_readw(chip, AD_DS_WSMC); | ||
375 | |||
376 | /* Mask out 16-bit / Stereo */ | ||
377 | reg &= ~(AD_DS_WSMC_WA16 | AD_DS_WSMC_WAST); | ||
378 | |||
379 | if (snd_pcm_format_width(rt->format) == 16) | ||
380 | reg |= AD_DS_WSMC_WA16; | ||
381 | |||
382 | if (rt->channels > 1) | ||
383 | reg |= AD_DS_WSMC_WAST; | ||
384 | |||
385 | /* let's make sure we don't clobber ourselves */ | ||
386 | spin_lock_irq(&chip->lock); | ||
387 | |||
388 | chip->wave.size = size; | ||
389 | chip->wave.reg = reg; | ||
390 | chip->wave.addr = rt->dma_addr; | ||
391 | |||
392 | ad1889_writew(chip, AD_DS_WSMC, chip->wave.reg); | ||
393 | |||
394 | /* Set sample rates on the codec */ | ||
395 | ad1889_writew(chip, AD_DS_WAS, rt->rate); | ||
396 | |||
397 | /* Set up DMA */ | ||
398 | ad1889_load_wave_buffer_address(chip, chip->wave.addr); | ||
399 | ad1889_load_wave_buffer_count(chip, size); | ||
400 | ad1889_load_wave_interrupt_count(chip, count); | ||
401 | |||
402 | /* writes flush */ | ||
403 | ad1889_readw(chip, AD_DS_WSMC); | ||
404 | |||
405 | spin_unlock_irq(&chip->lock); | ||
406 | |||
407 | ad1889_debug("prepare playback: addr = 0x%x, count = %u, " | ||
408 | "size = %u, reg = 0x%x, rate = %u\n", chip->wave.addr, | ||
409 | count, size, reg, rt->rate); | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static int | ||
414 | snd_ad1889_capture_prepare(snd_pcm_substream_t *ss) | ||
415 | { | ||
416 | struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); | ||
417 | snd_pcm_runtime_t *rt = ss->runtime; | ||
418 | unsigned int size = snd_pcm_lib_buffer_bytes(ss); | ||
419 | unsigned int count = snd_pcm_lib_period_bytes(ss); | ||
420 | u16 reg; | ||
421 | |||
422 | ad1889_channel_reset(chip, AD_CHAN_ADC); | ||
423 | |||
424 | reg = ad1889_readw(chip, AD_DS_RAMC); | ||
425 | |||
426 | /* Mask out 16-bit / Stereo */ | ||
427 | reg &= ~(AD_DS_RAMC_AD16 | AD_DS_RAMC_ADST); | ||
428 | |||
429 | if (snd_pcm_format_width(rt->format) == 16) | ||
430 | reg |= AD_DS_RAMC_AD16; | ||
431 | |||
432 | if (rt->channels > 1) | ||
433 | reg |= AD_DS_RAMC_ADST; | ||
434 | |||
435 | /* let's make sure we don't clobber ourselves */ | ||
436 | spin_lock_irq(&chip->lock); | ||
437 | |||
438 | chip->ramc.size = size; | ||
439 | chip->ramc.reg = reg; | ||
440 | chip->ramc.addr = rt->dma_addr; | ||
441 | |||
442 | ad1889_writew(chip, AD_DS_RAMC, chip->ramc.reg); | ||
443 | |||
444 | /* Set up DMA */ | ||
445 | ad1889_load_adc_buffer_address(chip, chip->ramc.addr); | ||
446 | ad1889_load_adc_buffer_count(chip, size); | ||
447 | ad1889_load_adc_interrupt_count(chip, count); | ||
448 | |||
449 | /* writes flush */ | ||
450 | ad1889_readw(chip, AD_DS_RAMC); | ||
451 | |||
452 | spin_unlock_irq(&chip->lock); | ||
453 | |||
454 | ad1889_debug("prepare capture: addr = 0x%x, count = %u, " | ||
455 | "size = %u, reg = 0x%x, rate = %u\n", chip->ramc.addr, | ||
456 | count, size, reg, rt->rate); | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | /* this is called in atomic context with IRQ disabled. | ||
461 | Must be as fast as possible and not sleep. | ||
462 | DMA should be *triggered* by this call. | ||
463 | The WSMC "WAEN" bit triggers DMA Wave On/Off */ | ||
464 | static int | ||
465 | snd_ad1889_playback_trigger(snd_pcm_substream_t *ss, int cmd) | ||
466 | { | ||
467 | u16 wsmc; | ||
468 | struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); | ||
469 | |||
470 | wsmc = ad1889_readw(chip, AD_DS_WSMC); | ||
471 | |||
472 | switch (cmd) { | ||
473 | case SNDRV_PCM_TRIGGER_START: | ||
474 | /* enable DMA loop & interrupts */ | ||
475 | ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT); | ||
476 | wsmc |= AD_DS_WSMC_WAEN; | ||
477 | /* 1 to clear CHSS bit */ | ||
478 | ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS); | ||
479 | ad1889_unmute(chip); | ||
480 | break; | ||
481 | case SNDRV_PCM_TRIGGER_STOP: | ||
482 | ad1889_mute(chip); | ||
483 | wsmc &= ~AD_DS_WSMC_WAEN; | ||
484 | break; | ||
485 | default: | ||
486 | snd_BUG(); | ||
487 | return -EINVAL; | ||
488 | } | ||
489 | |||
490 | chip->wave.reg = wsmc; | ||
491 | ad1889_writew(chip, AD_DS_WSMC, wsmc); | ||
492 | ad1889_readw(chip, AD_DS_WSMC); /* flush */ | ||
493 | |||
494 | /* reset the chip when STOP - will disable IRQs */ | ||
495 | if (cmd == SNDRV_PCM_TRIGGER_STOP) | ||
496 | ad1889_channel_reset(chip, AD_CHAN_WAV); | ||
497 | |||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | /* this is called in atomic context with IRQ disabled. | ||
502 | Must be as fast as possible and not sleep. | ||
503 | DMA should be *triggered* by this call. | ||
504 | The RAMC "ADEN" bit triggers DMA ADC On/Off */ | ||
505 | static int | ||
506 | snd_ad1889_capture_trigger(snd_pcm_substream_t *ss, int cmd) | ||
507 | { | ||
508 | u16 ramc; | ||
509 | struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); | ||
510 | |||
511 | ramc = ad1889_readw(chip, AD_DS_RAMC); | ||
512 | |||
513 | switch (cmd) { | ||
514 | case SNDRV_PCM_TRIGGER_START: | ||
515 | /* enable DMA loop & interrupts */ | ||
516 | ad1889_writew(chip, AD_DMA_ADC, AD_DMA_LOOP | AD_DMA_IM_CNT); | ||
517 | ramc |= AD_DS_RAMC_ADEN; | ||
518 | /* 1 to clear CHSS bit */ | ||
519 | ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_ADCS); | ||
520 | break; | ||
521 | case SNDRV_PCM_TRIGGER_STOP: | ||
522 | ramc &= ~AD_DS_RAMC_ADEN; | ||
523 | break; | ||
524 | default: | ||
525 | return -EINVAL; | ||
526 | } | ||
527 | |||
528 | chip->ramc.reg = ramc; | ||
529 | ad1889_writew(chip, AD_DS_RAMC, ramc); | ||
530 | ad1889_readw(chip, AD_DS_RAMC); /* flush */ | ||
531 | |||
532 | /* reset the chip when STOP - will disable IRQs */ | ||
533 | if (cmd == SNDRV_PCM_TRIGGER_STOP) | ||
534 | ad1889_channel_reset(chip, AD_CHAN_ADC); | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | /* Called in atomic context with IRQ disabled */ | ||
540 | static snd_pcm_uframes_t | ||
541 | snd_ad1889_playback_pointer(snd_pcm_substream_t *ss) | ||
542 | { | ||
543 | size_t ptr = 0; | ||
544 | struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); | ||
545 | |||
546 | if (unlikely(!(chip->wave.reg & AD_DS_WSMC_WAEN))) | ||
547 | return 0; | ||
548 | |||
549 | ptr = ad1889_readl(chip, AD_DMA_WAVCA); | ||
550 | ptr -= chip->wave.addr; | ||
551 | |||
552 | snd_assert((ptr >= 0) && (ptr < chip->wave.size), return 0); | ||
553 | |||
554 | return bytes_to_frames(ss->runtime, ptr); | ||
555 | } | ||
556 | |||
557 | /* Called in atomic context with IRQ disabled */ | ||
558 | static snd_pcm_uframes_t | ||
559 | snd_ad1889_capture_pointer(snd_pcm_substream_t *ss) | ||
560 | { | ||
561 | size_t ptr = 0; | ||
562 | struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); | ||
563 | |||
564 | if (unlikely(!(chip->ramc.reg & AD_DS_RAMC_ADEN))) | ||
565 | return 0; | ||
566 | |||
567 | ptr = ad1889_readl(chip, AD_DMA_ADCCA); | ||
568 | ptr -= chip->ramc.addr; | ||
569 | |||
570 | snd_assert((ptr >= 0) && (ptr < chip->ramc.size), return 0); | ||
571 | |||
572 | return bytes_to_frames(ss->runtime, ptr); | ||
573 | } | ||
574 | |||
575 | static snd_pcm_ops_t snd_ad1889_playback_ops = { | ||
576 | .open = snd_ad1889_playback_open, | ||
577 | .close = snd_ad1889_playback_close, | ||
578 | .ioctl = snd_pcm_lib_ioctl, | ||
579 | .hw_params = snd_ad1889_hw_params, | ||
580 | .hw_free = snd_ad1889_hw_free, | ||
581 | .prepare = snd_ad1889_playback_prepare, | ||
582 | .trigger = snd_ad1889_playback_trigger, | ||
583 | .pointer = snd_ad1889_playback_pointer, | ||
584 | }; | ||
585 | |||
586 | static snd_pcm_ops_t snd_ad1889_capture_ops = { | ||
587 | .open = snd_ad1889_capture_open, | ||
588 | .close = snd_ad1889_capture_close, | ||
589 | .ioctl = snd_pcm_lib_ioctl, | ||
590 | .hw_params = snd_ad1889_hw_params, | ||
591 | .hw_free = snd_ad1889_hw_free, | ||
592 | .prepare = snd_ad1889_capture_prepare, | ||
593 | .trigger = snd_ad1889_capture_trigger, | ||
594 | .pointer = snd_ad1889_capture_pointer, | ||
595 | }; | ||
596 | |||
597 | static irqreturn_t | ||
598 | snd_ad1889_interrupt(int irq, | ||
599 | void *dev_id, | ||
600 | struct pt_regs *regs) | ||
601 | { | ||
602 | unsigned long st; | ||
603 | struct snd_ad1889 *chip = dev_id; | ||
604 | |||
605 | st = ad1889_readl(chip, AD_DMA_DISR); | ||
606 | |||
607 | /* clear ISR */ | ||
608 | ad1889_writel(chip, AD_DMA_DISR, st); | ||
609 | |||
610 | st &= AD_INTR_MASK; | ||
611 | |||
612 | if (unlikely(!st)) | ||
613 | return IRQ_NONE; | ||
614 | |||
615 | if (st & (AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI)) | ||
616 | ad1889_debug("Unexpected master or target abort interrupt!\n"); | ||
617 | |||
618 | if ((st & AD_DMA_DISR_WAVI) && chip->psubs) | ||
619 | snd_pcm_period_elapsed(chip->psubs); | ||
620 | if ((st & AD_DMA_DISR_ADCI) && chip->csubs) | ||
621 | snd_pcm_period_elapsed(chip->csubs); | ||
622 | |||
623 | return IRQ_HANDLED; | ||
624 | } | ||
625 | |||
626 | static void | ||
627 | snd_ad1889_pcm_free(snd_pcm_t *pcm) | ||
628 | { | ||
629 | struct snd_ad1889 *chip = pcm->private_data; | ||
630 | chip->pcm = NULL; | ||
631 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
632 | } | ||
633 | |||
634 | static int __devinit | ||
635 | snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, snd_pcm_t **rpcm) | ||
636 | { | ||
637 | int err; | ||
638 | snd_pcm_t *pcm; | ||
639 | |||
640 | if (rpcm) | ||
641 | *rpcm = NULL; | ||
642 | |||
643 | err = snd_pcm_new(chip->card, chip->card->driver, device, 1, 1, &pcm); | ||
644 | if (err < 0) | ||
645 | return err; | ||
646 | |||
647 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, | ||
648 | &snd_ad1889_playback_ops); | ||
649 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | ||
650 | &snd_ad1889_capture_ops); | ||
651 | |||
652 | pcm->private_data = chip; | ||
653 | pcm->private_free = snd_ad1889_pcm_free; | ||
654 | pcm->info_flags = 0; | ||
655 | strcpy(pcm->name, chip->card->shortname); | ||
656 | |||
657 | chip->pcm = pcm; | ||
658 | chip->psubs = NULL; | ||
659 | chip->csubs = NULL; | ||
660 | |||
661 | err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | ||
662 | snd_dma_pci_data(chip->pci), | ||
663 | BUFFER_BYTES_MAX / 2, | ||
664 | BUFFER_BYTES_MAX); | ||
665 | |||
666 | if (err < 0) { | ||
667 | snd_printk(KERN_ERR PFX "buffer allocation error: %d\n", err); | ||
668 | return err; | ||
669 | } | ||
670 | |||
671 | if (rpcm) | ||
672 | *rpcm = pcm; | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | static void | ||
678 | snd_ad1889_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) | ||
679 | { | ||
680 | struct snd_ad1889 *chip = entry->private_data; | ||
681 | u16 reg; | ||
682 | int tmp; | ||
683 | |||
684 | reg = ad1889_readw(chip, AD_DS_WSMC); | ||
685 | snd_iprintf(buffer, "Wave output: %s\n", | ||
686 | (reg & AD_DS_WSMC_WAEN) ? "enabled" : "disabled"); | ||
687 | snd_iprintf(buffer, "Wave Channels: %s\n", | ||
688 | (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); | ||
689 | snd_iprintf(buffer, "Wave Quality: %d-bit linear\n", | ||
690 | (reg & AD_DS_WSMC_WA16) ? 16 : 8); | ||
691 | |||
692 | /* WARQ is at offset 12 */ | ||
693 | tmp = (reg & AD_DS_WSMC_WARQ) ? | ||
694 | (((reg & AD_DS_WSMC_WARQ >> 12) & 0x01) ? 12 : 18) : 4; | ||
695 | tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1; | ||
696 | |||
697 | snd_iprintf(buffer, "Wave FIFO: %d %s words\n\n", tmp, | ||
698 | (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); | ||
699 | |||
700 | |||
701 | snd_iprintf(buffer, "Synthesis output: %s\n", | ||
702 | reg & AD_DS_WSMC_SYEN ? "enabled" : "disabled"); | ||
703 | |||
704 | /* SYRQ is at offset 4 */ | ||
705 | tmp = (reg & AD_DS_WSMC_SYRQ) ? | ||
706 | (((reg & AD_DS_WSMC_SYRQ >> 4) & 0x01) ? 12 : 18) : 4; | ||
707 | tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1; | ||
708 | |||
709 | snd_iprintf(buffer, "Synthesis FIFO: %d %s words\n\n", tmp, | ||
710 | (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); | ||
711 | |||
712 | reg = ad1889_readw(chip, AD_DS_RAMC); | ||
713 | snd_iprintf(buffer, "ADC input: %s\n", | ||
714 | (reg & AD_DS_RAMC_ADEN) ? "enabled" : "disabled"); | ||
715 | snd_iprintf(buffer, "ADC Channels: %s\n", | ||
716 | (reg & AD_DS_RAMC_ADST) ? "stereo" : "mono"); | ||
717 | snd_iprintf(buffer, "ADC Quality: %d-bit linear\n", | ||
718 | (reg & AD_DS_RAMC_AD16) ? 16 : 8); | ||
719 | |||
720 | /* ACRQ is at offset 4 */ | ||
721 | tmp = (reg & AD_DS_RAMC_ACRQ) ? | ||
722 | (((reg & AD_DS_RAMC_ACRQ >> 4) & 0x01) ? 12 : 18) : 4; | ||
723 | tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1; | ||
724 | |||
725 | snd_iprintf(buffer, "ADC FIFO: %d %s words\n\n", tmp, | ||
726 | (reg & AD_DS_RAMC_ADST) ? "stereo" : "mono"); | ||
727 | |||
728 | snd_iprintf(buffer, "Resampler input: %s\n", | ||
729 | reg & AD_DS_RAMC_REEN ? "enabled" : "disabled"); | ||
730 | |||
731 | /* RERQ is at offset 12 */ | ||
732 | tmp = (reg & AD_DS_RAMC_RERQ) ? | ||
733 | (((reg & AD_DS_RAMC_RERQ >> 12) & 0x01) ? 12 : 18) : 4; | ||
734 | tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1; | ||
735 | |||
736 | snd_iprintf(buffer, "Resampler FIFO: %d %s words\n\n", tmp, | ||
737 | (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); | ||
738 | |||
739 | |||
740 | /* doc says LSB represents -1.5dB, but the max value (-94.5dB) | ||
741 | suggests that LSB is -3dB, which is more coherent with the logarithmic | ||
742 | nature of the dB scale */ | ||
743 | reg = ad1889_readw(chip, AD_DS_WADA); | ||
744 | snd_iprintf(buffer, "Left: %s, -%d dB\n", | ||
745 | (reg & AD_DS_WADA_LWAM) ? "mute" : "unmute", | ||
746 | ((reg & AD_DS_WADA_LWAA) >> 8) * 3); | ||
747 | reg = ad1889_readw(chip, AD_DS_WADA); | ||
748 | snd_iprintf(buffer, "Right: %s, -%d dB\n", | ||
749 | (reg & AD_DS_WADA_RWAM) ? "mute" : "unmute", | ||
750 | ((reg & AD_DS_WADA_RWAA) >> 8) * 3); | ||
751 | |||
752 | reg = ad1889_readw(chip, AD_DS_WAS); | ||
753 | snd_iprintf(buffer, "Wave samplerate: %u Hz\n", reg); | ||
754 | reg = ad1889_readw(chip, AD_DS_RES); | ||
755 | snd_iprintf(buffer, "Resampler samplerate: %u Hz\n", reg); | ||
756 | } | ||
757 | |||
758 | static void __devinit | ||
759 | snd_ad1889_proc_init(struct snd_ad1889 *chip) | ||
760 | { | ||
761 | snd_info_entry_t *entry; | ||
762 | |||
763 | if (!snd_card_proc_new(chip->card, chip->card->driver, &entry)) | ||
764 | snd_info_set_text_ops(entry, chip, 1024, snd_ad1889_proc_read); | ||
765 | } | ||
766 | |||
767 | static struct ac97_quirk ac97_quirks[] = { | ||
768 | { | ||
769 | .subvendor = 0x11d4, /* AD */ | ||
770 | .subdevice = 0x1889, /* AD1889 */ | ||
771 | .codec_id = AC97_ID_AD1819, | ||
772 | .name = "AD1889", | ||
773 | .type = AC97_TUNE_HP_ONLY | ||
774 | }, | ||
775 | { } /* terminator */ | ||
776 | }; | ||
777 | |||
778 | static void __devinit | ||
779 | snd_ad1889_ac97_xinit(struct snd_ad1889 *chip) | ||
780 | { | ||
781 | u16 reg; | ||
782 | |||
783 | reg = ad1889_readw(chip, AD_AC97_ACIC); | ||
784 | reg |= AD_AC97_ACIC_ACRD; /* Reset Disable */ | ||
785 | ad1889_writew(chip, AD_AC97_ACIC, reg); | ||
786 | ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */ | ||
787 | udelay(10); | ||
788 | /* Interface Enable */ | ||
789 | reg |= AD_AC97_ACIC_ACIE; | ||
790 | ad1889_writew(chip, AD_AC97_ACIC, reg); | ||
791 | |||
792 | snd_ad1889_ac97_ready(chip); | ||
793 | |||
794 | /* Audio Stream Output | Variable Sample Rate Mode */ | ||
795 | reg = ad1889_readw(chip, AD_AC97_ACIC); | ||
796 | reg |= AD_AC97_ACIC_ASOE | AD_AC97_ACIC_VSRM; | ||
797 | ad1889_writew(chip, AD_AC97_ACIC, reg); | ||
798 | ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */ | ||
799 | |||
800 | } | ||
801 | |||
802 | static void | ||
803 | snd_ad1889_ac97_bus_free(ac97_bus_t *bus) | ||
804 | { | ||
805 | struct snd_ad1889 *chip = bus->private_data; | ||
806 | chip->ac97_bus = NULL; | ||
807 | } | ||
808 | |||
809 | static void | ||
810 | snd_ad1889_ac97_free(ac97_t *ac97) | ||
811 | { | ||
812 | struct snd_ad1889 *chip = ac97->private_data; | ||
813 | chip->ac97 = NULL; | ||
814 | } | ||
815 | |||
816 | static int __devinit | ||
817 | snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override) | ||
818 | { | ||
819 | int err; | ||
820 | ac97_template_t ac97; | ||
821 | static ac97_bus_ops_t ops = { | ||
822 | .write = snd_ad1889_ac97_write, | ||
823 | .read = snd_ad1889_ac97_read, | ||
824 | }; | ||
825 | |||
826 | /* doing that here, it works. */ | ||
827 | snd_ad1889_ac97_xinit(chip); | ||
828 | |||
829 | err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus); | ||
830 | if (err < 0) | ||
831 | return err; | ||
832 | |||
833 | chip->ac97_bus->private_free = snd_ad1889_ac97_bus_free; | ||
834 | |||
835 | memset(&ac97, 0, sizeof(ac97)); | ||
836 | ac97.private_data = chip; | ||
837 | ac97.private_free = snd_ad1889_ac97_free; | ||
838 | ac97.pci = chip->pci; | ||
839 | |||
840 | err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97); | ||
841 | if (err < 0) | ||
842 | return err; | ||
843 | |||
844 | snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override); | ||
845 | |||
846 | return 0; | ||
847 | } | ||
848 | |||
849 | static int | ||
850 | snd_ad1889_free(struct snd_ad1889 *chip) | ||
851 | { | ||
852 | if (chip->irq < 0) | ||
853 | goto skip_hw; | ||
854 | |||
855 | spin_lock_irq(&chip->lock); | ||
856 | |||
857 | ad1889_mute(chip); | ||
858 | |||
859 | /* Turn off interrupt on count and zero DMA registers */ | ||
860 | ad1889_channel_reset(chip, AD_CHAN_WAV | AD_CHAN_ADC); | ||
861 | |||
862 | /* clear DISR. If we don't, we'd better jump off the Eiffel Tower */ | ||
863 | ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PTAI | AD_DMA_DISR_PMAI); | ||
864 | ad1889_readl(chip, AD_DMA_DISR); /* flush, dammit! */ | ||
865 | |||
866 | spin_unlock_irq(&chip->lock); | ||
867 | |||
868 | synchronize_irq(chip->irq); | ||
869 | |||
870 | if (chip->irq >= 0) | ||
871 | free_irq(chip->irq, (void*)chip); | ||
872 | |||
873 | skip_hw: | ||
874 | if (chip->iobase) | ||
875 | iounmap(chip->iobase); | ||
876 | |||
877 | pci_release_regions(chip->pci); | ||
878 | pci_disable_device(chip->pci); | ||
879 | |||
880 | kfree(chip); | ||
881 | return 0; | ||
882 | } | ||
883 | |||
884 | static inline int | ||
885 | snd_ad1889_dev_free(snd_device_t *device) | ||
886 | { | ||
887 | struct snd_ad1889 *chip = device->device_data; | ||
888 | return snd_ad1889_free(chip); | ||
889 | } | ||
890 | |||
891 | static int __devinit | ||
892 | snd_ad1889_init(struct snd_ad1889 *chip) | ||
893 | { | ||
894 | ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */ | ||
895 | ad1889_readw(chip, AD_DS_CCS); /* flush posted write */ | ||
896 | |||
897 | mdelay(10); | ||
898 | |||
899 | /* enable Master and Target abort interrupts */ | ||
900 | ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PMAE | AD_DMA_DISR_PTAE); | ||
901 | |||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | static int __devinit | ||
906 | snd_ad1889_create(snd_card_t *card, | ||
907 | struct pci_dev *pci, | ||
908 | struct snd_ad1889 **rchip) | ||
909 | { | ||
910 | int err; | ||
911 | |||
912 | struct snd_ad1889 *chip; | ||
913 | static snd_device_ops_t ops = { | ||
914 | .dev_free = snd_ad1889_dev_free, | ||
915 | }; | ||
916 | |||
917 | *rchip = NULL; | ||
918 | |||
919 | if ((err = pci_enable_device(pci)) < 0) | ||
920 | return err; | ||
921 | |||
922 | /* check PCI availability (32bit DMA) */ | ||
923 | if (pci_set_dma_mask(pci, 0xffffffff) < 0 || | ||
924 | pci_set_consistent_dma_mask(pci, 0xffffffff) < 0) { | ||
925 | printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n"); | ||
926 | pci_disable_device(pci); | ||
927 | return -ENXIO; | ||
928 | } | ||
929 | |||
930 | /* allocate chip specific data with zero-filled memory */ | ||
931 | if ((chip = kcalloc(1, sizeof(*chip), GFP_KERNEL)) == NULL) { | ||
932 | pci_disable_device(pci); | ||
933 | return -ENOMEM; | ||
934 | } | ||
935 | |||
936 | chip->card = card; | ||
937 | card->private_data = chip; | ||
938 | chip->pci = pci; | ||
939 | chip->irq = -1; | ||
940 | |||
941 | /* (1) PCI resource allocation */ | ||
942 | if ((err = pci_request_regions(pci, card->driver)) < 0) | ||
943 | goto free_and_ret; | ||
944 | |||
945 | chip->bar = pci_resource_start(pci, 0); | ||
946 | chip->iobase = ioremap_nocache(chip->bar, pci_resource_len(pci, 0)); | ||
947 | if (chip->iobase == NULL) { | ||
948 | printk(KERN_ERR PFX "unable to reserve region.\n"); | ||
949 | err = -EBUSY; | ||
950 | goto free_and_ret; | ||
951 | } | ||
952 | |||
953 | pci_set_master(pci); | ||
954 | |||
955 | spin_lock_init(&chip->lock); /* only now can we call ad1889_free */ | ||
956 | |||
957 | if (request_irq(pci->irq, snd_ad1889_interrupt, | ||
958 | SA_INTERRUPT|SA_SHIRQ, card->driver, (void*)chip)) { | ||
959 | printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq); | ||
960 | snd_ad1889_free(chip); | ||
961 | return -EBUSY; | ||
962 | } | ||
963 | |||
964 | chip->irq = pci->irq; | ||
965 | synchronize_irq(chip->irq); | ||
966 | |||
967 | /* (2) initialization of the chip hardware */ | ||
968 | if ((err = snd_ad1889_init(chip)) < 0) { | ||
969 | snd_ad1889_free(chip); | ||
970 | return err; | ||
971 | } | ||
972 | |||
973 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | ||
974 | snd_ad1889_free(chip); | ||
975 | return err; | ||
976 | } | ||
977 | |||
978 | snd_card_set_dev(card, &pci->dev); | ||
979 | |||
980 | *rchip = chip; | ||
981 | |||
982 | return 0; | ||
983 | |||
984 | free_and_ret: | ||
985 | if (chip) | ||
986 | kfree(chip); | ||
987 | pci_disable_device(pci); | ||
988 | |||
989 | return err; | ||
990 | } | ||
991 | |||
992 | static int __devinit | ||
993 | snd_ad1889_probe(struct pci_dev *pci, | ||
994 | const struct pci_device_id *pci_id) | ||
995 | { | ||
996 | int err; | ||
997 | static int devno; | ||
998 | snd_card_t *card; | ||
999 | struct snd_ad1889 *chip; | ||
1000 | |||
1001 | /* (1) */ | ||
1002 | if (devno >= SNDRV_CARDS) | ||
1003 | return -ENODEV; | ||
1004 | if (!enable[devno]) { | ||
1005 | devno++; | ||
1006 | return -ENOENT; | ||
1007 | } | ||
1008 | |||
1009 | /* (2) */ | ||
1010 | card = snd_card_new(index[devno], id[devno], THIS_MODULE, 0); | ||
1011 | /* XXX REVISIT: we can probably allocate chip in this call */ | ||
1012 | if (card == NULL) | ||
1013 | return -ENOMEM; | ||
1014 | |||
1015 | strcpy(card->driver, "AD1889"); | ||
1016 | strcpy(card->shortname, "Analog Devices AD1889"); | ||
1017 | |||
1018 | /* (3) */ | ||
1019 | err = snd_ad1889_create(card, pci, &chip); | ||
1020 | if (err < 0) | ||
1021 | goto free_and_ret; | ||
1022 | |||
1023 | /* (4) */ | ||
1024 | sprintf(card->longname, "%s at 0x%lx irq %i", | ||
1025 | card->shortname, chip->bar, chip->irq); | ||
1026 | |||
1027 | /* (5) */ | ||
1028 | /* register AC97 mixer */ | ||
1029 | err = snd_ad1889_ac97_init(chip, ac97_quirk[devno]); | ||
1030 | if (err < 0) | ||
1031 | goto free_and_ret; | ||
1032 | |||
1033 | err = snd_ad1889_pcm_init(chip, 0, NULL); | ||
1034 | if (err < 0) | ||
1035 | goto free_and_ret; | ||
1036 | |||
1037 | /* register proc interface */ | ||
1038 | snd_ad1889_proc_init(chip); | ||
1039 | |||
1040 | /* (6) */ | ||
1041 | err = snd_card_register(card); | ||
1042 | if (err < 0) | ||
1043 | goto free_and_ret; | ||
1044 | |||
1045 | /* (7) */ | ||
1046 | pci_set_drvdata(pci, card); | ||
1047 | |||
1048 | devno++; | ||
1049 | return 0; | ||
1050 | |||
1051 | free_and_ret: | ||
1052 | snd_card_free(card); | ||
1053 | return err; | ||
1054 | } | ||
1055 | |||
1056 | static void __devexit | ||
1057 | snd_ad1889_remove(struct pci_dev *pci) | ||
1058 | { | ||
1059 | snd_card_free(pci_get_drvdata(pci)); | ||
1060 | pci_set_drvdata(pci, NULL); | ||
1061 | } | ||
1062 | |||
1063 | static struct pci_device_id snd_ad1889_ids[] = { | ||
1064 | { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) }, | ||
1065 | { 0, }, | ||
1066 | }; | ||
1067 | MODULE_DEVICE_TABLE(pci, snd_ad1889_ids); | ||
1068 | |||
1069 | static struct pci_driver ad1889_pci = { | ||
1070 | .name = "AD1889 Audio", | ||
1071 | .id_table = snd_ad1889_ids, | ||
1072 | .probe = snd_ad1889_probe, | ||
1073 | .remove = __devexit_p(snd_ad1889_remove), | ||
1074 | }; | ||
1075 | |||
1076 | static int __init | ||
1077 | alsa_ad1889_init(void) | ||
1078 | { | ||
1079 | return pci_register_driver(&ad1889_pci); | ||
1080 | } | ||
1081 | |||
1082 | static void __exit | ||
1083 | alsa_ad1889_fini(void) | ||
1084 | { | ||
1085 | pci_unregister_driver(&ad1889_pci); | ||
1086 | } | ||
1087 | |||
1088 | module_init(alsa_ad1889_init); | ||
1089 | module_exit(alsa_ad1889_fini); | ||