xref: /openbmc/linux/include/sound/opl3.h (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*1a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds #ifndef __SOUND_OPL3_H
31da177e4SLinus Torvalds #define __SOUND_OPL3_H
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds /*
61da177e4SLinus Torvalds  * Definitions of the OPL-3 registers.
71da177e4SLinus Torvalds  *
8c1017a4cSJaroslav Kysela  * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
91da177e4SLinus Torvalds  *                  Hannu Savolainen 1993-1996
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  *      The OPL-3 mode is switched on by writing 0x01, to the offset 5
121da177e4SLinus Torvalds  *      of the right side.
131da177e4SLinus Torvalds  *
141da177e4SLinus Torvalds  *      Another special register at the right side is at offset 4. It contains
151da177e4SLinus Torvalds  *      a bit mask defining which voices are used as 4 OP voices.
161da177e4SLinus Torvalds  *
171da177e4SLinus Torvalds  *      The percussive mode is implemented in the left side only.
181da177e4SLinus Torvalds  *
191da177e4SLinus Torvalds  *      With the above exceptions the both sides can be operated independently.
201da177e4SLinus Torvalds  *
211da177e4SLinus Torvalds  *      A 4 OP voice can be created by setting the corresponding
221da177e4SLinus Torvalds  *      bit at offset 4 of the right side.
231da177e4SLinus Torvalds  *
241da177e4SLinus Torvalds  *      For example setting the rightmost bit (0x01) changes the
251da177e4SLinus Torvalds  *      first voice on the right side to the 4 OP mode. The fourth
261da177e4SLinus Torvalds  *      voice is made inaccessible.
271da177e4SLinus Torvalds  *
281da177e4SLinus Torvalds  *      If a voice is set to the 2 OP mode, it works like 2 OP modes
291da177e4SLinus Torvalds  *      of the original YM3812 (AdLib). In addition the voice can
301da177e4SLinus Torvalds  *      be connected the left, right or both stereo channels. It can
311da177e4SLinus Torvalds  *      even be left unconnected. This works with 4 OP voices also.
321da177e4SLinus Torvalds  *
331da177e4SLinus Torvalds  *      The stereo connection bits are located in the FEEDBACK_CONNECTION
341da177e4SLinus Torvalds  *      register of the voice (0xC0-0xC8). In 4 OP voices these bits are
351da177e4SLinus Torvalds  *      in the second half of the voice.
361da177e4SLinus Torvalds  */
371da177e4SLinus Torvalds 
389004acc7STakashi Iwai #include <sound/core.h>
399004acc7STakashi Iwai #include <sound/hwdep.h>
409004acc7STakashi Iwai #include <sound/timer.h>
419004acc7STakashi Iwai #include <sound/seq_midi_emul.h>
429004acc7STakashi Iwai #include <sound/seq_oss.h>
439004acc7STakashi Iwai #include <sound/seq_oss_legacy.h>
449004acc7STakashi Iwai #include <sound/seq_device.h>
459004acc7STakashi Iwai #include <sound/asound_fm.h>
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds /*
481da177e4SLinus Torvalds  *    Register numbers for the global registers
491da177e4SLinus Torvalds  */
501da177e4SLinus Torvalds 
511da177e4SLinus Torvalds #define OPL3_REG_TEST			0x01
521da177e4SLinus Torvalds #define   OPL3_ENABLE_WAVE_SELECT	0x20
531da177e4SLinus Torvalds 
541da177e4SLinus Torvalds #define OPL3_REG_TIMER1			0x02
551da177e4SLinus Torvalds #define OPL3_REG_TIMER2			0x03
561da177e4SLinus Torvalds #define OPL3_REG_TIMER_CONTROL		0x04	/* Left side */
571da177e4SLinus Torvalds #define   OPL3_IRQ_RESET		0x80
581da177e4SLinus Torvalds #define   OPL3_TIMER1_MASK		0x40
591da177e4SLinus Torvalds #define   OPL3_TIMER2_MASK		0x20
601da177e4SLinus Torvalds #define   OPL3_TIMER1_START		0x01
611da177e4SLinus Torvalds #define   OPL3_TIMER2_START		0x02
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds #define OPL3_REG_CONNECTION_SELECT	0x04	/* Right side */
641da177e4SLinus Torvalds #define   OPL3_LEFT_4OP_0		0x01
651da177e4SLinus Torvalds #define   OPL3_LEFT_4OP_1		0x02
661da177e4SLinus Torvalds #define   OPL3_LEFT_4OP_2		0x04
671da177e4SLinus Torvalds #define   OPL3_RIGHT_4OP_0		0x08
681da177e4SLinus Torvalds #define   OPL3_RIGHT_4OP_1		0x10
691da177e4SLinus Torvalds #define   OPL3_RIGHT_4OP_2		0x20
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds #define OPL3_REG_MODE			0x05	/* Right side */
721da177e4SLinus Torvalds #define   OPL3_OPL3_ENABLE		0x01	/* OPL3 mode */
731da177e4SLinus Torvalds #define   OPL3_OPL4_ENABLE		0x02	/* OPL4 mode */
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds #define OPL3_REG_KBD_SPLIT		0x08	/* Left side */
761da177e4SLinus Torvalds #define   OPL3_COMPOSITE_SINE_WAVE_MODE	0x80	/* Don't use with OPL-3? */
771da177e4SLinus Torvalds #define   OPL3_KEYBOARD_SPLIT		0x40
781da177e4SLinus Torvalds 
791da177e4SLinus Torvalds #define OPL3_REG_PERCUSSION		0xbd	/* Left side only */
801da177e4SLinus Torvalds #define   OPL3_TREMOLO_DEPTH		0x80
811da177e4SLinus Torvalds #define   OPL3_VIBRATO_DEPTH		0x40
821da177e4SLinus Torvalds #define	  OPL3_PERCUSSION_ENABLE	0x20
831da177e4SLinus Torvalds #define   OPL3_BASSDRUM_ON		0x10
841da177e4SLinus Torvalds #define   OPL3_SNAREDRUM_ON		0x08
851da177e4SLinus Torvalds #define   OPL3_TOMTOM_ON		0x04
861da177e4SLinus Torvalds #define   OPL3_CYMBAL_ON		0x02
871da177e4SLinus Torvalds #define   OPL3_HIHAT_ON			0x01
881da177e4SLinus Torvalds 
891da177e4SLinus Torvalds /*
901da177e4SLinus Torvalds  *    Offsets to the register banks for operators. To get the
911da177e4SLinus Torvalds  *      register number just add the operator offset to the bank offset
921da177e4SLinus Torvalds  *
931da177e4SLinus Torvalds  *      AM/VIB/EG/KSR/Multiple (0x20 to 0x35)
941da177e4SLinus Torvalds  */
951da177e4SLinus Torvalds #define OPL3_REG_AM_VIB			0x20
961da177e4SLinus Torvalds #define   OPL3_TREMOLO_ON		0x80
971da177e4SLinus Torvalds #define   OPL3_VIBRATO_ON		0x40
981da177e4SLinus Torvalds #define   OPL3_SUSTAIN_ON		0x20
991da177e4SLinus Torvalds #define   OPL3_KSR			0x10	/* Key scaling rate */
1001da177e4SLinus Torvalds #define   OPL3_MULTIPLE_MASK		0x0f	/* Frequency multiplier */
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds  /*
1031da177e4SLinus Torvalds   *   KSL/Total level (0x40 to 0x55)
1041da177e4SLinus Torvalds   */
1051da177e4SLinus Torvalds #define OPL3_REG_KSL_LEVEL		0x40
1061da177e4SLinus Torvalds #define   OPL3_KSL_MASK			0xc0	/* Envelope scaling bits */
1071da177e4SLinus Torvalds #define   OPL3_TOTAL_LEVEL_MASK		0x3f	/* Strength (volume) of OP */
1081da177e4SLinus Torvalds 
1091da177e4SLinus Torvalds /*
1101da177e4SLinus Torvalds  *    Attack / Decay rate (0x60 to 0x75)
1111da177e4SLinus Torvalds  */
1121da177e4SLinus Torvalds #define OPL3_REG_ATTACK_DECAY		0x60
1131da177e4SLinus Torvalds #define   OPL3_ATTACK_MASK		0xf0
1141da177e4SLinus Torvalds #define   OPL3_DECAY_MASK		0x0f
1151da177e4SLinus Torvalds 
1161da177e4SLinus Torvalds /*
1171da177e4SLinus Torvalds  * Sustain level / Release rate (0x80 to 0x95)
1181da177e4SLinus Torvalds  */
1191da177e4SLinus Torvalds #define OPL3_REG_SUSTAIN_RELEASE	0x80
1201da177e4SLinus Torvalds #define   OPL3_SUSTAIN_MASK		0xf0
1211da177e4SLinus Torvalds #define   OPL3_RELEASE_MASK		0x0f
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds /*
1241da177e4SLinus Torvalds  * Wave select (0xE0 to 0xF5)
1251da177e4SLinus Torvalds  */
1261da177e4SLinus Torvalds #define OPL3_REG_WAVE_SELECT		0xe0
1271da177e4SLinus Torvalds #define   OPL3_WAVE_SELECT_MASK		0x07
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds /*
1301da177e4SLinus Torvalds  *    Offsets to the register banks for voices. Just add to the
1311da177e4SLinus Torvalds  *      voice number to get the register number.
1321da177e4SLinus Torvalds  *
1331da177e4SLinus Torvalds  *      F-Number low bits (0xA0 to 0xA8).
1341da177e4SLinus Torvalds  */
1351da177e4SLinus Torvalds #define OPL3_REG_FNUM_LOW		0xa0
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds /*
1381da177e4SLinus Torvalds  *    F-number high bits / Key on / Block (octave) (0xB0 to 0xB8)
1391da177e4SLinus Torvalds  */
1401da177e4SLinus Torvalds #define OPL3_REG_KEYON_BLOCK		0xb0
1411da177e4SLinus Torvalds #define	  OPL3_KEYON_BIT		0x20
1421da177e4SLinus Torvalds #define	  OPL3_BLOCKNUM_MASK		0x1c
1431da177e4SLinus Torvalds #define   OPL3_FNUM_HIGH_MASK		0x03
1441da177e4SLinus Torvalds 
1451da177e4SLinus Torvalds /*
1461da177e4SLinus Torvalds  *    Feedback / Connection (0xc0 to 0xc8)
1471da177e4SLinus Torvalds  *
1481da177e4SLinus Torvalds  *      These registers have two new bits when the OPL-3 mode
1491da177e4SLinus Torvalds  *      is selected. These bits controls connecting the voice
1501da177e4SLinus Torvalds  *      to the stereo channels. For 4 OP voices this bit is
1511da177e4SLinus Torvalds  *      defined in the second half of the voice (add 3 to the
1521da177e4SLinus Torvalds  *      register offset).
1531da177e4SLinus Torvalds  *
1541da177e4SLinus Torvalds  *      For 4 OP voices the connection bit is used in the
1551da177e4SLinus Torvalds  *      both halves (gives 4 ways to connect the operators).
1561da177e4SLinus Torvalds  */
1571da177e4SLinus Torvalds #define OPL3_REG_FEEDBACK_CONNECTION	0xc0
1581da177e4SLinus Torvalds #define   OPL3_FEEDBACK_MASK		0x0e	/* Valid just for 1st OP of a voice */
1591da177e4SLinus Torvalds #define   OPL3_CONNECTION_BIT		0x01
1601da177e4SLinus Torvalds /*
1611da177e4SLinus Torvalds  *    In the 4 OP mode there is four possible configurations how the
1621da177e4SLinus Torvalds  *      operators can be connected together (in 2 OP modes there is just
1631da177e4SLinus Torvalds  *      AM or FM). The 4 OP connection mode is defined by the rightmost
1641da177e4SLinus Torvalds  *      bit of the FEEDBACK_CONNECTION (0xC0-0xC8) on the both halves.
1651da177e4SLinus Torvalds  *
1661da177e4SLinus Torvalds  *      First half      Second half     Mode
1671da177e4SLinus Torvalds  *
1681da177e4SLinus Torvalds  *                                       +---+
1691da177e4SLinus Torvalds  *                                       v   |
1701da177e4SLinus Torvalds  *      0               0               >+-1-+--2--3--4-->
1711da177e4SLinus Torvalds  *
1721da177e4SLinus Torvalds  *
1731da177e4SLinus Torvalds  *
1741da177e4SLinus Torvalds  *                                       +---+
1751da177e4SLinus Torvalds  *                                       |   |
1761da177e4SLinus Torvalds  *      0               1               >+-1-+--2-+
1771da177e4SLinus Torvalds  *                                                |->
1781da177e4SLinus Torvalds  *                                      >--3----4-+
1791da177e4SLinus Torvalds  *
1801da177e4SLinus Torvalds  *                                       +---+
1811da177e4SLinus Torvalds  *                                       |   |
1821da177e4SLinus Torvalds  *      1               0               >+-1-+-----+
1831da177e4SLinus Torvalds  *                                                 |->
1841da177e4SLinus Torvalds  *                                      >--2--3--4-+
1851da177e4SLinus Torvalds  *
1861da177e4SLinus Torvalds  *                                       +---+
1871da177e4SLinus Torvalds  *                                       |   |
1881da177e4SLinus Torvalds  *      1               1               >+-1-+--+
1891da177e4SLinus Torvalds  *                                              |
1901da177e4SLinus Torvalds  *                                      >--2--3-+->
1911da177e4SLinus Torvalds  *                                              |
1921da177e4SLinus Torvalds  *                                      >--4----+
1931da177e4SLinus Torvalds  */
1941da177e4SLinus Torvalds #define   OPL3_STEREO_BITS		0x30	/* OPL-3 only */
1951da177e4SLinus Torvalds #define     OPL3_VOICE_TO_LEFT		0x10
1961da177e4SLinus Torvalds #define     OPL3_VOICE_TO_RIGHT		0x20
1971da177e4SLinus Torvalds 
1981da177e4SLinus Torvalds /*
1991da177e4SLinus Torvalds 
2001da177e4SLinus Torvalds  */
2011da177e4SLinus Torvalds 
2021da177e4SLinus Torvalds #define OPL3_LEFT		0x0000
2031da177e4SLinus Torvalds #define OPL3_RIGHT		0x0100
2041da177e4SLinus Torvalds 
2051da177e4SLinus Torvalds #define OPL3_HW_AUTO		0x0000
2061da177e4SLinus Torvalds #define OPL3_HW_OPL2		0x0200
2071da177e4SLinus Torvalds #define OPL3_HW_OPL3		0x0300
2081da177e4SLinus Torvalds #define OPL3_HW_OPL3_SV		0x0301	/* S3 SonicVibes */
2091da177e4SLinus Torvalds #define OPL3_HW_OPL3_CS		0x0302	/* CS4232/CS4236+ */
2101da177e4SLinus Torvalds #define OPL3_HW_OPL3_FM801	0x0303	/* FM801 */
2111da177e4SLinus Torvalds #define OPL3_HW_OPL3_CS4281	0x0304	/* CS4281 */
2121da177e4SLinus Torvalds #define OPL3_HW_OPL4		0x0400	/* YMF278B/YMF295 */
2131da177e4SLinus Torvalds #define OPL3_HW_OPL4_ML		0x0401	/* YMF704/YMF721 */
2141da177e4SLinus Torvalds #define OPL3_HW_MASK		0xff00
2151da177e4SLinus Torvalds 
2161da177e4SLinus Torvalds #define MAX_OPL2_VOICES		9
2171da177e4SLinus Torvalds #define MAX_OPL3_VOICES		18
2181da177e4SLinus Torvalds 
2195b1646a8STakashi Iwai struct snd_opl3;
2201da177e4SLinus Torvalds 
2211da177e4SLinus Torvalds /*
222224a0332STakashi Iwai  * Instrument record, aka "Patch"
223224a0332STakashi Iwai  */
224224a0332STakashi Iwai 
225224a0332STakashi Iwai /* FM operator */
226224a0332STakashi Iwai struct fm_operator {
227224a0332STakashi Iwai 	unsigned char am_vib;
228224a0332STakashi Iwai 	unsigned char ksl_level;
229224a0332STakashi Iwai 	unsigned char attack_decay;
230224a0332STakashi Iwai 	unsigned char sustain_release;
231224a0332STakashi Iwai 	unsigned char wave_select;
232224a0332STakashi Iwai } __attribute__((packed));
233224a0332STakashi Iwai 
234224a0332STakashi Iwai /* Instrument data */
235224a0332STakashi Iwai struct fm_instrument {
236224a0332STakashi Iwai 	struct fm_operator op[4];
237224a0332STakashi Iwai 	unsigned char feedback_connection[2];
238224a0332STakashi Iwai 	unsigned char echo_delay;
239224a0332STakashi Iwai 	unsigned char echo_atten;
240224a0332STakashi Iwai 	unsigned char chorus_spread;
241224a0332STakashi Iwai 	unsigned char trnsps;
242224a0332STakashi Iwai 	unsigned char fix_dur;
243224a0332STakashi Iwai 	unsigned char modes;
244224a0332STakashi Iwai 	unsigned char fix_key;
245224a0332STakashi Iwai };
246224a0332STakashi Iwai 
247224a0332STakashi Iwai /* type */
248224a0332STakashi Iwai #define FM_PATCH_OPL2	0x01		/* OPL2 2 operators FM instrument */
249224a0332STakashi Iwai #define FM_PATCH_OPL3	0x02		/* OPL3 4 operators FM instrument */
250224a0332STakashi Iwai 
251224a0332STakashi Iwai /* Instrument record */
252224a0332STakashi Iwai struct fm_patch {
253224a0332STakashi Iwai 	unsigned char prog;
254224a0332STakashi Iwai 	unsigned char bank;
255224a0332STakashi Iwai 	unsigned char type;
256224a0332STakashi Iwai 	struct fm_instrument inst;
257224a0332STakashi Iwai 	char name[24];
258224a0332STakashi Iwai 	struct fm_patch *next;
259224a0332STakashi Iwai };
260224a0332STakashi Iwai 
261224a0332STakashi Iwai 
262224a0332STakashi Iwai /*
2631da177e4SLinus Torvalds  * A structure to keep track of each hardware voice
2641da177e4SLinus Torvalds  */
2655b1646a8STakashi Iwai struct snd_opl3_voice {
2661da177e4SLinus Torvalds 	int  state;		/* status */
2671da177e4SLinus Torvalds #define SNDRV_OPL3_ST_OFF		0	/* Not playing */
2681da177e4SLinus Torvalds #define SNDRV_OPL3_ST_ON_2OP	1	/* 2op voice is allocated */
2691da177e4SLinus Torvalds #define SNDRV_OPL3_ST_ON_4OP	2	/* 4op voice is allocated */
2701da177e4SLinus Torvalds #define SNDRV_OPL3_ST_NOT_AVAIL	-1	/* voice is not available */
2711da177e4SLinus Torvalds 
2721da177e4SLinus Torvalds 	unsigned int time;	/* An allocation time */
2731da177e4SLinus Torvalds 	unsigned char note;	/* Note currently assigned to this voice */
2741da177e4SLinus Torvalds 
2751da177e4SLinus Torvalds 	unsigned long note_off;	/* note-off time */
2761da177e4SLinus Torvalds 	int note_off_check;	/* check note-off time */
2771da177e4SLinus Torvalds 
2781da177e4SLinus Torvalds 	unsigned char keyon_reg;	/* KON register shadow */
2791da177e4SLinus Torvalds 
2805b1646a8STakashi Iwai 	struct snd_midi_channel *chan;	/* Midi channel for this note */
2815b1646a8STakashi Iwai };
2821da177e4SLinus Torvalds 
2831da177e4SLinus Torvalds struct snd_opl3 {
2841da177e4SLinus Torvalds 	unsigned long l_port;
2851da177e4SLinus Torvalds 	unsigned long r_port;
2861da177e4SLinus Torvalds 	struct resource *res_l_port;
2871da177e4SLinus Torvalds 	struct resource *res_r_port;
2881da177e4SLinus Torvalds 	unsigned short hardware;
2891da177e4SLinus Torvalds 	/* hardware access */
2905b1646a8STakashi Iwai 	void (*command) (struct snd_opl3 * opl3, unsigned short cmd, unsigned char val);
2911da177e4SLinus Torvalds 	unsigned short timer_enable;
2921da177e4SLinus Torvalds 	int seq_dev_num;	/* sequencer device number */
2935b1646a8STakashi Iwai 	struct snd_timer *timer1;
2945b1646a8STakashi Iwai 	struct snd_timer *timer2;
2951da177e4SLinus Torvalds 	spinlock_t timer_lock;
2961da177e4SLinus Torvalds 
2971da177e4SLinus Torvalds 	void *private_data;
2985b1646a8STakashi Iwai 	void (*private_free)(struct snd_opl3 *);
2991da177e4SLinus Torvalds 
30004576525STakashi Iwai 	struct snd_hwdep *hwdep;
3011da177e4SLinus Torvalds 	spinlock_t reg_lock;
3025b1646a8STakashi Iwai 	struct snd_card *card;		/* The card that this belongs to */
3031da177e4SLinus Torvalds 	unsigned char fm_mode;		/* OPL mode, see SNDRV_DM_FM_MODE_XXX */
3041da177e4SLinus Torvalds 	unsigned char rhythm;		/* percussion mode flag */
3051da177e4SLinus Torvalds 	unsigned char max_voices;	/* max number of voices */
3066d2412b8STakashi Iwai #if IS_ENABLED(CONFIG_SND_SEQUENCER)
3071da177e4SLinus Torvalds #define SNDRV_OPL3_MODE_SYNTH 0		/* OSS - voices allocated by application */
3081da177e4SLinus Torvalds #define SNDRV_OPL3_MODE_SEQ 1		/* ALSA - driver handles voice allocation */
3091da177e4SLinus Torvalds 	int synth_mode;			/* synth mode */
3101da177e4SLinus Torvalds 	int seq_client;
3111da177e4SLinus Torvalds 
3125b1646a8STakashi Iwai 	struct snd_seq_device *seq_dev;	/* sequencer device */
3135b1646a8STakashi Iwai 	struct snd_midi_channel_set * chset;
3141da177e4SLinus Torvalds 
3153d774d5eSTakashi Iwai #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
3165b1646a8STakashi Iwai 	struct snd_seq_device *oss_seq_dev;	/* OSS sequencer device */
3175b1646a8STakashi Iwai 	struct snd_midi_channel_set * oss_chset;
3181da177e4SLinus Torvalds #endif
3191da177e4SLinus Torvalds 
320224a0332STakashi Iwai #define OPL3_PATCH_HASH_SIZE	32
321224a0332STakashi Iwai 	struct fm_patch *patch_table[OPL3_PATCH_HASH_SIZE];
3221da177e4SLinus Torvalds 
3235b1646a8STakashi Iwai 	struct snd_opl3_voice voices[MAX_OPL3_VOICES]; /* Voices (OPL3 'channel') */
3241da177e4SLinus Torvalds 	int use_time;			/* allocation counter */
3251da177e4SLinus Torvalds 
3261da177e4SLinus Torvalds 	unsigned short connection_reg;	/* connection reg shadow */
3271da177e4SLinus Torvalds 	unsigned char drum_reg;		/* percussion reg shadow */
3281da177e4SLinus Torvalds 
3291da177e4SLinus Torvalds 	spinlock_t voice_lock;		/* Lock for voice access */
3301da177e4SLinus Torvalds 
3311da177e4SLinus Torvalds 	struct timer_list tlist;	/* timer for note-offs and effects */
3321da177e4SLinus Torvalds 	int sys_timer_status;		/* system timer run status */
3331da177e4SLinus Torvalds 	spinlock_t sys_timer_lock;	/* Lock for system timer access */
3341da177e4SLinus Torvalds #endif
3351da177e4SLinus Torvalds };
3361da177e4SLinus Torvalds 
3371da177e4SLinus Torvalds /* opl3.c */
3385b1646a8STakashi Iwai void snd_opl3_interrupt(struct snd_hwdep * hw);
3395b1646a8STakashi Iwai int snd_opl3_new(struct snd_card *card, unsigned short hardware,
3405b1646a8STakashi Iwai 		 struct snd_opl3 **ropl3);
3415b1646a8STakashi Iwai int snd_opl3_init(struct snd_opl3 *opl3);
3425b1646a8STakashi Iwai int snd_opl3_create(struct snd_card *card,
3431da177e4SLinus Torvalds 		    unsigned long l_port, unsigned long r_port,
3441da177e4SLinus Torvalds 		    unsigned short hardware,
3451da177e4SLinus Torvalds 		    int integrated,
3465b1646a8STakashi Iwai 		    struct snd_opl3 ** opl3);
3475b1646a8STakashi Iwai int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev);
3485b1646a8STakashi Iwai int snd_opl3_hwdep_new(struct snd_opl3 * opl3, int device, int seq_device,
3495b1646a8STakashi Iwai 		       struct snd_hwdep ** rhwdep);
3501da177e4SLinus Torvalds 
3511da177e4SLinus Torvalds /* opl3_synth */
3525b1646a8STakashi Iwai int snd_opl3_open(struct snd_hwdep * hw, struct file *file);
3535b1646a8STakashi Iwai int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
3541da177e4SLinus Torvalds 		   unsigned int cmd, unsigned long arg);
3555b1646a8STakashi Iwai int snd_opl3_release(struct snd_hwdep * hw, struct file *file);
3561da177e4SLinus Torvalds 
3575b1646a8STakashi Iwai void snd_opl3_reset(struct snd_opl3 * opl3);
3581da177e4SLinus Torvalds 
3596d2412b8STakashi Iwai #if IS_ENABLED(CONFIG_SND_SEQUENCER)
3600ee46c9dSTakashi Iwai long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count,
3610ee46c9dSTakashi Iwai 		    loff_t *offset);
362224a0332STakashi Iwai int snd_opl3_load_patch(struct snd_opl3 *opl3,
363224a0332STakashi Iwai 			int prog, int bank, int type,
364224a0332STakashi Iwai 			const char *name,
365224a0332STakashi Iwai 			const unsigned char *ext,
366224a0332STakashi Iwai 			const unsigned char *data);
367224a0332STakashi Iwai struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank,
368224a0332STakashi Iwai 				     int create_patch);
369224a0332STakashi Iwai void snd_opl3_clear_patches(struct snd_opl3 *opl3);
3700ee46c9dSTakashi Iwai #else
3710ee46c9dSTakashi Iwai #define snd_opl3_write	NULL
snd_opl3_clear_patches(struct snd_opl3 * opl3)3720ee46c9dSTakashi Iwai static inline void snd_opl3_clear_patches(struct snd_opl3 *opl3) {}
3730ee46c9dSTakashi Iwai #endif
374224a0332STakashi Iwai 
3751da177e4SLinus Torvalds #endif /* __SOUND_OPL3_H */
376