sound fixes for 5.16-rc3
A lot of small changes at this time. There are many ASoC fixes, and the majority of them are new machine quirks for Intel platforms, as well as the device-specific fixes for Mediatek and Qualcomm. In addition, a regression fix for USB-audio and a few more HD- and USB-audio quirks are found here. -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmGbwIoOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE+img//RtAbJKqAnyksve8R8MXygLZnXpt5SnqaCKM+ J7wS16pEzWdPrnfW1bhyooy3xdGttRDyye5PVBbA55p3me5d5MPMLMcnESnD6Fw0 RVkw9F+SMdLF9neO6+mxBUivwNap2SjmXd0+40vJLXooBLgM8PZnfV8RqCS4DgzL wUnqAQAS/vqMXzflIuHXSp2k2ZA/RhTsj/NEt8cf9Oy7YY8eaWFjckrkp+WBd13W jplucD/GjCfWQe3fKb3dFrXsS02+iJqudXpBfpzIUbuPNJr2iI/nfluuvXRcUmyd LjfdQIOVEUwAMd/2vcBvujfUFYaJfcopK/DJkBNTJQK4KuSjsp2Lhj3Kw8jdLOqH ymrHONZ07j4Y0bqvydn22H5T78D+TT5nD4GKVrUFAoNbwXYVmfgPvqlNxhFZBVXV gbUwD9ZG8j2pYftCVaiLGfnt/ogd87VFGsjmA3b4Z1Y1vvxlqhVG2P/yEhPNdcSj 48TZ+bzQC2YvGYxFfB9ABn0N+hU4+VbN6fZOBg9Dara6bzHNK50w27Zm6ZR2zRek uZ2LnH9c4bzgbrhdXA3IBMavExwcyuCS6V/7cx3SLQGpFIHnsNmmqgNsBKPw/9bd hOI0cEtCCa6PX83tQ3wJpOOFR4zkHoD9NVyOlG7f/v13YOelqsGaLlpq0ELSRdVH xBUbB7k= =sp2K -----END PGP SIGNATURE----- Merge tag 'sound-5.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "A lot of small changes at this time. There are many ASoC fixes, and the majority of them are new machine quirks for Intel platforms, as well as the device-specific fixes for Mediatek and Qualcomm. In addition, a regression fix for USB-audio and a few more HD- and USB-audio quirks are found here" * tag 'sound-5.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (41 commits) ALSA: intel-dsp-config: add quirk for JSL devices based on ES8336 codec ALSA: usb-audio: Don't start stream for capture at prepare ALSA: usb-audio: Switch back to non-latency mode at a later point ALSA: ctxfi: Fix out-of-range access ALSA: hda/realtek: Fix LED on HP ProBook 435 G7 ASoC: stm32: i2s: fix 32 bits channel length without mclk ASoC: codecs: lpass-rx-macro: fix HPHR setting CLSH mask ASoC: codecs: wcd934x: return error code correctly from hw_params ASoC: codecs: wcd938x: fix volatile register range ASoC: topology: Add missing rwsem around snd_ctl_remove() calls ASoC: qdsp6: q6routing: validate port id before setting up route ASoC: qdsp6: q6adm: improve error reporting ASoC: qdsp6: q6asm: fix q6asm_dai_prepare error handling ASoC: qdsp6: q6routing: Conditionally reset FrontEnd Mixer ASoC: qdsp6: qdsp6: q6prm: handle clk disable correctly ASoC: wm_adsp: wm_adsp_control_add() error: uninitialized symbol 'ret' ALSA: cmipci: Drop stale variable assignment ALSA: hda/realtek: Add quirk for ASRock NUC Box 1100 ASoC: rsnd: fixup DMAEngine API ASoC: SOF: build compression interface into snd_sof.ko ...
This commit is contained in:
commit
b735936289
|
@ -299,6 +299,15 @@ static const struct config_entry config_table[] = {
|
|||
},
|
||||
#endif
|
||||
|
||||
/* JasperLake */
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
|
||||
{
|
||||
.flags = FLAG_SOF,
|
||||
.device = 0x4dc8,
|
||||
.codec_hid = "ESSX8336",
|
||||
},
|
||||
#endif
|
||||
|
||||
/* Tigerlake */
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
|
||||
{
|
||||
|
|
|
@ -3218,7 +3218,6 @@ static int snd_cmipci_probe(struct pci_dev *pci,
|
|||
{
|
||||
static int dev;
|
||||
struct snd_card *card;
|
||||
struct cmipci *cm;
|
||||
int err;
|
||||
|
||||
if (dev >= SNDRV_CARDS)
|
||||
|
@ -3229,10 +3228,9 @@ static int snd_cmipci_probe(struct pci_dev *pci,
|
|||
}
|
||||
|
||||
err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
|
||||
sizeof(*cm), &card);
|
||||
sizeof(struct cmipci), &card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
cm = card->private_data;
|
||||
|
||||
switch (pci->device) {
|
||||
case PCI_DEVICE_ID_CMEDIA_CM8738:
|
||||
|
|
|
@ -23,16 +23,15 @@
|
|||
|
||||
#define BLANK_SLOT 4094
|
||||
|
||||
static int amixer_master(struct rsc *rsc)
|
||||
static void amixer_master(struct rsc *rsc)
|
||||
{
|
||||
rsc->conj = 0;
|
||||
return rsc->idx = container_of(rsc, struct amixer, rsc)->idx[0];
|
||||
rsc->idx = container_of(rsc, struct amixer, rsc)->idx[0];
|
||||
}
|
||||
|
||||
static int amixer_next_conj(struct rsc *rsc)
|
||||
static void amixer_next_conj(struct rsc *rsc)
|
||||
{
|
||||
rsc->conj++;
|
||||
return container_of(rsc, struct amixer, rsc)->idx[rsc->conj];
|
||||
}
|
||||
|
||||
static int amixer_index(const struct rsc *rsc)
|
||||
|
@ -331,16 +330,15 @@ int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr)
|
|||
|
||||
/* SUM resource management */
|
||||
|
||||
static int sum_master(struct rsc *rsc)
|
||||
static void sum_master(struct rsc *rsc)
|
||||
{
|
||||
rsc->conj = 0;
|
||||
return rsc->idx = container_of(rsc, struct sum, rsc)->idx[0];
|
||||
rsc->idx = container_of(rsc, struct sum, rsc)->idx[0];
|
||||
}
|
||||
|
||||
static int sum_next_conj(struct rsc *rsc)
|
||||
static void sum_next_conj(struct rsc *rsc)
|
||||
{
|
||||
rsc->conj++;
|
||||
return container_of(rsc, struct sum, rsc)->idx[rsc->conj];
|
||||
}
|
||||
|
||||
static int sum_index(const struct rsc *rsc)
|
||||
|
|
|
@ -51,12 +51,12 @@ static const struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
|
|||
[SPDIFIO] = {.left = 0x05, .right = 0x85},
|
||||
};
|
||||
|
||||
static int daio_master(struct rsc *rsc)
|
||||
static void daio_master(struct rsc *rsc)
|
||||
{
|
||||
/* Actually, this is not the resource index of DAIO.
|
||||
* For DAO, it is the input mapper index. And, for DAI,
|
||||
* it is the output time-slot index. */
|
||||
return rsc->conj = rsc->idx;
|
||||
rsc->conj = rsc->idx;
|
||||
}
|
||||
|
||||
static int daio_index(const struct rsc *rsc)
|
||||
|
@ -64,19 +64,19 @@ static int daio_index(const struct rsc *rsc)
|
|||
return rsc->conj;
|
||||
}
|
||||
|
||||
static int daio_out_next_conj(struct rsc *rsc)
|
||||
static void daio_out_next_conj(struct rsc *rsc)
|
||||
{
|
||||
return rsc->conj += 2;
|
||||
rsc->conj += 2;
|
||||
}
|
||||
|
||||
static int daio_in_next_conj_20k1(struct rsc *rsc)
|
||||
static void daio_in_next_conj_20k1(struct rsc *rsc)
|
||||
{
|
||||
return rsc->conj += 0x200;
|
||||
rsc->conj += 0x200;
|
||||
}
|
||||
|
||||
static int daio_in_next_conj_20k2(struct rsc *rsc)
|
||||
static void daio_in_next_conj_20k2(struct rsc *rsc)
|
||||
{
|
||||
return rsc->conj += 0x100;
|
||||
rsc->conj += 0x100;
|
||||
}
|
||||
|
||||
static const struct rsc_ops daio_out_rsc_ops = {
|
||||
|
|
|
@ -109,18 +109,17 @@ static int audio_ring_slot(const struct rsc *rsc)
|
|||
return (rsc->conj << 4) + offset_in_audio_slot_block[rsc->type];
|
||||
}
|
||||
|
||||
static int rsc_next_conj(struct rsc *rsc)
|
||||
static void rsc_next_conj(struct rsc *rsc)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; (i < 8) && (!(rsc->msr & (0x1 << i))); )
|
||||
i++;
|
||||
rsc->conj += (AUDIO_SLOT_BLOCK_NUM >> i);
|
||||
return rsc->conj;
|
||||
}
|
||||
|
||||
static int rsc_master(struct rsc *rsc)
|
||||
static void rsc_master(struct rsc *rsc)
|
||||
{
|
||||
return rsc->conj = rsc->idx;
|
||||
rsc->conj = rsc->idx;
|
||||
}
|
||||
|
||||
static const struct rsc_ops rsc_generic_ops = {
|
||||
|
|
|
@ -39,8 +39,8 @@ struct rsc {
|
|||
};
|
||||
|
||||
struct rsc_ops {
|
||||
int (*master)(struct rsc *rsc); /* Move to master resource */
|
||||
int (*next_conj)(struct rsc *rsc); /* Move to next conjugate resource */
|
||||
void (*master)(struct rsc *rsc); /* Move to master resource */
|
||||
void (*next_conj)(struct rsc *rsc); /* Move to next conjugate resource */
|
||||
int (*index)(const struct rsc *rsc); /* Return the index of resource */
|
||||
/* Return the output slot number */
|
||||
int (*output_slot)(const struct rsc *rsc);
|
||||
|
|
|
@ -590,16 +590,15 @@ int src_mgr_destroy(struct src_mgr *src_mgr)
|
|||
|
||||
/* SRCIMP resource manager operations */
|
||||
|
||||
static int srcimp_master(struct rsc *rsc)
|
||||
static void srcimp_master(struct rsc *rsc)
|
||||
{
|
||||
rsc->conj = 0;
|
||||
return rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0];
|
||||
rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0];
|
||||
}
|
||||
|
||||
static int srcimp_next_conj(struct rsc *rsc)
|
||||
static void srcimp_next_conj(struct rsc *rsc)
|
||||
{
|
||||
rsc->conj++;
|
||||
return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
|
||||
}
|
||||
|
||||
static int srcimp_index(const struct rsc *rsc)
|
||||
|
|
|
@ -6521,6 +6521,27 @@ static void alc256_fixup_tongfang_reset_persistent_settings(struct hda_codec *co
|
|||
alc_write_coef_idx(codec, 0x45, 0x5089);
|
||||
}
|
||||
|
||||
static const struct coef_fw alc233_fixup_no_audio_jack_coefs[] = {
|
||||
WRITE_COEF(0x1a, 0x9003), WRITE_COEF(0x1b, 0x0e2b), WRITE_COEF(0x37, 0xfe06),
|
||||
WRITE_COEF(0x38, 0x4981), WRITE_COEF(0x45, 0xd489), WRITE_COEF(0x46, 0x0074),
|
||||
WRITE_COEF(0x49, 0x0149),
|
||||
{}
|
||||
};
|
||||
|
||||
static void alc233_fixup_no_audio_jack(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix,
|
||||
int action)
|
||||
{
|
||||
/*
|
||||
* The audio jack input and output is not detected on the ASRock NUC Box
|
||||
* 1100 series when cold booting without this fix. Warm rebooting from a
|
||||
* certain other OS makes the audio functional, as COEF settings are
|
||||
* preserved in this case. This fix sets these altered COEF values as
|
||||
* the default.
|
||||
*/
|
||||
alc_process_coef_fw(codec, alc233_fixup_no_audio_jack_coefs);
|
||||
}
|
||||
|
||||
enum {
|
||||
ALC269_FIXUP_GPIO2,
|
||||
ALC269_FIXUP_SONY_VAIO,
|
||||
|
@ -6740,6 +6761,7 @@ enum {
|
|||
ALC287_FIXUP_13S_GEN2_SPEAKERS,
|
||||
ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS,
|
||||
ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
|
||||
ALC233_FIXUP_NO_AUDIO_JACK,
|
||||
};
|
||||
|
||||
static const struct hda_fixup alc269_fixups[] = {
|
||||
|
@ -8460,6 +8482,10 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
|
||||
},
|
||||
[ALC233_FIXUP_NO_AUDIO_JACK] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc233_fixup_no_audio_jack,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
|
@ -8639,6 +8665,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x103c, 0x8728, "HP EliteBook 840 G7", ALC285_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8735, "HP ProBook 435 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
|
||||
|
@ -8894,6 +8921,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
|
||||
SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
|
||||
SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
|
||||
SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
|
||||
SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
|
||||
SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
|
||||
SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI),
|
||||
|
|
|
@ -612,6 +612,12 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0),
|
||||
|
||||
SND_SOC_DAPM_SIGGEN("VSENSE"),
|
||||
SND_SOC_DAPM_SIGGEN("ISENSE"),
|
||||
SND_SOC_DAPM_SIGGEN("VP"),
|
||||
SND_SOC_DAPM_SIGGEN("VBST"),
|
||||
SND_SOC_DAPM_SIGGEN("TEMP"),
|
||||
|
||||
SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0),
|
||||
SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0),
|
||||
SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0),
|
||||
|
@ -623,12 +629,6 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
|
|||
cs35l41_main_amp_event,
|
||||
SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
|
||||
SND_SOC_DAPM_INPUT("VP"),
|
||||
SND_SOC_DAPM_INPUT("VBST"),
|
||||
SND_SOC_DAPM_INPUT("ISENSE"),
|
||||
SND_SOC_DAPM_INPUT("VSENSE"),
|
||||
SND_SOC_DAPM_INPUT("TEMP"),
|
||||
|
||||
SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux),
|
||||
SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux),
|
||||
SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux),
|
||||
|
@ -674,8 +674,8 @@ static const struct snd_soc_dapm_route cs35l41_audio_map[] = {
|
|||
{"VMON ADC", NULL, "VSENSE"},
|
||||
{"IMON ADC", NULL, "ISENSE"},
|
||||
{"VPMON ADC", NULL, "VP"},
|
||||
{"TEMPMON ADC", NULL, "TEMP"},
|
||||
{"VBSTMON ADC", NULL, "VBST"},
|
||||
{"TEMPMON ADC", NULL, "TEMP"},
|
||||
|
||||
{"ASPRX1", NULL, "AMP Playback"},
|
||||
{"ASPRX2", NULL, "AMP Playback"},
|
||||
|
|
|
@ -2188,7 +2188,7 @@ static int rx_macro_config_classh(struct snd_soc_component *component,
|
|||
snd_soc_component_update_bits(component,
|
||||
CDC_RX_CLSH_DECAY_CTRL,
|
||||
CDC_RX_CLSH_DECAY_RATE_MASK, 0x0);
|
||||
snd_soc_component_update_bits(component,
|
||||
snd_soc_component_write_field(component,
|
||||
CDC_RX_RX1_RX_PATH_CFG0,
|
||||
CDC_RX_RXn_CLSH_EN_MASK, 0x1);
|
||||
break;
|
||||
|
|
|
@ -1311,13 +1311,54 @@ static int rt1011_r0_load_info(struct snd_kcontrol *kcontrol,
|
|||
.put = rt1011_r0_load_mode_put \
|
||||
}
|
||||
|
||||
static const char * const rt1011_i2s_ref_texts[] = {
|
||||
"Left Channel", "Right Channel"
|
||||
static const char * const rt1011_i2s_ref[] = {
|
||||
"None", "Left Channel", "Right Channel"
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(rt1011_i2s_ref_enum,
|
||||
RT1011_TDM1_SET_1, 7,
|
||||
rt1011_i2s_ref_texts);
|
||||
static SOC_ENUM_SINGLE_DECL(rt1011_i2s_ref_enum, 0, 0,
|
||||
rt1011_i2s_ref);
|
||||
|
||||
static int rt1011_i2s_ref_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct rt1011_priv *rt1011 =
|
||||
snd_soc_component_get_drvdata(component);
|
||||
|
||||
rt1011->i2s_ref = ucontrol->value.enumerated.item[0];
|
||||
switch (rt1011->i2s_ref) {
|
||||
case RT1011_I2S_REF_LEFT_CH:
|
||||
regmap_write(rt1011->regmap, RT1011_TDM_TOTAL_SET, 0x0240);
|
||||
regmap_write(rt1011->regmap, RT1011_TDM1_SET_2, 0x8);
|
||||
regmap_write(rt1011->regmap, RT1011_TDM1_SET_1, 0x1022);
|
||||
regmap_write(rt1011->regmap, RT1011_ADCDAT_OUT_SOURCE, 0x4);
|
||||
break;
|
||||
case RT1011_I2S_REF_RIGHT_CH:
|
||||
regmap_write(rt1011->regmap, RT1011_TDM_TOTAL_SET, 0x0240);
|
||||
regmap_write(rt1011->regmap, RT1011_TDM1_SET_2, 0x8);
|
||||
regmap_write(rt1011->regmap, RT1011_TDM1_SET_1, 0x10a2);
|
||||
regmap_write(rt1011->regmap, RT1011_ADCDAT_OUT_SOURCE, 0x4);
|
||||
break;
|
||||
default:
|
||||
dev_info(component->dev, "I2S Reference: Do nothing\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1011_i2s_ref_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct rt1011_priv *rt1011 =
|
||||
snd_soc_component_get_drvdata(component);
|
||||
|
||||
ucontrol->value.enumerated.item[0] = rt1011->i2s_ref;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new rt1011_snd_controls[] = {
|
||||
/* I2S Data In Selection */
|
||||
|
@ -1358,7 +1399,8 @@ static const struct snd_kcontrol_new rt1011_snd_controls[] = {
|
|||
SOC_SINGLE("R0 Temperature", RT1011_STP_INITIAL_RESISTANCE_TEMP,
|
||||
2, 255, 0),
|
||||
/* I2S Reference */
|
||||
SOC_ENUM("I2S Reference", rt1011_i2s_ref_enum),
|
||||
SOC_ENUM_EXT("I2S Reference", rt1011_i2s_ref_enum,
|
||||
rt1011_i2s_ref_get, rt1011_i2s_ref_put),
|
||||
};
|
||||
|
||||
static int rt1011_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
|
||||
|
@ -2017,6 +2059,7 @@ static int rt1011_probe(struct snd_soc_component *component)
|
|||
|
||||
schedule_work(&rt1011->cali_work);
|
||||
|
||||
rt1011->i2s_ref = 0;
|
||||
rt1011->bq_drc_params = devm_kcalloc(component->dev,
|
||||
RT1011_ADVMODE_NUM, sizeof(struct rt1011_bq_drc_params *),
|
||||
GFP_KERNEL);
|
||||
|
|
|
@ -654,6 +654,12 @@ enum {
|
|||
RT1011_AIFS
|
||||
};
|
||||
|
||||
enum {
|
||||
RT1011_I2S_REF_NONE,
|
||||
RT1011_I2S_REF_LEFT_CH,
|
||||
RT1011_I2S_REF_RIGHT_CH,
|
||||
};
|
||||
|
||||
/* BiQual & DRC related settings */
|
||||
#define RT1011_BQ_DRC_NUM 128
|
||||
struct rt1011_bq_drc_params {
|
||||
|
@ -692,6 +698,7 @@ struct rt1011_priv {
|
|||
unsigned int r0_reg, cali_done;
|
||||
unsigned int r0_calib, temperature_calib;
|
||||
int recv_spk_mode;
|
||||
int i2s_ref;
|
||||
};
|
||||
|
||||
#endif /* end of _RT1011_H_ */
|
||||
|
|
|
@ -198,6 +198,7 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
|
|||
}
|
||||
|
||||
mutex_init(&rt5682->calibrate_mutex);
|
||||
mutex_init(&rt5682->jdet_mutex);
|
||||
rt5682_calibrate(rt5682);
|
||||
|
||||
rt5682_apply_patch_list(rt5682, &i2c->dev);
|
||||
|
|
|
@ -48,6 +48,8 @@ static const struct reg_sequence patch_list[] = {
|
|||
{RT5682_SAR_IL_CMD_6, 0x0110},
|
||||
{RT5682_CHARGE_PUMP_1, 0x0210},
|
||||
{RT5682_HP_LOGIC_CTRL_2, 0x0007},
|
||||
{RT5682_SAR_IL_CMD_2, 0xac00},
|
||||
{RT5682_CBJ_CTRL_7, 0x0104},
|
||||
};
|
||||
|
||||
void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev)
|
||||
|
@ -940,6 +942,10 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert)
|
|||
snd_soc_component_update_bits(component,
|
||||
RT5682_HP_CHARGE_PUMP_1,
|
||||
RT5682_OSW_L_MASK | RT5682_OSW_R_MASK, 0);
|
||||
rt5682_enable_push_button_irq(component, false);
|
||||
snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
|
||||
RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW);
|
||||
usleep_range(55000, 60000);
|
||||
snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
|
||||
RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_HIGH);
|
||||
|
||||
|
@ -1092,6 +1098,7 @@ void rt5682_jack_detect_handler(struct work_struct *work)
|
|||
while (!rt5682->component->card->instantiated)
|
||||
usleep_range(10000, 15000);
|
||||
|
||||
mutex_lock(&rt5682->jdet_mutex);
|
||||
mutex_lock(&rt5682->calibrate_mutex);
|
||||
|
||||
val = snd_soc_component_read(rt5682->component, RT5682_AJD1_CTRL)
|
||||
|
@ -1165,6 +1172,7 @@ void rt5682_jack_detect_handler(struct work_struct *work)
|
|||
}
|
||||
|
||||
mutex_unlock(&rt5682->calibrate_mutex);
|
||||
mutex_unlock(&rt5682->jdet_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt5682_jack_detect_handler);
|
||||
|
||||
|
@ -1514,6 +1522,7 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
|
|||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_dapm_to_component(w->dapm);
|
||||
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
|
@ -1525,12 +1534,17 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
|
|||
RT5682_DEPOP_1, 0x60, 0x60);
|
||||
snd_soc_component_update_bits(component,
|
||||
RT5682_DAC_ADC_DIG_VOL1, 0x00c0, 0x0080);
|
||||
|
||||
mutex_lock(&rt5682->jdet_mutex);
|
||||
|
||||
snd_soc_component_update_bits(component, RT5682_HP_CTRL_2,
|
||||
RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN,
|
||||
RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN);
|
||||
usleep_range(5000, 10000);
|
||||
snd_soc_component_update_bits(component, RT5682_CHARGE_PUMP_1,
|
||||
RT5682_CP_SW_SIZE_MASK, RT5682_CP_SW_SIZE_L);
|
||||
|
||||
mutex_unlock(&rt5682->jdet_mutex);
|
||||
break;
|
||||
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
|
@ -2942,10 +2956,7 @@ static int rt5682_suspend(struct snd_soc_component *component)
|
|||
|
||||
cancel_delayed_work_sync(&rt5682->jack_detect_work);
|
||||
cancel_delayed_work_sync(&rt5682->jd_check_work);
|
||||
if (rt5682->hs_jack && rt5682->jack_type == SND_JACK_HEADSET) {
|
||||
snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
|
||||
RT5682_MB1_PATH_MASK | RT5682_MB2_PATH_MASK,
|
||||
RT5682_CTRL_MB1_REG | RT5682_CTRL_MB2_REG);
|
||||
if (rt5682->hs_jack && (rt5682->jack_type & SND_JACK_HEADSET) == SND_JACK_HEADSET) {
|
||||
val = snd_soc_component_read(component,
|
||||
RT5682_CBJ_CTRL_2) & RT5682_JACK_TYPE_MASK;
|
||||
|
||||
|
@ -2967,10 +2978,17 @@ static int rt5682_suspend(struct snd_soc_component *component)
|
|||
/* enter SAR ADC power saving mode */
|
||||
snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1,
|
||||
RT5682_SAR_BUTT_DET_MASK | RT5682_SAR_BUTDET_MODE_MASK |
|
||||
RT5682_SAR_BUTDET_RST_MASK | RT5682_SAR_SEL_MB1_MB2_MASK, 0);
|
||||
RT5682_SAR_SEL_MB1_MB2_MASK, 0);
|
||||
usleep_range(5000, 6000);
|
||||
snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
|
||||
RT5682_MB1_PATH_MASK | RT5682_MB2_PATH_MASK,
|
||||
RT5682_CTRL_MB1_REG | RT5682_CTRL_MB2_REG);
|
||||
usleep_range(10000, 12000);
|
||||
snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1,
|
||||
RT5682_SAR_BUTT_DET_MASK | RT5682_SAR_BUTDET_MODE_MASK | RT5682_SAR_BUTDET_RST_MASK,
|
||||
RT5682_SAR_BUTT_DET_EN | RT5682_SAR_BUTDET_POW_SAV | RT5682_SAR_BUTDET_RST_NORMAL);
|
||||
RT5682_SAR_BUTT_DET_MASK | RT5682_SAR_BUTDET_MODE_MASK,
|
||||
RT5682_SAR_BUTT_DET_EN | RT5682_SAR_BUTDET_POW_SAV);
|
||||
snd_soc_component_update_bits(component, RT5682_HP_CHARGE_PUMP_1,
|
||||
RT5682_OSW_L_MASK | RT5682_OSW_R_MASK, 0);
|
||||
}
|
||||
|
||||
regcache_cache_only(rt5682->regmap, true);
|
||||
|
@ -2988,10 +3006,11 @@ static int rt5682_resume(struct snd_soc_component *component)
|
|||
regcache_cache_only(rt5682->regmap, false);
|
||||
regcache_sync(rt5682->regmap);
|
||||
|
||||
if (rt5682->hs_jack && rt5682->jack_type == SND_JACK_HEADSET) {
|
||||
if (rt5682->hs_jack && (rt5682->jack_type & SND_JACK_HEADSET) == SND_JACK_HEADSET) {
|
||||
snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1,
|
||||
RT5682_SAR_BUTDET_MODE_MASK | RT5682_SAR_SEL_MB1_MB2_MASK,
|
||||
RT5682_SAR_BUTDET_POW_NORM | RT5682_SAR_SEL_MB1_MB2_AUTO);
|
||||
usleep_range(5000, 6000);
|
||||
snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
|
||||
RT5682_MB1_PATH_MASK | RT5682_MB2_PATH_MASK,
|
||||
RT5682_CTRL_MB1_FSM | RT5682_CTRL_MB2_FSM);
|
||||
|
@ -2999,8 +3018,9 @@ static int rt5682_resume(struct snd_soc_component *component)
|
|||
RT5682_PWR_CBJ, RT5682_PWR_CBJ);
|
||||
}
|
||||
|
||||
rt5682->jack_type = 0;
|
||||
mod_delayed_work(system_power_efficient_wq,
|
||||
&rt5682->jack_detect_work, msecs_to_jiffies(250));
|
||||
&rt5682->jack_detect_work, msecs_to_jiffies(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1463,6 +1463,7 @@ struct rt5682_priv {
|
|||
|
||||
int jack_type;
|
||||
int irq_work_delay_time;
|
||||
struct mutex jdet_mutex;
|
||||
};
|
||||
|
||||
extern const char *rt5682_supply_names[RT5682_NUM_SUPPLIES];
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
|
@ -23,9 +24,11 @@
|
|||
#define RT9120_REG_ERRRPT 0x10
|
||||
#define RT9120_REG_MSVOL 0x20
|
||||
#define RT9120_REG_SWRESET 0x40
|
||||
#define RT9120_REG_INTERCFG 0x63
|
||||
#define RT9120_REG_INTERNAL0 0x65
|
||||
#define RT9120_REG_INTERNAL1 0x69
|
||||
#define RT9120_REG_UVPOPT 0x6C
|
||||
#define RT9120_REG_DIGCFG 0xF8
|
||||
|
||||
#define RT9120_VID_MASK GENMASK(15, 8)
|
||||
#define RT9120_SWRST_MASK BIT(7)
|
||||
|
@ -46,8 +49,10 @@
|
|||
#define RT9120_CFG_WORDLEN_24 24
|
||||
#define RT9120_CFG_WORDLEN_32 32
|
||||
#define RT9120_DVDD_UVSEL_MASK GENMASK(5, 4)
|
||||
#define RT9120_AUTOSYNC_MASK BIT(6)
|
||||
|
||||
#define RT9120_VENDOR_ID 0x4200
|
||||
#define RT9120_VENDOR_ID 0x42
|
||||
#define RT9120S_VENDOR_ID 0x43
|
||||
#define RT9120_RESET_WAITMS 20
|
||||
#define RT9120_CHIPON_WAITMS 20
|
||||
#define RT9120_AMPON_WAITMS 50
|
||||
|
@ -61,9 +66,16 @@
|
|||
SNDRV_PCM_FMTBIT_S24_LE |\
|
||||
SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
enum {
|
||||
CHIP_IDX_RT9120 = 0,
|
||||
CHIP_IDX_RT9120S,
|
||||
CHIP_IDX_MAX
|
||||
};
|
||||
|
||||
struct rt9120_data {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
int chip_idx;
|
||||
};
|
||||
|
||||
/* 11bit [min,max,step] = [-103.9375dB, 24dB, 0.0625dB] */
|
||||
|
@ -149,8 +161,12 @@ static int rt9120_codec_probe(struct snd_soc_component *comp)
|
|||
snd_soc_component_init_regmap(comp, data->regmap);
|
||||
|
||||
/* Internal setting */
|
||||
snd_soc_component_write(comp, RT9120_REG_INTERNAL1, 0x03);
|
||||
snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x69);
|
||||
if (data->chip_idx == CHIP_IDX_RT9120S) {
|
||||
snd_soc_component_write(comp, RT9120_REG_INTERCFG, 0xde);
|
||||
snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x66);
|
||||
} else
|
||||
snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x04);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -201,8 +217,8 @@ static int rt9120_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_component *comp = dai->component;
|
||||
unsigned int param_width, param_slot_width;
|
||||
int width;
|
||||
unsigned int param_width, param_slot_width, auto_sync;
|
||||
int width, fs;
|
||||
|
||||
switch (width = params_width(param)) {
|
||||
case 16:
|
||||
|
@ -240,6 +256,16 @@ static int rt9120_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
snd_soc_component_update_bits(comp, RT9120_REG_I2SWL,
|
||||
RT9120_AUDWL_MASK, param_slot_width);
|
||||
|
||||
fs = width * params_channels(param);
|
||||
/* If fs is divided by 48, disable auto sync */
|
||||
if (fs % 48 == 0)
|
||||
auto_sync = 0;
|
||||
else
|
||||
auto_sync = RT9120_AUTOSYNC_MASK;
|
||||
|
||||
snd_soc_component_update_bits(comp, RT9120_REG_DIGCFG,
|
||||
RT9120_AUTOSYNC_MASK, auto_sync);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -279,9 +305,11 @@ static const struct regmap_range rt9120_rd_yes_ranges[] = {
|
|||
regmap_reg_range(0x20, 0x27),
|
||||
regmap_reg_range(0x30, 0x38),
|
||||
regmap_reg_range(0x3A, 0x40),
|
||||
regmap_reg_range(0x63, 0x63),
|
||||
regmap_reg_range(0x65, 0x65),
|
||||
regmap_reg_range(0x69, 0x69),
|
||||
regmap_reg_range(0x6C, 0x6C)
|
||||
regmap_reg_range(0x6C, 0x6C),
|
||||
regmap_reg_range(0xF8, 0xF8)
|
||||
};
|
||||
|
||||
static const struct regmap_access_table rt9120_rd_table = {
|
||||
|
@ -297,9 +325,11 @@ static const struct regmap_range rt9120_wr_yes_ranges[] = {
|
|||
regmap_reg_range(0x30, 0x38),
|
||||
regmap_reg_range(0x3A, 0x3D),
|
||||
regmap_reg_range(0x40, 0x40),
|
||||
regmap_reg_range(0x63, 0x63),
|
||||
regmap_reg_range(0x65, 0x65),
|
||||
regmap_reg_range(0x69, 0x69),
|
||||
regmap_reg_range(0x6C, 0x6C)
|
||||
regmap_reg_range(0x6C, 0x6C),
|
||||
regmap_reg_range(0xF8, 0xF8)
|
||||
};
|
||||
|
||||
static const struct regmap_access_table rt9120_wr_table = {
|
||||
|
@ -370,7 +400,7 @@ static int rt9120_reg_write(void *context, unsigned int reg, unsigned int val)
|
|||
static const struct regmap_config rt9120_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 32,
|
||||
.max_register = RT9120_REG_UVPOPT,
|
||||
.max_register = RT9120_REG_DIGCFG,
|
||||
|
||||
.reg_read = rt9120_reg_read,
|
||||
.reg_write = rt9120_reg_write,
|
||||
|
@ -388,8 +418,16 @@ static int rt9120_check_vendor_info(struct rt9120_data *data)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((devid & RT9120_VID_MASK) != RT9120_VENDOR_ID) {
|
||||
dev_err(data->dev, "DEVID not correct [0x%04x]\n", devid);
|
||||
devid = FIELD_GET(RT9120_VID_MASK, devid);
|
||||
switch (devid) {
|
||||
case RT9120_VENDOR_ID:
|
||||
data->chip_idx = CHIP_IDX_RT9120;
|
||||
break;
|
||||
case RT9120S_VENDOR_ID:
|
||||
data->chip_idx = CHIP_IDX_RT9120S;
|
||||
break;
|
||||
default:
|
||||
dev_err(data->dev, "DEVID not correct [0x%0x]\n", devid);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
|
|
@ -1896,9 +1896,8 @@ static int wcd934x_hw_params(struct snd_pcm_substream *substream,
|
|||
}
|
||||
|
||||
wcd->dai[dai->id].sconfig.rate = params_rate(params);
|
||||
wcd934x_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream);
|
||||
|
||||
return 0;
|
||||
return wcd934x_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream);
|
||||
}
|
||||
|
||||
static int wcd934x_hw_free(struct snd_pcm_substream *substream,
|
||||
|
|
|
@ -1174,6 +1174,9 @@ static bool wcd938x_readonly_register(struct device *dev, unsigned int reg)
|
|||
case WCD938X_DIGITAL_INTR_STATUS_0:
|
||||
case WCD938X_DIGITAL_INTR_STATUS_1:
|
||||
case WCD938X_DIGITAL_INTR_STATUS_2:
|
||||
case WCD938X_DIGITAL_INTR_CLEAR_0:
|
||||
case WCD938X_DIGITAL_INTR_CLEAR_1:
|
||||
case WCD938X_DIGITAL_INTR_CLEAR_2:
|
||||
case WCD938X_DIGITAL_SWR_HM_TEST_0:
|
||||
case WCD938X_DIGITAL_SWR_HM_TEST_1:
|
||||
case WCD938X_DIGITAL_EFUSE_T_DATA_0:
|
||||
|
|
|
@ -617,8 +617,9 @@ static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl)
|
|||
switch (cs_dsp->fw_ver) {
|
||||
case 0:
|
||||
case 1:
|
||||
snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %x",
|
||||
cs_dsp->name, region_name, cs_ctl->alg_region.alg);
|
||||
ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
|
||||
"%s %s %x", cs_dsp->name, region_name,
|
||||
cs_ctl->alg_region.alg);
|
||||
break;
|
||||
case 2:
|
||||
ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
|
||||
|
|
|
@ -248,6 +248,75 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
|
|||
SOF_BT_OFFLOAD_SSP(2) |
|
||||
SOF_SSP_BT_OFFLOAD_PRESENT),
|
||||
},
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF3"),
|
||||
},
|
||||
/* No Jack */
|
||||
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
|
||||
SOF_SDW_FOUR_SPK),
|
||||
},
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00")
|
||||
},
|
||||
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
|
||||
RT711_JD2 |
|
||||
SOF_SDW_FOUR_SPK),
|
||||
},
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01")
|
||||
},
|
||||
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
|
||||
RT711_JD2 |
|
||||
SOF_SDW_FOUR_SPK),
|
||||
},
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B11")
|
||||
},
|
||||
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
|
||||
RT711_JD2 |
|
||||
SOF_SDW_FOUR_SPK),
|
||||
},
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B12")
|
||||
},
|
||||
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
|
||||
RT711_JD2 |
|
||||
SOF_SDW_FOUR_SPK),
|
||||
},
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B13"),
|
||||
},
|
||||
/* No Jack */
|
||||
.driver_data = (void *)SOF_SDW_TGL_HDMI,
|
||||
},
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B29"),
|
||||
},
|
||||
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
|
||||
RT711_JD2 |
|
||||
SOF_SDW_FOUR_SPK),
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -74,6 +74,15 @@ static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt711_sdca_2_adr[] = {
|
||||
{
|
||||
.adr = 0x000230025D071101ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &single_endpoint,
|
||||
.name_prefix = "rt711"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1316_1_group1_adr[] = {
|
||||
{
|
||||
.adr = 0x000131025D131601ull, /* unique ID is set for some reason */
|
||||
|
@ -101,6 +110,24 @@ static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1316_0_group2_adr[] = {
|
||||
{
|
||||
.adr = 0x000031025D131601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_l_endpoint,
|
||||
.name_prefix = "rt1316-1"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = {
|
||||
{
|
||||
.adr = 0x000130025D131601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_r_endpoint,
|
||||
.name_prefix = "rt1316-2"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1316_2_single_adr[] = {
|
||||
{
|
||||
.adr = 0x000230025D131601ull,
|
||||
|
@ -209,6 +236,63 @@ static const struct snd_soc_acpi_link_adr adl_sdca_3_in_1[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr adl_sdw_rt711_link2_rt1316_link01_rt714_link3[] = {
|
||||
{
|
||||
.mask = BIT(2),
|
||||
.num_adr = ARRAY_SIZE(rt711_sdca_2_adr),
|
||||
.adr_d = rt711_sdca_2_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(0),
|
||||
.num_adr = ARRAY_SIZE(rt1316_0_group2_adr),
|
||||
.adr_d = rt1316_0_group2_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(1),
|
||||
.num_adr = ARRAY_SIZE(rt1316_1_group2_adr),
|
||||
.adr_d = rt1316_1_group2_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(3),
|
||||
.num_adr = ARRAY_SIZE(rt714_3_adr),
|
||||
.adr_d = rt714_3_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link12_rt714_link0[] = {
|
||||
{
|
||||
.mask = BIT(1),
|
||||
.num_adr = ARRAY_SIZE(rt1316_1_group1_adr),
|
||||
.adr_d = rt1316_1_group1_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(2),
|
||||
.num_adr = ARRAY_SIZE(rt1316_2_group1_adr),
|
||||
.adr_d = rt1316_2_group1_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(0),
|
||||
.num_adr = ARRAY_SIZE(rt714_0_adr),
|
||||
.adr_d = rt714_0_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link2_rt714_link3[] = {
|
||||
{
|
||||
.mask = BIT(2),
|
||||
.num_adr = ARRAY_SIZE(rt1316_2_single_adr),
|
||||
.adr_d = rt1316_2_single_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(3),
|
||||
.num_adr = ARRAY_SIZE(rt714_3_adr),
|
||||
.adr_d = rt714_3_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link2_rt714_link0[] = {
|
||||
{
|
||||
.mask = BIT(2),
|
||||
|
@ -339,6 +423,27 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = {
|
|||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-adl-rt711-l0-rt1316-l13-rt714-l2.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = 0xF, /* 4 active links required */
|
||||
.links = adl_sdw_rt711_link2_rt1316_link01_rt714_link3,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_fw_filename = "sof-adl.ri",
|
||||
.sof_tplg_filename = "sof-adl-rt711-l2-rt1316-l01-rt714-l3.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = 0xC, /* rt1316 on link2 & rt714 on link3 */
|
||||
.links = adl_sdw_rt1316_link2_rt714_link3,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_fw_filename = "sof-adl.ri",
|
||||
.sof_tplg_filename = "sof-adl-rt1316-l2-mono-rt714-l3.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = 0x7, /* rt714 on link0 & two rt1316s on link1 and link2 */
|
||||
.links = adl_sdw_rt1316_link12_rt714_link0,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_fw_filename = "sof-adl.ri",
|
||||
.sof_tplg_filename = "sof-adl-rt1316-l12-rt714-l0.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = 0x5, /* 2 active links required */
|
||||
.links = adl_sdw_rt1316_link2_rt714_link0,
|
||||
|
|
|
@ -1054,6 +1054,7 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
|
|||
int irq_id;
|
||||
struct mtk_base_afe *afe;
|
||||
struct mt8173_afe_private *afe_priv;
|
||||
struct snd_soc_component *comp_pcm, *comp_hdmi;
|
||||
|
||||
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
|
||||
if (ret)
|
||||
|
@ -1142,23 +1143,55 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
goto err_pm_disable;
|
||||
|
||||
ret = devm_snd_soc_register_component(&pdev->dev,
|
||||
&mt8173_afe_pcm_dai_component,
|
||||
mt8173_afe_pcm_dais,
|
||||
ARRAY_SIZE(mt8173_afe_pcm_dais));
|
||||
comp_pcm = devm_kzalloc(&pdev->dev, sizeof(*comp_pcm), GFP_KERNEL);
|
||||
if (!comp_pcm) {
|
||||
ret = -ENOMEM;
|
||||
goto err_pm_disable;
|
||||
}
|
||||
|
||||
ret = snd_soc_component_initialize(comp_pcm,
|
||||
&mt8173_afe_pcm_dai_component,
|
||||
&pdev->dev);
|
||||
if (ret)
|
||||
goto err_pm_disable;
|
||||
|
||||
ret = devm_snd_soc_register_component(&pdev->dev,
|
||||
&mt8173_afe_hdmi_dai_component,
|
||||
mt8173_afe_hdmi_dais,
|
||||
ARRAY_SIZE(mt8173_afe_hdmi_dais));
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
comp_pcm->debugfs_prefix = "pcm";
|
||||
#endif
|
||||
|
||||
ret = snd_soc_add_component(comp_pcm,
|
||||
mt8173_afe_pcm_dais,
|
||||
ARRAY_SIZE(mt8173_afe_pcm_dais));
|
||||
if (ret)
|
||||
goto err_pm_disable;
|
||||
|
||||
comp_hdmi = devm_kzalloc(&pdev->dev, sizeof(*comp_hdmi), GFP_KERNEL);
|
||||
if (!comp_hdmi) {
|
||||
ret = -ENOMEM;
|
||||
goto err_pm_disable;
|
||||
}
|
||||
|
||||
ret = snd_soc_component_initialize(comp_hdmi,
|
||||
&mt8173_afe_hdmi_dai_component,
|
||||
&pdev->dev);
|
||||
if (ret)
|
||||
goto err_pm_disable;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
comp_hdmi->debugfs_prefix = "hdmi";
|
||||
#endif
|
||||
|
||||
ret = snd_soc_add_component(comp_hdmi,
|
||||
mt8173_afe_hdmi_dais,
|
||||
ARRAY_SIZE(mt8173_afe_hdmi_dais));
|
||||
if (ret)
|
||||
goto err_cleanup_components;
|
||||
|
||||
dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n");
|
||||
return 0;
|
||||
|
||||
err_cleanup_components:
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
err_pm_disable:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return ret;
|
||||
|
@ -1166,6 +1199,8 @@ err_pm_disable:
|
|||
|
||||
static int mt8173_afe_pcm_dev_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (!pm_runtime_status_suspended(&pdev->dev))
|
||||
mt8173_afe_runtime_suspend(&pdev->dev);
|
||||
|
|
|
@ -30,15 +30,15 @@ static struct mt8173_rt5650_platform_data mt8173_rt5650_priv = {
|
|||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget mt8173_rt5650_widgets[] = {
|
||||
SND_SOC_DAPM_SPK("Speaker", NULL),
|
||||
SND_SOC_DAPM_SPK("Ext Spk", NULL),
|
||||
SND_SOC_DAPM_MIC("Int Mic", NULL),
|
||||
SND_SOC_DAPM_HP("Headphone", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route mt8173_rt5650_routes[] = {
|
||||
{"Speaker", NULL, "SPOL"},
|
||||
{"Speaker", NULL, "SPOR"},
|
||||
{"Ext Spk", NULL, "SPOL"},
|
||||
{"Ext Spk", NULL, "SPOR"},
|
||||
{"DMIC L1", NULL, "Int Mic"},
|
||||
{"DMIC R1", NULL, "Int Mic"},
|
||||
{"Headphone", NULL, "HPOL"},
|
||||
|
@ -48,7 +48,7 @@ static const struct snd_soc_dapm_route mt8173_rt5650_routes[] = {
|
|||
};
|
||||
|
||||
static const struct snd_kcontrol_new mt8173_rt5650_controls[] = {
|
||||
SOC_DAPM_PIN_SWITCH("Speaker"),
|
||||
SOC_DAPM_PIN_SWITCH("Ext Spk"),
|
||||
SOC_DAPM_PIN_SWITCH("Int Mic"),
|
||||
SOC_DAPM_PIN_SWITCH("Headphone"),
|
||||
SOC_DAPM_PIN_SWITCH("Headset Mic"),
|
||||
|
|
|
@ -550,6 +550,10 @@ struct audio_hw_clk_cfg {
|
|||
uint32_t clock_root;
|
||||
} __packed;
|
||||
|
||||
struct audio_hw_clk_rel_cfg {
|
||||
uint32_t clock_id;
|
||||
} __packed;
|
||||
|
||||
#define PARAM_ID_HW_EP_POWER_MODE_CFG 0x8001176
|
||||
#define AR_HW_EP_POWER_MODE_0 0 /* default */
|
||||
#define AR_HW_EP_POWER_MODE_1 1 /* XO Shutdown allowed */
|
||||
|
|
|
@ -390,7 +390,7 @@ struct q6copp *q6adm_open(struct device *dev, int port_id, int path, int rate,
|
|||
int ret = 0;
|
||||
|
||||
if (port_id < 0) {
|
||||
dev_err(dev, "Invalid port_id 0x%x\n", port_id);
|
||||
dev_err(dev, "Invalid port_id %d\n", port_id);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
|
@ -508,7 +508,7 @@ int q6adm_matrix_map(struct device *dev, int path,
|
|||
int port_idx = payload_map.port_id[i];
|
||||
|
||||
if (port_idx < 0) {
|
||||
dev_err(dev, "Invalid port_id 0x%x\n",
|
||||
dev_err(dev, "Invalid port_id %d\n",
|
||||
payload_map.port_id[i]);
|
||||
kfree(pkt);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -269,9 +269,7 @@ static int q6asm_dai_prepare(struct snd_soc_component *component,
|
|||
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: q6asm_open_write failed\n", __func__);
|
||||
q6asm_audio_client_free(prtd->audio_client);
|
||||
prtd->audio_client = NULL;
|
||||
return -ENOMEM;
|
||||
goto open_err;
|
||||
}
|
||||
|
||||
prtd->session_id = q6asm_get_session_id(prtd->audio_client);
|
||||
|
@ -279,7 +277,7 @@ static int q6asm_dai_prepare(struct snd_soc_component *component,
|
|||
prtd->session_id, substream->stream);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: stream reg failed ret:%d\n", __func__, ret);
|
||||
return ret;
|
||||
goto routing_err;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
|
@ -301,10 +299,19 @@ static int q6asm_dai_prepare(struct snd_soc_component *component,
|
|||
}
|
||||
if (ret < 0)
|
||||
dev_info(dev, "%s: CMD Format block failed\n", __func__);
|
||||
else
|
||||
prtd->state = Q6ASM_STREAM_RUNNING;
|
||||
|
||||
prtd->state = Q6ASM_STREAM_RUNNING;
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
routing_err:
|
||||
q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
|
||||
open_err:
|
||||
q6asm_unmap_memory_regions(substream->stream, prtd->audio_client);
|
||||
q6asm_audio_client_free(prtd->audio_client);
|
||||
prtd->audio_client = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int q6asm_dai_trigger(struct snd_soc_component *component,
|
||||
|
|
|
@ -42,6 +42,12 @@ struct prm_cmd_request_rsc {
|
|||
struct audio_hw_clk_cfg clock_id;
|
||||
} __packed;
|
||||
|
||||
struct prm_cmd_release_rsc {
|
||||
struct apm_module_param_data param_data;
|
||||
uint32_t num_clk_id;
|
||||
struct audio_hw_clk_rel_cfg clock_id;
|
||||
} __packed;
|
||||
|
||||
static int q6prm_send_cmd_sync(struct q6prm *prm, struct gpr_pkt *pkt, uint32_t rsp_opcode)
|
||||
{
|
||||
return audioreach_send_cmd_sync(prm->dev, prm->gdev, &prm->result, &prm->lock,
|
||||
|
@ -102,8 +108,8 @@ int q6prm_unvote_lpass_core_hw(struct device *dev, uint32_t hw_block_id, uint32_
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(q6prm_unvote_lpass_core_hw);
|
||||
|
||||
int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_root,
|
||||
unsigned int freq)
|
||||
static int q6prm_request_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_root,
|
||||
unsigned int freq)
|
||||
{
|
||||
struct q6prm *prm = dev_get_drvdata(dev->parent);
|
||||
struct apm_module_param_data *param_data;
|
||||
|
@ -138,6 +144,49 @@ int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int q6prm_release_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_root,
|
||||
unsigned int freq)
|
||||
{
|
||||
struct q6prm *prm = dev_get_drvdata(dev->parent);
|
||||
struct apm_module_param_data *param_data;
|
||||
struct prm_cmd_release_rsc *rel;
|
||||
gpr_device_t *gdev = prm->gdev;
|
||||
struct gpr_pkt *pkt;
|
||||
int rc;
|
||||
|
||||
pkt = audioreach_alloc_cmd_pkt(sizeof(*rel), PRM_CMD_RELEASE_HW_RSC, 0, gdev->svc.id,
|
||||
GPR_PRM_MODULE_IID);
|
||||
if (IS_ERR(pkt))
|
||||
return PTR_ERR(pkt);
|
||||
|
||||
rel = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
|
||||
|
||||
param_data = &rel->param_data;
|
||||
|
||||
param_data->module_instance_id = GPR_PRM_MODULE_IID;
|
||||
param_data->error_code = 0;
|
||||
param_data->param_id = PARAM_ID_RSC_AUDIO_HW_CLK;
|
||||
param_data->param_size = sizeof(*rel) - APM_MODULE_PARAM_DATA_SIZE;
|
||||
|
||||
rel->num_clk_id = 1;
|
||||
rel->clock_id.clock_id = clk_id;
|
||||
|
||||
rc = q6prm_send_cmd_sync(prm, pkt, PRM_CMD_RSP_RELEASE_HW_RSC);
|
||||
|
||||
kfree(pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_root,
|
||||
unsigned int freq)
|
||||
{
|
||||
if (freq)
|
||||
return q6prm_request_lpass_clock(dev, clk_id, clk_attr, clk_attr, freq);
|
||||
|
||||
return q6prm_release_lpass_clock(dev, clk_id, clk_attr, clk_attr, freq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(q6prm_set_lpass_clock);
|
||||
|
||||
static int prm_callback(struct gpr_resp_pkt *data, void *priv, int op)
|
||||
|
|
|
@ -372,6 +372,12 @@ int q6routing_stream_open(int fedai_id, int perf_mode,
|
|||
}
|
||||
|
||||
session = &routing_data->sessions[stream_id - 1];
|
||||
if (session->port_id < 0) {
|
||||
dev_err(routing_data->dev, "Routing not setup for MultiMedia%d Session\n",
|
||||
session->fedai_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdata = &routing_data->port_data[session->port_id];
|
||||
|
||||
mutex_lock(&routing_data->lock);
|
||||
|
@ -495,7 +501,11 @@ static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
|
|||
session->port_id = be_id;
|
||||
snd_soc_dapm_mixer_update_power(dapm, kcontrol, 1, update);
|
||||
} else {
|
||||
session->port_id = -1;
|
||||
if (session->port_id == be_id) {
|
||||
session->port_id = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
snd_soc_dapm_mixer_update_power(dapm, kcontrol, 0, update);
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ static int rsnd_dmaen_stop(struct rsnd_mod *mod,
|
|||
struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
|
||||
|
||||
if (dmaen->chan)
|
||||
dmaengine_terminate_sync(dmaen->chan);
|
||||
dmaengine_terminate_async(dmaen->chan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2559,8 +2559,13 @@ static struct snd_soc_dapm_widget *dapm_find_widget(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
|
||||
const char *pin, int status)
|
||||
/*
|
||||
* set the DAPM pin status:
|
||||
* returns 1 when the value has been updated, 0 when unchanged, or a negative
|
||||
* error code; called from kcontrol put callback
|
||||
*/
|
||||
static int __snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
|
||||
const char *pin, int status)
|
||||
{
|
||||
struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
|
||||
int ret = 0;
|
||||
|
@ -2586,6 +2591,18 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* similar as __snd_soc_dapm_set_pin(), but returns 0 when successful;
|
||||
* called from several API functions below
|
||||
*/
|
||||
static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
|
||||
const char *pin, int status)
|
||||
{
|
||||
int ret = __snd_soc_dapm_set_pin(dapm, pin, status);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_sync_unlocked - scan and power dapm paths
|
||||
* @dapm: DAPM context
|
||||
|
@ -3589,10 +3606,10 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
|
|||
const char *pin = (const char *)kcontrol->private_value;
|
||||
int ret;
|
||||
|
||||
if (ucontrol->value.integer.value[0])
|
||||
ret = snd_soc_dapm_enable_pin(&card->dapm, pin);
|
||||
else
|
||||
ret = snd_soc_dapm_disable_pin(&card->dapm, pin);
|
||||
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
|
||||
ret = __snd_soc_dapm_set_pin(&card->dapm, pin,
|
||||
!!ucontrol->value.integer.value[0]);
|
||||
mutex_unlock(&card->dapm_mutex);
|
||||
|
||||
snd_soc_dapm_sync(&card->dapm);
|
||||
return ret;
|
||||
|
|
|
@ -2700,6 +2700,7 @@ EXPORT_SYMBOL_GPL(snd_soc_tplg_component_load);
|
|||
/* remove dynamic controls from the component driver */
|
||||
int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
|
||||
{
|
||||
struct snd_card *card = comp->card->snd_card;
|
||||
struct snd_soc_dobj *dobj, *next_dobj;
|
||||
int pass = SOC_TPLG_PASS_END;
|
||||
|
||||
|
@ -2707,6 +2708,7 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
|
|||
while (pass >= SOC_TPLG_PASS_START) {
|
||||
|
||||
/* remove mixer controls */
|
||||
down_write(&card->controls_rwsem);
|
||||
list_for_each_entry_safe(dobj, next_dobj, &comp->dobj_list,
|
||||
list) {
|
||||
|
||||
|
@ -2745,6 +2747,7 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
|
|||
break;
|
||||
}
|
||||
}
|
||||
up_write(&card->controls_rwsem);
|
||||
pass--;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ config SND_SOC_SOF_OF
|
|||
Say Y if you need this option. If unsure select "N".
|
||||
|
||||
config SND_SOC_SOF_COMPRESS
|
||||
tristate
|
||||
bool
|
||||
select SND_SOC_COMPRESS
|
||||
|
||||
config SND_SOC_SOF_DEBUG_PROBES
|
||||
|
|
|
@ -69,7 +69,7 @@ static void snd_sof_refresh_control(struct snd_sof_control *scontrol)
|
|||
{
|
||||
struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
|
||||
struct snd_soc_component *scomp = scontrol->scomp;
|
||||
enum sof_ipc_ctrl_type ctrl_type;
|
||||
u32 ipc_cmd;
|
||||
int ret;
|
||||
|
||||
if (!scontrol->comp_data_dirty)
|
||||
|
@ -79,9 +79,9 @@ static void snd_sof_refresh_control(struct snd_sof_control *scontrol)
|
|||
return;
|
||||
|
||||
if (scontrol->cmd == SOF_CTRL_CMD_BINARY)
|
||||
ctrl_type = SOF_IPC_COMP_GET_DATA;
|
||||
ipc_cmd = SOF_IPC_COMP_GET_DATA;
|
||||
else
|
||||
ctrl_type = SOF_IPC_COMP_GET_VALUE;
|
||||
ipc_cmd = SOF_IPC_COMP_GET_VALUE;
|
||||
|
||||
/* set the ABI header values */
|
||||
cdata->data->magic = SOF_ABI_MAGIC;
|
||||
|
@ -89,7 +89,7 @@ static void snd_sof_refresh_control(struct snd_sof_control *scontrol)
|
|||
|
||||
/* refresh the component data from DSP */
|
||||
scontrol->comp_data_dirty = false;
|
||||
ret = snd_sof_ipc_set_get_comp_data(scontrol, ctrl_type,
|
||||
ret = snd_sof_ipc_set_get_comp_data(scontrol, ipc_cmd,
|
||||
SOF_CTRL_TYPE_VALUE_CHAN_GET,
|
||||
scontrol->cmd, false);
|
||||
if (ret < 0) {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <linux/io.h>
|
||||
#include <sound/hdaudio.h>
|
||||
#include <sound/hda_i915.h>
|
||||
#include <sound/hda_codec.h>
|
||||
#include <sound/hda_register.h>
|
||||
#include "../sof-priv.h"
|
||||
#include "hda.h"
|
||||
|
||||
|
@ -21,6 +23,18 @@
|
|||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
|
||||
static void update_codec_wake_enable(struct hdac_bus *bus, unsigned int addr, bool link_power)
|
||||
{
|
||||
unsigned int mask = snd_hdac_chip_readw(bus, WAKEEN);
|
||||
|
||||
if (link_power)
|
||||
mask &= ~BIT(addr);
|
||||
else
|
||||
mask |= BIT(addr);
|
||||
|
||||
snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask);
|
||||
}
|
||||
|
||||
static void sof_hda_bus_link_power(struct hdac_device *codec, bool enable)
|
||||
{
|
||||
struct hdac_bus *bus = codec->bus;
|
||||
|
@ -41,6 +55,9 @@ static void sof_hda_bus_link_power(struct hdac_device *codec, bool enable)
|
|||
*/
|
||||
if (codec->addr == HDA_IDISP_ADDR && !enable)
|
||||
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
|
||||
|
||||
/* WAKEEN needs to be set for disabled links */
|
||||
update_codec_wake_enable(bus, codec->addr, enable);
|
||||
}
|
||||
|
||||
static const struct hdac_bus_ops bus_core_ops = {
|
||||
|
|
|
@ -622,8 +622,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
|
|||
hda_dsp_ipc_int_disable(sdev);
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
|
||||
if (runtime_suspend)
|
||||
hda_codec_jack_wake_enable(sdev, true);
|
||||
hda_codec_jack_wake_enable(sdev, runtime_suspend);
|
||||
|
||||
/* power down all hda link */
|
||||
snd_hdac_ext_bus_link_power_down_all(bus);
|
||||
|
|
|
@ -810,6 +810,20 @@ skip_soundwire:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void hda_check_for_state_change(struct snd_sof_dev *sdev)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
|
||||
struct hdac_bus *bus = sof_to_bus(sdev);
|
||||
unsigned int codec_mask;
|
||||
|
||||
codec_mask = snd_hdac_chip_readw(bus, STATESTS);
|
||||
if (codec_mask) {
|
||||
hda_codec_jack_check(sdev);
|
||||
snd_hdac_chip_writew(bus, STATESTS, codec_mask);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static irqreturn_t hda_dsp_interrupt_handler(int irq, void *context)
|
||||
{
|
||||
struct snd_sof_dev *sdev = context;
|
||||
|
@ -851,6 +865,8 @@ static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context)
|
|||
if (hda_sdw_check_wakeen_irq(sdev))
|
||||
hda_sdw_process_wakeen(sdev);
|
||||
|
||||
hda_check_for_state_change(sdev);
|
||||
|
||||
/* enable GIE interrupt */
|
||||
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
|
||||
SOF_HDA_INTCTL,
|
||||
|
|
|
@ -700,7 +700,7 @@ static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
nb_bits = frame_len * ((cgfr & I2S_CGFR_CHLEN) + 1);
|
||||
nb_bits = frame_len * (FIELD_GET(I2S_CGFR_CHLEN, cgfr) + 1);
|
||||
ret = stm32_i2s_calc_clk_div(i2s, i2s_clock_rate,
|
||||
(nb_bits * rate));
|
||||
if (ret)
|
||||
|
|
|
@ -581,6 +581,12 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* free-wheeling mode? (e.g. dmix) */
|
||||
static int in_free_wheeling_mode(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
return runtime->stop_threshold > runtime->buffer_size;
|
||||
}
|
||||
|
||||
/* check whether early start is needed for playback stream */
|
||||
static int lowlatency_playback_available(struct snd_pcm_runtime *runtime,
|
||||
struct snd_usb_substream *subs)
|
||||
|
@ -592,8 +598,7 @@ static int lowlatency_playback_available(struct snd_pcm_runtime *runtime,
|
|||
/* disabled via module option? */
|
||||
if (!chip->lowlatency)
|
||||
return false;
|
||||
/* free-wheeling mode? (e.g. dmix) */
|
||||
if (runtime->stop_threshold > runtime->buffer_size)
|
||||
if (in_free_wheeling_mode(runtime))
|
||||
return false;
|
||||
/* implicit feedback mode has own operation mode */
|
||||
if (snd_usb_endpoint_implicit_feedback_sink(subs->data_endpoint))
|
||||
|
@ -635,7 +640,8 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
|
|||
runtime->delay = 0;
|
||||
|
||||
subs->lowlatency_playback = lowlatency_playback_available(runtime, subs);
|
||||
if (!subs->lowlatency_playback)
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
!subs->lowlatency_playback)
|
||||
ret = start_endpoints(subs);
|
||||
|
||||
unlock:
|
||||
|
@ -1552,6 +1558,8 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
|
|||
subs);
|
||||
if (subs->lowlatency_playback &&
|
||||
cmd == SNDRV_PCM_TRIGGER_START) {
|
||||
if (in_free_wheeling_mode(substream->runtime))
|
||||
subs->lowlatency_playback = false;
|
||||
err = start_endpoints(subs);
|
||||
if (err < 0) {
|
||||
snd_usb_endpoint_set_callback(subs->data_endpoint,
|
||||
|
|
Loading…
Reference in New Issue