1 | /* |
2 | * Local definitions for the OPL4 driver |
3 | * |
4 | * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de> |
5 | * All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions, and the following disclaimer, |
12 | * without modification. |
13 | * 2. The name of the author may not be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. |
15 | * |
16 | * Alternatively, this software may be distributed and/or modified under the |
17 | * terms of the GNU General Public License as published by the Free Software |
18 | * Foundation; either version 2 of the License, or (at your option) any later |
19 | * version. |
20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR |
25 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
31 | * SUCH DAMAGE. |
32 | */ |
33 | |
34 | #ifndef __OPL4_LOCAL_H |
35 | #define __OPL4_LOCAL_H |
36 | |
37 | #include <sound/opl4.h> |
38 | |
39 | /* |
40 | * Register numbers |
41 | */ |
42 | |
43 | #define OPL4_REG_TEST0 0x00 |
44 | #define OPL4_REG_TEST1 0x01 |
45 | |
46 | #define OPL4_REG_MEMORY_CONFIGURATION 0x02 |
47 | #define OPL4_MODE_BIT 0x01 |
48 | #define OPL4_MTYPE_BIT 0x02 |
49 | #define 0x1c |
50 | #define OPL4_DEVICE_ID_MASK 0xe0 |
51 | |
52 | #define OPL4_REG_MEMORY_ADDRESS_HIGH 0x03 |
53 | #define OPL4_REG_MEMORY_ADDRESS_MID 0x04 |
54 | #define OPL4_REG_MEMORY_ADDRESS_LOW 0x05 |
55 | #define OPL4_REG_MEMORY_DATA 0x06 |
56 | |
57 | /* |
58 | * Offsets to the register banks for voices. To get the |
59 | * register number just add the voice number to the bank offset. |
60 | * |
61 | * Wave Table Number low bits (0x08 to 0x1F) |
62 | */ |
63 | #define OPL4_REG_TONE_NUMBER 0x08 |
64 | |
65 | /* Wave Table Number high bit, F-Number low bits (0x20 to 0x37) */ |
66 | #define OPL4_REG_F_NUMBER 0x20 |
67 | #define OPL4_TONE_NUMBER_BIT8 0x01 |
68 | #define OPL4_F_NUMBER_LOW_MASK 0xfe |
69 | |
70 | /* F-Number high bits, Octave, Pseudo-Reverb (0x38 to 0x4F) */ |
71 | #define OPL4_REG_OCTAVE 0x38 |
72 | #define OPL4_F_NUMBER_HIGH_MASK 0x07 |
73 | #define OPL4_BLOCK_MASK 0xf0 |
74 | #define OPL4_PSEUDO_REVERB_BIT 0x08 |
75 | |
76 | /* Total Level, Level Direct (0x50 to 0x67) */ |
77 | #define OPL4_REG_LEVEL 0x50 |
78 | #define OPL4_TOTAL_LEVEL_MASK 0xfe |
79 | #define OPL4_LEVEL_DIRECT_BIT 0x01 |
80 | |
81 | /* Key On, Damp, LFO RST, CH, Panpot (0x68 to 0x7F) */ |
82 | #define OPL4_REG_MISC 0x68 |
83 | #define OPL4_KEY_ON_BIT 0x80 |
84 | #define OPL4_DAMP_BIT 0x40 |
85 | #define OPL4_LFO_RESET_BIT 0x20 |
86 | #define OPL4_OUTPUT_CHANNEL_BIT 0x10 |
87 | #define OPL4_PAN_POT_MASK 0x0f |
88 | |
89 | /* LFO, VIB (0x80 to 0x97) */ |
90 | #define OPL4_REG_LFO_VIBRATO 0x80 |
91 | #define OPL4_LFO_FREQUENCY_MASK 0x38 |
92 | #define OPL4_VIBRATO_DEPTH_MASK 0x07 |
93 | #define OPL4_CHORUS_SEND_MASK 0xc0 /* ML only */ |
94 | |
95 | /* Attack / Decay 1 rate (0x98 to 0xAF) */ |
96 | #define OPL4_REG_ATTACK_DECAY1 0x98 |
97 | #define OPL4_ATTACK_RATE_MASK 0xf0 |
98 | #define OPL4_DECAY1_RATE_MASK 0x0f |
99 | |
100 | /* Decay level / 2 rate (0xB0 to 0xC7) */ |
101 | #define OPL4_REG_LEVEL_DECAY2 0xb0 |
102 | #define OPL4_DECAY_LEVEL_MASK 0xf0 |
103 | #define OPL4_DECAY2_RATE_MASK 0x0f |
104 | |
105 | /* Release rate / Rate correction (0xC8 to 0xDF) */ |
106 | #define OPL4_REG_RELEASE_CORRECTION 0xc8 |
107 | #define OPL4_RELEASE_RATE_MASK 0x0f |
108 | #define OPL4_RATE_INTERPOLATION_MASK 0xf0 |
109 | |
110 | /* AM (0xE0 to 0xF7) */ |
111 | #define OPL4_REG_TREMOLO 0xe0 |
112 | #define OPL4_TREMOLO_DEPTH_MASK 0x07 |
113 | #define OPL4_REVERB_SEND_MASK 0xe0 /* ML only */ |
114 | |
115 | /* Mixer */ |
116 | #define OPL4_REG_MIX_CONTROL_FM 0xf8 |
117 | #define OPL4_REG_MIX_CONTROL_PCM 0xf9 |
118 | #define OPL4_MIX_LEFT_MASK 0x07 |
119 | #define OPL4_MIX_RIGHT_MASK 0x38 |
120 | |
121 | #define OPL4_REG_ATC 0xfa |
122 | #define OPL4_ATC_BIT 0x01 /* ???, ML only */ |
123 | |
124 | /* bits in the OPL3 Status register */ |
125 | #define OPL4_STATUS_BUSY 0x01 |
126 | #define OPL4_STATUS_LOAD 0x02 |
127 | |
128 | |
129 | #define OPL4_MAX_VOICES 24 |
130 | |
131 | #define SNDRV_SEQ_DEV_ID_OPL4 "opl4-synth" |
132 | |
133 | |
134 | struct opl4_sound { |
135 | u16 tone; |
136 | s16 pitch_offset; |
137 | u8 key_scaling; |
138 | s8 panpot; |
139 | u8 vibrato; |
140 | u8 tone_attenuate; |
141 | u8 volume_factor; |
142 | u8 reg_lfo_vibrato; |
143 | u8 reg_attack_decay1; |
144 | u8 reg_level_decay2; |
145 | u8 reg_release_correction; |
146 | u8 reg_tremolo; |
147 | }; |
148 | |
149 | struct opl4_region { |
150 | u8 key_min, key_max; |
151 | struct opl4_sound sound; |
152 | }; |
153 | |
154 | struct opl4_region_ptr { |
155 | int count; |
156 | const struct opl4_region *regions; |
157 | }; |
158 | |
159 | struct opl4_voice { |
160 | struct list_head list; |
161 | int number; |
162 | struct snd_midi_channel *chan; |
163 | int note; |
164 | int velocity; |
165 | const struct opl4_sound *sound; |
166 | u8 level_direct; |
167 | u8 reg_f_number; |
168 | u8 reg_misc; |
169 | u8 reg_lfo_vibrato; |
170 | }; |
171 | |
172 | struct snd_opl4 { |
173 | unsigned long fm_port; |
174 | unsigned long pcm_port; |
175 | struct resource *res_fm_port; |
176 | struct resource *res_pcm_port; |
177 | unsigned short hardware; |
178 | spinlock_t reg_lock; |
179 | struct snd_card *card; |
180 | |
181 | #ifdef CONFIG_SND_PROC_FS |
182 | struct snd_info_entry *proc_entry; |
183 | int memory_access; |
184 | #endif |
185 | struct mutex access_mutex; |
186 | |
187 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
188 | int used; |
189 | |
190 | int seq_dev_num; |
191 | int seq_client; |
192 | struct snd_seq_device *seq_dev; |
193 | |
194 | struct snd_midi_channel_set *chset; |
195 | struct opl4_voice voices[OPL4_MAX_VOICES]; |
196 | struct list_head off_voices; |
197 | struct list_head on_voices; |
198 | #endif |
199 | }; |
200 | |
201 | /* opl4_lib.c */ |
202 | void snd_opl4_write(struct snd_opl4 *opl4, u8 reg, u8 value); |
203 | u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg); |
204 | void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size); |
205 | void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size); |
206 | |
207 | /* opl4_mixer.c */ |
208 | int snd_opl4_create_mixer(struct snd_opl4 *opl4); |
209 | |
210 | #ifdef CONFIG_SND_PROC_FS |
211 | /* opl4_proc.c */ |
212 | int snd_opl4_create_proc(struct snd_opl4 *opl4); |
213 | void snd_opl4_free_proc(struct snd_opl4 *opl4); |
214 | #else |
215 | static inline int snd_opl4_create_proc(struct snd_opl4 *opl4) { return 0; } |
216 | static inline void snd_opl4_free_proc(struct snd_opl4 *opl4) {} |
217 | #endif |
218 | |
219 | /* opl4_seq.c */ |
220 | extern int volume_boost; |
221 | |
222 | /* opl4_synth.c */ |
223 | void snd_opl4_synth_reset(struct snd_opl4 *opl4); |
224 | void snd_opl4_synth_shutdown(struct snd_opl4 *opl4); |
225 | void snd_opl4_note_on(void *p, int note, int vel, struct snd_midi_channel *chan); |
226 | void snd_opl4_note_off(void *p, int note, int vel, struct snd_midi_channel *chan); |
227 | void snd_opl4_terminate_note(void *p, int note, struct snd_midi_channel *chan); |
228 | void snd_opl4_control(void *p, int type, struct snd_midi_channel *chan); |
229 | void snd_opl4_sysex(void *p, unsigned char *buf, int len, int parsed, struct snd_midi_channel_set *chset); |
230 | |
231 | /* yrw801.c */ |
232 | int snd_yrw801_detect(struct snd_opl4 *opl4); |
233 | extern const struct opl4_region_ptr snd_yrw801_regions[]; |
234 | |
235 | #endif /* __OPL4_LOCAL_H */ |
236 | |