Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Tested-by: Samreen Nilofer <samreen.nilofer@intel.com>

+22
+8
include/linux/mfd/wm8994/registers.h
··· 2668 2668 /* 2669 2669 * R772 (0x304) - AIF1ADC LRCLK 2670 2670 */ 2671 + #define WM8958_AIF1_LRCLK_INV 0x1000 /* AIF1_LRCLK_INV */ 2672 + #define WM8958_AIF1_LRCLK_INV_MASK 0x1000 /* AIF1_LRCLK_INV */ 2673 + #define WM8958_AIF1_LRCLK_INV_SHIFT 12 /* AIF1_LRCLK_INV */ 2674 + #define WM8958_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */ 2671 2675 #define WM8994_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */ 2672 2676 #define WM8994_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */ 2673 2677 #define WM8994_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */ ··· 2683 2679 /* 2684 2680 * R773 (0x305) - AIF1DAC LRCLK 2685 2681 */ 2682 + #define WM8958_AIF1_LRCLK_INV 0x1000 /* AIF1_LRCLK_INV */ 2683 + #define WM8958_AIF1_LRCLK_INV_MASK 0x1000 /* AIF1_LRCLK_INV */ 2684 + #define WM8958_AIF1_LRCLK_INV_SHIFT 12 /* AIF1_LRCLK_INV */ 2685 + #define WM8958_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */ 2686 2686 #define WM8994_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */ 2687 2687 #define WM8994_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */ 2688 2688 #define WM8994_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */
+14
sound/soc/codecs/wm8994.c
··· 2574 2574 struct wm8994 *control = wm8994->wm8994; 2575 2575 int ms_reg; 2576 2576 int aif1_reg; 2577 + int dac_reg; 2578 + int adc_reg; 2577 2579 int ms = 0; 2578 2580 int aif1 = 0; 2581 + int lrclk = 0; 2579 2582 2580 2583 switch (dai->id) { 2581 2584 case 1: 2582 2585 ms_reg = WM8994_AIF1_MASTER_SLAVE; 2583 2586 aif1_reg = WM8994_AIF1_CONTROL_1; 2587 + dac_reg = WM8994_AIF1DAC_LRCLK; 2588 + adc_reg = WM8994_AIF1ADC_LRCLK; 2584 2589 break; 2585 2590 case 2: 2586 2591 ms_reg = WM8994_AIF2_MASTER_SLAVE; 2587 2592 aif1_reg = WM8994_AIF2_CONTROL_1; 2593 + dac_reg = WM8994_AIF1DAC_LRCLK; 2594 + adc_reg = WM8994_AIF1ADC_LRCLK; 2588 2595 break; 2589 2596 default: 2590 2597 return -EINVAL; ··· 2610 2603 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 2611 2604 case SND_SOC_DAIFMT_DSP_B: 2612 2605 aif1 |= WM8994_AIF1_LRCLK_INV; 2606 + lrclk |= WM8958_AIF1_LRCLK_INV; 2613 2607 case SND_SOC_DAIFMT_DSP_A: 2614 2608 aif1 |= 0x18; 2615 2609 break; ··· 2649 2641 break; 2650 2642 case SND_SOC_DAIFMT_IB_IF: 2651 2643 aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV; 2644 + lrclk |= WM8958_AIF1_LRCLK_INV; 2652 2645 break; 2653 2646 case SND_SOC_DAIFMT_IB_NF: 2654 2647 aif1 |= WM8994_AIF1_BCLK_INV; 2655 2648 break; 2656 2649 case SND_SOC_DAIFMT_NB_IF: 2657 2650 aif1 |= WM8994_AIF1_LRCLK_INV; 2651 + lrclk |= WM8958_AIF1_LRCLK_INV; 2658 2652 break; 2659 2653 default: 2660 2654 return -EINVAL; ··· 2687 2677 aif1); 2688 2678 snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR, 2689 2679 ms); 2680 + snd_soc_update_bits(codec, dac_reg, 2681 + WM8958_AIF1_LRCLK_INV, lrclk); 2682 + snd_soc_update_bits(codec, adc_reg, 2683 + WM8958_AIF1_LRCLK_INV, lrclk); 2690 2684 2691 2685 return 0; 2692 2686 }