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
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
Show 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 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <sound/simple_card.h>
...
...
@@ -57,11 +58,147 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
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
)
{
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
;
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
)
{
dev_err
(
dev
,
"no info for asoc-simple-card
\n
"
);
return
-
EINVAL
;
...
...
@@ -69,10 +206,10 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
if
(
!
cinfo
->
name
||
!
cinfo
->
card
||
!
cinfo
->
codec
||
!
cinfo
->
platform
||
!
cinfo
->
cpu_dai
.
name
||
!
cinfo
->
codec_dai
.
name
)
{
!
cinfo
->
codec
_dai
.
name
||
!
(
cinfo
->
codec
||
of_codec
)
||
!
(
cinfo
->
platform
||
of_platform
)
||
!
(
cinfo
->
cpu_dai
.
name
||
of_cpu
)
)
{
dev_err
(
dev
,
"insufficient asoc_simple_card_info settings
\n
"
);
return
-
EINVAL
;
}
...
...
@@ -86,6 +223,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
cinfo
->
snd_link
.
platform_name
=
cinfo
->
platform
;
cinfo
->
snd_link
.
codec_name
=
cinfo
->
codec
;
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
;
/*
...
...
@@ -107,10 +247,17 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
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
=
{
.
driver
=
{
.
name
=
"asoc-simple-card"
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
asoc_simple_of_match
,
},
.
probe
=
asoc_simple_card_probe
,
.
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