1 /* 2 ********************************************************************** 3 * sblive_fx.h 4 * Copyright 1999, 2000 Creative Labs, Inc. 5 * 6 ********************************************************************** 7 * 8 * Date Author Summary of changes 9 * ---- ------ ------------------ 10 * October 20, 1999 Bertrand Lee base code release 11 * 12 ********************************************************************** 13 * 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public License as 16 * published by the Free Software Foundation; either version 2 of 17 * the License, or (at your option) any later version. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public 25 * License along with this program; if not, write to the Free 26 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 27 * USA. 28 * 29 ********************************************************************** 30 */ 31 32 #ifndef _EFXMGR_H 33 #define _EFXMGR_H 34 35 #define WRITE_EFX(a, b, c) sblive_writeptr((a), MICROCODEBASE + (b), 0, (c)) 36 37 #define OP(op, z, w, x, y) \ 38 do { WRITE_EFX(card, (pc) * 2, ((x) << 10) | (y)); \ 39 WRITE_EFX(card, (pc) * 2 + 1, ((op) << 20) | ((z) << 10) | (w)); \ 40 ++pc; } while (0) 41 42 #define NUM_INPUTS 0x20 43 #define NUM_OUTPUTS 0x20 44 #define NUM_GPRS 0x100 45 #define GPR_NAME_SIZE 32 46 #define PATCH_NAME_SIZE 32 47 48 struct dsp_rpatch { 49 char name[PATCH_NAME_SIZE]; 50 u16 code_start; 51 u16 code_size; 52 53 unsigned long gpr_used[NUM_GPRS / (sizeof(unsigned long) * 8) + 1]; 54 unsigned long gpr_input[NUM_GPRS / (sizeof(unsigned long) * 8) + 1]; 55 unsigned long route[NUM_OUTPUTS]; 56 unsigned long route_v[NUM_OUTPUTS]; 57 }; 58 59 struct dsp_patch { 60 char name[PATCH_NAME_SIZE]; 61 u8 id; 62 unsigned long input; /* bitmap of the lines used as inputs */ 63 unsigned long output; /* bitmap of the lines used as outputs */ 64 u16 code_start; 65 u16 code_size; 66 67 unsigned long gpr_used[NUM_GPRS / (sizeof(unsigned long) * 8) + 1]; /* bitmap of used gprs */ 68 unsigned long gpr_input[NUM_GPRS / (sizeof(unsigned long) * 8) + 1]; 69 u8 traml_istart; /* starting address of the internal tram lines used */ 70 u8 traml_isize; /* number of internal tram lines used */ 71 72 u8 traml_estart; 73 u8 traml_esize; 74 75 u16 tramb_istart; /* starting address of the internal tram memory used */ 76 u16 tramb_isize; /* amount of internal memory used */ 77 u32 tramb_estart; 78 u32 tramb_esize; 79 }; 80 81 struct dsp_gpr { 82 u8 type; /* gpr type, STATIC, DYNAMIC, INPUT, OUTPUT, CONTROL */ 83 char name[GPR_NAME_SIZE]; /* gpr value, only valid for control gprs */ 84 s32 min, max; /* value range for this gpr, only valid for control gprs */ 85 u8 line; /* which input/output line is the gpr attached, only valid for input/output gprs */ 86 u8 usage; 87 }; 88 89 enum { 90 GPR_TYPE_NULL = 0, 91 GPR_TYPE_IO, 92 GPR_TYPE_STATIC, 93 GPR_TYPE_DYNAMIC, 94 GPR_TYPE_CONTROL, 95 GPR_TYPE_CONSTANT 96 }; 97 98 #define GPR_BASE 0x100 99 #define OUTPUT_BASE 0x20 100 101 #define MAX_PATCHES_PAGES 32 102 103 struct patch_manager { 104 void *patch[MAX_PATCHES_PAGES]; 105 int current_pages; 106 struct dsp_rpatch rpatch; 107 struct dsp_gpr gpr[NUM_GPRS]; /* gpr usage table */ 108 spinlock_t lock; 109 s16 ctrl_gpr[SOUND_MIXER_NRDEVICES][2]; 110 }; 111 112 #define PATCHES_PER_PAGE (PAGE_SIZE / sizeof(struct dsp_patch)) 113 114 #define PATCH(mgr, i) ((struct dsp_patch *) (mgr)->patch[(i) / PATCHES_PER_PAGE] + (i) % PATCHES_PER_PAGE) 115 116 /* PCM volume control */ 117 #define TMP_PCM_L 0x100 //temp PCM L (after the vol control) 118 #define TMP_PCM_R 0x101 119 #define VOL_PCM_L 0x102 //vol PCM 120 #define VOL_PCM_R 0x103 121 122 /* Routing patch */ 123 #define TMP_AC_L 0x104 //tmp ac97 out 124 #define TMP_AC_R 0x105 125 #define TMP_REAR_L 0x106 //output - Temp Rear 126 #define TMP_REAR_R 0x107 127 #define TMP_DIGI_L 0x108 //output - Temp digital 128 #define TMP_DIGI_R 0x109 129 #define DSP_VOL_L 0x10a // main dsp volume 130 #define DSP_VOL_R 0x10b 131 132 /* hw inputs */ 133 #define PCM_IN_L 0x00 134 #define PCM_IN_R 0x01 135 136 #define PCM1_IN_L 0x04 137 #define PCM1_IN_R 0x05 138 //mutilchannel playback stream appear here: 139 140 #define MULTI_FRONT_L 0x08 141 #define MULTI_FRONT_R 0x09 142 #define MULTI_REAR_L 0x0a 143 #define MULTI_REAR_R 0x0b 144 #define MULTI_CENTER 0x0c 145 #define MULTI_LFE 0x0d 146 147 #define AC97_IN_L 0x10 148 #define AC97_IN_R 0x11 149 #define SPDIF_CD_L 0x12 150 #define SPDIF_CD_R 0x13 151 152 /* hw outputs */ 153 #define AC97_FRONT_L 0x20 154 #define AC97_FRONT_R 0x21 155 #define DIGITAL_OUT_L 0x22 156 #define DIGITAL_OUT_R 0x23 157 #define DIGITAL_CENTER 0x24 158 #define DIGITAL_LFE 0x25 159 160 #define ANALOG_REAR_L 0x28 161 #define ANALOG_REAR_R 0x29 162 #define ADC_REC_L 0x2a 163 #define ADC_REC_R 0x2b 164 165 #define ANALOG_CENTER 0x31 166 #define ANALOG_LFE 0x32 167 168 169 #define INPUT_PATCH_START(patch, nm, ln, i) \ 170 do { \ 171 patch = PATCH(mgr, patch_n); \ 172 strcpy(patch->name, nm); \ 173 patch->code_start = pc * 2; \ 174 patch->input = (1<<(0x1f&ln)); \ 175 patch->output= (1<<(0x1f&ln)); \ 176 patch->id = i; \ 177 } while(0) 178 179 #define INPUT_PATCH_END(patch) \ 180 do { \ 181 patch->code_size = pc * 2 - patch->code_start; \ 182 patch_n++; \ 183 } while(0) 184 185 186 #define ROUTING_PATCH_START(patch, nm) \ 187 do { \ 188 patch = &mgr->rpatch; \ 189 strcpy(patch->name, nm); \ 190 patch->code_start = pc * 2; \ 191 } while(0) 192 193 #define ROUTING_PATCH_END(patch) \ 194 do { \ 195 patch->code_size = pc * 2 - patch->code_start; \ 196 } while(0) 197 198 #define CONNECT(input, output) set_bit(input, &rpatch->route[(output) - OUTPUT_BASE]); 199 200 #define CONNECT_V(input, output) set_bit(input, &rpatch->route_v[(output) - OUTPUT_BASE]); 201 202 #define OUTPUT_PATCH_START(patch, nm, ln, i) \ 203 do { \ 204 patch = PATCH(mgr, patch_n); \ 205 strcpy(patch->name, nm); \ 206 patch->code_start = pc * 2; \ 207 patch->input = (1<<(0x1f&ln)); \ 208 patch->output= (1<<(0x1f&ln)); \ 209 patch->id = i; \ 210 } while(0) 211 212 #define OUTPUT_PATCH_END(patch) \ 213 do { \ 214 patch->code_size = pc * 2 - patch->code_start; \ 215 patch_n++; \ 216 } while(0) 217 218 #define GET_OUTPUT_GPR(patch, g, ln) \ 219 do { \ 220 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_IO; \ 221 mgr->gpr[(g) - GPR_BASE].usage++; \ 222 mgr->gpr[(g) - GPR_BASE].line = ln; \ 223 set_bit((g) - GPR_BASE, patch->gpr_used); \ 224 } while(0) 225 226 #define GET_INPUT_GPR(patch, g, ln) \ 227 do { \ 228 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_IO; \ 229 mgr->gpr[(g) - GPR_BASE].usage++; \ 230 mgr->gpr[(g) - GPR_BASE].line = ln; \ 231 set_bit((g) - GPR_BASE, patch->gpr_used); \ 232 set_bit((g) - GPR_BASE, patch->gpr_input); \ 233 } while(0) 234 235 #define GET_DYNAMIC_GPR(patch, g) \ 236 do { \ 237 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_DYNAMIC; \ 238 mgr->gpr[(g) - GPR_BASE].usage++; \ 239 set_bit((g) - GPR_BASE, patch->gpr_used); \ 240 } while(0) 241 242 #define GET_CONTROL_GPR(patch, g, nm, a, b) \ 243 do { \ 244 strcpy(mgr->gpr[(g) - GPR_BASE].name, nm); \ 245 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_CONTROL; \ 246 mgr->gpr[(g) - GPR_BASE].usage++; \ 247 mgr->gpr[(g) - GPR_BASE].min = a; \ 248 mgr->gpr[(g) - GPR_BASE].max = b; \ 249 sblive_writeptr(card, g, 0, b); \ 250 set_bit((g) - GPR_BASE, patch->gpr_used); \ 251 } while(0) 252 253 #endif /* _EFXMGR_H */ 254