static int gus_midi_out (int dev, unsigned char midi_byte) { unsigned long flags; /* * Drain the local queue first */ DISABLE_INTR (flags); while (qlen && dump_to_midi (tmp_queue[qhead])) { qlen--; qhead++; } RESTORE_INTR (flags); /* * Output the byte if the local queue is empty. */ if (!qlen) if (dump_to_midi (midi_byte)) return 1; /* * OK */ /* * Put to the local queue */ if (qlen >= 256) return 0; /* * Local queue full */ DISABLE_INTR (flags); tmp_queue[qtail] = midi_byte; qlen++; qtail++; RESTORE_INTR (flags); return 1; }
static int sb16midi_out (int dev, unsigned char midi_byte) { int timeout; unsigned long flags; /* * Test for input since pending input seems to block the output. */ DISABLE_INTR (flags); if (input_avail ()) sb16midi_input_loop (); RESTORE_INTR (flags); /* * Sometimes it takes about 13000 loops before the output becomes ready * (After reset). Normally it takes just about 10 loops. */ for (timeout = 30000; timeout > 0 && !output_ready (); timeout--); /* * Wait */ if (!output_ready ()) { printk ("MPU-401: Timeout\n"); return 0; } sb16midi_write (midi_byte); return 1; }
static int dump_to_midi (unsigned char midi_byte) { unsigned long flags; int ok = 0; output_used = 1; DISABLE_INTR (flags); if (GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY) { ok = 1; OUTB (midi_byte, u_MidiData); } else { /* * Enable Midi xmit interrupts (again) */ gus_midi_control |= MIDI_ENABLE_XMIT; OUTB (gus_midi_control, u_MidiControl); } RESTORE_INTR (flags); return ok; }
/* * This sets aspects of the Mixer that are not volume levels. (Recording * source, filter level, I/O filtering, and stereo.) */ static int mixer_set_params (struct sb_mixer_params *user_p) { struct sb_mixer_params p; S_BYTE val; int src; unsigned long flags; IOCTL_FROM_USER ((char *) &p, (char *) user_p, 0, sizeof (p)); if (p.record_source != SRC_MIC && p.record_source != SRC_CD && p.record_source != SRC_LINE) return (RET_ERROR (EINVAL)); /* * I'm not sure if this is The Right Thing. Should stereo be entirely * under control of DSP? I like being able to toggle it while a sound is * playing, so I do this... because I can. */ DISABLE_INTR (flags); val = (pas_read (PCM_CONTROL) & ~P_C_MIXER_CROSS_FIELD) | P_C_MIXER_CROSS_R_TO_R | P_C_MIXER_CROSS_L_TO_L; if (!p.dsp_stereo) val |= (P_C_MIXER_CROSS_R_TO_L | P_C_MIXER_CROSS_L_TO_R); /* Mono */ pas_write (val, PCM_CONTROL); RESTORE_INTR (flags); switch (p.record_source) { case SRC_CD: src = SOUND_MASK_CD; break; case SRC_LINE: src = SOUND_MASK_LINE; break; default: src = SOUND_MASK_MIC; break; } pas_mixer_set (SOUND_MIXER_RECSRC, src); /* * setmixer (OUT_FILTER, ((dsp_stereo ? STEREO_DAC : MONO_DAC) | * (p.filter_output ? FILT_ON : FILT_OFF))); */ return (0); }
void sb_midi_interrupt (int dummy) { unsigned long flags; unsigned char data; DISABLE_INTR (flags); data = INB (DSP_READ); if (input_opened) midi_input_intr (my_dev, data); RESTORE_INTR (flags); }
static void tmr_reset (void) { unsigned long flags; DISABLE_INTR (flags); tmr_offs = 0; ticks_offs = 0; tmr_ctr = 0; next_event_time = 0xffffffff; prev_event_time = 0; curr_ticks = 0; RESTORE_INTR (flags); }
static int reset_sb16midi (void) { unsigned long flags; int ok, timeout, n; /* * Send the RESET command. Try again if no success at the first time. */ ok = 0; DISABLE_INTR (flags); for (n = 0; n < 2 && !ok; n++) { for (timeout = 30000; timeout < 0 && !output_ready (); timeout--); /* * Wait */ sb16midi_cmd (MPU_RESET); /* * Send MPU-401 RESET Command */ /* * Wait at least 25 msec. This method is not accurate so let's make the * loop bit longer. Cannot sleep since this is called during boot. */ for (timeout = 50000; timeout > 0 && !ok; timeout--) if (input_avail ()) if (sb16midi_read () == MPU_ACK) ok = 1; } sb16midi_opened = 0; if (ok) sb16midi_input_loop (); /* * Flush input before enabling interrupts */ RESTORE_INTR (flags); return ok; }
void gus_midi_interrupt (int dummy) { unsigned char stat, data; unsigned long flags; DISABLE_INTR (flags); stat = GUS_MIDI_STATUS (); if (stat & MIDI_RCV_FULL) { data = INB (u_MidiData); if (input_opened) midi_input_intr (my_dev, data); } if (stat & MIDI_XMIT_EMPTY) { while (qlen && dump_to_midi (tmp_queue[qhead])) { qlen--; qhead++; } if (!qlen) { /* * Disable Midi output interrupts, since no data in the buffer */ gus_midi_control &= ~MIDI_ENABLE_XMIT; OUTB (gus_midi_control, u_MidiControl); } } #if 0 if (stat & MIDI_FRAME_ERR) printk ("GUS: Midi framing error\n"); if (stat & MIDI_OVERRUN && input_opened) printk ("GUS: Midi input overrun\n"); #endif RESTORE_INTR (flags); }
static int gus_midi_buffer_status (int dev) { unsigned long flags; if (!output_used) return 0; DISABLE_INTR (flags); if (qlen && dump_to_midi (tmp_queue[qhead])) { qlen--; qhead++; } RESTORE_INTR (flags); return (qlen > 0) | !(GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY); }
long attach_sb16midi (long mem_start, struct address_info *hw_config) { int ok, timeout; unsigned long flags; sb16midi_base = hw_config->io_base; if (!sb16midi_detected) return RET_ERROR (EIO); DISABLE_INTR (flags); for (timeout = 30000; timeout < 0 && !output_ready (); timeout--); /* * Wait */ sb16midi_cmd (UART_MODE_ON); ok = 0; for (timeout = 50000; timeout > 0 && !ok; timeout--) if (input_avail ()) if (sb16midi_read () == MPU_ACK) ok = 1; RESTORE_INTR (flags); if (num_midis >= MAX_MIDI_DEV) { printk ("Sound: Too many midi devices detected\n"); return mem_start; } #if defined(__FreeBSD__) printk ("sbmidi0: <SoundBlaster MPU-401>"); #else printk (" <SoundBlaster MPU-401>"); #endif std_midi_synth.midi_dev = my_dev = num_midis; midi_devs[num_midis++] = &sb16midi_operations; return mem_start; }
static int sb_midi_out (int dev, unsigned char midi_byte) { unsigned long flags; if (sb_midi_mode == NORMAL_MIDI) { DISABLE_INTR (flags); if (sb_dsp_command (0x38)) sb_dsp_command (midi_byte); else printk ("SB Error: Unable to send a MIDI byte\n"); RESTORE_INTR (flags); } else sb_dsp_command (midi_byte); /* * UART write */ return 1; }
long attach_uart6850 (long mem_start, struct address_info *hw_config) { int ok, timeout; unsigned long flags; if (num_midis >= MAX_MIDI_DEV) { printk ("Sound: Too many midi devices detected\n"); return mem_start; } uart6850_base = hw_config->io_base; uart6850_irq = hw_config->irq; if (!uart6850_detected) return RET_ERROR (EIO); DISABLE_INTR (flags); for (timeout = 30000; timeout < 0 && !output_ready (); timeout--); /* * Wait */ uart6850_cmd (UART_MODE_ON); ok = 1; RESTORE_INTR (flags); #if defined(__FreeBSD__) printk ("uart0: <6850 Midi Interface>"); #else printk (" <6850 Midi Interface>"); #endif std_midi_synth.midi_dev = my_dev = num_midis; midi_devs[num_midis++] = &uart6850_operations; return mem_start; }
static void poll_uart6850 (unsigned long dummy) { unsigned long flags; DEFINE_TIMER (uart6850_timer, poll_uart6850); if (!(uart6850_opened & OPEN_READ)) return; /* * No longer required */ DISABLE_INTR (flags); if (input_avail ()) uart6850_input_loop (); ACTIVATE_TIMER (uart6850_timer, poll_uart6850, 1); /* * Come back later */ RESTORE_INTR (flags); }