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
7471c5c9
Commit
7471c5c9
authored
Jan 02, 2014
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/dt' into asoc-next
parents
75aac820
dd41e0c4
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
221 additions
and
6 deletions
+221
-6
Documentation/devicetree/bindings/sound/simple-card.txt
Documentation/devicetree/bindings/sound/simple-card.txt
+68
-0
sound/soc/generic/simple-card.c
sound/soc/generic/simple-card.c
+153
-6
No files found.
Documentation/devicetree/bindings/sound/simple-card.txt
0 → 100644
View file @
7471c5c9
Simple-Card:
Simple-Card specifies audio DAI connection of SoC <-> codec.
Required properties:
- compatible : "simple-audio-card"
Optional properties:
- simple-audio-card,format : CPU/CODEC common audio format.
"i2s", "right_j", "left_j" , "dsp_a"
"dsp_b", "ac97", "pdm", "msb", "lsb"
Required subnodes:
- simple-audio-card,cpu : CPU sub-node
- simple-audio-card,codec : CODEC sub-node
Required CPU/CODEC subnodes properties:
- sound-dai : phandle and port of CPU/CODEC
Optional CPU/CODEC subnodes properties:
- format : CPU/CODEC specific audio format if needed.
see simple-audio-card,format
- frame-master : bool property. add this if subnode is frame master
- bitclock-master : bool property. add this if subnode is bitclock master
- bitclock-inversion : bool property. add this if subnode has clock inversion
- frame-inversion : bool property. add this if subnode has frame inversion
- clocks / system-clock-frequency : specify subnode's clock if needed.
it can be specified via "clocks" if system has
clock node (= common clock), or "system-clock-frequency"
(if system doens't support common clock)
Example:
sound {
compatible = "simple-audio-card";
simple-audio-card,format = "left_j";
simple-audio-card,cpu {
sound-dai = <&sh_fsi2 0>;
};
simple-audio-card,codec {
sound-dai = <&ak4648>;
bitclock-master;
frame-master;
clocks = <&osc>;
};
};
&i2c0 {
ak4648: ak4648@12 {
#sound-dai-cells = <0>;
compatible = "asahi-kasei,ak4648";
reg = <0x12>;
};
};
sh_fsi2: sh_fsi2@ec230000 {
#sound-dai-cells = <1>;
compatible = "renesas,sh_fsi2";
reg = <0xec230000 0x400>;
interrupt-parent = <&gic>;
interrupts = <0 146 0x4>;
};
sound/soc/generic/simple-card.c
View file @
7471c5c9
...
@@ -8,7 +8,8 @@
...
@@ -8,7 +8,8 @@
* it under the terms of the GNU General Public License version 2 as
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
* published by the Free Software Foundation.
*/
*/
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/module.h>
#include <sound/simple_card.h>
#include <sound/simple_card.h>
...
@@ -57,11 +58,147 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -57,11 +58,147 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
return
0
;
return
0
;
}
}
static
int
asoc_simple_card_sub_parse_of
(
struct
device_node
*
np
,
struct
asoc_simple_dai
*
dai
,
struct
device_node
**
node
)
{
struct
clk
*
clk
;
int
ret
;
/*
* get node via "sound-dai = <&phandle port>"
* it will be used as xxx_of_node on soc_bind_dai_link()
*/
*
node
=
of_parse_phandle
(
np
,
"sound-dai"
,
0
);
if
(
!*
node
)
return
-
ENODEV
;
/* get dai->name */
ret
=
snd_soc_of_get_dai_name
(
np
,
&
dai
->
name
);
if
(
ret
<
0
)
goto
parse_error
;
/*
* bitclock-inversion, frame-inversion
* bitclock-master, frame-master
* and specific "format" if it has
*/
dai
->
fmt
=
snd_soc_of_parse_daifmt
(
np
,
NULL
);
/*
* dai->sysclk come from
* "clocks = <&xxx>" (if system has common clock)
* or "system-clock-frequency = <xxx>"
*/
clk
=
of_clk_get
(
np
,
0
);
if
(
IS_ERR
(
clk
))
of_property_read_u32
(
np
,
"system-clock-frequency"
,
&
dai
->
sysclk
);
else
dai
->
sysclk
=
clk_get_rate
(
clk
);
ret
=
0
;
parse_error:
of_node_put
(
*
node
);
return
ret
;
}
static
int
asoc_simple_card_parse_of
(
struct
device_node
*
node
,
struct
asoc_simple_card_info
*
info
,
struct
device
*
dev
,
struct
device_node
**
of_cpu
,
struct
device_node
**
of_codec
,
struct
device_node
**
of_platform
)
{
struct
device_node
*
np
;
char
*
name
;
int
ret
=
0
;
/* get CPU/CODEC common format via simple-audio-card,format */
info
->
daifmt
=
snd_soc_of_parse_daifmt
(
node
,
"simple-audio-card,"
)
&
(
SND_SOC_DAIFMT_FORMAT_MASK
|
SND_SOC_DAIFMT_INV_MASK
);
/* CPU sub-node */
ret
=
-
EINVAL
;
np
=
of_get_child_by_name
(
node
,
"simple-audio-card,cpu"
);
if
(
np
)
ret
=
asoc_simple_card_sub_parse_of
(
np
,
&
info
->
cpu_dai
,
of_cpu
);
if
(
ret
<
0
)
return
ret
;
/* CODEC sub-node */
ret
=
-
EINVAL
;
np
=
of_get_child_by_name
(
node
,
"simple-audio-card,codec"
);
if
(
np
)
ret
=
asoc_simple_card_sub_parse_of
(
np
,
&
info
->
codec_dai
,
of_codec
);
if
(
ret
<
0
)
return
ret
;
if
(
!
info
->
cpu_dai
.
name
||
!
info
->
codec_dai
.
name
)
return
-
EINVAL
;
/* card name is created from CPU/CODEC dai name */
name
=
devm_kzalloc
(
dev
,
strlen
(
info
->
cpu_dai
.
name
)
+
strlen
(
info
->
codec_dai
.
name
)
+
2
,
GFP_KERNEL
);
sprintf
(
name
,
"%s-%s"
,
info
->
cpu_dai
.
name
,
info
->
codec_dai
.
name
);
info
->
name
=
info
->
card
=
name
;
/* simple-card assumes platform == cpu */
*
of_platform
=
*
of_cpu
;
dev_dbg
(
dev
,
"card-name : %s
\n
"
,
info
->
card
);
dev_dbg
(
dev
,
"platform : %04x
\n
"
,
info
->
daifmt
);
dev_dbg
(
dev
,
"cpu : %s / %04x / %d
\n
"
,
info
->
cpu_dai
.
name
,
info
->
cpu_dai
.
fmt
,
info
->
cpu_dai
.
sysclk
);
dev_dbg
(
dev
,
"codec : %s / %04x / %d
\n
"
,
info
->
codec_dai
.
name
,
info
->
codec_dai
.
fmt
,
info
->
codec_dai
.
sysclk
);
return
0
;
}
static
int
asoc_simple_card_probe
(
struct
platform_device
*
pdev
)
static
int
asoc_simple_card_probe
(
struct
platform_device
*
pdev
)
{
{
struct
asoc_simple_card_info
*
cinfo
=
pdev
->
dev
.
platform_data
;
struct
asoc_simple_card_info
*
cinfo
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
device_node
*
of_cpu
,
*
of_codec
,
*
of_platform
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
device
*
dev
=
&
pdev
->
dev
;
cinfo
=
NULL
;
of_cpu
=
NULL
;
of_codec
=
NULL
;
of_platform
=
NULL
;
if
(
np
&&
of_device_is_available
(
np
))
{
cinfo
=
devm_kzalloc
(
dev
,
sizeof
(
*
cinfo
),
GFP_KERNEL
);
if
(
cinfo
)
{
int
ret
;
ret
=
asoc_simple_card_parse_of
(
np
,
cinfo
,
dev
,
&
of_cpu
,
&
of_codec
,
&
of_platform
);
if
(
ret
<
0
)
{
if
(
ret
!=
-
EPROBE_DEFER
)
dev_err
(
dev
,
"parse error %d
\n
"
,
ret
);
return
ret
;
}
}
}
else
{
cinfo
=
pdev
->
dev
.
platform_data
;
}
if
(
!
cinfo
)
{
if
(
!
cinfo
)
{
dev_err
(
dev
,
"no info for asoc-simple-card
\n
"
);
dev_err
(
dev
,
"no info for asoc-simple-card
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -69,10 +206,10 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
...
@@ -69,10 +206,10 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
if
(
!
cinfo
->
name
||
if
(
!
cinfo
->
name
||
!
cinfo
->
card
||
!
cinfo
->
card
||
!
cinfo
->
codec
||
!
cinfo
->
codec
_dai
.
name
||
!
cinfo
->
platform
||
!
(
cinfo
->
codec
||
of_codec
)
||
!
cinfo
->
cpu_dai
.
name
||
!
(
cinfo
->
platform
||
of_platform
)
||
!
cinfo
->
codec_dai
.
name
)
{
!
(
cinfo
->
cpu_dai
.
name
||
of_cpu
)
)
{
dev_err
(
dev
,
"insufficient asoc_simple_card_info settings
\n
"
);
dev_err
(
dev
,
"insufficient asoc_simple_card_info settings
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -86,6 +223,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
...
@@ -86,6 +223,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
cinfo
->
snd_link
.
platform_name
=
cinfo
->
platform
;
cinfo
->
snd_link
.
platform_name
=
cinfo
->
platform
;
cinfo
->
snd_link
.
codec_name
=
cinfo
->
codec
;
cinfo
->
snd_link
.
codec_name
=
cinfo
->
codec
;
cinfo
->
snd_link
.
codec_dai_name
=
cinfo
->
codec_dai
.
name
;
cinfo
->
snd_link
.
codec_dai_name
=
cinfo
->
codec_dai
.
name
;
cinfo
->
snd_link
.
cpu_of_node
=
of_cpu
;
cinfo
->
snd_link
.
codec_of_node
=
of_codec
;
cinfo
->
snd_link
.
platform_of_node
=
of_platform
;
cinfo
->
snd_link
.
init
=
asoc_simple_card_dai_init
;
cinfo
->
snd_link
.
init
=
asoc_simple_card_dai_init
;
/*
/*
...
@@ -107,10 +247,17 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
...
@@ -107,10 +247,17 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
return
snd_soc_unregister_card
(
&
cinfo
->
snd_card
);
return
snd_soc_unregister_card
(
&
cinfo
->
snd_card
);
}
}
static
const
struct
of_device_id
asoc_simple_of_match
[]
=
{
{
.
compatible
=
"simple-audio-card"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
asoc_simple_of_match
);
static
struct
platform_driver
asoc_simple_card
=
{
static
struct
platform_driver
asoc_simple_card
=
{
.
driver
=
{
.
driver
=
{
.
name
=
"asoc-simple-card"
,
.
name
=
"asoc-simple-card"
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
asoc_simple_of_match
,
},
},
.
probe
=
asoc_simple_card_probe
,
.
probe
=
asoc_simple_card_probe
,
.
remove
=
asoc_simple_card_remove
,
.
remove
=
asoc_simple_card_remove
,
...
...
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