Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
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