1 // SPDX-License-Identifier: GPL-2.0-or-later 1 2 /* 3 */ 4 5 /* 6 * Someday its supposed to make use of the WT 7 * for a Wavetable synthesizer. 8 */ 9 10 #include "au88x0.h" 11 #include "au88x0_wt.h" 12 13 static void vortex_fifo_setwtvalid(vortex_t * 14 static void vortex_connection_adb_mixin(vortex 15 unsign 16 unsign 17 unsign 18 static void vortex_connection_mixin_mix(vortex 19 unsign 20 unsign 21 static void vortex_fifo_wtinitialize(vortex_t 22 static int vortex_wt_SetReg(vortex_t * vortex, 23 u32 val); 24 25 /* WT */ 26 27 /* Put 2 WT channels together for one stereo i 28 static void vortex_wt_setstereo(vortex_t * vor 29 { 30 int temp; 31 32 //temp = hwread(vortex->mmio, 0x80 + ( 33 temp = hwread(vortex->mmio, WT_STEREO( 34 temp = (temp & 0xfe) | (stereo & 1); 35 //hwwrite(vortex->mmio, 0x80 + ((wt >> 36 hwwrite(vortex->mmio, WT_STEREO(wt), t 37 } 38 39 /* Join to mixdown route. */ 40 static void vortex_wt_setdsout(vortex_t * vort 41 { 42 int temp; 43 44 /* There is one DSREG register for eac 45 temp = hwread(vortex->mmio, WT_DSREG(( 46 if (en) 47 temp |= (1 << (wt & 0x1f)); 48 else 49 temp &= ~(1 << (wt & 0x1f)); 50 hwwrite(vortex->mmio, WT_DSREG((wt >= 51 } 52 53 /* Setup WT route. */ 54 static int vortex_wt_allocroute(vortex_t * vor 55 { 56 wt_voice_t *voice = &(vortex->wt_voice 57 int temp; 58 59 //FIXME: WT audio routing. 60 if (nr_ch) { 61 vortex_fifo_wtinitialize(vorte 62 vortex_fifo_setwtvalid(vortex, 63 vortex_wt_setstereo(vortex, wt 64 } else 65 vortex_fifo_setwtvalid(vortex, 66 67 /* Set mixdown mode. */ 68 vortex_wt_setdsout(vortex, wt, 1); 69 /* Set other parameter registers. */ 70 hwwrite(vortex->mmio, WT_SRAMP(0), 0x8 71 //hwwrite(vortex->mmio, WT_GMODE(0), 0 72 #ifdef CHIP_AU8830 73 hwwrite(vortex->mmio, WT_SRAMP(1), 0x8 74 //hwwrite(vortex->mmio, WT_GMODE(1), 0 75 #endif 76 hwwrite(vortex->mmio, WT_PARM(wt, 0), 77 hwwrite(vortex->mmio, WT_PARM(wt, 1), 78 hwwrite(vortex->mmio, WT_PARM(wt, 2), 79 80 temp = hwread(vortex->mmio, WT_PARM(wt 81 dev_dbg(vortex->card->dev, "WT PARM3: 82 //hwwrite(vortex->mmio, WT_PARM(wt, 3) 83 84 hwwrite(vortex->mmio, WT_DELAY(wt, 0), 85 hwwrite(vortex->mmio, WT_DELAY(wt, 1), 86 hwwrite(vortex->mmio, WT_DELAY(wt, 2), 87 hwwrite(vortex->mmio, WT_DELAY(wt, 3), 88 89 dev_dbg(vortex->card->dev, "WT GMODE: 90 hwread(vortex->mmio, WT_GMODE( 91 92 hwwrite(vortex->mmio, WT_PARM(wt, 2), 93 hwwrite(vortex->mmio, WT_PARM(wt, 3), 94 95 voice->parm0 = voice->parm1 = 0xcfb23e 96 hwwrite(vortex->mmio, WT_PARM(wt, 0), 97 hwwrite(vortex->mmio, WT_PARM(wt, 1), 98 dev_dbg(vortex->card->dev, "WT GMODE 2 99 hwread(vortex->mmio, WT_GMODE( 100 return 0; 101 } 102 103 104 static void vortex_wt_connect(vortex_t * vorte 105 { 106 int i, ii, mix; 107 108 #define NR_WTROUTES 6 109 #ifdef CHIP_AU8830 110 #define NR_WTBLOCKS 2 111 #else 112 #define NR_WTBLOCKS 1 113 #endif 114 115 for (i = 0; i < NR_WTBLOCKS; i++) { 116 for (ii = 0; ii < NR_WTROUTES; 117 mix = 118 vortex_adb_checkin 119 120 121 vortex->mixwt[(i * NR_ 122 123 vortex_route(vortex, e 124 ADB_WTOUT 125 126 vortex_connection_mixi 127 128 if (VORTEX_IS_QUAD(vor 129 vortex_connect 130 131 132 133 } 134 } 135 for (i = 0; i < NR_WT; i++) { 136 hwwrite(vortex->mmio, WT_RUN(i 137 } 138 } 139 140 /* Read WT Register */ 141 #if 0 142 static int vortex_wt_GetReg(vortex_t * vortex, 143 { 144 //int eax, esi; 145 146 if (reg == 4) { 147 return hwread(vortex->mmio, WT 148 } 149 if (reg == 7) { 150 return hwread(vortex->mmio, WT 151 } 152 153 return 0; 154 } 155 156 /* WT hardware abstraction layer generic regis 157 static int 158 vortex_wt_SetReg2(vortex_t * vortex, unsigned 159 u16 val) 160 { 161 /* 162 int eax, edx; 163 164 if (wt >= NR_WT) // 0x40 -> NR_WT 165 return 0; 166 167 if ((reg - 0x20) > 0) { 168 if ((reg - 0x21) != 0) 169 return 0; 170 eax = ((((b & 0xff) << 0xb) + (edx 171 } else { 172 eax = ((((b & 0xff) << 0xb) + (edx 173 } 174 hwwrite(vortex->mmio, eax, c); 175 */ 176 return 1; 177 } 178 179 /*public: static void __thiscall CWTHal::SetRe 180 #endif 181 static int 182 vortex_wt_SetReg(vortex_t * vortex, unsigned c 183 u32 val) 184 { 185 int ecx; 186 187 if ((reg == 5) || ((reg >= 7) && (reg 188 if (wt >= (NR_WT / NR_WT_PB)) 189 dev_warn(vortex->card- 190 "WT SetReg: b 191 reg, wt); 192 return 0; 193 } 194 } else { 195 if (wt >= NR_WT) { 196 dev_err(vortex->card-> 197 "WT SetReg: vo 198 return 0; 199 } 200 } 201 if (reg > 0xc) 202 return 0; 203 204 switch (reg) { 205 /* Voice specific parameters * 206 case 0: /* running */ 207 /* 208 pr_debug( "vortex: WT SetReg(0 209 WT_RUN(wt), (int)val); 210 */ 211 hwwrite(vortex->mmio, WT_RUN(w 212 return 0xc; 213 case 1: /* param 0 */ 214 /* 215 pr_debug( "vortex: WT SetReg(0 216 WT_PARM(wt,0), (int)val 217 */ 218 hwwrite(vortex->mmio, WT_PARM( 219 return 0xc; 220 case 2: /* param 1 */ 221 /* 222 pr_debug( "vortex: WT SetReg(0 223 WT_PARM(wt,1), (int)val 224 */ 225 hwwrite(vortex->mmio, WT_PARM( 226 return 0xc; 227 case 3: /* param 2 */ 228 /* 229 pr_debug( "vortex: WT SetReg(0 230 WT_PARM(wt,2), (int)val 231 */ 232 hwwrite(vortex->mmio, WT_PARM( 233 return 0xc; 234 case 4: /* param 3 */ 235 /* 236 pr_debug( "vortex: WT SetReg(0 237 WT_PARM(wt,3), (int)val 238 */ 239 hwwrite(vortex->mmio, WT_PARM( 240 return 0xc; 241 case 6: /* mute */ 242 /* 243 pr_debug( "vortex: WT SetReg(0 244 WT_MUTE(wt), (int)val); 245 */ 246 hwwrite(vortex->mmio, WT_MUTE( 247 return 0xc; 248 case 0xb: 249 /* delay */ 250 /* 251 pr_debug( "vortex: WT SetReg(0 252 WT_DELAY(wt,0), (int)va 253 */ 254 hwwrite(vortex->mmio, WT_DELAY 255 hwwrite(vortex->mmio, WT_DELAY 256 hwwrite(vortex->mmio, WT_DELAY 257 hwwrite(vortex->mmio, WT_DELAY 258 return 0xc; 259 /* Global WT block parameters 260 case 5: /* sramp */ 261 ecx = WT_SRAMP(wt); 262 break; 263 case 8: /* aramp */ 264 ecx = WT_ARAMP(wt); 265 break; 266 case 9: /* mramp */ 267 ecx = WT_MRAMP(wt); 268 break; 269 case 0xa: /* ctrl */ 270 ecx = WT_CTRL(wt); 271 break; 272 case 0xc: /* ds_reg */ 273 ecx = WT_DSREG(wt); 274 break; 275 default: 276 return 0; 277 } 278 /* 279 pr_debug( "vortex: WT SetReg(0x%x) = 0 280 */ 281 hwwrite(vortex->mmio, ecx, val); 282 return 1; 283 } 284 285 static void vortex_wt_init(vortex_t * vortex) 286 { 287 u32 var4, var8, varc, var10 = 0, edi; 288 289 var10 &= 0xFFFFFFE3; 290 var10 |= 0x22; 291 var10 &= 0xFFFFFEBF; 292 var10 |= 0x80; 293 var10 |= 0x200; 294 var10 &= 0xfffffffe; 295 var10 &= 0xfffffbff; 296 var10 |= 0x1800; 297 // var10 = 0x1AA2 298 var4 = 0x10000000; 299 varc = 0x00830000; 300 var8 = 0x00830000; 301 302 /* Init Bank registers. */ 303 for (edi = 0; edi < (NR_WT / NR_WT_PB) 304 vortex_wt_SetReg(vortex, 0xc, 305 vortex_wt_SetReg(vortex, 0xa, 306 vortex_wt_SetReg(vortex, 0x9, 307 vortex_wt_SetReg(vortex, 0x8, 308 vortex_wt_SetReg(vortex, 0x5, 309 } 310 /* Init Voice registers. */ 311 for (edi = 0; edi < NR_WT; edi++) { 312 vortex_wt_SetReg(vortex, 0x4, 313 vortex_wt_SetReg(vortex, 0x3, 314 vortex_wt_SetReg(vortex, 0x2, 315 vortex_wt_SetReg(vortex, 0x1, 316 vortex_wt_SetReg(vortex, 0xb, 317 } 318 var10 |= 1; 319 for (edi = 0; edi < (NR_WT / NR_WT_PB) 320 vortex_wt_SetReg(vortex, 0xa, 321 } 322 323 /* Extract of CAdbTopology::SetVolume(struct _ 324 #if 0 325 static void vortex_wt_SetVolume(vortex_t * vor 326 { 327 wt_voice_t *voice = &(vortex->wt_voice 328 int ecx = vol[1], eax = vol[0]; 329 330 /* This is pure guess */ 331 voice->parm0 &= 0xff00ffff; 332 voice->parm0 |= (vol[0] & 0xff) << 0x1 333 voice->parm1 &= 0xff00ffff; 334 voice->parm1 |= (vol[1] & 0xff) << 0x1 335 336 /* This is real */ 337 hwwrite(vortex, WT_PARM(wt, 0), voice- 338 hwwrite(vortex, WT_PARM(wt, 1), voice- 339 340 if (voice->this_1D0 & 4) { 341 eax >>= 8; 342 ecx = eax; 343 if (ecx < 0x80) 344 ecx = 0x7f; 345 voice->parm3 &= 0xFFFFC07F; 346 voice->parm3 |= (ecx & 0x7f) < 347 voice->parm3 &= 0xFFFFFF80; 348 voice->parm3 |= (eax & 0x7f); 349 } else { 350 voice->parm3 &= 0xFFE03FFF; 351 voice->parm3 |= (eax & 0xFE00) 352 } 353 354 hwwrite(vortex, WT_PARM(wt, 3), voice- 355 } 356 357 /* Extract of CAdbTopology::SetFrequency(unsig 358 static void vortex_wt_SetFrequency(vortex_t * 359 { 360 wt_voice_t *voice = &(vortex->wt_voice 361 u32 eax, edx; 362 363 //FIXME: 64 bit operation. 364 eax = ((sr << 0xf) * 0x57619F1) & 0xff 365 edx = (((sr << 0xf) * 0x57619F1)) >> 0 366 367 edx >>= 0xa; 368 edx <<= 1; 369 if (edx) { 370 if (edx & 0x0FFF80000) 371 eax = 0x7fff; 372 else { 373 edx <<= 0xd; 374 eax = 7; 375 while ((edx & 0x800000 376 edx <<= 1; 377 eax--; 378 if (eax == 0) 379 break; 380 } 381 if (eax) 382 edx <<= 1; 383 eax <<= 0xc; 384 edx >>= 0x14; 385 eax |= edx; 386 } 387 } else 388 eax = 0; 389 voice->parm0 &= 0xffff0001; 390 voice->parm0 |= (eax & 0x7fff) << 1; 391 voice->parm1 = voice->parm0 | 1; 392 // Wt: this_1D4 393 //AuWt::WriteReg((ulong)(this_1DC<<4)+ 394 //AuWt::WriteReg((ulong)(this_1DC<<4)+ 395 hwwrite(vortex->mmio, WT_PARM(wt, 0), 396 hwwrite(vortex->mmio, WT_PARM(wt, 1), 397 } 398 #endif 399 400 /* End of File */ 401
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.