linux/include/sound/soc-dpcm.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0
   2 *
   3 * linux/sound/soc-dpcm.h -- ALSA SoC Dynamic PCM Support
   4 *
   5 * Author:              Liam Girdwood <lrg@ti.com>
   6 */
   7
   8#ifndef __LINUX_SND_SOC_DPCM_H
   9#define __LINUX_SND_SOC_DPCM_H
  10
  11#include <linux/slab.h>
  12#include <linux/list.h>
  13#include <sound/pcm.h>
  14
  15struct snd_soc_pcm_runtime;
  16
  17/*
  18 * Types of runtime_update to perform. e.g. originated from FE PCM ops
  19 * or audio route changes triggered by muxes/mixers.
  20 */
  21enum snd_soc_dpcm_update {
  22        SND_SOC_DPCM_UPDATE_NO  = 0,
  23        SND_SOC_DPCM_UPDATE_BE,
  24        SND_SOC_DPCM_UPDATE_FE,
  25};
  26
  27/*
  28 * Dynamic PCM Frontend -> Backend link management states.
  29 */
  30enum snd_soc_dpcm_link_state {
  31        SND_SOC_DPCM_LINK_STATE_NEW     = 0,    /* newly created link */
  32        SND_SOC_DPCM_LINK_STATE_FREE,           /* link to be dismantled */
  33};
  34
  35/*
  36 * Dynamic PCM Frontend -> Backend link PCM states.
  37 */
  38enum snd_soc_dpcm_state {
  39        SND_SOC_DPCM_STATE_NEW  = 0,
  40        SND_SOC_DPCM_STATE_OPEN,
  41        SND_SOC_DPCM_STATE_HW_PARAMS,
  42        SND_SOC_DPCM_STATE_PREPARE,
  43        SND_SOC_DPCM_STATE_START,
  44        SND_SOC_DPCM_STATE_STOP,
  45        SND_SOC_DPCM_STATE_PAUSED,
  46        SND_SOC_DPCM_STATE_SUSPEND,
  47        SND_SOC_DPCM_STATE_HW_FREE,
  48        SND_SOC_DPCM_STATE_CLOSE,
  49};
  50
  51/*
  52 * Dynamic PCM trigger ordering. Triggering flexibility is required as some
  53 * DSPs require triggering before/after their CPU platform and DAIs.
  54 *
  55 * i.e. some clients may want to manually order this call in their PCM
  56 * trigger() whilst others will just use the regular core ordering.
  57 */
  58enum snd_soc_dpcm_trigger {
  59        SND_SOC_DPCM_TRIGGER_PRE                = 0,
  60        SND_SOC_DPCM_TRIGGER_POST,
  61        SND_SOC_DPCM_TRIGGER_BESPOKE,
  62};
  63
  64/*
  65 * Dynamic PCM link
  66 * This links together a FE and BE DAI at runtime and stores the link
  67 * state information and the hw_params configuration.
  68 */
  69struct snd_soc_dpcm {
  70        /* FE and BE DAIs*/
  71        struct snd_soc_pcm_runtime *be;
  72        struct snd_soc_pcm_runtime *fe;
  73
  74        /* link state */
  75        enum snd_soc_dpcm_link_state state;
  76
  77        /* list of BE and FE for this DPCM link */
  78        struct list_head list_be;
  79        struct list_head list_fe;
  80
  81        /* hw params for this link - may be different for each link */
  82        struct snd_pcm_hw_params hw_params;
  83#ifdef CONFIG_DEBUG_FS
  84        struct dentry *debugfs_state;
  85#endif
  86};
  87
  88/*
  89 * Dynamic PCM runtime data.
  90 */
  91struct snd_soc_dpcm_runtime {
  92        struct list_head be_clients;
  93        struct list_head fe_clients;
  94
  95        int users;
  96        struct snd_pcm_runtime *runtime;
  97        struct snd_pcm_hw_params hw_params;
  98
  99        /* state and update */
 100        enum snd_soc_dpcm_update runtime_update;
 101        enum snd_soc_dpcm_state state;
 102
 103        int trigger_pending; /* trigger cmd + 1 if pending, 0 if not */
 104};
 105
 106#define for_each_dpcm_fe(be, stream, _dpcm)                             \
 107        list_for_each_entry(_dpcm, &(be)->dpcm[stream].fe_clients, list_fe)
 108
 109#define for_each_dpcm_be(fe, stream, _dpcm)                             \
 110        list_for_each_entry(_dpcm, &(fe)->dpcm[stream].be_clients, list_be)
 111#define for_each_dpcm_be_safe(fe, stream, _dpcm, __dpcm)                        \
 112        list_for_each_entry_safe(_dpcm, __dpcm, &(fe)->dpcm[stream].be_clients, list_be)
 113#define for_each_dpcm_be_rollback(fe, stream, _dpcm)                    \
 114        list_for_each_entry_continue_reverse(_dpcm, &(fe)->dpcm[stream].be_clients, list_be)
 115
 116/* can this BE stop and free */
 117int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
 118                struct snd_soc_pcm_runtime *be, int stream);
 119
 120/* can this BE perform a hw_params() */
 121int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
 122                struct snd_soc_pcm_runtime *be, int stream);
 123
 124/* is the current PCM operation for this FE ? */
 125int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream);
 126
 127/* is the current PCM operation for this BE ? */
 128int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe,
 129                struct snd_soc_pcm_runtime *be, int stream);
 130
 131/* get the substream for this BE */
 132struct snd_pcm_substream *
 133        snd_soc_dpcm_get_substream(struct snd_soc_pcm_runtime *be, int stream);
 134
 135/* update audio routing between PCMs and any DAI links */
 136int snd_soc_dpcm_runtime_update(struct snd_soc_card *card);
 137
 138#ifdef CONFIG_DEBUG_FS
 139void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd);
 140#else
 141static inline void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
 142{
 143}
 144#endif
 145
 146int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
 147        int stream, struct snd_soc_dapm_widget_list **list_);
 148void dpcm_path_put(struct snd_soc_dapm_widget_list **list);
 149int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
 150        int stream, struct snd_soc_dapm_widget_list **list, int new);
 151int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream);
 152void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream,
 153                      int do_hw_free, struct snd_soc_dpcm *last);
 154void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream);
 155void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream);
 156void dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream);
 157int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int tream);
 158int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd);
 159int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream);
 160int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
 161        int event);
 162
 163#define dpcm_be_dai_startup_rollback(fe, stream, last)  \
 164                                                dpcm_be_dai_stop(fe, stream, 0, last)
 165#define dpcm_be_dai_startup_unwind(fe, stream)  dpcm_be_dai_stop(fe, stream, 0, NULL)
 166#define dpcm_be_dai_shutdown(fe, stream)        dpcm_be_dai_stop(fe, stream, 1, NULL)
 167
 168#endif
 169