/* * Capture cannot use ping-pong buffer since hw_ptr at IRQ may be * smaller than period_size due to AFE's internal buffer. * This easily leads to overrun when avail_min is period_size. * One more period can hold the possible unread buffer.
*/ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { int periods_max = mtk_afe_hardware->periods_max;
ret = snd_pcm_hw_constraint_minmax(runtime,
SNDRV_PCM_HW_PARAM_PERIODS,
3, periods_max); if (ret < 0) {
dev_err(afe->dev, "hw_constraint_minmax failed\n"); return ret;
}
}
ret = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0)
dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n");
/* dynamic allocate irq to memif */ if (memif->irq_usage < 0) { int irq_id = mtk_dynamic_irq_acquire(afe);
if (irq_id != afe->irqs_size) { /* link */
memif->irq_usage = irq_id;
} else {
dev_err(afe->dev, "%s() error: no more asys irq\n",
__func__);
ret = -EBUSY;
}
} return ret;
}
EXPORT_SYMBOL_GPL(mtk_afe_fe_startup);
/* set addr */
ret = mtk_memif_set_addr(afe, id,
substream->runtime->dma_area,
substream->runtime->dma_addr,
substream->runtime->dma_bytes); if (ret) {
dev_err(afe->dev, "%s(), error, id %d, set addr, ret %d\n",
__func__, id, ret); return ret;
}
/* set channel */
ret = mtk_memif_set_channel(afe, id, channels); if (ret) {
dev_err(afe->dev, "%s(), error, id %d, set channel %d, ret %d\n",
__func__, id, channels, ret); return ret;
}
/* set rate */
ret = mtk_memif_set_rate_substream(substream, id, rate); if (ret) {
dev_err(afe->dev, "%s(), error, id %d, set rate %d, ret %d\n",
__func__, id, rate, ret); return ret;
}
/* set format */
ret = mtk_memif_set_format(afe, id, format); if (ret) {
dev_err(afe->dev, "%s(), error, id %d, set format %d, ret %d\n",
__func__, id, format, ret); return ret;
}
switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME:
ret = mtk_memif_set_enable(afe, id); if (ret) {
dev_err(afe->dev, "%s(), error, id %d, memif enable, ret %d\n",
__func__, id, ret); return ret;
}
/* set irq counter */
mtk_regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
irq_data->irq_cnt_maskbit, counter,
irq_data->irq_cnt_shift);
/* set irq fs */
fs = afe->irq_fs(substream, runtime->rate);
return 0; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND:
ret = mtk_memif_set_disable(afe, id); if (ret) {
dev_err(afe->dev, "%s(), error, id %d, memif enable, ret %d\n",
__func__, id, ret);
}
if (pm_runtime_status_suspended(dev) || !afe->suspended) return 0;
afe->runtime_resume(dev);
if (!afe->reg_back_up) {
dev_dbg(dev, "%s no reg_backup\n", __func__);
} else { for (i = 0; i < afe->reg_back_up_list_num; i++)
mtk_regmap_write(regmap, afe->reg_back_up_list[i],
afe->reg_back_up[i]);
}
/* set start, end, upper 32 bits */ if (memif->data->reg_ofs_base_msb) {
mtk_regmap_write(afe->regmap, memif->data->reg_ofs_base_msb,
phys_buf_addr_upper_32);
mtk_regmap_write(afe->regmap,
memif->data->reg_ofs_end_msb,
phys_buf_addr_upper_32);
}
/* * set MSB to 33-bit, for memif address * only for memif base address, if msb_end_reg exists
*/ if (memif->data->msb_reg)
mtk_regmap_update_bits(afe->regmap, memif->data->msb_reg,
1, msb_at_bit33, memif->data->msb_shift);
/* set MSB to 33-bit, for memif end address */ if (memif->data->msb_end_reg)
mtk_regmap_update_bits(afe->regmap, memif->data->msb_end_reg,
1, msb_at_bit33,
memif->data->msb_end_shift);
/* for specific configuration of memif mono mode */ if (memif->data->int_odd_flag_reg)
mtk_regmap_update_bits(afe->regmap,
memif->data->int_odd_flag_reg,
1, mono,
memif->data->int_odd_flag_shift);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.