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
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