diff options
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/cs4349.c | 1 | ||||
-rw-r--r-- | sound/soc/codecs/es8316.c | 7 | ||||
-rw-r--r-- | sound/soc/codecs/es8328.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/hdac_hda.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/hdac_hdmi.c | 57 | ||||
-rw-r--r-- | sound/soc/codecs/rt1011.c | 27 | ||||
-rw-r--r-- | sound/soc/codecs/wm8737.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wm8904.c | 56 |
8 files changed, 114 insertions, 42 deletions
diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index 09716fab1e26..3381209a882d 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c @@ -378,6 +378,7 @@ static struct i2c_driver cs4349_i2c_driver = { .driver = { .name = "cs4349", .of_match_table = cs4349_of_match, + .pm = &cs4349_runtime_pm, }, .id_table = cs4349_i2c_id, .probe = cs4349_i2c_probe, diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index 6db002cc2058..ed2959dbe1fb 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -51,7 +51,10 @@ static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv, -1650, 150, 0); -static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(hpmixer_gain_tlv, -1200, 150, 0); +static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpmixer_gain_tlv, + 0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0), + 8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0), +); static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(adc_pga_gain_tlv, 0, 0, TLV_DB_SCALE_ITEM(-350, 0, 0), @@ -89,7 +92,7 @@ static const struct snd_kcontrol_new es8316_snd_controls[] = { SOC_DOUBLE_TLV("Headphone Playback Volume", ES8316_CPHP_ICAL_VOL, 4, 0, 3, 1, hpout_vol_tlv), SOC_DOUBLE_TLV("Headphone Mixer Volume", ES8316_HPMIX_VOL, - 0, 4, 7, 0, hpmixer_gain_tlv), + 4, 0, 11, 0, hpmixer_gain_tlv), SOC_ENUM("Playback Polarity", dacpol), SOC_DOUBLE_R_TLV("DAC Playback Volume", ES8316_DAC_VOLL, diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index 822a25a8f53c..69b81e704127 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -228,7 +228,7 @@ static const struct soc_enum es8328_rline_enum = ARRAY_SIZE(es8328_line_texts), es8328_line_texts); static const struct snd_kcontrol_new es8328_right_line_controls = - SOC_DAPM_ENUM("Route", es8328_lline_enum); + SOC_DAPM_ENUM("Route", es8328_rline_enum); /* Left Mixer */ static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { 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/rt1011.c b/sound/soc/codecs/rt1011.c index 0a6ff13d76e1..ed28250d5e34 100644 --- a/sound/soc/codecs/rt1011.c +++ b/sound/soc/codecs/rt1011.c @@ -1619,14 +1619,18 @@ static int rt1011_hw_params(struct snd_pcm_substream *substream, static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct snd_soc_component *component = dai->component; + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); unsigned int reg_val = 0, reg_bclk_inv = 0; + int ret = 0; + snd_soc_dapm_mutex_lock(dapm); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: reg_val |= RT1011_I2S_TDM_MS_S; break; default: - return -EINVAL; + ret = -EINVAL; } switch (fmt & SND_SOC_DAIFMT_INV_MASK) { @@ -1636,7 +1640,7 @@ static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) reg_bclk_inv |= RT1011_TDM_INV_BCLK; break; default: - return -EINVAL; + ret = -EINVAL; } switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -1652,7 +1656,7 @@ static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) reg_val |= RT1011_I2S_TDM_DF_PCM_B; break; default: - return -EINVAL; + ret = -EINVAL; } switch (dai->id) { @@ -1667,9 +1671,11 @@ static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) break; default: dev_err(component->dev, "Invalid dai->id: %d\n", dai->id); - return -EINVAL; + ret = -EINVAL; } - return 0; + + snd_soc_dapm_mutex_unlock(dapm); + return ret; } static int rt1011_set_component_sysclk(struct snd_soc_component *component, @@ -1788,8 +1794,12 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) { struct snd_soc_component *component = dai->component; + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); unsigned int val = 0, tdm_en = 0; + int ret = 0; + snd_soc_dapm_mutex_lock(dapm); if (rx_mask || tx_mask) tdm_en = RT1011_TDM_I2S_DOCK_EN_1; @@ -1809,7 +1819,7 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai, case 2: break; default: - return -EINVAL; + ret = -EINVAL; } switch (slot_width) { @@ -1828,7 +1838,7 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai, case 16: break; default: - return -EINVAL; + ret = -EINVAL; } snd_soc_component_update_bits(component, RT1011_TDM1_SET_1, @@ -1845,7 +1855,8 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai, RT1011_ADCDAT1_PIN_CONFIG | RT1011_ADCDAT2_PIN_CONFIG, RT1011_ADCDAT1_OUTPUT | RT1011_ADCDAT2_OUTPUT); - return 0; + snd_soc_dapm_mutex_unlock(dapm); + return ret; } static int rt1011_probe(struct snd_soc_component *component) 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" }, |