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
0c2964cb
Commit
0c2964cb
authored
Apr 30, 2017
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
parents
d872f046
081dc8ab
Changes
33
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
1408 additions
and
427 deletions
+1408
-427
include/sound/soc.h
include/sound/soc.h
+8
-0
sound/hda/hdac_controller.c
sound/hda/hdac_controller.c
+1
-1
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/hdac_hdmi.c
+2
-2
sound/soc/codecs/rt5670.c
sound/soc/codecs/rt5670.c
+21
-0
sound/soc/intel/Kconfig
sound/soc/intel/Kconfig
+24
-0
sound/soc/intel/atom/sst/sst_acpi.c
sound/soc/intel/atom/sst/sst_acpi.c
+39
-2
sound/soc/intel/atom/sst/sst_ipc.c
sound/soc/intel/atom/sst/sst_ipc.c
+3
-1
sound/soc/intel/boards/Makefile
sound/soc/intel/boards/Makefile
+4
-0
sound/soc/intel/boards/bdw-rt5677.c
sound/soc/intel/boards/bdw-rt5677.c
+2
-3
sound/soc/intel/boards/broadwell.c
sound/soc/intel/boards/broadwell.c
+0
-3
sound/soc/intel/boards/bxt_da7219_max98357a.c
sound/soc/intel/boards/bxt_da7219_max98357a.c
+53
-44
sound/soc/intel/boards/bxt_rt298.c
sound/soc/intel/boards/bxt_rt298.c
+3
-0
sound/soc/intel/boards/bytcht_da7213.c
sound/soc/intel/boards/bytcht_da7213.c
+283
-0
sound/soc/intel/boards/bytcht_nocodec.c
sound/soc/intel/boards/bytcht_nocodec.c
+208
-0
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/intel/boards/bytcr_rt5640.c
+84
-25
sound/soc/intel/haswell/sst-haswell-ipc.c
sound/soc/intel/haswell/sst-haswell-ipc.c
+0
-6
sound/soc/intel/skylake/bxt-sst.c
sound/soc/intel/skylake/bxt-sst.c
+53
-65
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl-messages.c
+6
-10
sound/soc/intel/skylake/skl-nhlt.c
sound/soc/intel/skylake/skl-nhlt.c
+3
-4
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-pcm.c
+86
-32
sound/soc/intel/skylake/skl-sst-cldma.c
sound/soc/intel/skylake/skl-sst-cldma.c
+17
-9
sound/soc/intel/skylake/skl-sst-cldma.h
sound/soc/intel/skylake/skl-sst-cldma.h
+1
-1
sound/soc/intel/skylake/skl-sst-dsp.c
sound/soc/intel/skylake/skl-sst-dsp.c
+4
-2
sound/soc/intel/skylake/skl-sst-dsp.h
sound/soc/intel/skylake/skl-sst-dsp.h
+32
-8
sound/soc/intel/skylake/skl-sst-ipc.c
sound/soc/intel/skylake/skl-sst-ipc.c
+53
-23
sound/soc/intel/skylake/skl-sst-ipc.h
sound/soc/intel/skylake/skl-sst-ipc.h
+16
-1
sound/soc/intel/skylake/skl-sst-utils.c
sound/soc/intel/skylake/skl-sst-utils.c
+88
-52
sound/soc/intel/skylake/skl-sst.c
sound/soc/intel/skylake/skl-sst.c
+137
-38
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl-topology.c
+164
-83
sound/soc/intel/skylake/skl-topology.h
sound/soc/intel/skylake/skl-topology.h
+6
-11
sound/soc/intel/skylake/skl.c
sound/soc/intel/skylake/skl.c
+1
-1
sound/soc/intel/skylake/skl.h
sound/soc/intel/skylake/skl.h
+1
-0
sound/soc/soc-core.c
sound/soc/soc-core.c
+5
-0
No files found.
include/sound/soc.h
View file @
0c2964cb
...
...
@@ -497,7 +497,15 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
int
snd_soc_runtime_set_dai_fmt
(
struct
snd_soc_pcm_runtime
*
rtd
,
unsigned
int
dai_fmt
);
#ifdef CONFIG_DMI
int
snd_soc_set_dmi_name
(
struct
snd_soc_card
*
card
,
const
char
*
flavour
);
#else
static
inline
int
snd_soc_set_dmi_name
(
struct
snd_soc_card
*
card
,
const
char
*
flavour
)
{
return
0
;
}
#endif
/* Utility functions to get clock rates from various things */
int
snd_soc_calc_frame_size
(
int
sample_size
,
int
channels
,
int
tdm_slots
);
...
...
sound/hda/hdac_controller.c
View file @
0c2964cb
...
...
@@ -268,7 +268,7 @@ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
unsigned
int
offset
;
unsigned
int
counter
=
0
;
offset
=
snd_hdac_chip_read
l
(
bus
,
LLCH
);
offset
=
snd_hdac_chip_read
w
(
bus
,
LLCH
);
/* Lets walk the linked capabilities list */
do
{
...
...
sound/soc/codecs/hdac_hdmi.c
View file @
0c2964cb
...
...
@@ -469,7 +469,7 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
format
=
snd_hdac_calc_stream_format
(
params_rate
(
hparams
),
params_channels
(
hparams
),
params_format
(
hparams
),
24
,
0
);
dai
->
driver
->
playback
.
sig_bits
,
0
);
pcm
=
hdac_hdmi_get_pcm_from_cvt
(
hdmi
,
dai_map
->
cvt
);
if
(
!
pcm
)
...
...
@@ -1419,8 +1419,8 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdac,
hdmi_dais
[
i
].
playback
.
rate_min
=
rate_min
;
hdmi_dais
[
i
].
playback
.
channels_min
=
2
;
hdmi_dais
[
i
].
playback
.
channels_max
=
2
;
hdmi_dais
[
i
].
playback
.
sig_bits
=
bps
;
hdmi_dais
[
i
].
ops
=
&
hdmi_dai_ops
;
i
++
;
}
...
...
sound/soc/codecs/rt5670.c
View file @
0c2964cb
...
...
@@ -2835,6 +2835,27 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"Wyse 3040"
),
},
},
{
.
ident
=
"Lenovo Thinkpad Tablet 10"
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"LENOVO"
),
DMI_MATCH
(
DMI_PRODUCT_VERSION
,
"ThinkPad 10"
),
},
},
{
.
ident
=
"Lenovo Thinkpad Tablet 10"
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"LENOVO"
),
DMI_MATCH
(
DMI_PRODUCT_VERSION
,
"ThinkPad Tablet B"
),
},
},
{
.
ident
=
"Lenovo Thinkpad Tablet 10"
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"LENOVO"
),
DMI_MATCH
(
DMI_PRODUCT_VERSION
,
"Lenovo Miix 2 10"
),
},
},
{}
};
...
...
sound/soc/intel/Kconfig
View file @
0c2964cb
...
...
@@ -202,6 +202,30 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
platforms with MAX98090 audio codec it also can support TI jack chip as aux device.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with DA7212/7213 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SOC_DA7213
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help
This adds support for ASoC machine driver for Intel(R) Baytrail & CherryTrail
platforms with DA7212/7213 audio codec.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH
tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail platform with no codec (MinnowBoard MAX, Up)"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help
This adds support for ASoC machine driver for the MinnowBoard Max or
Up boards and provides access to I2S signals on the Low-Speed
connector
If unsure select "N".
config SND_SOC_INTEL_SKYLAKE
tristate
select SND_HDA_EXT_CORE
...
...
sound/soc/intel/atom/sst/sst_acpi.c
View file @
0c2964cb
...
...
@@ -420,7 +420,21 @@ static const struct dmi_system_id byt_table[] = {
.
callback
=
byt_thinkpad10_quirk_cb
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"LENOVO"
),
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"20C3001VHH"
),
DMI_MATCH
(
DMI_PRODUCT_VERSION
,
"ThinkPad 10"
),
},
},
{
.
callback
=
byt_thinkpad10_quirk_cb
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"LENOVO"
),
DMI_MATCH
(
DMI_PRODUCT_VERSION
,
"ThinkPad Tablet B"
),
},
},
{
.
callback
=
byt_thinkpad10_quirk_cb
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"LENOVO"
),
DMI_MATCH
(
DMI_PRODUCT_VERSION
,
"Lenovo Miix 2 10"
),
},
},
{
}
...
...
@@ -480,12 +494,23 @@ static struct sst_acpi_mach sst_acpi_bytcr[] = {
&
byt_rvp_platform_data
},
{
"10EC5651"
,
"bytcr_rt5651"
,
"intel/fw_sst_0f28.bin"
,
"bytcr_rt5651"
,
NULL
,
&
byt_rvp_platform_data
},
{
"DLGS7212"
,
"bytcht_da7213"
,
"intel/fw_sst_0f28.bin"
,
"bytcht_da7213"
,
NULL
,
&
byt_rvp_platform_data
},
{
"DLGS7213"
,
"bytcht_da7213"
,
"intel/fw_sst_0f28.bin"
,
"bytcht_da7213"
,
NULL
,
&
byt_rvp_platform_data
},
/* some Baytrail platforms rely on RT5645, use CHT machine driver */
{
"10EC5645"
,
"cht-bsw-rt5645"
,
"intel/fw_sst_0f28.bin"
,
"cht-bsw"
,
NULL
,
&
byt_rvp_platform_data
},
{
"10EC5648"
,
"cht-bsw-rt5645"
,
"intel/fw_sst_0f28.bin"
,
"cht-bsw"
,
NULL
,
&
byt_rvp_platform_data
},
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
/*
* This is always last in the table so that it is selected only when
* enabled explicitly and there is no codec-related information in SSDT
*/
{
"80860F28"
,
"bytcht_nocodec"
,
"intel/fw_sst_0f28.bin"
,
"bytcht_nocodec"
,
NULL
,
&
byt_rvp_platform_data
},
#endif
{},
};
...
...
@@ -504,6 +529,10 @@ static struct sst_acpi_mach sst_acpi_chv[] = {
{
"193C9890"
,
"cht-bsw-max98090"
,
"intel/fw_sst_22a8.bin"
,
"cht-bsw"
,
NULL
,
&
chv_platform_data
},
{
"DLGS7212"
,
"bytcht_da7213"
,
"intel/fw_sst_22a8.bin"
,
"bytcht_da7213"
,
NULL
,
&
chv_platform_data
},
{
"DLGS7213"
,
"bytcht_da7213"
,
"intel/fw_sst_22a8.bin"
,
"bytcht_da7213"
,
NULL
,
&
chv_platform_data
},
/* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
{
"10EC5640"
,
"bytcr_rt5640"
,
"intel/fw_sst_22a8.bin"
,
"bytcr_rt5640"
,
cht_quirk
,
&
chv_platform_data
},
...
...
@@ -512,6 +541,14 @@ static struct sst_acpi_mach sst_acpi_chv[] = {
/* some CHT-T platforms rely on RT5651, use Baytrail machine driver */
{
"10EC5651"
,
"bytcr_rt5651"
,
"intel/fw_sst_22a8.bin"
,
"bytcr_rt5651"
,
NULL
,
&
chv_platform_data
},
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
/*
* This is always last in the table so that it is selected only when
* enabled explicitly and there is no codec-related information in SSDT
*/
{
"808622A8"
,
"bytcht_nocodec"
,
"intel/fw_sst_22a8.bin"
,
"bytcht_nocodec"
,
NULL
,
&
chv_platform_data
},
#endif
{},
};
...
...
sound/soc/intel/atom/sst/sst_ipc.c
View file @
0c2964cb
...
...
@@ -236,7 +236,9 @@ static void process_fw_init(struct intel_sst_drv *sst_drv_ctx,
retval
=
init
->
result
;
goto
ret
;
}
dev_info
(
sst_drv_ctx
->
dev
,
"FW Version %02x.%02x.%02x.%02x
\n
"
,
if
(
memcmp
(
&
sst_drv_ctx
->
fw_version
,
&
init
->
fw_version
,
sizeof
(
init
->
fw_version
)))
dev_info
(
sst_drv_ctx
->
dev
,
"FW Version %02x.%02x.%02x.%02x
\n
"
,
init
->
fw_version
.
type
,
init
->
fw_version
.
major
,
init
->
fw_version
.
minor
,
init
->
fw_version
.
build
);
dev_dbg
(
sst_drv_ctx
->
dev
,
"Build date %s Time %s
\n
"
,
...
...
sound/soc/intel/boards/Makefile
View file @
0c2964cb
...
...
@@ -10,6 +10,8 @@ snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o
snd-soc-sst-cht-bsw-rt5672-objs
:=
cht_bsw_rt5672.o
snd-soc-sst-cht-bsw-rt5645-objs
:=
cht_bsw_rt5645.o
snd-soc-sst-cht-bsw-max98090_ti-objs
:=
cht_bsw_max98090_ti.o
snd-soc-sst-byt-cht-da7213-objs
:=
bytcht_da7213.o
snd-soc-sst-byt-cht-nocodec-objs
:=
bytcht_nocodec.o
snd-soc-skl_rt286-objs
:=
skl_rt286.o
snd-skl_nau88l25_max98357a-objs
:=
skl_nau88l25_max98357a.o
snd-soc-skl_nau88l25_ssm4567-objs
:=
skl_nau88l25_ssm4567.o
...
...
@@ -26,6 +28,8 @@ obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH)
+=
snd-soc-sst-cht-bsw-rt5672.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH)
+=
snd-soc-sst-cht-bsw-rt5645.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH)
+=
snd-soc-sst-cht-bsw-max98090_ti.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH)
+=
snd-soc-sst-byt-cht-da7213.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
+=
snd-soc-sst-byt-cht-nocodec.o
obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH)
+=
snd-soc-skl_rt286.o
obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH)
+=
snd-skl_nau88l25_max98357a.o
obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH)
+=
snd-soc-skl_nau88l25_ssm4567.o
sound/soc/intel/boards/bdw-rt5677.c
View file @
0c2964cb
...
...
@@ -193,13 +193,12 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
RT5677_CLK_SEL_I2S1_ASRC
);
/* Request rt5677 GPIO for headphone amp control */
bdw_rt5677
->
gpio_hp_en
=
devm_gpiod_get
_index
(
codec
->
dev
,
"headphone-enable"
,
0
,
0
);
bdw_rt5677
->
gpio_hp_en
=
devm_gpiod_get
(
codec
->
dev
,
"headphone-enable"
,
GPIOD_OUT_LOW
);
if
(
IS_ERR
(
bdw_rt5677
->
gpio_hp_en
))
{
dev_err
(
codec
->
dev
,
"Can't find HP_AMP_SHDN_L gpio
\n
"
);
return
PTR_ERR
(
bdw_rt5677
->
gpio_hp_en
);
}
gpiod_direction_output
(
bdw_rt5677
->
gpio_hp_en
,
0
);
/* Create and initialize headphone jack */
if
(
!
snd_soc_card_jack_new
(
rtd
->
card
,
"Headphone Jack"
,
...
...
sound/soc/intel/boards/broadwell.c
View file @
0c2964cb
...
...
@@ -269,9 +269,6 @@ static struct snd_soc_card broadwell_rt286 = {
static
int
broadwell_audio_probe
(
struct
platform_device
*
pdev
)
{
broadwell_rt286
.
dev
=
&
pdev
->
dev
;
snd_soc_set_dmi_name
(
&
broadwell_rt286
,
NULL
);
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
broadwell_rt286
);
}
...
...
sound/soc/intel/boards/bxt_da7219_max98357a.c
View file @
0c2964cb
...
...
@@ -55,6 +55,54 @@ enum {
BXT_DPCM_AUDIO_HDMI3_PB
,
};
static
inline
struct
snd_soc_dai
*
bxt_get_codec_dai
(
struct
snd_soc_card
*
card
)
{
struct
snd_soc_pcm_runtime
*
rtd
;
list_for_each_entry
(
rtd
,
&
card
->
rtd_list
,
list
)
{
if
(
!
strncmp
(
rtd
->
codec_dai
->
name
,
BXT_DIALOG_CODEC_DAI
,
strlen
(
BXT_DIALOG_CODEC_DAI
)))
return
rtd
->
codec_dai
;
}
return
NULL
;
}
static
int
platform_clock_control
(
struct
snd_soc_dapm_widget
*
w
,
struct
snd_kcontrol
*
k
,
int
event
)
{
int
ret
=
0
;
struct
snd_soc_dapm_context
*
dapm
=
w
->
dapm
;
struct
snd_soc_card
*
card
=
dapm
->
card
;
struct
snd_soc_dai
*
codec_dai
;
codec_dai
=
bxt_get_codec_dai
(
card
);
if
(
!
codec_dai
)
{
dev_err
(
card
->
dev
,
"Codec dai not found; Unable to set/unset codec pll
\n
"
);
return
-
EIO
;
}
if
(
SND_SOC_DAPM_EVENT_OFF
(
event
))
{
ret
=
snd_soc_dai_set_pll
(
codec_dai
,
0
,
DA7219_SYSCLK_MCLK
,
0
,
0
);
if
(
ret
)
dev_err
(
card
->
dev
,
"failed to stop PLL: %d
\n
"
,
ret
);
}
else
if
(
SND_SOC_DAPM_EVENT_ON
(
event
))
{
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
DA7219_CLKSRC_MCLK
,
19200000
,
SND_SOC_CLOCK_IN
);
if
(
ret
)
dev_err
(
card
->
dev
,
"can't set codec sysclk configuration
\n
"
);
ret
=
snd_soc_dai_set_pll
(
codec_dai
,
0
,
DA7219_SYSCLK_PLL_SRM
,
0
,
DA7219_PLL_FREQ_OUT_98304
);
if
(
ret
)
dev_err
(
card
->
dev
,
"failed to start PLL: %d
\n
"
,
ret
);
}
return
ret
;
}
static
const
struct
snd_kcontrol_new
broxton_controls
[]
=
{
SOC_DAPM_PIN_SWITCH
(
"Headphone Jack"
),
SOC_DAPM_PIN_SWITCH
(
"Headset Mic"
),
...
...
@@ -69,6 +117,8 @@ static const struct snd_soc_dapm_widget broxton_widgets[] = {
SND_SOC_DAPM_SPK
(
"HDMI1"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI2"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI3"
,
NULL
),
SND_SOC_DAPM_SUPPLY
(
"Platform Clock"
,
SND_SOC_NOPM
,
0
,
0
,
platform_clock_control
,
SND_SOC_DAPM_POST_PMD
|
SND_SOC_DAPM_PRE_PMU
),
};
static
const
struct
snd_soc_dapm_route
broxton_map
[]
=
{
...
...
@@ -109,6 +159,9 @@ static const struct snd_soc_dapm_route broxton_map[] = {
/* DMIC */
{
"dmic01_hifi"
,
NULL
,
"DMIC01 Rx"
},
{
"DMIC01 Rx"
,
NULL
,
"DMIC AIF"
},
{
"Headphone Jack"
,
NULL
,
"Platform Clock"
},
{
"Headset Mic"
,
NULL
,
"Platform Clock"
},
};
static
int
broxton_ssp_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
...
...
@@ -243,49 +296,6 @@ static const struct snd_soc_ops broxton_da7219_fe_ops = {
.
startup
=
bxt_fe_startup
,
};
static
int
broxton_da7219_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
;
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
DA7219_CLKSRC_MCLK
,
19200000
,
SND_SOC_CLOCK_IN
);
if
(
ret
<
0
)
dev_err
(
codec_dai
->
dev
,
"can't set codec sysclk configuration
\n
"
);
ret
=
snd_soc_dai_set_pll
(
codec_dai
,
0
,
DA7219_SYSCLK_PLL_SRM
,
0
,
DA7219_PLL_FREQ_OUT_98304
);
if
(
ret
<
0
)
{
dev_err
(
codec_dai
->
dev
,
"failed to start PLL: %d
\n
"
,
ret
);
return
-
EIO
;
}
return
ret
;
}
static
int
broxton_da7219_hw_free
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
;
ret
=
snd_soc_dai_set_pll
(
codec_dai
,
0
,
DA7219_SYSCLK_MCLK
,
0
,
0
);
if
(
ret
<
0
)
{
dev_err
(
codec_dai
->
dev
,
"failed to stop PLL: %d
\n
"
,
ret
);
return
-
EIO
;
}
return
ret
;
}
static
const
struct
snd_soc_ops
broxton_da7219_ops
=
{
.
hw_params
=
broxton_da7219_hw_params
,
.
hw_free
=
broxton_da7219_hw_free
,
};
static
int
broxton_dmic_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
struct
snd_pcm_hw_params
*
params
)
{
...
...
@@ -467,7 +477,6 @@ static struct snd_soc_dai_link broxton_dais[] = {
SND_SOC_DAIFMT_CBS_CFS
,
.
ignore_pmdown_time
=
1
,
.
be_hw_params_fixup
=
broxton_ssp_fixup
,
.
ops
=
&
broxton_da7219_ops
,
.
dpcm_playback
=
1
,
.
dpcm_capture
=
1
,
},
...
...
sound/soc/intel/boards/bxt_rt298.c
View file @
0c2964cb
...
...
@@ -274,12 +274,15 @@ static int bxt_fe_startup(struct snd_pcm_substream *substream)
* on this platform for PCM device we support:
* 48Khz
* stereo
* 16-bit audio
*/
runtime
->
hw
.
channels_max
=
2
;
snd_pcm_hw_constraint_list
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
&
constraints_channels
);
runtime
->
hw
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
;
snd_pcm_hw_constraint_msbits
(
runtime
,
0
,
16
,
16
);
snd_pcm_hw_constraint_list
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_RATE
,
&
constraints_rates
);
...
...
sound/soc/intel/boards/bytcht_da7213.c
0 → 100644
View file @
0c2964cb
/*
* bytcht-da7213.c - ASoc Machine driver for Intel Baytrail and
* Cherrytrail-based platforms, with Dialog DA7213 codec
*
* Copyright (C) 2017 Intel Corporation
* Author: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <linux/module.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <asm/platform_sst_audio.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "../../codecs/da7213.h"
#include "../atom/sst-atom-controls.h"
#include "../common/sst-acpi.h"
static
const
struct
snd_kcontrol_new
controls
[]
=
{
SOC_DAPM_PIN_SWITCH
(
"Headphone Jack"
),
SOC_DAPM_PIN_SWITCH
(
"Headset Mic"
),
SOC_DAPM_PIN_SWITCH
(
"Mic"
),
SOC_DAPM_PIN_SWITCH
(
"Aux In"
),
};
static
const
struct
snd_soc_dapm_widget
dapm_widgets
[]
=
{
SND_SOC_DAPM_HP
(
"Headphone Jack"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Headset Mic"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Mic"
,
NULL
),
SND_SOC_DAPM_LINE
(
"Aux In"
,
NULL
),
};
static
const
struct
snd_soc_dapm_route
audio_map
[]
=
{
{
"Headphone Jack"
,
NULL
,
"HPL"
},
{
"Headphone Jack"
,
NULL
,
"HPR"
},
{
"AUXL"
,
NULL
,
"Aux In"
},
{
"AUXR"
,
NULL
,
"Aux In"
},
/* Assume Mic1 is linked to Headset and Mic2 to on-board mic */
{
"MIC1"
,
NULL
,
"Headset Mic"
},
{
"MIC2"
,
NULL
,
"Mic"
},
/* SOC-codec link */
{
"ssp2 Tx"
,
NULL
,
"codec_out0"
},
{
"ssp2 Tx"
,
NULL
,
"codec_out1"
},
{
"codec_in0"
,
NULL
,
"ssp2 Rx"
},
{
"codec_in1"
,
NULL
,
"ssp2 Rx"
},
{
"Playback"
,
NULL
,
"ssp2 Tx"
},
{
"ssp2 Rx"
,
NULL
,
"Capture"
},
};
static
int
codec_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
struct
snd_pcm_hw_params
*
params
)
{
int
ret
;
struct
snd_interval
*
rate
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_RATE
);
struct
snd_interval
*
channels
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_CHANNELS
);
/* The DSP will convert the FE rate to 48k, stereo, 24bits */
rate
->
min
=
rate
->
max
=
48000
;
channels
->
min
=
channels
->
max
=
2
;
/* set SSP2 to 24-bit */
params_set_format
(
params
,
SNDRV_PCM_FORMAT_S24_LE
);
/*
* Default mode for SSP configuration is TDM 4 slot, override config
* with explicit setting to I2S 2ch 24-bit. The word length is set with
* dai_set_tdm_slot() since there is no other API exposed
*/
ret
=
snd_soc_dai_set_fmt
(
rtd
->
cpu_dai
,
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBS_CFS
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"can't set format to I2S, err %d
\n
"
,
ret
);
return
ret
;
}
ret
=
snd_soc_dai_set_tdm_slot
(
rtd
->
cpu_dai
,
0x3
,
0x3
,
2
,
24
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"can't set I2S config, err %d
\n
"
,
ret
);
return
ret
;
}
return
0
;
}
static
int
aif1_startup
(
struct
snd_pcm_substream
*
substream
)
{
return
snd_pcm_hw_constraint_single
(
substream
->
runtime
,
SNDRV_PCM_HW_PARAM_RATE
,
48000
);
}
static
int
aif1_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
;
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
DA7213_CLKSRC_MCLK
,
19200000
,
SND_SOC_CLOCK_IN
);
if
(
ret
<
0
)
dev_err
(
codec_dai
->
dev
,
"can't set codec sysclk configuration
\n
"
);
ret
=
snd_soc_dai_set_pll
(
codec_dai
,
0
,
DA7213_SYSCLK_PLL_SRM
,
0
,
DA7213_PLL_FREQ_OUT_98304000
);
if
(
ret
<
0
)
{
dev_err
(
codec_dai
->
dev
,
"failed to start PLL: %d
\n
"
,
ret
);
return
-
EIO
;
}
return
ret
;
}
static
int
aif1_hw_free
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
;
ret
=
snd_soc_dai_set_pll
(
codec_dai
,
0
,
DA7213_SYSCLK_MCLK
,
0
,
0
);
if
(
ret
<
0
)
{
dev_err
(
codec_dai
->
dev
,
"failed to stop PLL: %d
\n
"
,
ret
);
return
-
EIO
;
}
return
ret
;
}
static
const
struct
snd_soc_ops
aif1_ops
=
{
.
startup
=
aif1_startup
,
};
static
const
struct
snd_soc_ops
ssp2_ops
=
{
.
hw_params
=
aif1_hw_params
,
.
hw_free
=
aif1_hw_free
,
};
static
struct
snd_soc_dai_link
dailink
[]
=
{
[
MERR_DPCM_AUDIO
]
=
{
.
name
=
"Audio Port"
,
.
stream_name
=
"Audio"
,
.
cpu_dai_name
=
"media-cpu-dai"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
codec_name
=
"snd-soc-dummy"
,
.
platform_name
=
"sst-mfld-platform"
,
.
nonatomic
=
true
,
.
dynamic
=
1
,
.
dpcm_playback
=
1
,
.
dpcm_capture
=
1
,
.
ops
=
&
aif1_ops
,
},
[
MERR_DPCM_DEEP_BUFFER
]
=
{
.
name
=
"Deep-Buffer Audio Port"
,
.
stream_name
=
"Deep-Buffer Audio"
,
.
cpu_dai_name
=
"deepbuffer-cpu-dai"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
codec_name
=
"snd-soc-dummy"
,
.
platform_name
=
"sst-mfld-platform"
,
.
nonatomic
=
true
,
.
dynamic
=
1
,
.
dpcm_playback
=
1
,
.
ops
=
&
aif1_ops
,
},
[
MERR_DPCM_COMPR
]
=
{
.
name
=
"Compressed Port"
,
.
stream_name
=
"Compress"
,
.
cpu_dai_name
=
"compress-cpu-dai"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
codec_name
=
"snd-soc-dummy"
,
.
platform_name
=
"sst-mfld-platform"
,
},
/* CODEC<->CODEC link */
/* back ends */
{
.
name
=
"SSP2-Codec"
,
.
id
=
1
,
.
cpu_dai_name
=
"ssp2-port"
,
.
platform_name
=
"sst-mfld-platform"
,
.
no_pcm
=
1
,
.
codec_dai_name
=
"da7213-hifi"
,
.
codec_name
=
"i2c-DLGS7213:00"
,
.
dai_fmt
=
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBS_CFS
,
.
be_hw_params_fixup
=
codec_fixup
,
.
nonatomic
=
true
,
.
dpcm_playback
=
1
,
.
dpcm_capture
=
1
,
.
ops
=
&
ssp2_ops
,
},
};
/* SoC card */
static
struct
snd_soc_card
bytcht_da7213_card
=
{
.
name
=
"bytcht-da7213"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
dailink
,
.
num_links
=
ARRAY_SIZE
(
dailink
),
.
controls
=
controls
,
.
num_controls
=
ARRAY_SIZE
(
controls
),
.
dapm_widgets
=
dapm_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
dapm_widgets
),
.
dapm_routes
=
audio_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
audio_map
),
};
static
char
codec_name
[
16
];
/* i2c-<HID>:00 with HID being 8 chars */
static
int
bytcht_da7213_probe
(
struct
platform_device
*
pdev
)
{
int
ret_val
=
0
;
int
i
;
struct
snd_soc_card
*
card
;
struct
sst_acpi_mach
*
mach
;
const
char
*
i2c_name
=
NULL
;
int
dai_index
=
0
;
mach
=
(
&
pdev
->
dev
)
->
platform_data
;
card
=
&
bytcht_da7213_card
;
card
->
dev
=
&
pdev
->
dev
;
/* fix index of codec dai */
dai_index
=
MERR_DPCM_COMPR
+
1
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
dailink
);
i
++
)
{
if
(
!
strcmp
(
dailink
[
i
].
codec_name
,
"i2c-DLGS7213:00"
))
{
dai_index
=
i
;
break
;
}
}
/* fixup codec name based on HID */
i2c_name
=
sst_acpi_find_name_from_hid
(
mach
->
id
);
if
(
i2c_name
!=
NULL
)
{
snprintf
(
codec_name
,
sizeof
(
codec_name
),
"%s%s"
,
"i2c-"
,
i2c_name
);
dailink
[
dai_index
].
codec_name
=
codec_name
;
}
ret_val
=
devm_snd_soc_register_card
(
&
pdev
->
dev
,
card
);
if
(
ret_val
)
{
dev_err
(
&
pdev
->
dev
,
"snd_soc_register_card failed %d
\n
"
,
ret_val
);
return
ret_val
;
}
platform_set_drvdata
(
pdev
,
card
);
return
ret_val
;
}
static
struct
platform_driver
bytcht_da7213_driver
=
{
.
driver
=
{
.
name
=
"bytcht_da7213"
,
},
.
probe
=
bytcht_da7213_probe
,
};
module_platform_driver
(
bytcht_da7213_driver
);
MODULE_DESCRIPTION
(
"ASoC Intel(R) Baytrail/Cherrytrail+DA7213 Machine driver"
);
MODULE_AUTHOR
(
"Pierre-Louis Bossart"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_ALIAS
(
"platform:bytcht_da7213"
);
sound/soc/intel/boards/bytcht_nocodec.c
0 → 100644
View file @
0c2964cb
/*
* bytcht_nocodec.c - ASoc Machine driver for MinnowBoard Max and Up
* to make I2S signals observable on the Low-Speed connector. Audio codec
* is not managed by ASoC/DAPM
*
* Copyright (C) 2015-2017 Intel Corp
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <linux/module.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "../atom/sst-atom-controls.h"
static
const
struct
snd_soc_dapm_widget
widgets
[]
=
{
SND_SOC_DAPM_MIC
(
"Mic"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Speaker"
,
NULL
),
};
static
const
struct
snd_kcontrol_new
controls
[]
=
{
SOC_DAPM_PIN_SWITCH
(
"Mic"
),
SOC_DAPM_PIN_SWITCH
(
"Speaker"
),
};
static
const
struct
snd_soc_dapm_route
audio_map
[]
=
{
{
"ssp2 Tx"
,
NULL
,
"codec_out0"
},
{
"ssp2 Tx"
,
NULL
,
"codec_out1"
},
{
"codec_in0"
,
NULL
,
"ssp2 Rx"
},
{
"codec_in1"
,
NULL
,
"ssp2 Rx"
},
{
"ssp2 Rx"
,
NULL
,
"Mic"
},
{
"Speaker"
,
NULL
,
"ssp2 Tx"
},
};
static
int
codec_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_interval
*
rate
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_RATE
);
struct
snd_interval
*
channels
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_CHANNELS
);
int
ret
;
/* The DSP will convert the FE rate to 48k, stereo, 24bits */
rate
->
min
=
rate
->
max
=
48000
;
channels
->
min
=
channels
->
max
=
2
;
/* set SSP2 to 24-bit */
params_set_format
(
params
,
SNDRV_PCM_FORMAT_S24_LE
);
/*
* Default mode for SSP configuration is TDM 4 slot, override config
* with explicit setting to I2S 2ch 24-bit. The word length is set with
* dai_set_tdm_slot() since there is no other API exposed
*/
ret
=
snd_soc_dai_set_fmt
(
rtd
->
cpu_dai
,
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBS_CFS
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"can't set format to I2S, err %d
\n
"
,
ret
);
return
ret
;
}
ret
=
snd_soc_dai_set_tdm_slot
(
rtd
->
cpu_dai
,
0x3
,
0x3
,
2
,
24
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"can't set I2S config, err %d
\n
"
,
ret
);
return
ret
;
}
return
0
;
}
static
unsigned
int
rates_48000
[]
=
{
48000
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_48000
=
{
.
count
=
ARRAY_SIZE
(
rates_48000
),
.
list
=
rates_48000
,
};
static
int
aif1_startup
(
struct
snd_pcm_substream
*
substream
)
{
return
snd_pcm_hw_constraint_list
(
substream
->
runtime
,
0
,
SNDRV_PCM_HW_PARAM_RATE
,
&
constraints_48000
);
}
static
struct
snd_soc_ops
aif1_ops
=
{
.
startup
=
aif1_startup
,
};
static
struct
snd_soc_dai_link
dais
[]
=
{
[
MERR_DPCM_AUDIO
]
=
{
.
name
=
"Audio Port"
,
.
stream_name
=
"Audio"
,
.
cpu_dai_name
=
"media-cpu-dai"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
codec_name
=
"snd-soc-dummy"
,
.
platform_name
=
"sst-mfld-platform"
,
.
ignore_suspend
=
1
,
.
nonatomic
=
true
,
.
dynamic
=
1
,
.
dpcm_playback
=
1
,
.
dpcm_capture
=
1
,
.
ops
=
&
aif1_ops
,
},
[
MERR_DPCM_DEEP_BUFFER
]
=
{
.
name
=
"Deep-Buffer Audio Port"
,
.
stream_name
=
"Deep-Buffer Audio"
,
.
cpu_dai_name
=
"deepbuffer-cpu-dai"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
codec_name
=
"snd-soc-dummy"
,
.
platform_name
=
"sst-mfld-platform"
,
.
ignore_suspend
=
1
,
.
nonatomic
=
true
,
.
dynamic
=
1
,
.
dpcm_playback
=
1
,
.
ops
=
&
aif1_ops
,
},
[
MERR_DPCM_COMPR
]
=
{
.
name
=
"Compressed Port"
,
.
stream_name
=
"Compress"
,
.
cpu_dai_name
=
"compress-cpu-dai"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
codec_name
=
"snd-soc-dummy"
,
.
platform_name
=
"sst-mfld-platform"
,
},
/* CODEC<->CODEC link */
/* back ends */
{
.
name
=
"SSP2-LowSpeed Connector"
,
.
id
=
1
,
.
cpu_dai_name
=
"ssp2-port"
,
.
platform_name
=
"sst-mfld-platform"
,
.
no_pcm
=
1
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
codec_name
=
"snd-soc-dummy"
,
.
dai_fmt
=
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBS_CFS
,
.
be_hw_params_fixup
=
codec_fixup
,
.
ignore_suspend
=
1
,
.
nonatomic
=
true
,
.
dpcm_playback
=
1
,
.
dpcm_capture
=
1
,
},
};
/* SoC card */
static
struct
snd_soc_card
bytcht_nocodec_card
=
{
.
name
=
"bytcht-nocodec"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
dais
,
.
num_links
=
ARRAY_SIZE
(
dais
),
.
dapm_widgets
=
widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
widgets
),
.
dapm_routes
=
audio_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
audio_map
),
.
controls
=
controls
,
.
num_controls
=
ARRAY_SIZE
(
controls
),
.
fully_routed
=
true
,
};
static
int
snd_bytcht_nocodec_mc_probe
(
struct
platform_device
*
pdev
)
{
int
ret_val
=
0
;
/* register the soc card */
bytcht_nocodec_card
.
dev
=
&
pdev
->
dev
;
ret_val
=
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
bytcht_nocodec_card
);
if
(
ret_val
)
{
dev_err
(
&
pdev
->
dev
,
"devm_snd_soc_register_card failed %d
\n
"
,
ret_val
);
return
ret_val
;
}
platform_set_drvdata
(
pdev
,
&
bytcht_nocodec_card
);
return
ret_val
;
}
static
struct
platform_driver
snd_bytcht_nocodec_mc_driver
=
{
.
driver
=
{
.
name
=
"bytcht_nocodec"
,
},
.
probe
=
snd_bytcht_nocodec_mc_probe
,
};
module_platform_driver
(
snd_bytcht_nocodec_mc_driver
);
MODULE_DESCRIPTION
(
"ASoC Intel(R) Baytrail/Cherrytrail Nocodec Machine driver"
);
MODULE_AUTHOR
(
"Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_ALIAS
(
"platform:bytcht_nocodec"
);
sound/soc/intel/boards/bytcr_rt5640.c
View file @
0c2964cb
...
...
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
#include <linux/device.h>
...
...
@@ -56,35 +57,88 @@ enum {
struct
byt_rt5640_private
{
struct
clk
*
mclk
;
};
static
bool
is_bytcr
;
static
unsigned
long
byt_rt5640_quirk
=
BYT_RT5640_MCLK_EN
;
static
unsigned
int
quirk_override
;
module_param_named
(
quirk
,
quirk_override
,
uint
,
0444
);
MODULE_PARM_DESC
(
quirk
,
"Board-specific quirk override"
);
static
void
log_quirks
(
struct
device
*
dev
)
{
if
(
BYT_RT5640_MAP
(
byt_rt5640_quirk
)
==
BYT_RT5640_DMIC1_MAP
)
dev_info
(
dev
,
"quirk DMIC1_MAP enabled"
);
if
(
BYT_RT5640_MAP
(
byt_rt5640_quirk
)
==
BYT_RT5640_DMIC2_MAP
)
dev_info
(
dev
,
"quirk DMIC2_MAP enabled"
);
if
(
BYT_RT5640_MAP
(
byt_rt5640_quirk
)
==
BYT_RT5640_IN1_MAP
)
dev_info
(
dev
,
"quirk IN1_MAP enabled"
);
if
(
BYT_RT5640_MAP
(
byt_rt5640_quirk
)
==
BYT_RT5640_IN3_MAP
)
dev_info
(
dev
,
"quirk IN3_MAP enabled"
);
if
(
byt_rt5640_quirk
&
BYT_RT5640_DMIC_EN
)
dev_info
(
dev
,
"quirk DMIC enabled"
);
int
map
;
bool
has_dmic
=
false
;
bool
has_mclk
=
false
;
bool
has_ssp0
=
false
;
bool
has_ssp0_aif1
=
false
;
bool
has_ssp0_aif2
=
false
;
bool
has_ssp2_aif2
=
false
;
map
=
BYT_RT5640_MAP
(
byt_rt5640_quirk
);
switch
(
map
)
{
case
BYT_RT5640_DMIC1_MAP
:
dev_info
(
dev
,
"quirk DMIC1_MAP enabled
\n
"
);
has_dmic
=
true
;
break
;
case
BYT_RT5640_DMIC2_MAP
:
dev_info
(
dev
,
"quirk DMIC2_MAP enabled
\n
"
);
has_dmic
=
true
;
break
;
case
BYT_RT5640_IN1_MAP
:
dev_info
(
dev
,
"quirk IN1_MAP enabled
\n
"
);
break
;
case
BYT_RT5640_IN3_MAP
:
dev_info
(
dev
,
"quirk IN3_MAP enabled
\n
"
);
break
;
default:
dev_err
(
dev
,
"quirk map 0x%x is not supported, microphone input will not work
\n
"
,
map
);
break
;
}
if
(
byt_rt5640_quirk
&
BYT_RT5640_DMIC_EN
)
{
if
(
has_dmic
)
dev_info
(
dev
,
"quirk DMIC enabled
\n
"
);
else
dev_err
(
dev
,
"quirk DMIC enabled but no DMIC input set, will be ignored
\n
"
);
}
if
(
byt_rt5640_quirk
&
BYT_RT5640_MONO_SPEAKER
)
dev_info
(
dev
,
"quirk MONO_SPEAKER enabled"
);
if
(
byt_rt5640_quirk
&
BYT_RT5640_DIFF_MIC
)
dev_info
(
dev
,
"quirk DIFF_MIC enabled"
);
if
(
byt_rt5640_quirk
&
BYT_RT5640_SSP2_AIF2
)
dev_info
(
dev
,
"quirk SSP2_AIF2 enabled"
);
if
(
byt_rt5640_quirk
&
BYT_RT5640_SSP0_AIF1
)
dev_info
(
dev
,
"quirk SSP0_AIF1 enabled"
);
if
(
byt_rt5640_quirk
&
BYT_RT5640_SSP0_AIF2
)
dev_info
(
dev
,
"quirk SSP0_AIF2 enabled"
);
if
(
byt_rt5640_quirk
&
BYT_RT5640_MCLK_EN
)
dev_info
(
dev
,
"quirk MCLK_EN enabled"
);
if
(
byt_rt5640_quirk
&
BYT_RT5640_MCLK_25MHZ
)
dev_info
(
dev
,
"quirk MCLK_25MHZ enabled"
);
dev_info
(
dev
,
"quirk MONO_SPEAKER enabled
\n
"
);
if
(
byt_rt5640_quirk
&
BYT_RT5640_DIFF_MIC
)
{
if
(
!
has_dmic
)
dev_info
(
dev
,
"quirk DIFF_MIC enabled
\n
"
);
else
dev_info
(
dev
,
"quirk DIFF_MIC enabled but DMIC input selected, will be ignored
\n
"
);
}
if
(
byt_rt5640_quirk
&
BYT_RT5640_SSP0_AIF1
)
{
dev_info
(
dev
,
"quirk SSP0_AIF1 enabled
\n
"
);
has_ssp0
=
true
;
has_ssp0_aif1
=
true
;
}
if
(
byt_rt5640_quirk
&
BYT_RT5640_SSP0_AIF2
)
{
dev_info
(
dev
,
"quirk SSP0_AIF2 enabled
\n
"
);
has_ssp0
=
true
;
has_ssp0_aif2
=
true
;
}
if
(
byt_rt5640_quirk
&
BYT_RT5640_SSP2_AIF2
)
{
dev_info
(
dev
,
"quirk SSP2_AIF2 enabled
\n
"
);
has_ssp2_aif2
=
true
;
}
if
(
is_bytcr
&&
!
has_ssp0
)
dev_err
(
dev
,
"Invalid routing, bytcr detected but no SSP0-based quirk, audio cannot work with SSP2 on bytcr
\n
"
);
if
(
has_ssp0_aif1
&&
has_ssp0_aif2
)
dev_err
(
dev
,
"Invalid routing, SSP0 cannot be connected to both AIF1 and AIF2
\n
"
);
if
(
has_ssp0
&&
has_ssp2_aif2
)
dev_err
(
dev
,
"Invalid routing, cannot have both SSP0 and SSP2 connected to codec
\n
"
);
if
(
byt_rt5640_quirk
&
BYT_RT5640_MCLK_EN
)
{
dev_info
(
dev
,
"quirk MCLK_EN enabled
\n
"
);
has_mclk
=
true
;
}
if
(
byt_rt5640_quirk
&
BYT_RT5640_MCLK_25MHZ
)
{
if
(
has_mclk
)
dev_info
(
dev
,
"quirk MCLK_25MHZ enabled
\n
"
);
else
dev_err
(
dev
,
"quirk MCLK_25MHZ enabled but quirk MCLK not selected, will be ignored
\n
"
);
}
}
...
...
@@ -128,7 +182,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
ret
=
clk_prepare_enable
(
priv
->
mclk
);
if
(
ret
<
0
)
{
dev_err
(
card
->
dev
,
"could not configure MCLK state"
);
"could not configure MCLK state
\n
"
);
return
ret
;
}
}
...
...
@@ -710,8 +764,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
int
i
;
int
dai_index
;
struct
byt_rt5640_private
*
priv
;
bool
is_bytcr
=
false
;
is_bytcr
=
false
;
priv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
priv
),
GFP_ATOMIC
);
if
(
!
priv
)
return
-
ENOMEM
;
...
...
@@ -806,6 +860,11 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
/* check quirks before creating card */
dmi_check_system
(
byt_rt5640_quirk_table
);
if
(
quirk_override
)
{
dev_info
(
&
pdev
->
dev
,
"Overriding quirk 0x%x => 0x%x
\n
"
,
(
unsigned
int
)
byt_rt5640_quirk
,
quirk_override
);
byt_rt5640_quirk
=
quirk_override
;
}
log_quirks
(
&
pdev
->
dev
);
if
((
byt_rt5640_quirk
&
BYT_RT5640_SSP2_AIF2
)
||
...
...
sound/soc/intel/haswell/sst-haswell-ipc.c
View file @
0c2964cb
...
...
@@ -2000,10 +2000,8 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
u32
param_size
,
char
*
param
)
{
int
ret
;
unsigned
char
*
data
=
NULL
;
u32
header
=
0
;
u32
payload_size
=
0
,
transfer_parameter_size
=
0
;
dma_addr_t
dma_addr
=
0
;
struct
sst_hsw_transfer_parameter
*
parameter
;
struct
device
*
dev
=
hsw
->
dev
;
...
...
@@ -2047,10 +2045,6 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
kfree
(
parameter
);
if
(
data
)
dma_free_coherent
(
hsw
->
dsp
->
dma_dev
,
param_size
,
(
void
*
)
data
,
dma_addr
);
return
ret
;
}
...
...
sound/soc/intel/skylake/bxt-sst.c
View file @
0c2964cb
...
...
@@ -25,7 +25,8 @@
#include "skl-sst-ipc.h"
#define BXT_BASEFW_TIMEOUT 3000
#define BXT_INIT_TIMEOUT 500
#define BXT_INIT_TIMEOUT 300
#define BXT_ROM_INIT_TIMEOUT 70
#define BXT_IPC_PURGE_FW 0x01004000
#define BXT_ROM_INIT 0x5
...
...
@@ -45,6 +46,8 @@
/* Delay before scheduling D0i3 entry */
#define BXT_D0I3_DELAY 5000
#define BXT_FW_ROM_INIT_RETRY 3
static
unsigned
int
bxt_get_errorcode
(
struct
sst_dsp
*
ctx
)
{
return
sst_dsp_shim_read
(
ctx
,
BXT_ADSP_ERROR_CODE
);
...
...
@@ -55,29 +58,15 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
{
struct
snd_dma_buffer
dmab
;
struct
skl_sst
*
skl
=
ctx
->
thread_context
;
const
struct
firmware
*
fw
=
NULL
;
struct
firmware
stripped_fw
;
int
ret
=
0
,
i
,
dma_id
,
stream_tag
;
/* library indices start from 1 to N. 0 represents base FW */
for
(
i
=
1
;
i
<
lib_count
;
i
++
)
{
ret
=
request_firmware
(
&
fw
,
linfo
[
i
].
name
,
ctx
->
dev
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Request lib %s failed:%d
\n
"
,
linfo
[
i
].
name
,
ret
);
return
ret
;
}
if
(
skl
->
is_first_boot
)
{
ret
=
snd_skl_parse_uuids
(
ctx
,
fw
,
ret
=
skl_prepare_lib_load
(
skl
,
&
skl
->
lib_info
[
i
],
&
stripped_fw
,
BXT_ADSP_FW_BIN_HDR_OFFSET
,
i
);
if
(
ret
<
0
)
goto
load_library_failed
;
}
stripped_fw
.
data
=
fw
->
data
;
stripped_fw
.
size
=
fw
->
size
;
skl_dsp_strip_extended_manifest
(
&
stripped_fw
);
if
(
ret
<
0
)
goto
load_library_failed
;
stream_tag
=
ctx
->
dsp_ops
.
prepare
(
ctx
->
dev
,
0x40
,
stripped_fw
.
size
,
&
dmab
);
...
...
@@ -92,21 +81,19 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
memcpy
(
dmab
.
area
,
stripped_fw
.
data
,
stripped_fw
.
size
);
ctx
->
dsp_ops
.
trigger
(
ctx
->
dev
,
true
,
stream_tag
);
ret
=
skl_sst_ipc_load_library
(
&
skl
->
ipc
,
dma_id
,
i
);
ret
=
skl_sst_ipc_load_library
(
&
skl
->
ipc
,
dma_id
,
i
,
true
);
if
(
ret
<
0
)
dev_err
(
ctx
->
dev
,
"IPC Load Lib for %s fail: %d
\n
"
,
linfo
[
i
].
name
,
ret
);
ctx
->
dsp_ops
.
trigger
(
ctx
->
dev
,
false
,
stream_tag
);
ctx
->
dsp_ops
.
cleanup
(
ctx
->
dev
,
&
dmab
,
stream_tag
);
release_firmware
(
fw
);
fw
=
NULL
;
}
return
ret
;
load_library_failed:
release_firmware
(
fw
);
skl_release_library
(
linfo
,
lib_count
);
return
ret
;
}
...
...
@@ -156,7 +143,7 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
SKL_ADSP_REG_HIPCIE_DONE
,
BXT_INIT_TIMEOUT
,
"HIPCIE Done"
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Timout for Purge Request%d
\n
"
,
ret
);
dev_err
(
ctx
->
dev
,
"Tim
e
out for Purge Request%d
\n
"
,
ret
);
goto
base_fw_load_failed
;
}
...
...
@@ -173,7 +160,7 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
/* Step 7: Wait for ROM init */
ret
=
sst_dsp_register_poll
(
ctx
,
BXT_ADSP_FW_STATUS
,
SKL_FW_STS_MASK
,
SKL_FW_INIT
,
BXT_INIT_TIMEOUT
,
"ROM Load"
);
SKL_FW_INIT
,
BXT_
ROM_
INIT_TIMEOUT
,
"ROM Load"
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Timeout for ROM init, ret:%d
\n
"
,
ret
);
goto
base_fw_load_failed
;
...
...
@@ -206,18 +193,16 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
{
struct
firmware
stripped_fw
;
struct
skl_sst
*
skl
=
ctx
->
thread_context
;
int
ret
;
int
ret
,
i
;
ret
=
request_firmware
(
&
ctx
->
fw
,
ctx
->
fw_name
,
ctx
->
dev
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Request firmware failed %d
\n
"
,
ret
);
goto
sst_load_base_firmware_failed
;
if
(
ctx
->
fw
==
NULL
)
{
ret
=
request_firmware
(
&
ctx
->
fw
,
ctx
->
fw_name
,
ctx
->
dev
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Request firmware failed %d
\n
"
,
ret
);
return
ret
;
}
}
/* check for extended manifest */
if
(
ctx
->
fw
==
NULL
)
goto
sst_load_base_firmware_failed
;
/* prase uuids on first boot */
if
(
skl
->
is_first_boot
)
{
ret
=
snd_skl_parse_uuids
(
ctx
,
ctx
->
fw
,
BXT_ADSP_FW_BIN_HDR_OFFSET
,
0
);
...
...
@@ -229,18 +214,20 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
stripped_fw
.
size
=
ctx
->
fw
->
size
;
skl_dsp_strip_extended_manifest
(
&
stripped_fw
);
ret
=
sst_bxt_prepare_fw
(
ctx
,
stripped_fw
.
data
,
stripped_fw
.
size
);
/* Retry Enabling core and ROM load. Retry seemed to help */
if
(
ret
<
0
)
{
for
(
i
=
0
;
i
<
BXT_FW_ROM_INIT_RETRY
;
i
++
)
{
ret
=
sst_bxt_prepare_fw
(
ctx
,
stripped_fw
.
data
,
stripped_fw
.
size
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Error code=0x%x: FW status=0x%x
\n
"
,
if
(
ret
==
0
)
break
;
}
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Error code=0x%x: FW status=0x%x
\n
"
,
sst_dsp_shim_read
(
ctx
,
BXT_ADSP_ERROR_CODE
),
sst_dsp_shim_read
(
ctx
,
BXT_ADSP_FW_STATUS
));
dev_err
(
ctx
->
dev
,
"Core En/ROM load fail:%d
\n
"
,
ret
);
goto
sst_load_base_firmware_failed
;
}
dev_err
(
ctx
->
dev
,
"Core En/ROM load fail:%d
\n
"
,
ret
);
goto
sst_load_base_firmware_failed
;
}
ret
=
sst_transfer_fw_host_dma
(
ctx
);
...
...
@@ -265,8 +252,11 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
}
}
return
ret
;
sst_load_base_firmware_failed:
release_firmware
(
ctx
->
fw
);
ctx
->
fw
=
NULL
;
return
ret
;
}
...
...
@@ -428,6 +418,7 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
return
ret
;
}
}
skl
->
cores
.
state
[
core_id
]
=
SKL_DSP_RUNNING
;
return
ret
;
}
...
...
@@ -514,11 +505,22 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
ret
=
skl_ipc_set_dx
(
&
skl
->
ipc
,
BXT_INSTANCE_ID
,
BXT_BASE_FW_MODULE_ID
,
&
dx
);
if
(
ret
<
0
)
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Failed to set DSP to D3:core id = %d;Continue reset
\n
"
,
core_id
);
/*
* In case of D3 failure, re-download the firmware, so set
* fw_loaded to false.
*/
skl
->
fw_loaded
=
false
;
}
if
(
core_id
==
SKL_DSP_CORE0_ID
)
{
/* disable Interrupt */
skl_ipc_op_int_disable
(
ctx
);
skl_ipc_int_disable
(
ctx
);
}
ret
=
skl_dsp_disable_core
(
ctx
,
core_mask
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Failed to disable core %d
\n
"
,
ret
);
...
...
@@ -560,23 +562,14 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
struct
sst_dsp
*
sst
;
int
ret
;
skl
=
devm_kzalloc
(
dev
,
sizeof
(
*
skl
),
GFP_KERNEL
);
if
(
skl
==
NULL
)
return
-
ENOMEM
;
skl
->
dev
=
dev
;
skl_dev
.
thread_context
=
skl
;
INIT_LIST_HEAD
(
&
skl
->
uuid_list
);
skl
->
dsp
=
skl_dsp_ctx_init
(
dev
,
&
skl_dev
,
irq
);
if
(
!
skl
->
dsp
)
{
dev_err
(
skl
->
dev
,
"skl_dsp_ctx_init failed
\n
"
);
return
-
ENODEV
;
ret
=
skl_sst_ctx_init
(
dev
,
irq
,
fw_name
,
dsp_ops
,
dsp
,
&
skl_dev
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"%s: no device
\n
"
,
__func__
);
return
ret
;
}
skl
=
*
dsp
;
sst
=
skl
->
dsp
;
sst
->
fw_name
=
fw_name
;
sst
->
dsp_ops
=
dsp_ops
;
sst
->
fw_ops
=
bxt_fw_ops
;
sst
->
addr
.
lpe
=
mmio_base
;
sst
->
addr
.
shim
=
mmio_base
;
...
...
@@ -584,24 +577,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
sst_dsp_mailbox_init
(
sst
,
(
BXT_ADSP_SRAM0_BASE
+
SKL_ADSP_W0_STAT_SZ
),
SKL_ADSP_W0_UP_SZ
,
BXT_ADSP_SRAM1_BASE
,
SKL_ADSP_W1_SZ
);
INIT_LIST_HEAD
(
&
sst
->
module_list
);
ret
=
skl_ipc_init
(
dev
,
skl
);
if
(
ret
)
return
ret
;
/* set the D0i3 check */
skl
->
ipc
.
ops
.
check_dsp_lp_on
=
skl_ipc_check_D0i0
;
skl
->
cores
.
count
=
2
;
skl
->
boot_complete
=
false
;
init_waitqueue_head
(
&
skl
->
boot_wait
);
skl
->
is_first_boot
=
true
;
INIT_DELAYED_WORK
(
&
skl
->
d0i3
.
work
,
bxt_set_dsp_D0i3
);
skl
->
d0i3
.
state
=
SKL_DSP_D0I3_NONE
;
if
(
dsp
)
*
dsp
=
skl
;
return
0
;
}
EXPORT_SYMBOL_GPL
(
bxt_sst_dsp_init
);
...
...
@@ -635,6 +619,10 @@ EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
void
bxt_sst_dsp_cleanup
(
struct
device
*
dev
,
struct
skl_sst
*
ctx
)
{
skl_release_library
(
ctx
->
lib_info
,
ctx
->
lib_count
);
if
(
ctx
->
dsp
->
fw
)
release_firmware
(
ctx
->
dsp
->
fw
);
skl_freeup_uuid_list
(
ctx
);
skl_ipc_free
(
&
ctx
->
ipc
);
ctx
->
dsp
->
cl_dev
.
ops
.
cl_cleanup_controller
(
ctx
->
dsp
);
...
...
sound/soc/intel/skylake/skl-messages.c
View file @
0c2964cb
...
...
@@ -58,7 +58,7 @@ static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
#define NOTIFICATION_MASK 0xf
/* disable notfication for underruns/overruns from firmware module */
static
void
skl_dsp_enable_notification
(
struct
skl_sst
*
ctx
,
bool
enable
)
void
skl_dsp_enable_notification
(
struct
skl_sst
*
ctx
,
bool
enable
)
{
struct
notification_mask
mask
;
struct
skl_ipc_large_config_msg
msg
=
{
0
};
...
...
@@ -209,7 +209,7 @@ static const struct skl_dsp_ops dsp_ops[] = {
{
.
id
=
0x9d71
,
.
loader_ops
=
skl_get_loader_ops
,
.
init
=
sk
l_sst_dsp_init
,
.
init
=
kb
l_sst_dsp_init
,
.
init_fw
=
skl_sst_init_fw
,
.
cleanup
=
skl_sst_dsp_cleanup
},
...
...
@@ -274,6 +274,7 @@ int skl_init_dsp(struct skl *skl)
if
(
ret
<
0
)
return
ret
;
skl
->
skl_sst
->
dsp_ops
=
ops
;
dev_dbg
(
bus
->
dev
,
"dsp registration status=%d
\n
"
,
ret
);
return
ret
;
...
...
@@ -284,16 +285,11 @@ int skl_free_dsp(struct skl *skl)
struct
hdac_ext_bus
*
ebus
=
&
skl
->
ebus
;
struct
hdac_bus
*
bus
=
ebus_to_hbus
(
ebus
);
struct
skl_sst
*
ctx
=
skl
->
skl_sst
;
const
struct
skl_dsp_ops
*
ops
;
/* disable ppcap interrupt */
snd_hdac_ext_bus_ppcap_int_enable
(
&
skl
->
ebus
,
false
);
ops
=
skl_get_dsp_ops
(
skl
->
pci
->
device
);
if
(
!
ops
)
return
-
EIO
;
ops
->
cleanup
(
bus
->
dev
,
ctx
);
ctx
->
dsp_ops
->
cleanup
(
bus
->
dev
,
ctx
);
if
(
ctx
->
dsp
->
addr
.
lpe
)
iounmap
(
ctx
->
dsp
->
addr
.
lpe
);
...
...
@@ -866,7 +862,7 @@ static void skl_clear_module_state(struct skl_module_pin *mpin, int max,
}
if
(
!
found
)
mcfg
->
m_state
=
SKL_MODULE_
UNINIT
;
mcfg
->
m_state
=
SKL_MODULE_
INIT_DONE
;
return
;
}
...
...
@@ -1098,7 +1094,7 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
dev_dbg
(
ctx
->
dev
,
"%s: pipe = %d
\n
"
,
__func__
,
pipe
->
ppl_id
);
/* If pipe is started, do stop the pipe in FW. */
if
(
pipe
->
state
>
SKL_PIPE_STARTED
)
{
if
(
pipe
->
state
>
=
SKL_PIPE_STARTED
)
{
ret
=
skl_set_pipe_state
(
ctx
,
pipe
,
PPL_PAUSED
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Failed to stop pipeline
\n
"
);
...
...
sound/soc/intel/skylake/skl-nhlt.c
View file @
0c2964cb
...
...
@@ -24,8 +24,6 @@
static
u8
OSC_UUID
[
16
]
=
{
0x6E
,
0x88
,
0x9F
,
0xA6
,
0xEB
,
0x6C
,
0x94
,
0x45
,
0xA4
,
0x1F
,
0x7B
,
0x5D
,
0xCE
,
0x24
,
0xC5
,
0x53
};
#define DSDT_NHLT_PATH "\\_SB.PCI0.HDAS"
struct
nhlt_acpi_table
*
skl_nhlt_init
(
struct
device
*
dev
)
{
acpi_handle
handle
;
...
...
@@ -33,8 +31,9 @@ struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
struct
nhlt_resource_desc
*
nhlt_ptr
=
NULL
;
struct
nhlt_acpi_table
*
nhlt_table
=
NULL
;
if
(
ACPI_FAILURE
(
acpi_get_handle
(
NULL
,
DSDT_NHLT_PATH
,
&
handle
)))
{
dev_err
(
dev
,
"Requested NHLT device not found
\n
"
);
handle
=
ACPI_HANDLE
(
dev
);
if
(
!
handle
)
{
dev_err
(
dev
,
"Didn't find ACPI_HANDLE
\n
"
);
return
NULL
;
}
...
...
sound/soc/intel/skylake/skl-pcm.c
View file @
0c2964cb
...
...
@@ -21,6 +21,7 @@
#include <linux/pci.h>
#include <linux/pm_runtime.h>
#include <linux/delay.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "skl.h"
...
...
@@ -155,7 +156,7 @@ int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
snd_hdac_ext_stream_decouple
(
ebus
,
stream
,
true
);
format_val
=
snd_hdac_calc_stream_format
(
params
->
s_freq
,
params
->
ch
,
params
->
format
,
32
,
0
);
params
->
ch
,
params
->
format
,
params
->
host_bps
,
0
);
dev_dbg
(
dev
,
"format_val=%d, rate=%d, ch=%d, format=%d
\n
"
,
format_val
,
params
->
s_freq
,
params
->
ch
,
params
->
format
);
...
...
@@ -190,8 +191,8 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
stream
=
stream_to_hdac_ext_stream
(
hstream
);
snd_hdac_ext_stream_decouple
(
ebus
,
stream
,
true
);
format_val
=
snd_hdac_calc_stream_format
(
params
->
s_freq
,
params
->
ch
,
params
->
format
,
24
,
0
);
format_val
=
snd_hdac_calc_stream_format
(
params
->
s_freq
,
params
->
ch
,
params
->
format
,
params
->
link_bps
,
0
);
dev_dbg
(
dev
,
"format_val=%d, rate=%d, ch=%d, format=%d
\n
"
,
format_val
,
params
->
s_freq
,
params
->
ch
,
params
->
format
);
...
...
@@ -262,23 +263,6 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
return
0
;
}
static
int
skl_be_prepare
(
struct
snd_pcm_substream
*
substream
,
struct
snd_soc_dai
*
dai
)
{
struct
skl
*
skl
=
get_skl_ctx
(
dai
->
dev
);
struct
skl_sst
*
ctx
=
skl
->
skl_sst
;
struct
skl_module_cfg
*
mconfig
;
if
(
dai
->
playback_widget
->
power
||
dai
->
capture_widget
->
power
)
return
0
;
mconfig
=
skl_tplg_be_get_cpr_module
(
dai
,
substream
->
stream
);
if
(
mconfig
==
NULL
)
return
-
EINVAL
;
return
skl_dsp_set_dma_control
(
ctx
,
mconfig
);
}
static
int
skl_pcm_prepare
(
struct
snd_pcm_substream
*
substream
,
struct
snd_soc_dai
*
dai
)
{
...
...
@@ -326,6 +310,11 @@ static int skl_pcm_hw_params(struct snd_pcm_substream *substream,
p_params
.
host_dma_id
=
dma_id
;
p_params
.
stream
=
substream
->
stream
;
p_params
.
format
=
params_format
(
params
);
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
p_params
.
host_bps
=
dai
->
driver
->
playback
.
sig_bits
;
else
p_params
.
host_bps
=
dai
->
driver
->
capture
.
sig_bits
;
m_cfg
=
skl_tplg_fe_get_cpr_module
(
dai
,
p_params
.
stream
);
if
(
m_cfg
)
...
...
@@ -564,6 +553,11 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
p_params
.
link_index
=
link
->
index
;
p_params
.
format
=
params_format
(
params
);
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
p_params
.
link_bps
=
codec_dai
->
driver
->
playback
.
sig_bits
;
else
p_params
.
link_bps
=
codec_dai
->
driver
->
capture
.
sig_bits
;
return
skl_tplg_be_update_params
(
dai
,
&
p_params
);
}
...
...
@@ -649,7 +643,6 @@ static struct snd_soc_dai_ops skl_dmic_dai_ops = {
static
struct
snd_soc_dai_ops
skl_be_ssp_dai_ops
=
{
.
hw_params
=
skl_be_hw_params
,
.
prepare
=
skl_be_prepare
,
};
static
struct
snd_soc_dai_ops
skl_link_dai_ops
=
{
...
...
@@ -670,6 +663,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
rates
=
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_16000
|
SNDRV_PCM_RATE_8000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S24_LE
|
SNDRV_PCM_FMTBIT_S32_LE
,
.
sig_bits
=
32
,
},
.
capture
=
{
.
stream_name
=
"System Capture"
,
...
...
@@ -677,6 +671,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
channels_max
=
HDA_STEREO
,
.
rates
=
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_16000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S24_LE
,
.
sig_bits
=
32
,
},
},
{
...
...
@@ -688,6 +683,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
channels_max
=
HDA_QUAD
,
.
rates
=
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_16000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S24_LE
,
.
sig_bits
=
32
,
},
},
{
...
...
@@ -699,6 +695,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
channels_max
=
HDA_STEREO
,
.
rates
=
SNDRV_PCM_RATE_48000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S24_LE
,
.
sig_bits
=
32
,
},
},
{
...
...
@@ -710,6 +707,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
channels_max
=
HDA_STEREO
,
.
rates
=
SNDRV_PCM_RATE_48000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S24_LE
,
.
sig_bits
=
32
,
},
},
{
...
...
@@ -721,6 +719,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
channels_max
=
HDA_QUAD
,
.
rates
=
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_16000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S24_LE
,
.
sig_bits
=
32
,
},
},
{
...
...
@@ -736,6 +735,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
SNDRV_PCM_RATE_192000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S24_LE
|
SNDRV_PCM_FMTBIT_S32_LE
,
.
sig_bits
=
32
,
},
},
{
...
...
@@ -751,6 +751,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
SNDRV_PCM_RATE_192000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S24_LE
|
SNDRV_PCM_FMTBIT_S32_LE
,
.
sig_bits
=
32
,
},
},
{
...
...
@@ -766,6 +767,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
SNDRV_PCM_RATE_192000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S24_LE
|
SNDRV_PCM_FMTBIT_S32_LE
,
.
sig_bits
=
32
,
},
},
...
...
@@ -949,14 +951,12 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
static
int
skl_platform_open
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcm_runtime
*
runtime
;
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai_link
*
dai_link
=
rtd
->
dai_link
;
dev_dbg
(
rtd
->
cpu_dai
->
dev
,
"In %s:%s
\n
"
,
__func__
,
dai_link
->
cpu_dai_name
);
runtime
=
substream
->
runtime
;
snd_soc_set_runtime_hwparams
(
substream
,
&
azx_pcm_hw
);
return
0
;
...
...
@@ -1062,13 +1062,31 @@ static snd_pcm_uframes_t skl_platform_pcm_pointer
* HAD space reflects the actual data that is transferred.
* Use the position buffer for capture, as DPIB write gets
* completed earlier than the actual data written to the DDR.
*
* For capture stream following workaround is required to fix the
* incorrect position reporting.
*
* 1. Wait for 20us before reading the DMA position in buffer once
* the interrupt is generated for stream completion as update happens
* on the HDA frame boundary i.e. 20.833uSec.
* 2. Read DPIB register to flush the DMA position value. This dummy
* read is required to flush DMA position value.
* 3. Read the DMA Position-in-Buffer. This value now will be equal to
* or greater than period boundary.
*/
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
pos
=
readl
(
ebus
->
bus
.
remap_addr
+
AZX_REG_VS_SDXDPIB_XBASE
+
(
AZX_REG_VS_SDXDPIB_XINTERVAL
*
hdac_stream
(
hstream
)
->
index
));
else
}
else
{
udelay
(
20
);
readl
(
ebus
->
bus
.
remap_addr
+
AZX_REG_VS_SDXDPIB_XBASE
+
(
AZX_REG_VS_SDXDPIB_XINTERVAL
*
hdac_stream
(
hstream
)
->
index
));
pos
=
snd_hdac_stream_get_pos_posbuf
(
hdac_stream
(
hstream
));
}
if
(
pos
>=
hdac_stream
(
hstream
)
->
bufsize
)
pos
=
0
;
...
...
@@ -1165,7 +1183,7 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
snd_dma_pci_data
(
skl
->
pci
),
size
,
MAX_PREALLOC_SIZE
);
if
(
retval
)
{
dev_err
(
dai
->
dev
,
"dma buffer allocation
f
fail
\n
"
);
dev_err
(
dai
->
dev
,
"dma buffer allocation fail
\n
"
);
return
retval
;
}
}
...
...
@@ -1173,29 +1191,52 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
return
retval
;
}
static
int
skl_get_module_info
(
struct
skl
*
skl
,
struct
skl_module_cfg
*
mconfig
)
{
struct
skl_sst
*
ctx
=
skl
->
skl_sst
;
struct
uuid_module
*
module
;
uuid_le
*
uuid_mod
;
uuid_mod
=
(
uuid_le
*
)
mconfig
->
guid
;
if
(
list_empty
(
&
ctx
->
uuid_list
))
{
dev_err
(
ctx
->
dev
,
"Module list is empty
\n
"
);
return
-
EIO
;
}
list_for_each_entry
(
module
,
&
ctx
->
uuid_list
,
list
)
{
if
(
uuid_le_cmp
(
*
uuid_mod
,
module
->
uuid
)
==
0
)
{
mconfig
->
id
.
module_id
=
module
->
id
;
mconfig
->
is_loadable
=
module
->
is_loadable
;
return
0
;
}
}
return
-
EIO
;
}
static
int
skl_populate_modules
(
struct
skl
*
skl
)
{
struct
skl_pipeline
*
p
;
struct
skl_pipe_module
*
m
;
struct
snd_soc_dapm_widget
*
w
;
struct
skl_module_cfg
*
mconfig
;
int
ret
;
int
ret
=
0
;
list_for_each_entry
(
p
,
&
skl
->
ppl_list
,
node
)
{
list_for_each_entry
(
m
,
&
p
->
pipe
->
w_list
,
node
)
{
w
=
m
->
w
;
mconfig
=
w
->
priv
;
ret
=
s
nd_skl_get_module_info
(
skl
->
skl_sst
,
mconfig
);
ret
=
s
kl_get_module_info
(
skl
,
mconfig
);
if
(
ret
<
0
)
{
dev_err
(
skl
->
skl_sst
->
dev
,
"query module info failed
:%d
\n
"
,
ret
);
goto
err
;
"query module info failed
\n
"
);
return
ret
;
}
}
}
err:
return
ret
;
}
...
...
@@ -1232,6 +1273,7 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
}
skl_populate_modules
(
skl
);
skl
->
skl_sst
->
update_d0i3c
=
skl_update_d0i3c
;
skl_dsp_enable_notification
(
skl
->
skl_sst
,
false
);
}
pm_runtime_mark_last_busy
(
platform
->
dev
);
pm_runtime_put_autosuspend
(
platform
->
dev
);
...
...
@@ -1256,6 +1298,7 @@ int skl_platform_register(struct device *dev)
struct
skl
*
skl
=
ebus_to_skl
(
ebus
);
INIT_LIST_HEAD
(
&
skl
->
ppl_list
);
INIT_LIST_HEAD
(
&
skl
->
bind_list
);
ret
=
snd_soc_register_platform
(
dev
,
&
skl_platform_drv
);
if
(
ret
)
{
...
...
@@ -1276,6 +1319,17 @@ int skl_platform_register(struct device *dev)
int
skl_platform_unregister
(
struct
device
*
dev
)
{
struct
hdac_ext_bus
*
ebus
=
dev_get_drvdata
(
dev
);
struct
skl
*
skl
=
ebus_to_skl
(
ebus
);
struct
skl_module_deferred_bind
*
modules
,
*
tmp
;
if
(
!
list_empty
(
&
skl
->
bind_list
))
{
list_for_each_entry_safe
(
modules
,
tmp
,
&
skl
->
bind_list
,
node
)
{
list_del
(
&
modules
->
node
);
kfree
(
modules
);
}
}
snd_soc_unregister_component
(
dev
);
snd_soc_unregister_platform
(
dev
);
return
0
;
...
...
sound/soc/intel/skylake/skl-sst-cldma.c
View file @
0c2964cb
...
...
@@ -164,7 +164,7 @@ static void skl_cldma_cleanup(struct sst_dsp *ctx)
ctx
->
dsp_ops
.
free_dma_buf
(
ctx
->
dev
,
&
ctx
->
cl_dev
.
dmab_bdl
);
}
static
int
skl_cldma_wait_interruptible
(
struct
sst_dsp
*
ctx
)
int
skl_cldma_wait_interruptible
(
struct
sst_dsp
*
ctx
)
{
int
ret
=
0
;
...
...
@@ -243,9 +243,14 @@ static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size,
* 2. Polling on fw register to identify if data left to transferred doesn't
* fill the ring buffer. Caller takes care of polling the required status
* register to identify the transfer status.
* 3. if wait flag is set, waits for DBL interrupt to copy the next chunk till
* bytes_left is 0.
* if wait flag is not set, doesn't wait for BDL interrupt. after ccopying
* the first chunk return the no of bytes_left to be copied.
*/
static
int
skl_cldma_copy_to_buf
(
struct
sst_dsp
*
ctx
,
const
void
*
bin
,
u32
total_size
)
skl_cldma_copy_to_buf
(
struct
sst_dsp
*
ctx
,
const
void
*
bin
,
u32
total_size
,
bool
wait
)
{
int
ret
=
0
;
bool
start
=
true
;
...
...
@@ -272,13 +277,14 @@ skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin, u32 total_size)
size
=
ctx
->
cl_dev
.
bufsize
;
skl_cldma_fill_buffer
(
ctx
,
size
,
curr_pos
,
true
,
start
);
start
=
false
;
ret
=
skl_cldma_wait_interruptible
(
ctx
);
if
(
ret
<
0
)
{
skl_cldma_stop
(
ctx
);
return
ret
;
if
(
wait
)
{
start
=
false
;
ret
=
skl_cldma_wait_interruptible
(
ctx
);
if
(
ret
<
0
)
{
skl_cldma_stop
(
ctx
);
return
ret
;
}
}
}
else
{
skl_cldma_int_disable
(
ctx
);
...
...
@@ -298,9 +304,11 @@ skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin, u32 total_size)
}
bytes_left
-=
size
;
curr_pos
=
curr_pos
+
size
;
if
(
!
wait
)
return
bytes_left
;
}
return
re
t
;
return
bytes_lef
t
;
}
void
skl_cldma_process_intr
(
struct
sst_dsp
*
ctx
)
...
...
sound/soc/intel/skylake/skl-sst-cldma.h
View file @
0c2964cb
...
...
@@ -213,7 +213,7 @@ struct skl_cl_dev_ops {
void
(
*
cl_trigger
)(
struct
sst_dsp
*
ctx
,
bool
enable
);
void
(
*
cl_cleanup_controller
)(
struct
sst_dsp
*
ctx
);
int
(
*
cl_copy_to_dmabuf
)(
struct
sst_dsp
*
ctx
,
const
void
*
bin
,
u32
size
);
const
void
*
bin
,
u32
size
,
bool
wait
);
void
(
*
cl_stop_dma
)(
struct
sst_dsp
*
ctx
);
};
...
...
sound/soc/intel/skylake/skl-sst-dsp.c
View file @
0c2964cb
...
...
@@ -355,12 +355,13 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
ret
=
ctx
->
fw_ops
.
set_state_D0
(
ctx
,
core_id
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"unable to get core%d
\n
"
,
core_id
);
return
re
t
;
goto
ou
t
;
}
}
skl
->
cores
.
usage_count
[
core_id
]
++
;
out:
dev_dbg
(
ctx
->
dev
,
"core id %d state %d usage_count %d
\n
"
,
core_id
,
skl
->
cores
.
state
[
core_id
],
skl
->
cores
.
usage_count
[
core_id
]);
...
...
@@ -379,7 +380,8 @@ int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id)
return
-
EINVAL
;
}
if
(
--
skl
->
cores
.
usage_count
[
core_id
]
==
0
)
{
if
((
--
skl
->
cores
.
usage_count
[
core_id
]
==
0
)
&&
(
skl
->
cores
.
state
[
core_id
]
!=
SKL_DSP_RESET
))
{
ret
=
ctx
->
fw_ops
.
set_state_D3
(
ctx
,
core_id
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"unable to put core %d: %d
\n
"
,
...
...
sound/soc/intel/skylake/skl-sst-dsp.h
View file @
0c2964cb
...
...
@@ -17,13 +17,15 @@
#define __SKL_SST_DSP_H__
#include <linux/interrupt.h>
#include <linux/uuid.h>
#include <linux/firmware.h>
#include <sound/memalloc.h>
#include "skl-sst-cldma.h"
#include "skl-topology.h"
struct
sst_dsp
;
struct
skl_sst
;
struct
sst_dsp_device
;
struct
skl_lib_info
;
/* Intel HD Audio General DSP Registers */
#define SKL_ADSP_GEN_BASE 0x0
...
...
@@ -144,7 +146,7 @@ struct skl_dsp_fw_ops {
int
(
*
load_fw
)(
struct
sst_dsp
*
ctx
);
/* FW module parser/loader */
int
(
*
load_library
)(
struct
sst_dsp
*
ctx
,
struct
skl_lib_info
*
linfo
,
int
count
);
struct
skl_lib_info
*
linfo
,
int
lib_
count
);
int
(
*
parse_fw
)(
struct
sst_dsp
*
ctx
);
int
(
*
set_state_D0
)(
struct
sst_dsp
*
ctx
,
unsigned
int
core_id
);
int
(
*
set_state_D3
)(
struct
sst_dsp
*
ctx
,
unsigned
int
core_id
);
...
...
@@ -172,6 +174,19 @@ struct skl_dsp_loader_ops {
int
stream_tag
);
};
#define MAX_INSTANCE_BUFF 2
struct
uuid_module
{
uuid_le
uuid
;
int
id
;
int
is_loadable
;
int
max_instance
;
u64
pvt_id
[
MAX_INSTANCE_BUFF
];
int
*
instance_id
;
struct
list_head
list
;
};
struct
skl_load_module_info
{
u16
mod_id
;
const
struct
firmware
*
fw
;
...
...
@@ -186,6 +201,7 @@ struct skl_module_table {
void
skl_cldma_process_intr
(
struct
sst_dsp
*
ctx
);
void
skl_cldma_int_disable
(
struct
sst_dsp
*
ctx
);
int
skl_cldma_prepare
(
struct
sst_dsp
*
ctx
);
int
skl_cldma_wait_interruptible
(
struct
sst_dsp
*
ctx
);
void
skl_dsp_set_state_locked
(
struct
sst_dsp
*
ctx
,
int
state
);
struct
sst_dsp
*
skl_dsp_ctx_init
(
struct
device
*
dev
,
...
...
@@ -214,6 +230,9 @@ int skl_dsp_boot(struct sst_dsp *ctx);
int
skl_sst_dsp_init
(
struct
device
*
dev
,
void
__iomem
*
mmio_base
,
int
irq
,
const
char
*
fw_name
,
struct
skl_dsp_loader_ops
dsp_ops
,
struct
skl_sst
**
dsp
);
int
kbl_sst_dsp_init
(
struct
device
*
dev
,
void
__iomem
*
mmio_base
,
int
irq
,
const
char
*
fw_name
,
struct
skl_dsp_loader_ops
dsp_ops
,
struct
skl_sst
**
dsp
);
int
bxt_sst_dsp_init
(
struct
device
*
dev
,
void
__iomem
*
mmio_base
,
int
irq
,
const
char
*
fw_name
,
struct
skl_dsp_loader_ops
dsp_ops
,
struct
skl_sst
**
dsp
);
...
...
@@ -222,17 +241,22 @@ int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx);
void
skl_sst_dsp_cleanup
(
struct
device
*
dev
,
struct
skl_sst
*
ctx
);
void
bxt_sst_dsp_cleanup
(
struct
device
*
dev
,
struct
skl_sst
*
ctx
);
int
snd_skl_get_module_info
(
struct
skl_sst
*
ctx
,
struct
skl_module_cfg
*
mconfig
);
int
snd_skl_parse_uuids
(
struct
sst_dsp
*
ctx
,
const
struct
firmware
*
fw
,
unsigned
int
offset
,
int
index
);
int
skl_get_pvt_id
(
struct
skl_sst
*
ctx
,
struct
skl_module_cfg
*
mconfig
);
int
skl_put_pvt_id
(
struct
skl_sst
*
ctx
,
struct
skl_module_cfg
*
mconfig
);
int
skl_get_pvt_id
(
struct
skl_sst
*
ctx
,
uuid_le
*
uuid_mod
,
int
instance_id
);
int
skl_put_pvt_id
(
struct
skl_sst
*
ctx
,
uuid_le
*
uuid_mod
,
int
*
pvt_id
);
int
skl_get_pvt_instance_id_map
(
struct
skl_sst
*
ctx
,
int
module_id
,
int
instance_id
);
void
skl_freeup_uuid_list
(
struct
skl_sst
*
ctx
);
int
skl_dsp_strip_extended_manifest
(
struct
firmware
*
fw
);
void
skl_dsp_enable_notification
(
struct
skl_sst
*
ctx
,
bool
enable
);
int
skl_sst_ctx_init
(
struct
device
*
dev
,
int
irq
,
const
char
*
fw_name
,
struct
skl_dsp_loader_ops
dsp_ops
,
struct
skl_sst
**
dsp
,
struct
sst_dsp_device
*
skl_dev
);
int
skl_prepare_lib_load
(
struct
skl_sst
*
skl
,
struct
skl_lib_info
*
linfo
,
struct
firmware
*
stripped_fw
,
unsigned
int
hdr_offset
,
int
index
);
void
skl_release_library
(
struct
skl_lib_info
*
linfo
,
int
lib_count
);
#endif
/*__SKL_SST_DSP_H__*/
sound/soc/intel/skylake/skl-sst-ipc.c
View file @
0c2964cb
...
...
@@ -34,6 +34,11 @@
#define IPC_GLB_REPLY_STATUS_MASK ((0x1 << IPC_GLB_REPLY_STATUS_SHIFT) - 1)
#define IPC_GLB_REPLY_STATUS(x) ((x) << IPC_GLB_REPLY_STATUS_SHIFT)
#define IPC_GLB_REPLY_TYPE_SHIFT 29
#define IPC_GLB_REPLY_TYPE_MASK 0x1F
#define IPC_GLB_REPLY_TYPE(x) (((x) >> IPC_GLB_REPLY_TYPE_SHIFT) \
& IPC_GLB_RPLY_TYPE_MASK)
#define IPC_TIMEOUT_MSECS 3000
#define IPC_EMPTY_LIST_SIZE 8
...
...
@@ -387,12 +392,27 @@ static int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
return
0
;
}
static
int
skl_ipc_set_reply_error_code
(
u32
reply
)
{
switch
(
reply
)
{
case
IPC_GLB_REPLY_OUT_OF_MEMORY
:
return
-
ENOMEM
;
case
IPC_GLB_REPLY_BUSY
:
return
-
EBUSY
;
default:
return
-
EINVAL
;
}
}
static
void
skl_ipc_process_reply
(
struct
sst_generic_ipc
*
ipc
,
struct
skl_ipc_header
header
)
{
struct
ipc_message
*
msg
;
u32
reply
=
header
.
primary
&
IPC_GLB_REPLY_STATUS_MASK
;
u64
*
ipc_header
=
(
u64
*
)(
&
header
);
struct
skl_sst
*
skl
=
container_of
(
ipc
,
struct
skl_sst
,
ipc
);
msg
=
skl_ipc_reply_get_msg
(
ipc
,
*
ipc_header
);
if
(
msg
==
NULL
)
{
...
...
@@ -401,33 +421,39 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
}
/* first process the header */
switch
(
reply
)
{
case
IPC_GLB_REPLY_SUCCESS
:
if
(
reply
==
IPC_GLB_REPLY_SUCCESS
)
{
dev_dbg
(
ipc
->
dev
,
"ipc FW reply %x: success
\n
"
,
header
.
primary
);
/* copy the rx data from the mailbox */
sst_dsp_inbox_read
(
ipc
->
dsp
,
msg
->
rx_data
,
msg
->
rx_size
);
break
;
case
IPC_GLB_REPLY_OUT_OF_MEMORY
:
dev_err
(
ipc
->
dev
,
"ipc fw reply: %x: no memory
\n
"
,
header
.
primary
);
msg
->
errno
=
-
ENOMEM
;
break
;
case
IPC_GLB_REPLY_BUSY
:
dev_err
(
ipc
->
dev
,
"ipc fw reply: %x: Busy
\n
"
,
header
.
primary
);
msg
->
errno
=
-
EBUSY
;
break
;
switch
(
IPC_GLB_NOTIFY_MSG_TYPE
(
header
.
primary
))
{
case
IPC_GLB_LOAD_MULTIPLE_MODS
:
case
IPC_GLB_LOAD_LIBRARY
:
skl
->
mod_load_complete
=
true
;
skl
->
mod_load_status
=
true
;
wake_up
(
&
skl
->
mod_load_wait
);
break
;
default:
dev_err
(
ipc
->
dev
,
"Unknown ipc reply: 0x%x
\n
"
,
reply
);
msg
->
errno
=
-
EINVAL
;
break
;
}
default:
break
;
if
(
reply
!=
IPC_GLB_REPLY_SUCCESS
)
{
}
}
else
{
msg
->
errno
=
skl_ipc_set_reply_error_code
(
reply
);
dev_err
(
ipc
->
dev
,
"ipc FW reply: reply=%d
\n
"
,
reply
);
dev_err
(
ipc
->
dev
,
"FW Error Code: %u
\n
"
,
ipc
->
dsp
->
fw_ops
.
get_fw_errcode
(
ipc
->
dsp
));
switch
(
IPC_GLB_NOTIFY_MSG_TYPE
(
header
.
primary
))
{
case
IPC_GLB_LOAD_MULTIPLE_MODS
:
case
IPC_GLB_LOAD_LIBRARY
:
skl
->
mod_load_complete
=
true
;
skl
->
mod_load_status
=
false
;
wake_up
(
&
skl
->
mod_load_wait
);
break
;
default:
break
;
}
}
list_del
(
&
msg
->
list
);
...
...
@@ -811,8 +837,8 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
header
.
primary
|=
IPC_GLB_TYPE
(
IPC_GLB_LOAD_MULTIPLE_MODS
);
header
.
primary
|=
IPC_LOAD_MODULE_CNT
(
module_cnt
);
ret
=
sst_ipc_tx_message_wait
(
ipc
,
*
ipc_header
,
data
,
(
sizeof
(
u16
)
*
module_cnt
)
,
NULL
,
0
);
ret
=
sst_ipc_tx_message_
no
wait
(
ipc
,
*
ipc_header
,
data
,
(
sizeof
(
u16
)
*
module_cnt
));
if
(
ret
<
0
)
dev_err
(
ipc
->
dev
,
"ipc: load modules failed :%d
\n
"
,
ret
);
...
...
@@ -947,7 +973,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
EXPORT_SYMBOL_GPL
(
skl_ipc_get_large_config
);
int
skl_sst_ipc_load_library
(
struct
sst_generic_ipc
*
ipc
,
u8
dma_id
,
u8
table_id
)
u8
dma_id
,
u8
table_id
,
bool
wait
)
{
struct
skl_ipc_header
header
=
{
0
};
u64
*
ipc_header
=
(
u64
*
)(
&
header
);
...
...
@@ -959,7 +985,11 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
header
.
primary
|=
IPC_MOD_INSTANCE_ID
(
table_id
);
header
.
primary
|=
IPC_MOD_ID
(
dma_id
);
ret
=
sst_ipc_tx_message_wait
(
ipc
,
*
ipc_header
,
NULL
,
0
,
NULL
,
0
);
if
(
wait
)
ret
=
sst_ipc_tx_message_wait
(
ipc
,
*
ipc_header
,
NULL
,
0
,
NULL
,
0
);
else
ret
=
sst_ipc_tx_message_nowait
(
ipc
,
*
ipc_header
,
NULL
,
0
);
if
(
ret
<
0
)
dev_err
(
ipc
->
dev
,
"ipc: load lib failed
\n
"
);
...
...
sound/soc/intel/skylake/skl-sst-ipc.h
View file @
0c2964cb
...
...
@@ -69,6 +69,14 @@ struct skl_d0i3_data {
struct
delayed_work
work
;
};
#define SKL_LIB_NAME_LENGTH 128
#define SKL_MAX_LIB 16
struct
skl_lib_info
{
char
name
[
SKL_LIB_NAME_LENGTH
];
const
struct
firmware
*
fw
;
};
struct
skl_sst
{
struct
device
*
dev
;
struct
sst_dsp
*
dsp
;
...
...
@@ -77,6 +85,11 @@ struct skl_sst {
wait_queue_head_t
boot_wait
;
bool
boot_complete
;
/* module load */
wait_queue_head_t
mod_load_wait
;
bool
mod_load_complete
;
bool
mod_load_status
;
/* IPC messaging */
struct
sst_generic_ipc
ipc
;
...
...
@@ -105,6 +118,8 @@ struct skl_sst {
void
(
*
update_d0i3c
)(
struct
device
*
dev
,
bool
enable
);
struct
skl_d0i3_data
d0i3
;
const
struct
skl_dsp_ops
*
dsp_ops
;
};
struct
skl_ipc_init_instance_msg
{
...
...
@@ -182,7 +197,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
struct
skl_ipc_large_config_msg
*
msg
,
u32
*
param
);
int
skl_sst_ipc_load_library
(
struct
sst_generic_ipc
*
ipc
,
u8
dma_id
,
u8
table_id
);
u8
dma_id
,
u8
table_id
,
bool
wait
);
int
skl_ipc_set_d0ix
(
struct
sst_generic_ipc
*
ipc
,
struct
skl_ipc_d0ix_msg
*
msg
);
...
...
sound/soc/intel/skylake/skl-sst-utils.c
View file @
0c2964cb
...
...
@@ -94,19 +94,6 @@ struct adsp_fw_hdr {
u32
load_offset
;
}
__packed
;
#define MAX_INSTANCE_BUFF 2
struct
uuid_module
{
uuid_le
uuid
;
int
id
;
int
is_loadable
;
int
max_instance
;
u64
pvt_id
[
MAX_INSTANCE_BUFF
];
int
*
instance_id
;
struct
list_head
list
;
};
struct
skl_ext_manifest_hdr
{
u32
id
;
u32
len
;
...
...
@@ -115,32 +102,6 @@ struct skl_ext_manifest_hdr {
u32
entries
;
};
int
snd_skl_get_module_info
(
struct
skl_sst
*
ctx
,
struct
skl_module_cfg
*
mconfig
)
{
struct
uuid_module
*
module
;
uuid_le
*
uuid_mod
;
uuid_mod
=
(
uuid_le
*
)
mconfig
->
guid
;
if
(
list_empty
(
&
ctx
->
uuid_list
))
{
dev_err
(
ctx
->
dev
,
"Module list is empty
\n
"
);
return
-
EINVAL
;
}
list_for_each_entry
(
module
,
&
ctx
->
uuid_list
,
list
)
{
if
(
uuid_le_cmp
(
*
uuid_mod
,
module
->
uuid
)
==
0
)
{
mconfig
->
id
.
module_id
=
module
->
id
;
mconfig
->
is_loadable
=
module
->
is_loadable
;
return
0
;
}
}
return
-
EINVAL
;
}
EXPORT_SYMBOL_GPL
(
snd_skl_get_module_info
);
static
int
skl_get_pvtid_map
(
struct
uuid_module
*
module
,
int
instance_id
)
{
int
pvt_id
;
...
...
@@ -222,21 +183,18 @@ static inline int skl_pvtid_128(struct uuid_module *module)
* This generates a 128 bit private unique id for a module TYPE so that
* module instance is unique
*/
int
skl_get_pvt_id
(
struct
skl_sst
*
ctx
,
struct
skl_module_cfg
*
mconfig
)
int
skl_get_pvt_id
(
struct
skl_sst
*
ctx
,
uuid_le
*
uuid_mod
,
int
instance_id
)
{
struct
uuid_module
*
module
;
uuid_le
*
uuid_mod
;
int
pvt_id
;
uuid_mod
=
(
uuid_le
*
)
mconfig
->
guid
;
list_for_each_entry
(
module
,
&
ctx
->
uuid_list
,
list
)
{
if
(
uuid_le_cmp
(
*
uuid_mod
,
module
->
uuid
)
==
0
)
{
pvt_id
=
skl_pvtid_128
(
module
);
if
(
pvt_id
>=
0
)
{
module
->
instance_id
[
pvt_id
]
=
mconfig
->
id
.
instance_id
;
module
->
instance_id
[
pvt_id
]
=
instance_id
;
return
pvt_id
;
}
}
...
...
@@ -254,23 +212,21 @@ EXPORT_SYMBOL_GPL(skl_get_pvt_id);
*
* This frees a 128 bit private unique id previously generated
*/
int
skl_put_pvt_id
(
struct
skl_sst
*
ctx
,
struct
skl_module_cfg
*
mconfig
)
int
skl_put_pvt_id
(
struct
skl_sst
*
ctx
,
uuid_le
*
uuid_mod
,
int
*
pvt_id
)
{
int
i
;
uuid_le
*
uuid_mod
;
struct
uuid_module
*
module
;
uuid_mod
=
(
uuid_le
*
)
mconfig
->
guid
;
list_for_each_entry
(
module
,
&
ctx
->
uuid_list
,
list
)
{
if
(
uuid_le_cmp
(
*
uuid_mod
,
module
->
uuid
)
==
0
)
{
if
(
mconfig
->
id
.
pvt_id
!=
0
)
i
=
(
mconfig
->
id
.
pvt_id
)
/
64
;
if
(
*
pvt_id
!=
0
)
i
=
(
*
pvt_id
)
/
64
;
else
i
=
0
;
module
->
pvt_id
[
i
]
&=
~
(
1
<<
(
mconfig
->
id
.
pvt_id
));
mconfig
->
id
.
pvt_id
=
-
1
;
module
->
pvt_id
[
i
]
&=
~
(
1
<<
(
*
pvt_id
));
*
pvt_id
=
-
1
;
return
0
;
}
}
...
...
@@ -405,3 +361,83 @@ int skl_dsp_strip_extended_manifest(struct firmware *fw)
return
0
;
}
int
skl_sst_ctx_init
(
struct
device
*
dev
,
int
irq
,
const
char
*
fw_name
,
struct
skl_dsp_loader_ops
dsp_ops
,
struct
skl_sst
**
dsp
,
struct
sst_dsp_device
*
skl_dev
)
{
struct
skl_sst
*
skl
;
struct
sst_dsp
*
sst
;
int
ret
;
skl
=
devm_kzalloc
(
dev
,
sizeof
(
*
skl
),
GFP_KERNEL
);
if
(
skl
==
NULL
)
return
-
ENOMEM
;
skl
->
dev
=
dev
;
skl_dev
->
thread_context
=
skl
;
INIT_LIST_HEAD
(
&
skl
->
uuid_list
);
skl
->
dsp
=
skl_dsp_ctx_init
(
dev
,
skl_dev
,
irq
);
if
(
!
skl
->
dsp
)
{
dev_err
(
skl
->
dev
,
"%s: no device
\n
"
,
__func__
);
return
-
ENODEV
;
}
sst
=
skl
->
dsp
;
sst
->
fw_name
=
fw_name
;
sst
->
dsp_ops
=
dsp_ops
;
init_waitqueue_head
(
&
skl
->
mod_load_wait
);
INIT_LIST_HEAD
(
&
sst
->
module_list
);
ret
=
skl_ipc_init
(
dev
,
skl
);
if
(
ret
)
return
ret
;
skl
->
is_first_boot
=
true
;
if
(
dsp
)
*
dsp
=
skl
;
return
ret
;
}
int
skl_prepare_lib_load
(
struct
skl_sst
*
skl
,
struct
skl_lib_info
*
linfo
,
struct
firmware
*
stripped_fw
,
unsigned
int
hdr_offset
,
int
index
)
{
int
ret
;
struct
sst_dsp
*
dsp
=
skl
->
dsp
;
if
(
linfo
->
fw
==
NULL
)
{
ret
=
request_firmware
(
&
linfo
->
fw
,
linfo
->
name
,
skl
->
dev
);
if
(
ret
<
0
)
{
dev_err
(
skl
->
dev
,
"Request lib %s failed:%d
\n
"
,
linfo
->
name
,
ret
);
return
ret
;
}
}
if
(
skl
->
is_first_boot
)
{
ret
=
snd_skl_parse_uuids
(
dsp
,
linfo
->
fw
,
hdr_offset
,
index
);
if
(
ret
<
0
)
return
ret
;
}
stripped_fw
->
data
=
linfo
->
fw
->
data
;
stripped_fw
->
size
=
linfo
->
fw
->
size
;
skl_dsp_strip_extended_manifest
(
stripped_fw
);
return
0
;
}
void
skl_release_library
(
struct
skl_lib_info
*
linfo
,
int
lib_count
)
{
int
i
;
/* library indices start from 1 to N. 0 represents base FW */
for
(
i
=
1
;
i
<
lib_count
;
i
++
)
{
if
(
linfo
[
i
].
fw
)
{
release_firmware
(
linfo
[
i
].
fw
);
linfo
[
i
].
fw
=
NULL
;
}
}
}
sound/soc/intel/skylake/skl-sst.c
View file @
0c2964cb
...
...
@@ -52,7 +52,8 @@ static int skl_transfer_firmware(struct sst_dsp *ctx,
{
int
ret
=
0
;
ret
=
ctx
->
cl_dev
.
ops
.
cl_copy_to_dmabuf
(
ctx
,
basefw
,
base_fw_size
);
ret
=
ctx
->
cl_dev
.
ops
.
cl_copy_to_dmabuf
(
ctx
,
basefw
,
base_fw_size
,
true
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -178,6 +179,18 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
dev_err
(
ctx
->
dev
,
"unable to load firmware
\n
"
);
return
ret
;
}
/* load libs as they are also lost on D3 */
if
(
skl
->
lib_count
>
1
)
{
ret
=
ctx
->
fw_ops
.
load_library
(
ctx
,
skl
->
lib_info
,
skl
->
lib_count
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"reload libs failed: %d
\n
"
,
ret
);
return
ret
;
}
}
}
/*
...
...
@@ -203,7 +216,7 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
skl
->
cores
.
state
[
core_id
]
=
SKL_DSP_RUNNING
;
return
ret
;
return
0
;
}
static
int
skl_set_dsp_D3
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_id
)
...
...
@@ -323,27 +336,85 @@ static struct skl_module_table *skl_module_get_from_id(
return
NULL
;
}
static
int
skl_transfer_module
(
struct
sst_dsp
*
ctx
,
struct
skl_load_module_info
*
module
)
static
int
skl_transfer_module
(
struct
sst_dsp
*
ctx
,
const
void
*
data
,
u32
size
,
u16
mod_id
,
u8
table_id
,
bool
is_
module
)
{
int
ret
;
int
ret
,
bytes_left
,
curr_pos
;
struct
skl_sst
*
skl
=
ctx
->
thread_context
;
skl
->
mod_load_complete
=
false
;
ret
=
ctx
->
cl_dev
.
ops
.
cl_copy_to_dmabuf
(
ctx
,
module
->
fw
->
data
,
module
->
fw
->
size
);
if
(
ret
<
0
)
return
ret
;
bytes_left
=
ctx
->
cl_dev
.
ops
.
cl_copy_to_dmabuf
(
ctx
,
data
,
size
,
false
);
if
(
bytes_left
<
0
)
return
bytes_left
;
ret
=
skl_ipc_load_modules
(
&
skl
->
ipc
,
SKL_NUM_MODULES
,
(
void
*
)
&
module
->
mod_id
);
if
(
ret
<
0
)
dev_err
(
ctx
->
dev
,
"Failed to Load module: %d
\n
"
,
ret
);
/* check is_module flag to load module or library */
if
(
is_module
)
ret
=
skl_ipc_load_modules
(
&
skl
->
ipc
,
SKL_NUM_MODULES
,
&
mod_id
);
else
ret
=
skl_sst_ipc_load_library
(
&
skl
->
ipc
,
0
,
table_id
,
false
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Failed to Load %s with err %d
\n
"
,
is_module
?
"module"
:
"lib"
,
ret
);
goto
out
;
}
/*
* if bytes_left > 0 then wait for BDL complete interrupt and
* copy the next chunk till bytes_left is 0. if bytes_left is
* is zero, then wait for load module IPC reply
*/
while
(
bytes_left
>
0
)
{
curr_pos
=
size
-
bytes_left
;
ret
=
skl_cldma_wait_interruptible
(
ctx
);
if
(
ret
<
0
)
goto
out
;
bytes_left
=
ctx
->
cl_dev
.
ops
.
cl_copy_to_dmabuf
(
ctx
,
data
+
curr_pos
,
bytes_left
,
false
);
}
ret
=
wait_event_timeout
(
skl
->
mod_load_wait
,
skl
->
mod_load_complete
,
msecs_to_jiffies
(
SKL_IPC_BOOT_MSECS
));
if
(
ret
==
0
||
!
skl
->
mod_load_status
)
{
dev_err
(
ctx
->
dev
,
"Module Load failed
\n
"
);
ret
=
-
EIO
;
}
out:
ctx
->
cl_dev
.
ops
.
cl_stop_dma
(
ctx
);
return
ret
;
}
static
int
kbl_load_library
(
struct
sst_dsp
*
ctx
,
struct
skl_lib_info
*
linfo
,
int
lib_count
)
{
struct
skl_sst
*
skl
=
ctx
->
thread_context
;
struct
firmware
stripped_fw
;
int
ret
,
i
;
/* library indices start from 1 to N. 0 represents base FW */
for
(
i
=
1
;
i
<
lib_count
;
i
++
)
{
ret
=
skl_prepare_lib_load
(
skl
,
&
skl
->
lib_info
[
i
],
&
stripped_fw
,
SKL_ADSP_FW_BIN_HDR_OFFSET
,
i
);
if
(
ret
<
0
)
goto
load_library_failed
;
ret
=
skl_transfer_module
(
ctx
,
stripped_fw
.
data
,
stripped_fw
.
size
,
0
,
i
,
false
);
if
(
ret
<
0
)
goto
load_library_failed
;
}
return
0
;
load_library_failed:
skl_release_library
(
linfo
,
lib_count
);
return
ret
;
}
static
int
skl_load_module
(
struct
sst_dsp
*
ctx
,
u16
mod_id
,
u8
*
guid
)
{
struct
skl_module_table
*
module_entry
=
NULL
;
...
...
@@ -365,7 +436,9 @@ static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
}
if
(
!
module_entry
->
usage_cnt
)
{
ret
=
skl_transfer_module
(
ctx
,
module_entry
->
mod_info
);
ret
=
skl_transfer_module
(
ctx
,
module_entry
->
mod_info
->
fw
->
data
,
module_entry
->
mod_info
->
fw
->
size
,
mod_id
,
0
,
true
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"Failed to Load module
\n
"
);
return
ret
;
...
...
@@ -388,6 +461,11 @@ static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id)
dev_err
(
ctx
->
dev
,
"Module bad usage cnt!:%d
\n
"
,
usage_cnt
);
return
-
EIO
;
}
/* if module is used by others return, no need to unload */
if
(
usage_cnt
>
0
)
return
0
;
ret
=
skl_ipc_unload_modules
(
&
skl
->
ipc
,
SKL_NUM_MODULES
,
&
mod_id
);
if
(
ret
<
0
)
{
...
...
@@ -434,6 +512,16 @@ static struct skl_dsp_fw_ops skl_fw_ops = {
.
unload_mod
=
skl_unload_module
,
};
static
struct
skl_dsp_fw_ops
kbl_fw_ops
=
{
.
set_state_D0
=
skl_set_dsp_D0
,
.
set_state_D3
=
skl_set_dsp_D3
,
.
load_fw
=
skl_load_base_firmware
,
.
get_fw_errcode
=
skl_get_errorcode
,
.
load_library
=
kbl_load_library
,
.
load_mod
=
skl_load_module
,
.
unload_mod
=
skl_unload_module
,
};
static
struct
sst_ops
skl_ops
=
{
.
irq_handler
=
skl_dsp_sst_interrupt
,
.
write
=
sst_shim32_write
,
...
...
@@ -455,45 +543,47 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
struct
sst_dsp
*
sst
;
int
ret
;
skl
=
devm_kzalloc
(
dev
,
sizeof
(
*
skl
),
GFP_KERNEL
);
if
(
skl
==
NULL
)
return
-
ENOMEM
;
skl
->
dev
=
dev
;
skl_dev
.
thread_context
=
skl
;
INIT_LIST_HEAD
(
&
skl
->
uuid_list
);
skl
->
dsp
=
skl_dsp_ctx_init
(
dev
,
&
skl_dev
,
irq
);
if
(
!
skl
->
dsp
)
{
dev_err
(
skl
->
dev
,
"%s: no device
\n
"
,
__func__
);
return
-
ENODEV
;
ret
=
skl_sst_ctx_init
(
dev
,
irq
,
fw_name
,
dsp_ops
,
dsp
,
&
skl_dev
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"%s: no device
\n
"
,
__func__
);
return
ret
;
}
skl
=
*
dsp
;
sst
=
skl
->
dsp
;
sst
->
fw_name
=
fw_name
;
sst
->
addr
.
lpe
=
mmio_base
;
sst
->
addr
.
shim
=
mmio_base
;
sst_dsp_mailbox_init
(
sst
,
(
SKL_ADSP_SRAM0_BASE
+
SKL_ADSP_W0_STAT_SZ
),
SKL_ADSP_W0_UP_SZ
,
SKL_ADSP_SRAM1_BASE
,
SKL_ADSP_W1_SZ
);
INIT_LIST_HEAD
(
&
sst
->
module_list
);
sst
->
dsp_ops
=
dsp_ops
;
sst
->
fw_ops
=
skl_fw_ops
;
ret
=
skl_ipc_init
(
dev
,
skl
);
if
(
ret
)
skl
->
cores
.
count
=
2
;
return
0
;
}
EXPORT_SYMBOL_GPL
(
skl_sst_dsp_init
);
int
kbl_sst_dsp_init
(
struct
device
*
dev
,
void
__iomem
*
mmio_base
,
int
irq
,
const
char
*
fw_name
,
struct
skl_dsp_loader_ops
dsp_ops
,
struct
skl_sst
**
dsp
)
{
struct
sst_dsp
*
sst
;
int
ret
;
ret
=
skl_sst_dsp_init
(
dev
,
mmio_base
,
irq
,
fw_name
,
dsp_ops
,
dsp
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"%s: Init failed %d
\n
"
,
__func__
,
ret
);
return
ret
;
}
s
kl
->
cores
.
count
=
2
;
s
kl
->
is_first_boot
=
true
;
s
st
=
(
*
dsp
)
->
dsp
;
s
st
->
fw_ops
=
kbl_fw_ops
;
if
(
dsp
)
*
dsp
=
skl
;
return
0
;
return
ret
;
}
EXPORT_SYMBOL_GPL
(
sk
l_sst_dsp_init
);
EXPORT_SYMBOL_GPL
(
kb
l_sst_dsp_init
);
int
skl_sst_init_fw
(
struct
device
*
dev
,
struct
skl_sst
*
ctx
)
{
...
...
@@ -507,6 +597,15 @@ int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
}
skl_dsp_init_core_state
(
sst
);
if
(
ctx
->
lib_count
>
1
)
{
ret
=
sst
->
fw_ops
.
load_library
(
sst
,
ctx
->
lib_info
,
ctx
->
lib_count
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"Load Library failed : %x
\n
"
,
ret
);
return
ret
;
}
}
ctx
->
is_first_boot
=
false
;
return
0
;
...
...
sound/soc/intel/skylake/skl-topology.c
View file @
0c2964cb
This diff is collapsed.
Click to expand it.
sound/soc/intel/skylake/skl-topology.h
View file @
0c2964cb
...
...
@@ -257,6 +257,8 @@ struct skl_pipe_params {
snd_pcm_format_t
format
;
int
link_index
;
int
stream
;
unsigned
int
host_bps
;
unsigned
int
link_bps
;
};
struct
skl_pipe
{
...
...
@@ -334,17 +336,10 @@ struct skl_pipeline {
struct
list_head
node
;
};
#define SKL_LIB_NAME_LENGTH 128
#define SKL_MAX_LIB 16
struct
skl_lib_info
{
char
name
[
SKL_LIB_NAME_LENGTH
];
const
struct
firmware
*
fw
;
};
struct
skl_manifest
{
u32
lib_count
;
struct
skl_lib_info
lib
[
SKL_MAX_LIB
];
struct
skl_module_deferred_bind
{
struct
skl_module_cfg
*
src
;
struct
skl_module_cfg
*
dst
;
struct
list_head
node
;
};
static
inline
struct
skl
*
get_skl_ctx
(
struct
device
*
dev
)
...
...
sound/soc/intel/skylake/skl.c
View file @
0c2964cb
...
...
@@ -512,7 +512,7 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr)
struct
hdac_bus
*
bus
=
ebus_to_hbus
(
ebus
);
unsigned
int
cmd
=
(
addr
<<
28
)
|
(
AC_NODE_ROOT
<<
20
)
|
(
AC_VERB_PARAMETERS
<<
8
)
|
AC_PAR_VENDOR_ID
;
unsigned
int
res
;
unsigned
int
res
=
-
1
;
mutex_lock
(
&
bus
->
cmd_mutex
);
snd_hdac_bus_send_cmd
(
bus
,
cmd
);
...
...
sound/soc/intel/skylake/skl.h
View file @
0c2964cb
...
...
@@ -77,6 +77,7 @@ struct skl {
struct
skl_dsp_resource
resource
;
struct
list_head
ppl_list
;
struct
list_head
bind_list
;
const
char
*
fw_name
;
char
tplg_name
[
64
];
...
...
sound/soc/soc-core.c
View file @
0c2964cb
...
...
@@ -1913,6 +1913,7 @@ int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
EXPORT_SYMBOL_GPL
(
snd_soc_runtime_set_dai_fmt
);
#ifdef CONFIG_DMI
/* Trim special characters, and replace '-' with '_' since '-' is used to
* separate different DMI fields in the card long name. Only number and
* alphabet characters and a few separator characters are kept.
...
...
@@ -2044,6 +2045,7 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_set_dmi_name
);
#endif
/* CONFIG_DMI */
static
int
snd_soc_instantiate_card
(
struct
snd_soc_card
*
card
)
{
...
...
@@ -2185,6 +2187,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
snd_soc_dapm_add_routes
(
&
card
->
dapm
,
card
->
of_dapm_routes
,
card
->
num_of_dapm_routes
);
/* try to set some sane longname if DMI is available */
snd_soc_set_dmi_name
(
card
,
NULL
);
snprintf
(
card
->
snd_card
->
shortname
,
sizeof
(
card
->
snd_card
->
shortname
),
"%s"
,
card
->
name
);
snprintf
(
card
->
snd_card
->
longname
,
sizeof
(
card
->
snd_card
->
longname
),
...
...
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