Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
07056901
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
07056901
编写于
10月 24, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/dapm' into asoc-next
上级
85eb5dce
30a765d6
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
279 addition
and
85 deletion
+279
-85
drivers/base/regmap/internal.h
drivers/base/regmap/internal.h
+3
-2
drivers/base/regmap/regcache.c
drivers/base/regmap/regcache.c
+1
-2
drivers/base/regmap/regmap.c
drivers/base/regmap/regmap.c
+157
-34
include/linux/regmap.h
include/linux/regmap.h
+31
-0
include/sound/soc-dapm.h
include/sound/soc-dapm.h
+4
-0
include/sound/soc.h
include/sound/soc.h
+2
-1
sound/soc/soc-dapm.c
sound/soc/soc-dapm.c
+75
-45
sound/soc/soc-jack.c
sound/soc/soc-jack.c
+6
-1
未找到文件。
drivers/base/regmap/internal.h
浏览文件 @
07056901
...
...
@@ -44,7 +44,6 @@ struct regmap_format {
struct
regmap_async
{
struct
list_head
list
;
struct
work_struct
cleanup
;
struct
regmap
*
map
;
void
*
work_buf
;
};
...
...
@@ -64,9 +63,11 @@ struct regmap {
void
*
bus_context
;
const
char
*
name
;
bool
async
;
spinlock_t
async_lock
;
wait_queue_head_t
async_waitq
;
struct
list_head
async_list
;
struct
list_head
async_free
;
int
async_ret
;
#ifdef CONFIG_DEBUG_FS
...
...
@@ -218,7 +219,7 @@ bool regcache_set_val(struct regmap *map, void *base, unsigned int idx,
int
regcache_lookup_reg
(
struct
regmap
*
map
,
unsigned
int
reg
);
int
_regmap_raw_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
const
void
*
val
,
size_t
val_len
,
bool
async
);
const
void
*
val
,
size_t
val_len
);
void
regmap_async_complete_cb
(
struct
regmap_async
*
async
,
int
ret
);
...
...
drivers/base/regmap/regcache.c
浏览文件 @
07056901
...
...
@@ -631,8 +631,7 @@ static int regcache_sync_block_raw_flush(struct regmap *map, const void **data,
map
->
cache_bypass
=
1
;
ret
=
_regmap_raw_write
(
map
,
base
,
*
data
,
count
*
val_bytes
,
false
);
ret
=
_regmap_raw_write
(
map
,
base
,
*
data
,
count
*
val_bytes
);
map
->
cache_bypass
=
0
;
...
...
drivers/base/regmap/regmap.c
浏览文件 @
07056901
...
...
@@ -42,15 +42,6 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
static
int
_regmap_bus_raw_write
(
void
*
context
,
unsigned
int
reg
,
unsigned
int
val
);
static
void
async_cleanup
(
struct
work_struct
*
work
)
{
struct
regmap_async
*
async
=
container_of
(
work
,
struct
regmap_async
,
cleanup
);
kfree
(
async
->
work_buf
);
kfree
(
async
);
}
bool
regmap_reg_in_ranges
(
unsigned
int
reg
,
const
struct
regmap_range
*
ranges
,
unsigned
int
nranges
)
...
...
@@ -465,6 +456,7 @@ struct regmap *regmap_init(struct device *dev,
spin_lock_init
(
&
map
->
async_lock
);
INIT_LIST_HEAD
(
&
map
->
async_list
);
INIT_LIST_HEAD
(
&
map
->
async_free
);
init_waitqueue_head
(
&
map
->
async_waitq
);
if
(
config
->
read_flag_mask
||
config
->
write_flag_mask
)
{
...
...
@@ -942,12 +934,22 @@ EXPORT_SYMBOL_GPL(regmap_reinit_cache);
*/
void
regmap_exit
(
struct
regmap
*
map
)
{
struct
regmap_async
*
async
;
regcache_exit
(
map
);
regmap_debugfs_exit
(
map
);
regmap_range_exit
(
map
);
if
(
map
->
bus
&&
map
->
bus
->
free_context
)
map
->
bus
->
free_context
(
map
->
bus_context
);
kfree
(
map
->
work_buf
);
while
(
!
list_empty
(
&
map
->
async_free
))
{
async
=
list_first_entry_or_null
(
&
map
->
async_free
,
struct
regmap_async
,
list
);
list_del
(
&
async
->
list
);
kfree
(
async
->
work_buf
);
kfree
(
async
);
}
kfree
(
map
);
}
EXPORT_SYMBOL_GPL
(
regmap_exit
);
...
...
@@ -1039,7 +1041,7 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
}
int
_regmap_raw_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
const
void
*
val
,
size_t
val_len
,
bool
async
)
const
void
*
val
,
size_t
val_len
)
{
struct
regmap_range_node
*
range
;
unsigned
long
flags
;
...
...
@@ -1091,7 +1093,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
dev_dbg
(
map
->
dev
,
"Writing window %d/%zu
\n
"
,
win_residue
,
val_len
/
map
->
format
.
val_bytes
);
ret
=
_regmap_raw_write
(
map
,
reg
,
val
,
win_residue
*
map
->
format
.
val_bytes
,
async
);
map
->
format
.
val_bytes
);
if
(
ret
!=
0
)
return
ret
;
...
...
@@ -1114,21 +1116,42 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
u8
[
0
]
|=
map
->
write_flag_mask
;
if
(
async
&&
map
->
bus
->
async_write
)
{
struct
regmap_async
*
async
=
map
->
bus
->
async_alloc
();
if
(
!
async
)
return
-
ENOMEM
;
/*
* Essentially all I/O mechanisms will be faster with a single
* buffer to write. Since register syncs often generate raw
* writes of single registers optimise that case.
*/
if
(
val
!=
work_val
&&
val_len
==
map
->
format
.
val_bytes
)
{
memcpy
(
work_val
,
val
,
map
->
format
.
val_bytes
);
val
=
work_val
;
}
if
(
map
->
async
&&
map
->
bus
->
async_write
)
{
struct
regmap_async
*
async
;
trace_regmap_async_write_start
(
map
->
dev
,
reg
,
val_len
);
async
->
work_buf
=
kzalloc
(
map
->
format
.
buf_size
,
GFP_KERNEL
|
GFP_DMA
);
if
(
!
async
->
work_buf
)
{
kfree
(
async
);
return
-
ENOMEM
;
spin_lock_irqsave
(
&
map
->
async_lock
,
flags
);
async
=
list_first_entry_or_null
(
&
map
->
async_free
,
struct
regmap_async
,
list
);
if
(
async
)
list_del
(
&
async
->
list
);
spin_unlock_irqrestore
(
&
map
->
async_lock
,
flags
);
if
(
!
async
)
{
async
=
map
->
bus
->
async_alloc
();
if
(
!
async
)
return
-
ENOMEM
;
async
->
work_buf
=
kzalloc
(
map
->
format
.
buf_size
,
GFP_KERNEL
|
GFP_DMA
);
if
(
!
async
->
work_buf
)
{
kfree
(
async
);
return
-
ENOMEM
;
}
}
INIT_WORK
(
&
async
->
cleanup
,
async_cleanup
);
async
->
map
=
map
;
/* If the caller supplied the value we can use it safely. */
...
...
@@ -1152,11 +1175,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
ret
);
spin_lock_irqsave
(
&
map
->
async_lock
,
flags
);
list_
del
(
&
async
->
list
);
list_
move
(
&
async
->
list
,
&
map
->
async_free
);
spin_unlock_irqrestore
(
&
map
->
async_lock
,
flags
);
kfree
(
async
->
work_buf
);
kfree
(
async
);
}
return
ret
;
...
...
@@ -1253,7 +1273,7 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
map
->
work_buf
+
map
->
format
.
reg_bytes
+
map
->
format
.
pad_bytes
,
map
->
format
.
val_bytes
,
false
);
map
->
format
.
val_bytes
);
}
static
inline
void
*
_regmap_map_get_context
(
struct
regmap
*
map
)
...
...
@@ -1317,6 +1337,37 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
}
EXPORT_SYMBOL_GPL
(
regmap_write
);
/**
* regmap_write_async(): Write a value to a single register asynchronously
*
* @map: Register map to write to
* @reg: Register to write to
* @val: Value to be written
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
int
regmap_write_async
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
val
)
{
int
ret
;
if
(
reg
%
map
->
reg_stride
)
return
-
EINVAL
;
map
->
lock
(
map
->
lock_arg
);
map
->
async
=
true
;
ret
=
_regmap_write
(
map
,
reg
,
val
);
map
->
async
=
false
;
map
->
unlock
(
map
->
lock_arg
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
regmap_write_async
);
/**
* regmap_raw_write(): Write raw values to one or more registers
*
...
...
@@ -1345,7 +1396,7 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
map
->
lock
(
map
->
lock_arg
);
ret
=
_regmap_raw_write
(
map
,
reg
,
val
,
val_len
,
false
);
ret
=
_regmap_raw_write
(
map
,
reg
,
val
,
val_len
);
map
->
unlock
(
map
->
lock_arg
);
...
...
@@ -1426,8 +1477,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
return
ret
;
}
}
else
{
ret
=
_regmap_raw_write
(
map
,
reg
,
wval
,
val_bytes
*
val_count
,
false
);
ret
=
_regmap_raw_write
(
map
,
reg
,
wval
,
val_bytes
*
val_count
);
}
if
(
val_bytes
!=
1
)
...
...
@@ -1473,7 +1523,11 @@ int regmap_raw_write_async(struct regmap *map, unsigned int reg,
map
->
lock
(
map
->
lock_arg
);
ret
=
_regmap_raw_write
(
map
,
reg
,
val
,
val_len
,
true
);
map
->
async
=
true
;
ret
=
_regmap_raw_write
(
map
,
reg
,
val
,
val_len
);
map
->
async
=
false
;
map
->
unlock
(
map
->
lock_arg
);
...
...
@@ -1787,6 +1841,41 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
}
EXPORT_SYMBOL_GPL
(
regmap_update_bits
);
/**
* regmap_update_bits_async: Perform a read/modify/write cycle on the register
* map asynchronously
*
* @map: Register map to update
* @reg: Register to update
* @mask: Bitmask to change
* @val: New value for bitmask
*
* With most buses the read must be done synchronously so this is most
* useful for devices with a cache which do not need to interact with
* the hardware to determine the current register value.
*
* Returns zero for success, a negative number on error.
*/
int
regmap_update_bits_async
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
mask
,
unsigned
int
val
)
{
bool
change
;
int
ret
;
map
->
lock
(
map
->
lock_arg
);
map
->
async
=
true
;
ret
=
_regmap_update_bits
(
map
,
reg
,
mask
,
val
,
&
change
);
map
->
async
=
false
;
map
->
unlock
(
map
->
lock_arg
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
regmap_update_bits_async
);
/**
* regmap_update_bits_check: Perform a read/modify/write cycle on the
* register map and report if updated
...
...
@@ -1812,6 +1901,43 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
}
EXPORT_SYMBOL_GPL
(
regmap_update_bits_check
);
/**
* regmap_update_bits_check_async: Perform a read/modify/write cycle on the
* register map asynchronously and report if
* updated
*
* @map: Register map to update
* @reg: Register to update
* @mask: Bitmask to change
* @val: New value for bitmask
* @change: Boolean indicating if a write was done
*
* With most buses the read must be done synchronously so this is most
* useful for devices with a cache which do not need to interact with
* the hardware to determine the current register value.
*
* Returns zero for success, a negative number on error.
*/
int
regmap_update_bits_check_async
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
mask
,
unsigned
int
val
,
bool
*
change
)
{
int
ret
;
map
->
lock
(
map
->
lock_arg
);
map
->
async
=
true
;
ret
=
_regmap_update_bits
(
map
,
reg
,
mask
,
val
,
change
);
map
->
async
=
false
;
map
->
unlock
(
map
->
lock_arg
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
regmap_update_bits_check_async
);
void
regmap_async_complete_cb
(
struct
regmap_async
*
async
,
int
ret
)
{
struct
regmap
*
map
=
async
->
map
;
...
...
@@ -1820,8 +1946,7 @@ void regmap_async_complete_cb(struct regmap_async *async, int ret)
trace_regmap_async_io_complete
(
map
->
dev
);
spin_lock
(
&
map
->
async_lock
);
list_del
(
&
async
->
list
);
list_move
(
&
async
->
list
,
&
map
->
async_free
);
wake
=
list_empty
(
&
map
->
async_list
);
if
(
ret
!=
0
)
...
...
@@ -1829,8 +1954,6 @@ void regmap_async_complete_cb(struct regmap_async *async, int ret)
spin_unlock
(
&
map
->
async_lock
);
schedule_work
(
&
async
->
cleanup
);
if
(
wake
)
wake_up
(
&
map
->
async_waitq
);
}
...
...
include/linux/regmap.h
浏览文件 @
07056901
...
...
@@ -374,6 +374,7 @@ int regmap_reinit_cache(struct regmap *map,
const
struct
regmap_config
*
config
);
struct
regmap
*
dev_get_regmap
(
struct
device
*
dev
,
const
char
*
name
);
int
regmap_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
val
);
int
regmap_write_async
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
val
);
int
regmap_raw_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
const
void
*
val
,
size_t
val_len
);
int
regmap_bulk_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
const
void
*
val
,
...
...
@@ -387,9 +388,14 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
size_t
val_count
);
int
regmap_update_bits
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
mask
,
unsigned
int
val
);
int
regmap_update_bits_async
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
mask
,
unsigned
int
val
);
int
regmap_update_bits_check
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
mask
,
unsigned
int
val
,
bool
*
change
);
int
regmap_update_bits_check_async
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
mask
,
unsigned
int
val
,
bool
*
change
);
int
regmap_get_val_bytes
(
struct
regmap
*
map
);
int
regmap_async_complete
(
struct
regmap
*
map
);
bool
regmap_can_raw_write
(
struct
regmap
*
map
);
...
...
@@ -527,6 +533,13 @@ static inline int regmap_write(struct regmap *map, unsigned int reg,
return
-
EINVAL
;
}
static
inline
int
regmap_write_async
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
val
)
{
WARN_ONCE
(
1
,
"regmap API is disabled"
);
return
-
EINVAL
;
}
static
inline
int
regmap_raw_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
const
void
*
val
,
size_t
val_len
)
{
...
...
@@ -576,6 +589,14 @@ static inline int regmap_update_bits(struct regmap *map, unsigned int reg,
return
-
EINVAL
;
}
static
inline
int
regmap_update_bits_async
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
mask
,
unsigned
int
val
)
{
WARN_ONCE
(
1
,
"regmap API is disabled"
);
return
-
EINVAL
;
}
static
inline
int
regmap_update_bits_check
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
mask
,
unsigned
int
val
,
...
...
@@ -585,6 +606,16 @@ static inline int regmap_update_bits_check(struct regmap *map,
return
-
EINVAL
;
}
static
inline
int
regmap_update_bits_check_async
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
mask
,
unsigned
int
val
,
bool
*
change
)
{
WARN_ONCE
(
1
,
"regmap API is disabled"
);
return
-
EINVAL
;
}
static
inline
int
regmap_get_val_bytes
(
struct
regmap
*
map
)
{
WARN_ONCE
(
1
,
"regmap API is disabled"
);
...
...
include/sound/soc-dapm.h
浏览文件 @
07056901
...
...
@@ -286,6 +286,8 @@ struct device;
.info = snd_soc_info_volsw, \
.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) }
#define SOC_DAPM_SINGLE_VIRT(xname, max) \
SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0)
#define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, \
...
...
@@ -300,6 +302,8 @@ struct device;
.tlv.p = (tlv_array), \
.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
#define SOC_DAPM_SINGLE_TLV_VIRT(xname, max, tlv_array) \
SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0, tlv_array)
#define SOC_DAPM_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_enum_double, \
...
...
include/sound/soc.h
浏览文件 @
07056901
...
...
@@ -1047,7 +1047,8 @@ struct snd_soc_pcm_runtime {
/* mixer control */
struct
soc_mixer_control
{
int
min
,
max
,
platform_max
;
unsigned
int
reg
,
rreg
,
shift
,
rshift
;
int
reg
,
rreg
;
unsigned
int
shift
,
rshift
;
unsigned
int
invert
:
1
;
unsigned
int
autodisable
:
1
;
};
...
...
sound/soc/soc-dapm.c
浏览文件 @
07056901
...
...
@@ -59,31 +59,31 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
/* dapm power sequences - make this per codec in the future */
static
int
dapm_up_seq
[]
=
{
[
snd_soc_dapm_pre
]
=
0
,
[
snd_soc_dapm_supply
]
=
1
,
[
snd_soc_dapm_regulator_supply
]
=
1
,
[
snd_soc_dapm_clock_supply
]
=
1
,
[
snd_soc_dapm_micbias
]
=
2
,
[
snd_soc_dapm_supply
]
=
2
,
[
snd_soc_dapm_micbias
]
=
3
,
[
snd_soc_dapm_dai_link
]
=
2
,
[
snd_soc_dapm_dai_in
]
=
3
,
[
snd_soc_dapm_dai_out
]
=
3
,
[
snd_soc_dapm_aif_in
]
=
3
,
[
snd_soc_dapm_aif_out
]
=
3
,
[
snd_soc_dapm_mic
]
=
4
,
[
snd_soc_dapm_mux
]
=
5
,
[
snd_soc_dapm_virt_mux
]
=
5
,
[
snd_soc_dapm_value_mux
]
=
5
,
[
snd_soc_dapm_dac
]
=
6
,
[
snd_soc_dapm_switch
]
=
7
,
[
snd_soc_dapm_mixer
]
=
7
,
[
snd_soc_dapm_mixer_named_ctl
]
=
7
,
[
snd_soc_dapm_pga
]
=
8
,
[
snd_soc_dapm_adc
]
=
9
,
[
snd_soc_dapm_out_drv
]
=
1
0
,
[
snd_soc_dapm_hp
]
=
1
0
,
[
snd_soc_dapm_spk
]
=
1
0
,
[
snd_soc_dapm_line
]
=
1
0
,
[
snd_soc_dapm_kcontrol
]
=
1
1
,
[
snd_soc_dapm_post
]
=
1
2
,
[
snd_soc_dapm_dai_in
]
=
4
,
[
snd_soc_dapm_dai_out
]
=
4
,
[
snd_soc_dapm_aif_in
]
=
4
,
[
snd_soc_dapm_aif_out
]
=
4
,
[
snd_soc_dapm_mic
]
=
5
,
[
snd_soc_dapm_mux
]
=
6
,
[
snd_soc_dapm_virt_mux
]
=
6
,
[
snd_soc_dapm_value_mux
]
=
6
,
[
snd_soc_dapm_dac
]
=
7
,
[
snd_soc_dapm_switch
]
=
8
,
[
snd_soc_dapm_mixer
]
=
8
,
[
snd_soc_dapm_mixer_named_ctl
]
=
8
,
[
snd_soc_dapm_pga
]
=
9
,
[
snd_soc_dapm_adc
]
=
10
,
[
snd_soc_dapm_out_drv
]
=
1
1
,
[
snd_soc_dapm_hp
]
=
1
1
,
[
snd_soc_dapm_spk
]
=
1
1
,
[
snd_soc_dapm_line
]
=
1
1
,
[
snd_soc_dapm_kcontrol
]
=
1
2
,
[
snd_soc_dapm_post
]
=
1
3
,
};
static
int
dapm_down_seq
[]
=
{
...
...
@@ -109,10 +109,10 @@ static int dapm_down_seq[] = {
[
snd_soc_dapm_dai_in
]
=
10
,
[
snd_soc_dapm_dai_out
]
=
10
,
[
snd_soc_dapm_dai_link
]
=
11
,
[
snd_soc_dapm_clock_supply
]
=
12
,
[
snd_soc_dapm_regulator_supply
]
=
12
,
[
snd_soc_dapm_supply
]
=
12
,
[
snd_soc_dapm_post
]
=
13
,
[
snd_soc_dapm_clock_supply
]
=
13
,
[
snd_soc_dapm_regulator_supply
]
=
13
,
[
snd_soc_dapm_post
]
=
14
,
};
static
void
pop_wait
(
u32
pop_time
)
...
...
@@ -409,6 +409,12 @@ static inline void soc_widget_unlock(struct snd_soc_dapm_widget *w)
mutex_unlock
(
&
w
->
platform
->
mutex
);
}
static
void
soc_dapm_async_complete
(
struct
snd_soc_dapm_context
*
dapm
)
{
if
(
dapm
->
codec
&&
dapm
->
codec
->
using_regmap
)
regmap_async_complete
(
dapm
->
codec
->
control_data
);
}
static
int
soc_widget_update_bits_locked
(
struct
snd_soc_dapm_widget
*
w
,
unsigned
short
reg
,
unsigned
int
mask
,
unsigned
int
value
)
{
...
...
@@ -417,8 +423,9 @@ static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
int
ret
;
if
(
w
->
codec
&&
w
->
codec
->
using_regmap
)
{
ret
=
regmap_update_bits_check
(
w
->
codec
->
control_data
,
reg
,
mask
,
value
,
&
change
);
ret
=
regmap_update_bits_check_async
(
w
->
codec
->
control_data
,
reg
,
mask
,
value
,
&
change
);
if
(
ret
!=
0
)
return
ret
;
}
else
{
...
...
@@ -499,18 +506,22 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
int
val
;
struct
soc_mixer_control
*
mc
=
(
struct
soc_mixer_control
*
)
w
->
kcontrol_news
[
i
].
private_value
;
unsigned
int
reg
=
mc
->
reg
;
int
reg
=
mc
->
reg
;
unsigned
int
shift
=
mc
->
shift
;
int
max
=
mc
->
max
;
unsigned
int
mask
=
(
1
<<
fls
(
max
))
-
1
;
unsigned
int
invert
=
mc
->
invert
;
val
=
soc_widget_read
(
w
,
reg
);
val
=
(
val
>>
shift
)
&
mask
;
if
(
invert
)
val
=
max
-
val
;
if
(
reg
!=
SND_SOC_NOPM
)
{
val
=
soc_widget_read
(
w
,
reg
);
val
=
(
val
>>
shift
)
&
mask
;
if
(
invert
)
val
=
max
-
val
;
p
->
connect
=
!!
val
;
}
else
{
p
->
connect
=
0
;
}
p
->
connect
=
!!
val
;
}
break
;
case
snd_soc_dapm_mux
:
{
...
...
@@ -1197,6 +1208,8 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
{
int
ret
;
soc_dapm_async_complete
(
w
->
dapm
);
if
(
SND_SOC_DAPM_EVENT_ON
(
event
))
{
if
(
w
->
on_val
&
SND_SOC_DAPM_REGULATOR_BYPASS
)
{
ret
=
regulator_allow_bypass
(
w
->
regulator
,
false
);
...
...
@@ -1230,6 +1243,8 @@ int dapm_clock_event(struct snd_soc_dapm_widget *w,
if
(
!
w
->
clk
)
return
-
EIO
;
soc_dapm_async_complete
(
w
->
dapm
);
#ifdef CONFIG_HAVE_CLK
if
(
SND_SOC_DAPM_EVENT_ON
(
event
))
{
return
clk_prepare_enable
(
w
->
clk
);
...
...
@@ -1422,6 +1437,7 @@ static void dapm_seq_check_event(struct snd_soc_card *card,
if
(
w
->
event
&&
(
w
->
event_flags
&
event
))
{
pop_dbg
(
w
->
dapm
->
dev
,
card
->
pop_time
,
"pop test : %s %s
\n
"
,
w
->
name
,
ev_name
);
soc_dapm_async_complete
(
w
->
dapm
);
trace_snd_soc_dapm_widget_event_start
(
w
,
event
);
ret
=
w
->
event
(
w
,
NULL
,
event
);
trace_snd_soc_dapm_widget_event_done
(
w
,
event
);
...
...
@@ -1494,6 +1510,7 @@ static void dapm_seq_run(struct snd_soc_card *card,
struct
list_head
*
list
,
int
event
,
bool
power_up
)
{
struct
snd_soc_dapm_widget
*
w
,
*
n
;
struct
snd_soc_dapm_context
*
d
;
LIST_HEAD
(
pending
);
int
cur_sort
=
-
1
;
int
cur_subseq
=
-
1
;
...
...
@@ -1524,6 +1541,9 @@ static void dapm_seq_run(struct snd_soc_card *card,
cur_subseq
);
}
if
(
cur_dapm
&&
w
->
dapm
!=
cur_dapm
)
soc_dapm_async_complete
(
cur_dapm
);
INIT_LIST_HEAD
(
&
pending
);
cur_sort
=
-
1
;
cur_subseq
=
INT_MIN
;
...
...
@@ -1582,6 +1602,10 @@ static void dapm_seq_run(struct snd_soc_card *card,
cur_dapm
->
seq_notifier
(
cur_dapm
,
i
,
cur_subseq
);
}
list_for_each_entry
(
d
,
&
card
->
dapm_list
,
list
)
{
soc_dapm_async_complete
(
d
);
}
}
static
void
dapm_widget_update
(
struct
snd_soc_card
*
card
)
...
...
@@ -1840,6 +1864,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
*/
switch
(
w
->
id
)
{
case
snd_soc_dapm_siggen
:
case
snd_soc_dapm_vmid
:
break
;
case
snd_soc_dapm_supply
:
case
snd_soc_dapm_regulator_supply
:
...
...
@@ -2791,7 +2816,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
struct
snd_soc_card
*
card
=
codec
->
card
;
struct
soc_mixer_control
*
mc
=
(
struct
soc_mixer_control
*
)
kcontrol
->
private_value
;
unsigned
int
reg
=
mc
->
reg
;
int
reg
=
mc
->
reg
;
unsigned
int
shift
=
mc
->
shift
;
int
max
=
mc
->
max
;
unsigned
int
mask
=
(
1
<<
fls
(
max
))
-
1
;
...
...
@@ -2804,7 +2829,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
kcontrol
->
id
.
name
);
mutex_lock_nested
(
&
card
->
dapm_mutex
,
SND_SOC_DAPM_CLASS_RUNTIME
);
if
(
dapm_kcontrol_is_powered
(
kcontrol
))
if
(
dapm_kcontrol_is_powered
(
kcontrol
)
&&
reg
!=
SND_SOC_NOPM
)
val
=
(
snd_soc_read
(
codec
,
reg
)
>>
shift
)
&
mask
;
else
val
=
dapm_kcontrol_get_value
(
kcontrol
);
...
...
@@ -2835,7 +2860,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
struct
snd_soc_card
*
card
=
codec
->
card
;
struct
soc_mixer_control
*
mc
=
(
struct
soc_mixer_control
*
)
kcontrol
->
private_value
;
unsigned
int
reg
=
mc
->
reg
;
int
reg
=
mc
->
reg
;
unsigned
int
shift
=
mc
->
shift
;
int
max
=
mc
->
max
;
unsigned
int
mask
=
(
1
<<
fls
(
max
))
-
1
;
...
...
@@ -2857,19 +2882,24 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
mutex_lock_nested
(
&
card
->
dapm_mutex
,
SND_SOC_DAPM_CLASS_RUNTIME
);
dapm_kcontrol_set_value
(
kcontrol
,
val
);
change
=
dapm_kcontrol_set_value
(
kcontrol
,
val
);
if
(
reg
!=
SND_SOC_NOPM
)
{
mask
=
mask
<<
shift
;
val
=
val
<<
shift
;
mask
=
mask
<<
shift
;
val
=
val
<<
shift
;
change
=
snd_soc_test_bits
(
codec
,
reg
,
mask
,
val
)
;
}
change
=
snd_soc_test_bits
(
codec
,
reg
,
mask
,
val
);
if
(
change
)
{
update
.
kcontrol
=
kcontrol
;
update
.
reg
=
reg
;
update
.
mask
=
mask
;
update
.
val
=
val
;
if
(
reg
!=
SND_SOC_NOPM
)
{
update
.
kcontrol
=
kcontrol
;
update
.
reg
=
reg
;
update
.
mask
=
mask
;
update
.
val
=
val
;
card
->
update
=
&
update
;
card
->
update
=
&
update
;
}
soc_dapm_mixer_update_power
(
card
,
kcontrol
,
connect
);
...
...
sound/soc/soc-jack.c
浏览文件 @
07056901
...
...
@@ -65,6 +65,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
struct
snd_soc_codec
*
codec
;
struct
snd_soc_dapm_context
*
dapm
;
struct
snd_soc_jack_pin
*
pin
;
unsigned
int
sync
=
0
;
int
enable
;
trace_snd_soc_jack_report
(
jack
,
mask
,
status
);
...
...
@@ -92,12 +93,16 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
snd_soc_dapm_enable_pin
(
dapm
,
pin
->
pin
);
else
snd_soc_dapm_disable_pin
(
dapm
,
pin
->
pin
);
/* we need to sync for this case only */
sync
=
1
;
}
/* Report before the DAPM sync to help users updating micbias status */
blocking_notifier_call_chain
(
&
jack
->
notifier
,
jack
->
status
,
jack
);
snd_soc_dapm_sync
(
dapm
);
if
(
sync
)
snd_soc_dapm_sync
(
dapm
);
snd_jack_report
(
jack
->
jack
,
jack
->
status
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录