⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cs4231.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
}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 + -