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

📄 nm256.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	runtime->rate = samplerates[rate_index];	switch (substream->stream) {	case SNDRV_PCM_STREAM_PLAYBACK:		snd_nm256_load_coefficient(chip, 0, rate_index); /* 0 = playback */		snd_nm256_writeb(chip,				 NM_PLAYBACK_REG_OFFSET + NM_RATE_REG_OFFSET,				 ratebits);		break;	case SNDRV_PCM_STREAM_CAPTURE:		snd_nm256_load_coefficient(chip, 1, rate_index); /* 1 = record */		snd_nm256_writeb(chip,				 NM_RECORD_REG_OFFSET + NM_RATE_REG_OFFSET,				 ratebits);		break;	}}/* acquire interrupt */static int snd_nm256_acquire_irq(struct nm256 *chip){	mutex_lock(&chip->irq_mutex);	if (chip->irq < 0) {		if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ,				chip->card->driver, chip)) {			snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);			mutex_unlock(&chip->irq_mutex);			return -EBUSY;		}		chip->irq = chip->pci->irq;	}	chip->irq_acks++;	mutex_unlock(&chip->irq_mutex);	return 0;}/* release interrupt */static void snd_nm256_release_irq(struct nm256 *chip){	mutex_lock(&chip->irq_mutex);	if (chip->irq_acks > 0)		chip->irq_acks--;	if (chip->irq_acks == 0 && chip->irq >= 0) {		free_irq(chip->irq, chip);		chip->irq = -1;	}	mutex_unlock(&chip->irq_mutex);}/* * start / stop *//* update the watermark (current period) */static void snd_nm256_pcm_mark(struct nm256 *chip, struct nm256_stream *s, int reg){	s->cur_period++;	s->cur_period %= s->periods;	snd_nm256_writel(chip, reg, s->buf + s->cur_period * s->period_size);}#define snd_nm256_playback_mark(chip, s) snd_nm256_pcm_mark(chip, s, NM_PBUFFER_WMARK)#define snd_nm256_capture_mark(chip, s)  snd_nm256_pcm_mark(chip, s, NM_RBUFFER_WMARK)static voidsnd_nm256_playback_start(struct nm256 *chip, struct nm256_stream *s,			 struct snd_pcm_substream *substream){	/* program buffer pointers */	snd_nm256_writel(chip, NM_PBUFFER_START, s->buf);	snd_nm256_writel(chip, NM_PBUFFER_END, s->buf + s->dma_size - (1 << s->shift));	snd_nm256_writel(chip, NM_PBUFFER_CURRP, s->buf);	snd_nm256_playback_mark(chip, s);	/* Enable playback engine and interrupts. */	snd_nm256_writeb(chip, NM_PLAYBACK_ENABLE_REG,			 NM_PLAYBACK_ENABLE_FLAG | NM_PLAYBACK_FREERUN);	/* Enable both channels. */	snd_nm256_writew(chip, NM_AUDIO_MUTE_REG, 0x0);}static voidsnd_nm256_capture_start(struct nm256 *chip, struct nm256_stream *s,			struct snd_pcm_substream *substream){	/* program buffer pointers */	snd_nm256_writel(chip, NM_RBUFFER_START, s->buf);	snd_nm256_writel(chip, NM_RBUFFER_END, s->buf + s->dma_size);	snd_nm256_writel(chip, NM_RBUFFER_CURRP, s->buf);	snd_nm256_capture_mark(chip, s);	/* Enable playback engine and interrupts. */	snd_nm256_writeb(chip, NM_RECORD_ENABLE_REG,			 NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN);}/* Stop the play engine. */static voidsnd_nm256_playback_stop(struct nm256 *chip){	/* Shut off sound from both channels. */	snd_nm256_writew(chip, NM_AUDIO_MUTE_REG,			 NM_AUDIO_MUTE_LEFT | NM_AUDIO_MUTE_RIGHT);	/* Disable play engine. */	snd_nm256_writeb(chip, NM_PLAYBACK_ENABLE_REG, 0);}static voidsnd_nm256_capture_stop(struct nm256 *chip){	/* Disable recording engine. */	snd_nm256_writeb(chip, NM_RECORD_ENABLE_REG, 0);}static intsnd_nm256_playback_trigger(struct snd_pcm_substream *substream, int cmd){	struct nm256 *chip = snd_pcm_substream_chip(substream);	struct nm256_stream *s = substream->runtime->private_data;	int err = 0;	snd_assert(s != NULL, return -ENXIO);	spin_lock(&chip->reg_lock);	switch (cmd) {	case SNDRV_PCM_TRIGGER_RESUME:		s->suspended = 0;		/* fallthru */	case SNDRV_PCM_TRIGGER_START:		if (! s->running) {			snd_nm256_playback_start(chip, s, substream);			s->running = 1;		}		break;	case SNDRV_PCM_TRIGGER_SUSPEND:		s->suspended = 1;		/* fallthru */	case SNDRV_PCM_TRIGGER_STOP:		if (s->running) {			snd_nm256_playback_stop(chip);			s->running = 0;		}		break;	default:		err = -EINVAL;		break;	}	spin_unlock(&chip->reg_lock);	return err;}static intsnd_nm256_capture_trigger(struct snd_pcm_substream *substream, int cmd){	struct nm256 *chip = snd_pcm_substream_chip(substream);	struct nm256_stream *s = substream->runtime->private_data;	int err = 0;	snd_assert(s != NULL, return -ENXIO);	spin_lock(&chip->reg_lock);	switch (cmd) {	case SNDRV_PCM_TRIGGER_START:	case SNDRV_PCM_TRIGGER_RESUME:		if (! s->running) {			snd_nm256_capture_start(chip, s, substream);			s->running = 1;		}		break;	case SNDRV_PCM_TRIGGER_STOP:	case SNDRV_PCM_TRIGGER_SUSPEND:		if (s->running) {			snd_nm256_capture_stop(chip);			s->running = 0;		}		break;	default:		err = -EINVAL;		break;	}	spin_unlock(&chip->reg_lock);	return err;}/* * prepare playback/capture channel */static int snd_nm256_pcm_prepare(struct snd_pcm_substream *substream){	struct nm256 *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	struct nm256_stream *s = runtime->private_data;	snd_assert(s, return -ENXIO);	s->dma_size = frames_to_bytes(runtime, substream->runtime->buffer_size);	s->period_size = frames_to_bytes(runtime, substream->runtime->period_size);	s->periods = substream->runtime->periods;	s->cur_period = 0;	spin_lock_irq(&chip->reg_lock);	s->running = 0;	snd_nm256_set_format(chip, s, substream);	spin_unlock_irq(&chip->reg_lock);	return 0;}/* * get the current pointer */static snd_pcm_uframes_tsnd_nm256_playback_pointer(struct snd_pcm_substream *substream){	struct nm256 *chip = snd_pcm_substream_chip(substream);	struct nm256_stream *s = substream->runtime->private_data;	unsigned long curp;	snd_assert(s, return 0);	curp = snd_nm256_readl(chip, NM_PBUFFER_CURRP) - (unsigned long)s->buf;	curp %= s->dma_size;	return bytes_to_frames(substream->runtime, curp);}static snd_pcm_uframes_tsnd_nm256_capture_pointer(struct snd_pcm_substream *substream){	struct nm256 *chip = snd_pcm_substream_chip(substream);	struct nm256_stream *s = substream->runtime->private_data;	unsigned long curp;	snd_assert(s != NULL, return 0);	curp = snd_nm256_readl(chip, NM_RBUFFER_CURRP) - (unsigned long)s->buf;	curp %= s->dma_size;		return bytes_to_frames(substream->runtime, curp);}/* Remapped I/O space can be accessible as pointer on i386 *//* This might be changed in the future */#ifndef __i386__/* * silence / copy for playback */static intsnd_nm256_playback_silence(struct snd_pcm_substream *substream,			   int channel, /* not used (interleaved data) */			   snd_pcm_uframes_t pos,			   snd_pcm_uframes_t count){	struct snd_pcm_runtime *runtime = substream->runtime;	struct nm256_stream *s = runtime->private_data;	count = frames_to_bytes(runtime, count);	pos = frames_to_bytes(runtime, pos);	memset_io(s->bufptr + pos, 0, count);	return 0;}static intsnd_nm256_playback_copy(struct snd_pcm_substream *substream,			int channel, /* not used (interleaved data) */			snd_pcm_uframes_t pos,			void __user *src,			snd_pcm_uframes_t count){	struct snd_pcm_runtime *runtime = substream->runtime;	struct nm256_stream *s = runtime->private_data;	count = frames_to_bytes(runtime, count);	pos = frames_to_bytes(runtime, pos);	if (copy_from_user_toio(s->bufptr + pos, src, count))		return -EFAULT;	return 0;}/* * copy to user */static intsnd_nm256_capture_copy(struct snd_pcm_substream *substream,		       int channel, /* not used (interleaved data) */		       snd_pcm_uframes_t pos,		       void __user *dst,		       snd_pcm_uframes_t count){	struct snd_pcm_runtime *runtime = substream->runtime;	struct nm256_stream *s = runtime->private_data;	count = frames_to_bytes(runtime, count);	pos = frames_to_bytes(runtime, pos);	if (copy_to_user_fromio(dst, s->bufptr + pos, count))		return -EFAULT;	return 0;}#endif /* !__i386__ *//* * update playback/capture watermarks *//* spinlock held! */static voidsnd_nm256_playback_update(struct nm256 *chip){	struct nm256_stream *s;	s = &chip->streams[SNDRV_PCM_STREAM_PLAYBACK];	if (s->running && s->substream) {		spin_unlock(&chip->reg_lock);		snd_pcm_period_elapsed(s->substream);		spin_lock(&chip->reg_lock);		snd_nm256_playback_mark(chip, s);	}}/* spinlock held! */static voidsnd_nm256_capture_update(struct nm256 *chip){	struct nm256_stream *s;	s = &chip->streams[SNDRV_PCM_STREAM_CAPTURE];	if (s->running && s->substream) {		spin_unlock(&chip->reg_lock);		snd_pcm_period_elapsed(s->substream);		spin_lock(&chip->reg_lock);		snd_nm256_capture_mark(chip, s);	}}/* * hardware info */static struct snd_pcm_hardware snd_nm256_playback ={	.info =			SNDRV_PCM_INFO_MMAP_IOMEM |SNDRV_PCM_INFO_MMAP_VALID |				SNDRV_PCM_INFO_INTERLEAVED |				/*SNDRV_PCM_INFO_PAUSE |*/				SNDRV_PCM_INFO_RESUME,	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_KNOT/*24k*/ | SNDRV_PCM_RATE_8000_48000,	.rate_min =		8000,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.periods_min =		2,	.periods_max =		1024,	.buffer_bytes_max =	128 * 1024,	.period_bytes_min =	256,	.period_bytes_max =	128 * 1024,};static struct snd_pcm_hardware snd_nm256_capture ={	.info =			SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID |				SNDRV_PCM_INFO_INTERLEAVED |				/*SNDRV_PCM_INFO_PAUSE |*/				SNDRV_PCM_INFO_RESUME,	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_KNOT/*24k*/ | SNDRV_PCM_RATE_8000_48000,	.rate_min =		8000,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.periods_min =		2,	.periods_max =		1024,	.buffer_bytes_max =	128 * 1024,	.period_bytes_min =	256,	.period_bytes_max =	128 * 1024,};/* set dma transfer size */static int snd_nm256_pcm_hw_params(struct snd_pcm_substream *substream,				   struct snd_pcm_hw_params *hw_params){	/* area and addr are already set and unchanged */	substream->runtime->dma_bytes = params_buffer_bytes(hw_params);	return 0;}/* * open */static void snd_nm256_setup_stream(struct nm256 *chip, struct nm256_stream *s,				   struct snd_pcm_substream *substream,				   struct snd_pcm_hardware *hw_ptr){	struct snd_pcm_runtime *runtime = substream->runtime;	s->running = 0;	runtime->hw = *hw_ptr;	runtime->hw.buffer_bytes_max = s->bufsize;	runtime->hw.period_bytes_max = s->bufsize / 2;	runtime->dma_area = (void __force *) s->bufptr;	runtime->dma_addr = s->bufptr_addr;	runtime->dma_bytes = s->bufsize;	runtime->private_data = s;	s->substream = substream;	snd_pcm_set_sync(substream);	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				   &constraints_rates);}static intsnd_nm256_playback_open(struct snd_pcm_substream *substream){	struct nm256 *chip = snd_pcm_substream_chip(substream);	if (snd_nm256_acquire_irq(chip) < 0)		return -EBUSY;	snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK],			       substream, &snd_nm256_playback);	return 0;}static intsnd_nm256_capture_open(struct snd_pcm_substream *substream){	struct nm256 *chip = snd_pcm_substream_chip(substream);	if (snd_nm256_acquire_irq(chip) < 0)		return -EBUSY;	snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_CAPTURE],			       substream, &snd_nm256_capture);	return 0;}/* * close - we don't have to do special.. */static intsnd_nm256_playback_close(struct snd_pcm_substream *substream){	struct nm256 *chip = snd_pcm_substream_chip(substream);	snd_nm256_release_irq(chip);	return 0;}

⌨️ 快捷键说明

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