1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun #ifndef __SOUND_OPL3_H
3*4882a593Smuzhiyun #define __SOUND_OPL3_H
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun /*
6*4882a593Smuzhiyun * Definitions of the OPL-3 registers.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
9*4882a593Smuzhiyun * Hannu Savolainen 1993-1996
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * The OPL-3 mode is switched on by writing 0x01, to the offset 5
12*4882a593Smuzhiyun * of the right side.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * Another special register at the right side is at offset 4. It contains
15*4882a593Smuzhiyun * a bit mask defining which voices are used as 4 OP voices.
16*4882a593Smuzhiyun *
17*4882a593Smuzhiyun * The percussive mode is implemented in the left side only.
18*4882a593Smuzhiyun *
19*4882a593Smuzhiyun * With the above exceptions the both sides can be operated independently.
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun * A 4 OP voice can be created by setting the corresponding
22*4882a593Smuzhiyun * bit at offset 4 of the right side.
23*4882a593Smuzhiyun *
24*4882a593Smuzhiyun * For example setting the rightmost bit (0x01) changes the
25*4882a593Smuzhiyun * first voice on the right side to the 4 OP mode. The fourth
26*4882a593Smuzhiyun * voice is made inaccessible.
27*4882a593Smuzhiyun *
28*4882a593Smuzhiyun * If a voice is set to the 2 OP mode, it works like 2 OP modes
29*4882a593Smuzhiyun * of the original YM3812 (AdLib). In addition the voice can
30*4882a593Smuzhiyun * be connected the left, right or both stereo channels. It can
31*4882a593Smuzhiyun * even be left unconnected. This works with 4 OP voices also.
32*4882a593Smuzhiyun *
33*4882a593Smuzhiyun * The stereo connection bits are located in the FEEDBACK_CONNECTION
34*4882a593Smuzhiyun * register of the voice (0xC0-0xC8). In 4 OP voices these bits are
35*4882a593Smuzhiyun * in the second half of the voice.
36*4882a593Smuzhiyun */
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #include <sound/core.h>
39*4882a593Smuzhiyun #include <sound/hwdep.h>
40*4882a593Smuzhiyun #include <sound/timer.h>
41*4882a593Smuzhiyun #include <sound/seq_midi_emul.h>
42*4882a593Smuzhiyun #include <sound/seq_oss.h>
43*4882a593Smuzhiyun #include <sound/seq_oss_legacy.h>
44*4882a593Smuzhiyun #include <sound/seq_device.h>
45*4882a593Smuzhiyun #include <sound/asound_fm.h>
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /*
48*4882a593Smuzhiyun * Register numbers for the global registers
49*4882a593Smuzhiyun */
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #define OPL3_REG_TEST 0x01
52*4882a593Smuzhiyun #define OPL3_ENABLE_WAVE_SELECT 0x20
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun #define OPL3_REG_TIMER1 0x02
55*4882a593Smuzhiyun #define OPL3_REG_TIMER2 0x03
56*4882a593Smuzhiyun #define OPL3_REG_TIMER_CONTROL 0x04 /* Left side */
57*4882a593Smuzhiyun #define OPL3_IRQ_RESET 0x80
58*4882a593Smuzhiyun #define OPL3_TIMER1_MASK 0x40
59*4882a593Smuzhiyun #define OPL3_TIMER2_MASK 0x20
60*4882a593Smuzhiyun #define OPL3_TIMER1_START 0x01
61*4882a593Smuzhiyun #define OPL3_TIMER2_START 0x02
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun #define OPL3_REG_CONNECTION_SELECT 0x04 /* Right side */
64*4882a593Smuzhiyun #define OPL3_LEFT_4OP_0 0x01
65*4882a593Smuzhiyun #define OPL3_LEFT_4OP_1 0x02
66*4882a593Smuzhiyun #define OPL3_LEFT_4OP_2 0x04
67*4882a593Smuzhiyun #define OPL3_RIGHT_4OP_0 0x08
68*4882a593Smuzhiyun #define OPL3_RIGHT_4OP_1 0x10
69*4882a593Smuzhiyun #define OPL3_RIGHT_4OP_2 0x20
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun #define OPL3_REG_MODE 0x05 /* Right side */
72*4882a593Smuzhiyun #define OPL3_OPL3_ENABLE 0x01 /* OPL3 mode */
73*4882a593Smuzhiyun #define OPL3_OPL4_ENABLE 0x02 /* OPL4 mode */
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun #define OPL3_REG_KBD_SPLIT 0x08 /* Left side */
76*4882a593Smuzhiyun #define OPL3_COMPOSITE_SINE_WAVE_MODE 0x80 /* Don't use with OPL-3? */
77*4882a593Smuzhiyun #define OPL3_KEYBOARD_SPLIT 0x40
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun #define OPL3_REG_PERCUSSION 0xbd /* Left side only */
80*4882a593Smuzhiyun #define OPL3_TREMOLO_DEPTH 0x80
81*4882a593Smuzhiyun #define OPL3_VIBRATO_DEPTH 0x40
82*4882a593Smuzhiyun #define OPL3_PERCUSSION_ENABLE 0x20
83*4882a593Smuzhiyun #define OPL3_BASSDRUM_ON 0x10
84*4882a593Smuzhiyun #define OPL3_SNAREDRUM_ON 0x08
85*4882a593Smuzhiyun #define OPL3_TOMTOM_ON 0x04
86*4882a593Smuzhiyun #define OPL3_CYMBAL_ON 0x02
87*4882a593Smuzhiyun #define OPL3_HIHAT_ON 0x01
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /*
90*4882a593Smuzhiyun * Offsets to the register banks for operators. To get the
91*4882a593Smuzhiyun * register number just add the operator offset to the bank offset
92*4882a593Smuzhiyun *
93*4882a593Smuzhiyun * AM/VIB/EG/KSR/Multiple (0x20 to 0x35)
94*4882a593Smuzhiyun */
95*4882a593Smuzhiyun #define OPL3_REG_AM_VIB 0x20
96*4882a593Smuzhiyun #define OPL3_TREMOLO_ON 0x80
97*4882a593Smuzhiyun #define OPL3_VIBRATO_ON 0x40
98*4882a593Smuzhiyun #define OPL3_SUSTAIN_ON 0x20
99*4882a593Smuzhiyun #define OPL3_KSR 0x10 /* Key scaling rate */
100*4882a593Smuzhiyun #define OPL3_MULTIPLE_MASK 0x0f /* Frequency multiplier */
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /*
103*4882a593Smuzhiyun * KSL/Total level (0x40 to 0x55)
104*4882a593Smuzhiyun */
105*4882a593Smuzhiyun #define OPL3_REG_KSL_LEVEL 0x40
106*4882a593Smuzhiyun #define OPL3_KSL_MASK 0xc0 /* Envelope scaling bits */
107*4882a593Smuzhiyun #define OPL3_TOTAL_LEVEL_MASK 0x3f /* Strength (volume) of OP */
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun /*
110*4882a593Smuzhiyun * Attack / Decay rate (0x60 to 0x75)
111*4882a593Smuzhiyun */
112*4882a593Smuzhiyun #define OPL3_REG_ATTACK_DECAY 0x60
113*4882a593Smuzhiyun #define OPL3_ATTACK_MASK 0xf0
114*4882a593Smuzhiyun #define OPL3_DECAY_MASK 0x0f
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun /*
117*4882a593Smuzhiyun * Sustain level / Release rate (0x80 to 0x95)
118*4882a593Smuzhiyun */
119*4882a593Smuzhiyun #define OPL3_REG_SUSTAIN_RELEASE 0x80
120*4882a593Smuzhiyun #define OPL3_SUSTAIN_MASK 0xf0
121*4882a593Smuzhiyun #define OPL3_RELEASE_MASK 0x0f
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun /*
124*4882a593Smuzhiyun * Wave select (0xE0 to 0xF5)
125*4882a593Smuzhiyun */
126*4882a593Smuzhiyun #define OPL3_REG_WAVE_SELECT 0xe0
127*4882a593Smuzhiyun #define OPL3_WAVE_SELECT_MASK 0x07
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun /*
130*4882a593Smuzhiyun * Offsets to the register banks for voices. Just add to the
131*4882a593Smuzhiyun * voice number to get the register number.
132*4882a593Smuzhiyun *
133*4882a593Smuzhiyun * F-Number low bits (0xA0 to 0xA8).
134*4882a593Smuzhiyun */
135*4882a593Smuzhiyun #define OPL3_REG_FNUM_LOW 0xa0
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun /*
138*4882a593Smuzhiyun * F-number high bits / Key on / Block (octave) (0xB0 to 0xB8)
139*4882a593Smuzhiyun */
140*4882a593Smuzhiyun #define OPL3_REG_KEYON_BLOCK 0xb0
141*4882a593Smuzhiyun #define OPL3_KEYON_BIT 0x20
142*4882a593Smuzhiyun #define OPL3_BLOCKNUM_MASK 0x1c
143*4882a593Smuzhiyun #define OPL3_FNUM_HIGH_MASK 0x03
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /*
146*4882a593Smuzhiyun * Feedback / Connection (0xc0 to 0xc8)
147*4882a593Smuzhiyun *
148*4882a593Smuzhiyun * These registers have two new bits when the OPL-3 mode
149*4882a593Smuzhiyun * is selected. These bits controls connecting the voice
150*4882a593Smuzhiyun * to the stereo channels. For 4 OP voices this bit is
151*4882a593Smuzhiyun * defined in the second half of the voice (add 3 to the
152*4882a593Smuzhiyun * register offset).
153*4882a593Smuzhiyun *
154*4882a593Smuzhiyun * For 4 OP voices the connection bit is used in the
155*4882a593Smuzhiyun * both halves (gives 4 ways to connect the operators).
156*4882a593Smuzhiyun */
157*4882a593Smuzhiyun #define OPL3_REG_FEEDBACK_CONNECTION 0xc0
158*4882a593Smuzhiyun #define OPL3_FEEDBACK_MASK 0x0e /* Valid just for 1st OP of a voice */
159*4882a593Smuzhiyun #define OPL3_CONNECTION_BIT 0x01
160*4882a593Smuzhiyun /*
161*4882a593Smuzhiyun * In the 4 OP mode there is four possible configurations how the
162*4882a593Smuzhiyun * operators can be connected together (in 2 OP modes there is just
163*4882a593Smuzhiyun * AM or FM). The 4 OP connection mode is defined by the rightmost
164*4882a593Smuzhiyun * bit of the FEEDBACK_CONNECTION (0xC0-0xC8) on the both halves.
165*4882a593Smuzhiyun *
166*4882a593Smuzhiyun * First half Second half Mode
167*4882a593Smuzhiyun *
168*4882a593Smuzhiyun * +---+
169*4882a593Smuzhiyun * v |
170*4882a593Smuzhiyun * 0 0 >+-1-+--2--3--4-->
171*4882a593Smuzhiyun *
172*4882a593Smuzhiyun *
173*4882a593Smuzhiyun *
174*4882a593Smuzhiyun * +---+
175*4882a593Smuzhiyun * | |
176*4882a593Smuzhiyun * 0 1 >+-1-+--2-+
177*4882a593Smuzhiyun * |->
178*4882a593Smuzhiyun * >--3----4-+
179*4882a593Smuzhiyun *
180*4882a593Smuzhiyun * +---+
181*4882a593Smuzhiyun * | |
182*4882a593Smuzhiyun * 1 0 >+-1-+-----+
183*4882a593Smuzhiyun * |->
184*4882a593Smuzhiyun * >--2--3--4-+
185*4882a593Smuzhiyun *
186*4882a593Smuzhiyun * +---+
187*4882a593Smuzhiyun * | |
188*4882a593Smuzhiyun * 1 1 >+-1-+--+
189*4882a593Smuzhiyun * |
190*4882a593Smuzhiyun * >--2--3-+->
191*4882a593Smuzhiyun * |
192*4882a593Smuzhiyun * >--4----+
193*4882a593Smuzhiyun */
194*4882a593Smuzhiyun #define OPL3_STEREO_BITS 0x30 /* OPL-3 only */
195*4882a593Smuzhiyun #define OPL3_VOICE_TO_LEFT 0x10
196*4882a593Smuzhiyun #define OPL3_VOICE_TO_RIGHT 0x20
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun /*
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun */
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun #define OPL3_LEFT 0x0000
203*4882a593Smuzhiyun #define OPL3_RIGHT 0x0100
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun #define OPL3_HW_AUTO 0x0000
206*4882a593Smuzhiyun #define OPL3_HW_OPL2 0x0200
207*4882a593Smuzhiyun #define OPL3_HW_OPL3 0x0300
208*4882a593Smuzhiyun #define OPL3_HW_OPL3_SV 0x0301 /* S3 SonicVibes */
209*4882a593Smuzhiyun #define OPL3_HW_OPL3_CS 0x0302 /* CS4232/CS4236+ */
210*4882a593Smuzhiyun #define OPL3_HW_OPL3_FM801 0x0303 /* FM801 */
211*4882a593Smuzhiyun #define OPL3_HW_OPL3_CS4281 0x0304 /* CS4281 */
212*4882a593Smuzhiyun #define OPL3_HW_OPL4 0x0400 /* YMF278B/YMF295 */
213*4882a593Smuzhiyun #define OPL3_HW_OPL4_ML 0x0401 /* YMF704/YMF721 */
214*4882a593Smuzhiyun #define OPL3_HW_MASK 0xff00
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun #define MAX_OPL2_VOICES 9
217*4882a593Smuzhiyun #define MAX_OPL3_VOICES 18
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun struct snd_opl3;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun /*
222*4882a593Smuzhiyun * Instrument record, aka "Patch"
223*4882a593Smuzhiyun */
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun /* FM operator */
226*4882a593Smuzhiyun struct fm_operator {
227*4882a593Smuzhiyun unsigned char am_vib;
228*4882a593Smuzhiyun unsigned char ksl_level;
229*4882a593Smuzhiyun unsigned char attack_decay;
230*4882a593Smuzhiyun unsigned char sustain_release;
231*4882a593Smuzhiyun unsigned char wave_select;
232*4882a593Smuzhiyun } __attribute__((packed));
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun /* Instrument data */
235*4882a593Smuzhiyun struct fm_instrument {
236*4882a593Smuzhiyun struct fm_operator op[4];
237*4882a593Smuzhiyun unsigned char feedback_connection[2];
238*4882a593Smuzhiyun unsigned char echo_delay;
239*4882a593Smuzhiyun unsigned char echo_atten;
240*4882a593Smuzhiyun unsigned char chorus_spread;
241*4882a593Smuzhiyun unsigned char trnsps;
242*4882a593Smuzhiyun unsigned char fix_dur;
243*4882a593Smuzhiyun unsigned char modes;
244*4882a593Smuzhiyun unsigned char fix_key;
245*4882a593Smuzhiyun };
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun /* type */
248*4882a593Smuzhiyun #define FM_PATCH_OPL2 0x01 /* OPL2 2 operators FM instrument */
249*4882a593Smuzhiyun #define FM_PATCH_OPL3 0x02 /* OPL3 4 operators FM instrument */
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun /* Instrument record */
252*4882a593Smuzhiyun struct fm_patch {
253*4882a593Smuzhiyun unsigned char prog;
254*4882a593Smuzhiyun unsigned char bank;
255*4882a593Smuzhiyun unsigned char type;
256*4882a593Smuzhiyun struct fm_instrument inst;
257*4882a593Smuzhiyun char name[24];
258*4882a593Smuzhiyun struct fm_patch *next;
259*4882a593Smuzhiyun };
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun /*
263*4882a593Smuzhiyun * A structure to keep track of each hardware voice
264*4882a593Smuzhiyun */
265*4882a593Smuzhiyun struct snd_opl3_voice {
266*4882a593Smuzhiyun int state; /* status */
267*4882a593Smuzhiyun #define SNDRV_OPL3_ST_OFF 0 /* Not playing */
268*4882a593Smuzhiyun #define SNDRV_OPL3_ST_ON_2OP 1 /* 2op voice is allocated */
269*4882a593Smuzhiyun #define SNDRV_OPL3_ST_ON_4OP 2 /* 4op voice is allocated */
270*4882a593Smuzhiyun #define SNDRV_OPL3_ST_NOT_AVAIL -1 /* voice is not available */
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun unsigned int time; /* An allocation time */
273*4882a593Smuzhiyun unsigned char note; /* Note currently assigned to this voice */
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun unsigned long note_off; /* note-off time */
276*4882a593Smuzhiyun int note_off_check; /* check note-off time */
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun unsigned char keyon_reg; /* KON register shadow */
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun struct snd_midi_channel *chan; /* Midi channel for this note */
281*4882a593Smuzhiyun };
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun struct snd_opl3 {
284*4882a593Smuzhiyun unsigned long l_port;
285*4882a593Smuzhiyun unsigned long r_port;
286*4882a593Smuzhiyun struct resource *res_l_port;
287*4882a593Smuzhiyun struct resource *res_r_port;
288*4882a593Smuzhiyun unsigned short hardware;
289*4882a593Smuzhiyun /* hardware access */
290*4882a593Smuzhiyun void (*command) (struct snd_opl3 * opl3, unsigned short cmd, unsigned char val);
291*4882a593Smuzhiyun unsigned short timer_enable;
292*4882a593Smuzhiyun int seq_dev_num; /* sequencer device number */
293*4882a593Smuzhiyun struct snd_timer *timer1;
294*4882a593Smuzhiyun struct snd_timer *timer2;
295*4882a593Smuzhiyun spinlock_t timer_lock;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun void *private_data;
298*4882a593Smuzhiyun void (*private_free)(struct snd_opl3 *);
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun struct snd_hwdep *hwdep;
301*4882a593Smuzhiyun spinlock_t reg_lock;
302*4882a593Smuzhiyun struct snd_card *card; /* The card that this belongs to */
303*4882a593Smuzhiyun unsigned char fm_mode; /* OPL mode, see SNDRV_DM_FM_MODE_XXX */
304*4882a593Smuzhiyun unsigned char rhythm; /* percussion mode flag */
305*4882a593Smuzhiyun unsigned char max_voices; /* max number of voices */
306*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SEQUENCER)
307*4882a593Smuzhiyun #define SNDRV_OPL3_MODE_SYNTH 0 /* OSS - voices allocated by application */
308*4882a593Smuzhiyun #define SNDRV_OPL3_MODE_SEQ 1 /* ALSA - driver handles voice allocation */
309*4882a593Smuzhiyun int synth_mode; /* synth mode */
310*4882a593Smuzhiyun int seq_client;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun struct snd_seq_device *seq_dev; /* sequencer device */
313*4882a593Smuzhiyun struct snd_midi_channel_set * chset;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
316*4882a593Smuzhiyun struct snd_seq_device *oss_seq_dev; /* OSS sequencer device */
317*4882a593Smuzhiyun struct snd_midi_channel_set * oss_chset;
318*4882a593Smuzhiyun #endif
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun #define OPL3_PATCH_HASH_SIZE 32
321*4882a593Smuzhiyun struct fm_patch *patch_table[OPL3_PATCH_HASH_SIZE];
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun struct snd_opl3_voice voices[MAX_OPL3_VOICES]; /* Voices (OPL3 'channel') */
324*4882a593Smuzhiyun int use_time; /* allocation counter */
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun unsigned short connection_reg; /* connection reg shadow */
327*4882a593Smuzhiyun unsigned char drum_reg; /* percussion reg shadow */
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun spinlock_t voice_lock; /* Lock for voice access */
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun struct timer_list tlist; /* timer for note-offs and effects */
332*4882a593Smuzhiyun int sys_timer_status; /* system timer run status */
333*4882a593Smuzhiyun spinlock_t sys_timer_lock; /* Lock for system timer access */
334*4882a593Smuzhiyun #endif
335*4882a593Smuzhiyun };
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun /* opl3.c */
338*4882a593Smuzhiyun void snd_opl3_interrupt(struct snd_hwdep * hw);
339*4882a593Smuzhiyun int snd_opl3_new(struct snd_card *card, unsigned short hardware,
340*4882a593Smuzhiyun struct snd_opl3 **ropl3);
341*4882a593Smuzhiyun int snd_opl3_init(struct snd_opl3 *opl3);
342*4882a593Smuzhiyun int snd_opl3_create(struct snd_card *card,
343*4882a593Smuzhiyun unsigned long l_port, unsigned long r_port,
344*4882a593Smuzhiyun unsigned short hardware,
345*4882a593Smuzhiyun int integrated,
346*4882a593Smuzhiyun struct snd_opl3 ** opl3);
347*4882a593Smuzhiyun int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev);
348*4882a593Smuzhiyun int snd_opl3_hwdep_new(struct snd_opl3 * opl3, int device, int seq_device,
349*4882a593Smuzhiyun struct snd_hwdep ** rhwdep);
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun /* opl3_synth */
352*4882a593Smuzhiyun int snd_opl3_open(struct snd_hwdep * hw, struct file *file);
353*4882a593Smuzhiyun int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
354*4882a593Smuzhiyun unsigned int cmd, unsigned long arg);
355*4882a593Smuzhiyun int snd_opl3_release(struct snd_hwdep * hw, struct file *file);
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun void snd_opl3_reset(struct snd_opl3 * opl3);
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SEQUENCER)
360*4882a593Smuzhiyun long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count,
361*4882a593Smuzhiyun loff_t *offset);
362*4882a593Smuzhiyun int snd_opl3_load_patch(struct snd_opl3 *opl3,
363*4882a593Smuzhiyun int prog, int bank, int type,
364*4882a593Smuzhiyun const char *name,
365*4882a593Smuzhiyun const unsigned char *ext,
366*4882a593Smuzhiyun const unsigned char *data);
367*4882a593Smuzhiyun struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank,
368*4882a593Smuzhiyun int create_patch);
369*4882a593Smuzhiyun void snd_opl3_clear_patches(struct snd_opl3 *opl3);
370*4882a593Smuzhiyun #else
371*4882a593Smuzhiyun #define snd_opl3_write NULL
snd_opl3_clear_patches(struct snd_opl3 * opl3)372*4882a593Smuzhiyun static inline void snd_opl3_clear_patches(struct snd_opl3 *opl3) {}
373*4882a593Smuzhiyun #endif
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun #endif /* __SOUND_OPL3_H */
376