Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
c41788c0
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看板
提交
c41788c0
编写于
8月 22, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/samsung' into asoc-next
上级
3f151cbf
06b10ff9
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
248 addition
and
137 deletion
+248
-137
Documentation/devicetree/bindings/sound/samsung-i2s.txt
Documentation/devicetree/bindings/sound/samsung-i2s.txt
+10
-12
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5250.dtsi
+3
-6
include/linux/platform_data/asoc-s3c.h
include/linux/platform_data/asoc-s3c.h
+1
-0
sound/soc/samsung/ac97.c
sound/soc/samsung/ac97.c
+3
-8
sound/soc/samsung/dma.c
sound/soc/samsung/dma.c
+8
-4
sound/soc/samsung/dma.h
sound/soc/samsung/dma.h
+2
-2
sound/soc/samsung/i2s-regs.h
sound/soc/samsung/i2s-regs.h
+35
-16
sound/soc/samsung/i2s.c
sound/soc/samsung/i2s.c
+141
-52
sound/soc/samsung/pcm.c
sound/soc/samsung/pcm.c
+2
-2
sound/soc/samsung/s3c2412-i2s.c
sound/soc/samsung/s3c2412-i2s.c
+2
-2
sound/soc/samsung/s3c24xx-i2s.c
sound/soc/samsung/s3c24xx-i2s.c
+2
-2
sound/soc/samsung/smdk_wm8994.c
sound/soc/samsung/smdk_wm8994.c
+35
-23
sound/soc/samsung/spdif.c
sound/soc/samsung/spdif.c
+4
-8
未找到文件。
Documentation/devicetree/bindings/sound/samsung-i2s.txt
浏览文件 @
c41788c0
...
...
@@ -2,7 +2,15 @@
Required SoC Specific Properties:
- compatible : "samsung,i2s-v5"
- compatible : should be one of the following.
- samsung,s3c6410-i2s: for 8/16/24bit stereo I2S.
- samsung,s5pv210-i2s: for 8/16/24bit multichannel(5.1) I2S with
secondary fifo, s/w reset control and internal mux for root clk src.
- samsung,exynos5420-i2s: for 8/16/24bit multichannel(7.1) I2S with
secondary fifo, s/w reset control, internal mux for root clk src and
TDM support. TDM (Time division multiplexing) is to allow transfer of
multiple channel audio data on single data line.
- reg: physical base address of the controller and length of memory mapped
region.
- dmas: list of DMA controller phandle and DMA request line ordered pairs.
...
...
@@ -21,13 +29,6 @@ Required SoC Specific Properties:
Optional SoC Specific Properties:
- samsung,supports-6ch: If the I2S Primary sound source has 5.1 Channel
support, this flag is enabled.
- samsung,supports-rstclr: This flag should be set if I2S software reset bit
control is required. When this flag is set I2S software reset bit will be
enabled or disabled based on need.
- samsung,supports-secdai:If I2S block has a secondary FIFO and internal DMA,
then this flag is enabled.
- samsung,idma-addr: Internal DMA register base address of the audio
sub system(used in secondary sound source).
- pinctrl-0: Should specify pin control groups used for this controller.
...
...
@@ -36,7 +37,7 @@ Optional SoC Specific Properties:
Example:
i2s0: i2s@03830000 {
compatible = "samsung,
i2s-v5
";
compatible = "samsung,
s5pv210-i2s
";
reg = <0x03830000 0x100>;
dmas = <&pdma0 10
&pdma0 9
...
...
@@ -46,9 +47,6 @@ i2s0: i2s@03830000 {
<&clock_audss EXYNOS_I2S_BUS>,
<&clock_audss EXYNOS_SCLK_I2S>;
clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
samsung,supports-6ch;
samsung,supports-rstclr;
samsung,supports-secdai;
samsung,idma-addr = <0x03000000>;
pinctrl-names = "default";
pinctrl-0 = <&i2s0_bus>;
...
...
arch/arm/boot/dts/exynos5250.dtsi
浏览文件 @
c41788c0
...
...
@@ -405,7 +405,7 @@
};
i2s0: i2s@03830000 {
compatible = "samsung,
i2s-v5
";
compatible = "samsung,
s5pv210-i2s
";
reg = <0x03830000 0x100>;
dmas = <&pdma0 10
&pdma0 9
...
...
@@ -415,16 +415,13 @@
<&clock_audss EXYNOS_I2S_BUS>,
<&clock_audss EXYNOS_SCLK_I2S>;
clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
samsung,supports-6ch;
samsung,supports-rstclr;
samsung,supports-secdai;
samsung,idma-addr = <0x03000000>;
pinctrl-names = "default";
pinctrl-0 = <&i2s0_bus>;
};
i2s1: i2s@12D60000 {
compatible = "samsung,
i2s-v5
";
compatible = "samsung,
s3c6410-i2s
";
reg = <0x12D60000 0x100>;
dmas = <&pdma1 12
&pdma1 11>;
...
...
@@ -436,7 +433,7 @@
};
i2s2: i2s@12D70000 {
compatible = "samsung,
i2s-v5
";
compatible = "samsung,
s3c6410-i2s
";
reg = <0x12D70000 0x100>;
dmas = <&pdma0 12
&pdma0 11>;
...
...
include/linux/platform_data/asoc-s3c.h
浏览文件 @
c41788c0
...
...
@@ -36,6 +36,7 @@ struct samsung_i2s {
*/
#define QUIRK_NO_MUXPSR (1 << 2)
#define QUIRK_NEED_RSTCLR (1 << 3)
#define QUIRK_SUPPORTS_TDM (1 << 4)
/* Quirks of the I2S controller */
u32
quirks
;
dma_addr_t
idma_addr
;
...
...
sound/soc/samsung/ac97.c
浏览文件 @
c41788c0
...
...
@@ -404,18 +404,13 @@ static int s3c_ac97_probe(struct platform_device *pdev)
return
-
ENXIO
;
}
mem_res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
mem_res
)
{
dev_err
(
&
pdev
->
dev
,
"Unable to get register resource
\n
"
);
return
-
ENXIO
;
}
irq_res
=
platform_get_resource
(
pdev
,
IORESOURCE_IRQ
,
0
);
if
(
!
irq_res
)
{
dev_err
(
&
pdev
->
dev
,
"AC97 IRQ not provided!
\n
"
);
return
-
ENXIO
;
}
mem_res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
s3c_ac97
.
regs
=
devm_ioremap_resource
(
&
pdev
->
dev
,
mem_res
);
if
(
IS_ERR
(
s3c_ac97
.
regs
))
return
PTR_ERR
(
s3c_ac97
.
regs
);
...
...
@@ -462,7 +457,7 @@ static int s3c_ac97_probe(struct platform_device *pdev)
if
(
ret
)
goto
err5
;
ret
=
asoc_dma_platform_register
(
&
pdev
->
dev
);
ret
=
samsung_
asoc_dma_platform_register
(
&
pdev
->
dev
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get register DMA: %d
\n
"
,
ret
);
goto
err6
;
...
...
@@ -485,7 +480,7 @@ static int s3c_ac97_remove(struct platform_device *pdev)
{
struct
resource
*
irq_res
;
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
samsung_
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
snd_soc_unregister_component
(
&
pdev
->
dev
);
irq_res
=
platform_get_resource
(
pdev
,
IORESOURCE_IRQ
,
0
);
...
...
sound/soc/samsung/dma.c
浏览文件 @
c41788c0
...
...
@@ -176,6 +176,10 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
prtd
->
params
->
ch
=
prtd
->
params
->
ops
->
request
(
prtd
->
params
->
channel
,
&
req
,
rtd
->
cpu_dai
->
dev
,
prtd
->
params
->
ch_name
);
if
(
!
prtd
->
params
->
ch
)
{
pr_err
(
"Failed to allocate DMA channel
\n
"
);
return
-
ENXIO
;
}
prtd
->
params
->
ops
->
config
(
prtd
->
params
->
ch
,
&
config
);
}
...
...
@@ -433,17 +437,17 @@ static struct snd_soc_platform_driver samsung_asoc_platform = {
.
pcm_free
=
dma_free_dma_buffers
,
};
int
asoc_dma_platform_register
(
struct
device
*
dev
)
int
samsung_
asoc_dma_platform_register
(
struct
device
*
dev
)
{
return
snd_soc_register_platform
(
dev
,
&
samsung_asoc_platform
);
}
EXPORT_SYMBOL_GPL
(
asoc_dma_platform_register
);
EXPORT_SYMBOL_GPL
(
samsung_
asoc_dma_platform_register
);
void
asoc_dma_platform_unregister
(
struct
device
*
dev
)
void
samsung_
asoc_dma_platform_unregister
(
struct
device
*
dev
)
{
snd_soc_unregister_platform
(
dev
);
}
EXPORT_SYMBOL_GPL
(
asoc_dma_platform_unregister
);
EXPORT_SYMBOL_GPL
(
samsung_
asoc_dma_platform_unregister
);
MODULE_AUTHOR
(
"Ben Dooks, <ben@simtec.co.uk>"
);
MODULE_DESCRIPTION
(
"Samsung ASoC DMA Driver"
);
...
...
sound/soc/samsung/dma.h
浏览文件 @
c41788c0
...
...
@@ -22,7 +22,7 @@ struct s3c_dma_params {
char
*
ch_name
;
};
int
asoc_dma_platform_register
(
struct
device
*
dev
);
void
asoc_dma_platform_unregister
(
struct
device
*
dev
);
int
samsung_
asoc_dma_platform_register
(
struct
device
*
dev
);
void
samsung_
asoc_dma_platform_unregister
(
struct
device
*
dev
);
#endif
sound/soc/samsung/i2s-regs.h
浏览文件 @
c41788c0
...
...
@@ -31,6 +31,10 @@
#define I2SLVL1ADDR 0x34
#define I2SLVL2ADDR 0x38
#define I2SLVL3ADDR 0x3c
#define I2SSTR1 0x40
#define I2SVER 0x44
#define I2SFIC2 0x48
#define I2STDM 0x4c
#define CON_RSTCLR (1 << 31)
#define CON_FRXOFSTATUS (1 << 26)
...
...
@@ -95,24 +99,39 @@
#define MOD_RXONLY (1 << 8)
#define MOD_TXRX (2 << 8)
#define MOD_MASK (3 << 8)
#define MOD_LR_LLOW (0 << 7)
#define MOD_LR_RLOW (1 << 7)
#define MOD_SDF_IIS (0 << 5)
#define MOD_SDF_MSB (1 << 5)
#define MOD_SDF_LSB (2 << 5)
#define MOD_SDF_MASK (3 << 5)
#define MOD_RCLK_256FS (0 << 3)
#define MOD_RCLK_512FS (1 << 3)
#define MOD_RCLK_384FS (2 << 3)
#define MOD_RCLK_768FS (3 << 3)
#define MOD_RCLK_MASK (3 << 3)
#define MOD_BCLK_32FS (0 << 1)
#define MOD_BCLK_48FS (1 << 1)
#define MOD_BCLK_16FS (2 << 1)
#define MOD_BCLK_24FS (3 << 1)
#define MOD_BCLK_MASK (3 << 1)
#define MOD_LRP_SHIFT 7
#define MOD_LR_LLOW 0
#define MOD_LR_RLOW 1
#define MOD_SDF_SHIFT 5
#define MOD_SDF_IIS 0
#define MOD_SDF_MSB 1
#define MOD_SDF_LSB 2
#define MOD_SDF_MASK 3
#define MOD_RCLK_SHIFT 3
#define MOD_RCLK_256FS 0
#define MOD_RCLK_512FS 1
#define MOD_RCLK_384FS 2
#define MOD_RCLK_768FS 3
#define MOD_RCLK_MASK 3
#define MOD_BCLK_SHIFT 1
#define MOD_BCLK_32FS 0
#define MOD_BCLK_48FS 1
#define MOD_BCLK_16FS 2
#define MOD_BCLK_24FS 3
#define MOD_BCLK_MASK 3
#define MOD_8BIT (1 << 0)
#define EXYNOS5420_MOD_LRP_SHIFT 15
#define EXYNOS5420_MOD_SDF_SHIFT 6
#define EXYNOS5420_MOD_RCLK_SHIFT 4
#define EXYNOS5420_MOD_BCLK_SHIFT 0
#define EXYNOS5420_MOD_BCLK_64FS 4
#define EXYNOS5420_MOD_BCLK_96FS 5
#define EXYNOS5420_MOD_BCLK_128FS 6
#define EXYNOS5420_MOD_BCLK_192FS 7
#define EXYNOS5420_MOD_BCLK_256FS 8
#define EXYNOS5420_MOD_BCLK_MASK 0xf
#define MOD_CDCLKCON (1 << 12)
#define PSR_PSREN (1 << 15)
...
...
sound/soc/samsung/i2s.c
浏览文件 @
c41788c0
...
...
@@ -40,6 +40,7 @@ enum samsung_dai_type {
struct
samsung_i2s_dai_data
{
int
dai_type
;
u32
quirks
;
};
struct
i2s_dai
{
...
...
@@ -198,7 +199,13 @@ static inline bool is_manager(struct i2s_dai *i2s)
/* Read RCLK of I2S (in multiples of LRCLK) */
static
inline
unsigned
get_rfs
(
struct
i2s_dai
*
i2s
)
{
u32
rfs
=
(
readl
(
i2s
->
addr
+
I2SMOD
)
>>
3
)
&
0x3
;
u32
rfs
;
if
(
i2s
->
quirks
&
QUIRK_SUPPORTS_TDM
)
rfs
=
readl
(
i2s
->
addr
+
I2SMOD
)
>>
EXYNOS5420_MOD_RCLK_SHIFT
;
else
rfs
=
(
readl
(
i2s
->
addr
+
I2SMOD
)
>>
MOD_RCLK_SHIFT
);
rfs
&=
MOD_RCLK_MASK
;
switch
(
rfs
)
{
case
3
:
return
768
;
...
...
@@ -212,21 +219,26 @@ static inline unsigned get_rfs(struct i2s_dai *i2s)
static
inline
void
set_rfs
(
struct
i2s_dai
*
i2s
,
unsigned
rfs
)
{
u32
mod
=
readl
(
i2s
->
addr
+
I2SMOD
);
int
rfs_shift
;
mod
&=
~
MOD_RCLK_MASK
;
if
(
i2s
->
quirks
&
QUIRK_SUPPORTS_TDM
)
rfs_shift
=
EXYNOS5420_MOD_RCLK_SHIFT
;
else
rfs_shift
=
MOD_RCLK_SHIFT
;
mod
&=
~
(
MOD_RCLK_MASK
<<
rfs_shift
);
switch
(
rfs
)
{
case
768
:
mod
|=
MOD_RCLK_768FS
;
mod
|=
(
MOD_RCLK_768FS
<<
rfs_shift
)
;
break
;
case
512
:
mod
|=
MOD_RCLK_512FS
;
mod
|=
(
MOD_RCLK_512FS
<<
rfs_shift
)
;
break
;
case
384
:
mod
|=
MOD_RCLK_384FS
;
mod
|=
(
MOD_RCLK_384FS
<<
rfs_shift
)
;
break
;
default:
mod
|=
MOD_RCLK_256FS
;
mod
|=
(
MOD_RCLK_256FS
<<
rfs_shift
)
;
break
;
}
...
...
@@ -236,9 +248,22 @@ static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
/* Read Bit-Clock of I2S (in multiples of LRCLK) */
static
inline
unsigned
get_bfs
(
struct
i2s_dai
*
i2s
)
{
u32
bfs
=
(
readl
(
i2s
->
addr
+
I2SMOD
)
>>
1
)
&
0x3
;
u32
bfs
;
if
(
i2s
->
quirks
&
QUIRK_SUPPORTS_TDM
)
{
bfs
=
readl
(
i2s
->
addr
+
I2SMOD
)
>>
EXYNOS5420_MOD_BCLK_SHIFT
;
bfs
&=
EXYNOS5420_MOD_BCLK_MASK
;
}
else
{
bfs
=
readl
(
i2s
->
addr
+
I2SMOD
)
>>
MOD_BCLK_SHIFT
;
bfs
&=
MOD_BCLK_MASK
;
}
switch
(
bfs
)
{
case
8
:
return
256
;
case
7
:
return
192
;
case
6
:
return
128
;
case
5
:
return
96
;
case
4
:
return
64
;
case
3
:
return
24
;
case
2
:
return
16
;
case
1
:
return
48
;
...
...
@@ -250,21 +275,50 @@ static inline unsigned get_bfs(struct i2s_dai *i2s)
static
inline
void
set_bfs
(
struct
i2s_dai
*
i2s
,
unsigned
bfs
)
{
u32
mod
=
readl
(
i2s
->
addr
+
I2SMOD
);
int
bfs_shift
;
int
tdm
=
i2s
->
quirks
&
QUIRK_SUPPORTS_TDM
;
mod
&=
~
MOD_BCLK_MASK
;
if
(
i2s
->
quirks
&
QUIRK_SUPPORTS_TDM
)
{
bfs_shift
=
EXYNOS5420_MOD_BCLK_SHIFT
;
mod
&=
~
(
EXYNOS5420_MOD_BCLK_MASK
<<
bfs_shift
);
}
else
{
bfs_shift
=
MOD_BCLK_SHIFT
;
mod
&=
~
(
MOD_BCLK_MASK
<<
bfs_shift
);
}
/* Non-TDM I2S controllers do not support BCLK > 48 * FS */
if
(
!
tdm
&&
bfs
>
48
)
{
dev_err
(
&
i2s
->
pdev
->
dev
,
"Unsupported BCLK divider
\n
"
);
return
;
}
switch
(
bfs
)
{
case
48
:
mod
|=
MOD_BCLK_48FS
;
mod
|=
(
MOD_BCLK_48FS
<<
bfs_shift
)
;
break
;
case
32
:
mod
|=
MOD_BCLK_32FS
;
mod
|=
(
MOD_BCLK_32FS
<<
bfs_shift
)
;
break
;
case
24
:
mod
|=
MOD_BCLK_24FS
;
mod
|=
(
MOD_BCLK_24FS
<<
bfs_shift
)
;
break
;
case
16
:
mod
|=
MOD_BCLK_16FS
;
mod
|=
(
MOD_BCLK_16FS
<<
bfs_shift
);
break
;
case
64
:
mod
|=
(
EXYNOS5420_MOD_BCLK_64FS
<<
bfs_shift
);
break
;
case
96
:
mod
|=
(
EXYNOS5420_MOD_BCLK_96FS
<<
bfs_shift
);
break
;
case
128
:
mod
|=
(
EXYNOS5420_MOD_BCLK_128FS
<<
bfs_shift
);
break
;
case
192
:
mod
|=
(
EXYNOS5420_MOD_BCLK_192FS
<<
bfs_shift
);
break
;
case
256
:
mod
|=
(
EXYNOS5420_MOD_BCLK_256FS
<<
bfs_shift
);
break
;
default:
dev_err
(
&
i2s
->
pdev
->
dev
,
"Wrong BCLK Divider!
\n
"
);
...
...
@@ -491,20 +545,32 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
{
struct
i2s_dai
*
i2s
=
to_info
(
dai
);
u32
mod
=
readl
(
i2s
->
addr
+
I2SMOD
);
int
lrp_shift
,
sdf_shift
,
sdf_mask
,
lrp_rlow
;
u32
tmp
=
0
;
if
(
i2s
->
quirks
&
QUIRK_SUPPORTS_TDM
)
{
lrp_shift
=
EXYNOS5420_MOD_LRP_SHIFT
;
sdf_shift
=
EXYNOS5420_MOD_SDF_SHIFT
;
}
else
{
lrp_shift
=
MOD_LRP_SHIFT
;
sdf_shift
=
MOD_SDF_SHIFT
;
}
sdf_mask
=
MOD_SDF_MASK
<<
sdf_shift
;
lrp_rlow
=
MOD_LR_RLOW
<<
lrp_shift
;
/* Format is priority */
switch
(
fmt
&
SND_SOC_DAIFMT_FORMAT_MASK
)
{
case
SND_SOC_DAIFMT_RIGHT_J
:
tmp
|=
MOD_LR_RLOW
;
tmp
|=
MOD_SDF_MSB
;
tmp
|=
lrp_rlow
;
tmp
|=
(
MOD_SDF_MSB
<<
sdf_shift
)
;
break
;
case
SND_SOC_DAIFMT_LEFT_J
:
tmp
|=
MOD_LR_RLOW
;
tmp
|=
MOD_SDF_LSB
;
tmp
|=
lrp_rlow
;
tmp
|=
(
MOD_SDF_LSB
<<
sdf_shift
)
;
break
;
case
SND_SOC_DAIFMT_I2S
:
tmp
|=
MOD_SDF_IIS
;
tmp
|=
(
MOD_SDF_IIS
<<
sdf_shift
)
;
break
;
default:
dev_err
(
&
i2s
->
pdev
->
dev
,
"Format not supported
\n
"
);
...
...
@@ -519,10 +585,10 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
case
SND_SOC_DAIFMT_NB_NF
:
break
;
case
SND_SOC_DAIFMT_NB_IF
:
if
(
tmp
&
MOD_LR_RLOW
)
tmp
&=
~
MOD_LR_RLOW
;
if
(
tmp
&
lrp_rlow
)
tmp
&=
~
lrp_rlow
;
else
tmp
|=
MOD_LR_RLOW
;
tmp
|=
lrp_rlow
;
break
;
default:
dev_err
(
&
i2s
->
pdev
->
dev
,
"Polarity not supported
\n
"
);
...
...
@@ -544,15 +610,18 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
return
-
EINVAL
;
}
/*
* Don't change the I2S mode if any controller is active on this
* channel.
*/
if
(
any_active
(
i2s
)
&&
((
mod
&
(
MOD_SDF_MASK
|
MOD_LR_RLOW
|
MOD_SLAVE
))
!=
tmp
))
{
((
mod
&
(
sdf_mask
|
lrp_rlow
|
MOD_SLAVE
))
!=
tmp
))
{
dev_err
(
&
i2s
->
pdev
->
dev
,
"%s:%d Other DAI busy
\n
"
,
__func__
,
__LINE__
);
return
-
EAGAIN
;
}
mod
&=
~
(
MOD_SDF_MASK
|
MOD_LR_RLOW
|
MOD_SLAVE
);
mod
&=
~
(
sdf_mask
|
lrp_rlow
|
MOD_SLAVE
);
mod
|=
tmp
;
writel
(
mod
,
i2s
->
addr
+
I2SMOD
);
...
...
@@ -1007,6 +1076,8 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
if
(
IS_ERR
(
i2s
->
pdev
))
return
NULL
;
i2s
->
pdev
->
dev
.
parent
=
&
pdev
->
dev
;
platform_set_drvdata
(
i2s
->
pdev
,
i2s
);
ret
=
platform_device_add
(
i2s
->
pdev
);
if
(
ret
<
0
)
...
...
@@ -1018,18 +1089,18 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
static
const
struct
of_device_id
exynos_i2s_match
[];
static
inline
int
samsung_i2s_get_driver_data
(
struct
platform_device
*
pdev
)
static
inline
const
struct
samsung_i2s_dai_data
*
samsung_i2s_get_driver_data
(
struct
platform_device
*
pdev
)
{
#ifdef CONFIG_OF
struct
samsung_i2s_dai_data
*
data
;
if
(
pdev
->
dev
.
of_node
)
{
const
struct
of_device_id
*
match
;
match
=
of_match_node
(
exynos_i2s_match
,
pdev
->
dev
.
of_node
);
data
=
(
struct
samsung_i2s_dai_data
*
)
match
->
data
;
return
data
->
dai_type
;
return
match
->
data
;
}
else
#endif
return
platform_get_device_id
(
pdev
)
->
driver_data
;
return
(
struct
samsung_i2s_dai_data
*
)
platform_get_device_id
(
pdev
)
->
driver_data
;
}
#ifdef CONFIG_PM_RUNTIME
...
...
@@ -1060,13 +1131,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
struct
resource
*
res
;
u32
regs_base
,
quirks
=
0
,
idma_addr
=
0
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
enum
samsung_dai_type
samsung_dai_type
;
const
struct
samsung_i2s_dai_data
*
i2s_dai_data
;
int
ret
=
0
;
/* Call during Seconday interface registration */
samsung_dai_type
=
samsung_i2s_get_driver_data
(
pdev
);
i2s_dai_data
=
samsung_i2s_get_driver_data
(
pdev
);
if
(
samsung_
dai_type
==
TYPE_SEC
)
{
if
(
i2s_dai_data
->
dai_type
==
TYPE_SEC
)
{
sec_dai
=
dev_get_drvdata
(
&
pdev
->
dev
);
if
(
!
sec_dai
)
{
dev_err
(
&
pdev
->
dev
,
"Unable to get drvdata
\n
"
);
...
...
@@ -1075,7 +1146,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
snd_soc_register_component
(
&
sec_dai
->
pdev
->
dev
,
&
samsung_i2s_component
,
&
sec_dai
->
i2s_dai_drv
,
1
);
asoc_dma_platform_register
(
&
pdev
->
dev
);
samsung_
asoc_dma_platform_register
(
&
pdev
->
dev
);
return
0
;
}
...
...
@@ -1115,15 +1186,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
idma_addr
=
i2s_cfg
->
idma_addr
;
}
}
else
{
if
(
of_find_property
(
np
,
"samsung,supports-6ch"
,
NULL
))
quirks
|=
QUIRK_PRI_6CHAN
;
if
(
of_find_property
(
np
,
"samsung,supports-secdai"
,
NULL
))
quirks
|=
QUIRK_SEC_DAI
;
if
(
of_find_property
(
np
,
"samsung,supports-rstclr"
,
NULL
))
quirks
|=
QUIRK_NEED_RSTCLR
;
quirks
=
i2s_dai_data
->
quirks
;
if
(
of_property_read_u32
(
np
,
"samsung,idma-addr"
,
&
idma_addr
))
{
if
(
quirks
&
QUIRK_SEC_DAI
)
{
...
...
@@ -1200,7 +1263,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
pm_runtime_enable
(
&
pdev
->
dev
);
asoc_dma_platform_register
(
&
pdev
->
dev
);
samsung_
asoc_dma_platform_register
(
&
pdev
->
dev
);
return
0
;
err:
...
...
@@ -1230,33 +1293,59 @@ static int samsung_i2s_remove(struct platform_device *pdev)
i2s
->
pri_dai
=
NULL
;
i2s
->
sec_dai
=
NULL
;
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
samsung_
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
snd_soc_unregister_component
(
&
pdev
->
dev
);
return
0
;
}
static
const
struct
samsung_i2s_dai_data
i2sv3_dai_type
=
{
.
dai_type
=
TYPE_PRI
,
.
quirks
=
QUIRK_NO_MUXPSR
,
};
static
const
struct
samsung_i2s_dai_data
i2sv5_dai_type
=
{
.
dai_type
=
TYPE_PRI
,
.
quirks
=
QUIRK_PRI_6CHAN
|
QUIRK_SEC_DAI
|
QUIRK_NEED_RSTCLR
,
};
static
const
struct
samsung_i2s_dai_data
i2sv6_dai_type
=
{
.
dai_type
=
TYPE_PRI
,
.
quirks
=
QUIRK_PRI_6CHAN
|
QUIRK_SEC_DAI
|
QUIRK_NEED_RSTCLR
|
QUIRK_SUPPORTS_TDM
,
};
static
const
struct
samsung_i2s_dai_data
samsung_dai_type_pri
=
{
.
dai_type
=
TYPE_PRI
,
};
static
const
struct
samsung_i2s_dai_data
samsung_dai_type_sec
=
{
.
dai_type
=
TYPE_SEC
,
};
static
struct
platform_device_id
samsung_i2s_driver_ids
[]
=
{
{
.
name
=
"samsung-i2s"
,
.
driver_data
=
TYPE_PRI
,
.
driver_data
=
(
kernel_ulong_t
)
&
samsung_dai_type_pri
,
},
{
.
name
=
"samsung-i2s-sec"
,
.
driver_data
=
TYPE_SEC
,
.
driver_data
=
(
kernel_ulong_t
)
&
samsung_dai_type_sec
,
},
{},
};
MODULE_DEVICE_TABLE
(
platform
,
samsung_i2s_driver_ids
);
#ifdef CONFIG_OF
static
struct
samsung_i2s_dai_data
samsung_i2s_dai_data_array
[]
=
{
[
TYPE_PRI
]
=
{
TYPE_PRI
},
[
TYPE_SEC
]
=
{
TYPE_SEC
},
};
static
const
struct
of_device_id
exynos_i2s_match
[]
=
{
{
.
compatible
=
"samsung,i2s-v5"
,
.
data
=
&
samsung_i2s_dai_data_array
[
TYPE_PRI
],
{
.
compatible
=
"samsung,s3c6410-i2s"
,
.
data
=
&
i2sv3_dai_type
,
},
{
.
compatible
=
"samsung,s5pv210-i2s"
,
.
data
=
&
i2sv5_dai_type
,
},
{
.
compatible
=
"samsung,exynos5420-i2s"
,
.
data
=
&
i2sv6_dai_type
,
},
{},
};
...
...
sound/soc/samsung/pcm.c
浏览文件 @
c41788c0
...
...
@@ -594,7 +594,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
goto
err5
;
}
ret
=
asoc_dma_platform_register
(
&
pdev
->
dev
);
ret
=
samsung_
asoc_dma_platform_register
(
&
pdev
->
dev
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get register DMA: %d
\n
"
,
ret
);
goto
err6
;
...
...
@@ -623,7 +623,7 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev)
struct
s3c_pcm_info
*
pcm
=
&
s3c_pcm
[
pdev
->
id
];
struct
resource
*
mem_res
;
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
samsung_
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
snd_soc_unregister_component
(
&
pdev
->
dev
);
pm_runtime_disable
(
&
pdev
->
dev
);
...
...
sound/soc/samsung/s3c2412-i2s.c
浏览文件 @
c41788c0
...
...
@@ -176,7 +176,7 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
return
ret
;
}
ret
=
asoc_dma_platform_register
(
&
pdev
->
dev
);
ret
=
samsung_
asoc_dma_platform_register
(
&
pdev
->
dev
);
if
(
ret
)
{
pr_err
(
"failed to register the DMA: %d
\n
"
,
ret
);
goto
err
;
...
...
@@ -190,7 +190,7 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
static
int
s3c2412_iis_dev_remove
(
struct
platform_device
*
pdev
)
{
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
samsung_
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
snd_soc_unregister_component
(
&
pdev
->
dev
);
return
0
;
}
...
...
sound/soc/samsung/s3c24xx-i2s.c
浏览文件 @
c41788c0
...
...
@@ -480,7 +480,7 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
return
ret
;
}
ret
=
asoc_dma_platform_register
(
&
pdev
->
dev
);
ret
=
samsung_
asoc_dma_platform_register
(
&
pdev
->
dev
);
if
(
ret
)
{
pr_err
(
"failed to register the dma: %d
\n
"
,
ret
);
goto
err
;
...
...
@@ -494,7 +494,7 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
static
int
s3c24xx_iis_dev_remove
(
struct
platform_device
*
pdev
)
{
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
samsung_
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
snd_soc_unregister_component
(
&
pdev
->
dev
);
return
0
;
}
...
...
sound/soc/samsung/smdk_wm8994.c
浏览文件 @
c41788c0
...
...
@@ -11,6 +11,7 @@
#include <sound/pcm_params.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
/*
* Default CFG switch settings to use this driver:
...
...
@@ -37,11 +38,19 @@
/* SMDK has a 16.934MHZ crystal attached to WM8994 */
#define SMDK_WM8994_FREQ 16934000
struct
smdk_wm8994_data
{
int
mclk1_rate
;
};
/* Default SMDKs */
static
struct
smdk_wm8994_data
smdk_board_data
=
{
.
mclk1_rate
=
SMDK_WM8994_FREQ
,
};
static
int
smdk_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
unsigned
int
pll_out
;
int
ret
;
...
...
@@ -54,18 +63,6 @@ static int smdk_hw_params(struct snd_pcm_substream *substream,
else
pll_out
=
params_rate
(
params
)
*
256
;
ret
=
snd_soc_dai_set_fmt
(
codec_dai
,
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBM_CFM
);
if
(
ret
<
0
)
return
ret
;
ret
=
snd_soc_dai_set_fmt
(
cpu_dai
,
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBM_CFM
);
if
(
ret
<
0
)
return
ret
;
ret
=
snd_soc_dai_set_pll
(
codec_dai
,
WM8994_FLL1
,
WM8994_FLL_SRC_MCLK1
,
SMDK_WM8994_FREQ
,
pll_out
);
if
(
ret
<
0
)
...
...
@@ -131,6 +128,8 @@ static struct snd_soc_dai_link smdk_dai[] = {
.
platform_name
=
"samsung-i2s.0"
,
.
codec_name
=
"wm8994-codec"
,
.
init
=
smdk_wm8994_init_paiftx
,
.
dai_fmt
=
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBM_CFM
,
.
ops
=
&
smdk_ops
,
},
{
/* Sec_Fifo Playback i/f */
.
name
=
"Sec_FIFO TX"
,
...
...
@@ -139,6 +138,8 @@ static struct snd_soc_dai_link smdk_dai[] = {
.
codec_dai_name
=
"wm8994-aif1"
,
.
platform_name
=
"samsung-i2s-sec"
,
.
codec_name
=
"wm8994-codec"
,
.
dai_fmt
=
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBM_CFM
,
.
ops
=
&
smdk_ops
,
},
};
...
...
@@ -150,15 +151,28 @@ static struct snd_soc_card smdk = {
.
num_links
=
ARRAY_SIZE
(
smdk_dai
),
};
#ifdef CONFIG_OF
static
const
struct
of_device_id
samsung_wm8994_of_match
[]
=
{
{
.
compatible
=
"samsung,smdk-wm8994"
,
.
data
=
&
smdk_board_data
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
samsung_wm8994_of_match
);
#endif
/* CONFIG_OF */
static
int
smdk_audio_probe
(
struct
platform_device
*
pdev
)
{
int
ret
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
snd_soc_card
*
card
=
&
smdk
;
struct
smdk_wm8994_data
*
board
;
const
struct
of_device_id
*
id
;
card
->
dev
=
&
pdev
->
dev
;
board
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
board
),
GFP_KERNEL
);
if
(
!
board
)
return
-
ENOMEM
;
if
(
np
)
{
smdk_dai
[
0
].
cpu_dai_name
=
NULL
;
smdk_dai
[
0
].
cpu_of_node
=
of_parse_phandle
(
np
,
...
...
@@ -173,6 +187,12 @@ static int smdk_audio_probe(struct platform_device *pdev)
smdk_dai
[
0
].
platform_of_node
=
smdk_dai
[
0
].
cpu_of_node
;
}
id
=
of_match_device
(
samsung_wm8994_of_match
,
&
pdev
->
dev
);
if
(
id
)
*
board
=
*
((
struct
smdk_wm8994_data
*
)
id
->
data
);
platform_set_drvdata
(
pdev
,
board
);
ret
=
snd_soc_register_card
(
card
);
if
(
ret
)
...
...
@@ -190,17 +210,9 @@ static int smdk_audio_remove(struct platform_device *pdev)
return
0
;
}
#ifdef CONFIG_OF
static
const
struct
of_device_id
samsung_wm8994_of_match
[]
=
{
{
.
compatible
=
"samsung,smdk-wm8994"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
samsung_wm8994_of_match
);
#endif
/* CONFIG_OF */
static
struct
platform_driver
smdk_audio_driver
=
{
.
driver
=
{
.
name
=
"smdk-audio"
,
.
name
=
"smdk-audio
-wm8894
"
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
of_match_ptr
(
samsung_wm8994_of_match
),
},
...
...
@@ -212,4 +224,4 @@ module_platform_driver(smdk_audio_driver);
MODULE_DESCRIPTION
(
"ALSA SoC SMDK WM8994"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_ALIAS
(
"platform:smdk-audio"
);
MODULE_ALIAS
(
"platform:smdk-audio
-wm8994
"
);
sound/soc/samsung/spdif.c
浏览文件 @
c41788c0
...
...
@@ -395,7 +395,7 @@ static int spdif_probe(struct platform_device *pdev)
spin_lock_init
(
&
spdif
->
lock
);
spdif
->
pclk
=
clk_get
(
&
pdev
->
dev
,
"spdif"
);
spdif
->
pclk
=
devm_
clk_get
(
&
pdev
->
dev
,
"spdif"
);
if
(
IS_ERR
(
spdif
->
pclk
))
{
dev_err
(
&
pdev
->
dev
,
"failed to get peri-clock
\n
"
);
ret
=
-
ENOENT
;
...
...
@@ -403,7 +403,7 @@ static int spdif_probe(struct platform_device *pdev)
}
clk_prepare_enable
(
spdif
->
pclk
);
spdif
->
sclk
=
clk_get
(
&
pdev
->
dev
,
"sclk_spdif"
);
spdif
->
sclk
=
devm_
clk_get
(
&
pdev
->
dev
,
"sclk_spdif"
);
if
(
IS_ERR
(
spdif
->
sclk
))
{
dev_err
(
&
pdev
->
dev
,
"failed to get internal source clock
\n
"
);
ret
=
-
ENOENT
;
...
...
@@ -442,7 +442,7 @@ static int spdif_probe(struct platform_device *pdev)
spdif
->
dma_playback
=
&
spdif_stereo_out
;
ret
=
asoc_dma_platform_register
(
&
pdev
->
dev
);
ret
=
samsung_
asoc_dma_platform_register
(
&
pdev
->
dev
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to register DMA: %d
\n
"
,
ret
);
goto
err5
;
...
...
@@ -457,10 +457,8 @@ static int spdif_probe(struct platform_device *pdev)
release_mem_region
(
mem_res
->
start
,
resource_size
(
mem_res
));
err2:
clk_disable_unprepare
(
spdif
->
sclk
);
clk_put
(
spdif
->
sclk
);
err1:
clk_disable_unprepare
(
spdif
->
pclk
);
clk_put
(
spdif
->
pclk
);
err0:
return
ret
;
}
...
...
@@ -470,7 +468,7 @@ static int spdif_remove(struct platform_device *pdev)
struct
samsung_spdif_info
*
spdif
=
&
spdif_info
;
struct
resource
*
mem_res
;
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
samsung_
asoc_dma_platform_unregister
(
&
pdev
->
dev
);
snd_soc_unregister_component
(
&
pdev
->
dev
);
iounmap
(
spdif
->
regs
);
...
...
@@ -480,9 +478,7 @@ static int spdif_remove(struct platform_device *pdev)
release_mem_region
(
mem_res
->
start
,
resource_size
(
mem_res
));
clk_disable_unprepare
(
spdif
->
sclk
);
clk_put
(
spdif
->
sclk
);
clk_disable_unprepare
(
spdif
->
pclk
);
clk_put
(
spdif
->
pclk
);
return
0
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录