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

Commit 435705e8 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: wm8994: Handle LRCLK inversion for WM8958 and WM1811A



On WM8958 and WM1811A separate control of the LRCLK inversion bit is
available for the DAC and ADC LRCLKs which for compatibility reasons is
done in a new register bit.

Since writes to each scheme have no effect on parts using the other just
always write to both for simplicity.

Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: default avatarVinod Koul <vinod.koul@intel.com>
Tested-by: default avatarSamreen Nilofer <samreen.nilofer@intel.com>
parent 571ab6c6
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -2668,6 +2668,10 @@
/*
/*
 * R772 (0x304) - AIF1ADC LRCLK
 * R772 (0x304) - AIF1ADC LRCLK
 */
 */
#define WM8958_AIF1_LRCLK_INV                   0x1000  /* AIF1_LRCLK_INV */
#define WM8958_AIF1_LRCLK_INV_MASK              0x1000  /* AIF1_LRCLK_INV */
#define WM8958_AIF1_LRCLK_INV_SHIFT                 12  /* AIF1_LRCLK_INV */
#define WM8958_AIF1_LRCLK_INV_WIDTH                  1  /* AIF1_LRCLK_INV */
#define WM8994_AIF1ADC_LRCLK_DIR                0x0800  /* AIF1ADC_LRCLK_DIR */
#define WM8994_AIF1ADC_LRCLK_DIR                0x0800  /* AIF1ADC_LRCLK_DIR */
#define WM8994_AIF1ADC_LRCLK_DIR_MASK           0x0800  /* AIF1ADC_LRCLK_DIR */
#define WM8994_AIF1ADC_LRCLK_DIR_MASK           0x0800  /* AIF1ADC_LRCLK_DIR */
#define WM8994_AIF1ADC_LRCLK_DIR_SHIFT              11  /* AIF1ADC_LRCLK_DIR */
#define WM8994_AIF1ADC_LRCLK_DIR_SHIFT              11  /* AIF1ADC_LRCLK_DIR */
@@ -2679,6 +2683,10 @@
/*
/*
 * R773 (0x305) - AIF1DAC LRCLK
 * R773 (0x305) - AIF1DAC LRCLK
 */
 */
#define WM8958_AIF1_LRCLK_INV                   0x1000  /* AIF1_LRCLK_INV */
#define WM8958_AIF1_LRCLK_INV_MASK              0x1000  /* AIF1_LRCLK_INV */
#define WM8958_AIF1_LRCLK_INV_SHIFT                 12  /* AIF1_LRCLK_INV */
#define WM8958_AIF1_LRCLK_INV_WIDTH                  1  /* AIF1_LRCLK_INV */
#define WM8994_AIF1DAC_LRCLK_DIR                0x0800  /* AIF1DAC_LRCLK_DIR */
#define WM8994_AIF1DAC_LRCLK_DIR                0x0800  /* AIF1DAC_LRCLK_DIR */
#define WM8994_AIF1DAC_LRCLK_DIR_MASK           0x0800  /* AIF1DAC_LRCLK_DIR */
#define WM8994_AIF1DAC_LRCLK_DIR_MASK           0x0800  /* AIF1DAC_LRCLK_DIR */
#define WM8994_AIF1DAC_LRCLK_DIR_SHIFT              11  /* AIF1DAC_LRCLK_DIR */
#define WM8994_AIF1DAC_LRCLK_DIR_SHIFT              11  /* AIF1DAC_LRCLK_DIR */
+14 −0
Original line number Original line Diff line number Diff line
@@ -2574,17 +2574,24 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
	struct wm8994 *control = wm8994->wm8994;
	struct wm8994 *control = wm8994->wm8994;
	int ms_reg;
	int ms_reg;
	int aif1_reg;
	int aif1_reg;
	int dac_reg;
	int adc_reg;
	int ms = 0;
	int ms = 0;
	int aif1 = 0;
	int aif1 = 0;
	int lrclk = 0;


	switch (dai->id) {
	switch (dai->id) {
	case 1:
	case 1:
		ms_reg = WM8994_AIF1_MASTER_SLAVE;
		ms_reg = WM8994_AIF1_MASTER_SLAVE;
		aif1_reg = WM8994_AIF1_CONTROL_1;
		aif1_reg = WM8994_AIF1_CONTROL_1;
		dac_reg = WM8994_AIF1DAC_LRCLK;
		adc_reg = WM8994_AIF1ADC_LRCLK;
		break;
		break;
	case 2:
	case 2:
		ms_reg = WM8994_AIF2_MASTER_SLAVE;
		ms_reg = WM8994_AIF2_MASTER_SLAVE;
		aif1_reg = WM8994_AIF2_CONTROL_1;
		aif1_reg = WM8994_AIF2_CONTROL_1;
		dac_reg = WM8994_AIF1DAC_LRCLK;
		adc_reg = WM8994_AIF1ADC_LRCLK;
		break;
		break;
	default:
	default:
		return -EINVAL;
		return -EINVAL;
@@ -2603,6 +2610,7 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_DSP_B:
	case SND_SOC_DAIFMT_DSP_B:
		aif1 |= WM8994_AIF1_LRCLK_INV;
		aif1 |= WM8994_AIF1_LRCLK_INV;
		lrclk |= WM8958_AIF1_LRCLK_INV;
	case SND_SOC_DAIFMT_DSP_A:
	case SND_SOC_DAIFMT_DSP_A:
		aif1 |= 0x18;
		aif1 |= 0x18;
		break;
		break;
@@ -2641,12 +2649,14 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
			break;
			break;
		case SND_SOC_DAIFMT_IB_IF:
		case SND_SOC_DAIFMT_IB_IF:
			aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
			aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
			lrclk |= WM8958_AIF1_LRCLK_INV;
			break;
			break;
		case SND_SOC_DAIFMT_IB_NF:
		case SND_SOC_DAIFMT_IB_NF:
			aif1 |= WM8994_AIF1_BCLK_INV;
			aif1 |= WM8994_AIF1_BCLK_INV;
			break;
			break;
		case SND_SOC_DAIFMT_NB_IF:
		case SND_SOC_DAIFMT_NB_IF:
			aif1 |= WM8994_AIF1_LRCLK_INV;
			aif1 |= WM8994_AIF1_LRCLK_INV;
			lrclk |= WM8958_AIF1_LRCLK_INV;
			break;
			break;
		default:
		default:
			return -EINVAL;
			return -EINVAL;
@@ -2677,6 +2687,10 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
			    aif1);
			    aif1);
	snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
	snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
			    ms);
			    ms);
	snd_soc_update_bits(codec, dac_reg,
			    WM8958_AIF1_LRCLK_INV, lrclk);
	snd_soc_update_bits(codec, adc_reg,
			    WM8958_AIF1_LRCLK_INV, lrclk);


	return 0;
	return 0;
}
}