Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gsplhtlxg
clone-Linux
提交
b7d023e1
C
clone-Linux
项目概览
gsplhtlxg
/
clone-Linux
通知
2
Star
0
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
clone-Linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b7d023e1
编写于
4月 16, 2015
作者:
T
Takashi Iwai
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ALSA: hda - Move PCM format and rate handling code to core library
Signed-off-by:
N
Takashi Iwai
<
tiwai@suse.de
>
上级
602518a2
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
317 addition
and
322 deletion
+317
-322
include/sound/hdaudio.h
include/sound/hdaudio.h
+9
-0
sound/hda/hdac_device.c
sound/hda/hdac_device.c
+300
-0
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.c
+0
-305
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_codec.h
+5
-10
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.c
+1
-2
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_ca0132.c
+2
-5
未找到文件。
include/sound/hdaudio.h
浏览文件 @
b7d023e1
...
...
@@ -123,6 +123,15 @@ int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
hda_nid_t
*
conn_list
,
int
max_conns
);
int
snd_hdac_get_sub_nodes
(
struct
hdac_device
*
codec
,
hda_nid_t
nid
,
hda_nid_t
*
start_id
);
unsigned
int
snd_hdac_calc_stream_format
(
unsigned
int
rate
,
unsigned
int
channels
,
unsigned
int
format
,
unsigned
int
maxbps
,
unsigned
short
spdif_ctls
);
int
snd_hdac_query_supported_pcm
(
struct
hdac_device
*
codec
,
hda_nid_t
nid
,
u32
*
ratesp
,
u64
*
formatsp
,
unsigned
int
*
bpsp
);
bool
snd_hdac_is_supported_format
(
struct
hdac_device
*
codec
,
hda_nid_t
nid
,
unsigned
int
format
);
/**
* snd_hdac_read_parm - read a codec parameter
...
...
sound/hda/hdac_device.c
浏览文件 @
b7d023e1
...
...
@@ -10,6 +10,7 @@
#include <linux/pm_runtime.h>
#include <sound/hdaudio.h>
#include <sound/hda_regmap.h>
#include <sound/pcm.h>
#include "local.h"
static
void
setup_fg_nodes
(
struct
hdac_device
*
codec
);
...
...
@@ -597,3 +598,302 @@ static int get_codec_vendor_name(struct hdac_device *codec)
codec
->
vendor_name
=
kasprintf
(
GFP_KERNEL
,
"Generic %04x"
,
vendor_id
);
return
codec
->
vendor_name
?
0
:
-
ENOMEM
;
}
/*
* stream formats
*/
struct
hda_rate_tbl
{
unsigned
int
hz
;
unsigned
int
alsa_bits
;
unsigned
int
hda_fmt
;
};
/* rate = base * mult / div */
#define HDA_RATE(base, mult, div) \
(AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \
(((div) - 1) << AC_FMT_DIV_SHIFT))
static
struct
hda_rate_tbl
rate_bits
[]
=
{
/* rate in Hz, ALSA rate bitmask, HDA format value */
/* autodetected value used in snd_hda_query_supported_pcm */
{
8000
,
SNDRV_PCM_RATE_8000
,
HDA_RATE
(
48
,
1
,
6
)
},
{
11025
,
SNDRV_PCM_RATE_11025
,
HDA_RATE
(
44
,
1
,
4
)
},
{
16000
,
SNDRV_PCM_RATE_16000
,
HDA_RATE
(
48
,
1
,
3
)
},
{
22050
,
SNDRV_PCM_RATE_22050
,
HDA_RATE
(
44
,
1
,
2
)
},
{
32000
,
SNDRV_PCM_RATE_32000
,
HDA_RATE
(
48
,
2
,
3
)
},
{
44100
,
SNDRV_PCM_RATE_44100
,
HDA_RATE
(
44
,
1
,
1
)
},
{
48000
,
SNDRV_PCM_RATE_48000
,
HDA_RATE
(
48
,
1
,
1
)
},
{
88200
,
SNDRV_PCM_RATE_88200
,
HDA_RATE
(
44
,
2
,
1
)
},
{
96000
,
SNDRV_PCM_RATE_96000
,
HDA_RATE
(
48
,
2
,
1
)
},
{
176400
,
SNDRV_PCM_RATE_176400
,
HDA_RATE
(
44
,
4
,
1
)
},
{
192000
,
SNDRV_PCM_RATE_192000
,
HDA_RATE
(
48
,
4
,
1
)
},
#define AC_PAR_PCM_RATE_BITS 11
/* up to bits 10, 384kHZ isn't supported properly */
/* not autodetected value */
{
9600
,
SNDRV_PCM_RATE_KNOT
,
HDA_RATE
(
48
,
1
,
5
)
},
{
0
}
/* terminator */
};
/**
* snd_hdac_calc_stream_format - calculate the format bitset
* @rate: the sample rate
* @channels: the number of channels
* @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
* @maxbps: the max. bps
* @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant)
*
* Calculate the format bitset from the given rate, channels and th PCM format.
*
* Return zero if invalid.
*/
unsigned
int
snd_hdac_calc_stream_format
(
unsigned
int
rate
,
unsigned
int
channels
,
unsigned
int
format
,
unsigned
int
maxbps
,
unsigned
short
spdif_ctls
)
{
int
i
;
unsigned
int
val
=
0
;
for
(
i
=
0
;
rate_bits
[
i
].
hz
;
i
++
)
if
(
rate_bits
[
i
].
hz
==
rate
)
{
val
=
rate_bits
[
i
].
hda_fmt
;
break
;
}
if
(
!
rate_bits
[
i
].
hz
)
return
0
;
if
(
channels
==
0
||
channels
>
8
)
return
0
;
val
|=
channels
-
1
;
switch
(
snd_pcm_format_width
(
format
))
{
case
8
:
val
|=
AC_FMT_BITS_8
;
break
;
case
16
:
val
|=
AC_FMT_BITS_16
;
break
;
case
20
:
case
24
:
case
32
:
if
(
maxbps
>=
32
||
format
==
SNDRV_PCM_FORMAT_FLOAT_LE
)
val
|=
AC_FMT_BITS_32
;
else
if
(
maxbps
>=
24
)
val
|=
AC_FMT_BITS_24
;
else
val
|=
AC_FMT_BITS_20
;
break
;
default:
return
0
;
}
if
(
spdif_ctls
&
AC_DIG1_NONAUDIO
)
val
|=
AC_FMT_TYPE_NON_PCM
;
return
val
;
}
EXPORT_SYMBOL_GPL
(
snd_hdac_calc_stream_format
);
static
unsigned
int
query_pcm_param
(
struct
hdac_device
*
codec
,
hda_nid_t
nid
)
{
unsigned
int
val
=
0
;
if
(
nid
!=
codec
->
afg
&&
(
get_wcaps
(
codec
,
nid
)
&
AC_WCAP_FORMAT_OVRD
))
val
=
snd_hdac_read_parm
(
codec
,
nid
,
AC_PAR_PCM
);
if
(
!
val
||
val
==
-
1
)
val
=
snd_hdac_read_parm
(
codec
,
codec
->
afg
,
AC_PAR_PCM
);
if
(
!
val
||
val
==
-
1
)
return
0
;
return
val
;
}
static
unsigned
int
query_stream_param
(
struct
hdac_device
*
codec
,
hda_nid_t
nid
)
{
unsigned
int
streams
=
snd_hdac_read_parm
(
codec
,
nid
,
AC_PAR_STREAM
);
if
(
!
streams
||
streams
==
-
1
)
streams
=
snd_hdac_read_parm
(
codec
,
codec
->
afg
,
AC_PAR_STREAM
);
if
(
!
streams
||
streams
==
-
1
)
return
0
;
return
streams
;
}
/**
* snd_hdac_query_supported_pcm - query the supported PCM rates and formats
* @codec: the codec object
* @nid: NID to query
* @ratesp: the pointer to store the detected rate bitflags
* @formatsp: the pointer to store the detected formats
* @bpsp: the pointer to store the detected format widths
*
* Queries the supported PCM rates and formats. The NULL @ratesp, @formatsp
* or @bsps argument is ignored.
*
* Returns 0 if successful, otherwise a negative error code.
*/
int
snd_hdac_query_supported_pcm
(
struct
hdac_device
*
codec
,
hda_nid_t
nid
,
u32
*
ratesp
,
u64
*
formatsp
,
unsigned
int
*
bpsp
)
{
unsigned
int
i
,
val
,
wcaps
;
wcaps
=
get_wcaps
(
codec
,
nid
);
val
=
query_pcm_param
(
codec
,
nid
);
if
(
ratesp
)
{
u32
rates
=
0
;
for
(
i
=
0
;
i
<
AC_PAR_PCM_RATE_BITS
;
i
++
)
{
if
(
val
&
(
1
<<
i
))
rates
|=
rate_bits
[
i
].
alsa_bits
;
}
if
(
rates
==
0
)
{
dev_err
(
&
codec
->
dev
,
"rates == 0 (nid=0x%x, val=0x%x, ovrd=%i)
\n
"
,
nid
,
val
,
(
wcaps
&
AC_WCAP_FORMAT_OVRD
)
?
1
:
0
);
return
-
EIO
;
}
*
ratesp
=
rates
;
}
if
(
formatsp
||
bpsp
)
{
u64
formats
=
0
;
unsigned
int
streams
,
bps
;
streams
=
query_stream_param
(
codec
,
nid
);
if
(
!
streams
)
return
-
EIO
;
bps
=
0
;
if
(
streams
&
AC_SUPFMT_PCM
)
{
if
(
val
&
AC_SUPPCM_BITS_8
)
{
formats
|=
SNDRV_PCM_FMTBIT_U8
;
bps
=
8
;
}
if
(
val
&
AC_SUPPCM_BITS_16
)
{
formats
|=
SNDRV_PCM_FMTBIT_S16_LE
;
bps
=
16
;
}
if
(
wcaps
&
AC_WCAP_DIGITAL
)
{
if
(
val
&
AC_SUPPCM_BITS_32
)
formats
|=
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
;
if
(
val
&
(
AC_SUPPCM_BITS_20
|
AC_SUPPCM_BITS_24
))
formats
|=
SNDRV_PCM_FMTBIT_S32_LE
;
if
(
val
&
AC_SUPPCM_BITS_24
)
bps
=
24
;
else
if
(
val
&
AC_SUPPCM_BITS_20
)
bps
=
20
;
}
else
if
(
val
&
(
AC_SUPPCM_BITS_20
|
AC_SUPPCM_BITS_24
|
AC_SUPPCM_BITS_32
))
{
formats
|=
SNDRV_PCM_FMTBIT_S32_LE
;
if
(
val
&
AC_SUPPCM_BITS_32
)
bps
=
32
;
else
if
(
val
&
AC_SUPPCM_BITS_24
)
bps
=
24
;
else
if
(
val
&
AC_SUPPCM_BITS_20
)
bps
=
20
;
}
}
#if 0 /* FIXME: CS4206 doesn't work, which is the only codec supporting float */
if (streams & AC_SUPFMT_FLOAT32) {
formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
if (!bps)
bps = 32;
}
#endif
if
(
streams
==
AC_SUPFMT_AC3
)
{
/* should be exclusive */
/* temporary hack: we have still no proper support
* for the direct AC3 stream...
*/
formats
|=
SNDRV_PCM_FMTBIT_U8
;
bps
=
8
;
}
if
(
formats
==
0
)
{
dev_err
(
&
codec
->
dev
,
"formats == 0 (nid=0x%x, val=0x%x, ovrd=%i, streams=0x%x)
\n
"
,
nid
,
val
,
(
wcaps
&
AC_WCAP_FORMAT_OVRD
)
?
1
:
0
,
streams
);
return
-
EIO
;
}
if
(
formatsp
)
*
formatsp
=
formats
;
if
(
bpsp
)
*
bpsp
=
bps
;
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_hdac_query_supported_pcm
);
/**
* snd_hdac_is_supported_format - Check the validity of the format
* @codec: the codec object
* @nid: NID to check
* @format: the HD-audio format value to check
*
* Check whether the given node supports the format value.
*
* Returns true if supported, false if not.
*/
bool
snd_hdac_is_supported_format
(
struct
hdac_device
*
codec
,
hda_nid_t
nid
,
unsigned
int
format
)
{
int
i
;
unsigned
int
val
=
0
,
rate
,
stream
;
val
=
query_pcm_param
(
codec
,
nid
);
if
(
!
val
)
return
false
;
rate
=
format
&
0xff00
;
for
(
i
=
0
;
i
<
AC_PAR_PCM_RATE_BITS
;
i
++
)
if
(
rate_bits
[
i
].
hda_fmt
==
rate
)
{
if
(
val
&
(
1
<<
i
))
break
;
return
false
;
}
if
(
i
>=
AC_PAR_PCM_RATE_BITS
)
return
false
;
stream
=
query_stream_param
(
codec
,
nid
);
if
(
!
stream
)
return
false
;
if
(
stream
&
AC_SUPFMT_PCM
)
{
switch
(
format
&
0xf0
)
{
case
0x00
:
if
(
!
(
val
&
AC_SUPPCM_BITS_8
))
return
false
;
break
;
case
0x10
:
if
(
!
(
val
&
AC_SUPPCM_BITS_16
))
return
false
;
break
;
case
0x20
:
if
(
!
(
val
&
AC_SUPPCM_BITS_20
))
return
false
;
break
;
case
0x30
:
if
(
!
(
val
&
AC_SUPPCM_BITS_24
))
return
false
;
break
;
case
0x40
:
if
(
!
(
val
&
AC_SUPPCM_BITS_32
))
return
false
;
break
;
default:
return
false
;
}
}
else
{
/* FIXME: check for float32 and AC3? */
}
return
true
;
}
EXPORT_SYMBOL_GPL
(
snd_hdac_is_supported_format
);
sound/pci/hda/hda_codec.c
浏览文件 @
b7d023e1
...
...
@@ -3191,311 +3191,6 @@ int snd_hda_codec_build_controls(struct hda_codec *codec)
return
0
;
}
/*
* stream formats
*/
struct
hda_rate_tbl
{
unsigned
int
hz
;
unsigned
int
alsa_bits
;
unsigned
int
hda_fmt
;
};
/* rate = base * mult / div */
#define HDA_RATE(base, mult, div) \
(AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \
(((div) - 1) << AC_FMT_DIV_SHIFT))
static
struct
hda_rate_tbl
rate_bits
[]
=
{
/* rate in Hz, ALSA rate bitmask, HDA format value */
/* autodetected value used in snd_hda_query_supported_pcm */
{
8000
,
SNDRV_PCM_RATE_8000
,
HDA_RATE
(
48
,
1
,
6
)
},
{
11025
,
SNDRV_PCM_RATE_11025
,
HDA_RATE
(
44
,
1
,
4
)
},
{
16000
,
SNDRV_PCM_RATE_16000
,
HDA_RATE
(
48
,
1
,
3
)
},
{
22050
,
SNDRV_PCM_RATE_22050
,
HDA_RATE
(
44
,
1
,
2
)
},
{
32000
,
SNDRV_PCM_RATE_32000
,
HDA_RATE
(
48
,
2
,
3
)
},
{
44100
,
SNDRV_PCM_RATE_44100
,
HDA_RATE
(
44
,
1
,
1
)
},
{
48000
,
SNDRV_PCM_RATE_48000
,
HDA_RATE
(
48
,
1
,
1
)
},
{
88200
,
SNDRV_PCM_RATE_88200
,
HDA_RATE
(
44
,
2
,
1
)
},
{
96000
,
SNDRV_PCM_RATE_96000
,
HDA_RATE
(
48
,
2
,
1
)
},
{
176400
,
SNDRV_PCM_RATE_176400
,
HDA_RATE
(
44
,
4
,
1
)
},
{
192000
,
SNDRV_PCM_RATE_192000
,
HDA_RATE
(
48
,
4
,
1
)
},
#define AC_PAR_PCM_RATE_BITS 11
/* up to bits 10, 384kHZ isn't supported properly */
/* not autodetected value */
{
9600
,
SNDRV_PCM_RATE_KNOT
,
HDA_RATE
(
48
,
1
,
5
)
},
{
0
}
/* terminator */
};
/**
* snd_hda_calc_stream_format - calculate format bitset
* @codec: HD-audio codec
* @rate: the sample rate
* @channels: the number of channels
* @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
* @maxbps: the max. bps
* @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant)
*
* Calculate the format bitset from the given rate, channels and th PCM format.
*
* Return zero if invalid.
*/
unsigned
int
snd_hda_calc_stream_format
(
struct
hda_codec
*
codec
,
unsigned
int
rate
,
unsigned
int
channels
,
unsigned
int
format
,
unsigned
int
maxbps
,
unsigned
short
spdif_ctls
)
{
int
i
;
unsigned
int
val
=
0
;
for
(
i
=
0
;
rate_bits
[
i
].
hz
;
i
++
)
if
(
rate_bits
[
i
].
hz
==
rate
)
{
val
=
rate_bits
[
i
].
hda_fmt
;
break
;
}
if
(
!
rate_bits
[
i
].
hz
)
{
codec_dbg
(
codec
,
"invalid rate %d
\n
"
,
rate
);
return
0
;
}
if
(
channels
==
0
||
channels
>
8
)
{
codec_dbg
(
codec
,
"invalid channels %d
\n
"
,
channels
);
return
0
;
}
val
|=
channels
-
1
;
switch
(
snd_pcm_format_width
(
format
))
{
case
8
:
val
|=
AC_FMT_BITS_8
;
break
;
case
16
:
val
|=
AC_FMT_BITS_16
;
break
;
case
20
:
case
24
:
case
32
:
if
(
maxbps
>=
32
||
format
==
SNDRV_PCM_FORMAT_FLOAT_LE
)
val
|=
AC_FMT_BITS_32
;
else
if
(
maxbps
>=
24
)
val
|=
AC_FMT_BITS_24
;
else
val
|=
AC_FMT_BITS_20
;
break
;
default:
codec_dbg
(
codec
,
"invalid format width %d
\n
"
,
snd_pcm_format_width
(
format
));
return
0
;
}
if
(
spdif_ctls
&
AC_DIG1_NONAUDIO
)
val
|=
AC_FMT_TYPE_NON_PCM
;
return
val
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_calc_stream_format
);
static
unsigned
int
query_pcm_param
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
)
{
unsigned
int
val
=
0
;
if
(
nid
!=
codec
->
core
.
afg
&&
(
get_wcaps
(
codec
,
nid
)
&
AC_WCAP_FORMAT_OVRD
))
val
=
snd_hda_param_read
(
codec
,
nid
,
AC_PAR_PCM
);
if
(
!
val
||
val
==
-
1
)
val
=
snd_hda_param_read
(
codec
,
codec
->
core
.
afg
,
AC_PAR_PCM
);
if
(
!
val
||
val
==
-
1
)
return
0
;
return
val
;
}
static
unsigned
int
query_stream_param
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
)
{
unsigned
int
streams
=
snd_hda_param_read
(
codec
,
nid
,
AC_PAR_STREAM
);
if
(
!
streams
||
streams
==
-
1
)
streams
=
snd_hda_param_read
(
codec
,
codec
->
core
.
afg
,
AC_PAR_STREAM
);
if
(
!
streams
||
streams
==
-
1
)
return
0
;
return
streams
;
}
/**
* snd_hda_query_supported_pcm - query the supported PCM rates and formats
* @codec: the HDA codec
* @nid: NID to query
* @ratesp: the pointer to store the detected rate bitflags
* @formatsp: the pointer to store the detected formats
* @bpsp: the pointer to store the detected format widths
*
* Queries the supported PCM rates and formats. The NULL @ratesp, @formatsp
* or @bsps argument is ignored.
*
* Returns 0 if successful, otherwise a negative error code.
*/
int
snd_hda_query_supported_pcm
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
u32
*
ratesp
,
u64
*
formatsp
,
unsigned
int
*
bpsp
)
{
unsigned
int
i
,
val
,
wcaps
;
wcaps
=
get_wcaps
(
codec
,
nid
);
val
=
query_pcm_param
(
codec
,
nid
);
if
(
ratesp
)
{
u32
rates
=
0
;
for
(
i
=
0
;
i
<
AC_PAR_PCM_RATE_BITS
;
i
++
)
{
if
(
val
&
(
1
<<
i
))
rates
|=
rate_bits
[
i
].
alsa_bits
;
}
if
(
rates
==
0
)
{
codec_err
(
codec
,
"rates == 0 (nid=0x%x, val=0x%x, ovrd=%i)
\n
"
,
nid
,
val
,
(
wcaps
&
AC_WCAP_FORMAT_OVRD
)
?
1
:
0
);
return
-
EIO
;
}
*
ratesp
=
rates
;
}
if
(
formatsp
||
bpsp
)
{
u64
formats
=
0
;
unsigned
int
streams
,
bps
;
streams
=
query_stream_param
(
codec
,
nid
);
if
(
!
streams
)
return
-
EIO
;
bps
=
0
;
if
(
streams
&
AC_SUPFMT_PCM
)
{
if
(
val
&
AC_SUPPCM_BITS_8
)
{
formats
|=
SNDRV_PCM_FMTBIT_U8
;
bps
=
8
;
}
if
(
val
&
AC_SUPPCM_BITS_16
)
{
formats
|=
SNDRV_PCM_FMTBIT_S16_LE
;
bps
=
16
;
}
if
(
wcaps
&
AC_WCAP_DIGITAL
)
{
if
(
val
&
AC_SUPPCM_BITS_32
)
formats
|=
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
;
if
(
val
&
(
AC_SUPPCM_BITS_20
|
AC_SUPPCM_BITS_24
))
formats
|=
SNDRV_PCM_FMTBIT_S32_LE
;
if
(
val
&
AC_SUPPCM_BITS_24
)
bps
=
24
;
else
if
(
val
&
AC_SUPPCM_BITS_20
)
bps
=
20
;
}
else
if
(
val
&
(
AC_SUPPCM_BITS_20
|
AC_SUPPCM_BITS_24
|
AC_SUPPCM_BITS_32
))
{
formats
|=
SNDRV_PCM_FMTBIT_S32_LE
;
if
(
val
&
AC_SUPPCM_BITS_32
)
bps
=
32
;
else
if
(
val
&
AC_SUPPCM_BITS_24
)
bps
=
24
;
else
if
(
val
&
AC_SUPPCM_BITS_20
)
bps
=
20
;
}
}
#if 0 /* FIXME: CS4206 doesn't work, which is the only codec supporting float */
if (streams & AC_SUPFMT_FLOAT32) {
formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
if (!bps)
bps = 32;
}
#endif
if
(
streams
==
AC_SUPFMT_AC3
)
{
/* should be exclusive */
/* temporary hack: we have still no proper support
* for the direct AC3 stream...
*/
formats
|=
SNDRV_PCM_FMTBIT_U8
;
bps
=
8
;
}
if
(
formats
==
0
)
{
codec_err
(
codec
,
"formats == 0 (nid=0x%x, val=0x%x, ovrd=%i, streams=0x%x)
\n
"
,
nid
,
val
,
(
wcaps
&
AC_WCAP_FORMAT_OVRD
)
?
1
:
0
,
streams
);
return
-
EIO
;
}
if
(
formatsp
)
*
formatsp
=
formats
;
if
(
bpsp
)
*
bpsp
=
bps
;
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_query_supported_pcm
);
/**
* snd_hda_is_supported_format - Check the validity of the format
* @codec: HD-audio codec
* @nid: NID to check
* @format: the HD-audio format value to check
*
* Check whether the given node supports the format value.
*
* Returns 1 if supported, 0 if not.
*/
int
snd_hda_is_supported_format
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
unsigned
int
format
)
{
int
i
;
unsigned
int
val
=
0
,
rate
,
stream
;
val
=
query_pcm_param
(
codec
,
nid
);
if
(
!
val
)
return
0
;
rate
=
format
&
0xff00
;
for
(
i
=
0
;
i
<
AC_PAR_PCM_RATE_BITS
;
i
++
)
if
(
rate_bits
[
i
].
hda_fmt
==
rate
)
{
if
(
val
&
(
1
<<
i
))
break
;
return
0
;
}
if
(
i
>=
AC_PAR_PCM_RATE_BITS
)
return
0
;
stream
=
query_stream_param
(
codec
,
nid
);
if
(
!
stream
)
return
0
;
if
(
stream
&
AC_SUPFMT_PCM
)
{
switch
(
format
&
0xf0
)
{
case
0x00
:
if
(
!
(
val
&
AC_SUPPCM_BITS_8
))
return
0
;
break
;
case
0x10
:
if
(
!
(
val
&
AC_SUPPCM_BITS_16
))
return
0
;
break
;
case
0x20
:
if
(
!
(
val
&
AC_SUPPCM_BITS_20
))
return
0
;
break
;
case
0x30
:
if
(
!
(
val
&
AC_SUPPCM_BITS_24
))
return
0
;
break
;
case
0x40
:
if
(
!
(
val
&
AC_SUPPCM_BITS_32
))
return
0
;
break
;
default:
return
0
;
}
}
else
{
/* FIXME: check for float32 and AC3? */
}
return
1
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_is_supported_format
);
/*
* PCM stuff
*/
...
...
sound/pci/hda/hda_codec.h
浏览文件 @
b7d023e1
...
...
@@ -365,8 +365,6 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
hda_nid_t
nid
,
int
recursive
);
int
snd_hda_get_devices
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
u8
*
dev_list
,
int
max_devices
);
int
snd_hda_query_supported_pcm
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
u32
*
ratesp
,
u64
*
formatsp
,
unsigned
int
*
bpsp
);
struct
hda_verb
{
hda_nid_t
nid
;
...
...
@@ -458,14 +456,11 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
int
do_now
);
#define snd_hda_codec_cleanup_stream(codec, nid) \
__snd_hda_codec_cleanup_stream(codec, nid, 0)
unsigned
int
snd_hda_calc_stream_format
(
struct
hda_codec
*
codec
,
unsigned
int
rate
,
unsigned
int
channels
,
unsigned
int
format
,
unsigned
int
maxbps
,
unsigned
short
spdif_ctls
);
int
snd_hda_is_supported_format
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
unsigned
int
format
);
#define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, bpsp) \
snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, bpsp)
#define snd_hda_is_supported_format(codec, nid, fmt) \
snd_hdac_is_supported_format(&(codec)->core, nid, fmt)
extern
const
struct
snd_pcm_chmap_elem
snd_pcm_2_1_chmaps
[];
...
...
sound/pci/hda/hda_controller.c
浏览文件 @
b7d023e1
...
...
@@ -167,8 +167,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
}
snd_hdac_stream_reset
(
azx_stream
(
azx_dev
));
format_val
=
snd_hda_calc_stream_format
(
apcm
->
codec
,
runtime
->
rate
,
format_val
=
snd_hdac_calc_stream_format
(
runtime
->
rate
,
runtime
->
channels
,
runtime
->
format
,
hinfo
->
maxbps
,
...
...
sound/pci/hda/patch_ca0132.c
浏览文件 @
b7d023e1
...
...
@@ -2052,11 +2052,8 @@ static int dma_convert_to_hda_format(struct hda_codec *codec,
{
unsigned
int
format_val
;
format_val
=
snd_hda_calc_stream_format
(
codec
,
sample_rate
,
channels
,
SNDRV_PCM_FORMAT_S32_LE
,
32
,
0
);
format_val
=
snd_hdac_calc_stream_format
(
sample_rate
,
channels
,
SNDRV_PCM_FORMAT_S32_LE
,
32
,
0
);
if
(
hda_format
)
*
hda_format
=
(
unsigned
short
)
format_val
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录