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