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
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
Hide 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
...
...
@@ -762,16 +762,19 @@ static u8 da850_iis_serializer_direction[] = {
};
static
struct
snd_platform_data
da850_evm_snd_data
=
{
.
tx_dma_offset
=
0x2000
,
.
rx_dma_offset
=
0x2000
,
.
op_mode
=
DAVINCI_MCASP_IIS_MODE
,
.
num_serializer
=
ARRAY_SIZE
(
da850_iis_serializer_direction
),
.
tdm_slots
=
2
,
.
serial_dir
=
da850_iis_serializer_direction
,
.
asp_chan_q
=
EVENTQ_0
,
.
version
=
MCASP_VERSION_2
,
.
txnumevt
=
1
,
.
rxnumevt
=
1
,
.
tx_dma_offset
=
0x2000
,
.
rx_dma_offset
=
0x2000
,
.
op_mode
=
DAVINCI_MCASP_IIS_MODE
,
.
num_serializer
=
ARRAY_SIZE
(
da850_iis_serializer_direction
),
.
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