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