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
cf44fba0
Commit
cf44fba0
authored
Oct 24, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/davinci' into asoc-next
parents
07056901
ee2f615d
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
382 additions
and
91 deletions
+382
-91
Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
...mentation/devicetree/bindings/sound/davinci-evm-audio.txt
+42
-0
Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
...ntation/devicetree/bindings/sound/davinci-mcasp-audio.txt
+27
-14
include/linux/platform_data/davinci_asp.h
include/linux/platform_data/davinci_asp.h
+2
-0
sound/soc/davinci/Kconfig
sound/soc/davinci/Kconfig
+15
-3
sound/soc/davinci/Makefile
sound/soc/davinci/Makefile
+1
-0
sound/soc/davinci/davinci-evm.c
sound/soc/davinci/davinci-evm.c
+166
-22
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-mcasp.c
+117
-52
sound/soc/davinci/davinci-mcasp.h
sound/soc/davinci/davinci-mcasp.h
+12
-0
No files found.
Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
0 → 100644
View file @
cf44fba0
* Texas Instruments SoC audio setups with TLV320AIC3X Codec
Required properties:
- compatible : "ti,da830-evm-audio" : forDM365/DA8xx/OMAPL1x/AM33xx
- ti,model : The user-visible name of this sound complex.
- ti,audio-codec : The phandle of the TLV320AIC3x audio codec
- ti,mcasp-controller : The phandle of the McASP controller
- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec
- ti,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,
the second being the connection's source. Valid names for sources and
sinks are the codec's pins, and the jacks on the board:
Board connectors:
* Headphone Jack
* Line Out
* Mic Jack
* Line In
Example:
sound {
compatible = "ti,da830-evm-audio";
ti,model = "DA830 EVM";
ti,audio-codec = <&tlv320aic3x>;
ti,mcasp-controller = <&mcasp1>;
ti,codec-clock-rate = <12000000>;
ti,audio-routing =
"Headphone Jack", "HPLOUT",
"Headphone Jack", "HPROUT",
"Line Out", "LLOUT",
"Line Out", "RLOUT",
"MIC3L", "Mic Bias 2V",
"MIC3R", "Mic Bias 2V",
"Mic Bias 2V", "Mic Jack",
"LINE1L", "Line In",
"LINE2L", "Line In",
"LINE1R", "Line In",
"LINE2R", "Line In";
};
Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
View file @
cf44fba0
...
...
@@ -4,17 +4,25 @@ Required properties:
- compatible :
"ti,dm646x-mcasp-audio" : for DM646x platforms
"ti,da830-mcasp-audio" : for both DA830 & DA850 platforms
"ti,omap2-mcasp-audio" : for OMAP2 platforms (TI81xx, AM33xx)
- reg : Should contain McASP registers offset and length
- interrupts : Interrupt number for McASP
- op-mode : I2S/DIT ops mode.
- tdm-slots : Slots for TDM operation.
- num-serializer : Serializers used by McASP.
- serial-dir : A list of serializer pin mode. The list number should be equal
to "num-serializer" parameter. Each entry is a number indication
serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX)
"ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, TI81xx)
- reg : Should contain reg specifiers for the entries in the reg-names property.
- reg-names : Should contain:
* "mpu" for the main registers (required). For compatibility with
existing software, it is recommended this is the first entry.
* "dat" for separate data port register access (optional).
- op-mode : I2S/DIT ops mode. 0 for I2S mode. 1 for DIT mode used for S/PDIF,
IEC60958-1, and AES-3 formats.
- tdm-slots : Slots for TDM operation. Indicates number of channels transmitted
or received over one serializer.
- serial-dir : A list of serializer configuration. Each entry is a number
indication for serializer pin direction.
(0 - INACTIVE, 1 - TX, 2 - RX)
- dmas: two element list of DMA controller phandles and DMA request line
ordered pairs.
- dma-names: identifier string for each DMA request line in the dmas property.
These strings correspond 1:1 with the ordered pairs in dmas. The dma
identifiers must be "rx" and "tx".
Optional properties:
...
...
@@ -23,18 +31,23 @@ Optional properties:
- rx-num-evt : FIFO levels.
- sram-size-playback : size of sram to be allocated during playback
- sram-size-capture : size of sram to be allocated during capture
- interrupts : Interrupt numbers for McASP, currently not used by the driver
- interrupt-names : Known interrupt names are "tx" and "rx"
- pinctrl-0: Should specify pin control group used for this controller.
- pinctrl-names: Should contain only one value - "default", for more details
please refer to pinctrl-bindings.txt
Example:
mcasp0: mcasp0@1d00000 {
compatible = "ti,da830-mcasp-audio";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x100000 0x3000>;
interrupts = <82 83>;
reg-names "mpu";
interrupts = <82>, <83>;
interrupts-names = "tx", "rx";
op-mode = <0>; /* MCASP_IIS_MODE */
tdm-slots = <2>;
num-serializer = <16>;
serial-dir = <
0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */
0 0 0 0
...
...
include/linux/platform_data/davinci_asp.h
View file @
cf44fba0
...
...
@@ -84,6 +84,8 @@ struct snd_platform_data {
u8
version
;
u8
txnumevt
;
u8
rxnumevt
;
int
tx_dma_channel
;
int
rx_dma_channel
;
};
enum
{
...
...
sound/soc/davinci/Kconfig
View file @
cf44fba0
config SND_DAVINCI_SOC
tristate "SoC Audio for the TI DAVINCI chip"
depends on ARCH_DAVINCI
tristate "SoC Audio for the TI DAVINCI
or AM33XX
chip"
depends on ARCH_DAVINCI
|| SOC_AM33XX
help
Platform driver for daVinci or AM33xx
Say Y or M if you want to add support for codecs attached to
the DAVINCI AC97
or I2S
interface. You will also need
the DAVINCI AC97
, I2S, or McASP
interface. You will also need
to select the audio interfaces to support below.
config SND_DAVINCI_SOC_I2S
...
...
@@ -15,6 +16,17 @@ config SND_DAVINCI_SOC_MCASP
config SND_DAVINCI_SOC_VCIF
tristate
config SND_AM33XX_SOC_EVM
tristate "SoC Audio for the AM33XX chip based boards"
depends on SND_DAVINCI_SOC && SOC_AM33XX
select SND_SOC_TLV320AIC3X
select SND_DAVINCI_SOC_MCASP
help
Say Y or M if you want to add support for SoC audio on AM33XX
boards using McASP and TLV320AIC3X codec. For example AM335X-EVM,
AM335X-EVMSK, and BeagelBone with AudioCape boards have this
setup.
config SND_DAVINCI_SOC_EVM
tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
depends on SND_DAVINCI_SOC
...
...
sound/soc/davinci/Makefile
View file @
cf44fba0
...
...
@@ -13,6 +13,7 @@ obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
snd-soc-evm-objs
:=
davinci-evm.o
obj-$(CONFIG_SND_DAVINCI_SOC_EVM)
+=
snd-soc-evm.o
obj-$(CONFIG_SND_AM33XX_SOC_EVM)
+=
snd-soc-evm.o
obj-$(CONFIG_SND_DM6467_SOC_EVM)
+=
snd-soc-evm.o
obj-$(CONFIG_SND_DA830_SOC_EVM)
+=
snd-soc-evm.o
obj-$(CONFIG_SND_DA850_SOC_EVM)
+=
snd-soc-evm.o
sound/soc/davinci/davinci-evm.c
View file @
cf44fba0
...
...
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/platform_data/edma.h>
#include <linux/i2c.h>
#include <linux/of_platform.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
...
...
@@ -23,10 +24,16 @@
#include <asm/dma.h>
#include <asm/mach-types.h>
#include <linux/edma.h>
#include "davinci-pcm.h"
#include "davinci-i2s.h"
#include "davinci-mcasp.h"
struct
snd_soc_card_drvdata_davinci
{
unsigned
sysclk
;
};
#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
static
int
evm_hw_params
(
struct
snd_pcm_substream
*
substream
,
...
...
@@ -35,27 +42,11 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
cpu_dai
;
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_card
*
soc_card
=
codec
->
card
;
int
ret
=
0
;
unsigned
sysclk
;
/* ASP1 on DM355 EVM is clocked by an external oscillator */
if
(
machine_is_davinci_dm355_evm
()
||
machine_is_davinci_dm6467_evm
()
||
machine_is_davinci_dm365_evm
())
sysclk
=
27000000
;
/* ASP0 in DM6446 EVM is clocked by U55, as configured by
* board-dm644x-evm.c using GPIOs from U18. There are six
* options; here we "know" we use a 48 KHz sample rate.
*/
else
if
(
machine_is_davinci_evm
())
sysclk
=
12288000
;
else
if
(
machine_is_davinci_da830_evm
()
||
machine_is_davinci_da850_evm
())
sysclk
=
24576000
;
else
return
-
EINVAL
;
unsigned
sysclk
=
((
struct
snd_soc_card_drvdata_davinci
*
)
snd_soc_card_get_drvdata
(
soc_card
))
->
sysclk
;
/* set codec DAI configuration */
ret
=
snd_soc_dai_set_fmt
(
codec_dai
,
AUDIO_FORMAT
);
...
...
@@ -133,13 +124,22 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
{
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
struct
device_node
*
np
=
codec
->
card
->
dev
->
of_node
;
int
ret
;
/* Add davinci-evm specific widgets */
snd_soc_dapm_new_controls
(
dapm
,
aic3x_dapm_widgets
,
ARRAY_SIZE
(
aic3x_dapm_widgets
));
if
(
np
)
{
ret
=
snd_soc_of_parse_audio_routing
(
codec
->
card
,
"ti,audio-routing"
);
if
(
ret
)
return
ret
;
}
else
{
/* Set up davinci-evm specific audio path audio_map */
snd_soc_dapm_add_routes
(
dapm
,
audio_map
,
ARRAY_SIZE
(
audio_map
));
}
/* not connected */
snd_soc_dapm_disable_pin
(
dapm
,
"MONO_LOUT"
);
...
...
@@ -243,35 +243,65 @@ static struct snd_soc_dai_link da850_evm_dai = {
};
/* davinci dm6446 evm audio machine driver */
/*
* ASP0 in DM6446 EVM is clocked by U55, as configured by
* board-dm644x-evm.c using GPIOs from U18. There are six
* options; here we "know" we use a 48 KHz sample rate.
*/
static
struct
snd_soc_card_drvdata_davinci
dm6446_snd_soc_card_drvdata
=
{
.
sysclk
=
12288000
,
};
static
struct
snd_soc_card
dm6446_snd_soc_card_evm
=
{
.
name
=
"DaVinci DM6446 EVM"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
dm6446_evm_dai
,
.
num_links
=
1
,
.
drvdata
=
&
dm6446_snd_soc_card_drvdata
,
};
/* davinci dm355 evm audio machine driver */
/* ASP1 on DM355 EVM is clocked by an external oscillator */
static
struct
snd_soc_card_drvdata_davinci
dm355_snd_soc_card_drvdata
=
{
.
sysclk
=
27000000
,
};
static
struct
snd_soc_card
dm355_snd_soc_card_evm
=
{
.
name
=
"DaVinci DM355 EVM"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
dm355_evm_dai
,
.
num_links
=
1
,
.
drvdata
=
&
dm355_snd_soc_card_drvdata
,
};
/* davinci dm365 evm audio machine driver */
static
struct
snd_soc_card_drvdata_davinci
dm365_snd_soc_card_drvdata
=
{
.
sysclk
=
27000000
,
};
static
struct
snd_soc_card
dm365_snd_soc_card_evm
=
{
.
name
=
"DaVinci DM365 EVM"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
dm365_evm_dai
,
.
num_links
=
1
,
.
drvdata
=
&
dm365_snd_soc_card_drvdata
,
};
/* davinci dm6467 evm audio machine driver */
static
struct
snd_soc_card_drvdata_davinci
dm6467_snd_soc_card_drvdata
=
{
.
sysclk
=
27000000
,
};
static
struct
snd_soc_card
dm6467_snd_soc_card_evm
=
{
.
name
=
"DaVinci DM6467 EVM"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
dm6467_evm_dai
,
.
num_links
=
ARRAY_SIZE
(
dm6467_evm_dai
),
.
drvdata
=
&
dm6467_snd_soc_card_drvdata
,
};
static
struct
snd_soc_card_drvdata_davinci
da830_snd_soc_card_drvdata
=
{
.
sysclk
=
24576000
,
};
static
struct
snd_soc_card
da830_snd_soc_card
=
{
...
...
@@ -279,6 +309,11 @@ static struct snd_soc_card da830_snd_soc_card = {
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
da830_evm_dai
,
.
num_links
=
1
,
.
drvdata
=
&
da830_snd_soc_card_drvdata
,
};
static
struct
snd_soc_card_drvdata_davinci
da850_snd_soc_card_drvdata
=
{
.
sysclk
=
24576000
,
};
static
struct
snd_soc_card
da850_snd_soc_card
=
{
...
...
@@ -286,8 +321,101 @@ static struct snd_soc_card da850_snd_soc_card = {
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
da850_evm_dai
,
.
num_links
=
1
,
.
drvdata
=
&
da850_snd_soc_card_drvdata
,
};
#if defined(CONFIG_OF)
/*
* The struct is used as place holder. It will be completely
* filled with data from dt node.
*/
static
struct
snd_soc_dai_link
evm_dai_tlv320aic3x
=
{
.
name
=
"TLV320AIC3X"
,
.
stream_name
=
"AIC3X"
,
.
codec_dai_name
=
"tlv320aic3x-hifi"
,
.
ops
=
&
evm_ops
,
.
init
=
evm_aic3x_init
,
};
static
const
struct
of_device_id
davinci_evm_dt_ids
[]
=
{
{
.
compatible
=
"ti,da830-evm-audio"
,
.
data
=
(
void
*
)
&
evm_dai_tlv320aic3x
,
},
{
/* sentinel */
}
};
MODULE_DEVICE_TABLE
(
of
,
davinci_evm_dt_ids
);
/* davinci evm audio machine driver */
static
struct
snd_soc_card
evm_soc_card
=
{
.
owner
=
THIS_MODULE
,
.
num_links
=
1
,
};
static
int
davinci_evm_probe
(
struct
platform_device
*
pdev
)
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
const
struct
of_device_id
*
match
=
of_match_device
(
of_match_ptr
(
davinci_evm_dt_ids
),
&
pdev
->
dev
);
struct
snd_soc_dai_link
*
dai
=
(
struct
snd_soc_dai_link
*
)
match
->
data
;
struct
snd_soc_card_drvdata_davinci
*
drvdata
=
NULL
;
int
ret
=
0
;
evm_soc_card
.
dai_link
=
dai
;
dai
->
codec_of_node
=
of_parse_phandle
(
np
,
"ti,audio-codec"
,
0
);
if
(
!
dai
->
codec_of_node
)
return
-
EINVAL
;
dai
->
cpu_of_node
=
of_parse_phandle
(
np
,
"ti,mcasp-controller"
,
0
);
if
(
!
dai
->
cpu_of_node
)
return
-
EINVAL
;
dai
->
platform_of_node
=
dai
->
cpu_of_node
;
evm_soc_card
.
dev
=
&
pdev
->
dev
;
ret
=
snd_soc_of_parse_card_name
(
&
evm_soc_card
,
"ti,model"
);
if
(
ret
)
return
ret
;
drvdata
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
drvdata
),
GFP_KERNEL
);
if
(
!
drvdata
)
return
-
ENOMEM
;
ret
=
of_property_read_u32
(
np
,
"ti,codec-clock-rate"
,
&
drvdata
->
sysclk
);
if
(
ret
<
0
)
return
-
EINVAL
;
snd_soc_card_set_drvdata
(
&
evm_soc_card
,
drvdata
);
ret
=
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
evm_soc_card
);
if
(
ret
)
dev_err
(
&
pdev
->
dev
,
"snd_soc_register_card failed (%d)
\n
"
,
ret
);
return
ret
;
}
static
int
davinci_evm_remove
(
struct
platform_device
*
pdev
)
{
struct
snd_soc_card
*
card
=
platform_get_drvdata
(
pdev
);
snd_soc_unregister_card
(
card
);
return
0
;
}
static
struct
platform_driver
davinci_evm_driver
=
{
.
probe
=
davinci_evm_probe
,
.
remove
=
davinci_evm_remove
,
.
driver
=
{
.
name
=
"davinci_evm"
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
of_match_ptr
(
davinci_evm_dt_ids
),
},
};
#endif
static
struct
platform_device
*
evm_snd_device
;
static
int
__init
evm_init
(
void
)
...
...
@@ -296,6 +424,15 @@ static int __init evm_init(void)
int
index
;
int
ret
;
/*
* If dtb is there, the devices will be created dynamically.
* Only register platfrom driver structure.
*/
#if defined(CONFIG_OF)
if
(
of_have_populated_dt
())
return
platform_driver_register
(
&
davinci_evm_driver
);
#endif
if
(
machine_is_davinci_evm
())
{
evm_snd_dev_data
=
&
dm6446_snd_soc_card_evm
;
index
=
0
;
...
...
@@ -331,6 +468,13 @@ static int __init evm_init(void)
static
void
__exit
evm_exit
(
void
)
{
#if defined(CONFIG_OF)
if
(
of_have_populated_dt
())
{
platform_driver_unregister
(
&
davinci_evm_driver
);
return
;
}
#endif
platform_device_unregister
(
evm_snd_device
);
}
...
...
sound/soc/davinci/davinci-mcasp.c
View file @
cf44fba0
...
...
@@ -1001,18 +1001,40 @@ static const struct snd_soc_component_driver davinci_mcasp_component = {
.
name
=
"davinci-mcasp"
,
};
/* Some HW specific values and defaults. The rest is filled in from DT. */
static
struct
snd_platform_data
dm646x_mcasp_pdata
=
{
.
tx_dma_offset
=
0x400
,
.
rx_dma_offset
=
0x400
,
.
asp_chan_q
=
EVENTQ_0
,
.
version
=
MCASP_VERSION_1
,
};
static
struct
snd_platform_data
da830_mcasp_pdata
=
{
.
tx_dma_offset
=
0x2000
,
.
rx_dma_offset
=
0x2000
,
.
asp_chan_q
=
EVENTQ_0
,
.
version
=
MCASP_VERSION_2
,
};
static
struct
snd_platform_data
omap2_mcasp_pdata
=
{
.
tx_dma_offset
=
0
,
.
rx_dma_offset
=
0
,
.
asp_chan_q
=
EVENTQ_0
,
.
version
=
MCASP_VERSION_3
,
};
static
const
struct
of_device_id
mcasp_dt_ids
[]
=
{
{
.
compatible
=
"ti,dm646x-mcasp-audio"
,
.
data
=
(
void
*
)
MCASP_VERSION_1
,
.
data
=
&
dm646x_mcasp_pdata
,
},
{
.
compatible
=
"ti,da830-mcasp-audio"
,
.
data
=
(
void
*
)
MCASP_VERSION_2
,
.
data
=
&
da830_mcasp_pdata
,
},
{
.
compatible
=
"ti,
omap2
-mcasp-audio"
,
.
data
=
(
void
*
)
MCASP_VERSION_3
,
.
compatible
=
"ti,
am33xx
-mcasp-audio"
,
.
data
=
&
omap2_mcasp_pdata
,
},
{
/* sentinel */
}
};
...
...
@@ -1025,9 +1047,9 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
struct
snd_platform_data
*
pdata
=
NULL
;
const
struct
of_device_id
*
match
=
of_match_device
(
mcasp_dt_ids
,
&
pdev
->
dev
);
struct
of_phandle_args
dma_spec
;
const
u32
*
of_serial_dir32
;
u8
*
of_serial_dir
;
u32
val
;
int
i
,
ret
=
0
;
...
...
@@ -1035,20 +1057,13 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
pdata
=
pdev
->
dev
.
platform_data
;
return
pdata
;
}
else
if
(
match
)
{
pdata
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
pdata
),
GFP_KERNEL
);
if
(
!
pdata
)
{
ret
=
-
ENOMEM
;
goto
nodata
;
}
pdata
=
(
struct
snd_platform_data
*
)
match
->
data
;
}
else
{
/* control shouldn't reach here. something is wrong */
ret
=
-
EINVAL
;
goto
nodata
;
}
if
(
match
->
data
)
pdata
->
version
=
(
u8
)((
int
)
match
->
data
);
ret
=
of_property_read_u32
(
np
,
"op-mode"
,
&
val
);
if
(
ret
>=
0
)
pdata
->
op_mode
=
val
;
...
...
@@ -1065,22 +1080,10 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
pdata
->
tdm_slots
=
val
;
}
ret
=
of_property_read_u32
(
np
,
"num-serializer"
,
&
val
);
if
(
ret
>=
0
)
pdata
->
num_serializer
=
val
;
of_serial_dir32
=
of_get_property
(
np
,
"serial-dir"
,
&
val
);
val
/=
sizeof
(
u32
);
if
(
val
!=
pdata
->
num_serializer
)
{
dev_err
(
&
pdev
->
dev
,
"num-serializer(%d) != serial-dir size(%d)
\n
"
,
pdata
->
num_serializer
,
val
);
ret
=
-
EINVAL
;
goto
nodata
;
}
if
(
of_serial_dir32
)
{
of_serial_dir
=
devm_kzalloc
(
&
pdev
->
dev
,
u8
*
of_serial_dir
=
devm_kzalloc
(
&
pdev
->
dev
,
(
sizeof
(
*
of_serial_dir
)
*
val
),
GFP_KERNEL
);
if
(
!
of_serial_dir
)
{
...
...
@@ -1088,12 +1091,35 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
goto
nodata
;
}
for
(
i
=
0
;
i
<
pdata
->
num_serializer
;
i
++
)
for
(
i
=
0
;
i
<
val
;
i
++
)
of_serial_dir
[
i
]
=
be32_to_cpup
(
&
of_serial_dir32
[
i
]);
pdata
->
num_serializer
=
val
;
pdata
->
serial_dir
=
of_serial_dir
;
}
ret
=
of_property_match_string
(
np
,
"dma-names"
,
"tx"
);
if
(
ret
<
0
)
goto
nodata
;
ret
=
of_parse_phandle_with_args
(
np
,
"dmas"
,
"#dma-cells"
,
ret
,
&
dma_spec
);
if
(
ret
<
0
)
goto
nodata
;
pdata
->
tx_dma_channel
=
dma_spec
.
args
[
0
];
ret
=
of_property_match_string
(
np
,
"dma-names"
,
"rx"
);
if
(
ret
<
0
)
goto
nodata
;
ret
=
of_parse_phandle_with_args
(
np
,
"dmas"
,
"#dma-cells"
,
ret
,
&
dma_spec
);
if
(
ret
<
0
)
goto
nodata
;
pdata
->
rx_dma_channel
=
dma_spec
.
args
[
0
];
ret
=
of_property_read_u32
(
np
,
"tx-num-evt"
,
&
val
);
if
(
ret
>=
0
)
pdata
->
txnumevt
=
val
;
...
...
@@ -1124,7 +1150,7 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
static
int
davinci_mcasp_probe
(
struct
platform_device
*
pdev
)
{
struct
davinci_pcm_dma_params
*
dma_data
;
struct
resource
*
mem
,
*
ioarea
,
*
res
;
struct
resource
*
mem
,
*
ioarea
,
*
res
,
*
dat
;
struct
snd_platform_data
*
pdata
;
struct
davinci_audio_dev
*
dev
;
int
ret
;
...
...
@@ -1145,11 +1171,16 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
return
-
EINVAL
;
}
mem
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"mpu"
);
if
(
!
mem
)
{
dev_warn
(
dev
->
dev
,
"
\"
mpu
\"
mem resource not found, using index 0
\n
"
);
mem
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
mem
)
{
dev_err
(
&
pdev
->
dev
,
"no mem resource?
\n
"
);
return
-
ENODEV
;
}
}
ioarea
=
devm_request_mem_region
(
&
pdev
->
dev
,
mem
->
start
,
resource_size
(
mem
),
pdev
->
name
);
...
...
@@ -1182,40 +1213,36 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dev
->
rxnumevt
=
pdata
->
rxnumevt
;
dev
->
dev
=
&
pdev
->
dev
;
dat
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"dat"
);
if
(
!
dat
)
dat
=
mem
;
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
);
dma_data
->
dma_addr
=
dat
->
start
+
pdata
->
tx_dma_offset
;
/* first TX, then RX */
res
=
platform_get_resource
(
pdev
,
IORESOURCE_DMA
,
0
);
if
(
!
res
)
{
dev_err
(
&
pdev
->
dev
,
"no DMA resource
\n
"
);
ret
=
-
ENODEV
;
goto
err_release_clk
;
}
if
(
res
)
dma_data
->
channel
=
res
->
start
;
else
dma_data
->
channel
=
pdata
->
tx_dma_channel
;
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
);
dma_data
->
dma_addr
=
dat
->
start
+
pdata
->
rx_dma_offset
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_DMA
,
1
);
if
(
!
res
)
{
dev_err
(
&
pdev
->
dev
,
"no DMA resource
\n
"
);
ret
=
-
ENODEV
;
goto
err_release_clk
;
}
if
(
res
)
dma_data
->
channel
=
res
->
start
;
else
dma_data
->
channel
=
pdata
->
rx_dma_channel
;
dev_set_drvdata
(
&
pdev
->
dev
,
dev
);
ret
=
snd_soc_register_component
(
&
pdev
->
dev
,
&
davinci_mcasp_component
,
&
davinci_mcasp_dai
[
pdata
->
op_mode
],
1
);
...
...
@@ -1251,12 +1278,51 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
return
0
;
}
#ifdef CONFIG_PM_SLEEP
static
int
davinci_mcasp_suspend
(
struct
device
*
dev
)
{
struct
davinci_audio_dev
*
a
=
dev_get_drvdata
(
dev
);
void
__iomem
*
base
=
a
->
base
;
a
->
context
.
txfmtctl
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_TXFMCTL_REG
);
a
->
context
.
rxfmtctl
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_RXFMCTL_REG
);
a
->
context
.
txfmt
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_TXFMT_REG
);
a
->
context
.
rxfmt
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_RXFMT_REG
);
a
->
context
.
aclkxctl
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_ACLKXCTL_REG
);
a
->
context
.
aclkrctl
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_ACLKRCTL_REG
);
a
->
context
.
pdir
=
mcasp_get_reg
(
base
+
DAVINCI_MCASP_PDIR_REG
);
return
0
;
}
static
int
davinci_mcasp_resume
(
struct
device
*
dev
)
{
struct
davinci_audio_dev
*
a
=
dev_get_drvdata
(
dev
);
void
__iomem
*
base
=
a
->
base
;
mcasp_set_reg
(
base
+
DAVINCI_MCASP_TXFMCTL_REG
,
a
->
context
.
txfmtctl
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_RXFMCTL_REG
,
a
->
context
.
rxfmtctl
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_TXFMT_REG
,
a
->
context
.
txfmt
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_RXFMT_REG
,
a
->
context
.
rxfmt
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_ACLKXCTL_REG
,
a
->
context
.
aclkxctl
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_ACLKRCTL_REG
,
a
->
context
.
aclkrctl
);
mcasp_set_reg
(
base
+
DAVINCI_MCASP_PDIR_REG
,
a
->
context
.
pdir
);
return
0
;
}
#endif
SIMPLE_DEV_PM_OPS
(
davinci_mcasp_pm_ops
,
davinci_mcasp_suspend
,
davinci_mcasp_resume
);
static
struct
platform_driver
davinci_mcasp_driver
=
{
.
probe
=
davinci_mcasp_probe
,
.
remove
=
davinci_mcasp_remove
,
.
driver
=
{
.
name
=
"davinci-mcasp"
,
.
owner
=
THIS_MODULE
,
.
pm
=
&
davinci_mcasp_pm_ops
,
.
of_match_table
=
mcasp_dt_ids
,
},
};
...
...
@@ -1266,4 +1332,3 @@ module_platform_driver(davinci_mcasp_driver);
MODULE_AUTHOR
(
"Steve Chen"
);
MODULE_DESCRIPTION
(
"TI DAVINCI McASP SoC Interface"
);
MODULE_LICENSE
(
"GPL"
);
sound/soc/davinci/davinci-mcasp.h
View file @
cf44fba0
...
...
@@ -43,6 +43,18 @@ struct davinci_audio_dev {
/* McASP FIFO related */
u8
txnumevt
;
u8
rxnumevt
;
#ifdef CONFIG_PM_SLEEP
struct
{
u32
txfmtctl
;
u32
rxfmtctl
;
u32
txfmt
;
u32
rxfmt
;
u32
aclkxctl
;
u32
aclkrctl
;
u32
pdir
;
}
context
;
#endif
};
#endif
/* DAVINCI_MCASP_H */
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