Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
e73462f5
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
e73462f5
编写于
12月 03, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/symmetry' into asoc-fsl
上级
2924a998
62e5f676
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
138 addition
and
28 deletion
+138
-28
include/sound/soc-dai.h
include/sound/soc-dai.h
+6
-0
include/sound/soc.h
include/sound/soc.h
+2
-0
sound/soc/soc-pcm.c
sound/soc/soc-pcm.c
+130
-28
未找到文件。
include/sound/soc-dai.h
浏览文件 @
e73462f5
...
...
@@ -220,6 +220,8 @@ struct snd_soc_dai_driver {
struct
snd_soc_pcm_stream
capture
;
struct
snd_soc_pcm_stream
playback
;
unsigned
int
symmetric_rates
:
1
;
unsigned
int
symmetric_channels
:
1
;
unsigned
int
symmetric_samplebits
:
1
;
/* probe ordering - for components with runtime dependencies */
int
probe_order
;
...
...
@@ -244,6 +246,8 @@ struct snd_soc_dai {
unsigned
int
capture_active
:
1
;
/* stream is in use */
unsigned
int
playback_active
:
1
;
/* stream is in use */
unsigned
int
symmetric_rates
:
1
;
unsigned
int
symmetric_channels
:
1
;
unsigned
int
symmetric_samplebits
:
1
;
struct
snd_pcm_runtime
*
runtime
;
unsigned
int
active
;
unsigned
char
probed
:
1
;
...
...
@@ -258,6 +262,8 @@ struct snd_soc_dai {
/* Symmetry data - only valid if symmetry is being enforced */
unsigned
int
rate
;
unsigned
int
channels
;
unsigned
int
sample_bits
;
/* parent platform/codec */
struct
snd_soc_platform
*
platform
;
...
...
include/sound/soc.h
浏览文件 @
e73462f5
...
...
@@ -879,6 +879,8 @@ struct snd_soc_dai_link {
/* Symmetry requirements */
unsigned
int
symmetric_rates
:
1
;
unsigned
int
symmetric_channels
:
1
;
unsigned
int
symmetric_samplebits
:
1
;
/* Do not create a PCM for this DAI link (Backend link) */
unsigned
int
no_pcm
:
1
;
...
...
sound/soc/soc-pcm.c
浏览文件 @
e73462f5
...
...
@@ -84,35 +84,117 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
int
ret
;
if
(
!
soc_dai
->
driver
->
symmetric_rates
&&
!
rtd
->
dai_link
->
symmetric_rates
)
return
0
;
if
(
soc_dai
->
rate
&&
(
soc_dai
->
driver
->
symmetric_rates
||
rtd
->
dai_link
->
symmetric_rates
))
{
dev_dbg
(
soc_dai
->
dev
,
"ASoC: Symmetry forces %dHz rate
\n
"
,
soc_dai
->
rate
);
ret
=
snd_pcm_hw_constraint_minmax
(
substream
->
runtime
,
SNDRV_PCM_HW_PARAM_RATE
,
soc_dai
->
rate
,
soc_dai
->
rate
);
if
(
ret
<
0
)
{
dev_err
(
soc_dai
->
dev
,
"ASoC: Unable to apply rate constraint: %d
\n
"
,
ret
);
return
ret
;
}
}
/* This can happen if multiple streams are starting simultaneously -
* the second can need to get its constraints before the first has
* picked a rate. Complain and allow the application to carry on.
*/
if
(
!
soc_dai
->
rate
)
{
dev_warn
(
soc_dai
->
dev
,
"ASoC: Not enforcing symmetric_rates due to race
\n
"
);
return
0
;
if
(
soc_dai
->
channels
&&
(
soc_dai
->
driver
->
symmetric_channels
||
rtd
->
dai_link
->
symmetric_channels
))
{
dev_dbg
(
soc_dai
->
dev
,
"ASoC: Symmetry forces %d channel(s)
\n
"
,
soc_dai
->
channels
);
ret
=
snd_pcm_hw_constraint_minmax
(
substream
->
runtime
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
soc_dai
->
channels
,
soc_dai
->
channels
);
if
(
ret
<
0
)
{
dev_err
(
soc_dai
->
dev
,
"ASoC: Unable to apply channel symmetry constraint: %d
\n
"
,
ret
);
return
ret
;
}
}
dev_dbg
(
soc_dai
->
dev
,
"ASoC: Symmetry forces %dHz rate
\n
"
,
soc_dai
->
rate
);
if
(
soc_dai
->
sample_bits
&&
(
soc_dai
->
driver
->
symmetric_samplebits
||
rtd
->
dai_link
->
symmetric_samplebits
))
{
dev_dbg
(
soc_dai
->
dev
,
"ASoC: Symmetry forces %d sample bits
\n
"
,
soc_dai
->
sample_bits
);
ret
=
snd_pcm_hw_constraint_minmax
(
substream
->
runtime
,
SNDRV_PCM_HW_PARAM_RATE
,
soc_dai
->
rate
,
soc_dai
->
rate
);
if
(
ret
<
0
)
{
dev_err
(
soc_dai
->
dev
,
"ASoC: Unable to apply rate symmetry constraint: %d
\n
"
,
ret
);
return
ret
;
ret
=
snd_pcm_hw_constraint_minmax
(
substream
->
runtime
,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS
,
soc_dai
->
sample_bits
,
soc_dai
->
sample_bits
);
if
(
ret
<
0
)
{
dev_err
(
soc_dai
->
dev
,
"ASoC: Unable to apply sample bits symmetry constraint: %d
\n
"
,
ret
);
return
ret
;
}
}
return
0
;
}
static
int
soc_pcm_params_symmetry
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
unsigned
int
rate
,
channels
,
sample_bits
,
symmetry
;
rate
=
params_rate
(
params
);
channels
=
params_channels
(
params
);
sample_bits
=
snd_pcm_format_physical_width
(
params_format
(
params
));
/* reject unmatched parameters when applying symmetry */
symmetry
=
cpu_dai
->
driver
->
symmetric_rates
||
codec_dai
->
driver
->
symmetric_rates
||
rtd
->
dai_link
->
symmetric_rates
;
if
(
symmetry
&&
cpu_dai
->
rate
&&
cpu_dai
->
rate
!=
rate
)
{
dev_err
(
rtd
->
dev
,
"ASoC: unmatched rate symmetry: %d - %d
\n
"
,
cpu_dai
->
rate
,
rate
);
return
-
EINVAL
;
}
symmetry
=
cpu_dai
->
driver
->
symmetric_channels
||
codec_dai
->
driver
->
symmetric_channels
||
rtd
->
dai_link
->
symmetric_channels
;
if
(
symmetry
&&
cpu_dai
->
channels
&&
cpu_dai
->
channels
!=
channels
)
{
dev_err
(
rtd
->
dev
,
"ASoC: unmatched channel symmetry: %d - %d
\n
"
,
cpu_dai
->
channels
,
channels
);
return
-
EINVAL
;
}
symmetry
=
cpu_dai
->
driver
->
symmetric_samplebits
||
codec_dai
->
driver
->
symmetric_samplebits
||
rtd
->
dai_link
->
symmetric_samplebits
;
if
(
symmetry
&&
cpu_dai
->
sample_bits
&&
cpu_dai
->
sample_bits
!=
sample_bits
)
{
dev_err
(
rtd
->
dev
,
"ASoC: unmatched sample bits symmetry: %d - %d
\n
"
,
cpu_dai
->
sample_bits
,
sample_bits
);
return
-
EINVAL
;
}
return
0
;
}
static
bool
soc_pcm_has_symmetry
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai_driver
*
cpu_driver
=
rtd
->
cpu_dai
->
driver
;
struct
snd_soc_dai_driver
*
codec_driver
=
rtd
->
codec_dai
->
driver
;
struct
snd_soc_dai_link
*
link
=
rtd
->
dai_link
;
return
cpu_driver
->
symmetric_rates
||
codec_driver
->
symmetric_rates
||
link
->
symmetric_rates
||
cpu_driver
->
symmetric_channels
||
codec_driver
->
symmetric_channels
||
link
->
symmetric_channels
||
cpu_driver
->
symmetric_samplebits
||
codec_driver
->
symmetric_samplebits
||
link
->
symmetric_samplebits
;
}
/*
* List of sample sizes that might go over the bus for parameter
* application. There ought to be a wildcard sample size for things
...
...
@@ -242,6 +324,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
&
cpu_dai_drv
->
capture
);
}
if
(
soc_pcm_has_symmetry
(
substream
))
runtime
->
hw
.
info
|=
SNDRV_PCM_INFO_JOINT_DUPLEX
;
ret
=
-
EINVAL
;
snd_pcm_limit_hw_rates
(
runtime
);
if
(
!
runtime
->
hw
.
rates
)
{
...
...
@@ -383,13 +468,6 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
codec_dai
->
active
--
;
codec
->
active
--
;
/* clear the corresponding DAIs rate when inactive */
if
(
!
cpu_dai
->
active
)
cpu_dai
->
rate
=
0
;
if
(
!
codec_dai
->
active
)
codec_dai
->
rate
=
0
;
/* Muting the DAC suppresses artifacts caused during digital
* shutdown, for example from stopping clocks.
*/
...
...
@@ -525,6 +603,10 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
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
)
{
ret
=
rtd
->
dai_link
->
ops
->
hw_params
(
substream
,
params
);
if
(
ret
<
0
)
{
...
...
@@ -561,9 +643,16 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
}
}
/* store the
rate
for each DAIs */
/* 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
));
codec_dai
->
rate
=
params_rate
(
params
);
codec_dai
->
channels
=
params_channels
(
params
);
codec_dai
->
sample_bits
=
snd_pcm_format_physical_width
(
params_format
(
params
));
out:
mutex_unlock
(
&
rtd
->
pcm_mutex
);
...
...
@@ -598,6 +687,19 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
/* clear the corresponding DAIs parameters when going to be inactive */
if
(
cpu_dai
->
active
==
1
)
{
cpu_dai
->
rate
=
0
;
cpu_dai
->
channels
=
0
;
cpu_dai
->
sample_bits
=
0
;
}
if
(
codec_dai
->
active
==
1
)
{
codec_dai
->
rate
=
0
;
codec_dai
->
channels
=
0
;
codec_dai
->
sample_bits
=
0
;
}
/* apply codec digital mute */
if
(
!
codec
->
active
)
snd_soc_dai_digital_mute
(
codec_dai
,
1
,
substream
->
stream
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录