in hid-prodikeys.c [601:720]
static int pcmidi_snd_initialise(struct pcmidi_snd *pm)
{
static int dev;
struct snd_card *card;
struct snd_rawmidi *rwmidi;
int err;
static struct snd_device_ops ops = {
.dev_free = pcmidi_snd_free,
};
if (pm->ifnum != 1)
return 0; /* only set up midi device ONCE for interace 1 */
if (dev >= SNDRV_CARDS)
return -ENODEV;
if (!enable[dev]) {
dev++;
return -ENOENT;
}
/* Setup sound card */
err = snd_card_new(&pm->pk->hdev->dev, index[dev], id[dev],
THIS_MODULE, 0, &card);
if (err < 0) {
pk_error("failed to create pc-midi sound card\n");
err = -ENOMEM;
goto fail;
}
pm->card = card;
/* Setup sound device */
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pm, &ops);
if (err < 0) {
pk_error("failed to create pc-midi sound device: error %d\n",
err);
goto fail;
}
strncpy(card->driver, shortname, sizeof(card->driver));
strncpy(card->shortname, shortname, sizeof(card->shortname));
strncpy(card->longname, longname, sizeof(card->longname));
/* Set up rawmidi */
err = snd_rawmidi_new(card, card->shortname, 0,
0, 1, &rwmidi);
if (err < 0) {
pk_error("failed to create pc-midi rawmidi device: error %d\n",
err);
goto fail;
}
pm->rwmidi = rwmidi;
strncpy(rwmidi->name, card->shortname, sizeof(rwmidi->name));
rwmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT;
rwmidi->private_data = pm;
snd_rawmidi_set_ops(rwmidi, SNDRV_RAWMIDI_STREAM_INPUT,
&pcmidi_in_ops);
/* create sysfs variables */
err = device_create_file(&pm->pk->hdev->dev,
sysfs_device_attr_channel);
if (err < 0) {
pk_error("failed to create sysfs attribute channel: error %d\n",
err);
goto fail;
}
err = device_create_file(&pm->pk->hdev->dev,
sysfs_device_attr_sustain);
if (err < 0) {
pk_error("failed to create sysfs attribute sustain: error %d\n",
err);
goto fail_attr_sustain;
}
err = device_create_file(&pm->pk->hdev->dev,
sysfs_device_attr_octave);
if (err < 0) {
pk_error("failed to create sysfs attribute octave: error %d\n",
err);
goto fail_attr_octave;
}
spin_lock_init(&pm->rawmidi_in_lock);
init_sustain_timers(pm);
err = pcmidi_set_operational(pm);
if (err < 0) {
pk_error("failed to find output report\n");
goto fail_register;
}
/* register it */
err = snd_card_register(card);
if (err < 0) {
pk_error("failed to register pc-midi sound card: error %d\n",
err);
goto fail_register;
}
dbg_hid("pcmidi_snd_initialise finished ok\n");
return 0;
fail_register:
stop_sustain_timers(pm);
device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_octave);
fail_attr_octave:
device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_sustain);
fail_attr_sustain:
device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_channel);
fail:
if (pm->card) {
snd_card_free(pm->card);
pm->card = NULL;
}
return err;
}