Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' into for-next

Back-merge of 6.3 devel branch for further changes of PCM and
documentation.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

+281 -105
+2
sound/core/pcm_lib.c
··· 2155 2155 ret = substream->ops->ack(substream); 2156 2156 if (ret < 0) { 2157 2157 runtime->control->appl_ptr = old_appl_ptr; 2158 + if (ret == -EPIPE) 2159 + __snd_pcm_xrun(substream); 2158 2160 return ret; 2159 2161 } 2160 2162 }
+9
sound/hda/intel-dsp-config.c
··· 472 472 }, 473 473 #endif 474 474 475 + /* Meteor Lake */ 476 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_METEORLAKE) 477 + /* Meteorlake-P */ 478 + { 479 + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, 480 + .device = 0x7e28, 481 + }, 482 + #endif 483 + 475 484 }; 476 485 477 486 static const struct config_entry *snd_intel_dsp_find_config
+1 -1
sound/pci/asihpi/hpi6205.c
··· 430 430 pao = hpi_find_adapter(phm->adapter_index); 431 431 } else { 432 432 /* subsys messages don't address an adapter */ 433 - _HPI_6205(NULL, phm, phr); 433 + phr->error = HPI_ERROR_INVALID_OBJ_INDEX; 434 434 return; 435 435 } 436 436
+3 -2
sound/pci/hda/hda_intel.c
··· 328 328 #define needs_eld_notify_link(chip) false 329 329 #endif 330 330 331 - #define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \ 331 + #define CONTROLLER_IN_GPU(pci) (((pci)->vendor == 0x8086) && \ 332 + (((pci)->device == 0x0a0c) || \ 332 333 ((pci)->device == 0x0c0c) || \ 333 334 ((pci)->device == 0x0d0c) || \ 334 335 ((pci)->device == 0x160c) || \ 335 336 ((pci)->device == 0x490d) || \ 336 337 ((pci)->device == 0x4f90) || \ 337 338 ((pci)->device == 0x4f91) || \ 338 - ((pci)->device == 0x4f92)) 339 + ((pci)->device == 0x4f92))) 339 340 340 341 #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) 341 342
+3 -1
sound/pci/hda/patch_ca0132.c
··· 4228 4228 4229 4229 for (i = 0; i < TUNING_CTLS_COUNT; i++) 4230 4230 if (nid == ca0132_tuning_ctls[i].nid) 4231 - break; 4231 + goto found; 4232 4232 4233 + return -EINVAL; 4234 + found: 4233 4235 snd_hda_power_up(codec); 4234 4236 dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20, 4235 4237 ca0132_tuning_ctls[i].req,
+5 -1
sound/pci/hda/patch_conexant.c
··· 980 980 SND_PCI_QUIRK(0x17aa, 0x3905, "Lenovo G50-30", CXT_FIXUP_STEREO_DMIC), 981 981 SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC), 982 982 SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), 983 - SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_PINCFG_LENOVO_NOTEBOOK), 983 + /* NOTE: we'd need to extend the quirk for 17aa:3977 as the same 984 + * PCI SSID is used on multiple Lenovo models 985 + */ 986 + SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), 984 987 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo G50-70", CXT_FIXUP_STEREO_DMIC), 985 988 SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), 986 989 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI), ··· 1006 1003 { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" }, 1007 1004 { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" }, 1008 1005 { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, 1006 + { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, 1009 1007 {} 1010 1008 }; 1011 1009
+7 -1
sound/pci/hda/patch_realtek.c
··· 2631 2631 SND_PCI_QUIRK(0x1558, 0x65e5, "Clevo PC50D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS), 2632 2632 SND_PCI_QUIRK(0x1558, 0x65f1, "Clevo PC50HS", ALC1220_FIXUP_CLEVO_PB51ED_PINS), 2633 2633 SND_PCI_QUIRK(0x1558, 0x65f5, "Clevo PD50PN[NRT]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), 2634 + SND_PCI_QUIRK(0x1558, 0x66a2, "Clevo PE60RNE", ALC1220_FIXUP_CLEVO_PB51ED_PINS), 2634 2635 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), 2635 2636 SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), 2636 2637 SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS), ··· 2652 2651 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950), 2653 2652 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950), 2654 2653 SND_PCI_QUIRK(0x1558, 0x97e2, "Clevo P970RC-M", ALC1220_FIXUP_CLEVO_P950), 2654 + SND_PCI_QUIRK(0x1558, 0xd502, "Clevo PD50SNE", ALC1220_FIXUP_CLEVO_PB51ED_PINS), 2655 2655 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), 2656 2656 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), 2657 2657 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), ··· 9262 9260 SND_PCI_QUIRK(0x1028, 0x0a62, "Dell Precision 5560", ALC289_FIXUP_DUAL_SPK), 9263 9261 SND_PCI_QUIRK(0x1028, 0x0a9d, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), 9264 9262 SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), 9265 - SND_PCI_QUIRK(0x1028, 0x0ac9, "Dell Precision 3260", ALC295_FIXUP_CHROME_BOOK), 9263 + SND_PCI_QUIRK(0x1028, 0x0ac9, "Dell Precision 3260", ALC283_FIXUP_CHROME_BOOK), 9266 9264 SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK), 9267 9265 SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK), 9268 9266 SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS), ··· 9449 9447 SND_PCI_QUIRK(0x103c, 0x8b8a, "HP", ALC236_FIXUP_HP_GPIO_LED), 9450 9448 SND_PCI_QUIRK(0x103c, 0x8b8b, "HP", ALC236_FIXUP_HP_GPIO_LED), 9451 9449 SND_PCI_QUIRK(0x103c, 0x8b8d, "HP", ALC236_FIXUP_HP_GPIO_LED), 9450 + SND_PCI_QUIRK(0x103c, 0x8b8f, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), 9452 9451 SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), 9453 9452 SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED), 9454 9453 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), ··· 9542 9539 SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP), 9543 9540 SND_PCI_QUIRK(0x144d, 0xc832, "Samsung Galaxy Book Flex Alpha (NP730QCJ)", ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), 9544 9541 SND_PCI_QUIRK(0x144d, 0xca03, "Samsung Galaxy Book2 Pro 360 (NP930QED)", ALC298_FIXUP_SAMSUNG_AMP), 9542 + SND_PCI_QUIRK(0x144d, 0xc868, "Samsung Galaxy Book2 Pro (NP930XED)", ALC298_FIXUP_SAMSUNG_AMP), 9545 9543 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), 9546 9544 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), 9547 9545 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), ··· 9577 9573 SND_PCI_QUIRK(0x1558, 0x5101, "Clevo S510WU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9578 9574 SND_PCI_QUIRK(0x1558, 0x5157, "Clevo W517GU1", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9579 9575 SND_PCI_QUIRK(0x1558, 0x51a1, "Clevo NS50MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9576 + SND_PCI_QUIRK(0x1558, 0x5630, "Clevo NP50RNJS", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9580 9577 SND_PCI_QUIRK(0x1558, 0x70a1, "Clevo NB70T[HJK]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9581 9578 SND_PCI_QUIRK(0x1558, 0x70b3, "Clevo NK70SB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9582 9579 SND_PCI_QUIRK(0x1558, 0x70f2, "Clevo NH79EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), ··· 9612 9607 SND_PCI_QUIRK(0x1558, 0x971d, "Clevo N970T[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9613 9608 SND_PCI_QUIRK(0x1558, 0xa500, "Clevo NL5[03]RU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9614 9609 SND_PCI_QUIRK(0x1558, 0xa600, "Clevo NL50NU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9610 + SND_PCI_QUIRK(0x1558, 0xa671, "Clevo NP70SN[CDE]", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9615 9611 SND_PCI_QUIRK(0x1558, 0xb018, "Clevo NP50D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9616 9612 SND_PCI_QUIRK(0x1558, 0xb019, "Clevo NH77D[BE]Q", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), 9617 9613 SND_PCI_QUIRK(0x1558, 0xb022, "Clevo NH77D[DC][QW]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+2
sound/soc/codecs/da7219-aad.c
··· 968 968 INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work); 969 969 INIT_WORK(&da7219_aad->jack_det_work, da7219_aad_jack_det_work); 970 970 971 + mutex_init(&da7219_aad->jack_det_mutex); 972 + 971 973 ret = request_threaded_irq(da7219_aad->irq, da7219_aad_pre_irq_thread, 972 974 da7219_aad_irq_thread, 973 975 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+11
sound/soc/codecs/hdmi-codec.c
··· 428 428 { 429 429 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); 430 430 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 431 + bool has_capture = !hcp->hcd.no_i2s_capture; 432 + bool has_playback = !hcp->hcd.no_i2s_playback; 431 433 int ret = 0; 434 + 435 + if (!((has_playback && tx) || (has_capture && !tx))) 436 + return 0; 432 437 433 438 mutex_lock(&hcp->lock); 434 439 if (hcp->busy) { ··· 473 468 struct snd_soc_dai *dai) 474 469 { 475 470 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); 471 + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 472 + bool has_capture = !hcp->hcd.no_i2s_capture; 473 + bool has_playback = !hcp->hcd.no_i2s_playback; 474 + 475 + if (!((has_playback && tx) || (has_capture && !tx))) 476 + return; 476 477 477 478 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; 478 479 hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
+6 -5
sound/soc/codecs/lpass-tx-macro.c
··· 242 242 243 243 struct tx_mute_work { 244 244 struct tx_macro *tx; 245 - u32 decimator; 245 + u8 decimator; 246 246 struct delayed_work dwork; 247 247 }; 248 248 ··· 635 635 return 0; 636 636 } 637 637 638 - static bool is_amic_enabled(struct snd_soc_component *component, int decimator) 638 + static bool is_amic_enabled(struct snd_soc_component *component, u8 decimator) 639 639 { 640 640 u16 adc_mux_reg, adc_reg, adc_n; 641 641 ··· 849 849 struct snd_kcontrol *kcontrol, int event) 850 850 { 851 851 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 852 - unsigned int decimator; 852 + u8 decimator; 853 853 u16 tx_vol_ctl_reg, dec_cfg_reg, hpf_gate_reg, tx_gain_ctl_reg; 854 854 u8 hpf_cut_off_freq; 855 855 int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS; ··· 1064 1064 struct snd_soc_dai *dai) 1065 1065 { 1066 1066 struct snd_soc_component *component = dai->component; 1067 - u32 decimator, sample_rate; 1067 + u32 sample_rate; 1068 + u8 decimator; 1068 1069 int tx_fs_rate; 1069 1070 struct tx_macro *tx = snd_soc_component_get_drvdata(component); 1070 1071 ··· 1129 1128 { 1130 1129 struct snd_soc_component *component = dai->component; 1131 1130 struct tx_macro *tx = snd_soc_component_get_drvdata(component); 1132 - u16 decimator; 1131 + u8 decimator; 1133 1132 1134 1133 /* active decimator not set yet */ 1135 1134 if (tx->active_decimator[dai->id] == -1)
+4
sound/soc/fsl/Kconfig
··· 294 294 Say Y if you want to add support for SoC audio on an i.MX board with 295 295 a sgtl5000 codec. 296 296 297 + Note that this is an old driver. Consider enabling 298 + SND_SOC_FSL_ASOC_CARD and SND_SOC_SGTL5000 to use the newer 299 + driver. 300 + 297 301 config SND_SOC_IMX_SPDIF 298 302 tristate "SoC Audio support for i.MX boards with S/PDIF" 299 303 select SND_SOC_IMX_PCM_DMA
+21
sound/soc/intel/avs/boards/da7219.c
··· 117 117 snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); 118 118 } 119 119 120 + static int 121 + avs_da7219_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_params *params) 122 + { 123 + struct snd_interval *rate, *channels; 124 + struct snd_mask *fmt; 125 + 126 + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 127 + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 128 + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 129 + 130 + /* The ADSP will convert the FE rate to 48k, stereo */ 131 + rate->min = rate->max = 48000; 132 + channels->min = channels->max = 2; 133 + 134 + /* set SSP0 to 24 bit */ 135 + snd_mask_none(fmt); 136 + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); 137 + return 0; 138 + } 139 + 120 140 static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, 121 141 struct snd_soc_dai_link **dai_link) 122 142 { ··· 168 148 dl->num_platforms = 1; 169 149 dl->id = 0; 170 150 dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; 151 + dl->be_hw_params_fixup = avs_da7219_be_fixup; 171 152 dl->init = avs_da7219_codec_init; 172 153 dl->exit = avs_da7219_codec_exit; 173 154 dl->nonatomic = 1;
+22
sound/soc/intel/avs/boards/max98357a.c
··· 8 8 9 9 #include <linux/module.h> 10 10 #include <linux/platform_device.h> 11 + #include <sound/pcm_params.h> 11 12 #include <sound/soc.h> 12 13 #include <sound/soc-acpi.h> 13 14 #include <sound/soc-dapm.h> ··· 24 23 static const struct snd_soc_dapm_route card_base_routes[] = { 25 24 { "Spk", NULL, "Speaker" }, 26 25 }; 26 + 27 + static int 28 + avs_max98357a_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_params *params) 29 + { 30 + struct snd_interval *rate, *channels; 31 + struct snd_mask *fmt; 32 + 33 + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 34 + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 35 + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 36 + 37 + /* The ADSP will convert the FE rate to 48k, stereo */ 38 + rate->min = rate->max = 48000; 39 + channels->min = channels->max = 2; 40 + 41 + /* set SSP0 to 16 bit */ 42 + snd_mask_none(fmt); 43 + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); 44 + return 0; 45 + } 27 46 28 47 static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, 29 48 struct snd_soc_dai_link **dai_link) ··· 76 55 dl->num_platforms = 1; 77 56 dl->id = 0; 78 57 dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; 58 + dl->be_hw_params_fixup = avs_max98357a_be_fixup; 79 59 dl->nonatomic = 1; 80 60 dl->no_pcm = 1; 81 61 dl->dpcm_playback = 1;
+7 -7
sound/soc/intel/avs/boards/nau8825.c
··· 33 33 return -EINVAL; 34 34 } 35 35 36 - if (!SND_SOC_DAPM_EVENT_ON(event)) { 36 + if (SND_SOC_DAPM_EVENT_ON(event)) 37 + ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_MCLK, 24000000, 38 + SND_SOC_CLOCK_IN); 39 + else 37 40 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN); 38 - if (ret < 0) { 39 - dev_err(card->dev, "set sysclk err = %d\n", ret); 40 - return ret; 41 - } 42 - } 41 + if (ret < 0) 42 + dev_err(card->dev, "Set sysclk failed: %d\n", ret); 43 43 44 - return 0; 44 + return ret; 45 45 } 46 46 47 47 static const struct snd_kcontrol_new card_controls[] = {
+22
sound/soc/intel/avs/boards/rt5682.c
··· 169 169 .hw_params = avs_rt5682_hw_params, 170 170 }; 171 171 172 + static int 173 + avs_rt5682_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) 174 + { 175 + struct snd_interval *rate, *channels; 176 + struct snd_mask *fmt; 177 + 178 + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 179 + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 180 + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 181 + 182 + /* The ADSP will convert the FE rate to 48k, stereo */ 183 + rate->min = rate->max = 48000; 184 + channels->min = channels->max = 2; 185 + 186 + /* set SSPN to 24 bit */ 187 + snd_mask_none(fmt); 188 + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); 189 + 190 + return 0; 191 + } 192 + 172 193 static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, 173 194 struct snd_soc_dai_link **dai_link) 174 195 { ··· 222 201 dl->id = 0; 223 202 dl->init = avs_rt5682_codec_init; 224 203 dl->exit = avs_rt5682_codec_exit; 204 + dl->be_hw_params_fixup = avs_rt5682_be_fixup; 225 205 dl->ops = &avs_rt5682_ops; 226 206 dl->nonatomic = 1; 227 207 dl->no_pcm = 1;
-31
sound/soc/intel/avs/boards/ssm4567.c
··· 15 15 #include <sound/soc-acpi.h> 16 16 #include "../../../codecs/nau8825.h" 17 17 18 - #define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" 19 18 #define SKL_SSM_CODEC_DAI "ssm4567-hifi" 20 19 21 20 static struct snd_soc_codec_conf card_codec_conf[] = { ··· 33 34 SOC_DAPM_PIN_SWITCH("Right Speaker"), 34 35 }; 35 36 36 - static int 37 - platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *control, int event) 38 - { 39 - struct snd_soc_dapm_context *dapm = w->dapm; 40 - struct snd_soc_card *card = dapm->card; 41 - struct snd_soc_dai *codec_dai; 42 - int ret; 43 - 44 - codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); 45 - if (!codec_dai) { 46 - dev_err(card->dev, "Codec dai not found\n"); 47 - return -EINVAL; 48 - } 49 - 50 - if (SND_SOC_DAPM_EVENT_ON(event)) { 51 - ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_MCLK, 24000000, 52 - SND_SOC_CLOCK_IN); 53 - if (ret < 0) 54 - dev_err(card->dev, "set sysclk err = %d\n", ret); 55 - } else { 56 - ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN); 57 - if (ret < 0) 58 - dev_err(card->dev, "set sysclk err = %d\n", ret); 59 - } 60 - 61 - return ret; 62 - } 63 - 64 37 static const struct snd_soc_dapm_widget card_widgets[] = { 65 38 SND_SOC_DAPM_SPK("Left Speaker", NULL), 66 39 SND_SOC_DAPM_SPK("Right Speaker", NULL), 67 40 SND_SOC_DAPM_SPK("DP1", NULL), 68 41 SND_SOC_DAPM_SPK("DP2", NULL), 69 - SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, platform_clock_control, 70 - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 71 42 }; 72 43 73 44 static const struct snd_soc_dapm_route card_base_routes[] = {
+1 -1
sound/soc/intel/common/soc-acpi-intel-adl-match.c
··· 559 559 { 560 560 .comp_ids = &essx_83x6, 561 561 .drv_name = "sof-essx8336", 562 - .sof_tplg_filename = "sof-adl-es83x6", /* the tplg suffix is added at run time */ 562 + .sof_tplg_filename = "sof-adl-es8336", /* the tplg suffix is added at run time */ 563 563 .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER | 564 564 SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | 565 565 SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
+2 -2
sound/soc/qcom/qdsp6/q6prm.c
··· 184 184 unsigned int freq) 185 185 { 186 186 if (freq) 187 - return q6prm_request_lpass_clock(dev, clk_id, clk_attr, clk_attr, freq); 187 + return q6prm_request_lpass_clock(dev, clk_id, clk_attr, clk_root, freq); 188 188 189 - return q6prm_release_lpass_clock(dev, clk_id, clk_attr, clk_attr, freq); 189 + return q6prm_release_lpass_clock(dev, clk_id, clk_attr, clk_root, freq); 190 190 } 191 191 EXPORT_SYMBOL_GPL(q6prm_set_lpass_clock); 192 192
+3
sound/soc/sof/intel/hda-ctrl.c
··· 196 196 goto err; 197 197 } 198 198 199 + usleep_range(500, 1000); 200 + 199 201 /* exit HDA controller reset */ 200 202 ret = hda_dsp_ctrl_link_reset(sdev, false); 201 203 if (ret < 0) { 202 204 dev_err(sdev->dev, "error: failed to exit HDA controller reset\n"); 203 205 goto err; 204 206 } 207 + usleep_range(1000, 1200); 205 208 206 209 hda_codec_detect_mask(sdev); 207 210
+12
sound/soc/sof/intel/hda-dsp.c
··· 392 392 snd_sof_dsp_update8(sdev, HDA_DSP_HDA_BAR, chip->d0i3_offset, 393 393 SOF_HDA_VS_D0I3C_I3, value); 394 394 395 + /* 396 + * The value written to the D0I3C::I3 bit may not be taken into account immediately. 397 + * A delay is recommended before checking if D0I3C::CIP is cleared 398 + */ 399 + usleep_range(30, 40); 400 + 395 401 /* Wait for cmd in progress to be cleared before exiting the function */ 396 402 ret = hda_dsp_wait_d0i3c_done(sdev); 397 403 if (ret < 0) { ··· 406 400 } 407 401 408 402 reg = snd_sof_dsp_read8(sdev, HDA_DSP_HDA_BAR, chip->d0i3_offset); 403 + /* Confirm d0i3 state changed with paranoia check */ 404 + if ((reg ^ value) & SOF_HDA_VS_D0I3C_I3) { 405 + dev_err(sdev->dev, "failed to update D0I3C!\n"); 406 + return -EIO; 407 + } 408 + 409 409 trace_sof_intel_D0I3C_updated(sdev, reg); 410 410 411 411 return 0;
+1
sound/soc/sof/intel/pci-apl.c
··· 78 78 .nocodec_tplg_filename = "sof-glk-nocodec.tplg", 79 79 .ops = &sof_apl_ops, 80 80 .ops_init = sof_apl_ops_init, 81 + .ops_free = hda_ops_free, 81 82 }; 82 83 83 84 /* PCI IDs */
+2
sound/soc/sof/intel/pci-cnl.c
··· 48 48 .nocodec_tplg_filename = "sof-cnl-nocodec.tplg", 49 49 .ops = &sof_cnl_ops, 50 50 .ops_init = sof_cnl_ops_init, 51 + .ops_free = hda_ops_free, 51 52 }; 52 53 53 54 static const struct sof_dev_desc cfl_desc = { ··· 112 111 .nocodec_tplg_filename = "sof-cnl-nocodec.tplg", 113 112 .ops = &sof_cnl_ops, 114 113 .ops_init = sof_cnl_ops_init, 114 + .ops_free = hda_ops_free, 115 115 }; 116 116 117 117 /* PCI IDs */
+1
sound/soc/sof/intel/pci-icl.c
··· 79 79 .nocodec_tplg_filename = "sof-jsl-nocodec.tplg", 80 80 .ops = &sof_cnl_ops, 81 81 .ops_init = sof_cnl_ops_init, 82 + .ops_free = hda_ops_free, 82 83 }; 83 84 84 85 /* PCI IDs */
+1
sound/soc/sof/intel/pci-mtl.c
··· 46 46 .nocodec_tplg_filename = "sof-mtl-nocodec.tplg", 47 47 .ops = &sof_mtl_ops, 48 48 .ops_init = sof_mtl_ops_init, 49 + .ops_free = hda_ops_free, 49 50 }; 50 51 51 52 /* PCI IDs */
+2
sound/soc/sof/intel/pci-skl.c
··· 38 38 .nocodec_tplg_filename = "sof-skl-nocodec.tplg", 39 39 .ops = &sof_skl_ops, 40 40 .ops_init = sof_skl_ops_init, 41 + .ops_free = hda_ops_free, 41 42 }; 42 43 43 44 static struct sof_dev_desc kbl_desc = { ··· 62 61 .nocodec_tplg_filename = "sof-kbl-nocodec.tplg", 63 62 .ops = &sof_skl_ops, 64 63 .ops_init = sof_skl_ops_init, 64 + .ops_free = hda_ops_free, 65 65 }; 66 66 67 67 /* PCI IDs */
+7
sound/soc/sof/intel/pci-tgl.c
··· 48 48 .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", 49 49 .ops = &sof_tgl_ops, 50 50 .ops_init = sof_tgl_ops_init, 51 + .ops_free = hda_ops_free, 51 52 }; 52 53 53 54 static const struct sof_dev_desc tglh_desc = { ··· 111 110 .nocodec_tplg_filename = "sof-ehl-nocodec.tplg", 112 111 .ops = &sof_tgl_ops, 113 112 .ops_init = sof_tgl_ops_init, 113 + .ops_free = hda_ops_free, 114 114 }; 115 115 116 116 static const struct sof_dev_desc adls_desc = { ··· 143 141 .nocodec_tplg_filename = "sof-adl-nocodec.tplg", 144 142 .ops = &sof_tgl_ops, 145 143 .ops_init = sof_tgl_ops_init, 144 + .ops_free = hda_ops_free, 146 145 }; 147 146 148 147 static const struct sof_dev_desc adl_desc = { ··· 175 172 .nocodec_tplg_filename = "sof-adl-nocodec.tplg", 176 173 .ops = &sof_tgl_ops, 177 174 .ops_init = sof_tgl_ops_init, 175 + .ops_free = hda_ops_free, 178 176 }; 179 177 180 178 static const struct sof_dev_desc adl_n_desc = { ··· 207 203 .nocodec_tplg_filename = "sof-adl-nocodec.tplg", 208 204 .ops = &sof_tgl_ops, 209 205 .ops_init = sof_tgl_ops_init, 206 + .ops_free = hda_ops_free, 210 207 }; 211 208 212 209 static const struct sof_dev_desc rpls_desc = { ··· 239 234 .nocodec_tplg_filename = "sof-rpl-nocodec.tplg", 240 235 .ops = &sof_tgl_ops, 241 236 .ops_init = sof_tgl_ops_init, 237 + .ops_free = hda_ops_free, 242 238 }; 243 239 244 240 static const struct sof_dev_desc rpl_desc = { ··· 271 265 .nocodec_tplg_filename = "sof-rpl-nocodec.tplg", 272 266 .ops = &sof_tgl_ops, 273 267 .ops_init = sof_tgl_ops_init, 268 + .ops_free = hda_ops_free, 274 269 }; 275 270 276 271 /* PCI IDs */
+1 -5
sound/soc/sof/intel/pci-tng.c
··· 75 75 76 76 /* LPE base */ 77 77 base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET; 78 - size = pci_resource_len(pci, desc->resindex_lpe_base); 79 - if (size < PCI_BAR_SIZE) { 80 - dev_err(sdev->dev, "error: I/O region is too small.\n"); 81 - return -ENODEV; 82 - } 78 + size = PCI_BAR_SIZE; 83 79 84 80 dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size); 85 81 sdev->bar[DSP_BAR] = devm_ioremap(sdev->dev, base, size);
+30 -2
sound/soc/sof/ipc3-topology.c
··· 2081 2081 break; 2082 2082 case SOF_DAI_INTEL_ALH: 2083 2083 if (data) { 2084 - config->dai_index = data->dai_index; 2084 + /* save the dai_index during hw_params and reuse it for hw_free */ 2085 + if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) 2086 + config->dai_index = data->dai_index; 2085 2087 config->alh.stream_id = data->dai_data; 2086 2088 } 2087 2089 break; ··· 2091 2089 break; 2092 2090 } 2093 2091 2094 - config->flags = flags; 2092 + /* 2093 + * The dai_config op is invoked several times and the flags argument varies as below: 2094 + * BE DAI hw_params: When the op is invoked during the BE DAI hw_params, flags contains 2095 + * SOF_DAI_CONFIG_FLAGS_HW_PARAMS along with quirks 2096 + * FE DAI hw_params: When invoked during FE DAI hw_params after the DAI widget has 2097 + * just been set up in the DSP, flags is set to SOF_DAI_CONFIG_FLAGS_HW_PARAMS with no 2098 + * quirks 2099 + * BE DAI trigger: When invoked during the BE DAI trigger, flags is set to 2100 + * SOF_DAI_CONFIG_FLAGS_PAUSE and contains no quirks 2101 + * BE DAI hw_free: When invoked during the BE DAI hw_free, flags is set to 2102 + * SOF_DAI_CONFIG_FLAGS_HW_FREE and contains no quirks 2103 + * FE DAI hw_free: When invoked during the FE DAI hw_free, flags is set to 2104 + * SOF_DAI_CONFIG_FLAGS_HW_FREE and contains no quirks 2105 + * 2106 + * The DAI_CONFIG IPC is sent to the DSP, only after the widget is set up during the FE 2107 + * DAI hw_params. But since the BE DAI hw_params precedes the FE DAI hw_params, the quirks 2108 + * need to be preserved when assigning the flags before sending the IPC. 2109 + * For the case of PAUSE/HW_FREE, since there are no quirks, flags can be used as is. 2110 + */ 2111 + 2112 + if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) 2113 + config->flags |= flags; 2114 + else 2115 + config->flags = flags; 2095 2116 2096 2117 /* only send the IPC if the widget is set up in the DSP */ 2097 2118 if (swidget->use_count > 0) { ··· 2122 2097 &reply, sizeof(reply)); 2123 2098 if (ret < 0) 2124 2099 dev_err(sdev->dev, "Failed to set dai config for %s\n", dai->name); 2100 + 2101 + /* clear the flags once the IPC has been sent even if it fails */ 2102 + config->flags = SOF_DAI_CONFIG_FLAGS_NONE; 2125 2103 } 2126 2104 2127 2105 return ret;
+3 -2
sound/soc/sof/ipc3.c
··· 970 970 return; 971 971 } 972 972 973 - if (hdr.size < sizeof(hdr)) { 974 - dev_err(sdev->dev, "The received message size is invalid\n"); 973 + if (hdr.size < sizeof(hdr) || hdr.size > SOF_IPC_MSG_MAX_SIZE) { 974 + dev_err(sdev->dev, "The received message size is invalid: %u\n", 975 + hdr.size); 975 976 return; 976 977 } 977 978
+2 -1
sound/soc/sof/ipc4-control.c
··· 97 97 } 98 98 99 99 /* set curve type and duration from topology */ 100 - data.curve_duration = gain->data.curve_duration; 100 + data.curve_duration_l = gain->data.curve_duration_l; 101 + data.curve_duration_h = gain->data.curve_duration_h; 101 102 data.curve_type = gain->data.curve_type; 102 103 103 104 msg->data_ptr = &data;
+16 -5
sound/soc/sof/ipc4-topology.c
··· 107 107 get_token_u32, offsetof(struct sof_ipc4_gain_data, curve_type)}, 108 108 {SOF_TKN_GAIN_RAMP_DURATION, 109 109 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 110 - offsetof(struct sof_ipc4_gain_data, curve_duration)}, 110 + offsetof(struct sof_ipc4_gain_data, curve_duration_l)}, 111 111 {SOF_TKN_GAIN_VAL, SND_SOC_TPLG_TUPLE_TYPE_WORD, 112 112 get_token_u32, offsetof(struct sof_ipc4_gain_data, init_val)}, 113 113 }; ··· 155 155 for (i = 0; i < num_format; i++, ptr = (u8 *)ptr + object_size) { 156 156 fmt = ptr; 157 157 dev_dbg(dev, 158 - " #%d: %uKHz, %ubit (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x)\n", 158 + " #%d: %uHz, %ubit (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x)\n", 159 159 i, fmt->sampling_frequency, fmt->bit_depth, fmt->ch_map, 160 160 fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg); 161 161 } ··· 692 692 693 693 dev_dbg(scomp->dev, 694 694 "pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x, cpc %d\n", 695 - swidget->widget->name, gain->data.curve_type, gain->data.curve_duration, 695 + swidget->widget->name, gain->data.curve_type, gain->data.curve_duration_l, 696 696 gain->data.init_val, gain->base_config.cpc); 697 697 698 698 ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg); ··· 980 980 981 981 ipc4_copier = dai->private; 982 982 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { 983 + struct sof_ipc4_copier_data *copier_data = &ipc4_copier->data; 983 984 struct sof_ipc4_alh_configuration_blob *blob; 984 985 unsigned int group_id; 985 986 ··· 990 989 ALH_MULTI_GTW_BASE; 991 990 ida_free(&alh_group_ida, group_id); 992 991 } 992 + 993 + /* clear the node ID */ 994 + copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; 993 995 } 994 996 } 995 997 ··· 1944 1940 pipeline->skip_during_fe_trigger = true; 1945 1941 fallthrough; 1946 1942 case SOF_DAI_INTEL_ALH: 1947 - copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; 1948 - copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data); 1943 + /* 1944 + * Do not clear the node ID when this op is invoked with 1945 + * SOF_DAI_CONFIG_FLAGS_HW_FREE. It is needed to free the group_ida during 1946 + * unprepare. 1947 + */ 1948 + if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) { 1949 + copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; 1950 + copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data); 1951 + } 1949 1952 break; 1950 1953 case SOF_DAI_INTEL_DMIC: 1951 1954 case SOF_DAI_INTEL_SSP:
+5 -3
sound/soc/sof/ipc4-topology.h
··· 46 46 #define SOF_IPC4_NODE_INDEX_INTEL_SSP(x) (((x) & 0xf) << 4) 47 47 48 48 /* Node ID for DMIC type DAI copiers */ 49 - #define SOF_IPC4_NODE_INDEX_INTEL_DMIC(x) (((x) & 0x7) << 5) 49 + #define SOF_IPC4_NODE_INDEX_INTEL_DMIC(x) ((x) & 0x7) 50 50 51 51 #define SOF_IPC4_GAIN_ALL_CHANNELS_MASK 0xffffffff 52 52 #define SOF_IPC4_VOL_ZERO_DB 0x7fffffff ··· 277 277 * @init_val: Initial value 278 278 * @curve_type: Curve type 279 279 * @reserved: reserved for future use 280 - * @curve_duration: Curve duration 280 + * @curve_duration_l: Curve duration low part 281 + * @curve_duration_h: Curve duration high part 281 282 */ 282 283 struct sof_ipc4_gain_data { 283 284 uint32_t channels; 284 285 uint32_t init_val; 285 286 uint32_t curve_type; 286 287 uint32_t reserved; 287 - uint32_t curve_duration; 288 + uint32_t curve_duration_l; 289 + uint32_t curve_duration_h; 288 290 } __aligned(8); 289 291 290 292 /**
+27 -5
sound/soc/sof/sof-audio.c
··· 50 50 /* reset route setup status for all routes that contain this widget */ 51 51 sof_reset_route_setup_status(sdev, swidget); 52 52 53 + /* free DAI config and continue to free widget even if it fails */ 54 + if (WIDGET_IS_DAI(swidget->id)) { 55 + struct snd_sof_dai_config_data data; 56 + unsigned int flags = SOF_DAI_CONFIG_FLAGS_HW_FREE; 57 + 58 + data.dai_data = DMA_CHAN_INVALID; 59 + 60 + if (tplg_ops && tplg_ops->dai_config) { 61 + err = tplg_ops->dai_config(sdev, swidget, flags, &data); 62 + if (err < 0) 63 + dev_err(sdev->dev, "failed to free config for widget %s\n", 64 + swidget->widget->name); 65 + } 66 + } 67 + 53 68 /* continue to disable core even if IPC fails */ 54 - if (tplg_ops && tplg_ops->widget_free) 55 - err = tplg_ops->widget_free(sdev, swidget); 69 + if (tplg_ops && tplg_ops->widget_free) { 70 + ret = tplg_ops->widget_free(sdev, swidget); 71 + if (ret < 0 && !err) 72 + err = ret; 73 + } 56 74 57 75 /* 58 76 * disable widget core. continue to route setup status and complete flag ··· 169 151 170 152 /* send config for DAI components */ 171 153 if (WIDGET_IS_DAI(swidget->id)) { 172 - unsigned int flags = SOF_DAI_CONFIG_FLAGS_NONE; 154 + unsigned int flags = SOF_DAI_CONFIG_FLAGS_HW_PARAMS; 173 155 156 + /* 157 + * The config flags saved during BE DAI hw_params will be used for IPC3. IPC4 does 158 + * not use the flags argument. 159 + */ 174 160 if (tplg_ops && tplg_ops->dai_config) { 175 161 ret = tplg_ops->dai_config(sdev, swidget, flags, NULL); 176 162 if (ret < 0) ··· 610 588 ret = sof_walk_widgets_in_order(sdev, spcm, fe_params, platform_params, 611 589 dir, SOF_WIDGET_SETUP); 612 590 if (ret < 0) { 613 - ret = sof_walk_widgets_in_order(sdev, spcm, fe_params, platform_params, 614 - dir, SOF_WIDGET_UNPREPARE); 591 + sof_walk_widgets_in_order(sdev, spcm, fe_params, platform_params, 592 + dir, SOF_WIDGET_UNPREPARE); 615 593 return ret; 616 594 } 617 595
+17 -17
sound/soc/sof/topology.c
··· 1388 1388 if (ret < 0) { 1389 1389 dev_err(scomp->dev, "failed to parse component pin tokens for %s\n", 1390 1390 w->name); 1391 - return ret; 1391 + goto widget_free; 1392 1392 } 1393 1393 1394 1394 if (swidget->num_sink_pins > SOF_WIDGET_MAX_NUM_PINS || 1395 1395 swidget->num_source_pins > SOF_WIDGET_MAX_NUM_PINS) { 1396 1396 dev_err(scomp->dev, "invalid pins for %s: [sink: %d, src: %d]\n", 1397 1397 swidget->widget->name, swidget->num_sink_pins, swidget->num_source_pins); 1398 - return -EINVAL; 1398 + ret = -EINVAL; 1399 + goto widget_free; 1399 1400 } 1400 1401 1401 1402 if (swidget->num_sink_pins > 1) { ··· 1405 1404 if (ret < 0) { 1406 1405 dev_err(scomp->dev, "failed to parse sink pin binding for %s\n", 1407 1406 w->name); 1408 - return ret; 1407 + goto widget_free; 1409 1408 } 1410 1409 } 1411 1410 ··· 1415 1414 if (ret < 0) { 1416 1415 dev_err(scomp->dev, "failed to parse source pin binding for %s\n", 1417 1416 w->name); 1418 - return ret; 1417 + goto widget_free; 1419 1418 } 1420 1419 } 1421 1420 ··· 1437 1436 case snd_soc_dapm_dai_out: 1438 1437 dai = kzalloc(sizeof(*dai), GFP_KERNEL); 1439 1438 if (!dai) { 1440 - kfree(swidget); 1441 - return -ENOMEM; 1442 - 1439 + ret = -ENOMEM; 1440 + goto widget_free; 1443 1441 } 1444 1442 1445 1443 ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size); ··· 1496 1496 tw->shift, swidget->id, tw->name, 1497 1497 strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 1498 1498 ? tw->sname : "none"); 1499 - kfree(swidget); 1500 - return ret; 1499 + goto widget_free; 1501 1500 } 1502 1501 1503 1502 if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) { ··· 1517 1518 if (ret) { 1518 1519 dev_err(scomp->dev, "widget event binding failed for %s\n", 1519 1520 swidget->widget->name); 1520 - kfree(swidget->private); 1521 - kfree(swidget->tuples); 1522 - kfree(swidget); 1523 - return ret; 1521 + goto free; 1524 1522 } 1525 1523 } 1526 1524 } ··· 1528 1532 1529 1533 spipe = kzalloc(sizeof(*spipe), GFP_KERNEL); 1530 1534 if (!spipe) { 1531 - kfree(swidget->private); 1532 - kfree(swidget->tuples); 1533 - kfree(swidget); 1534 - return -ENOMEM; 1535 + ret = -ENOMEM; 1536 + goto free; 1535 1537 } 1536 1538 1537 1539 spipe->pipe_widget = swidget; ··· 1539 1545 1540 1546 w->dobj.private = swidget; 1541 1547 list_add(&swidget->list, &sdev->widget_list); 1548 + return ret; 1549 + free: 1550 + kfree(swidget->private); 1551 + kfree(swidget->tuples); 1552 + widget_free: 1553 + kfree(swidget); 1542 1554 return ret; 1543 1555 } 1544 1556
+14 -8
sound/usb/endpoint.c
··· 455 455 * This function is used both for implicit feedback endpoints and in low- 456 456 * latency playback mode. 457 457 */ 458 - void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep, 459 - bool in_stream_lock) 458 + int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep, 459 + bool in_stream_lock) 460 460 { 461 461 bool implicit_fb = snd_usb_endpoint_implicit_feedback_sink(ep); 462 462 ··· 480 480 spin_unlock_irqrestore(&ep->lock, flags); 481 481 482 482 if (ctx == NULL) 483 - return; 483 + break; 484 484 485 485 /* copy over the length information */ 486 486 if (implicit_fb) { ··· 495 495 break; 496 496 if (err < 0) { 497 497 /* push back to ready list again for -EAGAIN */ 498 - if (err == -EAGAIN) 498 + if (err == -EAGAIN) { 499 499 push_back_to_ready_list(ep, ctx); 500 - else 500 + break; 501 + } 502 + 503 + if (!in_stream_lock) 501 504 notify_xrun(ep); 502 - return; 505 + return -EPIPE; 503 506 } 504 507 505 508 err = usb_submit_urb(ctx->urb, GFP_ATOMIC); ··· 510 507 usb_audio_err(ep->chip, 511 508 "Unable to submit urb #%d: %d at %s\n", 512 509 ctx->index, err, __func__); 513 - notify_xrun(ep); 514 - return; 510 + if (!in_stream_lock) 511 + notify_xrun(ep); 512 + return -EPIPE; 515 513 } 516 514 517 515 set_bit(ctx->index, &ep->active_mask); 518 516 atomic_inc(&ep->submitted_urbs); 519 517 } 518 + 519 + return 0; 520 520 } 521 521 522 522 /*
+2 -2
sound/usb/endpoint.h
··· 52 52 int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep, 53 53 struct snd_urb_ctx *ctx, int idx, 54 54 unsigned int avail); 55 - void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep, 56 - bool in_stream_lock); 55 + int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep, 56 + bool in_stream_lock); 57 57 58 58 #endif /* __USBAUDIO_ENDPOINT_H */
+6 -2
sound/usb/format.c
··· 39 39 case UAC_VERSION_1: 40 40 default: { 41 41 struct uac_format_type_i_discrete_descriptor *fmt = _fmt; 42 - if (format >= 64) 43 - return 0; /* invalid format */ 42 + if (format >= 64) { 43 + usb_audio_info(chip, 44 + "%u:%d: invalid format type 0x%llx is detected, processed as PCM\n", 45 + fp->iface, fp->altsetting, format); 46 + format = UAC_FORMAT_TYPE_I_PCM; 47 + } 44 48 sample_width = fmt->bBitResolution; 45 49 sample_bytes = fmt->bSubframeSize; 46 50 format = 1ULL << format;
+1 -1
sound/usb/pcm.c
··· 1639 1639 * outputs here 1640 1640 */ 1641 1641 if (!ep->active_mask) 1642 - snd_usb_queue_pending_output_urbs(ep, true); 1642 + return snd_usb_queue_pending_output_urbs(ep, true); 1643 1643 return 0; 1644 1644 } 1645 1645