diff options
Diffstat (limited to 'sound')
30 files changed, 320 insertions, 110 deletions
diff --git a/sound/core/info.c b/sound/core/info.c index b5158b5673f1..79dee33b5035 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -325,10 +325,15 @@ static ssize_t snd_info_text_entry_write(struct file *file, size_t next; int err = 0; + if (!entry->c.text.write) + return -EIO; pos = *offset; if (!valid_pos(pos, count)) return -EIO; next = pos + count; + /* don't handle too large text inputs */ + if (next > 16 * 1024) + return -EIO; mutex_lock(&entry->access); buf = data->wbuffer; if (!buf) { @@ -366,7 +371,9 @@ static int snd_info_seq_show(struct seq_file *seq, void *p) struct snd_info_private_data *data = seq->private; struct snd_info_entry *entry = data->entry; - if (entry->c.text.read) { + if (!entry->c.text.read) { + return -EIO; + } else { data->rbuffer->buffer = (char *)seq; /* XXX hack! */ entry->c.text.read(entry, data->rbuffer); } diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index b73133885384..2530669e2f94 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1901,8 +1901,8 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream) snd_timer_interrupt(substream->timer, 1); #endif _end: - snd_pcm_stream_unlock_irqrestore(substream, flags); kill_fasync(&runtime->fasync, SIGIO, POLL_IN); + snd_pcm_stream_unlock_irqrestore(substream, flags); } EXPORT_SYMBOL(snd_pcm_period_elapsed); diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 36470af7eda7..92b819e4f729 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -1408,6 +1408,7 @@ snd_ali_playback_pointer(struct snd_pcm_substream *substream) spin_unlock(&codec->reg_lock); dev_dbg(codec->card->dev, "playback pointer returned cso=%xh.\n", cso); + cso %= runtime->buffer_size; return cso; } @@ -1428,6 +1429,7 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream) cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2)); spin_unlock(&codec->reg_lock); + cso %= runtime->buffer_size; return cso; } diff --git a/sound/pci/hda/dell_wmi_helper.c b/sound/pci/hda/dell_wmi_helper.c index 9c22f95838ef..19d41da79f93 100644 --- a/sound/pci/hda/dell_wmi_helper.c +++ b/sound/pci/hda/dell_wmi_helper.c @@ -49,7 +49,7 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec, removefunc = true; if (dell_led_set_func(DELL_LED_MICMUTE, false) >= 0) { dell_led_value = 0; - if (spec->gen.num_adc_nids > 1) + if (spec->gen.num_adc_nids > 1 && !spec->gen.dyn_adc_switch) codec_dbg(codec, "Skipping micmute LED control due to several ADCs"); else { dell_old_cap_hook = spec->gen.cap_sync_hook; diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 22dbfa563919..5baf8b56b6e7 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -956,7 +956,7 @@ irqreturn_t azx_interrupt(int irq, void *dev_id) status = azx_readb(chip, RIRBSTS); if (status & RIRB_INT_MASK) { if (status & RIRB_INT_RESPONSE) { - if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY) + if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) udelay(80); snd_hdac_bus_update_rirb(bus); } @@ -1055,11 +1055,6 @@ int azx_bus_init(struct azx *chip, const char *model, if (chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR) bus->core.corbrp_self_clear = true; - if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) { - dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n"); - bus->needs_damn_long_delay = 1; - } - if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) bus->core.align_bdle_4k = true; diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 7b635d68cfe1..b17539537b2e 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -32,8 +32,8 @@ #define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */ #define AZX_DCAPS_SNOOP_MASK (3 << 10) /* snoop type mask */ #define AZX_DCAPS_SNOOP_OFF (1 << 12) /* snoop default off */ -#define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */ -#define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */ +/* 13 unused */ +/* 14 unused */ #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ #define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ #define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d4671973d889..ad4a1e9a3ae1 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -334,8 +334,7 @@ enum { /* quirks for Nvidia */ #define AZX_DCAPS_PRESET_NVIDIA \ - (AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \ - AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR |\ + (AZX_DCAPS_NO_MSI | AZX_DCAPS_CORBRP_SELF_CLEAR |\ AZX_DCAPS_SNOOP_TYPE(NVIDIA)) #define AZX_DCAPS_PRESET_CTHDA \ @@ -1637,6 +1636,11 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, return err; } + if (chip->driver_type == AZX_DRIVER_NVIDIA) { + dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n"); + chip->bus.needs_damn_long_delay = 1; + } + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err < 0) { dev_err(card->dev, "Error creating device [card]!\n"); @@ -1720,6 +1724,10 @@ static int azx_first_init(struct azx *chip) } } + /* NVidia hardware normally only supports up to 40 bits of DMA */ + if (chip->pci->vendor == PCI_VENDOR_ID_NVIDIA) + dma_bits = 40; + /* disable 64bit DMA address on some devices */ if (chip->driver_caps & AZX_DCAPS_NO_64BIT) { dev_dbg(card->dev, "Disabling 64bit DMA\n"); @@ -2406,14 +2414,12 @@ static const struct pci_device_id azx_ids[] = { .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff, .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | - AZX_DCAPS_NO_64BIT | - AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, + AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB }, #else /* this entry seems still valid -- i.e. without emu20kx chip */ { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | - AZX_DCAPS_NO_64BIT | - AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, + AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB }, #endif /* CM8888 */ { PCI_DEVICE(0x13f6, 0x5011), diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c index 58c0aad37284..17fd81736d3d 100644 --- a/sound/pci/hda/hda_tegra.c +++ b/sound/pci/hda/hda_tegra.c @@ -464,6 +464,8 @@ static int hda_tegra_create(struct snd_card *card, if (err < 0) return err; + chip->bus.needs_damn_long_delay = 1; + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err < 0) { dev_err(card->dev, "Error creating device\n"); @@ -481,8 +483,7 @@ MODULE_DEVICE_TABLE(of, hda_tegra_match); static int hda_tegra_probe(struct platform_device *pdev) { - const unsigned int driver_flags = AZX_DCAPS_RIRB_DELAY | - AZX_DCAPS_CORBRP_SELF_CLEAR; + const unsigned int driver_flags = AZX_DCAPS_CORBRP_SELF_CLEAR; struct snd_card *card; struct azx *chip; struct hda_tegra *hda; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 600af5878e75..36cd715986bc 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -261,6 +261,7 @@ enum { CXT_FIXUP_HP_530, CXT_FIXUP_CAP_MIX_AMP_5047, CXT_FIXUP_MUTE_LED_EAPD, + CXT_FIXUP_HP_SPECTRE, }; /* for hda_fixup_thinkpad_acpi() */ @@ -765,6 +766,14 @@ static const struct hda_fixup cxt_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = cxt_fixup_mute_led_eapd, }, + [CXT_FIXUP_HP_SPECTRE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + /* enable NID 0x1d for the speaker on top */ + { 0x1d, 0x91170111 }, + { } + } + }, }; static const struct snd_pci_quirk cxt5045_fixups[] = { @@ -814,6 +823,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC), SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC), + SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), 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_realtek.c b/sound/pci/hda/patch_realtek.c index eaee626ab185..f0986cac82f1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5790,6 +5790,11 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {0x14, 0x90170110}, \ {0x15, 0x0221401f} +#define ALC295_STANDARD_PINS \ + {0x12, 0xb7a60130}, \ + {0x14, 0x90170110}, \ + {0x21, 0x04211020} + #define ALC298_STANDARD_PINS \ {0x12, 0x90a60130}, \ {0x21, 0x03211020} @@ -5830,11 +5835,23 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x14, 0x90170120}, {0x21, 0x02211030}), SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x14, 0x90170110}, + {0x1b, 0x02011020}, + {0x21, 0x0221101f}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x14, 0x90170110}, + {0x1b, 0x01011020}, + {0x21, 0x0221101f}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, {0x14, 0x90170130}, {0x1b, 0x01014020}, {0x21, 0x0221103f}), SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, {0x14, 0x90170130}, + {0x1b, 0x01011020}, + {0x21, 0x0221103f}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x14, 0x90170130}, {0x1b, 0x02011020}, {0x21, 0x0221103f}), SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, @@ -5895,6 +5912,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x14, 0x90170120}, {0x21, 0x02211030}), SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0xb7a60130}, + {0x14, 0x90170110}, + {0x21, 0x02211020}), + SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ALC256_STANDARD_PINS), SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, {0x12, 0x90a60130}, @@ -6005,6 +6026,14 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, ALC292_STANDARD_PINS, {0x13, 0x90a60140}), + SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC295_STANDARD_PINS, + {0x17, 0x21014020}, + {0x18, 0x21a19030}), + SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC295_STANDARD_PINS, + {0x17, 0x21014040}, + {0x18, 0x21a19050}), SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, ALC298_STANDARD_PINS, {0x17, 0x90170110}), diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c index 0a4ad5feb82e..12826ac0381f 100644 --- a/sound/pci/hda/thinkpad_helper.c +++ b/sound/pci/hda/thinkpad_helper.c @@ -75,7 +75,7 @@ static void hda_fixup_thinkpad_acpi(struct hda_codec *codec, removefunc = false; } if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) { - if (spec->num_adc_nids > 1) + if (spec->num_adc_nids > 1 && !spec->dyn_adc_switch) codec_dbg(codec, "Skipping micmute LED control due to several ADCs"); else { diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index e07807d96b68..3670086b9227 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -148,11 +148,11 @@ SND_SOC_DAPM_OUTPUT("AOUTR"), }; static const struct snd_soc_dapm_route cs4270_dapm_routes[] = { - { "Capture", NULL, "AINA" }, - { "Capture", NULL, "AINB" }, + { "Capture", NULL, "AINL" }, + { "Capture", NULL, "AINR" }, - { "AOUTA", NULL, "Playback" }, - { "AOUTB", NULL, "Playback" }, + { "AOUTL", NULL, "Playback" }, + { "AOUTR", NULL, "Playback" }, }; /** diff --git a/sound/soc/codecs/msm_hdmi_codec_rx.c b/sound/soc/codecs/msm_hdmi_codec_rx.c index 8ae789a90f33..e75e1939df33 100644 --- a/sound/soc/codecs/msm_hdmi_codec_rx.c +++ b/sound/soc/codecs/msm_hdmi_codec_rx.c @@ -20,10 +20,17 @@ #include <linux/msm_ext_display.h> #define MSM_EXT_DISP_PCM_RATES SNDRV_PCM_RATE_48000 +#define AUD_EXT_DISP_ACK_DISCONNECT (AUDIO_ACK_CONNECT ^ AUDIO_ACK_CONNECT) +#define AUD_EXT_DISP_ACK_CONNECT (AUDIO_ACK_CONNECT) +#define AUD_EXT_DISP_ACK_ENABLE (AUDIO_ACK_SET_ENABLE | AUDIO_ACK_ENABLE) static const char *const ext_disp_audio_type_text[] = {"None", "HDMI", "DP"}; +static const char *const ext_disp_audio_ack_text[] = {"Disconnect", "Connect", + "Ack_Enable"}; static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_audio_type, ext_disp_audio_type_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_audio_ack_state, + ext_disp_audio_ack_text); struct msm_ext_disp_audio_codec_rx_data { struct platform_device *ext_disp_core_pdev; @@ -176,6 +183,55 @@ done: return rc; } +static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_ext_disp_audio_codec_rx_data *codec_data; + u32 ack_state = 0; + int rc; + + codec_data = snd_soc_codec_get_drvdata(codec); + if (!codec_data || + !codec_data->ext_disp_ops.acknowledge) { + dev_err(codec->dev, + "%s: codec_data or ops acknowledge() is NULL\n", + __func__); + rc = -EINVAL; + goto done; + } + + switch (ucontrol->value.enumerated.item[0]) { + case 0: + ack_state = AUD_EXT_DISP_ACK_DISCONNECT; + break; + case 1: + ack_state = AUD_EXT_DISP_ACK_CONNECT; + break; + case 2: + ack_state = AUD_EXT_DISP_ACK_ENABLE; + break; + default: + rc = -EINVAL; + dev_err(codec->dev, + "%s: invalid value %d for mixer ctl\n", + __func__, ucontrol->value.enumerated.item[0]); + goto done; + } + dev_dbg(codec->dev, "%s: control %d, ack set value 0x%x\n", + __func__, ucontrol->value.enumerated.item[0], ack_state); + + rc = codec_data->ext_disp_ops.acknowledge( + codec_data->ext_disp_core_pdev, ack_state); + if (rc < 0) { + dev_err(codec->dev, "%s: error from acknowledge(), err:%d\n", + __func__, rc); + } + +done: + return rc; +} + static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { { .access = SNDRV_CTL_ELEM_ACCESS_READ | @@ -195,6 +251,8 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { }, SOC_ENUM_EXT("External Display Type", ext_disp_audio_type, msm_ext_disp_audio_type_get, NULL), + SOC_ENUM_EXT("External Display Audio Ack", ext_disp_audio_ack_state, + NULL, msm_ext_disp_audio_ack_set), }; static int msm_ext_disp_audio_codec_rx_dai_startup( diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index 6addbde34545..676c3b0335ef 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -1094,7 +1094,6 @@ static int wsa881x_swr_startup(struct swr_device *swr_dev) { int ret = 0; u8 devnum = 0; - u8 retry = WSA881X_NUM_RETRY; struct wsa881x_priv *wsa881x; wsa881x = swr_get_dev_data(swr_dev); @@ -1109,16 +1108,12 @@ static int wsa881x_swr_startup(struct swr_device *swr_dev) * as per HW requirement. */ usleep_range(5000, 5010); - while (swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum) && - retry--) { - /* Retry after 1 msec delay */ - usleep_range(1000, 1100); - } - if (retry == 0) { - dev_err(&swr_dev->dev, + ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum); + if (ret) { + dev_dbg(&swr_dev->dev, "%s get devnum %d for dev addr %lx failed\n", __func__, devnum, swr_dev->addr); - return -EINVAL; + goto err; } swr_dev->dev_num = devnum; diff --git a/sound/soc/intel/atom/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c index adb32fefd693..b1e6b8f34a6a 100644 --- a/sound/soc/intel/atom/sst/sst_pvt.c +++ b/sound/soc/intel/atom/sst/sst_pvt.c @@ -279,17 +279,15 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst, if (response) { ret = sst_wait_timeout(sst, block); - if (ret < 0) { + if (ret < 0) goto out; - } else if(block->data) { - if (!data) - goto out; - *data = kzalloc(block->size, GFP_KERNEL); - if (!(*data)) { + + if (data && block->data) { + *data = kmemdup(block->data, block->size, GFP_KERNEL); + if (!*data) { ret = -ENOMEM; goto out; - } else - memcpy(data, (void *) block->data, block->size); + } } } out: diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index caa69c4598a6..b4844f78266f 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -464,8 +464,10 @@ static int skl_probe(struct pci_dev *pci, skl->nhlt = skl_nhlt_init(bus->dev); - if (skl->nhlt == NULL) + if (skl->nhlt == NULL) { + err = -ENODEV; goto out_free; + } pci_set_drvdata(skl->pci, ebus); diff --git a/sound/soc/msm/msm-cpe-lsm.c b/sound/soc/msm/msm-cpe-lsm.c index b2008d6da2a1..48f8e22e7faa 100644 --- a/sound/soc/msm/msm-cpe-lsm.c +++ b/sound/soc/msm/msm-cpe-lsm.c @@ -2152,7 +2152,8 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if using topology\n", __func__, "LSM_REG_SND_MODEL_V2"); - return -EINVAL; + err = -EINVAL; + goto done; } if (copy_from_user(&snd_model, (void *)arg, @@ -2285,7 +2286,8 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if using topology\n", __func__, "SNDRV_LSM_SET_PARAMS"); - return -EINVAL; + err = -EINVAL; + goto done; } if (copy_from_user(&det_params, (void *) arg, @@ -2312,14 +2314,16 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if not using topology\n", __func__, "SET_MODULE_PARAMS"); - return -EINVAL; + err = -EINVAL; + goto done; } if (!arg) { dev_err(rtd->dev, "%s: %s: No Param data to set\n", __func__, "SET_MODULE_PARAMS"); - return -EINVAL; + err = -EINVAL; + goto done; } if (copy_from_user(&p_data, arg, @@ -2327,7 +2331,8 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: copy_from_user failed, size = %zd\n", __func__, "p_data", sizeof(p_data)); - return -EFAULT; + err = -EFAULT; + goto done; } if (p_data.num_params > LSM_PARAMS_MAX) { @@ -2335,7 +2340,8 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, "%s: %s: Invalid num_params %d\n", __func__, "SET_MODULE_PARAMS", p_data.num_params); - return -EINVAL; + err = -EINVAL; + goto done; } p_size = p_data.num_params * @@ -2346,12 +2352,15 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, "%s: %s: Invalid size %zd\n", __func__, "SET_MODULE_PARAMS", p_size); - return -EFAULT; + err = -EFAULT; + goto done; } params = kzalloc(p_size, GFP_KERNEL); - if (!params) - return -ENOMEM; + if (!params) { + err = -ENOMEM; + goto done; + } if (copy_from_user(params, p_data.params, p_data.data_size)) { @@ -2359,7 +2368,8 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, "%s: %s: copy_from_user failed, size = %d\n", __func__, "params", p_data.data_size); kfree(params); - return -EFAULT; + err = -EFAULT; + goto done; } err = msm_cpe_lsm_process_params(substream, &p_data, params); @@ -2470,7 +2480,8 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if using topology\n", __func__, "LSM_REG_SND_MODEL_V2_32"); - return -EINVAL; + err = -EINVAL; + goto done; } dev_dbg(rtd->dev, @@ -2690,7 +2701,9 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if using topology\n", __func__, "SNDRV_LSM_SET_PARAMS32"); - return -EINVAL; + + err = -EINVAL; + goto done; } if (copy_from_user(&det_params32, arg, @@ -2734,7 +2747,8 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if not using topology\n", __func__, "SET_MODULE_PARAMS_32"); - return -EINVAL; + err = -EINVAL; + goto done; } if (copy_from_user(&p_data_32, arg, @@ -2743,7 +2757,8 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, "%s: %s: copy_from_user failed, size = %zd\n", __func__, "SET_MODULE_PARAMS_32", sizeof(p_data_32)); - return -EFAULT; + err = -EFAULT; + goto done; } p_data.params = compat_ptr(p_data_32.params); @@ -2755,7 +2770,8 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, "%s: %s: Invalid num_params %d\n", __func__, "SET_MODULE_PARAMS_32", p_data.num_params); - return -EINVAL; + err = -EINVAL; + goto done; } if (p_data.data_size != @@ -2764,21 +2780,25 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, "%s: %s: Invalid size %d\n", __func__, "SET_MODULE_PARAMS_32", p_data.data_size); - return -EINVAL; + err = -EINVAL; + goto done; } p_size = sizeof(struct lsm_params_info_32) * p_data.num_params; params32 = kzalloc(p_size, GFP_KERNEL); - if (!params32) - return -ENOMEM; + if (!params32) { + err = -ENOMEM; + goto done; + } p_size = sizeof(struct lsm_params_info) * p_data.num_params; params = kzalloc(p_size, GFP_KERNEL); if (!params) { kfree(params32); - return -ENOMEM; + err = -ENOMEM; + goto done; } if (copy_from_user(params32, p_data.params, @@ -2788,7 +2808,8 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, __func__, "params32", p_data.data_size); kfree(params32); kfree(params); - return -EFAULT; + err = -EFAULT; + goto done; } p_info_32 = (struct lsm_params_info_32 *) params32; diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c index e7b51c5c2c00..6324e81759de 100644 --- a/sound/soc/msm/msm8998.c +++ b/sound/soc/msm/msm8998.c @@ -534,6 +534,7 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = { .key_code[7] = 0, .linein_th = 5000, .moisture_en = true, + .mbhc_micbias = MIC_BIAS_2, .anc_micbias = MIC_BIAS_2, .enable_anc_mic_detect = false, }; diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c index 46e2f7109b5a..26b7f3f26b26 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c @@ -434,8 +434,10 @@ static struct snd_soc_dai_driver msm_dai_q6_hdmi_hdmi_rx_dai = { .playback = { .stream_name = "HDMI Playback", .aif_name = "HDMI", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_192000, + .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .channels_min = 2, .channels_max = 8, @@ -453,7 +455,9 @@ static struct snd_soc_dai_driver msm_dai_q6_display_port_rx_dai[] = { .playback = { .stream_name = "Display Port Playback", .aif_name = "DISPLAY_PORT", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c index 3fa14d0113ef..ec4380036047 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -86,6 +86,7 @@ struct lsm_priv { atomic_t buf_count; atomic_t read_abort; wait_queue_head_t period_wait; + struct mutex lsm_api_lock; int appl_cnt; int dma_write; }; @@ -954,10 +955,18 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_dbg(rtd->dev, "%s: Get event status\n", __func__); atomic_set(&prtd->event_wait_stop, 0); + + /* + * Release the api lock before wait to allow + * other IOCTLs to be invoked while waiting + * for event + */ + mutex_unlock(&prtd->lsm_api_lock); rc = wait_event_freezable(prtd->event_wait, (cmpxchg(&prtd->event_avail, 1, 0) || (xchg = atomic_cmpxchg(&prtd->event_wait_stop, 1, 0)))); + mutex_lock(&prtd->lsm_api_lock); dev_dbg(rtd->dev, "%s: wait_event_freezable %d event_wait_stop %d\n", __func__, rc, xchg); if (!rc && !xchg) { @@ -1281,6 +1290,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, rtd = substream->private_data; prtd = runtime->private_data; + mutex_lock(&prtd->lsm_api_lock); + switch (cmd) { case SNDRV_LSM_EVENT_STATUS: { struct snd_lsm_event_status *user = NULL, userarg32; @@ -1288,7 +1299,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, if (copy_from_user(&userarg32, arg, sizeof(userarg32))) { dev_err(rtd->dev, "%s: err copyuser ioctl %s\n", __func__, "SNDRV_LSM_EVENT_STATUS"); - return -EFAULT; + err = -EFAULT; + goto done; } if (userarg32.payload_size > @@ -1296,7 +1308,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, pr_err("%s: payload_size %d is invalid, max allowed = %d\n", __func__, userarg32.payload_size, LISTEN_MAX_STATUS_PAYLOAD_SIZE); - return -EINVAL; + err = -EINVAL; + goto done; } size = sizeof(*user) + userarg32.payload_size; @@ -1305,7 +1318,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: Allocation failed event status size %d\n", __func__, size); - return -EFAULT; + err = -EFAULT; + goto done; } else { cmd = SNDRV_LSM_EVENT_STATUS; user->payload_size = userarg32.payload_size; @@ -1421,7 +1435,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if using topology\n", __func__, "REG_SND_MODEL_V2"); - return -EINVAL; + err = -EINVAL; + goto done; } if (copy_from_user(&snd_modelv232, arg, @@ -1462,7 +1477,7 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if using topology\n", __func__, "SET_PARAMS_32"); - return -EINVAL; + err = -EINVAL; } if (copy_from_user(&det_params32, arg, @@ -1505,7 +1520,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if not using topology\n", __func__, "SET_MODULE_PARAMS_32"); - return -EINVAL; + err = -EINVAL; + goto done; } if (copy_from_user(&p_data_32, arg, @@ -1514,7 +1530,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, "%s: %s: copy_from_user failed, size = %zd\n", __func__, "SET_MODULE_PARAMS_32", sizeof(p_data_32)); - return -EFAULT; + err = -EFAULT; + goto done; } p_data.params = compat_ptr(p_data_32.params); @@ -1526,7 +1543,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, "%s: %s: Invalid num_params %d\n", __func__, "SET_MODULE_PARAMS_32", p_data.num_params); - return -EINVAL; + err = -EINVAL; + goto done; } if (p_data.data_size != @@ -1535,7 +1553,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, "%s: %s: Invalid size %d\n", __func__, "SET_MODULE_PARAMS_32", p_data.data_size); - return -EINVAL; + err = -EINVAL; + goto done; } p_size = sizeof(struct lsm_params_info_32) * @@ -1546,7 +1565,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: no memory for params32, size = %zd\n", __func__, p_size); - return -ENOMEM; + err = -ENOMEM; + goto done; } p_size = sizeof(struct lsm_params_info) * p_data.num_params; @@ -1556,7 +1576,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, "%s: no memory for params, size = %zd\n", __func__, p_size); kfree(params32); - return -ENOMEM; + err = -ENOMEM; + goto done; } if (copy_from_user(params32, p_data.params, @@ -1566,7 +1587,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, __func__, "params32", p_data.data_size); kfree(params32); kfree(params); - return -EFAULT; + err = -EFAULT; + goto done; } p_info_32 = (struct lsm_params_info_32 *) params32; @@ -1609,6 +1631,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, err = msm_lsm_ioctl_shared(substream, cmd, arg); break; } +done: + mutex_unlock(&prtd->lsm_api_lock); return err; } #else @@ -1633,6 +1657,7 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, prtd = runtime->private_data; rtd = substream->private_data; + mutex_lock(&prtd->lsm_api_lock); switch (cmd) { case SNDRV_LSM_REG_SND_MODEL_V2: { struct snd_lsm_sound_model_v2 snd_model_v2; @@ -1641,7 +1666,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if using topology\n", __func__, "REG_SND_MODEL_V2"); - return -EINVAL; + err = -EINVAL; + goto done; } if (copy_from_user(&snd_model_v2, arg, sizeof(snd_model_v2))) { @@ -1668,7 +1694,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if using topology\n", __func__, "SET_PARAMS"); - return -EINVAL; + err = -EINVAL; + goto done; } pr_debug("%s: SNDRV_LSM_SET_PARAMS\n", __func__); @@ -1689,7 +1716,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: LSM_SET_PARAMS failed, err %d\n", __func__, err); - return err; + + goto done; } case SNDRV_LSM_SET_MODULE_PARAMS: { @@ -1701,7 +1729,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: not supported if not using topology\n", __func__, "SET_MODULE_PARAMS"); - return -EINVAL; + err = -EINVAL; + goto done; } if (copy_from_user(&p_data, arg, @@ -1709,7 +1738,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: %s: copy_from_user failed, size = %zd\n", __func__, "p_data", sizeof(p_data)); - return -EFAULT; + err = -EFAULT; + goto done; } if (p_data.num_params > LSM_PARAMS_MAX) { @@ -1717,7 +1747,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, "%s: %s: Invalid num_params %d\n", __func__, "SET_MODULE_PARAMS", p_data.num_params); - return -EINVAL; + err = -EINVAL; + goto done; } p_size = p_data.num_params * @@ -1728,7 +1759,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, "%s: %s: Invalid size %zd\n", __func__, "SET_MODULE_PARAMS", p_size); - return -EFAULT; + err = -EFAULT; + goto done; } params = kzalloc(p_size, GFP_KERNEL); @@ -1736,7 +1768,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: no memory for params\n", __func__); - return -ENOMEM; + err = -ENOMEM; + goto done; } if (copy_from_user(params, p_data.params, @@ -1745,7 +1778,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, "%s: %s: copy_from_user failed, size = %d\n", __func__, "params", p_data.data_size); kfree(params); - return -EFAULT; + err = -EFAULT; + goto done; } err = msm_lsm_process_params(substream, &p_data, params); @@ -1765,7 +1799,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: err copyuser event_status\n", __func__); - return -EFAULT; + err = -EFAULT; + goto done; } if (userarg.payload_size > @@ -1773,7 +1808,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, pr_err("%s: payload_size %d is invalid, max allowed = %d\n", __func__, userarg.payload_size, LISTEN_MAX_STATUS_PAYLOAD_SIZE); - return -EINVAL; + err = -EINVAL; + goto done; } size = sizeof(struct snd_lsm_event_status) + @@ -1783,7 +1819,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: Allocation failed event status size %d\n", __func__, size); - return -EFAULT; + err = -EFAULT; + goto done; } else { user->payload_size = userarg.payload_size; err = msm_lsm_ioctl_shared(substream, cmd, user); @@ -1806,7 +1843,7 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, if (err) dev_err(rtd->dev, "%s: lsmevent failed %d", __func__, err); - return err; + goto done; } case SNDRV_LSM_EVENT_STATUS_V3: { @@ -1873,6 +1910,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, err = msm_lsm_ioctl_shared(substream, cmd, arg); break; } +done: + mutex_unlock(&prtd->lsm_api_lock); return err; } @@ -1889,6 +1928,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) __func__); return -ENOMEM; } + mutex_init(&prtd->lsm_api_lock); spin_lock_init(&prtd->event_lock); init_waitqueue_head(&prtd->event_wait); init_waitqueue_head(&prtd->period_wait); @@ -2048,6 +2088,7 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) kfree(prtd->event_status); prtd->event_status = NULL; spin_unlock_irqrestore(&prtd->event_lock, flags); + mutex_destroy(&prtd->lsm_api_lock); kfree(prtd); runtime->private_data = NULL; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index 727bd6551018..3677a06c65ae 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -14701,6 +14701,7 @@ static void __exit msm_soc_routing_platform_exit(void) { msm_routing_delete_cal_data(); memset(&be_dai_name_table, 0, sizeof(be_dai_name_table)); + mutex_destroy(&routing_lock); platform_driver_unregister(&msm_routing_pcm_driver); } module_exit(msm_soc_routing_platform_exit); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c index c444a27c06e6..b2387a746f61 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -814,20 +814,25 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, if (prtd->mode == MODE_PCM) { ret = copy_from_user(&buf_node->frame.voc_pkt, buf, count); + if (ret) { + pr_err("%s: copy from user failed %d\n", + __func__, ret); + return -EFAULT; + } buf_node->frame.pktlen = count; } else { ret = copy_from_user(&buf_node->frame, buf, count); + if (ret) { + pr_err("%s: copy from user failed %d\n", + __func__, ret); + return -EFAULT; + } if (buf_node->frame.pktlen >= count) buf_node->frame.pktlen = count - (sizeof(buf_node->frame.frm_hdr) + sizeof(buf_node->frame.pktlen)); } - if (ret) { - pr_err("%s: copy from user failed %d\n", - __func__, ret); - return -EFAULT; - } spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); list_add_tail(&buf_node->list, &prtd->in_queue); spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); diff --git a/sound/soc/msm/sdm660-external.c b/sound/soc/msm/sdm660-external.c index 3fe327ad0442..191db6c2fa9d 100644 --- a/sound/soc/msm/sdm660-external.c +++ b/sound/soc/msm/sdm660-external.c @@ -676,7 +676,7 @@ static int msm_ext_get_spk(struct snd_kcontrol *kcontrol, static int msm_ext_set_spk(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); pr_debug("%s()\n", __func__); if (msm_ext_spk_control == ucontrol->value.integer.value[0]) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index b837265ac3e9..8d0d45d330e7 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -390,8 +390,8 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) pm_runtime_get_sync(mcpdm->dev); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); - ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler, - 0, "McPDM", (void *)mcpdm); + ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, 0, "McPDM", + (void *)mcpdm); pm_runtime_put_sync(mcpdm->dev); @@ -416,6 +416,7 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) { struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); + free_irq(mcpdm->irq, (void *)mcpdm); pm_runtime_disable(mcpdm->dev); return 0; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index b1980df07dce..8f76f551e229 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -826,6 +826,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w, case snd_soc_dapm_switch: case snd_soc_dapm_mixer: case snd_soc_dapm_pga: + case snd_soc_dapm_out_drv: wname_in_long_name = true; kcname_in_long_name = true; break; @@ -3030,6 +3031,9 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, } mutex_unlock(&card->dapm_mutex); + if (ret) + return ret; + if (invert) ucontrol->value.integer.value[0] = max - val; else @@ -3181,7 +3185,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, if (e->shift_l != e->shift_r) { if (item[1] > e->items) return -EINVAL; - val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l; + val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; mask |= e->mask << e->shift_r; } diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 6963ba20991c..70396d3f6472 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1484,6 +1484,7 @@ widget: if (widget == NULL) { dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n", w->name); + ret = -ENOMEM; goto hdr_err; } diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 1bb896d78d09..1a4999f9d56f 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -575,11 +575,11 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev) card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) - return NULL; + return ERR_PTR(-ENOMEM); card->dai_link = sun4i_codec_create_link(dev, &card->num_links); if (!card->dai_link) - return NULL; + return ERR_PTR(-ENOMEM); card->dev = dev; card->name = "sun4i-codec"; @@ -661,7 +661,8 @@ static int sun4i_codec_probe(struct platform_device *pdev) } card = sun4i_codec_create_card(&pdev->dev); - if (!card) { + if (IS_ERR(card)) { + ret = PTR_ERR(card); dev_err(&pdev->dev, "Failed to create our card\n"); goto err_unregister_codec; } diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 81b7da8e56d3..183311cb849e 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -29,7 +29,7 @@ /* This is Line 6's MIDI manufacturer ID. */ -const unsigned char line6_midi_id[] = { +const unsigned char line6_midi_id[3] = { 0x00, 0x01, 0x0c }; EXPORT_SYMBOL_GPL(line6_midi_id); diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index f6c3bf79af9a..04991b009132 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -1831,6 +1831,7 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer, } static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer, + struct usb_mixer_elem_info *cval, struct snd_kcontrol *kctl) { /* Approximation using 10 ranges based on output measurement on hw v1.2. @@ -1848,10 +1849,19 @@ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer, 41, 50, TLV_DB_MINMAX_ITEM(-441, 0), ); - usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n"); - kctl->tlv.p = scale; - kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; - kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; + if (cval->min == 0 && cval->max == 50) { + usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk (0-50 variant)\n"); + kctl->tlv.p = scale; + kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; + kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; + + } else if (cval->min == 0 && cval->max <= 1000) { + /* Some other clearly broken DragonFly variant. + * At least a 0..53 variant (hw v1.0) exists. + */ + usb_audio_info(mixer->chip, "ignoring too narrow dB range on a DragonFly device"); + kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; + } } void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, @@ -1860,8 +1870,8 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, { switch (mixer->chip->usb_id) { case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */ - if (unitid == 7 && cval->min == 0 && cval->max == 50) - snd_dragonfly_quirk_db_scale(mixer, kctl); + if (unitid == 7 && cval->control == UAC_FU_VOLUME) + snd_dragonfly_quirk_db_scale(mixer, cval, kctl); break; } } diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index c60a776e815d..8a59d4782a0f 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -2907,6 +2907,23 @@ AU0828_DEVICE(0x2040, 0x7260, "Hauppauge", "HVR-950Q"), AU0828_DEVICE(0x2040, 0x7213, "Hauppauge", "HVR-950Q"), AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), +/* Syntek STK1160 */ +{ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS, + .idVendor = 0x05e1, + .idProduct = 0x0408, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .vendor_name = "Syntek", + .product_name = "STK1160", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_AUDIO_ALIGN_TRANSFER + } +}, + /* Digidesign Mbox */ { /* Thanks to Clemens Ladisch <clemens@ladisch.de> */ |
