Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
18620cc5
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看板
提交
18620cc5
编写于
12月 10, 2012
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/jz4740' into asoc-next
上级
2766ee82
dd1b18ab
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
60 addition
and
83 deletion
+60
-83
sound/soc/codecs/Kconfig
sound/soc/codecs/Kconfig
+1
-0
sound/soc/codecs/jz4740.c
sound/soc/codecs/jz4740.c
+59
-83
未找到文件。
sound/soc/codecs/Kconfig
浏览文件 @
18620cc5
...
...
@@ -236,6 +236,7 @@ config SND_SOC_CX20442
tristate
config SND_SOC_JZ4740_CODEC
select REGMAP_MMIO
tristate
config SND_SOC_L3
...
...
sound/soc/codecs/jz4740.c
浏览文件 @
18620cc5
...
...
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/regmap.h>
#include <linux/delay.h>
...
...
@@ -24,9 +25,10 @@
#include <sound/pcm_params.h>
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#define JZ4740_REG_CODEC_1 0x0
#define JZ4740_REG_CODEC_2 0x
1
#define JZ4740_REG_CODEC_2 0x
4
#define JZ4740_CODEC_1_LINE_ENABLE BIT(29)
#define JZ4740_CODEC_1_MIC_ENABLE BIT(28)
...
...
@@ -67,43 +69,36 @@
#define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET 4
#define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET 0
static
const
uint32_t
jz4740_codec_regs
[]
=
{
0x021b2302
,
0x00170803
,
static
const
struct
reg_default
jz4740_codec_reg_defaults
[]
=
{
{
JZ4740_REG_CODEC_1
,
0x021b2302
},
{
JZ4740_REG_CODEC_2
,
0x00170803
},
};
struct
jz4740_codec
{
void
__iomem
*
base
;
struct
resource
*
mem
;
struct
regmap
*
regmap
;
};
static
unsigned
int
jz4740_codec_read
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
)
{
struct
jz4740_codec
*
jz4740_codec
=
snd_soc_codec_get_drvdata
(
codec
);
return
readl
(
jz4740_codec
->
base
+
(
reg
<<
2
));
}
static
int
jz4740_codec_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
val
)
{
struct
jz4740_codec
*
jz4740_codec
=
snd_soc_codec_get_drvdata
(
codec
);
u32
*
cache
=
codec
->
reg_cache
;
cache
[
reg
]
=
val
;
writel
(
val
,
jz4740_codec
->
base
+
(
reg
<<
2
));
static
const
unsigned
int
jz4740_mic_tlv
[]
=
{
TLV_DB_RANGE_HEAD
(
2
),
0
,
2
,
TLV_DB_SCALE_ITEM
(
0
,
600
,
0
),
3
,
3
,
TLV_DB_SCALE_ITEM
(
2000
,
0
,
0
),
};
return
0
;
}
static
const
DECLARE_TLV_DB_SCALE
(
jz4740_out_tlv
,
0
,
200
,
0
)
;
static
const
DECLARE_TLV_DB_SCALE
(
jz4740_in_tlv
,
-
3450
,
150
,
0
);
static
const
struct
snd_kcontrol_new
jz4740_codec_controls
[]
=
{
SOC_SINGLE
(
"Master Playback Volume"
,
JZ4740_REG_CODEC_2
,
JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET
,
3
,
0
),
SOC_SINGLE
(
"Master Capture Volume"
,
JZ4740_REG_CODEC_2
,
JZ4740_CODEC_2_INPUT_VOLUME_OFFSET
,
31
,
0
),
SOC_SINGLE_TLV
(
"Master Playback Volume"
,
JZ4740_REG_CODEC_2
,
JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET
,
3
,
0
,
jz4740_out_tlv
),
SOC_SINGLE_TLV
(
"Master Capture Volume"
,
JZ4740_REG_CODEC_2
,
JZ4740_CODEC_2_INPUT_VOLUME_OFFSET
,
31
,
0
,
jz4740_in_tlv
),
SOC_SINGLE
(
"Master Playback Switch"
,
JZ4740_REG_CODEC_1
,
JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET
,
1
,
1
),
SOC_SINGLE
(
"Mic Capture Volume"
,
JZ4740_REG_CODEC_2
,
JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET
,
3
,
0
),
SOC_SINGLE_TLV
(
"Mic Capture Volume"
,
JZ4740_REG_CODEC_2
,
JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET
,
3
,
0
,
jz4740_mic_tlv
),
};
static
const
struct
snd_kcontrol_new
jz4740_codec_output_controls
[]
=
{
...
...
@@ -163,8 +158,8 @@ static const struct snd_soc_dapm_route jz4740_codec_dapm_routes[] = {
static
int
jz4740_codec_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
,
struct
snd_soc_dai
*
dai
)
{
struct
jz4740_codec
*
jz4740_codec
=
snd_soc_codec_get_drvdata
(
dai
->
codec
);
uint32_t
val
;
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
switch
(
params_rate
(
params
))
{
case
8000
:
...
...
@@ -200,7 +195,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
val
<<=
JZ4740_CODEC_2_SAMPLE_RATE_OFFSET
;
snd_soc_update_bits
(
codec
,
JZ4740_REG_CODEC_2
,
regmap_update_bits
(
jz4740_codec
->
regmap
,
JZ4740_REG_CODEC_2
,
JZ4740_CODEC_2_SAMPLE_RATE_MASK
,
val
);
return
0
;
...
...
@@ -230,25 +225,23 @@ static struct snd_soc_dai_driver jz4740_codec_dai = {
.
symmetric_rates
=
1
,
};
static
void
jz4740_codec_wakeup
(
struct
snd_soc_codec
*
codec
)
static
void
jz4740_codec_wakeup
(
struct
regmap
*
regmap
)
{
int
i
;
uint32_t
*
cache
=
codec
->
reg_cache
;
snd_soc_update_bits
(
codec
,
JZ4740_REG_CODEC_1
,
regmap_update_bits
(
regmap
,
JZ4740_REG_CODEC_1
,
JZ4740_CODEC_1_RESET
,
JZ4740_CODEC_1_RESET
);
udelay
(
2
);
snd_soc_update_bits
(
codec
,
JZ4740_REG_CODEC_1
,
regmap_update_bits
(
regmap
,
JZ4740_REG_CODEC_1
,
JZ4740_CODEC_1_SUSPEND
|
JZ4740_CODEC_1_RESET
,
0
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
jz4740_codec_regs
);
++
i
)
jz4740_codec_write
(
codec
,
i
,
cache
[
i
]);
regcache_sync
(
regmap
);
}
static
int
jz4740_codec_set_bias_level
(
struct
snd_soc_codec
*
codec
,
enum
snd_soc_bias_level
level
)
{
struct
jz4740_codec
*
jz4740_codec
=
snd_soc_codec_get_drvdata
(
codec
);
struct
regmap
*
regmap
=
jz4740_codec
->
regmap
;
unsigned
int
mask
;
unsigned
int
value
;
...
...
@@ -261,12 +254,12 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M
;
value
=
0
;
snd_soc_update_bits
(
codec
,
JZ4740_REG_CODEC_1
,
mask
,
value
);
regmap_update_bits
(
regmap
,
JZ4740_REG_CODEC_1
,
mask
,
value
);
break
;
case
SND_SOC_BIAS_STANDBY
:
/* The only way to clear the suspend flag is to reset the codec */
if
(
codec
->
dapm
.
bias_level
==
SND_SOC_BIAS_OFF
)
jz4740_codec_wakeup
(
codec
);
jz4740_codec_wakeup
(
regmap
);
mask
=
JZ4740_CODEC_1_VREF_DISABLE
|
JZ4740_CODEC_1_VREF_AMP_DISABLE
|
...
...
@@ -275,13 +268,14 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
JZ4740_CODEC_1_VREF_AMP_DISABLE
|
JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M
;
snd_soc_update_bits
(
codec
,
JZ4740_REG_CODEC_1
,
mask
,
value
);
regmap_update_bits
(
regmap
,
JZ4740_REG_CODEC_1
,
mask
,
value
);
break
;
case
SND_SOC_BIAS_OFF
:
mask
=
JZ4740_CODEC_1_SUSPEND
;
value
=
JZ4740_CODEC_1_SUSPEND
;
snd_soc_update_bits
(
codec
,
JZ4740_REG_CODEC_1
,
mask
,
value
);
regmap_update_bits
(
regmap
,
JZ4740_REG_CODEC_1
,
mask
,
value
);
regcache_mark_dirty
(
regmap
);
break
;
default:
break
;
...
...
@@ -294,7 +288,9 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
static
int
jz4740_codec_dev_probe
(
struct
snd_soc_codec
*
codec
)
{
snd_soc_update_bits
(
codec
,
JZ4740_REG_CODEC_1
,
struct
jz4740_codec
*
jz4740_codec
=
snd_soc_codec_get_drvdata
(
codec
);
regmap_update_bits
(
jz4740_codec
->
regmap
,
JZ4740_REG_CODEC_1
,
JZ4740_CODEC_1_SW2_ENABLE
,
JZ4740_CODEC_1_SW2_ENABLE
);
jz4740_codec_set_bias_level
(
codec
,
SND_SOC_BIAS_STANDBY
);
...
...
@@ -331,12 +327,7 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
.
remove
=
jz4740_codec_dev_remove
,
.
suspend
=
jz4740_codec_suspend
,
.
resume
=
jz4740_codec_resume
,
.
read
=
jz4740_codec_read
,
.
write
=
jz4740_codec_write
,
.
set_bias_level
=
jz4740_codec_set_bias_level
,
.
reg_cache_default
=
jz4740_codec_regs
,
.
reg_word_size
=
sizeof
(
u32
),
.
reg_cache_size
=
2
,
.
controls
=
jz4740_codec_controls
,
.
num_controls
=
ARRAY_SIZE
(
jz4740_codec_controls
),
...
...
@@ -346,11 +337,23 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
.
num_dapm_routes
=
ARRAY_SIZE
(
jz4740_codec_dapm_routes
),
};
static
const
struct
regmap_config
jz4740_codec_regmap_config
=
{
.
reg_bits
=
32
,
.
reg_stride
=
4
,
.
val_bits
=
32
,
.
max_register
=
JZ4740_REG_CODEC_2
,
.
reg_defaults
=
jz4740_codec_reg_defaults
,
.
num_reg_defaults
=
ARRAY_SIZE
(
jz4740_codec_reg_defaults
),
.
cache_type
=
REGCACHE_RBTREE
,
};
static
int
__devinit
jz4740_codec_probe
(
struct
platform_device
*
pdev
)
{
int
ret
;
struct
jz4740_codec
*
jz4740_codec
;
struct
resource
*
mem
;
void
__iomem
*
base
;
jz4740_codec
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
jz4740_codec
),
GFP_KERNEL
);
...
...
@@ -358,56 +361,29 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev)
return
-
ENOMEM
;
mem
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
mem
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to get mmio memory resource
\n
"
);
ret
=
-
ENOENT
;
goto
err_out
;
}
mem
=
request_mem_region
(
mem
->
start
,
resource_size
(
mem
),
pdev
->
name
);
if
(
!
mem
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to request mmio memory region
\n
"
);
ret
=
-
EBUSY
;
goto
err_out
;
}
base
=
devm_request_and_ioremap
(
&
pdev
->
dev
,
mem
);
if
(
!
base
)
return
-
EBUSY
;
jz4740_codec
->
base
=
ioremap
(
mem
->
start
,
resource_size
(
mem
));
if
(
!
jz4740_codec
->
base
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to ioremap mmio memory
\n
"
);
ret
=
-
EBUSY
;
goto
err_release_mem_region
;
}
jz4740_codec
->
mem
=
mem
;
jz4740_codec
->
regmap
=
devm_regmap_init_mmio
(
&
pdev
->
dev
,
base
,
&
jz4740_codec_regmap_config
);
if
(
IS_ERR
(
jz4740_codec
->
regmap
))
return
PTR_ERR
(
jz4740_codec
->
regmap
);
platform_set_drvdata
(
pdev
,
jz4740_codec
);
ret
=
snd_soc_register_codec
(
&
pdev
->
dev
,
&
soc_codec_dev_jz4740_codec
,
&
jz4740_codec_dai
,
1
);
if
(
ret
)
{
if
(
ret
)
dev_err
(
&
pdev
->
dev
,
"Failed to register codec
\n
"
);
goto
err_iounmap
;
}
return
0
;
err_iounmap:
iounmap
(
jz4740_codec
->
base
);
err_release_mem_region:
release_mem_region
(
mem
->
start
,
resource_size
(
mem
));
err_out:
return
ret
;
}
static
int
__devexit
jz4740_codec_remove
(
struct
platform_device
*
pdev
)
{
struct
jz4740_codec
*
jz4740_codec
=
platform_get_drvdata
(
pdev
);
struct
resource
*
mem
=
jz4740_codec
->
mem
;
snd_soc_unregister_codec
(
&
pdev
->
dev
);
iounmap
(
jz4740_codec
->
base
);
release_mem_region
(
mem
->
start
,
resource_size
(
mem
));
platform_set_drvdata
(
pdev
,
NULL
);
return
0
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录