Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
70e0db2f
Commit
70e0db2f
authored
Oct 24, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/dma' into asoc-next
parents
48ce3ec1
90130d2e
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
115 additions
and
28 deletions
+115
-28
include/sound/dmaengine_pcm.h
include/sound/dmaengine_pcm.h
+8
-0
include/sound/soc-dai.h
include/sound/soc-dai.h
+7
-0
sound/soc/cirrus/ep93xx-pcm.c
sound/soc/cirrus/ep93xx-pcm.c
+13
-0
sound/soc/fsl/imx-pcm-dma.c
sound/soc/fsl/imx-pcm-dma.c
+1
-3
sound/soc/samsung/i2s.c
sound/soc/samsung/i2s.c
+2
-7
sound/soc/soc-generic-dmaengine-pcm.c
sound/soc/soc-generic-dmaengine-pcm.c
+84
-17
sound/soc/tegra/tegra_pcm.c
sound/soc/tegra/tegra_pcm.c
+0
-1
No files found.
include/sound/dmaengine_pcm.h
View file @
70e0db2f
...
...
@@ -61,6 +61,8 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
* @slave_id: Slave requester id for the DMA channel.
* @filter_data: Custom DMA channel filter data, this will usually be used when
* requesting the DMA channel.
* @chan_name: Custom channel name to use when requesting DMA channel.
* @fifo_size: FIFO size of the DAI controller in bytes
*/
struct
snd_dmaengine_dai_dma_data
{
dma_addr_t
addr
;
...
...
@@ -68,6 +70,8 @@ struct snd_dmaengine_dai_dma_data {
u32
maxburst
;
unsigned
int
slave_id
;
void
*
filter_data
;
const
char
*
chan_name
;
unsigned
int
fifo_size
;
};
void
snd_dmaengine_pcm_set_config_from_dai_data
(
...
...
@@ -96,6 +100,10 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
* playback.
*/
#define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
/*
* The PCM streams have custom channel names specified.
*/
#define SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME BIT(4)
/**
* struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
...
...
include/sound/soc-dai.h
View file @
70e0db2f
...
...
@@ -279,6 +279,13 @@ static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
dai
->
capture_dma_data
=
data
;
}
static
inline
void
snd_soc_dai_init_dma_data
(
struct
snd_soc_dai
*
dai
,
void
*
playback
,
void
*
capture
)
{
dai
->
playback_dma_data
=
playback
;
dai
->
capture_dma_data
=
capture
;
}
static
inline
void
snd_soc_dai_set_drvdata
(
struct
snd_soc_dai
*
dai
,
void
*
data
)
{
...
...
sound/soc/cirrus/ep93xx-pcm.c
View file @
70e0db2f
...
...
@@ -57,9 +57,22 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
return
false
;
}
static
struct
dma_chan
*
ep93xx_compat_request_channel
(
struct
snd_soc_pcm_runtime
*
rtd
,
struct
snd_pcm_substream
*
substream
)
{
struct
snd_dmaengine_dai_dma_data
*
dma_data
;
dma_data
=
snd_soc_dai_get_dma_data
(
rtd
->
cpu_dai
,
substream
);
return
snd_dmaengine_pcm_request_channel
(
ep93xx_pcm_dma_filter
,
dma_data
);
}
static
const
struct
snd_dmaengine_pcm_config
ep93xx_dmaengine_pcm_config
=
{
.
pcm_hardware
=
&
ep93xx_pcm_hardware
,
.
compat_filter_fn
=
ep93xx_pcm_dma_filter
,
.
compat_request_channel
=
ep93xx_compat_request_channel
,
.
prealloc_buffer_size
=
131072
,
};
...
...
sound/soc/fsl/imx-pcm-dma.c
View file @
70e0db2f
...
...
@@ -25,12 +25,10 @@
static
bool
filter
(
struct
dma_chan
*
chan
,
void
*
param
)
{
struct
snd_dmaengine_dai_dma_data
*
dma_data
=
param
;
if
(
!
imx_dma_is_general_purpose
(
chan
))
return
false
;
chan
->
private
=
dma_data
->
filter_data
;
chan
->
private
=
param
;
return
true
;
}
...
...
sound/soc/samsung/i2s.c
View file @
70e0db2f
...
...
@@ -702,13 +702,6 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
}
writel
(
mod
,
i2s
->
addr
+
I2SMOD
);
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
snd_soc_dai_set_dma_data
(
dai
,
substream
,
(
void
*
)
&
i2s
->
dma_playback
);
else
snd_soc_dai_set_dma_data
(
dai
,
substream
,
(
void
*
)
&
i2s
->
dma_capture
);
i2s
->
frmclk
=
params_rate
(
params
);
return
0
;
...
...
@@ -970,6 +963,8 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
}
clk_prepare_enable
(
i2s
->
clk
);
snd_soc_dai_init_dma_data
(
dai
,
&
i2s
->
dma_playback
,
&
i2s
->
dma_capture
);
if
(
other
)
{
other
->
addr
=
i2s
->
addr
;
other
->
clk
=
i2s
->
clk
;
...
...
sound/soc/soc-generic-dmaengine-pcm.c
View file @
70e0db2f
...
...
@@ -36,6 +36,15 @@ static struct dmaengine_pcm *soc_platform_to_pcm(struct snd_soc_platform *p)
return
container_of
(
p
,
struct
dmaengine_pcm
,
platform
);
}
static
struct
device
*
dmaengine_dma_dev
(
struct
dmaengine_pcm
*
pcm
,
struct
snd_pcm_substream
*
substream
)
{
if
(
!
pcm
->
chan
[
substream
->
stream
])
return
NULL
;
return
pcm
->
chan
[
substream
->
stream
]
->
device
->
dev
;
}
/**
* snd_dmaengine_pcm_prepare_slave_config() - Generic prepare_slave_config callback
* @substream: PCM substream
...
...
@@ -75,12 +84,19 @@ static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream,
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
dmaengine_pcm
*
pcm
=
soc_platform_to_pcm
(
rtd
->
platform
);
struct
dma_chan
*
chan
=
snd_dmaengine_pcm_get_chan
(
substream
);
int
(
*
prepare_slave_config
)(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
,
struct
dma_slave_config
*
slave_config
);
struct
dma_slave_config
slave_config
;
int
ret
;
if
(
pcm
->
config
->
prepare_slave_config
)
{
ret
=
pcm
->
config
->
prepare_slave_config
(
substream
,
params
,
&
slave_config
);
if
(
!
pcm
->
config
)
prepare_slave_config
=
snd_dmaengine_pcm_prepare_slave_config
;
else
prepare_slave_config
=
pcm
->
config
->
prepare_slave_config
;
if
(
prepare_slave_config
)
{
ret
=
prepare_slave_config
(
substream
,
params
,
&
slave_config
);
if
(
ret
)
return
ret
;
...
...
@@ -92,28 +108,54 @@ static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream,
return
snd_pcm_lib_malloc_pages
(
substream
,
params_buffer_bytes
(
params
));
}
static
int
dmaengine_pcm_
open
(
struct
snd_pcm_substream
*
substream
)
static
int
dmaengine_pcm_
set_runtime_hwparams
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
dmaengine_pcm
*
pcm
=
soc_platform_to_pcm
(
rtd
->
platform
);
struct
device
*
dma_dev
=
dmaengine_dma_dev
(
pcm
,
substream
);
struct
dma_chan
*
chan
=
pcm
->
chan
[
substream
->
stream
];
struct
snd_dmaengine_dai_dma_data
*
dma_data
;
struct
dma_slave_caps
dma_caps
;
struct
snd_pcm_hardware
hw
;
int
ret
;
ret
=
snd_soc_set_runtime_hwparams
(
substream
,
if
(
pcm
->
config
&&
pcm
->
config
->
pcm_hardware
)
return
snd_soc_set_runtime_hwparams
(
substream
,
pcm
->
config
->
pcm_hardware
);
if
(
ret
)
return
ret
;
return
snd_dmaengine_pcm_open
(
substream
,
chan
);
dma_data
=
snd_soc_dai_get_dma_data
(
rtd
->
cpu_dai
,
substream
);
memset
(
&
hw
,
0
,
sizeof
(
hw
));
hw
.
info
=
SNDRV_PCM_INFO_MMAP
|
SNDRV_PCM_INFO_MMAP_VALID
|
SNDRV_PCM_INFO_INTERLEAVED
;
hw
.
periods_min
=
2
;
hw
.
periods_max
=
UINT_MAX
;
hw
.
period_bytes_min
=
256
;
hw
.
period_bytes_max
=
dma_get_max_seg_size
(
dma_dev
);
hw
.
buffer_bytes_max
=
SIZE_MAX
;
hw
.
fifo_size
=
dma_data
->
fifo_size
;
ret
=
dma_get_slave_caps
(
chan
,
&
dma_caps
);
if
(
ret
==
0
)
{
if
(
dma_caps
.
cmd_pause
)
hw
.
info
|=
SNDRV_PCM_INFO_PAUSE
|
SNDRV_PCM_INFO_RESUME
;
}
return
snd_soc_set_runtime_hwparams
(
substream
,
&
hw
);
}
static
struct
device
*
dmaengine_dma_dev
(
struct
dmaengine_pcm
*
pcm
,
struct
snd_pcm_substream
*
substream
)
static
int
dmaengine_pcm_open
(
struct
snd_pcm_substream
*
substream
)
{
if
(
!
pcm
->
chan
[
substream
->
stream
])
return
NULL
;
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
dmaengine_pcm
*
pcm
=
soc_platform_to_pcm
(
rtd
->
platform
);
struct
dma_chan
*
chan
=
pcm
->
chan
[
substream
->
stream
];
int
ret
;
return
pcm
->
chan
[
substream
->
stream
]
->
device
->
dev
;
ret
=
dmaengine_pcm_set_runtime_hwparams
(
substream
);
if
(
ret
)
return
ret
;
return
snd_dmaengine_pcm_open
(
substream
,
chan
);
}
static
void
dmaengine_pcm_free
(
struct
snd_pcm
*
pcm
)
...
...
@@ -126,6 +168,9 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel(
struct
snd_pcm_substream
*
substream
)
{
struct
dmaengine_pcm
*
pcm
=
soc_platform_to_pcm
(
rtd
->
platform
);
struct
snd_dmaengine_dai_dma_data
*
dma_data
;
dma_data
=
snd_soc_dai_get_dma_data
(
rtd
->
cpu_dai
,
substream
);
if
((
pcm
->
flags
&
SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX
)
&&
pcm
->
chan
[
0
])
return
pcm
->
chan
[
0
];
...
...
@@ -134,22 +179,42 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel(
return
pcm
->
config
->
compat_request_channel
(
rtd
,
substream
);
return
snd_dmaengine_pcm_request_channel
(
pcm
->
config
->
compat_filter_fn
,
snd_soc_dai_get_dma_data
(
rtd
->
cpu_dai
,
substream
)
);
dma_data
->
filter_data
);
}
static
int
dmaengine_pcm_new
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
dmaengine_pcm
*
pcm
=
soc_platform_to_pcm
(
rtd
->
platform
);
const
struct
snd_dmaengine_pcm_config
*
config
=
pcm
->
config
;
struct
device
*
dev
=
rtd
->
platform
->
dev
;
struct
snd_dmaengine_dai_dma_data
*
dma_data
;
struct
snd_pcm_substream
*
substream
;
size_t
prealloc_buffer_size
;
size_t
max_buffer_size
;
unsigned
int
i
;
int
ret
;
if
(
config
&&
config
->
prealloc_buffer_size
)
{
prealloc_buffer_size
=
config
->
prealloc_buffer_size
;
max_buffer_size
=
config
->
pcm_hardware
->
buffer_bytes_max
;
}
else
{
prealloc_buffer_size
=
512
*
1024
;
max_buffer_size
=
SIZE_MAX
;
}
for
(
i
=
SNDRV_PCM_STREAM_PLAYBACK
;
i
<=
SNDRV_PCM_STREAM_CAPTURE
;
i
++
)
{
substream
=
rtd
->
pcm
->
streams
[
i
].
substream
;
if
(
!
substream
)
continue
;
dma_data
=
snd_soc_dai_get_dma_data
(
rtd
->
cpu_dai
,
substream
);
if
(
!
pcm
->
chan
[
i
]
&&
(
pcm
->
flags
&
SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME
))
pcm
->
chan
[
i
]
=
dma_request_slave_channel
(
dev
,
dma_data
->
chan_name
);
if
(
!
pcm
->
chan
[
i
]
&&
(
pcm
->
flags
&
SND_DMAENGINE_PCM_FLAG_COMPAT
))
{
pcm
->
chan
[
i
]
=
dmaengine_pcm_compat_request_channel
(
rtd
,
substream
);
...
...
@@ -165,8 +230,8 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
ret
=
snd_pcm_lib_preallocate_pages
(
substream
,
SNDRV_DMA_TYPE_DEV
,
dmaengine_dma_dev
(
pcm
,
substream
),
config
->
prealloc_buffer_size
,
config
->
pcm_hardware
->
buffer_bytes_max
);
prealloc_buffer_size
,
max_buffer_size
);
if
(
ret
)
goto
err_free
;
}
...
...
@@ -222,7 +287,9 @@ static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
{
unsigned
int
i
;
if
((
pcm
->
flags
&
SND_DMAENGINE_PCM_FLAG_NO_DT
)
||
!
dev
->
of_node
)
if
((
pcm
->
flags
&
(
SND_DMAENGINE_PCM_FLAG_NO_DT
|
SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME
))
||
!
dev
->
of_node
)
return
;
if
(
pcm
->
flags
&
SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX
)
{
...
...
sound/soc/tegra/tegra_pcm.c
View file @
70e0db2f
...
...
@@ -56,7 +56,6 @@ static const struct snd_pcm_hardware tegra_pcm_hardware = {
static
const
struct
snd_dmaengine_pcm_config
tegra_dmaengine_pcm_config
=
{
.
pcm_hardware
=
&
tegra_pcm_hardware
,
.
prepare_slave_config
=
snd_dmaengine_pcm_prepare_slave_config
,
.
compat_filter_fn
=
NULL
,
.
prealloc_buffer_size
=
PAGE_SIZE
*
8
,
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment