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

📄 cs4231.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                        READ_IDR();                        WRITE_IAR(IAR_AUTOCAL_BEGIN | 0x1c);                        tmp_bits = READ_IDR();                        WRITE_IDR(CHANGE_DFR(tmp_bits, set_bits));                        READ_IDR();                        READ_IDR();                        CHIP_READY();                        cs4231_chip->perchip_info.record.sample_rate = value;                        return 0;                }        }        dprintk(("input rate failed\n"));        return -EINVAL;}static int cs4231_get_input_rate(struct sparcaudio_driver *drv){      struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;      return cs4231_chip->perchip_info.record.sample_rate;}/* Generically we support 4 channels. This hardware does 2 */static int cs4231_set_input_channels(struct sparcaudio_driver *drv, int value){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        int tmp_bits;        tprintk(("input channels %d\n", value));        WRITE_IAR(IAR_AUTOCAL_BEGIN | 0x1c);        tmp_bits = READ_IDR();        switch (value) {        case 1:                WRITE_IDR(CS4231_MONO_ON(tmp_bits));                break;        case 2:                WRITE_IDR(CS4231_STEREO_ON(tmp_bits));                break;        default:                dprintk(("input chan failed\n"));                return -EINVAL;        };        CHIP_READY();        cs4231_chip->perchip_info.record.channels = value;        return 0;}static int cs4231_get_input_channels(struct sparcaudio_driver *drv){      struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;      return cs4231_chip->perchip_info.record.channels;}/* Generically we support 4 channels. This hardware does 2 */static int cs4231_set_output_channels(struct sparcaudio_driver *drv, int value){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        int tmp_bits;        tprintk(("output channels %d\n", value));        WRITE_IAR(IAR_AUTOCAL_BEGIN | 0x8);        tmp_bits = READ_IDR();        switch (value) {        case 1:                WRITE_IDR(CS4231_MONO_ON(tmp_bits));                break;        case 2:                WRITE_IDR(CS4231_STEREO_ON(tmp_bits));                break;        default:                dprintk(("output chan failed\n"));                return -EINVAL;        };        CHIP_READY();    	cs4231_chip->perchip_info.play.channels = value;        return 0;}static int cs4231_get_output_channels(struct sparcaudio_driver *drv){      struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;      return cs4231_chip->perchip_info.play.channels;}static int cs4231_get_input_precision(struct sparcaudio_driver *drv){      struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;      return cs4231_chip->perchip_info.record.precision;}static int cs4231_get_output_precision(struct sparcaudio_driver *drv){      struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;      return cs4231_chip->perchip_info.play.precision;}static int cs4231_set_input_precision(struct sparcaudio_driver *drv, int val){      struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;      cs4231_chip->perchip_info.record.precision = val;      return cs4231_chip->perchip_info.record.precision;}static int cs4231_set_output_precision(struct sparcaudio_driver *drv, int val){      struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;       cs4231_chip->perchip_info.play.precision = val;      return cs4231_chip->perchip_info.play.precision;}/* Wait until the auto calibration process has finished */static void cs4231_ready(struct sparcaudio_driver *drv) {        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        unsigned int x;        WRITE_IAR(IAR_AUTOCAL_END);        x = 0;        do {                if (READ_IDR() != IAR_NOT_READY)                        break;                x++;        } while (x <= CS_TIMEOUT);        WRITE_IAR(0x0b);        x = 0;        do {                if (READ_IDR() != AUTOCAL_IN_PROGRESS)                        break;                x++;        } while (x <= CS_TIMEOUT);}/* Set output mute */static int cs4231_output_muted(struct sparcaudio_driver *drv, int value){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        tprintk(("in cs4231_output_muted: %d\n", value));        if (!value) {                WRITE_IAR(0x7);                WRITE_IDR(READ_IDR() & OUTCR_UNMUTE);                WRITE_IAR(0x6);                WRITE_IDR(READ_IDR() & OUTCR_UNMUTE);                cs4231_chip->perchip_info.output_muted = 0;        } else {                WRITE_IAR(0x7);                WRITE_IDR(READ_IDR() | OUTCR_MUTE);                WRITE_IAR(0x6);                WRITE_IDR(READ_IDR() | OUTCR_MUTE);                cs4231_chip->perchip_info.output_muted = 1;        }        return 0;}static int cs4231_get_output_muted(struct sparcaudio_driver *drv){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        return cs4231_chip->perchip_info.output_muted;}static int cs4231_get_formats(struct sparcaudio_driver *drv){        return (AFMT_MU_LAW | AFMT_A_LAW |                AFMT_U8 | AFMT_IMA_ADPCM |                 AFMT_S16_LE | AFMT_S16_BE);}static int cs4231_get_output_ports(struct sparcaudio_driver *drv){        return (AUDIO_LINE_OUT | AUDIO_SPEAKER | AUDIO_HEADPHONE);}static int cs4231_get_input_ports(struct sparcaudio_driver *drv){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        /* This apparently applies only to APC ultras, not ebus ultras */        if (cs4231_chip->status & CS_STATUS_IS_ULTRA)                return (AUDIO_LINE_IN | AUDIO_MICROPHONE | AUDIO_ANALOG_LOOPBACK);        else                return (AUDIO_INTERNAL_CD_IN | AUDIO_LINE_IN |                        AUDIO_MICROPHONE | AUDIO_ANALOG_LOOPBACK);}/* Set chip "output" port */static int cs4231_set_output_port(struct sparcaudio_driver *drv, int value){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        int retval = 0;        tprintk(("output port: %d\n", value));        /* Aaaaaah! It's all coming so fast! Turn it all off, then selectively         * enable things.         */        WRITE_IAR(0x1a);        WRITE_IDR(READ_IDR() | MONO_IOCR_MUTE);        WRITE_IAR(0x0a);        WRITE_IDR(READ_IDR() | PINCR_LINE_MUTE);        WRITE_IDR(READ_IDR() | PINCR_HDPH_MUTE);        if (value & AUDIO_SPEAKER) {                WRITE_IAR(0x1a);                WRITE_IDR(READ_IDR() & ~MONO_IOCR_MUTE);                retval |= AUDIO_SPEAKER;        }        if (value & AUDIO_HEADPHONE) {                WRITE_IAR(0x0a);                WRITE_IDR(READ_IDR() & ~PINCR_HDPH_MUTE);                retval |= AUDIO_HEADPHONE;        }        if (value & AUDIO_LINE_OUT) {                WRITE_IAR(0x0a);                WRITE_IDR(READ_IDR() & ~PINCR_LINE_MUTE);                retval |= AUDIO_LINE_OUT;        }          cs4231_chip->perchip_info.play.port = retval;        return (retval);}static int cs4231_get_output_port(struct sparcaudio_driver *drv){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        return cs4231_chip->perchip_info.play.port;}/* Set chip "input" port */static int cs4231_set_input_port(struct sparcaudio_driver *drv, int value){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        int retval = 0;        tprintk(("input port: %d\n", value));        /* You can have one and only one. This is probably wrong, but         * appears to be how SunOS is doing it. Should be able to mix.         * More work to be done. CD input mixable, analog loopback may be.         */        /* Ultra systems do not support AUDIO_INTERNAL_CD_IN */        /* This apparently applies only to APC ultras, not ebus ultras */        if (!(cs4231_chip->status & CS_STATUS_IS_ULTRA)) {                if (value & AUDIO_INTERNAL_CD_IN) {                        WRITE_IAR(0x1);                        WRITE_IDR(CDROM_ENABLE(READ_IDR()));                        WRITE_IAR(0x0);                        WRITE_IDR(CDROM_ENABLE(READ_IDR()));                        retval = AUDIO_INTERNAL_CD_IN;                }        }        if ((value & AUDIO_LINE_IN)) {                WRITE_IAR(0x1);                WRITE_IDR(LINE_ENABLE(READ_IDR()));                WRITE_IAR(0x0);                WRITE_IDR(LINE_ENABLE(READ_IDR()));                retval = AUDIO_LINE_IN;        } else if (value & AUDIO_MICROPHONE) {                WRITE_IAR(0x1);                WRITE_IDR(MIC_ENABLE(READ_IDR()));                WRITE_IAR(0x0);                WRITE_IDR(MIC_ENABLE(READ_IDR()));                retval = AUDIO_MICROPHONE;        } else if (value & AUDIO_ANALOG_LOOPBACK) {                WRITE_IAR(0x1);                WRITE_IDR(OUTPUTLOOP_ENABLE(READ_IDR()));                WRITE_IAR(0x0);                WRITE_IDR(OUTPUTLOOP_ENABLE(READ_IDR()));                retval = AUDIO_ANALOG_LOOPBACK;        }        cs4231_chip->perchip_info.record.port = retval;        return retval;}static int cs4231_get_input_port(struct sparcaudio_driver *drv){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        return cs4231_chip->perchip_info.record.port;}/* Set chip "monitor" gain */static int cs4231_set_monitor_volume(struct sparcaudio_driver *drv, int value){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        int a = 0;        tprintk(("monitor gain: %d\n", value));        /* This interpolation really sucks. The question is, be compatible          * with ScumOS/Sloaris or not?         */        a = CS4231_MON_MAX_ATEN - (value * (CS4231_MON_MAX_ATEN + 1) /                                    (AUDIO_MAX_GAIN + 1));        WRITE_IAR(0x0d);        if (a >= CS4231_MON_MAX_ATEN)                 WRITE_IDR(LOOPB_OFF);        else                 WRITE_IDR((a << 2) | LOOPB_ON);        if (value == AUDIO_MAX_GAIN)                 cs4231_chip->perchip_info.monitor_gain = AUDIO_MAX_GAIN;        else                 cs4231_chip->perchip_info.monitor_gain =                        ((CS4231_MAX_DEV_ATEN - a) *                          (AUDIO_MAX_GAIN + 1) /                          (CS4231_MAX_DEV_ATEN + 1));        return 0;}static int cs4231_get_monitor_volume(struct sparcaudio_driver *drv){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        return (int) cs4231_chip->perchip_info.monitor_gain;}static int cs4231_get_output_error(struct sparcaudio_driver *drv){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        return (int) cs4231_chip->perchip_info.play.error;}static int cs4231_get_input_error(struct sparcaudio_driver *drv){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        return (int) cs4231_chip->perchip_info.record.error;}#ifdef EB4231_SUPPORTstatic int eb4231_get_output_samples(struct sparcaudio_driver *drv){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        u32 dbcr = readl(cs4231_chip->eb2p + EBDMA_COUNT);        int count =                cs4231_length_to_samplecount(&cs4231_chip->perchip_info.play, dbcr);        return (cs4231_chip->perchip_info.play.samples -                 ((count > cs4231_chip->perchip_info.play.samples)                  ? 0 : count));}static int eb4231_get_input_samples(struct sparcaudio_driver *drv){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        u32 dbcr = readl(cs4231_chip->eb2c + EBDMA_COUNT);        int count =                cs4231_length_to_samplecount(&cs4231_chip->perchip_info.record, dbcr);        return (cs4231_chip->perchip_info.record.samples -                 ((count > cs4231_chip->perchip_info.record.samples) ?                0 : count));}#endifstatic int cs4231_get_output_samples(struct sparcaudio_driver *drv){        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;        u32 dmapc = sbus_readl(cs4231_chip->regs + APCPC);        int count =           cs4231_length_to_samplecount(&cs4231_chip->perchip_info.play, dmapc);        return (cs4231_chip->perchip_info.play.samples -                 ((count > cs4231_chip->perchip_info.play.samples)                  ? 0 : count));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -