Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
1962fcab
Commit
1962fcab
authored
Apr 28, 2015
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/jack' into for-next
parents
f1a77547
12e180a2
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
242 additions
and
100 deletions
+242
-100
Documentation/sound/alsa/Jack-Controls.txt
Documentation/sound/alsa/Jack-Controls.txt
+43
-0
include/sound/control.h
include/sound/control.h
+1
-1
include/sound/jack.h
include/sound/jack.h
+10
-3
sound/core/Kconfig
sound/core/Kconfig
+0
-3
sound/core/Makefile
sound/core/Makefile
+1
-2
sound/core/ctljack.c
sound/core/ctljack.c
+35
-6
sound/core/jack.c
sound/core/jack.c
+121
-12
sound/pci/hda/Kconfig
sound/pci/hda/Kconfig
+1
-1
sound/pci/hda/hda_jack.c
sound/pci/hda/hda_jack.c
+25
-65
sound/pci/hda/hda_jack.h
sound/pci/hda/hda_jack.h
+1
-4
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_hdmi.c
+1
-1
sound/pci/oxygen/xonar_wm87x6.c
sound/pci/oxygen/xonar_wm87x6.c
+1
-1
sound/soc/soc-jack.c
sound/soc/soc-jack.c
+2
-1
No files found.
Documentation/sound/alsa/Jack-Controls.txt
0 → 100644
View file @
1962fcab
Why we need Jack kcontrols
==========================
ALSA uses kcontrols to export audio controls(switch, volume, Mux, ...)
to user space. This means userspace applications like pulseaudio can
switch off headphones and switch on speakers when no headphones are
pluged in.
The old ALSA jack code only created input devices for each registered
jack. These jack input devices are not readable by userspace devices
that run as non root.
The new jack code creates embedded jack kcontrols for each jack that
can be read by any process.
This can be combined with UCM to allow userspace to route audio more
intelligently based on jack insertion or removal events.
Jack Kcontrol Internals
=======================
Each jack will have a kcontrol list, so that we can create a kcontrol
and attach it to the jack, at jack creation stage. We can also add a
kcontrol to an existing jack, at anytime when required.
Those kcontrols will be freed automatically when the Jack is freed.
How to use jack kcontrols
=========================
In order to keep compatibility, snd_jack_new() has been modified by
adding two params :-
- @initial_kctl: if true, create a kcontrol and add it to the jack
list.
- @phantom_jack: Don't create a input device for phantom jacks.
HDA jacks can set phantom_jack to true in order to create a phantom
jack and set initial_kctl to true to create an initial kcontrol with
the correct id.
ASoC jacks should set initial_kctl as false. The pin name will be
assigned as the jack kcontrol name.
include/sound/control.h
View file @
1962fcab
...
@@ -252,7 +252,7 @@ void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
...
@@ -252,7 +252,7 @@ void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
* Helper functions for jack-detection controls
* Helper functions for jack-detection controls
*/
*/
struct
snd_kcontrol
*
struct
snd_kcontrol
*
snd_kctl_jack_new
(
const
char
*
name
,
int
idx
,
void
*
private_data
);
snd_kctl_jack_new
(
const
char
*
name
,
struct
snd_card
*
card
);
void
snd_kctl_jack_report
(
struct
snd_card
*
card
,
void
snd_kctl_jack_report
(
struct
snd_card
*
card
,
struct
snd_kcontrol
*
kctl
,
bool
status
);
struct
snd_kcontrol
*
kctl
,
bool
status
);
...
...
include/sound/jack.h
View file @
1962fcab
...
@@ -73,6 +73,8 @@ enum snd_jack_types {
...
@@ -73,6 +73,8 @@ enum snd_jack_types {
struct
snd_jack
{
struct
snd_jack
{
struct
input_dev
*
input_dev
;
struct
input_dev
*
input_dev
;
struct
list_head
kctl_list
;
struct
snd_card
*
card
;
int
registered
;
int
registered
;
int
type
;
int
type
;
const
char
*
id
;
const
char
*
id
;
...
@@ -85,7 +87,8 @@ struct snd_jack {
...
@@ -85,7 +87,8 @@ struct snd_jack {
#ifdef CONFIG_SND_JACK
#ifdef CONFIG_SND_JACK
int
snd_jack_new
(
struct
snd_card
*
card
,
const
char
*
id
,
int
type
,
int
snd_jack_new
(
struct
snd_card
*
card
,
const
char
*
id
,
int
type
,
struct
snd_jack
**
jack
);
struct
snd_jack
**
jack
,
bool
initial_kctl
,
bool
phantom_jack
);
int
snd_jack_add_new_kctl
(
struct
snd_jack
*
jack
,
const
char
*
name
,
int
mask
);
void
snd_jack_set_parent
(
struct
snd_jack
*
jack
,
struct
device
*
parent
);
void
snd_jack_set_parent
(
struct
snd_jack
*
jack
,
struct
device
*
parent
);
int
snd_jack_set_key
(
struct
snd_jack
*
jack
,
enum
snd_jack_types
type
,
int
snd_jack_set_key
(
struct
snd_jack
*
jack
,
enum
snd_jack_types
type
,
int
keytype
);
int
keytype
);
...
@@ -93,9 +96,13 @@ int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
...
@@ -93,9 +96,13 @@ int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
void
snd_jack_report
(
struct
snd_jack
*
jack
,
int
status
);
void
snd_jack_report
(
struct
snd_jack
*
jack
,
int
status
);
#else
#else
static
inline
int
snd_jack_new
(
struct
snd_card
*
card
,
const
char
*
id
,
int
type
,
static
inline
int
snd_jack_new
(
struct
snd_card
*
card
,
const
char
*
id
,
int
type
,
struct
snd_jack
**
jack
)
struct
snd_jack
**
jack
,
bool
initial_kctl
,
bool
phantom_jack
)
{
return
0
;
}
static
inline
int
snd_jack_add_new_kctl
(
struct
snd_jack
*
jack
,
const
char
*
name
,
int
mask
)
{
{
return
0
;
return
0
;
}
}
...
...
sound/core/Kconfig
View file @
1962fcab
...
@@ -221,9 +221,6 @@ config SND_PCM_XRUN_DEBUG
...
@@ -221,9 +221,6 @@ config SND_PCM_XRUN_DEBUG
config SND_VMASTER
config SND_VMASTER
bool
bool
config SND_KCTL_JACK
bool
config SND_DMA_SGBUF
config SND_DMA_SGBUF
def_bool y
def_bool y
depends on X86
depends on X86
...
...
sound/core/Makefile
View file @
1962fcab
...
@@ -11,8 +11,7 @@ endif
...
@@ -11,8 +11,7 @@ endif
snd-$(CONFIG_ISA_DMA_API)
+=
isadma.o
snd-$(CONFIG_ISA_DMA_API)
+=
isadma.o
snd-$(CONFIG_SND_OSSEMUL)
+=
sound_oss.o
snd-$(CONFIG_SND_OSSEMUL)
+=
sound_oss.o
snd-$(CONFIG_SND_VMASTER)
+=
vmaster.o
snd-$(CONFIG_SND_VMASTER)
+=
vmaster.o
snd-$(CONFIG_SND_KCTL_JACK)
+=
ctljack.o
snd-$(CONFIG_SND_JACK)
+=
ctljack.o jack.o
snd-$(CONFIG_SND_JACK)
+=
jack.o
snd-pcm-y
:=
pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o
\
snd-pcm-y
:=
pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o
\
pcm_memory.o memalloc.o
pcm_memory.o memalloc.o
...
...
sound/core/ctljack.c
View file @
1962fcab
...
@@ -31,19 +31,49 @@ static struct snd_kcontrol_new jack_detect_kctl = {
...
@@ -31,19 +31,49 @@ static struct snd_kcontrol_new jack_detect_kctl = {
.
get
=
jack_detect_kctl_get
,
.
get
=
jack_detect_kctl_get
,
};
};
static
int
get_available_index
(
struct
snd_card
*
card
,
const
char
*
name
)
{
struct
snd_ctl_elem_id
sid
;
memset
(
&
sid
,
0
,
sizeof
(
sid
));
sid
.
index
=
0
;
sid
.
iface
=
SNDRV_CTL_ELEM_IFACE_CARD
;
strlcpy
(
sid
.
name
,
name
,
sizeof
(
sid
.
name
));
while
(
snd_ctl_find_id
(
card
,
&
sid
))
sid
.
index
++
;
return
sid
.
index
;
}
static
void
jack_kctl_name_gen
(
char
*
name
,
const
char
*
src_name
,
int
size
)
{
size_t
count
=
strlen
(
src_name
);
bool
need_cat
=
true
;
/* remove redundant " Jack" from src_name */
if
(
count
>=
5
)
need_cat
=
strncmp
(
&
src_name
[
count
-
5
],
" Jack"
,
5
)
?
true
:
false
;
snprintf
(
name
,
size
,
need_cat
?
"%s Jack"
:
"%s"
,
src_name
);
}
struct
snd_kcontrol
*
struct
snd_kcontrol
*
snd_kctl_jack_new
(
const
char
*
name
,
int
idx
,
void
*
private_data
)
snd_kctl_jack_new
(
const
char
*
name
,
struct
snd_card
*
card
)
{
{
struct
snd_kcontrol
*
kctl
;
struct
snd_kcontrol
*
kctl
;
kctl
=
snd_ctl_new1
(
&
jack_detect_kctl
,
private_data
);
kctl
=
snd_ctl_new1
(
&
jack_detect_kctl
,
NULL
);
if
(
!
kctl
)
if
(
!
kctl
)
return
NULL
;
return
NULL
;
snprintf
(
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
),
"%s Jack"
,
name
);
kctl
->
id
.
index
=
idx
;
jack_kctl_name_gen
(
kctl
->
id
.
name
,
name
,
sizeof
(
kctl
->
id
.
name
));
kctl
->
id
.
index
=
get_available_index
(
card
,
name
);
kctl
->
private_value
=
0
;
kctl
->
private_value
=
0
;
return
kctl
;
return
kctl
;
}
}
EXPORT_SYMBOL_GPL
(
snd_kctl_jack_new
);
void
snd_kctl_jack_report
(
struct
snd_card
*
card
,
void
snd_kctl_jack_report
(
struct
snd_card
*
card
,
struct
snd_kcontrol
*
kctl
,
bool
status
)
struct
snd_kcontrol
*
kctl
,
bool
status
)
...
@@ -53,4 +83,3 @@ void snd_kctl_jack_report(struct snd_card *card,
...
@@ -53,4 +83,3 @@ void snd_kctl_jack_report(struct snd_card *card,
kctl
->
private_value
=
status
;
kctl
->
private_value
=
status
;
snd_ctl_notify
(
card
,
SNDRV_CTL_EVENT_MASK_VALUE
,
&
kctl
->
id
);
snd_ctl_notify
(
card
,
SNDRV_CTL_EVENT_MASK_VALUE
,
&
kctl
->
id
);
}
}
EXPORT_SYMBOL_GPL
(
snd_kctl_jack_report
);
sound/core/jack.c
View file @
1962fcab
...
@@ -24,6 +24,13 @@
...
@@ -24,6 +24,13 @@
#include <linux/module.h>
#include <linux/module.h>
#include <sound/jack.h>
#include <sound/jack.h>
#include <sound/core.h>
#include <sound/core.h>
#include <sound/control.h>
struct
snd_jack_kctl
{
struct
snd_kcontrol
*
kctl
;
struct
list_head
list
;
/* list of controls belong to the same jack */
unsigned
int
mask_bits
;
/* only masked status bits are reported via kctl */
};
static
int
jack_switch_types
[
SND_JACK_SWITCH_TYPES
]
=
{
static
int
jack_switch_types
[
SND_JACK_SWITCH_TYPES
]
=
{
SW_HEADPHONE_INSERT
,
SW_HEADPHONE_INSERT
,
...
@@ -54,7 +61,13 @@ static int snd_jack_dev_disconnect(struct snd_device *device)
...
@@ -54,7 +61,13 @@ static int snd_jack_dev_disconnect(struct snd_device *device)
static
int
snd_jack_dev_free
(
struct
snd_device
*
device
)
static
int
snd_jack_dev_free
(
struct
snd_device
*
device
)
{
{
struct
snd_jack
*
jack
=
device
->
device_data
;
struct
snd_jack
*
jack
=
device
->
device_data
;
struct
snd_card
*
card
=
device
->
card
;
struct
snd_jack_kctl
*
jack_kctl
,
*
tmp_jack_kctl
;
list_for_each_entry_safe
(
jack_kctl
,
tmp_jack_kctl
,
&
jack
->
kctl_list
,
list
)
{
list_del_init
(
&
jack_kctl
->
list
);
snd_ctl_remove
(
card
,
jack_kctl
->
kctl
);
}
if
(
jack
->
private_free
)
if
(
jack
->
private_free
)
jack
->
private_free
(
jack
);
jack
->
private_free
(
jack
);
...
@@ -100,6 +113,77 @@ static int snd_jack_dev_register(struct snd_device *device)
...
@@ -100,6 +113,77 @@ static int snd_jack_dev_register(struct snd_device *device)
return
err
;
return
err
;
}
}
static
void
snd_jack_kctl_private_free
(
struct
snd_kcontrol
*
kctl
)
{
struct
snd_jack_kctl
*
jack_kctl
;
jack_kctl
=
kctl
->
private_data
;
if
(
jack_kctl
)
{
list_del
(
&
jack_kctl
->
list
);
kfree
(
jack_kctl
);
}
}
static
void
snd_jack_kctl_add
(
struct
snd_jack
*
jack
,
struct
snd_jack_kctl
*
jack_kctl
)
{
list_add_tail
(
&
jack_kctl
->
list
,
&
jack
->
kctl_list
);
}
static
struct
snd_jack_kctl
*
snd_jack_kctl_new
(
struct
snd_card
*
card
,
const
char
*
name
,
unsigned
int
mask
)
{
struct
snd_kcontrol
*
kctl
;
struct
snd_jack_kctl
*
jack_kctl
;
int
err
;
kctl
=
snd_kctl_jack_new
(
name
,
card
);
if
(
!
kctl
)
return
NULL
;
err
=
snd_ctl_add
(
card
,
kctl
);
if
(
err
<
0
)
return
NULL
;
jack_kctl
=
kzalloc
(
sizeof
(
*
jack_kctl
),
GFP_KERNEL
);
if
(
!
jack_kctl
)
goto
error
;
jack_kctl
->
kctl
=
kctl
;
jack_kctl
->
mask_bits
=
mask
;
kctl
->
private_data
=
jack_kctl
;
kctl
->
private_free
=
snd_jack_kctl_private_free
;
return
jack_kctl
;
error:
snd_ctl_free_one
(
kctl
);
return
NULL
;
}
/**
* snd_jack_add_new_kctl - Create a new snd_jack_kctl and add it to jack
* @jack: the jack instance which the kctl will attaching to
* @name: the name for the snd_kcontrol object
* @mask: a bitmask of enum snd_jack_type values that can be detected
* by this snd_jack_kctl object.
*
* Creates a new snd_kcontrol object and adds it to the jack kctl_list.
*
* Return: Zero if successful, or a negative error code on failure.
*/
int
snd_jack_add_new_kctl
(
struct
snd_jack
*
jack
,
const
char
*
name
,
int
mask
)
{
struct
snd_jack_kctl
*
jack_kctl
;
jack_kctl
=
snd_jack_kctl_new
(
jack
->
card
,
name
,
mask
);
if
(
!
jack_kctl
)
return
-
ENOMEM
;
snd_jack_kctl_add
(
jack
,
jack_kctl
);
return
0
;
}
EXPORT_SYMBOL
(
snd_jack_add_new_kctl
);
/**
/**
* snd_jack_new - Create a new jack
* snd_jack_new - Create a new jack
* @card: the card instance
* @card: the card instance
...
@@ -107,6 +191,8 @@ static int snd_jack_dev_register(struct snd_device *device)
...
@@ -107,6 +191,8 @@ static int snd_jack_dev_register(struct snd_device *device)
* @type: a bitmask of enum snd_jack_type values that can be detected by
* @type: a bitmask of enum snd_jack_type values that can be detected by
* this jack
* this jack
* @jjack: Used to provide the allocated jack object to the caller.
* @jjack: Used to provide the allocated jack object to the caller.
* @initial_kctl: if true, create a kcontrol and add it to the jack list.
* @phantom_jack: Don't create a input device for phantom jacks.
*
*
* Creates a new jack object.
* Creates a new jack object.
*
*
...
@@ -114,9 +200,10 @@ static int snd_jack_dev_register(struct snd_device *device)
...
@@ -114,9 +200,10 @@ static int snd_jack_dev_register(struct snd_device *device)
* On success @jjack will be initialised.
* On success @jjack will be initialised.
*/
*/
int
snd_jack_new
(
struct
snd_card
*
card
,
const
char
*
id
,
int
type
,
int
snd_jack_new
(
struct
snd_card
*
card
,
const
char
*
id
,
int
type
,
struct
snd_jack
**
jjack
)
struct
snd_jack
**
jjack
,
bool
initial_kctl
,
bool
phantom_jack
)
{
{
struct
snd_jack
*
jack
;
struct
snd_jack
*
jack
;
struct
snd_jack_kctl
*
jack_kctl
=
NULL
;
int
err
;
int
err
;
int
i
;
int
i
;
static
struct
snd_device_ops
ops
=
{
static
struct
snd_device_ops
ops
=
{
...
@@ -125,12 +212,20 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
...
@@ -125,12 +212,20 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
.
dev_disconnect
=
snd_jack_dev_disconnect
,
.
dev_disconnect
=
snd_jack_dev_disconnect
,
};
};
if
(
initial_kctl
)
{
jack_kctl
=
snd_jack_kctl_new
(
card
,
id
,
type
);
if
(
!
jack_kctl
)
return
-
ENOMEM
;
}
jack
=
kzalloc
(
sizeof
(
struct
snd_jack
),
GFP_KERNEL
);
jack
=
kzalloc
(
sizeof
(
struct
snd_jack
),
GFP_KERNEL
);
if
(
jack
==
NULL
)
if
(
jack
==
NULL
)
return
-
ENOMEM
;
return
-
ENOMEM
;
jack
->
id
=
kstrdup
(
id
,
GFP_KERNEL
);
jack
->
id
=
kstrdup
(
id
,
GFP_KERNEL
);
/* don't creat input device for phantom jack */
if
(
!
phantom_jack
)
{
jack
->
input_dev
=
input_allocate_device
();
jack
->
input_dev
=
input_allocate_device
();
if
(
jack
->
input_dev
==
NULL
)
{
if
(
jack
->
input_dev
==
NULL
)
{
err
=
-
ENOMEM
;
err
=
-
ENOMEM
;
...
@@ -146,10 +241,18 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
...
@@ -146,10 +241,18 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
input_set_capability
(
jack
->
input_dev
,
EV_SW
,
input_set_capability
(
jack
->
input_dev
,
EV_SW
,
jack_switch_types
[
i
]);
jack_switch_types
[
i
]);
}
err
=
snd_device_new
(
card
,
SNDRV_DEV_JACK
,
jack
,
&
ops
);
err
=
snd_device_new
(
card
,
SNDRV_DEV_JACK
,
jack
,
&
ops
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
fail_input
;
goto
fail_input
;
jack
->
card
=
card
;
INIT_LIST_HEAD
(
&
jack
->
kctl_list
);
if
(
initial_kctl
)
snd_jack_kctl_add
(
jack
,
jack_kctl
);
*
jjack
=
jack
;
*
jjack
=
jack
;
return
0
;
return
0
;
...
@@ -230,6 +333,7 @@ EXPORT_SYMBOL(snd_jack_set_key);
...
@@ -230,6 +333,7 @@ EXPORT_SYMBOL(snd_jack_set_key);
*/
*/
void
snd_jack_report
(
struct
snd_jack
*
jack
,
int
status
)
void
snd_jack_report
(
struct
snd_jack
*
jack
,
int
status
)
{
{
struct
snd_jack_kctl
*
jack_kctl
;
int
i
;
int
i
;
if
(
!
jack
)
if
(
!
jack
)
...
@@ -252,6 +356,11 @@ void snd_jack_report(struct snd_jack *jack, int status)
...
@@ -252,6 +356,11 @@ void snd_jack_report(struct snd_jack *jack, int status)
}
}
input_sync
(
jack
->
input_dev
);
input_sync
(
jack
->
input_dev
);
list_for_each_entry
(
jack_kctl
,
&
jack
->
kctl_list
,
list
)
snd_kctl_jack_report
(
jack
->
card
,
jack_kctl
->
kctl
,
status
&
jack_kctl
->
mask_bits
);
}
}
EXPORT_SYMBOL
(
snd_jack_report
);
EXPORT_SYMBOL
(
snd_jack_report
);
...
...
sound/pci/hda/Kconfig
View file @
1962fcab
...
@@ -4,7 +4,7 @@ config SND_HDA
...
@@ -4,7 +4,7 @@ config SND_HDA
tristate
tristate
select SND_PCM
select SND_PCM
select SND_VMASTER
select SND_VMASTER
select SND_
KCTL_
JACK
select SND_JACK
select SND_HDA_CORE
select SND_HDA_CORE
config SND_HDA_INTEL
config SND_HDA_INTEL
...
...
sound/pci/hda/hda_jack.c
View file @
1962fcab
...
@@ -132,11 +132,11 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
...
@@ -132,11 +132,11 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
for
(
i
=
0
;
i
<
codec
->
jacktbl
.
used
;
i
++
,
jack
++
)
{
for
(
i
=
0
;
i
<
codec
->
jacktbl
.
used
;
i
++
,
jack
++
)
{
struct
hda_jack_callback
*
cb
,
*
next
;
struct
hda_jack_callback
*
cb
,
*
next
;
#ifdef CONFIG_SND_HDA_INPUT_JACK
/* free jack instances manually when clearing/reconfiguring */
/* free jack instances manually when clearing/reconfiguring */
if
(
!
codec
->
bus
->
shutdown
&&
jack
->
jack
)
if
(
!
codec
->
bus
->
shutdown
&&
jack
->
jack
)
snd_device_free
(
codec
->
card
,
jack
->
jack
);
snd_device_free
(
codec
->
card
,
jack
->
jack
);
#endif
for
(
cb
=
jack
->
callback
;
cb
;
cb
=
next
)
{
for
(
cb
=
jack
->
callback
;
cb
;
cb
=
next
)
{
next
=
cb
->
next
;
next
=
cb
->
next
;
kfree
(
cb
);
kfree
(
cb
);
...
@@ -337,20 +337,15 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
...
@@ -337,20 +337,15 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
jack
=
codec
->
jacktbl
.
list
;
jack
=
codec
->
jacktbl
.
list
;
for
(
i
=
0
;
i
<
codec
->
jacktbl
.
used
;
i
++
,
jack
++
)
for
(
i
=
0
;
i
<
codec
->
jacktbl
.
used
;
i
++
,
jack
++
)
if
(
jack
->
nid
)
{
if
(
jack
->
nid
)
{
if
(
!
jack
->
kctl
||
jack
->
block_report
)
if
(
!
jack
->
jack
||
jack
->
block_report
)
continue
;
continue
;
state
=
get_jack_plug_state
(
jack
->
pin_sense
);
state
=
get_jack_plug_state
(
jack
->
pin_sense
);
snd_kctl_jack_report
(
codec
->
card
,
jack
->
kctl
,
state
);
#ifdef CONFIG_SND_HDA_INPUT_JACK
if
(
jack
->
jack
)
snd_jack_report
(
jack
->
jack
,
snd_jack_report
(
jack
->
jack
,
state
?
jack
->
type
:
0
);
state
?
jack
->
type
:
0
);
#endif
}
}
}
}
EXPORT_SYMBOL_GPL
(
snd_hda_jack_report_sync
);
EXPORT_SYMBOL_GPL
(
snd_hda_jack_report_sync
);
#ifdef CONFIG_SND_HDA_INPUT_JACK
/* guess the jack type from the pin-config */
/* guess the jack type from the pin-config */
static
int
get_input_jack_type
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
)
static
int
get_input_jack_type
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
)
{
{
...
@@ -377,54 +372,42 @@ static void hda_free_jack_priv(struct snd_jack *jack)
...
@@ -377,54 +372,42 @@ static void hda_free_jack_priv(struct snd_jack *jack)
jacks
->
nid
=
0
;
jacks
->
nid
=
0
;
jacks
->
jack
=
NULL
;
jacks
->
jack
=
NULL
;
}
}
#endif
/**
/**
* snd_hda_jack_add_kctl - Add a kctl for the given pin
* snd_hda_jack_add_kctl - Add a kctl for the given pin
* @codec: the HDA codec
* @codec: the HDA codec
* @nid: pin NID to assign
* @nid: pin NID to assign
* @name: string name for the jack
* @name: string name for the jack
* @idx: index number for the jack
* @phantom_jack: flag to deal as a phantom jack
* @phantom_jack: flag to deal as a phantom jack
*
*
* This assigns a jack-detection kctl to the given pin. The kcontrol
* This assigns a jack-detection kctl to the given pin. The kcontrol
* will have the given name and index.
* will have the given name and index.
*/
*/
static
int
__snd_hda_jack_add_kctl
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
static
int
__snd_hda_jack_add_kctl
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
const
char
*
name
,
int
idx
,
bool
phantom_jack
)
const
char
*
name
,
bool
phantom_jack
)
{
{
struct
hda_jack_tbl
*
jack
;
struct
hda_jack_tbl
*
jack
;
struct
snd_kcontrol
*
kctl
;
int
err
,
state
,
type
;
int
err
,
state
;
jack
=
snd_hda_jack_tbl_new
(
codec
,
nid
);
jack
=
snd_hda_jack_tbl_new
(
codec
,
nid
);
if
(
!
jack
)
if
(
!
jack
)
return
0
;
return
0
;
if
(
jack
->
kctl
)
if
(
jack
->
jack
)
return
0
;
/* already created */
return
0
;
/* already created */
kctl
=
snd_kctl_jack_new
(
name
,
idx
,
codec
);
if
(
!
kctl
)
return
-
ENOMEM
;
err
=
snd_hda_ctl_add
(
codec
,
nid
,
kctl
);
if
(
err
<
0
)
return
err
;
jack
->
kctl
=
kctl
;
jack
->
phantom_jack
=
!!
phantom_jack
;
state
=
snd_hda_jack_detect
(
codec
,
nid
);
type
=
get_input_jack_type
(
codec
,
nid
);
snd_kctl_jack_report
(
codec
->
card
,
kctl
,
state
);
err
=
snd_jack_new
(
codec
->
card
,
name
,
type
,
#ifdef CONFIG_SND_HDA_INPUT_JACK
&
jack
->
jack
,
true
,
phantom_jack
);
if
(
!
phantom_jack
)
{
jack
->
type
=
get_input_jack_type
(
codec
,
nid
);
err
=
snd_jack_new
(
codec
->
card
,
name
,
jack
->
type
,
&
jack
->
jack
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
jack
->
phantom_jack
=
!!
phantom_jack
;
jack
->
type
=
type
;
jack
->
jack
->
private_data
=
jack
;
jack
->
jack
->
private_data
=
jack
;
jack
->
jack
->
private_free
=
hda_free_jack_priv
;
jack
->
jack
->
private_free
=
hda_free_jack_priv
;
state
=
snd_hda_jack_detect
(
codec
,
nid
);
snd_jack_report
(
jack
->
jack
,
state
?
jack
->
type
:
0
);
snd_jack_report
(
jack
->
jack
,
state
?
jack
->
type
:
0
);
}
#endif
return
0
;
return
0
;
}
}
...
@@ -433,44 +416,23 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
...
@@ -433,44 +416,23 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
* @codec: the HDA codec
* @codec: the HDA codec
* @nid: pin NID
* @nid: pin NID
* @name: the name string for the jack ctl
* @name: the name string for the jack ctl
* @idx: the ctl index for the jack ctl
*
*
* This is a simple helper calling __snd_hda_jack_add_kctl().
* This is a simple helper calling __snd_hda_jack_add_kctl().
*/
*/
int
snd_hda_jack_add_kctl
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
int
snd_hda_jack_add_kctl
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
const
char
*
name
,
int
idx
)
const
char
*
name
)
{
{
return
__snd_hda_jack_add_kctl
(
codec
,
nid
,
name
,
idx
,
false
);
return
__snd_hda_jack_add_kctl
(
codec
,
nid
,
name
,
false
);
}
}
EXPORT_SYMBOL_GPL
(
snd_hda_jack_add_kctl
);
EXPORT_SYMBOL_GPL
(
snd_hda_jack_add_kctl
);
/* get the unique index number for the given kctl name */
static
int
get_unique_index
(
struct
hda_codec
*
codec
,
const
char
*
name
,
int
idx
)
{
struct
hda_jack_tbl
*
jack
;
int
i
,
len
=
strlen
(
name
);
again:
jack
=
codec
->
jacktbl
.
list
;
for
(
i
=
0
;
i
<
codec
->
jacktbl
.
used
;
i
++
,
jack
++
)
{
/* jack->kctl.id contains "XXX Jack" name string with index */
if
(
jack
->
kctl
&&
!
strncmp
(
name
,
jack
->
kctl
->
id
.
name
,
len
)
&&
!
strcmp
(
" Jack"
,
jack
->
kctl
->
id
.
name
+
len
)
&&
jack
->
kctl
->
id
.
index
==
idx
)
{
idx
++
;
goto
again
;
}
}
return
idx
;
}
static
int
add_jack_kctl
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
static
int
add_jack_kctl
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
const
struct
auto_pin_cfg
*
cfg
,
const
struct
auto_pin_cfg
*
cfg
,
const
char
*
base_name
)
const
char
*
base_name
)
{
{
unsigned
int
def_conf
,
conn
;
unsigned
int
def_conf
,
conn
;
char
name
[
SNDRV_CTL_ELEM_ID_NAME_MAXLEN
];
char
name
[
SNDRV_CTL_ELEM_ID_NAME_MAXLEN
];
int
idx
,
err
;
int
err
;
bool
phantom_jack
;
bool
phantom_jack
;
if
(
!
nid
)
if
(
!
nid
)
...
@@ -482,16 +444,14 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
...
@@ -482,16 +444,14 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
phantom_jack
=
(
conn
!=
AC_JACK_PORT_COMPLEX
)
||
phantom_jack
=
(
conn
!=
AC_JACK_PORT_COMPLEX
)
||
!
is_jack_detectable
(
codec
,
nid
);
!
is_jack_detectable
(
codec
,
nid
);
if
(
base_name
)
{
if
(
base_name
)
strlcpy
(
name
,
base_name
,
sizeof
(
name
));
strlcpy
(
name
,
base_name
,
sizeof
(
name
));
idx
=
0
;
else
}
else
snd_hda_get_pin_label
(
codec
,
nid
,
cfg
,
name
,
sizeof
(
name
),
NULL
);
snd_hda_get_pin_label
(
codec
,
nid
,
cfg
,
name
,
sizeof
(
name
),
&
idx
);
if
(
phantom_jack
)
if
(
phantom_jack
)
/* Example final name: "Internal Mic Phantom Jack" */
/* Example final name: "Internal Mic Phantom Jack" */
strncat
(
name
,
" Phantom"
,
sizeof
(
name
)
-
strlen
(
name
)
-
1
);
strncat
(
name
,
" Phantom"
,
sizeof
(
name
)
-
strlen
(
name
)
-
1
);
idx
=
get_unique_index
(
codec
,
name
,
idx
);
err
=
__snd_hda_jack_add_kctl
(
codec
,
nid
,
name
,
phantom_jack
);
err
=
__snd_hda_jack_add_kctl
(
codec
,
nid
,
name
,
idx
,
phantom_jack
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
...
...
sound/pci/hda/hda_jack.h
View file @
1962fcab
...
@@ -39,11 +39,8 @@ struct hda_jack_tbl {
...
@@ -39,11 +39,8 @@ struct hda_jack_tbl {
unsigned
int
block_report
:
1
;
/* in a transitional state - do not report to userspace */
unsigned
int
block_report
:
1
;
/* in a transitional state - do not report to userspace */
hda_nid_t
gating_jack
;
/* valid when gating jack plugged */
hda_nid_t
gating_jack
;
/* valid when gating jack plugged */
hda_nid_t
gated_jack
;
/* gated is dependent on this jack */
hda_nid_t
gated_jack
;
/* gated is dependent on this jack */
struct
snd_kcontrol
*
kctl
;
/* assigned kctl for jack-detection */
#ifdef CONFIG_SND_HDA_INPUT_JACK
int
type
;
int
type
;
struct
snd_jack
*
jack
;
struct
snd_jack
*
jack
;
#endif
};
};
struct
hda_jack_tbl
*
struct
hda_jack_tbl
*
...
@@ -85,7 +82,7 @@ static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
...
@@ -85,7 +82,7 @@ static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
bool
is_jack_detectable
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
);
bool
is_jack_detectable
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
);
int
snd_hda_jack_add_kctl
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
int
snd_hda_jack_add_kctl
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
const
char
*
name
,
int
idx
);
const
char
*
name
);
int
snd_hda_jack_add_kctls
(
struct
hda_codec
*
codec
,
int
snd_hda_jack_add_kctls
(
struct
hda_codec
*
codec
,
const
struct
auto_pin_cfg
*
cfg
);
const
struct
auto_pin_cfg
*
cfg
);
...
...
sound/pci/hda/patch_hdmi.c
View file @
1962fcab
...
@@ -2081,7 +2081,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
...
@@ -2081,7 +2081,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
strncat
(
hdmi_str
,
" Phantom"
,
strncat
(
hdmi_str
,
" Phantom"
,
sizeof
(
hdmi_str
)
-
strlen
(
hdmi_str
)
-
1
);
sizeof
(
hdmi_str
)
-
strlen
(
hdmi_str
)
-
1
);
return
snd_hda_jack_add_kctl
(
codec
,
per_pin
->
pin_nid
,
hdmi_str
,
0
);
return
snd_hda_jack_add_kctl
(
codec
,
per_pin
->
pin_nid
,
hdmi_str
);
}
}
static
int
generic_hdmi_build_controls
(
struct
hda_codec
*
codec
)
static
int
generic_hdmi_build_controls
(
struct
hda_codec
*
codec
)
...
...
sound/pci/oxygen/xonar_wm87x6.c
View file @
1962fcab
...
@@ -286,7 +286,7 @@ static void xonar_ds_init(struct oxygen *chip)
...
@@ -286,7 +286,7 @@ static void xonar_ds_init(struct oxygen *chip)
xonar_enable_output
(
chip
);
xonar_enable_output
(
chip
);
snd_jack_new
(
chip
->
card
,
"Headphone"
,
snd_jack_new
(
chip
->
card
,
"Headphone"
,
SND_JACK_HEADPHONE
,
&
data
->
hp_jack
);
SND_JACK_HEADPHONE
,
&
data
->
hp_jack
,
false
,
false
);
xonar_ds_handle_hp_jack
(
chip
);
xonar_ds_handle_hp_jack
(
chip
);
snd_component_add
(
chip
->
card
,
"WM8776"
);
snd_component_add
(
chip
->
card
,
"WM8776"
);
...
...
sound/soc/soc-jack.c
View file @
1962fcab
...
@@ -48,7 +48,7 @@ int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
...
@@ -48,7 +48,7 @@ int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
INIT_LIST_HEAD
(
&
jack
->
jack_zones
);
INIT_LIST_HEAD
(
&
jack
->
jack_zones
);
BLOCKING_INIT_NOTIFIER_HEAD
(
&
jack
->
notifier
);
BLOCKING_INIT_NOTIFIER_HEAD
(
&
jack
->
notifier
);
ret
=
snd_jack_new
(
card
->
snd_card
,
id
,
type
,
&
jack
->
jack
);
ret
=
snd_jack_new
(
card
->
snd_card
,
id
,
type
,
&
jack
->
jack
,
false
,
false
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
...
@@ -197,6 +197,7 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
...
@@ -197,6 +197,7 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
INIT_LIST_HEAD
(
&
pins
[
i
].
list
);
INIT_LIST_HEAD
(
&
pins
[
i
].
list
);
list_add
(
&
(
pins
[
i
].
list
),
&
jack
->
pins
);
list_add
(
&
(
pins
[
i
].
list
),
&
jack
->
pins
);
snd_jack_add_new_kctl
(
jack
->
jack
,
pins
[
i
].
pin
,
pins
[
i
].
mask
);
}
}
/* Update to reflect the last reported status; canned jack
/* Update to reflect the last reported status; canned jack
...
...
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