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

📄 sbc.c

📁 powerpc内核mpc8241linux系统下char驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		printk(KERN_INFO "%s: DMA number out of range\n", hfmodem_drvname);		return -ENXIO;	}	if ((ret = config_resources(dev)))		return ret;	dev->scops = &sbc4_scops;	return 0;}/* --------------------------------------------------------------------- */static void sbc4_init(struct hfmodem_state *dev){}/* --------------------------------------------------------------------- */static void sbc4_prepare_input(struct hfmodem_state *dev){	unsigned long flags;        if (!reset_dsp(dev)) {                printk(KERN_ERR "%s: sbc: cannot reset sb dsp\n", hfmodem_drvname);                return;        }        save_flags(flags);        cli();        disable_dma(dev->io.dma);        clear_dma_ff(dev->io.dma);        set_dma_mode(dev->io.dma, DMA_MODE_READ | DMA_MODE_AUTOINIT);        set_dma_addr(dev->io.dma, virt_to_bus(dev->dma.buf));        set_dma_count(dev->io.dma, HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE);        enable_dma(dev->io.dma);        sbc_int_ack_16bit(dev);        write_dsp(dev, SBC_SAMPLE_RATE_IN); /* set sampling rate */        write_dsp(dev, HFMODEM_SRATE >> 8);        write_dsp(dev, HFMODEM_SRATE & 0xff);        write_dsp(dev, SBC_SPEAKER_OFF);         restore_flags(flags);}/* --------------------------------------------------------------------- */static void sbc4_trigger_input(struct hfmodem_state *dev){	unsigned long flags;        save_flags(flags);        cli();	write_dsp(dev, SBC4_IN16_AI_NO_FIFO);	write_dsp(dev, SBC4_MODE_UNS_MONO);	write_dsp(dev, (HFMODEM_FRAGSAMPLES-1) & 0xff);	write_dsp(dev, (HFMODEM_FRAGSAMPLES-1) >> 8);        restore_flags(flags);}/* --------------------------------------------------------------------- */static void sbc4_prepare_output(struct hfmodem_state *dev){	unsigned long flags;        if (!reset_dsp(dev)) {                printk(KERN_ERR "%s: sbc: cannot reset sb dsp\n", hfmodem_drvname);                return;        }        save_flags(flags);        cli();        disable_dma(dev->io.dma);        clear_dma_ff(dev->io.dma);        set_dma_mode(dev->io.dma, DMA_MODE_WRITE | DMA_MODE_AUTOINIT);        set_dma_addr(dev->io.dma, virt_to_bus(dev->dma.buf));        set_dma_count(dev->io.dma, HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE);        enable_dma(dev->io.dma);        sbc_int_ack_16bit(dev);        write_dsp(dev, SBC_SAMPLE_RATE_OUT); /* set sampling rate */        write_dsp(dev, HFMODEM_SRATE >> 8);        write_dsp(dev, HFMODEM_SRATE & 0xff);        write_dsp(dev, SBC_SPEAKER_ON);         restore_flags(flags);}/* --------------------------------------------------------------------- */static void sbc4_trigger_output(struct hfmodem_state *dev){	unsigned long flags;        save_flags(flags);        cli();	write_dsp(dev, SBC4_OUT16_AI_NO_FIFO);	write_dsp(dev, SBC4_MODE_UNS_MONO);	write_dsp(dev, (HFMODEM_FRAGSAMPLES-1) & 0xff);	write_dsp(dev, (HFMODEM_FRAGSAMPLES-1) >> 8);        restore_flags(flags);}/* --------------------------------------------------------------------- */static void sbc4_stop(struct hfmodem_state *dev){	reset_dsp(dev);}/* --------------------------------------------------------------------- */static unsigned int sbc4_intack(struct hfmodem_state *dev){	unsigned int dmaptr;	unsigned long flags;	unsigned char intsrc;	save_flags(flags);        cli();        outb(0x82, DSP_MIXER_ADDR(dev->io.base_addr));        intsrc = inb(DSP_MIXER_DATA(dev->io.base_addr));        if (intsrc & 0x01)                 sbc_int_ack_8bit(dev);        if (intsrc & 0x02)		sbc_int_ack_16bit(dev);        disable_dma(dev->io.dma);        clear_dma_ff(dev->io.dma);        dmaptr = get_dma_residue(dev->io.dma);        enable_dma(dev->io.dma);	restore_flags(flags);	if (dmaptr == 0 || dmaptr > HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE)		dmaptr = HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE;	return (HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE - dmaptr) / 2;}/* --------------------------------------------------------------------- */static void sbc4_mixer(struct hfmodem_state *dev, int src, int igain, int ogain){	unsigned long flags;	static const unsigned char srcbits[3] = { 0x18, 0x01, 0x06 };	save_flags(flags);	cli();	if (src >= 0 && src <= 2) {		set_mixer(dev, 0x3d, srcbits[src]);		set_mixer(dev, 0x3e, srcbits[src]);	}	if (ogain >= 0 && ogain <= 255) {		set_mixer(dev, 0x30, ogain);		set_mixer(dev, 0x31, ogain);	}	if (igain >= 0 && igain <= 255) {		set_mixer(dev, 0x36, igain);		set_mixer(dev, 0x37, igain);		set_mixer(dev, 0x38, igain);		set_mixer(dev, 0x39, igain);		set_mixer(dev, 0x3a, igain);	}	set_mixer(dev, 0x32, 0xff);	set_mixer(dev, 0x33, 0xff);	set_mixer(dev, 0x34, 0);	set_mixer(dev, 0x35, 0);	set_mixer(dev, 0x3b, 0); /* pc spkr vol */	set_mixer(dev, 0x3c, 0); /* output src */	set_mixer(dev, 0x3f, 0); /* inp gain */	set_mixer(dev, 0x40, 0);	set_mixer(dev, 0x41, 0); /* outp gain */	set_mixer(dev, 0x42, 0);	set_mixer(dev, 0x43, 1); /* mic agc off */	set_mixer(dev, 0x44, 8<<4); /* treble */	set_mixer(dev, 0x45, 8<<4); 	set_mixer(dev, 0x46, 8<<4); /* bass */	set_mixer(dev, 0x47, 8<<4); 		restore_flags(flags);}/* --------------------------------------------------------------------- */static void ess_prepare_input(struct hfmodem_state *dev){	unsigned long flags;	unsigned char tmp;        if (!reset_ess(dev)) {                printk(KERN_ERR "%s: sbc: cannot reset ess dsp\n", hfmodem_drvname);                return;        }        save_flags(flags);        cli();        disable_dma(dev->io.dma);        clear_dma_ff(dev->io.dma);        set_dma_mode(dev->io.dma, DMA_MODE_READ | DMA_MODE_AUTOINIT);        set_dma_addr(dev->io.dma, virt_to_bus(dev->dma.buf));        set_dma_count(dev->io.dma, HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE);        enable_dma(dev->io.dma);        sbc_int_ack_8bit(dev);	write_ess(dev, 0xa1, 128 - (397700 + HFMODEM_SRATE/2) / HFMODEM_SRATE);	/*	 * Set filter divider register	 * Rolloff at 90% of the half sampling rate	 */	write_ess(dev, 0xa2, 256-(7160000 / (82 * (HFMODEM_SRATE * 9 / 20))));        write_dsp(dev, SBC_SPEAKER_OFF); 	write_ess(dev, 0xb8, 0x0e); /* Auto init DMA mode */	read_ess(dev, 0xa8, &tmp);	write_ess(dev, 0xa8, (tmp & ~0x03) | 2);     /* Mono */	write_ess(dev, 0xb9, 2);    /* Demand mode (4 bytes/DMA request) */	/* 16 bit mono */	write_ess(dev, 0xb7, 0x71);	write_ess(dev, 0xb7, 0xf4);	read_ess(dev, 0xb1, &tmp);	write_ess(dev, 0xb1, (tmp & 0x0f) | 0x50);	read_ess(dev, 0xb2, &tmp);	write_ess(dev, 0xb2, (tmp & 0x0f) | 0x50); 	write_ess(dev, 0xa4, (unsigned char) ((-HFMODEM_FRAGSIZE) & 0xff));	write_ess(dev, 0xa5, (unsigned char) (((-HFMODEM_FRAGSIZE) >> 8) & 0xff));        restore_flags(flags);}/* --------------------------------------------------------------------- */static void ess_trigger_input(struct hfmodem_state *dev){	unsigned long flags;	unsigned char tmp;        save_flags(flags);        cli();	read_ess(dev, 0xb8, &tmp);	write_ess(dev, 0xb8, tmp | 0x0f);         /* Go */        restore_flags(flags);}/* --------------------------------------------------------------------- */void ess_prepare_output(struct hfmodem_state *dev){	unsigned long flags;	unsigned char tmp;        if (!reset_ess(dev)) {                printk(KERN_ERR "%s: sbc: cannot reset ess dsp\n", hfmodem_drvname);                return;        }        save_flags(flags);        cli();        disable_dma(dev->io.dma);        clear_dma_ff(dev->io.dma);        set_dma_mode(dev->io.dma, DMA_MODE_WRITE | DMA_MODE_AUTOINIT);        set_dma_addr(dev->io.dma, virt_to_bus(dev->dma.buf));        set_dma_count(dev->io.dma, HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE);        enable_dma(dev->io.dma);        sbc_int_ack_8bit(dev);	write_ess(dev, 0xa1, 128 - (397700 + HFMODEM_SRATE/2) / HFMODEM_SRATE);	/*	 * Set filter divider register	 * Rolloff at 90% of the half sampling rate	 */	write_ess(dev, 0xa2, 256-(7160000 / (82 * (HFMODEM_SRATE * 9 / 20))));	write_ess(dev, 0xb8, 0x04); /* Auto init DMA mode */	read_ess(dev, 0xa8, &tmp);	write_ess(dev, 0xa8, (tmp & ~0x03) | 2);     /* Mono */	write_ess(dev, 0xb9, 2);    /* Demand mode (4 bytes/DMA request) */	/* 16 bit mono */	write_ess(dev, 0xb6, 0x00);	write_ess(dev, 0xb7, 0x71);	write_ess(dev, 0xb7, 0xf4);	read_ess(dev, 0xb1, &tmp);	write_ess(dev, 0xb1, (tmp & 0x0f) | 0x50);	read_ess(dev, 0xb2, &tmp);	write_ess(dev, 0xb2, (tmp & 0x0f) | 0x50);	write_ess(dev, 0xa4, (unsigned char) ((-HFMODEM_FRAGSIZE) & 0xff));	write_ess(dev, 0xa5, (unsigned char) (((-HFMODEM_FRAGSIZE) >> 8) & 0xff));        write_dsp(dev, SBC_SPEAKER_ON);         restore_flags(flags);}/* --------------------------------------------------------------------- */void ess_trigger_output(struct hfmodem_state *dev){	unsigned long flags;	unsigned char tmp;        save_flags(flags);        cli();	read_ess(dev, 0xb8, &tmp);	write_ess(dev, 0xb8, tmp | 0x05);         /* Go */        restore_flags(flags);}/* --------------------------------------------------------------------- */unsigned int ess_intack(struct hfmodem_state *dev){	unsigned int dmaptr;	unsigned long flags;	unsigned char st;#if 0	static unsigned int cnt = 0;#endif	save_flags(flags);        cli();	st = inb(DSP_WRITE_STATUS(dev->io.base_addr));	sbc_int_ack_8bit(dev);        disable_dma(dev->io.dma);        clear_dma_ff(dev->io.dma);        dmaptr = get_dma_residue(dev->io.dma);        enable_dma(dev->io.dma);	restore_flags(flags);#if 0	cnt = (cnt + 1) & 0x3f;	if (!cnt)		printk(KERN_DEBUG "%s: ess: FIFO: full:%c empty:%c half empty:%c  IRQ: cpu:%c half empty:%c DMA:%c\n",		       hfmodem_drvname, '1'-!(st&0x20), '1'-!(st&0x10), '1'-!(st&0x8), 		       '1'-!(st&0x4), '1'-!(st&0x2), '1'-!(st&0x1));#endif	if (st & 0x20) /* FIFO full, 256 bytes */		dmaptr += 256;	else if (!(st & 0x10)) /* FIFO not empty, assume half full 128 bytes */		dmaptr += 128;	if (dmaptr > HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE)		dmaptr -= HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE;	if (dmaptr == 0 || dmaptr > HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE)		dmaptr = HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE;	return (HFMODEM_NUMFRAGS * HFMODEM_FRAGSIZE - dmaptr) / 2;}/* --------------------------------------------------------------------- */static void ess_mixer(struct hfmodem_state *dev, int src, int igain, int ogain){	unsigned long flags;	save_flags(flags);	cli();	if (src >= 0 && src <= 2) 		set_mixer(dev, 0x0c, ((src+3) & 3) << 1);	if (ogain >= 0 && ogain <= 255)		set_mixer(dev, 0x22, (ogain & 0xf0) | ((ogain >> 4) & 0xf));	if (igain >= 0 && igain <= 255) {		set_mixer(dev, 0x36, igain);		set_mixer(dev, 0x37, igain);		set_mixer(dev, 0x38, igain);		set_mixer(dev, 0x39, igain);		set_mixer(dev, 0x3a, igain);	}	set_mixer(dev, 0x4, 0xff);	set_mixer(dev, 0xe, 0x0);	set_mixer(dev, 0x26, 0);	set_mixer(dev, 0x28, 0);	set_mixer(dev, 0x2e, 0);	restore_flags(flags);}/* --------------------------------------------------------------------- */static const struct hfmodem_scops sbc4_scops = {	SBC_EXTENT, sbc4_init, sbc4_prepare_input, sbc4_trigger_input, 	sbc4_prepare_output, sbc4_trigger_output, sbc4_stop, sbc4_intack, sbc4_mixer};static const struct hfmodem_scops ess_scops = {	SBC_EXTENT, sbc4_init, ess_prepare_input, ess_trigger_input, 	ess_prepare_output, ess_trigger_output, sbc4_stop, ess_intack, ess_mixer};/* --------------------------------------------------------------------- */

⌨️ 快捷键说明

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