The real constructor of PCI drivers is the probe callback.
      The probe callback and other component-constructors which are called
      from the probe callback cannot be used with
      the __init prefix
      because any PCI device could be a hotplug device. 
      
        In the probe callback, the following scheme is often used.
      
  static int dev;
  ....
  if (dev >= SNDRV_CARDS)
          return -ENODEV;
  if (!enable[dev]) {
          dev++;
          return -ENOENT;
  }
            where enable[dev] is the module option.
          Each time the probe callback is called, check the
        availability of the device. If not available, simply increment
        the device index and returns. dev will be incremented also
        later (step
        7). 
        
  struct snd_card *card;
  int err;
  ....
  err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
                     0, &card);
            
The details will be explained in the section Management of Cards and Components.
In this part, the PCI resources are allocated.
  struct mychip *chip;
  ....
  err = snd_mychip_create(card, pci, &chip);
  if (err < 0) {
          snd_card_free(card);
          return err;
  }
            The details will be explained in the section PCI Resource Management.
  strcpy(card->driver, "My Chip");
  strcpy(card->shortname, "My Own Chip 123");
  sprintf(card->longname, "%s at 0x%lx irq %i",
          card->shortname, chip->ioport, chip->irq);
            The driver field holds the minimal ID string of the chip. This is used by alsa-lib's configurator, so keep it simple but unique. Even the same driver can have different driver IDs to distinguish the functionality of each chip type.
          The shortname field is a string shown as more verbose
        name. The longname field contains the information
        shown in /proc/asound/cards. 
        
Here you define the basic components such as PCM, mixer (e.g. AC97), MIDI (e.g. MPU-401), and other interfaces. Also, if you want a proc file, define it here, too.
  err = snd_card_register(card);
  if (err < 0) {
          snd_card_free(card);
          return err;
  }
            
Will be explained in the section Management of Cards and Components, too.