0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "opl3_voice.h"
0012 #include <linux/init.h>
0013 #include <linux/moduleparam.h>
0014 #include <linux/module.h>
0015 #include <sound/initval.h>
0016
0017 MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
0018 MODULE_LICENSE("GPL");
0019 MODULE_DESCRIPTION("ALSA driver for OPL3 FM synth");
0020
0021 bool use_internal_drums = 0;
0022 module_param(use_internal_drums, bool, 0444);
0023 MODULE_PARM_DESC(use_internal_drums, "Enable internal OPL2/3 drums.");
0024
0025 int snd_opl3_synth_use_inc(struct snd_opl3 * opl3)
0026 {
0027 if (!try_module_get(opl3->card->module))
0028 return -EFAULT;
0029 return 0;
0030
0031 }
0032
0033 void snd_opl3_synth_use_dec(struct snd_opl3 * opl3)
0034 {
0035 module_put(opl3->card->module);
0036 }
0037
0038 int snd_opl3_synth_setup(struct snd_opl3 * opl3)
0039 {
0040 int idx;
0041 struct snd_hwdep *hwdep = opl3->hwdep;
0042
0043 mutex_lock(&hwdep->open_mutex);
0044 if (hwdep->used) {
0045 mutex_unlock(&hwdep->open_mutex);
0046 return -EBUSY;
0047 }
0048 hwdep->used++;
0049 mutex_unlock(&hwdep->open_mutex);
0050
0051 snd_opl3_reset(opl3);
0052
0053 for (idx = 0; idx < MAX_OPL3_VOICES; idx++) {
0054 opl3->voices[idx].state = SNDRV_OPL3_ST_OFF;
0055 opl3->voices[idx].time = 0;
0056 opl3->voices[idx].keyon_reg = 0x00;
0057 }
0058 opl3->use_time = 0;
0059 opl3->connection_reg = 0x00;
0060 if (opl3->hardware >= OPL3_HW_OPL3) {
0061
0062 opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT,
0063 opl3->connection_reg);
0064 opl3->max_voices = MAX_OPL3_VOICES;
0065 }
0066 return 0;
0067 }
0068
0069 void snd_opl3_synth_cleanup(struct snd_opl3 * opl3)
0070 {
0071 unsigned long flags;
0072 struct snd_hwdep *hwdep;
0073
0074
0075 spin_lock_irqsave(&opl3->sys_timer_lock, flags);
0076 if (opl3->sys_timer_status) {
0077 del_timer(&opl3->tlist);
0078 opl3->sys_timer_status = 0;
0079 }
0080 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
0081
0082 snd_opl3_reset(opl3);
0083 hwdep = opl3->hwdep;
0084 mutex_lock(&hwdep->open_mutex);
0085 hwdep->used--;
0086 mutex_unlock(&hwdep->open_mutex);
0087 wake_up(&hwdep->open_wait);
0088 }
0089
0090 static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe * info)
0091 {
0092 struct snd_opl3 *opl3 = private_data;
0093 int err;
0094
0095 err = snd_opl3_synth_setup(opl3);
0096 if (err < 0)
0097 return err;
0098
0099 if (use_internal_drums) {
0100
0101 opl3->voices[6].state = opl3->voices[7].state =
0102 opl3->voices[8].state = SNDRV_OPL3_ST_NOT_AVAIL;
0103 snd_opl3_load_drums(opl3);
0104 opl3->drum_reg = OPL3_PERCUSSION_ENABLE;
0105 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, opl3->drum_reg);
0106 } else {
0107 opl3->drum_reg = 0x00;
0108 }
0109
0110 if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
0111 err = snd_opl3_synth_use_inc(opl3);
0112 if (err < 0)
0113 return err;
0114 }
0115 opl3->synth_mode = SNDRV_OPL3_MODE_SEQ;
0116 return 0;
0117 }
0118
0119 static int snd_opl3_synth_unuse(void *private_data, struct snd_seq_port_subscribe * info)
0120 {
0121 struct snd_opl3 *opl3 = private_data;
0122
0123 snd_opl3_synth_cleanup(opl3);
0124
0125 if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM)
0126 snd_opl3_synth_use_dec(opl3);
0127 return 0;
0128 }
0129
0130
0131
0132
0133 const struct snd_midi_op opl3_ops = {
0134 .note_on = snd_opl3_note_on,
0135 .note_off = snd_opl3_note_off,
0136 .key_press = snd_opl3_key_press,
0137 .note_terminate = snd_opl3_terminate_note,
0138 .control = snd_opl3_control,
0139 .nrpn = snd_opl3_nrpn,
0140 .sysex = snd_opl3_sysex,
0141 };
0142
0143 static int snd_opl3_synth_event_input(struct snd_seq_event * ev, int direct,
0144 void *private_data, int atomic, int hop)
0145 {
0146 struct snd_opl3 *opl3 = private_data;
0147
0148 snd_midi_process_event(&opl3_ops, ev, opl3->chset);
0149 return 0;
0150 }
0151
0152
0153
0154 static void snd_opl3_synth_free_port(void *private_data)
0155 {
0156 struct snd_opl3 *opl3 = private_data;
0157
0158 snd_midi_channel_free_set(opl3->chset);
0159 }
0160
0161 static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
0162 {
0163 struct snd_seq_port_callback callbacks;
0164 char name[32];
0165 int voices, opl_ver;
0166
0167 voices = (opl3->hardware < OPL3_HW_OPL3) ?
0168 MAX_OPL2_VOICES : MAX_OPL3_VOICES;
0169 opl3->chset = snd_midi_channel_alloc_set(16);
0170 if (opl3->chset == NULL)
0171 return -ENOMEM;
0172 opl3->chset->private_data = opl3;
0173
0174 memset(&callbacks, 0, sizeof(callbacks));
0175 callbacks.owner = THIS_MODULE;
0176 callbacks.use = snd_opl3_synth_use;
0177 callbacks.unuse = snd_opl3_synth_unuse;
0178 callbacks.event_input = snd_opl3_synth_event_input;
0179 callbacks.private_free = snd_opl3_synth_free_port;
0180 callbacks.private_data = opl3;
0181
0182 opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
0183 sprintf(name, "OPL%i FM Port", opl_ver);
0184
0185 opl3->chset->client = opl3->seq_client;
0186 opl3->chset->port = snd_seq_event_port_attach(opl3->seq_client, &callbacks,
0187 SNDRV_SEQ_PORT_CAP_WRITE |
0188 SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
0189 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
0190 SNDRV_SEQ_PORT_TYPE_MIDI_GM |
0191 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
0192 SNDRV_SEQ_PORT_TYPE_HARDWARE |
0193 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
0194 16, voices,
0195 name);
0196 if (opl3->chset->port < 0) {
0197 int port;
0198 port = opl3->chset->port;
0199 snd_midi_channel_free_set(opl3->chset);
0200 return port;
0201 }
0202 return 0;
0203 }
0204
0205
0206
0207 static int snd_opl3_seq_probe(struct device *_dev)
0208 {
0209 struct snd_seq_device *dev = to_seq_dev(_dev);
0210 struct snd_opl3 *opl3;
0211 int client, err;
0212 char name[32];
0213 int opl_ver;
0214
0215 opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
0216 if (opl3 == NULL)
0217 return -EINVAL;
0218
0219 spin_lock_init(&opl3->voice_lock);
0220
0221 opl3->seq_client = -1;
0222
0223
0224 opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
0225 sprintf(name, "OPL%i FM synth", opl_ver);
0226 client = opl3->seq_client =
0227 snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num,
0228 name);
0229 if (client < 0)
0230 return client;
0231
0232 err = snd_opl3_synth_create_port(opl3);
0233 if (err < 0) {
0234 snd_seq_delete_kernel_client(client);
0235 opl3->seq_client = -1;
0236 return err;
0237 }
0238
0239
0240 timer_setup(&opl3->tlist, snd_opl3_timer_func, 0);
0241 spin_lock_init(&opl3->sys_timer_lock);
0242 opl3->sys_timer_status = 0;
0243
0244 #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
0245 snd_opl3_init_seq_oss(opl3, name);
0246 #endif
0247 return 0;
0248 }
0249
0250 static int snd_opl3_seq_remove(struct device *_dev)
0251 {
0252 struct snd_seq_device *dev = to_seq_dev(_dev);
0253 struct snd_opl3 *opl3;
0254
0255 opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
0256 if (opl3 == NULL)
0257 return -EINVAL;
0258
0259 #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
0260 snd_opl3_free_seq_oss(opl3);
0261 #endif
0262 if (opl3->seq_client >= 0) {
0263 snd_seq_delete_kernel_client(opl3->seq_client);
0264 opl3->seq_client = -1;
0265 }
0266 return 0;
0267 }
0268
0269 static struct snd_seq_driver opl3_seq_driver = {
0270 .driver = {
0271 .name = KBUILD_MODNAME,
0272 .probe = snd_opl3_seq_probe,
0273 .remove = snd_opl3_seq_remove,
0274 },
0275 .id = SNDRV_SEQ_DEV_ID_OPL3,
0276 .argsize = sizeof(struct snd_opl3 *),
0277 };
0278
0279 module_snd_seq_driver(opl3_seq_driver);