at v2.6.13 1019 lines 37 kB view raw
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 37static unsigned char page_zero[] __initdata = { 380x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, 390x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00, 400x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00, 410x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x19, 500x01, 0x1a, 0x01, 0x20, 0x01, 0x40, 0x01, 0x17, 0x00, 0x00, 0x01, 510x80, 0x01, 0x20, 0x00, 0x10, 0x01, 0xa0, 0x03, 0xd1, 0x00, 0x00, 520x01, 0xf2, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf4, 0x02, 530xe0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 540x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x00, 0x00, 550x40, 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x60, 0x00, 0x00, 560x00, 0x92, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb3, 0x02, 570x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x40, 580x00, 0x80, 0x00, 0xf5, 0x00, 0x20, 0x00, 0x70, 0x00, 0xa0, 0x02, 590x11, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 600x02, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x17, 0x00, 0x1b, 0x00, 610x1d, 0x02, 0xdf 62}; 63 64static unsigned char page_one[] __initdata = { 650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00, 660x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00, 670x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 680xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x60, 770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x80, 0x00, 780x00, 0x02, 0xfb, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x1b, 0x02, 0xd7, 790x00, 0x00, 0x02, 0xf7, 0x03, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 800x1c, 0x03, 0x3c, 0x00, 0x00, 0x03, 0x3f, 0x00, 0x00, 0x03, 0xc0, 810x00, 0x00, 0x03, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5d, 0x00, 820x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0x7d, 0x00, 0x00, 0x03, 0xc0, 830x00, 0x00, 0x03, 0x9e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 840xbe, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 850x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 860xdb, 0x00, 0x00, 0x02, 0xdb, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 870x02, 0xfb, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xfb, 0x02, 880x60, 0x00, 0x1b 89}; 90 91static unsigned char page_two[] __initdata = { 920xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4, 930x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x07, 980x05, 0x05, 0x05, 0x04, 0x07, 0x05, 0x04, 0x07, 0x05, 0x44, 0x46, 990x44, 0x46, 0x46, 0x07, 0x05, 0x44, 0x46, 0x05, 0x46, 0x05, 0x46, 1000x05, 0x46, 0x05, 0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, 1010x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, 0x44, 0x05, 0x05, 1020x05, 0x44, 0x05, 0x05, 0x05, 0x46, 0x05, 0x46, 0x05, 0x46, 0x05, 1030x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44 104}; 105 106static unsigned char page_three[] __initdata = { 1070x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06, 1080x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 1130xc0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 1140x60, 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x42, 0x00, 0x40, 1150x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 1160x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 1170x00, 0x42, 0x00, 0x40, 0x00, 0x42, 0x00, 0x02, 0x00, 0x02, 0x00, 1180x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40 119}; 120 121static unsigned char page_four[] __initdata = { 1220x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02, 1230x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 1280x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 1290x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00, 1300x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 1310x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 1320x20, 0x00, 0x22, 0x02, 0x22, 0x02, 0x20, 0x00, 0x60, 0x00, 0x22, 1330x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01 134}; 135 136static unsigned char page_six[] __initdata = { 1370x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, 1380x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e, 1390x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00, 1400x16, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x1c, 0x00, 1410x00, 0x1e, 0x00, 0x00, 0x20, 0x00, 0x00, 0x22, 0x00, 0x00, 0x24, 1420x00, 0x00, 0x26, 0x00, 0x00, 0x28, 0x00, 0x00, 0x2a, 0x00, 0x00, 1430x2c, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x32, 0x00, 1440x00, 0x34, 0x00, 0x00, 0x36, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3a, 1450x00, 0x00, 0x3c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0x00, 1460x42, 0x03, 0x00, 0x44, 0x01, 0x00, 0x46, 0x0a, 0x21, 0x48, 0x0d, 1470x23, 0x4a, 0x23, 0x1b, 0x4c, 0x37, 0x8f, 0x4e, 0x45, 0x77, 0x50, 1480x52, 0xe2, 0x52, 0x1c, 0x92, 0x54, 0x1c, 0x52, 0x56, 0x07, 0x00, 1490x58, 0x2f, 0xc6, 0x5a, 0x0b, 0x00, 0x5c, 0x30, 0x06, 0x5e, 0x17, 1500x00, 0x60, 0x3d, 0xda, 0x62, 0x29, 0x00, 0x64, 0x3e, 0x41, 0x66, 1510x39, 0x00, 0x68, 0x4c, 0x48, 0x6a, 0x49, 0x00, 0x6c, 0x4c, 0x6c, 1520x6e, 0x11, 0xd2, 0x70, 0x16, 0x0c, 0x72, 0x00, 0x00, 0x74, 0x00, 1530x80, 0x76, 0x0f, 0x00, 0x78, 0x00, 0x80, 0x7a, 0x13, 0x00, 0x7c, 1540x80, 0x00, 0x7e, 0x80, 0x80 155}; 156 157static unsigned char page_seven[] __initdata = { 1580x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 1590x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 1600x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 1610xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff, 1720x0f, 0xff, 0x0f, 0xff, 0x02, 0xe9, 0x06, 0x8c, 0x06, 0x8c, 0x0f, 1730xff, 0x1a, 0x75, 0x0d, 0x8b, 0x04, 0xe9, 0x0b, 0x16, 0x1a, 0x38, 1740x0d, 0xc8, 0x04, 0x6f, 0x0b, 0x91, 0x0f, 0xff, 0x06, 0x40, 0x06, 1750x40, 0x02, 0x8f, 0x0f, 0xff, 0x06, 0x62, 0x06, 0x62, 0x02, 0x7b, 1760x0f, 0xff, 0x06, 0x97, 0x06, 0x97, 0x02, 0x52, 0x0f, 0xff, 0x06, 1770xf6, 0x06, 0xf6, 0x02, 0x19, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 1780x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x14, 1790xda, 0x0d, 0x93, 0x04, 0xda, 0x05, 0x93, 0x14, 0xda, 0x0d, 0x93, 1800x04, 0xda, 0x05, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1810x00, 0x02, 0x00 182}; 183 184static unsigned char page_zero_v2[] __initdata = { 1850x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 194}; 195 196static unsigned char page_one_v2[] __initdata = { 1970x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 1980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 206}; 207 208static unsigned char page_two_v2[] __initdata = { 2090x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2130x00, 0x00, 0x00, 0x00 214}; 215static unsigned char page_three_v2[] __initdata = { 2160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2200x00, 0x00, 0x00, 0x00 221}; 222static unsigned char page_four_v2[] __initdata = { 2230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2270x00, 0x00, 0x00, 0x00 228}; 229 230static unsigned char page_seven_v2[] __initdata = { 2310x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 240}; 241 242static unsigned char mod_v2[] __initdata = { 2430x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, 2440x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05, 2450x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0, 2460x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20, 0xb4, 0x20, 0xb5, 0x20, 2470xb6, 0x20, 0xb7, 0x20, 0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3, 2480x20, 0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20, 0x10, 0xff, 2490x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0xff, 0x15, 0xff, 0x16, 2500xff, 0x17, 0xff, 0x20, 0xff, 0x21, 0xff, 0x22, 0xff, 0x23, 0xff, 2510x24, 0xff, 0x25, 0xff, 0x26, 0xff, 0x27, 0xff, 0x30, 0x00, 0x31, 2520x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 2530x37, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 2540x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x50, 0x00, 0x51, 0x00, 2550x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 2560x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 2570x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x70, 0xc0, 0x71, 0xc0, 0x72, 2580xc0, 0x73, 0xc0, 0x74, 0xc0, 0x75, 0xc0, 0x76, 0xc0, 0x77, 0xc0, 2590x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 2600x00, 0x86, 0x00, 0x87, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 2610x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0xa0, 2620x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa5, 0x00, 2630xa6, 0x00, 0xa7, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3, 2640x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xd0, 0x00, 2650xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0xd6, 2660x00, 0xd7, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe3, 0x00, 2670xe4, 0x00, 0xe5, 0x00, 0xe6, 0x00, 0xe7, 0x00, 0x01, 0x00, 0x02, 2680x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03, 2690x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01, 2700x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01 271}; 272static unsigned char coefficients[] __initdata = { 2730x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03, 2740x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 2750x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01, 2760x40, 0x02, 0x40, 0x01, 0x41, 0x02, 0x60, 0x07, 0x40, 0x00, 0x00, 2770x07, 0x41, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 0x07, 0x4a, 0x00, 2780x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x4a, 0x01, 0x20, 0x07, 0x47, 2790x00, 0x00, 0x07, 0x4a, 0x00, 0x00, 0x07, 0x7c, 0x00, 0x00, 0x07, 2800x7e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x07, 0x7c, 0x00, 0x00, 2810x07, 0x7e, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x00, 0x44, 0x01, 2820x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, 2830x00, 0x00, 0x00, 0x42, 0x01, 0x1a, 0x00, 0x43, 0x01, 0x20, 0x07, 2840x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 2850x07, 0x41, 0x00, 0x00, 0x01, 0x40, 0x02, 0x40, 0x01, 0x41, 0x02, 2860x60, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x44, 2870x0f, 0xff, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, 2880x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x51, 0x06, 0x40, 2890x07, 0x50, 0x06, 0x40, 0x07, 0x4f, 0x03, 0x81, 0x07, 0x53, 0x1a, 2900x76, 0x07, 0x54, 0x0d, 0x8b, 0x07, 0x55, 0x04, 0xe9, 0x07, 0x56, 2910x0b, 0x17, 0x07, 0x57, 0x1a, 0x38, 0x07, 0x58, 0x0d, 0xc9, 0x07, 2920x59, 0x04, 0x6f, 0x07, 0x5a, 0x0b, 0x91, 0x07, 0x73, 0x14, 0xda, 2930x07, 0x74, 0x0d, 0x93, 0x07, 0x75, 0x04, 0xd9, 0x07, 0x76, 0x05, 2940x93, 0x07, 0x77, 0x14, 0xda, 0x07, 0x78, 0x0d, 0x93, 0x07, 0x79, 2950x04, 0xd9, 0x07, 0x7a, 0x05, 0x93, 0x07, 0x5e, 0x03, 0x68, 0x07, 2960x5c, 0x04, 0x31, 0x07, 0x5d, 0x04, 0x31, 0x07, 0x62, 0x03, 0x52, 2970x07, 0x60, 0x04, 0x76, 0x07, 0x61, 0x04, 0x76, 0x07, 0x66, 0x03, 2980x2e, 0x07, 0x64, 0x04, 0xda, 0x07, 0x65, 0x04, 0xda, 0x07, 0x6a, 2990x02, 0xf6, 0x07, 0x68, 0x05, 0x62, 0x07, 0x69, 0x05, 0x62, 0x06, 3000x46, 0x0a, 0x22, 0x06, 0x48, 0x0d, 0x24, 0x06, 0x6e, 0x11, 0xd3, 3010x06, 0x70, 0x15, 0xcb, 0x06, 0x52, 0x20, 0x93, 0x06, 0x54, 0x20, 3020x54, 0x06, 0x4a, 0x27, 0x1d, 0x06, 0x58, 0x2f, 0xc8, 0x06, 0x5c, 3030x30, 0x07, 0x06, 0x4c, 0x37, 0x90, 0x06, 0x60, 0x3d, 0xdb, 0x06, 3040x64, 0x3e, 0x42, 0x06, 0x4e, 0x45, 0x78, 0x06, 0x68, 0x4c, 0x48, 3050x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02, 3060xba 307}; 308static unsigned char coefficients2[] __initdata = { 3090x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f, 3100xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d, 3110x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07, 3120x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 3130x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00 314}; 315static unsigned char coefficients3[] __initdata = { 3160x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00, 3170x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc, 3180x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01, 3190x47, 0x01, 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x99, 0x01, 0x99, 3200x01, 0xc2, 0x01, 0xc2, 0x01, 0xeb, 0x01, 0xeb, 0x02, 0x14, 0x02, 3210x14, 0x02, 0x3d, 0x02, 0x3d, 0x02, 0x66, 0x02, 0x66, 0x02, 0x8f, 3220x02, 0x8f, 0x02, 0xb8, 0x02, 0xb8, 0x02, 0xe1, 0x02, 0xe1, 0x03, 3230x0a, 0x03, 0x0a, 0x03, 0x33, 0x03, 0x33, 0x03, 0x5c, 0x03, 0x5c, 3240x03, 0x85, 0x03, 0x85, 0x03, 0xae, 0x03, 0xae, 0x03, 0xd7, 0x03, 3250xd7, 0x04, 0x00, 0x04, 0x00, 0x04, 0x28, 0x04, 0x28, 0x04, 0x51, 3260x04, 0x51, 0x04, 0x7a, 0x04, 0x7a, 0x04, 0xa3, 0x04, 0xa3, 0x04, 3270xcc, 0x04, 0xcc, 0x04, 0xf5, 0x04, 0xf5, 0x05, 0x1e, 0x05, 0x1e, 3280x05, 0x47, 0x05, 0x47, 0x05, 0x70, 0x05, 0x70, 0x05, 0x99, 0x05, 3290x99, 0x05, 0xc2, 0x05, 0xc2, 0x05, 0xeb, 0x05, 0xeb, 0x06, 0x14, 3300x06, 0x14, 0x06, 0x3d, 0x06, 0x3d, 0x06, 0x66, 0x06, 0x66, 0x06, 3310x8f, 0x06, 0x8f, 0x06, 0xb8, 0x06, 0xb8, 0x06, 0xe1, 0x06, 0xe1, 3320x07, 0x0a, 0x07, 0x0a, 0x07, 0x33, 0x07, 0x33, 0x07, 0x5c, 0x07, 3330x5c, 0x07, 0x85, 0x07, 0x85, 0x07, 0xae, 0x07, 0xae, 0x07, 0xd7, 3340x07, 0xd7, 0x08, 0x00, 0x08, 0x00, 0x08, 0x28, 0x08, 0x28, 0x08, 3350x51, 0x08, 0x51, 0x08, 0x7a, 0x08, 0x7a, 0x08, 0xa3, 0x08, 0xa3, 3360x08, 0xcc, 0x08, 0xcc, 0x08, 0xf5, 0x08, 0xf5, 0x09, 0x1e, 0x09, 3370x1e, 0x09, 0x47, 0x09, 0x47, 0x09, 0x70, 0x09, 0x70, 0x09, 0x99, 3380x09, 0x99, 0x09, 0xc2, 0x09, 0xc2, 0x09, 0xeb, 0x09, 0xeb, 0x0a, 3390x14, 0x0a, 0x14, 0x0a, 0x3d, 0x0a, 0x3d, 0x0a, 0x66, 0x0a, 0x66, 3400x0a, 0x8f, 0x0a, 0x8f, 0x0a, 0xb8, 0x0a, 0xb8, 0x0a, 0xe1, 0x0a, 3410xe1, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, 0x33, 0x0b, 0x33, 0x0b, 0x5c, 3420x0b, 0x5c, 0x0b, 0x85, 0x0b, 0x85, 0x0b, 0xae, 0x0b, 0xae, 0x0b, 3430xd7, 0x0b, 0xd7, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x28, 0x0c, 0x28, 3440x0c, 0x51, 0x0c, 0x51, 0x0c, 0x7a, 0x0c, 0x7a, 0x0c, 0xa3, 0x0c, 3450xa3, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xf5, 0x0c, 0xf5, 0x0d, 0x1e, 3460x0d, 0x1e, 0x0d, 0x47, 0x0d, 0x47, 0x0d, 0x70, 0x0d, 0x70, 0x0d, 3470x99, 0x0d, 0x99, 0x0d, 0xc2, 0x0d, 0xc2, 0x0d, 0xeb, 0x0d, 0xeb, 3480x0e, 0x14, 0x0e, 0x14, 0x0e, 0x3d, 0x0e, 0x3d, 0x0e, 0x66, 0x0e, 3490x66, 0x0e, 0x8f, 0x0e, 0x8f, 0x0e, 0xb8, 0x0e, 0xb8, 0x0e, 0xe1, 3500x0e, 0xe1, 0x0f, 0x0a, 0x0f, 0x0a, 0x0f, 0x33, 0x0f, 0x33, 0x0f, 3510x5c, 0x0f, 0x5c, 0x0f, 0x85, 0x0f, 0x85, 0x0f, 0xae, 0x0f, 0xae, 3520x0f, 0xd7, 0x0f, 0xd7, 0x0f, 0xff, 0x0f, 0xff 353}; 354 355static int 356wavefront_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 377static void 378wavefront_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 388static int 389wavefront_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 444int 445snd_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 462int 463snd_wavefront_fx_open (snd_hwdep_t *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 472int 473snd_wavefront_fx_release (snd_hwdep_t *hw, struct file *file) 474 475{ 476 module_put(hw->card->module); 477 return 0; 478} 479 480int 481snd_wavefront_fx_ioctl (snd_hwdep_t *sdev, struct file *file, 482 unsigned int cmd, unsigned long arg) 483 484{ 485 snd_card_t *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 566int __init 567snd_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}