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
ca9e54c6
Commit
ca9e54c6
authored
Mar 23, 2014
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next
parents
980aac20
90e8e50f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
334 additions
and
3 deletions
+334
-3
Documentation/devicetree/bindings/sound/renesas,rsnd.txt
Documentation/devicetree/bindings/sound/renesas,rsnd.txt
+96
-0
sound/soc/sh/rcar/adg.c
sound/soc/sh/rcar/adg.c
+1
-0
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/core.c
+119
-3
sound/soc/sh/rcar/gen.c
sound/soc/sh/rcar/gen.c
+15
-0
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/rsnd.h
+11
-0
sound/soc/sh/rcar/src.c
sound/soc/sh/rcar/src.c
+36
-0
sound/soc/sh/rcar/ssi.c
sound/soc/sh/rcar/ssi.c
+56
-0
No files found.
Documentation/devicetree/bindings/sound/renesas,rsnd.txt
0 → 100644
View file @
ca9e54c6
Renesas R-Car sound
Required properties:
- compatible : "renesas,rcar_sound-gen1" if generation1
"renesas,rcar_sound-gen2" if generation2
- reg : Should contain the register physical address.
required register is
SRU/ADG/SSI if generation1
SRU/ADG/SSIU/SSI if generation2
- rcar_sound,ssi : SSI subnode
- rcar_sound,scu : SCU subnode
- rcar_sound,dai : DAI subnode
SSI subnode properties:
- interrupts : Should contain SSI interrupt for PIO transfer
- shared-pin : if shared clock pin
DAI subnode properties:
- playback : list of playback modules
- capture : list of capture modules
Example:
rcar_sound: rcar_sound@0xffd90000 {
#sound-dai-cells = <1>;
compatible = "renesas,rcar_sound-gen2";
reg = <0 0xec500000 0 0x1000>, /* SCU */
<0 0xec5a0000 0 0x100>, /* ADG */
<0 0xec540000 0 0x1000>, /* SSIU */
<0 0xec541000 0 0x1280>; /* SSI */
rcar_sound,src {
src0: src@0 { };
src1: src@1 { };
src2: src@2 { };
src3: src@3 { };
src4: src@4 { };
src5: src@5 { };
src6: src@6 { };
src7: src@7 { };
src8: src@8 { };
src9: src@9 { };
};
rcar_sound,ssi {
ssi0: ssi@0 {
interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>;
};
ssi1: ssi@1 {
interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>;
};
ssi2: ssi@2 {
interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>;
};
ssi3: ssi@3 {
interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>;
};
ssi4: ssi@4 {
interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>;
};
ssi5: ssi@5 {
interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>;
};
ssi6: ssi@6 {
interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>;
};
ssi7: ssi@7 {
interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>;
};
ssi8: ssi@8 {
interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>;
};
ssi9: ssi@9 {
interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>;
};
};
rcar_sound,dai {
dai0 {
playback = <&ssi5 &src5>;
capture = <&ssi6>;
};
dai1 {
playback = <&ssi3>;
};
dai2 {
capture = <&ssi4>;
};
dai3 {
playback = <&ssi7>;
};
dai4 {
capture = <&ssi8>;
};
};
};
sound/soc/sh/rcar/adg.c
View file @
ca9e54c6
...
...
@@ -392,6 +392,7 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
}
int
rsnd_adg_probe
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
)
{
struct
rsnd_adg
*
adg
;
...
...
sound/soc/sh/rcar/core.c
View file @
ca9e54c6
...
...
@@ -100,6 +100,21 @@
#define RSND_RATES SNDRV_PCM_RATE_8000_96000
#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
static
struct
rsnd_of_data
rsnd_of_data_gen1
=
{
.
flags
=
RSND_GEN1
,
};
static
struct
rsnd_of_data
rsnd_of_data_gen2
=
{
.
flags
=
RSND_GEN2
,
};
static
struct
of_device_id
rsnd_of_match
[]
=
{
{
.
compatible
=
"renesas,rcar_sound-gen1"
,
.
data
=
&
rsnd_of_data_gen1
},
{
.
compatible
=
"renesas,rcar_sound-gen2"
,
.
data
=
&
rsnd_of_data_gen2
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
rsnd_of_match
);
/*
* rsnd_platform functions
*/
...
...
@@ -620,7 +635,92 @@ static int rsnd_path_init(struct rsnd_priv *priv,
return
ret
;
}
static
void
rsnd_of_parse_dai
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
)
{
struct
device_node
*
dai_node
,
*
dai_np
;
struct
device_node
*
ssi_node
,
*
ssi_np
;
struct
device_node
*
src_node
,
*
src_np
;
struct
device_node
*
playback
,
*
capture
;
struct
rsnd_dai_platform_info
*
dai_info
;
struct
rcar_snd_info
*
info
=
rsnd_priv_to_info
(
priv
);
struct
device
*
dev
=
&
pdev
->
dev
;
int
nr
,
i
;
int
dai_i
,
ssi_i
,
src_i
;
if
(
!
of_data
)
return
;
dai_node
=
of_get_child_by_name
(
dev
->
of_node
,
"rcar_sound,dai"
);
if
(
!
dai_node
)
return
;
nr
=
of_get_child_count
(
dai_node
);
if
(
!
nr
)
return
;
dai_info
=
devm_kzalloc
(
dev
,
sizeof
(
struct
rsnd_dai_platform_info
)
*
nr
,
GFP_KERNEL
);
if
(
!
dai_info
)
{
dev_err
(
dev
,
"dai info allocation error
\n
"
);
return
;
}
info
->
dai_info_nr
=
nr
;
info
->
dai_info
=
dai_info
;
ssi_node
=
of_get_child_by_name
(
dev
->
of_node
,
"rcar_sound,ssi"
);
src_node
=
of_get_child_by_name
(
dev
->
of_node
,
"rcar_sound,src"
);
#define mod_parse(name) \
if (name##_node) { \
struct rsnd_##name##_platform_info *name##_info; \
\
name##_i = 0; \
for_each_child_of_node(name##_node, name##_np) { \
name##_info = info->name##_info + name##_i; \
\
if (name##_np == playback) \
dai_info->playback.name = name##_info; \
if (name##_np == capture) \
dai_info->capture.name = name##_info; \
\
name##_i++; \
} \
}
/*
* parse all dai
*/
dai_i
=
0
;
for_each_child_of_node
(
dai_node
,
dai_np
)
{
dai_info
=
info
->
dai_info
+
dai_i
;
for
(
i
=
0
;;
i
++
)
{
playback
=
of_parse_phandle
(
dai_np
,
"playback"
,
i
);
capture
=
of_parse_phandle
(
dai_np
,
"capture"
,
i
);
if
(
!
playback
&&
!
capture
)
break
;
mod_parse
(
ssi
);
mod_parse
(
src
);
if
(
playback
)
of_node_put
(
playback
);
if
(
capture
)
of_node_put
(
capture
);
}
dai_i
++
;
}
}
static
int
rsnd_dai_probe
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
)
{
struct
snd_soc_dai_driver
*
drv
;
...
...
@@ -628,13 +728,16 @@ static int rsnd_dai_probe(struct platform_device *pdev,
struct
rsnd_dai
*
rdai
;
struct
rsnd_mod
*
pmod
,
*
cmod
;
struct
device
*
dev
=
rsnd_priv_to_dev
(
priv
);
int
dai_nr
=
info
->
dai_info_nr
;
int
dai_nr
;
int
i
;
rsnd_of_parse_dai
(
pdev
,
of_data
,
priv
);
/*
* dai_nr should be set via dai_info_nr,
* but allow it to keeping compatible
*/
dai_nr
=
info
->
dai_info_nr
;
if
(
!
dai_nr
)
{
/* get max dai nr */
for
(
dai_nr
=
0
;
dai_nr
<
32
;
dai_nr
++
)
{
...
...
@@ -802,7 +905,10 @@ static int rsnd_probe(struct platform_device *pdev)
struct
rsnd_priv
*
priv
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
rsnd_dai
*
rdai
;
const
struct
of_device_id
*
of_id
=
of_match_device
(
rsnd_of_match
,
dev
);
const
struct
rsnd_of_data
*
of_data
;
int
(
*
probe_func
[])(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
)
=
{
rsnd_gen_probe
,
rsnd_ssi_probe
,
...
...
@@ -812,7 +918,16 @@ static int rsnd_probe(struct platform_device *pdev)
};
int
ret
,
i
;
info
=
pdev
->
dev
.
platform_data
;
info
=
NULL
;
of_data
=
NULL
;
if
(
of_id
)
{
info
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
rcar_snd_info
),
GFP_KERNEL
);
of_data
=
of_id
->
data
;
}
else
{
info
=
pdev
->
dev
.
platform_data
;
}
if
(
!
info
)
{
dev_err
(
dev
,
"driver needs R-Car sound information
\n
"
);
return
-
ENODEV
;
...
...
@@ -835,7 +950,7 @@ static int rsnd_probe(struct platform_device *pdev)
* init each module
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
probe_func
);
i
++
)
{
ret
=
probe_func
[
i
](
pdev
,
priv
);
ret
=
probe_func
[
i
](
pdev
,
of_data
,
priv
);
if
(
ret
)
return
ret
;
}
...
...
@@ -903,6 +1018,7 @@ static int rsnd_remove(struct platform_device *pdev)
static
struct
platform_driver
rsnd_driver
=
{
.
driver
=
{
.
name
=
"rcar_sound"
,
.
of_match_table
=
rsnd_of_match
,
},
.
probe
=
rsnd_probe
,
.
remove
=
rsnd_remove
,
...
...
sound/soc/sh/rcar/gen.c
View file @
ca9e54c6
...
...
@@ -359,13 +359,28 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
/*
* Gen
*/
static
void
rsnd_of_parse_gen
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
)
{
struct
rcar_snd_info
*
info
=
priv
->
info
;
if
(
!
of_data
)
return
;
info
->
flags
=
of_data
->
flags
;
}
int
rsnd_gen_probe
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
)
{
struct
device
*
dev
=
rsnd_priv_to_dev
(
priv
);
struct
rsnd_gen
*
gen
;
int
ret
;
rsnd_of_parse_gen
(
pdev
,
of_data
,
priv
);
gen
=
devm_kzalloc
(
dev
,
sizeof
(
*
gen
),
GFP_KERNEL
);
if
(
!
gen
)
{
dev_err
(
dev
,
"GEN allocate failed
\n
"
);
...
...
sound/soc/sh/rcar/rsnd.h
View file @
ca9e54c6
...
...
@@ -17,6 +17,8 @@
#include <linux/io.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/sh_dma.h>
#include <linux/workqueue.h>
#include <sound/rcar_snd.h>
...
...
@@ -113,6 +115,7 @@ enum rsnd_reg {
#define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18
#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19
struct
rsnd_of_data
;
struct
rsnd_priv
;
struct
rsnd_mod
;
struct
rsnd_dai
;
...
...
@@ -260,6 +263,7 @@ int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
* R-Car Gen1/Gen2
*/
int
rsnd_gen_probe
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
);
void
__iomem
*
rsnd_gen_reg_get
(
struct
rsnd_priv
*
priv
,
struct
rsnd_mod
*
mod
,
...
...
@@ -273,6 +277,7 @@ void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
int
rsnd_adg_ssi_clk_stop
(
struct
rsnd_mod
*
mod
);
int
rsnd_adg_ssi_clk_try_start
(
struct
rsnd_mod
*
mod
,
unsigned
int
rate
);
int
rsnd_adg_probe
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
);
int
rsnd_adg_set_convert_clk_gen1
(
struct
rsnd_priv
*
priv
,
struct
rsnd_mod
*
mod
,
...
...
@@ -290,6 +295,10 @@ int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
/*
* R-Car sound priv
*/
struct
rsnd_of_data
{
u32
flags
;
};
struct
rsnd_priv
{
struct
device
*
dev
;
...
...
@@ -348,6 +357,7 @@ struct rsnd_priv {
* R-Car SRC
*/
int
rsnd_src_probe
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
);
struct
rsnd_mod
*
rsnd_src_mod_get
(
struct
rsnd_priv
*
priv
,
int
id
);
unsigned
int
rsnd_src_get_ssi_rate
(
struct
rsnd_priv
*
priv
,
...
...
@@ -366,6 +376,7 @@ int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
* R-Car SSI
*/
int
rsnd_ssi_probe
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
);
struct
rsnd_mod
*
rsnd_ssi_mod_get
(
struct
rsnd_priv
*
priv
,
int
id
);
struct
rsnd_mod
*
rsnd_ssi_mod_get_frm_dai
(
struct
rsnd_priv
*
priv
,
...
...
sound/soc/sh/rcar/src.c
View file @
ca9e54c6
...
...
@@ -628,7 +628,41 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
return
&
((
struct
rsnd_src
*
)(
priv
->
src
)
+
id
)
->
mod
;
}
static
void
rsnd_of_parse_src
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
)
{
struct
device_node
*
src_node
;
struct
rcar_snd_info
*
info
=
rsnd_priv_to_info
(
priv
);
struct
rsnd_src_platform_info
*
src_info
;
struct
device
*
dev
=
&
pdev
->
dev
;
int
nr
;
if
(
!
of_data
)
return
;
src_node
=
of_get_child_by_name
(
dev
->
of_node
,
"rcar_sound,src"
);
if
(
!
src_node
)
return
;
nr
=
of_get_child_count
(
src_node
);
if
(
!
nr
)
return
;
src_info
=
devm_kzalloc
(
dev
,
sizeof
(
struct
rsnd_src_platform_info
)
*
nr
,
GFP_KERNEL
);
if
(
!
src_info
)
{
dev_err
(
dev
,
"src info allocation error
\n
"
);
return
;
}
info
->
src_info
=
src_info
;
info
->
src_info_nr
=
nr
;
}
int
rsnd_src_probe
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
)
{
struct
rcar_snd_info
*
info
=
rsnd_priv_to_info
(
priv
);
...
...
@@ -639,6 +673,8 @@ int rsnd_src_probe(struct platform_device *pdev,
char
name
[
RSND_SRC_NAME_SIZE
];
int
i
,
nr
;
rsnd_of_parse_src
(
pdev
,
of_data
,
priv
);
/*
* init SRC
*/
...
...
sound/soc/sh/rcar/ssi.c
View file @
ca9e54c6
...
...
@@ -588,7 +588,61 @@ static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *s
}
}
static
void
rsnd_of_parse_ssi
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
)
{
struct
device_node
*
node
;
struct
device_node
*
np
;
struct
rsnd_ssi_platform_info
*
ssi_info
;
struct
rcar_snd_info
*
info
=
rsnd_priv_to_info
(
priv
);
struct
device
*
dev
=
&
pdev
->
dev
;
int
nr
,
i
;
if
(
!
of_data
)
return
;
node
=
of_get_child_by_name
(
dev
->
of_node
,
"rcar_sound,ssi"
);
if
(
!
node
)
return
;
nr
=
of_get_child_count
(
node
);
if
(
!
nr
)
return
;
ssi_info
=
devm_kzalloc
(
dev
,
sizeof
(
struct
rsnd_ssi_platform_info
)
*
nr
,
GFP_KERNEL
);
if
(
!
ssi_info
)
{
dev_err
(
dev
,
"ssi info allocation error
\n
"
);
return
;
}
info
->
ssi_info
=
ssi_info
;
info
->
ssi_info_nr
=
nr
;
i
=
-
1
;
for_each_child_of_node
(
node
,
np
)
{
i
++
;
ssi_info
=
info
->
ssi_info
+
i
;
/*
* pin settings
*/
if
(
of_get_property
(
np
,
"shared-pin"
,
NULL
))
ssi_info
->
flags
|=
RSND_SSI_CLK_PIN_SHARE
;
/*
* irq
*/
ssi_info
->
pio_irq
=
irq_of_parse_and_map
(
np
,
0
);
}
}
int
rsnd_ssi_probe
(
struct
platform_device
*
pdev
,
const
struct
rsnd_of_data
*
of_data
,
struct
rsnd_priv
*
priv
)
{
struct
rcar_snd_info
*
info
=
rsnd_priv_to_info
(
priv
);
...
...
@@ -600,6 +654,8 @@ int rsnd_ssi_probe(struct platform_device *pdev,
char
name
[
RSND_SSI_NAME_SIZE
];
int
i
,
nr
;
rsnd_of_parse_ssi
(
pdev
,
of_data
,
priv
);
/*
* init SSI
*/
...
...
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