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
599ed4b0
Commit
599ed4b0
authored
May 23, 2012
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-3.5' of
git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc
into topic/asoc
parents
85e184e4
ced47a31
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
531 additions
and
103 deletions
+531
-103
Documentation/devicetree/bindings/sound/omap-dmic.txt
Documentation/devicetree/bindings/sound/omap-dmic.txt
+21
-0
Documentation/devicetree/bindings/sound/omap-mcpdm.txt
Documentation/devicetree/bindings/sound/omap-mcpdm.txt
+21
-0
sound/soc/omap/Kconfig
sound/soc/omap/Kconfig
+4
-3
sound/soc/omap/Makefile
sound/soc/omap/Makefile
+2
-2
sound/soc/omap/mcbsp.c
sound/soc/omap/mcbsp.c
+90
-25
sound/soc/omap/mcbsp.h
sound/soc/omap/mcbsp.h
+6
-2
sound/soc/omap/omap-abe-twl6040.c
sound/soc/omap/omap-abe-twl6040.c
+33
-35
sound/soc/omap/omap-dmic.c
sound/soc/omap/omap-dmic.c
+8
-0
sound/soc/omap/omap-hdmi-card.c
sound/soc/omap/omap-hdmi-card.c
+87
-0
sound/soc/omap/omap-hdmi.c
sound/soc/omap/omap-hdmi.c
+223
-15
sound/soc/omap/omap-hdmi.h
sound/soc/omap/omap-hdmi.h
+3
-1
sound/soc/omap/omap-mcbsp.c
sound/soc/omap/omap-mcbsp.c
+25
-20
sound/soc/omap/omap-mcpdm.c
sound/soc/omap/omap-mcpdm.c
+8
-0
No files found.
Documentation/devicetree/bindings/sound/omap-dmic.txt
0 → 100644
View file @
599ed4b0
* Texas Instruments OMAP4+ Digital Microphone Module
Required properties:
- compatible: "ti,omap4-dmic"
- reg: Register location and size as an array:
<MPU access base address, size>,
<L3 interconnect address, size>;
- interrupts: Interrupt number for DMIC
- interrupt-parent: The parent interrupt controller
- ti,hwmods: Name of the hwmod associated with OMAP dmic IP
Example:
dmic: dmic@4012e000 {
compatible = "ti,omap4-dmic";
reg = <0x4012e000 0x7f>, /* MPU private access */
<0x4902e000 0x7f>; /* L3 Interconnect */
interrupts = <0 114 0x4>;
interrupt-parent = <&gic>;
ti,hwmods = "dmic";
};
Documentation/devicetree/bindings/sound/omap-mcpdm.txt
0 → 100644
View file @
599ed4b0
* Texas Instruments OMAP4+ McPDM
Required properties:
- compatible: "ti,omap4-mcpdm"
- reg: Register location and size as an array:
<MPU access base address, size>,
<L3 interconnect address, size>;
- interrupts: Interrupt number for McPDM
- interrupt-parent: The parent interrupt controller
- ti,hwmods: Name of the hwmod associated to the McPDM
Example:
mcpdm: mcpdm@40132000 {
compatible = "ti,omap4-mcpdm";
reg = <0x40132000 0x7f>, /* MPU private access */
<0x49032000 0x7f>; /* L3 Interconnect */
interrupts = <0 112 0x4>;
interrupt-parent = <&gic>;
ti,hwmods = "mcpdm";
};
sound/soc/omap/Kconfig
View file @
599ed4b0
...
@@ -109,11 +109,12 @@ config SND_OMAP_SOC_OMAP_ABE_TWL6040
...
@@ -109,11 +109,12 @@ config SND_OMAP_SOC_OMAP_ABE_TWL6040
- PandaBoard (4430)
- PandaBoard (4430)
- PandaBoardES (4460)
- PandaBoardES (4460)
config SND_OMAP_SOC_OMAP
4
_HDMI
config SND_OMAP_SOC_OMAP_HDMI
tristate "SoC Audio support for Texas Instruments OMAP
4
HDMI"
tristate "SoC Audio support for Texas Instruments OMAP HDMI"
depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS
&& ARCH_OMAP4
depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS
select SND_OMAP_SOC_HDMI
select SND_OMAP_SOC_HDMI
select SND_SOC_OMAP_HDMI_CODEC
select SND_SOC_OMAP_HDMI_CODEC
select OMAP4_DSS_HDMI_AUDIO
help
help
Say Y if you want to add support for SoC HDMI audio on Texas Instruments
Say Y if you want to add support for SoC HDMI audio on Texas Instruments
OMAP4 chips
OMAP4 chips
...
...
sound/soc/omap/Makefile
View file @
599ed4b0
...
@@ -25,7 +25,7 @@ snd-soc-omap3pandora-objs := omap3pandora.o
...
@@ -25,7 +25,7 @@ snd-soc-omap3pandora-objs := omap3pandora.o
snd-soc-omap3beagle-objs
:=
omap3beagle.o
snd-soc-omap3beagle-objs
:=
omap3beagle.o
snd-soc-zoom2-objs
:=
zoom2.o
snd-soc-zoom2-objs
:=
zoom2.o
snd-soc-igep0020-objs
:=
igep0020.o
snd-soc-igep0020-objs
:=
igep0020.o
snd-soc-omap
4-hdmi-objs
:=
omap4
-hdmi-card.o
snd-soc-omap
-hdmi-card-objs
:=
omap
-hdmi-card.o
obj-$(CONFIG_SND_OMAP_SOC_N810)
+=
snd-soc-n810.o
obj-$(CONFIG_SND_OMAP_SOC_N810)
+=
snd-soc-n810.o
obj-$(CONFIG_SND_OMAP_SOC_RX51)
+=
snd-soc-rx51.o
obj-$(CONFIG_SND_OMAP_SOC_RX51)
+=
snd-soc-rx51.o
...
@@ -41,4 +41,4 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
...
@@ -41,4 +41,4 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE)
+=
snd-soc-omap3beagle.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE)
+=
snd-soc-omap3beagle.o
obj-$(CONFIG_SND_OMAP_SOC_ZOOM2)
+=
snd-soc-zoom2.o
obj-$(CONFIG_SND_OMAP_SOC_ZOOM2)
+=
snd-soc-zoom2.o
obj-$(CONFIG_SND_OMAP_SOC_IGEP0020)
+=
snd-soc-igep0020.o
obj-$(CONFIG_SND_OMAP_SOC_IGEP0020)
+=
snd-soc-igep0020.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP
4_HDMI)
+=
snd-soc-omap4-hdmi
.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP
_HDMI)
+=
snd-soc-omap-hdmi-card
.o
sound/soc/omap/mcbsp.c
View file @
599ed4b0
...
@@ -109,6 +109,47 @@ static void omap_mcbsp_dump_reg(struct omap_mcbsp *mcbsp)
...
@@ -109,6 +109,47 @@ static void omap_mcbsp_dump_reg(struct omap_mcbsp *mcbsp)
dev_dbg
(
mcbsp
->
dev
,
"***********************
\n
"
);
dev_dbg
(
mcbsp
->
dev
,
"***********************
\n
"
);
}
}
static
irqreturn_t
omap_mcbsp_irq_handler
(
int
irq
,
void
*
dev_id
)
{
struct
omap_mcbsp
*
mcbsp
=
dev_id
;
u16
irqst
;
irqst
=
MCBSP_READ
(
mcbsp
,
IRQST
);
dev_dbg
(
mcbsp
->
dev
,
"IRQ callback : 0x%x
\n
"
,
irqst
);
if
(
irqst
&
RSYNCERREN
)
dev_err
(
mcbsp
->
dev
,
"RX Frame Sync Error!
\n
"
);
if
(
irqst
&
RFSREN
)
dev_dbg
(
mcbsp
->
dev
,
"RX Frame Sync
\n
"
);
if
(
irqst
&
REOFEN
)
dev_dbg
(
mcbsp
->
dev
,
"RX End Of Frame
\n
"
);
if
(
irqst
&
RRDYEN
)
dev_dbg
(
mcbsp
->
dev
,
"RX Buffer Threshold Reached
\n
"
);
if
(
irqst
&
RUNDFLEN
)
dev_err
(
mcbsp
->
dev
,
"RX Buffer Underflow!
\n
"
);
if
(
irqst
&
ROVFLEN
)
dev_err
(
mcbsp
->
dev
,
"RX Buffer Overflow!
\n
"
);
if
(
irqst
&
XSYNCERREN
)
dev_err
(
mcbsp
->
dev
,
"TX Frame Sync Error!
\n
"
);
if
(
irqst
&
XFSXEN
)
dev_dbg
(
mcbsp
->
dev
,
"TX Frame Sync
\n
"
);
if
(
irqst
&
XEOFEN
)
dev_dbg
(
mcbsp
->
dev
,
"TX End Of Frame
\n
"
);
if
(
irqst
&
XRDYEN
)
dev_dbg
(
mcbsp
->
dev
,
"TX Buffer threshold Reached
\n
"
);
if
(
irqst
&
XUNDFLEN
)
dev_err
(
mcbsp
->
dev
,
"TX Buffer Underflow!
\n
"
);
if
(
irqst
&
XOVFLEN
)
dev_err
(
mcbsp
->
dev
,
"TX Buffer Overflow!
\n
"
);
if
(
irqst
&
XEMPTYEOFEN
)
dev_dbg
(
mcbsp
->
dev
,
"TX Buffer empty at end of frame
\n
"
);
MCBSP_WRITE
(
mcbsp
,
IRQST
,
irqst
);
return
IRQ_HANDLED
;
}
static
irqreturn_t
omap_mcbsp_tx_irq_handler
(
int
irq
,
void
*
dev_id
)
static
irqreturn_t
omap_mcbsp_tx_irq_handler
(
int
irq
,
void
*
dev_id
)
{
{
struct
omap_mcbsp
*
mcbsp_tx
=
dev_id
;
struct
omap_mcbsp
*
mcbsp_tx
=
dev_id
;
...
@@ -176,6 +217,10 @@ void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
...
@@ -176,6 +217,10 @@ void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
/* Enable wakeup behavior */
/* Enable wakeup behavior */
if
(
mcbsp
->
pdata
->
has_wakeup
)
if
(
mcbsp
->
pdata
->
has_wakeup
)
MCBSP_WRITE
(
mcbsp
,
WAKEUPEN
,
XRDYEN
|
RRDYEN
);
MCBSP_WRITE
(
mcbsp
,
WAKEUPEN
,
XRDYEN
|
RRDYEN
);
/* Enable TX/RX sync error interrupts by default */
if
(
mcbsp
->
irq
)
MCBSP_WRITE
(
mcbsp
,
IRQEN
,
RSYNCERREN
|
XSYNCERREN
);
}
}
/**
/**
...
@@ -489,23 +534,25 @@ int omap_mcbsp_request(struct omap_mcbsp *mcbsp)
...
@@ -489,23 +534,25 @@ int omap_mcbsp_request(struct omap_mcbsp *mcbsp)
MCBSP_WRITE
(
mcbsp
,
SPCR1
,
0
);
MCBSP_WRITE
(
mcbsp
,
SPCR1
,
0
);
MCBSP_WRITE
(
mcbsp
,
SPCR2
,
0
);
MCBSP_WRITE
(
mcbsp
,
SPCR2
,
0
);
err
=
request_irq
(
mcbsp
->
tx_irq
,
omap_mcbsp_tx_irq_handler
,
if
(
mcbsp
->
irq
)
{
0
,
"McBSP"
,
(
void
*
)
mcbsp
);
err
=
request_irq
(
mcbsp
->
irq
,
omap_mcbsp_irq_handler
,
0
,
if
(
err
!=
0
)
{
"McBSP"
,
(
void
*
)
mcbsp
);
dev_err
(
mcbsp
->
dev
,
"Unable to request TX IRQ %d "
if
(
err
!=
0
)
{
"for McBSP%d
\n
"
,
mcbsp
->
tx_irq
,
dev_err
(
mcbsp
->
dev
,
"Unable to request IRQ
\n
"
);
mcbsp
->
id
);
goto
err_clk_disable
;
goto
err_clk_disable
;
}
}
}
else
{
err
=
request_irq
(
mcbsp
->
tx_irq
,
omap_mcbsp_tx_irq_handler
,
0
,
"McBSP TX"
,
(
void
*
)
mcbsp
);
if
(
err
!=
0
)
{
dev_err
(
mcbsp
->
dev
,
"Unable to request TX IRQ
\n
"
);
goto
err_clk_disable
;
}
if
(
mcbsp
->
rx_irq
)
{
err
=
request_irq
(
mcbsp
->
rx_irq
,
omap_mcbsp_rx_irq_handler
,
0
,
err
=
request_irq
(
mcbsp
->
rx_irq
,
"McBSP RX"
,
(
void
*
)
mcbsp
);
omap_mcbsp_rx_irq_handler
,
0
,
"McBSP"
,
(
void
*
)
mcbsp
);
if
(
err
!=
0
)
{
if
(
err
!=
0
)
{
dev_err
(
mcbsp
->
dev
,
"Unable to request RX IRQ %d "
dev_err
(
mcbsp
->
dev
,
"Unable to request RX IRQ
\n
"
);
"for McBSP%d
\n
"
,
mcbsp
->
rx_irq
,
mcbsp
->
id
);
goto
err_free_irq
;
goto
err_free_irq
;
}
}
}
}
...
@@ -542,9 +589,16 @@ void omap_mcbsp_free(struct omap_mcbsp *mcbsp)
...
@@ -542,9 +589,16 @@ void omap_mcbsp_free(struct omap_mcbsp *mcbsp)
if
(
mcbsp
->
pdata
->
has_wakeup
)
if
(
mcbsp
->
pdata
->
has_wakeup
)
MCBSP_WRITE
(
mcbsp
,
WAKEUPEN
,
0
);
MCBSP_WRITE
(
mcbsp
,
WAKEUPEN
,
0
);
if
(
mcbsp
->
rx_irq
)
/* Disable interrupt requests */
if
(
mcbsp
->
irq
)
MCBSP_WRITE
(
mcbsp
,
IRQEN
,
0
);
if
(
mcbsp
->
irq
)
{
free_irq
(
mcbsp
->
irq
,
(
void
*
)
mcbsp
);
}
else
{
free_irq
(
mcbsp
->
rx_irq
,
(
void
*
)
mcbsp
);
free_irq
(
mcbsp
->
rx_irq
,
(
void
*
)
mcbsp
);
free_irq
(
mcbsp
->
tx_irq
,
(
void
*
)
mcbsp
);
free_irq
(
mcbsp
->
tx_irq
,
(
void
*
)
mcbsp
);
}
reg_cache
=
mcbsp
->
reg_cache
;
reg_cache
=
mcbsp
->
reg_cache
;
...
@@ -754,7 +808,7 @@ THRESHOLD_PROP_BUILDER(max_tx_thres);
...
@@ -754,7 +808,7 @@ THRESHOLD_PROP_BUILDER(max_tx_thres);
THRESHOLD_PROP_BUILDER
(
max_rx_thres
);
THRESHOLD_PROP_BUILDER
(
max_rx_thres
);
static
const
char
*
dma_op_modes
[]
=
{
static
const
char
*
dma_op_modes
[]
=
{
"element"
,
"threshold"
,
"frame"
,
"element"
,
"threshold"
,
};
};
static
ssize_t
dma_op_mode_show
(
struct
device
*
dev
,
static
ssize_t
dma_op_mode_show
(
struct
device
*
dev
,
...
@@ -949,13 +1003,24 @@ int __devinit omap_mcbsp_init(struct platform_device *pdev)
...
@@ -949,13 +1003,24 @@ int __devinit omap_mcbsp_init(struct platform_device *pdev)
else
else
mcbsp
->
phys_dma_base
=
res
->
start
;
mcbsp
->
phys_dma_base
=
res
->
start
;
mcbsp
->
tx_irq
=
platform_get_irq_byname
(
pdev
,
"tx"
);
/*
mcbsp
->
rx_irq
=
platform_get_irq_byname
(
pdev
,
"rx"
);
* OMAP1, 2 uses two interrupt lines: TX, RX
* OMAP2430, OMAP3 SoC have combined IRQ line as well.
/* From OMAP4 there will be a single irq line */
* OMAP4 and newer SoC only have the combined IRQ line.
if
(
mcbsp
->
tx_irq
==
-
ENXIO
)
{
* Use the combined IRQ if available since it gives better debugging
mcbsp
->
tx_irq
=
platform_get_irq
(
pdev
,
0
);
* possibilities.
mcbsp
->
rx_irq
=
0
;
*/
mcbsp
->
irq
=
platform_get_irq_byname
(
pdev
,
"common"
);
if
(
mcbsp
->
irq
==
-
ENXIO
)
{
mcbsp
->
tx_irq
=
platform_get_irq_byname
(
pdev
,
"tx"
);
if
(
mcbsp
->
tx_irq
==
-
ENXIO
)
{
mcbsp
->
irq
=
platform_get_irq
(
pdev
,
0
);
mcbsp
->
tx_irq
=
0
;
}
else
{
mcbsp
->
rx_irq
=
platform_get_irq_byname
(
pdev
,
"rx"
);
mcbsp
->
irq
=
0
;
}
}
}
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_DMA
,
"rx"
);
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_DMA
,
"rx"
);
...
...
sound/soc/omap/mcbsp.h
View file @
599ed4b0
...
@@ -217,17 +217,20 @@ enum {
...
@@ -217,17 +217,20 @@ enum {
/********************** McBSP DMA operating modes **************************/
/********************** McBSP DMA operating modes **************************/
#define MCBSP_DMA_MODE_ELEMENT 0
#define MCBSP_DMA_MODE_ELEMENT 0
#define MCBSP_DMA_MODE_THRESHOLD 1
#define MCBSP_DMA_MODE_THRESHOLD 1
#define MCBSP_DMA_MODE_FRAME 2
/********************** McBSP WAKEUPEN
bit definitions ************
*********/
/********************** McBSP WAKEUPEN
/IRQST/IRQEN bit definitions
*********/
#define RSYNCERREN BIT(0)
#define RSYNCERREN BIT(0)
#define RFSREN BIT(1)
#define RFSREN BIT(1)
#define REOFEN BIT(2)
#define REOFEN BIT(2)
#define RRDYEN BIT(3)
#define RRDYEN BIT(3)
#define RUNDFLEN BIT(4)
#define ROVFLEN BIT(5)
#define XSYNCERREN BIT(7)
#define XSYNCERREN BIT(7)
#define XFSXEN BIT(8)
#define XFSXEN BIT(8)
#define XEOFEN BIT(9)
#define XEOFEN BIT(9)
#define XRDYEN BIT(10)
#define XRDYEN BIT(10)
#define XUNDFLEN BIT(11)
#define XOVFLEN BIT(12)
#define XEMPTYEOFEN BIT(14)
#define XEMPTYEOFEN BIT(14)
/* Clock signal muxing options */
/* Clock signal muxing options */
...
@@ -295,6 +298,7 @@ struct omap_mcbsp {
...
@@ -295,6 +298,7 @@ struct omap_mcbsp {
int
configured
;
int
configured
;
u8
free
;
u8
free
;
int
irq
;
int
rx_irq
;
int
rx_irq
;
int
tx_irq
;
int
tx_irq
;
...
...
sound/soc/omap/omap-abe-twl6040.c
View file @
599ed4b0
...
@@ -40,6 +40,11 @@
...
@@ -40,6 +40,11 @@
#include "omap-pcm.h"
#include "omap-pcm.h"
#include "../codecs/twl6040.h"
#include "../codecs/twl6040.h"
struct
abe_twl6040
{
int
jack_detection
;
/* board can detect jack events */
int
mclk_freq
;
/* MCLK frequency speed for twl6040 */
};
static
int
omap_abe_hw_params
(
struct
snd_pcm_substream
*
substream
,
static
int
omap_abe_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
struct
snd_pcm_hw_params
*
params
)
{
{
...
@@ -47,13 +52,13 @@ static int omap_abe_hw_params(struct snd_pcm_substream *substream,
...
@@ -47,13 +52,13 @@ static int omap_abe_hw_params(struct snd_pcm_substream *substream,
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_card
*
card
=
codec
->
card
;
struct
snd_soc_card
*
card
=
codec
->
card
;
struct
omap_abe_twl6040_data
*
pdata
=
dev_get_platdata
(
card
->
dev
);
struct
abe_twl6040
*
priv
=
snd_soc_card_get_drvdata
(
card
);
int
clk_id
,
freq
;
int
clk_id
,
freq
;
int
ret
;
int
ret
;
clk_id
=
twl6040_get_clk_id
(
rtd
->
codec
);
clk_id
=
twl6040_get_clk_id
(
rtd
->
codec
);
if
(
clk_id
==
TWL6040_SYSCLK_SEL_HPPLL
)
if
(
clk_id
==
TWL6040_SYSCLK_SEL_HPPLL
)
freq
=
p
data
->
mclk_freq
;
freq
=
p
riv
->
mclk_freq
;
else
if
(
clk_id
==
TWL6040_SYSCLK_SEL_LPPLL
)
else
if
(
clk_id
==
TWL6040_SYSCLK_SEL_LPPLL
)
freq
=
32768
;
freq
=
32768
;
else
else
...
@@ -128,6 +133,9 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
...
@@ -128,6 +133,9 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
SND_SOC_DAPM_MIC
(
"Main Handset Mic"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Main Handset Mic"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Sub Handset Mic"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Sub Handset Mic"
,
NULL
),
SND_SOC_DAPM_LINE
(
"Line In"
,
NULL
),
SND_SOC_DAPM_LINE
(
"Line In"
,
NULL
),
/* Digital microphones */
SND_SOC_DAPM_MIC
(
"Digital Mic"
,
NULL
),
};
};
static
const
struct
snd_soc_dapm_route
audio_map
[]
=
{
static
const
struct
snd_soc_dapm_route
audio_map
[]
=
{
...
@@ -173,6 +181,7 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -173,6 +181,7 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
struct
snd_soc_card
*
card
=
codec
->
card
;
struct
snd_soc_card
*
card
=
codec
->
card
;
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
struct
omap_abe_twl6040_data
*
pdata
=
dev_get_platdata
(
card
->
dev
);
struct
omap_abe_twl6040_data
*
pdata
=
dev_get_platdata
(
card
->
dev
);
struct
abe_twl6040
*
priv
=
snd_soc_card_get_drvdata
(
card
);
int
hs_trim
;
int
hs_trim
;
int
ret
=
0
;
int
ret
=
0
;
...
@@ -196,7 +205,7 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -196,7 +205,7 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
TWL6040_HSF_TRIM_RIGHT
(
hs_trim
));
TWL6040_HSF_TRIM_RIGHT
(
hs_trim
));
/* Headset jack detection only if it is supported */
/* Headset jack detection only if it is supported */
if
(
p
data
->
jack_detection
)
{
if
(
p
riv
->
jack_detection
)
{
ret
=
snd_soc_jack_new
(
codec
,
"Headset Jack"
,
ret
=
snd_soc_jack_new
(
codec
,
"Headset Jack"
,
SND_JACK_HEADSET
,
&
hs_jack
);
SND_JACK_HEADSET
,
&
hs_jack
);
if
(
ret
)
if
(
ret
)
...
@@ -210,10 +219,6 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -210,10 +219,6 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
return
ret
;
return
ret
;
}
}
static
const
struct
snd_soc_dapm_widget
dmic_dapm_widgets
[]
=
{
SND_SOC_DAPM_MIC
(
"Digital Mic"
,
NULL
),
};
static
const
struct
snd_soc_dapm_route
dmic_audio_map
[]
=
{
static
const
struct
snd_soc_dapm_route
dmic_audio_map
[]
=
{
{
"DMic"
,
NULL
,
"Digital Mic"
},
{
"DMic"
,
NULL
,
"Digital Mic"
},
{
"Digital Mic"
,
NULL
,
"Digital Mic1 Bias"
},
{
"Digital Mic"
,
NULL
,
"Digital Mic1 Bias"
},
...
@@ -223,19 +228,13 @@ static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -223,19 +228,13 @@ static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd)
{
{
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
int
ret
;
ret
=
snd_soc_dapm_new_controls
(
dapm
,
dmic_dapm_widgets
,
ARRAY_SIZE
(
dmic_dapm_widgets
));
if
(
ret
)
return
ret
;
return
snd_soc_dapm_add_routes
(
dapm
,
dmic_audio_map
,
return
snd_soc_dapm_add_routes
(
dapm
,
dmic_audio_map
,
ARRAY_SIZE
(
dmic_audio_map
));
ARRAY_SIZE
(
dmic_audio_map
));
}
}
/* Digital audio interface glue - connects codec <--> CPU */
/* Digital audio interface glue - connects codec <--> CPU */
static
struct
snd_soc_dai_link
twl6040_dmic_dai
[]
=
{
static
struct
snd_soc_dai_link
abe_twl6040_dai_links
[]
=
{
{
{
.
name
=
"TWL6040"
,
.
name
=
"TWL6040"
,
.
stream_name
=
"TWL6040"
,
.
stream_name
=
"TWL6040"
,
...
@@ -258,19 +257,6 @@ static struct snd_soc_dai_link twl6040_dmic_dai[] = {
...
@@ -258,19 +257,6 @@ static struct snd_soc_dai_link twl6040_dmic_dai[] = {
},
},
};
};
static
struct
snd_soc_dai_link
twl6040_only_dai
[]
=
{
{
.
name
=
"TWL6040"
,
.
stream_name
=
"TWL6040"
,
.
cpu_dai_name
=
"omap-mcpdm"
,
.
codec_dai_name
=
"twl6040-legacy"
,
.
platform_name
=
"omap-pcm-audio"
,
.
codec_name
=
"twl6040-codec"
,
.
init
=
omap_abe_twl6040_init
,
.
ops
=
&
omap_abe_ops
,
},
};
/* Audio machine driver */
/* Audio machine driver */
static
struct
snd_soc_card
omap_abe_card
=
{
static
struct
snd_soc_card
omap_abe_card
=
{
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
...
@@ -285,6 +271,8 @@ static __devinit int omap_abe_probe(struct platform_device *pdev)
...
@@ -285,6 +271,8 @@ static __devinit int omap_abe_probe(struct platform_device *pdev)
{
{
struct
omap_abe_twl6040_data
*
pdata
=
dev_get_platdata
(
&
pdev
->
dev
);
struct
omap_abe_twl6040_data
*
pdata
=
dev_get_platdata
(
&
pdev
->
dev
);
struct
snd_soc_card
*
card
=
&
omap_abe_card
;
struct
snd_soc_card
*
card
=
&
omap_abe_card
;
struct
abe_twl6040
*
priv
;
int
num_links
=
0
;
int
ret
;
int
ret
;
card
->
dev
=
&
pdev
->
dev
;
card
->
dev
=
&
pdev
->
dev
;
...
@@ -294,6 +282,10 @@ static __devinit int omap_abe_probe(struct platform_device *pdev)
...
@@ -294,6 +282,10 @@ static __devinit int omap_abe_probe(struct platform_device *pdev)
return
-
ENODEV
;
return
-
ENODEV
;
}
}
priv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
abe_twl6040
),
GFP_KERNEL
);
if
(
priv
==
NULL
)
return
-
ENOMEM
;
if
(
pdata
->
card_name
)
{
if
(
pdata
->
card_name
)
{
card
->
name
=
pdata
->
card_name
;
card
->
name
=
pdata
->
card_name
;
}
else
{
}
else
{
...
@@ -301,18 +293,24 @@ static __devinit int omap_abe_probe(struct platform_device *pdev)
...
@@ -301,18 +293,24 @@ static __devinit int omap_abe_probe(struct platform_device *pdev)
return
-
ENODEV
;
return
-
ENODEV
;
}
}
if
(
!
pdata
->
mclk_freq
)
{
priv
->
jack_detection
=
pdata
->
jack_detection
;
priv
->
mclk_freq
=
pdata
->
mclk_freq
;
if
(
!
priv
->
mclk_freq
)
{
dev_err
(
&
pdev
->
dev
,
"MCLK frequency missing
\n
"
);
dev_err
(
&
pdev
->
dev
,
"MCLK frequency missing
\n
"
);
return
-
ENODEV
;
return
-
ENODEV
;
}
}
if
(
pdata
->
has_dmic
)
{
if
(
pdata
->
has_dmic
)
card
->
dai_link
=
twl6040_dmic_dai
;
num_links
=
2
;
card
->
num_links
=
ARRAY_SIZE
(
twl6040_dmic_dai
);
else
}
else
{
num_links
=
1
;
card
->
dai_link
=
twl6040_only_dai
;
card
->
num_links
=
ARRAY_SIZE
(
twl6040_only_dai
);
card
->
dai_link
=
abe_twl6040_dai_links
;
}
card
->
num_links
=
num_links
;
snd_soc_card_set_drvdata
(
card
,
priv
);
ret
=
snd_soc_register_card
(
card
);
ret
=
snd_soc_register_card
(
card
);
if
(
ret
)
if
(
ret
)
...
...
sound/soc/omap/omap-dmic.c
View file @
599ed4b0
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
#include <linux/io.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/pm_runtime.h>
#include <linux/of_device.h>
#include <plat/dma.h>
#include <plat/dma.h>
#include <sound/core.h>
#include <sound/core.h>
...
@@ -528,10 +529,17 @@ static int __devexit asoc_dmic_remove(struct platform_device *pdev)
...
@@ -528,10 +529,17 @@ static int __devexit asoc_dmic_remove(struct platform_device *pdev)
return
0
;
return
0
;
}
}
static
const
struct
of_device_id
omap_dmic_of_match
[]
=
{
{
.
compatible
=
"ti,omap4-dmic"
,
},
{
}
};
MODULE_DEVICE_TABLE
(
of
,
omap_dmic_of_match
);
static
struct
platform_driver
asoc_dmic_driver
=
{
static
struct
platform_driver
asoc_dmic_driver
=
{
.
driver
=
{
.
driver
=
{
.
name
=
"omap-dmic"
,
.
name
=
"omap-dmic"
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
omap_dmic_of_match
,
},
},
.
probe
=
asoc_dmic_probe
,
.
probe
=
asoc_dmic_probe
,
.
remove
=
__devexit_p
(
asoc_dmic_remove
),
.
remove
=
__devexit_p
(
asoc_dmic_remove
),
...
...
sound/soc/omap/omap
4
-hdmi-card.c
→
sound/soc/omap/omap-hdmi-card.c
View file @
599ed4b0
/*
/*
* omap
4
-hdmi-card.c
* omap-hdmi-card.c
*
*
* OMAP ALSA SoC machine driver for TI OMAP
4
HDMI
* OMAP ALSA SoC machine driver for TI OMAP HDMI
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
* Author: Ricardo Neri <ricardo.neri@ti.com>
* Author: Ricardo Neri <ricardo.neri@ti.com>
*
*
...
@@ -27,61 +27,27 @@
...
@@ -27,61 +27,27 @@
#include <asm/mach-types.h>
#include <asm/mach-types.h>
#include <video/omapdss.h>
#include <video/omapdss.h>
#define DRV_NAME "omap
4
-hdmi-audio"
#define DRV_NAME "omap-hdmi-audio"
static
int
omap4_hdmi_dai_hw_params
(
struct
snd_pcm_substream
*
substream
,
static
struct
snd_soc_dai_link
omap_hdmi_dai
=
{
struct
snd_pcm_hw_params
*
params
)
{
int
i
;
struct
omap_overlay_manager
*
mgr
=
NULL
;
struct
device
*
dev
=
substream
->
pcm
->
card
->
dev
;
/* Find DSS HDMI device */
for
(
i
=
0
;
i
<
omap_dss_get_num_overlay_managers
();
i
++
)
{
mgr
=
omap_dss_get_overlay_manager
(
i
);
if
(
mgr
&&
mgr
->
device
&&
mgr
->
device
->
type
==
OMAP_DISPLAY_TYPE_HDMI
)
break
;
}
if
(
i
==
omap_dss_get_num_overlay_managers
())
{
dev_err
(
dev
,
"HDMI display device not found!
\n
"
);
return
-
ENODEV
;
}
/* Make sure HDMI is power-on to avoid L3 interconnect errors */
if
(
mgr
->
device
->
state
!=
OMAP_DSS_DISPLAY_ACTIVE
)
{
dev_err
(
dev
,
"HDMI display is not active!
\n
"
);
return
-
EIO
;
}
return
0
;
}
static
struct
snd_soc_ops
omap4_hdmi_dai_ops
=
{
.
hw_params
=
omap4_hdmi_dai_hw_params
,
};
static
struct
snd_soc_dai_link
omap4_hdmi_dai
=
{
.
name
=
"HDMI"
,
.
name
=
"HDMI"
,
.
stream_name
=
"HDMI"
,
.
stream_name
=
"HDMI"
,
.
cpu_dai_name
=
"hdmi-audio-dai"
,
.
cpu_dai_name
=
"
omap-
hdmi-audio-dai"
,
.
platform_name
=
"omap-pcm-audio"
,
.
platform_name
=
"omap-pcm-audio"
,
.
codec_name
=
"omapdss_hdmi"
,
.
codec_name
=
"hdmi-audio-codec"
,
.
codec_dai_name
=
"hdmi-audio-codec"
,
.
codec_dai_name
=
"omap-hdmi-hifi"
,
.
ops
=
&
omap4_hdmi_dai_ops
,
};
};
static
struct
snd_soc_card
snd_soc_omap
4
_hdmi
=
{
static
struct
snd_soc_card
snd_soc_omap_hdmi
=
{
.
name
=
"OMAP
4
HDMI"
,
.
name
=
"OMAPHDMI"
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
&
omap
4
_hdmi_dai
,
.
dai_link
=
&
omap_hdmi_dai
,
.
num_links
=
1
,
.
num_links
=
1
,
};
};
static
__devinit
int
omap
4
_hdmi_probe
(
struct
platform_device
*
pdev
)
static
__devinit
int
omap_hdmi_probe
(
struct
platform_device
*
pdev
)
{
{
struct
snd_soc_card
*
card
=
&
snd_soc_omap
4
_hdmi
;
struct
snd_soc_card
*
card
=
&
snd_soc_omap_hdmi
;
int
ret
;
int
ret
;
card
->
dev
=
&
pdev
->
dev
;
card
->
dev
=
&
pdev
->
dev
;
...
@@ -95,7 +61,7 @@ static __devinit int omap4_hdmi_probe(struct platform_device *pdev)
...
@@ -95,7 +61,7 @@ static __devinit int omap4_hdmi_probe(struct platform_device *pdev)
return
0
;
return
0
;
}
}
static
int
__devexit
omap
4
_hdmi_remove
(
struct
platform_device
*
pdev
)
static
int
__devexit
omap_hdmi_remove
(
struct
platform_device
*
pdev
)
{
{
struct
snd_soc_card
*
card
=
platform_get_drvdata
(
pdev
);
struct
snd_soc_card
*
card
=
platform_get_drvdata
(
pdev
);
...
@@ -104,18 +70,18 @@ static int __devexit omap4_hdmi_remove(struct platform_device *pdev)
...
@@ -104,18 +70,18 @@ static int __devexit omap4_hdmi_remove(struct platform_device *pdev)
return
0
;
return
0
;
}
}
static
struct
platform_driver
omap
4
_hdmi_driver
=
{
static
struct
platform_driver
omap_hdmi_driver
=
{
.
driver
=
{
.
driver
=
{
.
name
=
"omap4-hdmi-audio"
,
.
name
=
DRV_NAME
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
},
},
.
probe
=
omap
4
_hdmi_probe
,
.
probe
=
omap_hdmi_probe
,
.
remove
=
__devexit_p
(
omap
4
_hdmi_remove
),
.
remove
=
__devexit_p
(
omap_hdmi_remove
),
};
};
module_platform_driver
(
omap
4
_hdmi_driver
);
module_platform_driver
(
omap_hdmi_driver
);
MODULE_AUTHOR
(
"Ricardo Neri <ricardo.neri@ti.com>"
);
MODULE_AUTHOR
(
"Ricardo Neri <ricardo.neri@ti.com>"
);
MODULE_DESCRIPTION
(
"OMAP
4
HDMI machine ASoC driver"
);
MODULE_DESCRIPTION
(
"OMAP HDMI machine ASoC driver"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_ALIAS
(
"platform:"
DRV_NAME
);
MODULE_ALIAS
(
"platform:"
DRV_NAME
);
sound/soc/omap/omap-hdmi.c
View file @
599ed4b0
...
@@ -30,21 +30,28 @@
...
@@ -30,21 +30,28 @@
#include <sound/pcm_params.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/soc.h>
#include <sound/asound.h>
#include <sound/asoundef.h>
#include <video/omapdss.h>
#include <plat/dma.h>
#include <plat/dma.h>
#include "omap-pcm.h"
#include "omap-pcm.h"
#include "omap-hdmi.h"
#include "omap-hdmi.h"
#define DRV_NAME "hdmi-audio-dai"
#define DRV_NAME "
omap-
hdmi-audio-dai"
static
struct
omap_pcm_dma_data
omap_hdmi_dai_dma_params
=
{
struct
hdmi_priv
{
.
name
=
"HDMI playback"
,
struct
omap_pcm_dma_data
dma_params
;
.
sync_mode
=
OMAP_DMA_SYNC_PACKET
,
struct
omap_dss_audio
dss_audio
;
struct
snd_aes_iec958
iec
;
struct
snd_cea_861_aud_if
cea
;
struct
omap_dss_device
*
dssdev
;
};
};
static
int
omap_hdmi_dai_startup
(
struct
snd_pcm_substream
*
substream
,
static
int
omap_hdmi_dai_startup
(
struct
snd_pcm_substream
*
substream
,
struct
snd_soc_dai
*
dai
)
struct
snd_soc_dai
*
dai
)
{
{
struct
hdmi_priv
*
priv
=
snd_soc_dai_get_drvdata
(
dai
);
int
err
;
int
err
;
/*
/*
* Make sure that the period bytes are multiple of the DMA packet size.
* Make sure that the period bytes are multiple of the DMA packet size.
...
@@ -52,46 +59,201 @@ static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
...
@@ -52,46 +59,201 @@ static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
*/
*/
err
=
snd_pcm_hw_constraint_step
(
substream
->
runtime
,
0
,
err
=
snd_pcm_hw_constraint_step
(
substream
->
runtime
,
0
,
SNDRV_PCM_HW_PARAM_PERIOD_BYTES
,
128
);
SNDRV_PCM_HW_PARAM_PERIOD_BYTES
,
128
);
if
(
err
<
0
)
if
(
err
<
0
)
{
dev_err
(
dai
->
dev
,
"could not apply constraint
\n
"
);
return
err
;
return
err
;
}
if
(
!
priv
->
dssdev
->
driver
->
audio_supported
(
priv
->
dssdev
))
{
dev_err
(
dai
->
dev
,
"audio not supported
\n
"
);
return
-
ENODEV
;
}
return
0
;
return
0
;
}
}
static
int
omap_hdmi_dai_prepare
(
struct
snd_pcm_substream
*
substream
,
struct
snd_soc_dai
*
dai
)
{
struct
hdmi_priv
*
priv
=
snd_soc_dai_get_drvdata
(
dai
);
return
priv
->
dssdev
->
driver
->
audio_enable
(
priv
->
dssdev
);
}
static
int
omap_hdmi_dai_hw_params
(
struct
snd_pcm_substream
*
substream
,
static
int
omap_hdmi_dai_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
,
struct
snd_pcm_hw_params
*
params
,
struct
snd_soc_dai
*
dai
)
struct
snd_soc_dai
*
dai
)
{
{
struct
hdmi_priv
*
priv
=
snd_soc_dai_get_drvdata
(
dai
);
struct
snd_aes_iec958
*
iec
=
&
priv
->
iec
;
struct
snd_cea_861_aud_if
*
cea
=
&
priv
->
cea
;
int
err
=
0
;
int
err
=
0
;
switch
(
params_format
(
params
))
{
switch
(
params_format
(
params
))
{
case
SNDRV_PCM_FORMAT_S16_LE
:
case
SNDRV_PCM_FORMAT_S16_LE
:
omap_hdmi_dai_
dma_params
.
packet_size
=
16
;
priv
->
dma_params
.
packet_size
=
16
;
break
;
break
;
case
SNDRV_PCM_FORMAT_S24_LE
:
case
SNDRV_PCM_FORMAT_S24_LE
:
omap_hdmi_dai_
dma_params
.
packet_size
=
32
;
priv
->
dma_params
.
packet_size
=
32
;
break
;
break
;
default:
default:
err
=
-
EINVAL
;
dev_err
(
dai
->
dev
,
"format not supported!
\n
"
);
return
-
EINVAL
;
}
}
omap_hdmi_dai_
dma_params
.
data_type
=
OMAP_DMA_DATA_TYPE_S32
;
priv
->
dma_params
.
data_type
=
OMAP_DMA_DATA_TYPE_S32
;
snd_soc_dai_set_dma_data
(
dai
,
substream
,
snd_soc_dai_set_dma_data
(
dai
,
substream
,
&
omap_hdmi_dai_dma_params
);
&
priv
->
dma_params
);
/*
* fill the IEC-60958 channel status word
*/
/* specify IEC-60958-3 (commercial use) */
iec
->
status
[
0
]
&=
~
IEC958_AES0_PROFESSIONAL
;
/* specify that the audio is LPCM*/
iec
->
status
[
0
]
&=
~
IEC958_AES0_NONAUDIO
;
iec
->
status
[
0
]
|=
IEC958_AES0_CON_NOT_COPYRIGHT
;
iec
->
status
[
0
]
|=
IEC958_AES0_CON_EMPHASIS_NONE
;
iec
->
status
[
0
]
|=
IEC958_AES1_PRO_MODE_NOTID
;
iec
->
status
[
1
]
=
IEC958_AES1_CON_GENERAL
;
iec
->
status
[
2
]
|=
IEC958_AES2_CON_SOURCE_UNSPEC
;
iec
->
status
[
2
]
|=
IEC958_AES2_CON_CHANNEL_UNSPEC
;
switch
(
params_rate
(
params
))
{
case
32000
:
iec
->
status
[
3
]
|=
IEC958_AES3_CON_FS_32000
;
break
;
case
44100
:
iec
->
status
[
3
]
|=
IEC958_AES3_CON_FS_44100
;
break
;
case
48000
:
iec
->
status
[
3
]
|=
IEC958_AES3_CON_FS_48000
;
break
;
case
88200
:
iec
->
status
[
3
]
|=
IEC958_AES3_CON_FS_88200
;
break
;
case
96000
:
iec
->
status
[
3
]
|=
IEC958_AES3_CON_FS_96000
;
break
;
case
176400
:
iec
->
status
[
3
]
|=
IEC958_AES3_CON_FS_176400
;
break
;
case
192000
:
iec
->
status
[
3
]
|=
IEC958_AES3_CON_FS_192000
;
break
;
default:
dev_err
(
dai
->
dev
,
"rate not supported!
\n
"
);
return
-
EINVAL
;
}
/* specify the clock accuracy */
iec
->
status
[
3
]
|=
IEC958_AES3_CON_CLOCK_1000PPM
;
/*
* specify the word length. The same word length value can mean
* two different lengths. Hence, we need to specify the maximum
* word length as well.
*/
switch
(
params_format
(
params
))
{
case
SNDRV_PCM_FORMAT_S16_LE
:
iec
->
status
[
4
]
|=
IEC958_AES4_CON_WORDLEN_20_16
;
iec
->
status
[
4
]
&=
~
IEC958_AES4_CON_MAX_WORDLEN_24
;
break
;
case
SNDRV_PCM_FORMAT_S24_LE
:
iec
->
status
[
4
]
|=
IEC958_AES4_CON_WORDLEN_24_20
;
iec
->
status
[
4
]
|=
IEC958_AES4_CON_MAX_WORDLEN_24
;
break
;
default:
dev_err
(
dai
->
dev
,
"format not supported!
\n
"
);
return
-
EINVAL
;
}
/*
* Fill the CEA-861 audio infoframe (see spec for details)
*/
cea
->
db1_ct_cc
=
(
params_channels
(
params
)
-
1
)
&
CEA861_AUDIO_INFOFRAME_DB1CC
;
cea
->
db1_ct_cc
|=
CEA861_AUDIO_INFOFRAME_DB1CT_FROM_STREAM
;
cea
->
db2_sf_ss
=
CEA861_AUDIO_INFOFRAME_DB2SF_FROM_STREAM
;
cea
->
db2_sf_ss
|=
CEA861_AUDIO_INFOFRAME_DB2SS_FROM_STREAM
;
cea
->
db3
=
0
;
/* not used, all zeros */
/*
* The OMAP HDMI IP requires to use the 8-channel channel code when
* transmitting more than two channels.
*/
if
(
params_channels
(
params
)
==
2
)
cea
->
db4_ca
=
0x0
;
else
cea
->
db4_ca
=
0x13
;
cea
->
db5_dminh_lsv
=
CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PROHIBITED
;
/* the expression is trivial but makes clear what we are doing */
cea
->
db5_dminh_lsv
|=
(
0
&
CEA861_AUDIO_INFOFRAME_DB5_LSV
);
priv
->
dss_audio
.
iec
=
iec
;
priv
->
dss_audio
.
cea
=
cea
;
err
=
priv
->
dssdev
->
driver
->
audio_config
(
priv
->
dssdev
,
&
priv
->
dss_audio
);
return
err
;
return
err
;
}
}
static
int
omap_hdmi_dai_trigger
(
struct
snd_pcm_substream
*
substream
,
int
cmd
,
struct
snd_soc_dai
*
dai
)
{
struct
hdmi_priv
*
priv
=
snd_soc_dai_get_drvdata
(
dai
);
int
err
=
0
;
switch
(
cmd
)
{
case
SNDRV_PCM_TRIGGER_START
:
case
SNDRV_PCM_TRIGGER_RESUME
:
case
SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
err
=
priv
->
dssdev
->
driver
->
audio_start
(
priv
->
dssdev
);
break
;
case
SNDRV_PCM_TRIGGER_STOP
:
case
SNDRV_PCM_TRIGGER_SUSPEND
:
case
SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
priv
->
dssdev
->
driver
->
audio_stop
(
priv
->
dssdev
);
break
;
default:
err
=
-
EINVAL
;
}
return
err
;
}
static
void
omap_hdmi_dai_shutdown
(
struct
snd_pcm_substream
*
substream
,
struct
snd_soc_dai
*
dai
)
{
struct
hdmi_priv
*
priv
=
snd_soc_dai_get_drvdata
(
dai
);
priv
->
dssdev
->
driver
->
audio_disable
(
priv
->
dssdev
);
}
static
const
struct
snd_soc_dai_ops
omap_hdmi_dai_ops
=
{
static
const
struct
snd_soc_dai_ops
omap_hdmi_dai_ops
=
{
.
startup
=
omap_hdmi_dai_startup
,
.
startup
=
omap_hdmi_dai_startup
,
.
hw_params
=
omap_hdmi_dai_hw_params
,
.
hw_params
=
omap_hdmi_dai_hw_params
,
.
prepare
=
omap_hdmi_dai_prepare
,
.
trigger
=
omap_hdmi_dai_trigger
,
.
shutdown
=
omap_hdmi_dai_shutdown
,
};
};
static
struct
snd_soc_dai_driver
omap_hdmi_dai
=
{
static
struct
snd_soc_dai_driver
omap_hdmi_dai
=
{
.
playback
=
{
.
playback
=
{
.
channels_min
=
2
,
.
channels_min
=
2
,
.
channels_max
=
2
,
.
channels_max
=
8
,
.
rates
=
OMAP_HDMI_RATES
,
.
rates
=
OMAP_HDMI_RATES
,
.
formats
=
OMAP_HDMI_FORMATS
,
.
formats
=
OMAP_HDMI_FORMATS
,
},
},
...
@@ -102,31 +264,77 @@ static __devinit int omap_hdmi_probe(struct platform_device *pdev)
...
@@ -102,31 +264,77 @@ static __devinit int omap_hdmi_probe(struct platform_device *pdev)
{
{
int
ret
;
int
ret
;
struct
resource
*
hdmi_rsrc
;
struct
resource
*
hdmi_rsrc
;
struct
hdmi_priv
*
hdmi_data
;
bool
hdmi_dev_found
=
false
;
hdmi_data
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
hdmi_data
),
GFP_KERNEL
);
if
(
hdmi_data
==
NULL
)
{
dev_err
(
&
pdev
->
dev
,
"Cannot allocate memory for HDMI data
\n
"
);
return
-
ENOMEM
;
}
hdmi_rsrc
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
hdmi_rsrc
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
hdmi_rsrc
)
{
if
(
!
hdmi_rsrc
)
{
dev_err
(
&
pdev
->
dev
,
"Cannot obtain IORESOURCE_MEM HDMI
\n
"
);
dev_err
(
&
pdev
->
dev
,
"Cannot obtain IORESOURCE_MEM HDMI
\n
"
);
return
-
E
INVAL
;
return
-
E
NODEV
;
}
}
omap_hdmi_dai_
dma_params
.
port_addr
=
hdmi_rsrc
->
start
hdmi_data
->
dma_params
.
port_addr
=
hdmi_rsrc
->
start
+
OMAP_HDMI_AUDIO_DMA_PORT
;
+
OMAP_HDMI_AUDIO_DMA_PORT
;
hdmi_rsrc
=
platform_get_resource
(
pdev
,
IORESOURCE_DMA
,
0
);
hdmi_rsrc
=
platform_get_resource
(
pdev
,
IORESOURCE_DMA
,
0
);
if
(
!
hdmi_rsrc
)
{
if
(
!
hdmi_rsrc
)
{
dev_err
(
&
pdev
->
dev
,
"Cannot obtain IORESOURCE_DMA HDMI
\n
"
);
dev_err
(
&
pdev
->
dev
,
"Cannot obtain IORESOURCE_DMA HDMI
\n
"
);
return
-
E
INVAL
;
return
-
E
NODEV
;
}
}
omap_hdmi_dai_dma_params
.
dma_req
=
hdmi_rsrc
->
start
;
hdmi_data
->
dma_params
.
dma_req
=
hdmi_rsrc
->
start
;
hdmi_data
->
dma_params
.
name
=
"HDMI playback"
;
hdmi_data
->
dma_params
.
sync_mode
=
OMAP_DMA_SYNC_PACKET
;
/*
* TODO: We assume that there is only one DSS HDMI device. Future
* OMAP implementations may support more than one HDMI devices and
* we should provided separate audio support for all of them.
*/
/* Find an HDMI device. */
for_each_dss_dev
(
hdmi_data
->
dssdev
)
{
omap_dss_get_device
(
hdmi_data
->
dssdev
);
if
(
!
hdmi_data
->
dssdev
->
driver
)
{
omap_dss_put_device
(
hdmi_data
->
dssdev
);
continue
;
}
if
(
hdmi_data
->
dssdev
->
type
==
OMAP_DISPLAY_TYPE_HDMI
)
{
hdmi_dev_found
=
true
;
break
;
}
}
if
(
!
hdmi_dev_found
)
{
dev_err
(
&
pdev
->
dev
,
"no driver for HDMI display found
\n
"
);
return
-
ENODEV
;
}
dev_set_drvdata
(
&
pdev
->
dev
,
hdmi_data
);
ret
=
snd_soc_register_dai
(
&
pdev
->
dev
,
&
omap_hdmi_dai
);
ret
=
snd_soc_register_dai
(
&
pdev
->
dev
,
&
omap_hdmi_dai
);
return
ret
;
return
ret
;
}
}
static
int
__devexit
omap_hdmi_remove
(
struct
platform_device
*
pdev
)
static
int
__devexit
omap_hdmi_remove
(
struct
platform_device
*
pdev
)
{
{
struct
hdmi_priv
*
hdmi_data
=
dev_get_drvdata
(
&
pdev
->
dev
);
snd_soc_unregister_dai
(
&
pdev
->
dev
);
snd_soc_unregister_dai
(
&
pdev
->
dev
);
if
(
hdmi_data
==
NULL
)
{
dev_err
(
&
pdev
->
dev
,
"cannot obtain HDMi data
\n
"
);
return
-
ENODEV
;
}
omap_dss_put_device
(
hdmi_data
->
dssdev
);
return
0
;
return
0
;
}
}
...
...
sound/soc/omap/omap-hdmi.h
View file @
599ed4b0
...
@@ -28,7 +28,9 @@
...
@@ -28,7 +28,9 @@
#define OMAP_HDMI_AUDIO_DMA_PORT 0x8c
#define OMAP_HDMI_AUDIO_DMA_PORT 0x8c
#define OMAP_HDMI_RATES (SNDRV_PCM_RATE_32000 | \
#define OMAP_HDMI_RATES (SNDRV_PCM_RATE_32000 | \
SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
#define OMAP_HDMI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
#define OMAP_HDMI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE)
SNDRV_PCM_FMTBIT_S24_LE)
...
...
sound/soc/omap/omap-mcbsp.c
View file @
599ed4b0
...
@@ -71,18 +71,17 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
...
@@ -71,18 +71,17 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
dma_data
=
snd_soc_dai_get_dma_data
(
rtd
->
cpu_dai
,
substream
);
dma_data
=
snd_soc_dai_get_dma_data
(
rtd
->
cpu_dai
,
substream
);
/* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
/*
if
(
mcbsp
->
dma_op_mode
==
MCBSP_DMA_MODE_THRESHOLD
)
* Configure McBSP threshold based on either:
/*
* packet_size, when the sDMA is in packet mode, or based on the
* Configure McBSP threshold based on either:
* period size in THRESHOLD mode, otherwise use McBSP threshold = 1
* packet_size, when the sDMA is in packet mode, or
* for mono streams.
* based on the period size.
*/
*/
if
(
dma_data
->
packet_size
)
if
(
dma_data
->
packet_size
)
words
=
dma_data
->
packet_size
;
words
=
dma_data
->
packet_size
;
else
if
(
mcbsp
->
dma_op_mode
==
MCBSP_DMA_MODE_THRESHOLD
)
else
words
=
snd_pcm_lib_period_bytes
(
substream
)
/
words
=
snd_pcm_lib_period_bytes
(
substream
)
/
(
mcbsp
->
wlen
/
8
);
(
mcbsp
->
wlen
/
8
);
else
else
words
=
1
;
words
=
1
;
...
@@ -139,13 +138,15 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
...
@@ -139,13 +138,15 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
if
(
mcbsp
->
pdata
->
buffer_size
)
{
if
(
mcbsp
->
pdata
->
buffer_size
)
{
/*
/*
* Rule for the buffer size. We should not allow
* Rule for the buffer size. We should not allow
* smaller buffer than the FIFO size to avoid underruns
* smaller buffer than the FIFO size to avoid underruns.
* This applies only for the playback stream.
*/
*/
snd_pcm_hw_rule_add
(
substream
->
runtime
,
0
,
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
SNDRV_PCM_HW_PARAM_BUFFER_SIZE
,
snd_pcm_hw_rule_add
(
substream
->
runtime
,
0
,
omap_mcbsp_hwrule_min_buffersize
,
SNDRV_PCM_HW_PARAM_BUFFER_SIZE
,
mcbsp
,
omap_mcbsp_hwrule_min_buffersize
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
-
1
);
mcbsp
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
-
1
);
/* Make sure, that the period size is always even */
/* Make sure, that the period size is always even */
snd_pcm_hw_constraint_step
(
substream
->
runtime
,
0
,
snd_pcm_hw_constraint_step
(
substream
->
runtime
,
0
,
...
@@ -230,6 +231,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
...
@@ -230,6 +231,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
unsigned
int
format
,
div
,
framesize
,
master
;
unsigned
int
format
,
div
,
framesize
,
master
;
dma_data
=
&
mcbsp
->
dma_data
[
substream
->
stream
];
dma_data
=
&
mcbsp
->
dma_data
[
substream
->
stream
];
channels
=
params_channels
(
params
);
switch
(
params_format
(
params
))
{
switch
(
params_format
(
params
))
{
case
SNDRV_PCM_FORMAT_S16_LE
:
case
SNDRV_PCM_FORMAT_S16_LE
:
...
@@ -245,7 +247,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
...
@@ -245,7 +247,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
}
}
if
(
mcbsp
->
pdata
->
buffer_size
)
{
if
(
mcbsp
->
pdata
->
buffer_size
)
{
dma_data
->
set_threshold
=
omap_mcbsp_set_threshold
;
dma_data
->
set_threshold
=
omap_mcbsp_set_threshold
;
/* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
if
(
mcbsp
->
dma_op_mode
==
MCBSP_DMA_MODE_THRESHOLD
)
{
if
(
mcbsp
->
dma_op_mode
==
MCBSP_DMA_MODE_THRESHOLD
)
{
int
period_words
,
max_thrsh
;
int
period_words
,
max_thrsh
;
...
@@ -283,6 +284,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
...
@@ -283,6 +284,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
}
else
{
}
else
{
sync_mode
=
OMAP_DMA_SYNC_FRAME
;
sync_mode
=
OMAP_DMA_SYNC_FRAME
;
}
}
}
else
if
(
channels
>
1
)
{
/* Use packet mode for non mono streams */
pkt_size
=
channels
;
sync_mode
=
OMAP_DMA_SYNC_PACKET
;
}
}
}
}
...
@@ -301,7 +306,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
...
@@ -301,7 +306,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
regs
->
rcr1
&=
~
(
RFRLEN1
(
0x7f
)
|
RWDLEN1
(
7
));
regs
->
rcr1
&=
~
(
RFRLEN1
(
0x7f
)
|
RWDLEN1
(
7
));
regs
->
xcr1
&=
~
(
XFRLEN1
(
0x7f
)
|
XWDLEN1
(
7
));
regs
->
xcr1
&=
~
(
XFRLEN1
(
0x7f
)
|
XWDLEN1
(
7
));
format
=
mcbsp
->
fmt
&
SND_SOC_DAIFMT_FORMAT_MASK
;
format
=
mcbsp
->
fmt
&
SND_SOC_DAIFMT_FORMAT_MASK
;
wpf
=
channels
=
params_channels
(
params
)
;
wpf
=
channels
;
if
(
channels
==
2
&&
(
format
==
SND_SOC_DAIFMT_I2S
||
if
(
channels
==
2
&&
(
format
==
SND_SOC_DAIFMT_I2S
||
format
==
SND_SOC_DAIFMT_LEFT_J
))
{
format
==
SND_SOC_DAIFMT_LEFT_J
))
{
/* Use dual-phase frames */
/* Use dual-phase frames */
...
...
sound/soc/omap/omap-mcpdm.c
View file @
599ed4b0
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
#include <linux/irq.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/pm_runtime.h>
#include <linux/of_device.h>
#include <sound/core.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm.h>
...
@@ -507,10 +508,17 @@ static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
...
@@ -507,10 +508,17 @@ static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
return
0
;
return
0
;
}
}
static
const
struct
of_device_id
omap_mcpdm_of_match
[]
=
{
{
.
compatible
=
"ti,omap4-mcpdm"
,
},
{
}
};
MODULE_DEVICE_TABLE
(
of
,
omap_mcpdm_of_match
);
static
struct
platform_driver
asoc_mcpdm_driver
=
{
static
struct
platform_driver
asoc_mcpdm_driver
=
{
.
driver
=
{
.
driver
=
{
.
name
=
"omap-mcpdm"
,
.
name
=
"omap-mcpdm"
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
omap_mcpdm_of_match
,
},
},
.
probe
=
asoc_mcpdm_probe
,
.
probe
=
asoc_mcpdm_probe
,
...
...
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