1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Interface for OSS sequencer emulation 4 * 5 * Copyright (C) 1999 Takashi Iwai <tiwai@suse.de> 6 * 7 * Changes 8 * 19990227 Steve Ratcliffe Made separate file and merged in latest 9 * midi emulation. 10 */ 11 12 13 #include <linux/export.h> 14 #include <linux/uaccess.h> 15 #include <sound/core.h> 16 #include "emux_voice.h" 17 #include <sound/asoundef.h> 18 19 static int snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure); 20 static int snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg); 21 static int snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, 22 unsigned long ioarg); 23 static int snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format, 24 const char __user *buf, int offs, int count); 25 static int snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg); 26 static int snd_emux_event_oss_input(struct snd_seq_event *ev, int direct, 27 void *private, int atomic, int hop); 28 static void reset_port_mode(struct snd_emux_port *port, int midi_mode); 29 static void emuspec_control(struct snd_emux *emu, struct snd_emux_port *port, 30 int cmd, unsigned char *event, int atomic, int hop); 31 static void gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, 32 int cmd, unsigned char *event, int atomic, int hop); 33 static void fake_event(struct snd_emux *emu, struct snd_emux_port *port, 34 int ch, int param, int val, int atomic, int hop); 35 36 /* operators */ 37 static struct snd_seq_oss_callback oss_callback = { 38 .owner = THIS_MODULE, 39 .open = snd_emux_open_seq_oss, 40 .close = snd_emux_close_seq_oss, 41 .ioctl = snd_emux_ioctl_seq_oss, 42 .load_patch = snd_emux_load_patch_seq_oss, 43 .reset = snd_emux_reset_seq_oss, 44 }; 45 46 47 /* 48 * register OSS synth 49 */ 50 51 void 52 snd_emux_init_seq_oss(struct snd_emux *emu) 53 { 54 struct snd_seq_oss_reg *arg; 55 struct snd_seq_device *dev; 56 57 /* using device#1 here for avoiding conflicts with OPL3 */ 58 if (snd_seq_device_new(emu->card, 1, SNDRV_SEQ_DEV_ID_OSS, 59 sizeof(struct snd_seq_oss_reg), &dev) < 0) 60 return; 61 62 emu->oss_synth = dev; 63 strcpy(dev->name, emu->name); 64 arg = SNDRV_SEQ_DEVICE_ARGPTR(dev); 65 arg->type = SYNTH_TYPE_SAMPLE; 66 arg->subtype = SAMPLE_TYPE_AWE32; 67 arg->nvoices = emu->max_voices; 68 arg->oper = oss_callback; 69 arg->private_data = emu; 70 71 /* register to OSS synth table */ 72 snd_device_register(emu->card, dev); 73 } 74 75 76 /* 77 * unregister 78 */ 79 void 80 snd_emux_detach_seq_oss(struct snd_emux *emu) 81 { 82 if (emu->oss_synth) { 83 snd_device_free(emu->card, emu->oss_synth); 84 emu->oss_synth = NULL; 85 } 86 } 87 88 89 /* use port number as a unique soundfont client number */ 90 #define SF_CLIENT_NO(p) ((p) + 0x1000) 91 92 /* 93 * open port for OSS sequencer 94 */ 95 static int 96 snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure) 97 { 98 struct snd_emux *emu; 99 struct snd_emux_port *p; 100 struct snd_seq_port_callback callback; 101 char tmpname[64]; 102 103 emu = closure; 104 if (snd_BUG_ON(!arg || !emu)) 105 return -ENXIO; 106 107 if (!snd_emux_inc_count(emu)) 108 return -EFAULT; 109 110 memset(&callback, 0, sizeof(callback)); 111 callback.owner = THIS_MODULE; 112 callback.event_input = snd_emux_event_oss_input; 113 114 sprintf(tmpname, "%s OSS Port", emu->name); 115 p = snd_emux_create_port(emu, tmpname, 32, 116 1, &callback); 117 if (p == NULL) { 118 snd_printk(KERN_ERR "can't create port\n"); 119 snd_emux_dec_count(emu); 120 return -ENOMEM; 121 } 122 123 /* fill the argument data */ 124 arg->private_data = p; 125 arg->addr.client = p->chset.client; 126 arg->addr.port = p->chset.port; 127 p->oss_arg = arg; 128 129 reset_port_mode(p, arg->seq_mode); 130 131 snd_emux_reset_port(p); 132 return 0; 133 } 134 135 136 #define DEFAULT_DRUM_FLAGS ((1<<9) | (1<<25)) 137 138 /* 139 * reset port mode 140 */ 141 static void 142 reset_port_mode(struct snd_emux_port *port, int midi_mode) 143 { 144 if (midi_mode) { 145 port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_MIDI; 146 port->drum_flags = DEFAULT_DRUM_FLAGS; 147 port->volume_atten = 0; 148 port->oss_arg->event_passing = SNDRV_SEQ_OSS_PROCESS_KEYPRESS; 149 } else { 150 port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_SYNTH; 151 port->drum_flags = 0; 152 port->volume_atten = 32; 153 port->oss_arg->event_passing = SNDRV_SEQ_OSS_PROCESS_EVENTS; 154 } 155 } 156 157 158 /* 159 * close port 160 */ 161 static int 162 snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg) 163 { 164 struct snd_emux *emu; 165 struct snd_emux_port *p; 166 167 if (snd_BUG_ON(!arg)) 168 return -ENXIO; 169 p = arg->private_data; 170 if (snd_BUG_ON(!p)) 171 return -ENXIO; 172 173 emu = p->emu; 174 if (snd_BUG_ON(!emu)) 175 return -ENXIO; 176 177 snd_emux_sounds_off_all(p); 178 snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port)); 179 snd_seq_event_port_detach(p->chset.client, p->chset.port); 180 snd_emux_dec_count(emu); 181 182 return 0; 183 } 184 185 186 /* 187 * load patch 188 */ 189 static int 190 snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format, 191 const char __user *buf, int offs, int count) 192 { 193 struct snd_emux *emu; 194 struct snd_emux_port *p; 195 int rc; 196 197 if (snd_BUG_ON(!arg)) 198 return -ENXIO; 199 p = arg->private_data; 200 if (snd_BUG_ON(!p)) 201 return -ENXIO; 202 203 emu = p->emu; 204 if (snd_BUG_ON(!emu)) 205 return -ENXIO; 206 207 if (format == GUS_PATCH) 208 rc = snd_soundfont_load_guspatch(emu->sflist, buf, count, 209 SF_CLIENT_NO(p->chset.port)); 210 else if (format == SNDRV_OSS_SOUNDFONT_PATCH) { 211 struct soundfont_patch_info patch; 212 if (count < (int)sizeof(patch)) 213 return -EINVAL; 214 if (copy_from_user(&patch, buf, sizeof(patch))) 215 return -EFAULT; 216 if (patch.type >= SNDRV_SFNT_LOAD_INFO && 217 patch.type <= SNDRV_SFNT_PROBE_DATA) 218 rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port)); 219 else { 220 if (emu->ops.load_fx) 221 rc = emu->ops.load_fx(emu, patch.type, patch.optarg, buf, count); 222 else 223 rc = -EINVAL; 224 } 225 } else 226 rc = 0; 227 return rc; 228 } 229 230 231 /* 232 * ioctl 233 */ 234 static int 235 snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, unsigned long ioarg) 236 { 237 struct snd_emux_port *p; 238 struct snd_emux *emu; 239 240 if (snd_BUG_ON(!arg)) 241 return -ENXIO; 242 p = arg->private_data; 243 if (snd_BUG_ON(!p)) 244 return -ENXIO; 245 246 emu = p->emu; 247 if (snd_BUG_ON(!emu)) 248 return -ENXIO; 249 250 switch (cmd) { 251 case SNDCTL_SEQ_RESETSAMPLES: 252 snd_soundfont_remove_samples(emu->sflist); 253 return 0; 254 255 case SNDCTL_SYNTH_MEMAVL: 256 if (emu->memhdr) 257 return snd_util_mem_avail(emu->memhdr); 258 return 0; 259 } 260 261 return 0; 262 } 263 264 265 /* 266 * reset device 267 */ 268 static int 269 snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg) 270 { 271 struct snd_emux_port *p; 272 273 if (snd_BUG_ON(!arg)) 274 return -ENXIO; 275 p = arg->private_data; 276 if (snd_BUG_ON(!p)) 277 return -ENXIO; 278 snd_emux_reset_port(p); 279 return 0; 280 } 281 282 283 /* 284 * receive raw events: only SEQ_PRIVATE is accepted. 285 */ 286 static int 287 snd_emux_event_oss_input(struct snd_seq_event *ev, int direct, void *private_data, 288 int atomic, int hop) 289 { 290 struct snd_emux *emu; 291 struct snd_emux_port *p; 292 unsigned char cmd, *data; 293 294 p = private_data; 295 if (snd_BUG_ON(!p)) 296 return -EINVAL; 297 emu = p->emu; 298 if (snd_BUG_ON(!emu)) 299 return -EINVAL; 300 if (ev->type != SNDRV_SEQ_EVENT_OSS) 301 return snd_emux_event_input(ev, direct, private_data, atomic, hop); 302 303 data = ev->data.raw8.d; 304 /* only SEQ_PRIVATE is accepted */ 305 if (data[0] != 0xfe) 306 return 0; 307 cmd = data[2] & _EMUX_OSS_MODE_VALUE_MASK; 308 if (data[2] & _EMUX_OSS_MODE_FLAG) 309 emuspec_control(emu, p, cmd, data, atomic, hop); 310 else 311 gusspec_control(emu, p, cmd, data, atomic, hop); 312 return 0; 313 } 314 315 316 /* 317 * OSS/AWE driver specific h/w controls 318 */ 319 static void 320 emuspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd, 321 unsigned char *event, int atomic, int hop) 322 { 323 int voice; 324 unsigned short p1; 325 short p2; 326 int i; 327 struct snd_midi_channel *chan; 328 329 voice = event[3]; 330 if (voice < 0 || voice >= port->chset.max_channels) 331 chan = NULL; 332 else 333 chan = &port->chset.channels[voice]; 334 335 p1 = *(unsigned short *) &event[4]; 336 p2 = *(short *) &event[6]; 337 338 switch (cmd) { 339 #if 0 /* don't do this atomically */ 340 case _EMUX_OSS_REMOVE_LAST_SAMPLES: 341 snd_soundfont_remove_unlocked(emu->sflist); 342 break; 343 #endif 344 case _EMUX_OSS_SEND_EFFECT: 345 if (chan) 346 snd_emux_send_effect_oss(port, chan, p1, p2); 347 break; 348 349 case _EMUX_OSS_TERMINATE_ALL: 350 snd_emux_terminate_all(emu); 351 break; 352 353 case _EMUX_OSS_TERMINATE_CHANNEL: 354 /*snd_emux_mute_channel(emu, chan);*/ 355 break; 356 case _EMUX_OSS_RESET_CHANNEL: 357 /*snd_emux_channel_init(chset, chan);*/ 358 break; 359 360 case _EMUX_OSS_RELEASE_ALL: 361 fake_event(emu, port, voice, MIDI_CTL_ALL_NOTES_OFF, 0, atomic, hop); 362 break; 363 case _EMUX_OSS_NOTEOFF_ALL: 364 fake_event(emu, port, voice, MIDI_CTL_ALL_SOUNDS_OFF, 0, atomic, hop); 365 break; 366 367 case _EMUX_OSS_INITIAL_VOLUME: 368 if (p2) { 369 port->volume_atten = (short)p1; 370 snd_emux_update_port(port, SNDRV_EMUX_UPDATE_VOLUME); 371 } 372 break; 373 374 case _EMUX_OSS_CHN_PRESSURE: 375 if (chan) { 376 chan->midi_pressure = p1; 377 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_FMMOD|SNDRV_EMUX_UPDATE_FM2FRQ2); 378 } 379 break; 380 381 case _EMUX_OSS_CHANNEL_MODE: 382 reset_port_mode(port, p1); 383 snd_emux_reset_port(port); 384 break; 385 386 case _EMUX_OSS_DRUM_CHANNELS: 387 port->drum_flags = *(unsigned int*)&event[4]; 388 for (i = 0; i < port->chset.max_channels; i++) { 389 chan = &port->chset.channels[i]; 390 chan->drum_channel = ((port->drum_flags >> i) & 1) ? 1 : 0; 391 } 392 break; 393 394 case _EMUX_OSS_MISC_MODE: 395 if (p1 < EMUX_MD_END) 396 port->ctrls[p1] = p2; 397 break; 398 case _EMUX_OSS_DEBUG_MODE: 399 break; 400 401 default: 402 if (emu->ops.oss_ioctl) 403 emu->ops.oss_ioctl(emu, cmd, p1, p2); 404 break; 405 } 406 } 407 408 /* 409 * GUS specific h/w controls 410 */ 411 412 #include <linux/ultrasound.h> 413 414 static void 415 gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd, 416 unsigned char *event, int atomic, int hop) 417 { 418 int voice; 419 unsigned short p1; 420 int plong; 421 struct snd_midi_channel *chan; 422 423 if (port->port_mode != SNDRV_EMUX_PORT_MODE_OSS_SYNTH) 424 return; 425 if (cmd == _GUS_NUMVOICES) 426 return; 427 voice = event[3]; 428 if (voice < 0 || voice >= port->chset.max_channels) 429 return; 430 431 chan = &port->chset.channels[voice]; 432 433 p1 = *(unsigned short *) &event[4]; 434 plong = *(int*) &event[4]; 435 436 switch (cmd) { 437 case _GUS_VOICESAMPLE: 438 chan->midi_program = p1; 439 return; 440 441 case _GUS_VOICEBALA: 442 /* 0 to 15 --> 0 to 127 */ 443 chan->control[MIDI_CTL_MSB_PAN] = (int)p1 << 3; 444 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN); 445 return; 446 447 case _GUS_VOICEVOL: 448 case _GUS_VOICEVOL2: 449 /* not supported yet */ 450 return; 451 452 case _GUS_RAMPRANGE: 453 case _GUS_RAMPRATE: 454 case _GUS_RAMPMODE: 455 case _GUS_RAMPON: 456 case _GUS_RAMPOFF: 457 /* volume ramping not supported */ 458 return; 459 460 case _GUS_VOLUME_SCALE: 461 return; 462 463 case _GUS_VOICE_POS: 464 #ifdef SNDRV_EMUX_USE_RAW_EFFECT 465 snd_emux_send_effect(port, chan, EMUX_FX_SAMPLE_START, 466 (short)(plong & 0x7fff), 467 EMUX_FX_FLAG_SET); 468 snd_emux_send_effect(port, chan, EMUX_FX_COARSE_SAMPLE_START, 469 (plong >> 15) & 0xffff, 470 EMUX_FX_FLAG_SET); 471 #endif 472 return; 473 } 474 } 475 476 477 /* 478 * send an event to midi emulation 479 */ 480 static void 481 fake_event(struct snd_emux *emu, struct snd_emux_port *port, int ch, int param, int val, int atomic, int hop) 482 { 483 struct snd_seq_event ev; 484 memset(&ev, 0, sizeof(ev)); 485 ev.type = SNDRV_SEQ_EVENT_CONTROLLER; 486 ev.data.control.channel = ch; 487 ev.data.control.param = param; 488 ev.data.control.value = val; 489 snd_emux_event_input(&ev, 0, port, atomic, hop); 490 } 491