Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
2ef39e60
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看板
提交
2ef39e60
编写于
9月 22, 2012
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/ux500' into for-3.7
上级
a89be93c
b4cad7af
变更
10
显示空白变更内容
内联
并排
Showing
10 changed file
with
292 addition
and
108 deletion
+292
-108
Documentation/devicetree/bindings/sound/ux500-mop500.txt
Documentation/devicetree/bindings/sound/ux500-mop500.txt
+39
-0
Documentation/devicetree/bindings/sound/ux500-msp.txt
Documentation/devicetree/bindings/sound/ux500-msp.txt
+43
-0
arch/arm/mach-ux500/board-mop500-msp.c
arch/arm/mach-ux500/board-mop500-msp.c
+1
-78
arch/arm/mach-ux500/include/mach/msp.h
arch/arm/mach-ux500/include/mach/msp.h
+0
-2
include/linux/mfd/abx500/ab8500-codec.h
include/linux/mfd/abx500/ab8500-codec.h
+4
-2
sound/soc/codecs/ab8500-codec.c
sound/soc/codecs/ab8500-codec.c
+81
-0
sound/soc/ux500/mop500.c
sound/soc/ux500/mop500.c
+42
-5
sound/soc/ux500/ux500_msp_dai.c
sound/soc/ux500/ux500_msp_dai.c
+6
-0
sound/soc/ux500/ux500_msp_i2s.c
sound/soc/ux500/ux500_msp_i2s.c
+70
-19
sound/soc/ux500/ux500_msp_i2s.h
sound/soc/ux500/ux500_msp_i2s.h
+6
-2
未找到文件。
Documentation/devicetree/bindings/sound/ux500-mop500.txt
0 → 100644
浏览文件 @
2ef39e60
* MOP500 Audio Machine Driver
This node is responsible for linking together all ux500 Audio Driver components.
Required properties:
- compatible : "stericsson,snd-soc-mop500"
Non-standard properties:
- stericsson,cpu-dai : Phandle to the CPU-side DAI
- stericsson,audio-codec : Phandle to the Audio CODEC
- stericsson,card-name : Over-ride default card name
Example:
sound {
compatible = "stericsson,snd-soc-mop500";
stericsson,cpu-dai = <&msp1 &msp3>;
stericsson,audio-codec = <&codec>;
};
msp1: msp@80124000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80124000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};
msp3: msp@80125000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80125000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};
codec: ab8500-codec {
compatible = "stericsson,ab8500-codec";
stericsson,earpeice-cmv = <950>; /* Units in mV. */
};
Documentation/devicetree/bindings/sound/ux500-msp.txt
0 → 100644
浏览文件 @
2ef39e60
* ux500 MSP (CPU-side Digital Audio Interface)
Required properties:
- compatible :"stericsson,ux500-msp-i2s"
- reg : Physical base address and length of the device's registers.
Optional properties:
- interrupts : The interrupt output from the device.
- interrupt-parent : The parent interrupt controller.
- <name>-supply : Phandle to the regulator <name> supply
Example:
sound {
compatible = "stericsson,snd-soc-mop500";
stericsson,platform-pcm-dma = <&pcm>;
stericsson,cpu-dai = <&msp1 &msp3>;
stericsson,audio-codec = <&codec>;
};
pcm: ux500-pcm {
compatible = "stericsson,ux500-pcm";
};
msp1: msp@80124000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80124000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};
msp3: msp@80125000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80125000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};
codec: ab8500-codec {
compatible = "stericsson,ab8500-codec";
stericsson,earpeice-cmv = <950>; /* Units in mV. */
};
arch/arm/mach-ux500/board-mop500-msp.c
浏览文件 @
2ef39e60
...
@@ -7,7 +7,6 @@
...
@@ -7,7 +7,6 @@
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/gpio.h>
#include <linux/pinctrl/consumer.h>
#include <plat/gpio-nomadik.h>
#include <plat/gpio-nomadik.h>
#include <plat/pincfg.h>
#include <plat/pincfg.h>
...
@@ -23,53 +22,6 @@
...
@@ -23,53 +22,6 @@
#include "devices-db8500.h"
#include "devices-db8500.h"
#include "pins-db8500.h"
#include "pins-db8500.h"
/* MSP1/3 Tx/Rx usage protection */
static
DEFINE_SPINLOCK
(
msp_rxtx_lock
);
/* Reference Count */
static
int
msp_rxtx_ref
;
/* Pin modes */
struct
pinctrl
*
msp1_p
;
struct
pinctrl_state
*
msp1_def
;
struct
pinctrl_state
*
msp1_sleep
;
int
msp13_i2s_init
(
void
)
{
int
retval
=
0
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
msp_rxtx_lock
,
flags
);
if
(
msp_rxtx_ref
==
0
&&
!
(
IS_ERR
(
msp1_p
)
||
IS_ERR
(
msp1_def
)))
{
retval
=
pinctrl_select_state
(
msp1_p
,
msp1_def
);
if
(
retval
)
pr_err
(
"could not set MSP1 defstate
\n
"
);
}
if
(
!
retval
)
msp_rxtx_ref
++
;
spin_unlock_irqrestore
(
&
msp_rxtx_lock
,
flags
);
return
retval
;
}
int
msp13_i2s_exit
(
void
)
{
int
retval
=
0
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
msp_rxtx_lock
,
flags
);
WARN_ON
(
!
msp_rxtx_ref
);
msp_rxtx_ref
--
;
if
(
msp_rxtx_ref
==
0
&&
!
(
IS_ERR
(
msp1_p
)
||
IS_ERR
(
msp1_sleep
)))
{
retval
=
pinctrl_select_state
(
msp1_p
,
msp1_sleep
);
if
(
retval
)
pr_err
(
"could not set MSP1 sleepstate
\n
"
);
}
spin_unlock_irqrestore
(
&
msp_rxtx_lock
,
flags
);
return
retval
;
}
static
struct
stedma40_chan_cfg
msp0_dma_rx
=
{
static
struct
stedma40_chan_cfg
msp0_dma_rx
=
{
.
high_priority
=
true
,
.
high_priority
=
true
,
.
dir
=
STEDMA40_PERIPH_TO_MEM
,
.
dir
=
STEDMA40_PERIPH_TO_MEM
,
...
@@ -132,8 +84,6 @@ static struct msp_i2s_platform_data msp1_platform_data = {
...
@@ -132,8 +84,6 @@ static struct msp_i2s_platform_data msp1_platform_data = {
.
id
=
MSP_I2S_1
,
.
id
=
MSP_I2S_1
,
.
msp_i2s_dma_rx
=
NULL
,
.
msp_i2s_dma_rx
=
NULL
,
.
msp_i2s_dma_tx
=
&
msp1_dma_tx
,
.
msp_i2s_dma_tx
=
&
msp1_dma_tx
,
.
msp_i2s_init
=
msp13_i2s_init
,
.
msp_i2s_exit
=
msp13_i2s_exit
,
};
};
static
struct
stedma40_chan_cfg
msp2_dma_rx
=
{
static
struct
stedma40_chan_cfg
msp2_dma_rx
=
{
...
@@ -219,49 +169,22 @@ static struct msp_i2s_platform_data msp3_platform_data = {
...
@@ -219,49 +169,22 @@ static struct msp_i2s_platform_data msp3_platform_data = {
.
id
=
MSP_I2S_3
,
.
id
=
MSP_I2S_3
,
.
msp_i2s_dma_rx
=
&
msp1_dma_rx
,
.
msp_i2s_dma_rx
=
&
msp1_dma_rx
,
.
msp_i2s_dma_tx
=
NULL
,
.
msp_i2s_dma_tx
=
NULL
,
.
msp_i2s_init
=
msp13_i2s_init
,
.
msp_i2s_exit
=
msp13_i2s_exit
,
};
};
int
mop500_msp_init
(
struct
device
*
parent
)
int
mop500_msp_init
(
struct
device
*
parent
)
{
{
struct
platform_device
*
msp1
;
pr_info
(
"%s: Register platform-device 'snd-soc-mop500'.
\n
"
,
__func__
);
pr_info
(
"%s: Register platform-device 'snd-soc-mop500'.
\n
"
,
__func__
);
platform_device_register
(
&
snd_soc_mop500
);
platform_device_register
(
&
snd_soc_mop500
);
pr_info
(
"Initialize MSP I2S-devices.
\n
"
);
pr_info
(
"Initialize MSP I2S-devices.
\n
"
);
db8500_add_msp_i2s
(
parent
,
0
,
U8500_MSP0_BASE
,
IRQ_DB8500_MSP0
,
db8500_add_msp_i2s
(
parent
,
0
,
U8500_MSP0_BASE
,
IRQ_DB8500_MSP0
,
&
msp0_platform_data
);
&
msp0_platform_data
);
msp1
=
db8500_add_msp_i2s
(
parent
,
1
,
U8500_MSP1_BASE
,
IRQ_DB8500_MSP1
,
db8500_add_msp_i2s
(
parent
,
1
,
U8500_MSP1_BASE
,
IRQ_DB8500_MSP1
,
&
msp1_platform_data
);
&
msp1_platform_data
);
db8500_add_msp_i2s
(
parent
,
2
,
U8500_MSP2_BASE
,
IRQ_DB8500_MSP2
,
db8500_add_msp_i2s
(
parent
,
2
,
U8500_MSP2_BASE
,
IRQ_DB8500_MSP2
,
&
msp2_platform_data
);
&
msp2_platform_data
);
db8500_add_msp_i2s
(
parent
,
3
,
U8500_MSP3_BASE
,
IRQ_DB8500_MSP1
,
db8500_add_msp_i2s
(
parent
,
3
,
U8500_MSP3_BASE
,
IRQ_DB8500_MSP1
,
&
msp3_platform_data
);
&
msp3_platform_data
);
/* Get the pinctrl handle for MSP1 */
if
(
msp1
)
{
msp1_p
=
pinctrl_get
(
&
msp1
->
dev
);
if
(
IS_ERR
(
msp1_p
))
dev_err
(
&
msp1
->
dev
,
"could not get MSP1 pinctrl
\n
"
);
else
{
msp1_def
=
pinctrl_lookup_state
(
msp1_p
,
PINCTRL_STATE_DEFAULT
);
if
(
IS_ERR
(
msp1_def
))
{
dev_err
(
&
msp1
->
dev
,
"could not get MSP1 defstate
\n
"
);
}
msp1_sleep
=
pinctrl_lookup_state
(
msp1_p
,
PINCTRL_STATE_SLEEP
);
if
(
IS_ERR
(
msp1_sleep
))
dev_err
(
&
msp1
->
dev
,
"could not get MSP1 idlestate
\n
"
);
}
}
pr_info
(
"%s: Register platform-device 'ux500-pcm'
\n
"
,
__func__
);
platform_device_register
(
&
ux500_pcm
);
return
0
;
return
0
;
}
}
arch/arm/mach-ux500/include/mach/msp.h
浏览文件 @
2ef39e60
...
@@ -22,8 +22,6 @@ struct msp_i2s_platform_data {
...
@@ -22,8 +22,6 @@ struct msp_i2s_platform_data {
enum
msp_i2s_id
id
;
enum
msp_i2s_id
id
;
struct
stedma40_chan_cfg
*
msp_i2s_dma_rx
;
struct
stedma40_chan_cfg
*
msp_i2s_dma_rx
;
struct
stedma40_chan_cfg
*
msp_i2s_dma_tx
;
struct
stedma40_chan_cfg
*
msp_i2s_dma_tx
;
int
(
*
msp_i2s_init
)
(
void
);
int
(
*
msp_i2s_exit
)
(
void
);
};
};
#endif
#endif
include/linux/mfd/abx500/ab8500-codec.h
浏览文件 @
2ef39e60
...
@@ -23,7 +23,8 @@ enum amic_type {
...
@@ -23,7 +23,8 @@ enum amic_type {
/* Mic-biases */
/* Mic-biases */
enum
amic_micbias
{
enum
amic_micbias
{
AMIC_MICBIAS_VAMIC1
,
AMIC_MICBIAS_VAMIC1
,
AMIC_MICBIAS_VAMIC2
AMIC_MICBIAS_VAMIC2
,
AMIC_MICBIAS_UNKNOWN
};
};
/* Bias-voltage */
/* Bias-voltage */
...
@@ -31,7 +32,8 @@ enum ear_cm_voltage {
...
@@ -31,7 +32,8 @@ enum ear_cm_voltage {
EAR_CMV_0_95V
,
EAR_CMV_0_95V
,
EAR_CMV_1_10V
,
EAR_CMV_1_10V
,
EAR_CMV_1_27V
,
EAR_CMV_1_27V
,
EAR_CMV_1_58V
EAR_CMV_1_58V
,
EAR_CMV_UNKNOWN
};
};
/* Analog microphone settings */
/* Analog microphone settings */
...
...
sound/soc/codecs/ab8500-codec.c
浏览文件 @
2ef39e60
...
@@ -34,6 +34,7 @@
...
@@ -34,6 +34,7 @@
#include <linux/mfd/abx500/ab8500-sysctrl.h>
#include <linux/mfd/abx500/ab8500-sysctrl.h>
#include <linux/mfd/abx500/ab8500-codec.h>
#include <linux/mfd/abx500/ab8500-codec.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/of.h>
#include <sound/core.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm.h>
...
@@ -2394,9 +2395,65 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = {
...
@@ -2394,9 +2395,65 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = {
}
}
};
};
static
void
ab8500_codec_of_probe
(
struct
device
*
dev
,
struct
device_node
*
np
,
struct
ab8500_codec_platform_data
*
codec
)
{
u32
value
;
if
(
of_get_property
(
np
,
"stericsson,amic1-type-single-ended"
,
NULL
))
codec
->
amics
.
mic1_type
=
AMIC_TYPE_SINGLE_ENDED
;
else
codec
->
amics
.
mic1_type
=
AMIC_TYPE_DIFFERENTIAL
;
if
(
of_get_property
(
np
,
"stericsson,amic2-type-single-ended"
,
NULL
))
codec
->
amics
.
mic2_type
=
AMIC_TYPE_SINGLE_ENDED
;
else
codec
->
amics
.
mic2_type
=
AMIC_TYPE_DIFFERENTIAL
;
/* Has a non-standard Vamic been requested? */
if
(
of_get_property
(
np
,
"stericsson,amic1a-bias-vamic2"
,
NULL
))
codec
->
amics
.
mic1a_micbias
=
AMIC_MICBIAS_VAMIC2
;
else
codec
->
amics
.
mic1a_micbias
=
AMIC_MICBIAS_VAMIC1
;
if
(
of_get_property
(
np
,
"stericsson,amic1b-bias-vamic2"
,
NULL
))
codec
->
amics
.
mic1b_micbias
=
AMIC_MICBIAS_VAMIC2
;
else
codec
->
amics
.
mic1b_micbias
=
AMIC_MICBIAS_VAMIC1
;
if
(
of_get_property
(
np
,
"stericsson,amic2-bias-vamic1"
,
NULL
))
codec
->
amics
.
mic2_micbias
=
AMIC_MICBIAS_VAMIC1
;
else
codec
->
amics
.
mic2_micbias
=
AMIC_MICBIAS_VAMIC2
;
if
(
!
of_property_read_u32
(
np
,
"stericsson,earpeice-cmv"
,
&
value
))
{
switch
(
value
)
{
case
950
:
codec
->
ear_cmv
=
EAR_CMV_0_95V
;
break
;
case
1100
:
codec
->
ear_cmv
=
EAR_CMV_1_10V
;
break
;
case
1270
:
codec
->
ear_cmv
=
EAR_CMV_1_27V
;
break
;
case
1580
:
codec
->
ear_cmv
=
EAR_CMV_1_58V
;
break
;
default
:
codec
->
ear_cmv
=
EAR_CMV_UNKNOWN
;
dev_err
(
dev
,
"Unsuitable earpiece voltage found in DT
\n
"
);
}
}
else
{
dev_warn
(
dev
,
"No earpiece voltage found in DT - using default
\n
"
);
codec
->
ear_cmv
=
EAR_CMV_0_95V
;
}
}
static
int
ab8500_codec_probe
(
struct
snd_soc_codec
*
codec
)
static
int
ab8500_codec_probe
(
struct
snd_soc_codec
*
codec
)
{
{
struct
device
*
dev
=
codec
->
dev
;
struct
device
*
dev
=
codec
->
dev
;
struct
device_node
*
np
=
dev
->
of_node
;
struct
ab8500_codec_drvdata
*
drvdata
=
dev_get_drvdata
(
dev
);
struct
ab8500_codec_drvdata
*
drvdata
=
dev_get_drvdata
(
dev
);
struct
ab8500_platform_data
*
pdata
;
struct
ab8500_platform_data
*
pdata
;
struct
filter_control
*
fc
;
struct
filter_control
*
fc
;
...
@@ -2407,6 +2464,30 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
...
@@ -2407,6 +2464,30 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
/* Setup AB8500 according to board-settings */
/* Setup AB8500 according to board-settings */
pdata
=
dev_get_platdata
(
dev
->
parent
);
pdata
=
dev_get_platdata
(
dev
->
parent
);
if
(
np
)
{
if
(
!
pdata
)
pdata
=
devm_kzalloc
(
dev
,
sizeof
(
struct
ab8500_platform_data
),
GFP_KERNEL
);
if
(
pdata
&&
!
pdata
->
codec
)
pdata
->
codec
=
devm_kzalloc
(
dev
,
sizeof
(
struct
ab8500_codec_platform_data
),
GFP_KERNEL
);
if
(
!
(
pdata
&&
pdata
->
codec
))
return
-
ENOMEM
;
ab8500_codec_of_probe
(
dev
,
np
,
pdata
->
codec
);
}
else
{
if
(
!
(
pdata
&&
pdata
->
codec
))
{
dev_err
(
dev
,
"No codec platform data or DT found
\n
"
);
return
-
EINVAL
;
}
}
status
=
ab8500_audio_setup_mics
(
codec
,
&
pdata
->
codec
->
amics
);
status
=
ab8500_audio_setup_mics
(
codec
,
&
pdata
->
codec
->
amics
);
if
(
status
<
0
)
{
if
(
status
<
0
)
{
pr_err
(
"%s: Failed to setup mics (%d)!
\n
"
,
__func__
,
status
);
pr_err
(
"%s: Failed to setup mics (%d)!
\n
"
,
__func__
,
status
);
...
...
sound/soc/ux500/mop500.c
浏览文件 @
2ef39e60
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi.h>
#include <linux/of.h>
#include <sound/soc.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/initval.h>
...
@@ -56,16 +57,47 @@ static struct snd_soc_card mop500_card = {
...
@@ -56,16 +57,47 @@ static struct snd_soc_card mop500_card = {
.
num_links
=
ARRAY_SIZE
(
mop500_dai_links
),
.
num_links
=
ARRAY_SIZE
(
mop500_dai_links
),
};
};
static
int
__devinit
mop500_of_probe
(
struct
platform_device
*
pdev
,
struct
device_node
*
np
)
{
struct
device_node
*
codec_np
,
*
msp_np
[
2
];
int
i
;
msp_np
[
0
]
=
of_parse_phandle
(
np
,
"stericsson,cpu-dai"
,
0
);
msp_np
[
1
]
=
of_parse_phandle
(
np
,
"stericsson,cpu-dai"
,
1
);
codec_np
=
of_parse_phandle
(
np
,
"stericsson,audio-codec"
,
0
);
if
(
!
(
msp_np
[
0
]
&&
msp_np
[
1
]
&&
codec_np
))
{
dev_err
(
&
pdev
->
dev
,
"Phandle missing or invalid
\n
"
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
2
;
i
++
)
{
mop500_dai_links
[
i
].
cpu_of_node
=
msp_np
[
i
];
mop500_dai_links
[
i
].
cpu_dai_name
=
NULL
;
mop500_dai_links
[
i
].
codec_of_node
=
codec_np
;
mop500_dai_links
[
i
].
codec_name
=
NULL
;
}
snd_soc_of_parse_card_name
(
&
mop500_card
,
"stericsson,card-name"
);
return
0
;
}
static
int
__devinit
mop500_probe
(
struct
platform_device
*
pdev
)
static
int
__devinit
mop500_probe
(
struct
platform_device
*
pdev
)
{
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
int
ret
;
int
ret
;
pr_debug
(
"%s: Enter.
\n
"
,
__func__
);
dev_dbg
(
&
pdev
->
dev
,
"%s: Enter.
\n
"
,
__func__
);
dev_dbg
(
&
pdev
->
dev
,
"%s: Enter.
\n
"
,
__func__
);
mop500_card
.
dev
=
&
pdev
->
dev
;
mop500_card
.
dev
=
&
pdev
->
dev
;
if
(
np
)
{
ret
=
mop500_of_probe
(
pdev
,
np
);
if
(
ret
)
return
ret
;
}
dev_dbg
(
&
pdev
->
dev
,
"%s: Card %s: Set platform drvdata.
\n
"
,
dev_dbg
(
&
pdev
->
dev
,
"%s: Card %s: Set platform drvdata.
\n
"
,
__func__
,
mop500_card
.
name
);
__func__
,
mop500_card
.
name
);
platform_set_drvdata
(
pdev
,
&
mop500_card
);
platform_set_drvdata
(
pdev
,
&
mop500_card
);
...
@@ -83,8 +115,7 @@ static int __devinit mop500_probe(struct platform_device *pdev)
...
@@ -83,8 +115,7 @@ static int __devinit mop500_probe(struct platform_device *pdev)
ret
=
snd_soc_register_card
(
&
mop500_card
);
ret
=
snd_soc_register_card
(
&
mop500_card
);
if
(
ret
)
if
(
ret
)
dev_err
(
&
pdev
->
dev
,
dev_err
(
&
pdev
->
dev
,
"Error: snd_soc_register_card failed (%d)!
\n
"
,
"Error: snd_soc_register_card failed (%d)!
\n
"
,
ret
);
ret
);
return
ret
;
return
ret
;
}
}
...
@@ -101,10 +132,16 @@ static int __devexit mop500_remove(struct platform_device *pdev)
...
@@ -101,10 +132,16 @@ static int __devexit mop500_remove(struct platform_device *pdev)
return
0
;
return
0
;
}
}
static
const
struct
of_device_id
snd_soc_mop500_match
[]
=
{
{
.
compatible
=
"stericsson,snd-soc-mop500"
,
},
{},
};
static
struct
platform_driver
snd_soc_mop500_driver
=
{
static
struct
platform_driver
snd_soc_mop500_driver
=
{
.
driver
=
{
.
driver
=
{
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
name
=
"snd-soc-mop500"
,
.
name
=
"snd-soc-mop500"
,
.
of_match_table
=
snd_soc_mop500_match
,
},
},
.
probe
=
mop500_probe
,
.
probe
=
mop500_probe
,
.
remove
=
__devexit_p
(
mop500_remove
),
.
remove
=
__devexit_p
(
mop500_remove
),
...
...
sound/soc/ux500/ux500_msp_dai.c
浏览文件 @
2ef39e60
...
@@ -833,10 +833,16 @@ static int __devexit ux500_msp_drv_remove(struct platform_device *pdev)
...
@@ -833,10 +833,16 @@ static int __devexit ux500_msp_drv_remove(struct platform_device *pdev)
return
0
;
return
0
;
}
}
static
const
struct
of_device_id
ux500_msp_i2s_match
[]
=
{
{
.
compatible
=
"stericsson,ux500-msp-i2s"
,
},
{},
};
static
struct
platform_driver
msp_i2s_driver
=
{
static
struct
platform_driver
msp_i2s_driver
=
{
.
driver
=
{
.
driver
=
{
.
name
=
"ux500-msp-i2s"
,
.
name
=
"ux500-msp-i2s"
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
ux500_msp_i2s_match
,
},
},
.
probe
=
ux500_msp_drv_probe
,
.
probe
=
ux500_msp_drv_probe
,
.
remove
=
ux500_msp_drv_remove
,
.
remove
=
ux500_msp_drv_remove
,
...
...
sound/soc/ux500/ux500_msp_i2s.c
浏览文件 @
2ef39e60
...
@@ -15,8 +15,10 @@
...
@@ -15,8 +15,10 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <mach/hardware.h>
#include <mach/hardware.h>
#include <mach/msp.h>
#include <mach/msp.h>
...
@@ -25,6 +27,9 @@
...
@@ -25,6 +27,9 @@
#include "ux500_msp_i2s.h"
#include "ux500_msp_i2s.h"
/* MSP1/3 Tx/Rx usage protection */
static
DEFINE_SPINLOCK
(
msp_rxtx_lock
);
/* Protocol desciptors */
/* Protocol desciptors */
static
const
struct
msp_protdesc
prot_descs
[]
=
{
static
const
struct
msp_protdesc
prot_descs
[]
=
{
{
/* I2S */
{
/* I2S */
...
@@ -352,17 +357,23 @@ static int configure_multichannel(struct ux500_msp *msp,
...
@@ -352,17 +357,23 @@ static int configure_multichannel(struct ux500_msp *msp,
static
int
enable_msp
(
struct
ux500_msp
*
msp
,
struct
ux500_msp_config
*
config
)
static
int
enable_msp
(
struct
ux500_msp
*
msp
,
struct
ux500_msp_config
*
config
)
{
{
int
status
=
0
;
int
status
=
0
,
retval
=
0
;
u32
reg_val_DMACR
,
reg_val_GCR
;
u32
reg_val_DMACR
,
reg_val_GCR
;
unsigned
long
flags
;
/* Check msp state whether in RUN or CONFIGURED Mode */
/* Check msp state whether in RUN or CONFIGURED Mode */
if
((
msp
->
msp_state
==
MSP_STATE_IDLE
)
&&
(
msp
->
plat_init
))
{
if
(
msp
->
msp_state
==
MSP_STATE_IDLE
)
{
status
=
msp
->
plat_init
();
spin_lock_irqsave
(
&
msp_rxtx_lock
,
flags
);
if
(
status
)
{
if
(
msp
->
pinctrl_rxtx_ref
==
0
&&
dev_err
(
msp
->
dev
,
"%s: ERROR: Failed to init MSP (%d)!
\n
"
,
!
(
IS_ERR
(
msp
->
pinctrl_p
)
||
IS_ERR
(
msp
->
pinctrl_def
)))
{
__func__
,
status
);
retval
=
pinctrl_select_state
(
msp
->
pinctrl_p
,
return
status
;
msp
->
pinctrl_def
);
if
(
retval
)
pr_err
(
"could not set MSP defstate
\n
"
);
}
}
if
(
!
retval
)
msp
->
pinctrl_rxtx_ref
++
;
spin_unlock_irqrestore
(
&
msp_rxtx_lock
,
flags
);
}
}
/* Configure msp with protocol dependent settings */
/* Configure msp with protocol dependent settings */
...
@@ -620,7 +631,8 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
...
@@ -620,7 +631,8 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
int
ux500_msp_i2s_close
(
struct
ux500_msp
*
msp
,
unsigned
int
dir
)
int
ux500_msp_i2s_close
(
struct
ux500_msp
*
msp
,
unsigned
int
dir
)
{
{
int
status
=
0
;
int
status
=
0
,
retval
=
0
;
unsigned
long
flags
;
dev_dbg
(
msp
->
dev
,
"%s: Enter (dir = 0x%01x).
\n
"
,
__func__
,
dir
);
dev_dbg
(
msp
->
dev
,
"%s: Enter (dir = 0x%01x).
\n
"
,
__func__
,
dir
);
...
@@ -631,12 +643,19 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
...
@@ -631,12 +643,19 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
writel
((
readl
(
msp
->
registers
+
MSP_GCR
)
&
writel
((
readl
(
msp
->
registers
+
MSP_GCR
)
&
(
~
(
FRAME_GEN_ENABLE
|
SRG_ENABLE
))),
(
~
(
FRAME_GEN_ENABLE
|
SRG_ENABLE
))),
msp
->
registers
+
MSP_GCR
);
msp
->
registers
+
MSP_GCR
);
if
(
msp
->
plat_exit
)
status
=
msp
->
plat_exit
();
spin_lock_irqsave
(
&
msp_rxtx_lock
,
flags
);
if
(
status
)
WARN_ON
(
!
msp
->
pinctrl_rxtx_ref
);
dev_warn
(
msp
->
dev
,
msp
->
pinctrl_rxtx_ref
--
;
"%s: WARN: ux500_msp_i2s_exit failed (%d)!
\n
"
,
if
(
msp
->
pinctrl_rxtx_ref
==
0
&&
__func__
,
status
);
!
(
IS_ERR
(
msp
->
pinctrl_p
)
||
IS_ERR
(
msp
->
pinctrl_sleep
)))
{
retval
=
pinctrl_select_state
(
msp
->
pinctrl_p
,
msp
->
pinctrl_sleep
);
if
(
retval
)
pr_err
(
"could not set MSP sleepstate
\n
"
);
}
spin_unlock_irqrestore
(
&
msp_rxtx_lock
,
flags
);
writel
(
0
,
msp
->
registers
+
MSP_GCR
);
writel
(
0
,
msp
->
registers
+
MSP_GCR
);
writel
(
0
,
msp
->
registers
+
MSP_TCF
);
writel
(
0
,
msp
->
registers
+
MSP_TCF
);
writel
(
0
,
msp
->
registers
+
MSP_RCF
);
writel
(
0
,
msp
->
registers
+
MSP_RCF
);
...
@@ -665,20 +684,33 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
...
@@ -665,20 +684,33 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
{
{
struct
resource
*
res
=
NULL
;
struct
resource
*
res
=
NULL
;
struct
i2s_controller
*
i2s_cont
;
struct
i2s_controller
*
i2s_cont
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
ux500_msp
*
msp
;
struct
ux500_msp
*
msp
;
dev_dbg
(
&
pdev
->
dev
,
"%s: Enter (name: %s, id: %d).
\n
"
,
__func__
,
pdev
->
name
,
platform_data
->
id
);
*
msp_p
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
ux500_msp
),
GFP_KERNEL
);
*
msp_p
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
ux500_msp
),
GFP_KERNEL
);
msp
=
*
msp_p
;
msp
=
*
msp_p
;
if
(
!
msp
)
if
(
!
msp
)
return
-
ENOMEM
;
return
-
ENOMEM
;
if
(
np
)
{
if
(
!
platform_data
)
{
platform_data
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
msp_i2s_platform_data
),
GFP_KERNEL
);
if
(
!
platform_data
)
ret
=
-
ENOMEM
;
}
}
else
if
(
!
platform_data
)
ret
=
-
EINVAL
;
if
(
ret
)
goto
err_res
;
dev_dbg
(
&
pdev
->
dev
,
"%s: Enter (name: %s, id: %d).
\n
"
,
__func__
,
pdev
->
name
,
platform_data
->
id
);
msp
->
id
=
platform_data
->
id
;
msp
->
id
=
platform_data
->
id
;
msp
->
dev
=
&
pdev
->
dev
;
msp
->
dev
=
&
pdev
->
dev
;
msp
->
plat_init
=
platform_data
->
msp_i2s_init
;
msp
->
plat_exit
=
platform_data
->
msp_i2s_exit
;
msp
->
dma_cfg_rx
=
platform_data
->
msp_i2s_dma_rx
;
msp
->
dma_cfg_rx
=
platform_data
->
msp_i2s_dma_rx
;
msp
->
dma_cfg_tx
=
platform_data
->
msp_i2s_dma_tx
;
msp
->
dma_cfg_tx
=
platform_data
->
msp_i2s_dma_tx
;
...
@@ -715,6 +747,25 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
...
@@ -715,6 +747,25 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
dev_dbg
(
&
pdev
->
dev
,
"I2S device-name: '%s'
\n
"
,
i2s_cont
->
name
);
dev_dbg
(
&
pdev
->
dev
,
"I2S device-name: '%s'
\n
"
,
i2s_cont
->
name
);
msp
->
i2s_cont
=
i2s_cont
;
msp
->
i2s_cont
=
i2s_cont
;
msp
->
pinctrl_p
=
pinctrl_get
(
msp
->
dev
);
if
(
IS_ERR
(
msp
->
pinctrl_p
))
dev_err
(
&
pdev
->
dev
,
"could not get MSP pinctrl
\n
"
);
else
{
msp
->
pinctrl_def
=
pinctrl_lookup_state
(
msp
->
pinctrl_p
,
PINCTRL_STATE_DEFAULT
);
if
(
IS_ERR
(
msp
->
pinctrl_def
))
{
dev_err
(
&
pdev
->
dev
,
"could not get MSP defstate (%li)
\n
"
,
PTR_ERR
(
msp
->
pinctrl_def
));
}
msp
->
pinctrl_sleep
=
pinctrl_lookup_state
(
msp
->
pinctrl_p
,
PINCTRL_STATE_SLEEP
);
if
(
IS_ERR
(
msp
->
pinctrl_sleep
))
dev_err
(
&
pdev
->
dev
,
"could not get MSP idlestate (%li)
\n
"
,
PTR_ERR
(
msp
->
pinctrl_def
));
}
return
0
;
return
0
;
}
}
...
...
sound/soc/ux500/ux500_msp_i2s.h
浏览文件 @
2ef39e60
...
@@ -524,14 +524,18 @@ struct ux500_msp {
...
@@ -524,14 +524,18 @@ struct ux500_msp {
struct
dma_chan
*
rx_pipeid
;
struct
dma_chan
*
rx_pipeid
;
enum
msp_state
msp_state
;
enum
msp_state
msp_state
;
int
(
*
transfer
)
(
struct
ux500_msp
*
msp
,
struct
i2s_message
*
message
);
int
(
*
transfer
)
(
struct
ux500_msp
*
msp
,
struct
i2s_message
*
message
);
int
(
*
plat_init
)
(
void
);
int
(
*
plat_exit
)
(
void
);
struct
timer_list
notify_timer
;
struct
timer_list
notify_timer
;
int
def_elem_len
;
int
def_elem_len
;
unsigned
int
dir_busy
;
unsigned
int
dir_busy
;
int
loopback_enable
;
int
loopback_enable
;
u32
backup_regs
[
MAX_MSP_BACKUP_REGS
];
u32
backup_regs
[
MAX_MSP_BACKUP_REGS
];
unsigned
int
f_bitclk
;
unsigned
int
f_bitclk
;
/* Pin modes */
struct
pinctrl
*
pinctrl_p
;
struct
pinctrl_state
*
pinctrl_def
;
struct
pinctrl_state
*
pinctrl_sleep
;
/* Reference Count */
int
pinctrl_rxtx_ref
;
};
};
struct
ux500_msp_dma_params
{
struct
ux500_msp_dma_params
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录