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

📄 ad1816a_lib.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if ((status & AD1816A_PLAYBACK_IRQ_PENDING) && chip->playback_substream)		snd_pcm_period_elapsed(chip->playback_substream);	if ((status & AD1816A_CAPTURE_IRQ_PENDING) && chip->capture_substream)		snd_pcm_period_elapsed(chip->capture_substream);	if ((status & AD1816A_TIMER_IRQ_PENDING) && chip->timer)		snd_timer_interrupt(chip->timer, chip->timer->sticks);	spin_lock(&chip->lock);	snd_ad1816a_out(chip, AD1816A_INTERRUPT_STATUS, 0x00);	spin_unlock(&chip->lock);	return IRQ_HANDLED;}static struct snd_pcm_hardware snd_ad1816a_playback = {	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		(SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |				 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |				 SNDRV_PCM_FMTBIT_S16_BE),	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,	.rate_min =		4000,	.rate_max =		55200,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};static struct snd_pcm_hardware snd_ad1816a_capture = {	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		(SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |				 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |				 SNDRV_PCM_FMTBIT_S16_BE),	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,	.rate_min =		4000,	.rate_max =		55200,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};#if 0 /* not used now */static int snd_ad1816a_timer_close(struct snd_timer *timer){	struct snd_ad1816a *chip = snd_timer_chip(timer);	snd_ad1816a_close(chip, AD1816A_MODE_TIMER);	return 0;}static int snd_ad1816a_timer_open(struct snd_timer *timer){	struct snd_ad1816a *chip = snd_timer_chip(timer);	snd_ad1816a_open(chip, AD1816A_MODE_TIMER);	return 0;}static unsigned long snd_ad1816a_timer_resolution(struct snd_timer *timer){	snd_assert(timer != NULL, return 0);	return 10000;}static int snd_ad1816a_timer_start(struct snd_timer *timer){	unsigned short bits;	unsigned long flags;	struct snd_ad1816a *chip = snd_timer_chip(timer);	spin_lock_irqsave(&chip->lock, flags);	bits = snd_ad1816a_read(chip, AD1816A_INTERRUPT_ENABLE);	if (!(bits & AD1816A_TIMER_ENABLE)) {		snd_ad1816a_write(chip, AD1816A_TIMER_BASE_COUNT,			timer->sticks & 0xffff);		snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,			AD1816A_TIMER_ENABLE, 0xffff);	}	spin_unlock_irqrestore(&chip->lock, flags);	return 0;}static int snd_ad1816a_timer_stop(struct snd_timer *timer){	unsigned long flags;	struct snd_ad1816a *chip = snd_timer_chip(timer);	spin_lock_irqsave(&chip->lock, flags);	snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,		AD1816A_TIMER_ENABLE, 0x0000);	spin_unlock_irqrestore(&chip->lock, flags);	return 0;}static struct snd_timer_hardware snd_ad1816a_timer_table = {	.flags =	SNDRV_TIMER_HW_AUTO,	.resolution =	10000,	.ticks =	65535,	.open =		snd_ad1816a_timer_open,	.close =	snd_ad1816a_timer_close,	.c_resolution =	snd_ad1816a_timer_resolution,	.start =	snd_ad1816a_timer_start,	.stop =		snd_ad1816a_timer_stop,};#endif /* not used now */static int snd_ad1816a_playback_open(struct snd_pcm_substream *substream){	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	int error;	if ((error = snd_ad1816a_open(chip, AD1816A_MODE_PLAYBACK)) < 0)		return error;	runtime->hw = snd_ad1816a_playback;	snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);	snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);	chip->playback_substream = substream;	return 0;}static int snd_ad1816a_capture_open(struct snd_pcm_substream *substream){	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	int error;	if ((error = snd_ad1816a_open(chip, AD1816A_MODE_CAPTURE)) < 0)		return error;	runtime->hw = snd_ad1816a_capture;	snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);	snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);	chip->capture_substream = substream;	return 0;}static int snd_ad1816a_playback_close(struct snd_pcm_substream *substream){	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);	chip->playback_substream = NULL;	snd_ad1816a_close(chip, AD1816A_MODE_PLAYBACK);	return 0;}static int snd_ad1816a_capture_close(struct snd_pcm_substream *substream){	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);	chip->capture_substream = NULL;	snd_ad1816a_close(chip, AD1816A_MODE_CAPTURE);	return 0;}static void __devinit snd_ad1816a_init(struct snd_ad1816a *chip){	unsigned long flags;	spin_lock_irqsave(&chip->lock, flags);	snd_ad1816a_out(chip, AD1816A_INTERRUPT_STATUS, 0x00);	snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,		AD1816A_PLAYBACK_ENABLE | AD1816A_PLAYBACK_PIO, 0x00);	snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,		AD1816A_CAPTURE_ENABLE | AD1816A_CAPTURE_PIO, 0x00);	snd_ad1816a_write(chip, AD1816A_INTERRUPT_ENABLE, 0x0000);	snd_ad1816a_write_mask(chip, AD1816A_CHIP_CONFIG,		AD1816A_CAPTURE_NOT_EQUAL | AD1816A_WSS_ENABLE, 0xffff);	snd_ad1816a_write(chip, AD1816A_DSP_CONFIG, 0x0000);	snd_ad1816a_write(chip, AD1816A_POWERDOWN_CTRL, 0x0000);	spin_unlock_irqrestore(&chip->lock, flags);}static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip){	unsigned long flags;	spin_lock_irqsave(&chip->lock, flags);	switch (chip->version = snd_ad1816a_read(chip, AD1816A_VERSION_ID)) {	case 0:		chip->hardware = AD1816A_HW_AD1815;		break;	case 1:		chip->hardware = AD1816A_HW_AD18MAX10;		break;	case 3:		chip->hardware = AD1816A_HW_AD1816A;		break;	default:		chip->hardware = AD1816A_HW_AUTO;	}	spin_unlock_irqrestore(&chip->lock, flags);	return 0;}static int snd_ad1816a_free(struct snd_ad1816a *chip){	release_and_free_resource(chip->res_port);	if (chip->irq >= 0)		free_irq(chip->irq, (void *) chip);	if (chip->dma1 >= 0) {		snd_dma_disable(chip->dma1);		free_dma(chip->dma1);	}	if (chip->dma2 >= 0) {		snd_dma_disable(chip->dma2);		free_dma(chip->dma2);	}	kfree(chip);	return 0;}static int snd_ad1816a_dev_free(struct snd_device *device){	struct snd_ad1816a *chip = device->device_data;	return snd_ad1816a_free(chip);}static const char __devinit *snd_ad1816a_chip_id(struct snd_ad1816a *chip){	switch (chip->hardware) {	case AD1816A_HW_AD1816A: return "AD1816A";	case AD1816A_HW_AD1815:	return "AD1815";	case AD1816A_HW_AD18MAX10: return "AD18max10";	default:		snd_printk("Unknown chip version %d:%d.\n",			chip->version, chip->hardware);		return "AD1816A - unknown";	}}int __devinit snd_ad1816a_create(struct snd_card *card,				 unsigned long port, int irq, int dma1, int dma2,				 struct snd_ad1816a **rchip){        static struct snd_device_ops ops = {		.dev_free =	snd_ad1816a_dev_free,	};	int error;	struct snd_ad1816a *chip;	*rchip = NULL;	chip = kzalloc(sizeof(*chip), GFP_KERNEL);	if (chip == NULL)		return -ENOMEM;	chip->irq = -1;	chip->dma1 = -1;	chip->dma2 = -1;	if ((chip->res_port = request_region(port, 16, "AD1816A")) == NULL) {		snd_printk(KERN_ERR "ad1816a: can't grab port 0x%lx\n", port);		snd_ad1816a_free(chip);		return -EBUSY;	}	if (request_irq(irq, snd_ad1816a_interrupt, IRQF_DISABLED, "AD1816A", (void *) chip)) {		snd_printk(KERN_ERR "ad1816a: can't grab IRQ %d\n", irq);		snd_ad1816a_free(chip);		return -EBUSY;	}	chip->irq = irq;	if (request_dma(dma1, "AD1816A - 1")) {		snd_printk(KERN_ERR "ad1816a: can't grab DMA1 %d\n", dma1);		snd_ad1816a_free(chip);		return -EBUSY;	}	chip->dma1 = dma1;	if (request_dma(dma2, "AD1816A - 2")) {		snd_printk(KERN_ERR "ad1816a: can't grab DMA2 %d\n", dma2);		snd_ad1816a_free(chip);		return -EBUSY;	}	chip->dma2 = dma2;	chip->card = card;	chip->port = port;	spin_lock_init(&chip->lock);	if ((error = snd_ad1816a_probe(chip))) {		snd_ad1816a_free(chip);		return error;	}	snd_ad1816a_init(chip);	/* Register device */	if ((error = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {		snd_ad1816a_free(chip);		return error;	}	*rchip = chip;	return 0;}static struct snd_pcm_ops snd_ad1816a_playback_ops = {	.open =		snd_ad1816a_playback_open,	.close =	snd_ad1816a_playback_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_ad1816a_hw_params,	.hw_free =	snd_ad1816a_hw_free,	.prepare =	snd_ad1816a_playback_prepare,	.trigger =	snd_ad1816a_playback_trigger,	.pointer =	snd_ad1816a_playback_pointer,};static struct snd_pcm_ops snd_ad1816a_capture_ops = {

⌨️ 快捷键说明

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