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.