Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
ec6659c3
Commit
ec6659c3
authored
Mar 24, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/vmaster-update' into for-linus
parents
c944a93d
79c7cdd5
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
97 additions
and
21 deletions
+97
-21
Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl
Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl
+4
-0
include/sound/control.h
include/sound/control.h
+50
-2
sound/core/vmaster.c
sound/core/vmaster.c
+43
-19
No files found.
Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl
View file @
ec6659c3
...
...
@@ -71,6 +71,10 @@
!Esound/pci/ac97/ac97_codec.c
!Esound/pci/ac97/ac97_pcm.c
</sect1>
<sect1><title>
Virtual Master Control API
</title>
!Esound/core/vmaster.c
!Iinclude/sound/control.h
</sect1>
</chapter>
<chapter><title>
MIDI API
</title>
<sect1><title>
Raw MIDI API
</title>
...
...
include/sound/control.h
View file @
ec6659c3
...
...
@@ -171,6 +171,54 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
*/
struct
snd_kcontrol
*
snd_ctl_make_virtual_master
(
char
*
name
,
const
unsigned
int
*
tlv
);
int
snd_ctl_add_slave
(
struct
snd_kcontrol
*
master
,
struct
snd_kcontrol
*
slave
);
int
_snd_ctl_add_slave
(
struct
snd_kcontrol
*
master
,
struct
snd_kcontrol
*
slave
,
unsigned
int
flags
);
/* optional flags for slave */
#define SND_CTL_SLAVE_NEED_UPDATE (1 << 0)
/**
* snd_ctl_add_slave - Add a virtual slave control
* @master: vmaster element
* @slave: slave element to add
*
* Add a virtual slave control to the given master element created via
* snd_ctl_create_virtual_master() beforehand.
* Returns zero if successful or a negative error code.
*
* All slaves must be the same type (returning the same information
* via info callback). The fucntion doesn't check it, so it's your
* responsibility.
*
* Also, some additional limitations:
* at most two channels,
* logarithmic volume control (dB level) thus no linear volume,
* master can only attenuate the volume without gain
*/
static
inline
int
snd_ctl_add_slave
(
struct
snd_kcontrol
*
master
,
struct
snd_kcontrol
*
slave
)
{
return
_snd_ctl_add_slave
(
master
,
slave
,
0
);
}
/**
* snd_ctl_add_slave_uncached - Add a virtual slave control
* @master: vmaster element
* @slave: slave element to add
*
* Add a virtual slave control to the given master.
* Unlike snd_ctl_add_slave(), the element added via this function
* is supposed to have volatile values, and get callback is called
* at each time quried from the master.
*
* When the control peeks the hardware values directly and the value
* can be changed by other means than the put callback of the element,
* this function should be used to keep the value always up-to-date.
*/
static
inline
int
snd_ctl_add_slave_uncached
(
struct
snd_kcontrol
*
master
,
struct
snd_kcontrol
*
slave
)
{
return
_snd_ctl_add_slave
(
master
,
slave
,
SND_CTL_SLAVE_NEED_UPDATE
);
}
#endif
/* __SOUND_CONTROL_H */
sound/core/vmaster.c
View file @
ec6659c3
...
...
@@ -50,18 +50,38 @@ struct link_slave {
struct
link_master
*
master
;
struct
link_ctl_info
info
;
int
vals
[
2
];
/* current values */
unsigned
int
flags
;
struct
snd_kcontrol
slave
;
/* the copy of original control entry */
};
static
int
slave_update
(
struct
link_slave
*
slave
)
{
struct
snd_ctl_elem_value
*
uctl
;
int
err
,
ch
;
uctl
=
kmalloc
(
sizeof
(
*
uctl
),
GFP_KERNEL
);
if
(
!
uctl
)
return
-
ENOMEM
;
uctl
->
id
=
slave
->
slave
.
id
;
err
=
slave
->
slave
.
get
(
&
slave
->
slave
,
uctl
);
for
(
ch
=
0
;
ch
<
slave
->
info
.
count
;
ch
++
)
slave
->
vals
[
ch
]
=
uctl
->
value
.
integer
.
value
[
ch
];
kfree
(
uctl
);
return
0
;
}
/* get the slave ctl info and save the initial values */
static
int
slave_init
(
struct
link_slave
*
slave
)
{
struct
snd_ctl_elem_info
*
uinfo
;
struct
snd_ctl_elem_value
*
uctl
;
int
err
,
ch
;
int
err
;
if
(
slave
->
info
.
count
)
return
0
;
/* already initialized */
if
(
slave
->
info
.
count
)
{
/* already initialized */
if
(
slave
->
flags
&
SND_CTL_SLAVE_NEED_UPDATE
)
return
slave_update
(
slave
);
return
0
;
}
uinfo
=
kmalloc
(
sizeof
(
*
uinfo
),
GFP_KERNEL
);
if
(
!
uinfo
)
...
...
@@ -85,15 +105,7 @@ static int slave_init(struct link_slave *slave)
slave
->
info
.
max_val
=
uinfo
->
value
.
integer
.
max
;
kfree
(
uinfo
);
uctl
=
kmalloc
(
sizeof
(
*
uctl
),
GFP_KERNEL
);
if
(
!
uctl
)
return
-
ENOMEM
;
uctl
->
id
=
slave
->
slave
.
id
;
err
=
slave
->
slave
.
get
(
&
slave
->
slave
,
uctl
);
for
(
ch
=
0
;
ch
<
slave
->
info
.
count
;
ch
++
)
slave
->
vals
[
ch
]
=
uctl
->
value
.
integer
.
value
[
ch
];
kfree
(
uctl
);
return
0
;
return
slave_update
(
slave
);
}
/* initialize master volume */
...
...
@@ -229,7 +241,8 @@ static void slave_free(struct snd_kcontrol *kcontrol)
* - logarithmic volume control (dB level), no linear volume
* - master can only attenuate the volume, no gain
*/
int
snd_ctl_add_slave
(
struct
snd_kcontrol
*
master
,
struct
snd_kcontrol
*
slave
)
int
_snd_ctl_add_slave
(
struct
snd_kcontrol
*
master
,
struct
snd_kcontrol
*
slave
,
unsigned
int
flags
)
{
struct
link_master
*
master_link
=
snd_kcontrol_chip
(
master
);
struct
link_slave
*
srec
;
...
...
@@ -241,6 +254,7 @@ int snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave)
srec
->
slave
=
*
slave
;
memcpy
(
srec
->
slave
.
vd
,
slave
->
vd
,
slave
->
count
*
sizeof
(
*
slave
->
vd
));
srec
->
master
=
master_link
;
srec
->
flags
=
flags
;
/* override callbacks */
slave
->
info
=
slave_info
;
...
...
@@ -254,8 +268,7 @@ int snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave)
list_add_tail
(
&
srec
->
list
,
&
master_link
->
slaves
);
return
0
;
}
EXPORT_SYMBOL
(
snd_ctl_add_slave
);
EXPORT_SYMBOL
(
_snd_ctl_add_slave
);
/*
* ctl callbacks for master controls
...
...
@@ -327,8 +340,20 @@ static void master_free(struct snd_kcontrol *kcontrol)
}
/*
* Create a virtual master control with the given name
/**
* snd_ctl_make_virtual_master - Create a virtual master control
* @name: name string of the control element to create
* @tlv: optional TLV int array for dB information
*
* Creates a virtual matster control with the given name string.
* Returns the created control element, or NULL for errors (ENOMEM).
*
* After creating a vmaster element, you can add the slave controls
* via snd_ctl_add_slave() or snd_ctl_add_slave_uncached().
*
* The optional argument @tlv can be used to specify the TLV information
* for dB scale of the master control. It should be a single element
* with #SNDRV_CTL_TLVT_DB_SCALE type, and should be the max 0dB.
*/
struct
snd_kcontrol
*
snd_ctl_make_virtual_master
(
char
*
name
,
const
unsigned
int
*
tlv
)
...
...
@@ -367,5 +392,4 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
return
kctl
;
}
EXPORT_SYMBOL
(
snd_ctl_make_virtual_master
);
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