Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
6a473669
Commit
6a473669
authored
Feb 11, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/compress' into asoc-next
parents
81fd7e48
da18396f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
131 additions
and
21 deletions
+131
-21
include/sound/soc-dai.h
include/sound/soc-dai.h
+3
-1
sound/soc/soc-compress.c
sound/soc/soc-compress.c
+111
-12
sound/soc/soc-core.c
sound/soc/soc-core.c
+10
-2
sound/soc/soc-dapm.c
sound/soc/soc-dapm.c
+4
-2
sound/soc/soc-pcm.c
sound/soc/soc-pcm.c
+3
-4
No files found.
include/sound/soc-dai.h
View file @
6a473669
...
...
@@ -126,7 +126,8 @@ int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
int
snd_soc_dai_set_tristate
(
struct
snd_soc_dai
*
dai
,
int
tristate
);
/* Digital Audio Interface mute */
int
snd_soc_dai_digital_mute
(
struct
snd_soc_dai
*
dai
,
int
mute
);
int
snd_soc_dai_digital_mute
(
struct
snd_soc_dai
*
dai
,
int
mute
,
int
direction
);
struct
snd_soc_dai_ops
{
/*
...
...
@@ -157,6 +158,7 @@ struct snd_soc_dai_ops {
* Called by soc-core to minimise any pops.
*/
int
(
*
digital_mute
)(
struct
snd_soc_dai
*
dai
,
int
mute
);
int
(
*
mute_stream
)(
struct
snd_soc_dai
*
dai
,
int
mute
,
int
stream
);
/*
* ALSA PCM audio operations - all optional.
...
...
sound/soc/soc-compress.c
View file @
6a473669
...
...
@@ -33,6 +33,8 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
=
0
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
open
)
{
ret
=
platform
->
driver
->
compr_ops
->
open
(
cstream
);
if
(
ret
<
0
)
{
...
...
@@ -61,15 +63,46 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
codec_dai
->
active
++
;
rtd
->
codec
->
active
++
;
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
0
;
machine_err:
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
free
)
platform
->
driver
->
compr_ops
->
free
(
cstream
);
out:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
/*
* Power down the audio subsystem pmdown_time msecs after close is called.
* This is to ensure there are no pops or clicks in between any music tracks
* due to DAPM power cycling.
*/
static
void
close_delayed_work
(
struct
work_struct
*
work
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
container_of
(
work
,
struct
snd_soc_pcm_runtime
,
delayed_work
.
work
);
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
dev_dbg
(
rtd
->
dev
,
"ASoC: pop wq checking: %s status: %s waiting: %s
\n
"
,
codec_dai
->
driver
->
playback
.
stream_name
,
codec_dai
->
playback_active
?
"active"
:
"inactive"
,
rtd
->
pop_wait
?
"yes"
:
"no"
);
/* are we waiting on this codec DAI stream */
if
(
rtd
->
pop_wait
==
1
)
{
rtd
->
pop_wait
=
0
;
snd_soc_dapm_stream_event
(
rtd
,
SNDRV_PCM_STREAM_PLAYBACK
,
SND_SOC_DAPM_STREAM_STOP
);
}
mutex_unlock
(
&
rtd
->
pcm_mutex
);
}
static
int
soc_compr_free
(
struct
snd_compr_stream
*
cstream
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
...
...
@@ -78,6 +111,8 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
{
cpu_dai
->
playback_active
--
;
codec_dai
->
playback_active
--
;
...
...
@@ -86,7 +121,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
codec_dai
->
capture_active
--
;
}
snd_soc_dai_digital_mute
(
codec_dai
,
1
);
snd_soc_dai_digital_mute
(
codec_dai
,
1
,
cstream
->
direction
);
cpu_dai
->
active
--
;
codec_dai
->
active
--
;
...
...
@@ -112,10 +147,11 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
snd_soc_dapm_stream_event
(
rtd
,
SNDRV_PCM_STREAM_PLAYBACK
,
SND_SOC_DAPM_STREAM_STOP
);
}
else
}
else
{
rtd
->
pop_wait
=
1
;
schedule_delayed_work
(
&
rtd
->
delayed_work
,
msecs_to_jiffies
(
rtd
->
pmdown_time
));
}
}
else
{
/* capture streams can be powered down now */
snd_soc_dapm_stream_event
(
rtd
,
...
...
@@ -123,6 +159,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
SND_SOC_DAPM_STREAM_STOP
);
}
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
0
;
}
...
...
@@ -134,17 +171,25 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
=
0
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
trigger
)
{
ret
=
platform
->
driver
->
compr_ops
->
trigger
(
cstream
,
cmd
);
if
(
ret
<
0
)
return
re
t
;
goto
ou
t
;
}
if
(
cmd
==
SNDRV_PCM_TRIGGER_START
)
snd_soc_dai_digital_mute
(
codec_dai
,
0
);
else
if
(
cmd
==
SNDRV_PCM_TRIGGER_STOP
)
snd_soc_dai_digital_mute
(
codec_dai
,
1
);
switch
(
cmd
)
{
case
SNDRV_PCM_TRIGGER_START
:
snd_soc_dai_digital_mute
(
codec_dai
,
0
,
cstream
->
direction
);
break
;
case
SNDRV_PCM_TRIGGER_STOP
:
snd_soc_dai_digital_mute
(
codec_dai
,
1
,
cstream
->
direction
);
break
;
}
out:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
...
...
@@ -155,6 +200,8 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
int
ret
=
0
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
/* first we call set_params for the platform driver
* this should configure the soc side
* if the machine has compressed ops then we call that as well
...
...
@@ -164,18 +211,20 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
set_params
)
{
ret
=
platform
->
driver
->
compr_ops
->
set_params
(
cstream
,
params
);
if
(
ret
<
0
)
return
re
t
;
goto
ou
t
;
}
if
(
rtd
->
dai_link
->
compr_ops
&&
rtd
->
dai_link
->
compr_ops
->
set_params
)
{
ret
=
rtd
->
dai_link
->
compr_ops
->
set_params
(
cstream
);
if
(
ret
<
0
)
return
re
t
;
goto
ou
t
;
}
snd_soc_dapm_stream_event
(
rtd
,
SNDRV_PCM_STREAM_PLAYBACK
,
SND_SOC_DAPM_STREAM_START
);
out:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
...
...
@@ -186,9 +235,12 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
int
ret
=
0
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_params
)
ret
=
platform
->
driver
->
compr_ops
->
get_params
(
cstream
,
params
);
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
...
...
@@ -199,9 +251,12 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
int
ret
=
0
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_caps
)
ret
=
platform
->
driver
->
compr_ops
->
get_caps
(
cstream
,
caps
);
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
...
...
@@ -212,9 +267,12 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
int
ret
=
0
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_codec_caps
)
ret
=
platform
->
driver
->
compr_ops
->
get_codec_caps
(
cstream
,
codec
);
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
...
...
@@ -224,9 +282,12 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
int
ret
=
0
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
ack
)
ret
=
platform
->
driver
->
compr_ops
->
ack
(
cstream
,
bytes
);
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
...
...
@@ -236,12 +297,31 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
pointer
)
platform
->
driver
->
compr_ops
->
pointer
(
cstream
,
tstamp
);
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
0
;
}
static
int
soc_compr_copy
(
struct
snd_compr_stream
*
cstream
,
const
char
__user
*
buf
,
size_t
count
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
int
ret
=
0
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
copy
)
ret
=
platform
->
driver
->
compr_ops
->
copy
(
cstream
,
buf
,
count
);
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
/* ASoC Compress operations */
static
struct
snd_compr_ops
soc_compr_ops
=
{
.
open
=
soc_compr_open
,
...
...
@@ -259,6 +339,7 @@ static struct snd_compr_ops soc_compr_ops = {
int
soc_new_compress
(
struct
snd_soc_pcm_runtime
*
rtd
,
int
num
)
{
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_compr
*
compr
;
...
...
@@ -275,20 +356,38 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
return
-
ENOMEM
;
}
compr
->
ops
=
&
soc_compr_ops
;
compr
->
ops
=
devm_kzalloc
(
rtd
->
card
->
dev
,
sizeof
(
soc_compr_ops
),
GFP_KERNEL
);
if
(
compr
->
ops
==
NULL
)
{
dev_err
(
rtd
->
card
->
dev
,
"Cannot allocate compressed ops
\n
"
);
ret
=
-
ENOMEM
;
goto
compr_err
;
}
memcpy
(
compr
->
ops
,
&
soc_compr_ops
,
sizeof
(
soc_compr_ops
));
/* Add copy callback for not memory mapped DSPs */
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
copy
)
compr
->
ops
->
copy
=
soc_compr_copy
;
mutex_init
(
&
compr
->
lock
);
ret
=
snd_compress_new
(
rtd
->
card
->
snd_card
,
num
,
direction
,
compr
);
if
(
ret
<
0
)
{
pr_err
(
"compress asoc: can't create compress for codec %s
\n
"
,
codec
->
name
);
kfree
(
compr
);
return
ret
;
goto
compr_err
;
}
/* DAPM dai link stream work */
INIT_DELAYED_WORK
(
&
rtd
->
delayed_work
,
close_delayed_work
);
rtd
->
compr
=
compr
;
compr
->
private_data
=
rtd
;
printk
(
KERN_INFO
"compress asoc: %s <-> %s mapping ok
\n
"
,
codec_dai
->
name
,
cpu_dai
->
name
);
return
ret
;
compr_err:
kfree
(
compr
);
return
ret
;
}
sound/soc/soc-core.c
View file @
6a473669
...
...
@@ -3540,12 +3540,20 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
* snd_soc_dai_digital_mute - configure DAI system or master clock.
* @dai: DAI
* @mute: mute enable
* @direction: stream to mute
*
* Mutes the DAI DAC.
*/
int
snd_soc_dai_digital_mute
(
struct
snd_soc_dai
*
dai
,
int
mute
)
int
snd_soc_dai_digital_mute
(
struct
snd_soc_dai
*
dai
,
int
mute
,
int
direction
)
{
if
(
dai
->
driver
&&
dai
->
driver
->
ops
->
digital_mute
)
if
(
!
dai
->
driver
)
return
-
ENOTSUPP
;
if
(
dai
->
driver
->
ops
->
mute_stream
)
return
dai
->
driver
->
ops
->
mute_stream
(
dai
,
mute
,
direction
);
else
if
(
direction
==
SNDRV_PCM_STREAM_PLAYBACK
&&
dai
->
driver
->
ops
->
digital_mute
)
return
dai
->
driver
->
ops
->
digital_mute
(
dai
,
mute
);
else
return
-
ENOTSUPP
;
...
...
sound/soc/soc-dapm.c
View file @
6a473669
...
...
@@ -3255,14 +3255,16 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
break
;
case
SND_SOC_DAPM_POST_PMU
:
ret
=
snd_soc_dai_digital_mute
(
sink
,
0
);
ret
=
snd_soc_dai_digital_mute
(
sink
,
0
,
SNDRV_PCM_STREAM_PLAYBACK
);
if
(
ret
!=
0
&&
ret
!=
-
ENOTSUPP
)
dev_warn
(
sink
->
dev
,
"ASoC: Failed to unmute: %d
\n
"
,
ret
);
ret
=
0
;
break
;
case
SND_SOC_DAPM_PRE_PMD
:
ret
=
snd_soc_dai_digital_mute
(
sink
,
1
);
ret
=
snd_soc_dai_digital_mute
(
sink
,
1
,
SNDRV_PCM_STREAM_PLAYBACK
);
if
(
ret
!=
0
&&
ret
!=
-
ENOTSUPP
)
dev_warn
(
sink
->
dev
,
"ASoC: Failed to mute: %d
\n
"
,
ret
);
ret
=
0
;
...
...
sound/soc/soc-pcm.c
View file @
6a473669
...
...
@@ -383,8 +383,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
/* Muting the DAC suppresses artifacts caused during digital
* shutdown, for example from stopping clocks.
*/
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
snd_soc_dai_digital_mute
(
codec_dai
,
1
);
snd_soc_dai_digital_mute
(
codec_dai
,
1
,
substream
->
stream
);
if
(
cpu_dai
->
driver
->
ops
->
shutdown
)
cpu_dai
->
driver
->
ops
->
shutdown
(
substream
,
cpu_dai
);
...
...
@@ -488,7 +487,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
snd_soc_dapm_stream_event
(
rtd
,
substream
->
stream
,
SND_SOC_DAPM_STREAM_START
);
snd_soc_dai_digital_mute
(
codec_dai
,
0
);
snd_soc_dai_digital_mute
(
codec_dai
,
0
,
substream
->
stream
);
out:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
...
...
@@ -586,7 +585,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
/* apply codec digital mute */
if
(
!
codec
->
active
)
snd_soc_dai_digital_mute
(
codec_dai
,
1
);
snd_soc_dai_digital_mute
(
codec_dai
,
1
,
substream
->
stream
);
/* free any machine hw params */
if
(
rtd
->
dai_link
->
ops
&&
rtd
->
dai_link
->
ops
->
hw_free
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment