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

📄 es1688_lib.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));}static int snd_es1688_hw_free(snd_pcm_substream_t * substream){	return snd_pcm_lib_free_pages(substream);}static int snd_es1688_playback_prepare(snd_pcm_substream_t * substream){	unsigned long flags;	es1688_t *chip = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	unsigned int size = snd_pcm_lib_buffer_bytes(substream);	unsigned int count = snd_pcm_lib_period_bytes(substream);	chip->dma_size = size;	spin_lock_irqsave(&chip->reg_lock, flags);	snd_es1688_reset(chip);	snd_es1688_set_rate(chip, substream);	snd_es1688_write(chip, 0xb8, 4);	/* auto init DMA mode */	snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels));	snd_es1688_write(chip, 0xb9, 2);	/* demand mode (4 bytes/request) */	if (runtime->channels == 1) {		if (snd_pcm_format_width(runtime->format) == 8) {			/* 8. bit mono */			snd_es1688_write(chip, 0xb6, 0x80);			snd_es1688_write(chip, 0xb7, 0x51);			snd_es1688_write(chip, 0xb7, 0xd0);		} else {			/* 16. bit mono */			snd_es1688_write(chip, 0xb6, 0x00);			snd_es1688_write(chip, 0xb7, 0x71);			snd_es1688_write(chip, 0xb7, 0xf4);		}	} else {		if (snd_pcm_format_width(runtime->format) == 8) {			/* 8. bit stereo */			snd_es1688_write(chip, 0xb6, 0x80);			snd_es1688_write(chip, 0xb7, 0x51);			snd_es1688_write(chip, 0xb7, 0x98);		} else {			/* 16. bit stereo */			snd_es1688_write(chip, 0xb6, 0x00);			snd_es1688_write(chip, 0xb7, 0x71);			snd_es1688_write(chip, 0xb7, 0xbc);		}	}	snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50);	snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50);	snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKON);	spin_unlock_irqrestore(&chip->reg_lock, flags);	/* --- */	count = -count;	snd_dma_program(chip->dma8, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);	spin_lock_irqsave(&chip->reg_lock, flags);	snd_es1688_write(chip, 0xa4, (unsigned char) count);	snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8));	spin_unlock_irqrestore(&chip->reg_lock, flags);	return 0;}static int snd_es1688_playback_trigger(snd_pcm_substream_t * substream,				       int cmd){	es1688_t *chip = snd_pcm_substream_chip(substream);	return snd_es1688_trigger(chip, cmd, 0x05);}static int snd_es1688_capture_prepare(snd_pcm_substream_t * substream){	unsigned long flags;	es1688_t *chip = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	unsigned int size = snd_pcm_lib_buffer_bytes(substream);	unsigned int count = snd_pcm_lib_period_bytes(substream);	chip->dma_size = size;	spin_lock_irqsave(&chip->reg_lock, flags);	snd_es1688_reset(chip);	snd_es1688_set_rate(chip, substream);	snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKOFF);	snd_es1688_write(chip, 0xb8, 0x0e);	/* auto init DMA mode */	snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels));	snd_es1688_write(chip, 0xb9, 2);	/* demand mode (4 bytes/request) */	if (runtime->channels == 1) {		if (snd_pcm_format_width(runtime->format) == 8) {			/* 8. bit mono */			snd_es1688_write(chip, 0xb7, 0x51);			snd_es1688_write(chip, 0xb7, 0xd0);		} else {			/* 16. bit mono */			snd_es1688_write(chip, 0xb7, 0x71);			snd_es1688_write(chip, 0xb7, 0xf4);		}	} else {		if (snd_pcm_format_width(runtime->format) == 8) {			/* 8. bit stereo */			snd_es1688_write(chip, 0xb7, 0x51);			snd_es1688_write(chip, 0xb7, 0x98);		} else {			/* 16. bit stereo */			snd_es1688_write(chip, 0xb7, 0x71);			snd_es1688_write(chip, 0xb7, 0xbc);		}	}	snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50);	snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50);	spin_unlock_irqrestore(&chip->reg_lock, flags);	/* --- */	count = -count;	snd_dma_program(chip->dma8, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);	spin_lock_irqsave(&chip->reg_lock, flags);	snd_es1688_write(chip, 0xa4, (unsigned char) count);	snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8));	spin_unlock_irqrestore(&chip->reg_lock, flags);	return 0;}static int snd_es1688_capture_trigger(snd_pcm_substream_t * substream,				      int cmd){	es1688_t *chip = snd_pcm_substream_chip(substream);	return snd_es1688_trigger(chip, cmd, 0x0f);}irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs){	es1688_t *chip = snd_magic_cast(es1688_t, dev_id, return IRQ_NONE);	if (chip->trigger_value == 0x05)	/* ok.. playback is active */		snd_pcm_period_elapsed(chip->playback_substream);	if (chip->trigger_value == 0x0f)	/* ok.. capture is active */		snd_pcm_period_elapsed(chip->capture_substream);	inb(ES1688P(chip, DATA_AVAIL));	/* ack interrupt */	return IRQ_HANDLED;}static snd_pcm_uframes_t snd_es1688_playback_pointer(snd_pcm_substream_t * substream){	es1688_t *chip = snd_pcm_substream_chip(substream);	size_t ptr;		if (chip->trigger_value != 0x05)		return 0;	ptr = snd_dma_pointer(chip->dma8, chip->dma_size);	return bytes_to_frames(substream->runtime, ptr);}static snd_pcm_uframes_t snd_es1688_capture_pointer(snd_pcm_substream_t * substream){	es1688_t *chip = snd_pcm_substream_chip(substream);	size_t ptr;		if (chip->trigger_value != 0x0f)		return 0;	ptr = snd_dma_pointer(chip->dma8, chip->dma_size);	return bytes_to_frames(substream->runtime, ptr);}/* */static snd_pcm_hardware_t snd_es1688_playback ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,	.rate_min =		4000,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	65536,	.period_bytes_min =	64,	.period_bytes_max =	65536,	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};static snd_pcm_hardware_t snd_es1688_capture ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,	.rate_min =		4000,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	65536,	.period_bytes_min =	64,	.period_bytes_max =	65536,	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};/* */static int snd_es1688_playback_open(snd_pcm_substream_t * substream){	es1688_t *chip = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	if (chip->capture_substream != NULL)		return -EAGAIN;	chip->playback_substream = substream;	runtime->hw = snd_es1688_playback;	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				      &hw_constraints_clocks);	return 0;}static int snd_es1688_capture_open(snd_pcm_substream_t * substream){	es1688_t *chip = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	if (chip->playback_substream != NULL)		return -EAGAIN;	chip->capture_substream = substream;	runtime->hw = snd_es1688_capture;	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				      &hw_constraints_clocks);	return 0;}static int snd_es1688_playback_close(snd_pcm_substream_t * substream){	es1688_t *chip = snd_pcm_substream_chip(substream);	chip->playback_substream = NULL;	return 0;}static int snd_es1688_capture_close(snd_pcm_substream_t * substream){	es1688_t *chip = snd_pcm_substream_chip(substream);	chip->capture_substream = NULL;	return 0;}static int snd_es1688_free(es1688_t *chip){	if (chip->res_port) {		snd_es1688_init(chip, 0);		release_resource(chip->res_port);		kfree_nocheck(chip->res_port);	}	if (chip->irq >= 0)		free_irq(chip->irq, (void *) chip);	if (chip->dma8 >= 0) {		disable_dma(chip->dma8);		free_dma(chip->dma8);	}	snd_magic_kfree(chip);	return 0;}static int snd_es1688_dev_free(snd_device_t *device){	es1688_t *chip = snd_magic_cast(es1688_t, device->device_data, return -ENXIO);	return snd_es1688_free(chip);}static const char *snd_es1688_chip_id(es1688_t *chip){	static char tmp[16];	sprintf(tmp, "ES%s688 rev %i", chip->hardware == ES1688_HW_688 ? "" : "1", chip->version & 0x0f);	return tmp;}int snd_es1688_create(snd_card_t * card,		      unsigned long port,		      unsigned long mpu_port,		      int irq,		      int mpu_irq,		      int dma8,		      unsigned short hardware,		      es1688_t **rchip){	static snd_device_ops_t ops = {		.dev_free =	snd_es1688_dev_free,	};                                	es1688_t *chip;	int err;	*rchip = NULL;	chip = snd_magic_kcalloc(es1688_t, 0, GFP_KERNEL);	if (chip == NULL)		return -ENOMEM;	chip->irq = -1;	chip->dma8 = -1;		if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) {		snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);		snd_es1688_free(chip);		return -EBUSY;	}	if (request_irq(irq, snd_es1688_interrupt, SA_INTERRUPT, "ES1688", (void *) chip)) {		snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);		snd_es1688_free(chip);		return -EBUSY;	}	chip->irq = irq;	if (request_dma(dma8, "ES1688")) {		snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8);		snd_es1688_free(chip);		return -EBUSY;	}	chip->dma8 = dma8;	spin_lock_init(&chip->reg_lock);	spin_lock_init(&chip->mixer_lock);	chip->card = card;	chip->port = port;	mpu_port &= ~0x000f;	if (mpu_port < 0x300 || mpu_port > 0x330)		mpu_port = 0;	chip->mpu_port = mpu_port;	chip->mpu_irq = mpu_irq;	chip->hardware = hardware;	if ((err = snd_es1688_probe(chip)) < 0) {		snd_es1688_free(chip);		return err;	}	if ((err = snd_es1688_init(chip, 1)) < 0) {		snd_es1688_free(chip);		return err;	}	/* Register device */	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {		snd_es1688_free(chip);		return err;	}	*rchip = chip;	return 0;}static snd_pcm_ops_t snd_es1688_playback_ops = {	.open =			snd_es1688_playback_open,	.close =		snd_es1688_playback_close,	.ioctl =		snd_es1688_ioctl,	.hw_params =		snd_es1688_hw_params,	.hw_free =		snd_es1688_hw_free,

⌨️ 快捷键说明

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