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
c0f2302a
Commit
c0f2302a
authored
Dec 12, 2016
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/dapm' into asoc-next
parents
3f1b8613
02866eab
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
141 additions
and
35 deletions
+141
-35
include/sound/soc-dapm.h
include/sound/soc-dapm.h
+14
-0
sound/soc/codecs/adau17x1.c
sound/soc/codecs/adau17x1.c
+1
-1
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/tlv320aic3x.c
+1
-1
sound/soc/codecs/wm9712.c
sound/soc/codecs/wm9712.c
+1
-1
sound/soc/codecs/wm9713.c
sound/soc/codecs/wm9713.c
+1
-1
sound/soc/soc-dapm.c
sound/soc/soc-dapm.c
+123
-31
No files found.
include/sound/soc-dapm.h
View file @
c0f2302a
...
...
@@ -272,6 +272,16 @@ struct device;
/* dapm kcontrol types */
#define SOC_DAPM_DOUBLE(xname, reg, lshift, rshift, max, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, \
.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
.private_value = SOC_DOUBLE_VALUE(reg, lshift, rshift, max, invert, 0) }
#define SOC_DAPM_DOUBLE_R(xname, lreg, rreg, shift, max, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, \
.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
.private_value = SOC_DOUBLE_R_VALUE(lreg, rreg, shift, max, invert) }
#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, \
...
...
@@ -615,6 +625,10 @@ struct snd_soc_dapm_update {
int
reg
;
int
mask
;
int
val
;
int
reg2
;
int
mask2
;
int
val2
;
bool
has_second_set
;
};
struct
snd_soc_dapm_wcache
{
...
...
sound/soc/codecs/adau17x1.c
View file @
c0f2302a
...
...
@@ -160,7 +160,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
struct
snd_soc_dapm_context
*
dapm
=
snd_soc_codec_get_dapm
(
codec
);
struct
adau
*
adau
=
snd_soc_codec_get_drvdata
(
codec
);
struct
soc_enum
*
e
=
(
struct
soc_enum
*
)
kcontrol
->
private_value
;
struct
snd_soc_dapm_update
update
;
struct
snd_soc_dapm_update
update
=
{
0
}
;
unsigned
int
stream
=
e
->
shift_l
;
unsigned
int
val
,
change
;
int
reg
;
...
...
sound/soc/codecs/tlv320aic3x.c
View file @
c0f2302a
...
...
@@ -157,7 +157,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
unsigned
int
mask
=
(
1
<<
fls
(
max
))
-
1
;
unsigned
int
invert
=
mc
->
invert
;
unsigned
short
val
;
struct
snd_soc_dapm_update
update
;
struct
snd_soc_dapm_update
update
=
{
0
}
;
int
connect
,
change
;
val
=
(
ucontrol
->
value
.
integer
.
value
[
0
]
&
mask
);
...
...
sound/soc/codecs/wm9712.c
View file @
c0f2302a
...
...
@@ -187,7 +187,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol,
struct
soc_mixer_control
*
mc
=
(
struct
soc_mixer_control
*
)
kcontrol
->
private_value
;
unsigned
int
mixer
,
mask
,
shift
,
old
;
struct
snd_soc_dapm_update
update
;
struct
snd_soc_dapm_update
update
=
{
0
}
;
bool
change
;
mixer
=
mc
->
shift
>>
8
;
...
...
sound/soc/codecs/wm9713.c
View file @
c0f2302a
...
...
@@ -231,7 +231,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol,
struct
soc_mixer_control
*
mc
=
(
struct
soc_mixer_control
*
)
kcontrol
->
private_value
;
unsigned
int
mixer
,
mask
,
shift
,
old
;
struct
snd_soc_dapm_update
update
;
struct
snd_soc_dapm_update
update
=
{
0
}
;
bool
change
;
mixer
=
mc
->
shift
>>
8
;
...
...
sound/soc/soc-dapm.c
View file @
c0f2302a
...
...
@@ -330,6 +330,11 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
case
snd_soc_dapm_mixer_named_ctl
:
mc
=
(
struct
soc_mixer_control
*
)
kcontrol
->
private_value
;
if
(
mc
->
autodisable
&&
snd_soc_volsw_is_stereo
(
mc
))
dev_warn
(
widget
->
dapm
->
dev
,
"ASoC: Unsupported stereo autodisable control '%s'
\n
"
,
ctrl_name
);
if
(
mc
->
autodisable
)
{
struct
snd_soc_dapm_widget
template
;
...
...
@@ -723,7 +728,8 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
}
/* set up initial codec paths */
static
void
dapm_set_mixer_path_status
(
struct
snd_soc_dapm_path
*
p
,
int
i
)
static
void
dapm_set_mixer_path_status
(
struct
snd_soc_dapm_path
*
p
,
int
i
,
int
nth_path
)
{
struct
soc_mixer_control
*
mc
=
(
struct
soc_mixer_control
*
)
p
->
sink
->
kcontrol_news
[
i
].
private_value
;
...
...
@@ -736,7 +742,25 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i)
if
(
reg
!=
SND_SOC_NOPM
)
{
soc_dapm_read
(
p
->
sink
->
dapm
,
reg
,
&
val
);
val
=
(
val
>>
shift
)
&
mask
;
/*
* The nth_path argument allows this function to know
* which path of a kcontrol it is setting the initial
* status for. Ideally this would support any number
* of paths and channels. But since kcontrols only come
* in mono and stereo variants, we are limited to 2
* channels.
*
* The following code assumes for stereo controls the
* first path is the left channel, and all remaining
* paths are the right channel.
*/
if
(
snd_soc_volsw_is_stereo
(
mc
)
&&
nth_path
>
0
)
{
if
(
reg
!=
mc
->
rreg
)
soc_dapm_read
(
p
->
sink
->
dapm
,
mc
->
rreg
,
&
val
);
val
=
(
val
>>
mc
->
rshift
)
&
mask
;
}
else
{
val
=
(
val
>>
shift
)
&
mask
;
}
if
(
invert
)
val
=
max
-
val
;
p
->
connect
=
!!
val
;
...
...
@@ -749,13 +773,13 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i)
static
int
dapm_connect_mixer
(
struct
snd_soc_dapm_context
*
dapm
,
struct
snd_soc_dapm_path
*
path
,
const
char
*
control_name
)
{
int
i
;
int
i
,
nth_path
=
0
;
/* search for mixer kcontrol */
for
(
i
=
0
;
i
<
path
->
sink
->
num_kcontrols
;
i
++
)
{
if
(
!
strcmp
(
control_name
,
path
->
sink
->
kcontrol_news
[
i
].
name
))
{
path
->
name
=
path
->
sink
->
kcontrol_news
[
i
].
name
;
dapm_set_mixer_path_status
(
path
,
i
);
dapm_set_mixer_path_status
(
path
,
i
,
nth_path
++
);
return
0
;
}
}
...
...
@@ -1626,6 +1650,15 @@ static void dapm_widget_update(struct snd_soc_card *card)
dev_err
(
w
->
dapm
->
dev
,
"ASoC: %s DAPM update failed: %d
\n
"
,
w
->
name
,
ret
);
if
(
update
->
has_second_set
)
{
ret
=
soc_dapm_update_bits
(
w
->
dapm
,
update
->
reg2
,
update
->
mask2
,
update
->
val2
);
if
(
ret
<
0
)
dev_err
(
w
->
dapm
->
dev
,
"ASoC: %s DAPM update failed: %d
\n
"
,
w
->
name
,
ret
);
}
for
(
wi
=
0
;
wi
<
wlist
->
num_widgets
;
wi
++
)
{
w
=
wlist
->
widgets
[
wi
];
...
...
@@ -2177,7 +2210,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
/* test and update the power status of a mixer or switch widget */
static
int
soc_dapm_mixer_update_power
(
struct
snd_soc_card
*
card
,
struct
snd_kcontrol
*
kcontrol
,
int
connect
)
struct
snd_kcontrol
*
kcontrol
,
int
connect
,
int
rconnect
)
{
struct
snd_soc_dapm_path
*
path
;
int
found
=
0
;
...
...
@@ -2186,8 +2220,33 @@ static int soc_dapm_mixer_update_power(struct snd_soc_card *card,
/* find dapm widget path assoc with kcontrol */
dapm_kcontrol_for_each_path
(
path
,
kcontrol
)
{
/*
* Ideally this function should support any number of
* paths and channels. But since kcontrols only come
* in mono and stereo variants, we are limited to 2
* channels.
*
* The following code assumes for stereo controls the
* first path (when 'found == 0') is the left channel,
* and all remaining paths (when 'found == 1') are the
* right channel.
*
* A stereo control is signified by a valid 'rconnect'
* value, either 0 for unconnected, or >= 0 for connected.
* This is chosen instead of using snd_soc_volsw_is_stereo,
* so that the behavior of snd_soc_dapm_mixer_update_power
* doesn't change even when the kcontrol passed in is
* stereo.
*
* It passes 'connect' as the path connect status for
* the left channel, and 'rconnect' for the right
* channel.
*/
if
(
found
&&
rconnect
>=
0
)
soc_dapm_connect_path
(
path
,
rconnect
,
"mixer update"
);
else
soc_dapm_connect_path
(
path
,
connect
,
"mixer update"
);
found
=
1
;
soc_dapm_connect_path
(
path
,
connect
,
"mixer update"
);
}
if
(
found
)
...
...
@@ -2205,7 +2264,7 @@ int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
mutex_lock_nested
(
&
card
->
dapm_mutex
,
SND_SOC_DAPM_CLASS_RUNTIME
);
card
->
update
=
update
;
ret
=
soc_dapm_mixer_update_power
(
card
,
kcontrol
,
connect
);
ret
=
soc_dapm_mixer_update_power
(
card
,
kcontrol
,
connect
,
-
1
);
card
->
update
=
NULL
;
mutex_unlock
(
&
card
->
dapm_mutex
);
if
(
ret
>
0
)
...
...
@@ -3030,22 +3089,28 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
int
reg
=
mc
->
reg
;
unsigned
int
shift
=
mc
->
shift
;
int
max
=
mc
->
max
;
unsigned
int
width
=
fls
(
max
);
unsigned
int
mask
=
(
1
<<
fls
(
max
))
-
1
;
unsigned
int
invert
=
mc
->
invert
;
unsigned
int
val
;
unsigned
int
reg_val
,
val
,
rval
=
0
;
int
ret
=
0
;
if
(
snd_soc_volsw_is_stereo
(
mc
))
dev_warn
(
dapm
->
dev
,
"ASoC: Control '%s' is stereo, which is not supported
\n
"
,
kcontrol
->
id
.
name
);
mutex_lock_nested
(
&
card
->
dapm_mutex
,
SND_SOC_DAPM_CLASS_RUNTIME
);
if
(
dapm_kcontrol_is_powered
(
kcontrol
)
&&
reg
!=
SND_SOC_NOPM
)
{
ret
=
soc_dapm_read
(
dapm
,
reg
,
&
val
);
val
=
(
val
>>
shift
)
&
mask
;
ret
=
soc_dapm_read
(
dapm
,
reg
,
&
reg_val
);
val
=
(
reg_val
>>
shift
)
&
mask
;
if
(
ret
==
0
&&
reg
!=
mc
->
rreg
)
ret
=
soc_dapm_read
(
dapm
,
mc
->
rreg
,
&
reg_val
);
if
(
snd_soc_volsw_is_stereo
(
mc
))
rval
=
(
reg_val
>>
mc
->
rshift
)
&
mask
;
}
else
{
val
=
dapm_kcontrol_get_value
(
kcontrol
);
reg_val
=
dapm_kcontrol_get_value
(
kcontrol
);
val
=
reg_val
&
mask
;
if
(
snd_soc_volsw_is_stereo
(
mc
))
rval
=
(
reg_val
>>
width
)
&
mask
;
}
mutex_unlock
(
&
card
->
dapm_mutex
);
...
...
@@ -3057,6 +3122,13 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
else
ucontrol
->
value
.
integer
.
value
[
0
]
=
val
;
if
(
snd_soc_volsw_is_stereo
(
mc
))
{
if
(
invert
)
ucontrol
->
value
.
integer
.
value
[
1
]
=
max
-
rval
;
else
ucontrol
->
value
.
integer
.
value
[
1
]
=
rval
;
}
return
ret
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_dapm_get_volsw
);
...
...
@@ -3080,46 +3152,66 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
int
reg
=
mc
->
reg
;
unsigned
int
shift
=
mc
->
shift
;
int
max
=
mc
->
max
;
unsigned
int
mask
=
(
1
<<
fls
(
max
))
-
1
;
unsigned
int
width
=
fls
(
max
);
unsigned
int
mask
=
(
1
<<
width
)
-
1
;
unsigned
int
invert
=
mc
->
invert
;
unsigned
int
val
;
int
connect
,
change
,
reg_change
=
0
;
struct
snd_soc_dapm_update
update
;
unsigned
int
val
,
rval
=
0
;
int
connect
,
rconnect
=
-
1
,
change
,
reg_change
=
0
;
struct
snd_soc_dapm_update
update
=
{
NULL
}
;
int
ret
=
0
;
if
(
snd_soc_volsw_is_stereo
(
mc
))
dev_warn
(
dapm
->
dev
,
"ASoC: Control '%s' is stereo, which is not supported
\n
"
,
kcontrol
->
id
.
name
);
val
=
(
ucontrol
->
value
.
integer
.
value
[
0
]
&
mask
);
connect
=
!!
val
;
if
(
invert
)
val
=
max
-
val
;
if
(
snd_soc_volsw_is_stereo
(
mc
))
{
rval
=
(
ucontrol
->
value
.
integer
.
value
[
1
]
&
mask
);
rconnect
=
!!
rval
;
if
(
invert
)
rval
=
max
-
rval
;
}
mutex_lock_nested
(
&
card
->
dapm_mutex
,
SND_SOC_DAPM_CLASS_RUNTIME
);
change
=
dapm_kcontrol_set_value
(
kcontrol
,
val
);
/* This assumes field width < (bits in unsigned int / 2) */
if
(
width
>
sizeof
(
unsigned
int
)
*
8
/
2
)
dev_warn
(
dapm
->
dev
,
"ASoC: control %s field width limit exceeded
\n
"
,
kcontrol
->
id
.
name
);
change
=
dapm_kcontrol_set_value
(
kcontrol
,
val
|
(
rval
<<
width
));
if
(
reg
!=
SND_SOC_NOPM
)
{
mask
=
mask
<<
shift
;
val
=
val
<<
shift
;
rval
=
rval
<<
mc
->
rshift
;
reg_change
=
soc_dapm_test_bits
(
dapm
,
reg
,
mask
<<
shift
,
val
);
reg_change
=
soc_dapm_test_bits
(
dapm
,
reg
,
mask
,
val
);
if
(
snd_soc_volsw_is_stereo
(
mc
))
reg_change
|=
soc_dapm_test_bits
(
dapm
,
mc
->
rreg
,
mask
<<
mc
->
rshift
,
rval
);
}
if
(
change
||
reg_change
)
{
if
(
reg_change
)
{
if
(
snd_soc_volsw_is_stereo
(
mc
))
{
update
.
has_second_set
=
true
;
update
.
reg2
=
mc
->
rreg
;
update
.
mask2
=
mask
<<
mc
->
rshift
;
update
.
val2
=
rval
;
}
update
.
kcontrol
=
kcontrol
;
update
.
reg
=
reg
;
update
.
mask
=
mask
;
update
.
mask
=
mask
<<
shift
;
update
.
val
=
val
;
card
->
update
=
&
update
;
}
change
|=
reg_change
;
ret
=
soc_dapm_mixer_update_power
(
card
,
kcontrol
,
connect
);
ret
=
soc_dapm_mixer_update_power
(
card
,
kcontrol
,
connect
,
rconnect
);
card
->
update
=
NULL
;
}
...
...
@@ -3192,7 +3284,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
unsigned
int
*
item
=
ucontrol
->
value
.
enumerated
.
item
;
unsigned
int
val
,
change
,
reg_change
=
0
;
unsigned
int
mask
;
struct
snd_soc_dapm_update
update
;
struct
snd_soc_dapm_update
update
=
{
NULL
}
;
int
ret
=
0
;
if
(
item
[
0
]
>=
e
->
items
)
...
...
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