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
da8ab21c
Commit
da8ab21c
authored
Mar 12, 2014
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/core' into asoc-next
parents
c6c12422
5c1d5f09
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
275 additions
and
261 deletions
+275
-261
drivers/base/regmap/regmap.c
drivers/base/regmap/regmap.c
+12
-0
include/linux/regmap.h
include/linux/regmap.h
+9
-0
include/sound/soc-dai.h
include/sound/soc-dai.h
+1
-0
include/sound/soc.h
include/sound/soc.h
+22
-2
sound/soc/codecs/adav80x.c
sound/soc/codecs/adav80x.c
+2
-2
sound/soc/codecs/tlv320aic23.c
sound/soc/codecs/tlv320aic23.c
+1
-1
sound/soc/codecs/tlv320dac33.c
sound/soc/codecs/tlv320dac33.c
+1
-1
sound/soc/codecs/uda1380.c
sound/soc/codecs/uda1380.c
+1
-1
sound/soc/codecs/wl1273.c
sound/soc/codecs/wl1273.c
+1
-1
sound/soc/codecs/wm8711.c
sound/soc/codecs/wm8711.c
+1
-1
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8753.c
+2
-2
sound/soc/soc-cache.c
sound/soc/soc-cache.c
+7
-6
sound/soc/soc-compress.c
sound/soc/soc-compress.c
+13
-52
sound/soc/soc-core.c
sound/soc/soc-core.c
+117
-168
sound/soc/soc-pcm.c
sound/soc/soc-pcm.c
+85
-24
No files found.
drivers/base/regmap/regmap.c
View file @
da8ab21c
...
...
@@ -2240,6 +2240,18 @@ int regmap_get_val_bytes(struct regmap *map)
}
EXPORT_SYMBOL_GPL
(
regmap_get_val_bytes
);
int
regmap_parse_val
(
struct
regmap
*
map
,
const
void
*
buf
,
unsigned
int
*
val
)
{
if
(
!
map
->
format
.
parse_val
)
return
-
EINVAL
;
*
val
=
map
->
format
.
parse_val
(
buf
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
regmap_parse_val
);
static
int
__init
regmap_initcall
(
void
)
{
regmap_debugfs_initcall
();
...
...
include/linux/regmap.h
View file @
da8ab21c
...
...
@@ -423,6 +423,8 @@ bool regmap_check_range_table(struct regmap *map, unsigned int reg,
int
regmap_register_patch
(
struct
regmap
*
map
,
const
struct
reg_default
*
regs
,
int
num_regs
);
int
regmap_parse_val
(
struct
regmap
*
map
,
const
void
*
buf
,
unsigned
int
*
val
);
static
inline
bool
regmap_reg_in_range
(
unsigned
int
reg
,
const
struct
regmap_range
*
range
)
...
...
@@ -695,6 +697,13 @@ static inline int regmap_register_patch(struct regmap *map,
return
-
EINVAL
;
}
static
inline
int
regmap_parse_val
(
struct
regmap
*
map
,
const
void
*
buf
,
unsigned
int
*
val
)
{
WARN_ONCE
(
1
,
"regmap API is disabled"
);
return
-
EINVAL
;
}
static
inline
struct
regmap
*
dev_get_regmap
(
struct
device
*
dev
,
const
char
*
name
)
{
...
...
include/sound/soc-dai.h
View file @
da8ab21c
...
...
@@ -270,6 +270,7 @@ struct snd_soc_dai {
/* parent platform/codec */
struct
snd_soc_platform
*
platform
;
struct
snd_soc_codec
*
codec
;
struct
snd_soc_component
*
component
;
struct
snd_soc_card
*
card
;
...
...
include/sound/soc.h
View file @
da8ab21c
...
...
@@ -413,6 +413,10 @@ struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
struct
snd_soc_pcm_runtime
*
snd_soc_get_pcm_runtime
(
struct
snd_soc_card
*
card
,
const
char
*
dai_link
);
bool
snd_soc_runtime_ignore_pmdown_time
(
struct
snd_soc_pcm_runtime
*
rtd
);
void
snd_soc_runtime_activate
(
struct
snd_soc_pcm_runtime
*
rtd
,
int
stream
);
void
snd_soc_runtime_deactivate
(
struct
snd_soc_pcm_runtime
*
rtd
,
int
stream
);
/* Utility functions to get clock rates from various things */
int
snd_soc_calc_frame_size
(
int
sample_size
,
int
channels
,
int
tdm_slots
);
int
snd_soc_params_to_frame_size
(
struct
snd_pcm_hw_params
*
params
);
...
...
@@ -656,12 +660,19 @@ struct snd_soc_component {
const
char
*
name
;
int
id
;
struct
device
*
dev
;
unsigned
int
active
;
unsigned
int
ignore_pmdown_time
:
1
;
/* pmdown_time is ignored at stop */
struct
list_head
list
;
struct
snd_soc_dai_driver
*
dai_drv
;
int
num_dai
;
const
struct
snd_soc_component_driver
*
driver
;
struct
list_head
dai_list
;
};
/* SoC Audio Codec device */
...
...
@@ -683,7 +694,6 @@ struct snd_soc_codec {
/* runtime */
struct
snd_ac97
*
ac97
;
/* for ad-hoc ac97 devices */
unsigned
int
active
;
unsigned
int
cache_bypass
:
1
;
/* Suppress access to the cache */
unsigned
int
suspended
:
1
;
/* Codec is in suspend PM state */
unsigned
int
probed
:
1
;
/* Codec has been probed */
...
...
@@ -709,7 +719,6 @@ struct snd_soc_codec {
/* dapm */
struct
snd_soc_dapm_context
dapm
;
unsigned
int
ignore_pmdown_time
:
1
;
/* pmdown_time is ignored at stop */
#ifdef CONFIG_DEBUG_FS
struct
dentry
*
debugfs_codec_root
;
...
...
@@ -1168,6 +1177,17 @@ static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
return
1
;
}
static
inline
bool
snd_soc_component_is_active
(
struct
snd_soc_component
*
component
)
{
return
component
->
active
!=
0
;
}
static
inline
bool
snd_soc_codec_is_active
(
struct
snd_soc_codec
*
codec
)
{
return
snd_soc_component_is_active
(
&
codec
->
component
);
}
int
snd_soc_util_init
(
void
);
void
snd_soc_util_exit
(
void
);
...
...
sound/soc/codecs/adav80x.c
View file @
da8ab21c
...
...
@@ -722,7 +722,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream,
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
struct
adav80x
*
adav80x
=
snd_soc_codec_get_drvdata
(
codec
);
if
(
!
codec
->
active
||
!
adav80x
->
rate
)
if
(
!
snd_soc_codec_is_active
(
codec
)
||
!
adav80x
->
rate
)
return
0
;
return
snd_pcm_hw_constraint_minmax
(
substream
->
runtime
,
...
...
@@ -735,7 +735,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
struct
adav80x
*
adav80x
=
snd_soc_codec_get_drvdata
(
codec
);
if
(
!
codec
->
active
)
if
(
!
snd_soc_codec_is_active
(
codec
)
)
adav80x
->
rate
=
0
;
}
...
...
sound/soc/codecs/tlv320aic23.c
View file @
da8ab21c
...
...
@@ -400,7 +400,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
struct
aic23
*
aic23
=
snd_soc_codec_get_drvdata
(
codec
);
/* deactivate */
if
(
!
codec
->
active
)
{
if
(
!
snd_soc_codec_is_active
(
codec
)
)
{
udelay
(
50
);
snd_soc_write
(
codec
,
TLV320AIC23_ACTIVE
,
0x0
);
}
...
...
sound/soc/codecs/tlv320dac33.c
View file @
da8ab21c
...
...
@@ -461,7 +461,7 @@ static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
if
(
dac33
->
fifo_mode
==
ucontrol
->
value
.
integer
.
value
[
0
])
return
0
;
/* Do not allow changes while stream is running*/
if
(
codec
->
active
)
if
(
snd_soc_codec_is_active
(
codec
)
)
return
-
EPERM
;
if
(
ucontrol
->
value
.
integer
.
value
[
0
]
<
0
||
...
...
sound/soc/codecs/uda1380.c
View file @
da8ab21c
...
...
@@ -108,7 +108,7 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
/* the interpolator & decimator regs must only be written when the
* codec DAI is active.
*/
if
(
!
codec
->
active
&&
(
reg
>=
UDA1380_MVOL
))
if
(
!
snd_soc_codec_is_active
(
codec
)
&&
(
reg
>=
UDA1380_MVOL
))
return
0
;
pr_debug
(
"uda1380: hw write %x val %x
\n
"
,
reg
,
value
);
if
(
codec
->
hw_write
(
codec
->
control_data
,
data
,
3
)
==
3
)
{
...
...
sound/soc/codecs/wl1273.c
View file @
da8ab21c
...
...
@@ -197,7 +197,7 @@ static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
return
0
;
/* Do not allow changes while stream is running */
if
(
codec
->
active
)
if
(
snd_soc_codec_is_active
(
codec
)
)
return
-
EPERM
;
if
(
ucontrol
->
value
.
integer
.
value
[
0
]
<
0
||
...
...
sound/soc/codecs/wm8711.c
View file @
da8ab21c
...
...
@@ -201,7 +201,7 @@ static void wm8711_shutdown(struct snd_pcm_substream *substream,
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
/* deactivate */
if
(
!
codec
->
active
)
{
if
(
!
snd_soc_codec_is_active
(
codec
)
)
{
udelay
(
50
);
snd_soc_write
(
codec
,
WM8711_ACTIVE
,
0x0
);
}
...
...
sound/soc/codecs/wm8753.c
View file @
da8ab21c
...
...
@@ -251,7 +251,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
if
(
wm8753
->
dai_func
==
ucontrol
->
value
.
integer
.
value
[
0
])
return
0
;
if
(
codec
->
active
)
if
(
snd_soc_codec_is_active
(
codec
)
)
return
-
EBUSY
;
ioctl
=
snd_soc_read
(
codec
,
WM8753_IOCTL
);
...
...
@@ -1314,7 +1314,7 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
/* the digital mute covers the HiFi and Voice DAC's on the WM8753.
* make sure we check if they are not both active when we mute */
if
(
mute
&&
wm8753
->
dai_func
==
1
)
{
if
(
!
codec
->
active
)
if
(
!
snd_soc_codec_is_active
(
codec
)
)
snd_soc_write
(
codec
,
WM8753_DAC
,
mute_reg
|
0x8
);
}
else
{
if
(
mute
)
...
...
sound/soc/soc-cache.c
View file @
da8ab21c
...
...
@@ -96,8 +96,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec)
{
dev_dbg
(
codec
->
dev
,
"ASoC: Destroying cache for %s codec
\n
"
,
codec
->
name
);
if
(
!
codec
->
reg_cache
)
return
0
;
kfree
(
codec
->
reg_cache
);
codec
->
reg_cache
=
NULL
;
return
0
;
...
...
@@ -117,8 +116,9 @@ int snd_soc_cache_read(struct snd_soc_codec *codec,
return
-
EINVAL
;
mutex_lock
(
&
codec
->
cache_rw_mutex
);
*
value
=
snd_soc_get_cache_val
(
codec
->
reg_cache
,
reg
,
codec
->
driver
->
reg_word_size
);
if
(
!
ZERO_OR_NULL_PTR
(
codec
->
reg_cache
))
*
value
=
snd_soc_get_cache_val
(
codec
->
reg_cache
,
reg
,
codec
->
driver
->
reg_word_size
);
mutex_unlock
(
&
codec
->
cache_rw_mutex
);
return
0
;
...
...
@@ -136,8 +136,9 @@ int snd_soc_cache_write(struct snd_soc_codec *codec,
unsigned
int
reg
,
unsigned
int
value
)
{
mutex_lock
(
&
codec
->
cache_rw_mutex
);
snd_soc_set_cache_val
(
codec
->
reg_cache
,
reg
,
value
,
codec
->
driver
->
reg_word_size
);
if
(
!
ZERO_OR_NULL_PTR
(
codec
->
reg_cache
))
snd_soc_set_cache_val
(
codec
->
reg_cache
,
reg
,
value
,
codec
->
driver
->
reg_word_size
);
mutex_unlock
(
&
codec
->
cache_rw_mutex
);
return
0
;
...
...
sound/soc/soc-compress.c
View file @
da8ab21c
...
...
@@ -30,8 +30,6 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
{
struct
snd_soc_pcm_runtime
*
rtd
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
=
0
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
...
...
@@ -52,17 +50,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
}
}
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
{
cpu_dai
->
playback_active
++
;
codec_dai
->
playback_active
++
;
}
else
{
cpu_dai
->
capture_active
++
;
codec_dai
->
capture_active
++
;
}
cpu_dai
->
active
++
;
codec_dai
->
active
++
;
rtd
->
codec
->
active
++
;
snd_soc_runtime_activate
(
rtd
,
cstream
->
direction
);
mutex_unlock
(
&
rtd
->
pcm_mutex
);
...
...
@@ -81,8 +69,6 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
struct
snd_soc_pcm_runtime
*
fe
=
cstream
->
private_data
;
struct
snd_pcm_substream
*
fe_substream
=
fe
->
pcm
->
streams
[
0
].
substream
;
struct
snd_soc_platform
*
platform
=
fe
->
platform
;
struct
snd_soc_dai
*
cpu_dai
=
fe
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
=
fe
->
codec_dai
;
struct
snd_soc_dpcm
*
dpcm
;
struct
snd_soc_dapm_widget_list
*
list
;
int
stream
;
...
...
@@ -140,17 +126,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
fe
->
dpcm
[
stream
].
state
=
SND_SOC_DPCM_STATE_OPEN
;
fe
->
dpcm
[
stream
].
runtime_update
=
SND_SOC_DPCM_UPDATE_NO
;
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
{
cpu_dai
->
playback_active
++
;
codec_dai
->
playback_active
++
;
}
else
{
cpu_dai
->
capture_active
++
;
codec_dai
->
capture_active
++
;
}
cpu_dai
->
active
++
;
codec_dai
->
active
++
;
fe
->
codec
->
active
++
;
snd_soc_runtime_activate
(
fe
,
stream
);
mutex_unlock
(
&
fe
->
card
->
mutex
);
...
...
@@ -202,23 +178,18 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
int
stream
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
{
cpu_dai
->
playback_active
--
;
codec_dai
->
playback_active
--
;
}
else
{
cpu_dai
->
capture_active
--
;
codec_dai
->
capture_active
--
;
}
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
stream
=
SNDRV_PCM_STREAM_PLAYBACK
;
else
stream
=
SNDRV_PCM_STREAM_CAPTURE
;
snd_soc_
dai_digital_mute
(
codec_dai
,
1
,
cstream
->
direction
);
snd_soc_
runtime_deactivate
(
rtd
,
stream
);
cpu_dai
->
active
--
;
codec_dai
->
active
--
;
codec
->
active
--
;
snd_soc_dai_digital_mute
(
codec_dai
,
1
,
cstream
->
direction
);
if
(
!
cpu_dai
->
active
)
cpu_dai
->
rate
=
0
;
...
...
@@ -235,8 +206,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
cpu_dai
->
runtime
=
NULL
;
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
{
if
(
!
rtd
->
pmdown_time
||
codec
->
ignore_pmdown_time
||
rtd
->
dai_link
->
ignore_pmdown_time
)
{
if
(
snd_soc_runtime_ignore_pmdown_time
(
rtd
))
{
snd_soc_dapm_stream_event
(
rtd
,
SNDRV_PCM_STREAM_PLAYBACK
,
SND_SOC_DAPM_STREAM_STOP
);
...
...
@@ -261,26 +231,17 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
{
struct
snd_soc_pcm_runtime
*
fe
=
cstream
->
private_data
;
struct
snd_soc_platform
*
platform
=
fe
->
platform
;
struct
snd_soc_dai
*
cpu_dai
=
fe
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
=
fe
->
codec_dai
;
struct
snd_soc_dpcm
*
dpcm
;
int
stream
,
ret
;
mutex_lock_nested
(
&
fe
->
card
->
mutex
,
SND_SOC_CARD_CLASS_RUNTIME
);
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
{
if
(
cstream
->
direction
==
SND_COMPRESS_PLAYBACK
)
stream
=
SNDRV_PCM_STREAM_PLAYBACK
;
cpu_dai
->
playback_active
--
;
codec_dai
->
playback_active
--
;
}
else
{
else
stream
=
SNDRV_PCM_STREAM_CAPTURE
;
cpu_dai
->
capture_active
--
;
codec_dai
->
capture_active
--
;
}
cpu_dai
->
active
--
;
codec_dai
->
active
--
;
fe
->
codec
->
active
--
;
snd_soc_runtime_deactivate
(
fe
,
stream
);
fe
->
dpcm
[
stream
].
runtime_update
=
SND_SOC_DPCM_UPDATE_FE
;
...
...
sound/soc/soc-core.c
View file @
da8ab21c
...
...
@@ -56,7 +56,6 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
#endif
static
DEFINE_MUTEX
(
client_mutex
);
static
LIST_HEAD
(
dai_list
);
static
LIST_HEAD
(
platform_list
);
static
LIST_HEAD
(
codec_list
);
static
LIST_HEAD
(
component_list
);
...
...
@@ -370,18 +369,22 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf,
{
char
*
buf
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
ssize_t
len
,
ret
=
0
;
struct
snd_soc_component
*
component
;
struct
snd_soc_dai
*
dai
;
if
(
!
buf
)
return
-
ENOMEM
;
list_for_each_entry
(
dai
,
&
dai_list
,
list
)
{
len
=
snprintf
(
buf
+
ret
,
PAGE_SIZE
-
ret
,
"%s
\n
"
,
dai
->
name
);
if
(
len
>=
0
)
ret
+=
len
;
if
(
ret
>
PAGE_SIZE
)
{
ret
=
PAGE_SIZE
;
break
;
list_for_each_entry
(
component
,
&
component_list
,
list
)
{
list_for_each_entry
(
dai
,
&
component
->
dai_list
,
list
)
{
len
=
snprintf
(
buf
+
ret
,
PAGE_SIZE
-
ret
,
"%s
\n
"
,
dai
->
name
);
if
(
len
>=
0
)
ret
+=
len
;
if
(
ret
>
PAGE_SIZE
)
{
ret
=
PAGE_SIZE
;
break
;
}
}
}
...
...
@@ -855,6 +858,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
{
struct
snd_soc_dai_link
*
dai_link
=
&
card
->
dai_link
[
num
];
struct
snd_soc_pcm_runtime
*
rtd
=
&
card
->
rtd
[
num
];
struct
snd_soc_component
*
component
;
struct
snd_soc_codec
*
codec
;
struct
snd_soc_platform
*
platform
;
struct
snd_soc_dai
*
codec_dai
,
*
cpu_dai
;
...
...
@@ -863,18 +867,20 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
dev_dbg
(
card
->
dev
,
"ASoC: binding %s at idx %d
\n
"
,
dai_link
->
name
,
num
);
/* Find CPU DAI from registered DAIs*/
list_for_each_entry
(
c
pu_dai
,
&
dai
_list
,
list
)
{
list_for_each_entry
(
c
omponent
,
&
component
_list
,
list
)
{
if
(
dai_link
->
cpu_of_node
&&
(
cpu_dai
->
dev
->
of_node
!=
dai_link
->
cpu_of_node
)
)
component
->
dev
->
of_node
!=
dai_link
->
cpu_of_node
)
continue
;
if
(
dai_link
->
cpu_name
&&
strcmp
(
dev_name
(
cpu_dai
->
dev
),
dai_link
->
cpu_name
))
continue
;
if
(
dai_link
->
cpu_dai_name
&&
strcmp
(
cpu_dai
->
name
,
dai_link
->
cpu_dai_name
))
strcmp
(
dev_name
(
component
->
dev
),
dai_link
->
cpu_name
))
continue
;
list_for_each_entry
(
cpu_dai
,
&
component
->
dai_list
,
list
)
{
if
(
dai_link
->
cpu_dai_name
&&
strcmp
(
cpu_dai
->
name
,
dai_link
->
cpu_dai_name
))
continue
;
rtd
->
cpu_dai
=
cpu_dai
;
rtd
->
cpu_dai
=
cpu_dai
;
}
}
if
(
!
rtd
->
cpu_dai
)
{
...
...
@@ -899,12 +905,10 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
* CODEC found, so find CODEC DAI from registered DAIs from
* this CODEC
*/
list_for_each_entry
(
codec_dai
,
&
dai_list
,
list
)
{
if
(
codec
->
dev
==
codec_dai
->
dev
&&
!
strcmp
(
codec_dai
->
name
,
dai_link
->
codec_dai_name
))
{
list_for_each_entry
(
codec_dai
,
&
codec
->
component
.
dai_list
,
list
)
{
if
(
!
strcmp
(
codec_dai
->
name
,
dai_link
->
codec_dai_name
))
{
rtd
->
codec_dai
=
codec_dai
;
break
;
}
}
...
...
@@ -1128,12 +1132,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
driver
->
num_dapm_widgets
);
/* Create DAPM widgets for each DAI stream */
list_for_each_entry
(
dai
,
&
dai_list
,
list
)
{
if
(
dai
->
dev
!=
codec
->
dev
)
continue
;
list_for_each_entry
(
dai
,
&
codec
->
component
.
dai_list
,
list
)
snd_soc_dapm_new_dai_widgets
(
&
codec
->
dapm
,
dai
);
}
codec
->
dapm
.
idle_bias_off
=
driver
->
idle_bias_off
;
...
...
@@ -1180,6 +1180,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
{
int
ret
=
0
;
const
struct
snd_soc_platform_driver
*
driver
=
platform
->
driver
;
struct
snd_soc_component
*
component
;
struct
snd_soc_dai
*
dai
;
platform
->
card
=
card
;
...
...
@@ -1195,11 +1196,11 @@ static int soc_probe_platform(struct snd_soc_card *card,
driver
->
dapm_widgets
,
driver
->
num_dapm_widgets
);
/* Create DAPM widgets for each DAI stream */
list_for_each_entry
(
dai
,
&
dai
_list
,
list
)
{
if
(
dai
->
dev
!=
platform
->
dev
)
list_for_each_entry
(
component
,
&
component
_list
,
list
)
{
if
(
component
->
dev
!=
platform
->
dev
)
continue
;
snd_soc_dapm_new_dai_widgets
(
&
platform
->
dapm
,
dai
);
list_for_each_entry
(
dai
,
&
component
->
dai_list
,
list
)
snd_soc_dapm_new_dai_widgets
(
&
platform
->
dapm
,
dai
);
}
platform
->
dapm
.
idle_bias_off
=
1
;
...
...
@@ -2818,7 +2819,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
unsigned
int
mask
=
(
1
<<
fls
(
max
))
-
1
;
unsigned
int
invert
=
mc
->
invert
;
int
err
;
bool
type_2r
=
0
;
bool
type_2r
=
false
;
unsigned
int
val2
=
0
;
unsigned
int
val
,
val_mask
;
...
...
@@ -2836,7 +2837,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
val
|=
val2
<<
rshift
;
}
else
{
val2
=
val2
<<
shift
;
type_2r
=
1
;
type_2r
=
true
;
}
}
err
=
snd_soc_update_bits_locked
(
codec
,
reg
,
val_mask
,
val
);
...
...
@@ -3234,7 +3235,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
struct
soc_bytes
*
params
=
(
void
*
)
kcontrol
->
private_value
;
struct
snd_soc_codec
*
codec
=
snd_kcontrol_chip
(
kcontrol
);
int
ret
,
len
;
unsigned
int
val
;
unsigned
int
val
,
mask
;
void
*
data
;
if
(
!
codec
->
using_regmap
)
...
...
@@ -3264,12 +3265,36 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
((
u8
*
)
data
)[
0
]
|=
val
;
break
;
case
2
:
((
u16
*
)
data
)[
0
]
&=
cpu_to_be16
(
~
params
->
mask
);
((
u16
*
)
data
)[
0
]
|=
cpu_to_be16
(
val
);
mask
=
~
params
->
mask
;
ret
=
regmap_parse_val
(
codec
->
control_data
,
&
mask
,
&
mask
);
if
(
ret
!=
0
)
goto
out
;
((
u16
*
)
data
)[
0
]
&=
mask
;
ret
=
regmap_parse_val
(
codec
->
control_data
,
&
val
,
&
val
);
if
(
ret
!=
0
)
goto
out
;
((
u16
*
)
data
)[
0
]
|=
val
;
break
;
case
4
:
((
u32
*
)
data
)[
0
]
&=
cpu_to_be32
(
~
params
->
mask
);
((
u32
*
)
data
)[
0
]
|=
cpu_to_be32
(
val
);
mask
=
~
params
->
mask
;
ret
=
regmap_parse_val
(
codec
->
control_data
,
&
mask
,
&
mask
);
if
(
ret
!=
0
)
goto
out
;
((
u32
*
)
data
)[
0
]
&=
mask
;
ret
=
regmap_parse_val
(
codec
->
control_data
,
&
val
,
&
val
);
if
(
ret
!=
0
)
goto
out
;
((
u32
*
)
data
)[
0
]
|=
val
;
break
;
default:
ret
=
-
EINVAL
;
...
...
@@ -3626,7 +3651,7 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
return
dai
->
driver
->
ops
->
set_tdm_slot
(
dai
,
tx_mask
,
rx_mask
,
slots
,
slot_width
);
else
return
-
E
INVAL
;
return
-
E
NOTSUPP
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_dai_set_tdm_slot
);
...
...
@@ -3882,95 +3907,42 @@ static inline char *fmt_multiple_name(struct device *dev,
}
/**
* snd_soc_
register_dai - Register a DAI with
the ASoC core
* snd_soc_
unregister_dai - Unregister DAIs from
the ASoC core
*
* @
dai: DAI to register
* @
component: The component for which the DAIs should be unregistered
*/
static
int
snd_soc_register_dai
(
struct
device
*
dev
,
struct
snd_soc_dai_driver
*
dai_drv
)
static
void
snd_soc_unregister_dais
(
struct
snd_soc_component
*
component
)
{
struct
snd_soc_codec
*
codec
;
struct
snd_soc_dai
*
dai
;
dev_dbg
(
dev
,
"ASoC: dai register %s
\n
"
,
dev_name
(
dev
));
struct
snd_soc_dai
*
dai
,
*
_dai
;
dai
=
kzalloc
(
sizeof
(
struct
snd_soc_dai
),
GFP_KERNEL
);
if
(
dai
==
NULL
)
return
-
ENOMEM
;
/* create DAI component name */
dai
->
name
=
fmt_single_name
(
dev
,
&
dai
->
id
);
if
(
dai
->
name
==
NULL
)
{
list_for_each_entry_safe
(
dai
,
_dai
,
&
component
->
dai_list
,
list
)
{
dev_dbg
(
component
->
dev
,
"ASoC: Unregistered DAI '%s'
\n
"
,
dai
->
name
);
list_del
(
&
dai
->
list
);
kfree
(
dai
->
name
);
kfree
(
dai
);
return
-
ENOMEM
;
}
dai
->
dev
=
dev
;
dai
->
driver
=
dai_drv
;
dai
->
dapm
.
dev
=
dev
;
if
(
!
dai
->
driver
->
ops
)
dai
->
driver
->
ops
=
&
null_dai_ops
;
mutex_lock
(
&
client_mutex
);
list_for_each_entry
(
codec
,
&
codec_list
,
list
)
{
if
(
codec
->
dev
==
dev
)
{
dev_dbg
(
dev
,
"ASoC: Mapped DAI %s to CODEC %s
\n
"
,
dai
->
name
,
codec
->
name
);
dai
->
codec
=
codec
;
break
;
}
}
if
(
!
dai
->
codec
)
dai
->
dapm
.
idle_bias_off
=
1
;
list_add
(
&
dai
->
list
,
&
dai_list
);
mutex_unlock
(
&
client_mutex
);
dev_dbg
(
dev
,
"ASoC: Registered DAI '%s'
\n
"
,
dai
->
name
);
return
0
;
}
/**
* snd_soc_unregister_dai - Unregister a DAI from the ASoC core
*
* @dai: DAI to unregister
*/
static
void
snd_soc_unregister_dai
(
struct
device
*
dev
)
{
struct
snd_soc_dai
*
dai
;
list_for_each_entry
(
dai
,
&
dai_list
,
list
)
{
if
(
dev
==
dai
->
dev
)
goto
found
;
}
return
;
found:
mutex_lock
(
&
client_mutex
);
list_del
(
&
dai
->
list
);
mutex_unlock
(
&
client_mutex
);
dev_dbg
(
dev
,
"ASoC: Unregistered DAI '%s'
\n
"
,
dai
->
name
);
kfree
(
dai
->
name
);
kfree
(
dai
);
}
/**
* snd_soc_register_dais - Register
multiple DAIs
with the ASoC core
* snd_soc_register_dais - Register
a DAI
with the ASoC core
*
* @dai: Array of DAIs to register
* @component: The component the DAIs are registered for
* @codec: The CODEC that the DAIs are registered for, NULL if the component is
* not a CODEC.
* @dai_drv: DAI driver to use for the DAIs
* @count: Number of DAIs
* @legacy_dai_naming: Use the legacy naming scheme and let the DAI inherit the
* parent's name.
*/
static
int
snd_soc_register_dais
(
struct
device
*
dev
,
struct
snd_soc_dai_driver
*
dai_drv
,
size_t
count
)
static
int
snd_soc_register_dais
(
struct
snd_soc_component
*
component
,
struct
snd_soc_codec
*
codec
,
struct
snd_soc_dai_driver
*
dai_drv
,
size_t
count
,
bool
legacy_dai_naming
)
{
struct
snd_soc_codec
*
codec
;
struct
device
*
dev
=
component
->
dev
;
struct
snd_soc_dai
*
dai
;
int
i
,
ret
=
0
;
unsigned
int
i
;
int
ret
;
dev_dbg
(
dev
,
"ASoC: dai register %s #%Zu
\n
"
,
dev_name
(
dev
),
count
);
...
...
@@ -3982,69 +3954,53 @@ static int snd_soc_register_dais(struct device *dev,
goto
err
;
}
/* create DAI component name */
dai
->
name
=
fmt_multiple_name
(
dev
,
&
dai_drv
[
i
]);
/*
* Back in the old days when we still had component-less DAIs,
* instead of having a static name, component-less DAIs would
* inherit the name of the parent device so it is possible to
* register multiple instances of the DAI. We still need to keep
* the same naming style even though those DAIs are not
* component-less anymore.
*/
if
(
count
==
1
&&
legacy_dai_naming
)
{
dai
->
name
=
fmt_single_name
(
dev
,
&
dai
->
id
);
}
else
{
dai
->
name
=
fmt_multiple_name
(
dev
,
&
dai_drv
[
i
]);
if
(
dai_drv
[
i
].
id
)
dai
->
id
=
dai_drv
[
i
].
id
;
else
dai
->
id
=
i
;
}
if
(
dai
->
name
==
NULL
)
{
kfree
(
dai
);
ret
=
-
E
INVAL
;
ret
=
-
E
NOMEM
;
goto
err
;
}
dai
->
component
=
component
;
dai
->
codec
=
codec
;
dai
->
dev
=
dev
;
dai
->
driver
=
&
dai_drv
[
i
];
if
(
dai
->
driver
->
id
)
dai
->
id
=
dai
->
driver
->
id
;
else
dai
->
id
=
i
;
dai
->
dapm
.
dev
=
dev
;
if
(
!
dai
->
driver
->
ops
)
dai
->
driver
->
ops
=
&
null_dai_ops
;
mutex_lock
(
&
client_mutex
);
list_for_each_entry
(
codec
,
&
codec_list
,
list
)
{
if
(
codec
->
dev
==
dev
)
{
dev_dbg
(
dev
,
"ASoC: Mapped DAI %s to CODEC %s
\n
"
,
dai
->
name
,
codec
->
name
);
dai
->
codec
=
codec
;
break
;
}
}
if
(
!
dai
->
codec
)
dai
->
dapm
.
idle_bias_off
=
1
;
list_add
(
&
dai
->
list
,
&
dai_list
);
mutex_unlock
(
&
client_mutex
);
list_add
(
&
dai
->
list
,
&
component
->
dai_list
);
dev_dbg
(
d
ai
->
d
ev
,
"ASoC: Registered DAI '%s'
\n
"
,
dai
->
name
);
dev_dbg
(
dev
,
"ASoC: Registered DAI '%s'
\n
"
,
dai
->
name
);
}
return
0
;
err:
for
(
i
--
;
i
>=
0
;
i
--
)
snd_soc_unregister_dai
(
dev
);
snd_soc_unregister_dais
(
component
);
return
ret
;
}
/**
* snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
*
* @dai: Array of DAIs to unregister
* @count: Number of DAIs
*/
static
void
snd_soc_unregister_dais
(
struct
device
*
dev
,
size_t
count
)
{
int
i
;
for
(
i
=
0
;
i
<
count
;
i
++
)
snd_soc_unregister_dai
(
dev
);
}
/**
* snd_soc_register_component - Register a component with the ASoC core
*
...
...
@@ -4053,6 +4009,7 @@ static int
__snd_soc_register_component
(
struct
device
*
dev
,
struct
snd_soc_component
*
cmpnt
,
const
struct
snd_soc_component_driver
*
cmpnt_drv
,
struct
snd_soc_codec
*
codec
,
struct
snd_soc_dai_driver
*
dai_drv
,
int
num_dai
,
bool
allow_single_dai
)
{
...
...
@@ -4075,20 +4032,10 @@ __snd_soc_register_component(struct device *dev,
cmpnt
->
driver
=
cmpnt_drv
;
cmpnt
->
dai_drv
=
dai_drv
;
cmpnt
->
num_dai
=
num_dai
;
INIT_LIST_HEAD
(
&
cmpnt
->
dai_list
);
/*
* snd_soc_register_dai() uses fmt_single_name(), and
* snd_soc_register_dais() uses fmt_multiple_name()
* for dai->name which is used for name based matching
*
* this function is used from cpu/codec.
* allow_single_dai flag can ignore "codec" driver reworking
* since it had been used snd_soc_register_dais(),
*/
if
((
1
==
num_dai
)
&&
allow_single_dai
)
ret
=
snd_soc_register_dai
(
dev
,
dai_drv
);
else
ret
=
snd_soc_register_dais
(
dev
,
dai_drv
,
num_dai
);
ret
=
snd_soc_register_dais
(
cmpnt
,
codec
,
dai_drv
,
num_dai
,
allow_single_dai
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"ASoC: Failed to regster DAIs: %d
\n
"
,
ret
);
goto
error_component_name
;
...
...
@@ -4121,7 +4068,9 @@ int snd_soc_register_component(struct device *dev,
return
-
ENOMEM
;
}
return
__snd_soc_register_component
(
dev
,
cmpnt
,
cmpnt_drv
,
cmpnt
->
ignore_pmdown_time
=
true
;
return
__snd_soc_register_component
(
dev
,
cmpnt
,
cmpnt_drv
,
NULL
,
dai_drv
,
num_dai
,
true
);
}
EXPORT_SYMBOL_GPL
(
snd_soc_register_component
);
...
...
@@ -4141,7 +4090,7 @@ void snd_soc_unregister_component(struct device *dev)
return
;
found:
snd_soc_unregister_dais
(
dev
,
cmpnt
->
num_dai
);
snd_soc_unregister_dais
(
cmpnt
);
mutex_lock
(
&
client_mutex
);
list_del
(
&
cmpnt
->
list
);
...
...
@@ -4319,7 +4268,7 @@ int snd_soc_register_codec(struct device *dev,
codec
->
volatile_register
=
codec_drv
->
volatile_register
;
codec
->
readable_register
=
codec_drv
->
readable_register
;
codec
->
writable_register
=
codec_drv
->
writable_register
;
codec
->
ignore_pmdown_time
=
codec_drv
->
ignore_pmdown_time
;
codec
->
component
.
ignore_pmdown_time
=
codec_drv
->
ignore_pmdown_time
;
codec
->
dapm
.
bias_level
=
SND_SOC_BIAS_OFF
;
codec
->
dapm
.
dev
=
dev
;
codec
->
dapm
.
codec
=
codec
;
...
...
@@ -4342,7 +4291,7 @@ int snd_soc_register_codec(struct device *dev,
/* register component */
ret
=
__snd_soc_register_component
(
dev
,
&
codec
->
component
,
&
codec_drv
->
component_driver
,
dai_drv
,
num_dai
,
false
);
codec
,
dai_drv
,
num_dai
,
false
);
if
(
ret
<
0
)
{
dev_err
(
codec
->
dev
,
"ASoC: Failed to regster component: %d
\n
"
,
ret
);
goto
fail_codec_name
;
...
...
sound/soc/soc-pcm.c
View file @
da8ab21c
...
...
@@ -34,6 +34,86 @@
#define DPCM_MAX_BE_USERS 8
/**
* snd_soc_runtime_activate() - Increment active count for PCM runtime components
* @rtd: ASoC PCM runtime that is activated
* @stream: Direction of the PCM stream
*
* Increments the active count for all the DAIs and components attached to a PCM
* runtime. Should typically be called when a stream is opened.
*
* Must be called with the rtd->pcm_mutex being held
*/
void
snd_soc_runtime_activate
(
struct
snd_soc_pcm_runtime
*
rtd
,
int
stream
)
{
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
lockdep_assert_held
(
&
rtd
->
pcm_mutex
);
if
(
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
cpu_dai
->
playback_active
++
;
codec_dai
->
playback_active
++
;
}
else
{
cpu_dai
->
capture_active
++
;
codec_dai
->
capture_active
++
;
}
cpu_dai
->
active
++
;
codec_dai
->
active
++
;
cpu_dai
->
component
->
active
++
;
codec_dai
->
component
->
active
++
;
}
/**
* snd_soc_runtime_deactivate() - Decrement active count for PCM runtime components
* @rtd: ASoC PCM runtime that is deactivated
* @stream: Direction of the PCM stream
*
* Decrements the active count for all the DAIs and components attached to a PCM
* runtime. Should typically be called when a stream is closed.
*
* Must be called with the rtd->pcm_mutex being held
*/
void
snd_soc_runtime_deactivate
(
struct
snd_soc_pcm_runtime
*
rtd
,
int
stream
)
{
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
lockdep_assert_held
(
&
rtd
->
pcm_mutex
);
if
(
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
cpu_dai
->
playback_active
--
;
codec_dai
->
playback_active
--
;
}
else
{
cpu_dai
->
capture_active
--
;
codec_dai
->
capture_active
--
;
}
cpu_dai
->
active
--
;
codec_dai
->
active
--
;
cpu_dai
->
component
->
active
--
;
codec_dai
->
component
->
active
--
;
}
/**
* snd_soc_runtime_ignore_pmdown_time() - Check whether to ignore the power down delay
* @rtd: The ASoC PCM runtime that should be checked.
*
* This function checks whether the power down delay should be ignored for a
* specific PCM runtime. Returns true if the delay is 0, if it the DAI link has
* been configured to ignore the delay, or if none of the components benefits
* from having the delay.
*/
bool
snd_soc_runtime_ignore_pmdown_time
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
if
(
!
rtd
->
pmdown_time
||
rtd
->
dai_link
->
ignore_pmdown_time
)
return
true
;
return
rtd
->
cpu_dai
->
component
->
ignore_pmdown_time
&&
rtd
->
codec_dai
->
component
->
ignore_pmdown_time
;
}
/**
* snd_soc_set_runtime_hwparams - set the runtime hardware parameters
* @substream: the pcm substream
...
...
@@ -378,16 +458,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
runtime
->
hw
.
rate_max
);
dynamic:
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
cpu_dai
->
playback_active
++
;
codec_dai
->
playback_active
++
;
}
else
{
cpu_dai
->
capture_active
++
;
codec_dai
->
capture_active
++
;
}
cpu_dai
->
active
++
;
codec_dai
->
active
++
;
rtd
->
codec
->
active
++
;
snd_soc_runtime_activate
(
rtd
,
substream
->
stream
);
mutex_unlock
(
&
rtd
->
pcm_mutex
);
return
0
;
...
...
@@ -459,21 +532,10 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
struct
snd_soc_platform
*
platform
=
rtd
->
platform
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
mutex_lock_nested
(
&
rtd
->
pcm_mutex
,
rtd
->
pcm_subclass
);
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
cpu_dai
->
playback_active
--
;
codec_dai
->
playback_active
--
;
}
else
{
cpu_dai
->
capture_active
--
;
codec_dai
->
capture_active
--
;
}
cpu_dai
->
active
--
;
codec_dai
->
active
--
;
codec
->
active
--
;
snd_soc_runtime_deactivate
(
rtd
,
substream
->
stream
);
/* clear the corresponding DAIs rate when inactive */
if
(
!
cpu_dai
->
active
)
...
...
@@ -496,8 +558,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
cpu_dai
->
runtime
=
NULL
;
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
if
(
!
rtd
->
pmdown_time
||
codec
->
ignore_pmdown_time
||
rtd
->
dai_link
->
ignore_pmdown_time
)
{
if
(
snd_soc_runtime_ignore_pmdown_time
(
rtd
))
{
/* powered down playback stream now */
snd_soc_dapm_stream_event
(
rtd
,
SNDRV_PCM_STREAM_PLAYBACK
,
...
...
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