本文整理汇总了C++中snd_pcm_period_elapsed函数的典型用法代码示例。如果您正苦于以下问题:C++ snd_pcm_period_elapsed函数的具体用法?C++ snd_pcm_period_elapsed怎么用?C++ snd_pcm_period_elapsed使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了snd_pcm_period_elapsed函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: lpass_platform_lpaif_irq
static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data)
{
struct snd_pcm_substream *substream = data;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct lpass_data *drvdata =
snd_soc_platform_get_drvdata(soc_runtime->platform);
unsigned int interrupts;
irqreturn_t ret = IRQ_NONE;
int rv;
rv = regmap_read(drvdata->lpaif_map,
LPAIF_IRQSTAT_REG(LPAIF_IRQ_PORT_HOST), &interrupts);
if (rv) {
dev_err(soc_runtime->dev, "%s() error reading from irqstat reg: %d\n",
__func__, rv);
return IRQ_NONE;
}
interrupts &= LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S);
if (interrupts & LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S)) {
rv = regmap_write(drvdata->lpaif_map,
LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S));
if (rv) {
dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
__func__, rv);
return IRQ_NONE;
}
snd_pcm_period_elapsed(substream);
ret = IRQ_HANDLED;
}
if (interrupts & LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S)) {
rv = regmap_write(drvdata->lpaif_map,
LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S));
if (rv) {
dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
__func__, rv);
return IRQ_NONE;
}
dev_warn(soc_runtime->dev, "%s() xrun warning\n", __func__);
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
ret = IRQ_HANDLED;
}
if (interrupts & LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S)) {
rv = regmap_write(drvdata->lpaif_map,
LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S));
if (rv) {
dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
__func__, rv);
return IRQ_NONE;
}
dev_err(soc_runtime->dev, "%s() bus access error\n", __func__);
snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
ret = IRQ_HANDLED;
}
return ret;
}
示例2: pcm_afe_process_rx_pkt
static void pcm_afe_process_rx_pkt(uint32_t opcode,
uint32_t token, uint32_t *payload,
void *priv)
{
struct pcm_afe_info *prtd = priv;
unsigned long dsp_flags;
struct snd_pcm_substream *substream = NULL;
struct snd_pcm_runtime *runtime = NULL;
uint16_t event;
if (prtd == NULL)
return;
substream = prtd->substream;
runtime = substream->runtime;
pr_debug("%s\n", __func__);
spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
switch (opcode) {
case AFE_EVENT_RT_PROXY_PORT_STATUS: {
event = (uint16_t)((0xFFFF0000 & payload[0]) >> 0x10);
switch (event) {
case AFE_EVENT_RTPORT_START: {
prtd->dsp_cnt = 0;
prtd->poll_time = ((unsigned long)((
snd_pcm_lib_period_bytes(prtd->substream)
* 1000 * 1000)/(runtime->rate
* runtime->channels * 2)));
hrtimer_start(&prtd->hrt,
ns_to_ktime(0),
HRTIMER_MODE_REL);
pr_debug("prtd->poll_time : %d", prtd->poll_time);
break;
}
case AFE_EVENT_RTPORT_STOP:
pr_debug("%s: event!=0\n", __func__);
prtd->start = 0;
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
break;
case AFE_EVENT_RTPORT_LOW_WM:
pr_debug("%s: Underrun\n", __func__);
break;
case AFE_EVENT_RTPORT_HI_WM:
pr_debug("%s: Overrun\n", __func__);
break;
default:
break;
}
break;
}
case APR_BASIC_RSP_RESULT: {
switch (payload[0]) {
case AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2:
pr_debug("Read done\n");
prtd->pcm_irq_pos += snd_pcm_lib_period_bytes
(prtd->substream);
snd_pcm_period_elapsed(prtd->substream);
break;
default:
break;
}
break;
}
default:
break;
}
spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
}
示例3: bcm947xx_i2s_isr
irqreturn_t bcm947xx_i2s_isr(int irq, void *devid)
{
uint32 intstatus, intmask;
uint32 intstatus_new = 0;
uint32 int_errmask = I2S_INT_DESCERR | I2S_INT_DATAERR | I2S_INT_DESC_PROTO_ERR |
I2S_INT_SPDIF_PAR_ERR;
struct snd_pcm *pcm = devid;
struct snd_soc_pcm_runtime *rtd = pcm->private_data;
bcm947xx_i2s_info_t *snd_bcm = rtd->dai->cpu_dai->private_data;
struct snd_pcm_substream *substream;
struct bcm947xx_runtime_data *brtd;
// DBG("%s enter\n", __FUNCTION__);
intstatus = R_REG(snd_bcm->osh, &snd_bcm->regs->intstatus);
if (BCM947XX_PCM_DEBUG_ON) {
intmask = R_REG(snd_bcm->osh, &snd_bcm->regs->intmask);
} else {
(void)intmask;
}
// DBG("%s: intstatus 0x%x intmask 0x%x\n", __FUNCTION__, intstatus, intmask);
/* Playback. */
substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
if ((brtd = bcm947xx_pcm_brtd_from_running_substream(substream))) {
if (intstatus & I2S_INT_XMT_INT) {
/* reclaim descriptors that have been TX'd */
spin_lock(&brtd->lock);
dma_getnexttxp(snd_bcm->di[0], HNDDMA_RANGE_TRANSMITTED);
spin_unlock(&brtd->lock);
/* clear this bit by writing a "1" back, we've serviced this */
intstatus_new |= I2S_INT_XMT_INT;
snd_pcm_period_elapsed(substream);
spin_lock(&brtd->lock);
snd_BUG_ON(0 == brtd->dma_loaded);
brtd->dma_loaded--;
spin_unlock(&brtd->lock);
}
if (intstatus & I2S_INT_XMTFIFO_UFLOW) {
intstatus_new |= I2S_INT_XMTFIFO_UFLOW;
bcm947xx_dma_abort(substream);
}
}
/* Capture. */
substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
if ((brtd = bcm947xx_pcm_brtd_from_running_substream(substream))) {
if (intstatus & I2S_INT_RCV_INT) {
spin_lock(&brtd->lock);
dma_getnextrxp(snd_bcm->di[0], false);
spin_unlock(&brtd->lock);
/* clear this bit by writing a "1" back, we've serviced this */
intstatus_new |= I2S_INT_RCV_INT;
snd_pcm_period_elapsed(substream);
spin_lock(&brtd->lock);
snd_BUG_ON(0 == brtd->dma_loaded);
brtd->dma_loaded--;
spin_unlock(&brtd->lock);
}
if (intstatus & I2S_INT_RCVFIFO_OFLOW) {
intstatus_new |= I2S_INT_RCVFIFO_OFLOW;
bcm947xx_dma_abort(substream);
}
}
/* Common.*/
if (intstatus & int_errmask) {
DBG("\n\n%s: Turning off all interrupts due to error\n", __FUNCTION__);
DBG("%s: intstatus 0x%x intmask 0x%x\n", __FUNCTION__, intstatus, intmask);
/* something bad happened, turn off all interrupts */
W_REG(snd_bcm->osh, &snd_bcm->regs->intmask, 0);
}
/* Acknowledge interrupts. */
W_REG(snd_bcm->osh, &snd_bcm->regs->intstatus, intstatus_new);
// DBG("%s exit\n", __FUNCTION__);
return IRQ_RETVAL(intstatus);
}
示例4: atmel_ac97c_dma_playback_period_done
/* This function is called by the DMA driver. */
static void atmel_ac97c_dma_playback_period_done(void *arg)
{
struct atmel_ac97c *chip = arg;
snd_pcm_period_elapsed(chip->playback_substream);
}
示例5: pcm_afe_process_rx_pkt
static void pcm_afe_process_rx_pkt(uint32_t opcode,
uint32_t token, uint32_t *payload,
void *priv)
{
struct pcm_afe_info *prtd = priv;
unsigned long dsp_flags;
struct snd_pcm_substream *substream = NULL;
struct snd_pcm_runtime *runtime = NULL;
uint16_t event;
uint64_t period_bytes;
uint64_t bytes_one_sec;
if (prtd == NULL)
return;
substream = prtd->substream;
runtime = substream->runtime;
pr_debug("%s\n", __func__);
spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
switch (opcode) {
case AFE_EVENT_RT_PROXY_PORT_STATUS: {
event = (uint16_t)((0xFFFF0000 & payload[0]) >> 0x10);
switch (event) {
case AFE_EVENT_RTPORT_START: {
prtd->dsp_cnt = 0;
/* Calculate poll time. Split steps to avoid overflow.
* Poll time-time corresponding to one period in bytes.
* (Samplerate * channelcount * format)=bytes in 1 sec.
* Poll time = (period bytes / bytes in one sec) *
* 1000000 micro seconds.
* Multiplication by 1000000 is done in two steps to
* keep the accuracy of poll time.
*/
period_bytes = ((uint64_t)(
(snd_pcm_lib_period_bytes(prtd->substream)) *
1000));
bytes_one_sec = (runtime->rate * runtime->channels * 2);
bytes_one_sec = div_u64(bytes_one_sec , 1000);
prtd->poll_time =
div_u64(period_bytes, bytes_one_sec);
pr_debug("prtd->poll_time : %d\n", prtd->poll_time);
break;
}
case AFE_EVENT_RTPORT_STOP:
pr_debug("%s: event!=0\n", __func__);
prtd->start = 0;
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
break;
case AFE_EVENT_RTPORT_LOW_WM:
pr_debug("%s: Underrun\n", __func__);
break;
case AFE_EVENT_RTPORT_HI_WM:
pr_debug("%s: Overrun\n", __func__);
break;
default:
break;
}
break;
}
case APR_BASIC_RSP_RESULT: {
switch (payload[0]) {
case AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2:
pr_debug("Read done\n");
prtd->pcm_irq_pos += snd_pcm_lib_period_bytes
(prtd->substream);
snd_pcm_period_elapsed(prtd->substream);
break;
default:
break;
}
break;
}
default:
break;
}
spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
}
示例6: saudio_data_transfer_process
static int saudio_data_transfer_process(struct saudio_stream *stream,
struct saudio_msg *msg)
{
struct snd_pcm_runtime *runtime = stream->substream->runtime;
struct sblock blk = { 0 };
int32_t result = 0;
struct cmd_common *common = NULL;
int32_t elapsed_blks = 0;
int32_t periods_avail;
int32_t periods_tosend;
int32_t cur_blk_count = 0;
cur_blk_count = sblock_get_free_count(stream->dst, stream->channel);
elapsed_blks =
(cur_blk_count + stream->last_getblk_count - stream->blk_count) -
stream->last_elapsed_count;
if (stream->stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
periods_avail = snd_pcm_playback_avail(runtime) /
runtime->period_size;
} else {
periods_avail = snd_pcm_capture_avail(runtime) /
runtime->period_size;
}
periods_tosend = stream->periods_avail - periods_avail;
if (periods_tosend > 0) {
stream->periods_tosend += periods_tosend;
}
if (stream->periods_tosend) {
while (stream->periods_tosend) {
result =
sblock_get(stream->dst, stream->channel, &blk, 0);
if (result) {
break;
}
stream->last_getblk_count++;
common = (struct cmd_common *)blk.addr;
blk.length =
frames_to_bytes(runtime, runtime->period_size);
common->command = SAUDIO_DATA_PCM;
common->sub_cmd = stream->stream_id;
common->reserved1 =
stream->substream->dma_buffer.addr +
stream->period * blk.length;
sblock_send(stream->dst, stream->channel, &blk);
stream->periods_tosend--;
stream->period++;
stream->period = stream->period % runtime->periods;
}
} else {
pr_debug("saudio.c: saudio no data to send ");
if (sblock_get_free_count(stream->dst, stream->channel) ==
SAUDIO_STREAM_BLOCK_COUNT) {
pr_debug
("saudio.c: saudio no data to send and is empty ");
result =
sblock_get(stream->dst, stream->channel, &blk, 0);
if (result) {
ETRACE("saudio.c: no data and no blk\n");
} else {
stream->last_getblk_count++;
common = (struct cmd_common *)blk.addr;
common->command = SAUDIO_DATA_SILENCE;
common->sub_cmd = stream->stream_id;
sblock_send(stream->dst, stream->channel, &blk);
stream->last_elapsed_count++;
schedule_timeout_interruptible(msecs_to_jiffies(5));
}
}
}
while (elapsed_blks > 0) {
elapsed_blks--;
stream->hwptr_done++;
stream->hwptr_done %= runtime->periods;
snd_pcm_period_elapsed(stream->substream);
stream->periods_avail++;
stream->last_elapsed_count++;
}
return 0;
}
示例7: ivtv_alsa_announce_pcm_data
static void ivtv_alsa_announce_pcm_data(struct snd_ivtv_card *itvsc,
u8 *pcm_data,
size_t num_bytes)
{
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
unsigned int oldptr;
unsigned int stride;
int period_elapsed = 0;
int length;
dprintk("ivtv alsa announce ptr=%p data=%p num_bytes=%zu\n", itvsc,
pcm_data, num_bytes);
substream = itvsc->capture_pcm_substream;
if (substream == NULL) {
dprintk("substream was NULL\n");
return;
}
runtime = substream->runtime;
if (runtime == NULL) {
dprintk("runtime was NULL\n");
return;
}
stride = runtime->frame_bits >> 3;
if (stride == 0) {
dprintk("stride is zero\n");
return;
}
length = num_bytes / stride;
if (length == 0) {
dprintk("%s: length was zero\n", __func__);
return;
}
if (runtime->dma_area == NULL) {
dprintk("dma area was NULL - ignoring\n");
return;
}
oldptr = itvsc->hwptr_done_capture;
if (oldptr + length >= runtime->buffer_size) {
unsigned int cnt =
runtime->buffer_size - oldptr;
memcpy(runtime->dma_area + oldptr * stride, pcm_data,
cnt * stride);
memcpy(runtime->dma_area, pcm_data + cnt * stride,
length * stride - cnt * stride);
} else {
memcpy(runtime->dma_area + oldptr * stride, pcm_data,
length * stride);
}
snd_pcm_stream_lock(substream);
itvsc->hwptr_done_capture += length;
if (itvsc->hwptr_done_capture >=
runtime->buffer_size)
itvsc->hwptr_done_capture -=
runtime->buffer_size;
itvsc->capture_transfer_done += length;
if (itvsc->capture_transfer_done >=
runtime->period_size) {
itvsc->capture_transfer_done -=
runtime->period_size;
period_elapsed = 1;
}
snd_pcm_stream_unlock(substream);
if (period_elapsed)
snd_pcm_period_elapsed(substream);
}
示例8: snd_msnd_eval_dsp_msg
static void snd_msnd_eval_dsp_msg(struct snd_msnd *chip, u16 wMessage)
{
switch (HIBYTE(wMessage)) {
case HIMT_PLAY_DONE: {
if (chip->banksPlayed < 3)
snd_printdd("%08X: HIMT_PLAY_DONE: %i\n",
(unsigned)jiffies, LOBYTE(wMessage));
if (chip->last_playbank == LOBYTE(wMessage)) {
snd_printdd("chip.last_playbank == LOBYTE(wMessage)\n");
break;
}
chip->banksPlayed++;
if (test_bit(F_WRITING, &chip->flags))
snd_msnd_DAPQ(chip, 0);
chip->last_playbank = LOBYTE(wMessage);
chip->playDMAPos += chip->play_period_bytes;
if (chip->playDMAPos > chip->playLimit)
chip->playDMAPos = 0;
snd_pcm_period_elapsed(chip->playback_substream);
break;
}
case HIMT_RECORD_DONE:
if (chip->last_recbank == LOBYTE(wMessage))
break;
chip->last_recbank = LOBYTE(wMessage);
chip->captureDMAPos += chip->capturePeriodBytes;
if (chip->captureDMAPos > (chip->captureLimit))
chip->captureDMAPos = 0;
if (test_bit(F_READING, &chip->flags))
snd_msnd_DARQ(chip, chip->last_recbank);
snd_pcm_period_elapsed(chip->capture_substream);
break;
case HIMT_DSP:
switch (LOBYTE(wMessage)) {
#ifndef MSND_CLASSIC
case HIDSP_PLAY_UNDER:
#endif
case HIDSP_INT_PLAY_UNDER:
snd_printd(KERN_WARNING LOGNAME ": Play underflow %i\n",
chip->banksPlayed);
if (chip->banksPlayed > 2)
clear_bit(F_WRITING, &chip->flags);
break;
case HIDSP_INT_RECORD_OVER:
snd_printd(KERN_WARNING LOGNAME ": Record overflow\n");
clear_bit(F_READING, &chip->flags);
break;
default:
snd_printd(KERN_WARNING LOGNAME
": DSP message %d 0x%02x\n",
LOBYTE(wMessage), LOBYTE(wMessage));
break;
}
break;
case HIMT_MIDI_IN_UCHAR:
if (chip->msndmidi_mpu)
snd_msndmidi_input_read(chip->msndmidi_mpu);
break;
default:
snd_printd(KERN_WARNING LOGNAME ": HIMT message %d 0x%02x\n",
HIBYTE(wMessage), HIBYTE(wMessage));
break;
}
}
示例9: snd_atiixp_update_dma
/*
* the period ack. update the substream.
*/
static void snd_atiixp_update_dma(struct atiixp *chip, struct atiixp_dma *dma)
{
if (! dma->substream || ! dma->running)
return;
snd_pcm_period_elapsed(dma->substream);
}
示例10: vaudio_intr_data
static void
vaudio_intr_data (void* cookie, NkXIrq xirq)
{
struct vaudio_stream* s = (struct vaudio_stream*) cookie;
NkDevRing* ring = s->ring;
nku32_f oresp = s->resp;
const nku32_f mask = ring->imask;
const nku32_f nresp = ring->iresp;
bool trigger = 0;
#if VAUDIO_PROC_SYNC
if (vaudio_sync_force_close &&
s->stream->pcm->device == 0 &&
s->stream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) {
while (vaudio_send_data(s) >= 0);
// memset(s->stream->dma_buffer.area, 0, NK_VAUDIO_MAX_RING_SIZE);
return;
}
#endif
(void) xirq;
if (s->active) {
struct snd_pcm_runtime* runtime = s->stream->runtime;
int periods_avail;
int periods_tosend;
if (s->stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
periods_avail = snd_pcm_playback_avail(runtime) /
runtime->period_size;
} else {
periods_avail = snd_pcm_capture_avail(runtime) /
runtime->period_size;
}
DTRACE ("%d %d %d\n",
s->periods_avail, periods_avail, s->periods_tosend);
periods_tosend = s->periods_avail - periods_avail;
if (periods_tosend > 0) {
s->periods_tosend += periods_tosend;
}
s->periods_avail = periods_avail;
while (s->periods_tosend) {
const int res = vaudio_send_data(s);
if (res < 0) break;
if (res == 1) trigger = 1;
s->periods_tosend--;
}
}
while (oresp != nresp) {
NkRingDesc* desc = s->rbase + (oresp & mask);
if (desc->status == (nku32_f) NK_VAUDIO_STATUS_ERROR) {
snd_pcm_stop(s->stream, SNDRV_PCM_STATE_XRUN);
} else {
if (s->active) {
struct snd_pcm_runtime* runtime = s->stream->runtime;
s->hwptr_done++;
s->hwptr_done %= runtime->periods;
snd_pcm_period_elapsed(s->stream);
s->periods_avail++;
}
}
oresp++;
}
s->resp = oresp;
if (trigger) {
nkops.nk_xirq_trigger(ring->cxirq, s->vaudio->vlink->s_id);
}
}
示例11: atmel_ac97c_dma_capture_period_done
static void atmel_ac97c_dma_capture_period_done(void *arg)
{
struct atmel_ac97c *chip = arg;
snd_pcm_period_elapsed(chip->capture_substream);
}
示例12: atmel_abdac_dma_period_done
/* This function is called by the DMA driver. */
static void atmel_abdac_dma_period_done(void *arg)
{
struct atmel_abdac *dac = arg;
snd_pcm_period_elapsed(dac->substream);
}
示例13: atmel_ac97c_interrupt
static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
{
struct atmel_ac97c *chip = (struct atmel_ac97c *)dev;
irqreturn_t retval = IRQ_NONE;
u32 sr = ac97c_readl(chip, SR);
u32 casr = ac97c_readl(chip, CASR);
u32 cosr = ac97c_readl(chip, COSR);
u32 camr = ac97c_readl(chip, CAMR);
if (sr & AC97C_SR_CAEVT) {
struct snd_pcm_runtime *runtime;
int offset, next_period, block_size;
dev_dbg(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
casr & AC97C_CSR_OVRUN ? " OVRUN" : "",
casr & AC97C_CSR_RXRDY ? " RXRDY" : "",
casr & AC97C_CSR_UNRUN ? " UNRUN" : "",
casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
casr & AC97C_CSR_TXRDY ? " TXRDY" : "",
!casr ? " NONE" : "");
if (!cpu_is_at32ap7000()) {
if ((casr & camr) & AC97C_CSR_ENDTX) {
runtime = chip->playback_substream->runtime;
block_size = frames_to_bytes(runtime,
runtime->period_size);
chip->playback_period++;
if (chip->playback_period == runtime->periods)
chip->playback_period = 0;
next_period = chip->playback_period + 1;
if (next_period == runtime->periods)
next_period = 0;
offset = block_size * next_period;
writel(runtime->dma_addr + offset,
chip->regs + ATMEL_PDC_TNPR);
writel(block_size / 2,
chip->regs + ATMEL_PDC_TNCR);
snd_pcm_period_elapsed(
chip->playback_substream);
}
if ((casr & camr) & AC97C_CSR_ENDRX) {
runtime = chip->capture_substream->runtime;
block_size = frames_to_bytes(runtime,
runtime->period_size);
chip->capture_period++;
if (chip->capture_period == runtime->periods)
chip->capture_period = 0;
next_period = chip->capture_period + 1;
if (next_period == runtime->periods)
next_period = 0;
offset = block_size * next_period;
writel(runtime->dma_addr + offset,
chip->regs + ATMEL_PDC_RNPR);
writel(block_size / 2,
chip->regs + ATMEL_PDC_RNCR);
snd_pcm_period_elapsed(chip->capture_substream);
}
}
retval = IRQ_HANDLED;
}
if (sr & AC97C_SR_COEVT) {
dev_info(&chip->pdev->dev, "codec channel event%s%s%s%s%s\n",
cosr & AC97C_CSR_OVRUN ? " OVRUN" : "",
cosr & AC97C_CSR_RXRDY ? " RXRDY" : "",
cosr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
cosr & AC97C_CSR_TXRDY ? " TXRDY" : "",
!cosr ? " NONE" : "");
retval = IRQ_HANDLED;
}
if (retval == IRQ_NONE) {
dev_err(&chip->pdev->dev, "spurious interrupt sr 0x%08x "
"casr 0x%08x cosr 0x%08x\n", sr, casr, cosr);
}
return retval;
}
示例14: intel_alsa_ifx_dma_capture_complete
/*
* intel_alsa_ifx_dma_capture_complete - End of capture callback
* called in DMA Complete Tasklet context
* This Callback has in charge of re-programming a new read request to
* Intel MID I2S Driver if the stream has not been Closed.
* It calls also the snd_pcm_period_elapsed if the stream is not
* PAUSED or SUSPENDED to inform ALSA Kernel that the Ring Buffer
* period has been received properly
*
* Input parameters
* @param : pointer to a structure
* Output parameters
* @ret_val : status
*/
int intel_alsa_ifx_dma_capture_complete(void *param)
{
struct intel_alsa_ssp_dma_buf *sb_rx;
struct intel_alsa_ifx_stream_info *str_info;
bool call_back = false;
bool reset_index = false;
WARN(!param, "ALSA IFX: ERROR param NULL\n");
if (!param)
return -EBUSY;
str_info = param;
sb_rx = &(str_info->dma_slot);
if (test_and_clear_bit(INTEL_ALSA_SSP_STREAM_RUNNING, &str_info->stream_status)) {
if (test_and_clear_bit(INTEL_ALSA_SSP_STREAM_DROPPED, &str_info->stream_status)) {
if (test_bit(INTEL_ALSA_SSP_STREAM_STARTED, &str_info->stream_status)) {
/*
* the stream has been dropped and
* restarted before the callback occurs
* in this case the we have to reprogram the requests
* to SSP driver and reset the stream's indexes
*/
call_back = true;
reset_index = true;
} else
call_back = false;
} else {
if (test_bit(INTEL_ALSA_SSP_STREAM_STARTED, &str_info->stream_status)) {
/*
* the stream is on going
*/
call_back = true;
} else {
WARN(1, "ALSA_IFX: FCT %s spurious"
"playback DMA complete 1 ?!\n",
__func__);
return -EBUSY;
}
}
} else {
WARN(1, "ALSA_IFX: FCT %s spurious playback DMA complete 2 ?!\n",
__func__);
return -EBUSY;
}
if (call_back == true) {
pr_debug("ALSA_IFX: playback (REQ=%d,CB=%d): PLAYBACK_DMA_REQ_COMPLETE\n",
sb_rx->period_req_index,
sb_rx->period_cb_index);
if (reset_index) {
sb_rx->period_cb_index = 0;
sb_rx->period_req_index = 0;
} else if (++(sb_rx->period_cb_index) >= sb_rx->period_index_max)
sb_rx->period_cb_index = 0;
/*
* Launch the next Playback request if no
* CLOSE has been requested
*/
intel_alsa_ifx_dma_capture_req(str_info);
/*
* Call the snd_pcm_period_elapsed to inform ALSA kernel
* that a ring buffer period has been played
*/
snd_pcm_period_elapsed(str_info->substream);
}
return 0;
} /* intel_alsa_ifx_dma_capture_complete */
示例15: aml_i2s_timer_callback
static void aml_i2s_timer_callback(unsigned long data)
{
struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
struct snd_pcm_runtime *runtime = substream->runtime;
struct aml_runtime_data *prtd = runtime->private_data;
audio_stream_t *s = &prtd->s;
unsigned int last_ptr, size = 0;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (s->active == 1) {
spin_lock(&s->lock);
if (s->device_type == AML_AUDIO_I2SOUT) {
last_ptr = read_i2s_rd_ptr();
} else {
last_ptr = read_iec958_rd_ptr();
}
if (last_ptr < s->last_ptr) {
size = runtime->dma_bytes + last_ptr - (s->last_ptr);
} else {
size = last_ptr - (s->last_ptr);
}
s->last_ptr = last_ptr;
s->size += bytes_to_frames(substream->runtime, size);
if (s->size >= runtime->period_size) {
s->size %= runtime->period_size;
spin_unlock(&s->lock);
snd_pcm_period_elapsed(substream);
spin_lock(&s->lock);
}
mod_timer(&prtd->timer, jiffies + 1);
spin_unlock(&s->lock);
} else {
mod_timer(&prtd->timer, jiffies + 1);
}
} else {
if (s->active == 1) {
spin_lock(&s->lock);
if (s->device_type == AML_AUDIO_I2SIN) {
last_ptr = audio_in_i2s_wr_ptr() ;
} else {
last_ptr = audio_in_spdif_wr_ptr();
}
if (last_ptr < s->last_ptr) {
size = runtime->dma_bytes + (last_ptr - (s->last_ptr)) / 2;
} else if (last_ptr == s->last_ptr) {
if (s->xrun_num++ > 100) {
printk(KERN_INFO "alsa capture long time no data, quit xrun!\n");
s->xrun_num = 0;
s->size = runtime->period_size;
}
} else {
size = (last_ptr - (s->last_ptr)) / 2;
}
s->last_ptr = last_ptr;
s->size += bytes_to_frames(substream->runtime, size);
if (s->size >= runtime->period_size) {
s->size %= runtime->period_size;
spin_unlock(&s->lock);
snd_pcm_period_elapsed(substream);
spin_lock(&s->lock);
}
mod_timer(&prtd->timer, jiffies + 1);
spin_unlock(&s->lock);
} else {
mod_timer(&prtd->timer, jiffies + 1);
}
}
}