[ALSA] snd-emu10k1: Added support for emu1010, including E-Mu 1212m and E-Mu 1820m
Signed-off-by: James Courtier-Dutton <James@superbug.co.uk> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
This commit is contained in:
parent
5986a2ec35
commit
9f4bd5dde8
|
@ -188,7 +188,35 @@
|
|||
#define HCFG_LEGACYINT 0x00200000 /* 1 = legacy event captured. Write 1 to clear. */
|
||||
/* NOTE: The rest of the bits in this register */
|
||||
/* _are_ relevant under Linux. */
|
||||
#define HCFG_CODECFORMAT_MASK 0x00070000 /* CODEC format */
|
||||
#define HCFG_PUSH_BUTTON_ENABLE 0x00100000 /* Enables Volume Inc/Dec and Mute functions */
|
||||
#define HCFG_BAUD_RATE 0x00080000 /* 0 = 48kHz, 1 = 44.1kHz */
|
||||
#define HCFG_EXPANDED_MEM 0x00040000 /* 1 = any 16M of 4G addr, 0 = 32M of 2G addr */
|
||||
#define HCFG_CODECFORMAT_MASK 0x00030000 /* CODEC format */
|
||||
|
||||
/* Specific to Alice2, CA0102 */
|
||||
#define HCFG_CODECFORMAT_AC97_1 0x00000000 /* AC97 CODEC format -- Ver 1.03 */
|
||||
#define HCFG_CODECFORMAT_AC97_2 0x00010000 /* AC97 CODEC format -- Ver 2.1 */
|
||||
#define HCFG_AUTOMUTE_ASYNC 0x00008000 /* When set, the async sample rate convertors */
|
||||
/* will automatically mute their output when */
|
||||
/* they are not rate-locked to the external */
|
||||
/* async audio source */
|
||||
#define HCFG_AUTOMUTE_SPDIF 0x00004000 /* When set, the async sample rate convertors */
|
||||
/* will automatically mute their output when */
|
||||
/* the SPDIF V-bit indicates invalid audio */
|
||||
#define HCFG_EMU32_SLAVE 0x00002000 /* 0 = Master, 1 = Slave. Slave for EMU1010 */
|
||||
#define HCFG_SLOW_RAMP 0x00001000 /* Increases Send Smoothing time constant */
|
||||
/* 0x00000800 not used on Alice2 */
|
||||
#define HCFG_PHASE_TRACK_MASK 0x00000700 /* When set, forces corresponding input to */
|
||||
/* phase track the previous input. */
|
||||
/* I2S0 can phase track the last S/PDIF input */
|
||||
#define HCFG_I2S_ASRC_ENABLE 0x00000070 /* When set, enables asynchronous sample rate */
|
||||
/* conversion for the corresponding */
|
||||
/* I2S format input */
|
||||
/* Rest of HCFG 0x0000000f same as below. LOCKSOUNDCACHE etc. */
|
||||
|
||||
|
||||
|
||||
/* Older chips */
|
||||
#define HCFG_CODECFORMAT_AC97 0x00000000 /* AC97 CODEC format -- Primary Output */
|
||||
#define HCFG_CODECFORMAT_I2S 0x00010000 /* I2S CODEC format -- Secondary (Rear) Output */
|
||||
#define HCFG_GPINPUT0 0x00004000 /* External pin112 */
|
||||
|
@ -886,6 +914,280 @@
|
|||
#define A_HIWORD_RESULT_MASK 0x007ff000
|
||||
#define A_HIWORD_OPA_MASK 0x000007ff
|
||||
|
||||
/************************************************************************************************/
|
||||
/* EMU1010m HANA FPGA registers */
|
||||
/************************************************************************************************/
|
||||
#define EMU_HANA_DESTHI 0x00 /* 0000xxx 3 bits Link Destination */
|
||||
#define EMU_HANA_DESTLO 0x01 /* 00xxxxx 5 bits */
|
||||
#define EMU_HANA_SRCHI 0x02 /* 0000xxx 3 bits Link Source */
|
||||
#define EMU_HANA_SRCLO 0x03 /* 00xxxxx 5 bits */
|
||||
#define EMU_HANA_DOCK_PWR 0x04 /* 000000x 1 bits Audio Dock power */
|
||||
#define EMU_HANA_DOCK_PWR_ON 0x01 /* Audio Dock power on */
|
||||
#define EMU_HANA_WCLOCK 0x05 /* 0000xxx 3 bits Word Clock source select */
|
||||
/* Must be written after power on to reset DLL */
|
||||
/* One is unable to detect the Audio dock without this */
|
||||
#define EMU_HANA_WCLOCK_SRC_MASK 0x07
|
||||
#define EMU_HANA_WCLOCK_INT_48K 0x00
|
||||
#define EMU_HANA_WCLOCK_INT_44_1K 0x01
|
||||
#define EMU_HANA_WCLOCK_HANA_SPDIF_IN 0x02
|
||||
#define EMU_HANA_WCLOCK_HANA_ADAT_IN 0x03
|
||||
#define EMU_HANA_WCLOCK_SYNC_BNCN 0x04
|
||||
#define EMU_HANA_WCLOCK_2ND_HANA 0x05
|
||||
#define EMU_HANA_WCLOCK_SRC_RESERVED 0x06
|
||||
#define EMU_HANA_WCLOCK_OFF 0x07 /* For testing, forces fallback to DEFCLOCK */
|
||||
#define EMU_HANA_WCLOCK_MULT_MASK 0x18
|
||||
#define EMU_HANA_WCLOCK_1X 0x00
|
||||
#define EMU_HANA_WCLOCK_2X 0x08
|
||||
#define EMU_HANA_WCLOCK_4X 0x10
|
||||
#define EMU_HANA_WCLOCK_MULT_RESERVED 0x18
|
||||
|
||||
#define EMU_HANA_DEFCLOCK 0x06 /* 000000x 1 bits Default Word Clock */
|
||||
#define EMU_HANA_DEFCLOCK_48K 0x00
|
||||
#define EMU_HANA_DEFCLOCK_44_1K 0x01
|
||||
|
||||
#define EMU_HANA_UNMUTE 0x07 /* 000000x 1 bits Mute all audio outputs */
|
||||
#define EMU_MUTE 0x00
|
||||
#define EMU_UNMUTE 0x01
|
||||
|
||||
#define EMU_HANA_FPGA_CONFIG 0x08 /* 00000xx 2 bits Config control of FPGAs */
|
||||
#define EMU_HANA_FPGA_CONFIG_AUDIODOCK 0x01 /* Set in order to program FPGA on Audio Dock */
|
||||
#define EMU_HANA_FPGA_CONFIG_HANA 0x02 /* Set in order to program FPGA on Hana */
|
||||
|
||||
#define EMU_HANA_IRQ_ENABLE 0x09 /* 000xxxx 4 bits IRQ Enable */
|
||||
#define EMU_HANA_IRQ_WCLK_CHANGED 0x01
|
||||
#define EMU_HANA_IRQ_ADAT 0x02
|
||||
#define EMU_HANA_IRQ_DOCK 0x04
|
||||
#define EMU_HANA_IRQ_DOCK_LOST 0x08
|
||||
|
||||
#define EMU_HANA_SPDIF_MODE 0x0a /* 00xxxxx 5 bits SPDIF MODE */
|
||||
#define EMU_HANA_SPDIF_MODE_TX_COMSUMER 0x00
|
||||
#define EMU_HANA_SPDIF_MODE_TX_PRO 0x01
|
||||
#define EMU_HANA_SPDIF_MODE_TX_NOCOPY 0x02
|
||||
#define EMU_HANA_SPDIF_MODE_RX_COMSUMER 0x00
|
||||
#define EMU_HANA_SPDIF_MODE_RX_PRO 0x04
|
||||
#define EMU_HANA_SPDIF_MODE_RX_NOCOPY 0x08
|
||||
#define EMU_HANA_SPDIF_MODE_RX_INVALID 0x10
|
||||
|
||||
#define EMU_HANA_OPTICAL_TYPE 0x0b /* 00000xx 2 bits ADAT or SPDIF in/out */
|
||||
#define EMU_HANA_OPTICAL_IN_SPDIF 0x00
|
||||
#define EMU_HANA_OPTICAL_IN_ADAT 0x01
|
||||
#define EMU_HANA_OPTICAL_OUT_SPDIF 0x00
|
||||
#define EMU_HANA_OPTICAL_OUT_ADAT 0x02
|
||||
|
||||
#define EMU_HANA_MIDI 0x0c /* 000000x 1 bit Control MIDI */
|
||||
#define EMU_HANA_MIDI_IN_FROM_HAMOA 0x00 /* HAMOA MIDI in to Alice 2 MIDI B */
|
||||
#define EMU_HANA_MIDI_IN_FROM_DOCK 0x01 /* Audio Dock MIDI in to Alice 2 MIDI B */
|
||||
|
||||
#define EMU_HANA_DOCK_LEDS_1 0x0d /* 000xxxx 4 bit Audio Dock LEDs */
|
||||
#define EMU_HANA_DOCK_LEDS_1_MIDI1 0x01 /* MIDI 1 LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_1_MIDI2 0x02 /* MIDI 2 LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_1_SMPTE_IN 0x04 /* SMPTE IN LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_1_SMPTE_OUT 0x08 /* SMPTE OUT LED on */
|
||||
|
||||
#define EMU_HANA_DOCK_LEDS_2 0x0e /* 0xxxxxx 6 bit Audio Dock LEDs */
|
||||
#define EMU_HANA_DOCK_LEDS_2_44K 0x01 /* 44.1 kHz LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_2_48K 0x02 /* 48 kHz LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_2_96K 0x04 /* 96 kHz LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_2_192K 0x08 /* 192 kHz LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_2_LOCK 0x10 /* LOCK LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_2_EXT 0x20 /* EXT LED on */
|
||||
|
||||
#define EMU_HANA_DOCK_LEDS_3 0x0f /* 0xxxxxx 6 bit Audio Dock LEDs */
|
||||
#define EMU_HANA_DOCK_LEDS_3_CLIP_A 0x01 /* Mic A Clip LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_3_CLIP_B 0x02 /* Mic B Clip LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_3_SIGNAL_A 0x04 /* Signal A Clip LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_3_SIGNAL_B 0x08 /* Signal B Clip LED on */
|
||||
#define EMU_HANA_DOCK_LEDS_3_MANUAL_CLIP 0x10 /* Manual Clip detection */
|
||||
#define EMU_HANA_DOCK_LEDS_3_MANUAL_SIGNAL 0x20 /* Manual Signal detection */
|
||||
|
||||
#define EMU_HANA_DOCK_PADS 0x10 /* 0000xxx 3 bit Audio Dock ADC 14dB pads */
|
||||
#define EMU_HANA_DOCK_PAD1 0x01 /* 14dB Attenuation on ADC 1 */
|
||||
#define EMU_HANA_DOCK_PAD2 0x02 /* 14dB Attenuation on ADC 2 */
|
||||
#define EMU_HANA_DOCK_PAD3 0x04 /* 14dB Attenuation on ADC 3 */
|
||||
|
||||
#define EMU_HANA_DOCK_MISC 0x11 /* 0xxxxxx 6 bit Audio Dock misc bits */
|
||||
#define EMU_HANA_DOCK_DAC1_MUTE 0x01 /* DAC 1 Mute */
|
||||
#define EMU_HANA_DOCK_DAC2_MUTE 0x02 /* DAC 2 Mute */
|
||||
#define EMU_HANA_DOCK_DAC3_MUTE 0x04 /* DAC 3 Mute */
|
||||
#define EMU_HANA_DOCK_DAC4_MUTE 0x08 /* DAC 4 Mute */
|
||||
#define EMU_HANA_DOCK_PHONES_192_DAC1 0x00 /* DAC 1 Headphones source at 192kHz */
|
||||
#define EMU_HANA_DOCK_PHONES_192_DAC2 0x10 /* DAC 2 Headphones source at 192kHz */
|
||||
#define EMU_HANA_DOCK_PHONES_192_DAC3 0x20 /* DAC 3 Headphones source at 192kHz */
|
||||
#define EMU_HANA_DOCK_PHONES_192_DAC4 0x30 /* DAC 4 Headphones source at 192kHz */
|
||||
|
||||
#define EMU_HANA_UNKNOWN12 0x12 /* 0xxxxxx 6 bit Unknown12 */
|
||||
#define EMU_HANA_UNKNOWN13 0x13 /* 0xxxxxx 6 bit Unknown13 */
|
||||
/* 0x14 - 0x1f Unused R/W registers */
|
||||
#define EMU_HANA_IRQ_STATUS 0x20 /* 000xxxx 4 bits IRQ Status */
|
||||
#if 0 /* Already defined for reg 0x09 IRQ_ENABLE */
|
||||
#define EMU_HANA_IRQ_WCLK_CHANGED 0x01
|
||||
#define EMU_HANA_IRQ_ADAT 0x02
|
||||
#define EMU_HANA_IRQ_DOCK 0x04
|
||||
#define EMU_HANA_IRQ_DOCK_LOST 0x08
|
||||
#endif
|
||||
|
||||
#define EMU_HANA_OPTION_CARDS 0x21 /* 000xxxx 4 bits Presence of option cards */
|
||||
#define EMU_HANA_OPTION_HAMOA 0x01 /* HAMOA card present */
|
||||
#define EMU_HANA_OPTION_SYNC 0x02 /* Sync card present */
|
||||
#define EMU_HANA_OPTION_DOCK_ONLINE 0x04 /* Audio Dock online and FPGA configured */
|
||||
#define EMU_HANA_OPTION_DOCK_OFFLINE 0x08 /* Audio Dock online and FPGA not configured */
|
||||
|
||||
#define EMU_HANA_ID 0x22 /* 1010101 7 bits ID byte & 0x7f = 0x55 */
|
||||
|
||||
#define EMU_HANA_MAJOR_REV 0x23 /* 0000xxx 3 bit Hana FPGA Major rev */
|
||||
#define EMU_HANA_MINOR_REV 0x24 /* 0000xxx 3 bit Hana FPGA Minor rev */
|
||||
|
||||
#define EMU_DOCK_MAJOR_REV 0x25 /* 0000xxx 3 bit Audio Dock FPGA Major rev */
|
||||
#define EMU_DOCK_MINOR_REV 0x26 /* 0000xxx 3 bit Audio Dock FPGA Minor rev */
|
||||
|
||||
#define EMU_DOCK_BOARD_ID 0x27 /* 00000xx 2 bits Audio Dock ID pins */
|
||||
#define EMU_DOCK_BOARD_ID0 0x00 /* ID bit 0 */
|
||||
#define EMU_DOCK_BOARD_ID1 0x03 /* ID bit 1 */
|
||||
|
||||
#define EMU_HANA_WC_SPDIF_HI 0x28 /* 0xxxxxx 6 bit SPDIF IN Word clock, upper 6 bits */
|
||||
#define EMU_HANA_WC_SPDIF_LO 0x29 /* 0xxxxxx 6 bit SPDIF IN Word clock, lower 6 bits */
|
||||
|
||||
#define EMU_HANA_WC_ADAT_HI 0x2a /* 0xxxxxx 6 bit ADAT IN Word clock, upper 6 bits */
|
||||
#define EMU_HANA_WC_ADAT_LO 0x2b /* 0xxxxxx 6 bit ADAT IN Word clock, lower 6 bits */
|
||||
|
||||
#define EMU_HANA_WC_BNC_LO 0x2c /* 0xxxxxx 6 bit BNC IN Word clock, lower 6 bits */
|
||||
#define EMU_HANA_WC_BNC_HI 0x2d /* 0xxxxxx 6 bit BNC IN Word clock, upper 6 bits */
|
||||
|
||||
#define EMU_HANA2_WC_SPDIF_HI 0x2e /* 0xxxxxx 6 bit HANA2 SPDIF IN Word clock, upper 6 bits */
|
||||
#define EMU_HANA2_WC_SPDIF_LO 0x2f /* 0xxxxxx 6 bit HANA2 SPDIF IN Word clock, lower 6 bits */
|
||||
/* 0x30 - 0x3f Unused Read only registers */
|
||||
|
||||
/************************************************************************************************/
|
||||
/* EMU1010m HANA Destinations */
|
||||
/************************************************************************************************/
|
||||
#define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_2 0x0001 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_3 0x0002 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_4 0x0003 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_5 0x0004 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_6 0x0005 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_7 0x0006 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_8 0x0007 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_9 0x0008 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_A 0x0009 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_B 0x000a /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_C 0x000b /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_D 0x000c /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_E 0x000d /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_F 0x000e /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_DOCK_DAC1_LEFT1 0x0100 /* Audio Dock DAC1 Left, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_DAC1_LEFT2 0x0101 /* Audio Dock DAC1 Left, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC1_LEFT3 0x0102 /* Audio Dock DAC1 Left, 3rd or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC1_LEFT4 0x0103 /* Audio Dock DAC1 Left, 4th or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC1_RIGHT1 0x0104 /* Audio Dock DAC1 Right, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_DAC1_RIGHT2 0x0105 /* Audio Dock DAC1 Right, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC1_RIGHT3 0x0106 /* Audio Dock DAC1 Right, 3rd or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC1_RIGHT4 0x0107 /* Audio Dock DAC1 Right, 4th or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC2_LEFT1 0x0108 /* Audio Dock DAC2 Left, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_DAC2_LEFT2 0x0109 /* Audio Dock DAC2 Left, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC2_LEFT3 0x010a /* Audio Dock DAC2 Left, 3rd or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC2_LEFT4 0x010b /* Audio Dock DAC2 Left, 4th or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC2_RIGHT1 0x010c /* Audio Dock DAC2 Right, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_DAC2_RIGHT2 0x010d /* Audio Dock DAC2 Right, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC2_RIGHT3 0x010e /* Audio Dock DAC2 Right, 3rd or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC2_RIGHT4 0x010f /* Audio Dock DAC2 Right, 4th or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC3_LEFT1 0x0110 /* Audio Dock DAC1 Left, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_DAC3_LEFT2 0x0111 /* Audio Dock DAC1 Left, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC3_LEFT3 0x0112 /* Audio Dock DAC1 Left, 3rd or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC3_LEFT4 0x0113 /* Audio Dock DAC1 Left, 4th or 192kHz */
|
||||
#define EMU_DST_DOCK_PHONES_LEFT1 0x0112 /* Audio Dock PHONES Left, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_PHONES_LEFT2 0x0113 /* Audio Dock PHONES Left, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC3_RIGHT1 0x0114 /* Audio Dock DAC1 Right, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_DAC3_RIGHT2 0x0115 /* Audio Dock DAC1 Right, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC3_RIGHT3 0x0116 /* Audio Dock DAC1 Right, 3rd or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC3_RIGHT4 0x0117 /* Audio Dock DAC1 Right, 4th or 192kHz */
|
||||
#define EMU_DST_DOCK_PHONES_RIGHT1 0x0116 /* Audio Dock PHONES Right, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_PHONES_RIGHT2 0x0117 /* Audio Dock PHONES Right, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC4_LEFT1 0x0118 /* Audio Dock DAC2 Left, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_DAC4_LEFT2 0x0119 /* Audio Dock DAC2 Left, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC4_LEFT3 0x011a /* Audio Dock DAC2 Left, 3rd or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC4_LEFT4 0x011b /* Audio Dock DAC2 Left, 4th or 192kHz */
|
||||
#define EMU_DST_DOCK_SPDIF_LEFT1 0x011a /* Audio Dock SPDIF Left, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_SPDIF_LEFT2 0x011b /* Audio Dock SPDIF Left, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC4_RIGHT1 0x011c /* Audio Dock DAC2 Right, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_DAC4_RIGHT2 0x011d /* Audio Dock DAC2 Right, 2nd or 96kHz */
|
||||
#define EMU_DST_DOCK_DAC4_RIGHT3 0x011e /* Audio Dock DAC2 Right, 3rd or 192kHz */
|
||||
#define EMU_DST_DOCK_DAC4_RIGHT4 0x011f /* Audio Dock DAC2 Right, 4th or 192kHz */
|
||||
#define EMU_DST_DOCK_SPDIF_RIGHT1 0x011e /* Audio Dock SPDIF Right, 1st or 48kHz only */
|
||||
#define EMU_DST_DOCK_SPDIF_RIGHT2 0x011f /* Audio Dock SPDIF Right, 2nd or 96kHz */
|
||||
#define EMU_DST_HANA_SPDIF_LEFT1 0x0200 /* Hana SPDIF Left, 1st or 48kHz only */
|
||||
#define EMU_DST_HANA_SPDIF_LEFT2 0x0202 /* Hana SPDIF Left, 2nd or 96kHz */
|
||||
#define EMU_DST_HANA_SPDIF_RIGHT1 0x0201 /* Hana SPDIF Right, 1st or 48kHz only */
|
||||
#define EMU_DST_HANA_SPDIF_RIGHT2 0x0203 /* Hana SPDIF Right, 2nd or 96kHz */
|
||||
#define EMU_DST_HAMOA_DAC_LEFT1 0x0300 /* Hamoa DAC Left, 1st or 48kHz only */
|
||||
#define EMU_DST_HAMOA_DAC_LEFT2 0x0302 /* Hamoa DAC Left, 2nd or 96kHz */
|
||||
#define EMU_DST_HAMOA_DAC_LEFT3 0x0304 /* Hamoa DAC Left, 3rd or 192kHz */
|
||||
#define EMU_DST_HAMOA_DAC_LEFT4 0x0306 /* Hamoa DAC Left, 4th or 192kHz */
|
||||
#define EMU_DST_HAMOA_DAC_RIGHT1 0x0301 /* Hamoa DAC Right, 1st or 48kHz only */
|
||||
#define EMU_DST_HAMOA_DAC_RIGHT2 0x0303 /* Hamoa DAC Right, 2nd or 96kHz */
|
||||
#define EMU_DST_HAMOA_DAC_RIGHT3 0x0305 /* Hamoa DAC Right, 3rd or 192kHz */
|
||||
#define EMU_DST_HAMOA_DAC_RIGHT4 0x0307 /* Hamoa DAC Right, 4th or 192kHz */
|
||||
#define EMU_DST_HANA_ADAT 0x0400 /* Hana ADAT 8 channel out +0 to +7 */
|
||||
#define EMU_DST_ALICE_I2S0_LEFT 0x0500 /* Alice2 I2S0 Left */
|
||||
#define EMU_DST_ALICE_I2S0_RIGHT 0x0501 /* Alice2 I2S0 Right */
|
||||
#define EMU_DST_ALICE_I2S1_LEFT 0x0600 /* Alice2 I2S1 Left */
|
||||
#define EMU_DST_ALICE_I2S1_RIGHT 0x0601 /* Alice2 I2S1 Right */
|
||||
#define EMU_DST_ALICE_I2S2_LEFT 0x0700 /* Alice2 I2S2 Left */
|
||||
#define EMU_DST_ALICE_I2S2_RIGHT 0x0701 /* Alice2 I2S2 Right */
|
||||
|
||||
/************************************************************************************************/
|
||||
/* EMU1010m HANA Sources */
|
||||
/************************************************************************************************/
|
||||
#define EMU_SRC_SILENCE 0x0000 /* Silence */
|
||||
#define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */
|
||||
#define EMU_SRC_DOCK_MIC_A2 0x0101 /* Audio Dock Mic A, 2nd or 96kHz */
|
||||
#define EMU_SRC_DOCK_MIC_A3 0x0102 /* Audio Dock Mic A, 3rd or 192kHz */
|
||||
#define EMU_SRC_DOCK_MIC_A4 0x0103 /* Audio Dock Mic A, 4th or 192kHz */
|
||||
#define EMU_SRC_DOCK_MIC_B1 0x0104 /* Audio Dock Mic B, 1st or 48kHz only */
|
||||
#define EMU_SRC_DOCK_MIC_B2 0x0105 /* Audio Dock Mic B, 2nd or 96kHz */
|
||||
#define EMU_SRC_DOCK_MIC_B3 0x0106 /* Audio Dock Mic B, 3rd or 192kHz */
|
||||
#define EMU_SRC_DOCK_MIC_B4 0x0107 /* Audio Dock Mic B, 4th or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC1_LEFT1 0x0108 /* Audio Dock ADC1 Left, 1st or 48kHz only */
|
||||
#define EMU_SRC_DOCK_ADC1_LEFT2 0x0109 /* Audio Dock ADC1 Left, 2nd or 96kHz */
|
||||
#define EMU_SRC_DOCK_ADC1_LEFT3 0x010a /* Audio Dock ADC1 Left, 3rd or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC1_LEFT4 0x010b /* Audio Dock ADC1 Left, 4th or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC1_RIGHT1 0x010c /* Audio Dock ADC1 Right, 1st or 48kHz only */
|
||||
#define EMU_SRC_DOCK_ADC1_RIGHT2 0x010d /* Audio Dock ADC1 Right, 2nd or 96kHz */
|
||||
#define EMU_SRC_DOCK_ADC1_RIGHT3 0x010e /* Audio Dock ADC1 Right, 3rd or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC1_RIGHT4 0x010f /* Audio Dock ADC1 Right, 4th or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC2_LEFT1 0x0110 /* Audio Dock ADC2 Left, 1st or 48kHz only */
|
||||
#define EMU_SRC_DOCK_ADC2_LEFT2 0x0111 /* Audio Dock ADC2 Left, 2nd or 96kHz */
|
||||
#define EMU_SRC_DOCK_ADC2_LEFT3 0x0112 /* Audio Dock ADC2 Left, 3rd or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC2_LEFT4 0x0113 /* Audio Dock ADC2 Left, 4th or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC2_RIGHT1 0x0114 /* Audio Dock ADC2 Right, 1st or 48kHz only */
|
||||
#define EMU_SRC_DOCK_ADC2_RIGHT2 0x0115 /* Audio Dock ADC2 Right, 2nd or 96kHz */
|
||||
#define EMU_SRC_DOCK_ADC2_RIGHT3 0x0116 /* Audio Dock ADC2 Right, 3rd or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC2_RIGHT4 0x0117 /* Audio Dock ADC2 Right, 4th or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC3_LEFT1 0x0118 /* Audio Dock ADC3 Left, 1st or 48kHz only */
|
||||
#define EMU_SRC_DOCK_ADC3_LEFT2 0x0119 /* Audio Dock ADC3 Left, 2nd or 96kHz */
|
||||
#define EMU_SRC_DOCK_ADC3_LEFT3 0x011a /* Audio Dock ADC3 Left, 3rd or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC3_LEFT4 0x011b /* Audio Dock ADC3 Left, 4th or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC3_RIGHT1 0x011c /* Audio Dock ADC3 Right, 1st or 48kHz only */
|
||||
#define EMU_SRC_DOCK_ADC3_RIGHT2 0x011d /* Audio Dock ADC3 Right, 2nd or 96kHz */
|
||||
#define EMU_SRC_DOCK_ADC3_RIGHT3 0x011e /* Audio Dock ADC3 Right, 3rd or 192kHz */
|
||||
#define EMU_SRC_DOCK_ADC3_RIGHT4 0x011f /* Audio Dock ADC3 Right, 4th or 192kHz */
|
||||
#define EMU_SRC_HAMOA_ADC_LEFT1 0x0200 /* Hamoa ADC Left, 1st or 48kHz only */
|
||||
#define EMU_SRC_HAMOA_ADC_LEFT2 0x0202 /* Hamoa ADC Left, 2nd or 96kHz */
|
||||
#define EMU_SRC_HAMOA_ADC_LEFT3 0x0204 /* Hamoa ADC Left, 3rd or 192kHz */
|
||||
#define EMU_SRC_HAMOA_ADC_LEFT4 0x0206 /* Hamoa ADC Left, 4th or 192kHz */
|
||||
#define EMU_SRC_HAMOA_ADC_RIGHT1 0x0201 /* Hamoa ADC Right, 1st or 48kHz only */
|
||||
#define EMU_SRC_HAMOA_ADC_RIGHT2 0x0203 /* Hamoa ADC Right, 2nd or 96kHz */
|
||||
#define EMU_SRC_HAMOA_ADC_RIGHT3 0x0205 /* Hamoa ADC Right, 3rd or 192kHz */
|
||||
#define EMU_SRC_HAMOA_ADC_RIGHT4 0x0207 /* Hamoa ADC Right, 4th or 192kHz */
|
||||
#define EMU_SRC_ALICE_EMU32A 0x0300 /* Alice2 EMU32a 16 outputs. +0 to +0xf */
|
||||
#define EMU_SRC_ALICE_EMU32B 0x0310 /* Alice2 EMU32b 16 outputs. +0 to +0xf */
|
||||
#define EMU_SRC_HANA_ADAT 0x0400 /* Hana ADAT 8 channel in +0 to +7 */
|
||||
#define EMU_SRC_HANA_SPDIF_LEFT1 0x0500 /* Hana SPDIF Left, 1st or 48kHz only */
|
||||
#define EMU_SRC_HANA_SPDIF_LEFT2 0x0502 /* Hana SPDIF Left, 2nd or 96kHz */
|
||||
#define EMU_SRC_HANA_SPDIF_RIGHT1 0x0501 /* Hana SPDIF Right, 1st or 48kHz only */
|
||||
#define EMU_SRC_HANA_SPDIF_RIGHT2 0x0503 /* Hana SPDIF Right, 2nd or 96kHz */
|
||||
/* 0x600 and 0x700 no used */
|
||||
|
||||
/* ------------------- STRUCTURES -------------------- */
|
||||
|
||||
|
@ -1063,7 +1365,7 @@ struct snd_emu_chip_details {
|
|||
unsigned char spdif_bug; /* Has Spdif phasing bug */
|
||||
unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */
|
||||
unsigned char ecard; /* APS EEPROM */
|
||||
unsigned char emu1212m; /* EMU 1212m card */
|
||||
unsigned char emu1010; /* EMU 1010m card */
|
||||
unsigned char spi_dac; /* SPI interface for DAC */
|
||||
unsigned char i2c_adc; /* I2C interface for ADC */
|
||||
unsigned char adc_1361t; /* Use Philips 1361T ADC */
|
||||
|
@ -1072,6 +1374,11 @@ struct snd_emu_chip_details {
|
|||
const char *id; /* for backward compatibility - can be NULL if not needed */
|
||||
};
|
||||
|
||||
struct snd_emu1010 {
|
||||
unsigned int output_source[64];
|
||||
unsigned int input_source[64];
|
||||
};
|
||||
|
||||
struct snd_emu10k1 {
|
||||
int irq;
|
||||
|
||||
|
@ -1132,6 +1439,7 @@ struct snd_emu10k1 {
|
|||
int p16v_device_offset;
|
||||
u32 p16v_capture_source;
|
||||
u32 p16v_capture_channel;
|
||||
struct snd_emu1010 emu1010;
|
||||
struct snd_emu10k1_pcm_mixer pcm_mixer[32];
|
||||
struct snd_emu10k1_pcm_mixer efx_pcm_mixer[NUM_EFX_PLAYBACK];
|
||||
struct snd_kcontrol *ctl_send_routing;
|
||||
|
@ -1208,6 +1516,9 @@ void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned i
|
|||
unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn);
|
||||
void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
|
||||
int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data);
|
||||
int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value);
|
||||
int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value);
|
||||
int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, int dst, int src);
|
||||
unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
|
||||
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
|
||||
void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
* Creative Labs, Inc.
|
||||
* Routines for control of EMU10K1 chips
|
||||
*
|
||||
* Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
|
||||
* Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
|
||||
* Added support for Audigy 2 Value.
|
||||
* Added EMU 1010 support.
|
||||
* General bug fixes and enhancements.
|
||||
*
|
||||
*
|
||||
* BUGS:
|
||||
|
@ -41,6 +43,7 @@
|
|||
|
||||
#include <sound/core.h>
|
||||
#include <sound/emu10k1.h>
|
||||
#include <linux/firmware.h>
|
||||
#include "p16v.h"
|
||||
#include "tina2.h"
|
||||
|
||||
|
@ -239,6 +242,10 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
|
|||
snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
|
||||
}
|
||||
|
||||
if (emu->card_capabilities->emu1010) {
|
||||
outl(HCFG_AUTOMUTE_ASYNC |
|
||||
HCFG_EMU32_SLAVE |
|
||||
HCFG_AUDIOENABLE, emu->port + HCFG);
|
||||
/*
|
||||
* Hokay, setup HCFG
|
||||
* Mute Disable Audio = 0
|
||||
|
@ -246,7 +253,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
|
|||
* Lock Sound Memory = 0
|
||||
* Auto Mute = 1
|
||||
*/
|
||||
if (emu->audigy) {
|
||||
} else if (emu->audigy) {
|
||||
if (emu->revision == 4) /* audigy2 */
|
||||
outl(HCFG_AUDIOENABLE |
|
||||
HCFG_AC3ENABLE_CDSPDIF |
|
||||
|
@ -265,8 +272,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
|
|||
outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
|
||||
|
||||
if (enable_ir) { /* enable IR for SB Live */
|
||||
if ( emu->card_capabilities->emu1212m) {
|
||||
; /* Disable all access to A_IOCFG for the emu1212m */
|
||||
if (emu->card_capabilities->emu1010) {
|
||||
; /* Disable all access to A_IOCFG for the emu1010 */
|
||||
} else if (emu->audigy) {
|
||||
unsigned int reg = inl(emu->port + A_IOCFG);
|
||||
outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
|
||||
|
@ -284,8 +291,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
|
|||
}
|
||||
}
|
||||
|
||||
if ( emu->card_capabilities->emu1212m) {
|
||||
; /* Disable all access to A_IOCFG for the emu1212m */
|
||||
if (emu->card_capabilities->emu1010) {
|
||||
; /* Disable all access to A_IOCFG for the emu1010 */
|
||||
} else if (emu->audigy) { /* enable analog output */
|
||||
unsigned int reg = inl(emu->port + A_IOCFG);
|
||||
outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
|
||||
|
@ -302,8 +309,8 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
|
|||
outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
|
||||
|
||||
/* Enable analog/digital outs on audigy */
|
||||
if ( emu->card_capabilities->emu1212m) {
|
||||
; /* Disable all access to A_IOCFG for the emu1212m */
|
||||
if (emu->card_capabilities->emu1010) {
|
||||
; /* Disable all access to A_IOCFG for the emu1010 */
|
||||
} else if (emu->audigy) {
|
||||
outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
|
||||
|
||||
|
@ -596,133 +603,417 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
|
||||
static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * filename)
|
||||
{
|
||||
if (reg<0 || reg>0x3f)
|
||||
return 1;
|
||||
reg+=0x40; /* 0x40 upwards are registers. */
|
||||
if (value<0 || value>0x3f) /* 0 to 0x3f are values */
|
||||
return 1;
|
||||
int err;
|
||||
int n, i;
|
||||
int reg;
|
||||
int value;
|
||||
const struct firmware *fw_entry;
|
||||
|
||||
if ((err = request_firmware(&fw_entry, filename, &emu->pci->dev)) != 0) {
|
||||
snd_printk(KERN_ERR "firmware: %s not found. Err=%d\n",filename, err);
|
||||
return err;
|
||||
}
|
||||
snd_printk(KERN_INFO "firmware size=0x%x\n",fw_entry->size);
|
||||
if (fw_entry->size != 0x133a4) {
|
||||
snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* The FPGA is a Xilinx Spartan IIE XC2S50E */
|
||||
/* GPIO7 -> FPGA PGMN
|
||||
* GPIO6 -> FPGA CCLK
|
||||
* GPIO5 -> FPGA DIN
|
||||
* FPGA CONFIG OFF -> FPGA PGMN
|
||||
*/
|
||||
outl(0x00, emu->port + A_IOCFG); /* Set PGMN low for 1uS. */
|
||||
udelay(1);
|
||||
outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */
|
||||
udelay(100); /* Allow FPGA memory to clean */
|
||||
for(n = 0; n < fw_entry->size; n++) {
|
||||
value=fw_entry->data[n];
|
||||
for(i = 0; i < 8; i++) {
|
||||
reg = 0x80;
|
||||
if (value & 0x1)
|
||||
reg = reg | 0x20;
|
||||
value = value >> 1;
|
||||
outl(reg, emu->port + A_IOCFG);
|
||||
outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
|
||||
outl(value, emu->port + A_IOCFG);
|
||||
outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
|
||||
outl(reg | 0x40, emu->port + A_IOCFG);
|
||||
}
|
||||
}
|
||||
/* After programming, set GPIO bit 4 high again. */
|
||||
outl(0x10, emu->port + A_IOCFG);
|
||||
|
||||
|
||||
release_firmware(fw_entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
|
||||
{
|
||||
if (reg<0 || reg>0x3f)
|
||||
return 1;
|
||||
reg+=0x40; /* 0x40 upwards are registers. */
|
||||
outl(reg, emu->port + A_IOCFG);
|
||||
outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
|
||||
*value = inl(emu->port + A_IOCFG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value)
|
||||
{
|
||||
snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) );
|
||||
snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) );
|
||||
snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) );
|
||||
snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu)
|
||||
static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
|
||||
{
|
||||
unsigned int i;
|
||||
int tmp;
|
||||
int tmp,tmp2;
|
||||
int reg;
|
||||
int err;
|
||||
const char *hana_filename = "emu/hana.fw";
|
||||
const char *dock_filename = "emu/audio_dock.fw";
|
||||
|
||||
snd_printk(KERN_ERR "emu1212m: Special config.\n");
|
||||
snd_printk(KERN_INFO "emu1010: Special config.\n");
|
||||
/* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
|
||||
* Lock Sound Memory Cache, Lock Tank Memory Cache,
|
||||
* Mute all codecs.
|
||||
*/
|
||||
outl(0x0005a00c, emu->port + HCFG);
|
||||
/* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
|
||||
* Lock Tank Memory Cache,
|
||||
* Mute all codecs.
|
||||
*/
|
||||
outl(0x0005a004, emu->port + HCFG);
|
||||
/* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
|
||||
* Mute all codecs.
|
||||
*/
|
||||
outl(0x0005a000, emu->port + HCFG);
|
||||
/* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
|
||||
* Mute all codecs.
|
||||
*/
|
||||
outl(0x0005a000, emu->port + HCFG);
|
||||
|
||||
snd_emu1212m_fpga_read(emu, 0x22, &tmp );
|
||||
snd_emu1212m_fpga_read(emu, 0x23, &tmp );
|
||||
snd_emu1212m_fpga_read(emu, 0x24, &tmp );
|
||||
snd_emu1212m_fpga_write(emu, 0x04, 0x01 );
|
||||
snd_emu1212m_fpga_read(emu, 0x0b, &tmp );
|
||||
snd_emu1212m_fpga_write(emu, 0x0b, 0x01 );
|
||||
snd_emu1212m_fpga_read(emu, 0x10, &tmp );
|
||||
snd_emu1212m_fpga_write(emu, 0x10, 0x00 );
|
||||
snd_emu1212m_fpga_read(emu, 0x11, &tmp );
|
||||
snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
|
||||
snd_emu1212m_fpga_read(emu, 0x13, &tmp );
|
||||
snd_emu1212m_fpga_write(emu, 0x13, 0x0f );
|
||||
snd_emu1212m_fpga_read(emu, 0x11, &tmp );
|
||||
snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
|
||||
snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
|
||||
snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
|
||||
snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
|
||||
snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
|
||||
snd_emu1212m_fpga_write(emu, 0x09, 0x0f );
|
||||
snd_emu1212m_fpga_write(emu, 0x06, 0x00 );
|
||||
snd_emu1212m_fpga_write(emu, 0x05, 0x00 );
|
||||
snd_emu1212m_fpga_write(emu, 0x0e, 0x12 );
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201);
|
||||
/* Disable 48Volt power to Audio Dock */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 );
|
||||
|
||||
/* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® );
|
||||
snd_printdd("reg1=0x%x\n",reg);
|
||||
if (reg == 0x55) {
|
||||
/* FPGA netlist already present so clear it */
|
||||
/* Return to programming mode */
|
||||
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02 );
|
||||
}
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® );
|
||||
snd_printdd("reg2=0x%x\n",reg);
|
||||
if (reg == 0x55) {
|
||||
/* FPGA failed to return to programming mode */
|
||||
return -ENODEV;
|
||||
}
|
||||
snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg);
|
||||
if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) {
|
||||
snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ID, should read & 0x7f = 0x55 when FPGA programmed. */
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® );
|
||||
if (reg != 0x55) {
|
||||
/* FPGA failed to be programmed */
|
||||
snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n");
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp );
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2 );
|
||||
snd_printk("Hana ver:%d.%d\n",tmp ,tmp2);
|
||||
/* Enable 48Volt power to Audio Dock */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON );
|
||||
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® );
|
||||
snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg);
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® );
|
||||
snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg);
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp );
|
||||
/* ADAT input. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x01 );
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_PADS, &tmp );
|
||||
/* Set no attenuation on Audio Dock pads. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PADS, 0x00 );
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp );
|
||||
/* Unmute Audio dock DACs, Headphone source DAC-4. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 );
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 );
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_UNKNOWN13, &tmp );
|
||||
/* Unknown. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_UNKNOWN13, 0x0f );
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp );
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 );
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp );
|
||||
/* SPDIF Format. Set Consumer mode, 24bit, copy enable */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 );
|
||||
/* MIDI routing */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_MIDI, 0x19 );
|
||||
/* Unknown. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_UNKNOWN12, 0x0c );
|
||||
/* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); // IRQ Enable: All on */
|
||||
/* IRQ Enable: All off */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00 );
|
||||
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® );
|
||||
snd_printk(KERN_INFO "emu1010: Card options3=0x%x\n",reg);
|
||||
/* Default WCLK set to 48kHz. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00 );
|
||||
/* Word Clock source, Internal 48kHz x1 */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K );
|
||||
//snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X );
|
||||
/* Audio Dock LEDs. */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 );
|
||||
|
||||
#if 0
|
||||
/* For 96kHz */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT2);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT2);
|
||||
#endif
|
||||
#if 0
|
||||
/* For 192kHz */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_RIGHT2);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT3);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT3);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_6, EMU_SRC_HAMOA_ADC_LEFT4);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_7, EMU_SRC_HAMOA_ADC_RIGHT4);
|
||||
#endif
|
||||
#if 1
|
||||
/* For 48kHz */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_0, EMU_SRC_DOCK_MIC_A1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_1, EMU_SRC_DOCK_MIC_B1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_LEFT2);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_4, EMU_SRC_DOCK_ADC1_LEFT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_5, EMU_SRC_DOCK_ADC1_RIGHT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1);
|
||||
#endif
|
||||
#if 0
|
||||
/* Original */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_4, EMU_SRC_HANA_ADAT);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_5, EMU_SRC_HANA_ADAT + 1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_6, EMU_SRC_HANA_ADAT + 2);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_7, EMU_SRC_HANA_ADAT + 3);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_8, EMU_SRC_HANA_ADAT + 4);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_9, EMU_SRC_HANA_ADAT + 5);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_A, EMU_SRC_HANA_ADAT + 6);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_B, EMU_SRC_HANA_ADAT + 7);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_MIC_A1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_MIC_B1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_E, EMU_SRC_HAMOA_ADC_LEFT2);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2);
|
||||
#endif
|
||||
for (i = 0;i < 0x20; i++ ) {
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000);
|
||||
/* AudioDock Elink <- Silence */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu, 0x0100+i, EMU_SRC_SILENCE);
|
||||
}
|
||||
for (i = 0;i < 4; i++) {
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000);
|
||||
/* Hana SPDIF Out <- Silence */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu, 0x0200+i, EMU_SRC_SILENCE);
|
||||
}
|
||||
for (i = 0;i < 7; i++) {
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000);
|
||||
/* Hamoa DAC <- Silence */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu, 0x0300+i, EMU_SRC_SILENCE);
|
||||
}
|
||||
for (i = 0;i < 7; i++) {
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000);
|
||||
/* Hana ADAT Out <- Silence */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE);
|
||||
}
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c);
|
||||
snd_emu1212m_fpga_write(emu, 0x07, 0x01 );
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE_I2S0_LEFT, EMU_SRC_DOCK_ADC1_LEFT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE_I2S0_RIGHT, EMU_SRC_DOCK_ADC1_RIGHT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE_I2S1_LEFT, EMU_SRC_DOCK_ADC2_LEFT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE_I2S1_RIGHT, EMU_SRC_DOCK_ADC2_RIGHT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1);
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1);
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01 ); // Unmute all
|
||||
|
||||
snd_emu1212m_fpga_read(emu, 0x21, &tmp );
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp );
|
||||
|
||||
/* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
|
||||
* Lock Sound Memory Cache, Lock Tank Memory Cache,
|
||||
* Mute all codecs.
|
||||
*/
|
||||
outl(0x0000a000, emu->port + HCFG);
|
||||
/* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
|
||||
* Lock Sound Memory Cache, Lock Tank Memory Cache,
|
||||
* Un-Mute all codecs.
|
||||
*/
|
||||
outl(0x0000a001, emu->port + HCFG);
|
||||
|
||||
/* Initial boot complete. Now patches */
|
||||
|
||||
snd_emu1212m_fpga_read(emu, 0x21, &tmp );
|
||||
snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
|
||||
snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
|
||||
snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
|
||||
snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
|
||||
snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
|
||||
snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp );
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_MIDI, 0x19 ); /* MIDI Route */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_UNKNOWN12, 0x0c ); /* Unknown */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_MIDI, 0x19 ); /* MIDI Route */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_UNKNOWN12, 0x0c ); /* Unknown */
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp );
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */
|
||||
|
||||
snd_emu1212m_fpga_read(emu, 0x20, &tmp );
|
||||
snd_emu1212m_fpga_read(emu, 0x21, &tmp );
|
||||
/* Delay to allow Audio Dock to settle */
|
||||
msleep(100);
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); /* OPTIONS: Which cards are attached to the EMU */
|
||||
/* FIXME: The loading of this should be able to happen any time,
|
||||
* as the user can plug/unplug it at any time
|
||||
*/
|
||||
if (reg & (EMU_HANA_OPTION_DOCK_ONLINE | EMU_HANA_OPTION_DOCK_OFFLINE) ) {
|
||||
/* Audio Dock attached */
|
||||
/* Return to Audio Dock programming mode */
|
||||
snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK );
|
||||
if ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) {
|
||||
return err;
|
||||
}
|
||||
snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 );
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® );
|
||||
snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg);
|
||||
/* ID, should read & 0x7f = 0x55 when FPGA programmed. */
|
||||
snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® );
|
||||
snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg);
|
||||
if (reg != 0x55) {
|
||||
/* FPGA failed to be programmed */
|
||||
snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg);
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32B + 3); /* ALICE2 bus 0xa3 */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 2); /* ALICE2 bus 0xb2 */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); /* ALICE2 bus 0xb3 */
|
||||
#endif
|
||||
/* Default outputs */
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
|
||||
emu->emu1010.output_source[0] = 21;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
|
||||
emu->emu1010.output_source[1] = 22;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2);
|
||||
emu->emu1010.output_source[2] = 23;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3);
|
||||
emu->emu1010.output_source[3] = 24;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4);
|
||||
emu->emu1010.output_source[4] = 25;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5);
|
||||
emu->emu1010.output_source[5] = 26;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_DAC4_LEFT1, EMU_SRC_ALICE_EMU32A + 6);
|
||||
emu->emu1010.output_source[6] = 27;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_DAC4_RIGHT1, EMU_SRC_ALICE_EMU32A + 7);
|
||||
emu->emu1010.output_source[7] = 28;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_PHONES_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
|
||||
emu->emu1010.output_source[8] = 21;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_PHONES_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
|
||||
emu->emu1010.output_source[9] = 22;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
|
||||
emu->emu1010.output_source[10] = 21;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_DOCK_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
|
||||
emu->emu1010.output_source[11] = 22;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
|
||||
emu->emu1010.output_source[12] = 21;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
|
||||
emu->emu1010.output_source[13] = 22;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
|
||||
emu->emu1010.output_source[14] = 21;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
|
||||
emu->emu1010.output_source[15] = 22;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_ADAT, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
|
||||
emu->emu1010.output_source[16] = 21;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_ADAT + 1, EMU_SRC_ALICE_EMU32A + 1);
|
||||
emu->emu1010.output_source[17] = 22;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_ADAT + 2, EMU_SRC_ALICE_EMU32A + 2);
|
||||
emu->emu1010.output_source[18] = 23;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_ADAT + 3, EMU_SRC_ALICE_EMU32A + 3);
|
||||
emu->emu1010.output_source[19] = 24;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_ADAT + 4, EMU_SRC_ALICE_EMU32A + 4);
|
||||
emu->emu1010.output_source[20] = 25;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_ADAT + 5, EMU_SRC_ALICE_EMU32A + 5);
|
||||
emu->emu1010.output_source[21] = 26;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_ADAT + 6, EMU_SRC_ALICE_EMU32A + 6);
|
||||
emu->emu1010.output_source[22] = 27;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7);
|
||||
emu->emu1010.output_source[23] = 28;
|
||||
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302);
|
||||
snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303);
|
||||
/* TEMP: Select SPDIF in/out */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */
|
||||
|
||||
/* TEMP: Select 48kHz SPDIF out */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */
|
||||
/* Word Clock source, Internal 48kHz x1 */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K );
|
||||
//snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X );
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);/* Set LEDs on Audio Dock */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */
|
||||
//snd_emu1010_fpga_write(emu, 0x7, 0x0); /* Mute all */
|
||||
//snd_emu1010_fpga_write(emu, 0x7, 0x1); /* Unmute all */
|
||||
//snd_emu1010_fpga_write(emu, 0xe, 0x12); /* Set LEDs on Audio Dock */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -747,6 +1038,10 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
|
|||
}
|
||||
snd_emu10k1_free_efx(emu);
|
||||
}
|
||||
if (emu->card_capabilities->emu1010) {
|
||||
/* Disable 48Volt power to Audio Dock */
|
||||
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 );
|
||||
}
|
||||
if (emu->memhdr)
|
||||
snd_util_memhdr_free(emu->memhdr);
|
||||
if (emu->silent_page.area)
|
||||
|
@ -865,11 +1160,12 @@ static struct snd_emu_chip_details emu_chip_details[] = {
|
|||
.ac97_chip = 1} ,
|
||||
/* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */
|
||||
{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
|
||||
.driver = "Audigy2", .name = "E-mu 1212m [4001]",
|
||||
.id = "EMU1212m",
|
||||
.driver = "Audigy2", .name = "E-mu 1010 [4001]",
|
||||
.id = "EMU1010",
|
||||
.emu10k2_chip = 1,
|
||||
.ca0102_chip = 1,
|
||||
.emu1212m = 1} ,
|
||||
.spk71 = 1,
|
||||
.emu1010 = 1} ,
|
||||
/* Tested by James@superbug.co.uk 3rd July 2005 */
|
||||
{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
|
||||
.driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]",
|
||||
|
@ -1297,8 +1593,8 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
|
|||
} else if (emu->card_capabilities->ca_cardbus_chip) {
|
||||
if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
|
||||
goto error;
|
||||
} else if (emu->card_capabilities->emu1212m) {
|
||||
if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) {
|
||||
} else if (emu->card_capabilities->emu1010) {
|
||||
if ((err = snd_emu10k1_emu1010_init(emu)) < 0) {
|
||||
snd_emu10k1_free(emu);
|
||||
return err;
|
||||
}
|
||||
|
@ -1446,8 +1742,8 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
|
|||
snd_emu10k1_ecard_init(emu);
|
||||
else if (emu->card_capabilities->ca_cardbus_chip)
|
||||
snd_emu10k1_cardbus_init(emu);
|
||||
else if (emu->card_capabilities->emu1212m)
|
||||
snd_emu10k1_emu1212m_init(emu);
|
||||
else if (emu->card_capabilities->emu1010)
|
||||
snd_emu10k1_emu1010_init(emu);
|
||||
else
|
||||
snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
|
||||
snd_emu10k1_init(emu, emu->enable_ir, 1);
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
* Creative Labs, Inc.
|
||||
* Routines for effect processor FX8010
|
||||
*
|
||||
* Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
|
||||
* Added EMU 1010 support.
|
||||
*
|
||||
* BUGS:
|
||||
* --
|
||||
*
|
||||
|
@ -1069,6 +1072,21 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl
|
|||
ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
|
||||
}
|
||||
|
||||
static int snd_emu10k1_audigy_dsp_convert_32_to_2x16(
|
||||
struct snd_emu10k1_fx8010_code *icode,
|
||||
u32 *ptr, int tmp, int bit_shifter16,
|
||||
int reg_in, int reg_out)
|
||||
{
|
||||
A_OP(icode, ptr, iACC3, A_GPR(tmp + 1), reg_in, A_C_00000000, A_C_00000000);
|
||||
A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp + 1), A_GPR(bit_shifter16 - 1), A_C_00000000);
|
||||
A_OP(icode, ptr, iTSTNEG, A_GPR(tmp + 2), A_GPR(tmp), A_C_80000000, A_GPR(bit_shifter16 - 2));
|
||||
A_OP(icode, ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_C_80000000, A_C_00000000);
|
||||
A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp), A_GPR(bit_shifter16 - 3), A_C_00000000);
|
||||
A_OP(icode, ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A_GPR(tmp), A_C_00010000);
|
||||
A_OP(icode, ptr, iANDXOR, reg_out, A_GPR(tmp), A_C_ffffffff, A_GPR(tmp + 2));
|
||||
A_OP(icode, ptr, iACC3, reg_out + 1, A_GPR(tmp + 1), A_C_00000000, A_C_00000000);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* initial DSP configuration for Audigy
|
||||
|
@ -1077,6 +1095,7 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl
|
|||
static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
|
||||
{
|
||||
int err, i, z, gpr, nctl;
|
||||
int bit_shifter16;
|
||||
const int playback = 10;
|
||||
const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
|
||||
const int stereo_mix = capture + 2;
|
||||
|
@ -1114,17 +1133,14 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
|
|||
ptr = 0;
|
||||
nctl = 0;
|
||||
gpr = stereo_mix + 10;
|
||||
gpr_map[gpr++] = 0x00007fff;
|
||||
gpr_map[gpr++] = 0x00008000;
|
||||
gpr_map[gpr++] = 0x0000ffff;
|
||||
bit_shifter16 = gpr;
|
||||
|
||||
/* stop FX processor */
|
||||
snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
|
||||
|
||||
#if 0
|
||||
/* FIX: jcd test */
|
||||
for (z = 0; z < 80; z=z+2) {
|
||||
A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */
|
||||
A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */
|
||||
}
|
||||
#endif /* jcd test */
|
||||
#if 1
|
||||
/* PCM front Playback Volume (independent from stereo mix) */
|
||||
A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
|
||||
|
@ -1189,6 +1205,13 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
|
|||
#define A_ADD_VOLUME_IN(var,vol,input) \
|
||||
A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
|
||||
|
||||
/* emu1212 DSP 0 and DSP 1 Capture */
|
||||
if (emu->card_capabilities->emu1010) {
|
||||
A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
|
||||
A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
|
||||
snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
|
||||
gpr += 2;
|
||||
}
|
||||
/* AC'97 Playback Volume - used only for mic (renamed later) */
|
||||
A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
|
||||
A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
|
||||
|
@ -1429,6 +1452,13 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
|
|||
|
||||
/* digital outputs */
|
||||
/* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
|
||||
if (emu->card_capabilities->emu1010) {
|
||||
/* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */
|
||||
snd_printk("EMU outputs on\n");
|
||||
for (z = 0; z < 8; z++) {
|
||||
A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
|
||||
}
|
||||
}
|
||||
|
||||
/* IEC958 Optical Raw Playback Switch */
|
||||
gpr_map[gpr++] = 0;
|
||||
|
@ -1466,10 +1496,58 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
|
|||
A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
|
||||
#endif
|
||||
|
||||
if (emu->card_capabilities->emu1010) {
|
||||
snd_printk("EMU inputs on\n");
|
||||
/* Capture 8 channels of S32_LE sound */
|
||||
|
||||
/* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */
|
||||
/* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
|
||||
/* A_P16VIN(0) is delayed by one sample,
|
||||
* so all other A_P16VIN channels will need to also be delayed
|
||||
*/
|
||||
/* Left ADC in. 1 of 2 */
|
||||
snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
|
||||
/* Right ADC in 1 of 2 */
|
||||
gpr_map[gpr++] = 0x00000000;
|
||||
snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
|
||||
A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
|
||||
gpr_map[gpr++] = 0x00000000;
|
||||
snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
|
||||
A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
|
||||
gpr_map[gpr++] = 0x00000000;
|
||||
snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
|
||||
A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
|
||||
/* For 96kHz mode */
|
||||
/* Left ADC in. 2 of 2 */
|
||||
gpr_map[gpr++] = 0x00000000;
|
||||
snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
|
||||
A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
|
||||
/* Right ADC in 2 of 2 */
|
||||
gpr_map[gpr++] = 0x00000000;
|
||||
snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
|
||||
A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
|
||||
gpr_map[gpr++] = 0x00000000;
|
||||
snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
|
||||
A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
|
||||
gpr_map[gpr++] = 0x00000000;
|
||||
snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
|
||||
A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
|
||||
|
||||
#if 0
|
||||
for (z = 4; z < 8; z++) {
|
||||
A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
|
||||
}
|
||||
for (z = 0xc; z < 0x10; z++) {
|
||||
A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* EFX capture - capture the 16 EXTINs */
|
||||
/* Capture 16 channels of S16_LE sound */
|
||||
for (z = 0; z < 16; z++) {
|
||||
A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* JCD test */
|
||||
/*
|
||||
|
@ -2138,7 +2216,7 @@ void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
|
|||
snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
|
||||
}
|
||||
|
||||
#if 0 // FIXME: who use them?
|
||||
#if 0 /* FIXME: who use them? */
|
||||
int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
|
||||
{
|
||||
if (output < 0 || output >= 6)
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
* Routines for control of EMU10K1 chips / mixer routines
|
||||
* Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
|
||||
*
|
||||
* Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
|
||||
* Added EMU 1010 support.
|
||||
*
|
||||
* BUGS:
|
||||
* --
|
||||
*
|
||||
|
@ -68,6 +71,311 @@ static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char *emu1010_src_texts[] = {
|
||||
"Silence",
|
||||
"Dock Mic A",
|
||||
"Dock Mic B",
|
||||
"Dock ADC1 Left",
|
||||
"Dock ADC1 Right",
|
||||
"Dock ADC2 Left",
|
||||
"Dock ADC2 Right",
|
||||
"Dock ADC3 Left",
|
||||
"Dock ADC3 Right",
|
||||
"0202 ADC Left",
|
||||
"0202 ADC Right",
|
||||
"0202 SPDIF Left",
|
||||
"0202 SPDIF Right",
|
||||
"ADAT 0",
|
||||
"ADAT 1",
|
||||
"ADAT 2",
|
||||
"ADAT 3",
|
||||
"ADAT 4",
|
||||
"ADAT 5",
|
||||
"ADAT 6",
|
||||
"ADAT 7",
|
||||
"DSP 0",
|
||||
"DSP 1",
|
||||
"DSP 2",
|
||||
"DSP 3",
|
||||
"DSP 4",
|
||||
"DSP 5",
|
||||
"DSP 6",
|
||||
"DSP 7",
|
||||
"DSP 8",
|
||||
"DSP 9",
|
||||
"DSP 10",
|
||||
"DSP 11",
|
||||
"DSP 12",
|
||||
"DSP 13",
|
||||
"DSP 14",
|
||||
"DSP 15",
|
||||
"DSP 16",
|
||||
"DSP 17",
|
||||
"DSP 18",
|
||||
"DSP 19",
|
||||
"DSP 20",
|
||||
"DSP 21",
|
||||
"DSP 22",
|
||||
"DSP 23",
|
||||
"DSP 24",
|
||||
"DSP 25",
|
||||
"DSP 26",
|
||||
"DSP 27",
|
||||
"DSP 28",
|
||||
"DSP 29",
|
||||
"DSP 30",
|
||||
"DSP 31",
|
||||
};
|
||||
|
||||
static unsigned int emu1010_src_regs[] = {
|
||||
EMU_SRC_SILENCE,/* 0 */
|
||||
EMU_SRC_DOCK_MIC_A1, /* 1 */
|
||||
EMU_SRC_DOCK_MIC_B1, /* 2 */
|
||||
EMU_SRC_DOCK_ADC1_LEFT1, /* 3 */
|
||||
EMU_SRC_DOCK_ADC1_RIGHT1, /* 4 */
|
||||
EMU_SRC_DOCK_ADC2_LEFT1, /* 5 */
|
||||
EMU_SRC_DOCK_ADC2_RIGHT1, /* 6 */
|
||||
EMU_SRC_DOCK_ADC3_LEFT1, /* 7 */
|
||||
EMU_SRC_DOCK_ADC3_RIGHT1, /* 8 */
|
||||
EMU_SRC_HAMOA_ADC_LEFT1, /* 9 */
|
||||
EMU_SRC_HAMOA_ADC_RIGHT1, /* 10 */
|
||||
EMU_SRC_HANA_SPDIF_LEFT1, /* 11 */
|
||||
EMU_SRC_HANA_SPDIF_RIGHT1, /* 12 */
|
||||
EMU_SRC_HANA_ADAT, /* 13 */
|
||||
EMU_SRC_HANA_ADAT+1, /* 14 */
|
||||
EMU_SRC_HANA_ADAT+2, /* 15 */
|
||||
EMU_SRC_HANA_ADAT+3, /* 16 */
|
||||
EMU_SRC_HANA_ADAT+4, /* 17 */
|
||||
EMU_SRC_HANA_ADAT+5, /* 18 */
|
||||
EMU_SRC_HANA_ADAT+6, /* 19 */
|
||||
EMU_SRC_HANA_ADAT+7, /* 20 */
|
||||
EMU_SRC_ALICE_EMU32A, /* 21 */
|
||||
EMU_SRC_ALICE_EMU32A+1, /* 22 */
|
||||
EMU_SRC_ALICE_EMU32A+2, /* 23 */
|
||||
EMU_SRC_ALICE_EMU32A+3, /* 24 */
|
||||
EMU_SRC_ALICE_EMU32A+4, /* 25 */
|
||||
EMU_SRC_ALICE_EMU32A+5, /* 26 */
|
||||
EMU_SRC_ALICE_EMU32A+6, /* 27 */
|
||||
EMU_SRC_ALICE_EMU32A+7, /* 28 */
|
||||
EMU_SRC_ALICE_EMU32A+8, /* 29 */
|
||||
EMU_SRC_ALICE_EMU32A+9, /* 30 */
|
||||
EMU_SRC_ALICE_EMU32A+0xa, /* 31 */
|
||||
EMU_SRC_ALICE_EMU32A+0xb, /* 32 */
|
||||
EMU_SRC_ALICE_EMU32A+0xc, /* 33 */
|
||||
EMU_SRC_ALICE_EMU32A+0xd, /* 34 */
|
||||
EMU_SRC_ALICE_EMU32A+0xe, /* 35 */
|
||||
EMU_SRC_ALICE_EMU32A+0xf, /* 36 */
|
||||
EMU_SRC_ALICE_EMU32B, /* 37 */
|
||||
EMU_SRC_ALICE_EMU32B+1, /* 38 */
|
||||
EMU_SRC_ALICE_EMU32B+2, /* 39 */
|
||||
EMU_SRC_ALICE_EMU32B+3, /* 40 */
|
||||
EMU_SRC_ALICE_EMU32B+4, /* 41 */
|
||||
EMU_SRC_ALICE_EMU32B+5, /* 42 */
|
||||
EMU_SRC_ALICE_EMU32B+6, /* 43 */
|
||||
EMU_SRC_ALICE_EMU32B+7, /* 44 */
|
||||
EMU_SRC_ALICE_EMU32B+8, /* 45 */
|
||||
EMU_SRC_ALICE_EMU32B+9, /* 46 */
|
||||
EMU_SRC_ALICE_EMU32B+0xa, /* 47 */
|
||||
EMU_SRC_ALICE_EMU32B+0xb, /* 48 */
|
||||
EMU_SRC_ALICE_EMU32B+0xc, /* 49 */
|
||||
EMU_SRC_ALICE_EMU32B+0xd, /* 50 */
|
||||
EMU_SRC_ALICE_EMU32B+0xe, /* 51 */
|
||||
EMU_SRC_ALICE_EMU32B+0xf, /* 52 */
|
||||
};
|
||||
|
||||
static unsigned int emu1010_output_dst[] = {
|
||||
EMU_DST_DOCK_DAC1_LEFT1, /* 0 */
|
||||
EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */
|
||||
EMU_DST_DOCK_DAC2_LEFT1, /* 2 */
|
||||
EMU_DST_DOCK_DAC2_RIGHT1, /* 3 */
|
||||
EMU_DST_DOCK_DAC3_LEFT1, /* 4 */
|
||||
EMU_DST_DOCK_DAC3_RIGHT1, /* 5 */
|
||||
EMU_DST_DOCK_DAC4_LEFT1, /* 6 */
|
||||
EMU_DST_DOCK_DAC4_RIGHT1, /* 7 */
|
||||
EMU_DST_DOCK_PHONES_LEFT1, /* 8 */
|
||||
EMU_DST_DOCK_PHONES_RIGHT1, /* 9 */
|
||||
EMU_DST_DOCK_SPDIF_LEFT1, /* 10 */
|
||||
EMU_DST_DOCK_SPDIF_RIGHT1, /* 11 */
|
||||
EMU_DST_HANA_SPDIF_LEFT1, /* 12 */
|
||||
EMU_DST_HANA_SPDIF_RIGHT1, /* 13 */
|
||||
EMU_DST_HAMOA_DAC_LEFT1, /* 14 */
|
||||
EMU_DST_HAMOA_DAC_RIGHT1, /* 15 */
|
||||
EMU_DST_HANA_ADAT, /* 16 */
|
||||
EMU_DST_HANA_ADAT+1, /* 17 */
|
||||
EMU_DST_HANA_ADAT+2, /* 18 */
|
||||
EMU_DST_HANA_ADAT+3, /* 19 */
|
||||
EMU_DST_HANA_ADAT+4, /* 20 */
|
||||
EMU_DST_HANA_ADAT+5, /* 21 */
|
||||
EMU_DST_HANA_ADAT+6, /* 22 */
|
||||
EMU_DST_HANA_ADAT+7, /* 23 */
|
||||
};
|
||||
|
||||
static unsigned int emu1010_input_dst[] = {
|
||||
EMU_DST_ALICE2_EMU32_0,
|
||||
EMU_DST_ALICE2_EMU32_1,
|
||||
EMU_DST_ALICE2_EMU32_2,
|
||||
EMU_DST_ALICE2_EMU32_3,
|
||||
EMU_DST_ALICE2_EMU32_4,
|
||||
EMU_DST_ALICE2_EMU32_5,
|
||||
EMU_DST_ALICE2_EMU32_6,
|
||||
EMU_DST_ALICE2_EMU32_7,
|
||||
EMU_DST_ALICE2_EMU32_8,
|
||||
EMU_DST_ALICE2_EMU32_9,
|
||||
EMU_DST_ALICE2_EMU32_A,
|
||||
EMU_DST_ALICE2_EMU32_B,
|
||||
EMU_DST_ALICE2_EMU32_C,
|
||||
EMU_DST_ALICE2_EMU32_D,
|
||||
EMU_DST_ALICE2_EMU32_E,
|
||||
EMU_DST_ALICE2_EMU32_F,
|
||||
EMU_DST_ALICE_I2S0_LEFT,
|
||||
EMU_DST_ALICE_I2S0_RIGHT,
|
||||
EMU_DST_ALICE_I2S1_LEFT,
|
||||
EMU_DST_ALICE_I2S1_RIGHT,
|
||||
EMU_DST_ALICE_I2S2_LEFT,
|
||||
EMU_DST_ALICE_I2S2_RIGHT,
|
||||
};
|
||||
|
||||
static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.enumerated.items = 53;
|
||||
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
|
||||
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
|
||||
strcpy(uinfo->value.enumerated.name, emu1010_src_texts[uinfo->value.enumerated.item]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
|
||||
int channel;
|
||||
|
||||
channel = (kcontrol->private_value) & 0xff;
|
||||
ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
|
||||
int change = 0;
|
||||
unsigned int val;
|
||||
int channel;
|
||||
|
||||
channel = (kcontrol->private_value) & 0xff;
|
||||
if (emu->emu1010.output_source[channel] != ucontrol->value.enumerated.item[0]) {
|
||||
val = emu->emu1010.output_source[channel] = ucontrol->value.enumerated.item[0];
|
||||
change = 1;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
emu1010_output_dst[channel], emu1010_src_regs[val]);
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
static int snd_emu1010_input_source_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
|
||||
int channel;
|
||||
|
||||
channel = (kcontrol->private_value) & 0xff;
|
||||
ucontrol->value.enumerated.item[0] = emu->emu1010.input_source[channel];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
|
||||
int change = 0;
|
||||
unsigned int val;
|
||||
int channel;
|
||||
|
||||
channel = (kcontrol->private_value) & 0xff;
|
||||
if (emu->emu1010.input_source[channel] != ucontrol->value.enumerated.item[0]) {
|
||||
val = emu->emu1010.input_source[channel] = ucontrol->value.enumerated.item[0];
|
||||
change = 1;
|
||||
snd_emu1010_fpga_link_dst_src_write(emu,
|
||||
emu1010_input_dst[channel], emu1010_src_regs[val]);
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
#define EMU1010_SOURCE_OUTPUT(xname,chid) \
|
||||
{ \
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
|
||||
.info = snd_emu1010_input_output_source_info, \
|
||||
.get = snd_emu1010_output_source_get, \
|
||||
.put = snd_emu1010_output_source_put, \
|
||||
.private_value = chid \
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new snd_emu1010_output_enum_ctls[] __devinitdata = {
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock DAC1 Left", 0),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock DAC1 Right", 1),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock DAC2 Left", 2),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock DAC2 Right", 3),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock DAC3 Left", 4),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock DAC3 Right", 5),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock DAC4 Left", 6),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock DAC4 Right", 7),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock Phones Left", 8),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock Phones Right", 9),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock SPDIF Left", 0xa),
|
||||
EMU1010_SOURCE_OUTPUT("Playback Dock SPDIF Right", 0xb),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 1010 SPDIF Left", 0xc),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 1010 SPDIF Right", 0xd),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 0202 DAC Left", 0xe),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 0202 DAC Right", 0xf),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 0", 0x10),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 1", 0x11),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 2", 0x12),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 3", 0x13),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 4", 0x14),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 5", 0x15),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 6", 0x16),
|
||||
EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 7", 0x17),
|
||||
};
|
||||
|
||||
#define EMU1010_SOURCE_INPUT(xname,chid) \
|
||||
{ \
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
|
||||
.info = snd_emu1010_input_output_source_info, \
|
||||
.get = snd_emu1010_input_source_get, \
|
||||
.put = snd_emu1010_input_source_put, \
|
||||
.private_value = chid \
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new snd_emu1010_input_enum_ctls[] __devinitdata = {
|
||||
EMU1010_SOURCE_INPUT("DSP 0 CAPTURE ENUM", 0),
|
||||
EMU1010_SOURCE_INPUT("DSP 1 CAPTURE ENUM", 1),
|
||||
EMU1010_SOURCE_INPUT("DSP 2 CAPTURE ENUM", 2),
|
||||
EMU1010_SOURCE_INPUT("DSP 3 CAPTURE ENUM", 3),
|
||||
EMU1010_SOURCE_INPUT("DSP 4 CAPTURE ENUM", 4),
|
||||
EMU1010_SOURCE_INPUT("DSP 5 CAPTURE ENUM", 5),
|
||||
EMU1010_SOURCE_INPUT("DSP 6 CAPTURE ENUM", 6),
|
||||
EMU1010_SOURCE_INPUT("DSP 7 CAPTURE ENUM", 7),
|
||||
EMU1010_SOURCE_INPUT("DSP 8 CAPTURE ENUM", 8),
|
||||
EMU1010_SOURCE_INPUT("DSP 9 CAPTURE ENUM", 9),
|
||||
EMU1010_SOURCE_INPUT("DSP A CAPTURE ENUM", 0xa),
|
||||
EMU1010_SOURCE_INPUT("DSP B CAPTURE ENUM", 0xb),
|
||||
EMU1010_SOURCE_INPUT("DSP C CAPTURE ENUM", 0xc),
|
||||
EMU1010_SOURCE_INPUT("DSP D CAPTURE ENUM", 0xd),
|
||||
EMU1010_SOURCE_INPUT("DSP E CAPTURE ENUM", 0xe),
|
||||
EMU1010_SOURCE_INPUT("DSP F CAPTURE ENUM", 0xf),
|
||||
EMU1010_SOURCE_INPUT("DSP 10 CAPTURE ENUM", 0x10),
|
||||
EMU1010_SOURCE_INPUT("DSP 11 CAPTURE ENUM", 0x11),
|
||||
EMU1010_SOURCE_INPUT("DSP 12 CAPTURE ENUM", 0x12),
|
||||
EMU1010_SOURCE_INPUT("DSP 13 CAPTURE ENUM", 0x13),
|
||||
EMU1010_SOURCE_INPUT("DSP 14 CAPTURE ENUM", 0x14),
|
||||
EMU1010_SOURCE_INPUT("DSP 15 CAPTURE ENUM", 0x15),
|
||||
};
|
||||
|
||||
#if 0
|
||||
static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
|
@ -1021,7 +1329,7 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
|
|||
return err;
|
||||
}
|
||||
|
||||
if ( emu->card_capabilities->emu1212m) {
|
||||
if ( emu->card_capabilities->emu1010) {
|
||||
; /* Disable the snd_audigy_spdif_shared_spdif */
|
||||
} else if (emu->audigy) {
|
||||
if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
|
||||
|
@ -1046,5 +1354,20 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
|
|||
return err;
|
||||
}
|
||||
|
||||
if ( emu->card_capabilities->emu1010) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(snd_emu1010_output_enum_ctls); i++) {
|
||||
err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_output_enum_ctls[i], emu));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(snd_emu1010_input_enum_ctls); i++) {
|
||||
err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_input_enum_ctls[i], emu));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voic
|
|||
1,
|
||||
&epcm->extra);
|
||||
if (err < 0) {
|
||||
// printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame);
|
||||
/* printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame); */
|
||||
for (i = 0; i < voices; i++) {
|
||||
snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
|
||||
epcm->voices[i] = NULL;
|
||||
|
@ -339,7 +339,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
|
|||
}
|
||||
}
|
||||
|
||||
// setup routing
|
||||
/* setup routing */
|
||||
if (emu->audigy) {
|
||||
snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
|
||||
snd_emu10k1_compose_audigy_fxrt1(send_routing));
|
||||
|
@ -353,8 +353,8 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
|
|||
} else
|
||||
snd_emu10k1_ptr_write(emu, FXRT, voice,
|
||||
snd_emu10k1_compose_send_routing(send_routing));
|
||||
// Stop CA
|
||||
// Assumption that PT is already 0 so no harm overwriting
|
||||
/* Stop CA */
|
||||
/* Assumption that PT is already 0 so no harm overwriting */
|
||||
snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
|
||||
snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
|
||||
snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24));
|
||||
|
@ -367,14 +367,14 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
|
|||
snd_emu10k1_ptr_write(emu, CCCA, voice, (start_addr + ccis) |
|
||||
emu10k1_select_interprom(pitch_target) |
|
||||
(w_16 ? 0 : CCCA_8BITSELECT));
|
||||
// Clear filter delay memory
|
||||
/* Clear filter delay memory */
|
||||
snd_emu10k1_ptr_write(emu, Z1, voice, 0);
|
||||
snd_emu10k1_ptr_write(emu, Z2, voice, 0);
|
||||
// invalidate maps
|
||||
/* invalidate maps */
|
||||
silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK;
|
||||
snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
|
||||
snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
|
||||
// modulation envelope
|
||||
/* modulation envelope */
|
||||
snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff);
|
||||
snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0);
|
||||
|
@ -385,12 +385,12 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
|
|||
snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0);
|
||||
snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0);
|
||||
snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000);
|
||||
// volume envelope
|
||||
/* volume envelope */
|
||||
snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f);
|
||||
snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000);
|
||||
// filter envelope
|
||||
/* filter envelope */
|
||||
snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f);
|
||||
// pitch envelope
|
||||
/* pitch envelope */
|
||||
snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0);
|
||||
|
||||
spin_unlock_irqrestore(&emu->reg_lock, flags);
|
||||
|
@ -637,7 +637,7 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e
|
|||
stereo = (!extra && runtime->channels == 2);
|
||||
sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080;
|
||||
ccis = emu10k1_ccis(stereo, sample == 0);
|
||||
// set cs to 2 * number of cache registers beside the invalidated
|
||||
/* set cs to 2 * number of cache registers beside the invalidated */
|
||||
cs = (sample == 0) ? (32-ccis) : (64-ccis+1) >> 1;
|
||||
if (cs > 16) cs = 16;
|
||||
for (i = 0; i < cs; i++) {
|
||||
|
@ -646,14 +646,14 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e
|
|||
snd_emu10k1_ptr_write(emu, CD0 + i, voice + 1, sample);
|
||||
}
|
||||
}
|
||||
// reset cache
|
||||
/* reset cache */
|
||||
snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0);
|
||||
snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra);
|
||||
if (stereo) {
|
||||
snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0);
|
||||
snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra);
|
||||
}
|
||||
// fill cache
|
||||
/* fill cache */
|
||||
snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis);
|
||||
if (stereo) {
|
||||
snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis);
|
||||
|
@ -732,7 +732,7 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
|
|||
struct snd_emu10k1_pcm_mixer *mix;
|
||||
int result = 0;
|
||||
|
||||
// printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream));
|
||||
/* printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream)); */
|
||||
spin_lock(&emu->reg_lock);
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
|
@ -778,10 +778,10 @@ static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream,
|
|||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
// hmm this should cause full and half full interrupt to be raised?
|
||||
/* hmm this should cause full and half full interrupt to be raised? */
|
||||
outl(epcm->capture_ipr, emu->port + IPR);
|
||||
snd_emu10k1_intr_enable(emu, epcm->capture_inte);
|
||||
// printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs);
|
||||
/* printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs); */
|
||||
switch (epcm->type) {
|
||||
case CAPTURE_AC97ADC:
|
||||
snd_emu10k1_ptr_write(emu, ADCCR, 0, epcm->capture_cr_val);
|
||||
|
@ -790,6 +790,7 @@ static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream,
|
|||
if (emu->audigy) {
|
||||
snd_emu10k1_ptr_write(emu, A_FXWC1, 0, epcm->capture_cr_val);
|
||||
snd_emu10k1_ptr_write(emu, A_FXWC2, 0, epcm->capture_cr_val2);
|
||||
snd_printdd("cr_val=0x%x, cr_val2=0x%x\n", epcm->capture_cr_val, epcm->capture_cr_val2);
|
||||
} else
|
||||
snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val);
|
||||
break;
|
||||
|
@ -851,7 +852,7 @@ static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream *
|
|||
ptr -= runtime->buffer_size;
|
||||
}
|
||||
#endif
|
||||
// printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size);
|
||||
/* printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size); */
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -868,7 +869,7 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
|
|||
spin_lock(&emu->reg_lock);
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
// prepare voices
|
||||
/* prepare voices */
|
||||
for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
|
||||
snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]);
|
||||
}
|
||||
|
@ -917,7 +918,7 @@ static snd_pcm_uframes_t snd_emu10k1_capture_pointer(struct snd_pcm_substream *s
|
|||
if (!epcm->running)
|
||||
return 0;
|
||||
if (epcm->first_ptr) {
|
||||
udelay(50); // hack, it takes awhile until capture is started
|
||||
udelay(50); /* hack, it takes awhile until capture is started */
|
||||
epcm->first_ptr = 0;
|
||||
}
|
||||
ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff;
|
||||
|
@ -972,6 +973,28 @@ static struct snd_pcm_hardware snd_emu10k1_capture =
|
|||
.fifo_size = 0,
|
||||
};
|
||||
|
||||
static struct snd_pcm_hardware snd_emu10k1_capture_efx =
|
||||
{
|
||||
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
SNDRV_PCM_INFO_MMAP_VALID),
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
|
||||
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
|
||||
SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
|
||||
.rate_min = 44100,
|
||||
.rate_max = 192000,
|
||||
.channels_min = 8,
|
||||
.channels_max = 8,
|
||||
.buffer_bytes_max = (64*1024),
|
||||
.period_bytes_min = 384,
|
||||
.period_bytes_max = (64*1024),
|
||||
.periods_min = 2,
|
||||
.periods_max = 2,
|
||||
.fifo_size = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
@ -1199,10 +1222,53 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
|
|||
epcm->capture_idx_reg = FXIDX;
|
||||
substream->runtime->private_data = epcm;
|
||||
substream->runtime->private_free = snd_emu10k1_pcm_free_substream;
|
||||
runtime->hw = snd_emu10k1_capture;
|
||||
runtime->hw = snd_emu10k1_capture_efx;
|
||||
runtime->hw.rates = SNDRV_PCM_RATE_48000;
|
||||
runtime->hw.rate_min = runtime->hw.rate_max = 48000;
|
||||
spin_lock_irq(&emu->reg_lock);
|
||||
if (emu->card_capabilities->emu1010) {
|
||||
/* TODO
|
||||
* SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE
|
||||
* SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
|
||||
* SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
|
||||
* SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000
|
||||
* rate_min = 44100,
|
||||
* rate_max = 192000,
|
||||
* channels_min = 8,
|
||||
* channels_max = 8,
|
||||
* Need to add mixer control to fix sample rate
|
||||
*
|
||||
* There are 16 mono channels of 16bits each.
|
||||
* 24bit Audio uses 2x channels over 16bit
|
||||
* 96kHz uses 2x channels over 48kHz
|
||||
* 192kHz uses 4x channels over 48kHz
|
||||
* So, for 48kHz 24bit, one has 8 channels
|
||||
* for 96kHz 24bit, one has 4 channels
|
||||
* for 192kHz 24bit, one has 2 channels
|
||||
*/
|
||||
#if 1
|
||||
/* For 48kHz */
|
||||
runtime->hw.rates = SNDRV_PCM_RATE_48000;
|
||||
runtime->hw.rate_min = runtime->hw.rate_max = 48000;
|
||||
runtime->hw.channels_min = runtime->hw.channels_max = 8;
|
||||
#endif
|
||||
#if 0
|
||||
/* For 96kHz */
|
||||
runtime->hw.rates = SNDRV_PCM_RATE_96000;
|
||||
runtime->hw.rate_min = runtime->hw.rate_max = 96000;
|
||||
runtime->hw.channels_min = runtime->hw.channels_max = 4;
|
||||
#endif
|
||||
#if 0
|
||||
/* For 192kHz */
|
||||
runtime->hw.rates = SNDRV_PCM_RATE_192000;
|
||||
runtime->hw.rate_min = runtime->hw.rate_max = 192000;
|
||||
runtime->hw.channels_min = runtime->hw.channels_max = 2;
|
||||
#endif
|
||||
runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
|
||||
/* efx_voices_mask[0] is expected to be zero
|
||||
* efx_voices_mask[1] is expected to have 16bits set
|
||||
*/
|
||||
} else {
|
||||
runtime->hw.channels_min = runtime->hw.channels_max = 0;
|
||||
for (idx = 0; idx < nefx; idx++) {
|
||||
if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) {
|
||||
|
@ -1210,6 +1276,7 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
|
|||
runtime->hw.channels_max++;
|
||||
}
|
||||
}
|
||||
}
|
||||
epcm->capture_cr_val = emu->efx_voices_mask[0];
|
||||
epcm->capture_cr_val2 = emu->efx_voices_mask[1];
|
||||
spin_unlock_irq(&emu->reg_lock);
|
||||
|
@ -1460,7 +1527,7 @@ static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left,
|
|||
unsigned int count,
|
||||
unsigned int tram_shift)
|
||||
{
|
||||
// printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count);
|
||||
/* printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count); */
|
||||
if ((tram_shift & 1) == 0) {
|
||||
while (count--) {
|
||||
*dst_left-- = *src++;
|
||||
|
@ -1537,7 +1604,7 @@ static int snd_emu10k1_fx8010_playback_prepare(struct snd_pcm_substream *substre
|
|||
struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
|
||||
unsigned int i;
|
||||
|
||||
// printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2);
|
||||
/* printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2); */
|
||||
memset(&pcm->pcm_rec, 0, sizeof(pcm->pcm_rec));
|
||||
pcm->pcm_rec.hw_buffer_size = pcm->buffer_size * 2; /* byte size */
|
||||
pcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
* Creative Labs, Inc.
|
||||
* Routines for control of EMU10K1 chips / proc interface routines
|
||||
*
|
||||
* Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
|
||||
* Added EMU 1010 support.
|
||||
*
|
||||
* BUGS:
|
||||
* --
|
||||
*
|
||||
|
@ -372,6 +375,27 @@ static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry,
|
||||
struct snd_info_buffer *buffer)
|
||||
{
|
||||
struct snd_emu10k1 *emu = entry->private_data;
|
||||
unsigned long value;
|
||||
unsigned long flags;
|
||||
unsigned long regs;
|
||||
int i;
|
||||
snd_iprintf(buffer, "EMU1010 Registers:\n\n");
|
||||
|
||||
for(i = 0; i < 0x30; i+=1) {
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
regs=i+0x40; /* 0x40 upwards are registers. */
|
||||
outl(regs, emu->port + A_IOCFG);
|
||||
outl(regs | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
|
||||
value = inl(emu->port + A_IOCFG);
|
||||
spin_unlock_irqrestore(&emu->emu_lock, flags);
|
||||
snd_iprintf(buffer, "%02X: %08lX, %02lX\n", i, value, (value >> 8) & 0x7f);
|
||||
}
|
||||
}
|
||||
|
||||
static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry,
|
||||
struct snd_info_buffer *buffer)
|
||||
{
|
||||
|
@ -531,6 +555,10 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
|
|||
{
|
||||
struct snd_info_entry *entry;
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
if ((emu->card_capabilities->emu1010) &&
|
||||
snd_card_proc_new(emu->card, "emu1010_regs", &entry)) {
|
||||
snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read);
|
||||
}
|
||||
if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
|
||||
snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read);
|
||||
entry->c.text.write = snd_emu_proc_io_reg_write;
|
||||
|
|
|
@ -167,6 +167,51 @@ int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
|
||||
{
|
||||
if (reg < 0 || reg > 0x3f)
|
||||
return 1;
|
||||
reg += 0x40; /* 0x40 upwards are registers. */
|
||||
if (value < 0 || value > 0x3f) /* 0 to 0x3f are values */
|
||||
return 1;
|
||||
outl(reg, emu->port + A_IOCFG);
|
||||
udelay(10);
|
||||
outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
|
||||
udelay(10);
|
||||
outl(value, emu->port + A_IOCFG);
|
||||
udelay(10);
|
||||
outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
|
||||
{
|
||||
if (reg < 0 || reg > 0x3f)
|
||||
return 1;
|
||||
reg += 0x40; /* 0x40 upwards are registers. */
|
||||
outl(reg, emu->port + A_IOCFG);
|
||||
udelay(10);
|
||||
outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
|
||||
udelay(10);
|
||||
*value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Each Destination has one and only one Source,
|
||||
* but one Source can feed any number of Destinations simultaneously.
|
||||
*/
|
||||
int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, int dst, int src)
|
||||
{
|
||||
snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) );
|
||||
snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) );
|
||||
snd_emu1010_fpga_write(emu, 0x02, ((src >> 8) & 0x3f) );
|
||||
snd_emu1010_fpga_write(emu, 0x03, (src & 0x3f) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
|
Loading…
Reference in New Issue