162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci */ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * Someday its supposed to make use of the WT DMA engine 762306a36Sopenharmony_ci * for a Wavetable synthesizer. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "au88x0.h" 1162306a36Sopenharmony_ci#include "au88x0_wt.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistatic void vortex_fifo_setwtvalid(vortex_t * vortex, int fifo, int en); 1462306a36Sopenharmony_cistatic void vortex_connection_adb_mixin(vortex_t * vortex, int en, 1562306a36Sopenharmony_ci unsigned char channel, 1662306a36Sopenharmony_ci unsigned char source, 1762306a36Sopenharmony_ci unsigned char mixin); 1862306a36Sopenharmony_cistatic void vortex_connection_mixin_mix(vortex_t * vortex, int en, 1962306a36Sopenharmony_ci unsigned char mixin, 2062306a36Sopenharmony_ci unsigned char mix, int a); 2162306a36Sopenharmony_cistatic void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j); 2262306a36Sopenharmony_cistatic int vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, 2362306a36Sopenharmony_ci u32 val); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* WT */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* Put 2 WT channels together for one stereo interlaced channel. */ 2862306a36Sopenharmony_cistatic void vortex_wt_setstereo(vortex_t * vortex, u32 wt, u32 stereo) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci int temp; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci //temp = hwread(vortex->mmio, 0x80 + ((wt >> 0x5)<< 0xf) + (((wt & 0x1f) >> 1) << 2)); 3362306a36Sopenharmony_ci temp = hwread(vortex->mmio, WT_STEREO(wt)); 3462306a36Sopenharmony_ci temp = (temp & 0xfe) | (stereo & 1); 3562306a36Sopenharmony_ci //hwwrite(vortex->mmio, 0x80 + ((wt >> 0x5)<< 0xf) + (((wt & 0x1f) >> 1) << 2), temp); 3662306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_STEREO(wt), temp); 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* Join to mixdown route. */ 4062306a36Sopenharmony_cistatic void vortex_wt_setdsout(vortex_t * vortex, u32 wt, int en) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci int temp; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci /* There is one DSREG register for each bank (32 voices each). */ 4562306a36Sopenharmony_ci temp = hwread(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0)); 4662306a36Sopenharmony_ci if (en) 4762306a36Sopenharmony_ci temp |= (1 << (wt & 0x1f)); 4862306a36Sopenharmony_ci else 4962306a36Sopenharmony_ci temp &= ~(1 << (wt & 0x1f)); 5062306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0), temp); 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* Setup WT route. */ 5462306a36Sopenharmony_cistatic int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci wt_voice_t *voice = &(vortex->wt_voice[wt]); 5762306a36Sopenharmony_ci int temp; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci //FIXME: WT audio routing. 6062306a36Sopenharmony_ci if (nr_ch) { 6162306a36Sopenharmony_ci vortex_fifo_wtinitialize(vortex, wt, 1); 6262306a36Sopenharmony_ci vortex_fifo_setwtvalid(vortex, wt, 1); 6362306a36Sopenharmony_ci vortex_wt_setstereo(vortex, wt, nr_ch - 1); 6462306a36Sopenharmony_ci } else 6562306a36Sopenharmony_ci vortex_fifo_setwtvalid(vortex, wt, 0); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci /* Set mixdown mode. */ 6862306a36Sopenharmony_ci vortex_wt_setdsout(vortex, wt, 1); 6962306a36Sopenharmony_ci /* Set other parameter registers. */ 7062306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_SRAMP(0), 0x880000); 7162306a36Sopenharmony_ci //hwwrite(vortex->mmio, WT_GMODE(0), 0xffffffff); 7262306a36Sopenharmony_ci#ifdef CHIP_AU8830 7362306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_SRAMP(1), 0x880000); 7462306a36Sopenharmony_ci //hwwrite(vortex->mmio, WT_GMODE(1), 0xffffffff); 7562306a36Sopenharmony_ci#endif 7662306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 0), 0); 7762306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 1), 0); 7862306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 2), 0); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci temp = hwread(vortex->mmio, WT_PARM(wt, 3)); 8162306a36Sopenharmony_ci dev_dbg(vortex->card->dev, "WT PARM3: %x\n", temp); 8262306a36Sopenharmony_ci //hwwrite(vortex->mmio, WT_PARM(wt, 3), temp); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0); 8562306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_DELAY(wt, 1), 0); 8662306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0); 8762306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci dev_dbg(vortex->card->dev, "WT GMODE: %x\n", 9062306a36Sopenharmony_ci hwread(vortex->mmio, WT_GMODE(wt))); 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff); 9362306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci voice->parm0 = voice->parm1 = 0xcfb23e2f; 9662306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0); 9762306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1); 9862306a36Sopenharmony_ci dev_dbg(vortex->card->dev, "WT GMODE 2 : %x\n", 9962306a36Sopenharmony_ci hwread(vortex->mmio, WT_GMODE(wt))); 10062306a36Sopenharmony_ci return 0; 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic void vortex_wt_connect(vortex_t * vortex, int en) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci int i, ii, mix; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci#define NR_WTROUTES 6 10962306a36Sopenharmony_ci#ifdef CHIP_AU8830 11062306a36Sopenharmony_ci#define NR_WTBLOCKS 2 11162306a36Sopenharmony_ci#else 11262306a36Sopenharmony_ci#define NR_WTBLOCKS 1 11362306a36Sopenharmony_ci#endif 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci for (i = 0; i < NR_WTBLOCKS; i++) { 11662306a36Sopenharmony_ci for (ii = 0; ii < NR_WTROUTES; ii++) { 11762306a36Sopenharmony_ci mix = 11862306a36Sopenharmony_ci vortex_adb_checkinout(vortex, 11962306a36Sopenharmony_ci vortex->fixed_res, en, 12062306a36Sopenharmony_ci VORTEX_RESOURCE_MIXIN); 12162306a36Sopenharmony_ci vortex->mixwt[(i * NR_WTROUTES) + ii] = mix; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci vortex_route(vortex, en, 0x11, 12462306a36Sopenharmony_ci ADB_WTOUT(i, ii + 0x20), ADB_MIXIN(mix)); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci vortex_connection_mixin_mix(vortex, en, mix, 12762306a36Sopenharmony_ci vortex->mixplayb[ii % 2], 0); 12862306a36Sopenharmony_ci if (VORTEX_IS_QUAD(vortex)) 12962306a36Sopenharmony_ci vortex_connection_mixin_mix(vortex, en, 13062306a36Sopenharmony_ci mix, 13162306a36Sopenharmony_ci vortex->mixplayb[2 + 13262306a36Sopenharmony_ci (ii % 2)], 0); 13362306a36Sopenharmony_ci } 13462306a36Sopenharmony_ci } 13562306a36Sopenharmony_ci for (i = 0; i < NR_WT; i++) { 13662306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_RUN(i), 1); 13762306a36Sopenharmony_ci } 13862306a36Sopenharmony_ci} 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci/* Read WT Register */ 14162306a36Sopenharmony_ci#if 0 14262306a36Sopenharmony_cistatic int vortex_wt_GetReg(vortex_t * vortex, char reg, int wt) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci //int eax, esi; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci if (reg == 4) { 14762306a36Sopenharmony_ci return hwread(vortex->mmio, WT_PARM(wt, 3)); 14862306a36Sopenharmony_ci } 14962306a36Sopenharmony_ci if (reg == 7) { 15062306a36Sopenharmony_ci return hwread(vortex->mmio, WT_GMODE(wt)); 15162306a36Sopenharmony_ci } 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci return 0; 15462306a36Sopenharmony_ci} 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci/* WT hardware abstraction layer generic register interface. */ 15762306a36Sopenharmony_cistatic int 15862306a36Sopenharmony_civortex_wt_SetReg2(vortex_t * vortex, unsigned char reg, int wt, 15962306a36Sopenharmony_ci u16 val) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci /* 16262306a36Sopenharmony_ci int eax, edx; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci if (wt >= NR_WT) // 0x40 -> NR_WT 16562306a36Sopenharmony_ci return 0; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci if ((reg - 0x20) > 0) { 16862306a36Sopenharmony_ci if ((reg - 0x21) != 0) 16962306a36Sopenharmony_ci return 0; 17062306a36Sopenharmony_ci eax = ((((b & 0xff) << 0xb) + (edx & 0xff)) << 4) + 0x208; // param 2 17162306a36Sopenharmony_ci } else { 17262306a36Sopenharmony_ci eax = ((((b & 0xff) << 0xb) + (edx & 0xff)) << 4) + 0x20a; // param 3 17362306a36Sopenharmony_ci } 17462306a36Sopenharmony_ci hwwrite(vortex->mmio, eax, c); 17562306a36Sopenharmony_ci */ 17662306a36Sopenharmony_ci return 1; 17762306a36Sopenharmony_ci} 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci/*public: static void __thiscall CWTHal::SetReg(unsigned char,int,unsigned long) */ 18062306a36Sopenharmony_ci#endif 18162306a36Sopenharmony_cistatic int 18262306a36Sopenharmony_civortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, 18362306a36Sopenharmony_ci u32 val) 18462306a36Sopenharmony_ci{ 18562306a36Sopenharmony_ci int ecx; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci if ((reg == 5) || ((reg >= 7) && (reg <= 10)) || (reg == 0xc)) { 18862306a36Sopenharmony_ci if (wt >= (NR_WT / NR_WT_PB)) { 18962306a36Sopenharmony_ci dev_warn(vortex->card->dev, 19062306a36Sopenharmony_ci "WT SetReg: bank out of range. reg=0x%x, wt=%d\n", 19162306a36Sopenharmony_ci reg, wt); 19262306a36Sopenharmony_ci return 0; 19362306a36Sopenharmony_ci } 19462306a36Sopenharmony_ci } else { 19562306a36Sopenharmony_ci if (wt >= NR_WT) { 19662306a36Sopenharmony_ci dev_err(vortex->card->dev, 19762306a36Sopenharmony_ci "WT SetReg: voice out of range\n"); 19862306a36Sopenharmony_ci return 0; 19962306a36Sopenharmony_ci } 20062306a36Sopenharmony_ci } 20162306a36Sopenharmony_ci if (reg > 0xc) 20262306a36Sopenharmony_ci return 0; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci switch (reg) { 20562306a36Sopenharmony_ci /* Voice specific parameters */ 20662306a36Sopenharmony_ci case 0: /* running */ 20762306a36Sopenharmony_ci /* 20862306a36Sopenharmony_ci pr_debug( "vortex: WT SetReg(0x%x) = 0x%08x\n", 20962306a36Sopenharmony_ci WT_RUN(wt), (int)val); 21062306a36Sopenharmony_ci */ 21162306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_RUN(wt), val); 21262306a36Sopenharmony_ci return 0xc; 21362306a36Sopenharmony_ci case 1: /* param 0 */ 21462306a36Sopenharmony_ci /* 21562306a36Sopenharmony_ci pr_debug( "vortex: WT SetReg(0x%x) = 0x%08x\n", 21662306a36Sopenharmony_ci WT_PARM(wt,0), (int)val); 21762306a36Sopenharmony_ci */ 21862306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 0), val); 21962306a36Sopenharmony_ci return 0xc; 22062306a36Sopenharmony_ci case 2: /* param 1 */ 22162306a36Sopenharmony_ci /* 22262306a36Sopenharmony_ci pr_debug( "vortex: WT SetReg(0x%x) = 0x%08x\n", 22362306a36Sopenharmony_ci WT_PARM(wt,1), (int)val); 22462306a36Sopenharmony_ci */ 22562306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 1), val); 22662306a36Sopenharmony_ci return 0xc; 22762306a36Sopenharmony_ci case 3: /* param 2 */ 22862306a36Sopenharmony_ci /* 22962306a36Sopenharmony_ci pr_debug( "vortex: WT SetReg(0x%x) = 0x%08x\n", 23062306a36Sopenharmony_ci WT_PARM(wt,2), (int)val); 23162306a36Sopenharmony_ci */ 23262306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 2), val); 23362306a36Sopenharmony_ci return 0xc; 23462306a36Sopenharmony_ci case 4: /* param 3 */ 23562306a36Sopenharmony_ci /* 23662306a36Sopenharmony_ci pr_debug( "vortex: WT SetReg(0x%x) = 0x%08x\n", 23762306a36Sopenharmony_ci WT_PARM(wt,3), (int)val); 23862306a36Sopenharmony_ci */ 23962306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 3), val); 24062306a36Sopenharmony_ci return 0xc; 24162306a36Sopenharmony_ci case 6: /* mute */ 24262306a36Sopenharmony_ci /* 24362306a36Sopenharmony_ci pr_debug( "vortex: WT SetReg(0x%x) = 0x%08x\n", 24462306a36Sopenharmony_ci WT_MUTE(wt), (int)val); 24562306a36Sopenharmony_ci */ 24662306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_MUTE(wt), val); 24762306a36Sopenharmony_ci return 0xc; 24862306a36Sopenharmony_ci case 0xb: 24962306a36Sopenharmony_ci /* delay */ 25062306a36Sopenharmony_ci /* 25162306a36Sopenharmony_ci pr_debug( "vortex: WT SetReg(0x%x) = 0x%08x\n", 25262306a36Sopenharmony_ci WT_DELAY(wt,0), (int)val); 25362306a36Sopenharmony_ci */ 25462306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_DELAY(wt, 3), val); 25562306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_DELAY(wt, 2), val); 25662306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_DELAY(wt, 1), val); 25762306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_DELAY(wt, 0), val); 25862306a36Sopenharmony_ci return 0xc; 25962306a36Sopenharmony_ci /* Global WT block parameters */ 26062306a36Sopenharmony_ci case 5: /* sramp */ 26162306a36Sopenharmony_ci ecx = WT_SRAMP(wt); 26262306a36Sopenharmony_ci break; 26362306a36Sopenharmony_ci case 8: /* aramp */ 26462306a36Sopenharmony_ci ecx = WT_ARAMP(wt); 26562306a36Sopenharmony_ci break; 26662306a36Sopenharmony_ci case 9: /* mramp */ 26762306a36Sopenharmony_ci ecx = WT_MRAMP(wt); 26862306a36Sopenharmony_ci break; 26962306a36Sopenharmony_ci case 0xa: /* ctrl */ 27062306a36Sopenharmony_ci ecx = WT_CTRL(wt); 27162306a36Sopenharmony_ci break; 27262306a36Sopenharmony_ci case 0xc: /* ds_reg */ 27362306a36Sopenharmony_ci ecx = WT_DSREG(wt); 27462306a36Sopenharmony_ci break; 27562306a36Sopenharmony_ci default: 27662306a36Sopenharmony_ci return 0; 27762306a36Sopenharmony_ci } 27862306a36Sopenharmony_ci /* 27962306a36Sopenharmony_ci pr_debug( "vortex: WT SetReg(0x%x) = 0x%08x\n", ecx, (int)val); 28062306a36Sopenharmony_ci */ 28162306a36Sopenharmony_ci hwwrite(vortex->mmio, ecx, val); 28262306a36Sopenharmony_ci return 1; 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_cistatic void vortex_wt_init(vortex_t * vortex) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci u32 var4, var8, varc, var10 = 0, edi; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci var10 &= 0xFFFFFFE3; 29062306a36Sopenharmony_ci var10 |= 0x22; 29162306a36Sopenharmony_ci var10 &= 0xFFFFFEBF; 29262306a36Sopenharmony_ci var10 |= 0x80; 29362306a36Sopenharmony_ci var10 |= 0x200; 29462306a36Sopenharmony_ci var10 &= 0xfffffffe; 29562306a36Sopenharmony_ci var10 &= 0xfffffbff; 29662306a36Sopenharmony_ci var10 |= 0x1800; 29762306a36Sopenharmony_ci // var10 = 0x1AA2 29862306a36Sopenharmony_ci var4 = 0x10000000; 29962306a36Sopenharmony_ci varc = 0x00830000; 30062306a36Sopenharmony_ci var8 = 0x00830000; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci /* Init Bank registers. */ 30362306a36Sopenharmony_ci for (edi = 0; edi < (NR_WT / NR_WT_PB); edi++) { 30462306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0xc, edi, 0); /* ds_reg */ 30562306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0xa, edi, var10); /* ctrl */ 30662306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0x9, edi, var4); /* mramp */ 30762306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0x8, edi, varc); /* aramp */ 30862306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0x5, edi, var8); /* sramp */ 30962306a36Sopenharmony_ci } 31062306a36Sopenharmony_ci /* Init Voice registers. */ 31162306a36Sopenharmony_ci for (edi = 0; edi < NR_WT; edi++) { 31262306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0x4, edi, 0); /* param 3 0x20c */ 31362306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0x3, edi, 0); /* param 2 0x208 */ 31462306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0x2, edi, 0); /* param 1 0x204 */ 31562306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0x1, edi, 0); /* param 0 0x200 */ 31662306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0xb, edi, 0); /* delay 0x400 - 0x40c */ 31762306a36Sopenharmony_ci } 31862306a36Sopenharmony_ci var10 |= 1; 31962306a36Sopenharmony_ci for (edi = 0; edi < (NR_WT / NR_WT_PB); edi++) 32062306a36Sopenharmony_ci vortex_wt_SetReg(vortex, 0xa, edi, var10); /* ctrl */ 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci/* Extract of CAdbTopology::SetVolume(struct _ASPVOLUME *) */ 32462306a36Sopenharmony_ci#if 0 32562306a36Sopenharmony_cistatic void vortex_wt_SetVolume(vortex_t * vortex, int wt, int vol[]) 32662306a36Sopenharmony_ci{ 32762306a36Sopenharmony_ci wt_voice_t *voice = &(vortex->wt_voice[wt]); 32862306a36Sopenharmony_ci int ecx = vol[1], eax = vol[0]; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci /* This is pure guess */ 33162306a36Sopenharmony_ci voice->parm0 &= 0xff00ffff; 33262306a36Sopenharmony_ci voice->parm0 |= (vol[0] & 0xff) << 0x10; 33362306a36Sopenharmony_ci voice->parm1 &= 0xff00ffff; 33462306a36Sopenharmony_ci voice->parm1 |= (vol[1] & 0xff) << 0x10; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci /* This is real */ 33762306a36Sopenharmony_ci hwwrite(vortex, WT_PARM(wt, 0), voice->parm0); 33862306a36Sopenharmony_ci hwwrite(vortex, WT_PARM(wt, 1), voice->parm0); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci if (voice->this_1D0 & 4) { 34162306a36Sopenharmony_ci eax >>= 8; 34262306a36Sopenharmony_ci ecx = eax; 34362306a36Sopenharmony_ci if (ecx < 0x80) 34462306a36Sopenharmony_ci ecx = 0x7f; 34562306a36Sopenharmony_ci voice->parm3 &= 0xFFFFC07F; 34662306a36Sopenharmony_ci voice->parm3 |= (ecx & 0x7f) << 7; 34762306a36Sopenharmony_ci voice->parm3 &= 0xFFFFFF80; 34862306a36Sopenharmony_ci voice->parm3 |= (eax & 0x7f); 34962306a36Sopenharmony_ci } else { 35062306a36Sopenharmony_ci voice->parm3 &= 0xFFE03FFF; 35162306a36Sopenharmony_ci voice->parm3 |= (eax & 0xFE00) << 5; 35262306a36Sopenharmony_ci } 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci hwwrite(vortex, WT_PARM(wt, 3), voice->parm3); 35562306a36Sopenharmony_ci} 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci/* Extract of CAdbTopology::SetFrequency(unsigned long arg_0) */ 35862306a36Sopenharmony_cistatic void vortex_wt_SetFrequency(vortex_t * vortex, int wt, unsigned int sr) 35962306a36Sopenharmony_ci{ 36062306a36Sopenharmony_ci wt_voice_t *voice = &(vortex->wt_voice[wt]); 36162306a36Sopenharmony_ci u32 eax, edx; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci //FIXME: 64 bit operation. 36462306a36Sopenharmony_ci eax = ((sr << 0xf) * 0x57619F1) & 0xffffffff; 36562306a36Sopenharmony_ci edx = (((sr << 0xf) * 0x57619F1)) >> 0x20; 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci edx >>= 0xa; 36862306a36Sopenharmony_ci edx <<= 1; 36962306a36Sopenharmony_ci if (edx) { 37062306a36Sopenharmony_ci if (edx & 0x0FFF80000) 37162306a36Sopenharmony_ci eax = 0x7fff; 37262306a36Sopenharmony_ci else { 37362306a36Sopenharmony_ci edx <<= 0xd; 37462306a36Sopenharmony_ci eax = 7; 37562306a36Sopenharmony_ci while ((edx & 0x80000000) == 0) { 37662306a36Sopenharmony_ci edx <<= 1; 37762306a36Sopenharmony_ci eax--; 37862306a36Sopenharmony_ci if (eax == 0) 37962306a36Sopenharmony_ci break; 38062306a36Sopenharmony_ci } 38162306a36Sopenharmony_ci if (eax) 38262306a36Sopenharmony_ci edx <<= 1; 38362306a36Sopenharmony_ci eax <<= 0xc; 38462306a36Sopenharmony_ci edx >>= 0x14; 38562306a36Sopenharmony_ci eax |= edx; 38662306a36Sopenharmony_ci } 38762306a36Sopenharmony_ci } else 38862306a36Sopenharmony_ci eax = 0; 38962306a36Sopenharmony_ci voice->parm0 &= 0xffff0001; 39062306a36Sopenharmony_ci voice->parm0 |= (eax & 0x7fff) << 1; 39162306a36Sopenharmony_ci voice->parm1 = voice->parm0 | 1; 39262306a36Sopenharmony_ci // Wt: this_1D4 39362306a36Sopenharmony_ci //AuWt::WriteReg((ulong)(this_1DC<<4)+0x200, (ulong)this_1E4); 39462306a36Sopenharmony_ci //AuWt::WriteReg((ulong)(this_1DC<<4)+0x204, (ulong)this_1E8); 39562306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0); 39662306a36Sopenharmony_ci hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1); 39762306a36Sopenharmony_ci} 39862306a36Sopenharmony_ci#endif 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci/* End of File */ 401