2 * Copyright (c) 1998-2002 by Paul Davis <pbd@op.net>
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.
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.
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
19 #include <sound/driver.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>
28 /* Control bits for the Load Control Register
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 */
35 /* weird stuff, derived from port I/O tracing with dosemu */
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,
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,
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
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
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
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
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,
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
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
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
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
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
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
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
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,
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
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
356 wavefront_fx_idle (snd_wavefront_t *dev)
360 unsigned int x = 0x80;
362 for (i = 0; i < 1000; i++) {
363 x = inb (dev->fx_status);
364 if ((x & 0x80) == 0) {
370 snd_printk ("FX device never idle.\n");
378 wavefront_fx_mute (snd_wavefront_t *dev, int onoff)
381 if (!wavefront_fx_idle(dev)) {
385 outb (onoff ? 0x02 : 0x00, dev->fx_op);
389 wavefront_fx_memset (snd_wavefront_t *dev,
393 unsigned short *data)
395 if (page < 0 || page > 7) {
396 snd_printk ("FX memset: "
397 "page must be >= 0 and <= 7\n");
401 if (addr < 0 || addr > 0x7f) {
402 snd_printk ("FX memset: "
403 "addr must be >= 0 and <= 7f\n");
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);
415 snd_printk ("FX: addr %d:%x set to 0x%x\n",
416 page, addr, data[0]);
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);
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)) {
434 snd_printk ("FX memset "
435 "(0x%x, 0x%x, 0x%lx, %d) incomplete\n",
436 page, addr, (unsigned long) data, cnt);
445 snd_wavefront_fx_detect (snd_wavefront_t *dev)
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
454 if (inb (dev->fx_status) & 0x80) {
455 snd_printk ("Hmm, probably a Maui or Tropez.\n");
463 snd_wavefront_fx_open (struct snd_hwdep *hw, struct file *file)
466 if (!try_module_get(hw->card->module))
468 file->private_data = hw;
473 snd_wavefront_fx_release (struct snd_hwdep *hw, struct file *file)
476 module_put(hw->card->module);
481 snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file,
482 unsigned int cmd, unsigned long arg)
485 struct snd_card *card;
486 snd_wavefront_card_t *acard;
487 snd_wavefront_t *dev;
489 unsigned short *page_data = NULL;
493 snd_assert(sdev->card != NULL, return -ENODEV);
497 snd_assert(card->private_data != NULL, return -ENODEV);
499 acard = card->private_data;
500 dev = &acard->wavefront;
502 if (copy_from_user (&r, (void __user *)arg, sizeof (wavefront_fx_info)))
507 wavefront_fx_mute (dev, r.data[0]);
511 if (r.data[2] <= 0) {
512 snd_printk ("cannot write "
513 "<= 0 bytes to FX\n");
515 } else if (r.data[2] == 1) {
516 pd = (unsigned short *) &r.data[3];
518 if (r.data[2] > 256) {
519 snd_printk ("cannot write "
520 "> 512 bytes to FX\n");
523 page_data = kmalloc(r.data[2] * sizeof(short), GFP_KERNEL);
526 if (copy_from_user (page_data,
527 (unsigned char __user *) r.data[3],
528 r.data[2] * sizeof(short))) {
535 err = wavefront_fx_memset (dev,
536 r.data[0], /* page */
537 r.data[1], /* addr */
544 snd_printk ("FX: ioctl %d not yet supported\n",
551 /* YSS225 initialization.
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.
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.
567 snd_wavefront_fx_start (snd_wavefront_t *dev)
572 /* Set all bits for all channels on the MOD unit to zero */
573 /* XXX But why do this twice ? */
575 for (j = 0; j < 2; j++) {
576 for (i = 0x10; i <= 0xff; i++) {
578 if (!wavefront_fx_idle (dev)) {
582 outb (i, dev->fx_mod_addr);
583 outb (0x0, dev->fx_mod_data);
587 if (!wavefront_fx_idle (dev)) return (-1);
588 outb (0x02, dev->fx_op); /* mute on */
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);
636 /* either because of stupidity by TB's programmers, or because it
637 actually does something, rezero the MOD page.
639 for (i = 0x10; i <= 0xff; i++) {
641 if (!wavefront_fx_idle (dev)) {
645 outb (i, dev->fx_mod_addr);
646 outb (0x0, dev->fx_mod_data);
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);
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);
660 /* Now load page one */
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);
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);
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);
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);
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);
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);
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);
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);
699 /* Load memory area (page six) */
701 outb (FX_LSB_TRANSFER, dev->fx_lcr);
702 outb (0x06, dev->fx_dsp_page);
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);
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);
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);
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
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);
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);
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);
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);
753 outb (0x1e, dev->fx_mod_addr);
754 outb (0x40, dev->fx_mod_data);
755 if (!wavefront_fx_idle (dev)) return (-1);
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);
763 outb (0x2e, dev->fx_mod_addr);
764 outb (0x00, dev->fx_mod_data);
765 if (!wavefront_fx_idle (dev)) return (-1);
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);
773 outb (0x3f, dev->fx_mod_addr);
774 outb (0x20, dev->fx_mod_data);
775 if (!wavefront_fx_idle (dev)) return (-1);
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);
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);
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);
797 outb (0x6c, dev->fx_mod_addr);
798 outb (0x40, dev->fx_mod_data);
799 if (!wavefront_fx_idle (dev)) return (-1);
801 outb (0x6d, dev->fx_mod_addr);
802 outb (0x00, dev->fx_mod_data);
803 if (!wavefront_fx_idle (dev)) return (-1);
805 outb (0x6e, dev->fx_mod_addr);
806 outb (0x40, dev->fx_mod_data);
807 if (!wavefront_fx_idle (dev)) return (-1);
809 outb (0x6f, dev->fx_mod_addr);
810 outb (0x40, dev->fx_mod_data);
811 if (!wavefront_fx_idle (dev)) return (-1);
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);
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);
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);
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);
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);
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);
852 outb (0x02, dev->fx_op); /* mute on */
854 /* Now set the coefficients and so forth for the programs above */
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);
864 /* Some settings (?) that are too small to bundle into loops */
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);
876 /* some more coefficients */
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);
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.
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);
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);
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);
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);
940 if (!wavefront_fx_idle (dev)) return (-1);
941 if (!wavefront_fx_idle (dev)) return (-1);
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);
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);
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);
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);
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);
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);
969 outb (FX_LSB_TRANSFER, dev->fx_lcr);
970 outb (0x06, dev->fx_dsp_page);
972 /* Page six v.2 is algorithmic */
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);
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);
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);
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);
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);
1005 for (i = 0; i < sizeof (coefficients3); i += 2) {
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);
1015 outb (0x00, dev->fx_op); /* mute off */
1016 if (!wavefront_fx_idle (dev)) return (-1);