Chip-Specific Data

1. Allocating via snd_card_new().
2. Allocating an extra device.

Chip-specific information, e.g. the I/O port address, its resource pointer, or the irq number, is stored in the chip-specific record.


  struct mychip {
          ....
  };

          

In general, there are two ways of allocating the chip record.

1. Allocating via snd_card_new().

As mentioned above, you can pass the extra-data-length to the 5th argument of snd_card_new(), i.e.


  err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
                     sizeof(struct mychip), &card);

            

struct mychip is the type of the chip record.

In return, the allocated record can be accessed as


  struct mychip *chip = card->private_data;

            

With this method, you don't have to allocate twice. The record is released together with the card instance.

2. Allocating an extra device.

After allocating a card instance via snd_card_new() (with 0 on the 4th arg), call kzalloc().


  struct snd_card *card;
  struct mychip *chip;
  err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
                     0, &card);
  .....
  chip = kzalloc(sizeof(*chip), GFP_KERNEL);

            

The chip record should have the field to hold the card pointer at least,


  struct mychip {
          struct snd_card *card;
          ....
  };

            

Then, set the card pointer in the returned chip instance.


  chip->card = card;

            

Next, initialize the fields, and register this chip record as a low-level device with a specified ops,


  static struct snd_device_ops ops = {
          .dev_free =        snd_mychip_dev_free,
  };
  ....
  snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);

            

snd_mychip_dev_free() is the device-destructor function, which will call the real destructor.


  static int snd_mychip_dev_free(struct snd_device *device)
  {
          return snd_mychip_free(device->device_data);
  }

            

where snd_mychip_free() is the real destructor.