Beispiel #1
0
static int nd_3c59x_probe(void)
{
	struct netdev *nd = &net_dev_3com_3c59x;
	unsigned long pci_config_base;
	int i;

	pci_config_base = pci_lookup_vendor_device(0x10b7, 0x5900);
	if (!pci_config_base)
		pci_config_base = pci_lookup_vendor_device(0x10b7, 0x5950);
	if (!pci_config_base)
		pci_config_base = pci_lookup_vendor_device(0x10b7, 0x5951);
	if (!pci_config_base)
		pci_config_base = pci_lookup_vendor_device(0x10b7, 0x5952);

	if (pci_config_base) {
		nd->io_base = pci_read_config_long(pci_config_base, PCI_BASE0) & ~3;

		for (i = 0; i < 3; i++) {
			int addr;

			addr = eeprom_read(nd, i + 10);

			nd->hw_addr[i * 2] = addr >> 8;
			nd->hw_addr[i * 2 + 1] = addr;
		}
		eth_setup(nd);
	}

	return net_dev_3com_3c59x.io_base ? 0 : -1;
}
ULONG ahi_pci_read_config_long(UBYTE reg, APTR dev)
{
  return pci_read_config_long(reg, dev);
}
struct EMU10kxData*
AllocDriverData( struct pci_dev*    dev,
		 struct DriverBase* AHIsubBase )
#endif
{
  struct EMU10kxBase* EMU10kxBase = (struct EMU10kxBase*) AHIsubBase;
  struct EMU10kxData* dd;
  UWORD               command_word;

  // FIXME: This should be non-cachable, DMA-able memory
  dd = AllocVec( sizeof( *dd ), MEMF_PUBLIC | MEMF_CLEAR );

  if( dd == NULL )
  {
    Req( "Unable to allocate driver structure." );
    return NULL;
  }


  dd->ahisubbase = AHIsubBase;

  dd->interrupt.is_Node.ln_Type = INTERRUPT_NODE_TYPE;
  dd->interrupt.is_Node.ln_Pri  = 0;
  dd->interrupt.is_Node.ln_Name = (STRPTR) LibName;
  dd->interrupt.is_Code         = (void(*)(void)) &emu10kxinterrupt;
  dd->interrupt.is_Data         = (APTR) dd;

  dd->playback_interrupt.is_Node.ln_Type = INTERRUPT_NODE_TYPE;
  dd->playback_interrupt.is_Node.ln_Pri  = 0;
  dd->playback_interrupt.is_Node.ln_Name = (STRPTR) LibName;
  dd->playback_interrupt.is_Code         = (void(*)(void)) &playbackinterrupt;
  dd->playback_interrupt.is_Data         = (APTR) dd;

  dd->record_interrupt.is_Node.ln_Type = INTERRUPT_NODE_TYPE;
  dd->record_interrupt.is_Node.ln_Pri  = 0;
  dd->record_interrupt.is_Node.ln_Name = (STRPTR) LibName;
  dd->record_interrupt.is_Code         = (void(*)(void)) &recordinterrupt;
  dd->record_interrupt.is_Data         = (APTR) dd;
  
  dd->card.pci_dev = dev;

//  if( pci_set_dma_mask(dd->card.pci_dev, EMU10K1_DMA_MASK) )
//  {
//    printf( "Unable to set DMA mask for card." );
//    goto error;
//  }

  #ifdef __AMIGAOS4__
  command_word = dev->ReadConfigWord( PCI_COMMAND );  
  command_word |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
  dev->WriteConfigWord( PCI_COMMAND, command_word );
  #else
  command_word = pci_read_config_word( PCI_COMMAND, dd->card.pci_dev );
  command_word |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
  pci_write_config_word( PCI_COMMAND, command_word, dd->card.pci_dev );
  #endif

  dd->pci_master_enabled = TRUE;

  // FIXME: How about latency/pcibios_set_master()??

  #ifdef __AMIGAOS4__
  dd->card.iobase  = dev->GetResourceRange(0)->BaseAddress;
  dd->card.length  = ~( dev->GetResourceRange(0)->Size & PCI_BASE_ADDRESS_IO_MASK );
  dd->card.irq     = dev->MapInterrupt();
  dd->card.chiprev = dev->ReadConfigByte( PCI_REVISION_ID);
  dd->card.model   = dev->ReadConfigWord( PCI_SUBSYSTEM_ID);
  dd->card.is_audigy = ( dev->ReadConfigWord( PCI_DEVICE_ID) == PCI_DEVICE_ID_CREATIVE_AUDIGY );
  dd->card.is_aps   = ( dev->ReadConfigLong( PCI_SUBSYSTEM_VENDOR_ID)
		       == EMU_APS_SUBID );

  dev->OutLong(dd->card.iobase + IPR, 0xffffffff);
  dev->OutLong(dd->card.iobase + INTE, 0);

  AddIntServer(dev->MapInterrupt(), &dd->interrupt );
  #else
  dd->card.iobase  = dev->base_address[ 0 ];
  dd->card.length  = ~( dev->base_size[ 0 ] & PCI_BASE_ADDRESS_IO_MASK );
  dd->card.irq     = dev->irq;
  dd->card.chiprev = pci_read_config_byte( PCI_REVISION_ID, dd->card.pci_dev );
  dd->card.model   = pci_read_config_word( PCI_SUBSYSTEM_ID, dd->card.pci_dev );
  dd->card.is_audigy = ( dev->device == PCI_DEVICE_ID_CREATIVE_AUDIGY );
  dd->card.is_aps   = ( pci_read_config_long( PCI_SUBSYSTEM_VENDOR_ID,
					     dd->card.pci_dev )
		       == EMU_APS_SUBID );

  pci_add_intserver( &dd->interrupt, dd->card.pci_dev );
  #endif

  dd->interrupt_added = TRUE;

  /* Initialize chip */
  if( emu10k1_init( &dd->card ) < 0 )
  {
    Req( "Unable to initialize EMU10kx subsystem.");
    return NULL;
  }

  dd->emu10k1_initialized = TRUE;

    
  /* Initialize mixer */

  emu10k1_writeac97( &dd->card, AC97_RESET, 0L);

  Delay( 1 );

  if (emu10k1_readac97( &dd->card, AC97_RESET ) & 0x8000) {
    Req( "ac97 codec not present.");
    return NULL;
  }


  dd->input          = 0;
  dd->output         = 0;
  dd->monitor_volume = Linear2MixerGain( 0, &dd->monitor_volume_bits );
  dd->input_gain     = Linear2RecordGain( 0x10000, &dd->input_gain_bits );
  dd->output_volume  = Linear2MixerGain( 0x10000, &dd->output_volume_bits );

  // No attenuation and natural tone for all outputs
  emu10k1_writeac97( &dd->card, AC97_MASTER_VOL_STEREO, 0x0000 );
  emu10k1_writeac97( &dd->card, AC97_HEADPHONE_VOL,     0x0000 );
  emu10k1_writeac97( &dd->card, AC97_MASTER_VOL_MONO,   0x0000 );
  emu10k1_writeac97( &dd->card, AC97_MASTER_TONE,       0x0f0f );

  emu10k1_writeac97( &dd->card, AC97_RECORD_GAIN,       0x0000 );
  emu10k1_writeac97( &dd->card, AC97_RECORD_SELECT,     InputBits[ 0 ] );

  emu10k1_writeac97( &dd->card, AC97_PCMOUT_VOL,        0x0808 );
  emu10k1_writeac97( &dd->card, AC97_PCBEEP_VOL,        0x0000 );

  emu10k1_writeac97( &dd->card, AC97_LINEIN_VOL,        0x0808 );
  emu10k1_writeac97( &dd->card, AC97_MIC_VOL,           AC97_MUTE | 0x0008 );
  emu10k1_writeac97( &dd->card, AC97_CD_VOL,            0x0808 );
  emu10k1_writeac97( &dd->card, AC97_AUX_VOL,           0x0808 );
  emu10k1_writeac97( &dd->card, AC97_PHONE_VOL,         0x0008 );
  emu10k1_writeac97( &dd->card, AC97_VIDEO_VOL,         0x0808 );


  if (emu10k1_readac97( &dd->card, AC97_EXTENDED_ID ) & 0x0080 )
  {
    sblive_writeptr( &dd->card, AC97SLOT, 0, AC97SLOT_CNTR | AC97SLOT_LFE);
    emu10k1_writeac97( &dd->card, AC97_SURROUND_MASTER, 0x0 );
  }
  
  return dd;
}