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