Merge branch 'for-linus' into for-next

Pull 6.17-devel branch for applying further changes cleanly.

Signed-off-by: Taksahi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai
2025-09-28 08:34:58 +02:00
35 changed files with 294 additions and 134 deletions

View File

@@ -2293,7 +2293,7 @@ delayed_register
notice the need.
skip_validation
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
can check its details.
quirk_flags

View File

@@ -46,6 +46,7 @@ struct sdca_device_data {
enum sdca_quirk {
SDCA_QUIRKS_RT712_VB,
SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING,
};
#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
* @hid: HID device structure
* @hidtx_ids: HIDTx Report ID
* @num_hidtx_ids: number of HIDTx Report ID
* @hidrx_ids: HIDRx Report ID
* @num_hidrx_ids: number of HIDRx Report ID
* @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
* @af_number_list: which Audio Function Numbers within this Device are sending/receiving the messages in this HIDE
* @hid_desc: HID descriptor for the HIDE Entity
* @hidtx_ids: HIDTx Report ID
* @hidrx_ids: HIDRx Report ID
* @af_number_list: which Audio Function Numbers within this Device are
* 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_desc: HID descriptor for the HIDE Entity
*/
struct sdca_entity_hide {
struct hid_device *hid;
unsigned int *hidtx_ids;
int num_hidtx_ids;
unsigned int *hidrx_ids;
int num_hidtx_ids;
int num_hidrx_ids;
unsigned int af_number_list[SDCA_MAX_FUNCTION_COUNT];
unsigned int hide_reside_function_num;
unsigned int max_delay;
unsigned int af_number_list[SDCA_MAX_FUNCTION_COUNT];
struct hid_descriptor hid_desc;
unsigned char *hid_report_desc;
struct hid_descriptor hid_desc;
};
/**

View File

@@ -3700,6 +3700,7 @@ enum {
ALC236_FIXUP_DELL_DUAL_CODECS,
ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
ALC287_FIXUP_TAS2781_I2C,
ALC295_FIXUP_DELL_TAS2781_I2C,
ALC245_FIXUP_TAS2781_SPI_2,
ALC287_FIXUP_TXNW2781_I2C,
ALC287_FIXUP_YOGA7_14ARB7_I2C,
@@ -5165,6 +5166,12 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.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] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
@@ -6287,8 +6294,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, 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, 0x0c94, "Dell Polaris 3 metal", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x1028, 0x0c96, "Dell Polaris 2in1", 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", 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, 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),
@@ -6467,6 +6474,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, 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, 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, 0x89a6, "HP ProBook 450 G9", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED),
@@ -6477,6 +6485,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x89da, "HP Spectre x360 14t-ea100", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
SND_PCI_QUIRK(0x103c, 0x89e7, "HP Elite x2 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
@@ -7069,8 +7078,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, 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, 0x38c7, "Thinkbook 13x Gen 4", ALC287_FIXUP_CS35L41_I2C_4),
SND_PCI_QUIRK(0x17aa, 0x38c8, "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_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
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, 0x38d2, "Lenovo Yoga 9 14IMH9", ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN),
@@ -7091,6 +7100,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, 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, 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, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
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 },
{ "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 },
{ "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", "17AA38F9", 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");
/*
* 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)
{
struct calidata *cali_data = &p->cali_data;
@@ -103,8 +120,7 @@ static void tas2781_apply_calib(struct tasdevice_priv *p)
data[l] = k;
oft++;
for (i = 0; i < TASDEV_CALIB_N * 4; i++)
data[l + i + 1] = data[4 * oft + i];
cali_cnv(data, 4 * oft, l);
k++;
}
}
@@ -130,9 +146,8 @@ static void tas2781_apply_calib(struct tasdevice_priv *p)
for (j = p->ndev - 1; j >= 0; j--) {
l = j * (cali_data->cali_dat_sz_per_dev + 1);
for (i = TASDEV_CALIB_N * 4; i > 0 ; i--)
data[l + i] = data[p->index * 5 + i];
data[l+i] = j;
cali_cnv(data, cali_data->cali_dat_sz_per_dev * j, l);
data[l] = j;
}
}
@@ -178,6 +193,11 @@ int tas2781_save_calibration(struct tas2781_hda *hda)
efi_status_t status;
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)
efi_guid = tasdev_fct_efi_guid[hda->catlog_id];

View File

@@ -317,6 +317,11 @@ static int tas2563_save_calibration(struct tas2781_hda *h)
unsigned int attr;
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;
/* 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;
handle = ACPI_HANDLE(&pci->dev);
if (!handle)
return -ENODEV;
ret = sdw_intel_acpi_scan(handle, &info);
if (ret < 0)

View File

@@ -73,7 +73,7 @@ static int acp_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt)
{
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;
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 lrclk_div_val, bclk_div_val;
chip = dev_get_platdata(dev);
chip = dev_get_drvdata(dev->parent);
rsrc = chip->rsrc;
/* 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 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;
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)
{
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_stream *stream = substream->runtime->private_data;
u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0;
u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl;
unsigned int dir = substream->stream;
chip = dev_get_platdata(dev);
switch (dai->driver->id) {
case I2S_SP_INSTANCE:
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 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;
unsigned int dir = substream->stream;
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),
},
{
.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_DEC_64 0x2
#define PDM_CLK_FREQ_MASK 0x07
#define PDM_MISC_CTRL_MASK 0x10
#define PDM_MISC_CTRL_MASK 0x18
#define PDM_ENABLE 0x01
#define PDM_DISABLE 0x00
#define DMA_EN_MASK 0x02

View File

@@ -618,6 +618,7 @@ static struct interp_sample_rate sr_val_tbl[] = {
{176400, 0xB}, {352800, 0xC},
};
/* Matches also rx_macro_mux_text */
enum {
RX_MACRO_AIF1_PB,
RX_MACRO_AIF2_PB,
@@ -722,6 +723,7 @@ static const char * const rx_int2_2_interp_mux_text[] = {
"ZERO", "RX INT2_2 MUX",
};
/* Order must match RX_MACRO_MAX_DAIS enum (offset by 1) */
static const char *const rx_macro_mux_text[] = {
"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 snd_soc_dapm_update *update = NULL;
u32 rx_port_value = ucontrol->value.enumerated.item[0];
unsigned int dai_id;
u32 aif_rst;
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) {
case 0:
if (rx->active_ch_cnt[aif_rst]) {
clear_bit(widget->shift,
&rx->active_ch_mask[aif_rst]);
rx->active_ch_cnt[aif_rst]--;
/*
* active_ch_cnt and active_ch_mask use DAI IDs (RX_MACRO_MAX_DAIS).
* active_ch_cnt == 0 was tested in if() above.
*/
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;
case 1:
case 2:
case 3:
case 4:
set_bit(widget->shift,
&rx->active_ch_mask[rx_port_value]);
rx->active_ch_cnt[rx_port_value]++;
/* active_ch_cnt and active_ch_mask use DAI IDs (WSA_MACRO_MAX_DAIS). */
dai_id = rx_port_value - 1;
set_bit(widget->shift, &rx->active_ch_mask[dai_id]);
rx->active_ch_cnt[dai_id]++;
break;
default:
dev_err(component->dev,

View File

@@ -368,6 +368,7 @@ static struct interp_sample_rate int_mix_sample_rate_val[] = {
{192000, 0x6}, /* 192K */
};
/* Matches also rx_mux_text */
enum {
WSA_MACRO_AIF1_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"
};
/* Order must match WSA_MACRO_MAX_DAIS enum (offset by 1) */
static const char *const rx_mux_text[] = {
"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 bit_input;
u32 aif_rst;
unsigned int dai_id;
struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
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) {
case 0:
if (wsa->active_ch_cnt[aif_rst]) {
clear_bit(bit_input,
&wsa->active_ch_mask[aif_rst]);
wsa->active_ch_cnt[aif_rst]--;
/*
* active_ch_cnt and active_ch_mask use DAI IDs (WSA_MACRO_MAX_DAIS).
* active_ch_cnt == 0 was tested in if() above.
*/
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;
case 1:
case 2:
set_bit(bit_input,
&wsa->active_ch_mask[rx_port_value]);
wsa->active_ch_cnt[rx_port_value]++;
/* active_ch_cnt and active_ch_mask use DAI IDs (WSA_MACRO_MAX_DAIS). */
dai_id = rx_port_value - 1;
set_bit(bit_input, &wsa->active_ch_mask[dai_id]);
wsa->active_ch_cnt[dai_id]++;
break;
default:
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) {
case SAR_PWR_SAVING:
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,
RT5682S_MB1_PATH_MASK | RT5682S_MB2_PATH_MASK,
RT5682S_CTRL_MB1_REG | RT5682S_CTRL_MB2_REG);
RT5682S_MB1_PATH_MASK | RT5682S_MB2_PATH_MASK |
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,
RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK |
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);
snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1,
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,
RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK |
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;
default:
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,
RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK |
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;
snd_soc_component_write(component, RT5682S_SAR_IL_CMD_3, 0x024c);
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,
RT5682S_SAR_SEL_MB1_2_MASK, val << RT5682S_SAR_SEL_MB1_2_SFT);
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_POL_FAST_OFF_MASK | RT5682S_MIC_CAP_MASK,
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,
RT5682S_SAR_POW_MASK, RT5682S_SAR_POW_EN);
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);
} else {
if (!rt712->dmic_function_found) {
dev_err(&slave->dev, "%s RT712 VB detected but no SMART_MIC function exposed in ACPI\n",
if (!rt712->dmic_function_found)
dev_warn(&slave->dev, "%s RT712 VB detected but no SMART_MIC function exposed in ACPI\n",
__func__);
goto suspend;
}
/* multilanes and DMIC are supported by rt712vb */
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.num_mode = data[sma1307->set.header_size - 1];
num_mode = sma1307->set.num_mode;
sma1307->set.header = devm_kzalloc(sma1307->dev,
sma1307->set.header_size,
GFP_KERNEL);
sma1307->set.header = devm_kmalloc_array(sma1307->dev,
sma1307->set.header_size,
sizeof(int),
GFP_KERNEL);
if (!sma1307->set.header) {
sma1307->set.status = false;
return;

View File

@@ -220,7 +220,7 @@ static const struct snd_kcontrol_new wm8940_snd_controls[] = {
SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL,
0, 255, 0, wm8940_adc_tlv),
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),
SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL,
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);
if (f != priv->mclk) {
/* 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);

View File

@@ -419,10 +419,14 @@ static int wm8974_update_clocks(struct snd_soc_dai *dai)
fs256 = 256 * priv->fs;
f = wm8974_get_mclkdiv(priv->mclk, fs256, &mclkdiv);
if (f != priv->mclk) {
/* 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);

View File

@@ -761,7 +761,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
.callback = sof_sdw_quirk_cb,
.matches = {
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 |
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 */
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);

View File

@@ -568,8 +568,9 @@ static const struct snd_pcm_hardware catpt_pcm_hardware = {
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
.period_bytes_min = PAGE_SIZE,
.period_bytes_max = CATPT_BUFFER_MAX_SIZE / 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_max = 2,
.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 = {
.stream_name = "Analog Capture",
.channels_min = 2,
.channels_max = 4,
.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_max = 2,
.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_max = 2,
.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_max = 2,
.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_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);

View File

@@ -1022,6 +1022,7 @@ static int audioreach_i2s_set_media_format(struct q6apm_graph *graph,
param_data->param_id = PARAM_ID_I2S_INTF_CFG;
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.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;
err:
q6apm_graph_close(dai_data->graph[dai->id]);
dai_data->graph[dai->id] = NULL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
q6apm_graph_close(dai_data->graph[dai->id]);
dai_data->graph[dai->id] = NULL;
}
return rc;
}
@@ -260,6 +262,7 @@ static const struct snd_soc_dai_ops q6i2s_ops = {
.shutdown = q6apm_lpass_dai_shutdown,
.set_channel_map = q6dma_set_channel_map,
.hw_params = q6dma_hw_params,
.set_fmt = q6i2s_set_fmt,
};
static const struct snd_soc_dai_ops q6hdmi_ops = {

View File

@@ -33,6 +33,10 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
int dp_pcm_id = 0;
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_1:
/*
@@ -189,7 +193,7 @@ static int sc8280xp_platform_probe(struct platform_device *pdev)
static const struct of_device_id snd_sc8280xp_dt_match[] = {
{.compatible = "qcom,qcm6490-idp-sndcard", "qcm6490"},
{.compatible = "qcom,qcs6490-rb3gen2-sndcard", "qcs6490"},
{.compatible = "qcom,qcs8275-sndcard", "qcs8275"},
{.compatible = "qcom,qcs8275-sndcard", "qcs8300"},
{.compatible = "qcom,qcs9075-sndcard", "qcs9075"},
{.compatible = "qcom,qcs9100-sndcard", "qcs9100"},
{.compatible = "qcom,sc8280xp-sndcard", "sc8280xp"},

View File

@@ -7,6 +7,7 @@
*/
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/soundwire/sdw.h>
@@ -55,11 +56,30 @@ static bool sdca_device_quirk_rt712_vb(struct sdw_slave *slave)
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)
{
switch (quirk) {
case SDCA_QUIRKS_RT712_VB:
return sdca_device_quirk_rt712_vb(slave);
case SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING:
return sdca_device_quirk_skip_func_type_patching(slave);
default:
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 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 fwnode_handle *control5; /* used to identify function type */
const char *function_name;
@@ -137,11 +138,13 @@ static int find_sdca_function(struct acpi_device *adev, void *data)
return ret;
}
ret = patch_sdca_function_type(sdca_data->interface_revision, &function_type);
if (ret < 0) {
dev_err(dev, "SDCA version %#x invalid function type %d\n",
sdca_data->interface_revision, function_type);
return ret;
if (!sdca_device_quirk_match(slave, SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING)) {
ret = patch_sdca_function_type(sdca_data->interface_revision, &function_type);
if (ret < 0) {
dev_err(dev, "SDCA version %#x invalid function type %d\n",
sdca_data->interface_revision, function_type);
return ret;
}
}
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);
if (!name)
return -ENOMEM;
return IRQ_NONE;
kctl = snd_soc_component_get_kcontrol(component, name);
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);
if (!control)
return false;
return -EINVAL;
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);
if (!sdev->bar[blk_type])
if (IS_ERR(sdev->bar[blk_type]))
return dev_err_probe(sdev->dev,
-ENOMEM,
PTR_ERR(sdev->bar[blk_type]),
"failed to ioremap %s region\n",
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) {
dev_err(sdev->dev, "error: too many capture streams %d\n",
num_playback);
num_capture);
return -EINVAL;
}

View File

@@ -1511,15 +1511,14 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi)
{
int i;
if (!umidi->disconnected)
snd_usbmidi_disconnect(&umidi->list);
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i];
if (ep->out)
snd_usbmidi_out_endpoint_delete(ep->out);
if (ep->in)
snd_usbmidi_in_endpoint_delete(ep->in);
kfree(ep->out);
}
mutex_destroy(&umidi->mutex);
timer_shutdown_sync(&umidi->error_timer);
kfree(umidi);
}

View File

@@ -93,6 +93,7 @@ struct s1810c_ctl_packet {
#define SC1810C_CTL_LINE_SW 0
#define SC1810C_CTL_MUTE_SW 1
#define SC1824C_CTL_MONO_SW 2
#define SC1810C_CTL_AB_SW 3
#define SC1810C_CTL_48V_SW 4
@@ -123,6 +124,7 @@ struct s1810c_state_packet {
#define SC1810C_STATE_48V_SW 58
#define SC1810C_STATE_LINE_SW 59
#define SC1810C_STATE_MUTE_SW 60
#define SC1824C_STATE_MONO_SW 61
#define SC1810C_STATE_AB_SW 62
struct s1810_mixer_state {
@@ -493,6 +495,15 @@ static const struct snd_kcontrol_new snd_s1810c_mute_sw = {
.private_value = (SC1810C_STATE_MUTE_SW | SC1810C_CTL_MUTE_SW << 8)
};
static const struct snd_kcontrol_new snd_s1824c_mono_sw = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Mono Main Out Switch",
.info = snd_ctl_boolean_mono_info,
.get = snd_s1810c_switch_get,
.put = snd_s1810c_switch_set,
.private_value = (SC1824C_STATE_MONO_SW | SC1824C_CTL_MONO_SW << 8)
};
static const struct snd_kcontrol_new snd_s1810c_48v_sw = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "48V Phantom Power On Mic Inputs Switch",
@@ -579,8 +590,17 @@ int snd_sc1810_init_mixer(struct usb_mixer_interface *mixer)
if (ret < 0)
return ret;
ret = snd_s1810c_switch_init(mixer, &snd_s1810c_ab_sw);
if (ret < 0)
return ret;
// The 1824c has a Mono Main switch instead of a
// A/B select switch.
if (mixer->chip->usb_id == USB_ID(0x194f, 0x010d)) {
ret = snd_s1810c_switch_init(mixer, &snd_s1824c_mono_sw);
if (ret < 0)
return ret;
} else if (mixer->chip->usb_id == USB_ID(0x194f, 0x010c)) {
ret = snd_s1810c_switch_init(mixer, &snd_s1810c_ab_sw);
if (ret < 0)
return ret;
}
return ret;
}

View File

@@ -538,38 +538,33 @@ static void uaudio_iommu_unmap(enum mem_type mtype, unsigned long iova,
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
* @dma_coherent: dma coherent
* @pa: physical address for ring/buffer
* @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
* used by the adsp. This will be mapped to the domain, which is created by
* the ASoC USB backend driver.
*
*/
static unsigned long uaudio_iommu_map(enum mem_type mtype, bool dma_coherent,
phys_addr_t pa, size_t size,
struct sg_table *sgt)
static unsigned long uaudio_iommu_map_pa(enum mem_type mtype, bool dma_coherent,
phys_addr_t pa, size_t size)
{
struct scatterlist *sg;
unsigned long iova = 0;
size_t total_len = 0;
unsigned long iova_sg;
phys_addr_t pa_sg;
bool map = true;
size_t sg_len;
int prot;
int ret;
int i;
prot = IOMMU_READ | IOMMU_WRITE;
if (dma_coherent)
prot |= IOMMU_CACHE;
int prot = uaudio_iommu_map_prot(dma_coherent);
switch (mtype) {
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_list, size);
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:
dev_err(uaudio_qdev->data->dev, "unknown mem type %d\n", mtype);
}
if (!iova || !map)
goto done;
return 0;
if (!sgt)
goto skip_sgt_map;
iommu_map(uaudio_qdev->data->domain, iova, pa, size, prot, GFP_KERNEL);
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;
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);
iova = 0;
}
return iova;
skip_sgt_map:
iommu_map(uaudio_qdev->data->domain, iova, pa, size, prot, GFP_KERNEL);
done:
return iova;
}
@@ -1012,7 +1023,6 @@ static int uaudio_transfer_buffer_setup(struct snd_usb_substream *subs,
struct sg_table xfer_buf_sgt;
dma_addr_t xfer_buf_dma;
void *xfer_buf;
phys_addr_t xfer_buf_pa;
u32 len = xfer_buf_len;
bool dma_coherent;
dma_addr_t xfer_buf_dma_sysdev;
@@ -1043,18 +1053,12 @@ static int uaudio_transfer_buffer_setup(struct snd_usb_substream *subs,
if (!xfer_buf)
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,
xfer_buf_dma, len);
/* map the physical buffer into sysdev as well */
xfer_buf_dma_sysdev = uaudio_iommu_map(MEM_XFER_BUF, dma_coherent,
xfer_buf_pa, len, &xfer_buf_sgt);
xfer_buf_dma_sysdev = uaudio_iommu_map_xfer_buf(dma_coherent,
len, &xfer_buf_sgt);
if (!xfer_buf_dma_sysdev) {
ret = -ENOMEM;
goto unmap_sync;
@@ -1135,8 +1139,8 @@ uaudio_endpoint_setup(struct snd_usb_substream *subs,
sg_free_table(sgt);
/* data transfer ring */
iova = uaudio_iommu_map(MEM_XFER_RING, dma_coherent, tr_pa,
PAGE_SIZE, NULL);
iova = uaudio_iommu_map_pa(MEM_XFER_RING, dma_coherent, tr_pa,
PAGE_SIZE);
if (!iova) {
ret = -ENOMEM;
goto clear_pa;
@@ -1199,8 +1203,8 @@ static int uaudio_event_ring_setup(struct snd_usb_substream *subs,
mem_info->dma = sg_dma_address(sgt->sgl);
sg_free_table(sgt);
iova = uaudio_iommu_map(MEM_EVENT_RING, dma_coherent, er_pa,
PAGE_SIZE, NULL);
iova = uaudio_iommu_map_pa(MEM_EVENT_RING, dma_coherent, er_pa,
PAGE_SIZE);
if (!iova) {
ret = -ENOMEM;
goto clear_pa;

View File

@@ -1599,9 +1599,6 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
/* presonus studio 1810c: skip altsets incompatible with device_setup */
if (chip->usb_id == USB_ID(0x194f, 0x010c))
return s1810c_skip_setting_quirk(chip, iface, altno);
/* presonus studio 1824c: skip altsets incompatible with device_setup */
if (chip->usb_id == USB_ID(0x194f, 0x010d))
return s1810c_skip_setting_quirk(chip, iface, altno);
return 0;
}