sound fixes for 6.17-rc7

A collection of small fixes.  The volume became higher than wished,
 but nothing really stands out -- all small, nice and smooth.
 A slightly large change is found in qcom USB-audio offload stuff, but
 this is a regression fix specific to this device, hence it should be
 safe to apply at this late stage.
 
 - Various small fixes for ASoC Cirrus, Realtek, lpass, Intel and
   Qualcomm drivers
 - ASoC SoundWire fixes
 - A few TAS2781 HD-audio side-codec driver fixes
 - A fix for Qualcomm USB-audio offload breakage
 - Usual a few HD-audio quirks
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmjNFBMOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE9ngw/+P0wvO9UkWQwf1K1w1NfikJhrBP6+90adiK3x
 UN3o/GZRWFFgLlSST9Uq2XyZZd0PZoiYxWrNNCNo9IUqaOTYvj5Cpznon/ZEQqnS
 dyx8FnPymnx2OK7kN0RCXQ2ALwP8lpZJFtUTJ+sSF2f9JaRaTAFP2RQHG6VXYutz
 9+y/cQBa1/nt8f6DQWmrS2kIdh8tu6lB4+bzMfUl4OrQ/7ySOIPgMXdvizCCLjLA
 uxUpHwYIzYbk4+UZKh9jdvGyMfyzScA9YhX537c3VCQBo6Z8Wg4s2BbkUuFZsnU6
 6c9piUbPzI2JOV9Hs9rBhWo+OOm7x6R0Cy6f5ulaoT4XuBFU7WMRhTi4t6czJGSC
 w1JhHjbG0Tqk/ti1TCuhhDk2yiNcUjizotQEO4EPe1LYnPRIt1UaStw9KnRc+3G8
 iQm3sqYCPMrUK6EWMeHFrImrodllzKbHdOq77SrPdNV8AX5i0OqkJTUmxEhqexbj
 6tU/hIHJ8bT2c04yopne1e9ii9g9KBQGiVkAVY5xl0F1VXh1omrWCVT6zdskTKys
 goFhU/3Qj/9fY1I86A/Pg3D03VIdXNHNDVgBMQxDQ/yUXIFrjYjHfQBs+uPFMRKy
 nQpbXaF3kXwPxa7H4WrMisqsIiEtbBsN3ZLQwIz+7xsM5U3KXypo1OthWZV3q6ej
 VX4liSY=
 =amzV
 -----END PGP SIGNATURE-----

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

Pull sound fixes from Takashi Iwai:
 "A collection of small fixes. The volume became higher than wished, but
  nothing really stands out -- all small, nice and smooth.

  A slightly large change is found in qcom USB-audio offload stuff, but
  this is a regression fix specific to this device, hence it should be
  safe to apply at this late stage.

   - Various small fixes for ASoC Cirrus, Realtek, lpass, Intel and
     Qualcomm drivers

   - ASoC SoundWire fixes

   - A few TAS2781 HD-audio side-codec driver fixes

   - A fix for Qualcomm USB-audio offload breakage

   - Usual a few HD-audio quirks"

* tag 'sound-6.17-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (35 commits)
  ALSA: hda/realtek: Fix mute led for HP Laptop 15-dw4xx
  ALSA: hda: intel-dsp-config: Prevent SEGFAULT if ACPI_HANDLE() is NULL
  ALSA: usb: qcom: Fix false-positive address space check
  ASoC: rt5682s: Adjust SAR ADC button mode to fix noise issue
  ASoC: Intel: PTL: Add entry for HDMI-In capture support to non-I2S codec boards.
  ASoC: amd: acp: Fix incorrect retrival of acp_chip_info
  ASoC: Intel: sof_sdw: use PRODUCT_FAMILY for Fatcat series
  ASoC: qcom: sc8280xp: Fix sound card driver name match data for QCS8275
  ALSA: hda/realtek: Fix volume control on Lenovo Thinkbook 13x Gen 4
  ALSA: hda/realtek: Support Lenovo Thinkbook 13x Gen 5
  ALSA: hda: cs35l41: Support Lenovo Thinkbook 13x Gen 5
  ALSA: hda/realtek: Add ALC295 Dell TAS2781 I2C fixup
  ALSA: hda/tas2781: Fix a potential race condition that causes a NULL pointer in case no efi.get_variable exsits
  ASoC: qcom: sc8280xp: Enable DAI format configuration for MI2S interfaces
  ASoC: qcom: q6apm-lpass-dais: Fix missing set_fmt DAI op for I2S
  ASoC: qcom: audioreach: Fix lpaif_type configuration for the I2S interface
  ASoC: Intel: catpt: Expose correct bit depth to userspace
  ALSA: hda/tas2781: Fix the order of TAS2781 calibrated-data
  ASoC: codecs: lpass-wsa-macro: Fix speaker quality distortion
  ASoC: codecs: lpass-rx-macro: Fix playback quality distortion
  ...
This commit is contained in:
Linus Torvalds 2025-09-19 08:22:07 -07:00
commit e8442d5b7b
32 changed files with 266 additions and 123 deletions

View File

@ -2293,7 +2293,7 @@ delayed_register
notice the need. notice the need.
skip_validation skip_validation
Skip unit descriptor validation (default: no). Skip unit descriptor validation (default: no).
The option is used to ignores the validation errors with the hexdump The option is used to ignore the validation errors with the hexdump
of the unit descriptor instead of a driver probe error, so that we of the unit descriptor instead of a driver probe error, so that we
can check its details. can check its details.
quirk_flags quirk_flags

View File

@ -46,6 +46,7 @@ struct sdca_device_data {
enum sdca_quirk { enum sdca_quirk {
SDCA_QUIRKS_RT712_VB, SDCA_QUIRKS_RT712_VB,
SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING,
}; };
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA) #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)

View File

@ -1063,27 +1063,30 @@ struct sdca_entity_ge {
/** /**
* struct sdca_entity_hide - information specific to HIDE Entities * struct sdca_entity_hide - information specific to HIDE Entities
* @hid: HID device structure * @hid: HID device structure
* @hidtx_ids: HIDTx Report ID
* @num_hidtx_ids: number of HIDTx Report ID * @num_hidtx_ids: number of HIDTx Report ID
* @hidrx_ids: HIDRx Report ID
* @num_hidrx_ids: number of HIDRx Report ID * @num_hidrx_ids: number of HIDRx Report ID
* @hide_reside_function_num: indicating which Audio Function Numbers within this Device * @hidtx_ids: HIDTx Report ID
* @max_delay: the maximum time in microseconds allowed for the Device to change the ownership from Device to Host * @hidrx_ids: HIDRx Report ID
* @af_number_list: which Audio Function Numbers within this Device are sending/receiving the messages in this HIDE * @af_number_list: which Audio Function Numbers within this Device are
* @hid_desc: HID descriptor for the HIDE Entity * sending/receiving the messages in this HIDE
* @hide_reside_function_num: indicating which Audio Function Numbers
* within this Device
* @max_delay: the maximum time in microseconds allowed for the Device
* to change the ownership from Device to Host
* @hid_report_desc: HID Report Descriptor for the HIDE Entity * @hid_report_desc: HID Report Descriptor for the HIDE Entity
* @hid_desc: HID descriptor for the HIDE Entity
*/ */
struct sdca_entity_hide { struct sdca_entity_hide {
struct hid_device *hid; struct hid_device *hid;
unsigned int *hidtx_ids; unsigned int *hidtx_ids;
int num_hidtx_ids;
unsigned int *hidrx_ids; unsigned int *hidrx_ids;
int num_hidtx_ids;
int num_hidrx_ids; int num_hidrx_ids;
unsigned int af_number_list[SDCA_MAX_FUNCTION_COUNT];
unsigned int hide_reside_function_num; unsigned int hide_reside_function_num;
unsigned int max_delay; unsigned int max_delay;
unsigned int af_number_list[SDCA_MAX_FUNCTION_COUNT];
struct hid_descriptor hid_desc;
unsigned char *hid_report_desc; unsigned char *hid_report_desc;
struct hid_descriptor hid_desc;
}; };
/** /**

View File

@ -3702,6 +3702,7 @@ enum {
ALC236_FIXUP_DELL_DUAL_CODECS, ALC236_FIXUP_DELL_DUAL_CODECS,
ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI, ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
ALC287_FIXUP_TAS2781_I2C, ALC287_FIXUP_TAS2781_I2C,
ALC295_FIXUP_DELL_TAS2781_I2C,
ALC245_FIXUP_TAS2781_SPI_2, ALC245_FIXUP_TAS2781_SPI_2,
ALC287_FIXUP_TXNW2781_I2C, ALC287_FIXUP_TXNW2781_I2C,
ALC287_FIXUP_YOGA7_14ARB7_I2C, ALC287_FIXUP_YOGA7_14ARB7_I2C,
@ -5167,6 +5168,12 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
.v.func = alc294_fixup_gx502_hp, .v.func = alc294_fixup_gx502_hp,
}, },
[ALC295_FIXUP_DELL_TAS2781_I2C] = {
.type = HDA_FIXUP_FUNC,
.v.func = tas2781_fixup_tias_i2c,
.chained = true,
.chain_id = ALC289_FIXUP_DUAL_SPK
},
[ALC294_FIXUP_ASUS_GU502_PINS] = { [ALC294_FIXUP_ASUS_GU502_PINS] = {
.type = HDA_FIXUP_PINS, .type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) { .v.pins = (const struct hda_pintbl[]) {
@ -6289,8 +6296,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS), SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c28, "Dell Inspiron 16 Plus 7630", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS), SND_PCI_QUIRK(0x1028, 0x0c28, "Dell Inspiron 16 Plus 7630", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x0c4d, "Dell", ALC287_FIXUP_CS35L41_I2C_4), SND_PCI_QUIRK(0x1028, 0x0c4d, "Dell", ALC287_FIXUP_CS35L41_I2C_4),
SND_PCI_QUIRK(0x1028, 0x0c94, "Dell Polaris 3 metal", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x1028, 0x0c94, "Dell Polaris 3 metal", ALC295_FIXUP_DELL_TAS2781_I2C),
SND_PCI_QUIRK(0x1028, 0x0c96, "Dell Polaris 2in1", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x1028, 0x0c96, "Dell Polaris 2in1", ALC295_FIXUP_DELL_TAS2781_I2C),
SND_PCI_QUIRK(0x1028, 0x0cbd, "Dell Oasis 13 CS MTL-U", ALC289_FIXUP_DELL_CS35L41_SPI_2), SND_PCI_QUIRK(0x1028, 0x0cbd, "Dell Oasis 13 CS MTL-U", ALC289_FIXUP_DELL_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1028, 0x0cbe, "Dell Oasis 13 2-IN-1 MTL-U", ALC289_FIXUP_DELL_CS35L41_SPI_2), SND_PCI_QUIRK(0x1028, 0x0cbe, "Dell Oasis 13 2-IN-1 MTL-U", ALC289_FIXUP_DELL_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1028, 0x0cbf, "Dell Oasis 13 Low Weight MTU-L", ALC289_FIXUP_DELL_CS35L41_SPI_2), SND_PCI_QUIRK(0x1028, 0x0cbf, "Dell Oasis 13 Low Weight MTU-L", ALC289_FIXUP_DELL_CS35L41_SPI_2),
@ -6469,6 +6476,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8992, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8992, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8994, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8994, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8995, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8995, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x89a0, "HP Laptop 15-dw4xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
SND_PCI_QUIRK(0x103c, 0x89a4, "HP ProBook 440 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89a4, "HP ProBook 440 G9", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89a6, "HP ProBook 450 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89a6, "HP ProBook 450 G9", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED),
@ -7071,8 +7079,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38bf, "Yoga S980-14.5 proX LX Dual", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38bf, "Yoga S980-14.5 proX LX Dual", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38c3, "Y980 DUAL", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38c3, "Y980 DUAL", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38c7, "Thinkbook 13x Gen 4", ALC287_FIXUP_CS35L41_I2C_4), SND_PCI_QUIRK(0x17aa, 0x38c7, "Thinkbook 13x Gen 4", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x38c8, "Thinkbook 13x Gen 4", ALC287_FIXUP_CS35L41_I2C_4), SND_PCI_QUIRK(0x17aa, 0x38c8, "Thinkbook 13x Gen 4", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x38cb, "Y790 YG DUAL", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38cb, "Y790 YG DUAL", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38cd, "Y790 VECO DUAL", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38cd, "Y790 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38d2, "Lenovo Yoga 9 14IMH9", ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN), SND_PCI_QUIRK(0x17aa, 0x38d2, "Lenovo Yoga 9 14IMH9", ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN),
@ -7093,6 +7101,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3913, "Lenovo 145", ALC236_FIXUP_LENOVO_INV_DMIC), SND_PCI_QUIRK(0x17aa, 0x3913, "Lenovo 145", ALC236_FIXUP_LENOVO_INV_DMIC),
SND_PCI_QUIRK(0x17aa, 0x391f, "Yoga S990-16 pro Quad YC Quad", ALC287_FIXUP_TXNW2781_I2C), SND_PCI_QUIRK(0x17aa, 0x391f, "Yoga S990-16 pro Quad YC Quad", ALC287_FIXUP_TXNW2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x3920, "Yoga S990-16 pro Quad VECO Quad", ALC287_FIXUP_TXNW2781_I2C), SND_PCI_QUIRK(0x17aa, 0x3920, "Yoga S990-16 pro Quad VECO Quad", ALC287_FIXUP_TXNW2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x3929, "Thinkbook 13x Gen 5", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x392b, "Thinkbook 13x Gen 5", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),

View File

@ -135,6 +135,8 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "17AA38C8", 4, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT }, 0, 2, -1, 1000, 4500, 24 }, { "17AA38C8", 4, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT }, 0, 2, -1, 1000, 4500, 24 },
{ "17AA38F9", 2, EXTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, 0, 2, -1, 0, 0, 0 }, { "17AA38F9", 2, EXTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
{ "17AA38FA", 2, EXTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, 0, 2, -1, 0, 0, 0 }, { "17AA38FA", 2, EXTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
{ "17AA3929", 4, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT }, 0, 2, -1, 1000, 4500, 24 },
{ "17AA392B", 4, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT }, 0, 2, -1, 1000, 4500, 24 },
{} {}
}; };
@ -558,6 +560,8 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "17AA38C8", generic_dsd_config }, { "CSC3551", "17AA38C8", generic_dsd_config },
{ "CSC3551", "17AA38F9", generic_dsd_config }, { "CSC3551", "17AA38F9", generic_dsd_config },
{ "CSC3551", "17AA38FA", generic_dsd_config }, { "CSC3551", "17AA38FA", generic_dsd_config },
{ "CSC3551", "17AA3929", generic_dsd_config },
{ "CSC3551", "17AA392B", generic_dsd_config },
{} {}
}; };

View File

@ -33,6 +33,23 @@ const efi_guid_t tasdev_fct_efi_guid[] = {
}; };
EXPORT_SYMBOL_NS_GPL(tasdev_fct_efi_guid, "SND_HDA_SCODEC_TAS2781"); EXPORT_SYMBOL_NS_GPL(tasdev_fct_efi_guid, "SND_HDA_SCODEC_TAS2781");
/*
* The order of calibrated-data writing function is a bit different from the
* order in UEFI. Here is the conversion to match the order of calibrated-data
* writing function.
*/
static void cali_cnv(unsigned char *data, unsigned int base, int offset)
{
struct cali_reg reg_data;
memcpy(&reg_data, &data[base], sizeof(reg_data));
/* the data order has to be swapped between r0_low_reg and inv0_reg */
swap(reg_data.r0_low_reg, reg_data.invr0_reg);
cpu_to_be32_array((__force __be32 *)(data + offset + 1),
(u32 *)&reg_data, TASDEV_CALIB_N);
}
static void tas2781_apply_calib(struct tasdevice_priv *p) static void tas2781_apply_calib(struct tasdevice_priv *p)
{ {
struct calidata *cali_data = &p->cali_data; struct calidata *cali_data = &p->cali_data;
@ -103,8 +120,7 @@ static void tas2781_apply_calib(struct tasdevice_priv *p)
data[l] = k; data[l] = k;
oft++; oft++;
for (i = 0; i < TASDEV_CALIB_N * 4; i++) cali_cnv(data, 4 * oft, l);
data[l + i + 1] = data[4 * oft + i];
k++; k++;
} }
} }
@ -130,9 +146,8 @@ static void tas2781_apply_calib(struct tasdevice_priv *p)
for (j = p->ndev - 1; j >= 0; j--) { for (j = p->ndev - 1; j >= 0; j--) {
l = j * (cali_data->cali_dat_sz_per_dev + 1); l = j * (cali_data->cali_dat_sz_per_dev + 1);
for (i = TASDEV_CALIB_N * 4; i > 0 ; i--) cali_cnv(data, cali_data->cali_dat_sz_per_dev * j, l);
data[l + i] = data[p->index * 5 + i]; data[l] = j;
data[l+i] = j;
} }
} }
@ -178,6 +193,11 @@ int tas2781_save_calibration(struct tas2781_hda *hda)
efi_status_t status; efi_status_t status;
int i; int i;
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) {
dev_err(p->dev, "%s: NO EFI FOUND!\n", __func__);
return -EINVAL;
}
if (hda->catlog_id < LENOVO) if (hda->catlog_id < LENOVO)
efi_guid = tasdev_fct_efi_guid[hda->catlog_id]; efi_guid = tasdev_fct_efi_guid[hda->catlog_id];

View File

@ -315,6 +315,11 @@ static int tas2563_save_calibration(struct tas2781_hda *h)
unsigned int attr; unsigned int attr;
int ret, i, j, k; int ret, i, j, k;
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) {
dev_err(p->dev, "%s: NO EFI FOUND!\n", __func__);
return -EINVAL;
}
cd->cali_dat_sz_per_dev = TAS2563_CAL_DATA_SIZE * TASDEV_CALIB_N; cd->cali_dat_sz_per_dev = TAS2563_CAL_DATA_SIZE * TASDEV_CALIB_N;
/* extra byte for each device is the device number */ /* extra byte for each device is the device number */

View File

@ -650,6 +650,8 @@ static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
int ret; int ret;
handle = ACPI_HANDLE(&pci->dev); handle = ACPI_HANDLE(&pci->dev);
if (!handle)
return -ENODEV;
ret = sdw_intel_acpi_scan(handle, &info); ret = sdw_intel_acpi_scan(handle, &info);
if (ret < 0) if (ret < 0)

View File

@ -73,7 +73,7 @@ static int acp_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt) unsigned int fmt)
{ {
struct device *dev = cpu_dai->component->dev; struct device *dev = cpu_dai->component->dev;
struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_chip_info *chip = dev_get_drvdata(dev->parent);
int mode; int mode;
mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK; mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
@ -199,7 +199,7 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
u32 reg_val, fmt_reg, tdm_fmt; u32 reg_val, fmt_reg, tdm_fmt;
u32 lrclk_div_val, bclk_div_val; u32 lrclk_div_val, bclk_div_val;
chip = dev_get_platdata(dev); chip = dev_get_drvdata(dev->parent);
rsrc = chip->rsrc; rsrc = chip->rsrc;
/* These values are as per Hardware Spec */ /* These values are as per Hardware Spec */
@ -386,7 +386,7 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
{ {
struct acp_stream *stream = substream->runtime->private_data; struct acp_stream *stream = substream->runtime->private_data;
struct device *dev = dai->component->dev; struct device *dev = dai->component->dev;
struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_chip_info *chip = dev_get_drvdata(dev->parent);
struct acp_resource *rsrc = chip->rsrc; struct acp_resource *rsrc = chip->rsrc;
u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg; u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg;
@ -516,14 +516,13 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{ {
struct device *dev = dai->component->dev; struct device *dev = dai->component->dev;
struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_chip_info *chip = dev_get_drvdata(dev->parent);
struct acp_resource *rsrc = chip->rsrc; struct acp_resource *rsrc = chip->rsrc;
struct acp_stream *stream = substream->runtime->private_data; struct acp_stream *stream = substream->runtime->private_data;
u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0; u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0;
u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl; u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl;
unsigned int dir = substream->stream; unsigned int dir = substream->stream;
chip = dev_get_platdata(dev);
switch (dai->driver->id) { switch (dai->driver->id) {
case I2S_SP_INSTANCE: case I2S_SP_INSTANCE:
if (dir == SNDRV_PCM_STREAM_PLAYBACK) { if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
@ -632,7 +631,7 @@ static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_d
{ {
struct acp_stream *stream = substream->runtime->private_data; struct acp_stream *stream = substream->runtime->private_data;
struct device *dev = dai->component->dev; struct device *dev = dai->component->dev;
struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_chip_info *chip = dev_get_drvdata(dev->parent);
struct acp_resource *rsrc = chip->rsrc; struct acp_resource *rsrc = chip->rsrc;
unsigned int dir = substream->stream; unsigned int dir = substream->stream;
unsigned int irq_bit = 0; unsigned int irq_bit = 0;

View File

@ -79,6 +79,22 @@ static const struct dmi_system_id soc_sdw_quirk_table[] = {
}, },
.driver_data = (void *)(ASOC_SDW_CODEC_SPKR), .driver_data = (void *)(ASOC_SDW_CODEC_SPKR),
}, },
{
.callback = soc_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0DD3"),
},
.driver_data = (void *)(ASOC_SDW_CODEC_SPKR),
},
{
.callback = soc_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0DD4"),
},
.driver_data = (void *)(ASOC_SDW_CODEC_SPKR),
},
{} {}
}; };

View File

@ -130,7 +130,7 @@
#define PDM_DMA_INTR_MASK 0x10000 #define PDM_DMA_INTR_MASK 0x10000
#define PDM_DEC_64 0x2 #define PDM_DEC_64 0x2
#define PDM_CLK_FREQ_MASK 0x07 #define PDM_CLK_FREQ_MASK 0x07
#define PDM_MISC_CTRL_MASK 0x10 #define PDM_MISC_CTRL_MASK 0x18
#define PDM_ENABLE 0x01 #define PDM_ENABLE 0x01
#define PDM_DISABLE 0x00 #define PDM_DISABLE 0x00
#define DMA_EN_MASK 0x02 #define DMA_EN_MASK 0x02

View File

@ -618,6 +618,7 @@ static struct interp_sample_rate sr_val_tbl[] = {
{176400, 0xB}, {352800, 0xC}, {176400, 0xB}, {352800, 0xC},
}; };
/* Matches also rx_macro_mux_text */
enum { enum {
RX_MACRO_AIF1_PB, RX_MACRO_AIF1_PB,
RX_MACRO_AIF2_PB, RX_MACRO_AIF2_PB,
@ -722,6 +723,7 @@ static const char * const rx_int2_2_interp_mux_text[] = {
"ZERO", "RX INT2_2 MUX", "ZERO", "RX INT2_2 MUX",
}; };
/* Order must match RX_MACRO_MAX_DAIS enum (offset by 1) */
static const char *const rx_macro_mux_text[] = { static const char *const rx_macro_mux_text[] = {
"ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB"
}; };
@ -2474,6 +2476,7 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol,
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
struct snd_soc_dapm_update *update = NULL; struct snd_soc_dapm_update *update = NULL;
u32 rx_port_value = ucontrol->value.enumerated.item[0]; u32 rx_port_value = ucontrol->value.enumerated.item[0];
unsigned int dai_id;
u32 aif_rst; u32 aif_rst;
struct rx_macro *rx = snd_soc_component_get_drvdata(component); struct rx_macro *rx = snd_soc_component_get_drvdata(component);
@ -2490,19 +2493,24 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol,
switch (rx_port_value) { switch (rx_port_value) {
case 0: case 0:
if (rx->active_ch_cnt[aif_rst]) { /*
clear_bit(widget->shift, * active_ch_cnt and active_ch_mask use DAI IDs (RX_MACRO_MAX_DAIS).
&rx->active_ch_mask[aif_rst]); * active_ch_cnt == 0 was tested in if() above.
rx->active_ch_cnt[aif_rst]--; */
dai_id = aif_rst - 1;
if (rx->active_ch_cnt[dai_id]) {
clear_bit(widget->shift, &rx->active_ch_mask[dai_id]);
rx->active_ch_cnt[dai_id]--;
} }
break; break;
case 1: case 1:
case 2: case 2:
case 3: case 3:
case 4: case 4:
set_bit(widget->shift, /* active_ch_cnt and active_ch_mask use DAI IDs (WSA_MACRO_MAX_DAIS). */
&rx->active_ch_mask[rx_port_value]); dai_id = rx_port_value - 1;
rx->active_ch_cnt[rx_port_value]++; set_bit(widget->shift, &rx->active_ch_mask[dai_id]);
rx->active_ch_cnt[dai_id]++;
break; break;
default: default:
dev_err(component->dev, dev_err(component->dev,

View File

@ -368,6 +368,7 @@ static struct interp_sample_rate int_mix_sample_rate_val[] = {
{192000, 0x6}, /* 192K */ {192000, 0x6}, /* 192K */
}; };
/* Matches also rx_mux_text */
enum { enum {
WSA_MACRO_AIF1_PB, WSA_MACRO_AIF1_PB,
WSA_MACRO_AIF_MIX1_PB, WSA_MACRO_AIF_MIX1_PB,
@ -465,6 +466,7 @@ static const char *const rx_mix_ec_text[] = {
"ZERO", "RX_MIX_TX0", "RX_MIX_TX1" "ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
}; };
/* Order must match WSA_MACRO_MAX_DAIS enum (offset by 1) */
static const char *const rx_mux_text[] = { static const char *const rx_mux_text[] = {
"ZERO", "AIF1_PB", "AIF_MIX1_PB" "ZERO", "AIF1_PB", "AIF_MIX1_PB"
}; };
@ -2207,6 +2209,7 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
u32 rx_port_value = ucontrol->value.integer.value[0]; u32 rx_port_value = ucontrol->value.integer.value[0];
u32 bit_input; u32 bit_input;
u32 aif_rst; u32 aif_rst;
unsigned int dai_id;
struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
aif_rst = wsa->rx_port_value[widget->shift]; aif_rst = wsa->rx_port_value[widget->shift];
@ -2224,17 +2227,22 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
switch (rx_port_value) { switch (rx_port_value) {
case 0: case 0:
if (wsa->active_ch_cnt[aif_rst]) { /*
clear_bit(bit_input, * active_ch_cnt and active_ch_mask use DAI IDs (WSA_MACRO_MAX_DAIS).
&wsa->active_ch_mask[aif_rst]); * active_ch_cnt == 0 was tested in if() above.
wsa->active_ch_cnt[aif_rst]--; */
dai_id = aif_rst - 1;
if (wsa->active_ch_cnt[dai_id]) {
clear_bit(bit_input, &wsa->active_ch_mask[dai_id]);
wsa->active_ch_cnt[dai_id]--;
} }
break; break;
case 1: case 1:
case 2: case 2:
set_bit(bit_input, /* active_ch_cnt and active_ch_mask use DAI IDs (WSA_MACRO_MAX_DAIS). */
&wsa->active_ch_mask[rx_port_value]); dai_id = rx_port_value - 1;
wsa->active_ch_cnt[rx_port_value]++; set_bit(bit_input, &wsa->active_ch_mask[dai_id]);
wsa->active_ch_cnt[dai_id]++;
break; break;
default: default:
dev_err(component->dev, dev_err(component->dev,

View File

@ -653,14 +653,15 @@ static void rt5682s_sar_power_mode(struct snd_soc_component *component, int mode
switch (mode) { switch (mode) {
case SAR_PWR_SAVING: case SAR_PWR_SAVING:
snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_3, snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_3,
RT5682S_CBJ_IN_BUF_MASK, RT5682S_CBJ_IN_BUF_DIS); RT5682S_CBJ_IN_BUF_MASK, RT5682S_CBJ_IN_BUF_EN);
snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1,
RT5682S_MB1_PATH_MASK | RT5682S_MB2_PATH_MASK, RT5682S_MB1_PATH_MASK | RT5682S_MB2_PATH_MASK |
RT5682S_CTRL_MB1_REG | RT5682S_CTRL_MB2_REG); RT5682S_VREF_POW_MASK, RT5682S_CTRL_MB1_FSM |
RT5682S_CTRL_MB2_FSM | RT5682S_VREF_POW_FSM);
snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1,
RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK |
RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS | RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS |
RT5682S_SAR_BUTDET_POW_SAV | RT5682S_SAR_SEL_MB1_2_MANU); RT5682S_SAR_BUTDET_POW_NORM | RT5682S_SAR_SEL_MB1_2_MANU);
usleep_range(5000, 5500); usleep_range(5000, 5500);
snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1,
RT5682S_SAR_BUTDET_MASK, RT5682S_SAR_BUTDET_EN); RT5682S_SAR_BUTDET_MASK, RT5682S_SAR_BUTDET_EN);
@ -688,7 +689,7 @@ static void rt5682s_sar_power_mode(struct snd_soc_component *component, int mode
snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1,
RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK |
RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS | RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS |
RT5682S_SAR_BUTDET_POW_SAV | RT5682S_SAR_SEL_MB1_2_MANU); RT5682S_SAR_BUTDET_POW_NORM | RT5682S_SAR_SEL_MB1_2_MANU);
break; break;
default: default:
dev_err(component->dev, "Invalid SAR Power mode: %d\n", mode); dev_err(component->dev, "Invalid SAR Power mode: %d\n", mode);
@ -725,7 +726,7 @@ static void rt5682s_disable_push_button_irq(struct snd_soc_component *component)
snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1,
RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK |
RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS | RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS |
RT5682S_SAR_BUTDET_POW_SAV | RT5682S_SAR_SEL_MB1_2_MANU); RT5682S_SAR_BUTDET_POW_NORM | RT5682S_SAR_SEL_MB1_2_MANU);
} }
/** /**
@ -786,7 +787,7 @@ static int rt5682s_headset_detect(struct snd_soc_component *component, int jack_
jack_type = SND_JACK_HEADSET; jack_type = SND_JACK_HEADSET;
snd_soc_component_write(component, RT5682S_SAR_IL_CMD_3, 0x024c); snd_soc_component_write(component, RT5682S_SAR_IL_CMD_3, 0x024c);
snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1,
RT5682S_FAST_OFF_MASK, RT5682S_FAST_OFF_EN); RT5682S_FAST_OFF_MASK, RT5682S_FAST_OFF_DIS);
snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1,
RT5682S_SAR_SEL_MB1_2_MASK, val << RT5682S_SAR_SEL_MB1_2_SFT); RT5682S_SAR_SEL_MB1_2_MASK, val << RT5682S_SAR_SEL_MB1_2_SFT);
rt5682s_enable_push_button_irq(component); rt5682s_enable_push_button_irq(component);
@ -966,7 +967,7 @@ static int rt5682s_set_jack_detect(struct snd_soc_component *component,
RT5682S_EMB_JD_MASK | RT5682S_DET_TYPE | RT5682S_EMB_JD_MASK | RT5682S_DET_TYPE |
RT5682S_POL_FAST_OFF_MASK | RT5682S_MIC_CAP_MASK, RT5682S_POL_FAST_OFF_MASK | RT5682S_MIC_CAP_MASK,
RT5682S_EMB_JD_EN | RT5682S_DET_TYPE | RT5682S_EMB_JD_EN | RT5682S_DET_TYPE |
RT5682S_POL_FAST_OFF_HIGH | RT5682S_MIC_CAP_HS); RT5682S_POL_FAST_OFF_LOW | RT5682S_MIC_CAP_HS);
regmap_update_bits(rt5682s->regmap, RT5682S_SAR_IL_CMD_1, regmap_update_bits(rt5682s->regmap, RT5682S_SAR_IL_CMD_1,
RT5682S_SAR_POW_MASK, RT5682S_SAR_POW_EN); RT5682S_SAR_POW_MASK, RT5682S_SAR_POW_EN);
regmap_update_bits(rt5682s->regmap, RT5682S_GPIO_CTRL_1, regmap_update_bits(rt5682s->regmap, RT5682S_GPIO_CTRL_1,

View File

@ -1890,11 +1890,9 @@ int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)
rt712_sdca_va_io_init(rt712); rt712_sdca_va_io_init(rt712);
} else { } else {
if (!rt712->dmic_function_found) { if (!rt712->dmic_function_found)
dev_err(&slave->dev, "%s RT712 VB detected but no SMART_MIC function exposed in ACPI\n", dev_warn(&slave->dev, "%s RT712 VB detected but no SMART_MIC function exposed in ACPI\n",
__func__); __func__);
goto suspend;
}
/* multilanes and DMIC are supported by rt712vb */ /* multilanes and DMIC are supported by rt712vb */
prop->lane_control_support = true; prop->lane_control_support = true;

View File

@ -1737,9 +1737,10 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
sma1307->set.checksum = data[sma1307->set.header_size - 2]; sma1307->set.checksum = data[sma1307->set.header_size - 2];
sma1307->set.num_mode = data[sma1307->set.header_size - 1]; sma1307->set.num_mode = data[sma1307->set.header_size - 1];
num_mode = sma1307->set.num_mode; num_mode = sma1307->set.num_mode;
sma1307->set.header = devm_kzalloc(sma1307->dev, sma1307->set.header = devm_kmalloc_array(sma1307->dev,
sma1307->set.header_size, sma1307->set.header_size,
GFP_KERNEL); sizeof(int),
GFP_KERNEL);
if (!sma1307->set.header) { if (!sma1307->set.header) {
sma1307->set.status = false; sma1307->set.status = false;
return; return;

View File

@ -220,7 +220,7 @@ static const struct snd_kcontrol_new wm8940_snd_controls[] = {
SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL, SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL,
0, 255, 0, wm8940_adc_tlv), 0, 255, 0, wm8940_adc_tlv),
SOC_ENUM("Mic Bias Level", wm8940_mic_bias_level_enum), SOC_ENUM("Mic Bias Level", wm8940_mic_bias_level_enum),
SOC_SINGLE_TLV("Capture Boost Volue", WM8940_ADCBOOST, SOC_SINGLE_TLV("Capture Boost Volume", WM8940_ADCBOOST,
8, 1, 0, wm8940_capture_boost_vol_tlv), 8, 1, 0, wm8940_capture_boost_vol_tlv),
SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL, SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL,
0, 63, 0, wm8940_spk_vol_tlv), 0, 63, 0, wm8940_spk_vol_tlv),
@ -693,7 +693,12 @@ static int wm8940_update_clocks(struct snd_soc_dai *dai)
f = wm8940_get_mclkdiv(priv->mclk, fs256, &mclkdiv); f = wm8940_get_mclkdiv(priv->mclk, fs256, &mclkdiv);
if (f != priv->mclk) { if (f != priv->mclk) {
/* The PLL performs best around 90MHz */ /* The PLL performs best around 90MHz */
fpll = wm8940_get_mclkdiv(22500000, fs256, &mclkdiv); if (fs256 % 8000)
f = 22579200;
else
f = 24576000;
fpll = wm8940_get_mclkdiv(f, fs256, &mclkdiv);
} }
wm8940_set_dai_pll(dai, 0, 0, priv->mclk, fpll); wm8940_set_dai_pll(dai, 0, 0, priv->mclk, fpll);

View File

@ -419,10 +419,14 @@ static int wm8974_update_clocks(struct snd_soc_dai *dai)
fs256 = 256 * priv->fs; fs256 = 256 * priv->fs;
f = wm8974_get_mclkdiv(priv->mclk, fs256, &mclkdiv); f = wm8974_get_mclkdiv(priv->mclk, fs256, &mclkdiv);
if (f != priv->mclk) { if (f != priv->mclk) {
/* The PLL performs best around 90MHz */ /* The PLL performs best around 90MHz */
fpll = wm8974_get_mclkdiv(22500000, fs256, &mclkdiv); if (fs256 % 8000)
f = 22579200;
else
f = 24576000;
fpll = wm8974_get_mclkdiv(f, fs256, &mclkdiv);
} }
wm8974_set_dai_pll(dai, 0, 0, priv->mclk, fpll); wm8974_set_dai_pll(dai, 0, 0, priv->mclk, fpll);

View File

@ -761,7 +761,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
.callback = sof_sdw_quirk_cb, .callback = sof_sdw_quirk_cb,
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"), DMI_MATCH(DMI_SYS_VENDOR, "Google"),
DMI_MATCH(DMI_PRODUCT_NAME, "Fatcat"), DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Fatcat"),
}, },
.driver_data = (void *)(SOC_SDW_PCH_DMIC | .driver_data = (void *)(SOC_SDW_PCH_DMIC |
SOF_BT_OFFLOAD_SSP(2) | SOF_BT_OFFLOAD_SSP(2) |

View File

@ -216,6 +216,12 @@ static const struct platform_device_id board_ids[] = {
/* SSP 0 and SSP 2 are used for HDMI IN */ /* SSP 0 and SSP 2 are used for HDMI IN */
SOF_HDMI_PLAYBACK_PRESENT), SOF_HDMI_PLAYBACK_PRESENT),
}, },
{
.name = "ptl_lt6911_hdmi_ssp",
.driver_data = (kernel_ulong_t)(SOF_SSP_MASK_HDMI_CAPTURE(0x5) |
/* SSP 0 and SSP 2 are used for HDMI IN */
SOF_HDMI_PLAYBACK_PRESENT),
},
{ } { }
}; };
MODULE_DEVICE_TABLE(platform, board_ids); MODULE_DEVICE_TABLE(platform, board_ids);

View File

@ -568,8 +568,9 @@ static const struct snd_pcm_hardware catpt_pcm_hardware = {
SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
.formats = SNDRV_PCM_FMTBIT_S16_LE | .formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE, SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
.period_bytes_min = PAGE_SIZE, .period_bytes_min = PAGE_SIZE,
.period_bytes_max = CATPT_BUFFER_MAX_SIZE / CATPT_PCM_PERIODS_MIN, .period_bytes_max = CATPT_BUFFER_MAX_SIZE / CATPT_PCM_PERIODS_MIN,
.periods_min = CATPT_PCM_PERIODS_MIN, .periods_min = CATPT_PCM_PERIODS_MIN,
@ -698,14 +699,18 @@ static struct snd_soc_dai_driver dai_drivers[] = {
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
.rates = SNDRV_PCM_RATE_48000, .rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
}, },
.capture = { .capture = {
.stream_name = "Analog Capture", .stream_name = "Analog Capture",
.channels_min = 2, .channels_min = 2,
.channels_max = 4, .channels_max = 4,
.rates = SNDRV_PCM_RATE_48000, .rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
}, },
}, },
{ {
@ -717,7 +722,9 @@ static struct snd_soc_dai_driver dai_drivers[] = {
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_192000, .rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
}, },
}, },
{ {
@ -729,7 +736,9 @@ static struct snd_soc_dai_driver dai_drivers[] = {
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_192000, .rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
}, },
}, },
{ {
@ -741,7 +750,9 @@ static struct snd_soc_dai_driver dai_drivers[] = {
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
.rates = SNDRV_PCM_RATE_48000, .rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
}, },
}, },
{ {

View File

@ -61,6 +61,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_machines[] = {
SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
}, },
/* place amp-only boards in the end of table */
{
.id = "INTC10B0",
.drv_name = "ptl_lt6911_hdmi_ssp",
.sof_tplg_filename = "sof-ptl-hdmi-ssp02.tplg",
},
{}, {},
}; };
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_machines); EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_machines);

View File

@ -971,6 +971,7 @@ static int audioreach_i2s_set_media_format(struct q6apm_graph *graph,
param_data->param_id = PARAM_ID_I2S_INTF_CFG; param_data->param_id = PARAM_ID_I2S_INTF_CFG;
param_data->param_size = ic_sz - APM_MODULE_PARAM_DATA_SIZE; param_data->param_size = ic_sz - APM_MODULE_PARAM_DATA_SIZE;
intf_cfg->cfg.lpaif_type = module->hw_interface_type;
intf_cfg->cfg.intf_idx = module->hw_interface_idx; intf_cfg->cfg.intf_idx = module->hw_interface_idx;
intf_cfg->cfg.sd_line_idx = module->sd_line_idx; intf_cfg->cfg.sd_line_idx = module->sd_line_idx;

View File

@ -213,8 +213,10 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
return 0; return 0;
err: err:
q6apm_graph_close(dai_data->graph[dai->id]); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
dai_data->graph[dai->id] = NULL; q6apm_graph_close(dai_data->graph[dai->id]);
dai_data->graph[dai->id] = NULL;
}
return rc; return rc;
} }
@ -260,6 +262,7 @@ static const struct snd_soc_dai_ops q6i2s_ops = {
.shutdown = q6apm_lpass_dai_shutdown, .shutdown = q6apm_lpass_dai_shutdown,
.set_channel_map = q6dma_set_channel_map, .set_channel_map = q6dma_set_channel_map,
.hw_params = q6dma_hw_params, .hw_params = q6dma_hw_params,
.set_fmt = q6i2s_set_fmt,
}; };
static const struct snd_soc_dai_ops q6hdmi_ops = { static const struct snd_soc_dai_ops q6hdmi_ops = {

View File

@ -32,6 +32,10 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
int dp_pcm_id = 0; int dp_pcm_id = 0;
switch (cpu_dai->id) { switch (cpu_dai->id) {
case PRIMARY_MI2S_RX...QUATERNARY_MI2S_TX:
case QUINARY_MI2S_RX...QUINARY_MI2S_TX:
snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
break;
case WSA_CODEC_DMA_RX_0: case WSA_CODEC_DMA_RX_0:
case WSA_CODEC_DMA_RX_1: case WSA_CODEC_DMA_RX_1:
/* /*
@ -186,7 +190,7 @@ static int sc8280xp_platform_probe(struct platform_device *pdev)
static const struct of_device_id snd_sc8280xp_dt_match[] = { static const struct of_device_id snd_sc8280xp_dt_match[] = {
{.compatible = "qcom,qcm6490-idp-sndcard", "qcm6490"}, {.compatible = "qcom,qcm6490-idp-sndcard", "qcm6490"},
{.compatible = "qcom,qcs6490-rb3gen2-sndcard", "qcs6490"}, {.compatible = "qcom,qcs6490-rb3gen2-sndcard", "qcs6490"},
{.compatible = "qcom,qcs8275-sndcard", "qcs8275"}, {.compatible = "qcom,qcs8275-sndcard", "qcs8300"},
{.compatible = "qcom,qcs9075-sndcard", "qcs9075"}, {.compatible = "qcom,qcs9075-sndcard", "qcs9075"},
{.compatible = "qcom,qcs9100-sndcard", "qcs9100"}, {.compatible = "qcom,qcs9100-sndcard", "qcs9100"},
{.compatible = "qcom,sc8280xp-sndcard", "sc8280xp"}, {.compatible = "qcom,sc8280xp-sndcard", "sc8280xp"},

View File

@ -7,6 +7,7 @@
*/ */
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/soundwire/sdw.h> #include <linux/soundwire/sdw.h>
@ -55,11 +56,30 @@ static bool sdca_device_quirk_rt712_vb(struct sdw_slave *slave)
return false; return false;
} }
static bool sdca_device_quirk_skip_func_type_patching(struct sdw_slave *slave)
{
const char *vendor, *sku;
vendor = dmi_get_system_info(DMI_SYS_VENDOR);
sku = dmi_get_system_info(DMI_PRODUCT_SKU);
if (vendor && sku &&
!strcmp(vendor, "Dell Inc.") &&
(!strcmp(sku, "0C62") || !strcmp(sku, "0C63") || !strcmp(sku, "0C6B")) &&
slave->sdca_data.interface_revision == 0x061c &&
slave->id.mfg_id == 0x01fa && slave->id.part_id == 0x4243)
return true;
return false;
}
bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk) bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk)
{ {
switch (quirk) { switch (quirk) {
case SDCA_QUIRKS_RT712_VB: case SDCA_QUIRKS_RT712_VB:
return sdca_device_quirk_rt712_vb(slave); return sdca_device_quirk_rt712_vb(slave);
case SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING:
return sdca_device_quirk_skip_func_type_patching(slave);
default: default:
break; break;
} }

View File

@ -90,6 +90,7 @@ static int find_sdca_function(struct acpi_device *adev, void *data)
{ {
struct fwnode_handle *function_node = acpi_fwnode_handle(adev); struct fwnode_handle *function_node = acpi_fwnode_handle(adev);
struct sdca_device_data *sdca_data = data; struct sdca_device_data *sdca_data = data;
struct sdw_slave *slave = container_of(sdca_data, struct sdw_slave, sdca_data);
struct device *dev = &adev->dev; struct device *dev = &adev->dev;
struct fwnode_handle *control5; /* used to identify function type */ struct fwnode_handle *control5; /* used to identify function type */
const char *function_name; const char *function_name;
@ -137,11 +138,13 @@ static int find_sdca_function(struct acpi_device *adev, void *data)
return ret; return ret;
} }
ret = patch_sdca_function_type(sdca_data->interface_revision, &function_type); if (!sdca_device_quirk_match(slave, SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING)) {
if (ret < 0) { ret = patch_sdca_function_type(sdca_data->interface_revision, &function_type);
dev_err(dev, "SDCA version %#x invalid function type %d\n", if (ret < 0) {
sdca_data->interface_revision, function_type); dev_err(dev, "SDCA version %#x invalid function type %d\n",
return ret; sdca_data->interface_revision, function_type);
return ret;
}
} }
function_name = get_sdca_function_name(function_type); function_name = get_sdca_function_name(function_type);

View File

@ -155,7 +155,7 @@ static irqreturn_t detected_mode_handler(int irq, void *data)
SDCA_CTL_SELECTED_MODE_NAME); SDCA_CTL_SELECTED_MODE_NAME);
if (!name) if (!name)
return -ENOMEM; return IRQ_NONE;
kctl = snd_soc_component_get_kcontrol(component, name); kctl = snd_soc_component_get_kcontrol(component, name);
if (!kctl) { if (!kctl) {

View File

@ -196,7 +196,7 @@ int sdca_regmap_mbq_size(struct sdca_function_data *function, unsigned int reg)
control = function_find_control(function, reg); control = function_find_control(function, reg);
if (!control) if (!control)
return false; return -EINVAL;
return clamp_val(control->nbits / BITS_PER_BYTE, sizeof(u8), sizeof(u32)); return clamp_val(control->nbits / BITS_PER_BYTE, sizeof(u8), sizeof(u32));
} }

View File

@ -316,9 +316,9 @@ static int imx_parse_ioremap_memory(struct snd_sof_dev *sdev)
} }
sdev->bar[blk_type] = devm_ioremap_resource(sdev->dev, res); sdev->bar[blk_type] = devm_ioremap_resource(sdev->dev, res);
if (!sdev->bar[blk_type]) if (IS_ERR(sdev->bar[blk_type]))
return dev_err_probe(sdev->dev, return dev_err_probe(sdev->dev,
-ENOMEM, PTR_ERR(sdev->bar[blk_type]),
"failed to ioremap %s region\n", "failed to ioremap %s region\n",
chip_info->memory[i].name); chip_info->memory[i].name);
} }

View File

@ -890,7 +890,7 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev)
if (num_capture >= SOF_HDA_CAPTURE_STREAMS) { if (num_capture >= SOF_HDA_CAPTURE_STREAMS) {
dev_err(sdev->dev, "error: too many capture streams %d\n", dev_err(sdev->dev, "error: too many capture streams %d\n",
num_playback); num_capture);
return -EINVAL; return -EINVAL;
} }

View File

@ -538,38 +538,33 @@ static void uaudio_iommu_unmap(enum mem_type mtype, unsigned long iova,
umap_size, iova, mapped_iova_size); umap_size, iova, mapped_iova_size);
} }
static int uaudio_iommu_map_prot(bool dma_coherent)
{
int prot = IOMMU_READ | IOMMU_WRITE;
if (dma_coherent)
prot |= IOMMU_CACHE;
return prot;
}
/** /**
* uaudio_iommu_map() - maps iommu memory for adsp * uaudio_iommu_map_pa() - maps iommu memory for adsp
* @mtype: ring type * @mtype: ring type
* @dma_coherent: dma coherent * @dma_coherent: dma coherent
* @pa: physical address for ring/buffer * @pa: physical address for ring/buffer
* @size: size of memory region * @size: size of memory region
* @sgt: sg table for memory region
* *
* Maps the XHCI related resources to a memory region that is assigned to be * Maps the XHCI related resources to a memory region that is assigned to be
* used by the adsp. This will be mapped to the domain, which is created by * used by the adsp. This will be mapped to the domain, which is created by
* the ASoC USB backend driver. * the ASoC USB backend driver.
* *
*/ */
static unsigned long uaudio_iommu_map(enum mem_type mtype, bool dma_coherent, static unsigned long uaudio_iommu_map_pa(enum mem_type mtype, bool dma_coherent,
phys_addr_t pa, size_t size, phys_addr_t pa, size_t size)
struct sg_table *sgt)
{ {
struct scatterlist *sg;
unsigned long iova = 0; unsigned long iova = 0;
size_t total_len = 0;
unsigned long iova_sg;
phys_addr_t pa_sg;
bool map = true; bool map = true;
size_t sg_len; int prot = uaudio_iommu_map_prot(dma_coherent);
int prot;
int ret;
int i;
prot = IOMMU_READ | IOMMU_WRITE;
if (dma_coherent)
prot |= IOMMU_CACHE;
switch (mtype) { switch (mtype) {
case MEM_EVENT_RING: case MEM_EVENT_RING:
@ -583,20 +578,41 @@ static unsigned long uaudio_iommu_map(enum mem_type mtype, bool dma_coherent,
&uaudio_qdev->xfer_ring_iova_size, &uaudio_qdev->xfer_ring_iova_size,
&uaudio_qdev->xfer_ring_list, size); &uaudio_qdev->xfer_ring_list, size);
break; break;
case MEM_XFER_BUF:
iova = uaudio_get_iova(&uaudio_qdev->curr_xfer_buf_iova,
&uaudio_qdev->xfer_buf_iova_size,
&uaudio_qdev->xfer_buf_list, size);
break;
default: default:
dev_err(uaudio_qdev->data->dev, "unknown mem type %d\n", mtype); dev_err(uaudio_qdev->data->dev, "unknown mem type %d\n", mtype);
} }
if (!iova || !map) if (!iova || !map)
goto done; return 0;
if (!sgt) iommu_map(uaudio_qdev->data->domain, iova, pa, size, prot, GFP_KERNEL);
goto skip_sgt_map;
return iova;
}
static unsigned long uaudio_iommu_map_xfer_buf(bool dma_coherent, size_t size,
struct sg_table *sgt)
{
struct scatterlist *sg;
unsigned long iova = 0;
size_t total_len = 0;
unsigned long iova_sg;
phys_addr_t pa_sg;
size_t sg_len;
int prot = uaudio_iommu_map_prot(dma_coherent);
int ret;
int i;
prot = IOMMU_READ | IOMMU_WRITE;
if (dma_coherent)
prot |= IOMMU_CACHE;
iova = uaudio_get_iova(&uaudio_qdev->curr_xfer_buf_iova,
&uaudio_qdev->xfer_buf_iova_size,
&uaudio_qdev->xfer_buf_list, size);
if (!iova)
goto done;
iova_sg = iova; iova_sg = iova;
for_each_sg(sgt->sgl, sg, sgt->nents, i) { for_each_sg(sgt->sgl, sg, sgt->nents, i) {
@ -618,11 +634,6 @@ static unsigned long uaudio_iommu_map(enum mem_type mtype, bool dma_coherent,
uaudio_iommu_unmap(MEM_XFER_BUF, iova, size, total_len); uaudio_iommu_unmap(MEM_XFER_BUF, iova, size, total_len);
iova = 0; iova = 0;
} }
return iova;
skip_sgt_map:
iommu_map(uaudio_qdev->data->domain, iova, pa, size, prot, GFP_KERNEL);
done: done:
return iova; return iova;
} }
@ -1020,7 +1031,6 @@ static int uaudio_transfer_buffer_setup(struct snd_usb_substream *subs,
struct sg_table xfer_buf_sgt; struct sg_table xfer_buf_sgt;
dma_addr_t xfer_buf_dma; dma_addr_t xfer_buf_dma;
void *xfer_buf; void *xfer_buf;
phys_addr_t xfer_buf_pa;
u32 len = xfer_buf_len; u32 len = xfer_buf_len;
bool dma_coherent; bool dma_coherent;
dma_addr_t xfer_buf_dma_sysdev; dma_addr_t xfer_buf_dma_sysdev;
@ -1051,18 +1061,12 @@ static int uaudio_transfer_buffer_setup(struct snd_usb_substream *subs,
if (!xfer_buf) if (!xfer_buf)
return -ENOMEM; return -ENOMEM;
/* Remapping is not possible if xfer_buf is outside of linear map */
xfer_buf_pa = virt_to_phys(xfer_buf);
if (WARN_ON(!page_is_ram(PFN_DOWN(xfer_buf_pa)))) {
ret = -ENXIO;
goto unmap_sync;
}
dma_get_sgtable(subs->dev->bus->sysdev, &xfer_buf_sgt, xfer_buf, dma_get_sgtable(subs->dev->bus->sysdev, &xfer_buf_sgt, xfer_buf,
xfer_buf_dma, len); xfer_buf_dma, len);
/* map the physical buffer into sysdev as well */ /* map the physical buffer into sysdev as well */
xfer_buf_dma_sysdev = uaudio_iommu_map(MEM_XFER_BUF, dma_coherent, xfer_buf_dma_sysdev = uaudio_iommu_map_xfer_buf(dma_coherent,
xfer_buf_pa, len, &xfer_buf_sgt); len, &xfer_buf_sgt);
if (!xfer_buf_dma_sysdev) { if (!xfer_buf_dma_sysdev) {
ret = -ENOMEM; ret = -ENOMEM;
goto unmap_sync; goto unmap_sync;
@ -1143,8 +1147,8 @@ uaudio_endpoint_setup(struct snd_usb_substream *subs,
sg_free_table(sgt); sg_free_table(sgt);
/* data transfer ring */ /* data transfer ring */
iova = uaudio_iommu_map(MEM_XFER_RING, dma_coherent, tr_pa, iova = uaudio_iommu_map_pa(MEM_XFER_RING, dma_coherent, tr_pa,
PAGE_SIZE, NULL); PAGE_SIZE);
if (!iova) { if (!iova) {
ret = -ENOMEM; ret = -ENOMEM;
goto clear_pa; goto clear_pa;
@ -1207,8 +1211,8 @@ static int uaudio_event_ring_setup(struct snd_usb_substream *subs,
mem_info->dma = sg_dma_address(sgt->sgl); mem_info->dma = sg_dma_address(sgt->sgl);
sg_free_table(sgt); sg_free_table(sgt);
iova = uaudio_iommu_map(MEM_EVENT_RING, dma_coherent, er_pa, iova = uaudio_iommu_map_pa(MEM_EVENT_RING, dma_coherent, er_pa,
PAGE_SIZE, NULL); PAGE_SIZE);
if (!iova) { if (!iova) {
ret = -ENOMEM; ret = -ENOMEM;
goto clear_pa; goto clear_pa;