2020-02-13 16:51:52 +01:00
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2019 BayLibre, SAS.
// Author: Jerome Brunet <jbrunet@baylibre.com>
# include <linux/module.h>
# include <sound/pcm_params.h>
# include <sound/soc.h>
# include <sound/soc-dai.h>
# include "meson-codec-glue.h"
static struct snd_soc_dapm_widget *
meson_codec_glue_get_input ( struct snd_soc_dapm_widget * w )
{
2022-05-20 16:17:19 -05:00
struct snd_soc_dapm_path * p ;
2020-02-13 16:51:52 +01:00
struct snd_soc_dapm_widget * in ;
snd_soc_dapm_widget_for_each_source_path ( w , p ) {
if ( ! p - > connect )
continue ;
/* Check that we still are in the same component */
if ( snd_soc_dapm_to_component ( w - > dapm ) ! =
snd_soc_dapm_to_component ( p - > source - > dapm ) )
continue ;
if ( p - > source - > id = = snd_soc_dapm_dai_in )
return p - > source ;
in = meson_codec_glue_get_input ( p - > source ) ;
if ( in )
return in ;
}
return NULL ;
}
static void meson_codec_glue_input_set_data ( struct snd_soc_dai * dai ,
struct meson_codec_glue_input * data )
{
dai - > playback_dma_data = data ;
}
struct meson_codec_glue_input *
meson_codec_glue_input_get_data ( struct snd_soc_dai * dai )
{
return dai - > playback_dma_data ;
}
EXPORT_SYMBOL_GPL ( meson_codec_glue_input_get_data ) ;
static struct meson_codec_glue_input *
meson_codec_glue_output_get_input_data ( struct snd_soc_dapm_widget * w )
{
struct snd_soc_dapm_widget * in =
meson_codec_glue_get_input ( w ) ;
struct snd_soc_dai * dai ;
if ( WARN_ON ( ! in ) )
return NULL ;
dai = in - > priv ;
return meson_codec_glue_input_get_data ( dai ) ;
}
int meson_codec_glue_input_hw_params ( struct snd_pcm_substream * substream ,
struct snd_pcm_hw_params * params ,
struct snd_soc_dai * dai )
{
struct meson_codec_glue_input * data =
meson_codec_glue_input_get_data ( dai ) ;
data - > params . rates = snd_pcm_rate_to_rate_bit ( params_rate ( params ) ) ;
data - > params . rate_min = params_rate ( params ) ;
data - > params . rate_max = params_rate ( params ) ;
2020-02-14 14:13:50 +01:00
data - > params . formats = 1ULL < < ( __force int ) params_format ( params ) ;
2020-02-13 16:51:52 +01:00
data - > params . channels_min = params_channels ( params ) ;
data - > params . channels_max = params_channels ( params ) ;
data - > params . sig_bits = dai - > driver - > playback . sig_bits ;
return 0 ;
}
EXPORT_SYMBOL_GPL ( meson_codec_glue_input_hw_params ) ;
int meson_codec_glue_input_set_fmt ( struct snd_soc_dai * dai ,
unsigned int fmt )
{
struct meson_codec_glue_input * data =
meson_codec_glue_input_get_data ( dai ) ;
/* Save the source stream format for the downstream link */
data - > fmt = fmt ;
return 0 ;
}
EXPORT_SYMBOL_GPL ( meson_codec_glue_input_set_fmt ) ;
int meson_codec_glue_output_startup ( struct snd_pcm_substream * substream ,
struct snd_soc_dai * dai )
{
2020-07-20 10:19:14 +09:00
struct snd_soc_pcm_runtime * rtd = asoc_substream_to_rtd ( substream ) ;
2020-02-13 16:51:52 +01:00
struct meson_codec_glue_input * in_data =
meson_codec_glue_output_get_input_data ( dai - > capture_widget ) ;
if ( ! in_data )
return - ENODEV ;
if ( WARN_ON ( ! rtd - > dai_link - > params ) ) {
dev_warn ( dai - > dev , " codec2codec link expected \n " ) ;
return - EINVAL ;
}
/* Replace link params with the input params */
rtd - > dai_link - > params = & in_data - > params ;
return snd_soc_runtime_set_dai_fmt ( rtd , in_data - > fmt ) ;
}
EXPORT_SYMBOL_GPL ( meson_codec_glue_output_startup ) ;
int meson_codec_glue_input_dai_probe ( struct snd_soc_dai * dai )
{
struct meson_codec_glue_input * data ;
data = kzalloc ( sizeof ( * data ) , GFP_KERNEL ) ;
if ( ! data )
return - ENOMEM ;
meson_codec_glue_input_set_data ( dai , data ) ;
return 0 ;
}
EXPORT_SYMBOL_GPL ( meson_codec_glue_input_dai_probe ) ;
int meson_codec_glue_input_dai_remove ( struct snd_soc_dai * dai )
{
struct meson_codec_glue_input * data =
meson_codec_glue_input_get_data ( dai ) ;
kfree ( data ) ;
return 0 ;
}
EXPORT_SYMBOL_GPL ( meson_codec_glue_input_dai_remove ) ;
MODULE_AUTHOR ( " Jerome Brunet <jbrunet@baylibre.com> " ) ;
MODULE_DESCRIPTION ( " Amlogic Codec Glue Helpers " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;