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