diff options
Diffstat (limited to 'sound')
31 files changed, 262 insertions, 149 deletions
diff --git a/sound/core/seq/Kconfig b/sound/core/seq/Kconfig index a536760a94c2..45c1336c6597 100644 --- a/sound/core/seq/Kconfig +++ b/sound/core/seq/Kconfig @@ -47,10 +47,10 @@ config SND_SEQ_HRTIMER_DEFAULT timer. config SND_SEQ_MIDI_EVENT - def_tristate SND_RAWMIDI + tristate config SND_SEQ_MIDI - tristate + def_tristate SND_RAWMIDI select SND_SEQ_MIDI_EVENT config SND_SEQ_MIDI_EMUL diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 272c55fe17c8..ea2d0ae85bd3 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -1502,16 +1502,11 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client, static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) { struct snd_seq_queue_info *info = arg; - int result; struct snd_seq_queue *q; - result = snd_seq_queue_alloc(client->number, info->locked, info->flags); - if (result < 0) - return result; - - q = queueptr(result); - if (q == NULL) - return -EINVAL; + q = snd_seq_queue_alloc(client->number, info->locked, info->flags); + if (IS_ERR(q)) + return PTR_ERR(q); info->queue = q->queue; info->locked = q->locked; @@ -1521,7 +1516,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) if (!info->name[0]) snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue); strlcpy(q->name, info->name, sizeof(q->name)); - queuefree(q); + snd_use_lock_free(&q->use_lock); return 0; } diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 450c5187eecb..79e0c5604ef8 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -184,22 +184,26 @@ void __exit snd_seq_queues_delete(void) static void queue_use(struct snd_seq_queue *queue, int client, int use); /* allocate a new queue - - * return queue index value or negative value for error + * return pointer to new queue or ERR_PTR(-errno) for error + * The new queue's use_lock is set to 1. It is the caller's responsibility to + * call snd_use_lock_free(&q->use_lock). */ -int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags) +struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int info_flags) { struct snd_seq_queue *q; q = queue_new(client, locked); if (q == NULL) - return -ENOMEM; + return ERR_PTR(-ENOMEM); q->info_flags = info_flags; queue_use(q, client, 1); + snd_use_lock_use(&q->use_lock); if (queue_list_add(q) < 0) { + snd_use_lock_free(&q->use_lock); queue_delete(q); - return -ENOMEM; + return ERR_PTR(-ENOMEM); } - return q->queue; + return q; } /* delete a queue - queue must be owned by the client */ diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h index 30c8111477f6..719093489a2c 100644 --- a/sound/core/seq/seq_queue.h +++ b/sound/core/seq/seq_queue.h @@ -71,7 +71,7 @@ void snd_seq_queues_delete(void); /* create new queue (constructor) */ -int snd_seq_queue_alloc(int client, int locked, unsigned int flags); +struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int flags); /* delete queue (destructor) */ int snd_seq_queue_delete(int client, int queueid); diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index dc585959ca32..a2b56b188be4 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -698,10 +698,18 @@ static int copy_gctl(struct snd_emu10k1 *emu, { struct snd_emu10k1_fx8010_control_old_gpr __user *octl; - if (emu->support_tlv) - return copy_from_user(gctl, &_gctl[idx], sizeof(*gctl)); + if (emu->support_tlv) { + if (in_kernel) + memcpy(gctl, (void *)&_gctl[idx], sizeof(*gctl)); + else if (copy_from_user(gctl, &_gctl[idx], sizeof(*gctl))) + return -EFAULT; + return 0; + } + octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl; - if (copy_from_user(gctl, &octl[idx], sizeof(*octl))) + if (in_kernel) + memcpy(gctl, (void *)&octl[idx], sizeof(*octl)); + else if (copy_from_user(gctl, &octl[idx], sizeof(*octl))) return -EFAULT; gctl->tlv = NULL; return 0; diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 2e402ece4c86..8e6b04b39dcc 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1235,8 +1235,6 @@ static int snd_fm801_create(struct snd_card *card, } } - snd_fm801_chip_init(chip); - if ((chip->tea575x_tuner & TUNER_ONLY) == 0) { if (devm_request_irq(&pci->dev, pci->irq, snd_fm801_interrupt, IRQF_SHARED, KBUILD_MODNAME, chip)) { @@ -1248,6 +1246,8 @@ static int snd_fm801_create(struct snd_card *card, pci_set_master(pci); } + snd_fm801_chip_init(chip); + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { snd_fm801_free(chip); return err; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 63bc894ddf5e..8c1289963c80 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -933,6 +933,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO), SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index d549f35f39d3..53f9311370de 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -3733,11 +3733,15 @@ HDA_CODEC_ENTRY(0x1002aa01, "R6xx HDMI", patch_atihdmi), HDA_CODEC_ENTRY(0x10951390, "SiI1390 HDMI", patch_generic_hdmi), HDA_CODEC_ENTRY(0x10951392, "SiI1392 HDMI", patch_generic_hdmi), HDA_CODEC_ENTRY(0x17e80047, "Chrontel HDMI", patch_generic_hdmi), +HDA_CODEC_ENTRY(0x10de0001, "MCP73 HDMI", patch_nvhdmi_2ch), HDA_CODEC_ENTRY(0x10de0002, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x), HDA_CODEC_ENTRY(0x10de0003, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x), +HDA_CODEC_ENTRY(0x10de0004, "GPU 04 HDMI", patch_nvhdmi_8ch_7x), HDA_CODEC_ENTRY(0x10de0005, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x), HDA_CODEC_ENTRY(0x10de0006, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x), HDA_CODEC_ENTRY(0x10de0007, "MCP79/7A HDMI", patch_nvhdmi_8ch_7x), +HDA_CODEC_ENTRY(0x10de0008, "GPU 08 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0009, "GPU 09 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de000a, "GPU 0a HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de000b, "GPU 0b HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de000c, "MCP89 HDMI", patch_nvhdmi), @@ -3764,17 +3768,40 @@ HDA_CODEC_ENTRY(0x10de0041, "GPU 41 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0042, "GPU 42 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0043, "GPU 43 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0044, "GPU 44 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0045, "GPU 45 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0050, "GPU 50 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0051, "GPU 51 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0052, "GPU 52 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0060, "GPU 60 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0061, "GPU 61 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0062, "GPU 62 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0067, "MCP67 HDMI", patch_nvhdmi_2ch), HDA_CODEC_ENTRY(0x10de0070, "GPU 70 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0071, "GPU 71 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0072, "GPU 72 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0073, "GPU 73 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0074, "GPU 74 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0076, "GPU 76 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de007b, "GPU 7b HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de007c, "GPU 7c HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de007d, "GPU 7d HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de007e, "GPU 7e HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0080, "GPU 80 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0081, "GPU 81 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0082, "GPU 82 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0083, "GPU 83 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0084, "GPU 84 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0090, "GPU 90 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0091, "GPU 91 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0092, "GPU 92 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0093, "GPU 93 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0094, "GPU 94 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0095, "GPU 95 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0097, "GPU 97 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0098, "GPU 98 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0099, "GPU 99 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch), +HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI", patch_nvhdmi_2ch), HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi), HDA_CODEC_ENTRY(0x11069f81, "VX900 HDMI/DP", patch_via_hdmi), HDA_CODEC_ENTRY(0x11069f84, "VX11 HDMI/DP", patch_generic_hdmi), diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 45d58fc1df39..217bb582aff1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2296,6 +2296,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3), SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), + SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP), @@ -3838,6 +3839,17 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, } } +static struct coef_fw alc225_pre_hsmode[] = { + UPDATE_COEF(0x4a, 1<<8, 0), + UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), + UPDATE_COEF(0x63, 3<<14, 3<<14), + UPDATE_COEF(0x4a, 3<<4, 2<<4), + UPDATE_COEF(0x4a, 3<<10, 3<<10), + UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10), + UPDATE_COEF(0x4a, 3<<10, 0), + {} +}; + static void alc_headset_mode_unplugged(struct hda_codec *codec) { static struct coef_fw coef0255[] = { @@ -3873,6 +3885,10 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) UPDATE_COEF(0x67, 0x2000, 0), {} }; + static struct coef_fw coef0298[] = { + UPDATE_COEF(0x19, 0x1300, 0x0300), + {} + }; static struct coef_fw coef0292[] = { WRITE_COEF(0x76, 0x000e), WRITE_COEF(0x6c, 0x2400), @@ -3895,13 +3911,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) {} }; static struct coef_fw coef0225[] = { - UPDATE_COEF(0x4a, 1<<8, 0), - UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), - UPDATE_COEF(0x63, 3<<14, 3<<14), - UPDATE_COEF(0x4a, 3<<4, 2<<4), - UPDATE_COEF(0x4a, 3<<10, 3<<10), - UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10), - UPDATE_COEF(0x4a, 3<<10, 0), + UPDATE_COEF(0x63, 3<<14, 0), {} }; static struct coef_fw coef0274[] = { @@ -3935,7 +3945,10 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) break; case 0x10ec0286: case 0x10ec0288: + alc_process_coef_fw(codec, coef0288); + break; case 0x10ec0298: + alc_process_coef_fw(codec, coef0298); alc_process_coef_fw(codec, coef0288); break; case 0x10ec0292: @@ -3976,6 +3989,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, {} }; static struct coef_fw coef0288[] = { + UPDATE_COEF(0x4f, 0x00c0, 0), UPDATE_COEF(0x50, 0x2000, 0), UPDATE_COEF(0x56, 0x0006, 0), UPDATE_COEF(0x4f, 0xfcc0, 0xc400), @@ -4039,7 +4053,6 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, case 0x10ec0286: case 0x10ec0288: case 0x10ec0298: - alc_update_coef_idx(codec, 0x4f, 0x000c, 0); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); alc_process_coef_fw(codec, coef0288); snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); @@ -4072,6 +4085,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, case 0x10ec0225: case 0x10ec0295: case 0x10ec0299: + alc_process_coef_fw(codec, alc225_pre_hsmode); alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); alc_process_coef_fw(codec, coef0225); @@ -4084,7 +4098,12 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, static void alc_headset_mode_default(struct hda_codec *codec) { static struct coef_fw coef0225[] = { - UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10), + UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10), + UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10), + UPDATE_COEF(0x49, 3<<8, 0<<8), + UPDATE_COEF(0x4a, 3<<4, 3<<4), + UPDATE_COEF(0x63, 3<<14, 0), + UPDATE_COEF(0x67, 0xf000, 0x3000), {} }; static struct coef_fw coef0255[] = { @@ -4138,6 +4157,7 @@ static void alc_headset_mode_default(struct hda_codec *codec) case 0x10ec0225: case 0x10ec0295: case 0x10ec0299: + alc_process_coef_fw(codec, alc225_pre_hsmode); alc_process_coef_fw(codec, coef0225); break; case 0x10ec0255: @@ -4177,6 +4197,8 @@ static void alc_headset_mode_default(struct hda_codec *codec) /* Iphone type */ static void alc_headset_mode_ctia(struct hda_codec *codec) { + int val; + static struct coef_fw coef0255[] = { WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */ WRITE_COEF(0x1b, 0x0c2b), @@ -4219,11 +4241,14 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) WRITE_COEF(0xc3, 0x0000), {} }; - static struct coef_fw coef0225[] = { + static struct coef_fw coef0225_1[] = { UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10), - UPDATE_COEF(0x49, 1<<8, 1<<8), - UPDATE_COEF(0x4a, 7<<6, 7<<6), - UPDATE_COEF(0x4a, 3<<4, 3<<4), + UPDATE_COEF(0x63, 3<<14, 2<<14), + {} + }; + static struct coef_fw coef0225_2[] = { + UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10), + UPDATE_COEF(0x63, 3<<14, 1<<14), {} }; @@ -4244,8 +4269,17 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) alc_process_coef_fw(codec, coef0233); break; case 0x10ec0298: - alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);/* Headset output enable */ - /* ALC298 jack type setting is the same with ALC286/ALC288 */ + val = alc_read_coef_idx(codec, 0x50); + if (val & (1 << 12)) { + alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020); + alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400); + msleep(300); + } else { + alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010); + alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400); + msleep(300); + } + break; case 0x10ec0286: case 0x10ec0288: alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400); @@ -4264,7 +4298,11 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) case 0x10ec0225: case 0x10ec0295: case 0x10ec0299: - alc_process_coef_fw(codec, coef0225); + val = alc_read_coef_idx(codec, 0x45); + if (val & (1 << 9)) + alc_process_coef_fw(codec, coef0225_2); + else + alc_process_coef_fw(codec, coef0225_1); break; case 0x10ec0867: alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0); @@ -4320,9 +4358,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) }; static struct coef_fw coef0225[] = { UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10), - UPDATE_COEF(0x49, 1<<8, 1<<8), - UPDATE_COEF(0x4a, 7<<6, 7<<6), - UPDATE_COEF(0x4a, 3<<4, 3<<4), + UPDATE_COEF(0x63, 3<<14, 2<<14), {} }; @@ -4344,7 +4380,9 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) break; case 0x10ec0298: alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */ - /* ALC298 jack type setting is the same with ALC286/ALC288 */ + alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400); + msleep(300); + break; case 0x10ec0286: case 0x10ec0288: alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400); @@ -4384,6 +4422,14 @@ static void alc_determine_headset_type(struct hda_codec *codec) UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */ {} }; + static struct coef_fw coef0298[] = { + UPDATE_COEF(0x50, 0x2000, 0x2000), + UPDATE_COEF(0x56, 0x0006, 0x0006), + UPDATE_COEF(0x66, 0x0008, 0), + UPDATE_COEF(0x67, 0x2000, 0), + UPDATE_COEF(0x19, 0x1300, 0x1300), + {} + }; static struct coef_fw coef0293[] = { UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */ WRITE_COEF(0x45, 0xD429), /* Set to ctia type */ @@ -4396,11 +4442,6 @@ static void alc_determine_headset_type(struct hda_codec *codec) WRITE_COEF(0xc3, 0x0c00), {} }; - static struct coef_fw coef0225[] = { - UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10), - UPDATE_COEF(0x49, 1<<8, 1<<8), - {} - }; static struct coef_fw coef0274[] = { UPDATE_COEF(0x4a, 0x0010, 0), UPDATE_COEF(0x4a, 0x8000, 0), @@ -4433,8 +4474,34 @@ static void alc_determine_headset_type(struct hda_codec *codec) is_ctia = (val & 0x0070) == 0x0070; break; case 0x10ec0298: - alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020); /* Headset output enable */ - /* ALC298 check jack type is the same with ALC286/ALC288 */ + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + msleep(100); + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + msleep(200); + + val = alc_read_coef_idx(codec, 0x50); + if (val & (1 << 12)) { + alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020); + alc_process_coef_fw(codec, coef0288); + msleep(350); + val = alc_read_coef_idx(codec, 0x50); + is_ctia = (val & 0x0070) == 0x0070; + } else { + alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010); + alc_process_coef_fw(codec, coef0288); + msleep(350); + val = alc_read_coef_idx(codec, 0x50); + is_ctia = (val & 0x0070) == 0x0070; + } + alc_process_coef_fw(codec, coef0298); + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); + msleep(75); + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + break; case 0x10ec0286: case 0x10ec0288: alc_process_coef_fw(codec, coef0288); @@ -4463,10 +4530,25 @@ static void alc_determine_headset_type(struct hda_codec *codec) case 0x10ec0225: case 0x10ec0295: case 0x10ec0299: - alc_process_coef_fw(codec, coef0225); - msleep(800); - val = alc_read_coef_idx(codec, 0x46); - is_ctia = (val & 0x00f0) == 0x00f0; + alc_process_coef_fw(codec, alc225_pre_hsmode); + alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000); + val = alc_read_coef_idx(codec, 0x45); + if (val & (1 << 9)) { + alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10); + alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8); + msleep(800); + val = alc_read_coef_idx(codec, 0x46); + is_ctia = (val & 0x00f0) == 0x00f0; + } else { + alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10); + alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8); + msleep(800); + val = alc_read_coef_idx(codec, 0x46); + is_ctia = (val & 0x00f0) == 0x00f0; + } + alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6); + alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4); + alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); break; case 0x10ec0867: is_ctia = true; @@ -6565,7 +6647,6 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, ALC225_STANDARD_PINS, {0x12, 0xb7a60130}, - {0x13, 0xb8a61140}, {0x17, 0x90170110}), {} }; @@ -6724,6 +6805,7 @@ static int patch_alc269(struct hda_codec *codec) case 0x10ec0225: case 0x10ec0295: spec->codec_variant = ALC269_TYPE_ALC225; + spec->gen.mixer_nid = 0; /* no loopback on ALC225 ALC295 */ break; case 0x10ec0299: spec->codec_variant = ALC269_TYPE_ALC225; diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index a78802920c3c..5710fd440bcd 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -36,7 +36,7 @@ #define CDC_D_CDC_DIG_CLK_CTL (0xf04A) #define DIG_CLK_CTL_RXD1_CLK_EN BIT(0) #define DIG_CLK_CTL_RXD2_CLK_EN BIT(1) -#define DIG_CLK_CTL_RXD3_CLK_EN BIT(3) +#define DIG_CLK_CTL_RXD3_CLK_EN BIT(2) #define DIG_CLK_CTL_TXD_CLK_EN BIT(4) #define DIG_CLK_CTL_NCP_CLK_EN_MASK BIT(6) #define DIG_CLK_CTL_NCP_CLK_EN BIT(6) diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index a33202affeb1..fa550e3c1332 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -466,7 +466,7 @@ static const struct reg_default rt5663_reg[] = { { 0x0006, 0x1000 }, { 0x000a, 0x0000 }, { 0x0010, 0x000f }, - { 0x0015, 0x42c1 }, + { 0x0015, 0x42f1 }, { 0x0016, 0x0000 }, { 0x0018, 0x000b }, { 0x0019, 0xafaf }, @@ -509,7 +509,7 @@ static const struct reg_default rt5663_reg[] = { { 0x008a, 0x0000 }, { 0x008b, 0x0000 }, { 0x008c, 0x0003 }, - { 0x008e, 0x0004 }, + { 0x008e, 0x0008 }, { 0x008f, 0x1000 }, { 0x0090, 0x0646 }, { 0x0091, 0x0e3e }, @@ -520,7 +520,7 @@ static const struct reg_default rt5663_reg[] = { { 0x0098, 0x0000 }, { 0x009a, 0x0000 }, { 0x009f, 0x0000 }, - { 0x00ae, 0x2000 }, + { 0x00ae, 0x6000 }, { 0x00af, 0x0000 }, { 0x00b6, 0x0000 }, { 0x00b7, 0x0000 }, @@ -538,7 +538,7 @@ static const struct reg_default rt5663_reg[] = { { 0x00d9, 0x08f9 }, { 0x00db, 0x0008 }, { 0x00dc, 0x00c0 }, - { 0x00dd, 0x6724 }, + { 0x00dd, 0x6729 }, { 0x00de, 0x3131 }, { 0x00df, 0x0008 }, { 0x00e0, 0x4000 }, @@ -578,7 +578,7 @@ static const struct reg_default rt5663_reg[] = { { 0x0116, 0x0000 }, { 0x0117, 0x0f00 }, { 0x0118, 0x0006 }, - { 0x0125, 0x2224 }, + { 0x0125, 0x2424 }, { 0x0126, 0x5550 }, { 0x0127, 0x0400 }, { 0x0128, 0x7711 }, @@ -596,8 +596,8 @@ static const struct reg_default rt5663_reg[] = { { 0x0145, 0x0002 }, { 0x0146, 0x0000 }, { 0x0160, 0x0e80 }, - { 0x0161, 0x0020 }, - { 0x0162, 0x0080 }, + { 0x0161, 0x0080 }, + { 0x0162, 0x0200 }, { 0x0163, 0x0800 }, { 0x0164, 0x0000 }, { 0x0165, 0x0000 }, @@ -676,8 +676,8 @@ static const struct reg_default rt5663_reg[] = { { 0x0251, 0x0000 }, { 0x0252, 0x028a }, { 0x02fa, 0x0000 }, - { 0x02fb, 0x0000 }, - { 0x02fc, 0x0000 }, + { 0x02fb, 0x00a4 }, + { 0x02fc, 0x0300 }, { 0x0300, 0x0000 }, { 0x03d0, 0x0000 }, { 0x03d1, 0x0000 }, diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index 370ed54d1e15..e597c893536d 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c @@ -4368,12 +4368,12 @@ static int rt5665_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) switch (dai->id) { case RT5665_AIF2_1: case RT5665_AIF2_2: - snd_soc_update_bits(codec, RT5665_ADDA_CLK_1, + snd_soc_update_bits(codec, RT5665_ADDA_CLK_2, RT5665_I2S_BCLK_MS2_MASK, RT5665_I2S_BCLK_MS2_64); break; case RT5665_AIF3: - snd_soc_update_bits(codec, RT5665_ADDA_CLK_1, + snd_soc_update_bits(codec, RT5665_ADDA_CLK_2, RT5665_I2S_BCLK_MS3_MASK, RT5665_I2S_BCLK_MS3_64); break; diff --git a/sound/soc/codecs/rt5665.h b/sound/soc/codecs/rt5665.h index 1db5c6a62a8e..d95249c4c47b 100644 --- a/sound/soc/codecs/rt5665.h +++ b/sound/soc/codecs/rt5665.h @@ -1692,8 +1692,8 @@ #define RT5665_GP6_PIN_MASK (0x3 << 5) #define RT5665_GP6_PIN_SFT 5 #define RT5665_GP6_PIN_GPIO6 (0x0 << 5) -#define RT5665_GP6_PIN_BCLK3 (0x0 << 5) -#define RT5665_GP6_PIN_PDM_SCL (0x1 << 5) +#define RT5665_GP6_PIN_BCLK3 (0x1 << 5) +#define RT5665_GP6_PIN_PDM_SCL (0x2 << 5) #define RT5665_GP7_PIN_MASK (0x3 << 3) #define RT5665_GP7_PIN_SFT 3 #define RT5665_GP7_PIN_GPIO7 (0x0 << 3) diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 8f6814c1eb6b..80f6d1da7095 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -409,7 +409,7 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol, static int avc_get_threshold(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int db, i; u16 reg = snd_soc_read(codec, SGTL5000_DAP_AVC_THRESHOLD); @@ -442,7 +442,7 @@ static int avc_get_threshold(struct snd_kcontrol *kcontrol, static int avc_put_threshold(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int db; u16 reg; diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index b95132e2f9dc..06790615e04e 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -527,6 +527,10 @@ static int imx_ssi_probe(struct platform_device *pdev) } ssi->irq = platform_get_irq(pdev, 0); + if (ssi->irq < 0) { + dev_err(&pdev->dev, "Failed to get IRQ: %d\n", ssi->irq); + return ssi->irq; + } ssi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ssi->clk)) { diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 105ec3a6e30d..de2550c7a96b 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -224,9 +224,11 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { ret = asoc_graph_card_dai_link_of(it.node, priv, idx++); - of_node_put(it.node); - if (ret < 0) + if (ret < 0) { + of_node_put(it.node); + return ret; + } } return asoc_simple_card_parse_card_name(card, NULL); @@ -239,10 +241,8 @@ static int asoc_graph_get_dais_count(struct device *dev) int count = 0; int rc; - of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { + of_for_each_phandle(&it, rc, node, "dais", NULL, 0) count++; - of_node_put(it.node); - } return count; } diff --git a/sound/soc/generic/audio-graph-scu-card.c b/sound/soc/generic/audio-graph-scu-card.c index dcd2df37bc3b..758ac06f3a99 100644 --- a/sound/soc/generic/audio-graph-scu-card.c +++ b/sound/soc/generic/audio-graph-scu-card.c @@ -215,7 +215,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) codec_ep = of_graph_get_remote_endpoint(cpu_ep); rcpu_ep = of_graph_get_remote_endpoint(codec_ep); - of_node_put(cpu_port); of_node_put(cpu_ep); of_node_put(codec_ep); of_node_put(rcpu_ep); @@ -232,8 +231,10 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, NULL, &daifmt); - if (ret < 0) + if (ret < 0) { + of_node_put(cpu_port); goto parse_of_err; + } } dai_idx = 0; @@ -250,7 +251,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) codec_ep = of_graph_get_remote_endpoint(cpu_ep); codec_port = of_graph_get_port_parent(codec_ep); - of_node_put(cpu_port); of_node_put(cpu_ep); of_node_put(codec_ep); of_node_put(codec_port); @@ -266,13 +266,17 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) /* Back-End (= Codec) */ ret = asoc_graph_card_dai_link_of(codec_ep, priv, daifmt, dai_idx++, 0); - if (ret < 0) + if (ret < 0) { + of_node_put(cpu_port); goto parse_of_err; + } } else { /* Front-End (= CPU) */ ret = asoc_graph_card_dai_link_of(cpu_ep, priv, daifmt, dai_idx++, 1); - if (ret < 0) + if (ret < 0) { + of_node_put(cpu_port); goto parse_of_err; + } } } } @@ -306,7 +310,6 @@ static int asoc_graph_get_dais_count(struct device *dev) codec_ep = of_graph_get_remote_endpoint(cpu_ep); codec_port = of_graph_get_port_parent(codec_ep); - of_node_put(cpu_port); of_node_put(cpu_ep); of_node_put(codec_ep); of_node_put(codec_port); diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 26d64fa40c9c..7d7ab4aee42e 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -263,6 +263,9 @@ static int asoc_simple_card_get_dai_id(struct device_node *ep) id = i; i++; } + + of_node_put(node); + if (id < 0) return -ENODEV; @@ -282,11 +285,6 @@ int asoc_simple_card_parse_graph_dai(struct device_node *ep, if (!dai_name) return 0; - /* - * of_graph_get_port_parent() will call - * of_node_put(). So, call of_node_get() here - */ - of_node_get(ep); node = of_graph_get_port_parent(ep); /* Get dai->name */ diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 3fe4a0807095..cfd89ca6a18d 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c @@ -319,7 +319,9 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, int ret; /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ - rt5663_sel_asrc_clk_src(codec_dai->codec, RT5663_DA_STEREO_FILTER, 1); + rt5663_sel_asrc_clk_src(codec_dai->codec, + RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, + RT5663_CLK_SEL_I2S1_ASRC); ret = snd_soc_dai_set_sysclk(codec_dai, RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); @@ -349,19 +351,10 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, return ret; } - ret = snd_soc_dai_set_pll(codec_dai, 0, - RT5514_PLL1_S_BCLK, RT5514_AIF1_BCLK_FREQ, - RT5514_AIF1_SYSCLK_FREQ); - if (ret < 0) { - dev_err(rtd->dev, "set bclk err: %d\n", ret); - return ret; - } - ret = snd_soc_dai_set_sysclk(codec_dai, - RT5514_SCLK_S_PLL1, RT5514_AIF1_SYSCLK_FREQ, - SND_SOC_CLOCK_IN); + RT5514_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); if (ret < 0) { - dev_err(rtd->dev, "set sclk err: %d\n", ret); + dev_err(rtd->dev, "set sysclk err: %d\n", ret); return ret; } } diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index eca85827dbd2..fb2f1f603f3c 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -540,6 +540,14 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, cpr_mconfig->gtw_cfg.dma_buffer_size = mconfig->dma_buffer_size * dma_io_buf; + /* fallback to 2ms default value */ + if (!cpr_mconfig->gtw_cfg.dma_buffer_size) { + if (mconfig->hw_conn_type == SKL_CONN_SOURCE) + cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->obs; + else + cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->ibs; + } + cpr_mconfig->cpr_feature_mask = 0; cpr_mconfig->gtw_cfg.config_length = 0; diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 334917ee41cf..9e3f8c04dd32 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -941,6 +941,7 @@ static struct sst_acpi_mach sst_bxtp_devdata[] = { .machine_quirk = sst_acpi_codec_list, .quirk_data = &bxt_codecs, }, + {} }; static struct sst_acpi_mach sst_kbl_devdata[] = { @@ -991,6 +992,7 @@ static struct sst_acpi_mach sst_glk_devdata[] = { .drv_name = "glk_alc298s_i2s", .fw_filename = "intel/dsp_fw_glk.bin", }, + {} }; /* PCI IDs */ diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 960744e46edc..484ab3c2ad67 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -1,6 +1,7 @@ config SND_PXA2XX_SOC tristate "SoC Audio for the Intel PXA2xx chip" depends on ARCH_PXA || COMPILE_TEST + depends on HAS_DMA select SND_PXA2XX_LIB help Say Y or M if you want to add support for codecs attached to diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c index 0c0b00e40646..0834319ead42 100644 --- a/sound/soc/samsung/odroid.c +++ b/sound/soc/samsung/odroid.c @@ -42,17 +42,17 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream, switch (params_rate(params)) { case 32000: case 64000: - pll_freq = 131072000U; + pll_freq = 131072006U; break; case 44100: case 88200: case 176400: - pll_freq = 180633600U; + pll_freq = 180633609U; break; case 48000: case 96000: case 192000: - pll_freq = 196608000U; + pll_freq = 196608001U; break; default: return -EINVAL; diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index 84c51037a7d0..624aaf569fef 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c @@ -315,6 +315,8 @@ static const struct snd_soc_component_driver sh4_hac_component = { static int hac_soc_platform_probe(struct platform_device *pdev) { + int ret; + ret = snd_soc_set_ac97_ops(&hac_ac97_ops); if (ret != 0) return ret; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 921622a01944..13c875e2392a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3171,8 +3171,6 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, component->remove = component->driver->remove; component->suspend = component->driver->suspend; component->resume = component->driver->resume; - component->pcm_new = component->driver->pcm_new; - component->pcm_free = component->driver->pcm_free; dapm = &component->dapm; dapm->dev = dev; @@ -3360,25 +3358,6 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component) platform->driver->remove(platform); } -static int snd_soc_platform_drv_pcm_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_platform *platform = rtd->platform; - - if (platform->driver->pcm_new) - return platform->driver->pcm_new(rtd); - else - return 0; -} - -static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm) -{ - struct snd_soc_pcm_runtime *rtd = pcm->private_data; - struct snd_soc_platform *platform = rtd->platform; - - if (platform->driver->pcm_free) - platform->driver->pcm_free(pcm); -} - /** * snd_soc_add_platform - Add a platform to the ASoC core * @dev: The parent device for the platform @@ -3402,10 +3381,6 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, platform->component.probe = snd_soc_platform_drv_probe; if (platform_drv->remove) platform->component.remove = snd_soc_platform_drv_remove; - if (platform_drv->pcm_new) - platform->component.pcm_new = snd_soc_platform_drv_pcm_new; - if (platform_drv->pcm_free) - platform->component.pcm_free = snd_soc_platform_drv_pcm_free; #ifdef CONFIG_DEBUG_FS platform->component.debugfs_prefix = "platform"; @@ -4113,6 +4088,8 @@ int snd_soc_get_dai_id(struct device_node *ep) } mutex_unlock(&client_mutex); + of_node_put(node); + return ret; } EXPORT_SYMBOL_GPL(snd_soc_get_dai_id); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index dcc5ece08668..7d3859e1a7b9 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -181,6 +181,10 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n", be->dai_link->name, event, dir); + if ((event == SND_SOC_DAPM_STREAM_STOP) && + (be->dpcm[dir].users >= 1)) + continue; + snd_soc_dapm_stream_event(be, dir, event); } @@ -2628,25 +2632,12 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream) return ret; } -static void soc_pcm_free(struct snd_pcm *pcm) -{ - struct snd_soc_pcm_runtime *rtd = pcm->private_data; - struct snd_soc_component *component; - - list_for_each_entry(component, &rtd->card->component_dev_list, - card_list) { - if (component->pcm_free) - component->pcm_free(pcm); - } -} - /* create a new pcm */ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) { struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_component *component; struct snd_pcm *pcm; char new_name[64]; int ret = 0, playback = 0, capture = 0; @@ -2756,18 +2747,17 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) if (capture) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops); - list_for_each_entry(component, &rtd->card->component_dev_list, card_list) { - if (component->pcm_new) { - ret = component->pcm_new(rtd); - if (ret < 0) { - dev_err(component->dev, - "ASoC: pcm constructor failed: %d\n", - ret); - return ret; - } + if (platform->driver->pcm_new) { + ret = platform->driver->pcm_new(rtd); + if (ret < 0) { + dev_err(platform->dev, + "ASoC: pcm constructor failed: %d\n", + ret); + return ret; } } - pcm->private_free = soc_pcm_free; + + pcm->private_free = platform->driver->pcm_free; out: dev_info(rtd->card->dev, "%s <-> %s mapping ok\n", (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name, diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index b50f68a439ce..ba9fc099cf67 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c @@ -33,6 +33,7 @@ static struct snd_soc_dai_link mop500_dai_links[] = { .stream_name = "ab8500_0", .cpu_dai_name = "ux500-msp-i2s.1", .codec_dai_name = "ab8500-codec-dai.0", + .platform_name = "ux500-msp-i2s.1", .codec_name = "ab8500-codec.0", .init = mop500_ab8500_machine_init, .ops = mop500_ab8500_ops, @@ -42,6 +43,7 @@ static struct snd_soc_dai_link mop500_dai_links[] = { .stream_name = "ab8500_1", .cpu_dai_name = "ux500-msp-i2s.3", .codec_dai_name = "ab8500-codec-dai.1", + .platform_name = "ux500-msp-i2s.3", .codec_name = "ab8500-codec.0", .init = NULL, .ops = mop500_ab8500_ops, @@ -85,6 +87,8 @@ static int mop500_of_probe(struct platform_device *pdev, for (i = 0; i < 2; i++) { mop500_dai_links[i].cpu_of_node = msp_np[i]; mop500_dai_links[i].cpu_dai_name = NULL; + mop500_dai_links[i].platform_of_node = msp_np[i]; + mop500_dai_links[i].platform_name = NULL; mop500_dai_links[i].codec_of_node = codec_np; mop500_dai_links[i].codec_name = NULL; } diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 082736c539bc..e630813c5008 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -542,6 +542,8 @@ int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, if (size < sizeof(scale)) return -ENOMEM; + if (cval->min_mute) + scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE; scale[2] = cval->dBmin; scale[3] = cval->dBmax; if (copy_to_user(_tlv, scale, sizeof(scale))) diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index 3417ef347e40..2b4b067646ab 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h @@ -64,6 +64,7 @@ struct usb_mixer_elem_info { int cached; int cache_val[MAX_CHANNELS]; u8 initialized; + u8 min_mute; void *private_data; }; diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index e3d1dec48ee4..e1e7ce9ab217 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -1878,6 +1878,12 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, if (unitid == 7 && cval->control == UAC_FU_VOLUME) snd_dragonfly_quirk_db_scale(mixer, cval, kctl); break; + /* lowest playback value is muted on C-Media devices */ + case USB_ID(0x0d8c, 0x000c): + case USB_ID(0x0d8c, 0x0014): + if (strstr(kctl->id.name, "Playback")) + cval->min_mute = 1; + break; } } diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index d7b0b0a3a2db..6a03f9697039 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1142,6 +1142,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */ case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */ case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ + case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */ case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */ case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */ case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */ @@ -1374,6 +1375,10 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, } } break; + case USB_ID(0x16d0, 0x0a23): + if (fp->altsetting == 2) + return SNDRV_PCM_FMTBIT_DSD_U32_BE; + break; default: break; |