Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
bug2833
cloud-kernel
提交
ac97d4e0
cloud-kernel
项目概览
bug2833
/
cloud-kernel
与 Fork 源项目一致
Fork自
openanolis / cloud-kernel
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ac97d4e0
编写于
11月 08, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/davinci' into asoc-next
上级
1d697db0
ee2f615d
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
382 addition
and
91 deletion
+382
-91
Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
...mentation/devicetree/bindings/sound/davinci-evm-audio.txt
+42
-0
Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
...ntation/devicetree/bindings/sound/davinci-mcasp-audio.txt
+27
-14
include/linux/platform_data/davinci_asp.h
include/linux/platform_data/davinci_asp.h
+2
-0
sound/soc/davinci/Kconfig
sound/soc/davinci/Kconfig
+15
-3
sound/soc/davinci/Makefile
sound/soc/davinci/Makefile
+1
-0
sound/soc/davinci/davinci-evm.c
sound/soc/davinci/davinci-evm.c
+166
-22
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-mcasp.c
+117
-52
sound/soc/davinci/davinci-mcasp.h
sound/soc/davinci/davinci-mcasp.h
+12
-0
未找到文件。
Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
0 → 100644
浏览文件 @
ac97d4e0
* Texas Instruments SoC audio setups with TLV320AIC3X Codec
Required properties:
- compatible : "ti,da830-evm-audio" : forDM365/DA8xx/OMAPL1x/AM33xx
- ti,model : The user-visible name of this sound complex.
- ti,audio-codec : The phandle of the TLV320AIC3x audio codec
- ti,mcasp-controller : The phandle of the McASP controller
- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec
- ti,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,
the second being the connection's source. Valid names for sources and
sinks are the codec's pins, and the jacks on the board:
Board connectors:
* Headphone Jack
* Line Out
* Mic Jack
* Line In
Example:
sound {
compatible = "ti,da830-evm-audio";
ti,model = "DA830 EVM";
ti,audio-codec = <&tlv320aic3x>;
ti,mcasp-controller = <&mcasp1>;
ti,codec-clock-rate = <12000000>;
ti,audio-routing =
"Headphone Jack", "HPLOUT",
"Headphone Jack", "HPROUT",
"Line Out", "LLOUT",
"Line Out", "RLOUT",
"MIC3L", "Mic Bias 2V",
"MIC3R", "Mic Bias 2V",
"Mic Bias 2V", "Mic Jack",
"LINE1L", "Line In",
"LINE2L", "Line In",
"LINE1R", "Line In",
"LINE2R", "Line In";
};
Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
浏览文件 @
ac97d4e0
...
...
@@ -4,17 +4,25 @@ Required properties:
- compatible :
"ti,dm646x-mcasp-audio" : for DM646x platforms
"ti,da830-mcasp-audio" : for both DA830 & DA850 platforms
"ti,omap2-mcasp-audio" : for OMAP2 platforms (TI81xx, AM33xx)
- reg : Should contain McASP registers offset and length
- interrupts : Interrupt number for McASP
- op-mode : I2S/DIT ops mode.
- tdm-slots : Slots for TDM operation.
- num-serializer : Serializers used by McASP.
- serial-dir : A list of serializer pin mode. The list number should be equal
to "num-serializer" parameter. Each entry is a number indication
serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX)
"ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, TI81xx)
- reg : Should contain reg specifiers for the entries in the reg-names property.
- reg-names : Should contain:
* "mpu" for the main registers (required). For compatibility with
existing software, it is recommended this is the first entry.
* "dat" for separate data port register access (optional).
- op-mode : I2S/DIT ops mode. 0 for I2S mode. 1 for DIT mode used for S/PDIF,
IEC60958-1, and AES-3 formats.
- tdm-slots : Slots for TDM operation. Indicates number of channels transmitted
or received over one serializer.
- serial-dir : A list of serializer configuration. Each entry is a number
indication for serializer pin direction.
(0 - INACTIVE, 1 - TX, 2 - RX)
- dmas: two element list of DMA controller phandles and DMA request line
ordered pairs.
- dma-names: identifier string for each DMA request line in the dmas property.
These strings correspond 1:1 with the ordered pairs in dmas. The dma
identifiers must be "rx" and "tx".
Optional properties:
...
...
@@ -23,18 +31,23 @@ Optional properties:
- rx-num-evt : FIFO levels.
- sram-size-playback : size of sram to be allocated during playback
- sram-size-capture : size of sram to be allocated during capture
- interrupts : Interrupt numbers for McASP, currently not used by the driver
- interrupt-names : Known interrupt names are "tx" and "rx"
- pinctrl-0: Should specify pin control group used for this controller.
- pinctrl-names: Should contain only one value - "default", for more details
please refer to pinctrl-bindings.txt
Example:
mcasp0: mcasp0@1d00000 {
compatible = "ti,da830-mcasp-audio";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x100000 0x3000>;
interrupts = <82 83>;
reg-names "mpu";
interrupts = <82>, <83>;
interrupts-names = "tx", "rx";
op-mode = <0>; /* MCASP_IIS_MODE */
tdm-slots = <2>;
num-serializer = <16>;
serial-dir = <
0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */
0 0 0 0
...
...
include/linux/platform_data/davinci_asp.h
浏览文件 @
ac97d4e0
...
...
@@ -84,6 +84,8 @@ struct snd_platform_data {
u8
version
;
u8
txnumevt
;
u8
rxnumevt
;
int
tx_dma_channel
;
int
rx_dma_channel
;
};
enum
{
...
...
sound/soc/davinci/Kconfig
浏览文件 @
ac97d4e0
config SND_DAVINCI_SOC
tristate "SoC Audio for the TI DAVINCI chip"
depends on ARCH_DAVINCI
tristate "SoC Audio for the TI DAVINCI
or AM33XX
chip"
depends on ARCH_DAVINCI
|| SOC_AM33XX
help
Platform driver for daVinci or AM33xx
Say Y or M if you want to add support for codecs attached to
the DAVINCI AC97
or I2S
interface. You will also need
the DAVINCI AC97
, I2S, or McASP
interface. You will also need
to select the audio interfaces to support below.
config SND_DAVINCI_SOC_I2S
...
...
@@ -15,6 +16,17 @@ config SND_DAVINCI_SOC_MCASP
config SND_DAVINCI_SOC_VCIF
tristate
config SND_AM33XX_SOC_EVM
tristate "SoC Audio for the AM33XX chip based boards"
depends on SND_DAVINCI_SOC && SOC_AM33XX
select SND_SOC_TLV320AIC3X
select SND_DAVINCI_SOC_MCASP
help
Say Y or M if you want to add support for SoC audio on AM33XX
boards using McASP and TLV320AIC3X codec. For example AM335X-EVM,
AM335X-EVMSK, and BeagelBone with AudioCape boards have this
setup.
config SND_DAVINCI_SOC_EVM
tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
depends on SND_DAVINCI_SOC
...
...
sound/soc/davinci/Makefile
浏览文件 @
ac97d4e0
...
...
@@ -13,6 +13,7 @@ obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
snd-soc-evm-objs
:=
davinci-evm.o
obj-$(CONFIG_SND_DAVINCI_SOC_EVM)
+=
snd-soc-evm.o
obj-$(CONFIG_SND_AM33XX_SOC_EVM)
+=
snd-soc-evm.o
obj-$(CONFIG_SND_DM6467_SOC_EVM)
+=
snd-soc-evm.o
obj-$(CONFIG_SND_DA830_SOC_EVM)
+=
snd-soc-evm.o
obj-$(CONFIG_SND_DA850_SOC_EVM)
+=
snd-soc-evm.o
sound/soc/davinci/davinci-evm.c
浏览文件 @
ac97d4e0
...
...
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/platform_data/edma.h>
#include <linux/i2c.h>
#include <linux/of_platform.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
...
...
@@ -23,10 +24,16 @@
#include <asm/dma.h>
#include <asm/mach-types.h>
#include <linux/edma.h>
#include "davinci-pcm.h"
#include "davinci-i2s.h"
#include "davinci-mcasp.h"
struct
snd_soc_card_drvdata_davinci
{
unsigned
sysclk
;
};
#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
static
int
evm_hw_params
(
struct
snd_pcm_substream
*
substream
,
...
...
@@ -35,27 +42,11 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_card
*
soc_card
=
codec
->
card
;
int
ret
=
0
;
unsigned
sysclk
;
/* ASP1 on DM355 EVM is clocked by an external oscillator */
if
(
machine_is_davinci_dm355_evm
()
||
machine_is_davinci_dm6467_evm
()
||
machine_is_davinci_dm365_evm
())
sysclk
=
27000000
;
/* ASP0 in DM6446 EVM is clocked by U55, as configured by
* board-dm644x-evm.c using GPIOs from U18. There are six
* options; here we "know" we use a 48 KHz sample rate.
*/
else
if
(
machine_is_davinci_evm
())
sysclk
=
12288000
;
else
if
(
machine_is_davinci_da830_evm
()
||
machine_is_davinci_da850_evm
())
sysclk
=
24576000
;
else
return
-
EINVAL
;
unsigned
sysclk
=
((
struct
snd_soc_card_drvdata_davinci
*
)
snd_soc_card_get_drvdata
(
soc_card
))
->
sysclk
;
/* set codec DAI configuration */
ret
=
snd_soc_dai_set_fmt
(
codec_dai
,
AUDIO_FORMAT
);
...
...
@@ -133,13 +124,22 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
{
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
struct
device_node
*
np
=
codec
->
card
->
dev
->
of_node
;
int
ret
;
/* Add davinci-evm specific widgets */
snd_soc_dapm_new_controls
(
dapm
,
aic3x_dapm_widgets
,
ARRAY_SIZE
(
aic3x_dapm_widgets
));
if
(
np
)
{
ret
=
snd_soc_of_parse_audio_routing
(
codec
->
card
,
"ti,audio-routing"
);
if
(
ret
)
return
ret
;
}
else
{
/* Set up davinci-evm specific audio path audio_map */
snd_soc_dapm_add_routes
(
dapm
,
audio_map
,
ARRAY_SIZE
(
audio_map
));
}
/* not connected */
snd_soc_dapm_disable_pin
(
dapm
,
"MONO_LOUT"
);
...
...
@@ -243,35 +243,65 @@ static struct snd_soc_dai_link da850_evm_dai = {
};
/* davinci dm6446 evm audio machine driver */
/*
* ASP0 in DM6446 EVM is clocked by U55, as configured by
* board-dm644x-evm.c using GPIOs from U18. There are six
* options; here we "know" we use a 48 KHz sample rate.
*/
static
struct
snd_soc_card_drvdata_davinci
dm6446_snd_soc_card_drvdata
=
{
.
sysclk
=
12288000
,
};
static
struct
snd_soc_card
dm6446_snd_soc_card_evm
=
{
.
name
=
"DaVinci DM6446 EVM"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
dm6446_evm_dai
,
.
num_links
=
1
,
.
drvdata
=
&
dm6446_snd_soc_card_drvdata
,
};
/* davinci dm355 evm audio machine driver */
/* ASP1 on DM355 EVM is clocked by an external oscillator */
static
struct
snd_soc_card_drvdata_davinci
dm355_snd_soc_card_drvdata
=
{
.
sysclk
=
27000000
,
};
static
struct
snd_soc_card
dm355_snd_soc_card_evm
=
{
.
name
=
"DaVinci DM355 EVM"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
dm355_evm_dai
,
.
num_links
=
1
,
.
drvdata
=
&
dm355_snd_soc_card_drvdata
,
};
/* davinci dm365 evm audio machine driver */
static
struct
snd_soc_card_drvdata_davinci
dm365_snd_soc_card_drvdata
=
{
.
sysclk
=
27000000
,
};
static
struct
snd_soc_card
dm365_snd_soc_card_evm
=
{
.
name
=
"DaVinci DM365 EVM"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
dm365_evm_dai
,
.
num_links
=
1
,
.
drvdata
=
&
dm365_snd_soc_card_drvdata
,
};
/* davinci dm6467 evm audio machine driver */
static
struct
snd_soc_card_drvdata_davinci
dm6467_snd_soc_card_drvdata
=
{
.
sysclk
=
27000000
,
};
static
struct
snd_soc_card
dm6467_snd_soc_card_evm
=
{
.
name
=
"DaVinci DM6467 EVM"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
dm6467_evm_dai
,
.
num_links
=
ARRAY_SIZE
(
dm6467_evm_dai
),
.
drvdata
=
&
dm6467_snd_soc_card_drvdata
,
};
static
struct
snd_soc_card_drvdata_davinci
da830_snd_soc_card_drvdata
=
{
.
sysclk
=
24576000
,
};
static
struct
snd_soc_card
da830_snd_soc_card
=
{
...
...
@@ -279,6 +309,11 @@ static struct snd_soc_card da830_snd_soc_card = {
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
da830_evm_dai
,
.
num_links
=
1
,
.
drvdata
=
&
da830_snd_soc_card_drvdata
,
};
static
struct
snd_soc_card_drvdata_davinci
da850_snd_soc_card_drvdata
=
{
.
sysclk
=
24576000
,
};
static
struct
snd_soc_card
da850_snd_soc_card
=
{
...
...
@@ -286,8 +321,101 @@ static struct snd_soc_card da850_snd_soc_card = {
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
da850_evm_dai
,
.
num_links
=
1
,
.
drvdata
=
&
da850_snd_soc_card_drvdata
,
};
#if defined(CONFIG_OF)
/*
* The struct is used as place holder. It will be completely
* filled with data from dt node.
*/
static
struct
snd_soc_dai_link
evm_dai_tlv320aic3x
=
{
.
name
=
"TLV320AIC3X"
,
.
stream_name
=
"AIC3X"
,
.
codec_dai_name
=
"tlv320aic3x-hifi"
,
.
ops
=
&
evm_ops
,
.
init
=
evm_aic3x_init
,
};
static
const
struct
of_device_id
davinci_evm_dt_ids
[]
=
{
{
.
compatible
=
"ti,da830-evm-audio"
,
.
data
=
(
void
*
)
&
evm_dai_tlv320aic3x
,
},
{
/* sentinel */
}
};
MODULE_DEVICE_TABLE
(
of
,
davinci_evm_dt_ids
);
/* davinci evm audio machine driver */
static
struct
snd_soc_card
evm_soc_card
=
{
.
owner
=
THIS_MODULE
,
.
num_links
=
1
,
};
static
int
davinci_evm_probe
(
struct
platform_device
*
pdev
)
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
const
struct
of_device_id
*
match
=
of_match_device
(
of_match_ptr
(
davinci_evm_dt_ids
),
&
pdev
->
dev
);
struct
snd_soc_dai_link
*
dai
=
(
struct
snd_soc_dai_link
*
)
match
->
data
;
struct
snd_soc_card_drvdata_davinci
*
drvdata
=
NULL
;
int
ret
=
0
;
evm_soc_card
.
dai_link
=
dai
;
dai
->
codec_of_node
=
of_parse_phandle
(
np
,
"ti,audio-codec"
,
0
);
if
(
!
dai
->
codec_of_node
)
return
-
EINVAL
;
dai
->
cpu_of_node
=
of_parse_phandle
(
np
,
"ti,mcasp-controller"
,
0
);
if
(
!
dai
->
cpu_of_node
)
return
-
EINVAL
;
dai
->
platform_of_node
=
dai
->
cpu_of_node
;
evm_soc_card
.
dev
=
&
pdev
->
dev
;
ret
=
snd_soc_of_parse_card_name
(
&
evm_soc_card
,
"ti,model"
);
if
(
ret
)
return
ret
;
drvdata
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
drvdata
),
GFP_KERNEL
);
if
(
!
drvdata
)
return
-
ENOMEM
;
ret
=
of_property_read_u32
(
np
,
"ti,codec-clock-rate"
,
&
drvdata
->
sysclk
);
if
(
ret
<
0
)
return
-
EINVAL
;
snd_soc_card_set_drvdata
(
&
evm_soc_card
,
drvdata
);
ret
=
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
evm_soc_card
);
if
(
ret
)
dev_err
(
&
pdev
->
dev
,
"snd_soc_register_card failed (%d)
\n
"
,
ret
);
return
ret
;
}
static
int
davinci_evm_remove
(
struct
platform_device
*
pdev
)
{
struct
snd_soc_card
*
card
=
platform_get_drvdata
(
pdev
);
snd_soc_unregister_card
(
card
);
return
0
;
}
static
struct
platform_driver
davinci_evm_driver
=
{
.
probe
=
davinci_evm_probe
,
.
remove
=
davinci_evm_remove
,
.
driver
=
{
.
name
=
"davinci_evm"
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
of_match_ptr
(
davinci_evm_dt_ids
),
},
};
#endif
static
struct
platform_device
*
evm_snd_device
;
static
int
__init
evm_init
(
void
)
...
...
@@ -296,6 +424,15 @@ static int __init evm_init(void)
int
index
;
int
ret
;
/*
* If dtb is there, the devices will be created dynamically.
* Only register platfrom driver structure.
*/
#if defined(CONFIG_OF)
if
(
of_have_populated_dt
())
return
platform_driver_register
(
&
davinci_evm_driver
);
#endif
if
(
machine_is_davinci_evm
())
{
evm_snd_dev_data
=
&
dm6446_snd_soc_card_evm
;
index
=
0
;
...
...
@@ -331,6 +468,13 @@ static int __init evm_init(void)
static
void
__exit
evm_exit
(
void
)
{
#if defined(CONFIG_OF)
if
(
of_have_populated_dt
())
{
platform_driver_unregister
(
&
davinci_evm_driver
);
return
;
}
#endif
platform_device_unregister
(
evm_snd_device
);
}
...
...
sound/soc/davinci/davinci-mcasp.c
浏览文件 @
ac97d4e0
...
...
@@ -1001,18 +1001,40 @@ static const struct snd_soc_component_driver davinci_mcasp_component = {
.
name
=
"davinci-mcasp"
,
};
/* Some HW specific values and defaults. The rest is filled in from DT. */
static
struct
snd_platform_data
dm646x_mcasp_pdata
=
{
.
tx_dma_offset
=
0x400
,
.
rx_dma_offset
=
0x400
,
.
asp_chan_q
=
EVENTQ_0
,
.
version
=
MCASP_VERSION_1
,
};
static
struct
snd_platform_data
da830_mcasp_pdata
=
{
.
tx_dma_offset
=
0x2000
,
.
rx_dma_offset
=
0x2000
,
.
asp_chan_q
=
EVENTQ_0
,
.
version
=
MCASP_VERSION_2
,
};
static
struct
snd_platform_data
omap2_mcasp_pdata
=
{
.
tx_dma_offset
=
0
,
.
rx_dma_offset
=
0
,
.
asp_chan_q
=
EVENTQ_0
,
.
version
=
MCASP_VERSION_3
,
};
static
const
struct
of_device_id
mcasp_dt_ids
[]
=
{
{
.
compatible
=
"ti,dm646x-mcasp-audio"
,
.
data
=
(
void
*
)
MCASP_VERSION_1
,
.
data
=
&
dm646x_mcasp_pdata
,
},
{
.
compatible
=
"ti,da830-mcasp-audio"
,
.
data
=
(
void
*
)
MCASP_VERSION_2
,
.
data
=
&
da830_mcasp_pdata
,
},
{
.
compatible
=
"ti,
omap2
-mcasp-audio"
,
.
data
=
(
void
*
)
MCASP_VERSION_3
,
.
compatible
=
"ti,
am33xx
-mcasp-audio"
,
.
data
=
&
omap2_mcasp_pdata
,
},
{
/* sentinel */
}
};
...
...
@@ -1025,9 +1047,9 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
struct
snd_platform_data
*
pdata
=
NULL
;
const
struct
of_device_id
*
match
=
of_match_device
(
mcasp_dt_ids
,
&
pdev
->
dev
);
struct
of_phandle_args
dma_spec
;
const
u32
*
of_serial_dir32
;
u8
*
of_serial_dir
;
u32
val
;
int
i
,
ret
=
0
;
...
...
@@ -1035,20 +1057,13 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
pdata
=
pdev
->
dev
.
platform_data
;
return
pdata
;
}
else
if
(
match
)
{
pdata
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
pdata
),
GFP_KERNEL
);
if
(
!
pdata
)
{
ret
=
-
ENOMEM
;
goto
nodata
;
}
pdata
=
(
struct
snd_platform_data
*
)
match
->
data
;
}
else
{
/* control shouldn't reach here. something is wrong */
ret
=
-
EINVAL
;
goto
nodata
;
}
if
(
match
->
data
)
pdata
->
version
=
(
u8
)((
int
)
match
->
data
);
ret
=
of_property_read_u32
(
np
,
"op-mode"
,
&
val
);
if
(
ret
>=
0
)
pdata
->
op_mode
=
val
;
...
...
@@ -1065,22 +1080,10 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
pdata
->
tdm_slots
=
val
;
}
ret
=
of_property_read_u32
(
np
,
"num-serializer"
,
&
val
);
if
(
ret
>=
0
)
pdata
->
num_serializer
=
val
;
of_serial_dir32
=
of_get_property
(
np
,
"serial-dir"
,
&
val
);
val
/=
sizeof
(
u32
);
if
(
val
!=
pdata
->
num_serializer
)
{
dev_err
(
&
pdev
->
dev
,
"num-serializer(%d) != serial-dir size(%d)
\n
"
,
pdata
->
num_serializer
,
val
);
ret
=
-
EINVAL
;
goto
nodata
;
}
if
(
of_serial_dir32
)
{
of_serial_dir
=
devm_kzalloc
(
&
pdev
->
dev
,
u8
*
of_serial_dir
=
devm_kzalloc
(
&
pdev
->
dev
,
(
sizeof
(
*
of_serial_dir
)
*
val
),
GFP_KERNEL
);
if
(
!
of_serial_dir
)
{
...
...
@@ -1088,12 +1091,35 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
goto
nodata
;
}
for
(
i
=
0
;
i
<
pdata
->
num_serializer
;
i
++
)
for
(
i
=
0
;
i
<
val
;
i
++
)
of_serial_dir
[
i
]
=
be32_to_cpup
(
&
of_serial_dir32
[
i
]);
pdata
->
num_serializer
=
val
;
pdata
->
serial_dir
=
of_serial_dir
;
}
ret
=
of_property_match_string
(
np
,
"dma-names"
,
"tx"
);
if
(
ret
<
0
)
goto
nodata
;
ret
=
of_parse_phandle_with_args
(
np
,
"dmas"
,
"#dma-cells"
,
ret
,
&
dma_spec
);
if
(
ret
<
0
)
goto
nodata
;
pdata
->
tx_dma_channel
=
dma_spec
.
args
[
0
];
ret
=
of_property_match_string
(
np
,
"dma-names"
,
"rx"
);
if
(
ret
<
0
)
goto
nodata
;
ret
=
of_parse_phandle_with_args
(
np
,
"dmas"
,
"#dma-cells"
,
ret
,
&
dma_spec
);
if
(
ret
<
0
)
goto
nodata
;
pdata
->
rx_dma_channel
=
dma_spec
.
args
[
0
];
ret
=
of_property_read_u32
(
np
,
"tx-num-evt"
,
&
val
);
if
(
ret
>=
0
)
pdata
->
txnumevt
=
val
;
...
...
@@ -1124,7 +1150,7 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
static
int
davinci_mcasp_probe
(
struct
platform_device
*
pdev
)
{
struct
davinci_pcm_dma_params
*
dma_data
;
struct
resource
*
mem
,
*
ioarea
,
*
res
;
struct
resource
*
mem
,
*
ioarea
,
*
res
,
*
dat
;
struct
snd_platform_data
*
pdata
;
struct
davinci_audio_dev
*
dev
;
int
ret
;
...
...
@@ -1145,11 +1171,16 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
return
-
EINVAL
;
}
mem
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"mpu"
);
if
(
!
mem
)
{
dev_warn
(
dev
->
dev
,
"
\"
mpu
\"
mem resource not found, using index 0
\n
"
);
mem
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
mem
)
{
dev_err
(
&
pdev
->
dev
,
"no mem resource?
\n
"
);
return
-
ENODEV
;
}
}
ioarea
=
devm_request_mem_region
(
&
pdev
->
dev
,
mem
->
start
,
resource_size
(
mem
),
pdev
->
name
);
...
...
@@ -1182,40 +1213,36 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dev
->
rxnumevt
=
pdata
->
rxnumevt
;
dev
->
dev
=
&
pdev
->
dev
;
dat
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"dat"
);
if
(
!
dat
)
dat
=
mem
;
dma_data
=
&
dev
->
dma_params
[
SNDRV_PCM_STREAM_PLAYBACK
];
dma_data
->
asp_chan_q
=
pdata
->
asp_chan_q
;
dma_data
->
ram_chan_q
=
pdata
->
ram_chan_q
;
dma_data
->
sram_pool
=
pdata
->
sram_pool
;
dma_data
->
sram_size
=
pdata
->
sram_size_playback
;
dma_data
->
dma_addr
=
(
dma_addr_t
)
(
pdata
->
tx_dma_offset
+
mem
->
start
);
dma_data
->
dma_addr
=
dat
->
start
+
pdata
->
tx_dma_offset
;
/* first TX, then RX */
res
=
platform_get_resource
(
pdev
,
IORESOURCE_DMA
,
0
);
if
(
!
res
)
{
dev_err
(
&
pdev
->
dev
,
"no DMA resource
\n
"
);
ret
=
-
ENODEV
;
goto
err_release_clk
;
}
if
(
res
)
dma_data
->
channel
=
res
->
start
;
else
dma_data
->
channel
=
pdata
->
tx_dma_channel
;
dma_data
=
&
dev
->
dma_params
[
SNDRV_PCM_STREAM_CAPTURE
];
dma_data
->
asp_chan_q
=
pdata
->
asp_chan_q
;
dma_data
->
ram_chan_q
=
pdata
->
ram_chan_q
;
dma_data
->
sram_pool
=
pdata
->
sram_pool
;
dma_data
->
sram_size
=
pdata
->
sram_size_capture
;
dma_data
->
dma_addr
=
(
dma_addr_t
)(
pdata
->
rx_dma_offset
+
mem
->
start
);
dma_data
->
dma_addr
=
dat
->
start
+
pdata
->
rx_dma_offset
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_DMA
,
1
);
if
(
!
res
)
{
dev_err
(
&
pdev
->
dev
,
"no DMA resource
\n
"
);
ret
=
-
ENODEV
;
goto
err_release_clk
;
}
if
(
res
)
dma_data
->
channel
=
res
->
start
;
else
dma_data
->
channel
=
pdata
->
rx_dma_channel
;
dev_set_drvdata
(
&
pdev
->
dev
,
dev
);
ret
=
snd_soc_register_component
(
&
pdev
->
dev
,
&
davinci_mcasp_component
,
&
davinci_mcasp_dai
[
pdata
->
op_mode
],
1
);
...
...
@@ -1251,12 +1278,51 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
return
0
;
}
#ifdef CONFIG_PM_SLEEP
static
int
davinci_mcasp_suspend
(
struct
device
*
dev
)
{
struct
davinci_audio_dev
*
a
=
dev_get_drvdata
(
dev
);
void
__iomem
*
base
=
a
->
base
;
a
->
context
.
txfmtctl
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_TXFMCTL_REG
);
a
->
context
.
rxfmtctl
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_RXFMCTL_REG
);
a
->
context
.
txfmt
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_TXFMT_REG
);
a
->
context
.
rxfmt
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_RXFMT_REG
);
a
->
context
.
aclkxctl
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_ACLKXCTL_REG
);
a
->
context
.
aclkrctl
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_ACLKRCTL_REG
);
a
->
context
.
pdir
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_PDIR_REG
);
return
0
;
}
static
int
davinci_mcasp_resume
(
struct
device
*
dev
)
{
struct
davinci_audio_dev
*
a
=
dev_get_drvdata
(
dev
);
void
__iomem
*
base
=
a
->
base
;
mcasp_set_reg
(
base
+
DAVINCI_MCASP_TXFMCTL_REG
,
a
->
context
.
txfmtctl
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_RXFMCTL_REG
,
a
->
context
.
rxfmtctl
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_TXFMT_REG
,
a
->
context
.
txfmt
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_RXFMT_REG
,
a
->
context
.
rxfmt
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_ACLKXCTL_REG
,
a
->
context
.
aclkxctl
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_ACLKRCTL_REG
,
a
->
context
.
aclkrctl
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_PDIR_REG
,
a
->
context
.
pdir
);
return
0
;
}
#endif
SIMPLE_DEV_PM_OPS
(
davinci_mcasp_pm_ops
,
davinci_mcasp_suspend
,
davinci_mcasp_resume
);
static
struct
platform_driver
davinci_mcasp_driver
=
{
.
probe
=
davinci_mcasp_probe
,
.
remove
=
davinci_mcasp_remove
,
.
driver
=
{
.
name
=
"davinci-mcasp"
,
.
owner
=
THIS_MODULE
,
.
pm
=
&
davinci_mcasp_pm_ops
,
.
of_match_table
=
mcasp_dt_ids
,
},
};
...
...
@@ -1266,4 +1332,3 @@ module_platform_driver(davinci_mcasp_driver);
MODULE_AUTHOR
(
"Steve Chen"
);
MODULE_DESCRIPTION
(
"TI DAVINCI McASP SoC Interface"
);
MODULE_LICENSE
(
"GPL"
);
sound/soc/davinci/davinci-mcasp.h
浏览文件 @
ac97d4e0
...
...
@@ -43,6 +43,18 @@ struct davinci_audio_dev {
/* McASP FIFO related */
u8
txnumevt
;
u8
rxnumevt
;
#ifdef CONFIG_PM_SLEEP
struct
{
u32
txfmtctl
;
u32
rxfmtctl
;
u32
txfmt
;
u32
rxfmt
;
u32
aclkxctl
;
u32
aclkrctl
;
u32
pdir
;
}
context
;
#endif
};
#endif
/* DAVINCI_MCASP_H */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录