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
644ed467
Commit
644ed467
authored
Jun 22, 2022
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
ASoC: Merge fixes
Needed for new development.
parents
6b183919
f69a10f8
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
272 additions
and
130 deletions
+272
-130
MAINTAINERS
MAINTAINERS
+1
-1
drivers/base/regmap/regmap.c
drivers/base/regmap/regmap.c
+8
-7
sound/soc/codecs/cs35l41.c
sound/soc/codecs/cs35l41.c
+6
-6
sound/soc/codecs/rt711-sdca.c
sound/soc/codecs/rt711-sdca.c
+2
-2
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm5110.c
+6
-2
sound/soc/codecs/wm_adsp.c
sound/soc/codecs/wm_adsp.c
+1
-1
sound/soc/rockchip/rockchip_i2s.c
sound/soc/rockchip/rockchip_i2s.c
+129
-31
sound/soc/sof/intel/hda-loader.c
sound/soc/sof/intel/hda-loader.c
+2
-1
sound/soc/sof/intel/hda-pcm.c
sound/soc/sof/intel/hda-pcm.c
+1
-73
sound/soc/sof/intel/hda-stream.c
sound/soc/sof/intel/hda-stream.c
+90
-4
sound/soc/sof/intel/hda.h
sound/soc/sof/intel/hda.h
+3
-0
sound/soc/sof/mediatek/mt8186/mt8186.c
sound/soc/sof/mediatek/mt8186/mt8186.c
+1
-1
sound/soc/sof/pm.c
sound/soc/sof/pm.c
+20
-1
sound/soc/sof/sof-priv.h
sound/soc/sof/sof-priv.h
+2
-0
No files found.
MAINTAINERS
View file @
644ed467
...
...
@@ -16247,7 +16247,7 @@ F: drivers/crypto/qat/
QCOM AUDIO (ASoC) DRIVERS
M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
M: Banajit Goswami <bgoswami@
codeaurora.org
>
M: Banajit Goswami <bgoswami@
quicinc.com
>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
F: sound/soc/codecs/lpass-va-macro.c
...
...
drivers/base/regmap/regmap.c
View file @
644ed467
...
...
@@ -1880,8 +1880,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
*/
bool
regmap_can_raw_write
(
struct
regmap
*
map
)
{
return
map
->
bus
&&
map
->
bus
->
write
&&
map
->
format
.
format_val
&&
map
->
format
.
format_reg
;
return
map
->
write
&&
map
->
format
.
format_val
&&
map
->
format
.
format_reg
;
}
EXPORT_SYMBOL_GPL
(
regmap_can_raw_write
);
...
...
@@ -2155,10 +2154,9 @@ int regmap_noinc_write(struct regmap *map, unsigned int reg,
size_t
write_len
;
int
ret
;
if
(
!
map
->
bus
)
return
-
EINVAL
;
if
(
!
map
->
bus
->
write
)
if
(
!
map
->
write
)
return
-
ENOTSUPP
;
if
(
val_len
%
map
->
format
.
val_bytes
)
return
-
EINVAL
;
if
(
!
IS_ALIGNED
(
reg
,
map
->
reg_stride
))
...
...
@@ -2300,7 +2298,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
* Some devices don't support bulk write, for them we have a series of
* single write operations.
*/
if
(
!
map
->
bus
||
!
map
->
format
.
parse_inplace
)
{
if
(
!
map
->
write
||
!
map
->
format
.
parse_inplace
)
{
map
->
lock
(
map
->
lock_arg
);
for
(
i
=
0
;
i
<
val_count
;
i
++
)
{
unsigned
int
ival
;
...
...
@@ -2926,6 +2924,9 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg,
size_t
read_len
;
int
ret
;
if
(
!
map
->
read
)
return
-
ENOTSUPP
;
if
(
val_len
%
map
->
format
.
val_bytes
)
return
-
EINVAL
;
if
(
!
IS_ALIGNED
(
reg
,
map
->
reg_stride
))
...
...
@@ -3039,7 +3040,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
if
(
val_count
==
0
)
return
-
EINVAL
;
if
(
map
->
format
.
parse_inplace
&&
(
vol
||
map
->
cache_type
==
REGCACHE_NONE
))
{
if
(
map
->
read
&&
map
->
format
.
parse_inplace
&&
(
vol
||
map
->
cache_type
==
REGCACHE_NONE
))
{
ret
=
regmap_raw_read
(
map
,
reg
,
val
,
val_bytes
*
val_count
);
if
(
ret
!=
0
)
return
ret
;
...
...
sound/soc/codecs/cs35l41.c
View file @
644ed467
...
...
@@ -333,7 +333,7 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
SOC_SINGLE
(
"HW Noise Gate Enable"
,
CS35L41_NG_CFG
,
8
,
63
,
0
),
SOC_SINGLE
(
"HW Noise Gate Delay"
,
CS35L41_NG_CFG
,
4
,
7
,
0
),
SOC_SINGLE
(
"HW Noise Gate Threshold"
,
CS35L41_NG_CFG
,
0
,
7
,
0
),
SOC_SINGLE
(
"Aux Noise Gate CH1
Enable
"
,
SOC_SINGLE
(
"Aux Noise Gate CH1
Switch
"
,
CS35L41_MIXER_NGATE_CH1_CFG
,
16
,
1
,
0
),
SOC_SINGLE
(
"Aux Noise Gate CH1 Entry Delay"
,
CS35L41_MIXER_NGATE_CH1_CFG
,
8
,
15
,
0
),
...
...
@@ -341,15 +341,15 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
CS35L41_MIXER_NGATE_CH1_CFG
,
0
,
7
,
0
),
SOC_SINGLE
(
"Aux Noise Gate CH2 Entry Delay"
,
CS35L41_MIXER_NGATE_CH2_CFG
,
8
,
15
,
0
),
SOC_SINGLE
(
"Aux Noise Gate CH2
Enable
"
,
SOC_SINGLE
(
"Aux Noise Gate CH2
Switch
"
,
CS35L41_MIXER_NGATE_CH2_CFG
,
16
,
1
,
0
),
SOC_SINGLE
(
"Aux Noise Gate CH2 Threshold"
,
CS35L41_MIXER_NGATE_CH2_CFG
,
0
,
7
,
0
),
SOC_SINGLE
(
"SCLK Force"
,
CS35L41_SP_FORMAT
,
CS35L41_SCLK_FRC_SHIFT
,
1
,
0
),
SOC_SINGLE
(
"LRCLK Force"
,
CS35L41_SP_FORMAT
,
CS35L41_LRCLK_FRC_SHIFT
,
1
,
0
),
SOC_SINGLE
(
"Invert Class D"
,
CS35L41_AMP_DIG_VOL_CTRL
,
SOC_SINGLE
(
"SCLK Force
Switch
"
,
CS35L41_SP_FORMAT
,
CS35L41_SCLK_FRC_SHIFT
,
1
,
0
),
SOC_SINGLE
(
"LRCLK Force
Switch
"
,
CS35L41_SP_FORMAT
,
CS35L41_LRCLK_FRC_SHIFT
,
1
,
0
),
SOC_SINGLE
(
"Invert Class D
Switch
"
,
CS35L41_AMP_DIG_VOL_CTRL
,
CS35L41_AMP_INV_PCM_SHIFT
,
1
,
0
),
SOC_SINGLE
(
"Amp Gain ZC"
,
CS35L41_AMP_GAIN_CTRL
,
SOC_SINGLE
(
"Amp Gain ZC
Switch
"
,
CS35L41_AMP_GAIN_CTRL
,
CS35L41_AMP_GAIN_ZC_SHIFT
,
1
,
0
),
WM_ADSP2_PRELOAD_SWITCH
(
"DSP1"
,
1
),
WM_ADSP_FW_CONTROL
(
"DSP1"
,
0
),
...
...
sound/soc/codecs/rt711-sdca.c
View file @
644ed467
...
...
@@ -34,7 +34,7 @@ static int rt711_sdca_index_write(struct rt711_sdca_priv *rt711,
ret
=
regmap_write
(
regmap
,
addr
,
value
);
if
(
ret
<
0
)
dev_err
(
rt711
->
component
->
dev
,
dev_err
(
&
rt711
->
slave
->
dev
,
"Failed to set private value: %06x <= %04x ret=%d
\n
"
,
addr
,
value
,
ret
);
...
...
@@ -50,7 +50,7 @@ static int rt711_sdca_index_read(struct rt711_sdca_priv *rt711,
ret
=
regmap_read
(
regmap
,
addr
,
value
);
if
(
ret
<
0
)
dev_err
(
rt711
->
component
->
dev
,
dev_err
(
&
rt711
->
slave
->
dev
,
"Failed to get private value: %06x => %04x ret=%d
\n
"
,
addr
,
*
value
,
ret
);
...
...
sound/soc/codecs/wm5110.c
View file @
644ed467
...
...
@@ -413,6 +413,7 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol,
unsigned
int
rnew
=
(
!!
ucontrol
->
value
.
integer
.
value
[
1
])
<<
mc
->
rshift
;
unsigned
int
lold
,
rold
;
unsigned
int
lena
,
rena
;
bool
change
=
false
;
int
ret
;
snd_soc_dapm_mutex_lock
(
dapm
);
...
...
@@ -440,8 +441,8 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol,
goto
err
;
}
ret
=
regmap_update_bits
(
arizona
->
regmap
,
ARIZONA_DRE_ENABLE
,
mask
,
lnew
|
rnew
);
ret
=
regmap_update_bits
_check
(
arizona
->
regmap
,
ARIZONA_DRE_ENABLE
,
mask
,
lnew
|
rnew
,
&
change
);
if
(
ret
)
{
dev_err
(
arizona
->
dev
,
"Failed to set DRE: %d
\n
"
,
ret
);
goto
err
;
...
...
@@ -454,6 +455,9 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol,
if
(
!
rnew
&&
rold
)
wm5110_clear_pga_volume
(
arizona
,
mc
->
rshift
);
if
(
change
)
ret
=
1
;
err:
snd_soc_dapm_mutex_unlock
(
dapm
);
...
...
sound/soc/codecs/wm_adsp.c
View file @
644ed467
...
...
@@ -997,7 +997,7 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
snd_soc_dapm_sync
(
dapm
);
}
return
0
;
return
1
;
}
EXPORT_SYMBOL_GPL
(
wm_adsp2_preloader_put
);
...
...
sound/soc/rockchip/rockchip_i2s.c
View file @
644ed467
...
...
@@ -13,6 +13,7 @@
#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
...
...
@@ -54,8 +55,40 @@ struct rk_i2s_dev {
const
struct
rk_i2s_pins
*
pins
;
unsigned
int
bclk_ratio
;
spinlock_t
lock
;
/* tx/rx lock */
struct
pinctrl
*
pinctrl
;
struct
pinctrl_state
*
bclk_on
;
struct
pinctrl_state
*
bclk_off
;
};
static
int
i2s_pinctrl_select_bclk_on
(
struct
rk_i2s_dev
*
i2s
)
{
int
ret
=
0
;
if
(
!
IS_ERR
(
i2s
->
pinctrl
)
&&
!
IS_ERR_OR_NULL
(
i2s
->
bclk_on
))
ret
=
pinctrl_select_state
(
i2s
->
pinctrl
,
i2s
->
bclk_on
);
if
(
ret
)
dev_err
(
i2s
->
dev
,
"bclk enable failed %d
\n
"
,
ret
);
return
ret
;
}
static
int
i2s_pinctrl_select_bclk_off
(
struct
rk_i2s_dev
*
i2s
)
{
int
ret
=
0
;
if
(
!
IS_ERR
(
i2s
->
pinctrl
)
&&
!
IS_ERR_OR_NULL
(
i2s
->
bclk_off
))
ret
=
pinctrl_select_state
(
i2s
->
pinctrl
,
i2s
->
bclk_off
);
if
(
ret
)
dev_err
(
i2s
->
dev
,
"bclk disable failed %d
\n
"
,
ret
);
return
ret
;
}
static
int
i2s_runtime_suspend
(
struct
device
*
dev
)
{
struct
rk_i2s_dev
*
i2s
=
dev_get_drvdata
(
dev
);
...
...
@@ -92,38 +125,49 @@ static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)
return
snd_soc_dai_get_drvdata
(
dai
);
}
static
void
rockchip_snd_txctrl
(
struct
rk_i2s_dev
*
i2s
,
int
on
)
static
int
rockchip_snd_txctrl
(
struct
rk_i2s_dev
*
i2s
,
int
on
)
{
unsigned
int
val
=
0
;
int
retry
=
10
;
int
ret
=
0
;
spin_lock
(
&
i2s
->
lock
);
if
(
on
)
{
regmap_update_bits
(
i2s
->
regmap
,
I2S_DMACR
,
I2S_DMACR_TDE_ENABLE
,
I2S_DMACR_TDE_ENABLE
);
ret
=
regmap_update_bits
(
i2s
->
regmap
,
I2S_DMACR
,
I2S_DMACR_TDE_ENABLE
,
I2S_DMACR_TDE_ENABLE
);
if
(
ret
<
0
)
goto
end
;
regmap_update_bits
(
i2s
->
regmap
,
I2S_XFER
,
I2S_XFER_TXS_START
|
I2S_XFER_RXS_START
,
I2S_XFER_TXS_START
|
I2S_XFER_RXS_START
);
ret
=
regmap_update_bits
(
i2s
->
regmap
,
I2S_XFER
,
I2S_XFER_TXS_START
|
I2S_XFER_RXS_START
,
I2S_XFER_TXS_START
|
I2S_XFER_RXS_START
);
if
(
ret
<
0
)
goto
end
;
i2s
->
tx_start
=
true
;
}
else
{
i2s
->
tx_start
=
false
;
regmap_update_bits
(
i2s
->
regmap
,
I2S_DMACR
,
I2S_DMACR_TDE_ENABLE
,
I2S_DMACR_TDE_DISABLE
);
ret
=
regmap_update_bits
(
i2s
->
regmap
,
I2S_DMACR
,
I2S_DMACR_TDE_ENABLE
,
I2S_DMACR_TDE_DISABLE
);
if
(
ret
<
0
)
goto
end
;
if
(
!
i2s
->
rx_start
)
{
regmap_update_bits
(
i2s
->
regmap
,
I2S_XFER
,
I2S_XFER_TXS_START
|
I2S_XFER_RXS_START
,
I2S_XFER_TXS_STOP
|
I2S_XFER_RXS_STOP
);
ret
=
regmap_update_bits
(
i2s
->
regmap
,
I2S_XFER
,
I2S_XFER_TXS_START
|
I2S_XFER_RXS_START
,
I2S_XFER_TXS_STOP
|
I2S_XFER_RXS_STOP
);
if
(
ret
<
0
)
goto
end
;
udelay
(
150
);
regmap_update_bits
(
i2s
->
regmap
,
I2S_CLR
,
I2S_CLR_TXC
|
I2S_CLR_RXC
,
I2S_CLR_TXC
|
I2S_CLR_RXC
);
ret
=
regmap_update_bits
(
i2s
->
regmap
,
I2S_CLR
,
I2S_CLR_TXC
|
I2S_CLR_RXC
,
I2S_CLR_TXC
|
I2S_CLR_RXC
);
if
(
ret
<
0
)
goto
end
;
regmap_read
(
i2s
->
regmap
,
I2S_CLR
,
&
val
);
...
...
@@ -138,44 +182,57 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
}
}
}
end:
spin_unlock
(
&
i2s
->
lock
);
if
(
ret
<
0
)
dev_err
(
i2s
->
dev
,
"lrclk update failed
\n
"
);
return
ret
;
}
static
void
rockchip_snd_rxctrl
(
struct
rk_i2s_dev
*
i2s
,
int
on
)
static
int
rockchip_snd_rxctrl
(
struct
rk_i2s_dev
*
i2s
,
int
on
)
{
unsigned
int
val
=
0
;
int
retry
=
10
;
int
ret
=
0
;
spin_lock
(
&
i2s
->
lock
);
if
(
on
)
{
regmap_update_bits
(
i2s
->
regmap
,
I2S_DMACR
,
re
t
=
re
gmap_update_bits
(
i2s
->
regmap
,
I2S_DMACR
,
I2S_DMACR_RDE_ENABLE
,
I2S_DMACR_RDE_ENABLE
);
if
(
ret
<
0
)
goto
end
;
regmap_update_bits
(
i2s
->
regmap
,
I2S_XFER
,
re
t
=
re
gmap_update_bits
(
i2s
->
regmap
,
I2S_XFER
,
I2S_XFER_TXS_START
|
I2S_XFER_RXS_START
,
I2S_XFER_TXS_START
|
I2S_XFER_RXS_START
);
if
(
ret
<
0
)
goto
end
;
i2s
->
rx_start
=
true
;
}
else
{
i2s
->
rx_start
=
false
;
regmap_update_bits
(
i2s
->
regmap
,
I2S_DMACR
,
re
t
=
re
gmap_update_bits
(
i2s
->
regmap
,
I2S_DMACR
,
I2S_DMACR_RDE_ENABLE
,
I2S_DMACR_RDE_DISABLE
);
if
(
ret
<
0
)
goto
end
;
if
(
!
i2s
->
tx_start
)
{
regmap_update_bits
(
i2s
->
regmap
,
I2S_XFER
,
re
t
=
re
gmap_update_bits
(
i2s
->
regmap
,
I2S_XFER
,
I2S_XFER_TXS_START
|
I2S_XFER_RXS_START
,
I2S_XFER_TXS_STOP
|
I2S_XFER_RXS_STOP
);
if
(
ret
<
0
)
goto
end
;
udelay
(
150
);
regmap_update_bits
(
i2s
->
regmap
,
I2S_CLR
,
re
t
=
re
gmap_update_bits
(
i2s
->
regmap
,
I2S_CLR
,
I2S_CLR_TXC
|
I2S_CLR_RXC
,
I2S_CLR_TXC
|
I2S_CLR_RXC
);
if
(
ret
<
0
)
goto
end
;
regmap_read
(
i2s
->
regmap
,
I2S_CLR
,
&
val
);
/* Should wait for clear operation to finish */
while
(
val
)
{
regmap_read
(
i2s
->
regmap
,
I2S_CLR
,
&
val
);
...
...
@@ -187,7 +244,12 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
}
}
}
end:
spin_unlock
(
&
i2s
->
lock
);
if
(
ret
<
0
)
dev_err
(
i2s
->
dev
,
"lrclk update failed
\n
"
);
return
ret
;
}
static
int
rockchip_i2s_set_fmt
(
struct
snd_soc_dai
*
cpu_dai
,
...
...
@@ -425,17 +487,26 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream,
case
SNDRV_PCM_TRIGGER_RESUME
:
case
SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_CAPTURE
)
rockchip_snd_rxctrl
(
i2s
,
1
);
r
et
=
r
ockchip_snd_rxctrl
(
i2s
,
1
);
else
rockchip_snd_txctrl
(
i2s
,
1
);
ret
=
rockchip_snd_txctrl
(
i2s
,
1
);
/* Do not turn on bclk if lrclk open fails. */
if
(
ret
<
0
)
return
ret
;
i2s_pinctrl_select_bclk_on
(
i2s
);
break
;
case
SNDRV_PCM_TRIGGER_SUSPEND
:
case
SNDRV_PCM_TRIGGER_STOP
:
case
SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_CAPTURE
)
rockchip_snd_rxctrl
(
i2s
,
0
);
else
rockchip_snd_txctrl
(
i2s
,
0
);
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_CAPTURE
)
{
if
(
!
i2s
->
tx_start
)
i2s_pinctrl_select_bclk_off
(
i2s
);
ret
=
rockchip_snd_rxctrl
(
i2s
,
0
);
}
else
{
if
(
!
i2s
->
rx_start
)
i2s_pinctrl_select_bclk_off
(
i2s
);
ret
=
rockchip_snd_txctrl
(
i2s
,
0
);
}
break
;
default:
ret
=
-
EINVAL
;
...
...
@@ -736,6 +807,33 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
}
i2s
->
bclk_ratio
=
64
;
i2s
->
pinctrl
=
devm_pinctrl_get
(
&
pdev
->
dev
);
if
(
IS_ERR
(
i2s
->
pinctrl
))
dev_err
(
&
pdev
->
dev
,
"failed to find i2s pinctrl
\n
"
);
i2s
->
bclk_on
=
pinctrl_lookup_state
(
i2s
->
pinctrl
,
"bclk_on"
);
if
(
IS_ERR_OR_NULL
(
i2s
->
bclk_on
))
dev_err
(
&
pdev
->
dev
,
"failed to find i2s default state
\n
"
);
else
dev_dbg
(
&
pdev
->
dev
,
"find i2s bclk state
\n
"
);
i2s
->
bclk_off
=
pinctrl_lookup_state
(
i2s
->
pinctrl
,
"bclk_off"
);
if
(
IS_ERR_OR_NULL
(
i2s
->
bclk_off
))
dev_err
(
&
pdev
->
dev
,
"failed to find i2s gpio state
\n
"
);
else
dev_dbg
(
&
pdev
->
dev
,
"find i2s bclk_off state
\n
"
);
i2s_pinctrl_select_bclk_off
(
i2s
);
i2s
->
playback_dma_data
.
addr
=
res
->
start
+
I2S_TXDR
;
i2s
->
playback_dma_data
.
addr_width
=
DMA_SLAVE_BUSWIDTH_4_BYTES
;
i2s
->
playback_dma_data
.
maxburst
=
4
;
i2s
->
capture_dma_data
.
addr
=
res
->
start
+
I2S_RXDR
;
i2s
->
capture_dma_data
.
addr_width
=
DMA_SLAVE_BUSWIDTH_4_BYTES
;
i2s
->
capture_dma_data
.
maxburst
=
4
;
dev_set_drvdata
(
&
pdev
->
dev
,
i2s
);
...
...
sound/soc/sof/intel/hda-loader.c
View file @
644ed467
...
...
@@ -395,7 +395,8 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
struct
snd_dma_buffer
dmab
;
int
ret
,
ret1
,
i
;
if
(
hda
->
imrboot_supported
&&
!
sdev
->
first_boot
)
{
if
(
sdev
->
system_suspend_target
<
SOF_SUSPEND_S4
&&
hda
->
imrboot_supported
&&
!
sdev
->
first_boot
)
{
dev_dbg
(
sdev
->
dev
,
"IMR restore supported, booting from IMR directly
\n
"
);
hda
->
boot_iteration
=
0
;
ret
=
hda_dsp_boot_imr
(
sdev
);
...
...
sound/soc/sof/intel/hda-pcm.c
View file @
644ed467
...
...
@@ -192,79 +192,7 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
goto
found
;
}
switch
(
sof_hda_position_quirk
)
{
case
SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY
:
/*
* This legacy code, inherited from the Skylake driver,
* mixes DPIB registers and DPIB DDR updates and
* does not seem to follow any known hardware recommendations.
* It's not clear e.g. why there is a different flow
* for capture and playback, the only information that matters is
* what traffic class is used, and on all SOF-enabled platforms
* only VC0 is supported so the work-around was likely not necessary
* and quite possibly wrong.
*/
/* DPIB/posbuf position mode:
* For Playback, Use DPIB register from HDA space which
* reflects the actual data transferred.
* For Capture, Use the position buffer for pointer, as DPIB
* is not accurate enough, its update may be completed
* earlier than the data written to DDR.
*/
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
pos
=
snd_sof_dsp_read
(
sdev
,
HDA_DSP_HDA_BAR
,
AZX_REG_VS_SDXDPIB_XBASE
+
(
AZX_REG_VS_SDXDPIB_XINTERVAL
*
hstream
->
index
));
}
else
{
/*
* For capture stream, we need more workaround to fix the
* position incorrect issue:
*
* 1. Wait at least 20us before reading position buffer after
* the interrupt generated(IOC), to make sure position update
* happens on frame boundary i.e. 20.833uSec for 48KHz.
* 2. Perform a dummy Read to DPIB register to flush DMA
* position value.
* 3. Read the DMA Position from posbuf. Now the readback
* value should be >= period boundary.
*/
usleep_range
(
20
,
21
);
snd_sof_dsp_read
(
sdev
,
HDA_DSP_HDA_BAR
,
AZX_REG_VS_SDXDPIB_XBASE
+
(
AZX_REG_VS_SDXDPIB_XINTERVAL
*
hstream
->
index
));
pos
=
snd_hdac_stream_get_pos_posbuf
(
hstream
);
}
break
;
case
SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS
:
/*
* In case VC1 traffic is disabled this is the recommended option
*/
pos
=
snd_sof_dsp_read
(
sdev
,
HDA_DSP_HDA_BAR
,
AZX_REG_VS_SDXDPIB_XBASE
+
(
AZX_REG_VS_SDXDPIB_XINTERVAL
*
hstream
->
index
));
break
;
case
SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE
:
/*
* This is the recommended option when VC1 is enabled.
* While this isn't needed for SOF platforms it's added for
* consistency and debug.
*/
pos
=
snd_hdac_stream_get_pos_posbuf
(
hstream
);
break
;
default:
dev_err_once
(
sdev
->
dev
,
"hda_position_quirk value %d not supported
\n
"
,
sof_hda_position_quirk
);
pos
=
0
;
break
;
}
if
(
pos
>=
hstream
->
bufsize
)
pos
=
0
;
pos
=
hda_dsp_stream_get_position
(
hstream
,
substream
->
stream
,
true
);
found:
pos
=
bytes_to_frames
(
substream
->
runtime
,
pos
);
...
...
sound/soc/sof/intel/hda-stream.c
View file @
644ed467
...
...
@@ -707,12 +707,13 @@ bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev)
}
static
void
hda_dsp_
set_bytes_transferred
(
struct
hdac_stream
*
hstream
,
u64
buffer_size
)
hda_dsp_
compr_bytes_transferred
(
struct
hdac_stream
*
hstream
,
int
direction
)
{
u64
buffer_size
=
hstream
->
bufsize
;
u64
prev_pos
,
pos
,
num_bytes
;
div64_u64_rem
(
hstream
->
curr_pos
,
buffer_size
,
&
prev_pos
);
pos
=
snd_hdac_stream_get_pos_posbuf
(
hstream
);
pos
=
hda_dsp_stream_get_position
(
hstream
,
direction
,
false
);
if
(
pos
<
prev_pos
)
num_bytes
=
(
buffer_size
-
prev_pos
)
+
pos
;
...
...
@@ -748,8 +749,7 @@ static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status)
if
(
s
->
substream
&&
sof_hda
->
no_ipc_position
)
{
snd_sof_pcm_period_elapsed
(
s
->
substream
);
}
else
if
(
s
->
cstream
)
{
hda_dsp_set_bytes_transferred
(
s
,
s
->
cstream
->
runtime
->
buffer_size
);
hda_dsp_compr_bytes_transferred
(
s
,
s
->
cstream
->
direction
);
snd_compr_fragment_elapsed
(
s
->
cstream
);
}
}
...
...
@@ -1009,3 +1009,89 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev)
devm_kfree
(
sdev
->
dev
,
hda_stream
);
}
}
snd_pcm_uframes_t
hda_dsp_stream_get_position
(
struct
hdac_stream
*
hstream
,
int
direction
,
bool
can_sleep
)
{
struct
hdac_ext_stream
*
hext_stream
=
stream_to_hdac_ext_stream
(
hstream
);
struct
sof_intel_hda_stream
*
hda_stream
=
hstream_to_sof_hda_stream
(
hext_stream
);
struct
snd_sof_dev
*
sdev
=
hda_stream
->
sdev
;
snd_pcm_uframes_t
pos
;
switch
(
sof_hda_position_quirk
)
{
case
SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY
:
/*
* This legacy code, inherited from the Skylake driver,
* mixes DPIB registers and DPIB DDR updates and
* does not seem to follow any known hardware recommendations.
* It's not clear e.g. why there is a different flow
* for capture and playback, the only information that matters is
* what traffic class is used, and on all SOF-enabled platforms
* only VC0 is supported so the work-around was likely not necessary
* and quite possibly wrong.
*/
/* DPIB/posbuf position mode:
* For Playback, Use DPIB register from HDA space which
* reflects the actual data transferred.
* For Capture, Use the position buffer for pointer, as DPIB
* is not accurate enough, its update may be completed
* earlier than the data written to DDR.
*/
if
(
direction
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
pos
=
snd_sof_dsp_read
(
sdev
,
HDA_DSP_HDA_BAR
,
AZX_REG_VS_SDXDPIB_XBASE
+
(
AZX_REG_VS_SDXDPIB_XINTERVAL
*
hstream
->
index
));
}
else
{
/*
* For capture stream, we need more workaround to fix the
* position incorrect issue:
*
* 1. Wait at least 20us before reading position buffer after
* the interrupt generated(IOC), to make sure position update
* happens on frame boundary i.e. 20.833uSec for 48KHz.
* 2. Perform a dummy Read to DPIB register to flush DMA
* position value.
* 3. Read the DMA Position from posbuf. Now the readback
* value should be >= period boundary.
*/
if
(
can_sleep
)
usleep_range
(
20
,
21
);
snd_sof_dsp_read
(
sdev
,
HDA_DSP_HDA_BAR
,
AZX_REG_VS_SDXDPIB_XBASE
+
(
AZX_REG_VS_SDXDPIB_XINTERVAL
*
hstream
->
index
));
pos
=
snd_hdac_stream_get_pos_posbuf
(
hstream
);
}
break
;
case
SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS
:
/*
* In case VC1 traffic is disabled this is the recommended option
*/
pos
=
snd_sof_dsp_read
(
sdev
,
HDA_DSP_HDA_BAR
,
AZX_REG_VS_SDXDPIB_XBASE
+
(
AZX_REG_VS_SDXDPIB_XINTERVAL
*
hstream
->
index
));
break
;
case
SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE
:
/*
* This is the recommended option when VC1 is enabled.
* While this isn't needed for SOF platforms it's added for
* consistency and debug.
*/
pos
=
snd_hdac_stream_get_pos_posbuf
(
hstream
);
break
;
default:
dev_err_once
(
sdev
->
dev
,
"hda_position_quirk value %d not supported
\n
"
,
sof_hda_position_quirk
);
pos
=
0
;
break
;
}
if
(
pos
>=
hstream
->
bufsize
)
pos
=
0
;
return
pos
;
}
sound/soc/sof/intel/hda.h
View file @
644ed467
...
...
@@ -565,6 +565,9 @@ int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
bool
hda_dsp_check_ipc_irq
(
struct
snd_sof_dev
*
sdev
);
bool
hda_dsp_check_stream_irq
(
struct
snd_sof_dev
*
sdev
);
snd_pcm_uframes_t
hda_dsp_stream_get_position
(
struct
hdac_stream
*
hstream
,
int
direction
,
bool
can_sleep
);
struct
hdac_ext_stream
*
hda_dsp_stream_get
(
struct
snd_sof_dev
*
sdev
,
int
direction
,
u32
flags
);
int
hda_dsp_stream_put
(
struct
snd_sof_dev
*
sdev
,
int
direction
,
int
stream_tag
);
...
...
sound/soc/sof/mediatek/mt8186/mt8186.c
View file @
644ed467
...
...
@@ -392,7 +392,7 @@ static int mt8186_dsp_probe(struct snd_sof_dev *sdev)
PLATFORM_DEVID_NONE
,
pdev
,
sizeof
(
*
pdev
));
if
(
IS_ERR
(
priv
->
ipc_dev
))
{
ret
=
IS
_ERR
(
priv
->
ipc_dev
);
ret
=
PTR
_ERR
(
priv
->
ipc_dev
);
dev_err
(
sdev
->
dev
,
"failed to create mtk-adsp-ipc device
\n
"
);
goto
err_adsp_off
;
}
...
...
sound/soc/sof/pm.c
View file @
644ed467
...
...
@@ -23,6 +23,9 @@ static u32 snd_sof_dsp_power_target(struct snd_sof_dev *sdev)
u32
target_dsp_state
;
switch
(
sdev
->
system_suspend_target
)
{
case
SOF_SUSPEND_S5
:
case
SOF_SUSPEND_S4
:
/* DSP should be in D3 if the system is suspending to S3+ */
case
SOF_SUSPEND_S3
:
/* DSP should be in D3 if the system is suspending to S3 */
target_dsp_state
=
SOF_DSP_PM_D3
;
...
...
@@ -335,8 +338,24 @@ int snd_sof_prepare(struct device *dev)
return
0
;
#if defined(CONFIG_ACPI)
if
(
acpi_target_system_state
()
==
ACPI_STATE_S0
)
switch
(
acpi_target_system_state
())
{
case
ACPI_STATE_S0
:
sdev
->
system_suspend_target
=
SOF_SUSPEND_S0IX
;
break
;
case
ACPI_STATE_S1
:
case
ACPI_STATE_S2
:
case
ACPI_STATE_S3
:
sdev
->
system_suspend_target
=
SOF_SUSPEND_S3
;
break
;
case
ACPI_STATE_S4
:
sdev
->
system_suspend_target
=
SOF_SUSPEND_S4
;
break
;
case
ACPI_STATE_S5
:
sdev
->
system_suspend_target
=
SOF_SUSPEND_S5
;
break
;
default:
break
;
}
#endif
return
0
;
...
...
sound/soc/sof/sof-priv.h
View file @
644ed467
...
...
@@ -91,6 +91,8 @@ enum sof_system_suspend_state {
SOF_SUSPEND_NONE
=
0
,
SOF_SUSPEND_S0IX
,
SOF_SUSPEND_S3
,
SOF_SUSPEND_S4
,
SOF_SUSPEND_S5
,
};
enum
sof_dfsentry_type
{
...
...
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