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
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