sound fixes for 5.6-rc1

A collection of pending small fixes since the previous PR.
 
 ALSA core:
 - PCM memory leak fix
 
 ASoC:
 - Lots of SOF and Intel driver fixes
 - Addition of COMMON_CLK for wcd934x
 - Regression fixes for AMD and Tegra platforms
 
 HD-audio:
 - DP-MST HDMI regression fix, Tegra workarounds, HP quirk fix
 
 Others:
 - A few fixes relevant with the recent uapi-updates
 - Sparse warnings and endianness fixes
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAl47+oEOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE+GYg//dNu8r2M6y60btHjaWxblmdhHF3XQ5EwSxvSX
 QT1gm3pg8PMefJNOSD5IhD7Spll6SYz89YpKpPr3NneV5bcDSozdAt50vbtZvqry
 notOqSpL4DubIcYIrhLWI6mq9cIOXIgGnY1cs2KIkoDdNUSDD44nCG1FoUu163tI
 mBPDgjZqAAMseCu4jwRInfE2iUJHGNrkQBDc3+1yZFPog/APoLocRKF7paF1N73f
 A8kGDCoWUmk8mGb93lUxiDg09gK0aCHNmcjIR4Q4MPD16Yg+o1RgGwY81xdyKjs1
 neNCfSCyhYgkON8rvJIsE46qGbqax6/JT7QxCqbyy/Vj4s5MfUivqnWRFwnUisB+
 OoQa37Vd893gjxz1+JvmjrqKTWPmSbHMiuqFj5e1X+HqEVxdKDJMMPwzqlVjRq4K
 Ma18ACK1EQmb4Hsh2U488EjZp/n/FoOmqFSjE6qaHpfdq7YT0bv2lV+f8QFNmliF
 aeJ+ktp6GU2FFV2U4/iZmRUeTZgJpz6m2mLix++Jn11RbSewxj4uyZPKbBYPj7JZ
 NK2l/OgMUxj4qM3ZkgQUOnihIWSqdx0lySgXPWe7fLokMTPNsVr5X2ztD9m1uyX8
 lbJuZsXNGMUS6v3aAy8zoCp2sc1G8heM5Z/WUiZQtUtjpUJ3DATK7sEdv3hLJpFB
 sYw41vs=
 =Mcey
 -----END PGP SIGNATURE-----

Merge tag 'sound-fix-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "A collection of pending small fixes:

  ALSA core:
   - PCM memory leak fix

  ASoC:
   - Lots of SOF and Intel driver fixes
   - Addition of COMMON_CLK for wcd934x
   - Regression fixes for AMD and Tegra platforms

  HD-audio:
   - DP-MST HDMI regression fix, Tegra workarounds, HP quirk fix

  Others:
   - A few fixes relevant with the recent uapi-updates
   - Sparse warnings and endianness fixes"

* tag 'sound-fix-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (35 commits)
  ALSA: hda: Clear RIRB status before reading WP
  ALSA: hda/realtek - Fixed one of HP ALC671 platform Headset Mic supported
  ASoC: wcd934x: Add missing COMMON_CLK dependency to SND_SOC_ALL_CODECS
  ALSA: hda - Fix DP-MST support for NVIDIA codecs
  ASoC: wcd934x: Add missing COMMON_CLK dependency
  MAINTAINERS: Remove the Bard Liao from the MAINTAINERS of Realtek CODECs
  ASoC: tegra: Revert 24 and 32 bit support
  ASoC: SOF: Intel: add PCI ID for JasperLake
  ALSA: hdsp: Make the firmware loading ioctl a bit more readable
  ALSA: emu10k1: Fix annotation and cast for the recent uapi header change
  ALSA: dummy: Fix PCM format loop in proc output
  ALSA: usb-audio: Annotate endianess in Scarlett gen2 quirk
  ALSA: usb-audio: Fix endianess in descriptor validation
  ALSA: hda: Add JasperLake PCI ID and codec vid
  ALSA: pcm: Fix sparse warnings wrt snd_pcm_state_t
  ALSA: pcm: Fix memory leak at closing a stream without hw_free
  ALSA: uapi: Fix sparse warning
  ASoC: rt715: Add __maybe_unused to PM callbacks
  ASoC: rt711: Add __maybe_unused to PM callbacks
  ASoC: rt700: Add __maybe_unused to PM callbacks
  ...
This commit is contained in:
Linus Torvalds 2020-02-06 14:15:01 +00:00
commit 750ce8ccd8
39 changed files with 491 additions and 364 deletions

View File

@ -14106,7 +14106,6 @@ F: include/linux/platform_data/rtc-*
F: tools/testing/selftests/rtc/ F: tools/testing/selftests/rtc/
REALTEK AUDIO CODECS REALTEK AUDIO CODECS
M: Bard Liao <bardliao@realtek.com>
M: Oder Chiou <oder_chiou@realtek.com> M: Oder Chiou <oder_chiou@realtek.com>
S: Maintained S: Maintained
F: sound/soc/codecs/rt* F: sound/soc/codecs/rt*

View File

@ -1450,7 +1450,7 @@ struct snd_pcm_status64 {
#define SNDRV_PCM_IOCTL_STATUS_EXT64 _IOWR('A', 0x24, struct snd_pcm_status64) #define SNDRV_PCM_IOCTL_STATUS_EXT64 _IOWR('A', 0x24, struct snd_pcm_status64)
struct snd_pcm_status32 { struct snd_pcm_status32 {
s32 state; /* stream state */ snd_pcm_state_t state; /* stream state */
s32 trigger_tstamp_sec; /* time when stream was started/stopped/paused */ s32 trigger_tstamp_sec; /* time when stream was started/stopped/paused */
s32 trigger_tstamp_nsec; s32 trigger_tstamp_nsec;
s32 tstamp_sec; /* reference timestamp */ s32 tstamp_sec; /* reference timestamp */
@ -1461,7 +1461,7 @@ struct snd_pcm_status32 {
u32 avail; /* number of frames available */ u32 avail; /* number of frames available */
u32 avail_max; /* max frames available on hw since last status */ u32 avail_max; /* max frames available on hw since last status */
u32 overrange; /* count of ADC (capture) overrange detections from last status */ u32 overrange; /* count of ADC (capture) overrange detections from last status */
s32 suspended_state; /* suspended stream state */ snd_pcm_state_t suspended_state; /* suspended stream state */
u32 audio_tstamp_data; /* needed for 64-bit alignment, used for configs/report to/from userspace */ u32 audio_tstamp_data; /* needed for 64-bit alignment, used for configs/report to/from userspace */
s32 audio_tstamp_sec; /* sample counter, wall clock, PHC or on-demand sync'ed */ s32 audio_tstamp_sec; /* sample counter, wall clock, PHC or on-demand sync'ed */
s32 audio_tstamp_nsec; s32 audio_tstamp_nsec;

View File

@ -564,13 +564,13 @@ typedef char __pad_after_uframe[sizeof(__u64) - sizeof(snd_pcm_uframes_t)];
#endif #endif
struct __snd_pcm_mmap_status64 { struct __snd_pcm_mmap_status64 {
__s32 state; /* RO: state - SNDRV_PCM_STATE_XXXX */ snd_pcm_state_t state; /* RO: state - SNDRV_PCM_STATE_XXXX */
__u32 pad1; /* Needed for 64 bit alignment */ __u32 pad1; /* Needed for 64 bit alignment */
__pad_before_uframe __pad1; __pad_before_uframe __pad1;
snd_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */ snd_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */
__pad_after_uframe __pad2; __pad_after_uframe __pad2;
struct __snd_timespec64 tstamp; /* Timestamp */ struct __snd_timespec64 tstamp; /* Timestamp */
__s32 suspended_state; /* RO: suspended stream state */ snd_pcm_state_t suspended_state;/* RO: suspended stream state */
__u32 pad3; /* Needed for 64 bit alignment */ __u32 pad3; /* Needed for 64 bit alignment */
struct __snd_timespec64 audio_tstamp; /* sample counter or wall clock */ struct __snd_timespec64 audio_tstamp; /* sample counter or wall clock */
}; };

View File

@ -156,7 +156,7 @@ static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
#endif /* CONFIG_X86_X32 */ #endif /* CONFIG_X86_X32 */
struct compat_snd_pcm_status64 { struct compat_snd_pcm_status64 {
s32 state; snd_pcm_state_t state;
u8 rsvd[4]; /* alignment */ u8 rsvd[4]; /* alignment */
s64 trigger_tstamp_sec; s64 trigger_tstamp_sec;
s64 trigger_tstamp_nsec; s64 trigger_tstamp_nsec;
@ -168,7 +168,7 @@ struct compat_snd_pcm_status64 {
u32 avail; u32 avail;
u32 avail_max; u32 avail_max;
u32 overrange; u32 overrange;
s32 suspended_state; snd_pcm_state_t suspended_state;
u32 audio_tstamp_data; u32 audio_tstamp_data;
s64 audio_tstamp_sec; s64 audio_tstamp_sec;
s64 audio_tstamp_nsec; s64 audio_tstamp_nsec;
@ -376,13 +376,13 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
#ifdef CONFIG_X86_X32 #ifdef CONFIG_X86_X32
/* X32 ABI has 64bit timespec and 64bit alignment */ /* X32 ABI has 64bit timespec and 64bit alignment */
struct snd_pcm_mmap_status_x32 { struct snd_pcm_mmap_status_x32 {
s32 state; snd_pcm_state_t state;
s32 pad1; s32 pad1;
u32 hw_ptr; u32 hw_ptr;
u32 pad2; /* alignment */ u32 pad2; /* alignment */
s64 tstamp_sec; s64 tstamp_sec;
s64 tstamp_nsec; s64 tstamp_nsec;
s32 suspended_state; snd_pcm_state_t suspended_state;
s32 pad3; s32 pad3;
s64 audio_tstamp_sec; s64 audio_tstamp_sec;
s64 audio_tstamp_nsec; s64 audio_tstamp_nsec;

View File

@ -551,7 +551,8 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime)
return usecs; return usecs;
} }
static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state) static void snd_pcm_set_state(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED) if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED)
@ -786,10 +787,22 @@ static int snd_pcm_hw_params_user(struct snd_pcm_substream *substream,
return err; return err;
} }
static int do_hw_free(struct snd_pcm_substream *substream)
{
int result = 0;
snd_pcm_sync_stop(substream);
if (substream->ops->hw_free)
result = substream->ops->hw_free(substream);
if (substream->managed_buffer_alloc)
snd_pcm_lib_free_pages(substream);
return result;
}
static int snd_pcm_hw_free(struct snd_pcm_substream *substream) static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
{ {
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
int result = 0; int result;
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return -ENXIO; return -ENXIO;
@ -806,11 +819,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
if (atomic_read(&substream->mmap_count)) if (atomic_read(&substream->mmap_count))
return -EBADFD; return -EBADFD;
snd_pcm_sync_stop(substream); result = do_hw_free(substream);
if (substream->ops->hw_free)
result = substream->ops->hw_free(substream);
if (substream->managed_buffer_alloc)
snd_pcm_lib_free_pages(substream);
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
pm_qos_remove_request(&substream->latency_pm_qos_req); pm_qos_remove_request(&substream->latency_pm_qos_req);
return result; return result;
@ -1097,11 +1106,17 @@ static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
runtime->trigger_master = NULL; runtime->trigger_master = NULL;
} }
#define ACTION_ARG_IGNORE (__force snd_pcm_state_t)0
struct action_ops { struct action_ops {
int (*pre_action)(struct snd_pcm_substream *substream, int state); int (*pre_action)(struct snd_pcm_substream *substream,
int (*do_action)(struct snd_pcm_substream *substream, int state); snd_pcm_state_t state);
void (*undo_action)(struct snd_pcm_substream *substream, int state); int (*do_action)(struct snd_pcm_substream *substream,
void (*post_action)(struct snd_pcm_substream *substream, int state); snd_pcm_state_t state);
void (*undo_action)(struct snd_pcm_substream *substream,
snd_pcm_state_t state);
void (*post_action)(struct snd_pcm_substream *substream,
snd_pcm_state_t state);
}; };
/* /*
@ -1111,7 +1126,8 @@ struct action_ops {
*/ */
static int snd_pcm_action_group(const struct action_ops *ops, static int snd_pcm_action_group(const struct action_ops *ops,
struct snd_pcm_substream *substream, struct snd_pcm_substream *substream,
int state, int do_lock) snd_pcm_state_t state,
bool do_lock)
{ {
struct snd_pcm_substream *s = NULL; struct snd_pcm_substream *s = NULL;
struct snd_pcm_substream *s1; struct snd_pcm_substream *s1;
@ -1168,7 +1184,7 @@ static int snd_pcm_action_group(const struct action_ops *ops,
*/ */
static int snd_pcm_action_single(const struct action_ops *ops, static int snd_pcm_action_single(const struct action_ops *ops,
struct snd_pcm_substream *substream, struct snd_pcm_substream *substream,
int state) snd_pcm_state_t state)
{ {
int res; int res;
@ -1249,14 +1265,14 @@ snd_pcm_stream_group_ref(struct snd_pcm_substream *substream)
*/ */
static int snd_pcm_action(const struct action_ops *ops, static int snd_pcm_action(const struct action_ops *ops,
struct snd_pcm_substream *substream, struct snd_pcm_substream *substream,
int state) snd_pcm_state_t state)
{ {
struct snd_pcm_group *group; struct snd_pcm_group *group;
int res; int res;
group = snd_pcm_stream_group_ref(substream); group = snd_pcm_stream_group_ref(substream);
if (group) if (group)
res = snd_pcm_action_group(ops, substream, state, 1); res = snd_pcm_action_group(ops, substream, state, true);
else else
res = snd_pcm_action_single(ops, substream, state); res = snd_pcm_action_single(ops, substream, state);
snd_pcm_group_unref(group, substream); snd_pcm_group_unref(group, substream);
@ -1268,7 +1284,7 @@ static int snd_pcm_action(const struct action_ops *ops,
*/ */
static int snd_pcm_action_lock_irq(const struct action_ops *ops, static int snd_pcm_action_lock_irq(const struct action_ops *ops,
struct snd_pcm_substream *substream, struct snd_pcm_substream *substream,
int state) snd_pcm_state_t state)
{ {
int res; int res;
@ -1282,14 +1298,14 @@ static int snd_pcm_action_lock_irq(const struct action_ops *ops,
*/ */
static int snd_pcm_action_nonatomic(const struct action_ops *ops, static int snd_pcm_action_nonatomic(const struct action_ops *ops,
struct snd_pcm_substream *substream, struct snd_pcm_substream *substream,
int state) snd_pcm_state_t state)
{ {
int res; int res;
/* Guarantee the group members won't change during non-atomic action */ /* Guarantee the group members won't change during non-atomic action */
down_read(&snd_pcm_link_rwsem); down_read(&snd_pcm_link_rwsem);
if (snd_pcm_stream_linked(substream)) if (snd_pcm_stream_linked(substream))
res = snd_pcm_action_group(ops, substream, state, 0); res = snd_pcm_action_group(ops, substream, state, false);
else else
res = snd_pcm_action_single(ops, substream, state); res = snd_pcm_action_single(ops, substream, state);
up_read(&snd_pcm_link_rwsem); up_read(&snd_pcm_link_rwsem);
@ -1299,7 +1315,8 @@ static int snd_pcm_action_nonatomic(const struct action_ops *ops,
/* /*
* start callbacks * start callbacks
*/ */
static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state) static int snd_pcm_pre_start(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (runtime->status->state != SNDRV_PCM_STATE_PREPARED) if (runtime->status->state != SNDRV_PCM_STATE_PREPARED)
@ -1312,20 +1329,23 @@ static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state)
return 0; return 0;
} }
static int snd_pcm_do_start(struct snd_pcm_substream *substream, int state) static int snd_pcm_do_start(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
if (substream->runtime->trigger_master != substream) if (substream->runtime->trigger_master != substream)
return 0; return 0;
return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START); return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
} }
static void snd_pcm_undo_start(struct snd_pcm_substream *substream, int state) static void snd_pcm_undo_start(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
if (substream->runtime->trigger_master == substream) if (substream->runtime->trigger_master == substream)
substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
} }
static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state) static void snd_pcm_post_start(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream); snd_pcm_trigger_tstamp(substream);
@ -1369,7 +1389,8 @@ static int snd_pcm_start_lock_irq(struct snd_pcm_substream *substream)
/* /*
* stop callbacks * stop callbacks
*/ */
static int snd_pcm_pre_stop(struct snd_pcm_substream *substream, int state) static int snd_pcm_pre_stop(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
@ -1378,7 +1399,8 @@ static int snd_pcm_pre_stop(struct snd_pcm_substream *substream, int state)
return 0; return 0;
} }
static int snd_pcm_do_stop(struct snd_pcm_substream *substream, int state) static int snd_pcm_do_stop(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
if (substream->runtime->trigger_master == substream && if (substream->runtime->trigger_master == substream &&
snd_pcm_running(substream)) snd_pcm_running(substream))
@ -1386,7 +1408,8 @@ static int snd_pcm_do_stop(struct snd_pcm_substream *substream, int state)
return 0; /* unconditonally stop all substreams */ return 0; /* unconditonally stop all substreams */
} }
static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state) static void snd_pcm_post_stop(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (runtime->status->state != state) { if (runtime->status->state != state) {
@ -1457,14 +1480,17 @@ int snd_pcm_stop_xrun(struct snd_pcm_substream *substream)
EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun); EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun);
/* /*
* pause callbacks * pause callbacks: pass boolean (to start pause or resume) as state argument
*/ */
static int snd_pcm_pre_pause(struct snd_pcm_substream *substream, int push) #define pause_pushed(state) (__force bool)(state)
static int snd_pcm_pre_pause(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (!(runtime->info & SNDRV_PCM_INFO_PAUSE)) if (!(runtime->info & SNDRV_PCM_INFO_PAUSE))
return -ENOSYS; return -ENOSYS;
if (push) { if (pause_pushed(state)) {
if (runtime->status->state != SNDRV_PCM_STATE_RUNNING) if (runtime->status->state != SNDRV_PCM_STATE_RUNNING)
return -EBADFD; return -EBADFD;
} else if (runtime->status->state != SNDRV_PCM_STATE_PAUSED) } else if (runtime->status->state != SNDRV_PCM_STATE_PAUSED)
@ -1473,13 +1499,14 @@ static int snd_pcm_pre_pause(struct snd_pcm_substream *substream, int push)
return 0; return 0;
} }
static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push) static int snd_pcm_do_pause(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
if (substream->runtime->trigger_master != substream) if (substream->runtime->trigger_master != substream)
return 0; return 0;
/* some drivers might use hw_ptr to recover from the pause - /* some drivers might use hw_ptr to recover from the pause -
update the hw_ptr now */ update the hw_ptr now */
if (push) if (pause_pushed(state))
snd_pcm_update_hw_ptr(substream); snd_pcm_update_hw_ptr(substream);
/* The jiffies check in snd_pcm_update_hw_ptr*() is done by /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
* a delta between the current jiffies, this gives a large enough * a delta between the current jiffies, this gives a large enough
@ -1487,23 +1514,27 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
*/ */
substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000; substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
return substream->ops->trigger(substream, return substream->ops->trigger(substream,
push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH : pause_pushed(state) ?
SNDRV_PCM_TRIGGER_PAUSE_RELEASE); SNDRV_PCM_TRIGGER_PAUSE_PUSH :
SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
} }
static void snd_pcm_undo_pause(struct snd_pcm_substream *substream, int push) static void snd_pcm_undo_pause(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
if (substream->runtime->trigger_master == substream) if (substream->runtime->trigger_master == substream)
substream->ops->trigger(substream, substream->ops->trigger(substream,
push ? SNDRV_PCM_TRIGGER_PAUSE_RELEASE : pause_pushed(state) ?
SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
SNDRV_PCM_TRIGGER_PAUSE_PUSH); SNDRV_PCM_TRIGGER_PAUSE_PUSH);
} }
static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push) static void snd_pcm_post_pause(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream); snd_pcm_trigger_tstamp(substream);
if (push) { if (pause_pushed(state)) {
runtime->status->state = SNDRV_PCM_STATE_PAUSED; runtime->status->state = SNDRV_PCM_STATE_PAUSED;
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MPAUSE); snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MPAUSE);
wake_up(&runtime->sleep); wake_up(&runtime->sleep);
@ -1524,15 +1555,24 @@ static const struct action_ops snd_pcm_action_pause = {
/* /*
* Push/release the pause for all linked streams. * Push/release the pause for all linked streams.
*/ */
static int snd_pcm_pause(struct snd_pcm_substream *substream, int push) static int snd_pcm_pause(struct snd_pcm_substream *substream, bool push)
{ {
return snd_pcm_action(&snd_pcm_action_pause, substream, push); return snd_pcm_action(&snd_pcm_action_pause, substream,
(__force snd_pcm_state_t)push);
}
static int snd_pcm_pause_lock_irq(struct snd_pcm_substream *substream,
bool push)
{
return snd_pcm_action_lock_irq(&snd_pcm_action_pause, substream,
(__force snd_pcm_state_t)push);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* suspend */ /* suspend callback: state argument ignored */
static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state) static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
switch (runtime->status->state) { switch (runtime->status->state) {
@ -1548,7 +1588,8 @@ static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state)
return 0; return 0;
} }
static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, int state) static int snd_pcm_do_suspend(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (runtime->trigger_master != substream) if (runtime->trigger_master != substream)
@ -1559,7 +1600,8 @@ static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, int state)
return 0; /* suspend unconditionally */ return 0; /* suspend unconditionally */
} }
static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state) static void snd_pcm_post_suspend(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream); snd_pcm_trigger_tstamp(substream);
@ -1590,7 +1632,8 @@ static int snd_pcm_suspend(struct snd_pcm_substream *substream)
unsigned long flags; unsigned long flags;
snd_pcm_stream_lock_irqsave(substream, flags); snd_pcm_stream_lock_irqsave(substream, flags);
err = snd_pcm_action(&snd_pcm_action_suspend, substream, 0); err = snd_pcm_action(&snd_pcm_action_suspend, substream,
ACTION_ARG_IGNORE);
snd_pcm_stream_unlock_irqrestore(substream, flags); snd_pcm_stream_unlock_irqrestore(substream, flags);
return err; return err;
} }
@ -1634,9 +1677,10 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)
} }
EXPORT_SYMBOL(snd_pcm_suspend_all); EXPORT_SYMBOL(snd_pcm_suspend_all);
/* resume */ /* resume callbacks: state argument ignored */
static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state) static int snd_pcm_pre_resume(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (!(runtime->info & SNDRV_PCM_INFO_RESUME)) if (!(runtime->info & SNDRV_PCM_INFO_RESUME))
@ -1645,7 +1689,8 @@ static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
return 0; return 0;
} }
static int snd_pcm_do_resume(struct snd_pcm_substream *substream, int state) static int snd_pcm_do_resume(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (runtime->trigger_master != substream) if (runtime->trigger_master != substream)
@ -1658,14 +1703,16 @@ static int snd_pcm_do_resume(struct snd_pcm_substream *substream, int state)
return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME); return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME);
} }
static void snd_pcm_undo_resume(struct snd_pcm_substream *substream, int state) static void snd_pcm_undo_resume(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
if (substream->runtime->trigger_master == substream && if (substream->runtime->trigger_master == substream &&
snd_pcm_running(substream)) snd_pcm_running(substream))
substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND); substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
} }
static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state) static void snd_pcm_post_resume(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream); snd_pcm_trigger_tstamp(substream);
@ -1683,7 +1730,8 @@ static const struct action_ops snd_pcm_action_resume = {
static int snd_pcm_resume(struct snd_pcm_substream *substream) static int snd_pcm_resume(struct snd_pcm_substream *substream)
{ {
return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0); return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream,
ACTION_ARG_IGNORE);
} }
#else #else
@ -1724,7 +1772,9 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream)
/* /*
* reset ioctl * reset ioctl
*/ */
static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state) /* reset callbacks: state argument ignored */
static int snd_pcm_pre_reset(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
switch (runtime->status->state) { switch (runtime->status->state) {
@ -1738,7 +1788,8 @@ static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state)
} }
} }
static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state) static int snd_pcm_do_reset(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
int err = snd_pcm_ops_ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL); int err = snd_pcm_ops_ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
@ -1752,7 +1803,8 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
return 0; return 0;
} }
static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state) static void snd_pcm_post_reset(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
runtime->control->appl_ptr = runtime->status->hw_ptr; runtime->control->appl_ptr = runtime->status->hw_ptr;
@ -1769,17 +1821,20 @@ static const struct action_ops snd_pcm_action_reset = {
static int snd_pcm_reset(struct snd_pcm_substream *substream) static int snd_pcm_reset(struct snd_pcm_substream *substream)
{ {
return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream, 0); return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream,
ACTION_ARG_IGNORE);
} }
/* /*
* prepare ioctl * prepare ioctl
*/ */
/* we use the second argument for updating f_flags */ /* pass f_flags as state argument */
static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
int f_flags) snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
int f_flags = (__force int)state;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN || if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
@ -1789,17 +1844,19 @@ static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static int snd_pcm_do_prepare(struct snd_pcm_substream *substream, int state) static int snd_pcm_do_prepare(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
int err; int err;
snd_pcm_sync_stop(substream); snd_pcm_sync_stop(substream);
err = substream->ops->prepare(substream); err = substream->ops->prepare(substream);
if (err < 0) if (err < 0)
return err; return err;
return snd_pcm_do_reset(substream, 0); return snd_pcm_do_reset(substream, state);
} }
static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state) static void snd_pcm_post_prepare(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
runtime->control->appl_ptr = runtime->status->hw_ptr; runtime->control->appl_ptr = runtime->status->hw_ptr;
@ -1832,7 +1889,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
switch (substream->runtime->status->state) { switch (substream->runtime->status->state) {
case SNDRV_PCM_STATE_PAUSED: case SNDRV_PCM_STATE_PAUSED:
snd_pcm_pause(substream, 0); snd_pcm_pause(substream, false);
/* fallthru */ /* fallthru */
case SNDRV_PCM_STATE_SUSPENDED: case SNDRV_PCM_STATE_SUSPENDED:
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
@ -1841,14 +1898,17 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
return snd_pcm_action_nonatomic(&snd_pcm_action_prepare, return snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
substream, f_flags); substream,
(__force snd_pcm_state_t)f_flags);
} }
/* /*
* drain ioctl * drain ioctl
*/ */
static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) /* drain init callbacks: state argument ignored */
static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
switch (runtime->status->state) { switch (runtime->status->state) {
@ -1861,7 +1921,8 @@ static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state
return 0; return 0;
} }
static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state) static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@ -1887,7 +1948,9 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
} else { } else {
/* stop running stream */ /* stop running stream */
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) { if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
int new_state = snd_pcm_capture_avail(runtime) > 0 ? snd_pcm_state_t new_state;
new_state = snd_pcm_capture_avail(runtime) > 0 ?
SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP; SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP;
snd_pcm_do_stop(substream, new_state); snd_pcm_do_stop(substream, new_state);
snd_pcm_post_stop(substream, new_state); snd_pcm_post_stop(substream, new_state);
@ -1903,7 +1966,8 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
return 0; return 0;
} }
static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream, int state) static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{ {
} }
@ -1946,10 +2010,11 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
/* resume pause */ /* resume pause */
if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
snd_pcm_pause(substream, 0); snd_pcm_pause(substream, false);
/* pre-start/stop - all running streams are changed to DRAINING state */ /* pre-start/stop - all running streams are changed to DRAINING state */
result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0); result = snd_pcm_action(&snd_pcm_action_drain_init, substream,
ACTION_ARG_IGNORE);
if (result < 0) if (result < 0)
goto unlock; goto unlock;
/* in non-blocking, we don't wait in ioctl but let caller poll */ /* in non-blocking, we don't wait in ioctl but let caller poll */
@ -2050,7 +2115,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
/* resume pause */ /* resume pause */
if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
snd_pcm_pause(substream, 0); snd_pcm_pause(substream, false);
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
/* runtime->control->appl_ptr = runtime->status->hw_ptr; */ /* runtime->control->appl_ptr = runtime->status->hw_ptr; */
@ -2529,9 +2594,7 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
snd_pcm_drop(substream); snd_pcm_drop(substream);
if (substream->hw_opened) { if (substream->hw_opened) {
if (substream->ops->hw_free && do_hw_free(substream);
substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
substream->ops->hw_free(substream);
substream->ops->close(substream); substream->ops->close(substream);
substream->hw_opened = 0; substream->hw_opened = 0;
} }
@ -2894,12 +2957,12 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
} }
struct snd_pcm_mmap_status32 { struct snd_pcm_mmap_status32 {
s32 state; snd_pcm_state_t state;
s32 pad1; s32 pad1;
u32 hw_ptr; u32 hw_ptr;
s32 tstamp_sec; s32 tstamp_sec;
s32 tstamp_nsec; s32 tstamp_nsec;
s32 suspended_state; snd_pcm_state_t suspended_state;
s32 audio_tstamp_sec; s32 audio_tstamp_sec;
s32 audio_tstamp_nsec; s32 audio_tstamp_nsec;
} __attribute__((packed)); } __attribute__((packed));
@ -3177,9 +3240,7 @@ static int snd_pcm_common_ioctl(struct file *file,
case SNDRV_PCM_IOCTL_DROP: case SNDRV_PCM_IOCTL_DROP:
return snd_pcm_drop(substream); return snd_pcm_drop(substream);
case SNDRV_PCM_IOCTL_PAUSE: case SNDRV_PCM_IOCTL_PAUSE:
return snd_pcm_action_lock_irq(&snd_pcm_action_pause, return snd_pcm_pause_lock_irq(substream, (unsigned long)arg);
substream,
(int)(unsigned long)arg);
case SNDRV_PCM_IOCTL_WRITEI_FRAMES: case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
case SNDRV_PCM_IOCTL_READI_FRAMES: case SNDRV_PCM_IOCTL_READI_FRAMES:
return snd_pcm_xferi_frames_ioctl(substream, arg); return snd_pcm_xferi_frames_ioctl(substream, arg);

View File

@ -903,7 +903,7 @@ static void print_formats(struct snd_dummy *dummy,
{ {
int i; int i;
for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
if (dummy->pcm_hw.formats & (1ULL << i)) if (dummy->pcm_hw.formats & (1ULL << i))
snd_iprintf(buffer, " %s", snd_pcm_format_name(i)); snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
} }

View File

@ -631,20 +631,27 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
nwait = 0; nwait = 0;
i = 0; i = 0;
list_for_each_entry(s, &bus->stream_list, list) { list_for_each_entry(s, &bus->stream_list, list) {
if (streams & (1 << i)) { if (!(streams & (1 << i++)))
if (start) { continue;
/* check FIFO gets ready */
if (!(snd_hdac_stream_readb(s, SD_STS) & if (start) {
SD_STS_FIFO_READY)) /* check FIFO gets ready */
nwait++; if (!(snd_hdac_stream_readb(s, SD_STS) &
} else { SD_STS_FIFO_READY))
/* check RUN bit is cleared */ nwait++;
if (snd_hdac_stream_readb(s, SD_CTL) & } else {
SD_CTL_DMA_START) /* check RUN bit is cleared */
nwait++; if (snd_hdac_stream_readb(s, SD_CTL) &
SD_CTL_DMA_START) {
nwait++;
/*
* Perform stream reset if DMA RUN
* bit not cleared within given timeout
*/
if (timeout == 1)
snd_hdac_stream_reset(s);
} }
} }
i++;
} }
if (!nwait) if (!nwait)
break; break;

View File

@ -463,7 +463,7 @@ static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
u_int32_t *code; u_int32_t *code;
if (snd_BUG_ON(*ptr >= 512)) if (snd_BUG_ON(*ptr >= 512))
return; return;
code = (u_int32_t __force *)icode->code + (*ptr) * 2; code = icode->code + (*ptr) * 2;
set_bit(*ptr, icode->code_valid); set_bit(*ptr, icode->code_valid);
code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff); code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff); code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
@ -480,7 +480,7 @@ static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
u_int32_t *code; u_int32_t *code;
if (snd_BUG_ON(*ptr >= 1024)) if (snd_BUG_ON(*ptr >= 1024))
return; return;
code = (u_int32_t __force *)icode->code + (*ptr) * 2; code = icode->code + (*ptr) * 2;
set_bit(*ptr, icode->code_valid); set_bit(*ptr, icode->code_valid);
code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff); code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff); code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
@ -513,8 +513,8 @@ static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
if (!test_bit(gpr, icode->gpr_valid)) if (!test_bit(gpr, icode->gpr_valid))
continue; continue;
if (in_kernel) if (in_kernel)
val = *(__force u32 *)&icode->gpr_map[gpr]; val = icode->gpr_map[gpr];
else if (get_user(val, &icode->gpr_map[gpr])) else if (get_user(val, (__user u32 *)&icode->gpr_map[gpr]))
return -EFAULT; return -EFAULT;
snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val); snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
} }
@ -530,7 +530,7 @@ static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) { for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
set_bit(gpr, icode->gpr_valid); set_bit(gpr, icode->gpr_valid);
val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0); val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
if (put_user(val, &icode->gpr_map[gpr])) if (put_user(val, (__user u32 *)&icode->gpr_map[gpr]))
return -EFAULT; return -EFAULT;
} }
return 0; return 0;
@ -547,11 +547,11 @@ static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
if (!test_bit(tram, icode->tram_valid)) if (!test_bit(tram, icode->tram_valid))
continue; continue;
if (in_kernel) { if (in_kernel) {
val = *(__force u32 *)&icode->tram_data_map[tram]; val = icode->tram_data_map[tram];
addr = *(__force u32 *)&icode->tram_addr_map[tram]; addr = icode->tram_addr_map[tram];
} else { } else {
if (get_user(val, &icode->tram_data_map[tram]) || if (get_user(val, (__user __u32 *)&icode->tram_data_map[tram]) ||
get_user(addr, &icode->tram_addr_map[tram])) get_user(addr, (__user __u32 *)&icode->tram_addr_map[tram]))
return -EFAULT; return -EFAULT;
} }
snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val); snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
@ -581,8 +581,8 @@ static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12; addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20; addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
} }
if (put_user(val, &icode->tram_data_map[tram]) || if (put_user(val, (__user u32 *)&icode->tram_data_map[tram]) ||
put_user(addr, &icode->tram_addr_map[tram])) put_user(addr, (__user u32 *)&icode->tram_addr_map[tram]))
return -EFAULT; return -EFAULT;
} }
return 0; return 0;
@ -598,11 +598,11 @@ static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
if (!test_bit(pc / 2, icode->code_valid)) if (!test_bit(pc / 2, icode->code_valid))
continue; continue;
if (in_kernel) { if (in_kernel) {
lo = *(__force u32 *)&icode->code[pc + 0]; lo = icode->code[pc + 0];
hi = *(__force u32 *)&icode->code[pc + 1]; hi = icode->code[pc + 1];
} else { } else {
if (get_user(lo, &icode->code[pc + 0]) || if (get_user(lo, (__user u32 *)&icode->code[pc + 0]) ||
get_user(hi, &icode->code[pc + 1])) get_user(hi, (__user u32 *)&icode->code[pc + 1]))
return -EFAULT; return -EFAULT;
} }
snd_emu10k1_efx_write(emu, pc + 0, lo); snd_emu10k1_efx_write(emu, pc + 0, lo);
@ -619,17 +619,21 @@ static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
memset(icode->code_valid, 0, sizeof(icode->code_valid)); memset(icode->code_valid, 0, sizeof(icode->code_valid));
for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) { for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
set_bit(pc / 2, icode->code_valid); set_bit(pc / 2, icode->code_valid);
if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0])) if (put_user(snd_emu10k1_efx_read(emu, pc + 0),
(__user u32 *)&icode->code[pc + 0]))
return -EFAULT; return -EFAULT;
if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1])) if (put_user(snd_emu10k1_efx_read(emu, pc + 1),
(__user u32 *)&icode->code[pc + 1]))
return -EFAULT; return -EFAULT;
} }
return 0; return 0;
} }
static struct snd_emu10k1_fx8010_ctl * static struct snd_emu10k1_fx8010_ctl *
snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct emu10k1_ctl_elem_id *id) snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu,
struct emu10k1_ctl_elem_id *_id)
{ {
struct snd_ctl_elem_id *id = (struct snd_ctl_elem_id *)_id;
struct snd_emu10k1_fx8010_ctl *ctl; struct snd_emu10k1_fx8010_ctl *ctl;
struct snd_kcontrol *kcontrol; struct snd_kcontrol *kcontrol;
@ -672,41 +676,60 @@ static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel)
} }
static int copy_gctl(struct snd_emu10k1 *emu, static int copy_gctl(struct snd_emu10k1 *emu,
struct snd_emu10k1_fx8010_control_gpr *gctl, struct snd_emu10k1_fx8010_control_gpr *dst,
struct snd_emu10k1_fx8010_control_gpr __user *_gctl, struct snd_emu10k1_fx8010_control_gpr *src,
int idx, bool in_kernel) int idx, bool in_kernel)
{ {
struct snd_emu10k1_fx8010_control_old_gpr __user *octl; struct snd_emu10k1_fx8010_control_gpr __user *_src;
struct snd_emu10k1_fx8010_control_old_gpr *octl;
struct snd_emu10k1_fx8010_control_old_gpr __user *_octl;
_src = (struct snd_emu10k1_fx8010_control_gpr __user *)src;
if (emu->support_tlv) { if (emu->support_tlv) {
if (in_kernel) if (in_kernel)
memcpy(gctl, (__force void *)&_gctl[idx], sizeof(*gctl)); *dst = src[idx];
else if (copy_from_user(gctl, &_gctl[idx], sizeof(*gctl))) else if (copy_from_user(dst, &_src[idx], sizeof(*src)))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl; octl = (struct snd_emu10k1_fx8010_control_old_gpr *)src;
_octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)octl;
if (in_kernel) if (in_kernel)
memcpy(gctl, (__force void *)&octl[idx], sizeof(*octl)); memcpy(dst, &octl[idx], sizeof(*octl));
else if (copy_from_user(gctl, &octl[idx], sizeof(*octl))) else if (copy_from_user(dst, &_octl[idx], sizeof(*octl)))
return -EFAULT; return -EFAULT;
gctl->tlv = NULL; dst->tlv = NULL;
return 0; return 0;
} }
static int copy_gctl_to_user(struct snd_emu10k1 *emu, static int copy_gctl_to_user(struct snd_emu10k1 *emu,
struct snd_emu10k1_fx8010_control_gpr __user *_gctl, struct snd_emu10k1_fx8010_control_gpr *dst,
struct snd_emu10k1_fx8010_control_gpr *gctl, struct snd_emu10k1_fx8010_control_gpr *src,
int idx) int idx)
{ {
struct snd_emu10k1_fx8010_control_gpr __user *_dst;
struct snd_emu10k1_fx8010_control_old_gpr __user *octl; struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
_dst = (struct snd_emu10k1_fx8010_control_gpr __user *)dst;
if (emu->support_tlv) if (emu->support_tlv)
return copy_to_user(&_gctl[idx], gctl, sizeof(*gctl)); return copy_to_user(&_dst[idx], src, sizeof(*src));
octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl; octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)dst;
return copy_to_user(&octl[idx], gctl, sizeof(*octl)); return copy_to_user(&octl[idx], src, sizeof(*octl));
}
static int copy_ctl_elem_id(const struct emu10k1_ctl_elem_id *list, int i,
struct emu10k1_ctl_elem_id *ret, bool in_kernel)
{
struct emu10k1_ctl_elem_id __user *_id =
(struct emu10k1_ctl_elem_id __user *)&list[i];
if (in_kernel)
*ret = list[i];
else if (copy_from_user(ret, _id, sizeof(*ret)))
return -EFAULT;
return 0;
} }
static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
@ -714,17 +737,16 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
bool in_kernel) bool in_kernel)
{ {
unsigned int i; unsigned int i;
struct emu10k1_ctl_elem_id __user *_id;
struct emu10k1_ctl_elem_id id; struct emu10k1_ctl_elem_id id;
struct snd_emu10k1_fx8010_control_gpr *gctl; struct snd_emu10k1_fx8010_control_gpr *gctl;
struct snd_ctl_elem_id *gctl_id;
int err; int err;
_id = (__force struct emu10k1_ctl_elem_id __user *)icode->gpr_del_controls; for (i = 0; i < icode->gpr_del_control_count; i++) {
for (i = 0; i < icode->gpr_del_control_count; i++, _id++) { err = copy_ctl_elem_id(icode->gpr_del_controls, i, &id,
if (in_kernel) in_kernel);
id = *(__force struct emu10k1_ctl_elem_id *)_id; if (err < 0)
else if (copy_from_user(&id, _id, sizeof(id))) return err;
return -EFAULT;
if (snd_emu10k1_look_for_ctl(emu, &id) == NULL) if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
return -ENOENT; return -ENOENT;
} }
@ -740,16 +762,16 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
} }
if (snd_emu10k1_look_for_ctl(emu, &gctl->id)) if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
continue; continue;
gctl_id = (struct snd_ctl_elem_id *)&gctl->id;
down_read(&emu->card->controls_rwsem); down_read(&emu->card->controls_rwsem);
if (snd_ctl_find_id(emu->card, if (snd_ctl_find_id(emu->card, gctl_id)) {
(struct snd_ctl_elem_id *)&gctl->id)) {
up_read(&emu->card->controls_rwsem); up_read(&emu->card->controls_rwsem);
err = -EEXIST; err = -EEXIST;
goto __error; goto __error;
} }
up_read(&emu->card->controls_rwsem); up_read(&emu->card->controls_rwsem);
if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER && if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) { gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) {
err = -EINVAL; err = -EINVAL;
goto __error; goto __error;
} }
@ -784,6 +806,7 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
{ {
unsigned int i, j; unsigned int i, j;
struct snd_emu10k1_fx8010_control_gpr *gctl; struct snd_emu10k1_fx8010_control_gpr *gctl;
struct snd_ctl_elem_id *gctl_id;
struct snd_emu10k1_fx8010_ctl *ctl, *nctl; struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
struct snd_kcontrol_new knew; struct snd_kcontrol_new knew;
struct snd_kcontrol *kctl; struct snd_kcontrol *kctl;
@ -804,24 +827,25 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
err = -EFAULT; err = -EFAULT;
goto __error; goto __error;
} }
if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER && gctl_id = (struct snd_ctl_elem_id *)&gctl->id;
gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) { if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) {
err = -EINVAL; err = -EINVAL;
goto __error; goto __error;
} }
if (! gctl->id.name[0]) { if (!*gctl_id->name) {
err = -EINVAL; err = -EINVAL;
goto __error; goto __error;
} }
ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id); ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
memset(&knew, 0, sizeof(knew)); memset(&knew, 0, sizeof(knew));
knew.iface = gctl->id.iface; knew.iface = gctl_id->iface;
knew.name = gctl->id.name; knew.name = gctl_id->name;
knew.index = gctl->id.index; knew.index = gctl_id->index;
knew.device = gctl->id.device; knew.device = gctl_id->device;
knew.subdevice = gctl->id.subdevice; knew.subdevice = gctl_id->subdevice;
knew.info = snd_emu10k1_gpr_ctl_info; knew.info = snd_emu10k1_gpr_ctl_info;
knew.tlv.p = copy_tlv((__force const unsigned int __user *)gctl->tlv, in_kernel); knew.tlv.p = copy_tlv((const unsigned int __user *)gctl->tlv, in_kernel);
if (knew.tlv.p) if (knew.tlv.p)
knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ; SNDRV_CTL_ELEM_ACCESS_TLV_READ;
@ -878,17 +902,15 @@ static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
{ {
unsigned int i; unsigned int i;
struct emu10k1_ctl_elem_id id; struct emu10k1_ctl_elem_id id;
struct emu10k1_ctl_elem_id __user *_id;
struct snd_emu10k1_fx8010_ctl *ctl; struct snd_emu10k1_fx8010_ctl *ctl;
struct snd_card *card = emu->card; struct snd_card *card = emu->card;
int err;
_id = (__force struct emu10k1_ctl_elem_id __user *)icode->gpr_del_controls; for (i = 0; i < icode->gpr_del_control_count; i++) {
err = copy_ctl_elem_id(icode->gpr_del_controls, i, &id,
for (i = 0; i < icode->gpr_del_control_count; i++, _id++) { in_kernel);
if (in_kernel) if (err < 0)
id = *(__force struct emu10k1_ctl_elem_id *)_id; return err;
else if (copy_from_user(&id, _id, sizeof(id)))
return -EFAULT;
down_write(&card->controls_rwsem); down_write(&card->controls_rwsem);
ctl = snd_emu10k1_look_for_ctl(emu, &id); ctl = snd_emu10k1_look_for_ctl(emu, &id);
if (ctl) if (ctl)
@ -917,7 +939,7 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
i < icode->gpr_list_control_count) { i < icode->gpr_list_control_count) {
memset(gctl, 0, sizeof(*gctl)); memset(gctl, 0, sizeof(*gctl));
id = &ctl->kcontrol->id; id = &ctl->kcontrol->id;
gctl->id.iface = id->iface; gctl->id.iface = (__force int)id->iface;
strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name)); strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
gctl->id.index = id->index; gctl->id.index = id->index;
gctl->id.device = id->device; gctl->id.device = id->device;
@ -1095,7 +1117,7 @@ static void
snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl, snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
const char *name, int gpr, int defval) const char *name, int gpr, int defval)
{ {
ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
strcpy(ctl->id.name, name); strcpy(ctl->id.name, name);
ctl->vcount = ctl->count = 1; ctl->vcount = ctl->count = 1;
ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
@ -1116,7 +1138,7 @@ static void
snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl, snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
const char *name, int gpr, int defval) const char *name, int gpr, int defval)
{ {
ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
strcpy(ctl->id.name, name); strcpy(ctl->id.name, name);
ctl->vcount = ctl->count = 2; ctl->vcount = ctl->count = 2;
ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
@ -1138,7 +1160,7 @@ static void
snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl, snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
const char *name, int gpr, int defval) const char *name, int gpr, int defval)
{ {
ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
strcpy(ctl->id.name, name); strcpy(ctl->id.name, name);
ctl->vcount = ctl->count = 1; ctl->vcount = ctl->count = 1;
ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
@ -1151,7 +1173,7 @@ static void
snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl, snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
const char *name, int gpr, int defval) const char *name, int gpr, int defval)
{ {
ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
strcpy(ctl->id.name, name); strcpy(ctl->id.name, name);
ctl->vcount = ctl->count = 2; ctl->vcount = ctl->count = 2;
ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
@ -1204,8 +1226,8 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
if (!icode) if (!icode)
return err; return err;
icode->gpr_map = (u_int32_t __user *) kcalloc(512 + 256 + 256 + 2 * 1024, icode->gpr_map = kcalloc(512 + 256 + 256 + 2 * 1024,
sizeof(u_int32_t), GFP_KERNEL); sizeof(u_int32_t), GFP_KERNEL);
if (!icode->gpr_map) if (!icode->gpr_map)
goto __err_gpr; goto __err_gpr;
controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
@ -1213,7 +1235,7 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
if (!controls) if (!controls)
goto __err_ctrls; goto __err_ctrls;
gpr_map = (u32 __force *)icode->gpr_map; gpr_map = icode->gpr_map;
icode->tram_data_map = icode->gpr_map + 512; icode->tram_data_map = icode->gpr_map + 512;
icode->tram_addr_map = icode->tram_data_map + 256; icode->tram_addr_map = icode->tram_data_map + 256;
@ -1468,7 +1490,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
ctl = &controls[nctl + 0]; ctl = &controls[nctl + 0];
ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
strcpy(ctl->id.name, "Tone Control - Bass"); strcpy(ctl->id.name, "Tone Control - Bass");
ctl->vcount = 2; ctl->vcount = 2;
ctl->count = 10; ctl->count = 10;
@ -1477,7 +1499,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
ctl->value[0] = ctl->value[1] = 20; ctl->value[0] = ctl->value[1] = 20;
ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
ctl = &controls[nctl + 1]; ctl = &controls[nctl + 1];
ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
strcpy(ctl->id.name, "Tone Control - Treble"); strcpy(ctl->id.name, "Tone Control - Treble");
ctl->vcount = 2; ctl->vcount = 2;
ctl->count = 10; ctl->count = 10;
@ -1758,7 +1780,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0); A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
icode->gpr_add_control_count = nctl; icode->gpr_add_control_count = nctl;
icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls; icode->gpr_add_controls = controls;
emu->support_tlv = 1; /* support TLV */ emu->support_tlv = 1; /* support TLV */
err = snd_emu10k1_icode_poke(emu, icode, true); err = snd_emu10k1_icode_poke(emu, icode, true);
emu->support_tlv = 0; /* clear again */ emu->support_tlv = 0; /* clear again */
@ -1766,7 +1788,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
__err: __err:
kfree(controls); kfree(controls);
__err_ctrls: __err_ctrls:
kfree((void __force *)icode->gpr_map); kfree(icode->gpr_map);
__err_gpr: __err_gpr:
kfree(icode); kfree(icode);
return err; return err;
@ -1839,8 +1861,8 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
if (!icode) if (!icode)
return err; return err;
icode->gpr_map = (u_int32_t __user *) kcalloc(256 + 160 + 160 + 2 * 512, icode->gpr_map = kcalloc(256 + 160 + 160 + 2 * 512,
sizeof(u_int32_t), GFP_KERNEL); sizeof(u_int32_t), GFP_KERNEL);
if (!icode->gpr_map) if (!icode->gpr_map)
goto __err_gpr; goto __err_gpr;
@ -1854,7 +1876,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
if (!ipcm) if (!ipcm)
goto __err_ipcm; goto __err_ipcm;
gpr_map = (u32 __force *)icode->gpr_map; gpr_map = icode->gpr_map;
icode->tram_data_map = icode->gpr_map + 256; icode->tram_data_map = icode->gpr_map + 256;
icode->tram_addr_map = icode->tram_data_map + 160; icode->tram_addr_map = icode->tram_data_map + 160;
@ -2188,7 +2210,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */ OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
ctl = &controls[i + 0]; ctl = &controls[i + 0];
ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
strcpy(ctl->id.name, "Tone Control - Bass"); strcpy(ctl->id.name, "Tone Control - Bass");
ctl->vcount = 2; ctl->vcount = 2;
ctl->count = 10; ctl->count = 10;
@ -2198,7 +2220,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
ctl->tlv = snd_emu10k1_bass_treble_db_scale; ctl->tlv = snd_emu10k1_bass_treble_db_scale;
ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
ctl = &controls[i + 1]; ctl = &controls[i + 1];
ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
strcpy(ctl->id.name, "Tone Control - Treble"); strcpy(ctl->id.name, "Tone Control - Treble");
ctl->vcount = 2; ctl->vcount = 2;
ctl->count = 10; ctl->count = 10;
@ -2384,7 +2406,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0) if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
goto __err; goto __err;
icode->gpr_add_control_count = i; icode->gpr_add_control_count = i;
icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls; icode->gpr_add_controls = controls;
emu->support_tlv = 1; /* support TLV */ emu->support_tlv = 1; /* support TLV */
err = snd_emu10k1_icode_poke(emu, icode, true); err = snd_emu10k1_icode_poke(emu, icode, true);
emu->support_tlv = 0; /* clear again */ emu->support_tlv = 0; /* clear again */
@ -2395,7 +2417,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
__err_ipcm: __err_ipcm:
kfree(controls); kfree(controls);
__err_ctrls: __err_ctrls:
kfree((void __force *)icode->gpr_map); kfree(icode->gpr_map);
__err_gpr: __err_gpr:
kfree(icode); kfree(icode);
return err; return err;

View File

@ -1110,16 +1110,23 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)
if (snd_hdac_bus_handle_stream_irq(bus, status, stream_update)) if (snd_hdac_bus_handle_stream_irq(bus, status, stream_update))
active = true; active = true;
/* clear rirb int */
status = azx_readb(chip, RIRBSTS); status = azx_readb(chip, RIRBSTS);
if (status & RIRB_INT_MASK) { if (status & RIRB_INT_MASK) {
/*
* Clearing the interrupt status here ensures that no
* interrupt gets masked after the RIRB wp is read in
* snd_hdac_bus_update_rirb. This avoids a possible
* race condition where codec response in RIRB may
* remain unserviced by IRQ, eventually falling back
* to polling mode in azx_rirb_get_response.
*/
azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
active = true; active = true;
if (status & RIRB_INT_RESPONSE) { if (status & RIRB_INT_RESPONSE) {
if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
udelay(80); udelay(80);
snd_hdac_bus_update_rirb(bus); snd_hdac_bus_update_rirb(bus);
} }
azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
} }
} while (active && ++repeat < 10); } while (active && ++repeat < 10);

View File

@ -2451,6 +2451,8 @@ static const struct pci_device_id azx_ids[] = {
/* Jasperlake */ /* Jasperlake */
{ PCI_DEVICE(0x8086, 0x38c8), { PCI_DEVICE(0x8086, 0x38c8),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
{ PCI_DEVICE(0x8086, 0x4dc8),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
/* Tigerlake */ /* Tigerlake */
{ PCI_DEVICE(0x8086, 0xa0c8), { PCI_DEVICE(0x8086, 0xa0c8),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},

View File

@ -1550,6 +1550,34 @@ static bool update_eld(struct hda_codec *codec,
return eld_changed; return eld_changed;
} }
static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec,
struct hdmi_spec_per_pin *per_pin)
{
struct hdmi_spec *spec = codec->spec;
struct snd_jack *jack = NULL;
struct hda_jack_tbl *jack_tbl;
/* if !dyn_pcm_assign, get jack from hda_jack_tbl
* in !dyn_pcm_assign case, spec->pcm_rec[].jack is not
* NULL even after snd_hda_jack_tbl_clear() is called to
* free snd_jack. This may cause access invalid memory
* when calling snd_jack_report
*/
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_mst(codec, per_pin->pin_nid,
per_pin->dev_id);
if (jack_tbl)
jack = jack_tbl->jack;
}
return jack;
}
/* update ELD and jack state via HD-audio verbs */ /* update ELD and jack state via HD-audio verbs */
static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
int repoll) int repoll)
@ -1571,6 +1599,7 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
int present; int present;
bool ret; bool ret;
bool do_repoll = false; bool do_repoll = false;
struct snd_jack *pcm_jack = NULL;
present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id); present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id);
@ -1598,10 +1627,19 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
do_repoll = true; do_repoll = true;
} }
if (do_repoll) if (do_repoll) {
schedule_delayed_work(&per_pin->work, msecs_to_jiffies(300)); schedule_delayed_work(&per_pin->work, msecs_to_jiffies(300));
else } else {
/*
* pcm_idx >=0 before update_eld() means it is in monitor
* disconnected event. Jack must be fetched before
* update_eld().
*/
pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
update_eld(codec, per_pin, eld); update_eld(codec, per_pin, eld);
if (!pcm_jack)
pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
}
ret = !repoll || !eld->monitor_present || eld->eld_valid; ret = !repoll || !eld->monitor_present || eld->eld_valid;
@ -1610,40 +1648,34 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
jack->block_report = !ret; jack->block_report = !ret;
jack->pin_sense = (eld->monitor_present && eld->eld_valid) ? jack->pin_sense = (eld->monitor_present && eld->eld_valid) ?
AC_PINSENSE_PRESENCE : 0; AC_PINSENSE_PRESENCE : 0;
if (spec->dyn_pcm_assign && pcm_jack && !do_repoll) {
int state = 0;
if (jack->pin_sense & AC_PINSENSE_PRESENCE)
state = SND_JACK_AVOUT;
snd_jack_report(pcm_jack, state);
}
/*
* snd_hda_jack_pin_sense() call at the beginning of this
* function, updates jack->pins_sense and clears
* jack->jack_dirty, therefore snd_hda_jack_report_sync() will
* not override the jack->pin_sense.
*
* snd_hda_jack_report_sync() is superfluous for dyn_pcm_assign
* case. The jack->pin_sense update was already performed, and
* hda_jack->jack is NULL for dyn_pcm_assign.
*
* Don't call snd_hda_jack_report_sync() for
* dyn_pcm_assign.
*/
ret = ret && !spec->dyn_pcm_assign;
} }
mutex_unlock(&per_pin->lock); mutex_unlock(&per_pin->lock);
return ret; return ret;
} }
static struct snd_jack *pin_idx_to_jack(struct hda_codec *codec,
struct hdmi_spec_per_pin *per_pin)
{
struct hdmi_spec *spec = codec->spec;
struct snd_jack *jack = NULL;
struct hda_jack_tbl *jack_tbl;
/* if !dyn_pcm_assign, get jack from hda_jack_tbl
* in !dyn_pcm_assign case, spec->pcm_rec[].jack is not
* NULL even after snd_hda_jack_tbl_clear() is called to
* free snd_jack. This may cause access invalid memory
* when calling snd_jack_report
*/
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_mst(codec, per_pin->pin_nid,
per_pin->dev_id);
if (jack_tbl)
jack = jack_tbl->jack;
}
return jack;
}
/* update ELD and jack state via audio component */ /* update ELD and jack state via audio component */
static void sync_eld_via_acomp(struct hda_codec *codec, static void sync_eld_via_acomp(struct hda_codec *codec,
struct hdmi_spec_per_pin *per_pin) struct hdmi_spec_per_pin *per_pin)
@ -1677,10 +1709,10 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
/* pcm_idx >=0 before update_eld() means it is in monitor /* pcm_idx >=0 before update_eld() means it is in monitor
* disconnected event. Jack must be fetched before update_eld() * disconnected event. Jack must be fetched before update_eld()
*/ */
jack = pin_idx_to_jack(codec, per_pin); jack = pin_idx_to_pcm_jack(codec, per_pin);
changed = update_eld(codec, per_pin, eld); changed = update_eld(codec, per_pin, eld);
if (jack == NULL) if (jack == NULL)
jack = pin_idx_to_jack(codec, per_pin); jack = pin_idx_to_pcm_jack(codec, per_pin);
if (changed && jack) if (changed && jack)
snd_jack_report(jack, snd_jack_report(jack,
(eld->monitor_present && eld->eld_valid) ? (eld->monitor_present && eld->eld_valid) ?
@ -4256,6 +4288,7 @@ HDA_CODEC_ENTRY(0x8086280c, "Cannonlake HDMI", patch_i915_glk_hdmi),
HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi), HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi),
HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI", patch_i915_icl_hdmi), HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI", patch_i915_icl_hdmi),
HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi), HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi),
HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi), HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),
HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi), HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),

View File

@ -9111,6 +9111,7 @@ static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2, SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
{0x14, 0x01014010}, {0x14, 0x01014010},
{0x17, 0x90170150}, {0x17, 0x90170150},
{0x19, 0x02a11060},
{0x1b, 0x01813030}, {0x1b, 0x01813030},
{0x21, 0x02211020}), {0x21, 0x02211020}),
SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2, SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,

View File

@ -4802,7 +4802,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
break; break;
} }
case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: { case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
struct hdsp_firmware __user *firmware; struct hdsp_firmware firmware;
u32 __user *firmware_data; u32 __user *firmware_data;
int err; int err;
@ -4815,10 +4815,9 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
dev_info(hdsp->card->dev, dev_info(hdsp->card->dev,
"initializing firmware upload\n"); "initializing firmware upload\n");
firmware = (struct hdsp_firmware __user *)argp; if (copy_from_user(&firmware, argp, sizeof(firmware)))
if (get_user(firmware_data, (__force void __user **)&firmware->firmware_data))
return -EFAULT; return -EFAULT;
firmware_data = (u32 __user *)firmware.firmware_data;
if (hdsp_check_for_iobox (hdsp)) if (hdsp_check_for_iobox (hdsp))
return -EIO; return -EIO;

View File

@ -234,30 +234,32 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
switch (rtd->i2s_instance) { switch (rtd->i2s_instance) {
case I2S_BT_INSTANCE: case I2S_BT_INSTANCE:
reg_val = mmACP_BTTDM_ITER; reg_val = mmACP_BTTDM_ITER;
ier_val = mmACP_BTTDM_IER;
break; break;
case I2S_SP_INSTANCE: case I2S_SP_INSTANCE:
default: default:
reg_val = mmACP_I2STDM_ITER; reg_val = mmACP_I2STDM_ITER;
ier_val = mmACP_I2STDM_IER;
} }
} else { } else {
switch (rtd->i2s_instance) { switch (rtd->i2s_instance) {
case I2S_BT_INSTANCE: case I2S_BT_INSTANCE:
reg_val = mmACP_BTTDM_IRER; reg_val = mmACP_BTTDM_IRER;
ier_val = mmACP_BTTDM_IER;
break; break;
case I2S_SP_INSTANCE: case I2S_SP_INSTANCE:
default: default:
reg_val = mmACP_I2STDM_IRER; reg_val = mmACP_I2STDM_IRER;
ier_val = mmACP_I2STDM_IER;
} }
} }
val = rv_readl(rtd->acp3x_base + reg_val); val = rv_readl(rtd->acp3x_base + reg_val);
val = val & ~BIT(0); val = val & ~BIT(0);
rv_writel(val, rtd->acp3x_base + reg_val); rv_writel(val, rtd->acp3x_base + reg_val);
rv_writel(0, rtd->acp3x_base + ier_val);
if (!(rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER) & BIT(0)) &&
!(rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER) & BIT(0)))
rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER);
if (!(rv_readl(rtd->acp3x_base + mmACP_I2STDM_ITER) & BIT(0)) &&
!(rv_readl(rtd->acp3x_base + mmACP_I2STDM_IRER) & BIT(0)))
rv_writel(0, rtd->acp3x_base + mmACP_I2STDM_IER);
ret = 0; ret = 0;
break; break;
default: default:

View File

@ -349,13 +349,6 @@ static int acp3x_dma_close(struct snd_soc_component *component,
component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
adata = dev_get_drvdata(component->dev); adata = dev_get_drvdata(component->dev);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
adata->play_stream = NULL;
adata->i2ssp_play_stream = NULL;
} else {
adata->capture_stream = NULL;
adata->i2ssp_capture_stream = NULL;
}
/* Disable ACP irq, when the current stream is being closed and /* Disable ACP irq, when the current stream is being closed and
* another stream is also not active. * another stream is also not active.
@ -363,6 +356,13 @@ static int acp3x_dma_close(struct snd_soc_component *component,
if (!adata->play_stream && !adata->capture_stream && if (!adata->play_stream && !adata->capture_stream &&
!adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) !adata->i2ssp_play_stream && !adata->i2ssp_capture_stream)
rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
adata->play_stream = NULL;
adata->i2ssp_play_stream = NULL;
} else {
adata->capture_stream = NULL;
adata->i2ssp_capture_stream = NULL;
}
return 0; return 0;
} }

View File

@ -214,7 +214,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_UDA134X select SND_SOC_UDA134X
select SND_SOC_UDA1380 if I2C select SND_SOC_UDA1380 if I2C
select SND_SOC_WCD9335 if SLIMBUS select SND_SOC_WCD9335 if SLIMBUS
select SND_SOC_WCD934X if MFD_WCD934X select SND_SOC_WCD934X if MFD_WCD934X && COMMON_CLK
select SND_SOC_WL1273 if MFD_WL1273_CORE select SND_SOC_WL1273 if MFD_WL1273_CORE
select SND_SOC_WM0010 if SPI_MASTER select SND_SOC_WM0010 if SPI_MASTER
select SND_SOC_WM1250_EV1 if I2C select SND_SOC_WM1250_EV1 if I2C
@ -1334,6 +1334,7 @@ config SND_SOC_WCD9335
config SND_SOC_WCD934X config SND_SOC_WCD934X
tristate "WCD9340/WCD9341 Codec" tristate "WCD9340/WCD9341 Codec"
depends on COMMON_CLK
depends on MFD_WCD934X depends on MFD_WCD934X
help help
The WCD9340/9341 is a audio codec IC Integrated in The WCD9340/9341 is a audio codec IC Integrated in

View File

@ -52,7 +52,8 @@ static void max98090_shdn_restore_locked(struct max98090_priv *max98090)
static void max98090_shdn_save(struct max98090_priv *max98090) static void max98090_shdn_save(struct max98090_priv *max98090)
{ {
mutex_lock(&max98090->component->card->dapm_mutex); mutex_lock_nested(&max98090->component->card->dapm_mutex,
SND_SOC_DAPM_CLASS_RUNTIME);
max98090_shdn_save_locked(max98090); max98090_shdn_save_locked(max98090);
} }

View File

@ -389,7 +389,7 @@ static const char * const rt1015_boost_mode[] = {
"Bypass", "Adaptive", "Fixed Adaptive" "Bypass", "Adaptive", "Fixed Adaptive"
}; };
static const SOC_ENUM_SINGLE_DECL(rt1015_boost_mode_enum, 0, 0, static SOC_ENUM_SINGLE_DECL(rt1015_boost_mode_enum, 0, 0,
rt1015_boost_mode); rt1015_boost_mode);
static int rt1015_boost_mode_get(struct snd_kcontrol *kcontrol, static int rt1015_boost_mode_get(struct snd_kcontrol *kcontrol,

View File

@ -673,7 +673,7 @@ static const struct sdw_device_id rt1308_id[] = {
}; };
MODULE_DEVICE_TABLE(sdw, rt1308_id); MODULE_DEVICE_TABLE(sdw, rt1308_id);
static int rt1308_dev_suspend(struct device *dev) static int __maybe_unused rt1308_dev_suspend(struct device *dev)
{ {
struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev); struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
@ -687,7 +687,7 @@ static int rt1308_dev_suspend(struct device *dev)
#define RT1308_PROBE_TIMEOUT 2000 #define RT1308_PROBE_TIMEOUT 2000
static int rt1308_dev_resume(struct device *dev) static int __maybe_unused rt1308_dev_resume(struct device *dev)
{ {
struct sdw_slave *slave = dev_to_sdw_dev(dev); struct sdw_slave *slave = dev_to_sdw_dev(dev);
struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev); struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);

View File

@ -486,7 +486,7 @@ static const struct sdw_device_id rt700_id[] = {
}; };
MODULE_DEVICE_TABLE(sdw, rt700_id); MODULE_DEVICE_TABLE(sdw, rt700_id);
static int rt700_dev_suspend(struct device *dev) static int __maybe_unused rt700_dev_suspend(struct device *dev)
{ {
struct rt700_priv *rt700 = dev_get_drvdata(dev); struct rt700_priv *rt700 = dev_get_drvdata(dev);
@ -500,7 +500,7 @@ static int rt700_dev_suspend(struct device *dev)
#define RT700_PROBE_TIMEOUT 2000 #define RT700_PROBE_TIMEOUT 2000
static int rt700_dev_resume(struct device *dev) static int __maybe_unused rt700_dev_resume(struct device *dev)
{ {
struct sdw_slave *slave = dev_to_sdw_dev(dev); struct sdw_slave *slave = dev_to_sdw_dev(dev);
struct rt700_priv *rt700 = dev_get_drvdata(dev); struct rt700_priv *rt700 = dev_get_drvdata(dev);

View File

@ -487,7 +487,7 @@ static const struct sdw_device_id rt711_id[] = {
}; };
MODULE_DEVICE_TABLE(sdw, rt711_id); MODULE_DEVICE_TABLE(sdw, rt711_id);
static int rt711_dev_suspend(struct device *dev) static int __maybe_unused rt711_dev_suspend(struct device *dev)
{ {
struct rt711_priv *rt711 = dev_get_drvdata(dev); struct rt711_priv *rt711 = dev_get_drvdata(dev);
@ -501,7 +501,7 @@ static int rt711_dev_suspend(struct device *dev)
#define RT711_PROBE_TIMEOUT 2000 #define RT711_PROBE_TIMEOUT 2000
static int rt711_dev_resume(struct device *dev) static int __maybe_unused rt711_dev_resume(struct device *dev)
{ {
struct sdw_slave *slave = dev_to_sdw_dev(dev); struct sdw_slave *slave = dev_to_sdw_dev(dev);
struct rt711_priv *rt711 = dev_get_drvdata(dev); struct rt711_priv *rt711 = dev_get_drvdata(dev);

View File

@ -549,7 +549,7 @@ static const struct sdw_device_id rt715_id[] = {
}; };
MODULE_DEVICE_TABLE(sdw, rt715_id); MODULE_DEVICE_TABLE(sdw, rt715_id);
static int rt715_dev_suspend(struct device *dev) static int __maybe_unused rt715_dev_suspend(struct device *dev)
{ {
struct rt715_priv *rt715 = dev_get_drvdata(dev); struct rt715_priv *rt715 = dev_get_drvdata(dev);
@ -563,7 +563,7 @@ static int rt715_dev_suspend(struct device *dev)
#define RT715_PROBE_TIMEOUT 2000 #define RT715_PROBE_TIMEOUT 2000
static int rt715_dev_resume(struct device *dev) static int __maybe_unused rt715_dev_resume(struct device *dev)
{ {
struct sdw_slave *slave = dev_to_sdw_dev(dev); struct sdw_slave *slave = dev_to_sdw_dev(dev);
struct rt715_priv *rt715 = dev_get_drvdata(dev); struct rt715_priv *rt715 = dev_get_drvdata(dev);

View File

@ -617,12 +617,15 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
snd_soc_dapm_add_routes(&card->dapm, broxton_map, snd_soc_dapm_add_routes(&card->dapm, broxton_map,
ARRAY_SIZE(broxton_map)); ARRAY_SIZE(broxton_map));
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm, if (list_empty(&ctx->hdmi_pcm_list))
head); return -EINVAL;
component = pcm->codec_dai->component;
if (ctx->common_hdmi_codec_drv) if (ctx->common_hdmi_codec_drv) {
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm,
head);
component = pcm->codec_dai->component;
return hda_dsp_hdmi_build_controls(card, component); return hda_dsp_hdmi_build_controls(card, component);
}
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
component = pcm->codec_dai->component; component = pcm->codec_dai->component;
@ -643,9 +646,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
i++; i++;
} }
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(component, &card->dapm); return hdac_hdmi_jack_port_init(component, &card->dapm);
} }

View File

@ -529,12 +529,15 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
int err, i = 0; int err, i = 0;
char jack_name[NAME_SIZE]; char jack_name[NAME_SIZE];
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm, if (list_empty(&ctx->hdmi_pcm_list))
head); return -EINVAL;
component = pcm->codec_dai->component;
if (ctx->common_hdmi_codec_drv) if (ctx->common_hdmi_codec_drv) {
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm,
head);
component = pcm->codec_dai->component;
return hda_dsp_hdmi_build_controls(card, component); return hda_dsp_hdmi_build_controls(card, component);
}
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
component = pcm->codec_dai->component; component = pcm->codec_dai->component;
@ -555,9 +558,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
i++; i++;
} }
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(component, &card->dapm); return hdac_hdmi_jack_port_init(component, &card->dapm);
} }

View File

@ -241,12 +241,15 @@ static int sof_card_late_probe(struct snd_soc_card *card)
struct hdmi_pcm *pcm; struct hdmi_pcm *pcm;
int ret, i = 0; int ret, i = 0;
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm, if (list_empty(&ctx->hdmi_pcm_list))
head); return -EINVAL;
component = pcm->codec_dai->component;
if (ctx->common_hdmi_codec_drv) if (ctx->common_hdmi_codec_drv) {
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm,
head);
component = pcm->codec_dai->component;
return hda_dsp_hdmi_build_controls(card, component); return hda_dsp_hdmi_build_controls(card, component);
}
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
component = pcm->codec_dai->component; component = pcm->codec_dai->component;
@ -265,8 +268,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
i++; i++;
} }
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(component, &card->dapm); return hdac_hdmi_jack_port_init(component, &card->dapm);
} }

View File

@ -534,15 +534,18 @@ static int glk_card_late_probe(struct snd_soc_card *card)
struct snd_soc_component *component = NULL; struct snd_soc_component *component = NULL;
char jack_name[NAME_SIZE]; char jack_name[NAME_SIZE];
struct glk_hdmi_pcm *pcm; struct glk_hdmi_pcm *pcm;
int err = 0; int err;
int i = 0; int i = 0;
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct glk_hdmi_pcm, if (list_empty(&ctx->hdmi_pcm_list))
head); return -EINVAL;
component = pcm->codec_dai->component;
if (ctx->common_hdmi_codec_drv) if (ctx->common_hdmi_codec_drv) {
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct glk_hdmi_pcm,
head);
component = pcm->codec_dai->component;
return hda_dsp_hdmi_build_controls(card, component); return hda_dsp_hdmi_build_controls(card, component);
}
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
component = pcm->codec_dai->component; component = pcm->codec_dai->component;
@ -563,9 +566,6 @@ static int glk_card_late_probe(struct snd_soc_card *card)
i++; i++;
} }
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(component, &card->dapm); return hdac_hdmi_jack_port_init(component, &card->dapm);
} }

View File

@ -273,19 +273,22 @@ static int sof_card_late_probe(struct snd_soc_card *card)
struct snd_soc_component *component = NULL; struct snd_soc_component *component = NULL;
char jack_name[NAME_SIZE]; char jack_name[NAME_SIZE];
struct sof_hdmi_pcm *pcm; struct sof_hdmi_pcm *pcm;
int err = 0; int err;
int i = 0; int i = 0;
/* HDMI is not supported by SOF on Baytrail/CherryTrail */ /* HDMI is not supported by SOF on Baytrail/CherryTrail */
if (is_legacy_cpu) if (is_legacy_cpu)
return 0; return 0;
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, if (list_empty(&ctx->hdmi_pcm_list))
head); return -EINVAL;
component = pcm->codec_dai->component;
if (ctx->common_hdmi_codec_drv) if (ctx->common_hdmi_codec_drv) {
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
head);
component = pcm->codec_dai->component;
return hda_dsp_hdmi_build_controls(card, component); return hda_dsp_hdmi_build_controls(card, component);
}
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
component = pcm->codec_dai->component; component = pcm->codec_dai->component;
@ -305,8 +308,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
i++; i++;
} }
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(component, &card->dapm); return hdac_hdmi_jack_port_init(component, &card->dapm);
} }

View File

@ -59,7 +59,7 @@ static const u64 rt1308_2_adr[] = {
}; };
static const u64 rt715_3_adr[] = { static const u64 rt715_3_adr[] = {
0x000310025D715000 0x000310025D071500
}; };
static const struct snd_soc_acpi_link_adr icl_3_in_1_default[] = { static const struct snd_soc_acpi_link_adr icl_3_in_1_default[] = {

View File

@ -224,12 +224,12 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
if (ret < 0) { if (ret < 0) {
dev_err(sdev->dev, dev_err(sdev->dev,
"error: failed to register DSP DAI driver %d\n", ret); "error: failed to register DSP DAI driver %d\n", ret);
goto fw_run_err; goto fw_trace_err;
} }
ret = snd_sof_machine_register(sdev, plat_data); ret = snd_sof_machine_register(sdev, plat_data);
if (ret < 0) if (ret < 0)
goto fw_run_err; goto fw_trace_err;
/* /*
* Some platforms in SOF, ex: BYT, may not have their platform PM * Some platforms in SOF, ex: BYT, may not have their platform PM
@ -244,7 +244,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
return 0; return 0;
#if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE) fw_trace_err:
snd_sof_free_trace(sdev);
fw_run_err: fw_run_err:
snd_sof_fw_unload(sdev); snd_sof_fw_unload(sdev);
fw_load_err: fw_load_err:
@ -253,21 +254,10 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
snd_sof_free_debug(sdev); snd_sof_free_debug(sdev);
dbg_err: dbg_err:
snd_sof_remove(sdev); snd_sof_remove(sdev);
#else
/* /* all resources freed, update state to match */
* when the probe_continue is handled in a work queue, the sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
* probe does not fail so we don't release resources here. sdev->first_boot = true;
* They will be released with an explicit call to
* snd_sof_device_remove() when the PCI/ACPI device is removed
*/
fw_run_err:
fw_load_err:
ipc_err:
dbg_err:
#endif
return ret; return ret;
} }
@ -350,10 +340,12 @@ int snd_sof_device_remove(struct device *dev)
if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
cancel_work_sync(&sdev->probe_work); cancel_work_sync(&sdev->probe_work);
snd_sof_fw_unload(sdev); if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) {
snd_sof_ipc_free(sdev); snd_sof_fw_unload(sdev);
snd_sof_free_debug(sdev); snd_sof_ipc_free(sdev);
snd_sof_free_trace(sdev); snd_sof_free_debug(sdev);
snd_sof_free_trace(sdev);
}
/* /*
* Unregister machine driver. This will unbind the snd_card which * Unregister machine driver. This will unbind the snd_card which
@ -361,13 +353,15 @@ int snd_sof_device_remove(struct device *dev)
* before freeing the snd_card. * before freeing the snd_card.
*/ */
snd_sof_machine_unregister(sdev, pdata); snd_sof_machine_unregister(sdev, pdata);
/* /*
* Unregistering the machine driver results in unloading the topology. * Unregistering the machine driver results in unloading the topology.
* Some widgets, ex: scheduler, attempt to power down the core they are * Some widgets, ex: scheduler, attempt to power down the core they are
* scheduled on, when they are unloaded. Therefore, the DSP must be * scheduled on, when they are unloaded. Therefore, the DSP must be
* removed only after the topology has been unloaded. * removed only after the topology has been unloaded.
*/ */
snd_sof_remove(sdev); if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED)
snd_sof_remove(sdev);
/* release firmware */ /* release firmware */
release_firmware(pdata->fw); release_firmware(pdata->fw);

View File

@ -170,23 +170,14 @@ EXPORT_SYMBOL_NS(hda_codec_probe_bus, SND_SOC_SOF_HDA_AUDIO_CODEC);
#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \ #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \
IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI) IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)
void hda_codec_i915_get(struct snd_sof_dev *sdev) void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable)
{ {
struct hdac_bus *bus = sof_to_bus(sdev); struct hdac_bus *bus = sof_to_bus(sdev);
dev_dbg(bus->dev, "Turning i915 HDAC power on\n"); dev_dbg(bus->dev, "Turning i915 HDAC power %d\n", enable);
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true); snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, enable);
} }
EXPORT_SYMBOL_NS(hda_codec_i915_get, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); EXPORT_SYMBOL_NS(hda_codec_i915_display_power, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
void hda_codec_i915_put(struct snd_sof_dev *sdev)
{
struct hdac_bus *bus = sof_to_bus(sdev);
dev_dbg(bus->dev, "Turning i915 HDAC power off\n");
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
}
EXPORT_SYMBOL_NS(hda_codec_i915_put, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
int hda_codec_i915_init(struct snd_sof_dev *sdev) int hda_codec_i915_init(struct snd_sof_dev *sdev)
{ {
@ -198,7 +189,7 @@ int hda_codec_i915_init(struct snd_sof_dev *sdev)
if (ret < 0) if (ret < 0)
return ret; return ret;
hda_codec_i915_get(sdev); hda_codec_i915_display_power(sdev, true);
return 0; return 0;
} }
@ -209,7 +200,7 @@ int hda_codec_i915_exit(struct snd_sof_dev *sdev)
struct hdac_bus *bus = sof_to_bus(sdev); struct hdac_bus *bus = sof_to_bus(sdev);
int ret; int ret;
hda_codec_i915_put(sdev); hda_codec_i915_display_power(sdev, false);
ret = snd_hdac_i915_exit(bus); ret = snd_hdac_i915_exit(bus);

View File

@ -380,7 +380,8 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
/* create codec instances */ /* create codec instances */
hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi); hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi);
hda_codec_i915_put(sdev); if (!HDA_IDISP_CODEC(bus->codec_mask))
hda_codec_i915_display_power(sdev, false);
/* /*
* we are done probing so decrement link counts * we are done probing so decrement link counts

View File

@ -586,15 +586,14 @@ void hda_codec_jack_check(struct snd_sof_dev *sdev);
(IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \ (IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \
IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
void hda_codec_i915_get(struct snd_sof_dev *sdev); void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable);
void hda_codec_i915_put(struct snd_sof_dev *sdev);
int hda_codec_i915_init(struct snd_sof_dev *sdev); int hda_codec_i915_init(struct snd_sof_dev *sdev);
int hda_codec_i915_exit(struct snd_sof_dev *sdev); int hda_codec_i915_exit(struct snd_sof_dev *sdev);
#else #else
static inline void hda_codec_i915_get(struct snd_sof_dev *sdev) { } static inline void hda_codec_i915_display_power(struct snd_sof_dev *sdev,
static inline void hda_codec_i915_put(struct snd_sof_dev *sdev) { } bool enable) { }
static inline int hda_codec_i915_init(struct snd_sof_dev *sdev) { return 0; } static inline int hda_codec_i915_init(struct snd_sof_dev *sdev) { return 0; }
static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; } static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; }

View File

@ -591,6 +591,11 @@ static int sof_pcm_new(struct snd_soc_component *component,
"spcm: allocate %s playback DMA buffer size 0x%x max 0x%x\n", "spcm: allocate %s playback DMA buffer size 0x%x max 0x%x\n",
caps->name, caps->buffer_size_min, caps->buffer_size_max); caps->name, caps->buffer_size_min, caps->buffer_size_max);
if (!pcm->streams[stream].substream) {
dev_err(component->dev, "error: NULL playback substream!\n");
return -EINVAL;
}
snd_pcm_set_managed_buffer(pcm->streams[stream].substream, snd_pcm_set_managed_buffer(pcm->streams[stream].substream,
SNDRV_DMA_TYPE_DEV_SG, sdev->dev, SNDRV_DMA_TYPE_DEV_SG, sdev->dev,
le32_to_cpu(caps->buffer_size_min), le32_to_cpu(caps->buffer_size_min),
@ -609,6 +614,11 @@ static int sof_pcm_new(struct snd_soc_component *component,
"spcm: allocate %s capture DMA buffer size 0x%x max 0x%x\n", "spcm: allocate %s capture DMA buffer size 0x%x max 0x%x\n",
caps->name, caps->buffer_size_min, caps->buffer_size_max); caps->name, caps->buffer_size_min, caps->buffer_size_max);
if (!pcm->streams[stream].substream) {
dev_err(component->dev, "error: NULL capture substream!\n");
return -EINVAL;
}
snd_pcm_set_managed_buffer(pcm->streams[stream].substream, snd_pcm_set_managed_buffer(pcm->streams[stream].substream,
SNDRV_DMA_TYPE_DEV_SG, sdev->dev, SNDRV_DMA_TYPE_DEV_SG, sdev->dev,
le32_to_cpu(caps->buffer_size_min), le32_to_cpu(caps->buffer_size_min),

View File

@ -56,6 +56,10 @@ static int sof_resume(struct device *dev, bool runtime_resume)
if (!sof_ops(sdev)->resume || !sof_ops(sdev)->runtime_resume) if (!sof_ops(sdev)->resume || !sof_ops(sdev)->runtime_resume)
return 0; return 0;
/* DSP was never successfully started, nothing to resume */
if (sdev->first_boot)
return 0;
/* /*
* if the runtime_resume flag is set, call the runtime_resume routine * if the runtime_resume flag is set, call the runtime_resume routine
* or else call the system resume routine * or else call the system resume routine

View File

@ -235,6 +235,7 @@ static const struct sof_dev_desc jsl_desc = {
.chip_info = &jsl_chip_info, .chip_info = &jsl_chip_info,
.default_fw_path = "intel/sof", .default_fw_path = "intel/sof",
.default_tplg_path = "intel/sof-tplg", .default_tplg_path = "intel/sof-tplg",
.default_fw_filename = "sof-jsl.ri",
.nocodec_tplg_filename = "sof-jsl-nocodec.tplg", .nocodec_tplg_filename = "sof-jsl-nocodec.tplg",
.ops = &sof_cnl_ops, .ops = &sof_cnl_ops,
}; };
@ -416,6 +417,8 @@ static const struct pci_device_id sof_pci_ids[] = {
#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE) #if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
{ PCI_DEVICE(0x8086, 0x38c8), { PCI_DEVICE(0x8086, 0x38c8),
.driver_data = (unsigned long)&jsl_desc}, .driver_data = (unsigned long)&jsl_desc},
{ PCI_DEVICE(0x8086, 0x4dc8),
.driver_data = (unsigned long)&jsl_desc},
#endif #endif
#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_LP) #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_LP)
{ PCI_DEVICE(0x8086, 0x02c8), { PCI_DEVICE(0x8086, 0x02c8),

View File

@ -343,7 +343,10 @@ void snd_sof_free_trace(struct snd_sof_dev *sdev)
snd_sof_release_trace(sdev); snd_sof_release_trace(sdev);
snd_dma_free_pages(&sdev->dmatb); if (sdev->dma_trace_pages) {
snd_dma_free_pages(&sdev->dmatp); snd_dma_free_pages(&sdev->dmatb);
snd_dma_free_pages(&sdev->dmatp);
sdev->dma_trace_pages = 0;
}
} }
EXPORT_SYMBOL(snd_sof_free_trace); EXPORT_SYMBOL(snd_sof_free_trace);

View File

@ -127,7 +127,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
struct device *dev = dai->dev; struct device *dev = dai->dev;
struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
unsigned int mask, val, reg; unsigned int mask, val, reg;
int ret, sample_size, srate, i2sclock, bitcnt, audio_bits; int ret, sample_size, srate, i2sclock, bitcnt;
struct tegra30_ahub_cif_conf cif_conf; struct tegra30_ahub_cif_conf cif_conf;
if (params_channels(params) != 2) if (params_channels(params) != 2)
@ -137,19 +137,8 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
switch (params_format(params)) { switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_LE:
val = TEGRA30_I2S_CTRL_BIT_SIZE_16; val = TEGRA30_I2S_CTRL_BIT_SIZE_16;
audio_bits = TEGRA30_AUDIOCIF_BITS_16;
sample_size = 16; sample_size = 16;
break; break;
case SNDRV_PCM_FORMAT_S24_LE:
val = TEGRA30_I2S_CTRL_BIT_SIZE_24;
audio_bits = TEGRA30_AUDIOCIF_BITS_24;
sample_size = 24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
val = TEGRA30_I2S_CTRL_BIT_SIZE_32;
audio_bits = TEGRA30_AUDIOCIF_BITS_32;
sample_size = 32;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
@ -181,8 +170,8 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
cif_conf.threshold = 0; cif_conf.threshold = 0;
cif_conf.audio_channels = 2; cif_conf.audio_channels = 2;
cif_conf.client_channels = 2; cif_conf.client_channels = 2;
cif_conf.audio_bits = audio_bits; cif_conf.audio_bits = TEGRA30_AUDIOCIF_BITS_16;
cif_conf.client_bits = audio_bits; cif_conf.client_bits = TEGRA30_AUDIOCIF_BITS_16;
cif_conf.expand = 0; cif_conf.expand = 0;
cif_conf.stereo_conv = 0; cif_conf.stereo_conv = 0;
cif_conf.replicate = 0; cif_conf.replicate = 0;
@ -317,18 +306,14 @@ static const struct snd_soc_dai_driver tegra30_i2s_dai_template = {
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_96000, .rates = SNDRV_PCM_RATE_8000_96000,
.formats = SNDRV_PCM_FMTBIT_S32_LE | .formats = SNDRV_PCM_FMTBIT_S16_LE,
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S16_LE,
}, },
.capture = { .capture = {
.stream_name = "Capture", .stream_name = "Capture",
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_96000, .rates = SNDRV_PCM_RATE_8000_96000,
.formats = SNDRV_PCM_FMTBIT_S32_LE | .formats = SNDRV_PCM_FMTBIT_S16_LE,
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S16_LE,
}, },
.ops = &tegra30_i2s_dai_ops, .ops = &tegra30_i2s_dai_ops,
.symmetric_rates = 1, .symmetric_rates = 1,

View File

@ -558,11 +558,11 @@ static const struct scarlett2_config
/* proprietary request/response format */ /* proprietary request/response format */
struct scarlett2_usb_packet { struct scarlett2_usb_packet {
u32 cmd; __le32 cmd;
u16 size; __le16 size;
u16 seq; __le16 seq;
u32 error; __le32 error;
u32 pad; __le32 pad;
u8 data[]; u8 data[];
}; };
@ -664,11 +664,11 @@ static int scarlett2_usb(
"Scarlett Gen 2 USB invalid response; " "Scarlett Gen 2 USB invalid response; "
"cmd tx/rx %d/%d seq %d/%d size %d/%d " "cmd tx/rx %d/%d seq %d/%d size %d/%d "
"error %d pad %d\n", "error %d pad %d\n",
le16_to_cpu(req->cmd), le16_to_cpu(resp->cmd), le32_to_cpu(req->cmd), le32_to_cpu(resp->cmd),
le16_to_cpu(req->seq), le16_to_cpu(resp->seq), le16_to_cpu(req->seq), le16_to_cpu(resp->seq),
resp_size, le16_to_cpu(resp->size), resp_size, le16_to_cpu(resp->size),
le16_to_cpu(resp->error), le32_to_cpu(resp->error),
le16_to_cpu(resp->pad)); le32_to_cpu(resp->pad));
err = -EINVAL; err = -EINVAL;
goto unlock; goto unlock;
} }
@ -687,7 +687,7 @@ static int scarlett2_usb(
/* Send SCARLETT2_USB_DATA_CMD SCARLETT2_USB_CONFIG_SAVE */ /* Send SCARLETT2_USB_DATA_CMD SCARLETT2_USB_CONFIG_SAVE */
static void scarlett2_config_save(struct usb_mixer_interface *mixer) static void scarlett2_config_save(struct usb_mixer_interface *mixer)
{ {
u32 req = cpu_to_le32(SCARLETT2_USB_CONFIG_SAVE); __le32 req = cpu_to_le32(SCARLETT2_USB_CONFIG_SAVE);
scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD, scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD,
&req, sizeof(u32), &req, sizeof(u32),
@ -713,11 +713,11 @@ static int scarlett2_usb_set_config(
const struct scarlett2_config config_item = const struct scarlett2_config config_item =
scarlett2_config_items[config_item_num]; scarlett2_config_items[config_item_num];
struct { struct {
u32 offset; __le32 offset;
u32 bytes; __le32 bytes;
s32 value; __le32 value;
} __packed req; } __packed req;
u32 req2; __le32 req2;
int err; int err;
struct scarlett2_mixer_data *private = mixer->private_data; struct scarlett2_mixer_data *private = mixer->private_data;
@ -753,8 +753,8 @@ static int scarlett2_usb_get(
int offset, void *buf, int size) int offset, void *buf, int size)
{ {
struct { struct {
u32 offset; __le32 offset;
u32 size; __le32 size;
} __packed req; } __packed req;
req.offset = cpu_to_le32(offset); req.offset = cpu_to_le32(offset);
@ -794,8 +794,8 @@ static int scarlett2_usb_set_mix(struct usb_mixer_interface *mixer,
const struct scarlett2_device_info *info = private->info; const struct scarlett2_device_info *info = private->info;
struct { struct {
u16 mix_num; __le16 mix_num;
u16 data[SCARLETT2_INPUT_MIX_MAX]; __le16 data[SCARLETT2_INPUT_MIX_MAX];
} __packed req; } __packed req;
int i, j; int i, j;
@ -850,9 +850,9 @@ static int scarlett2_usb_set_mux(struct usb_mixer_interface *mixer)
}; };
struct { struct {
u16 pad; __le16 pad;
u16 num; __le16 num;
u32 data[SCARLETT2_MUX_MAX]; __le32 data[SCARLETT2_MUX_MAX];
} __packed req; } __packed req;
req.pad = 0; req.pad = 0;
@ -911,9 +911,9 @@ static int scarlett2_usb_get_meter_levels(struct usb_mixer_interface *mixer,
u16 *levels) u16 *levels)
{ {
struct { struct {
u16 pad; __le16 pad;
u16 num_meters; __le16 num_meters;
u32 magic; __le32 magic;
} __packed req; } __packed req;
u32 resp[SCARLETT2_NUM_METERS]; u32 resp[SCARLETT2_NUM_METERS];
int i, err; int i, err;

View File

@ -110,7 +110,7 @@ static bool validate_processing_unit(const void *p,
default: default:
if (v->type == UAC1_EXTENSION_UNIT) if (v->type == UAC1_EXTENSION_UNIT)
return true; /* OK */ return true; /* OK */
switch (d->wProcessType) { switch (le16_to_cpu(d->wProcessType)) {
case UAC_PROCESS_UP_DOWNMIX: case UAC_PROCESS_UP_DOWNMIX:
case UAC_PROCESS_DOLBY_PROLOGIC: case UAC_PROCESS_DOLBY_PROLOGIC:
if (d->bLength < len + 1) /* bNrModes */ if (d->bLength < len + 1) /* bNrModes */
@ -125,7 +125,7 @@ static bool validate_processing_unit(const void *p,
case UAC_VERSION_2: case UAC_VERSION_2:
if (v->type == UAC2_EXTENSION_UNIT_V2) if (v->type == UAC2_EXTENSION_UNIT_V2)
return true; /* OK */ return true; /* OK */
switch (d->wProcessType) { switch (le16_to_cpu(d->wProcessType)) {
case UAC2_PROCESS_UP_DOWNMIX: case UAC2_PROCESS_UP_DOWNMIX:
case UAC2_PROCESS_DOLBY_PROLOCIC: /* SiC! */ case UAC2_PROCESS_DOLBY_PROLOCIC: /* SiC! */
if (d->bLength < len + 1) /* bNrModes */ if (d->bLength < len + 1) /* bNrModes */
@ -142,7 +142,7 @@ static bool validate_processing_unit(const void *p,
len += 2; /* wClusterDescrID */ len += 2; /* wClusterDescrID */
break; break;
} }
switch (d->wProcessType) { switch (le16_to_cpu(d->wProcessType)) {
case UAC3_PROCESS_UP_DOWNMIX: case UAC3_PROCESS_UP_DOWNMIX:
if (d->bLength < len + 1) /* bNrModes */ if (d->bLength < len + 1) /* bNrModes */
return false; return false;