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.
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.
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.