Commit d09c774f authored by Sameer Pujar's avatar Sameer Pujar Committed by Mark Brown

ASoC: audio-graph: Expose new members for asoc_simple_priv

Add new members in struct 'asoc_simple_priv'. Idea is to leverage
simple or graph card driver as much as possible and vendor can
maintain a thin driver to control the behavior by populating these
newly exposed members.

Following are the members added in 'asoc_simple_priv':

  - 'ops' struct: In some cases SoC vendor drivers may want to
    implement 'snd_soc_ops' callbacks differently. In such cases
    custom callbacks would be used.

  - 'force_dpcm' flag: Right now simple or graph card drivers
    detect DAI links as DPCM links if:

      * The dpcm_selectable is set AND
      * Codec is connected to multiple CPU endpoints or aconvert
        property is used for rate/channels.

    So there is no way to directly specify usage of DPCM alone. So a
    flag is exposed to mark all links as DPCM. Vendor driver can
    set this if required.

  - 'dpcm_selectable': Currently simple or audio graph drivers
    provide a way to enable this for specific compatibles. However
    vendor driver may want to define some additional info. Thus
    expose this variable where vendor drivers can set this if
    required.

Audio graph driver is updated to consider above flags or callbacks.
Subsequent patches in the series illustrate usage for above.
Signed-off-by: default avatarSameer Pujar <spujar@nvidia.com>
Cc: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/1604329814-24779-7-git-send-email-spujar@nvidia.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 930dd47d
...@@ -56,6 +56,9 @@ struct asoc_simple_priv { ...@@ -56,6 +56,9 @@ struct asoc_simple_priv {
struct asoc_simple_dai *dais; struct asoc_simple_dai *dais;
struct snd_soc_codec_conf *codec_conf; struct snd_soc_codec_conf *codec_conf;
struct gpio_desc *pa_gpio; struct gpio_desc *pa_gpio;
const struct snd_soc_ops *ops;
unsigned int dpcm_selectable:1;
unsigned int force_dpcm:1;
}; };
#define simple_priv_to_card(priv) (&(priv)->snd_card) #define simple_priv_to_card(priv) (&(priv)->snd_card)
#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i)) #define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
......
...@@ -355,6 +355,11 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv, ...@@ -355,6 +355,11 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
snd_soc_dai_link_set_capabilities(dai_link); snd_soc_dai_link_set_capabilities(dai_link);
dai_link->ops = &graph_ops; dai_link->ops = &graph_ops;
/* Use custom snd_soc_ops callbacks if available */
if (priv->ops)
dai_link->ops = priv->ops;
dai_link->init = asoc_simple_dai_init; dai_link->init = asoc_simple_dai_init;
out_put_node: out_put_node:
...@@ -439,6 +444,28 @@ static int graph_dai_link_of(struct asoc_simple_priv *priv, ...@@ -439,6 +444,28 @@ static int graph_dai_link_of(struct asoc_simple_priv *priv,
return 0; return 0;
} }
static inline bool parse_as_dpcm_link(struct asoc_simple_priv *priv,
struct device_node *codec_port,
struct asoc_simple_data *adata)
{
if (priv->force_dpcm)
return true;
if (!priv->dpcm_selectable)
return false;
/*
* It is DPCM
* if Codec port has many endpoints,
* or has convert-xxx property
*/
if ((of_get_child_count(codec_port) > 1) ||
(adata->convert_rate || adata->convert_channels))
return true;
return false;
}
static int graph_for_each_link(struct asoc_simple_priv *priv, static int graph_for_each_link(struct asoc_simple_priv *priv,
struct link_info *li, struct link_info *li,
int (*func_noml)(struct asoc_simple_priv *priv, int (*func_noml)(struct asoc_simple_priv *priv,
...@@ -459,7 +486,6 @@ static int graph_for_each_link(struct asoc_simple_priv *priv, ...@@ -459,7 +486,6 @@ static int graph_for_each_link(struct asoc_simple_priv *priv,
struct device_node *codec_port; struct device_node *codec_port;
struct device_node *codec_port_old = NULL; struct device_node *codec_port_old = NULL;
struct asoc_simple_data adata; struct asoc_simple_data adata;
uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev);
int rc, ret; int rc, ret;
/* loop for all listed CPU port */ /* loop for all listed CPU port */
...@@ -482,14 +508,8 @@ static int graph_for_each_link(struct asoc_simple_priv *priv, ...@@ -482,14 +508,8 @@ static int graph_for_each_link(struct asoc_simple_priv *priv,
graph_parse_convert(dev, codec_ep, &adata); graph_parse_convert(dev, codec_ep, &adata);
graph_parse_convert(dev, cpu_ep, &adata); graph_parse_convert(dev, cpu_ep, &adata);
/* /* check if link requires DPCM parsing */
* It is DPCM if (parse_as_dpcm_link(priv, codec_port, &adata))
* if Codec port has many endpoints,
* or has convert-xxx property
*/
if (dpcm_selectable &&
((of_get_child_count(codec_port) > 1) ||
adata.convert_rate || adata.convert_channels))
ret = func_dpcm(priv, cpu_ep, codec_ep, li, ret = func_dpcm(priv, cpu_ep, codec_ep, li,
(codec_port_old == codec_port)); (codec_port_old == codec_port));
/* else normal sound */ /* else normal sound */
...@@ -678,6 +698,9 @@ static int graph_probe(struct platform_device *pdev) ...@@ -678,6 +698,9 @@ static int graph_probe(struct platform_device *pdev)
card->num_dapm_widgets = ARRAY_SIZE(graph_dapm_widgets); card->num_dapm_widgets = ARRAY_SIZE(graph_dapm_widgets);
card->probe = graph_card_probe; card->probe = graph_card_probe;
if (of_device_get_match_data(dev))
priv->dpcm_selectable = 1;
memset(&li, 0, sizeof(li)); memset(&li, 0, sizeof(li));
graph_get_dais_count(priv, &li); graph_get_dais_count(priv, &li);
if (!li.link || !li.dais) if (!li.link || !li.dais)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment