summaryrefslogtreecommitdiffstats
path: root/kernel/sound/drivers/opl4/opl4_local.h
blob: 9a41bdebce6b465415dcf7ae3895281231b99493 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
 * Local definitions for the OPL4 driver
 *
 * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed and/or modified under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef __OPL4_LOCAL_H
#define __OPL4_LOCAL_H

#include <sound/opl4.h>

/*
 * Register numbers
 */

#define OPL4_REG_TEST0			0x00
#define OPL4_REG_TEST1			0x01

#define OPL4_REG_MEMORY_CONFIGURATION	0x02
#define   OPL4_MODE_BIT			0x01
#define   OPL4_MTYPE_BIT		0x02
#define   OPL4_TONE_HEADER_MASK		0x1c
#define   OPL4_DEVICE_ID_MASK		0xe0

#define OPL4_REG_MEMORY_ADDRESS_HIGH	0x03
#define OPL4_REG_MEMORY_ADDRESS_MID	0x04
#define OPL4_REG_MEMORY_ADDRESS_LOW	0x05
#define OPL4_REG_MEMORY_DATA		0x06

/*
 * Offsets to the register banks for voices. To get the
 * register number just add the voice number to the bank offset.
 *
 * Wave Table Number low bits (0x08 to 0x1F)
 */
#define OPL4_REG_TONE_NUMBER		0x08

/* Wave Table Number high bit, F-Number low bits (0x20 to 0x37) */
#define OPL4_REG_F_NUMBER		0x20
#define   OPL4_TONE_NUMBER_BIT8		0x01
#define   OPL4_F_NUMBER_LOW_MASK	0xfe

/* F-Number high bits, Octave, Pseudo-Reverb (0x38 to 0x4F) */
#define OPL4_REG_OCTAVE			0x38
#define   OPL4_F_NUMBER_HIGH_MASK	0x07
#define   OPL4_BLOCK_MASK		0xf0
#define   OPL4_PSEUDO_REVERB_BIT	0x08

/* Total Level, Level Direct (0x50 to 0x67) */
#define OPL4_REG_LEVEL			0x50
#define   OPL4_TOTAL_LEVEL_MASK		0xfe
#define   OPL4_LEVEL_DIRECT_BIT		0x01

/* Key On, Damp, LFO RST, CH, Panpot (0x68 to 0x7F) */
#define OPL4_REG_MISC			0x68
#define   OPL4_KEY_ON_BIT		0x80
#define   OPL4_DAMP_BIT			0x40
#define   OPL4_LFO_RESET_BIT		0x20
#define   OPL4_OUTPUT_CHANNEL_BIT	0x10
#define   OPL4_PAN_POT_MASK		0x0f

/* LFO, VIB (0x80 to 0x97) */
#define OPL4_REG_LFO_VIBRATO		0x80
#define   OPL4_LFO_FREQUENCY_MASK	0x38
#define   OPL4_VIBRATO_DEPTH_MASK	0x07
#define   OPL4_CHORUS_SEND_MASK		0xc0 /* ML only */

/* Attack / Decay 1 rate (0x98 to 0xAF) */
#define OPL4_REG_ATTACK_DECAY1		0x98
#define   OPL4_ATTACK_RATE_MASK		0xf0
#define   OPL4_DECAY1_RATE_MASK		0x0f

/* Decay level / 2 rate (0xB0 to 0xC7) */
#define OPL4_REG_LEVEL_DECAY2		0xb0
#define   OPL4_DECAY_LEVEL_MASK		0xf0
#define   OPL4_DECAY2_RATE_MASK		0x0f

/* Release rate / Rate correction (0xC8 to 0xDF) */
#define OPL4_REG_RELEASE_CORRECTION	0xc8
#define   OPL4_RELEASE_RATE_MASK	0x0f
#define   OPL4_RATE_INTERPOLATION_MASK	0xf0

/* AM (0xE0 to 0xF7) */
#define OPL4_REG_TREMOLO		0xe0
#define   OPL4_TREMOLO_DEPTH_MASK	0x07
#define   OPL4_REVERB_SEND_MASK		0xe0 /* ML only */

/* Mixer */
#define OPL4_REG_MIX_CONTROL_FM		0xf8
#define OPL4_REG_MIX_CONTROL_PCM	0xf9
#define   OPL4_MIX_LEFT_MASK		0x07
#define   OPL4_MIX_RIGHT_MASK		0x38

#define OPL4_REG_ATC			0xfa
#define   OPL4_ATC_BIT			0x01 /* ???, ML only */

/* bits in the OPL3 Status register */
#define OPL4_STATUS_BUSY		0x01
#define OPL4_STATUS_LOAD		0x02


#define OPL4_MAX_VOICES 24

#define SNDRV_SEQ_DEV_ID_OPL4 "opl4-synth"


struct opl4_sound {
	u16 tone;
	s16 pitch_offset;
	u8 key_scaling;
	s8 panpot;
	u8 vibrato;
	u8 tone_attenuate;
	u8 volume_factor;
	u8 reg_lfo_vibrato;
	u8 reg_attack_decay1;
	u8 reg_level_decay2;
	u8 reg_release_correction;
	u8 reg_tremolo;
};

struct opl4_region {
	u8 key_min, key_max;
	struct opl4_sound sound;
};

struct opl4_region_ptr {
	int count;
	const struct opl4_region *regions;
};

struct opl4_voice {
	struct list_head list;
	int number;
	struct snd_midi_channel *chan;
	int note;
	int velocity;
	const struct opl4_sound *sound;
	u8 level_direct;
	u8 reg_f_number;
	u8 reg_misc;
	u8 reg_lfo_vibrato;
};

struct snd_opl4 {
	unsigned long fm_port;
	unsigned long pcm_port;
	struct resource *res_fm_port;
	struct resource *res_pcm_port;
	unsigned short hardware;
	spinlock_t reg_lock;
	struct snd_card *card;

#ifdef CONFIG_SND_PROC_FS
	struct snd_info_entry *proc_entry;
	int memory_access;
#endif
	struct mutex access_mutex;

#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
	int used;

	int seq_dev_num;
	int seq_client;
	struct snd_seq_device *seq_dev;

	struct snd_midi_channel_set *chset;
	struct opl4_voice voices[OPL4_MAX_VOICES];
	struct list_head off_voices;
	struct list_head on_voices;
#endif
};

/* opl4_lib.c */
void snd_opl4_write(struct snd_opl4 *opl4, u8 reg, u8 value);
u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg);
void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size);
void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size);

/* opl4_mixer.c */
int snd_opl4_create_mixer(struct snd_opl4 *opl4);

#ifdef CONFIG_SND_PROC_FS
/* opl4_proc.c */
int snd_opl4_create_proc(struct snd_opl4 *opl4);
void snd_opl4_free_proc(struct snd_opl4 *opl4);
#else
static inline int snd_opl4_create_proc(struct snd_opl4 *opl4) { return 0; }
static inline void snd_opl4_free_proc(struct snd_opl4 *opl4) {}
#endif

/* opl4_seq.c */
extern int volume_boost;

/* opl4_synth.c */
void snd_opl4_synth_reset(struct snd_opl4 *opl4);
void snd_opl4_synth_shutdown(struct snd_opl4 *opl4);
void snd_opl4_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
void snd_opl4_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
void snd_opl4_terminate_note(void *p, int note, struct snd_midi_channel *chan);
void snd_opl4_control(void *p, int type, struct snd_midi_channel *chan);
void snd_opl4_sysex(void *p, unsigned char *buf, int len, int parsed, struct snd_midi_channel_set *chset);

/* yrw801.c */
int snd_yrw801_detect(struct snd_opl4 *opl4);
extern const struct opl4_region_ptr snd_yrw801_regions[];

#endif /* __OPL4_LOCAL_H */