OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [sound/] [gus_card.c] - Rev 1626

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 * sound/gus_card.c
 *
 * Detection routine for the Gravis Ultrasound.
 */
/*
 * Copyright (C) by Hannu Savolainen 1993-1996
 *
 * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
 * for more info.
 */
#include <linux/config.h>
 
 
#include "sound_config.h"
 
#if defined(CONFIG_GUS)
 
#include "gus_hw.h"
 
void            gusintr (int irq, void *dev_id, struct pt_regs *dummy);
 
int             gus_base, gus_irq, gus_dma;
extern int      gus_wave_volume;
extern int      gus_pcm_volume;
extern int      have_gus_max;
int             gus_pnp_flag = 0;
 
int            *gus_osp;
 
void
attach_gus_card (struct address_info *hw_config)
{
  int             io_addr;
 
  gus_osp = hw_config->osp;
  snd_set_irq_handler (hw_config->irq, gusintr, "Gravis Ultrasound", hw_config->osp);
 
  if (gus_wave_detect (hw_config->io_base))	/*
						 * Try first the default
						 */
    {
      gus_wave_init (hw_config);
 
      request_region (hw_config->io_base, 16, "GUS");
      request_region (hw_config->io_base + 0x100, 12, "GUS");	/* 0x10c-> is MAX */
 
      if (sound_alloc_dma (hw_config->dma, "GUS"))
	printk ("gus_card.c: Can't allocate DMA channel\n");
      if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
	if (sound_alloc_dma (hw_config->dma2, "GUS(2)"))
	  printk ("gus_card.c: Can't allocate DMA channel2\n");
#ifdef CONFIG_MIDI
      gus_midi_init ();
#endif
      return;
    }
 
#ifndef EXCLUDE_GUS_IODETECT
 
  /*
   * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
   */
 
  for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
    if (io_addr != hw_config->io_base)	/*
					 * Already tested
					 */
      if (gus_wave_detect (io_addr))
	{
	  hw_config->io_base = io_addr;
 
	  printk (" WARNING! GUS found at %x, config was %x ", io_addr, hw_config->io_base);
	  gus_wave_init (hw_config);
	  request_region (io_addr, 16, "GUS");
	  request_region (io_addr + 0x100, 12, "GUS");	/* 0x10c-> is MAX */
	  if (sound_alloc_dma (hw_config->dma, "GUS"))
	    printk ("gus_card.c: Can't allocate DMA channel\n");
	  if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
	    if (sound_alloc_dma (hw_config->dma2, "GUS"))
	      printk ("gus_card.c: Can't allocate DMA channel2\n");
#ifdef CONFIG_MIDI
	  gus_midi_init ();
#endif
	  return;
	}
 
#endif
 
}
 
int
probe_gus (struct address_info *hw_config)
{
  int             io_addr, irq;
 
  gus_osp = hw_config->osp;
 
  if (hw_config->card_subtype == 1)
    gus_pnp_flag = 1;
 
  irq = hw_config->irq;
 
  if (hw_config->card_subtype == 0)	/* GUS/MAX/ACE */
    if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
	irq != 11 && irq != 12 && irq != 15)
      {
	printk ("GUS: Unsupported IRQ %d\n", irq);
	return 0;
      }
 
  if (check_region (hw_config->io_base, 16))
    printk ("GUS: I/O range conflict (1)\n");
  else if (check_region (hw_config->io_base + 0x100, 16))
    printk ("GUS: I/O range conflict (2)\n");
  else if (gus_wave_detect (hw_config->io_base))
    return 1;
 
#ifndef EXCLUDE_GUS_IODETECT
 
  /*
   * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
   */
 
  for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
    if (io_addr != hw_config->io_base)	/*
					 * Already tested
					 */
      if (!check_region (io_addr, 16))
	if (!check_region (io_addr + 0x100, 16))
	  if (gus_wave_detect (io_addr))
	    {
	      hw_config->io_base = io_addr;
	      return 1;
	    }
 
#endif
 
  return 0;
}
 
void
unload_gus (struct address_info *hw_config)
{
  DDB (printk ("unload_gus(%x)\n", hw_config->io_base));
 
  gus_wave_unload ();
 
  release_region (hw_config->io_base, 16);
  release_region (hw_config->io_base + 0x100, 12);	/* 0x10c-> is MAX */
  snd_release_irq (hw_config->irq);
 
  sound_free_dma (hw_config->dma);
 
  if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
    sound_free_dma (hw_config->dma2);
}
 
void
gusintr (int irq, void *dev_id, struct pt_regs *dummy)
{
  unsigned char   src;
  extern int      gus_timer_enabled;
 
  sti ();
 
#ifdef CONFIG_GUSMAX
  if (have_gus_max)
    ad1848_interrupt (irq, NULL, NULL);
#endif
 
  while (1)
    {
      if (!(src = inb (u_IrqStatus)))
	return;
 
      if (src & DMA_TC_IRQ)
	{
	  guswave_dma_irq ();
	}
 
      if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
	{
#ifdef CONFIG_MIDI
	  gus_midi_interrupt (0);
#endif
	}
 
      if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
	{
#ifdef CONFIG_SEQUENCER
	  if (gus_timer_enabled)
	    {
	      sound_timer_interrupt ();
	    }
 
	  gus_write8 (0x45, 0);	/* Ack IRQ */
	  gus_timer_command (4, 0x80);	/* Reset IRQ flags */
 
#else
	  gus_write8 (0x45, 0);	/* Stop timers */
#endif
	}
 
      if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
	{
	  gus_voice_irq ();
	}
    }
}
 
#endif
 
/*
 * Some extra code for the 16 bit sampling option
 */
#if defined(CONFIG_GUS16)
 
int
probe_gus_db16 (struct address_info *hw_config)
{
  return ad1848_detect (hw_config->io_base, NULL, hw_config->osp);
}
 
void
attach_gus_db16 (struct address_info *hw_config)
{
#ifdef CONFIG_GUS
  gus_pcm_volume = 100;
  gus_wave_volume = 90;
#endif
 
  ad1848_init ("GUS 16 bit sampling", hw_config->io_base,
	       hw_config->irq,
	       hw_config->dma,
	       hw_config->dma, 0,
	       hw_config->osp);
}
 
void
unload_gus_db16 (struct address_info *hw_config)
{
 
  ad1848_unload (hw_config->io_base,
		 hw_config->irq,
		 hw_config->dma,
		 hw_config->dma, 0);
}
#endif
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.