Unverified Commit d3d8fead authored by Mark Brown's avatar Mark Brown
Browse files

Specify clock provider directly to CPU DAIs

Merge series from Charles Keepax <ckeepax@opensource.cirrus.com>:

Currently the set_fmt callback always passes clock provider/consumer
with respect to the CODEC. This made sense when the framework was
directly broken down into platforms and CODECs. However, as things
are now broken down into components which can be connected as either
the CPU or CODEC side of a DAI link it simplifies things if each
side of the link is just told if it is provider or consumer of the
clocks. Making this change allows us to remove one of the last parts
of the ASoC core that needs to know if a driver is a CODEC driver,
where it flips the clock format specifier if a CODEC driver is used on
the CPU side of a DAI link, as well as just being conceptually more
consistent with componentisation.

The basic idea of this patch chain is to change the set_fmt callback
from specifying if the CODEC is provider/consumer into directly
specifying if the component is provider/consumer. To do this we add
some new defines, and then to preserve bisectability, the migration is
done by adding a new callback, converting over all existing CPU side
drivers, converting the core, and then finally reverting back to the
old callback.

Converting the platform drivers makes sense as the existing defines
are from the perspective of the CODEC and there are more CODEC drivers
than platform drivers.

Obviously a fair amount of this patch chain I was only able to build
test, so any testing that can be done would be greatly appreciated.
parents ff87d619 28086d05
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -348,11 +348,6 @@ static inline int snd_soc_component_cache_sync(
	return regcache_sync(component->regmap);
}

static inline int snd_soc_component_is_codec(struct snd_soc_component *component)
{
	return component->driver->non_legacy_dai_naming;
}

void snd_soc_component_set_aux(struct snd_soc_component *component,
			       struct snd_soc_aux_dev *aux);
int snd_soc_component_init(struct snd_soc_component *component);
+6 −0
Original line number Diff line number Diff line
@@ -124,6 +124,12 @@ struct snd_compr_stream;
#define SND_SOC_DAIFMT_CBM_CFS		SND_SOC_DAIFMT_CBP_CFC
#define SND_SOC_DAIFMT_CBS_CFS		SND_SOC_DAIFMT_CBC_CFC

/* when passed to set_fmt directly indicate if the device is provider or consumer */
#define SND_SOC_DAIFMT_BP_FP		SND_SOC_DAIFMT_CBP_CFP
#define SND_SOC_DAIFMT_BC_FP		SND_SOC_DAIFMT_CBC_CFP
#define SND_SOC_DAIFMT_BP_FC		SND_SOC_DAIFMT_CBP_CFC
#define SND_SOC_DAIFMT_BC_FC		SND_SOC_DAIFMT_CBC_CFC

/* Describes the possible PCM format */
#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT	48
#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_MASK	(0xFFFFULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
+2 −2
Original line number Diff line number Diff line
@@ -37,10 +37,10 @@ static int acp5x_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
	}
	mode = fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
	switch (mode) {
	case SND_SOC_DAIFMT_CBC_CFC:
	case SND_SOC_DAIFMT_BP_FP:
		adata->master_mode = I2S_MASTER_MODE_ENABLE;
		break;
	case SND_SOC_DAIFMT_CBP_CFP:
	case SND_SOC_DAIFMT_BC_FC:
		adata->master_mode = I2S_MASTER_MODE_DISABLE;
		break;
	}
+2 −2
Original line number Diff line number Diff line
@@ -343,7 +343,7 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
	}

	switch (dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_CBC_CFC:
	case SND_SOC_DAIFMT_BP_FP:
		/* codec is slave, so cpu is master */
		mr |= ATMEL_I2SC_MR_MODE_MASTER;
		ret = atmel_i2s_get_gck_param(dev, params_rate(params));
@@ -351,7 +351,7 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
			return ret;
		break;

	case SND_SOC_DAIFMT_CBP_CFP:
	case SND_SOC_DAIFMT_BC_FC:
		/* codec is master, so cpu is slave */
		mr |= ATMEL_I2SC_MR_MODE_SLAVE;
		dev->gck_param = NULL;
+9 −9
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@ static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params,
		return frame_size;

	switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_CBP_CFC:
	case SND_SOC_DAIFMT_BC_FP:
		if ((ssc_p->dir_mask & SSC_DIR_MASK_CAPTURE)
		    && ssc->clk_from_rk_pin)
			/* Receiver Frame Synchro (i.e. capture)
@@ -220,7 +220,7 @@ static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params,
			mck_div = 3;
		break;

	case SND_SOC_DAIFMT_CBP_CFP:
	case SND_SOC_DAIFMT_BC_FC:
		if ((ssc_p->dir_mask & SSC_DIR_MASK_PLAYBACK)
		    && !ssc->clk_from_rk_pin)
			/* Transmit Frame Synchro (i.e. playback)
@@ -233,7 +233,7 @@ static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params,
	}

	switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_CBC_CFC:
	case SND_SOC_DAIFMT_BP_FP:
		r.num = ssc_p->mck_rate / mck_div / frame_size;

		ret = snd_interval_ratnum(i, 1, &r, &num, &den);
@@ -243,8 +243,8 @@ static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params,
		}
		break;

	case SND_SOC_DAIFMT_CBP_CFC:
	case SND_SOC_DAIFMT_CBP_CFP:
	case SND_SOC_DAIFMT_BC_FP:
	case SND_SOC_DAIFMT_BC_FC:
		t.min = 8000;
		t.max = ssc_p->mck_rate / mck_div / frame_size;
		t.openmin = t.openmax = 0;
@@ -433,8 +433,8 @@ static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
static int atmel_ssc_cfs(struct atmel_ssc_info *ssc_p)
{
	switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_CBP_CFC:
	case SND_SOC_DAIFMT_CBC_CFC:
	case SND_SOC_DAIFMT_BC_FP:
	case SND_SOC_DAIFMT_BP_FP:
		return 1;
	}
	return 0;
@@ -444,8 +444,8 @@ static int atmel_ssc_cfs(struct atmel_ssc_info *ssc_p)
static int atmel_ssc_cbs(struct atmel_ssc_info *ssc_p)
{
	switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_CBC_CFP:
	case SND_SOC_DAIFMT_CBC_CFC:
	case SND_SOC_DAIFMT_BP_FC:
	case SND_SOC_DAIFMT_BP_FP:
		return 1;
	}
	return 0;
Loading