/* * registration of the synth device */ int snd_seq_oss_synth_register(struct snd_seq_device *dev) { int i; struct seq_oss_synth *rec; struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev); unsigned long flags; if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL) { snd_printk(KERN_ERR "can't malloc synth info\n"); return -ENOMEM; } rec->seq_device = -1; rec->synth_type = reg->type; rec->synth_subtype = reg->subtype; rec->nr_voices = reg->nvoices; rec->oper = reg->oper; rec->private_data = reg->private_data; rec->opened = 0; snd_use_lock_init(&rec->use_lock); /* copy and truncate the name of synth device */ strlcpy(rec->name, dev->name, sizeof(rec->name)); /* registration */ spin_lock_irqsave(®ister_lock, flags); for (i = 0; i < max_synth_devs; i++) { if (synth_devs[i] == NULL) break; } if (i >= max_synth_devs) { if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) { spin_unlock_irqrestore(®ister_lock, flags); snd_printk(KERN_ERR "no more synth slot\n"); kfree(rec); return -ENOMEM; } max_synth_devs++; } rec->seq_device = i; synth_devs[i] = rec; #ifdef CONFIG_DEBUG_PRINTK debug_printk(("synth %s registered %d\n", rec->name, i)); #else debug_; #endif spin_unlock_irqrestore(®ister_lock, flags); dev->driver_data = rec; #ifdef SNDRV_OSS_INFO_DEV_SYNTH if (i < SNDRV_CARDS) snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, i, rec->name); #endif return 0; }
/* * create a new hardware dependent device for Emu8000 */ static int snd_emu8000_new_device(struct snd_seq_device *dev) { struct snd_emu8000 *hw; struct snd_emux *emu; hw = *(struct snd_emu8000**)SNDRV_SEQ_DEVICE_ARGPTR(dev); if (hw == NULL) return -EINVAL; if (hw->emu) return -EBUSY; /* already exists..? */ if (snd_emux_new(&emu) < 0) return -ENOMEM; hw->emu = emu; snd_emu8000_ops_setup(hw); emu->hw = hw; emu->max_voices = EMU8000_DRAM_VOICES; emu->num_ports = hw->seq_ports; if (hw->memhdr) { ; snd_util_memhdr_free(hw->memhdr); } hw->memhdr = snd_util_memhdr_new(hw->mem_size); if (hw->memhdr == NULL) { snd_emux_free(emu); hw->emu = NULL; return -ENOMEM; } emu->memhdr = hw->memhdr; emu->midi_ports = hw->seq_ports < 2 ? hw->seq_ports : 2; /* number of virmidi ports */ emu->midi_devidx = 1; emu->linear_panning = 1; emu->hwdep_idx = 2; /* FIXED */ if (snd_emux_register(emu, dev->card, hw->index, "Emu8000") < 0) { snd_emux_free(emu); snd_util_memhdr_free(hw->memhdr); hw->emu = NULL; hw->memhdr = NULL; return -ENOMEM; } if (hw->mem_size > 0) snd_emu8000_pcm_new(dev->card, hw, 1); dev->driver_data = hw; return 0; }
static int snd_opl4_create_seq_dev(struct snd_opl4 *opl4, int seq_device) { opl4->seq_dev_num = seq_device; if (snd_seq_device_new(opl4->card, seq_device, SNDRV_SEQ_DEV_ID_OPL4, sizeof(struct snd_opl4 *), &opl4->seq_dev) >= 0) { strcpy(opl4->seq_dev->name, "OPL4 Wavetable"); *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(opl4->seq_dev) = opl4; opl4->seq_dev->private_data = opl4; opl4->seq_dev->private_free = snd_opl4_seq_dev_free; } return 0; }
static int snd_opl3_seq_new_device(struct snd_seq_device *dev) { struct snd_opl3 *opl3; int client, err; char name[32]; int opl_ver; opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev); if (opl3 == NULL) return -EINVAL; spin_lock_init(&opl3->voice_lock); opl3->seq_client = -1; /* allocate new client */ opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8; sprintf(name, "OPL%i FM synth", opl_ver); client = opl3->seq_client = snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num, name); if (client < 0) return client; if ((err = snd_opl3_synth_create_port(opl3)) < 0) { snd_seq_delete_kernel_client(client); opl3->seq_client = -1; return err; } /* initialize instrument list */ opl3->ilist = snd_seq_instr_list_new(); if (opl3->ilist == NULL) { snd_seq_delete_kernel_client(client); opl3->seq_client = -1; return -ENOMEM; } opl3->ilist->flags = SNDRV_SEQ_INSTR_FLG_DIRECT; snd_seq_fm_init(&opl3->fm_ops, NULL); /* setup system timer */ init_timer(&opl3->tlist); opl3->tlist.function = snd_opl3_timer_func; opl3->tlist.data = (unsigned long) opl3; spin_lock_init(&opl3->sys_timer_lock); opl3->sys_timer_status = 0; #ifdef CONFIG_SND_SEQUENCER_OSS snd_opl3_init_seq_oss(opl3, name); #endif return 0; }
static int snd_opl4_seq_delete_device(struct snd_seq_device *dev) { struct snd_opl4 *opl4; opl4 = *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(dev); if (!opl4) return -EINVAL; if (opl4->seq_client >= 0) { snd_seq_delete_kernel_client(opl4->seq_client); opl4->seq_client = -1; } return 0; }
/* * create a new hardware dependent device for Emu10k1 */ static int snd_emu10k1_synth_new_device(struct snd_seq_device *dev) { struct snd_emux *emux; struct snd_emu10k1 *hw; struct snd_emu10k1_synth_arg *arg; unsigned long flags; arg = SNDRV_SEQ_DEVICE_ARGPTR(dev); if (arg == NULL) return -EINVAL; if (arg->seq_ports <= 0) return 0; /* nothing */ if (arg->max_voices < 1) arg->max_voices = 1; else if (arg->max_voices > 64) arg->max_voices = 64; if (snd_emux_new(&emux) < 0) return -ENOMEM; snd_emu10k1_ops_setup(emux); hw = arg->hwptr; emux->hw = hw; emux->max_voices = arg->max_voices; emux->num_ports = arg->seq_ports; emux->pitch_shift = -501; emux->memhdr = hw->memhdr; /* maximum two ports */ emux->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2; /* audigy has two external midis */ emux->midi_devidx = hw->audigy ? 2 : 1; emux->linear_panning = 0; emux->hwdep_idx = 2; /* FIXED */ if (snd_emux_register(emux, dev->card, arg->index, "Emu10k1") < 0) { snd_emux_free(emux); return -ENOMEM; } spin_lock_irqsave(&hw->voice_lock, flags); hw->synth = emux; hw->get_synth_voice = snd_emu10k1_synth_get_voice; spin_unlock_irqrestore(&hw->voice_lock, flags); dev->driver_data = emux; return 0; }
/* * registration of the synth device */ int snd_seq_oss_synth_probe(struct device *_dev) { struct snd_seq_device *dev = to_seq_dev(_dev); int i; struct seq_oss_synth *rec; struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev); unsigned long flags; rec = kzalloc(sizeof(*rec), GFP_KERNEL); if (!rec) return -ENOMEM; rec->seq_device = -1; rec->synth_type = reg->type; rec->synth_subtype = reg->subtype; rec->nr_voices = reg->nvoices; rec->oper = reg->oper; rec->private_data = reg->private_data; rec->opened = 0; snd_use_lock_init(&rec->use_lock); /* copy and truncate the name of synth device */ strlcpy(rec->name, dev->name, sizeof(rec->name)); /* registration */ spin_lock_irqsave(®ister_lock, flags); for (i = 0; i < max_synth_devs; i++) { if (synth_devs[i] == NULL) break; } if (i >= max_synth_devs) { if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) { spin_unlock_irqrestore(®ister_lock, flags); pr_err("ALSA: seq_oss: no more synth slot\n"); kfree(rec); return -ENOMEM; } max_synth_devs++; } rec->seq_device = i; synth_devs[i] = rec; spin_unlock_irqrestore(®ister_lock, flags); dev->driver_data = rec; #ifdef SNDRV_OSS_INFO_DEV_SYNTH if (i < SNDRV_CARDS) snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, i, rec->name); #endif return 0; }
static int snd_gus_synth_delete_device(snd_seq_device_t *dev) { snd_gus_card_t *gus; gus = *(snd_gus_card_t**)SNDRV_SEQ_DEVICE_ARGPTR(dev); if (gus == NULL) return -EINVAL; if (gus->gf1.seq_client >= 0) { snd_seq_delete_kernel_client(gus->gf1.seq_client); gus->gf1.seq_client = -1; } if (gus->gf1.ilist) snd_seq_instr_list_free(&gus->gf1.ilist); return 0; }
static int snd_opl3_seq_delete_device(struct snd_seq_device *dev) { struct snd_opl3 *opl3; opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev); if (opl3 == NULL) return -EINVAL; #ifdef CONFIG_SND_SEQUENCER_OSS snd_opl3_free_seq_oss(opl3); #endif if (opl3->seq_client >= 0) { snd_seq_delete_kernel_client(opl3->seq_client); opl3->seq_client = -1; } return 0; }
static int snd_opl3_seq_probe(struct device *_dev) { struct snd_seq_device *dev = to_seq_dev(_dev); struct snd_opl3 *opl3; int client, err; char name[32]; int opl_ver; opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev); if (opl3 == NULL) return -EINVAL; spin_lock_init(&opl3->voice_lock); opl3->seq_client = -1; /* allocate new client */ opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8; sprintf(name, "OPL%i FM synth", opl_ver); client = opl3->seq_client = snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num, name); if (client < 0) return client; if ((err = snd_opl3_synth_create_port(opl3)) < 0) { snd_seq_delete_kernel_client(client); opl3->seq_client = -1; return err; } /* setup system timer */ setup_timer(&opl3->tlist, snd_opl3_timer_func, (unsigned long) opl3); spin_lock_init(&opl3->sys_timer_lock); opl3->sys_timer_status = 0; #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) snd_opl3_init_seq_oss(opl3, name); #endif return 0; }
void snd_emux_init_seq_oss(struct snd_emux *emu) { struct snd_seq_oss_reg *arg; struct snd_seq_device *dev; if (snd_seq_device_new(emu->card, 0, SNDRV_SEQ_DEV_ID_OSS, sizeof(struct snd_seq_oss_reg), &dev) < 0) return; emu->oss_synth = dev; strcpy(dev->name, emu->name); arg = SNDRV_SEQ_DEVICE_ARGPTR(dev); arg->type = SYNTH_TYPE_SAMPLE; arg->subtype = SAMPLE_TYPE_AWE32; arg->nvoices = emu->max_voices; arg->oper = oss_callback; arg->private_data = emu; /* register to OSS synth table */ snd_device_register(emu->card, dev); }
static int snd_card_emu10k1_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { static int dev; struct snd_card *card; struct snd_emu10k1 *emu; #ifdef ENABLE_SYNTH struct snd_seq_device *wave = NULL; #endif int err; if (dev >= SNDRV_CARDS) return -ENODEV; if (!enable[dev]) { dev++; return -ENOENT; } err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); if (err < 0) return err; if (max_buffer_size[dev] < 32) max_buffer_size[dev] = 32; else if (max_buffer_size[dev] > 1024) max_buffer_size[dev] = 1024; if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev], (long)max_buffer_size[dev] * 1024 * 1024, enable_ir[dev], subsystem[dev], &emu)) < 0) goto error; card->private_data = emu; emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f; if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) goto error; if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) goto error; if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0) goto error; /* This stores the periods table. */ if (emu->card_capabilities->ca0151_chip) { /* P16V */ if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &emu->p16v_buffer)) < 0) goto error; } if ((err = snd_emu10k1_mixer(emu, 0, 3)) < 0) goto error; if ((err = snd_emu10k1_timer(emu, 0)) < 0) goto error; if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0) goto error; if (emu->card_capabilities->ca0151_chip) { /* P16V */ if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) goto error; } if (emu->audigy) { if ((err = snd_emu10k1_audigy_midi(emu)) < 0) goto error; } else { if ((err = snd_emu10k1_midi(emu)) < 0) goto error; } if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0) goto error; #ifdef ENABLE_SYNTH if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, sizeof(struct snd_emu10k1_synth_arg), &wave) < 0 || wave == NULL) { snd_printk(KERN_WARNING "can't initialize Emu10k1 wavetable synth\n"); } else { struct snd_emu10k1_synth_arg *arg; arg = SNDRV_SEQ_DEVICE_ARGPTR(wave); strcpy(wave->name, "Emu-10k1 Synth"); arg->hwptr = emu; arg->index = 1; arg->seq_ports = seq_ports[dev]; arg->max_voices = max_synth_voices[dev]; } #endif strlcpy(card->driver, emu->card_capabilities->driver, sizeof(card->driver)); strlcpy(card->shortname, emu->card_capabilities->name, sizeof(card->shortname)); snprintf(card->longname, sizeof(card->longname), "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", card->shortname, emu->revision, emu->serial, emu->port, emu->irq); if ((err = snd_card_register(card)) < 0) goto error; pci_set_drvdata(pci, card); dev++; return 0; error: snd_card_free(card); return err; }
// constructor -- see "Constructor" sub-section static int __devinit snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { static int dev; snd_card_t *card; vortex_t *chip; int err; // (1) if (dev >= SNDRV_CARDS) return -ENODEV; if (!enable[dev]) { dev++; return -ENOENT; } // (2) card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); if (card == NULL) return -ENOMEM; // (3) if ((err = snd_vortex_create(card, pci, &chip)) < 0) { snd_card_free(card); return err; } snd_vortex_workaround(pci, pcifix[dev]); // (4) Alloc components. // ADB pcm. if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_ADB)) < 0) { snd_card_free(card); return err; } #ifndef CHIP_AU8820 // ADB SPDIF if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_SPDIF, 1)) < 0) { snd_card_free(card); return err; } // A3D if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_A3D, NR_A3D)) < 0) { snd_card_free(card); return err; } #endif /* // ADB I2S if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_I2S, 1)) < 0) { snd_card_free(card); return err; } */ #ifndef CHIP_AU8810 // WT pcm. if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_WT, NR_WT)) < 0) { snd_card_free(card); return err; } #endif // snd_ac97_mixer and Vortex mixer. if ((err = snd_vortex_mixer(chip)) < 0) { snd_card_free(card); return err; } if ((err = snd_vortex_midi(chip)) < 0) { snd_card_free(card); return err; } if ((err = vortex_gameport_register(chip)) < 0) { snd_card_free(card); return err; } #if 0 if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH, sizeof(snd_vortex_synth_arg_t), &wave) < 0 || wave == NULL) { snd_printk("Can't initialize Aureal wavetable synth\n"); } else { snd_vortex_synth_arg_t *arg; arg = SNDRV_SEQ_DEVICE_ARGPTR(wave); strcpy(wave->name, "Aureal Synth"); arg->hwptr = vortex; arg->index = 1; arg->seq_ports = seq_ports[dev]; arg->max_voices = max_synth_voices[dev]; } #endif // (5) strcpy(card->driver, CARD_NAME_SHORT); strcpy(card->shortname, CARD_NAME_SHORT); sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->io, chip->irq); if ((err = pci_read_config_word(pci, PCI_DEVICE_ID, &(chip->device))) < 0) { snd_card_free(card); return err; } if ((err = pci_read_config_word(pci, PCI_VENDOR_ID, &(chip->vendor))) < 0) { snd_card_free(card); return err; } if ((err = pci_read_config_byte(pci, PCI_REVISION_ID, &(chip->rev))) < 0) { snd_card_free(card); return err; } #ifdef CHIP_AU8830 if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) { printk(KERN_ALERT "vortex: The revision (%x) of your card has not been seen before.\n", chip->rev); printk(KERN_ALERT "vortex: Please email the results of 'lspci -vv' to [email protected].\n"); snd_card_free(card); err = -ENODEV; return err; } #endif // (6) if ((err = snd_card_register(card)) < 0) { snd_card_free(card); return err; } // (7) pci_set_drvdata(pci, card); dev++; vortex_connect_default(chip, 1); vortex_enable_int(chip); return 0; }
static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { static int dev; snd_card_t *card; emu10k1_t *emu; #ifdef ENABLE_SYNTH snd_seq_device_t *wave = NULL; #endif int err; if (dev >= SNDRV_CARDS) return -ENODEV; if (!enable[dev]) { dev++; return -ENOENT; } card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); if (card == NULL) return -ENOMEM; if (max_buffer_size[dev] < 32) max_buffer_size[dev] = 32; else if (max_buffer_size[dev] > 1024) max_buffer_size[dev] = 1024; if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev], (long)max_buffer_size[dev] * 1024 * 1024, enable_ir[dev], &emu)) < 0) { snd_card_free(card); return err; } if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) { snd_card_free(card); return err; } if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) { snd_card_free(card); return err; } if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0) { snd_card_free(card); return err; } if ((err = snd_emu10k1_mixer(emu)) < 0) { snd_card_free(card); return err; } if ((err = snd_emu10k1_timer(emu, 0)) < 0) { snd_card_free(card); return err; } if (emu->audigy) { if ((err = snd_emu10k1_audigy_midi(emu)) < 0) { snd_card_free(card); return err; } } else { if ((err = snd_emu10k1_midi(emu)) < 0) { snd_card_free(card); return err; } } if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0) { snd_card_free(card); return err; } #ifdef ENABLE_SYNTH if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, sizeof(snd_emu10k1_synth_arg_t), &wave) < 0 || wave == NULL) { snd_printk("can't initialize Emu10k1 wavetable synth\n"); } else { snd_emu10k1_synth_arg_t *arg; arg = SNDRV_SEQ_DEVICE_ARGPTR(wave); strcpy(wave->name, "Emu-10k1 Synth"); arg->hwptr = emu; arg->index = 1; arg->seq_ports = seq_ports[dev]; arg->max_voices = max_synth_voices[dev]; } #endif if (emu->audigy && (emu->serial == 0x10011102) ) { strcpy(card->driver, "Audigy2"); strcpy(card->shortname, "Sound Blaster Audigy2_Value"); } else if (emu->audigy && (emu->revision == 4) ) { strcpy(card->driver, "Audigy2"); strcpy(card->shortname, "Sound Blaster Audigy2"); } else if (emu->audigy) { strcpy(card->driver, "Audigy"); strcpy(card->shortname, "Sound Blaster Audigy"); } else if (emu->APS) { strcpy(card->driver, "E-mu APS"); strcpy(card->shortname, "E-mu APS"); } else { strcpy(card->driver, "EMU10K1"); strcpy(card->shortname, "Sound Blaster Live!"); } sprintf(card->longname, "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", card->shortname, emu->revision, emu->serial, emu->port, emu->irq); if ((err = snd_card_register(card)) < 0) { snd_card_free(card); return err; } pci_set_drvdata(pci, card); dev++; return 0; }
static int snd_gus_synth_new_device(snd_seq_device_t *dev) { snd_gus_card_t *gus; int client, i; snd_seq_client_callback_t callbacks; snd_seq_client_info_t *cinfo; snd_seq_port_subscribe_t sub; snd_iwffff_ops_t *iwops; snd_gf1_ops_t *gf1ops; snd_simple_ops_t *simpleops; gus = *(snd_gus_card_t**)SNDRV_SEQ_DEVICE_ARGPTR(dev); if (gus == NULL) return -EINVAL; init_MUTEX(&gus->register_mutex); gus->gf1.seq_client = -1; cinfo = kmalloc(sizeof(*cinfo), GFP_KERNEL); if (! cinfo) return -ENOMEM; /* allocate new client */ memset(&callbacks, 0, sizeof(callbacks)); callbacks.private_data = gus; callbacks.allow_output = callbacks.allow_input = 1; client = gus->gf1.seq_client = snd_seq_create_kernel_client(gus->card, 1, &callbacks); if (client < 0) { kfree(cinfo); return client; } /* change name of client */ memset(cinfo, 0, sizeof(*cinfo)); cinfo->client = client; cinfo->type = KERNEL_CLIENT; sprintf(cinfo->name, gus->interwave ? "AMD InterWave" : "GF1"); snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, cinfo); kfree(cinfo); for (i = 0; i < 4; i++) snd_gus_synth_create_port(gus, i); gus->gf1.ilist = snd_seq_instr_list_new(); if (gus->gf1.ilist == NULL) { snd_seq_delete_kernel_client(client); gus->gf1.seq_client = -1; return -ENOMEM; } gus->gf1.ilist->flags = SNDRV_SEQ_INSTR_FLG_DIRECT; simpleops = &gus->gf1.simple_ops; snd_seq_simple_init(simpleops, gus, NULL); simpleops->put_sample = snd_gus_simple_put_sample; simpleops->get_sample = snd_gus_simple_get_sample; simpleops->remove_sample = snd_gus_simple_remove_sample; simpleops->notify = snd_gus_synth_instr_notify; gf1ops = &gus->gf1.gf1_ops; snd_seq_gf1_init(gf1ops, gus, &simpleops->kops); gf1ops->put_sample = snd_gus_gf1_put_sample; gf1ops->get_sample = snd_gus_gf1_get_sample; gf1ops->remove_sample = snd_gus_gf1_remove_sample; gf1ops->notify = snd_gus_synth_instr_notify; iwops = &gus->gf1.iwffff_ops; snd_seq_iwffff_init(iwops, gus, &gf1ops->kops); iwops->put_sample = snd_gus_iwffff_put_sample; iwops->get_sample = snd_gus_iwffff_get_sample; iwops->remove_sample = snd_gus_iwffff_remove_sample; iwops->notify = snd_gus_synth_instr_notify; memset(&sub, 0, sizeof(sub)); sub.sender.client = SNDRV_SEQ_CLIENT_SYSTEM; sub.sender.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE; sub.dest.client = client; sub.dest.port = 0; snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &sub); return 0; }