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
nexedi
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