1 /* 2 * Copyright (c) by Uros Bizjak <uros@kss-loka.si> 3 * 4 * Routines for OPL2/OPL3/OPL4 control 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 21 22 #include <linux/slab.h> 23 #include <linux/export.h> 24 #include <linux/nospec.h> 25 #include <sound/opl3.h> 26 #include <sound/asound_fm.h> 27 28 #if IS_ENABLED(CONFIG_SND_SEQUENCER) 29 #define OPL3_SUPPORT_SYNTH 30 #endif 31 32 /* 33 * There is 18 possible 2 OP voices 34 * (9 in the left and 9 in the right). 35 * The first OP is the modulator and 2nd is the carrier. 36 * 37 * The first three voices in the both sides may be connected 38 * with another voice to a 4 OP voice. For example voice 0 39 * can be connected with voice 3. The operators of voice 3 are 40 * used as operators 3 and 4 of the new 4 OP voice. 41 * In this case the 2 OP voice number 0 is the 'first half' and 42 * voice 3 is the second. 43 */ 44 45 46 /* 47 * Register offset table for OPL2/3 voices, 48 * OPL2 / one OPL3 register array side only 49 */ 50 51 char snd_opl3_regmap[MAX_OPL2_VOICES][4] = 52 { 53 /* OP1 OP2 OP3 OP4 */ 54 /* ------------------------ */ 55 { 0x00, 0x03, 0x08, 0x0b }, 56 { 0x01, 0x04, 0x09, 0x0c }, 57 { 0x02, 0x05, 0x0a, 0x0d }, 58 59 { 0x08, 0x0b, 0x00, 0x00 }, 60 { 0x09, 0x0c, 0x00, 0x00 }, 61 { 0x0a, 0x0d, 0x00, 0x00 }, 62 63 { 0x10, 0x13, 0x00, 0x00 }, /* used by percussive voices */ 64 { 0x11, 0x14, 0x00, 0x00 }, /* if the percussive mode */ 65 { 0x12, 0x15, 0x00, 0x00 } /* is selected (only left reg block) */ 66 }; 67 68 EXPORT_SYMBOL(snd_opl3_regmap); 69 70 /* 71 * prototypes 72 */ 73 static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note); 74 static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice); 75 static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params); 76 static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode); 77 static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection); 78 79 /* ------------------------------ */ 80 81 /* 82 * open the device exclusively 83 */ 84 int snd_opl3_open(struct snd_hwdep * hw, struct file *file) 85 { 86 return 0; 87 } 88 89 /* 90 * ioctl for hwdep device: 91 */ 92 int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file, 93 unsigned int cmd, unsigned long arg) 94 { 95 struct snd_opl3 *opl3 = hw->private_data; 96 void __user *argp = (void __user *)arg; 97 98 if (snd_BUG_ON(!opl3)) 99 return -EINVAL; 100 101 switch (cmd) { 102 /* get information */ 103 case SNDRV_DM_FM_IOCTL_INFO: 104 { 105 struct snd_dm_fm_info info; 106 107 info.fm_mode = opl3->fm_mode; 108 info.rhythm = opl3->rhythm; 109 if (copy_to_user(argp, &info, sizeof(struct snd_dm_fm_info))) 110 return -EFAULT; 111 return 0; 112 } 113 114 case SNDRV_DM_FM_IOCTL_RESET: 115 #ifdef CONFIG_SND_OSSEMUL 116 case SNDRV_DM_FM_OSS_IOCTL_RESET: 117 #endif 118 snd_opl3_reset(opl3); 119 return 0; 120 121 case SNDRV_DM_FM_IOCTL_PLAY_NOTE: 122 #ifdef CONFIG_SND_OSSEMUL 123 case SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE: 124 #endif 125 { 126 struct snd_dm_fm_note note; 127 if (copy_from_user(¬e, argp, sizeof(struct snd_dm_fm_note))) 128 return -EFAULT; 129 return snd_opl3_play_note(opl3, ¬e); 130 } 131 132 case SNDRV_DM_FM_IOCTL_SET_VOICE: 133 #ifdef CONFIG_SND_OSSEMUL 134 case SNDRV_DM_FM_OSS_IOCTL_SET_VOICE: 135 #endif 136 { 137 struct snd_dm_fm_voice voice; 138 if (copy_from_user(&voice, argp, sizeof(struct snd_dm_fm_voice))) 139 return -EFAULT; 140 return snd_opl3_set_voice(opl3, &voice); 141 } 142 143 case SNDRV_DM_FM_IOCTL_SET_PARAMS: 144 #ifdef CONFIG_SND_OSSEMUL 145 case SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS: 146 #endif 147 { 148 struct snd_dm_fm_params params; 149 if (copy_from_user(¶ms, argp, sizeof(struct snd_dm_fm_params))) 150 return -EFAULT; 151 return snd_opl3_set_params(opl3, ¶ms); 152 } 153 154 case SNDRV_DM_FM_IOCTL_SET_MODE: 155 #ifdef CONFIG_SND_OSSEMUL 156 case SNDRV_DM_FM_OSS_IOCTL_SET_MODE: 157 #endif 158 return snd_opl3_set_mode(opl3, (int) arg); 159 160 case SNDRV_DM_FM_IOCTL_SET_CONNECTION: 161 #ifdef CONFIG_SND_OSSEMUL 162 case SNDRV_DM_FM_OSS_IOCTL_SET_OPL: 163 #endif 164 return snd_opl3_set_connection(opl3, (int) arg); 165 166 #ifdef OPL3_SUPPORT_SYNTH 167 case SNDRV_DM_FM_IOCTL_CLEAR_PATCHES: 168 snd_opl3_clear_patches(opl3); 169 return 0; 170 #endif 171 172 #ifdef CONFIG_SND_DEBUG 173 default: 174 snd_printk(KERN_WARNING "unknown IOCTL: 0x%x\n", cmd); 175 #endif 176 } 177 return -ENOTTY; 178 } 179 180 /* 181 * close the device 182 */ 183 int snd_opl3_release(struct snd_hwdep * hw, struct file *file) 184 { 185 struct snd_opl3 *opl3 = hw->private_data; 186 187 snd_opl3_reset(opl3); 188 return 0; 189 } 190 191 #ifdef OPL3_SUPPORT_SYNTH 192 /* 193 * write the device - load patches 194 */ 195 long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count, 196 loff_t *offset) 197 { 198 struct snd_opl3 *opl3 = hw->private_data; 199 long result = 0; 200 int err = 0; 201 struct sbi_patch inst; 202 203 while (count >= sizeof(inst)) { 204 unsigned char type; 205 if (copy_from_user(&inst, buf, sizeof(inst))) 206 return -EFAULT; 207 if (!memcmp(inst.key, FM_KEY_SBI, 4) || 208 !memcmp(inst.key, FM_KEY_2OP, 4)) 209 type = FM_PATCH_OPL2; 210 else if (!memcmp(inst.key, FM_KEY_4OP, 4)) 211 type = FM_PATCH_OPL3; 212 else /* invalid type */ 213 break; 214 err = snd_opl3_load_patch(opl3, inst.prog, inst.bank, type, 215 inst.name, inst.extension, 216 inst.data); 217 if (err < 0) 218 break; 219 result += sizeof(inst); 220 count -= sizeof(inst); 221 } 222 return result > 0 ? result : err; 223 } 224 225 226 /* 227 * Patch management 228 */ 229 230 /* offsets for SBI params */ 231 #define AM_VIB 0 232 #define KSL_LEVEL 2 233 #define ATTACK_DECAY 4 234 #define SUSTAIN_RELEASE 6 235 #define WAVE_SELECT 8 236 237 /* offset for SBI instrument */ 238 #define CONNECTION 10 239 #define OFFSET_4OP 11 240 241 /* 242 * load a patch, obviously. 243 * 244 * loaded on the given program and bank numbers with the given type 245 * (FM_PATCH_OPLx). 246 * data is the pointer of SBI record _without_ header (key and name). 247 * name is the name string of the patch. 248 * ext is the extension data of 7 bytes long (stored in name of SBI 249 * data up to offset 25), or NULL to skip. 250 * return 0 if successful or a negative error code. 251 */ 252 int snd_opl3_load_patch(struct snd_opl3 *opl3, 253 int prog, int bank, int type, 254 const char *name, 255 const unsigned char *ext, 256 const unsigned char *data) 257 { 258 struct fm_patch *patch; 259 int i; 260 261 patch = snd_opl3_find_patch(opl3, prog, bank, 1); 262 if (!patch) 263 return -ENOMEM; 264 265 patch->type = type; 266 267 for (i = 0; i < 2; i++) { 268 patch->inst.op[i].am_vib = data[AM_VIB + i]; 269 patch->inst.op[i].ksl_level = data[KSL_LEVEL + i]; 270 patch->inst.op[i].attack_decay = data[ATTACK_DECAY + i]; 271 patch->inst.op[i].sustain_release = data[SUSTAIN_RELEASE + i]; 272 patch->inst.op[i].wave_select = data[WAVE_SELECT + i]; 273 } 274 patch->inst.feedback_connection[0] = data[CONNECTION]; 275 276 if (type == FM_PATCH_OPL3) { 277 for (i = 0; i < 2; i++) { 278 patch->inst.op[i+2].am_vib = 279 data[OFFSET_4OP + AM_VIB + i]; 280 patch->inst.op[i+2].ksl_level = 281 data[OFFSET_4OP + KSL_LEVEL + i]; 282 patch->inst.op[i+2].attack_decay = 283 data[OFFSET_4OP + ATTACK_DECAY + i]; 284 patch->inst.op[i+2].sustain_release = 285 data[OFFSET_4OP + SUSTAIN_RELEASE + i]; 286 patch->inst.op[i+2].wave_select = 287 data[OFFSET_4OP + WAVE_SELECT + i]; 288 } 289 patch->inst.feedback_connection[1] = 290 data[OFFSET_4OP + CONNECTION]; 291 } 292 293 if (ext) { 294 patch->inst.echo_delay = ext[0]; 295 patch->inst.echo_atten = ext[1]; 296 patch->inst.chorus_spread = ext[2]; 297 patch->inst.trnsps = ext[3]; 298 patch->inst.fix_dur = ext[4]; 299 patch->inst.modes = ext[5]; 300 patch->inst.fix_key = ext[6]; 301 } 302 303 if (name) 304 strlcpy(patch->name, name, sizeof(patch->name)); 305 306 return 0; 307 } 308 EXPORT_SYMBOL(snd_opl3_load_patch); 309 310 /* 311 * find a patch with the given program and bank numbers, returns its pointer 312 * if no matching patch is found and create_patch is set, it creates a 313 * new patch object. 314 */ 315 struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank, 316 int create_patch) 317 { 318 /* pretty dumb hash key */ 319 unsigned int key = (prog + bank) % OPL3_PATCH_HASH_SIZE; 320 struct fm_patch *patch; 321 322 for (patch = opl3->patch_table[key]; patch; patch = patch->next) { 323 if (patch->prog == prog && patch->bank == bank) 324 return patch; 325 } 326 if (!create_patch) 327 return NULL; 328 329 patch = kzalloc(sizeof(*patch), GFP_KERNEL); 330 if (!patch) 331 return NULL; 332 patch->prog = prog; 333 patch->bank = bank; 334 patch->next = opl3->patch_table[key]; 335 opl3->patch_table[key] = patch; 336 return patch; 337 } 338 EXPORT_SYMBOL(snd_opl3_find_patch); 339 340 /* 341 * Clear all patches of the given OPL3 instance 342 */ 343 void snd_opl3_clear_patches(struct snd_opl3 *opl3) 344 { 345 int i; 346 for (i = 0; i < OPL3_PATCH_HASH_SIZE; i++) { 347 struct fm_patch *patch, *next; 348 for (patch = opl3->patch_table[i]; patch; patch = next) { 349 next = patch->next; 350 kfree(patch); 351 } 352 } 353 memset(opl3->patch_table, 0, sizeof(opl3->patch_table)); 354 } 355 #endif /* OPL3_SUPPORT_SYNTH */ 356 357 /* ------------------------------ */ 358 359 void snd_opl3_reset(struct snd_opl3 * opl3) 360 { 361 unsigned short opl3_reg; 362 363 unsigned short reg_side; 364 unsigned char voice_offset; 365 366 int max_voices, i; 367 368 max_voices = (opl3->hardware < OPL3_HW_OPL3) ? 369 MAX_OPL2_VOICES : MAX_OPL3_VOICES; 370 371 for (i = 0; i < max_voices; i++) { 372 /* Get register array side and offset of voice */ 373 if (i < MAX_OPL2_VOICES) { 374 /* Left register block for voices 0 .. 8 */ 375 reg_side = OPL3_LEFT; 376 voice_offset = i; 377 } else { 378 /* Right register block for voices 9 .. 17 */ 379 reg_side = OPL3_RIGHT; 380 voice_offset = i - MAX_OPL2_VOICES; 381 } 382 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + snd_opl3_regmap[voice_offset][0]); 383 opl3->command(opl3, opl3_reg, OPL3_TOTAL_LEVEL_MASK); /* Operator 1 volume */ 384 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + snd_opl3_regmap[voice_offset][1]); 385 opl3->command(opl3, opl3_reg, OPL3_TOTAL_LEVEL_MASK); /* Operator 2 volume */ 386 387 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); 388 opl3->command(opl3, opl3_reg, 0x00); /* Note off */ 389 } 390 391 opl3->max_voices = MAX_OPL2_VOICES; 392 opl3->fm_mode = SNDRV_DM_FM_MODE_OPL2; 393 394 opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT); 395 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00); /* Melodic mode */ 396 opl3->rhythm = 0; 397 } 398 399 EXPORT_SYMBOL(snd_opl3_reset); 400 401 static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note) 402 { 403 unsigned short reg_side; 404 unsigned char voice_offset; 405 406 unsigned short opl3_reg; 407 unsigned char reg_val; 408 409 /* Voices 0 - 8 in OPL2 mode */ 410 /* Voices 0 - 17 in OPL3 mode */ 411 if (note->voice >= ((opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) ? 412 MAX_OPL3_VOICES : MAX_OPL2_VOICES)) 413 return -EINVAL; 414 415 /* Get register array side and offset of voice */ 416 if (note->voice < MAX_OPL2_VOICES) { 417 /* Left register block for voices 0 .. 8 */ 418 reg_side = OPL3_LEFT; 419 voice_offset = note->voice; 420 } else { 421 /* Right register block for voices 9 .. 17 */ 422 reg_side = OPL3_RIGHT; 423 voice_offset = note->voice - MAX_OPL2_VOICES; 424 } 425 426 /* Set lower 8 bits of note frequency */ 427 reg_val = (unsigned char) note->fnum; 428 opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset); 429 opl3->command(opl3, opl3_reg, reg_val); 430 431 reg_val = 0x00; 432 /* Set output sound flag */ 433 if (note->key_on) 434 reg_val |= OPL3_KEYON_BIT; 435 /* Set octave */ 436 reg_val |= (note->octave << 2) & OPL3_BLOCKNUM_MASK; 437 /* Set higher 2 bits of note frequency */ 438 reg_val |= (unsigned char) (note->fnum >> 8) & OPL3_FNUM_HIGH_MASK; 439 440 /* Set OPL3 KEYON_BLOCK register of requested voice */ 441 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); 442 opl3->command(opl3, opl3_reg, reg_val); 443 444 return 0; 445 } 446 447 448 static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice) 449 { 450 unsigned short reg_side; 451 unsigned char op_offset; 452 unsigned char voice_offset, voice_op; 453 454 unsigned short opl3_reg; 455 unsigned char reg_val; 456 457 /* Only operators 1 and 2 */ 458 if (voice->op > 1) 459 return -EINVAL; 460 /* Voices 0 - 8 in OPL2 mode */ 461 /* Voices 0 - 17 in OPL3 mode */ 462 if (voice->voice >= ((opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) ? 463 MAX_OPL3_VOICES : MAX_OPL2_VOICES)) 464 return -EINVAL; 465 466 /* Get register array side and offset of voice */ 467 if (voice->voice < MAX_OPL2_VOICES) { 468 /* Left register block for voices 0 .. 8 */ 469 reg_side = OPL3_LEFT; 470 voice_offset = voice->voice; 471 } else { 472 /* Right register block for voices 9 .. 17 */ 473 reg_side = OPL3_RIGHT; 474 voice_offset = voice->voice - MAX_OPL2_VOICES; 475 } 476 /* Get register offset of operator */ 477 voice_offset = array_index_nospec(voice_offset, MAX_OPL2_VOICES); 478 voice_op = array_index_nospec(voice->op, 4); 479 op_offset = snd_opl3_regmap[voice_offset][voice_op]; 480 481 reg_val = 0x00; 482 /* Set amplitude modulation (tremolo) effect */ 483 if (voice->am) 484 reg_val |= OPL3_TREMOLO_ON; 485 /* Set vibrato effect */ 486 if (voice->vibrato) 487 reg_val |= OPL3_VIBRATO_ON; 488 /* Set sustaining sound phase */ 489 if (voice->do_sustain) 490 reg_val |= OPL3_SUSTAIN_ON; 491 /* Set keyboard scaling bit */ 492 if (voice->kbd_scale) 493 reg_val |= OPL3_KSR; 494 /* Set harmonic or frequency multiplier */ 495 reg_val |= voice->harmonic & OPL3_MULTIPLE_MASK; 496 497 /* Set OPL3 AM_VIB register of requested voice/operator */ 498 opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset); 499 opl3->command(opl3, opl3_reg, reg_val); 500 501 /* Set decreasing volume of higher notes */ 502 reg_val = (voice->scale_level << 6) & OPL3_KSL_MASK; 503 /* Set output volume */ 504 reg_val |= ~voice->volume & OPL3_TOTAL_LEVEL_MASK; 505 506 /* Set OPL3 KSL_LEVEL register of requested voice/operator */ 507 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset); 508 opl3->command(opl3, opl3_reg, reg_val); 509 510 /* Set attack phase level */ 511 reg_val = (voice->attack << 4) & OPL3_ATTACK_MASK; 512 /* Set decay phase level */ 513 reg_val |= voice->decay & OPL3_DECAY_MASK; 514 515 /* Set OPL3 ATTACK_DECAY register of requested voice/operator */ 516 opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset); 517 opl3->command(opl3, opl3_reg, reg_val); 518 519 /* Set sustain phase level */ 520 reg_val = (voice->sustain << 4) & OPL3_SUSTAIN_MASK; 521 /* Set release phase level */ 522 reg_val |= voice->release & OPL3_RELEASE_MASK; 523 524 /* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */ 525 opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset); 526 opl3->command(opl3, opl3_reg, reg_val); 527 528 /* Set inter-operator feedback */ 529 reg_val = (voice->feedback << 1) & OPL3_FEEDBACK_MASK; 530 /* Set inter-operator connection */ 531 if (voice->connection) 532 reg_val |= OPL3_CONNECTION_BIT; 533 /* OPL-3 only */ 534 if (opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) { 535 if (voice->left) 536 reg_val |= OPL3_VOICE_TO_LEFT; 537 if (voice->right) 538 reg_val |= OPL3_VOICE_TO_RIGHT; 539 } 540 /* Feedback/connection bits are applicable to voice */ 541 opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset); 542 opl3->command(opl3, opl3_reg, reg_val); 543 544 /* Select waveform */ 545 reg_val = voice->waveform & OPL3_WAVE_SELECT_MASK; 546 opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset); 547 opl3->command(opl3, opl3_reg, reg_val); 548 549 return 0; 550 } 551 552 static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params) 553 { 554 unsigned char reg_val; 555 556 reg_val = 0x00; 557 /* Set keyboard split method */ 558 if (params->kbd_split) 559 reg_val |= OPL3_KEYBOARD_SPLIT; 560 opl3->command(opl3, OPL3_LEFT | OPL3_REG_KBD_SPLIT, reg_val); 561 562 reg_val = 0x00; 563 /* Set amplitude modulation (tremolo) depth */ 564 if (params->am_depth) 565 reg_val |= OPL3_TREMOLO_DEPTH; 566 /* Set vibrato depth */ 567 if (params->vib_depth) 568 reg_val |= OPL3_VIBRATO_DEPTH; 569 /* Set percussion mode */ 570 if (params->rhythm) { 571 reg_val |= OPL3_PERCUSSION_ENABLE; 572 opl3->rhythm = 1; 573 } else { 574 opl3->rhythm = 0; 575 } 576 /* Play percussion instruments */ 577 if (params->bass) 578 reg_val |= OPL3_BASSDRUM_ON; 579 if (params->snare) 580 reg_val |= OPL3_SNAREDRUM_ON; 581 if (params->tomtom) 582 reg_val |= OPL3_TOMTOM_ON; 583 if (params->cymbal) 584 reg_val |= OPL3_CYMBAL_ON; 585 if (params->hihat) 586 reg_val |= OPL3_HIHAT_ON; 587 588 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, reg_val); 589 return 0; 590 } 591 592 static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode) 593 { 594 if ((mode == SNDRV_DM_FM_MODE_OPL3) && (opl3->hardware < OPL3_HW_OPL3)) 595 return -EINVAL; 596 597 opl3->fm_mode = mode; 598 if (opl3->hardware >= OPL3_HW_OPL3) 599 opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, 0x00); /* Clear 4-op connections */ 600 601 return 0; 602 } 603 604 static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection) 605 { 606 unsigned char reg_val; 607 608 /* OPL-3 only */ 609 if (opl3->fm_mode != SNDRV_DM_FM_MODE_OPL3) 610 return -EINVAL; 611 612 reg_val = connection & (OPL3_RIGHT_4OP_0 | OPL3_RIGHT_4OP_1 | OPL3_RIGHT_4OP_2 | 613 OPL3_LEFT_4OP_0 | OPL3_LEFT_4OP_1 | OPL3_LEFT_4OP_2); 614 /* Set 4-op connections */ 615 opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, reg_val); 616 617 return 0; 618 } 619 620