summaryrefslogtreecommitdiff
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2019-08-20 18:28:43 +0100
committerMark Brown <broonie@kernel.org>2019-08-20 18:28:43 +0100
commitdd28d54c248fa37794dfa3d23a24ff99a1d3b6ac (patch)
tree066b7a24eb08527f47da41ac3fd3621d073a24d6 /sound/soc/codecs
parentd5e120422db8808e1c8b1507900ca393a877c58f (diff)
parentbf283a05c09b58db83afbb1a8a3c6a684c56c1bb (diff)
Merge branch 'asoc-5.3' into asoc-5.4
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/hdac_hda.c4
-rw-r--r--sound/soc/codecs/hdac_hdmi.c57
-rw-r--r--sound/soc/codecs/max98373.c6
-rw-r--r--sound/soc/codecs/max98373.h2
-rw-r--r--sound/soc/codecs/wm8737.c2
-rw-r--r--sound/soc/codecs/wm8904.c56
6 files changed, 96 insertions, 31 deletions
diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
index 7d4940256914..91242b6f8ea7 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -495,6 +495,10 @@ static int hdac_hda_dev_probe(struct hdac_device *hdev)
static int hdac_hda_dev_remove(struct hdac_device *hdev)
{
+ struct hdac_hda_priv *hda_pvt;
+
+ hda_pvt = dev_get_drvdata(&hdev->dev);
+ cancel_delayed_work_sync(&hda_pvt->codec.jackpoll_work);
return 0;
}
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 29918954e740..18c173e6a13b 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -88,8 +88,10 @@ struct hdac_hdmi_port {
hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
struct hdac_hdmi_eld eld;
const char *jack_pin;
+ bool is_connect;
struct snd_soc_dapm_context *dapm;
const char *output_pin;
+ struct work_struct dapm_work;
};
struct hdac_hdmi_pcm {
@@ -163,11 +165,7 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
{
struct hdac_device *hdev = port->pin->hdev;
- if (is_connect)
- snd_soc_dapm_enable_pin(port->dapm, port->jack_pin);
- else
- snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
-
+ port->is_connect = is_connect;
if (is_connect) {
/*
* Report Jack connect event when a device is connected
@@ -193,10 +191,32 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
if (pcm->jack_event > 0)
pcm->jack_event--;
}
+}
+static void hdac_hdmi_port_dapm_update(struct hdac_hdmi_port *port)
+{
+ if (port->is_connect)
+ snd_soc_dapm_enable_pin(port->dapm, port->jack_pin);
+ else
+ snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
snd_soc_dapm_sync(port->dapm);
}
+static void hdac_hdmi_jack_dapm_work(struct work_struct *work)
+{
+ struct hdac_hdmi_port *port;
+
+ port = container_of(work, struct hdac_hdmi_port, dapm_work);
+ hdac_hdmi_port_dapm_update(port);
+}
+
+static void hdac_hdmi_jack_report_sync(struct hdac_hdmi_pcm *pcm,
+ struct hdac_hdmi_port *port, bool is_connect)
+{
+ hdac_hdmi_jack_report(pcm, port, is_connect);
+ hdac_hdmi_port_dapm_update(port);
+}
+
/* MST supported verbs */
/*
* Get the no devices that can be connected to a port on the Pin widget.
@@ -904,7 +924,7 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
list_for_each_entry_safe(p, p_next, &pcm->port_list, head) {
if (p == port && p->id == port->id &&
p->pin == port->pin) {
- hdac_hdmi_jack_report(pcm, port, false);
+ hdac_hdmi_jack_report_sync(pcm, port, false);
list_del(&p->head);
}
}
@@ -918,7 +938,7 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
if (!strcmp(cvt_name, pcm->cvt->name)) {
list_add_tail(&port->head, &pcm->port_list);
if (port->eld.monitor_present && port->eld.eld_valid) {
- hdac_hdmi_jack_report(pcm, port, true);
+ hdac_hdmi_jack_report_sync(pcm, port, true);
mutex_unlock(&hdmi->pin_mutex);
return ret;
}
@@ -1281,16 +1301,20 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
* report jack here. It will be done in usermode mux
* control select.
*/
- if (pcm)
+ if (pcm) {
hdac_hdmi_jack_report(pcm, port, false);
+ schedule_work(&port->dapm_work);
+ }
mutex_unlock(&hdmi->pin_mutex);
return;
}
if (port->eld.monitor_present && port->eld.eld_valid) {
- if (pcm)
+ if (pcm) {
hdac_hdmi_jack_report(pcm, port, true);
+ schedule_work(&port->dapm_work);
+ }
print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
port->eld.eld_buffer, port->eld.eld_size, false);
@@ -1319,6 +1343,7 @@ static int hdac_hdmi_add_ports(struct hdac_device *hdev,
for (i = 0; i < max_ports; i++) {
ports[i].id = i;
ports[i].pin = pin;
+ INIT_WORK(&ports[i].dapm_work, hdac_hdmi_jack_dapm_work);
}
pin->ports = ports;
pin->num_ports = max_ports;
@@ -2083,8 +2108,20 @@ static int hdac_hdmi_dev_probe(struct hdac_device *hdev)
return ret;
}
+static void clear_dapm_works(struct hdac_device *hdev)
+{
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
+ struct hdac_hdmi_pin *pin;
+ int i;
+
+ list_for_each_entry(pin, &hdmi->pin_list, head)
+ for (i = 0; i < pin->num_ports; i++)
+ cancel_work_sync(&pin->ports[i].dapm_work);
+}
+
static int hdac_hdmi_dev_remove(struct hdac_device *hdev)
{
+ clear_dapm_works(hdev);
snd_hdac_display_power(hdev->bus, hdev->addr, false);
return 0;
@@ -2103,6 +2140,8 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
if (!bus)
return 0;
+ clear_dapm_works(hdev);
+
/*
* Power down afg.
* codec_read is preferred over codec_write to set the power state.
diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c
index 9a1eb7222357..e609abcf3220 100644
--- a/sound/soc/codecs/max98373.c
+++ b/sound/soc/codecs/max98373.c
@@ -268,6 +268,12 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
case 48000:
sampling_rate = MAX98373_PCM_SR_SET1_SR_48000;
break;
+ case 88200:
+ sampling_rate = MAX98373_PCM_SR_SET1_SR_88200;
+ break;
+ case 96000:
+ sampling_rate = MAX98373_PCM_SR_SET1_SR_96000;
+ break;
default:
dev_err(component->dev, "rate %d not supported\n",
params_rate(params));
diff --git a/sound/soc/codecs/max98373.h b/sound/soc/codecs/max98373.h
index 533d2053f608..63dae8be7105 100644
--- a/sound/soc/codecs/max98373.h
+++ b/sound/soc/codecs/max98373.h
@@ -130,6 +130,8 @@
#define MAX98373_PCM_SR_SET1_SR_32000 (0x6 << 0)
#define MAX98373_PCM_SR_SET1_SR_44100 (0x7 << 0)
#define MAX98373_PCM_SR_SET1_SR_48000 (0x8 << 0)
+#define MAX98373_PCM_SR_SET1_SR_88200 (0x9 << 0)
+#define MAX98373_PCM_SR_SET1_SR_96000 (0xA << 0)
/* MAX98373_R2028_PCM_SR_SETUP_2 */
#define MAX98373_PCM_SR_SET2_SR_MASK (0xF << 4)
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index 0c246fb5e5ac..7a3f9fbe8d53 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -167,7 +167,7 @@ SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0),
SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0),
SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0),
SOC_ENUM("3D Low Cut-off", low_3d),
-SOC_ENUM("3D High Cut-off", low_3d),
+SOC_ENUM("3D High Cut-off", high_3d),
SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv),
SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0),
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 5ebdd1d9afde..bcb3c9d5abf0 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -545,18 +545,6 @@ static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-static const char *input_mode_text[] = {
- "Single-Ended", "Differential Line", "Differential Mic"
-};
-
-static SOC_ENUM_SINGLE_DECL(lin_mode,
- WM8904_ANALOGUE_LEFT_INPUT_1, 0,
- input_mode_text);
-
-static SOC_ENUM_SINGLE_DECL(rin_mode,
- WM8904_ANALOGUE_RIGHT_INPUT_1, 0,
- input_mode_text);
-
static const char *hpf_mode_text[] = {
"Hi-fi", "Voice 1", "Voice 2", "Voice 3"
};
@@ -591,9 +579,6 @@ static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
-SOC_ENUM("Left Capture Mode", lin_mode),
-SOC_ENUM("Right Capture Mode", rin_mode),
-
/* No TLV since it depends on mode */
SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
@@ -852,6 +837,10 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
return 0;
}
+static const char *input_mode_text[] = {
+ "Single-Ended", "Differential Line", "Differential Mic"
+};
+
static const char *lin_text[] = {
"IN1L", "IN2L", "IN3L"
};
@@ -866,7 +855,14 @@ static SOC_ENUM_SINGLE_DECL(lin_inv_enum, WM8904_ANALOGUE_LEFT_INPUT_1, 4,
lin_text);
static const struct snd_kcontrol_new lin_inv_mux =
- SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
+ SOC_DAPM_ENUM("Left Capture Inverting Mux", lin_inv_enum);
+
+static SOC_ENUM_SINGLE_DECL(lin_mode_enum,
+ WM8904_ANALOGUE_LEFT_INPUT_1, 0,
+ input_mode_text);
+
+static const struct snd_kcontrol_new lin_mode =
+ SOC_DAPM_ENUM("Left Capture Mode", lin_mode_enum);
static const char *rin_text[] = {
"IN1R", "IN2R", "IN3R"
@@ -882,7 +878,14 @@ static SOC_ENUM_SINGLE_DECL(rin_inv_enum, WM8904_ANALOGUE_RIGHT_INPUT_1, 4,
rin_text);
static const struct snd_kcontrol_new rin_inv_mux =
- SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
+ SOC_DAPM_ENUM("Right Capture Inverting Mux", rin_inv_enum);
+
+static SOC_ENUM_SINGLE_DECL(rin_mode_enum,
+ WM8904_ANALOGUE_RIGHT_INPUT_1, 0,
+ input_mode_text);
+
+static const struct snd_kcontrol_new rin_mode =
+ SOC_DAPM_ENUM("Right Capture Mode", rin_mode_enum);
static const char *aif_text[] = {
"Left", "Right"
@@ -932,9 +935,11 @@ SND_SOC_DAPM_SUPPLY("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0),
SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
&lin_inv_mux),
+SND_SOC_DAPM_MUX("Left Capture Mode", SND_SOC_NOPM, 0, 0, &lin_mode),
SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
&rin_inv_mux),
+SND_SOC_DAPM_MUX("Right Capture Mode", SND_SOC_NOPM, 0, 0, &rin_mode),
SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
NULL, 0),
@@ -1057,6 +1062,12 @@ static const struct snd_soc_dapm_route adc_intercon[] = {
{ "Left Capture Inverting Mux", "IN2L", "IN2L" },
{ "Left Capture Inverting Mux", "IN3L", "IN3L" },
+ { "Left Capture Mode", "Single-Ended", "Left Capture Inverting Mux" },
+ { "Left Capture Mode", "Differential Line", "Left Capture Mux" },
+ { "Left Capture Mode", "Differential Line", "Left Capture Inverting Mux" },
+ { "Left Capture Mode", "Differential Mic", "Left Capture Mux" },
+ { "Left Capture Mode", "Differential Mic", "Left Capture Inverting Mux" },
+
{ "Right Capture Mux", "IN1R", "IN1R" },
{ "Right Capture Mux", "IN2R", "IN2R" },
{ "Right Capture Mux", "IN3R", "IN3R" },
@@ -1065,11 +1076,14 @@ static const struct snd_soc_dapm_route adc_intercon[] = {
{ "Right Capture Inverting Mux", "IN2R", "IN2R" },
{ "Right Capture Inverting Mux", "IN3R", "IN3R" },
- { "Left Capture PGA", NULL, "Left Capture Mux" },
- { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
+ { "Right Capture Mode", "Single-Ended", "Right Capture Inverting Mux" },
+ { "Right Capture Mode", "Differential Line", "Right Capture Mux" },
+ { "Right Capture Mode", "Differential Line", "Right Capture Inverting Mux" },
+ { "Right Capture Mode", "Differential Mic", "Right Capture Mux" },
+ { "Right Capture Mode", "Differential Mic", "Right Capture Inverting Mux" },
- { "Right Capture PGA", NULL, "Right Capture Mux" },
- { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
+ { "Left Capture PGA", NULL, "Left Capture Mode" },
+ { "Right Capture PGA", NULL, "Right Capture Mode" },
{ "AIFOUTL Mux", "Left", "ADCL" },
{ "AIFOUTL Mux", "Right", "ADCR" },