This source file includes following definitions.
- pas_read
 
- pas_write
 
- pas2_msg
 
- pasintr
 
- pas_set_intr
 
- pas_remove_intr
 
- config_pas_hw
 
- detect_pas_hw
 
- attach_pas_card
 
- probe_pas
 
   1 #define _PAS2_CARD_C_
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 #include "sound_config.h"
  32 
  33 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PAS)
  34 
  35 #define DEFINE_TRANSLATIONS
  36 #include "pas.h"
  37 
  38 
  39 
  40 
  41 
  42 
  43 int             translat_code;
  44 static int      pas_intr_mask = 0;
  45 static int      pas_irq = 0;
  46 
  47 static char     pas_model;
  48 static char    *pas_model_names[] =
  49 {"", "Pro AudioSpectrum+", "CDPC", "Pro AudioSpectrum 16", "Pro AudioSpectrum 16D"};
  50 
  51 
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 
  60 
  61 unsigned char
  62 pas_read (int ioaddr)
     
  63 {
  64   return INB (ioaddr ^ translat_code);
  65 }
  66 
  67 void
  68 pas_write (unsigned char data, int ioaddr)
     
  69 {
  70   OUTB (data, ioaddr ^ translat_code);
  71 }
  72 
  73 void
  74 pas2_msg (char *foo)
     
  75 {
  76   printk ("    PAS2: %s.\n", foo);
  77 }
  78 
  79 
  80 
  81 void
  82 pasintr (int unused)
     
  83 {
  84   int             status;
  85 
  86   status = pas_read (INTERRUPT_STATUS);
  87   pas_write (status, INTERRUPT_STATUS); 
  88 
  89 
  90 
  91   if (status & I_S_PCM_SAMPLE_BUFFER_IRQ)
  92     {
  93 #ifndef EXCLUDE_AUDIO
  94       pas_pcm_interrupt (status, 1);
  95 #endif
  96       status &= ~I_S_PCM_SAMPLE_BUFFER_IRQ;
  97     }
  98   if (status & I_S_MIDI_IRQ)
  99     {
 100 #ifndef EXCLUDE_MIDI
 101 #ifdef EXCLUDE_PRO_MIDI
 102       pas_midi_interrupt ();
 103 #endif
 104 #endif
 105       status &= ~I_S_MIDI_IRQ;
 106     }
 107 
 108 }
 109 
 110 int
 111 pas_set_intr (int mask)
     
 112 {
 113   int             err;
 114 
 115   if (!mask)
 116     return 0;
 117 
 118   if (!pas_intr_mask)
 119     {
 120       if ((err = snd_set_irq_handler (pas_irq, pasintr)) < 0)
 121         return err;
 122     }
 123   pas_intr_mask |= mask;
 124 
 125   pas_write (pas_intr_mask, INTERRUPT_MASK);
 126   return 0;
 127 }
 128 
 129 int
 130 pas_remove_intr (int mask)
     
 131 {
 132   if (!mask)
 133     return 0;
 134 
 135   pas_intr_mask &= ~mask;
 136   pas_write (pas_intr_mask, INTERRUPT_MASK);
 137 
 138   if (!pas_intr_mask)
 139     {
 140       snd_release_irq (pas_irq);
 141     }
 142   return 0;
 143 }
 144 
 145 
 146 
 147 
 148 
 149 int
 150 config_pas_hw (struct address_info *hw_config)
     
 151 {
 152   char            ok = 1;
 153   unsigned        int_ptrs;     
 154 
 155   pas_irq = hw_config->irq;
 156 
 157   pas_write (0x00, INTERRUPT_MASK);
 158 
 159   pas_write (0x36, SAMPLE_COUNTER_CONTROL);     
 160 
 161 
 162 
 163 
 164   pas_write (0x36, SAMPLE_RATE_TIMER);  
 165 
 166 
 167   pas_write (0, SAMPLE_RATE_TIMER);
 168 
 169   pas_write (0x74, SAMPLE_COUNTER_CONTROL);     
 170 
 171 
 172 
 173 
 174   pas_write (0x74, SAMPLE_BUFFER_COUNTER);      
 175 
 176 
 177 
 178   pas_write (0, SAMPLE_BUFFER_COUNTER);
 179 
 180   pas_write (F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER | F_F_MIXER_UNMUTE | 1, FILTER_FREQUENCY);
 181   pas_write (P_C_PCM_DMA_ENABLE | P_C_PCM_MONO | P_C_PCM_DAC_MODE | P_C_MIXER_CROSS_L_TO_L | P_C_MIXER_CROSS_R_TO_R, PCM_CONTROL);
 182   pas_write (S_M_PCM_RESET | S_M_FM_RESET | S_M_SB_RESET | S_M_MIXER_RESET      
 183 
 184 
 185  , SERIAL_MIXER);
 186 
 187   pas_write (I_C_1_BOOT_RESET_ENABLE, IO_CONFIGURATION_1);
 188 
 189   if (pas_irq < 0 || pas_irq > 15)
 190     {
 191       printk ("PAS2: Invalid IRQ %d", pas_irq);
 192       ok = 0;
 193     }
 194   else
 195     {
 196       int_ptrs = pas_read (IO_CONFIGURATION_3);
 197       int_ptrs |= I_C_3_PCM_IRQ_translate[pas_irq] & 0xf;
 198       pas_write (int_ptrs, IO_CONFIGURATION_3);
 199       if (!I_C_3_PCM_IRQ_translate[pas_irq])
 200         {
 201           printk ("PAS2: Invalid IRQ %d", pas_irq);
 202           ok = 0;
 203         }
 204     }
 205 
 206   if (hw_config->dma < 0 || hw_config->dma > 7)
 207     {
 208       printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
 209       ok = 0;
 210     }
 211   else
 212     {
 213       pas_write (I_C_2_PCM_DMA_translate[hw_config->dma], IO_CONFIGURATION_2);
 214       if (!I_C_2_PCM_DMA_translate[hw_config->dma])
 215         {
 216           printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
 217           ok = 0;
 218         }
 219     }
 220 
 221   
 222 
 223 
 224 
 225 #ifdef SYMPHONY_PAS
 226   OUTB (0x05, 0xa8);
 227   OUTB (0x60, 0xa9);
 228 #endif
 229 
 230 #ifdef BROKEN_BUS_CLOCK
 231   pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND | S_C_1_FM_EMULATE_CLOCK, SYSTEM_CONFIGURATION_1);
 232 #else
 233   
 234 
 235 
 236   pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND, SYSTEM_CONFIGURATION_1);
 237 #endif
 238   pas_write (0x18, SYSTEM_CONFIGURATION_3);     
 239 
 240 
 241 
 242   pas_write (F_F_MIXER_UNMUTE | 0x01, FILTER_FREQUENCY);        
 243 
 244 
 245 
 246 
 247 
 248 
 249 
 250 
 251   if (pas_model == PAS_16 || pas_model == PAS_16D)
 252     pas_write (8, PRESCALE_DIVIDER);
 253   else
 254     pas_write (0, PRESCALE_DIVIDER);
 255 
 256   pas_write (P_M_MV508_ADDRESS | 5, PARALLEL_MIXER);
 257   pas_write (5, PARALLEL_MIXER);
 258 
 259 #if !defined(EXCLUDE_SB_EMULATION) || !defined(EXCLUDE_SB)
 260 
 261   {
 262     struct address_info *sb_config;
 263 
 264     if ((sb_config = sound_getconf (SNDCARD_SB)))
 265       {
 266         unsigned char   irq_dma;
 267 
 268         
 269 
 270 
 271         
 272 
 273 
 274         
 275 
 276 
 277         pas_write (0x02, COMPATIBILITY_ENABLE);
 278 
 279         
 280 
 281 
 282         pas_write ((sb_config->io_base >> 4) & 0x0f, EMULATION_ADDRESS);
 283 
 284         if (!E_C_SB_DMA_translate[sb_config->dma])
 285           printk ("\n\nPAS16 Warning: Invalid SB DMA %d\n\n",
 286                   sb_config->dma);
 287 
 288         if (!E_C_SB_IRQ_translate[sb_config->irq])
 289           printk ("\n\nPAS16 Warning: Invalid SB IRQ %d\n\n",
 290                   sb_config->irq);
 291 
 292         irq_dma = E_C_SB_DMA_translate[sb_config->dma] |
 293           E_C_SB_IRQ_translate[sb_config->irq];
 294 
 295         pas_write (irq_dma, EMULATION_CONFIGURATION);
 296       }
 297   }
 298 #endif
 299 
 300   if (!ok)
 301     pas2_msg ("Driver not enabled");
 302 
 303   return ok;
 304 }
 305 
 306 int
 307 detect_pas_hw (struct address_info *hw_config)
     
 308 {
 309   unsigned char   board_id, foo;
 310 
 311   
 312 
 313 
 314 
 315 
 316 
 317 
 318   OUTB (0xBC, MASTER_DECODE);   
 319 
 320 
 321   OUTB (hw_config->io_base >> 2, MASTER_DECODE);        
 322 
 323 
 324   translat_code = PAS_DEFAULT_BASE ^ hw_config->io_base;
 325   pas_write (1, WAIT_STATE);    
 326 
 327 
 328 
 329   board_id = pas_read (INTERRUPT_MASK);
 330 
 331   if (board_id == 0xff)
 332     return 0;
 333 
 334   
 335 
 336 
 337 
 338 
 339 
 340   foo = board_id ^ 0xe0;
 341 
 342   pas_write (foo, INTERRUPT_MASK);
 343   foo = INB (INTERRUPT_MASK);
 344   pas_write (board_id, INTERRUPT_MASK);
 345 
 346   if (board_id != foo)          
 347 
 348 
 349     return 0;
 350 
 351   pas_model = O_M_1_to_card[pas_read (OPERATION_MODE_1) & 0x0f];
 352 
 353   return pas_model;
 354 }
 355 
 356 long
 357 attach_pas_card (long mem_start, struct address_info *hw_config)
     
 358 {
 359   pas_irq = hw_config->irq;
 360 
 361   if (detect_pas_hw (hw_config))
 362     {
 363 
 364       if ((pas_model = O_M_1_to_card[pas_read (OPERATION_MODE_1) & 0x0f]))
 365         {
 366           printk (" <%s rev %d>", pas_model_names[(int) pas_model], pas_read (BOARD_REV_ID));
 367         }
 368 
 369       if (config_pas_hw (hw_config))
 370         {
 371 
 372 #ifndef EXCLUDE_AUDIO
 373           mem_start = pas_pcm_init (mem_start, hw_config);
 374 #endif
 375 
 376 #if !defined(EXCLUDE_SB_EMULATION) && !defined(EXCLUDE_SB)
 377 
 378           sb_dsp_disable_midi ();       
 379 
 380 
 381 
 382 #endif
 383 
 384 #ifndef EXCLUDE_YM3812
 385           enable_opl3_mode (0x388, 0x38a, 0);
 386 #endif
 387 
 388 #ifndef EXCLUDE_MIDI
 389 #ifdef EXCLUDE_PRO_MIDI
 390           mem_start = pas_midi_init (mem_start);
 391 #endif
 392 #endif
 393 
 394           pas_init_mixer ();
 395         }
 396     }
 397 
 398   return mem_start;
 399 }
 400 
 401 int
 402 probe_pas (struct address_info *hw_config)
     
 403 {
 404   return detect_pas_hw (hw_config);
 405 }
 406 
 407 #endif