Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
723b4cb5
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
161
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看板
提交
723b4cb5
编写于
12月 02, 2012
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/fsl' into asoc-next
上级
546694bc
29df4306
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
418 addition
and
3 deletion
+418
-3
sound/soc/fsl/Kconfig
sound/soc/fsl/Kconfig
+15
-1
sound/soc/fsl/Makefile
sound/soc/fsl/Makefile
+4
-0
sound/soc/fsl/imx-pcm.c
sound/soc/fsl/imx-pcm.c
+4
-0
sound/soc/fsl/imx-sgtl5000.c
sound/soc/fsl/imx-sgtl5000.c
+1
-0
sound/soc/fsl/p1022_rdk.c
sound/soc/fsl/p1022_rdk.c
+392
-0
sound/soc/fsl/pcm030-audio-fabric.c
sound/soc/fsl/pcm030-audio-fabric.c
+2
-2
未找到文件。
sound/soc/fsl/Kconfig
浏览文件 @
723b4cb5
...
...
@@ -46,6 +46,20 @@ config SND_SOC_P1022_DS
This will also include the Wolfson Microelectronics WM8776 codec
driver.
config SND_SOC_P1022_RDK
tristate "ALSA SoC support for the Freescale / iVeia P1022 RDK board"
# I2C is necessary for the WM8960 driver
depends on P1022_RDK && I2C
select SND_SOC_FSL_SSI
select SND_SOC_FSL_UTILS
select SND_SOC_POWERPC_DMA
select SND_SOC_WM8960
default y if P1022_RDK
help
Say Y if you want to enable audio on the Freescale / iVeia
P1022 RDK board. This will also include the Wolfson
Microelectronics WM8960 codec driver.
config SND_SOC_MPC5200_I2S
tristate "Freescale MPC5200 PSC in I2S mode driver"
depends on PPC_MPC52xx && PPC_BESTCOMM
...
...
@@ -112,7 +126,7 @@ config SND_SOC_IMX_AUDMUX
config SND_MXC_SOC_WM1133_EV1
tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted"
depends on MACH_MX31ADS_WM1133_EV1
&& EXPERIMENTAL
depends on MACH_MX31ADS_WM1133_EV1
select SND_SOC_WM8350
select SND_SOC_IMX_PCM_FIQ
select SND_SOC_IMX_AUDMUX
...
...
sound/soc/fsl/Makefile
浏览文件 @
723b4cb5
...
...
@@ -6,6 +6,10 @@ obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o
snd-soc-p1022-ds-objs
:=
p1022_ds.o
obj-$(CONFIG_SND_SOC_P1022_DS)
+=
snd-soc-p1022-ds.o
# P1022 RDK Machine Support
snd-soc-p1022-rdk-objs
:=
p1022_rdk.o
obj-$(CONFIG_SND_SOC_P1022_RDK)
+=
snd-soc-p1022-rdk.o
# Freescale PowerPC SSI/DMA Platform Support
snd-soc-fsl-ssi-objs
:=
fsl_ssi.o
snd-soc-fsl-utils-objs
:=
fsl_utils.o
...
...
sound/soc/fsl/imx-pcm.c
浏览文件 @
723b4cb5
...
...
@@ -103,3 +103,7 @@ void imx_pcm_free(struct snd_pcm *pcm)
}
}
EXPORT_SYMBOL_GPL
(
imx_pcm_free
);
MODULE_DESCRIPTION
(
"Freescale i.MX PCM driver"
);
MODULE_AUTHOR
(
"Sascha Hauer <s.hauer@pengutronix.de>"
);
MODULE_LICENSE
(
"GPL"
);
sound/soc/fsl/imx-sgtl5000.c
浏览文件 @
723b4cb5
...
...
@@ -162,6 +162,7 @@ static int __devinit imx_sgtl5000_probe(struct platform_device *pdev)
if
(
ret
)
goto
clk_fail
;
data
->
card
.
num_links
=
1
;
data
->
card
.
owner
=
THIS_MODULE
;
data
->
card
.
dai_link
=
&
data
->
dai
;
data
->
card
.
dapm_widgets
=
imx_sgtl5000_dapm_widgets
;
data
->
card
.
num_dapm_widgets
=
ARRAY_SIZE
(
imx_sgtl5000_dapm_widgets
);
...
...
sound/soc/fsl/p1022_rdk.c
0 → 100644
浏览文件 @
723b4cb5
/**
* Freescale P1022RDK ALSA SoC Machine driver
*
* Author: Timur Tabi <timur@freescale.com>
*
* Copyright 2012 Freescale Semiconductor, Inc.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*
* Note: in order for audio to work correctly, the output controls need
* to be enabled, because they control the clock. So for playback, for
* example:
*
* amixer sset 'Left Output Mixer PCM' on
* amixer sset 'Right Output Mixer PCM' on
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <sound/soc.h>
#include <asm/fsl_guts.h>
#include "fsl_dma.h"
#include "fsl_ssi.h"
#include "fsl_utils.h"
/* P1022-specific PMUXCR and DMUXCR bit definitions */
#define CCSR_GUTS_PMUXCR_UART0_I2C1_MASK 0x0001c000
#define CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI 0x00010000
#define CCSR_GUTS_PMUXCR_UART0_I2C1_SSI 0x00018000
#define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK 0x00000c00
#define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI 0x00000000
#define CCSR_GUTS_DMUXCR_PAD 1
/* DMA controller/channel set to pad */
#define CCSR_GUTS_DMUXCR_SSI 2
/* DMA controller/channel set to SSI */
/*
* Set the DMACR register in the GUTS
*
* The DMACR register determines the source of initiated transfers for each
* channel on each DMA controller. Rather than have a bunch of repetitive
* macros for the bit patterns, we just have a function that calculates
* them.
*
* guts: Pointer to GUTS structure
* co: The DMA controller (0 or 1)
* ch: The channel on the DMA controller (0, 1, 2, or 3)
* device: The device to set as the target (CCSR_GUTS_DMUXCR_xxx)
*/
static
inline
void
guts_set_dmuxcr
(
struct
ccsr_guts
__iomem
*
guts
,
unsigned
int
co
,
unsigned
int
ch
,
unsigned
int
device
)
{
unsigned
int
shift
=
16
+
(
8
*
(
1
-
co
)
+
2
*
(
3
-
ch
));
clrsetbits_be32
(
&
guts
->
dmuxcr
,
3
<<
shift
,
device
<<
shift
);
}
/* There's only one global utilities register */
static
phys_addr_t
guts_phys
;
/**
* machine_data: machine-specific ASoC device data
*
* This structure contains data for a single sound platform device on an
* P1022 RDK. Some of the data is taken from the device tree.
*/
struct
machine_data
{
struct
snd_soc_dai_link
dai
[
2
];
struct
snd_soc_card
card
;
unsigned
int
dai_format
;
unsigned
int
codec_clk_direction
;
unsigned
int
cpu_clk_direction
;
unsigned
int
clk_frequency
;
unsigned
int
dma_id
[
2
];
/* 0 = DMA1, 1 = DMA2, etc */
unsigned
int
dma_channel_id
[
2
];
/* 0 = ch 0, 1 = ch 1, etc*/
char
platform_name
[
2
][
DAI_NAME_SIZE
];
/* One for each DMA channel */
};
/**
* p1022_rdk_machine_probe: initialize the board
*
* This function is used to initialize the board-specific hardware.
*
* Here we program the DMACR and PMUXCR registers.
*/
static
int
p1022_rdk_machine_probe
(
struct
snd_soc_card
*
card
)
{
struct
machine_data
*
mdata
=
container_of
(
card
,
struct
machine_data
,
card
);
struct
ccsr_guts
__iomem
*
guts
;
guts
=
ioremap
(
guts_phys
,
sizeof
(
struct
ccsr_guts
));
if
(
!
guts
)
{
dev_err
(
card
->
dev
,
"could not map global utilities
\n
"
);
return
-
ENOMEM
;
}
/* Enable SSI Tx signal */
clrsetbits_be32
(
&
guts
->
pmuxcr
,
CCSR_GUTS_PMUXCR_UART0_I2C1_MASK
,
CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI
);
/* Enable SSI Rx signal */
clrsetbits_be32
(
&
guts
->
pmuxcr
,
CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK
,
CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI
);
/* Enable DMA Channel for SSI */
guts_set_dmuxcr
(
guts
,
mdata
->
dma_id
[
0
],
mdata
->
dma_channel_id
[
0
],
CCSR_GUTS_DMUXCR_SSI
);
guts_set_dmuxcr
(
guts
,
mdata
->
dma_id
[
1
],
mdata
->
dma_channel_id
[
1
],
CCSR_GUTS_DMUXCR_SSI
);
iounmap
(
guts
);
return
0
;
}
/**
* p1022_rdk_startup: program the board with various hardware parameters
*
* This function takes board-specific information, like clock frequencies
* and serial data formats, and passes that information to the codec and
* transport drivers.
*/
static
int
p1022_rdk_startup
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
machine_data
*
mdata
=
container_of
(
rtd
->
card
,
struct
machine_data
,
card
);
struct
device
*
dev
=
rtd
->
card
->
dev
;
int
ret
=
0
;
/* Tell the codec driver what the serial protocol is. */
ret
=
snd_soc_dai_set_fmt
(
rtd
->
codec_dai
,
mdata
->
dai_format
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"could not set codec driver audio format (ret=%i)
\n
"
,
ret
);
return
ret
;
}
ret
=
snd_soc_dai_set_pll
(
rtd
->
codec_dai
,
0
,
0
,
mdata
->
clk_frequency
,
mdata
->
clk_frequency
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"could not set codec PLL frequency (ret=%i)
\n
"
,
ret
);
return
ret
;
}
return
0
;
}
/**
* p1022_rdk_machine_remove: Remove the sound device
*
* This function is called to remove the sound device for one SSI. We
* de-program the DMACR and PMUXCR register.
*/
static
int
p1022_rdk_machine_remove
(
struct
snd_soc_card
*
card
)
{
struct
machine_data
*
mdata
=
container_of
(
card
,
struct
machine_data
,
card
);
struct
ccsr_guts
__iomem
*
guts
;
guts
=
ioremap
(
guts_phys
,
sizeof
(
struct
ccsr_guts
));
if
(
!
guts
)
{
dev_err
(
card
->
dev
,
"could not map global utilities
\n
"
);
return
-
ENOMEM
;
}
/* Restore the signal routing */
clrbits32
(
&
guts
->
pmuxcr
,
CCSR_GUTS_PMUXCR_UART0_I2C1_MASK
);
clrbits32
(
&
guts
->
pmuxcr
,
CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK
);
guts_set_dmuxcr
(
guts
,
mdata
->
dma_id
[
0
],
mdata
->
dma_channel_id
[
0
],
0
);
guts_set_dmuxcr
(
guts
,
mdata
->
dma_id
[
1
],
mdata
->
dma_channel_id
[
1
],
0
);
iounmap
(
guts
);
return
0
;
}
/**
* p1022_rdk_ops: ASoC machine driver operations
*/
static
struct
snd_soc_ops
p1022_rdk_ops
=
{
.
startup
=
p1022_rdk_startup
,
};
/**
* p1022_rdk_probe: platform probe function for the machine driver
*
* Although this is a machine driver, the SSI node is the "master" node with
* respect to audio hardware connections. Therefore, we create a new ASoC
* device for each new SSI node that has a codec attached.
*/
static
int
p1022_rdk_probe
(
struct
platform_device
*
pdev
)
{
struct
device
*
dev
=
pdev
->
dev
.
parent
;
/* ssi_pdev is the platform device for the SSI node that probed us */
struct
platform_device
*
ssi_pdev
=
container_of
(
dev
,
struct
platform_device
,
dev
);
struct
device_node
*
np
=
ssi_pdev
->
dev
.
of_node
;
struct
device_node
*
codec_np
=
NULL
;
struct
machine_data
*
mdata
;
const
u32
*
iprop
;
int
ret
;
/* Find the codec node for this SSI. */
codec_np
=
of_parse_phandle
(
np
,
"codec-handle"
,
0
);
if
(
!
codec_np
)
{
dev_err
(
dev
,
"could not find codec node
\n
"
);
return
-
EINVAL
;
}
mdata
=
kzalloc
(
sizeof
(
struct
machine_data
),
GFP_KERNEL
);
if
(
!
mdata
)
{
ret
=
-
ENOMEM
;
goto
error_put
;
}
mdata
->
dai
[
0
].
cpu_dai_name
=
dev_name
(
&
ssi_pdev
->
dev
);
mdata
->
dai
[
0
].
ops
=
&
p1022_rdk_ops
;
/* ASoC core can match codec with device node */
mdata
->
dai
[
0
].
codec_of_node
=
codec_np
;
/*
* We register two DAIs per SSI, one for playback and the other for
* capture. We support codecs that have separate DAIs for both playback
* and capture.
*/
memcpy
(
&
mdata
->
dai
[
1
],
&
mdata
->
dai
[
0
],
sizeof
(
struct
snd_soc_dai_link
));
/* The DAI names from the codec (snd_soc_dai_driver.name) */
mdata
->
dai
[
0
].
codec_dai_name
=
"wm8960-hifi"
;
mdata
->
dai
[
1
].
codec_dai_name
=
mdata
->
dai
[
0
].
codec_dai_name
;
/*
* Configure the SSI for I2S slave mode. Older device trees have
* an fsl,mode property, but we ignore that since there's really
* only one way to configure the SSI.
*/
mdata
->
dai_format
=
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_CBM_CFM
;
mdata
->
codec_clk_direction
=
SND_SOC_CLOCK_OUT
;
mdata
->
cpu_clk_direction
=
SND_SOC_CLOCK_IN
;
/*
* In i2s-slave mode, the codec has its own clock source, so we
* need to get the frequency from the device tree and pass it to
* the codec driver.
*/
iprop
=
of_get_property
(
codec_np
,
"clock-frequency"
,
NULL
);
if
(
!
iprop
||
!*
iprop
)
{
dev_err
(
&
pdev
->
dev
,
"codec bus-frequency property is missing or invalid
\n
"
);
ret
=
-
EINVAL
;
goto
error
;
}
mdata
->
clk_frequency
=
be32_to_cpup
(
iprop
);
if
(
!
mdata
->
clk_frequency
)
{
dev_err
(
&
pdev
->
dev
,
"unknown clock frequency
\n
"
);
ret
=
-
EINVAL
;
goto
error
;
}
/* Find the playback DMA channel to use. */
mdata
->
dai
[
0
].
platform_name
=
mdata
->
platform_name
[
0
];
ret
=
fsl_asoc_get_dma_channel
(
np
,
"fsl,playback-dma"
,
&
mdata
->
dai
[
0
],
&
mdata
->
dma_channel_id
[
0
],
&
mdata
->
dma_id
[
0
]);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"missing/invalid playback DMA phandle (ret=%i)
\n
"
,
ret
);
goto
error
;
}
/* Find the capture DMA channel to use. */
mdata
->
dai
[
1
].
platform_name
=
mdata
->
platform_name
[
1
];
ret
=
fsl_asoc_get_dma_channel
(
np
,
"fsl,capture-dma"
,
&
mdata
->
dai
[
1
],
&
mdata
->
dma_channel_id
[
1
],
&
mdata
->
dma_id
[
1
]);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"missing/invalid capture DMA phandle (ret=%i)
\n
"
,
ret
);
goto
error
;
}
/* Initialize our DAI data structure. */
mdata
->
dai
[
0
].
stream_name
=
"playback"
;
mdata
->
dai
[
1
].
stream_name
=
"capture"
;
mdata
->
dai
[
0
].
name
=
mdata
->
dai
[
0
].
stream_name
;
mdata
->
dai
[
1
].
name
=
mdata
->
dai
[
1
].
stream_name
;
mdata
->
card
.
probe
=
p1022_rdk_machine_probe
;
mdata
->
card
.
remove
=
p1022_rdk_machine_remove
;
mdata
->
card
.
name
=
pdev
->
name
;
/* The platform driver name */
mdata
->
card
.
owner
=
THIS_MODULE
;
mdata
->
card
.
dev
=
&
pdev
->
dev
;
mdata
->
card
.
num_links
=
2
;
mdata
->
card
.
dai_link
=
mdata
->
dai
;
/* Register with ASoC */
ret
=
snd_soc_register_card
(
&
mdata
->
card
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"could not register card (ret=%i)
\n
"
,
ret
);
goto
error
;
}
return
0
;
error:
kfree
(
mdata
);
error_put:
of_node_put
(
codec_np
);
return
ret
;
}
/**
* p1022_rdk_remove: remove the platform device
*
* This function is called when the platform device is removed.
*/
static
int
__devexit
p1022_rdk_remove
(
struct
platform_device
*
pdev
)
{
struct
snd_soc_card
*
card
=
platform_get_drvdata
(
pdev
);
struct
machine_data
*
mdata
=
container_of
(
card
,
struct
machine_data
,
card
);
snd_soc_unregister_card
(
card
);
kfree
(
mdata
);
return
0
;
}
static
struct
platform_driver
p1022_rdk_driver
=
{
.
probe
=
p1022_rdk_probe
,
.
remove
=
__devexit_p
(
p1022_rdk_remove
),
.
driver
=
{
/*
* The name must match 'compatible' property in the device tree,
* in lowercase letters.
*/
.
name
=
"snd-soc-p1022rdk"
,
.
owner
=
THIS_MODULE
,
},
};
/**
* p1022_rdk_init: machine driver initialization.
*
* This function is called when this module is loaded.
*/
static
int
__init
p1022_rdk_init
(
void
)
{
struct
device_node
*
guts_np
;
struct
resource
res
;
/* Get the physical address of the global utilities registers */
guts_np
=
of_find_compatible_node
(
NULL
,
NULL
,
"fsl,p1022-guts"
);
if
(
of_address_to_resource
(
guts_np
,
0
,
&
res
))
{
pr_err
(
"snd-soc-p1022rdk: missing/invalid global utils node
\n
"
);
of_node_put
(
guts_np
);
return
-
EINVAL
;
}
guts_phys
=
res
.
start
;
of_node_put
(
guts_np
);
return
platform_driver_register
(
&
p1022_rdk_driver
);
}
/**
* p1022_rdk_exit: machine driver exit
*
* This function is called when this driver is unloaded.
*/
static
void
__exit
p1022_rdk_exit
(
void
)
{
platform_driver_unregister
(
&
p1022_rdk_driver
);
}
late_initcall
(
p1022_rdk_init
);
module_exit
(
p1022_rdk_exit
);
MODULE_AUTHOR
(
"Timur Tabi <timur@freescale.com>"
);
MODULE_DESCRIPTION
(
"Freescale / iVeia P1022 RDK ALSA SoC machine driver"
);
MODULE_LICENSE
(
"GPL v2"
);
sound/soc/fsl/pcm030-audio-fabric.c
浏览文件 @
723b4cb5
...
...
@@ -29,14 +29,14 @@ struct pcm030_audio_data {
static
struct
snd_soc_dai_link
pcm030_fabric_dai
[]
=
{
{
.
name
=
"AC97"
,
.
name
=
"AC97
.0
"
,
.
stream_name
=
"AC97 Analog"
,
.
codec_dai_name
=
"wm9712-hifi"
,
.
cpu_dai_name
=
"mpc5200-psc-ac97.0"
,
.
codec_name
=
"wm9712-codec"
,
},
{
.
name
=
"AC97"
,
.
name
=
"AC97
.1
"
,
.
stream_name
=
"AC97 IEC958"
,
.
codec_dai_name
=
"wm9712-aux"
,
.
cpu_dai_name
=
"mpc5200-psc-ac97.1"
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录