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
a451d4e0
Commit
a451d4e0
authored
Jan 26, 2018
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branches 'asoc/topic/rl6231' and 'asoc/topic/rt5514' into asoc-next
parents
7cf143ca
790dde24
fc9cab05
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
156 additions
and
30 deletions
+156
-30
include/sound/rt5514.h
include/sound/rt5514.h
+2
-0
sound/soc/codecs/rl6231.c
sound/soc/codecs/rl6231.c
+64
-29
sound/soc/codecs/rt5514-spi.c
sound/soc/codecs/rt5514-spi.c
+1
-0
sound/soc/codecs/rt5514.c
sound/soc/codecs/rt5514.c
+85
-0
sound/soc/codecs/rt5514.h
sound/soc/codecs/rt5514.h
+4
-1
No files found.
include/sound/rt5514.h
View file @
a451d4e0
...
...
@@ -14,6 +14,8 @@
struct
rt5514_platform_data
{
unsigned
int
dmic_init_delay
;
const
char
*
dsp_calib_clk_name
;
unsigned
int
dsp_calib_clk_rate
;
};
#endif
...
...
sound/soc/codecs/rl6231.c
View file @
a451d4e0
...
...
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/gcd.h>
#include "rl6231.h"
/**
...
...
@@ -106,6 +107,25 @@ static const struct pll_calc_map pll_preset_table[] = {
{
19200000
,
24576000
,
3
,
30
,
3
,
false
},
};
static
unsigned
int
find_best_div
(
unsigned
int
in
,
unsigned
int
max
,
unsigned
int
div
)
{
unsigned
int
d
;
if
(
in
<=
max
)
return
1
;
d
=
in
/
max
;
if
(
in
%
max
)
d
++
;
while
(
div
%
d
!=
0
)
d
++
;
return
d
;
}
/**
* rl6231_pll_calc - Calcualte PLL M/N/K code.
* @freq_in: external clock provided to codec.
...
...
@@ -120,9 +140,11 @@ int rl6231_pll_calc(const unsigned int freq_in,
const
unsigned
int
freq_out
,
struct
rl6231_pll_code
*
pll_code
)
{
int
max_n
=
RL6231_PLL_N_MAX
,
max_m
=
RL6231_PLL_M_MAX
;
int
i
,
k
,
red
,
n_t
,
pll_out
,
in_t
,
out_t
;
int
n
=
0
,
m
=
0
,
m_t
=
0
;
int
red_t
=
abs
(
freq_out
-
freq_in
);
int
i
,
k
,
n_t
;
int
k_t
,
min_k
,
max_k
,
n
=
0
,
m
=
0
,
m_t
=
0
;
unsigned
int
red
,
pll_out
,
in_t
,
out_t
,
div
,
div_t
;
unsigned
int
red_t
=
abs
(
freq_out
-
freq_in
);
unsigned
int
f_in
,
f_out
,
f_max
;
bool
bypass
=
false
;
if
(
RL6231_PLL_INP_MAX
<
freq_in
||
RL6231_PLL_INP_MIN
>
freq_in
)
...
...
@@ -140,39 +162,52 @@ int rl6231_pll_calc(const unsigned int freq_in,
}
}
k
=
100000000
/
freq_out
-
2
;
if
(
k
>
RL6231_PLL_K_MAX
)
k
=
RL6231_PLL_K_MAX
;
for
(
n_t
=
0
;
n_t
<=
max_n
;
n_t
++
)
{
in_t
=
freq_in
/
(
k
+
2
);
pll_out
=
freq_out
/
(
n_t
+
2
);
if
(
in_t
<
0
)
continue
;
if
(
in_t
==
pll_out
)
{
bypass
=
true
;
n
=
n_t
;
goto
code_find
;
}
red
=
abs
(
in_t
-
pll_out
);
if
(
red
<
red_t
)
{
bypass
=
true
;
n
=
n_t
;
m
=
m_t
;
if
(
red
==
0
)
min_k
=
80000000
/
freq_out
-
2
;
max_k
=
150000000
/
freq_out
-
2
;
if
(
max_k
>
RL6231_PLL_K_MAX
)
max_k
=
RL6231_PLL_K_MAX
;
if
(
min_k
>
RL6231_PLL_K_MAX
)
min_k
=
max_k
=
RL6231_PLL_K_MAX
;
div_t
=
gcd
(
freq_in
,
freq_out
);
f_max
=
0xffffffff
/
RL6231_PLL_N_MAX
;
div
=
find_best_div
(
freq_in
,
f_max
,
div_t
);
f_in
=
freq_in
/
div
;
f_out
=
freq_out
/
div
;
k
=
min_k
;
for
(
k_t
=
min_k
;
k_t
<=
max_k
;
k_t
++
)
{
for
(
n_t
=
0
;
n_t
<=
max_n
;
n_t
++
)
{
in_t
=
f_in
*
(
n_t
+
2
);
pll_out
=
f_out
*
(
k_t
+
2
);
if
(
in_t
==
pll_out
)
{
bypass
=
true
;
n
=
n_t
;
k
=
k_t
;
goto
code_find
;
red_t
=
red
;
}
for
(
m_t
=
0
;
m_t
<=
max_m
;
m_t
++
)
{
out_t
=
in_t
/
(
m_t
+
2
);
red
=
abs
(
out_t
-
pll_out
);
}
out_t
=
in_t
/
(
k_t
+
2
);
red
=
abs
(
f_out
-
out_t
);
if
(
red
<
red_t
)
{
bypass
=
fals
e
;
bypass
=
tru
e
;
n
=
n_t
;
m
=
m_t
;
m
=
0
;
k
=
k_t
;
if
(
red
==
0
)
goto
code_find
;
red_t
=
red
;
}
for
(
m_t
=
0
;
m_t
<=
max_m
;
m_t
++
)
{
out_t
=
in_t
/
((
m_t
+
2
)
*
(
k_t
+
2
));
red
=
abs
(
f_out
-
out_t
);
if
(
red
<
red_t
)
{
bypass
=
false
;
n
=
n_t
;
m
=
m_t
;
k
=
k_t
;
if
(
red
==
0
)
goto
code_find
;
red_t
=
red
;
}
}
}
}
pr_debug
(
"Only get approximation about PLL
\n
"
);
...
...
sound/soc/codecs/rt5514-spi.c
View file @
a451d4e0
...
...
@@ -381,6 +381,7 @@ int rt5514_spi_burst_read(unsigned int addr, u8 *rxbuf, size_t len)
return
true
;
}
EXPORT_SYMBOL_GPL
(
rt5514_spi_burst_read
);
/**
* rt5514_spi_burst_write - Write data to SPI by rt5514 address.
...
...
sound/soc/codecs/rt5514.c
View file @
a451d4e0
...
...
@@ -295,6 +295,33 @@ static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol,
return
0
;
}
static
int
rt5514_calibration
(
struct
rt5514_priv
*
rt5514
,
bool
on
)
{
if
(
on
)
{
regmap_write
(
rt5514
->
regmap
,
RT5514_ANA_CTRL_PLL3
,
0x0000000a
);
regmap_update_bits
(
rt5514
->
regmap
,
RT5514_PLL_SOURCE_CTRL
,
0xf
,
0xa
);
regmap_update_bits
(
rt5514
->
regmap
,
RT5514_PWR_ANA1
,
0x301
,
0x301
);
regmap_write
(
rt5514
->
regmap
,
RT5514_PLL3_CALIB_CTRL4
,
0x80000000
|
rt5514
->
pll3_cal_value
);
regmap_write
(
rt5514
->
regmap
,
RT5514_PLL3_CALIB_CTRL1
,
0x8bb80800
);
regmap_update_bits
(
rt5514
->
regmap
,
RT5514_PLL3_CALIB_CTRL5
,
0xc0000000
,
0x80000000
);
regmap_update_bits
(
rt5514
->
regmap
,
RT5514_PLL3_CALIB_CTRL5
,
0xc0000000
,
0xc0000000
);
}
else
{
regmap_update_bits
(
rt5514
->
regmap
,
RT5514_PLL3_CALIB_CTRL5
,
0xc0000000
,
0x40000000
);
regmap_update_bits
(
rt5514
->
regmap
,
RT5514_PWR_ANA1
,
0x301
,
0
);
regmap_update_bits
(
rt5514
->
regmap
,
RT5514_PLL_SOURCE_CTRL
,
0xf
,
0x4
);
}
return
0
;
}
static
int
rt5514_dsp_voice_wake_up_put
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
...
...
@@ -302,6 +329,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
struct
rt5514_priv
*
rt5514
=
snd_soc_component_get_drvdata
(
component
);
struct
snd_soc_codec
*
codec
=
rt5514
->
codec
;
const
struct
firmware
*
fw
=
NULL
;
u8
buf
[
8
];
if
(
ucontrol
->
value
.
integer
.
value
[
0
]
==
rt5514
->
dsp_enabled
)
return
0
;
...
...
@@ -310,6 +338,35 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
rt5514
->
dsp_enabled
=
ucontrol
->
value
.
integer
.
value
[
0
];
if
(
rt5514
->
dsp_enabled
)
{
if
(
rt5514
->
pdata
.
dsp_calib_clk_name
&&
!
IS_ERR
(
rt5514
->
dsp_calib_clk
))
{
if
(
clk_set_rate
(
rt5514
->
dsp_calib_clk
,
rt5514
->
pdata
.
dsp_calib_clk_rate
))
dev_err
(
codec
->
dev
,
"Can't set rate for mclk"
);
if
(
clk_prepare_enable
(
rt5514
->
dsp_calib_clk
))
dev_err
(
codec
->
dev
,
"Can't enable dsp_calib_clk"
);
rt5514_calibration
(
rt5514
,
true
);
msleep
(
20
);
#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
rt5514_spi_burst_read
(
RT5514_PLL3_CALIB_CTRL6
|
RT5514_DSP_MAPPING
,
(
u8
*
)
&
buf
,
sizeof
(
buf
));
#else
dev_err
(
codec
->
dev
,
"There is no SPI driver for"
" loading the firmware
\n
"
);
#endif
rt5514
->
pll3_cal_value
=
buf
[
0
]
|
buf
[
1
]
<<
8
|
buf
[
2
]
<<
16
|
buf
[
3
]
<<
24
;
rt5514_calibration
(
rt5514
,
false
);
clk_disable_unprepare
(
rt5514
->
dsp_calib_clk
);
}
rt5514_enable_dsp_prepare
(
rt5514
);
request_firmware
(
&
fw
,
RT5514_FIRMWARE1
,
codec
->
dev
);
...
...
@@ -341,6 +398,20 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
/* DSP run */
regmap_write
(
rt5514
->
i2c_regmap
,
0x18002f00
,
0x00055148
);
if
(
rt5514
->
pdata
.
dsp_calib_clk_name
&&
!
IS_ERR
(
rt5514
->
dsp_calib_clk
))
{
msleep
(
20
);
regmap_write
(
rt5514
->
i2c_regmap
,
0x1800211c
,
rt5514
->
pll3_cal_value
);
regmap_write
(
rt5514
->
i2c_regmap
,
0x18002124
,
0x00220012
);
regmap_write
(
rt5514
->
i2c_regmap
,
0x18002124
,
0x80220042
);
regmap_write
(
rt5514
->
i2c_regmap
,
0x18002124
,
0xe0220042
);
}
}
else
{
regmap_multi_reg_write
(
rt5514
->
i2c_regmap
,
rt5514_i2c_patch
,
ARRAY_SIZE
(
rt5514_i2c_patch
));
...
...
@@ -1024,12 +1095,22 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec,
static
int
rt5514_probe
(
struct
snd_soc_codec
*
codec
)
{
struct
rt5514_priv
*
rt5514
=
snd_soc_codec_get_drvdata
(
codec
);
struct
platform_device
*
pdev
=
container_of
(
codec
->
dev
,
struct
platform_device
,
dev
);
rt5514
->
mclk
=
devm_clk_get
(
codec
->
dev
,
"mclk"
);
if
(
PTR_ERR
(
rt5514
->
mclk
)
==
-
EPROBE_DEFER
)
return
-
EPROBE_DEFER
;
if
(
rt5514
->
pdata
.
dsp_calib_clk_name
)
{
rt5514
->
dsp_calib_clk
=
devm_clk_get
(
&
pdev
->
dev
,
rt5514
->
pdata
.
dsp_calib_clk_name
);
if
(
PTR_ERR
(
rt5514
->
dsp_calib_clk
)
==
-
EPROBE_DEFER
)
return
-
EPROBE_DEFER
;
}
rt5514
->
codec
=
codec
;
rt5514
->
pll3_cal_value
=
0x0078b000
;
return
0
;
}
...
...
@@ -1147,6 +1228,10 @@ static int rt5514_parse_dp(struct rt5514_priv *rt5514, struct device *dev)
{
device_property_read_u32
(
dev
,
"realtek,dmic-init-delay-ms"
,
&
rt5514
->
pdata
.
dmic_init_delay
);
device_property_read_string
(
dev
,
"realtek,dsp-calib-clk-name"
,
&
rt5514
->
pdata
.
dsp_calib_clk_name
);
device_property_read_u32
(
dev
,
"realtek,dsp-calib-clk-rate"
,
&
rt5514
->
pdata
.
dsp_calib_clk_rate
);
return
0
;
}
...
...
sound/soc/codecs/rt5514.h
View file @
a451d4e0
...
...
@@ -34,7 +34,9 @@
#define RT5514_CLK_CTRL1 0x2104
#define RT5514_CLK_CTRL2 0x2108
#define RT5514_PLL3_CALIB_CTRL1 0x2110
#define RT5514_PLL3_CALIB_CTRL4 0x2120
#define RT5514_PLL3_CALIB_CTRL5 0x2124
#define RT5514_PLL3_CALIB_CTRL6 0x2128
#define RT5514_DELAY_BUF_CTRL1 0x2140
#define RT5514_DELAY_BUF_CTRL3 0x2148
#define RT5514_ASRC_IN_CTRL1 0x2180
...
...
@@ -272,7 +274,7 @@ struct rt5514_priv {
struct
rt5514_platform_data
pdata
;
struct
snd_soc_codec
*
codec
;
struct
regmap
*
i2c_regmap
,
*
regmap
;
struct
clk
*
mclk
;
struct
clk
*
mclk
,
*
dsp_calib_clk
;
int
sysclk
;
int
sysclk_src
;
int
lrck
;
...
...
@@ -281,6 +283,7 @@ struct rt5514_priv {
int
pll_in
;
int
pll_out
;
int
dsp_enabled
;
unsigned
int
pll3_cal_value
;
};
#endif
/* __RT5514_H__ */
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