1 /* 2 * Copyright (c) by Uros Bizjak <uros@kss-loka.si> 3 * 4 * Routines for OPL2/OPL3/OPL4 control 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 21 22 #include <sound/opl3.h> 23 #include <sound/asound_fm.h> 24 25 /* 26 * There is 18 possible 2 OP voices 27 * (9 in the left and 9 in the right). 28 * The first OP is the modulator and 2nd is the carrier. 29 * 30 * The first three voices in the both sides may be connected 31 * with another voice to a 4 OP voice. For example voice 0 32 * can be connected with voice 3. The operators of voice 3 are 33 * used as operators 3 and 4 of the new 4 OP voice. 34 * In this case the 2 OP voice number 0 is the 'first half' and 35 * voice 3 is the second. 36 */ 37 38 39 /* 40 * Register offset table for OPL2/3 voices, 41 * OPL2 / one OPL3 register array side only 42 */ 43 44 char snd_opl3_regmap[MAX_OPL2_VOICES][4] = 45 { 46 /* OP1 OP2 OP3 OP4 */ 47 /* ------------------------ */ 48 { 0x00, 0x03, 0x08, 0x0b }, 49 { 0x01, 0x04, 0x09, 0x0c }, 50 { 0x02, 0x05, 0x0a, 0x0d }, 51 52 { 0x08, 0x0b, 0x00, 0x00 }, 53 { 0x09, 0x0c, 0x00, 0x00 }, 54 { 0x0a, 0x0d, 0x00, 0x00 }, 55 56 { 0x10, 0x13, 0x00, 0x00 }, /* used by percussive voices */ 57 { 0x11, 0x14, 0x00, 0x00 }, /* if the percussive mode */ 58 { 0x12, 0x15, 0x00, 0x00 } /* is selected (only left reg block) */ 59 }; 60 61 EXPORT_SYMBOL(snd_opl3_regmap); 62 63 /* 64 * prototypes 65 */ 66 static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note); 67 static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice); 68 static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params); 69 static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode); 70 static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection); 71 72 /* ------------------------------ */ 73 74 /* 75 * open the device exclusively 76 */ 77 int snd_opl3_open(struct snd_hwdep * hw, struct file *file) 78 { 79 struct snd_opl3 *opl3 = hw->private_data; 80 81 mutex_lock(&opl3->access_mutex); 82 if (opl3->used) { 83 mutex_unlock(&opl3->access_mutex); 84 return -EAGAIN; 85 } 86 opl3->used++; 87 mutex_unlock(&opl3->access_mutex); 88 89 return 0; 90 } 91 92 /* 93 * ioctl for hwdep device: 94 */ 95 int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file, 96 unsigned int cmd, unsigned long arg) 97 { 98 struct snd_opl3 *opl3 = hw->private_data; 99 void __user *argp = (void __user *)arg; 100 101 snd_assert(opl3 != NULL, return -EINVAL); 102 103 switch (cmd) { 104 /* get information */ 105 case SNDRV_DM_FM_IOCTL_INFO: 106 { 107 struct snd_dm_fm_info info; 108 109 info.fm_mode = opl3->fm_mode; 110 info.rhythm = opl3->rhythm; 111 if (copy_to_user(argp, &info, sizeof(struct snd_dm_fm_info))) 112 return -EFAULT; 113 return 0; 114 } 115 116 case SNDRV_DM_FM_IOCTL_RESET: 117 #ifdef CONFIG_SND_OSSEMUL 118 case SNDRV_DM_FM_OSS_IOCTL_RESET: 119 #endif 120 snd_opl3_reset(opl3); 121 return 0; 122 123 case SNDRV_DM_FM_IOCTL_PLAY_NOTE: 124 #ifdef CONFIG_SND_OSSEMUL 125 case SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE: 126 #endif 127 { 128 struct snd_dm_fm_note note; 129 if (copy_from_user(¬e, argp, sizeof(struct snd_dm_fm_note))) 130 return -EFAULT; 131 return snd_opl3_play_note(opl3, ¬e); 132 } 133 134 case SNDRV_DM_FM_IOCTL_SET_VOICE: 135 #ifdef CONFIG_SND_OSSEMUL 136 case SNDRV_DM_FM_OSS_IOCTL_SET_VOICE: 137 #endif 138 { 139 struct snd_dm_fm_voice voice; 140 if (copy_from_user(&voice, argp, sizeof(struct snd_dm_fm_voice))) 141 return -EFAULT; 142 return snd_opl3_set_voice(opl3, &voice); 143 } 144 145 case SNDRV_DM_FM_IOCTL_SET_PARAMS: 146 #ifdef CONFIG_SND_OSSEMUL 147 case SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS: 148 #endif 149 { 150 struct snd_dm_fm_params params; 151 if (copy_from_user(¶ms, argp, sizeof(struct snd_dm_fm_params))) 152 return -EFAULT; 153 return snd_opl3_set_params(opl3, ¶ms); 154 } 155 156 case SNDRV_DM_FM_IOCTL_SET_MODE: 157 #ifdef CONFIG_SND_OSSEMUL 158 case SNDRV_DM_FM_OSS_IOCTL_SET_MODE: 159 #endif 160 return snd_opl3_set_mode(opl3, (int) arg); 161 162 case SNDRV_DM_FM_IOCTL_SET_CONNECTION: 163 #ifdef CONFIG_SND_OSSEMUL 164 case SNDRV_DM_FM_OSS_IOCTL_SET_OPL: 165 #endif 166 return snd_opl3_set_connection(opl3, (int) arg); 167 168 #ifdef CONFIG_SND_DEBUG 169 default: 170 snd_printk("unknown IOCTL: 0x%x\n", cmd); 171 #endif 172 } 173 return -ENOTTY; 174 } 175 176 /* 177 * close the device 178 */ 179 int snd_opl3_release(struct snd_hwdep * hw, struct file *file) 180 { 181 struct snd_opl3 *opl3 = hw->private_data; 182 183 snd_opl3_reset(opl3); 184 mutex_lock(&opl3->access_mutex); 185 opl3->used--; 186 mutex_unlock(&opl3->access_mutex); 187 188 return 0; 189 } 190 191 /* ------------------------------ */ 192 193 void snd_opl3_reset(struct snd_opl3 * opl3) 194 { 195 unsigned short opl3_reg; 196 197 unsigned short reg_side; 198 unsigned char voice_offset; 199 200 int max_voices, i; 201 202 max_voices = (opl3->hardware < OPL3_HW_OPL3) ? 203 MAX_OPL2_VOICES : MAX_OPL3_VOICES; 204 205 for (i = 0; i < max_voices; i++) { 206 /* Get register array side and offset of voice */ 207 if (i < MAX_OPL2_VOICES) { 208 /* Left register block for voices 0 .. 8 */ 209 reg_side = OPL3_LEFT; 210 voice_offset = i; 211 } else { 212 /* Right register block for voices 9 .. 17 */ 213 reg_side = OPL3_RIGHT; 214 voice_offset = i - MAX_OPL2_VOICES; 215 } 216 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + snd_opl3_regmap[voice_offset][0]); 217 opl3->command(opl3, opl3_reg, OPL3_TOTAL_LEVEL_MASK); /* Operator 1 volume */ 218 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + snd_opl3_regmap[voice_offset][1]); 219 opl3->command(opl3, opl3_reg, OPL3_TOTAL_LEVEL_MASK); /* Operator 2 volume */ 220 221 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); 222 opl3->command(opl3, opl3_reg, 0x00); /* Note off */ 223 } 224 225 opl3->max_voices = MAX_OPL2_VOICES; 226 opl3->fm_mode = SNDRV_DM_FM_MODE_OPL2; 227 228 opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT); 229 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00); /* Melodic mode */ 230 opl3->rhythm = 0; 231 } 232 233 EXPORT_SYMBOL(snd_opl3_reset); 234 235 static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note) 236 { 237 unsigned short reg_side; 238 unsigned char voice_offset; 239 240 unsigned short opl3_reg; 241 unsigned char reg_val; 242 243 /* Voices 0 - 8 in OPL2 mode */ 244 /* Voices 0 - 17 in OPL3 mode */ 245 if (note->voice >= ((opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) ? 246 MAX_OPL3_VOICES : MAX_OPL2_VOICES)) 247 return -EINVAL; 248 249 /* Get register array side and offset of voice */ 250 if (note->voice < MAX_OPL2_VOICES) { 251 /* Left register block for voices 0 .. 8 */ 252 reg_side = OPL3_LEFT; 253 voice_offset = note->voice; 254 } else { 255 /* Right register block for voices 9 .. 17 */ 256 reg_side = OPL3_RIGHT; 257 voice_offset = note->voice - MAX_OPL2_VOICES; 258 } 259 260 /* Set lower 8 bits of note frequency */ 261 reg_val = (unsigned char) note->fnum; 262 opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset); 263 opl3->command(opl3, opl3_reg, reg_val); 264 265 reg_val = 0x00; 266 /* Set output sound flag */ 267 if (note->key_on) 268 reg_val |= OPL3_KEYON_BIT; 269 /* Set octave */ 270 reg_val |= (note->octave << 2) & OPL3_BLOCKNUM_MASK; 271 /* Set higher 2 bits of note frequency */ 272 reg_val |= (unsigned char) (note->fnum >> 8) & OPL3_FNUM_HIGH_MASK; 273 274 /* Set OPL3 KEYON_BLOCK register of requested voice */ 275 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); 276 opl3->command(opl3, opl3_reg, reg_val); 277 278 return 0; 279 } 280 281 282 static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice) 283 { 284 unsigned short reg_side; 285 unsigned char op_offset; 286 unsigned char voice_offset; 287 288 unsigned short opl3_reg; 289 unsigned char reg_val; 290 291 /* Only operators 1 and 2 */ 292 if (voice->op > 1) 293 return -EINVAL; 294 /* Voices 0 - 8 in OPL2 mode */ 295 /* Voices 0 - 17 in OPL3 mode */ 296 if (voice->voice >= ((opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) ? 297 MAX_OPL3_VOICES : MAX_OPL2_VOICES)) 298 return -EINVAL; 299 300 /* Get register array side and offset of voice */ 301 if (voice->voice < MAX_OPL2_VOICES) { 302 /* Left register block for voices 0 .. 8 */ 303 reg_side = OPL3_LEFT; 304 voice_offset = voice->voice; 305 } else { 306 /* Right register block for voices 9 .. 17 */ 307 reg_side = OPL3_RIGHT; 308 voice_offset = voice->voice - MAX_OPL2_VOICES; 309 } 310 /* Get register offset of operator */ 311 op_offset = snd_opl3_regmap[voice_offset][voice->op]; 312 313 reg_val = 0x00; 314 /* Set amplitude modulation (tremolo) effect */ 315 if (voice->am) 316 reg_val |= OPL3_TREMOLO_ON; 317 /* Set vibrato effect */ 318 if (voice->vibrato) 319 reg_val |= OPL3_VIBRATO_ON; 320 /* Set sustaining sound phase */ 321 if (voice->do_sustain) 322 reg_val |= OPL3_SUSTAIN_ON; 323 /* Set keyboard scaling bit */ 324 if (voice->kbd_scale) 325 reg_val |= OPL3_KSR; 326 /* Set harmonic or frequency multiplier */ 327 reg_val |= voice->harmonic & OPL3_MULTIPLE_MASK; 328 329 /* Set OPL3 AM_VIB register of requested voice/operator */ 330 opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset); 331 opl3->command(opl3, opl3_reg, reg_val); 332 333 /* Set decreasing volume of higher notes */ 334 reg_val = (voice->scale_level << 6) & OPL3_KSL_MASK; 335 /* Set output volume */ 336 reg_val |= ~voice->volume & OPL3_TOTAL_LEVEL_MASK; 337 338 /* Set OPL3 KSL_LEVEL register of requested voice/operator */ 339 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset); 340 opl3->command(opl3, opl3_reg, reg_val); 341 342 /* Set attack phase level */ 343 reg_val = (voice->attack << 4) & OPL3_ATTACK_MASK; 344 /* Set decay phase level */ 345 reg_val |= voice->decay & OPL3_DECAY_MASK; 346 347 /* Set OPL3 ATTACK_DECAY register of requested voice/operator */ 348 opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset); 349 opl3->command(opl3, opl3_reg, reg_val); 350 351 /* Set sustain phase level */ 352 reg_val = (voice->sustain << 4) & OPL3_SUSTAIN_MASK; 353 /* Set release phase level */ 354 reg_val |= voice->release & OPL3_RELEASE_MASK; 355 356 /* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */ 357 opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset); 358 opl3->command(opl3, opl3_reg, reg_val); 359 360 /* Set inter-operator feedback */ 361 reg_val = (voice->feedback << 1) & OPL3_FEEDBACK_MASK; 362 /* Set inter-operator connection */ 363 if (voice->connection) 364 reg_val |= OPL3_CONNECTION_BIT; 365 /* OPL-3 only */ 366 if (opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) { 367 if (voice->left) 368 reg_val |= OPL3_VOICE_TO_LEFT; 369 if (voice->right) 370 reg_val |= OPL3_VOICE_TO_RIGHT; 371 } 372 /* Feedback/connection bits are applicable to voice */ 373 opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset); 374 opl3->command(opl3, opl3_reg, reg_val); 375 376 /* Select waveform */ 377 reg_val = voice->waveform & OPL3_WAVE_SELECT_MASK; 378 opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset); 379 opl3->command(opl3, opl3_reg, reg_val); 380 381 return 0; 382 } 383 384 static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params) 385 { 386 unsigned char reg_val; 387 388 reg_val = 0x00; 389 /* Set keyboard split method */ 390 if (params->kbd_split) 391 reg_val |= OPL3_KEYBOARD_SPLIT; 392 opl3->command(opl3, OPL3_LEFT | OPL3_REG_KBD_SPLIT, reg_val); 393 394 reg_val = 0x00; 395 /* Set amplitude modulation (tremolo) depth */ 396 if (params->am_depth) 397 reg_val |= OPL3_TREMOLO_DEPTH; 398 /* Set vibrato depth */ 399 if (params->vib_depth) 400 reg_val |= OPL3_VIBRATO_DEPTH; 401 /* Set percussion mode */ 402 if (params->rhythm) { 403 reg_val |= OPL3_PERCUSSION_ENABLE; 404 opl3->rhythm = 1; 405 } else { 406 opl3->rhythm = 0; 407 } 408 /* Play percussion instruments */ 409 if (params->bass) 410 reg_val |= OPL3_BASSDRUM_ON; 411 if (params->snare) 412 reg_val |= OPL3_SNAREDRUM_ON; 413 if (params->tomtom) 414 reg_val |= OPL3_TOMTOM_ON; 415 if (params->cymbal) 416 reg_val |= OPL3_CYMBAL_ON; 417 if (params->hihat) 418 reg_val |= OPL3_HIHAT_ON; 419 420 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, reg_val); 421 return 0; 422 } 423 424 static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode) 425 { 426 if ((mode == SNDRV_DM_FM_MODE_OPL3) && (opl3->hardware < OPL3_HW_OPL3)) 427 return -EINVAL; 428 429 opl3->fm_mode = mode; 430 if (opl3->hardware >= OPL3_HW_OPL3) 431 opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, 0x00); /* Clear 4-op connections */ 432 433 return 0; 434 } 435 436 static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection) 437 { 438 unsigned char reg_val; 439 440 /* OPL-3 only */ 441 if (opl3->fm_mode != SNDRV_DM_FM_MODE_OPL3) 442 return -EINVAL; 443 444 reg_val = connection & (OPL3_RIGHT_4OP_0 | OPL3_RIGHT_4OP_1 | OPL3_RIGHT_4OP_2 | 445 OPL3_LEFT_4OP_0 | OPL3_LEFT_4OP_1 | OPL3_LEFT_4OP_2); 446 /* Set 4-op connections */ 447 opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, reg_val); 448 449 return 0; 450 } 451 452