Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  mtk-afe-platform-driver.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * mtk-afe-platform-driver.c  --  Mediatek afe platform driver
 *
 * Copyright (c) 2016 MediaTek Inc.
 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
 */


#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <sound/soc.h>

#include "mtk-afe-platform-driver.h"
#include "mtk-base-afe.h"

int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe)
{
 struct mtk_base_afe_dai *dai;
 size_t num_dai_drivers = 0, dai_idx = 0;

 /* calcualte total dai driver size */
 list_for_each_entry(dai, &afe->sub_dais, list) {
  num_dai_drivers += dai->num_dai_drivers;
 }

 dev_info(afe->dev, "%s(), num of dai %zd\n", __func__, num_dai_drivers);

 /* combine sub_dais */
 afe->num_dai_drivers = num_dai_drivers;
 afe->dai_drivers = devm_kcalloc(afe->dev,
     num_dai_drivers,
     sizeof(struct snd_soc_dai_driver),
     GFP_KERNEL);
 if (!afe->dai_drivers)
  return -ENOMEM;

 list_for_each_entry(dai, &afe->sub_dais, list) {
  /* dai driver */
  memcpy(&afe->dai_drivers[dai_idx],
         dai->dai_drivers,
         dai->num_dai_drivers *
         sizeof(struct snd_soc_dai_driver));
  dai_idx += dai->num_dai_drivers;
 }
 return 0;
}
EXPORT_SYMBOL_GPL(mtk_afe_combine_sub_dai);

int mtk_afe_add_sub_dai_control(struct snd_soc_component *component)
{
 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 struct mtk_base_afe_dai *dai;

 list_for_each_entry(dai, &afe->sub_dais, list) {
  if (dai->controls)
   snd_soc_add_component_controls(component,
             dai->controls,
             dai->num_controls);

  if (dai->dapm_widgets)
   snd_soc_dapm_new_controls(&component->dapm,
        dai->dapm_widgets,
        dai->num_dapm_widgets);
 }
 /* add routes after all widgets are added */
 list_for_each_entry(dai, &afe->sub_dais, list) {
  if (dai->dapm_routes)
   snd_soc_dapm_add_routes(&component->dapm,
      dai->dapm_routes,
      dai->num_dapm_routes);
 }

 snd_soc_dapm_new_widgets(component->dapm.card);

 return 0;

}
EXPORT_SYMBOL_GPL(mtk_afe_add_sub_dai_control);

snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component,
          struct snd_pcm_substream *substream)
{
 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 struct mtk_base_afe_memif *memif = &afe->memif[snd_soc_rtd_to_cpu(rtd, 0)->id];
 const struct mtk_base_memif_data *memif_data = memif->data;
 struct regmap *regmap = afe->regmap;
 struct device *dev = afe->dev;
 int reg_ofs_base = memif_data->reg_ofs_base;
 int reg_ofs_cur = memif_data->reg_ofs_cur;
 unsigned int hw_ptr = 0, hw_base = 0;
 int ret, pcm_ptr_bytes;

 ret = regmap_read(regmap, reg_ofs_cur, &hw_ptr);
 if (ret || hw_ptr == 0) {
  dev_err(dev, "%s hw_ptr err\n", __func__);
  pcm_ptr_bytes = 0;
  goto POINTER_RETURN_FRAMES;
 }

 ret = regmap_read(regmap, reg_ofs_base, &hw_base);
 if (ret || hw_base == 0) {
  dev_err(dev, "%s hw_ptr err\n", __func__);
  pcm_ptr_bytes = 0;
  goto POINTER_RETURN_FRAMES;
 }

 pcm_ptr_bytes = hw_ptr - hw_base;

POINTER_RETURN_FRAMES:
 return bytes_to_frames(substream->runtime, pcm_ptr_bytes);
}
EXPORT_SYMBOL_GPL(mtk_afe_pcm_pointer);

int mtk_afe_pcm_new(struct snd_soc_component *component,
      struct snd_soc_pcm_runtime *rtd)
{
 size_t size;
 struct snd_pcm *pcm = rtd->pcm;
 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);

 size = afe->mtk_afe_hardware->buffer_bytes_max;
 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, afe->dev,
           afe->preallocate_buffers ? size : 0,
           size);

 return 0;
}
EXPORT_SYMBOL_GPL(mtk_afe_pcm_new);

static int mtk_afe_component_probe(struct snd_soc_component *component)
{
 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 int ret;

 snd_soc_component_init_regmap(component, afe->regmap);

 /* If the list was never initialized there are no sub-DAIs */
 if (afe->sub_dais.next && afe->sub_dais.prev) {
  ret = mtk_afe_add_sub_dai_control(component);
  if (ret)
   return ret;
 }

 return 0;
}

const struct snd_soc_component_driver mtk_afe_pcm_platform = {
 .name  = AFE_PCM_NAME,
 .pointer = mtk_afe_pcm_pointer,
 .pcm_construct = mtk_afe_pcm_new,
 .probe  = mtk_afe_component_probe,
};
EXPORT_SYMBOL_GPL(mtk_afe_pcm_platform);

MODULE_DESCRIPTION("Mediatek simple platform driver");
MODULE_AUTHOR("Garlic Tseng ");
MODULE_LICENSE("GPL v2");


Messung V0.5
C=91 H=98 G=94

¤ Dauer der Verarbeitung: 0.18 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge