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
42dc2378
Commit
42dc2378
authored
Oct 27, 2008
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/hda-next' into topic/hda
parents
da74ae3e
74aeaabc
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
970 additions
and
412 deletions
+970
-412
include/linux/input.h
include/linux/input.h
+1
-0
include/sound/jack.h
include/sound/jack.h
+1
-0
sound/core/jack.c
sound/core/jack.c
+8
-1
sound/pci/Kconfig
sound/pci/Kconfig
+1
-0
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.c
+333
-95
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_codec.h
+41
-5
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.c
+12
-8
sound/pci/hda/hda_hwdep.c
sound/pci/hda/hda_hwdep.c
+228
-0
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.c
+35
-86
sound/pci/hda/hda_local.h
sound/pci/hda/hda_local.h
+10
-0
sound/pci/hda/hda_proc.c
sound/pci/hda/hda_proc.c
+5
-39
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_analog.c
+27
-29
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_conexant.c
+0
-11
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_realtek.c
+40
-46
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_sigmatel.c
+198
-51
sound/pci/hda/patch_via.c
sound/pci/hda/patch_via.c
+30
-41
No files found.
include/linux/input.h
View file @
42dc2378
...
...
@@ -644,6 +644,7 @@ struct input_absinfo {
#define SW_RADIO SW_RFKILL_ALL
/* deprecated */
#define SW_MICROPHONE_INSERT 0x04
/* set = inserted */
#define SW_DOCK 0x05
/* set = plugged into dock */
#define SW_LINEOUT_INSERT 0x06
/* set = inserted */
#define SW_MAX 0x0f
#define SW_CNT (SW_MAX+1)
...
...
include/sound/jack.h
View file @
42dc2378
...
...
@@ -35,6 +35,7 @@ enum snd_jack_types {
SND_JACK_HEADPHONE
=
0x0001
,
SND_JACK_MICROPHONE
=
0x0002
,
SND_JACK_HEADSET
=
SND_JACK_HEADPHONE
|
SND_JACK_MICROPHONE
,
SND_JACK_LINEOUT
=
0x0004
,
};
struct
snd_jack
{
...
...
sound/core/jack.c
View file @
42dc2378
...
...
@@ -34,6 +34,7 @@ static int snd_jack_dev_free(struct snd_device *device)
else
input_free_device
(
jack
->
input_dev
);
kfree
(
jack
->
id
);
kfree
(
jack
);
return
0
;
...
...
@@ -87,7 +88,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
if
(
jack
==
NULL
)
return
-
ENOMEM
;
jack
->
id
=
id
;
jack
->
id
=
kstrdup
(
id
,
GFP_KERNEL
)
;
jack
->
input_dev
=
input_allocate_device
();
if
(
jack
->
input_dev
==
NULL
)
{
...
...
@@ -102,6 +103,9 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
if
(
type
&
SND_JACK_HEADPHONE
)
input_set_capability
(
jack
->
input_dev
,
EV_SW
,
SW_HEADPHONE_INSERT
);
if
(
type
&
SND_JACK_LINEOUT
)
input_set_capability
(
jack
->
input_dev
,
EV_SW
,
SW_LINEOUT_INSERT
);
if
(
type
&
SND_JACK_MICROPHONE
)
input_set_capability
(
jack
->
input_dev
,
EV_SW
,
SW_MICROPHONE_INSERT
);
...
...
@@ -150,6 +154,9 @@ void snd_jack_report(struct snd_jack *jack, int status)
if
(
jack
->
type
&
SND_JACK_HEADPHONE
)
input_report_switch
(
jack
->
input_dev
,
SW_HEADPHONE_INSERT
,
status
&
SND_JACK_HEADPHONE
);
if
(
jack
->
type
&
SND_JACK_LINEOUT
)
input_report_switch
(
jack
->
input_dev
,
SW_LINEOUT_INSERT
,
status
&
SND_JACK_LINEOUT
);
if
(
jack
->
type
&
SND_JACK_MICROPHONE
)
input_report_switch
(
jack
->
input_dev
,
SW_MICROPHONE_INSERT
,
status
&
SND_JACK_MICROPHONE
);
...
...
sound/pci/Kconfig
View file @
42dc2378
...
...
@@ -501,6 +501,7 @@ config SND_HDA_INTEL
tristate "Intel HD Audio"
select SND_PCM
select SND_VMASTER
select SND_JACK if INPUT=y || INPUT=SND
help
Say Y here to include support for Intel "High Definition
Audio" (Azalia) motherboard devices.
...
...
sound/pci/hda/hda_codec.c
View file @
42dc2378
This diff is collapsed.
Click to expand it.
sound/pci/hda/hda_codec.h
View file @
42dc2378
...
...
@@ -519,6 +519,26 @@ enum {
/* max. codec address */
#define HDA_MAX_CODEC_ADDRESS 0x0f
/*
* generic arrays
*/
struct
snd_array
{
unsigned
int
used
;
unsigned
int
alloced
;
unsigned
int
elem_size
;
unsigned
int
alloc_align
;
void
*
list
;
};
void
*
snd_array_new
(
struct
snd_array
*
array
);
void
snd_array_free
(
struct
snd_array
*
array
);
static
inline
void
snd_array_init
(
struct
snd_array
*
array
,
unsigned
int
size
,
unsigned
int
align
)
{
array
->
elem_size
=
size
;
array
->
alloc_align
=
align
;
}
/*
* Structures
*/
...
...
@@ -542,6 +562,8 @@ struct hda_bus_ops {
unsigned
int
(
*
get_response
)(
struct
hda_codec
*
codec
);
/* free the private data */
void
(
*
private_free
)(
struct
hda_bus
*
);
/* attach a PCM stream */
int
(
*
attach_pcm
)(
struct
hda_codec
*
codec
,
struct
hda_pcm
*
pcm
);
#ifdef CONFIG_SND_HDA_POWER_SAVE
/* notify power-up/down from codec to controller */
void
(
*
pm_notify
)(
struct
hda_codec
*
codec
);
...
...
@@ -635,10 +657,7 @@ struct hda_amp_info {
struct
hda_cache_rec
{
u16
hash
[
64
];
/* hash table for index */
unsigned
int
num_entries
;
/* number of assigned entries */
unsigned
int
size
;
/* allocated size */
unsigned
int
record_size
;
/* record size (including header) */
void
*
buffer
;
/* hash table entries */
struct
snd_array
buf
;
/* record entries */
};
/* PCM callbacks */
...
...
@@ -680,7 +699,8 @@ struct hda_pcm {
char
*
name
;
struct
hda_pcm_stream
stream
[
2
];
unsigned
int
pcm_type
;
/* HDA_PCM_TYPE_XXX */
int
device
;
/* assigned device number */
int
device
;
/* device number to assign */
struct
snd_pcm
*
pcm
;
/* assigned PCM instance */
};
/* codec information */
...
...
@@ -699,6 +719,8 @@ struct hda_codec {
/* detected preset */
const
struct
hda_codec_preset
*
preset
;
const
char
*
name
;
/* codec name */
const
char
*
modelname
;
/* model name for preset */
/* set by patch */
struct
hda_codec_ops
patch_ops
;
...
...
@@ -718,6 +740,8 @@ struct hda_codec {
hda_nid_t
start_nid
;
u32
*
wcaps
;
struct
snd_array
mixers
;
/* list of assigned mixer elements */
struct
hda_cache_rec
amp_cache
;
/* cache for amp access */
struct
hda_cache_rec
cmd_cache
;
/* cache for other commands */
...
...
@@ -727,7 +751,11 @@ struct hda_codec {
unsigned
int
spdif_in_enable
;
/* SPDIF input enable? */
hda_nid_t
*
slave_dig_outs
;
/* optional digital out slave widgets */
#ifdef CONFIG_SND_HDA_HWDEP
struct
snd_hwdep
*
hwdep
;
/* assigned hwdep device */
struct
snd_array
init_verbs
;
/* additional init verbs */
struct
snd_array
hints
;
/* additional hints */
#endif
/* misc flags */
unsigned
int
spdif_status_reset
:
1
;
/* needs to toggle SPDIF for each
...
...
@@ -799,6 +827,7 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec);
* Mixer
*/
int
snd_hda_build_controls
(
struct
hda_bus
*
bus
);
int
snd_hda_codec_build_controls
(
struct
hda_codec
*
codec
);
/*
* PCM
...
...
@@ -830,6 +859,13 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state);
int
snd_hda_resume
(
struct
hda_bus
*
bus
);
#endif
/*
* get widget information
*/
const
char
*
snd_hda_get_jack_connectivity
(
u32
cfg
);
const
char
*
snd_hda_get_jack_type
(
u32
cfg
);
const
char
*
snd_hda_get_jack_location
(
u32
cfg
);
/*
* power saving
*/
...
...
sound/pci/hda/hda_generic.c
View file @
42dc2378
...
...
@@ -723,7 +723,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
if
(
is_loopback
)
add_input_loopback
(
codec
,
node
->
nid
,
HDA_INPUT
,
index
);
snd_printdd
(
"[%s] NID=0x%x, DIR=IN, IDX=0x%x
\n
"
,
name
,
node
->
nid
,
index
);
if
((
err
=
snd_ctl_add
(
codec
->
bus
->
card
,
snd_ctl_new1
(
&
knew
,
codec
)))
<
0
)
err
=
snd_hda_ctl_add
(
codec
,
snd_ctl_new1
(
&
knew
,
codec
));
if
(
err
<
0
)
return
err
;
created
=
1
;
}
else
if
((
node
->
wid_caps
&
AC_WCAP_OUT_AMP
)
&&
...
...
@@ -732,7 +733,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
if
(
is_loopback
)
add_input_loopback
(
codec
,
node
->
nid
,
HDA_OUTPUT
,
0
);
snd_printdd
(
"[%s] NID=0x%x, DIR=OUT
\n
"
,
name
,
node
->
nid
);
if
((
err
=
snd_ctl_add
(
codec
->
bus
->
card
,
snd_ctl_new1
(
&
knew
,
codec
)))
<
0
)
err
=
snd_hda_ctl_add
(
codec
,
snd_ctl_new1
(
&
knew
,
codec
));
if
(
err
<
0
)
return
err
;
created
=
1
;
}
...
...
@@ -745,14 +747,16 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
(
node
->
amp_in_caps
&
AC_AMPCAP_NUM_STEPS
))
{
knew
=
(
struct
snd_kcontrol_new
)
HDA_CODEC_VOLUME
(
name
,
node
->
nid
,
index
,
HDA_INPUT
);
snd_printdd
(
"[%s] NID=0x%x, DIR=IN, IDX=0x%x
\n
"
,
name
,
node
->
nid
,
index
);
if
((
err
=
snd_ctl_add
(
codec
->
bus
->
card
,
snd_ctl_new1
(
&
knew
,
codec
)))
<
0
)
err
=
snd_hda_ctl_add
(
codec
,
snd_ctl_new1
(
&
knew
,
codec
));
if
(
err
<
0
)
return
err
;
created
=
1
;
}
else
if
((
node
->
wid_caps
&
AC_WCAP_OUT_AMP
)
&&
(
node
->
amp_out_caps
&
AC_AMPCAP_NUM_STEPS
))
{
knew
=
(
struct
snd_kcontrol_new
)
HDA_CODEC_VOLUME
(
name
,
node
->
nid
,
0
,
HDA_OUTPUT
);
snd_printdd
(
"[%s] NID=0x%x, DIR=OUT
\n
"
,
name
,
node
->
nid
);
if
((
err
=
snd_ctl_add
(
codec
->
bus
->
card
,
snd_ctl_new1
(
&
knew
,
codec
)))
<
0
)
err
=
snd_hda_ctl_add
(
codec
,
snd_ctl_new1
(
&
knew
,
codec
));
if
(
err
<
0
)
return
err
;
created
=
1
;
}
...
...
@@ -849,8 +853,8 @@ static int build_input_controls(struct hda_codec *codec)
}
/* create input MUX if multiple sources are available */
if
((
err
=
snd_ctl_add
(
codec
->
bus
->
card
,
snd_ctl_new1
(
&
cap_sel
,
codec
)))
<
0
)
err
=
snd_hda_ctl_add
(
codec
,
snd_ctl_new1
(
&
cap_sel
,
codec
));
if
(
err
<
0
)
return
err
;
/* no volume control? */
...
...
@@ -867,8 +871,8 @@ static int build_input_controls(struct hda_codec *codec)
HDA_CODEC_VOLUME
(
name
,
adc_node
->
nid
,
spec
->
input_mux
.
items
[
i
].
index
,
HDA_INPUT
);
if
((
err
=
snd_ctl_add
(
codec
->
bus
->
card
,
snd_ctl_new1
(
&
knew
,
codec
)))
<
0
)
err
=
snd_hda_ctl_add
(
codec
,
snd_ctl_new1
(
&
knew
,
codec
));
if
(
err
<
0
)
return
err
;
}
...
...
sound/pci/hda/hda_hwdep.c
View file @
42dc2378
...
...
@@ -23,10 +23,12 @@
#include <linux/pci.h>
#include <linux/compat.h>
#include <linux/mutex.h>
#include <linux/ctype.h>
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_local.h"
#include <sound/hda_hwdep.h>
#include <sound/minors.h>
/*
* write/read an out-of-bound verb
...
...
@@ -95,6 +97,25 @@ static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
return
0
;
}
static
void
clear_hwdep_elements
(
struct
hda_codec
*
codec
)
{
char
**
head
;
int
i
;
/* clear init verbs */
snd_array_free
(
&
codec
->
init_verbs
);
/* clear hints */
head
=
codec
->
hints
.
list
;
for
(
i
=
0
;
i
<
codec
->
hints
.
used
;
i
++
,
head
++
)
kfree
(
*
head
);
snd_array_free
(
&
codec
->
hints
);
}
static
void
hwdep_free
(
struct
snd_hwdep
*
hwdep
)
{
clear_hwdep_elements
(
hwdep
->
private_data
);
}
int
__devinit
snd_hda_create_hwdep
(
struct
hda_codec
*
codec
)
{
char
hwname
[
16
];
...
...
@@ -109,6 +130,7 @@ int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
sprintf
(
hwdep
->
name
,
"HDA Codec %d"
,
codec
->
addr
);
hwdep
->
iface
=
SNDRV_HWDEP_IFACE_HDA
;
hwdep
->
private_data
=
codec
;
hwdep
->
private_free
=
hwdep_free
;
hwdep
->
exclusive
=
1
;
hwdep
->
ops
.
open
=
hda_hwdep_open
;
...
...
@@ -117,5 +139,211 @@ int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
hwdep
->
ops
.
ioctl_compat
=
hda_hwdep_ioctl_compat
;
#endif
snd_array_init
(
&
codec
->
init_verbs
,
sizeof
(
struct
hda_verb
),
32
);
snd_array_init
(
&
codec
->
hints
,
sizeof
(
char
*
),
32
);
return
0
;
}
/*
* sysfs interface
*/
static
int
clear_codec
(
struct
hda_codec
*
codec
)
{
snd_hda_codec_reset
(
codec
);
clear_hwdep_elements
(
codec
);
return
0
;
}
static
int
reconfig_codec
(
struct
hda_codec
*
codec
)
{
int
err
;
snd_printk
(
KERN_INFO
"hda-codec: reconfiguring
\n
"
);
snd_hda_codec_reset
(
codec
);
err
=
snd_hda_codec_configure
(
codec
);
if
(
err
<
0
)
return
err
;
/* rebuild PCMs */
err
=
snd_hda_build_pcms
(
codec
->
bus
);
if
(
err
<
0
)
return
err
;
/* rebuild mixers */
err
=
snd_hda_codec_build_controls
(
codec
);
if
(
err
<
0
)
return
err
;
return
0
;
}
/*
* allocate a string at most len chars, and remove the trailing EOL
*/
static
char
*
kstrndup_noeol
(
const
char
*
src
,
size_t
len
)
{
char
*
s
=
kstrndup
(
src
,
len
,
GFP_KERNEL
);
char
*
p
;
if
(
!
s
)
return
NULL
;
p
=
strchr
(
s
,
'\n'
);
if
(
p
)
*
p
=
0
;
return
s
;
}
#define CODEC_INFO_SHOW(type) \
static ssize_t type##_show(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
struct hda_codec *codec = hwdep->private_data; \
return sprintf(buf, "0x%x\n", codec->type); \
}
#define CODEC_INFO_STR_SHOW(type) \
static ssize_t type##_show(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
struct hda_codec *codec = hwdep->private_data; \
return sprintf(buf, "%s\n", \
codec->type ? codec->type : ""); \
}
CODEC_INFO_SHOW
(
vendor_id
);
CODEC_INFO_SHOW
(
subsystem_id
);
CODEC_INFO_SHOW
(
revision_id
);
CODEC_INFO_SHOW
(
afg
);
CODEC_INFO_SHOW
(
mfg
);
CODEC_INFO_STR_SHOW
(
name
);
CODEC_INFO_STR_SHOW
(
modelname
);
#define CODEC_INFO_STORE(type) \
static ssize_t type##_store(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
struct hda_codec *codec = hwdep->private_data; \
char *after; \
codec->type = simple_strtoul(buf, &after, 0); \
return count; \
}
#define CODEC_INFO_STR_STORE(type) \
static ssize_t type##_store(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
struct hda_codec *codec = hwdep->private_data; \
char *s = kstrndup_noeol(buf, 64); \
if (!s) \
return -ENOMEM; \
kfree(codec->type); \
codec->type = s; \
return count; \
}
CODEC_INFO_STORE
(
vendor_id
);
CODEC_INFO_STORE
(
subsystem_id
);
CODEC_INFO_STORE
(
revision_id
);
CODEC_INFO_STR_STORE
(
name
);
CODEC_INFO_STR_STORE
(
modelname
);
#define CODEC_ACTION_STORE(type) \
static ssize_t type##_store(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
struct hda_codec *codec = hwdep->private_data; \
int err = 0; \
if (*buf) \
err = type##_codec(codec); \
return err < 0 ? err : count; \
}
CODEC_ACTION_STORE
(
reconfig
);
CODEC_ACTION_STORE
(
clear
);
static
ssize_t
init_verbs_store
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
snd_hwdep
*
hwdep
=
dev_get_drvdata
(
dev
);
struct
hda_codec
*
codec
=
hwdep
->
private_data
;
char
*
p
;
struct
hda_verb
verb
,
*
v
;
verb
.
nid
=
simple_strtoul
(
buf
,
&
p
,
0
);
verb
.
verb
=
simple_strtoul
(
p
,
&
p
,
0
);
verb
.
param
=
simple_strtoul
(
p
,
&
p
,
0
);
if
(
!
verb
.
nid
||
!
verb
.
verb
||
!
verb
.
param
)
return
-
EINVAL
;
v
=
snd_array_new
(
&
codec
->
init_verbs
);
if
(
!
v
)
return
-
ENOMEM
;
*
v
=
verb
;
return
count
;
}
static
ssize_t
hints_store
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
snd_hwdep
*
hwdep
=
dev_get_drvdata
(
dev
);
struct
hda_codec
*
codec
=
hwdep
->
private_data
;
char
*
p
;
char
**
hint
;
if
(
!*
buf
||
isspace
(
*
buf
)
||
*
buf
==
'#'
||
*
buf
==
'\n'
)
return
count
;
p
=
kstrndup_noeol
(
buf
,
1024
);
if
(
!
p
)
return
-
ENOMEM
;
hint
=
snd_array_new
(
&
codec
->
hints
);
if
(
!
hint
)
{
kfree
(
p
);
return
-
ENOMEM
;
}
*
hint
=
p
;
return
count
;
}
#define CODEC_ATTR_RW(type) \
__ATTR(type, 0644, type##_show, type##_store)
#define CODEC_ATTR_RO(type) \
__ATTR_RO(type)
#define CODEC_ATTR_WO(type) \
__ATTR(type, 0200, NULL, type##_store)
static
struct
device_attribute
codec_attrs
[]
=
{
CODEC_ATTR_RW
(
vendor_id
),
CODEC_ATTR_RW
(
subsystem_id
),
CODEC_ATTR_RW
(
revision_id
),
CODEC_ATTR_RO
(
afg
),
CODEC_ATTR_RO
(
mfg
),
CODEC_ATTR_RW
(
name
),
CODEC_ATTR_RW
(
modelname
),
CODEC_ATTR_WO
(
init_verbs
),
CODEC_ATTR_WO
(
hints
),
CODEC_ATTR_WO
(
reconfig
),
CODEC_ATTR_WO
(
clear
),
};
/*
* create sysfs files on hwdep directory
*/
int
snd_hda_hwdep_add_sysfs
(
struct
hda_codec
*
codec
)
{
struct
snd_hwdep
*
hwdep
=
codec
->
hwdep
;
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
codec_attrs
);
i
++
)
snd_add_device_sysfs_file
(
SNDRV_DEVICE_TYPE_HWDEP
,
hwdep
->
card
,
hwdep
->
device
,
&
codec_attrs
[
i
]);
return
0
;
}
sound/pci/hda/hda_intel.c
View file @
42dc2378
...
...
@@ -1180,6 +1180,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
return
0
;
}
static
int
azx_attach_pcm_stream
(
struct
hda_codec
*
codec
,
struct
hda_pcm
*
cpcm
);
/*
* Codec initialization
...
...
@@ -1212,6 +1213,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
bus_temp
.
pci
=
chip
->
pci
;
bus_temp
.
ops
.
command
=
azx_send_cmd
;
bus_temp
.
ops
.
get_response
=
azx_get_response
;
bus_temp
.
ops
.
attach_pcm
=
azx_attach_pcm_stream
;
#ifdef CONFIG_SND_HDA_POWER_SAVE
bus_temp
.
ops
.
pm_notify
=
azx_power_notify
;
#endif
...
...
@@ -1718,111 +1720,58 @@ static struct snd_pcm_ops azx_pcm_ops = {
static
void
azx_pcm_free
(
struct
snd_pcm
*
pcm
)
{
kfree
(
pcm
->
private_data
);
struct
azx_pcm
*
apcm
=
pcm
->
private_data
;
if
(
apcm
)
{
apcm
->
chip
->
pcm
[
pcm
->
device
]
=
NULL
;
kfree
(
apcm
);
}
}
static
int
__devinit
create_codec_pcm
(
struct
azx
*
chip
,
struct
hda_codec
*
codec
,
struct
hda_pcm
*
cpcm
)
static
int
azx_attach_pcm_stream
(
struct
hda_codec
*
codec
,
struct
hda_pcm
*
cpcm
)
{
int
err
;
struct
azx
*
chip
=
codec
->
bus
->
private_data
;
struct
snd_pcm
*
pcm
;
struct
azx_pcm
*
apcm
;
int
pcm_dev
=
cpcm
->
device
;
int
s
,
err
;
/* if no substreams are defined for both playback and capture,
* it's just a placeholder. ignore it.
*/
if
(
!
cpcm
->
stream
[
0
].
substreams
&&
!
cpcm
->
stream
[
1
].
substreams
)
return
0
;
if
(
snd_BUG_ON
(
!
cpcm
->
name
))
if
(
pcm_dev
>=
AZX_MAX_PCMS
)
{
snd_printk
(
KERN_ERR
SFX
"Invalid PCM device number %d
\n
"
,
pcm_dev
);
return
-
EINVAL
;
err
=
snd_pcm_new
(
chip
->
card
,
cpcm
->
name
,
cpcm
->
device
,
cpcm
->
stream
[
0
].
substreams
,
cpcm
->
stream
[
1
].
substreams
,
}
if
(
chip
->
pcm
[
pcm_dev
])
{
snd_printk
(
KERN_ERR
SFX
"PCM %d already exists
\n
"
,
pcm_dev
);
return
-
EBUSY
;
}
err
=
snd_pcm_new
(
chip
->
card
,
cpcm
->
name
,
pcm_dev
,
cpcm
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
substreams
,
cpcm
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
substreams
,
&
pcm
);
if
(
err
<
0
)
return
err
;
strcpy
(
pcm
->
name
,
cpcm
->
name
);
apcm
=
k
m
alloc
(
sizeof
(
*
apcm
),
GFP_KERNEL
);
apcm
=
k
z
alloc
(
sizeof
(
*
apcm
),
GFP_KERNEL
);
if
(
apcm
==
NULL
)
return
-
ENOMEM
;
apcm
->
chip
=
chip
;
apcm
->
codec
=
codec
;
apcm
->
hinfo
[
0
]
=
&
cpcm
->
stream
[
0
];
apcm
->
hinfo
[
1
]
=
&
cpcm
->
stream
[
1
];
pcm
->
private_data
=
apcm
;
pcm
->
private_free
=
azx_pcm_free
;
if
(
cpcm
->
stream
[
0
].
substreams
)
snd_pcm_set_ops
(
pcm
,
SNDRV_PCM_STREAM_PLAYBACK
,
&
azx_pcm_ops
);
if
(
cpcm
->
stream
[
1
].
substreams
)
snd_pcm_set_ops
(
pcm
,
SNDRV_PCM_STREAM_CAPTURE
,
&
azx_pcm_ops
);
if
(
cpcm
->
pcm_type
==
HDA_PCM_TYPE_MODEM
)
pcm
->
dev_class
=
SNDRV_PCM_CLASS_MODEM
;
chip
->
pcm
[
pcm_dev
]
=
pcm
;
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
);
}
/* buffer pre-allocation */
snd_pcm_lib_preallocate_pages_for_all
(
pcm
,
SNDRV_DMA_TYPE_DEV_SG
,
snd_dma_pci_data
(
chip
->
pci
),
1024
*
64
,
32
*
1024
*
1024
);
chip
->
pcm
[
cpcm
->
device
]
=
pcm
;
return
0
;
}
static
int
__devinit
azx_pcm_create
(
struct
azx
*
chip
)
{
static
const
char
*
dev_name
[
HDA_PCM_NTYPES
]
=
{
"Audio"
,
"SPDIF"
,
"HDMI"
,
"Modem"
};
/* starting device index for each PCM type */
static
int
dev_idx
[
HDA_PCM_NTYPES
]
=
{
[
HDA_PCM_TYPE_AUDIO
]
=
0
,
[
HDA_PCM_TYPE_SPDIF
]
=
1
,
[
HDA_PCM_TYPE_HDMI
]
=
3
,
[
HDA_PCM_TYPE_MODEM
]
=
6
};
/* normal audio device indices; not linear to keep compatibility */
static
int
audio_idx
[
4
]
=
{
0
,
2
,
4
,
5
};
struct
hda_codec
*
codec
;
int
c
,
err
;
int
num_devs
[
HDA_PCM_NTYPES
];
err
=
snd_hda_build_pcms
(
chip
->
bus
);
if
(
err
<
0
)
return
err
;
/* create audio PCMs */
memset
(
num_devs
,
0
,
sizeof
(
num_devs
));
list_for_each_entry
(
codec
,
&
chip
->
bus
->
codec_list
,
list
)
{
for
(
c
=
0
;
c
<
codec
->
num_pcms
;
c
++
)
{
struct
hda_pcm
*
cpcm
=
&
codec
->
pcm_info
[
c
];
int
type
=
cpcm
->
pcm_type
;
switch
(
type
)
{
case
HDA_PCM_TYPE_AUDIO
:
if
(
num_devs
[
type
]
>=
ARRAY_SIZE
(
audio_idx
))
{
snd_printk
(
KERN_WARNING
"Too many audio devices
\n
"
);
continue
;
}
cpcm
->
device
=
audio_idx
[
num_devs
[
type
]];
break
;
case
HDA_PCM_TYPE_SPDIF
:
case
HDA_PCM_TYPE_HDMI
:
case
HDA_PCM_TYPE_MODEM
:
if
(
num_devs
[
type
])
{
snd_printk
(
KERN_WARNING
"%s already defined
\n
"
,
dev_name
[
type
]);
continue
;
}
cpcm
->
device
=
dev_idx
[
type
];
break
;
default:
snd_printk
(
KERN_WARNING
"Invalid PCM type %d
\n
"
,
type
);
continue
;
}
num_devs
[
type
]
++
;
err
=
create_codec_pcm
(
chip
,
codec
,
cpcm
);
if
(
err
<
0
)
return
err
;
}
}
return
0
;
}
...
...
@@ -2324,7 +2273,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
}
/* create PCM streams */
err
=
azx_pcm_create
(
chip
);
err
=
snd_hda_build_pcms
(
chip
->
bus
);
if
(
err
<
0
)
{
snd_card_free
(
card
);
return
err
;
...
...
sound/pci/hda/hda_local.h
View file @
42dc2378
...
...
@@ -96,6 +96,8 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
const
char
*
name
);
int
snd_hda_add_vmaster
(
struct
hda_codec
*
codec
,
char
*
name
,
unsigned
int
*
tlv
,
const
char
**
slaves
);
void
snd_hda_codec_reset
(
struct
hda_codec
*
codec
);
int
snd_hda_codec_configure
(
struct
hda_codec
*
codec
);
/* amp value bits */
#define HDA_AMP_MUTE 0x80
...
...
@@ -393,10 +395,18 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
int
snd_hda_override_amp_caps
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
int
dir
,
unsigned
int
caps
);
int
snd_hda_ctl_add
(
struct
hda_codec
*
codec
,
struct
snd_kcontrol
*
kctl
);
void
snd_hda_ctls_clear
(
struct
hda_codec
*
codec
);
/*
* hwdep interface
*/
#ifdef CONFIG_SND_HDA_HWDEP
int
snd_hda_create_hwdep
(
struct
hda_codec
*
codec
);
int
snd_hda_hwdep_add_sysfs
(
struct
hda_codec
*
codec
);
#else
static
inline
int
snd_hda_create_hwdep
(
struct
hda_codec
*
codec
)
{
return
0
;
}
#endif
/*
* power-management
...
...
sound/pci/hda/hda_proc.c
View file @
42dc2378
...
...
@@ -145,32 +145,6 @@ static void print_pcm_caps(struct snd_info_buffer *buffer,
print_pcm_formats
(
buffer
,
stream
);
}
static
const
char
*
get_jack_location
(
u32
cfg
)
{
static
char
*
bases
[
7
]
=
{
"N/A"
,
"Rear"
,
"Front"
,
"Left"
,
"Right"
,
"Top"
,
"Bottom"
,
};
static
unsigned
char
specials_idx
[]
=
{
0x07
,
0x08
,
0x17
,
0x18
,
0x19
,
0x37
,
0x38
};
static
char
*
specials
[]
=
{
"Rear Panel"
,
"Drive Bar"
,
"Riser"
,
"HDMI"
,
"ATAPI"
,
"Mobile-In"
,
"Mobile-Out"
};
int
i
;
cfg
=
(
cfg
&
AC_DEFCFG_LOCATION
)
>>
AC_DEFCFG_LOCATION_SHIFT
;
if
((
cfg
&
0x0f
)
<
7
)
return
bases
[
cfg
&
0x0f
];
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
specials_idx
);
i
++
)
{
if
(
cfg
==
specials_idx
[
i
])
return
specials
[
i
];
}
return
"UNKNOWN"
;
}
static
const
char
*
get_jack_connection
(
u32
cfg
)
{
static
char
*
names
[
16
]
=
{
...
...
@@ -206,13 +180,6 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
int
*
supports_vref
)
{
static
char
*
jack_conns
[
4
]
=
{
"Jack"
,
"N/A"
,
"Fixed"
,
"Both"
};
static
char
*
jack_types
[
16
]
=
{
"Line Out"
,
"Speaker"
,
"HP Out"
,
"CD"
,
"SPDIF Out"
,
"Digital Out"
,
"Modem Line"
,
"Modem Hand"
,
"Line In"
,
"Aux"
,
"Mic"
,
"Telephony"
,
"SPDIF In"
,
"Digitial In"
,
"Reserved"
,
"Other"
};
static
char
*
jack_locations
[
4
]
=
{
"Ext"
,
"Int"
,
"Sep"
,
"Oth"
};
unsigned
int
caps
,
val
;
caps
=
snd_hda_param_read
(
codec
,
nid
,
AC_PAR_PIN_CAP
);
...
...
@@ -274,9 +241,9 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
caps
=
snd_hda_codec_read
(
codec
,
nid
,
0
,
AC_VERB_GET_CONFIG_DEFAULT
,
0
);
snd_iprintf
(
buffer
,
" Pin Default 0x%08x: [%s] %s at %s %s
\n
"
,
caps
,
jack_conns
[(
caps
&
AC_DEFCFG_PORT_CONN
)
>>
AC_DEFCFG_PORT_CONN_SHIFT
],
jack_types
[(
caps
&
AC_DEFCFG_DEVICE
)
>>
AC_DEFCFG_DEVICE_SHIFT
]
,
jack_locations
[(
caps
>>
(
AC_DEFCFG_LOCATION_SHIFT
+
4
))
&
3
]
,
get_jack_location
(
caps
));
snd_hda_get_jack_type
(
caps
)
,
snd_hda_get_jack_connectivity
(
caps
)
,
snd_hda_
get_jack_location
(
caps
));
snd_iprintf
(
buffer
,
" Conn = %s, Color = %s
\n
"
,
get_jack_connection
(
caps
),
get_jack_color
(
caps
));
...
...
@@ -511,12 +478,11 @@ static void print_codec_info(struct snd_info_entry *entry,
struct
snd_info_buffer
*
buffer
)
{
struct
hda_codec
*
codec
=
entry
->
private_data
;
char
buf
[
32
];
hda_nid_t
nid
;
int
i
,
nodes
;
snd_
hda_get_codec_name
(
codec
,
buf
,
sizeof
(
buf
));
snd_iprintf
(
buffer
,
"Codec: %s
\n
"
,
buf
);
snd_
iprintf
(
buffer
,
"Codec: %s
\n
"
,
codec
->
name
?
codec
->
name
:
"Not Set"
);
snd_iprintf
(
buffer
,
"Address: %d
\n
"
,
codec
->
addr
);
snd_iprintf
(
buffer
,
"Vendor Id: 0x%x
\n
"
,
codec
->
vendor_id
);
snd_iprintf
(
buffer
,
"Subsystem Id: 0x%x
\n
"
,
codec
->
subsystem_id
);
...
...
sound/pci/hda/patch_analog.c
View file @
42dc2378
...
...
@@ -67,8 +67,7 @@ struct ad198x_spec {
/* dynamic controls, init_verbs and input_mux */
struct
auto_pin_cfg
autocfg
;
unsigned
int
num_kctl_alloc
,
num_kctl_used
;
struct
snd_kcontrol_new
*
kctl_alloc
;
struct
snd_array
kctls
;
struct
hda_input_mux
private_imux
;
hda_nid_t
private_dac_nids
[
AUTO_CFG_MAX_OUTS
];
...
...
@@ -154,6 +153,8 @@ static const char *ad_slave_sws[] = {
NULL
};
static
void
ad198x_free_kctls
(
struct
hda_codec
*
codec
);
static
int
ad198x_build_controls
(
struct
hda_codec
*
codec
)
{
struct
ad198x_spec
*
spec
=
codec
->
spec
;
...
...
@@ -202,6 +203,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
return
err
;
}
ad198x_free_kctls
(
codec
);
/* no longer needed */
return
0
;
}
...
...
@@ -375,16 +377,27 @@ static int ad198x_build_pcms(struct hda_codec *codec)
return
0
;
}
static
void
ad198x_free
(
struct
hda_codec
*
codec
)
static
void
ad198x_free
_kctls
(
struct
hda_codec
*
codec
)
{
struct
ad198x_spec
*
spec
=
codec
->
spec
;
unsigned
int
i
;
if
(
spec
->
kctl_alloc
)
{
for
(
i
=
0
;
i
<
spec
->
num_kctl_used
;
i
++
)
kfree
(
spec
->
kctl_alloc
[
i
].
name
);
kfree
(
spec
->
kctl_alloc
);
if
(
spec
->
kctls
.
list
)
{
struct
snd_kcontrol_new
*
kctl
=
spec
->
kctls
.
list
;
int
i
;
for
(
i
=
0
;
i
<
spec
->
kctls
.
used
;
i
++
)
kfree
(
kctl
[
i
].
name
);
}
snd_array_free
(
&
spec
->
kctls
);
}
static
void
ad198x_free
(
struct
hda_codec
*
codec
)
{
struct
ad198x_spec
*
spec
=
codec
->
spec
;
if
(
!
spec
)
return
;
ad198x_free_kctls
(
codec
);
kfree
(
codec
->
spec
);
}
...
...
@@ -2452,9 +2465,6 @@ static struct hda_amp_list ad1988_loopbacks[] = {
* Automatic parse of I/O pins from the BIOS configuration
*/
#define NUM_CONTROL_ALLOC 32
#define NUM_VERB_ALLOC 32
enum
{
AD_CTL_WIDGET_VOL
,
AD_CTL_WIDGET_MUTE
,
...
...
@@ -2472,27 +2482,15 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
{
struct
snd_kcontrol_new
*
knew
;
if
(
spec
->
num_kctl_used
>=
spec
->
num_kctl_alloc
)
{
int
num
=
spec
->
num_kctl_alloc
+
NUM_CONTROL_ALLOC
;
knew
=
kcalloc
(
num
+
1
,
sizeof
(
*
knew
),
GFP_KERNEL
);
/* array + terminator */
if
(
!
knew
)
return
-
ENOMEM
;
if
(
spec
->
kctl_alloc
)
{
memcpy
(
knew
,
spec
->
kctl_alloc
,
sizeof
(
*
knew
)
*
spec
->
num_kctl_alloc
);
kfree
(
spec
->
kctl_alloc
);
}
spec
->
kctl_alloc
=
knew
;
spec
->
num_kctl_alloc
=
num
;
}
knew
=
&
spec
->
kctl_alloc
[
spec
->
num_kctl_used
];
snd_array_init
(
&
spec
->
kctls
,
sizeof
(
*
knew
),
32
);
knew
=
snd_array_new
(
&
spec
->
kctls
);
if
(
!
knew
)
return
-
ENOMEM
;
*
knew
=
ad1988_control_templates
[
type
];
knew
->
name
=
kstrdup
(
name
,
GFP_KERNEL
);
if
(
!
knew
->
name
)
return
-
ENOMEM
;
knew
->
private_value
=
val
;
spec
->
num_kctl_used
++
;
return
0
;
}
...
...
@@ -2846,8 +2844,8 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_in_pin
)
spec
->
dig_in_nid
=
AD1988_SPDIF_IN
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
init_verbs
[
spec
->
num_init_verbs
++
]
=
ad1988_6stack_init_verbs
;
...
...
sound/pci/hda/patch_conexant.c
View file @
42dc2378
...
...
@@ -86,8 +86,6 @@ struct conexant_spec {
/* dynamic controls, init_verbs and input_mux */
struct
auto_pin_cfg
autocfg
;
unsigned
int
num_kctl_alloc
,
num_kctl_used
;
struct
snd_kcontrol_new
*
kctl_alloc
;
struct
hda_input_mux
private_imux
;
hda_nid_t
private_dac_nids
[
AUTO_CFG_MAX_OUTS
];
...
...
@@ -344,15 +342,6 @@ static int conexant_init(struct hda_codec *codec)
static
void
conexant_free
(
struct
hda_codec
*
codec
)
{
struct
conexant_spec
*
spec
=
codec
->
spec
;
unsigned
int
i
;
if
(
spec
->
kctl_alloc
)
{
for
(
i
=
0
;
i
<
spec
->
num_kctl_used
;
i
++
)
kfree
(
spec
->
kctl_alloc
[
i
].
name
);
kfree
(
spec
->
kctl_alloc
);
}
kfree
(
codec
->
spec
);
}
...
...
sound/pci/hda/patch_realtek.c
View file @
42dc2378
...
...
@@ -284,8 +284,7 @@ struct alc_spec {
/* dynamic controls, init_verbs and input_mux */
struct
auto_pin_cfg
autocfg
;
unsigned
int
num_kctl_alloc
,
num_kctl_used
;
struct
snd_kcontrol_new
*
kctl_alloc
;
struct
snd_array
kctls
;
struct
hda_input_mux
private_imux
;
hda_nid_t
private_dac_nids
[
AUTO_CFG_MAX_OUTS
];
...
...
@@ -1625,6 +1624,9 @@ static const char *alc_slave_sws[] = {
/*
* build control elements
*/
static
void
alc_free_kctls
(
struct
hda_codec
*
codec
);
static
int
alc_build_controls
(
struct
hda_codec
*
codec
)
{
struct
alc_spec
*
spec
=
codec
->
spec
;
...
...
@@ -1671,6 +1673,7 @@ static int alc_build_controls(struct hda_codec *codec)
return
err
;
}
alc_free_kctls
(
codec
);
/* no longer needed */
return
0
;
}
...
...
@@ -2761,19 +2764,27 @@ static int alc_build_pcms(struct hda_codec *codec)
return
0
;
}
static
void
alc_free_kctls
(
struct
hda_codec
*
codec
)
{
struct
alc_spec
*
spec
=
codec
->
spec
;
if
(
spec
->
kctls
.
list
)
{
struct
snd_kcontrol_new
*
kctl
=
spec
->
kctls
.
list
;
int
i
;
for
(
i
=
0
;
i
<
spec
->
kctls
.
used
;
i
++
)
kfree
(
kctl
[
i
].
name
);
}
snd_array_free
(
&
spec
->
kctls
);
}
static
void
alc_free
(
struct
hda_codec
*
codec
)
{
struct
alc_spec
*
spec
=
codec
->
spec
;
unsigned
int
i
;
if
(
!
spec
)
return
;
if
(
spec
->
kctl_alloc
)
{
for
(
i
=
0
;
i
<
spec
->
num_kctl_used
;
i
++
)
kfree
(
spec
->
kctl_alloc
[
i
].
name
);
kfree
(
spec
->
kctl_alloc
);
}
alc_free_kctls
(
codec
);
kfree
(
spec
);
codec
->
spec
=
NULL
;
/* to be sure */
}
...
...
@@ -3458,9 +3469,6 @@ static struct alc_config_preset alc880_presets[] = {
* Automatic parse of I/O pins from the BIOS configuration
*/
#define NUM_CONTROL_ALLOC 32
#define NUM_VERB_ALLOC 32
enum
{
ALC_CTL_WIDGET_VOL
,
ALC_CTL_WIDGET_MUTE
,
...
...
@@ -3478,29 +3486,15 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
{
struct
snd_kcontrol_new
*
knew
;
if
(
spec
->
num_kctl_used
>=
spec
->
num_kctl_alloc
)
{
int
num
=
spec
->
num_kctl_alloc
+
NUM_CONTROL_ALLOC
;
/* array + terminator */
knew
=
kcalloc
(
num
+
1
,
sizeof
(
*
knew
),
GFP_KERNEL
);
if
(
!
knew
)
return
-
ENOMEM
;
if
(
spec
->
kctl_alloc
)
{
memcpy
(
knew
,
spec
->
kctl_alloc
,
sizeof
(
*
knew
)
*
spec
->
num_kctl_alloc
);
kfree
(
spec
->
kctl_alloc
);
}
spec
->
kctl_alloc
=
knew
;
spec
->
num_kctl_alloc
=
num
;
}
knew
=
&
spec
->
kctl_alloc
[
spec
->
num_kctl_used
];
snd_array_init
(
&
spec
->
kctls
,
sizeof
(
*
knew
),
32
);
knew
=
snd_array_new
(
&
spec
->
kctls
);
if
(
!
knew
)
return
-
ENOMEM
;
*
knew
=
alc880_control_templates
[
type
];
knew
->
name
=
kstrdup
(
name
,
GFP_KERNEL
);
if
(
!
knew
->
name
)
return
-
ENOMEM
;
knew
->
private_value
=
val
;
spec
->
num_kctl_used
++
;
return
0
;
}
...
...
@@ -3824,8 +3818,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_in_pin
)
spec
->
dig_in_nid
=
ALC880_DIGIN_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
init_verbs
[
spec
->
num_init_verbs
++
]
=
alc880_volume_init_verbs
;
...
...
@@ -5218,7 +5212,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
err
=
alc260_auto_create_multi_out_ctls
(
spec
,
&
spec
->
autocfg
);
if
(
err
<
0
)
return
err
;
if
(
!
spec
->
kctl
_alloc
)
if
(
!
spec
->
kctl
s
.
list
)
return
0
;
/* can't find valid BIOS pin config */
err
=
alc260_auto_create_analog_input_ctls
(
spec
,
&
spec
->
autocfg
);
if
(
err
<
0
)
...
...
@@ -5228,8 +5222,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_out_pin
)
spec
->
multiout
.
dig_out_nid
=
ALC260_DIGOUT_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
init_verbs
[
spec
->
num_init_verbs
++
]
=
alc260_volume_init_verbs
;
...
...
@@ -10302,8 +10296,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_in_pin
)
spec
->
dig_in_nid
=
ALC262_DIGIN_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
init_verbs
[
spec
->
num_init_verbs
++
]
=
alc262_volume_init_verbs
;
spec
->
num_mux_defs
=
1
;
...
...
@@ -11433,8 +11427,8 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_out_pin
)
spec
->
multiout
.
dig_out_nid
=
ALC268_DIGOUT_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
if
(
spec
->
autocfg
.
speaker_pins
[
0
]
!=
0x1d
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
alc268_beep_mixer
;
...
...
@@ -12205,8 +12199,8 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_out_pin
)
spec
->
multiout
.
dig_out_nid
=
ALC269_DIGOUT_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
/* create a beep mixer control if the pin 0x1d isn't assigned */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
spec
->
autocfg
.
input_pins
);
i
++
)
...
...
@@ -13303,8 +13297,8 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_out_pin
)
spec
->
multiout
.
dig_out_nid
=
ALC861_DIGOUT_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
init_verbs
[
spec
->
num_init_verbs
++
]
=
alc861_auto_init_verbs
;
...
...
@@ -14414,8 +14408,8 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_out_pin
)
spec
->
multiout
.
dig_out_nid
=
ALC861VD_DIGOUT_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
init_verbs
[
spec
->
num_init_verbs
++
]
=
alc861vd_volume_init_verbs
;
...
...
@@ -16241,8 +16235,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_out_pin
)
spec
->
multiout
.
dig_out_nid
=
ALC880_DIGOUT_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
num_mux_defs
=
1
;
spec
->
input_mux
=
&
spec
->
private_imux
;
...
...
sound/pci/hda/patch_sigmatel.c
View file @
42dc2378
This diff is collapsed.
Click to expand it.
sound/pci/hda/patch_via.c
View file @
42dc2378
...
...
@@ -53,9 +53,6 @@
#define AMP_VAL_IDX_SHIFT 19
#define AMP_VAL_IDX_MASK (0x0f<<19)
#define NUM_CONTROL_ALLOC 32
#define NUM_VERB_ALLOC 32
/* Pin Widget NID */
#define VT1708_HP_NID 0x13
#define VT1708_DIGOUT_NID 0x14
...
...
@@ -227,8 +224,7 @@ struct via_spec {
/* dynamic controls, init_verbs and input_mux */
struct
auto_pin_cfg
autocfg
;
unsigned
int
num_kctl_alloc
,
num_kctl_used
;
struct
snd_kcontrol_new
*
kctl_alloc
;
struct
snd_array
kctls
;
struct
hda_input_mux
private_imux
[
2
];
hda_nid_t
private_dac_nids
[
AUTO_CFG_MAX_OUTS
];
...
...
@@ -272,33 +268,31 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
{
struct
snd_kcontrol_new
*
knew
;
if
(
spec
->
num_kctl_used
>=
spec
->
num_kctl_alloc
)
{
int
num
=
spec
->
num_kctl_alloc
+
NUM_CONTROL_ALLOC
;
/* array + terminator */
knew
=
kcalloc
(
num
+
1
,
sizeof
(
*
knew
),
GFP_KERNEL
);
if
(
!
knew
)
return
-
ENOMEM
;
if
(
spec
->
kctl_alloc
)
{
memcpy
(
knew
,
spec
->
kctl_alloc
,
sizeof
(
*
knew
)
*
spec
->
num_kctl_alloc
);
kfree
(
spec
->
kctl_alloc
);
}
spec
->
kctl_alloc
=
knew
;
spec
->
num_kctl_alloc
=
num
;
}
knew
=
&
spec
->
kctl_alloc
[
spec
->
num_kctl_used
];
snd_array_init
(
&
spec
->
kctls
,
sizeof
(
*
knew
),
32
);
knew
=
snd_array_new
(
&
spec
->
kctls
);
if
(
!
knew
)
return
-
ENOMEM
;
*
knew
=
vt1708_control_templates
[
type
];
knew
->
name
=
kstrdup
(
name
,
GFP_KERNEL
);
if
(
!
knew
->
name
)
return
-
ENOMEM
;
knew
->
private_value
=
val
;
spec
->
num_kctl_used
++
;
return
0
;
}
static
void
via_free_kctls
(
struct
hda_codec
*
codec
)
{
struct
via_spec
*
spec
=
codec
->
spec
;
if
(
spec
->
kctls
.
list
)
{
struct
snd_kcontrol_new
*
kctl
=
spec
->
kctls
.
list
;
int
i
;
for
(
i
=
0
;
i
<
spec
->
kctls
.
used
;
i
++
)
kfree
(
kctl
[
i
].
name
);
}
snd_array_free
(
&
spec
->
kctls
);
}
/* create input playback/capture controls for the given pin */
static
int
via_new_analog_input
(
struct
via_spec
*
spec
,
hda_nid_t
pin
,
const
char
*
ctlname
,
int
idx
,
int
mix_nid
)
...
...
@@ -896,6 +890,7 @@ static int via_build_controls(struct hda_codec *codec)
if
(
err
<
0
)
return
err
;
}
via_free_kctls
(
codec
);
/* no longer needed */
return
0
;
}
...
...
@@ -941,17 +936,11 @@ static int via_build_pcms(struct hda_codec *codec)
static
void
via_free
(
struct
hda_codec
*
codec
)
{
struct
via_spec
*
spec
=
codec
->
spec
;
unsigned
int
i
;
if
(
!
spec
)
return
;
if
(
spec
->
kctl_alloc
)
{
for
(
i
=
0
;
i
<
spec
->
num_kctl_used
;
i
++
)
kfree
(
spec
->
kctl_alloc
[
i
].
name
);
kfree
(
spec
->
kctl_alloc
);
}
via_free_kctls
(
codec
);
kfree
(
codec
->
spec
);
}
...
...
@@ -1373,8 +1362,8 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_in_pin
)
spec
->
dig_in_nid
=
VT1708_DIGIN_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
init_verbs
[
spec
->
num_iverbs
++
]
=
vt1708_volume_init_verbs
;
...
...
@@ -1846,8 +1835,8 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_in_pin
)
spec
->
dig_in_nid
=
VT1709_DIGIN_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
input_mux
=
&
spec
->
private_imux
[
0
];
...
...
@@ -2390,8 +2379,8 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
if
(
spec
->
autocfg
.
dig_in_pin
)
spec
->
dig_in_nid
=
VT1708B_DIGIN_NID
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
input_mux
=
&
spec
->
private_imux
[
0
];
...
...
@@ -2855,8 +2844,8 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
spec
->
extra_dig_out_nid
=
0x15
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
input_mux
=
&
spec
->
private_imux
[
0
];
...
...
@@ -3174,8 +3163,8 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
spec
->
extra_dig_out_nid
=
0x1B
;
if
(
spec
->
kctl
_alloc
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
_alloc
;
if
(
spec
->
kctl
s
.
list
)
spec
->
mixers
[
spec
->
num_mixers
++
]
=
spec
->
kctl
s
.
list
;
spec
->
input_mux
=
&
spec
->
private_imux
[
0
];
...
...
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