2 * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
6 * FEATURES currently supported:
7 * Front, Rear and Center/LFE.
8 * Surround40 and Surround51.
9 * Capture from MIC an LINE IN input.
10 * SPDIF digital playback of PCM stereo and AC3/DTS works.
11 * (One can use a standard mono mini-jack to one RCA plugs cable.
12 * or one can use a standard stereo mini-jack to two RCA plugs cable.
13 * Plug one of the RCA plugs into the Coax input of the external decoder/receiver.)
14 * ( In theory one could output 3 different AC3 streams at once, to 3 different SPDIF outputs. )
15 * Notes on how to capture sound:
16 * The AC97 is used in the PLAYBACK direction.
17 * The output from the AC97 chip, instead of reaching the speakers, is fed into the Philips 1361T ADC.
18 * So, to record from the MIC, set the MIC Playback volume to max,
19 * unmute the MIC and turn up the MASTER Playback volume.
20 * So, to prevent feedback when capturing, minimise the "Capture feedback into Playback" volume.
22 * The only playback controls that currently do anything are: -
30 * For capture from Mic in or Line in.
31 * Digital/Analog ( switch must be in Analog mode for CAPTURE. )
33 * CAPTURE feedback into PLAYBACK
36 * Support interrupts per period.
37 * Removed noise from Center/LFE channel when in Analog mode.
38 * Rename and remove mixer controls.
40 * Use separate card based DMA buffer for periods table list.
42 * Change remove and rename ctrls into lists.
44 * Try to fix capture sources.
47 * Enable S32_LE format support.
49 * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
51 * Add Model name recognition.
53 * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
54 * Remove redundent "voice" handling.
56 * Single trigger call for multi channels.
58 * Set limits based on what the sound card hardware can do.
59 * playback periods_min=2, periods_max=8
60 * capture hw constraints require period_size = n * 64 bytes.
61 * playback hw constraints require period_size = n * 64 bytes.
65 * Implement 192000 sample rate.
67 * Add support for SB0410 and SB0413.
69 * Modified Copyright message.
71 * Finally fix support for SB Live 24 bit. SB0410 and SB0413.
72 * The output codec needs resetting, otherwise all output is muted.
74 * Merge "pci_disable_device(pci);" fixes.
76 * Add 4 capture channels. (SPDIF only comes in on channel 0. )
77 * Add SPDIF capture using optional digital I/O module for SB Live 24bit. (Analog capture does not yet work.)
80 * Some stability problems when unloading the snd-ca0106 kernel module.
84 * 4 Capture channels, only one implemented so far.
85 * Other capture rates apart from 48khz not implemented.
90 * P17 Chip: CA0106-DAT
91 * AC97 Codec: STAC 9721
92 * ADC: Philips 1361T (Stereo 24bit)
93 * DAC: WM8746EDS (6-channel, 24bit, 192Khz)
97 * P17 Chip: CA0106-DAT
99 * ADC: WM8775EDS (4 Channel)
100 * DAC: CS4382 (114 dB, 24-Bit, 192 kHz, 8-Channel D/A Converter with DSD Support)
101 * SPDIF Out control switches between Mic in and SPDIF out.
102 * No sound out or mic input working yet.
106 * P17 Chip: CA0106-DAT
110 * Trying to handle it like the SB0410.
112 * This code was initally based on code from ALSA's emu10k1x.c which is:
113 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
115 * This program is free software; you can redistribute it and/or modify
116 * it under the terms of the GNU General Public License as published by
117 * the Free Software Foundation; either version 2 of the License, or
118 * (at your option) any later version.
120 * This program is distributed in the hope that it will be useful,
121 * but WITHOUT ANY WARRANTY; without even the implied warranty of
122 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
123 * GNU General Public License for more details.
125 * You should have received a copy of the GNU General Public License
126 * along with this program; if not, write to the Free Software
127 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
130 #include <sound/driver.h>
131 #include <linux/delay.h>
132 #include <linux/init.h>
133 #include <linux/interrupt.h>
134 #include <linux/pci.h>
135 #include <linux/slab.h>
136 #include <linux/moduleparam.h>
137 #include <sound/core.h>
138 #include <sound/initval.h>
139 #include <sound/pcm.h>
140 #include <sound/ac97_codec.h>
141 #include <sound/info.h>
143 MODULE_AUTHOR("James Courtier-Dutton <James@superbug.demon.co.uk>");
144 MODULE_DESCRIPTION("CA0106");
145 MODULE_LICENSE("GPL");
146 MODULE_SUPPORTED_DEVICE("{{Creative,SB CA0106 chip}}");
148 // module parameters (see "Module Parameters")
149 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
150 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
151 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
153 module_param_array(index, int, NULL, 0444);
154 MODULE_PARM_DESC(index, "Index value for the CA0106 soundcard.");
155 module_param_array(id, charp, NULL, 0444);
156 MODULE_PARM_DESC(id, "ID string for the CA0106 soundcard.");
157 module_param_array(enable, bool, NULL, 0444);
158 MODULE_PARM_DESC(enable, "Enable the CA0106 soundcard.");
167 static ca0106_names_t ca0106_chip_names[] = {
168 { 0x10021102, "AudigyLS [SB0310]"} ,
169 { 0x10051102, "AudigyLS [SB0310b]"} , /* Unknown AudigyLS that also says SB0310 on it */
170 { 0x10061102, "Live! 7.1 24bit [SB0410]"} , /* New Sound Blaster Live! 7.1 24bit. This does not have an AC97. 53SB041000001 */
171 { 0x10071102, "Live! 7.1 24bit [SB0413]"} , /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */
172 { 0, "AudigyLS [Unknown]" }
175 /* hardware definition */
176 static snd_pcm_hardware_t snd_ca0106_playback_hw = {
177 .info = (SNDRV_PCM_INFO_MMAP |
178 SNDRV_PCM_INFO_INTERLEAVED |
179 SNDRV_PCM_INFO_BLOCK_TRANSFER |
180 SNDRV_PCM_INFO_MMAP_VALID),
181 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
182 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
185 .channels_min = 2, //1,
186 .channels_max = 2, //6,
187 .buffer_bytes_max = (32*1024),
188 .period_bytes_min = 64,
189 .period_bytes_max = (16*1024),
195 static snd_pcm_hardware_t snd_ca0106_capture_hw = {
196 .info = (SNDRV_PCM_INFO_MMAP |
197 SNDRV_PCM_INFO_INTERLEAVED |
198 SNDRV_PCM_INFO_BLOCK_TRANSFER |
199 SNDRV_PCM_INFO_MMAP_VALID),
200 .formats = SNDRV_PCM_FMTBIT_S16_LE,
201 .rates = SNDRV_PCM_RATE_48000,
206 .buffer_bytes_max = (32*1024),
207 .period_bytes_min = 64,
208 .period_bytes_max = (16*1024),
214 unsigned int snd_ca0106_ptr_read(ca0106_t * emu,
219 unsigned int regptr, val;
221 regptr = (reg << 16) | chn;
223 spin_lock_irqsave(&emu->emu_lock, flags);
224 outl(regptr, emu->port + PTR);
225 val = inl(emu->port + DATA);
226 spin_unlock_irqrestore(&emu->emu_lock, flags);
230 void snd_ca0106_ptr_write(ca0106_t *emu,
238 regptr = (reg << 16) | chn;
240 spin_lock_irqsave(&emu->emu_lock, flags);
241 outl(regptr, emu->port + PTR);
242 outl(data, emu->port + DATA);
243 spin_unlock_irqrestore(&emu->emu_lock, flags);
246 static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb)
251 spin_lock_irqsave(&emu->emu_lock, flags);
252 enable = inl(emu->port + INTE) | intrenb;
253 outl(enable, emu->port + INTE);
254 spin_unlock_irqrestore(&emu->emu_lock, flags);
257 static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime)
259 ca0106_pcm_t *epcm = runtime->private_data;
266 /* open_playback callback */
267 static int snd_ca0106_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id)
269 ca0106_t *chip = snd_pcm_substream_chip(substream);
270 ca0106_channel_t *channel = &(chip->playback_channels[channel_id]);
272 snd_pcm_runtime_t *runtime = substream->runtime;
275 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
280 epcm->substream = substream;
281 epcm->channel_id=channel_id;
283 runtime->private_data = epcm;
284 runtime->private_free = snd_ca0106_pcm_free_substream;
286 runtime->hw = snd_ca0106_playback_hw;
289 channel->number = channel_id;
292 //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
293 //channel->interrupt = snd_ca0106_pcm_channel_interrupt;
295 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
297 if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
303 static int snd_ca0106_pcm_close_playback(snd_pcm_substream_t *substream)
305 ca0106_t *chip = snd_pcm_substream_chip(substream);
306 snd_pcm_runtime_t *runtime = substream->runtime;
307 ca0106_pcm_t *epcm = runtime->private_data;
308 chip->playback_channels[epcm->channel_id].use=0;
309 /* FIXME: maybe zero others */
313 static int snd_ca0106_pcm_open_playback_front(snd_pcm_substream_t *substream)
315 return snd_ca0106_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
318 static int snd_ca0106_pcm_open_playback_center_lfe(snd_pcm_substream_t *substream)
320 return snd_ca0106_pcm_open_playback_channel(substream, PCM_CENTER_LFE_CHANNEL);
323 static int snd_ca0106_pcm_open_playback_unknown(snd_pcm_substream_t *substream)
325 return snd_ca0106_pcm_open_playback_channel(substream, PCM_UNKNOWN_CHANNEL);
328 static int snd_ca0106_pcm_open_playback_rear(snd_pcm_substream_t *substream)
330 return snd_ca0106_pcm_open_playback_channel(substream, PCM_REAR_CHANNEL);
333 /* open_capture callback */
334 static int snd_ca0106_pcm_open_capture_channel(snd_pcm_substream_t *substream, int channel_id)
336 ca0106_t *chip = snd_pcm_substream_chip(substream);
337 ca0106_channel_t *channel = &(chip->capture_channels[channel_id]);
339 snd_pcm_runtime_t *runtime = substream->runtime;
342 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
344 snd_printk("open_capture_channel: failed epcm alloc\n");
348 epcm->substream = substream;
349 epcm->channel_id=channel_id;
351 runtime->private_data = epcm;
352 runtime->private_free = snd_ca0106_pcm_free_substream;
354 runtime->hw = snd_ca0106_capture_hw;
357 channel->number = channel_id;
360 //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
361 //channel->interrupt = snd_ca0106_pcm_channel_interrupt;
363 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
365 //snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes);
366 if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
372 static int snd_ca0106_pcm_close_capture(snd_pcm_substream_t *substream)
374 ca0106_t *chip = snd_pcm_substream_chip(substream);
375 snd_pcm_runtime_t *runtime = substream->runtime;
376 ca0106_pcm_t *epcm = runtime->private_data;
377 chip->capture_channels[epcm->channel_id].use=0;
378 /* FIXME: maybe zero others */
382 static int snd_ca0106_pcm_open_0_capture(snd_pcm_substream_t *substream)
384 return snd_ca0106_pcm_open_capture_channel(substream, 0);
387 static int snd_ca0106_pcm_open_1_capture(snd_pcm_substream_t *substream)
389 return snd_ca0106_pcm_open_capture_channel(substream, 1);
392 static int snd_ca0106_pcm_open_2_capture(snd_pcm_substream_t *substream)
394 return snd_ca0106_pcm_open_capture_channel(substream, 2);
397 static int snd_ca0106_pcm_open_3_capture(snd_pcm_substream_t *substream)
399 return snd_ca0106_pcm_open_capture_channel(substream, 3);
402 /* hw_params callback */
403 static int snd_ca0106_pcm_hw_params_playback(snd_pcm_substream_t *substream,
404 snd_pcm_hw_params_t * hw_params)
406 return snd_pcm_lib_malloc_pages(substream,
407 params_buffer_bytes(hw_params));
410 /* hw_free callback */
411 static int snd_ca0106_pcm_hw_free_playback(snd_pcm_substream_t *substream)
413 return snd_pcm_lib_free_pages(substream);
416 /* hw_params callback */
417 static int snd_ca0106_pcm_hw_params_capture(snd_pcm_substream_t *substream,
418 snd_pcm_hw_params_t * hw_params)
420 return snd_pcm_lib_malloc_pages(substream,
421 params_buffer_bytes(hw_params));
424 /* hw_free callback */
425 static int snd_ca0106_pcm_hw_free_capture(snd_pcm_substream_t *substream)
427 return snd_pcm_lib_free_pages(substream);
430 /* prepare playback callback */
431 static int snd_ca0106_pcm_prepare_playback(snd_pcm_substream_t *substream)
433 ca0106_t *emu = snd_pcm_substream_chip(substream);
434 snd_pcm_runtime_t *runtime = substream->runtime;
435 ca0106_pcm_t *epcm = runtime->private_data;
436 int channel = epcm->channel_id;
437 u32 *table_base = (u32 *)(emu->buffer.area+(8*16*channel));
438 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
439 u32 hcfg_mask = HCFG_PLAYBACK_S32_LE;
440 u32 hcfg_set = 0x00000000;
442 u32 reg40_mask = 0x30000 << (channel<<1);
445 /* FIXME: Depending on mixer selection of SPDIF out or not, select the spdif rate or the DAC rate. */
446 u32 reg71_mask = 0x03030000 ; /* Global. Set SPDIF rate. We only support 44100 to spdif, not to DAC. */
451 //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
452 //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
453 //snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->buffer.addr, emu->buffer.area, emu->buffer.bytes);
454 /* Rate can be set per channel. */
455 /* reg40 control host to fifo */
456 /* reg71 controls DAC rate. */
457 switch (runtime->rate) {
459 reg40_set = 0x10000 << (channel<<1);
460 reg71_set = 0x01010000;
467 reg40_set = 0x20000 << (channel<<1);
468 reg71_set = 0x02020000;
471 reg40_set = 0x30000 << (channel<<1);
472 reg71_set = 0x03030000;
479 /* Format is a global setting */
480 /* FIXME: Only let the first channel accessed set this. */
481 switch (runtime->format) {
482 case SNDRV_PCM_FORMAT_S16_LE:
485 case SNDRV_PCM_FORMAT_S32_LE:
486 hcfg_set = HCFG_PLAYBACK_S32_LE;
492 hcfg = inl(emu->port + HCFG) ;
493 hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
494 outl(hcfg, emu->port + HCFG);
495 reg40 = snd_ca0106_ptr_read(emu, 0x40, 0);
496 reg40 = (reg40 & ~reg40_mask) | reg40_set;
497 snd_ca0106_ptr_write(emu, 0x40, 0, reg40);
498 reg71 = snd_ca0106_ptr_read(emu, 0x71, 0);
499 reg71 = (reg71 & ~reg71_mask) | reg71_set;
500 snd_ca0106_ptr_write(emu, 0x71, 0, reg71);
502 /* FIXME: Check emu->buffer.size before actually writing to it. */
503 for(i=0; i < runtime->periods; i++) {
504 table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
505 table_base[(i*2)+1]=period_size_bytes<<16;
508 snd_ca0106_ptr_write(emu, PLAYBACK_LIST_ADDR, channel, emu->buffer.addr+(8*16*channel));
509 snd_ca0106_ptr_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
510 snd_ca0106_ptr_write(emu, PLAYBACK_LIST_PTR, channel, 0);
511 snd_ca0106_ptr_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
512 snd_ca0106_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
513 snd_ca0106_ptr_write(emu, PLAYBACK_POINTER, channel, 0);
514 snd_ca0106_ptr_write(emu, 0x07, channel, 0x0);
515 snd_ca0106_ptr_write(emu, 0x08, channel, 0);
516 snd_ca0106_ptr_write(emu, PLAYBACK_MUTE, 0x0, 0x0); /* Unmute output */
518 snd_ca0106_ptr_write(emu, SPCS0, 0,
519 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
520 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
521 SPCS_GENERATIONSTATUS | 0x00001200 |
522 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT );
529 /* prepare capture callback */
530 static int snd_ca0106_pcm_prepare_capture(snd_pcm_substream_t *substream)
532 ca0106_t *emu = snd_pcm_substream_chip(substream);
533 snd_pcm_runtime_t *runtime = substream->runtime;
534 ca0106_pcm_t *epcm = runtime->private_data;
535 int channel = epcm->channel_id;
536 //printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, frames_to_bytes(runtime, 1));
537 snd_ca0106_ptr_write(emu, 0x13, channel, 0);
538 snd_ca0106_ptr_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
539 snd_ca0106_ptr_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
540 snd_ca0106_ptr_write(emu, CAPTURE_POINTER, channel, 0);
545 /* trigger_playback callback */
546 static int snd_ca0106_pcm_trigger_playback(snd_pcm_substream_t *substream,
549 ca0106_t *emu = snd_pcm_substream_chip(substream);
550 snd_pcm_runtime_t *runtime;
554 struct list_head *pos;
555 snd_pcm_substream_t *s;
561 case SNDRV_PCM_TRIGGER_START:
564 case SNDRV_PCM_TRIGGER_STOP:
569 snd_pcm_group_for_each(pos, substream) {
570 s = snd_pcm_group_substream_entry(pos);
571 runtime = s->runtime;
572 epcm = runtime->private_data;
573 channel = epcm->channel_id;
574 //snd_printk("channel=%d\n",channel);
575 epcm->running = running;
576 basic |= (0x1<<channel);
577 extended |= (0x10<<channel);
578 snd_pcm_trigger_done(s, substream);
580 //snd_printk("basic=0x%x, extended=0x%x\n",basic, extended);
583 case SNDRV_PCM_TRIGGER_START:
584 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (extended));
585 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(basic));
587 case SNDRV_PCM_TRIGGER_STOP:
588 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
589 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(extended));
598 /* trigger_capture callback */
599 static int snd_ca0106_pcm_trigger_capture(snd_pcm_substream_t *substream,
602 ca0106_t *emu = snd_pcm_substream_chip(substream);
603 snd_pcm_runtime_t *runtime = substream->runtime;
604 ca0106_pcm_t *epcm = runtime->private_data;
605 int channel = epcm->channel_id;
609 case SNDRV_PCM_TRIGGER_START:
610 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
611 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
614 case SNDRV_PCM_TRIGGER_STOP:
615 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
616 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));
626 /* pointer_playback callback */
627 static snd_pcm_uframes_t
628 snd_ca0106_pcm_pointer_playback(snd_pcm_substream_t *substream)
630 ca0106_t *emu = snd_pcm_substream_chip(substream);
631 snd_pcm_runtime_t *runtime = substream->runtime;
632 ca0106_pcm_t *epcm = runtime->private_data;
633 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
634 int channel = epcm->channel_id;
639 ptr3 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
640 ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel);
641 ptr4 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
642 if (ptr3 != ptr4) ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel);
643 ptr2 = bytes_to_frames(runtime, ptr1);
644 ptr2+= (ptr4 >> 3) * runtime->period_size;
646 if (ptr >= runtime->buffer_size)
647 ptr -= runtime->buffer_size;
648 //printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate);
653 /* pointer_capture callback */
654 static snd_pcm_uframes_t
655 snd_ca0106_pcm_pointer_capture(snd_pcm_substream_t *substream)
657 ca0106_t *emu = snd_pcm_substream_chip(substream);
658 snd_pcm_runtime_t *runtime = substream->runtime;
659 ca0106_pcm_t *epcm = runtime->private_data;
660 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
661 int channel = channel=epcm->channel_id;
666 ptr1 = snd_ca0106_ptr_read(emu, CAPTURE_POINTER, channel);
667 ptr2 = bytes_to_frames(runtime, ptr1);
669 if (ptr >= runtime->buffer_size)
670 ptr -= runtime->buffer_size;
671 //printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate);
677 static snd_pcm_ops_t snd_ca0106_playback_front_ops = {
678 .open = snd_ca0106_pcm_open_playback_front,
679 .close = snd_ca0106_pcm_close_playback,
680 .ioctl = snd_pcm_lib_ioctl,
681 .hw_params = snd_ca0106_pcm_hw_params_playback,
682 .hw_free = snd_ca0106_pcm_hw_free_playback,
683 .prepare = snd_ca0106_pcm_prepare_playback,
684 .trigger = snd_ca0106_pcm_trigger_playback,
685 .pointer = snd_ca0106_pcm_pointer_playback,
688 static snd_pcm_ops_t snd_ca0106_capture_0_ops = {
689 .open = snd_ca0106_pcm_open_0_capture,
690 .close = snd_ca0106_pcm_close_capture,
691 .ioctl = snd_pcm_lib_ioctl,
692 .hw_params = snd_ca0106_pcm_hw_params_capture,
693 .hw_free = snd_ca0106_pcm_hw_free_capture,
694 .prepare = snd_ca0106_pcm_prepare_capture,
695 .trigger = snd_ca0106_pcm_trigger_capture,
696 .pointer = snd_ca0106_pcm_pointer_capture,
699 static snd_pcm_ops_t snd_ca0106_capture_1_ops = {
700 .open = snd_ca0106_pcm_open_1_capture,
701 .close = snd_ca0106_pcm_close_capture,
702 .ioctl = snd_pcm_lib_ioctl,
703 .hw_params = snd_ca0106_pcm_hw_params_capture,
704 .hw_free = snd_ca0106_pcm_hw_free_capture,
705 .prepare = snd_ca0106_pcm_prepare_capture,
706 .trigger = snd_ca0106_pcm_trigger_capture,
707 .pointer = snd_ca0106_pcm_pointer_capture,
710 static snd_pcm_ops_t snd_ca0106_capture_2_ops = {
711 .open = snd_ca0106_pcm_open_2_capture,
712 .close = snd_ca0106_pcm_close_capture,
713 .ioctl = snd_pcm_lib_ioctl,
714 .hw_params = snd_ca0106_pcm_hw_params_capture,
715 .hw_free = snd_ca0106_pcm_hw_free_capture,
716 .prepare = snd_ca0106_pcm_prepare_capture,
717 .trigger = snd_ca0106_pcm_trigger_capture,
718 .pointer = snd_ca0106_pcm_pointer_capture,
721 static snd_pcm_ops_t snd_ca0106_capture_3_ops = {
722 .open = snd_ca0106_pcm_open_3_capture,
723 .close = snd_ca0106_pcm_close_capture,
724 .ioctl = snd_pcm_lib_ioctl,
725 .hw_params = snd_ca0106_pcm_hw_params_capture,
726 .hw_free = snd_ca0106_pcm_hw_free_capture,
727 .prepare = snd_ca0106_pcm_prepare_capture,
728 .trigger = snd_ca0106_pcm_trigger_capture,
729 .pointer = snd_ca0106_pcm_pointer_capture,
732 static snd_pcm_ops_t snd_ca0106_playback_center_lfe_ops = {
733 .open = snd_ca0106_pcm_open_playback_center_lfe,
734 .close = snd_ca0106_pcm_close_playback,
735 .ioctl = snd_pcm_lib_ioctl,
736 .hw_params = snd_ca0106_pcm_hw_params_playback,
737 .hw_free = snd_ca0106_pcm_hw_free_playback,
738 .prepare = snd_ca0106_pcm_prepare_playback,
739 .trigger = snd_ca0106_pcm_trigger_playback,
740 .pointer = snd_ca0106_pcm_pointer_playback,
743 static snd_pcm_ops_t snd_ca0106_playback_unknown_ops = {
744 .open = snd_ca0106_pcm_open_playback_unknown,
745 .close = snd_ca0106_pcm_close_playback,
746 .ioctl = snd_pcm_lib_ioctl,
747 .hw_params = snd_ca0106_pcm_hw_params_playback,
748 .hw_free = snd_ca0106_pcm_hw_free_playback,
749 .prepare = snd_ca0106_pcm_prepare_playback,
750 .trigger = snd_ca0106_pcm_trigger_playback,
751 .pointer = snd_ca0106_pcm_pointer_playback,
754 static snd_pcm_ops_t snd_ca0106_playback_rear_ops = {
755 .open = snd_ca0106_pcm_open_playback_rear,
756 .close = snd_ca0106_pcm_close_playback,
757 .ioctl = snd_pcm_lib_ioctl,
758 .hw_params = snd_ca0106_pcm_hw_params_playback,
759 .hw_free = snd_ca0106_pcm_hw_free_playback,
760 .prepare = snd_ca0106_pcm_prepare_playback,
761 .trigger = snd_ca0106_pcm_trigger_playback,
762 .pointer = snd_ca0106_pcm_pointer_playback,
766 static unsigned short snd_ca0106_ac97_read(ac97_t *ac97,
769 ca0106_t *emu = ac97->private_data;
773 spin_lock_irqsave(&emu->emu_lock, flags);
774 outb(reg, emu->port + AC97ADDRESS);
775 val = inw(emu->port + AC97DATA);
776 spin_unlock_irqrestore(&emu->emu_lock, flags);
780 static void snd_ca0106_ac97_write(ac97_t *ac97,
781 unsigned short reg, unsigned short val)
783 ca0106_t *emu = ac97->private_data;
786 spin_lock_irqsave(&emu->emu_lock, flags);
787 outb(reg, emu->port + AC97ADDRESS);
788 outw(val, emu->port + AC97DATA);
789 spin_unlock_irqrestore(&emu->emu_lock, flags);
792 static int snd_ca0106_ac97(ca0106_t *chip)
795 ac97_template_t ac97;
797 static ac97_bus_ops_t ops = {
798 .write = snd_ca0106_ac97_write,
799 .read = snd_ca0106_ac97_read,
802 if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
804 pbus->no_vra = 1; /* we don't need VRA */
806 memset(&ac97, 0, sizeof(ac97));
807 ac97.private_data = chip;
808 return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
811 static int snd_ca0106_free(ca0106_t *chip)
813 if (chip->res_port != NULL) { /* avoid access to already used hardware */
814 // disable interrupts
815 snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0);
816 outl(0, chip->port + INTE);
817 snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
820 //outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
821 outl(0, chip->port + HCFG);
822 /* FIXME: We need to stop and DMA transfers here.
823 * But as I am not sure how yet, we cannot from the dma pages.
824 * So we can fix: snd-malloc: Memory leak? pages not freed = 8
829 if (chip->buffer.area)
830 snd_dma_free_pages(&chip->buffer);
833 // release the i/o port
834 if (chip->res_port) {
835 release_resource(chip->res_port);
836 kfree_nocheck(chip->res_port);
840 free_irq(chip->irq, (void *)chip);
841 pci_disable_device(chip->pci);
846 static int snd_ca0106_dev_free(snd_device_t *device)
848 ca0106_t *chip = device->device_data;
849 return snd_ca0106_free(chip);
852 static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id,
853 struct pt_regs *regs)
857 ca0106_t *chip = dev_id;
861 ca0106_channel_t *pchannel;
863 spin_lock(&chip->emu_lock);
865 status = inl(chip->port + IPR);
867 // call updater, unlock before it
868 spin_unlock(&chip->emu_lock);
873 stat76 = snd_ca0106_ptr_read(chip, EXTENDED_INT, 0);
874 //snd_printk("interrupt status = 0x%08x, stat76=0x%08x\n", status, stat76);
875 //snd_printk("ptr=0x%08x\n",snd_ca0106_ptr_read(chip, PLAYBACK_POINTER, 0));
876 mask = 0x11; /* 0x1 for one half, 0x10 for the other half period. */
877 for(i = 0; i < 4; i++) {
878 pchannel = &(chip->playback_channels[i]);
880 /* FIXME: Select the correct substream for period elapsed */
882 snd_pcm_period_elapsed(pchannel->epcm->substream);
883 //printk(KERN_INFO "interrupt [%d] used\n", i);
886 //printk(KERN_INFO "channel=%p\n",pchannel);
887 //printk(KERN_INFO "interrupt stat76[%d] = %08x, use=%d, channel=%d\n", i, stat76, pchannel->use, pchannel->number);
890 mask = 0x110000; /* 0x1 for one half, 0x10 for the other half period. */
891 for(i = 0; i < 4; i++) {
892 pchannel = &(chip->capture_channels[i]);
894 /* FIXME: Select the correct substream for period elapsed */
896 snd_pcm_period_elapsed(pchannel->epcm->substream);
897 //printk(KERN_INFO "interrupt [%d] used\n", i);
900 //printk(KERN_INFO "channel=%p\n",pchannel);
901 //printk(KERN_INFO "interrupt stat76[%d] = %08x, use=%d, channel=%d\n", i, stat76, pchannel->use, pchannel->number);
905 snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76);
906 spin_lock(&chip->emu_lock);
907 // acknowledge the interrupt if necessary
908 outl(status, chip->port+IPR);
910 spin_unlock(&chip->emu_lock);
915 static void snd_ca0106_pcm_free(snd_pcm_t *pcm)
917 ca0106_t *emu = pcm->private_data;
919 snd_pcm_lib_preallocate_free_for_all(pcm);
922 static int __devinit snd_ca0106_pcm(ca0106_t *emu, int device, snd_pcm_t **rpcm)
925 snd_pcm_substream_t *substream;
930 if ((err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm)) < 0)
933 pcm->private_data = emu;
934 pcm->private_free = snd_ca0106_pcm_free;
938 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_front_ops);
939 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_0_ops);
942 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_rear_ops);
943 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_1_ops);
946 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_center_lfe_ops);
947 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_2_ops);
950 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_unknown_ops);
951 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_3_ops);
956 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
957 strcpy(pcm->name, "CA0106");
960 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
962 substream = substream->next) {
963 if ((err = snd_pcm_lib_preallocate_pages(substream,
965 snd_dma_pci_data(emu->pci),
966 64*1024, 64*1024)) < 0) /* FIXME: 32*1024 for sound buffer, between 32and64 for Periods table. */
970 for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
972 substream = substream->next) {
973 if ((err = snd_pcm_lib_preallocate_pages(substream,
975 snd_dma_pci_data(emu->pci),
976 64*1024, 64*1024)) < 0)
986 static int __devinit snd_ca0106_create(snd_card_t *card,
993 static snd_device_ops_t ops = {
994 .dev_free = snd_ca0106_dev_free,
999 if ((err = pci_enable_device(pci)) < 0)
1001 if (pci_set_dma_mask(pci, 0xffffffffUL) < 0 ||
1002 pci_set_consistent_dma_mask(pci, 0xffffffffUL) < 0) {
1003 printk(KERN_ERR "error to set 32bit mask DMA\n");
1004 pci_disable_device(pci);
1008 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
1010 pci_disable_device(pci);
1018 spin_lock_init(&chip->emu_lock);
1020 chip->port = pci_resource_start(pci, 0);
1021 if ((chip->res_port = request_region(chip->port, 0x20,
1022 "snd_ca0106")) == NULL) {
1023 snd_ca0106_free(chip);
1024 printk(KERN_ERR "cannot allocate the port\n");
1028 if (request_irq(pci->irq, snd_ca0106_interrupt,
1029 SA_INTERRUPT|SA_SHIRQ, "snd_ca0106",
1031 snd_ca0106_free(chip);
1032 printk(KERN_ERR "cannot grab irq\n");
1035 chip->irq = pci->irq;
1037 /* This stores the periods table. */
1038 if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &chip->buffer) < 0) {
1039 snd_ca0106_free(chip);
1043 pci_set_master(pci);
1044 /* read revision & serial */
1045 pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&chip->revision);
1046 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
1047 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
1049 printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
1050 chip->revision, chip->serial);
1053 outl(0, chip->port + INTE);
1056 * Init to 0x02109204 :
1057 * Clock accuracy = 0 (1000ppm)
1058 * Sample Rate = 2 (48kHz)
1059 * Audio Channel = 1 (Left of 2)
1060 * Source Number = 0 (Unspecified)
1061 * Generation Status = 1 (Original for Cat Code 12)
1062 * Cat Code = 12 (Digital Signal Mixer)
1064 * Emphasis = 0 (None)
1065 * CP = 1 (Copyright unasserted)
1066 * AN = 0 (Audio data)
1069 snd_ca0106_ptr_write(chip, SPCS0, 0,
1070 chip->spdif_bits[0] =
1071 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1072 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1073 SPCS_GENERATIONSTATUS | 0x00001200 |
1074 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1075 /* Only SPCS1 has been tested */
1076 snd_ca0106_ptr_write(chip, SPCS1, 0,
1077 chip->spdif_bits[1] =
1078 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1079 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1080 SPCS_GENERATIONSTATUS | 0x00001200 |
1081 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1082 snd_ca0106_ptr_write(chip, SPCS2, 0,
1083 chip->spdif_bits[2] =
1084 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1085 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1086 SPCS_GENERATIONSTATUS | 0x00001200 |
1087 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1088 snd_ca0106_ptr_write(chip, SPCS3, 0,
1089 chip->spdif_bits[3] =
1090 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1091 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1092 SPCS_GENERATIONSTATUS | 0x00001200 |
1093 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1095 snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000);
1096 snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000);
1098 /* Write 0x8000 to AC97_REC_GAIN to mute it. */
1099 outb(AC97_REC_GAIN, chip->port + AC97ADDRESS);
1100 outw(0x8000, chip->port + AC97DATA);
1102 snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006);
1103 snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006);
1104 snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006);
1105 snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006);
1108 //snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); /* OSS drivers set this. */
1109 /* Analog or Digital output */
1110 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf);
1111 snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000b0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers */
1112 chip->spdif_enable = 0; /* Set digital SPDIF output off */
1113 chip->capture_source = 3; /* Set CAPTURE_SOURCE */
1114 //snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */
1115 //snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */
1117 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000); /* goes to 0x40c80000 when doing SPDIF IN/OUT */
1118 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff); /* (Mute) CAPTURE feedback into PLAYBACK volume. Only lower 16 bits matter. */
1119 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000); /* SPDIF IN Volume */
1120 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000); /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
1121 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410);
1122 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676);
1123 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410);
1124 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676);
1125 for(ch = 0; ch < 4; ch++) {
1126 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030); /* Only high 16 bits matter */
1127 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030);
1128 //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040); /* Mute */
1129 //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040); /* Mute */
1130 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */
1131 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */
1133 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */
1134 chip->capture_source = 3; /* Set CAPTURE_SOURCE */
1136 if ((chip->serial == 0x10061102) || (chip->serial == 0x10071102) ) { /* The SB0410 and SB0413 use GPIO differently. */
1137 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
1138 outl(0x0, chip->port+GPIO);
1139 //outl(0x00f0e000, chip->port+GPIO); /* Analog */
1140 outl(0x005f4300, chip->port+GPIO); /* Analog */
1142 outl(0x0, chip->port+GPIO);
1143 outl(0x005f03a3, chip->port+GPIO); /* Analog */
1144 //outl(0x005f02a2, chip->port+GPIO); /* SPDIF */
1146 snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */
1148 //outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
1149 //outl(0x00001409, chip->port+HCFG); /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
1150 //outl(0x00000009, chip->port+HCFG);
1151 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */
1153 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
1155 snd_ca0106_free(chip);
1162 static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1163 const struct pci_device_id *pci_id)
1171 if (dev >= SNDRV_CARDS)
1178 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1182 if ((err = snd_ca0106_create(card, pci, &chip)) < 0) {
1183 snd_card_free(card);
1187 if ((err = snd_ca0106_pcm(chip, 0, NULL)) < 0) {
1188 snd_card_free(card);
1191 if ((err = snd_ca0106_pcm(chip, 1, NULL)) < 0) {
1192 snd_card_free(card);
1195 if ((err = snd_ca0106_pcm(chip, 2, NULL)) < 0) {
1196 snd_card_free(card);
1199 if ((err = snd_ca0106_pcm(chip, 3, NULL)) < 0) {
1200 snd_card_free(card);
1203 if ((chip->serial != 0x10061102) && (chip->serial != 0x10071102) ) { /* The SB0410 and SB0413 do not have an ac97 chip. */
1204 if ((err = snd_ca0106_ac97(chip)) < 0) {
1205 snd_card_free(card);
1209 if ((err = snd_ca0106_mixer(chip)) < 0) {
1210 snd_card_free(card);
1214 snd_ca0106_proc_init(chip);
1216 strcpy(card->driver, "CA0106");
1217 strcpy(card->shortname, "CA0106");
1219 for (c=ca0106_chip_names; c->serial; c++) {
1220 if (c->serial == chip->serial) break;
1222 sprintf(card->longname, "%s at 0x%lx irq %i",
1223 c->name, chip->port, chip->irq);
1225 if ((err = snd_card_register(card)) < 0) {
1226 snd_card_free(card);
1230 pci_set_drvdata(pci, card);
1235 static void __devexit snd_ca0106_remove(struct pci_dev *pci)
1237 snd_card_free(pci_get_drvdata(pci));
1238 pci_set_drvdata(pci, NULL);
1242 static struct pci_device_id snd_ca0106_ids[] = {
1243 { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */
1246 MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
1248 // pci_driver definition
1249 static struct pci_driver driver = {
1251 .id_table = snd_ca0106_ids,
1252 .probe = snd_ca0106_probe,
1253 .remove = __devexit_p(snd_ca0106_remove),
1256 // initialization of the module
1257 static int __init alsa_card_ca0106_init(void)
1261 if ((err = pci_module_init(&driver)) > 0)
1267 // clean up the module
1268 static void __exit alsa_card_ca0106_exit(void)
1270 pci_unregister_driver(&driver);
1273 module_init(alsa_card_ca0106_init)
1274 module_exit(alsa_card_ca0106_exit)