Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
3cabd442
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
3cabd442
编写于
10月 24, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/tlv320aic26' into asoc-next
上级
2b48f86b
7fbdeb80
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
28 addition
and
116 deletion
+28
-116
sound/soc/codecs/tlv320aic26.c
sound/soc/codecs/tlv320aic26.c
+27
-112
sound/soc/codecs/tlv320aic26.h
sound/soc/codecs/tlv320aic26.h
+1
-4
未找到文件。
sound/soc/codecs/tlv320aic26.c
浏览文件 @
3cabd442
...
...
@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL");
/* AIC26 driver private data */
struct
aic26
{
struct
spi_device
*
spi
;
struct
regmap
*
regmap
;
struct
snd_soc_codec
*
codec
;
int
master
;
int
datfm
;
...
...
@@ -40,85 +41,6 @@ struct aic26 {
int
keyclick_len
;
};
/* ---------------------------------------------------------------------
* Register access routines
*/
static
unsigned
int
aic26_reg_read
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
)
{
struct
aic26
*
aic26
=
snd_soc_codec_get_drvdata
(
codec
);
u16
*
cache
=
codec
->
reg_cache
;
u16
cmd
,
value
;
u8
buffer
[
2
];
int
rc
;
if
(
reg
>=
AIC26_NUM_REGS
)
{
WARN_ON_ONCE
(
1
);
return
0
;
}
/* Do SPI transfer; first 16bits are command; remaining is
* register contents */
cmd
=
AIC26_READ_COMMAND_WORD
(
reg
);
buffer
[
0
]
=
(
cmd
>>
8
)
&
0xff
;
buffer
[
1
]
=
cmd
&
0xff
;
rc
=
spi_write_then_read
(
aic26
->
spi
,
buffer
,
2
,
buffer
,
2
);
if
(
rc
)
{
dev_err
(
&
aic26
->
spi
->
dev
,
"AIC26 reg read error
\n
"
);
return
-
EIO
;
}
value
=
(
buffer
[
0
]
<<
8
)
|
buffer
[
1
];
/* Update the cache before returning with the value */
cache
[
reg
]
=
value
;
return
value
;
}
static
unsigned
int
aic26_reg_read_cache
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
)
{
u16
*
cache
=
codec
->
reg_cache
;
if
(
reg
>=
AIC26_NUM_REGS
)
{
WARN_ON_ONCE
(
1
);
return
0
;
}
return
cache
[
reg
];
}
static
int
aic26_reg_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
value
)
{
struct
aic26
*
aic26
=
snd_soc_codec_get_drvdata
(
codec
);
u16
*
cache
=
codec
->
reg_cache
;
u16
cmd
;
u8
buffer
[
4
];
int
rc
;
if
(
reg
>=
AIC26_NUM_REGS
)
{
WARN_ON_ONCE
(
1
);
return
-
EINVAL
;
}
/* Do SPI transfer; first 16bits are command; remaining is data
* to write into register */
cmd
=
AIC26_WRITE_COMMAND_WORD
(
reg
);
buffer
[
0
]
=
(
cmd
>>
8
)
&
0xff
;
buffer
[
1
]
=
cmd
&
0xff
;
buffer
[
2
]
=
value
>>
8
;
buffer
[
3
]
=
value
;
rc
=
spi_write
(
aic26
->
spi
,
buffer
,
4
);
if
(
rc
)
{
dev_err
(
&
aic26
->
spi
->
dev
,
"AIC26 reg read error
\n
"
);
return
-
EIO
;
}
/* update cache before returning */
cache
[
reg
]
=
value
;
return
0
;
}
static
const
struct
snd_soc_dapm_widget
tlv320aic26_dapm_widgets
[]
=
{
SND_SOC_DAPM_INPUT
(
"MICIN"
),
SND_SOC_DAPM_INPUT
(
"AUX"
),
...
...
@@ -195,19 +117,15 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
snd_soc_write
(
codec
,
AIC26_REG_PLL_PROG2
,
reg
);
/* Audio Control 3 (master mode, fsref rate) */
reg
=
aic26_reg_read_cache
(
codec
,
AIC26_REG_AUDIO_CTRL3
);
reg
&=
~
0xf800
;
if
(
aic26
->
master
)
reg
|
=
0x0800
;
reg
=
0x0800
;
if
(
fsref
==
48000
)
reg
|
=
0x2000
;
snd_soc_
write
(
codec
,
AIC26_REG_AUDIO_CTRL3
,
reg
);
reg
=
0x2000
;
snd_soc_
update_bits
(
codec
,
AIC26_REG_AUDIO_CTRL3
,
0xf800
,
reg
);
/* Audio Control 1 (FSref divisor) */
reg
=
aic26_reg_read_cache
(
codec
,
AIC26_REG_AUDIO_CTRL1
);
reg
&=
~
0x0fff
;
reg
|=
wlen
|
aic26
->
datfm
|
(
divisor
<<
3
)
|
divisor
;
snd_soc_write
(
codec
,
AIC26_REG_AUDIO_CTRL1
,
reg
);
reg
=
wlen
|
aic26
->
datfm
|
(
divisor
<<
3
)
|
divisor
;
snd_soc_update_bits
(
codec
,
AIC26_REG_AUDIO_CTRL1
,
0xfff
,
reg
);
return
0
;
}
...
...
@@ -219,16 +137,16 @@ static int aic26_mute(struct snd_soc_dai *dai, int mute)
{
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
struct
aic26
*
aic26
=
snd_soc_codec_get_drvdata
(
codec
);
u16
reg
=
aic26_reg_read_cache
(
codec
,
AIC26_REG_DAC_GAIN
)
;
u16
reg
;
dev_dbg
(
&
aic26
->
spi
->
dev
,
"aic26_mute(dai=%p, mute=%i)
\n
"
,
dai
,
mute
);
if
(
mute
)
reg
|
=
0x8080
;
reg
=
0x8080
;
else
reg
&=
~
0x808
0
;
snd_soc_
write
(
codec
,
AIC26_REG_DAC_GAIN
,
reg
);
reg
=
0
;
snd_soc_
update_bits
(
codec
,
AIC26_REG_DAC_GAIN
,
0x8000
,
reg
);
return
0
;
}
...
...
@@ -346,7 +264,7 @@ static ssize_t aic26_keyclick_show(struct device *dev,
struct
aic26
*
aic26
=
dev_get_drvdata
(
dev
);
int
val
,
amp
,
freq
,
len
;
val
=
aic26_reg_read_cache
(
aic26
->
codec
,
AIC26_REG_AUDIO_CTRL2
);
val
=
snd_soc_read
(
aic26
->
codec
,
AIC26_REG_AUDIO_CTRL2
);
amp
=
(
val
>>
12
)
&
0x7
;
freq
=
(
125
<<
((
val
>>
8
)
&
0x7
))
>>
1
;
len
=
2
*
(
1
+
((
val
>>
4
)
&
0xf
));
...
...
@@ -360,11 +278,9 @@ static ssize_t aic26_keyclick_set(struct device *dev,
const
char
*
buf
,
size_t
count
)
{
struct
aic26
*
aic26
=
dev_get_drvdata
(
dev
);
int
val
;
val
=
aic26_reg_read_cache
(
aic26
->
codec
,
AIC26_REG_AUDIO_CTRL2
);
val
|=
0x8000
;
snd_soc_write
(
aic26
->
codec
,
AIC26_REG_AUDIO_CTRL2
,
val
);
snd_soc_update_bits
(
aic26
->
codec
,
AIC26_REG_AUDIO_CTRL2
,
0x8000
,
0x800
);
return
count
;
}
...
...
@@ -377,7 +293,9 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
static
int
aic26_probe
(
struct
snd_soc_codec
*
codec
)
{
struct
aic26
*
aic26
=
dev_get_drvdata
(
codec
->
dev
);
int
ret
,
err
,
i
,
reg
;
int
ret
,
reg
;
snd_soc_codec_set_cache_io
(
codec
,
16
,
16
,
SND_SOC_REGMAP
);
aic26
->
codec
=
codec
;
...
...
@@ -393,37 +311,30 @@ static int aic26_probe(struct snd_soc_codec *codec)
reg
|=
0x0800
;
/* set master mode */
snd_soc_write
(
codec
,
AIC26_REG_AUDIO_CTRL3
,
reg
);
/* Fill register cache */
for
(
i
=
0
;
i
<
codec
->
driver
->
reg_cache_size
;
i
++
)
snd_soc_read
(
codec
,
i
);
/* Register the sysfs files for debugging */
/* Create SysFS files */
ret
=
device_create_file
(
codec
->
dev
,
&
dev_attr_keyclick
);
if
(
ret
)
dev_info
(
codec
->
dev
,
"error creating sysfs files
\n
"
);
/* register controls */
dev_dbg
(
codec
->
dev
,
"Registering controls
\n
"
);
err
=
snd_soc_add_codec_controls
(
codec
,
aic26_snd_controls
,
ARRAY_SIZE
(
aic26_snd_controls
));
WARN_ON
(
err
<
0
);
return
0
;
}
static
struct
snd_soc_codec_driver
aic26_soc_codec_dev
=
{
.
probe
=
aic26_probe
,
.
read
=
aic26_reg_read
,
.
write
=
aic26_reg_write
,
.
reg_cache_size
=
AIC26_NUM_REGS
,
.
reg_word_size
=
sizeof
(
u16
),
.
controls
=
aic26_snd_controls
,
.
num_controls
=
ARRAY_SIZE
(
aic26_snd_controls
),
.
dapm_widgets
=
tlv320aic26_dapm_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
tlv320aic26_dapm_widgets
),
.
dapm_routes
=
tlv320aic26_dapm_routes
,
.
num_dapm_routes
=
ARRAY_SIZE
(
tlv320aic26_dapm_routes
),
};
static
const
struct
regmap_config
aic26_regmap
=
{
.
reg_bits
=
16
,
.
val_bits
=
16
,
};
/* ---------------------------------------------------------------------
* SPI device portion of driver: probe and release routines and SPI
* driver registration.
...
...
@@ -440,6 +351,10 @@ static int aic26_spi_probe(struct spi_device *spi)
if
(
!
aic26
)
return
-
ENOMEM
;
aic26
->
regmap
=
devm_regmap_init_spi
(
spi
,
&
aic26_regmap
);
if
(
IS_ERR
(
aic26
->
regmap
))
return
PTR_ERR
(
aic26
->
regmap
);
/* Initialize the driver data */
aic26
->
spi
=
spi
;
dev_set_drvdata
(
&
spi
->
dev
,
aic26
);
...
...
sound/soc/codecs/tlv320aic26.h
浏览文件 @
3cabd442
...
...
@@ -9,10 +9,7 @@
#define _TLV320AIC16_H_
/* AIC26 Registers */
#define AIC26_READ_COMMAND_WORD(addr) ((1 << 15) | (addr << 5))
#define AIC26_WRITE_COMMAND_WORD(addr) ((0 << 15) | (addr << 5))
#define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset)
#define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0)
#define AIC26_PAGE_ADDR(page, offset) ((page << 11) | offset << 5)
/* Page 0: Auxiliary data registers */
#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录