Unverified Commit 748fd07e authored by Charles Keepax's avatar Charles Keepax Committed by Mark Brown
Browse files

ASoC: madera: Read device tree configuration



Read the configuration of the Madera ASoC driver from device tree.

Signed-off-by: default avatarCharles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20190722135209.30302-1-ckeepax@opensource.cirrus.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent b6319b06
Loading
Loading
Loading
Loading
+97 −0
Original line number Diff line number Diff line
@@ -300,6 +300,100 @@ int madera_free_overheat(struct madera_priv *priv)
}
EXPORT_SYMBOL_GPL(madera_free_overheat);

static int madera_get_variable_u32_array(struct device *dev,
					 const char *propname,
					 u32 *dest, int n_max,
					 int multiple)
{
	int n, ret;

	n = device_property_count_u32(dev, propname);
	if (n < 0) {
		if (n == -EINVAL)
			return 0;	/* missing, ignore */

		dev_warn(dev, "%s malformed (%d)\n", propname, n);

		return n;
	} else if ((n % multiple) != 0) {
		dev_warn(dev, "%s not a multiple of %d entries\n",
			 propname, multiple);

		return -EINVAL;
	}

	if (n > n_max)
		n = n_max;

	ret = device_property_read_u32_array(dev, propname, dest, n);
	if (ret < 0)
		return ret;

	return n;
}

static void madera_prop_get_inmode(struct madera_priv *priv)
{
	struct madera *madera = priv->madera;
	struct madera_codec_pdata *pdata = &madera->pdata.codec;
	u32 tmp[MADERA_MAX_INPUT * MADERA_MAX_MUXED_CHANNELS];
	int n, i, in_idx, ch_idx;

	BUILD_BUG_ON(ARRAY_SIZE(pdata->inmode) != MADERA_MAX_INPUT);
	BUILD_BUG_ON(ARRAY_SIZE(pdata->inmode[0]) != MADERA_MAX_MUXED_CHANNELS);

	n = madera_get_variable_u32_array(madera->dev, "cirrus,inmode",
					  tmp, ARRAY_SIZE(tmp),
					  MADERA_MAX_MUXED_CHANNELS);
	if (n < 0)
		return;

	in_idx = 0;
	ch_idx = 0;
	for (i = 0; i < n; ++i) {
		pdata->inmode[in_idx][ch_idx] = tmp[i];

		if (++ch_idx == MADERA_MAX_MUXED_CHANNELS) {
			ch_idx = 0;
			++in_idx;
		}
	}
}

static void madera_prop_get_pdata(struct madera_priv *priv)
{
	struct madera *madera = priv->madera;
	struct madera_codec_pdata *pdata = &madera->pdata.codec;
	u32 out_mono[ARRAY_SIZE(pdata->out_mono)];
	int i, n;

	madera_prop_get_inmode(priv);

	n = madera_get_variable_u32_array(madera->dev, "cirrus,out-mono",
					  out_mono, ARRAY_SIZE(out_mono), 1);
	if (n > 0)
		for (i = 0; i < n; ++i)
			pdata->out_mono[i] = !!out_mono[i];

	madera_get_variable_u32_array(madera->dev,
				      "cirrus,max-channels-clocked",
				      pdata->max_channels_clocked,
				      ARRAY_SIZE(pdata->max_channels_clocked),
				      1);

	madera_get_variable_u32_array(madera->dev, "cirrus,pdm-fmt",
				      pdata->pdm_fmt,
				      ARRAY_SIZE(pdata->pdm_fmt), 1);

	madera_get_variable_u32_array(madera->dev, "cirrus,pdm-mute",
				      pdata->pdm_mute,
				      ARRAY_SIZE(pdata->pdm_mute), 1);

	madera_get_variable_u32_array(madera->dev, "cirrus,dmic-ref",
				      pdata->dmic_ref,
				      ARRAY_SIZE(pdata->dmic_ref), 1);
}

int madera_core_init(struct madera_priv *priv)
{
	int i;
@@ -308,6 +402,9 @@ int madera_core_init(struct madera_priv *priv)
	BUILD_BUG_ON(!madera_mixer_texts[MADERA_NUM_MIXER_INPUTS - 1]);
	BUILD_BUG_ON(!madera_mixer_values[MADERA_NUM_MIXER_INPUTS - 1]);

	if (!dev_get_platdata(priv->madera->dev))
		madera_prop_get_pdata(priv);

	mutex_init(&priv->rate_lock);

	for (i = 0; i < MADERA_MAX_HP_OUTPUT; i++)