Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
bb3784ae
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
bb3784ae
编写于
8月 08, 2011
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'regmap-asoc' into for-3.2
上级
18d4ed43
0671da18
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
42 addition
and
284 deletion
+42
-284
include/sound/soc.h
include/sound/soc.h
+3
-0
sound/soc/Kconfig
sound/soc/Kconfig
+2
-0
sound/soc/soc-io.c
sound/soc/soc-io.c
+37
-284
未找到文件。
include/sound/soc.h
浏览文件 @
bb3784ae
...
...
@@ -19,6 +19,7 @@
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/control.h>
...
...
@@ -260,6 +261,7 @@ extern struct snd_ac97_bus_ops soc_ac97_ops;
enum
snd_soc_control_type
{
SND_SOC_I2C
=
1
,
SND_SOC_SPI
,
SND_SOC_REGMAP
,
};
enum
snd_soc_compress_type
{
...
...
@@ -576,6 +578,7 @@ struct snd_soc_codec {
const
void
*
reg_def_copy
;
const
struct
snd_soc_cache_ops
*
cache_ops
;
struct
mutex
cache_rw_mutex
;
int
val_bytes
;
/* dapm */
struct
snd_soc_dapm_context
dapm
;
...
...
sound/soc/Kconfig
浏览文件 @
bb3784ae
...
...
@@ -7,6 +7,8 @@ menuconfig SND_SOC
select SND_PCM
select AC97_BUS if SND_SOC_AC97_BUS
select SND_JACK if INPUT=y || INPUT=SND
select REGMAP_I2C if I2C
select REGMAP_SPI if SPI_MASTER
---help---
If you want ASoC support, you should say Y here and also to the
...
...
sound/soc/soc-io.c
浏览文件 @
bb3784ae
...
...
@@ -13,26 +13,13 @@
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/regmap.h>
#include <sound/soc.h>
#include <trace/events/asoc.h>
#ifdef CONFIG_SPI_MASTER
static
int
do_spi_write
(
void
*
control
,
const
char
*
data
,
int
len
)
{
struct
spi_device
*
spi
=
control
;
int
ret
;
ret
=
spi_write
(
spi
,
data
,
len
);
if
(
ret
<
0
)
return
ret
;
return
len
;
}
#endif
static
int
do_hw_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
value
,
const
void
*
data
,
int
len
)
static
int
hw_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
value
)
{
int
ret
;
...
...
@@ -49,13 +36,7 @@ static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
return
0
;
}
ret
=
codec
->
hw_write
(
codec
->
control_data
,
data
,
len
);
if
(
ret
==
len
)
return
0
;
if
(
ret
<
0
)
return
ret
;
else
return
-
EIO
;
return
regmap_write
(
codec
->
control_data
,
reg
,
value
);
}
static
unsigned
int
hw_read
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
)
...
...
@@ -69,8 +50,11 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
if
(
codec
->
cache_only
)
return
-
1
;
BUG_ON
(
!
codec
->
hw_read
);
return
codec
->
hw_read
(
codec
,
reg
);
ret
=
regmap_read
(
codec
->
control_data
,
reg
,
&
val
);
if
(
ret
==
0
)
return
val
;
else
return
ret
;
}
ret
=
snd_soc_cache_read
(
codec
,
reg
,
&
val
);
...
...
@@ -79,183 +63,18 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
return
val
;
}
static
int
snd_soc_4_12_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
value
)
{
u16
data
;
data
=
cpu_to_be16
((
reg
<<
12
)
|
(
value
&
0xffffff
));
return
do_hw_write
(
codec
,
reg
,
value
,
&
data
,
2
);
}
static
int
snd_soc_7_9_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
value
)
{
u16
data
;
data
=
cpu_to_be16
((
reg
<<
9
)
|
(
value
&
0x1ff
));
return
do_hw_write
(
codec
,
reg
,
value
,
&
data
,
2
);
}
static
int
snd_soc_8_8_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
value
)
{
u8
data
[
2
];
reg
&=
0xff
;
data
[
0
]
=
reg
;
data
[
1
]
=
value
&
0xff
;
return
do_hw_write
(
codec
,
reg
,
value
,
data
,
2
);
}
static
int
snd_soc_8_16_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
value
)
{
u8
data
[
3
];
u16
val
=
cpu_to_be16
(
value
);
data
[
0
]
=
reg
;
memcpy
(
&
data
[
1
],
&
val
,
sizeof
(
val
));
return
do_hw_write
(
codec
,
reg
,
value
,
data
,
3
);
}
#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
static
unsigned
int
do_i2c_read
(
struct
snd_soc_codec
*
codec
,
void
*
reg
,
int
reglen
,
void
*
data
,
int
datalen
)
{
struct
i2c_msg
xfer
[
2
];
int
ret
;
struct
i2c_client
*
client
=
codec
->
control_data
;
/* Write register */
xfer
[
0
].
addr
=
client
->
addr
;
xfer
[
0
].
flags
=
0
;
xfer
[
0
].
len
=
reglen
;
xfer
[
0
].
buf
=
reg
;
/* Read data */
xfer
[
1
].
addr
=
client
->
addr
;
xfer
[
1
].
flags
=
I2C_M_RD
;
xfer
[
1
].
len
=
datalen
;
xfer
[
1
].
buf
=
data
;
ret
=
i2c_transfer
(
client
->
adapter
,
xfer
,
2
);
if
(
ret
==
2
)
return
0
;
else
if
(
ret
<
0
)
return
ret
;
else
return
-
EIO
;
}
#endif
#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
static
unsigned
int
snd_soc_8_8_read_i2c
(
struct
snd_soc_codec
*
codec
,
unsigned
int
r
)
{
u8
reg
=
r
;
u8
data
;
int
ret
;
ret
=
do_i2c_read
(
codec
,
&
reg
,
1
,
&
data
,
1
);
if
(
ret
<
0
)
return
0
;
return
data
;
}
#else
#define snd_soc_8_8_read_i2c NULL
#endif
#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
static
unsigned
int
snd_soc_8_16_read_i2c
(
struct
snd_soc_codec
*
codec
,
unsigned
int
r
)
{
u8
reg
=
r
;
u16
data
;
int
ret
;
ret
=
do_i2c_read
(
codec
,
&
reg
,
1
,
&
data
,
2
);
if
(
ret
<
0
)
return
0
;
return
(
data
>>
8
)
|
((
data
&
0xff
)
<<
8
);
}
#else
#define snd_soc_8_16_read_i2c NULL
#endif
#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
static
unsigned
int
snd_soc_16_8_read_i2c
(
struct
snd_soc_codec
*
codec
,
unsigned
int
r
)
{
u16
reg
=
r
;
u8
data
;
int
ret
;
ret
=
do_i2c_read
(
codec
,
&
reg
,
2
,
&
data
,
1
);
if
(
ret
<
0
)
return
0
;
return
data
;
}
#else
#define snd_soc_16_8_read_i2c NULL
#endif
static
int
snd_soc_16_8_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
value
)
{
u8
data
[
3
];
u16
rval
=
cpu_to_be16
(
reg
);
memcpy
(
data
,
&
rval
,
sizeof
(
rval
));
data
[
2
]
=
value
;
return
do_hw_write
(
codec
,
reg
,
value
,
data
,
3
);
}
#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
static
unsigned
int
snd_soc_16_16_read_i2c
(
struct
snd_soc_codec
*
codec
,
unsigned
int
r
)
{
u16
reg
=
cpu_to_be16
(
r
);
u16
data
;
int
ret
;
ret
=
do_i2c_read
(
codec
,
&
reg
,
2
,
&
data
,
2
);
if
(
ret
<
0
)
return
0
;
return
be16_to_cpu
(
data
);
}
#else
#define snd_soc_16_16_read_i2c NULL
#endif
static
int
snd_soc_16_16_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
value
)
{
u16
data
[
2
];
data
[
0
]
=
cpu_to_be16
(
reg
);
data
[
1
]
=
cpu_to_be16
(
value
);
return
do_hw_write
(
codec
,
reg
,
value
,
data
,
sizeof
(
data
));
}
/* Primitive bulk write support for soc-cache. The data pointed to by
* `data' needs to already be in the form the hardware expects
* including any leading register specific data. Any data written
* through this function will not go through the cache as it only
* handles writing to volatile or out of bounds registers.
* `data' needs to already be in the form the hardware expects. Any
* data written through this function will not go through the cache as
* it only handles writing to volatile or out of bounds registers.
*
* This is currently only supported for devices using the regmap API
* wrappers.
*/
static
int
snd_soc_hw_bulk_write_raw
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
static
int
snd_soc_hw_bulk_write_raw
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
const
void
*
data
,
size_t
len
)
{
int
ret
;
/* To ensure that we don't get out of sync with the cache, check
* whether the base register is volatile or if we've directly asked
* to bypass the cache. Out of bounds registers are considered
...
...
@@ -266,66 +85,9 @@ static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int r
&&
reg
<
codec
->
driver
->
reg_cache_size
)
return
-
EINVAL
;
switch
(
codec
->
control_type
)
{
#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
case
SND_SOC_I2C
:
ret
=
i2c_master_send
(
to_i2c_client
(
codec
->
dev
),
data
,
len
);
break
;
#endif
#if defined(CONFIG_SPI_MASTER)
case
SND_SOC_SPI
:
ret
=
spi_write
(
to_spi_device
(
codec
->
dev
),
data
,
len
);
break
;
#endif
default:
BUG
();
}
if
(
ret
==
len
)
return
0
;
if
(
ret
<
0
)
return
ret
;
else
return
-
EIO
;
return
regmap_raw_write
(
codec
->
control_data
,
reg
,
data
,
len
);
}
static
struct
{
int
addr_bits
;
int
data_bits
;
int
(
*
write
)(
struct
snd_soc_codec
*
codec
,
unsigned
int
,
unsigned
int
);
unsigned
int
(
*
read
)(
struct
snd_soc_codec
*
,
unsigned
int
);
unsigned
int
(
*
i2c_read
)(
struct
snd_soc_codec
*
,
unsigned
int
);
}
io_types
[]
=
{
{
.
addr_bits
=
4
,
.
data_bits
=
12
,
.
write
=
snd_soc_4_12_write
,
},
{
.
addr_bits
=
7
,
.
data_bits
=
9
,
.
write
=
snd_soc_7_9_write
,
},
{
.
addr_bits
=
8
,
.
data_bits
=
8
,
.
write
=
snd_soc_8_8_write
,
.
i2c_read
=
snd_soc_8_8_read_i2c
,
},
{
.
addr_bits
=
8
,
.
data_bits
=
16
,
.
write
=
snd_soc_8_16_write
,
.
i2c_read
=
snd_soc_8_16_read_i2c
,
},
{
.
addr_bits
=
16
,
.
data_bits
=
8
,
.
write
=
snd_soc_16_8_write
,
.
i2c_read
=
snd_soc_16_8_read_i2c
,
},
{
.
addr_bits
=
16
,
.
data_bits
=
16
,
.
write
=
snd_soc_16_16_write
,
.
i2c_read
=
snd_soc_16_16_read_i2c
,
},
};
/**
* snd_soc_codec_set_cache_io: Set up standard I/O functions.
*
...
...
@@ -349,47 +111,38 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
int
addr_bits
,
int
data_bits
,
enum
snd_soc_control_type
control
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
io_types
);
i
++
)
if
(
io_types
[
i
].
addr_bits
==
addr_bits
&&
io_types
[
i
].
data_bits
==
data_bits
)
break
;
if
(
i
==
ARRAY_SIZE
(
io_types
))
{
printk
(
KERN_ERR
"No I/O functions for %d bit address %d bit data
\n
"
,
addr_bits
,
data_bits
);
return
-
EINVAL
;
}
struct
regmap_config
config
;
codec
->
write
=
io_types
[
i
].
write
;
memset
(
&
config
,
0
,
sizeof
(
config
));
codec
->
write
=
hw_write
;
codec
->
read
=
hw_read
;
codec
->
bulk_write_raw
=
snd_soc_hw_bulk_write_raw
;
config
.
reg_bits
=
addr_bits
;
config
.
val_bits
=
data_bits
;
switch
(
control
)
{
case
SND_SOC_I2C
:
#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
codec
->
hw_write
=
(
hw_write_t
)
i2c_master_send
;
#endif
if
(
io_types
[
i
].
i2c_read
)
codec
->
hw_read
=
io_types
[
i
].
i2c_read
;
codec
->
control_data
=
container_of
(
codec
->
dev
,
struct
i2c_client
,
dev
);
codec
->
control_data
=
regmap_init_i2c
(
to_i2c_client
(
codec
->
dev
),
&
config
);
break
;
case
SND_SOC_SPI
:
#ifdef CONFIG_SPI_MASTER
codec
->
hw_write
=
do_spi_write
;
#endif
codec
->
control_data
=
regmap_init_spi
(
to_spi_device
(
codec
->
dev
),
&
config
)
;
break
;
codec
->
control_data
=
container_of
(
codec
->
dev
,
struct
spi_device
,
dev
);
case
SND_SOC_REGMAP
:
/* Device has made its own regmap arrangements */
break
;
default:
return
-
EINVAL
;
}
if
(
IS_ERR
(
codec
->
control_data
))
return
PTR_ERR
(
codec
->
control_data
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_codec_set_cache_io
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录