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
aa38bff8
Commit
aa38bff8
authored
Nov 10, 2017
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/core' into asoc-next
parents
73e13d0f
e07bd30b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1090 additions
and
138 deletions
+1090
-138
include/sound/soc.h
include/sound/soc.h
+94
-0
sound/soc/soc-compress.c
sound/soc/soc-compress.c
+427
-34
sound/soc/soc-core.c
sound/soc/soc-core.c
+142
-50
sound/soc/soc-dapm.c
sound/soc/soc-dapm.c
+4
-4
sound/soc/soc-io.c
sound/soc/soc-io.c
+14
-0
sound/soc/soc-pcm.c
sound/soc/soc-pcm.c
+409
-50
No files found.
include/sound/soc.h
View file @
aa38bff8
...
...
@@ -480,6 +480,8 @@ int devm_snd_soc_register_component(struct device *dev,
const
struct
snd_soc_component_driver
*
component_driver
,
struct
snd_soc_dai_driver
*
dai_drv
,
int
num_dai
);
void
snd_soc_unregister_component
(
struct
device
*
dev
);
struct
snd_soc_component
*
snd_soc_lookup_component
(
struct
device
*
dev
,
const
char
*
driver_name
);
int
snd_soc_cache_init
(
struct
snd_soc_codec
*
codec
);
int
snd_soc_cache_exit
(
struct
snd_soc_codec
*
codec
);
...
...
@@ -800,6 +802,10 @@ struct snd_soc_component_driver {
int
(
*
suspend
)(
struct
snd_soc_component
*
);
int
(
*
resume
)(
struct
snd_soc_component
*
);
/* pcm creation and destruction */
int
(
*
pcm_new
)(
struct
snd_soc_pcm_runtime
*
);
void
(
*
pcm_free
)(
struct
snd_pcm
*
);
/* component wide operations */
int
(
*
set_sysclk
)(
struct
snd_soc_component
*
component
,
int
clk_id
,
int
source
,
unsigned
int
freq
,
int
dir
);
...
...
@@ -817,10 +823,22 @@ struct snd_soc_component_driver {
void
(
*
seq_notifier
)(
struct
snd_soc_component
*
,
enum
snd_soc_dapm_type
,
int
subseq
);
int
(
*
stream_event
)(
struct
snd_soc_component
*
,
int
event
);
int
(
*
set_bias_level
)(
struct
snd_soc_component
*
component
,
enum
snd_soc_bias_level
level
);
const
struct
snd_pcm_ops
*
ops
;
const
struct
snd_compr_ops
*
compr_ops
;
/* probe ordering - for components with runtime dependencies */
int
probe_order
;
int
remove_order
;
/* bits */
unsigned
int
idle_bias_on
:
1
;
unsigned
int
suspend_bias_off
:
1
;
unsigned
int
pmdown_time
:
1
;
/* care pmdown_time at stop */
unsigned
int
endianness
:
1
;
unsigned
int
non_legacy_dai_naming
:
1
;
};
struct
snd_soc_component
{
...
...
@@ -877,6 +895,8 @@ struct snd_soc_component {
void
(
*
remove
)(
struct
snd_soc_component
*
);
int
(
*
suspend
)(
struct
snd_soc_component
*
);
int
(
*
resume
)(
struct
snd_soc_component
*
);
int
(
*
pcm_new
)(
struct
snd_soc_component
*
,
struct
snd_soc_pcm_runtime
*
);
void
(
*
pcm_free
)(
struct
snd_soc_component
*
,
struct
snd_pcm
*
);
int
(
*
set_sysclk
)(
struct
snd_soc_component
*
component
,
int
clk_id
,
int
source
,
unsigned
int
freq
,
int
dir
);
...
...
@@ -884,6 +904,8 @@ struct snd_soc_component {
int
source
,
unsigned
int
freq_in
,
unsigned
int
freq_out
);
int
(
*
set_jack
)(
struct
snd_soc_component
*
component
,
struct
snd_soc_jack
*
jack
,
void
*
data
);
int
(
*
set_bias_level
)(
struct
snd_soc_component
*
component
,
enum
snd_soc_bias_level
level
);
/* machine specific init */
int
(
*
init
)(
struct
snd_soc_component
*
component
);
...
...
@@ -1417,6 +1439,21 @@ static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec,
snd_soc_dapm_init_bias_level
(
snd_soc_codec_get_dapm
(
codec
),
level
);
}
/**
* snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level
* @component: The COMPONENT for which to initialize the DAPM bias level
* @level: The DAPM level to initialize to
*
* Initializes the COMPONENT DAPM bias level. See snd_soc_dapm_init_bias_level().
*/
static
inline
void
snd_soc_component_init_bias_level
(
struct
snd_soc_component
*
component
,
enum
snd_soc_bias_level
level
)
{
snd_soc_dapm_init_bias_level
(
snd_soc_component_get_dapm
(
component
),
level
);
}
/**
* snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level
* @codec: The CODEC for which to get the DAPM bias level
...
...
@@ -1429,6 +1466,19 @@ static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level(
return
snd_soc_dapm_get_bias_level
(
snd_soc_codec_get_dapm
(
codec
));
}
/**
* snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level
* @component: The COMPONENT for which to get the DAPM bias level
*
* Returns: The current DAPM bias level of the COMPONENT.
*/
static
inline
enum
snd_soc_bias_level
snd_soc_component_get_bias_level
(
struct
snd_soc_component
*
component
)
{
return
snd_soc_dapm_get_bias_level
(
snd_soc_component_get_dapm
(
component
));
}
/**
* snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level
* @codec: The CODEC for which to set the level
...
...
@@ -1444,6 +1494,23 @@ static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec,
level
);
}
/**
* snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level
* @component: The COMPONENT for which to set the level
* @level: The level to set to
*
* Forces the COMPONENT bias level to a specific state. See
* snd_soc_dapm_force_bias_level().
*/
static
inline
int
snd_soc_component_force_bias_level
(
struct
snd_soc_component
*
component
,
enum
snd_soc_bias_level
level
)
{
return
snd_soc_dapm_force_bias_level
(
snd_soc_component_get_dapm
(
component
),
level
);
}
/**
* snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
* @kcontrol: The kcontrol
...
...
@@ -1457,6 +1524,19 @@ static inline struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(
return
snd_soc_dapm_to_codec
(
snd_soc_dapm_kcontrol_dapm
(
kcontrol
));
}
/**
* snd_soc_dapm_kcontrol_component() - Returns the component associated to a kcontrol
* @kcontrol: The kcontrol
*
* This function must only be used on DAPM contexts that are known to be part of
* a COMPONENT (e.g. in a COMPONENT driver). Otherwise the behavior is undefined.
*/
static
inline
struct
snd_soc_component
*
snd_soc_dapm_kcontrol_component
(
struct
snd_kcontrol
*
kcontrol
)
{
return
snd_soc_dapm_to_component
(
snd_soc_dapm_kcontrol_dapm
(
kcontrol
));
}
/* codec IO */
unsigned
int
snd_soc_read
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
);
int
snd_soc_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
...
...
@@ -1473,9 +1553,23 @@ static inline int snd_soc_cache_sync(struct snd_soc_codec *codec)
return
regcache_sync
(
codec
->
component
.
regmap
);
}
/**
* snd_soc_component_cache_sync() - Sync the register cache with the hardware
* @component: COMPONENT to sync
*
* Note: This function will call regcache_sync()
*/
static
inline
int
snd_soc_component_cache_sync
(
struct
snd_soc_component
*
component
)
{
return
regcache_sync
(
component
->
regmap
);
}
/* component IO */
int
snd_soc_component_read
(
struct
snd_soc_component
*
component
,
unsigned
int
reg
,
unsigned
int
*
val
);
unsigned
int
snd_soc_component_read32
(
struct
snd_soc_component
*
component
,
unsigned
int
reg
);
int
snd_soc_component_write
(
struct
snd_soc_component
*
component
,
unsigned
int
reg
,
unsigned
int
val
);
int
snd_soc_component_update_bits
(
struct
snd_soc_component
*
component
,
...
...
sound/soc/soc-compress.c
View file @
aa38bff8
...
...
@@ -30,8 +30,10 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
int
ret
=
0
;
int
ret
=
0
,
__ret
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
...
...
@@ -44,7 +46,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
}
}
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
open
)
{
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
open
)
{
ret
=
platform
->
driver
->
compr_ops
->
open
(
cstream
);
if
(
ret
<
0
)
{
pr_err
(
"compress asoc: can't open platform %s
\n
"
,
...
...
@@ -53,6 +55,27 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
}
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
open
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
open
(
cstream
);
if
(
__ret
<
0
)
{
pr_err
(
"compress asoc: can't open platform %s
\n
"
,
component
->
name
);
ret
=
__ret
;
}
}
if
(
ret
<
0
)
goto
machine_err
;
if
(
rtd
->
dai_link
->
compr_ops
&&
rtd
->
dai_link
->
compr_ops
->
startup
)
{
ret
=
rtd
->
dai_link
->
compr_ops
->
startup
(
cstream
);
if
(
ret
<
0
)
{
...
...
@@ -68,7 +91,21 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
return
0
;
machine_err:
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
free
)
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
free
)
continue
;
component
->
driver
->
compr_ops
->
free
(
cstream
);
}
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
free
)
platform
->
driver
->
compr_ops
->
free
(
cstream
);
plat_err:
if
(
cpu_dai
->
driver
->
cops
&&
cpu_dai
->
driver
->
cops
->
shutdown
)
...
...
@@ -84,11 +121,13 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
struct
snd_pcm_substream
*
fe_substream
=
fe
->
pcm
->
streams
[
cstream
->
direction
].
substream
;
struct
snd_soc_platform
*
platform
=
fe
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
fe
->
cpu_dai
;
struct
snd_soc_dpcm
*
dpcm
;
struct
snd_soc_dapm_widget_list
*
list
;
int
stream
;
int
ret
=
0
;
int
ret
=
0
,
__ret
;
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
stream
=
SNDRV_PCM_STREAM_PLAYBACK
;
...
...
@@ -107,7 +146,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
}
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
open
)
{
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
open
)
{
ret
=
platform
->
driver
->
compr_ops
->
open
(
cstream
);
if
(
ret
<
0
)
{
pr_err
(
"compress asoc: can't open platform %s
\n
"
,
...
...
@@ -116,6 +155,27 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
}
}
for_each_rtdcom
(
fe
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
open
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
open
(
cstream
);
if
(
__ret
<
0
)
{
pr_err
(
"compress asoc: can't open platform %s
\n
"
,
component
->
name
);
ret
=
__ret
;
}
}
if
(
ret
<
0
)
goto
machine_err
;
if
(
fe
->
dai_link
->
compr_ops
&&
fe
->
dai_link
->
compr_ops
->
startup
)
{
ret
=
fe
->
dai_link
->
compr_ops
->
startup
(
cstream
);
if
(
ret
<
0
)
{
...
...
@@ -167,7 +227,21 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
if
(
fe
->
dai_link
->
compr_ops
&&
fe
->
dai_link
->
compr_ops
->
shutdown
)
fe
->
dai_link
->
compr_ops
->
shutdown
(
cstream
);
machine_err:
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
free
)
for_each_rtdcom
(
fe
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
free
)
continue
;
component
->
driver
->
compr_ops
->
free
(
cstream
);
}
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
free
)
platform
->
driver
->
compr_ops
->
free
(
cstream
);
plat_err:
if
(
cpu_dai
->
driver
->
cops
&&
cpu_dai
->
driver
->
cops
->
shutdown
)
...
...
@@ -210,6 +284,8 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
stream
;
...
...
@@ -235,7 +311,21 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
if
(
rtd
->
dai_link
->
compr_ops
&&
rtd
->
dai_link
->
compr_ops
->
shutdown
)
rtd
->
dai_link
->
compr_ops
->
shutdown
(
cstream
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
free
)
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
free
)
continue
;
component
->
driver
->
compr_ops
->
free
(
cstream
);
}
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
free
)
platform
->
driver
->
compr_ops
->
free
(
cstream
);
if
(
cpu_dai
->
driver
->
cops
&&
cpu_dai
->
driver
->
cops
->
shutdown
)
...
...
@@ -267,6 +357,8 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
{
struct
snd_soc_pcm_runtime
*
fe
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
fe
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
fe
->
cpu_dai
;
struct
snd_soc_dpcm
*
dpcm
;
int
stream
,
ret
;
...
...
@@ -304,9 +396,23 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
if
(
fe
->
dai_link
->
compr_ops
&&
fe
->
dai_link
->
compr_ops
->
shutdown
)
fe
->
dai_link
->
compr_ops
->
shutdown
(
cstream
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
free
)
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
free
)
platform
->
driver
->
compr_ops
->
free
(
cstream
);
for_each_rtdcom
(
fe
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
free
)
continue
;
component
->
driver
->
compr_ops
->
free
(
cstream
);
}
if
(
cpu_dai
->
driver
->
cops
&&
cpu_dai
->
driver
->
cops
->
shutdown
)
cpu_dai
->
driver
->
cops
->
shutdown
(
cstream
,
cpu_dai
);
...
...
@@ -319,18 +425,38 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
int
ret
=
0
;
int
ret
=
0
,
__ret
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
trigger
)
{
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
trigger
)
{
ret
=
platform
->
driver
->
compr_ops
->
trigger
(
cstream
,
cmd
);
if
(
ret
<
0
)
goto
out
;
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
trigger
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
trigger
(
cstream
,
cmd
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
if
(
ret
<
0
)
goto
out
;
if
(
cpu_dai
->
driver
->
cops
&&
cpu_dai
->
driver
->
cops
->
trigger
)
cpu_dai
->
driver
->
cops
->
trigger
(
cstream
,
cmd
,
cpu_dai
);
...
...
@@ -353,16 +479,36 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
{
struct
snd_soc_pcm_runtime
*
fe
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
fe
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
fe
->
cpu_dai
;
int
ret
=
0
,
stream
;
int
ret
=
0
,
__ret
,
stream
;
if
(
cmd
==
SND_COMPR_TRIGGER_PARTIAL_DRAIN
||
cmd
==
SND_COMPR_TRIGGER_DRAIN
)
{
if
(
platform
->
driver
->
compr_ops
&&
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
trigger
)
return
platform
->
driver
->
compr_ops
->
trigger
(
cstream
,
cmd
);
for_each_rtdcom
(
fe
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
trigger
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
trigger
(
cstream
,
cmd
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
return
ret
;
}
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
...
...
@@ -379,12 +525,30 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
goto
out
;
}
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
trigger
)
{
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
trigger
)
{
ret
=
platform
->
driver
->
compr_ops
->
trigger
(
cstream
,
cmd
);
if
(
ret
<
0
)
goto
out
;
}
for_each_rtdcom
(
fe
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
trigger
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
trigger
(
cstream
,
cmd
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
if
(
ret
<
0
)
goto
out
;
fe
->
dpcm
[
stream
].
runtime_update
=
SND_SOC_DPCM_UPDATE_FE
;
ret
=
dpcm_be_dai_trigger
(
fe
,
stream
,
cmd
);
...
...
@@ -415,8 +579,10 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
int
ret
=
0
;
int
ret
=
0
,
__ret
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
...
...
@@ -432,12 +598,30 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
goto
err
;
}
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
set_params
)
{
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
set_params
)
{
ret
=
platform
->
driver
->
compr_ops
->
set_params
(
cstream
,
params
);
if
(
ret
<
0
)
goto
err
;
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
set_params
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
set_params
(
cstream
,
params
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
if
(
ret
<
0
)
goto
err
;
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
)
...
...
@@ -471,8 +655,10 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
struct
snd_pcm_substream
*
fe_substream
=
fe
->
pcm
->
streams
[
cstream
->
direction
].
substream
;
struct
snd_soc_platform
*
platform
=
fe
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
fe
->
cpu_dai
;
int
ret
=
0
,
stream
;
int
ret
=
0
,
__ret
,
stream
;
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
stream
=
SNDRV_PCM_STREAM_PLAYBACK
;
...
...
@@ -487,12 +673,30 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
goto
out
;
}
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
set_params
)
{
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
set_params
)
{
ret
=
platform
->
driver
->
compr_ops
->
set_params
(
cstream
,
params
);
if
(
ret
<
0
)
goto
out
;
}
for_each_rtdcom
(
fe
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
set_params
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
set_params
(
cstream
,
params
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
if
(
ret
<
0
)
goto
out
;
if
(
fe
->
dai_link
->
compr_ops
&&
fe
->
dai_link
->
compr_ops
->
set_params
)
{
ret
=
fe
->
dai_link
->
compr_ops
->
set_params
(
cstream
);
if
(
ret
<
0
)
...
...
@@ -531,8 +735,10 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
int
ret
=
0
;
int
ret
=
0
,
__ret
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
...
...
@@ -542,8 +748,27 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
goto
err
;
}
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_params
)
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_params
)
{
ret
=
platform
->
driver
->
compr_ops
->
get_params
(
cstream
,
params
);
if
(
ret
<
0
)
goto
err
;
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
get_params
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
get_params
(
cstream
,
params
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
err:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
...
...
@@ -555,13 +780,35 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
int
ret
=
0
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
int
ret
=
0
,
__ret
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_caps
)
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_caps
)
{
ret
=
platform
->
driver
->
compr_ops
->
get_caps
(
cstream
,
caps
);
if
(
ret
<
0
)
goto
err
;
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
get_caps
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
get_caps
(
cstream
,
caps
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
err:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
...
...
@@ -571,13 +818,35 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
int
ret
=
0
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
int
ret
=
0
,
__ret
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_codec_caps
)
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_codec_caps
)
{
ret
=
platform
->
driver
->
compr_ops
->
get_codec_caps
(
cstream
,
codec
);
if
(
ret
<
0
)
goto
err
;
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
get_codec_caps
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
get_codec_caps
(
cstream
,
codec
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
err:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
...
...
@@ -586,8 +855,10 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
int
ret
=
0
;
int
ret
=
0
,
__ret
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
...
...
@@ -597,8 +868,27 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
goto
err
;
}
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
ack
)
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
ack
)
{
ret
=
platform
->
driver
->
compr_ops
->
ack
(
cstream
,
bytes
);
if
(
ret
<
0
)
goto
err
;
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
ack
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
ack
(
cstream
,
bytes
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
err:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
...
...
@@ -610,7 +900,9 @@ 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
;
int
ret
=
0
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
int
ret
=
0
,
__ret
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
...
...
@@ -618,9 +910,29 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
if
(
cpu_dai
->
driver
->
cops
&&
cpu_dai
->
driver
->
cops
->
pointer
)
cpu_dai
->
driver
->
cops
->
pointer
(
cstream
,
tstamp
,
cpu_dai
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
pointer
)
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
pointer
)
{
ret
=
platform
->
driver
->
compr_ops
->
pointer
(
cstream
,
tstamp
);
if
(
ret
<
0
)
goto
err
;
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
pointer
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
pointer
(
cstream
,
tstamp
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
err:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
...
...
@@ -630,13 +942,34 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
int
ret
=
0
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
int
ret
=
0
,
__ret
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
copy
)
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
copy
)
{
ret
=
platform
->
driver
->
compr_ops
->
copy
(
cstream
,
buf
,
count
);
if
(
ret
<
0
)
goto
err
;
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
copy
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
copy
(
cstream
,
buf
,
count
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
err:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
}
...
...
@@ -646,8 +979,10 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
int
ret
=
0
;
int
ret
=
0
,
__ret
;
if
(
cpu_dai
->
driver
->
cops
&&
cpu_dai
->
driver
->
cops
->
set_metadata
)
{
ret
=
cpu_dai
->
driver
->
cops
->
set_metadata
(
cstream
,
metadata
,
cpu_dai
);
...
...
@@ -655,8 +990,27 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
return
ret
;
}
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
set_metadata
)
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
set_metadata
)
{
ret
=
platform
->
driver
->
compr_ops
->
set_metadata
(
cstream
,
metadata
);
if
(
ret
<
0
)
return
ret
;
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
set_metadata
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
set_metadata
(
cstream
,
metadata
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
return
ret
;
}
...
...
@@ -666,8 +1020,10 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
int
ret
=
0
;
int
ret
=
0
,
__ret
;
if
(
cpu_dai
->
driver
->
cops
&&
cpu_dai
->
driver
->
cops
->
get_metadata
)
{
ret
=
cpu_dai
->
driver
->
cops
->
get_metadata
(
cstream
,
metadata
,
cpu_dai
);
...
...
@@ -675,8 +1031,27 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
return
ret
;
}
if
(
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_metadata
)
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
get_metadata
)
{
ret
=
platform
->
driver
->
compr_ops
->
get_metadata
(
cstream
,
metadata
);
if
(
ret
<
0
)
return
ret
;
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
get_metadata
)
continue
;
__ret
=
component
->
driver
->
compr_ops
->
get_metadata
(
cstream
,
metadata
);
if
(
__ret
<
0
)
ret
=
__ret
;
}
return
ret
;
}
...
...
@@ -723,6 +1098,8 @@ int snd_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_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_compr
*
compr
;
...
...
@@ -798,9 +1175,25 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
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
)
if
(
platform
&&
platform
->
driver
->
compr_ops
&&
platform
->
driver
->
compr_ops
->
copy
)
compr
->
ops
->
copy
=
soc_compr_copy
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
compr_ops
||
!
component
->
driver
->
compr_ops
->
copy
)
continue
;
compr
->
ops
->
copy
=
soc_compr_copy
;
}
mutex_init
(
&
compr
->
lock
);
ret
=
snd_compress_new
(
rtd
->
card
->
snd_card
,
num
,
direction
,
...
...
sound/soc/soc-core.c
View file @
aa38bff8
...
...
@@ -614,6 +614,8 @@ struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
}
EXPORT_SYMBOL_GPL
(
snd_soc_get_dai_substream
);
static
const
struct
snd_soc_ops
null_snd_soc_ops
;
static
struct
snd_soc_pcm_runtime
*
soc_new_pcm_runtime
(
struct
snd_soc_card
*
card
,
struct
snd_soc_dai_link
*
dai_link
)
{
...
...
@@ -626,6 +628,9 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
INIT_LIST_HEAD
(
&
rtd
->
component_list
);
rtd
->
card
=
card
;
rtd
->
dai_link
=
dai_link
;
if
(
!
rtd
->
dai_link
->
ops
)
rtd
->
dai_link
->
ops
=
&
null_snd_soc_ops
;
rtd
->
codec_dais
=
kzalloc
(
sizeof
(
struct
snd_soc_dai
*
)
*
dai_link
->
num_codecs
,
GFP_KERNEL
);
...
...
@@ -639,8 +644,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
static
void
soc_free_pcm_runtime
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
if
(
rtd
&&
rtd
->
codec_dais
)
kfree
(
rtd
->
codec_dais
);
kfree
(
rtd
->
codec_dais
);
snd_soc_rtdcom_del_all
(
rtd
);
kfree
(
rtd
);
}
...
...
@@ -2632,7 +2636,7 @@ EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
int
snd_soc_dai_set_sysclk
(
struct
snd_soc_dai
*
dai
,
int
clk_id
,
unsigned
int
freq
,
int
dir
)
{
if
(
dai
->
driver
&&
dai
->
driver
->
ops
->
set_sysclk
)
if
(
dai
->
driver
->
ops
->
set_sysclk
)
return
dai
->
driver
->
ops
->
set_sysclk
(
dai
,
clk_id
,
freq
,
dir
);
return
snd_soc_component_set_sysclk
(
dai
->
component
,
clk_id
,
0
,
...
...
@@ -2700,7 +2704,7 @@ EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
int
snd_soc_dai_set_clkdiv
(
struct
snd_soc_dai
*
dai
,
int
div_id
,
int
div
)
{
if
(
dai
->
driver
&&
dai
->
driver
->
ops
->
set_clkdiv
)
if
(
dai
->
driver
->
ops
->
set_clkdiv
)
return
dai
->
driver
->
ops
->
set_clkdiv
(
dai
,
div_id
,
div
);
else
return
-
EINVAL
;
...
...
@@ -2720,7 +2724,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
int
snd_soc_dai_set_pll
(
struct
snd_soc_dai
*
dai
,
int
pll_id
,
int
source
,
unsigned
int
freq_in
,
unsigned
int
freq_out
)
{
if
(
dai
->
driver
&&
dai
->
driver
->
ops
->
set_pll
)
if
(
dai
->
driver
->
ops
->
set_pll
)
return
dai
->
driver
->
ops
->
set_pll
(
dai
,
pll_id
,
source
,
freq_in
,
freq_out
);
...
...
@@ -2786,7 +2790,7 @@ EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
*/
int
snd_soc_dai_set_bclk_ratio
(
struct
snd_soc_dai
*
dai
,
unsigned
int
ratio
)
{
if
(
dai
->
driver
&&
dai
->
driver
->
ops
->
set_bclk_ratio
)
if
(
dai
->
driver
->
ops
->
set_bclk_ratio
)
return
dai
->
driver
->
ops
->
set_bclk_ratio
(
dai
,
ratio
);
else
return
-
EINVAL
;
...
...
@@ -2860,7 +2864,7 @@ static int snd_soc_xlate_tdm_slot_mask(unsigned int slots,
int
snd_soc_dai_set_tdm_slot
(
struct
snd_soc_dai
*
dai
,
unsigned
int
tx_mask
,
unsigned
int
rx_mask
,
int
slots
,
int
slot_width
)
{
if
(
dai
->
driver
&&
dai
->
driver
->
ops
->
xlate_tdm_slot_mask
)
if
(
dai
->
driver
->
ops
->
xlate_tdm_slot_mask
)
dai
->
driver
->
ops
->
xlate_tdm_slot_mask
(
slots
,
&
tx_mask
,
&
rx_mask
);
else
...
...
@@ -2869,7 +2873,7 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
dai
->
tx_mask
=
tx_mask
;
dai
->
rx_mask
=
rx_mask
;
if
(
dai
->
driver
&&
dai
->
driver
->
ops
->
set_tdm_slot
)
if
(
dai
->
driver
->
ops
->
set_tdm_slot
)
return
dai
->
driver
->
ops
->
set_tdm_slot
(
dai
,
tx_mask
,
rx_mask
,
slots
,
slot_width
);
else
...
...
@@ -2893,7 +2897,7 @@ int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
unsigned
int
tx_num
,
unsigned
int
*
tx_slot
,
unsigned
int
rx_num
,
unsigned
int
*
rx_slot
)
{
if
(
dai
->
driver
&&
dai
->
driver
->
ops
->
set_channel_map
)
if
(
dai
->
driver
->
ops
->
set_channel_map
)
return
dai
->
driver
->
ops
->
set_channel_map
(
dai
,
tx_num
,
tx_slot
,
rx_num
,
rx_slot
);
else
...
...
@@ -2910,7 +2914,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
*/
int
snd_soc_dai_set_tristate
(
struct
snd_soc_dai
*
dai
,
int
tristate
)
{
if
(
dai
->
driver
&&
dai
->
driver
->
ops
->
set_tristate
)
if
(
dai
->
driver
->
ops
->
set_tristate
)
return
dai
->
driver
->
ops
->
set_tristate
(
dai
,
tristate
);
else
return
-
EINVAL
;
...
...
@@ -3250,6 +3254,30 @@ static int snd_soc_component_stream_event(struct snd_soc_dapm_context *dapm,
return
component
->
driver
->
stream_event
(
component
,
event
);
}
static
int
snd_soc_component_drv_pcm_new
(
struct
snd_soc_component
*
component
,
struct
snd_soc_pcm_runtime
*
rtd
)
{
if
(
component
->
driver
->
pcm_new
)
return
component
->
driver
->
pcm_new
(
rtd
);
return
0
;
}
static
void
snd_soc_component_drv_pcm_free
(
struct
snd_soc_component
*
component
,
struct
snd_pcm
*
pcm
)
{
if
(
component
->
driver
->
pcm_free
)
component
->
driver
->
pcm_free
(
pcm
);
}
static
int
snd_soc_component_set_bias_level
(
struct
snd_soc_dapm_context
*
dapm
,
enum
snd_soc_bias_level
level
)
{
struct
snd_soc_component
*
component
=
dapm
->
component
;
return
component
->
driver
->
set_bias_level
(
component
,
level
);
}
static
int
snd_soc_component_initialize
(
struct
snd_soc_component
*
component
,
const
struct
snd_soc_component_driver
*
driver
,
struct
device
*
dev
)
{
...
...
@@ -3270,16 +3298,21 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
component
->
set_sysclk
=
component
->
driver
->
set_sysclk
;
component
->
set_pll
=
component
->
driver
->
set_pll
;
component
->
set_jack
=
component
->
driver
->
set_jack
;
component
->
pcm_new
=
snd_soc_component_drv_pcm_new
;
component
->
pcm_free
=
snd_soc_component_drv_pcm_free
;
dapm
=
snd_soc_component_get_dapm
(
component
);
dapm
->
dev
=
dev
;
dapm
->
component
=
component
;
dapm
->
bias_level
=
SND_SOC_BIAS_OFF
;
dapm
->
idle_bias_off
=
true
;
dapm
->
idle_bias_off
=
!
driver
->
idle_bias_on
;
dapm
->
suspend_bias_off
=
driver
->
suspend_bias_off
;
if
(
driver
->
seq_notifier
)
dapm
->
seq_notifier
=
snd_soc_component_seq_notifier
;
if
(
driver
->
stream_event
)
dapm
->
stream_event
=
snd_soc_component_stream_event
;
if
(
driver
->
set_bias_level
)
dapm
->
set_bias_level
=
snd_soc_component_set_bias_level
;
INIT_LIST_HEAD
(
&
component
->
dai_list
);
mutex_init
(
&
component
->
io_mutex
);
...
...
@@ -3371,6 +3404,41 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
list_del
(
&
component
->
list
);
}
#define ENDIANNESS_MAP(name) \
(SNDRV_PCM_FMTBIT_##name##LE | SNDRV_PCM_FMTBIT_##name##BE)
static
u64
endianness_format_map
[]
=
{
ENDIANNESS_MAP
(
S16_
),
ENDIANNESS_MAP
(
U16_
),
ENDIANNESS_MAP
(
S24_
),
ENDIANNESS_MAP
(
U24_
),
ENDIANNESS_MAP
(
S32_
),
ENDIANNESS_MAP
(
U32_
),
ENDIANNESS_MAP
(
S24_3
),
ENDIANNESS_MAP
(
U24_3
),
ENDIANNESS_MAP
(
S20_3
),
ENDIANNESS_MAP
(
U20_3
),
ENDIANNESS_MAP
(
S18_3
),
ENDIANNESS_MAP
(
U18_3
),
ENDIANNESS_MAP
(
FLOAT_
),
ENDIANNESS_MAP
(
FLOAT64_
),
ENDIANNESS_MAP
(
IEC958_SUBFRAME_
),
};
/*
* Fix up the DAI formats for endianness: codecs don't actually see
* the endianness of the data but we're using the CPU format
* definitions which do need to include endianness so we ensure that
* codec DAIs always have both big and little endian variants set.
*/
static
void
convert_endianness_formats
(
struct
snd_soc_pcm_stream
*
stream
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
endianness_format_map
);
i
++
)
if
(
stream
->
formats
&
endianness_format_map
[
i
])
stream
->
formats
|=
endianness_format_map
[
i
];
}
int
snd_soc_add_component
(
struct
device
*
dev
,
struct
snd_soc_component
*
component
,
const
struct
snd_soc_component_driver
*
component_driver
,
...
...
@@ -3378,6 +3446,7 @@ int snd_soc_add_component(struct device *dev,
int
num_dai
)
{
int
ret
;
int
i
;
ret
=
snd_soc_component_initialize
(
component
,
component_driver
,
dev
);
if
(
ret
)
...
...
@@ -3386,7 +3455,15 @@ int snd_soc_add_component(struct device *dev,
component
->
ignore_pmdown_time
=
true
;
component
->
registered_as_component
=
true
;
ret
=
snd_soc_register_dais
(
component
,
dai_drv
,
num_dai
,
true
);
if
(
component_driver
->
endianness
)
{
for
(
i
=
0
;
i
<
num_dai
;
i
++
)
{
convert_endianness_formats
(
&
dai_drv
[
i
].
playback
);
convert_endianness_formats
(
&
dai_drv
[
i
].
capture
);
}
}
ret
=
snd_soc_register_dais
(
component
,
dai_drv
,
num_dai
,
!
component_driver
->
non_legacy_dai_naming
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"ASoC: Failed to register DAIs: %d
\n
"
,
ret
);
goto
err_cleanup
;
...
...
@@ -3412,10 +3489,8 @@ int snd_soc_register_component(struct device *dev,
struct
snd_soc_component
*
component
;
component
=
kzalloc
(
sizeof
(
*
component
),
GFP_KERNEL
);
if
(
!
component
)
{
dev_err
(
dev
,
"ASoC: Failed to allocate memory
\n
"
);
if
(
!
component
)
return
-
ENOMEM
;
}
return
snd_soc_add_component
(
dev
,
component
,
component_driver
,
dai_drv
,
num_dai
);
...
...
@@ -3460,6 +3535,32 @@ void snd_soc_unregister_component(struct device *dev)
}
EXPORT_SYMBOL_GPL
(
snd_soc_unregister_component
);
struct
snd_soc_component
*
snd_soc_lookup_component
(
struct
device
*
dev
,
const
char
*
driver_name
)
{
struct
snd_soc_component
*
component
;
struct
snd_soc_component
*
ret
;
ret
=
NULL
;
mutex_lock
(
&
client_mutex
);
list_for_each_entry
(
component
,
&
component_list
,
list
)
{
if
(
dev
!=
component
->
dev
)
continue
;
if
(
driver_name
&&
(
driver_name
!=
component
->
driver
->
name
)
&&
(
strcmp
(
component
->
driver
->
name
,
driver_name
)
!=
0
))
continue
;
ret
=
component
;
break
;
}
mutex_unlock
(
&
client_mutex
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_lookup_component
);
static
int
snd_soc_platform_drv_probe
(
struct
snd_soc_component
*
component
)
{
struct
snd_soc_platform
*
platform
=
snd_soc_component_to_platform
(
component
);
...
...
@@ -3474,6 +3575,26 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
platform
->
driver
->
remove
(
platform
);
}
static
int
snd_soc_platform_drv_pcm_new
(
struct
snd_soc_component
*
component
,
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
snd_soc_platform
*
platform
=
snd_soc_component_to_platform
(
component
);
if
(
platform
->
driver
->
pcm_new
)
return
platform
->
driver
->
pcm_new
(
rtd
);
return
0
;
}
static
void
snd_soc_platform_drv_pcm_free
(
struct
snd_soc_component
*
component
,
struct
snd_pcm
*
pcm
)
{
struct
snd_soc_platform
*
platform
=
snd_soc_component_to_platform
(
component
);
if
(
platform
->
driver
->
pcm_free
)
platform
->
driver
->
pcm_free
(
pcm
);
}
/**
* snd_soc_add_platform - Add a platform to the ASoC core
* @dev: The parent device for the platform
...
...
@@ -3497,6 +3618,10 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
platform
->
component
.
probe
=
snd_soc_platform_drv_probe
;
if
(
platform_drv
->
remove
)
platform
->
component
.
remove
=
snd_soc_platform_drv_remove
;
if
(
platform_drv
->
pcm_new
)
platform
->
component
.
pcm_new
=
snd_soc_platform_drv_pcm_new
;
if
(
platform_drv
->
pcm_free
)
platform
->
component
.
pcm_free
=
snd_soc_platform_drv_pcm_free
;
#ifdef CONFIG_DEBUG_FS
platform
->
component
.
debugfs_prefix
=
"platform"
;
...
...
@@ -3594,39 +3719,6 @@ void snd_soc_unregister_platform(struct device *dev)
}
EXPORT_SYMBOL_GPL
(
snd_soc_unregister_platform
);
static
u64
codec_format_map
[]
=
{
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S16_BE
,
SNDRV_PCM_FMTBIT_U16_LE
|
SNDRV_PCM_FMTBIT_U16_BE
,
SNDRV_PCM_FMTBIT_S24_LE
|
SNDRV_PCM_FMTBIT_S24_BE
,
SNDRV_PCM_FMTBIT_U24_LE
|
SNDRV_PCM_FMTBIT_U24_BE
,
SNDRV_PCM_FMTBIT_S32_LE
|
SNDRV_PCM_FMTBIT_S32_BE
,
SNDRV_PCM_FMTBIT_U32_LE
|
SNDRV_PCM_FMTBIT_U32_BE
,
SNDRV_PCM_FMTBIT_S24_3LE
|
SNDRV_PCM_FMTBIT_U24_3BE
,
SNDRV_PCM_FMTBIT_U24_3LE
|
SNDRV_PCM_FMTBIT_U24_3BE
,
SNDRV_PCM_FMTBIT_S20_3LE
|
SNDRV_PCM_FMTBIT_S20_3BE
,
SNDRV_PCM_FMTBIT_U20_3LE
|
SNDRV_PCM_FMTBIT_U20_3BE
,
SNDRV_PCM_FMTBIT_S18_3LE
|
SNDRV_PCM_FMTBIT_S18_3BE
,
SNDRV_PCM_FMTBIT_U18_3LE
|
SNDRV_PCM_FMTBIT_U18_3BE
,
SNDRV_PCM_FMTBIT_FLOAT_LE
|
SNDRV_PCM_FMTBIT_FLOAT_BE
,
SNDRV_PCM_FMTBIT_FLOAT64_LE
|
SNDRV_PCM_FMTBIT_FLOAT64_BE
,
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
|
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE
,
};
/* Fix up the DAI formats for endianness: codecs don't actually see
* the endianness of the data but we're using the CPU format
* definitions which do need to include endianness so we ensure that
* codec DAIs always have both big and little endian variants set.
*/
static
void
fixup_codec_formats
(
struct
snd_soc_pcm_stream
*
stream
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
codec_format_map
);
i
++
)
if
(
stream
->
formats
&
codec_format_map
[
i
])
stream
->
formats
|=
codec_format_map
[
i
];
}
static
int
snd_soc_codec_drv_probe
(
struct
snd_soc_component
*
component
)
{
struct
snd_soc_codec
*
codec
=
snd_soc_component_to_codec
(
component
);
...
...
@@ -3777,8 +3869,8 @@ int snd_soc_register_codec(struct device *dev,
codec
->
component
.
regmap
=
codec_drv
->
get_regmap
(
dev
);
for
(
i
=
0
;
i
<
num_dai
;
i
++
)
{
fixup_codec
_formats
(
&
dai_drv
[
i
].
playback
);
fixup_codec
_formats
(
&
dai_drv
[
i
].
capture
);
convert_endianness
_formats
(
&
dai_drv
[
i
].
playback
);
convert_endianness
_formats
(
&
dai_drv
[
i
].
capture
);
}
ret
=
snd_soc_register_dais
(
&
codec
->
component
,
dai_drv
,
num_dai
,
false
);
...
...
sound/soc/soc-dapm.c
View file @
aa38bff8
...
...
@@ -3681,7 +3681,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
switch
(
event
)
{
case
SND_SOC_DAPM_PRE_PMU
:
substream
.
stream
=
SNDRV_PCM_STREAM_CAPTURE
;
if
(
source
->
driver
->
ops
&&
source
->
driver
->
ops
->
startup
)
{
if
(
source
->
driver
->
ops
->
startup
)
{
ret
=
source
->
driver
->
ops
->
startup
(
&
substream
,
source
);
if
(
ret
<
0
)
{
dev_err
(
source
->
dev
,
...
...
@@ -3695,7 +3695,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
goto
out
;
substream
.
stream
=
SNDRV_PCM_STREAM_PLAYBACK
;
if
(
sink
->
driver
->
ops
&&
sink
->
driver
->
ops
->
startup
)
{
if
(
sink
->
driver
->
ops
->
startup
)
{
ret
=
sink
->
driver
->
ops
->
startup
(
&
substream
,
sink
);
if
(
ret
<
0
)
{
dev_err
(
sink
->
dev
,
...
...
@@ -3725,13 +3725,13 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
ret
=
0
;
source
->
active
--
;
if
(
source
->
driver
->
ops
&&
source
->
driver
->
ops
->
shutdown
)
{
if
(
source
->
driver
->
ops
->
shutdown
)
{
substream
.
stream
=
SNDRV_PCM_STREAM_CAPTURE
;
source
->
driver
->
ops
->
shutdown
(
&
substream
,
source
);
}
sink
->
active
--
;
if
(
sink
->
driver
->
ops
&&
sink
->
driver
->
ops
->
shutdown
)
{
if
(
sink
->
driver
->
ops
->
shutdown
)
{
substream
.
stream
=
SNDRV_PCM_STREAM_PLAYBACK
;
sink
->
driver
->
ops
->
shutdown
(
&
substream
,
sink
);
}
...
...
sound/soc/soc-io.c
View file @
aa38bff8
...
...
@@ -41,6 +41,20 @@ int snd_soc_component_read(struct snd_soc_component *component,
}
EXPORT_SYMBOL_GPL
(
snd_soc_component_read
);
unsigned
int
snd_soc_component_read32
(
struct
snd_soc_component
*
component
,
unsigned
int
reg
)
{
unsigned
int
val
;
int
ret
;
ret
=
snd_soc_component_read
(
component
,
reg
,
&
val
);
if
(
ret
<
0
)
return
-
1
;
return
val
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_component_read32
);
/**
* snd_soc_component_write() - Write register value
* @component: Component to write to
...
...
sound/soc/soc-pcm.c
View file @
aa38bff8
...
...
@@ -133,16 +133,25 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
*/
bool
snd_soc_runtime_ignore_pmdown_time
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_component
*
component
;
int
i
;
bool
ignore
=
true
;
if
(
!
rtd
->
pmdown_time
||
rtd
->
dai_link
->
ignore_pmdown_time
)
return
true
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
ignore
&=
!
component
->
driver
->
pmdown_time
;
}
/* this will be removed */
for
(
i
=
0
;
i
<
rtd
->
num_codecs
;
i
++
)
ignore
&=
rtd
->
codec_dais
[
i
]
->
component
->
ignore_pmdown_time
;
return
rtd
->
cpu_dai
->
component
->
ignore_pmdown_time
&&
ignore
;
return
ignore
;
}
/**
...
...
@@ -459,7 +468,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
;
const
char
*
codec_dai_name
=
"multicodec"
;
int
i
,
ret
=
0
;
int
i
,
ret
=
0
,
__ret
;
pinctrl_pm_select_default_state
(
cpu_dai
->
dev
);
for
(
i
=
0
;
i
<
rtd
->
num_codecs
;
i
++
)
...
...
@@ -474,7 +483,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
/* startup the audio subsystem */
if
(
cpu_dai
->
driver
->
ops
&&
cpu_dai
->
driver
->
ops
->
startup
)
{
if
(
cpu_dai
->
driver
->
ops
->
startup
)
{
ret
=
cpu_dai
->
driver
->
ops
->
startup
(
substream
,
cpu_dai
);
if
(
ret
<
0
)
{
dev_err
(
cpu_dai
->
dev
,
"ASoC: can't open interface"
...
...
@@ -483,7 +492,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
}
}
if
(
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
open
)
{
if
(
platform
&&
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
open
)
{
ret
=
platform
->
driver
->
ops
->
open
(
substream
);
if
(
ret
<
0
)
{
dev_err
(
platform
->
dev
,
"ASoC: can't open platform"
...
...
@@ -492,9 +501,32 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
}
}
ret
=
0
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
open
)
continue
;
__ret
=
component
->
driver
->
ops
->
open
(
substream
);
if
(
__ret
<
0
)
{
dev_err
(
component
->
dev
,
"ASoC: can't open component %s: %d
\n
"
,
component
->
name
,
ret
);
ret
=
__ret
;
}
}
if
(
ret
<
0
)
goto
component_err
;
for
(
i
=
0
;
i
<
rtd
->
num_codecs
;
i
++
)
{
codec_dai
=
rtd
->
codec_dais
[
i
];
if
(
codec_dai
->
driver
->
ops
&&
codec_dai
->
driver
->
ops
->
startup
)
{
if
(
codec_dai
->
driver
->
ops
->
startup
)
{
ret
=
codec_dai
->
driver
->
ops
->
startup
(
substream
,
codec_dai
);
if
(
ret
<
0
)
{
...
...
@@ -511,7 +543,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
codec_dai
->
rx_mask
=
0
;
}
if
(
rtd
->
dai_link
->
ops
&&
rtd
->
dai_link
->
ops
->
startup
)
{
if
(
rtd
->
dai_link
->
ops
->
startup
)
{
ret
=
rtd
->
dai_link
->
ops
->
startup
(
substream
);
if
(
ret
<
0
)
{
pr_err
(
"ASoC: %s startup failed: %d
\n
"
,
...
...
@@ -585,7 +617,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
return
0
;
config_err:
if
(
rtd
->
dai_link
->
ops
&&
rtd
->
dai_link
->
ops
->
shutdown
)
if
(
rtd
->
dai_link
->
ops
->
shutdown
)
rtd
->
dai_link
->
ops
->
shutdown
(
substream
);
machine_err:
...
...
@@ -598,7 +630,22 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
codec_dai
->
driver
->
ops
->
shutdown
(
substream
,
codec_dai
);
}
if
(
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
close
)
component_err:
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
close
)
continue
;
component
->
driver
->
ops
->
close
(
substream
);
}
if
(
platform
&&
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
close
)
platform
->
driver
->
ops
->
close
(
substream
);
platform_err:
...
...
@@ -692,12 +739,26 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
codec_dai
->
driver
->
ops
->
shutdown
(
substream
,
codec_dai
);
}
if
(
rtd
->
dai_link
->
ops
&&
rtd
->
dai_link
->
ops
->
shutdown
)
if
(
rtd
->
dai_link
->
ops
->
shutdown
)
rtd
->
dai_link
->
ops
->
shutdown
(
substream
);
if
(
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
close
)
if
(
platform
&&
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
close
)
platform
->
driver
->
ops
->
close
(
substream
);
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
close
)
continue
;
component
->
driver
->
ops
->
close
(
substream
);
}
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
if
(
snd_soc_runtime_ignore_pmdown_time
(
rtd
))
{
/* powered down playback stream now */
...
...
@@ -745,13 +806,15 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
;
int
i
,
ret
=
0
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
rtd
->
dai_link
->
ops
&&
rtd
->
dai_link
->
ops
->
prepare
)
{
if
(
rtd
->
dai_link
->
ops
->
prepare
)
{
ret
=
rtd
->
dai_link
->
ops
->
prepare
(
substream
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
card
->
dev
,
"ASoC: machine prepare error:"
...
...
@@ -760,7 +823,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
}
}
if
(
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
prepare
)
{
if
(
platform
&&
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
prepare
)
{
ret
=
platform
->
driver
->
ops
->
prepare
(
substream
);
if
(
ret
<
0
)
{
dev_err
(
platform
->
dev
,
"ASoC: platform prepare error:"
...
...
@@ -769,9 +832,28 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
}
}
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
prepare
)
continue
;
ret
=
component
->
driver
->
ops
->
prepare
(
substream
);
if
(
ret
<
0
)
{
dev_err
(
component
->
dev
,
"ASoC: platform prepare error: %d
\n
"
,
ret
);
goto
out
;
}
}
for
(
i
=
0
;
i
<
rtd
->
num_codecs
;
i
++
)
{
codec_dai
=
rtd
->
codec_dais
[
i
];
if
(
codec_dai
->
driver
->
ops
&&
codec_dai
->
driver
->
ops
->
prepare
)
{
if
(
codec_dai
->
driver
->
ops
->
prepare
)
{
ret
=
codec_dai
->
driver
->
ops
->
prepare
(
substream
,
codec_dai
);
if
(
ret
<
0
)
{
...
...
@@ -783,7 +865,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
}
}
if
(
cpu_dai
->
driver
->
ops
&&
cpu_dai
->
driver
->
ops
->
prepare
)
{
if
(
cpu_dai
->
driver
->
ops
->
prepare
)
{
ret
=
cpu_dai
->
driver
->
ops
->
prepare
(
substream
,
cpu_dai
);
if
(
ret
<
0
)
{
dev_err
(
cpu_dai
->
dev
,
...
...
@@ -829,7 +911,7 @@ int soc_dai_hw_params(struct snd_pcm_substream *substream,
{
int
ret
;
if
(
dai
->
driver
->
ops
&&
dai
->
driver
->
ops
->
hw_params
)
{
if
(
dai
->
driver
->
ops
->
hw_params
)
{
ret
=
dai
->
driver
->
ops
->
hw_params
(
substream
,
params
,
dai
);
if
(
ret
<
0
)
{
dev_err
(
dai
->
dev
,
"ASoC: can't set %s hw params: %d
\n
"
,
...
...
@@ -851,16 +933,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
int
i
,
ret
=
0
;
int
i
,
ret
=
0
,
__ret
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
ret
=
soc_pcm_params_symmetry
(
substream
,
params
);
if
(
ret
)
goto
out
;
if
(
rtd
->
dai_link
->
ops
&&
rtd
->
dai_link
->
ops
->
hw_params
)
{
if
(
rtd
->
dai_link
->
ops
->
hw_params
)
{
ret
=
rtd
->
dai_link
->
ops
->
hw_params
(
substream
,
params
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
card
->
dev
,
"ASoC: machine hw_params"
...
...
@@ -915,7 +994,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
if
(
ret
<
0
)
goto
interface_err
;
if
(
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
hw_params
)
{
if
(
platform
&&
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
hw_params
)
{
ret
=
platform
->
driver
->
ops
->
hw_params
(
substream
,
params
);
if
(
ret
<
0
)
{
dev_err
(
platform
->
dev
,
"ASoC: %s hw params failed: %d
\n
"
,
...
...
@@ -924,18 +1003,62 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
}
}
ret
=
0
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
hw_params
)
continue
;
__ret
=
component
->
driver
->
ops
->
hw_params
(
substream
,
params
);
if
(
__ret
<
0
)
{
dev_err
(
component
->
dev
,
"ASoC: %s hw params failed: %d
\n
"
,
component
->
name
,
ret
);
ret
=
__ret
;
}
}
if
(
ret
<
0
)
goto
component_err
;
/* store the parameters for each DAIs */
cpu_dai
->
rate
=
params_rate
(
params
);
cpu_dai
->
channels
=
params_channels
(
params
);
cpu_dai
->
sample_bits
=
snd_pcm_format_physical_width
(
params_format
(
params
));
ret
=
soc_pcm_params_symmetry
(
substream
,
params
);
if
(
ret
)
goto
component_err
;
out:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
ret
;
component_err:
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
hw_free
)
continue
;
component
->
driver
->
ops
->
hw_free
(
substream
);
}
if
(
platform
&&
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
hw_free
)
platform
->
driver
->
ops
->
hw_free
(
substream
);
platform_err:
if
(
cpu_dai
->
driver
->
ops
&&
cpu_dai
->
driver
->
ops
->
hw_free
)
if
(
cpu_dai
->
driver
->
ops
->
hw_free
)
cpu_dai
->
driver
->
ops
->
hw_free
(
substream
,
cpu_dai
);
interface_err:
...
...
@@ -944,12 +1067,12 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
codec_err:
while
(
--
i
>=
0
)
{
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dais
[
i
];
if
(
codec_dai
->
driver
->
ops
&&
codec_dai
->
driver
->
ops
->
hw_free
)
if
(
codec_dai
->
driver
->
ops
->
hw_free
)
codec_dai
->
driver
->
ops
->
hw_free
(
substream
,
codec_dai
);
codec_dai
->
rate
=
0
;
}
if
(
rtd
->
dai_link
->
ops
&&
rtd
->
dai_link
->
ops
->
hw_free
)
if
(
rtd
->
dai_link
->
ops
->
hw_free
)
rtd
->
dai_link
->
ops
->
hw_free
(
substream
);
mutex_unlock
(
&
rtd
->
pcm_mutex
);
...
...
@@ -963,6 +1086,8 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
;
bool
playback
=
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
;
...
...
@@ -995,21 +1120,36 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
}
/* free any machine hw params */
if
(
rtd
->
dai_link
->
ops
&&
rtd
->
dai_link
->
ops
->
hw_free
)
if
(
rtd
->
dai_link
->
ops
->
hw_free
)
rtd
->
dai_link
->
ops
->
hw_free
(
substream
);
/* free any DMA resources */
if
(
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
hw_free
)
if
(
platform
&&
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
hw_free
)
platform
->
driver
->
ops
->
hw_free
(
substream
);
/* free any component resources */
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
hw_free
)
continue
;
component
->
driver
->
ops
->
hw_free
(
substream
);
}
/* now free hw params for the DAIs */
for
(
i
=
0
;
i
<
rtd
->
num_codecs
;
i
++
)
{
codec_dai
=
rtd
->
codec_dais
[
i
];
if
(
codec_dai
->
driver
->
ops
&&
codec_dai
->
driver
->
ops
->
hw_free
)
if
(
codec_dai
->
driver
->
ops
->
hw_free
)
codec_dai
->
driver
->
ops
->
hw_free
(
substream
,
codec_dai
);
}
if
(
cpu_dai
->
driver
->
ops
&&
cpu_dai
->
driver
->
ops
->
hw_free
)
if
(
cpu_dai
->
driver
->
ops
->
hw_free
)
cpu_dai
->
driver
->
ops
->
hw_free
(
substream
,
cpu_dai
);
mutex_unlock
(
&
rtd
->
pcm_mutex
);
...
...
@@ -1020,13 +1160,15 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
;
int
i
,
ret
;
for
(
i
=
0
;
i
<
rtd
->
num_codecs
;
i
++
)
{
codec_dai
=
rtd
->
codec_dais
[
i
];
if
(
codec_dai
->
driver
->
ops
&&
codec_dai
->
driver
->
ops
->
trigger
)
{
if
(
codec_dai
->
driver
->
ops
->
trigger
)
{
ret
=
codec_dai
->
driver
->
ops
->
trigger
(
substream
,
cmd
,
codec_dai
);
if
(
ret
<
0
)
...
...
@@ -1034,19 +1176,35 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
}
}
if
(
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
trigger
)
{
if
(
platform
&&
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
trigger
)
{
ret
=
platform
->
driver
->
ops
->
trigger
(
substream
,
cmd
);
if
(
ret
<
0
)
return
ret
;
}
if
(
cpu_dai
->
driver
->
ops
&&
cpu_dai
->
driver
->
ops
->
trigger
)
{
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
trigger
)
continue
;
ret
=
component
->
driver
->
ops
->
trigger
(
substream
,
cmd
);
if
(
ret
<
0
)
return
ret
;
}
if
(
cpu_dai
->
driver
->
ops
->
trigger
)
{
ret
=
cpu_dai
->
driver
->
ops
->
trigger
(
substream
,
cmd
,
cpu_dai
);
if
(
ret
<
0
)
return
ret
;
}
if
(
rtd
->
dai_link
->
ops
&&
rtd
->
dai_link
->
ops
->
trigger
)
{
if
(
rtd
->
dai_link
->
ops
->
trigger
)
{
ret
=
rtd
->
dai_link
->
ops
->
trigger
(
substream
,
cmd
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -1065,8 +1223,7 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
for
(
i
=
0
;
i
<
rtd
->
num_codecs
;
i
++
)
{
codec_dai
=
rtd
->
codec_dais
[
i
];
if
(
codec_dai
->
driver
->
ops
&&
codec_dai
->
driver
->
ops
->
bespoke_trigger
)
{
if
(
codec_dai
->
driver
->
ops
->
bespoke_trigger
)
{
ret
=
codec_dai
->
driver
->
ops
->
bespoke_trigger
(
substream
,
cmd
,
codec_dai
);
if
(
ret
<
0
)
...
...
@@ -1074,7 +1231,7 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
}
}
if
(
cpu_dai
->
driver
->
ops
&&
cpu_dai
->
driver
->
ops
->
bespoke_trigger
)
{
if
(
cpu_dai
->
driver
->
ops
->
bespoke_trigger
)
{
ret
=
cpu_dai
->
driver
->
ops
->
bespoke_trigger
(
substream
,
cmd
,
cpu_dai
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -1090,6 +1247,8 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
;
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
...
...
@@ -1098,15 +1257,31 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
snd_pcm_sframes_t
codec_delay
=
0
;
int
i
;
if
(
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
pointer
)
if
(
platform
&&
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
pointer
)
offset
=
platform
->
driver
->
ops
->
pointer
(
substream
);
if
(
cpu_dai
->
driver
->
ops
&&
cpu_dai
->
driver
->
ops
->
delay
)
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
pointer
)
continue
;
/* FIXME: use 1st pointer */
offset
=
component
->
driver
->
ops
->
pointer
(
substream
);
break
;
}
if
(
cpu_dai
->
driver
->
ops
->
delay
)
delay
+=
cpu_dai
->
driver
->
ops
->
delay
(
substream
,
cpu_dai
);
for
(
i
=
0
;
i
<
rtd
->
num_codecs
;
i
++
)
{
codec_dai
=
rtd
->
codec_dais
[
i
];
if
(
codec_dai
->
driver
->
ops
&&
codec_dai
->
driver
->
ops
->
delay
)
if
(
codec_dai
->
driver
->
ops
->
delay
)
codec_delay
=
max
(
codec_delay
,
codec_dai
->
driver
->
ops
->
delay
(
substream
,
codec_dai
));
...
...
@@ -2285,9 +2460,27 @@ static int soc_pcm_ioctl(struct snd_pcm_substream *substream,
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
if
(
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
ioctl
)
if
(
platform
&&
platform
->
driver
->
ops
&&
platform
->
driver
->
ops
->
ioctl
)
return
platform
->
driver
->
ops
->
ioctl
(
substream
,
cmd
,
arg
);
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* ignore duplication for now */
if
(
platform
&&
(
component
==
&
platform
->
component
))
continue
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
ioctl
)
continue
;
/* FIXME: use 1st ioctl */
return
component
->
driver
->
ops
->
ioctl
(
substream
,
cmd
,
arg
);
}
return
snd_pcm_lib_ioctl
(
substream
,
cmd
,
arg
);
}
...
...
@@ -2635,12 +2828,150 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
static
void
soc_pcm_private_free
(
struct
snd_pcm
*
pcm
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
pcm
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_component
*
component
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
/* need to sync the delayed work before releasing resources */
flush_delayed_work
(
&
rtd
->
delayed_work
);
component
=
rtdcom
->
component
;
if
(
component
->
pcm_free
)
component
->
pcm_free
(
component
,
pcm
);
}
}
static
int
soc_rtdcom_ack
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_component
*
component
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
ack
)
continue
;
/* FIXME. it returns 1st ask now */
return
component
->
driver
->
ops
->
ack
(
substream
);
}
return
-
EINVAL
;
}
static
int
soc_rtdcom_copy_user
(
struct
snd_pcm_substream
*
substream
,
int
channel
,
unsigned
long
pos
,
void
__user
*
buf
,
unsigned
long
bytes
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_component
*
component
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
copy_user
)
continue
;
/* FIXME. it returns 1st copy now */
return
component
->
driver
->
ops
->
copy_user
(
substream
,
channel
,
pos
,
buf
,
bytes
);
}
return
-
EINVAL
;
}
static
int
soc_rtdcom_copy_kernel
(
struct
snd_pcm_substream
*
substream
,
int
channel
,
unsigned
long
pos
,
void
*
buf
,
unsigned
long
bytes
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_component
*
component
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
/* need to sync the delayed work before releasing resources */
flush_delayed_work
(
&
rtd
->
delayed_work
);
if
(
platform
->
driver
->
pcm_free
)
platform
->
driver
->
pcm_free
(
pcm
);
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
copy_kernel
)
continue
;
/* FIXME. it returns 1st copy now */
return
component
->
driver
->
ops
->
copy_kernel
(
substream
,
channel
,
pos
,
buf
,
bytes
);
}
return
-
EINVAL
;
}
static
int
soc_rtdcom_fill_silence
(
struct
snd_pcm_substream
*
substream
,
int
channel
,
unsigned
long
pos
,
unsigned
long
bytes
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_component
*
component
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
fill_silence
)
continue
;
/* FIXME. it returns 1st silence now */
return
component
->
driver
->
ops
->
fill_silence
(
substream
,
channel
,
pos
,
bytes
);
}
return
-
EINVAL
;
}
static
struct
page
*
soc_rtdcom_page
(
struct
snd_pcm_substream
*
substream
,
unsigned
long
offset
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_component
*
component
;
struct
page
*
page
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
page
)
continue
;
/* FIXME. it returns 1st page now */
page
=
component
->
driver
->
ops
->
page
(
substream
,
offset
);
if
(
page
)
return
page
;
}
return
NULL
;
}
static
int
soc_rtdcom_mmap
(
struct
snd_pcm_substream
*
substream
,
struct
vm_area_struct
*
vma
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_soc_component
*
component
;
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
if
(
!
component
->
driver
->
ops
||
!
component
->
driver
->
ops
->
mmap
)
continue
;
/* FIXME. it returns 1st mmap now */
return
component
->
driver
->
ops
->
mmap
(
substream
,
vma
);
}
return
-
EINVAL
;
}
/* create a new pcm */
...
...
@@ -2649,6 +2980,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_dai
*
codec_dai
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_component
*
component
;
struct
snd_soc_rtdcom_list
*
rtdcom
;
struct
snd_pcm
*
pcm
;
char
new_name
[
64
];
int
ret
=
0
,
playback
=
0
,
capture
=
0
;
...
...
@@ -2743,7 +3076,28 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
rtd
->
ops
.
ioctl
=
soc_pcm_ioctl
;
}
if
(
platform
->
driver
->
ops
)
{
for_each_rtdcom
(
rtd
,
rtdcom
)
{
const
struct
snd_pcm_ops
*
ops
=
rtdcom
->
component
->
driver
->
ops
;
if
(
!
ops
)
continue
;
if
(
ops
->
ack
)
rtd
->
ops
.
ack
=
soc_rtdcom_ack
;
if
(
ops
->
copy_user
)
rtd
->
ops
.
copy_user
=
soc_rtdcom_copy_user
;
if
(
ops
->
copy_kernel
)
rtd
->
ops
.
copy_kernel
=
soc_rtdcom_copy_kernel
;
if
(
ops
->
fill_silence
)
rtd
->
ops
.
fill_silence
=
soc_rtdcom_fill_silence
;
if
(
ops
->
page
)
rtd
->
ops
.
page
=
soc_rtdcom_page
;
if
(
ops
->
mmap
)
rtd
->
ops
.
mmap
=
soc_rtdcom_mmap
;
}
/* overwrite */
if
(
platform
&&
platform
->
driver
->
ops
)
{
rtd
->
ops
.
ack
=
platform
->
driver
->
ops
->
ack
;
rtd
->
ops
.
copy_user
=
platform
->
driver
->
ops
->
copy_user
;
rtd
->
ops
.
copy_kernel
=
platform
->
driver
->
ops
->
copy_kernel
;
...
...
@@ -2758,10 +3112,15 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
if
(
capture
)
snd_pcm_set_ops
(
pcm
,
SNDRV_PCM_STREAM_CAPTURE
,
&
rtd
->
ops
);
if
(
platform
->
driver
->
pcm_new
)
{
ret
=
platform
->
driver
->
pcm_new
(
rtd
);
for_each_rtdcom
(
rtd
,
rtdcom
)
{
component
=
rtdcom
->
component
;
if
(
!
component
->
pcm_new
)
continue
;
ret
=
component
->
pcm_new
(
component
,
rtd
);
if
(
ret
<
0
)
{
dev_err
(
platform
->
dev
,
dev_err
(
component
->
dev
,
"ASoC: pcm constructor failed: %d
\n
"
,
ret
);
return
ret
;
...
...
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