📄 cs4231.c
字号:
}static int cs4231_get_input_samples(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; u32 dmacc = sbus_readl(cs4231_chip->regs + APCCC); int count = cs4231_length_to_samplecount(&cs4231_chip->perchip_info.record, dmacc); return (cs4231_chip->perchip_info.record.samples - ((count > cs4231_chip->perchip_info.record.samples) ? 0 : count));}static int cs4231_get_output_pause(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; return (int) cs4231_chip->perchip_info.play.pause;}static int cs4231_get_input_pause(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; return (int) cs4231_chip->perchip_info.record.pause;}/* But for play/record we have these cheesy jacket routines because of * how this crap gets set. */static int cs4231_set_input_volume(struct sparcaudio_driver *drv, int value){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; cs4231_record_gain(drv, value, cs4231_chip->perchip_info.record.balance); return 0;}static int cs4231_get_input_volume(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; return (int) cs4231_chip->perchip_info.record.gain;}static int cs4231_set_output_volume(struct sparcaudio_driver *drv, int value){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; cs4231_play_gain(drv, value, cs4231_chip->perchip_info.play.balance); return 0;}static int cs4231_get_output_volume(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; return cs4231_chip->perchip_info.play.gain;}/* Likewise for balance */static int cs4231_set_input_balance(struct sparcaudio_driver *drv, int value){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; cs4231_chip->perchip_info.record.balance = value; cs4231_record_gain(drv, cs4231_chip->perchip_info.record.gain, cs4231_chip->perchip_info.record.balance); return 0;}static int cs4231_get_input_balance(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; return (int) cs4231_chip->perchip_info.record.balance;}static int cs4231_set_output_balance(struct sparcaudio_driver *drv, int value){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; cs4231_chip->perchip_info.play.balance = value; cs4231_play_gain(drv, cs4231_chip->perchip_info.play.gain, cs4231_chip->perchip_info.play.balance); return 0;}static int cs4231_get_output_balance(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; return (int) cs4231_chip->perchip_info.play.balance;}/* Set chip record gain */static int cs4231_record_gain(struct sparcaudio_driver *drv, int value, unsigned char balance){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; int tmp = 0, r, l, r_adj, l_adj; unsigned char old_gain; r = l = value; if (balance < AUDIO_MID_BALANCE) { r = (int) (value - ((AUDIO_MID_BALANCE - balance) << AUDIO_BALANCE_SHIFT)); if (r < 0) r = 0; } else if (balance > AUDIO_MID_BALANCE) { l = (int) (value - ((balance - AUDIO_MID_BALANCE) << AUDIO_BALANCE_SHIFT)); if (l < 0) l = 0; } l_adj = l * (CS4231_MAX_GAIN + 1) / (AUDIO_MAX_GAIN + 1); r_adj = r * (CS4231_MAX_GAIN + 1) / (AUDIO_MAX_GAIN + 1); WRITE_IAR(0x0); old_gain = READ_IDR(); WRITE_IDR(RECGAIN_SET(old_gain, l_adj)); WRITE_IAR(0x1); old_gain = READ_IDR(); WRITE_IDR(RECGAIN_SET(old_gain, r_adj)); if (l == value) { (l == 0) ? (tmp = 0) : (tmp = ((l_adj + 1) * AUDIO_MAX_GAIN) / (CS4231_MAX_GAIN + 1)); } else if (r == value) { (r == 0) ? (tmp = 0) : (tmp = ((r_adj + 1) * AUDIO_MAX_GAIN) / (CS4231_MAX_GAIN + 1)); } cs4231_chip->perchip_info.record.gain = tmp; return 0;}/* Set chip play gain */static int cs4231_play_gain(struct sparcaudio_driver *drv, int value, unsigned char balance){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; int tmp = 0, r, l, r_adj, l_adj; unsigned char old_gain; tprintk(("in play_gain: %d %c\n", value, balance)); r = l = value; if (balance < AUDIO_MID_BALANCE) { r = (int) (value - ((AUDIO_MID_BALANCE - balance) << AUDIO_BALANCE_SHIFT)); if (r < 0) r = 0; } else if (balance > AUDIO_MID_BALANCE) { l = (int) (value - ((balance - AUDIO_MID_BALANCE) << AUDIO_BALANCE_SHIFT)); if (l < 0) l = 0; } (l == 0) ? (l_adj = CS4231_MAX_DEV_ATEN) : (l_adj = CS4231_MAX_ATEN - (l * (CS4231_MAX_ATEN + 1) / (AUDIO_MAX_GAIN + 1))); (r == 0) ? (r_adj = CS4231_MAX_DEV_ATEN) : (r_adj = CS4231_MAX_ATEN - (r * (CS4231_MAX_ATEN + 1) / (AUDIO_MAX_GAIN + 1))); WRITE_IAR(0x6); old_gain = READ_IDR(); WRITE_IDR(GAIN_SET(old_gain, l_adj)); WRITE_IAR(0x7); old_gain = READ_IDR(); WRITE_IDR(GAIN_SET(old_gain, r_adj)); if ((value == 0) || (value == AUDIO_MAX_GAIN)) { tmp = value; } else { if (value == l) { tmp = ((CS4231_MAX_ATEN - l_adj) * (AUDIO_MAX_GAIN + 1) / (CS4231_MAX_ATEN + 1)); } else if (value == r) { tmp = ((CS4231_MAX_ATEN - r_adj) * (AUDIO_MAX_GAIN + 1) / (CS4231_MAX_ATEN + 1)); } } cs4231_chip->perchip_info.play.gain = tmp; return 0;}/* Reset the audio chip to a sane state. */static void cs4231_chip_reset(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; unsigned char vers; tprintk(("in cs4231_chip_reset\n")); if (cs4231_chip->status & CS_STATUS_IS_EBUS) {#ifdef EB4231_SUPPORT writel(EBUS_DCSR_RESET, cs4231_chip->eb2p + EBDMA_CSR); writel(EBUS_DCSR_RESET, cs4231_chip->eb2c + EBDMA_CSR); writel(EBUS_DCSR_BURST_SZ_16, cs4231_chip->eb2p + EBDMA_CSR); writel(EBUS_DCSR_BURST_SZ_16, cs4231_chip->eb2c + EBDMA_CSR);#endif } else { u32 tmp; sbus_writel(APC_CHIP_RESET, cs4231_chip->regs + APCCSR); sbus_writel(0x00, cs4231_chip->regs + APCCSR); tmp = sbus_readl(cs4231_chip->regs + APCCSR); tmp |= APC_CDC_RESET; sbus_writel(tmp, cs4231_chip->regs + APCCSR); udelay(20); tmp = sbus_readl(cs4231_chip->regs + APCCSR); tmp &= ~(APC_CDC_RESET); sbus_writel(tmp, cs4231_chip->regs + APCCSR); } WRITE_IAR(READ_IAR() | IAR_AUTOCAL_BEGIN); CHIP_READY(); WRITE_IAR(IAR_AUTOCAL_BEGIN | 0x0c); WRITE_IDR(MISC_IR_MODE2); /* This is the equivalent of DEFAULT_DATA_FMAT */ cs4231_set_input_encoding(drv, AUDIO_ENCODING_ULAW); cs4231_set_input_rate(drv, CS4231_RATE); cs4231_set_input_channels(drv, CS4231_CHANNELS); cs4231_set_input_precision(drv, CS4231_PRECISION); cs4231_set_output_encoding(drv, AUDIO_ENCODING_ULAW); cs4231_set_output_rate(drv, CS4231_RATE); cs4231_set_output_channels(drv, CS4231_CHANNELS); cs4231_set_output_precision(drv, CS4231_PRECISION); WRITE_IAR(0x19); /* see what we can turn on */ vers = READ_IDR(); if (vers & CS4231A) { tprintk(("This is a CS4231A\n")); cs4231_chip->status |= CS_STATUS_REV_A; } else { cs4231_chip->status &= ~CS_STATUS_REV_A; } WRITE_IAR(IAR_AUTOCAL_BEGIN | 0x10); WRITE_IDR(OLB_ENABLE); WRITE_IAR(IAR_AUTOCAL_BEGIN | 0x11); if (cs4231_chip->status & CS_STATUS_REV_A) WRITE_IDR(HPF_ON | XTALE_ON); else WRITE_IDR(HPF_ON); WRITE_IAR(IAR_AUTOCAL_BEGIN | 0x1a); WRITE_IDR(0x00); /* Now set things up for defaults */ cs4231_set_input_balance(drv, AUDIO_MID_BALANCE); cs4231_set_output_balance(drv, AUDIO_MID_BALANCE); cs4231_set_input_volume(drv, CS4231_DEFAULT_RECGAIN); cs4231_set_output_volume(drv, CS4231_DEFAULT_PLAYGAIN); cs4231_set_input_port(drv, AUDIO_MICROPHONE); cs4231_set_output_port(drv, AUDIO_SPEAKER); cs4231_set_monitor_volume(drv, LOOPB_OFF); WRITE_IAR(IAR_AUTOCAL_END); cs4231_ready(drv); WRITE_IAR(IAR_AUTOCAL_BEGIN | 0x09); WRITE_IDR(READ_IDR() & ACAL_DISABLE); WRITE_IAR(IAR_AUTOCAL_END); cs4231_ready(drv); cs4231_output_muted(drv, 0); cs4231_chip->recording_count = 0; cs4231_chip->input_next_dma_handle = 0; cs4231_chip->input_dma_handle = 0; cs4231_chip->input_next_dma_size = 0; cs4231_chip->input_dma_size = 0; cs4231_chip->playing_count = 0; cs4231_chip->output_next_dma_handle = 0; cs4231_chip->output_dma_handle = 0; cs4231_chip->output_next_dma_size = 0; cs4231_chip->output_dma_size = 0;}static intcs4231_length_to_samplecount(struct audio_prinfo *thisdir, unsigned int length){ unsigned int count; if (thisdir->channels == 2) count = (length / 2); else count = length; if (thisdir->encoding == AUDIO_ENCODING_LINEAR) count = (count / 2); else if (thisdir->encoding == AUDIO_ENCODING_DVI) count = (count / 4); return count;}#ifdef EB4231_SUPPORTstatic void eb4231_getsamplecount(struct sparcaudio_driver *drv, unsigned int length, unsigned int direction){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; struct audio_prinfo *thisdir; unsigned int count, curcount, nextcount, dbcr; if(direction == 1) { thisdir = &cs4231_chip->perchip_info.record; dbcr = readl(cs4231_chip->eb2c + EBDMA_COUNT); nextcount = cs4231_chip->input_next_dma_size; } else { thisdir = &cs4231_chip->perchip_info.play; dbcr = readl(cs4231_chip->eb2p + EBDMA_COUNT); nextcount = cs4231_chip->output_next_dma_size; } curcount = cs4231_length_to_samplecount(thisdir, dbcr); count = thisdir->samples; length = cs4231_length_to_samplecount(thisdir, length); /* normalize for where we are. */ thisdir->samples = ((count - nextcount) + (length - curcount));}#endifstatic void cs4231_getsamplecount(struct sparcaudio_driver *drv, unsigned int length, unsigned int direction){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; struct audio_prinfo *thisdir; unsigned int count, nextcount, curcount; u32 tmp; if (direction == 1) { /* record */ thisdir = &cs4231_chip->perchip_info.record; tmp = sbus_readl(cs4231_chip->regs + APCCC); curcount = cs4231_length_to_samplecount(thisdir, tmp); tmp = sbus_readl(cs4231_chip->regs + APCCNC); nextcount = cs4231_length_to_samplecount(thisdir, tmp); } else { /* play */ thisdir = &cs4231_chip->perchip_info.play; tmp = sbus_readl(cs4231_chip->regs + APCPC); curcount = cs4231_length_to_samplecount(thisdir, tmp); tmp = sbus_readl(cs4231_chip->regs + APCPNC); nextcount = cs4231_length_to_samplecount(thisdir, tmp); } count = thisdir->samples; length = cs4231_length_to_samplecount(thisdir, length);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -