1 /* 2 * Copyright (c) 1998-2002 by Paul Davis <pbd@op.net> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19 #include <sound/driver.h> 20 #include <asm/io.h> 21 #include <linux/init.h> 22 #include <linux/time.h> 23 #include <linux/wait.h> 24 #include <sound/core.h> 25 #include <sound/snd_wavefront.h> 26 #include <sound/initval.h> 27 28 /* Control bits for the Load Control Register 29 */ 30 31 #define FX_LSB_TRANSFER 0x01 /* transfer after DSP LSB byte written */ 32 #define FX_MSB_TRANSFER 0x02 /* transfer after DSP MSB byte written */ 33 #define FX_AUTO_INCR 0x04 /* auto-increment DSP address after transfer */ 34 35 /* weird stuff, derived from port I/O tracing with dosemu */ 36 37 static unsigned char page_zero[] __initdata = { 38 0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, 39 0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00, 40 0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00, 41 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x19, 50 0x01, 0x1a, 0x01, 0x20, 0x01, 0x40, 0x01, 0x17, 0x00, 0x00, 0x01, 51 0x80, 0x01, 0x20, 0x00, 0x10, 0x01, 0xa0, 0x03, 0xd1, 0x00, 0x00, 52 0x01, 0xf2, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf4, 0x02, 53 0xe0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 54 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x00, 0x00, 55 0x40, 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x60, 0x00, 0x00, 56 0x00, 0x92, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb3, 0x02, 57 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x40, 58 0x00, 0x80, 0x00, 0xf5, 0x00, 0x20, 0x00, 0x70, 0x00, 0xa0, 0x02, 59 0x11, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 60 0x02, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x17, 0x00, 0x1b, 0x00, 61 0x1d, 0x02, 0xdf 62 }; 63 64 static unsigned char page_one[] __initdata = { 65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00, 66 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00, 67 0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 68 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x60, 77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x80, 0x00, 78 0x00, 0x02, 0xfb, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x1b, 0x02, 0xd7, 79 0x00, 0x00, 0x02, 0xf7, 0x03, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 80 0x1c, 0x03, 0x3c, 0x00, 0x00, 0x03, 0x3f, 0x00, 0x00, 0x03, 0xc0, 81 0x00, 0x00, 0x03, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5d, 0x00, 82 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0x7d, 0x00, 0x00, 0x03, 0xc0, 83 0x00, 0x00, 0x03, 0x9e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 84 0xbe, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 86 0xdb, 0x00, 0x00, 0x02, 0xdb, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 87 0x02, 0xfb, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xfb, 0x02, 88 0x60, 0x00, 0x1b 89 }; 90 91 static unsigned char page_two[] __initdata = { 92 0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4, 93 0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x07, 98 0x05, 0x05, 0x05, 0x04, 0x07, 0x05, 0x04, 0x07, 0x05, 0x44, 0x46, 99 0x44, 0x46, 0x46, 0x07, 0x05, 0x44, 0x46, 0x05, 0x46, 0x05, 0x46, 100 0x05, 0x46, 0x05, 0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, 101 0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, 0x44, 0x05, 0x05, 102 0x05, 0x44, 0x05, 0x05, 0x05, 0x46, 0x05, 0x46, 0x05, 0x46, 0x05, 103 0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44 104 }; 105 106 static unsigned char page_three[] __initdata = { 107 0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06, 108 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 113 0xc0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 114 0x60, 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x42, 0x00, 0x40, 115 0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 116 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 117 0x00, 0x42, 0x00, 0x40, 0x00, 0x42, 0x00, 0x02, 0x00, 0x02, 0x00, 118 0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40 119 }; 120 121 static unsigned char page_four[] __initdata = { 122 0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02, 123 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 128 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 129 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00, 130 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 131 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 132 0x20, 0x00, 0x22, 0x02, 0x22, 0x02, 0x20, 0x00, 0x60, 0x00, 0x22, 133 0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01 134 }; 135 136 static unsigned char page_six[] __initdata = { 137 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, 138 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e, 139 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00, 140 0x16, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x1c, 0x00, 141 0x00, 0x1e, 0x00, 0x00, 0x20, 0x00, 0x00, 0x22, 0x00, 0x00, 0x24, 142 0x00, 0x00, 0x26, 0x00, 0x00, 0x28, 0x00, 0x00, 0x2a, 0x00, 0x00, 143 0x2c, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x32, 0x00, 144 0x00, 0x34, 0x00, 0x00, 0x36, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3a, 145 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0x00, 146 0x42, 0x03, 0x00, 0x44, 0x01, 0x00, 0x46, 0x0a, 0x21, 0x48, 0x0d, 147 0x23, 0x4a, 0x23, 0x1b, 0x4c, 0x37, 0x8f, 0x4e, 0x45, 0x77, 0x50, 148 0x52, 0xe2, 0x52, 0x1c, 0x92, 0x54, 0x1c, 0x52, 0x56, 0x07, 0x00, 149 0x58, 0x2f, 0xc6, 0x5a, 0x0b, 0x00, 0x5c, 0x30, 0x06, 0x5e, 0x17, 150 0x00, 0x60, 0x3d, 0xda, 0x62, 0x29, 0x00, 0x64, 0x3e, 0x41, 0x66, 151 0x39, 0x00, 0x68, 0x4c, 0x48, 0x6a, 0x49, 0x00, 0x6c, 0x4c, 0x6c, 152 0x6e, 0x11, 0xd2, 0x70, 0x16, 0x0c, 0x72, 0x00, 0x00, 0x74, 0x00, 153 0x80, 0x76, 0x0f, 0x00, 0x78, 0x00, 0x80, 0x7a, 0x13, 0x00, 0x7c, 154 0x80, 0x00, 0x7e, 0x80, 0x80 155 }; 156 157 static unsigned char page_seven[] __initdata = { 158 0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 159 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 160 0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 161 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff, 172 0x0f, 0xff, 0x0f, 0xff, 0x02, 0xe9, 0x06, 0x8c, 0x06, 0x8c, 0x0f, 173 0xff, 0x1a, 0x75, 0x0d, 0x8b, 0x04, 0xe9, 0x0b, 0x16, 0x1a, 0x38, 174 0x0d, 0xc8, 0x04, 0x6f, 0x0b, 0x91, 0x0f, 0xff, 0x06, 0x40, 0x06, 175 0x40, 0x02, 0x8f, 0x0f, 0xff, 0x06, 0x62, 0x06, 0x62, 0x02, 0x7b, 176 0x0f, 0xff, 0x06, 0x97, 0x06, 0x97, 0x02, 0x52, 0x0f, 0xff, 0x06, 177 0xf6, 0x06, 0xf6, 0x02, 0x19, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 178 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x14, 179 0xda, 0x0d, 0x93, 0x04, 0xda, 0x05, 0x93, 0x14, 0xda, 0x0d, 0x93, 180 0x04, 0xda, 0x05, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 181 0x00, 0x02, 0x00 182 }; 183 184 static unsigned char page_zero_v2[] __initdata = { 185 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 194 }; 195 196 static unsigned char page_one_v2[] __initdata = { 197 0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 206 }; 207 208 static unsigned char page_two_v2[] __initdata = { 209 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 213 0x00, 0x00, 0x00, 0x00 214 }; 215 static unsigned char page_three_v2[] __initdata = { 216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 220 0x00, 0x00, 0x00, 0x00 221 }; 222 static unsigned char page_four_v2[] __initdata = { 223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 227 0x00, 0x00, 0x00, 0x00 228 }; 229 230 static unsigned char page_seven_v2[] __initdata = { 231 0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 233 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 240 }; 241 242 static unsigned char mod_v2[] __initdata = { 243 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, 244 0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05, 245 0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0, 246 0x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20, 0xb4, 0x20, 0xb5, 0x20, 247 0xb6, 0x20, 0xb7, 0x20, 0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3, 248 0x20, 0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20, 0x10, 0xff, 249 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0xff, 0x15, 0xff, 0x16, 250 0xff, 0x17, 0xff, 0x20, 0xff, 0x21, 0xff, 0x22, 0xff, 0x23, 0xff, 251 0x24, 0xff, 0x25, 0xff, 0x26, 0xff, 0x27, 0xff, 0x30, 0x00, 0x31, 252 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 253 0x37, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 254 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x50, 0x00, 0x51, 0x00, 255 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 256 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 257 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x70, 0xc0, 0x71, 0xc0, 0x72, 258 0xc0, 0x73, 0xc0, 0x74, 0xc0, 0x75, 0xc0, 0x76, 0xc0, 0x77, 0xc0, 259 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 260 0x00, 0x86, 0x00, 0x87, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 261 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0xa0, 262 0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa5, 0x00, 263 0xa6, 0x00, 0xa7, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3, 264 0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xd0, 0x00, 265 0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0xd6, 266 0x00, 0xd7, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe3, 0x00, 267 0xe4, 0x00, 0xe5, 0x00, 0xe6, 0x00, 0xe7, 0x00, 0x01, 0x00, 0x02, 268 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03, 269 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01, 270 0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01 271 }; 272 static unsigned char coefficients[] __initdata = { 273 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03, 274 0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 275 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01, 276 0x40, 0x02, 0x40, 0x01, 0x41, 0x02, 0x60, 0x07, 0x40, 0x00, 0x00, 277 0x07, 0x41, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 0x07, 0x4a, 0x00, 278 0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x4a, 0x01, 0x20, 0x07, 0x47, 279 0x00, 0x00, 0x07, 0x4a, 0x00, 0x00, 0x07, 0x7c, 0x00, 0x00, 0x07, 280 0x7e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x07, 0x7c, 0x00, 0x00, 281 0x07, 0x7e, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x00, 0x44, 0x01, 282 0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, 283 0x00, 0x00, 0x00, 0x42, 0x01, 0x1a, 0x00, 0x43, 0x01, 0x20, 0x07, 284 0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 285 0x07, 0x41, 0x00, 0x00, 0x01, 0x40, 0x02, 0x40, 0x01, 0x41, 0x02, 286 0x60, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x44, 287 0x0f, 0xff, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, 288 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x51, 0x06, 0x40, 289 0x07, 0x50, 0x06, 0x40, 0x07, 0x4f, 0x03, 0x81, 0x07, 0x53, 0x1a, 290 0x76, 0x07, 0x54, 0x0d, 0x8b, 0x07, 0x55, 0x04, 0xe9, 0x07, 0x56, 291 0x0b, 0x17, 0x07, 0x57, 0x1a, 0x38, 0x07, 0x58, 0x0d, 0xc9, 0x07, 292 0x59, 0x04, 0x6f, 0x07, 0x5a, 0x0b, 0x91, 0x07, 0x73, 0x14, 0xda, 293 0x07, 0x74, 0x0d, 0x93, 0x07, 0x75, 0x04, 0xd9, 0x07, 0x76, 0x05, 294 0x93, 0x07, 0x77, 0x14, 0xda, 0x07, 0x78, 0x0d, 0x93, 0x07, 0x79, 295 0x04, 0xd9, 0x07, 0x7a, 0x05, 0x93, 0x07, 0x5e, 0x03, 0x68, 0x07, 296 0x5c, 0x04, 0x31, 0x07, 0x5d, 0x04, 0x31, 0x07, 0x62, 0x03, 0x52, 297 0x07, 0x60, 0x04, 0x76, 0x07, 0x61, 0x04, 0x76, 0x07, 0x66, 0x03, 298 0x2e, 0x07, 0x64, 0x04, 0xda, 0x07, 0x65, 0x04, 0xda, 0x07, 0x6a, 299 0x02, 0xf6, 0x07, 0x68, 0x05, 0x62, 0x07, 0x69, 0x05, 0x62, 0x06, 300 0x46, 0x0a, 0x22, 0x06, 0x48, 0x0d, 0x24, 0x06, 0x6e, 0x11, 0xd3, 301 0x06, 0x70, 0x15, 0xcb, 0x06, 0x52, 0x20, 0x93, 0x06, 0x54, 0x20, 302 0x54, 0x06, 0x4a, 0x27, 0x1d, 0x06, 0x58, 0x2f, 0xc8, 0x06, 0x5c, 303 0x30, 0x07, 0x06, 0x4c, 0x37, 0x90, 0x06, 0x60, 0x3d, 0xdb, 0x06, 304 0x64, 0x3e, 0x42, 0x06, 0x4e, 0x45, 0x78, 0x06, 0x68, 0x4c, 0x48, 305 0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02, 306 0xba 307 }; 308 static unsigned char coefficients2[] __initdata = { 309 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f, 310 0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d, 311 0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07, 312 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 313 0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00 314 }; 315 static unsigned char coefficients3[] __initdata = { 316 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00, 317 0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc, 318 0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01, 319 0x47, 0x01, 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x99, 0x01, 0x99, 320 0x01, 0xc2, 0x01, 0xc2, 0x01, 0xeb, 0x01, 0xeb, 0x02, 0x14, 0x02, 321 0x14, 0x02, 0x3d, 0x02, 0x3d, 0x02, 0x66, 0x02, 0x66, 0x02, 0x8f, 322 0x02, 0x8f, 0x02, 0xb8, 0x02, 0xb8, 0x02, 0xe1, 0x02, 0xe1, 0x03, 323 0x0a, 0x03, 0x0a, 0x03, 0x33, 0x03, 0x33, 0x03, 0x5c, 0x03, 0x5c, 324 0x03, 0x85, 0x03, 0x85, 0x03, 0xae, 0x03, 0xae, 0x03, 0xd7, 0x03, 325 0xd7, 0x04, 0x00, 0x04, 0x00, 0x04, 0x28, 0x04, 0x28, 0x04, 0x51, 326 0x04, 0x51, 0x04, 0x7a, 0x04, 0x7a, 0x04, 0xa3, 0x04, 0xa3, 0x04, 327 0xcc, 0x04, 0xcc, 0x04, 0xf5, 0x04, 0xf5, 0x05, 0x1e, 0x05, 0x1e, 328 0x05, 0x47, 0x05, 0x47, 0x05, 0x70, 0x05, 0x70, 0x05, 0x99, 0x05, 329 0x99, 0x05, 0xc2, 0x05, 0xc2, 0x05, 0xeb, 0x05, 0xeb, 0x06, 0x14, 330 0x06, 0x14, 0x06, 0x3d, 0x06, 0x3d, 0x06, 0x66, 0x06, 0x66, 0x06, 331 0x8f, 0x06, 0x8f, 0x06, 0xb8, 0x06, 0xb8, 0x06, 0xe1, 0x06, 0xe1, 332 0x07, 0x0a, 0x07, 0x0a, 0x07, 0x33, 0x07, 0x33, 0x07, 0x5c, 0x07, 333 0x5c, 0x07, 0x85, 0x07, 0x85, 0x07, 0xae, 0x07, 0xae, 0x07, 0xd7, 334 0x07, 0xd7, 0x08, 0x00, 0x08, 0x00, 0x08, 0x28, 0x08, 0x28, 0x08, 335 0x51, 0x08, 0x51, 0x08, 0x7a, 0x08, 0x7a, 0x08, 0xa3, 0x08, 0xa3, 336 0x08, 0xcc, 0x08, 0xcc, 0x08, 0xf5, 0x08, 0xf5, 0x09, 0x1e, 0x09, 337 0x1e, 0x09, 0x47, 0x09, 0x47, 0x09, 0x70, 0x09, 0x70, 0x09, 0x99, 338 0x09, 0x99, 0x09, 0xc2, 0x09, 0xc2, 0x09, 0xeb, 0x09, 0xeb, 0x0a, 339 0x14, 0x0a, 0x14, 0x0a, 0x3d, 0x0a, 0x3d, 0x0a, 0x66, 0x0a, 0x66, 340 0x0a, 0x8f, 0x0a, 0x8f, 0x0a, 0xb8, 0x0a, 0xb8, 0x0a, 0xe1, 0x0a, 341 0xe1, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, 0x33, 0x0b, 0x33, 0x0b, 0x5c, 342 0x0b, 0x5c, 0x0b, 0x85, 0x0b, 0x85, 0x0b, 0xae, 0x0b, 0xae, 0x0b, 343 0xd7, 0x0b, 0xd7, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x28, 0x0c, 0x28, 344 0x0c, 0x51, 0x0c, 0x51, 0x0c, 0x7a, 0x0c, 0x7a, 0x0c, 0xa3, 0x0c, 345 0xa3, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xf5, 0x0c, 0xf5, 0x0d, 0x1e, 346 0x0d, 0x1e, 0x0d, 0x47, 0x0d, 0x47, 0x0d, 0x70, 0x0d, 0x70, 0x0d, 347 0x99, 0x0d, 0x99, 0x0d, 0xc2, 0x0d, 0xc2, 0x0d, 0xeb, 0x0d, 0xeb, 348 0x0e, 0x14, 0x0e, 0x14, 0x0e, 0x3d, 0x0e, 0x3d, 0x0e, 0x66, 0x0e, 349 0x66, 0x0e, 0x8f, 0x0e, 0x8f, 0x0e, 0xb8, 0x0e, 0xb8, 0x0e, 0xe1, 350 0x0e, 0xe1, 0x0f, 0x0a, 0x0f, 0x0a, 0x0f, 0x33, 0x0f, 0x33, 0x0f, 351 0x5c, 0x0f, 0x5c, 0x0f, 0x85, 0x0f, 0x85, 0x0f, 0xae, 0x0f, 0xae, 352 0x0f, 0xd7, 0x0f, 0xd7, 0x0f, 0xff, 0x0f, 0xff 353 }; 354 355 static int 356 wavefront_fx_idle (snd_wavefront_t *dev) 357 358 { 359 int i; 360 unsigned int x = 0x80; 361 362 for (i = 0; i < 1000; i++) { 363 x = inb (dev->fx_status); 364 if ((x & 0x80) == 0) { 365 break; 366 } 367 } 368 369 if (x & 0x80) { 370 snd_printk ("FX device never idle.\n"); 371 return 0; 372 } 373 374 return (1); 375 } 376 377 static void 378 wavefront_fx_mute (snd_wavefront_t *dev, int onoff) 379 380 { 381 if (!wavefront_fx_idle(dev)) { 382 return; 383 } 384 385 outb (onoff ? 0x02 : 0x00, dev->fx_op); 386 } 387 388 static int 389 wavefront_fx_memset (snd_wavefront_t *dev, 390 int page, 391 int addr, 392 int cnt, 393 unsigned short *data) 394 { 395 if (page < 0 || page > 7) { 396 snd_printk ("FX memset: " 397 "page must be >= 0 and <= 7\n"); 398 return -(EINVAL); 399 } 400 401 if (addr < 0 || addr > 0x7f) { 402 snd_printk ("FX memset: " 403 "addr must be >= 0 and <= 7f\n"); 404 return -(EINVAL); 405 } 406 407 if (cnt == 1) { 408 409 outb (FX_LSB_TRANSFER, dev->fx_lcr); 410 outb (page, dev->fx_dsp_page); 411 outb (addr, dev->fx_dsp_addr); 412 outb ((data[0] >> 8), dev->fx_dsp_msb); 413 outb ((data[0] & 0xff), dev->fx_dsp_lsb); 414 415 snd_printk ("FX: addr %d:%x set to 0x%x\n", 416 page, addr, data[0]); 417 418 } else { 419 int i; 420 421 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 422 outb (page, dev->fx_dsp_page); 423 outb (addr, dev->fx_dsp_addr); 424 425 for (i = 0; i < cnt; i++) { 426 outb ((data[i] >> 8), dev->fx_dsp_msb); 427 outb ((data[i] & 0xff), dev->fx_dsp_lsb); 428 if (!wavefront_fx_idle (dev)) { 429 break; 430 } 431 } 432 433 if (i != cnt) { 434 snd_printk ("FX memset " 435 "(0x%x, 0x%x, 0x%lx, %d) incomplete\n", 436 page, addr, (unsigned long) data, cnt); 437 return -(EIO); 438 } 439 } 440 441 return 0; 442 } 443 444 int 445 snd_wavefront_fx_detect (snd_wavefront_t *dev) 446 447 { 448 /* This is a crude check, but its the best one I have for now. 449 Certainly on the Maui and the Tropez, wavefront_fx_idle() will 450 report "never idle", which suggests that this test should 451 work OK. 452 */ 453 454 if (inb (dev->fx_status) & 0x80) { 455 snd_printk ("Hmm, probably a Maui or Tropez.\n"); 456 return -1; 457 } 458 459 return 0; 460 } 461 462 int 463 snd_wavefront_fx_open (struct snd_hwdep *hw, struct file *file) 464 465 { 466 if (!try_module_get(hw->card->module)) 467 return -EFAULT; 468 file->private_data = hw; 469 return 0; 470 } 471 472 int 473 snd_wavefront_fx_release (struct snd_hwdep *hw, struct file *file) 474 475 { 476 module_put(hw->card->module); 477 return 0; 478 } 479 480 int 481 snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file, 482 unsigned int cmd, unsigned long arg) 483 484 { 485 struct snd_card *card; 486 snd_wavefront_card_t *acard; 487 snd_wavefront_t *dev; 488 wavefront_fx_info r; 489 unsigned short *page_data = NULL; 490 unsigned short *pd; 491 int err = 0; 492 493 snd_assert(sdev->card != NULL, return -ENODEV); 494 495 card = sdev->card; 496 497 snd_assert(card->private_data != NULL, return -ENODEV); 498 499 acard = card->private_data; 500 dev = &acard->wavefront; 501 502 if (copy_from_user (&r, (void __user *)arg, sizeof (wavefront_fx_info))) 503 return -EFAULT; 504 505 switch (r.request) { 506 case WFFX_MUTE: 507 wavefront_fx_mute (dev, r.data[0]); 508 return -EIO; 509 510 case WFFX_MEMSET: 511 if (r.data[2] <= 0) { 512 snd_printk ("cannot write " 513 "<= 0 bytes to FX\n"); 514 return -EIO; 515 } else if (r.data[2] == 1) { 516 pd = (unsigned short *) &r.data[3]; 517 } else { 518 if (r.data[2] > 256) { 519 snd_printk ("cannot write " 520 "> 512 bytes to FX\n"); 521 return -EIO; 522 } 523 page_data = kmalloc(r.data[2] * sizeof(short), GFP_KERNEL); 524 if (!page_data) 525 return -ENOMEM; 526 if (copy_from_user (page_data, 527 (unsigned char __user *) r.data[3], 528 r.data[2] * sizeof(short))) { 529 kfree(page_data); 530 return -EFAULT; 531 } 532 pd = page_data; 533 } 534 535 err = wavefront_fx_memset (dev, 536 r.data[0], /* page */ 537 r.data[1], /* addr */ 538 r.data[2], /* cnt */ 539 pd); 540 kfree(page_data); 541 break; 542 543 default: 544 snd_printk ("FX: ioctl %d not yet supported\n", 545 r.request); 546 return -ENOTTY; 547 } 548 return err; 549 } 550 551 /* YSS225 initialization. 552 553 This code was developed using DOSEMU. The Turtle Beach SETUPSND 554 utility was run with I/O tracing in DOSEMU enabled, and a reconstruction 555 of the port I/O done, using the Yamaha faxback document as a guide 556 to add more logic to the code. Its really pretty weird. 557 558 There was an alternative approach of just dumping the whole I/O 559 sequence as a series of port/value pairs and a simple loop 560 that output it. However, I hope that eventually I'll get more 561 control over what this code does, and so I tried to stick with 562 a somewhat "algorithmic" approach. 563 */ 564 565 566 int __init 567 snd_wavefront_fx_start (snd_wavefront_t *dev) 568 569 { 570 unsigned int i, j; 571 572 /* Set all bits for all channels on the MOD unit to zero */ 573 /* XXX But why do this twice ? */ 574 575 for (j = 0; j < 2; j++) { 576 for (i = 0x10; i <= 0xff; i++) { 577 578 if (!wavefront_fx_idle (dev)) { 579 return (-1); 580 } 581 582 outb (i, dev->fx_mod_addr); 583 outb (0x0, dev->fx_mod_data); 584 } 585 } 586 587 if (!wavefront_fx_idle (dev)) return (-1); 588 outb (0x02, dev->fx_op); /* mute on */ 589 590 if (!wavefront_fx_idle (dev)) return (-1); 591 outb (0x07, dev->fx_dsp_page); 592 outb (0x44, dev->fx_dsp_addr); 593 outb (0x00, dev->fx_dsp_msb); 594 outb (0x00, dev->fx_dsp_lsb); 595 if (!wavefront_fx_idle (dev)) return (-1); 596 outb (0x07, dev->fx_dsp_page); 597 outb (0x42, dev->fx_dsp_addr); 598 outb (0x00, dev->fx_dsp_msb); 599 outb (0x00, dev->fx_dsp_lsb); 600 if (!wavefront_fx_idle (dev)) return (-1); 601 outb (0x07, dev->fx_dsp_page); 602 outb (0x43, dev->fx_dsp_addr); 603 outb (0x00, dev->fx_dsp_msb); 604 outb (0x00, dev->fx_dsp_lsb); 605 if (!wavefront_fx_idle (dev)) return (-1); 606 outb (0x07, dev->fx_dsp_page); 607 outb (0x7c, dev->fx_dsp_addr); 608 outb (0x00, dev->fx_dsp_msb); 609 outb (0x00, dev->fx_dsp_lsb); 610 if (!wavefront_fx_idle (dev)) return (-1); 611 outb (0x07, dev->fx_dsp_page); 612 outb (0x7e, dev->fx_dsp_addr); 613 outb (0x00, dev->fx_dsp_msb); 614 outb (0x00, dev->fx_dsp_lsb); 615 if (!wavefront_fx_idle (dev)) return (-1); 616 outb (0x07, dev->fx_dsp_page); 617 outb (0x46, dev->fx_dsp_addr); 618 outb (0x00, dev->fx_dsp_msb); 619 outb (0x00, dev->fx_dsp_lsb); 620 if (!wavefront_fx_idle (dev)) return (-1); 621 outb (0x07, dev->fx_dsp_page); 622 outb (0x49, dev->fx_dsp_addr); 623 outb (0x00, dev->fx_dsp_msb); 624 outb (0x00, dev->fx_dsp_lsb); 625 if (!wavefront_fx_idle (dev)) return (-1); 626 outb (0x07, dev->fx_dsp_page); 627 outb (0x47, dev->fx_dsp_addr); 628 outb (0x00, dev->fx_dsp_msb); 629 outb (0x00, dev->fx_dsp_lsb); 630 if (!wavefront_fx_idle (dev)) return (-1); 631 outb (0x07, dev->fx_dsp_page); 632 outb (0x4a, dev->fx_dsp_addr); 633 outb (0x00, dev->fx_dsp_msb); 634 outb (0x00, dev->fx_dsp_lsb); 635 636 /* either because of stupidity by TB's programmers, or because it 637 actually does something, rezero the MOD page. 638 */ 639 for (i = 0x10; i <= 0xff; i++) { 640 641 if (!wavefront_fx_idle (dev)) { 642 return (-1); 643 } 644 645 outb (i, dev->fx_mod_addr); 646 outb (0x0, dev->fx_mod_data); 647 } 648 /* load page zero */ 649 650 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 651 outb (0x00, dev->fx_dsp_page); 652 outb (0x00, dev->fx_dsp_addr); 653 654 for (i = 0; i < sizeof (page_zero); i += 2) { 655 outb (page_zero[i], dev->fx_dsp_msb); 656 outb (page_zero[i+1], dev->fx_dsp_lsb); 657 if (!wavefront_fx_idle (dev)) return (-1); 658 } 659 660 /* Now load page one */ 661 662 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 663 outb (0x01, dev->fx_dsp_page); 664 outb (0x00, dev->fx_dsp_addr); 665 666 for (i = 0; i < sizeof (page_one); i += 2) { 667 outb (page_one[i], dev->fx_dsp_msb); 668 outb (page_one[i+1], dev->fx_dsp_lsb); 669 if (!wavefront_fx_idle (dev)) return (-1); 670 } 671 672 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 673 outb (0x02, dev->fx_dsp_page); 674 outb (0x00, dev->fx_dsp_addr); 675 676 for (i = 0; i < sizeof (page_two); i++) { 677 outb (page_two[i], dev->fx_dsp_lsb); 678 if (!wavefront_fx_idle (dev)) return (-1); 679 } 680 681 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 682 outb (0x03, dev->fx_dsp_page); 683 outb (0x00, dev->fx_dsp_addr); 684 685 for (i = 0; i < sizeof (page_three); i++) { 686 outb (page_three[i], dev->fx_dsp_lsb); 687 if (!wavefront_fx_idle (dev)) return (-1); 688 } 689 690 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 691 outb (0x04, dev->fx_dsp_page); 692 outb (0x00, dev->fx_dsp_addr); 693 694 for (i = 0; i < sizeof (page_four); i++) { 695 outb (page_four[i], dev->fx_dsp_lsb); 696 if (!wavefront_fx_idle (dev)) return (-1); 697 } 698 699 /* Load memory area (page six) */ 700 701 outb (FX_LSB_TRANSFER, dev->fx_lcr); 702 outb (0x06, dev->fx_dsp_page); 703 704 for (i = 0; i < sizeof (page_six); i += 3) { 705 outb (page_six[i], dev->fx_dsp_addr); 706 outb (page_six[i+1], dev->fx_dsp_msb); 707 outb (page_six[i+2], dev->fx_dsp_lsb); 708 if (!wavefront_fx_idle (dev)) return (-1); 709 } 710 711 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 712 outb (0x07, dev->fx_dsp_page); 713 outb (0x00, dev->fx_dsp_addr); 714 715 for (i = 0; i < sizeof (page_seven); i += 2) { 716 outb (page_seven[i], dev->fx_dsp_msb); 717 outb (page_seven[i+1], dev->fx_dsp_lsb); 718 if (!wavefront_fx_idle (dev)) return (-1); 719 } 720 721 /* Now setup the MOD area. We do this algorithmically in order to 722 save a little data space. It could be done in the same fashion 723 as the "pages". 724 */ 725 726 for (i = 0x00; i <= 0x0f; i++) { 727 outb (0x01, dev->fx_mod_addr); 728 outb (i, dev->fx_mod_data); 729 if (!wavefront_fx_idle (dev)) return (-1); 730 outb (0x02, dev->fx_mod_addr); 731 outb (0x00, dev->fx_mod_data); 732 if (!wavefront_fx_idle (dev)) return (-1); 733 } 734 735 for (i = 0xb0; i <= 0xbf; i++) { 736 outb (i, dev->fx_mod_addr); 737 outb (0x20, dev->fx_mod_data); 738 if (!wavefront_fx_idle (dev)) return (-1); 739 } 740 741 for (i = 0xf0; i <= 0xff; i++) { 742 outb (i, dev->fx_mod_addr); 743 outb (0x20, dev->fx_mod_data); 744 if (!wavefront_fx_idle (dev)) return (-1); 745 } 746 747 for (i = 0x10; i <= 0x1d; i++) { 748 outb (i, dev->fx_mod_addr); 749 outb (0xff, dev->fx_mod_data); 750 if (!wavefront_fx_idle (dev)) return (-1); 751 } 752 753 outb (0x1e, dev->fx_mod_addr); 754 outb (0x40, dev->fx_mod_data); 755 if (!wavefront_fx_idle (dev)) return (-1); 756 757 for (i = 0x1f; i <= 0x2d; i++) { 758 outb (i, dev->fx_mod_addr); 759 outb (0xff, dev->fx_mod_data); 760 if (!wavefront_fx_idle (dev)) return (-1); 761 } 762 763 outb (0x2e, dev->fx_mod_addr); 764 outb (0x00, dev->fx_mod_data); 765 if (!wavefront_fx_idle (dev)) return (-1); 766 767 for (i = 0x2f; i <= 0x3e; i++) { 768 outb (i, dev->fx_mod_addr); 769 outb (0x00, dev->fx_mod_data); 770 if (!wavefront_fx_idle (dev)) return (-1); 771 } 772 773 outb (0x3f, dev->fx_mod_addr); 774 outb (0x20, dev->fx_mod_data); 775 if (!wavefront_fx_idle (dev)) return (-1); 776 777 for (i = 0x40; i <= 0x4d; i++) { 778 outb (i, dev->fx_mod_addr); 779 outb (0x00, dev->fx_mod_data); 780 if (!wavefront_fx_idle (dev)) return (-1); 781 } 782 783 outb (0x4e, dev->fx_mod_addr); 784 outb (0x0e, dev->fx_mod_data); 785 if (!wavefront_fx_idle (dev)) return (-1); 786 outb (0x4f, dev->fx_mod_addr); 787 outb (0x0e, dev->fx_mod_data); 788 if (!wavefront_fx_idle (dev)) return (-1); 789 790 791 for (i = 0x50; i <= 0x6b; i++) { 792 outb (i, dev->fx_mod_addr); 793 outb (0x00, dev->fx_mod_data); 794 if (!wavefront_fx_idle (dev)) return (-1); 795 } 796 797 outb (0x6c, dev->fx_mod_addr); 798 outb (0x40, dev->fx_mod_data); 799 if (!wavefront_fx_idle (dev)) return (-1); 800 801 outb (0x6d, dev->fx_mod_addr); 802 outb (0x00, dev->fx_mod_data); 803 if (!wavefront_fx_idle (dev)) return (-1); 804 805 outb (0x6e, dev->fx_mod_addr); 806 outb (0x40, dev->fx_mod_data); 807 if (!wavefront_fx_idle (dev)) return (-1); 808 809 outb (0x6f, dev->fx_mod_addr); 810 outb (0x40, dev->fx_mod_data); 811 if (!wavefront_fx_idle (dev)) return (-1); 812 813 for (i = 0x70; i <= 0x7f; i++) { 814 outb (i, dev->fx_mod_addr); 815 outb (0xc0, dev->fx_mod_data); 816 if (!wavefront_fx_idle (dev)) return (-1); 817 } 818 819 for (i = 0x80; i <= 0xaf; i++) { 820 outb (i, dev->fx_mod_addr); 821 outb (0x00, dev->fx_mod_data); 822 if (!wavefront_fx_idle (dev)) return (-1); 823 } 824 825 for (i = 0xc0; i <= 0xdd; i++) { 826 outb (i, dev->fx_mod_addr); 827 outb (0x00, dev->fx_mod_data); 828 if (!wavefront_fx_idle (dev)) return (-1); 829 } 830 831 outb (0xde, dev->fx_mod_addr); 832 outb (0x10, dev->fx_mod_data); 833 if (!wavefront_fx_idle (dev)) return (-1); 834 outb (0xdf, dev->fx_mod_addr); 835 outb (0x10, dev->fx_mod_data); 836 if (!wavefront_fx_idle (dev)) return (-1); 837 838 for (i = 0xe0; i <= 0xef; i++) { 839 outb (i, dev->fx_mod_addr); 840 outb (0x00, dev->fx_mod_data); 841 if (!wavefront_fx_idle (dev)) return (-1); 842 } 843 844 for (i = 0x00; i <= 0x0f; i++) { 845 outb (0x01, dev->fx_mod_addr); 846 outb (i, dev->fx_mod_data); 847 outb (0x02, dev->fx_mod_addr); 848 outb (0x01, dev->fx_mod_data); 849 if (!wavefront_fx_idle (dev)) return (-1); 850 } 851 852 outb (0x02, dev->fx_op); /* mute on */ 853 854 /* Now set the coefficients and so forth for the programs above */ 855 856 for (i = 0; i < sizeof (coefficients); i += 4) { 857 outb (coefficients[i], dev->fx_dsp_page); 858 outb (coefficients[i+1], dev->fx_dsp_addr); 859 outb (coefficients[i+2], dev->fx_dsp_msb); 860 outb (coefficients[i+3], dev->fx_dsp_lsb); 861 if (!wavefront_fx_idle (dev)) return (-1); 862 } 863 864 /* Some settings (?) that are too small to bundle into loops */ 865 866 if (!wavefront_fx_idle (dev)) return (-1); 867 outb (0x1e, dev->fx_mod_addr); 868 outb (0x14, dev->fx_mod_data); 869 if (!wavefront_fx_idle (dev)) return (-1); 870 outb (0xde, dev->fx_mod_addr); 871 outb (0x20, dev->fx_mod_data); 872 if (!wavefront_fx_idle (dev)) return (-1); 873 outb (0xdf, dev->fx_mod_addr); 874 outb (0x20, dev->fx_mod_data); 875 876 /* some more coefficients */ 877 878 if (!wavefront_fx_idle (dev)) return (-1); 879 outb (0x06, dev->fx_dsp_page); 880 outb (0x78, dev->fx_dsp_addr); 881 outb (0x00, dev->fx_dsp_msb); 882 outb (0x40, dev->fx_dsp_lsb); 883 if (!wavefront_fx_idle (dev)) return (-1); 884 outb (0x07, dev->fx_dsp_page); 885 outb (0x03, dev->fx_dsp_addr); 886 outb (0x0f, dev->fx_dsp_msb); 887 outb (0xff, dev->fx_dsp_lsb); 888 if (!wavefront_fx_idle (dev)) return (-1); 889 outb (0x07, dev->fx_dsp_page); 890 outb (0x0b, dev->fx_dsp_addr); 891 outb (0x0f, dev->fx_dsp_msb); 892 outb (0xff, dev->fx_dsp_lsb); 893 if (!wavefront_fx_idle (dev)) return (-1); 894 outb (0x07, dev->fx_dsp_page); 895 outb (0x02, dev->fx_dsp_addr); 896 outb (0x00, dev->fx_dsp_msb); 897 outb (0x00, dev->fx_dsp_lsb); 898 if (!wavefront_fx_idle (dev)) return (-1); 899 outb (0x07, dev->fx_dsp_page); 900 outb (0x0a, dev->fx_dsp_addr); 901 outb (0x00, dev->fx_dsp_msb); 902 outb (0x00, dev->fx_dsp_lsb); 903 if (!wavefront_fx_idle (dev)) return (-1); 904 outb (0x07, dev->fx_dsp_page); 905 outb (0x46, dev->fx_dsp_addr); 906 outb (0x00, dev->fx_dsp_msb); 907 outb (0x00, dev->fx_dsp_lsb); 908 if (!wavefront_fx_idle (dev)) return (-1); 909 outb (0x07, dev->fx_dsp_page); 910 outb (0x49, dev->fx_dsp_addr); 911 outb (0x00, dev->fx_dsp_msb); 912 outb (0x00, dev->fx_dsp_lsb); 913 914 /* Now, for some strange reason, lets reload every page 915 and all the coefficients over again. I have *NO* idea 916 why this is done. I do know that no sound is produced 917 is this phase is omitted. 918 */ 919 920 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 921 outb (0x00, dev->fx_dsp_page); 922 outb (0x10, dev->fx_dsp_addr); 923 924 for (i = 0; i < sizeof (page_zero_v2); i += 2) { 925 outb (page_zero_v2[i], dev->fx_dsp_msb); 926 outb (page_zero_v2[i+1], dev->fx_dsp_lsb); 927 if (!wavefront_fx_idle (dev)) return (-1); 928 } 929 930 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 931 outb (0x01, dev->fx_dsp_page); 932 outb (0x10, dev->fx_dsp_addr); 933 934 for (i = 0; i < sizeof (page_one_v2); i += 2) { 935 outb (page_one_v2[i], dev->fx_dsp_msb); 936 outb (page_one_v2[i+1], dev->fx_dsp_lsb); 937 if (!wavefront_fx_idle (dev)) return (-1); 938 } 939 940 if (!wavefront_fx_idle (dev)) return (-1); 941 if (!wavefront_fx_idle (dev)) return (-1); 942 943 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 944 outb (0x02, dev->fx_dsp_page); 945 outb (0x10, dev->fx_dsp_addr); 946 947 for (i = 0; i < sizeof (page_two_v2); i++) { 948 outb (page_two_v2[i], dev->fx_dsp_lsb); 949 if (!wavefront_fx_idle (dev)) return (-1); 950 } 951 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 952 outb (0x03, dev->fx_dsp_page); 953 outb (0x10, dev->fx_dsp_addr); 954 955 for (i = 0; i < sizeof (page_three_v2); i++) { 956 outb (page_three_v2[i], dev->fx_dsp_lsb); 957 if (!wavefront_fx_idle (dev)) return (-1); 958 } 959 960 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 961 outb (0x04, dev->fx_dsp_page); 962 outb (0x10, dev->fx_dsp_addr); 963 964 for (i = 0; i < sizeof (page_four_v2); i++) { 965 outb (page_four_v2[i], dev->fx_dsp_lsb); 966 if (!wavefront_fx_idle (dev)) return (-1); 967 } 968 969 outb (FX_LSB_TRANSFER, dev->fx_lcr); 970 outb (0x06, dev->fx_dsp_page); 971 972 /* Page six v.2 is algorithmic */ 973 974 for (i = 0x10; i <= 0x3e; i += 2) { 975 outb (i, dev->fx_dsp_addr); 976 outb (0x00, dev->fx_dsp_msb); 977 outb (0x00, dev->fx_dsp_lsb); 978 if (!wavefront_fx_idle (dev)) return (-1); 979 } 980 981 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); 982 outb (0x07, dev->fx_dsp_page); 983 outb (0x10, dev->fx_dsp_addr); 984 985 for (i = 0; i < sizeof (page_seven_v2); i += 2) { 986 outb (page_seven_v2[i], dev->fx_dsp_msb); 987 outb (page_seven_v2[i+1], dev->fx_dsp_lsb); 988 if (!wavefront_fx_idle (dev)) return (-1); 989 } 990 991 for (i = 0x00; i < sizeof(mod_v2); i += 2) { 992 outb (mod_v2[i], dev->fx_mod_addr); 993 outb (mod_v2[i+1], dev->fx_mod_data); 994 if (!wavefront_fx_idle (dev)) return (-1); 995 } 996 997 for (i = 0; i < sizeof (coefficients2); i += 4) { 998 outb (coefficients2[i], dev->fx_dsp_page); 999 outb (coefficients2[i+1], dev->fx_dsp_addr); 1000 outb (coefficients2[i+2], dev->fx_dsp_msb); 1001 outb (coefficients2[i+3], dev->fx_dsp_lsb); 1002 if (!wavefront_fx_idle (dev)) return (-1); 1003 } 1004 1005 for (i = 0; i < sizeof (coefficients3); i += 2) { 1006 int x; 1007 1008 outb (0x07, dev->fx_dsp_page); 1009 x = (i % 4) ? 0x4e : 0x4c; 1010 outb (x, dev->fx_dsp_addr); 1011 outb (coefficients3[i], dev->fx_dsp_msb); 1012 outb (coefficients3[i+1], dev->fx_dsp_lsb); 1013 } 1014 1015 outb (0x00, dev->fx_op); /* mute off */ 1016 if (!wavefront_fx_idle (dev)) return (-1); 1017 1018 return (0); 1019 } 1020