Commit bb95d607 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-5.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Here are the pending sound fixes for 5.10: all small device-specific
  fixes, and nothing particular stands out, so far"

* tag 'sound-5.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda/realtek: Add mute LED quirk to yet another HP x360 model
  ALSA: hda/realtek: Fix bass speaker DAC assignment on Asus Zephyrus G14
  ALSA: hda/generic: Add option to enforce preferred_dacs pairs
  ALSA: usb-audio: US16x08: fix value count for level meters
  ALSA: hda/realtek - Add new codec supported for ALC897
  ASoC: rt5682: change SAR voltage threshold
  ASoC: wm_adsp: fix error return code in wm_adsp_load()
  ALSA: hda/realtek: Enable headset of ASUS UX482EG & B9400CEA with ALC294
  ASoC: qcom: Fix enabling BCLK and LRCLK in LPAIF invalid state
  ALSA: hda/realtek - Fixed Dell AIO wrong sound tone
  ASoC: Intel: bytcr_rt5640: Fix HP Pavilion x2 Detachable quirks
parents 8a02ec8f aeedad25
...@@ -1364,16 +1364,20 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs, ...@@ -1364,16 +1364,20 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
struct nid_path *path; struct nid_path *path;
hda_nid_t pin = pins[i]; hda_nid_t pin = pins[i];
if (!spec->obey_preferred_dacs) {
path = snd_hda_get_path_from_idx(codec, path_idx[i]); path = snd_hda_get_path_from_idx(codec, path_idx[i]);
if (path) { if (path) {
badness += assign_out_path_ctls(codec, path); badness += assign_out_path_ctls(codec, path);
continue; continue;
} }
}
dacs[i] = get_preferred_dac(codec, pin); dacs[i] = get_preferred_dac(codec, pin);
if (dacs[i]) { if (dacs[i]) {
if (is_dac_already_used(codec, dacs[i])) if (is_dac_already_used(codec, dacs[i]))
badness += bad->shared_primary; badness += bad->shared_primary;
} else if (spec->obey_preferred_dacs) {
badness += BAD_NO_PRIMARY_DAC;
} }
if (!dacs[i]) if (!dacs[i])
......
...@@ -237,6 +237,7 @@ struct hda_gen_spec { ...@@ -237,6 +237,7 @@ struct hda_gen_spec {
unsigned int power_down_unused:1; /* power down unused widgets */ unsigned int power_down_unused:1; /* power down unused widgets */
unsigned int dac_min_mute:1; /* minimal = mute for DACs */ unsigned int dac_min_mute:1; /* minimal = mute for DACs */
unsigned int suppress_vmaster:1; /* don't create vmaster kctls */ unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
unsigned int obey_preferred_dacs:1; /* obey preferred_dacs assignment */
/* other internal flags */ /* other internal flags */
unsigned int no_analog:1; /* digital I/O only */ unsigned int no_analog:1; /* digital I/O only */
......
...@@ -119,6 +119,7 @@ struct alc_spec { ...@@ -119,6 +119,7 @@ struct alc_spec {
unsigned int no_shutup_pins:1; unsigned int no_shutup_pins:1;
unsigned int ultra_low_power:1; unsigned int ultra_low_power:1;
unsigned int has_hs_key:1; unsigned int has_hs_key:1;
unsigned int no_internal_mic_pin:1;
/* for PLL fix */ /* for PLL fix */
hda_nid_t pll_nid; hda_nid_t pll_nid;
...@@ -445,6 +446,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) ...@@ -445,6 +446,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
alc_update_coef_idx(codec, 0x7, 1<<5, 0); alc_update_coef_idx(codec, 0x7, 1<<5, 0);
break; break;
case 0x10ec0892: case 0x10ec0892:
case 0x10ec0897:
alc_update_coef_idx(codec, 0x7, 1<<5, 0); alc_update_coef_idx(codec, 0x7, 1<<5, 0);
break; break;
case 0x10ec0899: case 0x10ec0899:
...@@ -4523,6 +4525,7 @@ static const struct coef_fw alc225_pre_hsmode[] = { ...@@ -4523,6 +4525,7 @@ static const struct coef_fw alc225_pre_hsmode[] = {
static void alc_headset_mode_unplugged(struct hda_codec *codec) static void alc_headset_mode_unplugged(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec;
static const struct coef_fw coef0255[] = { static const struct coef_fw coef0255[] = {
WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */ WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */ WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
...@@ -4597,6 +4600,11 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) ...@@ -4597,6 +4600,11 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
{} {}
}; };
if (spec->no_internal_mic_pin) {
alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
return;
}
switch (codec->core.vendor_id) { switch (codec->core.vendor_id) {
case 0x10ec0255: case 0x10ec0255:
alc_process_coef_fw(codec, coef0255); alc_process_coef_fw(codec, coef0255);
...@@ -5163,6 +5171,11 @@ static void alc_determine_headset_type(struct hda_codec *codec) ...@@ -5163,6 +5171,11 @@ static void alc_determine_headset_type(struct hda_codec *codec)
{} {}
}; };
if (spec->no_internal_mic_pin) {
alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
return;
}
switch (codec->core.vendor_id) { switch (codec->core.vendor_id) {
case 0x10ec0255: case 0x10ec0255:
alc_process_coef_fw(codec, coef0255); alc_process_coef_fw(codec, coef0255);
...@@ -6014,6 +6027,21 @@ static void alc274_fixup_bind_dacs(struct hda_codec *codec, ...@@ -6014,6 +6027,21 @@ static void alc274_fixup_bind_dacs(struct hda_codec *codec,
codec->power_save_node = 0; codec->power_save_node = 0;
} }
/* avoid DAC 0x06 for bass speaker 0x17; it has no volume control */
static void alc289_fixup_asus_ga401(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
static const hda_nid_t preferred_pairs[] = {
0x14, 0x02, 0x17, 0x02, 0x21, 0x03, 0
};
struct alc_spec *spec = codec->spec;
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->gen.preferred_dacs = preferred_pairs;
spec->gen.obey_preferred_dacs = 1;
}
}
/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */ /* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
static void alc285_fixup_invalidate_dacs(struct hda_codec *codec, static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
const struct hda_fixup *fix, int action) const struct hda_fixup *fix, int action)
...@@ -6121,6 +6149,23 @@ static void alc274_fixup_hp_headset_mic(struct hda_codec *codec, ...@@ -6121,6 +6149,23 @@ static void alc274_fixup_hp_headset_mic(struct hda_codec *codec,
} }
} }
static void alc_fixup_no_int_mic(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
struct alc_spec *spec = codec->spec;
switch (action) {
case HDA_FIXUP_ACT_PRE_PROBE:
/* Mic RING SLEEVE swap for combo jack */
alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
spec->no_internal_mic_pin = true;
break;
case HDA_FIXUP_ACT_INIT:
alc_combo_jack_hp_jd_restart(codec);
break;
}
}
/* for hda_fixup_thinkpad_acpi() */ /* for hda_fixup_thinkpad_acpi() */
#include "thinkpad_helper.c" #include "thinkpad_helper.c"
...@@ -6320,6 +6365,7 @@ enum { ...@@ -6320,6 +6365,7 @@ enum {
ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
ALC287_FIXUP_HP_GPIO_LED, ALC287_FIXUP_HP_GPIO_LED,
ALC256_FIXUP_HP_HEADSET_MIC, ALC256_FIXUP_HP_HEADSET_MIC,
ALC236_FIXUP_DELL_AIO_HEADSET_MIC,
}; };
static const struct hda_fixup alc269_fixups[] = { static const struct hda_fixup alc269_fixups[] = {
...@@ -7569,11 +7615,10 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -7569,11 +7615,10 @@ static const struct hda_fixup alc269_fixups[] = {
.chain_id = ALC269_FIXUP_HEADSET_MIC .chain_id = ALC269_FIXUP_HEADSET_MIC
}, },
[ALC289_FIXUP_ASUS_GA401] = { [ALC289_FIXUP_ASUS_GA401] = {
.type = HDA_FIXUP_PINS, .type = HDA_FIXUP_FUNC,
.v.pins = (const struct hda_pintbl[]) { .v.func = alc289_fixup_asus_ga401,
{ 0x19, 0x03a11020 }, /* headset mic with jack detect */ .chained = true,
{ } .chain_id = ALC289_FIXUP_ASUS_GA502,
},
}, },
[ALC289_FIXUP_ASUS_GA502] = { [ALC289_FIXUP_ASUS_GA502] = {
.type = HDA_FIXUP_PINS, .type = HDA_FIXUP_PINS,
...@@ -7697,7 +7742,7 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -7697,7 +7742,7 @@ static const struct hda_fixup alc269_fixups[] = {
{ } { }
}, },
.chained = true, .chained = true,
.chain_id = ALC289_FIXUP_ASUS_GA401 .chain_id = ALC289_FIXUP_ASUS_GA502
}, },
[ALC274_FIXUP_HP_MIC] = { [ALC274_FIXUP_HP_MIC] = {
.type = HDA_FIXUP_VERBS, .type = HDA_FIXUP_VERBS,
...@@ -7738,6 +7783,12 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -7738,6 +7783,12 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
.v.func = alc274_fixup_hp_headset_mic, .v.func = alc274_fixup_hp_headset_mic,
}, },
[ALC236_FIXUP_DELL_AIO_HEADSET_MIC] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_no_int_mic,
.chained = true,
.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
},
}; };
static const struct snd_pci_quirk alc269_fixup_tbl[] = { static const struct snd_pci_quirk alc269_fixup_tbl[] = {
...@@ -7815,6 +7866,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -7815,6 +7866,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK), SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0a2e, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
SND_PCI_QUIRK(0x1028, 0x0a30, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
...@@ -7881,6 +7934,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -7881,6 +7934,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360), SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
SND_PCI_QUIRK(0x103c, 0x827f, "HP x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
...@@ -8353,6 +8407,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { ...@@ -8353,6 +8407,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
{0x19, 0x02a11020}, {0x19, 0x02a11020},
{0x1a, 0x02a11030}, {0x1a, 0x02a11030},
{0x21, 0x0221101f}), {0x21, 0x0221101f}),
SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC,
{0x21, 0x02211010}),
SND_HDA_PIN_QUIRK(0x10ec0236, 0x103c, "HP", ALC256_FIXUP_HP_HEADSET_MIC, SND_HDA_PIN_QUIRK(0x10ec0236, 0x103c, "HP", ALC256_FIXUP_HP_HEADSET_MIC,
{0x14, 0x90170110}, {0x14, 0x90170110},
{0x19, 0x02a11020}, {0x19, 0x02a11020},
...@@ -8585,6 +8641,9 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { ...@@ -8585,6 +8641,9 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC292_STANDARD_PINS, ALC292_STANDARD_PINS,
{0x13, 0x90a60140}), {0x13, 0x90a60140}),
SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_HPE,
{0x17, 0x90170110},
{0x21, 0x04211020}),
SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC, SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
{0x14, 0x90170110}, {0x14, 0x90170110},
{0x1b, 0x90a70130}, {0x1b, 0x90a70130},
...@@ -10171,6 +10230,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = { ...@@ -10171,6 +10230,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882), HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882), HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662), HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
HDA_CODEC_ENTRY(0x10ec0897, "ALC897", patch_alc662),
HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882), HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882), HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882), HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
......
...@@ -43,6 +43,7 @@ static const struct reg_sequence patch_list[] = { ...@@ -43,6 +43,7 @@ static const struct reg_sequence patch_list[] = {
{RT5682_DAC_ADC_DIG_VOL1, 0xa020}, {RT5682_DAC_ADC_DIG_VOL1, 0xa020},
{RT5682_I2C_CTRL, 0x000f}, {RT5682_I2C_CTRL, 0x000f},
{RT5682_PLL2_INTERNAL, 0x8266}, {RT5682_PLL2_INTERNAL, 0x8266},
{RT5682_SAR_IL_CMD_3, 0x8365},
}; };
void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev) void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev)
......
...@@ -1937,6 +1937,7 @@ static int wm_adsp_load(struct wm_adsp *dsp) ...@@ -1937,6 +1937,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
mem = wm_adsp_find_region(dsp, type); mem = wm_adsp_find_region(dsp, type);
if (!mem) { if (!mem) {
adsp_err(dsp, "No region of type: %x\n", type); adsp_err(dsp, "No region of type: %x\n", type);
ret = -EINVAL;
goto out_fw; goto out_fw;
} }
......
...@@ -520,10 +520,10 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -520,10 +520,10 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
.driver_data = (void *)(BYT_RT5640_IN1_MAP | .driver_data = (void *)(BYT_RT5640_IN1_MAP |
BYT_RT5640_MCLK_EN), BYT_RT5640_MCLK_EN),
}, },
{ /* HP Pavilion x2 10-n000nd */ { /* HP Pavilion x2 10-k0XX, 10-n0XX */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
}, },
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP | .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
BYT_RT5640_JD_SRC_JD2_IN4N | BYT_RT5640_JD_SRC_JD2_IN4N |
...@@ -532,6 +532,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -532,6 +532,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
BYT_RT5640_SSP0_AIF1 | BYT_RT5640_SSP0_AIF1 |
BYT_RT5640_MCLK_EN), BYT_RT5640_MCLK_EN),
}, },
{ /* HP Pavilion x2 10-p0XX */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
},
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
BYT_RT5640_JD_SRC_JD1_IN4P |
BYT_RT5640_OVCD_TH_1500UA |
BYT_RT5640_OVCD_SF_0P75 |
BYT_RT5640_MCLK_EN),
},
{ /* HP Stream 7 */ { /* HP Stream 7 */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
......
...@@ -263,28 +263,6 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream, ...@@ -263,28 +263,6 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
unsigned int id = dai->driver->id;
int ret;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = regmap_fields_write(i2sctl->spken, id,
LPAIF_I2SCTL_SPKEN_ENABLE);
} else {
ret = regmap_fields_write(i2sctl->micen, id,
LPAIF_I2SCTL_MICEN_ENABLE);
}
if (ret)
dev_err(dai->dev, "error writing to i2sctl enable: %d\n", ret);
return ret;
}
static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai) int cmd, struct snd_soc_dai *dai)
{ {
...@@ -292,6 +270,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -292,6 +270,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
struct lpaif_i2sctl *i2sctl = drvdata->i2sctl; struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
unsigned int id = dai->driver->id; unsigned int id = dai->driver->id;
int ret = -EINVAL; int ret = -EINVAL;
unsigned int val = 0;
ret = regmap_read(drvdata->lpaif_map,
LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), &val);
if (ret) {
dev_err(dai->dev, "error reading from i2sctl reg: %d\n", ret);
return ret;
}
if (val == LPAIF_I2SCTL_RESET_STATE) {
dev_err(dai->dev, "error in i2sctl register state\n");
return -ENOTRECOVERABLE;
}
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
...@@ -308,12 +298,15 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -308,12 +298,15 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
dev_err(dai->dev, "error writing to i2sctl reg: %d\n", dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
ret); ret);
if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_DISABLE) {
ret = clk_enable(drvdata->mi2s_bit_clk[id]); ret = clk_enable(drvdata->mi2s_bit_clk[id]);
if (ret) { if (ret) {
dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret); dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
clk_disable(drvdata->mi2s_osr_clk[id]); clk_disable(drvdata->mi2s_osr_clk[id]);
return ret; return ret;
} }
drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_ENABLE;
}
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
...@@ -329,7 +322,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -329,7 +322,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
if (ret) if (ret)
dev_err(dai->dev, "error writing to i2sctl reg: %d\n", dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
ret); ret);
if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_ENABLE) {
clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]); clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);
drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_DISABLE;
}
break; break;
} }
...@@ -341,7 +337,6 @@ const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = { ...@@ -341,7 +337,6 @@ const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = {
.startup = lpass_cpu_daiops_startup, .startup = lpass_cpu_daiops_startup,
.shutdown = lpass_cpu_daiops_shutdown, .shutdown = lpass_cpu_daiops_shutdown,
.hw_params = lpass_cpu_daiops_hw_params, .hw_params = lpass_cpu_daiops_hw_params,
.prepare = lpass_cpu_daiops_prepare,
.trigger = lpass_cpu_daiops_trigger, .trigger = lpass_cpu_daiops_trigger,
}; };
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops); EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops);
...@@ -459,16 +454,20 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg) ...@@ -459,16 +454,20 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
struct lpass_variant *v = drvdata->variant; struct lpass_variant *v = drvdata->variant;
int i; int i;
for (i = 0; i < v->i2s_ports; ++i)
if (reg == LPAIF_I2SCTL_REG(v, i))
return true;
for (i = 0; i < v->irq_ports; ++i) for (i = 0; i < v->irq_ports; ++i)
if (reg == LPAIF_IRQSTAT_REG(v, i)) if (reg == LPAIF_IRQSTAT_REG(v, i))
return true; return true;
for (i = 0; i < v->rdma_channels; ++i) for (i = 0; i < v->rdma_channels; ++i)
if (reg == LPAIF_RDMACURR_REG(v, i)) if (reg == LPAIF_RDMACURR_REG(v, i) || reg == LPAIF_RDMACTL_REG(v, i))
return true; return true;
for (i = 0; i < v->wrdma_channels; ++i) for (i = 0; i < v->wrdma_channels; ++i)
if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start)) if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start) ||
reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start))
return true; return true;
return false; return false;
...@@ -861,6 +860,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) ...@@ -861,6 +860,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
PTR_ERR(drvdata->mi2s_bit_clk[dai_id])); PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
} }
drvdata->bit_clk_state[dai_id] = LPAIF_BIT_CLK_DISABLE;
} }
/* Allocation for i2sctl regmap fields */ /* Allocation for i2sctl regmap fields */
......
...@@ -60,6 +60,13 @@ ...@@ -60,6 +60,13 @@
#define LPAIF_I2SCTL_BITWIDTH_24 1 #define LPAIF_I2SCTL_BITWIDTH_24 1
#define LPAIF_I2SCTL_BITWIDTH_32 2 #define LPAIF_I2SCTL_BITWIDTH_32 2
#define LPAIF_BIT_CLK_DISABLE 0
#define LPAIF_BIT_CLK_ENABLE 1
#define LPAIF_I2SCTL_RESET_STATE 0x003C0004
#define LPAIF_DMACTL_RESET_STATE 0x00200000
/* LPAIF IRQ */ /* LPAIF IRQ */
#define LPAIF_IRQ_REG_ADDR(v, addr, port) \ #define LPAIF_IRQ_REG_ADDR(v, addr, port) \
(v->irq_reg_base + (addr) + v->irq_reg_stride * (port)) (v->irq_reg_base + (addr) + v->irq_reg_stride * (port))
......
...@@ -110,6 +110,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component, ...@@ -110,6 +110,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component,
struct regmap *map; struct regmap *map;
unsigned int dai_id = cpu_dai->driver->id; unsigned int dai_id = cpu_dai->driver->id;
component->id = dai_id;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
...@@ -451,19 +452,34 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component, ...@@ -451,19 +452,34 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
unsigned int reg_irqclr = 0, val_irqclr = 0; unsigned int reg_irqclr = 0, val_irqclr = 0;
unsigned int reg_irqen = 0, val_irqen = 0, val_mask = 0; unsigned int reg_irqen = 0, val_irqen = 0, val_mask = 0;
unsigned int dai_id = cpu_dai->driver->id; unsigned int dai_id = cpu_dai->driver->id;
unsigned int dma_ctrl_reg = 0;
ch = pcm_data->dma_ch; ch = pcm_data->dma_ch;
if (dir == SNDRV_PCM_STREAM_PLAYBACK) { if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
id = pcm_data->dma_ch; id = pcm_data->dma_ch;
if (dai_id == LPASS_DP_RX) if (dai_id == LPASS_DP_RX) {
dmactl = drvdata->hdmi_rd_dmactl; dmactl = drvdata->hdmi_rd_dmactl;
else map = drvdata->hdmiif_map;
} else {
dmactl = drvdata->rd_dmactl; dmactl = drvdata->rd_dmactl;
map = drvdata->lpaif_map;
}
} else { } else {
dmactl = drvdata->wr_dmactl; dmactl = drvdata->wr_dmactl;
id = pcm_data->dma_ch - v->wrdma_channel_start; id = pcm_data->dma_ch - v->wrdma_channel_start;
map = drvdata->lpaif_map;
}
ret = regmap_read(map, LPAIF_DMACTL_REG(v, ch, dir, dai_id), &dma_ctrl_reg);
if (ret) {
dev_err(soc_runtime->dev, "error reading from rdmactl reg: %d\n", ret);
return ret;
} }
if (dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE ||
dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE + 1) {
dev_err(soc_runtime->dev, "error in rdmactl register state\n");
return -ENOTRECOVERABLE;
}
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
......
...@@ -68,6 +68,7 @@ struct lpass_data { ...@@ -68,6 +68,7 @@ struct lpass_data {
unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS];
unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS];
int hdmi_port_enable; int hdmi_port_enable;
int bit_clk_state[LPASS_MAX_MI2S_PORTS];
/* low-power audio interface (LPAIF) registers */ /* low-power audio interface (LPAIF) registers */
void __iomem *lpaif; void __iomem *lpaif;
......
...@@ -607,7 +607,7 @@ static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol, ...@@ -607,7 +607,7 @@ static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol, static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo) struct snd_ctl_elem_info *uinfo)
{ {
uinfo->count = 1; uinfo->count = 34;
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->value.integer.max = 0x7FFF; uinfo->value.integer.max = 0x7FFF;
uinfo->value.integer.min = 0; uinfo->value.integer.min = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment