Merge the fixes branch up so we can apply further AMD work.
Unified · Split
| @@ -416,6 +416,7 @@ TripleX Chung <xxx.phy@gmail.com> <triplex@zh-kernel.org> · 415 unmodified lines | |||
| 416 | TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn> | 416 | TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn> |
| 417 | Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com> | 417 | Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com> |
| 418 | Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws> | 418 | Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws> |
| 419 | Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com> | ||
| 419 | Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> | 420 | Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> |
| 420 | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 421 | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> |
| 421 | Uwe Kleine-König <ukleinek@strlen.de> | 422 | Uwe Kleine-König <ukleinek@strlen.de> |
| @@ -8,7 +8,7 @@ title: Audio codec controlled by ChromeOS EC · 7 unmodified lines | |||
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Cheng-Yi Chiang <cychiang@chromium.org> | 10 | - Cheng-Yi Chiang <cychiang@chromium.org> |
| 11 | - Tzung-Bi Shih <tzungbi@google.com> | 11 | - Tzung-Bi Shih <tzungbi@kernel.org> |
| 12 | 12 | ||
| 13 | description: | | 13 | description: | |
| 14 | Google's ChromeOS EC codec is a digital mic codec provided by the | 14 | Google's ChromeOS EC codec is a digital mic codec provided by the |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Realtek rt1015p codec devicetree bindings | 7 | title: Realtek rt1015p codec devicetree bindings |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Tzung-Bi Shih <tzungbi@google.com> | 10 | - Tzung-Bi Shih <tzungbi@kernel.org> |
| 11 | 11 | ||
| 12 | description: | | 12 | description: | |
| 13 | Rt1015p is a rt1015 variant which does not support I2C and | 13 | Rt1015p is a rt1015 variant which does not support I2C and |
| @@ -4911,7 +4911,7 @@ F: drivers/platform/chrome/ · 4910 unmodified lines | |||
| 4911 | 4911 | ||
| 4912 | CHROMEOS EC CODEC DRIVER | 4912 | CHROMEOS EC CODEC DRIVER |
| 4913 | M: Cheng-Yi Chiang <cychiang@chromium.org> | 4913 | M: Cheng-Yi Chiang <cychiang@chromium.org> |
| 4914 | M: Tzung-Bi Shih <tzungbi@google.com> | 4914 | M: Tzung-Bi Shih <tzungbi@kernel.org> |
| 4915 | R: Guenter Roeck <groeck@chromium.org> | 4915 | R: Guenter Roeck <groeck@chromium.org> |
| 4916 | L: chrome-platform@lists.linux.dev | 4916 | L: chrome-platform@lists.linux.dev |
| 4917 | S: Maintained | 4917 | S: Maintained |
| @@ -84,8 +84,8 @@ enum sof_ipc_dai_type { · 83 unmodified lines | |||
| 84 | SOF_DAI_AMD_BT, /**< AMD ACP BT*/ | 84 | SOF_DAI_AMD_BT, /**< AMD ACP BT*/ |
| 85 | SOF_DAI_AMD_SP, /**< AMD ACP SP */ | 85 | SOF_DAI_AMD_SP, /**< AMD ACP SP */ |
| 86 | SOF_DAI_AMD_DMIC, /**< AMD ACP DMIC */ | 86 | SOF_DAI_AMD_DMIC, /**< AMD ACP DMIC */ |
| 87 | SOF_DAI_AMD_HS, /**< Amd HS */ | ||
| 88 | SOF_DAI_MEDIATEK_AFE, /**< Mediatek AFE */ | 87 | SOF_DAI_MEDIATEK_AFE, /**< Mediatek AFE */ |
| 88 | SOF_DAI_AMD_HS, /**< Amd HS */ | ||
| 89 | }; | 89 | }; |
| 90 | 90 | ||
| 91 | /* general purpose DAI configuration */ | 91 | /* general purpose DAI configuration */ |
| @@ -36,6 +36,10 @@ enum sof_ipc_ext_data { · 35 unmodified lines | |||
| 36 | SOF_IPC_EXT_USER_ABI_INFO = 4, | 36 | SOF_IPC_EXT_USER_ABI_INFO = 4, |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | /* Build u32 number in format MMmmmppp */ | ||
| 40 | #define SOF_FW_VER(MAJOR, MINOR, PATCH) ((uint32_t)( \ | ||
| 41 | ((MAJOR) << 24) | ((MINOR) << 12) | (PATCH))) | ||
| 42 | |||
| 39 | /* FW version - SOF_IPC_GLB_VERSION */ | 43 | /* FW version - SOF_IPC_GLB_VERSION */ |
| 40 | struct sof_ipc_fw_version { | 44 | struct sof_ipc_fw_version { |
| 41 | struct sof_ipc_hdr hdr; | 45 | struct sof_ipc_hdr hdr; |
| @@ -320,6 +320,11 @@ static const struct config_entry config_table[] = { · 319 unmodified lines | |||
| 320 | {} | 320 | {} |
| 321 | } | 321 | } |
| 322 | }, | 322 | }, |
| 323 | { | ||
| 324 | .flags = FLAG_SOF, | ||
| 325 | .device = 0x34c8, | ||
| 326 | .codec_hid = &essx_83x6, | ||
| 327 | }, | ||
| 323 | { | 328 | { |
| 324 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | 329 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
| 325 | .device = 0x34c8, | 330 | .device = 0x34c8, |
| @@ -206,6 +206,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { · 205 unmodified lines | |||
| 206 | DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"), | 206 | DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"), |
| 207 | } | 207 | } |
| 208 | }, | 208 | }, |
| 209 | { | ||
| 210 | .driver_data = &acp6x_card, | ||
| 211 | .matches = { | ||
| 212 | DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"), | ||
| 213 | DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"), | ||
| 214 | } | ||
| 215 | }, | ||
| 209 | {} | 216 | {} |
| 210 | }; | 217 | }; |
| 211 | 218 | ||
| @@ -143,7 +143,7 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = { · 142 unmodified lines | |||
| 143 | 0, 0xA0, 96, adc_att_tlv), | 143 | 0, 0xA0, 96, adc_att_tlv), |
| 144 | SOC_DOUBLE_R_SX_TLV("PGA Volume", | 144 | SOC_DOUBLE_R_SX_TLV("PGA Volume", |
| 145 | CS42L51_ALC_PGA_CTL, CS42L51_ALC_PGB_CTL, | 145 | CS42L51_ALC_PGA_CTL, CS42L51_ALC_PGB_CTL, |
| 146 | 0, 0x19, 30, pga_tlv), | 146 | 0, 0x1A, 30, pga_tlv), |
| 147 | SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0), | 147 | SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0), |
| 148 | SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0), | 148 | SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0), |
| 149 | SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0), | 149 | SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0), |
| @@ -14,7 +14,7 @@ enum { · 13 unmodified lines | |||
| 14 | HDAC_HDMI_1_DAI_ID, | 14 | HDAC_HDMI_1_DAI_ID, |
| 15 | HDAC_HDMI_2_DAI_ID, | 15 | HDAC_HDMI_2_DAI_ID, |
| 16 | HDAC_HDMI_3_DAI_ID, | 16 | HDAC_HDMI_3_DAI_ID, |
| 17 | HDAC_LAST_DAI_ID = HDAC_HDMI_3_DAI_ID, | 17 | HDAC_DAI_ID_NUM |
| 18 | }; | 18 | }; |
| 19 | 19 | ||
| 20 | struct hdac_hda_pcm { | 20 | struct hdac_hda_pcm { |
| @@ -24,7 +24,7 @@ struct hdac_hda_pcm { · 3 unmodified lines | |||
| 24 | 24 | ||
| 25 | struct hdac_hda_priv { | 25 | struct hdac_hda_priv { |
| 26 | struct hda_codec *codec; | 26 | struct hda_codec *codec; |
| 27 | struct hdac_hda_pcm pcm[HDAC_LAST_DAI_ID]; | 27 | struct hdac_hda_pcm pcm[HDAC_DAI_ID_NUM]; |
| 28 | bool need_display_power; | 28 | bool need_display_power; |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| @@ -549,6 +549,10 @@ static int max98373_i2c_probe(struct i2c_client *i2c) · 548 unmodified lines | |||
| 549 | max98373->cache = devm_kcalloc(&i2c->dev, max98373->cache_num, | 549 | max98373->cache = devm_kcalloc(&i2c->dev, max98373->cache_num, |
| 550 | sizeof(*max98373->cache), | 550 | sizeof(*max98373->cache), |
| 551 | GFP_KERNEL); | 551 | GFP_KERNEL); |
| 552 | if (!max98373->cache) { | ||
| 553 | ret = -ENOMEM; | ||
| 554 | return ret; | ||
| 555 | } | ||
| 552 | 556 | ||
| 553 | for (i = 0; i < max98373->cache_num; i++) | 557 | for (i = 0; i < max98373->cache_num; i++) |
| 554 | max98373->cache[i].reg = max98373_i2c_cache_reg[i]; | 558 | max98373->cache[i].reg = max98373_i2c_cache_reg[i]; |
| @@ -298,13 +298,14 @@ static int rt5514_spi_pcm_new(struct snd_soc_component *component, · 297 unmodified lines | |||
| 298 | } | 298 | } |
| 299 | 299 | ||
| 300 | static const struct snd_soc_component_driver rt5514_spi_component = { | 300 | static const struct snd_soc_component_driver rt5514_spi_component = { |
| 301 | .name = DRV_NAME, | 301 | .name = DRV_NAME, |
| 302 | .probe = rt5514_spi_pcm_probe, | 302 | .probe = rt5514_spi_pcm_probe, |
| 303 | .open = rt5514_spi_pcm_open, | 303 | .open = rt5514_spi_pcm_open, |
| 304 | .hw_params = rt5514_spi_hw_params, | 304 | .hw_params = rt5514_spi_hw_params, |
| 305 | .hw_free = rt5514_spi_hw_free, | 305 | .hw_free = rt5514_spi_hw_free, |
| 306 | .pointer = rt5514_spi_pcm_pointer, | 306 | .pointer = rt5514_spi_pcm_pointer, |
| 307 | .pcm_construct = rt5514_spi_pcm_new, | 307 | .pcm_construct = rt5514_spi_pcm_new, |
| 308 | .legacy_dai_naming = 1, | ||
| 308 | }; | 309 | }; |
| 309 | 310 | ||
| 310 | /** | 311 | /** |
| @@ -396,15 +396,16 @@ static int rt5677_spi_pcm_probe(struct snd_soc_component *component) · 395 unmodified lines | |||
| 396 | } | 396 | } |
| 397 | 397 | ||
| 398 | static const struct snd_soc_component_driver rt5677_spi_dai_component = { | 398 | static const struct snd_soc_component_driver rt5677_spi_dai_component = { |
| 399 | .name = DRV_NAME, | 399 | .name = DRV_NAME, |
| 400 | .probe = rt5677_spi_pcm_probe, | 400 | .probe = rt5677_spi_pcm_probe, |
| 401 | .open = rt5677_spi_pcm_open, | 401 | .open = rt5677_spi_pcm_open, |
| 402 | .close = rt5677_spi_pcm_close, | 402 | .close = rt5677_spi_pcm_close, |
| 403 | .hw_params = rt5677_spi_hw_params, | 403 | .hw_params = rt5677_spi_hw_params, |
| 404 | .hw_free = rt5677_spi_hw_free, | 404 | .hw_free = rt5677_spi_hw_free, |
| 405 | .prepare = rt5677_spi_prepare, | 405 | .prepare = rt5677_spi_prepare, |
| 406 | .pointer = rt5677_spi_pcm_pointer, | 406 | .pointer = rt5677_spi_pcm_pointer, |
| 407 | .pcm_construct = rt5677_spi_pcm_new, | 407 | .pcm_construct = rt5677_spi_pcm_new, |
| 408 | .legacy_dai_naming = 1, | ||
| 408 | }; | 409 | }; |
| 409 | 410 | ||
| 410 | /* Select a suitable transfer command for the next transfer to ensure | 411 | /* Select a suitable transfer command for the next transfer to ensure |
| @@ -230,7 +230,7 @@ static int rt711_sdca_read_prop(struct sdw_slave *slave) · 229 unmodified lines | |||
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | /* set the timeout values */ | 232 | /* set the timeout values */ |
| 233 | prop->clk_stop_timeout = 20; | 233 | prop->clk_stop_timeout = 700; |
| 234 | 234 | ||
| 235 | /* wake-up event */ | 235 | /* wake-up event */ |
| 236 | prop->wake_capable = 1; | 236 | prop->wake_capable = 1; |
| @@ -1794,6 +1794,7 @@ static void sgtl5000_i2c_remove(struct i2c_client *client) · 1793 unmodified lines | |||
| 1794 | { | 1794 | { |
| 1795 | struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client); | 1795 | struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client); |
| 1796 | 1796 | ||
| 1797 | regmap_write(sgtl5000->regmap, SGTL5000_CHIP_CLK_CTRL, SGTL5000_CHIP_CLK_CTRL_DEFAULT); | ||
| 1797 | regmap_write(sgtl5000->regmap, SGTL5000_CHIP_DIG_POWER, SGTL5000_DIG_POWER_DEFAULT); | 1798 | regmap_write(sgtl5000->regmap, SGTL5000_CHIP_DIG_POWER, SGTL5000_DIG_POWER_DEFAULT); |
| 1798 | regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, SGTL5000_ANA_POWER_DEFAULT); | 1799 | regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, SGTL5000_ANA_POWER_DEFAULT); |
| 1799 | 1800 | ||
| @@ -438,20 +438,13 @@ static int tas2764_set_dai_tdm_slot(struct snd_soc_dai *dai, · 437 unmodified lines | |||
| 438 | if (tx_mask == 0 || rx_mask != 0) | 438 | if (tx_mask == 0 || rx_mask != 0) |
| 439 | return -EINVAL; | 439 | return -EINVAL; |
| 440 | 440 | ||
| 441 | if (slots == 1) { | 441 | left_slot = __ffs(tx_mask); |
| 442 | if (tx_mask != 1) | 442 | tx_mask &= ~(1 << left_slot); |
| 443 | return -EINVAL; | 443 | if (tx_mask == 0) { |
| 444 | left_slot = 0; | 444 | right_slot = left_slot; |
| 445 | right_slot = 0; | ||
| 446 | } else { | 445 | } else { |
| 447 | left_slot = __ffs(tx_mask); | 446 | right_slot = __ffs(tx_mask); |
| 448 | tx_mask &= ~(1 << left_slot); | 447 | tx_mask &= ~(1 << right_slot); |
| 449 | if (tx_mask == 0) { | ||
| 450 | right_slot = left_slot; | ||
| 451 | } else { | ||
| 452 | right_slot = __ffs(tx_mask); | ||
| 453 | tx_mask &= ~(1 << right_slot); | ||
| 454 | } | ||
| 455 | } | 448 | } |
| 456 | 449 | ||
| 457 | if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) | 450 | if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) |
| @@ -395,21 +395,13 @@ static int tas2770_set_dai_tdm_slot(struct snd_soc_dai *dai, · 394 unmodified lines | |||
| 395 | if (tx_mask == 0 || rx_mask != 0) | 395 | if (tx_mask == 0 || rx_mask != 0) |
| 396 | return -EINVAL; | 396 | return -EINVAL; |
| 397 | 397 | ||
| 398 | if (slots == 1) { | 398 | left_slot = __ffs(tx_mask); |
| 399 | if (tx_mask != 1) | 399 | tx_mask &= ~(1 << left_slot); |
| 400 | return -EINVAL; | 400 | if (tx_mask == 0) { |
| 401 | 401 | right_slot = left_slot; | |
| 402 | left_slot = 0; | ||
| 403 | right_slot = 0; | ||
| 404 | } else { | 402 | } else { |
| 405 | left_slot = __ffs(tx_mask); | 403 | right_slot = __ffs(tx_mask); |
| 406 | tx_mask &= ~(1 << left_slot); | 404 | tx_mask &= ~(1 << right_slot); |
| 407 | if (tx_mask == 0) { | ||
| 408 | right_slot = left_slot; | ||
| 409 | } else { | ||
| 410 | right_slot = __ffs(tx_mask); | ||
| 411 | tx_mask &= ~(1 << right_slot); | ||
| 412 | } | ||
| 413 | } | 405 | } |
| 414 | 406 | ||
| 415 | if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) | 407 | if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) |
| @@ -380,20 +380,13 @@ static int tas2780_set_dai_tdm_slot(struct snd_soc_dai *dai, · 379 unmodified lines | |||
| 380 | if (tx_mask == 0 || rx_mask != 0) | 380 | if (tx_mask == 0 || rx_mask != 0) |
| 381 | return -EINVAL; | 381 | return -EINVAL; |
| 382 | 382 | ||
| 383 | if (slots == 1) { | 383 | left_slot = __ffs(tx_mask); |
| 384 | if (tx_mask != 1) | 384 | tx_mask &= ~(1 << left_slot); |
| 385 | return -EINVAL; | 385 | if (tx_mask == 0) { |
| 386 | left_slot = 0; | 386 | right_slot = left_slot; |
| 387 | right_slot = 0; | ||
| 388 | } else { | 387 | } else { |
| 389 | left_slot = __ffs(tx_mask); | 388 | right_slot = __ffs(tx_mask); |
| 390 | tx_mask &= ~(1 << left_slot); | 389 | tx_mask &= ~(1 << right_slot); |
| 391 | if (tx_mask == 0) { | ||
| 392 | right_slot = left_slot; | ||
| 393 | } else { | ||
| 394 | right_slot = __ffs(tx_mask); | ||
| 395 | tx_mask &= ~(1 << right_slot); | ||
| 396 | } | ||
| 397 | } | 390 | } |
| 398 | 391 | ||
| 399 | if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) | 392 | if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #include <dt-bindings/sound/tlv320adc3xxx.h> | 15 | #include <dt-bindings/sound/tlv320adc3xxx.h> |
| 16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
| 17 | #include <linux/gpio/consumer.h> | ||
| 17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 18 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
| 19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| @@ -1025,7 +1026,9 @@ static const struct gpio_chip adc3xxx_gpio_chip = { · 1005 unmodified lines | |||
| 1025 | 1026 | ||
| 1026 | static void adc3xxx_free_gpio(struct adc3xxx *adc3xxx) | 1027 | static void adc3xxx_free_gpio(struct adc3xxx *adc3xxx) |
| 1027 | { | 1028 | { |
| 1029 | #ifdef CONFIG_GPIOLIB | ||
| 1028 | gpiochip_remove(&adc3xxx->gpio_chip); | 1030 | gpiochip_remove(&adc3xxx->gpio_chip); |
| 1031 | #endif | ||
| 1029 | } | 1032 | } |
| 1030 | 1033 | ||
| 1031 | static void adc3xxx_init_gpio(struct adc3xxx *adc3xxx) | 1034 | static void adc3xxx_init_gpio(struct adc3xxx *adc3xxx) |
| @@ -2503,6 +2503,14 @@ static void wm8962_configure_bclk(struct snd_soc_component *component) · 2502 unmodified lines | |||
| 2503 | snd_soc_component_update_bits(component, WM8962_CLOCKING2, | 2503 | snd_soc_component_update_bits(component, WM8962_CLOCKING2, |
| 2504 | WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA); | 2504 | WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA); |
| 2505 | 2505 | ||
| 2506 | /* DSPCLK_DIV field in WM8962_CLOCKING1 register is used to generate | ||
| 2507 | * correct frequency of LRCLK and BCLK. Sometimes the read-only value | ||
| 2508 | * can't be updated timely after enabling SYSCLK. This results in wrong | ||
| 2509 | * calculation values. Delay is introduced here to wait for newest | ||
| 2510 | * value from register. The time of the delay should be at least | ||
| 2511 | * 500~1000us according to test. | ||
| 2512 | */ | ||
| 2513 | usleep_range(500, 1000); | ||
| 2506 | dspclk = snd_soc_component_read(component, WM8962_CLOCKING1); | 2514 | dspclk = snd_soc_component_read(component, WM8962_CLOCKING1); |
| 2507 | 2515 | ||
| 2508 | if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON) | 2516 | if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON) |
| @@ -1232,7 +1232,7 @@ static int fsl_asrc_probe(struct platform_device *pdev) · 1231 unmodified lines | |||
| 1232 | } | 1232 | } |
| 1233 | 1233 | ||
| 1234 | ret = pm_runtime_put_sync(&pdev->dev); | 1234 | ret = pm_runtime_put_sync(&pdev->dev); |
| 1235 | if (ret < 0) | 1235 | if (ret < 0 && ret != -ENOSYS) |
| 1236 | goto err_pm_get_sync; | 1236 | goto err_pm_get_sync; |
| 1237 | 1237 | ||
| 1238 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component, | 1238 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component, |
| @@ -1069,7 +1069,7 @@ static int fsl_esai_probe(struct platform_device *pdev) · 1068 unmodified lines | |||
| 1069 | regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0); | 1069 | regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0); |
| 1070 | 1070 | ||
| 1071 | ret = pm_runtime_put_sync(&pdev->dev); | 1071 | ret = pm_runtime_put_sync(&pdev->dev); |
| 1072 | if (ret < 0) | 1072 | if (ret < 0 && ret != -ENOSYS) |
| 1073 | goto err_pm_get_sync; | 1073 | goto err_pm_get_sync; |
| 1074 | 1074 | ||
| 1075 | /* | 1075 | /* |
| @@ -376,6 +376,25 @@ static int fsl_micfil_reset(struct device *dev) · 375 unmodified lines | |||
| 376 | if (ret) | 376 | if (ret) |
| 377 | return ret; | 377 | return ret; |
| 378 | 378 | ||
| 379 | /* | ||
| 380 | * SRES is self-cleared bit, but REG_MICFIL_CTRL1 is defined | ||
| 381 | * as non-volatile register, so SRES still remain in regmap | ||
| 382 | * cache after set, that every update of REG_MICFIL_CTRL1, | ||
| 383 | * software reset happens. so clear it explicitly. | ||
| 384 | */ | ||
| 385 | ret = regmap_clear_bits(micfil->regmap, REG_MICFIL_CTRL1, | ||
| 386 | MICFIL_CTRL1_SRES); | ||
| 387 | if (ret) | ||
| 388 | return ret; | ||
| 389 | |||
| 390 | /* | ||
| 391 | * Set SRES should clear CHnF flags, But even add delay here | ||
| 392 | * the CHnF may not be cleared sometimes, so clear CHnF explicitly. | ||
| 393 | */ | ||
| 394 | ret = regmap_write_bits(micfil->regmap, REG_MICFIL_STAT, 0xFF, 0xFF); | ||
| 395 | if (ret) | ||
| 396 | return ret; | ||
| 397 | |||
| 379 | return 0; | 398 | return 0; |
| 380 | } | 399 | } |
| 381 | 400 | ||
| @@ -1448,7 +1448,7 @@ static int fsl_sai_probe(struct platform_device *pdev) · 1447 unmodified lines | |||
| 1448 | } | 1448 | } |
| 1449 | 1449 | ||
| 1450 | ret = pm_runtime_put_sync(dev); | 1450 | ret = pm_runtime_put_sync(dev); |
| 1451 | if (ret < 0) | 1451 | if (ret < 0 && ret != -ENOSYS) |
| 1452 | goto err_pm_get_sync; | 1452 | goto err_pm_get_sync; |
| 1453 | 1453 | ||
| 1454 | /* | 1454 | /* |
| @@ -443,6 +443,13 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = { · 442 unmodified lines | |||
| 443 | | BYT_CHT_ES8316_INTMIC_IN2_MAP | 443 | | BYT_CHT_ES8316_INTMIC_IN2_MAP |
| 444 | | BYT_CHT_ES8316_JD_INVERTED), | 444 | | BYT_CHT_ES8316_JD_INVERTED), |
| 445 | }, | 445 | }, |
| 446 | { /* Nanote UMPC-01 */ | ||
| 447 | .matches = { | ||
| 448 | DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"), | ||
| 449 | DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"), | ||
| 450 | }, | ||
| 451 | .driver_data = (void *)BYT_CHT_ES8316_INTMIC_IN1_MAP, | ||
| 452 | }, | ||
| 446 | { /* Teclast X98 Plus II */ | 453 | { /* Teclast X98 Plus II */ |
| 447 | .matches = { | 454 | .matches = { |
| 448 | DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), | 455 | DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), |
| @@ -63,6 +63,7 @@ struct sof_es8336_private { · 62 unmodified lines | |||
| 63 | struct snd_soc_jack jack; | 63 | struct snd_soc_jack jack; |
| 64 | struct list_head hdmi_pcm_list; | 64 | struct list_head hdmi_pcm_list; |
| 65 | bool speaker_en; | 65 | bool speaker_en; |
| 66 | struct delayed_work pcm_pop_work; | ||
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| 68 | struct sof_hdmi_pcm { | 69 | struct sof_hdmi_pcm { |
| @@ -111,6 +112,46 @@ static void log_quirks(struct device *dev) · 42 unmodified lines | |||
| 111 | dev_info(dev, "quirk headset at mic1 port enabled\n"); | 112 | dev_info(dev, "quirk headset at mic1 port enabled\n"); |
| 112 | } | 113 | } |
| 113 | 114 | ||
| 115 | static void pcm_pop_work_events(struct work_struct *work) | ||
| 116 | { | ||
| 117 | struct sof_es8336_private *priv = | ||
| 118 | container_of(work, struct sof_es8336_private, pcm_pop_work.work); | ||
| 119 | |||
| 120 | gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en); | ||
| 121 | |||
| 122 | if (quirk & SOF_ES8336_HEADPHONE_GPIO) | ||
| 123 | gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en); | ||
| 124 | |||
| 125 | } | ||
| 126 | |||
| 127 | static int sof_8336_trigger(struct snd_pcm_substream *substream, int cmd) | ||
| 128 | { | ||
| 129 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | ||
| 130 | struct snd_soc_card *card = rtd->card; | ||
| 131 | struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); | ||
| 132 | |||
| 133 | switch (cmd) { | ||
| 134 | case SNDRV_PCM_TRIGGER_START: | ||
| 135 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 136 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 137 | break; | ||
| 138 | |||
| 139 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
| 140 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 141 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 142 | if (priv->speaker_en == false) | ||
| 143 | if (substream->stream == 0) { | ||
| 144 | cancel_delayed_work(&priv->pcm_pop_work); | ||
| 145 | gpiod_set_value_cansleep(priv->gpio_speakers, true); | ||
| 146 | } | ||
| 147 | break; | ||
| 148 | default: | ||
| 149 | return -EINVAL; | ||
| 150 | } | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 114 | static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, | 155 | static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, |
| 115 | struct snd_kcontrol *kcontrol, int event) | 156 | struct snd_kcontrol *kcontrol, int event) |
| 116 | { | 157 | { |
| @@ -122,19 +163,7 @@ static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, · 5 unmodified lines | |||
| 122 | 163 | ||
| 123 | priv->speaker_en = !SND_SOC_DAPM_EVENT_ON(event); | 164 | priv->speaker_en = !SND_SOC_DAPM_EVENT_ON(event); |
| 124 | 165 | ||
| 125 | if (SND_SOC_DAPM_EVENT_ON(event)) | 166 | queue_delayed_work(system_wq, &priv->pcm_pop_work, msecs_to_jiffies(70)); |
| 126 | msleep(70); | ||
| 127 | |||
| 128 | gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en); | ||
| 129 | |||
| 130 | if (!(quirk & SOF_ES8336_HEADPHONE_GPIO)) | ||
| 131 | return 0; | ||
| 132 | |||
| 133 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
| 134 | msleep(70); | ||
| 135 | |||
| 136 | gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en); | ||
| 137 | |||
| 138 | return 0; | 167 | return 0; |
| 139 | } | 168 | } |
| 140 | 169 | ||
| @@ -344,6 +373,7 @@ static int sof_es8336_hw_params(struct snd_pcm_substream *substream, · 203 unmodified lines | |||
| 344 | /* machine stream operations */ | 373 | /* machine stream operations */ |
| 345 | static struct snd_soc_ops sof_es8336_ops = { | 374 | static struct snd_soc_ops sof_es8336_ops = { |
| 346 | .hw_params = sof_es8336_hw_params, | 375 | .hw_params = sof_es8336_hw_params, |
| 376 | .trigger = sof_8336_trigger, | ||
| 347 | }; | 377 | }; |
| 348 | 378 | ||
| 349 | static struct snd_soc_dai_link_component platform_component[] = { | 379 | static struct snd_soc_dai_link_component platform_component[] = { |
| @@ -723,7 +753,8 @@ static int sof_es8336_probe(struct platform_device *pdev) · 373 unmodified lines | |||
| 723 | } | 753 | } |
| 724 | 754 | ||
| 725 | INIT_LIST_HEAD(&priv->hdmi_pcm_list); | 755 | INIT_LIST_HEAD(&priv->hdmi_pcm_list); |
| 726 | 756 | INIT_DELAYED_WORK(&priv->pcm_pop_work, | |
| 757 | pcm_pop_work_events); | ||
| 727 | snd_soc_card_set_drvdata(card, priv); | 758 | snd_soc_card_set_drvdata(card, priv); |
| 728 | 759 | ||
| 729 | if (mach->mach_params.dmic_num > 0) { | 760 | if (mach->mach_params.dmic_num > 0) { |
| @@ -752,6 +783,7 @@ static int sof_es8336_remove(struct platform_device *pdev) · 22 unmodified lines | |||
| 752 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 783 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
| 753 | struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); | 784 | struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); |
| 754 | 785 | ||
| 786 | cancel_delayed_work(&priv->pcm_pop_work); | ||
| 755 | gpiod_put(priv->gpio_speakers); | 787 | gpiod_put(priv->gpio_speakers); |
| 756 | device_remove_software_node(priv->codec_dev); | 788 | device_remove_software_node(priv->codec_dev); |
| 757 | put_device(priv->codec_dev); | 789 | put_device(priv->codec_dev); |
| @@ -10,6 +10,11 @@ · 9 unmodified lines | |||
| 10 | #include <sound/soc-acpi-intel-match.h> | 10 | #include <sound/soc-acpi-intel-match.h> |
| 11 | #include "../skylake/skl.h" | 11 | #include "../skylake/skl.h" |
| 12 | 12 | ||
| 13 | static const struct snd_soc_acpi_codecs essx_83x6 = { | ||
| 14 | .num_codecs = 3, | ||
| 15 | .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, | ||
| 16 | }; | ||
| 17 | |||
| 13 | static struct skl_machine_pdata icl_pdata = { | 18 | static struct skl_machine_pdata icl_pdata = { |
| 14 | .use_tplg_pcm = true, | 19 | .use_tplg_pcm = true, |
| 15 | }; | 20 | }; |
| @@ -27,6 +32,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = { · 11 unmodified lines | |||
| 27 | .drv_name = "sof_rt5682", | 32 | .drv_name = "sof_rt5682", |
| 28 | .sof_tplg_filename = "sof-icl-rt5682.tplg", | 33 | .sof_tplg_filename = "sof-icl-rt5682.tplg", |
| 29 | }, | 34 | }, |
| 35 | { | ||
| 36 | .comp_ids = &essx_83x6, | ||
| 37 | .drv_name = "sof-essx8336", | ||
| 38 | .sof_tplg_filename = "sof-icl-es8336", /* the tplg suffix is added at run time */ | ||
| 39 | .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER | | ||
| 40 | SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | | ||
| 41 | SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, | ||
| 42 | }, | ||
| 30 | {}, | 43 | {}, |
| 31 | }; | 44 | }; |
| 32 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines); | 45 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines); |
| @@ -3477,10 +3477,23 @@ EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_cpus); · 3476 unmodified lines | |||
| 3477 | 3477 | ||
| 3478 | static int __init snd_soc_init(void) | 3478 | static int __init snd_soc_init(void) |
| 3479 | { | 3479 | { |
| 3480 | int ret; | ||
| 3481 | |||
| 3480 | snd_soc_debugfs_init(); | 3482 | snd_soc_debugfs_init(); |
| 3481 | snd_soc_util_init(); | 3483 | ret = snd_soc_util_init(); |
| 3484 | if (ret) | ||
| 3485 | goto err_util_init; | ||
| 3482 | 3486 | ||
| 3483 | return platform_driver_register(&soc_driver); | 3487 | ret = platform_driver_register(&soc_driver); |
| 3488 | if (ret) | ||
| 3489 | goto err_register; | ||
| 3490 | return 0; | ||
| 3491 | |||
| 3492 | err_register: | ||
| 3493 | snd_soc_util_exit(); | ||
| 3494 | err_util_init: | ||
| 3495 | snd_soc_debugfs_exit(); | ||
| 3496 | return ret; | ||
| 3484 | } | 3497 | } |
| 3485 | module_init(snd_soc_init); | 3498 | module_init(snd_soc_init); |
| 3486 | 3499 | ||
| @@ -3620,7 +3620,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, · 3619 unmodified lines | |||
| 3620 | 3620 | ||
| 3621 | switch (w->id) { | 3621 | switch (w->id) { |
| 3622 | case snd_soc_dapm_regulator_supply: | 3622 | case snd_soc_dapm_regulator_supply: |
| 3623 | w->regulator = devm_regulator_get(dapm->dev, w->name); | 3623 | w->regulator = devm_regulator_get(dapm->dev, widget->name); |
| 3624 | if (IS_ERR(w->regulator)) { | 3624 | if (IS_ERR(w->regulator)) { |
| 3625 | ret = PTR_ERR(w->regulator); | 3625 | ret = PTR_ERR(w->regulator); |
| 3626 | goto request_failed; | 3626 | goto request_failed; |
| @@ -452,7 +452,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, · 451 unmodified lines | |||
| 452 | val = ucontrol->value.integer.value[0]; | 452 | val = ucontrol->value.integer.value[0]; |
| 453 | if (mc->platform_max && val > mc->platform_max) | 453 | if (mc->platform_max && val > mc->platform_max) |
| 454 | return -EINVAL; | 454 | return -EINVAL; |
| 455 | if (val > max - min) | 455 | if (val > max) |
| 456 | return -EINVAL; | 456 | return -EINVAL; |
| 457 | val_mask = mask << shift; | 457 | val_mask = mask << shift; |
| 458 | val = (val + min) & mask; | 458 | val = (val + min) & mask; |
| @@ -464,10 +464,15 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, · 5 unmodified lines | |||
| 464 | ret = err; | 464 | ret = err; |
| 465 | 465 | ||
| 466 | if (snd_soc_volsw_is_stereo(mc)) { | 466 | if (snd_soc_volsw_is_stereo(mc)) { |
| 467 | unsigned int val2; | 467 | unsigned int val2 = ucontrol->value.integer.value[1]; |
| 468 | |||
| 469 | if (mc->platform_max && val2 > mc->platform_max) | ||
| 470 | return -EINVAL; | ||
| 471 | if (val2 > max) | ||
| 472 | return -EINVAL; | ||
| 468 | 473 | ||
| 469 | val_mask = mask << rshift; | 474 | val_mask = mask << rshift; |
| 470 | val2 = (ucontrol->value.integer.value[1] + min) & mask; | 475 | val2 = (val2 + min) & mask; |
| 471 | val2 = val2 << rshift; | 476 | val2 = val2 << rshift; |
| 472 | 477 | ||
| 473 | err = snd_soc_component_update_bits(component, reg2, val_mask, | 478 | err = snd_soc_component_update_bits(component, reg2, val_mask, |
| @@ -822,11 +822,6 @@ static int __soc_pcm_open(struct snd_soc_pcm_runtime *rtd, · 821 unmodified lines | |||
| 822 | ret = snd_soc_dai_startup(dai, substream); | 822 | ret = snd_soc_dai_startup(dai, substream); |
| 823 | if (ret < 0) | 823 | if (ret < 0) |
| 824 | goto err; | 824 | goto err; |
| 825 | |||
| 826 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 827 | dai->tx_mask = 0; | ||
| 828 | else | ||
| 829 | dai->rx_mask = 0; | ||
| 830 | } | 825 | } |
| 831 | 826 | ||
| 832 | /* Dynamic PCM DAI links compat checks use dynamic capabilities */ | 827 | /* Dynamic PCM DAI links compat checks use dynamic capabilities */ |
| @@ -1252,6 +1247,8 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe, · 419 unmodified lines | |||
| 1252 | return; | 1247 | return; |
| 1253 | 1248 | ||
| 1254 | be_substream = snd_soc_dpcm_get_substream(be, stream); | 1249 | be_substream = snd_soc_dpcm_get_substream(be, stream); |
| 1250 | if (!be_substream) | ||
| 1251 | return; | ||
| 1255 | 1252 | ||
| 1256 | for_each_dpcm_fe(be, stream, dpcm) { | 1253 | for_each_dpcm_fe(be, stream, dpcm) { |
| 1257 | if (dpcm->fe == fe) | 1254 | if (dpcm->fe == fe) |
| @@ -2275,6 +2275,7 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif · 2274 unmodified lines | |||
| 2275 | struct sof_ipc_fw_version *v = &sdev->fw_ready.version; | 2275 | struct sof_ipc_fw_version *v = &sdev->fw_ready.version; |
| 2276 | struct snd_sof_widget *swidget; | 2276 | struct snd_sof_widget *swidget; |
| 2277 | struct snd_sof_route *sroute; | 2277 | struct snd_sof_route *sroute; |
| 2278 | bool dyn_widgets = false; | ||
| 2278 | int ret; | 2279 | int ret; |
| 2279 | 2280 | ||
| 2280 | /* | 2281 | /* |
| @@ -2284,12 +2285,14 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif · 3 unmodified lines | |||
| 2284 | * topology loading the sound card unavailable to open PCMs. | 2285 | * topology loading the sound card unavailable to open PCMs. |
| 2285 | */ | 2286 | */ |
| 2286 | list_for_each_entry(swidget, &sdev->widget_list, list) { | 2287 | list_for_each_entry(swidget, &sdev->widget_list, list) { |
| 2287 | if (swidget->dynamic_pipeline_widget) | 2288 | if (swidget->dynamic_pipeline_widget) { |
| 2289 | dyn_widgets = true; | ||
| 2288 | continue; | 2290 | continue; |
| 2291 | } | ||
| 2289 | 2292 | ||
| 2290 | /* Do not free widgets for static pipelines with FW ABI older than 3.19 */ | 2293 | /* Do not free widgets for static pipelines with FW older than SOF2.2 */ |
| 2291 | if (!verify && !swidget->dynamic_pipeline_widget && | 2294 | if (!verify && !swidget->dynamic_pipeline_widget && |
| 2292 | v->abi_version < SOF_ABI_VER(3, 19, 0)) { | 2295 | SOF_FW_VER(v->major, v->minor, v->micro) < SOF_FW_VER(2, 2, 0)) { |
| 2293 | swidget->use_count = 0; | 2296 | swidget->use_count = 0; |
| 2294 | swidget->complete = 0; | 2297 | swidget->complete = 0; |
| 2295 | continue; | 2298 | continue; |
| @@ -2303,9 +2306,11 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif · 7 unmodified lines | |||
| 2303 | /* | 2306 | /* |
| 2304 | * Tear down all pipelines associated with PCMs that did not get suspended | 2307 | * Tear down all pipelines associated with PCMs that did not get suspended |
| 2305 | * and unset the prepare flag so that they can be set up again during resume. | 2308 | * and unset the prepare flag so that they can be set up again during resume. |
| 2306 | * Skip this step for older firmware. | 2309 | * Skip this step for older firmware unless topology has any |
| 2310 | * dynamic pipeline (in which case the step is mandatory). | ||
| 2307 | */ | 2311 | */ |
| 2308 | if (!verify && v->abi_version >= SOF_ABI_VER(3, 19, 0)) { | 2312 | if (!verify && (dyn_widgets || SOF_FW_VER(v->major, v->minor, v->micro) >= |
| 2313 | SOF_FW_VER(2, 2, 0))) { | ||
| 2309 | ret = sof_tear_down_left_over_pipelines(sdev); | 2314 | ret = sof_tear_down_left_over_pipelines(sdev); |
| 2310 | if (ret < 0) { | 2315 | if (ret < 0) { |
| 2311 | dev_err(sdev->dev, "failed to tear down paused pipelines\n"); | 2316 | dev_err(sdev->dev, "failed to tear down paused pipelines\n"); |
| @@ -1499,16 +1499,6 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index, · 1498 unmodified lines | |||
| 1499 | break; | 1499 | break; |
| 1500 | } | 1500 | } |
| 1501 | 1501 | ||
| 1502 | if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) { | ||
| 1503 | swidget->core = SOF_DSP_PRIMARY_CORE; | ||
| 1504 | } else { | ||
| 1505 | int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples, | ||
| 1506 | swidget->num_tuples); | ||
| 1507 | |||
| 1508 | if (core >= 0) | ||
| 1509 | swidget->core = core; | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | /* check token parsing reply */ | 1502 | /* check token parsing reply */ |
| 1513 | if (ret < 0) { | 1503 | if (ret < 0) { |
| 1514 | dev_err(scomp->dev, | 1504 | dev_err(scomp->dev, |
| @@ -1520,6 +1510,16 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index, · 5 unmodified lines | |||
| 1520 | return ret; | 1510 | return ret; |
| 1521 | } | 1511 | } |
| 1522 | 1512 | ||
| 1513 | if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) { | ||
| 1514 | swidget->core = SOF_DSP_PRIMARY_CORE; | ||
| 1515 | } else { | ||
| 1516 | int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples, | ||
| 1517 | swidget->num_tuples); | ||
| 1518 | |||
| 1519 | if (core >= 0) | ||
| 1520 | swidget->core = core; | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | /* bind widget to external event */ | 1523 | /* bind widget to external event */ |
| 1524 | if (tw->event_type) { | 1524 | if (tw->event_type) { |
| 1525 | if (widget_ops[w->id].bind_event) { | 1525 | if (widget_ops[w->id].bind_event) { |
| @@ -304,6 +304,11 @@ static int stm32_adfsdm_dummy_cb(const void *data, void *private) · 303 unmodified lines | |||
| 304 | return 0; | 304 | return 0; |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | static void stm32_adfsdm_cleanup(void *data) | ||
| 308 | { | ||
| 309 | iio_channel_release_all_cb(data); | ||
| 310 | } | ||
| 311 | |||
| 307 | static struct snd_soc_component_driver stm32_adfsdm_soc_platform = { | 312 | static struct snd_soc_component_driver stm32_adfsdm_soc_platform = { |
| 308 | .open = stm32_adfsdm_pcm_open, | 313 | .open = stm32_adfsdm_pcm_open, |
| 309 | .close = stm32_adfsdm_pcm_close, | 314 | .close = stm32_adfsdm_pcm_close, |
| @@ -350,6 +355,12 @@ static int stm32_adfsdm_probe(struct platform_device *pdev) · 40 unmodified lines | |||
| 350 | if (IS_ERR(priv->iio_cb)) | 355 | if (IS_ERR(priv->iio_cb)) |
| 351 | return PTR_ERR(priv->iio_cb); | 356 | return PTR_ERR(priv->iio_cb); |
| 352 | 357 | ||
| 358 | ret = devm_add_action_or_reset(&pdev->dev, stm32_adfsdm_cleanup, priv->iio_cb); | ||
| 359 | if (ret < 0) { | ||
| 360 | dev_err(&pdev->dev, "Unable to add action\n"); | ||
| 361 | return ret; | ||
| 362 | } | ||
| 363 | |||
| 353 | component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL); | 364 | component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL); |
| 354 | if (!component) | 365 | if (!component) |
| 355 | return -ENOMEM; | 366 | return -ENOMEM; |
| @@ -1077,7 +1077,7 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev, · 1076 unmodified lines | |||
| 1077 | if (irq < 0) | 1077 | if (irq < 0) |
| 1078 | return irq; | 1078 | return irq; |
| 1079 | 1079 | ||
| 1080 | ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, IRQF_ONESHOT, | 1080 | ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, 0, |
| 1081 | dev_name(&pdev->dev), i2s); | 1081 | dev_name(&pdev->dev), i2s); |
| 1082 | if (ret) { | 1082 | if (ret) { |
| 1083 | dev_err(&pdev->dev, "irq request returned %d\n", ret); | 1083 | dev_err(&pdev->dev, "irq request returned %d\n", ret); |