alsa.audio: Furter work on skeleton
[AROS.git] / workbench / devs / AHI / Drivers / Envy24HT / misc.c
blob7425312b0f88875c891f5ee6bcce8bd08013977a
1 /*
2 Copyright © 2005-2013, Davy Wentzler. All rights reserved.
3 $Id$
4 */
6 #include <exec/memory.h>
7 #include <proto/expansion.h>
9 #include <proto/dos.h>
10 #include "pci_wrapper.h"
12 #ifdef __amigaos4__
13 #include "library_card.h"
14 #elif __MORPHOS__
15 #include "library_mos.h"
16 #else
17 #include "library.h"
18 #endif
19 #include "regs.h"
20 #include "interrupt.h"
21 #include "misc.h"
22 #include "ak4114.h"
23 #include "DriverData.h"
24 #include "Revo51.h"
27 /* Global in Card.c */
28 extern const UWORD InputBits[];
29 extern struct DOSIFace *IDOS;
30 extern struct MMUIFace* IMMU;
32 struct Device *TimerBase = NULL;
33 struct timerequest *TimerIO = NULL;
34 struct MsgPort *replymp = NULL;
35 unsigned long Dirs[7] = {0x005FFFFF, 0x005FFFFF, 0x001EFFF7, 0x004000FA, 0x004000FA, 0x007FFF9F, 0x00FFFFFF};
37 /* Public functions in main.c */
38 int card_init(struct CardData *card);
39 void card_cleanup(struct CardData *card);
40 int aureon_ac97_init(struct CardData *card, unsigned long base);
41 void AddResetHandler(struct CardData *card);
43 #ifdef __MORPHOS__
44 extern struct DriverBase* AHIsubBase;
45 #endif
47 static unsigned char inits_ak4358[] = {
48 0x01, 0x02, /* 1: reset + soft mute */
50 0x00, 0x87, // I2S + unreset (used to be 0F)
52 0x01, 0x01, // unreset + soft mute off
53 0x02, 0x4F, /* 2: DA's power up, normal speed, RSTN#=0 */
54 0x03, 0x01, /* 3: de-emphasis 44.1 */
56 0x04, 0xFF, /* 4: LOUT1 volume (PCM) */
57 0x05, 0xFF, /* 5: ROUT1 volume */
59 0x06, 0x00, /* 6: LOUT2 volume (analogue in monitor, doesn't work) */
60 0x07, 0x00, /* 7: ROUT2 volume */
62 0x08, 0xFF, /* 8: LOUT3 volume (dig out monitor, use it as analogue out) */
63 0x09, 0xFF, /* 9: ROUT3 volume */
65 0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
67 0x0b, 0xFF, /* b: LOUT4 volume */
68 0x0c, 0xFF, /* c: ROUT4 volume */
70 0x0d, 0xFF, // DFZ
71 0x0E, 0x00,
72 0x0F, 0x00,
73 0xff, 0xff
76 void revo_i2s_mclk_changed(struct CardData *card)
78 struct PCIDevice *dev = card->pci_dev;
80 /* assert PRST# to converters; MT05 bit 7 */
81 OUTBYTE(card->mtbase + MT_AC97_CMD_STATUS, INBYTE(card->mtbase + MT_AC97_CMD_STATUS) | 0x80);
82 MicroDelay(5);
83 /* deassert PRST# */
84 OUTBYTE(card->mtbase + MT_AC97_CMD_STATUS, INBYTE(card->mtbase + MT_AC97_CMD_STATUS) & ~0x80);
88 void ClearMask8(struct CardData *card, unsigned long base, unsigned char reg, unsigned char mask)
90 UBYTE tmp;
92 tmp = INBYTE(base + reg);
93 tmp &= ~mask;
94 OUTBYTE(base + reg, tmp);
98 void WriteMask8(struct CardData *card, unsigned long base, unsigned char reg, unsigned char mask)
100 UBYTE tmp;
102 tmp = INBYTE(base + reg);
103 tmp |= mask;
104 OUTBYTE(base + reg, tmp);
108 void WritePartialMask(struct CardData *card, unsigned long base, unsigned char reg, unsigned long shift, unsigned long mask, unsigned long val)
110 ULONG tmp;
112 tmp = INLONG(base + reg);
113 tmp &= ~(mask << shift);
114 tmp |= val << shift;
115 OUTLONG(base + reg, tmp);
119 void SetGPIOData(struct CardData *card, unsigned long base, unsigned long data)
121 OUTWORD(base + CCS_GPIO_DATA, data & 0xFFFF);
122 OUTBYTE(base + CCS_GPIO_DATA2, (data & (0xFF0000)) >> 16);
123 INWORD(base + CCS_GPIO_DATA); /* dummy read for pci-posting */
126 void SetGPIOMask(struct CardData *card, unsigned long base, unsigned long data)
128 OUTWORD(base + CCS_GPIO_MASK, data & 0xFFFF);
129 OUTBYTE(base + CCS_GPIO_MASK2, (data & (0xFF0000)) >> 16);
130 INWORD(base + CCS_GPIO_MASK); /* dummy read for pci-posting */
134 void SaveGPIO(struct PCIDevice *dev, struct CardData* card)
136 card->SavedDir = INLONG(card->iobase + CCS_GPIO_DIR) & 0x7FFFFF;
137 card->SavedMask = INWORD(card->iobase + CCS_GPIO_MASK);
141 void RestoreGPIO(struct PCIDevice *dev, struct CardData* card)
143 OUTLONG(card->iobase + CCS_GPIO_DIR, card->SavedDir);
144 OUTWORD(card->iobase + CCS_GPIO_MASK, card->SavedMask);
148 unsigned long GetGPIOData(struct CardData *card, unsigned long base)
150 unsigned long data;
152 data = (unsigned long) INBYTE(base + CCS_GPIO_DATA2);
153 data = (data << 16) | INWORD(base + CCS_GPIO_DATA);
154 return data;
158 void SetGPIODir(struct PCIDevice *dev, struct CardData* card, unsigned long data)
160 OUTLONG(card->iobase + CCS_GPIO_DIR, data);
161 INWORD(card->iobase + CCS_GPIO_DIR);
165 unsigned char ReadI2C(struct PCIDevice *dev, struct CardData *card, unsigned char addr)
167 unsigned char val;
168 int counter = 0;
170 MicroDelay(1);
171 OUTBYTE(card->iobase + CCS_I2C_ADDR, addr);
172 OUTBYTE(card->iobase + CCS_I2C_DEV_ADDRESS, 0xA0);
174 while ((INBYTE(card->iobase + CCS_I2C_STATUS) & CCS_I2C_BUSY) && counter < 10000)
176 MicroDelay(1);
177 counter++;
180 if (counter == 10000)
182 bug("Error reading from I2C\n");
185 val = INBYTE(card->iobase + CCS_I2C_DATA);
187 return val;
191 void WriteI2C(struct PCIDevice *dev, struct CardData *card, unsigned chip_address, unsigned char reg, unsigned char data)
193 int counter = 0;
195 while ((INBYTE(card->iobase + CCS_I2C_STATUS) & CCS_I2C_BUSY) && counter < 10000)
197 MicroDelay(1);
198 counter++;
201 if (counter == 10000)
203 bug("Error reading from I2C (for write)\n");
205 counter = 0;
207 OUTBYTE(card->iobase + CCS_I2C_ADDR, reg);
208 OUTBYTE(card->iobase + CCS_I2C_DATA, data);
210 while ((INBYTE(card->iobase + CCS_I2C_STATUS) & CCS_I2C_BUSY) && counter < 10000)
212 counter++;
215 if (counter == 10000)
217 bug("Error reading from I2C (for write 2)\n");
220 OUTBYTE(card->iobase + CCS_I2C_DEV_ADDRESS, chip_address | CCS_ADDRESS_WRITE);
224 void update_spdif_bits(struct CardData *card, unsigned short val)
226 unsigned char cbit, disabled;
227 struct PCIDevice *dev = card->pci_dev;
229 cbit = INBYTE(card->iobase + CCS_SPDIF_CONFIG); // get S/PDIF status
230 disabled = cbit & ~CCS_SPDIF_INTEGRATED; // status without enabled bit set
232 if (cbit != disabled) // it was enabled
233 OUTBYTE(card->iobase + CCS_SPDIF_CONFIG, disabled); // so, disable it
235 OUTWORD(card->mtbase + MT_SPDIF_TRANSMIT, val); // now we can safely write to the SPDIF control reg
237 if (cbit != disabled)
238 OUTBYTE(card->iobase + CCS_SPDIF_CONFIG, cbit); // restore
240 OUTWORD(card->mtbase + MT_SPDIF_TRANSMIT, val); // twice???
244 void update_spdif_rate(struct CardData *card, unsigned short rate)
246 unsigned short val, nval;
247 unsigned long flags;
248 struct PCIDevice *dev = card->pci_dev;
250 nval = val = INWORD(card->mtbase + MT_SPDIF_TRANSMIT);
251 nval &= ~(7 << 12);
252 switch (rate) {
253 case 44100: break;
254 case 48000: nval |= 2 << 12; break;
255 case 32000: nval |= 3 << 12; break;
257 if (val != nval)
258 update_spdif_bits(card, nval);
262 static void aureon_spi_write(struct CardData *card, unsigned long base, unsigned int cs, unsigned int data, int bits)
264 struct PCIDevice *dev = card->pci_dev;
265 unsigned int tmp;
266 int i;
268 tmp = GetGPIOData(card, base);
270 if (card->SubType == PHASE28)
271 SetGPIOMask(card, base, ~(AUREON_WM_RW|AUREON_WM_DATA|AUREON_WM_CLK|AUREON_WM_CS));
272 else
273 SetGPIOMask(card, base, ~(AUREON_WM_RW|AUREON_WM_DATA|AUREON_WM_CLK|AUREON_WM_CS | AUREON_CS8415_CS));
275 SetGPIOMask(card, base, 0);
277 tmp |= AUREON_WM_RW;
278 tmp &= ~cs;
279 SetGPIOData(card, base, tmp); // set CS low
280 MicroDelay(1);
283 for (i = bits - 1; i >= 0; i--) {
284 tmp &= ~AUREON_WM_CLK;
285 SetGPIOData(card, base, tmp);
286 MicroDelay(1);
287 if (data & (1 << i))
288 tmp |= AUREON_WM_DATA;
289 else
290 tmp &= ~AUREON_WM_DATA;
291 SetGPIOData(card, base, tmp);
292 MicroDelay(1);
293 tmp |= AUREON_WM_CLK;
294 SetGPIOData(card, base, tmp);
295 MicroDelay(1);
298 tmp &= ~AUREON_WM_CLK;
299 tmp |= cs;
300 SetGPIOData(card, base, tmp);
301 MicroDelay(1);
302 tmp |= AUREON_WM_CLK;
303 SetGPIOData(card, base, tmp);
304 MicroDelay(1);
308 static void aureon_ac97_write(struct CardData *card, unsigned long base, unsigned short reg, unsigned short val)
310 unsigned int tmp;
312 /* Send address to XILINX chip */
313 tmp = (GetGPIOData(card, base) & ~0xFF) | (reg & 0x7F);
314 SetGPIOData(card, base, tmp);
315 MicroDelay(10);
316 tmp |= AUREON_AC97_ADDR;
317 SetGPIOData(card, base, tmp);
318 MicroDelay(10);
319 tmp &= ~AUREON_AC97_ADDR;
320 SetGPIOData(card, base, tmp);
321 MicroDelay(10);
323 /* Send low-order byte to XILINX chip */
324 tmp &= ~AUREON_AC97_DATA_MASK;
325 tmp |= val & AUREON_AC97_DATA_MASK;
326 SetGPIOData(card, base, tmp);
327 MicroDelay(10);
328 tmp |= AUREON_AC97_DATA_LOW;
329 SetGPIOData(card, base, tmp);
330 MicroDelay(10);
331 tmp &= ~AUREON_AC97_DATA_LOW;
332 SetGPIOData(card, base, tmp);
333 MicroDelay(10);
335 /* Send high-order byte to XILINX chip */
336 tmp &= ~AUREON_AC97_DATA_MASK;
337 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
339 SetGPIOData(card, base, tmp);
340 MicroDelay(10);
341 tmp |= AUREON_AC97_DATA_HIGH;
342 SetGPIOData(card, base, tmp);
343 MicroDelay(10);
344 tmp &= ~AUREON_AC97_DATA_HIGH;
345 SetGPIOData(card, base, tmp);
346 MicroDelay(10);
348 /* Instruct XILINX chip to parse the data to the STAC9744 chip */
349 tmp |= AUREON_AC97_COMMIT;
350 SetGPIOData(card, base, tmp);
351 MicroDelay(10);
352 tmp &= ~AUREON_AC97_COMMIT;
353 SetGPIOData(card, base, tmp);
354 MicroDelay(10);
358 int aureon_ac97_init(struct CardData *card, unsigned long base)
360 int i;
361 static unsigned short ac97_defaults[] = {
362 AC97_RESET, 0x6940,
363 AC97_MASTER_VOL_STEREO, 0x0101, // 0dB atten., no mute, may not exceed 0101!!!
364 AC97_AUXOUT_VOL, 0x8808,
365 AC97_MASTER_VOL_MONO, 0x8000,
366 AC97_PHONE_VOL, 0x8008, // mute
367 AC97_MIC_VOL, 0x8008,
368 AC97_LINEIN_VOL, 0x8808,
369 AC97_CD_VOL, 0x0808,
370 AC97_VIDEO_VOL, 0x8808,
371 AC97_AUX_VOL, 0x8808,
372 AC97_PCMOUT_VOL, 0x8808,
373 //0x1C, 0x8000,
374 //0x26, 0x000F,
375 //0x28, 0x0201,
376 0x2C, 0xAC44,
377 0x32, 0xAC44,
378 //0x7C, 0x8384,
379 //0x7E, 0x7644,
380 (unsigned short)-1
382 unsigned int tmp;
384 /* Cold reset */
385 tmp = (GetGPIOData(card, base) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
387 SetGPIOData(card, base, tmp);
388 MicroDelay(3);
390 tmp &= ~AUREON_AC97_RESET;
391 SetGPIOData(card, base, tmp);
392 MicroDelay(3);
394 tmp |= AUREON_AC97_RESET;
395 SetGPIOData(card, base, tmp);
396 MicroDelay(3);
398 for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
399 aureon_ac97_write(card, base, ac97_defaults[i], ac97_defaults[i+1]);
401 return 0;
408 * get the current register value of WM codec
410 static unsigned short wm_get(struct PCIDevice *dev, unsigned long base, int reg)
412 // reg <<= 1;
413 // return ((unsigned short)ice->akm[0].images[reg] << 8) | ice->akm[0].images[reg + 1];
414 return 0;
417 void wm_put(struct CardData *card, unsigned long base, unsigned short reg, unsigned short val)
419 aureon_spi_write(card, base, AUREON_WM_CS, (reg << 9) | (val & 0x1ff), 16);
424 BOOL SetupTimerDevice()
426 return TRUE;
431 void MicroDelay(unsigned int val)
433 replymp = (struct MsgPort *) CREATEPORT( NULL, 0 );
434 if( !replymp )
436 DEBUGPRINTF("Could not create the reply port!\n" );
437 return;
440 TimerIO = (struct timerequest *) CREATEIOREQUEST( replymp, sizeof( struct timerequest) );
442 if( TimerIO == NULL)
444 DEBUGPRINTF( "Out of memory.\n" );
445 return;
448 if( OPENDEVICE( "timer.device", UNIT_MICROHZ, (struct IORequest *) TimerIO, 0) != 0 )
450 DEBUGPRINTF( "Unable to open 'timer.device'.\n" );
451 return;
453 else
456 TimerBase = (struct Device *) TimerIO->tr_node.io_Device;
459 if (TimerIO)
462 TimerIO->tr_node.io_Command = TR_ADDREQUEST; /* Add a request. */
463 TimerIO->tr_time.tv_secs = 0; /* 0 seconds. */
464 TimerIO->tr_time.tv_micro = val; /* 'val' micro seconds. */
465 DOIO( (struct IORequest *) TimerIO );
466 CLOSEDEVICE( (struct IORequest *) TimerIO );
467 DELETEIOREQUEST( (struct IORequest *) TimerIO);
468 TimerIO = NULL;
471 if( replymp )
473 DELETEPORT(replymp);
478 void CleanUpTimerDevice()
483 #ifdef __MORPHOS__
484 INTGW( static, void, playbackinterrupt, PlaybackInterrupt );
485 INTGW( static, void, recordinterrupt, RecordInterrupt );
486 INTGW( static, ULONG, cardinterrupt, CardInterrupt );
487 #endif
489 /******************************************************************************
490 ** DriverData allocation ******************************************************
491 ******************************************************************************/
493 // This code used to be in _AHIsub_AllocAudio(), but since we're now
494 // handling CAMD support too, it needs to be done at driver loading
495 // time.
497 struct CardData* AllocDriverData(struct PCIDevice *dev, struct DriverBase* AHIsubBase)
499 struct CardBase* CardBase = (struct CardBase*) AHIsubBase;
500 struct CardData* card;
501 UWORD command_word;
502 int i;
504 card = ALLOCVEC( sizeof( *card ), MEMF_PUBLIC | MEMF_CLEAR );
506 if( card == NULL )
508 Req( "Unable to allocate driver structure." );
509 return NULL;
512 card->ahisubbase = AHIsubBase;
514 card->interrupt.is_Node.ln_Type = IRQTYPE;
515 card->interrupt.is_Node.ln_Pri = 0;
516 card->interrupt.is_Node.ln_Name = (STRPTR) LibName;
517 #ifndef __MORPHOS__
518 card->interrupt.is_Code = (void(*)(void)) CardInterrupt;
519 #else
520 card->interrupt.is_Code = (void(*)(void)) &cardinterrupt;
521 #endif
522 card->interrupt.is_Data = (APTR) card;
524 card->playback_interrupt.is_Node.ln_Type = IRQTYPE;
525 card->playback_interrupt.is_Node.ln_Pri = 0;
526 card->playback_interrupt.is_Node.ln_Name = (STRPTR) LibName;
527 #ifndef __MORPHOS__
528 card->playback_interrupt.is_Code = PlaybackInterrupt;
529 #else
530 card->playback_interrupt.is_Code = (void(*)(void)) &playbackinterrupt;
531 #endif
532 card->playback_interrupt.is_Data = (APTR) card;
534 card->record_interrupt.is_Node.ln_Type = IRQTYPE;
535 card->record_interrupt.is_Node.ln_Pri = 0;
536 card->record_interrupt.is_Node.ln_Name = (STRPTR) LibName;
537 #ifndef __MORPHOS__
538 card->record_interrupt.is_Code = RecordInterrupt;
539 #else
540 card->record_interrupt.is_Code = (void(*)(void)) &recordinterrupt;
541 #endif
542 card->record_interrupt.is_Data = (APTR) card;
544 card->pci_dev = dev;
546 command_word = READCONFIGWORD( PCI_COMMAND );
547 command_word |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY; // | PCI_COMMAND_MASTER;
548 WRITECONFIGWORD( PCI_COMMAND, command_word );
551 card->pci_master_enabled = TRUE;
554 card->iobase = ahi_pci_get_base_address(0, dev);
555 card->mtbase = ahi_pci_get_base_address(1, dev);
556 card->irq = ahi_pci_get_irq(dev);
557 card->chiprev = READCONFIGBYTE( PCI_REVISION_ID);
558 card->model = READCONFIGWORD( PCI_SUBSYSTEM_ID);
559 card->SavedMask = 0;
561 /*DEBUGPRINTF("---> chiprev = %u, model = %x, Vendor = %x\n", READCONFIGBYTE( PCI_REVISION_ID), READCONFIGWORD( PCI_SUBSYSTEM_ID),
562 READCONFIGWORD( PCI_SUBSYSTEM_VENDOR_ID));*/
566 if (SetupTimerDevice() == FALSE)
568 return NULL;
571 /* Initialize chip */
572 if( card_init( card ) < 0 )
574 DEBUGPRINTF("Unable to initialize Card subsystem.");
575 return NULL;
579 //DEBUGPRINTF("INTERRUPT %lu\n", dev->MapInterrupt());
580 ahi_pci_add_intserver(&card->interrupt, dev);
581 card->interrupt_added = TRUE;
583 card->card_initialized = TRUE;
585 if (card->SubType == REVO51)
587 card->input = 1; // line in
589 else
591 card->input = 0;
593 card->output = 0;
594 card->monitor_volume = 0;
595 card->input_gain = 0x10000;
596 card->output_volume = 0x10000;
597 card->input_is_24bits = FALSE;
598 card->playback_buffer = NULL;
599 card->current_bytesize = 0;
601 //SaveMixerState(card);
603 #ifdef __amigaos4__
604 AddResetHandler(card);
605 #endif
607 return card;
611 /******************************************************************************
612 ** DriverData deallocation ****************************************************
613 ******************************************************************************/
615 // And this code used to be in _AHIsub_FreeAudio().
617 void
618 FreeDriverData( struct CardData* card,
619 struct DriverBase* AHIsubBase )
621 if( card != NULL )
623 if( card->pci_dev != NULL )
625 if( card->card_initialized )
627 card_cleanup( card );
630 if( card->pci_master_enabled )
632 UWORD cmd;
633 struct PCIDevice * dev = card->pci_dev;
634 cmd = READCONFIGWORD( PCI_COMMAND );
635 cmd &= ~( PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER );
636 WRITECONFIGWORD( PCI_COMMAND, cmd );
640 if( card->interrupt_added )
642 ahi_pci_rem_intserver(&card->interrupt, card->pci_dev);
645 FREEVEC( card );
648 CleanUpTimerDevice();
652 static unsigned short wm_inits[] = {
654 0x18, 0x000, /* All power-up */
656 0x1b, 0x022, /* ADC Mux (AIN1 = CD-in) */
657 0x1c, 0x00B, /* Output1 = DAC + Aux (= ac'97 mix), output2 = DAC */
658 0x1d, 0x009, /* Output3+4 = DAC */
660 0x16, 0x122, /* I2S, normal polarity, 24bit */
661 0x17, 0x022, /* 256fs, slave mode */
663 0x00, 0x17F, /* DAC1 analog mute */
664 0x01, 0x17F, /* DAC2 analog mute */
665 0x02, 0x17F, /* DAC3 analog mute */
666 0x03, 0x17F, /* DAC4 analog mute */
667 0x04, 0x7F, /* DAC5 analog mute */
668 0x05, 0x7F, /* DAC6 analog mute */
669 0x06, 0x7F, /* DAC7 analog mute */
670 0x07, 0x7F, /* DAC8 analog mute */
671 0x08, 0x17F, /* master analog mute */
672 0x09, 0x1ff, /* DAC1 digital full */
673 0x0a, 0x1ff, /* DAC2 digital full */
674 0x0b, 0xff, /* DAC3 digital full */
675 0x0c, 0xff, /* DAC4 digital full */
676 0x0d, 0xff, /* DAC5 digital full */
677 0x0e, 0xff, /* DAC6 digital full */
678 0x0f, 0xff, /* DAC7 digital full */
679 0x10, 0xff, /* DAC8 digital full */
680 0x11, 0x1ff, /* master digital full */
681 0x12, 0x000, /* phase normal */
682 0x13, 0x090, /* unmute DAC L/R */
683 0x14, 0x000, /* all unmute (bit 5 is rec enable) */
684 0x15, 0x000, /* no deemphasis, no ZFLG */
685 0x19, 0x0C, /* 0dB gain ADC/L */
686 0x1a, 0x0C /* 0dB gain ADC/R */
689 static unsigned short wm_inits_Phase28[] = {
691 0x18, 0x000, /* All power-up */
693 0x1b, 0x000, /* ADC Mux (AIN1 = Line-in, no other inputs are present) */
694 0x1c, 0x009, /* Output1 = DAC , Output2 = DAC */
695 0x1d, 0x009, /* Output3+4 = DAC */
697 0x16, 0x122, /* I2S, normal polarity, 24bit */
698 0x17, 0x022, /* 256fs, slave mode */
700 0x00, 0x000, /* DAC1 analog mute */
701 0x01, 0x000, /* DAC2 analog mute */
702 0x02, 0x7F, /* DAC3 analog mute */
703 0x03, 0x7F, /* DAC4 analog mute */
704 0x04, 0x7F, /* DAC5 analog mute */
705 0x05, 0x7F, /* DAC6 analog mute */
706 0x06, 0x7F, /* DAC7 analog mute */
707 0x07, 0x7F, /* DAC8 analog mute */
708 0x08, 0x17F, /* master analog mute */
709 0x09, 0xff, /* DAC1 digital full */
710 0x0a, 0xff, /* DAC2 digital full */
711 0x0b, 0xff, /* DAC3 digital full */
712 0x0c, 0xff, /* DAC4 digital full */
713 0x0d, 0xff, /* DAC5 digital full */
714 0x0e, 0xff, /* DAC6 digital full */
715 0x0f, 0xff, /* DAC7 digital full */
716 0x10, 0xff, /* DAC8 digital full */
717 0x11, 0x1ff, /* master digital full */
718 0x12, 0x000, /* phase normal */
719 0x13, 0x090, /* unmute DAC L/R */
720 0x14, 0x000, /* all unmute (bit 5 is rec enable) */
721 0x15, 0x000, /* no deemphasis, no ZFLG */
722 0x19, 0x0C, /* 0dB gain ADC/L */
723 0x1a, 0x0C /* 0dB gain ADC/R */
726 static unsigned short cs_inits[] = {
727 0x0441, /* RUN */
728 0x0180, /* no mute */
729 0x0201, /* */
730 0x0605, /* master, 16-bit slave, 24bit */
734 int card_init(struct CardData *card)
736 struct PCIDevice *dev = (struct PCIDevice *) card->pci_dev;
737 unsigned short cod;
738 int i;
739 unsigned int tmp, eepromsize;
740 unsigned char eeprom[128];
742 OUTBYTE(card->mtbase + MT_AC97_CMD_STATUS, MT_AC97_RESET); // tbd
743 MicroDelay(5);
744 OUTBYTE(card->mtbase + MT_AC97_CMD_STATUS, 0x00); // tbd
746 //DEBUGPRINTF("Envy24HT: card_init %lx\n", card);
748 OUTBYTE(card->iobase + CCS_POWER_DOWN, 0); // power up the whole thing
750 // reset
751 OUTBYTE(card->mtbase + CCS_CTRL, CCS_RESET_ALL);
752 MicroDelay(100);
753 ClearMask8(card, card->mtbase, CCS_CTRL, CCS_RESET_ALL);
754 MicroDelay(100);
756 //DEBUGPRINTF("Envy24HT: reading eeprom\n");
757 if ((INBYTE(card->iobase + CCS_I2C_STATUS) & CCS_I2C_EPROM) != 0)
759 unsigned long subvendor = 0;
761 subvendor =
762 (ReadI2C(dev, card, 0x00) << 0) |
763 (ReadI2C(dev, card, 0x01) << 8) |
764 (ReadI2C(dev, card, 0x02) << 16) |
765 (ReadI2C(dev, card, 0x03) << 24);
767 switch (subvendor)
769 case SUBVENDOR_AUREON_SKY: card->SubType = AUREON_SKY;
770 break;
772 case SUBVENDOR_AUREON_SPACE: card->SubType = AUREON_SPACE;
773 break;
775 case SUBVENDOR_PHASE28: card->SubType = PHASE28;
776 break;
778 case SUBVENDOR_MAUDIO_REVOLUTION51: card->SubType = REVO51;
779 break;
781 case SUBVENDOR_MAUDIO_REVOLUTION71: card->SubType = REVO71;
782 break;
784 case SUBVENDOR_JULIA: card->SubType = JULIA;
785 break;
787 case SUBVENDOR_PHASE22: card->SubType = PHASE22;
788 break;
790 default:
791 card->SubType = AUREON_SKY;
794 DEBUGPRINTF("subvendor = %lx, Type = %d\n", subvendor, card->SubType);
798 if (card->SubType == PHASE22)
800 OUTBYTE(card->iobase + CCS_SYSTEM_CONFIG, 0x28);
801 OUTBYTE(card->iobase + CCS_ACLINK_CONFIG, 0x80); // AC-link
802 OUTBYTE(card->iobase + CCS_I2S_FEATURES, 0x70); // I2S
803 OUTBYTE(card->iobase + CCS_SPDIF_CONFIG, 0xC3); // S/PDIF
805 else
807 if (card->SubType == PHASE28)
808 OUTBYTE(card->iobase + CCS_SYSTEM_CONFIG, 0x2B); // MIDI, ADC+SPDIF IN, 4 DACS
809 else if (card->SubType == AUREON_SPACE)
810 OUTBYTE(card->iobase + CCS_SYSTEM_CONFIG, 0x0B); // ADC+SPDIF IN, 4 DACS
811 else if (card->SubType == REVO71)
812 OUTBYTE(card->iobase + CCS_SYSTEM_CONFIG, 0x43); // XIN1 + ADC + 4 DACS
813 else if (card->SubType == REVO51)
814 OUTBYTE(card->iobase + CCS_SYSTEM_CONFIG, 0x42);
815 else if (card->SubType == JULIA)
816 OUTBYTE(card->iobase + CCS_SYSTEM_CONFIG, 0x20); // MIDI + ADC + DAC
817 else if (card->SubType == AUREON_SKY)
818 OUTBYTE(card->iobase + CCS_SYSTEM_CONFIG, 0x0A); // ADC+SPDIF IN, 3 DACS
820 OUTBYTE(card->iobase + CCS_ACLINK_CONFIG, CCS_ACLINK_I2S); // I2S in split mode
822 if (card->SubType == JULIA)
823 OUTBYTE(card->iobase + CCS_I2S_FEATURES, CCS_I2S_96KHZ | CCS_I2S_24BIT | CCS_I2S_192KHZ);
824 else
825 OUTBYTE(card->iobase + CCS_I2S_FEATURES, CCS_I2S_VOLMUTE | CCS_I2S_96KHZ | CCS_I2S_24BIT | CCS_I2S_192KHZ);
827 if (card->SubType == REVO71 || card->SubType == REVO51)
828 OUTBYTE(card->iobase + CCS_SPDIF_CONFIG, CCS_SPDIF_INTEGRATED | CCS_SPDIF_INTERNAL_OUT | CCS_SPDIF_EXTERNAL_OUT);
829 else
830 OUTBYTE(card->iobase + CCS_SPDIF_CONFIG, CCS_SPDIF_INTEGRATED | CCS_SPDIF_INTERNAL_OUT | CCS_SPDIF_IN_PRESENT | CCS_SPDIF_EXTERNAL_OUT);
834 card->SavedDir = Dirs[card->SubType];
835 OUTBYTE(card->mtbase + MT_INTR_MASK, MT_DMA_FIFO_MASK);
837 if (card->SubType == REVO71)
838 SetGPIOMask(card, card->iobase, 0x00BFFF85);
839 else if (card->SubType == REVO51)
840 SetGPIOMask(card, card->iobase, 0x00BFFF05);
841 else
842 SetGPIOMask(card, card->iobase, 0x00000000);
844 OUTLONG(card->iobase + CCS_GPIO_DIR, Dirs[card->SubType]); // input/output
845 INWORD(card->iobase + CCS_GPIO_DIR);
847 if (card->SubType == REVO71 || card->SubType == REVO51) {
848 OUTWORD(card->iobase + CCS_GPIO_DATA, 0x0072);
849 OUTBYTE(card->iobase + CCS_GPIO_DATA2, 0x00);
851 else if (card->SubType == JULIA) {
852 OUTWORD(card->iobase + CCS_GPIO_DATA, 0x3819);
854 else {
855 OUTWORD(card->iobase + CCS_GPIO_DATA, 0x0000);
856 if (card->SubType != PHASE22)
857 OUTBYTE(card->iobase + CCS_GPIO_DATA2, 0x00);
859 INWORD(card->iobase + CCS_GPIO_DATA);
861 //SaveGPIO(dev, card);
863 if (card->SubType == REVO71 || card->SubType == REVO51)
864 OUTBYTE(card->mtbase + MT_I2S_FORMAT, 0x08);
865 else
866 OUTBYTE(card->mtbase + MT_I2S_FORMAT, 0);
868 if (card->SubType == AUREON_SKY || card->SubType == AUREON_SPACE || card->SubType == PHASE28)
870 if (card->SubType == AUREON_SKY || card->SubType == AUREON_SPACE)
872 aureon_ac97_init(card, card->iobase);
873 SetGPIOMask(card, card->iobase, ~(AUREON_WM_RESET | AUREON_WM_CS | AUREON_CS8415_CS));
875 else if (card->SubType == PHASE28)
876 SetGPIOMask(card, card->iobase, ~(AUREON_WM_RESET | AUREON_WM_CS));
879 tmp = GetGPIOData(card, card->iobase);
880 tmp &= ~AUREON_WM_RESET;
881 SetGPIOData(card, card->iobase, tmp);
882 MicroDelay(1);
884 if (card->SubType != PHASE28)
885 tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
886 else
887 tmp |= AUREON_WM_CS;
889 SetGPIOData(card, card->iobase, tmp);
890 MicroDelay(1);
891 tmp |= AUREON_WM_RESET;
892 SetGPIOData(card, card->iobase, tmp);
893 MicroDelay(1);
895 if (card->SubType != PHASE28)
897 /* initialize WM8770 codec */
898 for (i = 0; i < 60; i += 2)
900 wm_put(card, card->iobase, wm_inits[i], wm_inits[i+1]);
903 /* initialize CS8415A codec */
904 for (i = 0; i < 4; i++)
905 aureon_spi_write(card, card->iobase, AUREON_CS8415_CS, cs_inits[i] | 0x200000, 24);
907 else
909 /* initialize WM8770 codec */
910 for (i = 0; i < 60; i += 2)
912 wm_put(card, card->iobase, wm_inits_Phase28[i], wm_inits_Phase28[i+1]);
916 else if (card->SubType == REVO51)
918 card->RevoFrontCodec = ALLOCVEC(sizeof(struct akm_codec), MEMF_ANY);
919 card->RevoFrontCodec->caddr = 2;
920 card->RevoFrontCodec->cif = 0;
921 card->RevoFrontCodec->datamask = REVO_CDOUT;
922 card->RevoFrontCodec->clockmask = REVO_CCLK;
923 card->RevoFrontCodec->csmask = REVO_CS0 | REVO_CS1;
924 card->RevoFrontCodec->csaddr = REVO_CS1;
925 card->RevoFrontCodec->csnone = REVO_CS0 | REVO_CS1;
926 card->RevoFrontCodec->addflags = REVO_CCLK;
927 card->RevoFrontCodec->type = AKM4358;
928 card->RevoFrontCodec->totalmask = 0;
929 card->RevoFrontCodec->newflag = 1;
932 card->RevoSurroundCodec = NULL;
934 card->RevoRecCodec = ALLOCVEC(sizeof(struct akm_codec), MEMF_ANY);
935 card->RevoRecCodec->caddr = 2;
936 card->RevoRecCodec->csmask = REVO_CS0 | REVO_CS1;
937 card->RevoRecCodec->clockmask = REVO_CCLK;
938 card->RevoRecCodec->datamask = REVO_CDOUT;
939 card->RevoRecCodec->type = AKM5365;
940 card->RevoRecCodec->cif = 0;
941 card->RevoRecCodec->addflags = REVO_CCLK;
942 card->RevoRecCodec->csaddr = REVO_CS0;
943 card->RevoRecCodec->csnone = REVO_CS0 | REVO_CS1;
944 card->RevoRecCodec->totalmask = 0;
945 card->RevoRecCodec->newflag = 1;
947 OUTBYTE(card->mtbase + MT_SAMPLERATE, 8);
950 unsigned int tmp = GetGPIOData(card, card->iobase);
951 tmp &= ~REVO_MUTE; // mute
952 SetGPIOData(card, card->iobase, tmp);
955 Init_akm4xxx(card, card->RevoFrontCodec);
958 unsigned int tmp = GetGPIOData(card, card->iobase);
959 tmp |= REVO_MUTE; // unmute
960 SetGPIOData(card, card->iobase, tmp);
963 // Has to be after mute, otherwise the mask is changed in Revo51_Init() which enables the mute mask bit...
964 Revo51_Init(card); // I2C
966 else if (card->SubType == REVO71)
968 card->RevoFrontCodec = ALLOCVEC(sizeof(struct akm_codec), MEMF_ANY);
969 card->RevoFrontCodec->caddr = 1;
970 card->RevoFrontCodec->csmask = REVO_CS1;
971 card->RevoFrontCodec->clockmask = REVO_CCLK;
972 card->RevoFrontCodec->datamask = REVO_CDOUT;
973 card->RevoFrontCodec->type = AKM4381;
974 card->RevoFrontCodec->cif = 0;
975 card->RevoFrontCodec->addflags = 0; //REVO_CCLK;?
977 card->RevoSurroundCodec = ALLOCVEC(sizeof(struct akm_codec), MEMF_ANY);
978 card->RevoSurroundCodec->caddr = 3;
979 card->RevoSurroundCodec->csmask = REVO_CS2;
980 card->RevoSurroundCodec->clockmask = REVO_CCLK;
981 card->RevoSurroundCodec->datamask = REVO_CDOUT;
982 card->RevoSurroundCodec->type = AKM4355;
983 card->RevoSurroundCodec->cif = 0;
984 card->RevoSurroundCodec->addflags = 0; //REVO_CCLK;?
986 OUTBYTE(card->mtbase + MT_SAMPLERATE, 8);
989 unsigned int tmp = GetGPIOData(card, card->iobase);
990 tmp &= ~REVO_MUTE; // mute
991 SetGPIOData(card, card->iobase, tmp);
994 Init_akm4xxx(card, card->RevoFrontCodec);
995 Init_akm4xxx(card, card->RevoSurroundCodec);
996 //revo_i2s_mclk_changed(card);
999 unsigned int tmp = GetGPIOData(card, card->iobase);
1000 tmp |= REVO_MUTE; // unmute
1001 SetGPIOData(card, card->iobase, tmp);
1005 else if (card->SubType == JULIA)
1007 unsigned char *ptr, reg, data;
1011 static unsigned char inits_ak4114[] = {
1012 0x00, 0x00, // power down & reset
1013 0x00, 0x0F, // power on
1014 0x01, 0x70, // I2S
1015 0x02, 0x80, // TX1 output enable
1016 0x03, 0x49, // 1024 LRCK + transmit data
1017 0x04, 0x00, // no mask
1018 0x05, 0x00, // no mask
1019 0x0D, 0x41, //
1020 0x0E, 0x02,
1021 0x0F, 0x2C,
1022 0x10, 0x00,
1023 0x11, 0x00,
1024 0xff, 0xff
1027 ptr = inits_ak4358;
1028 while (*ptr != 0xff) {
1029 reg = *ptr++;
1030 data = *ptr++;
1031 WriteI2C(dev, card, AK4358_ADDR, reg, data);
1032 MicroDelay(5);
1035 ptr = inits_ak4114;
1036 while (*ptr != 0xff) {
1037 reg = *ptr++;
1038 data = *ptr++;
1039 WriteI2C(dev, card, AK4114_ADDR, reg, data);
1040 MicroDelay(100);
1043 OUTBYTE(card->mtbase + MT_SAMPLERATE, MT_SPDIF_MASTER);
1044 OUTLONG(card->mtbase + 0x2C, 0x300200); // route
1046 else if (card->SubType == PHASE22)
1048 unsigned int tmp;
1050 card->RevoFrontCodec = ALLOCVEC(sizeof(struct akm_codec), MEMF_ANY);
1051 card->RevoFrontCodec->caddr = 2;
1052 card->RevoFrontCodec->csmask = 1 << 10;
1053 card->RevoFrontCodec->clockmask = 1 << 5;
1054 card->RevoFrontCodec->datamask = 1 << 4;
1055 card->RevoFrontCodec->type = AKM4524;
1056 card->RevoFrontCodec->cif = 1;
1057 card->RevoFrontCodec->addflags = 1 << 3;
1059 Init_akm4xxx(card, card->RevoFrontCodec);
1062 //RestoreGPIO(dev, card);
1064 ClearMask8(card, card->iobase, CCS_INTR_MASK, CCS_INTR_PLAYREC); // enable
1066 // Enter SPI mode for CS8415A digital receiver
1067 /*SetGPIOMask(card, card->iobase, ~(AUREON_CS8415_CS));
1068 tmp |= AUREON_CS8415_CS;
1069 SetGPIOData(card, card->iobase, tmp); // set CS high
1070 MicroDelay(1);
1072 tmp &= ~AUREON_CS8415_CS;
1073 SetGPIOData(card, card->iobase, tmp); // set CS low
1074 MicroDelay(1);*/
1076 // WritePartialMask(card, card->mtbase, 0x2C, 8, 7, 6); // this line is to route the s/pdif input to the left
1077 // analogue output for testing purposes
1079 return 0;
1083 void card_cleanup(struct CardData *card)
1089 /******************************************************************************
1090 ** Misc. **********************************************************************
1091 ******************************************************************************/
1093 void
1094 SaveMixerState( struct CardData* card )
1099 void
1100 RestoreMixerState( struct CardData* card )
1104 void
1105 UpdateMonitorMixer( struct CardData* card )
1110 Fixed
1111 Linear2MixerGain( Fixed linear,
1112 UWORD* bits )
1114 static const Fixed gain[ 256 ] =
1116 0x0, // -127.5 dB
1117 0x0, // -127.0 dB
1118 0x0, // -126.5 dB
1119 0x0, // -126.0 dB
1120 0x0, // -125.5 dB
1121 0x0, // -125.0 dB
1122 0x0, // -124.5 dB
1123 0x0, // -124.0 dB
1124 0x0, // -123.5 dB
1125 0x0, // -123.0 dB
1126 0x0, // -122.5 dB
1127 0x0, // -122.0 dB
1128 0x0, // -121.5 dB
1129 0x0, // -121.0 dB
1130 0x0, // -120.5 dB
1131 0x0, // -120.0 dB
1132 0x0, // -119.5 dB
1133 0x0, // -119.0 dB
1134 0x0, // -118.5 dB
1135 0x0, // -118.0 dB
1136 0x0, // -117.5 dB
1137 0x0, // -117.0 dB
1138 0x0, // -116.5 dB
1139 0x0, // -116.0 dB
1140 0x0, // -115.5 dB
1141 0x0, // -115.0 dB
1142 0x0, // -114.5 dB
1143 0x0, // -114.0 dB
1144 0x0, // -113.5 dB
1145 0x0, // -113.0 dB
1146 0x0, // -112.5 dB
1147 0x0, // -112.0 dB
1148 0x0, // -111.5 dB
1149 0x0, // -111.0 dB
1150 0x0, // -110.5 dB
1151 0x0, // -110.0 dB
1152 0x0, // -109.5 dB
1153 0x0, // -109.0 dB
1154 0x0, // -108.5 dB
1155 0x0, // -108.0 dB
1156 0x0, // -107.5 dB
1157 0x0, // -107.0 dB
1158 0x0, // -106.5 dB
1159 0x0, // -106.0 dB
1160 0x0, // -105.5 dB
1161 0x0, // -105.0 dB
1162 0x0, // -104.5 dB
1163 0x0, // -104.0 dB
1164 0x0, // -103.5 dB
1165 0x0, // -103.0 dB
1166 0x0, // -102.5 dB
1167 0x0, // -102.0 dB
1168 0x0, // -101.5 dB
1169 0x0, // -101.0 dB
1170 0x0, // -100.5 dB
1171 0x0, // -100.0 dB
1172 0x0, // -99.5 dB
1173 0x0, // -99.0 dB
1174 0x0, // -98.5 dB
1175 0x0, // -98.0 dB
1176 0x0, // -97.5 dB
1177 0x0, // -97.0 dB
1178 0x0, // -96.5 dB
1179 0x1, // -96.0 dB
1180 0x1, // -95.5 dB
1181 0x1, // -95.0 dB
1182 0x1, // -94.5 dB
1183 0x1, // -94.0 dB
1184 0x1, // -93.5 dB
1185 0x1, // -93.0 dB
1186 0x1, // -92.5 dB
1187 0x1, // -92.0 dB
1188 0x1, // -91.5 dB
1189 0x1, // -91.0 dB
1190 0x1, // -90.5 dB
1191 0x2, // -90.0 dB
1192 0x2, // -89.5 dB
1193 0x2, // -89.0 dB
1194 0x2, // -88.5 dB
1195 0x2, // -88.0 dB
1196 0x2, // -87.5 dB
1197 0x2, // -87.0 dB
1198 0x3, // -86.5 dB
1199 0x3, // -86.0 dB
1200 0x3, // -85.5 dB
1201 0x3, // -85.0 dB
1202 0x3, // -84.5 dB
1203 0x4, // -84.0 dB
1204 0x4, // -83.5 dB
1205 0x4, // -83.0 dB
1206 0x4, // -82.5 dB
1207 0x5, // -82.0 dB
1208 0x5, // -81.5 dB
1209 0x5, // -81.0 dB
1210 0x6, // -80.5 dB
1211 0x6, // -80.0 dB
1212 0x6, // -79.5 dB
1213 0x7, // -79.0 dB
1214 0x7, // -78.5 dB
1215 0x8, // -78.0 dB
1216 0x8, // -77.5 dB
1217 0x9, // -77.0 dB
1218 0x9, // -76.5 dB
1219 0xa, // -76.0 dB
1220 0xb, // -75.5 dB
1221 0xb, // -75.0 dB
1222 0xc, // -74.5 dB
1223 0xd, // -74.0 dB
1224 0xd, // -73.5 dB
1225 0xe, // -73.0 dB
1226 0xf, // -72.5 dB
1227 0x10, // -72.0 dB
1228 0x11, // -71.5 dB
1229 0x12, // -71.0 dB
1230 0x13, // -70.5 dB
1231 0x14, // -70.0 dB
1232 0x15, // -69.5 dB
1233 0x17, // -69.0 dB
1234 0x18, // -68.5 dB
1235 0x1a, // -68.0 dB
1236 0x1b, // -67.5 dB
1237 0x1d, // -67.0 dB
1238 0x1f, // -66.5 dB
1239 0x20, // -66.0 dB
1240 0x22, // -65.5 dB
1241 0x24, // -65.0 dB
1242 0x27, // -64.5 dB
1243 0x29, // -64.0 dB
1244 0x2b, // -63.5 dB
1245 0x2e, // -63.0 dB
1246 0x31, // -62.5 dB
1247 0x34, // -62.0 dB
1248 0x37, // -61.5 dB
1249 0x3a, // -61.0 dB
1250 0x3d, // -60.5 dB
1251 0x41, // -60.0 dB
1252 0x45, // -59.5 dB
1253 0x49, // -59.0 dB
1254 0x4d, // -58.5 dB
1255 0x52, // -58.0 dB
1256 0x57, // -57.5 dB
1257 0x5c, // -57.0 dB
1258 0x62, // -56.5 dB
1259 0x67, // -56.0 dB
1260 0x6e, // -55.5 dB
1261 0x74, // -55.0 dB
1262 0x7b, // -54.5 dB
1263 0x82, // -54.0 dB
1264 0x8a, // -53.5 dB
1265 0x92, // -53.0 dB
1266 0x9b, // -52.5 dB
1267 0xa4, // -52.0 dB
1268 0xae, // -51.5 dB
1269 0xb8, // -51.0 dB
1270 0xc3, // -50.5 dB
1271 0xcf, // -50.0 dB
1272 0xdb, // -49.5 dB
1273 0xe8, // -49.0 dB
1274 0xf6, // -48.5 dB
1275 0x104, // -48.0 dB
1276 0x114, // -47.5 dB
1277 0x124, // -47.0 dB
1278 0x136, // -46.5 dB
1279 0x148, // -46.0 dB
1280 0x15b, // -45.5 dB
1281 0x170, // -45.0 dB
1282 0x186, // -44.5 dB
1283 0x19d, // -44.0 dB
1284 0x1b6, // -43.5 dB
1285 0x1cf, // -43.0 dB
1286 0x1eb, // -42.5 dB
1287 0x208, // -42.0 dB
1288 0x227, // -41.5 dB
1289 0x248, // -41.0 dB
1290 0x26a, // -40.5 dB
1291 0x28f, // -40.0 dB
1292 0x2b6, // -39.5 dB
1293 0x2df, // -39.0 dB
1294 0x30a, // -38.5 dB
1295 0x339, // -38.0 dB
1296 0x369, // -37.5 dB
1297 0x39d, // -37.0 dB
1298 0x3d4, // -36.5 dB
1299 0x40e, // -36.0 dB
1300 0x44c, // -35.5 dB
1301 0x48d, // -35.0 dB
1302 0x4d2, // -34.5 dB
1303 0x51b, // -34.0 dB
1304 0x569, // -33.5 dB
1305 0x5bb, // -33.0 dB
1306 0x612, // -32.5 dB
1307 0x66e, // -32.0 dB
1308 0x6cf, // -31.5 dB
1309 0x737, // -31.0 dB
1310 0x7a4, // -30.5 dB
1311 0x818, // -30.0 dB
1312 0x893, // -29.5 dB
1313 0x915, // -29.0 dB
1314 0x99f, // -28.5 dB
1315 0xa31, // -28.0 dB
1316 0xacb, // -27.5 dB
1317 0xb6f, // -27.0 dB
1318 0xc1c, // -26.5 dB
1319 0xcd4, // -26.0 dB
1320 0xd97, // -25.5 dB
1321 0xe65, // -25.0 dB
1322 0xf3f, // -24.5 dB
1323 0x1027, // -24.0 dB
1324 0x111c, // -23.5 dB
1325 0x121f, // -23.0 dB
1326 0x1332, // -22.5 dB
1327 0x1455, // -22.0 dB
1328 0x158a, // -21.5 dB
1329 0x16d0, // -21.0 dB
1330 0x182a, // -20.5 dB
1331 0x1999, // -20.0 dB
1332 0x1b1d, // -19.5 dB
1333 0x1cb9, // -19.0 dB
1334 0x1e6c, // -18.5 dB
1335 0x203a, // -18.0 dB
1336 0x2223, // -17.5 dB
1337 0x2429, // -17.0 dB
1338 0x264d, // -16.5 dB
1339 0x2892, // -16.0 dB
1340 0x2afa, // -15.5 dB
1341 0x2d86, // -15.0 dB
1342 0x3038, // -14.5 dB
1343 0x3314, // -14.0 dB
1344 0x361a, // -13.5 dB
1345 0x394f, // -13.0 dB
1346 0x3cb5, // -12.5 dB
1347 0x404d, // -12.0 dB
1348 0x441d, // -11.5 dB
1349 0x4826, // -11.0 dB
1350 0x4c6d, // -10.5 dB
1351 0x50f4, // -10.0 dB
1352 0x55c0, // -9.5 dB
1353 0x5ad5, // -9.0 dB
1354 0x6036, // -8.5 dB
1355 0x65ea, // -8.0 dB
1356 0x6bf4, // -7.5 dB
1357 0x7259, // -7.0 dB
1358 0x7920, // -6.5 dB
1359 0x804d, // -6.0 dB
1360 0x87e8, // -5.5 dB
1361 0x8ff5, // -5.0 dB
1362 0x987d, // -4.5 dB
1363 0xa186, // -4.0 dB
1364 0xab18, // -3.5 dB
1365 0xb53b, // -3.0 dB
1366 0xbff9, // -2.5 dB
1367 0xcb59, // -2.0 dB
1368 0xd765, // -1.5 dB
1369 0xe429, // -1.0 dB
1370 0xf1ad, // -0.5 dB
1371 0x10000, // 0.0 dB
1374 int v = 0;
1376 while( linear > gain[ v ] && v < 255)
1378 ++v;
1381 *bits = v;
1383 return gain[ v ];
1387 Fixed
1388 Linear2AKMGain( Fixed linear,
1389 UWORD* bits )
1391 static const Fixed gain[ 101 ] =
1393 0x0, // -100 dB
1394 0x0, // -99 dB
1395 0x0, // -98 dB
1396 0x0, // -97 dB
1397 0x1, // -96 dB
1398 0x1, // -95 dB
1399 0x1, // -94 dB
1400 0x1, // -93 dB
1401 0x1, // -92 dB
1402 0x1, // -91 dB
1403 0x2, // -90 dB
1404 0x2, // -89 dB
1405 0x2, // -88 dB
1406 0x2, // -87 dB
1407 0x3, // -86 dB
1408 0x3, // -85 dB
1409 0x4, // -84 dB
1410 0x4, // -83 dB
1411 0x5, // -82 dB
1412 0x5, // -81 dB
1413 0x6, // -80 dB
1414 0x7, // -79 dB
1415 0x8, // -78 dB
1416 0x9, // -77 dB
1417 0xa, // -76 dB
1418 0xb, // -75 dB
1419 0xd, // -74 dB
1420 0xe, // -73 dB
1421 0x10, // -72 dB
1422 0x12, // -71 dB
1423 0x14, // -70 dB
1424 0x17, // -69 dB
1425 0x1a, // -68 dB
1426 0x1d, // -67 dB
1427 0x20, // -66 dB
1428 0x24, // -65 dB
1429 0x29, // -64 dB
1430 0x2e, // -63 dB
1431 0x34, // -62 dB
1432 0x3a, // -61 dB
1433 0x41, // -60 dB
1434 0x49, // -59 dB
1435 0x52, // -58 dB
1436 0x5c, // -57 dB
1437 0x67, // -56 dB
1438 0x74, // -55 dB
1439 0x82, // -54 dB
1440 0x92, // -53 dB
1441 0xa4, // -52 dB
1442 0xb8, // -51 dB
1443 0xcf, // -50 dB
1444 0xe8, // -49 dB
1445 0x104, // -48 dB
1446 0x124, // -47 dB
1447 0x148, // -46 dB
1448 0x170, // -45 dB
1449 0x19d, // -44 dB
1450 0x1cf, // -43 dB
1451 0x208, // -42 dB
1452 0x248, // -41 dB
1453 0x28f, // -40 dB
1454 0x2df, // -39 dB
1455 0x339, // -38 dB
1456 0x39d, // -37 dB
1457 0x40e, // -36 dB
1458 0x48d, // -35 dB
1459 0x51b, // -34 dB
1460 0x5bb, // -33 dB
1461 0x66e, // -32 dB
1462 0x737, // -31 dB
1463 0x818, // -30 dB
1464 0x915, // -29 dB
1465 0xa31, // -28 dB
1466 0xb6f, // -27 dB
1467 0xcd4, // -26 dB
1468 0xe65, // -25 dB
1469 0x1027, // -24 dB
1470 0x121f, // -23 dB
1471 0x1455, // -22 dB
1472 0x16d0, // -21 dB
1473 0x1999, // -20 dB
1474 0x1cb9, // -19 dB
1475 0x203a, // -18 dB
1476 0x2429, // -17 dB
1477 0x2892, // -16 dB
1478 0x2d86, // -15 dB
1479 0x3314, // -14 dB
1480 0x394f, // -13 dB
1481 0x404d, // -12 dB
1482 0x4826, // -11 dB
1483 0x50f4, // -10 dB
1484 0x5ad5, // -9 dB
1485 0x65ea, // -8 dB
1486 0x7259, // -7 dB
1487 0x804d, // -6 dB
1488 0x8ff5, // -5 dB
1489 0xa186, // -4 dB
1490 0xb53b, // -3 dB
1491 0xcb59, // -2 dB
1492 0xe429, // -1 dB
1493 0x10000, // 0 dB
1497 int v = 0;
1499 while( linear > gain[ v ] && v < 100)
1501 ++v;
1504 *bits = v + 0x9B;
1506 return gain[ v ];
1511 Fixed
1512 Linear2RecordGain( Fixed linear,
1513 UWORD* bits )
1515 static const Fixed gain[ 32 ] =
1517 0x404d, // -12 dB
1518 0x4826, // -11 dB
1519 0x50f4, // -10 dB
1520 0x5ad5, // -9 dB
1521 0x65ea, // -8 dB
1522 0x7259, // -7 dB
1523 0x804d, // -6 dB
1524 0x8ff5, // -5 dB
1525 0xa186, // -4 dB
1526 0xb53b, // -3 dB
1527 0xcb59, // -2 dB
1528 0xe429, // -1 dB
1529 0x10000, // 0 dB
1530 0x11f3c, // 1 dB
1531 0x14248, // 2 dB
1532 0x1699c, // 3 dB
1533 0x195bb, // 4 dB
1534 0x1c73d, // 5 dB
1535 0x1fec9, // 6 dB
1536 0x23d1c, // 7 dB
1537 0x2830a, // 8 dB
1538 0x2d181, // 9 dB
1539 0x3298b, // 10 dB
1540 0x38c52, // 11 dB
1541 0x3fb27, // 12 dB
1542 0x47782, // 13 dB
1543 0x5030a, // 14 dB
1544 0x59f98, // 15 dB
1545 0x64f40, // 16 dB
1546 0x71457, // 17 dB
1547 0x7f17a, // 18 dB
1548 0x8e99a, // 19 dB
1551 int v = 0;
1553 while( linear > gain[ v ] && v < 32)
1555 ++v;
1558 *bits = v;
1560 return gain[ v ];
1564 ULONG
1565 SamplerateToLinearPitch( ULONG samplingrate )
1567 samplingrate = (samplingrate << 8) / 375;
1568 return (samplingrate >> 1) + (samplingrate & 1);
1572 #define CACHELINE_SIZE 4096
1574 void *pci_alloc_consistent(size_t size, APTR *NonAlignedAddress, unsigned int boundary)
1576 #ifdef __amigaos4__
1577 void* address;
1578 unsigned long a;
1580 if (IExec->OpenResource("newmemory.resource"))
1582 address = ALLOCVECTags(size, AVT_Type, MEMF_SHARED, AVT_Contiguous, TRUE, AVT_Lock, TRUE,
1583 AVT_PhysicalAlignment, 32, AVT_Clear, 0, TAG_DONE);
1585 else
1587 address = ALLOCVEC( size + CACHELINE_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
1589 if( address != NULL )
1591 a = (unsigned long) address;
1592 a = (a + CACHELINE_SIZE - 1) & ~(CACHELINE_SIZE - 1);
1593 address = (void *) a;
1597 *NonAlignedAddress = address;
1599 return address;
1600 #else
1601 void* address;
1602 unsigned long a;
1604 #ifdef __MORPHOS__
1605 //address = AllocVecDMA(size + boundary, MEMF_PUBLIC | MEMF_CLEAR);
1606 #if 0
1607 address = AllocVec(size + CACHELINE_SIZE - 1, MEMF_PUBLIC & ~MEMF_CLEAR);
1608 Forbid();
1609 FreeMem(address, size + CACHELINE_SIZE - 1);
1610 address = AllocAbs(size, (void*) ((ULONG) (address + CACHELINE_SIZE - 1) & ~(CACHELINE_SIZE-1) ) );
1611 Permit();
1612 #endif
1613 address = AllocVecDMA(size, MEMF_PUBLIC | MEMF_CLEAR);
1614 *NonAlignedAddress = address;
1616 memset(address, 0, size);
1618 return address;
1620 #else
1621 address = AllocVec(size + boundary, MEMF_PUBLIC | MEMF_CLEAR);
1623 if (address != NULL)
1625 a = (unsigned long) address;
1626 a = (a + boundary - 1) & ~(boundary - 1);
1627 address = (void *) a;
1630 if (NonAlignedAddress)
1632 *NonAlignedAddress = address;
1635 return address;
1636 #endif
1637 #endif
1641 void pci_free_consistent(void* addr)
1643 #ifdef __MORPHOS__
1644 FreeVecDMA(addr);
1645 #else
1646 FREEVEC( addr );
1647 #endif
1650 #ifdef __amigaos4__
1651 static ULONG ResetHandler(struct ExceptionContext *ctx, struct ExecBase *pExecBase, struct CardData *card)
1653 struct PCIDevice *dev = card->pci_dev;
1655 ClearMask8(card, card->mtbase, MT_DMA_CONTROL, MT_PDMA0_START | MT_PDMA4_START | MT_RDMA0_MASK | MT_RDMA1_MASK);
1656 WriteMask8(card, card->mtbase, MT_INTR_MASK, MT_DMA_FIFO_MASK | MT_PDMA0_MASK | MT_RDMA0_MASK | MT_RDMA1_MASK);
1658 return 0UL;
1661 void AddResetHandler(struct CardData *card)
1663 static struct Interrupt interrupt;
1665 interrupt.is_Code = (void (*)())ResetHandler;
1666 interrupt.is_Data = (APTR) card;
1667 interrupt.is_Node.ln_Pri = 0;
1668 interrupt.is_Node.ln_Type = NT_EXTINTERRUPT;
1669 interrupt.is_Node.ln_Name = "reset handler";
1671 IExec->AddResetCallback( &interrupt );
1673 #endif
1677 #if 0
1678 if ((INBYTE(card->iobase + CCS_I2C_STATUS) & CCS_I2C_EPROM) == 0)
1680 DEBUGPRINTF("No EEPROM found!\n");
1682 else
1684 DEBUGPRINTF("EEPROM found!\n");
1688 /*OUTBYTE(card->iobase + CCS_I2C_DATA, 0x11);
1689 OUTBYTE(card->iobase + CCS_I2C_ADDR, 0);
1691 while (INBYTE(card->iobase + CCS_I2C_STATUS) & CCS_I2C_BUSY)
1694 OUTBYTE(card->iobase + CCS_I2C_DEV_ADDRESS, 0xA0);
1695 DELAY(1);*/
1697 for (i = 0; i < 6; i++)
1699 OUTBYTE(card->iobase + CCS_I2C_ADDR, i);
1701 while (INBYTE(card->iobase + CCS_I2C_STATUS) & CCS_I2C_BUSY)
1705 OUTBYTE(card->iobase + CCS_I2C_DEV_ADDRESS, 0xA0);
1707 while (INBYTE(card->iobase + CCS_I2C_STATUS) & CCS_I2C_BUSY)
1712 DEBUGPRINTF("%d = %x\n",i, INBYTE(card->iobase + CCS_I2C_DATA));
1713 DELAY(1);
1715 #endif