Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
458bcee9
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看板
提交
458bcee9
编写于
6月 17, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/ux500' into asoc-next
上级
93d4c1e0
eef6473f
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
159 addition
and
205 deletion
+159
-205
sound/soc/codecs/ab8500-codec.c
sound/soc/codecs/ab8500-codec.c
+46
-33
sound/soc/codecs/ab8500-codec.h
sound/soc/codecs/ab8500-codec.h
+22
-20
sound/soc/ux500/mop500_ab8500.c
sound/soc/ux500/mop500_ab8500.c
+36
-0
sound/soc/ux500/ux500_msp_dai.c
sound/soc/ux500/ux500_msp_dai.c
+4
-7
sound/soc/ux500/ux500_msp_dai.h
sound/soc/ux500/ux500_msp_dai.h
+0
-4
sound/soc/ux500/ux500_msp_i2s.c
sound/soc/ux500/ux500_msp_i2s.c
+11
-77
sound/soc/ux500/ux500_msp_i2s.h
sound/soc/ux500/ux500_msp_i2s.h
+10
-64
sound/soc/ux500/ux500_pcm.c
sound/soc/ux500/ux500_pcm.c
+30
-0
未找到文件。
sound/soc/codecs/ab8500-codec.c
浏览文件 @
458bcee9
...
...
@@ -2236,7 +2236,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
int
slots
,
int
slot_width
)
{
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
unsigned
int
val
,
mask
,
slots_active
;
unsigned
int
val
,
mask
,
slot
,
slot
s_active
;
mask
=
BIT
(
AB8500_DIGIFCONF2_IF0WL0
)
|
BIT
(
AB8500_DIGIFCONF2_IF0WL1
);
...
...
@@ -2292,27 +2292,34 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
snd_soc_update_bits
(
codec
,
AB8500_DIGIFCONF1
,
mask
,
val
);
/* Setup TDM DA according to active tx slots */
if
(
tx_mask
&
~
0xff
)
return
-
EINVAL
;
mask
=
AB8500_DASLOTCONFX_SLTODAX_MASK
;
tx_mask
=
tx_mask
<<
AB8500_DA_DATA0_OFFSET
;
slots_active
=
hweight32
(
tx_mask
);
dev_dbg
(
dai
->
codec
->
dev
,
"%s: Slots, active, TX: %d
\n
"
,
__func__
,
slots_active
);
switch
(
slots_active
)
{
case
0
:
break
;
case
1
:
/* Slot 9 -> DA_IN1 & DA_IN3 */
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF1
,
mask
,
11
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF3
,
mask
,
11
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF2
,
mask
,
11
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF4
,
mask
,
11
);
slot
=
find_first_bit
((
unsigned
long
*
)
&
tx_mask
,
32
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF1
,
mask
,
slot
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF3
,
mask
,
slot
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF2
,
mask
,
slot
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF4
,
mask
,
slot
);
break
;
case
2
:
/* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF1
,
mask
,
9
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF3
,
mask
,
9
);
s
nd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF2
,
mask
,
1
1
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF
4
,
mask
,
11
);
slot
=
find_first_bit
((
unsigned
long
*
)
&
tx_mask
,
32
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF1
,
mask
,
slot
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF3
,
mask
,
slot
);
s
lot
=
find_next_bit
((
unsigned
long
*
)
&
tx_mask
,
32
,
slot
+
1
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF
2
,
mask
,
slot
);
snd_soc_update_bits
(
codec
,
AB8500_DASLOTCONF4
,
mask
,
slot
);
break
;
case
8
:
dev_dbg
(
dai
->
codec
->
dev
,
...
...
@@ -2327,25 +2334,36 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
}
/* Setup TDM AD according to active RX-slots */
if
(
rx_mask
&
~
0xff
)
return
-
EINVAL
;
rx_mask
=
rx_mask
<<
AB8500_AD_DATA0_OFFSET
;
slots_active
=
hweight32
(
rx_mask
);
dev_dbg
(
dai
->
codec
->
dev
,
"%s: Slots, active, RX: %d
\n
"
,
__func__
,
slots_active
);
switch
(
slots_active
)
{
case
0
:
break
;
case
1
:
/* AD_OUT3 -> slot 0 & 1 */
snd_soc_update_bits
(
codec
,
AB8500_ADSLOTSEL
1
,
AB8500_MASK_ALL
,
AB8500_
ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN
|
AB8500_ADSLOTSELX_AD_OUT
3_TO_SLOT_ODD
);
slot
=
find_first_bit
((
unsigned
long
*
)
&
rx_mask
,
32
);
snd_soc_update_bits
(
codec
,
AB8500_ADSLOTSEL
(
slot
)
,
AB8500_
MASK_SLOT
(
slot
),
AB8500_ADSLOTSELX_AD_OUT
_TO_SLOT
(
AB8500_AD_OUT3
,
slot
)
);
break
;
case
2
:
/* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */
slot
=
find_first_bit
((
unsigned
long
*
)
&
rx_mask
,
32
);
snd_soc_update_bits
(
codec
,
AB8500_ADSLOTSEL
(
slot
),
AB8500_MASK_SLOT
(
slot
),
AB8500_ADSLOTSELX_AD_OUT_TO_SLOT
(
AB8500_AD_OUT3
,
slot
));
slot
=
find_next_bit
((
unsigned
long
*
)
&
rx_mask
,
32
,
slot
+
1
);
snd_soc_update_bits
(
codec
,
AB8500_ADSLOTSEL1
,
AB8500_MASK_ALL
,
AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN
|
AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD
);
AB8500_ADSLOTSEL
(
slot
),
AB8500_MASK_SLOT
(
slot
),
AB8500_ADSLOTSELX_AD_OUT_TO_SLOT
(
AB8500_AD_OUT2
,
slot
));
break
;
case
8
:
dev_dbg
(
dai
->
codec
->
dev
,
...
...
@@ -2362,6 +2380,11 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
return
0
;
}
static
const
struct
snd_soc_dai_ops
ab8500_codec_ops
=
{
.
set_fmt
=
ab8500_codec_set_dai_fmt
,
.
set_tdm_slot
=
ab8500_codec_set_dai_tdm_slot
,
};
static
struct
snd_soc_dai_driver
ab8500_codec_dai
[]
=
{
{
.
name
=
"ab8500-codec-dai.0"
,
...
...
@@ -2373,12 +2396,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
.
rates
=
AB8500_SUPPORTED_RATE
,
.
formats
=
AB8500_SUPPORTED_FMT
,
},
.
ops
=
(
struct
snd_soc_dai_ops
[])
{
{
.
set_tdm_slot
=
ab8500_codec_set_dai_tdm_slot
,
.
set_fmt
=
ab8500_codec_set_dai_fmt
,
}
},
.
ops
=
&
ab8500_codec_ops
,
.
symmetric_rates
=
1
},
{
...
...
@@ -2391,12 +2409,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
.
rates
=
AB8500_SUPPORTED_RATE
,
.
formats
=
AB8500_SUPPORTED_FMT
,
},
.
ops
=
(
struct
snd_soc_dai_ops
[])
{
{
.
set_tdm_slot
=
ab8500_codec_set_dai_tdm_slot
,
.
set_fmt
=
ab8500_codec_set_dai_fmt
,
}
},
.
ops
=
&
ab8500_codec_ops
,
.
symmetric_rates
=
1
}
};
...
...
sound/soc/codecs/ab8500-codec.h
浏览文件 @
458bcee9
...
...
@@ -24,6 +24,13 @@
#define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000)
#define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE)
/* AB8500 interface slot offset definitions */
#define AB8500_AD_DATA0_OFFSET 0
#define AB8500_DA_DATA0_OFFSET 8
#define AB8500_AD_DATA1_OFFSET 16
#define AB8500_DA_DATA1_OFFSET 24
/* AB8500 audio bank (0x0d) register definitions */
#define AB8500_POWERUP 0x00
...
...
@@ -73,6 +80,7 @@
#define AB8500_ADSLOTSEL14 0x2C
#define AB8500_ADSLOTSEL15 0x2D
#define AB8500_ADSLOTSEL16 0x2E
#define AB8500_ADSLOTSEL(slot) (AB8500_ADSLOTSEL1 + (slot >> 1))
#define AB8500_ADSLOTHIZCTRL1 0x2F
#define AB8500_ADSLOTHIZCTRL2 0x30
#define AB8500_ADSLOTHIZCTRL3 0x31
...
...
@@ -144,6 +152,7 @@
#define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1)
#define AB8500_MASK_ALL 0xFF
#define AB8500_MASK_SLOT(slot) ((slot & 1) ? 0xF0 : 0x0F)
#define AB8500_MASK_NONE 0x00
/* AB8500_POWERUP */
...
...
@@ -347,28 +356,21 @@
#define AB8500_DIGIFCONF4_IF1WL0 0
/* AB8500_ADSLOTSELX */
#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD 0x00
#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x10
#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x20
#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x30
#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x40
#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x50
#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x60
#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x70
#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x80
#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0xF0
#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00
#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x01
#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x02
#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x03
#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x04
#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x05
#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x06
#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x07
#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x08
#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0x0F
#define AB8500_AD_OUT1 0x0
#define AB8500_AD_OUT2 0x1
#define AB8500_AD_OUT3 0x2
#define AB8500_AD_OUT4 0x3
#define AB8500_AD_OUT5 0x4
#define AB8500_AD_OUT6 0x5
#define AB8500_AD_OUT7 0x6
#define AB8500_AD_OUT8 0x7
#define AB8500_ZEROES 0x8
#define AB8500_TRISTATE 0xF
#define AB8500_ADSLOTSELX_EVEN_SHIFT 0
#define AB8500_ADSLOTSELX_ODD_SHIFT 4
#define AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(out, slot) \
((out) << (((slot) & 1) ? \
AB8500_ADSLOTSELX_ODD_SHIFT : AB8500_ADSLOTSELX_EVEN_SHIFT))
/* AB8500_ADSLOTHIZCTRL1 */
/* AB8500_ADSLOTHIZCTRL2 */
...
...
sound/soc/ux500/mop500_ab8500.c
浏览文件 @
458bcee9
...
...
@@ -16,6 +16,7 @@
#include <linux/device.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
...
...
@@ -24,6 +25,7 @@
#include "ux500_pcm.h"
#include "ux500_msp_dai.h"
#include "mop500_ab8500.h"
#include "../codecs/ab8500-codec.h"
#define TX_SLOT_MONO 0x0008
...
...
@@ -43,6 +45,12 @@
static
unsigned
int
tx_slots
=
DEF_TX_SLOTS
;
static
unsigned
int
rx_slots
=
DEF_RX_SLOTS
;
/* Configuration consistency parameters */
static
DEFINE_MUTEX
(
mop500_ab8500_params_lock
);
static
unsigned
long
mop500_ab8500_usage
;
static
int
mop500_ab8500_rate
;
static
int
mop500_ab8500_channels
;
/* Clocks */
static
const
char
*
const
enum_mclk
[]
=
{
"SYSCLK"
,
...
...
@@ -230,6 +238,21 @@ static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
substream
->
name
,
substream
->
number
);
/* Ensure configuration consistency between DAIs */
mutex_lock
(
&
mop500_ab8500_params_lock
);
if
(
mop500_ab8500_usage
)
{
if
(
mop500_ab8500_rate
!=
params_rate
(
params
)
||
mop500_ab8500_channels
!=
params_channels
(
params
))
{
mutex_unlock
(
&
mop500_ab8500_params_lock
);
return
-
EBUSY
;
}
}
else
{
mop500_ab8500_rate
=
params_rate
(
params
);
mop500_ab8500_channels
=
params_channels
(
params
);
}
__set_bit
(
cpu_dai
->
id
,
&
mop500_ab8500_usage
);
mutex_unlock
(
&
mop500_ab8500_params_lock
);
channels
=
params_channels
(
params
);
switch
(
params_format
(
params
))
{
...
...
@@ -328,9 +351,22 @@ static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
return
0
;
}
static
int
mop500_ab8500_hw_free
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
mutex_lock
(
&
mop500_ab8500_params_lock
);
__clear_bit
(
cpu_dai
->
id
,
&
mop500_ab8500_usage
);
mutex_unlock
(
&
mop500_ab8500_params_lock
);
return
0
;
}
struct
snd_soc_ops
mop500_ab8500_ops
[]
=
{
{
.
hw_params
=
mop500_ab8500_hw_params
,
.
hw_free
=
mop500_ab8500_hw_free
,
.
startup
=
mop500_ab8500_startup
,
.
shutdown
=
mop500_ab8500_shutdown
,
}
...
...
sound/soc/ux500/ux500_msp_dai.c
浏览文件 @
458bcee9
...
...
@@ -658,14 +658,11 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
{
struct
ux500_msp_i2s_drvdata
*
drvdata
=
dev_get_drvdata
(
dai
->
dev
);
d
rvdata
->
playback_dma_data
.
dma_cfg
=
drvdata
->
msp
->
dma_cfg_tx
;
d
rvdata
->
capture_dma_data
.
dma_cfg
=
drvdata
->
msp
->
dma_cfg_rx
;
d
ai
->
playback_dma_data
=
&
drvdata
->
msp
->
playback_dma_data
;
d
ai
->
capture_dma_data
=
&
drvdata
->
msp
->
capture_dma_data
;
dai
->
playback_dma_data
=
&
drvdata
->
playback_dma_data
;
dai
->
capture_dma_data
=
&
drvdata
->
capture_dma_data
;
drvdata
->
playback_dma_data
.
data_size
=
drvdata
->
slot_width
;
drvdata
->
capture_dma_data
.
data_size
=
drvdata
->
slot_width
;
drvdata
->
msp
->
playback_dma_data
.
data_size
=
drvdata
->
slot_width
;
drvdata
->
msp
->
capture_dma_data
.
data_size
=
drvdata
->
slot_width
;
return
0
;
}
...
...
sound/soc/ux500/ux500_msp_dai.h
浏览文件 @
458bcee9
...
...
@@ -51,15 +51,11 @@ enum ux500_msp_clock_id {
struct
ux500_msp_i2s_drvdata
{
struct
ux500_msp
*
msp
;
struct
regulator
*
reg_vape
;
struct
ux500_msp_dma_params
playback_dma_data
;
struct
ux500_msp_dma_params
capture_dma_data
;
unsigned
int
fmt
;
unsigned
int
tx_mask
;
unsigned
int
rx_mask
;
int
slots
;
int
slot_width
;
u8
configured
;
int
data_delay
;
/* Clocks */
unsigned
int
master_clk
;
...
...
sound/soc/ux500/ux500_msp_i2s.c
浏览文件 @
458bcee9
...
...
@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/io.h>
...
...
@@ -26,9 +25,6 @@
#include "ux500_msp_i2s.h"
/* MSP1/3 Tx/Rx usage protection */
static
DEFINE_SPINLOCK
(
msp_rxtx_lock
);
/* Protocol desciptors */
static
const
struct
msp_protdesc
prot_descs
[]
=
{
{
/* I2S */
...
...
@@ -356,24 +352,8 @@ static int configure_multichannel(struct ux500_msp *msp,
static
int
enable_msp
(
struct
ux500_msp
*
msp
,
struct
ux500_msp_config
*
config
)
{
int
status
=
0
,
retval
=
0
;
int
status
=
0
;
u32
reg_val_DMACR
,
reg_val_GCR
;
unsigned
long
flags
;
/* Check msp state whether in RUN or CONFIGURED Mode */
if
(
msp
->
msp_state
==
MSP_STATE_IDLE
)
{
spin_lock_irqsave
(
&
msp_rxtx_lock
,
flags
);
if
(
msp
->
pinctrl_rxtx_ref
==
0
&&
!
(
IS_ERR
(
msp
->
pinctrl_p
)
||
IS_ERR
(
msp
->
pinctrl_def
)))
{
retval
=
pinctrl_select_state
(
msp
->
pinctrl_p
,
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_protocol
(
msp
,
config
);
...
...
@@ -387,12 +367,14 @@ static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
}
/* Make sure the correct DMA-directions are configured */
if
((
config
->
direction
&
MSP_DIR_RX
)
&&
(
!
msp
->
dma_cfg_rx
))
{
if
((
config
->
direction
&
MSP_DIR_RX
)
&&
!
msp
->
capture_dma_data
.
dma_cfg
)
{
dev_err
(
msp
->
dev
,
"%s: ERROR: MSP RX-mode is not configured!"
,
__func__
);
return
-
EINVAL
;
}
if
((
config
->
direction
==
MSP_DIR_TX
)
&&
(
!
msp
->
dma_cfg_tx
))
{
if
((
config
->
direction
==
MSP_DIR_TX
)
&&
!
msp
->
playback_dma_data
.
dma_cfg
)
{
dev_err
(
msp
->
dev
,
"%s: ERROR: MSP TX-mode is not configured!"
,
__func__
);
return
-
EINVAL
;
...
...
@@ -630,8 +612,7 @@ 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
status
=
0
,
retval
=
0
;
unsigned
long
flags
;
int
status
=
0
;
dev_dbg
(
msp
->
dev
,
"%s: Enter (dir = 0x%01x).
\n
"
,
__func__
,
dir
);
...
...
@@ -643,18 +624,6 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
(
~
(
FRAME_GEN_ENABLE
|
SRG_ENABLE
))),
msp
->
registers
+
MSP_GCR
);
spin_lock_irqsave
(
&
msp_rxtx_lock
,
flags
);
WARN_ON
(
!
msp
->
pinctrl_rxtx_ref
);
msp
->
pinctrl_rxtx_ref
--
;
if
(
msp
->
pinctrl_rxtx_ref
==
0
&&
!
(
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_TCF
);
writel
(
0
,
msp
->
registers
+
MSP_RCF
);
...
...
@@ -682,7 +651,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
struct
msp_i2s_platform_data
*
platform_data
)
{
struct
resource
*
res
=
NULL
;
struct
i2s_controller
*
i2s_cont
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
ux500_msp
*
msp
;
...
...
@@ -707,8 +675,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
msp
->
id
=
platform_data
->
id
;
msp
->
dev
=
&
pdev
->
dev
;
msp
->
dma_cfg_rx
=
platform_data
->
msp_i2s_dma_r
x
;
msp
->
dma_cfg_tx
=
platform_data
->
msp_i2s_dma_t
x
;
msp
->
playback_dma_data
.
dma_cfg
=
platform_data
->
msp_i2s_dma_t
x
;
msp
->
capture_dma_data
.
dma_cfg
=
platform_data
->
msp_i2s_dma_r
x
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
res
==
NULL
)
{
...
...
@@ -717,6 +685,9 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
return
-
ENOMEM
;
}
msp
->
playback_dma_data
.
tx_rx_addr
=
res
->
start
+
MSP_DR
;
msp
->
capture_dma_data
.
tx_rx_addr
=
res
->
start
+
MSP_DR
;
msp
->
registers
=
devm_ioremap
(
&
pdev
->
dev
,
res
->
start
,
resource_size
(
res
));
if
(
msp
->
registers
==
NULL
)
{
...
...
@@ -727,41 +698,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
msp
->
msp_state
=
MSP_STATE_IDLE
;
msp
->
loopback_enable
=
0
;
/* I2S-controller is allocated and added in I2S controller class. */
i2s_cont
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
i2s_cont
),
GFP_KERNEL
);
if
(
!
i2s_cont
)
{
dev_err
(
&
pdev
->
dev
,
"%s: ERROR: Failed to allocate I2S-controller!
\n
"
,
__func__
);
return
-
ENOMEM
;
}
i2s_cont
->
dev
.
parent
=
&
pdev
->
dev
;
i2s_cont
->
data
=
(
void
*
)
msp
;
i2s_cont
->
id
=
(
s16
)
msp
->
id
;
snprintf
(
i2s_cont
->
name
,
sizeof
(
i2s_cont
->
name
),
"ux500-msp-i2s.%04x"
,
msp
->
id
);
dev_dbg
(
&
pdev
->
dev
,
"I2S device-name: '%s'
\n
"
,
i2s_cont
->
name
);
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
;
}
...
...
@@ -769,8 +705,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
struct
ux500_msp
*
msp
)
{
dev_dbg
(
msp
->
dev
,
"%s: Enter (id = %d).
\n
"
,
__func__
,
msp
->
id
);
device_unregister
(
&
msp
->
i2s_cont
->
dev
);
}
MODULE_LICENSE
(
"GPL v2"
);
sound/soc/ux500/ux500_msp_i2s.h
浏览文件 @
458bcee9
...
...
@@ -16,6 +16,7 @@
#define UX500_MSP_I2S_H
#include <linux/platform_device.h>
#include <linux/platform_data/asoc-ux500-msp.h>
#define MSP_INPUT_FREQ_APB 48000000
...
...
@@ -341,11 +342,6 @@ enum msp_compress_mode {
MSP_COMPRESS_MODE_A_LAW
=
3
};
enum
msp_spi_burst_mode
{
MSP_SPI_BURST_MODE_DISABLE
=
0
,
MSP_SPI_BURST_MODE_ENABLE
=
1
};
enum
msp_expand_mode
{
MSP_EXPAND_MODE_LINEAR
=
0
,
MSP_EXPAND_MODE_LINEAR_SIGNED
=
1
,
...
...
@@ -370,13 +366,6 @@ enum msp_protocol {
*/
#define MAX_MSP_BACKUP_REGS 36
enum
enum_i2s_controller
{
MSP_0_I2S_CONTROLLER
=
0
,
MSP_1_I2S_CONTROLLER
,
MSP_2_I2S_CONTROLLER
,
MSP_3_I2S_CONTROLLER
,
};
enum
i2s_direction_t
{
MSP_DIR_TX
=
0x01
,
MSP_DIR_RX
=
0x02
,
...
...
@@ -454,32 +443,6 @@ struct msp_protdesc {
u32
clocks_per_frame
;
};
struct
i2s_message
{
enum
i2s_direction_t
i2s_direction
;
void
*
txdata
;
void
*
rxdata
;
size_t
txbytes
;
size_t
rxbytes
;
int
dma_flag
;
int
tx_offset
;
int
rx_offset
;
bool
cyclic_dma
;
dma_addr_t
buf_addr
;
size_t
buf_len
;
size_t
period_len
;
};
struct
i2s_controller
{
struct
module
*
owner
;
unsigned
int
id
;
unsigned
int
class
;
const
struct
i2s_algorithm
*
algo
;
/* the algorithm to access the bus */
void
*
data
;
struct
mutex
bus_lock
;
struct
device
dev
;
/* the controller device */
char
name
[
48
];
};
struct
ux500_msp_config
{
unsigned
int
f_inputclk
;
unsigned
int
rx_clk_sel
;
...
...
@@ -491,8 +454,6 @@ struct ux500_msp_config {
unsigned
int
tx_fsync_sel
;
unsigned
int
rx_fifo_config
;
unsigned
int
tx_fifo_config
;
unsigned
int
spi_clk_mode
;
unsigned
int
spi_burst_mode
;
unsigned
int
loopback_enable
;
unsigned
int
tx_data_enable
;
unsigned
int
default_protdesc
;
...
...
@@ -502,43 +463,28 @@ struct ux500_msp_config {
unsigned
int
direction
;
unsigned
int
protocol
;
unsigned
int
frame_freq
;
unsigned
int
frame_size
;
enum
msp_data_size
data_size
;
unsigned
int
def_elem_len
;
unsigned
int
iodelay
;
void
(
*
handler
)
(
void
*
data
);
void
*
tx_callback_data
;
void
*
rx_callback_data
;
};
struct
ux500_msp_dma_params
{
unsigned
int
data_size
;
dma_addr_t
tx_rx_addr
;
struct
stedma40_chan_cfg
*
dma_cfg
;
};
struct
ux500_msp
{
enum
enum_i2s_controller
id
;
enum
msp_i2s_id
id
;
void
__iomem
*
registers
;
struct
device
*
dev
;
struct
i2s_controller
*
i2s_cont
;
struct
stedma40_chan_cfg
*
dma_cfg_rx
;
struct
stedma40_chan_cfg
*
dma_cfg_tx
;
struct
dma_chan
*
tx_pipeid
;
struct
dma_chan
*
rx_pipeid
;
struct
ux500_msp_dma_params
playback_dma_data
;
struct
ux500_msp_dma_params
capture_dma_data
;
enum
msp_state
msp_state
;
int
(
*
transfer
)
(
struct
ux500_msp
*
msp
,
struct
i2s_message
*
message
);
struct
timer_list
notify_timer
;
int
def_elem_len
;
unsigned
int
dir_busy
;
int
loopback_enable
;
u32
backup_regs
[
MAX_MSP_BACKUP_REGS
];
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
{
unsigned
int
data_size
;
struct
stedma40_chan_cfg
*
dma_cfg
;
};
struct
msp_i2s_platform_data
;
...
...
sound/soc/ux500/ux500_pcm.c
浏览文件 @
458bcee9
...
...
@@ -103,10 +103,40 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
return
snd_dmaengine_pcm_request_channel
(
stedma40_filter
,
dma_cfg
);
}
static
int
ux500_pcm_prepare_slave_config
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
,
struct
dma_slave_config
*
slave_config
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
ux500_msp_dma_params
*
dma_params
;
struct
stedma40_chan_cfg
*
dma_cfg
;
int
ret
;
dma_params
=
snd_soc_dai_get_dma_data
(
rtd
->
cpu_dai
,
substream
);
dma_cfg
=
dma_params
->
dma_cfg
;
ret
=
snd_hwparams_to_dma_slave_config
(
substream
,
params
,
slave_config
);
if
(
ret
)
return
ret
;
slave_config
->
dst_maxburst
=
4
;
slave_config
->
dst_addr_width
=
dma_cfg
->
dst_info
.
data_width
;
slave_config
->
src_maxburst
=
4
;
slave_config
->
src_addr_width
=
dma_cfg
->
src_info
.
data_width
;
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
slave_config
->
dst_addr
=
dma_params
->
tx_rx_addr
;
else
slave_config
->
src_addr
=
dma_params
->
tx_rx_addr
;
return
0
;
}
static
const
struct
snd_dmaengine_pcm_config
ux500_dmaengine_pcm_config
=
{
.
pcm_hardware
=
&
ux500_pcm_hw
,
.
compat_request_channel
=
ux500_pcm_request_chan
,
.
prealloc_buffer_size
=
128
*
1024
,
.
prepare_slave_config
=
ux500_pcm_prepare_slave_config
,
};
int
ux500_pcm_register_platform
(
struct
platform_device
*
pdev
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录