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
1bd202e4
Commit
1bd202e4
authored
Dec 10, 2012
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/davinci' into asoc-next
parents
57769541
1b3bc060
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
158 additions
and
97 deletions
+158
-97
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/board-da850-evm.c
+14
-10
include/linux/platform_data/davinci_asp.h
include/linux/platform_data/davinci_asp.h
+3
-1
sound/soc/davinci/davinci-evm.c
sound/soc/davinci/davinci-evm.c
+5
-0
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-mcasp.c
+97
-55
sound/soc/davinci/davinci-mcasp.h
sound/soc/davinci/davinci-mcasp.h
+2
-13
sound/soc/davinci/davinci-pcm.c
sound/soc/davinci/davinci-pcm.c
+35
-18
sound/soc/davinci/davinci-pcm.h
sound/soc/davinci/davinci-pcm.h
+2
-0
No files found.
arch/arm/mach-davinci/board-da850-evm.c
View file @
1bd202e4
...
...
@@ -769,9 +769,12 @@ static struct snd_platform_data da850_evm_snd_data = {
.
tdm_slots
=
2
,
.
serial_dir
=
da850_iis_serializer_direction
,
.
asp_chan_q
=
EVENTQ_0
,
.
ram_chan_q
=
EVENTQ_1
,
.
version
=
MCASP_VERSION_2
,
.
txnumevt
=
1
,
.
rxnumevt
=
1
,
.
sram_size_playback
=
SZ_8K
,
.
sram_size_capture
=
SZ_8K
,
};
static
const
short
da850_evm_mcasp_pins
[]
__initconst
=
{
...
...
@@ -1509,6 +1512,7 @@ static __init void da850_evm_init(void)
pr_warning
(
"da850_evm_init: mcasp mux setup failed: %d
\n
"
,
ret
);
da850_evm_snd_data
.
sram_pool
=
sram_get_gen_pool
();
da8xx_register_mcasp
(
0
,
&
da850_evm_snd_data
);
ret
=
davinci_cfg_reg_list
(
da850_lcdcntl_pins
);
...
...
include/linux/platform_data/davinci_asp.h
View file @
1bd202e4
...
...
@@ -16,12 +16,13 @@
#ifndef __DAVINCI_ASP_H
#define __DAVINCI_ASP_H
#include <linux/genalloc.h>
struct
snd_platform_data
{
u32
tx_dma_offset
;
u32
rx_dma_offset
;
int
asp_chan_q
;
/* event queue number for ASP channel */
int
ram_chan_q
;
/* event queue number for RAM channel */
unsigned
int
codec_fmt
;
/*
* Allowing this is more efficient and eliminates left and right swaps
* caused by underruns, but will swap the left and right channels
...
...
@@ -30,6 +31,7 @@ struct snd_platform_data {
unsigned
enable_channel_combine
:
1
;
unsigned
sram_size_playback
;
unsigned
sram_size_capture
;
struct
gen_pool
*
sram_pool
;
/*
* If McBSP peripheral gets the clock from an external pin,
...
...
sound/soc/davinci/davinci-evm.c
View file @
1bd202e4
...
...
@@ -71,6 +71,11 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
if
(
ret
<
0
)
return
ret
;
/* set the CPU system clock */
ret
=
snd_soc_dai_set_sysclk
(
cpu_dai
,
0
,
sysclk
,
SND_SOC_CLOCK_OUT
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
...
...
sound/soc/davinci/davinci-mcasp.c
View file @
1bd202e4
...
...
@@ -199,6 +199,7 @@
#define ACLKXE BIT(5)
#define TX_ASYNC BIT(6)
#define ACLKXPOL BIT(7)
#define ACLKXDIV_MASK 0x1f
/*
* DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits
...
...
@@ -207,6 +208,7 @@
#define ACLKRE BIT(5)
#define RX_ASYNC BIT(6)
#define ACLKRPOL BIT(7)
#define ACLKRDIV_MASK 0x1f
/*
* DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control
...
...
@@ -215,6 +217,7 @@
#define AHCLKXDIV(val) (val)
#define AHCLKXPOL BIT(14)
#define AHCLKXE BIT(15)
#define AHCLKXDIV_MASK 0xfff
/*
* DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control
...
...
@@ -223,6 +226,7 @@
#define AHCLKRDIV(val) (val)
#define AHCLKRPOL BIT(14)
#define AHCLKRE BIT(15)
#define AHCLKRDIV_MASK 0xfff
/*
* DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits
...
...
@@ -473,6 +477,23 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
struct
davinci_audio_dev
*
dev
=
snd_soc_dai_get_drvdata
(
cpu_dai
);
void
__iomem
*
base
=
dev
->
base
;
switch
(
fmt
&
SND_SOC_DAIFMT_FORMAT_MASK
)
{
case
SND_SOC_DAIFMT_DSP_B
:
case
SND_SOC_DAIFMT_AC97
:
mcasp_clr_bits
(
dev
->
base
+
DAVINCI_MCASP_TXFMCTL_REG
,
FSXDUR
);
mcasp_clr_bits
(
dev
->
base
+
DAVINCI_MCASP_RXFMCTL_REG
,
FSRDUR
);
break
;
default:
/* configure a full-word SYNC pulse (LRCLK) */
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_TXFMCTL_REG
,
FSXDUR
);
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_RXFMCTL_REG
,
FSRDUR
);
/* make 1st data bit occur one ACLK cycle after the frame sync */
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_TXFMT_REG
,
FSXDLY
(
1
));
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_RXFMT_REG
,
FSRDLY
(
1
));
break
;
}
switch
(
fmt
&
SND_SOC_DAIFMT_MASTER_MASK
)
{
case
SND_SOC_DAIFMT_CBS_CFS
:
/* codec is clock and frame slave */
...
...
@@ -482,8 +503,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
mcasp_set_bits
(
base
+
DAVINCI_MCASP_ACLKRCTL_REG
,
ACLKRE
);
mcasp_set_bits
(
base
+
DAVINCI_MCASP_RXFMCTL_REG
,
AFSRE
);
mcasp_set_bits
(
base
+
DAVINCI_MCASP_PDIR_REG
,
ACLKX
|
AHCLKX
|
AFSX
);
mcasp_set_bits
(
base
+
DAVINCI_MCASP_PDIR_REG
,
ACLKX
|
AFSX
);
break
;
case
SND_SOC_DAIFMT_CBM_CFS
:
/* codec is clock master and frame slave */
...
...
@@ -554,59 +574,75 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
return
0
;
}
static
int
davinci_config_channel_size
(
struct
davinci_audio_dev
*
dev
,
int
channel_size
)
static
int
davinci_mcasp_set_clkdiv
(
struct
snd_soc_dai
*
dai
,
int
div_id
,
int
div
)
{
u32
fmt
=
0
;
u32
mask
,
rotate
;
switch
(
channel_size
)
{
case
DAVINCI_AUDIO_WORD_8
:
fmt
=
0x03
;
rotate
=
6
;
mask
=
0x000000ff
;
break
;
struct
davinci_audio_dev
*
dev
=
snd_soc_dai_get_drvdata
(
dai
);
case
DAVINCI_AUDIO_WORD_12
:
fmt
=
0x05
;
rotate
=
5
;
mask
=
0x00000fff
;
switch
(
div_id
)
{
case
0
:
/* MCLK divider */
mcasp_mod_bits
(
dev
->
base
+
DAVINCI_MCASP_AHCLKXCTL_REG
,
AHCLKXDIV
(
div
-
1
),
AHCLKXDIV_MASK
);
mcasp_mod_bits
(
dev
->
base
+
DAVINCI_MCASP_AHCLKRCTL_REG
,
AHCLKRDIV
(
div
-
1
),
AHCLKRDIV_MASK
);
break
;
case
DAVINCI_AUDIO_WORD_16
:
fmt
=
0x07
;
rotate
=
4
;
mask
=
0x0000ffff
;
case
1
:
/* BCLK divider */
mcasp_mod_bits
(
dev
->
base
+
DAVINCI_MCASP_ACLKXCTL_REG
,
ACLKXDIV
(
div
-
1
),
ACLKXDIV_MASK
);
mcasp_mod_bits
(
dev
->
base
+
DAVINCI_MCASP_ACLKRCTL_REG
,
ACLKRDIV
(
div
-
1
),
ACLKRDIV_MASK
);
break
;
case
DAVINCI_AUDIO_WORD_20
:
fmt
=
0x09
;
rotate
=
3
;
mask
=
0x000fffff
;
case
2
:
/* BCLK/LRCLK ratio */
dev
->
bclk_lrclk_ratio
=
div
;
break
;
case
DAVINCI_AUDIO_WORD_24
:
fmt
=
0x0B
;
rotate
=
2
;
mask
=
0x00ffffff
;
break
;
default:
return
-
EINVAL
;
}
case
DAVINCI_AUDIO_WORD_28
:
fmt
=
0x0D
;
rotate
=
1
;
mask
=
0x0fffffff
;
break
;
return
0
;
}
case
DAVINCI_AUDIO_WORD_32
:
fmt
=
0x0F
;
rotate
=
0
;
mask
=
0xffffffff
;
break
;
static
int
davinci_mcasp_set_sysclk
(
struct
snd_soc_dai
*
dai
,
int
clk_id
,
unsigned
int
freq
,
int
dir
)
{
struct
davinci_audio_dev
*
dev
=
snd_soc_dai_get_drvdata
(
dai
);
default:
return
-
EINVAL
;
if
(
dir
==
SND_SOC_CLOCK_OUT
)
{
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_AHCLKXCTL_REG
,
AHCLKXE
);
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_AHCLKRCTL_REG
,
AHCLKRE
);
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_PDIR_REG
,
AHCLKX
);
}
else
{
mcasp_clr_bits
(
dev
->
base
+
DAVINCI_MCASP_AHCLKXCTL_REG
,
AHCLKXE
);
mcasp_clr_bits
(
dev
->
base
+
DAVINCI_MCASP_AHCLKRCTL_REG
,
AHCLKRE
);
mcasp_clr_bits
(
dev
->
base
+
DAVINCI_MCASP_PDIR_REG
,
AHCLKX
);
}
return
0
;
}
static
int
davinci_config_channel_size
(
struct
davinci_audio_dev
*
dev
,
int
word_length
)
{
u32
fmt
;
u32
rotate
=
(
32
-
word_length
)
/
4
;
u32
mask
=
(
1ULL
<<
word_length
)
-
1
;
/*
* if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv()
* callback, take it into account here. That allows us to for example
* send 32 bits per channel to the codec, while only 16 of them carry
* audio payload.
* The clock ratio is given for a full period of data (both left and
* right channels), so it has to be divided by 2.
*/
if
(
dev
->
bclk_lrclk_ratio
)
word_length
=
dev
->
bclk_lrclk_ratio
/
2
;
/* mapping of the XSSZ bit-field as described in the datasheet */
fmt
=
(
word_length
>>
1
)
-
1
;
mcasp_mod_bits
(
dev
->
base
+
DAVINCI_MCASP_RXFMT_REG
,
RXSSZ
(
fmt
),
RXSSZ
(
0x0F
));
mcasp_mod_bits
(
dev
->
base
+
DAVINCI_MCASP_TXFMT_REG
,
...
...
@@ -709,8 +745,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
if
(
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
/* bit stream is MSB first with no delay */
/* DSP_B mode */
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_AHCLKXCTL_REG
,
AHCLKXE
);
mcasp_set_reg
(
dev
->
base
+
DAVINCI_MCASP_TXTDM_REG
,
mask
);
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_TXFMT_REG
,
TXORD
);
...
...
@@ -720,14 +754,10 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
else
printk
(
KERN_ERR
"playback tdm slot %d not supported
\n
"
,
dev
->
tdm_slots
);
mcasp_clr_bits
(
dev
->
base
+
DAVINCI_MCASP_TXFMCTL_REG
,
FSXDUR
);
}
else
{
/* bit stream is MSB first with no delay */
/* DSP_B mode */
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_RXFMT_REG
,
RXORD
);
mcasp_set_bits
(
dev
->
base
+
DAVINCI_MCASP_AHCLKRCTL_REG
,
AHCLKRE
);
mcasp_set_reg
(
dev
->
base
+
DAVINCI_MCASP_RXTDM_REG
,
mask
);
if
((
dev
->
tdm_slots
>=
2
)
&&
(
dev
->
tdm_slots
<=
32
))
...
...
@@ -736,8 +766,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
else
printk
(
KERN_ERR
"capture tdm slot %d not supported
\n
"
,
dev
->
tdm_slots
);
mcasp_clr_bits
(
dev
->
base
+
DAVINCI_MCASP_RXFMCTL_REG
,
FSRDUR
);
}
}
...
...
@@ -800,19 +828,27 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
case
SNDRV_PCM_FORMAT_U8
:
case
SNDRV_PCM_FORMAT_S8
:
dma_params
->
data_type
=
1
;
word_length
=
DAVINCI_AUDIO_WORD_
8
;
word_length
=
8
;
break
;
case
SNDRV_PCM_FORMAT_U16_LE
:
case
SNDRV_PCM_FORMAT_S16_LE
:
dma_params
->
data_type
=
2
;
word_length
=
DAVINCI_AUDIO_WORD_
16
;
word_length
=
16
;
break
;
case
SNDRV_PCM_FORMAT_U24_3LE
:
case
SNDRV_PCM_FORMAT_S24_3LE
:
dma_params
->
data_type
=
3
;
word_length
=
24
;
break
;
case
SNDRV_PCM_FORMAT_U24_LE
:
case
SNDRV_PCM_FORMAT_S24_LE
:
case
SNDRV_PCM_FORMAT_U32_LE
:
case
SNDRV_PCM_FORMAT_S32_LE
:
dma_params
->
data_type
=
4
;
word_length
=
DAVINCI_AUDIO_WORD_
32
;
word_length
=
32
;
break
;
default:
...
...
@@ -880,13 +916,18 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
.
trigger
=
davinci_mcasp_trigger
,
.
hw_params
=
davinci_mcasp_hw_params
,
.
set_fmt
=
davinci_mcasp_set_dai_fmt
,
.
set_clkdiv
=
davinci_mcasp_set_clkdiv
,
.
set_sysclk
=
davinci_mcasp_set_sysclk
,
};
#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_U8 | \
SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_U16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_U24_LE | \
SNDRV_PCM_FMTBIT_S24_3LE | \
SNDRV_PCM_FMTBIT_U24_3LE | \
SNDRV_PCM_FMTBIT_S32_LE | \
SNDRV_PCM_FMTBIT_U32_LE)
...
...
@@ -1089,7 +1130,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dev
->
tdm_slots
=
pdata
->
tdm_slots
;
dev
->
num_serializer
=
pdata
->
num_serializer
;
dev
->
serial_dir
=
pdata
->
serial_dir
;
dev
->
codec_fmt
=
pdata
->
codec_fmt
;
dev
->
version
=
pdata
->
version
;
dev
->
txnumevt
=
pdata
->
txnumevt
;
dev
->
rxnumevt
=
pdata
->
rxnumevt
;
...
...
@@ -1098,6 +1138,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
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
);
...
...
@@ -1115,6 +1156,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
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
);
...
...
sound/soc/davinci/davinci-mcasp.h
View file @
1bd202e4
...
...
@@ -23,26 +23,14 @@
#include "davinci-pcm.h"
#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_
96
000
#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_
192
000
#define DAVINCI_MCASP_I2S_DAI 0
#define DAVINCI_MCASP_DIT_DAI 1
enum
{
DAVINCI_AUDIO_WORD_8
=
0
,
DAVINCI_AUDIO_WORD_12
,
DAVINCI_AUDIO_WORD_16
,
DAVINCI_AUDIO_WORD_20
,
DAVINCI_AUDIO_WORD_24
,
DAVINCI_AUDIO_WORD_32
,
DAVINCI_AUDIO_WORD_28
,
/* This is only valid for McASP */
};
struct
davinci_audio_dev
{
struct
davinci_pcm_dma_params
dma_params
[
2
];
void
__iomem
*
base
;
int
sample_rate
;
struct
device
*
dev
;
unsigned
int
codec_fmt
;
/* McASP specific data */
int
tdm_slots
;
...
...
@@ -50,6 +38,7 @@ struct davinci_audio_dev {
u8
num_serializer
;
u8
*
serial_dir
;
u8
version
;
u8
bclk_lrclk_ratio
;
/* McASP FIFO related */
u8
txnumevt
;
...
...
sound/soc/davinci/davinci-pcm.c
View file @
1bd202e4
...
...
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/genalloc.h>
#include <sound/core.h>
#include <sound/pcm.h>
...
...
@@ -23,7 +24,6 @@
#include <sound/soc.h>
#include <asm/dma.h>
#include <mach/sram.h>
#include "davinci-pcm.h"
...
...
@@ -67,13 +67,9 @@ static struct snd_pcm_hardware pcm_hardware_playback = {
SNDRV_PCM_INFO_PAUSE
|
SNDRV_PCM_INFO_RESUME
|
SNDRV_PCM_INFO_BATCH
),
.
formats
=
DAVINCI_PCM_FMTBITS
,
.
rates
=
(
SNDRV_PCM_RATE_8000
|
SNDRV_PCM_RATE_16000
|
SNDRV_PCM_RATE_22050
|
SNDRV_PCM_RATE_32000
|
SNDRV_PCM_RATE_44100
|
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_88200
|
SNDRV_PCM_RATE_96000
|
SNDRV_PCM_RATE_KNOT
),
.
rates
=
SNDRV_PCM_RATE_8000_192000
|
SNDRV_PCM_RATE_KNOT
,
.
rate_min
=
8000
,
.
rate_max
=
96
000
,
.
rate_max
=
192
000
,
.
channels_min
=
2
,
.
channels_max
=
384
,
.
buffer_bytes_max
=
128
*
1024
,
...
...
@@ -90,13 +86,9 @@ static struct snd_pcm_hardware pcm_hardware_capture = {
SNDRV_PCM_INFO_PAUSE
|
SNDRV_PCM_INFO_BATCH
),
.
formats
=
DAVINCI_PCM_FMTBITS
,
.
rates
=
(
SNDRV_PCM_RATE_8000
|
SNDRV_PCM_RATE_16000
|
SNDRV_PCM_RATE_22050
|
SNDRV_PCM_RATE_32000
|
SNDRV_PCM_RATE_44100
|
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_88200
|
SNDRV_PCM_RATE_96000
|
SNDRV_PCM_RATE_KNOT
),
.
rates
=
SNDRV_PCM_RATE_8000_192000
|
SNDRV_PCM_RATE_KNOT
,
.
rate_min
=
8000
,
.
rate_max
=
96
000
,
.
rate_max
=
192
000
,
.
channels_min
=
2
,
.
channels_max
=
384
,
.
buffer_bytes_max
=
128
*
1024
,
...
...
@@ -259,7 +251,9 @@ static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
}
}
static
int
allocate_sram
(
struct
snd_pcm_substream
*
substream
,
unsigned
size
,
#ifdef CONFIG_GENERIC_ALLOCATOR
static
int
allocate_sram
(
struct
snd_pcm_substream
*
substream
,
struct
gen_pool
*
sram_pool
,
unsigned
size
,
struct
snd_pcm_hardware
*
ppcm
)
{
struct
snd_dma_buffer
*
buf
=
&
substream
->
dma_buffer
;
...
...
@@ -271,9 +265,10 @@ static int allocate_sram(struct snd_pcm_substream *substream, unsigned size,
return
0
;
ppcm
->
period_bytes_max
=
size
;
iram_virt
=
sram_alloc
(
size
,
&
iram_phys
);
iram_virt
=
(
void
*
)
gen_pool_alloc
(
sram_pool
,
size
);
if
(
!
iram_virt
)
goto
exit1
;
iram_phys
=
gen_pool_virt_to_phys
(
sram_pool
,
(
unsigned
)
iram_virt
);
iram_dma
=
kzalloc
(
sizeof
(
*
iram_dma
),
GFP_KERNEL
);
if
(
!
iram_dma
)
goto
exit2
;
...
...
@@ -285,11 +280,33 @@ static int allocate_sram(struct snd_pcm_substream *substream, unsigned size,
return
0
;
exit2:
if
(
iram_virt
)
sram_free
(
iram_virt
,
size
);
gen_pool_free
(
sram_pool
,
(
unsigned
)
iram_virt
,
size
);
exit1:
return
-
ENOMEM
;
}
static
void
davinci_free_sram
(
struct
snd_pcm_substream
*
substream
,
struct
snd_dma_buffer
*
iram_dma
)
{
struct
davinci_runtime_data
*
prtd
=
substream
->
runtime
->
private_data
;
struct
gen_pool
*
sram_pool
=
prtd
->
params
->
sram_pool
;
gen_pool_free
(
sram_pool
,
(
unsigned
)
iram_dma
->
area
,
iram_dma
->
bytes
);
}
#else
static
int
allocate_sram
(
struct
snd_pcm_substream
*
substream
,
struct
gen_pool
*
sram_pool
,
unsigned
size
,
struct
snd_pcm_hardware
*
ppcm
)
{
return
0
;
}
static
void
davinci_free_sram
(
struct
snd_pcm_substream
*
substream
,
struct
snd_dma_buffer
*
iram_dma
)
{
}
#endif
/*
* Only used with ping/pong.
* This is called after runtime->dma_addr, period_bytes and data_type are valid
...
...
@@ -676,7 +693,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
ppcm
=
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
?
&
pcm_hardware_playback
:
&
pcm_hardware_capture
;
allocate_sram
(
substream
,
params
->
sram_size
,
ppcm
);
allocate_sram
(
substream
,
params
->
sram_
pool
,
params
->
sram_
size
,
ppcm
);
snd_soc_set_runtime_hwparams
(
substream
,
ppcm
);
/* ensure that buffer size is a multiple of period size */
ret
=
snd_pcm_hw_constraint_integer
(
runtime
,
...
...
@@ -819,7 +836,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
buf
->
area
=
NULL
;
iram_dma
=
buf
->
private_data
;
if
(
iram_dma
)
{
sram_free
(
iram_dma
->
area
,
iram_dma
->
bytes
);
davinci_free_sram
(
substream
,
iram_dma
);
kfree
(
iram_dma
);
}
}
...
...
sound/soc/davinci/davinci-pcm.h
View file @
1bd202e4
...
...
@@ -12,6 +12,7 @@
#ifndef _DAVINCI_PCM_H
#define _DAVINCI_PCM_H
#include <linux/genalloc.h>
#include <linux/platform_data/davinci_asp.h>
#include <mach/edma.h>
...
...
@@ -20,6 +21,7 @@ struct davinci_pcm_dma_params {
unsigned
short
acnt
;
dma_addr_t
dma_addr
;
/* device physical address for DMA */
unsigned
sram_size
;
struct
gen_pool
*
sram_pool
;
/* SRAM gen_pool for ping pong */
enum
dma_event_q
asp_chan_q
;
/* event queue number for ASP channel */
enum
dma_event_q
ram_chan_q
;
/* event queue number for RAM channel */
unsigned
char
data_type
;
/* xfer data type */
...
...
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