Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
bug2833
cloud-kernel
提交
506ecbca
cloud-kernel
项目概览
bug2833
/
cloud-kernel
与 Fork 源项目一致
Fork自
openanolis / cloud-kernel
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
506ecbca
编写于
10月 25, 2010
作者:
T
Takashi Iwai
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/hda' into for-linus
上级
aa5c14d5
0e7adbe2
变更
21
展开全部
隐藏空白更改
内联
并排
Showing
21 changed file
with
2837 addition
and
2239 deletion
+2837
-2239
Documentation/sound/alsa/HD-Audio.txt
Documentation/sound/alsa/HD-Audio.txt
+5
-3
include/sound/tlv.h
include/sound/tlv.h
+3
-1
sound/pci/hda/Kconfig
sound/pci/hda/Kconfig
+6
-33
sound/pci/hda/Makefile
sound/pci/hda/Makefile
+3
-12
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.c
+216
-55
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_codec.h
+13
-0
sound/pci/hda/hda_eld.c
sound/pci/hda/hda_eld.c
+0
-7
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.c
+5
-36
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.c
+53
-48
sound/pci/hda/hda_local.h
sound/pci/hda/hda_local.h
+40
-11
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_analog.c
+28
-20
sound/pci/hda/patch_atihdmi.c
sound/pci/hda/patch_atihdmi.c
+0
-224
sound/pci/hda/patch_ca0110.c
sound/pci/hda/patch_ca0110.c
+5
-5
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_cirrus.c
+70
-24
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_conexant.c
+642
-9
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_hdmi.c
+756
-41
sound/pci/hda/patch_intelhdmi.c
sound/pci/hda/patch_intelhdmi.c
+0
-220
sound/pci/hda/patch_nvhdmi.c
sound/pci/hda/patch_nvhdmi.c
+0
-608
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_realtek.c
+648
-260
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_sigmatel.c
+192
-187
sound/pci/hda/patch_via.c
sound/pci/hda/patch_via.c
+152
-435
未找到文件。
Documentation/sound/alsa/HD-Audio.txt
浏览文件 @
506ecbca
...
...
@@ -57,9 +57,11 @@ dead. However, this detection isn't perfect on some devices. In such
a case, you can change the default method via `position_fix` option.
`position_fix=1` means to use LPIB method explicitly.
`position_fix=2` means to use the position-buffer. 0 is the default
value, the automatic check and fallback to LPIB as described in the
above. If you get a problem of repeated sounds, this option might
`position_fix=2` means to use the position-buffer.
`position_fix=3` means to use a combination of both methods, needed
for some VIA and ATI controllers. 0 is the default value for all other
controllers, the automatic check and fallback to LPIB as described in
the above. If you get a problem of repeated sounds, this option might
help.
In addition to that, every controller is known to be broken regarding
...
...
include/sound/tlv.h
浏览文件 @
506ecbca
...
...
@@ -38,9 +38,11 @@
#define SNDRV_CTL_TLVT_DB_MINMAX 4
/* dB scale with min/max */
#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5
/* dB scale with min/max with mute */
#define TLV_DB_SCALE_MASK 0xffff
#define TLV_DB_SCALE_MUTE 0x10000
#define TLV_DB_SCALE_ITEM(min, step, mute) \
SNDRV_CTL_TLVT_DB_SCALE, 2 * sizeof(unsigned int), \
(min), ((step) &
0xffff) | ((mute) ? 0x10000
: 0)
(min), ((step) &
TLV_DB_SCALE_MASK) | ((mute) ? TLV_DB_SCALE_MUTE
: 0)
#define DECLARE_TLV_DB_SCALE(name, min, step, mute) \
unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) }
...
...
sound/pci/hda/Kconfig
浏览文件 @
506ecbca
...
...
@@ -119,47 +119,20 @@ config SND_HDA_CODEC_VIA
snd-hda-codec-via.
This module is automatically loaded at probing.
config SND_HDA_CODEC_ATIHDMI
bool "Build ATI HDMI HD-audio codec support"
default y
help
Say Y here to include ATI HDMI HD-audio codec support in
snd-hda-intel driver, such as ATI RS600 HDMI.
When the HD-audio driver is built as a module, the codec
support code is also built as another module,
snd-hda-codec-atihdmi.
This module is automatically loaded at probing.
config SND_HDA_CODEC_NVHDMI
bool "Build NVIDIA HDMI HD-audio codec support"
default y
help
Say Y here to include NVIDIA HDMI HD-audio codec support in
snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
When the HD-audio driver is built as a module, the codec
support code is also built as another module,
snd-hda-codec-nvhdmi.
This module is automatically loaded at probing.
config SND_HDA_CODEC_INTELHDMI
bool "Build INTEL HDMI HD-audio codec support"
config SND_HDA_CODEC_HDMI
bool "Build HDMI/DisplayPort HD-audio codec support"
select SND_DYNAMIC_MINORS
default y
help
Say Y here to include INTEL HDMI HD-audio codec support in
snd-hda-intel driver, such as Eaglelake integrated HDMI.
Say Y here to include HDMI and DisplayPort HD-audio codec
support in snd-hda-intel driver. This includes all AMD/ATI,
Intel and Nvidia HDMI/DisplayPort codecs.
When the HD-audio driver is built as a module, the codec
support code is also built as another module,
snd-hda-codec-
intel
hdmi.
snd-hda-codec-hdmi.
This module is automatically loaded at probing.
config SND_HDA_ELD
def_bool y
depends on SND_HDA_CODEC_INTELHDMI || SND_HDA_CODEC_NVHDMI
config SND_HDA_CODEC_CIRRUS
bool "Build Cirrus Logic codec support"
depends on SND_HDA_INTEL
...
...
sound/pci/hda/Makefile
浏览文件 @
506ecbca
...
...
@@ -3,7 +3,6 @@ snd-hda-intel-objs := hda_intel.o
snd-hda-codec-y
:=
hda_codec.o
snd-hda-codec-$(CONFIG_SND_HDA_GENERIC)
+=
hda_generic.o
snd-hda-codec-$(CONFIG_PROC_FS)
+=
hda_proc.o
snd-hda-codec-$(CONFIG_SND_HDA_ELD)
+=
hda_eld.o
snd-hda-codec-$(CONFIG_SND_HDA_HWDEP)
+=
hda_hwdep.o
snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP)
+=
hda_beep.o
...
...
@@ -12,13 +11,11 @@ snd-hda-codec-cmedia-objs := patch_cmedia.o
snd-hda-codec-analog-objs
:=
patch_analog.o
snd-hda-codec-idt-objs
:=
patch_sigmatel.o
snd-hda-codec-si3054-objs
:=
patch_si3054.o
snd-hda-codec-atihdmi-objs
:=
patch_atihdmi.o
snd-hda-codec-cirrus-objs
:=
patch_cirrus.o
snd-hda-codec-ca0110-objs
:=
patch_ca0110.o
snd-hda-codec-conexant-objs
:=
patch_conexant.o
snd-hda-codec-via-objs
:=
patch_via.o
snd-hda-codec-nvhdmi-objs
:=
patch_nvhdmi.o
snd-hda-codec-intelhdmi-objs
:=
patch_intelhdmi.o
snd-hda-codec-hdmi-objs
:=
patch_hdmi.o hda_eld.o
# common driver
obj-$(CONFIG_SND_HDA_INTEL)
:=
snd-hda-codec.o
...
...
@@ -39,9 +36,6 @@ endif
ifdef
CONFIG_SND_HDA_CODEC_SI3054
obj-$(CONFIG_SND_HDA_INTEL)
+=
snd-hda-codec-si3054.o
endif
ifdef
CONFIG_SND_HDA_CODEC_ATIHDMI
obj-$(CONFIG_SND_HDA_INTEL)
+=
snd-hda-codec-atihdmi.o
endif
ifdef
CONFIG_SND_HDA_CODEC_CIRRUS
obj-$(CONFIG_SND_HDA_INTEL)
+=
snd-hda-codec-cirrus.o
endif
...
...
@@ -54,11 +48,8 @@ endif
ifdef
CONFIG_SND_HDA_CODEC_VIA
obj-$(CONFIG_SND_HDA_INTEL)
+=
snd-hda-codec-via.o
endif
ifdef
CONFIG_SND_HDA_CODEC_NVHDMI
obj-$(CONFIG_SND_HDA_INTEL)
+=
snd-hda-codec-nvhdmi.o
endif
ifdef
CONFIG_SND_HDA_CODEC_INTELHDMI
obj-$(CONFIG_SND_HDA_INTEL)
+=
snd-hda-codec-intelhdmi.o
ifdef
CONFIG_SND_HDA_CODEC_HDMI
obj-$(CONFIG_SND_HDA_INTEL)
+=
snd-hda-codec-hdmi.o
endif
# this must be the last entry after codec drivers;
...
...
sound/pci/hda/hda_codec.c
浏览文件 @
506ecbca
...
...
@@ -1216,6 +1216,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
struct
hda_codec
*
c
;
struct
hda_cvt_setup
*
p
;
unsigned
int
oldval
,
newval
;
int
type
;
int
i
;
if
(
!
nid
)
...
...
@@ -1254,10 +1255,12 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
p
->
dirty
=
0
;
/* make other inactive cvts with the same stream-tag dirty */
type
=
get_wcaps_type
(
get_wcaps
(
codec
,
nid
));
list_for_each_entry
(
c
,
&
codec
->
bus
->
codec_list
,
list
)
{
for
(
i
=
0
;
i
<
c
->
cvt_setups
.
used
;
i
++
)
{
p
=
snd_array_elem
(
&
c
->
cvt_setups
,
i
);
if
(
!
p
->
active
&&
p
->
stream_tag
==
stream_tag
)
if
(
!
p
->
active
&&
p
->
stream_tag
==
stream_tag
&&
get_wcaps_type
(
get_wcaps
(
codec
,
p
->
nid
))
==
type
)
p
->
dirty
=
1
;
}
}
...
...
@@ -1281,6 +1284,9 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
if
(
!
nid
)
return
;
if
(
codec
->
no_sticky_stream
)
do_now
=
1
;
snd_printdd
(
"hda_codec_cleanup_stream: NID=0x%x
\n
"
,
nid
);
p
=
get_hda_cvt_setup
(
codec
,
nid
);
if
(
p
)
{
...
...
@@ -1831,6 +1837,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
hda_nid_t
nid
=
get_amp_nid
(
kcontrol
);
int
dir
=
get_amp_direction
(
kcontrol
);
unsigned
int
ofs
=
get_amp_offset
(
kcontrol
);
bool
min_mute
=
get_amp_min_mute
(
kcontrol
);
u32
caps
,
val1
,
val2
;
if
(
size
<
4
*
sizeof
(
unsigned
int
))
...
...
@@ -1841,6 +1848,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
val1
=
-
((
caps
&
AC_AMPCAP_OFFSET
)
>>
AC_AMPCAP_OFFSET_SHIFT
);
val1
+=
ofs
;
val1
=
((
int
)
val1
)
*
((
int
)
val2
);
if
(
min_mute
)
val2
|=
TLV_DB_SCALE_MUTE
;
if
(
put_user
(
SNDRV_CTL_TLVT_DB_SCALE
,
_tlv
))
return
-
EFAULT
;
if
(
put_user
(
2
*
sizeof
(
unsigned
int
),
_tlv
+
1
))
...
...
@@ -2228,10 +2237,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
change
|=
snd_hda_codec_amp_update
(
codec
,
nid
,
1
,
dir
,
idx
,
HDA_AMP_MUTE
,
*
valp
?
0
:
HDA_AMP_MUTE
);
#ifdef CONFIG_SND_HDA_POWER_SAVE
if
(
codec
->
patch_ops
.
check_power_status
)
codec
->
patch_ops
.
check_power_status
(
codec
,
nid
);
#endif
hda_call_check_power_status
(
codec
,
nid
);
snd_hda_power_down
(
codec
);
return
change
;
}
...
...
@@ -4372,6 +4378,34 @@ static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
}
/* add the found input-pin to the cfg->inputs[] table */
static
void
add_auto_cfg_input_pin
(
struct
auto_pin_cfg
*
cfg
,
hda_nid_t
nid
,
int
type
)
{
if
(
cfg
->
num_inputs
<
AUTO_CFG_MAX_INS
)
{
cfg
->
inputs
[
cfg
->
num_inputs
].
pin
=
nid
;
cfg
->
inputs
[
cfg
->
num_inputs
].
type
=
type
;
cfg
->
num_inputs
++
;
}
}
/* sort inputs in the order of AUTO_PIN_* type */
static
void
sort_autocfg_input_pins
(
struct
auto_pin_cfg
*
cfg
)
{
int
i
,
j
;
for
(
i
=
0
;
i
<
cfg
->
num_inputs
;
i
++
)
{
for
(
j
=
i
+
1
;
j
<
cfg
->
num_inputs
;
j
++
)
{
if
(
cfg
->
inputs
[
i
].
type
>
cfg
->
inputs
[
j
].
type
)
{
struct
auto_pin_cfg_item
tmp
;
tmp
=
cfg
->
inputs
[
i
];
cfg
->
inputs
[
i
]
=
cfg
->
inputs
[
j
];
cfg
->
inputs
[
j
]
=
tmp
;
}
}
}
}
/*
* Parse all pin widgets and store the useful pin nids to cfg
*
...
...
@@ -4385,7 +4419,7 @@ static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
* output, i.e. to line_out_pins[0]. So, line_outs is always positive
* if any analog output exists.
*
* The analog input pins are assigned to input
_pin
s array.
* The analog input pins are assigned to inputs array.
* The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
* respectively.
*/
...
...
@@ -4398,6 +4432,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
short
sequences_line_out
[
ARRAY_SIZE
(
cfg
->
line_out_pins
)];
short
sequences_speaker
[
ARRAY_SIZE
(
cfg
->
speaker_pins
)];
short
sequences_hp
[
ARRAY_SIZE
(
cfg
->
hp_pins
)];
int
i
;
memset
(
cfg
,
0
,
sizeof
(
*
cfg
));
...
...
@@ -4468,33 +4503,17 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
sequences_hp
[
cfg
->
hp_outs
]
=
(
assoc
<<
4
)
|
seq
;
cfg
->
hp_outs
++
;
break
;
case
AC_JACK_MIC_IN
:
{
int
preferred
,
alt
;
if
(
loc
==
AC_JACK_LOC_FRONT
||
(
loc
&
0x30
)
==
AC_JACK_LOC_INTERNAL
)
{
preferred
=
AUTO_PIN_FRONT_MIC
;
alt
=
AUTO_PIN_MIC
;
}
else
{
preferred
=
AUTO_PIN_MIC
;
alt
=
AUTO_PIN_FRONT_MIC
;
}
if
(
!
cfg
->
input_pins
[
preferred
])
cfg
->
input_pins
[
preferred
]
=
nid
;
else
if
(
!
cfg
->
input_pins
[
alt
])
cfg
->
input_pins
[
alt
]
=
nid
;
case
AC_JACK_MIC_IN
:
add_auto_cfg_input_pin
(
cfg
,
nid
,
AUTO_PIN_MIC
);
break
;
}
case
AC_JACK_LINE_IN
:
if
(
loc
==
AC_JACK_LOC_FRONT
)
cfg
->
input_pins
[
AUTO_PIN_FRONT_LINE
]
=
nid
;
else
cfg
->
input_pins
[
AUTO_PIN_LINE
]
=
nid
;
add_auto_cfg_input_pin
(
cfg
,
nid
,
AUTO_PIN_LINE_IN
);
break
;
case
AC_JACK_CD
:
cfg
->
input_pins
[
AUTO_PIN_CD
]
=
nid
;
add_auto_cfg_input_pin
(
cfg
,
nid
,
AUTO_PIN_CD
)
;
break
;
case
AC_JACK_AUX
:
cfg
->
input_pins
[
AUTO_PIN_AUX
]
=
nid
;
add_auto_cfg_input_pin
(
cfg
,
nid
,
AUTO_PIN_AUX
)
;
break
;
case
AC_JACK_SPDIF_OUT
:
case
AC_JACK_DIG_OTHER_OUT
:
...
...
@@ -4539,6 +4558,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
memmove
(
sequences_hp
+
i
,
sequences_hp
+
i
+
1
,
sizeof
(
sequences_hp
[
0
])
*
(
cfg
->
hp_outs
-
i
));
}
memset
(
cfg
->
hp_pins
+
cfg
->
hp_outs
,
0
,
sizeof
(
hda_nid_t
)
*
(
AUTO_CFG_MAX_OUTS
-
cfg
->
hp_outs
));
}
/* sort by sequence */
...
...
@@ -4549,21 +4570,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
sort_pins_by_sequence
(
cfg
->
hp_pins
,
sequences_hp
,
cfg
->
hp_outs
);
/* if we have only one mic, make it AUTO_PIN_MIC */
if
(
!
cfg
->
input_pins
[
AUTO_PIN_MIC
]
&&
cfg
->
input_pins
[
AUTO_PIN_FRONT_MIC
])
{
cfg
->
input_pins
[
AUTO_PIN_MIC
]
=
cfg
->
input_pins
[
AUTO_PIN_FRONT_MIC
];
cfg
->
input_pins
[
AUTO_PIN_FRONT_MIC
]
=
0
;
}
/* ditto for line-in */
if
(
!
cfg
->
input_pins
[
AUTO_PIN_LINE
]
&&
cfg
->
input_pins
[
AUTO_PIN_FRONT_LINE
])
{
cfg
->
input_pins
[
AUTO_PIN_LINE
]
=
cfg
->
input_pins
[
AUTO_PIN_FRONT_LINE
];
cfg
->
input_pins
[
AUTO_PIN_FRONT_LINE
]
=
0
;
}
/*
* FIX-UP: if no line-outs are detected, try to use speaker or HP pin
* as a primary output
...
...
@@ -4602,6 +4608,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
break
;
}
sort_autocfg_input_pins
(
cfg
);
/*
* debug prints of the parsed results
*/
...
...
@@ -4621,14 +4629,13 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
if
(
cfg
->
dig_outs
)
snd_printd
(
" dig-out=0x%x/0x%x
\n
"
,
cfg
->
dig_out_pins
[
0
],
cfg
->
dig_out_pins
[
1
]);
snd_printd
(
" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
" cd=0x%x, aux=0x%x
\n
"
,
cfg
->
input_pins
[
AUTO_PIN_MIC
],
cfg
->
input_pins
[
AUTO_PIN_FRONT_MIC
],
cfg
->
input_pins
[
AUTO_PIN_LINE
],
cfg
->
input_pins
[
AUTO_PIN_FRONT_LINE
],
cfg
->
input_pins
[
AUTO_PIN_CD
],
cfg
->
input_pins
[
AUTO_PIN_AUX
]);
snd_printd
(
" inputs:"
);
for
(
i
=
0
;
i
<
cfg
->
num_inputs
;
i
++
)
{
snd_printdd
(
" %s=0x%x"
,
hda_get_autocfg_input_label
(
codec
,
cfg
,
i
),
cfg
->
inputs
[
i
].
pin
);
}
snd_printd
(
"
\n
"
);
if
(
cfg
->
dig_in_pin
)
snd_printd
(
" dig-in=0x%x
\n
"
,
cfg
->
dig_in_pin
);
...
...
@@ -4636,11 +4643,165 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
}
EXPORT_SYMBOL_HDA
(
snd_hda_parse_pin_def_config
);
/* labels for input pins */
const
char
*
auto_pin_cfg_labels
[
AUTO_PIN_LAST
]
=
{
"Mic"
,
"Front Mic"
,
"Line"
,
"Front Line"
,
"CD"
,
"Aux"
};
EXPORT_SYMBOL_HDA
(
auto_pin_cfg_labels
);
int
snd_hda_get_input_pin_attr
(
unsigned
int
def_conf
)
{
unsigned
int
loc
=
get_defcfg_location
(
def_conf
);
unsigned
int
conn
=
get_defcfg_connect
(
def_conf
);
if
(
conn
==
AC_JACK_PORT_NONE
)
return
INPUT_PIN_ATTR_UNUSED
;
/* Windows may claim the internal mic to be BOTH, too */
if
(
conn
==
AC_JACK_PORT_FIXED
||
conn
==
AC_JACK_PORT_BOTH
)
return
INPUT_PIN_ATTR_INT
;
if
((
loc
&
0x30
)
==
AC_JACK_LOC_INTERNAL
)
return
INPUT_PIN_ATTR_INT
;
if
((
loc
&
0x30
)
==
AC_JACK_LOC_SEPARATE
)
return
INPUT_PIN_ATTR_DOCK
;
if
(
loc
==
AC_JACK_LOC_REAR
)
return
INPUT_PIN_ATTR_REAR
;
if
(
loc
==
AC_JACK_LOC_FRONT
)
return
INPUT_PIN_ATTR_FRONT
;
return
INPUT_PIN_ATTR_NORMAL
;
}
EXPORT_SYMBOL_HDA
(
snd_hda_get_input_pin_attr
);
/**
* hda_get_input_pin_label - Give a label for the given input pin
*
* When check_location is true, the function checks the pin location
* for mic and line-in pins, and set an appropriate prefix like "Front",
* "Rear", "Internal".
*/
const
char
*
hda_get_input_pin_label
(
struct
hda_codec
*
codec
,
hda_nid_t
pin
,
int
check_location
)
{
unsigned
int
def_conf
;
static
const
char
*
mic_names
[]
=
{
"Internal Mic"
,
"Dock Mic"
,
"Mic"
,
"Front Mic"
,
"Rear Mic"
,
};
int
attr
;
def_conf
=
snd_hda_codec_get_pincfg
(
codec
,
pin
);
switch
(
get_defcfg_device
(
def_conf
))
{
case
AC_JACK_MIC_IN
:
if
(
!
check_location
)
return
"Mic"
;
attr
=
snd_hda_get_input_pin_attr
(
def_conf
);
if
(
!
attr
)
return
"None"
;
return
mic_names
[
attr
-
1
];
case
AC_JACK_LINE_IN
:
if
(
!
check_location
)
return
"Line"
;
attr
=
snd_hda_get_input_pin_attr
(
def_conf
);
if
(
!
attr
)
return
"None"
;
if
(
attr
==
INPUT_PIN_ATTR_DOCK
)
return
"Dock Line"
;
return
"Line"
;
case
AC_JACK_AUX
:
return
"Aux"
;
case
AC_JACK_CD
:
return
"CD"
;
case
AC_JACK_SPDIF_IN
:
return
"SPDIF In"
;
case
AC_JACK_DIG_OTHER_IN
:
return
"Digital In"
;
default:
return
"Misc"
;
}
}
EXPORT_SYMBOL_HDA
(
hda_get_input_pin_label
);
/* Check whether the location prefix needs to be added to the label.
* If all mic-jacks are in the same location (e.g. rear panel), we don't
* have to put "Front" prefix to each label. In such a case, returns false.
*/
static
int
check_mic_location_need
(
struct
hda_codec
*
codec
,
const
struct
auto_pin_cfg
*
cfg
,
int
input
)
{
unsigned
int
defc
;
int
i
,
attr
,
attr2
;
defc
=
snd_hda_codec_get_pincfg
(
codec
,
cfg
->
inputs
[
input
].
pin
);
attr
=
snd_hda_get_input_pin_attr
(
defc
);
/* for internal or docking mics, we need locations */
if
(
attr
<=
INPUT_PIN_ATTR_NORMAL
)
return
1
;
attr
=
0
;
for
(
i
=
0
;
i
<
cfg
->
num_inputs
;
i
++
)
{
defc
=
snd_hda_codec_get_pincfg
(
codec
,
cfg
->
inputs
[
i
].
pin
);
attr2
=
snd_hda_get_input_pin_attr
(
defc
);
if
(
attr2
>=
INPUT_PIN_ATTR_NORMAL
)
{
if
(
attr
&&
attr
!=
attr2
)
return
1
;
/* different locations found */
attr
=
attr2
;
}
}
return
0
;
}
/**
* hda_get_autocfg_input_label - Get a label for the given input
*
* Get a label for the given input pin defined by the autocfg item.
* Unlike hda_get_input_pin_label(), this function checks all inputs
* defined in autocfg and avoids the redundant mic/line prefix as much as
* possible.
*/
const
char
*
hda_get_autocfg_input_label
(
struct
hda_codec
*
codec
,
const
struct
auto_pin_cfg
*
cfg
,
int
input
)
{
int
type
=
cfg
->
inputs
[
input
].
type
;
int
has_multiple_pins
=
0
;
if
((
input
>
0
&&
cfg
->
inputs
[
input
-
1
].
type
==
type
)
||
(
input
<
cfg
->
num_inputs
-
1
&&
cfg
->
inputs
[
input
+
1
].
type
==
type
))
has_multiple_pins
=
1
;
if
(
has_multiple_pins
&&
type
==
AUTO_PIN_MIC
)
has_multiple_pins
&=
check_mic_location_need
(
codec
,
cfg
,
input
);
return
hda_get_input_pin_label
(
codec
,
cfg
->
inputs
[
input
].
pin
,
has_multiple_pins
);
}
EXPORT_SYMBOL_HDA
(
hda_get_autocfg_input_label
);
/**
* snd_hda_add_imux_item - Add an item to input_mux
*
* When the same label is used already in the existing items, the number
* suffix is appended to the label. This label index number is stored
* to type_idx when non-NULL pointer is given.
*/
int
snd_hda_add_imux_item
(
struct
hda_input_mux
*
imux
,
const
char
*
label
,
int
index
,
int
*
type_idx
)
{
int
i
,
label_idx
=
0
;
if
(
imux
->
num_items
>=
HDA_MAX_NUM_INPUTS
)
{
snd_printd
(
KERN_ERR
"hda_codec: Too many imux items!
\n
"
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
imux
->
num_items
;
i
++
)
{
if
(
!
strncmp
(
label
,
imux
->
items
[
i
].
label
,
strlen
(
label
)))
label_idx
++
;
}
if
(
type_idx
)
*
type_idx
=
label_idx
;
if
(
label_idx
>
0
)
snprintf
(
imux
->
items
[
imux
->
num_items
].
label
,
sizeof
(
imux
->
items
[
imux
->
num_items
].
label
),
"%s %d"
,
label
,
label_idx
);
else
strlcpy
(
imux
->
items
[
imux
->
num_items
].
label
,
label
,
sizeof
(
imux
->
items
[
imux
->
num_items
].
label
));
imux
->
items
[
imux
->
num_items
].
index
=
index
;
imux
->
num_items
++
;
return
0
;
}
EXPORT_SYMBOL_HDA
(
snd_hda_add_imux_item
);
#ifdef CONFIG_PM
...
...
sound/pci/hda/hda_codec.h
浏览文件 @
506ecbca
...
...
@@ -850,6 +850,7 @@ struct hda_codec {
unsigned
int
pin_amp_workaround
:
1
;
/* pin out-amp takes index
* (e.g. Conexant codecs)
*/
unsigned
int
no_sticky_stream
:
1
;
/* no sticky-PCM stream assignment */
unsigned
int
pins_shutup
:
1
;
/* pins are shut up */
unsigned
int
no_trigger_sense
:
1
;
/* don't trigger at pin-sensing */
#ifdef CONFIG_SND_HDA_POWER_SAVE
...
...
@@ -989,6 +990,18 @@ int snd_hda_suspend(struct hda_bus *bus);
int
snd_hda_resume
(
struct
hda_bus
*
bus
);
#endif
#ifdef CONFIG_SND_HDA_POWER_SAVE
static
inline
int
hda_call_check_power_status
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
)
{
if
(
codec
->
patch_ops
.
check_power_status
)
return
codec
->
patch_ops
.
check_power_status
(
codec
,
nid
);
return
0
;
}
#else
#define hda_call_check_power_status(codec, nid) 0
#endif
/*
* get widget information
*/
...
...
sound/pci/hda/hda_eld.c
浏览文件 @
506ecbca
...
...
@@ -332,7 +332,6 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
return
snd_hda_codec_read
(
codec
,
nid
,
0
,
AC_VERB_GET_HDMI_DIP_SIZE
,
AC_DIPSIZE_ELD_BUF
);
}
EXPORT_SYMBOL_HDA
(
snd_hdmi_get_eld_size
);
int
snd_hdmi_get_eld
(
struct
hdmi_eld
*
eld
,
struct
hda_codec
*
codec
,
hda_nid_t
nid
)
...
...
@@ -368,7 +367,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
kfree
(
buf
);
return
ret
;
}
EXPORT_SYMBOL_HDA
(
snd_hdmi_get_eld
);
static
void
hdmi_show_short_audio_desc
(
struct
cea_sad
*
a
)
{
...
...
@@ -407,7 +405,6 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
}
buf
[
j
]
=
'\0'
;
/* necessary when j == 0 */
}
EXPORT_SYMBOL_HDA
(
snd_print_channel_allocation
);
void
snd_hdmi_show_eld
(
struct
hdmi_eld
*
e
)
{
...
...
@@ -426,7 +423,6 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
for
(
i
=
0
;
i
<
e
->
sad_count
;
i
++
)
hdmi_show_short_audio_desc
(
e
->
sad
+
i
);
}
EXPORT_SYMBOL_HDA
(
snd_hdmi_show_eld
);
#ifdef CONFIG_PROC_FS
...
...
@@ -585,7 +581,6 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
return
0
;
}
EXPORT_SYMBOL_HDA
(
snd_hda_eld_proc_new
);
void
snd_hda_eld_proc_free
(
struct
hda_codec
*
codec
,
struct
hdmi_eld
*
eld
)
{
...
...
@@ -594,7 +589,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
eld
->
proc_entry
=
NULL
;
}
}
EXPORT_SYMBOL_HDA
(
snd_hda_eld_proc_free
);
#endif
/* CONFIG_PROC_FS */
...
...
@@ -645,4 +639,3 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
pcm
->
channels_max
=
min
(
pcm
->
channels_max
,
codec_pars
->
channels_max
);
pcm
->
maxbps
=
min
(
pcm
->
maxbps
,
codec_pars
->
maxbps
);
}
EXPORT_SYMBOL_HDA
(
hdmi_eld_update_pcm_info
);
sound/pci/hda/hda_generic.c
浏览文件 @
506ecbca
...
...
@@ -61,7 +61,6 @@ struct hda_gspec {
struct
hda_gnode
*
cap_vol_node
;
/* Node for capture volume */
unsigned
int
cur_cap_src
;
/* current capture source */
struct
hda_input_mux
input_mux
;
char
cap_labels
[
HDA_MAX_NUM_INPUTS
][
16
];
unsigned
int
def_amp_in_caps
;
unsigned
int
def_amp_out_caps
;
...
...
@@ -506,11 +505,10 @@ static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl)
* returns 0 if not found, 1 if found, or a negative error code.
*/
static
int
parse_adc_sub_nodes
(
struct
hda_codec
*
codec
,
struct
hda_gspec
*
spec
,
struct
hda_gnode
*
node
)
struct
hda_gnode
*
node
,
int
idx
)
{
int
i
,
err
;
unsigned
int
pinctl
;
char
*
label
;
const
char
*
type
;
if
(
node
->
checked
)
...
...
@@ -523,7 +521,7 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
child
=
hda_get_node
(
spec
,
node
->
conn_list
[
i
]);
if
(
!
child
)
continue
;
err
=
parse_adc_sub_nodes
(
codec
,
spec
,
child
);
err
=
parse_adc_sub_nodes
(
codec
,
spec
,
child
,
idx
);
if
(
err
<
0
)
return
err
;
if
(
err
>
0
)
{
...
...
@@ -564,9 +562,7 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
return
0
;
type
=
"Input"
;
}
label
=
spec
->
cap_labels
[
spec
->
input_mux
.
num_items
];
strcpy
(
label
,
type
);
spec
->
input_mux
.
items
[
spec
->
input_mux
.
num_items
].
label
=
label
;
snd_hda_add_imux_item
(
&
spec
->
input_mux
,
type
,
idx
,
NULL
);
/* unmute the PIN external input */
unmute_input
(
codec
,
node
,
0
);
/* index = 0? */
...
...
@@ -577,29 +573,6 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
return
1
;
/* found */
}
/* add a capture source element */
static
void
add_cap_src
(
struct
hda_gspec
*
spec
,
int
idx
)
{
struct
hda_input_mux_item
*
csrc
;
char
*
buf
;
int
num
,
ocap
;
num
=
spec
->
input_mux
.
num_items
;
csrc
=
&
spec
->
input_mux
.
items
[
num
];
buf
=
spec
->
cap_labels
[
num
];
for
(
ocap
=
0
;
ocap
<
num
;
ocap
++
)
{
if
(
!
strcmp
(
buf
,
spec
->
cap_labels
[
ocap
]))
{
/* same label already exists,
* put the index number to be unique
*/
sprintf
(
buf
,
"%s %d"
,
spec
->
cap_labels
[
ocap
],
num
);
break
;
}
}
csrc
->
index
=
idx
;
spec
->
input_mux
.
num_items
++
;
}
/*
* parse input
*/
...
...
@@ -624,22 +597,18 @@ static int parse_input_path(struct hda_codec *codec, struct hda_gnode *adc_node)
for
(
i
=
0
;
i
<
adc_node
->
nconns
;
i
++
)
{
node
=
hda_get_node
(
spec
,
adc_node
->
conn_list
[
i
]);
if
(
node
&&
node
->
type
==
AC_WID_PIN
)
{
err
=
parse_adc_sub_nodes
(
codec
,
spec
,
node
);
err
=
parse_adc_sub_nodes
(
codec
,
spec
,
node
,
i
);
if
(
err
<
0
)
return
err
;
else
if
(
err
>
0
)
add_cap_src
(
spec
,
i
);
}
}
/* ... then check the rests, more complicated connections */
for
(
i
=
0
;
i
<
adc_node
->
nconns
;
i
++
)
{
node
=
hda_get_node
(
spec
,
adc_node
->
conn_list
[
i
]);
if
(
node
&&
node
->
type
!=
AC_WID_PIN
)
{
err
=
parse_adc_sub_nodes
(
codec
,
spec
,
node
);
err
=
parse_adc_sub_nodes
(
codec
,
spec
,
node
,
i
);
if
(
err
<
0
)
return
err
;
else
if
(
err
>
0
)
add_cap_src
(
spec
,
i
);
}
}
...
...
sound/pci/hda/hda_intel.c
浏览文件 @
506ecbca
...
...
@@ -78,8 +78,8 @@ MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
module_param_array
(
model
,
charp
,
NULL
,
0444
);
MODULE_PARM_DESC
(
model
,
"Use the given board model."
);
module_param_array
(
position_fix
,
int
,
NULL
,
0444
);
MODULE_PARM_DESC
(
position_fix
,
"
Fix DMA pointer
"
"(0 = auto, 1 =
none, 2 = POSBUF
)."
);
MODULE_PARM_DESC
(
position_fix
,
"
DMA pointer read method.
"
"(0 = auto, 1 =
LPIB, 2 = POSBUF, 3 = VIACOMBO
)."
);
module_param_array
(
bdl_pos_adj
,
int
,
NULL
,
0644
);
MODULE_PARM_DESC
(
bdl_pos_adj
,
"BDL position adjustment offset."
);
module_param_array
(
probe_mask
,
int
,
NULL
,
0444
);
...
...
@@ -305,6 +305,7 @@ enum {
POS_FIX_AUTO
,
POS_FIX_LPIB
,
POS_FIX_POSBUF
,
POS_FIX_VIACOMBO
,
};
/* Defines for ATI HD Audio support in SB450 south bridge */
...
...
@@ -433,7 +434,6 @@ struct azx {
unsigned
int
polling_mode
:
1
;
unsigned
int
msi
:
1
;
unsigned
int
irq_pending_warned
:
1
;
unsigned
int
via_dmapos_patch
:
1
;
/* enable DMA-position fix for VIA */
unsigned
int
probing
:
1
;
/* codec probing phase */
/* for debugging */
...
...
@@ -458,6 +458,7 @@ enum {
AZX_DRIVER_ULI
,
AZX_DRIVER_NVIDIA
,
AZX_DRIVER_TERA
,
AZX_DRIVER_CTX
,
AZX_DRIVER_GENERIC
,
AZX_NUM_DRIVERS
,
/* keep this as last entry */
};
...
...
@@ -473,6 +474,7 @@ static char *driver_short_names[] __devinitdata = {
[
AZX_DRIVER_ULI
]
=
"HDA ULI M5461"
,
[
AZX_DRIVER_NVIDIA
]
=
"HDA NVidia"
,
[
AZX_DRIVER_TERA
]
=
"HDA Teradici"
,
[
AZX_DRIVER_CTX
]
=
"HDA Creative"
,
[
AZX_DRIVER_GENERIC
]
=
"HD-Audio Generic"
,
};
...
...
@@ -563,7 +565,10 @@ static void azx_init_cmd_io(struct azx *chip)
/* reset the rirb hw write pointer */
azx_writew
(
chip
,
RIRBWP
,
ICH6_RIRBWP_RST
);
/* set N=1, get RIRB response interrupt for new entry */
azx_writew
(
chip
,
RINTCNT
,
1
);
if
(
chip
->
driver_type
==
AZX_DRIVER_CTX
)
azx_writew
(
chip
,
RINTCNT
,
0xc0
);
else
azx_writew
(
chip
,
RINTCNT
,
1
);
/* enable rirb dma and response irq */
azx_writeb
(
chip
,
RIRBCTL
,
ICH6_RBCTL_DMA_EN
|
ICH6_RBCTL_IRQ_EN
);
spin_unlock_irq
(
&
chip
->
reg_lock
);
...
...
@@ -1136,8 +1141,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
/* clear rirb int */
status
=
azx_readb
(
chip
,
RIRBSTS
);
if
(
status
&
RIRB_INT_MASK
)
{
if
(
status
&
RIRB_INT_RESPONSE
)
if
(
status
&
RIRB_INT_RESPONSE
)
{
if
(
chip
->
driver_type
==
AZX_DRIVER_CTX
)
udelay
(
80
);
azx_update_rirb
(
chip
);
}
azx_writeb
(
chip
,
RIRBSTS
,
RIRB_INT_MASK
);
}
...
...
@@ -1309,11 +1317,8 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
azx_sd_writel
(
azx_dev
,
SD_BDLPU
,
upper_32_bits
(
azx_dev
->
bdl
.
addr
));
/* enable the position buffer */
if
(
chip
->
position_fix
[
0
]
==
POS_FIX_POSBUF
||
chip
->
position_fix
[
0
]
==
POS_FIX_AUTO
||
chip
->
position_fix
[
1
]
==
POS_FIX_POSBUF
||
chip
->
position_fix
[
1
]
==
POS_FIX_AUTO
||
chip
->
via_dmapos_patch
)
{
if
(
chip
->
position_fix
[
0
]
!=
POS_FIX_LPIB
||
chip
->
position_fix
[
1
]
!=
POS_FIX_LPIB
)
{
if
(
!
(
azx_readl
(
chip
,
DPLBASE
)
&
ICH6_DPLBASE_ENABLE
))
azx_writel
(
chip
,
DPLBASE
,
(
u32
)
chip
->
posbuf
.
addr
|
ICH6_DPLBASE_ENABLE
);
...
...
@@ -1647,7 +1652,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
struct
azx_dev
*
azx_dev
=
get_azx_dev
(
substream
);
struct
hda_pcm_stream
*
hinfo
=
apcm
->
hinfo
[
substream
->
stream
];
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
unsigned
int
bufsize
,
period_bytes
,
format_val
;
unsigned
int
bufsize
,
period_bytes
,
format_val
,
stream_tag
;
int
err
;
azx_stream_reset
(
chip
,
azx_dev
);
...
...
@@ -1689,7 +1694,12 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
else
azx_dev
->
fifo_size
=
0
;
return
snd_hda_codec_prepare
(
apcm
->
codec
,
hinfo
,
azx_dev
->
stream_tag
,
stream_tag
=
azx_dev
->
stream_tag
;
/* CA-IBG chips need the playback stream starting from 1 */
if
(
chip
->
driver_type
==
AZX_DRIVER_CTX
&&
stream_tag
>
chip
->
capture_streams
)
stream_tag
-=
chip
->
capture_streams
;
return
snd_hda_codec_prepare
(
apcm
->
codec
,
hinfo
,
stream_tag
,
azx_dev
->
format_val
,
substream
);
}
...
...
@@ -1852,20 +1862,21 @@ static unsigned int azx_get_position(struct azx *chip,
struct
azx_dev
*
azx_dev
)
{
unsigned
int
pos
;
int
stream
=
azx_dev
->
substream
->
stream
;
if
(
chip
->
via_dmapos_patch
)
switch
(
chip
->
position_fix
[
stream
])
{
case
POS_FIX_LPIB
:
/* read LPIB */
pos
=
azx_sd_readl
(
azx_dev
,
SD_LPIB
);
break
;
case
POS_FIX_VIACOMBO
:
pos
=
azx_via_get_position
(
chip
,
azx_dev
);
else
{
int
stream
=
azx_dev
->
substream
->
stream
;
if
(
chip
->
position_fix
[
stream
]
==
POS_FIX_POSBUF
||
chip
->
position_fix
[
stream
]
==
POS_FIX_AUTO
)
{
/* use the position buffer */
pos
=
le32_to_cpu
(
*
azx_dev
->
posbuf
);
}
else
{
/* read LPIB */
pos
=
azx_sd_readl
(
azx_dev
,
SD_LPIB
);
}
break
;
default:
/* use the position buffer */
pos
=
le32_to_cpu
(
*
azx_dev
->
posbuf
);
}
if
(
pos
>=
azx_dev
->
bufsize
)
pos
=
0
;
return
pos
;
...
...
@@ -2313,19 +2324,10 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
switch
(
fix
)
{
case
POS_FIX_LPIB
:
case
POS_FIX_POSBUF
:
case
POS_FIX_VIACOMBO
:
return
fix
;
}
/* Check VIA/ATI HD Audio Controller exist */
switch
(
chip
->
driver_type
)
{
case
AZX_DRIVER_VIA
:
case
AZX_DRIVER_ATI
:
chip
->
via_dmapos_patch
=
1
;
/* Use link position directly, avoid any transfer problem. */
return
POS_FIX_LPIB
;
}
chip
->
via_dmapos_patch
=
0
;
q
=
snd_pci_quirk_lookup
(
chip
->
pci
,
position_fix_list
);
if
(
q
)
{
printk
(
KERN_INFO
...
...
@@ -2334,6 +2336,15 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
q
->
value
,
q
->
subvendor
,
q
->
subdevice
);
return
q
->
value
;
}
/* Check VIA/ATI HD Audio Controller exist */
switch
(
chip
->
driver_type
)
{
case
AZX_DRIVER_VIA
:
case
AZX_DRIVER_ATI
:
/* Use link position directly, avoid any transfer problem. */
return
POS_FIX_VIACOMBO
;
}
return
POS_FIX_AUTO
;
}
...
...
@@ -2735,25 +2746,17 @@ static void __devexit azx_remove(struct pci_dev *pci)
/* PCI IDs */
static
DEFINE_PCI_DEVICE_TABLE
(
azx_ids
)
=
{
/* ICH 6..10 */
{
PCI_DEVICE
(
0x8086
,
0x2668
),
.
driver_data
=
AZX_DRIVER_ICH
},
{
PCI_DEVICE
(
0x8086
,
0x27d8
),
.
driver_data
=
AZX_DRIVER_ICH
},
{
PCI_DEVICE
(
0x8086
,
0x269a
),
.
driver_data
=
AZX_DRIVER_ICH
},
{
PCI_DEVICE
(
0x8086
,
0x284b
),
.
driver_data
=
AZX_DRIVER_ICH
},
{
PCI_DEVICE
(
0x8086
,
0x2911
),
.
driver_data
=
AZX_DRIVER_ICH
},
{
PCI_DEVICE
(
0x8086
,
0x293e
),
.
driver_data
=
AZX_DRIVER_ICH
},
{
PCI_DEVICE
(
0x8086
,
0x293f
),
.
driver_data
=
AZX_DRIVER_ICH
},
{
PCI_DEVICE
(
0x8086
,
0x3a3e
),
.
driver_data
=
AZX_DRIVER_ICH
},
{
PCI_DEVICE
(
0x8086
,
0x3a6e
),
.
driver_data
=
AZX_DRIVER_ICH
},
/* PCH */
{
PCI_DEVICE
(
0x8086
,
0x3b56
),
.
driver_data
=
AZX_DRIVER_ICH
},
{
PCI_DEVICE
(
0x8086
,
0x3b57
),
.
driver_data
=
AZX_DRIVER_ICH
},
/* CPT */
{
PCI_DEVICE
(
0x8086
,
0x1c20
),
.
driver_data
=
AZX_DRIVER_PCH
},
/* PBG */
{
PCI_DEVICE
(
0x8086
,
0x1d20
),
.
driver_data
=
AZX_DRIVER_PCH
},
/* SCH */
{
PCI_DEVICE
(
0x8086
,
0x811b
),
.
driver_data
=
AZX_DRIVER_SCH
},
/* Generic Intel */
{
PCI_DEVICE
(
PCI_VENDOR_ID_INTEL
,
PCI_ANY_ID
),
.
class
=
PCI_CLASS_MULTIMEDIA_HD_AUDIO
<<
8
,
.
class_mask
=
0xffffff
,
.
driver_data
=
AZX_DRIVER_ICH
},
/* ATI SB 450/600 */
{
PCI_DEVICE
(
0x1002
,
0x437b
),
.
driver_data
=
AZX_DRIVER_ATI
},
{
PCI_DEVICE
(
0x1002
,
0x4383
),
.
driver_data
=
AZX_DRIVER_ATI
},
...
...
@@ -2794,11 +2797,13 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
{
PCI_DEVICE
(
PCI_VENDOR_ID_CREATIVE
,
PCI_ANY_ID
),
.
class
=
PCI_CLASS_MULTIMEDIA_HD_AUDIO
<<
8
,
.
class_mask
=
0xffffff
,
.
driver_data
=
AZX_DRIVER_
GENERIC
},
.
driver_data
=
AZX_DRIVER_
CTX
},
#else
/* this entry seems still valid -- i.e. without emu20kx chip */
{
PCI_DEVICE
(
0x1102
,
0x0009
),
.
driver_data
=
AZX_DRIVER_
GENERIC
},
{
PCI_DEVICE
(
0x1102
,
0x0009
),
.
driver_data
=
AZX_DRIVER_
CTX
},
#endif
/* Vortex86MX */
{
PCI_DEVICE
(
0x17f3
,
0x3010
),
.
driver_data
=
AZX_DRIVER_GENERIC
},
/* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
{
PCI_DEVICE
(
PCI_VENDOR_ID_ATI
,
PCI_ANY_ID
),
.
class
=
PCI_CLASS_MULTIMEDIA_HD_AUDIO
<<
8
,
...
...
sound/pci/hda/hda_local.h
浏览文件 @
506ecbca
...
...
@@ -38,10 +38,11 @@
*/
#define HDA_COMPOSE_AMP_VAL_OFS(nid,chs,idx,dir,ofs) \
((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19) | ((ofs)<<23))
#define HDA_AMP_VAL_MIN_MUTE (1<<29)
#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \
HDA_COMPOSE_AMP_VAL_OFS(nid, chs, idx, dir, 0)
/* mono volume with index (index=0,1,...) (channel=1,2) */
#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, dir
ection
) \
#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, dir
, flags
) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
.subdevice = HDA_SUBDEV_AMP_FLAG, \
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
...
...
@@ -51,16 +52,20 @@
.get = snd_hda_mixer_amp_volume_get, \
.put = snd_hda_mixer_amp_volume_put, \
.tlv = { .c = snd_hda_mixer_amp_tlv }, \
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, dir
ection)
}
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, dir
) | flags
}
/* stereo volume with index */
#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction
, 0
)
/* mono volume */
#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction)
HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction
, 0
)
/* stereo volume */
#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
/* stereo volume with min=mute */
#define HDA_CODEC_VOLUME_MIN_MUTE(xname, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, 3, xindex, direction, \
HDA_AMP_VAL_MIN_MUTE)
/* mono mute switch with index (index=0,1,...) (channel=1,2) */
#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
...
...
@@ -215,7 +220,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
*/
#define HDA_MAX_NUM_INPUTS 16
struct
hda_input_mux_item
{
c
onst
char
*
label
;
c
har
label
[
32
]
;
unsigned
int
index
;
};
struct
hda_input_mux
{
...
...
@@ -366,9 +371,7 @@ struct hda_bus_unsolicited {
enum
{
AUTO_PIN_MIC
,
AUTO_PIN_FRONT_MIC
,
AUTO_PIN_LINE
,
AUTO_PIN_FRONT_LINE
,
AUTO_PIN_LINE_IN
,
AUTO_PIN_CD
,
AUTO_PIN_AUX
,
AUTO_PIN_LAST
...
...
@@ -380,9 +383,33 @@ enum {
AUTO_PIN_HP_OUT
};
extern
const
char
*
auto_pin_cfg_labels
[
AUTO_PIN_LAST
];
#define AUTO_CFG_MAX_OUTS 5
#define AUTO_CFG_MAX_INS 8
struct
auto_pin_cfg_item
{
hda_nid_t
pin
;
int
type
;
};
struct
auto_pin_cfg
;
const
char
*
hda_get_input_pin_label
(
struct
hda_codec
*
codec
,
hda_nid_t
pin
,
int
check_location
);
const
char
*
hda_get_autocfg_input_label
(
struct
hda_codec
*
codec
,
const
struct
auto_pin_cfg
*
cfg
,
int
input
);
int
snd_hda_add_imux_item
(
struct
hda_input_mux
*
imux
,
const
char
*
label
,
int
index
,
int
*
type_index_ret
);
enum
{
INPUT_PIN_ATTR_UNUSED
,
/* pin not connected */
INPUT_PIN_ATTR_INT
,
/* internal mic/line-in */
INPUT_PIN_ATTR_DOCK
,
/* docking mic/line-in */
INPUT_PIN_ATTR_NORMAL
,
/* mic/line-in jack */
INPUT_PIN_ATTR_FRONT
,
/* mic/line-in jack in front */
INPUT_PIN_ATTR_REAR
,
/* mic/line-in jack in rear */
};
int
snd_hda_get_input_pin_attr
(
unsigned
int
def_conf
);
struct
auto_pin_cfg
{
int
line_outs
;
...
...
@@ -393,7 +420,8 @@ struct auto_pin_cfg {
int
hp_outs
;
int
line_out_type
;
/* AUTO_PIN_XXX_OUT */
hda_nid_t
hp_pins
[
AUTO_CFG_MAX_OUTS
];
hda_nid_t
input_pins
[
AUTO_PIN_LAST
];
int
num_inputs
;
struct
auto_pin_cfg_item
inputs
[
AUTO_CFG_MAX_INS
];
int
dig_outs
;
hda_nid_t
dig_out_pins
[
2
];
hda_nid_t
dig_in_pin
;
...
...
@@ -558,6 +586,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1)
/*
* CEA Short Audio Descriptor data
...
...
sound/pci/hda/patch_analog.c
浏览文件 @
506ecbca
...
...
@@ -1276,6 +1276,7 @@ static int patch_ad1986a(struct hda_codec *codec)
spec
->
multiout
.
no_share_stream
=
1
;
codec
->
no_trigger_sense
=
1
;
codec
->
no_sticky_stream
=
1
;
return
0
;
}
...
...
@@ -1463,6 +1464,7 @@ static int patch_ad1983(struct hda_codec *codec)
codec
->
patch_ops
=
ad198x_patch_ops
;
codec
->
no_trigger_sense
=
1
;
codec
->
no_sticky_stream
=
1
;
return
0
;
}
...
...
@@ -1917,6 +1919,7 @@ static int patch_ad1981(struct hda_codec *codec)
}
codec
->
no_trigger_sense
=
1
;
codec
->
no_sticky_stream
=
1
;
return
0
;
}
...
...
@@ -2880,7 +2883,7 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
/* create input playback/capture controls for the given pin */
static
int
new_analog_input
(
struct
ad198x_spec
*
spec
,
hda_nid_t
pin
,
const
char
*
ctlname
,
int
boost
)
const
char
*
ctlname
,
int
ctlidx
,
int
boost
)
{
char
name
[
32
];
int
err
,
idx
;
...
...
@@ -2909,25 +2912,27 @@ static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
}
/* create playback/capture controls for input pins */
static
int
ad1988_auto_create_analog_input_ctls
(
struct
ad198x_spec
*
sp
ec
,
static
int
ad1988_auto_create_analog_input_ctls
(
struct
hda_codec
*
cod
ec
,
const
struct
auto_pin_cfg
*
cfg
)
{
struct
ad198x_spec
*
spec
=
codec
->
spec
;
struct
hda_input_mux
*
imux
=
&
spec
->
private_imux
;
int
i
,
err
;
for
(
i
=
0
;
i
<
AUTO_PIN_LAST
;
i
++
)
{
err
=
new_analog_input
(
spec
,
cfg
->
input_pins
[
i
],
auto_pin_cfg_labels
[
i
],
i
<=
AUTO_PIN_FRONT_MIC
);
int
i
,
err
,
type
,
type_idx
;
for
(
i
=
0
;
i
<
cfg
->
num_inputs
;
i
++
)
{
const
char
*
label
;
type
=
cfg
->
inputs
[
i
].
type
;
label
=
hda_get_autocfg_input_label
(
codec
,
cfg
,
i
);
snd_hda_add_imux_item
(
imux
,
label
,
ad1988_pin_to_adc_idx
(
cfg
->
inputs
[
i
].
pin
),
&
type_idx
);
err
=
new_analog_input
(
spec
,
cfg
->
inputs
[
i
].
pin
,
label
,
type_idx
,
type
==
AUTO_PIN_MIC
);
if
(
err
<
0
)
return
err
;
imux
->
items
[
imux
->
num_items
].
label
=
auto_pin_cfg_labels
[
i
];
imux
->
items
[
imux
->
num_items
].
index
=
ad1988_pin_to_adc_idx
(
cfg
->
input_pins
[
i
]);
imux
->
num_items
++
;
}
imux
->
items
[
imux
->
num_items
].
label
=
"Mix"
;
imux
->
items
[
imux
->
num_items
].
index
=
9
;
imux
->
num_items
++
;
snd_hda_add_imux_item
(
imux
,
"Mix"
,
9
,
NULL
);
if
((
err
=
add_control
(
spec
,
AD_CTL_WIDGET_VOL
,
"Analog Mix Playback Volume"
,
...
...
@@ -2994,12 +2999,11 @@ static void ad1988_auto_init_extra_out(struct hda_codec *codec)
static
void
ad1988_auto_init_analog_input
(
struct
hda_codec
*
codec
)
{
struct
ad198x_spec
*
spec
=
codec
->
spec
;
const
struct
auto_pin_cfg
*
cfg
=
&
spec
->
autocfg
;
int
i
,
idx
;
for
(
i
=
0
;
i
<
AUTO_PIN_LAST
;
i
++
)
{
hda_nid_t
nid
=
spec
->
autocfg
.
input_pins
[
i
];
if
(
!
nid
)
continue
;
for
(
i
=
0
;
i
<
cfg
->
num_inputs
;
i
++
)
{
hda_nid_t
nid
=
cfg
->
inputs
[
i
].
pin
;
switch
(
nid
)
{
case
0x15
:
/* port-C */
snd_hda_codec_write
(
codec
,
0x33
,
0
,
AC_VERB_SET_CONNECT_SEL
,
0x0
);
...
...
@@ -3009,7 +3013,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec)
break
;
}
snd_hda_codec_write
(
codec
,
nid
,
0
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
i
<=
AUTO_PIN_FRONT
_MIC
?
PIN_VREF80
:
PIN_IN
);
i
==
AUTO_PIN
_MIC
?
PIN_VREF80
:
PIN_IN
);
if
(
nid
!=
AD1988_PIN_CD_NID
)
snd_hda_codec_write
(
codec
,
nid
,
0
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_OUT_MUTE
);
...
...
@@ -3040,7 +3044,7 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
"Speaker"
))
<
0
||
(
err
=
ad1988_auto_create_extra_out
(
codec
,
spec
->
autocfg
.
hp_pins
[
0
],
"Headphone"
))
<
0
||
(
err
=
ad1988_auto_create_analog_input_ctls
(
sp
ec
,
&
spec
->
autocfg
))
<
0
)
(
err
=
ad1988_auto_create_analog_input_ctls
(
cod
ec
,
&
spec
->
autocfg
))
<
0
)
return
err
;
spec
->
multiout
.
max_channels
=
spec
->
multiout
.
num_dacs
*
2
;
...
...
@@ -3235,6 +3239,7 @@ static int patch_ad1988(struct hda_codec *codec)
spec
->
vmaster_nid
=
0x04
;
codec
->
no_trigger_sense
=
1
;
codec
->
no_sticky_stream
=
1
;
return
0
;
}
...
...
@@ -3449,6 +3454,7 @@ static int patch_ad1884(struct hda_codec *codec)
codec
->
patch_ops
=
ad198x_patch_ops
;
codec
->
no_trigger_sense
=
1
;
codec
->
no_sticky_stream
=
1
;
return
0
;
}
...
...
@@ -4422,6 +4428,7 @@ static int patch_ad1884a(struct hda_codec *codec)
}
codec
->
no_trigger_sense
=
1
;
codec
->
no_sticky_stream
=
1
;
return
0
;
}
...
...
@@ -4761,6 +4768,7 @@ static int patch_ad1882(struct hda_codec *codec)
}
codec
->
no_trigger_sense
=
1
;
codec
->
no_sticky_stream
=
1
;
return
0
;
}
...
...
sound/pci/hda/patch_atihdmi.c
已删除
100644 → 0
浏览文件 @
aa5c14d5
/*
* Universal Interface for Intel High Definition Audio Codec
*
* HD audio interface patch for ATI HDMI codecs
*
* Copyright (c) 2006 ATI Technologies Inc.
*
*
* This driver is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This driver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_local.h"
struct
atihdmi_spec
{
struct
hda_multi_out
multiout
;
struct
hda_pcm
pcm_rec
;
};
#define CVT_NID 0x02
/* audio converter */
#define PIN_NID 0x03
/* HDMI output pin */
static
struct
hda_verb
atihdmi_basic_init
[]
=
{
/* enable digital output on pin widget */
{
0x03
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_OUT
},
{}
/* terminator */
};
/*
* Controls
*/
static
int
atihdmi_build_controls
(
struct
hda_codec
*
codec
)
{
struct
atihdmi_spec
*
spec
=
codec
->
spec
;
int
err
;
err
=
snd_hda_create_spdif_out_ctls
(
codec
,
spec
->
multiout
.
dig_out_nid
);
if
(
err
<
0
)
return
err
;
return
0
;
}
static
int
atihdmi_init
(
struct
hda_codec
*
codec
)
{
snd_hda_sequence_write
(
codec
,
atihdmi_basic_init
);
/* SI codec requires to unmute the pin */
if
(
get_wcaps
(
codec
,
PIN_NID
)
&
AC_WCAP_OUT_AMP
)
snd_hda_codec_write
(
codec
,
PIN_NID
,
0
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_OUT_UNMUTE
);
return
0
;
}
/*
* Digital out
*/
static
int
atihdmi_dig_playback_pcm_open
(
struct
hda_pcm_stream
*
hinfo
,
struct
hda_codec
*
codec
,
struct
snd_pcm_substream
*
substream
)
{
struct
atihdmi_spec
*
spec
=
codec
->
spec
;
return
snd_hda_multi_out_dig_open
(
codec
,
&
spec
->
multiout
);
}
static
int
atihdmi_dig_playback_pcm_close
(
struct
hda_pcm_stream
*
hinfo
,
struct
hda_codec
*
codec
,
struct
snd_pcm_substream
*
substream
)
{
struct
atihdmi_spec
*
spec
=
codec
->
spec
;
return
snd_hda_multi_out_dig_close
(
codec
,
&
spec
->
multiout
);
}
static
int
atihdmi_dig_playback_pcm_prepare
(
struct
hda_pcm_stream
*
hinfo
,
struct
hda_codec
*
codec
,
unsigned
int
stream_tag
,
unsigned
int
format
,
struct
snd_pcm_substream
*
substream
)
{
struct
atihdmi_spec
*
spec
=
codec
->
spec
;
int
chans
=
substream
->
runtime
->
channels
;
int
i
,
err
;
err
=
snd_hda_multi_out_dig_prepare
(
codec
,
&
spec
->
multiout
,
stream_tag
,
format
,
substream
);
if
(
err
<
0
)
return
err
;
snd_hda_codec_write
(
codec
,
CVT_NID
,
0
,
AC_VERB_SET_CVT_CHAN_COUNT
,
chans
-
1
);
/* FIXME: XXX */
for
(
i
=
0
;
i
<
chans
;
i
++
)
{
snd_hda_codec_write
(
codec
,
CVT_NID
,
0
,
AC_VERB_SET_HDMI_CHAN_SLOT
,
(
i
<<
4
)
|
i
);
}
return
0
;
}
static
struct
hda_pcm_stream
atihdmi_pcm_digital_playback
=
{
.
substreams
=
1
,
.
channels_min
=
2
,
.
channels_max
=
2
,
.
nid
=
CVT_NID
,
/* NID to query formats and rates and setup streams */
.
ops
=
{
.
open
=
atihdmi_dig_playback_pcm_open
,
.
close
=
atihdmi_dig_playback_pcm_close
,
.
prepare
=
atihdmi_dig_playback_pcm_prepare
},
};
static
int
atihdmi_build_pcms
(
struct
hda_codec
*
codec
)
{
struct
atihdmi_spec
*
spec
=
codec
->
spec
;
struct
hda_pcm
*
info
=
&
spec
->
pcm_rec
;
unsigned
int
chans
;
codec
->
num_pcms
=
1
;
codec
->
pcm_info
=
info
;
info
->
name
=
"ATI HDMI"
;
info
->
pcm_type
=
HDA_PCM_TYPE_HDMI
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
atihdmi_pcm_digital_playback
;
/* FIXME: we must check ELD and change the PCM parameters dynamically
*/
chans
=
get_wcaps
(
codec
,
CVT_NID
);
chans
=
get_wcaps_channels
(
chans
);
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
channels_max
=
chans
;
return
0
;
}
static
void
atihdmi_free
(
struct
hda_codec
*
codec
)
{
kfree
(
codec
->
spec
);
}
static
struct
hda_codec_ops
atihdmi_patch_ops
=
{
.
build_controls
=
atihdmi_build_controls
,
.
build_pcms
=
atihdmi_build_pcms
,
.
init
=
atihdmi_init
,
.
free
=
atihdmi_free
,
};
static
int
patch_atihdmi
(
struct
hda_codec
*
codec
)
{
struct
atihdmi_spec
*
spec
;
spec
=
kzalloc
(
sizeof
(
*
spec
),
GFP_KERNEL
);
if
(
spec
==
NULL
)
return
-
ENOMEM
;
codec
->
spec
=
spec
;
spec
->
multiout
.
num_dacs
=
0
;
/* no analog */
spec
->
multiout
.
max_channels
=
2
;
/* NID for copying analog to digital,
* seems to be unused in pure-digital
* case.
*/
spec
->
multiout
.
dig_out_nid
=
CVT_NID
;
codec
->
patch_ops
=
atihdmi_patch_ops
;
return
0
;
}
/*
* patch entries
*/
static
struct
hda_codec_preset
snd_hda_preset_atihdmi
[]
=
{
{
.
id
=
0x1002793c
,
.
name
=
"RS600 HDMI"
,
.
patch
=
patch_atihdmi
},
{
.
id
=
0x10027919
,
.
name
=
"RS600 HDMI"
,
.
patch
=
patch_atihdmi
},
{
.
id
=
0x1002791a
,
.
name
=
"RS690/780 HDMI"
,
.
patch
=
patch_atihdmi
},
{
.
id
=
0x1002aa01
,
.
name
=
"R6xx HDMI"
,
.
patch
=
patch_atihdmi
},
{
.
id
=
0x10951390
,
.
name
=
"SiI1390 HDMI"
,
.
patch
=
patch_atihdmi
},
{
.
id
=
0x17e80047
,
.
name
=
"Chrontel HDMI"
,
.
patch
=
patch_atihdmi
},
{}
/* terminator */
};
MODULE_ALIAS
(
"snd-hda-codec-id:1002793c"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10027919"
);
MODULE_ALIAS
(
"snd-hda-codec-id:1002791a"
);
MODULE_ALIAS
(
"snd-hda-codec-id:1002aa01"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10951390"
);
MODULE_ALIAS
(
"snd-hda-codec-id:17e80047"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"ATI HDMI HD-audio codec"
);
static
struct
hda_codec_preset_list
atihdmi_list
=
{
.
preset
=
snd_hda_preset_atihdmi
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_atihdmi_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
atihdmi_list
);
}
static
void
__exit
patch_atihdmi_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
atihdmi_list
);
}
module_init
(
patch_atihdmi_init
)
module_exit
(
patch_atihdmi_exit
)
sound/pci/hda/patch_ca0110.c
浏览文件 @
506ecbca
...
...
@@ -468,13 +468,13 @@ static void parse_input(struct hda_codec *codec)
spec
->
dig_in
=
nid
;
continue
;
}
for
(
j
=
0
;
j
<
AUTO_PIN_LAST
;
j
++
)
if
(
cfg
->
input
_pins
[
j
]
==
pin
)
for
(
j
=
0
;
j
<
cfg
->
num_inputs
;
j
++
)
if
(
cfg
->
input
s
[
j
].
pin
==
pin
)
break
;
if
(
j
>=
AUTO_PIN_LAST
)
if
(
j
>=
cfg
->
num_inputs
)
continue
;
spec
->
input_pins
[
n
]
=
pin
;
spec
->
input_labels
[
n
]
=
auto_pin_cfg_labels
[
j
]
;
spec
->
input_labels
[
n
]
=
hda_get_input_pin_label
(
codec
,
pin
,
1
)
;
spec
->
adcs
[
n
]
=
nid
;
n
++
;
}
...
...
@@ -489,7 +489,7 @@ static void parse_digital(struct hda_codec *codec)
if
(
cfg
->
dig_outs
&&
snd_hda_get_connections
(
codec
,
cfg
->
dig_out_pins
[
0
],
&
spec
->
dig_out
,
1
)
==
1
)
spec
->
multiout
.
dig_out_nid
=
cfg
->
dig_out_pins
[
0
]
;
spec
->
multiout
.
dig_out_nid
=
spec
->
dig_out
;
}
static
int
ca0110_parse_auto_config
(
struct
hda_codec
*
codec
)
...
...
sound/pci/hda/patch_cirrus.c
浏览文件 @
506ecbca
...
...
@@ -65,6 +65,7 @@ struct cs_spec {
/* available models */
enum
{
CS420X_MBP53
,
CS420X_MBP55
,
CS420X_IMAC27
,
CS420X_AUTO
,
...
...
@@ -329,12 +330,12 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
{
struct
cs_spec
*
spec
=
codec
->
spec
;
struct
auto_pin_cfg
*
cfg
=
&
spec
->
autocfg
;
hda_nid_t
pin
=
cfg
->
input
_pins
[
idx
]
;
hda_nid_t
pin
=
cfg
->
input
s
[
idx
].
pin
;
unsigned
int
val
=
snd_hda_query_pin_caps
(
codec
,
pin
);
if
(
!
(
val
&
AC_PINCAP_PRES_DETECT
))
return
0
;
val
=
snd_hda_codec_get_pincfg
(
codec
,
pin
);
return
(
get_defcfg_connect
(
val
)
==
AC_JACK_PORT_COMPLEX
);
return
(
snd_hda_get_input_pin_attr
(
val
)
!=
INPUT_PIN_ATTR_INT
);
}
static
hda_nid_t
get_adc
(
struct
hda_codec
*
codec
,
hda_nid_t
pin
,
...
...
@@ -424,10 +425,8 @@ static int parse_input(struct hda_codec *codec)
struct
auto_pin_cfg
*
cfg
=
&
spec
->
autocfg
;
int
i
;
for
(
i
=
0
;
i
<
AUTO_PIN_LAST
;
i
++
)
{
hda_nid_t
pin
=
cfg
->
input_pins
[
i
];
if
(
!
pin
)
continue
;
for
(
i
=
0
;
i
<
cfg
->
num_inputs
;
i
++
)
{
hda_nid_t
pin
=
cfg
->
inputs
[
i
].
pin
;
spec
->
input_idx
[
spec
->
num_inputs
]
=
i
;
spec
->
capsrc_idx
[
i
]
=
spec
->
num_inputs
++
;
spec
->
cur_input
=
i
;
...
...
@@ -438,16 +437,17 @@ static int parse_input(struct hda_codec *codec)
/* check whether the automatic mic switch is available */
if
(
spec
->
num_inputs
==
2
&&
spec
->
adc_nid
[
AUTO_PIN_MIC
]
&&
spec
->
adc_nid
[
AUTO_PIN_FRONT_MIC
])
{
if
(
is_ext_mic
(
codec
,
cfg
->
input_pins
[
AUTO_PIN_FRONT_MIC
]))
{
if
(
!
is_ext_mic
(
codec
,
cfg
->
input_pins
[
AUTO_PIN_MIC
]))
{
cfg
->
inputs
[
0
].
type
==
AUTO_PIN_MIC
&&
cfg
->
inputs
[
1
].
type
==
AUTO_PIN_MIC
)
{
if
(
is_ext_mic
(
codec
,
cfg
->
inputs
[
0
].
pin
))
{
if
(
!
is_ext_mic
(
codec
,
cfg
->
inputs
[
1
].
pin
))
{
spec
->
mic_detect
=
1
;
spec
->
automic_idx
=
AUTO_PIN_FRONT_MIC
;
spec
->
automic_idx
=
0
;
}
}
else
{
if
(
is_ext_mic
(
codec
,
cfg
->
input
_pins
[
AUTO_PIN_MIC
]
))
{
if
(
is_ext_mic
(
codec
,
cfg
->
input
s
[
1
].
pin
))
{
spec
->
mic_detect
=
1
;
spec
->
automic_idx
=
AUTO_PIN_MIC
;
spec
->
automic_idx
=
1
;
}
}
}
...
...
@@ -674,6 +674,7 @@ static int cs_capture_source_info(struct snd_kcontrol *kcontrol,
{
struct
hda_codec
*
codec
=
snd_kcontrol_chip
(
kcontrol
);
struct
cs_spec
*
spec
=
codec
->
spec
;
struct
auto_pin_cfg
*
cfg
=
&
spec
->
autocfg
;
unsigned
int
idx
;
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
...
...
@@ -682,7 +683,8 @@ static int cs_capture_source_info(struct snd_kcontrol *kcontrol,
if
(
uinfo
->
value
.
enumerated
.
item
>=
spec
->
num_inputs
)
uinfo
->
value
.
enumerated
.
item
=
spec
->
num_inputs
-
1
;
idx
=
spec
->
input_idx
[
uinfo
->
value
.
enumerated
.
item
];
strcpy
(
uinfo
->
value
.
enumerated
.
name
,
auto_pin_cfg_labels
[
idx
]);
strcpy
(
uinfo
->
value
.
enumerated
.
name
,
hda_get_input_pin_label
(
codec
,
cfg
->
inputs
[
idx
].
pin
,
1
));
return
0
;
}
...
...
@@ -740,6 +742,27 @@ static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec,
return
bind
;
}
/* add a (input-boost) volume control to the given input pin */
static
int
add_input_volume_control
(
struct
hda_codec
*
codec
,
struct
auto_pin_cfg
*
cfg
,
int
item
)
{
hda_nid_t
pin
=
cfg
->
inputs
[
item
].
pin
;
u32
caps
;
const
char
*
label
;
struct
snd_kcontrol
*
kctl
;
if
(
!
(
get_wcaps
(
codec
,
pin
)
&
AC_WCAP_IN_AMP
))
return
0
;
caps
=
query_amp_caps
(
codec
,
pin
,
HDA_INPUT
);
caps
=
(
caps
&
AC_AMPCAP_NUM_STEPS
)
>>
AC_AMPCAP_NUM_STEPS_SHIFT
;
if
(
caps
<=
1
)
return
0
;
label
=
hda_get_autocfg_input_label
(
codec
,
cfg
,
item
);
return
add_volume
(
codec
,
label
,
0
,
HDA_COMPOSE_AMP_VAL
(
pin
,
3
,
0
,
HDA_INPUT
),
1
,
&
kctl
);
}
static
int
build_input
(
struct
hda_codec
*
codec
)
{
struct
cs_spec
*
spec
=
codec
->
spec
;
...
...
@@ -779,6 +802,12 @@ static int build_input(struct hda_codec *codec)
return
err
;
}
for
(
i
=
0
;
i
<
spec
->
num_inputs
;
i
++
)
{
err
=
add_input_volume_control
(
codec
,
&
spec
->
autocfg
,
i
);
if
(
err
<
0
)
return
err
;
}
return
0
;
}
...
...
@@ -838,7 +867,8 @@ static void cs_automute(struct hda_codec *codec)
AC_VERB_SET_PIN_WIDGET_CONTROL
,
hp_present
?
0
:
PIN_OUT
);
}
if
(
spec
->
board_config
==
CS420X_MBP55
||
if
(
spec
->
board_config
==
CS420X_MBP53
||
spec
->
board_config
==
CS420X_MBP55
||
spec
->
board_config
==
CS420X_IMAC27
)
{
unsigned
int
gpio
=
hp_present
?
0x02
:
0x08
;
snd_hda_codec_write
(
codec
,
0x01
,
0
,
...
...
@@ -853,15 +883,12 @@ static void cs_automic(struct hda_codec *codec)
hda_nid_t
nid
;
unsigned
int
present
;
nid
=
cfg
->
input
_pins
[
spec
->
automic_idx
]
;
nid
=
cfg
->
input
s
[
spec
->
automic_idx
].
pin
;
present
=
snd_hda_jack_detect
(
codec
,
nid
);
if
(
present
)
change_cur_input
(
codec
,
spec
->
automic_idx
,
0
);
else
{
unsigned
int
imic
=
(
spec
->
automic_idx
==
AUTO_PIN_MIC
)
?
AUTO_PIN_FRONT_MIC
:
AUTO_PIN_MIC
;
change_cur_input
(
codec
,
imic
,
0
);
}
else
change_cur_input
(
codec
,
!
spec
->
automic_idx
,
0
);
}
/*
...
...
@@ -918,14 +945,14 @@ static void init_input(struct hda_codec *codec)
unsigned
int
coef
;
int
i
;
for
(
i
=
0
;
i
<
AUTO_PIN_LAST
;
i
++
)
{
for
(
i
=
0
;
i
<
cfg
->
num_inputs
;
i
++
)
{
unsigned
int
ctl
;
hda_nid_t
pin
=
cfg
->
input
_pins
[
i
]
;
if
(
!
pin
||
!
spec
->
adc_nid
[
i
])
hda_nid_t
pin
=
cfg
->
input
s
[
i
].
pin
;
if
(
!
spec
->
adc_nid
[
i
])
continue
;
/* set appropriate pin control and mute first */
ctl
=
PIN_IN
;
if
(
i
<=
AUTO_PIN_FRONT
_MIC
)
{
if
(
cfg
->
inputs
[
i
].
type
==
AUTO_PIN
_MIC
)
{
unsigned
int
caps
=
snd_hda_query_pin_caps
(
codec
,
pin
);
caps
>>=
AC_PINCAP_VREF_SHIFT
;
if
(
caps
&
AC_PINCAP_VREF_80
)
...
...
@@ -1130,6 +1157,7 @@ static int cs_parse_auto_config(struct hda_codec *codec)
}
static
const
char
*
cs420x_models
[
CS420X_MODELS
]
=
{
[
CS420X_MBP53
]
=
"mbp53"
,
[
CS420X_MBP55
]
=
"mbp55"
,
[
CS420X_IMAC27
]
=
"imac27"
,
[
CS420X_AUTO
]
=
"auto"
,
...
...
@@ -1137,7 +1165,9 @@ static const char *cs420x_models[CS420X_MODELS] = {
static
struct
snd_pci_quirk
cs420x_cfg_tbl
[]
=
{
SND_PCI_QUIRK
(
0x10de
,
0x0ac0
,
"MacBookPro 5,3"
,
CS420X_MBP53
),
SND_PCI_QUIRK
(
0x10de
,
0xcb79
,
"MacBookPro 5,5"
,
CS420X_MBP55
),
SND_PCI_QUIRK
(
0x10de
,
0xcb89
,
"MacBookPro 7,1"
,
CS420X_MBP55
),
SND_PCI_QUIRK
(
0x8086
,
0x7270
,
"IMac 27 Inch"
,
CS420X_IMAC27
),
{}
/* terminator */
};
...
...
@@ -1147,6 +1177,20 @@ struct cs_pincfg {
u32
val
;
};
static
struct
cs_pincfg
mbp53_pincfgs
[]
=
{
{
0x09
,
0x012b4050
},
{
0x0a
,
0x90100141
},
{
0x0b
,
0x90100140
},
{
0x0c
,
0x018b3020
},
{
0x0d
,
0x90a00110
},
{
0x0e
,
0x400000f0
},
{
0x0f
,
0x01cbe030
},
{
0x10
,
0x014be060
},
{
0x12
,
0x400000f0
},
{
0x15
,
0x400000f0
},
{}
/* terminator */
};
static
struct
cs_pincfg
mbp55_pincfgs
[]
=
{
{
0x09
,
0x012b4030
},
{
0x0a
,
0x90100121
},
...
...
@@ -1176,6 +1220,7 @@ static struct cs_pincfg imac27_pincfgs[] = {
};
static
struct
cs_pincfg
*
cs_pincfgs
[
CS420X_MODELS
]
=
{
[
CS420X_MBP53
]
=
mbp53_pincfgs
,
[
CS420X_MBP55
]
=
mbp55_pincfgs
,
[
CS420X_IMAC27
]
=
imac27_pincfgs
,
};
...
...
@@ -1208,6 +1253,7 @@ static int patch_cs420x(struct hda_codec *codec)
switch
(
spec
->
board_config
)
{
case
CS420X_IMAC27
:
case
CS420X_MBP53
:
case
CS420X_MBP55
:
/* GPIO1 = headphones */
/* GPIO3 = speakers */
...
...
sound/pci/hda/patch_conexant.c
浏览文件 @
506ecbca
此差异已折叠。
点击以展开。
sound/pci/hda/patch_hdmi.c
浏览文件 @
506ecbca
此差异已折叠。
点击以展开。
sound/pci/hda/patch_intelhdmi.c
已删除
100644 → 0
浏览文件 @
aa5c14d5
/*
*
* patch_intelhdmi.c - Patch for Intel HDMI codecs
*
* Copyright(c) 2008 Intel Corporation. All rights reserved.
*
* Authors:
* Jiang Zhe <zhe.jiang@intel.com>
* Wu Fengguang <wfg@linux.intel.com>
*
* Maintained by:
* Wu Fengguang <wfg@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_local.h"
/*
* The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
* could support two independent pipes, each of them can be connected to one or
* more ports (DVI, HDMI or DisplayPort).
*
* The HDA correspondence of pipes/ports are converter/pin nodes.
*/
#define MAX_HDMI_CVTS 3
#define MAX_HDMI_PINS 3
#include "patch_hdmi.c"
static
char
*
intel_hdmi_pcm_names
[
MAX_HDMI_CVTS
]
=
{
"INTEL HDMI 0"
,
"INTEL HDMI 1"
,
"INTEL HDMI 2"
,
};
/*
* HDMI callbacks
*/
static
int
intel_hdmi_playback_pcm_prepare
(
struct
hda_pcm_stream
*
hinfo
,
struct
hda_codec
*
codec
,
unsigned
int
stream_tag
,
unsigned
int
format
,
struct
snd_pcm_substream
*
substream
)
{
hdmi_set_channel_count
(
codec
,
hinfo
->
nid
,
substream
->
runtime
->
channels
);
hdmi_setup_audio_infoframe
(
codec
,
hinfo
->
nid
,
substream
);
return
hdmi_setup_stream
(
codec
,
hinfo
->
nid
,
stream_tag
,
format
);
}
static
struct
hda_pcm_stream
intel_hdmi_pcm_playback
=
{
.
substreams
=
1
,
.
channels_min
=
2
,
.
ops
=
{
.
open
=
hdmi_pcm_open
,
.
prepare
=
intel_hdmi_playback_pcm_prepare
,
},
};
static
int
intel_hdmi_build_pcms
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
struct
hda_pcm
*
info
=
spec
->
pcm_rec
;
int
i
;
codec
->
num_pcms
=
spec
->
num_cvts
;
codec
->
pcm_info
=
info
;
for
(
i
=
0
;
i
<
codec
->
num_pcms
;
i
++
,
info
++
)
{
unsigned
int
chans
;
chans
=
get_wcaps
(
codec
,
spec
->
cvt
[
i
]);
chans
=
get_wcaps_channels
(
chans
);
info
->
name
=
intel_hdmi_pcm_names
[
i
];
info
->
pcm_type
=
HDA_PCM_TYPE_HDMI
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
intel_hdmi_pcm_playback
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
nid
=
spec
->
cvt
[
i
];
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
channels_max
=
chans
;
}
return
0
;
}
static
int
intel_hdmi_build_controls
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
int
err
;
int
i
;
for
(
i
=
0
;
i
<
codec
->
num_pcms
;
i
++
)
{
err
=
snd_hda_create_spdif_out_ctls
(
codec
,
spec
->
cvt
[
i
]);
if
(
err
<
0
)
return
err
;
}
return
0
;
}
static
int
intel_hdmi_init
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
int
i
;
for
(
i
=
0
;
spec
->
pin
[
i
];
i
++
)
{
hdmi_enable_output
(
codec
,
spec
->
pin
[
i
]);
snd_hda_codec_write
(
codec
,
spec
->
pin
[
i
],
0
,
AC_VERB_SET_UNSOLICITED_ENABLE
,
AC_USRSP_EN
|
spec
->
pin
[
i
]);
}
return
0
;
}
static
void
intel_hdmi_free
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
int
i
;
for
(
i
=
0
;
i
<
spec
->
num_pins
;
i
++
)
snd_hda_eld_proc_free
(
codec
,
&
spec
->
sink_eld
[
i
]);
kfree
(
spec
);
}
static
struct
hda_codec_ops
intel_hdmi_patch_ops
=
{
.
init
=
intel_hdmi_init
,
.
free
=
intel_hdmi_free
,
.
build_pcms
=
intel_hdmi_build_pcms
,
.
build_controls
=
intel_hdmi_build_controls
,
.
unsol_event
=
hdmi_unsol_event
,
};
static
int
patch_intel_hdmi
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
;
int
i
;
spec
=
kzalloc
(
sizeof
(
*
spec
),
GFP_KERNEL
);
if
(
spec
==
NULL
)
return
-
ENOMEM
;
codec
->
spec
=
spec
;
if
(
hdmi_parse_codec
(
codec
)
<
0
)
{
codec
->
spec
=
NULL
;
kfree
(
spec
);
return
-
EINVAL
;
}
codec
->
patch_ops
=
intel_hdmi_patch_ops
;
for
(
i
=
0
;
i
<
spec
->
num_pins
;
i
++
)
snd_hda_eld_proc_new
(
codec
,
&
spec
->
sink_eld
[
i
],
i
);
init_channel_allocations
();
return
0
;
}
static
struct
hda_codec_preset
snd_hda_preset_intelhdmi
[]
=
{
{
.
id
=
0x808629fb
,
.
name
=
"Crestline HDMI"
,
.
patch
=
patch_intel_hdmi
},
{
.
id
=
0x80862801
,
.
name
=
"Bearlake HDMI"
,
.
patch
=
patch_intel_hdmi
},
{
.
id
=
0x80862802
,
.
name
=
"Cantiga HDMI"
,
.
patch
=
patch_intel_hdmi
},
{
.
id
=
0x80862803
,
.
name
=
"Eaglelake HDMI"
,
.
patch
=
patch_intel_hdmi
},
{
.
id
=
0x80862804
,
.
name
=
"IbexPeak HDMI"
,
.
patch
=
patch_intel_hdmi
},
{
.
id
=
0x80860054
,
.
name
=
"IbexPeak HDMI"
,
.
patch
=
patch_intel_hdmi
},
{
.
id
=
0x80862805
,
.
name
=
"CougarPoint HDMI"
,
.
patch
=
patch_intel_hdmi
},
{
.
id
=
0x10951392
,
.
name
=
"SiI1392 HDMI"
,
.
patch
=
patch_intel_hdmi
},
{}
/* terminator */
};
MODULE_ALIAS
(
"snd-hda-codec-id:808629fb"
);
MODULE_ALIAS
(
"snd-hda-codec-id:80862801"
);
MODULE_ALIAS
(
"snd-hda-codec-id:80862802"
);
MODULE_ALIAS
(
"snd-hda-codec-id:80862803"
);
MODULE_ALIAS
(
"snd-hda-codec-id:80862804"
);
MODULE_ALIAS
(
"snd-hda-codec-id:80862805"
);
MODULE_ALIAS
(
"snd-hda-codec-id:80860054"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10951392"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Intel HDMI HD-audio codec"
);
static
struct
hda_codec_preset_list
intel_list
=
{
.
preset
=
snd_hda_preset_intelhdmi
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_intelhdmi_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
intel_list
);
}
static
void
__exit
patch_intelhdmi_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
intel_list
);
}
module_init
(
patch_intelhdmi_init
)
module_exit
(
patch_intelhdmi_exit
)
sound/pci/hda/patch_nvhdmi.c
已删除
100644 → 0
浏览文件 @
aa5c14d5
/*
* Universal Interface for Intel High Definition Audio Codec
*
* HD audio interface patch for NVIDIA HDMI codecs
*
* Copyright (c) 2008 NVIDIA Corp. All rights reserved.
* Copyright (c) 2008 Wei Ni <wni@nvidia.com>
*
*
* This driver is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This driver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_local.h"
#define MAX_HDMI_CVTS 1
#define MAX_HDMI_PINS 1
#include "patch_hdmi.c"
static
char
*
nvhdmi_pcm_names
[
MAX_HDMI_CVTS
]
=
{
"NVIDIA HDMI"
,
};
/* define below to restrict the supported rates and formats */
/* #define LIMITED_RATE_FMT_SUPPORT */
enum
HDACodec
{
HDA_CODEC_NVIDIA_MCP7X
,
HDA_CODEC_NVIDIA_MCP89
,
HDA_CODEC_NVIDIA_GT21X
,
HDA_CODEC_INVALID
};
#define Nv_VERB_SET_Channel_Allocation 0xF79
#define Nv_VERB_SET_Info_Frame_Checksum 0xF7A
#define Nv_VERB_SET_Audio_Protection_On 0xF98
#define Nv_VERB_SET_Audio_Protection_Off 0xF99
#define nvhdmi_master_con_nid_7x 0x04
#define nvhdmi_master_pin_nid_7x 0x05
#define nvhdmi_master_con_nid_89 0x04
#define nvhdmi_master_pin_nid_89 0x05
static
hda_nid_t
nvhdmi_con_nids_7x
[
4
]
=
{
/*front, rear, clfe, rear_surr */
0x6
,
0x8
,
0xa
,
0xc
,
};
static
struct
hda_verb
nvhdmi_basic_init_7x
[]
=
{
/* set audio protect on */
{
0x1
,
Nv_VERB_SET_Audio_Protection_On
,
0x1
},
/* enable digital output on pin widget */
{
0x5
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_OUT
|
0x5
},
{
0x7
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_OUT
|
0x5
},
{
0x9
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_OUT
|
0x5
},
{
0xb
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_OUT
|
0x5
},
{
0xd
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_OUT
|
0x5
},
{}
/* terminator */
};
#ifdef LIMITED_RATE_FMT_SUPPORT
/* support only the safe format and rate */
#define SUPPORTED_RATES SNDRV_PCM_RATE_48000
#define SUPPORTED_MAXBPS 16
#define SUPPORTED_FORMATS SNDRV_PCM_FMTBIT_S16_LE
#else
/* support all rates and formats */
#define SUPPORTED_RATES \
(SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
SNDRV_PCM_RATE_192000)
#define SUPPORTED_MAXBPS 24
#define SUPPORTED_FORMATS \
(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
#endif
/*
* Controls
*/
static
int
nvhdmi_build_controls
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
int
err
;
int
i
;
if
((
spec
->
codec_type
==
HDA_CODEC_NVIDIA_MCP89
)
||
(
spec
->
codec_type
==
HDA_CODEC_NVIDIA_GT21X
))
{
for
(
i
=
0
;
i
<
codec
->
num_pcms
;
i
++
)
{
err
=
snd_hda_create_spdif_out_ctls
(
codec
,
spec
->
cvt
[
i
]);
if
(
err
<
0
)
return
err
;
}
}
else
{
err
=
snd_hda_create_spdif_out_ctls
(
codec
,
spec
->
multiout
.
dig_out_nid
);
if
(
err
<
0
)
return
err
;
}
return
0
;
}
static
int
nvhdmi_init
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
int
i
;
if
((
spec
->
codec_type
==
HDA_CODEC_NVIDIA_MCP89
)
||
(
spec
->
codec_type
==
HDA_CODEC_NVIDIA_GT21X
))
{
for
(
i
=
0
;
spec
->
pin
[
i
];
i
++
)
{
hdmi_enable_output
(
codec
,
spec
->
pin
[
i
]);
snd_hda_codec_write
(
codec
,
spec
->
pin
[
i
],
0
,
AC_VERB_SET_UNSOLICITED_ENABLE
,
AC_USRSP_EN
|
spec
->
pin
[
i
]);
}
}
else
{
snd_hda_sequence_write
(
codec
,
nvhdmi_basic_init_7x
);
}
return
0
;
}
static
void
nvhdmi_free
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
int
i
;
if
((
spec
->
codec_type
==
HDA_CODEC_NVIDIA_MCP89
)
||
(
spec
->
codec_type
==
HDA_CODEC_NVIDIA_GT21X
))
{
for
(
i
=
0
;
i
<
spec
->
num_pins
;
i
++
)
snd_hda_eld_proc_free
(
codec
,
&
spec
->
sink_eld
[
i
]);
}
kfree
(
spec
);
}
/*
* Digital out
*/
static
int
nvhdmi_dig_playback_pcm_open
(
struct
hda_pcm_stream
*
hinfo
,
struct
hda_codec
*
codec
,
struct
snd_pcm_substream
*
substream
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
return
snd_hda_multi_out_dig_open
(
codec
,
&
spec
->
multiout
);
}
static
int
nvhdmi_dig_playback_pcm_close_8ch_7x
(
struct
hda_pcm_stream
*
hinfo
,
struct
hda_codec
*
codec
,
struct
snd_pcm_substream
*
substream
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
int
i
;
snd_hda_codec_write
(
codec
,
nvhdmi_master_con_nid_7x
,
0
,
AC_VERB_SET_CHANNEL_STREAMID
,
0
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
/* set the stream id */
snd_hda_codec_write
(
codec
,
nvhdmi_con_nids_7x
[
i
],
0
,
AC_VERB_SET_CHANNEL_STREAMID
,
0
);
/* set the stream format */
snd_hda_codec_write
(
codec
,
nvhdmi_con_nids_7x
[
i
],
0
,
AC_VERB_SET_STREAM_FORMAT
,
0
);
}
return
snd_hda_multi_out_dig_close
(
codec
,
&
spec
->
multiout
);
}
static
int
nvhdmi_dig_playback_pcm_close_2ch
(
struct
hda_pcm_stream
*
hinfo
,
struct
hda_codec
*
codec
,
struct
snd_pcm_substream
*
substream
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
return
snd_hda_multi_out_dig_close
(
codec
,
&
spec
->
multiout
);
}
static
int
nvhdmi_dig_playback_pcm_prepare_8ch_89
(
struct
hda_pcm_stream
*
hinfo
,
struct
hda_codec
*
codec
,
unsigned
int
stream_tag
,
unsigned
int
format
,
struct
snd_pcm_substream
*
substream
)
{
hdmi_set_channel_count
(
codec
,
hinfo
->
nid
,
substream
->
runtime
->
channels
);
hdmi_setup_audio_infoframe
(
codec
,
hinfo
->
nid
,
substream
);
return
hdmi_setup_stream
(
codec
,
hinfo
->
nid
,
stream_tag
,
format
);
}
static
int
nvhdmi_dig_playback_pcm_prepare_8ch
(
struct
hda_pcm_stream
*
hinfo
,
struct
hda_codec
*
codec
,
unsigned
int
stream_tag
,
unsigned
int
format
,
struct
snd_pcm_substream
*
substream
)
{
int
chs
;
unsigned
int
dataDCC1
,
dataDCC2
,
chan
,
chanmask
,
channel_id
;
int
i
;
mutex_lock
(
&
codec
->
spdif_mutex
);
chs
=
substream
->
runtime
->
channels
;
chan
=
chs
?
(
chs
-
1
)
:
1
;
switch
(
chs
)
{
default:
case
0
:
case
2
:
chanmask
=
0x00
;
break
;
case
4
:
chanmask
=
0x08
;
break
;
case
6
:
chanmask
=
0x0b
;
break
;
case
8
:
chanmask
=
0x13
;
break
;
}
dataDCC1
=
AC_DIG1_ENABLE
|
AC_DIG1_COPYRIGHT
;
dataDCC2
=
0x2
;
/* set the Audio InforFrame Channel Allocation */
snd_hda_codec_write
(
codec
,
0x1
,
0
,
Nv_VERB_SET_Channel_Allocation
,
chanmask
);
/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
if
(
codec
->
spdif_status_reset
&&
(
codec
->
spdif_ctls
&
AC_DIG1_ENABLE
))
snd_hda_codec_write
(
codec
,
nvhdmi_master_con_nid_7x
,
0
,
AC_VERB_SET_DIGI_CONVERT_1
,
codec
->
spdif_ctls
&
~
AC_DIG1_ENABLE
&
0xff
);
/* set the stream id */
snd_hda_codec_write
(
codec
,
nvhdmi_master_con_nid_7x
,
0
,
AC_VERB_SET_CHANNEL_STREAMID
,
(
stream_tag
<<
4
)
|
0x0
);
/* set the stream format */
snd_hda_codec_write
(
codec
,
nvhdmi_master_con_nid_7x
,
0
,
AC_VERB_SET_STREAM_FORMAT
,
format
);
/* turn on again (if needed) */
/* enable and set the channel status audio/data flag */
if
(
codec
->
spdif_status_reset
&&
(
codec
->
spdif_ctls
&
AC_DIG1_ENABLE
))
{
snd_hda_codec_write
(
codec
,
nvhdmi_master_con_nid_7x
,
0
,
AC_VERB_SET_DIGI_CONVERT_1
,
codec
->
spdif_ctls
&
0xff
);
snd_hda_codec_write
(
codec
,
nvhdmi_master_con_nid_7x
,
0
,
AC_VERB_SET_DIGI_CONVERT_2
,
dataDCC2
);
}
for
(
i
=
0
;
i
<
4
;
i
++
)
{
if
(
chs
==
2
)
channel_id
=
0
;
else
channel_id
=
i
*
2
;
/* turn off SPDIF once;
*otherwise the IEC958 bits won't be updated
*/
if
(
codec
->
spdif_status_reset
&&
(
codec
->
spdif_ctls
&
AC_DIG1_ENABLE
))
snd_hda_codec_write
(
codec
,
nvhdmi_con_nids_7x
[
i
],
0
,
AC_VERB_SET_DIGI_CONVERT_1
,
codec
->
spdif_ctls
&
~
AC_DIG1_ENABLE
&
0xff
);
/* set the stream id */
snd_hda_codec_write
(
codec
,
nvhdmi_con_nids_7x
[
i
],
0
,
AC_VERB_SET_CHANNEL_STREAMID
,
(
stream_tag
<<
4
)
|
channel_id
);
/* set the stream format */
snd_hda_codec_write
(
codec
,
nvhdmi_con_nids_7x
[
i
],
0
,
AC_VERB_SET_STREAM_FORMAT
,
format
);
/* turn on again (if needed) */
/* enable and set the channel status audio/data flag */
if
(
codec
->
spdif_status_reset
&&
(
codec
->
spdif_ctls
&
AC_DIG1_ENABLE
))
{
snd_hda_codec_write
(
codec
,
nvhdmi_con_nids_7x
[
i
],
0
,
AC_VERB_SET_DIGI_CONVERT_1
,
codec
->
spdif_ctls
&
0xff
);
snd_hda_codec_write
(
codec
,
nvhdmi_con_nids_7x
[
i
],
0
,
AC_VERB_SET_DIGI_CONVERT_2
,
dataDCC2
);
}
}
/* set the Audio Info Frame Checksum */
snd_hda_codec_write
(
codec
,
0x1
,
0
,
Nv_VERB_SET_Info_Frame_Checksum
,
(
0x71
-
chan
-
chanmask
));
mutex_unlock
(
&
codec
->
spdif_mutex
);
return
0
;
}
static
int
nvhdmi_dig_playback_pcm_prepare_2ch
(
struct
hda_pcm_stream
*
hinfo
,
struct
hda_codec
*
codec
,
unsigned
int
stream_tag
,
unsigned
int
format
,
struct
snd_pcm_substream
*
substream
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
return
snd_hda_multi_out_dig_prepare
(
codec
,
&
spec
->
multiout
,
stream_tag
,
format
,
substream
);
}
static
struct
hda_pcm_stream
nvhdmi_pcm_digital_playback_8ch_89
=
{
.
substreams
=
1
,
.
channels_min
=
2
,
.
ops
=
{
.
open
=
hdmi_pcm_open
,
.
prepare
=
nvhdmi_dig_playback_pcm_prepare_8ch_89
,
},
};
static
struct
hda_pcm_stream
nvhdmi_pcm_digital_playback_8ch_7x
=
{
.
substreams
=
1
,
.
channels_min
=
2
,
.
channels_max
=
8
,
.
nid
=
nvhdmi_master_con_nid_7x
,
.
rates
=
SUPPORTED_RATES
,
.
maxbps
=
SUPPORTED_MAXBPS
,
.
formats
=
SUPPORTED_FORMATS
,
.
ops
=
{
.
open
=
nvhdmi_dig_playback_pcm_open
,
.
close
=
nvhdmi_dig_playback_pcm_close_8ch_7x
,
.
prepare
=
nvhdmi_dig_playback_pcm_prepare_8ch
},
};
static
struct
hda_pcm_stream
nvhdmi_pcm_digital_playback_2ch
=
{
.
substreams
=
1
,
.
channels_min
=
2
,
.
channels_max
=
2
,
.
nid
=
nvhdmi_master_con_nid_7x
,
.
rates
=
SUPPORTED_RATES
,
.
maxbps
=
SUPPORTED_MAXBPS
,
.
formats
=
SUPPORTED_FORMATS
,
.
ops
=
{
.
open
=
nvhdmi_dig_playback_pcm_open
,
.
close
=
nvhdmi_dig_playback_pcm_close_2ch
,
.
prepare
=
nvhdmi_dig_playback_pcm_prepare_2ch
},
};
static
int
nvhdmi_build_pcms_8ch_89
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
struct
hda_pcm
*
info
=
spec
->
pcm_rec
;
int
i
;
codec
->
num_pcms
=
spec
->
num_cvts
;
codec
->
pcm_info
=
info
;
for
(
i
=
0
;
i
<
codec
->
num_pcms
;
i
++
,
info
++
)
{
unsigned
int
chans
;
chans
=
get_wcaps
(
codec
,
spec
->
cvt
[
i
]);
chans
=
get_wcaps_channels
(
chans
);
info
->
name
=
nvhdmi_pcm_names
[
i
];
info
->
pcm_type
=
HDA_PCM_TYPE_HDMI
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
nvhdmi_pcm_digital_playback_8ch_89
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
nid
=
spec
->
cvt
[
i
];
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
channels_max
=
chans
;
}
return
0
;
}
static
int
nvhdmi_build_pcms_8ch_7x
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
struct
hda_pcm
*
info
=
spec
->
pcm_rec
;
codec
->
num_pcms
=
1
;
codec
->
pcm_info
=
info
;
info
->
name
=
"NVIDIA HDMI"
;
info
->
pcm_type
=
HDA_PCM_TYPE_HDMI
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
nvhdmi_pcm_digital_playback_8ch_7x
;
return
0
;
}
static
int
nvhdmi_build_pcms_2ch
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
=
codec
->
spec
;
struct
hda_pcm
*
info
=
spec
->
pcm_rec
;
codec
->
num_pcms
=
1
;
codec
->
pcm_info
=
info
;
info
->
name
=
"NVIDIA HDMI"
;
info
->
pcm_type
=
HDA_PCM_TYPE_HDMI
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
nvhdmi_pcm_digital_playback_2ch
;
return
0
;
}
static
struct
hda_codec_ops
nvhdmi_patch_ops_8ch_89
=
{
.
build_controls
=
nvhdmi_build_controls
,
.
build_pcms
=
nvhdmi_build_pcms_8ch_89
,
.
init
=
nvhdmi_init
,
.
free
=
nvhdmi_free
,
.
unsol_event
=
hdmi_unsol_event
,
};
static
struct
hda_codec_ops
nvhdmi_patch_ops_8ch_7x
=
{
.
build_controls
=
nvhdmi_build_controls
,
.
build_pcms
=
nvhdmi_build_pcms_8ch_7x
,
.
init
=
nvhdmi_init
,
.
free
=
nvhdmi_free
,
};
static
struct
hda_codec_ops
nvhdmi_patch_ops_2ch
=
{
.
build_controls
=
nvhdmi_build_controls
,
.
build_pcms
=
nvhdmi_build_pcms_2ch
,
.
init
=
nvhdmi_init
,
.
free
=
nvhdmi_free
,
};
static
int
patch_nvhdmi_8ch_89
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
;
int
i
;
spec
=
kzalloc
(
sizeof
(
*
spec
),
GFP_KERNEL
);
if
(
spec
==
NULL
)
return
-
ENOMEM
;
codec
->
spec
=
spec
;
spec
->
codec_type
=
HDA_CODEC_NVIDIA_MCP89
;
spec
->
old_pin_detect
=
1
;
if
(
hdmi_parse_codec
(
codec
)
<
0
)
{
codec
->
spec
=
NULL
;
kfree
(
spec
);
return
-
EINVAL
;
}
codec
->
patch_ops
=
nvhdmi_patch_ops_8ch_89
;
for
(
i
=
0
;
i
<
spec
->
num_pins
;
i
++
)
snd_hda_eld_proc_new
(
codec
,
&
spec
->
sink_eld
[
i
],
i
);
init_channel_allocations
();
return
0
;
}
static
int
patch_nvhdmi_8ch_7x
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
;
spec
=
kzalloc
(
sizeof
(
*
spec
),
GFP_KERNEL
);
if
(
spec
==
NULL
)
return
-
ENOMEM
;
codec
->
spec
=
spec
;
spec
->
multiout
.
num_dacs
=
0
;
/* no analog */
spec
->
multiout
.
max_channels
=
8
;
spec
->
multiout
.
dig_out_nid
=
nvhdmi_master_con_nid_7x
;
spec
->
codec_type
=
HDA_CODEC_NVIDIA_MCP7X
;
spec
->
old_pin_detect
=
1
;
codec
->
patch_ops
=
nvhdmi_patch_ops_8ch_7x
;
return
0
;
}
static
int
patch_nvhdmi_2ch
(
struct
hda_codec
*
codec
)
{
struct
hdmi_spec
*
spec
;
spec
=
kzalloc
(
sizeof
(
*
spec
),
GFP_KERNEL
);
if
(
spec
==
NULL
)
return
-
ENOMEM
;
codec
->
spec
=
spec
;
spec
->
multiout
.
num_dacs
=
0
;
/* no analog */
spec
->
multiout
.
max_channels
=
2
;
spec
->
multiout
.
dig_out_nid
=
nvhdmi_master_con_nid_7x
;
spec
->
codec_type
=
HDA_CODEC_NVIDIA_MCP7X
;
spec
->
old_pin_detect
=
1
;
codec
->
patch_ops
=
nvhdmi_patch_ops_2ch
;
return
0
;
}
/*
* patch entries
*/
static
struct
hda_codec_preset
snd_hda_preset_nvhdmi
[]
=
{
{
.
id
=
0x10de0002
,
.
name
=
"MCP77/78 HDMI"
,
.
patch
=
patch_nvhdmi_8ch_7x
},
{
.
id
=
0x10de0003
,
.
name
=
"MCP77/78 HDMI"
,
.
patch
=
patch_nvhdmi_8ch_7x
},
{
.
id
=
0x10de0005
,
.
name
=
"MCP77/78 HDMI"
,
.
patch
=
patch_nvhdmi_8ch_7x
},
{
.
id
=
0x10de0006
,
.
name
=
"MCP77/78 HDMI"
,
.
patch
=
patch_nvhdmi_8ch_7x
},
{
.
id
=
0x10de0007
,
.
name
=
"MCP79/7A HDMI"
,
.
patch
=
patch_nvhdmi_8ch_7x
},
{
.
id
=
0x10de000a
,
.
name
=
"GPU 0a HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de000b
,
.
name
=
"GPU 0b HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de000c
,
.
name
=
"MCP89 HDMI"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de000d
,
.
name
=
"GPU 0d HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0010
,
.
name
=
"GPU 10 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0011
,
.
name
=
"GPU 11 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0012
,
.
name
=
"GPU 12 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0013
,
.
name
=
"GPU 13 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0014
,
.
name
=
"GPU 14 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0018
,
.
name
=
"GPU 18 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0019
,
.
name
=
"GPU 19 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de001a
,
.
name
=
"GPU 1a HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de001b
,
.
name
=
"GPU 1b HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de001c
,
.
name
=
"GPU 1c HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0040
,
.
name
=
"GPU 40 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0041
,
.
name
=
"GPU 41 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0042
,
.
name
=
"GPU 42 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0043
,
.
name
=
"GPU 43 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0044
,
.
name
=
"GPU 44 HDMI/DP"
,
.
patch
=
patch_nvhdmi_8ch_89
},
{
.
id
=
0x10de0067
,
.
name
=
"MCP67 HDMI"
,
.
patch
=
patch_nvhdmi_2ch
},
{
.
id
=
0x10de8001
,
.
name
=
"MCP73 HDMI"
,
.
patch
=
patch_nvhdmi_2ch
},
{}
/* terminator */
};
MODULE_ALIAS
(
"snd-hda-codec-id:10de0002"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0003"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0005"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0006"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0007"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de000a"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de000b"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de000c"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de000d"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0010"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0011"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0012"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0013"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0014"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0018"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0019"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de001a"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de001b"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de001c"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0040"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0041"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0042"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0043"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0044"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de0067"
);
MODULE_ALIAS
(
"snd-hda-codec-id:10de8001"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"NVIDIA HDMI HD-audio codec"
);
static
struct
hda_codec_preset_list
nvhdmi_list
=
{
.
preset
=
snd_hda_preset_nvhdmi
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_nvhdmi_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
nvhdmi_list
);
}
static
void
__exit
patch_nvhdmi_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
nvhdmi_list
);
}
module_init
(
patch_nvhdmi_init
)
module_exit
(
patch_nvhdmi_exit
)
sound/pci/hda/patch_realtek.c
浏览文件 @
506ecbca
此差异已折叠。
点击以展开。
sound/pci/hda/patch_sigmatel.c
浏览文件 @
506ecbca
此差异已折叠。
点击以展开。
sound/pci/hda/patch_via.c
浏览文件 @
506ecbca
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录