mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-17 02:15:57 +00:00
sound fixes #2 for 6.9-rc2
The remaining fixes for 6.9-rc1 that have been gathered in this week. More about ASoC at this time (one long-standing fix for compress offload, SOF, AMD ACP, Rockchip, Cirrus and tlv320 stuff) while another regression fix in ALSA core and a couple of HD-audio quirks as usual are included. -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmX8acUOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE9MWw/9FBmHy2z4F6vV17h6oR7CMxuxkB7ZDZbNAApD 9sZDyx7s2hCenO0xcCu77BAkq0s1Ry0GylJrR9tlEDj+NOtEVnBKMP8nqx0RASJK nsApk2XX3gC89cJEv9sY9cNi6Co7jkSbRjB2UM609ZmSnx0HAZcnq+sY+1CljOFW ulgkrXiFg0OPtxj9LJ4rd9vDQeGHALy7/IKX6AK9bqFcZIbbYZCOcfLDr604tOTe Uy1qoZRghyqB4VvpO1A11AfVg7sn3ZWqn29wWDfll8QylCwG/VjDjSYYMcXPL5Ds TGQWPnnXhWZ4oXYCpDQdyZOhZ/amuo11YBSM+3FNKQgfwa8hOCLESpJrEtSSomqd C4ZB8jk4NsQ3+VdtE2jfIzyL11N4bt2dwyrrGT8+hC/vyim0SiUl12HT1phu7nhO KRcmy9KKt4oHYmkGmRxzFmGLYB3NCieIbRfkKiQiN0MqJ+QpIPNtwCGOqvua1dtT Dx7kYhLeAdqV7clxW2d9xuGBeIbJxv56J36yLt/z1d4TOiHRSEk+K4w4Yv1NpZLc KcUacbFePqbvVXeA34wH1YspX6VkKleorVcjBZCt0DpheWnfCPiVYluvJ8WalcXa U0/4H9hLhnanQljZlukoJ1XshVjvz1UdPCLWfYhy0hFxSHSbszuxGLFRCa/6e0k/ xHBPT/A= =my1j -----END PGP SIGNATURE----- Merge tag 'sound-fix2-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull more sound fixes from Takashi Iwai: "The remaining fixes for 6.9-rc1 that have been gathered in this week. More about ASoC at this time (one long-standing fix for compress offload, SOF, AMD ACP, Rockchip, Cirrus and tlv320 stuff) while another regression fix in ALSA core and a couple of HD-audio quirks as usual are included" * tag 'sound-fix2-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: control: Fix unannotated kfree() cleanup ALSA: hda/realtek: Add quirks for some Clevo laptops ALSA: hda/realtek: Add quirk for HP Spectre x360 14 eu0000 ALSA: hda/realtek: fix the hp playback volume issue for LG machines ASoC: soc-compress: Fix and add DPCM locking ASoC: SOF: amd: Skip IRAM/DRAM size modification for Steam Deck OLED ASoC: SOF: amd: Move signed_fw_image to struct acp_quirk_entry ASoC: amd: yc: Revert "add new YC platform variant (0x63) support" ASoC: amd: yc: Revert "Fix non-functional mic on Lenovo 21J2" ASoC: soc-core.c: Skip dummy codec when adding platforms ASoC: rockchip: i2s-tdm: Fix inaccurate sampling rates ASoC: dt-bindings: cirrus,cs42l43: Fix 'gpio-ranges' schema ASoC: amd: yc: Fix non-functional mic on ASUS M7600RE ASoC: tlv320adc3xxx: Don't strip remove function when driver is builtin
This commit is contained in:
commit
6b571e2676
@ -185,11 +185,12 @@ properties:
|
|||||||
|
|
||||||
gpio-ranges:
|
gpio-ranges:
|
||||||
items:
|
items:
|
||||||
- description: A phandle to the CODEC pinctrl node
|
- items:
|
||||||
minimum: 0
|
- description: A phandle to the CODEC pinctrl node
|
||||||
- const: 0
|
minimum: 0
|
||||||
- const: 0
|
- const: 0
|
||||||
- const: 3
|
- const: 0
|
||||||
|
- const: 3
|
||||||
|
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"-state$":
|
"-state$":
|
||||||
|
@ -1275,12 +1275,12 @@ static int snd_ctl_elem_read(struct snd_card *card,
|
|||||||
static int snd_ctl_elem_read_user(struct snd_card *card,
|
static int snd_ctl_elem_read_user(struct snd_card *card,
|
||||||
struct snd_ctl_elem_value __user *_control)
|
struct snd_ctl_elem_value __user *_control)
|
||||||
{
|
{
|
||||||
struct snd_ctl_elem_value *control;
|
struct snd_ctl_elem_value *control __free(kfree) = NULL;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
control = memdup_user(_control, sizeof(*control));
|
control = memdup_user(_control, sizeof(*control));
|
||||||
if (IS_ERR(control))
|
if (IS_ERR(control))
|
||||||
return PTR_ERR(control);
|
return PTR_ERR(no_free_ptr(control));
|
||||||
|
|
||||||
result = snd_ctl_elem_read(card, control);
|
result = snd_ctl_elem_read(card, control);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
|
@ -2645,6 +2645,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
|||||||
SND_PCI_QUIRK(0x1558, 0x65f1, "Clevo PC50HS", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
SND_PCI_QUIRK(0x1558, 0x65f1, "Clevo PC50HS", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
SND_PCI_QUIRK(0x1558, 0x65f5, "Clevo PD50PN[NRT]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
SND_PCI_QUIRK(0x1558, 0x65f5, "Clevo PD50PN[NRT]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
SND_PCI_QUIRK(0x1558, 0x66a2, "Clevo PE60RNE", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
SND_PCI_QUIRK(0x1558, 0x66a2, "Clevo PE60RNE", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x66a6, "Clevo PE60SN[CDE]-[GS]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
@ -6964,6 +6965,25 @@ static void alc256_fixup_mic_no_presence_and_resume(struct hda_codec *codec,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void alc256_decrease_headphone_amp_val(struct hda_codec *codec,
|
||||||
|
const struct hda_fixup *fix, int action)
|
||||||
|
{
|
||||||
|
u32 caps;
|
||||||
|
u8 nsteps, offs;
|
||||||
|
|
||||||
|
if (action != HDA_FIXUP_ACT_PRE_PROBE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
caps = query_amp_caps(codec, 0x3, HDA_OUTPUT);
|
||||||
|
nsteps = ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) - 10;
|
||||||
|
offs = ((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT) - 10;
|
||||||
|
caps &= ~AC_AMPCAP_NUM_STEPS & ~AC_AMPCAP_OFFSET;
|
||||||
|
caps |= (nsteps << AC_AMPCAP_NUM_STEPS_SHIFT) | (offs << AC_AMPCAP_OFFSET_SHIFT);
|
||||||
|
|
||||||
|
if (snd_hda_override_amp_caps(codec, 0x3, HDA_OUTPUT, caps))
|
||||||
|
codec_warn(codec, "failed to override amp caps for NID 0x3\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void alc_fixup_dell4_mic_no_presence_quiet(struct hda_codec *codec,
|
static void alc_fixup_dell4_mic_no_presence_quiet(struct hda_codec *codec,
|
||||||
const struct hda_fixup *fix,
|
const struct hda_fixup *fix,
|
||||||
int action)
|
int action)
|
||||||
@ -7104,6 +7124,38 @@ static void alc_fixup_headset_mic(struct hda_codec *codec,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void alc245_fixup_hp_spectre_x360_eu0xxx(struct hda_codec *codec,
|
||||||
|
const struct hda_fixup *fix, int action)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The Pin Complex 0x14 for the treble speakers is wrongly reported as
|
||||||
|
* unconnected.
|
||||||
|
* The Pin Complex 0x17 for the bass speakers has the lowest association
|
||||||
|
* and sequence values so shift it up a bit to squeeze 0x14 in.
|
||||||
|
*/
|
||||||
|
static const struct hda_pintbl pincfgs[] = {
|
||||||
|
{ 0x14, 0x90170110 }, // top/treble
|
||||||
|
{ 0x17, 0x90170111 }, // bottom/bass
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force DAC 0x02 for the bass speakers 0x17.
|
||||||
|
*/
|
||||||
|
static const hda_nid_t conn[] = { 0x02 };
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||||
|
snd_hda_apply_pincfgs(codec, pincfgs);
|
||||||
|
snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cs35l41_fixup_i2c_two(codec, fix, action);
|
||||||
|
alc245_fixup_hp_mute_led_coefbit(codec, fix, action);
|
||||||
|
alc245_fixup_hp_gpio_led(codec, fix, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ALC269_FIXUP_GPIO2,
|
ALC269_FIXUP_GPIO2,
|
||||||
@ -7382,6 +7434,8 @@ enum {
|
|||||||
ALC294_FIXUP_CS35L41_I2C_2,
|
ALC294_FIXUP_CS35L41_I2C_2,
|
||||||
ALC245_FIXUP_CS35L56_SPI_4_HP_GPIO_LED,
|
ALC245_FIXUP_CS35L56_SPI_4_HP_GPIO_LED,
|
||||||
ALC256_FIXUP_ACER_SFG16_MICMUTE_LED,
|
ALC256_FIXUP_ACER_SFG16_MICMUTE_LED,
|
||||||
|
ALC256_FIXUP_HEADPHONE_AMP_VOL,
|
||||||
|
ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A special fixup for Lenovo C940 and Yoga Duet 7;
|
/* A special fixup for Lenovo C940 and Yoga Duet 7;
|
||||||
@ -9581,6 +9635,14 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||||||
.type = HDA_FIXUP_FUNC,
|
.type = HDA_FIXUP_FUNC,
|
||||||
.v.func = alc256_fixup_acer_sfg16_micmute_led,
|
.v.func = alc256_fixup_acer_sfg16_micmute_led,
|
||||||
},
|
},
|
||||||
|
[ALC256_FIXUP_HEADPHONE_AMP_VOL] = {
|
||||||
|
.type = HDA_FIXUP_FUNC,
|
||||||
|
.v.func = alc256_decrease_headphone_amp_val,
|
||||||
|
},
|
||||||
|
[ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX] = {
|
||||||
|
.type = HDA_FIXUP_FUNC,
|
||||||
|
.v.func = alc245_fixup_hp_spectre_x360_eu0xxx,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
@ -9944,7 +10006,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||||||
SND_PCI_QUIRK(0x103c, 0x8be8, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
|
SND_PCI_QUIRK(0x103c, 0x8be8, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8be9, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
|
SND_PCI_QUIRK(0x103c, 0x8be9, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED),
|
SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8c15, "HP Spectre 14", ALC287_FIXUP_CS35L41_I2C_2),
|
SND_PCI_QUIRK(0x103c, 0x8c15, "HP Spectre x360 2-in-1 Laptop 14-eu0xxx", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8c16, "HP Spectre 16", ALC287_FIXUP_CS35L41_I2C_2),
|
SND_PCI_QUIRK(0x103c, 0x8c16, "HP Spectre 16", ALC287_FIXUP_CS35L41_I2C_2),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8c17, "HP Spectre 16", ALC287_FIXUP_CS35L41_I2C_2),
|
SND_PCI_QUIRK(0x103c, 0x8c17, "HP Spectre 16", ALC287_FIXUP_CS35L41_I2C_2),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8c46, "HP EliteBook 830 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
SND_PCI_QUIRK(0x103c, 0x8c46, "HP EliteBook 830 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||||
@ -10115,12 +10177,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||||||
SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x152d, 0x1082, "Quanta NL3", ALC269_FIXUP_LIFEBOOK),
|
SND_PCI_QUIRK(0x152d, 0x1082, "Quanta NL3", ALC269_FIXUP_LIFEBOOK),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x0353, "Clevo V35[05]SN[CDE]Q", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1558, 0x1323, "Clevo N130ZU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1558, 0x1323, "Clevo N130ZU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1558, 0x1325, "Clevo N15[01][CW]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1558, 0x1325, "Clevo N15[01][CW]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1558, 0x1401, "Clevo L140[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1558, 0x1401, "Clevo L140[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1558, 0x1403, "Clevo N140CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1558, 0x1403, "Clevo N140CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1558, 0x1404, "Clevo N150CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1558, 0x1404, "Clevo N150CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1558, 0x14a1, "Clevo L141MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1558, 0x14a1, "Clevo L141MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x2624, "Clevo L240TU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1558, 0x4018, "Clevo NV40M[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1558, 0x4018, "Clevo NV40M[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1558, 0x4019, "Clevo NV40MZ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1558, 0x4019, "Clevo NV40MZ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1558, 0x4020, "Clevo NV40MB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1558, 0x4020, "Clevo NV40MB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||||
@ -10319,6 +10383,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||||||
SND_PCI_QUIRK(0x17aa, 0x9e56, "Lenovo ZhaoYang CF4620Z", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x17aa, 0x9e56, "Lenovo ZhaoYang CF4620Z", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
|
SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
|
||||||
SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC),
|
||||||
|
SND_PCI_QUIRK(0x1854, 0x0440, "LG CQ6", ALC256_FIXUP_HEADPHONE_AMP_VOL),
|
||||||
|
SND_PCI_QUIRK(0x1854, 0x0441, "LG CQ6 AIO", ALC256_FIXUP_HEADPHONE_AMP_VOL),
|
||||||
SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
|
SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
|
||||||
SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
|
SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
|
||||||
|
@ -199,13 +199,6 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
|||||||
DMI_MATCH(DMI_PRODUCT_NAME, "21HY"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "21HY"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.driver_data = &acp6x_card,
|
|
||||||
.matches = {
|
|
||||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "21J2"),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.driver_data = &acp6x_card,
|
.driver_data = &acp6x_card,
|
||||||
.matches = {
|
.matches = {
|
||||||
@ -318,6 +311,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
|||||||
DMI_MATCH(DMI_PRODUCT_NAME, "E1504FA"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "E1504FA"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.driver_data = &acp6x_card,
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "M7600RE"),
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.driver_data = &acp6x_card,
|
.driver_data = &acp6x_card,
|
||||||
.matches = {
|
.matches = {
|
||||||
|
@ -162,7 +162,6 @@ static int snd_acp6x_probe(struct pci_dev *pci,
|
|||||||
/* Yellow Carp device check */
|
/* Yellow Carp device check */
|
||||||
switch (pci->revision) {
|
switch (pci->revision) {
|
||||||
case 0x60:
|
case 0x60:
|
||||||
case 0x63:
|
|
||||||
case 0x6f:
|
case 0x6f:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1429,7 +1429,7 @@ err_unprepare_mclk:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit adc3xxx_i2c_remove(struct i2c_client *client)
|
static void adc3xxx_i2c_remove(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct adc3xxx *adc3xxx = i2c_get_clientdata(client);
|
struct adc3xxx *adc3xxx = i2c_get_clientdata(client);
|
||||||
|
|
||||||
@ -1452,7 +1452,7 @@ static struct i2c_driver adc3xxx_i2c_driver = {
|
|||||||
.of_match_table = tlv320adc3xxx_of_match,
|
.of_match_table = tlv320adc3xxx_of_match,
|
||||||
},
|
},
|
||||||
.probe = adc3xxx_i2c_probe,
|
.probe = adc3xxx_i2c_probe,
|
||||||
.remove = __exit_p(adc3xxx_i2c_remove),
|
.remove = adc3xxx_i2c_remove,
|
||||||
.id_table = adc3xxx_i2c_id,
|
.id_table = adc3xxx_i2c_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
#define DEFAULT_MCLK_FS 256
|
#define DEFAULT_MCLK_FS 256
|
||||||
#define CH_GRP_MAX 4 /* The max channel 8 / 2 */
|
#define CH_GRP_MAX 4 /* The max channel 8 / 2 */
|
||||||
#define MULTIPLEX_CH_MAX 10
|
#define MULTIPLEX_CH_MAX 10
|
||||||
#define CLK_PPM_MIN -1000
|
|
||||||
#define CLK_PPM_MAX 1000
|
|
||||||
|
|
||||||
#define TRCM_TXRX 0
|
#define TRCM_TXRX 0
|
||||||
#define TRCM_TX 1
|
#define TRCM_TX 1
|
||||||
@ -53,20 +51,6 @@ struct rk_i2s_tdm_dev {
|
|||||||
struct clk *hclk;
|
struct clk *hclk;
|
||||||
struct clk *mclk_tx;
|
struct clk *mclk_tx;
|
||||||
struct clk *mclk_rx;
|
struct clk *mclk_rx;
|
||||||
/* The mclk_tx_src is parent of mclk_tx */
|
|
||||||
struct clk *mclk_tx_src;
|
|
||||||
/* The mclk_rx_src is parent of mclk_rx */
|
|
||||||
struct clk *mclk_rx_src;
|
|
||||||
/*
|
|
||||||
* The mclk_root0 and mclk_root1 are root parent and supplies for
|
|
||||||
* the different FS.
|
|
||||||
*
|
|
||||||
* e.g:
|
|
||||||
* mclk_root0 is VPLL0, used for FS=48000Hz
|
|
||||||
* mclk_root1 is VPLL1, used for FS=44100Hz
|
|
||||||
*/
|
|
||||||
struct clk *mclk_root0;
|
|
||||||
struct clk *mclk_root1;
|
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
struct regmap *grf;
|
struct regmap *grf;
|
||||||
struct snd_dmaengine_dai_dma_data capture_dma_data;
|
struct snd_dmaengine_dai_dma_data capture_dma_data;
|
||||||
@ -76,19 +60,11 @@ struct rk_i2s_tdm_dev {
|
|||||||
const struct rk_i2s_soc_data *soc_data;
|
const struct rk_i2s_soc_data *soc_data;
|
||||||
bool is_master_mode;
|
bool is_master_mode;
|
||||||
bool io_multiplex;
|
bool io_multiplex;
|
||||||
bool mclk_calibrate;
|
|
||||||
bool tdm_mode;
|
bool tdm_mode;
|
||||||
unsigned int mclk_rx_freq;
|
|
||||||
unsigned int mclk_tx_freq;
|
|
||||||
unsigned int mclk_root0_freq;
|
|
||||||
unsigned int mclk_root1_freq;
|
|
||||||
unsigned int mclk_root0_initial_freq;
|
|
||||||
unsigned int mclk_root1_initial_freq;
|
|
||||||
unsigned int frame_width;
|
unsigned int frame_width;
|
||||||
unsigned int clk_trcm;
|
unsigned int clk_trcm;
|
||||||
unsigned int i2s_sdis[CH_GRP_MAX];
|
unsigned int i2s_sdis[CH_GRP_MAX];
|
||||||
unsigned int i2s_sdos[CH_GRP_MAX];
|
unsigned int i2s_sdos[CH_GRP_MAX];
|
||||||
int clk_ppm;
|
|
||||||
int refcount;
|
int refcount;
|
||||||
spinlock_t lock; /* xfer lock */
|
spinlock_t lock; /* xfer lock */
|
||||||
bool has_playback;
|
bool has_playback;
|
||||||
@ -114,12 +90,6 @@ static void i2s_tdm_disable_unprepare_mclk(struct rk_i2s_tdm_dev *i2s_tdm)
|
|||||||
{
|
{
|
||||||
clk_disable_unprepare(i2s_tdm->mclk_tx);
|
clk_disable_unprepare(i2s_tdm->mclk_tx);
|
||||||
clk_disable_unprepare(i2s_tdm->mclk_rx);
|
clk_disable_unprepare(i2s_tdm->mclk_rx);
|
||||||
if (i2s_tdm->mclk_calibrate) {
|
|
||||||
clk_disable_unprepare(i2s_tdm->mclk_tx_src);
|
|
||||||
clk_disable_unprepare(i2s_tdm->mclk_rx_src);
|
|
||||||
clk_disable_unprepare(i2s_tdm->mclk_root0);
|
|
||||||
clk_disable_unprepare(i2s_tdm->mclk_root1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,29 +112,9 @@ static int i2s_tdm_prepare_enable_mclk(struct rk_i2s_tdm_dev *i2s_tdm)
|
|||||||
ret = clk_prepare_enable(i2s_tdm->mclk_rx);
|
ret = clk_prepare_enable(i2s_tdm->mclk_rx);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_mclk_rx;
|
goto err_mclk_rx;
|
||||||
if (i2s_tdm->mclk_calibrate) {
|
|
||||||
ret = clk_prepare_enable(i2s_tdm->mclk_tx_src);
|
|
||||||
if (ret)
|
|
||||||
goto err_mclk_rx;
|
|
||||||
ret = clk_prepare_enable(i2s_tdm->mclk_rx_src);
|
|
||||||
if (ret)
|
|
||||||
goto err_mclk_rx_src;
|
|
||||||
ret = clk_prepare_enable(i2s_tdm->mclk_root0);
|
|
||||||
if (ret)
|
|
||||||
goto err_mclk_root0;
|
|
||||||
ret = clk_prepare_enable(i2s_tdm->mclk_root1);
|
|
||||||
if (ret)
|
|
||||||
goto err_mclk_root1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_mclk_root1:
|
|
||||||
clk_disable_unprepare(i2s_tdm->mclk_root0);
|
|
||||||
err_mclk_root0:
|
|
||||||
clk_disable_unprepare(i2s_tdm->mclk_rx_src);
|
|
||||||
err_mclk_rx_src:
|
|
||||||
clk_disable_unprepare(i2s_tdm->mclk_tx_src);
|
|
||||||
err_mclk_rx:
|
err_mclk_rx:
|
||||||
clk_disable_unprepare(i2s_tdm->mclk_tx);
|
clk_disable_unprepare(i2s_tdm->mclk_tx);
|
||||||
err_mclk_tx:
|
err_mclk_tx:
|
||||||
@ -564,159 +514,6 @@ static void rockchip_i2s_tdm_xfer_resume(struct snd_pcm_substream *substream,
|
|||||||
I2S_XFER_RXS_START);
|
I2S_XFER_RXS_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rockchip_i2s_tdm_clk_set_rate(struct rk_i2s_tdm_dev *i2s_tdm,
|
|
||||||
struct clk *clk, unsigned long rate,
|
|
||||||
int ppm)
|
|
||||||
{
|
|
||||||
unsigned long rate_target;
|
|
||||||
int delta, ret;
|
|
||||||
|
|
||||||
if (ppm == i2s_tdm->clk_ppm)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (ppm < 0)
|
|
||||||
delta = -1;
|
|
||||||
else
|
|
||||||
delta = 1;
|
|
||||||
|
|
||||||
delta *= (int)div64_u64((u64)rate * (u64)abs(ppm) + 500000,
|
|
||||||
1000000);
|
|
||||||
|
|
||||||
rate_target = rate + delta;
|
|
||||||
|
|
||||||
if (!rate_target)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ret = clk_set_rate(clk, rate_target);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
i2s_tdm->clk_ppm = ppm;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rockchip_i2s_tdm_calibrate_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
|
|
||||||
struct snd_pcm_substream *substream,
|
|
||||||
unsigned int lrck_freq)
|
|
||||||
{
|
|
||||||
struct clk *mclk_root;
|
|
||||||
struct clk *mclk_parent;
|
|
||||||
unsigned int mclk_root_freq;
|
|
||||||
unsigned int mclk_root_initial_freq;
|
|
||||||
unsigned int mclk_parent_freq;
|
|
||||||
unsigned int div, delta;
|
|
||||||
u64 ppm;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
||||||
mclk_parent = i2s_tdm->mclk_tx_src;
|
|
||||||
else
|
|
||||||
mclk_parent = i2s_tdm->mclk_rx_src;
|
|
||||||
|
|
||||||
switch (lrck_freq) {
|
|
||||||
case 8000:
|
|
||||||
case 16000:
|
|
||||||
case 24000:
|
|
||||||
case 32000:
|
|
||||||
case 48000:
|
|
||||||
case 64000:
|
|
||||||
case 96000:
|
|
||||||
case 192000:
|
|
||||||
mclk_root = i2s_tdm->mclk_root0;
|
|
||||||
mclk_root_freq = i2s_tdm->mclk_root0_freq;
|
|
||||||
mclk_root_initial_freq = i2s_tdm->mclk_root0_initial_freq;
|
|
||||||
mclk_parent_freq = DEFAULT_MCLK_FS * 192000;
|
|
||||||
break;
|
|
||||||
case 11025:
|
|
||||||
case 22050:
|
|
||||||
case 44100:
|
|
||||||
case 88200:
|
|
||||||
case 176400:
|
|
||||||
mclk_root = i2s_tdm->mclk_root1;
|
|
||||||
mclk_root_freq = i2s_tdm->mclk_root1_freq;
|
|
||||||
mclk_root_initial_freq = i2s_tdm->mclk_root1_initial_freq;
|
|
||||||
mclk_parent_freq = DEFAULT_MCLK_FS * 176400;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dev_err(i2s_tdm->dev, "Invalid LRCK frequency: %u Hz\n",
|
|
||||||
lrck_freq);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_set_parent(mclk_parent, mclk_root);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, mclk_root,
|
|
||||||
mclk_root_freq, 0);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
delta = abs(mclk_root_freq % mclk_parent_freq - mclk_parent_freq);
|
|
||||||
ppm = div64_u64((uint64_t)delta * 1000000, (uint64_t)mclk_root_freq);
|
|
||||||
|
|
||||||
if (ppm) {
|
|
||||||
div = DIV_ROUND_CLOSEST(mclk_root_initial_freq, mclk_parent_freq);
|
|
||||||
if (!div)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
mclk_root_freq = mclk_parent_freq * round_up(div, 2);
|
|
||||||
|
|
||||||
ret = clk_set_rate(mclk_root, mclk_root_freq);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
i2s_tdm->mclk_root0_freq = clk_get_rate(i2s_tdm->mclk_root0);
|
|
||||||
i2s_tdm->mclk_root1_freq = clk_get_rate(i2s_tdm->mclk_root1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return clk_set_rate(mclk_parent, mclk_parent_freq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rockchip_i2s_tdm_set_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
|
|
||||||
struct snd_pcm_substream *substream,
|
|
||||||
struct clk **mclk)
|
|
||||||
{
|
|
||||||
unsigned int mclk_freq;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (i2s_tdm->clk_trcm) {
|
|
||||||
if (i2s_tdm->mclk_tx_freq != i2s_tdm->mclk_rx_freq) {
|
|
||||||
dev_err(i2s_tdm->dev,
|
|
||||||
"clk_trcm, tx: %d and rx: %d should be the same\n",
|
|
||||||
i2s_tdm->mclk_tx_freq,
|
|
||||||
i2s_tdm->mclk_rx_freq);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_set_rate(i2s_tdm->mclk_tx, i2s_tdm->mclk_tx_freq);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = clk_set_rate(i2s_tdm->mclk_rx, i2s_tdm->mclk_rx_freq);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* mclk_rx is also ok. */
|
|
||||||
*mclk = i2s_tdm->mclk_tx;
|
|
||||||
} else {
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
||||||
*mclk = i2s_tdm->mclk_tx;
|
|
||||||
mclk_freq = i2s_tdm->mclk_tx_freq;
|
|
||||||
} else {
|
|
||||||
*mclk = i2s_tdm->mclk_rx;
|
|
||||||
mclk_freq = i2s_tdm->mclk_rx_freq;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_set_rate(*mclk, mclk_freq);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rockchip_i2s_ch_to_io(unsigned int ch, bool substream_capture)
|
static int rockchip_i2s_ch_to_io(unsigned int ch, bool substream_capture)
|
||||||
{
|
{
|
||||||
if (substream_capture) {
|
if (substream_capture) {
|
||||||
@ -853,19 +650,17 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
|
|||||||
struct snd_soc_dai *dai)
|
struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
|
struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
|
||||||
struct clk *mclk;
|
|
||||||
int ret = 0;
|
|
||||||
unsigned int val = 0;
|
unsigned int val = 0;
|
||||||
unsigned int mclk_rate, bclk_rate, div_bclk = 4, div_lrck = 64;
|
unsigned int mclk_rate, bclk_rate, div_bclk = 4, div_lrck = 64;
|
||||||
|
int err;
|
||||||
|
|
||||||
if (i2s_tdm->is_master_mode) {
|
if (i2s_tdm->is_master_mode) {
|
||||||
if (i2s_tdm->mclk_calibrate)
|
struct clk *mclk = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||||
rockchip_i2s_tdm_calibrate_mclk(i2s_tdm, substream,
|
i2s_tdm->mclk_tx : i2s_tdm->mclk_rx;
|
||||||
params_rate(params));
|
|
||||||
|
|
||||||
ret = rockchip_i2s_tdm_set_mclk(i2s_tdm, substream, &mclk);
|
err = clk_set_rate(mclk, DEFAULT_MCLK_FS * params_rate(params));
|
||||||
if (ret)
|
if (err)
|
||||||
return ret;
|
return err;
|
||||||
|
|
||||||
mclk_rate = clk_get_rate(mclk);
|
mclk_rate = clk_get_rate(mclk);
|
||||||
bclk_rate = i2s_tdm->frame_width * params_rate(params);
|
bclk_rate = i2s_tdm->frame_width * params_rate(params);
|
||||||
@ -973,96 +768,6 @@ static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream *substream,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rockchip_i2s_tdm_set_sysclk(struct snd_soc_dai *cpu_dai, int stream,
|
|
||||||
unsigned int freq, int dir)
|
|
||||||
{
|
|
||||||
struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
|
|
||||||
|
|
||||||
/* Put set mclk rate into rockchip_i2s_tdm_set_mclk() */
|
|
||||||
if (i2s_tdm->clk_trcm) {
|
|
||||||
i2s_tdm->mclk_tx_freq = freq;
|
|
||||||
i2s_tdm->mclk_rx_freq = freq;
|
|
||||||
} else {
|
|
||||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
||||||
i2s_tdm->mclk_tx_freq = freq;
|
|
||||||
else
|
|
||||||
i2s_tdm->mclk_rx_freq = freq;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_dbg(i2s_tdm->dev, "The target mclk_%s freq is: %d\n",
|
|
||||||
stream ? "rx" : "tx", freq);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rockchip_i2s_tdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_info *uinfo)
|
|
||||||
{
|
|
||||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
|
||||||
uinfo->count = 1;
|
|
||||||
uinfo->value.integer.min = CLK_PPM_MIN;
|
|
||||||
uinfo->value.integer.max = CLK_PPM_MAX;
|
|
||||||
uinfo->value.integer.step = 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rockchip_i2s_tdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
|
||||||
{
|
|
||||||
struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
|
|
||||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
|
|
||||||
|
|
||||||
ucontrol->value.integer.value[0] = i2s_tdm->clk_ppm;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rockchip_i2s_tdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
|
||||||
{
|
|
||||||
struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
|
|
||||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
|
|
||||||
int ret = 0, ppm = 0;
|
|
||||||
int changed = 0;
|
|
||||||
unsigned long old_rate;
|
|
||||||
|
|
||||||
if (ucontrol->value.integer.value[0] < CLK_PPM_MIN ||
|
|
||||||
ucontrol->value.integer.value[0] > CLK_PPM_MAX)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ppm = ucontrol->value.integer.value[0];
|
|
||||||
|
|
||||||
old_rate = clk_get_rate(i2s_tdm->mclk_root0);
|
|
||||||
ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root0,
|
|
||||||
i2s_tdm->mclk_root0_freq, ppm);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
if (old_rate != clk_get_rate(i2s_tdm->mclk_root0))
|
|
||||||
changed = 1;
|
|
||||||
|
|
||||||
if (clk_is_match(i2s_tdm->mclk_root0, i2s_tdm->mclk_root1))
|
|
||||||
return changed;
|
|
||||||
|
|
||||||
old_rate = clk_get_rate(i2s_tdm->mclk_root1);
|
|
||||||
ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root1,
|
|
||||||
i2s_tdm->mclk_root1_freq, ppm);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
if (old_rate != clk_get_rate(i2s_tdm->mclk_root1))
|
|
||||||
changed = 1;
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct snd_kcontrol_new rockchip_i2s_tdm_compensation_control = {
|
|
||||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
|
||||||
.name = "PCM Clock Compensation in PPM",
|
|
||||||
.info = rockchip_i2s_tdm_clk_compensation_info,
|
|
||||||
.get = rockchip_i2s_tdm_clk_compensation_get,
|
|
||||||
.put = rockchip_i2s_tdm_clk_compensation_put,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
|
static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
|
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
|
||||||
@ -1072,9 +777,6 @@ static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
|
|||||||
if (i2s_tdm->has_playback)
|
if (i2s_tdm->has_playback)
|
||||||
snd_soc_dai_dma_data_set_playback(dai, &i2s_tdm->playback_dma_data);
|
snd_soc_dai_dma_data_set_playback(dai, &i2s_tdm->playback_dma_data);
|
||||||
|
|
||||||
if (i2s_tdm->mclk_calibrate)
|
|
||||||
snd_soc_add_dai_controls(dai, &rockchip_i2s_tdm_compensation_control, 1);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1115,7 +817,6 @@ static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = {
|
|||||||
.probe = rockchip_i2s_tdm_dai_probe,
|
.probe = rockchip_i2s_tdm_dai_probe,
|
||||||
.hw_params = rockchip_i2s_tdm_hw_params,
|
.hw_params = rockchip_i2s_tdm_hw_params,
|
||||||
.set_bclk_ratio = rockchip_i2s_tdm_set_bclk_ratio,
|
.set_bclk_ratio = rockchip_i2s_tdm_set_bclk_ratio,
|
||||||
.set_sysclk = rockchip_i2s_tdm_set_sysclk,
|
|
||||||
.set_fmt = rockchip_i2s_tdm_set_fmt,
|
.set_fmt = rockchip_i2s_tdm_set_fmt,
|
||||||
.set_tdm_slot = rockchip_dai_tdm_slot,
|
.set_tdm_slot = rockchip_dai_tdm_slot,
|
||||||
.trigger = rockchip_i2s_tdm_trigger,
|
.trigger = rockchip_i2s_tdm_trigger,
|
||||||
@ -1444,35 +1145,6 @@ static void rockchip_i2s_tdm_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
|
|||||||
rockchip_i2s_tdm_tx_path_config(i2s_tdm, num);
|
rockchip_i2s_tdm_tx_path_config(i2s_tdm, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rockchip_i2s_tdm_get_calibrate_mclks(struct rk_i2s_tdm_dev *i2s_tdm)
|
|
||||||
{
|
|
||||||
int num_mclks = 0;
|
|
||||||
|
|
||||||
i2s_tdm->mclk_tx_src = devm_clk_get(i2s_tdm->dev, "mclk_tx_src");
|
|
||||||
if (!IS_ERR(i2s_tdm->mclk_tx_src))
|
|
||||||
num_mclks++;
|
|
||||||
|
|
||||||
i2s_tdm->mclk_rx_src = devm_clk_get(i2s_tdm->dev, "mclk_rx_src");
|
|
||||||
if (!IS_ERR(i2s_tdm->mclk_rx_src))
|
|
||||||
num_mclks++;
|
|
||||||
|
|
||||||
i2s_tdm->mclk_root0 = devm_clk_get(i2s_tdm->dev, "mclk_root0");
|
|
||||||
if (!IS_ERR(i2s_tdm->mclk_root0))
|
|
||||||
num_mclks++;
|
|
||||||
|
|
||||||
i2s_tdm->mclk_root1 = devm_clk_get(i2s_tdm->dev, "mclk_root1");
|
|
||||||
if (!IS_ERR(i2s_tdm->mclk_root1))
|
|
||||||
num_mclks++;
|
|
||||||
|
|
||||||
if (num_mclks < 4 && num_mclks != 0)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
if (num_mclks == 4)
|
|
||||||
i2s_tdm->mclk_calibrate = 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rockchip_i2s_tdm_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
|
static int rockchip_i2s_tdm_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
|
||||||
struct device_node *np,
|
struct device_node *np,
|
||||||
bool is_rx_path)
|
bool is_rx_path)
|
||||||
@ -1610,11 +1282,6 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
|
|||||||
i2s_tdm->io_multiplex =
|
i2s_tdm->io_multiplex =
|
||||||
of_property_read_bool(node, "rockchip,io-multiplex");
|
of_property_read_bool(node, "rockchip,io-multiplex");
|
||||||
|
|
||||||
ret = rockchip_i2s_tdm_get_calibrate_mclks(i2s_tdm);
|
|
||||||
if (ret)
|
|
||||||
return dev_err_probe(i2s_tdm->dev, ret,
|
|
||||||
"mclk-calibrate clocks missing");
|
|
||||||
|
|
||||||
regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||||
if (IS_ERR(regs)) {
|
if (IS_ERR(regs)) {
|
||||||
return dev_err_probe(i2s_tdm->dev, PTR_ERR(regs),
|
return dev_err_probe(i2s_tdm->dev, PTR_ERR(regs),
|
||||||
@ -1667,13 +1334,6 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
|
|||||||
goto err_disable_hclk;
|
goto err_disable_hclk;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i2s_tdm->mclk_calibrate) {
|
|
||||||
i2s_tdm->mclk_root0_initial_freq = clk_get_rate(i2s_tdm->mclk_root0);
|
|
||||||
i2s_tdm->mclk_root1_initial_freq = clk_get_rate(i2s_tdm->mclk_root1);
|
|
||||||
i2s_tdm->mclk_root0_freq = i2s_tdm->mclk_root0_initial_freq;
|
|
||||||
i2s_tdm->mclk_root1_freq = i2s_tdm->mclk_root1_initial_freq;
|
|
||||||
}
|
|
||||||
|
|
||||||
pm_runtime_enable(&pdev->dev);
|
pm_runtime_enable(&pdev->dev);
|
||||||
|
|
||||||
regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
|
regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
|
||||||
|
@ -385,11 +385,15 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
|
|||||||
|
|
||||||
fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
|
fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
|
||||||
|
|
||||||
|
snd_soc_dpcm_mutex_lock(fe);
|
||||||
ret = dpcm_be_dai_hw_params(fe, stream);
|
ret = dpcm_be_dai_hw_params(fe, stream);
|
||||||
|
snd_soc_dpcm_mutex_unlock(fe);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
snd_soc_dpcm_mutex_lock(fe);
|
||||||
ret = dpcm_be_dai_prepare(fe, stream);
|
ret = dpcm_be_dai_prepare(fe, stream);
|
||||||
|
snd_soc_dpcm_mutex_unlock(fe);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -1219,6 +1219,9 @@ static int snd_soc_add_pcm_runtime(struct snd_soc_card *card,
|
|||||||
if (!snd_soc_is_matching_component(platform, component))
|
if (!snd_soc_is_matching_component(platform, component))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (snd_soc_component_is_dummy(component) && component->num_dai)
|
||||||
|
continue;
|
||||||
|
|
||||||
snd_soc_rtd_add_component(rtd, component);
|
snd_soc_rtd_add_component(rtd, component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
|
|||||||
|
|
||||||
adata = sdev->pdata->hw_pdata;
|
adata = sdev->pdata->hw_pdata;
|
||||||
|
|
||||||
if (adata->signed_fw_image)
|
if (adata->quirks && adata->quirks->signed_fw_image)
|
||||||
size_fw = adata->fw_bin_size - ACP_FIRMWARE_SIGNATURE;
|
size_fw = adata->fw_bin_size - ACP_FIRMWARE_SIGNATURE;
|
||||||
else
|
else
|
||||||
size_fw = adata->fw_bin_size;
|
size_fw = adata->fw_bin_size;
|
||||||
|
@ -20,12 +20,15 @@
|
|||||||
#include "acp.h"
|
#include "acp.h"
|
||||||
#include "acp-dsp-offset.h"
|
#include "acp-dsp-offset.h"
|
||||||
|
|
||||||
#define SECURED_FIRMWARE 1
|
|
||||||
|
|
||||||
static bool enable_fw_debug;
|
static bool enable_fw_debug;
|
||||||
module_param(enable_fw_debug, bool, 0444);
|
module_param(enable_fw_debug, bool, 0444);
|
||||||
MODULE_PARM_DESC(enable_fw_debug, "Enable Firmware debug");
|
MODULE_PARM_DESC(enable_fw_debug, "Enable Firmware debug");
|
||||||
|
|
||||||
|
static struct acp_quirk_entry quirk_valve_galileo = {
|
||||||
|
.signed_fw_image = true,
|
||||||
|
.skip_iram_dram_size_mod = true,
|
||||||
|
};
|
||||||
|
|
||||||
const struct dmi_system_id acp_sof_quirk_table[] = {
|
const struct dmi_system_id acp_sof_quirk_table[] = {
|
||||||
{
|
{
|
||||||
/* Steam Deck OLED device */
|
/* Steam Deck OLED device */
|
||||||
@ -33,7 +36,7 @@ const struct dmi_system_id acp_sof_quirk_table[] = {
|
|||||||
DMI_MATCH(DMI_SYS_VENDOR, "Valve"),
|
DMI_MATCH(DMI_SYS_VENDOR, "Valve"),
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Galileo"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "Galileo"),
|
||||||
},
|
},
|
||||||
.driver_data = (void *)SECURED_FIRMWARE,
|
.driver_data = &quirk_valve_galileo,
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
@ -254,7 +257,7 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adata->signed_fw_image)
|
if (adata->quirks && adata->quirks->signed_fw_image)
|
||||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_INCLUDE_HDR, ACP_SHA_HEADER);
|
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_INCLUDE_HDR, ACP_SHA_HEADER);
|
||||||
|
|
||||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_STRT_ADDR, start_addr);
|
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_STRT_ADDR, start_addr);
|
||||||
@ -278,7 +281,7 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* psp_send_cmd only required for vangogh platform (rev - 5) */
|
/* psp_send_cmd only required for vangogh platform (rev - 5) */
|
||||||
if (desc->rev == 5) {
|
if (desc->rev == 5 && !(adata->quirks && adata->quirks->skip_iram_dram_size_mod)) {
|
||||||
/* Modify IRAM and DRAM size */
|
/* Modify IRAM and DRAM size */
|
||||||
ret = psp_send_cmd(adata, MBOX_ACP_IRAM_DRAM_FENCE_COMMAND | IRAM_DRAM_FENCE_2);
|
ret = psp_send_cmd(adata, MBOX_ACP_IRAM_DRAM_FENCE_COMMAND | IRAM_DRAM_FENCE_2);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -738,26 +741,27 @@ skip_soundwire:
|
|||||||
sdev->debug_box.offset = sdev->host_box.offset + sdev->host_box.size;
|
sdev->debug_box.offset = sdev->host_box.offset + sdev->host_box.size;
|
||||||
sdev->debug_box.size = BOX_SIZE_1024;
|
sdev->debug_box.size = BOX_SIZE_1024;
|
||||||
|
|
||||||
adata->signed_fw_image = false;
|
|
||||||
dmi_id = dmi_first_match(acp_sof_quirk_table);
|
dmi_id = dmi_first_match(acp_sof_quirk_table);
|
||||||
if (dmi_id && dmi_id->driver_data) {
|
if (dmi_id) {
|
||||||
adata->fw_code_bin = devm_kasprintf(sdev->dev, GFP_KERNEL,
|
adata->quirks = dmi_id->driver_data;
|
||||||
"sof-%s-code.bin",
|
|
||||||
chip->name);
|
|
||||||
if (!adata->fw_code_bin) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto free_ipc_irq;
|
|
||||||
}
|
|
||||||
|
|
||||||
adata->fw_data_bin = devm_kasprintf(sdev->dev, GFP_KERNEL,
|
if (adata->quirks->signed_fw_image) {
|
||||||
"sof-%s-data.bin",
|
adata->fw_code_bin = devm_kasprintf(sdev->dev, GFP_KERNEL,
|
||||||
chip->name);
|
"sof-%s-code.bin",
|
||||||
if (!adata->fw_data_bin) {
|
chip->name);
|
||||||
ret = -ENOMEM;
|
if (!adata->fw_code_bin) {
|
||||||
goto free_ipc_irq;
|
ret = -ENOMEM;
|
||||||
}
|
goto free_ipc_irq;
|
||||||
|
}
|
||||||
|
|
||||||
adata->signed_fw_image = dmi_id->driver_data;
|
adata->fw_data_bin = devm_kasprintf(sdev->dev, GFP_KERNEL,
|
||||||
|
"sof-%s-data.bin",
|
||||||
|
chip->name);
|
||||||
|
if (!adata->fw_data_bin) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto free_ipc_irq;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
adata->enable_fw_debug = enable_fw_debug;
|
adata->enable_fw_debug = enable_fw_debug;
|
||||||
|
@ -207,6 +207,11 @@ struct sof_amd_acp_desc {
|
|||||||
u64 sdw_acpi_dev_addr;
|
u64 sdw_acpi_dev_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct acp_quirk_entry {
|
||||||
|
bool signed_fw_image;
|
||||||
|
bool skip_iram_dram_size_mod;
|
||||||
|
};
|
||||||
|
|
||||||
/* Common device data struct for ACP devices */
|
/* Common device data struct for ACP devices */
|
||||||
struct acp_dev_data {
|
struct acp_dev_data {
|
||||||
struct snd_sof_dev *dev;
|
struct snd_sof_dev *dev;
|
||||||
@ -236,7 +241,7 @@ struct acp_dev_data {
|
|||||||
u8 *data_buf;
|
u8 *data_buf;
|
||||||
dma_addr_t sram_dma_addr;
|
dma_addr_t sram_dma_addr;
|
||||||
u8 *sram_data_buf;
|
u8 *sram_data_buf;
|
||||||
bool signed_fw_image;
|
struct acp_quirk_entry *quirks;
|
||||||
struct dma_descriptor dscr_info[ACP_MAX_DESC];
|
struct dma_descriptor dscr_info[ACP_MAX_DESC];
|
||||||
struct acp_dsp_stream stream_buf[ACP_MAX_STREAM];
|
struct acp_dsp_stream stream_buf[ACP_MAX_STREAM];
|
||||||
struct acp_dsp_stream *dtrace_stream;
|
struct acp_dsp_stream *dtrace_stream;
|
||||||
|
@ -143,6 +143,7 @@ EXPORT_SYMBOL_NS(sof_vangogh_ops, SND_SOC_SOF_AMD_COMMON);
|
|||||||
int sof_vangogh_ops_init(struct snd_sof_dev *sdev)
|
int sof_vangogh_ops_init(struct snd_sof_dev *sdev)
|
||||||
{
|
{
|
||||||
const struct dmi_system_id *dmi_id;
|
const struct dmi_system_id *dmi_id;
|
||||||
|
struct acp_quirk_entry *quirks;
|
||||||
|
|
||||||
/* common defaults */
|
/* common defaults */
|
||||||
memcpy(&sof_vangogh_ops, &sof_acp_common_ops, sizeof(struct snd_sof_dsp_ops));
|
memcpy(&sof_vangogh_ops, &sof_acp_common_ops, sizeof(struct snd_sof_dsp_ops));
|
||||||
@ -151,8 +152,12 @@ int sof_vangogh_ops_init(struct snd_sof_dev *sdev)
|
|||||||
sof_vangogh_ops.num_drv = ARRAY_SIZE(vangogh_sof_dai);
|
sof_vangogh_ops.num_drv = ARRAY_SIZE(vangogh_sof_dai);
|
||||||
|
|
||||||
dmi_id = dmi_first_match(acp_sof_quirk_table);
|
dmi_id = dmi_first_match(acp_sof_quirk_table);
|
||||||
if (dmi_id && dmi_id->driver_data)
|
if (dmi_id) {
|
||||||
sof_vangogh_ops.load_firmware = acp_sof_load_signed_firmware;
|
quirks = dmi_id->driver_data;
|
||||||
|
|
||||||
|
if (quirks->signed_fw_image)
|
||||||
|
sof_vangogh_ops.load_firmware = acp_sof_load_signed_firmware;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user