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
b7d023e1
Commit
b7d023e1
authored
Apr 16, 2015
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ALSA: hda - Move PCM format and rate handling code to core library
Signed-off-by:
Takashi Iwai
<
tiwai@suse.de
>
parent
602518a2
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
317 additions
and
322 deletions
+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
No files found.
include/sound/hdaudio.h
View file @
b7d023e1
...
@@ -123,6 +123,15 @@ int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
...
@@ -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
);
hda_nid_t
*
conn_list
,
int
max_conns
);
int
snd_hdac_get_sub_nodes
(
struct
hdac_device
*
codec
,
hda_nid_t
nid
,
int
snd_hdac_get_sub_nodes
(
struct
hdac_device
*
codec
,
hda_nid_t
nid
,
hda_nid_t
*
start_id
);
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
* snd_hdac_read_parm - read a codec parameter
...
...
sound/hda/hdac_device.c
View file @
b7d023e1
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
#include <linux/pm_runtime.h>
#include <linux/pm_runtime.h>
#include <sound/hdaudio.h>
#include <sound/hdaudio.h>
#include <sound/hda_regmap.h>
#include <sound/hda_regmap.h>
#include <sound/pcm.h>
#include "local.h"
#include "local.h"
static
void
setup_fg_nodes
(
struct
hdac_device
*
codec
);
static
void
setup_fg_nodes
(
struct
hdac_device
*
codec
);
...
@@ -597,3 +598,302 @@ static int get_codec_vendor_name(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
);
codec
->
vendor_name
=
kasprintf
(
GFP_KERNEL
,
"Generic %04x"
,
vendor_id
);
return
codec
->
vendor_name
?
0
:
-
ENOMEM
;
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
View file @
b7d023e1
...
@@ -3191,311 +3191,6 @@ int snd_hda_codec_build_controls(struct hda_codec *codec)
...
@@ -3191,311 +3191,6 @@ int snd_hda_codec_build_controls(struct hda_codec *codec)
return
0
;
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
* PCM stuff
*/
*/
...
...
sound/pci/hda/hda_codec.h
View file @
b7d023e1
...
@@ -365,8 +365,6 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
...
@@ -365,8 +365,6 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
hda_nid_t
nid
,
int
recursive
);
hda_nid_t
nid
,
int
recursive
);
int
snd_hda_get_devices
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
int
snd_hda_get_devices
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
u8
*
dev_list
,
int
max_devices
);
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
{
struct
hda_verb
{
hda_nid_t
nid
;
hda_nid_t
nid
;
...
@@ -458,14 +456,11 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, 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
);
int
do_now
);
#define snd_hda_codec_cleanup_stream(codec, nid) \
#define snd_hda_codec_cleanup_stream(codec, nid) \
__snd_hda_codec_cleanup_stream(codec, nid, 0)
__snd_hda_codec_cleanup_stream(codec, nid, 0)
unsigned
int
snd_hda_calc_stream_format
(
struct
hda_codec
*
codec
,
unsigned
int
rate
,
#define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, bpsp) \
unsigned
int
channels
,
snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, bpsp)
unsigned
int
format
,
#define snd_hda_is_supported_format(codec, nid, fmt) \
unsigned
int
maxbps
,
snd_hdac_is_supported_format(&(codec)->core, nid, fmt)
unsigned
short
spdif_ctls
);
int
snd_hda_is_supported_format
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
unsigned
int
format
);
extern
const
struct
snd_pcm_chmap_elem
snd_pcm_2_1_chmaps
[];
extern
const
struct
snd_pcm_chmap_elem
snd_pcm_2_1_chmaps
[];
...
...
sound/pci/hda/hda_controller.c
View file @
b7d023e1
...
@@ -167,8 +167,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
...
@@ -167,8 +167,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
}
}
snd_hdac_stream_reset
(
azx_stream
(
azx_dev
));
snd_hdac_stream_reset
(
azx_stream
(
azx_dev
));
format_val
=
snd_hda_calc_stream_format
(
apcm
->
codec
,
format_val
=
snd_hdac_calc_stream_format
(
runtime
->
rate
,
runtime
->
rate
,
runtime
->
channels
,
runtime
->
channels
,
runtime
->
format
,
runtime
->
format
,
hinfo
->
maxbps
,
hinfo
->
maxbps
,
...
...
sound/pci/hda/patch_ca0132.c
View file @
b7d023e1
...
@@ -2052,11 +2052,8 @@ static int dma_convert_to_hda_format(struct hda_codec *codec,
...
@@ -2052,11 +2052,8 @@ static int dma_convert_to_hda_format(struct hda_codec *codec,
{
{
unsigned
int
format_val
;
unsigned
int
format_val
;
format_val
=
snd_hda_calc_stream_format
(
codec
,
format_val
=
snd_hdac_calc_stream_format
(
sample_rate
,
sample_rate
,
channels
,
SNDRV_PCM_FORMAT_S32_LE
,
32
,
0
);
channels
,
SNDRV_PCM_FORMAT_S32_LE
,
32
,
0
);
if
(
hda_format
)
if
(
hda_format
)
*
hda_format
=
(
unsigned
short
)
format_val
;
*
hda_format
=
(
unsigned
short
)
format_val
;
...
...
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