Path: blob/master/sound/soc/mediatek/common/mtk-afe-platform-driver.c
52580 views
// SPDX-License-Identifier: GPL-2.01/*2* mtk-afe-platform-driver.c -- Mediatek afe platform driver3*4* Copyright (c) 2016 MediaTek Inc.5* Author: Garlic Tseng <[email protected]>6*/78#include <linux/module.h>9#include <linux/dma-mapping.h>10#include <sound/soc.h>1112#include "mtk-afe-platform-driver.h"13#include "mtk-base-afe.h"1415int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe)16{17struct mtk_base_afe_dai *dai;18size_t num_dai_drivers = 0, dai_idx = 0;1920/* calcualte total dai driver size */21list_for_each_entry(dai, &afe->sub_dais, list) {22num_dai_drivers += dai->num_dai_drivers;23}2425dev_info(afe->dev, "%s(), num of dai %zd\n", __func__, num_dai_drivers);2627/* combine sub_dais */28afe->num_dai_drivers = num_dai_drivers;29afe->dai_drivers = devm_kcalloc(afe->dev,30num_dai_drivers,31sizeof(struct snd_soc_dai_driver),32GFP_KERNEL);33if (!afe->dai_drivers)34return -ENOMEM;3536list_for_each_entry(dai, &afe->sub_dais, list) {37/* dai driver */38memcpy(&afe->dai_drivers[dai_idx],39dai->dai_drivers,40dai->num_dai_drivers *41sizeof(struct snd_soc_dai_driver));42dai_idx += dai->num_dai_drivers;43}44return 0;45}46EXPORT_SYMBOL_GPL(mtk_afe_combine_sub_dai);4748int mtk_afe_add_sub_dai_control(struct snd_soc_component *component)49{50struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);51struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);52struct mtk_base_afe_dai *dai;5354list_for_each_entry(dai, &afe->sub_dais, list) {55if (dai->controls)56snd_soc_add_component_controls(component,57dai->controls,58dai->num_controls);5960if (dai->dapm_widgets)61snd_soc_dapm_new_controls(dapm,62dai->dapm_widgets,63dai->num_dapm_widgets);64}65/* add routes after all widgets are added */66list_for_each_entry(dai, &afe->sub_dais, list) {67if (dai->dapm_routes)68snd_soc_dapm_add_routes(dapm,69dai->dapm_routes,70dai->num_dapm_routes);71}7273snd_soc_dapm_new_widgets(component->card);7475return 0;7677}78EXPORT_SYMBOL_GPL(mtk_afe_add_sub_dai_control);7980snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component,81struct snd_pcm_substream *substream)82{83struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);84struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);85struct mtk_base_afe_memif *memif = &afe->memif[snd_soc_rtd_to_cpu(rtd, 0)->id];86const struct mtk_base_memif_data *memif_data = memif->data;87struct regmap *regmap = afe->regmap;88struct device *dev = afe->dev;89int reg_ofs_base = memif_data->reg_ofs_base;90int reg_ofs_cur = memif_data->reg_ofs_cur;91unsigned int hw_ptr = 0, hw_base = 0;92int ret, pcm_ptr_bytes;9394ret = regmap_read(regmap, reg_ofs_cur, &hw_ptr);95if (ret || hw_ptr == 0) {96dev_err(dev, "%s hw_ptr err\n", __func__);97pcm_ptr_bytes = 0;98goto POINTER_RETURN_FRAMES;99}100101ret = regmap_read(regmap, reg_ofs_base, &hw_base);102if (ret || hw_base == 0) {103dev_err(dev, "%s hw_ptr err\n", __func__);104pcm_ptr_bytes = 0;105goto POINTER_RETURN_FRAMES;106}107108pcm_ptr_bytes = hw_ptr - hw_base;109110POINTER_RETURN_FRAMES:111return bytes_to_frames(substream->runtime, pcm_ptr_bytes);112}113EXPORT_SYMBOL_GPL(mtk_afe_pcm_pointer);114115int mtk_afe_pcm_new(struct snd_soc_component *component,116struct snd_soc_pcm_runtime *rtd)117{118size_t size;119struct snd_pcm *pcm = rtd->pcm;120struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);121122size = afe->mtk_afe_hardware->buffer_bytes_max;123snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, afe->dev,124afe->preallocate_buffers ? size : 0,125size);126127return 0;128}129EXPORT_SYMBOL_GPL(mtk_afe_pcm_new);130131static int mtk_afe_component_probe(struct snd_soc_component *component)132{133struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);134int ret;135136snd_soc_component_init_regmap(component, afe->regmap);137138/* If the list was never initialized there are no sub-DAIs */139if (afe->sub_dais.next && afe->sub_dais.prev) {140ret = mtk_afe_add_sub_dai_control(component);141if (ret)142return ret;143}144145return 0;146}147148const struct snd_soc_component_driver mtk_afe_pcm_platform = {149.name = AFE_PCM_NAME,150.pointer = mtk_afe_pcm_pointer,151.pcm_construct = mtk_afe_pcm_new,152.probe = mtk_afe_component_probe,153};154EXPORT_SYMBOL_GPL(mtk_afe_pcm_platform);155156MODULE_DESCRIPTION("Mediatek simple platform driver");157MODULE_AUTHOR("Garlic Tseng <[email protected]>");158MODULE_LICENSE("GPL v2");159160161162