sound fixes for 4.17-rc3
A significant amount of fixes have been piled up at this time. - Possible Spectre v1 coverage in OSS sequencer API, control API, HD-audio hwdep ioctl, ASIHPI hwdep ioctl, OPL3, and HDSPM/RME channel_info API. - A regression fix in PCM delay reporting that happened at the code refactoring for the set_fs() removal - The long-standing bug in PCM sync_ptr ioctl that missed the audio timestamp field - USB-audio regression fixes due to the recent UAC2 jack support - vm_fault_t conversions in a couple of places - ASoC topology API fixes - Assorted driver fixes: * ASoC rsnd, FSL, Intel SST, DMIC, AMD, ADAU17x1, Realtek codec * FireWire typo fix * HD-audio quirks and USB-audio Dell fixup * USB-audio UAC3 corrections -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAlrh07cOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE8+6g/9F9nI4FEBb+jpP360vPyRJmjIR5Y5pp34+bA7 paMaa67J7HielEwUoos/8RhoH9/i1dXrT/ZhA1CkFleDohQqV6u0xpaT/07m+Yak lwQK2qJMn9hpahxrWDZ68qqIuI5IB7DzeRNjt9BmedWgzxn3PMoFc1ETGK8EepkL v9DSr+htSl83bmYxmhabBWCcI8lbpnPDbKwTewqp2GDarz7WBI/Mqw5tEycvpd04 oSxKruFGYUMw+e7+eEX/h+LxA7Wx7jmroXdMq5C8OC3oQ+T0n1I84MeCHvp8/Lh6 5u5jdm1nKH16pe6L6ZzcQ9iWHgATyGKi7u3dmvfl58GrVJsBtYpZxCA59bktl1Ab JFn1hqrM49IbndfuPaznAtIhGg/dd3wZcN32owKo+U2TWIzKflA7NQaqceTXhlxn Ly6v9HcI9hCAuLObVAFZ8WaJlQGUNGOSabtjUqsYVFwe4s0dTWVYKyCGGiahQ7UL LJ1sH1vH7vfn48FCxOUOODw/l9N8Ka/rqTdfKJRYsZPBRyzbXqty1VdFXJbhbWsX 7qkpYwM2zuNTyUASBkKgJY9SuGtUQlvusuLLTf/8j6srR94fz1H5uww0V+2WEgT/ GyoXRLtiDPvf/+MnIhKBnOWcpyz+1Pql7LNX9YWe/f13ibGFfV5SdddbIOu+08Xa N/eA+I0= =eSik -----END PGP SIGNATURE----- Merge tag 'sound-4.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "A significant amount of fixes have been piled up at this time. - Possible Spectre v1 coverage in OSS sequencer API, control API, HD-audio hwdep ioctl, ASIHPI hwdep ioctl, OPL3, and HDSPM/RME channel_info API. - A regression fix in PCM delay reporting that happened at the code refactoring for the set_fs() removal - The long-standing bug in PCM sync_ptr ioctl that missed the audio timestamp field - USB-audio regression fixes due to the recent UAC2 jack support - vm_fault_t conversions in a couple of places - ASoC topology API fixes - Assorted driver fixes: * ASoC rsnd, FSL, Intel SST, DMIC, AMD, ADAU17x1, Realtek codec * FireWire typo fix * HD-audio quirks and USB-audio Dell fixup * USB-audio UAC3 corrections" * tag 'sound-4.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (35 commits) ALSA: dice: fix error path to destroy initialized stream data ALSA: hda - Skip jack and others for non-existing PCM streams ALSA: hda/realtek - change the location for one of two front mics ALSA: rme9652: Hardening for potential Spectre v1 ALSA: hdspm: Hardening for potential Spectre v1 ALSA: asihpi: Hardening for potential Spectre v1 ALSA: opl3: Hardening for potential Spectre v1 ALSA: hda: Hardening for potential Spectre v1 ALSA: control: Hardening for potential Spectre v1 ALSA: seq: oss: Hardening for potential Spectre v1 ALSA: seq: oss: Fix unbalanced use lock for synth MIDI device ALSA: hda/realtek - Update ALC255 depop optimize ALSA: hda/realtek - Add some fixes for ALC233 ALSA: pcm: Change return type to vm_fault_t ALSA: usx2y: Change return type to vm_fault_t ALSA: usb-audio: ADC3: Fix channel mapping conversion for ADC3. ALSA: dice: fix OUI for TC group ALSA: usb-audio: Skip broken EU on Dell dock USB-audio ALSA: usb-audio: Fix missing endian conversion ALSA: usb-audio: Fix forgotten conversion of control query functions ...
This commit is contained in:
commit
7ff5000268
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
#include <sound/asound.h>
|
#include <sound/asound.h>
|
||||||
|
|
||||||
#define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
|
#define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
|
||||||
|
@ -148,12 +149,14 @@ int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type);
|
||||||
|
|
||||||
static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
|
static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
|
||||||
{
|
{
|
||||||
return id->numid - kctl->id.numid;
|
unsigned int ioff = id->numid - kctl->id.numid;
|
||||||
|
return array_index_nospec(ioff, kctl->count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
|
static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
|
||||||
{
|
{
|
||||||
return id->index - kctl->id.index;
|
unsigned int ioff = id->index - kctl->id.index;
|
||||||
|
return array_index_nospec(ioff, kctl->count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
|
static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
|
||||||
|
|
|
@ -1492,7 +1492,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
|
||||||
int op_flag)
|
int op_flag)
|
||||||
{
|
{
|
||||||
struct snd_ctl_tlv header;
|
struct snd_ctl_tlv header;
|
||||||
unsigned int *container;
|
unsigned int __user *container;
|
||||||
unsigned int container_size;
|
unsigned int container_size;
|
||||||
struct snd_kcontrol *kctl;
|
struct snd_kcontrol *kctl;
|
||||||
struct snd_ctl_elem_id id;
|
struct snd_ctl_elem_id id;
|
||||||
|
|
|
@ -27,10 +27,11 @@ static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
|
||||||
s32 __user *src)
|
s32 __user *src)
|
||||||
{
|
{
|
||||||
snd_pcm_sframes_t delay;
|
snd_pcm_sframes_t delay;
|
||||||
|
int err;
|
||||||
|
|
||||||
delay = snd_pcm_delay(substream);
|
err = snd_pcm_delay(substream, &delay);
|
||||||
if (delay < 0)
|
if (err)
|
||||||
return delay;
|
return err;
|
||||||
if (put_user(delay, src))
|
if (put_user(delay, src))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2692,7 +2692,8 @@ static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static snd_pcm_sframes_t snd_pcm_delay(struct snd_pcm_substream *substream)
|
static int snd_pcm_delay(struct snd_pcm_substream *substream,
|
||||||
|
snd_pcm_sframes_t *delay)
|
||||||
{
|
{
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
int err;
|
int err;
|
||||||
|
@ -2708,7 +2709,9 @@ static snd_pcm_sframes_t snd_pcm_delay(struct snd_pcm_substream *substream)
|
||||||
n += runtime->delay;
|
n += runtime->delay;
|
||||||
}
|
}
|
||||||
snd_pcm_stream_unlock_irq(substream);
|
snd_pcm_stream_unlock_irq(substream);
|
||||||
return err < 0 ? err : n;
|
if (!err)
|
||||||
|
*delay = n;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
|
static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
|
||||||
|
@ -2751,6 +2754,7 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
|
||||||
sync_ptr.s.status.hw_ptr = status->hw_ptr;
|
sync_ptr.s.status.hw_ptr = status->hw_ptr;
|
||||||
sync_ptr.s.status.tstamp = status->tstamp;
|
sync_ptr.s.status.tstamp = status->tstamp;
|
||||||
sync_ptr.s.status.suspended_state = status->suspended_state;
|
sync_ptr.s.status.suspended_state = status->suspended_state;
|
||||||
|
sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
|
||||||
snd_pcm_stream_unlock_irq(substream);
|
snd_pcm_stream_unlock_irq(substream);
|
||||||
if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
|
if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -2916,11 +2920,13 @@ static int snd_pcm_common_ioctl(struct file *file,
|
||||||
return snd_pcm_hwsync(substream);
|
return snd_pcm_hwsync(substream);
|
||||||
case SNDRV_PCM_IOCTL_DELAY:
|
case SNDRV_PCM_IOCTL_DELAY:
|
||||||
{
|
{
|
||||||
snd_pcm_sframes_t delay = snd_pcm_delay(substream);
|
snd_pcm_sframes_t delay;
|
||||||
snd_pcm_sframes_t __user *res = arg;
|
snd_pcm_sframes_t __user *res = arg;
|
||||||
|
int err;
|
||||||
|
|
||||||
if (delay < 0)
|
err = snd_pcm_delay(substream, &delay);
|
||||||
return delay;
|
if (err)
|
||||||
|
return err;
|
||||||
if (put_user(delay, res))
|
if (put_user(delay, res))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3008,13 +3014,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
|
||||||
case SNDRV_PCM_IOCTL_DROP:
|
case SNDRV_PCM_IOCTL_DROP:
|
||||||
return snd_pcm_drop(substream);
|
return snd_pcm_drop(substream);
|
||||||
case SNDRV_PCM_IOCTL_DELAY:
|
case SNDRV_PCM_IOCTL_DELAY:
|
||||||
{
|
return snd_pcm_delay(substream, frames);
|
||||||
result = snd_pcm_delay(substream);
|
|
||||||
if (result < 0)
|
|
||||||
return result;
|
|
||||||
*frames = result;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -3234,7 +3234,7 @@ static __poll_t snd_pcm_capture_poll(struct file *file, poll_table * wait)
|
||||||
/*
|
/*
|
||||||
* mmap status record
|
* mmap status record
|
||||||
*/
|
*/
|
||||||
static int snd_pcm_mmap_status_fault(struct vm_fault *vmf)
|
static vm_fault_t snd_pcm_mmap_status_fault(struct vm_fault *vmf)
|
||||||
{
|
{
|
||||||
struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
|
struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
|
||||||
struct snd_pcm_runtime *runtime;
|
struct snd_pcm_runtime *runtime;
|
||||||
|
@ -3270,7 +3270,7 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
|
||||||
/*
|
/*
|
||||||
* mmap control record
|
* mmap control record
|
||||||
*/
|
*/
|
||||||
static int snd_pcm_mmap_control_fault(struct vm_fault *vmf)
|
static vm_fault_t snd_pcm_mmap_control_fault(struct vm_fault *vmf)
|
||||||
{
|
{
|
||||||
struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
|
struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
|
||||||
struct snd_pcm_runtime *runtime;
|
struct snd_pcm_runtime *runtime;
|
||||||
|
@ -3359,7 +3359,7 @@ snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
|
||||||
/*
|
/*
|
||||||
* fault callback for mmapping a RAM page
|
* fault callback for mmapping a RAM page
|
||||||
*/
|
*/
|
||||||
static int snd_pcm_mmap_data_fault(struct vm_fault *vmf)
|
static vm_fault_t snd_pcm_mmap_data_fault(struct vm_fault *vmf)
|
||||||
{
|
{
|
||||||
struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
|
struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
|
||||||
struct snd_pcm_runtime *runtime;
|
struct snd_pcm_runtime *runtime;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <sound/seq_oss_legacy.h>
|
#include <sound/seq_oss_legacy.h>
|
||||||
#include "seq_oss_readq.h"
|
#include "seq_oss_readq.h"
|
||||||
#include "seq_oss_writeq.h"
|
#include "seq_oss_writeq.h"
|
||||||
|
#include <linux/nospec.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -287,10 +288,10 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st
|
||||||
{
|
{
|
||||||
struct seq_oss_synthinfo *info;
|
struct seq_oss_synthinfo *info;
|
||||||
|
|
||||||
if (!snd_seq_oss_synth_is_valid(dp, dev))
|
info = snd_seq_oss_synth_info(dp, dev);
|
||||||
|
if (!info)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
info = &dp->synths[dev];
|
|
||||||
switch (info->arg.event_passing) {
|
switch (info->arg.event_passing) {
|
||||||
case SNDRV_SEQ_OSS_PROCESS_EVENTS:
|
case SNDRV_SEQ_OSS_PROCESS_EVENTS:
|
||||||
if (! info->ch || ch < 0 || ch >= info->nr_voices) {
|
if (! info->ch || ch < 0 || ch >= info->nr_voices) {
|
||||||
|
@ -298,6 +299,7 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st
|
||||||
return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
|
return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ch = array_index_nospec(ch, info->nr_voices);
|
||||||
if (note == 255 && info->ch[ch].note >= 0) {
|
if (note == 255 && info->ch[ch].note >= 0) {
|
||||||
/* volume control */
|
/* volume control */
|
||||||
int type;
|
int type;
|
||||||
|
@ -347,10 +349,10 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
|
||||||
{
|
{
|
||||||
struct seq_oss_synthinfo *info;
|
struct seq_oss_synthinfo *info;
|
||||||
|
|
||||||
if (!snd_seq_oss_synth_is_valid(dp, dev))
|
info = snd_seq_oss_synth_info(dp, dev);
|
||||||
|
if (!info)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
info = &dp->synths[dev];
|
|
||||||
switch (info->arg.event_passing) {
|
switch (info->arg.event_passing) {
|
||||||
case SNDRV_SEQ_OSS_PROCESS_EVENTS:
|
case SNDRV_SEQ_OSS_PROCESS_EVENTS:
|
||||||
if (! info->ch || ch < 0 || ch >= info->nr_voices) {
|
if (! info->ch || ch < 0 || ch >= info->nr_voices) {
|
||||||
|
@ -358,6 +360,7 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
|
||||||
return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
|
return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ch = array_index_nospec(ch, info->nr_voices);
|
||||||
if (info->ch[ch].note >= 0) {
|
if (info->ch[ch].note >= 0) {
|
||||||
note = info->ch[ch].note;
|
note = info->ch[ch].note;
|
||||||
info->ch[ch].vel = 0;
|
info->ch[ch].vel = 0;
|
||||||
|
@ -381,7 +384,7 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
|
||||||
static int
|
static int
|
||||||
set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev)
|
set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev)
|
||||||
{
|
{
|
||||||
if (! snd_seq_oss_synth_is_valid(dp, dev))
|
if (!snd_seq_oss_synth_info(dp, dev))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
ev->type = type;
|
ev->type = type;
|
||||||
|
@ -399,7 +402,7 @@ set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note,
|
||||||
static int
|
static int
|
||||||
set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev)
|
set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev)
|
||||||
{
|
{
|
||||||
if (! snd_seq_oss_synth_is_valid(dp, dev))
|
if (!snd_seq_oss_synth_info(dp, dev))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
ev->type = type;
|
ev->type = type;
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "../seq_lock.h"
|
#include "../seq_lock.h"
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -315,6 +316,7 @@ get_mididev(struct seq_oss_devinfo *dp, int dev)
|
||||||
{
|
{
|
||||||
if (dev < 0 || dev >= dp->max_mididev)
|
if (dev < 0 || dev >= dp->max_mididev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
dev = array_index_nospec(dev, dp->max_mididev);
|
||||||
return get_mdev(dev);
|
return get_mdev(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* constants
|
* constants
|
||||||
|
@ -339,17 +340,13 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
|
||||||
dp->max_synthdev = 0;
|
dp->max_synthdev = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static struct seq_oss_synthinfo *
|
||||||
* check if the specified device is MIDI mapped device
|
get_synthinfo_nospec(struct seq_oss_devinfo *dp, int dev)
|
||||||
*/
|
|
||||||
static int
|
|
||||||
is_midi_dev(struct seq_oss_devinfo *dp, int dev)
|
|
||||||
{
|
{
|
||||||
if (dev < 0 || dev >= dp->max_synthdev)
|
if (dev < 0 || dev >= dp->max_synthdev)
|
||||||
return 0;
|
return NULL;
|
||||||
if (dp->synths[dev].is_midi)
|
dev = array_index_nospec(dev, SNDRV_SEQ_OSS_MAX_SYNTH_DEVS);
|
||||||
return 1;
|
return &dp->synths[dev];
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -359,14 +356,20 @@ static struct seq_oss_synth *
|
||||||
get_synthdev(struct seq_oss_devinfo *dp, int dev)
|
get_synthdev(struct seq_oss_devinfo *dp, int dev)
|
||||||
{
|
{
|
||||||
struct seq_oss_synth *rec;
|
struct seq_oss_synth *rec;
|
||||||
if (dev < 0 || dev >= dp->max_synthdev)
|
struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev);
|
||||||
|
|
||||||
|
if (!info)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (! dp->synths[dev].opened)
|
if (!info->opened)
|
||||||
return NULL;
|
|
||||||
if (dp->synths[dev].is_midi)
|
|
||||||
return &midi_synth_dev;
|
|
||||||
if ((rec = get_sdev(dev)) == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (info->is_midi) {
|
||||||
|
rec = &midi_synth_dev;
|
||||||
|
snd_use_lock_use(&rec->use_lock);
|
||||||
|
} else {
|
||||||
|
rec = get_sdev(dev);
|
||||||
|
if (!rec)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (! rec->opened) {
|
if (! rec->opened) {
|
||||||
snd_use_lock_free(&rec->use_lock);
|
snd_use_lock_free(&rec->use_lock);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -402,10 +405,8 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
|
||||||
struct seq_oss_synth *rec;
|
struct seq_oss_synth *rec;
|
||||||
struct seq_oss_synthinfo *info;
|
struct seq_oss_synthinfo *info;
|
||||||
|
|
||||||
if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev))
|
info = get_synthinfo_nospec(dp, dev);
|
||||||
return;
|
if (!info || !info->opened)
|
||||||
info = &dp->synths[dev];
|
|
||||||
if (! info->opened)
|
|
||||||
return;
|
return;
|
||||||
if (info->sysex)
|
if (info->sysex)
|
||||||
info->sysex->len = 0; /* reset sysex */
|
info->sysex->len = 0; /* reset sysex */
|
||||||
|
@ -454,12 +455,14 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
|
||||||
const char __user *buf, int p, int c)
|
const char __user *buf, int p, int c)
|
||||||
{
|
{
|
||||||
struct seq_oss_synth *rec;
|
struct seq_oss_synth *rec;
|
||||||
|
struct seq_oss_synthinfo *info;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (dev < 0 || dev >= dp->max_synthdev)
|
info = get_synthinfo_nospec(dp, dev);
|
||||||
|
if (!info)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
if (is_midi_dev(dp, dev))
|
if (info->is_midi)
|
||||||
return 0;
|
return 0;
|
||||||
if ((rec = get_synthdev(dp, dev)) == NULL)
|
if ((rec = get_synthdev(dp, dev)) == NULL)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
@ -467,24 +470,25 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
|
||||||
if (rec->oper.load_patch == NULL)
|
if (rec->oper.load_patch == NULL)
|
||||||
rc = -ENXIO;
|
rc = -ENXIO;
|
||||||
else
|
else
|
||||||
rc = rec->oper.load_patch(&dp->synths[dev].arg, fmt, buf, p, c);
|
rc = rec->oper.load_patch(&info->arg, fmt, buf, p, c);
|
||||||
snd_use_lock_free(&rec->use_lock);
|
snd_use_lock_free(&rec->use_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check if the device is valid synth device
|
* check if the device is valid synth device and return the synth info
|
||||||
*/
|
*/
|
||||||
int
|
struct seq_oss_synthinfo *
|
||||||
snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev)
|
snd_seq_oss_synth_info(struct seq_oss_devinfo *dp, int dev)
|
||||||
{
|
{
|
||||||
struct seq_oss_synth *rec;
|
struct seq_oss_synth *rec;
|
||||||
|
|
||||||
rec = get_synthdev(dp, dev);
|
rec = get_synthdev(dp, dev);
|
||||||
if (rec) {
|
if (rec) {
|
||||||
snd_use_lock_free(&rec->use_lock);
|
snd_use_lock_free(&rec->use_lock);
|
||||||
return 1;
|
return get_synthinfo_nospec(dp, dev);
|
||||||
}
|
}
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -499,16 +503,18 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
|
||||||
int i, send;
|
int i, send;
|
||||||
unsigned char *dest;
|
unsigned char *dest;
|
||||||
struct seq_oss_synth_sysex *sysex;
|
struct seq_oss_synth_sysex *sysex;
|
||||||
|
struct seq_oss_synthinfo *info;
|
||||||
|
|
||||||
if (! snd_seq_oss_synth_is_valid(dp, dev))
|
info = snd_seq_oss_synth_info(dp, dev);
|
||||||
|
if (!info)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
sysex = dp->synths[dev].sysex;
|
sysex = info->sysex;
|
||||||
if (sysex == NULL) {
|
if (sysex == NULL) {
|
||||||
sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
|
sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
|
||||||
if (sysex == NULL)
|
if (sysex == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
dp->synths[dev].sysex = sysex;
|
info->sysex = sysex;
|
||||||
}
|
}
|
||||||
|
|
||||||
send = 0;
|
send = 0;
|
||||||
|
@ -553,10 +559,12 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
|
||||||
int
|
int
|
||||||
snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev)
|
snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev)
|
||||||
{
|
{
|
||||||
if (! snd_seq_oss_synth_is_valid(dp, dev))
|
struct seq_oss_synthinfo *info = snd_seq_oss_synth_info(dp, dev);
|
||||||
|
|
||||||
|
if (!info)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
snd_seq_oss_fill_addr(dp, ev, dp->synths[dev].arg.addr.client,
|
snd_seq_oss_fill_addr(dp, ev, info->arg.addr.client,
|
||||||
dp->synths[dev].arg.addr.port);
|
info->arg.addr.port);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,16 +576,18 @@ int
|
||||||
snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
|
snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
|
||||||
{
|
{
|
||||||
struct seq_oss_synth *rec;
|
struct seq_oss_synth *rec;
|
||||||
|
struct seq_oss_synthinfo *info;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (is_midi_dev(dp, dev))
|
info = get_synthinfo_nospec(dp, dev);
|
||||||
|
if (!info || info->is_midi)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
if ((rec = get_synthdev(dp, dev)) == NULL)
|
if ((rec = get_synthdev(dp, dev)) == NULL)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
if (rec->oper.ioctl == NULL)
|
if (rec->oper.ioctl == NULL)
|
||||||
rc = -ENXIO;
|
rc = -ENXIO;
|
||||||
else
|
else
|
||||||
rc = rec->oper.ioctl(&dp->synths[dev].arg, cmd, addr);
|
rc = rec->oper.ioctl(&info->arg, cmd, addr);
|
||||||
snd_use_lock_free(&rec->use_lock);
|
snd_use_lock_free(&rec->use_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -589,7 +599,10 @@ snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, u
|
||||||
int
|
int
|
||||||
snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev)
|
snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev)
|
||||||
{
|
{
|
||||||
if (! snd_seq_oss_synth_is_valid(dp, dev) || is_midi_dev(dp, dev))
|
struct seq_oss_synthinfo *info;
|
||||||
|
|
||||||
|
info = snd_seq_oss_synth_info(dp, dev);
|
||||||
|
if (!info || info->is_midi)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
ev->type = SNDRV_SEQ_EVENT_OSS;
|
ev->type = SNDRV_SEQ_EVENT_OSS;
|
||||||
memcpy(ev->data.raw8.d, data, 8);
|
memcpy(ev->data.raw8.d, data, 8);
|
||||||
|
|
|
@ -37,7 +37,8 @@ void snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp);
|
||||||
void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev);
|
void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev);
|
||||||
int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
|
int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
|
||||||
const char __user *buf, int p, int c);
|
const char __user *buf, int p, int c);
|
||||||
int snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev);
|
struct seq_oss_synthinfo *snd_seq_oss_synth_info(struct seq_oss_devinfo *dp,
|
||||||
|
int dev);
|
||||||
int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
|
int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
|
||||||
struct snd_seq_event *ev);
|
struct snd_seq_event *ev);
|
||||||
int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev);
|
int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
#include <sound/opl3.h>
|
#include <sound/opl3.h>
|
||||||
#include <sound/asound_fm.h>
|
#include <sound/asound_fm.h>
|
||||||
|
|
||||||
|
@ -448,7 +449,7 @@ static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * v
|
||||||
{
|
{
|
||||||
unsigned short reg_side;
|
unsigned short reg_side;
|
||||||
unsigned char op_offset;
|
unsigned char op_offset;
|
||||||
unsigned char voice_offset;
|
unsigned char voice_offset, voice_op;
|
||||||
|
|
||||||
unsigned short opl3_reg;
|
unsigned short opl3_reg;
|
||||||
unsigned char reg_val;
|
unsigned char reg_val;
|
||||||
|
@ -473,7 +474,9 @@ static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * v
|
||||||
voice_offset = voice->voice - MAX_OPL2_VOICES;
|
voice_offset = voice->voice - MAX_OPL2_VOICES;
|
||||||
}
|
}
|
||||||
/* Get register offset of operator */
|
/* Get register offset of operator */
|
||||||
op_offset = snd_opl3_regmap[voice_offset][voice->op];
|
voice_offset = array_index_nospec(voice_offset, MAX_OPL2_VOICES);
|
||||||
|
voice_op = array_index_nospec(voice->op, 4);
|
||||||
|
op_offset = snd_opl3_regmap[voice_offset][voice_op];
|
||||||
|
|
||||||
reg_val = 0x00;
|
reg_val = 0x00;
|
||||||
/* Set amplitude modulation (tremolo) effect */
|
/* Set amplitude modulation (tremolo) effect */
|
||||||
|
|
|
@ -435,7 +435,7 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice)
|
||||||
err = init_stream(dice, AMDTP_IN_STREAM, i);
|
err = init_stream(dice, AMDTP_IN_STREAM, i);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
for (; i >= 0; i--)
|
for (; i >= 0; i--)
|
||||||
destroy_stream(dice, AMDTP_OUT_STREAM, i);
|
destroy_stream(dice, AMDTP_IN_STREAM, i);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ MODULE_LICENSE("GPL v2");
|
||||||
#define OUI_WEISS 0x001c6a
|
#define OUI_WEISS 0x001c6a
|
||||||
#define OUI_LOUD 0x000ff2
|
#define OUI_LOUD 0x000ff2
|
||||||
#define OUI_FOCUSRITE 0x00130e
|
#define OUI_FOCUSRITE 0x00130e
|
||||||
#define OUI_TCELECTRONIC 0x001486
|
#define OUI_TCELECTRONIC 0x000166
|
||||||
|
|
||||||
#define DICE_CATEGORY_ID 0x04
|
#define DICE_CATEGORY_ID 0x04
|
||||||
#define WEISS_CATEGORY_ID 0x00
|
#define WEISS_CATEGORY_ID 0x00
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "hpi_internal.h"
|
#include "hpi_internal.h"
|
||||||
#include "hpimsginit.h"
|
#include "hpimsginit.h"
|
||||||
|
#include <linux/nospec.h>
|
||||||
|
|
||||||
/* The actual message size for each object type */
|
/* The actual message size for each object type */
|
||||||
static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
|
static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
|
||||||
|
@ -39,10 +40,12 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
|
||||||
{
|
{
|
||||||
u16 size;
|
u16 size;
|
||||||
|
|
||||||
if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
|
if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
|
||||||
|
object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
|
||||||
size = msg_size[object];
|
size = msg_size[object];
|
||||||
else
|
} else {
|
||||||
size = sizeof(*phm);
|
size = sizeof(*phm);
|
||||||
|
}
|
||||||
|
|
||||||
memset(phm, 0, size);
|
memset(phm, 0, size);
|
||||||
phm->size = size;
|
phm->size = size;
|
||||||
|
@ -66,10 +69,12 @@ void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
|
||||||
{
|
{
|
||||||
u16 size;
|
u16 size;
|
||||||
|
|
||||||
if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
|
if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
|
||||||
|
object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
|
||||||
size = res_size[object];
|
size = res_size[object];
|
||||||
else
|
} else {
|
||||||
size = sizeof(*phr);
|
size = sizeof(*phr);
|
||||||
|
}
|
||||||
|
|
||||||
memset(phr, 0, sizeof(*phr));
|
memset(phr, 0, sizeof(*phr));
|
||||||
phr->size = size;
|
phr->size = size;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <linux/stringify.h>
|
#include <linux/stringify.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
|
|
||||||
#ifdef MODULE_FIRMWARE
|
#ifdef MODULE_FIRMWARE
|
||||||
MODULE_FIRMWARE("asihpi/dsp5000.bin");
|
MODULE_FIRMWARE("asihpi/dsp5000.bin");
|
||||||
|
@ -186,7 +187,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
struct hpi_adapter *pa = NULL;
|
struct hpi_adapter *pa = NULL;
|
||||||
|
|
||||||
if (hm->h.adapter_index < ARRAY_SIZE(adapters))
|
if (hm->h.adapter_index < ARRAY_SIZE(adapters))
|
||||||
pa = &adapters[hm->h.adapter_index];
|
pa = &adapters[array_index_nospec(hm->h.adapter_index,
|
||||||
|
ARRAY_SIZE(adapters))];
|
||||||
|
|
||||||
if (!pa || !pa->adapter || !pa->adapter->type) {
|
if (!pa || !pa->adapter || !pa->adapter->type) {
|
||||||
hpi_init_response(&hr->r0, hm->h.object,
|
hpi_init_response(&hr->r0, hm->h.object,
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include "hda_codec.h"
|
#include "hda_codec.h"
|
||||||
#include "hda_local.h"
|
#include "hda_local.h"
|
||||||
|
@ -51,7 +52,16 @@ static int get_wcap_ioctl(struct hda_codec *codec,
|
||||||
|
|
||||||
if (get_user(verb, &arg->verb))
|
if (get_user(verb, &arg->verb))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
res = get_wcaps(codec, verb >> 24);
|
/* open-code get_wcaps(verb>>24) with nospec */
|
||||||
|
verb >>= 24;
|
||||||
|
if (verb < codec->core.start_nid ||
|
||||||
|
verb >= codec->core.start_nid + codec->core.num_nodes) {
|
||||||
|
res = 0;
|
||||||
|
} else {
|
||||||
|
verb -= codec->core.start_nid;
|
||||||
|
verb = array_index_nospec(verb, codec->core.num_nodes);
|
||||||
|
res = codec->wcaps[verb];
|
||||||
|
}
|
||||||
if (put_user(res, &arg->res))
|
if (put_user(res, &arg->res))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1383,6 +1383,8 @@ static void hdmi_pcm_setup_pin(struct hdmi_spec *spec,
|
||||||
pcm = get_pcm_rec(spec, per_pin->pcm_idx);
|
pcm = get_pcm_rec(spec, per_pin->pcm_idx);
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
if (!pcm->pcm)
|
||||||
|
return;
|
||||||
if (!test_bit(per_pin->pcm_idx, &spec->pcm_in_use))
|
if (!test_bit(per_pin->pcm_idx, &spec->pcm_in_use))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2151,8 +2153,13 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
|
||||||
int dev, err;
|
int dev, err;
|
||||||
int pin_idx, pcm_idx;
|
int pin_idx, pcm_idx;
|
||||||
|
|
||||||
|
|
||||||
for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
|
for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
|
||||||
|
if (!get_pcm_rec(spec, pcm_idx)->pcm) {
|
||||||
|
/* no PCM: mark this for skipping permanently */
|
||||||
|
set_bit(pcm_idx, &spec->pcm_bitmap);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
err = generic_hdmi_build_jack(codec, pcm_idx);
|
err = generic_hdmi_build_jack(codec, pcm_idx);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -331,6 +331,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 0x10ec0215:
|
case 0x10ec0215:
|
||||||
case 0x10ec0233:
|
case 0x10ec0233:
|
||||||
|
case 0x10ec0235:
|
||||||
case 0x10ec0236:
|
case 0x10ec0236:
|
||||||
case 0x10ec0255:
|
case 0x10ec0255:
|
||||||
case 0x10ec0256:
|
case 0x10ec0256:
|
||||||
|
@ -6575,6 +6576,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
|
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, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
|
SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
|
||||||
|
SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3138, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
|
SND_PCI_QUIRK(0x17aa, 0x3138, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
|
SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
|
SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
|
||||||
|
@ -7160,8 +7162,11 @@ static int patch_alc269(struct hda_codec *codec)
|
||||||
case 0x10ec0298:
|
case 0x10ec0298:
|
||||||
spec->codec_variant = ALC269_TYPE_ALC298;
|
spec->codec_variant = ALC269_TYPE_ALC298;
|
||||||
break;
|
break;
|
||||||
|
case 0x10ec0235:
|
||||||
case 0x10ec0255:
|
case 0x10ec0255:
|
||||||
spec->codec_variant = ALC269_TYPE_ALC255;
|
spec->codec_variant = ALC269_TYPE_ALC255;
|
||||||
|
spec->shutup = alc256_shutup;
|
||||||
|
spec->init_hook = alc256_init;
|
||||||
break;
|
break;
|
||||||
case 0x10ec0236:
|
case 0x10ec0236:
|
||||||
case 0x10ec0256:
|
case 0x10ec0256:
|
||||||
|
|
|
@ -137,6 +137,7 @@
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/math64.h>
|
#include <linux/math64.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
|
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/control.h>
|
#include <sound/control.h>
|
||||||
|
@ -5698,40 +5699,43 @@ static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
|
||||||
struct snd_pcm_channel_info *info)
|
struct snd_pcm_channel_info *info)
|
||||||
{
|
{
|
||||||
struct hdspm *hdspm = snd_pcm_substream_chip(substream);
|
struct hdspm *hdspm = snd_pcm_substream_chip(substream);
|
||||||
|
unsigned int channel = info->channel;
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) {
|
if (snd_BUG_ON(channel >= hdspm->max_channels_out)) {
|
||||||
dev_info(hdspm->card->dev,
|
dev_info(hdspm->card->dev,
|
||||||
"snd_hdspm_channel_info: output channel out of range (%d)\n",
|
"snd_hdspm_channel_info: output channel out of range (%d)\n",
|
||||||
info->channel);
|
channel);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdspm->channel_map_out[info->channel] < 0) {
|
channel = array_index_nospec(channel, hdspm->max_channels_out);
|
||||||
|
if (hdspm->channel_map_out[channel] < 0) {
|
||||||
dev_info(hdspm->card->dev,
|
dev_info(hdspm->card->dev,
|
||||||
"snd_hdspm_channel_info: output channel %d mapped out\n",
|
"snd_hdspm_channel_info: output channel %d mapped out\n",
|
||||||
info->channel);
|
channel);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->offset = hdspm->channel_map_out[info->channel] *
|
info->offset = hdspm->channel_map_out[channel] *
|
||||||
HDSPM_CHANNEL_BUFFER_BYTES;
|
HDSPM_CHANNEL_BUFFER_BYTES;
|
||||||
} else {
|
} else {
|
||||||
if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) {
|
if (snd_BUG_ON(channel >= hdspm->max_channels_in)) {
|
||||||
dev_info(hdspm->card->dev,
|
dev_info(hdspm->card->dev,
|
||||||
"snd_hdspm_channel_info: input channel out of range (%d)\n",
|
"snd_hdspm_channel_info: input channel out of range (%d)\n",
|
||||||
info->channel);
|
channel);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdspm->channel_map_in[info->channel] < 0) {
|
channel = array_index_nospec(channel, hdspm->max_channels_in);
|
||||||
|
if (hdspm->channel_map_in[channel] < 0) {
|
||||||
dev_info(hdspm->card->dev,
|
dev_info(hdspm->card->dev,
|
||||||
"snd_hdspm_channel_info: input channel %d mapped out\n",
|
"snd_hdspm_channel_info: input channel %d mapped out\n",
|
||||||
info->channel);
|
channel);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->offset = hdspm->channel_map_in[info->channel] *
|
info->offset = hdspm->channel_map_in[channel] *
|
||||||
HDSPM_CHANNEL_BUFFER_BYTES;
|
HDSPM_CHANNEL_BUFFER_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
|
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/control.h>
|
#include <sound/control.h>
|
||||||
|
@ -2071,9 +2072,10 @@ static int snd_rme9652_channel_info(struct snd_pcm_substream *substream,
|
||||||
if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
|
if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if ((chn = rme9652->channel_map[info->channel]) < 0) {
|
chn = rme9652->channel_map[array_index_nospec(info->channel,
|
||||||
|
RME9652_NCHANNELS)];
|
||||||
|
if (chn < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
|
||||||
|
|
||||||
info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES;
|
info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES;
|
||||||
info->first = 0;
|
info->first = 0;
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#define DUAL_CHANNEL 2
|
#define DUAL_CHANNEL 2
|
||||||
|
|
||||||
static struct snd_soc_jack cz_jack;
|
static struct snd_soc_jack cz_jack;
|
||||||
struct clk *da7219_dai_clk;
|
static struct clk *da7219_dai_clk;
|
||||||
|
|
||||||
static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
|
static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -502,7 +502,7 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adau->sigmadsp) {
|
if (adau->sigmadsp) {
|
||||||
ret = adau17x1_setup_firmware(adau, params_rate(params));
|
ret = adau17x1_setup_firmware(component, params_rate(params));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -835,26 +835,40 @@ bool adau17x1_volatile_register(struct device *dev, unsigned int reg)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(adau17x1_volatile_register);
|
EXPORT_SYMBOL_GPL(adau17x1_volatile_register);
|
||||||
|
|
||||||
int adau17x1_setup_firmware(struct adau *adau, unsigned int rate)
|
int adau17x1_setup_firmware(struct snd_soc_component *component,
|
||||||
|
unsigned int rate)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int dspsr;
|
int dspsr, dsp_run;
|
||||||
|
struct adau *adau = snd_soc_component_get_drvdata(component);
|
||||||
|
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
|
||||||
|
|
||||||
|
snd_soc_dapm_mutex_lock(dapm);
|
||||||
|
|
||||||
ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr);
|
ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err;
|
||||||
|
|
||||||
|
ret = regmap_read(adau->regmap, ADAU17X1_DSP_RUN, &dsp_run);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1);
|
regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1);
|
||||||
regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf);
|
regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf);
|
||||||
|
regmap_write(adau->regmap, ADAU17X1_DSP_RUN, 0);
|
||||||
|
|
||||||
ret = sigmadsp_setup(adau->sigmadsp, rate);
|
ret = sigmadsp_setup(adau->sigmadsp, rate);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0);
|
regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0);
|
||||||
return ret;
|
goto err;
|
||||||
}
|
}
|
||||||
regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr);
|
regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr);
|
||||||
|
regmap_write(adau->regmap, ADAU17X1_DSP_RUN, dsp_run);
|
||||||
|
|
||||||
return 0;
|
err:
|
||||||
|
snd_soc_dapm_mutex_unlock(dapm);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(adau17x1_setup_firmware);
|
EXPORT_SYMBOL_GPL(adau17x1_setup_firmware);
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,8 @@ int adau17x1_resume(struct snd_soc_component *component);
|
||||||
|
|
||||||
extern const struct snd_soc_dai_ops adau17x1_dai_ops;
|
extern const struct snd_soc_dai_ops adau17x1_dai_ops;
|
||||||
|
|
||||||
int adau17x1_setup_firmware(struct adau *adau, unsigned int rate);
|
int adau17x1_setup_firmware(struct snd_soc_component *component,
|
||||||
|
unsigned int rate);
|
||||||
bool adau17x1_has_dsp(struct adau *adau);
|
bool adau17x1_has_dsp(struct adau *adau);
|
||||||
|
|
||||||
#define ADAU17X1_CLOCK_CONTROL 0x4000
|
#define ADAU17X1_CLOCK_CONTROL 0x4000
|
||||||
|
|
|
@ -1187,7 +1187,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
|
||||||
return irq;
|
return irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_request_irq(dev, irq, pm8916_mbhc_switch_irq_handler,
|
ret = devm_request_threaded_irq(dev, irq, NULL,
|
||||||
|
pm8916_mbhc_switch_irq_handler,
|
||||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
|
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
|
||||||
IRQF_ONESHOT,
|
IRQF_ONESHOT,
|
||||||
"mbhc switch irq", priv);
|
"mbhc switch irq", priv);
|
||||||
|
@ -1201,7 +1202,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
|
||||||
return irq;
|
return irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_request_irq(dev, irq, mbhc_btn_press_irq_handler,
|
ret = devm_request_threaded_irq(dev, irq, NULL,
|
||||||
|
mbhc_btn_press_irq_handler,
|
||||||
IRQF_TRIGGER_RISING |
|
IRQF_TRIGGER_RISING |
|
||||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||||
"mbhc btn press irq", priv);
|
"mbhc btn press irq", priv);
|
||||||
|
@ -1214,7 +1216,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
|
||||||
return irq;
|
return irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_request_irq(dev, irq, mbhc_btn_release_irq_handler,
|
ret = devm_request_threaded_irq(dev, irq, NULL,
|
||||||
|
mbhc_btn_release_irq_handler,
|
||||||
IRQF_TRIGGER_RISING |
|
IRQF_TRIGGER_RISING |
|
||||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||||
"mbhc btn release irq", priv);
|
"mbhc btn release irq", priv);
|
||||||
|
|
|
@ -89,6 +89,7 @@ static const struct reg_default rt5514_reg[] = {
|
||||||
{RT5514_PLL3_CALIB_CTRL5, 0x40220012},
|
{RT5514_PLL3_CALIB_CTRL5, 0x40220012},
|
||||||
{RT5514_DELAY_BUF_CTRL1, 0x7fff006a},
|
{RT5514_DELAY_BUF_CTRL1, 0x7fff006a},
|
||||||
{RT5514_DELAY_BUF_CTRL3, 0x00000000},
|
{RT5514_DELAY_BUF_CTRL3, 0x00000000},
|
||||||
|
{RT5514_ASRC_IN_CTRL1, 0x00000003},
|
||||||
{RT5514_DOWNFILTER0_CTRL1, 0x00020c2f},
|
{RT5514_DOWNFILTER0_CTRL1, 0x00020c2f},
|
||||||
{RT5514_DOWNFILTER0_CTRL2, 0x00020c2f},
|
{RT5514_DOWNFILTER0_CTRL2, 0x00020c2f},
|
||||||
{RT5514_DOWNFILTER0_CTRL3, 0x10000362},
|
{RT5514_DOWNFILTER0_CTRL3, 0x10000362},
|
||||||
|
@ -181,6 +182,7 @@ static bool rt5514_readable_register(struct device *dev, unsigned int reg)
|
||||||
case RT5514_PLL3_CALIB_CTRL5:
|
case RT5514_PLL3_CALIB_CTRL5:
|
||||||
case RT5514_DELAY_BUF_CTRL1:
|
case RT5514_DELAY_BUF_CTRL1:
|
||||||
case RT5514_DELAY_BUF_CTRL3:
|
case RT5514_DELAY_BUF_CTRL3:
|
||||||
|
case RT5514_ASRC_IN_CTRL1:
|
||||||
case RT5514_DOWNFILTER0_CTRL1:
|
case RT5514_DOWNFILTER0_CTRL1:
|
||||||
case RT5514_DOWNFILTER0_CTRL2:
|
case RT5514_DOWNFILTER0_CTRL2:
|
||||||
case RT5514_DOWNFILTER0_CTRL3:
|
case RT5514_DOWNFILTER0_CTRL3:
|
||||||
|
@ -238,6 +240,7 @@ static bool rt5514_i2c_readable_register(struct device *dev,
|
||||||
case RT5514_DSP_MAPPING | RT5514_PLL3_CALIB_CTRL5:
|
case RT5514_DSP_MAPPING | RT5514_PLL3_CALIB_CTRL5:
|
||||||
case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL1:
|
case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL1:
|
||||||
case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL3:
|
case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL3:
|
||||||
|
case RT5514_DSP_MAPPING | RT5514_ASRC_IN_CTRL1:
|
||||||
case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL1:
|
case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL1:
|
||||||
case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL2:
|
case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL2:
|
||||||
case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL3:
|
case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL3:
|
||||||
|
|
|
@ -144,6 +144,13 @@ static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
|
||||||
|
|
||||||
psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
|
psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
|
||||||
|
|
||||||
|
/* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */
|
||||||
|
if (ratio <= 256) {
|
||||||
|
pm = ratio;
|
||||||
|
fp = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the max fluctuation -- 0.1% of the max devisor */
|
/* Set the max fluctuation -- 0.1% of the max devisor */
|
||||||
savesub = (psr ? 1 : 8) * 256 * maxfp / 1000;
|
savesub = (psr ? 1 : 8) * 256 * maxfp / 1000;
|
||||||
|
|
||||||
|
|
|
@ -217,6 +217,7 @@ struct fsl_ssi_soc_data {
|
||||||
* @dai_fmt: DAI configuration this device is currently used with
|
* @dai_fmt: DAI configuration this device is currently used with
|
||||||
* @streams: Mask of current active streams: BIT(TX) and BIT(RX)
|
* @streams: Mask of current active streams: BIT(TX) and BIT(RX)
|
||||||
* @i2s_net: I2S and Network mode configurations of SCR register
|
* @i2s_net: I2S and Network mode configurations of SCR register
|
||||||
|
* (this is the initial settings based on the DAI format)
|
||||||
* @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK
|
* @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK
|
||||||
* @use_dma: DMA is used or FIQ with stream filter
|
* @use_dma: DMA is used or FIQ with stream filter
|
||||||
* @use_dual_fifo: DMA with support for dual FIFO mode
|
* @use_dual_fifo: DMA with support for dual FIFO mode
|
||||||
|
@ -829,16 +830,23 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fsl_ssi_is_ac97(ssi)) {
|
if (!fsl_ssi_is_ac97(ssi)) {
|
||||||
|
/*
|
||||||
|
* Keep the ssi->i2s_net intact while having a local variable
|
||||||
|
* to override settings for special use cases. Otherwise, the
|
||||||
|
* ssi->i2s_net will lose the settings for regular use cases.
|
||||||
|
*/
|
||||||
|
u8 i2s_net = ssi->i2s_net;
|
||||||
|
|
||||||
/* Normal + Network mode to send 16-bit data in 32-bit frames */
|
/* Normal + Network mode to send 16-bit data in 32-bit frames */
|
||||||
if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16)
|
if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16)
|
||||||
ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
|
i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
|
||||||
|
|
||||||
/* Use Normal mode to send mono data at 1st slot of 2 slots */
|
/* Use Normal mode to send mono data at 1st slot of 2 slots */
|
||||||
if (channels == 1)
|
if (channels == 1)
|
||||||
ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL;
|
i2s_net = SSI_SCR_I2S_MODE_NORMAL;
|
||||||
|
|
||||||
regmap_update_bits(regs, REG_SSI_SCR,
|
regmap_update_bits(regs, REG_SSI_SCR,
|
||||||
SSI_SCR_I2S_NET_MASK, ssi->i2s_net);
|
SSI_SCR_I2S_NET_MASK, i2s_net);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In synchronous mode, the SSI uses STCCR for capture */
|
/* In synchronous mode, the SSI uses STCCR for capture */
|
||||||
|
|
|
@ -72,24 +72,28 @@ config SND_SOC_INTEL_BAYTRAIL
|
||||||
for Baytrail Chromebooks but this option is now deprecated and is
|
for Baytrail Chromebooks but this option is now deprecated and is
|
||||||
not recommended, use SND_SST_ATOM_HIFI2_PLATFORM instead.
|
not recommended, use SND_SST_ATOM_HIFI2_PLATFORM instead.
|
||||||
|
|
||||||
|
config SND_SST_ATOM_HIFI2_PLATFORM
|
||||||
|
tristate
|
||||||
|
select SND_SOC_COMPRESS
|
||||||
|
|
||||||
config SND_SST_ATOM_HIFI2_PLATFORM_PCI
|
config SND_SST_ATOM_HIFI2_PLATFORM_PCI
|
||||||
tristate "PCI HiFi2 (Medfield, Merrifield) Platforms"
|
tristate "PCI HiFi2 (Merrifield) Platforms"
|
||||||
depends on X86 && PCI
|
depends on X86 && PCI
|
||||||
select SND_SST_IPC_PCI
|
select SND_SST_IPC_PCI
|
||||||
select SND_SOC_COMPRESS
|
select SND_SST_ATOM_HIFI2_PLATFORM
|
||||||
help
|
help
|
||||||
If you have a Intel Medfield or Merrifield/Edison platform, then
|
If you have a Intel Merrifield/Edison platform, then
|
||||||
enable this option by saying Y or m. Distros will typically not
|
enable this option by saying Y or m. Distros will typically not
|
||||||
enable this option: Medfield devices are not available to
|
enable this option: while Merrifield/Edison can run a mainline
|
||||||
developers and while Merrifield/Edison can run a mainline kernel with
|
kernel with limited functionality it will require a firmware file
|
||||||
limited functionality it will require a firmware file which
|
which is not in the standard firmware tree
|
||||||
is not in the standard firmware tree
|
|
||||||
|
|
||||||
config SND_SST_ATOM_HIFI2_PLATFORM
|
config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
|
||||||
tristate "ACPI HiFi2 (Baytrail, Cherrytrail) Platforms"
|
tristate "ACPI HiFi2 (Baytrail, Cherrytrail) Platforms"
|
||||||
|
default ACPI
|
||||||
depends on X86 && ACPI
|
depends on X86 && ACPI
|
||||||
select SND_SST_IPC_ACPI
|
select SND_SST_IPC_ACPI
|
||||||
select SND_SOC_COMPRESS
|
select SND_SST_ATOM_HIFI2_PLATFORM
|
||||||
select SND_SOC_ACPI_INTEL_MATCH
|
select SND_SOC_ACPI_INTEL_MATCH
|
||||||
select IOSF_MBI
|
select IOSF_MBI
|
||||||
help
|
help
|
||||||
|
|
|
@ -281,7 +281,7 @@ static int omap_dmic_dai_trigger(struct snd_pcm_substream *substream,
|
||||||
static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
|
static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
|
||||||
unsigned int freq)
|
unsigned int freq)
|
||||||
{
|
{
|
||||||
struct clk *parent_clk;
|
struct clk *parent_clk, *mux;
|
||||||
char *parent_clk_name;
|
char *parent_clk_name;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -329,14 +329,21 @@ static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mux = clk_get_parent(dmic->fclk);
|
||||||
|
if (IS_ERR(mux)) {
|
||||||
|
dev_err(dmic->dev, "can't get fck mux parent\n");
|
||||||
|
clk_put(parent_clk);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(&dmic->mutex);
|
mutex_lock(&dmic->mutex);
|
||||||
if (dmic->active) {
|
if (dmic->active) {
|
||||||
/* disable clock while reparenting */
|
/* disable clock while reparenting */
|
||||||
pm_runtime_put_sync(dmic->dev);
|
pm_runtime_put_sync(dmic->dev);
|
||||||
ret = clk_set_parent(dmic->fclk, parent_clk);
|
ret = clk_set_parent(mux, parent_clk);
|
||||||
pm_runtime_get_sync(dmic->dev);
|
pm_runtime_get_sync(dmic->dev);
|
||||||
} else {
|
} else {
|
||||||
ret = clk_set_parent(dmic->fclk, parent_clk);
|
ret = clk_set_parent(mux, parent_clk);
|
||||||
}
|
}
|
||||||
mutex_unlock(&dmic->mutex);
|
mutex_unlock(&dmic->mutex);
|
||||||
|
|
||||||
|
@ -349,6 +356,7 @@ static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
|
||||||
dmic->fclk_freq = freq;
|
dmic->fclk_freq = freq;
|
||||||
|
|
||||||
err_busy:
|
err_busy:
|
||||||
|
clk_put(mux);
|
||||||
clk_put(parent_clk);
|
clk_put(parent_clk);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -1536,7 +1536,7 @@ static int rsnd_remove(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rsnd_suspend(struct device *dev)
|
static int __maybe_unused rsnd_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
struct rsnd_priv *priv = dev_get_drvdata(dev);
|
struct rsnd_priv *priv = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
@ -1545,7 +1545,7 @@ static int rsnd_suspend(struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rsnd_resume(struct device *dev)
|
static int __maybe_unused rsnd_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct rsnd_priv *priv = dev_get_drvdata(dev);
|
struct rsnd_priv *priv = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
|
|
@ -513,7 +513,7 @@ static void remove_widget(struct snd_soc_component *comp,
|
||||||
*/
|
*/
|
||||||
if (dobj->widget.kcontrol_type == SND_SOC_TPLG_TYPE_ENUM) {
|
if (dobj->widget.kcontrol_type == SND_SOC_TPLG_TYPE_ENUM) {
|
||||||
/* enumerated widget mixer */
|
/* enumerated widget mixer */
|
||||||
for (i = 0; i < w->num_kcontrols; i++) {
|
for (i = 0; w->kcontrols != NULL && i < w->num_kcontrols; i++) {
|
||||||
struct snd_kcontrol *kcontrol = w->kcontrols[i];
|
struct snd_kcontrol *kcontrol = w->kcontrols[i];
|
||||||
struct soc_enum *se =
|
struct soc_enum *se =
|
||||||
(struct soc_enum *)kcontrol->private_value;
|
(struct soc_enum *)kcontrol->private_value;
|
||||||
|
@ -530,7 +530,7 @@ static void remove_widget(struct snd_soc_component *comp,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* volume mixer or bytes controls */
|
/* volume mixer or bytes controls */
|
||||||
for (i = 0; i < w->num_kcontrols; i++) {
|
for (i = 0; w->kcontrols != NULL && i < w->num_kcontrols; i++) {
|
||||||
struct snd_kcontrol *kcontrol = w->kcontrols[i];
|
struct snd_kcontrol *kcontrol = w->kcontrols[i];
|
||||||
|
|
||||||
if (dobj->widget.kcontrol_type
|
if (dobj->widget.kcontrol_type
|
||||||
|
@ -1325,8 +1325,10 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
|
||||||
ec->hdr.name);
|
ec->hdr.name);
|
||||||
|
|
||||||
kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL);
|
kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL);
|
||||||
if (kc[i].name == NULL)
|
if (kc[i].name == NULL) {
|
||||||
|
kfree(se);
|
||||||
goto err_se;
|
goto err_se;
|
||||||
|
}
|
||||||
kc[i].private_value = (long)se;
|
kc[i].private_value = (long)se;
|
||||||
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
||||||
kc[i].access = ec->hdr.access;
|
kc[i].access = ec->hdr.access;
|
||||||
|
@ -1442,8 +1444,10 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
|
||||||
be->hdr.name, be->hdr.access);
|
be->hdr.name, be->hdr.access);
|
||||||
|
|
||||||
kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL);
|
kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL);
|
||||||
if (kc[i].name == NULL)
|
if (kc[i].name == NULL) {
|
||||||
|
kfree(sbe);
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
kc[i].private_value = (long)sbe;
|
kc[i].private_value = (long)sbe;
|
||||||
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
||||||
kc[i].access = be->hdr.access;
|
kc[i].access = be->hdr.access;
|
||||||
|
@ -2576,7 +2580,7 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index)
|
||||||
|
|
||||||
/* match index */
|
/* match index */
|
||||||
if (dobj->index != index &&
|
if (dobj->index != index &&
|
||||||
dobj->index != SND_SOC_TPLG_INDEX_ALL)
|
index != SND_SOC_TPLG_INDEX_ALL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (dobj->type) {
|
switch (dobj->type) {
|
||||||
|
|
|
@ -1776,7 +1776,8 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
|
||||||
build_feature_ctl(state, _ftr, ch_bits, control,
|
build_feature_ctl(state, _ftr, ch_bits, control,
|
||||||
&iterm, unitid, ch_read_only);
|
&iterm, unitid, ch_read_only);
|
||||||
if (uac_v2v3_control_is_readable(master_bits, control))
|
if (uac_v2v3_control_is_readable(master_bits, control))
|
||||||
build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
|
build_feature_ctl(state, _ftr, 0, control,
|
||||||
|
&iterm, unitid,
|
||||||
!uac_v2v3_control_is_writeable(master_bits,
|
!uac_v2v3_control_is_writeable(master_bits,
|
||||||
control));
|
control));
|
||||||
}
|
}
|
||||||
|
@ -1859,7 +1860,7 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
|
||||||
check_input_term(state, d->bTerminalID, &iterm);
|
check_input_term(state, d->bTerminalID, &iterm);
|
||||||
if (state->mixer->protocol == UAC_VERSION_2) {
|
if (state->mixer->protocol == UAC_VERSION_2) {
|
||||||
/* Check for jack detection. */
|
/* Check for jack detection. */
|
||||||
if (uac_v2v3_control_is_readable(d->bmControls,
|
if (uac_v2v3_control_is_readable(le16_to_cpu(d->bmControls),
|
||||||
UAC2_TE_CONNECTOR)) {
|
UAC2_TE_CONNECTOR)) {
|
||||||
build_connector_control(state, &iterm, true);
|
build_connector_control(state, &iterm, true);
|
||||||
}
|
}
|
||||||
|
@ -2561,7 +2562,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
|
||||||
if (err < 0 && err != -EINVAL)
|
if (err < 0 && err != -EINVAL)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (uac_v2v3_control_is_readable(desc->bmControls,
|
if (uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls),
|
||||||
UAC2_TE_CONNECTOR)) {
|
UAC2_TE_CONNECTOR)) {
|
||||||
build_connector_control(&state, &state.oterm,
|
build_connector_control(&state, &state.oterm,
|
||||||
false);
|
false);
|
||||||
|
|
|
@ -353,8 +353,11 @@ static struct usbmix_name_map bose_companion5_map[] = {
|
||||||
/*
|
/*
|
||||||
* Dell usb dock with ALC4020 codec had a firmware problem where it got
|
* Dell usb dock with ALC4020 codec had a firmware problem where it got
|
||||||
* screwed up when zero volume is passed; just skip it as a workaround
|
* screwed up when zero volume is passed; just skip it as a workaround
|
||||||
|
*
|
||||||
|
* Also the extension unit gives an access error, so skip it as well.
|
||||||
*/
|
*/
|
||||||
static const struct usbmix_name_map dell_alc4020_map[] = {
|
static const struct usbmix_name_map dell_alc4020_map[] = {
|
||||||
|
{ 4, NULL }, /* extension unit */
|
||||||
{ 16, NULL },
|
{ 16, NULL },
|
||||||
{ 19, NULL },
|
{ 19, NULL },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
|
|
|
@ -349,7 +349,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
|
||||||
* TODO: this conversion is not complete, update it
|
* TODO: this conversion is not complete, update it
|
||||||
* after adding UAC3 values to asound.h
|
* after adding UAC3 values to asound.h
|
||||||
*/
|
*/
|
||||||
switch (is->bChPurpose) {
|
switch (is->bChRelationship) {
|
||||||
case UAC3_CH_MONO:
|
case UAC3_CH_MONO:
|
||||||
map = SNDRV_CHMAP_MONO;
|
map = SNDRV_CHMAP_MONO;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -139,7 +139,7 @@ static void usb_stream_hwdep_vm_open(struct vm_area_struct *area)
|
||||||
snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
|
snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
|
static vm_fault_t usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
|
||||||
{
|
{
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "usbusx2y.h"
|
#include "usbusx2y.h"
|
||||||
#include "usX2Yhwdep.h"
|
#include "usX2Yhwdep.h"
|
||||||
|
|
||||||
static int snd_us428ctls_vm_fault(struct vm_fault *vmf)
|
static vm_fault_t snd_us428ctls_vm_fault(struct vm_fault *vmf)
|
||||||
{
|
{
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
struct page * page;
|
struct page * page;
|
||||||
|
|
|
@ -652,7 +652,7 @@ static void snd_usX2Y_hwdep_pcm_vm_close(struct vm_area_struct *area)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int snd_usX2Y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
|
static vm_fault_t snd_usX2Y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
|
||||||
{
|
{
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
void *vaddr;
|
void *vaddr;
|
||||||
|
|
Loading…
Reference in New Issue