1/* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU Library General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 */ 16 17/* 18 * Someday its supposed to make use of the WT DMA engine 19 * for a Wavetable synthesizer. 20 */ 21 22#include "au88x0.h" 23#include "au88x0_wt.h" 24 25static void vortex_fifo_setwtvalid(vortex_t * vortex, int fifo, int en); 26static void vortex_connection_adb_mixin(vortex_t * vortex, int en, 27 unsigned char channel, 28 unsigned char source, 29 unsigned char mixin); 30static void vortex_connection_mixin_mix(vortex_t * vortex, int en, 31 unsigned char mixin, 32 unsigned char mix, int a); 33static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j); 34static int vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, 35 u32 val); 36 37/* WT */ 38 39/* Put 2 WT channels together for one stereo interlaced channel. */ 40static void vortex_wt_setstereo(vortex_t * vortex, u32 wt, u32 stereo) 41{ 42 int temp; 43 44 //temp = hwread(vortex->mmio, 0x80 + ((wt >> 0x5)<< 0xf) + (((wt & 0x1f) >> 1) << 2)); 45 temp = hwread(vortex->mmio, WT_STEREO(wt)); 46 temp = (temp & 0xfe) | (stereo & 1); 47 //hwwrite(vortex->mmio, 0x80 + ((wt >> 0x5)<< 0xf) + (((wt & 0x1f) >> 1) << 2), temp); 48 hwwrite(vortex->mmio, WT_STEREO(wt), temp); 49} 50 51/* Join to mixdown route. */ 52static void vortex_wt_setdsout(vortex_t * vortex, u32 wt, int en) 53{ 54 int temp; 55 56 /* There is one DSREG register for each bank (32 voices each). */ 57 temp = hwread(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0)); 58 if (en) 59 temp |= (1 << (wt & 0x1f)); 60 else 61 temp &= (1 << ~(wt & 0x1f)); 62 hwwrite(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0), temp); 63} 64 65/* Setup WT route. */ 66static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch) 67{ 68 wt_voice_t *voice = &(vortex->wt_voice[wt]); 69 int temp; 70 71 if (nr_ch) { 72 vortex_fifo_wtinitialize(vortex, wt, 1); 73 vortex_fifo_setwtvalid(vortex, wt, 1); 74 vortex_wt_setstereo(vortex, wt, nr_ch - 1); 75 } else 76 vortex_fifo_setwtvalid(vortex, wt, 0); 77 78 /* Set mixdown mode. */ 79 vortex_wt_setdsout(vortex, wt, 1); 80 /* Set other parameter registers. */ 81 hwwrite(vortex->mmio, WT_SRAMP(0), 0x880000); 82 //hwwrite(vortex->mmio, WT_GMODE(0), 0xffffffff); 83#ifdef CHIP_AU8830 84 hwwrite(vortex->mmio, WT_SRAMP(1), 0x880000); 85 //hwwrite(vortex->mmio, WT_GMODE(1), 0xffffffff); 86#endif 87 hwwrite(vortex->mmio, WT_PARM(wt, 0), 0); 88 hwwrite(vortex->mmio, WT_PARM(wt, 1), 0); 89 hwwrite(vortex->mmio, WT_PARM(wt, 2), 0); 90 91 temp = hwread(vortex->mmio, WT_PARM(wt, 3)); 92 printk(KERN_DEBUG "vortex: WT PARM3: %x\n", temp); 93 //hwwrite(vortex->mmio, WT_PARM(wt, 3), temp); 94 95 hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0); 96 hwwrite(vortex->mmio, WT_DELAY(wt, 1), 0); 97 hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0); 98 hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0); 99 100 printk(KERN_DEBUG "vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt))); 101 102 hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff); 103 hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810); 104 105 voice->parm0 = voice->parm1 = 0xcfb23e2f; 106 hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0); 107 hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1); 108 printk(KERN_DEBUG "vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt))); 109 return 0; 110} 111 112 113static void vortex_wt_connect(vortex_t * vortex, int en) 114{ 115 int i, ii, mix; 116 117#define NR_WTROUTES 6 118#ifdef CHIP_AU8830 119#define NR_WTBLOCKS 2 120#else 121#define NR_WTBLOCKS 1 122#endif 123 124 for (i = 0; i < NR_WTBLOCKS; i++) { 125 for (ii = 0; ii < NR_WTROUTES; ii++) { 126 mix = 127 vortex_adb_checkinout(vortex, 128 vortex->fixed_res, en, 129 VORTEX_RESOURCE_MIXIN); 130 vortex->mixwt[(i * NR_WTROUTES) + ii] = mix; 131 132 vortex_route(vortex, en, 0x11, 133 ADB_WTOUT(i, ii + 0x20), ADB_MIXIN(mix)); 134 135 vortex_connection_mixin_mix(vortex, en, mix, 136 vortex->mixplayb[ii % 2], 0); 137 if (VORTEX_IS_QUAD(vortex)) 138 vortex_connection_mixin_mix(vortex, en, 139 mix, 140 vortex->mixplayb[2 + 141 (ii % 2)], 0); 142 } 143 } 144 for (i = 0; i < NR_WT; i++) { 145 hwwrite(vortex->mmio, WT_RUN(i), 1); 146 } 147} 148 149/* Read WT Register */ 150static int 151vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, 152 u32 val) 153{ 154 int ecx; 155 156 if ((reg == 5) || ((reg >= 7) && (reg <= 10)) || (reg == 0xc)) { 157 if (wt >= (NR_WT / NR_WT_PB)) { 158 printk 159 ("vortex: WT SetReg: bank out of range. reg=0x%x, wt=%d\n", 160 reg, wt); 161 return 0; 162 } 163 } else { 164 if (wt >= NR_WT) { 165 printk(KERN_ERR "vortex: WT SetReg: voice out of range\n"); 166 return 0; 167 } 168 } 169 if (reg > 0xc) 170 return 0; 171 172 switch (reg) { 173 /* Voice specific parameters */ 174 case 0: /* running */ 175 /* 176 printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", 177 WT_RUN(wt), (int)val); 178 */ 179 hwwrite(vortex->mmio, WT_RUN(wt), val); 180 return 0xc; 181 break; 182 case 1: /* param 0 */ 183 /* 184 printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", 185 WT_PARM(wt,0), (int)val); 186 */ 187 hwwrite(vortex->mmio, WT_PARM(wt, 0), val); 188 return 0xc; 189 break; 190 case 2: /* param 1 */ 191 /* 192 printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", 193 WT_PARM(wt,1), (int)val); 194 */ 195 hwwrite(vortex->mmio, WT_PARM(wt, 1), val); 196 return 0xc; 197 break; 198 case 3: /* param 2 */ 199 /* 200 printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", 201 WT_PARM(wt,2), (int)val); 202 */ 203 hwwrite(vortex->mmio, WT_PARM(wt, 2), val); 204 return 0xc; 205 break; 206 case 4: /* param 3 */ 207 /* 208 printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", 209 WT_PARM(wt,3), (int)val); 210 */ 211 hwwrite(vortex->mmio, WT_PARM(wt, 3), val); 212 return 0xc; 213 break; 214 case 6: /* mute */ 215 /* 216 printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", 217 WT_MUTE(wt), (int)val); 218 */ 219 hwwrite(vortex->mmio, WT_MUTE(wt), val); 220 return 0xc; 221 break; 222 case 0xb: 223 { /* delay */ 224 /* 225 printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", 226 WT_DELAY(wt,0), (int)val); 227 */ 228 hwwrite(vortex->mmio, WT_DELAY(wt, 3), val); 229 hwwrite(vortex->mmio, WT_DELAY(wt, 2), val); 230 hwwrite(vortex->mmio, WT_DELAY(wt, 1), val); 231 hwwrite(vortex->mmio, WT_DELAY(wt, 0), val); 232 return 0xc; 233 } 234 break; 235 /* Global WT block parameters */ 236 case 5: /* sramp */ 237 ecx = WT_SRAMP(wt); 238 break; 239 case 8: /* aramp */ 240 ecx = WT_ARAMP(wt); 241 break; 242 case 9: /* mramp */ 243 ecx = WT_MRAMP(wt); 244 break; 245 case 0xa: /* ctrl */ 246 ecx = WT_CTRL(wt); 247 break; 248 case 0xc: /* ds_reg */ 249 ecx = WT_DSREG(wt); 250 break; 251 default: 252 return 0; 253 break; 254 } 255 /* 256 printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", ecx, (int)val); 257 */ 258 hwwrite(vortex->mmio, ecx, val); 259 return 1; 260} 261 262static void vortex_wt_init(vortex_t * vortex) 263{ 264 u32 var4, var8, varc, var10 = 0, edi; 265 266 var10 &= 0xFFFFFFE3; 267 var10 |= 0x22; 268 var10 &= 0xFFFFFEBF; 269 var10 |= 0x80; 270 var10 |= 0x200; 271 var10 &= 0xfffffffe; 272 var10 &= 0xfffffbff; 273 var10 |= 0x1800; 274 // var10 = 0x1AA2 275 var4 = 0x10000000; 276 varc = 0x00830000; 277 var8 = 0x00830000; 278 279 /* Init Bank registers. */ 280 for (edi = 0; edi < (NR_WT / NR_WT_PB); edi++) { 281 vortex_wt_SetReg(vortex, 0xc, edi, 0); /* ds_reg */ 282 vortex_wt_SetReg(vortex, 0xa, edi, var10); /* ctrl */ 283 vortex_wt_SetReg(vortex, 0x9, edi, var4); /* mramp */ 284 vortex_wt_SetReg(vortex, 0x8, edi, varc); /* aramp */ 285 vortex_wt_SetReg(vortex, 0x5, edi, var8); /* sramp */ 286 } 287 /* Init Voice registers. */ 288 for (edi = 0; edi < NR_WT; edi++) { 289 vortex_wt_SetReg(vortex, 0x4, edi, 0); /* param 3 0x20c */ 290 vortex_wt_SetReg(vortex, 0x3, edi, 0); /* param 2 0x208 */ 291 vortex_wt_SetReg(vortex, 0x2, edi, 0); /* param 1 0x204 */ 292 vortex_wt_SetReg(vortex, 0x1, edi, 0); /* param 0 0x200 */ 293 vortex_wt_SetReg(vortex, 0xb, edi, 0); /* delay 0x400 - 0x40c */ 294 } 295 var10 |= 1; 296 for (edi = 0; edi < (NR_WT / NR_WT_PB); edi++) 297 vortex_wt_SetReg(vortex, 0xa, edi, var10); /* ctrl */ 298} 299 300/* Extract of CAdbTopology::SetVolume(struct _ASPVOLUME *) */ 301 302/* End of File */ 303