diff options
Diffstat (limited to 'sound')
39 files changed, 279 insertions, 137 deletions
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 1c16830af3d8..6faaac60161a 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -520,7 +520,7 @@ static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip, | |||
520 | snd_es18xx_mixer_write(chip, 0x78, 0x93); | 520 | snd_es18xx_mixer_write(chip, 0x78, 0x93); |
521 | #ifdef AVOID_POPS | 521 | #ifdef AVOID_POPS |
522 | /* Avoid pops */ | 522 | /* Avoid pops */ |
523 | udelay(100000); | 523 | mdelay(100); |
524 | if (chip->caps & ES18XX_PCM2) | 524 | if (chip->caps & ES18XX_PCM2) |
525 | /* Restore Audio 2 volume */ | 525 | /* Restore Audio 2 volume */ |
526 | snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol); | 526 | snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol); |
@@ -537,7 +537,7 @@ static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip, | |||
537 | /* Stop DMA */ | 537 | /* Stop DMA */ |
538 | snd_es18xx_mixer_write(chip, 0x78, 0x00); | 538 | snd_es18xx_mixer_write(chip, 0x78, 0x00); |
539 | #ifdef AVOID_POPS | 539 | #ifdef AVOID_POPS |
540 | udelay(25000); | 540 | mdelay(25); |
541 | if (chip->caps & ES18XX_PCM2) | 541 | if (chip->caps & ES18XX_PCM2) |
542 | /* Set Audio 2 volume to 0 */ | 542 | /* Set Audio 2 volume to 0 */ |
543 | snd_es18xx_mixer_write(chip, 0x7C, 0); | 543 | snd_es18xx_mixer_write(chip, 0x7C, 0); |
@@ -596,7 +596,7 @@ static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream) | |||
596 | snd_es18xx_write(chip, 0xA5, count >> 8); | 596 | snd_es18xx_write(chip, 0xA5, count >> 8); |
597 | 597 | ||
598 | #ifdef AVOID_POPS | 598 | #ifdef AVOID_POPS |
599 | udelay(100000); | 599 | mdelay(100); |
600 | #endif | 600 | #endif |
601 | 601 | ||
602 | /* Set format */ | 602 | /* Set format */ |
@@ -691,7 +691,7 @@ static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip, | |||
691 | snd_es18xx_write(chip, 0xB8, 0x05); | 691 | snd_es18xx_write(chip, 0xB8, 0x05); |
692 | #ifdef AVOID_POPS | 692 | #ifdef AVOID_POPS |
693 | /* Avoid pops */ | 693 | /* Avoid pops */ |
694 | udelay(100000); | 694 | mdelay(100); |
695 | /* Enable Audio 1 */ | 695 | /* Enable Audio 1 */ |
696 | snd_es18xx_dsp_command(chip, 0xD1); | 696 | snd_es18xx_dsp_command(chip, 0xD1); |
697 | #endif | 697 | #endif |
@@ -705,7 +705,7 @@ static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip, | |||
705 | snd_es18xx_write(chip, 0xB8, 0x00); | 705 | snd_es18xx_write(chip, 0xB8, 0x00); |
706 | #ifdef AVOID_POPS | 706 | #ifdef AVOID_POPS |
707 | /* Avoid pops */ | 707 | /* Avoid pops */ |
708 | udelay(25000); | 708 | mdelay(25); |
709 | /* Disable Audio 1 */ | 709 | /* Disable Audio 1 */ |
710 | snd_es18xx_dsp_command(chip, 0xD3); | 710 | snd_es18xx_dsp_command(chip, 0xD3); |
711 | #endif | 711 | #endif |
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 6496822c1808..1ff78ec9f0ac 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c | |||
@@ -818,12 +818,14 @@ int snd_sbmixer_new(struct snd_sb *chip) | |||
818 | return err; | 818 | return err; |
819 | break; | 819 | break; |
820 | case SB_HW_DT019X: | 820 | case SB_HW_DT019X: |
821 | if ((err = snd_sbmixer_init(chip, | 821 | err = snd_sbmixer_init(chip, |
822 | snd_dt019x_controls, | 822 | snd_dt019x_controls, |
823 | ARRAY_SIZE(snd_dt019x_controls), | 823 | ARRAY_SIZE(snd_dt019x_controls), |
824 | snd_dt019x_init_values, | 824 | snd_dt019x_init_values, |
825 | ARRAY_SIZE(snd_dt019x_init_values), | 825 | ARRAY_SIZE(snd_dt019x_init_values), |
826 | "DT019X")) < 0) | 826 | "DT019X"); |
827 | if (err < 0) | ||
828 | return err; | ||
827 | break; | 829 | break; |
828 | default: | 830 | default: |
829 | strcpy(card->mixername, "???"); | 831 | strcpy(card->mixername, "???"); |
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 248b90abb882..480bbddbd801 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
@@ -1059,24 +1059,26 @@ static void azx_init_cmd_io(struct azx *chip) | |||
1059 | 1059 | ||
1060 | /* reset the corb hw read pointer */ | 1060 | /* reset the corb hw read pointer */ |
1061 | azx_writew(chip, CORBRP, ICH6_CORBRP_RST); | 1061 | azx_writew(chip, CORBRP, ICH6_CORBRP_RST); |
1062 | for (timeout = 1000; timeout > 0; timeout--) { | 1062 | if (!(chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR)) { |
1063 | if ((azx_readw(chip, CORBRP) & ICH6_CORBRP_RST) == ICH6_CORBRP_RST) | 1063 | for (timeout = 1000; timeout > 0; timeout--) { |
1064 | break; | 1064 | if ((azx_readw(chip, CORBRP) & ICH6_CORBRP_RST) == ICH6_CORBRP_RST) |
1065 | udelay(1); | 1065 | break; |
1066 | } | 1066 | udelay(1); |
1067 | if (timeout <= 0) | 1067 | } |
1068 | dev_err(chip->card->dev, "CORB reset timeout#1, CORBRP = %d\n", | 1068 | if (timeout <= 0) |
1069 | azx_readw(chip, CORBRP)); | 1069 | dev_err(chip->card->dev, "CORB reset timeout#1, CORBRP = %d\n", |
1070 | azx_readw(chip, CORBRP)); | ||
1070 | 1071 | ||
1071 | azx_writew(chip, CORBRP, 0); | 1072 | azx_writew(chip, CORBRP, 0); |
1072 | for (timeout = 1000; timeout > 0; timeout--) { | 1073 | for (timeout = 1000; timeout > 0; timeout--) { |
1073 | if (azx_readw(chip, CORBRP) == 0) | 1074 | if (azx_readw(chip, CORBRP) == 0) |
1074 | break; | 1075 | break; |
1075 | udelay(1); | 1076 | udelay(1); |
1077 | } | ||
1078 | if (timeout <= 0) | ||
1079 | dev_err(chip->card->dev, "CORB reset timeout#2, CORBRP = %d\n", | ||
1080 | azx_readw(chip, CORBRP)); | ||
1076 | } | 1081 | } |
1077 | if (timeout <= 0) | ||
1078 | dev_err(chip->card->dev, "CORB reset timeout#2, CORBRP = %d\n", | ||
1079 | azx_readw(chip, CORBRP)); | ||
1080 | 1082 | ||
1081 | /* enable corb dma */ | 1083 | /* enable corb dma */ |
1082 | azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN); | 1084 | azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN); |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d6bca62ef387..2c54629d62d1 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -249,7 +249,8 @@ enum { | |||
249 | /* quirks for Nvidia */ | 249 | /* quirks for Nvidia */ |
250 | #define AZX_DCAPS_PRESET_NVIDIA \ | 250 | #define AZX_DCAPS_PRESET_NVIDIA \ |
251 | (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\ | 251 | (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\ |
252 | AZX_DCAPS_ALIGN_BUFSIZE | AZX_DCAPS_NO_64BIT) | 252 | AZX_DCAPS_ALIGN_BUFSIZE | AZX_DCAPS_NO_64BIT |\ |
253 | AZX_DCAPS_CORBRP_SELF_CLEAR) | ||
253 | 254 | ||
254 | #define AZX_DCAPS_PRESET_CTHDA \ | 255 | #define AZX_DCAPS_PRESET_CTHDA \ |
255 | (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_4K_BDLE_BOUNDARY) | 256 | (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_4K_BDLE_BOUNDARY) |
@@ -1366,6 +1367,12 @@ static int azx_first_init(struct azx *chip) | |||
1366 | /* initialize streams */ | 1367 | /* initialize streams */ |
1367 | azx_init_stream(chip); | 1368 | azx_init_stream(chip); |
1368 | 1369 | ||
1370 | /* workaround for Broadwell HDMI: the first stream is broken, | ||
1371 | * so mask it by keeping it as if opened | ||
1372 | */ | ||
1373 | if (pci->vendor == 0x8086 && pci->device == 0x160c) | ||
1374 | chip->azx_dev[0].opened = 1; | ||
1375 | |||
1369 | /* initialize chip */ | 1376 | /* initialize chip */ |
1370 | azx_init_pci(chip); | 1377 | azx_init_pci(chip); |
1371 | azx_init_chip(chip, (probe_only[dev] & 2) == 0); | 1378 | azx_init_chip(chip, (probe_only[dev] & 2) == 0); |
diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h index ba38b819f984..4a7cb01fa912 100644 --- a/sound/pci/hda/hda_priv.h +++ b/sound/pci/hda/hda_priv.h | |||
@@ -189,6 +189,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
189 | #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ | 189 | #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ |
190 | #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ | 190 | #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ |
191 | #define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */ | 191 | #define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */ |
192 | #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ | ||
192 | 193 | ||
193 | /* position fix mode */ | 194 | /* position fix mode */ |
194 | enum { | 195 | enum { |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 0cb5b89cd0c8..b4218a19df22 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -1127,8 +1127,10 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, | |||
1127 | AMP_OUT_UNMUTE); | 1127 | AMP_OUT_UNMUTE); |
1128 | 1128 | ||
1129 | eld = &per_pin->sink_eld; | 1129 | eld = &per_pin->sink_eld; |
1130 | if (!eld->monitor_present) | 1130 | if (!eld->monitor_present) { |
1131 | hdmi_set_channel_count(codec, per_pin->cvt_nid, channels); | ||
1131 | return; | 1132 | return; |
1133 | } | ||
1132 | 1134 | ||
1133 | if (!non_pcm && per_pin->chmap_set) | 1135 | if (!non_pcm && per_pin->chmap_set) |
1134 | ca = hdmi_manual_channel_allocation(channels, per_pin->chmap); | 1136 | ca = hdmi_manual_channel_allocation(channels, per_pin->chmap); |
@@ -3330,6 +3332,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
3330 | { .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_nvhdmi }, | 3332 | { .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_nvhdmi }, |
3331 | { .id = 0x10de0060, .name = "GPU 60 HDMI/DP", .patch = patch_nvhdmi }, | 3333 | { .id = 0x10de0060, .name = "GPU 60 HDMI/DP", .patch = patch_nvhdmi }, |
3332 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, | 3334 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, |
3335 | { .id = 0x10de0071, .name = "GPU 71 HDMI/DP", .patch = patch_nvhdmi }, | ||
3333 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, | 3336 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, |
3334 | { .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, | 3337 | { .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, |
3335 | { .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, | 3338 | { .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, |
@@ -3385,6 +3388,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0044"); | |||
3385 | MODULE_ALIAS("snd-hda-codec-id:10de0051"); | 3388 | MODULE_ALIAS("snd-hda-codec-id:10de0051"); |
3386 | MODULE_ALIAS("snd-hda-codec-id:10de0060"); | 3389 | MODULE_ALIAS("snd-hda-codec-id:10de0060"); |
3387 | MODULE_ALIAS("snd-hda-codec-id:10de0067"); | 3390 | MODULE_ALIAS("snd-hda-codec-id:10de0067"); |
3391 | MODULE_ALIAS("snd-hda-codec-id:10de0071"); | ||
3388 | MODULE_ALIAS("snd-hda-codec-id:10de8001"); | 3392 | MODULE_ALIAS("snd-hda-codec-id:10de8001"); |
3389 | MODULE_ALIAS("snd-hda-codec-id:11069f80"); | 3393 | MODULE_ALIAS("snd-hda-codec-id:11069f80"); |
3390 | MODULE_ALIAS("snd-hda-codec-id:11069f81"); | 3394 | MODULE_ALIAS("snd-hda-codec-id:11069f81"); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 14ae979a92ea..49e884fb3e5d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -4616,11 +4616,17 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4616 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4616 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4617 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4617 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4618 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4618 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4619 | SND_PCI_QUIRK(0x1028, 0x065c, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4619 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4620 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4620 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4621 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4621 | SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4622 | SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4622 | SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), | 4623 | SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), |
4623 | SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), | 4624 | SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), |
4625 | SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4626 | SND_PCI_QUIRK(0x1028, 0x067e, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4627 | SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4628 | SND_PCI_QUIRK(0x1028, 0x0680, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4629 | SND_PCI_QUIRK(0x1028, 0x0684, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
4624 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4630 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4625 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4631 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4626 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 4632 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
@@ -4912,6 +4918,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
4912 | spec->codec_variant = ALC269_TYPE_ALC285; | 4918 | spec->codec_variant = ALC269_TYPE_ALC285; |
4913 | break; | 4919 | break; |
4914 | case 0x10ec0286: | 4920 | case 0x10ec0286: |
4921 | case 0x10ec0288: | ||
4915 | spec->codec_variant = ALC269_TYPE_ALC286; | 4922 | spec->codec_variant = ALC269_TYPE_ALC286; |
4916 | break; | 4923 | break; |
4917 | case 0x10ec0255: | 4924 | case 0x10ec0255: |
@@ -5539,6 +5546,8 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { | |||
5539 | SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5546 | SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5540 | SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5547 | SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5541 | SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5548 | SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5549 | SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | ||
5550 | SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | ||
5542 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 5551 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
5543 | SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), | 5552 | SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), |
5544 | SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), | 5553 | SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), |
@@ -5781,6 +5790,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
5781 | { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, | 5790 | { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, |
5782 | { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, | 5791 | { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, |
5783 | { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, | 5792 | { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, |
5793 | { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, | ||
5784 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, | 5794 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, |
5785 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, | 5795 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, |
5786 | { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, | 5796 | { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, |
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index f500905e9373..2acf82f4a08a 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c | |||
@@ -1018,13 +1018,13 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
1018 | dev_err(&client->dev, "failed to read vendor ID1: %d\n", ret); | 1018 | dev_err(&client->dev, "failed to read vendor ID1: %d\n", ret); |
1019 | return ret; | 1019 | return ret; |
1020 | } | 1020 | } |
1021 | vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); | ||
1022 | 1021 | ||
1023 | ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID2, &vid2); | 1022 | ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID2, &vid2); |
1024 | if (ret < 0) { | 1023 | if (ret < 0) { |
1025 | dev_err(&client->dev, "failed to read vendor ID2: %d\n", ret); | 1024 | dev_err(&client->dev, "failed to read vendor ID2: %d\n", ret); |
1026 | return ret; | 1025 | return ret; |
1027 | } | 1026 | } |
1027 | vid2 >>= 8; | ||
1028 | 1028 | ||
1029 | if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { | 1029 | if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { |
1030 | dev_err(&client->dev, "unknown or wrong codec\n"); | 1030 | dev_err(&client->dev, "unknown or wrong codec\n"); |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 460d35547a68..2213a037c893 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -1229,8 +1229,10 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, | |||
1229 | } | 1229 | } |
1230 | 1230 | ||
1231 | if (cs42l52->pdata.reset_gpio) { | 1231 | if (cs42l52->pdata.reset_gpio) { |
1232 | ret = gpio_request_one(cs42l52->pdata.reset_gpio, | 1232 | ret = devm_gpio_request_one(&i2c_client->dev, |
1233 | GPIOF_OUT_INIT_HIGH, "CS42L52 /RST"); | 1233 | cs42l52->pdata.reset_gpio, |
1234 | GPIOF_OUT_INIT_HIGH, | ||
1235 | "CS42L52 /RST"); | ||
1234 | if (ret < 0) { | 1236 | if (ret < 0) { |
1235 | dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n", | 1237 | dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n", |
1236 | cs42l52->pdata.reset_gpio, ret); | 1238 | cs42l52->pdata.reset_gpio, ret); |
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 0ee60a19a263..ae3717992d56 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -1443,8 +1443,10 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1443 | i2c_set_clientdata(i2c_client, cs42l73); | 1443 | i2c_set_clientdata(i2c_client, cs42l73); |
1444 | 1444 | ||
1445 | if (cs42l73->pdata.reset_gpio) { | 1445 | if (cs42l73->pdata.reset_gpio) { |
1446 | ret = gpio_request_one(cs42l73->pdata.reset_gpio, | 1446 | ret = devm_gpio_request_one(&i2c_client->dev, |
1447 | GPIOF_OUT_INIT_HIGH, "CS42L73 /RST"); | 1447 | cs42l73->pdata.reset_gpio, |
1448 | GPIOF_OUT_INIT_HIGH, | ||
1449 | "CS42L73 /RST"); | ||
1448 | if (ret < 0) { | 1450 | if (ret < 0) { |
1449 | dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n", | 1451 | dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n", |
1450 | cs42l73->pdata.reset_gpio, ret); | 1452 | cs42l73->pdata.reset_gpio, ret); |
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index fa158cfe9b32..d1929de641e2 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c | |||
@@ -376,7 +376,7 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, | |||
376 | reg = AIC31XX_ADCFLAG; | 376 | reg = AIC31XX_ADCFLAG; |
377 | break; | 377 | break; |
378 | default: | 378 | default: |
379 | dev_err(w->codec->dev, "Unknown widget '%s' calling %s/n", | 379 | dev_err(w->codec->dev, "Unknown widget '%s' calling %s\n", |
380 | w->name, __func__); | 380 | w->name, __func__); |
381 | return -EINVAL; | 381 | return -EINVAL; |
382 | } | 382 | } |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index b1835103e9b4..d7349bc89ad3 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -1399,7 +1399,6 @@ static int aic3x_probe(struct snd_soc_codec *codec) | |||
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | aic3x_add_widgets(codec); | 1401 | aic3x_add_widgets(codec); |
1402 | list_add(&aic3x->list, &reset_list); | ||
1403 | 1402 | ||
1404 | return 0; | 1403 | return 0; |
1405 | 1404 | ||
@@ -1569,7 +1568,13 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
1569 | 1568 | ||
1570 | ret = snd_soc_register_codec(&i2c->dev, | 1569 | ret = snd_soc_register_codec(&i2c->dev, |
1571 | &soc_codec_dev_aic3x, &aic3x_dai, 1); | 1570 | &soc_codec_dev_aic3x, &aic3x_dai, 1); |
1572 | return ret; | 1571 | |
1572 | if (ret != 0) | ||
1573 | goto err_gpio; | ||
1574 | |||
1575 | list_add(&aic3x->list, &reset_list); | ||
1576 | |||
1577 | return 0; | ||
1573 | 1578 | ||
1574 | err_gpio: | 1579 | err_gpio: |
1575 | if (gpio_is_valid(aic3x->gpio_reset) && | 1580 | if (gpio_is_valid(aic3x->gpio_reset) && |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 5522d2566c67..ecd26dd2e442 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -154,6 +154,7 @@ static struct reg_default wm8962_reg[] = { | |||
154 | { 40, 0x0000 }, /* R40 - SPKOUTL volume */ | 154 | { 40, 0x0000 }, /* R40 - SPKOUTL volume */ |
155 | { 41, 0x0000 }, /* R41 - SPKOUTR volume */ | 155 | { 41, 0x0000 }, /* R41 - SPKOUTR volume */ |
156 | 156 | ||
157 | { 49, 0x0010 }, /* R49 - Class D Control 1 */ | ||
157 | { 51, 0x0003 }, /* R51 - Class D Control 2 */ | 158 | { 51, 0x0003 }, /* R51 - Class D Control 2 */ |
158 | 159 | ||
159 | { 56, 0x0506 }, /* R56 - Clocking 4 */ | 160 | { 56, 0x0506 }, /* R56 - Clocking 4 */ |
@@ -795,7 +796,6 @@ static bool wm8962_volatile_register(struct device *dev, unsigned int reg) | |||
795 | case WM8962_ALC2: | 796 | case WM8962_ALC2: |
796 | case WM8962_THERMAL_SHUTDOWN_STATUS: | 797 | case WM8962_THERMAL_SHUTDOWN_STATUS: |
797 | case WM8962_ADDITIONAL_CONTROL_4: | 798 | case WM8962_ADDITIONAL_CONTROL_4: |
798 | case WM8962_CLASS_D_CONTROL_1: | ||
799 | case WM8962_DC_SERVO_6: | 799 | case WM8962_DC_SERVO_6: |
800 | case WM8962_INTERRUPT_STATUS_1: | 800 | case WM8962_INTERRUPT_STATUS_1: |
801 | case WM8962_INTERRUPT_STATUS_2: | 801 | case WM8962_INTERRUPT_STATUS_2: |
@@ -2929,13 +2929,22 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
2929 | static int wm8962_mute(struct snd_soc_dai *dai, int mute) | 2929 | static int wm8962_mute(struct snd_soc_dai *dai, int mute) |
2930 | { | 2930 | { |
2931 | struct snd_soc_codec *codec = dai->codec; | 2931 | struct snd_soc_codec *codec = dai->codec; |
2932 | int val; | 2932 | int val, ret; |
2933 | 2933 | ||
2934 | if (mute) | 2934 | if (mute) |
2935 | val = WM8962_DAC_MUTE; | 2935 | val = WM8962_DAC_MUTE | WM8962_DAC_MUTE_ALT; |
2936 | else | 2936 | else |
2937 | val = 0; | 2937 | val = 0; |
2938 | 2938 | ||
2939 | /** | ||
2940 | * The DAC mute bit is mirrored in two registers, update both to keep | ||
2941 | * the register cache consistent. | ||
2942 | */ | ||
2943 | ret = snd_soc_update_bits(codec, WM8962_CLASS_D_CONTROL_1, | ||
2944 | WM8962_DAC_MUTE_ALT, val); | ||
2945 | if (ret < 0) | ||
2946 | return ret; | ||
2947 | |||
2939 | return snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1, | 2948 | return snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1, |
2940 | WM8962_DAC_MUTE, val); | 2949 | WM8962_DAC_MUTE, val); |
2941 | } | 2950 | } |
diff --git a/sound/soc/codecs/wm8962.h b/sound/soc/codecs/wm8962.h index a1a5d5294c19..910aafd09d21 100644 --- a/sound/soc/codecs/wm8962.h +++ b/sound/soc/codecs/wm8962.h | |||
@@ -1954,6 +1954,10 @@ | |||
1954 | #define WM8962_SPKOUTL_ENA_MASK 0x0040 /* SPKOUTL_ENA */ | 1954 | #define WM8962_SPKOUTL_ENA_MASK 0x0040 /* SPKOUTL_ENA */ |
1955 | #define WM8962_SPKOUTL_ENA_SHIFT 6 /* SPKOUTL_ENA */ | 1955 | #define WM8962_SPKOUTL_ENA_SHIFT 6 /* SPKOUTL_ENA */ |
1956 | #define WM8962_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */ | 1956 | #define WM8962_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */ |
1957 | #define WM8962_DAC_MUTE_ALT 0x0010 /* DAC_MUTE */ | ||
1958 | #define WM8962_DAC_MUTE_ALT_MASK 0x0010 /* DAC_MUTE */ | ||
1959 | #define WM8962_DAC_MUTE_ALT_SHIFT 4 /* DAC_MUTE */ | ||
1960 | #define WM8962_DAC_MUTE_ALT_WIDTH 1 /* DAC_MUTE */ | ||
1957 | #define WM8962_SPKOUTL_PGA_MUTE 0x0002 /* SPKOUTL_PGA_MUTE */ | 1961 | #define WM8962_SPKOUTL_PGA_MUTE 0x0002 /* SPKOUTL_PGA_MUTE */ |
1958 | #define WM8962_SPKOUTL_PGA_MUTE_MASK 0x0002 /* SPKOUTL_PGA_MUTE */ | 1962 | #define WM8962_SPKOUTL_PGA_MUTE_MASK 0x0002 /* SPKOUTL_PGA_MUTE */ |
1959 | #define WM8962_SPKOUTL_PGA_MUTE_SHIFT 1 /* SPKOUTL_PGA_MUTE */ | 1963 | #define WM8962_SPKOUTL_PGA_MUTE_SHIFT 1 /* SPKOUTL_PGA_MUTE */ |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index c8e5db1414d7..496ce2eb2f1f 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -258,10 +258,16 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
258 | return -EINVAL; | 258 | return -EINVAL; |
259 | } | 259 | } |
260 | 260 | ||
261 | if (ratio == 1) { | 261 | /* Only EXTAL source can be output directly without using PSR and PM */ |
262 | if (ratio == 1 && clksrc == esai_priv->extalclk) { | ||
262 | /* Bypass all the dividers if not being needed */ | 263 | /* Bypass all the dividers if not being needed */ |
263 | ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO; | 264 | ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO; |
264 | goto out; | 265 | goto out; |
266 | } else if (ratio < 2) { | ||
267 | /* The ratio should be no less than 2 if using other sources */ | ||
268 | dev_err(dai->dev, "failed to derive required HCK%c rate\n", | ||
269 | tx ? 'T' : 'R'); | ||
270 | return -EINVAL; | ||
265 | } | 271 | } |
266 | 272 | ||
267 | ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0); | 273 | ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0); |
@@ -307,7 +313,8 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) | |||
307 | return -EINVAL; | 313 | return -EINVAL; |
308 | } | 314 | } |
309 | 315 | ||
310 | if (esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) { | 316 | /* The ratio should be contented by FP alone if bypassing PM and PSR */ |
317 | if (!esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) { | ||
311 | dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n"); | 318 | dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n"); |
312 | return -EINVAL; | 319 | return -EINVAL; |
313 | } | 320 | } |
@@ -454,12 +461,6 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream, | |||
454 | } | 461 | } |
455 | 462 | ||
456 | if (!dai->active) { | 463 | if (!dai->active) { |
457 | /* Reset Port C */ | ||
458 | regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC, | ||
459 | ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO)); | ||
460 | regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC, | ||
461 | ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO)); | ||
462 | |||
463 | /* Set synchronous mode */ | 464 | /* Set synchronous mode */ |
464 | regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR, | 465 | regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR, |
465 | ESAI_SAICR_SYNC, esai_priv->synchronous ? | 466 | ESAI_SAICR_SYNC, esai_priv->synchronous ? |
@@ -519,6 +520,11 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, | |||
519 | 520 | ||
520 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val); | 521 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val); |
521 | 522 | ||
523 | /* Remove ESAI personal reset by configuring ESAI_PCRC and ESAI_PRRC */ | ||
524 | regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC, | ||
525 | ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO)); | ||
526 | regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC, | ||
527 | ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO)); | ||
522 | return 0; | 528 | return 0; |
523 | } | 529 | } |
524 | 530 | ||
diff --git a/sound/soc/fsl/fsl_spdif.h b/sound/soc/fsl/fsl_spdif.h index b1266790d117..605a10b2112b 100644 --- a/sound/soc/fsl/fsl_spdif.h +++ b/sound/soc/fsl/fsl_spdif.h | |||
@@ -144,8 +144,8 @@ enum spdif_gainsel { | |||
144 | 144 | ||
145 | /* SPDIF Clock register */ | 145 | /* SPDIF Clock register */ |
146 | #define STC_SYSCLK_DIV_OFFSET 11 | 146 | #define STC_SYSCLK_DIV_OFFSET 11 |
147 | #define STC_SYSCLK_DIV_MASK (0x1ff << STC_TXCLK_SRC_OFFSET) | 147 | #define STC_SYSCLK_DIV_MASK (0x1ff << STC_SYSCLK_DIV_OFFSET) |
148 | #define STC_SYSCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_SYSCLK_DIV_MASK) | 148 | #define STC_SYSCLK_DIV(x) ((((x) - 1) << STC_SYSCLK_DIV_OFFSET) & STC_SYSCLK_DIV_MASK) |
149 | #define STC_TXCLK_SRC_OFFSET 8 | 149 | #define STC_TXCLK_SRC_OFFSET 8 |
150 | #define STC_TXCLK_SRC_MASK (0x7 << STC_TXCLK_SRC_OFFSET) | 150 | #define STC_TXCLK_SRC_MASK (0x7 << STC_TXCLK_SRC_OFFSET) |
151 | #define STC_TXCLK_SRC_SET(x) ((x << STC_TXCLK_SRC_OFFSET) & STC_TXCLK_SRC_MASK) | 151 | #define STC_TXCLK_SRC_SET(x) ((x << STC_TXCLK_SRC_OFFSET) & STC_TXCLK_SRC_MASK) |
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index ac869931d7f1..267717aa96c1 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c | |||
@@ -145,7 +145,7 @@ static const struct file_operations audmux_debugfs_fops = { | |||
145 | .llseek = default_llseek, | 145 | .llseek = default_llseek, |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static void __init audmux_debugfs_init(void) | 148 | static void audmux_debugfs_init(void) |
149 | { | 149 | { |
150 | int i; | 150 | int i; |
151 | char buf[20]; | 151 | char buf[20]; |
diff --git a/sound/soc/intel/sst-acpi.c b/sound/soc/intel/sst-acpi.c index 5d06eecb6198..18aee77f8d4a 100644 --- a/sound/soc/intel/sst-acpi.c +++ b/sound/soc/intel/sst-acpi.c | |||
@@ -138,6 +138,7 @@ static int sst_acpi_probe(struct platform_device *pdev) | |||
138 | 138 | ||
139 | sst_pdata = &sst_acpi->sst_pdata; | 139 | sst_pdata = &sst_acpi->sst_pdata; |
140 | sst_pdata->id = desc->sst_id; | 140 | sst_pdata->id = desc->sst_id; |
141 | sst_pdata->dma_dev = dev; | ||
141 | sst_acpi->desc = desc; | 142 | sst_acpi->desc = desc; |
142 | sst_acpi->mach = mach; | 143 | sst_acpi->mach = mach; |
143 | 144 | ||
diff --git a/sound/soc/intel/sst-baytrail-dsp.c b/sound/soc/intel/sst-baytrail-dsp.c index a50bf7fc0e3a..adf0aca5aca6 100644 --- a/sound/soc/intel/sst-baytrail-dsp.c +++ b/sound/soc/intel/sst-baytrail-dsp.c | |||
@@ -324,7 +324,7 @@ static int sst_byt_init(struct sst_dsp *sst, struct sst_pdata *pdata) | |||
324 | memcpy_toio(sst->addr.lpe + SST_BYT_MAILBOX_OFFSET, | 324 | memcpy_toio(sst->addr.lpe + SST_BYT_MAILBOX_OFFSET, |
325 | &pdata->fw_base, sizeof(u32)); | 325 | &pdata->fw_base, sizeof(u32)); |
326 | 326 | ||
327 | ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); | 327 | ret = dma_coerce_mask_and_coherent(sst->dma_dev, DMA_BIT_MASK(32)); |
328 | if (ret) | 328 | if (ret) |
329 | return ret; | 329 | return ret; |
330 | 330 | ||
diff --git a/sound/soc/intel/sst-baytrail-ipc.c b/sound/soc/intel/sst-baytrail-ipc.c index d0eaeee21be4..0d31dbbf4806 100644 --- a/sound/soc/intel/sst-baytrail-ipc.c +++ b/sound/soc/intel/sst-baytrail-ipc.c | |||
@@ -542,16 +542,20 @@ struct sst_byt_stream *sst_byt_stream_new(struct sst_byt *byt, int id, | |||
542 | void *data) | 542 | void *data) |
543 | { | 543 | { |
544 | struct sst_byt_stream *stream; | 544 | struct sst_byt_stream *stream; |
545 | struct sst_dsp *sst = byt->dsp; | ||
546 | unsigned long flags; | ||
545 | 547 | ||
546 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | 548 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); |
547 | if (stream == NULL) | 549 | if (stream == NULL) |
548 | return NULL; | 550 | return NULL; |
549 | 551 | ||
552 | spin_lock_irqsave(&sst->spinlock, flags); | ||
550 | list_add(&stream->node, &byt->stream_list); | 553 | list_add(&stream->node, &byt->stream_list); |
551 | stream->notify_position = notify_position; | 554 | stream->notify_position = notify_position; |
552 | stream->pdata = data; | 555 | stream->pdata = data; |
553 | stream->byt = byt; | 556 | stream->byt = byt; |
554 | stream->str_id = id; | 557 | stream->str_id = id; |
558 | spin_unlock_irqrestore(&sst->spinlock, flags); | ||
555 | 559 | ||
556 | return stream; | 560 | return stream; |
557 | } | 561 | } |
@@ -630,6 +634,8 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream) | |||
630 | { | 634 | { |
631 | u64 header; | 635 | u64 header; |
632 | int ret = 0; | 636 | int ret = 0; |
637 | struct sst_dsp *sst = byt->dsp; | ||
638 | unsigned long flags; | ||
633 | 639 | ||
634 | if (!stream->commited) | 640 | if (!stream->commited) |
635 | goto out; | 641 | goto out; |
@@ -644,8 +650,10 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream) | |||
644 | 650 | ||
645 | stream->commited = false; | 651 | stream->commited = false; |
646 | out: | 652 | out: |
653 | spin_lock_irqsave(&sst->spinlock, flags); | ||
647 | list_del(&stream->node); | 654 | list_del(&stream->node); |
648 | kfree(stream); | 655 | kfree(stream); |
656 | spin_unlock_irqrestore(&sst->spinlock, flags); | ||
649 | 657 | ||
650 | return ret; | 658 | return ret; |
651 | } | 659 | } |
diff --git a/sound/soc/intel/sst-dsp-priv.h b/sound/soc/intel/sst-dsp-priv.h index fe8e81aad646..401213455497 100644 --- a/sound/soc/intel/sst-dsp-priv.h +++ b/sound/soc/intel/sst-dsp-priv.h | |||
@@ -136,7 +136,7 @@ struct sst_module_data { | |||
136 | enum sst_data_type data_type; /* type of module data */ | 136 | enum sst_data_type data_type; /* type of module data */ |
137 | 137 | ||
138 | u32 size; /* size in bytes */ | 138 | u32 size; /* size in bytes */ |
139 | u32 offset; /* offset in FW file */ | 139 | int32_t offset; /* offset in FW file */ |
140 | u32 data_offset; /* offset in ADSP memory space */ | 140 | u32 data_offset; /* offset in ADSP memory space */ |
141 | void *data; /* module data */ | 141 | void *data; /* module data */ |
142 | }; | 142 | }; |
@@ -228,6 +228,7 @@ struct sst_dsp { | |||
228 | spinlock_t spinlock; /* IPC locking */ | 228 | spinlock_t spinlock; /* IPC locking */ |
229 | struct mutex mutex; /* DSP FW lock */ | 229 | struct mutex mutex; /* DSP FW lock */ |
230 | struct device *dev; | 230 | struct device *dev; |
231 | struct device *dma_dev; | ||
231 | void *thread_context; | 232 | void *thread_context; |
232 | int irq; | 233 | int irq; |
233 | u32 id; | 234 | u32 id; |
diff --git a/sound/soc/intel/sst-dsp.c b/sound/soc/intel/sst-dsp.c index 0c129fd85ecf..0b715b20a2d7 100644 --- a/sound/soc/intel/sst-dsp.c +++ b/sound/soc/intel/sst-dsp.c | |||
@@ -337,6 +337,7 @@ struct sst_dsp *sst_dsp_new(struct device *dev, | |||
337 | spin_lock_init(&sst->spinlock); | 337 | spin_lock_init(&sst->spinlock); |
338 | mutex_init(&sst->mutex); | 338 | mutex_init(&sst->mutex); |
339 | sst->dev = dev; | 339 | sst->dev = dev; |
340 | sst->dma_dev = pdata->dma_dev; | ||
340 | sst->thread_context = sst_dev->thread_context; | 341 | sst->thread_context = sst_dev->thread_context; |
341 | sst->sst_dev = sst_dev; | 342 | sst->sst_dev = sst_dev; |
342 | sst->id = pdata->id; | 343 | sst->id = pdata->id; |
diff --git a/sound/soc/intel/sst-dsp.h b/sound/soc/intel/sst-dsp.h index 74052b59485c..e44423be66c4 100644 --- a/sound/soc/intel/sst-dsp.h +++ b/sound/soc/intel/sst-dsp.h | |||
@@ -169,6 +169,7 @@ struct sst_pdata { | |||
169 | u32 dma_base; | 169 | u32 dma_base; |
170 | u32 dma_size; | 170 | u32 dma_size; |
171 | int dma_engine; | 171 | int dma_engine; |
172 | struct device *dma_dev; | ||
172 | 173 | ||
173 | /* DSP */ | 174 | /* DSP */ |
174 | u32 id; | 175 | u32 id; |
diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index f7687107cf7f..928f228c38e7 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c | |||
@@ -57,14 +57,8 @@ struct sst_fw *sst_fw_new(struct sst_dsp *dsp, | |||
57 | sst_fw->private = private; | 57 | sst_fw->private = private; |
58 | sst_fw->size = fw->size; | 58 | sst_fw->size = fw->size; |
59 | 59 | ||
60 | err = dma_coerce_mask_and_coherent(dsp->dev, DMA_BIT_MASK(32)); | ||
61 | if (err < 0) { | ||
62 | kfree(sst_fw); | ||
63 | return NULL; | ||
64 | } | ||
65 | |||
66 | /* allocate DMA buffer to store FW data */ | 60 | /* allocate DMA buffer to store FW data */ |
67 | sst_fw->dma_buf = dma_alloc_coherent(dsp->dev, sst_fw->size, | 61 | sst_fw->dma_buf = dma_alloc_coherent(dsp->dma_dev, sst_fw->size, |
68 | &sst_fw->dmable_fw_paddr, GFP_DMA | GFP_KERNEL); | 62 | &sst_fw->dmable_fw_paddr, GFP_DMA | GFP_KERNEL); |
69 | if (!sst_fw->dma_buf) { | 63 | if (!sst_fw->dma_buf) { |
70 | dev_err(dsp->dev, "error: DMA alloc failed\n"); | 64 | dev_err(dsp->dev, "error: DMA alloc failed\n"); |
@@ -106,7 +100,7 @@ void sst_fw_free(struct sst_fw *sst_fw) | |||
106 | list_del(&sst_fw->list); | 100 | list_del(&sst_fw->list); |
107 | mutex_unlock(&dsp->mutex); | 101 | mutex_unlock(&dsp->mutex); |
108 | 102 | ||
109 | dma_free_coherent(dsp->dev, sst_fw->size, sst_fw->dma_buf, | 103 | dma_free_coherent(dsp->dma_dev, sst_fw->size, sst_fw->dma_buf, |
110 | sst_fw->dmable_fw_paddr); | 104 | sst_fw->dmable_fw_paddr); |
111 | kfree(sst_fw); | 105 | kfree(sst_fw); |
112 | } | 106 | } |
@@ -202,6 +196,9 @@ static int block_alloc_contiguous(struct sst_module *module, | |||
202 | size -= block->size; | 196 | size -= block->size; |
203 | } | 197 | } |
204 | 198 | ||
199 | list_for_each_entry(block, &tmp, list) | ||
200 | list_add(&block->module_list, &module->block_list); | ||
201 | |||
205 | list_splice(&tmp, &dsp->used_block_list); | 202 | list_splice(&tmp, &dsp->used_block_list); |
206 | return 0; | 203 | return 0; |
207 | } | 204 | } |
@@ -247,8 +244,7 @@ static int block_alloc(struct sst_module *module, | |||
247 | /* do we span > 1 blocks */ | 244 | /* do we span > 1 blocks */ |
248 | if (data->size > block->size) { | 245 | if (data->size > block->size) { |
249 | ret = block_alloc_contiguous(module, data, | 246 | ret = block_alloc_contiguous(module, data, |
250 | block->offset + block->size, | 247 | block->offset, data->size); |
251 | data->size - block->size); | ||
252 | if (ret == 0) | 248 | if (ret == 0) |
253 | return ret; | 249 | return ret; |
254 | } | 250 | } |
@@ -344,7 +340,7 @@ static int block_alloc_fixed(struct sst_module *module, | |||
344 | 340 | ||
345 | err = block_alloc_contiguous(module, data, | 341 | err = block_alloc_contiguous(module, data, |
346 | block->offset + block->size, | 342 | block->offset + block->size, |
347 | data->size - block->size + data->offset - block->offset); | 343 | data->size - block->size); |
348 | if (err < 0) | 344 | if (err < 0) |
349 | return -ENOMEM; | 345 | return -ENOMEM; |
350 | 346 | ||
@@ -371,15 +367,10 @@ static int block_alloc_fixed(struct sst_module *module, | |||
371 | if (data->offset >= block->offset && data->offset < block_end) { | 367 | if (data->offset >= block->offset && data->offset < block_end) { |
372 | 368 | ||
373 | err = block_alloc_contiguous(module, data, | 369 | err = block_alloc_contiguous(module, data, |
374 | block->offset + block->size, | 370 | block->offset, data->size); |
375 | data->size - block->size); | ||
376 | if (err < 0) | 371 | if (err < 0) |
377 | return -ENOMEM; | 372 | return -ENOMEM; |
378 | 373 | ||
379 | /* add block */ | ||
380 | block->data_type = data->data_type; | ||
381 | list_move(&block->list, &dsp->used_block_list); | ||
382 | list_add(&block->module_list, &module->block_list); | ||
383 | return 0; | 374 | return 0; |
384 | } | 375 | } |
385 | 376 | ||
diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c index f5ebf36af889..535f517629fd 100644 --- a/sound/soc/intel/sst-haswell-dsp.c +++ b/sound/soc/intel/sst-haswell-dsp.c | |||
@@ -433,7 +433,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata) | |||
433 | int ret = -ENODEV, i, j, region_count; | 433 | int ret = -ENODEV, i, j, region_count; |
434 | u32 offset, size; | 434 | u32 offset, size; |
435 | 435 | ||
436 | dev = sst->dev; | 436 | dev = sst->dma_dev; |
437 | 437 | ||
438 | switch (sst->id) { | 438 | switch (sst->id) { |
439 | case SST_DEV_ID_LYNX_POINT: | 439 | case SST_DEV_ID_LYNX_POINT: |
@@ -466,7 +466,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata) | |||
466 | return ret; | 466 | return ret; |
467 | } | 467 | } |
468 | 468 | ||
469 | ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); | 469 | ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(31)); |
470 | if (ret) | 470 | if (ret) |
471 | return ret; | 471 | return ret; |
472 | 472 | ||
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index f46bb4ddde6f..e7996b39a484 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c | |||
@@ -617,7 +617,7 @@ static void hsw_notification_work(struct work_struct *work) | |||
617 | case IPC_POSITION_CHANGED: | 617 | case IPC_POSITION_CHANGED: |
618 | trace_ipc_notification("DSP stream position changed for", | 618 | trace_ipc_notification("DSP stream position changed for", |
619 | stream->reply.stream_hw_id); | 619 | stream->reply.stream_hw_id); |
620 | sst_dsp_inbox_read(hsw->dsp, pos, sizeof(pos)); | 620 | sst_dsp_inbox_read(hsw->dsp, pos, sizeof(*pos)); |
621 | 621 | ||
622 | if (stream->notify_position) | 622 | if (stream->notify_position) |
623 | stream->notify_position(stream, stream->pdata); | 623 | stream->notify_position(stream, stream->pdata); |
@@ -991,7 +991,8 @@ int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream | |||
991 | return -EINVAL; | 991 | return -EINVAL; |
992 | 992 | ||
993 | sst_dsp_read(hsw->dsp, volume, | 993 | sst_dsp_read(hsw->dsp, volume, |
994 | stream->reply.volume_register_address[channel], sizeof(volume)); | 994 | stream->reply.volume_register_address[channel], |
995 | sizeof(*volume)); | ||
995 | 996 | ||
996 | return 0; | 997 | return 0; |
997 | } | 998 | } |
@@ -1158,11 +1159,14 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id, | |||
1158 | void *data) | 1159 | void *data) |
1159 | { | 1160 | { |
1160 | struct sst_hsw_stream *stream; | 1161 | struct sst_hsw_stream *stream; |
1162 | struct sst_dsp *sst = hsw->dsp; | ||
1163 | unsigned long flags; | ||
1161 | 1164 | ||
1162 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | 1165 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); |
1163 | if (stream == NULL) | 1166 | if (stream == NULL) |
1164 | return NULL; | 1167 | return NULL; |
1165 | 1168 | ||
1169 | spin_lock_irqsave(&sst->spinlock, flags); | ||
1166 | list_add(&stream->node, &hsw->stream_list); | 1170 | list_add(&stream->node, &hsw->stream_list); |
1167 | stream->notify_position = notify_position; | 1171 | stream->notify_position = notify_position; |
1168 | stream->pdata = data; | 1172 | stream->pdata = data; |
@@ -1171,6 +1175,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id, | |||
1171 | 1175 | ||
1172 | /* work to process notification messages */ | 1176 | /* work to process notification messages */ |
1173 | INIT_WORK(&stream->notify_work, hsw_notification_work); | 1177 | INIT_WORK(&stream->notify_work, hsw_notification_work); |
1178 | spin_unlock_irqrestore(&sst->spinlock, flags); | ||
1174 | 1179 | ||
1175 | return stream; | 1180 | return stream; |
1176 | } | 1181 | } |
@@ -1179,6 +1184,8 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1179 | { | 1184 | { |
1180 | u32 header; | 1185 | u32 header; |
1181 | int ret = 0; | 1186 | int ret = 0; |
1187 | struct sst_dsp *sst = hsw->dsp; | ||
1188 | unsigned long flags; | ||
1182 | 1189 | ||
1183 | /* dont free DSP streams that are not commited */ | 1190 | /* dont free DSP streams that are not commited */ |
1184 | if (!stream->commited) | 1191 | if (!stream->commited) |
@@ -1200,8 +1207,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1200 | trace_hsw_stream_free_req(stream, &stream->free_req); | 1207 | trace_hsw_stream_free_req(stream, &stream->free_req); |
1201 | 1208 | ||
1202 | out: | 1209 | out: |
1210 | cancel_work_sync(&stream->notify_work); | ||
1211 | spin_lock_irqsave(&sst->spinlock, flags); | ||
1203 | list_del(&stream->node); | 1212 | list_del(&stream->node); |
1204 | kfree(stream); | 1213 | kfree(stream); |
1214 | spin_unlock_irqrestore(&sst->spinlock, flags); | ||
1205 | 1215 | ||
1206 | return ret; | 1216 | return ret; |
1207 | } | 1217 | } |
@@ -1537,10 +1547,28 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1537 | } | 1547 | } |
1538 | 1548 | ||
1539 | /* Stream pointer positions */ | 1549 | /* Stream pointer positions */ |
1540 | int sst_hsw_get_dsp_position(struct sst_hsw *hsw, | 1550 | u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw, |
1541 | struct sst_hsw_stream *stream) | 1551 | struct sst_hsw_stream *stream) |
1542 | { | 1552 | { |
1543 | return stream->rpos.position; | 1553 | u32 rpos; |
1554 | |||
1555 | sst_dsp_read(hsw->dsp, &rpos, | ||
1556 | stream->reply.read_position_register_address, sizeof(rpos)); | ||
1557 | |||
1558 | return rpos; | ||
1559 | } | ||
1560 | |||
1561 | /* Stream presentation (monotonic) positions */ | ||
1562 | u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw, | ||
1563 | struct sst_hsw_stream *stream) | ||
1564 | { | ||
1565 | u64 ppos; | ||
1566 | |||
1567 | sst_dsp_read(hsw->dsp, &ppos, | ||
1568 | stream->reply.presentation_position_register_address, | ||
1569 | sizeof(ppos)); | ||
1570 | |||
1571 | return ppos; | ||
1544 | } | 1572 | } |
1545 | 1573 | ||
1546 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, | 1574 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, |
@@ -1609,7 +1637,7 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw, | |||
1609 | trace_ipc_request("PM enter Dx state", state); | 1637 | trace_ipc_request("PM enter Dx state", state); |
1610 | 1638 | ||
1611 | ret = ipc_tx_message_wait(hsw, header, &state_, sizeof(state_), | 1639 | ret = ipc_tx_message_wait(hsw, header, &state_, sizeof(state_), |
1612 | dx, sizeof(dx)); | 1640 | dx, sizeof(*dx)); |
1613 | if (ret < 0) { | 1641 | if (ret < 0) { |
1614 | dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); | 1642 | dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); |
1615 | return ret; | 1643 | return ret; |
diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h index d517929ccc38..2ac194a6d04b 100644 --- a/sound/soc/intel/sst-haswell-ipc.h +++ b/sound/soc/intel/sst-haswell-ipc.h | |||
@@ -464,7 +464,9 @@ int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw, | |||
464 | struct sst_hsw_stream *stream, u32 *position); | 464 | struct sst_hsw_stream *stream, u32 *position); |
465 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, | 465 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, |
466 | struct sst_hsw_stream *stream, u32 stage_id, u32 position); | 466 | struct sst_hsw_stream *stream, u32 stage_id, u32 position); |
467 | int sst_hsw_get_dsp_position(struct sst_hsw *hsw, | 467 | u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw, |
468 | struct sst_hsw_stream *stream); | ||
469 | u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw, | ||
468 | struct sst_hsw_stream *stream); | 470 | struct sst_hsw_stream *stream); |
469 | 471 | ||
470 | /* HW port config */ | 472 | /* HW port config */ |
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 0a32dd13a23d..9d5f64a583a3 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c | |||
@@ -99,6 +99,7 @@ struct hsw_pcm_data { | |||
99 | struct snd_compr_stream *cstream; | 99 | struct snd_compr_stream *cstream; |
100 | unsigned int wpos; | 100 | unsigned int wpos; |
101 | struct mutex mutex; | 101 | struct mutex mutex; |
102 | bool allocated; | ||
102 | }; | 103 | }; |
103 | 104 | ||
104 | /* private data for the driver */ | 105 | /* private data for the driver */ |
@@ -107,12 +108,14 @@ struct hsw_priv_data { | |||
107 | struct sst_hsw *hsw; | 108 | struct sst_hsw *hsw; |
108 | 109 | ||
109 | /* page tables */ | 110 | /* page tables */ |
110 | unsigned char *pcm_pg[HSW_PCM_COUNT][2]; | 111 | struct snd_dma_buffer dmab[HSW_PCM_COUNT][2]; |
111 | 112 | ||
112 | /* DAI data */ | 113 | /* DAI data */ |
113 | struct hsw_pcm_data pcm[HSW_PCM_COUNT]; | 114 | struct hsw_pcm_data pcm[HSW_PCM_COUNT]; |
114 | }; | 115 | }; |
115 | 116 | ||
117 | static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data); | ||
118 | |||
116 | static inline u32 hsw_mixer_to_ipc(unsigned int value) | 119 | static inline u32 hsw_mixer_to_ipc(unsigned int value) |
117 | { | 120 | { |
118 | if (value >= ARRAY_SIZE(volume_map)) | 121 | if (value >= ARRAY_SIZE(volume_map)) |
@@ -273,28 +276,26 @@ static const struct snd_kcontrol_new hsw_volume_controls[] = { | |||
273 | }; | 276 | }; |
274 | 277 | ||
275 | /* Create DMA buffer page table for DSP */ | 278 | /* Create DMA buffer page table for DSP */ |
276 | static int create_adsp_page_table(struct hsw_priv_data *pdata, | 279 | static int create_adsp_page_table(struct snd_pcm_substream *substream, |
277 | struct snd_soc_pcm_runtime *rtd, | 280 | struct hsw_priv_data *pdata, struct snd_soc_pcm_runtime *rtd, |
278 | unsigned char *dma_area, size_t size, int pcm, int stream) | 281 | unsigned char *dma_area, size_t size, int pcm) |
279 | { | 282 | { |
280 | int i, pages; | 283 | struct snd_dma_buffer *dmab = snd_pcm_get_dma_buf(substream); |
284 | int i, pages, stream = substream->stream; | ||
281 | 285 | ||
282 | if (size % PAGE_SIZE) | 286 | pages = snd_sgbuf_aligned_pages(size); |
283 | pages = (size / PAGE_SIZE) + 1; | ||
284 | else | ||
285 | pages = size / PAGE_SIZE; | ||
286 | 287 | ||
287 | dev_dbg(rtd->dev, "generating page table for %p size 0x%zu pages %d\n", | 288 | dev_dbg(rtd->dev, "generating page table for %p size 0x%zu pages %d\n", |
288 | dma_area, size, pages); | 289 | dma_area, size, pages); |
289 | 290 | ||
290 | for (i = 0; i < pages; i++) { | 291 | for (i = 0; i < pages; i++) { |
291 | u32 idx = (((i << 2) + i)) >> 1; | 292 | u32 idx = (((i << 2) + i)) >> 1; |
292 | u32 pfn = (virt_to_phys(dma_area + i * PAGE_SIZE)) >> PAGE_SHIFT; | 293 | u32 pfn = snd_sgbuf_get_addr(dmab, i * PAGE_SIZE) >> PAGE_SHIFT; |
293 | u32 *pg_table; | 294 | u32 *pg_table; |
294 | 295 | ||
295 | dev_dbg(rtd->dev, "pfn i %i idx %d pfn %x\n", i, idx, pfn); | 296 | dev_dbg(rtd->dev, "pfn i %i idx %d pfn %x\n", i, idx, pfn); |
296 | 297 | ||
297 | pg_table = (u32*)(pdata->pcm_pg[pcm][stream] + idx); | 298 | pg_table = (u32 *)(pdata->dmab[pcm][stream].area + idx); |
298 | 299 | ||
299 | if (i & 1) | 300 | if (i & 1) |
300 | *pg_table |= (pfn << 4); | 301 | *pg_table |= (pfn << 4); |
@@ -317,12 +318,36 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, | |||
317 | struct sst_hsw *hsw = pdata->hsw; | 318 | struct sst_hsw *hsw = pdata->hsw; |
318 | struct sst_module *module_data; | 319 | struct sst_module *module_data; |
319 | struct sst_dsp *dsp; | 320 | struct sst_dsp *dsp; |
321 | struct snd_dma_buffer *dmab; | ||
320 | enum sst_hsw_stream_type stream_type; | 322 | enum sst_hsw_stream_type stream_type; |
321 | enum sst_hsw_stream_path_id path_id; | 323 | enum sst_hsw_stream_path_id path_id; |
322 | u32 rate, bits, map, pages, module_id; | 324 | u32 rate, bits, map, pages, module_id; |
323 | u8 channels; | 325 | u8 channels; |
324 | int ret; | 326 | int ret; |
325 | 327 | ||
328 | /* check if we are being called a subsequent time */ | ||
329 | if (pcm_data->allocated) { | ||
330 | ret = sst_hsw_stream_reset(hsw, pcm_data->stream); | ||
331 | if (ret < 0) | ||
332 | dev_dbg(rtd->dev, "error: reset stream failed %d\n", | ||
333 | ret); | ||
334 | |||
335 | ret = sst_hsw_stream_free(hsw, pcm_data->stream); | ||
336 | if (ret < 0) { | ||
337 | dev_dbg(rtd->dev, "error: free stream failed %d\n", | ||
338 | ret); | ||
339 | return ret; | ||
340 | } | ||
341 | pcm_data->allocated = false; | ||
342 | |||
343 | pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id, | ||
344 | hsw_notify_pointer, pcm_data); | ||
345 | if (pcm_data->stream == NULL) { | ||
346 | dev_err(rtd->dev, "error: failed to create stream\n"); | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | } | ||
350 | |||
326 | /* stream direction */ | 351 | /* stream direction */ |
327 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 352 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
328 | path_id = SST_HSW_STREAM_PATH_SSP0_OUT; | 353 | path_id = SST_HSW_STREAM_PATH_SSP0_OUT; |
@@ -416,8 +441,10 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, | |||
416 | return ret; | 441 | return ret; |
417 | } | 442 | } |
418 | 443 | ||
419 | ret = create_adsp_page_table(pdata, rtd, runtime->dma_area, | 444 | dmab = snd_pcm_get_dma_buf(substream); |
420 | runtime->dma_bytes, rtd->cpu_dai->id, substream->stream); | 445 | |
446 | ret = create_adsp_page_table(substream, pdata, rtd, runtime->dma_area, | ||
447 | runtime->dma_bytes, rtd->cpu_dai->id); | ||
421 | if (ret < 0) | 448 | if (ret < 0) |
422 | return ret; | 449 | return ret; |
423 | 450 | ||
@@ -430,9 +457,9 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, | |||
430 | pages = runtime->dma_bytes / PAGE_SIZE; | 457 | pages = runtime->dma_bytes / PAGE_SIZE; |
431 | 458 | ||
432 | ret = sst_hsw_stream_buffer(hsw, pcm_data->stream, | 459 | ret = sst_hsw_stream_buffer(hsw, pcm_data->stream, |
433 | virt_to_phys(pdata->pcm_pg[rtd->cpu_dai->id][substream->stream]), | 460 | pdata->dmab[rtd->cpu_dai->id][substream->stream].addr, |
434 | pages, runtime->dma_bytes, 0, | 461 | pages, runtime->dma_bytes, 0, |
435 | (u32)(virt_to_phys(runtime->dma_area) >> PAGE_SHIFT)); | 462 | snd_sgbuf_get_addr(dmab, 0) >> PAGE_SHIFT); |
436 | if (ret < 0) { | 463 | if (ret < 0) { |
437 | dev_err(rtd->dev, "error: failed to set DMA buffer %d\n", ret); | 464 | dev_err(rtd->dev, "error: failed to set DMA buffer %d\n", ret); |
438 | return ret; | 465 | return ret; |
@@ -474,6 +501,7 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, | |||
474 | dev_err(rtd->dev, "error: failed to commit stream %d\n", ret); | 501 | dev_err(rtd->dev, "error: failed to commit stream %d\n", ret); |
475 | return ret; | 502 | return ret; |
476 | } | 503 | } |
504 | pcm_data->allocated = true; | ||
477 | 505 | ||
478 | ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1); | 506 | ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1); |
479 | if (ret < 0) | 507 | if (ret < 0) |
@@ -541,12 +569,14 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream) | |||
541 | struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 569 | struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); |
542 | struct sst_hsw *hsw = pdata->hsw; | 570 | struct sst_hsw *hsw = pdata->hsw; |
543 | snd_pcm_uframes_t offset; | 571 | snd_pcm_uframes_t offset; |
572 | uint64_t ppos; | ||
573 | u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream); | ||
544 | 574 | ||
545 | offset = bytes_to_frames(runtime, | 575 | offset = bytes_to_frames(runtime, position); |
546 | sst_hsw_get_dsp_position(hsw, pcm_data->stream)); | 576 | ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream); |
547 | 577 | ||
548 | dev_dbg(rtd->dev, "PCM: DMA pointer %zu bytes\n", | 578 | dev_dbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n", |
549 | frames_to_bytes(runtime, (u32)offset)); | 579 | position, ppos); |
550 | return offset; | 580 | return offset; |
551 | } | 581 | } |
552 | 582 | ||
@@ -606,6 +636,7 @@ static int hsw_pcm_close(struct snd_pcm_substream *substream) | |||
606 | dev_dbg(rtd->dev, "error: free stream failed %d\n", ret); | 636 | dev_dbg(rtd->dev, "error: free stream failed %d\n", ret); |
607 | goto out; | 637 | goto out; |
608 | } | 638 | } |
639 | pcm_data->allocated = 0; | ||
609 | pcm_data->stream = NULL; | 640 | pcm_data->stream = NULL; |
610 | 641 | ||
611 | out: | 642 | out: |
@@ -621,7 +652,7 @@ static struct snd_pcm_ops hsw_pcm_ops = { | |||
621 | .hw_free = hsw_pcm_hw_free, | 652 | .hw_free = hsw_pcm_hw_free, |
622 | .trigger = hsw_pcm_trigger, | 653 | .trigger = hsw_pcm_trigger, |
623 | .pointer = hsw_pcm_pointer, | 654 | .pointer = hsw_pcm_pointer, |
624 | .mmap = snd_pcm_lib_default_mmap, | 655 | .page = snd_pcm_sgbuf_ops_page, |
625 | }; | 656 | }; |
626 | 657 | ||
627 | static void hsw_pcm_free(struct snd_pcm *pcm) | 658 | static void hsw_pcm_free(struct snd_pcm *pcm) |
@@ -632,17 +663,16 @@ static void hsw_pcm_free(struct snd_pcm *pcm) | |||
632 | static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) | 663 | static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) |
633 | { | 664 | { |
634 | struct snd_pcm *pcm = rtd->pcm; | 665 | struct snd_pcm *pcm = rtd->pcm; |
666 | struct snd_soc_platform *platform = rtd->platform; | ||
667 | struct sst_pdata *pdata = dev_get_platdata(platform->dev); | ||
668 | struct device *dev = pdata->dma_dev; | ||
635 | int ret = 0; | 669 | int ret = 0; |
636 | 670 | ||
637 | ret = dma_coerce_mask_and_coherent(rtd->card->dev, DMA_BIT_MASK(32)); | ||
638 | if (ret) | ||
639 | return ret; | ||
640 | |||
641 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream || | 671 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream || |
642 | pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | 672 | pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { |
643 | ret = snd_pcm_lib_preallocate_pages_for_all(pcm, | 673 | ret = snd_pcm_lib_preallocate_pages_for_all(pcm, |
644 | SNDRV_DMA_TYPE_DEV, | 674 | SNDRV_DMA_TYPE_DEV_SG, |
645 | rtd->card->dev, | 675 | dev, |
646 | hsw_pcm_hardware.buffer_bytes_max, | 676 | hsw_pcm_hardware.buffer_bytes_max, |
647 | hsw_pcm_hardware.buffer_bytes_max); | 677 | hsw_pcm_hardware.buffer_bytes_max); |
648 | if (ret) { | 678 | if (ret) { |
@@ -742,11 +772,14 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform) | |||
742 | { | 772 | { |
743 | struct sst_pdata *pdata = dev_get_platdata(platform->dev); | 773 | struct sst_pdata *pdata = dev_get_platdata(platform->dev); |
744 | struct hsw_priv_data *priv_data; | 774 | struct hsw_priv_data *priv_data; |
745 | int i; | 775 | struct device *dma_dev; |
776 | int i, ret = 0; | ||
746 | 777 | ||
747 | if (!pdata) | 778 | if (!pdata) |
748 | return -ENODEV; | 779 | return -ENODEV; |
749 | 780 | ||
781 | dma_dev = pdata->dma_dev; | ||
782 | |||
750 | priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data), GFP_KERNEL); | 783 | priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data), GFP_KERNEL); |
751 | priv_data->hsw = pdata->dsp; | 784 | priv_data->hsw = pdata->dsp; |
752 | snd_soc_platform_set_drvdata(platform, priv_data); | 785 | snd_soc_platform_set_drvdata(platform, priv_data); |
@@ -758,15 +791,17 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform) | |||
758 | 791 | ||
759 | /* playback */ | 792 | /* playback */ |
760 | if (hsw_dais[i].playback.channels_min) { | 793 | if (hsw_dais[i].playback.channels_min) { |
761 | priv_data->pcm_pg[i][0] = kzalloc(PAGE_SIZE, GFP_DMA); | 794 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, |
762 | if (priv_data->pcm_pg[i][0] == NULL) | 795 | PAGE_SIZE, &priv_data->dmab[i][0]); |
796 | if (ret < 0) | ||
763 | goto err; | 797 | goto err; |
764 | } | 798 | } |
765 | 799 | ||
766 | /* capture */ | 800 | /* capture */ |
767 | if (hsw_dais[i].capture.channels_min) { | 801 | if (hsw_dais[i].capture.channels_min) { |
768 | priv_data->pcm_pg[i][1] = kzalloc(PAGE_SIZE, GFP_DMA); | 802 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, |
769 | if (priv_data->pcm_pg[i][1] == NULL) | 803 | PAGE_SIZE, &priv_data->dmab[i][1]); |
804 | if (ret < 0) | ||
770 | goto err; | 805 | goto err; |
771 | } | 806 | } |
772 | } | 807 | } |
@@ -776,11 +811,11 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform) | |||
776 | err: | 811 | err: |
777 | for (;i >= 0; i--) { | 812 | for (;i >= 0; i--) { |
778 | if (hsw_dais[i].playback.channels_min) | 813 | if (hsw_dais[i].playback.channels_min) |
779 | kfree(priv_data->pcm_pg[i][0]); | 814 | snd_dma_free_pages(&priv_data->dmab[i][0]); |
780 | if (hsw_dais[i].capture.channels_min) | 815 | if (hsw_dais[i].capture.channels_min) |
781 | kfree(priv_data->pcm_pg[i][1]); | 816 | snd_dma_free_pages(&priv_data->dmab[i][1]); |
782 | } | 817 | } |
783 | return -ENOMEM; | 818 | return ret; |
784 | } | 819 | } |
785 | 820 | ||
786 | static int hsw_pcm_remove(struct snd_soc_platform *platform) | 821 | static int hsw_pcm_remove(struct snd_soc_platform *platform) |
@@ -791,9 +826,9 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform) | |||
791 | 826 | ||
792 | for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { | 827 | for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { |
793 | if (hsw_dais[i].playback.channels_min) | 828 | if (hsw_dais[i].playback.channels_min) |
794 | kfree(priv_data->pcm_pg[i][0]); | 829 | snd_dma_free_pages(&priv_data->dmab[i][0]); |
795 | if (hsw_dais[i].capture.channels_min) | 830 | if (hsw_dais[i].capture.channels_min) |
796 | kfree(priv_data->pcm_pg[i][1]); | 831 | snd_dma_free_pages(&priv_data->dmab[i][1]); |
797 | } | 832 | } |
798 | 833 | ||
799 | return 0; | 834 | return 0; |
diff --git a/sound/soc/jz4740/Makefile b/sound/soc/jz4740/Makefile index be873c1b0c20..d32c540555c4 100644 --- a/sound/soc/jz4740/Makefile +++ b/sound/soc/jz4740/Makefile | |||
@@ -1,10 +1,8 @@ | |||
1 | # | 1 | # |
2 | # Jz4740 Platform Support | 2 | # Jz4740 Platform Support |
3 | # | 3 | # |
4 | snd-soc-jz4740-objs := jz4740-pcm.o | ||
5 | snd-soc-jz4740-i2s-objs := jz4740-i2s.o | 4 | snd-soc-jz4740-i2s-objs := jz4740-i2s.o |
6 | 5 | ||
7 | obj-$(CONFIG_SND_JZ4740_SOC) += snd-soc-jz4740.o | ||
8 | obj-$(CONFIG_SND_JZ4740_SOC_I2S) += snd-soc-jz4740-i2s.o | 6 | obj-$(CONFIG_SND_JZ4740_SOC_I2S) += snd-soc-jz4740-i2s.o |
9 | 7 | ||
10 | # Jz4740 Machine Support | 8 | # Jz4740 Machine Support |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 215b668166be..89424470a1f3 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -197,13 +197,12 @@ static void rsnd_dma_complete(void *data) | |||
197 | * rsnd_dai_pointer_update() will be called twice, | 197 | * rsnd_dai_pointer_update() will be called twice, |
198 | * ant it will breaks io->byte_pos | 198 | * ant it will breaks io->byte_pos |
199 | */ | 199 | */ |
200 | |||
201 | rsnd_dai_pointer_update(io, io->byte_per_period); | ||
202 | |||
203 | if (dma->submit_loop) | 200 | if (dma->submit_loop) |
204 | rsnd_dma_continue(dma); | 201 | rsnd_dma_continue(dma); |
205 | 202 | ||
206 | rsnd_unlock(priv, flags); | 203 | rsnd_unlock(priv, flags); |
204 | |||
205 | rsnd_dai_pointer_update(io, io->byte_per_period); | ||
207 | } | 206 | } |
208 | 207 | ||
209 | static void __rsnd_dma_start(struct rsnd_dma *dma) | 208 | static void __rsnd_dma_start(struct rsnd_dma *dma) |
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 6232b7d307aa..4d0720ed5a90 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -258,7 +258,7 @@ static int rsnd_src_init(struct rsnd_mod *mod, | |||
258 | { | 258 | { |
259 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 259 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
260 | 260 | ||
261 | clk_enable(src->clk); | 261 | clk_prepare_enable(src->clk); |
262 | 262 | ||
263 | return 0; | 263 | return 0; |
264 | } | 264 | } |
@@ -269,7 +269,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod, | |||
269 | { | 269 | { |
270 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 270 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
271 | 271 | ||
272 | clk_disable(src->clk); | 272 | clk_disable_unprepare(src->clk); |
273 | 273 | ||
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 4b7e20603dd7..1d8387c25bd8 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -171,7 +171,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | |||
171 | u32 cr; | 171 | u32 cr; |
172 | 172 | ||
173 | if (0 == ssi->usrcnt) { | 173 | if (0 == ssi->usrcnt) { |
174 | clk_enable(ssi->clk); | 174 | clk_prepare_enable(ssi->clk); |
175 | 175 | ||
176 | if (rsnd_dai_is_clk_master(rdai)) { | 176 | if (rsnd_dai_is_clk_master(rdai)) { |
177 | if (rsnd_ssi_clk_from_parent(ssi)) | 177 | if (rsnd_ssi_clk_from_parent(ssi)) |
@@ -230,7 +230,7 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, | |||
230 | rsnd_ssi_master_clk_stop(ssi); | 230 | rsnd_ssi_master_clk_stop(ssi); |
231 | } | 231 | } |
232 | 232 | ||
233 | clk_disable(ssi->clk); | 233 | clk_disable_unprepare(ssi->clk); |
234 | } | 234 | } |
235 | 235 | ||
236 | dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod)); | 236 | dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod)); |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c8a780d0d057..6d6ceee447d5 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -254,7 +254,6 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, | |||
254 | static void dapm_kcontrol_free(struct snd_kcontrol *kctl) | 254 | static void dapm_kcontrol_free(struct snd_kcontrol *kctl) |
255 | { | 255 | { |
256 | struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl); | 256 | struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl); |
257 | kfree(data->widget); | ||
258 | kfree(data->wlist); | 257 | kfree(data->wlist); |
259 | kfree(data); | 258 | kfree(data); |
260 | } | 259 | } |
@@ -1613,8 +1612,11 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) | |||
1613 | "ASoC: Failed to turn on bias: %d\n", ret); | 1612 | "ASoC: Failed to turn on bias: %d\n", ret); |
1614 | } | 1613 | } |
1615 | 1614 | ||
1616 | /* Prepare for a STADDBY->ON or ON->STANDBY transition */ | 1615 | /* Prepare for a transition to ON or away from ON */ |
1617 | if (d->bias_level != d->target_bias_level) { | 1616 | if ((d->target_bias_level == SND_SOC_BIAS_ON && |
1617 | d->bias_level != SND_SOC_BIAS_ON) || | ||
1618 | (d->target_bias_level != SND_SOC_BIAS_ON && | ||
1619 | d->bias_level == SND_SOC_BIAS_ON)) { | ||
1618 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE); | 1620 | ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE); |
1619 | if (ret != 0) | 1621 | if (ret != 0) |
1620 | dev_err(d->dev, | 1622 | dev_err(d->dev, |
@@ -3476,8 +3478,11 @@ void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) | |||
3476 | cpu_dai = rtd->cpu_dai; | 3478 | cpu_dai = rtd->cpu_dai; |
3477 | codec_dai = rtd->codec_dai; | 3479 | codec_dai = rtd->codec_dai; |
3478 | 3480 | ||
3479 | /* dynamic FE links have no fixed DAI mapping */ | 3481 | /* |
3480 | if (rtd->dai_link->dynamic) | 3482 | * dynamic FE links have no fixed DAI mapping. |
3483 | * CODEC<->CODEC links have no direct connection. | ||
3484 | */ | ||
3485 | if (rtd->dai_link->dynamic || rtd->dai_link->params) | ||
3481 | continue; | 3486 | continue; |
3482 | 3487 | ||
3483 | /* there is no point in connecting BE DAI links with dummies */ | 3488 | /* there is no point in connecting BE DAI links with dummies */ |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 2cedf09f6d96..a391de058037 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -1675,7 +1675,7 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, | |||
1675 | be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; | 1675 | be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; |
1676 | break; | 1676 | break; |
1677 | case SNDRV_PCM_TRIGGER_SUSPEND: | 1677 | case SNDRV_PCM_TRIGGER_SUSPEND: |
1678 | if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) | 1678 | if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) |
1679 | continue; | 1679 | continue; |
1680 | 1680 | ||
1681 | if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) | 1681 | if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 893d5a1afc3c..c3b5b7dca1c3 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -651,7 +651,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) | |||
651 | int err = -ENODEV; | 651 | int err = -ENODEV; |
652 | 652 | ||
653 | down_read(&chip->shutdown_rwsem); | 653 | down_read(&chip->shutdown_rwsem); |
654 | if (chip->probing) | 654 | if (chip->probing && chip->in_pm) |
655 | err = 0; | 655 | err = 0; |
656 | else if (!chip->shutdown) | 656 | else if (!chip->shutdown) |
657 | err = usb_autopm_get_interface(chip->pm_intf); | 657 | err = usb_autopm_get_interface(chip->pm_intf); |
@@ -663,7 +663,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) | |||
663 | void snd_usb_autosuspend(struct snd_usb_audio *chip) | 663 | void snd_usb_autosuspend(struct snd_usb_audio *chip) |
664 | { | 664 | { |
665 | down_read(&chip->shutdown_rwsem); | 665 | down_read(&chip->shutdown_rwsem); |
666 | if (!chip->shutdown && !chip->probing) | 666 | if (!chip->shutdown && !chip->probing && !chip->in_pm) |
667 | usb_autopm_put_interface(chip->pm_intf); | 667 | usb_autopm_put_interface(chip->pm_intf); |
668 | up_read(&chip->shutdown_rwsem); | 668 | up_read(&chip->shutdown_rwsem); |
669 | } | 669 | } |
@@ -695,8 +695,9 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) | |||
695 | chip->autosuspended = 1; | 695 | chip->autosuspended = 1; |
696 | } | 696 | } |
697 | 697 | ||
698 | list_for_each_entry(mixer, &chip->mixer_list, list) | 698 | if (chip->num_suspended_intf == 1) |
699 | snd_usb_mixer_suspend(mixer); | 699 | list_for_each_entry(mixer, &chip->mixer_list, list) |
700 | snd_usb_mixer_suspend(mixer); | ||
700 | 701 | ||
701 | return 0; | 702 | return 0; |
702 | } | 703 | } |
@@ -711,6 +712,8 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume) | |||
711 | return 0; | 712 | return 0; |
712 | if (--chip->num_suspended_intf) | 713 | if (--chip->num_suspended_intf) |
713 | return 0; | 714 | return 0; |
715 | |||
716 | chip->in_pm = 1; | ||
714 | /* | 717 | /* |
715 | * ALSA leaves material resumption to user space | 718 | * ALSA leaves material resumption to user space |
716 | * we just notify and restart the mixers | 719 | * we just notify and restart the mixers |
@@ -726,6 +729,7 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume) | |||
726 | chip->autosuspended = 0; | 729 | chip->autosuspended = 0; |
727 | 730 | ||
728 | err_out: | 731 | err_out: |
732 | chip->in_pm = 0; | ||
729 | return err; | 733 | return err; |
730 | } | 734 | } |
731 | 735 | ||
diff --git a/sound/usb/card.h b/sound/usb/card.h index 9867ab866857..97acb906acc2 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -92,6 +92,7 @@ struct snd_usb_endpoint { | |||
92 | unsigned int curframesize; /* current packet size in frames (for capture) */ | 92 | unsigned int curframesize; /* current packet size in frames (for capture) */ |
93 | unsigned int syncmaxsize; /* sync endpoint packet size */ | 93 | unsigned int syncmaxsize; /* sync endpoint packet size */ |
94 | unsigned int fill_max:1; /* fill max packet size always */ | 94 | unsigned int fill_max:1; /* fill max packet size always */ |
95 | unsigned int udh01_fb_quirk:1; /* corrupted feedback data */ | ||
95 | unsigned int datainterval; /* log_2 of data packet interval */ | 96 | unsigned int datainterval; /* log_2 of data packet interval */ |
96 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ | 97 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ |
97 | unsigned char silence_value; | 98 | unsigned char silence_value; |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index e70a87e0d9fe..289f582c9130 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -471,6 +471,10 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | |||
471 | ep->syncinterval = 3; | 471 | ep->syncinterval = 3; |
472 | 472 | ||
473 | ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); | 473 | ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); |
474 | |||
475 | if (chip->usb_id == USB_ID(0x0644, 0x8038) /* TEAC UD-H01 */ && | ||
476 | ep->syncmaxsize == 4) | ||
477 | ep->udh01_fb_quirk = 1; | ||
474 | } | 478 | } |
475 | 479 | ||
476 | list_add_tail(&ep->list, &chip->ep_list); | 480 | list_add_tail(&ep->list, &chip->ep_list); |
@@ -1105,7 +1109,16 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | |||
1105 | if (f == 0) | 1109 | if (f == 0) |
1106 | return; | 1110 | return; |
1107 | 1111 | ||
1108 | if (unlikely(ep->freqshift == INT_MIN)) { | 1112 | if (unlikely(sender->udh01_fb_quirk)) { |
1113 | /* | ||
1114 | * The TEAC UD-H01 firmware sometimes changes the feedback value | ||
1115 | * by +/- 0x1.0000. | ||
1116 | */ | ||
1117 | if (f < ep->freqn - 0x8000) | ||
1118 | f += 0x10000; | ||
1119 | else if (f > ep->freqn + 0x8000) | ||
1120 | f -= 0x10000; | ||
1121 | } else if (unlikely(ep->freqshift == INT_MIN)) { | ||
1109 | /* | 1122 | /* |
1110 | * The first time we see a feedback value, determine its format | 1123 | * The first time we see a feedback value, determine its format |
1111 | * by shifting it left or right until it matches the nominal | 1124 | * by shifting it left or right until it matches the nominal |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 131336d40492..c62a1659106d 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -1501,9 +1501,8 @@ static void retire_playback_urb(struct snd_usb_substream *subs, | |||
1501 | * The error should be lower than 2ms since the estimate relies | 1501 | * The error should be lower than 2ms since the estimate relies |
1502 | * on two reads of a counter updated every ms. | 1502 | * on two reads of a counter updated every ms. |
1503 | */ | 1503 | */ |
1504 | if (printk_ratelimit() && | 1504 | if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2) |
1505 | abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2) | 1505 | dev_dbg_ratelimited(&subs->dev->dev, |
1506 | dev_dbg(&subs->dev->dev, | ||
1507 | "delay: estimated %d, actual %d\n", | 1506 | "delay: estimated %d, actual %d\n", |
1508 | est_delay, subs->last_delay); | 1507 | est_delay, subs->last_delay); |
1509 | 1508 | ||
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 25c4c7e217de..91d0380431b4 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -40,6 +40,7 @@ struct snd_usb_audio { | |||
40 | struct rw_semaphore shutdown_rwsem; | 40 | struct rw_semaphore shutdown_rwsem; |
41 | unsigned int shutdown:1; | 41 | unsigned int shutdown:1; |
42 | unsigned int probing:1; | 42 | unsigned int probing:1; |
43 | unsigned int in_pm:1; | ||
43 | unsigned int autosuspended:1; | 44 | unsigned int autosuspended:1; |
44 | unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ | 45 | unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ |
45 | 46 | ||