📄 cs4218_tdm.c
字号:
*frameUsed += used * 4; return stereo? used * 2: used;}/* This is the default format of the codec. Signed, 16-bit stereo * generated by an application shouldn't have to be copied at all. * We should just get the phsical address of the buffers and update * the TDM BDs directly. */static ssize_t cs4218_ct_s16(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ ssize_t count, used; int stereo = sound.soft.stereo; short *fp = (short *) &frame[*frameUsed]; frameLeft >>= 2; userCount >>= (stereo? 2: 1); used = count = min(userCount, frameLeft); if (!stereo) { short *up = (short *) userPtr; while (count > 0) { short data; if (get_user(data, up++)) return -EFAULT; *fp++ = data; *fp++ = data; count--; } } else { if (copy_from_user(fp, userPtr, count * 4)) return -EFAULT; } *frameUsed += used * 4; return stereo? used * 4: used * 2;}static ssize_t cs4218_ct_u16(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ ssize_t count, used; int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); int stereo = sound.soft.stereo; short *fp = (short *) &frame[*frameUsed]; short *up = (short *) userPtr; frameLeft >>= 2; userCount >>= (stereo? 2: 1); used = count = min(userCount, frameLeft); while (count > 0) { int data; if (get_user(data, up++)) return -EFAULT; data ^= mask; *fp++ = data; if (stereo) { if (get_user(data, up++)) return -EFAULT; data ^= mask; } *fp++ = data; count--; } *frameUsed += used * 4; return stereo? used * 4: used * 2;}static ssize_t cs4218_ctx_law(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ unsigned short *table = (unsigned short *) (sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16); unsigned int data = expand_data; unsigned int *p = (unsigned int *) &frame[*frameUsed]; int bal = expand_bal; int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; int utotal, ftotal; int stereo = sound.soft.stereo; frameLeft >>= 2; if (stereo) userCount >>= 1; ftotal = frameLeft; utotal = userCount; while (frameLeft) { u_char c; if (bal < 0) { if (userCount == 0) break; if (get_user(c, userPtr++)) return -EFAULT; data = table[c]; if (stereo) { if (get_user(c, userPtr++)) return -EFAULT; data = (data << 16) + table[c]; } else data = (data << 16) + data; userCount--; bal += hSpeed; } *p++ = data; frameLeft--; bal -= sSpeed; } expand_bal = bal; expand_data = data; *frameUsed += (ftotal - frameLeft) * 4; utotal -= userCount; return stereo? utotal * 2: utotal;}static ssize_t cs4218_ctx_s8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ unsigned int *p = (unsigned int *) &frame[*frameUsed]; unsigned int data = expand_data; int bal = expand_bal; int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; int stereo = sound.soft.stereo; int utotal, ftotal; frameLeft >>= 2; if (stereo) userCount >>= 1; ftotal = frameLeft; utotal = userCount; while (frameLeft) { u_char c; if (bal < 0) { if (userCount == 0) break; if (get_user(c, userPtr++)) return -EFAULT; data = c << 8; if (stereo) { if (get_user(c, userPtr++)) return -EFAULT; data = (data << 16) + (c << 8); } else data = (data << 16) + data; userCount--; bal += hSpeed; } *p++ = data; frameLeft--; bal -= sSpeed; } expand_bal = bal; expand_data = data; *frameUsed += (ftotal - frameLeft) * 4; utotal -= userCount; return stereo? utotal * 2: utotal;}static ssize_t cs4218_ctx_u8(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ unsigned int *p = (unsigned int *) &frame[*frameUsed]; unsigned int data = expand_data; int bal = expand_bal; int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; int stereo = sound.soft.stereo; int utotal, ftotal; frameLeft >>= 2; if (stereo) userCount >>= 1; ftotal = frameLeft; utotal = userCount; while (frameLeft) { u_char c; if (bal < 0) { if (userCount == 0) break; if (get_user(c, userPtr++)) return -EFAULT; data = (c ^ 0x80) << 8; if (stereo) { if (get_user(c, userPtr++)) return -EFAULT; data = (data << 16) + ((c ^ 0x80) << 8); } else data = (data << 16) + data; userCount--; bal += hSpeed; } *p++ = data; frameLeft--; bal -= sSpeed; } expand_bal = bal; expand_data = data; *frameUsed += (ftotal - frameLeft) * 4; utotal -= userCount; return stereo? utotal * 2: utotal;}static ssize_t cs4218_ctx_s16(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ unsigned int *p = (unsigned int *) &frame[*frameUsed]; unsigned int data = expand_data; unsigned short *up = (unsigned short *) userPtr; int bal = expand_bal; int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; int stereo = sound.soft.stereo; int utotal, ftotal; frameLeft >>= 2; userCount >>= (stereo? 2: 1); ftotal = frameLeft; utotal = userCount; while (frameLeft) { unsigned short c; if (bal < 0) { if (userCount == 0) break; if (get_user(data, up++)) return -EFAULT; if (stereo) { if (get_user(c, up++)) return -EFAULT; data = (data << 16) + c; } else data = (data << 16) + data; userCount--; bal += hSpeed; } *p++ = data; frameLeft--; bal -= sSpeed; } expand_bal = bal; expand_data = data; *frameUsed += (ftotal - frameLeft) * 4; utotal -= userCount; return stereo? utotal * 4: utotal * 2;}static ssize_t cs4218_ctx_u16(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); unsigned int *p = (unsigned int *) &frame[*frameUsed]; unsigned int data = expand_data; unsigned short *up = (unsigned short *) userPtr; int bal = expand_bal; int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; int stereo = sound.soft.stereo; int utotal, ftotal; frameLeft >>= 2; userCount >>= (stereo? 2: 1); ftotal = frameLeft; utotal = userCount; while (frameLeft) { unsigned short c; if (bal < 0) { if (userCount == 0) break; if (get_user(data, up++)) return -EFAULT; data ^= mask; if (stereo) { if (get_user(c, up++)) return -EFAULT; data = (data << 16) + (c ^ mask); } else data = (data << 16) + data; userCount--; bal += hSpeed; } *p++ = data; frameLeft--; bal -= sSpeed; } expand_bal = bal; expand_data = data; *frameUsed += (ftotal - frameLeft) * 4; utotal -= userCount; return stereo? utotal * 4: utotal * 2;}static ssize_t cs4218_ct_s8_read(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ ssize_t count, used; short *p = (short *) &frame[*frameUsed]; int val, stereo = sound.soft.stereo; frameLeft >>= 2; if (stereo) userCount >>= 1; used = count = min(userCount, frameLeft); while (count > 0) { u_char data; val = *p++; data = val >> 8; if (put_user(data, (u_char *)userPtr++)) return -EFAULT; if (stereo) { val = *p; data = val >> 8; if (put_user(data, (u_char *)userPtr++)) return -EFAULT; } p++; count--; } *frameUsed += used * 4; return stereo? used * 2: used;}static ssize_t cs4218_ct_u8_read(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ ssize_t count, used; short *p = (short *) &frame[*frameUsed]; int val, stereo = sound.soft.stereo; frameLeft >>= 2; if (stereo) userCount >>= 1; used = count = min(userCount, frameLeft); while (count > 0) { u_char data; val = *p++; data = (val >> 8) ^ 0x80; if (put_user(data, (u_char *)userPtr++)) return -EFAULT; if (stereo) { val = *p; data = (val >> 8) ^ 0x80; if (put_user(data, (u_char *)userPtr++)) return -EFAULT; } p++; count--; } *frameUsed += used * 4; return stereo? used * 2: used;}static ssize_t cs4218_ct_s16_read(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ ssize_t count, used; int stereo = sound.soft.stereo; short *fp = (short *) &frame[*frameUsed]; frameLeft >>= 2; userCount >>= (stereo? 2: 1); used = count = min(userCount, frameLeft); if (!stereo) { short *up = (short *) userPtr; while (count > 0) { short data; data = *fp; if (put_user(data, up++)) return -EFAULT; fp+=2; count--; } } else { if (copy_to_user((u_char *)userPtr, fp, count * 4)) return -EFAULT; } *frameUsed += used * 4; return stereo? used * 4: used * 2;}static ssize_t cs4218_ct_u16_read(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ ssize_t count, used; int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); int stereo = sound.soft.stereo; short *fp = (short *) &frame[*frameUsed]; short *up = (short *) userPtr; frameLeft >>= 2; userCount >>= (stereo? 2: 1); used = count = min(userCount, frameLeft); while (count > 0) { int data; data = *fp++; data ^= mask; if (put_user(data, up++)) return -EFAULT; if (stereo) { data = *fp; data ^= mask; if (put_user(data, up++)) return -EFAULT; } fp++; count--; } *frameUsed += used * 4; return stereo? used * 4: used * 2;}static TRANS transCSNormal = { cs4218_ct_law, cs4218_ct_law, cs4218_ct_s8, cs4218_ct_u8, cs4218_ct_s16, cs4218_ct_u16, cs4218_ct_s16, cs4218_ct_u16};static TRANS transCSExpand = { cs4218_ctx_law, cs4218_ctx_law, cs4218_ctx_s8, cs4218_ctx_u8, cs4218_ctx_s16, cs4218_ctx_u16, cs4218_ctx_s16, cs4218_ctx_u16};static TRANS transCSNormalRead = { NULL, NULL, cs4218_ct_s8_read, cs4218_ct_u8_read, cs4218_ct_s16_read, cs4218_ct_u16_read, cs4218_ct_s16_read, cs4218_ct_u16_read};/*** Low level stuff *********************************************************/static void *CS_Alloc(unsigned int size, gfp_t flags){ int order; size >>= 13; for (order=0; order < 5; order++) { if (size == 0) break; size >>= 1; } return (void *)__get_free_pages(flags, order);}static void CS_Free(void *ptr, unsigned int size){ int order; size >>= 13; for (order=0; order < 5; order++) { if (size == 0) break; size >>= 1; } free_pages((ulong)ptr, order);}static int __init CS_IrqInit(void){ cpm_install_handler(CPMVEC_SMC2, cs4218_intr, NULL); return 1;}#ifdef MODULEstatic void CS_IrqCleanup(void){ volatile smc_t *sp; volatile cpm8xx_t *cp; /* First disable transmitter and receiver. */ sp = &cpmp->cp_smc[1]; sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); /* And now shut down the SMC. */ cp = cpmp; /* Get pointer to Communication Processor */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_STOP_TX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); /* Release the interrupt handler. */ cpm_free_handler(CPMVEC_SMC2); kfree(beep_buf); kd_mksound = orig_mksound;}#endif /* MODULE */static void CS_Silence(void){ volatile smc_t *sp; /* Disable transmitter. */ sp = &cpmp->cp_smc[1]; sp->smc_smcmr &= ~SMCMR_TEN;}/* Frequencies depend upon external oscillator. There are two * choices, 12.288 and 11.2896 MHz. The RPCG audio supports both through * and external control register selection bit. */static int cs4218_freqs[] = { /* 12.288 11.2896 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -