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
Kirill Smelkov
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