Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c21e634 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branches 'asoc/topic/bcm2835', 'asoc/topic/cs42l56',...

Merge remote-tracking branches 'asoc/topic/bcm2835', 'asoc/topic/cs42l56', 'asoc/topic/da7213', 'asoc/topic/da7218' and 'asoc/topic/da7219' into asoc-next
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -259,6 +259,9 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream,
	case SNDRV_PCM_FORMAT_S16_LE:
		data_length = 16;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		data_length = 24;
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		data_length = 32;
		break;
@@ -273,13 +276,20 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream,
		/* otherwise calculate a fitting block ratio */
		bclk_ratio = 2 * data_length;

	/* set target clock rate*/
	/* Clock should only be set up here if CPU is clock master */
	switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
	case SND_SOC_DAIFMT_CBS_CFM:
		clk_set_rate(dev->clk, sampling_rate * bclk_ratio);
		break;
	default:
		break;
	}

	/* Setup the frame format */
	format = BCM2835_I2S_CHEN;

	if (data_length > 24)
	if (data_length >= 24)
		format |= BCM2835_I2S_CHWEX;

	format |= BCM2835_I2S_CHWID((data_length-8)&0xf);
@@ -570,6 +580,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = {
		.channels_max = 2,
		.rates =	SNDRV_PCM_RATE_8000_192000,
		.formats =	SNDRV_PCM_FMTBIT_S16_LE
				| SNDRV_PCM_FMTBIT_S24_LE
				| SNDRV_PCM_FMTBIT_S32_LE
		},
	.capture = {
@@ -577,6 +588,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = {
		.channels_max = 2,
		.rates =	SNDRV_PCM_RATE_8000_192000,
		.formats =	SNDRV_PCM_FMTBIT_S16_LE
				| SNDRV_PCM_FMTBIT_S24_LE
				| SNDRV_PCM_FMTBIT_S32_LE
		},
	.ops = &bcm2835_i2s_dai_ops,
@@ -678,6 +690,15 @@ static int bcm2835_i2s_probe(struct platform_device *pdev)
	dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2;
	dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2;

	/*
	 * Set the PACK flag to enable S16_LE support (2 S16_LE values
	 * packed into 32-bit transfers).
	 */
	dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].flags =
		SND_DMAENGINE_PCM_DAI_FLAG_PACK;
	dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].flags =
		SND_DMAENGINE_PCM_DAI_FLAG_PACK;

	/* BCLK ratio - use default */
	dev->bclk_ratio = 0;

+1 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ struct cs42l56_private {
	u8 iface;
	u8 iface_fmt;
	u8 iface_inv;
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
#if IS_ENABLED(CONFIG_INPUT)
	struct input_dev *beep;
	struct work_struct beep_work;
	int beep_rate;
+82 −17
Original line number Diff line number Diff line
@@ -725,6 +725,68 @@ static const struct snd_kcontrol_new da7213_dapm_mixoutr_controls[] = {
};


/*
 * DAPM Events
 */

static int da7213_dai_event(struct snd_soc_dapm_widget *w,
			    struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
	u8 pll_ctrl, pll_status;
	int i = 0;
	bool srm_lock = false;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		/* Enable DAI clks for master mode */
		if (da7213->master)
			snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE,
					    DA7213_DAI_CLK_EN_MASK,
					    DA7213_DAI_CLK_EN_MASK);

		/* PC synchronised to DAI */
		snd_soc_update_bits(codec, DA7213_PC_COUNT,
				    DA7213_PC_FREERUN_MASK, 0);

		/* Slave mode, if SRM not enabled no need for status checks */
		pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
		if (!(pll_ctrl & DA7213_PLL_SRM_EN))
			return 0;

		/* Check SRM has locked */
		do {
			pll_status = snd_soc_read(codec, DA7213_PLL_STATUS);
			if (pll_status & DA7219_PLL_SRM_LOCK) {
				srm_lock = true;
			} else {
				++i;
				msleep(50);
			}
		} while ((i < DA7213_SRM_CHECK_RETRIES) & (!srm_lock));

		if (!srm_lock)
			dev_warn(codec->dev, "SRM failed to lock\n");

		return 0;
	case SND_SOC_DAPM_POST_PMD:
		/* PC free-running */
		snd_soc_update_bits(codec, DA7213_PC_COUNT,
				    DA7213_PC_FREERUN_MASK,
				    DA7213_PC_FREERUN_MASK);

		/* Disable DAI clks if in master mode */
		if (da7213->master)
			snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE,
					    DA7213_DAI_CLK_EN_MASK, 0);
		return 0;
	default:
		return -EINVAL;
	}
}


/*
 * DAPM widgets
 */
@@ -736,7 +798,8 @@ static const struct snd_soc_dapm_widget da7213_dapm_widgets[] = {

	/* Use a supply here as this controls both input & output DAIs */
	SND_SOC_DAPM_SUPPLY("DAI", DA7213_DAI_CTRL, DA7213_DAI_EN_SHIFT,
			    DA7213_NO_INVERT, NULL, 0),
			    DA7213_NO_INVERT, da7213_dai_event,
			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),

	/*
	 * Input
@@ -1143,11 +1206,9 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
	/* Set master/slave mode */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		dai_clk_mode |= DA7213_DAI_CLK_EN_MASTER_MODE;
		da7213->master = true;
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		dai_clk_mode |= DA7213_DAI_CLK_EN_SLAVE_MODE;
		da7213->master = false;
		break;
	default:
@@ -1281,28 +1342,28 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
	pll_ctrl = 0;

	/* Workout input divider based on MCLK rate */
	if ((da7213->mclk_rate == 32768) && (source == DA7213_SYSCLK_PLL)) {
	if (da7213->mclk_rate == 32768) {
		/* 32KHz PLL Mode */
		indiv_bits = DA7213_PLL_INDIV_10_20_MHZ;
		indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL;
		indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ;
		indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL;
		freq_ref = 3750000;
		pll_ctrl |= DA7213_PLL_32K_MODE;
	} else {
		/* 5 - 54MHz MCLK */
		if (da7213->mclk_rate < 5000000) {
			goto pll_err;
		} else if (da7213->mclk_rate <= 10000000) {
			indiv_bits = DA7213_PLL_INDIV_5_10_MHZ;
			indiv = DA7213_PLL_INDIV_5_10_MHZ_VAL;
		} else if (da7213->mclk_rate <= 20000000) {
			indiv_bits = DA7213_PLL_INDIV_10_20_MHZ;
			indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL;
		} else if (da7213->mclk_rate <= 40000000) {
			indiv_bits = DA7213_PLL_INDIV_20_40_MHZ;
			indiv = DA7213_PLL_INDIV_20_40_MHZ_VAL;
		} else if (da7213->mclk_rate <= 9000000) {
			indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ;
			indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL;
		} else if (da7213->mclk_rate <= 18000000) {
			indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ;
			indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL;
		} else if (da7213->mclk_rate <= 36000000) {
			indiv_bits = DA7213_PLL_INDIV_18_TO_36_MHZ;
			indiv = DA7213_PLL_INDIV_18_TO_36_MHZ_VAL;
		} else if (da7213->mclk_rate <= 54000000) {
			indiv_bits = DA7213_PLL_INDIV_40_54_MHZ;
			indiv = DA7213_PLL_INDIV_40_54_MHZ_VAL;
			indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ;
			indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL;
		} else {
			goto pll_err;
		}
@@ -1547,6 +1608,10 @@ static int da7213_probe(struct snd_soc_codec *codec)
	/* Default to using SRM for slave mode */
	da7213->srm_en = true;

	/* Default PC counter to free-running */
	snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK,
			    DA7213_PC_FREERUN_MASK);

	/* Enable all Gain Ramps */
	snd_soc_update_bits(codec, DA7213_AUX_L_CTRL,
			    DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
+20 −15
Original line number Diff line number Diff line
@@ -142,6 +142,9 @@
 * Bit fields
 */

/* DA7213_PLL_STATUS = 0x03 */
#define DA7219_PLL_SRM_LOCK					(0x1 << 1)

/* DA7213_SR = 0x22 */
#define DA7213_SR_8000						(0x1 << 0)
#define DA7213_SR_11025						(0x2 << 0)
@@ -160,10 +163,10 @@
#define DA7213_VMID_EN						(0x1 << 7)

/* DA7213_PLL_CTRL = 0x27 */
#define DA7213_PLL_INDIV_5_10_MHZ				(0x0 << 2)
#define DA7213_PLL_INDIV_10_20_MHZ				(0x1 << 2)
#define DA7213_PLL_INDIV_20_40_MHZ				(0x2 << 2)
#define DA7213_PLL_INDIV_40_54_MHZ				(0x3 << 2)
#define DA7213_PLL_INDIV_5_TO_9_MHZ				(0x0 << 2)
#define DA7213_PLL_INDIV_9_TO_18_MHZ				(0x1 << 2)
#define DA7213_PLL_INDIV_18_TO_36_MHZ				(0x2 << 2)
#define DA7213_PLL_INDIV_36_TO_54_MHZ				(0x3 << 2)
#define DA7213_PLL_INDIV_MASK					(0x3 << 2)
#define DA7213_PLL_MCLK_SQR_EN					(0x1 << 4)
#define DA7213_PLL_32K_MODE					(0x1 << 5)
@@ -178,8 +181,6 @@
#define DA7213_DAI_BCLKS_PER_WCLK_MASK				(0x3 << 0)
#define DA7213_DAI_CLK_POL_INV					(0x1 << 2)
#define DA7213_DAI_WCLK_POL_INV					(0x1 << 3)
#define DA7213_DAI_CLK_EN_SLAVE_MODE				(0x0 << 7)
#define DA7213_DAI_CLK_EN_MASTER_MODE				(0x1 << 7)
#define DA7213_DAI_CLK_EN_MASK					(0x1 << 7)

/* DA7213_DAI_CTRL = 0x29 */
@@ -412,6 +413,9 @@
#define DA7213_DMIC_CLK_RATE_SHIFT				2
#define DA7213_DMIC_CLK_RATE_MASK				(0x1 << 2)

/* DA7213_PC_COUNT = 0x94 */
#define DA7213_PC_FREERUN_MASK					(0x1 << 0)

/* DA7213_DIG_CTRL = 0x99 */
#define DA7213_DAC_L_INV_SHIFT					3
#define DA7213_DAC_R_INV_SHIFT					7
@@ -500,10 +504,11 @@
#define DA7213_PLL_FREQ_OUT_90316800		90316800
#define DA7213_PLL_FREQ_OUT_98304000		98304000
#define DA7213_PLL_FREQ_OUT_94310400		94310400
#define DA7213_PLL_INDIV_5_10_MHZ_VAL	2
#define DA7213_PLL_INDIV_10_20_MHZ_VAL	4
#define DA7213_PLL_INDIV_20_40_MHZ_VAL	8
#define DA7213_PLL_INDIV_40_54_MHZ_VAL	16
#define DA7213_PLL_INDIV_5_TO_9_MHZ_VAL		2
#define DA7213_PLL_INDIV_9_TO_18_MHZ_VAL	4
#define DA7213_PLL_INDIV_18_TO_36_MHZ_VAL	8
#define DA7213_PLL_INDIV_36_TO_54_MHZ_VAL	16
#define DA7213_SRM_CHECK_RETRIES		8

enum da7213_clk_src {
	DA7213_CLKSRC_MCLK = 0,
+16 −16
Original line number Diff line number Diff line
@@ -1868,27 +1868,27 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,

	/* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */
	if (da7218->mclk_rate == 32768) {
		indiv_bits = DA7218_PLL_INDIV_2_5_MHZ;
		indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL;
		indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ;
		indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL;
	} else if (da7218->mclk_rate < 2000000) {
		dev_err(codec->dev, "PLL input clock %d below valid range\n",
			da7218->mclk_rate);
		return -EINVAL;
	} else if (da7218->mclk_rate <= 5000000) {
		indiv_bits = DA7218_PLL_INDIV_2_5_MHZ;
		indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL;
	} else if (da7218->mclk_rate <= 10000000) {
		indiv_bits = DA7218_PLL_INDIV_5_10_MHZ;
		indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL;
	} else if (da7218->mclk_rate <= 20000000) {
		indiv_bits = DA7218_PLL_INDIV_10_20_MHZ;
		indiv = DA7218_PLL_INDIV_10_20_MHZ_VAL;
	} else if (da7218->mclk_rate <= 40000000) {
		indiv_bits = DA7218_PLL_INDIV_20_40_MHZ;
		indiv = DA7218_PLL_INDIV_20_40_MHZ_VAL;
	} else if (da7218->mclk_rate <= 4500000) {
		indiv_bits = DA7218_PLL_INDIV_2_TO_4_5_MHZ;
		indiv = DA7218_PLL_INDIV_2_TO_4_5_MHZ_VAL;
	} else if (da7218->mclk_rate <= 9000000) {
		indiv_bits = DA7218_PLL_INDIV_4_5_TO_9_MHZ;
		indiv = DA7218_PLL_INDIV_4_5_TO_9_MHZ_VAL;
	} else if (da7218->mclk_rate <= 18000000) {
		indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ;
		indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL;
	} else if (da7218->mclk_rate <= 36000000) {
		indiv_bits = DA7218_PLL_INDIV_18_TO_36_MHZ;
		indiv = DA7218_PLL_INDIV_18_TO_36_MHZ_VAL;
	} else if (da7218->mclk_rate <= 54000000) {
		indiv_bits = DA7218_PLL_INDIV_40_54_MHZ;
		indiv = DA7218_PLL_INDIV_40_54_MHZ_VAL;
		indiv_bits = DA7218_PLL_INDIV_36_TO_54_MHZ;
		indiv = DA7218_PLL_INDIV_36_TO_54_MHZ_VAL;
	} else {
		dev_err(codec->dev, "PLL input clock %d above valid range\n",
			da7218->mclk_rate);
Loading