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
f904f846
Commit
f904f846
authored
Nov 10, 2017
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next
parents
1cae4146
c409c2a9
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
403 additions
and
190 deletions
+403
-190
Documentation/devicetree/bindings/sound/audio-graph-scu-card.txt
...tation/devicetree/bindings/sound/audio-graph-scu-card.txt
+3
-2
sound/soc/sh/rcar/adg.c
sound/soc/sh/rcar/adg.c
+47
-25
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/core.c
+35
-16
sound/soc/sh/rcar/ctu.c
sound/soc/sh/rcar/ctu.c
+48
-40
sound/soc/sh/rcar/dma.c
sound/soc/sh/rcar/dma.c
+50
-34
sound/soc/sh/rcar/dvc.c
sound/soc/sh/rcar/dvc.c
+22
-38
sound/soc/sh/rcar/mix.c
sound/soc/sh/rcar/mix.c
+152
-6
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/rsnd.h
+17
-5
sound/soc/sh/rcar/ssi.c
sound/soc/sh/rcar/ssi.c
+29
-24
No files found.
Documentation/devicetree/bindings/sound/audio-graph-scu-card.txt
View file @
f904f846
...
...
@@ -43,7 +43,7 @@ Example 1. Sampling Rate Conversion
label = "sound-card";
prefix = "codec";
routing = "codec Playback", "DAI0 Playback",
"codec Playback", "DAI1 Playback
";
"DAI0 Capture", "codec Capture
";
convert-rate = <48000>;
dais = <&cpu_port>;
...
...
@@ -79,7 +79,8 @@ Example 2. 2 CPU 1 Codec (Mixing)
label = "sound-card";
prefix = "codec";
routing = "codec Playback", "DAI0 Playback",
"codec Playback", "DAI1 Playback";
"codec Playback", "DAI1 Playback",
"DAI0 Capture", "codec Capture";
convert-rate = <48000>;
dais = <&cpu_port0
...
...
sound/soc/sh/rcar/adg.c
View file @
f904f846
...
...
@@ -44,7 +44,6 @@ struct rsnd_adg {
#define LRCLK_ASYNC (1 << 0)
#define AUDIO_OUT_48 (1 << 1)
#define adg_mode_flags(adg) (adg->flags)
#define for_each_rsnd_clk(pos, adg, i) \
for (i = 0; \
...
...
@@ -58,6 +57,13 @@ struct rsnd_adg {
i++)
#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
static
const
char
*
const
clk_name
[]
=
{
[
CLKA
]
=
"clk_a"
,
[
CLKB
]
=
"clk_b"
,
[
CLKC
]
=
"clk_c"
,
[
CLKI
]
=
"clk_i"
,
};
static
u32
rsnd_adg_calculate_rbgx
(
unsigned
long
div
)
{
int
i
,
ratio
;
...
...
@@ -280,6 +286,7 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
struct
rsnd_priv
*
priv
=
rsnd_mod_to_priv
(
ssi_mod
);
struct
rsnd_adg
*
adg
=
rsnd_priv_to_adg
(
priv
);
struct
rsnd_mod
*
adg_mod
=
rsnd_mod_get
(
adg
);
struct
device
*
dev
=
rsnd_priv_to_dev
(
priv
);
int
id
=
rsnd_mod_id
(
ssi_mod
);
int
shift
=
(
id
%
4
)
*
8
;
u32
mask
=
0xFF
<<
shift
;
...
...
@@ -306,12 +313,13 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
rsnd_mod_bset
(
adg_mod
,
AUDIO_CLK_SEL2
,
mask
,
val
);
break
;
}
dev_dbg
(
dev
,
"AUDIO_CLK_SEL is 0x%x
\n
"
,
val
);
}
int
rsnd_adg_clk_query
(
struct
rsnd_priv
*
priv
,
unsigned
int
rate
)
{
struct
rsnd_adg
*
adg
=
rsnd_priv_to_adg
(
priv
);
struct
device
*
dev
=
rsnd_priv_to_dev
(
priv
);
struct
clk
*
clk
;
int
i
;
int
sel_table
[]
=
{
...
...
@@ -321,8 +329,6 @@ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
[
CLKI
]
=
0x0
,
};
dev_dbg
(
dev
,
"request clock = %d
\n
"
,
rate
);
/*
* find suitable clock from
* AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
...
...
@@ -366,8 +372,8 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
rsnd_adg_set_ssi_clk
(
ssi_mod
,
data
);
if
(
adg_mode_flags
(
adg
)
&
LRCLK_ASYNC
)
{
if
(
adg_mode_flags
(
adg
)
&
AUDIO_OUT_48
)
if
(
rsnd_flags_has
(
adg
,
LRCLK_ASYNC
)
)
{
if
(
rsnd_flags_has
(
adg
,
AUDIO_OUT_48
)
)
ckr
=
0x80000000
;
}
else
{
if
(
0
==
(
rate
%
8000
))
...
...
@@ -378,9 +384,10 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
rsnd_mod_write
(
adg_mod
,
BRRA
,
adg
->
rbga
);
rsnd_mod_write
(
adg_mod
,
BRRB
,
adg
->
rbgb
);
dev_dbg
(
dev
,
"ADG: %s[%d] selects 0x%x for %d
\n
"
,
rsnd_mod_name
(
ssi_mod
),
rsnd_mod_id
(
ssi_mod
),
data
,
rate
);
dev_dbg
(
dev
,
"CLKOUT is based on BRG%c (= %dHz)
\n
"
,
(
ckr
)
?
'B'
:
'A'
,
(
ckr
)
?
adg
->
rbgb_rate_for_48khz
:
adg
->
rbga_rate_for_441khz
);
return
0
;
}
...
...
@@ -409,21 +416,12 @@ static void rsnd_adg_get_clkin(struct rsnd_priv *priv,
{
struct
device
*
dev
=
rsnd_priv_to_dev
(
priv
);
struct
clk
*
clk
;
static
const
char
*
const
clk_name
[]
=
{
[
CLKA
]
=
"clk_a"
,
[
CLKB
]
=
"clk_b"
,
[
CLKC
]
=
"clk_c"
,
[
CLKI
]
=
"clk_i"
,
};
int
i
;
for
(
i
=
0
;
i
<
CLKMAX
;
i
++
)
{
clk
=
devm_clk_get
(
dev
,
clk_name
[
i
]);
adg
->
clk
[
i
]
=
IS_ERR
(
clk
)
?
NULL
:
clk
;
}
for_each_rsnd_clk
(
clk
,
adg
,
i
)
dev_dbg
(
dev
,
"clk %d : %p : %ld
\n
"
,
i
,
clk
,
clk_get_rate
(
clk
));
}
static
void
rsnd_adg_get_clkout
(
struct
rsnd_priv
*
priv
,
...
...
@@ -479,10 +477,10 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
}
if
(
req_rate
[
0
]
%
48000
==
0
)
adg
->
flags
|=
AUDIO_OUT_48
;
rsnd_flags_set
(
adg
,
AUDIO_OUT_48
)
;
if
(
of_get_property
(
np
,
"clkout-lr-asynchronous"
,
NULL
))
adg
->
flags
|=
LRCLK_ASYNC
;
rsnd_flags_set
(
adg
,
LRCLK_ASYNC
)
;
/*
* This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
...
...
@@ -512,7 +510,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
adg
->
rbga_rate_for_441khz
=
rate
/
div
;
ckr
|=
brg_table
[
i
]
<<
20
;
if
(
req_441kHz_rate
&&
!
(
adg_mode_flags
(
adg
)
&
AUDIO_OUT_48
))
!
rsnd_flags_has
(
adg
,
AUDIO_OUT_48
))
parent_clk_name
=
__clk_get_name
(
clk
);
}
}
...
...
@@ -528,7 +526,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
adg
->
rbgb_rate_for_48khz
=
rate
/
div
;
ckr
|=
brg_table
[
i
]
<<
16
;
if
(
req_48kHz_rate
&&
(
adg_mode_flags
(
adg
)
&
AUDIO_OUT_48
))
rsnd_flags_has
(
adg
,
AUDIO_OUT_48
))
parent_clk_name
=
__clk_get_name
(
clk
);
}
}
...
...
@@ -572,12 +570,35 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
adg
->
ckr
=
ckr
;
adg
->
rbga
=
rbga
;
adg
->
rbgb
=
rbgb
;
}
#ifdef DEBUG
static
void
rsnd_adg_clk_dbg_info
(
struct
rsnd_priv
*
priv
,
struct
rsnd_adg
*
adg
)
{
struct
device
*
dev
=
rsnd_priv_to_dev
(
priv
);
struct
clk
*
clk
;
int
i
;
for_each_rsnd_clk
(
clk
,
adg
,
i
)
dev_dbg
(
dev
,
"%s : %p : %ld
\n
"
,
clk_name
[
i
],
clk
,
clk_get_rate
(
clk
));
for_each_rsnd_clkout
(
clk
,
adg
,
i
)
dev_dbg
(
dev
,
"clkout %d : %p : %ld
\n
"
,
i
,
clk
,
clk_get_rate
(
clk
));
dev_dbg
(
dev
,
"BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x
\n
"
,
ckr
,
rbga
,
rbgb
);
adg
->
ckr
,
adg
->
rbga
,
adg
->
rbgb
);
dev_dbg
(
dev
,
"BRGA (for 44100 base) = %d
\n
"
,
adg
->
rbga_rate_for_441khz
);
dev_dbg
(
dev
,
"BRGB (for 48000 base) = %d
\n
"
,
adg
->
rbgb_rate_for_48khz
);
/*
* Actual CLKOUT will be exchanged in rsnd_adg_ssi_clk_try_start()
* by BRGCKR::BRGCKR_31
*/
for_each_rsnd_clkout
(
clk
,
adg
,
i
)
dev_dbg
(
dev
,
"clkout %d : %p : %ld
\n
"
,
i
,
clk
,
clk_get_rate
(
clk
));
}
#else
#define rsnd_adg_clk_dbg_info(priv, adg)
#endif
int
rsnd_adg_probe
(
struct
rsnd_priv
*
priv
)
{
...
...
@@ -596,6 +617,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
rsnd_adg_get_clkin
(
priv
,
adg
);
rsnd_adg_get_clkout
(
priv
,
adg
);
rsnd_adg_clk_dbg_info
(
priv
,
adg
);
priv
->
adg
=
adg
;
...
...
sound/soc/sh/rcar/core.c
View file @
f904f846
...
...
@@ -121,14 +121,6 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
}
}
char
*
rsnd_mod_name
(
struct
rsnd_mod
*
mod
)
{
if
(
!
mod
||
!
mod
->
ops
)
return
"unknown"
;
return
mod
->
ops
->
name
;
}
struct
dma_chan
*
rsnd_mod_dma_req
(
struct
rsnd_dai_stream
*
io
,
struct
rsnd_mod
*
mod
)
{
...
...
@@ -172,8 +164,7 @@ int rsnd_mod_init(struct rsnd_priv *priv,
void
rsnd_mod_quit
(
struct
rsnd_mod
*
mod
)
{
if
(
mod
->
clk
)
clk_unprepare
(
mod
->
clk
);
clk_unprepare
(
mod
->
clk
);
mod
->
clk
=
NULL
;
}
...
...
@@ -200,7 +191,10 @@ void rsnd_mod_interrupt(struct rsnd_mod *mod,
int
rsnd_io_is_working
(
struct
rsnd_dai_stream
*
io
)
{
/* see rsnd_dai_stream_init/quit() */
return
!!
io
->
substream
;
if
(
io
->
substream
)
return
snd_pcm_running
(
io
->
substream
);
return
0
;
}
int
rsnd_runtime_channel_original
(
struct
rsnd_dai_stream
*
io
)
...
...
@@ -407,11 +401,9 @@ struct rsnd_mod *rsnd_mod_next(int *iterator,
for
(;
*
iterator
<
max
;
(
*
iterator
)
++
)
{
type
=
(
array
)
?
array
[
*
iterator
]
:
*
iterator
;
mod
=
io
->
mod
[
type
];
if
(
!
mod
)
continue
;
return
mod
;
mod
=
rsnd_io_to_mod
(
io
,
type
);
if
(
mod
)
return
mod
;
}
return
NULL
;
...
...
@@ -1242,6 +1234,33 @@ struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg)
return
&
cfg
->
cfg
;
}
const
char
*
const
volume_ramp_rate
[]
=
{
"128 dB/1 step"
,
/* 00000 */
"64 dB/1 step"
,
/* 00001 */
"32 dB/1 step"
,
/* 00010 */
"16 dB/1 step"
,
/* 00011 */
"8 dB/1 step"
,
/* 00100 */
"4 dB/1 step"
,
/* 00101 */
"2 dB/1 step"
,
/* 00110 */
"1 dB/1 step"
,
/* 00111 */
"0.5 dB/1 step"
,
/* 01000 */
"0.25 dB/1 step"
,
/* 01001 */
"0.125 dB/1 step"
,
/* 01010 = VOLUME_RAMP_MAX_MIX */
"0.125 dB/2 steps"
,
/* 01011 */
"0.125 dB/4 steps"
,
/* 01100 */
"0.125 dB/8 steps"
,
/* 01101 */
"0.125 dB/16 steps"
,
/* 01110 */
"0.125 dB/32 steps"
,
/* 01111 */
"0.125 dB/64 steps"
,
/* 10000 */
"0.125 dB/128 steps"
,
/* 10001 */
"0.125 dB/256 steps"
,
/* 10010 */
"0.125 dB/512 steps"
,
/* 10011 */
"0.125 dB/1024 steps"
,
/* 10100 */
"0.125 dB/2048 steps"
,
/* 10101 */
"0.125 dB/4096 steps"
,
/* 10110 */
"0.125 dB/8192 steps"
,
/* 10111 = VOLUME_RAMP_MAX_DVC */
};
int
rsnd_kctrl_new
(
struct
rsnd_mod
*
mod
,
struct
rsnd_dai_stream
*
io
,
struct
snd_soc_pcm_runtime
*
rtd
,
...
...
sound/soc/sh/rcar/ctu.c
View file @
f904f846
...
...
@@ -81,8 +81,11 @@ struct rsnd_ctu {
struct
rsnd_kctrl_cfg_m
sv3
;
struct
rsnd_kctrl_cfg_s
reset
;
int
channels
;
u32
flags
;
};
#define KCTRL_INITIALIZED (1 << 0)
#define rsnd_ctu_nr(priv) ((priv)->ctu_nr)
#define for_each_rsnd_ctu(pos, priv, i) \
for ((i) = 0; \
...
...
@@ -130,7 +133,7 @@ static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
int
i
;
for
(
i
=
0
;
i
<
RSND_MAX_CHANNELS
;
i
++
)
{
u32
val
=
ctu
->
pass
.
val
[
i
]
;
u32
val
=
rsnd_kctrl_valm
(
ctu
->
pass
,
i
)
;
cpmdr
|=
val
<<
(
28
-
(
i
*
4
));
...
...
@@ -147,44 +150,44 @@ static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
rsnd_mod_write
(
mod
,
CTU_SCMDR
,
scmdr
);
if
(
scmdr
>
0
)
{
rsnd_mod_write
(
mod
,
CTU_SV00R
,
ctu
->
sv0
.
val
[
0
]
);
rsnd_mod_write
(
mod
,
CTU_SV01R
,
ctu
->
sv0
.
val
[
1
]
);
rsnd_mod_write
(
mod
,
CTU_SV02R
,
ctu
->
sv0
.
val
[
2
]
);
rsnd_mod_write
(
mod
,
CTU_SV03R
,
ctu
->
sv0
.
val
[
3
]
);
rsnd_mod_write
(
mod
,
CTU_SV04R
,
ctu
->
sv0
.
val
[
4
]
);
rsnd_mod_write
(
mod
,
CTU_SV05R
,
ctu
->
sv0
.
val
[
5
]
);
rsnd_mod_write
(
mod
,
CTU_SV06R
,
ctu
->
sv0
.
val
[
6
]
);
rsnd_mod_write
(
mod
,
CTU_SV07R
,
ctu
->
sv0
.
val
[
7
]
);
rsnd_mod_write
(
mod
,
CTU_SV00R
,
rsnd_kctrl_valm
(
ctu
->
sv0
,
0
)
);
rsnd_mod_write
(
mod
,
CTU_SV01R
,
rsnd_kctrl_valm
(
ctu
->
sv0
,
1
)
);
rsnd_mod_write
(
mod
,
CTU_SV02R
,
rsnd_kctrl_valm
(
ctu
->
sv0
,
2
)
);
rsnd_mod_write
(
mod
,
CTU_SV03R
,
rsnd_kctrl_valm
(
ctu
->
sv0
,
3
)
);
rsnd_mod_write
(
mod
,
CTU_SV04R
,
rsnd_kctrl_valm
(
ctu
->
sv0
,
4
)
);
rsnd_mod_write
(
mod
,
CTU_SV05R
,
rsnd_kctrl_valm
(
ctu
->
sv0
,
5
)
);
rsnd_mod_write
(
mod
,
CTU_SV06R
,
rsnd_kctrl_valm
(
ctu
->
sv0
,
6
)
);
rsnd_mod_write
(
mod
,
CTU_SV07R
,
rsnd_kctrl_valm
(
ctu
->
sv0
,
7
)
);
}
if
(
scmdr
>
1
)
{
rsnd_mod_write
(
mod
,
CTU_SV10R
,
ctu
->
sv1
.
val
[
0
]
);
rsnd_mod_write
(
mod
,
CTU_SV11R
,
ctu
->
sv1
.
val
[
1
]
);
rsnd_mod_write
(
mod
,
CTU_SV12R
,
ctu
->
sv1
.
val
[
2
]
);
rsnd_mod_write
(
mod
,
CTU_SV13R
,
ctu
->
sv1
.
val
[
3
]
);
rsnd_mod_write
(
mod
,
CTU_SV14R
,
ctu
->
sv1
.
val
[
4
]
);
rsnd_mod_write
(
mod
,
CTU_SV15R
,
ctu
->
sv1
.
val
[
5
]
);
rsnd_mod_write
(
mod
,
CTU_SV16R
,
ctu
->
sv1
.
val
[
6
]
);
rsnd_mod_write
(
mod
,
CTU_SV17R
,
ctu
->
sv1
.
val
[
7
]
);
rsnd_mod_write
(
mod
,
CTU_SV10R
,
rsnd_kctrl_valm
(
ctu
->
sv1
,
0
)
);
rsnd_mod_write
(
mod
,
CTU_SV11R
,
rsnd_kctrl_valm
(
ctu
->
sv1
,
1
)
);
rsnd_mod_write
(
mod
,
CTU_SV12R
,
rsnd_kctrl_valm
(
ctu
->
sv1
,
2
)
);
rsnd_mod_write
(
mod
,
CTU_SV13R
,
rsnd_kctrl_valm
(
ctu
->
sv1
,
3
)
);
rsnd_mod_write
(
mod
,
CTU_SV14R
,
rsnd_kctrl_valm
(
ctu
->
sv1
,
4
)
);
rsnd_mod_write
(
mod
,
CTU_SV15R
,
rsnd_kctrl_valm
(
ctu
->
sv1
,
5
)
);
rsnd_mod_write
(
mod
,
CTU_SV16R
,
rsnd_kctrl_valm
(
ctu
->
sv1
,
6
)
);
rsnd_mod_write
(
mod
,
CTU_SV17R
,
rsnd_kctrl_valm
(
ctu
->
sv1
,
7
)
);
}
if
(
scmdr
>
2
)
{
rsnd_mod_write
(
mod
,
CTU_SV20R
,
ctu
->
sv2
.
val
[
0
]
);
rsnd_mod_write
(
mod
,
CTU_SV21R
,
ctu
->
sv2
.
val
[
1
]
);
rsnd_mod_write
(
mod
,
CTU_SV22R
,
ctu
->
sv2
.
val
[
2
]
);
rsnd_mod_write
(
mod
,
CTU_SV23R
,
ctu
->
sv2
.
val
[
3
]
);
rsnd_mod_write
(
mod
,
CTU_SV24R
,
ctu
->
sv2
.
val
[
4
]
);
rsnd_mod_write
(
mod
,
CTU_SV25R
,
ctu
->
sv2
.
val
[
5
]
);
rsnd_mod_write
(
mod
,
CTU_SV26R
,
ctu
->
sv2
.
val
[
6
]
);
rsnd_mod_write
(
mod
,
CTU_SV27R
,
ctu
->
sv2
.
val
[
7
]
);
rsnd_mod_write
(
mod
,
CTU_SV20R
,
rsnd_kctrl_valm
(
ctu
->
sv2
,
0
)
);
rsnd_mod_write
(
mod
,
CTU_SV21R
,
rsnd_kctrl_valm
(
ctu
->
sv2
,
1
)
);
rsnd_mod_write
(
mod
,
CTU_SV22R
,
rsnd_kctrl_valm
(
ctu
->
sv2
,
2
)
);
rsnd_mod_write
(
mod
,
CTU_SV23R
,
rsnd_kctrl_valm
(
ctu
->
sv2
,
3
)
);
rsnd_mod_write
(
mod
,
CTU_SV24R
,
rsnd_kctrl_valm
(
ctu
->
sv2
,
4
)
);
rsnd_mod_write
(
mod
,
CTU_SV25R
,
rsnd_kctrl_valm
(
ctu
->
sv2
,
5
)
);
rsnd_mod_write
(
mod
,
CTU_SV26R
,
rsnd_kctrl_valm
(
ctu
->
sv2
,
6
)
);
rsnd_mod_write
(
mod
,
CTU_SV27R
,
rsnd_kctrl_valm
(
ctu
->
sv2
,
7
)
);
}
if
(
scmdr
>
3
)
{
rsnd_mod_write
(
mod
,
CTU_SV30R
,
ctu
->
sv3
.
val
[
0
]
);
rsnd_mod_write
(
mod
,
CTU_SV31R
,
ctu
->
sv3
.
val
[
1
]
);
rsnd_mod_write
(
mod
,
CTU_SV32R
,
ctu
->
sv3
.
val
[
2
]
);
rsnd_mod_write
(
mod
,
CTU_SV33R
,
ctu
->
sv3
.
val
[
3
]
);
rsnd_mod_write
(
mod
,
CTU_SV34R
,
ctu
->
sv3
.
val
[
4
]
);
rsnd_mod_write
(
mod
,
CTU_SV35R
,
ctu
->
sv3
.
val
[
5
]
);
rsnd_mod_write
(
mod
,
CTU_SV36R
,
ctu
->
sv3
.
val
[
6
]
);
rsnd_mod_write
(
mod
,
CTU_SV37R
,
ctu
->
sv3
.
val
[
7
]
);
rsnd_mod_write
(
mod
,
CTU_SV30R
,
rsnd_kctrl_valm
(
ctu
->
sv3
,
0
)
);
rsnd_mod_write
(
mod
,
CTU_SV31R
,
rsnd_kctrl_valm
(
ctu
->
sv3
,
1
)
);
rsnd_mod_write
(
mod
,
CTU_SV32R
,
rsnd_kctrl_valm
(
ctu
->
sv3
,
2
)
);
rsnd_mod_write
(
mod
,
CTU_SV33R
,
rsnd_kctrl_valm
(
ctu
->
sv3
,
3
)
);
rsnd_mod_write
(
mod
,
CTU_SV34R
,
rsnd_kctrl_valm
(
ctu
->
sv3
,
4
)
);
rsnd_mod_write
(
mod
,
CTU_SV35R
,
rsnd_kctrl_valm
(
ctu
->
sv3
,
5
)
);
rsnd_mod_write
(
mod
,
CTU_SV36R
,
rsnd_kctrl_valm
(
ctu
->
sv3
,
6
)
);
rsnd_mod_write
(
mod
,
CTU_SV37R
,
rsnd_kctrl_valm
(
ctu
->
sv3
,
7
)
);
}
rsnd_mod_write
(
mod
,
CTU_CTUIR
,
0
);
...
...
@@ -196,17 +199,17 @@ static void rsnd_ctu_value_reset(struct rsnd_dai_stream *io,
struct
rsnd_ctu
*
ctu
=
rsnd_mod_to_ctu
(
mod
);
int
i
;
if
(
!
ctu
->
reset
.
val
)
if
(
!
rsnd_kctrl_vals
(
ctu
->
reset
)
)
return
;
for
(
i
=
0
;
i
<
RSND_MAX_CHANNELS
;
i
++
)
{
ctu
->
pass
.
val
[
i
]
=
0
;
ctu
->
sv0
.
val
[
i
]
=
0
;
ctu
->
sv1
.
val
[
i
]
=
0
;
ctu
->
sv2
.
val
[
i
]
=
0
;
ctu
->
sv3
.
val
[
i
]
=
0
;
rsnd_kctrl_valm
(
ctu
->
pass
,
i
)
=
0
;
rsnd_kctrl_valm
(
ctu
->
sv0
,
i
)
=
0
;
rsnd_kctrl_valm
(
ctu
->
sv1
,
i
)
=
0
;
rsnd_kctrl_valm
(
ctu
->
sv2
,
i
)
=
0
;
rsnd_kctrl_valm
(
ctu
->
sv3
,
i
)
=
0
;
}
ctu
->
reset
.
val
=
0
;
rsnd_kctrl_vals
(
ctu
->
reset
)
=
0
;
}
static
int
rsnd_ctu_init
(
struct
rsnd_mod
*
mod
,
...
...
@@ -277,6 +280,9 @@ static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
struct
rsnd_ctu
*
ctu
=
rsnd_mod_to_ctu
(
mod
);
int
ret
;
if
(
rsnd_flags_has
(
ctu
,
KCTRL_INITIALIZED
))
return
0
;
/* CTU Pass */
ret
=
rsnd_kctrl_new_m
(
mod
,
io
,
rtd
,
"CTU Pass"
,
rsnd_kctrl_accept_anytime
,
...
...
@@ -326,6 +332,8 @@ static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
rsnd_ctu_value_reset
,
&
ctu
->
reset
,
1
);
rsnd_flags_set
(
ctu
,
KCTRL_INITIALIZED
);
return
ret
;
}
...
...
sound/soc/sh/rcar/dma.c
View file @
f904f846
...
...
@@ -60,6 +60,14 @@ struct rsnd_dma_ctrl {
#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
/* for DEBUG */
static
struct
rsnd_mod_ops
mem_ops
=
{
.
name
=
"mem"
,
};
static
struct
rsnd_mod
mem
=
{
};
/*
* Audio DMAC
*/
...
...
@@ -211,11 +219,9 @@ static int rsnd_dmaen_nolock_start(struct rsnd_mod *mod,
dma
->
mod_from
,
dma
->
mod_to
);
if
(
IS_ERR_OR_NULL
(
dmaen
->
chan
))
{
int
ret
=
PTR_ERR
(
dmaen
->
chan
);
dmaen
->
chan
=
NULL
;
dev_err
(
dev
,
"can't get dma channel
\n
"
);
return
ret
;
return
-
EIO
;
}
return
0
;
...
...
@@ -747,20 +753,22 @@ static void rsnd_dma_of_path(struct rsnd_mod *this,
rsnd_mod_name
(
this
),
rsnd_mod_id
(
this
));
for
(
i
=
0
;
i
<=
idx
;
i
++
)
{
dev_dbg
(
dev
,
" %s[%d]%s
\n
"
,
rsnd_mod_name
(
mod
[
i
]),
rsnd_mod_id
(
mod
[
i
]),
(
mod
[
i
]
==
*
mod_from
)
?
" from"
:
(
mod
[
i
]
==
*
mod_to
)
?
" to"
:
""
);
rsnd_mod_name
(
mod
[
i
]
?
mod
[
i
]
:
&
mem
),
rsnd_mod_id
(
mod
[
i
]
?
mod
[
i
]
:
&
mem
),
(
mod
[
i
]
==
*
mod_from
)
?
" from"
:
(
mod
[
i
]
==
*
mod_to
)
?
" to"
:
""
);
}
}
int
rsnd_dma_attach
(
struct
rsnd_dai_stream
*
io
,
struct
rsnd_mod
*
mod
,
struct
rsnd_mod
**
dma_mod
)
static
int
rsnd_dma_alloc
(
struct
rsnd_dai_stream
*
io
,
struct
rsnd_mod
*
mod
,
struct
rsnd_mod
**
dma_mod
)
{
struct
rsnd_mod
*
mod_from
=
NULL
;
struct
rsnd_mod
*
mod_to
=
NULL
;
struct
rsnd_priv
*
priv
=
rsnd_io_to_priv
(
io
);
struct
rsnd_dma_ctrl
*
dmac
=
rsnd_priv_to_dmac
(
priv
);
struct
device
*
dev
=
rsnd_priv_to_dev
(
priv
);
struct
rsnd_dma
*
dma
;
struct
rsnd_mod_ops
*
ops
;
enum
rsnd_mod_type
type
;
int
(
*
attach
)(
struct
rsnd_dai_stream
*
io
,
struct
rsnd_dma
*
dma
,
...
...
@@ -800,40 +808,47 @@ int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
type
=
RSND_MOD_AUDMA
;
}
if
(
!
(
*
dma_mod
))
{
struct
rsnd_dma
*
dma
;
dma
=
devm_kzalloc
(
dev
,
sizeof
(
*
dma
),
GFP_KERNEL
);
if
(
!
dma
)
return
-
ENOMEM
;
dma
=
devm_kzalloc
(
dev
,
sizeof
(
*
dma
),
GFP_KERNEL
);
if
(
!
dma
)
return
-
ENOMEM
;
*
dma_mod
=
rsnd_mod_get
(
dma
);
*
dma_mod
=
rsnd_mod_get
(
dma
);
ret
=
rsnd_mod_init
(
priv
,
*
dma_mod
,
ops
,
NULL
,
rsnd_mod_get_status
,
type
,
dma_id
);
if
(
ret
<
0
)
return
ret
;
ret
=
rsnd_mod_init
(
priv
,
*
dma_mod
,
ops
,
NULL
,
rsnd_mod_get_status
,
type
,
dma_id
);
if
(
ret
<
0
)
return
ret
;
dev_dbg
(
dev
,
"%s[%d] %s[%d] -> %s[%d]
\n
"
,
rsnd_mod_name
(
*
dma_mod
),
rsnd_mod_id
(
*
dma_mod
),
rsnd_mod_name
(
mod_from
?
mod_from
:
&
mem
),
rsnd_mod_id
(
mod_from
?
mod_from
:
&
mem
),
rsnd_mod_name
(
mod_to
?
mod_to
:
&
mem
),
rsnd_mod_id
(
mod_to
?
mod_to
:
&
mem
));
dev_dbg
(
dev
,
"%s[%d] %s[%d] -> %s[%d]
\n
"
,
rsnd_mod_name
(
*
dma_mod
),
rsnd_mod_id
(
*
dma_mod
),
rsnd_mod_name
(
mod_from
),
rsnd_mod_id
(
mod_from
),
rsnd_mod_name
(
mod_to
),
rsnd_mod_id
(
mod_to
));
ret
=
attach
(
io
,
dma
,
mod_from
,
mod_to
);
if
(
ret
<
0
)
return
ret
;
dma
->
src_addr
=
rsnd_dma_addr
(
io
,
mod_from
,
is_play
,
1
);
dma
->
dst_addr
=
rsnd_dma_addr
(
io
,
mod_to
,
is_play
,
0
);
dma
->
mod_from
=
mod_from
;
dma
->
mod_to
=
mod_to
;
return
0
;
}
int
rsnd_dma_attach
(
struct
rsnd_dai_stream
*
io
,
struct
rsnd_mod
*
mod
,
struct
rsnd_mod
**
dma_mod
)
{
if
(
!
(
*
dma_mod
))
{
int
ret
=
rsnd_dma_alloc
(
io
,
mod
,
dma_mod
);
ret
=
attach
(
io
,
dma
,
mod_from
,
mod_to
);
if
(
ret
<
0
)
return
ret
;
dma
->
src_addr
=
rsnd_dma_addr
(
io
,
mod_from
,
is_play
,
1
);
dma
->
dst_addr
=
rsnd_dma_addr
(
io
,
mod_to
,
is_play
,
0
);
dma
->
mod_from
=
mod_from
;
dma
->
mod_to
=
mod_to
;
}
ret
=
rsnd_dai_connect
(
*
dma_mod
,
io
,
type
);
if
(
ret
<
0
)
return
ret
;
return
0
;
return
rsnd_dai_connect
(
*
dma_mod
,
io
,
(
*
dma_mod
)
->
type
);
}
int
rsnd_dma_probe
(
struct
rsnd_priv
*
priv
)
...
...
@@ -866,5 +881,6 @@ int rsnd_dma_probe(struct rsnd_priv *priv)
priv
->
dma
=
dmac
;
return
0
;
/* dummy mem mod for debug */
return
rsnd_mod_init
(
NULL
,
&
mem
,
&
mem_ops
,
NULL
,
NULL
,
0
,
0
);
}
sound/soc/sh/rcar/dvc.c
View file @
f904f846
...
...
@@ -44,8 +44,11 @@ struct rsnd_dvc {
struct
rsnd_kctrl_cfg_s
ren
;
/* Ramp Enable */
struct
rsnd_kctrl_cfg_s
rup
;
/* Ramp Rate Up */
struct
rsnd_kctrl_cfg_s
rdown
;
/* Ramp Rate Down */
u32
flags
;
};
#define KCTRL_INITIALIZED (1 << 0)
#define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id)
#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
...
...
@@ -58,33 +61,6 @@ struct rsnd_dvc {
((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \
i++)
static
const
char
*
const
dvc_ramp_rate
[]
=
{
"128 dB/1 step"
,
/* 00000 */
"64 dB/1 step"
,
/* 00001 */
"32 dB/1 step"
,
/* 00010 */
"16 dB/1 step"
,
/* 00011 */
"8 dB/1 step"
,
/* 00100 */
"4 dB/1 step"
,
/* 00101 */
"2 dB/1 step"
,
/* 00110 */
"1 dB/1 step"
,
/* 00111 */
"0.5 dB/1 step"
,
/* 01000 */
"0.25 dB/1 step"
,
/* 01001 */
"0.125 dB/1 step"
,
/* 01010 */
"0.125 dB/2 steps"
,
/* 01011 */
"0.125 dB/4 steps"
,
/* 01100 */
"0.125 dB/8 steps"
,
/* 01101 */
"0.125 dB/16 steps"
,
/* 01110 */
"0.125 dB/32 steps"
,
/* 01111 */
"0.125 dB/64 steps"
,
/* 10000 */
"0.125 dB/128 steps"
,
/* 10001 */
"0.125 dB/256 steps"
,
/* 10010 */
"0.125 dB/512 steps"
,
/* 10011 */
"0.125 dB/1024 steps"
,
/* 10100 */
"0.125 dB/2048 steps"
,
/* 10101 */
"0.125 dB/4096 steps"
,
/* 10110 */
"0.125 dB/8192 steps"
,
/* 10111 */
};
static
void
rsnd_dvc_activation
(
struct
rsnd_mod
*
mod
)
{
rsnd_mod_write
(
mod
,
DVC_SWRSR
,
0
);
...
...
@@ -97,8 +73,9 @@ static void rsnd_dvc_halt(struct rsnd_mod *mod)
rsnd_mod_write
(
mod
,
DVC_SWRSR
,
0
);
}
#define rsnd_dvc_get_vrpdr(dvc) (dvc->rup.val << 8 | dvc->rdown.val)
#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (dvc->volume.val[0] >> 13))
#define rsnd_dvc_get_vrpdr(dvc) (rsnd_kctrl_vals(dvc->rup) << 8 | \
rsnd_kctrl_vals(dvc->rdown))
#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (rsnd_kctrl_valm(dvc->volume, 0) >> 13))
static
void
rsnd_dvc_volume_parameter
(
struct
rsnd_dai_stream
*
io
,
struct
rsnd_mod
*
mod
)
...
...
@@ -108,12 +85,12 @@ static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
int
i
;
/* Enable Ramp */
if
(
dvc
->
ren
.
val
)
if
(
rsnd_kctrl_vals
(
dvc
->
ren
)
)
for
(
i
=
0
;
i
<
RSND_MAX_CHANNELS
;
i
++
)
val
[
i
]
=
dvc
->
volume
.
cfg
.
max
;
val
[
i
]
=
rsnd_kctrl_max
(
dvc
->
volume
)
;
else
for
(
i
=
0
;
i
<
RSND_MAX_CHANNELS
;
i
++
)
val
[
i
]
=
dvc
->
volume
.
val
[
i
]
;
val
[
i
]
=
rsnd_kctrl_valm
(
dvc
->
volume
,
i
)
;
/* Enable Digital Volume */
rsnd_mod_write
(
mod
,
DVC_VOL0R
,
val
[
0
]);
...
...
@@ -143,7 +120,7 @@ static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
dvucr
|=
0x101
;
/* Enable Ramp */
if
(
dvc
->
ren
.
val
)
{
if
(
rsnd_kctrl_vals
(
dvc
->
ren
)
)
{
dvucr
|=
0x10
;
/*
...
...
@@ -185,10 +162,10 @@ static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
u32
vrdbr
=
0
;
int
i
;
for
(
i
=
0
;
i
<
dvc
->
mute
.
cfg
.
size
;
i
++
)
zcmcr
|=
(
!!
dvc
->
mute
.
cfg
.
val
[
i
]
)
<<
i
;
for
(
i
=
0
;
i
<
rsnd_kctrl_size
(
dvc
->
mute
)
;
i
++
)
zcmcr
|=
(
!!
rsnd_kctrl_valm
(
dvc
->
mute
,
i
)
)
<<
i
;
if
(
dvc
->
ren
.
val
)
{
if
(
rsnd_kctrl_vals
(
dvc
->
ren
)
)
{
vrpdr
=
rsnd_dvc_get_vrpdr
(
dvc
);
vrdbr
=
rsnd_dvc_get_vrdbr
(
dvc
);
}
...
...
@@ -254,6 +231,9 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
int
channels
=
rsnd_rdai_channels_get
(
rdai
);
int
ret
;
if
(
rsnd_flags_has
(
dvc
,
KCTRL_INITIALIZED
))
return
0
;
/* Volume */
ret
=
rsnd_kctrl_new_m
(
mod
,
io
,
rtd
,
is_play
?
...
...
@@ -292,7 +272,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
rsnd_kctrl_accept_anytime
,
rsnd_dvc_volume_update
,
&
dvc
->
rup
,
dvc_ramp_rate
);
volume_ramp_rate
,
VOLUME_RAMP_MAX_DVC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -302,11 +283,14 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
rsnd_kctrl_accept_anytime
,
rsnd_dvc_volume_update
,
&
dvc
->
rdown
,
dvc_ramp_rate
);
volume_ramp_rate
,
VOLUME_RAMP_MAX_DVC
);
if
(
ret
<
0
)
return
ret
;
rsnd_flags_set
(
dvc
,
KCTRL_INITIALIZED
);
return
0
;
}
...
...
sound/soc/sh/rcar/mix.c
View file @
f904f846
...
...
@@ -7,6 +7,33 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/*
* CTUn MIXn
* +------+ +------+
* [SRC3 / SRC6] -> |CTU n0| -> [MIX n0| ->
* [SRC4 / SRC9] -> |CTU n1| -> [MIX n1| ->
* [SRC0 / SRC1] -> |CTU n2| -> [MIX n2| ->
* [SRC2 / SRC5] -> |CTU n3| -> [MIX n3| ->
* +------+ +------+
*
* ex)
* DAI0 : playback = <&src0 &ctu02 &mix0 &dvc0 &ssi0>;
* DAI1 : playback = <&src2 &ctu03 &mix0 &dvc0 &ssi0>;
*
* MIX Volume
* amixer set "MIX",0 100% // DAI0 Volume
* amixer set "MIX",1 100% // DAI1 Volume
*
* Volume Ramp
* amixer set "MIX Ramp Up Rate" "0.125 dB/1 step"
* amixer set "MIX Ramp Down Rate" "4 dB/1 step"
* amixer set "MIX Ramp" on
* aplay xxx.wav &
* amixer set "MIX",0 80% // DAI0 Volume Down
* amixer set "MIX",1 100% // DAI1 Volume Up
*/
#include "rsnd.h"
#define MIX_NAME_SIZE 16
...
...
@@ -14,8 +41,27 @@
struct
rsnd_mix
{
struct
rsnd_mod
mod
;
struct
rsnd_kctrl_cfg_s
volumeA
;
/* MDBAR */
struct
rsnd_kctrl_cfg_s
volumeB
;
/* MDBBR */
struct
rsnd_kctrl_cfg_s
volumeC
;
/* MDBCR */
struct
rsnd_kctrl_cfg_s
volumeD
;
/* MDBDR */
struct
rsnd_kctrl_cfg_s
ren
;
/* Ramp Enable */
struct
rsnd_kctrl_cfg_s
rup
;
/* Ramp Rate Up */
struct
rsnd_kctrl_cfg_s
rdw
;
/* Ramp Rate Down */
u32
flags
;
};
#define ONCE_KCTRL_INITIALIZED (1 << 0)
#define HAS_VOLA (1 << 1)
#define HAS_VOLB (1 << 2)
#define HAS_VOLC (1 << 3)
#define HAS_VOLD (1 << 4)
#define VOL_MAX 0x3ff
#define rsnd_mod_to_mix(_mod) \
container_of((_mod), struct rsnd_mix, mod)
#define rsnd_mix_get(priv, id) ((struct rsnd_mix *)(priv->mix) + id)
#define rsnd_mix_nr(priv) ((priv)->mix_nr)
#define for_each_rsnd_mix(pos, priv, i) \
...
...
@@ -36,26 +82,43 @@ static void rsnd_mix_halt(struct rsnd_mod *mod)
rsnd_mod_write
(
mod
,
MIX_SWRSR
,
0
);
}
#define rsnd_mix_get_vol(mix, X) \
rsnd_flags_has(mix, HAS_VOL##X) ? \
(VOL_MAX - rsnd_kctrl_vals(mix->volume##X)) : 0
static
void
rsnd_mix_volume_parameter
(
struct
rsnd_dai_stream
*
io
,
struct
rsnd_mod
*
mod
)
{
rsnd_mod_write
(
mod
,
MIX_MDBAR
,
0
);
rsnd_mod_write
(
mod
,
MIX_MDBBR
,
0
);
rsnd_mod_write
(
mod
,
MIX_MDBCR
,
0
);
rsnd_mod_write
(
mod
,
MIX_MDBDR
,
0
);
struct
rsnd_priv
*
priv
=
rsnd_mod_to_priv
(
mod
);
struct
device
*
dev
=
rsnd_priv_to_dev
(
priv
);
struct
rsnd_mix
*
mix
=
rsnd_mod_to_mix
(
mod
);
u32
volA
=
rsnd_mix_get_vol
(
mix
,
A
);
u32
volB
=
rsnd_mix_get_vol
(
mix
,
B
);
u32
volC
=
rsnd_mix_get_vol
(
mix
,
C
);
u32
volD
=
rsnd_mix_get_vol
(
mix
,
D
);
dev_dbg
(
dev
,
"MIX A/B/C/D = %02x/%02x/%02x/%02x
\n
"
,
volA
,
volB
,
volC
,
volD
);
rsnd_mod_write
(
mod
,
MIX_MDBAR
,
volA
);
rsnd_mod_write
(
mod
,
MIX_MDBBR
,
volB
);
rsnd_mod_write
(
mod
,
MIX_MDBCR
,
volC
);
rsnd_mod_write
(
mod
,
MIX_MDBDR
,
volD
);
}
static
void
rsnd_mix_volume_init
(
struct
rsnd_dai_stream
*
io
,
struct
rsnd_mod
*
mod
)
{
struct
rsnd_mix
*
mix
=
rsnd_mod_to_mix
(
mod
);
rsnd_mod_write
(
mod
,
MIX_MIXIR
,
1
);
/* General Information */
rsnd_mod_write
(
mod
,
MIX_ADINR
,
rsnd_runtime_channel_after_ctu
(
io
));
/* volume step */
rsnd_mod_write
(
mod
,
MIX_MIXMR
,
0
);
rsnd_mod_write
(
mod
,
MIX_MVPDR
,
0
);
rsnd_mod_write
(
mod
,
MIX_MIXMR
,
rsnd_kctrl_vals
(
mix
->
ren
));
rsnd_mod_write
(
mod
,
MIX_MVPDR
,
rsnd_kctrl_vals
(
mix
->
rup
)
<<
8
|
rsnd_kctrl_vals
(
mix
->
rdw
));
/* common volume parameter */
rsnd_mix_volume_parameter
(
io
,
mod
);
...
...
@@ -109,11 +172,94 @@ static int rsnd_mix_quit(struct rsnd_mod *mod,
return
0
;
}
static
int
rsnd_mix_pcm_new
(
struct
rsnd_mod
*
mod
,
struct
rsnd_dai_stream
*
io
,
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
rsnd_priv
*
priv
=
rsnd_mod_to_priv
(
mod
);
struct
device
*
dev
=
rsnd_priv_to_dev
(
priv
);
struct
rsnd_mix
*
mix
=
rsnd_mod_to_mix
(
mod
);
struct
rsnd_mod
*
src_mod
=
rsnd_io_to_mod_src
(
io
);
struct
rsnd_kctrl_cfg_s
*
volume
;
int
ret
;
switch
(
rsnd_mod_id
(
src_mod
))
{
case
3
:
case
6
:
/* MDBAR */
volume
=
&
mix
->
volumeA
;
rsnd_flags_set
(
mix
,
HAS_VOLA
);
break
;
case
4
:
case
9
:
/* MDBBR */
volume
=
&
mix
->
volumeB
;
rsnd_flags_set
(
mix
,
HAS_VOLB
);
break
;
case
0
:
case
1
:
/* MDBCR */
volume
=
&
mix
->
volumeC
;
rsnd_flags_set
(
mix
,
HAS_VOLC
);
break
;
case
2
:
case
5
:
/* MDBDR */
volume
=
&
mix
->
volumeD
;
rsnd_flags_set
(
mix
,
HAS_VOLD
);
break
;
default:
dev_err
(
dev
,
"unknown SRC is connected
\n
"
);
return
-
EINVAL
;
}
/* Volume */
ret
=
rsnd_kctrl_new_s
(
mod
,
io
,
rtd
,
"MIX Playback Volume"
,
rsnd_kctrl_accept_anytime
,
rsnd_mix_volume_update
,
volume
,
VOL_MAX
);
if
(
ret
<
0
)
return
ret
;
rsnd_kctrl_vals
(
*
volume
)
=
VOL_MAX
;
if
(
rsnd_flags_has
(
mix
,
ONCE_KCTRL_INITIALIZED
))
return
ret
;
/* Ramp */
ret
=
rsnd_kctrl_new_s
(
mod
,
io
,
rtd
,
"MIX Ramp Switch"
,
rsnd_kctrl_accept_anytime
,
rsnd_mix_volume_update
,
&
mix
->
ren
,
1
);
if
(
ret
<
0
)
return
ret
;
ret
=
rsnd_kctrl_new_e
(
mod
,
io
,
rtd
,
"MIX Ramp Up Rate"
,
rsnd_kctrl_accept_anytime
,
rsnd_mix_volume_update
,
&
mix
->
rup
,
volume_ramp_rate
,
VOLUME_RAMP_MAX_MIX
);
if
(
ret
<
0
)
return
ret
;
ret
=
rsnd_kctrl_new_e
(
mod
,
io
,
rtd
,
"MIX Ramp Down Rate"
,
rsnd_kctrl_accept_anytime
,
rsnd_mix_volume_update
,
&
mix
->
rdw
,
volume_ramp_rate
,
VOLUME_RAMP_MAX_MIX
);
rsnd_flags_set
(
mix
,
ONCE_KCTRL_INITIALIZED
);
return
ret
;
}
static
struct
rsnd_mod_ops
rsnd_mix_ops
=
{
.
name
=
MIX_NAME
,
.
probe
=
rsnd_mix_probe_
,
.
init
=
rsnd_mix_init
,
.
quit
=
rsnd_mix_quit
,
.
pcm_new
=
rsnd_mix_pcm_new
,
};
struct
rsnd_mod
*
rsnd_mix_mod_get
(
struct
rsnd_priv
*
priv
,
int
id
)
...
...
sound/soc/sh/rcar/rsnd.h
View file @
f904f846
...
...
@@ -355,8 +355,9 @@ struct rsnd_mod {
#define __rsnd_mod_call_nolock_start 0
#define __rsnd_mod_call_nolock_stop 1
#define rsnd_mod_to_priv(mod) ((mod)->priv)
#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)
#define rsnd_mod_to_priv(mod) ((mod)->priv)
#define rsnd_mod_name(mod) ((mod)->ops->name)
#define rsnd_mod_id(mod) ((mod)->id)
#define rsnd_mod_power_on(mod) clk_enable((mod)->clk)
#define rsnd_mod_power_off(mod) clk_disable((mod)->clk)
#define rsnd_mod_get(ip) (&(ip)->mod)
...
...
@@ -371,7 +372,6 @@ int rsnd_mod_init(struct rsnd_priv *priv,
enum
rsnd_mod_type
type
,
int
id
);
void
rsnd_mod_quit
(
struct
rsnd_mod
*
mod
);
char
*
rsnd_mod_name
(
struct
rsnd_mod
*
mod
);
struct
dma_chan
*
rsnd_mod_dma_req
(
struct
rsnd_dai_stream
*
io
,
struct
rsnd_mod
*
mod
);
void
rsnd_mod_interrupt
(
struct
rsnd_mod
*
mod
,
...
...
@@ -601,6 +601,10 @@ struct rsnd_priv {
#define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1)
#define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2)
#define rsnd_flags_has(p, f) ((p)->flags & (f))
#define rsnd_flags_set(p, f) ((p)->flags |= (f))
#define rsnd_flags_del(p, f) ((p)->flags &= ~(f))
/*
* rsnd_kctrl
*/
...
...
@@ -627,6 +631,10 @@ struct rsnd_kctrl_cfg_s {
struct
rsnd_kctrl_cfg
cfg
;
u32
val
;
};
#define rsnd_kctrl_size(x) ((x).cfg.size)
#define rsnd_kctrl_max(x) ((x).cfg.max)
#define rsnd_kctrl_valm(x, i) ((x).val[i])
/* = (x).cfg.val[i] */
#define rsnd_kctrl_vals(x) ((x).val)
/* = (x).cfg.val[0] */
int
rsnd_kctrl_accept_anytime
(
struct
rsnd_dai_stream
*
io
);
int
rsnd_kctrl_accept_runtime
(
struct
rsnd_dai_stream
*
io
);
...
...
@@ -652,9 +660,13 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,
rsnd_kctrl_new(mod, io, rtd, name, accept, update, rsnd_kctrl_init_s(cfg), \
NULL, 1, max)
#define rsnd_kctrl_new_e(mod, io, rtd, name, accept, update, cfg, texts
)
\
#define rsnd_kctrl_new_e(mod, io, rtd, name, accept, update, cfg, texts
, size)
\
rsnd_kctrl_new(mod, io, rtd, name, accept, update, rsnd_kctrl_init_s(cfg), \
texts, 1, ARRAY_SIZE(texts))
texts, 1, size)
extern
const
char
*
const
volume_ramp_rate
[];
#define VOLUME_RAMP_MAX_DVC (0x17 + 1)
#define VOLUME_RAMP_MAX_MIX (0x0a + 1)
/*
* R-Car SSI
...
...
sound/soc/sh/rcar/ssi.c
View file @
f904f846
...
...
@@ -101,9 +101,6 @@ struct rsnd_ssi {
#define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id)
#define rsnd_ssi_nr(priv) ((priv)->ssi_nr)
#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
#define rsnd_ssi_flags_has(p, f) ((p)->flags & f)
#define rsnd_ssi_flags_set(p, f) ((p)->flags |= f)
#define rsnd_ssi_flags_del(p, f) ((p)->flags = ((p)->flags & ~f))
#define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io))
#define rsnd_ssi_is_multi_slave(mod, io) \
(rsnd_ssi_multi_slaves(io) & (1 << rsnd_mod_id(mod)))
...
...
@@ -116,10 +113,10 @@ int rsnd_ssi_hdmi_port(struct rsnd_dai_stream *io)
struct
rsnd_mod
*
mod
=
rsnd_io_to_mod_ssi
(
io
);
struct
rsnd_ssi
*
ssi
=
rsnd_mod_to_ssi
(
mod
);
if
(
rsnd_
ssi_
flags_has
(
ssi
,
RSND_SSI_HDMI0
))
if
(
rsnd_flags_has
(
ssi
,
RSND_SSI_HDMI0
))
return
RSND_SSI_HDMI_PORT0
;
if
(
rsnd_
ssi_
flags_has
(
ssi
,
RSND_SSI_HDMI1
))
if
(
rsnd_flags_has
(
ssi
,
RSND_SSI_HDMI1
))
return
RSND_SSI_HDMI_PORT1
;
return
0
;
...
...
@@ -134,7 +131,7 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
if
(
!
rsnd_ssi_is_dma_mode
(
mod
))
return
0
;
if
(
!
(
rsnd_
ssi_
flags_has
(
ssi
,
RSND_SSI_NO_BUSIF
)))
if
(
!
(
rsnd_flags_has
(
ssi
,
RSND_SSI_NO_BUSIF
)))
use_busif
=
1
;
if
(
rsnd_io_to_mod_src
(
io
))
use_busif
=
1
;
...
...
@@ -198,10 +195,15 @@ static u32 rsnd_ssi_run_mods(struct rsnd_dai_stream *io)
{
struct
rsnd_mod
*
ssi_mod
=
rsnd_io_to_mod_ssi
(
io
);
struct
rsnd_mod
*
ssi_parent_mod
=
rsnd_io_to_mod_ssip
(
io
);
u32
mods
;
return
rsnd_ssi_multi_slaves_runtime
(
io
)
|
1
<<
rsnd_mod_id
(
ssi_mod
)
|
1
<<
rsnd_mod_id
(
ssi_parent_mod
);
mods
=
rsnd_ssi_multi_slaves_runtime
(
io
)
|
1
<<
rsnd_mod_id
(
ssi_mod
);
if
(
ssi_parent_mod
)
mods
|=
1
<<
rsnd_mod_id
(
ssi_parent_mod
);
return
mods
;
}
u32
rsnd_ssi_multi_slaves_runtime
(
struct
rsnd_dai_stream
*
io
)
...
...
@@ -601,15 +603,18 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
if
(
rsnd_ssi_is_parent
(
mod
,
io
))
return
0
;
/*
* disable all IRQ,
* and, wait all data was sent
*/
cr
=
ssi
->
cr_own
|
ssi
->
cr_clk
;
rsnd_mod_write
(
mod
,
SSICR
,
cr
|
EN
);
rsnd_ssi_status_check
(
mod
,
DIRQ
);
/*
* disable all IRQ,
* Playback: Wait all data was sent
* Capture: It might not receave data. Do nothing
*/
if
(
rsnd_io_is_play
(
io
))
{
rsnd_mod_write
(
mod
,
SSICR
,
cr
|
EN
);
rsnd_ssi_status_check
(
mod
,
DIRQ
);
}
/*
* disable SSI,
...
...
@@ -793,13 +798,13 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod,
* But it don't need to call request_irq() many times.
* Let's control it by RSND_SSI_PROBED flag.
*/
if
(
!
rsnd_
ssi_
flags_has
(
ssi
,
RSND_SSI_PROBED
))
{
if
(
!
rsnd_flags_has
(
ssi
,
RSND_SSI_PROBED
))
{
ret
=
request_irq
(
ssi
->
irq
,
rsnd_ssi_interrupt
,
IRQF_SHARED
,
dev_name
(
dev
),
mod
);
rsnd_
ssi_
flags_set
(
ssi
,
RSND_SSI_PROBED
);
rsnd_flags_set
(
ssi
,
RSND_SSI_PROBED
);
}
return
ret
;
...
...
@@ -817,10 +822,10 @@ static int rsnd_ssi_common_remove(struct rsnd_mod *mod,
return
0
;
/* PIO will request IRQ again */
if
(
rsnd_
ssi_
flags_has
(
ssi
,
RSND_SSI_PROBED
))
{
if
(
rsnd_flags_has
(
ssi
,
RSND_SSI_PROBED
))
{
free_irq
(
ssi
->
irq
,
mod
);
rsnd_
ssi_
flags_del
(
ssi
,
RSND_SSI_PROBED
);
rsnd_flags_del
(
ssi
,
RSND_SSI_PROBED
);
}
return
0
;
...
...
@@ -1003,13 +1008,13 @@ static void __rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv,
ssi
=
rsnd_mod_to_ssi
(
mod
);
if
(
strstr
(
remote_ep
->
full_name
,
"hdmi0"
))
{
rsnd_
ssi_
flags_set
(
ssi
,
RSND_SSI_HDMI0
);
rsnd_flags_set
(
ssi
,
RSND_SSI_HDMI0
);
dev_dbg
(
dev
,
"%s[%d] connected to HDMI0
\n
"
,
rsnd_mod_name
(
mod
),
rsnd_mod_id
(
mod
));
}
if
(
strstr
(
remote_ep
->
full_name
,
"hdmi1"
))
{
rsnd_
ssi_
flags_set
(
ssi
,
RSND_SSI_HDMI1
);
rsnd_flags_set
(
ssi
,
RSND_SSI_HDMI1
);
dev_dbg
(
dev
,
"%s[%d] connected to HDMI1
\n
"
,
rsnd_mod_name
(
mod
),
rsnd_mod_id
(
mod
));
}
...
...
@@ -1042,7 +1047,7 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
{
struct
rsnd_ssi
*
ssi
=
rsnd_mod_to_ssi
(
mod
);
return
!!
(
rsnd_
ssi_
flags_has
(
ssi
,
RSND_SSI_CLK_PIN_SHARE
));
return
!!
(
rsnd_flags_has
(
ssi
,
RSND_SSI_CLK_PIN_SHARE
));
}
static
u32
*
rsnd_ssi_get_status
(
struct
rsnd_dai_stream
*
io
,
...
...
@@ -1128,10 +1133,10 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
}
if
(
of_get_property
(
np
,
"shared-pin"
,
NULL
))
rsnd_
ssi_
flags_set
(
ssi
,
RSND_SSI_CLK_PIN_SHARE
);
rsnd_flags_set
(
ssi
,
RSND_SSI_CLK_PIN_SHARE
);
if
(
of_get_property
(
np
,
"no-busif"
,
NULL
))
rsnd_
ssi_
flags_set
(
ssi
,
RSND_SSI_NO_BUSIF
);
rsnd_flags_set
(
ssi
,
RSND_SSI_NO_BUSIF
);
ssi
->
irq
=
irq_of_parse_and_map
(
np
,
0
);
if
(
!
ssi
->
irq
)
{
...
...
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