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
nexedi
linux
Commits
8f88f025
Commit
8f88f025
authored
Mar 16, 2015
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/hda-bus' into for-next
parents
34e72afe
820cc6cf
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
572 additions
and
991 deletions
+572
-991
sound/pci/hda/Makefile
sound/pci/hda/Makefile
+1
-1
sound/pci/hda/hda_beep.c
sound/pci/hda/hda_beep.c
+1
-1
sound/pci/hda/hda_bind.c
sound/pci/hda/hda_bind.c
+321
-0
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.c
+142
-589
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_codec.h
+29
-79
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.c
+19
-43
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_controller.h
+2
-2
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.c
+13
-5
sound/pci/hda/hda_hwdep.c
sound/pci/hda/hda_hwdep.c
+0
-3
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.c
+6
-27
sound/pci/hda/hda_local.h
sound/pci/hda/hda_local.h
+8
-33
sound/pci/hda/hda_tegra.c
sound/pci/hda/hda_tegra.c
+3
-20
sound/pci/hda/hda_trace.h
sound/pci/hda/hda_trace.h
+0
-24
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_analog.c
+2
-14
sound/pci/hda/patch_ca0110.c
sound/pci/hda/patch_ca0110.c
+2
-14
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_ca0132.c
+2
-14
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_cirrus.c
+2
-14
sound/pci/hda/patch_cmedia.c
sound/pci/hda/patch_cmedia.c
+2
-14
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_conexant.c
+2
-14
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_hdmi.c
+4
-23
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_realtek.c
+2
-14
sound/pci/hda/patch_si3054.c
sound/pci/hda/patch_si3054.c
+2
-14
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_sigmatel.c
+5
-15
sound/pci/hda/patch_via.c
sound/pci/hda/patch_via.c
+2
-14
No files found.
sound/pci/hda/Makefile
View file @
8f88f025
...
...
@@ -4,7 +4,7 @@ snd-hda-tegra-objs := hda_tegra.o
# for haswell power well
snd-hda-intel-$(CONFIG_SND_HDA_I915)
+=
hda_i915.o
snd-hda-codec-y
:=
hda_codec.o hda_jack.o hda_auto_parser.o hda_sysfs.o
snd-hda-codec-y
:=
hda_
bind.o hda_
codec.o hda_jack.o hda_auto_parser.o hda_sysfs.o
snd-hda-codec-$(CONFIG_PROC_FS)
+=
hda_proc.o
snd-hda-codec-$(CONFIG_SND_HDA_HWDEP)
+=
hda_hwdep.o
snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP)
+=
hda_beep.o
...
...
sound/pci/hda/hda_beep.c
View file @
8f88f025
...
...
@@ -160,6 +160,7 @@ static int snd_hda_do_attach(struct hda_beep *beep)
input_dev
->
name
=
"HDA Digital PCBeep"
;
input_dev
->
phys
=
beep
->
phys
;
input_dev
->
id
.
bustype
=
BUS_PCI
;
input_dev
->
dev
.
parent
=
&
codec
->
bus
->
card
->
card_dev
;
input_dev
->
id
.
vendor
=
codec
->
vendor_id
>>
16
;
input_dev
->
id
.
product
=
codec
->
vendor_id
&
0xffff
;
...
...
@@ -168,7 +169,6 @@ static int snd_hda_do_attach(struct hda_beep *beep)
input_dev
->
evbit
[
0
]
=
BIT_MASK
(
EV_SND
);
input_dev
->
sndbit
[
0
]
=
BIT_MASK
(
SND_BELL
)
|
BIT_MASK
(
SND_TONE
);
input_dev
->
event
=
snd_hda_beep_event
;
input_dev
->
dev
.
parent
=
&
codec
->
dev
;
input_set_drvdata
(
input_dev
,
beep
);
beep
->
dev
=
input_dev
;
...
...
sound/pci/hda/hda_bind.c
0 → 100644
View file @
8f88f025
/*
* HD-audio codec driver binding
* Copyright (c) Takashi Iwai <tiwai@suse.de>
*/
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/pm.h>
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_local.h"
/* codec vendor labels */
struct
hda_vendor_id
{
unsigned
int
id
;
const
char
*
name
;
};
static
struct
hda_vendor_id
hda_vendor_ids
[]
=
{
{
0x1002
,
"ATI"
},
{
0x1013
,
"Cirrus Logic"
},
{
0x1057
,
"Motorola"
},
{
0x1095
,
"Silicon Image"
},
{
0x10de
,
"Nvidia"
},
{
0x10ec
,
"Realtek"
},
{
0x1102
,
"Creative"
},
{
0x1106
,
"VIA"
},
{
0x111d
,
"IDT"
},
{
0x11c1
,
"LSI"
},
{
0x11d4
,
"Analog Devices"
},
{
0x13f6
,
"C-Media"
},
{
0x14f1
,
"Conexant"
},
{
0x17e8
,
"Chrontel"
},
{
0x1854
,
"LG"
},
{
0x1aec
,
"Wolfson Microelectronics"
},
{
0x1af4
,
"QEMU"
},
{
0x434d
,
"C-Media"
},
{
0x8086
,
"Intel"
},
{
0x8384
,
"SigmaTel"
},
{}
/* terminator */
};
/*
* find a matching codec preset
*/
static
int
hda_bus_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
struct
hda_codec
*
codec
=
container_of
(
dev
,
struct
hda_codec
,
dev
);
struct
hda_codec_driver
*
driver
=
container_of
(
drv
,
struct
hda_codec_driver
,
driver
);
const
struct
hda_codec_preset
*
preset
;
/* check probe_id instead of vendor_id if set */
u32
id
=
codec
->
probe_id
?
codec
->
probe_id
:
codec
->
vendor_id
;
for
(
preset
=
driver
->
preset
;
preset
->
id
;
preset
++
)
{
u32
mask
=
preset
->
mask
;
if
(
preset
->
afg
&&
preset
->
afg
!=
codec
->
afg
)
continue
;
if
(
preset
->
mfg
&&
preset
->
mfg
!=
codec
->
mfg
)
continue
;
if
(
!
mask
)
mask
=
~
0
;
if
(
preset
->
id
==
(
id
&
mask
)
&&
(
!
preset
->
rev
||
preset
->
rev
==
codec
->
revision_id
))
{
codec
->
preset
=
preset
;
return
1
;
}
}
return
0
;
}
/* reset the codec name from the preset */
static
int
codec_refresh_name
(
struct
hda_codec
*
codec
,
const
char
*
name
)
{
char
tmp
[
16
];
kfree
(
codec
->
chip_name
);
if
(
!
name
)
{
sprintf
(
tmp
,
"ID %x"
,
codec
->
vendor_id
&
0xffff
);
name
=
tmp
;
}
codec
->
chip_name
=
kstrdup
(
name
,
GFP_KERNEL
);
return
codec
->
chip_name
?
0
:
-
ENOMEM
;
}
static
int
hda_codec_driver_probe
(
struct
device
*
dev
)
{
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
struct
module
*
owner
=
dev
->
driver
->
owner
;
int
err
;
if
(
WARN_ON
(
!
codec
->
preset
))
return
-
EINVAL
;
err
=
codec_refresh_name
(
codec
,
codec
->
preset
->
name
);
if
(
err
<
0
)
goto
error
;
if
(
!
try_module_get
(
owner
))
{
err
=
-
EINVAL
;
goto
error
;
}
err
=
codec
->
preset
->
patch
(
codec
);
if
(
err
<
0
)
{
module_put
(
owner
);
goto
error
;
}
return
0
;
error:
codec
->
preset
=
NULL
;
memset
(
&
codec
->
patch_ops
,
0
,
sizeof
(
codec
->
patch_ops
));
return
err
;
}
static
int
hda_codec_driver_remove
(
struct
device
*
dev
)
{
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
if
(
codec
->
patch_ops
.
free
)
codec
->
patch_ops
.
free
(
codec
);
codec
->
preset
=
NULL
;
memset
(
&
codec
->
patch_ops
,
0
,
sizeof
(
codec
->
patch_ops
));
module_put
(
dev
->
driver
->
owner
);
return
0
;
}
int
__hda_codec_driver_register
(
struct
hda_codec_driver
*
drv
,
const
char
*
name
,
struct
module
*
owner
)
{
drv
->
driver
.
name
=
name
;
drv
->
driver
.
owner
=
owner
;
drv
->
driver
.
bus
=
&
snd_hda_bus_type
;
drv
->
driver
.
probe
=
hda_codec_driver_probe
;
drv
->
driver
.
remove
=
hda_codec_driver_remove
;
drv
->
driver
.
pm
=
&
hda_codec_driver_pm
;
return
driver_register
(
&
drv
->
driver
);
}
EXPORT_SYMBOL_GPL
(
__hda_codec_driver_register
);
void
hda_codec_driver_unregister
(
struct
hda_codec_driver
*
drv
)
{
driver_unregister
(
&
drv
->
driver
);
}
EXPORT_SYMBOL_GPL
(
hda_codec_driver_unregister
);
static
inline
bool
codec_probed
(
struct
hda_codec
*
codec
)
{
return
device_attach
(
hda_codec_dev
(
codec
))
>
0
&&
codec
->
preset
;
}
/* try to auto-load and bind the codec module */
static
void
codec_bind_module
(
struct
hda_codec
*
codec
)
{
#ifdef MODULE
request_module
(
"snd-hda-codec-id:%08x"
,
codec
->
vendor_id
);
if
(
codec_probed
(
codec
))
return
;
request_module
(
"snd-hda-codec-id:%04x*"
,
(
codec
->
vendor_id
>>
16
)
&
0xffff
);
if
(
codec_probed
(
codec
))
return
;
#endif
}
/* store the codec vendor name */
static
int
get_codec_vendor_name
(
struct
hda_codec
*
codec
)
{
const
struct
hda_vendor_id
*
c
;
const
char
*
vendor
=
NULL
;
u16
vendor_id
=
codec
->
vendor_id
>>
16
;
char
tmp
[
16
];
for
(
c
=
hda_vendor_ids
;
c
->
id
;
c
++
)
{
if
(
c
->
id
==
vendor_id
)
{
vendor
=
c
->
name
;
break
;
}
}
if
(
!
vendor
)
{
sprintf
(
tmp
,
"Generic %04x"
,
vendor_id
);
vendor
=
tmp
;
}
codec
->
vendor_name
=
kstrdup
(
vendor
,
GFP_KERNEL
);
if
(
!
codec
->
vendor_name
)
return
-
ENOMEM
;
return
0
;
}
#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
/* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */
static
bool
is_likely_hdmi_codec
(
struct
hda_codec
*
codec
)
{
hda_nid_t
nid
=
codec
->
start_nid
;
int
i
;
for
(
i
=
0
;
i
<
codec
->
num_nodes
;
i
++
,
nid
++
)
{
unsigned
int
wcaps
=
get_wcaps
(
codec
,
nid
);
switch
(
get_wcaps_type
(
wcaps
))
{
case
AC_WID_AUD_IN
:
return
false
;
/* HDMI parser supports only HDMI out */
case
AC_WID_AUD_OUT
:
if
(
!
(
wcaps
&
AC_WCAP_DIGITAL
))
return
false
;
break
;
}
}
return
true
;
}
#else
/* no HDMI codec parser support */
#define is_likely_hdmi_codec(codec) false
#endif
/* CONFIG_SND_HDA_CODEC_HDMI */
static
int
codec_bind_generic
(
struct
hda_codec
*
codec
)
{
if
(
codec
->
probe_id
)
return
-
ENODEV
;
if
(
is_likely_hdmi_codec
(
codec
))
{
codec
->
probe_id
=
HDA_CODEC_ID_GENERIC_HDMI
;
#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
request_module
(
"snd-hda-codec-hdmi"
);
#endif
if
(
codec_probed
(
codec
))
return
0
;
}
codec
->
probe_id
=
HDA_CODEC_ID_GENERIC
;
#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
request_module
(
"snd-hda-codec-generic"
);
#endif
if
(
codec_probed
(
codec
))
return
0
;
return
-
ENODEV
;
}
#if IS_ENABLED(CONFIG_SND_HDA_GENERIC)
#define is_generic_config(codec) \
(codec->modelname && !strcmp(codec->modelname, "generic"))
#else
#define is_generic_config(codec) 0
#endif
/**
* snd_hda_codec_configure - (Re-)configure the HD-audio codec
* @codec: the HDA codec
*
* Start parsing of the given codec tree and (re-)initialize the whole
* patch instance.
*
* Returns 0 if successful or a negative error code.
*/
int
snd_hda_codec_configure
(
struct
hda_codec
*
codec
)
{
int
err
;
if
(
!
codec
->
vendor_name
)
{
err
=
get_codec_vendor_name
(
codec
);
if
(
err
<
0
)
return
err
;
}
if
(
is_generic_config
(
codec
))
codec
->
probe_id
=
HDA_CODEC_ID_GENERIC
;
else
codec
->
probe_id
=
0
;
err
=
device_add
(
hda_codec_dev
(
codec
));
if
(
err
<
0
)
return
err
;
if
(
!
codec
->
preset
)
codec_bind_module
(
codec
);
if
(
!
codec
->
preset
)
{
err
=
codec_bind_generic
(
codec
);
if
(
err
<
0
)
{
codec_err
(
codec
,
"Unable to bind the codec
\n
"
);
goto
error
;
}
}
/* audio codec should override the mixer name */
if
(
codec
->
afg
||
!*
codec
->
bus
->
card
->
mixername
)
snprintf
(
codec
->
bus
->
card
->
mixername
,
sizeof
(
codec
->
bus
->
card
->
mixername
),
"%s %s"
,
codec
->
vendor_name
,
codec
->
chip_name
);
return
0
;
error:
device_del
(
hda_codec_dev
(
codec
));
return
err
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_codec_configure
);
/*
* bus registration
*/
struct
bus_type
snd_hda_bus_type
=
{
.
name
=
"hdaudio"
,
.
match
=
hda_bus_match
,
};
static
int
__init
hda_codec_init
(
void
)
{
return
bus_register
(
&
snd_hda_bus_type
);
}
static
void
__exit
hda_codec_exit
(
void
)
{
bus_unregister
(
&
snd_hda_bus_type
);
}
module_init
(
hda_codec_init
);
module_exit
(
hda_codec_exit
);
sound/pci/hda/hda_codec.c
View file @
8f88f025
...
...
@@ -26,6 +26,8 @@
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/async.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <sound/core.h>
#include "hda_codec.h"
#include <sound/asoundef.h>
...
...
@@ -40,92 +42,13 @@
#define CREATE_TRACE_POINTS
#include "hda_trace.h"
/*
* vendor / preset table
*/
struct
hda_vendor_id
{
unsigned
int
id
;
const
char
*
name
;
};
/* codec vendor labels */
static
struct
hda_vendor_id
hda_vendor_ids
[]
=
{
{
0x1002
,
"ATI"
},
{
0x1013
,
"Cirrus Logic"
},
{
0x1057
,
"Motorola"
},
{
0x1095
,
"Silicon Image"
},
{
0x10de
,
"Nvidia"
},
{
0x10ec
,
"Realtek"
},
{
0x1102
,
"Creative"
},
{
0x1106
,
"VIA"
},
{
0x111d
,
"IDT"
},
{
0x11c1
,
"LSI"
},
{
0x11d4
,
"Analog Devices"
},
{
0x13f6
,
"C-Media"
},
{
0x14f1
,
"Conexant"
},
{
0x17e8
,
"Chrontel"
},
{
0x1854
,
"LG"
},
{
0x1aec
,
"Wolfson Microelectronics"
},
{
0x1af4
,
"QEMU"
},
{
0x434d
,
"C-Media"
},
{
0x8086
,
"Intel"
},
{
0x8384
,
"SigmaTel"
},
{}
/* terminator */
};
static
DEFINE_MUTEX
(
preset_mutex
);
static
LIST_HEAD
(
hda_preset_tables
);
/**
* snd_hda_add_codec_preset - Add a codec preset to the chain
* @preset: codec preset table to add
*/
int
snd_hda_add_codec_preset
(
struct
hda_codec_preset_list
*
preset
)
{
mutex_lock
(
&
preset_mutex
);
list_add_tail
(
&
preset
->
list
,
&
hda_preset_tables
);
mutex_unlock
(
&
preset_mutex
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_add_codec_preset
);
/**
* snd_hda_delete_codec_preset - Delete a codec preset from the chain
* @preset: codec preset table to delete
*/
int
snd_hda_delete_codec_preset
(
struct
hda_codec_preset_list
*
preset
)
{
mutex_lock
(
&
preset_mutex
);
list_del
(
&
preset
->
list
);
mutex_unlock
(
&
preset_mutex
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_delete_codec_preset
);
#ifdef CONFIG_PM
#define codec_in_pm(codec) ((codec)->in_pm)
static
void
hda_power_work
(
struct
work_struct
*
work
);
static
void
hda_keep_power_on
(
struct
hda_codec
*
codec
);
#define hda_codec_is_power_on(codec) ((codec)->power_on)
static
void
hda_call_pm_notify
(
struct
hda_codec
*
codec
,
bool
power_up
)
{
struct
hda_bus
*
bus
=
codec
->
bus
;
if
((
power_up
&&
codec
->
pm_up_notified
)
||
(
!
power_up
&&
!
codec
->
pm_up_notified
))
return
;
if
(
bus
->
ops
.
pm_notify
)
bus
->
ops
.
pm_notify
(
bus
,
power_up
);
codec
->
pm_up_notified
=
power_up
;
}
#define codec_in_pm(codec) atomic_read(&(codec)->in_pm)
#define hda_codec_is_power_on(codec) \
(!pm_runtime_suspended(hda_codec_dev(codec)))
#else
#define codec_in_pm(codec) 0
static
inline
void
hda_keep_power_on
(
struct
hda_codec
*
codec
)
{}
#define hda_codec_is_power_on(codec) 1
#define hda_call_pm_notify(codec, state) {}
#endif
/**
...
...
@@ -885,111 +808,6 @@ int snd_hda_bus_new(struct snd_card *card,
}
EXPORT_SYMBOL_GPL
(
snd_hda_bus_new
);
#if IS_ENABLED(CONFIG_SND_HDA_GENERIC)
#define is_generic_config(codec) \
(codec->modelname && !strcmp(codec->modelname, "generic"))
#else
#define is_generic_config(codec) 0
#endif
#ifdef MODULE
#define HDA_MODREQ_MAX_COUNT 2
/* two request_modules()'s */
#else
#define HDA_MODREQ_MAX_COUNT 0
/* all presets are statically linked */
#endif
/*
* find a matching codec preset
*/
static
const
struct
hda_codec_preset
*
find_codec_preset
(
struct
hda_codec
*
codec
)
{
struct
hda_codec_preset_list
*
tbl
;
const
struct
hda_codec_preset
*
preset
;
unsigned
int
mod_requested
=
0
;
again:
mutex_lock
(
&
preset_mutex
);
list_for_each_entry
(
tbl
,
&
hda_preset_tables
,
list
)
{
if
(
!
try_module_get
(
tbl
->
owner
))
{
codec_err
(
codec
,
"cannot module_get
\n
"
);
continue
;
}
for
(
preset
=
tbl
->
preset
;
preset
->
id
;
preset
++
)
{
u32
mask
=
preset
->
mask
;
if
(
preset
->
afg
&&
preset
->
afg
!=
codec
->
afg
)
continue
;
if
(
preset
->
mfg
&&
preset
->
mfg
!=
codec
->
mfg
)
continue
;
if
(
!
mask
)
mask
=
~
0
;
if
(
preset
->
id
==
(
codec
->
vendor_id
&
mask
)
&&
(
!
preset
->
rev
||
preset
->
rev
==
codec
->
revision_id
))
{
mutex_unlock
(
&
preset_mutex
);
codec
->
owner
=
tbl
->
owner
;
return
preset
;
}
}
module_put
(
tbl
->
owner
);
}
mutex_unlock
(
&
preset_mutex
);
if
(
mod_requested
<
HDA_MODREQ_MAX_COUNT
)
{
if
(
!
mod_requested
)
request_module
(
"snd-hda-codec-id:%08x"
,
codec
->
vendor_id
);
else
request_module
(
"snd-hda-codec-id:%04x*"
,
(
codec
->
vendor_id
>>
16
)
&
0xffff
);
mod_requested
++
;
goto
again
;
}
return
NULL
;
}
/*
* get_codec_name - store the codec name
*/
static
int
get_codec_name
(
struct
hda_codec
*
codec
)
{
const
struct
hda_vendor_id
*
c
;
const
char
*
vendor
=
NULL
;
u16
vendor_id
=
codec
->
vendor_id
>>
16
;
char
tmp
[
16
];
if
(
codec
->
vendor_name
)
goto
get_chip_name
;
for
(
c
=
hda_vendor_ids
;
c
->
id
;
c
++
)
{
if
(
c
->
id
==
vendor_id
)
{
vendor
=
c
->
name
;
break
;
}
}
if
(
!
vendor
)
{
sprintf
(
tmp
,
"Generic %04x"
,
vendor_id
);
vendor
=
tmp
;
}
codec
->
vendor_name
=
kstrdup
(
vendor
,
GFP_KERNEL
);
if
(
!
codec
->
vendor_name
)
return
-
ENOMEM
;
get_chip_name:
if
(
codec
->
chip_name
)
return
0
;
if
(
codec
->
preset
&&
codec
->
preset
->
name
)
codec
->
chip_name
=
kstrdup
(
codec
->
preset
->
name
,
GFP_KERNEL
);
else
{
sprintf
(
tmp
,
"ID %x"
,
codec
->
vendor_id
&
0xffff
);
codec
->
chip_name
=
kstrdup
(
tmp
,
GFP_KERNEL
);
}
if
(
!
codec
->
chip_name
)
return
-
ENOMEM
;
return
0
;
}
/*
* look for an AFG and MFG nodes
*/
...
...
@@ -1300,20 +1118,6 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
return
p
;
}
/*
* Dynamic symbol binding for the codec parsers
*/
#define load_parser(codec, sym) \
((codec)->parser = (int (*)(struct hda_codec *))symbol_request(sym))
static
void
unload_parser
(
struct
hda_codec
*
codec
)
{
if
(
codec
->
parser
)
symbol_put_addr
(
codec
->
parser
);
codec
->
parser
=
NULL
;
}
/*
* codec destructor
*/
...
...
@@ -1322,12 +1126,11 @@ static void snd_hda_codec_free(struct hda_codec *codec)
if
(
!
codec
)
return
;
cancel_delayed_work_sync
(
&
codec
->
jackpoll_work
);
if
(
device_is_registered
(
hda_codec_dev
(
codec
)))
device_del
(
hda_codec_dev
(
codec
));
snd_hda_jack_tbl_clear
(
codec
);
free_init_pincfgs
(
codec
);
#ifdef CONFIG_PM
cancel_delayed_work
(
&
codec
->
power_work
);
flush_workqueue
(
codec
->
bus
->
workq
);
#endif
list_del
(
&
codec
->
list
);
snd_array_free
(
&
codec
->
mixers
);
snd_array_free
(
&
codec
->
nids
);
...
...
@@ -1335,12 +1138,8 @@ static void snd_hda_codec_free(struct hda_codec *codec)
snd_array_free
(
&
codec
->
spdif_out
);
remove_conn_list
(
codec
);
codec
->
bus
->
caddr_tbl
[
codec
->
addr
]
=
NULL
;
if
(
codec
->
patch_ops
.
free
)
codec
->
patch_ops
.
free
(
codec
);
hda_call_pm_notify
(
codec
,
false
);
/* cancel leftover refcounts */
clear_bit
(
codec
->
addr
,
&
codec
->
bus
->
codec_powered
);
snd_hda_sysfs_clear
(
codec
);
unload_parser
(
codec
);
module_put
(
codec
->
owner
);
free_hda_cache
(
&
codec
->
amp_cache
);
free_hda_cache
(
&
codec
->
cmd_cache
);
kfree
(
codec
->
vendor_name
);
...
...
@@ -1348,7 +1147,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
kfree
(
codec
->
modelname
);
kfree
(
codec
->
wcaps
);
codec
->
bus
->
num_codecs
--
;
put_device
(
&
codec
->
dev
);
put_device
(
hda_codec_dev
(
codec
)
);
}
static
bool
snd_hda_codec_get_supported_ps
(
struct
hda_codec
*
codec
,
...
...
@@ -1360,11 +1159,12 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
static
int
snd_hda_codec_dev_register
(
struct
snd_device
*
device
)
{
struct
hda_codec
*
codec
=
device
->
device_data
;
int
err
=
device_add
(
&
codec
->
dev
);
if
(
err
<
0
)
return
err
;
snd_hda_register_beep_device
(
codec
);
if
(
device_is_registered
(
hda_codec_dev
(
codec
)))
pm_runtime_enable
(
hda_codec_dev
(
codec
));
/* it was powered up in snd_hda_codec_new(), now all done */
snd_hda_power_down
(
codec
);
return
0
;
}
...
...
@@ -1373,7 +1173,6 @@ static int snd_hda_codec_dev_disconnect(struct snd_device *device)
struct
hda_codec
*
codec
=
device
->
device_data
;
snd_hda_detach_beep_device
(
codec
);
device_del
(
&
codec
->
dev
);
return
0
;
}
...
...
@@ -1386,7 +1185,7 @@ static int snd_hda_codec_dev_free(struct snd_device *device)
/* just free the container */
static
void
snd_hda_codec_dev_release
(
struct
device
*
dev
)
{
kfree
(
container_of
(
dev
,
struct
hda_codec
,
dev
));
kfree
(
dev_to_hda_codec
(
dev
));
}
/**
...
...
@@ -1402,6 +1201,7 @@ int snd_hda_codec_new(struct hda_bus *bus,
struct
hda_codec
**
codecp
)
{
struct
hda_codec
*
codec
;
struct
device
*
dev
;
char
component
[
31
];
hda_nid_t
fg
;
int
err
;
...
...
@@ -1429,14 +1229,15 @@ int snd_hda_codec_new(struct hda_bus *bus,
return
-
ENOMEM
;
}
device_initialize
(
&
codec
->
dev
);
codec
->
dev
.
parent
=
&
bus
->
card
->
card_dev
;
codec
->
dev
.
class
=
sound_class
;
codec
->
dev
.
release
=
snd_hda_codec_dev_release
;
codec
->
dev
.
groups
=
snd_hda_dev_attr_groups
;
dev_set_name
(
&
codec
->
dev
,
"hdaudioC%dD%d"
,
bus
->
card
->
number
,
codec_addr
);
dev_set_drvdata
(
&
codec
->
dev
,
codec
);
/* for sysfs */
dev
=
hda_codec_dev
(
codec
);
device_initialize
(
dev
);
dev
->
parent
=
bus
->
card
->
dev
;
dev
->
bus
=
&
snd_hda_bus_type
;
dev
->
release
=
snd_hda_codec_dev_release
;
dev
->
groups
=
snd_hda_dev_attr_groups
;
dev_set_name
(
dev
,
"hdaudioC%dD%d"
,
bus
->
card
->
number
,
codec_addr
);
dev_set_drvdata
(
dev
,
codec
);
/* for sysfs */
device_enable_async_suspend
(
dev
);
codec
->
bus
=
bus
;
codec
->
addr
=
codec_addr
;
...
...
@@ -1460,13 +1261,13 @@ int snd_hda_codec_new(struct hda_bus *bus,
codec
->
fixup_id
=
HDA_FIXUP_ID_NOT_SET
;
#ifdef CONFIG_PM
spin_lock_init
(
&
codec
->
power_lock
);
INIT_DELAYED_WORK
(
&
codec
->
power_work
,
hda_power_work
);
/* snd_hda_codec_new() marks the codec as power-up, and leave it as is.
* the caller has to power down appropriatley after initialization
* phase.
* it's powered down later in snd_hda_codec_dev_register().
*/
hda_keep_power_on
(
codec
);
set_bit
(
codec
->
addr
,
&
bus
->
codec_powered
);
pm_runtime_set_active
(
hda_codec_dev
(
codec
));
pm_runtime_get_noresume
(
hda_codec_dev
(
codec
));
codec
->
power_jiffies
=
jiffies
;
#endif
snd_hda_sysfs_init
(
codec
);
...
...
@@ -1526,11 +1327,6 @@ int snd_hda_codec_new(struct hda_bus *bus,
#endif
codec
->
epss
=
snd_hda_codec_get_supported_ps
(
codec
,
fg
,
AC_PWRST_EPSS
);
#ifdef CONFIG_PM
if
(
!
codec
->
d3_stop_clk
||
!
codec
->
epss
)
bus
->
power_keep_link_on
=
1
;
#endif
/* power-up all before initialization */
hda_set_power_state
(
codec
,
AC_PWRST_D0
);
...
...
@@ -1587,92 +1383,6 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec)
}
EXPORT_SYMBOL_GPL
(
snd_hda_codec_update_widgets
);
#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
/* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */
static
bool
is_likely_hdmi_codec
(
struct
hda_codec
*
codec
)
{
hda_nid_t
nid
=
codec
->
start_nid
;
int
i
;
for
(
i
=
0
;
i
<
codec
->
num_nodes
;
i
++
,
nid
++
)
{
unsigned
int
wcaps
=
get_wcaps
(
codec
,
nid
);
switch
(
get_wcaps_type
(
wcaps
))
{
case
AC_WID_AUD_IN
:
return
false
;
/* HDMI parser supports only HDMI out */
case
AC_WID_AUD_OUT
:
if
(
!
(
wcaps
&
AC_WCAP_DIGITAL
))
return
false
;
break
;
}
}
return
true
;
}
#else
/* no HDMI codec parser support */
#define is_likely_hdmi_codec(codec) false
#endif
/* CONFIG_SND_HDA_CODEC_HDMI */
/**
* snd_hda_codec_configure - (Re-)configure the HD-audio codec
* @codec: the HDA codec
*
* Start parsing of the given codec tree and (re-)initialize the whole
* patch instance.
*
* Returns 0 if successful or a negative error code.
*/
int
snd_hda_codec_configure
(
struct
hda_codec
*
codec
)
{
int
(
*
patch
)(
struct
hda_codec
*
)
=
NULL
;
int
err
;
codec
->
preset
=
find_codec_preset
(
codec
);
if
(
!
codec
->
vendor_name
||
!
codec
->
chip_name
)
{
err
=
get_codec_name
(
codec
);
if
(
err
<
0
)
return
err
;
}
if
(
!
is_generic_config
(
codec
)
&&
codec
->
preset
)
patch
=
codec
->
preset
->
patch
;
if
(
!
patch
)
{
unload_parser
(
codec
);
/* to be sure */
if
(
is_likely_hdmi_codec
(
codec
))
{
#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
patch
=
load_parser
(
codec
,
snd_hda_parse_hdmi_codec
);
#elif IS_BUILTIN(CONFIG_SND_HDA_CODEC_HDMI)
patch
=
snd_hda_parse_hdmi_codec
;
#endif
}
if
(
!
patch
)
{
#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
patch
=
load_parser
(
codec
,
snd_hda_parse_generic_codec
);
#elif IS_BUILTIN(CONFIG_SND_HDA_GENERIC)
patch
=
snd_hda_parse_generic_codec
;
#endif
}
if
(
!
patch
)
{
codec_err
(
codec
,
"No codec parser is available
\n
"
);
return
-
ENODEV
;
}
}
err
=
patch
(
codec
);
if
(
err
<
0
)
{
unload_parser
(
codec
);
return
err
;
}
/* audio codec should override the mixer name */
if
(
codec
->
afg
||
!*
codec
->
bus
->
card
->
mixername
)
snprintf
(
codec
->
bus
->
card
->
mixername
,
sizeof
(
codec
->
bus
->
card
->
mixername
),
"%s %s"
,
codec
->
vendor_name
,
codec
->
chip_name
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_codec_configure
);
/* update the stream-id if changed */
static
void
update_pcm_stream_id
(
struct
hda_codec
*
codec
,
struct
hda_cvt_setup
*
p
,
hda_nid_t
nid
,
...
...
@@ -2725,10 +2435,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
/* OK, let it free */
cancel_delayed_work_sync
(
&
codec
->
jackpoll_work
);
#ifdef CONFIG_PM
cancel_delayed_work_sync
(
&
codec
->
power_work
);
flush_workqueue
(
bus
->
workq
);
#endif
snd_hda_ctls_clear
(
codec
);
/* release PCMs */
for
(
i
=
0
;
i
<
codec
->
num_pcms
;
i
++
)
{
...
...
@@ -2739,8 +2446,9 @@ int snd_hda_codec_reset(struct hda_codec *codec)
}
}
snd_hda_detach_beep_device
(
codec
);
if
(
codec
->
patch_ops
.
free
)
codec
->
patch_ops
.
free
(
codec
);
if
(
device_is_registered
(
hda_codec_dev
(
codec
)))
device_del
(
hda_codec_dev
(
codec
));
memset
(
&
codec
->
patch_ops
,
0
,
sizeof
(
codec
->
patch_ops
));
snd_hda_jack_tbl_clear
(
codec
);
codec
->
proc_widget_hook
=
NULL
;
...
...
@@ -2759,9 +2467,6 @@ int snd_hda_codec_reset(struct hda_codec *codec)
codec
->
preset
=
NULL
;
codec
->
slave_dig_outs
=
NULL
;
codec
->
spdif_status_reset
=
0
;
unload_parser
(
codec
);
module_put
(
codec
->
owner
);
codec
->
owner
=
NULL
;
/* allow device access again */
snd_hda_unlock_devices
(
bus
);
...
...
@@ -4167,31 +3872,40 @@ static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
#endif
#ifdef CONFIG_PM
/* update the power on/off account with the current jiffies */
static
void
update_power_acct
(
struct
hda_codec
*
codec
,
bool
on
)
{
unsigned
long
delta
=
jiffies
-
codec
->
power_jiffies
;
if
(
on
)
codec
->
power_on_acct
+=
delta
;
else
codec
->
power_off_acct
+=
delta
;
codec
->
power_jiffies
+=
delta
;
}
void
snd_hda_update_power_acct
(
struct
hda_codec
*
codec
)
{
update_power_acct
(
codec
,
hda_codec_is_power_on
(
codec
));
}
/*
* call suspend and power-down; used both from PM and power-save
* this function returns the power state in the end
*/
static
unsigned
int
hda_call_codec_suspend
(
struct
hda_codec
*
codec
,
bool
in_wq
)
static
unsigned
int
hda_call_codec_suspend
(
struct
hda_codec
*
codec
)
{
unsigned
int
state
;
codec
->
in_pm
=
1
;
atomic_inc
(
&
codec
->
in_pm
)
;
if
(
codec
->
patch_ops
.
suspend
)
codec
->
patch_ops
.
suspend
(
codec
);
hda_cleanup_all_streams
(
codec
);
state
=
hda_set_power_state
(
codec
,
AC_PWRST_D3
);
/* Cancel delayed work if we aren't currently running from it. */
if
(
!
in_wq
)
cancel_delayed_work_sync
(
&
codec
->
power_work
);
spin_lock
(
&
codec
->
power_lock
);
snd_hda_update_power_acct
(
codec
);
trace_hda_power_down
(
codec
);
codec
->
power_on
=
0
;
codec
->
power_transition
=
0
;
codec
->
power_jiffies
=
jiffies
;
spin_unlock
(
&
codec
->
power_lock
);
codec
->
in_pm
=
0
;
update_power_acct
(
codec
,
true
);
atomic_dec
(
&
codec
->
in_pm
);
return
state
;
}
...
...
@@ -4216,14 +3930,13 @@ static void hda_mark_cmd_cache_dirty(struct hda_codec *codec)
*/
static
void
hda_call_codec_resume
(
struct
hda_codec
*
codec
)
{
codec
->
in_pm
=
1
;
atomic_inc
(
&
codec
->
in_pm
)
;
trace_hda_power_up
(
codec
);
hda_mark_cmd_cache_dirty
(
codec
);
/* set as if powered on for avoiding re-entering the resume
* in the resume / power-save sequence
*/
hda_keep_power_on
(
codec
);
codec
->
power_jiffies
=
jiffies
;
hda_set_power_state
(
codec
,
AC_PWRST_D0
);
restore_shutup_pins
(
codec
);
hda_exec_init_verbs
(
codec
);
...
...
@@ -4241,12 +3954,42 @@ static void hda_call_codec_resume(struct hda_codec *codec)
hda_jackpoll_work
(
&
codec
->
jackpoll_work
.
work
);
else
snd_hda_jack_report_sync
(
codec
);
atomic_dec
(
&
codec
->
in_pm
);
}
static
int
hda_codec_runtime_suspend
(
struct
device
*
dev
)
{
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
unsigned
int
state
;
int
i
;
cancel_delayed_work_sync
(
&
codec
->
jackpoll_work
);
for
(
i
=
0
;
i
<
codec
->
num_pcms
;
i
++
)
snd_pcm_suspend_all
(
codec
->
pcm_info
[
i
].
pcm
);
state
=
hda_call_codec_suspend
(
codec
);
if
(
codec
->
d3_stop_clk
&&
codec
->
epss
&&
(
state
&
AC_PWRST_CLK_STOP_OK
))
clear_bit
(
codec
->
addr
,
&
codec
->
bus
->
codec_powered
);
return
0
;
}
static
int
hda_codec_runtime_resume
(
struct
device
*
dev
)
{
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
codec
->
in_pm
=
0
;
snd_hda_power_down
(
codec
);
/* flag down before returning */
set_bit
(
codec
->
addr
,
&
codec
->
bus
->
codec_powered
);
hda_call_codec_resume
(
codec
);
pm_runtime_mark_last_busy
(
dev
);
return
0
;
}
#endif
/* CONFIG_PM */
/* referred in hda_bind.c */
const
struct
dev_pm_ops
hda_codec_driver_pm
=
{
SET_SYSTEM_SLEEP_PM_OPS
(
pm_runtime_force_suspend
,
pm_runtime_force_resume
)
SET_RUNTIME_PM_OPS
(
hda_codec_runtime_suspend
,
hda_codec_runtime_resume
,
NULL
)
};
/**
* snd_hda_build_controls - build mixer controls
...
...
@@ -4984,127 +4727,70 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
EXPORT_SYMBOL_GPL
(
snd_hda_add_new_ctls
);
#ifdef CONFIG_PM
static
void
hda_power_work
(
struct
work_struct
*
work
)
/**
* snd_hda_power_up - Power-up the codec
* @codec: HD-audio codec
*
* Increment the usage counter and resume the device if not done yet.
*/
void
snd_hda_power_up
(
struct
hda_codec
*
codec
)
{
struct
hda_codec
*
codec
=
container_of
(
work
,
struct
hda_codec
,
power_work
.
work
);
struct
hda_bus
*
bus
=
codec
->
bus
;
unsigned
int
state
;
struct
device
*
dev
=
hda_codec_dev
(
codec
);
spin_lock
(
&
codec
->
power_lock
);
if
(
codec
->
power_transition
>
0
)
{
/* during power-up sequence? */
spin_unlock
(
&
codec
->
power_lock
);
return
;
}
if
(
!
codec
->
power_on
||
codec
->
power_count
)
{
codec
->
power_transition
=
0
;
spin_unlock
(
&
codec
->
power_lock
);
if
(
codec_in_pm
(
codec
))
return
;
}
spin_unlock
(
&
codec
->
power_lock
);
state
=
hda_call_codec_suspend
(
codec
,
true
);
if
(
!
bus
->
power_keep_link_on
&&
(
state
&
AC_PWRST_CLK_STOP_OK
))
hda_call_pm_notify
(
codec
,
false
);
}
static
void
hda_keep_power_on
(
struct
hda_codec
*
codec
)
{
spin_lock
(
&
codec
->
power_lock
);
codec
->
power_count
++
;
codec
->
power_on
=
1
;
codec
->
power_jiffies
=
jiffies
;
spin_unlock
(
&
codec
->
power_lock
);
hda_call_pm_notify
(
codec
,
true
);
pm_runtime_get_sync
(
dev
);
}
EXPORT_SYMBOL_GPL
(
snd_hda_power_up
);
/* update the power on/off account with the current jiffies */
void
snd_hda_update_power_acct
(
struct
hda_codec
*
codec
)
{
unsigned
long
delta
=
jiffies
-
codec
->
power_jiffies
;
if
(
codec
->
power_on
)
codec
->
power_on_acct
+=
delta
;
else
codec
->
power_off_acct
+=
delta
;
codec
->
power_jiffies
+=
delta
;
}
/* Transition to powered up, if wait_power_down then wait for a pending
* transition to D3 to complete. A pending D3 transition is indicated
* with power_transition == -1. */
/* call this with codec->power_lock held! */
static
void
__snd_hda_power_up
(
struct
hda_codec
*
codec
,
bool
wait_power_down
)
/**
* snd_hda_power_down - Power-down the codec
* @codec: HD-audio codec
*
* Decrement the usage counter and schedules the autosuspend if none used.
*/
void
snd_hda_power_down
(
struct
hda_codec
*
codec
)
{
/* Return if power_on or transitioning to power_on, unless currently
* powering down. */
if
((
codec
->
power_on
||
codec
->
power_transition
>
0
)
&&
!
(
wait_power_down
&&
codec
->
power_transition
<
0
))
return
;
spin_unlock
(
&
codec
->
power_lock
);
cancel_delayed_work_sync
(
&
codec
->
power_work
);
struct
device
*
dev
=
hda_codec_dev
(
codec
);
spin_lock
(
&
codec
->
power_lock
);
/* If the power down delayed work was cancelled above before starting,
* then there is no need to go through power up here.
*/
if
(
codec
->
power_on
)
{
if
(
codec
->
power_transition
<
0
)
codec
->
power_transition
=
0
;
if
(
codec_in_pm
(
codec
))
return
;
}
trace_hda_power_up
(
codec
);
snd_hda_update_power_acct
(
codec
);
codec
->
power_on
=
1
;
codec
->
power_jiffies
=
jiffies
;
codec
->
power_transition
=
1
;
/* avoid reentrance */
spin_unlock
(
&
codec
->
power_lock
);
hda_call_codec_resume
(
codec
);
spin_lock
(
&
codec
->
power_lock
);
codec
->
power_transition
=
0
;
pm_runtime_mark_last_busy
(
dev
);
pm_runtime_put_autosuspend
(
dev
);
}
EXPORT_SYMBOL_GPL
(
snd_hda_power_down
);
#define power_save(codec) \
((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
/* Transition to powered down */
static
void
__snd_hda_power_down
(
struct
hda_codec
*
codec
)
static
void
codec_set_power_save
(
struct
hda_codec
*
codec
,
int
delay
)
{
if
(
!
codec
->
power_on
||
codec
->
power_count
||
codec
->
power_transition
)
return
;
struct
device
*
dev
=
hda_codec_dev
(
codec
);
if
(
power_save
(
codec
))
{
codec
->
power_transition
=
-
1
;
/* avoid reentrance */
queue_delayed_work
(
codec
->
bus
->
workq
,
&
codec
->
power_work
,
msecs_to_jiffies
(
power_save
(
codec
)
*
1000
));
if
(
delay
>
0
)
{
pm_runtime_set_autosuspend_delay
(
dev
,
delay
);
pm_runtime_use_autosuspend
(
dev
);
pm_runtime_allow
(
dev
);
if
(
!
pm_runtime_suspended
(
dev
))
pm_runtime_mark_last_busy
(
dev
);
}
else
{
pm_runtime_dont_use_autosuspend
(
dev
);
pm_runtime_forbid
(
dev
);
}
}
/**
* snd_hda_power_save - Power-up/down/sync the codec
* @codec: HD-audio codec
* @delta: the counter delta to change
* @d3wait: sync for D3 transition complete
* snd_hda_set_power_save - reprogram autosuspend for the given delay
* @bus: HD-audio bus
* @delay: autosuspend delay in msec, 0 = off
*
* Change the power-up counter via @delta, and power up or down the hardware
* appropriately. For the power-down, queue to the delayed action.
* Passing zero to @delta means to synchronize the power state.
* Synchronize the runtime PM autosuspend state from the power_save option.
*/
void
snd_hda_
power_save
(
struct
hda_codec
*
codec
,
int
delta
,
bool
d3wait
)
void
snd_hda_
set_power_save
(
struct
hda_bus
*
bus
,
int
delay
)
{
spin_lock
(
&
codec
->
power_lock
);
codec
->
power_count
+=
delta
;
trace_hda_power_count
(
codec
);
if
(
delta
>
0
)
__snd_hda_power_up
(
codec
,
d3wait
);
else
__snd_hda_power_down
(
codec
);
spin_unlock
(
&
codec
->
power_lock
);
struct
hda_codec
*
c
;
list_for_each_entry
(
c
,
&
bus
->
codec_list
,
list
)
codec_set_power_save
(
c
,
delay
);
}
EXPORT_SYMBOL_GPL
(
snd_hda_power_save
);
EXPORT_SYMBOL_GPL
(
snd_hda_
set_
power_save
);
/**
* snd_hda_check_amp_list_power - Check the amp list and update the power
...
...
@@ -5157,88 +4843,6 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
EXPORT_SYMBOL_GPL
(
snd_hda_check_amp_list_power
);
#endif
/*
* Channel mode helper
*/
/**
* snd_hda_ch_mode_info - Info callback helper for the channel mode enum
* @codec: the HDA codec
* @uinfo: pointer to get/store the data
* @chmode: channel mode array
* @num_chmodes: channel mode array size
*/
int
snd_hda_ch_mode_info
(
struct
hda_codec
*
codec
,
struct
snd_ctl_elem_info
*
uinfo
,
const
struct
hda_channel_mode
*
chmode
,
int
num_chmodes
)
{
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
uinfo
->
count
=
1
;
uinfo
->
value
.
enumerated
.
items
=
num_chmodes
;
if
(
uinfo
->
value
.
enumerated
.
item
>=
num_chmodes
)
uinfo
->
value
.
enumerated
.
item
=
num_chmodes
-
1
;
sprintf
(
uinfo
->
value
.
enumerated
.
name
,
"%dch"
,
chmode
[
uinfo
->
value
.
enumerated
.
item
].
channels
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_ch_mode_info
);
/**
* snd_hda_ch_mode_get - Get callback helper for the channel mode enum
* @codec: the HDA codec
* @ucontrol: pointer to get/store the data
* @chmode: channel mode array
* @num_chmodes: channel mode array size
* @max_channels: max number of channels
*/
int
snd_hda_ch_mode_get
(
struct
hda_codec
*
codec
,
struct
snd_ctl_elem_value
*
ucontrol
,
const
struct
hda_channel_mode
*
chmode
,
int
num_chmodes
,
int
max_channels
)
{
int
i
;
for
(
i
=
0
;
i
<
num_chmodes
;
i
++
)
{
if
(
max_channels
==
chmode
[
i
].
channels
)
{
ucontrol
->
value
.
enumerated
.
item
[
0
]
=
i
;
break
;
}
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_ch_mode_get
);
/**
* snd_hda_ch_mode_put - Put callback helper for the channel mode enum
* @codec: the HDA codec
* @ucontrol: pointer to get/store the data
* @chmode: channel mode array
* @num_chmodes: channel mode array size
* @max_channelsp: pointer to store the max channels
*/
int
snd_hda_ch_mode_put
(
struct
hda_codec
*
codec
,
struct
snd_ctl_elem_value
*
ucontrol
,
const
struct
hda_channel_mode
*
chmode
,
int
num_chmodes
,
int
*
max_channelsp
)
{
unsigned
int
mode
;
mode
=
ucontrol
->
value
.
enumerated
.
item
[
0
];
if
(
mode
>=
num_chmodes
)
return
-
EINVAL
;
if
(
*
max_channelsp
==
chmode
[
mode
].
channels
)
return
0
;
/* change the current channel setting */
*
max_channelsp
=
chmode
[
mode
].
channels
;
if
(
chmode
[
mode
].
sequence
)
snd_hda_sequence_write_cache
(
codec
,
chmode
[
mode
].
sequence
);
return
1
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_ch_mode_put
);
/*
* input MUX helper
*/
...
...
@@ -5780,77 +5384,26 @@ int snd_hda_add_imux_item(struct hda_codec *codec,
}
EXPORT_SYMBOL_GPL
(
snd_hda_add_imux_item
);
#ifdef CONFIG_PM
/*
* power management
*/
static
void
hda_async_suspend
(
void
*
data
,
async_cookie_t
cookie
)
{
hda_call_codec_suspend
(
data
,
false
);
}
static
void
hda_async_resume
(
void
*
data
,
async_cookie_t
cookie
)
{
hda_call_codec_resume
(
data
);
}
/**
* snd_hda_suspend - suspend the codecs
* @bus: the HDA bus
*
* Returns 0 if successful.
* snd_hda_bus_reset - Reset the bus
* @bus: HD-audio bus
*/
int
snd_hda_suspend
(
struct
hda_bus
*
bus
)
void
snd_hda_bus_reset
(
struct
hda_bus
*
bus
)
{
struct
hda_codec
*
codec
;
ASYNC_DOMAIN_EXCLUSIVE
(
domain
);
list_for_each_entry
(
codec
,
&
bus
->
codec_list
,
list
)
{
/* FIXME: maybe a better way needed for forced reset */
cancel_delayed_work_sync
(
&
codec
->
jackpoll_work
);
#ifdef CONFIG_PM
if
(
hda_codec_is_power_on
(
codec
))
{
if
(
bus
->
num_codecs
>
1
)
async_schedule_domain
(
hda_async_suspend
,
codec
,
&
domain
);
else
hda_call_codec_suspend
(
codec
,
false
);
}
}
if
(
bus
->
num_codecs
>
1
)
async_synchronize_full_domain
(
&
domain
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_suspend
);
/**
* snd_hda_resume - resume the codecs
* @bus: the HDA bus
*
* Returns 0 if successful.
*/
int
snd_hda_resume
(
struct
hda_bus
*
bus
)
{
struct
hda_codec
*
codec
;
ASYNC_DOMAIN_EXCLUSIVE
(
domain
);
list_for_each_entry
(
codec
,
&
bus
->
codec_list
,
list
)
{
if
(
bus
->
num_codecs
>
1
)
async_schedule_domain
(
hda_async_resume
,
codec
,
&
domain
);
else
hda_call_codec_suspend
(
codec
);
hda_call_codec_resume
(
codec
);
}
#endif
}
if
(
bus
->
num_codecs
>
1
)
async_synchronize_full_domain
(
&
domain
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_resume
);
#endif
/* CONFIG_PM */
EXPORT_SYMBOL_GPL
(
snd_hda_bus_reset
);
/*
* generic arrays
...
...
sound/pci/hda/hda_codec.h
View file @
8f88f025
...
...
@@ -83,10 +83,6 @@ struct hda_bus_ops {
struct
hda_pcm
*
pcm
);
/* reset bus for retry verb */
void
(
*
bus_reset
)(
struct
hda_bus
*
bus
);
#ifdef CONFIG_PM
/* notify power-up/down from codec to controller */
void
(
*
pm_notify
)(
struct
hda_bus
*
bus
,
bool
power_up
);
#endif
#ifdef CONFIG_SND_HDA_DSP_LOADER
/* prepare DSP transfer */
int
(
*
load_dsp_prepare
)(
struct
hda_bus
*
bus
,
unsigned
int
format
,
...
...
@@ -122,7 +118,6 @@ struct hda_bus {
void
*
private_data
;
struct
pci_dev
*
pci
;
const
char
*
modelname
;
int
*
power_save
;
struct
hda_bus_ops
ops
;
/* codec linked list */
...
...
@@ -151,10 +146,10 @@ struct hda_bus {
unsigned
int
rirb_error
:
1
;
/* error in codec communication */
unsigned
int
response_reset
:
1
;
/* controller was reset */
unsigned
int
in_reset
:
1
;
/* during reset operation */
unsigned
int
power_keep_link_on
:
1
;
/* don't power off HDA link */
unsigned
int
no_response_fallback
:
1
;
/* don't fallback at RIRB error */
int
primary_dig_out_type
;
/* primary digital out PCM type */
unsigned
long
codec_powered
;
/* bit flags of powered codecs */
};
/*
...
...
@@ -174,15 +169,22 @@ struct hda_codec_preset {
int
(
*
patch
)(
struct
hda_codec
*
codec
);
};
struct
hda_codec_preset_list
{
#define HDA_CODEC_ID_GENERIC_HDMI 0x00000101
#define HDA_CODEC_ID_GENERIC 0x00000201
struct
hda_codec_driver
{
struct
device_driver
driver
;
const
struct
hda_codec_preset
*
preset
;
struct
module
*
owner
;
struct
list_head
list
;
};
/* initial hook */
int
snd_hda_add_codec_preset
(
struct
hda_codec_preset_list
*
preset
);
int
snd_hda_delete_codec_preset
(
struct
hda_codec_preset_list
*
preset
);
int
__hda_codec_driver_register
(
struct
hda_codec_driver
*
drv
,
const
char
*
name
,
struct
module
*
owner
);
#define hda_codec_driver_register(drv) \
__hda_codec_driver_register(drv, KBUILD_MODNAME, THIS_MODULE)
void
hda_codec_driver_unregister
(
struct
hda_codec_driver
*
drv
);
#define module_hda_codec_driver(drv) \
module_driver(drv, hda_codec_driver_register, \
hda_codec_driver_unregister)
/* ops set by the preset patch */
struct
hda_codec_ops
{
...
...
@@ -286,11 +288,10 @@ struct hda_codec {
u32
vendor_id
;
u32
subsystem_id
;
u32
revision_id
;
u32
probe_id
;
/* overridden id for probing */
/* detected preset */
const
struct
hda_codec_preset
*
preset
;
struct
module
*
owner
;
int
(
*
parser
)(
struct
hda_codec
*
codec
);
const
char
*
vendor_name
;
/* codec vendor name */
const
char
*
chip_name
;
/* codec chip name */
const
char
*
modelname
;
/* model name for preset */
...
...
@@ -366,17 +367,11 @@ struct hda_codec {
unsigned
int
dp_mst
:
1
;
/* support DP1.2 Multi-stream transport */
unsigned
int
dump_coef
:
1
;
/* dump processing coefs in codec proc file */
#ifdef CONFIG_PM
unsigned
int
power_on
:
1
;
/* current (global) power-state */
unsigned
int
d3_stop_clk
:
1
;
/* support D3 operation without BCLK */
unsigned
int
pm_up_notified
:
1
;
/* PM notified to controller */
unsigned
int
in_pm
:
1
;
/* suspend/resume being performed */
int
power_transition
;
/* power-state in transition */
int
power_count
;
/* current (global) power refcount */
struct
delayed_work
power_work
;
/* delayed task for powerdown */
atomic_t
in_pm
;
/* suspend/resume being performed */
unsigned
long
power_on_acct
;
unsigned
long
power_off_acct
;
unsigned
long
power_jiffies
;
spinlock_t
power_lock
;
#endif
/* filter the requested power state per nid */
...
...
@@ -408,6 +403,11 @@ struct hda_codec {
struct
snd_array
verbs
;
};
#define dev_to_hda_codec(_dev) container_of(_dev, struct hda_codec, dev)
#define hda_codec_dev(_dev) (&(_dev)->dev)
extern
struct
bus_type
snd_hda_bus_type
;
/* direction */
enum
{
HDA_INPUT
,
HDA_OUTPUT
...
...
@@ -556,14 +556,12 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
int
snd_hda_lock_devices
(
struct
hda_bus
*
bus
);
void
snd_hda_unlock_devices
(
struct
hda_bus
*
bus
);
void
snd_hda_bus_reset
(
struct
hda_bus
*
bus
);
/*
* power management
*/
#ifdef CONFIG_PM
int
snd_hda_suspend
(
struct
hda_bus
*
bus
);
int
snd_hda_resume
(
struct
hda_bus
*
bus
);
#endif
extern
const
struct
dev_pm_ops
hda_codec_driver_pm
;
static
inline
int
hda_call_check_power_status
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
)
...
...
@@ -586,64 +584,16 @@ const char *snd_hda_get_jack_location(u32 cfg);
* power saving
*/
#ifdef CONFIG_PM
void
snd_hda_power_save
(
struct
hda_codec
*
codec
,
int
delta
,
bool
d3wait
);
void
snd_hda_power_up
(
struct
hda_codec
*
codec
);
void
snd_hda_power_down
(
struct
hda_codec
*
codec
);
void
snd_hda_set_power_save
(
struct
hda_bus
*
bus
,
int
delay
);
void
snd_hda_update_power_acct
(
struct
hda_codec
*
codec
);
#else
static
inline
void
snd_hda_power_save
(
struct
hda_codec
*
codec
,
int
delta
,
bool
d3wait
)
{}
static
inline
void
snd_hda_power_up
(
struct
hda_codec
*
codec
)
{}
static
inline
void
snd_hda_power_down
(
struct
hda_codec
*
codec
)
{}
static
inline
void
snd_hda_set_power_save
(
struct
hda_bus
*
bus
,
int
delay
)
{}
#endif
/**
* snd_hda_power_up - Power-up the codec
* @codec: HD-audio codec
*
* Increment the power-up counter and power up the hardware really when
* not turned on yet.
*/
static
inline
void
snd_hda_power_up
(
struct
hda_codec
*
codec
)
{
snd_hda_power_save
(
codec
,
1
,
false
);
}
/**
* snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending
* D3 transition to complete. This differs from snd_hda_power_up() when
* power_transition == -1. snd_hda_power_up sees this case as a nop,
* snd_hda_power_up_d3wait waits for the D3 transition to complete then powers
* back up.
* @codec: HD-audio codec
*
* Cancel any power down operation hapenning on the work queue, then power up.
*/
static
inline
void
snd_hda_power_up_d3wait
(
struct
hda_codec
*
codec
)
{
snd_hda_power_save
(
codec
,
1
,
true
);
}
/**
* snd_hda_power_down - Power-down the codec
* @codec: HD-audio codec
*
* Decrement the power-up counter and schedules the power-off work if
* the counter rearches to zero.
*/
static
inline
void
snd_hda_power_down
(
struct
hda_codec
*
codec
)
{
snd_hda_power_save
(
codec
,
-
1
,
false
);
}
/**
* snd_hda_power_sync - Synchronize the power-save status
* @codec: HD-audio codec
*
* Synchronize the actual power state with the power account;
* called when power_save parameter is changed
*/
static
inline
void
snd_hda_power_sync
(
struct
hda_codec
*
codec
)
{
snd_hda_power_save
(
codec
,
0
,
false
);
}
#ifdef CONFIG_SND_HDA_PATCH_LOADER
/*
* patch firmware
...
...
sound/pci/hda/hda_controller.c
View file @
8f88f025
...
...
@@ -258,11 +258,18 @@ static void azx_timecounter_init(struct snd_pcm_substream *substream,
tc
->
cycle_last
=
last
;
}
static
inline
struct
hda_pcm_stream
*
to_hda_pcm_stream
(
struct
snd_pcm_substream
*
substream
)
{
struct
azx_pcm
*
apcm
=
snd_pcm_substream_chip
(
substream
);
return
&
apcm
->
info
->
stream
[
substream
->
stream
];
}
static
u64
azx_adjust_codec_delay
(
struct
snd_pcm_substream
*
substream
,
u64
nsec
)
{
struct
azx_pcm
*
apcm
=
snd_pcm_substream_chip
(
substream
);
struct
hda_pcm_stream
*
hinfo
=
apcm
->
hinfo
[
substream
->
stream
]
;
struct
hda_pcm_stream
*
hinfo
=
to_hda_pcm_stream
(
substream
)
;
u64
codec_frames
,
codec_nsecs
;
if
(
!
hinfo
->
ops
.
get_delay
)
...
...
@@ -398,7 +405,7 @@ static int azx_setup_periods(struct azx *chip,
static
int
azx_pcm_close
(
struct
snd_pcm_substream
*
substream
)
{
struct
azx_pcm
*
apcm
=
snd_pcm_substream_chip
(
substream
);
struct
hda_pcm_stream
*
hinfo
=
apcm
->
hinfo
[
substream
->
stream
]
;
struct
hda_pcm_stream
*
hinfo
=
to_hda_pcm_stream
(
substream
)
;
struct
azx
*
chip
=
apcm
->
chip
;
struct
azx_dev
*
azx_dev
=
get_azx_dev
(
substream
);
unsigned
long
flags
;
...
...
@@ -440,7 +447,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
struct
azx_pcm
*
apcm
=
snd_pcm_substream_chip
(
substream
);
struct
azx_dev
*
azx_dev
=
get_azx_dev
(
substream
);
struct
azx
*
chip
=
apcm
->
chip
;
struct
hda_pcm_stream
*
hinfo
=
apcm
->
hinfo
[
substream
->
stream
]
;
struct
hda_pcm_stream
*
hinfo
=
to_hda_pcm_stream
(
substream
)
;
int
err
;
/* reset BDL address */
...
...
@@ -467,7 +474,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
struct
azx_pcm
*
apcm
=
snd_pcm_substream_chip
(
substream
);
struct
azx
*
chip
=
apcm
->
chip
;
struct
azx_dev
*
azx_dev
=
get_azx_dev
(
substream
);
struct
hda_pcm_stream
*
hinfo
=
apcm
->
hinfo
[
substream
->
stream
]
;
struct
hda_pcm_stream
*
hinfo
=
to_hda_pcm_stream
(
substream
)
;
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
unsigned
int
bufsize
,
period_bytes
,
format_val
,
stream_tag
;
int
err
;
...
...
@@ -707,7 +714,7 @@ unsigned int azx_get_position(struct azx *chip,
if
(
substream
->
runtime
)
{
struct
azx_pcm
*
apcm
=
snd_pcm_substream_chip
(
substream
);
struct
hda_pcm_stream
*
hinfo
=
apcm
->
hinfo
[
stream
]
;
struct
hda_pcm_stream
*
hinfo
=
to_hda_pcm_stream
(
substream
)
;
if
(
chip
->
get_delay
[
stream
])
delay
+=
chip
->
get_delay
[
stream
](
chip
,
azx_dev
,
pos
);
...
...
@@ -790,7 +797,7 @@ static struct snd_pcm_hardware azx_pcm_hw = {
static
int
azx_pcm_open
(
struct
snd_pcm_substream
*
substream
)
{
struct
azx_pcm
*
apcm
=
snd_pcm_substream_chip
(
substream
);
struct
hda_pcm_stream
*
hinfo
=
apcm
->
hinfo
[
substream
->
stream
]
;
struct
hda_pcm_stream
*
hinfo
=
to_hda_pcm_stream
(
substream
)
;
struct
azx
*
chip
=
apcm
->
chip
;
struct
azx_dev
*
azx_dev
;
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
...
...
@@ -836,7 +843,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
buff_step
);
snd_pcm_hw_constraint_step
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_PERIOD_BYTES
,
buff_step
);
snd_hda_power_up
_d3wait
(
apcm
->
codec
);
snd_hda_power_up
(
apcm
->
codec
);
err
=
hinfo
->
ops
.
open
(
hinfo
,
apcm
->
codec
,
substream
);
if
(
err
<
0
)
{
azx_release_device
(
azx_dev
);
...
...
@@ -904,6 +911,7 @@ static void azx_pcm_free(struct snd_pcm *pcm)
struct
azx_pcm
*
apcm
=
pcm
->
private_data
;
if
(
apcm
)
{
list_del
(
&
apcm
->
list
);
apcm
->
info
->
pcm
=
NULL
;
kfree
(
apcm
);
}
}
...
...
@@ -940,6 +948,7 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
apcm
->
chip
=
chip
;
apcm
->
pcm
=
pcm
;
apcm
->
codec
=
codec
;
apcm
->
info
=
cpcm
;
pcm
->
private_data
=
apcm
;
pcm
->
private_free
=
azx_pcm_free
;
if
(
cpcm
->
pcm_type
==
HDA_PCM_TYPE_MODEM
)
...
...
@@ -947,7 +956,6 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
list_add_tail
(
&
apcm
->
list
,
&
chip
->
pcm_list
);
cpcm
->
pcm
=
pcm
;
for
(
s
=
0
;
s
<
2
;
s
++
)
{
apcm
->
hinfo
[
s
]
=
&
cpcm
->
stream
[
s
];
if
(
cpcm
->
stream
[
s
].
substreams
)
snd_pcm_set_ops
(
pcm
,
s
,
&
azx_pcm_ops
);
}
...
...
@@ -958,9 +966,6 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
snd_pcm_lib_preallocate_pages_for_all
(
pcm
,
SNDRV_DMA_TYPE_DEV_SG
,
chip
->
card
->
dev
,
size
,
MAX_PREALLOC_SIZE
);
/* link to codec */
for
(
s
=
0
;
s
<
2
;
s
++
)
pcm
->
streams
[
s
].
dev
.
parent
=
&
codec
->
dev
;
return
0
;
}
...
...
@@ -1778,34 +1783,11 @@ static void azx_bus_reset(struct hda_bus *bus)
bus
->
in_reset
=
1
;
azx_stop_chip
(
chip
);
azx_init_chip
(
chip
,
true
);
#ifdef CONFIG_PM
if
(
chip
->
initialized
)
{
struct
azx_pcm
*
p
;
list_for_each_entry
(
p
,
&
chip
->
pcm_list
,
list
)
snd_pcm_suspend_all
(
p
->
pcm
);
snd_hda_suspend
(
chip
->
bus
);
snd_hda_resume
(
chip
->
bus
);
}
#endif
if
(
chip
->
initialized
)
snd_hda_bus_reset
(
chip
->
bus
);
bus
->
in_reset
=
0
;
}
#ifdef CONFIG_PM
/* power-up/down the controller */
static
void
azx_power_notify
(
struct
hda_bus
*
bus
,
bool
power_up
)
{
struct
azx
*
chip
=
bus
->
private_data
;
if
(
!
azx_has_pm_runtime
(
chip
))
return
;
if
(
power_up
)
pm_runtime_get_sync
(
chip
->
card
->
dev
);
else
pm_runtime_put_sync
(
chip
->
card
->
dev
);
}
#endif
static
int
get_jackpoll_interval
(
struct
azx
*
chip
)
{
int
i
;
...
...
@@ -1832,9 +1814,6 @@ static struct hda_bus_ops bus_ops = {
.
get_response
=
azx_get_response
,
.
attach_pcm
=
azx_attach_pcm_stream
,
.
bus_reset
=
azx_bus_reset
,
#ifdef CONFIG_PM
.
pm_notify
=
azx_power_notify
,
#endif
#ifdef CONFIG_SND_HDA_DSP_LOADER
.
load_dsp_prepare
=
azx_load_dsp_prepare
,
.
load_dsp_trigger
=
azx_load_dsp_trigger
,
...
...
@@ -1843,7 +1822,7 @@ static struct hda_bus_ops bus_ops = {
};
/* HD-audio bus initialization */
int
azx_bus_create
(
struct
azx
*
chip
,
const
char
*
model
,
int
*
power_save_to
)
int
azx_bus_create
(
struct
azx
*
chip
,
const
char
*
model
)
{
struct
hda_bus
*
bus
;
int
err
;
...
...
@@ -1857,9 +1836,6 @@ int azx_bus_create(struct azx *chip, const char *model, int *power_save_to)
bus
->
pci
=
chip
->
pci
;
bus
->
modelname
=
model
;
bus
->
ops
=
bus_ops
;
#ifdef CONFIG_PM
bus
->
power_save
=
power_save_to
;
#endif
if
(
chip
->
driver_caps
&
AZX_DCAPS_RIRB_DELAY
)
{
dev_dbg
(
chip
->
card
->
dev
,
"Enable delay in RIRB handling
\n
"
);
...
...
sound/pci/hda/hda_controller.h
View file @
8f88f025
...
...
@@ -283,7 +283,7 @@ struct azx_pcm {
struct
azx
*
chip
;
struct
snd_pcm
*
pcm
;
struct
hda_codec
*
codec
;
struct
hda_pcm
_stream
*
hinfo
[
2
]
;
struct
hda_pcm
*
info
;
struct
list_head
list
;
};
...
...
@@ -432,7 +432,7 @@ void azx_enter_link_reset(struct azx *chip);
irqreturn_t
azx_interrupt
(
int
irq
,
void
*
dev_id
);
/* Codec interface */
int
azx_bus_create
(
struct
azx
*
chip
,
const
char
*
model
,
int
*
power_save_to
);
int
azx_bus_create
(
struct
azx
*
chip
,
const
char
*
model
);
int
azx_probe_codecs
(
struct
azx
*
chip
,
unsigned
int
max_slots
);
int
azx_codec_configure
(
struct
azx
*
chip
);
int
azx_init_stream
(
struct
azx
*
chip
);
...
...
sound/pci/hda/hda_generic.c
View file @
8f88f025
...
...
@@ -5524,13 +5524,11 @@ static const struct hda_codec_ops generic_patch_ops = {
#endif
};
/*
*
/*
* snd_hda_parse_generic_codec - Generic codec parser
* @codec: the HDA codec
*
* This should be called from the HDA codec core.
*/
int
snd_hda_parse_generic_codec
(
struct
hda_codec
*
codec
)
static
int
snd_hda_parse_generic_codec
(
struct
hda_codec
*
codec
)
{
struct
hda_gen_spec
*
spec
;
int
err
;
...
...
@@ -5556,7 +5554,17 @@ int snd_hda_parse_generic_codec(struct hda_codec *codec)
snd_hda_gen_free
(
codec
);
return
err
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_parse_generic_codec
);
static
const
struct
hda_codec_preset
snd_hda_preset_generic
[]
=
{
{
.
id
=
HDA_CODEC_ID_GENERIC
,
.
patch
=
snd_hda_parse_generic_codec
},
{}
/* terminator */
};
static
struct
hda_codec_driver
generic_driver
=
{
.
preset
=
snd_hda_preset_generic
,
};
module_hda_codec_driver
(
generic_driver
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Generic HD-audio codec parser"
);
sound/pci/hda/hda_hwdep.c
View file @
8f88f025
...
...
@@ -116,9 +116,6 @@ int snd_hda_create_hwdep(struct hda_codec *codec)
hwdep
->
ops
.
ioctl_compat
=
hda_hwdep_ioctl_compat
;
#endif
/* link to codec */
hwdep
->
dev
.
parent
=
&
codec
->
dev
;
/* for sysfs */
hwdep
->
dev
.
groups
=
snd_hda_dev_attr_groups
;
dev_set_drvdata
(
&
hwdep
->
dev
,
codec
);
...
...
sound/pci/hda/hda_intel.c
View file @
8f88f025
...
...
@@ -173,7 +173,6 @@ static struct kernel_param_ops param_ops_xint = {
#define param_check_xint param_check_int
static
int
power_save
=
CONFIG_SND_HDA_POWER_SAVE_DEFAULT
;
static
int
*
power_save_addr
=
&
power_save
;
module_param
(
power_save
,
xint
,
0644
);
MODULE_PARM_DESC
(
power_save
,
"Automatic power-saving timeout "
"(in second, 0 = disable)."
);
...
...
@@ -186,7 +185,7 @@ static bool power_save_controller = 1;
module_param
(
power_save_controller
,
bool
,
0644
);
MODULE_PARM_DESC
(
power_save_controller
,
"Reset controller in power save mode."
);
#else
static
int
*
power_save_addr
;
#define power_save 0
#endif
/* CONFIG_PM */
static
int
align_buffer_size
=
-
1
;
...
...
@@ -740,7 +739,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
{
struct
hda_intel
*
hda
;
struct
azx
*
chip
;
struct
hda_codec
*
c
;
int
prev
=
power_save
;
int
ret
=
param_set_int
(
val
,
kp
);
...
...
@@ -752,8 +750,7 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
chip
=
&
hda
->
chip
;
if
(
!
chip
->
bus
||
chip
->
disabled
)
continue
;
list_for_each_entry
(
c
,
&
chip
->
bus
->
codec_list
,
list
)
snd_hda_power_sync
(
c
);
snd_hda_set_power_save
(
chip
->
bus
,
power_save
*
1000
);
}
mutex_unlock
(
&
card_list_lock
);
return
0
;
...
...
@@ -772,7 +769,6 @@ static int azx_suspend(struct device *dev)
struct
snd_card
*
card
=
dev_get_drvdata
(
dev
);
struct
azx
*
chip
;
struct
hda_intel
*
hda
;
struct
azx_pcm
*
p
;
if
(
!
card
)
return
0
;
...
...
@@ -784,10 +780,6 @@ static int azx_suspend(struct device *dev)
snd_power_change_state
(
card
,
SNDRV_CTL_POWER_D3hot
);
azx_clear_irq_pending
(
chip
);
list_for_each_entry
(
p
,
&
chip
->
pcm_list
,
list
)
snd_pcm_suspend_all
(
p
->
pcm
);
if
(
chip
->
initialized
)
snd_hda_suspend
(
chip
->
bus
);
azx_stop_chip
(
chip
);
azx_enter_link_reset
(
chip
);
if
(
chip
->
irq
>=
0
)
{
...
...
@@ -830,7 +822,6 @@ static int azx_resume(struct device *dev)
azx_init_chip
(
chip
,
true
);
snd_hda_resume
(
chip
->
bus
);
snd_power_change_state
(
card
,
SNDRV_CTL_POWER_D0
);
return
0
;
}
...
...
@@ -927,7 +918,8 @@ static int azx_runtime_idle(struct device *dev)
if
(
chip
->
disabled
||
hda
->
init_failed
)
return
0
;
if
(
!
power_save_controller
||
!
azx_has_pm_runtime
(
chip
))
if
(
!
power_save_controller
||
!
azx_has_pm_runtime
(
chip
)
||
chip
->
bus
->
codec_powered
)
return
-
EBUSY
;
return
0
;
...
...
@@ -1612,19 +1604,6 @@ static int azx_first_init(struct azx *chip)
return
0
;
}
static
void
power_down_all_codecs
(
struct
azx
*
chip
)
{
#ifdef CONFIG_PM
/* The codecs were powered up in snd_hda_codec_new().
* Now all initialization done, so turn them down if possible
*/
struct
hda_codec
*
codec
;
list_for_each_entry
(
codec
,
&
chip
->
bus
->
codec_list
,
list
)
{
snd_hda_power_down
(
codec
);
}
#endif
}
#ifdef CONFIG_SND_HDA_PATCH_LOADER
/* callback from request_firmware_nowait() */
static
void
azx_firmware_cb
(
const
struct
firmware
*
fw
,
void
*
context
)
...
...
@@ -1893,7 +1872,7 @@ static int azx_probe_continue(struct azx *chip)
#endif
/* create codec instances */
err
=
azx_bus_create
(
chip
,
model
[
dev
]
,
power_save_addr
);
err
=
azx_bus_create
(
chip
,
model
[
dev
]);
if
(
err
<
0
)
goto
out_free
;
...
...
@@ -1934,9 +1913,9 @@ static int azx_probe_continue(struct azx *chip)
goto
out_free
;
chip
->
running
=
1
;
power_down_all_codecs
(
chip
);
azx_notifier_register
(
chip
);
azx_add_card_list
(
chip
);
snd_hda_set_power_save
(
chip
->
bus
,
power_save
*
1000
);
if
(
azx_has_pm_runtime
(
chip
)
||
hda
->
use_vga_switcheroo
)
pm_runtime_put_noidle
(
&
pci
->
dev
);
...
...
sound/pci/hda/hda_local.h
View file @
8f88f025
...
...
@@ -272,29 +272,6 @@ int snd_hda_add_imux_item(struct hda_codec *codec,
struct
hda_input_mux
*
imux
,
const
char
*
label
,
int
index
,
int
*
type_index_ret
);
/*
* Channel mode helper
*/
struct
hda_channel_mode
{
int
channels
;
const
struct
hda_verb
*
sequence
;
};
int
snd_hda_ch_mode_info
(
struct
hda_codec
*
codec
,
struct
snd_ctl_elem_info
*
uinfo
,
const
struct
hda_channel_mode
*
chmode
,
int
num_chmodes
);
int
snd_hda_ch_mode_get
(
struct
hda_codec
*
codec
,
struct
snd_ctl_elem_value
*
ucontrol
,
const
struct
hda_channel_mode
*
chmode
,
int
num_chmodes
,
int
max_channels
);
int
snd_hda_ch_mode_put
(
struct
hda_codec
*
codec
,
struct
snd_ctl_elem_value
*
ucontrol
,
const
struct
hda_channel_mode
*
chmode
,
int
num_chmodes
,
int
*
max_channelsp
);
/*
* Multi-channel / digital-out PCM helper
*/
...
...
@@ -350,12 +327,6 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
int
snd_hda_multi_out_analog_cleanup
(
struct
hda_codec
*
codec
,
struct
hda_multi_out
*
mout
);
/*
* generic codec parser
*/
int
snd_hda_parse_generic_codec
(
struct
hda_codec
*
codec
);
int
snd_hda_parse_hdmi_codec
(
struct
hda_codec
*
codec
);
/*
* generic proc interface
*/
...
...
@@ -783,9 +754,13 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
/*
*/
#define codec_err(codec, fmt, args...) dev_err(&(codec)->dev, fmt, ##args)
#define codec_warn(codec, fmt, args...) dev_warn(&(codec)->dev, fmt, ##args)
#define codec_info(codec, fmt, args...) dev_info(&(codec)->dev, fmt, ##args)
#define codec_dbg(codec, fmt, args...) dev_dbg(&(codec)->dev, fmt, ##args)
#define codec_err(codec, fmt, args...) \
dev_err(hda_codec_dev(codec), fmt, ##args)
#define codec_warn(codec, fmt, args...) \
dev_warn(hda_codec_dev(codec), fmt, ##args)
#define codec_info(codec, fmt, args...) \
dev_info(hda_codec_dev(codec), fmt, ##args)
#define codec_dbg(codec, fmt, args...) \
dev_dbg(hda_codec_dev(codec), fmt, ##args)
#endif
/* __SOUND_HDA_LOCAL_H */
sound/pci/hda/hda_tegra.c
View file @
8f88f025
...
...
@@ -81,7 +81,7 @@ module_param(power_save, bint, 0644);
MODULE_PARM_DESC
(
power_save
,
"Automatic power-saving timeout (in seconds, 0 = disable)."
);
#else
static
int
power_save
=
0
;
#define power_save 0
#endif
/*
...
...
@@ -249,14 +249,9 @@ static int hda_tegra_suspend(struct device *dev)
{
struct
snd_card
*
card
=
dev_get_drvdata
(
dev
);
struct
azx
*
chip
=
card
->
private_data
;
struct
azx_pcm
*
p
;
struct
hda_tegra
*
hda
=
container_of
(
chip
,
struct
hda_tegra
,
chip
);
snd_power_change_state
(
card
,
SNDRV_CTL_POWER_D3hot
);
list_for_each_entry
(
p
,
&
chip
->
pcm_list
,
list
)
snd_pcm_suspend_all
(
p
->
pcm
);
if
(
chip
->
initialized
)
snd_hda_suspend
(
chip
->
bus
);
azx_stop_chip
(
chip
);
azx_enter_link_reset
(
chip
);
...
...
@@ -277,7 +272,6 @@ static int hda_tegra_resume(struct device *dev)
azx_init_chip
(
chip
,
1
);
snd_hda_resume
(
chip
->
bus
);
snd_power_change_state
(
card
,
SNDRV_CTL_POWER_D0
);
return
0
;
...
...
@@ -343,17 +337,6 @@ static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev)
return
0
;
}
/*
* The codecs were powered up in snd_hda_codec_new().
* Now all initialization done, so turn them down if possible
*/
static
void
power_down_all_codecs
(
struct
azx
*
chip
)
{
struct
hda_codec
*
codec
;
list_for_each_entry
(
codec
,
&
chip
->
bus
->
codec_list
,
list
)
snd_hda_power_down
(
codec
);
}
static
int
hda_tegra_first_init
(
struct
azx
*
chip
,
struct
platform_device
*
pdev
)
{
struct
snd_card
*
card
=
chip
->
card
;
...
...
@@ -502,7 +485,7 @@ static int hda_tegra_probe(struct platform_device *pdev)
goto
out_free
;
/* create codec instances */
err
=
azx_bus_create
(
chip
,
NULL
,
&
power_save
);
err
=
azx_bus_create
(
chip
,
NULL
);
if
(
err
<
0
)
goto
out_free
;
...
...
@@ -529,8 +512,8 @@ static int hda_tegra_probe(struct platform_device *pdev)
goto
out_free
;
chip
->
running
=
1
;
power_down_all_codecs
(
chip
);
azx_notifier_register
(
chip
);
snd_hda_set_power_save
(
chip
->
bus
,
power_save
*
1000
);
return
0
;
...
...
sound/pci/hda/hda_trace.h
View file @
8f88f025
...
...
@@ -87,30 +87,6 @@ DEFINE_EVENT(hda_power, hda_power_up,
TP_PROTO
(
struct
hda_codec
*
codec
),
TP_ARGS
(
codec
)
);
TRACE_EVENT
(
hda_power_count
,
TP_PROTO
(
struct
hda_codec
*
codec
),
TP_ARGS
(
codec
),
TP_STRUCT__entry
(
__field
(
unsigned
int
,
card
)
__field
(
unsigned
int
,
addr
)
__field
(
int
,
power_count
)
__field
(
int
,
power_on
)
__field
(
int
,
power_transition
)
),
TP_fast_assign
(
__entry
->
card
=
(
codec
)
->
bus
->
card
->
number
;
__entry
->
addr
=
(
codec
)
->
addr
;
__entry
->
power_count
=
(
codec
)
->
power_count
;
__entry
->
power_on
=
(
codec
)
->
power_on
;
__entry
->
power_transition
=
(
codec
)
->
power_transition
;
),
TP_printk
(
"[%d:%d] power_count=%d, power_on=%d, power_transition=%d"
,
__entry
->
card
,
__entry
->
addr
,
__entry
->
power_count
,
__entry
->
power_on
,
__entry
->
power_transition
)
);
#endif
/* CONFIG_PM */
TRACE_EVENT
(
hda_unsol_event
,
...
...
sound/pci/hda/patch_analog.c
View file @
8f88f025
...
...
@@ -1194,20 +1194,8 @@ MODULE_ALIAS("snd-hda-codec-id:11d4*");
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Analog Devices HD-audio codec"
);
static
struct
hda_codec_
preset_list
analog_list
=
{
static
struct
hda_codec_
driver
analog_driver
=
{
.
preset
=
snd_hda_preset_analog
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_analog_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
analog_list
);
}
static
void
__exit
patch_analog_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
analog_list
);
}
module_init
(
patch_analog_init
)
module_exit
(
patch_analog_exit
)
module_hda_codec_driver
(
analog_driver
);
sound/pci/hda/patch_ca0110.c
View file @
8f88f025
...
...
@@ -98,20 +98,8 @@ MODULE_ALIAS("snd-hda-codec-id:1102000d");
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Creative CA0110-IBG HD-audio codec"
);
static
struct
hda_codec_
preset_list
ca0110_list
=
{
static
struct
hda_codec_
driver
ca0110_driver
=
{
.
preset
=
snd_hda_preset_ca0110
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_ca0110_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
ca0110_list
);
}
static
void
__exit
patch_ca0110_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
ca0110_list
);
}
module_init
(
patch_ca0110_init
)
module_exit
(
patch_ca0110_exit
)
module_hda_codec_driver
(
ca0110_driver
);
sound/pci/hda/patch_ca0132.c
View file @
8f88f025
...
...
@@ -4702,20 +4702,8 @@ MODULE_ALIAS("snd-hda-codec-id:11020011");
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Creative Sound Core3D codec"
);
static
struct
hda_codec_
preset_list
ca0132_list
=
{
static
struct
hda_codec_
driver
ca0132_driver
=
{
.
preset
=
snd_hda_preset_ca0132
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_ca0132_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
ca0132_list
);
}
static
void
__exit
patch_ca0132_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
ca0132_list
);
}
module_init
(
patch_ca0132_init
)
module_exit
(
patch_ca0132_exit
)
module_hda_codec_driver
(
ca0132_driver
);
sound/pci/hda/patch_cirrus.c
View file @
8f88f025
...
...
@@ -1221,20 +1221,8 @@ MODULE_ALIAS("snd-hda-codec-id:10134213");
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Cirrus Logic HD-audio codec"
);
static
struct
hda_codec_
preset_list
cirrus_list
=
{
static
struct
hda_codec_
driver
cirrus_driver
=
{
.
preset
=
snd_hda_preset_cirrus
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_cirrus_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
cirrus_list
);
}
static
void
__exit
patch_cirrus_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
cirrus_list
);
}
module_init
(
patch_cirrus_init
)
module_exit
(
patch_cirrus_exit
)
module_hda_codec_driver
(
cirrus_driver
);
sound/pci/hda/patch_cmedia.c
View file @
8f88f025
...
...
@@ -137,20 +137,8 @@ MODULE_ALIAS("snd-hda-codec-id:434d4980");
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"C-Media HD-audio codec"
);
static
struct
hda_codec_
preset_list
cmedia_list
=
{
static
struct
hda_codec_
driver
cmedia_driver
=
{
.
preset
=
snd_hda_preset_cmedia
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_cmedia_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
cmedia_list
);
}
static
void
__exit
patch_cmedia_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
cmedia_list
);
}
module_init
(
patch_cmedia_init
)
module_exit
(
patch_cmedia_exit
)
module_hda_codec_driver
(
cmedia_driver
);
sound/pci/hda/patch_conexant.c
View file @
8f88f025
...
...
@@ -1018,20 +1018,8 @@ MODULE_ALIAS("snd-hda-codec-id:14f151d7");
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Conexant HD-audio codec"
);
static
struct
hda_codec_
preset_list
conexant_list
=
{
static
struct
hda_codec_
driver
conexant_driver
=
{
.
preset
=
snd_hda_preset_conexant
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_conexant_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
conexant_list
);
}
static
void
__exit
patch_conexant_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
conexant_list
);
}
module_init
(
patch_conexant_init
)
module_exit
(
patch_conexant_exit
)
module_hda_codec_driver
(
conexant_driver
);
sound/pci/hda/patch_hdmi.c
View file @
8f88f025
...
...
@@ -3300,15 +3300,6 @@ static int patch_via_hdmi(struct hda_codec *codec)
return
patch_simple_hdmi
(
codec
,
VIAHDMI_CVT_NID
,
VIAHDMI_PIN_NID
);
}
/*
* called from hda_codec.c for generic HDMI support
*/
int
snd_hda_parse_hdmi_codec
(
struct
hda_codec
*
codec
)
{
return
patch_generic_hdmi
(
codec
);
}
EXPORT_SYMBOL_GPL
(
snd_hda_parse_hdmi_codec
);
/*
* patch entries
*/
...
...
@@ -3373,6 +3364,8 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
{
.
id
=
0x80862882
,
.
name
=
"Valleyview2 HDMI"
,
.
patch
=
patch_generic_hdmi
},
{
.
id
=
0x80862883
,
.
name
=
"Braswell HDMI"
,
.
patch
=
patch_generic_hdmi
},
{
.
id
=
0x808629fb
,
.
name
=
"Crestline HDMI"
,
.
patch
=
patch_generic_hdmi
},
/* special ID for generic HDMI */
{
.
id
=
HDA_CODEC_ID_GENERIC_HDMI
,
.
patch
=
patch_generic_hdmi
},
{}
/* terminator */
};
...
...
@@ -3442,20 +3435,8 @@ MODULE_ALIAS("snd-hda-codec-intelhdmi");
MODULE_ALIAS
(
"snd-hda-codec-nvhdmi"
);
MODULE_ALIAS
(
"snd-hda-codec-atihdmi"
);
static
struct
hda_codec_
preset_list
intel_list
=
{
static
struct
hda_codec_
driver
hdmi_driver
=
{
.
preset
=
snd_hda_preset_hdmi
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_hdmi_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
intel_list
);
}
static
void
__exit
patch_hdmi_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
intel_list
);
}
module_init
(
patch_hdmi_init
)
module_exit
(
patch_hdmi_exit
)
module_hda_codec_driver
(
hdmi_driver
);
sound/pci/hda/patch_realtek.c
View file @
8f88f025
...
...
@@ -6521,20 +6521,8 @@ MODULE_ALIAS("snd-hda-codec-id:10ec*");
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Realtek HD-audio codec"
);
static
struct
hda_codec_
preset_list
realtek_list
=
{
static
struct
hda_codec_
driver
realtek_driver
=
{
.
preset
=
snd_hda_preset_realtek
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_realtek_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
realtek_list
);
}
static
void
__exit
patch_realtek_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
realtek_list
);
}
module_init
(
patch_realtek_init
)
module_exit
(
patch_realtek_exit
)
module_hda_codec_driver
(
realtek_driver
);
sound/pci/hda/patch_si3054.c
View file @
8f88f025
...
...
@@ -319,20 +319,8 @@ MODULE_ALIAS("snd-hda-codec-id:18540018");
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Si3054 HD-audio modem codec"
);
static
struct
hda_codec_
preset_list
si3054_list
=
{
static
struct
hda_codec_
driver
si3054_driver
=
{
.
preset
=
snd_hda_preset_si3054
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_si3054_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
si3054_list
);
}
static
void
__exit
patch_si3054_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
si3054_list
);
}
module_init
(
patch_si3054_init
)
module_exit
(
patch_si3054_exit
)
module_hda_codec_driver
(
si3054_driver
);
sound/pci/hda/patch_sigmatel.c
View file @
8f88f025
...
...
@@ -2132,8 +2132,10 @@ static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec,
if
(
action
==
HDA_FIXUP_ACT_PRE_PROBE
)
{
spec
->
mic_mute_led_gpio
=
0x08
;
/* GPIO3 */
#ifdef CONFIG_PM
/* resetting controller clears GPIO, so we need to keep on */
codec
->
bus
->
power_keep_link_on
=
1
;
codec
->
d3_stop_clk
=
0
;
#endif
}
}
...
...
@@ -5091,20 +5093,8 @@ MODULE_ALIAS("snd-hda-codec-id:111d*");
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"IDT/Sigmatel HD-audio codec"
);
static
struct
hda_codec_
preset_list
sigmatel_list
=
{
static
struct
hda_codec_
driver
sigmatel_driver
=
{
.
preset
=
snd_hda_preset_sigmatel
,
.
owner
=
THIS_MODULE
,
};
static
int
__init
patch_sigmatel_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
sigmatel_list
);
}
static
void
__exit
patch_sigmatel_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
sigmatel_list
);
}
module_init
(
patch_sigmatel_init
)
module_exit
(
patch_sigmatel_exit
)
module_hda_codec_driver
(
sigmatel_driver
);
sound/pci/hda/patch_via.c
View file @
8f88f025
...
...
@@ -1884,23 +1884,11 @@ static const struct hda_codec_preset snd_hda_preset_via[] = {
MODULE_ALIAS
(
"snd-hda-codec-id:1106*"
);
static
struct
hda_codec_
preset_list
via_list
=
{
static
struct
hda_codec_
driver
via_driver
=
{
.
preset
=
snd_hda_preset_via
,
.
owner
=
THIS_MODULE
,
};
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"VIA HD-audio codec"
);
static
int
__init
patch_via_init
(
void
)
{
return
snd_hda_add_codec_preset
(
&
via_list
);
}
static
void
__exit
patch_via_exit
(
void
)
{
snd_hda_delete_codec_preset
(
&
via_list
);
}
module_init
(
patch_via_init
)
module_exit
(
patch_via_exit
)
module_hda_codec_driver
(
via_driver
);
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