示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
/*
 * 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);
}
示例#5
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);
}
示例#6
0
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);
}
示例#7
0
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;
}
示例#8
0
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);
}
示例#9
0
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);
}
示例#10
0
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;
}
示例#11
0
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;
}
示例#12
0
文件: uart6850.c 项目: metacore/spin
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;
}
示例#13
0
文件: uart6850.c 项目: metacore/spin
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);
}