root/sound/soc/mediatek/common/mtk-afe-platform-driver.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mtk_afe_combine_sub_dai
  2. mtk_afe_add_sub_dai_control
  3. mtk_afe_pcm_new
  4. mtk_afe_pcm_free

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * mtk-afe-platform-driver.c  --  Mediatek afe platform driver
   4  *
   5  * Copyright (c) 2016 MediaTek Inc.
   6  * Author: Garlic Tseng <garlic.tseng@mediatek.com>
   7  */
   8 
   9 #include <linux/module.h>
  10 #include <linux/dma-mapping.h>
  11 #include <sound/soc.h>
  12 
  13 #include "mtk-afe-platform-driver.h"
  14 #include "mtk-base-afe.h"
  15 
  16 int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe)
  17 {
  18         struct mtk_base_afe_dai *dai;
  19         size_t num_dai_drivers = 0, dai_idx = 0;
  20 
  21         /* calcualte total dai driver size */
  22         list_for_each_entry(dai, &afe->sub_dais, list) {
  23                 num_dai_drivers += dai->num_dai_drivers;
  24         }
  25 
  26         dev_info(afe->dev, "%s(), num of dai %zd\n", __func__, num_dai_drivers);
  27 
  28         /* combine sub_dais */
  29         afe->num_dai_drivers = num_dai_drivers;
  30         afe->dai_drivers = devm_kcalloc(afe->dev,
  31                                         num_dai_drivers,
  32                                         sizeof(struct snd_soc_dai_driver),
  33                                         GFP_KERNEL);
  34         if (!afe->dai_drivers)
  35                 return -ENOMEM;
  36 
  37         list_for_each_entry(dai, &afe->sub_dais, list) {
  38                 /* dai driver */
  39                 memcpy(&afe->dai_drivers[dai_idx],
  40                        dai->dai_drivers,
  41                        dai->num_dai_drivers *
  42                        sizeof(struct snd_soc_dai_driver));
  43                 dai_idx += dai->num_dai_drivers;
  44         }
  45         return 0;
  46 }
  47 EXPORT_SYMBOL_GPL(mtk_afe_combine_sub_dai);
  48 
  49 int mtk_afe_add_sub_dai_control(struct snd_soc_component *component)
  50 {
  51         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
  52         struct mtk_base_afe_dai *dai;
  53 
  54         list_for_each_entry(dai, &afe->sub_dais, list) {
  55                 if (dai->controls)
  56                         snd_soc_add_component_controls(component,
  57                                                        dai->controls,
  58                                                        dai->num_controls);
  59 
  60                 if (dai->dapm_widgets)
  61                         snd_soc_dapm_new_controls(&component->dapm,
  62                                                   dai->dapm_widgets,
  63                                                   dai->num_dapm_widgets);
  64         }
  65         /* add routes after all widgets are added */
  66         list_for_each_entry(dai, &afe->sub_dais, list) {
  67                 if (dai->dapm_routes)
  68                         snd_soc_dapm_add_routes(&component->dapm,
  69                                                 dai->dapm_routes,
  70                                                 dai->num_dapm_routes);
  71         }
  72 
  73         snd_soc_dapm_new_widgets(component->dapm.card);
  74 
  75         return 0;
  76 
  77 }
  78 EXPORT_SYMBOL_GPL(mtk_afe_add_sub_dai_control);
  79 
  80 static snd_pcm_uframes_t mtk_afe_pcm_pointer
  81                          (struct snd_pcm_substream *substream)
  82 {
  83         struct snd_soc_pcm_runtime *rtd = substream->private_data;
  84         struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
  85         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
  86         struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
  87         const struct mtk_base_memif_data *memif_data = memif->data;
  88         struct regmap *regmap = afe->regmap;
  89         struct device *dev = afe->dev;
  90         int reg_ofs_base = memif_data->reg_ofs_base;
  91         int reg_ofs_cur = memif_data->reg_ofs_cur;
  92         unsigned int hw_ptr = 0, hw_base = 0;
  93         int ret, pcm_ptr_bytes;
  94 
  95         ret = regmap_read(regmap, reg_ofs_cur, &hw_ptr);
  96         if (ret || hw_ptr == 0) {
  97                 dev_err(dev, "%s hw_ptr err\n", __func__);
  98                 pcm_ptr_bytes = 0;
  99                 goto POINTER_RETURN_FRAMES;
 100         }
 101 
 102         ret = regmap_read(regmap, reg_ofs_base, &hw_base);
 103         if (ret || hw_base == 0) {
 104                 dev_err(dev, "%s hw_ptr err\n", __func__);
 105                 pcm_ptr_bytes = 0;
 106                 goto POINTER_RETURN_FRAMES;
 107         }
 108 
 109         pcm_ptr_bytes = hw_ptr - hw_base;
 110 
 111 POINTER_RETURN_FRAMES:
 112         return bytes_to_frames(substream->runtime, pcm_ptr_bytes);
 113 }
 114 
 115 const struct snd_pcm_ops mtk_afe_pcm_ops = {
 116         .ioctl = snd_pcm_lib_ioctl,
 117         .pointer = mtk_afe_pcm_pointer,
 118 };
 119 EXPORT_SYMBOL_GPL(mtk_afe_pcm_ops);
 120 
 121 int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd)
 122 {
 123         size_t size;
 124         struct snd_pcm *pcm = rtd->pcm;
 125         struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
 126         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 127 
 128         size = afe->mtk_afe_hardware->buffer_bytes_max;
 129         snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
 130                                               afe->dev, size, size);
 131         return 0;
 132 }
 133 EXPORT_SYMBOL_GPL(mtk_afe_pcm_new);
 134 
 135 void mtk_afe_pcm_free(struct snd_pcm *pcm)
 136 {
 137         snd_pcm_lib_preallocate_free_for_all(pcm);
 138 }
 139 EXPORT_SYMBOL_GPL(mtk_afe_pcm_free);
 140 
 141 const struct snd_soc_component_driver mtk_afe_pcm_platform = {
 142         .name = AFE_PCM_NAME,
 143         .ops = &mtk_afe_pcm_ops,
 144         .pcm_new = mtk_afe_pcm_new,
 145         .pcm_free = mtk_afe_pcm_free,
 146 };
 147 EXPORT_SYMBOL_GPL(mtk_afe_pcm_platform);
 148 
 149 MODULE_DESCRIPTION("Mediatek simple platform driver");
 150 MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
 151 MODULE_LICENSE("GPL v2");
 152 

/* [<][>][^][v][top][bottom][index][help] */