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