Merge branch 'topic/hda-micmute-led' into for-next
authorTakashi Iwai <tiwai@suse.de>
Fri, 19 Jun 2020 10:14:58 +0000 (12:14 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 19 Jun 2020 10:15:04 +0000 (12:15 +0200)
This is a patch set inspired by the recent patch Kai-Heng posted about
the HD-audio mic-mute LED control.  Currently HD-audio driver deals
with the mute and mic-mute LED in several different ways: primarily
with the direct callback of vmaster hook and capture sync hook, while
another with the LED class device binding.  The latter has been used
for binding with the platform device LEDs like Thinkpad, Dell,
Huawei.  And, yet, recently we added our own LED classdev for the
mic-mute LED on some HP systems although they are controlled directly
with the callback; it's exposed, however, for the DMIC that is
governed by a different ASoC driver.

This patch set is an attempt to sort out and make them consistent:
namely,
* All LEDs are now controlled via LED class device
* The generic driver provides helper functions to easily build up the
  LED class dev and the relevant mixer controls
* Conversion of the existing framework and clean ups

The patches are lightly tested in my side with a couple of machines
and also through hda-emu tests.  Some devices receive new kcontrols
for the mute LED behavior (that have been missing so far), but
anything else look good though my tests.

Link: https://lore.kernel.org/r/20200618110842.27238-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
13 files changed:
include/sound/memalloc.h
sound/core/memalloc.c
sound/core/pcm_memory.c
sound/core/pcm_native.c
sound/core/sgbuf.c
sound/firewire/motu/motu-protocol-v3.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_hdmi.c
sound/usb/format.c
sound/usb/pcm.c
sound/usb/quirks.c

index 3b47832..5daa937 100644 (file)
@@ -94,7 +94,11 @@ static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab,
                                           size_t offset)
 {
        struct snd_sg_buf *sgbuf = dmab->private_data;
-       dma_addr_t addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
+       dma_addr_t addr;
+
+       if (!sgbuf)
+               return dmab->addr + offset;
+       addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
        addr &= ~((dma_addr_t)PAGE_SIZE - 1);
        return addr + offset % PAGE_SIZE;
 }
@@ -106,6 +110,9 @@ static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab,
                                     size_t offset)
 {
        struct snd_sg_buf *sgbuf = dmab->private_data;
+
+       if (!sgbuf)
+               return dmab->area + offset;
        return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE;
 }
 
index bea46ed..d8f28d0 100644 (file)
@@ -135,16 +135,17 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
        dmab->dev.type = type;
        dmab->dev.dev = device;
        dmab->bytes = 0;
+       dmab->area = NULL;
+       dmab->addr = 0;
+       dmab->private_data = NULL;
        switch (type) {
        case SNDRV_DMA_TYPE_CONTINUOUS:
                gfp = snd_mem_get_gfp_flags(device, GFP_KERNEL);
                dmab->area = alloc_pages_exact(size, gfp);
-               dmab->addr = 0;
                break;
        case SNDRV_DMA_TYPE_VMALLOC:
                gfp = snd_mem_get_gfp_flags(device, GFP_KERNEL | __GFP_HIGHMEM);
                dmab->area = __vmalloc(size, gfp);
-               dmab->addr = 0;
                break;
 #ifdef CONFIG_HAS_DMA
 #ifdef CONFIG_GENERIC_ALLOCATOR
@@ -171,8 +172,6 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
 #endif
        default:
                pr_err("snd-malloc: invalid device type %d\n", type);
-               dmab->area = NULL;
-               dmab->addr = 0;
                return -ENXIO;
        }
        if (! dmab->area)
index 860935e..8326d16 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
 #include <linux/export.h>
+#include <linux/dma-mapping.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/info.h>
@@ -39,6 +40,18 @@ static int do_alloc_pages(struct snd_card *card, int type, struct device *dev,
        if (max_alloc_per_card &&
            card->total_pcm_alloc_bytes + size > max_alloc_per_card)
                return -ENOMEM;
+
+       if (IS_ENABLED(CONFIG_SND_DMA_SGBUF) &&
+           (type == SNDRV_DMA_TYPE_DEV_SG || type == SNDRV_DMA_TYPE_DEV_UC_SG) &&
+           !dma_is_direct(get_dma_ops(dev))) {
+               /* mutate to continuous page allocation */
+               dev_dbg(dev, "Use continuous page allocator\n");
+               if (type == SNDRV_DMA_TYPE_DEV_SG)
+                       type = SNDRV_DMA_TYPE_DEV;
+               else
+                       type = SNDRV_DMA_TYPE_DEV_UC;
+       }
+
        err = snd_dma_alloc_pages(type, dev, size, dmab);
        if (!err) {
                mutex_lock(&card->memory_mutex);
index 9630d25..1e51c84 100644 (file)
@@ -3713,7 +3713,6 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
                                area->vm_end - area->vm_start, area->vm_page_prot);
        }
 #endif /* CONFIG_GENERIC_ALLOCATOR */
-#ifndef CONFIG_X86 /* for avoiding warnings arch/x86/mm/pat.c */
        if (IS_ENABLED(CONFIG_HAS_DMA) && !substream->ops->page &&
            (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV ||
             substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_UC))
@@ -3722,7 +3721,6 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
                                         substream->runtime->dma_area,
                                         substream->runtime->dma_addr,
                                         substream->runtime->dma_bytes);
-#endif /* CONFIG_X86 */
        /* mmap with fault handler */
        area->vm_ops = &snd_pcm_vm_ops_data_fault;
        return 0;
index c42217e..29ddb76 100644 (file)
@@ -142,6 +142,9 @@ unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
        struct snd_sg_buf *sg = dmab->private_data;
        unsigned int start, end, pg;
 
+       if (!sg)
+               return size;
+
        start = ofs >> PAGE_SHIFT;
        end = (ofs + size - 1) >> PAGE_SHIFT;
        /* check page continuity */
index 01a47ac..4e6b0e4 100644 (file)
@@ -24,6 +24,9 @@
 #define  V3_NO_ADAT_OPT_OUT_IFACE_A    0x00040000
 #define  V3_NO_ADAT_OPT_OUT_IFACE_B    0x00400000
 
+#define V3_MSG_FLAG_CLK_CHANGED                0x00000002
+#define V3_CLK_WAIT_MSEC               4000
+
 int snd_motu_protocol_v3_get_clock_rate(struct snd_motu *motu,
                                        unsigned int *rate)
 {
@@ -79,9 +82,16 @@ int snd_motu_protocol_v3_set_clock_rate(struct snd_motu *motu,
                return err;
 
        if (need_to_wait) {
-               /* Cost expensive. */
-               if (msleep_interruptible(4000) > 0)
-                       return -EINTR;
+               int result;
+
+               motu->msg = 0;
+               result = wait_event_interruptible_timeout(motu->hwdep_wait,
+                                       motu->msg & V3_MSG_FLAG_CLK_CHANGED,
+                                       msecs_to_jiffies(V3_CLK_WAIT_MSEC));
+               if (result < 0)
+                       return result;
+               if (result == 0)
+                       return -ETIMEDOUT;
        }
 
        return 0;
index 9765652..80016b7 100644 (file)
@@ -1202,15 +1202,8 @@ int azx_bus_init(struct azx *chip, const char *model)
        if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY)
                bus->core.align_bdle_4k = true;
 
-       /* AMD chipsets often cause the communication stalls upon certain
-        * sequence like the pin-detection.  It seems that forcing the synced
-        * access works around the stall.  Grrr...
-        */
-       if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) {
-               dev_dbg(chip->card->dev, "Enable sync_write for stable communication\n");
-               bus->core.sync_write = 1;
-               bus->allow_bus_reset = 1;
-       }
+       /* enable sync_write flag for stable communication as default */
+       bus->core.sync_write = 1;
 
        return 0;
 }
index 82e2644..fe17168 100644 (file)
@@ -33,7 +33,7 @@
 #define AZX_DCAPS_POSFIX_LPIB  (1 << 16)       /* Use LPIB as default */
 #define AZX_DCAPS_AMD_WORKAROUND (1 << 17)     /* AMD-specific workaround */
 #define AZX_DCAPS_NO_64BIT     (1 << 18)       /* No 64bit address */
-#define AZX_DCAPS_SYNC_WRITE   (1 << 19)       /* sync each cmd write */
+/* 19 unused */
 #define AZX_DCAPS_OLD_SSYNC    (1 << 20)       /* Old SSYNC reg for ICH */
 #define AZX_DCAPS_NO_ALIGN_BUFSIZE (1 << 21)   /* no buffer size alignment */
 /* 22 unused */
index d20aedd..59c87ab 100644 (file)
@@ -283,13 +283,12 @@ enum {
 
 /* quirks for old Intel chipsets */
 #define AZX_DCAPS_INTEL_ICH \
-       (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE |\
-        AZX_DCAPS_SYNC_WRITE)
+       (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE)
 
 /* quirks for Intel PCH */
 #define AZX_DCAPS_INTEL_PCH_BASE \
        (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\
-        AZX_DCAPS_SNOOP_TYPE(SCH) | AZX_DCAPS_SYNC_WRITE)
+        AZX_DCAPS_SNOOP_TYPE(SCH))
 
 /* PCH up to IVB; no runtime PM; bind with i915 gfx */
 #define AZX_DCAPS_INTEL_PCH_NOPM \
@@ -304,13 +303,13 @@ enum {
 #define AZX_DCAPS_INTEL_HASWELL \
        (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\
         AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\
-        AZX_DCAPS_SNOOP_TYPE(SCH) | AZX_DCAPS_SYNC_WRITE)
+        AZX_DCAPS_SNOOP_TYPE(SCH))
 
 /* Broadwell HDMI can't use position buffer reliably, force to use LPIB */
 #define AZX_DCAPS_INTEL_BROADWELL \
        (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\
         AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\
-        AZX_DCAPS_SNOOP_TYPE(SCH) | AZX_DCAPS_SYNC_WRITE)
+        AZX_DCAPS_SNOOP_TYPE(SCH))
 
 #define AZX_DCAPS_INTEL_BAYTRAIL \
        (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT)
@@ -321,19 +320,18 @@ enum {
 
 #define AZX_DCAPS_INTEL_SKYLAKE \
        (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
-        AZX_DCAPS_SYNC_WRITE |\
         AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT)
 
 #define AZX_DCAPS_INTEL_BROXTON                AZX_DCAPS_INTEL_SKYLAKE
 
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
-       (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB |\
+       (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB |\
         AZX_DCAPS_SNOOP_TYPE(ATI))
 
 /* quirks for ATI/AMD HDMI */
 #define AZX_DCAPS_PRESET_ATI_HDMI \
-       (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB|\
+       (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB|\
         AZX_DCAPS_NO_MSI64)
 
 /* quirks for ATI HDMI with snoop off */
@@ -342,7 +340,7 @@ enum {
 
 /* quirks for AMD SB */
 #define AZX_DCAPS_PRESET_AMD_SB \
-       (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_AMD_WORKAROUND |\
+       (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_AMD_WORKAROUND |\
         AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME)
 
 /* quirks for Nvidia */
index fbd7cc6..e2b21ef 100644 (file)
@@ -4145,6 +4145,11 @@ 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(0x10de009a, "GPU 9a HDMI/DP",  patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de009d, "GPU 9d HDMI/DP",  patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de009e, "GPU 9e HDMI/DP",  patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de009f, "GPU 9f HDMI/DP",  patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de00a0, "GPU a0 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),
index 5ffb457..1b28d01 100644 (file)
@@ -394,8 +394,9 @@ skip_rate:
        return nr_rates;
 }
 
-/* Line6 Helix series don't support the UAC2_CS_RANGE usb function
- * call. Return a static table of known clock rates.
+/* Line6 Helix series and the Rode Rodecaster Pro don't support the
+ * UAC2_CS_RANGE usb function call. Return a static table of known
+ * clock rates.
  */
 static int line6_parse_audio_format_rates_quirk(struct snd_usb_audio *chip,
                                                struct audioformat *fp)
@@ -408,6 +409,7 @@ static int line6_parse_audio_format_rates_quirk(struct snd_usb_audio *chip,
        case USB_ID(0x0e41, 0x4248): /* Line6 Helix >= fw 2.82 */
        case USB_ID(0x0e41, 0x4249): /* Line6 Helix Rack >= fw 2.82 */
        case USB_ID(0x0e41, 0x424a): /* Line6 Helix LT >= fw 2.82 */
+       case USB_ID(0x19f7, 0x0011): /* Rode Rodecaster Pro */
                return set_fixed_rate(fp, 48000, SNDRV_PCM_RATE_48000);
        }
 
index 8a05dcb..84c0ae4 100644 (file)
@@ -367,6 +367,7 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs,
                ifnum = 0;
                goto add_sync_ep_from_ifnum;
        case USB_ID(0x07fd, 0x0008): /* MOTU M Series */
+       case USB_ID(0x31e9, 0x0002): /* Solid State Logic SSL2+ */
                ep = 0x81;
                ifnum = 2;
                goto add_sync_ep_from_ifnum;
index bca0179..c495e72 100644 (file)
@@ -1532,6 +1532,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
 static bool is_itf_usb_dsd_dac(unsigned int id)
 {
        switch (id) {
+       case USB_ID(0x154e, 0x1002): /* Denon DCD-1500RE */
        case USB_ID(0x154e, 0x1003): /* Denon DA-300USB */
        case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */
        case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */