summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/cs42l73.c116
-rw-r--r--sound/soc/codecs/sigmadsp.c2
-rw-r--r--sound/soc/codecs/tpa6130a2.c23
-rw-r--r--sound/soc/soc-compress.c2
-rw-r--r--sound/soc/soc-core.c10
-rw-r--r--sound/soc/soc-pcm.c12
6 files changed, 108 insertions, 57 deletions
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index a0791ecf6d95..6361dab48bd1 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -40,6 +40,7 @@ struct cs42l73_private {
u32 sysclk;
u8 mclksel;
u32 mclk;
+ int shutdwn_delay;
};
static const struct reg_default cs42l73_reg_defaults[] = {
@@ -588,7 +589,60 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum),
};
+static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ /* 150 ms delay between setting PDN and MCLKDIS */
+ priv->shutdwn_delay = 150;
+ break;
+ default:
+ pr_err("Invalid event = 0x%x\n", event);
+ }
+ return 0;
+}
+
+static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ /* 50 ms delay between setting PDN and MCLKDIS */
+ if (priv->shutdwn_delay < 50)
+ priv->shutdwn_delay = 50;
+ break;
+ default:
+ pr_err("Invalid event = 0x%x\n", event);
+ }
+ return 0;
+}
+
+
+static int cs42l73_hp_amp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ /* 30 ms delay between setting PDN and MCLKDIS */
+ if (priv->shutdwn_delay < 30)
+ priv->shutdwn_delay = 30;
+ break;
+ default:
+ pr_err("Invalid event = 0x%x\n", event);
+ }
+ return 0;
+}
+
static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
+ SND_SOC_DAPM_INPUT("DMICA"),
+ SND_SOC_DAPM_INPUT("DMICB"),
SND_SOC_DAPM_INPUT("LINEINA"),
SND_SOC_DAPM_INPUT("LINEINB"),
SND_SOC_DAPM_INPUT("MIC1"),
@@ -604,9 +658,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
CS42L73_PWRCTL2, 3, 1),
SND_SOC_DAPM_AIF_OUT("ASPOUTR", NULL, 0,
CS42L73_PWRCTL2, 3, 1),
- SND_SOC_DAPM_AIF_OUT("VSPOUTL", NULL, 0,
- CS42L73_PWRCTL2, 4, 1),
- SND_SOC_DAPM_AIF_OUT("VSPOUTR", NULL, 0,
+ SND_SOC_DAPM_AIF_OUT("VSPINOUT", NULL, 0,
CS42L73_PWRCTL2, 4, 1),
SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -632,8 +684,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("VSP Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_AIF_IN("XSPINL", NULL, 0,
CS42L73_PWRCTL2, 0, 1),
@@ -649,7 +700,7 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
SND_SOC_DAPM_AIF_IN("ASPINM", NULL, 0,
CS42L73_PWRCTL2, 2, 1),
- SND_SOC_DAPM_AIF_IN("VSPIN", NULL, 0,
+ SND_SOC_DAPM_AIF_IN("VSPINOUT", NULL, 0,
CS42L73_PWRCTL2, 4, 1),
SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -674,16 +725,20 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1,
- &hp_amp_ctl),
+ SND_SOC_DAPM_SWITCH_E("HP Amp", CS42L73_PWRCTL3, 0, 1,
+ &hp_amp_ctl, cs42l73_hp_amp_event,
+ SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1,
&lo_amp_ctl),
- SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1,
- &spk_amp_ctl),
- SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1,
- &ear_amp_ctl),
- SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
- &spklo_amp_ctl),
+ SND_SOC_DAPM_SWITCH_E("SPK Amp", CS42L73_PWRCTL3, 2, 1,
+ &spk_amp_ctl, cs42l73_spklo_spk_amp_event,
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SWITCH_E("EAR Amp", CS42L73_PWRCTL3, 3, 1,
+ &ear_amp_ctl, cs42l73_ear_amp_event,
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SWITCH_E("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
+ &spklo_amp_ctl, cs42l73_spklo_spk_amp_event,
+ SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_OUTPUT("HPOUTA"),
SND_SOC_DAPM_OUTPUT("HPOUTB"),
@@ -705,7 +760,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
{"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"},
{"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"},
- {"ESL DAC", "ESL-VSP Mono Volume", "VSPIN"},
+ {"ESL DAC", "ESL-VSP Mono Volume", "VSPINOUT"},
/* Loopback */
{"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"},
{"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"},
@@ -727,7 +782,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
{"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"},
{"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"},
- {"SPK DAC", "SPK-VSP Mono Volume", "VSPIN"},
+ {"SPK DAC", "SPK-VSP Mono Volume", "VSPINOUT"},
/* Loopback */
{"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"},
{"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"},
@@ -770,8 +825,8 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
{"HL Right Mixer", NULL, "ASPINR"},
{"HL Left Mixer", NULL, "XSPINL"},
{"HL Right Mixer", NULL, "XSPINR"},
- {"HL Left Mixer", NULL, "VSPIN"},
- {"HL Right Mixer", NULL, "VSPIN"},
+ {"HL Left Mixer", NULL, "VSPINOUT"},
+ {"HL Right Mixer", NULL, "VSPINOUT"},
{"ASPINL", NULL, "ASP Playback"},
{"ASPINM", NULL, "ASP Playback"},
@@ -779,7 +834,7 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
{"XSPINL", NULL, "XSP Playback"},
{"XSPINM", NULL, "XSP Playback"},
{"XSPINR", NULL, "XSP Playback"},
- {"VSPIN", NULL, "VSP Playback"},
+ {"VSPINOUT", NULL, "VSP Playback"},
/* Capture Paths */
{"MIC1", NULL, "MIC1 Bias"},
@@ -795,6 +850,8 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
{"ADC Left", NULL, "PGA Left"},
{"ADC Right", NULL, "PGA Right"},
+ {"DMIC Left", NULL, "DMICA"},
+ {"DMIC Right", NULL, "DMICB"},
{"Input Left Capture", "ADC Left Input", "ADC Left"},
{"Input Right Capture", "ADC Right Input", "ADC Right"},
@@ -819,21 +876,18 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
{"XSPOUTR", NULL, "XSPR Output Mixer"},
/* Voice Capture */
- {"VSPL Output Mixer", NULL, "Input Left Capture"},
- {"VSPR Output Mixer", NULL, "Input Left Capture"},
+ {"VSP Output Mixer", NULL, "Input Left Capture"},
+ {"VSP Output Mixer", NULL, "Input Right Capture"},
- {"VSPOUTL", "VSP-IP Volume", "VSPL Output Mixer"},
- {"VSPOUTR", "VSP-IP Volume", "VSPR Output Mixer"},
+ {"VSPINOUT", "VSP-IP Volume", "VSP Output Mixer"},
- {"VSPOUTL", NULL, "VSPL Output Mixer"},
- {"VSPOUTR", NULL, "VSPR Output Mixer"},
+ {"VSPINOUT", NULL, "VSP Output Mixer"},
{"ASP Capture", NULL, "ASPOUTL"},
{"ASP Capture", NULL, "ASPOUTR"},
{"XSP Capture", NULL, "XSPOUTL"},
{"XSP Capture", NULL, "XSPOUTR"},
- {"VSP Capture", NULL, "VSPOUTL"},
- {"VSP Capture", NULL, "VSPOUTR"},
+ {"VSP Capture", NULL, "VSPINOUT"},
};
struct cs42l73_mclk_div {
@@ -1167,6 +1221,14 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_OFF:
snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
+ if (cs42l73->shutdwn_delay > 0) {
+ mdelay(cs42l73->shutdwn_delay);
+ cs42l73->shutdwn_delay = 0;
+ } else {
+ mdelay(15); /* Min amount of time requred to power
+ * down.
+ */
+ }
snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1);
break;
}
diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c
index 5be42bf56996..4068f2491232 100644
--- a/sound/soc/codecs/sigmadsp.c
+++ b/sound/soc/codecs/sigmadsp.c
@@ -225,7 +225,7 @@ EXPORT_SYMBOL(process_sigma_firmware);
static int sigma_action_write_regmap(void *control_data,
const struct sigma_action *sa, size_t len)
{
- return regmap_raw_write(control_data, le16_to_cpu(sa->addr),
+ return regmap_raw_write(control_data, be16_to_cpu(sa->addr),
sa->payload, len - 2);
}
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 8d75aa152c8c..c58bee8346ce 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -398,7 +398,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
TPA6130A2_MUTE_L;
if (data->power_gpio >= 0) {
- ret = gpio_request(data->power_gpio, "tpa6130a2 enable");
+ ret = devm_gpio_request(dev, data->power_gpio,
+ "tpa6130a2 enable");
if (ret < 0) {
dev_err(dev, "Failed to request power GPIO (%d)\n",
data->power_gpio);
@@ -419,16 +420,16 @@ static int tpa6130a2_probe(struct i2c_client *client,
break;
}
- data->supply = regulator_get(dev, regulator);
+ data->supply = devm_regulator_get(dev, regulator);
if (IS_ERR(data->supply)) {
ret = PTR_ERR(data->supply);
dev_err(dev, "Failed to request supply: %d\n", ret);
- goto err_regulator;
+ goto err_gpio;
}
ret = tpa6130a2_power(1);
if (ret != 0)
- goto err_power;
+ goto err_gpio;
/* Read version */
@@ -440,15 +441,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
/* Disable the chip */
ret = tpa6130a2_power(0);
if (ret != 0)
- goto err_power;
+ goto err_gpio;
return 0;
-err_power:
- regulator_put(data->supply);
-err_regulator:
- if (data->power_gpio >= 0)
- gpio_free(data->power_gpio);
err_gpio:
tpa6130a2_client = NULL;
@@ -457,14 +453,7 @@ err_gpio:
static int tpa6130a2_remove(struct i2c_client *client)
{
- struct tpa6130a2_data *data = i2c_get_clientdata(client);
-
tpa6130a2_power(0);
-
- if (data->power_gpio >= 0)
- gpio_free(data->power_gpio);
-
- regulator_put(data->supply);
tpa6130a2_client = NULL;
return 0;
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 967d0e173e1b..5fbfb06e8083 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -113,7 +113,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
SNDRV_PCM_STREAM_PLAYBACK,
SND_SOC_DAPM_STREAM_STOP);
} else
- codec_dai->pop_wait = 1;
+ rtd->pop_wait = 1;
schedule_delayed_work(&rtd->delayed_work,
msecs_to_jiffies(rtd->pmdown_time));
} else {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 9c768bcb98a6..91d592ff67b7 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4155,9 +4155,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
ret = of_property_read_string_index(np, propname,
2 * i, &routes[i].sink);
if (ret) {
- dev_err(card->dev, "ASoC: Property '%s' index %d"
- " could not be read: %d\n", propname, 2 * i,
- ret);
+ dev_err(card->dev,
+ "ASoC: Property '%s' index %d could not be read: %d\n",
+ propname, 2 * i, ret);
kfree(routes);
return -EINVAL;
}
@@ -4165,8 +4165,8 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
(2 * i) + 1, &routes[i].source);
if (ret) {
dev_err(card->dev,
- "ASoC: Property '%s' index %d could not be"
- " read: %d\n", propname, (2 * i) + 1, ret);
+ "ASoC: Property '%s' index %d could not be read: %d\n",
+ propname, (2 * i) + 1, ret);
kfree(routes);
return -EINVAL;
}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 5c3ca2a34661..d7711fce119b 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -334,11 +334,11 @@ static void close_delayed_work(struct work_struct *work)
dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
codec_dai->driver->playback.stream_name,
codec_dai->playback_active ? "active" : "inactive",
- codec_dai->pop_wait ? "yes" : "no");
+ rtd->pop_wait ? "yes" : "no");
/* are we waiting on this codec DAI stream */
- if (codec_dai->pop_wait == 1) {
- codec_dai->pop_wait = 0;
+ if (rtd->pop_wait == 1) {
+ rtd->pop_wait = 0;
snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
SND_SOC_DAPM_STREAM_STOP);
}
@@ -408,7 +408,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
SND_SOC_DAPM_STREAM_STOP);
} else {
/* start delayed pop wq here for playback streams */
- codec_dai->pop_wait = 1;
+ rtd->pop_wait = 1;
schedule_delayed_work(&rtd->delayed_work,
msecs_to_jiffies(rtd->pmdown_time));
}
@@ -480,8 +480,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
/* cancel any delayed stream shutdown that is pending */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- codec_dai->pop_wait) {
- codec_dai->pop_wait = 0;
+ rtd->pop_wait) {
+ rtd->pop_wait = 0;
cancel_delayed_work(&rtd->delayed_work);
}