diff options
Diffstat (limited to 'sound')
59 files changed, 509 insertions, 271 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index fb096cb20a80..c109b82eef4b 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -25,6 +25,7 @@ #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/time.h> +#include <linux/sched/signal.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/info.h> diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 36d2416f90d9..9602a7e38d8a 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -25,6 +25,7 @@ #include <linux/time.h> #include <linux/mutex.h> #include <linux/module.h> +#include <linux/sched/signal.h> #include <sound/core.h> #include <sound/control.h> #include <sound/minors.h> diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 698a01419515..36baf962f9b0 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -28,6 +28,7 @@ #include <linux/init.h> #include <linux/slab.h> +#include <linux/sched/signal.h> #include <linux/time.h> #include <linux/vmalloc.h> #include <linux/module.h> diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index bb1261591a1f..5088d4b8db22 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -21,6 +21,7 @@ */ #include <linux/slab.h> +#include <linux/sched/signal.h> #include <linux/time.h> #include <linux/math64.h> #include <linux/export.h> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 9d33c1e85c79..13dec5ec93f2 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -23,6 +23,7 @@ #include <linux/module.h> #include <linux/file.h> #include <linux/slab.h> +#include <linux/sched/signal.h> #include <linux/time.h> #include <linux/pm_qos.h> #include <linux/io.h> @@ -3245,10 +3246,9 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait) /* * mmap status record */ -static int snd_pcm_mmap_status_fault(struct vm_area_struct *area, - struct vm_fault *vmf) +static int snd_pcm_mmap_status_fault(struct vm_fault *vmf) { - struct snd_pcm_substream *substream = area->vm_private_data; + struct snd_pcm_substream *substream = vmf->vma->vm_private_data; struct snd_pcm_runtime *runtime; if (substream == NULL) @@ -3282,10 +3282,9 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file /* * mmap control record */ -static int snd_pcm_mmap_control_fault(struct vm_area_struct *area, - struct vm_fault *vmf) +static int snd_pcm_mmap_control_fault(struct vm_fault *vmf) { - struct snd_pcm_substream *substream = area->vm_private_data; + struct snd_pcm_substream *substream = vmf->vma->vm_private_data; struct snd_pcm_runtime *runtime; if (substream == NULL) @@ -3341,10 +3340,9 @@ snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs) /* * fault callback for mmapping a RAM page */ -static int snd_pcm_mmap_data_fault(struct vm_area_struct *area, - struct vm_fault *vmf) +static int snd_pcm_mmap_data_fault(struct vm_fault *vmf) { - struct snd_pcm_substream *substream = area->vm_private_data; + struct snd_pcm_substream *substream = vmf->vma->vm_private_data; struct snd_pcm_runtime *runtime; unsigned long offset; struct page * page; diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 8da9cb245d01..ab890336175f 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -22,7 +22,7 @@ #include <sound/core.h> #include <linux/major.h> #include <linux/init.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> #include <linux/slab.h> #include <linux/time.h> #include <linux/wait.h> diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h index d7b4d016b547..afa007c0cc2d 100644 --- a/sound/core/seq/oss/seq_oss_device.h +++ b/sound/core/seq/oss/seq_oss_device.h @@ -24,7 +24,7 @@ #include <linux/time.h> #include <linux/wait.h> #include <linux/slab.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> #include <sound/core.h> #include <sound/seq_oss.h> #include <sound/rawmidi.h> diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c index 1f6788a18444..5e04f4df10e4 100644 --- a/sound/core/seq/oss/seq_oss_writeq.c +++ b/sound/core/seq/oss/seq_oss_writeq.c @@ -28,6 +28,7 @@ #include "../seq_clientmgr.h" #include <linux/wait.h> #include <linux/slab.h> +#include <linux/sched/signal.h> /* diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c index 1d5acbe0c08b..448efd4e980e 100644 --- a/sound/core/seq/seq_fifo.c +++ b/sound/core/seq/seq_fifo.c @@ -21,6 +21,8 @@ #include <sound/core.h> #include <linux/slab.h> +#include <linux/sched/signal.h> + #include "seq_fifo.h" #include "seq_lock.h" @@ -135,6 +137,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, f->tail = cell; if (f->head == NULL) f->head = cell; + cell->next = NULL; f->cells++; spin_unlock_irqrestore(&f->lock, flags); @@ -214,6 +217,8 @@ void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f, spin_lock_irqsave(&f->lock, flags); cell->next = f->head; f->head = cell; + if (!f->tail) + f->tail = cell; f->cells++; spin_unlock_irqrestore(&f->lock, flags); } diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index dfa5156f3585..1a1acf3ddda4 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -23,6 +23,7 @@ #include <linux/init.h> #include <linux/export.h> #include <linux/slab.h> +#include <linux/sched/signal.h> #include <linux/vmalloc.h> #include <sound/core.h> diff --git a/sound/core/timer.c b/sound/core/timer.c index fc144f43faa6..6d4fbc439246 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -27,6 +27,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/string.h> +#include <linux/sched/signal.h> #include <sound/core.h> #include <sound/timer.h> #include <sound/control.h> @@ -1702,9 +1703,21 @@ static int snd_timer_user_params(struct file *file, return -EBADFD; if (copy_from_user(¶ms, _params, sizeof(params))) return -EFAULT; - if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) { - err = -EINVAL; - goto _end; + if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) { + u64 resolution; + + if (params.ticks < 1) { + err = -EINVAL; + goto _end; + } + + /* Don't allow resolution less than 1ms */ + resolution = snd_timer_resolution(tu->timeri); + resolution *= params.ticks; + if (resolution < 1000000) { + err = -EINVAL; + goto _end; + } } if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) { diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h index 175da875162d..17678d6ab5a2 100644 --- a/sound/firewire/bebob/bebob.h +++ b/sound/firewire/bebob/bebob.h @@ -17,6 +17,7 @@ #include <linux/mod_devicetable.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/sched/signal.h> #include <sound/core.h> #include <sound/initval.h> diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h index e6c07857f475..da00e75e09d4 100644 --- a/sound/firewire/dice/dice.h +++ b/sound/firewire/dice/dice.h @@ -23,6 +23,7 @@ #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/wait.h> +#include <linux/sched/signal.h> #include <sound/control.h> #include <sound/core.h> diff --git a/sound/firewire/digi00x/digi00x.h b/sound/firewire/digi00x/digi00x.h index 2cd465c0caae..9dc761bdacca 100644 --- a/sound/firewire/digi00x/digi00x.h +++ b/sound/firewire/digi00x/digi00x.h @@ -16,6 +16,7 @@ #include <linux/mod_devicetable.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/sched/signal.h> #include <sound/core.h> #include <sound/initval.h> diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h index d73c12b8753d..9b19c7f05d57 100644 --- a/sound/firewire/fireworks/fireworks.h +++ b/sound/firewire/fireworks/fireworks.h @@ -17,6 +17,7 @@ #include <linux/mod_devicetable.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/sched/signal.h> #include <sound/core.h> #include <sound/initval.h> diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h index 2047dcb27625..d54d4a9ac4a1 100644 --- a/sound/firewire/oxfw/oxfw.h +++ b/sound/firewire/oxfw/oxfw.h @@ -13,6 +13,7 @@ #include <linux/mutex.h> #include <linux/slab.h> #include <linux/compat.h> +#include <linux/sched/signal.h> #include <sound/control.h> #include <sound/core.h> diff --git a/sound/firewire/tascam/tascam.h b/sound/firewire/tascam/tascam.h index 1f61011579a7..d3cd4065722b 100644 --- a/sound/firewire/tascam/tascam.h +++ b/sound/firewire/tascam/tascam.h @@ -17,6 +17,7 @@ #include <linux/mutex.h> #include <linux/slab.h> #include <linux/compat.h> +#include <linux/sched/signal.h> #include <sound/core.h> #include <sound/initval.h> diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index 25f6788ccef3..06505999155f 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c @@ -27,6 +27,8 @@ #include <asm/dma.h> #include <linux/slab.h> +#include <linux/sched/signal.h> + #include <sound/core.h> #include <sound/control.h> #include <sound/gus.h> diff --git a/sound/isa/msnd/msnd.c b/sound/isa/msnd/msnd.c index 835d4aa26761..8109ab3d29d1 100644 --- a/sound/isa/msnd/msnd.c +++ b/sound/isa/msnd/msnd.c @@ -36,6 +36,7 @@ ********************************************************************/ #include <linux/kernel.h> +#include <linux/sched/signal.h> #include <linux/types.h> #include <linux/interrupt.h> #include <linux/io.h> diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index 94c411299e5a..ec180708f160 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -21,7 +21,7 @@ */ #include <linux/wait.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> #include <linux/slab.h> #include <linux/ioport.h> #include <linux/export.h> diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c index 71d13c0bb746..c2e41d2762f7 100644 --- a/sound/isa/sb/emu8000_patch.c +++ b/sound/isa/sb/emu8000_patch.c @@ -20,6 +20,8 @@ */ #include "emu8000_local.h" + +#include <linux/sched/signal.h> #include <linux/uaccess.h> #include <linux/moduleparam.h> diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c index 250fd0006b53..32f234f494e5 100644 --- a/sound/isa/sb/emu8000_pcm.c +++ b/sound/isa/sb/emu8000_pcm.c @@ -19,6 +19,8 @@ */ #include "emu8000_local.h" + +#include <linux/sched/signal.h> #include <linux/init.h> #include <linux/slab.h> #include <sound/initval.h> diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 718d5e3b7806..4dae9ff9ef5a 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -26,6 +26,7 @@ #include <linux/delay.h> #include <linux/time.h> #include <linux/wait.h> +#include <linux/sched/signal.h> #include <linux/firmware.h> #include <linux/moduleparam.h> #include <linux/slab.h> diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c index e3f29132d3ac..c5dd396c66a2 100644 --- a/sound/oss/dmabuf.c +++ b/sound/oss/dmabuf.c @@ -27,6 +27,8 @@ #include <linux/mm.h> #include <linux/gfp.h> +#include <linux/sched/signal.h> + #include "sound_config.h" #include "sleep.h" diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index 5f248fb41bea..fb3bbceb1fef 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -182,6 +182,7 @@ #include <linux/soundcard.h> #include <linux/poll.h> #include <linux/mutex.h> +#include <linux/sched/signal.h> #include <linux/uaccess.h> diff --git a/sound/oss/midibuf.c b/sound/oss/midibuf.c index 8f45cd999965..701c7625c971 100644 --- a/sound/oss/midibuf.c +++ b/sound/oss/midibuf.c @@ -16,6 +16,8 @@ #include <linux/stddef.h> #include <linux/kmod.h> #include <linux/spinlock.h> +#include <linux/sched/signal.h> + #define MIDIBUF_C #include "sound_config.h" diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c index a8bb4a06ba6f..f34ec01d2239 100644 --- a/sound/oss/msnd_pinnacle.c +++ b/sound/oss/msnd_pinnacle.c @@ -41,6 +41,8 @@ #include <linux/interrupt.h> #include <linux/mutex.h> #include <linux/gfp.h> +#include <linux/sched/signal.h> + #include <asm/irq.h> #include <asm/io.h> #include "sound_config.h" diff --git a/sound/oss/sound_config.h b/sound/oss/sound_config.h index f2554ab78f5e..5253b0a70437 100644 --- a/sound/oss/sound_config.h +++ b/sound/oss/sound_config.h @@ -16,6 +16,7 @@ #include <linux/fs.h> #include <linux/sound.h> +#include <linux/sched/signal.h> #include "os.h" #include "soundvers.h" diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index f3af63e58b36..97899352b15f 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c @@ -64,7 +64,7 @@ #include <linux/module.h> #include <linux/string.h> #include <linux/ioport.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> #include <linux/delay.h> #include <linux/sound.h> #include <linux/slab.h> diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index f4234edb878c..8cf0dc7a07a4 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -3093,7 +3093,7 @@ static int patch_cm9739(struct snd_ac97 * ac97) /* set-up multi channel */ /* bit 14: 0 = SPDIF, 1 = EAPD */ /* bit 13: enable internal vref output for mic */ - /* bit 12: disable center/lfe (swithable) */ + /* bit 12: disable center/lfe (switchable) */ /* bit 10: disable surround/line (switchable) */ /* bit 9: mix 2 surround off */ /* bit 4: undocumented; 0 mutes the CM9739A, which defaults to 1 */ diff --git a/sound/pci/cs46xx/cs46xx_dsp_task_types.h b/sound/pci/cs46xx/cs46xx_dsp_task_types.h index 5cf920bfda27..be5694718546 100644 --- a/sound/pci/cs46xx/cs46xx_dsp_task_types.h +++ b/sound/pci/cs46xx/cs46xx_dsp_task_types.h @@ -203,7 +203,7 @@ struct dsp_task_tree_context_block { u32 saverfe; - /* Value may be overwriten by stack save algorithm. + /* Value may be overwritten by stack save algorithm. Retain the size of the stack data saved here if used */ ___DSP_DUAL_16BIT_ALLOC( reserved1, diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 9667cbfb0ca2..79edd88d5cd0 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -27,12 +27,6 @@ #include "cthw20k1.h" #include "ct20k1reg.h" -#if BITS_PER_LONG == 32 -#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bit PTE */ -#else -#define CT_XFI_DMA_MASK DMA_BIT_MASK(64) /* 64 bit PTE */ -#endif - struct hw20k1 { struct hw hw; spinlock_t reg_20k1_lock; @@ -1904,19 +1898,18 @@ static int hw_card_start(struct hw *hw) { int err; struct pci_dev *pci = hw->pci; + const unsigned int dma_bits = BITS_PER_LONG; err = pci_enable_device(pci); if (err < 0) return err; /* Set DMA transfer mask */ - if (dma_set_mask(&pci->dev, CT_XFI_DMA_MASK) < 0 || - dma_set_coherent_mask(&pci->dev, CT_XFI_DMA_MASK) < 0) { - dev_err(hw->card->dev, - "architecture does not support PCI busmaster DMA with mask 0x%llx\n", - CT_XFI_DMA_MASK); - err = -ENXIO; - goto error1; + if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { + dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits)); + } else { + dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); + dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); } if (!hw->io_base) { diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index 6414ecf93efa..18ee7768b7c4 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -26,12 +26,6 @@ #include "cthw20k2.h" #include "ct20k2reg.h" -#if BITS_PER_LONG == 32 -#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bit PTE */ -#else -#define CT_XFI_DMA_MASK DMA_BIT_MASK(64) /* 64 bit PTE */ -#endif - struct hw20k2 { struct hw hw; /* for i2c */ @@ -2029,19 +2023,18 @@ static int hw_card_start(struct hw *hw) int err = 0; struct pci_dev *pci = hw->pci; unsigned int gctl; + const unsigned int dma_bits = BITS_PER_LONG; err = pci_enable_device(pci); if (err < 0) return err; /* Set DMA transfer mask */ - if (dma_set_mask(&pci->dev, CT_XFI_DMA_MASK) < 0 || - dma_set_coherent_mask(&pci->dev, CT_XFI_DMA_MASK) < 0) { - dev_err(hw->card->dev, - "architecture does not support PCI busmaster DMA with mask 0x%llx\n", - CT_XFI_DMA_MASK); - err = -ENXIO; - goto error1; + if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { + dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits)); + } else { + dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); + dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); } if (!hw->io_base) { diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index bf491eb58b24..70bb365a08d2 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -311,9 +311,15 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, } EXPORT_SYMBOL_GPL(snd_hda_get_conn_index); - -/* return DEVLIST_LEN parameter of the given widget */ -static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid) +/** + * snd_hda_get_num_devices - get DEVLIST_LEN parameter of the given widget + * @codec: the HDA codec + * @nid: NID of the pin to parse + * + * Get the device entry number on the given widget. This is a feature of + * DP MST audio. Each pin can have several device entries in it. + */ +unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid) { unsigned int wcaps = get_wcaps(codec, nid); unsigned int parm; @@ -327,6 +333,7 @@ static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid) parm = 0; return parm & AC_DEV_LIST_LEN_MASK; } +EXPORT_SYMBOL_GPL(snd_hda_get_num_devices); /** * snd_hda_get_devices - copy device list without cache @@ -344,7 +351,7 @@ int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid, unsigned int parm; int i, dev_len, devices; - parm = get_num_devices(codec, nid); + parm = snd_hda_get_num_devices(codec, nid); if (!parm) /* not multi-stream capable */ return 0; @@ -368,6 +375,63 @@ int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid, return devices; } +/** + * snd_hda_get_dev_select - get device entry select on the pin + * @codec: the HDA codec + * @nid: NID of the pin to get device entry select + * + * Get the devcie entry select on the pin. Return the device entry + * id selected on the pin. Return 0 means the first device entry + * is selected or MST is not supported. + */ +int snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid) +{ + /* not support dp_mst will always return 0, using first dev_entry */ + if (!codec->dp_mst) + return 0; + + return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DEVICE_SEL, 0); +} +EXPORT_SYMBOL_GPL(snd_hda_get_dev_select); + +/** + * snd_hda_set_dev_select - set device entry select on the pin + * @codec: the HDA codec + * @nid: NID of the pin to set device entry select + * @dev_id: device entry id to be set + * + * Set the device entry select on the pin nid. + */ +int snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id) +{ + int ret, num_devices; + + /* not support dp_mst will always return 0, using first dev_entry */ + if (!codec->dp_mst) + return 0; + + /* AC_PAR_DEVLIST_LEN is 0 based. */ + num_devices = snd_hda_get_num_devices(codec, nid) + 1; + /* If Device List Length is 0 (num_device = 1), + * the pin is not multi stream capable. + * Do nothing in this case. + */ + if (num_devices == 1) + return 0; + + /* Behavior of setting index being equal to or greater than + * Device List Length is not predictable + */ + if (num_devices <= dev_id) + return -EINVAL; + + ret = snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_DEVICE_SEL, dev_id); + + return ret; +} +EXPORT_SYMBOL_GPL(snd_hda_set_dev_select); + /* * read widget caps for each widget and store in cache */ @@ -403,6 +467,10 @@ static int read_pin_defaults(struct hda_codec *codec) pin->nid = nid; pin->cfg = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); + /* + * all device entries are the same widget control so far + * fixme: if any codec is different, need fix here + */ pin->ctrl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 373fcad840ea..f17f25245e52 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -347,8 +347,11 @@ int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums, const hda_nid_t *list); int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, hda_nid_t nid, int recursive); +unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid); int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid, u8 *dev_list, int max_devices); +int snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid); +int snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id); struct hda_verb { hda_nid_t nid; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 16108f0eb688..c8256a89375a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2255,6 +2255,9 @@ static const struct pci_device_id azx_ids[] = { /* Broxton-T */ { PCI_DEVICE(0x8086, 0x1a98), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON }, + /* Gemini-Lake */ + { PCI_DEVICE(0x8086, 0x3198), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON }, /* Haswell */ { PCI_DEVICE(0x8086, 0x0a0c), .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL }, diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 9ec4dba8a793..07a9deb17477 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -2866,7 +2866,7 @@ static unsigned int ca0132_capture_pcm_delay(struct hda_pcm_stream *info, #define CA0132_CODEC_MUTE(xname, nid, dir) \ CA0132_CODEC_MUTE_MONO(xname, nid, 3, dir) -/* The followings are for tuning of products */ +/* The following are for tuning of products */ #ifdef ENABLE_TUNING_CONTROLS static unsigned int voice_focus_vals_lookup[] = { diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index c15c51bea26d..69266b8ea2ad 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_DOCK, CXT_FIXUP_HP_SPECTRE, CXT_FIXUP_HP_GATE_MIC, }; @@ -778,6 +779,14 @@ static const struct hda_fixup cxt_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = cxt_fixup_mute_led_eapd, }, + [CXT_FIXUP_HP_DOCK] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x16, 0x21011020 }, /* line-out */ + { 0x18, 0x2181103f }, /* line-in */ + { } + } + }, [CXT_FIXUP_HP_SPECTRE] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -839,6 +848,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, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), 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(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), @@ -871,6 +881,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { { .id = CXT_PINCFG_LEMOTE_A1205, .name = "lemote-a1205" }, { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, + { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" }, {} }; diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 3ce872c26436..37f11560186a 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -76,6 +76,7 @@ struct hdmi_spec_per_cvt { struct hdmi_spec_per_pin { hda_nid_t pin_nid; + int dev_id; /* pin idx, different device entries on the same pin use the same idx */ int pin_nid_idx; int num_mux_nids; @@ -130,7 +131,23 @@ struct hdmi_spec { struct snd_array cvts; /* struct hdmi_spec_per_cvt */ hda_nid_t cvt_nids[4]; /* only for haswell fix */ + /* + * num_pins is the number of virtual pins + * for example, there are 3 pins, and each pin + * has 4 device entries, then the num_pins is 12 + */ int num_pins; + /* + * num_nids is the number of real pins + * In the above example, num_nids is 3 + */ + int num_nids; + /* + * dev_num is the number of device entries + * on each pin. + * In the above example, dev_num is 4 + */ + int dev_num; struct snd_array pins; /* struct hdmi_spec_per_pin */ struct hdmi_pcm pcm_rec[16]; struct mutex pcm_lock; @@ -217,14 +234,26 @@ union audio_infoframe { /* obtain hda_pcm object assigned to idx */ #define get_pcm_rec(spec, idx) (get_hdmi_pcm(spec, idx)->pcm) -static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid) +static int pin_id_to_pin_index(struct hda_codec *codec, + hda_nid_t pin_nid, int dev_id) { struct hdmi_spec *spec = codec->spec; int pin_idx; + struct hdmi_spec_per_pin *per_pin; + + /* + * (dev_id == -1) means it is NON-MST pin + * return the first virtual pin on this port + */ + if (dev_id == -1) + dev_id = 0; - for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) - if (get_pin(spec, pin_idx)->pin_nid == pin_nid) + for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { + per_pin = get_pin(spec, pin_idx); + if ((per_pin->pin_nid == pin_nid) && + (per_pin->dev_id == dev_id)) return pin_idx; + } codec_warn(codec, "HDMI: pin nid %d not registered\n", pin_nid); return -EINVAL; @@ -724,10 +753,11 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); -static void check_presence_and_report(struct hda_codec *codec, hda_nid_t nid) +static void check_presence_and_report(struct hda_codec *codec, hda_nid_t nid, + int dev_id) { struct hdmi_spec *spec = codec->spec; - int pin_idx = pin_nid_to_pin_index(codec, nid); + int pin_idx = pin_id_to_pin_index(codec, nid, dev_id); if (pin_idx < 0) return; @@ -738,7 +768,8 @@ static void check_presence_and_report(struct hda_codec *codec, hda_nid_t nid) static void jack_callback(struct hda_codec *codec, struct hda_jack_callback *jack) { - check_presence_and_report(codec, jack->nid); + /* hda_jack don't support DP MST */ + check_presence_and_report(codec, jack->nid, 0); } static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) @@ -747,6 +778,12 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) struct hda_jack_tbl *jack; int dev_entry = (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT; + /* + * assume DP MST uses dyn_pcm_assign and acomp and + * never comes here + * if DP MST supports unsol event, below code need + * consider dev_entry + */ jack = snd_hda_jack_tbl_get_from_tag(codec, tag); if (!jack) return; @@ -757,7 +794,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) codec->addr, jack->nid, dev_entry, !!(res & AC_UNSOL_RES_IA), !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV)); - check_presence_and_report(codec, jack->nid); + /* hda_jack don't support DP MST */ + check_presence_and_report(codec, jack->nid, 0); } static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) @@ -970,28 +1008,60 @@ static int intel_cvt_id_to_mux_idx(struct hdmi_spec *spec, * by any other pins. */ static void intel_not_share_assigned_cvt(struct hda_codec *codec, - hda_nid_t pin_nid, int mux_idx) + hda_nid_t pin_nid, + int dev_id, int mux_idx) { struct hdmi_spec *spec = codec->spec; hda_nid_t nid; int cvt_idx, curr; struct hdmi_spec_per_cvt *per_cvt; + struct hdmi_spec_per_pin *per_pin; + int pin_idx; + + /* configure the pins connections */ + for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { + int dev_id_saved; + int dev_num; - /* configure all pins, including "no physical connection" ones */ - for_each_hda_codec_node(nid, codec) { - unsigned int wid_caps = get_wcaps(codec, nid); - unsigned int wid_type = get_wcaps_type(wid_caps); + per_pin = get_pin(spec, pin_idx); + /* + * pin not connected to monitor + * no need to operate on it + */ + if (!per_pin->pcm) + continue; - if (wid_type != AC_WID_PIN) + if ((per_pin->pin_nid == pin_nid) && + (per_pin->dev_id == dev_id)) continue; - if (nid == pin_nid) + /* + * if per_pin->dev_id >= dev_num, + * snd_hda_get_dev_select() will fail, + * and the following operation is unpredictable. + * So skip this situation. + */ + dev_num = snd_hda_get_num_devices(codec, per_pin->pin_nid) + 1; + if (per_pin->dev_id >= dev_num) continue; + nid = per_pin->pin_nid; + + /* + * Calling this function should not impact + * on the device entry selection + * So let's save the dev id for each pin, + * and restore it when return + */ + dev_id_saved = snd_hda_get_dev_select(codec, nid); + snd_hda_set_dev_select(codec, nid, per_pin->dev_id); curr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); - if (curr != mux_idx) + if (curr != mux_idx) { + snd_hda_set_dev_select(codec, nid, dev_id_saved); continue; + } + /* choose an unassigned converter. The conveters in the * connection list are in the same order as in the codec. @@ -1008,12 +1078,13 @@ static void intel_not_share_assigned_cvt(struct hda_codec *codec, break; } } + snd_hda_set_dev_select(codec, nid, dev_id_saved); } } /* A wrapper of intel_not_share_asigned_cvt() */ static void intel_not_share_assigned_cvt_nid(struct hda_codec *codec, - hda_nid_t pin_nid, hda_nid_t cvt_nid) + hda_nid_t pin_nid, int dev_id, hda_nid_t cvt_nid) { int mux_idx; struct hdmi_spec *spec = codec->spec; @@ -1025,7 +1096,7 @@ static void intel_not_share_assigned_cvt_nid(struct hda_codec *codec, */ mux_idx = intel_cvt_id_to_mux_idx(spec, cvt_nid); if (mux_idx >= 0) - intel_not_share_assigned_cvt(codec, pin_nid, mux_idx); + intel_not_share_assigned_cvt(codec, pin_nid, dev_id, mux_idx); } /* skeleton caller of pin_cvt_fixup ops */ @@ -1140,6 +1211,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, per_pin->cvt_nid = per_cvt->cvt_nid; hinfo->nid = per_cvt->cvt_nid; + snd_hda_set_dev_select(codec, per_pin->pin_nid, per_pin->dev_id); snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0, AC_VERB_SET_CONNECT_SEL, per_pin->mux_idx); @@ -1198,6 +1270,7 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) return -EINVAL; } + /* all the device entries on the same pin have the same conn list */ per_pin->num_mux_nids = snd_hda_get_connections(codec, pin_nid, per_pin->mux_nids, HDA_MAX_CONNECTIONS); @@ -1215,13 +1288,13 @@ static int hdmi_find_pcm_slot(struct hdmi_spec *spec, return per_pin->pin_nid_idx; /* have a second try; check the "reserved area" over num_pins */ - for (i = spec->num_pins; i < spec->pcm_used; i++) { + for (i = spec->num_nids; i < spec->pcm_used; i++) { if (!test_bit(i, &spec->pcm_bitmap)) return i; } /* the last try; check the empty slots in pins */ - for (i = 0; i < spec->num_pins; i++) { + for (i = 0; i < spec->num_nids; i++) { if (!test_bit(i, &spec->pcm_bitmap)) return i; } @@ -1296,10 +1369,13 @@ static void hdmi_pcm_setup_pin(struct hdmi_spec *spec, per_pin->cvt_nid = hinfo->nid; mux_idx = hdmi_get_pin_cvt_mux(spec, per_pin, hinfo->nid); - if (mux_idx < per_pin->num_mux_nids) + if (mux_idx < per_pin->num_mux_nids) { + snd_hda_set_dev_select(codec, per_pin->pin_nid, + per_pin->dev_id); snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0, AC_VERB_SET_CONNECT_SEL, mux_idx); + } snd_hda_spdif_ctls_assign(codec, per_pin->pcm_idx, hinfo->nid); non_pcm = check_non_pcm_per_cvt(codec, hinfo->nid); @@ -1467,6 +1543,11 @@ static struct snd_jack *pin_idx_to_jack(struct hda_codec *codec, if (per_pin->pcm_idx >= 0 && spec->dyn_pcm_assign) jack = spec->pcm_rec[per_pin->pcm_idx].jack; else if (!spec->dyn_pcm_assign) { + /* + * jack tbl doesn't support DP MST + * DP MST will use dyn_pcm_assign, + * so DP MST will never come here + */ jack_tbl = snd_hda_jack_tbl_get(codec, per_pin->pin_nid); if (jack_tbl) jack = jack_tbl->jack; @@ -1485,9 +1566,9 @@ static void sync_eld_via_acomp(struct hda_codec *codec, mutex_lock(&per_pin->lock); eld->monitor_present = false; - size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1, - &eld->monitor_present, eld->eld_buffer, - ELD_MAX_SIZE); + size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, + per_pin->dev_id, &eld->monitor_present, + eld->eld_buffer, ELD_MAX_SIZE); if (size > 0) { size = min(size, ELD_MAX_SIZE); if (snd_hdmi_parse_eld(codec, &eld->info, @@ -1565,38 +1646,81 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) int pin_idx; struct hdmi_spec_per_pin *per_pin; int err; + int dev_num, i; caps = snd_hda_query_pin_caps(codec, pin_nid); if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) return 0; + /* + * For DP MST audio, Configuration Default is the same for + * all device entries on the same pin + */ config = snd_hda_codec_get_pincfg(codec, pin_nid); if (get_defcfg_connect(config) == AC_JACK_PORT_NONE) return 0; - if (is_haswell_plus(codec)) - intel_haswell_fixup_connect_list(codec, pin_nid); - - pin_idx = spec->num_pins; - per_pin = snd_array_new(&spec->pins); - if (!per_pin) - return -ENOMEM; - - per_pin->pin_nid = pin_nid; - per_pin->non_pcm = false; - if (spec->dyn_pcm_assign) - per_pin->pcm_idx = -1; - else { - per_pin->pcm = get_hdmi_pcm(spec, pin_idx); - per_pin->pcm_idx = pin_idx; + /* + * To simplify the implementation, malloc all + * the virtual pins in the initialization statically + */ + if (is_haswell_plus(codec)) { + /* + * On Intel platforms, device entries number is + * changed dynamically. If there is a DP MST + * hub connected, the device entries number is 3. + * Otherwise, it is 1. + * Here we manually set dev_num to 3, so that + * we can initialize all the device entries when + * bootup statically. + */ + dev_num = 3; + spec->dev_num = 3; + } else if (spec->dyn_pcm_assign && codec->dp_mst) { + dev_num = snd_hda_get_num_devices(codec, pin_nid) + 1; + /* + * spec->dev_num is the maxinum number of device entries + * among all the pins + */ + spec->dev_num = (spec->dev_num > dev_num) ? + spec->dev_num : dev_num; + } else { + /* + * If the platform doesn't support DP MST, + * manually set dev_num to 1. This means + * the pin has only one device entry. + */ + dev_num = 1; + spec->dev_num = 1; } - per_pin->pin_nid_idx = pin_idx; - err = hdmi_read_pin_conn(codec, pin_idx); - if (err < 0) - return err; + for (i = 0; i < dev_num; i++) { + pin_idx = spec->num_pins; + per_pin = snd_array_new(&spec->pins); - spec->num_pins++; + if (!per_pin) + return -ENOMEM; + + if (spec->dyn_pcm_assign) { + per_pin->pcm = NULL; + per_pin->pcm_idx = -1; + } else { + per_pin->pcm = get_hdmi_pcm(spec, pin_idx); + per_pin->pcm_idx = pin_idx; + } + per_pin->pin_nid = pin_nid; + per_pin->pin_nid_idx = spec->num_nids; + per_pin->dev_id = i; + per_pin->non_pcm = false; + snd_hda_set_dev_select(codec, pin_nid, i); + if (is_haswell_plus(codec)) + intel_haswell_fixup_connect_list(codec, pin_nid); + err = hdmi_read_pin_conn(codec, pin_idx); + if (err < 0) + return err; + spec->num_pins++; + } + spec->num_nids++; return 0; } @@ -1744,7 +1868,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, /* Call sync_audio_rate to set the N/CTS/M manually if necessary */ /* Todo: add DP1.2 MST audio support later */ if (codec_has_acomp(codec)) - snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1, + snd_hdac_sync_audio_rate(&codec->core, pin_nid, per_pin->dev_id, runtime->rate); non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); @@ -1762,6 +1886,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, pinctl | PIN_OUT); } + /* snd_hda_set_dev_select() has been called before */ err = spec->ops.setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); mutex_unlock(&spec->pcm_lock); @@ -1897,17 +2022,23 @@ static bool is_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx) static int generic_hdmi_build_pcms(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; - int pin_idx; + int idx; - for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { + /* + * for non-mst mode, pcm number is the same as before + * for DP MST mode, pcm number is (nid number + dev_num - 1) + * dev_num is the device entry number in a pin + * + */ + for (idx = 0; idx < spec->num_nids + spec->dev_num - 1; idx++) { struct hda_pcm *info; struct hda_pcm_stream *pstr; - info = snd_hda_codec_pcm_new(codec, "HDMI %d", pin_idx); + info = snd_hda_codec_pcm_new(codec, "HDMI %d", idx); if (!info) return -ENOMEM; - spec->pcm_rec[pin_idx].pcm = info; + spec->pcm_rec[idx].pcm = info; spec->pcm_used++; info->pcm_type = HDA_PCM_TYPE_HDMI; info->own_chmap = true; @@ -1915,6 +2046,9 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; pstr->substreams = 1; pstr->ops = generic_ops; + /* pcm number is less than 16 */ + if (spec->pcm_used >= 16) + break; /* other pstr fields are set in open */ } @@ -2070,7 +2204,9 @@ static int generic_hdmi_init(struct hda_codec *codec) for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); hda_nid_t pin_nid = per_pin->pin_nid; + int dev_id = per_pin->dev_id; + snd_hda_set_dev_select(codec, pin_nid, dev_id); hdmi_init_pin(codec, pin_nid); if (!codec_has_acomp(codec)) snd_hda_jack_detect_enable_callback(codec, pin_nid, @@ -2178,6 +2314,7 @@ static int alloc_generic_hdmi(struct hda_codec *codec) return -ENOMEM; spec->ops = generic_standard_hdmi_ops; + spec->dev_num = 1; /* initialize to 1 */ mutex_init(&spec->pcm_lock); snd_hdac_register_chmap_ops(&codec->core, &spec->chmap); @@ -2295,6 +2432,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe) { struct hda_codec *codec = audio_ptr; int pin_nid; + int dev_id = pipe; /* we assume only from port-B to port-D */ if (port < 1 || port > 3) @@ -2321,7 +2459,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe) return; snd_hdac_i915_set_bclk(&codec->bus->core); - check_presence_and_report(codec, pin_nid); + check_presence_and_report(codec, pin_nid, dev_id); } /* register i915 component pin_eld_notify callback */ @@ -2354,11 +2492,13 @@ static void i915_pin_cvt_fixup(struct hda_codec *codec, hda_nid_t cvt_nid) { if (per_pin) { + snd_hda_set_dev_select(codec, per_pin->pin_nid, + per_pin->dev_id); intel_verify_pin_cvt_connect(codec, per_pin); intel_not_share_assigned_cvt(codec, per_pin->pin_nid, - per_pin->mux_idx); + per_pin->dev_id, per_pin->mux_idx); } else { - intel_not_share_assigned_cvt_nid(codec, 0, cvt_nid); + intel_not_share_assigned_cvt_nid(codec, 0, 0, cvt_nid); } } @@ -2378,6 +2518,8 @@ static int patch_i915_hsw_hdmi(struct hda_codec *codec) if (err < 0) return err; spec = codec->spec; + codec->dp_mst = true; + spec->dyn_pcm_assign = true; intel_haswell_enable_all_pins(codec, true); intel_haswell_fixup_enable_dp12(codec); @@ -2389,7 +2531,6 @@ static int patch_i915_hsw_hdmi(struct hda_codec *codec) codec->core.link_power_control = 1; codec->patch_ops.set_power_state = haswell_set_power_state; - codec->dp_mst = true; codec->depop_delay = 0; codec->auto_runtime_pm = 1; @@ -3659,6 +3800,7 @@ HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_i915_hsw_hdmi), HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_i915_hsw_hdmi), HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_i915_hsw_hdmi), HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_i915_hsw_hdmi), +HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_hsw_hdmi), HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi), HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi), diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f3919bb45af6..c5f2489f0906 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4849,6 +4849,7 @@ enum { ALC286_FIXUP_HP_GPIO_LED, ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, ALC280_FIXUP_HP_DOCK_PINS, + ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, ALC280_FIXUP_HP_9480M, ALC288_FIXUP_DELL_HEADSET_MODE, ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, @@ -5413,6 +5414,16 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC280_FIXUP_HP_GPIO4 }, + [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x1b, 0x21011020 }, /* line-out */ + { 0x18, 0x2181103f }, /* line-in */ + { }, + }, + .chained = true, + .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED + }, [ALC280_FIXUP_HP_9480M] = { .type = HDA_FIXUP_FUNC, .v.func = alc280_fixup_hp_9480m, @@ -5675,6 +5686,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE), SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME), + SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), @@ -5715,7 +5727,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), - SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), @@ -5805,6 +5817,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460), SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), + SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), @@ -5895,6 +5908,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"}, {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, + {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"}, {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, diff --git a/sound/pci/ice1712/wm8766.c b/sound/pci/ice1712/wm8766.c index f7ac8d5e862c..27c03e40c9b1 100644 --- a/sound/pci/ice1712/wm8766.c +++ b/sound/pci/ice1712/wm8766.c @@ -254,7 +254,7 @@ static int snd_wm8766_ctl_put(struct snd_kcontrol *kcontrol, int n = kcontrol->private_value; u16 val, regval1, regval2; - /* this also works for enum because value is an union */ + /* this also works for enum because value is a union */ regval1 = ucontrol->value.integer.value[0]; regval2 = ucontrol->value.integer.value[1]; if (wm->ctl[n].flags & WM8766_FLAG_INVERT) { diff --git a/sound/pci/ice1712/wm8776.c b/sound/pci/ice1712/wm8776.c index ebd2fe4b4a57..553669b103c2 100644 --- a/sound/pci/ice1712/wm8776.c +++ b/sound/pci/ice1712/wm8776.c @@ -528,7 +528,7 @@ static int snd_wm8776_ctl_put(struct snd_kcontrol *kcontrol, int n = kcontrol->private_value; u16 val, regval1, regval2; - /* this also works for enum because value is an union */ + /* this also works for enum because value is a union */ regval1 = ucontrol->value.integer.value[0]; regval2 = ucontrol->value.integer.value[1]; if (wm->ctl[n].flags & WM8776_FLAG_INVERT) { diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 565f7f55c3ca..1e25095fd144 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -2051,7 +2051,7 @@ static void snd_korg1212_proc_read(struct snd_info_entry *entry, snd_iprintf(buffer, korg1212->card->longname); snd_iprintf(buffer, " (index #%d)\n", korg1212->card->number + 1); snd_iprintf(buffer, "\nGeneral settings\n"); - snd_iprintf(buffer, " period size: %Zd bytes\n", K1212_PERIOD_BYTES); + snd_iprintf(buffer, " period size: %zd bytes\n", K1212_PERIOD_BYTES); snd_iprintf(buffer, " clock mode: %s\n", clockSourceName[korg1212->clkSrcRate] ); snd_iprintf(buffer, " left ADC Sens: %d\n", korg1212->leftADCInSens ); snd_iprintf(buffer, " right ADC Sens: %d\n", korg1212->rightADCInSens ); @@ -2276,7 +2276,7 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci, if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), sizeof(struct KorgSharedBuffer), &korg1212->dma_shared) < 0) { - snd_printk(KERN_ERR "korg1212: can not allocate shared buffer memory (%Zd bytes)\n", sizeof(struct KorgSharedBuffer)); + snd_printk(KERN_ERR "korg1212: can not allocate shared buffer memory (%zd bytes)\n", sizeof(struct KorgSharedBuffer)); snd_korg1212_free(korg1212); return -ENOMEM; } diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c index 80633055e17e..a99808ab01fe 100644 --- a/sound/pci/pcxhr/pcxhr_hwdep.c +++ b/sound/pci/pcxhr/pcxhr_hwdep.c @@ -292,7 +292,7 @@ static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, int err, card_index; dev_dbg(&mgr->pci->dev, - "loading dsp [%d] size = %Zd\n", index, dsp->size); + "loading dsp [%d] size = %zd\n", index, dsp->size); switch (index) { case PCXHR_FIRMWARE_XLX_INT_INDEX: diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c index 56aa1ba73ccc..5f97791f00d7 100644 --- a/sound/pcmcia/vx/vxp_ops.c +++ b/sound/pcmcia/vx/vxp_ops.c @@ -201,7 +201,7 @@ static int vxp_load_xilinx_binary(struct vx_core *_chip, const struct firmware * c |= (int)vx_inb(chip, RXM) << 8; c |= vx_inb(chip, RXL); - snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%Zx\n", c, fw->size); + snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%zx\n", c, fw->size); vx_outb(chip, ICR, ICR_HF0); diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index b84d7d34f188..cdd44abfc9e0 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c @@ -883,7 +883,7 @@ static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) static void snd_ps3_audio_fixup(struct snd_ps3_card_info *card) { /* - * avsetting driver seems to never change the followings + * avsetting driver seems to never change the following * so, init them here once */ diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 818b052377f3..08b1399d1da2 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -89,7 +89,7 @@ static void acp_reg_write(u32 val, void __iomem *acp_mmio, u32 reg) writel(val, acp_mmio + (reg * 4)); } -/* Configure a given dma channel parameters - enable/disble, +/* Configure a given dma channel parameters - enable/disable, * number of descriptors, priority */ static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num, @@ -506,7 +506,7 @@ static int acp_init(void __iomem *acp_mmio) return 0; } -/* Deintialize ACP */ +/* Deinitialize ACP */ static int acp_deinit(void __iomem *acp_mmio) { u32 val; diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 624b3b9cb079..63b2745f8169 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -1269,7 +1269,7 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_ON: - /* Turn off any unneded single ended outputs */ + /* Turn off any unneeded single ended outputs */ val = 0; mask = 0; diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 1d82f68305c3..8cfffa70c144 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -368,7 +368,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair) fsl_asrc_set_watermarks(pair, ASRC_INPUTFIFO_THRESHOLD, ASRC_INPUTFIFO_THRESHOLD); - /* Configure the followings only for Ideal Ratio mode */ + /* Configure the following only for Ideal Ratio mode */ if (!ideal) return 0; diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h index 924971b6ded5..9b031352ea3c 100644 --- a/sound/soc/qcom/lpass.h +++ b/sound/soc/qcom/lpass.h @@ -82,7 +82,7 @@ struct lpass_variant { **/ u32 dmactl_audif_start; u32 wrdma_channel_start; - /* SOC specific intialization like clocks */ + /* SOC specific initialization like clocks */ int (*init)(struct platform_device *pdev); int (*exit)(struct platform_device *pdev); int (*alloc_dma_channel)(struct lpass_data *data, int direction); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a110d3987d4a..6dca408faae3 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3041,7 +3041,7 @@ static int snd_soc_register_dais(struct snd_soc_component *component, unsigned int i; int ret; - dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count); + dev_dbg(dev, "ASoC: dai register %s #%zu\n", dev_name(dev), count); component->dai_drv = dai_drv; diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index aff3d8129ac9..3e9b1c0bb1ce 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -344,7 +344,7 @@ static int soc_tplg_widget_load(struct soc_tplg *tplg, return 0; } -/* pass DAI configurations to component driver for extra intialization */ +/* pass DAI configurations to component driver for extra initialization */ static int soc_tplg_dai_load(struct soc_tplg *tplg, struct snd_soc_dai_driver *dai_drv) { @@ -354,7 +354,7 @@ static int soc_tplg_dai_load(struct soc_tplg *tplg, return 0; } -/* pass link configurations to component driver for extra intialization */ +/* pass link configurations to component driver for extra initialization */ static int soc_tplg_dai_link_load(struct soc_tplg *tplg, struct snd_soc_dai_link *link) { diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c index 7ac45ec372b9..dc48eedea92e 100644 --- a/sound/usb/mixer_us16x08.c +++ b/sound/usb/mixer_us16x08.c @@ -176,15 +176,9 @@ static int snd_us16x08_recv_urb(struct snd_usb_audio *chip, */ static int snd_us16x08_send_urb(struct snd_usb_audio *chip, char *buf, int size) { - int err = 0; - - if (chip) { - err = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), + return snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), SND_US16X08_URB_REQUEST, SND_US16X08_URB_REQUESTTYPE, 0, 0, buf, size); - } - - return err; } static int snd_us16x08_route_info(struct snd_kcontrol *kcontrol, @@ -212,10 +206,7 @@ static int snd_us16x08_route_put(struct snd_kcontrol *kcontrol, struct snd_usb_audio *chip = elem->head.mixer->chip; int index = ucontrol->id.index; char buf[sizeof(route_msg)]; - int val, val_org, err = 0; - - /* prepare the message buffer from template */ - memcpy(buf, route_msg, sizeof(route_msg)); + int val, val_org, err; /* get the new value (no bias for routes) */ val = ucontrol->value.enumerated.item[0]; @@ -224,6 +215,9 @@ static int snd_us16x08_route_put(struct snd_kcontrol *kcontrol, if (val < 0 || val > 9) return -EINVAL; + /* prepare the message buffer from template */ + memcpy(buf, route_msg, sizeof(route_msg)); + if (val < 2) { /* input comes from a master channel */ val_org = val; @@ -279,12 +273,9 @@ static int snd_us16x08_master_put(struct snd_kcontrol *kcontrol, struct usb_mixer_elem_info *elem = kcontrol->private_data; struct snd_usb_audio *chip = elem->head.mixer->chip; char buf[sizeof(mix_msg_out)]; - int val, err = 0; + int val, err; int index = ucontrol->id.index; - /* prepare the message buffer from template */ - memcpy(buf, mix_msg_out, sizeof(mix_msg_out)); - /* new control value incl. bias*/ val = ucontrol->value.integer.value[0]; @@ -293,6 +284,9 @@ static int snd_us16x08_master_put(struct snd_kcontrol *kcontrol, || val > SND_US16X08_KCMAX(kcontrol)) return -EINVAL; + /* prepare the message buffer from template */ + memcpy(buf, mix_msg_out, sizeof(mix_msg_out)); + buf[8] = val - SND_US16X08_KCBIAS(kcontrol); buf[6] = elem->head.id; @@ -392,9 +386,6 @@ static int snd_us16x08_channel_put(struct snd_kcontrol *kcontrol, int val, err; int index = ucontrol->id.index; - /* prepare URB message from template */ - memcpy(buf, mix_msg_in, sizeof(mix_msg_in)); - val = ucontrol->value.integer.value[0]; /* sanity check */ @@ -402,6 +393,9 @@ static int snd_us16x08_channel_put(struct snd_kcontrol *kcontrol, || val > SND_US16X08_KCMAX(kcontrol)) return -EINVAL; + /* prepare URB message from template */ + memcpy(buf, mix_msg_in, sizeof(mix_msg_in)); + /* add the bias to the new value */ buf[8] = val - SND_US16X08_KCBIAS(kcontrol); buf[6] = elem->head.id; @@ -434,8 +428,7 @@ static int snd_us16x08_comp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct usb_mixer_elem_info *elem = kcontrol->private_data; - struct snd_us16x08_comp_store *store = - ((struct snd_us16x08_comp_store *) elem->private_data); + struct snd_us16x08_comp_store *store = elem->private_data; int index = ucontrol->id.index; int val_idx = COMP_STORE_IDX(elem->head.id); @@ -449,18 +442,11 @@ static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol, { struct usb_mixer_elem_info *elem = kcontrol->private_data; struct snd_usb_audio *chip = elem->head.mixer->chip; - struct snd_us16x08_comp_store *store = - ((struct snd_us16x08_comp_store *) elem->private_data); + struct snd_us16x08_comp_store *store = elem->private_data; int index = ucontrol->id.index; char buf[sizeof(comp_msg)]; int val_idx, val; - int err = 0; - - /* prepare compressor URB message from template */ - memcpy(buf, comp_msg, sizeof(comp_msg)); - - /* new control value incl. bias*/ - val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE; + int err; val = ucontrol->value.integer.value[0]; @@ -469,8 +455,14 @@ static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol, || val > SND_US16X08_KCMAX(kcontrol)) return -EINVAL; + /* new control value incl. bias*/ + val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE; + store->val[val_idx][index] = ucontrol->value.integer.value[0]; + /* prepare compressor URB message from template */ + memcpy(buf, comp_msg, sizeof(comp_msg)); + /* place comp values in message buffer watch bias! */ buf[8] = store->val[ COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index] @@ -502,10 +494,9 @@ static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol, static int snd_us16x08_eqswitch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - int val = 0; + int val; struct usb_mixer_elem_info *elem = kcontrol->private_data; - struct snd_us16x08_eq_store *store = - ((struct snd_us16x08_eq_store *) elem->private_data); + struct snd_us16x08_eq_store *store = elem->private_data; int index = ucontrol->id.index; /* get low switch from cache is enough, cause all bands are together */ @@ -521,10 +512,8 @@ static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol, { struct usb_mixer_elem_info *elem = kcontrol->private_data; struct snd_usb_audio *chip = elem->head.mixer->chip; - struct snd_us16x08_eq_store *store = - ((struct snd_us16x08_eq_store *) elem->private_data); + struct snd_us16x08_eq_store *store = elem->private_data; int index = ucontrol->id.index; - char buf[sizeof(eqs_msq)]; int val, err = 0; int b_idx; @@ -564,10 +553,9 @@ static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol, static int snd_us16x08_eq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - int val = 0; + int val; struct usb_mixer_elem_info *elem = kcontrol->private_data; - struct snd_us16x08_eq_store *store = - ((struct snd_us16x08_eq_store *) elem->private_data); + struct snd_us16x08_eq_store *store = elem->private_data; int index = ucontrol->id.index; int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1; int p_idx = EQ_STORE_PARAM_IDX(elem->head.id); @@ -584,17 +572,13 @@ static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol, { struct usb_mixer_elem_info *elem = kcontrol->private_data; struct snd_usb_audio *chip = elem->head.mixer->chip; - struct snd_us16x08_eq_store *store = - ((struct snd_us16x08_eq_store *) elem->private_data); + struct snd_us16x08_eq_store *store = elem->private_data; int index = ucontrol->id.index; char buf[sizeof(eqs_msq)]; - int val, err = 0; + int val, err; int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1; int p_idx = EQ_STORE_PARAM_IDX(elem->head.id); - /* copy URB buffer from EQ template */ - memcpy(buf, eqs_msq, sizeof(eqs_msq)); - val = ucontrol->value.integer.value[0]; /* sanity check */ @@ -602,6 +586,9 @@ static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol, || val > SND_US16X08_KCMAX(kcontrol)) return -EINVAL; + /* copy URB buffer from EQ template */ + memcpy(buf, eqs_msq, sizeof(eqs_msq)); + store->val[b_idx][p_idx][index] = val; buf[20] = store->val[b_idx][3][index]; buf[17] = store->val[b_idx][2][index]; @@ -711,18 +698,12 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, struct snd_usb_audio *chip = elem->head.mixer->chip; struct snd_us16x08_meter_store *store = elem->private_data; u8 meter_urb[64]; - char tmp[max(sizeof(mix_init_msg1), sizeof(mix_init_msg2))]; - - if (elem) { - store = (struct snd_us16x08_meter_store *) elem->private_data; - chip = elem->head.mixer->chip; - } else - return 0; + char tmp[sizeof(mix_init_msg2)] = {0}; switch (kcontrol->private_value) { case 0: - memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1)); - snd_us16x08_send_urb(chip, tmp, 4); + snd_us16x08_send_urb(chip, (char *)mix_init_msg1, + sizeof(mix_init_msg1)); snd_us16x08_recv_urb(chip, meter_urb, sizeof(meter_urb)); kcontrol->private_value++; @@ -740,7 +721,7 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, case 3: memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2)); tmp[2] = snd_get_meter_comp_index(store); - snd_us16x08_send_urb(chip, tmp, 10); + snd_us16x08_send_urb(chip, tmp, sizeof(mix_init_msg2)); snd_us16x08_recv_urb(chip, meter_urb, sizeof(meter_urb)); kcontrol->private_value = 0; @@ -983,11 +964,11 @@ static struct snd_kcontrol_new snd_us16x08_meter_ctl = { /* setup compressor store and assign default value */ static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void) { - int i = 0; - struct snd_us16x08_comp_store *tmp = - kmalloc(sizeof(struct snd_us16x08_comp_store), GFP_KERNEL); + int i; + struct snd_us16x08_comp_store *tmp; - if (tmp == NULL) + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) return NULL; for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) { @@ -1006,10 +987,10 @@ static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void) static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void) { int i, b_idx; - struct snd_us16x08_eq_store *tmp = - kmalloc(sizeof(struct snd_us16x08_eq_store), GFP_KERNEL); + struct snd_us16x08_eq_store *tmp; - if (tmp == NULL) + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) return NULL; for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) { @@ -1042,22 +1023,32 @@ static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void) static struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void) { - struct snd_us16x08_meter_store *tmp = - kzalloc(sizeof(struct snd_us16x08_meter_store), GFP_KERNEL); + struct snd_us16x08_meter_store *tmp; + tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); if (!tmp) return NULL; tmp->comp_index = 1; tmp->comp_active_index = 0; return tmp; +} + +/* release elem->private_free as well; called only once for each *_store */ +static void elem_private_free(struct snd_kcontrol *kctl) +{ + struct usb_mixer_elem_info *elem = kctl->private_data; + if (elem) + kfree(elem->private_data); + kfree(elem); + kctl->private_data = NULL; } static int add_new_ctl(struct usb_mixer_interface *mixer, const struct snd_kcontrol_new *ncontrol, int index, int val_type, int channels, - const char *name, const void *opt, - void (*freeer)(struct snd_kcontrol *kctl), + const char *name, void *opt, + bool do_private_free, struct usb_mixer_elem_info **elem_ret) { struct snd_kcontrol *kctl; @@ -1077,7 +1068,7 @@ static int add_new_ctl(struct usb_mixer_interface *mixer, elem->head.id = index; elem->val_type = val_type; elem->channels = channels; - elem->private_data = (void *) opt; + elem->private_data = opt; kctl = snd_ctl_new1(ncontrol, elem); if (!kctl) { @@ -1085,7 +1076,10 @@ static int add_new_ctl(struct usb_mixer_interface *mixer, return -ENOMEM; } - kctl->private_free = freeer; + if (do_private_free) + kctl->private_free = elem_private_free; + else + kctl->private_free = snd_usb_mixer_elem_free; strlcpy(kctl->id.name, name, sizeof(kctl->id.name)); @@ -1099,17 +1093,14 @@ static int add_new_ctl(struct usb_mixer_interface *mixer, return 0; } -static struct snd_us16x08_control_params control_params; - /* table of EQ controls */ -static struct snd_us16x08_control_params eq_controls[] = { +static const struct snd_us16x08_control_params eq_controls[] = { { /* EQ switch */ .kcontrol_new = &snd_us16x08_eq_switch_ctl, .control_id = SND_US16X08_ID_EQENABLE, .type = USB_MIXER_BOOLEAN, .num_channels = 16, .name = "EQ Switch", - .freeer = snd_usb_mixer_elem_free }, { /* EQ low gain */ .kcontrol_new = &snd_us16x08_eq_gain_ctl, @@ -1117,7 +1108,6 @@ static struct snd_us16x08_control_params eq_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "EQ Low Volume", - .freeer = snd_usb_mixer_elem_free }, { /* EQ low freq */ .kcontrol_new = &snd_us16x08_eq_low_freq_ctl, @@ -1125,7 +1115,6 @@ static struct snd_us16x08_control_params eq_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "EQ Low Frequence", - .freeer = NULL }, { /* EQ mid low gain */ .kcontrol_new = &snd_us16x08_eq_gain_ctl, @@ -1133,7 +1122,6 @@ static struct snd_us16x08_control_params eq_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "EQ MidLow Volume", - .freeer = snd_usb_mixer_elem_free }, { /* EQ mid low freq */ .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl, @@ -1141,7 +1129,6 @@ static struct snd_us16x08_control_params eq_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "EQ MidLow Frequence", - .freeer = NULL }, { /* EQ mid low Q */ .kcontrol_new = &snd_us16x08_eq_mid_width_ctl, @@ -1149,7 +1136,6 @@ static struct snd_us16x08_control_params eq_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "EQ MidQLow Q", - .freeer = NULL }, { /* EQ mid high gain */ .kcontrol_new = &snd_us16x08_eq_gain_ctl, @@ -1157,7 +1143,6 @@ static struct snd_us16x08_control_params eq_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "EQ MidHigh Volume", - .freeer = snd_usb_mixer_elem_free }, { /* EQ mid high freq */ .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl, @@ -1165,7 +1150,6 @@ static struct snd_us16x08_control_params eq_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "EQ MidHigh Frequence", - .freeer = NULL }, { /* EQ mid high Q */ .kcontrol_new = &snd_us16x08_eq_mid_width_ctl, @@ -1173,7 +1157,6 @@ static struct snd_us16x08_control_params eq_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "EQ MidHigh Q", - .freeer = NULL }, { /* EQ high gain */ .kcontrol_new = &snd_us16x08_eq_gain_ctl, @@ -1181,7 +1164,6 @@ static struct snd_us16x08_control_params eq_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "EQ High Volume", - .freeer = snd_usb_mixer_elem_free }, { /* EQ low freq */ .kcontrol_new = &snd_us16x08_eq_high_freq_ctl, @@ -1189,19 +1171,17 @@ static struct snd_us16x08_control_params eq_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "EQ High Frequence", - .freeer = NULL }, }; /* table of compressor controls */ -static struct snd_us16x08_control_params comp_controls[] = { +static const struct snd_us16x08_control_params comp_controls[] = { { /* Comp enable */ .kcontrol_new = &snd_us16x08_compswitch_ctl, .control_id = SND_US16X08_ID_COMP_SWITCH, .type = USB_MIXER_BOOLEAN, .num_channels = 16, .name = "Compressor Switch", - .freeer = snd_usb_mixer_elem_free }, { /* Comp threshold */ .kcontrol_new = &snd_us16x08_comp_threshold_ctl, @@ -1209,7 +1189,6 @@ static struct snd_us16x08_control_params comp_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "Compressor Threshold Volume", - .freeer = NULL }, { /* Comp ratio */ .kcontrol_new = &snd_us16x08_comp_ratio_ctl, @@ -1217,7 +1196,6 @@ static struct snd_us16x08_control_params comp_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "Compressor Ratio", - .freeer = NULL }, { /* Comp attack */ .kcontrol_new = &snd_us16x08_comp_attack_ctl, @@ -1225,7 +1203,6 @@ static struct snd_us16x08_control_params comp_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "Compressor Attack", - .freeer = NULL }, { /* Comp release */ .kcontrol_new = &snd_us16x08_comp_release_ctl, @@ -1233,7 +1210,6 @@ static struct snd_us16x08_control_params comp_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "Compressor Release", - .freeer = NULL }, { /* Comp gain */ .kcontrol_new = &snd_us16x08_comp_gain_ctl, @@ -1241,19 +1217,17 @@ static struct snd_us16x08_control_params comp_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "Compressor Volume", - .freeer = NULL }, }; /* table of channel controls */ -static struct snd_us16x08_control_params channel_controls[] = { +static const struct snd_us16x08_control_params channel_controls[] = { { /* Phase */ .kcontrol_new = &snd_us16x08_ch_boolean_ctl, .control_id = SND_US16X08_ID_PHASE, .type = USB_MIXER_BOOLEAN, .num_channels = 16, .name = "Phase Switch", - .freeer = snd_usb_mixer_elem_free, .default_val = 0 }, { /* Fader */ @@ -1262,7 +1236,6 @@ static struct snd_us16x08_control_params channel_controls[] = { .type = USB_MIXER_U8, .num_channels = 16, .name = "Line Volume", - .freeer = NULL, .default_val = 127 }, { /* Mute */ @@ -1271,7 +1244,6 @@ static struct snd_us16x08_control_params channel_controls[] = { .type = USB_MIXER_BOOLEAN, .num_channels = 16, .name = "Mute Switch", - .freeer = NULL, .default_val = 0 }, { /* Pan */ @@ -1280,20 +1252,18 @@ static struct snd_us16x08_control_params channel_controls[] = { .type = USB_MIXER_U16, .num_channels = 16, .name = "Pan Left-Right Volume", - .freeer = NULL, .default_val = 127 }, }; /* table of master controls */ -static struct snd_us16x08_control_params master_controls[] = { +static const struct snd_us16x08_control_params master_controls[] = { { /* Master */ .kcontrol_new = &snd_us16x08_master_ctl, .control_id = SND_US16X08_ID_FADER, .type = USB_MIXER_U8, .num_channels = 16, .name = "Master Volume", - .freeer = NULL, .default_val = 127 }, { /* Bypass */ @@ -1302,7 +1272,6 @@ static struct snd_us16x08_control_params master_controls[] = { .type = USB_MIXER_BOOLEAN, .num_channels = 16, .name = "DSP Bypass Switch", - .freeer = NULL, .default_val = 0 }, { /* Buss out */ @@ -1311,7 +1280,6 @@ static struct snd_us16x08_control_params master_controls[] = { .type = USB_MIXER_BOOLEAN, .num_channels = 16, .name = "Buss Out Switch", - .freeer = NULL, .default_val = 0 }, { /* Master mute */ @@ -1320,7 +1288,6 @@ static struct snd_us16x08_control_params master_controls[] = { .type = USB_MIXER_BOOLEAN, .num_channels = 16, .name = "Master Mute Switch", - .freeer = NULL, .default_val = 0 }, @@ -1338,30 +1305,10 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer) /* just check for non-MIDI interface */ if (mixer->hostif->desc.bInterfaceNumber == 3) { - /* create compressor mixer elements */ - comp_store = snd_us16x08_create_comp_store(); - if (comp_store == NULL) - return -ENOMEM; - - /* create eq store */ - eq_store = snd_us16x08_create_eq_store(); - if (eq_store == NULL) { - kfree(comp_store); - return -ENOMEM; - } - - /* create meters store */ - meter_store = snd_us16x08_create_meter_store(); - if (meter_store == NULL) { - kfree(comp_store); - kfree(eq_store); - return -ENOMEM; - } - /* add routing control */ err = add_new_ctl(mixer, &snd_us16x08_route_ctl, SND_US16X08_ID_ROUTE, USB_MIXER_U8, 8, "Line Out Route", - NULL, NULL, &elem); + NULL, false, &elem); if (err < 0) { usb_audio_dbg(mixer->chip, "Failed to create route control, err:%d\n", @@ -1372,11 +1319,13 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer) elem->cache_val[i] = i < 2 ? i : i + 2; elem->cached = 0xff; + /* create compressor mixer elements */ + comp_store = snd_us16x08_create_comp_store(); + if (!comp_store) + return -ENOMEM; + /* add master controls */ - for (i = 0; - i < sizeof(master_controls) - / sizeof(control_params); - i++) { + for (i = 0; i < ARRAY_SIZE(master_controls); i++) { err = add_new_ctl(mixer, master_controls[i].kcontrol_new, @@ -1385,7 +1334,8 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer) master_controls[i].num_channels, master_controls[i].name, comp_store, - master_controls[i].freeer, &elem); + i == 0, /* release comp_store only once */ + &elem); if (err < 0) return err; elem->cache_val[0] = master_controls[i].default_val; @@ -1393,10 +1343,7 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer) } /* add channel controls */ - for (i = 0; - i < sizeof(channel_controls) - / sizeof(control_params); - i++) { + for (i = 0; i < ARRAY_SIZE(channel_controls); i++) { err = add_new_ctl(mixer, channel_controls[i].kcontrol_new, @@ -1405,7 +1352,7 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer) channel_controls[i].num_channels, channel_controls[i].name, comp_store, - channel_controls[i].freeer, &elem); + false, &elem); if (err < 0) return err; for (j = 0; j < SND_US16X08_MAX_CHANNELS; j++) { @@ -1415,9 +1362,13 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer) elem->cached = 0xffff; } + /* create eq store */ + eq_store = snd_us16x08_create_eq_store(); + if (!eq_store) + return -ENOMEM; + /* add EQ controls */ - for (i = 0; i < sizeof(eq_controls) / - sizeof(control_params); i++) { + for (i = 0; i < ARRAY_SIZE(eq_controls); i++) { err = add_new_ctl(mixer, eq_controls[i].kcontrol_new, @@ -1426,16 +1377,14 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer) eq_controls[i].num_channels, eq_controls[i].name, eq_store, - eq_controls[i].freeer, NULL); + i == 0, /* release eq_store only once */ + NULL); if (err < 0) return err; } /* add compressor controls */ - for (i = 0; - i < sizeof(comp_controls) - / sizeof(control_params); - i++) { + for (i = 0; i < ARRAY_SIZE(comp_controls); i++) { err = add_new_ctl(mixer, comp_controls[i].kcontrol_new, @@ -1444,18 +1393,23 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer) comp_controls[i].num_channels, comp_controls[i].name, comp_store, - comp_controls[i].freeer, NULL); + false, NULL); if (err < 0) return err; } + /* create meters store */ + meter_store = snd_us16x08_create_meter_store(); + if (!meter_store) + return -ENOMEM; + /* meter function 'get' must access to compressor store * so place a reference here */ meter_store->comp_store = comp_store; err = add_new_ctl(mixer, &snd_us16x08_meter_ctl, SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter", - (void *) meter_store, snd_usb_mixer_elem_free, NULL); + meter_store, true, NULL); if (err < 0) return err; } diff --git a/sound/usb/mixer_us16x08.h b/sound/usb/mixer_us16x08.h index 64f89b5eca2d..a6312fb0f962 100644 --- a/sound/usb/mixer_us16x08.h +++ b/sound/usb/mixer_us16x08.h @@ -112,7 +112,6 @@ struct snd_us16x08_control_params { int type; int num_channels; const char *name; - void (*freeer)(struct snd_kcontrol *kctl); int default_val; }; diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index cf5dc33f4a6d..cf45bf1f7ee0 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c @@ -137,13 +137,12 @@ static void usb_stream_hwdep_vm_open(struct vm_area_struct *area) snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count)); } -static int usb_stream_hwdep_vm_fault(struct vm_area_struct *area, - struct vm_fault *vmf) +static int usb_stream_hwdep_vm_fault(struct vm_fault *vmf) { unsigned long offset; struct page *page; void *vaddr; - struct us122l *us122l = area->vm_private_data; + struct us122l *us122l = vmf->vma->vm_private_data; struct usb_stream *s; mutex_lock(&us122l->mutex); diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c index 0b34dbc8f302..605e1047c01d 100644 --- a/sound/usb/usx2y/usX2Yhwdep.c +++ b/sound/usb/usx2y/usX2Yhwdep.c @@ -31,19 +31,18 @@ #include "usbusx2y.h" #include "usX2Yhwdep.h" -static int snd_us428ctls_vm_fault(struct vm_area_struct *area, - struct vm_fault *vmf) +static int snd_us428ctls_vm_fault(struct vm_fault *vmf) { unsigned long offset; struct page * page; void *vaddr; snd_printdd("ENTER, start %lXh, pgoff %ld\n", - area->vm_start, + vmf->vma->vm_start, vmf->pgoff); offset = vmf->pgoff << PAGE_SHIFT; - vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->us428ctls_sharedmem + offset; + vaddr = (char *)((struct usX2Ydev *)vmf->vma->vm_private_data)->us428ctls_sharedmem + offset; page = virt_to_page(vaddr); get_page(page); vmf->page = page; diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index 90766a92e7fd..f95164b91152 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c @@ -652,14 +652,13 @@ static void snd_usX2Y_hwdep_pcm_vm_close(struct vm_area_struct *area) } -static int snd_usX2Y_hwdep_pcm_vm_fault(struct vm_area_struct *area, - struct vm_fault *vmf) +static int snd_usX2Y_hwdep_pcm_vm_fault(struct vm_fault *vmf) { unsigned long offset; void *vaddr; offset = vmf->pgoff << PAGE_SHIFT; - vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->hwdep_pcm_shm + offset; + vaddr = (char *)((struct usX2Ydev *)vmf->vma->vm_private_data)->hwdep_pcm_shm + offset; vmf->page = virt_to_page(vaddr); get_page(vmf->page); return 0; diff --git a/sound/x86/Kconfig b/sound/x86/Kconfig index 30d066e4885e..84c8f8fc597c 100644 --- a/sound/x86/Kconfig +++ b/sound/x86/Kconfig @@ -9,6 +9,7 @@ if SND_X86 config HDMI_LPE_AUDIO tristate "HDMI audio without HDaudio on Intel Atom platforms" depends on DRM_I915 + select SND_PCM help Choose this option to support HDMI LPE Audio mode diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 360cff35b239..c505b019e09c 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1082,7 +1082,8 @@ static int had_pcm_open(struct snd_pcm_substream *substream) return retval; error: - pm_runtime_put(intelhaddata->dev); + pm_runtime_mark_last_busy(intelhaddata->dev); + pm_runtime_put_autosuspend(intelhaddata->dev); return retval; } @@ -1106,7 +1107,8 @@ static int had_pcm_close(struct snd_pcm_substream *substream) } spin_unlock_irq(&intelhaddata->had_spinlock); - pm_runtime_put(intelhaddata->dev); + pm_runtime_mark_last_busy(intelhaddata->dev); + pm_runtime_put_autosuspend(intelhaddata->dev); return 0; } @@ -1596,7 +1598,8 @@ static void had_audio_wq(struct work_struct *work) had_process_mode_change(ctx); } mutex_unlock(&ctx->mutex); - pm_runtime_put(ctx->dev); + pm_runtime_mark_last_busy(ctx->dev); + pm_runtime_put_autosuspend(ctx->dev); } /* @@ -1643,10 +1646,17 @@ static int __maybe_unused hdmi_lpe_audio_suspend(struct device *dev) return err; } +static int hdmi_lpe_audio_runtime_resume(struct device *dev) +{ + pm_runtime_mark_last_busy(dev); + return 0; +} + static int __maybe_unused hdmi_lpe_audio_resume(struct device *dev) { struct snd_intelhad *ctx = dev_get_drvdata(dev); + hdmi_lpe_audio_runtime_resume(dev); snd_power_change_state(ctx->card, SNDRV_CTL_POWER_D0); return 0; } @@ -1799,8 +1809,13 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) pdata->notify_pending = false; spin_unlock_irq(&pdata->lpe_audio_slock); + /* runtime PM isn't enabled as default, since it won't save much on + * BYT/CHT devices; user who want the runtime PM should adjust the + * power/ontrol and power/autosuspend_delay_ms sysfs entries instead + */ + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); dev_dbg(&pdev->dev, "%s: handle pending notification\n", __func__); schedule_work(&ctx->hdmi_audio_wq); @@ -1827,7 +1842,8 @@ static int hdmi_lpe_audio_remove(struct platform_device *pdev) static const struct dev_pm_ops hdmi_lpe_audio_pm = { SET_SYSTEM_SLEEP_PM_OPS(hdmi_lpe_audio_suspend, hdmi_lpe_audio_resume) - SET_RUNTIME_PM_OPS(hdmi_lpe_audio_runtime_suspend, NULL, NULL) + SET_RUNTIME_PM_OPS(hdmi_lpe_audio_runtime_suspend, + hdmi_lpe_audio_runtime_resume, NULL) }; static struct platform_driver hdmi_lpe_audio_driver = { |