From b22da3d8526a935aa31e086e63f60ff3246cb61c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 07:24:11 +0000
Subject: [PATCH] add stmac read mac form eeprom
---
kernel/sound/soc/codecs/wm8994.c | 301 ++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 233 insertions(+), 68 deletions(-)
diff --git a/kernel/sound/soc/codecs/wm8994.c b/kernel/sound/soc/codecs/wm8994.c
index e3e0692..f578841 100644
--- a/kernel/sound/soc/codecs/wm8994.c
+++ b/kernel/sound/soc/codecs/wm8994.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* wm8994.c -- WM8994 ALSA SoC Audio driver
*
* Copyright 2009-12 Wolfson Microelectronics plc
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/module.h>
@@ -47,10 +43,12 @@
#define WM8994_NUM_DRC 3
#define WM8994_NUM_EQ 3
-static struct {
+struct wm8994_reg_mask {
unsigned int reg;
unsigned int mask;
-} wm8994_vu_bits[] = {
+};
+
+static struct wm8994_reg_mask wm8994_vu_bits[] = {
{ WM8994_LEFT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU },
{ WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU },
{ WM8994_LEFT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU },
@@ -64,20 +62,24 @@
{ WM8994_AIF1_DAC1_LEFT_VOLUME, WM8994_AIF1DAC1_VU },
{ WM8994_AIF1_DAC1_RIGHT_VOLUME, WM8994_AIF1DAC1_VU },
- { WM8994_AIF1_DAC2_LEFT_VOLUME, WM8994_AIF1DAC2_VU },
- { WM8994_AIF1_DAC2_RIGHT_VOLUME, WM8994_AIF1DAC2_VU },
{ WM8994_AIF2_DAC_LEFT_VOLUME, WM8994_AIF2DAC_VU },
{ WM8994_AIF2_DAC_RIGHT_VOLUME, WM8994_AIF2DAC_VU },
{ WM8994_AIF1_ADC1_LEFT_VOLUME, WM8994_AIF1ADC1_VU },
{ WM8994_AIF1_ADC1_RIGHT_VOLUME, WM8994_AIF1ADC1_VU },
- { WM8994_AIF1_ADC2_LEFT_VOLUME, WM8994_AIF1ADC2_VU },
- { WM8994_AIF1_ADC2_RIGHT_VOLUME, WM8994_AIF1ADC2_VU },
{ WM8994_AIF2_ADC_LEFT_VOLUME, WM8994_AIF2ADC_VU },
{ WM8994_AIF2_ADC_RIGHT_VOLUME, WM8994_AIF1ADC2_VU },
{ WM8994_DAC1_LEFT_VOLUME, WM8994_DAC1_VU },
{ WM8994_DAC1_RIGHT_VOLUME, WM8994_DAC1_VU },
{ WM8994_DAC2_LEFT_VOLUME, WM8994_DAC2_VU },
{ WM8994_DAC2_RIGHT_VOLUME, WM8994_DAC2_VU },
+};
+
+/* VU bitfields for ADC2, DAC2 not available on WM1811 */
+static struct wm8994_reg_mask wm8994_adc2_dac2_vu_bits[] = {
+ { WM8994_AIF1_DAC2_LEFT_VOLUME, WM8994_AIF1DAC2_VU },
+ { WM8994_AIF1_DAC2_RIGHT_VOLUME, WM8994_AIF1DAC2_VU },
+ { WM8994_AIF1_ADC2_LEFT_VOLUME, WM8994_AIF1ADC2_VU },
+ { WM8994_AIF1_ADC2_RIGHT_VOLUME, WM8994_AIF1ADC2_VU },
};
static int wm8994_drc_base[] = {
@@ -117,7 +119,7 @@
idle = !wm8994->jack_mic;
- sysclk = snd_soc_component_read32(component, WM8994_CLOCKING_1);
+ sysclk = snd_soc_component_read(component, WM8994_CLOCKING_1);
if (sysclk & WM8994_SYSCLK_SRC)
sysclk = wm8994->aifclk[1];
else
@@ -171,12 +173,12 @@
switch (wm8994->sysclk[aif]) {
case WM8994_SYSCLK_MCLK1:
- rate = wm8994->mclk[0];
+ rate = wm8994->mclk_rate[0];
break;
case WM8994_SYSCLK_MCLK2:
reg1 |= 0x8;
- rate = wm8994->mclk[1];
+ rate = wm8994->mclk_rate[1];
break;
case WM8994_SYSCLK_FLL1:
@@ -251,7 +253,7 @@
struct snd_soc_dapm_widget *sink)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
- int reg = snd_soc_component_read32(component, WM8994_CLOCKING_1);
+ int reg = snd_soc_component_read(component, WM8994_CLOCKING_1);
const char *clk;
/* Check what we're currently using for CLK_SYS */
@@ -289,7 +291,6 @@
static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
-static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0);
#define WM8994_DRC_SWITCH(xname, reg, shift) \
SOC_SINGLE_EXT(xname, reg, shift, 1, 0, \
@@ -310,7 +311,7 @@
else
mask = WM8994_AIF1DAC1_DRC_ENA_MASK;
- ret = snd_soc_component_read32(component, mc->reg);
+ ret = snd_soc_component_read(component, mc->reg);
if (ret < 0)
return ret;
if (ret & mask)
@@ -329,7 +330,7 @@
int save, i;
/* Save any enables; the configuration should clear them. */
- save = snd_soc_component_read32(component, base);
+ save = snd_soc_component_read(component, base);
save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
WM8994_AIF1ADC1R_DRC_ENA;
@@ -439,7 +440,7 @@
/* The EQ will be disabled while reconfiguring it, remember the
* current configuration.
*/
- save = snd_soc_component_read32(component, base);
+ save = snd_soc_component_read(component, base);
save &= WM8994_AIF1DAC1_EQ_ENA;
for (i = 0; i < WM8994_EQ_REGS; i++)
@@ -737,13 +738,6 @@
7, 1, ng_tlv),
};
-static const struct snd_kcontrol_new wm1811_snd_controls[] = {
-SOC_SINGLE_TLV("MIXINL IN1LP Boost Volume", WM8994_INPUT_MIXER_1, 7, 1, 0,
- mixin_boost_tlv),
-SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0,
- mixin_boost_tlv),
-};
-
/* We run all mode setting through a function to enforce audio mode */
static void wm1811_jackdet_set_mode(struct snd_soc_component *component, u16 mode)
{
@@ -865,7 +859,7 @@
switch (wm8994->vmid_mode) {
default:
WARN_ON(NULL == "Invalid VMID mode");
- /* fall through */
+ fallthrough;
case WM8994_VMID_NORMAL:
/* Startup bias, VMID ramp & buffer */
snd_soc_component_update_bits(component, WM8994_ANTIPOP_2,
@@ -1010,7 +1004,7 @@
int reg, reg_r;
/* We also need the same AIF source for L/R and only one path */
- reg = snd_soc_component_read32(component, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ reg = snd_soc_component_read(component, WM8994_DAC1_LEFT_MIXER_ROUTING);
switch (reg) {
case WM8994_AIF2DACL_TO_DAC1L:
dev_vdbg(component->dev, "Class W source AIF2DAC\n");
@@ -1029,7 +1023,7 @@
return false;
}
- reg_r = snd_soc_component_read32(component, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ reg_r = snd_soc_component_read(component, WM8994_DAC1_RIGHT_MIXER_ROUTING);
if (reg_r != reg) {
dev_vdbg(component->dev, "Left and right DAC mixers different\n");
return false;
@@ -1042,6 +1036,65 @@
return true;
}
+static void wm8994_update_vu_bits(struct snd_soc_component *component)
+{
+ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
+ struct wm8994 *control = wm8994->wm8994;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
+ snd_soc_component_write(component, wm8994_vu_bits[i].reg,
+ snd_soc_component_read(component,
+ wm8994_vu_bits[i].reg));
+ if (control->type == WM1811)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(wm8994_adc2_dac2_vu_bits); i++)
+ snd_soc_component_write(component,
+ wm8994_adc2_dac2_vu_bits[i].reg,
+ snd_soc_component_read(component,
+ wm8994_adc2_dac2_vu_bits[i].reg));
+}
+
+static int aif_mclk_set(struct snd_soc_component *component, int aif, bool enable)
+{
+ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
+ unsigned int offset, val, clk_idx;
+ int ret;
+
+ if (aif)
+ offset = 4;
+ else
+ offset = 0;
+
+ val = snd_soc_component_read(component, WM8994_AIF1_CLOCKING_1 + offset);
+ val &= WM8994_AIF1CLK_SRC_MASK;
+
+ switch (val) {
+ case 0:
+ clk_idx = WM8994_MCLK1;
+ break;
+ case 1:
+ clk_idx = WM8994_MCLK2;
+ break;
+ default:
+ return 0;
+ }
+
+ if (enable) {
+ ret = clk_prepare_enable(wm8994->mclk[clk_idx].clk);
+ if (ret < 0) {
+ dev_err(component->dev, "Failed to enable MCLK%d\n",
+ clk_idx);
+ return ret;
+ }
+ } else {
+ clk_disable_unprepare(wm8994->mclk[clk_idx].clk);
+ }
+
+ return 0;
+}
+
static int aif1clk_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -1049,7 +1102,7 @@
struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
struct wm8994 *control = wm8994->wm8994;
int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
- int i;
+ int ret;
int dac;
int adc;
int val;
@@ -1065,11 +1118,15 @@
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ ret = aif_mclk_set(component, 0, true);
+ if (ret < 0)
+ return ret;
+
/* Don't enable timeslot 2 if not in use */
if (wm8994->channels[0] <= 2)
mask &= ~(WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
- val = snd_soc_component_read32(component, WM8994_AIF1_CONTROL_1);
+ val = snd_soc_component_read(component, WM8994_AIF1_CONTROL_1);
if ((val & WM8994_AIF1ADCL_SRC) &&
(val & WM8994_AIF1ADCR_SRC))
adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA;
@@ -1080,7 +1137,7 @@
adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA |
WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA;
- val = snd_soc_component_read32(component, WM8994_AIF1_CONTROL_2);
+ val = snd_soc_component_read(component, WM8994_AIF1_CONTROL_2);
if ((val & WM8994_AIF1DACL_SRC) &&
(val & WM8994_AIF1DACR_SRC))
dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA;
@@ -1113,10 +1170,7 @@
break;
case SND_SOC_DAPM_POST_PMU:
- for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
- snd_soc_component_write(component, wm8994_vu_bits[i].reg,
- snd_soc_component_read32(component,
- wm8994_vu_bits[i].reg));
+ wm8994_update_vu_bits(component);
break;
case SND_SOC_DAPM_PRE_PMD:
@@ -1126,7 +1180,7 @@
snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_4,
mask, 0);
- val = snd_soc_component_read32(component, WM8994_CLOCKING_1);
+ val = snd_soc_component_read(component, WM8994_CLOCKING_1);
if (val & WM8994_AIF2DSPCLK_ENA)
val = WM8994_SYSDSPCLK_ENA;
else
@@ -1137,6 +1191,12 @@
break;
}
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ aif_mclk_set(component, 0, false);
+ break;
+ }
+
return 0;
}
@@ -1144,14 +1204,18 @@
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
- int i;
+ int ret;
int dac;
int adc;
int val;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- val = snd_soc_component_read32(component, WM8994_AIF2_CONTROL_1);
+ ret = aif_mclk_set(component, 1, true);
+ if (ret < 0)
+ return ret;
+
+ val = snd_soc_component_read(component, WM8994_AIF2_CONTROL_1);
if ((val & WM8994_AIF2ADCL_SRC) &&
(val & WM8994_AIF2ADCR_SRC))
adc = WM8994_AIF2ADCR_ENA;
@@ -1162,7 +1226,7 @@
adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA;
- val = snd_soc_component_read32(component, WM8994_AIF2_CONTROL_2);
+ val = snd_soc_component_read(component, WM8994_AIF2_CONTROL_2);
if ((val & WM8994_AIF2DACL_SRC) &&
(val & WM8994_AIF2DACR_SRC))
dac = WM8994_AIF2DACR_ENA;
@@ -1196,10 +1260,7 @@
break;
case SND_SOC_DAPM_POST_PMU:
- for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
- snd_soc_component_write(component, wm8994_vu_bits[i].reg,
- snd_soc_component_read32(component,
- wm8994_vu_bits[i].reg));
+ wm8994_update_vu_bits(component);
break;
case SND_SOC_DAPM_PRE_PMD:
@@ -1211,7 +1272,7 @@
WM8994_AIF2ADCL_ENA |
WM8994_AIF2ADCR_ENA, 0);
- val = snd_soc_component_read32(component, WM8994_CLOCKING_1);
+ val = snd_soc_component_read(component, WM8994_CLOCKING_1);
if (val & WM8994_AIF1DSPCLK_ENA)
val = WM8994_SYSDSPCLK_ENA;
else
@@ -1219,6 +1280,12 @@
snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
WM8994_SYSDSPCLK_ENA |
WM8994_AIF2DSPCLK_ENA, val);
+ break;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ aif_mclk_set(component, 1, false);
break;
}
@@ -1382,7 +1449,7 @@
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
dev_dbg(component->dev, "SRC status: %x\n",
- snd_soc_component_read32(component,
+ snd_soc_component_read(component,
WM8994_RATE_STATUS));
return 0;
}
@@ -1627,10 +1694,10 @@
static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
@@ -2145,6 +2212,7 @@
u16 reg, clk1, aif_reg, aif_src;
unsigned long timeout;
bool was_enabled;
+ struct clk *mclk;
switch (id) {
case WM8994_FLL1:
@@ -2161,7 +2229,7 @@
return -EINVAL;
}
- reg = snd_soc_component_read32(component, WM8994_FLL1_CONTROL_1 + reg_offset);
+ reg = snd_soc_component_read(component, WM8994_FLL1_CONTROL_1 + reg_offset);
was_enabled = reg & WM8994_FLL1_ENA;
switch (src) {
@@ -2202,12 +2270,12 @@
return ret;
/* Make sure that we're not providing SYSCLK right now */
- clk1 = snd_soc_component_read32(component, WM8994_CLOCKING_1);
+ clk1 = snd_soc_component_read(component, WM8994_CLOCKING_1);
if (clk1 & WM8994_SYSCLK_SRC)
aif_reg = WM8994_AIF2_CLOCKING_1;
else
aif_reg = WM8994_AIF1_CLOCKING_1;
- reg = snd_soc_component_read32(component, aif_reg);
+ reg = snd_soc_component_read(component, aif_reg);
if ((reg & WM8994_AIF1CLK_ENA) &&
(reg & WM8994_AIF1CLK_SRC_MASK) == aif_src) {
@@ -2219,6 +2287,27 @@
/* We always need to disable the FLL while reconfiguring */
snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_1 + reg_offset,
WM8994_FLL1_ENA, 0);
+
+ /* Disable MCLK if needed before we possibly change to new clock parent */
+ if (was_enabled) {
+ reg = snd_soc_component_read(component, WM8994_FLL1_CONTROL_5
+ + reg_offset);
+ reg = ((reg & WM8994_FLL1_REFCLK_SRC_MASK)
+ >> WM8994_FLL1_REFCLK_SRC_SHIFT) + 1;
+
+ switch (reg) {
+ case WM8994_FLL_SRC_MCLK1:
+ mclk = wm8994->mclk[WM8994_MCLK1].clk;
+ break;
+ case WM8994_FLL_SRC_MCLK2:
+ mclk = wm8994->mclk[WM8994_MCLK2].clk;
+ break;
+ default:
+ mclk = NULL;
+ }
+
+ clk_disable_unprepare(mclk);
+ }
if (wm8994->fll_byp && src == WM8994_FLL_SRC_BCLK &&
freq_in == freq_out && freq_out) {
@@ -2264,10 +2353,29 @@
/* Clear any pending completion from a previous failure */
try_wait_for_completion(&wm8994->fll_locked[id]);
+ switch (src) {
+ case WM8994_FLL_SRC_MCLK1:
+ mclk = wm8994->mclk[WM8994_MCLK1].clk;
+ break;
+ case WM8994_FLL_SRC_MCLK2:
+ mclk = wm8994->mclk[WM8994_MCLK2].clk;
+ break;
+ default:
+ mclk = NULL;
+ }
+
/* Enable (with fractional mode if required) */
if (freq_out) {
+ ret = clk_prepare_enable(mclk);
+ if (ret < 0) {
+ dev_err(component->dev, "Failed to enable MCLK for FLL%d\n",
+ id + 1);
+ return ret;
+ }
+
/* Enable VMID if we need it */
if (!was_enabled) {
+
active_reference(component);
switch (control->type) {
@@ -2335,9 +2443,9 @@
if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) {
dev_dbg(component->dev, "Configuring AIFs for 128fs\n");
- wm8994->aifdiv[0] = snd_soc_component_read32(component, WM8994_AIF1_RATE)
+ wm8994->aifdiv[0] = snd_soc_component_read(component, WM8994_AIF1_RATE)
& WM8994_AIF1CLK_RATE_MASK;
- wm8994->aifdiv[1] = snd_soc_component_read32(component, WM8994_AIF2_RATE)
+ wm8994->aifdiv[1] = snd_soc_component_read(component, WM8994_AIF2_RATE)
& WM8994_AIF1CLK_RATE_MASK;
snd_soc_component_update_bits(component, WM8994_AIF1_RATE,
@@ -2376,12 +2484,29 @@
return _wm8994_set_fll(dai->component, id, src, freq_in, freq_out);
}
+static int wm8994_set_mclk_rate(struct wm8994_priv *wm8994, unsigned int id,
+ unsigned int *freq)
+{
+ int ret;
+
+ if (!wm8994->mclk[id].clk || *freq == wm8994->mclk_rate[id])
+ return 0;
+
+ ret = clk_set_rate(wm8994->mclk[id].clk, *freq);
+ if (ret < 0)
+ return ret;
+
+ *freq = clk_get_rate(wm8994->mclk[id].clk);
+
+ return 0;
+}
+
static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_component *component = dai->component;
struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
- int i;
+ int ret, i;
switch (dai->id) {
case 1:
@@ -2396,7 +2521,12 @@
switch (clk_id) {
case WM8994_SYSCLK_MCLK1:
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
- wm8994->mclk[0] = freq;
+
+ ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq);
+ if (ret < 0)
+ return ret;
+
+ wm8994->mclk_rate[0] = freq;
dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
dai->id, freq);
break;
@@ -2404,7 +2534,12 @@
case WM8994_SYSCLK_MCLK2:
/* TODO: Set GPIO AF */
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
- wm8994->mclk[1] = freq;
+
+ ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq);
+ if (ret < 0)
+ return ret;
+
+ wm8994->mclk_rate[1] = freq;
dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
dai->id, freq);
break;
@@ -2452,9 +2587,9 @@
if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) {
dev_dbg(component->dev, "Configuring AIFs for 128fs\n");
- wm8994->aifdiv[0] = snd_soc_component_read32(component, WM8994_AIF1_RATE)
+ wm8994->aifdiv[0] = snd_soc_component_read(component, WM8994_AIF1_RATE)
& WM8994_AIF1CLK_RATE_MASK;
- wm8994->aifdiv[1] = snd_soc_component_read32(component, WM8994_AIF2_RATE)
+ wm8994->aifdiv[1] = snd_soc_component_read(component, WM8994_AIF2_RATE)
& WM8994_AIF1CLK_RATE_MASK;
snd_soc_component_update_bits(component, WM8994_AIF1_RATE,
@@ -2661,7 +2796,7 @@
case SND_SOC_DAIFMT_DSP_B:
aif1 |= WM8994_AIF1_LRCLK_INV;
lrclk |= WM8958_AIF1_LRCLK_INV;
- /* fall through */
+ fallthrough;
case SND_SOC_DAIFMT_DSP_A:
aif1 |= 0x18;
break;
@@ -2876,7 +3011,7 @@
dai->id, wm8994->aifclk[id], bclk_rate);
if (wm8994->channels[id] == 1 &&
- (snd_soc_component_read32(component, aif1_reg) & 0x18) == 0x18)
+ (snd_soc_component_read(component, aif1_reg) & 0x18) == 0x18)
aif2 |= WM8994_AIF1_MONO;
if (wm8994->aifclk[id] == 0) {
@@ -2995,7 +3130,8 @@
return snd_soc_component_update_bits(component, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
}
-static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
+static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute,
+ int direction)
{
struct snd_soc_component *component = codec_dai->component;
int mute_reg;
@@ -3072,18 +3208,20 @@
.set_sysclk = wm8994_set_dai_sysclk,
.set_fmt = wm8994_set_dai_fmt,
.hw_params = wm8994_hw_params,
- .digital_mute = wm8994_aif_mute,
+ .mute_stream = wm8994_aif_mute,
.set_pll = wm8994_set_fll,
.set_tristate = wm8994_set_tristate,
+ .no_capture_mute = 1,
};
static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
.set_sysclk = wm8994_set_dai_sysclk,
.set_fmt = wm8994_set_dai_fmt,
.hw_params = wm8994_hw_params,
- .digital_mute = wm8994_aif_mute,
+ .mute_stream = wm8994_aif_mute,
.set_pll = wm8994_set_fll,
.set_tristate = wm8994_set_tristate,
+ .no_capture_mute = 1,
};
static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
@@ -3684,7 +3822,7 @@
mutex_lock(&wm8994->accdet_lock);
- reg = snd_soc_component_read32(component, WM1811_JACKDET_CTRL);
+ reg = snd_soc_component_read(component, WM1811_JACKDET_CTRL);
if (reg < 0) {
dev_err(component->dev, "Failed to read jack status: %d\n", reg);
mutex_unlock(&wm8994->accdet_lock);
@@ -3766,6 +3904,10 @@
*
* @component: WM8958 component
* @jack: jack to report detection events on
+ * @det_cb: detection callback
+ * @det_cb_data: data for detection callback
+ * @id_cb: mic id callback
+ * @id_cb_data: data for mic id callback
*
* Enable microphone detection functionality for the WM8958. By
* default simple detection which supports the detection of up to 6
@@ -3899,7 +4041,7 @@
* with an update of the MICDET status; if so it will have
* stopped detection and we can ignore this interrupt.
*/
- if (!(snd_soc_component_read32(component, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
+ if (!(snd_soc_component_read(component, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
return IRQ_HANDLED;
cancel_delayed_work_sync(&wm8994->mic_complete_work);
@@ -3912,7 +4054,7 @@
*/
count = 10;
do {
- reg = snd_soc_component_read32(component, WM8958_MIC_DETECT_3);
+ reg = snd_soc_component_read(component, WM8958_MIC_DETECT_3);
if (reg < 0) {
dev_err(component->dev,
"Failed to read mic detect status: %d\n",
@@ -3941,7 +4083,7 @@
/* Avoid a transient report when the accessory is being removed */
if (wm8994->jackdet) {
- ret = snd_soc_component_read32(component, WM1811_JACKDET_CTRL);
+ ret = snd_soc_component_read(component, WM1811_JACKDET_CTRL);
if (ret < 0) {
dev_err(component->dev, "Failed to read jack status: %d\n",
ret);
@@ -4234,6 +4376,14 @@
wm8994_vu_bits[i].mask,
wm8994_vu_bits[i].mask);
+ if (control->type != WM1811) {
+ for (i = 0; i < ARRAY_SIZE(wm8994_adc2_dac2_vu_bits); i++)
+ snd_soc_component_update_bits(component,
+ wm8994_adc2_dac2_vu_bits[i].reg,
+ wm8994_adc2_dac2_vu_bits[i].mask,
+ wm8994_adc2_dac2_vu_bits[i].mask);
+ }
+
/* Set the low bit of the 3D stereo depth so TLV matches */
snd_soc_component_update_bits(component, WM8994_AIF1_DAC1_FILTERS_2,
1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT,
@@ -4470,6 +4620,7 @@
static int wm8994_probe(struct platform_device *pdev)
{
struct wm8994_priv *wm8994;
+ int ret;
wm8994 = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_priv),
GFP_KERNEL);
@@ -4481,11 +4632,25 @@
wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent);
+ wm8994->mclk[WM8994_MCLK1].id = "MCLK1";
+ wm8994->mclk[WM8994_MCLK2].id = "MCLK2";
+
+ ret = devm_clk_bulk_get_optional(pdev->dev.parent, ARRAY_SIZE(wm8994->mclk),
+ wm8994->mclk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to get clocks: %d\n", ret);
+ return ret;
+ }
+
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
- return devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_wm8994,
+ ret = devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_wm8994,
wm8994_dai, ARRAY_SIZE(wm8994_dai));
+ if (ret < 0)
+ pm_runtime_disable(&pdev->dev);
+
+ return ret;
}
static int wm8994_remove(struct platform_device *pdev)
--
Gitblit v1.6.2