/* * close the device */ int snd_opl3_release(struct snd_hwdep * hw, struct file *file) { struct snd_opl3 *opl3 = hw->private_data; snd_opl3_reset(opl3); return 0; }
int snd_opl3_synth_setup(struct snd_opl3 * opl3) { int idx; mutex_lock(&opl3->access_mutex); if (opl3->used) { mutex_unlock(&opl3->access_mutex); return -EBUSY; } opl3->used++; mutex_unlock(&opl3->access_mutex); snd_opl3_reset(opl3); for (idx = 0; idx < MAX_OPL3_VOICES; idx++) { opl3->voices[idx].state = SNDRV_OPL3_ST_OFF; opl3->voices[idx].time = 0; opl3->voices[idx].keyon_reg = 0x00; } opl3->use_time = 0; opl3->connection_reg = 0x00; if (opl3->hardware >= OPL3_HW_OPL3) { /* Clear 4-op connections */ opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, opl3->connection_reg); opl3->max_voices = MAX_OPL3_VOICES; } return 0; }
void snd_opl3_synth_cleanup(struct snd_opl3 * opl3) { unsigned long flags; /* Stop system timer */ spin_lock_irqsave(&opl3->sys_timer_lock, flags); if (opl3->sys_timer_status) { del_timer(&opl3->tlist); opl3->sys_timer_status = 0; } spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); snd_opl3_reset(opl3); mutex_lock(&opl3->access_mutex); opl3->used--; mutex_unlock(&opl3->access_mutex); }
void snd_opl3_synth_cleanup(struct snd_opl3 * opl3) { unsigned long flags; struct snd_hwdep *hwdep; /* Stop system timer */ spin_lock_irqsave(&opl3->sys_timer_lock, flags); if (opl3->sys_timer_status) { del_timer(&opl3->tlist); opl3->sys_timer_status = 0; } spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); snd_opl3_reset(opl3); hwdep = opl3->hwdep; mutex_lock(&hwdep->open_mutex); hwdep->used--; mutex_unlock(&hwdep->open_mutex); wake_up(&hwdep->open_wait); }
/* * ioctl for hwdep device: */ int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg) { struct snd_opl3 *opl3 = hw->private_data; void __user *argp = (void __user *)arg; if (snd_BUG_ON(!opl3)) return -EINVAL; switch (cmd) { /* get information */ case SNDRV_DM_FM_IOCTL_INFO: { struct snd_dm_fm_info info; info.fm_mode = opl3->fm_mode; info.rhythm = opl3->rhythm; if (copy_to_user(argp, &info, sizeof(struct snd_dm_fm_info))) return -EFAULT; return 0; } case SNDRV_DM_FM_IOCTL_RESET: #ifdef CONFIG_SND_OSSEMUL case SNDRV_DM_FM_OSS_IOCTL_RESET: #endif snd_opl3_reset(opl3); return 0; case SNDRV_DM_FM_IOCTL_PLAY_NOTE: #ifdef CONFIG_SND_OSSEMUL case SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE: #endif { struct snd_dm_fm_note note; if (copy_from_user(¬e, argp, sizeof(struct snd_dm_fm_note))) return -EFAULT; return snd_opl3_play_note(opl3, ¬e); } case SNDRV_DM_FM_IOCTL_SET_VOICE: #ifdef CONFIG_SND_OSSEMUL case SNDRV_DM_FM_OSS_IOCTL_SET_VOICE: #endif { struct snd_dm_fm_voice voice; if (copy_from_user(&voice, argp, sizeof(struct snd_dm_fm_voice))) return -EFAULT; return snd_opl3_set_voice(opl3, &voice); } case SNDRV_DM_FM_IOCTL_SET_PARAMS: #ifdef CONFIG_SND_OSSEMUL case SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS: #endif { struct snd_dm_fm_params params; if (copy_from_user(¶ms, argp, sizeof(struct snd_dm_fm_params))) return -EFAULT; return snd_opl3_set_params(opl3, ¶ms); } case SNDRV_DM_FM_IOCTL_SET_MODE: #ifdef CONFIG_SND_OSSEMUL case SNDRV_DM_FM_OSS_IOCTL_SET_MODE: #endif return snd_opl3_set_mode(opl3, (int) arg); case SNDRV_DM_FM_IOCTL_SET_CONNECTION: #ifdef CONFIG_SND_OSSEMUL case SNDRV_DM_FM_OSS_IOCTL_SET_OPL: #endif return snd_opl3_set_connection(opl3, (int) arg); #ifdef OPL3_SUPPORT_SYNTH case SNDRV_DM_FM_IOCTL_CLEAR_PATCHES: snd_opl3_clear_patches(opl3); return 0; #endif #ifdef CONFIG_SND_DEBUG default: snd_printk(KERN_WARNING "unknown IOCTL: 0x%x\n", cmd); #endif } return -ENOTTY; }