File: /usr/src/linux/drivers/sound/emu10k1/efxmgr.h
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 u32 gpr_used[NUM_GPRS / 32];
54 u32 gpr_input[NUM_GPRS / 32];
55 u32 route[NUM_OUTPUTS];
56 u32 route_v[NUM_OUTPUTS];
57 };
58
59 struct dsp_patch {
60 char name[PATCH_NAME_SIZE];
61 u8 id;
62 u32 input; /* bitmap of the lines used as inputs */
63 u32 output; /* bitmap of the lines used as outputs */
64 u16 code_start;
65 u16 code_size;
66
67 u32 gpr_used[NUM_GPRS / 32]; /* bitmap of used gprs */
68 u32 gpr_input[NUM_GPRS / 32];
69 u8 traml_istart; /* starting address of the internal tram lines used */ u8 traml_isize; /* number of internal tram lines used */
70
71 u8 traml_estart;
72 u8 traml_esize;
73
74 u16 tramb_istart; /* starting address of the internal tram memory used */
75 u16 tramb_isize; /* amount of internal memory used */
76 u32 tramb_estart;
77 u32 tramb_esize;
78 };
79
80 struct dsp_gpr {
81 u8 type; /* gpr type, STATIC, DYNAMIC, INPUT, OUTPUT, CONTROL */
82 char name[GPR_NAME_SIZE]; /* gpr value, only valid for control gprs */
83 s32 min, max; /* value range for this gpr, only valid for control gprs */
84 u8 line; /* which input/output line is the gpr attached, only valid for input/output gprs */
85 u8 usage;
86 };
87
88 enum {
89 GPR_TYPE_NULL = 0,
90 GPR_TYPE_IO,
91 GPR_TYPE_STATIC,
92 GPR_TYPE_DYNAMIC,
93 GPR_TYPE_CONTROL,
94 GPR_TYPE_CONSTANT
95 };
96
97 #define GPR_BASE 0x100
98 #define OUTPUT_BASE 0x20
99
100 //We can get this info by looking at the code start
101 //#define PATCH_TYPE_INPUT 0x1
102 //#define PATCH_TYPE_OUTPUT 0x2
103
104 #define MAX_PATCHES_PAGES 32
105
106 struct patch_manager {
107 void *patch[MAX_PATCHES_PAGES];
108 int current_pages;
109 struct dsp_rpatch rpatch;
110 struct dsp_gpr gpr[NUM_GPRS]; /* gpr usage table */
111 spinlock_t lock;
112 s16 ctrl_gpr[SOUND_MIXER_NRDEVICES][2];
113 };
114
115
116 #define PATCHES_PER_PAGE (PAGE_SIZE / sizeof(struct dsp_patch))
117
118 #define PATCH(mgr, i) ((struct dsp_patch *) (mgr)->patch[(i) / PATCHES_PER_PAGE] + (i) % PATCHES_PER_PAGE)
119
120 /* PCM volume control */
121 #define TMP_PCM_L 0x100 //temp PCM L (after the vol control)
122 #define TMP_PCM_R 0x101
123 #define VOL_PCM_L 0x102 //vol PCM
124 #define VOL_PCM_R 0x103
125
126 /* Routing patch */
127 #define TMP_AC_L 0x104 //tmp ac97 out
128 #define TMP_AC_R 0x105
129 #define TMP_REAR_L 0x106 //output - Temp Rear
130 #define TMP_REAR_R 0x107
131 #define TMP_DIGI_L 0x108 //output - Temp digital
132 #define TMP_DIGI_R 0x109
133 #define DSP_VOL_L 0x10a // main dsp volume
134 #define DSP_VOL_R 0x10b
135
136 /* hw inputs */
137 #define PCM_IN_L 0x00
138 #define PCM_IN_R 0x01
139
140 #define PCM1_IN_L 0x04
141 #define PCM1_IN_R 0x05
142
143 #define AC97_IN_L 0x10
144 #define AC97_IN_R 0x11
145 #define SPDIF_CD_L 0x12
146 #define SPDIF_CD_R 0x13
147
148 /* hw outputs */
149 #define AC97_FRONT_L 0x20
150 #define AC97_FRONT_R 0x21
151 #define DIGITAL_OUT_L 0x22
152 #define DIGITAL_OUT_R 0x23
153 #define ANALOG_REAR_L 0x28
154 #define ANALOG_REAR_R 0x29
155 #define ADC_REC_L 0x2a
156 #define ADC_REC_R 0x2b
157
158 #define INPUT_PATCH_START(patch, nm, ln, i) \
159 do { \
160 patch = PATCH(mgr, patch_n); \
161 strcpy(patch->name, nm); \
162 patch->code_start = pc * 2; \
163 patch->input = (1<<(0x1f&ln)); \
164 patch->output= (1<<(0x1f&ln)); \
165 patch->id = i; \
166 } while(0)
167
168 #define INPUT_PATCH_END(patch) \
169 do { \
170 patch->code_size = pc * 2 - patch->code_start; \
171 patch_n++; \
172 } while(0)
173
174
175 #define ROUTING_PATCH_START(patch, nm) \
176 do { \
177 patch = &mgr->rpatch; \
178 strcpy(patch->name, nm); \
179 patch->code_start = pc * 2; \
180 } while(0)
181
182 #define ROUTING_PATCH_END(patch) \
183 do { \
184 patch->code_size = pc * 2 - patch->code_start; \
185 } while(0)
186
187 #define CONNECT(input, output) set_bit(input, &rpatch->route[(output) - OUTPUT_BASE]);
188
189 #define CONNECT_V(input, output) set_bit(input, &rpatch->route_v[(output) - OUTPUT_BASE]);
190
191 #define OUTPUT_PATCH_START(patch, nm, ln, i) \
192 do { \
193 patch = PATCH(mgr, patch_n); \
194 strcpy(patch->name, nm); \
195 patch->code_start = pc * 2; \
196 patch->input = (1<<(0x1f&ln)); \
197 patch->output= (1<<(0x1f&ln)); \
198 patch->id = i; \
199 } while(0)
200
201 #define OUTPUT_PATCH_END(patch) \
202 do { \
203 patch->code_size = pc * 2 - patch->code_start; \
204 patch_n++; \
205 } while(0)
206
207 #define GET_OUTPUT_GPR(patch, g, ln) \
208 do { \
209 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_IO; \
210 mgr->gpr[(g) - GPR_BASE].usage++; \
211 mgr->gpr[(g) - GPR_BASE].line = ln; \
212 set_bit((g) - GPR_BASE, patch->gpr_used); \
213 } while(0)
214
215 #define GET_INPUT_GPR(patch, g, ln) \
216 do { \
217 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_IO; \
218 mgr->gpr[(g) - GPR_BASE].usage++; \
219 mgr->gpr[(g) - GPR_BASE].line = ln; \
220 set_bit((g) - GPR_BASE, patch->gpr_used); \
221 set_bit((g) - GPR_BASE, patch->gpr_input); \
222 } while(0)
223
224 #define GET_DYNAMIC_GPR(patch, g) \
225 do { \
226 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_DYNAMIC; \
227 mgr->gpr[(g) - GPR_BASE].usage++; \
228 set_bit((g) - GPR_BASE, patch->gpr_used); \
229 } while(0)
230
231 #define GET_CONTROL_GPR(patch, g, nm, a, b) \
232 do { \
233 strcpy(mgr->gpr[(g) - GPR_BASE].name, nm); \
234 mgr->gpr[(g) - GPR_BASE].type = GPR_TYPE_CONTROL; \
235 mgr->gpr[(g) - GPR_BASE].usage++; \
236 mgr->gpr[(g) - GPR_BASE].min = a; \
237 mgr->gpr[(g) - GPR_BASE].max = b; \
238 sblive_writeptr(card, g, 0, b); \
239 set_bit((g) - GPR_BASE, patch->gpr_used); \
240 } while(0)
241
242 #endif /* _EFXMGR_H */
243