static void snd_nm256_capture_start(nm256_t *chip, nm256_stream_t *s, snd_pcm_substream_t *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); }
static void snd_nm256_load_one_coefficient(struct nm256 *chip, int stream, u32 port, int which) { u32 coeff_buf = chip->coeff_buf[stream]; u16 offset = snd_nm256_get_start_offset(which); u16 size = coefficient_sizes[which]; snd_nm256_write_buffer(chip, coefficients + offset, coeff_buf, size); snd_nm256_writel(chip, port, coeff_buf); /* ??? Record seems to behave differently than playback. */ if (stream == SNDRV_PCM_STREAM_PLAYBACK) size--; snd_nm256_writel(chip, port + 4, coeff_buf + size); }
static void snd_nm256_capture_start(struct nm256 *chip, struct nm256_stream *s, struct snd_pcm_substream *substream) { 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); snd_nm256_writeb(chip, NM_RECORD_ENABLE_REG, NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN); }
static void snd_nm256_playback_start(nm256_t *chip, nm256_stream_t *s, snd_pcm_substream_t *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 void snd_nm256_playback_start(struct nm256 *chip, struct nm256_stream *s, struct snd_pcm_substream *substream) { 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); snd_nm256_writeb(chip, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_ENABLE_FLAG | NM_PLAYBACK_FREERUN); snd_nm256_writew(chip, NM_AUDIO_MUTE_REG, 0x0); }
static void snd_nm256_load_coefficient(struct nm256 *chip, int stream, int number) { /* The enable register for the specified engine. */ u32 poffset = (stream == SNDRV_PCM_STREAM_CAPTURE ? NM_RECORD_ENABLE_REG : NM_PLAYBACK_ENABLE_REG); u32 addr = NM_COEFF_START_OFFSET; addr += (stream == SNDRV_PCM_STREAM_CAPTURE ? NM_RECORD_REG_OFFSET : NM_PLAYBACK_REG_OFFSET); if (snd_nm256_readb(chip, poffset) & 1) { snd_printd("NM256: Engine was enabled while loading coefficients!\n"); return; } /* The recording engine uses coefficient values 8-15. */ number &= 7; if (stream == SNDRV_PCM_STREAM_CAPTURE) number += 8; if (! chip->use_cache) { snd_nm256_load_one_coefficient(chip, stream, addr, number); return; } if (! chip->coeffs_current) { snd_nm256_write_buffer(chip, coefficients, chip->all_coeff_buf, NM_TOTAL_COEFF_COUNT * 4); chip->coeffs_current = 1; } else { u32 base = chip->all_coeff_buf; u32 offset = snd_nm256_get_start_offset(number); u32 end_offset = offset + coefficient_sizes[number]; snd_nm256_writel(chip, addr, base + offset); if (stream == SNDRV_PCM_STREAM_PLAYBACK) end_offset--; snd_nm256_writel(chip, addr + 4, base + end_offset); } }
/* 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); }