Unverified Commit 7766861d authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

ASoC: soc-core: add snd_soc_daifmt_parse_format/clock_provider()



snd_soc_of_parse_daifmt() parses daifmt, but bitclock/frame provider
parsing part is one of headacke, because we are assuming below both cases.

A)	node {
		bitclock-master;
		frame-master;
		...
	};

B)	link {
		bitclock-master = <&xxx>;
		frame-master = <&xxx>;
		...
	};

The original was style A), and style B) was added later
by commit b3ca11ff ("ASoC: simple-card: Move dai-link level
properties away from dai subnodes").

snd_soc_of_parse_daifmt() parses it as style A),
and user need to update it to style B) if needed.

To handle it more flexibile, this patch adds new functions
which separates snd_soc_of_parse_daifmt() helper function.

 snd_soc_daifmt_parse_format()			 :for DAI format
 snd_soc_daifmt_parse_clock_provider_as_flag()	 :for style A)
 snd_soc_daifmt_parse_clock_provider_as_phandl() :for style B)
 snd_soc_daifmt_parse_clock_provider_as_bitmap() :use with _from_bitmap

This means

 snd_soc_of_parse_daifmt() ==
	snd_soc_daifmt_parse_format() |
	snd_soc_daifmt_parse_clock_provider_as_flag()

This patch also indicate relatesionship comment for
snd_soc_daifmt_clock_provider_from_bitmap().

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/877dixw9ej.wl-kuninori.morimoto.gx@renesas.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent b44a67f8
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1235,6 +1235,20 @@ int snd_soc_of_parse_aux_devs(struct snd_soc_card *card, const char *propname);

unsigned int snd_soc_daifmt_clock_provider_fliped(unsigned int dai_fmt);
unsigned int snd_soc_daifmt_clock_provider_from_bitmap(unsigned int bit_frame);

unsigned int snd_soc_daifmt_parse_format(struct device_node *np, const char *prefix);
unsigned int snd_soc_daifmt_parse_clock_provider_raw(struct device_node *np,
						     const char *prefix,
						     struct device_node **bitclkmaster,
						     struct device_node **framemaster);
#define snd_soc_daifmt_parse_clock_provider_as_bitmap(np, prefix)	\
	snd_soc_daifmt_parse_clock_provider_raw(np, prefix, NULL, NULL)
#define snd_soc_daifmt_parse_clock_provider_as_phandle			\
	snd_soc_daifmt_parse_clock_provider_raw
#define snd_soc_daifmt_parse_clock_provider_as_flag(np, prefix)		\
	snd_soc_daifmt_clock_provider_from_bitmap(			\
		snd_soc_daifmt_parse_clock_provider_as_bitmap(np, prefix))

unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
				     const char *prefix,
				     struct device_node **bitclkmaster,
+124 −0
Original line number Diff line number Diff line
@@ -3029,6 +3029,11 @@ EXPORT_SYMBOL_GPL(snd_soc_daifmt_clock_provider_fliped);

unsigned int snd_soc_daifmt_clock_provider_from_bitmap(unsigned int bit_frame)
{
	/*
	 * bit_frame is return value from
	 *	snd_soc_daifmt_parse_clock_provider_raw()
	 */

	/* Codec base */
	switch (bit_frame) {
	case 0x11:
@@ -3045,6 +3050,125 @@ unsigned int snd_soc_daifmt_clock_provider_from_bitmap(unsigned int bit_frame)
}
EXPORT_SYMBOL_GPL(snd_soc_daifmt_clock_provider_from_bitmap);

unsigned int snd_soc_daifmt_parse_format(struct device_node *np,
					 const char *prefix)
{
	int ret, i;
	char prop[128];
	unsigned int format = 0;
	int bit, frame;
	const char *str;
	struct {
		char *name;
		unsigned int val;
	} of_fmt_table[] = {
		{ "i2s",	SND_SOC_DAIFMT_I2S },
		{ "right_j",	SND_SOC_DAIFMT_RIGHT_J },
		{ "left_j",	SND_SOC_DAIFMT_LEFT_J },
		{ "dsp_a",	SND_SOC_DAIFMT_DSP_A },
		{ "dsp_b",	SND_SOC_DAIFMT_DSP_B },
		{ "ac97",	SND_SOC_DAIFMT_AC97 },
		{ "pdm",	SND_SOC_DAIFMT_PDM},
		{ "msb",	SND_SOC_DAIFMT_MSB },
		{ "lsb",	SND_SOC_DAIFMT_LSB },
	};

	if (!prefix)
		prefix = "";

	/*
	 * check "dai-format = xxx"
	 * or    "[prefix]format = xxx"
	 * SND_SOC_DAIFMT_FORMAT_MASK area
	 */
	ret = of_property_read_string(np, "dai-format", &str);
	if (ret < 0) {
		snprintf(prop, sizeof(prop), "%sformat", prefix);
		ret = of_property_read_string(np, prop, &str);
	}
	if (ret == 0) {
		for (i = 0; i < ARRAY_SIZE(of_fmt_table); i++) {
			if (strcmp(str, of_fmt_table[i].name) == 0) {
				format |= of_fmt_table[i].val;
				break;
			}
		}
	}

	/*
	 * check "[prefix]continuous-clock"
	 * SND_SOC_DAIFMT_CLOCK_MASK area
	 */
	snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix);
	if (of_property_read_bool(np, prop))
		format |= SND_SOC_DAIFMT_CONT;
	else
		format |= SND_SOC_DAIFMT_GATED;

	/*
	 * check "[prefix]bitclock-inversion"
	 * check "[prefix]frame-inversion"
	 * SND_SOC_DAIFMT_INV_MASK area
	 */
	snprintf(prop, sizeof(prop), "%sbitclock-inversion", prefix);
	bit = !!of_get_property(np, prop, NULL);

	snprintf(prop, sizeof(prop), "%sframe-inversion", prefix);
	frame = !!of_get_property(np, prop, NULL);

	switch ((bit << 4) + frame) {
	case 0x11:
		format |= SND_SOC_DAIFMT_IB_IF;
		break;
	case 0x10:
		format |= SND_SOC_DAIFMT_IB_NF;
		break;
	case 0x01:
		format |= SND_SOC_DAIFMT_NB_IF;
		break;
	default:
		/* SND_SOC_DAIFMT_NB_NF is default */
		break;
	}

	return format;
}
EXPORT_SYMBOL_GPL(snd_soc_daifmt_parse_format);

unsigned int snd_soc_daifmt_parse_clock_provider_raw(struct device_node *np,
						     const char *prefix,
						     struct device_node **bitclkmaster,
						     struct device_node **framemaster)
{
	char prop[128];
	unsigned int bit, frame;

	if (!prefix)
		prefix = "";

	/*
	 * check "[prefix]bitclock-master"
	 * check "[prefix]frame-master"
	 */
	snprintf(prop, sizeof(prop), "%sbitclock-master", prefix);
	bit = !!of_get_property(np, prop, NULL);
	if (bit && bitclkmaster)
		*bitclkmaster = of_parse_phandle(np, prop, 0);

	snprintf(prop, sizeof(prop), "%sframe-master", prefix);
	frame = !!of_get_property(np, prop, NULL);
	if (frame && framemaster)
		*framemaster = of_parse_phandle(np, prop, 0);

	/*
	 * return bitmap.
	 * It will be parameter of
	 *	snd_soc_daifmt_clock_provider_from_bitmap()
	 */
	return (bit << 4) + frame;
}
EXPORT_SYMBOL_GPL(snd_soc_daifmt_parse_clock_provider_raw);

unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
				     const char *prefix,
				     struct device_node **bitclkmaster,