📄 au88x0_core.c
字号:
hwwrite(vortex->mmio, VORTEX_SRC_DATA0 + (src << 7) + (i << 2), 0); hwwrite(vortex->mmio, VORTEX_SRC_DATA + (src << 3), 0); hwwrite(vortex->mmio, VORTEX_SRC_DATA + (src << 3) + 4, 0);}static void vortex_src_cleardrift(vortex_t * vortex, unsigned char src){ hwwrite(vortex->mmio, VORTEX_SRC_DRIFT0 + (src << 2), 0); hwwrite(vortex->mmio, VORTEX_SRC_DRIFT1 + (src << 2), 0); hwwrite(vortex->mmio, VORTEX_SRC_DRIFT2 + (src << 2), 1);}static voidvortex_src_set_throttlesource(vortex_t * vortex, unsigned char src, int en){ int temp; temp = hwread(vortex->mmio, VORTEX_SRC_SOURCE); if (en) temp |= 1 << src; else temp &= ~(1 << src); hwwrite(vortex->mmio, VORTEX_SRC_SOURCE, temp);}static intvortex_src_persist_convratio(vortex_t * vortex, unsigned char src, int ratio){ int temp, lifeboat = 0; do { hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), ratio); temp = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2)); if ((++lifeboat) > 0x9) { printk(KERN_ERR "Vortex: Src cvr fail\n"); break; } } while (temp != ratio); return temp;}#if 0static void vortex_src_slowlock(vortex_t * vortex, unsigned char src){ int temp; hwwrite(vortex->mmio, VORTEX_SRC_DRIFT2 + (src << 2), 1); hwwrite(vortex->mmio, VORTEX_SRC_DRIFT0 + (src << 2), 0); temp = hwread(vortex->mmio, VORTEX_SRC_U0 + (src << 2)); if (temp & 0x200) hwwrite(vortex->mmio, VORTEX_SRC_U0 + (src << 2), temp & ~0x200L);}static voidvortex_src_change_convratio(vortex_t * vortex, unsigned char src, int ratio){ int temp, a; if ((ratio & 0x10000) && (ratio != 0x10000)) { if (ratio & 0x3fff) a = (0x11 - ((ratio >> 0xe) & 0x3)) - 1; else a = (0x11 - ((ratio >> 0xe) & 0x3)) - 2; } else a = 0xc; temp = hwread(vortex->mmio, VORTEX_SRC_U0 + (src << 2)); if (((temp >> 4) & 0xf) != a) hwwrite(vortex->mmio, VORTEX_SRC_U0 + (src << 2), (temp & 0xf) | ((a & 0xf) << 4)); vortex_src_persist_convratio(vortex, src, ratio);}static intvortex_src_checkratio(vortex_t * vortex, unsigned char src, unsigned int desired_ratio){ int hw_ratio, lifeboat = 0; hw_ratio = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2)); while (hw_ratio != desired_ratio) { hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), desired_ratio); if ((lifeboat++) > 15) { printk(KERN_ERR "Vortex: could not set src-%d from %d to %d\n", src, hw_ratio, desired_ratio); break; } } return hw_ratio;}#endif/* Objective: Set samplerate for given SRC module. Arguments: card: pointer to vortex_t strcut. src: Integer index of the SRC module. cr: Current sample rate conversion factor. b: unknown 16 bit value. sweep: Enable Samplerate fade from cr toward tr flag. dirplay: 1: playback, 0: recording. sl: Slow Lock flag. tr: Target samplerate conversion. thsource: Throttle source flag (no idea what that means).*/static void vortex_src_setupchannel(vortex_t * card, unsigned char src, unsigned int cr, unsigned int b, int sweep, int d, int dirplay, int sl, unsigned int tr, int thsource){ // noplayback: d=2,4,7,0xa,0xb when using first 2 src's. // c: enables pitch sweep. // looks like g is c related. Maybe g is a sweep parameter ? // g = cvr // dirplay: 0 = recording, 1 = playback // d = src hw index. int esi, ebp = 0, esp10; vortex_src_flushbuffers(card, src); if (sweep) { if ((tr & 0x10000) && (tr != 0x10000)) { tr = 0; esi = 0x7; } else { if ((((short)tr) < 0) && (tr != 0x8000)) { tr = 0; esi = 0x8; } else { tr = 1; esi = 0xc; } } } else { if ((cr & 0x10000) && (cr != 0x10000)) { tr = 0; /*ebx = 0 */ esi = 0x11 - ((cr >> 0xe) & 7); if (cr & 0x3fff) esi -= 1; else esi -= 2; } else { tr = 1; esi = 0xc; } } vortex_src_cleardrift(card, src); vortex_src_set_throttlesource(card, src, thsource); if ((dirplay == 0) && (sweep == 0)) { if (tr) esp10 = 0xf; else esp10 = 0xc; ebp = 0; } else { if (tr) ebp = 0xf; else ebp = 0xc; esp10 = 0; } hwwrite(card->mmio, VORTEX_SRC_U0 + (src << 2), (sl << 0x9) | (sweep << 0x8) | ((esi & 0xf) << 4) | d); /* 0xc0 esi=0xc c=f=0 d=0 */ vortex_src_persist_convratio(card, src, cr); hwwrite(card->mmio, VORTEX_SRC_U1 + (src << 2), b & 0xffff); /* 0 b=0 */ hwwrite(card->mmio, VORTEX_SRC_U2 + (src << 2), (tr << 0x11) | (dirplay << 0x10) | (ebp << 0x8) | esp10); /* 0x30f00 e=g=1 esp10=0 ebp=f */ //printk(KERN_INFO "vortex: SRC %d, d=0x%x, esi=0x%x, esp10=0x%x, ebp=0x%x\n", src, d, esi, esp10, ebp);}static void vortex_srcblock_init(vortex_t * vortex){ unsigned long addr; int x; hwwrite(vortex->mmio, VORTEX_SRC_SOURCESIZE, 0x1ff); /* for (x=0; x<0x10; x++) { vortex_src_init(&vortex_src[x], x); } */ //addr = 0xcc3c; //addr = 0x26c3c; addr = VORTEX_SRC_RTBASE + 0x3c; for (x = 0xf; x >= 0; x--) { hwwrite(vortex->mmio, addr, 0); addr -= 4; } //addr = 0xcc94; //addr = 0x26c94; addr = VORTEX_SRC_CHNBASE + 0x54; for (x = 0x15; x >= 0; x--) { hwwrite(vortex->mmio, addr, 0); addr -= 4; }}static intvortex_src_addWTD(vortex_t * vortex, unsigned char src, unsigned char ch){ int temp, lifeboat = 0, prev; // esp13 = src temp = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR); if ((temp & (1 << ch)) == 0) { hwwrite(vortex->mmio, VORTEX_SRC_CHNBASE + (ch << 2), src); vortex_src_en_sr(vortex, ch); return 1; } prev = VORTEX_SRC_CHNBASE + (ch << 2); /*ebp */ temp = hwread(vortex->mmio, prev); //while (temp & NR_SRC) { while (temp & 0x10) { prev = VORTEX_SRC_RTBASE + ((temp & 0xf) << 2); /*esp12 */ //prev = VORTEX_SRC_RTBASE + ((temp & (NR_SRC-1)) << 2); /*esp12*/ temp = hwread(vortex->mmio, prev); //printk(KERN_INFO "vortex: srcAddWTD: while addr=%x, val=%x\n", prev, temp); if ((++lifeboat) > 0xf) { printk(KERN_ERR "vortex_src_addWTD: lifeboat overflow\n"); return 0; } } hwwrite(vortex->mmio, VORTEX_SRC_RTBASE + ((temp & 0xf) << 2), src); //hwwrite(vortex->mmio, prev, (temp & (NR_SRC-1)) | NR_SRC); hwwrite(vortex->mmio, prev, (temp & 0xf) | 0x10); return 1;}static intvortex_src_delWTD(vortex_t * vortex, unsigned char src, unsigned char ch){ int esp14 = -1, esp18, eax, ebx, edx, ebp, esi = 0; //int esp1f=edi(while)=src, esp10=ch; eax = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR); if (((1 << ch) & eax) == 0) { printk(KERN_ERR "src alarm\n"); return 0; } ebp = VORTEX_SRC_CHNBASE + (ch << 2); esp18 = hwread(vortex->mmio, ebp); if (esp18 & 0x10) { ebx = (esp18 & 0xf); if (src == ebx) { ebx = VORTEX_SRC_RTBASE + (src << 2); edx = hwread(vortex->mmio, ebx); //7b60 hwwrite(vortex->mmio, ebp, edx); hwwrite(vortex->mmio, ebx, 0); } else { //7ad3 edx = hwread(vortex->mmio, VORTEX_SRC_RTBASE + (ebx << 2)); //printk(KERN_INFO "vortex: srcdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src); while ((edx & 0xf) != src) { if ((esi) > 0xf) { printk ("vortex: srcdelWTD: error, lifeboat overflow\n"); return 0; } esp14 = ebx; ebx = edx & 0xf; ebp = ebx << 2; edx = hwread(vortex->mmio, VORTEX_SRC_RTBASE + ebp); //printk(KERN_INFO "vortex: srcdelWTD: while addr=%x, val=%x\n", ebp, edx); esi++; } //7b30 ebp = ebx << 2; if (edx & 0x10) { /* Delete entry in between others */ ebx = VORTEX_SRC_RTBASE + ((edx & 0xf) << 2); edx = hwread(vortex->mmio, ebx); //7b60 hwwrite(vortex->mmio, VORTEX_SRC_RTBASE + ebp, edx); hwwrite(vortex->mmio, ebx, 0); //printk(KERN_INFO "vortex srcdelWTD between addr= 0x%x, val= 0x%x\n", ebp, edx); } else { /* Delete last entry */ //7b83 if (esp14 == -1) hwwrite(vortex->mmio, VORTEX_SRC_CHNBASE + (ch << 2), esp18 & 0xef); else { ebx = (0xffffffe0 & edx) | (0xf & ebx); hwwrite(vortex->mmio, VORTEX_SRC_RTBASE + (esp14 << 2), ebx); //printk(KERN_INFO"vortex srcdelWTD last addr= 0x%x, val= 0x%x\n", esp14, ebx); } hwwrite(vortex->mmio, VORTEX_SRC_RTBASE + ebp, 0); return 1; } } } else { //7be0 vortex_src_dis_sr(vortex, ch); hwwrite(vortex->mmio, ebp, 0); } return 1;} /*FIFO*/ static voidvortex_fifo_clearadbdata(vortex_t * vortex, int fifo, int x){ for (x--; x >= 0; x--) hwwrite(vortex->mmio, VORTEX_FIFO_ADBDATA + (((fifo << FIFO_SIZE_BITS) + x) << 2), 0);}#if 0static void vortex_fifo_adbinitialize(vortex_t * vortex, int fifo, int j){ vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE);#ifdef CHIP_AU8820 hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2), (FIFO_U1 | ((j & FIFO_MASK) << 0xb)));#else hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2), (FIFO_U1 | ((j & FIFO_MASK) << 0xc)));#endif}#endifstatic void vortex_fifo_setadbvalid(vortex_t * vortex, int fifo, int en){ hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2), (hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2)) & 0xffffffef) | ((1 & en) << 4) | FIFO_U1);}static voidvortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int b, int priority, int empty, int valid, int f){ int temp, lifeboat = 0; //int this_8[NR_ADB] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* position */ int this_4 = 0x2; /* f seems priority related. * CAsp4AdbDma::SetPriority is the only place that calls SetAdbCtrl with f set to 1 * every where else it is set to 0. It seems, however, that CAsp4AdbDma::SetPriority * is never called, thus the f related bits remain a mystery for now. */ do { temp = hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2)); if (lifeboat++ > 0xbb8) { printk(KERN_ERR "Vortex: vortex_fifo_setadbctrl fail\n"); break; } } while (temp & FIFO_RDONLY); // AU8830 semes to take some special care about fifo content (data). // But i'm just to lazy to translate that :) if (valid) { if ((temp & FIFO_VALID) == 0) { //this_8[fifo] = 0; vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE); // this_4#ifdef CHIP_AU8820 temp = (this_4 & 0x1f) << 0xb;#else temp = (this_4 & 0x3f) << 0xc;#endif temp = (temp & 0xfffffffd) | ((b & 1) << 1); temp = (temp & 0xfffffff3) | ((priority & 3) << 2); temp = (temp & 0xffffffef) | ((valid & 1) << 4); temp |= FIFO_U1; temp = (temp & 0xffffffdf) | ((empty & 1) << 5);#ifdef CHIP_AU8820 temp = (temp & 0xfffbffff) | ((f & 1) << 0x12);#endif#ifdef CHIP_AU8830 temp = (temp & 0xf7ffffff) | ((f & 1) << 0x1b); temp = (temp & 0xefffffff) | ((f & 1) << 0x1c);#endif#ifdef CHIP_AU8810 temp = (temp & 0xfeffffff) | ((f & 1) << 0x18); temp = (temp & 0xfdffffff) | ((f & 1) << 0x19);#endif } } else { if (temp & FIFO_VALID) {#ifdef CHIP_AU8820 temp = ((f & 1) << 0x12) | (temp & 0xfffbffef);#endif#ifdef CHIP_AU8830 temp = ((f & 1) << 0x1b) | (temp & 0xe7ffffef) | FIFO_BITS;#endif#ifdef CHIP_AU8810 temp = ((f & 1) << 0x18) | (temp & 0xfcffffef) | FIFO_BITS;#endif } else /*if (this_8[fifo]) */ vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE); } hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2), temp); hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2));}#ifndef CHIP_AU8810static void vortex_fifo_clearwtdata(vortex_t * vortex, int fifo, int x){ if (x < 1) return; for (x--; x >= 0; x--) hwwrite(vortex->mmio, VORTEX_FIFO_WTDATA + (((fifo << FIFO_SIZE_BITS) + x) << 2), 0);}static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j){ vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);#ifdef CHIP_AU8820 hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), (FIFO_U1 | ((j & FIFO_MASK) << 0xb)));#else hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), (FIFO_U1 | ((j & FIFO_MASK) << 0xc)));#endif}static void vortex_fifo_setwtvalid(vortex_t * vortex, int fifo, int en){ hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), (hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2)) & 0xffffffef) | ((en & 1) << 4) | FIFO_U1);}static voidvortex_fifo_setwtctrl(vortex_t * vortex, int fifo, int ctrl, int priority, int empty, int valid, int f){ int temp = 0, lifeboat = 0; int this_4 = 2; do { temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2)); if (lifeboat++ > 0xbb8) { printk(KERN_ERR "Vortex: vortex_fifo_setwtctrl fail\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -