Soundcard related structures and functions are in include/driver.h header file. Structure snd_card_t must be allocated by snd_card_new function and freed by snd_card_free function (whis isn't called from snd_card_unregister).
Functions list:
Variables from snd_card_t structure which must be filled:
Variables from snd_card_t structure which should be filled:
static void snd_soundcard_use_inc( snd_card_t *card )
{
MOD_INC_USE_COUNT;
}
static void snd_soundcard_use_dec( snd_card_t *card )
{
MOD_DEC_USE_COUNT;
}
int snd_soundcard_init( void )
{
snd_card_t *card;
card = snd_card_new( -1, NULL, snd_soundcard_use_inc, snd_soundcard_dec_inc );
if ( !card ) return -ENOMEM;
card -> type = SND_CARD_TYPE_SOUNDCARD; /* can be changed later */
... resource initialization, detection, device creation and registration ...
strcpy( card -> abbreviation, "SoundCard" );
strcpy( card -> shortname, "3-D SoundCard" );
strcpy( card -> longname, "3-D SoundCard at 0x500, irq 5, dma 5&6" );
if ( !snd_card_register( card ) )
return 0;
snd_card_free( card );
return -ENXIO;
}
Functions list:
Note 1: dma buffer must be assigned for all (PCI and other than ISA) soundcards, too. ALSA kernel and OSS PCM midlevel code contains mechanism for correct free when mmaped access was used. Buffer isn't allocated at register time. Buffer is managed with functions snd_dma_malloc and snd_dma_free when some device is opened/closed.
Note 2: routines for interrupt line and dma channel registering returns index do snd_card_t -> irqs and snd_card_t -> dmas arrays. This value isn't equal to interrupt number or dma channel number, but in driver irqnum or dmanum means irq or dma index (internal driver resource identification) and irq or dma means real irq or dma number.
int snd_irq = SND_DEFAULT_IRQ1;
int snd_dma1 = SND_DEFAULT_DMA1;
int snd_dma1_size = SND_DEFAULT_DMA_SIZE1;
static snd_card_t *snd_card = NULL;
static int snd_irqnum = SND_IRQ_DISABLE;
static void snd_soundcard_interrupt1( int irq, void *dev_id, struct pt_regs *regs )
{
... interrupt handler ...
}
void snd_soundcard_init_resources( void )
{
#ifdef EXAMPLE_FOR_ISA_BUS
static int possible_irqs[] = { 9, 10, 11, 7, -1 };
static int possible_dmas[] = { 1, 3, 0, -1 };
if ( (snd_irqnum = snd_register_interrupt( snd_card, "SoundCard", snd_irq, SND_IRQ_TYPE_ISA, snd_soundcard_interrupt, NULL, possible_irqs )) < 0 )
return snd_irqnum;
if ( (snd_dma1num = snd_register_dma_channel( snd_card, "SoundCard", snd_dma1, SND_DMA_TYPE_ISA, snd_dma1_size, possible_dmas )) < 0 )
return snd_dma1num;
#else /* EXAMPLE_FOR_PCI_BUS */
if ( (snd_irqnum = snd_register_interrupt( snd_card, "SoundCard", snd_irq, SND_IRQ_TYPE_PCI, snd_soundcard_interrupt, NULL, NULL )) < 0 )
return snd_irqnum;
if ( (snd_dma1num = snd_register_dma_channel( snd_card, "SoundCard", snd_dma1, SND_DMA_TYPE_PCI, snd_dma1_size, NULL )) < 0 )
return snd_dma1num;
#endif
}
int snd_soundcard_probe( unsigned short port )
{
if ( snd_register_ioport( snd_card, port, 8, "SoundCard - Codec" ) < 0 )
return -EBUSY;
if ( snd_register_ioport( snd_card, port + 0x100, 16, "SoundCard - Synthesizer" ) < 0 ) {
snd_unregister_ioports( snd_card );
return -EBUSY;
}
... hardware probe here - if fails - snd_unregister_ioports!!! ...
return 0;
}
Functions list:
PCI bus related structures and functions are in include/sndpci.h header file. Functions are designated for use with both type of kernels (2.0 and 2.1).
Read-only variables from struct snd_pci_dev structure which should be used:
Functions list:
struct snd_pci_dev pci_dev; /* use heap for this variable */
unsigned short cmd;
if ( snd_pci_find_device( PCI_VENDOR_ID_ENSONIQ,
PCI_DEVICE_ID_ENSONIQ_AUDIOPCI,
0,
&pci_dev ) < 0 )
return -ENODEV;
snd_printk( "First Ensoniq PCI soundcard found at 0x%x and irq %i\n",
pci_dev -> base_address[ 0 ] & ~3,
pci_dev -> irq );
snd_printk( "enabling Master..\n" );
snd_pci_read_config_word( &pci_dev, PCI_COMMAND, &cmd );
cmd |= PCI_COMMAND_IO | PCI_COMMAND_MASTER;
snd_pci_write_config_word( &pci_dev, PCI_COMMAND, cmd );