diff options
author | Olof Johansson <olof@lixom.net> | 2019-05-16 01:51:48 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2019-05-16 01:51:48 -0400 |
commit | 7a0c4c17089a8aff52f516f0f52002be52950aae (patch) | |
tree | 474dc451d62a1ba788ed52c4cecf93f9e50cc39a /sound | |
parent | a842b514db723d7bec5e8f9e6f57e5cfbb6b1f37 (diff) | |
parent | affe2a51001450c32886f70248b57eac0f9b68ef (diff) |
Merge branch 'fixes' into arm/soc
Merge in a few pending fixes from pre-5.1 that didn't get sent in:
MAINTAINERS: update arch/arm/mach-davinci
ARM: dts: ls1021: Fix SGMII PCS link remaining down after PHY disconnect
ARM: dts: imx6q-logicpd: Reduce inrush current on USBH1
ARM: dts: imx6q-logicpd: Reduce inrush current on start
ARM: dts: imx: Fix the AR803X phy-mode
ARM: dts: sun8i: a33: Reintroduce default pinctrl muxing
arm64: dts: allwinner: a64: Rename hpvcc-supply to cpvdd-supply
ARM: sunxi: fix a leaked reference by adding missing of_node_put
ARM: sunxi: fix a leaked reference by adding missing of_node_put
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'sound')
51 files changed, 750 insertions, 271 deletions
diff --git a/sound/core/info.c b/sound/core/info.c index 96a074019c33..0eb169acc850 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -713,8 +713,11 @@ snd_info_create_entry(const char *name, struct snd_info_entry *parent, | |||
713 | INIT_LIST_HEAD(&entry->list); | 713 | INIT_LIST_HEAD(&entry->list); |
714 | entry->parent = parent; | 714 | entry->parent = parent; |
715 | entry->module = module; | 715 | entry->module = module; |
716 | if (parent) | 716 | if (parent) { |
717 | mutex_lock(&parent->access); | ||
717 | list_add_tail(&entry->list, &parent->children); | 718 | list_add_tail(&entry->list, &parent->children); |
719 | mutex_unlock(&parent->access); | ||
720 | } | ||
718 | return entry; | 721 | return entry; |
719 | } | 722 | } |
720 | 723 | ||
@@ -792,7 +795,12 @@ void snd_info_free_entry(struct snd_info_entry * entry) | |||
792 | list_for_each_entry_safe(p, n, &entry->children, list) | 795 | list_for_each_entry_safe(p, n, &entry->children, list) |
793 | snd_info_free_entry(p); | 796 | snd_info_free_entry(p); |
794 | 797 | ||
795 | list_del(&entry->list); | 798 | p = entry->parent; |
799 | if (p) { | ||
800 | mutex_lock(&p->access); | ||
801 | list_del(&entry->list); | ||
802 | mutex_unlock(&p->access); | ||
803 | } | ||
796 | kfree(entry->name); | 804 | kfree(entry->name); |
797 | if (entry->private_free) | 805 | if (entry->private_free) |
798 | entry->private_free(entry); | 806 | entry->private_free(entry); |
diff --git a/sound/core/init.c b/sound/core/init.c index 0c4dc40376a7..079c12d64b0e 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -382,14 +382,7 @@ int snd_card_disconnect(struct snd_card *card) | |||
382 | card->shutdown = 1; | 382 | card->shutdown = 1; |
383 | spin_unlock(&card->files_lock); | 383 | spin_unlock(&card->files_lock); |
384 | 384 | ||
385 | /* phase 1: disable fops (user space) operations for ALSA API */ | 385 | /* replace file->f_op with special dummy operations */ |
386 | mutex_lock(&snd_card_mutex); | ||
387 | snd_cards[card->number] = NULL; | ||
388 | clear_bit(card->number, snd_cards_lock); | ||
389 | mutex_unlock(&snd_card_mutex); | ||
390 | |||
391 | /* phase 2: replace file->f_op with special dummy operations */ | ||
392 | |||
393 | spin_lock(&card->files_lock); | 386 | spin_lock(&card->files_lock); |
394 | list_for_each_entry(mfile, &card->files_list, list) { | 387 | list_for_each_entry(mfile, &card->files_list, list) { |
395 | /* it's critical part, use endless loop */ | 388 | /* it's critical part, use endless loop */ |
@@ -405,7 +398,7 @@ int snd_card_disconnect(struct snd_card *card) | |||
405 | } | 398 | } |
406 | spin_unlock(&card->files_lock); | 399 | spin_unlock(&card->files_lock); |
407 | 400 | ||
408 | /* phase 3: notify all connected devices about disconnection */ | 401 | /* notify all connected devices about disconnection */ |
409 | /* at this point, they cannot respond to any calls except release() */ | 402 | /* at this point, they cannot respond to any calls except release() */ |
410 | 403 | ||
411 | #if IS_ENABLED(CONFIG_SND_MIXER_OSS) | 404 | #if IS_ENABLED(CONFIG_SND_MIXER_OSS) |
@@ -421,6 +414,13 @@ int snd_card_disconnect(struct snd_card *card) | |||
421 | device_del(&card->card_dev); | 414 | device_del(&card->card_dev); |
422 | card->registered = false; | 415 | card->registered = false; |
423 | } | 416 | } |
417 | |||
418 | /* disable fops (user space) operations for ALSA API */ | ||
419 | mutex_lock(&snd_card_mutex); | ||
420 | snd_cards[card->number] = NULL; | ||
421 | clear_bit(card->number, snd_cards_lock); | ||
422 | mutex_unlock(&snd_card_mutex); | ||
423 | |||
424 | #ifdef CONFIG_PM | 424 | #ifdef CONFIG_PM |
425 | wake_up(&card->power_sleep); | 425 | wake_up(&card->power_sleep); |
426 | #endif | 426 | #endif |
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 7d4640d1fe9f..38e7deab6384 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c | |||
@@ -1252,7 +1252,7 @@ static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client, | |||
1252 | 1252 | ||
1253 | /* fill the info fields */ | 1253 | /* fill the info fields */ |
1254 | if (client_info->name[0]) | 1254 | if (client_info->name[0]) |
1255 | strlcpy(client->name, client_info->name, sizeof(client->name)); | 1255 | strscpy(client->name, client_info->name, sizeof(client->name)); |
1256 | 1256 | ||
1257 | client->filter = client_info->filter; | 1257 | client->filter = client_info->filter; |
1258 | client->event_lost = client_info->event_lost; | 1258 | client->event_lost = client_info->event_lost; |
@@ -1530,7 +1530,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) | |||
1530 | /* set queue name */ | 1530 | /* set queue name */ |
1531 | if (!info->name[0]) | 1531 | if (!info->name[0]) |
1532 | snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue); | 1532 | snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue); |
1533 | strlcpy(q->name, info->name, sizeof(q->name)); | 1533 | strscpy(q->name, info->name, sizeof(q->name)); |
1534 | snd_use_lock_free(&q->use_lock); | 1534 | snd_use_lock_free(&q->use_lock); |
1535 | 1535 | ||
1536 | return 0; | 1536 | return 0; |
@@ -1592,7 +1592,7 @@ static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client, | |||
1592 | queuefree(q); | 1592 | queuefree(q); |
1593 | return -EPERM; | 1593 | return -EPERM; |
1594 | } | 1594 | } |
1595 | strlcpy(q->name, info->name, sizeof(q->name)); | 1595 | strscpy(q->name, info->name, sizeof(q->name)); |
1596 | queuefree(q); | 1596 | queuefree(q); |
1597 | 1597 | ||
1598 | return 0; | 1598 | return 0; |
diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c index 9c37d9af3023..ec7715c6b0c0 100644 --- a/sound/hda/ext/hdac_ext_bus.c +++ b/sound/hda/ext/hdac_ext_bus.c | |||
@@ -107,7 +107,6 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, | |||
107 | INIT_LIST_HEAD(&bus->hlink_list); | 107 | INIT_LIST_HEAD(&bus->hlink_list); |
108 | bus->idx = idx++; | 108 | bus->idx = idx++; |
109 | 109 | ||
110 | mutex_init(&bus->lock); | ||
111 | bus->cmd_dma_state = true; | 110 | bus->cmd_dma_state = true; |
112 | 111 | ||
113 | return 0; | 112 | return 0; |
diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c index 012305177f68..ad8eee08013f 100644 --- a/sound/hda/hdac_bus.c +++ b/sound/hda/hdac_bus.c | |||
@@ -38,6 +38,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, | |||
38 | INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events); | 38 | INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events); |
39 | spin_lock_init(&bus->reg_lock); | 39 | spin_lock_init(&bus->reg_lock); |
40 | mutex_init(&bus->cmd_mutex); | 40 | mutex_init(&bus->cmd_mutex); |
41 | mutex_init(&bus->lock); | ||
41 | bus->irq = -1; | 42 | bus->irq = -1; |
42 | return 0; | 43 | return 0; |
43 | } | 44 | } |
diff --git a/sound/hda/hdac_component.c b/sound/hda/hdac_component.c index 5c95933e739a..1ea51e3b942a 100644 --- a/sound/hda/hdac_component.c +++ b/sound/hda/hdac_component.c | |||
@@ -69,13 +69,15 @@ void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable) | |||
69 | 69 | ||
70 | dev_dbg(bus->dev, "display power %s\n", | 70 | dev_dbg(bus->dev, "display power %s\n", |
71 | enable ? "enable" : "disable"); | 71 | enable ? "enable" : "disable"); |
72 | |||
73 | mutex_lock(&bus->lock); | ||
72 | if (enable) | 74 | if (enable) |
73 | set_bit(idx, &bus->display_power_status); | 75 | set_bit(idx, &bus->display_power_status); |
74 | else | 76 | else |
75 | clear_bit(idx, &bus->display_power_status); | 77 | clear_bit(idx, &bus->display_power_status); |
76 | 78 | ||
77 | if (!acomp || !acomp->ops) | 79 | if (!acomp || !acomp->ops) |
78 | return; | 80 | goto unlock; |
79 | 81 | ||
80 | if (bus->display_power_status) { | 82 | if (bus->display_power_status) { |
81 | if (!bus->display_power_active) { | 83 | if (!bus->display_power_active) { |
@@ -92,6 +94,8 @@ void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable) | |||
92 | bus->display_power_active = false; | 94 | bus->display_power_active = false; |
93 | } | 95 | } |
94 | } | 96 | } |
97 | unlock: | ||
98 | mutex_unlock(&bus->lock); | ||
95 | } | 99 | } |
96 | EXPORT_SYMBOL_GPL(snd_hdac_display_power); | 100 | EXPORT_SYMBOL_GPL(snd_hdac_display_power); |
97 | 101 | ||
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ec0b8595eb4d..701a69d856f5 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -969,6 +969,7 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, | |||
969 | 969 | ||
970 | /* power-up all before initialization */ | 970 | /* power-up all before initialization */ |
971 | hda_set_power_state(codec, AC_PWRST_D0); | 971 | hda_set_power_state(codec, AC_PWRST_D0); |
972 | codec->core.dev.power.power_state = PMSG_ON; | ||
972 | 973 | ||
973 | snd_hda_codec_proc_new(codec); | 974 | snd_hda_codec_proc_new(codec); |
974 | 975 | ||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ece256a3b48f..2ec91085fa3e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2142,6 +2142,8 @@ static struct snd_pci_quirk power_save_blacklist[] = { | |||
2142 | SND_PCI_QUIRK(0x8086, 0x2040, "Intel DZ77BH-55K", 0), | 2142 | SND_PCI_QUIRK(0x8086, 0x2040, "Intel DZ77BH-55K", 0), |
2143 | /* https://bugzilla.kernel.org/show_bug.cgi?id=199607 */ | 2143 | /* https://bugzilla.kernel.org/show_bug.cgi?id=199607 */ |
2144 | SND_PCI_QUIRK(0x8086, 0x2057, "Intel NUC5i7RYB", 0), | 2144 | SND_PCI_QUIRK(0x8086, 0x2057, "Intel NUC5i7RYB", 0), |
2145 | /* https://bugs.launchpad.net/bugs/1821663 */ | ||
2146 | SND_PCI_QUIRK(0x8086, 0x2064, "Intel SDP 8086:2064", 0), | ||
2145 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1520902 */ | 2147 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1520902 */ |
2146 | SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0), | 2148 | SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0), |
2147 | /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */ | 2149 | /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */ |
@@ -2150,6 +2152,8 @@ static struct snd_pci_quirk power_save_blacklist[] = { | |||
2150 | SND_PCI_QUIRK(0x17aa, 0x367b, "Lenovo IdeaCentre B550", 0), | 2152 | SND_PCI_QUIRK(0x17aa, 0x367b, "Lenovo IdeaCentre B550", 0), |
2151 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */ | 2153 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */ |
2152 | SND_PCI_QUIRK(0x17aa, 0x36a7, "Lenovo C50 All in one", 0), | 2154 | SND_PCI_QUIRK(0x17aa, 0x36a7, "Lenovo C50 All in one", 0), |
2155 | /* https://bugs.launchpad.net/bugs/1821663 */ | ||
2156 | SND_PCI_QUIRK(0x1631, 0xe017, "Packard Bell NEC IMEDIA 5204", 0), | ||
2153 | {} | 2157 | {} |
2154 | }; | 2158 | }; |
2155 | #endif /* CONFIG_PM */ | 2159 | #endif /* CONFIG_PM */ |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a3fb3d4c5730..f5b510f119ed 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1864,8 +1864,8 @@ enum { | |||
1864 | ALC887_FIXUP_BASS_CHMAP, | 1864 | ALC887_FIXUP_BASS_CHMAP, |
1865 | ALC1220_FIXUP_GB_DUAL_CODECS, | 1865 | ALC1220_FIXUP_GB_DUAL_CODECS, |
1866 | ALC1220_FIXUP_CLEVO_P950, | 1866 | ALC1220_FIXUP_CLEVO_P950, |
1867 | ALC1220_FIXUP_SYSTEM76_ORYP5, | 1867 | ALC1220_FIXUP_CLEVO_PB51ED, |
1868 | ALC1220_FIXUP_SYSTEM76_ORYP5_PINS, | 1868 | ALC1220_FIXUP_CLEVO_PB51ED_PINS, |
1869 | }; | 1869 | }; |
1870 | 1870 | ||
1871 | static void alc889_fixup_coef(struct hda_codec *codec, | 1871 | static void alc889_fixup_coef(struct hda_codec *codec, |
@@ -2070,7 +2070,7 @@ static void alc1220_fixup_clevo_p950(struct hda_codec *codec, | |||
2070 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, | 2070 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, |
2071 | const struct hda_fixup *fix, int action); | 2071 | const struct hda_fixup *fix, int action); |
2072 | 2072 | ||
2073 | static void alc1220_fixup_system76_oryp5(struct hda_codec *codec, | 2073 | static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec, |
2074 | const struct hda_fixup *fix, | 2074 | const struct hda_fixup *fix, |
2075 | int action) | 2075 | int action) |
2076 | { | 2076 | { |
@@ -2322,18 +2322,18 @@ static const struct hda_fixup alc882_fixups[] = { | |||
2322 | .type = HDA_FIXUP_FUNC, | 2322 | .type = HDA_FIXUP_FUNC, |
2323 | .v.func = alc1220_fixup_clevo_p950, | 2323 | .v.func = alc1220_fixup_clevo_p950, |
2324 | }, | 2324 | }, |
2325 | [ALC1220_FIXUP_SYSTEM76_ORYP5] = { | 2325 | [ALC1220_FIXUP_CLEVO_PB51ED] = { |
2326 | .type = HDA_FIXUP_FUNC, | 2326 | .type = HDA_FIXUP_FUNC, |
2327 | .v.func = alc1220_fixup_system76_oryp5, | 2327 | .v.func = alc1220_fixup_clevo_pb51ed, |
2328 | }, | 2328 | }, |
2329 | [ALC1220_FIXUP_SYSTEM76_ORYP5_PINS] = { | 2329 | [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = { |
2330 | .type = HDA_FIXUP_PINS, | 2330 | .type = HDA_FIXUP_PINS, |
2331 | .v.pins = (const struct hda_pintbl[]) { | 2331 | .v.pins = (const struct hda_pintbl[]) { |
2332 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 2332 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
2333 | {} | 2333 | {} |
2334 | }, | 2334 | }, |
2335 | .chained = true, | 2335 | .chained = true, |
2336 | .chain_id = ALC1220_FIXUP_SYSTEM76_ORYP5, | 2336 | .chain_id = ALC1220_FIXUP_CLEVO_PB51ED, |
2337 | }, | 2337 | }, |
2338 | }; | 2338 | }; |
2339 | 2339 | ||
@@ -2411,8 +2411,9 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
2411 | SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950), | 2411 | SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950), |
2412 | SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950), | 2412 | SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950), |
2413 | SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950), | 2413 | SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950), |
2414 | SND_PCI_QUIRK(0x1558, 0x96e1, "System76 Oryx Pro (oryp5)", ALC1220_FIXUP_SYSTEM76_ORYP5_PINS), | 2414 | SND_PCI_QUIRK(0x1558, 0x96e1, "System76 Oryx Pro (oryp5)", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
2415 | SND_PCI_QUIRK(0x1558, 0x97e1, "System76 Oryx Pro (oryp5)", ALC1220_FIXUP_SYSTEM76_ORYP5_PINS), | 2415 | SND_PCI_QUIRK(0x1558, 0x97e1, "System76 Oryx Pro (oryp5)", ALC1220_FIXUP_CLEVO_PB51ED_PINS), |
2416 | SND_PCI_QUIRK(0x1558, 0x65d1, "Tuxedo Book XC1509", ALC1220_FIXUP_CLEVO_PB51ED_PINS), | ||
2416 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), | 2417 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), |
2417 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), | 2418 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), |
2418 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), | 2419 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), |
@@ -5491,7 +5492,7 @@ static void alc_headset_btn_callback(struct hda_codec *codec, | |||
5491 | jack->jack->button_state = report; | 5492 | jack->jack->button_state = report; |
5492 | } | 5493 | } |
5493 | 5494 | ||
5494 | static void alc295_fixup_chromebook(struct hda_codec *codec, | 5495 | static void alc_fixup_headset_jack(struct hda_codec *codec, |
5495 | const struct hda_fixup *fix, int action) | 5496 | const struct hda_fixup *fix, int action) |
5496 | { | 5497 | { |
5497 | 5498 | ||
@@ -5501,16 +5502,6 @@ static void alc295_fixup_chromebook(struct hda_codec *codec, | |||
5501 | alc_headset_btn_callback); | 5502 | alc_headset_btn_callback); |
5502 | snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false, | 5503 | snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false, |
5503 | SND_JACK_HEADSET, alc_headset_btn_keymap); | 5504 | SND_JACK_HEADSET, alc_headset_btn_keymap); |
5504 | switch (codec->core.vendor_id) { | ||
5505 | case 0x10ec0295: | ||
5506 | alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */ | ||
5507 | alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15); | ||
5508 | break; | ||
5509 | case 0x10ec0236: | ||
5510 | alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */ | ||
5511 | alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15); | ||
5512 | break; | ||
5513 | } | ||
5514 | break; | 5505 | break; |
5515 | case HDA_FIXUP_ACT_INIT: | 5506 | case HDA_FIXUP_ACT_INIT: |
5516 | switch (codec->core.vendor_id) { | 5507 | switch (codec->core.vendor_id) { |
@@ -5531,6 +5522,25 @@ static void alc295_fixup_chromebook(struct hda_codec *codec, | |||
5531 | } | 5522 | } |
5532 | } | 5523 | } |
5533 | 5524 | ||
5525 | static void alc295_fixup_chromebook(struct hda_codec *codec, | ||
5526 | const struct hda_fixup *fix, int action) | ||
5527 | { | ||
5528 | switch (action) { | ||
5529 | case HDA_FIXUP_ACT_INIT: | ||
5530 | switch (codec->core.vendor_id) { | ||
5531 | case 0x10ec0295: | ||
5532 | alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */ | ||
5533 | alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15); | ||
5534 | break; | ||
5535 | case 0x10ec0236: | ||
5536 | alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */ | ||
5537 | alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15); | ||
5538 | break; | ||
5539 | } | ||
5540 | break; | ||
5541 | } | ||
5542 | } | ||
5543 | |||
5534 | static void alc_fixup_disable_mic_vref(struct hda_codec *codec, | 5544 | static void alc_fixup_disable_mic_vref(struct hda_codec *codec, |
5535 | const struct hda_fixup *fix, int action) | 5545 | const struct hda_fixup *fix, int action) |
5536 | { | 5546 | { |
@@ -5663,6 +5673,7 @@ enum { | |||
5663 | ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, | 5673 | ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, |
5664 | ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, | 5674 | ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, |
5665 | ALC233_FIXUP_LENOVO_MULTI_CODECS, | 5675 | ALC233_FIXUP_LENOVO_MULTI_CODECS, |
5676 | ALC233_FIXUP_ACER_HEADSET_MIC, | ||
5666 | ALC294_FIXUP_LENOVO_MIC_LOCATION, | 5677 | ALC294_FIXUP_LENOVO_MIC_LOCATION, |
5667 | ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, | 5678 | ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, |
5668 | ALC700_FIXUP_INTEL_REFERENCE, | 5679 | ALC700_FIXUP_INTEL_REFERENCE, |
@@ -5684,6 +5695,7 @@ enum { | |||
5684 | ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE, | 5695 | ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE, |
5685 | ALC255_FIXUP_ACER_HEADSET_MIC, | 5696 | ALC255_FIXUP_ACER_HEADSET_MIC, |
5686 | ALC295_FIXUP_CHROME_BOOK, | 5697 | ALC295_FIXUP_CHROME_BOOK, |
5698 | ALC225_FIXUP_HEADSET_JACK, | ||
5687 | ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE, | 5699 | ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE, |
5688 | ALC225_FIXUP_WYSE_AUTO_MUTE, | 5700 | ALC225_FIXUP_WYSE_AUTO_MUTE, |
5689 | ALC225_FIXUP_WYSE_DISABLE_MIC_VREF, | 5701 | ALC225_FIXUP_WYSE_DISABLE_MIC_VREF, |
@@ -6490,6 +6502,16 @@ static const struct hda_fixup alc269_fixups[] = { | |||
6490 | .type = HDA_FIXUP_FUNC, | 6502 | .type = HDA_FIXUP_FUNC, |
6491 | .v.func = alc233_alc662_fixup_lenovo_dual_codecs, | 6503 | .v.func = alc233_alc662_fixup_lenovo_dual_codecs, |
6492 | }, | 6504 | }, |
6505 | [ALC233_FIXUP_ACER_HEADSET_MIC] = { | ||
6506 | .type = HDA_FIXUP_VERBS, | ||
6507 | .v.verbs = (const struct hda_verb[]) { | ||
6508 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 }, | ||
6509 | { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 }, | ||
6510 | { } | ||
6511 | }, | ||
6512 | .chained = true, | ||
6513 | .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE | ||
6514 | }, | ||
6493 | [ALC294_FIXUP_LENOVO_MIC_LOCATION] = { | 6515 | [ALC294_FIXUP_LENOVO_MIC_LOCATION] = { |
6494 | .type = HDA_FIXUP_PINS, | 6516 | .type = HDA_FIXUP_PINS, |
6495 | .v.pins = (const struct hda_pintbl[]) { | 6517 | .v.pins = (const struct hda_pintbl[]) { |
@@ -6635,6 +6657,12 @@ static const struct hda_fixup alc269_fixups[] = { | |||
6635 | [ALC295_FIXUP_CHROME_BOOK] = { | 6657 | [ALC295_FIXUP_CHROME_BOOK] = { |
6636 | .type = HDA_FIXUP_FUNC, | 6658 | .type = HDA_FIXUP_FUNC, |
6637 | .v.func = alc295_fixup_chromebook, | 6659 | .v.func = alc295_fixup_chromebook, |
6660 | .chained = true, | ||
6661 | .chain_id = ALC225_FIXUP_HEADSET_JACK | ||
6662 | }, | ||
6663 | [ALC225_FIXUP_HEADSET_JACK] = { | ||
6664 | .type = HDA_FIXUP_FUNC, | ||
6665 | .v.func = alc_fixup_headset_jack, | ||
6638 | }, | 6666 | }, |
6639 | [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = { | 6667 | [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = { |
6640 | .type = HDA_FIXUP_PINS, | 6668 | .type = HDA_FIXUP_PINS, |
@@ -6737,6 +6765,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
6737 | SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), | 6765 | SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), |
6738 | SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), | 6766 | SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), |
6739 | SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), | 6767 | SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), |
6768 | SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC), | ||
6740 | SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC), | 6769 | SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC), |
6741 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 6770 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
6742 | SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), | 6771 | SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), |
@@ -7132,7 +7161,8 @@ static const struct hda_model_fixup alc269_fixup_models[] = { | |||
7132 | {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"}, | 7161 | {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"}, |
7133 | {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"}, | 7162 | {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"}, |
7134 | {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"}, | 7163 | {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"}, |
7135 | {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-sense-combo"}, | 7164 | {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"}, |
7165 | {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"}, | ||
7136 | {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"}, | 7166 | {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"}, |
7137 | {} | 7167 | {} |
7138 | }; | 7168 | }; |
@@ -7236,6 +7266,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { | |||
7236 | {0x12, 0x90a60140}, | 7266 | {0x12, 0x90a60140}, |
7237 | {0x14, 0x90170150}, | 7267 | {0x14, 0x90170150}, |
7238 | {0x21, 0x02211020}), | 7268 | {0x21, 0x02211020}), |
7269 | SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
7270 | {0x21, 0x02211020}), | ||
7239 | SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, | 7271 | SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, |
7240 | {0x14, 0x90170110}, | 7272 | {0x14, 0x90170110}, |
7241 | {0x21, 0x02211020}), | 7273 | {0x21, 0x02211020}), |
@@ -7346,6 +7378,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { | |||
7346 | {0x21, 0x0221101f}), | 7378 | {0x21, 0x0221101f}), |
7347 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | 7379 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, |
7348 | ALC256_STANDARD_PINS), | 7380 | ALC256_STANDARD_PINS), |
7381 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
7382 | {0x14, 0x90170110}, | ||
7383 | {0x1b, 0x01011020}, | ||
7384 | {0x21, 0x0221101f}), | ||
7349 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC, | 7385 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC, |
7350 | {0x14, 0x90170110}, | 7386 | {0x14, 0x90170110}, |
7351 | {0x1b, 0x90a70130}, | 7387 | {0x1b, 0x90a70130}, |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 419114edfd57..667fc1d59e18 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -1151,6 +1151,7 @@ config SND_SOC_WCD9335 | |||
1151 | tristate "WCD9335 Codec" | 1151 | tristate "WCD9335 Codec" |
1152 | depends on SLIMBUS | 1152 | depends on SLIMBUS |
1153 | select REGMAP_SLIMBUS | 1153 | select REGMAP_SLIMBUS |
1154 | select REGMAP_IRQ | ||
1154 | help | 1155 | help |
1155 | The WCD9335 is a standalone Hi-Fi audio CODEC IC, supports | 1156 | The WCD9335 is a standalone Hi-Fi audio CODEC IC, supports |
1156 | Qualcomm Technologies, Inc. (QTI) multimedia solutions, | 1157 | Qualcomm Technologies, Inc. (QTI) multimedia solutions, |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 03bbbcd3b6c1..87616b126018 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -2129,6 +2129,7 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
2129 | dev_err(dai->component->dev, | 2129 | dev_err(dai->component->dev, |
2130 | "%s: ERROR: The device is either a master or a slave.\n", | 2130 | "%s: ERROR: The device is either a master or a slave.\n", |
2131 | __func__); | 2131 | __func__); |
2132 | /* fall through */ | ||
2132 | default: | 2133 | default: |
2133 | dev_err(dai->component->dev, | 2134 | dev_err(dai->component->dev, |
2134 | "%s: ERROR: Unsupporter master mask 0x%x\n", | 2135 | "%s: ERROR: Unsupporter master mask 0x%x\n", |
diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c index 9f4a59871cee..c71696146c5e 100644 --- a/sound/soc/codecs/cs35l35.c +++ b/sound/soc/codecs/cs35l35.c | |||
@@ -1635,6 +1635,16 @@ err: | |||
1635 | return ret; | 1635 | return ret; |
1636 | } | 1636 | } |
1637 | 1637 | ||
1638 | static int cs35l35_i2c_remove(struct i2c_client *i2c_client) | ||
1639 | { | ||
1640 | struct cs35l35_private *cs35l35 = i2c_get_clientdata(i2c_client); | ||
1641 | |||
1642 | regulator_bulk_disable(cs35l35->num_supplies, cs35l35->supplies); | ||
1643 | gpiod_set_value_cansleep(cs35l35->reset_gpio, 0); | ||
1644 | |||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1638 | static const struct of_device_id cs35l35_of_match[] = { | 1648 | static const struct of_device_id cs35l35_of_match[] = { |
1639 | {.compatible = "cirrus,cs35l35"}, | 1649 | {.compatible = "cirrus,cs35l35"}, |
1640 | {}, | 1650 | {}, |
@@ -1655,6 +1665,7 @@ static struct i2c_driver cs35l35_i2c_driver = { | |||
1655 | }, | 1665 | }, |
1656 | .id_table = cs35l35_id, | 1666 | .id_table = cs35l35_id, |
1657 | .probe = cs35l35_i2c_probe, | 1667 | .probe = cs35l35_i2c_probe, |
1668 | .remove = cs35l35_i2c_remove, | ||
1658 | }; | 1669 | }; |
1659 | 1670 | ||
1660 | module_i2c_driver(cs35l35_i2c_driver); | 1671 | module_i2c_driver(cs35l35_i2c_driver); |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 33d74f163bd7..793a14d58667 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -642,6 +642,7 @@ static const struct regmap_config cs4270_regmap = { | |||
642 | .reg_defaults = cs4270_reg_defaults, | 642 | .reg_defaults = cs4270_reg_defaults, |
643 | .num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults), | 643 | .num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults), |
644 | .cache_type = REGCACHE_RBTREE, | 644 | .cache_type = REGCACHE_RBTREE, |
645 | .write_flag_mask = CS4270_I2C_INCR, | ||
645 | 646 | ||
646 | .readable_reg = cs4270_reg_is_readable, | 647 | .readable_reg = cs4270_reg_is_readable, |
647 | .volatile_reg = cs4270_reg_is_volatile, | 648 | .volatile_reg = cs4270_reg_is_volatile, |
diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c index ffecdaaa8cf2..f889d94c8e3c 100644 --- a/sound/soc/codecs/hdac_hda.c +++ b/sound/soc/codecs/hdac_hda.c | |||
@@ -38,6 +38,9 @@ static void hdac_hda_dai_close(struct snd_pcm_substream *substream, | |||
38 | struct snd_soc_dai *dai); | 38 | struct snd_soc_dai *dai); |
39 | static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, | 39 | static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, |
40 | struct snd_soc_dai *dai); | 40 | struct snd_soc_dai *dai); |
41 | static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream, | ||
42 | struct snd_pcm_hw_params *params, | ||
43 | struct snd_soc_dai *dai); | ||
41 | static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream, | 44 | static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream, |
42 | struct snd_soc_dai *dai); | 45 | struct snd_soc_dai *dai); |
43 | static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai, | 46 | static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai, |
@@ -50,6 +53,7 @@ static const struct snd_soc_dai_ops hdac_hda_dai_ops = { | |||
50 | .startup = hdac_hda_dai_open, | 53 | .startup = hdac_hda_dai_open, |
51 | .shutdown = hdac_hda_dai_close, | 54 | .shutdown = hdac_hda_dai_close, |
52 | .prepare = hdac_hda_dai_prepare, | 55 | .prepare = hdac_hda_dai_prepare, |
56 | .hw_params = hdac_hda_dai_hw_params, | ||
53 | .hw_free = hdac_hda_dai_hw_free, | 57 | .hw_free = hdac_hda_dai_hw_free, |
54 | .set_tdm_slot = hdac_hda_dai_set_tdm_slot, | 58 | .set_tdm_slot = hdac_hda_dai_set_tdm_slot, |
55 | }; | 59 | }; |
@@ -139,6 +143,39 @@ static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai, | |||
139 | return 0; | 143 | return 0; |
140 | } | 144 | } |
141 | 145 | ||
146 | static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream, | ||
147 | struct snd_pcm_hw_params *params, | ||
148 | struct snd_soc_dai *dai) | ||
149 | { | ||
150 | struct snd_soc_component *component = dai->component; | ||
151 | struct hdac_hda_priv *hda_pvt; | ||
152 | unsigned int format_val; | ||
153 | unsigned int maxbps; | ||
154 | |||
155 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
156 | maxbps = dai->driver->playback.sig_bits; | ||
157 | else | ||
158 | maxbps = dai->driver->capture.sig_bits; | ||
159 | |||
160 | hda_pvt = snd_soc_component_get_drvdata(component); | ||
161 | format_val = snd_hdac_calc_stream_format(params_rate(params), | ||
162 | params_channels(params), | ||
163 | params_format(params), | ||
164 | maxbps, | ||
165 | 0); | ||
166 | if (!format_val) { | ||
167 | dev_err(dai->dev, | ||
168 | "invalid format_val, rate=%d, ch=%d, format=%d, maxbps=%d\n", | ||
169 | params_rate(params), params_channels(params), | ||
170 | params_format(params), maxbps); | ||
171 | |||
172 | return -EINVAL; | ||
173 | } | ||
174 | |||
175 | hda_pvt->pcm[dai->id].format_val[substream->stream] = format_val; | ||
176 | return 0; | ||
177 | } | ||
178 | |||
142 | static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream, | 179 | static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream, |
143 | struct snd_soc_dai *dai) | 180 | struct snd_soc_dai *dai) |
144 | { | 181 | { |
@@ -162,10 +199,9 @@ static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, | |||
162 | struct snd_soc_dai *dai) | 199 | struct snd_soc_dai *dai) |
163 | { | 200 | { |
164 | struct snd_soc_component *component = dai->component; | 201 | struct snd_soc_component *component = dai->component; |
202 | struct hda_pcm_stream *hda_stream; | ||
165 | struct hdac_hda_priv *hda_pvt; | 203 | struct hdac_hda_priv *hda_pvt; |
166 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
167 | struct hdac_device *hdev; | 204 | struct hdac_device *hdev; |
168 | struct hda_pcm_stream *hda_stream; | ||
169 | unsigned int format_val; | 205 | unsigned int format_val; |
170 | struct hda_pcm *pcm; | 206 | struct hda_pcm *pcm; |
171 | unsigned int stream; | 207 | unsigned int stream; |
@@ -179,19 +215,8 @@ static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream, | |||
179 | 215 | ||
180 | hda_stream = &pcm->stream[substream->stream]; | 216 | hda_stream = &pcm->stream[substream->stream]; |
181 | 217 | ||
182 | format_val = snd_hdac_calc_stream_format(runtime->rate, | ||
183 | runtime->channels, | ||
184 | runtime->format, | ||
185 | hda_stream->maxbps, | ||
186 | 0); | ||
187 | if (!format_val) { | ||
188 | dev_err(&hdev->dev, | ||
189 | "invalid format_val, rate=%d, ch=%d, format=%d\n", | ||
190 | runtime->rate, runtime->channels, runtime->format); | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | |||
194 | stream = hda_pvt->pcm[dai->id].stream_tag[substream->stream]; | 218 | stream = hda_pvt->pcm[dai->id].stream_tag[substream->stream]; |
219 | format_val = hda_pvt->pcm[dai->id].format_val[substream->stream]; | ||
195 | 220 | ||
196 | ret = snd_hda_codec_prepare(&hda_pvt->codec, hda_stream, | 221 | ret = snd_hda_codec_prepare(&hda_pvt->codec, hda_stream, |
197 | stream, format_val, substream); | 222 | stream, format_val, substream); |
diff --git a/sound/soc/codecs/hdac_hda.h b/sound/soc/codecs/hdac_hda.h index e444ef593360..6b1bd4f428e7 100644 --- a/sound/soc/codecs/hdac_hda.h +++ b/sound/soc/codecs/hdac_hda.h | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | struct hdac_hda_pcm { | 9 | struct hdac_hda_pcm { |
10 | int stream_tag[2]; | 10 | int stream_tag[2]; |
11 | unsigned int format_val[2]; | ||
11 | }; | 12 | }; |
12 | 13 | ||
13 | struct hdac_hda_priv { | 14 | struct hdac_hda_priv { |
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index e5b6769b9797..35df73e42cbc 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c | |||
@@ -484,9 +484,6 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, | |||
484 | params_width(params), params_rate(params), | 484 | params_width(params), params_rate(params), |
485 | params_channels(params)); | 485 | params_channels(params)); |
486 | 486 | ||
487 | if (params_width(params) > 24) | ||
488 | params->msbits = 24; | ||
489 | |||
490 | ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status, | 487 | ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status, |
491 | sizeof(hp.iec.status)); | 488 | sizeof(hp.iec.status)); |
492 | if (ret < 0) { | 489 | if (ret < 0) { |
@@ -529,73 +526,71 @@ static int hdmi_codec_set_fmt(struct snd_soc_dai *dai, | |||
529 | { | 526 | { |
530 | struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); | 527 | struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); |
531 | struct hdmi_codec_daifmt cf = { 0 }; | 528 | struct hdmi_codec_daifmt cf = { 0 }; |
532 | int ret = 0; | ||
533 | 529 | ||
534 | dev_dbg(dai->dev, "%s()\n", __func__); | 530 | dev_dbg(dai->dev, "%s()\n", __func__); |
535 | 531 | ||
536 | if (dai->id == DAI_ID_SPDIF) { | 532 | if (dai->id == DAI_ID_SPDIF) |
537 | cf.fmt = HDMI_SPDIF; | 533 | return 0; |
538 | } else { | 534 | |
539 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 535 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
540 | case SND_SOC_DAIFMT_CBM_CFM: | 536 | case SND_SOC_DAIFMT_CBM_CFM: |
541 | cf.bit_clk_master = 1; | 537 | cf.bit_clk_master = 1; |
542 | cf.frame_clk_master = 1; | 538 | cf.frame_clk_master = 1; |
543 | break; | 539 | break; |
544 | case SND_SOC_DAIFMT_CBS_CFM: | 540 | case SND_SOC_DAIFMT_CBS_CFM: |
545 | cf.frame_clk_master = 1; | 541 | cf.frame_clk_master = 1; |
546 | break; | 542 | break; |
547 | case SND_SOC_DAIFMT_CBM_CFS: | 543 | case SND_SOC_DAIFMT_CBM_CFS: |
548 | cf.bit_clk_master = 1; | 544 | cf.bit_clk_master = 1; |
549 | break; | 545 | break; |
550 | case SND_SOC_DAIFMT_CBS_CFS: | 546 | case SND_SOC_DAIFMT_CBS_CFS: |
551 | break; | 547 | break; |
552 | default: | 548 | default: |
553 | return -EINVAL; | 549 | return -EINVAL; |
554 | } | 550 | } |
555 | 551 | ||
556 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 552 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
557 | case SND_SOC_DAIFMT_NB_NF: | 553 | case SND_SOC_DAIFMT_NB_NF: |
558 | break; | 554 | break; |
559 | case SND_SOC_DAIFMT_NB_IF: | 555 | case SND_SOC_DAIFMT_NB_IF: |
560 | cf.frame_clk_inv = 1; | 556 | cf.frame_clk_inv = 1; |
561 | break; | 557 | break; |
562 | case SND_SOC_DAIFMT_IB_NF: | 558 | case SND_SOC_DAIFMT_IB_NF: |
563 | cf.bit_clk_inv = 1; | 559 | cf.bit_clk_inv = 1; |
564 | break; | 560 | break; |
565 | case SND_SOC_DAIFMT_IB_IF: | 561 | case SND_SOC_DAIFMT_IB_IF: |
566 | cf.frame_clk_inv = 1; | 562 | cf.frame_clk_inv = 1; |
567 | cf.bit_clk_inv = 1; | 563 | cf.bit_clk_inv = 1; |
568 | break; | 564 | break; |
569 | } | 565 | } |
570 | 566 | ||
571 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 567 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
572 | case SND_SOC_DAIFMT_I2S: | 568 | case SND_SOC_DAIFMT_I2S: |
573 | cf.fmt = HDMI_I2S; | 569 | cf.fmt = HDMI_I2S; |
574 | break; | 570 | break; |
575 | case SND_SOC_DAIFMT_DSP_A: | 571 | case SND_SOC_DAIFMT_DSP_A: |
576 | cf.fmt = HDMI_DSP_A; | 572 | cf.fmt = HDMI_DSP_A; |
577 | break; | 573 | break; |
578 | case SND_SOC_DAIFMT_DSP_B: | 574 | case SND_SOC_DAIFMT_DSP_B: |
579 | cf.fmt = HDMI_DSP_B; | 575 | cf.fmt = HDMI_DSP_B; |
580 | break; | 576 | break; |
581 | case SND_SOC_DAIFMT_RIGHT_J: | 577 | case SND_SOC_DAIFMT_RIGHT_J: |
582 | cf.fmt = HDMI_RIGHT_J; | 578 | cf.fmt = HDMI_RIGHT_J; |
583 | break; | 579 | break; |
584 | case SND_SOC_DAIFMT_LEFT_J: | 580 | case SND_SOC_DAIFMT_LEFT_J: |
585 | cf.fmt = HDMI_LEFT_J; | 581 | cf.fmt = HDMI_LEFT_J; |
586 | break; | 582 | break; |
587 | case SND_SOC_DAIFMT_AC97: | 583 | case SND_SOC_DAIFMT_AC97: |
588 | cf.fmt = HDMI_AC97; | 584 | cf.fmt = HDMI_AC97; |
589 | break; | 585 | break; |
590 | default: | 586 | default: |
591 | dev_err(dai->dev, "Invalid DAI interface format\n"); | 587 | dev_err(dai->dev, "Invalid DAI interface format\n"); |
592 | return -EINVAL; | 588 | return -EINVAL; |
593 | } | ||
594 | } | 589 | } |
595 | 590 | ||
596 | hcp->daifmt[dai->id] = cf; | 591 | hcp->daifmt[dai->id] = cf; |
597 | 592 | ||
598 | return ret; | 593 | return 0; |
599 | } | 594 | } |
600 | 595 | ||
601 | static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute) | 596 | static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute) |
@@ -792,8 +787,10 @@ static int hdmi_codec_probe(struct platform_device *pdev) | |||
792 | i++; | 787 | i++; |
793 | } | 788 | } |
794 | 789 | ||
795 | if (hcd->spdif) | 790 | if (hcd->spdif) { |
796 | hcp->daidrv[i] = hdmi_spdif_dai; | 791 | hcp->daidrv[i] = hdmi_spdif_dai; |
792 | hcp->daifmt[DAI_ID_SPDIF].fmt = HDMI_SPDIF; | ||
793 | } | ||
797 | 794 | ||
798 | dev_set_drvdata(dev, hcp); | 795 | dev_set_drvdata(dev, hcp); |
799 | 796 | ||
diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index bfd74b86c9d2..645aa0794123 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c | |||
@@ -411,9 +411,9 @@ static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = { | |||
411 | SND_SOC_DAPM_MIXER("Mono Mixer", NAU8810_REG_POWER3, | 411 | SND_SOC_DAPM_MIXER("Mono Mixer", NAU8810_REG_POWER3, |
412 | NAU8810_MOUTMX_EN_SFT, 0, &nau8810_mono_mixer_controls[0], | 412 | NAU8810_MOUTMX_EN_SFT, 0, &nau8810_mono_mixer_controls[0], |
413 | ARRAY_SIZE(nau8810_mono_mixer_controls)), | 413 | ARRAY_SIZE(nau8810_mono_mixer_controls)), |
414 | SND_SOC_DAPM_DAC("DAC", "HiFi Playback", NAU8810_REG_POWER3, | 414 | SND_SOC_DAPM_DAC("DAC", "Playback", NAU8810_REG_POWER3, |
415 | NAU8810_DAC_EN_SFT, 0), | 415 | NAU8810_DAC_EN_SFT, 0), |
416 | SND_SOC_DAPM_ADC("ADC", "HiFi Capture", NAU8810_REG_POWER2, | 416 | SND_SOC_DAPM_ADC("ADC", "Capture", NAU8810_REG_POWER2, |
417 | NAU8810_ADC_EN_SFT, 0), | 417 | NAU8810_ADC_EN_SFT, 0), |
418 | SND_SOC_DAPM_PGA("SpkN Out", NAU8810_REG_POWER3, | 418 | SND_SOC_DAPM_PGA("SpkN Out", NAU8810_REG_POWER3, |
419 | NAU8810_NSPK_EN_SFT, 0, NULL, 0), | 419 | NAU8810_NSPK_EN_SFT, 0, NULL, 0), |
diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index 87ed3dc496dc..5ab05e75edea 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c | |||
@@ -681,8 +681,8 @@ static const struct snd_soc_dapm_widget nau8824_dapm_widgets[] = { | |||
681 | SND_SOC_DAPM_ADC("ADCR", NULL, NAU8824_REG_ANALOG_ADC_2, | 681 | SND_SOC_DAPM_ADC("ADCR", NULL, NAU8824_REG_ANALOG_ADC_2, |
682 | NAU8824_ADCR_EN_SFT, 0), | 682 | NAU8824_ADCR_EN_SFT, 0), |
683 | 683 | ||
684 | SND_SOC_DAPM_AIF_OUT("AIFTX", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0), | 684 | SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0), |
685 | SND_SOC_DAPM_AIF_IN("AIFRX", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0), | 685 | SND_SOC_DAPM_AIF_IN("AIFRX", "Playback", 0, SND_SOC_NOPM, 0, 0), |
686 | 686 | ||
687 | SND_SOC_DAPM_DAC("DACL", NULL, NAU8824_REG_RDAC, | 687 | SND_SOC_DAPM_DAC("DACL", NULL, NAU8824_REG_RDAC, |
688 | NAU8824_DACL_EN_SFT, 0), | 688 | NAU8824_DACL_EN_SFT, 0), |
@@ -831,6 +831,36 @@ static void nau8824_int_status_clear_all(struct regmap *regmap) | |||
831 | } | 831 | } |
832 | } | 832 | } |
833 | 833 | ||
834 | static void nau8824_dapm_disable_pin(struct nau8824 *nau8824, const char *pin) | ||
835 | { | ||
836 | struct snd_soc_dapm_context *dapm = nau8824->dapm; | ||
837 | const char *prefix = dapm->component->name_prefix; | ||
838 | char prefixed_pin[80]; | ||
839 | |||
840 | if (prefix) { | ||
841 | snprintf(prefixed_pin, sizeof(prefixed_pin), "%s %s", | ||
842 | prefix, pin); | ||
843 | snd_soc_dapm_disable_pin(dapm, prefixed_pin); | ||
844 | } else { | ||
845 | snd_soc_dapm_disable_pin(dapm, pin); | ||
846 | } | ||
847 | } | ||
848 | |||
849 | static void nau8824_dapm_enable_pin(struct nau8824 *nau8824, const char *pin) | ||
850 | { | ||
851 | struct snd_soc_dapm_context *dapm = nau8824->dapm; | ||
852 | const char *prefix = dapm->component->name_prefix; | ||
853 | char prefixed_pin[80]; | ||
854 | |||
855 | if (prefix) { | ||
856 | snprintf(prefixed_pin, sizeof(prefixed_pin), "%s %s", | ||
857 | prefix, pin); | ||
858 | snd_soc_dapm_force_enable_pin(dapm, prefixed_pin); | ||
859 | } else { | ||
860 | snd_soc_dapm_force_enable_pin(dapm, pin); | ||
861 | } | ||
862 | } | ||
863 | |||
834 | static void nau8824_eject_jack(struct nau8824 *nau8824) | 864 | static void nau8824_eject_jack(struct nau8824 *nau8824) |
835 | { | 865 | { |
836 | struct snd_soc_dapm_context *dapm = nau8824->dapm; | 866 | struct snd_soc_dapm_context *dapm = nau8824->dapm; |
@@ -839,8 +869,8 @@ static void nau8824_eject_jack(struct nau8824 *nau8824) | |||
839 | /* Clear all interruption status */ | 869 | /* Clear all interruption status */ |
840 | nau8824_int_status_clear_all(regmap); | 870 | nau8824_int_status_clear_all(regmap); |
841 | 871 | ||
842 | snd_soc_dapm_disable_pin(dapm, "SAR"); | 872 | nau8824_dapm_disable_pin(nau8824, "SAR"); |
843 | snd_soc_dapm_disable_pin(dapm, "MICBIAS"); | 873 | nau8824_dapm_disable_pin(nau8824, "MICBIAS"); |
844 | snd_soc_dapm_sync(dapm); | 874 | snd_soc_dapm_sync(dapm); |
845 | 875 | ||
846 | /* Enable the insertion interruption, disable the ejection | 876 | /* Enable the insertion interruption, disable the ejection |
@@ -870,8 +900,8 @@ static void nau8824_jdet_work(struct work_struct *work) | |||
870 | struct regmap *regmap = nau8824->regmap; | 900 | struct regmap *regmap = nau8824->regmap; |
871 | int adc_value, event = 0, event_mask = 0; | 901 | int adc_value, event = 0, event_mask = 0; |
872 | 902 | ||
873 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); | 903 | nau8824_dapm_enable_pin(nau8824, "MICBIAS"); |
874 | snd_soc_dapm_force_enable_pin(dapm, "SAR"); | 904 | nau8824_dapm_enable_pin(nau8824, "SAR"); |
875 | snd_soc_dapm_sync(dapm); | 905 | snd_soc_dapm_sync(dapm); |
876 | 906 | ||
877 | msleep(100); | 907 | msleep(100); |
@@ -882,8 +912,8 @@ static void nau8824_jdet_work(struct work_struct *work) | |||
882 | if (adc_value < HEADSET_SARADC_THD) { | 912 | if (adc_value < HEADSET_SARADC_THD) { |
883 | event |= SND_JACK_HEADPHONE; | 913 | event |= SND_JACK_HEADPHONE; |
884 | 914 | ||
885 | snd_soc_dapm_disable_pin(dapm, "SAR"); | 915 | nau8824_dapm_disable_pin(nau8824, "SAR"); |
886 | snd_soc_dapm_disable_pin(dapm, "MICBIAS"); | 916 | nau8824_dapm_disable_pin(nau8824, "MICBIAS"); |
887 | snd_soc_dapm_sync(dapm); | 917 | snd_soc_dapm_sync(dapm); |
888 | } else { | 918 | } else { |
889 | event |= SND_JACK_HEADSET; | 919 | event |= SND_JACK_HEADSET; |
diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 9d5acd2d04ab..86a7fa31c294 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c | |||
@@ -910,13 +910,21 @@ static int rt5682_headset_detect(struct snd_soc_component *component, | |||
910 | int jack_insert) | 910 | int jack_insert) |
911 | { | 911 | { |
912 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); | 912 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); |
913 | struct snd_soc_dapm_context *dapm = | ||
914 | snd_soc_component_get_dapm(component); | ||
915 | unsigned int val, count; | 913 | unsigned int val, count; |
916 | 914 | ||
917 | if (jack_insert) { | 915 | if (jack_insert) { |
918 | snd_soc_dapm_force_enable_pin(dapm, "CBJ Power"); | 916 | |
919 | snd_soc_dapm_sync(dapm); | 917 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, |
918 | RT5682_PWR_VREF2 | RT5682_PWR_MB, | ||
919 | RT5682_PWR_VREF2 | RT5682_PWR_MB); | ||
920 | snd_soc_component_update_bits(component, | ||
921 | RT5682_PWR_ANLG_1, RT5682_PWR_FV2, 0); | ||
922 | usleep_range(15000, 20000); | ||
923 | snd_soc_component_update_bits(component, | ||
924 | RT5682_PWR_ANLG_1, RT5682_PWR_FV2, RT5682_PWR_FV2); | ||
925 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, | ||
926 | RT5682_PWR_CBJ, RT5682_PWR_CBJ); | ||
927 | |||
920 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, | 928 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, |
921 | RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_HIGH); | 929 | RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_HIGH); |
922 | 930 | ||
@@ -944,8 +952,10 @@ static int rt5682_headset_detect(struct snd_soc_component *component, | |||
944 | rt5682_enable_push_button_irq(component, false); | 952 | rt5682_enable_push_button_irq(component, false); |
945 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, | 953 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, |
946 | RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); | 954 | RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); |
947 | snd_soc_dapm_disable_pin(dapm, "CBJ Power"); | 955 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, |
948 | snd_soc_dapm_sync(dapm); | 956 | RT5682_PWR_VREF2 | RT5682_PWR_MB, 0); |
957 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, | ||
958 | RT5682_PWR_CBJ, 0); | ||
949 | 959 | ||
950 | rt5682->jack_type = 0; | 960 | rt5682->jack_type = 0; |
951 | } | 961 | } |
@@ -1198,7 +1208,7 @@ static int set_filter_clk(struct snd_soc_dapm_widget *w, | |||
1198 | struct snd_soc_component *component = | 1208 | struct snd_soc_component *component = |
1199 | snd_soc_dapm_to_component(w->dapm); | 1209 | snd_soc_dapm_to_component(w->dapm); |
1200 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); | 1210 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); |
1201 | int ref, val, reg, sft, mask, idx = -EINVAL; | 1211 | int ref, val, reg, idx = -EINVAL; |
1202 | static const int div_f[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48}; | 1212 | static const int div_f[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48}; |
1203 | static const int div_o[] = {1, 2, 4, 6, 8, 12, 16, 24, 32, 48}; | 1213 | static const int div_o[] = {1, 2, 4, 6, 8, 12, 16, 24, 32, 48}; |
1204 | 1214 | ||
@@ -1212,15 +1222,10 @@ static int set_filter_clk(struct snd_soc_dapm_widget *w, | |||
1212 | 1222 | ||
1213 | idx = rt5682_div_sel(rt5682, ref, div_f, ARRAY_SIZE(div_f)); | 1223 | idx = rt5682_div_sel(rt5682, ref, div_f, ARRAY_SIZE(div_f)); |
1214 | 1224 | ||
1215 | if (w->shift == RT5682_PWR_ADC_S1F_BIT) { | 1225 | if (w->shift == RT5682_PWR_ADC_S1F_BIT) |
1216 | reg = RT5682_PLL_TRACK_3; | 1226 | reg = RT5682_PLL_TRACK_3; |
1217 | sft = RT5682_ADC_OSR_SFT; | 1227 | else |
1218 | mask = RT5682_ADC_OSR_MASK; | ||
1219 | } else { | ||
1220 | reg = RT5682_PLL_TRACK_2; | 1228 | reg = RT5682_PLL_TRACK_2; |
1221 | sft = RT5682_DAC_OSR_SFT; | ||
1222 | mask = RT5682_DAC_OSR_MASK; | ||
1223 | } | ||
1224 | 1229 | ||
1225 | snd_soc_component_update_bits(component, reg, | 1230 | snd_soc_component_update_bits(component, reg, |
1226 | RT5682_FILTER_CLK_DIV_MASK, idx << RT5682_FILTER_CLK_DIV_SFT); | 1231 | RT5682_FILTER_CLK_DIV_MASK, idx << RT5682_FILTER_CLK_DIV_SFT); |
@@ -1232,7 +1237,8 @@ static int set_filter_clk(struct snd_soc_dapm_widget *w, | |||
1232 | } | 1237 | } |
1233 | 1238 | ||
1234 | snd_soc_component_update_bits(component, RT5682_ADDA_CLK_1, | 1239 | snd_soc_component_update_bits(component, RT5682_ADDA_CLK_1, |
1235 | mask, idx << sft); | 1240 | RT5682_ADC_OSR_MASK | RT5682_DAC_OSR_MASK, |
1241 | (idx << RT5682_ADC_OSR_SFT) | (idx << RT5682_DAC_OSR_SFT)); | ||
1236 | 1242 | ||
1237 | return 0; | 1243 | return 0; |
1238 | } | 1244 | } |
@@ -1591,8 +1597,6 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { | |||
1591 | 0, NULL, 0), | 1597 | 0, NULL, 0), |
1592 | SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0, | 1598 | SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0, |
1593 | rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | 1599 | rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), |
1594 | SND_SOC_DAPM_SUPPLY("Vref2", RT5682_PWR_ANLG_1, RT5682_PWR_VREF2_BIT, 0, | ||
1595 | rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
1596 | 1600 | ||
1597 | /* ASRC */ | 1601 | /* ASRC */ |
1598 | SND_SOC_DAPM_SUPPLY_S("DAC STO1 ASRC", 1, RT5682_PLL_TRACK_1, | 1602 | SND_SOC_DAPM_SUPPLY_S("DAC STO1 ASRC", 1, RT5682_PLL_TRACK_1, |
@@ -1627,9 +1631,6 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { | |||
1627 | SND_SOC_DAPM_PGA("BST1 CBJ", SND_SOC_NOPM, | 1631 | SND_SOC_DAPM_PGA("BST1 CBJ", SND_SOC_NOPM, |
1628 | 0, 0, NULL, 0), | 1632 | 0, 0, NULL, 0), |
1629 | 1633 | ||
1630 | SND_SOC_DAPM_SUPPLY("CBJ Power", RT5682_PWR_ANLG_3, | ||
1631 | RT5682_PWR_CBJ_BIT, 0, NULL, 0), | ||
1632 | |||
1633 | /* REC Mixer */ | 1634 | /* REC Mixer */ |
1634 | SND_SOC_DAPM_MIXER("RECMIX1L", SND_SOC_NOPM, 0, 0, rt5682_rec1_l_mix, | 1635 | SND_SOC_DAPM_MIXER("RECMIX1L", SND_SOC_NOPM, 0, 0, rt5682_rec1_l_mix, |
1635 | ARRAY_SIZE(rt5682_rec1_l_mix)), | 1636 | ARRAY_SIZE(rt5682_rec1_l_mix)), |
@@ -1792,17 +1793,13 @@ static const struct snd_soc_dapm_route rt5682_dapm_routes[] = { | |||
1792 | 1793 | ||
1793 | /*Vref*/ | 1794 | /*Vref*/ |
1794 | {"MICBIAS1", NULL, "Vref1"}, | 1795 | {"MICBIAS1", NULL, "Vref1"}, |
1795 | {"MICBIAS1", NULL, "Vref2"}, | ||
1796 | {"MICBIAS2", NULL, "Vref1"}, | 1796 | {"MICBIAS2", NULL, "Vref1"}, |
1797 | {"MICBIAS2", NULL, "Vref2"}, | ||
1798 | 1797 | ||
1799 | {"CLKDET SYS", NULL, "CLKDET"}, | 1798 | {"CLKDET SYS", NULL, "CLKDET"}, |
1800 | 1799 | ||
1801 | {"IN1P", NULL, "LDO2"}, | 1800 | {"IN1P", NULL, "LDO2"}, |
1802 | 1801 | ||
1803 | {"BST1 CBJ", NULL, "IN1P"}, | 1802 | {"BST1 CBJ", NULL, "IN1P"}, |
1804 | {"BST1 CBJ", NULL, "CBJ Power"}, | ||
1805 | {"CBJ Power", NULL, "Vref2"}, | ||
1806 | 1803 | ||
1807 | {"RECMIX1L", "CBJ Switch", "BST1 CBJ"}, | 1804 | {"RECMIX1L", "CBJ Switch", "BST1 CBJ"}, |
1808 | {"RECMIX1L", NULL, "RECMIX1L Power"}, | 1805 | {"RECMIX1L", NULL, "RECMIX1L Power"}, |
@@ -1912,9 +1909,7 @@ static const struct snd_soc_dapm_route rt5682_dapm_routes[] = { | |||
1912 | {"HP Amp", NULL, "Capless"}, | 1909 | {"HP Amp", NULL, "Capless"}, |
1913 | {"HP Amp", NULL, "Charge Pump"}, | 1910 | {"HP Amp", NULL, "Charge Pump"}, |
1914 | {"HP Amp", NULL, "CLKDET SYS"}, | 1911 | {"HP Amp", NULL, "CLKDET SYS"}, |
1915 | {"HP Amp", NULL, "CBJ Power"}, | ||
1916 | {"HP Amp", NULL, "Vref1"}, | 1912 | {"HP Amp", NULL, "Vref1"}, |
1917 | {"HP Amp", NULL, "Vref2"}, | ||
1918 | {"HPOL Playback", "Switch", "HP Amp"}, | 1913 | {"HPOL Playback", "Switch", "HP Amp"}, |
1919 | {"HPOR Playback", "Switch", "HP Amp"}, | 1914 | {"HPOR Playback", "Switch", "HP Amp"}, |
1920 | {"HPOL", NULL, "HPOL Playback"}, | 1915 | {"HPOL", NULL, "HPOL Playback"}, |
@@ -2303,16 +2298,13 @@ static int rt5682_set_bias_level(struct snd_soc_component *component, | |||
2303 | switch (level) { | 2298 | switch (level) { |
2304 | case SND_SOC_BIAS_PREPARE: | 2299 | case SND_SOC_BIAS_PREPARE: |
2305 | regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, | 2300 | regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, |
2306 | RT5682_PWR_MB | RT5682_PWR_BG, | 2301 | RT5682_PWR_BG, RT5682_PWR_BG); |
2307 | RT5682_PWR_MB | RT5682_PWR_BG); | ||
2308 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, | 2302 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, |
2309 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO, | 2303 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO, |
2310 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO); | 2304 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO); |
2311 | break; | 2305 | break; |
2312 | 2306 | ||
2313 | case SND_SOC_BIAS_STANDBY: | 2307 | case SND_SOC_BIAS_STANDBY: |
2314 | regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, | ||
2315 | RT5682_PWR_MB, RT5682_PWR_MB); | ||
2316 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, | 2308 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, |
2317 | RT5682_DIG_GATE_CTRL, RT5682_DIG_GATE_CTRL); | 2309 | RT5682_DIG_GATE_CTRL, RT5682_DIG_GATE_CTRL); |
2318 | break; | 2310 | break; |
@@ -2320,7 +2312,7 @@ static int rt5682_set_bias_level(struct snd_soc_component *component, | |||
2320 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, | 2312 | regmap_update_bits(rt5682->regmap, RT5682_PWR_DIG_1, |
2321 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO, 0); | 2313 | RT5682_DIG_GATE_CTRL | RT5682_PWR_LDO, 0); |
2322 | regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, | 2314 | regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, |
2323 | RT5682_PWR_MB | RT5682_PWR_BG, 0); | 2315 | RT5682_PWR_BG, 0); |
2324 | break; | 2316 | break; |
2325 | 2317 | ||
2326 | default: | 2318 | default: |
@@ -2363,6 +2355,8 @@ static int rt5682_resume(struct snd_soc_component *component) | |||
2363 | regcache_cache_only(rt5682->regmap, false); | 2355 | regcache_cache_only(rt5682->regmap, false); |
2364 | regcache_sync(rt5682->regmap); | 2356 | regcache_sync(rt5682->regmap); |
2365 | 2357 | ||
2358 | rt5682_irq(0, rt5682); | ||
2359 | |||
2366 | return 0; | 2360 | return 0; |
2367 | } | 2361 | } |
2368 | #else | 2362 | #else |
diff --git a/sound/soc/codecs/tlv320aic32x4-i2c.c b/sound/soc/codecs/tlv320aic32x4-i2c.c index 385fa2e9525a..22c3a6bc0b6c 100644 --- a/sound/soc/codecs/tlv320aic32x4-i2c.c +++ b/sound/soc/codecs/tlv320aic32x4-i2c.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright 2011 NW Digital Radio | 4 | * Copyright 2011 NW Digital Radio |
5 | * | 5 | * |
6 | * Author: Jeremy McDermond <nh6z@nh6z.net> | 6 | * Author: Annaliese McDermond <nh6z@nh6z.net> |
7 | * | 7 | * |
8 | * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. | 8 | * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. |
9 | * | 9 | * |
@@ -72,5 +72,5 @@ static struct i2c_driver aic32x4_i2c_driver = { | |||
72 | module_i2c_driver(aic32x4_i2c_driver); | 72 | module_i2c_driver(aic32x4_i2c_driver); |
73 | 73 | ||
74 | MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver I2C"); | 74 | MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver I2C"); |
75 | MODULE_AUTHOR("Jeremy McDermond <nh6z@nh6z.net>"); | 75 | MODULE_AUTHOR("Annaliese McDermond <nh6z@nh6z.net>"); |
76 | MODULE_LICENSE("GPL"); | 76 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/tlv320aic32x4-spi.c b/sound/soc/codecs/tlv320aic32x4-spi.c index 07d78ae51e05..aa5b7ba0254b 100644 --- a/sound/soc/codecs/tlv320aic32x4-spi.c +++ b/sound/soc/codecs/tlv320aic32x4-spi.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright 2011 NW Digital Radio | 4 | * Copyright 2011 NW Digital Radio |
5 | * | 5 | * |
6 | * Author: Jeremy McDermond <nh6z@nh6z.net> | 6 | * Author: Annaliese McDermond <nh6z@nh6z.net> |
7 | * | 7 | * |
8 | * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. | 8 | * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. |
9 | * | 9 | * |
@@ -74,5 +74,5 @@ static struct spi_driver aic32x4_spi_driver = { | |||
74 | module_spi_driver(aic32x4_spi_driver); | 74 | module_spi_driver(aic32x4_spi_driver); |
75 | 75 | ||
76 | MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver SPI"); | 76 | MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver SPI"); |
77 | MODULE_AUTHOR("Jeremy McDermond <nh6z@nh6z.net>"); | 77 | MODULE_AUTHOR("Annaliese McDermond <nh6z@nh6z.net>"); |
78 | MODULE_LICENSE("GPL"); | 78 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 96f1526cb258..5520044929f4 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -490,6 +490,8 @@ static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = { | |||
490 | SND_SOC_DAPM_INPUT("IN2_R"), | 490 | SND_SOC_DAPM_INPUT("IN2_R"), |
491 | SND_SOC_DAPM_INPUT("IN3_L"), | 491 | SND_SOC_DAPM_INPUT("IN3_L"), |
492 | SND_SOC_DAPM_INPUT("IN3_R"), | 492 | SND_SOC_DAPM_INPUT("IN3_R"), |
493 | SND_SOC_DAPM_INPUT("CM_L"), | ||
494 | SND_SOC_DAPM_INPUT("CM_R"), | ||
493 | }; | 495 | }; |
494 | 496 | ||
495 | static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = { | 497 | static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = { |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 283583d1db60..516d17cb2182 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -1609,7 +1609,6 @@ static int aic3x_probe(struct snd_soc_component *component) | |||
1609 | struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component); | 1609 | struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component); |
1610 | int ret, i; | 1610 | int ret, i; |
1611 | 1611 | ||
1612 | INIT_LIST_HEAD(&aic3x->list); | ||
1613 | aic3x->component = component; | 1612 | aic3x->component = component; |
1614 | 1613 | ||
1615 | for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) { | 1614 | for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) { |
@@ -1873,6 +1872,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
1873 | if (ret != 0) | 1872 | if (ret != 0) |
1874 | goto err_gpio; | 1873 | goto err_gpio; |
1875 | 1874 | ||
1875 | INIT_LIST_HEAD(&aic3x->list); | ||
1876 | list_add(&aic3x->list, &reset_list); | 1876 | list_add(&aic3x->list, &reset_list); |
1877 | 1877 | ||
1878 | return 0; | 1878 | return 0; |
@@ -1889,6 +1889,8 @@ static int aic3x_i2c_remove(struct i2c_client *client) | |||
1889 | { | 1889 | { |
1890 | struct aic3x_priv *aic3x = i2c_get_clientdata(client); | 1890 | struct aic3x_priv *aic3x = i2c_get_clientdata(client); |
1891 | 1891 | ||
1892 | list_del(&aic3x->list); | ||
1893 | |||
1892 | if (gpio_is_valid(aic3x->gpio_reset) && | 1894 | if (gpio_is_valid(aic3x->gpio_reset) && |
1893 | !aic3x_is_shared_reset(aic3x)) { | 1895 | !aic3x_is_shared_reset(aic3x)) { |
1894 | gpio_set_value(aic3x->gpio_reset, 0); | 1896 | gpio_set_value(aic3x->gpio_reset, 0); |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index b93fdc8d2d6f..b0b48eb9c7c9 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -2905,6 +2905,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
2905 | if (wm_adsp_fw[dsp->fw].num_caps != 0) | 2905 | if (wm_adsp_fw[dsp->fw].num_caps != 0) |
2906 | wm_adsp_buffer_free(dsp); | 2906 | wm_adsp_buffer_free(dsp); |
2907 | 2907 | ||
2908 | dsp->fatal_error = false; | ||
2909 | |||
2908 | mutex_unlock(&dsp->pwr_lock); | 2910 | mutex_unlock(&dsp->pwr_lock); |
2909 | 2911 | ||
2910 | adsp_dbg(dsp, "Execution stopped\n"); | 2912 | adsp_dbg(dsp, "Execution stopped\n"); |
@@ -3000,6 +3002,9 @@ static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) | |||
3000 | { | 3002 | { |
3001 | struct wm_adsp_compr_buf *buf = NULL, *tmp; | 3003 | struct wm_adsp_compr_buf *buf = NULL, *tmp; |
3002 | 3004 | ||
3005 | if (compr->dsp->fatal_error) | ||
3006 | return -EINVAL; | ||
3007 | |||
3003 | list_for_each_entry(tmp, &compr->dsp->buffer_list, list) { | 3008 | list_for_each_entry(tmp, &compr->dsp->buffer_list, list) { |
3004 | if (!tmp->name || !strcmp(compr->name, tmp->name)) { | 3009 | if (!tmp->name || !strcmp(compr->name, tmp->name)) { |
3005 | buf = tmp; | 3010 | buf = tmp; |
@@ -3535,11 +3540,11 @@ static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf) | |||
3535 | 3540 | ||
3536 | ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); | 3541 | ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); |
3537 | if (ret < 0) { | 3542 | if (ret < 0) { |
3538 | adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret); | 3543 | compr_err(buf, "Failed to check buffer error: %d\n", ret); |
3539 | return ret; | 3544 | return ret; |
3540 | } | 3545 | } |
3541 | if (buf->error != 0) { | 3546 | if (buf->error != 0) { |
3542 | adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error); | 3547 | compr_err(buf, "Buffer error occurred: %d\n", buf->error); |
3543 | return -EIO; | 3548 | return -EIO; |
3544 | } | 3549 | } |
3545 | 3550 | ||
@@ -3571,8 +3576,6 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) | |||
3571 | if (ret < 0) | 3576 | if (ret < 0) |
3572 | break; | 3577 | break; |
3573 | 3578 | ||
3574 | wm_adsp_buffer_clear(compr->buf); | ||
3575 | |||
3576 | /* Trigger the IRQ at one fragment of data */ | 3579 | /* Trigger the IRQ at one fragment of data */ |
3577 | ret = wm_adsp_buffer_write(compr->buf, | 3580 | ret = wm_adsp_buffer_write(compr->buf, |
3578 | HOST_BUFFER_FIELD(high_water_mark), | 3581 | HOST_BUFFER_FIELD(high_water_mark), |
@@ -3584,6 +3587,8 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) | |||
3584 | } | 3587 | } |
3585 | break; | 3588 | break; |
3586 | case SNDRV_PCM_TRIGGER_STOP: | 3589 | case SNDRV_PCM_TRIGGER_STOP: |
3590 | if (wm_adsp_compr_attached(compr)) | ||
3591 | wm_adsp_buffer_clear(compr->buf); | ||
3587 | break; | 3592 | break; |
3588 | default: | 3593 | default: |
3589 | ret = -EINVAL; | 3594 | ret = -EINVAL; |
@@ -3917,22 +3922,40 @@ int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) | |||
3917 | } | 3922 | } |
3918 | EXPORT_SYMBOL_GPL(wm_adsp2_lock); | 3923 | EXPORT_SYMBOL_GPL(wm_adsp2_lock); |
3919 | 3924 | ||
3925 | static void wm_adsp_fatal_error(struct wm_adsp *dsp) | ||
3926 | { | ||
3927 | struct wm_adsp_compr *compr; | ||
3928 | |||
3929 | dsp->fatal_error = true; | ||
3930 | |||
3931 | list_for_each_entry(compr, &dsp->compr_list, list) { | ||
3932 | if (compr->stream) { | ||
3933 | snd_compr_stop_error(compr->stream, | ||
3934 | SNDRV_PCM_STATE_XRUN); | ||
3935 | snd_compr_fragment_elapsed(compr->stream); | ||
3936 | } | ||
3937 | } | ||
3938 | } | ||
3939 | |||
3920 | irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) | 3940 | irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) |
3921 | { | 3941 | { |
3922 | unsigned int val; | 3942 | unsigned int val; |
3923 | struct regmap *regmap = dsp->regmap; | 3943 | struct regmap *regmap = dsp->regmap; |
3924 | int ret = 0; | 3944 | int ret = 0; |
3925 | 3945 | ||
3946 | mutex_lock(&dsp->pwr_lock); | ||
3947 | |||
3926 | ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); | 3948 | ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); |
3927 | if (ret) { | 3949 | if (ret) { |
3928 | adsp_err(dsp, | 3950 | adsp_err(dsp, |
3929 | "Failed to read Region Lock Ctrl register: %d\n", ret); | 3951 | "Failed to read Region Lock Ctrl register: %d\n", ret); |
3930 | return IRQ_HANDLED; | 3952 | goto error; |
3931 | } | 3953 | } |
3932 | 3954 | ||
3933 | if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { | 3955 | if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { |
3934 | adsp_err(dsp, "watchdog timeout error\n"); | 3956 | adsp_err(dsp, "watchdog timeout error\n"); |
3935 | wm_adsp_stop_watchdog(dsp); | 3957 | wm_adsp_stop_watchdog(dsp); |
3958 | wm_adsp_fatal_error(dsp); | ||
3936 | } | 3959 | } |
3937 | 3960 | ||
3938 | if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { | 3961 | if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { |
@@ -3946,7 +3969,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) | |||
3946 | adsp_err(dsp, | 3969 | adsp_err(dsp, |
3947 | "Failed to read Bus Err Addr register: %d\n", | 3970 | "Failed to read Bus Err Addr register: %d\n", |
3948 | ret); | 3971 | ret); |
3949 | return IRQ_HANDLED; | 3972 | goto error; |
3950 | } | 3973 | } |
3951 | 3974 | ||
3952 | adsp_err(dsp, "bus error address = 0x%x\n", | 3975 | adsp_err(dsp, "bus error address = 0x%x\n", |
@@ -3959,7 +3982,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) | |||
3959 | adsp_err(dsp, | 3982 | adsp_err(dsp, |
3960 | "Failed to read Pmem Xmem Err Addr register: %d\n", | 3983 | "Failed to read Pmem Xmem Err Addr register: %d\n", |
3961 | ret); | 3984 | ret); |
3962 | return IRQ_HANDLED; | 3985 | goto error; |
3963 | } | 3986 | } |
3964 | 3987 | ||
3965 | adsp_err(dsp, "xmem error address = 0x%x\n", | 3988 | adsp_err(dsp, "xmem error address = 0x%x\n", |
@@ -3972,6 +3995,9 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) | |||
3972 | regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, | 3995 | regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, |
3973 | ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); | 3996 | ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); |
3974 | 3997 | ||
3998 | error: | ||
3999 | mutex_unlock(&dsp->pwr_lock); | ||
4000 | |||
3975 | return IRQ_HANDLED; | 4001 | return IRQ_HANDLED; |
3976 | } | 4002 | } |
3977 | EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); | 4003 | EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); |
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 59e07ad16329..8f09b4419a91 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h | |||
@@ -85,6 +85,7 @@ struct wm_adsp { | |||
85 | bool preloaded; | 85 | bool preloaded; |
86 | bool booted; | 86 | bool booted; |
87 | bool running; | 87 | bool running; |
88 | bool fatal_error; | ||
88 | 89 | ||
89 | struct list_head ctl_list; | 90 | struct list_head ctl_list; |
90 | 91 | ||
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 528e8b108422..0b937924d2e4 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c | |||
@@ -445,6 +445,19 @@ struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir) | |||
445 | } | 445 | } |
446 | EXPORT_SYMBOL_GPL(fsl_asrc_get_dma_channel); | 446 | EXPORT_SYMBOL_GPL(fsl_asrc_get_dma_channel); |
447 | 447 | ||
448 | static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream, | ||
449 | struct snd_soc_dai *dai) | ||
450 | { | ||
451 | struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(dai); | ||
452 | |||
453 | /* Odd channel number is not valid for older ASRC (channel_bits==3) */ | ||
454 | if (asrc_priv->channel_bits == 3) | ||
455 | snd_pcm_hw_constraint_step(substream->runtime, 0, | ||
456 | SNDRV_PCM_HW_PARAM_CHANNELS, 2); | ||
457 | |||
458 | return 0; | ||
459 | } | ||
460 | |||
448 | static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, | 461 | static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, |
449 | struct snd_pcm_hw_params *params, | 462 | struct snd_pcm_hw_params *params, |
450 | struct snd_soc_dai *dai) | 463 | struct snd_soc_dai *dai) |
@@ -539,6 +552,7 @@ static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
539 | } | 552 | } |
540 | 553 | ||
541 | static const struct snd_soc_dai_ops fsl_asrc_dai_ops = { | 554 | static const struct snd_soc_dai_ops fsl_asrc_dai_ops = { |
555 | .startup = fsl_asrc_dai_startup, | ||
542 | .hw_params = fsl_asrc_dai_hw_params, | 556 | .hw_params = fsl_asrc_dai_hw_params, |
543 | .hw_free = fsl_asrc_dai_hw_free, | 557 | .hw_free = fsl_asrc_dai_hw_free, |
544 | .trigger = fsl_asrc_dai_trigger, | 558 | .trigger = fsl_asrc_dai_trigger, |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index afe67c865330..3623aa9a6f2e 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -54,6 +54,8 @@ struct fsl_esai { | |||
54 | u32 fifo_depth; | 54 | u32 fifo_depth; |
55 | u32 slot_width; | 55 | u32 slot_width; |
56 | u32 slots; | 56 | u32 slots; |
57 | u32 tx_mask; | ||
58 | u32 rx_mask; | ||
57 | u32 hck_rate[2]; | 59 | u32 hck_rate[2]; |
58 | u32 sck_rate[2]; | 60 | u32 sck_rate[2]; |
59 | bool hck_dir[2]; | 61 | bool hck_dir[2]; |
@@ -361,21 +363,13 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
361 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, | 363 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, |
362 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); | 364 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); |
363 | 365 | ||
364 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, | ||
365 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); | ||
366 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, | ||
367 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask)); | ||
368 | |||
369 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, | 366 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, |
370 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); | 367 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); |
371 | 368 | ||
372 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, | ||
373 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); | ||
374 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, | ||
375 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); | ||
376 | |||
377 | esai_priv->slot_width = slot_width; | 369 | esai_priv->slot_width = slot_width; |
378 | esai_priv->slots = slots; | 370 | esai_priv->slots = slots; |
371 | esai_priv->tx_mask = tx_mask; | ||
372 | esai_priv->rx_mask = rx_mask; | ||
379 | 373 | ||
380 | return 0; | 374 | return 0; |
381 | } | 375 | } |
@@ -596,6 +590,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
596 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 590 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
597 | u8 i, channels = substream->runtime->channels; | 591 | u8 i, channels = substream->runtime->channels; |
598 | u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); | 592 | u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); |
593 | u32 mask; | ||
599 | 594 | ||
600 | switch (cmd) { | 595 | switch (cmd) { |
601 | case SNDRV_PCM_TRIGGER_START: | 596 | case SNDRV_PCM_TRIGGER_START: |
@@ -608,15 +603,38 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
608 | for (i = 0; tx && i < channels; i++) | 603 | for (i = 0; tx && i < channels; i++) |
609 | regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); | 604 | regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); |
610 | 605 | ||
606 | /* | ||
607 | * When set the TE/RE in the end of enablement flow, there | ||
608 | * will be channel swap issue for multi data line case. | ||
609 | * In order to workaround this issue, we switch the bit | ||
610 | * enablement sequence to below sequence | ||
611 | * 1) clear the xSMB & xSMA: which is done in probe and | ||
612 | * stop state. | ||
613 | * 2) set TE/RE | ||
614 | * 3) set xSMB | ||
615 | * 4) set xSMA: xSMA is the last one in this flow, which | ||
616 | * will trigger esai to start. | ||
617 | */ | ||
611 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | 618 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), |
612 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, | 619 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, |
613 | tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); | 620 | tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); |
621 | mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask; | ||
622 | |||
623 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), | ||
624 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask)); | ||
625 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), | ||
626 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask)); | ||
627 | |||
614 | break; | 628 | break; |
615 | case SNDRV_PCM_TRIGGER_SUSPEND: | 629 | case SNDRV_PCM_TRIGGER_SUSPEND: |
616 | case SNDRV_PCM_TRIGGER_STOP: | 630 | case SNDRV_PCM_TRIGGER_STOP: |
617 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 631 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
618 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | 632 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), |
619 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); | 633 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); |
634 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx), | ||
635 | ESAI_xSMA_xS_MASK, 0); | ||
636 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx), | ||
637 | ESAI_xSMB_xS_MASK, 0); | ||
620 | 638 | ||
621 | /* Disable and reset FIFO */ | 639 | /* Disable and reset FIFO */ |
622 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), | 640 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), |
@@ -906,6 +924,15 @@ static int fsl_esai_probe(struct platform_device *pdev) | |||
906 | return ret; | 924 | return ret; |
907 | } | 925 | } |
908 | 926 | ||
927 | esai_priv->tx_mask = 0xFFFFFFFF; | ||
928 | esai_priv->rx_mask = 0xFFFFFFFF; | ||
929 | |||
930 | /* Clear the TSMA, TSMB, RSMA, RSMB */ | ||
931 | regmap_write(esai_priv->regmap, REG_ESAI_TSMA, 0); | ||
932 | regmap_write(esai_priv->regmap, REG_ESAI_TSMB, 0); | ||
933 | regmap_write(esai_priv->regmap, REG_ESAI_RSMA, 0); | ||
934 | regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0); | ||
935 | |||
909 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, | 936 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, |
910 | &fsl_esai_dai, 1); | 937 | &fsl_esai_dai, 1); |
911 | if (ret) { | 938 | if (ret) { |
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index bb12351330e8..69bc4848d787 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
21 | #include <sound/simple_card_utils.h> | 21 | #include <sound/simple_card_utils.h> |
22 | 22 | ||
23 | #define DPCM_SELECTABLE 1 | ||
24 | |||
23 | struct graph_priv { | 25 | struct graph_priv { |
24 | struct snd_soc_card snd_card; | 26 | struct snd_soc_card snd_card; |
25 | struct graph_dai_props { | 27 | struct graph_dai_props { |
@@ -440,6 +442,7 @@ static int graph_for_each_link(struct graph_priv *priv, | |||
440 | struct device_node *codec_port; | 442 | struct device_node *codec_port; |
441 | struct device_node *codec_port_old = NULL; | 443 | struct device_node *codec_port_old = NULL; |
442 | struct asoc_simple_card_data adata; | 444 | struct asoc_simple_card_data adata; |
445 | uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev); | ||
443 | int rc, ret; | 446 | int rc, ret; |
444 | 447 | ||
445 | /* loop for all listed CPU port */ | 448 | /* loop for all listed CPU port */ |
@@ -470,8 +473,9 @@ static int graph_for_each_link(struct graph_priv *priv, | |||
470 | * if Codec port has many endpoints, | 473 | * if Codec port has many endpoints, |
471 | * or has convert-xxx property | 474 | * or has convert-xxx property |
472 | */ | 475 | */ |
473 | if ((of_get_child_count(codec_port) > 1) || | 476 | if (dpcm_selectable && |
474 | adata.convert_rate || adata.convert_channels) | 477 | ((of_get_child_count(codec_port) > 1) || |
478 | adata.convert_rate || adata.convert_channels)) | ||
475 | ret = func_dpcm(priv, cpu_ep, codec_ep, li, | 479 | ret = func_dpcm(priv, cpu_ep, codec_ep, li, |
476 | (codec_port_old == codec_port)); | 480 | (codec_port_old == codec_port)); |
477 | /* else normal sound */ | 481 | /* else normal sound */ |
@@ -732,7 +736,8 @@ static int graph_remove(struct platform_device *pdev) | |||
732 | 736 | ||
733 | static const struct of_device_id graph_of_match[] = { | 737 | static const struct of_device_id graph_of_match[] = { |
734 | { .compatible = "audio-graph-card", }, | 738 | { .compatible = "audio-graph-card", }, |
735 | { .compatible = "audio-graph-scu-card", }, | 739 | { .compatible = "audio-graph-scu-card", |
740 | .data = (void *)DPCM_SELECTABLE }, | ||
736 | {}, | 741 | {}, |
737 | }; | 742 | }; |
738 | MODULE_DEVICE_TABLE(of, graph_of_match); | 743 | MODULE_DEVICE_TABLE(of, graph_of_match); |
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 7147bba45a2a..34de32efc4c4 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
@@ -9,12 +9,15 @@ | |||
9 | #include <linux/device.h> | 9 | #include <linux/device.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
12 | #include <linux/of_device.h> | ||
12 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
13 | #include <linux/string.h> | 14 | #include <linux/string.h> |
14 | #include <sound/simple_card.h> | 15 | #include <sound/simple_card.h> |
15 | #include <sound/soc-dai.h> | 16 | #include <sound/soc-dai.h> |
16 | #include <sound/soc.h> | 17 | #include <sound/soc.h> |
17 | 18 | ||
19 | #define DPCM_SELECTABLE 1 | ||
20 | |||
18 | struct simple_priv { | 21 | struct simple_priv { |
19 | struct snd_soc_card snd_card; | 22 | struct snd_soc_card snd_card; |
20 | struct simple_dai_props { | 23 | struct simple_dai_props { |
@@ -441,6 +444,7 @@ static int simple_for_each_link(struct simple_priv *priv, | |||
441 | struct device *dev = simple_priv_to_dev(priv); | 444 | struct device *dev = simple_priv_to_dev(priv); |
442 | struct device_node *top = dev->of_node; | 445 | struct device_node *top = dev->of_node; |
443 | struct device_node *node; | 446 | struct device_node *node; |
447 | uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev); | ||
444 | bool is_top = 0; | 448 | bool is_top = 0; |
445 | int ret = 0; | 449 | int ret = 0; |
446 | 450 | ||
@@ -480,8 +484,9 @@ static int simple_for_each_link(struct simple_priv *priv, | |||
480 | * if it has many CPUs, | 484 | * if it has many CPUs, |
481 | * or has convert-xxx property | 485 | * or has convert-xxx property |
482 | */ | 486 | */ |
483 | if (num > 2 || | 487 | if (dpcm_selectable && |
484 | adata.convert_rate || adata.convert_channels) | 488 | (num > 2 || |
489 | adata.convert_rate || adata.convert_channels)) | ||
485 | ret = func_dpcm(priv, np, codec, li, is_top); | 490 | ret = func_dpcm(priv, np, codec, li, is_top); |
486 | /* else normal sound */ | 491 | /* else normal sound */ |
487 | else | 492 | else |
@@ -822,7 +827,8 @@ static int simple_remove(struct platform_device *pdev) | |||
822 | 827 | ||
823 | static const struct of_device_id simple_of_match[] = { | 828 | static const struct of_device_id simple_of_match[] = { |
824 | { .compatible = "simple-audio-card", }, | 829 | { .compatible = "simple-audio-card", }, |
825 | { .compatible = "simple-scu-audio-card", }, | 830 | { .compatible = "simple-scu-audio-card", |
831 | .data = (void *)DPCM_SELECTABLE }, | ||
826 | {}, | 832 | {}, |
827 | }; | 833 | }; |
828 | MODULE_DEVICE_TABLE(of, simple_of_match); | 834 | MODULE_DEVICE_TABLE(of, simple_of_match); |
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index 08cea5b5cda9..0e8b1c5eec88 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c | |||
@@ -706,9 +706,17 @@ static int sst_soc_probe(struct snd_soc_component *component) | |||
706 | return sst_dsp_init_v2_dpcm(component); | 706 | return sst_dsp_init_v2_dpcm(component); |
707 | } | 707 | } |
708 | 708 | ||
709 | static void sst_soc_remove(struct snd_soc_component *component) | ||
710 | { | ||
711 | struct sst_data *drv = dev_get_drvdata(component->dev); | ||
712 | |||
713 | drv->soc_card = NULL; | ||
714 | } | ||
715 | |||
709 | static const struct snd_soc_component_driver sst_soc_platform_drv = { | 716 | static const struct snd_soc_component_driver sst_soc_platform_drv = { |
710 | .name = DRV_NAME, | 717 | .name = DRV_NAME, |
711 | .probe = sst_soc_probe, | 718 | .probe = sst_soc_probe, |
719 | .remove = sst_soc_remove, | ||
712 | .ops = &sst_platform_ops, | 720 | .ops = &sst_platform_ops, |
713 | .compr_ops = &sst_platform_compr_ops, | 721 | .compr_ops = &sst_platform_compr_ops, |
714 | .pcm_new = sst_pcm_new, | 722 | .pcm_new = sst_pcm_new, |
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index 3263b0495853..c0e0844f75b9 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c | |||
@@ -43,6 +43,7 @@ struct cht_mc_private { | |||
43 | struct clk *mclk; | 43 | struct clk *mclk; |
44 | struct snd_soc_jack jack; | 44 | struct snd_soc_jack jack; |
45 | bool ts3a227e_present; | 45 | bool ts3a227e_present; |
46 | int quirks; | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | static int platform_clock_control(struct snd_soc_dapm_widget *w, | 49 | static int platform_clock_control(struct snd_soc_dapm_widget *w, |
@@ -54,6 +55,10 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, | |||
54 | struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); | 55 | struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); |
55 | int ret; | 56 | int ret; |
56 | 57 | ||
58 | /* See the comment in snd_cht_mc_probe() */ | ||
59 | if (ctx->quirks & QUIRK_PMC_PLT_CLK_0) | ||
60 | return 0; | ||
61 | |||
57 | codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI); | 62 | codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI); |
58 | if (!codec_dai) { | 63 | if (!codec_dai) { |
59 | dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); | 64 | dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); |
@@ -223,6 +228,10 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) | |||
223 | "jack detection gpios not added, error %d\n", ret); | 228 | "jack detection gpios not added, error %d\n", ret); |
224 | } | 229 | } |
225 | 230 | ||
231 | /* See the comment in snd_cht_mc_probe() */ | ||
232 | if (ctx->quirks & QUIRK_PMC_PLT_CLK_0) | ||
233 | return 0; | ||
234 | |||
226 | /* | 235 | /* |
227 | * The firmware might enable the clock at | 236 | * The firmware might enable the clock at |
228 | * boot (this information may or may not | 237 | * boot (this information may or may not |
@@ -423,16 +432,15 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
423 | const char *mclk_name; | 432 | const char *mclk_name; |
424 | struct snd_soc_acpi_mach *mach; | 433 | struct snd_soc_acpi_mach *mach; |
425 | const char *platform_name; | 434 | const char *platform_name; |
426 | int quirks = 0; | ||
427 | |||
428 | dmi_id = dmi_first_match(cht_max98090_quirk_table); | ||
429 | if (dmi_id) | ||
430 | quirks = (unsigned long)dmi_id->driver_data; | ||
431 | 435 | ||
432 | drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); | 436 | drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); |
433 | if (!drv) | 437 | if (!drv) |
434 | return -ENOMEM; | 438 | return -ENOMEM; |
435 | 439 | ||
440 | dmi_id = dmi_first_match(cht_max98090_quirk_table); | ||
441 | if (dmi_id) | ||
442 | drv->quirks = (unsigned long)dmi_id->driver_data; | ||
443 | |||
436 | drv->ts3a227e_present = acpi_dev_found("104C227E"); | 444 | drv->ts3a227e_present = acpi_dev_found("104C227E"); |
437 | if (!drv->ts3a227e_present) { | 445 | if (!drv->ts3a227e_present) { |
438 | /* no need probe TI jack detection chip */ | 446 | /* no need probe TI jack detection chip */ |
@@ -458,7 +466,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
458 | snd_soc_card_cht.dev = &pdev->dev; | 466 | snd_soc_card_cht.dev = &pdev->dev; |
459 | snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); | 467 | snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); |
460 | 468 | ||
461 | if (quirks & QUIRK_PMC_PLT_CLK_0) | 469 | if (drv->quirks & QUIRK_PMC_PLT_CLK_0) |
462 | mclk_name = "pmc_plt_clk_0"; | 470 | mclk_name = "pmc_plt_clk_0"; |
463 | else | 471 | else |
464 | mclk_name = "pmc_plt_clk_3"; | 472 | mclk_name = "pmc_plt_clk_3"; |
@@ -471,6 +479,21 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
471 | return PTR_ERR(drv->mclk); | 479 | return PTR_ERR(drv->mclk); |
472 | } | 480 | } |
473 | 481 | ||
482 | /* | ||
483 | * Boards which have the MAX98090's clk connected to clk_0 do not seem | ||
484 | * to like it if we muck with the clock. If we disable the clock when | ||
485 | * it is unused we get "max98090 i2c-193C9890:00: PLL unlocked" errors | ||
486 | * and the PLL never seems to lock again. | ||
487 | * So for these boards we enable it here once and leave it at that. | ||
488 | */ | ||
489 | if (drv->quirks & QUIRK_PMC_PLT_CLK_0) { | ||
490 | ret_val = clk_prepare_enable(drv->mclk); | ||
491 | if (ret_val < 0) { | ||
492 | dev_err(&pdev->dev, "MCLK enable error: %d\n", ret_val); | ||
493 | return ret_val; | ||
494 | } | ||
495 | } | ||
496 | |||
474 | ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); | 497 | ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); |
475 | if (ret_val) { | 498 | if (ret_val) { |
476 | dev_err(&pdev->dev, | 499 | dev_err(&pdev->dev, |
@@ -481,11 +504,23 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
481 | return ret_val; | 504 | return ret_val; |
482 | } | 505 | } |
483 | 506 | ||
507 | static int snd_cht_mc_remove(struct platform_device *pdev) | ||
508 | { | ||
509 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
510 | struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); | ||
511 | |||
512 | if (ctx->quirks & QUIRK_PMC_PLT_CLK_0) | ||
513 | clk_disable_unprepare(ctx->mclk); | ||
514 | |||
515 | return 0; | ||
516 | } | ||
517 | |||
484 | static struct platform_driver snd_cht_mc_driver = { | 518 | static struct platform_driver snd_cht_mc_driver = { |
485 | .driver = { | 519 | .driver = { |
486 | .name = "cht-bsw-max98090", | 520 | .name = "cht-bsw-max98090", |
487 | }, | 521 | }, |
488 | .probe = snd_cht_mc_probe, | 522 | .probe = snd_cht_mc_probe, |
523 | .remove = snd_cht_mc_remove, | ||
489 | }; | 524 | }; |
490 | 525 | ||
491 | module_platform_driver(snd_cht_mc_driver) | 526 | module_platform_driver(snd_cht_mc_driver) |
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 7044d8c2b187..879f14257a3e 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c | |||
@@ -405,7 +405,7 @@ static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { | |||
405 | }; | 405 | }; |
406 | 406 | ||
407 | static const unsigned int dmic_2ch[] = { | 407 | static const unsigned int dmic_2ch[] = { |
408 | 4, | 408 | 2, |
409 | }; | 409 | }; |
410 | 410 | ||
411 | static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { | 411 | static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { |
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 28c4806b196a..4bf70b4429f0 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c | |||
@@ -483,6 +483,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx, | |||
483 | base_cfg->audio_fmt.bit_depth = format->bit_depth; | 483 | base_cfg->audio_fmt.bit_depth = format->bit_depth; |
484 | base_cfg->audio_fmt.valid_bit_depth = format->valid_bit_depth; | 484 | base_cfg->audio_fmt.valid_bit_depth = format->valid_bit_depth; |
485 | base_cfg->audio_fmt.ch_cfg = format->ch_cfg; | 485 | base_cfg->audio_fmt.ch_cfg = format->ch_cfg; |
486 | base_cfg->audio_fmt.sample_type = format->sample_type; | ||
486 | 487 | ||
487 | dev_dbg(ctx->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n", | 488 | dev_dbg(ctx->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n", |
488 | format->bit_depth, format->valid_bit_depth, | 489 | format->bit_depth, format->valid_bit_depth, |
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 1ae83f4ccc36..9735e2412251 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c | |||
@@ -181,6 +181,7 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) | |||
181 | struct hdac_stream *hstream; | 181 | struct hdac_stream *hstream; |
182 | struct hdac_ext_stream *stream; | 182 | struct hdac_ext_stream *stream; |
183 | struct hdac_ext_link *link; | 183 | struct hdac_ext_link *link; |
184 | unsigned char stream_tag; | ||
184 | 185 | ||
185 | hstream = snd_hdac_get_stream(bus, params->stream, | 186 | hstream = snd_hdac_get_stream(bus, params->stream, |
186 | params->link_dma_id + 1); | 187 | params->link_dma_id + 1); |
@@ -199,10 +200,13 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) | |||
199 | 200 | ||
200 | snd_hdac_ext_link_stream_setup(stream, format_val); | 201 | snd_hdac_ext_link_stream_setup(stream, format_val); |
201 | 202 | ||
202 | list_for_each_entry(link, &bus->hlink_list, list) { | 203 | stream_tag = hstream->stream_tag; |
203 | if (link->index == params->link_index) | 204 | if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) { |
204 | snd_hdac_ext_link_set_stream_id(link, | 205 | list_for_each_entry(link, &bus->hlink_list, list) { |
205 | hstream->stream_tag); | 206 | if (link->index == params->link_index) |
207 | snd_hdac_ext_link_set_stream_id(link, | ||
208 | stream_tag); | ||
209 | } | ||
206 | } | 210 | } |
207 | 211 | ||
208 | stream->link_prepared = 1; | 212 | stream->link_prepared = 1; |
@@ -645,6 +649,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, | |||
645 | struct hdac_ext_stream *link_dev = | 649 | struct hdac_ext_stream *link_dev = |
646 | snd_soc_dai_get_dma_data(dai, substream); | 650 | snd_soc_dai_get_dma_data(dai, substream); |
647 | struct hdac_ext_link *link; | 651 | struct hdac_ext_link *link; |
652 | unsigned char stream_tag; | ||
648 | 653 | ||
649 | dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); | 654 | dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); |
650 | 655 | ||
@@ -654,7 +659,11 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, | |||
654 | if (!link) | 659 | if (!link) |
655 | return -EINVAL; | 660 | return -EINVAL; |
656 | 661 | ||
657 | snd_hdac_ext_link_clear_stream_id(link, hdac_stream(link_dev)->stream_tag); | 662 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
663 | stream_tag = hdac_stream(link_dev)->stream_tag; | ||
664 | snd_hdac_ext_link_clear_stream_id(link, stream_tag); | ||
665 | } | ||
666 | |||
658 | snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK); | 667 | snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK); |
659 | return 0; | 668 | return 0; |
660 | } | 669 | } |
@@ -1453,13 +1462,20 @@ static int skl_platform_soc_probe(struct snd_soc_component *component) | |||
1453 | return 0; | 1462 | return 0; |
1454 | } | 1463 | } |
1455 | 1464 | ||
1465 | static void skl_pcm_remove(struct snd_soc_component *component) | ||
1466 | { | ||
1467 | /* remove topology */ | ||
1468 | snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); | ||
1469 | } | ||
1470 | |||
1456 | static const struct snd_soc_component_driver skl_component = { | 1471 | static const struct snd_soc_component_driver skl_component = { |
1457 | .name = "pcm", | 1472 | .name = "pcm", |
1458 | .probe = skl_platform_soc_probe, | 1473 | .probe = skl_platform_soc_probe, |
1474 | .remove = skl_pcm_remove, | ||
1459 | .ops = &skl_platform_ops, | 1475 | .ops = &skl_platform_ops, |
1460 | .pcm_new = skl_pcm_new, | 1476 | .pcm_new = skl_pcm_new, |
1461 | .pcm_free = skl_pcm_free, | 1477 | .pcm_free = skl_pcm_free, |
1462 | .ignore_module_refcount = 1, /* do not increase the refcount in core */ | 1478 | .module_get_upon_open = 1, /* increment refcount when a pcm is opened */ |
1463 | }; | 1479 | }; |
1464 | 1480 | ||
1465 | int skl_platform_register(struct device *dev) | 1481 | int skl_platform_register(struct device *dev) |
diff --git a/sound/soc/mediatek/common/mtk-btcvsd.c b/sound/soc/mediatek/common/mtk-btcvsd.c index 1b8bcdaf02d1..9a163d7064d1 100644 --- a/sound/soc/mediatek/common/mtk-btcvsd.c +++ b/sound/soc/mediatek/common/mtk-btcvsd.c | |||
@@ -49,6 +49,7 @@ enum bt_sco_state { | |||
49 | BT_SCO_STATE_IDLE, | 49 | BT_SCO_STATE_IDLE, |
50 | BT_SCO_STATE_RUNNING, | 50 | BT_SCO_STATE_RUNNING, |
51 | BT_SCO_STATE_ENDING, | 51 | BT_SCO_STATE_ENDING, |
52 | BT_SCO_STATE_LOOPBACK, | ||
52 | }; | 53 | }; |
53 | 54 | ||
54 | enum bt_sco_direct { | 55 | enum bt_sco_direct { |
@@ -486,7 +487,8 @@ static irqreturn_t mtk_btcvsd_snd_irq_handler(int irq_id, void *dev) | |||
486 | if (bt->rx->state != BT_SCO_STATE_RUNNING && | 487 | if (bt->rx->state != BT_SCO_STATE_RUNNING && |
487 | bt->rx->state != BT_SCO_STATE_ENDING && | 488 | bt->rx->state != BT_SCO_STATE_ENDING && |
488 | bt->tx->state != BT_SCO_STATE_RUNNING && | 489 | bt->tx->state != BT_SCO_STATE_RUNNING && |
489 | bt->tx->state != BT_SCO_STATE_ENDING) { | 490 | bt->tx->state != BT_SCO_STATE_ENDING && |
491 | bt->tx->state != BT_SCO_STATE_LOOPBACK) { | ||
490 | dev_warn(bt->dev, "%s(), in idle state: rx->state: %d, tx->state: %d\n", | 492 | dev_warn(bt->dev, "%s(), in idle state: rx->state: %d, tx->state: %d\n", |
491 | __func__, bt->rx->state, bt->tx->state); | 493 | __func__, bt->rx->state, bt->tx->state); |
492 | goto irq_handler_exit; | 494 | goto irq_handler_exit; |
@@ -512,6 +514,42 @@ static irqreturn_t mtk_btcvsd_snd_irq_handler(int irq_id, void *dev) | |||
512 | buf_cnt_tx = btsco_packet_info[packet_type][2]; | 514 | buf_cnt_tx = btsco_packet_info[packet_type][2]; |
513 | buf_cnt_rx = btsco_packet_info[packet_type][3]; | 515 | buf_cnt_rx = btsco_packet_info[packet_type][3]; |
514 | 516 | ||
517 | if (bt->tx->state == BT_SCO_STATE_LOOPBACK) { | ||
518 | u8 *src, *dst; | ||
519 | unsigned long connsys_addr_rx, ap_addr_rx; | ||
520 | unsigned long connsys_addr_tx, ap_addr_tx; | ||
521 | |||
522 | connsys_addr_rx = *bt->bt_reg_pkt_r; | ||
523 | ap_addr_rx = (unsigned long)bt->bt_sram_bank2_base + | ||
524 | (connsys_addr_rx & 0xFFFF); | ||
525 | |||
526 | connsys_addr_tx = *bt->bt_reg_pkt_w; | ||
527 | ap_addr_tx = (unsigned long)bt->bt_sram_bank2_base + | ||
528 | (connsys_addr_tx & 0xFFFF); | ||
529 | |||
530 | if (connsys_addr_tx == 0xdeadfeed || | ||
531 | connsys_addr_rx == 0xdeadfeed) { | ||
532 | /* bt return 0xdeadfeed if read reg during bt sleep */ | ||
533 | dev_warn(bt->dev, "%s(), connsys_addr_tx == 0xdeadfeed\n", | ||
534 | __func__); | ||
535 | goto irq_handler_exit; | ||
536 | } | ||
537 | |||
538 | src = (u8 *)ap_addr_rx; | ||
539 | dst = (u8 *)ap_addr_tx; | ||
540 | |||
541 | mtk_btcvsd_snd_data_transfer(BT_SCO_DIRECT_BT2ARM, src, | ||
542 | bt->tx->temp_packet_buf, | ||
543 | packet_length, | ||
544 | packet_num); | ||
545 | mtk_btcvsd_snd_data_transfer(BT_SCO_DIRECT_ARM2BT, | ||
546 | bt->tx->temp_packet_buf, dst, | ||
547 | packet_length, | ||
548 | packet_num); | ||
549 | bt->rx->rw_cnt++; | ||
550 | bt->tx->rw_cnt++; | ||
551 | } | ||
552 | |||
515 | if (bt->rx->state == BT_SCO_STATE_RUNNING || | 553 | if (bt->rx->state == BT_SCO_STATE_RUNNING || |
516 | bt->rx->state == BT_SCO_STATE_ENDING) { | 554 | bt->rx->state == BT_SCO_STATE_ENDING) { |
517 | if (bt->rx->xrun) { | 555 | if (bt->rx->xrun) { |
@@ -1067,6 +1105,33 @@ static int btcvsd_band_set(struct snd_kcontrol *kcontrol, | |||
1067 | return 0; | 1105 | return 0; |
1068 | } | 1106 | } |
1069 | 1107 | ||
1108 | static int btcvsd_loopback_get(struct snd_kcontrol *kcontrol, | ||
1109 | struct snd_ctl_elem_value *ucontrol) | ||
1110 | { | ||
1111 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
1112 | struct mtk_btcvsd_snd *bt = snd_soc_component_get_drvdata(cmpnt); | ||
1113 | bool lpbk_en = bt->tx->state == BT_SCO_STATE_LOOPBACK; | ||
1114 | |||
1115 | ucontrol->value.integer.value[0] = lpbk_en; | ||
1116 | return 0; | ||
1117 | } | ||
1118 | |||
1119 | static int btcvsd_loopback_set(struct snd_kcontrol *kcontrol, | ||
1120 | struct snd_ctl_elem_value *ucontrol) | ||
1121 | { | ||
1122 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
1123 | struct mtk_btcvsd_snd *bt = snd_soc_component_get_drvdata(cmpnt); | ||
1124 | |||
1125 | if (ucontrol->value.integer.value[0]) { | ||
1126 | mtk_btcvsd_snd_set_state(bt, bt->tx, BT_SCO_STATE_LOOPBACK); | ||
1127 | mtk_btcvsd_snd_set_state(bt, bt->rx, BT_SCO_STATE_LOOPBACK); | ||
1128 | } else { | ||
1129 | mtk_btcvsd_snd_set_state(bt, bt->tx, BT_SCO_STATE_RUNNING); | ||
1130 | mtk_btcvsd_snd_set_state(bt, bt->rx, BT_SCO_STATE_RUNNING); | ||
1131 | } | ||
1132 | return 0; | ||
1133 | } | ||
1134 | |||
1070 | static int btcvsd_tx_mute_get(struct snd_kcontrol *kcontrol, | 1135 | static int btcvsd_tx_mute_get(struct snd_kcontrol *kcontrol, |
1071 | struct snd_ctl_elem_value *ucontrol) | 1136 | struct snd_ctl_elem_value *ucontrol) |
1072 | { | 1137 | { |
@@ -1202,6 +1267,8 @@ static int btcvsd_tx_timestamp_get(struct snd_kcontrol *kcontrol, | |||
1202 | static const struct snd_kcontrol_new mtk_btcvsd_snd_controls[] = { | 1267 | static const struct snd_kcontrol_new mtk_btcvsd_snd_controls[] = { |
1203 | SOC_ENUM_EXT("BTCVSD Band", btcvsd_enum[0], | 1268 | SOC_ENUM_EXT("BTCVSD Band", btcvsd_enum[0], |
1204 | btcvsd_band_get, btcvsd_band_set), | 1269 | btcvsd_band_get, btcvsd_band_set), |
1270 | SOC_SINGLE_BOOL_EXT("BTCVSD Loopback Switch", 0, | ||
1271 | btcvsd_loopback_get, btcvsd_loopback_set), | ||
1205 | SOC_SINGLE_BOOL_EXT("BTCVSD Tx Mute Switch", 0, | 1272 | SOC_SINGLE_BOOL_EXT("BTCVSD Tx Mute Switch", 0, |
1206 | btcvsd_tx_mute_get, btcvsd_tx_mute_set), | 1273 | btcvsd_tx_mute_get, btcvsd_tx_mute_set), |
1207 | SOC_SINGLE_BOOL_EXT("BTCVSD Tx Irq Received Switch", 0, | 1274 | SOC_SINGLE_BOOL_EXT("BTCVSD Tx Irq Received Switch", 0, |
diff --git a/sound/soc/mediatek/mt8183/mt8183-afe-clk.c b/sound/soc/mediatek/mt8183/mt8183-afe-clk.c index f523ad103acc..48e81c5d52fc 100644 --- a/sound/soc/mediatek/mt8183/mt8183-afe-clk.c +++ b/sound/soc/mediatek/mt8183/mt8183-afe-clk.c | |||
@@ -605,6 +605,10 @@ void mt8183_mck_disable(struct mtk_base_afe *afe, int mck_id) | |||
605 | int m_sel_id = mck_div[mck_id].m_sel_id; | 605 | int m_sel_id = mck_div[mck_id].m_sel_id; |
606 | int div_clk_id = mck_div[mck_id].div_clk_id; | 606 | int div_clk_id = mck_div[mck_id].div_clk_id; |
607 | 607 | ||
608 | /* i2s5 mck not support */ | ||
609 | if (mck_id == MT8183_I2S5_MCK) | ||
610 | return; | ||
611 | |||
608 | clk_disable_unprepare(afe_priv->clk[div_clk_id]); | 612 | clk_disable_unprepare(afe_priv->clk[div_clk_id]); |
609 | if (m_sel_id >= 0) | 613 | if (m_sel_id >= 0) |
610 | clk_disable_unprepare(afe_priv->clk[m_sel_id]); | 614 | clk_disable_unprepare(afe_priv->clk[m_sel_id]); |
diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index 400e29edb1c9..d0b403a0e27b 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include "rockchip_pdm.h" | 25 | #include "rockchip_pdm.h" |
26 | 26 | ||
27 | #define PDM_DMA_BURST_SIZE (16) /* size * width: 16*4 = 64 bytes */ | 27 | #define PDM_DMA_BURST_SIZE (8) /* size * width: 8*4 = 32 bytes */ |
28 | 28 | ||
29 | struct rk_pdm_dev { | 29 | struct rk_pdm_dev { |
30 | struct device *dev; | 30 | struct device *dev; |
@@ -208,7 +208,9 @@ static int rockchip_pdm_set_fmt(struct snd_soc_dai *cpu_dai, | |||
208 | return -EINVAL; | 208 | return -EINVAL; |
209 | } | 209 | } |
210 | 210 | ||
211 | pm_runtime_get_sync(cpu_dai->dev); | ||
211 | regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, mask, val); | 212 | regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, mask, val); |
213 | pm_runtime_put(cpu_dai->dev); | ||
212 | 214 | ||
213 | return 0; | 215 | return 0; |
214 | } | 216 | } |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 4231001226f4..ab471d550d17 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
@@ -1130,11 +1130,11 @@ static const struct snd_soc_dapm_widget samsung_i2s_widgets[] = { | |||
1130 | }; | 1130 | }; |
1131 | 1131 | ||
1132 | static const struct snd_soc_dapm_route samsung_i2s_dapm_routes[] = { | 1132 | static const struct snd_soc_dapm_route samsung_i2s_dapm_routes[] = { |
1133 | { "Playback Mixer", NULL, "Primary" }, | 1133 | { "Playback Mixer", NULL, "Primary Playback" }, |
1134 | { "Playback Mixer", NULL, "Secondary" }, | 1134 | { "Playback Mixer", NULL, "Secondary Playback" }, |
1135 | 1135 | ||
1136 | { "Mixer DAI TX", NULL, "Playback Mixer" }, | 1136 | { "Mixer DAI TX", NULL, "Playback Mixer" }, |
1137 | { "Playback Mixer", NULL, "Mixer DAI RX" }, | 1137 | { "Primary Capture", NULL, "Mixer DAI RX" }, |
1138 | }; | 1138 | }; |
1139 | 1139 | ||
1140 | static const struct snd_soc_component_driver samsung_i2s_component = { | 1140 | static const struct snd_soc_component_driver samsung_i2s_component = { |
@@ -1155,7 +1155,8 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv, | |||
1155 | int num_dais) | 1155 | int num_dais) |
1156 | { | 1156 | { |
1157 | static const char *dai_names[] = { "samsung-i2s", "samsung-i2s-sec" }; | 1157 | static const char *dai_names[] = { "samsung-i2s", "samsung-i2s-sec" }; |
1158 | static const char *stream_names[] = { "Primary", "Secondary" }; | 1158 | static const char *stream_names[] = { "Primary Playback", |
1159 | "Secondary Playback" }; | ||
1159 | struct snd_soc_dai_driver *dai_drv; | 1160 | struct snd_soc_dai_driver *dai_drv; |
1160 | struct i2s_dai *dai; | 1161 | struct i2s_dai *dai; |
1161 | int i; | 1162 | int i; |
@@ -1201,6 +1202,7 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv, | |||
1201 | dai_drv->capture.channels_max = 2; | 1202 | dai_drv->capture.channels_max = 2; |
1202 | dai_drv->capture.rates = i2s_dai_data->pcm_rates; | 1203 | dai_drv->capture.rates = i2s_dai_data->pcm_rates; |
1203 | dai_drv->capture.formats = SAMSUNG_I2S_FMTS; | 1204 | dai_drv->capture.formats = SAMSUNG_I2S_FMTS; |
1205 | dai_drv->capture.stream_name = "Primary Capture"; | ||
1204 | 1206 | ||
1205 | return 0; | 1207 | return 0; |
1206 | } | 1208 | } |
diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c index 694512f980fd..1dc54c4206f0 100644 --- a/sound/soc/samsung/odroid.c +++ b/sound/soc/samsung/odroid.c | |||
@@ -91,11 +91,11 @@ static int odroid_card_be_hw_params(struct snd_pcm_substream *substream, | |||
91 | return ret; | 91 | return ret; |
92 | 92 | ||
93 | /* | 93 | /* |
94 | * We add 1 to the rclk_freq value in order to avoid too low clock | 94 | * We add 2 to the rclk_freq value in order to avoid too low clock |
95 | * frequency values due to the EPLL output frequency not being exact | 95 | * frequency values due to the EPLL output frequency not being exact |
96 | * multiple of the audio sampling rate. | 96 | * multiple of the audio sampling rate. |
97 | */ | 97 | */ |
98 | rclk_freq = params_rate(params) * rfs + 1; | 98 | rclk_freq = params_rate(params) * rfs + 2; |
99 | 99 | ||
100 | ret = clk_set_rate(priv->sclk_i2s, rclk_freq); | 100 | ret = clk_set_rate(priv->sclk_i2s, rclk_freq); |
101 | if (ret < 0) | 101 | if (ret < 0) |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 022996d2db13..4fe83e611c01 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -110,6 +110,8 @@ static const struct of_device_id rsnd_of_match[] = { | |||
110 | { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 }, | 110 | { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 }, |
111 | { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 }, | 111 | { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 }, |
112 | { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN3 }, | 112 | { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN3 }, |
113 | /* Special Handling */ | ||
114 | { .compatible = "renesas,rcar_sound-r8a77990", .data = (void *)(RSND_GEN3 | RSND_SOC_E) }, | ||
113 | {}, | 115 | {}, |
114 | }; | 116 | }; |
115 | MODULE_DEVICE_TABLE(of, rsnd_of_match); | 117 | MODULE_DEVICE_TABLE(of, rsnd_of_match); |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 90625c57847b..0e6ef4e18400 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -607,6 +607,8 @@ struct rsnd_priv { | |||
607 | #define RSND_GEN1 (1 << 0) | 607 | #define RSND_GEN1 (1 << 0) |
608 | #define RSND_GEN2 (2 << 0) | 608 | #define RSND_GEN2 (2 << 0) |
609 | #define RSND_GEN3 (3 << 0) | 609 | #define RSND_GEN3 (3 << 0) |
610 | #define RSND_SOC_MASK (0xFF << 4) | ||
611 | #define RSND_SOC_E (1 << 4) /* E1/E2/E3 */ | ||
610 | 612 | ||
611 | /* | 613 | /* |
612 | * below value will be filled on rsnd_gen_probe() | 614 | * below value will be filled on rsnd_gen_probe() |
@@ -679,6 +681,9 @@ struct rsnd_priv { | |||
679 | #define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) | 681 | #define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) |
680 | #define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) | 682 | #define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) |
681 | #define rsnd_is_gen3(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN3) | 683 | #define rsnd_is_gen3(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN3) |
684 | #define rsnd_is_e3(priv) (((priv)->flags & \ | ||
685 | (RSND_GEN_MASK | RSND_SOC_MASK)) == \ | ||
686 | (RSND_GEN3 | RSND_SOC_E)) | ||
682 | 687 | ||
683 | #define rsnd_flags_has(p, f) ((p)->flags & (f)) | 688 | #define rsnd_flags_has(p, f) ((p)->flags & (f)) |
684 | #define rsnd_flags_set(p, f) ((p)->flags |= (f)) | 689 | #define rsnd_flags_set(p, f) ((p)->flags |= (f)) |
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index db81e066b92e..585ffba0244b 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -14,7 +14,6 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "rsnd.h" | 16 | #include "rsnd.h" |
17 | #include <linux/sys_soc.h> | ||
18 | 17 | ||
19 | #define SRC_NAME "src" | 18 | #define SRC_NAME "src" |
20 | 19 | ||
@@ -135,7 +134,7 @@ unsigned int rsnd_src_get_rate(struct rsnd_priv *priv, | |||
135 | return rate; | 134 | return rate; |
136 | } | 135 | } |
137 | 136 | ||
138 | const static u32 bsdsr_table_pattern1[] = { | 137 | static const u32 bsdsr_table_pattern1[] = { |
139 | 0x01800000, /* 6 - 1/6 */ | 138 | 0x01800000, /* 6 - 1/6 */ |
140 | 0x01000000, /* 6 - 1/4 */ | 139 | 0x01000000, /* 6 - 1/4 */ |
141 | 0x00c00000, /* 6 - 1/3 */ | 140 | 0x00c00000, /* 6 - 1/3 */ |
@@ -144,7 +143,7 @@ const static u32 bsdsr_table_pattern1[] = { | |||
144 | 0x00400000, /* 6 - 1 */ | 143 | 0x00400000, /* 6 - 1 */ |
145 | }; | 144 | }; |
146 | 145 | ||
147 | const static u32 bsdsr_table_pattern2[] = { | 146 | static const u32 bsdsr_table_pattern2[] = { |
148 | 0x02400000, /* 6 - 1/6 */ | 147 | 0x02400000, /* 6 - 1/6 */ |
149 | 0x01800000, /* 6 - 1/4 */ | 148 | 0x01800000, /* 6 - 1/4 */ |
150 | 0x01200000, /* 6 - 1/3 */ | 149 | 0x01200000, /* 6 - 1/3 */ |
@@ -153,7 +152,7 @@ const static u32 bsdsr_table_pattern2[] = { | |||
153 | 0x00600000, /* 6 - 1 */ | 152 | 0x00600000, /* 6 - 1 */ |
154 | }; | 153 | }; |
155 | 154 | ||
156 | const static u32 bsisr_table[] = { | 155 | static const u32 bsisr_table[] = { |
157 | 0x00100060, /* 6 - 1/6 */ | 156 | 0x00100060, /* 6 - 1/6 */ |
158 | 0x00100040, /* 6 - 1/4 */ | 157 | 0x00100040, /* 6 - 1/4 */ |
159 | 0x00100030, /* 6 - 1/3 */ | 158 | 0x00100030, /* 6 - 1/3 */ |
@@ -162,7 +161,7 @@ const static u32 bsisr_table[] = { | |||
162 | 0x00100020, /* 6 - 1 */ | 161 | 0x00100020, /* 6 - 1 */ |
163 | }; | 162 | }; |
164 | 163 | ||
165 | const static u32 chan288888[] = { | 164 | static const u32 chan288888[] = { |
166 | 0x00000006, /* 1 to 2 */ | 165 | 0x00000006, /* 1 to 2 */ |
167 | 0x000001fe, /* 1 to 8 */ | 166 | 0x000001fe, /* 1 to 8 */ |
168 | 0x000001fe, /* 1 to 8 */ | 167 | 0x000001fe, /* 1 to 8 */ |
@@ -171,7 +170,7 @@ const static u32 chan288888[] = { | |||
171 | 0x000001fe, /* 1 to 8 */ | 170 | 0x000001fe, /* 1 to 8 */ |
172 | }; | 171 | }; |
173 | 172 | ||
174 | const static u32 chan244888[] = { | 173 | static const u32 chan244888[] = { |
175 | 0x00000006, /* 1 to 2 */ | 174 | 0x00000006, /* 1 to 2 */ |
176 | 0x0000001e, /* 1 to 4 */ | 175 | 0x0000001e, /* 1 to 4 */ |
177 | 0x0000001e, /* 1 to 4 */ | 176 | 0x0000001e, /* 1 to 4 */ |
@@ -180,7 +179,7 @@ const static u32 chan244888[] = { | |||
180 | 0x000001fe, /* 1 to 8 */ | 179 | 0x000001fe, /* 1 to 8 */ |
181 | }; | 180 | }; |
182 | 181 | ||
183 | const static u32 chan222222[] = { | 182 | static const u32 chan222222[] = { |
184 | 0x00000006, /* 1 to 2 */ | 183 | 0x00000006, /* 1 to 2 */ |
185 | 0x00000006, /* 1 to 2 */ | 184 | 0x00000006, /* 1 to 2 */ |
186 | 0x00000006, /* 1 to 2 */ | 185 | 0x00000006, /* 1 to 2 */ |
@@ -189,18 +188,12 @@ const static u32 chan222222[] = { | |||
189 | 0x00000006, /* 1 to 2 */ | 188 | 0x00000006, /* 1 to 2 */ |
190 | }; | 189 | }; |
191 | 190 | ||
192 | static const struct soc_device_attribute ov_soc[] = { | ||
193 | { .soc_id = "r8a77990" }, /* E3 */ | ||
194 | { /* sentinel */ } | ||
195 | }; | ||
196 | |||
197 | static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, | 191 | static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, |
198 | struct rsnd_mod *mod) | 192 | struct rsnd_mod *mod) |
199 | { | 193 | { |
200 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 194 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
201 | struct device *dev = rsnd_priv_to_dev(priv); | 195 | struct device *dev = rsnd_priv_to_dev(priv); |
202 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 196 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
203 | const struct soc_device_attribute *soc = soc_device_match(ov_soc); | ||
204 | int is_play = rsnd_io_is_play(io); | 197 | int is_play = rsnd_io_is_play(io); |
205 | int use_src = 0; | 198 | int use_src = 0; |
206 | u32 fin, fout; | 199 | u32 fin, fout; |
@@ -307,7 +300,7 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, | |||
307 | /* | 300 | /* |
308 | * E3 need to overwrite | 301 | * E3 need to overwrite |
309 | */ | 302 | */ |
310 | if (soc) | 303 | if (rsnd_is_e3(priv)) |
311 | switch (rsnd_mod_id(mod)) { | 304 | switch (rsnd_mod_id(mod)) { |
312 | case 0: | 305 | case 0: |
313 | case 4: | 306 | case 4: |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 93d316d5bf8e..46e3ab0fced4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -947,7 +947,7 @@ static void soc_cleanup_component(struct snd_soc_component *component) | |||
947 | snd_soc_dapm_free(snd_soc_component_get_dapm(component)); | 947 | snd_soc_dapm_free(snd_soc_component_get_dapm(component)); |
948 | soc_cleanup_component_debugfs(component); | 948 | soc_cleanup_component_debugfs(component); |
949 | component->card = NULL; | 949 | component->card = NULL; |
950 | if (!component->driver->ignore_module_refcount) | 950 | if (!component->driver->module_get_upon_open) |
951 | module_put(component->dev->driver->owner); | 951 | module_put(component->dev->driver->owner); |
952 | } | 952 | } |
953 | 953 | ||
@@ -1381,7 +1381,7 @@ static int soc_probe_component(struct snd_soc_card *card, | |||
1381 | return 0; | 1381 | return 0; |
1382 | } | 1382 | } |
1383 | 1383 | ||
1384 | if (!component->driver->ignore_module_refcount && | 1384 | if (!component->driver->module_get_upon_open && |
1385 | !try_module_get(component->dev->driver->owner)) | 1385 | !try_module_get(component->dev->driver->owner)) |
1386 | return -ENODEV; | 1386 | return -ENODEV; |
1387 | 1387 | ||
@@ -2797,6 +2797,7 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
2797 | 2797 | ||
2798 | ret = soc_init_dai_link(card, link); | 2798 | ret = soc_init_dai_link(card, link); |
2799 | if (ret) { | 2799 | if (ret) { |
2800 | soc_cleanup_platform(card); | ||
2800 | dev_err(card->dev, "ASoC: failed to init link %s\n", | 2801 | dev_err(card->dev, "ASoC: failed to init link %s\n", |
2801 | link->name); | 2802 | link->name); |
2802 | mutex_unlock(&client_mutex); | 2803 | mutex_unlock(&client_mutex); |
@@ -2819,6 +2820,7 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
2819 | card->instantiated = 0; | 2820 | card->instantiated = 0; |
2820 | mutex_init(&card->mutex); | 2821 | mutex_init(&card->mutex); |
2821 | mutex_init(&card->dapm_mutex); | 2822 | mutex_init(&card->dapm_mutex); |
2823 | spin_lock_init(&card->dpcm_lock); | ||
2822 | 2824 | ||
2823 | return snd_soc_bind_card(card); | 2825 | return snd_soc_bind_card(card); |
2824 | } | 2826 | } |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1ec06ef6d161..0382a47b30bd 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -3650,6 +3650,13 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, | |||
3650 | case snd_soc_dapm_dac: | 3650 | case snd_soc_dapm_dac: |
3651 | case snd_soc_dapm_aif_in: | 3651 | case snd_soc_dapm_aif_in: |
3652 | case snd_soc_dapm_pga: | 3652 | case snd_soc_dapm_pga: |
3653 | case snd_soc_dapm_buffer: | ||
3654 | case snd_soc_dapm_scheduler: | ||
3655 | case snd_soc_dapm_effect: | ||
3656 | case snd_soc_dapm_src: | ||
3657 | case snd_soc_dapm_asrc: | ||
3658 | case snd_soc_dapm_encoder: | ||
3659 | case snd_soc_dapm_decoder: | ||
3653 | case snd_soc_dapm_out_drv: | 3660 | case snd_soc_dapm_out_drv: |
3654 | case snd_soc_dapm_micbias: | 3661 | case snd_soc_dapm_micbias: |
3655 | case snd_soc_dapm_line: | 3662 | case snd_soc_dapm_line: |
@@ -3957,6 +3964,10 @@ snd_soc_dapm_free_kcontrol(struct snd_soc_card *card, | |||
3957 | int count; | 3964 | int count; |
3958 | 3965 | ||
3959 | devm_kfree(card->dev, (void *)*private_value); | 3966 | devm_kfree(card->dev, (void *)*private_value); |
3967 | |||
3968 | if (!w_param_text) | ||
3969 | return; | ||
3970 | |||
3960 | for (count = 0 ; count < num_params; count++) | 3971 | for (count = 0 ; count < num_params; count++) |
3961 | devm_kfree(card->dev, (void *)w_param_text[count]); | 3972 | devm_kfree(card->dev, (void *)w_param_text[count]); |
3962 | devm_kfree(card->dev, w_param_text); | 3973 | devm_kfree(card->dev, w_param_text); |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 0d5ec68a1e50..be80a12fba27 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/pinctrl/consumer.h> | 16 | #include <linux/pinctrl/consumer.h> |
17 | #include <linux/pm_runtime.h> | 17 | #include <linux/pm_runtime.h> |
18 | #include <linux/module.h> | ||
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | #include <linux/workqueue.h> | 20 | #include <linux/workqueue.h> |
20 | #include <linux/export.h> | 21 | #include <linux/export.h> |
@@ -463,6 +464,9 @@ static int soc_pcm_components_close(struct snd_pcm_substream *substream, | |||
463 | continue; | 464 | continue; |
464 | 465 | ||
465 | component->driver->ops->close(substream); | 466 | component->driver->ops->close(substream); |
467 | |||
468 | if (component->driver->module_get_upon_open) | ||
469 | module_put(component->dev->driver->owner); | ||
466 | } | 470 | } |
467 | 471 | ||
468 | return 0; | 472 | return 0; |
@@ -513,6 +517,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
513 | !component->driver->ops->open) | 517 | !component->driver->ops->open) |
514 | continue; | 518 | continue; |
515 | 519 | ||
520 | if (component->driver->module_get_upon_open && | ||
521 | !try_module_get(component->dev->driver->owner)) { | ||
522 | ret = -ENODEV; | ||
523 | goto module_err; | ||
524 | } | ||
525 | |||
516 | ret = component->driver->ops->open(substream); | 526 | ret = component->driver->ops->open(substream); |
517 | if (ret < 0) { | 527 | if (ret < 0) { |
518 | dev_err(component->dev, | 528 | dev_err(component->dev, |
@@ -628,7 +638,7 @@ codec_dai_err: | |||
628 | 638 | ||
629 | component_err: | 639 | component_err: |
630 | soc_pcm_components_close(substream, component); | 640 | soc_pcm_components_close(substream, component); |
631 | 641 | module_err: | |
632 | if (cpu_dai->driver->ops->shutdown) | 642 | if (cpu_dai->driver->ops->shutdown) |
633 | cpu_dai->driver->ops->shutdown(substream, cpu_dai); | 643 | cpu_dai->driver->ops->shutdown(substream, cpu_dai); |
634 | out: | 644 | out: |
@@ -954,10 +964,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
954 | codec_params = *params; | 964 | codec_params = *params; |
955 | 965 | ||
956 | /* fixup params based on TDM slot masks */ | 966 | /* fixup params based on TDM slot masks */ |
957 | if (codec_dai->tx_mask) | 967 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && |
968 | codec_dai->tx_mask) | ||
958 | soc_pcm_codec_params_fixup(&codec_params, | 969 | soc_pcm_codec_params_fixup(&codec_params, |
959 | codec_dai->tx_mask); | 970 | codec_dai->tx_mask); |
960 | if (codec_dai->rx_mask) | 971 | |
972 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && | ||
973 | codec_dai->rx_mask) | ||
961 | soc_pcm_codec_params_fixup(&codec_params, | 974 | soc_pcm_codec_params_fixup(&codec_params, |
962 | codec_dai->rx_mask); | 975 | codec_dai->rx_mask); |
963 | 976 | ||
@@ -1213,6 +1226,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, | |||
1213 | struct snd_soc_pcm_runtime *be, int stream) | 1226 | struct snd_soc_pcm_runtime *be, int stream) |
1214 | { | 1227 | { |
1215 | struct snd_soc_dpcm *dpcm; | 1228 | struct snd_soc_dpcm *dpcm; |
1229 | unsigned long flags; | ||
1216 | 1230 | ||
1217 | /* only add new dpcms */ | 1231 | /* only add new dpcms */ |
1218 | for_each_dpcm_be(fe, stream, dpcm) { | 1232 | for_each_dpcm_be(fe, stream, dpcm) { |
@@ -1228,8 +1242,10 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, | |||
1228 | dpcm->fe = fe; | 1242 | dpcm->fe = fe; |
1229 | be->dpcm[stream].runtime = fe->dpcm[stream].runtime; | 1243 | be->dpcm[stream].runtime = fe->dpcm[stream].runtime; |
1230 | dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW; | 1244 | dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW; |
1245 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
1231 | list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients); | 1246 | list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients); |
1232 | list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients); | 1247 | list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients); |
1248 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
1233 | 1249 | ||
1234 | dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n", | 1250 | dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n", |
1235 | stream ? "capture" : "playback", fe->dai_link->name, | 1251 | stream ? "capture" : "playback", fe->dai_link->name, |
@@ -1275,6 +1291,7 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe, | |||
1275 | void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) | 1291 | void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) |
1276 | { | 1292 | { |
1277 | struct snd_soc_dpcm *dpcm, *d; | 1293 | struct snd_soc_dpcm *dpcm, *d; |
1294 | unsigned long flags; | ||
1278 | 1295 | ||
1279 | for_each_dpcm_be_safe(fe, stream, dpcm, d) { | 1296 | for_each_dpcm_be_safe(fe, stream, dpcm, d) { |
1280 | dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", | 1297 | dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", |
@@ -1294,8 +1311,10 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) | |||
1294 | #ifdef CONFIG_DEBUG_FS | 1311 | #ifdef CONFIG_DEBUG_FS |
1295 | debugfs_remove(dpcm->debugfs_state); | 1312 | debugfs_remove(dpcm->debugfs_state); |
1296 | #endif | 1313 | #endif |
1314 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
1297 | list_del(&dpcm->list_be); | 1315 | list_del(&dpcm->list_be); |
1298 | list_del(&dpcm->list_fe); | 1316 | list_del(&dpcm->list_fe); |
1317 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
1299 | kfree(dpcm); | 1318 | kfree(dpcm); |
1300 | } | 1319 | } |
1301 | } | 1320 | } |
@@ -1547,10 +1566,13 @@ int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, | |||
1547 | void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) | 1566 | void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) |
1548 | { | 1567 | { |
1549 | struct snd_soc_dpcm *dpcm; | 1568 | struct snd_soc_dpcm *dpcm; |
1569 | unsigned long flags; | ||
1550 | 1570 | ||
1571 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
1551 | for_each_dpcm_be(fe, stream, dpcm) | 1572 | for_each_dpcm_be(fe, stream, dpcm) |
1552 | dpcm->be->dpcm[stream].runtime_update = | 1573 | dpcm->be->dpcm[stream].runtime_update = |
1553 | SND_SOC_DPCM_UPDATE_NO; | 1574 | SND_SOC_DPCM_UPDATE_NO; |
1575 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
1554 | } | 1576 | } |
1555 | 1577 | ||
1556 | static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe, | 1578 | static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe, |
@@ -1899,10 +1921,15 @@ static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream, | |||
1899 | struct snd_soc_pcm_runtime *be = dpcm->be; | 1921 | struct snd_soc_pcm_runtime *be = dpcm->be; |
1900 | struct snd_pcm_substream *be_substream = | 1922 | struct snd_pcm_substream *be_substream = |
1901 | snd_soc_dpcm_get_substream(be, stream); | 1923 | snd_soc_dpcm_get_substream(be, stream); |
1902 | struct snd_soc_pcm_runtime *rtd = be_substream->private_data; | 1924 | struct snd_soc_pcm_runtime *rtd; |
1903 | struct snd_soc_dai *codec_dai; | 1925 | struct snd_soc_dai *codec_dai; |
1904 | int i; | 1926 | int i; |
1905 | 1927 | ||
1928 | /* A backend may not have the requested substream */ | ||
1929 | if (!be_substream) | ||
1930 | continue; | ||
1931 | |||
1932 | rtd = be_substream->private_data; | ||
1906 | if (rtd->dai_link->be_hw_params_fixup) | 1933 | if (rtd->dai_link->be_hw_params_fixup) |
1907 | continue; | 1934 | continue; |
1908 | 1935 | ||
@@ -2571,6 +2598,7 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) | |||
2571 | struct snd_soc_dpcm *dpcm; | 2598 | struct snd_soc_dpcm *dpcm; |
2572 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; | 2599 | enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; |
2573 | int ret; | 2600 | int ret; |
2601 | unsigned long flags; | ||
2574 | 2602 | ||
2575 | dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", | 2603 | dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", |
2576 | stream ? "capture" : "playback", fe->dai_link->name); | 2604 | stream ? "capture" : "playback", fe->dai_link->name); |
@@ -2640,11 +2668,13 @@ close: | |||
2640 | dpcm_be_dai_shutdown(fe, stream); | 2668 | dpcm_be_dai_shutdown(fe, stream); |
2641 | disconnect: | 2669 | disconnect: |
2642 | /* disconnect any non started BEs */ | 2670 | /* disconnect any non started BEs */ |
2671 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
2643 | for_each_dpcm_be(fe, stream, dpcm) { | 2672 | for_each_dpcm_be(fe, stream, dpcm) { |
2644 | struct snd_soc_pcm_runtime *be = dpcm->be; | 2673 | struct snd_soc_pcm_runtime *be = dpcm->be; |
2645 | if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) | 2674 | if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) |
2646 | dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; | 2675 | dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; |
2647 | } | 2676 | } |
2677 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
2648 | 2678 | ||
2649 | return ret; | 2679 | return ret; |
2650 | } | 2680 | } |
@@ -3221,7 +3251,10 @@ int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, | |||
3221 | { | 3251 | { |
3222 | struct snd_soc_dpcm *dpcm; | 3252 | struct snd_soc_dpcm *dpcm; |
3223 | int state; | 3253 | int state; |
3254 | int ret = 1; | ||
3255 | unsigned long flags; | ||
3224 | 3256 | ||
3257 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
3225 | for_each_dpcm_fe(be, stream, dpcm) { | 3258 | for_each_dpcm_fe(be, stream, dpcm) { |
3226 | 3259 | ||
3227 | if (dpcm->fe == fe) | 3260 | if (dpcm->fe == fe) |
@@ -3230,12 +3263,15 @@ int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, | |||
3230 | state = dpcm->fe->dpcm[stream].state; | 3263 | state = dpcm->fe->dpcm[stream].state; |
3231 | if (state == SND_SOC_DPCM_STATE_START || | 3264 | if (state == SND_SOC_DPCM_STATE_START || |
3232 | state == SND_SOC_DPCM_STATE_PAUSED || | 3265 | state == SND_SOC_DPCM_STATE_PAUSED || |
3233 | state == SND_SOC_DPCM_STATE_SUSPEND) | 3266 | state == SND_SOC_DPCM_STATE_SUSPEND) { |
3234 | return 0; | 3267 | ret = 0; |
3268 | break; | ||
3269 | } | ||
3235 | } | 3270 | } |
3271 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
3236 | 3272 | ||
3237 | /* it's safe to free/stop this BE DAI */ | 3273 | /* it's safe to free/stop this BE DAI */ |
3238 | return 1; | 3274 | return ret; |
3239 | } | 3275 | } |
3240 | EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop); | 3276 | EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop); |
3241 | 3277 | ||
@@ -3248,7 +3284,10 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, | |||
3248 | { | 3284 | { |
3249 | struct snd_soc_dpcm *dpcm; | 3285 | struct snd_soc_dpcm *dpcm; |
3250 | int state; | 3286 | int state; |
3287 | int ret = 1; | ||
3288 | unsigned long flags; | ||
3251 | 3289 | ||
3290 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
3252 | for_each_dpcm_fe(be, stream, dpcm) { | 3291 | for_each_dpcm_fe(be, stream, dpcm) { |
3253 | 3292 | ||
3254 | if (dpcm->fe == fe) | 3293 | if (dpcm->fe == fe) |
@@ -3258,12 +3297,15 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, | |||
3258 | if (state == SND_SOC_DPCM_STATE_START || | 3297 | if (state == SND_SOC_DPCM_STATE_START || |
3259 | state == SND_SOC_DPCM_STATE_PAUSED || | 3298 | state == SND_SOC_DPCM_STATE_PAUSED || |
3260 | state == SND_SOC_DPCM_STATE_SUSPEND || | 3299 | state == SND_SOC_DPCM_STATE_SUSPEND || |
3261 | state == SND_SOC_DPCM_STATE_PREPARE) | 3300 | state == SND_SOC_DPCM_STATE_PREPARE) { |
3262 | return 0; | 3301 | ret = 0; |
3302 | break; | ||
3303 | } | ||
3263 | } | 3304 | } |
3305 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | ||
3264 | 3306 | ||
3265 | /* it's safe to change hw_params */ | 3307 | /* it's safe to change hw_params */ |
3266 | return 1; | 3308 | return ret; |
3267 | } | 3309 | } |
3268 | EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); | 3310 | EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); |
3269 | 3311 | ||
@@ -3302,6 +3344,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, | |||
3302 | struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params; | 3344 | struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params; |
3303 | struct snd_soc_dpcm *dpcm; | 3345 | struct snd_soc_dpcm *dpcm; |
3304 | ssize_t offset = 0; | 3346 | ssize_t offset = 0; |
3347 | unsigned long flags; | ||
3305 | 3348 | ||
3306 | /* FE state */ | 3349 | /* FE state */ |
3307 | offset += snprintf(buf + offset, size - offset, | 3350 | offset += snprintf(buf + offset, size - offset, |
@@ -3329,6 +3372,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, | |||
3329 | goto out; | 3372 | goto out; |
3330 | } | 3373 | } |
3331 | 3374 | ||
3375 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | ||
3332 | for_each_dpcm_be(fe, stream, dpcm) { | 3376 | for_each_dpcm_be(fe, stream, dpcm) { |
3333 | struct snd_soc_pcm_runtime *be = dpcm->be; | 3377 | struct snd_soc_pcm_runtime *be = dpcm->be; |
3334 | params = &dpcm->hw_params; | 3378 | params = &dpcm->hw_params; |
@@ -3349,7 +3393,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, | |||
3349 | params_channels(params), | 3393 | params_channels(params), |
3350 | params_rate(params)); | 3394 | params_rate(params)); |
3351 | } | 3395 | } |
3352 | 3396 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | |
3353 | out: | 3397 | out: |
3354 | return offset; | 3398 | return offset; |
3355 | } | 3399 | } |
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 25fca7055464..96852d250619 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c | |||
@@ -482,10 +482,11 @@ static void remove_widget(struct snd_soc_component *comp, | |||
482 | 482 | ||
483 | snd_ctl_remove(card, kcontrol); | 483 | snd_ctl_remove(card, kcontrol); |
484 | 484 | ||
485 | kfree(dobj->control.dvalues); | 485 | /* free enum kcontrol's dvalues and dtexts */ |
486 | kfree(se->dobj.control.dvalues); | ||
486 | for (j = 0; j < se->items; j++) | 487 | for (j = 0; j < se->items; j++) |
487 | kfree(dobj->control.dtexts[j]); | 488 | kfree(se->dobj.control.dtexts[j]); |
488 | kfree(dobj->control.dtexts); | 489 | kfree(se->dobj.control.dtexts); |
489 | 490 | ||
490 | kfree(se); | 491 | kfree(se); |
491 | kfree(w->kcontrol_news[i].name); | 492 | kfree(w->kcontrol_news[i].name); |
diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c index 47901983a6ff..78bed9734713 100644 --- a/sound/soc/stm/stm32_adfsdm.c +++ b/sound/soc/stm/stm32_adfsdm.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/mutex.h> | ||
12 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
13 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
14 | 15 | ||
@@ -37,6 +38,8 @@ struct stm32_adfsdm_priv { | |||
37 | /* PCM buffer */ | 38 | /* PCM buffer */ |
38 | unsigned char *pcm_buff; | 39 | unsigned char *pcm_buff; |
39 | unsigned int pos; | 40 | unsigned int pos; |
41 | |||
42 | struct mutex lock; /* protect against race condition on iio state */ | ||
40 | }; | 43 | }; |
41 | 44 | ||
42 | static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = { | 45 | static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = { |
@@ -62,10 +65,12 @@ static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream, | |||
62 | { | 65 | { |
63 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); | 66 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); |
64 | 67 | ||
68 | mutex_lock(&priv->lock); | ||
65 | if (priv->iio_active) { | 69 | if (priv->iio_active) { |
66 | iio_channel_stop_all_cb(priv->iio_cb); | 70 | iio_channel_stop_all_cb(priv->iio_cb); |
67 | priv->iio_active = false; | 71 | priv->iio_active = false; |
68 | } | 72 | } |
73 | mutex_unlock(&priv->lock); | ||
69 | } | 74 | } |
70 | 75 | ||
71 | static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, | 76 | static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, |
@@ -74,13 +79,19 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, | |||
74 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); | 79 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); |
75 | int ret; | 80 | int ret; |
76 | 81 | ||
82 | mutex_lock(&priv->lock); | ||
83 | if (priv->iio_active) { | ||
84 | iio_channel_stop_all_cb(priv->iio_cb); | ||
85 | priv->iio_active = false; | ||
86 | } | ||
87 | |||
77 | ret = iio_write_channel_attribute(priv->iio_ch, | 88 | ret = iio_write_channel_attribute(priv->iio_ch, |
78 | substream->runtime->rate, 0, | 89 | substream->runtime->rate, 0, |
79 | IIO_CHAN_INFO_SAMP_FREQ); | 90 | IIO_CHAN_INFO_SAMP_FREQ); |
80 | if (ret < 0) { | 91 | if (ret < 0) { |
81 | dev_err(dai->dev, "%s: Failed to set %d sampling rate\n", | 92 | dev_err(dai->dev, "%s: Failed to set %d sampling rate\n", |
82 | __func__, substream->runtime->rate); | 93 | __func__, substream->runtime->rate); |
83 | return ret; | 94 | goto out; |
84 | } | 95 | } |
85 | 96 | ||
86 | if (!priv->iio_active) { | 97 | if (!priv->iio_active) { |
@@ -92,6 +103,9 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, | |||
92 | __func__, ret); | 103 | __func__, ret); |
93 | } | 104 | } |
94 | 105 | ||
106 | out: | ||
107 | mutex_unlock(&priv->lock); | ||
108 | |||
95 | return ret; | 109 | return ret; |
96 | } | 110 | } |
97 | 111 | ||
@@ -291,6 +305,7 @@ MODULE_DEVICE_TABLE(of, stm32_adfsdm_of_match); | |||
291 | static int stm32_adfsdm_probe(struct platform_device *pdev) | 305 | static int stm32_adfsdm_probe(struct platform_device *pdev) |
292 | { | 306 | { |
293 | struct stm32_adfsdm_priv *priv; | 307 | struct stm32_adfsdm_priv *priv; |
308 | struct snd_soc_component *component; | ||
294 | int ret; | 309 | int ret; |
295 | 310 | ||
296 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 311 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
@@ -299,6 +314,7 @@ static int stm32_adfsdm_probe(struct platform_device *pdev) | |||
299 | 314 | ||
300 | priv->dev = &pdev->dev; | 315 | priv->dev = &pdev->dev; |
301 | priv->dai_drv = stm32_adfsdm_dai; | 316 | priv->dai_drv = stm32_adfsdm_dai; |
317 | mutex_init(&priv->lock); | ||
302 | 318 | ||
303 | dev_set_drvdata(&pdev->dev, priv); | 319 | dev_set_drvdata(&pdev->dev, priv); |
304 | 320 | ||
@@ -317,9 +333,15 @@ static int stm32_adfsdm_probe(struct platform_device *pdev) | |||
317 | if (IS_ERR(priv->iio_cb)) | 333 | if (IS_ERR(priv->iio_cb)) |
318 | return PTR_ERR(priv->iio_cb); | 334 | return PTR_ERR(priv->iio_cb); |
319 | 335 | ||
320 | ret = devm_snd_soc_register_component(&pdev->dev, | 336 | component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL); |
321 | &stm32_adfsdm_soc_platform, | 337 | if (!component) |
322 | NULL, 0); | 338 | return -ENOMEM; |
339 | #ifdef CONFIG_DEBUG_FS | ||
340 | component->debugfs_prefix = "pcm"; | ||
341 | #endif | ||
342 | |||
343 | ret = snd_soc_add_component(&pdev->dev, component, | ||
344 | &stm32_adfsdm_soc_platform, NULL, 0); | ||
323 | if (ret < 0) | 345 | if (ret < 0) |
324 | dev_err(&pdev->dev, "%s: Failed to register PCM platform\n", | 346 | dev_err(&pdev->dev, "%s: Failed to register PCM platform\n", |
325 | __func__); | 347 | __func__); |
@@ -327,12 +349,20 @@ static int stm32_adfsdm_probe(struct platform_device *pdev) | |||
327 | return ret; | 349 | return ret; |
328 | } | 350 | } |
329 | 351 | ||
352 | static int stm32_adfsdm_remove(struct platform_device *pdev) | ||
353 | { | ||
354 | snd_soc_unregister_component(&pdev->dev); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
330 | static struct platform_driver stm32_adfsdm_driver = { | 359 | static struct platform_driver stm32_adfsdm_driver = { |
331 | .driver = { | 360 | .driver = { |
332 | .name = STM32_ADFSDM_DRV_NAME, | 361 | .name = STM32_ADFSDM_DRV_NAME, |
333 | .of_match_table = stm32_adfsdm_of_match, | 362 | .of_match_table = stm32_adfsdm_of_match, |
334 | }, | 363 | }, |
335 | .probe = stm32_adfsdm_probe, | 364 | .probe = stm32_adfsdm_probe, |
365 | .remove = stm32_adfsdm_remove, | ||
336 | }; | 366 | }; |
337 | 367 | ||
338 | module_platform_driver(stm32_adfsdm_driver); | 368 | module_platform_driver(stm32_adfsdm_driver); |
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 47c334de6b09..8968458eec62 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c | |||
@@ -281,7 +281,6 @@ static bool stm32_i2s_readable_reg(struct device *dev, unsigned int reg) | |||
281 | case STM32_I2S_CFG2_REG: | 281 | case STM32_I2S_CFG2_REG: |
282 | case STM32_I2S_IER_REG: | 282 | case STM32_I2S_IER_REG: |
283 | case STM32_I2S_SR_REG: | 283 | case STM32_I2S_SR_REG: |
284 | case STM32_I2S_TXDR_REG: | ||
285 | case STM32_I2S_RXDR_REG: | 284 | case STM32_I2S_RXDR_REG: |
286 | case STM32_I2S_CGFR_REG: | 285 | case STM32_I2S_CGFR_REG: |
287 | return true; | 286 | return true; |
@@ -293,7 +292,7 @@ static bool stm32_i2s_readable_reg(struct device *dev, unsigned int reg) | |||
293 | static bool stm32_i2s_volatile_reg(struct device *dev, unsigned int reg) | 292 | static bool stm32_i2s_volatile_reg(struct device *dev, unsigned int reg) |
294 | { | 293 | { |
295 | switch (reg) { | 294 | switch (reg) { |
296 | case STM32_I2S_TXDR_REG: | 295 | case STM32_I2S_SR_REG: |
297 | case STM32_I2S_RXDR_REG: | 296 | case STM32_I2S_RXDR_REG: |
298 | return true; | 297 | return true; |
299 | default: | 298 | default: |
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index 14c9591aae42..d68d62f12df5 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c | |||
@@ -105,6 +105,7 @@ static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, | |||
105 | if (!pdev) { | 105 | if (!pdev) { |
106 | dev_err(&sai_client->pdev->dev, | 106 | dev_err(&sai_client->pdev->dev, |
107 | "Device not found for node %pOFn\n", np_provider); | 107 | "Device not found for node %pOFn\n", np_provider); |
108 | of_node_put(np_provider); | ||
108 | return -ENODEV; | 109 | return -ENODEV; |
109 | } | 110 | } |
110 | 111 | ||
@@ -113,19 +114,20 @@ static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, | |||
113 | dev_err(&sai_client->pdev->dev, | 114 | dev_err(&sai_client->pdev->dev, |
114 | "SAI sync provider data not found\n"); | 115 | "SAI sync provider data not found\n"); |
115 | ret = -EINVAL; | 116 | ret = -EINVAL; |
116 | goto out_put_dev; | 117 | goto error; |
117 | } | 118 | } |
118 | 119 | ||
119 | /* Configure sync client */ | 120 | /* Configure sync client */ |
120 | ret = stm32_sai_sync_conf_client(sai_client, synci); | 121 | ret = stm32_sai_sync_conf_client(sai_client, synci); |
121 | if (ret < 0) | 122 | if (ret < 0) |
122 | goto out_put_dev; | 123 | goto error; |
123 | 124 | ||
124 | /* Configure sync provider */ | 125 | /* Configure sync provider */ |
125 | ret = stm32_sai_sync_conf_provider(sai_provider, synco); | 126 | ret = stm32_sai_sync_conf_provider(sai_provider, synco); |
126 | 127 | ||
127 | out_put_dev: | 128 | error: |
128 | put_device(&pdev->dev); | 129 | put_device(&pdev->dev); |
130 | of_node_put(np_provider); | ||
129 | return ret; | 131 | return ret; |
130 | } | 132 | } |
131 | 133 | ||
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index f9297228c41c..d7045aa520de 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #define SAI_IEC60958_STATUS_BYTES 24 | 70 | #define SAI_IEC60958_STATUS_BYTES 24 |
71 | 71 | ||
72 | #define SAI_MCLK_NAME_LEN 32 | 72 | #define SAI_MCLK_NAME_LEN 32 |
73 | #define SAI_RATE_11K 11025 | ||
73 | 74 | ||
74 | /** | 75 | /** |
75 | * struct stm32_sai_sub_data - private data of SAI sub block (block A or B) | 76 | * struct stm32_sai_sub_data - private data of SAI sub block (block A or B) |
@@ -100,8 +101,9 @@ | |||
100 | * @slot_mask: rx or tx active slots mask. set at init or at runtime | 101 | * @slot_mask: rx or tx active slots mask. set at init or at runtime |
101 | * @data_size: PCM data width. corresponds to PCM substream width. | 102 | * @data_size: PCM data width. corresponds to PCM substream width. |
102 | * @spdif_frm_cnt: S/PDIF playback frame counter | 103 | * @spdif_frm_cnt: S/PDIF playback frame counter |
103 | * @snd_aes_iec958: iec958 data | 104 | * @iec958: iec958 data |
104 | * @ctrl_lock: control lock | 105 | * @ctrl_lock: control lock |
106 | * @irq_lock: prevent race condition with IRQ | ||
105 | */ | 107 | */ |
106 | struct stm32_sai_sub_data { | 108 | struct stm32_sai_sub_data { |
107 | struct platform_device *pdev; | 109 | struct platform_device *pdev; |
@@ -133,6 +135,7 @@ struct stm32_sai_sub_data { | |||
133 | unsigned int spdif_frm_cnt; | 135 | unsigned int spdif_frm_cnt; |
134 | struct snd_aes_iec958 iec958; | 136 | struct snd_aes_iec958 iec958; |
135 | struct mutex ctrl_lock; /* protect resources accessed by controls */ | 137 | struct mutex ctrl_lock; /* protect resources accessed by controls */ |
138 | spinlock_t irq_lock; /* used to prevent race condition with IRQ */ | ||
136 | }; | 139 | }; |
137 | 140 | ||
138 | enum stm32_sai_fifo_th { | 141 | enum stm32_sai_fifo_th { |
@@ -307,6 +310,25 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai, | |||
307 | return ret; | 310 | return ret; |
308 | } | 311 | } |
309 | 312 | ||
313 | static int stm32_sai_set_parent_clock(struct stm32_sai_sub_data *sai, | ||
314 | unsigned int rate) | ||
315 | { | ||
316 | struct platform_device *pdev = sai->pdev; | ||
317 | struct clk *parent_clk = sai->pdata->clk_x8k; | ||
318 | int ret; | ||
319 | |||
320 | if (!(rate % SAI_RATE_11K)) | ||
321 | parent_clk = sai->pdata->clk_x11k; | ||
322 | |||
323 | ret = clk_set_parent(sai->sai_ck, parent_clk); | ||
324 | if (ret) | ||
325 | dev_err(&pdev->dev, " Error %d setting sai_ck parent clock. %s", | ||
326 | ret, ret == -EBUSY ? | ||
327 | "Active stream rates conflict\n" : "\n"); | ||
328 | |||
329 | return ret; | ||
330 | } | ||
331 | |||
310 | static long stm32_sai_mclk_round_rate(struct clk_hw *hw, unsigned long rate, | 332 | static long stm32_sai_mclk_round_rate(struct clk_hw *hw, unsigned long rate, |
311 | unsigned long *prate) | 333 | unsigned long *prate) |
312 | { | 334 | { |
@@ -474,8 +496,10 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid) | |||
474 | status = SNDRV_PCM_STATE_XRUN; | 496 | status = SNDRV_PCM_STATE_XRUN; |
475 | } | 497 | } |
476 | 498 | ||
477 | if (status != SNDRV_PCM_STATE_RUNNING) | 499 | spin_lock(&sai->irq_lock); |
500 | if (status != SNDRV_PCM_STATE_RUNNING && sai->substream) | ||
478 | snd_pcm_stop_xrun(sai->substream); | 501 | snd_pcm_stop_xrun(sai->substream); |
502 | spin_unlock(&sai->irq_lock); | ||
479 | 503 | ||
480 | return IRQ_HANDLED; | 504 | return IRQ_HANDLED; |
481 | } | 505 | } |
@@ -486,25 +510,29 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai, | |||
486 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); | 510 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); |
487 | int ret; | 511 | int ret; |
488 | 512 | ||
489 | if (dir == SND_SOC_CLOCK_OUT) { | 513 | if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) { |
490 | ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, | 514 | ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, |
491 | SAI_XCR1_NODIV, | 515 | SAI_XCR1_NODIV, |
492 | (unsigned int)~SAI_XCR1_NODIV); | 516 | (unsigned int)~SAI_XCR1_NODIV); |
493 | if (ret < 0) | 517 | if (ret < 0) |
494 | return ret; | 518 | return ret; |
495 | 519 | ||
496 | dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq); | 520 | /* If master clock is used, set parent clock now */ |
497 | sai->mclk_rate = freq; | 521 | ret = stm32_sai_set_parent_clock(sai, freq); |
522 | if (ret) | ||
523 | return ret; | ||
498 | 524 | ||
499 | if (sai->sai_mclk) { | 525 | ret = clk_set_rate_exclusive(sai->sai_mclk, freq); |
500 | ret = clk_set_rate_exclusive(sai->sai_mclk, | 526 | if (ret) { |
501 | sai->mclk_rate); | 527 | dev_err(cpu_dai->dev, |
502 | if (ret) { | 528 | ret == -EBUSY ? |
503 | dev_err(cpu_dai->dev, | 529 | "Active streams have incompatible rates" : |
504 | "Could not set mclk rate\n"); | 530 | "Could not set mclk rate\n"); |
505 | return ret; | 531 | return ret; |
506 | } | ||
507 | } | 532 | } |
533 | |||
534 | dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq); | ||
535 | sai->mclk_rate = freq; | ||
508 | } | 536 | } |
509 | 537 | ||
510 | return 0; | 538 | return 0; |
@@ -679,8 +707,19 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream, | |||
679 | { | 707 | { |
680 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); | 708 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); |
681 | int imr, cr2, ret; | 709 | int imr, cr2, ret; |
710 | unsigned long flags; | ||
682 | 711 | ||
712 | spin_lock_irqsave(&sai->irq_lock, flags); | ||
683 | sai->substream = substream; | 713 | sai->substream = substream; |
714 | spin_unlock_irqrestore(&sai->irq_lock, flags); | ||
715 | |||
716 | if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) { | ||
717 | snd_pcm_hw_constraint_mask64(substream->runtime, | ||
718 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
719 | SNDRV_PCM_FMTBIT_S32_LE); | ||
720 | snd_pcm_hw_constraint_single(substream->runtime, | ||
721 | SNDRV_PCM_HW_PARAM_CHANNELS, 2); | ||
722 | } | ||
684 | 723 | ||
685 | ret = clk_prepare_enable(sai->sai_ck); | 724 | ret = clk_prepare_enable(sai->sai_ck); |
686 | if (ret < 0) { | 725 | if (ret < 0) { |
@@ -898,14 +937,16 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai, | |||
898 | struct snd_pcm_hw_params *params) | 937 | struct snd_pcm_hw_params *params) |
899 | { | 938 | { |
900 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); | 939 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); |
901 | int div = 0; | 940 | int div = 0, cr1 = 0; |
902 | int sai_clk_rate, mclk_ratio, den; | 941 | int sai_clk_rate, mclk_ratio, den; |
903 | unsigned int rate = params_rate(params); | 942 | unsigned int rate = params_rate(params); |
943 | int ret; | ||
904 | 944 | ||
905 | if (!(rate % 11025)) | 945 | if (!sai->sai_mclk) { |
906 | clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k); | 946 | ret = stm32_sai_set_parent_clock(sai, rate); |
907 | else | 947 | if (ret) |
908 | clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k); | 948 | return ret; |
949 | } | ||
909 | sai_clk_rate = clk_get_rate(sai->sai_ck); | 950 | sai_clk_rate = clk_get_rate(sai->sai_ck); |
910 | 951 | ||
911 | if (STM_SAI_IS_F4(sai->pdata)) { | 952 | if (STM_SAI_IS_F4(sai->pdata)) { |
@@ -943,13 +984,19 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai, | |||
943 | } else { | 984 | } else { |
944 | if (sai->mclk_rate) { | 985 | if (sai->mclk_rate) { |
945 | mclk_ratio = sai->mclk_rate / rate; | 986 | mclk_ratio = sai->mclk_rate / rate; |
946 | if ((mclk_ratio != 512) && | 987 | if (mclk_ratio == 512) { |
947 | (mclk_ratio != 256)) { | 988 | cr1 = SAI_XCR1_OSR; |
989 | } else if (mclk_ratio != 256) { | ||
948 | dev_err(cpu_dai->dev, | 990 | dev_err(cpu_dai->dev, |
949 | "Wrong mclk ratio %d\n", | 991 | "Wrong mclk ratio %d\n", |
950 | mclk_ratio); | 992 | mclk_ratio); |
951 | return -EINVAL; | 993 | return -EINVAL; |
952 | } | 994 | } |
995 | |||
996 | regmap_update_bits(sai->regmap, | ||
997 | STM_SAI_CR1_REGX, | ||
998 | SAI_XCR1_OSR, cr1); | ||
999 | |||
953 | div = stm32_sai_get_clk_div(sai, sai_clk_rate, | 1000 | div = stm32_sai_get_clk_div(sai, sai_clk_rate, |
954 | sai->mclk_rate); | 1001 | sai->mclk_rate); |
955 | if (div < 0) | 1002 | if (div < 0) |
@@ -1051,28 +1098,36 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream, | |||
1051 | struct snd_soc_dai *cpu_dai) | 1098 | struct snd_soc_dai *cpu_dai) |
1052 | { | 1099 | { |
1053 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); | 1100 | struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); |
1101 | unsigned long flags; | ||
1054 | 1102 | ||
1055 | regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); | 1103 | regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); |
1056 | 1104 | ||
1057 | regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_NODIV, | 1105 | regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_NODIV, |
1058 | SAI_XCR1_NODIV); | 1106 | SAI_XCR1_NODIV); |
1059 | 1107 | ||
1060 | clk_disable_unprepare(sai->sai_ck); | 1108 | /* Release mclk rate only if rate was actually set */ |
1109 | if (sai->mclk_rate) { | ||
1110 | clk_rate_exclusive_put(sai->sai_mclk); | ||
1111 | sai->mclk_rate = 0; | ||
1112 | } | ||
1061 | 1113 | ||
1062 | clk_rate_exclusive_put(sai->sai_mclk); | 1114 | clk_disable_unprepare(sai->sai_ck); |
1063 | 1115 | ||
1116 | spin_lock_irqsave(&sai->irq_lock, flags); | ||
1064 | sai->substream = NULL; | 1117 | sai->substream = NULL; |
1118 | spin_unlock_irqrestore(&sai->irq_lock, flags); | ||
1065 | } | 1119 | } |
1066 | 1120 | ||
1067 | static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd, | 1121 | static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd, |
1068 | struct snd_soc_dai *cpu_dai) | 1122 | struct snd_soc_dai *cpu_dai) |
1069 | { | 1123 | { |
1070 | struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); | 1124 | struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); |
1125 | struct snd_kcontrol_new knew = iec958_ctls; | ||
1071 | 1126 | ||
1072 | if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) { | 1127 | if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) { |
1073 | dev_dbg(&sai->pdev->dev, "%s: register iec controls", __func__); | 1128 | dev_dbg(&sai->pdev->dev, "%s: register iec controls", __func__); |
1074 | return snd_ctl_add(rtd->pcm->card, | 1129 | knew.device = rtd->pcm->device; |
1075 | snd_ctl_new1(&iec958_ctls, sai)); | 1130 | return snd_ctl_add(rtd->pcm->card, snd_ctl_new1(&knew, sai)); |
1076 | } | 1131 | } |
1077 | 1132 | ||
1078 | return 0; | 1133 | return 0; |
@@ -1081,7 +1136,7 @@ static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd, | |||
1081 | static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) | 1136 | static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) |
1082 | { | 1137 | { |
1083 | struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); | 1138 | struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); |
1084 | int cr1 = 0, cr1_mask; | 1139 | int cr1 = 0, cr1_mask, ret; |
1085 | 1140 | ||
1086 | sai->cpu_dai = cpu_dai; | 1141 | sai->cpu_dai = cpu_dai; |
1087 | 1142 | ||
@@ -1111,8 +1166,10 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) | |||
1111 | /* Configure synchronization */ | 1166 | /* Configure synchronization */ |
1112 | if (sai->sync == SAI_SYNC_EXTERNAL) { | 1167 | if (sai->sync == SAI_SYNC_EXTERNAL) { |
1113 | /* Configure synchro client and provider */ | 1168 | /* Configure synchro client and provider */ |
1114 | sai->pdata->set_sync(sai->pdata, sai->np_sync_provider, | 1169 | ret = sai->pdata->set_sync(sai->pdata, sai->np_sync_provider, |
1115 | sai->synco, sai->synci); | 1170 | sai->synco, sai->synci); |
1171 | if (ret) | ||
1172 | return ret; | ||
1116 | } | 1173 | } |
1117 | 1174 | ||
1118 | cr1_mask |= SAI_XCR1_SYNCEN_MASK; | 1175 | cr1_mask |= SAI_XCR1_SYNCEN_MASK; |
@@ -1392,7 +1449,6 @@ static int stm32_sai_sub_dais_init(struct platform_device *pdev, | |||
1392 | if (!sai->cpu_dai_drv) | 1449 | if (!sai->cpu_dai_drv) |
1393 | return -ENOMEM; | 1450 | return -ENOMEM; |
1394 | 1451 | ||
1395 | sai->cpu_dai_drv->name = dev_name(&pdev->dev); | ||
1396 | if (STM_SAI_IS_PLAYBACK(sai)) { | 1452 | if (STM_SAI_IS_PLAYBACK(sai)) { |
1397 | memcpy(sai->cpu_dai_drv, &stm32_sai_playback_dai, | 1453 | memcpy(sai->cpu_dai_drv, &stm32_sai_playback_dai, |
1398 | sizeof(stm32_sai_playback_dai)); | 1454 | sizeof(stm32_sai_playback_dai)); |
@@ -1402,6 +1458,7 @@ static int stm32_sai_sub_dais_init(struct platform_device *pdev, | |||
1402 | sizeof(stm32_sai_capture_dai)); | 1458 | sizeof(stm32_sai_capture_dai)); |
1403 | sai->cpu_dai_drv->capture.stream_name = sai->cpu_dai_drv->name; | 1459 | sai->cpu_dai_drv->capture.stream_name = sai->cpu_dai_drv->name; |
1404 | } | 1460 | } |
1461 | sai->cpu_dai_drv->name = dev_name(&pdev->dev); | ||
1405 | 1462 | ||
1406 | return 0; | 1463 | return 0; |
1407 | } | 1464 | } |
@@ -1424,6 +1481,7 @@ static int stm32_sai_sub_probe(struct platform_device *pdev) | |||
1424 | 1481 | ||
1425 | sai->pdev = pdev; | 1482 | sai->pdev = pdev; |
1426 | mutex_init(&sai->ctrl_lock); | 1483 | mutex_init(&sai->ctrl_lock); |
1484 | spin_lock_init(&sai->irq_lock); | ||
1427 | platform_set_drvdata(pdev, sai); | 1485 | platform_set_drvdata(pdev, sai); |
1428 | 1486 | ||
1429 | sai->pdata = dev_get_drvdata(pdev->dev.parent); | 1487 | sai->pdata = dev_get_drvdata(pdev->dev.parent); |
diff --git a/sound/xen/xen_snd_front_alsa.c b/sound/xen/xen_snd_front_alsa.c index a7f413cb704d..b14ab512c2ce 100644 --- a/sound/xen/xen_snd_front_alsa.c +++ b/sound/xen/xen_snd_front_alsa.c | |||
@@ -441,7 +441,7 @@ static int shbuf_setup_backstore(struct xen_snd_front_pcm_stream_info *stream, | |||
441 | { | 441 | { |
442 | int i; | 442 | int i; |
443 | 443 | ||
444 | stream->buffer = alloc_pages_exact(stream->buffer_sz, GFP_KERNEL); | 444 | stream->buffer = alloc_pages_exact(buffer_sz, GFP_KERNEL); |
445 | if (!stream->buffer) | 445 | if (!stream->buffer) |
446 | return -ENOMEM; | 446 | return -ENOMEM; |
447 | 447 | ||