| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
| Jaroslav Kysela | c1017a4 | 2007-10-15 09:50:19 +0200 | [diff] [blame] | 2 | *  Copyright (c) by Jaroslav Kysela <perex@perex.cz> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 3 | *                   Creative Labs, Inc. | 
|  | 4 | *  Routines for control of EMU10K1 chips | 
|  | 5 | * | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 6 | *  Copyright (c) by James Courtier-Dutton <James@superbug.co.uk> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 7 | *      Added support for Audigy 2 Value. | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 8 | *  	Added EMU 1010 support. | 
|  | 9 | *  	General bug fixes and enhancements. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 10 | * | 
|  | 11 | * | 
|  | 12 | *  BUGS: | 
|  | 13 | *    -- | 
|  | 14 | * | 
|  | 15 | *  TODO: | 
|  | 16 | *    -- | 
|  | 17 | * | 
|  | 18 | *   This program is free software; you can redistribute it and/or modify | 
|  | 19 | *   it under the terms of the GNU General Public License as published by | 
|  | 20 | *   the Free Software Foundation; either version 2 of the License, or | 
|  | 21 | *   (at your option) any later version. | 
|  | 22 | * | 
|  | 23 | *   This program is distributed in the hope that it will be useful, | 
|  | 24 | *   but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 25 | *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | 26 | *   GNU General Public License for more details. | 
|  | 27 | * | 
|  | 28 | *   You should have received a copy of the GNU General Public License | 
|  | 29 | *   along with this program; if not, write to the Free Software | 
|  | 30 | *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA | 
|  | 31 | * | 
|  | 32 | */ | 
|  | 33 |  | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 34 | #include <linux/sched.h> | 
|  | 35 | #include <linux/kthread.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 36 | #include <linux/delay.h> | 
|  | 37 | #include <linux/init.h> | 
|  | 38 | #include <linux/interrupt.h> | 
|  | 39 | #include <linux/pci.h> | 
|  | 40 | #include <linux/slab.h> | 
|  | 41 | #include <linux/vmalloc.h> | 
| Ingo Molnar | 62932df | 2006-01-16 16:34:20 +0100 | [diff] [blame] | 42 | #include <linux/mutex.h> | 
|  | 43 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 44 |  | 
|  | 45 | #include <sound/core.h> | 
|  | 46 | #include <sound/emu10k1.h> | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 47 | #include <linux/firmware.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 48 | #include "p16v.h" | 
| James Courtier-Dutton | e2b15f8 | 2005-11-11 23:39:05 +0100 | [diff] [blame] | 49 | #include "tina2.h" | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 50 | #include "p17v.h" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 51 |  | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 52 |  | 
| Clemens Ladisch | 7e0af29 | 2007-05-03 17:59:54 +0200 | [diff] [blame] | 53 | #define HANA_FILENAME "emu/hana.fw" | 
|  | 54 | #define DOCK_FILENAME "emu/audio_dock.fw" | 
| James Courtier-Dutton | 3663d84 | 2007-07-14 02:18:26 +0100 | [diff] [blame] | 55 | #define EMU1010B_FILENAME "emu/emu1010b.fw" | 
|  | 56 | #define MICRO_DOCK_FILENAME "emu/micro_dock.fw" | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 57 | #define EMU0404_FILENAME "emu/emu0404.fw" | 
| James Courtier-Dutton | d9e8a55 | 2007-07-14 10:24:49 +0100 | [diff] [blame] | 58 | #define EMU1010_NOTEBOOK_FILENAME "emu/emu1010_notebook.fw" | 
| Clemens Ladisch | 7e0af29 | 2007-05-03 17:59:54 +0200 | [diff] [blame] | 59 |  | 
|  | 60 | MODULE_FIRMWARE(HANA_FILENAME); | 
|  | 61 | MODULE_FIRMWARE(DOCK_FILENAME); | 
| James Courtier-Dutton | 3663d84 | 2007-07-14 02:18:26 +0100 | [diff] [blame] | 62 | MODULE_FIRMWARE(EMU1010B_FILENAME); | 
|  | 63 | MODULE_FIRMWARE(MICRO_DOCK_FILENAME); | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 64 | MODULE_FIRMWARE(EMU0404_FILENAME); | 
| James Courtier-Dutton | d9e8a55 | 2007-07-14 10:24:49 +0100 | [diff] [blame] | 65 | MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME); | 
| Clemens Ladisch | 7e0af29 | 2007-05-03 17:59:54 +0200 | [diff] [blame] | 66 |  | 
|  | 67 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 68 | /************************************************************************* | 
|  | 69 | * EMU10K1 init / done | 
|  | 70 | *************************************************************************/ | 
|  | 71 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 72 | void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 73 | { | 
|  | 74 | snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0); | 
|  | 75 | snd_emu10k1_ptr_write(emu, IP, ch, 0); | 
|  | 76 | snd_emu10k1_ptr_write(emu, VTFT, ch, 0xffff); | 
|  | 77 | snd_emu10k1_ptr_write(emu, CVCF, ch, 0xffff); | 
|  | 78 | snd_emu10k1_ptr_write(emu, PTRX, ch, 0); | 
|  | 79 | snd_emu10k1_ptr_write(emu, CPF, ch, 0); | 
|  | 80 | snd_emu10k1_ptr_write(emu, CCR, ch, 0); | 
|  | 81 |  | 
|  | 82 | snd_emu10k1_ptr_write(emu, PSST, ch, 0); | 
|  | 83 | snd_emu10k1_ptr_write(emu, DSL, ch, 0x10); | 
|  | 84 | snd_emu10k1_ptr_write(emu, CCCA, ch, 0); | 
|  | 85 | snd_emu10k1_ptr_write(emu, Z1, ch, 0); | 
|  | 86 | snd_emu10k1_ptr_write(emu, Z2, ch, 0); | 
|  | 87 | snd_emu10k1_ptr_write(emu, FXRT, ch, 0x32100000); | 
|  | 88 |  | 
|  | 89 | snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0); | 
|  | 90 | snd_emu10k1_ptr_write(emu, DCYSUSM, ch, 0); | 
|  | 91 | snd_emu10k1_ptr_write(emu, IFATN, ch, 0xffff); | 
|  | 92 | snd_emu10k1_ptr_write(emu, PEFE, ch, 0); | 
|  | 93 | snd_emu10k1_ptr_write(emu, FMMOD, ch, 0); | 
|  | 94 | snd_emu10k1_ptr_write(emu, TREMFRQ, ch, 24);	/* 1 Hz */ | 
|  | 95 | snd_emu10k1_ptr_write(emu, FM2FRQ2, ch, 24);	/* 1 Hz */ | 
|  | 96 | snd_emu10k1_ptr_write(emu, TEMPENV, ch, 0); | 
|  | 97 |  | 
|  | 98 | /*** these are last so OFF prevents writing ***/ | 
|  | 99 | snd_emu10k1_ptr_write(emu, LFOVAL2, ch, 0); | 
|  | 100 | snd_emu10k1_ptr_write(emu, LFOVAL1, ch, 0); | 
|  | 101 | snd_emu10k1_ptr_write(emu, ATKHLDV, ch, 0); | 
|  | 102 | snd_emu10k1_ptr_write(emu, ENVVOL, ch, 0); | 
|  | 103 | snd_emu10k1_ptr_write(emu, ENVVAL, ch, 0); | 
|  | 104 |  | 
|  | 105 | /* Audigy extra stuffs */ | 
|  | 106 | if (emu->audigy) { | 
|  | 107 | snd_emu10k1_ptr_write(emu, 0x4c, ch, 0); /* ?? */ | 
|  | 108 | snd_emu10k1_ptr_write(emu, 0x4d, ch, 0); /* ?? */ | 
|  | 109 | snd_emu10k1_ptr_write(emu, 0x4e, ch, 0); /* ?? */ | 
|  | 110 | snd_emu10k1_ptr_write(emu, 0x4f, ch, 0); /* ?? */ | 
|  | 111 | snd_emu10k1_ptr_write(emu, A_FXRT1, ch, 0x03020100); | 
|  | 112 | snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x3f3f3f3f); | 
|  | 113 | snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, ch, 0); | 
|  | 114 | } | 
|  | 115 | } | 
|  | 116 |  | 
| James Courtier-Dutton | 18f3c59 | 2005-12-21 22:05:29 +0100 | [diff] [blame] | 117 | static unsigned int spi_dac_init[] = { | 
|  | 118 | 0x00ff, | 
|  | 119 | 0x02ff, | 
|  | 120 | 0x0400, | 
|  | 121 | 0x0520, | 
|  | 122 | 0x0600, | 
|  | 123 | 0x08ff, | 
|  | 124 | 0x0aff, | 
|  | 125 | 0x0cff, | 
|  | 126 | 0x0eff, | 
|  | 127 | 0x10ff, | 
|  | 128 | 0x1200, | 
|  | 129 | 0x1400, | 
|  | 130 | 0x1480, | 
|  | 131 | 0x1800, | 
|  | 132 | 0x1aff, | 
|  | 133 | 0x1cff, | 
|  | 134 | 0x1e00, | 
|  | 135 | 0x0530, | 
|  | 136 | 0x0602, | 
|  | 137 | 0x0622, | 
|  | 138 | 0x1400, | 
|  | 139 | }; | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 140 |  | 
|  | 141 | static unsigned int i2c_adc_init[][2] = { | 
|  | 142 | { 0x17, 0x00 }, /* Reset */ | 
|  | 143 | { 0x07, 0x00 }, /* Timeout */ | 
|  | 144 | { 0x0b, 0x22 },  /* Interface control */ | 
|  | 145 | { 0x0c, 0x22 },  /* Master mode control */ | 
|  | 146 | { 0x0d, 0x08 },  /* Powerdown control */ | 
|  | 147 | { 0x0e, 0xcf },  /* Attenuation Left  0x01 = -103dB, 0xff = 24dB */ | 
|  | 148 | { 0x0f, 0xcf },  /* Attenuation Right 0.5dB steps */ | 
|  | 149 | { 0x10, 0x7b },  /* ALC Control 1 */ | 
|  | 150 | { 0x11, 0x00 },  /* ALC Control 2 */ | 
|  | 151 | { 0x12, 0x32 },  /* ALC Control 3 */ | 
|  | 152 | { 0x13, 0x00 },  /* Noise gate control */ | 
|  | 153 | { 0x14, 0xa6 },  /* Limiter control */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 154 | { 0x15, ADC_MUX_2 },  /* ADC Mixer control. Mic for A2ZS Notebook */ | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 155 | }; | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 156 |  | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 157 | static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 158 | { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 159 | unsigned int silent_page; | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 160 | int ch; | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 161 | u32 tmp; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 162 |  | 
|  | 163 | /* disable audio and lock cache */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 164 | outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | | 
|  | 165 | HCFG_MUTEBUTTONENABLE, emu->port + HCFG); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 166 |  | 
|  | 167 | /* reset recording buffers */ | 
|  | 168 | snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE); | 
|  | 169 | snd_emu10k1_ptr_write(emu, MICBA, 0, 0); | 
|  | 170 | snd_emu10k1_ptr_write(emu, FXBS, 0, ADCBS_BUFSIZE_NONE); | 
|  | 171 | snd_emu10k1_ptr_write(emu, FXBA, 0, 0); | 
|  | 172 | snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE); | 
|  | 173 | snd_emu10k1_ptr_write(emu, ADCBA, 0, 0); | 
|  | 174 |  | 
|  | 175 | /* disable channel interrupt */ | 
|  | 176 | outl(0, emu->port + INTE); | 
|  | 177 | snd_emu10k1_ptr_write(emu, CLIEL, 0, 0); | 
|  | 178 | snd_emu10k1_ptr_write(emu, CLIEH, 0, 0); | 
|  | 179 | snd_emu10k1_ptr_write(emu, SOLEL, 0, 0); | 
|  | 180 | snd_emu10k1_ptr_write(emu, SOLEH, 0, 0); | 
|  | 181 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 182 | if (emu->audigy) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 183 | /* set SPDIF bypass mode */ | 
|  | 184 | snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT); | 
|  | 185 | /* enable rear left + rear right AC97 slots */ | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 186 | snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT | | 
|  | 187 | AC97SLOT_REAR_LEFT); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 188 | } | 
|  | 189 |  | 
|  | 190 | /* init envelope engine */ | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 191 | for (ch = 0; ch < NUM_G; ch++) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 192 | snd_emu10k1_voice_init(emu, ch); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 193 |  | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 194 | snd_emu10k1_ptr_write(emu, SPCS0, 0, emu->spdif_bits[0]); | 
|  | 195 | snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]); | 
|  | 196 | snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 197 |  | 
| Lee Revell | 2b637da | 2005-03-30 13:51:18 +0200 | [diff] [blame] | 198 | if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 199 | /* Hacks for Alice3 to work independent of haP16V driver */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 200 | /* Setup SRCMulti_I2S SamplingRate */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 201 | tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); | 
|  | 202 | tmp &= 0xfffff1ff; | 
|  | 203 | tmp |= (0x2<<9); | 
|  | 204 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 205 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 206 | /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */ | 
|  | 207 | snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14); | 
|  | 208 | /* Setup SRCMulti Input Audio Enable */ | 
|  | 209 | /* Use 0xFFFFFFFF to enable P16V sounds. */ | 
|  | 210 | snd_emu10k1_ptr20_write(emu, SRCMULTI_ENABLE, 0, 0xFFFFFFFF); | 
|  | 211 |  | 
|  | 212 | /* Enabled Phased (8-channel) P16V playback */ | 
|  | 213 | outl(0x0201, emu->port + HCFG2); | 
|  | 214 | /* Set playback routing. */ | 
| James Courtier-Dutton | fd9a98e | 2005-04-10 15:43:35 +0200 | [diff] [blame] | 215 | snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 216 | } | 
| James Courtier-Dutton | e0474e5 | 2005-07-02 16:33:34 +0200 | [diff] [blame] | 217 | if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 218 | /* Hacks for Alice3 to work independent of haP16V driver */ | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 219 | snd_printk(KERN_INFO "Audigy2 value: Special config.\n"); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 220 | /* Setup SRCMulti_I2S SamplingRate */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 221 | tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); | 
|  | 222 | tmp &= 0xfffff1ff; | 
|  | 223 | tmp |= (0x2<<9); | 
|  | 224 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp); | 
|  | 225 |  | 
|  | 226 | /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */ | 
|  | 227 | outl(0x600000, emu->port + 0x20); | 
|  | 228 | outl(0x14, emu->port + 0x24); | 
|  | 229 |  | 
|  | 230 | /* Setup SRCMulti Input Audio Enable */ | 
|  | 231 | outl(0x7b0000, emu->port + 0x20); | 
|  | 232 | outl(0xFF000000, emu->port + 0x24); | 
|  | 233 |  | 
|  | 234 | /* Setup SPDIF Out Audio Enable */ | 
|  | 235 | /* The Audigy 2 Value has a separate SPDIF out, | 
|  | 236 | * so no need for a mixer switch | 
|  | 237 | */ | 
|  | 238 | outl(0x7a0000, emu->port + 0x20); | 
|  | 239 | outl(0xFF000000, emu->port + 0x24); | 
|  | 240 | tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */ | 
|  | 241 | outl(tmp, emu->port + A_IOCFG); | 
|  | 242 | } | 
| James Courtier-Dutton | 27fe864 | 2005-12-21 15:06:08 +0100 | [diff] [blame] | 243 | if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */ | 
| James Courtier-Dutton | 18f3c59 | 2005-12-21 22:05:29 +0100 | [diff] [blame] | 244 | int size, n; | 
|  | 245 |  | 
|  | 246 | size = ARRAY_SIZE(spi_dac_init); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 247 | for (n = 0; n < size; n++) | 
| James Courtier-Dutton | 18f3c59 | 2005-12-21 22:05:29 +0100 | [diff] [blame] | 248 | snd_emu10k1_spi_write(emu, spi_dac_init[n]); | 
|  | 249 |  | 
| James Courtier-Dutton | 27fe864 | 2005-12-21 15:06:08 +0100 | [diff] [blame] | 250 | snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10); | 
| James Courtier-Dutton | ccadc3e | 2005-12-21 15:31:02 +0100 | [diff] [blame] | 251 | /* Enable GPIOs | 
|  | 252 | * GPIO0: Unknown | 
|  | 253 | * GPIO1: Speakers-enabled. | 
|  | 254 | * GPIO2: Unknown | 
|  | 255 | * GPIO3: Unknown | 
|  | 256 | * GPIO4: IEC958 Output on. | 
|  | 257 | * GPIO5: Unknown | 
|  | 258 | * GPIO6: Unknown | 
|  | 259 | * GPIO7: Unknown | 
|  | 260 | */ | 
|  | 261 | outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */ | 
| James Courtier-Dutton | 27fe864 | 2005-12-21 15:06:08 +0100 | [diff] [blame] | 262 | } | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 263 | if (emu->card_capabilities->i2c_adc) { /* Audigy 2 ZS Notebook with ADC Wolfson WM8775 */ | 
|  | 264 | int size, n; | 
|  | 265 |  | 
|  | 266 | snd_emu10k1_ptr20_write(emu, P17V_I2S_SRC_SEL, 0, 0x2020205f); | 
|  | 267 | tmp = inl(emu->port + A_IOCFG); | 
|  | 268 | outl(tmp | 0x4, emu->port + A_IOCFG);  /* Set bit 2 for mic input */ | 
|  | 269 | tmp = inl(emu->port + A_IOCFG); | 
|  | 270 | size = ARRAY_SIZE(i2c_adc_init); | 
|  | 271 | for (n = 0; n < size; n++) | 
|  | 272 | snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 273 | for (n = 0; n < 4; n++) { | 
|  | 274 | emu->i2c_capture_volume[n][0] = 0xcf; | 
|  | 275 | emu->i2c_capture_volume[n][1] = 0xcf; | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 276 | } | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 277 | } | 
|  | 278 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 279 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 280 | snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr); | 
|  | 281 | snd_emu10k1_ptr_write(emu, TCB, 0, 0);	/* taken from original driver */ | 
|  | 282 | snd_emu10k1_ptr_write(emu, TCBS, 0, 4);	/* taken from original driver */ | 
|  | 283 |  | 
|  | 284 | silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK; | 
|  | 285 | for (ch = 0; ch < NUM_G; ch++) { | 
|  | 286 | snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page); | 
|  | 287 | snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page); | 
|  | 288 | } | 
|  | 289 |  | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 290 | if (emu->card_capabilities->emu_model) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 291 | outl(HCFG_AUTOMUTE_ASYNC | | 
|  | 292 | HCFG_EMU32_SLAVE | | 
|  | 293 | HCFG_AUDIOENABLE, emu->port + HCFG); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 294 | /* | 
|  | 295 | *  Hokay, setup HCFG | 
|  | 296 | *   Mute Disable Audio = 0 | 
|  | 297 | *   Lock Tank Memory = 1 | 
|  | 298 | *   Lock Sound Memory = 0 | 
|  | 299 | *   Auto Mute = 1 | 
|  | 300 | */ | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 301 | } else if (emu->audigy) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 302 | if (emu->revision == 4) /* audigy2 */ | 
|  | 303 | outl(HCFG_AUDIOENABLE | | 
|  | 304 | HCFG_AC3ENABLE_CDSPDIF | | 
|  | 305 | HCFG_AC3ENABLE_GPSPDIF | | 
|  | 306 | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); | 
|  | 307 | else | 
|  | 308 | outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); | 
| James Courtier-Dutton | e0474e5 | 2005-07-02 16:33:34 +0200 | [diff] [blame] | 309 | /* FIXME: Remove all these emu->model and replace it with a card recognition parameter, | 
|  | 310 | * e.g. card_capabilities->joystick */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 311 | } else if (emu->model == 0x20 || | 
|  | 312 | emu->model == 0xc400 || | 
|  | 313 | (emu->model == 0x21 && emu->revision < 6)) | 
|  | 314 | outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG); | 
|  | 315 | else | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 316 | /* With on-chip joystick */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 317 | outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); | 
|  | 318 |  | 
|  | 319 | if (enable_ir) {	/* enable IR for SB Live */ | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 320 | if (emu->card_capabilities->emu_model) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 321 | ;  /* Disable all access to A_IOCFG for the emu1010 */ | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 322 | } else if (emu->card_capabilities->i2c_adc) { | 
|  | 323 | ;  /* Disable A_IOCFG for Audigy 2 ZS Notebook */ | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 324 | } else if (emu->audigy) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 325 | unsigned int reg = inl(emu->port + A_IOCFG); | 
|  | 326 | outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG); | 
|  | 327 | udelay(500); | 
|  | 328 | outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG); | 
|  | 329 | udelay(100); | 
|  | 330 | outl(reg, emu->port + A_IOCFG); | 
|  | 331 | } else { | 
|  | 332 | unsigned int reg = inl(emu->port + HCFG); | 
|  | 333 | outl(reg | HCFG_GPOUT2, emu->port + HCFG); | 
|  | 334 | udelay(500); | 
|  | 335 | outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG); | 
|  | 336 | udelay(100); | 
|  | 337 | outl(reg, emu->port + HCFG); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 338 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 339 | } | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 340 |  | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 341 | if (emu->card_capabilities->emu_model) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 342 | ;  /* Disable all access to A_IOCFG for the emu1010 */ | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 343 | } else if (emu->card_capabilities->i2c_adc) { | 
|  | 344 | ;  /* Disable A_IOCFG for Audigy 2 ZS Notebook */ | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 345 | } else if (emu->audigy) {	/* enable analog output */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 346 | unsigned int reg = inl(emu->port + A_IOCFG); | 
|  | 347 | outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); | 
|  | 348 | } | 
|  | 349 |  | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 350 | return 0; | 
|  | 351 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 352 |  | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 353 | static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu) | 
|  | 354 | { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 355 | /* | 
|  | 356 | *  Enable the audio bit | 
|  | 357 | */ | 
|  | 358 | outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG); | 
|  | 359 |  | 
|  | 360 | /* Enable analog/digital outs on audigy */ | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 361 | if (emu->card_capabilities->emu_model) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 362 | ;  /* Disable all access to A_IOCFG for the emu1010 */ | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 363 | } else if (emu->card_capabilities->i2c_adc) { | 
|  | 364 | ;  /* Disable A_IOCFG for Audigy 2 ZS Notebook */ | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 365 | } else if (emu->audigy) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 366 | outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 367 |  | 
| James Courtier-Dutton | e0474e5 | 2005-07-02 16:33:34 +0200 | [diff] [blame] | 368 | if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 369 | /* Unmute Analog now.  Set GPO6 to 1 for Apollo. | 
|  | 370 | * This has to be done after init ALice3 I2SOut beyond 48KHz. | 
|  | 371 | * So, sequence is important. */ | 
|  | 372 | outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG); | 
| James Courtier-Dutton | e0474e5 | 2005-07-02 16:33:34 +0200 | [diff] [blame] | 373 | } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 374 | /* Unmute Analog now. */ | 
|  | 375 | outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG); | 
|  | 376 | } else { | 
|  | 377 | /* Disable routing from AC97 line out to Front speakers */ | 
|  | 378 | outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG); | 
|  | 379 | } | 
|  | 380 | } | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 381 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 382 | #if 0 | 
|  | 383 | { | 
|  | 384 | unsigned int tmp; | 
|  | 385 | /* FIXME: the following routine disables LiveDrive-II !! */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 386 | /* TOSLink detection */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 387 | emu->tos_link = 0; | 
|  | 388 | tmp = inl(emu->port + HCFG); | 
|  | 389 | if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) { | 
|  | 390 | outl(tmp|0x800, emu->port + HCFG); | 
|  | 391 | udelay(50); | 
|  | 392 | if (tmp != (inl(emu->port + HCFG) & ~0x800)) { | 
|  | 393 | emu->tos_link = 1; | 
|  | 394 | outl(tmp, emu->port + HCFG); | 
|  | 395 | } | 
|  | 396 | } | 
|  | 397 | } | 
|  | 398 | #endif | 
|  | 399 |  | 
|  | 400 | snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 401 | } | 
|  | 402 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 403 | int snd_emu10k1_done(struct snd_emu10k1 *emu) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 404 | { | 
|  | 405 | int ch; | 
|  | 406 |  | 
|  | 407 | outl(0, emu->port + INTE); | 
|  | 408 |  | 
|  | 409 | /* | 
|  | 410 | *  Shutdown the chip | 
|  | 411 | */ | 
|  | 412 | for (ch = 0; ch < NUM_G; ch++) | 
|  | 413 | snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0); | 
|  | 414 | for (ch = 0; ch < NUM_G; ch++) { | 
|  | 415 | snd_emu10k1_ptr_write(emu, VTFT, ch, 0); | 
|  | 416 | snd_emu10k1_ptr_write(emu, CVCF, ch, 0); | 
|  | 417 | snd_emu10k1_ptr_write(emu, PTRX, ch, 0); | 
|  | 418 | snd_emu10k1_ptr_write(emu, CPF, ch, 0); | 
|  | 419 | } | 
|  | 420 |  | 
|  | 421 | /* reset recording buffers */ | 
|  | 422 | snd_emu10k1_ptr_write(emu, MICBS, 0, 0); | 
|  | 423 | snd_emu10k1_ptr_write(emu, MICBA, 0, 0); | 
|  | 424 | snd_emu10k1_ptr_write(emu, FXBS, 0, 0); | 
|  | 425 | snd_emu10k1_ptr_write(emu, FXBA, 0, 0); | 
|  | 426 | snd_emu10k1_ptr_write(emu, FXWC, 0, 0); | 
|  | 427 | snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE); | 
|  | 428 | snd_emu10k1_ptr_write(emu, ADCBA, 0, 0); | 
|  | 429 | snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K); | 
|  | 430 | snd_emu10k1_ptr_write(emu, TCB, 0, 0); | 
|  | 431 | if (emu->audigy) | 
|  | 432 | snd_emu10k1_ptr_write(emu, A_DBG, 0, A_DBG_SINGLE_STEP); | 
|  | 433 | else | 
|  | 434 | snd_emu10k1_ptr_write(emu, DBG, 0, EMU10K1_DBG_SINGLE_STEP); | 
|  | 435 |  | 
|  | 436 | /* disable channel interrupt */ | 
|  | 437 | snd_emu10k1_ptr_write(emu, CLIEL, 0, 0); | 
|  | 438 | snd_emu10k1_ptr_write(emu, CLIEH, 0, 0); | 
|  | 439 | snd_emu10k1_ptr_write(emu, SOLEL, 0, 0); | 
|  | 440 | snd_emu10k1_ptr_write(emu, SOLEH, 0, 0); | 
|  | 441 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 442 | /* disable audio and lock cache */ | 
|  | 443 | outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG); | 
|  | 444 | snd_emu10k1_ptr_write(emu, PTB, 0, 0); | 
|  | 445 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 446 | return 0; | 
|  | 447 | } | 
|  | 448 |  | 
|  | 449 | /************************************************************************* | 
|  | 450 | * ECARD functional implementation | 
|  | 451 | *************************************************************************/ | 
|  | 452 |  | 
|  | 453 | /* In A1 Silicon, these bits are in the HC register */ | 
|  | 454 | #define HOOKN_BIT		(1L << 12) | 
|  | 455 | #define HANDN_BIT		(1L << 11) | 
|  | 456 | #define PULSEN_BIT		(1L << 10) | 
|  | 457 |  | 
|  | 458 | #define EC_GDI1			(1 << 13) | 
|  | 459 | #define EC_GDI0			(1 << 14) | 
|  | 460 |  | 
|  | 461 | #define EC_NUM_CONTROL_BITS	20 | 
|  | 462 |  | 
|  | 463 | #define EC_AC3_DATA_SELN	0x0001L | 
|  | 464 | #define EC_EE_DATA_SEL		0x0002L | 
|  | 465 | #define EC_EE_CNTRL_SELN	0x0004L | 
|  | 466 | #define EC_EECLK		0x0008L | 
|  | 467 | #define EC_EECS			0x0010L | 
|  | 468 | #define EC_EESDO		0x0020L | 
|  | 469 | #define EC_TRIM_CSN		0x0040L | 
|  | 470 | #define EC_TRIM_SCLK		0x0080L | 
|  | 471 | #define EC_TRIM_SDATA		0x0100L | 
|  | 472 | #define EC_TRIM_MUTEN		0x0200L | 
|  | 473 | #define EC_ADCCAL		0x0400L | 
|  | 474 | #define EC_ADCRSTN		0x0800L | 
|  | 475 | #define EC_DACCAL		0x1000L | 
|  | 476 | #define EC_DACMUTEN		0x2000L | 
|  | 477 | #define EC_LEDN			0x4000L | 
|  | 478 |  | 
|  | 479 | #define EC_SPDIF0_SEL_SHIFT	15 | 
|  | 480 | #define EC_SPDIF1_SEL_SHIFT	17 | 
|  | 481 | #define EC_SPDIF0_SEL_MASK	(0x3L << EC_SPDIF0_SEL_SHIFT) | 
|  | 482 | #define EC_SPDIF1_SEL_MASK	(0x7L << EC_SPDIF1_SEL_SHIFT) | 
|  | 483 | #define EC_SPDIF0_SELECT(_x)	(((_x) << EC_SPDIF0_SEL_SHIFT) & EC_SPDIF0_SEL_MASK) | 
|  | 484 | #define EC_SPDIF1_SELECT(_x)	(((_x) << EC_SPDIF1_SEL_SHIFT) & EC_SPDIF1_SEL_MASK) | 
|  | 485 | #define EC_CURRENT_PROM_VERSION 0x01	/* Self-explanatory.  This should | 
|  | 486 | * be incremented any time the EEPROM's | 
|  | 487 | * format is changed.  */ | 
|  | 488 |  | 
|  | 489 | #define EC_EEPROM_SIZE		0x40	/* ECARD EEPROM has 64 16-bit words */ | 
|  | 490 |  | 
|  | 491 | /* Addresses for special values stored in to EEPROM */ | 
|  | 492 | #define EC_PROM_VERSION_ADDR	0x20	/* Address of the current prom version */ | 
|  | 493 | #define EC_BOARDREV0_ADDR	0x21	/* LSW of board rev */ | 
|  | 494 | #define EC_BOARDREV1_ADDR	0x22	/* MSW of board rev */ | 
|  | 495 |  | 
|  | 496 | #define EC_LAST_PROMFILE_ADDR	0x2f | 
|  | 497 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 498 | #define EC_SERIALNUM_ADDR	0x30	/* First word of serial number.  The | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 499 | * can be up to 30 characters in length | 
|  | 500 | * and is stored as a NULL-terminated | 
|  | 501 | * ASCII string.  Any unused bytes must be | 
|  | 502 | * filled with zeros */ | 
|  | 503 | #define EC_CHECKSUM_ADDR	0x3f	/* Location at which checksum is stored */ | 
|  | 504 |  | 
|  | 505 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 506 | /* Most of this stuff is pretty self-evident.  According to the hardware | 
|  | 507 | * dudes, we need to leave the ADCCAL bit low in order to avoid a DC | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 508 | * offset problem.  Weird. | 
|  | 509 | */ | 
|  | 510 | #define EC_RAW_RUN_MODE		(EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \ | 
|  | 511 | EC_TRIM_CSN) | 
|  | 512 |  | 
|  | 513 |  | 
|  | 514 | #define EC_DEFAULT_ADC_GAIN	0xC4C4 | 
|  | 515 | #define EC_DEFAULT_SPDIF0_SEL	0x0 | 
|  | 516 | #define EC_DEFAULT_SPDIF1_SEL	0x4 | 
|  | 517 |  | 
|  | 518 | /************************************************************************** | 
|  | 519 | * @func Clock bits into the Ecard's control latch.  The Ecard uses a | 
|  | 520 | *  control latch will is loaded bit-serially by toggling the Modem control | 
|  | 521 | *  lines from function 2 on the E8010.  This function hides these details | 
|  | 522 | *  and presents the illusion that we are actually writing to a distinct | 
|  | 523 | *  register. | 
|  | 524 | */ | 
|  | 525 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 526 | static void snd_emu10k1_ecard_write(struct snd_emu10k1 *emu, unsigned int value) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 527 | { | 
|  | 528 | unsigned short count; | 
|  | 529 | unsigned int data; | 
|  | 530 | unsigned long hc_port; | 
|  | 531 | unsigned int hc_value; | 
|  | 532 |  | 
|  | 533 | hc_port = emu->port + HCFG; | 
|  | 534 | hc_value = inl(hc_port) & ~(HOOKN_BIT | HANDN_BIT | PULSEN_BIT); | 
|  | 535 | outl(hc_value, hc_port); | 
|  | 536 |  | 
|  | 537 | for (count = 0; count < EC_NUM_CONTROL_BITS; count++) { | 
|  | 538 |  | 
|  | 539 | /* Set up the value */ | 
|  | 540 | data = ((value & 0x1) ? PULSEN_BIT : 0); | 
|  | 541 | value >>= 1; | 
|  | 542 |  | 
|  | 543 | outl(hc_value | data, hc_port); | 
|  | 544 |  | 
|  | 545 | /* Clock the shift register */ | 
|  | 546 | outl(hc_value | data | HANDN_BIT, hc_port); | 
|  | 547 | outl(hc_value | data, hc_port); | 
|  | 548 | } | 
|  | 549 |  | 
|  | 550 | /* Latch the bits */ | 
|  | 551 | outl(hc_value | HOOKN_BIT, hc_port); | 
|  | 552 | outl(hc_value, hc_port); | 
|  | 553 | } | 
|  | 554 |  | 
|  | 555 | /************************************************************************** | 
|  | 556 | * @func Set the gain of the ECARD's CS3310 Trim/gain controller.  The | 
|  | 557 | * trim value consists of a 16bit value which is composed of two | 
|  | 558 | * 8 bit gain/trim values, one for the left channel and one for the | 
|  | 559 | * right channel.  The following table maps from the Gain/Attenuation | 
|  | 560 | * value in decibels into the corresponding bit pattern for a single | 
|  | 561 | * channel. | 
|  | 562 | */ | 
|  | 563 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 564 | static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 *emu, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 565 | unsigned short gain) | 
|  | 566 | { | 
|  | 567 | unsigned int bit; | 
|  | 568 |  | 
|  | 569 | /* Enable writing to the TRIM registers */ | 
|  | 570 | snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN); | 
|  | 571 |  | 
|  | 572 | /* Do it again to insure that we meet hold time requirements */ | 
|  | 573 | snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN); | 
|  | 574 |  | 
|  | 575 | for (bit = (1 << 15); bit; bit >>= 1) { | 
|  | 576 | unsigned int value; | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 577 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 578 | value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA); | 
|  | 579 |  | 
|  | 580 | if (gain & bit) | 
|  | 581 | value |= EC_TRIM_SDATA; | 
|  | 582 |  | 
|  | 583 | /* Clock the bit */ | 
|  | 584 | snd_emu10k1_ecard_write(emu, value); | 
|  | 585 | snd_emu10k1_ecard_write(emu, value | EC_TRIM_SCLK); | 
|  | 586 | snd_emu10k1_ecard_write(emu, value); | 
|  | 587 | } | 
|  | 588 |  | 
|  | 589 | snd_emu10k1_ecard_write(emu, emu->ecard_ctrl); | 
|  | 590 | } | 
|  | 591 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 592 | static int snd_emu10k1_ecard_init(struct snd_emu10k1 *emu) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 593 | { | 
|  | 594 | unsigned int hc_value; | 
|  | 595 |  | 
|  | 596 | /* Set up the initial settings */ | 
|  | 597 | emu->ecard_ctrl = EC_RAW_RUN_MODE | | 
|  | 598 | EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) | | 
|  | 599 | EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL); | 
|  | 600 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 601 | /* Step 0: Set the codec type in the hardware control register | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 602 | * and enable audio output */ | 
|  | 603 | hc_value = inl(emu->port + HCFG); | 
|  | 604 | outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG); | 
|  | 605 | inl(emu->port + HCFG); | 
|  | 606 |  | 
|  | 607 | /* Step 1: Turn off the led and deassert TRIM_CS */ | 
|  | 608 | snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN); | 
|  | 609 |  | 
|  | 610 | /* Step 2: Calibrate the ADC and DAC */ | 
|  | 611 | snd_emu10k1_ecard_write(emu, EC_DACCAL | EC_LEDN | EC_TRIM_CSN); | 
|  | 612 |  | 
|  | 613 | /* Step 3: Wait for awhile;   XXX We can't get away with this | 
|  | 614 | * under a real operating system; we'll need to block and wait that | 
|  | 615 | * way. */ | 
|  | 616 | snd_emu10k1_wait(emu, 48000); | 
|  | 617 |  | 
|  | 618 | /* Step 4: Switch off the DAC and ADC calibration.  Note | 
|  | 619 | * That ADC_CAL is actually an inverted signal, so we assert | 
|  | 620 | * it here to stop calibration.  */ | 
|  | 621 | snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN); | 
|  | 622 |  | 
|  | 623 | /* Step 4: Switch into run mode */ | 
|  | 624 | snd_emu10k1_ecard_write(emu, emu->ecard_ctrl); | 
|  | 625 |  | 
|  | 626 | /* Step 5: Set the analog input gain */ | 
|  | 627 | snd_emu10k1_ecard_setadcgain(emu, EC_DEFAULT_ADC_GAIN); | 
|  | 628 |  | 
|  | 629 | return 0; | 
|  | 630 | } | 
|  | 631 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 632 | static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu) | 
| James Courtier-Dutton | d83c671 | 2005-10-31 10:27:41 +0000 | [diff] [blame] | 633 | { | 
|  | 634 | unsigned long special_port; | 
|  | 635 | unsigned int value; | 
|  | 636 |  | 
|  | 637 | /* Special initialisation routine | 
|  | 638 | * before the rest of the IO-Ports become active. | 
|  | 639 | */ | 
|  | 640 | special_port = emu->port + 0x38; | 
|  | 641 | value = inl(special_port); | 
|  | 642 | outl(0x00d00000, special_port); | 
|  | 643 | value = inl(special_port); | 
|  | 644 | outl(0x00d00001, special_port); | 
|  | 645 | value = inl(special_port); | 
|  | 646 | outl(0x00d0005f, special_port); | 
|  | 647 | value = inl(special_port); | 
|  | 648 | outl(0x00d0007f, special_port); | 
|  | 649 | value = inl(special_port); | 
|  | 650 | outl(0x0090007f, special_port); | 
|  | 651 | value = inl(special_port); | 
|  | 652 |  | 
| James Courtier-Dutton | e2b15f8 | 2005-11-11 23:39:05 +0100 | [diff] [blame] | 653 | snd_emu10k1_ptr20_write(emu, TINA2_VOLUME, 0, 0xfefefefe); /* Defaults to 0x30303030 */ | 
| James Courtier-Dutton | c94fa4c | 2007-11-10 17:55:14 +0000 | [diff] [blame] | 654 | /* Delay to give time for ADC chip to switch on. It needs 113ms */ | 
|  | 655 | msleep(200); | 
| James Courtier-Dutton | d83c671 | 2005-10-31 10:27:41 +0000 | [diff] [blame] | 656 | return 0; | 
|  | 657 | } | 
|  | 658 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 659 | static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, const char *filename) | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 660 | { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 661 | int err; | 
|  | 662 | int n, i; | 
|  | 663 | int reg; | 
|  | 664 | int value; | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 665 | unsigned int write_post; | 
|  | 666 | unsigned long flags; | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 667 | const struct firmware *fw_entry; | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 668 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 669 | err = request_firmware(&fw_entry, filename, &emu->pci->dev); | 
|  | 670 | if (err != 0) { | 
|  | 671 | snd_printk(KERN_ERR "firmware: %s not found. Err = %d\n", filename, err); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 672 | return err; | 
|  | 673 | } | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 674 | snd_printk(KERN_INFO "firmware size = 0x%zx\n", fw_entry->size); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 675 |  | 
|  | 676 | /* The FPGA is a Xilinx Spartan IIE XC2S50E */ | 
|  | 677 | /* GPIO7 -> FPGA PGMN | 
|  | 678 | * GPIO6 -> FPGA CCLK | 
|  | 679 | * GPIO5 -> FPGA DIN | 
|  | 680 | * FPGA CONFIG OFF -> FPGA PGMN | 
|  | 681 | */ | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 682 | spin_lock_irqsave(&emu->emu_lock, flags); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 683 | outl(0x00, emu->port + A_IOCFG); /* Set PGMN low for 1uS. */ | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 684 | write_post = inl(emu->port + A_IOCFG); | 
|  | 685 | udelay(100); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 686 | outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */ | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 687 | write_post = inl(emu->port + A_IOCFG); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 688 | udelay(100); /* Allow FPGA memory to clean */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 689 | for (n = 0; n < fw_entry->size; n++) { | 
|  | 690 | value = fw_entry->data[n]; | 
|  | 691 | for (i = 0; i < 8; i++) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 692 | reg = 0x80; | 
|  | 693 | if (value & 0x1) | 
|  | 694 | reg = reg | 0x20; | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 695 | value = value >> 1; | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 696 | outl(reg, emu->port + A_IOCFG); | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 697 | write_post = inl(emu->port + A_IOCFG); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 698 | outl(reg | 0x40, emu->port + A_IOCFG); | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 699 | write_post = inl(emu->port + A_IOCFG); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 700 | } | 
|  | 701 | } | 
|  | 702 | /* After programming, set GPIO bit 4 high again. */ | 
|  | 703 | outl(0x10, emu->port + A_IOCFG); | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 704 | write_post = inl(emu->port + A_IOCFG); | 
|  | 705 | spin_unlock_irqrestore(&emu->emu_lock, flags); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 706 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 707 | release_firmware(fw_entry); | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 708 | return 0; | 
|  | 709 | } | 
|  | 710 |  | 
| Takashi Iwai | bd3d1c2 | 2007-12-14 12:43:00 +0100 | [diff] [blame] | 711 | static int emu1010_firmware_thread(void *data) | 
|  | 712 | { | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 713 | struct snd_emu10k1 *emu = data; | 
| Hannes Eder | 730d45f | 2009-02-25 22:28:59 +0100 | [diff] [blame] | 714 | u32 tmp, tmp2, reg; | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 715 | int err; | 
|  | 716 |  | 
|  | 717 | for (;;) { | 
|  | 718 | /* Delay to allow Audio Dock to settle */ | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 719 | msleep_interruptible(1000); | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 720 | if (kthread_should_stop()) | 
|  | 721 | break; | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 722 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp); /* IRQ Status */ | 
|  | 723 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); /* OPTIONS: Which cards are attached to the EMU */ | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 724 | if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) { | 
|  | 725 | /* Audio Dock attached */ | 
|  | 726 | /* Return to Audio Dock programming mode */ | 
|  | 727 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 728 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK); | 
| Takashi Iwai | 3839e4f | 2007-12-21 16:33:32 +0100 | [diff] [blame] | 729 | if (emu->card_capabilities->emu_model == | 
|  | 730 | EMU_MODEL_EMU1010) { | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 731 | err = snd_emu1010_load_firmware(emu, DOCK_FILENAME); | 
|  | 732 | if (err != 0) | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 733 | continue; | 
| Takashi Iwai | 3839e4f | 2007-12-21 16:33:32 +0100 | [diff] [blame] | 734 | } else if (emu->card_capabilities->emu_model == | 
|  | 735 | EMU_MODEL_EMU1010B) { | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 736 | err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME); | 
|  | 737 | if (err != 0) | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 738 | continue; | 
| Takashi Iwai | 3839e4f | 2007-12-21 16:33:32 +0100 | [diff] [blame] | 739 | } else if (emu->card_capabilities->emu_model == | 
|  | 740 | EMU_MODEL_EMU1616) { | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 741 | err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME); | 
|  | 742 | if (err != 0) | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 743 | continue; | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 744 | } | 
|  | 745 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 746 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0); | 
|  | 747 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ®); | 
|  | 748 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS = 0x%x\n", reg); | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 749 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 750 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ®); | 
|  | 751 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", reg); | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 752 | if ((reg & 0x1f) != 0x15) { | 
|  | 753 | /* FPGA failed to be programmed */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 754 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg = 0x%x\n", reg); | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 755 | continue; | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 756 | } | 
|  | 757 | snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 758 | snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp); | 
|  | 759 | snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2); | 
| Hannes Eder | 730d45f | 2009-02-25 22:28:59 +0100 | [diff] [blame] | 760 | snd_printk(KERN_INFO "Audio Dock ver: %u.%u\n", | 
| Takashi Iwai | 28a97c1 | 2009-02-05 16:08:14 +0100 | [diff] [blame] | 761 | tmp, tmp2); | 
| James Courtier-Dutton | c93d1c2 | 2007-07-26 18:44:49 +0100 | [diff] [blame] | 762 | /* Sync clocking between 1010 and Dock */ | 
|  | 763 | /* Allow DLL to settle */ | 
|  | 764 | msleep(10); | 
|  | 765 | /* Unmute all. Default is muted after a firmware load */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 766 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE); | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 767 | } | 
|  | 768 | } | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 769 | snd_printk(KERN_INFO "emu1010: firmware thread stopping\n"); | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 770 | return 0; | 
|  | 771 | } | 
|  | 772 |  | 
| Pavel Hofman | 13d4570 | 2007-06-11 12:21:20 +0200 | [diff] [blame] | 773 | /* | 
|  | 774 | * EMU-1010 - details found out from this driver, official MS Win drivers, | 
|  | 775 | * testing the card: | 
|  | 776 | * | 
|  | 777 | * Audigy2 (aka Alice2): | 
|  | 778 | * --------------------- | 
|  | 779 | * 	* communication over PCI | 
|  | 780 | * 	* conversion of 32-bit data coming over EMU32 links from HANA FPGA | 
|  | 781 | *	  to 2 x 16-bit, using internal DSP instructions | 
|  | 782 | * 	* slave mode, clock supplied by HANA | 
|  | 783 | * 	* linked to HANA using: | 
|  | 784 | * 		32 x 32-bit serial EMU32 output channels | 
|  | 785 | * 		16 x EMU32 input channels | 
|  | 786 | * 		(?) x I2S I/O channels (?) | 
|  | 787 | * | 
|  | 788 | * FPGA (aka HANA): | 
|  | 789 | * --------------- | 
|  | 790 | * 	* provides all (?) physical inputs and outputs of the card | 
|  | 791 | * 		(ADC, DAC, SPDIF I/O, ADAT I/O, etc.) | 
|  | 792 | * 	* provides clock signal for the card and Alice2 | 
|  | 793 | * 	* two crystals - for 44.1kHz and 48kHz multiples | 
|  | 794 | * 	* provides internal routing of signal sources to signal destinations | 
|  | 795 | * 	* inputs/outputs to Alice2 - see above | 
|  | 796 | * | 
|  | 797 | * Current status of the driver: | 
|  | 798 | * ---------------------------- | 
|  | 799 | * 	* only 44.1/48kHz supported (the MS Win driver supports up to 192 kHz) | 
|  | 800 | * 	* PCM device nb. 2: | 
|  | 801 | *		16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops | 
|  | 802 | * 		16 x 32-bit capture - snd_emu10k1_capture_efx_ops | 
|  | 803 | */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 804 | static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 805 | { | 
|  | 806 | unsigned int i; | 
| Hannes Eder | 730d45f | 2009-02-25 22:28:59 +0100 | [diff] [blame] | 807 | u32 tmp, tmp2, reg; | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 808 | int err; | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 809 | const char *filename = NULL; | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 810 |  | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 811 | snd_printk(KERN_INFO "emu1010: Special config.\n"); | 
|  | 812 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, | 
|  | 813 | * Lock Sound Memory Cache, Lock Tank Memory Cache, | 
|  | 814 | * Mute all codecs. | 
|  | 815 | */ | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 816 | outl(0x0005a00c, emu->port + HCFG); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 817 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, | 
|  | 818 | * Lock Tank Memory Cache, | 
|  | 819 | * Mute all codecs. | 
|  | 820 | */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 821 | outl(0x0005a004, emu->port + HCFG); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 822 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, | 
|  | 823 | * Mute all codecs. | 
|  | 824 | */ | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 825 | outl(0x0005a000, emu->port + HCFG); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 826 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, | 
|  | 827 | * Mute all codecs. | 
|  | 828 | */ | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 829 | outl(0x0005a000, emu->port + HCFG); | 
|  | 830 |  | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 831 | /* Disable 48Volt power to Audio Dock */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 832 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0); | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 833 |  | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 834 | /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 835 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ®); | 
|  | 836 | snd_printdd("reg1 = 0x%x\n", reg); | 
| James Courtier-Dutton | d9e8a55 | 2007-07-14 10:24:49 +0100 | [diff] [blame] | 837 | if ((reg & 0x3f) == 0x15) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 838 | /* FPGA netlist already present so clear it */ | 
|  | 839 | /* Return to programming mode */ | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 840 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 841 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 842 | } | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 843 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ®); | 
|  | 844 | snd_printdd("reg2 = 0x%x\n", reg); | 
| James Courtier-Dutton | d9e8a55 | 2007-07-14 10:24:49 +0100 | [diff] [blame] | 845 | if ((reg & 0x3f) == 0x15) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 846 | /* FPGA failed to return to programming mode */ | 
| James Courtier-Dutton | d9e8a55 | 2007-07-14 10:24:49 +0100 | [diff] [blame] | 847 | snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n"); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 848 | return -ENODEV; | 
|  | 849 | } | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 850 | snd_printk(KERN_INFO "emu1010: EMU_HANA_ID = 0x%x\n", reg); | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 851 | switch (emu->card_capabilities->emu_model) { | 
| Takashi Iwai | 3839e4f | 2007-12-21 16:33:32 +0100 | [diff] [blame] | 852 | case EMU_MODEL_EMU1010: | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 853 | filename = HANA_FILENAME; | 
|  | 854 | break; | 
| Takashi Iwai | 3839e4f | 2007-12-21 16:33:32 +0100 | [diff] [blame] | 855 | case EMU_MODEL_EMU1010B: | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 856 | filename = EMU1010B_FILENAME; | 
|  | 857 | break; | 
| Takashi Iwai | 3839e4f | 2007-12-21 16:33:32 +0100 | [diff] [blame] | 858 | case EMU_MODEL_EMU1616: | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 859 | filename = EMU1010_NOTEBOOK_FILENAME; | 
|  | 860 | break; | 
| Takashi Iwai | 3839e4f | 2007-12-21 16:33:32 +0100 | [diff] [blame] | 861 | case EMU_MODEL_EMU0404: | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 862 | filename = EMU0404_FILENAME; | 
|  | 863 | break; | 
|  | 864 | default: | 
|  | 865 | filename = NULL; | 
|  | 866 | return -ENODEV; | 
|  | 867 | break; | 
|  | 868 | } | 
|  | 869 | snd_printk(KERN_INFO "emu1010: filename %s testing\n", filename); | 
|  | 870 | err = snd_emu1010_load_firmware(emu, filename); | 
|  | 871 | if (err != 0) { | 
|  | 872 | snd_printk( | 
|  | 873 | KERN_INFO "emu1010: Loading Firmware file %s failed\n", | 
|  | 874 | filename); | 
|  | 875 | return err; | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 876 | } | 
|  | 877 |  | 
|  | 878 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 879 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ®); | 
| James Courtier-Dutton | d9e8a55 | 2007-07-14 10:24:49 +0100 | [diff] [blame] | 880 | if ((reg & 0x3f) != 0x15) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 881 | /* FPGA failed to be programmed */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 882 | snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg = 0x%x\n", reg); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 883 | return -ENODEV; | 
|  | 884 | } | 
|  | 885 |  | 
|  | 886 | snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n"); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 887 | snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp); | 
|  | 888 | snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2); | 
| Hannes Eder | 730d45f | 2009-02-25 22:28:59 +0100 | [diff] [blame] | 889 | snd_printk(KERN_INFO "emu1010: Hana version: %u.%u\n", tmp, tmp2); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 890 | /* Enable 48Volt power to Audio Dock */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 891 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 892 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 893 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); | 
|  | 894 | snd_printk(KERN_INFO "emu1010: Card options = 0x%x\n", reg); | 
|  | 895 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); | 
|  | 896 | snd_printk(KERN_INFO "emu1010: Card options = 0x%x\n", reg); | 
|  | 897 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp); | 
| James Courtier-Dutton | edec7bb | 2007-07-23 20:30:22 +0100 | [diff] [blame] | 898 | /* Optical -> ADAT I/O  */ | 
| James Courtier-Dutton | f93abe5 | 2007-07-26 18:31:39 +0100 | [diff] [blame] | 899 | /* 0 : SPDIF | 
|  | 900 | * 1 : ADAT | 
|  | 901 | */ | 
|  | 902 | emu->emu1010.optical_in = 1; /* IN_ADAT */ | 
|  | 903 | emu->emu1010.optical_out = 1; /* IN_ADAT */ | 
|  | 904 | tmp = 0; | 
|  | 905 | tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) | | 
|  | 906 | (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 907 | snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp); | 
|  | 908 | snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 909 | /* Set no attenuation on Audio Dock pads. */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 910 | snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00); | 
| James Courtier-Dutton | 9148cc5 | 2006-10-09 23:08:00 +0100 | [diff] [blame] | 911 | emu->emu1010.adc_pads = 0x00; | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 912 | snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 913 | /* Unmute Audio dock DACs, Headphone source DAC-4. */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 914 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30); | 
|  | 915 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); | 
|  | 916 | snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp); | 
| James Courtier-Dutton | 9148cc5 | 2006-10-09 23:08:00 +0100 | [diff] [blame] | 917 | /* DAC PADs. */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 918 | snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f); | 
| James Courtier-Dutton | 9148cc5 | 2006-10-09 23:08:00 +0100 | [diff] [blame] | 919 | emu->emu1010.dac_pads = 0x0f; | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 920 | snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp); | 
|  | 921 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30); | 
|  | 922 | snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 923 | /* SPDIF Format. Set Consumer mode, 24bit, copy enable */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 924 | snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 925 | /* MIDI routing */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 926 | snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 927 | /* Unknown. */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 928 | snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); | 
|  | 929 | /* IRQ Enable: Alll on */ | 
|  | 930 | /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */ | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 931 | /* IRQ Enable: All off */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 932 | snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 933 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 934 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); | 
|  | 935 | snd_printk(KERN_INFO "emu1010: Card options3 = 0x%x\n", reg); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 936 | /* Default WCLK set to 48kHz. */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 937 | snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 938 | /* Word Clock source, Internal 48kHz x1 */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 939 | snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K); | 
|  | 940 | /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */ | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 941 | /* Audio Dock LEDs. */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 942 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 943 |  | 
|  | 944 | #if 0 | 
|  | 945 | /* For 96kHz */ | 
|  | 946 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 947 | EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1); | 
|  | 948 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 949 | EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1); | 
|  | 950 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 951 | EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT2); | 
|  | 952 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 953 | EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT2); | 
|  | 954 | #endif | 
|  | 955 | #if 0 | 
|  | 956 | /* For 192kHz */ | 
|  | 957 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 958 | EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1); | 
|  | 959 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 960 | EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1); | 
|  | 961 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 962 | EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2); | 
|  | 963 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 964 | EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_RIGHT2); | 
|  | 965 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 966 | EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT3); | 
|  | 967 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 968 | EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT3); | 
|  | 969 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 970 | EMU_DST_ALICE2_EMU32_6, EMU_SRC_HAMOA_ADC_LEFT4); | 
|  | 971 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 972 | EMU_DST_ALICE2_EMU32_7, EMU_SRC_HAMOA_ADC_RIGHT4); | 
|  | 973 | #endif | 
|  | 974 | #if 1 | 
|  | 975 | /* For 48kHz */ | 
|  | 976 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 977 | EMU_DST_ALICE2_EMU32_0, EMU_SRC_DOCK_MIC_A1); | 
|  | 978 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 979 | EMU_DST_ALICE2_EMU32_1, EMU_SRC_DOCK_MIC_B1); | 
|  | 980 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 981 | EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2); | 
|  | 982 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 983 | EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_LEFT2); | 
|  | 984 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 985 | EMU_DST_ALICE2_EMU32_4, EMU_SRC_DOCK_ADC1_LEFT1); | 
|  | 986 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 987 | EMU_DST_ALICE2_EMU32_5, EMU_SRC_DOCK_ADC1_RIGHT1); | 
|  | 988 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 989 | EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1); | 
|  | 990 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 991 | EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1); | 
| Pavel Hofman | 13d4570 | 2007-06-11 12:21:20 +0200 | [diff] [blame] | 992 | /* Pavel Hofman - setting defaults for 8 more capture channels | 
|  | 993 | * Defaults only, users will set their own values anyways, let's | 
|  | 994 | * just copy/paste. | 
|  | 995 | */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 996 |  | 
| Pavel Hofman | 13d4570 | 2007-06-11 12:21:20 +0200 | [diff] [blame] | 997 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 998 | EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1); | 
|  | 999 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1000 | EMU_DST_ALICE2_EMU32_9, EMU_SRC_DOCK_MIC_B1); | 
|  | 1001 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1002 | EMU_DST_ALICE2_EMU32_A, EMU_SRC_HAMOA_ADC_LEFT2); | 
|  | 1003 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1004 | EMU_DST_ALICE2_EMU32_B, EMU_SRC_HAMOA_ADC_LEFT2); | 
|  | 1005 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1006 | EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_ADC1_LEFT1); | 
|  | 1007 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1008 | EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_ADC1_RIGHT1); | 
|  | 1009 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1010 | EMU_DST_ALICE2_EMU32_E, EMU_SRC_DOCK_ADC2_LEFT1); | 
|  | 1011 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1012 | EMU_DST_ALICE2_EMU32_F, EMU_SRC_DOCK_ADC2_RIGHT1); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1013 | #endif | 
|  | 1014 | #if 0 | 
|  | 1015 | /* Original */ | 
|  | 1016 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1017 | EMU_DST_ALICE2_EMU32_4, EMU_SRC_HANA_ADAT); | 
|  | 1018 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1019 | EMU_DST_ALICE2_EMU32_5, EMU_SRC_HANA_ADAT + 1); | 
|  | 1020 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1021 | EMU_DST_ALICE2_EMU32_6, EMU_SRC_HANA_ADAT + 2); | 
|  | 1022 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1023 | EMU_DST_ALICE2_EMU32_7, EMU_SRC_HANA_ADAT + 3); | 
|  | 1024 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1025 | EMU_DST_ALICE2_EMU32_8, EMU_SRC_HANA_ADAT + 4); | 
|  | 1026 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1027 | EMU_DST_ALICE2_EMU32_9, EMU_SRC_HANA_ADAT + 5); | 
|  | 1028 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1029 | EMU_DST_ALICE2_EMU32_A, EMU_SRC_HANA_ADAT + 6); | 
|  | 1030 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1031 | EMU_DST_ALICE2_EMU32_B, EMU_SRC_HANA_ADAT + 7); | 
|  | 1032 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1033 | EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_MIC_A1); | 
|  | 1034 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1035 | EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_MIC_B1); | 
|  | 1036 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1037 | EMU_DST_ALICE2_EMU32_E, EMU_SRC_HAMOA_ADC_LEFT2); | 
|  | 1038 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1039 | EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2); | 
|  | 1040 | #endif | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1041 | for (i = 0; i < 0x20; i++) { | 
|  | 1042 | /* AudioDock Elink <- Silence */ | 
|  | 1043 | snd_emu1010_fpga_link_dst_src_write(emu, 0x0100 + i, EMU_SRC_SILENCE); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1044 | } | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1045 | for (i = 0; i < 4; i++) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1046 | /* Hana SPDIF Out <- Silence */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1047 | snd_emu1010_fpga_link_dst_src_write(emu, 0x0200 + i, EMU_SRC_SILENCE); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1048 | } | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1049 | for (i = 0; i < 7; i++) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1050 | /* Hamoa DAC <- Silence */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1051 | snd_emu1010_fpga_link_dst_src_write(emu, 0x0300 + i, EMU_SRC_SILENCE); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1052 | } | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1053 | for (i = 0; i < 7; i++) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1054 | /* Hana ADAT Out <- Silence */ | 
|  | 1055 | snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE); | 
|  | 1056 | } | 
|  | 1057 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1058 | EMU_DST_ALICE_I2S0_LEFT, EMU_SRC_DOCK_ADC1_LEFT1); | 
|  | 1059 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1060 | EMU_DST_ALICE_I2S0_RIGHT, EMU_SRC_DOCK_ADC1_RIGHT1); | 
|  | 1061 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1062 | EMU_DST_ALICE_I2S1_LEFT, EMU_SRC_DOCK_ADC2_LEFT1); | 
|  | 1063 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1064 | EMU_DST_ALICE_I2S1_RIGHT, EMU_SRC_DOCK_ADC2_RIGHT1); | 
|  | 1065 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1066 | EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1); | 
|  | 1067 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1068 | EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1069 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */ | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1070 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1071 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp); | 
|  | 1072 |  | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1073 | /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, | 
|  | 1074 | * Lock Sound Memory Cache, Lock Tank Memory Cache, | 
|  | 1075 | * Mute all codecs. | 
|  | 1076 | */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1077 | outl(0x0000a000, emu->port + HCFG); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1078 | /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, | 
|  | 1079 | * Lock Sound Memory Cache, Lock Tank Memory Cache, | 
|  | 1080 | * Un-Mute all codecs. | 
|  | 1081 | */ | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 1082 | outl(0x0000a001, emu->port + HCFG); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1083 |  | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 1084 | /* Initial boot complete. Now patches */ | 
|  | 1085 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1086 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp); | 
|  | 1087 | snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */ | 
|  | 1088 | snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */ | 
|  | 1089 | snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */ | 
|  | 1090 | snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */ | 
|  | 1091 | snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp); | 
|  | 1092 | snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10); /* SPDIF Format spdif  (or 0x11 for aes/ebu) */ | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 1093 |  | 
| James Courtier-Dutton | 42f5322 | 2007-07-23 17:52:27 +0100 | [diff] [blame] | 1094 | /* Start Micro/Audio Dock firmware loader thread */ | 
| Takashi Iwai | bd3d1c2 | 2007-12-14 12:43:00 +0100 | [diff] [blame] | 1095 | if (!emu->emu1010.firmware_thread) { | 
|  | 1096 | emu->emu1010.firmware_thread = | 
|  | 1097 | kthread_create(emu1010_firmware_thread, emu, | 
|  | 1098 | "emu1010_firmware"); | 
|  | 1099 | wake_up_process(emu->emu1010.firmware_thread); | 
|  | 1100 | } | 
| James Courtier-Dutton | 3663d84 | 2007-07-14 02:18:26 +0100 | [diff] [blame] | 1101 |  | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1102 | #if 0 | 
|  | 1103 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1104 | EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */ | 
|  | 1105 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1106 | EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32B + 3); /* ALICE2 bus 0xa3 */ | 
|  | 1107 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1108 | EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 2); /* ALICE2 bus 0xb2 */ | 
|  | 1109 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1110 | EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); /* ALICE2 bus 0xb3 */ | 
|  | 1111 | #endif | 
|  | 1112 | /* Default outputs */ | 
| Takashi Iwai | 3839e4f | 2007-12-21 16:33:32 +0100 | [diff] [blame] | 1113 | if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616) { | 
| Ctirad Fertr | 1c02e36 | 2007-12-13 16:27:13 +0100 | [diff] [blame] | 1114 | /* 1616(M) cardbus default outputs */ | 
|  | 1115 | /* ALICE2 bus 0xa0 */ | 
|  | 1116 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1117 | EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0); | 
|  | 1118 | emu->emu1010.output_source[0] = 17; | 
|  | 1119 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1120 | EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | 
|  | 1121 | emu->emu1010.output_source[1] = 18; | 
|  | 1122 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1123 | EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2); | 
|  | 1124 | emu->emu1010.output_source[2] = 19; | 
|  | 1125 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1126 | EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); | 
|  | 1127 | emu->emu1010.output_source[3] = 20; | 
|  | 1128 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1129 | EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4); | 
|  | 1130 | emu->emu1010.output_source[4] = 21; | 
|  | 1131 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1132 | EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5); | 
|  | 1133 | emu->emu1010.output_source[5] = 22; | 
|  | 1134 | /* ALICE2 bus 0xa0 */ | 
|  | 1135 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1136 | EMU_DST_MANA_DAC_LEFT, EMU_SRC_ALICE_EMU32A + 0); | 
|  | 1137 | emu->emu1010.output_source[16] = 17; | 
|  | 1138 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1139 | EMU_DST_MANA_DAC_RIGHT, EMU_SRC_ALICE_EMU32A + 1); | 
|  | 1140 | emu->emu1010.output_source[17] = 18; | 
|  | 1141 | } else { | 
|  | 1142 | /* ALICE2 bus 0xa0 */ | 
|  | 1143 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1144 | EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0); | 
|  | 1145 | emu->emu1010.output_source[0] = 21; | 
|  | 1146 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1147 | EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | 
|  | 1148 | emu->emu1010.output_source[1] = 22; | 
|  | 1149 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1150 | EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2); | 
|  | 1151 | emu->emu1010.output_source[2] = 23; | 
|  | 1152 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1153 | EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); | 
|  | 1154 | emu->emu1010.output_source[3] = 24; | 
|  | 1155 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1156 | EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4); | 
|  | 1157 | emu->emu1010.output_source[4] = 25; | 
|  | 1158 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1159 | EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5); | 
|  | 1160 | emu->emu1010.output_source[5] = 26; | 
|  | 1161 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1162 | EMU_DST_DOCK_DAC4_LEFT1, EMU_SRC_ALICE_EMU32A + 6); | 
|  | 1163 | emu->emu1010.output_source[6] = 27; | 
|  | 1164 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1165 | EMU_DST_DOCK_DAC4_RIGHT1, EMU_SRC_ALICE_EMU32A + 7); | 
|  | 1166 | emu->emu1010.output_source[7] = 28; | 
|  | 1167 | /* ALICE2 bus 0xa0 */ | 
|  | 1168 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1169 | EMU_DST_DOCK_PHONES_LEFT1, EMU_SRC_ALICE_EMU32A + 0); | 
|  | 1170 | emu->emu1010.output_source[8] = 21; | 
|  | 1171 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1172 | EMU_DST_DOCK_PHONES_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | 
|  | 1173 | emu->emu1010.output_source[9] = 22; | 
|  | 1174 | /* ALICE2 bus 0xa0 */ | 
|  | 1175 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1176 | EMU_DST_DOCK_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); | 
|  | 1177 | emu->emu1010.output_source[10] = 21; | 
|  | 1178 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1179 | EMU_DST_DOCK_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | 
|  | 1180 | emu->emu1010.output_source[11] = 22; | 
|  | 1181 | /* ALICE2 bus 0xa0 */ | 
|  | 1182 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1183 | EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); | 
|  | 1184 | emu->emu1010.output_source[12] = 21; | 
|  | 1185 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1186 | EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | 
|  | 1187 | emu->emu1010.output_source[13] = 22; | 
|  | 1188 | /* ALICE2 bus 0xa0 */ | 
|  | 1189 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1190 | EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32A + 0); | 
|  | 1191 | emu->emu1010.output_source[14] = 21; | 
|  | 1192 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1193 | EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | 
|  | 1194 | emu->emu1010.output_source[15] = 22; | 
|  | 1195 | /* ALICE2 bus 0xa0 */ | 
|  | 1196 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1197 | EMU_DST_HANA_ADAT, EMU_SRC_ALICE_EMU32A + 0); | 
|  | 1198 | emu->emu1010.output_source[16] = 21; | 
|  | 1199 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1200 | EMU_DST_HANA_ADAT + 1, EMU_SRC_ALICE_EMU32A + 1); | 
|  | 1201 | emu->emu1010.output_source[17] = 22; | 
|  | 1202 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1203 | EMU_DST_HANA_ADAT + 2, EMU_SRC_ALICE_EMU32A + 2); | 
|  | 1204 | emu->emu1010.output_source[18] = 23; | 
|  | 1205 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1206 | EMU_DST_HANA_ADAT + 3, EMU_SRC_ALICE_EMU32A + 3); | 
|  | 1207 | emu->emu1010.output_source[19] = 24; | 
|  | 1208 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1209 | EMU_DST_HANA_ADAT + 4, EMU_SRC_ALICE_EMU32A + 4); | 
|  | 1210 | emu->emu1010.output_source[20] = 25; | 
|  | 1211 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1212 | EMU_DST_HANA_ADAT + 5, EMU_SRC_ALICE_EMU32A + 5); | 
|  | 1213 | emu->emu1010.output_source[21] = 26; | 
|  | 1214 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1215 | EMU_DST_HANA_ADAT + 6, EMU_SRC_ALICE_EMU32A + 6); | 
|  | 1216 | emu->emu1010.output_source[22] = 27; | 
|  | 1217 | snd_emu1010_fpga_link_dst_src_write(emu, | 
|  | 1218 | EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7); | 
|  | 1219 | emu->emu1010.output_source[23] = 28; | 
|  | 1220 | } | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1221 | /* TEMP: Select SPDIF in/out */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1222 | /* snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); */ /* Output spdif */ | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1223 |  | 
|  | 1224 | /* TEMP: Select 48kHz SPDIF out */ | 
|  | 1225 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */ | 
|  | 1226 | snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */ | 
|  | 1227 | /* Word Clock source, Internal 48kHz x1 */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1228 | snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K); | 
|  | 1229 | /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */ | 
| James Courtier-Dutton | b0dbdae | 2006-10-10 18:08:45 +0100 | [diff] [blame] | 1230 | emu->emu1010.internal_clock = 1; /* 48000 */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1231 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); /* Set LEDs on Audio Dock */ | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1232 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1233 | /* snd_emu1010_fpga_write(emu, 0x7, 0x0); */ /* Mute all */ | 
|  | 1234 | /* snd_emu1010_fpga_write(emu, 0x7, 0x1); */ /* Unmute all */ | 
|  | 1235 | /* snd_emu1010_fpga_write(emu, 0xe, 0x12); */ /* Set LEDs on Audio Dock */ | 
| James Courtier-Dutton | 19b99fb | 2005-12-04 18:03:03 +0100 | [diff] [blame] | 1236 |  | 
|  | 1237 | return 0; | 
|  | 1238 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1239 | /* | 
|  | 1240 | *  Create the EMU10K1 instance | 
|  | 1241 | */ | 
|  | 1242 |  | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1243 | #ifdef CONFIG_PM | 
|  | 1244 | static int alloc_pm_buffer(struct snd_emu10k1 *emu); | 
|  | 1245 | static void free_pm_buffer(struct snd_emu10k1 *emu); | 
|  | 1246 | #endif | 
|  | 1247 |  | 
| Takashi Iwai | eb4698f | 2005-11-17 14:50:13 +0100 | [diff] [blame] | 1248 | static int snd_emu10k1_free(struct snd_emu10k1 *emu) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1249 | { | 
|  | 1250 | if (emu->port) {	/* avoid access to already used hardware */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1251 | snd_emu10k1_fx8010_tram_setup(emu, 0); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1252 | snd_emu10k1_done(emu); | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1253 | snd_emu10k1_free_efx(emu); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1254 | } | 
| Takashi Iwai | 3839e4f | 2007-12-21 16:33:32 +0100 | [diff] [blame] | 1255 | if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) { | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1256 | /* Disable 48Volt power to Audio Dock */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1257 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0); | 
| James Courtier-Dutton | 9f4bd5d | 2006-10-01 10:48:04 +0100 | [diff] [blame] | 1258 | } | 
| Takashi Iwai | bd3d1c2 | 2007-12-14 12:43:00 +0100 | [diff] [blame] | 1259 | if (emu->emu1010.firmware_thread) | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 1260 | kthread_stop(emu->emu1010.firmware_thread); | 
| Takashi Iwai | ebf029d | 2008-04-22 17:28:11 +0200 | [diff] [blame] | 1261 | if (emu->irq >= 0) | 
|  | 1262 | free_irq(emu->irq, emu); | 
|  | 1263 | /* remove reserved page */ | 
|  | 1264 | if (emu->reserved_page) { | 
|  | 1265 | snd_emu10k1_synth_free(emu, | 
|  | 1266 | (struct snd_util_memblk *)emu->reserved_page); | 
|  | 1267 | emu->reserved_page = NULL; | 
|  | 1268 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1269 | if (emu->memhdr) | 
|  | 1270 | snd_util_memhdr_free(emu->memhdr); | 
|  | 1271 | if (emu->silent_page.area) | 
|  | 1272 | snd_dma_free_pages(&emu->silent_page); | 
|  | 1273 | if (emu->ptb_pages.area) | 
|  | 1274 | snd_dma_free_pages(&emu->ptb_pages); | 
|  | 1275 | vfree(emu->page_ptr_table); | 
|  | 1276 | vfree(emu->page_addr_table); | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1277 | #ifdef CONFIG_PM | 
|  | 1278 | free_pm_buffer(emu); | 
|  | 1279 | #endif | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1280 | if (emu->port) | 
|  | 1281 | pci_release_regions(emu->pci); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1282 | if (emu->card_capabilities->ca0151_chip) /* P16V */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1283 | snd_p16v_free(emu); | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1284 | pci_disable_device(emu->pci); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1285 | kfree(emu); | 
|  | 1286 | return 0; | 
|  | 1287 | } | 
|  | 1288 |  | 
| Takashi Iwai | eb4698f | 2005-11-17 14:50:13 +0100 | [diff] [blame] | 1289 | static int snd_emu10k1_dev_free(struct snd_device *device) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1290 | { | 
| Takashi Iwai | eb4698f | 2005-11-17 14:50:13 +0100 | [diff] [blame] | 1291 | struct snd_emu10k1 *emu = device->device_data; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1292 | return snd_emu10k1_free(emu); | 
|  | 1293 | } | 
|  | 1294 |  | 
| Takashi Iwai | eb4698f | 2005-11-17 14:50:13 +0100 | [diff] [blame] | 1295 | static struct snd_emu_chip_details emu_chip_details[] = { | 
| James Courtier-Dutton | 21fddde | 2006-04-09 17:36:39 +0100 | [diff] [blame] | 1296 | /* Audigy4 (Not PRO) SB0610 */ | 
|  | 1297 | /* Tested by James@superbug.co.uk 4th April 2006 */ | 
|  | 1298 | /* A_IOCFG bits | 
|  | 1299 | * Output | 
|  | 1300 | * 0: ? | 
|  | 1301 | * 1: ? | 
|  | 1302 | * 2: ? | 
|  | 1303 | * 3: 0 - Digital Out, 1 - Line in | 
|  | 1304 | * 4: ? | 
|  | 1305 | * 5: ? | 
|  | 1306 | * 6: ? | 
|  | 1307 | * 7: ? | 
|  | 1308 | * Input | 
|  | 1309 | * 8: ? | 
|  | 1310 | * 9: ? | 
|  | 1311 | * A: Green jack sense (Front) | 
|  | 1312 | * B: ? | 
|  | 1313 | * C: Black jack sense (Rear/Side Right) | 
|  | 1314 | * D: Yellow jack sense (Center/LFE/Side Left) | 
|  | 1315 | * E: ? | 
|  | 1316 | * F: ? | 
|  | 1317 | * | 
|  | 1318 | * Digital Out/Line in switch using A_IOCFG bit 3 (0x08) | 
|  | 1319 | * 0 - Digital Out | 
|  | 1320 | * 1 - Line in | 
|  | 1321 | */ | 
|  | 1322 | /* Mic input not tested. | 
|  | 1323 | * Analog CD input not tested | 
|  | 1324 | * Digital Out not tested. | 
|  | 1325 | * Line in working. | 
|  | 1326 | * Audio output 5.1 working. Side outputs not working. | 
|  | 1327 | */ | 
|  | 1328 | /* DSP: CA10300-IAT LF | 
|  | 1329 | * DAC: Cirrus Logic CS4382-KQZ | 
|  | 1330 | * ADC: Philips 1361T | 
|  | 1331 | * AC97: Sigmatel STAC9750 | 
|  | 1332 | * CA0151: None | 
|  | 1333 | */ | 
|  | 1334 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1335 | .driver = "Audigy2", .name = "SB Audigy 4 [SB0610]", | 
| James Courtier-Dutton | 21fddde | 2006-04-09 17:36:39 +0100 | [diff] [blame] | 1336 | .id = "Audigy2", | 
|  | 1337 | .emu10k2_chip = 1, | 
|  | 1338 | .ca0108_chip = 1, | 
|  | 1339 | .spk71 = 1, | 
|  | 1340 | .adc_1361t = 1,  /* 24 bit capture instead of 16bit */ | 
|  | 1341 | .ac97_chip = 1} , | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1342 | /* Audigy 2 Value AC3 out does not work yet. | 
|  | 1343 | * Need to find out how to turn off interpolators. | 
|  | 1344 | */ | 
|  | 1345 | /* Tested by James@superbug.co.uk 3rd July 2005 */ | 
|  | 1346 | /* DSP: CA0108-IAT | 
|  | 1347 | * DAC: CS4382-KQ | 
|  | 1348 | * ADC: Philips 1361T | 
|  | 1349 | * AC97: STAC9750 | 
|  | 1350 | * CA0151: None | 
|  | 1351 | */ | 
|  | 1352 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102, | 
|  | 1353 | .driver = "Audigy2", .name = "SB Audigy 2 Value [SB0400]", | 
|  | 1354 | .id = "Audigy2", | 
|  | 1355 | .emu10k2_chip = 1, | 
|  | 1356 | .ca0108_chip = 1, | 
|  | 1357 | .spk71 = 1, | 
|  | 1358 | .ac97_chip = 1} , | 
| James Courtier-Dutton | d83c671 | 2005-10-31 10:27:41 +0000 | [diff] [blame] | 1359 | /* Audigy 2 ZS Notebook Cardbus card.*/ | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 1360 | /* Tested by James@superbug.co.uk 6th November 2006 */ | 
| James Courtier-Dutton | f951fd3 | 2005-12-22 13:05:23 +0100 | [diff] [blame] | 1361 | /* Audio output 7.1/Headphones working. | 
|  | 1362 | * Digital output working. (AC3 not checked, only PCM) | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 1363 | * Audio Mic/Line inputs working. | 
|  | 1364 | * Digital input not tested. | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1365 | */ | 
| James Courtier-Dutton | 21fddde | 2006-04-09 17:36:39 +0100 | [diff] [blame] | 1366 | /* DSP: Tina2 | 
| James Courtier-Dutton | f951fd3 | 2005-12-22 13:05:23 +0100 | [diff] [blame] | 1367 | * DAC: Wolfson WM8768/WM8568 | 
|  | 1368 | * ADC: Wolfson WM8775 | 
|  | 1369 | * AC97: None | 
|  | 1370 | * CA0151: None | 
|  | 1371 | */ | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 1372 | /* Tested by James@superbug.co.uk 4th April 2006 */ | 
|  | 1373 | /* A_IOCFG bits | 
|  | 1374 | * Output | 
|  | 1375 | * 0: Not Used | 
|  | 1376 | * 1: 0 = Mute all the 7.1 channel out. 1 = unmute. | 
|  | 1377 | * 2: Analog input 0 = line in, 1 = mic in | 
|  | 1378 | * 3: Not Used | 
|  | 1379 | * 4: Digital output 0 = off, 1 = on. | 
|  | 1380 | * 5: Not Used | 
|  | 1381 | * 6: Not Used | 
|  | 1382 | * 7: Not Used | 
|  | 1383 | * Input | 
|  | 1384 | *      All bits 1 (0x3fxx) means nothing plugged in. | 
|  | 1385 | * 8-9: 0 = Line in/Mic, 2 = Optical in, 3 = Nothing. | 
|  | 1386 | * A-B: 0 = Headphones, 2 = Optical out, 3 = Nothing. | 
|  | 1387 | * C-D: 2 = Front/Rear/etc, 3 = nothing. | 
|  | 1388 | * E-F: Always 0 | 
|  | 1389 | * | 
|  | 1390 | */ | 
| James Courtier-Dutton | d83c671 | 2005-10-31 10:27:41 +0000 | [diff] [blame] | 1391 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1392 | .driver = "Audigy2", .name = "SB Audigy 2 ZS Notebook [SB0530]", | 
| James Courtier-Dutton | d83c671 | 2005-10-31 10:27:41 +0000 | [diff] [blame] | 1393 | .id = "Audigy2", | 
|  | 1394 | .emu10k2_chip = 1, | 
|  | 1395 | .ca0108_chip = 1, | 
|  | 1396 | .ca_cardbus_chip = 1, | 
| James Courtier-Dutton | 27fe864 | 2005-12-21 15:06:08 +0100 | [diff] [blame] | 1397 | .spi_dac = 1, | 
| James Courtier-Dutton | 184c1e2 | 2006-12-06 15:58:02 +0000 | [diff] [blame] | 1398 | .i2c_adc = 1, | 
| James Courtier-Dutton | d83c671 | 2005-10-31 10:27:41 +0000 | [diff] [blame] | 1399 | .spk71 = 1} , | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 1400 | /* Tested by James@superbug.co.uk 4th Nov 2007. */ | 
| James Courtier-Dutton | 82c8c74 | 2007-04-19 11:14:41 +0100 | [diff] [blame] | 1401 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1402 | .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", | 
| James Courtier-Dutton | 82c8c74 | 2007-04-19 11:14:41 +0100 | [diff] [blame] | 1403 | .id = "EMU1010", | 
|  | 1404 | .emu10k2_chip = 1, | 
|  | 1405 | .ca0108_chip = 1, | 
|  | 1406 | .ca_cardbus_chip = 1, | 
| James Courtier-Dutton | d9e8a55 | 2007-07-14 10:24:49 +0100 | [diff] [blame] | 1407 | .spk71 = 1 , | 
| Takashi Iwai | 3839e4f | 2007-12-21 16:33:32 +0100 | [diff] [blame] | 1408 | .emu_model = EMU_MODEL_EMU1616}, | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 1409 | /* Tested by James@superbug.co.uk 4th Nov 2007. */ | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1410 | /* This is MAEM8960, 0202 is MAEM 8980 */ | 
| James Courtier-Dutton | 3663d84 | 2007-07-14 02:18:26 +0100 | [diff] [blame] | 1411 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1412 | .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM8960]", | 
| James Courtier-Dutton | 3663d84 | 2007-07-14 02:18:26 +0100 | [diff] [blame] | 1413 | .id = "EMU1010", | 
|  | 1414 | .emu10k2_chip = 1, | 
|  | 1415 | .ca0108_chip = 1, | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 1416 | .spk71 = 1, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1417 | .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 new revision */ | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 1418 | /* Tested by James@superbug.co.uk 8th July 2005. */ | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1419 | /* This is MAEM8810, 0202 is MAEM8820 */ | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 1420 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1421 | .driver = "Audigy2", .name = "E-mu 1010 [MAEM8810]", | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 1422 | .id = "EMU1010", | 
|  | 1423 | .emu10k2_chip = 1, | 
|  | 1424 | .ca0102_chip = 1, | 
|  | 1425 | .spk71 = 1, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1426 | .emu_model = EMU_MODEL_EMU1010}, /* EMU 1010 old revision */ | 
| Veli-Matti Valtonen | 493b4ac | 2008-01-07 12:36:56 +0100 | [diff] [blame] | 1427 | /* EMU0404b */ | 
|  | 1428 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1429 | .driver = "Audigy2", .name = "E-mu 0404b PCI [MAEM8852]", | 
| Veli-Matti Valtonen | 493b4ac | 2008-01-07 12:36:56 +0100 | [diff] [blame] | 1430 | .id = "EMU0404", | 
|  | 1431 | .emu10k2_chip = 1, | 
|  | 1432 | .ca0108_chip = 1, | 
|  | 1433 | .spk71 = 1, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1434 | .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 new revision */ | 
| Veli-Matti Valtonen | 493b4ac | 2008-01-07 12:36:56 +0100 | [diff] [blame] | 1435 | /* Tested by James@superbug.co.uk 20-3-2007. */ | 
|  | 1436 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1437 | .driver = "Audigy2", .name = "E-mu 0404 [MAEM8850]", | 
| Veli-Matti Valtonen | 493b4ac | 2008-01-07 12:36:56 +0100 | [diff] [blame] | 1438 | .id = "EMU0404", | 
|  | 1439 | .emu10k2_chip = 1, | 
|  | 1440 | .ca0102_chip = 1, | 
|  | 1441 | .spk71 = 1, | 
|  | 1442 | .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */ | 
| Vedran Miletic | 718a259 | 2008-10-21 21:31:27 +0200 | [diff] [blame] | 1443 | /* Note that all E-mu cards require kernel 2.6 or newer. */ | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1444 | {.vendor = 0x1102, .device = 0x0008, | 
|  | 1445 | .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]", | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1446 | .id = "Audigy2", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1447 | .emu10k2_chip = 1, | 
| Peter Zubaj | 2668907 | 2005-04-01 11:15:07 +0200 | [diff] [blame] | 1448 | .ca0108_chip = 1, | 
|  | 1449 | .ac97_chip = 1} , | 
| James Courtier-Dutton | 88dc0e5 | 2005-07-03 12:54:29 +0200 | [diff] [blame] | 1450 | /* Tested by James@superbug.co.uk 3rd July 2005 */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1451 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1452 | .driver = "Audigy2", .name = "SB Audigy 4 PRO [SB0380]", | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1453 | .id = "Audigy2", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1454 | .emu10k2_chip = 1, | 
|  | 1455 | .ca0102_chip = 1, | 
|  | 1456 | .ca0151_chip = 1, | 
|  | 1457 | .spk71 = 1, | 
|  | 1458 | .spdif_bug = 1, | 
|  | 1459 | .ac97_chip = 1} , | 
| Lee Revell | f6f8bb6 | 2005-11-07 14:59:19 +0100 | [diff] [blame] | 1460 | /* Tested by shane-alsa@cm.nu 5th Nov 2005 */ | 
| James Courtier-Dutton | 5b0e498 | 2006-04-09 22:45:58 +0200 | [diff] [blame] | 1461 | /* The 0x20061102 does have SB0350 written on it | 
|  | 1462 | * Just like 0x20021102 | 
|  | 1463 | */ | 
| Lee Revell | f6f8bb6 | 2005-11-07 14:59:19 +0100 | [diff] [blame] | 1464 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1465 | .driver = "Audigy2", .name = "SB Audigy 2 [SB0350b]", | 
| Lee Revell | f6f8bb6 | 2005-11-07 14:59:19 +0100 | [diff] [blame] | 1466 | .id = "Audigy2", | 
|  | 1467 | .emu10k2_chip = 1, | 
|  | 1468 | .ca0102_chip = 1, | 
|  | 1469 | .ca0151_chip = 1, | 
|  | 1470 | .spk71 = 1, | 
|  | 1471 | .spdif_bug = 1, | 
| Takashi Iwai | 55e03a6 | 2008-11-03 10:21:36 +0100 | [diff] [blame] | 1472 | .invert_shared_spdif = 1,	/* digital/analog switch swapped */ | 
| Lee Revell | f6f8bb6 | 2005-11-07 14:59:19 +0100 | [diff] [blame] | 1473 | .ac97_chip = 1} , | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1474 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1475 | .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0350]", | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1476 | .id = "Audigy2", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1477 | .emu10k2_chip = 1, | 
|  | 1478 | .ca0102_chip = 1, | 
|  | 1479 | .ca0151_chip = 1, | 
|  | 1480 | .spk71 = 1, | 
|  | 1481 | .spdif_bug = 1, | 
| Takashi Iwai | 55e03a6 | 2008-11-03 10:21:36 +0100 | [diff] [blame] | 1482 | .invert_shared_spdif = 1,	/* digital/analog switch swapped */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1483 | .ac97_chip = 1} , | 
|  | 1484 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1485 | .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0360]", | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1486 | .id = "Audigy2", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1487 | .emu10k2_chip = 1, | 
|  | 1488 | .ca0102_chip = 1, | 
|  | 1489 | .ca0151_chip = 1, | 
|  | 1490 | .spk71 = 1, | 
|  | 1491 | .spdif_bug = 1, | 
| Takashi Iwai | 55e03a6 | 2008-11-03 10:21:36 +0100 | [diff] [blame] | 1492 | .invert_shared_spdif = 1,	/* digital/analog switch swapped */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1493 | .ac97_chip = 1} , | 
| James Courtier-Dutton | 54efc96 | 2005-12-22 12:58:41 +0100 | [diff] [blame] | 1494 | /* Audigy 2 */ | 
|  | 1495 | /* Tested by James@superbug.co.uk 3rd July 2005 */ | 
|  | 1496 | /* DSP: CA0102-IAT | 
|  | 1497 | * DAC: CS4382-KQ | 
|  | 1498 | * ADC: Philips 1361T | 
|  | 1499 | * AC97: STAC9721 | 
|  | 1500 | * CA0151: Yes | 
|  | 1501 | */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1502 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1503 | .driver = "Audigy2", .name = "SB Audigy 2 [SB0240]", | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1504 | .id = "Audigy2", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1505 | .emu10k2_chip = 1, | 
|  | 1506 | .ca0102_chip = 1, | 
|  | 1507 | .ca0151_chip = 1, | 
|  | 1508 | .spk71 = 1, | 
|  | 1509 | .spdif_bug = 1, | 
| James Courtier-Dutton | 11b3a75 | 2006-07-08 16:39:30 +0100 | [diff] [blame] | 1510 | .adc_1361t = 1,  /* 24 bit capture instead of 16bit */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1511 | .ac97_chip = 1} , | 
|  | 1512 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1513 | .driver = "Audigy2", .name = "SB Audigy 2 Platinum EX [SB0280]", | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1514 | .id = "Audigy2", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1515 | .emu10k2_chip = 1, | 
|  | 1516 | .ca0102_chip = 1, | 
|  | 1517 | .ca0151_chip = 1, | 
| Lee Revell | 2f020aa | 2005-11-07 14:54:24 +0100 | [diff] [blame] | 1518 | .spk71 = 1, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1519 | .spdif_bug = 1} , | 
| James Courtier-Dutton | 264f957 | 2006-07-30 17:17:59 +0100 | [diff] [blame] | 1520 | /* Dell OEM/Creative Labs Audigy 2 ZS */ | 
|  | 1521 | /* See ALSA bug#1365 */ | 
|  | 1522 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10031102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1523 | .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0353]", | 
| James Courtier-Dutton | 264f957 | 2006-07-30 17:17:59 +0100 | [diff] [blame] | 1524 | .id = "Audigy2", | 
|  | 1525 | .emu10k2_chip = 1, | 
|  | 1526 | .ca0102_chip = 1, | 
|  | 1527 | .ca0151_chip = 1, | 
|  | 1528 | .spk71 = 1, | 
|  | 1529 | .spdif_bug = 1, | 
| Takashi Iwai | 1f9da55 | 2009-02-24 15:31:02 +0100 | [diff] [blame] | 1530 | .invert_shared_spdif = 1,	/* digital/analog switch swapped */ | 
| James Courtier-Dutton | 264f957 | 2006-07-30 17:17:59 +0100 | [diff] [blame] | 1531 | .ac97_chip = 1} , | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1532 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1533 | .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]", | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1534 | .id = "Audigy2", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1535 | .emu10k2_chip = 1, | 
|  | 1536 | .ca0102_chip = 1, | 
|  | 1537 | .ca0151_chip = 1, | 
|  | 1538 | .spk71 = 1, | 
|  | 1539 | .spdif_bug = 1, | 
| Takashi Iwai | d2cd74b | 2008-06-02 11:45:53 +0200 | [diff] [blame] | 1540 | .invert_shared_spdif = 1,	/* digital/analog switch swapped */ | 
| James Courtier-Dutton | 3271b7b | 2006-11-25 22:02:47 +0000 | [diff] [blame] | 1541 | .adc_1361t = 1,  /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1542 | .ac97_chip = 1} , | 
| Takashi Iwai | bdaed50 | 2005-04-07 15:48:42 +0200 | [diff] [blame] | 1543 | {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1544 | .driver = "Audigy2", .name = "SB Audigy 2 [Unknown]", | 
| Takashi Iwai | bdaed50 | 2005-04-07 15:48:42 +0200 | [diff] [blame] | 1545 | .id = "Audigy2", | 
|  | 1546 | .emu10k2_chip = 1, | 
|  | 1547 | .ca0102_chip = 1, | 
|  | 1548 | .ca0151_chip = 1, | 
|  | 1549 | .spdif_bug = 1, | 
|  | 1550 | .ac97_chip = 1} , | 
| Peter Zubaj | 2668907 | 2005-04-01 11:15:07 +0200 | [diff] [blame] | 1551 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1552 | .driver = "Audigy", .name = "SB Audigy 1 [SB0092]", | 
| Peter Zubaj | 2668907 | 2005-04-01 11:15:07 +0200 | [diff] [blame] | 1553 | .id = "Audigy", | 
|  | 1554 | .emu10k2_chip = 1, | 
|  | 1555 | .ca0102_chip = 1, | 
|  | 1556 | .ac97_chip = 1} , | 
| James Courtier-Dutton | ae3a72d | 2005-07-06 22:36:18 +0200 | [diff] [blame] | 1557 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1558 | .driver = "Audigy", .name = "SB Audigy 1 ES [SB0160]", | 
| James Courtier-Dutton | ae3a72d | 2005-07-06 22:36:18 +0200 | [diff] [blame] | 1559 | .id = "Audigy", | 
|  | 1560 | .emu10k2_chip = 1, | 
|  | 1561 | .ca0102_chip = 1, | 
|  | 1562 | .spdif_bug = 1, | 
|  | 1563 | .ac97_chip = 1} , | 
| Arnaud Patard | a6c17ec | 2005-05-27 12:31:34 +0200 | [diff] [blame] | 1564 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1565 | .driver = "Audigy", .name = "SB Audigy 1 [SB0090]", | 
| Arnaud Patard | a6c17ec | 2005-05-27 12:31:34 +0200 | [diff] [blame] | 1566 | .id = "Audigy", | 
|  | 1567 | .emu10k2_chip = 1, | 
|  | 1568 | .ca0102_chip = 1, | 
|  | 1569 | .ac97_chip = 1} , | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1570 | {.vendor = 0x1102, .device = 0x0004, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1571 | .driver = "Audigy", .name = "Audigy 1 [Unknown]", | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1572 | .id = "Audigy", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1573 | .emu10k2_chip = 1, | 
|  | 1574 | .ca0102_chip = 1, | 
| Peter Zubaj | 2668907 | 2005-04-01 11:15:07 +0200 | [diff] [blame] | 1575 | .ac97_chip = 1} , | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1576 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102, | 
|  | 1577 | .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0220]", | 
| James Courtier-Dutton | 2b6b22f | 2005-06-18 13:50:22 +0200 | [diff] [blame] | 1578 | .id = "Live", | 
|  | 1579 | .emu10k1_chip = 1, | 
|  | 1580 | .ac97_chip = 1, | 
|  | 1581 | .sblive51 = 1} , | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1582 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806b1102, | 
|  | 1583 | .driver = "EMU10K1", .name = "SB Live! [SB0105]", | 
|  | 1584 | .id = "Live", | 
|  | 1585 | .emu10k1_chip = 1, | 
|  | 1586 | .ac97_chip = 1, | 
|  | 1587 | .sblive51 = 1} , | 
|  | 1588 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806a1102, | 
|  | 1589 | .driver = "EMU10K1", .name = "SB Live! Value [SB0103]", | 
| James Courtier-Dutton | 2b6b22f | 2005-06-18 13:50:22 +0200 | [diff] [blame] | 1590 | .id = "Live", | 
|  | 1591 | .emu10k1_chip = 1, | 
|  | 1592 | .ac97_chip = 1, | 
|  | 1593 | .sblive51 = 1} , | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1594 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1595 | .driver = "EMU10K1", .name = "SB Live! Value [SB0101]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1596 | .id = "Live", | 
|  | 1597 | .emu10k1_chip = 1, | 
|  | 1598 | .ac97_chip = 1, | 
|  | 1599 | .sblive51 = 1} , | 
| James Courtier-Dutton | 0ba656d | 2005-12-26 15:30:03 +0100 | [diff] [blame] | 1600 | /* Tested by ALSA bug#1680 26th December 2005 */ | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1601 | /* note: It really has SB0220 written on the card, */ | 
|  | 1602 | /* but it's SB0228 according to kx.inf */ | 
| James Courtier-Dutton | 0ba656d | 2005-12-26 15:30:03 +0100 | [diff] [blame] | 1603 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80661102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1604 | .driver = "EMU10K1", .name = "SB Live! 5.1 Dell OEM [SB0228]", | 
| James Courtier-Dutton | 0ba656d | 2005-12-26 15:30:03 +0100 | [diff] [blame] | 1605 | .id = "Live", | 
|  | 1606 | .emu10k1_chip = 1, | 
|  | 1607 | .ac97_chip = 1, | 
|  | 1608 | .sblive51 = 1} , | 
| Lee Revell | c6c0b84 | 2005-08-29 17:42:00 +0200 | [diff] [blame] | 1609 | /* Tested by Thomas Zehetbauer 27th Aug 2005 */ | 
|  | 1610 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1611 | .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0220]", | 
| Gergely Tamas | a8ee729 | 2005-12-06 14:10:57 +0100 | [diff] [blame] | 1612 | .id = "Live", | 
|  | 1613 | .emu10k1_chip = 1, | 
|  | 1614 | .ac97_chip = 1, | 
|  | 1615 | .sblive51 = 1} , | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1616 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1617 | .driver = "EMU10K1", .name = "SB Live! 5.1", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1618 | .id = "Live", | 
|  | 1619 | .emu10k1_chip = 1, | 
|  | 1620 | .ac97_chip = 1, | 
|  | 1621 | .sblive51 = 1} , | 
| James Courtier-Dutton | afe0f1f | 2005-09-10 10:24:10 +0200 | [diff] [blame] | 1622 | /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */ | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1623 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1624 | .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0060]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1625 | .id = "Live", | 
|  | 1626 | .emu10k1_chip = 1, | 
| Takashi Iwai | f12aa40 | 2005-09-30 16:56:59 +0200 | [diff] [blame] | 1627 | .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum | 
|  | 1628 | * share the same IDs! | 
|  | 1629 | */ | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1630 | .sblive51 = 1} , | 
|  | 1631 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1632 | .driver = "EMU10K1", .name = "SB Live! Value [CT4850]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1633 | .id = "Live", | 
|  | 1634 | .emu10k1_chip = 1, | 
|  | 1635 | .ac97_chip = 1, | 
|  | 1636 | .sblive51 = 1} , | 
|  | 1637 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1638 | .driver = "EMU10K1", .name = "SB Live! Platinum [CT4760P]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1639 | .id = "Live", | 
|  | 1640 | .emu10k1_chip = 1, | 
|  | 1641 | .ac97_chip = 1} , | 
|  | 1642 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1643 | .driver = "EMU10K1", .name = "SB Live! Value [CT4871]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1644 | .id = "Live", | 
|  | 1645 | .emu10k1_chip = 1, | 
|  | 1646 | .ac97_chip = 1, | 
|  | 1647 | .sblive51 = 1} , | 
|  | 1648 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1649 | .driver = "EMU10K1", .name = "SB Live! Value [CT4831]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1650 | .id = "Live", | 
|  | 1651 | .emu10k1_chip = 1, | 
|  | 1652 | .ac97_chip = 1, | 
|  | 1653 | .sblive51 = 1} , | 
|  | 1654 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1655 | .driver = "EMU10K1", .name = "SB Live! Value [CT4870]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1656 | .id = "Live", | 
|  | 1657 | .emu10k1_chip = 1, | 
|  | 1658 | .ac97_chip = 1, | 
|  | 1659 | .sblive51 = 1} , | 
| James Courtier-Dutton | 88dc0e5 | 2005-07-03 12:54:29 +0200 | [diff] [blame] | 1660 | /* Tested by James@superbug.co.uk 3rd July 2005 */ | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1661 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1662 | .driver = "EMU10K1", .name = "SB Live! Value [CT4832]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1663 | .id = "Live", | 
|  | 1664 | .emu10k1_chip = 1, | 
|  | 1665 | .ac97_chip = 1, | 
|  | 1666 | .sblive51 = 1} , | 
|  | 1667 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1668 | .driver = "EMU10K1", .name = "SB Live! Value [CT4830]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1669 | .id = "Live", | 
|  | 1670 | .emu10k1_chip = 1, | 
|  | 1671 | .ac97_chip = 1, | 
|  | 1672 | .sblive51 = 1} , | 
|  | 1673 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1674 | .driver = "EMU10K1", .name = "SB PCI512 [CT4790]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1675 | .id = "Live", | 
|  | 1676 | .emu10k1_chip = 1, | 
|  | 1677 | .ac97_chip = 1, | 
|  | 1678 | .sblive51 = 1} , | 
|  | 1679 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1680 | .driver = "EMU10K1", .name = "SB Live! Value [CT4780]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1681 | .id = "Live", | 
|  | 1682 | .emu10k1_chip = 1, | 
|  | 1683 | .ac97_chip = 1, | 
|  | 1684 | .sblive51 = 1} , | 
|  | 1685 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1686 | .driver = "EMU10K1", .name = "E-mu APS [PC545]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1687 | .id = "APS", | 
|  | 1688 | .emu10k1_chip = 1, | 
|  | 1689 | .ecard = 1} , | 
|  | 1690 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1691 | .driver = "EMU10K1", .name = "SB Live! [CT4620]", | 
| James Courtier-Dutton | a6f6192 | 2005-07-03 12:32:40 +0200 | [diff] [blame] | 1692 | .id = "Live", | 
|  | 1693 | .emu10k1_chip = 1, | 
|  | 1694 | .ac97_chip = 1, | 
|  | 1695 | .sblive51 = 1} , | 
|  | 1696 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1697 | .driver = "EMU10K1", .name = "SB Live! Value [CT4670]", | 
| James Courtier-Dutton | 2b6b22f | 2005-06-18 13:50:22 +0200 | [diff] [blame] | 1698 | .id = "Live", | 
|  | 1699 | .emu10k1_chip = 1, | 
|  | 1700 | .ac97_chip = 1, | 
|  | 1701 | .sblive51 = 1} , | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1702 | {.vendor = 0x1102, .device = 0x0002, | 
| Vedran Miletic | 18c7109 | 2008-10-21 17:42:54 +0200 | [diff] [blame] | 1703 | .driver = "EMU10K1", .name = "SB Live! [Unknown]", | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1704 | .id = "Live", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1705 | .emu10k1_chip = 1, | 
| Lee Revell | 2b637da | 2005-03-30 13:51:18 +0200 | [diff] [blame] | 1706 | .ac97_chip = 1, | 
|  | 1707 | .sblive51 = 1} , | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1708 | { } /* terminator */ | 
|  | 1709 | }; | 
|  | 1710 |  | 
| Takashi Iwai | eb4698f | 2005-11-17 14:50:13 +0100 | [diff] [blame] | 1711 | int __devinit snd_emu10k1_create(struct snd_card *card, | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1712 | struct pci_dev *pci, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1713 | unsigned short extin_mask, | 
|  | 1714 | unsigned short extout_mask, | 
|  | 1715 | long max_cache_bytes, | 
|  | 1716 | int enable_ir, | 
| James Courtier-Dutton | e66bc8b | 2005-07-06 22:21:51 +0200 | [diff] [blame] | 1717 | uint subsystem, | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1718 | struct snd_emu10k1 **remu) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1719 | { | 
| Takashi Iwai | eb4698f | 2005-11-17 14:50:13 +0100 | [diff] [blame] | 1720 | struct snd_emu10k1 *emu; | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1721 | int idx, err; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1722 | int is_audigy; | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1723 | unsigned int silent_page; | 
| Takashi Iwai | eb4698f | 2005-11-17 14:50:13 +0100 | [diff] [blame] | 1724 | const struct snd_emu_chip_details *c; | 
|  | 1725 | static struct snd_device_ops ops = { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1726 | .dev_free =	snd_emu10k1_dev_free, | 
|  | 1727 | }; | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1728 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1729 | *remu = NULL; | 
|  | 1730 |  | 
|  | 1731 | /* enable PCI device */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1732 | err = pci_enable_device(pci); | 
|  | 1733 | if (err < 0) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1734 | return err; | 
|  | 1735 |  | 
| Takashi Iwai | e560d8d | 2005-09-09 14:21:46 +0200 | [diff] [blame] | 1736 | emu = kzalloc(sizeof(*emu), GFP_KERNEL); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1737 | if (emu == NULL) { | 
|  | 1738 | pci_disable_device(pci); | 
|  | 1739 | return -ENOMEM; | 
|  | 1740 | } | 
|  | 1741 | emu->card = card; | 
|  | 1742 | spin_lock_init(&emu->reg_lock); | 
|  | 1743 | spin_lock_init(&emu->emu_lock); | 
| James Courtier-Dutton | c94fa4c | 2007-11-10 17:55:14 +0000 | [diff] [blame] | 1744 | spin_lock_init(&emu->spi_lock); | 
|  | 1745 | spin_lock_init(&emu->i2c_lock); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1746 | spin_lock_init(&emu->voice_lock); | 
|  | 1747 | spin_lock_init(&emu->synth_lock); | 
|  | 1748 | spin_lock_init(&emu->memblk_lock); | 
| Ingo Molnar | 62932df | 2006-01-16 16:34:20 +0100 | [diff] [blame] | 1749 | mutex_init(&emu->fx8010.lock); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1750 | INIT_LIST_HEAD(&emu->mapped_link_head); | 
|  | 1751 | INIT_LIST_HEAD(&emu->mapped_order_link_head); | 
|  | 1752 | emu->pci = pci; | 
|  | 1753 | emu->irq = -1; | 
|  | 1754 | emu->synth = NULL; | 
|  | 1755 | emu->get_synth_voice = NULL; | 
|  | 1756 | /* read revision & serial */ | 
| Auke Kok | 44c1013 | 2007-06-08 15:46:36 -0700 | [diff] [blame] | 1757 | emu->revision = pci->revision; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1758 | pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial); | 
|  | 1759 | pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1760 | snd_printdd("vendor = 0x%x, device = 0x%x, subsystem_vendor_id = 0x%x, subsystem_id = 0x%x\n", pci->vendor, pci->device, emu->serial, emu->model); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1761 |  | 
|  | 1762 | for (c = emu_chip_details; c->vendor; c++) { | 
|  | 1763 | if (c->vendor == pci->vendor && c->device == pci->device) { | 
| James Courtier-Dutton | e66bc8b | 2005-07-06 22:21:51 +0200 | [diff] [blame] | 1764 | if (subsystem) { | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1765 | if (c->subsystem && (c->subsystem == subsystem)) | 
| James Courtier-Dutton | e66bc8b | 2005-07-06 22:21:51 +0200 | [diff] [blame] | 1766 | break; | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1767 | else | 
|  | 1768 | continue; | 
| James Courtier-Dutton | e66bc8b | 2005-07-06 22:21:51 +0200 | [diff] [blame] | 1769 | } else { | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1770 | if (c->subsystem && (c->subsystem != emu->serial)) | 
| James Courtier-Dutton | e66bc8b | 2005-07-06 22:21:51 +0200 | [diff] [blame] | 1771 | continue; | 
|  | 1772 | if (c->revision && c->revision != emu->revision) | 
|  | 1773 | continue; | 
|  | 1774 | } | 
| Takashi Iwai | bdaed50 | 2005-04-07 15:48:42 +0200 | [diff] [blame] | 1775 | break; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1776 | } | 
|  | 1777 | } | 
|  | 1778 | if (c->vendor == 0) { | 
|  | 1779 | snd_printk(KERN_ERR "emu10k1: Card not recognised\n"); | 
|  | 1780 | kfree(emu); | 
|  | 1781 | pci_disable_device(pci); | 
|  | 1782 | return -ENOENT; | 
|  | 1783 | } | 
|  | 1784 | emu->card_capabilities = c; | 
| James Courtier-Dutton | e66bc8b | 2005-07-06 22:21:51 +0200 | [diff] [blame] | 1785 | if (c->subsystem && !subsystem) | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1786 | snd_printdd("Sound card name = %s\n", c->name); | 
|  | 1787 | else if (subsystem) | 
|  | 1788 | snd_printdd("Sound card name = %s, " | 
|  | 1789 | "vendor = 0x%x, device = 0x%x, subsystem = 0x%x. " | 
|  | 1790 | "Forced to subsytem = 0x%x\n",	c->name, | 
|  | 1791 | pci->vendor, pci->device, emu->serial, c->subsystem); | 
|  | 1792 | else | 
|  | 1793 | snd_printdd("Sound card name = %s, " | 
|  | 1794 | "vendor = 0x%x, device = 0x%x, subsystem = 0x%x.\n", | 
|  | 1795 | c->name, pci->vendor, pci->device, | 
|  | 1796 | emu->serial); | 
|  | 1797 |  | 
| Takashi Iwai | 85a655d | 2005-03-30 14:40:25 +0200 | [diff] [blame] | 1798 | if (!*card->id && c->id) { | 
|  | 1799 | int i, n = 0; | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1800 | strlcpy(card->id, c->id, sizeof(card->id)); | 
| Takashi Iwai | 85a655d | 2005-03-30 14:40:25 +0200 | [diff] [blame] | 1801 | for (;;) { | 
|  | 1802 | for (i = 0; i < snd_ecards_limit; i++) { | 
|  | 1803 | if (snd_cards[i] && !strcmp(snd_cards[i]->id, card->id)) | 
|  | 1804 | break; | 
|  | 1805 | } | 
|  | 1806 | if (i >= snd_ecards_limit) | 
|  | 1807 | break; | 
|  | 1808 | n++; | 
|  | 1809 | if (n >= SNDRV_CARDS) | 
|  | 1810 | break; | 
|  | 1811 | snprintf(card->id, sizeof(card->id), "%s_%d", c->id, n); | 
|  | 1812 | } | 
|  | 1813 | } | 
| Takashi Iwai | aec72e0 | 2005-03-30 14:22:25 +0200 | [diff] [blame] | 1814 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1815 | is_audigy = emu->audigy = c->emu10k2_chip; | 
|  | 1816 |  | 
|  | 1817 | /* set the DMA transfer mask */ | 
|  | 1818 | emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK; | 
|  | 1819 | if (pci_set_dma_mask(pci, emu->dma_mask) < 0 || | 
|  | 1820 | pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) { | 
|  | 1821 | snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask); | 
|  | 1822 | kfree(emu); | 
|  | 1823 | pci_disable_device(pci); | 
|  | 1824 | return -ENXIO; | 
|  | 1825 | } | 
|  | 1826 | if (is_audigy) | 
|  | 1827 | emu->gpr_base = A_FXGPREGBASE; | 
|  | 1828 | else | 
|  | 1829 | emu->gpr_base = FXGPREGBASE; | 
|  | 1830 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1831 | err = pci_request_regions(pci, "EMU10K1"); | 
|  | 1832 | if (err < 0) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1833 | kfree(emu); | 
|  | 1834 | pci_disable_device(pci); | 
|  | 1835 | return err; | 
|  | 1836 | } | 
|  | 1837 | emu->port = pci_resource_start(pci, 0); | 
|  | 1838 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1839 | emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT; | 
|  | 1840 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), | 
|  | 1841 | 32 * 1024, &emu->ptb_pages) < 0) { | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1842 | err = -ENOMEM; | 
|  | 1843 | goto error; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1844 | } | 
|  | 1845 |  | 
| Jesper Juhl | 36726d9 | 2007-08-28 15:21:33 +0200 | [diff] [blame] | 1846 | emu->page_ptr_table = vmalloc(emu->max_cache_pages * sizeof(void *)); | 
|  | 1847 | emu->page_addr_table = vmalloc(emu->max_cache_pages * | 
|  | 1848 | sizeof(unsigned long)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1849 | if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) { | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1850 | err = -ENOMEM; | 
|  | 1851 | goto error; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1852 | } | 
|  | 1853 |  | 
|  | 1854 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), | 
|  | 1855 | EMUPAGESIZE, &emu->silent_page) < 0) { | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1856 | err = -ENOMEM; | 
|  | 1857 | goto error; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1858 | } | 
|  | 1859 | emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE); | 
|  | 1860 | if (emu->memhdr == NULL) { | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1861 | err = -ENOMEM; | 
|  | 1862 | goto error; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1863 | } | 
| Takashi Iwai | eb4698f | 2005-11-17 14:50:13 +0100 | [diff] [blame] | 1864 | emu->memhdr->block_extra_size = sizeof(struct snd_emu10k1_memblk) - | 
|  | 1865 | sizeof(struct snd_util_memblk); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1866 |  | 
|  | 1867 | pci_set_master(pci); | 
|  | 1868 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1869 | emu->fx8010.fxbus_mask = 0x303f; | 
|  | 1870 | if (extin_mask == 0) | 
|  | 1871 | extin_mask = 0x3fcf; | 
|  | 1872 | if (extout_mask == 0) | 
|  | 1873 | extout_mask = 0x7fff; | 
|  | 1874 | emu->fx8010.extin_mask = extin_mask; | 
|  | 1875 | emu->fx8010.extout_mask = extout_mask; | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1876 | emu->enable_ir = enable_ir; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1877 |  | 
| James Courtier-Dutton | d9e8a55 | 2007-07-14 10:24:49 +0100 | [diff] [blame] | 1878 | if (emu->card_capabilities->ca_cardbus_chip) { | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1879 | err = snd_emu10k1_cardbus_init(emu); | 
|  | 1880 | if (err < 0) | 
| James Courtier-Dutton | d9e8a55 | 2007-07-14 10:24:49 +0100 | [diff] [blame] | 1881 | goto error; | 
|  | 1882 | } | 
| Lee Revell | 2b637da | 2005-03-30 13:51:18 +0200 | [diff] [blame] | 1883 | if (emu->card_capabilities->ecard) { | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1884 | err = snd_emu10k1_ecard_init(emu); | 
|  | 1885 | if (err < 0) | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1886 | goto error; | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 1887 | } else if (emu->card_capabilities->emu_model) { | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1888 | err = snd_emu10k1_emu1010_init(emu); | 
|  | 1889 | if (err < 0) { | 
|  | 1890 | snd_emu10k1_free(emu); | 
|  | 1891 | return err; | 
|  | 1892 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1893 | } else { | 
|  | 1894 | /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version | 
|  | 1895 | does not support this, it shouldn't do any harm */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1896 | snd_emu10k1_ptr_write(emu, AC97SLOT, 0, | 
|  | 1897 | AC97SLOT_CNTR|AC97SLOT_LFE); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1898 | } | 
|  | 1899 |  | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1900 | /* initialize TRAM setup */ | 
|  | 1901 | emu->fx8010.itram_size = (16 * 1024)/2; | 
|  | 1902 | emu->fx8010.etram_pages.area = NULL; | 
|  | 1903 | emu->fx8010.etram_pages.bytes = 0; | 
|  | 1904 |  | 
| Jaroslav Franek | 868e15db | 2008-06-06 11:04:19 +0200 | [diff] [blame] | 1905 | /* irq handler must be registered after I/O ports are activated */ | 
|  | 1906 | if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED, | 
|  | 1907 | "EMU10K1", emu)) { | 
|  | 1908 | err = -EBUSY; | 
|  | 1909 | goto error; | 
|  | 1910 | } | 
|  | 1911 | emu->irq = pci->irq; | 
|  | 1912 |  | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1913 | /* | 
|  | 1914 | *  Init to 0x02109204 : | 
|  | 1915 | *  Clock accuracy    = 0     (1000ppm) | 
|  | 1916 | *  Sample Rate       = 2     (48kHz) | 
|  | 1917 | *  Audio Channel     = 1     (Left of 2) | 
|  | 1918 | *  Source Number     = 0     (Unspecified) | 
|  | 1919 | *  Generation Status = 1     (Original for Cat Code 12) | 
|  | 1920 | *  Cat Code          = 12    (Digital Signal Mixer) | 
|  | 1921 | *  Mode              = 0     (Mode 0) | 
|  | 1922 | *  Emphasis          = 0     (None) | 
|  | 1923 | *  CP                = 1     (Copyright unasserted) | 
|  | 1924 | *  AN                = 0     (Audio data) | 
|  | 1925 | *  P                 = 0     (Consumer) | 
|  | 1926 | */ | 
|  | 1927 | emu->spdif_bits[0] = emu->spdif_bits[1] = | 
|  | 1928 | emu->spdif_bits[2] = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | | 
|  | 1929 | SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | | 
|  | 1930 | SPCS_GENERATIONSTATUS | 0x00001200 | | 
|  | 1931 | 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT; | 
|  | 1932 |  | 
|  | 1933 | emu->reserved_page = (struct snd_emu10k1_memblk *) | 
|  | 1934 | snd_emu10k1_synth_alloc(emu, 4096); | 
|  | 1935 | if (emu->reserved_page) | 
|  | 1936 | emu->reserved_page->map_locked = 1; | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1937 |  | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1938 | /* Clear silent pages and set up pointers */ | 
|  | 1939 | memset(emu->silent_page.area, 0, PAGE_SIZE); | 
|  | 1940 | silent_page = emu->silent_page.addr << 1; | 
|  | 1941 | for (idx = 0; idx < MAXPAGES; idx++) | 
|  | 1942 | ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx); | 
|  | 1943 |  | 
|  | 1944 | /* set up voice indices */ | 
|  | 1945 | for (idx = 0; idx < NUM_G; idx++) { | 
|  | 1946 | emu->voices[idx].emu = emu; | 
|  | 1947 | emu->voices[idx].number = idx; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1948 | } | 
|  | 1949 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1950 | err = snd_emu10k1_init(emu, enable_ir, 0); | 
|  | 1951 | if (err < 0) | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1952 | goto error; | 
|  | 1953 | #ifdef CONFIG_PM | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1954 | err = alloc_pm_buffer(emu); | 
|  | 1955 | if (err < 0) | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1956 | goto error; | 
|  | 1957 | #endif | 
|  | 1958 |  | 
|  | 1959 | /*  Initialize the effect engine */ | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1960 | err = snd_emu10k1_init_efx(emu); | 
|  | 1961 | if (err < 0) | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1962 | goto error; | 
|  | 1963 | snd_emu10k1_audio_enable(emu); | 
|  | 1964 |  | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 1965 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops); | 
|  | 1966 | if (err < 0) | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1967 | goto error; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1968 |  | 
| Takashi Iwai | adf1b3d | 2005-12-01 10:49:58 +0100 | [diff] [blame] | 1969 | #ifdef CONFIG_PROC_FS | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1970 | snd_emu10k1_proc_init(emu); | 
| Takashi Iwai | adf1b3d | 2005-12-01 10:49:58 +0100 | [diff] [blame] | 1971 | #endif | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1972 |  | 
|  | 1973 | snd_card_set_dev(card, &pci->dev); | 
|  | 1974 | *remu = emu; | 
|  | 1975 | return 0; | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1976 |  | 
|  | 1977 | error: | 
|  | 1978 | snd_emu10k1_free(emu); | 
|  | 1979 | return err; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1980 | } | 
|  | 1981 |  | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 1982 | #ifdef CONFIG_PM | 
|  | 1983 | static unsigned char saved_regs[] = { | 
|  | 1984 | CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP, | 
|  | 1985 | FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL, | 
|  | 1986 | ATKHLDM, DCYSUSM, LFOVAL2, IP, IFATN, PEFE, FMMOD, TREMFRQ, FM2FRQ2, | 
|  | 1987 | TEMPENV, ADCCR, FXWC, MICBA, ADCBA, FXBA, | 
|  | 1988 | MICBS, ADCBS, FXBS, CDCS, GPSCS, SPCS0, SPCS1, SPCS2, | 
|  | 1989 | SPBYPASS, AC97SLOT, CDSRCS, GPSRCS, ZVSRCS, MICIDX, ADCIDX, FXIDX, | 
|  | 1990 | 0xff /* end */ | 
|  | 1991 | }; | 
|  | 1992 | static unsigned char saved_regs_audigy[] = { | 
|  | 1993 | A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_SAMPLE_RATE, | 
|  | 1994 | A_FXRT2, A_SENDAMOUNTS, A_FXRT1, | 
|  | 1995 | 0xff /* end */ | 
|  | 1996 | }; | 
|  | 1997 |  | 
|  | 1998 | static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu) | 
|  | 1999 | { | 
|  | 2000 | int size; | 
|  | 2001 |  | 
|  | 2002 | size = ARRAY_SIZE(saved_regs); | 
|  | 2003 | if (emu->audigy) | 
|  | 2004 | size += ARRAY_SIZE(saved_regs_audigy); | 
|  | 2005 | emu->saved_ptr = vmalloc(4 * NUM_G * size); | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 2006 | if (!emu->saved_ptr) | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 2007 | return -ENOMEM; | 
|  | 2008 | if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0) | 
|  | 2009 | return -ENOMEM; | 
|  | 2010 | if (emu->card_capabilities->ca0151_chip && | 
|  | 2011 | snd_p16v_alloc_pm_buffer(emu) < 0) | 
|  | 2012 | return -ENOMEM; | 
|  | 2013 | return 0; | 
|  | 2014 | } | 
|  | 2015 |  | 
|  | 2016 | static void free_pm_buffer(struct snd_emu10k1 *emu) | 
|  | 2017 | { | 
|  | 2018 | vfree(emu->saved_ptr); | 
|  | 2019 | snd_emu10k1_efx_free_pm_buffer(emu); | 
|  | 2020 | if (emu->card_capabilities->ca0151_chip) | 
|  | 2021 | snd_p16v_free_pm_buffer(emu); | 
|  | 2022 | } | 
|  | 2023 |  | 
|  | 2024 | void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu) | 
|  | 2025 | { | 
|  | 2026 | int i; | 
|  | 2027 | unsigned char *reg; | 
|  | 2028 | unsigned int *val; | 
|  | 2029 |  | 
|  | 2030 | val = emu->saved_ptr; | 
|  | 2031 | for (reg = saved_regs; *reg != 0xff; reg++) | 
|  | 2032 | for (i = 0; i < NUM_G; i++, val++) | 
|  | 2033 | *val = snd_emu10k1_ptr_read(emu, *reg, i); | 
|  | 2034 | if (emu->audigy) { | 
|  | 2035 | for (reg = saved_regs_audigy; *reg != 0xff; reg++) | 
|  | 2036 | for (i = 0; i < NUM_G; i++, val++) | 
|  | 2037 | *val = snd_emu10k1_ptr_read(emu, *reg, i); | 
|  | 2038 | } | 
|  | 2039 | if (emu->audigy) | 
|  | 2040 | emu->saved_a_iocfg = inl(emu->port + A_IOCFG); | 
|  | 2041 | emu->saved_hcfg = inl(emu->port + HCFG); | 
|  | 2042 | } | 
|  | 2043 |  | 
|  | 2044 | void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) | 
|  | 2045 | { | 
| James Courtier-Dutton | d9e8a55 | 2007-07-14 10:24:49 +0100 | [diff] [blame] | 2046 | if (emu->card_capabilities->ca_cardbus_chip) | 
|  | 2047 | snd_emu10k1_cardbus_init(emu); | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 2048 | if (emu->card_capabilities->ecard) | 
|  | 2049 | snd_emu10k1_ecard_init(emu); | 
| James Courtier-Dutton | 190d2c4 | 2007-11-04 14:08:26 +0000 | [diff] [blame] | 2050 | else if (emu->card_capabilities->emu_model) | 
| Vedran Miletic | 67679b1 | 2008-10-23 18:51:00 +0200 | [diff] [blame] | 2051 | snd_emu10k1_emu1010_init(emu); | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 2052 | else | 
|  | 2053 | snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); | 
|  | 2054 | snd_emu10k1_init(emu, emu->enable_ir, 1); | 
|  | 2055 | } | 
|  | 2056 |  | 
|  | 2057 | void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu) | 
|  | 2058 | { | 
|  | 2059 | int i; | 
|  | 2060 | unsigned char *reg; | 
|  | 2061 | unsigned int *val; | 
|  | 2062 |  | 
|  | 2063 | snd_emu10k1_audio_enable(emu); | 
|  | 2064 |  | 
|  | 2065 | /* resore for spdif */ | 
|  | 2066 | if (emu->audigy) | 
| Arnaud Patard | 4130d59 | 2006-10-04 18:21:05 +0200 | [diff] [blame] | 2067 | outl(emu->saved_a_iocfg, emu->port + A_IOCFG); | 
|  | 2068 | outl(emu->saved_hcfg, emu->port + HCFG); | 
| Takashi Iwai | 09668b4 | 2005-11-17 16:14:10 +0100 | [diff] [blame] | 2069 |  | 
|  | 2070 | val = emu->saved_ptr; | 
|  | 2071 | for (reg = saved_regs; *reg != 0xff; reg++) | 
|  | 2072 | for (i = 0; i < NUM_G; i++, val++) | 
|  | 2073 | snd_emu10k1_ptr_write(emu, *reg, i, *val); | 
|  | 2074 | if (emu->audigy) { | 
|  | 2075 | for (reg = saved_regs_audigy; *reg != 0xff; reg++) | 
|  | 2076 | for (i = 0; i < NUM_G; i++, val++) | 
|  | 2077 | snd_emu10k1_ptr_write(emu, *reg, i, *val); | 
|  | 2078 | } | 
|  | 2079 | } | 
|  | 2080 | #endif |