Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
460f623a
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
460f623a
编写于
9月 01, 2017
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
上级
39e0a0ae
38a77085
变更
30
展开全部
隐藏空白更改
内联
并排
Showing
30 changed file
with
2419 addition
and
277 deletion
+2419
-277
include/uapi/sound/snd_sst_tokens.h
include/uapi/sound/snd_sst_tokens.h
+91
-1
sound/soc/codecs/Makefile
sound/soc/codecs/Makefile
+1
-0
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/hdac_hdmi.c
+34
-5
sound/soc/codecs/max98371.c
sound/soc/codecs/max98371.c
+8
-6
sound/soc/intel/Kconfig
sound/soc/intel/Kconfig
+2
-1
sound/soc/intel/atom/sst-mfld-platform-pcm.c
sound/soc/intel/atom/sst-mfld-platform-pcm.c
+5
-5
sound/soc/intel/atom/sst/sst_drv_interface.c
sound/soc/intel/atom/sst/sst_drv_interface.c
+2
-2
sound/soc/intel/atom/sst/sst_pci.c
sound/soc/intel/atom/sst/sst_pci.c
+1
-1
sound/soc/intel/baytrail/sst-baytrail-pcm.c
sound/soc/intel/baytrail/sst-baytrail-pcm.c
+2
-2
sound/soc/intel/boards/bxt_rt298.c
sound/soc/intel/boards/bxt_rt298.c
+82
-4
sound/soc/intel/boards/kbl_rt5663_max98927.c
sound/soc/intel/boards/kbl_rt5663_max98927.c
+258
-52
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+68
-13
sound/soc/intel/boards/mfld_machine.c
sound/soc/intel/boards/mfld_machine.c
+1
-3
sound/soc/intel/haswell/sst-haswell-pcm.c
sound/soc/intel/haswell/sst-haswell-pcm.c
+1
-1
sound/soc/intel/skylake/Makefile
sound/soc/intel/skylake/Makefile
+3
-2
sound/soc/intel/skylake/bxt-sst.c
sound/soc/intel/skylake/bxt-sst.c
+7
-7
sound/soc/intel/skylake/cnl-sst-dsp.c
sound/soc/intel/skylake/cnl-sst-dsp.c
+274
-0
sound/soc/intel/skylake/cnl-sst-dsp.h
sound/soc/intel/skylake/cnl-sst-dsp.h
+112
-0
sound/soc/intel/skylake/cnl-sst.c
sound/soc/intel/skylake/cnl-sst.c
+497
-0
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl-messages.c
+135
-28
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-pcm.c
+72
-10
sound/soc/intel/skylake/skl-sst-dsp.c
sound/soc/intel/skylake/skl-sst-dsp.c
+3
-3
sound/soc/intel/skylake/skl-sst-ipc.c
sound/soc/intel/skylake/skl-sst-ipc.c
+3
-3
sound/soc/intel/skylake/skl-sst-ipc.h
sound/soc/intel/skylake/skl-sst-ipc.h
+8
-4
sound/soc/intel/skylake/skl-sst-utils.c
sound/soc/intel/skylake/skl-sst-utils.c
+1
-5
sound/soc/intel/skylake/skl-sst.c
sound/soc/intel/skylake/skl-sst.c
+8
-4
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl-topology.c
+633
-108
sound/soc/intel/skylake/skl-topology.h
sound/soc/intel/skylake/skl-topology.h
+83
-0
sound/soc/intel/skylake/skl.c
sound/soc/intel/skylake/skl.c
+21
-7
sound/soc/intel/skylake/skl.h
sound/soc/intel/skylake/skl.h
+3
-0
未找到文件。
include/uapi/sound/snd_sst_tokens.h
浏览文件 @
460f623a
...
@@ -163,8 +163,71 @@
...
@@ -163,8 +163,71 @@
*
*
* %SKL_TKN_U32_DMA_BUF_SIZE: DMA buffer size in millisec
* %SKL_TKN_U32_DMA_BUF_SIZE: DMA buffer size in millisec
*
*
* %SKL_TKN_U32_PIPE_DIR: Specifies pipe direction. Can be
* playback/capture.
*
* %SKL_TKN_U32_NUM_CONFIGS: Number of pipe configs
*
* %SKL_TKN_U32_PATH_MEM_PGS: Size of memory (in pages) required for pipeline
* and its data
*
* %SKL_TKN_U32_PIPE_CONFIG_ID: Config id for the modules in the pipe
* and PCM params supported by that pipe
* config. This is used as index to fill
* up the pipe config and module config
* structure.
*
* %SKL_TKN_U32_CFG_FREQ:
* %SKL_TKN_U8_CFG_CHAN:
* %SKL_TKN_U8_CFG_BPS: PCM params (freq, channels, bits per sample)
* supported for each of the pipe configs.
*
* %SKL_TKN_CFG_MOD_RES_ID: Module's resource index for each of the
* pipe config
*
* %SKL_TKN_CFG_MOD_FMT_ID: Module's interface index for each of the
* pipe config
*
* %SKL_TKN_U8_NUM_MOD: Number of modules in the manifest
*
* %SKL_TKN_MM_U8_MOD_IDX: Current index of the module in the manifest
*
* %SKL_TKN_MM_U8_NUM_RES: Number of resources for the module
*
* %SKL_TKN_MM_U8_NUM_INTF: Number of interfaces for the module
*
* %SKL_TKN_MM_U32_RES_ID: Resource index for the resource info to
* be filled into.
* A module can support multiple resource
* configuration and is represnted as a
* resource table. This index is used to
* fill information into appropriate index.
*
* %SKL_TKN_MM_U32_CPS: DSP cycles per second
*
* %SKL_TKN_MM_U32_DMA_SIZE: Allocated buffer size for gateway DMA
*
* %SKL_TKN_MM_U32_CPC: DSP cycles allocated per frame
*
* %SKL_TKN_MM_U32_RES_PIN_ID: Resource pin index in the module
*
* %SKL_TKN_MM_U32_INTF_PIN_ID: Interface index in the module
*
* %SKL_TKN_MM_U32_PIN_BUF: Buffer size of the module pin
*
* %SKL_TKN_MM_U32_FMT_ID: Format index for each of the interface/
* format information to be filled into.
*
* %SKL_TKN_MM_U32_NUM_IN_FMT: Number of input formats
* %SKL_TKN_MM_U32_NUM_OUT_FMT: Number of output formats
*
* module_id and loadable flags dont have tokens as these values will be
* module_id and loadable flags dont have tokens as these values will be
* read from the DSP FW manifest
* read from the DSP FW manifest
*
* Tokens defined can be used either in the manifest or widget private data.
*
* SKL_TKN_MM is used as a suffix for all tokens that represent
* module data in the manifest.
*/
*/
enum
SKL_TKNS
{
enum
SKL_TKNS
{
SKL_TKN_UUID
=
1
,
SKL_TKN_UUID
=
1
,
...
@@ -218,7 +281,34 @@ enum SKL_TKNS {
...
@@ -218,7 +281,34 @@ enum SKL_TKNS {
SKL_TKL_U32_D0I3_CAPS
,
/* Typo added at v4.10 */
SKL_TKL_U32_D0I3_CAPS
,
/* Typo added at v4.10 */
SKL_TKN_U32_D0I3_CAPS
=
SKL_TKL_U32_D0I3_CAPS
,
SKL_TKN_U32_D0I3_CAPS
=
SKL_TKL_U32_D0I3_CAPS
,
SKL_TKN_U32_DMA_BUF_SIZE
,
SKL_TKN_U32_DMA_BUF_SIZE
,
SKL_TKN_MAX
=
SKL_TKN_U32_DMA_BUF_SIZE
,
SKL_TKN_U32_PIPE_DIRECTION
,
SKL_TKN_U32_PIPE_CONFIG_ID
,
SKL_TKN_U32_NUM_CONFIGS
,
SKL_TKN_U32_PATH_MEM_PGS
,
SKL_TKN_U32_CFG_FREQ
,
SKL_TKN_U8_CFG_CHAN
,
SKL_TKN_U8_CFG_BPS
,
SKL_TKN_CFG_MOD_RES_ID
,
SKL_TKN_CFG_MOD_FMT_ID
,
SKL_TKN_U8_NUM_MOD
,
SKL_TKN_MM_U8_MOD_IDX
,
SKL_TKN_MM_U8_NUM_RES
,
SKL_TKN_MM_U8_NUM_INTF
,
SKL_TKN_MM_U32_RES_ID
,
SKL_TKN_MM_U32_CPS
,
SKL_TKN_MM_U32_DMA_SIZE
,
SKL_TKN_MM_U32_CPC
,
SKL_TKN_MM_U32_RES_PIN_ID
,
SKL_TKN_MM_U32_INTF_PIN_ID
,
SKL_TKN_MM_U32_PIN_BUF
,
SKL_TKN_MM_U32_FMT_ID
,
SKL_TKN_MM_U32_NUM_IN_FMT
,
SKL_TKN_MM_U32_NUM_OUT_FMT
,
SKL_TKN_MAX
=
SKL_TKN_MM_U32_NUM_OUT_FMT
,
};
};
#endif
#endif
sound/soc/codecs/Makefile
浏览文件 @
460f623a
...
@@ -321,6 +321,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
...
@@ -321,6 +321,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
obj-$(CONFIG_SND_SOC_MAX98090)
+=
snd-soc-max98090.o
obj-$(CONFIG_SND_SOC_MAX98090)
+=
snd-soc-max98090.o
obj-$(CONFIG_SND_SOC_MAX98095)
+=
snd-soc-max98095.o
obj-$(CONFIG_SND_SOC_MAX98095)
+=
snd-soc-max98095.o
obj-$(CONFIG_SND_SOC_MAX98357A)
+=
snd-soc-max98357a.o
obj-$(CONFIG_SND_SOC_MAX98357A)
+=
snd-soc-max98357a.o
obj-$(CONFIG_SND_SOC_MAX98371)
+=
snd-soc-max98371.o
obj-$(CONFIG_SND_SOC_MAX9867)
+=
snd-soc-max9867.o
obj-$(CONFIG_SND_SOC_MAX9867)
+=
snd-soc-max9867.o
obj-$(CONFIG_SND_SOC_MAX98925)
+=
snd-soc-max98925.o
obj-$(CONFIG_SND_SOC_MAX98925)
+=
snd-soc-max98925.o
obj-$(CONFIG_SND_SOC_MAX98926)
+=
snd-soc-max98926.o
obj-$(CONFIG_SND_SOC_MAX98926)
+=
snd-soc-max98926.o
...
...
sound/soc/codecs/hdac_hdmi.c
浏览文件 @
460f623a
...
@@ -121,6 +121,10 @@ struct hdac_hdmi_dai_port_map {
...
@@ -121,6 +121,10 @@ struct hdac_hdmi_dai_port_map {
struct
hdac_hdmi_cvt
*
cvt
;
struct
hdac_hdmi_cvt
*
cvt
;
};
};
struct
hdac_hdmi_drv_data
{
unsigned
int
vendor_nid
;
};
struct
hdac_hdmi_priv
{
struct
hdac_hdmi_priv
{
struct
hdac_hdmi_dai_port_map
dai_map
[
HDA_MAX_CVTS
];
struct
hdac_hdmi_dai_port_map
dai_map
[
HDA_MAX_CVTS
];
struct
list_head
pin_list
;
struct
list_head
pin_list
;
...
@@ -131,6 +135,7 @@ struct hdac_hdmi_priv {
...
@@ -131,6 +135,7 @@ struct hdac_hdmi_priv {
int
num_ports
;
int
num_ports
;
struct
mutex
pin_mutex
;
struct
mutex
pin_mutex
;
struct
hdac_chmap
chmap
;
struct
hdac_chmap
chmap
;
struct
hdac_hdmi_drv_data
*
drv_data
;
};
};
static
struct
hdac_hdmi_pcm
*
static
struct
hdac_hdmi_pcm
*
...
@@ -1321,6 +1326,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
...
@@ -1321,6 +1326,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
}
}
#define INTEL_VENDOR_NID 0x08
#define INTEL_VENDOR_NID 0x08
#define INTEL_GLK_VENDOR_NID 0x0b
#define INTEL_GET_VENDOR_VERB 0xf81
#define INTEL_GET_VENDOR_VERB 0xf81
#define INTEL_SET_VENDOR_VERB 0x781
#define INTEL_SET_VENDOR_VERB 0x781
#define INTEL_EN_DP12 0x02
/* enable DP 1.2 features */
#define INTEL_EN_DP12 0x02
/* enable DP 1.2 features */
...
@@ -1329,14 +1335,17 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
...
@@ -1329,14 +1335,17 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
static
void
hdac_hdmi_skl_enable_all_pins
(
struct
hdac_device
*
hdac
)
static
void
hdac_hdmi_skl_enable_all_pins
(
struct
hdac_device
*
hdac
)
{
{
unsigned
int
vendor_param
;
unsigned
int
vendor_param
;
struct
hdac_ext_device
*
edev
=
to_ehdac_device
(
hdac
);
struct
hdac_hdmi_priv
*
hdmi
=
edev
->
private_data
;
unsigned
int
vendor_nid
=
hdmi
->
drv_data
->
vendor_nid
;
vendor_param
=
snd_hdac_codec_read
(
hdac
,
INTEL_VENDOR_NID
,
0
,
vendor_param
=
snd_hdac_codec_read
(
hdac
,
vendor_nid
,
0
,
INTEL_GET_VENDOR_VERB
,
0
);
INTEL_GET_VENDOR_VERB
,
0
);
if
(
vendor_param
==
-
1
||
vendor_param
&
INTEL_EN_ALL_PIN_CVTS
)
if
(
vendor_param
==
-
1
||
vendor_param
&
INTEL_EN_ALL_PIN_CVTS
)
return
;
return
;
vendor_param
|=
INTEL_EN_ALL_PIN_CVTS
;
vendor_param
|=
INTEL_EN_ALL_PIN_CVTS
;
vendor_param
=
snd_hdac_codec_read
(
hdac
,
INTEL_VENDOR_NID
,
0
,
vendor_param
=
snd_hdac_codec_read
(
hdac
,
vendor_nid
,
0
,
INTEL_SET_VENDOR_VERB
,
vendor_param
);
INTEL_SET_VENDOR_VERB
,
vendor_param
);
if
(
vendor_param
==
-
1
)
if
(
vendor_param
==
-
1
)
return
;
return
;
...
@@ -1345,15 +1354,18 @@ static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
...
@@ -1345,15 +1354,18 @@ static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
static
void
hdac_hdmi_skl_enable_dp12
(
struct
hdac_device
*
hdac
)
static
void
hdac_hdmi_skl_enable_dp12
(
struct
hdac_device
*
hdac
)
{
{
unsigned
int
vendor_param
;
unsigned
int
vendor_param
;
struct
hdac_ext_device
*
edev
=
to_ehdac_device
(
hdac
);
struct
hdac_hdmi_priv
*
hdmi
=
edev
->
private_data
;
unsigned
int
vendor_nid
=
hdmi
->
drv_data
->
vendor_nid
;
vendor_param
=
snd_hdac_codec_read
(
hdac
,
INTEL_VENDOR_NID
,
0
,
vendor_param
=
snd_hdac_codec_read
(
hdac
,
vendor_nid
,
0
,
INTEL_GET_VENDOR_VERB
,
0
);
INTEL_GET_VENDOR_VERB
,
0
);
if
(
vendor_param
==
-
1
||
vendor_param
&
INTEL_EN_DP12
)
if
(
vendor_param
==
-
1
||
vendor_param
&
INTEL_EN_DP12
)
return
;
return
;
/* enable DP1.2 mode */
/* enable DP1.2 mode */
vendor_param
|=
INTEL_EN_DP12
;
vendor_param
|=
INTEL_EN_DP12
;
vendor_param
=
snd_hdac_codec_read
(
hdac
,
INTEL_VENDOR_NID
,
0
,
vendor_param
=
snd_hdac_codec_read
(
hdac
,
vendor_nid
,
0
,
INTEL_SET_VENDOR_VERB
,
vendor_param
);
INTEL_SET_VENDOR_VERB
,
vendor_param
);
if
(
vendor_param
==
-
1
)
if
(
vendor_param
==
-
1
)
return
;
return
;
...
@@ -1927,6 +1939,14 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
...
@@ -1927,6 +1939,14 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
return
port
->
eld
.
info
.
spk_alloc
;
return
port
->
eld
.
info
.
spk_alloc
;
}
}
static
struct
hdac_hdmi_drv_data
intel_glk_drv_data
=
{
.
vendor_nid
=
INTEL_GLK_VENDOR_NID
,
};
static
struct
hdac_hdmi_drv_data
intel_drv_data
=
{
.
vendor_nid
=
INTEL_VENDOR_NID
,
};
static
int
hdac_hdmi_dev_probe
(
struct
hdac_ext_device
*
edev
)
static
int
hdac_hdmi_dev_probe
(
struct
hdac_ext_device
*
edev
)
{
{
struct
hdac_device
*
codec
=
&
edev
->
hdac
;
struct
hdac_device
*
codec
=
&
edev
->
hdac
;
...
@@ -1935,6 +1955,8 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
...
@@ -1935,6 +1955,8 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
struct
hdac_ext_link
*
hlink
=
NULL
;
struct
hdac_ext_link
*
hlink
=
NULL
;
int
num_dais
=
0
;
int
num_dais
=
0
;
int
ret
=
0
;
int
ret
=
0
;
struct
hdac_driver
*
hdrv
=
drv_to_hdac_driver
(
codec
->
dev
.
driver
);
const
struct
hda_device_id
*
hdac_id
=
hdac_get_device_id
(
codec
,
hdrv
);
/* hold the ref while we probe */
/* hold the ref while we probe */
hlink
=
snd_hdac_ext_bus_get_link
(
edev
->
ebus
,
dev_name
(
&
edev
->
hdac
.
dev
));
hlink
=
snd_hdac_ext_bus_get_link
(
edev
->
ebus
,
dev_name
(
&
edev
->
hdac
.
dev
));
...
@@ -1956,6 +1978,12 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
...
@@ -1956,6 +1978,12 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
hdmi_priv
->
chmap
.
ops
.
is_pcm_attached
=
is_hdac_hdmi_pcm_attached
;
hdmi_priv
->
chmap
.
ops
.
is_pcm_attached
=
is_hdac_hdmi_pcm_attached
;
hdmi_priv
->
chmap
.
ops
.
get_spk_alloc
=
hdac_hdmi_get_spk_alloc
;
hdmi_priv
->
chmap
.
ops
.
get_spk_alloc
=
hdac_hdmi_get_spk_alloc
;
if
(
hdac_id
->
driver_data
)
hdmi_priv
->
drv_data
=
(
struct
hdac_hdmi_drv_data
*
)
hdac_id
->
driver_data
;
else
hdmi_priv
->
drv_data
=
&
intel_drv_data
;
dev_set_drvdata
(
&
codec
->
dev
,
edev
);
dev_set_drvdata
(
&
codec
->
dev
,
edev
);
INIT_LIST_HEAD
(
&
hdmi_priv
->
pin_list
);
INIT_LIST_HEAD
(
&
hdmi_priv
->
pin_list
);
...
@@ -2127,7 +2155,8 @@ static const struct hda_device_id hdmi_list[] = {
...
@@ -2127,7 +2155,8 @@ static const struct hda_device_id hdmi_list[] = {
HDA_CODEC_EXT_ENTRY
(
0x80862809
,
0x100000
,
"Skylake HDMI"
,
0
),
HDA_CODEC_EXT_ENTRY
(
0x80862809
,
0x100000
,
"Skylake HDMI"
,
0
),
HDA_CODEC_EXT_ENTRY
(
0x8086280a
,
0x100000
,
"Broxton HDMI"
,
0
),
HDA_CODEC_EXT_ENTRY
(
0x8086280a
,
0x100000
,
"Broxton HDMI"
,
0
),
HDA_CODEC_EXT_ENTRY
(
0x8086280b
,
0x100000
,
"Kabylake HDMI"
,
0
),
HDA_CODEC_EXT_ENTRY
(
0x8086280b
,
0x100000
,
"Kabylake HDMI"
,
0
),
HDA_CODEC_EXT_ENTRY
(
0x8086280d
,
0x100000
,
"Geminilake HDMI"
,
0
),
HDA_CODEC_EXT_ENTRY
(
0x8086280d
,
0x100000
,
"Geminilake HDMI"
,
&
intel_glk_drv_data
),
{}
{}
};
};
...
...
sound/soc/codecs/max98371.c
浏览文件 @
460f623a
...
@@ -349,12 +349,14 @@ static struct snd_soc_dai_driver max98371_dai[] = {
...
@@ -349,12 +349,14 @@ static struct snd_soc_dai_driver max98371_dai[] = {
};
};
static
const
struct
snd_soc_codec_driver
max98371_codec
=
{
static
const
struct
snd_soc_codec_driver
max98371_codec
=
{
.
controls
=
max98371_snd_controls
,
.
component_driver
=
{
.
num_controls
=
ARRAY_SIZE
(
max98371_snd_controls
),
.
controls
=
max98371_snd_controls
,
.
dapm_routes
=
max98371_audio_map
,
.
num_controls
=
ARRAY_SIZE
(
max98371_snd_controls
),
.
num_dapm_routes
=
ARRAY_SIZE
(
max98371_audio_map
),
.
dapm_routes
=
max98371_audio_map
,
.
dapm_widgets
=
max98371_dapm_widgets
,
.
num_dapm_routes
=
ARRAY_SIZE
(
max98371_audio_map
),
.
num_dapm_widgets
=
ARRAY_SIZE
(
max98371_dapm_widgets
),
.
dapm_widgets
=
max98371_dapm_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
max98371_dapm_widgets
),
},
};
};
static
const
struct
regmap_config
max98371_regmap
=
{
static
const
struct
regmap_config
max98371_regmap
=
{
...
...
sound/soc/intel/Kconfig
浏览文件 @
460f623a
...
@@ -255,11 +255,12 @@ config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH
...
@@ -255,11 +255,12 @@ config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH
config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH
config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH
tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode"
tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode"
depends on X86_INTEL_LPSS && I2C
depends on X86_INTEL_LPSS && I2C
&& SPI
select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SKYLAKE
select SND_SOC_INTEL_SKYLAKE
select SND_SOC_RT5663
select SND_SOC_RT5663
select SND_SOC_RT5514
select SND_SOC_RT5514
select SND_SOC_RT5514_SPI
select SND_SOC_MAX98927
select SND_SOC_MAX98927
select SND_SOC_HDAC_HDMI
select SND_SOC_HDAC_HDMI
help
help
...
...
sound/soc/intel/atom/sst-mfld-platform-pcm.c
浏览文件 @
460f623a
...
@@ -76,7 +76,7 @@ int sst_unregister_dsp(struct sst_device *dev)
...
@@ -76,7 +76,7 @@ int sst_unregister_dsp(struct sst_device *dev)
}
}
EXPORT_SYMBOL_GPL
(
sst_unregister_dsp
);
EXPORT_SYMBOL_GPL
(
sst_unregister_dsp
);
static
struct
snd_pcm_hardware
sst_platform_pcm_hw
=
{
static
const
struct
snd_pcm_hardware
sst_platform_pcm_hw
=
{
.
info
=
(
SNDRV_PCM_INFO_INTERLEAVED
|
.
info
=
(
SNDRV_PCM_INFO_INTERLEAVED
|
SNDRV_PCM_INFO_DOUBLE
|
SNDRV_PCM_INFO_DOUBLE
|
SNDRV_PCM_INFO_PAUSE
|
SNDRV_PCM_INFO_PAUSE
|
...
@@ -471,7 +471,7 @@ static void sst_disable_ssp(struct snd_pcm_substream *substream,
...
@@ -471,7 +471,7 @@ static void sst_disable_ssp(struct snd_pcm_substream *substream,
}
}
}
}
static
struct
snd_soc_dai_ops
sst_media_dai_ops
=
{
static
const
struct
snd_soc_dai_ops
sst_media_dai_ops
=
{
.
startup
=
sst_media_open
,
.
startup
=
sst_media_open
,
.
shutdown
=
sst_media_close
,
.
shutdown
=
sst_media_close
,
.
prepare
=
sst_media_prepare
,
.
prepare
=
sst_media_prepare
,
...
@@ -480,11 +480,11 @@ static struct snd_soc_dai_ops sst_media_dai_ops = {
...
@@ -480,11 +480,11 @@ static struct snd_soc_dai_ops sst_media_dai_ops = {
.
mute_stream
=
sst_media_digital_mute
,
.
mute_stream
=
sst_media_digital_mute
,
};
};
static
struct
snd_soc_dai_ops
sst_compr_dai_ops
=
{
static
const
struct
snd_soc_dai_ops
sst_compr_dai_ops
=
{
.
mute_stream
=
sst_media_digital_mute
,
.
mute_stream
=
sst_media_digital_mute
,
};
};
static
struct
snd_soc_dai_ops
sst_be_dai_ops
=
{
static
const
struct
snd_soc_dai_ops
sst_be_dai_ops
=
{
.
startup
=
sst_enable_ssp
,
.
startup
=
sst_enable_ssp
,
.
hw_params
=
sst_be_hw_params
,
.
hw_params
=
sst_be_hw_params
,
.
set_fmt
=
sst_set_format
,
.
set_fmt
=
sst_set_format
,
...
@@ -705,7 +705,7 @@ static int sst_soc_probe(struct snd_soc_platform *platform)
...
@@ -705,7 +705,7 @@ static int sst_soc_probe(struct snd_soc_platform *platform)
return
sst_dsp_init_v2_dpcm
(
platform
);
return
sst_dsp_init_v2_dpcm
(
platform
);
}
}
static
struct
snd_soc_platform_driver
sst_soc_platform_drv
=
{
static
const
struct
snd_soc_platform_driver
sst_soc_platform_drv
=
{
.
probe
=
sst_soc_probe
,
.
probe
=
sst_soc_probe
,
.
ops
=
&
sst_platform_ops
,
.
ops
=
&
sst_platform_ops
,
.
compr_ops
=
&
sst_platform_compr_ops
,
.
compr_ops
=
&
sst_platform_compr_ops
,
...
...
sound/soc/intel/atom/sst/sst_drv_interface.c
浏览文件 @
460f623a
...
@@ -407,7 +407,7 @@ static int sst_cdev_caps(struct snd_compr_caps *caps)
...
@@ -407,7 +407,7 @@ static int sst_cdev_caps(struct snd_compr_caps *caps)
return
0
;
return
0
;
}
}
static
struct
snd_compr_codec_caps
caps_mp3
=
{
static
const
struct
snd_compr_codec_caps
caps_mp3
=
{
.
num_descriptors
=
1
,
.
num_descriptors
=
1
,
.
descriptor
[
0
].
max_ch
=
2
,
.
descriptor
[
0
].
max_ch
=
2
,
.
descriptor
[
0
].
sample_rates
[
0
]
=
48000
,
.
descriptor
[
0
].
sample_rates
[
0
]
=
48000
,
...
@@ -424,7 +424,7 @@ static struct snd_compr_codec_caps caps_mp3 = {
...
@@ -424,7 +424,7 @@ static struct snd_compr_codec_caps caps_mp3 = {
.
descriptor
[
0
].
formats
=
0
,
.
descriptor
[
0
].
formats
=
0
,
};
};
static
struct
snd_compr_codec_caps
caps_aac
=
{
static
const
struct
snd_compr_codec_caps
caps_aac
=
{
.
num_descriptors
=
2
,
.
num_descriptors
=
2
,
.
descriptor
[
1
].
max_ch
=
2
,
.
descriptor
[
1
].
max_ch
=
2
,
.
descriptor
[
0
].
sample_rates
[
0
]
=
48000
,
.
descriptor
[
0
].
sample_rates
[
0
]
=
48000
,
...
...
sound/soc/intel/atom/sst/sst_pci.c
浏览文件 @
460f623a
...
@@ -181,7 +181,7 @@ static void intel_sst_remove(struct pci_dev *pci)
...
@@ -181,7 +181,7 @@ static void intel_sst_remove(struct pci_dev *pci)
}
}
/* PCI Routines */
/* PCI Routines */
static
struct
pci_device_id
intel_sst_ids
[]
=
{
static
const
struct
pci_device_id
intel_sst_ids
[]
=
{
{
PCI_VDEVICE
(
INTEL
,
SST_MRFLD_PCI_ID
),
0
},
{
PCI_VDEVICE
(
INTEL
,
SST_MRFLD_PCI_ID
),
0
},
{
0
,
}
{
0
,
}
};
};
...
...
sound/soc/intel/baytrail/sst-baytrail-pcm.c
浏览文件 @
460f623a
...
@@ -309,7 +309,7 @@ static int sst_byt_pcm_mmap(struct snd_pcm_substream *substream,
...
@@ -309,7 +309,7 @@ static int sst_byt_pcm_mmap(struct snd_pcm_substream *substream,
return
snd_pcm_lib_default_mmap
(
substream
,
vma
);
return
snd_pcm_lib_default_mmap
(
substream
,
vma
);
}
}
static
struct
snd_pcm_ops
sst_byt_pcm_ops
=
{
static
const
struct
snd_pcm_ops
sst_byt_pcm_ops
=
{
.
open
=
sst_byt_pcm_open
,
.
open
=
sst_byt_pcm_open
,
.
close
=
sst_byt_pcm_close
,
.
close
=
sst_byt_pcm_close
,
.
ioctl
=
snd_pcm_lib_ioctl
,
.
ioctl
=
snd_pcm_lib_ioctl
,
...
@@ -395,7 +395,7 @@ static int sst_byt_pcm_remove(struct snd_soc_platform *platform)
...
@@ -395,7 +395,7 @@ static int sst_byt_pcm_remove(struct snd_soc_platform *platform)
return
0
;
return
0
;
}
}
static
struct
snd_soc_platform_driver
byt_soc_platform
=
{
static
const
struct
snd_soc_platform_driver
byt_soc_platform
=
{
.
probe
=
sst_byt_pcm_probe
,
.
probe
=
sst_byt_pcm_probe
,
.
remove
=
sst_byt_pcm_remove
,
.
remove
=
sst_byt_pcm_remove
,
.
ops
=
&
sst_byt_pcm_ops
,
.
ops
=
&
sst_byt_pcm_ops
,
...
...
sound/soc/intel/boards/bxt_rt298.c
浏览文件 @
460f623a
...
@@ -114,7 +114,44 @@ static const struct snd_soc_dapm_route broxton_rt298_map[] = {
...
@@ -114,7 +114,44 @@ static const struct snd_soc_dapm_route broxton_rt298_map[] = {
{
"iDisp2 Tx"
,
NULL
,
"iDisp2_out"
},
{
"iDisp2 Tx"
,
NULL
,
"iDisp2_out"
},
{
"hifi1"
,
NULL
,
"iDisp1 Tx"
},
{
"hifi1"
,
NULL
,
"iDisp1 Tx"
},
{
"iDisp1 Tx"
,
NULL
,
"iDisp1_out"
},
{
"iDisp1 Tx"
,
NULL
,
"iDisp1_out"
},
};
static
const
struct
snd_soc_dapm_route
geminilake_rt298_map
[]
=
{
/* speaker */
{
"Speaker"
,
NULL
,
"SPOR"
},
{
"Speaker"
,
NULL
,
"SPOL"
},
/* HP jack connectors - unknown if we have jack detect */
{
"Headphone Jack"
,
NULL
,
"HPO Pin"
},
/* other jacks */
{
"MIC1"
,
NULL
,
"Mic Jack"
},
/* digital mics */
{
"DMIC1 Pin"
,
NULL
,
"DMIC2"
},
{
"DMic"
,
NULL
,
"SoC DMIC"
},
{
"HDMI1"
,
NULL
,
"hif5-0 Output"
},
{
"HDMI2"
,
NULL
,
"hif6-0 Output"
},
{
"HDMI2"
,
NULL
,
"hif7-0 Output"
},
/* CODEC BE connections */
{
"AIF1 Playback"
,
NULL
,
"ssp2 Tx"
},
{
"ssp2 Tx"
,
NULL
,
"codec0_out"
},
{
"ssp2 Tx"
,
NULL
,
"codec1_out"
},
{
"codec0_in"
,
NULL
,
"ssp2 Rx"
},
{
"ssp2 Rx"
,
NULL
,
"AIF1 Capture"
},
{
"dmic01_hifi"
,
NULL
,
"DMIC01 Rx"
},
{
"DMIC01 Rx"
,
NULL
,
"Capture"
},
{
"hifi3"
,
NULL
,
"iDisp3 Tx"
},
{
"iDisp3 Tx"
,
NULL
,
"iDisp3_out"
},
{
"hifi2"
,
NULL
,
"iDisp2 Tx"
},
{
"iDisp2 Tx"
,
NULL
,
"iDisp2_out"
},
{
"hifi1"
,
NULL
,
"iDisp1 Tx"
},
{
"iDisp1 Tx"
,
NULL
,
"iDisp1_out"
},
};
};
static
int
broxton_rt298_fe_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
broxton_rt298_fe_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
...
@@ -492,7 +529,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
...
@@ -492,7 +529,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
/* broxton audio machine driver for SPT + RT298S */
/* broxton audio machine driver for SPT + RT298S */
static
struct
snd_soc_card
broxton_rt298
=
{
static
struct
snd_soc_card
broxton_rt298
=
{
.
name
=
"broxton-rt298"
,
.
name
=
"broxton-rt298"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
broxton_rt298_dais
,
.
dai_link
=
broxton_rt298_dais
,
.
num_links
=
ARRAY_SIZE
(
broxton_rt298_dais
),
.
num_links
=
ARRAY_SIZE
(
broxton_rt298_dais
),
.
controls
=
broxton_controls
,
.
controls
=
broxton_controls
,
...
@@ -506,9 +542,41 @@ static struct snd_soc_card broxton_rt298 = {
...
@@ -506,9 +542,41 @@ static struct snd_soc_card broxton_rt298 = {
};
};
static
struct
snd_soc_card
geminilake_rt298
=
{
.
name
=
"geminilake-rt298"
,
.
dai_link
=
broxton_rt298_dais
,
.
num_links
=
ARRAY_SIZE
(
broxton_rt298_dais
),
.
controls
=
broxton_controls
,
.
num_controls
=
ARRAY_SIZE
(
broxton_controls
),
.
dapm_widgets
=
broxton_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
broxton_widgets
),
.
dapm_routes
=
geminilake_rt298_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
geminilake_rt298_map
),
.
fully_routed
=
true
,
.
late_probe
=
bxt_card_late_probe
,
};
static
int
broxton_audio_probe
(
struct
platform_device
*
pdev
)
static
int
broxton_audio_probe
(
struct
platform_device
*
pdev
)
{
{
struct
bxt_rt286_private
*
ctx
;
struct
bxt_rt286_private
*
ctx
;
struct
snd_soc_card
*
card
=
(
struct
snd_soc_card
*
)
pdev
->
id_entry
->
driver_data
;
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
broxton_rt298_dais
);
i
++
)
{
if
(
!
strncmp
(
card
->
dai_link
[
i
].
codec_name
,
"i2c-INT343A:00"
,
I2C_NAME_SIZE
))
{
if
(
!
strncmp
(
card
->
name
,
"broxton-rt298"
,
PLATFORM_NAME_SIZE
))
{
card
->
dai_link
[
i
].
name
=
"SSP5-Codec"
;
card
->
dai_link
[
i
].
cpu_dai_name
=
"SSP5 Pin"
;
}
else
if
(
!
strncmp
(
card
->
name
,
"geminilake-rt298"
,
PLATFORM_NAME_SIZE
))
{
card
->
dai_link
[
i
].
name
=
"SSP2-Codec"
;
card
->
dai_link
[
i
].
cpu_dai_name
=
"SSP2 Pin"
;
}
}
}
ctx
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
ctx
),
GFP_ATOMIC
);
ctx
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
ctx
),
GFP_ATOMIC
);
if
(
!
ctx
)
if
(
!
ctx
)
...
@@ -516,18 +584,27 @@ static int broxton_audio_probe(struct platform_device *pdev)
...
@@ -516,18 +584,27 @@ static int broxton_audio_probe(struct platform_device *pdev)
INIT_LIST_HEAD
(
&
ctx
->
hdmi_pcm_list
);
INIT_LIST_HEAD
(
&
ctx
->
hdmi_pcm_list
);
broxton_rt298
.
dev
=
&
pdev
->
dev
;
card
->
dev
=
&
pdev
->
dev
;
snd_soc_card_set_drvdata
(
&
broxton_rt298
,
ctx
);
snd_soc_card_set_drvdata
(
card
,
ctx
);
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
broxton_rt298
);
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
card
);
}
}
static
const
struct
platform_device_id
bxt_board_ids
[]
=
{
{
.
name
=
"bxt_alc298s_i2s"
,
.
driver_data
=
(
unsigned
long
)
&
broxton_rt298
},
{
.
name
=
"glk_alc298s_i2s"
,
.
driver_data
=
(
unsigned
long
)
&
geminilake_rt298
},
{}
};
static
struct
platform_driver
broxton_audio
=
{
static
struct
platform_driver
broxton_audio
=
{
.
probe
=
broxton_audio_probe
,
.
probe
=
broxton_audio_probe
,
.
driver
=
{
.
driver
=
{
.
name
=
"bxt_alc298s_i2s"
,
.
name
=
"bxt_alc298s_i2s"
,
.
pm
=
&
snd_soc_pm_ops
,
.
pm
=
&
snd_soc_pm_ops
,
},
},
.
id_table
=
bxt_board_ids
,
};
};
module_platform_driver
(
broxton_audio
)
module_platform_driver
(
broxton_audio
)
...
@@ -537,3 +614,4 @@ MODULE_AUTHOR("Senthilnathan Veppur <senthilnathanx.veppur@intel.com>");
...
@@ -537,3 +614,4 @@ MODULE_AUTHOR("Senthilnathan Veppur <senthilnathanx.veppur@intel.com>");
MODULE_DESCRIPTION
(
"Intel SST Audio for Broxton"
);
MODULE_DESCRIPTION
(
"Intel SST Audio for Broxton"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_ALIAS
(
"platform:bxt_alc298s_i2s"
);
MODULE_ALIAS
(
"platform:bxt_alc298s_i2s"
);
MODULE_ALIAS
(
"platform:glk_alc298s_i2s"
);
sound/soc/intel/boards/kbl_rt5663_max98927.c
浏览文件 @
460f623a
...
@@ -34,7 +34,7 @@
...
@@ -34,7 +34,7 @@
#define MAXIM_DEV0_NAME "i2c-MX98927:00"
#define MAXIM_DEV0_NAME "i2c-MX98927:00"
#define MAXIM_DEV1_NAME "i2c-MX98927:01"
#define MAXIM_DEV1_NAME "i2c-MX98927:01"
static
struct
snd_soc_card
kabylake_audio_card
;
static
struct
snd_soc_card
*
kabylake_audio_card
;
static
const
struct
snd_pcm_hw_constraint_list
*
dmic_constraints
;
static
const
struct
snd_pcm_hw_constraint_list
*
dmic_constraints
;
static
struct
snd_soc_jack
skylake_hdmi
[
3
];
static
struct
snd_soc_jack
skylake_hdmi
[
3
];
...
@@ -52,6 +52,8 @@ struct kbl_rt5663_private {
...
@@ -52,6 +52,8 @@ struct kbl_rt5663_private {
enum
{
enum
{
KBL_DPCM_AUDIO_PB
=
0
,
KBL_DPCM_AUDIO_PB
=
0
,
KBL_DPCM_AUDIO_CP
,
KBL_DPCM_AUDIO_CP
,
KBL_DPCM_AUDIO_HS_PB
,
KBL_DPCM_AUDIO_ECHO_REF_CP
,
KBL_DPCM_AUDIO_REF_CP
,
KBL_DPCM_AUDIO_REF_CP
,
KBL_DPCM_AUDIO_DMIC_CP
,
KBL_DPCM_AUDIO_DMIC_CP
,
KBL_DPCM_AUDIO_HDMI1_PB
,
KBL_DPCM_AUDIO_HDMI1_PB
,
...
@@ -72,8 +74,9 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = {
...
@@ -72,8 +74,9 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = {
SND_SOC_DAPM_SPK
(
"Left Spk"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Left Spk"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Right Spk"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Right Spk"
,
NULL
),
SND_SOC_DAPM_MIC
(
"SoC DMIC"
,
NULL
),
SND_SOC_DAPM_MIC
(
"SoC DMIC"
,
NULL
),
SND_SOC_DAPM_SPK
(
"DP"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI1"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI2"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI3"
,
NULL
),
};
};
...
@@ -91,20 +94,22 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
...
@@ -91,20 +94,22 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
{
"IN1N"
,
NULL
,
"Headset Mic"
},
{
"IN1N"
,
NULL
,
"Headset Mic"
},
{
"DMic"
,
NULL
,
"SoC DMIC"
},
{
"DMic"
,
NULL
,
"SoC DMIC"
},
{
"HDMI"
,
NULL
,
"hif5 Output"
},
{
"DP"
,
NULL
,
"hif6 Output"
},
/* CODEC BE connections */
/* CODEC BE connections */
{
"Left HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"Left HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"Right HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"Right HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"ssp0 Tx"
,
NULL
,
"
codec0
_out"
},
{
"ssp0 Tx"
,
NULL
,
"
spk
_out"
},
{
"AIF Playback"
,
NULL
,
"ssp1 Tx"
},
{
"AIF Playback"
,
NULL
,
"ssp1 Tx"
},
{
"ssp1 Tx"
,
NULL
,
"
codec1
_out"
},
{
"ssp1 Tx"
,
NULL
,
"
hs
_out"
},
{
"
codec0
_in"
,
NULL
,
"ssp1 Rx"
},
{
"
hs
_in"
,
NULL
,
"ssp1 Rx"
},
{
"ssp1 Rx"
,
NULL
,
"AIF Capture"
},
{
"ssp1 Rx"
,
NULL
,
"AIF Capture"
},
/* IV feedback path */
{
"codec0_fb_in"
,
NULL
,
"ssp0 Rx"
},
{
"ssp0 Rx"
,
NULL
,
"Left HiFi Capture"
},
{
"ssp0 Rx"
,
NULL
,
"Right HiFi Capture"
},
/* DMIC */
/* DMIC */
{
"dmic01_hifi"
,
NULL
,
"DMIC01 Rx"
},
{
"dmic01_hifi"
,
NULL
,
"DMIC01 Rx"
},
{
"DMIC01 Rx"
,
NULL
,
"DMIC AIF"
},
{
"DMIC01 Rx"
,
NULL
,
"DMIC AIF"
},
...
@@ -117,6 +122,49 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
...
@@ -117,6 +122,49 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
{
"iDisp1 Tx"
,
NULL
,
"iDisp1_out"
},
{
"iDisp1 Tx"
,
NULL
,
"iDisp1_out"
},
};
};
enum
{
KBL_DPCM_AUDIO_5663_PB
=
0
,
KBL_DPCM_AUDIO_5663_CP
,
KBL_DPCM_AUDIO_5663_HDMI1_PB
,
KBL_DPCM_AUDIO_5663_HDMI2_PB
,
};
static
const
struct
snd_kcontrol_new
kabylake_5663_controls
[]
=
{
SOC_DAPM_PIN_SWITCH
(
"Headphone Jack"
),
SOC_DAPM_PIN_SWITCH
(
"Headset Mic"
),
};
static
const
struct
snd_soc_dapm_widget
kabylake_5663_widgets
[]
=
{
SND_SOC_DAPM_HP
(
"Headphone Jack"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Headset Mic"
,
NULL
),
SND_SOC_DAPM_SPK
(
"DP"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI"
,
NULL
),
};
static
const
struct
snd_soc_dapm_route
kabylake_5663_map
[]
=
{
{
"Headphone Jack"
,
NULL
,
"HPOL"
},
{
"Headphone Jack"
,
NULL
,
"HPOR"
},
/* other jacks */
{
"IN1P"
,
NULL
,
"Headset Mic"
},
{
"IN1N"
,
NULL
,
"Headset Mic"
},
{
"HDMI"
,
NULL
,
"hif5 Output"
},
{
"DP"
,
NULL
,
"hif6 Output"
},
/* CODEC BE connections */
{
"AIF Playback"
,
NULL
,
"ssp1 Tx"
},
{
"ssp1 Tx"
,
NULL
,
"codec1_out"
},
{
"codec0_in"
,
NULL
,
"ssp1 Rx"
},
{
"ssp1 Rx"
,
NULL
,
"AIF Capture"
},
{
"hifi2"
,
NULL
,
"iDisp2 Tx"
},
{
"iDisp2 Tx"
,
NULL
,
"iDisp2_out"
},
{
"hifi1"
,
NULL
,
"iDisp1 Tx"
},
{
"iDisp1 Tx"
,
NULL
,
"iDisp1_out"
},
};
static
struct
snd_soc_codec_conf
max98927_codec_conf
[]
=
{
static
struct
snd_soc_codec_conf
max98927_codec_conf
[]
=
{
{
{
.
dev_name
=
MAXIM_DEV0_NAME
,
.
dev_name
=
MAXIM_DEV0_NAME
,
...
@@ -165,7 +213,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -165,7 +213,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
* Headset buttons map to the google Reference headset.
* Headset buttons map to the google Reference headset.
* These can be configured by userspace.
* These can be configured by userspace.
*/
*/
ret
=
snd_soc_card_jack_new
(
&
kabylake_audio_card
,
"Headset Jack"
,
ret
=
snd_soc_card_jack_new
(
kabylake_audio_card
,
"Headset Jack"
,
SND_JACK_HEADSET
|
SND_JACK_BTN_0
|
SND_JACK_BTN_1
|
SND_JACK_HEADSET
|
SND_JACK_BTN_0
|
SND_JACK_BTN_1
|
SND_JACK_BTN_2
|
SND_JACK_BTN_3
,
&
ctx
->
kabylake_headset
,
SND_JACK_BTN_2
|
SND_JACK_BTN_3
,
&
ctx
->
kabylake_headset
,
NULL
,
0
);
NULL
,
0
);
...
@@ -173,8 +221,18 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -173,8 +221,18 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
dev_err
(
rtd
->
dev
,
"Headset Jack creation failed %d
\n
"
,
ret
);
dev_err
(
rtd
->
dev
,
"Headset Jack creation failed %d
\n
"
,
ret
);
return
ret
;
return
ret
;
}
}
rt5663_set_jack_detect
(
codec
,
&
ctx
->
kabylake_headset
);
rt5663_set_jack_detect
(
codec
,
&
ctx
->
kabylake_headset
);
return
ret
;
}
static
int
kabylake_rt5663_max98927_codec_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
int
ret
;
ret
=
kabylake_rt5663_codec_init
(
rtd
);
if
(
ret
)
return
ret
;
ret
=
snd_soc_dapm_ignore_suspend
(
&
rtd
->
card
->
dapm
,
"SoC DMIC"
);
ret
=
snd_soc_dapm_ignore_suspend
(
&
rtd
->
card
->
dapm
,
"SoC DMIC"
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
rtd
->
dev
,
"SoC DMIC ignore suspend failed %d
\n
"
,
ret
);
dev_err
(
rtd
->
dev
,
"SoC DMIC ignore suspend failed %d
\n
"
,
ret
);
...
@@ -184,7 +242,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -184,7 +242,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
return
ret
;
return
ret
;
}
}
static
int
kabylake_hdmi
1_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
kabylake_hdmi
_init
(
struct
snd_soc_pcm_runtime
*
rtd
,
int
device
)
{
{
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
...
@@ -194,7 +252,7 @@ static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -194,7 +252,7 @@ static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
if
(
!
pcm
)
if
(
!
pcm
)
return
-
ENOMEM
;
return
-
ENOMEM
;
pcm
->
device
=
KBL_DPCM_AUDIO_HDMI1_PB
;
pcm
->
device
=
device
;
pcm
->
codec_dai
=
dai
;
pcm
->
codec_dai
=
dai
;
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
...
@@ -202,47 +260,36 @@ static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -202,47 +260,36 @@ static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
return
0
;
return
0
;
}
}
static
int
kabylake_hdmi
2
_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
kabylake_hdmi
1
_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
return
kabylake_hdmi_init
(
rtd
,
KBL_DPCM_AUDIO_HDMI1_PB
);
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
}
struct
kbl_hdmi_pcm
*
pcm
;
pcm
=
devm_kzalloc
(
rtd
->
card
->
dev
,
sizeof
(
*
pcm
),
GFP_KERNEL
);
if
(
!
pcm
)
return
-
ENOMEM
;
pcm
->
device
=
KBL_DPCM_AUDIO_HDMI2_PB
;
pcm
->
codec_dai
=
dai
;
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
return
0
;
static
int
kabylake_hdmi2_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
return
kabylake_hdmi_init
(
rtd
,
KBL_DPCM_AUDIO_HDMI2_PB
);
}
}
static
int
kabylake_hdmi3_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
kabylake_hdmi3_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
return
kabylake_hdmi_init
(
rtd
,
KBL_DPCM_AUDIO_HDMI3_PB
);
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
}
struct
kbl_hdmi_pcm
*
pcm
;
pcm
=
devm_kzalloc
(
rtd
->
card
->
dev
,
sizeof
(
*
pcm
),
GFP_KERNEL
);
if
(
!
pcm
)
return
-
ENOMEM
;
pcm
->
device
=
KBL_DPCM_AUDIO_HDMI3_PB
;
pcm
->
codec_dai
=
dai
;
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
static
int
kabylake_5663_hdmi1_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
return
kabylake_hdmi_init
(
rtd
,
KBL_DPCM_AUDIO_5663_HDMI1_PB
);
}
return
0
;
static
int
kabylake_5663_hdmi2_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
return
kabylake_hdmi_init
(
rtd
,
KBL_DPCM_AUDIO_5663_HDMI2_PB
);
}
}
static
unsigned
int
rates
[]
=
{
static
unsigned
int
rates
[]
=
{
48000
,
48000
,
};
};
static
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
.
count
=
ARRAY_SIZE
(
rates
),
.
count
=
ARRAY_SIZE
(
rates
),
.
list
=
rates
,
.
list
=
rates
,
.
mask
=
0
,
.
mask
=
0
,
...
@@ -252,7 +299,7 @@ static unsigned int channels[] = {
...
@@ -252,7 +299,7 @@ static unsigned int channels[] = {
2
,
2
,
};
};
static
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
.
count
=
ARRAY_SIZE
(
channels
),
.
count
=
ARRAY_SIZE
(
channels
),
.
list
=
channels
,
.
list
=
channels
,
.
mask
=
0
,
.
mask
=
0
,
...
@@ -312,11 +359,13 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
...
@@ -312,11 +359,13 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
;
int
ret
;
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
RT5663_SCLK_S_MCLK
,
24576000
,
SND_SOC_CLOCK_IN
);
/* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
/* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
rt5663_sel_asrc_clk_src
(
codec_dai
->
codec
,
RT5663_DA_STEREO_FILTER
,
1
);
rt5663_sel_asrc_clk_src
(
codec_dai
->
codec
,
RT5663_DA_STEREO_FILTER
|
RT5663_AD_STEREO_FILTER
,
RT5663_CLK_SEL_I2S1_ASRC
);
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
RT5663_SCLK_S_MCLK
,
24576000
,
SND_SOC_CLOCK_IN
);
if
(
ret
<
0
)
if
(
ret
<
0
)
dev_err
(
rtd
->
dev
,
"snd_soc_dai_set_sysclk err = %d
\n
"
,
ret
);
dev_err
(
rtd
->
dev
,
"snd_soc_dai_set_sysclk err = %d
\n
"
,
ret
);
...
@@ -381,7 +430,7 @@ static unsigned int rates_16000[] = {
...
@@ -381,7 +430,7 @@ static unsigned int rates_16000[] = {
16000
,
16000
,
};
};
static
struct
snd_pcm_hw_constraint_list
constraints_16000
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_16000
=
{
.
count
=
ARRAY_SIZE
(
rates_16000
),
.
count
=
ARRAY_SIZE
(
rates_16000
),
.
list
=
rates_16000
,
.
list
=
rates_16000
,
};
};
...
@@ -443,6 +492,28 @@ static struct snd_soc_dai_link kabylake_dais[] = {
...
@@ -443,6 +492,28 @@ static struct snd_soc_dai_link kabylake_dais[] = {
.
dpcm_capture
=
1
,
.
dpcm_capture
=
1
,
.
ops
=
&
kabylake_rt5663_fe_ops
,
.
ops
=
&
kabylake_rt5663_fe_ops
,
},
},
[
KBL_DPCM_AUDIO_HS_PB
]
=
{
.
name
=
"Kbl Audio Headset Playback"
,
.
stream_name
=
"Headset Audio"
,
.
cpu_dai_name
=
"System Pin2"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
platform_name
=
"0000:00:1f.3"
,
.
dpcm_playback
=
1
,
.
nonatomic
=
1
,
.
dynamic
=
1
,
},
[
KBL_DPCM_AUDIO_ECHO_REF_CP
]
=
{
.
name
=
"Kbl Audio Echo Reference cap"
,
.
stream_name
=
"Echoreference Capture"
,
.
cpu_dai_name
=
"Echoref Pin"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
platform_name
=
"0000:00:1f.3"
,
.
init
=
NULL
,
.
capture_only
=
1
,
.
nonatomic
=
1
,
},
[
KBL_DPCM_AUDIO_REF_CP
]
=
{
[
KBL_DPCM_AUDIO_REF_CP
]
=
{
.
name
=
"Kbl Audio Reference cap"
,
.
name
=
"Kbl Audio Reference cap"
,
.
stream_name
=
"Wake on Voice"
,
.
stream_name
=
"Wake on Voice"
,
...
@@ -538,7 +609,7 @@ static struct snd_soc_dai_link kabylake_dais[] = {
...
@@ -538,7 +609,7 @@ static struct snd_soc_dai_link kabylake_dais[] = {
.
no_pcm
=
1
,
.
no_pcm
=
1
,
.
codec_name
=
"i2c-10EC5663:00"
,
.
codec_name
=
"i2c-10EC5663:00"
,
.
codec_dai_name
=
KBL_REALTEK_CODEC_DAI
,
.
codec_dai_name
=
KBL_REALTEK_CODEC_DAI
,
.
init
=
kabylake_rt5663_codec_init
,
.
init
=
kabylake_rt5663_
max98927_
codec_init
,
.
dai_fmt
=
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
.
dai_fmt
=
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBS_CFS
,
SND_SOC_DAIFMT_CBS_CFS
,
.
ignore_pmdown_time
=
1
,
.
ignore_pmdown_time
=
1
,
...
@@ -594,15 +665,119 @@ static struct snd_soc_dai_link kabylake_dais[] = {
...
@@ -594,15 +665,119 @@ static struct snd_soc_dai_link kabylake_dais[] = {
},
},
};
};
static
struct
snd_soc_dai_link
kabylake_5663_dais
[]
=
{
/* Front End DAI links */
[
KBL_DPCM_AUDIO_5663_PB
]
=
{
.
name
=
"Kbl Audio Port"
,
.
stream_name
=
"Audio"
,
.
cpu_dai_name
=
"System Pin"
,
.
platform_name
=
"0000:00:1f.3"
,
.
dynamic
=
1
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
nonatomic
=
1
,
.
trigger
=
{
SND_SOC_DPCM_TRIGGER_POST
,
SND_SOC_DPCM_TRIGGER_POST
},
.
dpcm_playback
=
1
,
.
ops
=
&
kabylake_rt5663_fe_ops
,
},
[
KBL_DPCM_AUDIO_5663_CP
]
=
{
.
name
=
"Kbl Audio Capture Port"
,
.
stream_name
=
"Audio Record"
,
.
cpu_dai_name
=
"System Pin"
,
.
platform_name
=
"0000:00:1f.3"
,
.
dynamic
=
1
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
nonatomic
=
1
,
.
trigger
=
{
SND_SOC_DPCM_TRIGGER_POST
,
SND_SOC_DPCM_TRIGGER_POST
},
.
dpcm_capture
=
1
,
.
ops
=
&
kabylake_rt5663_fe_ops
,
},
[
KBL_DPCM_AUDIO_5663_HDMI1_PB
]
=
{
.
name
=
"Kbl HDMI Port1"
,
.
stream_name
=
"Hdmi1"
,
.
cpu_dai_name
=
"HDMI1 Pin"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
platform_name
=
"0000:00:1f.3"
,
.
dpcm_playback
=
1
,
.
init
=
NULL
,
.
trigger
=
{
SND_SOC_DPCM_TRIGGER_POST
,
SND_SOC_DPCM_TRIGGER_POST
},
.
nonatomic
=
1
,
.
dynamic
=
1
,
},
[
KBL_DPCM_AUDIO_5663_HDMI2_PB
]
=
{
.
name
=
"Kbl HDMI Port2"
,
.
stream_name
=
"Hdmi2"
,
.
cpu_dai_name
=
"HDMI2 Pin"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
platform_name
=
"0000:00:1f.3"
,
.
dpcm_playback
=
1
,
.
init
=
NULL
,
.
trigger
=
{
SND_SOC_DPCM_TRIGGER_POST
,
SND_SOC_DPCM_TRIGGER_POST
},
.
nonatomic
=
1
,
.
dynamic
=
1
,
},
/* Back End DAI links */
{
/* SSP1 - Codec */
.
name
=
"SSP1-Codec"
,
.
id
=
0
,
.
cpu_dai_name
=
"SSP1 Pin"
,
.
platform_name
=
"0000:00:1f.3"
,
.
no_pcm
=
1
,
.
codec_name
=
"i2c-10EC5663:00"
,
.
codec_dai_name
=
KBL_REALTEK_CODEC_DAI
,
.
init
=
kabylake_rt5663_codec_init
,
.
dai_fmt
=
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBS_CFS
,
.
ignore_pmdown_time
=
1
,
.
be_hw_params_fixup
=
kabylake_ssp_fixup
,
.
ops
=
&
kabylake_rt5663_ops
,
.
dpcm_playback
=
1
,
.
dpcm_capture
=
1
,
},
{
.
name
=
"iDisp1"
,
.
id
=
1
,
.
cpu_dai_name
=
"iDisp1 Pin"
,
.
codec_name
=
"ehdaudio0D2"
,
.
codec_dai_name
=
"intel-hdmi-hifi1"
,
.
platform_name
=
"0000:00:1f.3"
,
.
dpcm_playback
=
1
,
.
init
=
kabylake_5663_hdmi1_init
,
.
no_pcm
=
1
,
},
{
.
name
=
"iDisp2"
,
.
id
=
2
,
.
cpu_dai_name
=
"iDisp2 Pin"
,
.
codec_name
=
"ehdaudio0D2"
,
.
codec_dai_name
=
"intel-hdmi-hifi2"
,
.
platform_name
=
"0000:00:1f.3"
,
.
init
=
kabylake_5663_hdmi2_init
,
.
dpcm_playback
=
1
,
.
no_pcm
=
1
,
},
};
#define NAME_SIZE 32
#define NAME_SIZE 32
static
int
kabylake_card_late_probe
(
struct
snd_soc_card
*
card
)
static
int
kabylake_card_late_probe
(
struct
snd_soc_card
*
card
)
{
{
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
card
);
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
card
);
struct
kbl_hdmi_pcm
*
pcm
;
struct
kbl_hdmi_pcm
*
pcm
;
struct
snd_soc_codec
*
codec
=
NULL
;
int
err
,
i
=
0
;
int
err
,
i
=
0
;
char
jack_name
[
NAME_SIZE
];
char
jack_name
[
NAME_SIZE
];
list_for_each_entry
(
pcm
,
&
ctx
->
hdmi_pcm_list
,
head
)
{
list_for_each_entry
(
pcm
,
&
ctx
->
hdmi_pcm_list
,
head
)
{
codec
=
pcm
->
codec_dai
->
codec
;
snprintf
(
jack_name
,
sizeof
(
jack_name
),
snprintf
(
jack_name
,
sizeof
(
jack_name
),
"HDMI/DP, pcm=%d Jack"
,
pcm
->
device
);
"HDMI/DP, pcm=%d Jack"
,
pcm
->
device
);
err
=
snd_soc_card_jack_new
(
card
,
jack_name
,
err
=
snd_soc_card_jack_new
(
card
,
jack_name
,
...
@@ -620,11 +795,14 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
...
@@ -620,11 +795,14 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
i
++
;
i
++
;
}
}
return
0
;
if
(
!
codec
)
return
-
EINVAL
;
return
hdac_hdmi_jack_port_init
(
codec
,
&
card
->
dapm
);
}
}
/* kabylake audio machine driver for SPT + RT5663 */
/* kabylake audio machine driver for SPT + RT5663 */
static
struct
snd_soc_card
kabylake_audio_card
=
{
static
struct
snd_soc_card
kabylake_audio_card
_rt5663_m98927
=
{
.
name
=
"kblrt5663max"
,
.
name
=
"kblrt5663max"
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
kabylake_dais
,
.
dai_link
=
kabylake_dais
,
...
@@ -641,6 +819,22 @@ static struct snd_soc_card kabylake_audio_card = {
...
@@ -641,6 +819,22 @@ static struct snd_soc_card kabylake_audio_card = {
.
late_probe
=
kabylake_card_late_probe
,
.
late_probe
=
kabylake_card_late_probe
,
};
};
/* kabylake audio machine driver for RT5663 */
static
struct
snd_soc_card
kabylake_audio_card_rt5663
=
{
.
name
=
"kblrt5663"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
kabylake_5663_dais
,
.
num_links
=
ARRAY_SIZE
(
kabylake_5663_dais
),
.
controls
=
kabylake_5663_controls
,
.
num_controls
=
ARRAY_SIZE
(
kabylake_5663_controls
),
.
dapm_widgets
=
kabylake_5663_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
kabylake_5663_widgets
),
.
dapm_routes
=
kabylake_5663_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
kabylake_5663_map
),
.
fully_routed
=
true
,
.
late_probe
=
kabylake_card_late_probe
,
};
static
int
kabylake_audio_probe
(
struct
platform_device
*
pdev
)
static
int
kabylake_audio_probe
(
struct
platform_device
*
pdev
)
{
{
struct
kbl_rt5663_private
*
ctx
;
struct
kbl_rt5663_private
*
ctx
;
...
@@ -652,19 +846,30 @@ static int kabylake_audio_probe(struct platform_device *pdev)
...
@@ -652,19 +846,30 @@ static int kabylake_audio_probe(struct platform_device *pdev)
INIT_LIST_HEAD
(
&
ctx
->
hdmi_pcm_list
);
INIT_LIST_HEAD
(
&
ctx
->
hdmi_pcm_list
);
kabylake_audio_card
.
dev
=
&
pdev
->
dev
;
kabylake_audio_card
=
snd_soc_card_set_drvdata
(
&
kabylake_audio_card
,
ctx
);
(
struct
snd_soc_card
*
)
pdev
->
id_entry
->
driver_data
;
kabylake_audio_card
->
dev
=
&
pdev
->
dev
;
snd_soc_card_set_drvdata
(
kabylake_audio_card
,
ctx
);
pdata
=
dev_get_drvdata
(
&
pdev
->
dev
);
pdata
=
dev_get_drvdata
(
&
pdev
->
dev
);
if
(
pdata
)
if
(
pdata
)
dmic_constraints
=
pdata
->
dmic_num
==
2
?
dmic_constraints
=
pdata
->
dmic_num
==
2
?
&
constraints_dmic_2ch
:
&
constraints_dmic_channels
;
&
constraints_dmic_2ch
:
&
constraints_dmic_channels
;
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
kabylake_audio_card
);
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
kabylake_audio_card
);
}
}
static
const
struct
platform_device_id
kbl_board_ids
[]
=
{
static
const
struct
platform_device_id
kbl_board_ids
[]
=
{
{
.
name
=
"kbl_rt5663_m98927"
},
{
.
name
=
"kbl_rt5663"
,
.
driver_data
=
(
kernel_ulong_t
)
&
kabylake_audio_card_rt5663
,
},
{
.
name
=
"kbl_rt5663_m98927"
,
.
driver_data
=
(
kernel_ulong_t
)
&
kabylake_audio_card_rt5663_m98927
,
},
{
}
{
}
};
};
...
@@ -684,4 +889,5 @@ MODULE_DESCRIPTION("Audio Machine driver-RT5663 & MAX98927 in I2S mode");
...
@@ -684,4 +889,5 @@ MODULE_DESCRIPTION("Audio Machine driver-RT5663 & MAX98927 in I2S mode");
MODULE_AUTHOR
(
"Naveen M <naveen.m@intel.com>"
);
MODULE_AUTHOR
(
"Naveen M <naveen.m@intel.com>"
);
MODULE_AUTHOR
(
"Harsha Priya <harshapriya.n@intel.com>"
);
MODULE_AUTHOR
(
"Harsha Priya <harshapriya.n@intel.com>"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_ALIAS
(
"platform:kbl_rt5663"
);
MODULE_ALIAS
(
"platform:kbl_rt5663_m98927"
);
MODULE_ALIAS
(
"platform:kbl_rt5663_m98927"
);
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
浏览文件 @
460f623a
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
* GNU General Public License for more details.
* GNU General Public License for more details.
*/
*/
#include <linux/input.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/core.h>
...
@@ -62,7 +63,10 @@ struct kbl_codec_private {
...
@@ -62,7 +63,10 @@ struct kbl_codec_private {
enum
{
enum
{
KBL_DPCM_AUDIO_PB
=
0
,
KBL_DPCM_AUDIO_PB
=
0
,
KBL_DPCM_AUDIO_CP
,
KBL_DPCM_AUDIO_CP
,
KBL_DPCM_AUDIO_HS_PB
,
KBL_DPCM_AUDIO_ECHO_REF_CP
,
KBL_DPCM_AUDIO_DMIC_CP
,
KBL_DPCM_AUDIO_DMIC_CP
,
KBL_DPCM_AUDIO_RT5514_DSP
,
KBL_DPCM_AUDIO_HDMI1_PB
,
KBL_DPCM_AUDIO_HDMI1_PB
,
KBL_DPCM_AUDIO_HDMI2_PB
,
KBL_DPCM_AUDIO_HDMI2_PB
,
};
};
...
@@ -81,8 +85,8 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = {
...
@@ -81,8 +85,8 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = {
SND_SOC_DAPM_SPK
(
"Left Spk"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Left Spk"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Right Spk"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Right Spk"
,
NULL
),
SND_SOC_DAPM_MIC
(
"DMIC"
,
NULL
),
SND_SOC_DAPM_MIC
(
"DMIC"
,
NULL
),
SND_SOC_DAPM_SPK
(
"
DP
"
,
NULL
),
SND_SOC_DAPM_SPK
(
"
HDMI1
"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI
2
"
,
NULL
),
};
};
...
@@ -99,23 +103,25 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
...
@@ -99,23 +103,25 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
{
"IN1P"
,
NULL
,
"Headset Mic"
},
{
"IN1P"
,
NULL
,
"Headset Mic"
},
{
"IN1N"
,
NULL
,
"Headset Mic"
},
{
"IN1N"
,
NULL
,
"Headset Mic"
},
{
"HDMI"
,
NULL
,
"hif5 Output"
},
{
"DP"
,
NULL
,
"hif6 Output"
},
/* CODEC BE connections */
/* CODEC BE connections */
{
"Left HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"Left HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"Right HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"Right HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"ssp0 Tx"
,
NULL
,
"
codec0
_out"
},
{
"ssp0 Tx"
,
NULL
,
"
spk
_out"
},
{
"AIF Playback"
,
NULL
,
"ssp1 Tx"
},
{
"AIF Playback"
,
NULL
,
"ssp1 Tx"
},
{
"ssp1 Tx"
,
NULL
,
"
codec1
_out"
},
{
"ssp1 Tx"
,
NULL
,
"
hs
_out"
},
{
"
codec0
_in"
,
NULL
,
"ssp1 Rx"
},
{
"
hs
_in"
,
NULL
,
"ssp1 Rx"
},
{
"ssp1 Rx"
,
NULL
,
"AIF Capture"
},
{
"ssp1 Rx"
,
NULL
,
"AIF Capture"
},
{
"codec1_in"
,
NULL
,
"ssp0 Rx"
},
{
"codec1_in"
,
NULL
,
"ssp0 Rx"
},
{
"ssp0 Rx"
,
NULL
,
"AIF1 Capture"
},
{
"ssp0 Rx"
,
NULL
,
"AIF1 Capture"
},
/* IV feedback path */
{
"codec0_fb_in"
,
NULL
,
"ssp0 Rx"
},
{
"ssp0 Rx"
,
NULL
,
"Left HiFi Capture"
},
{
"ssp0 Rx"
,
NULL
,
"Right HiFi Capture"
},
/* DMIC */
/* DMIC */
{
"DMIC1L"
,
NULL
,
"DMIC"
},
{
"DMIC1L"
,
NULL
,
"DMIC"
},
{
"DMIC1R"
,
NULL
,
"DMIC"
},
{
"DMIC1R"
,
NULL
,
"DMIC"
},
...
@@ -173,6 +179,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -173,6 +179,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
int
ret
;
int
ret
;
struct
kbl_codec_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
kbl_codec_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_jack
*
jack
;
/*
/*
* Headset buttons map to the google Reference headset.
* Headset buttons map to the google Reference headset.
...
@@ -187,6 +194,12 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -187,6 +194,12 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
return
ret
;
return
ret
;
}
}
jack
=
&
ctx
->
kabylake_headset
;
snd_jack_set_key
(
jack
->
jack
,
SND_JACK_BTN_0
,
KEY_MEDIA
);
snd_jack_set_key
(
jack
->
jack
,
SND_JACK_BTN_1
,
KEY_VOICECOMMAND
);
snd_jack_set_key
(
jack
->
jack
,
SND_JACK_BTN_2
,
KEY_VOLUMEUP
);
snd_jack_set_key
(
jack
->
jack
,
SND_JACK_BTN_3
,
KEY_VOLUMEDOWN
);
rt5663_set_jack_detect
(
codec
,
&
ctx
->
kabylake_headset
);
rt5663_set_jack_detect
(
codec
,
&
ctx
->
kabylake_headset
);
ret
=
snd_soc_dapm_ignore_suspend
(
&
rtd
->
card
->
dapm
,
"DMIC"
);
ret
=
snd_soc_dapm_ignore_suspend
(
&
rtd
->
card
->
dapm
,
"DMIC"
);
...
@@ -358,11 +371,18 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
...
@@ -358,11 +371,18 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
return
ret
;
return
ret
;
}
}
}
}
if
(
!
strcmp
(
codec_dai
->
component
->
name
,
MAXIM_DEV0_NAME
)
||
if
(
!
strcmp
(
codec_dai
->
component
->
name
,
MAXIM_DEV0_NAME
))
{
!
strcmp
(
codec_dai
->
component
->
name
,
MAXIM_DEV1_NAME
))
{
ret
=
snd_soc_dai_set_tdm_slot
(
codec_dai
,
0x30
,
3
,
8
,
16
);
ret
=
snd_soc_dai_set_tdm_slot
(
codec_dai
,
0xF0
,
3
,
8
,
16
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"set TDM slot err:%d
\n
"
,
ret
);
dev_err
(
rtd
->
dev
,
"DEV0 TDM slot err:%d
\n
"
,
ret
);
return
ret
;
}
}
if
(
!
strcmp
(
codec_dai
->
component
->
name
,
MAXIM_DEV1_NAME
))
{
ret
=
snd_soc_dai_set_tdm_slot
(
codec_dai
,
0xC0
,
3
,
8
,
16
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"DEV1 TDM slot err:%d
\n
"
,
ret
);
return
ret
;
return
ret
;
}
}
}
}
...
@@ -442,6 +462,36 @@ static struct snd_soc_dai_link kabylake_dais[] = {
...
@@ -442,6 +462,36 @@ static struct snd_soc_dai_link kabylake_dais[] = {
.
dpcm_capture
=
1
,
.
dpcm_capture
=
1
,
.
ops
=
&
kabylake_rt5663_fe_ops
,
.
ops
=
&
kabylake_rt5663_fe_ops
,
},
},
[
KBL_DPCM_AUDIO_HS_PB
]
=
{
.
name
=
"Kbl Audio Headset Playback"
,
.
stream_name
=
"Headset Audio"
,
.
cpu_dai_name
=
"System Pin2"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
platform_name
=
"0000:00:1f.3"
,
.
dpcm_playback
=
1
,
.
nonatomic
=
1
,
.
dynamic
=
1
,
},
[
KBL_DPCM_AUDIO_ECHO_REF_CP
]
=
{
.
name
=
"Kbl Audio Echo Reference cap"
,
.
stream_name
=
"Echoreference Capture"
,
.
cpu_dai_name
=
"Echoref Pin"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
platform_name
=
"0000:00:1f.3"
,
.
init
=
NULL
,
.
capture_only
=
1
,
.
nonatomic
=
1
,
},
[
KBL_DPCM_AUDIO_RT5514_DSP
]
=
{
.
name
=
"rt5514 dsp"
,
.
stream_name
=
"Wake on Voice"
,
.
cpu_dai_name
=
"spi-PRP0001:00"
,
.
platform_name
=
"spi-PRP0001:00"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
},
[
KBL_DPCM_AUDIO_DMIC_CP
]
=
{
[
KBL_DPCM_AUDIO_DMIC_CP
]
=
{
.
name
=
"Kbl Audio DMIC cap"
,
.
name
=
"Kbl Audio DMIC cap"
,
.
stream_name
=
"dmiccap"
,
.
stream_name
=
"dmiccap"
,
...
@@ -548,10 +598,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
...
@@ -548,10 +598,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
{
{
struct
kbl_codec_private
*
ctx
=
snd_soc_card_get_drvdata
(
card
);
struct
kbl_codec_private
*
ctx
=
snd_soc_card_get_drvdata
(
card
);
struct
kbl_hdmi_pcm
*
pcm
;
struct
kbl_hdmi_pcm
*
pcm
;
struct
snd_soc_codec
*
codec
=
NULL
;
int
err
,
i
=
0
;
int
err
,
i
=
0
;
char
jack_name
[
NAME_SIZE
];
char
jack_name
[
NAME_SIZE
];
list_for_each_entry
(
pcm
,
&
ctx
->
hdmi_pcm_list
,
head
)
{
list_for_each_entry
(
pcm
,
&
ctx
->
hdmi_pcm_list
,
head
)
{
codec
=
pcm
->
codec_dai
->
codec
;
err
=
snd_soc_card_jack_new
(
card
,
jack_name
,
err
=
snd_soc_card_jack_new
(
card
,
jack_name
,
SND_JACK_AVOUT
,
&
ctx
->
kabylake_hdmi
[
i
],
SND_JACK_AVOUT
,
&
ctx
->
kabylake_hdmi
[
i
],
NULL
,
0
);
NULL
,
0
);
...
@@ -565,7 +617,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
...
@@ -565,7 +617,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
i
++
;
i
++
;
}
}
return
0
;
if
(
!
codec
)
return
-
EINVAL
;
return
hdac_hdmi_jack_port_init
(
codec
,
&
card
->
dapm
);
}
}
/*
/*
...
...
sound/soc/intel/boards/mfld_machine.c
浏览文件 @
460f623a
...
@@ -376,10 +376,8 @@ static int snd_mfld_mc_probe(struct platform_device *pdev)
...
@@ -376,10 +376,8 @@ static int snd_mfld_mc_probe(struct platform_device *pdev)
/* audio interrupt base of SRAM location where
/* audio interrupt base of SRAM location where
* interrupts are stored by System FW */
* interrupts are stored by System FW */
mc_drv_ctx
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
mc_drv_ctx
),
GFP_ATOMIC
);
mc_drv_ctx
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
mc_drv_ctx
),
GFP_ATOMIC
);
if
(
!
mc_drv_ctx
)
{
if
(
!
mc_drv_ctx
)
pr_err
(
"allocation failed
\n
"
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
irq_mem
=
platform_get_resource_byname
(
irq_mem
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"IRQ_BASE"
);
pdev
,
IORESOURCE_MEM
,
"IRQ_BASE"
);
...
...
sound/soc/intel/haswell/sst-haswell-pcm.c
浏览文件 @
460f623a
...
@@ -1135,7 +1135,7 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform)
...
@@ -1135,7 +1135,7 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform)
return
0
;
return
0
;
}
}
static
struct
snd_soc_platform_driver
hsw_soc_platform
=
{
static
const
struct
snd_soc_platform_driver
hsw_soc_platform
=
{
.
probe
=
hsw_pcm_probe
,
.
probe
=
hsw_pcm_probe
,
.
remove
=
hsw_pcm_remove
,
.
remove
=
hsw_pcm_remove
,
.
ops
=
&
hsw_pcm_ops
,
.
ops
=
&
hsw_pcm_ops
,
...
...
sound/soc/intel/skylake/Makefile
浏览文件 @
460f623a
...
@@ -8,7 +8,8 @@ endif
...
@@ -8,7 +8,8 @@ endif
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE)
+=
snd-soc-skl.o
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE)
+=
snd-soc-skl.o
# Skylake IPC Support
# Skylake IPC Support
snd-soc-skl-ipc-objs
:=
skl-sst-ipc.o skl-sst-dsp.o skl-sst-cldma.o
\
snd-soc-skl-ipc-objs
:=
skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o
\
skl-sst.o bxt-sst.o skl-sst-utils.o
skl-sst-cldma.o skl-sst.o bxt-sst.o cnl-sst.o
\
skl-sst-utils.o
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE)
+=
snd-soc-skl-ipc.o
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE)
+=
snd-soc-skl-ipc.o
sound/soc/intel/skylake/bxt-sst.c
浏览文件 @
460f623a
...
@@ -530,7 +530,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
...
@@ -530,7 +530,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
return
0
;
return
0
;
}
}
static
struct
skl_dsp_fw_ops
bxt_fw_ops
=
{
static
const
struct
skl_dsp_fw_ops
bxt_fw_ops
=
{
.
set_state_D0
=
bxt_set_dsp_D0
,
.
set_state_D0
=
bxt_set_dsp_D0
,
.
set_state_D3
=
bxt_set_dsp_D3
,
.
set_state_D3
=
bxt_set_dsp_D3
,
.
set_state_D0i3
=
bxt_schedule_dsp_D0i3
,
.
set_state_D0i3
=
bxt_schedule_dsp_D0i3
,
...
@@ -581,10 +581,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
...
@@ -581,10 +581,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
),
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
);
SKL_ADSP_W0_UP_SZ
,
BXT_ADSP_SRAM1_BASE
,
SKL_ADSP_W1_SZ
);
ret
=
skl_ipc_init
(
dev
,
skl
);
if
(
ret
)
{
skl_dsp_free
(
sst
);
return
ret
;
}
/* set the D0i3 check */
/* set the D0i3 check */
skl
->
ipc
.
ops
.
check_dsp_lp_on
=
skl_ipc_check_D0i0
;
skl
->
ipc
.
ops
.
check_dsp_lp_on
=
skl_ipc_check_D0i0
;
skl
->
cores
.
count
=
2
;
skl
->
boot_complete
=
false
;
skl
->
boot_complete
=
false
;
init_waitqueue_head
(
&
skl
->
boot_wait
);
init_waitqueue_head
(
&
skl
->
boot_wait
);
INIT_DELAYED_WORK
(
&
skl
->
d0i3
.
work
,
bxt_set_dsp_D0i3
);
INIT_DELAYED_WORK
(
&
skl
->
d0i3
.
work
,
bxt_set_dsp_D0i3
);
...
@@ -629,11 +634,6 @@ void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
...
@@ -629,11 +634,6 @@ void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
release_firmware
(
ctx
->
dsp
->
fw
);
release_firmware
(
ctx
->
dsp
->
fw
);
skl_freeup_uuid_list
(
ctx
);
skl_freeup_uuid_list
(
ctx
);
skl_ipc_free
(
&
ctx
->
ipc
);
skl_ipc_free
(
&
ctx
->
ipc
);
ctx
->
dsp
->
cl_dev
.
ops
.
cl_cleanup_controller
(
ctx
->
dsp
);
if
(
ctx
->
dsp
->
addr
.
lpe
)
iounmap
(
ctx
->
dsp
->
addr
.
lpe
);
ctx
->
dsp
->
ops
->
free
(
ctx
->
dsp
);
ctx
->
dsp
->
ops
->
free
(
ctx
->
dsp
);
}
}
EXPORT_SYMBOL_GPL
(
bxt_sst_dsp_cleanup
);
EXPORT_SYMBOL_GPL
(
bxt_sst_dsp_cleanup
);
...
...
sound/soc/intel/skylake/cnl-sst-dsp.c
0 → 100644
浏览文件 @
460f623a
/*
* cnl-sst-dsp.c - CNL SST library generic function
*
* Copyright (C) 2016-17, Intel Corporation.
* Author: Guneshwor Singh <guneshwor.o.singh@intel.com>
*
* Modified from:
* SKL SST library generic function
* Copyright (C) 2014-15, Intel Corporation.
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as version 2, as
* published by the Free Software Foundation.
*
* 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/device.h>
#include "../common/sst-dsp.h"
#include "../common/sst-ipc.h"
#include "../common/sst-dsp-priv.h"
#include "cnl-sst-dsp.h"
/* various timeout values */
#define CNL_DSP_PU_TO 50
#define CNL_DSP_PD_TO 50
#define CNL_DSP_RESET_TO 50
static
int
cnl_dsp_core_set_reset_state
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_mask
)
{
/* update bits */
sst_dsp_shim_update_bits_unlocked
(
ctx
,
CNL_ADSP_REG_ADSPCS
,
CNL_ADSPCS_CRST
(
core_mask
),
CNL_ADSPCS_CRST
(
core_mask
));
/* poll with timeout to check if operation successful */
return
sst_dsp_register_poll
(
ctx
,
CNL_ADSP_REG_ADSPCS
,
CNL_ADSPCS_CRST
(
core_mask
),
CNL_ADSPCS_CRST
(
core_mask
),
CNL_DSP_RESET_TO
,
"Set reset"
);
}
static
int
cnl_dsp_core_unset_reset_state
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_mask
)
{
/* update bits */
sst_dsp_shim_update_bits_unlocked
(
ctx
,
CNL_ADSP_REG_ADSPCS
,
CNL_ADSPCS_CRST
(
core_mask
),
0
);
/* poll with timeout to check if operation successful */
return
sst_dsp_register_poll
(
ctx
,
CNL_ADSP_REG_ADSPCS
,
CNL_ADSPCS_CRST
(
core_mask
),
0
,
CNL_DSP_RESET_TO
,
"Unset reset"
);
}
static
bool
is_cnl_dsp_core_enable
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_mask
)
{
int
val
;
bool
is_enable
;
val
=
sst_dsp_shim_read_unlocked
(
ctx
,
CNL_ADSP_REG_ADSPCS
);
is_enable
=
(
val
&
CNL_ADSPCS_CPA
(
core_mask
))
&&
(
val
&
CNL_ADSPCS_SPA
(
core_mask
))
&&
!
(
val
&
CNL_ADSPCS_CRST
(
core_mask
))
&&
!
(
val
&
CNL_ADSPCS_CSTALL
(
core_mask
));
dev_dbg
(
ctx
->
dev
,
"DSP core(s) enabled? %d: core_mask %#x
\n
"
,
is_enable
,
core_mask
);
return
is_enable
;
}
static
int
cnl_dsp_reset_core
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_mask
)
{
/* stall core */
sst_dsp_shim_update_bits_unlocked
(
ctx
,
CNL_ADSP_REG_ADSPCS
,
CNL_ADSPCS_CSTALL
(
core_mask
),
CNL_ADSPCS_CSTALL
(
core_mask
));
/* set reset state */
return
cnl_dsp_core_set_reset_state
(
ctx
,
core_mask
);
}
static
int
cnl_dsp_start_core
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_mask
)
{
int
ret
;
/* unset reset state */
ret
=
cnl_dsp_core_unset_reset_state
(
ctx
,
core_mask
);
if
(
ret
<
0
)
return
ret
;
/* run core */
sst_dsp_shim_update_bits_unlocked
(
ctx
,
CNL_ADSP_REG_ADSPCS
,
CNL_ADSPCS_CSTALL
(
core_mask
),
0
);
if
(
!
is_cnl_dsp_core_enable
(
ctx
,
core_mask
))
{
cnl_dsp_reset_core
(
ctx
,
core_mask
);
dev_err
(
ctx
->
dev
,
"DSP core mask %#x enable failed
\n
"
,
core_mask
);
ret
=
-
EIO
;
}
return
ret
;
}
static
int
cnl_dsp_core_power_up
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_mask
)
{
/* update bits */
sst_dsp_shim_update_bits_unlocked
(
ctx
,
CNL_ADSP_REG_ADSPCS
,
CNL_ADSPCS_SPA
(
core_mask
),
CNL_ADSPCS_SPA
(
core_mask
));
/* poll with timeout to check if operation successful */
return
sst_dsp_register_poll
(
ctx
,
CNL_ADSP_REG_ADSPCS
,
CNL_ADSPCS_CPA
(
core_mask
),
CNL_ADSPCS_CPA
(
core_mask
),
CNL_DSP_PU_TO
,
"Power up"
);
}
static
int
cnl_dsp_core_power_down
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_mask
)
{
/* update bits */
sst_dsp_shim_update_bits_unlocked
(
ctx
,
CNL_ADSP_REG_ADSPCS
,
CNL_ADSPCS_SPA
(
core_mask
),
0
);
/* poll with timeout to check if operation successful */
return
sst_dsp_register_poll
(
ctx
,
CNL_ADSP_REG_ADSPCS
,
CNL_ADSPCS_CPA
(
core_mask
),
0
,
CNL_DSP_PD_TO
,
"Power down"
);
}
int
cnl_dsp_enable_core
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_mask
)
{
int
ret
;
/* power up */
ret
=
cnl_dsp_core_power_up
(
ctx
,
core_mask
);
if
(
ret
<
0
)
{
dev_dbg
(
ctx
->
dev
,
"DSP core mask %#x power up failed"
,
core_mask
);
return
ret
;
}
return
cnl_dsp_start_core
(
ctx
,
core_mask
);
}
int
cnl_dsp_disable_core
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_mask
)
{
int
ret
;
ret
=
cnl_dsp_reset_core
(
ctx
,
core_mask
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"DSP core mask %#x reset failed
\n
"
,
core_mask
);
return
ret
;
}
/* power down core*/
ret
=
cnl_dsp_core_power_down
(
ctx
,
core_mask
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"DSP core mask %#x power down failed
\n
"
,
core_mask
);
return
ret
;
}
if
(
is_cnl_dsp_core_enable
(
ctx
,
core_mask
))
{
dev_err
(
ctx
->
dev
,
"DSP core mask %#x disable failed
\n
"
,
core_mask
);
ret
=
-
EIO
;
}
return
ret
;
}
irqreturn_t
cnl_dsp_sst_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
sst_dsp
*
ctx
=
dev_id
;
u32
val
;
irqreturn_t
ret
=
IRQ_NONE
;
spin_lock
(
&
ctx
->
spinlock
);
val
=
sst_dsp_shim_read_unlocked
(
ctx
,
CNL_ADSP_REG_ADSPIS
);
ctx
->
intr_status
=
val
;
if
(
val
==
0xffffffff
)
{
spin_unlock
(
&
ctx
->
spinlock
);
return
IRQ_NONE
;
}
if
(
val
&
CNL_ADSPIS_IPC
)
{
cnl_ipc_int_disable
(
ctx
);
ret
=
IRQ_WAKE_THREAD
;
}
spin_unlock
(
&
ctx
->
spinlock
);
return
ret
;
}
void
cnl_dsp_free
(
struct
sst_dsp
*
dsp
)
{
cnl_ipc_int_disable
(
dsp
);
free_irq
(
dsp
->
irq
,
dsp
);
cnl_ipc_op_int_disable
(
dsp
);
cnl_dsp_disable_core
(
dsp
,
SKL_DSP_CORE0_MASK
);
}
EXPORT_SYMBOL_GPL
(
cnl_dsp_free
);
void
cnl_ipc_int_enable
(
struct
sst_dsp
*
ctx
)
{
sst_dsp_shim_update_bits
(
ctx
,
CNL_ADSP_REG_ADSPIC
,
CNL_ADSPIC_IPC
,
CNL_ADSPIC_IPC
);
}
void
cnl_ipc_int_disable
(
struct
sst_dsp
*
ctx
)
{
sst_dsp_shim_update_bits_unlocked
(
ctx
,
CNL_ADSP_REG_ADSPIC
,
CNL_ADSPIC_IPC
,
0
);
}
void
cnl_ipc_op_int_enable
(
struct
sst_dsp
*
ctx
)
{
/* enable IPC DONE interrupt */
sst_dsp_shim_update_bits
(
ctx
,
CNL_ADSP_REG_HIPCCTL
,
CNL_ADSP_REG_HIPCCTL_DONE
,
CNL_ADSP_REG_HIPCCTL_DONE
);
/* enable IPC BUSY interrupt */
sst_dsp_shim_update_bits
(
ctx
,
CNL_ADSP_REG_HIPCCTL
,
CNL_ADSP_REG_HIPCCTL_BUSY
,
CNL_ADSP_REG_HIPCCTL_BUSY
);
}
void
cnl_ipc_op_int_disable
(
struct
sst_dsp
*
ctx
)
{
/* disable IPC DONE interrupt */
sst_dsp_shim_update_bits
(
ctx
,
CNL_ADSP_REG_HIPCCTL
,
CNL_ADSP_REG_HIPCCTL_DONE
,
0
);
/* disable IPC BUSY interrupt */
sst_dsp_shim_update_bits
(
ctx
,
CNL_ADSP_REG_HIPCCTL
,
CNL_ADSP_REG_HIPCCTL_BUSY
,
0
);
}
bool
cnl_ipc_int_status
(
struct
sst_dsp
*
ctx
)
{
return
sst_dsp_shim_read_unlocked
(
ctx
,
CNL_ADSP_REG_ADSPIS
)
&
CNL_ADSPIS_IPC
;
}
void
cnl_ipc_free
(
struct
sst_generic_ipc
*
ipc
)
{
cnl_ipc_op_int_disable
(
ipc
->
dsp
);
sst_ipc_fini
(
ipc
);
}
sound/soc/intel/skylake/cnl-sst-dsp.h
0 → 100644
浏览文件 @
460f623a
/*
* Cannonlake SST DSP Support
*
* Copyright (C) 2016-17, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as version 2, as
* published by the Free Software Foundation.
*
* 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.
*/
#ifndef __CNL_SST_DSP_H__
#define __CNL_SST_DSP_H__
struct
sst_dsp
;
struct
skl_sst
;
struct
sst_dsp_device
;
struct
sst_generic_ipc
;
/* Intel HD Audio General DSP Registers */
#define CNL_ADSP_GEN_BASE 0x0
#define CNL_ADSP_REG_ADSPCS (CNL_ADSP_GEN_BASE + 0x04)
#define CNL_ADSP_REG_ADSPIC (CNL_ADSP_GEN_BASE + 0x08)
#define CNL_ADSP_REG_ADSPIS (CNL_ADSP_GEN_BASE + 0x0c)
/* Intel HD Audio Inter-Processor Communication Registers */
#define CNL_ADSP_IPC_BASE 0xc0
#define CNL_ADSP_REG_HIPCTDR (CNL_ADSP_IPC_BASE + 0x00)
#define CNL_ADSP_REG_HIPCTDA (CNL_ADSP_IPC_BASE + 0x04)
#define CNL_ADSP_REG_HIPCTDD (CNL_ADSP_IPC_BASE + 0x08)
#define CNL_ADSP_REG_HIPCIDR (CNL_ADSP_IPC_BASE + 0x10)
#define CNL_ADSP_REG_HIPCIDA (CNL_ADSP_IPC_BASE + 0x14)
#define CNL_ADSP_REG_HIPCIDD (CNL_ADSP_IPC_BASE + 0x18)
#define CNL_ADSP_REG_HIPCCTL (CNL_ADSP_IPC_BASE + 0x28)
/* HIPCTDR */
#define CNL_ADSP_REG_HIPCTDR_BUSY BIT(31)
/* HIPCTDA */
#define CNL_ADSP_REG_HIPCTDA_DONE BIT(31)
/* HIPCIDR */
#define CNL_ADSP_REG_HIPCIDR_BUSY BIT(31)
/* HIPCIDA */
#define CNL_ADSP_REG_HIPCIDA_DONE BIT(31)
/* CNL HIPCCTL */
#define CNL_ADSP_REG_HIPCCTL_DONE BIT(1)
#define CNL_ADSP_REG_HIPCCTL_BUSY BIT(0)
/* CNL HIPCT */
#define CNL_ADSP_REG_HIPCT_BUSY BIT(31)
/* Intel HD Audio SRAM Window 1 */
#define CNL_ADSP_SRAM1_BASE 0xa0000
#define CNL_ADSP_MMIO_LEN 0x10000
#define CNL_ADSP_W0_STAT_SZ 0x1000
#define CNL_ADSP_W0_UP_SZ 0x1000
#define CNL_ADSP_W1_SZ 0x1000
#define CNL_FW_STS_MASK 0xf
#define CNL_ADSPIC_IPC 0x1
#define CNL_ADSPIS_IPC 0x1
#define CNL_DSP_CORES 4
#define CNL_DSP_CORES_MASK ((1 << CNL_DSP_CORES) - 1)
/* core reset - asserted high */
#define CNL_ADSPCS_CRST_SHIFT 0
#define CNL_ADSPCS_CRST(x) (x << CNL_ADSPCS_CRST_SHIFT)
/* core run/stall - when set to 1 core is stalled */
#define CNL_ADSPCS_CSTALL_SHIFT 8
#define CNL_ADSPCS_CSTALL(x) (x << CNL_ADSPCS_CSTALL_SHIFT)
/* set power active - when set to 1 turn core on */
#define CNL_ADSPCS_SPA_SHIFT 16
#define CNL_ADSPCS_SPA(x) (x << CNL_ADSPCS_SPA_SHIFT)
/* current power active - power status of cores, set by hardware */
#define CNL_ADSPCS_CPA_SHIFT 24
#define CNL_ADSPCS_CPA(x) (x << CNL_ADSPCS_CPA_SHIFT)
int
cnl_dsp_enable_core
(
struct
sst_dsp
*
ctx
,
unsigned
int
core
);
int
cnl_dsp_disable_core
(
struct
sst_dsp
*
ctx
,
unsigned
int
core
);
irqreturn_t
cnl_dsp_sst_interrupt
(
int
irq
,
void
*
dev_id
);
void
cnl_dsp_free
(
struct
sst_dsp
*
dsp
);
void
cnl_ipc_int_enable
(
struct
sst_dsp
*
ctx
);
void
cnl_ipc_int_disable
(
struct
sst_dsp
*
ctx
);
void
cnl_ipc_op_int_enable
(
struct
sst_dsp
*
ctx
);
void
cnl_ipc_op_int_disable
(
struct
sst_dsp
*
ctx
);
bool
cnl_ipc_int_status
(
struct
sst_dsp
*
ctx
);
void
cnl_ipc_free
(
struct
sst_generic_ipc
*
ipc
);
int
cnl_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
cnl_sst_init_fw
(
struct
device
*
dev
,
struct
skl_sst
*
ctx
);
void
cnl_sst_dsp_cleanup
(
struct
device
*
dev
,
struct
skl_sst
*
ctx
);
#endif
/*__CNL_SST_DSP_H__*/
sound/soc/intel/skylake/cnl-sst.c
0 → 100644
浏览文件 @
460f623a
/*
* cnl-sst.c - DSP library functions for CNL platform
*
* Copyright (C) 2016-17, Intel Corporation.
*
* Author: Guneshwor Singh <guneshwor.o.singh@intel.com>
*
* Modified from:
* HDA DSP library functions for SKL platform
* Copyright (C) 2014-15, Intel Corporation.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as version 2, as
* published by the Free Software Foundation.
*
* 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/delay.h>
#include <linux/firmware.h>
#include <linux/device.h>
#include "../common/sst-dsp.h"
#include "../common/sst-dsp-priv.h"
#include "../common/sst-ipc.h"
#include "cnl-sst-dsp.h"
#include "skl-sst-dsp.h"
#include "skl-sst-ipc.h"
#define CNL_FW_ROM_INIT 0x1
#define CNL_FW_INIT 0x5
#define CNL_IPC_PURGE 0x01004000
#define CNL_INIT_TIMEOUT 300
#define CNL_BASEFW_TIMEOUT 3000
#define CNL_ADSP_SRAM0_BASE 0x80000
/* Firmware status window */
#define CNL_ADSP_FW_STATUS CNL_ADSP_SRAM0_BASE
#define CNL_ADSP_ERROR_CODE (CNL_ADSP_FW_STATUS + 0x4)
#define CNL_INSTANCE_ID 0
#define CNL_BASE_FW_MODULE_ID 0
#define CNL_ADSP_FW_HDR_OFFSET 0x2000
#define CNL_ROM_CTRL_DMA_ID 0x9
static
int
cnl_prepare_fw
(
struct
sst_dsp
*
ctx
,
const
void
*
fwdata
,
u32
fwsize
)
{
int
ret
,
stream_tag
;
stream_tag
=
ctx
->
dsp_ops
.
prepare
(
ctx
->
dev
,
0x40
,
fwsize
,
&
ctx
->
dmab
);
if
(
stream_tag
<=
0
)
{
dev_err
(
ctx
->
dev
,
"dma prepare failed: 0%#x
\n
"
,
stream_tag
);
return
stream_tag
;
}
ctx
->
dsp_ops
.
stream_tag
=
stream_tag
;
memcpy
(
ctx
->
dmab
.
area
,
fwdata
,
fwsize
);
/* purge FW request */
sst_dsp_shim_write
(
ctx
,
CNL_ADSP_REG_HIPCIDR
,
CNL_ADSP_REG_HIPCIDR_BUSY
|
(
CNL_IPC_PURGE
|
((
stream_tag
-
1
)
<<
CNL_ROM_CTRL_DMA_ID
)));
ret
=
cnl_dsp_enable_core
(
ctx
,
SKL_DSP_CORE0_MASK
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"dsp boot core failed ret: %d
\n
"
,
ret
);
ret
=
-
EIO
;
goto
base_fw_load_failed
;
}
/* enable interrupt */
cnl_ipc_int_enable
(
ctx
);
cnl_ipc_op_int_enable
(
ctx
);
ret
=
sst_dsp_register_poll
(
ctx
,
CNL_ADSP_FW_STATUS
,
CNL_FW_STS_MASK
,
CNL_FW_ROM_INIT
,
CNL_INIT_TIMEOUT
,
"rom load"
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"rom init timeout, ret: %d
\n
"
,
ret
);
goto
base_fw_load_failed
;
}
return
0
;
base_fw_load_failed:
ctx
->
dsp_ops
.
cleanup
(
ctx
->
dev
,
&
ctx
->
dmab
,
stream_tag
);
cnl_dsp_disable_core
(
ctx
,
SKL_DSP_CORE0_MASK
);
return
ret
;
}
static
int
sst_transfer_fw_host_dma
(
struct
sst_dsp
*
ctx
)
{
int
ret
;
ctx
->
dsp_ops
.
trigger
(
ctx
->
dev
,
true
,
ctx
->
dsp_ops
.
stream_tag
);
ret
=
sst_dsp_register_poll
(
ctx
,
CNL_ADSP_FW_STATUS
,
CNL_FW_STS_MASK
,
CNL_FW_INIT
,
CNL_BASEFW_TIMEOUT
,
"firmware boot"
);
ctx
->
dsp_ops
.
trigger
(
ctx
->
dev
,
false
,
ctx
->
dsp_ops
.
stream_tag
);
ctx
->
dsp_ops
.
cleanup
(
ctx
->
dev
,
&
ctx
->
dmab
,
ctx
->
dsp_ops
.
stream_tag
);
return
ret
;
}
static
int
cnl_load_base_firmware
(
struct
sst_dsp
*
ctx
)
{
struct
firmware
stripped_fw
;
struct
skl_sst
*
cnl
=
ctx
->
thread_context
;
int
ret
;
if
(
!
ctx
->
fw
)
{
ret
=
request_firmware
(
&
ctx
->
fw
,
ctx
->
fw_name
,
ctx
->
dev
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"request firmware failed: %d
\n
"
,
ret
);
goto
cnl_load_base_firmware_failed
;
}
}
/* parse uuids if first boot */
if
(
cnl
->
is_first_boot
)
{
ret
=
snd_skl_parse_uuids
(
ctx
,
ctx
->
fw
,
CNL_ADSP_FW_HDR_OFFSET
,
0
);
if
(
ret
<
0
)
goto
cnl_load_base_firmware_failed
;
}
stripped_fw
.
data
=
ctx
->
fw
->
data
;
stripped_fw
.
size
=
ctx
->
fw
->
size
;
skl_dsp_strip_extended_manifest
(
&
stripped_fw
);
ret
=
cnl_prepare_fw
(
ctx
,
stripped_fw
.
data
,
stripped_fw
.
size
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"prepare firmware failed: %d
\n
"
,
ret
);
goto
cnl_load_base_firmware_failed
;
}
ret
=
sst_transfer_fw_host_dma
(
ctx
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"transfer firmware failed: %d
\n
"
,
ret
);
cnl_dsp_disable_core
(
ctx
,
SKL_DSP_CORE0_MASK
);
goto
cnl_load_base_firmware_failed
;
}
ret
=
wait_event_timeout
(
cnl
->
boot_wait
,
cnl
->
boot_complete
,
msecs_to_jiffies
(
SKL_IPC_BOOT_MSECS
));
if
(
ret
==
0
)
{
dev_err
(
ctx
->
dev
,
"FW ready timed-out
\n
"
);
cnl_dsp_disable_core
(
ctx
,
SKL_DSP_CORE0_MASK
);
ret
=
-
EIO
;
goto
cnl_load_base_firmware_failed
;
}
cnl
->
fw_loaded
=
true
;
return
0
;
cnl_load_base_firmware_failed:
release_firmware
(
ctx
->
fw
);
ctx
->
fw
=
NULL
;
return
ret
;
}
static
int
cnl_set_dsp_D0
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_id
)
{
struct
skl_sst
*
cnl
=
ctx
->
thread_context
;
unsigned
int
core_mask
=
SKL_DSP_CORE_MASK
(
core_id
);
struct
skl_ipc_dxstate_info
dx
;
int
ret
;
if
(
!
cnl
->
fw_loaded
)
{
cnl
->
boot_complete
=
false
;
ret
=
cnl_load_base_firmware
(
ctx
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"fw reload failed: %d
\n
"
,
ret
);
return
ret
;
}
cnl
->
cores
.
state
[
core_id
]
=
SKL_DSP_RUNNING
;
return
ret
;
}
ret
=
cnl_dsp_enable_core
(
ctx
,
core_mask
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"enable dsp core %d failed: %d
\n
"
,
core_id
,
ret
);
goto
err
;
}
if
(
core_id
==
SKL_DSP_CORE0_ID
)
{
/* enable interrupt */
cnl_ipc_int_enable
(
ctx
);
cnl_ipc_op_int_enable
(
ctx
);
cnl
->
boot_complete
=
false
;
ret
=
wait_event_timeout
(
cnl
->
boot_wait
,
cnl
->
boot_complete
,
msecs_to_jiffies
(
SKL_IPC_BOOT_MSECS
));
if
(
ret
==
0
)
{
dev_err
(
ctx
->
dev
,
"dsp boot timeout, status=%#x error=%#x
\n
"
,
sst_dsp_shim_read
(
ctx
,
CNL_ADSP_FW_STATUS
),
sst_dsp_shim_read
(
ctx
,
CNL_ADSP_ERROR_CODE
));
goto
err
;
}
}
else
{
dx
.
core_mask
=
core_mask
;
dx
.
dx_mask
=
core_mask
;
ret
=
skl_ipc_set_dx
(
&
cnl
->
ipc
,
CNL_INSTANCE_ID
,
CNL_BASE_FW_MODULE_ID
,
&
dx
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"set_dx failed, core: %d ret: %d
\n
"
,
core_id
,
ret
);
goto
err
;
}
}
cnl
->
cores
.
state
[
core_id
]
=
SKL_DSP_RUNNING
;
return
0
;
err:
cnl_dsp_disable_core
(
ctx
,
core_mask
);
return
ret
;
}
static
int
cnl_set_dsp_D3
(
struct
sst_dsp
*
ctx
,
unsigned
int
core_id
)
{
struct
skl_sst
*
cnl
=
ctx
->
thread_context
;
unsigned
int
core_mask
=
SKL_DSP_CORE_MASK
(
core_id
);
struct
skl_ipc_dxstate_info
dx
;
int
ret
;
dx
.
core_mask
=
core_mask
;
dx
.
dx_mask
=
SKL_IPC_D3_MASK
;
ret
=
skl_ipc_set_dx
(
&
cnl
->
ipc
,
CNL_INSTANCE_ID
,
CNL_BASE_FW_MODULE_ID
,
&
dx
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"dsp core %d to d3 failed; continue reset
\n
"
,
core_id
);
cnl
->
fw_loaded
=
false
;
}
/* disable interrupts if core 0 */
if
(
core_id
==
SKL_DSP_CORE0_ID
)
{
skl_ipc_op_int_disable
(
ctx
);
skl_ipc_int_disable
(
ctx
);
}
ret
=
cnl_dsp_disable_core
(
ctx
,
core_mask
);
if
(
ret
<
0
)
{
dev_err
(
ctx
->
dev
,
"disable dsp core %d failed: %d
\n
"
,
core_id
,
ret
);
return
ret
;
}
cnl
->
cores
.
state
[
core_id
]
=
SKL_DSP_RESET
;
return
ret
;
}
static
unsigned
int
cnl_get_errno
(
struct
sst_dsp
*
ctx
)
{
return
sst_dsp_shim_read
(
ctx
,
CNL_ADSP_ERROR_CODE
);
}
static
const
struct
skl_dsp_fw_ops
cnl_fw_ops
=
{
.
set_state_D0
=
cnl_set_dsp_D0
,
.
set_state_D3
=
cnl_set_dsp_D3
,
.
load_fw
=
cnl_load_base_firmware
,
.
get_fw_errcode
=
cnl_get_errno
,
};
static
struct
sst_ops
cnl_ops
=
{
.
irq_handler
=
cnl_dsp_sst_interrupt
,
.
write
=
sst_shim32_write
,
.
read
=
sst_shim32_read
,
.
ram_read
=
sst_memcpy_fromio_32
,
.
ram_write
=
sst_memcpy_toio_32
,
.
free
=
cnl_dsp_free
,
};
#define CNL_IPC_GLB_NOTIFY_RSP_SHIFT 29
#define CNL_IPC_GLB_NOTIFY_RSP_MASK 0x1
#define CNL_IPC_GLB_NOTIFY_RSP_TYPE(x) (((x) >> CNL_IPC_GLB_NOTIFY_RSP_SHIFT) \
& CNL_IPC_GLB_NOTIFY_RSP_MASK)
static
irqreturn_t
cnl_dsp_irq_thread_handler
(
int
irq
,
void
*
context
)
{
struct
sst_dsp
*
dsp
=
context
;
struct
skl_sst
*
cnl
=
sst_dsp_get_thread_context
(
dsp
);
struct
sst_generic_ipc
*
ipc
=
&
cnl
->
ipc
;
struct
skl_ipc_header
header
=
{
0
};
u32
hipcida
,
hipctdr
,
hipctdd
;
int
ipc_irq
=
0
;
/* here we handle ipc interrupts only */
if
(
!
(
dsp
->
intr_status
&
CNL_ADSPIS_IPC
))
return
IRQ_NONE
;
hipcida
=
sst_dsp_shim_read_unlocked
(
dsp
,
CNL_ADSP_REG_HIPCIDA
);
hipctdr
=
sst_dsp_shim_read_unlocked
(
dsp
,
CNL_ADSP_REG_HIPCTDR
);
/* reply message from dsp */
if
(
hipcida
&
CNL_ADSP_REG_HIPCIDA_DONE
)
{
sst_dsp_shim_update_bits
(
dsp
,
CNL_ADSP_REG_HIPCCTL
,
CNL_ADSP_REG_HIPCCTL_DONE
,
0
);
/* clear done bit - tell dsp operation is complete */
sst_dsp_shim_update_bits_forced
(
dsp
,
CNL_ADSP_REG_HIPCIDA
,
CNL_ADSP_REG_HIPCIDA_DONE
,
CNL_ADSP_REG_HIPCIDA_DONE
);
ipc_irq
=
1
;
/* unmask done interrupt */
sst_dsp_shim_update_bits
(
dsp
,
CNL_ADSP_REG_HIPCCTL
,
CNL_ADSP_REG_HIPCCTL_DONE
,
CNL_ADSP_REG_HIPCCTL_DONE
);
}
/* new message from dsp */
if
(
hipctdr
&
CNL_ADSP_REG_HIPCTDR_BUSY
)
{
hipctdd
=
sst_dsp_shim_read_unlocked
(
dsp
,
CNL_ADSP_REG_HIPCTDD
);
header
.
primary
=
hipctdr
;
header
.
extension
=
hipctdd
;
dev_dbg
(
dsp
->
dev
,
"IPC irq: Firmware respond primary:%x"
,
header
.
primary
);
dev_dbg
(
dsp
->
dev
,
"IPC irq: Firmware respond extension:%x"
,
header
.
extension
);
if
(
CNL_IPC_GLB_NOTIFY_RSP_TYPE
(
header
.
primary
))
{
/* Handle Immediate reply from DSP Core */
skl_ipc_process_reply
(
ipc
,
header
);
}
else
{
dev_dbg
(
dsp
->
dev
,
"IPC irq: Notification from firmware
\n
"
);
skl_ipc_process_notification
(
ipc
,
header
);
}
/* clear busy interrupt */
sst_dsp_shim_update_bits_forced
(
dsp
,
CNL_ADSP_REG_HIPCTDR
,
CNL_ADSP_REG_HIPCTDR_BUSY
,
CNL_ADSP_REG_HIPCTDR_BUSY
);
/* set done bit to ack dsp */
sst_dsp_shim_update_bits_forced
(
dsp
,
CNL_ADSP_REG_HIPCTDA
,
CNL_ADSP_REG_HIPCTDA_DONE
,
CNL_ADSP_REG_HIPCTDA_DONE
);
ipc_irq
=
1
;
}
if
(
ipc_irq
==
0
)
return
IRQ_NONE
;
cnl_ipc_int_enable
(
dsp
);
/* continue to send any remaining messages */
schedule_work
(
&
ipc
->
kwork
);
return
IRQ_HANDLED
;
}
static
struct
sst_dsp_device
cnl_dev
=
{
.
thread
=
cnl_dsp_irq_thread_handler
,
.
ops
=
&
cnl_ops
,
};
static
void
cnl_ipc_tx_msg
(
struct
sst_generic_ipc
*
ipc
,
struct
ipc_message
*
msg
)
{
struct
skl_ipc_header
*
header
=
(
struct
skl_ipc_header
*
)(
&
msg
->
header
);
if
(
msg
->
tx_size
)
sst_dsp_outbox_write
(
ipc
->
dsp
,
msg
->
tx_data
,
msg
->
tx_size
);
sst_dsp_shim_write_unlocked
(
ipc
->
dsp
,
CNL_ADSP_REG_HIPCIDD
,
header
->
extension
);
sst_dsp_shim_write_unlocked
(
ipc
->
dsp
,
CNL_ADSP_REG_HIPCIDR
,
header
->
primary
|
CNL_ADSP_REG_HIPCIDR_BUSY
);
}
static
bool
cnl_ipc_is_dsp_busy
(
struct
sst_dsp
*
dsp
)
{
u32
hipcidr
;
hipcidr
=
sst_dsp_shim_read_unlocked
(
dsp
,
CNL_ADSP_REG_HIPCIDR
);
return
(
hipcidr
&
CNL_ADSP_REG_HIPCIDR_BUSY
);
}
static
int
cnl_ipc_init
(
struct
device
*
dev
,
struct
skl_sst
*
cnl
)
{
struct
sst_generic_ipc
*
ipc
;
int
err
;
ipc
=
&
cnl
->
ipc
;
ipc
->
dsp
=
cnl
->
dsp
;
ipc
->
dev
=
dev
;
ipc
->
tx_data_max_size
=
CNL_ADSP_W1_SZ
;
ipc
->
rx_data_max_size
=
CNL_ADSP_W0_UP_SZ
;
err
=
sst_ipc_init
(
ipc
);
if
(
err
)
return
err
;
/*
* overriding tx_msg and is_dsp_busy since
* ipc registers are different for cnl
*/
ipc
->
ops
.
tx_msg
=
cnl_ipc_tx_msg
;
ipc
->
ops
.
tx_data_copy
=
skl_ipc_tx_data_copy
;
ipc
->
ops
.
is_dsp_busy
=
cnl_ipc_is_dsp_busy
;
return
0
;
}
int
cnl_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
skl_sst
*
cnl
;
struct
sst_dsp
*
sst
;
int
ret
;
ret
=
skl_sst_ctx_init
(
dev
,
irq
,
fw_name
,
dsp_ops
,
dsp
,
&
cnl_dev
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"%s: no device
\n
"
,
__func__
);
return
ret
;
}
cnl
=
*
dsp
;
sst
=
cnl
->
dsp
;
sst
->
fw_ops
=
cnl_fw_ops
;
sst
->
addr
.
lpe
=
mmio_base
;
sst
->
addr
.
shim
=
mmio_base
;
sst
->
addr
.
sram0_base
=
CNL_ADSP_SRAM0_BASE
;
sst
->
addr
.
sram1_base
=
CNL_ADSP_SRAM1_BASE
;
sst
->
addr
.
w0_stat_sz
=
CNL_ADSP_W0_STAT_SZ
;
sst
->
addr
.
w0_up_sz
=
CNL_ADSP_W0_UP_SZ
;
sst_dsp_mailbox_init
(
sst
,
(
CNL_ADSP_SRAM0_BASE
+
CNL_ADSP_W0_STAT_SZ
),
CNL_ADSP_W0_UP_SZ
,
CNL_ADSP_SRAM1_BASE
,
CNL_ADSP_W1_SZ
);
ret
=
cnl_ipc_init
(
dev
,
cnl
);
if
(
ret
)
{
skl_dsp_free
(
sst
);
return
ret
;
}
cnl
->
boot_complete
=
false
;
init_waitqueue_head
(
&
cnl
->
boot_wait
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
cnl_sst_dsp_init
);
int
cnl_sst_init_fw
(
struct
device
*
dev
,
struct
skl_sst
*
ctx
)
{
int
ret
;
struct
sst_dsp
*
sst
=
ctx
->
dsp
;
ret
=
ctx
->
dsp
->
fw_ops
.
load_fw
(
sst
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"load base fw failed: %d"
,
ret
);
return
ret
;
}
skl_dsp_init_core_state
(
sst
);
ctx
->
is_first_boot
=
false
;
return
0
;
}
EXPORT_SYMBOL_GPL
(
cnl_sst_init_fw
);
void
cnl_sst_dsp_cleanup
(
struct
device
*
dev
,
struct
skl_sst
*
ctx
)
{
if
(
ctx
->
dsp
->
fw
)
release_firmware
(
ctx
->
dsp
->
fw
);
skl_freeup_uuid_list
(
ctx
);
cnl_ipc_free
(
&
ctx
->
ipc
);
ctx
->
dsp
->
ops
->
free
(
ctx
->
dsp
);
}
EXPORT_SYMBOL_GPL
(
cnl_sst_dsp_cleanup
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_DESCRIPTION
(
"Intel Cannonlake IPC driver"
);
sound/soc/intel/skylake/skl-messages.c
浏览文件 @
460f623a
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <sound/core.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm.h>
#include "skl-sst-dsp.h"
#include "skl-sst-dsp.h"
#include "cnl-sst-dsp.h"
#include "skl-sst-ipc.h"
#include "skl-sst-ipc.h"
#include "skl.h"
#include "skl.h"
#include "../common/sst-dsp.h"
#include "../common/sst-dsp.h"
...
@@ -201,6 +202,7 @@ static struct skl_dsp_loader_ops bxt_get_loader_ops(void)
...
@@ -201,6 +202,7 @@ static struct skl_dsp_loader_ops bxt_get_loader_ops(void)
static
const
struct
skl_dsp_ops
dsp_ops
[]
=
{
static
const
struct
skl_dsp_ops
dsp_ops
[]
=
{
{
{
.
id
=
0x9d70
,
.
id
=
0x9d70
,
.
num_cores
=
2
,
.
loader_ops
=
skl_get_loader_ops
,
.
loader_ops
=
skl_get_loader_ops
,
.
init
=
skl_sst_dsp_init
,
.
init
=
skl_sst_dsp_init
,
.
init_fw
=
skl_sst_init_fw
,
.
init_fw
=
skl_sst_init_fw
,
...
@@ -208,6 +210,7 @@ static const struct skl_dsp_ops dsp_ops[] = {
...
@@ -208,6 +210,7 @@ static const struct skl_dsp_ops dsp_ops[] = {
},
},
{
{
.
id
=
0x9d71
,
.
id
=
0x9d71
,
.
num_cores
=
2
,
.
loader_ops
=
skl_get_loader_ops
,
.
loader_ops
=
skl_get_loader_ops
,
.
init
=
kbl_sst_dsp_init
,
.
init
=
kbl_sst_dsp_init
,
.
init_fw
=
skl_sst_init_fw
,
.
init_fw
=
skl_sst_init_fw
,
...
@@ -215,6 +218,7 @@ static const struct skl_dsp_ops dsp_ops[] = {
...
@@ -215,6 +218,7 @@ static const struct skl_dsp_ops dsp_ops[] = {
},
},
{
{
.
id
=
0x5a98
,
.
id
=
0x5a98
,
.
num_cores
=
2
,
.
loader_ops
=
bxt_get_loader_ops
,
.
loader_ops
=
bxt_get_loader_ops
,
.
init
=
bxt_sst_dsp_init
,
.
init
=
bxt_sst_dsp_init
,
.
init_fw
=
bxt_sst_init_fw
,
.
init_fw
=
bxt_sst_init_fw
,
...
@@ -222,11 +226,20 @@ static const struct skl_dsp_ops dsp_ops[] = {
...
@@ -222,11 +226,20 @@ static const struct skl_dsp_ops dsp_ops[] = {
},
},
{
{
.
id
=
0x3198
,
.
id
=
0x3198
,
.
num_cores
=
2
,
.
loader_ops
=
bxt_get_loader_ops
,
.
loader_ops
=
bxt_get_loader_ops
,
.
init
=
bxt_sst_dsp_init
,
.
init
=
bxt_sst_dsp_init
,
.
init_fw
=
bxt_sst_init_fw
,
.
init_fw
=
bxt_sst_init_fw
,
.
cleanup
=
bxt_sst_dsp_cleanup
.
cleanup
=
bxt_sst_dsp_cleanup
},
},
{
.
id
=
0x9dc8
,
.
num_cores
=
4
,
.
loader_ops
=
bxt_get_loader_ops
,
.
init
=
cnl_sst_dsp_init
,
.
init_fw
=
cnl_sst_init_fw
,
.
cleanup
=
cnl_sst_dsp_cleanup
},
};
};
const
struct
skl_dsp_ops
*
skl_get_dsp_ops
(
int
pci_id
)
const
struct
skl_dsp_ops
*
skl_get_dsp_ops
(
int
pci_id
)
...
@@ -249,6 +262,7 @@ int skl_init_dsp(struct skl *skl)
...
@@ -249,6 +262,7 @@ int skl_init_dsp(struct skl *skl)
struct
skl_dsp_loader_ops
loader_ops
;
struct
skl_dsp_loader_ops
loader_ops
;
int
irq
=
bus
->
irq
;
int
irq
=
bus
->
irq
;
const
struct
skl_dsp_ops
*
ops
;
const
struct
skl_dsp_ops
*
ops
;
struct
skl_dsp_cores
*
cores
;
int
ret
;
int
ret
;
/* enable ppcap interrupt */
/* enable ppcap interrupt */
...
@@ -263,8 +277,10 @@ int skl_init_dsp(struct skl *skl)
...
@@ -263,8 +277,10 @@ int skl_init_dsp(struct skl *skl)
}
}
ops
=
skl_get_dsp_ops
(
skl
->
pci
->
device
);
ops
=
skl_get_dsp_ops
(
skl
->
pci
->
device
);
if
(
!
ops
)
if
(
!
ops
)
{
return
-
EIO
;
ret
=
-
EIO
;
goto
unmap_mmio
;
}
loader_ops
=
ops
->
loader_ops
();
loader_ops
=
ops
->
loader_ops
();
ret
=
ops
->
init
(
bus
->
dev
,
mmio_base
,
irq
,
ret
=
ops
->
init
(
bus
->
dev
,
mmio_base
,
irq
,
...
@@ -272,11 +288,35 @@ int skl_init_dsp(struct skl *skl)
...
@@ -272,11 +288,35 @@ int skl_init_dsp(struct skl *skl)
&
skl
->
skl_sst
);
&
skl
->
skl_sst
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
goto
unmap_mmio
;
skl
->
skl_sst
->
dsp_ops
=
ops
;
skl
->
skl_sst
->
dsp_ops
=
ops
;
cores
=
&
skl
->
skl_sst
->
cores
;
cores
->
count
=
ops
->
num_cores
;
cores
->
state
=
kcalloc
(
cores
->
count
,
sizeof
(
*
cores
->
state
),
GFP_KERNEL
);
if
(
!
cores
->
state
)
{
ret
=
-
ENOMEM
;
goto
unmap_mmio
;
}
cores
->
usage_count
=
kcalloc
(
cores
->
count
,
sizeof
(
*
cores
->
usage_count
),
GFP_KERNEL
);
if
(
!
cores
->
usage_count
)
{
ret
=
-
ENOMEM
;
goto
free_core_state
;
}
dev_dbg
(
bus
->
dev
,
"dsp registration status=%d
\n
"
,
ret
);
dev_dbg
(
bus
->
dev
,
"dsp registration status=%d
\n
"
,
ret
);
return
0
;
free_core_state:
kfree
(
cores
->
state
);
unmap_mmio:
iounmap
(
mmio_base
);
return
ret
;
return
ret
;
}
}
...
@@ -291,6 +331,9 @@ int skl_free_dsp(struct skl *skl)
...
@@ -291,6 +331,9 @@ int skl_free_dsp(struct skl *skl)
ctx
->
dsp_ops
->
cleanup
(
bus
->
dev
,
ctx
);
ctx
->
dsp_ops
->
cleanup
(
bus
->
dev
,
ctx
);
kfree
(
ctx
->
cores
.
state
);
kfree
(
ctx
->
cores
.
usage_count
);
if
(
ctx
->
dsp
->
addr
.
lpe
)
if
(
ctx
->
dsp
->
addr
.
lpe
)
iounmap
(
ctx
->
dsp
->
addr
.
lpe
);
iounmap
(
ctx
->
dsp
->
addr
.
lpe
);
...
@@ -400,9 +443,12 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
...
@@ -400,9 +443,12 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
struct
skl_module_cfg
*
mconfig
,
struct
skl_module_cfg
*
mconfig
,
struct
skl_base_cfg
*
base_cfg
)
struct
skl_base_cfg
*
base_cfg
)
{
{
struct
skl_module_fmt
*
format
=
&
mconfig
->
in_fmt
[
0
];
struct
skl_module
*
module
=
mconfig
->
module
;
struct
skl_module_res
*
res
=
&
module
->
resources
[
mconfig
->
res_idx
];
struct
skl_module_iface
*
fmt
=
&
module
->
formats
[
mconfig
->
fmt_idx
];
struct
skl_module_fmt
*
format
=
&
fmt
->
inputs
[
0
].
fmt
;
base_cfg
->
audio_fmt
.
number_of_channels
=
(
u8
)
format
->
channels
;
base_cfg
->
audio_fmt
.
number_of_channels
=
format
->
channels
;
base_cfg
->
audio_fmt
.
s_freq
=
format
->
s_freq
;
base_cfg
->
audio_fmt
.
s_freq
=
format
->
s_freq
;
base_cfg
->
audio_fmt
.
bit_depth
=
format
->
bit_depth
;
base_cfg
->
audio_fmt
.
bit_depth
=
format
->
bit_depth
;
...
@@ -417,10 +463,10 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
...
@@ -417,10 +463,10 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
base_cfg
->
audio_fmt
.
interleaving
=
format
->
interleaving_style
;
base_cfg
->
audio_fmt
.
interleaving
=
format
->
interleaving_style
;
base_cfg
->
cps
=
mconfig
->
m
cps
;
base_cfg
->
cps
=
res
->
cps
;
base_cfg
->
ibs
=
mconfig
->
ibs
;
base_cfg
->
ibs
=
res
->
ibs
;
base_cfg
->
obs
=
mconfig
->
obs
;
base_cfg
->
obs
=
res
->
obs
;
base_cfg
->
is_pages
=
mconfig
->
mem
_pages
;
base_cfg
->
is_pages
=
res
->
is
_pages
;
}
}
/*
/*
...
@@ -508,6 +554,9 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
...
@@ -508,6 +554,9 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
struct
skl_cpr_cfg
*
cpr_mconfig
)
struct
skl_cpr_cfg
*
cpr_mconfig
)
{
{
u32
dma_io_buf
;
u32
dma_io_buf
;
struct
skl_module_res
*
res
;
int
res_idx
=
mconfig
->
res_idx
;
struct
skl
*
skl
=
get_skl_ctx
(
ctx
->
dev
);
cpr_mconfig
->
gtw_cfg
.
node_id
=
skl_get_node_id
(
ctx
,
mconfig
);
cpr_mconfig
->
gtw_cfg
.
node_id
=
skl_get_node_id
(
ctx
,
mconfig
);
...
@@ -516,19 +565,27 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
...
@@ -516,19 +565,27 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
return
;
return
;
}
}
if
(
skl
->
nr_modules
)
{
res
=
&
mconfig
->
module
->
resources
[
mconfig
->
res_idx
];
cpr_mconfig
->
gtw_cfg
.
dma_buffer_size
=
res
->
dma_buffer_size
;
goto
skip_buf_size_calc
;
}
else
{
res
=
&
mconfig
->
module
->
resources
[
res_idx
];
}
switch
(
mconfig
->
hw_conn_type
)
{
switch
(
mconfig
->
hw_conn_type
)
{
case
SKL_CONN_SOURCE
:
case
SKL_CONN_SOURCE
:
if
(
mconfig
->
dev_type
==
SKL_DEVICE_HDAHOST
)
if
(
mconfig
->
dev_type
==
SKL_DEVICE_HDAHOST
)
dma_io_buf
=
mconfig
->
ibs
;
dma_io_buf
=
res
->
ibs
;
else
else
dma_io_buf
=
mconfig
->
obs
;
dma_io_buf
=
res
->
obs
;
break
;
break
;
case
SKL_CONN_SINK
:
case
SKL_CONN_SINK
:
if
(
mconfig
->
dev_type
==
SKL_DEVICE_HDAHOST
)
if
(
mconfig
->
dev_type
==
SKL_DEVICE_HDAHOST
)
dma_io_buf
=
mconfig
->
obs
;
dma_io_buf
=
res
->
obs
;
else
else
dma_io_buf
=
mconfig
->
ibs
;
dma_io_buf
=
res
->
ibs
;
break
;
break
;
default:
default:
...
@@ -543,11 +600,12 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
...
@@ -543,11 +600,12 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
/* fallback to 2ms default value */
/* fallback to 2ms default value */
if
(
!
cpr_mconfig
->
gtw_cfg
.
dma_buffer_size
)
{
if
(
!
cpr_mconfig
->
gtw_cfg
.
dma_buffer_size
)
{
if
(
mconfig
->
hw_conn_type
==
SKL_CONN_SOURCE
)
if
(
mconfig
->
hw_conn_type
==
SKL_CONN_SOURCE
)
cpr_mconfig
->
gtw_cfg
.
dma_buffer_size
=
2
*
mconfig
->
obs
;
cpr_mconfig
->
gtw_cfg
.
dma_buffer_size
=
2
*
res
->
obs
;
else
else
cpr_mconfig
->
gtw_cfg
.
dma_buffer_size
=
2
*
mconfig
->
ibs
;
cpr_mconfig
->
gtw_cfg
.
dma_buffer_size
=
2
*
res
->
ibs
;
}
}
skip_buf_size_calc:
cpr_mconfig
->
cpr_feature_mask
=
0
;
cpr_mconfig
->
cpr_feature_mask
=
0
;
cpr_mconfig
->
gtw_cfg
.
config_length
=
0
;
cpr_mconfig
->
gtw_cfg
.
config_length
=
0
;
...
@@ -595,7 +653,9 @@ static void skl_setup_out_format(struct skl_sst *ctx,
...
@@ -595,7 +653,9 @@ static void skl_setup_out_format(struct skl_sst *ctx,
struct
skl_module_cfg
*
mconfig
,
struct
skl_module_cfg
*
mconfig
,
struct
skl_audio_data_format
*
out_fmt
)
struct
skl_audio_data_format
*
out_fmt
)
{
{
struct
skl_module_fmt
*
format
=
&
mconfig
->
out_fmt
[
0
];
struct
skl_module
*
module
=
mconfig
->
module
;
struct
skl_module_iface
*
fmt
=
&
module
->
formats
[
mconfig
->
fmt_idx
];
struct
skl_module_fmt
*
format
=
&
fmt
->
outputs
[
0
].
fmt
;
out_fmt
->
number_of_channels
=
(
u8
)
format
->
channels
;
out_fmt
->
number_of_channels
=
(
u8
)
format
->
channels
;
out_fmt
->
s_freq
=
format
->
s_freq
;
out_fmt
->
s_freq
=
format
->
s_freq
;
...
@@ -620,7 +680,9 @@ static void skl_set_src_format(struct skl_sst *ctx,
...
@@ -620,7 +680,9 @@ static void skl_set_src_format(struct skl_sst *ctx,
struct
skl_module_cfg
*
mconfig
,
struct
skl_module_cfg
*
mconfig
,
struct
skl_src_module_cfg
*
src_mconfig
)
struct
skl_src_module_cfg
*
src_mconfig
)
{
{
struct
skl_module_fmt
*
fmt
=
&
mconfig
->
out_fmt
[
0
];
struct
skl_module
*
module
=
mconfig
->
module
;
struct
skl_module_iface
*
iface
=
&
module
->
formats
[
mconfig
->
fmt_idx
];
struct
skl_module_fmt
*
fmt
=
&
iface
->
outputs
[
0
].
fmt
;
skl_set_base_module_format
(
ctx
,
mconfig
,
skl_set_base_module_format
(
ctx
,
mconfig
,
(
struct
skl_base_cfg
*
)
src_mconfig
);
(
struct
skl_base_cfg
*
)
src_mconfig
);
...
@@ -637,7 +699,9 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx,
...
@@ -637,7 +699,9 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx,
struct
skl_module_cfg
*
mconfig
,
struct
skl_module_cfg
*
mconfig
,
struct
skl_up_down_mixer_cfg
*
mixer_mconfig
)
struct
skl_up_down_mixer_cfg
*
mixer_mconfig
)
{
{
struct
skl_module_fmt
*
fmt
=
&
mconfig
->
out_fmt
[
0
];
struct
skl_module
*
module
=
mconfig
->
module
;
struct
skl_module_iface
*
iface
=
&
module
->
formats
[
mconfig
->
fmt_idx
];
struct
skl_module_fmt
*
fmt
=
&
iface
->
outputs
[
0
].
fmt
;
int
i
=
0
;
int
i
=
0
;
skl_set_base_module_format
(
ctx
,
mconfig
,
skl_set_base_module_format
(
ctx
,
mconfig
,
...
@@ -950,7 +1014,7 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg
...
@@ -950,7 +1014,7 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg
{
{
dev_dbg
(
ctx
->
dev
,
"%s: src module_id = %d src_instance=%d
\n
"
,
dev_dbg
(
ctx
->
dev
,
"%s: src module_id = %d src_instance=%d
\n
"
,
__func__
,
src_module
->
id
.
module_id
,
src_module
->
id
.
pvt_id
);
__func__
,
src_module
->
id
.
module_id
,
src_module
->
id
.
pvt_id
);
dev_dbg
(
ctx
->
dev
,
"%s: dst_module=%d dst_insta
cn
e=%d
\n
"
,
__func__
,
dev_dbg
(
ctx
->
dev
,
"%s: dst_module=%d dst_insta
nc
e=%d
\n
"
,
__func__
,
dst_module
->
id
.
module_id
,
dst_module
->
id
.
pvt_id
);
dst_module
->
id
.
module_id
,
dst_module
->
id
.
pvt_id
);
dev_dbg
(
ctx
->
dev
,
"src_module state = %d dst module state = %d
\n
"
,
dev_dbg
(
ctx
->
dev
,
"src_module state = %d dst module state = %d
\n
"
,
...
@@ -970,8 +1034,8 @@ int skl_unbind_modules(struct skl_sst *ctx,
...
@@ -970,8 +1034,8 @@ int skl_unbind_modules(struct skl_sst *ctx,
struct
skl_ipc_bind_unbind_msg
msg
;
struct
skl_ipc_bind_unbind_msg
msg
;
struct
skl_module_inst_id
src_id
=
src_mcfg
->
id
;
struct
skl_module_inst_id
src_id
=
src_mcfg
->
id
;
struct
skl_module_inst_id
dst_id
=
dst_mcfg
->
id
;
struct
skl_module_inst_id
dst_id
=
dst_mcfg
->
id
;
int
in_max
=
dst_mcfg
->
m
ax_in_queue
;
int
in_max
=
dst_mcfg
->
m
odule
->
max_input_pins
;
int
out_max
=
src_mcfg
->
m
ax_out_queue
;
int
out_max
=
src_mcfg
->
m
odule
->
max_output_pins
;
int
src_index
,
dst_index
,
src_pin_state
,
dst_pin_state
;
int
src_index
,
dst_index
,
src_pin_state
,
dst_pin_state
;
skl_dump_bind_info
(
ctx
,
src_mcfg
,
dst_mcfg
);
skl_dump_bind_info
(
ctx
,
src_mcfg
,
dst_mcfg
);
...
@@ -1019,6 +1083,21 @@ int skl_unbind_modules(struct skl_sst *ctx,
...
@@ -1019,6 +1083,21 @@ int skl_unbind_modules(struct skl_sst *ctx,
return
ret
;
return
ret
;
}
}
static
void
fill_pin_params
(
struct
skl_audio_data_format
*
pin_fmt
,
struct
skl_module_fmt
*
format
)
{
pin_fmt
->
number_of_channels
=
format
->
channels
;
pin_fmt
->
s_freq
=
format
->
s_freq
;
pin_fmt
->
bit_depth
=
format
->
bit_depth
;
pin_fmt
->
valid_bit_depth
=
format
->
valid_bit_depth
;
pin_fmt
->
ch_cfg
=
format
->
ch_cfg
;
pin_fmt
->
sample_type
=
format
->
sample_type
;
pin_fmt
->
channel_map
=
format
->
ch_map
;
pin_fmt
->
interleaving
=
format
->
interleaving_style
;
}
#define CPR_SINK_FMT_PARAM_ID 2
/*
/*
* Once a module is instantiated it need to be 'bind' with other modules in
* Once a module is instantiated it need to be 'bind' with other modules in
* the pipeline. For binding we need to find the module pins which are bind
* the pipeline. For binding we need to find the module pins which are bind
...
@@ -1030,11 +1109,15 @@ int skl_bind_modules(struct skl_sst *ctx,
...
@@ -1030,11 +1109,15 @@ int skl_bind_modules(struct skl_sst *ctx,
struct
skl_module_cfg
*
src_mcfg
,
struct
skl_module_cfg
*
src_mcfg
,
struct
skl_module_cfg
*
dst_mcfg
)
struct
skl_module_cfg
*
dst_mcfg
)
{
{
int
ret
;
int
ret
=
0
;
struct
skl_ipc_bind_unbind_msg
msg
;
struct
skl_ipc_bind_unbind_msg
msg
;
int
in_max
=
dst_mcfg
->
m
ax_in_queue
;
int
in_max
=
dst_mcfg
->
m
odule
->
max_input_pins
;
int
out_max
=
src_mcfg
->
m
ax_out_queue
;
int
out_max
=
src_mcfg
->
m
odule
->
max_output_pins
;
int
src_index
,
dst_index
;
int
src_index
,
dst_index
;
struct
skl_module_fmt
*
format
;
struct
skl_cpr_pin_fmt
pin_fmt
;
struct
skl_module
*
module
;
struct
skl_module_iface
*
fmt
;
skl_dump_bind_info
(
ctx
,
src_mcfg
,
dst_mcfg
);
skl_dump_bind_info
(
ctx
,
src_mcfg
,
dst_mcfg
);
...
@@ -1053,6 +1136,29 @@ int skl_bind_modules(struct skl_sst *ctx,
...
@@ -1053,6 +1136,29 @@ int skl_bind_modules(struct skl_sst *ctx,
return
-
EINVAL
;
return
-
EINVAL
;
}
}
/*
* Copier module requires the separate large_config_set_ipc to
* configure the pins other than 0
*/
if
(
src_mcfg
->
m_type
==
SKL_MODULE_TYPE_COPIER
&&
src_index
>
0
)
{
pin_fmt
.
sink_id
=
src_index
;
module
=
src_mcfg
->
module
;
fmt
=
&
module
->
formats
[
src_mcfg
->
fmt_idx
];
/* Input fmt is same as that of src module input cfg */
format
=
&
fmt
->
inputs
[
0
].
fmt
;
fill_pin_params
(
&
(
pin_fmt
.
src_fmt
),
format
);
format
=
&
fmt
->
outputs
[
src_index
].
fmt
;
fill_pin_params
(
&
(
pin_fmt
.
dst_fmt
),
format
);
ret
=
skl_set_module_params
(
ctx
,
(
void
*
)
&
pin_fmt
,
sizeof
(
struct
skl_cpr_pin_fmt
),
CPR_SINK_FMT_PARAM_ID
,
src_mcfg
);
if
(
ret
<
0
)
goto
out
;
}
msg
.
dst_queue
=
dst_index
;
msg
.
dst_queue
=
dst_index
;
dev_dbg
(
ctx
->
dev
,
"src queue = %d dst queue =%d
\n
"
,
dev_dbg
(
ctx
->
dev
,
"src queue = %d dst queue =%d
\n
"
,
...
@@ -1070,11 +1176,12 @@ int skl_bind_modules(struct skl_sst *ctx,
...
@@ -1070,11 +1176,12 @@ int skl_bind_modules(struct skl_sst *ctx,
src_mcfg
->
m_state
=
SKL_MODULE_BIND_DONE
;
src_mcfg
->
m_state
=
SKL_MODULE_BIND_DONE
;
src_mcfg
->
m_out_pin
[
src_index
].
pin_state
=
SKL_PIN_BIND_DONE
;
src_mcfg
->
m_out_pin
[
src_index
].
pin_state
=
SKL_PIN_BIND_DONE
;
dst_mcfg
->
m_in_pin
[
dst_index
].
pin_state
=
SKL_PIN_BIND_DONE
;
dst_mcfg
->
m_in_pin
[
dst_index
].
pin_state
=
SKL_PIN_BIND_DONE
;
}
else
{
return
ret
;
/* error case , if IPC fails, clear the queue index */
skl_free_queue
(
src_mcfg
->
m_out_pin
,
src_index
);
skl_free_queue
(
dst_mcfg
->
m_in_pin
,
dst_index
);
}
}
out:
/* error case , if IPC fails, clear the queue index */
skl_free_queue
(
src_mcfg
->
m_out_pin
,
src_index
);
skl_free_queue
(
dst_mcfg
->
m_in_pin
,
dst_index
);
return
ret
;
return
ret
;
}
}
...
...
sound/soc/intel/skylake/skl-pcm.c
浏览文件 @
460f623a
...
@@ -33,7 +33,7 @@
...
@@ -33,7 +33,7 @@
#define HDA_STEREO 2
#define HDA_STEREO 2
#define HDA_QUAD 4
#define HDA_QUAD 4
static
struct
snd_pcm_hardware
azx_pcm_hw
=
{
static
const
struct
snd_pcm_hardware
azx_pcm_hw
=
{
.
info
=
(
SNDRV_PCM_INFO_MMAP
|
.
info
=
(
SNDRV_PCM_INFO_MMAP
|
SNDRV_PCM_INFO_INTERLEAVED
|
SNDRV_PCM_INFO_INTERLEAVED
|
SNDRV_PCM_INFO_BLOCK_TRANSFER
|
SNDRV_PCM_INFO_BLOCK_TRANSFER
|
...
@@ -628,7 +628,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
...
@@ -628,7 +628,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
return
0
;
return
0
;
}
}
static
struct
snd_soc_dai_ops
skl_pcm_dai_ops
=
{
static
const
struct
snd_soc_dai_ops
skl_pcm_dai_ops
=
{
.
startup
=
skl_pcm_open
,
.
startup
=
skl_pcm_open
,
.
shutdown
=
skl_pcm_close
,
.
shutdown
=
skl_pcm_close
,
.
prepare
=
skl_pcm_prepare
,
.
prepare
=
skl_pcm_prepare
,
...
@@ -637,15 +637,15 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = {
...
@@ -637,15 +637,15 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = {
.
trigger
=
skl_pcm_trigger
,
.
trigger
=
skl_pcm_trigger
,
};
};
static
struct
snd_soc_dai_ops
skl_dmic_dai_ops
=
{
static
const
struct
snd_soc_dai_ops
skl_dmic_dai_ops
=
{
.
hw_params
=
skl_be_hw_params
,
.
hw_params
=
skl_be_hw_params
,
};
};
static
struct
snd_soc_dai_ops
skl_be_ssp_dai_ops
=
{
static
const
struct
snd_soc_dai_ops
skl_be_ssp_dai_ops
=
{
.
hw_params
=
skl_be_hw_params
,
.
hw_params
=
skl_be_hw_params
,
};
};
static
struct
snd_soc_dai_ops
skl_link_dai_ops
=
{
static
const
struct
snd_soc_dai_ops
skl_link_dai_ops
=
{
.
prepare
=
skl_link_pcm_prepare
,
.
prepare
=
skl_link_pcm_prepare
,
.
hw_params
=
skl_link_hw_params
,
.
hw_params
=
skl_link_hw_params
,
.
hw_free
=
skl_link_hw_free
,
.
hw_free
=
skl_link_hw_free
,
...
@@ -674,6 +674,32 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
...
@@ -674,6 +674,32 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
sig_bits
=
32
,
.
sig_bits
=
32
,
},
},
},
},
{
.
name
=
"System Pin2"
,
.
ops
=
&
skl_pcm_dai_ops
,
.
playback
=
{
.
stream_name
=
"Headset Playback"
,
.
channels_min
=
HDA_MONO
,
.
channels_max
=
HDA_STEREO
,
.
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
,
},
},
{
.
name
=
"Echoref Pin"
,
.
ops
=
&
skl_pcm_dai_ops
,
.
capture
=
{
.
stream_name
=
"Echoreference Capture"
,
.
channels_min
=
HDA_STEREO
,
.
channels_max
=
HDA_STEREO
,
.
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
,
},
},
{
{
.
name
=
"Reference Pin"
,
.
name
=
"Reference Pin"
,
.
ops
=
&
skl_pcm_dai_ops
,
.
ops
=
&
skl_pcm_dai_ops
,
...
@@ -1194,8 +1220,11 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
...
@@ -1194,8 +1220,11 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
static
int
skl_get_module_info
(
struct
skl
*
skl
,
struct
skl_module_cfg
*
mconfig
)
static
int
skl_get_module_info
(
struct
skl
*
skl
,
struct
skl_module_cfg
*
mconfig
)
{
{
struct
skl_sst
*
ctx
=
skl
->
skl_sst
;
struct
skl_sst
*
ctx
=
skl
->
skl_sst
;
struct
skl_module_inst_id
*
pin_id
;
uuid_le
*
uuid_mod
,
*
uuid_tplg
;
struct
skl_module
*
skl_module
;
struct
uuid_module
*
module
;
struct
uuid_module
*
module
;
uuid_le
*
uuid_mod
;
int
i
,
ret
=
-
EIO
;
uuid_mod
=
(
uuid_le
*
)
mconfig
->
guid
;
uuid_mod
=
(
uuid_le
*
)
mconfig
->
guid
;
...
@@ -1207,12 +1236,45 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
...
@@ -1207,12 +1236,45 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
list_for_each_entry
(
module
,
&
ctx
->
uuid_list
,
list
)
{
list_for_each_entry
(
module
,
&
ctx
->
uuid_list
,
list
)
{
if
(
uuid_le_cmp
(
*
uuid_mod
,
module
->
uuid
)
==
0
)
{
if
(
uuid_le_cmp
(
*
uuid_mod
,
module
->
uuid
)
==
0
)
{
mconfig
->
id
.
module_id
=
module
->
id
;
mconfig
->
id
.
module_id
=
module
->
id
;
mconfig
->
is_loadable
=
module
->
is_loadable
;
if
(
mconfig
->
module
)
return
0
;
mconfig
->
module
->
loadable
=
module
->
is_loadable
;
ret
=
0
;
break
;
}
}
if
(
ret
)
return
ret
;
uuid_mod
=
&
module
->
uuid
;
ret
=
-
EIO
;
for
(
i
=
0
;
i
<
skl
->
nr_modules
;
i
++
)
{
skl_module
=
skl
->
modules
[
i
];
uuid_tplg
=
&
skl_module
->
uuid
;
if
(
!
uuid_le_cmp
(
*
uuid_mod
,
*
uuid_tplg
))
{
mconfig
->
module
=
skl_module
;
ret
=
0
;
break
;
}
}
}
}
if
(
skl
->
nr_modules
&&
ret
)
return
ret
;
return
-
EIO
;
list_for_each_entry
(
module
,
&
ctx
->
uuid_list
,
list
)
{
for
(
i
=
0
;
i
<
MAX_IN_QUEUE
;
i
++
)
{
pin_id
=
&
mconfig
->
m_in_pin
[
i
].
id
;
if
(
!
uuid_le_cmp
(
pin_id
->
mod_uuid
,
module
->
uuid
))
pin_id
->
module_id
=
module
->
id
;
}
for
(
i
=
0
;
i
<
MAX_OUT_QUEUE
;
i
++
)
{
pin_id
=
&
mconfig
->
m_out_pin
[
i
].
id
;
if
(
!
uuid_le_cmp
(
pin_id
->
mod_uuid
,
module
->
uuid
))
pin_id
->
module_id
=
module
->
id
;
}
}
return
0
;
}
}
static
int
skl_populate_modules
(
struct
skl
*
skl
)
static
int
skl_populate_modules
(
struct
skl
*
skl
)
...
@@ -1284,7 +1346,7 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
...
@@ -1284,7 +1346,7 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
return
0
;
return
0
;
}
}
static
struct
snd_soc_platform_driver
skl_platform_drv
=
{
static
const
struct
snd_soc_platform_driver
skl_platform_drv
=
{
.
probe
=
skl_platform_soc_probe
,
.
probe
=
skl_platform_soc_probe
,
.
ops
=
&
skl_platform_ops
,
.
ops
=
&
skl_platform_ops
,
.
pcm_new
=
skl_pcm_new
,
.
pcm_new
=
skl_pcm_new
,
...
...
sound/soc/intel/skylake/skl-sst-dsp.c
浏览文件 @
460f623a
...
@@ -47,7 +47,7 @@ void skl_dsp_init_core_state(struct sst_dsp *ctx)
...
@@ -47,7 +47,7 @@ void skl_dsp_init_core_state(struct sst_dsp *ctx)
skl
->
cores
.
state
[
SKL_DSP_CORE0_ID
]
=
SKL_DSP_RUNNING
;
skl
->
cores
.
state
[
SKL_DSP_CORE0_ID
]
=
SKL_DSP_RUNNING
;
skl
->
cores
.
usage_count
[
SKL_DSP_CORE0_ID
]
=
1
;
skl
->
cores
.
usage_count
[
SKL_DSP_CORE0_ID
]
=
1
;
for
(
i
=
SKL_DSP_CORE0_ID
+
1
;
i
<
SKL_DSP_CORES_MAX
;
i
++
)
{
for
(
i
=
SKL_DSP_CORE0_ID
+
1
;
i
<
skl
->
cores
.
count
;
i
++
)
{
skl
->
cores
.
state
[
i
]
=
SKL_DSP_RESET
;
skl
->
cores
.
state
[
i
]
=
SKL_DSP_RESET
;
skl
->
cores
.
usage_count
[
i
]
=
0
;
skl
->
cores
.
usage_count
[
i
]
=
0
;
}
}
...
@@ -351,6 +351,8 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
...
@@ -351,6 +351,8 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
return
-
EINVAL
;
return
-
EINVAL
;
}
}
skl
->
cores
.
usage_count
[
core_id
]
++
;
if
(
skl
->
cores
.
state
[
core_id
]
==
SKL_DSP_RESET
)
{
if
(
skl
->
cores
.
state
[
core_id
]
==
SKL_DSP_RESET
)
{
ret
=
ctx
->
fw_ops
.
set_state_D0
(
ctx
,
core_id
);
ret
=
ctx
->
fw_ops
.
set_state_D0
(
ctx
,
core_id
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -359,8 +361,6 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
...
@@ -359,8 +361,6 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
}
}
}
}
skl
->
cores
.
usage_count
[
core_id
]
++
;
out:
out:
dev_dbg
(
ctx
->
dev
,
"core id %d state %d usage_count %d
\n
"
,
dev_dbg
(
ctx
->
dev
,
"core id %d state %d usage_count %d
\n
"
,
core_id
,
skl
->
cores
.
state
[
core_id
],
core_id
,
skl
->
cores
.
state
[
core_id
],
...
...
sound/soc/intel/skylake/skl-sst-ipc.c
浏览文件 @
460f623a
...
@@ -283,7 +283,7 @@ enum skl_ipc_module_msg {
...
@@ -283,7 +283,7 @@ enum skl_ipc_module_msg {
IPC_MOD_SET_D0IX
=
8
IPC_MOD_SET_D0IX
=
8
};
};
static
void
skl_ipc_tx_data_copy
(
struct
ipc_message
*
msg
,
char
*
tx_data
,
void
skl_ipc_tx_data_copy
(
struct
ipc_message
*
msg
,
char
*
tx_data
,
size_t
tx_size
)
size_t
tx_size
)
{
{
if
(
tx_size
)
if
(
tx_size
)
...
@@ -347,7 +347,7 @@ static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc,
...
@@ -347,7 +347,7 @@ static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc,
}
}
static
int
skl_ipc_process_notification
(
struct
sst_generic_ipc
*
ipc
,
int
skl_ipc_process_notification
(
struct
sst_generic_ipc
*
ipc
,
struct
skl_ipc_header
header
)
struct
skl_ipc_header
header
)
{
{
struct
skl_sst
*
skl
=
container_of
(
ipc
,
struct
skl_sst
,
ipc
);
struct
skl_sst
*
skl
=
container_of
(
ipc
,
struct
skl_sst
,
ipc
);
...
@@ -406,7 +406,7 @@ static int skl_ipc_set_reply_error_code(u32 reply)
...
@@ -406,7 +406,7 @@ static int skl_ipc_set_reply_error_code(u32 reply)
}
}
}
}
static
void
skl_ipc_process_reply
(
struct
sst_generic_ipc
*
ipc
,
void
skl_ipc_process_reply
(
struct
sst_generic_ipc
*
ipc
,
struct
skl_ipc_header
header
)
struct
skl_ipc_header
header
)
{
{
struct
ipc_message
*
msg
;
struct
ipc_message
*
msg
;
...
...
sound/soc/intel/skylake/skl-sst-ipc.h
浏览文件 @
460f623a
...
@@ -44,12 +44,10 @@ struct skl_ipc_header {
...
@@ -44,12 +44,10 @@ struct skl_ipc_header {
u32
extension
;
u32
extension
;
};
};
#define SKL_DSP_CORES_MAX 2
struct
skl_dsp_cores
{
struct
skl_dsp_cores
{
unsigned
int
count
;
unsigned
int
count
;
enum
skl_dsp_states
state
[
SKL_DSP_CORES_MAX
]
;
enum
skl_dsp_states
*
state
;
int
usage_count
[
SKL_DSP_CORES_MAX
]
;
int
*
usage_count
;
};
};
/**
/**
...
@@ -214,4 +212,10 @@ void skl_ipc_free(struct sst_generic_ipc *ipc);
...
@@ -214,4 +212,10 @@ void skl_ipc_free(struct sst_generic_ipc *ipc);
int
skl_ipc_init
(
struct
device
*
dev
,
struct
skl_sst
*
skl
);
int
skl_ipc_init
(
struct
device
*
dev
,
struct
skl_sst
*
skl
);
void
skl_clear_module_cnt
(
struct
sst_dsp
*
ctx
);
void
skl_clear_module_cnt
(
struct
sst_dsp
*
ctx
);
void
skl_ipc_process_reply
(
struct
sst_generic_ipc
*
ipc
,
struct
skl_ipc_header
header
);
int
skl_ipc_process_notification
(
struct
sst_generic_ipc
*
ipc
,
struct
skl_ipc_header
header
);
void
skl_ipc_tx_data_copy
(
struct
ipc_message
*
msg
,
char
*
tx_data
,
size_t
tx_size
);
#endif
/* __SKL_IPC_H */
#endif
/* __SKL_IPC_H */
sound/soc/intel/skylake/skl-sst-utils.c
浏览文件 @
460f623a
...
@@ -368,7 +368,6 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
...
@@ -368,7 +368,6 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
{
{
struct
skl_sst
*
skl
;
struct
skl_sst
*
skl
;
struct
sst_dsp
*
sst
;
struct
sst_dsp
*
sst
;
int
ret
;
skl
=
devm_kzalloc
(
dev
,
sizeof
(
*
skl
),
GFP_KERNEL
);
skl
=
devm_kzalloc
(
dev
,
sizeof
(
*
skl
),
GFP_KERNEL
);
if
(
skl
==
NULL
)
if
(
skl
==
NULL
)
...
@@ -388,15 +387,12 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
...
@@ -388,15 +387,12 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
sst
->
dsp_ops
=
dsp_ops
;
sst
->
dsp_ops
=
dsp_ops
;
init_waitqueue_head
(
&
skl
->
mod_load_wait
);
init_waitqueue_head
(
&
skl
->
mod_load_wait
);
INIT_LIST_HEAD
(
&
sst
->
module_list
);
INIT_LIST_HEAD
(
&
sst
->
module_list
);
ret
=
skl_ipc_init
(
dev
,
skl
);
if
(
ret
)
return
ret
;
skl
->
is_first_boot
=
true
;
skl
->
is_first_boot
=
true
;
if
(
dsp
)
if
(
dsp
)
*
dsp
=
skl
;
*
dsp
=
skl
;
return
ret
;
return
0
;
}
}
int
skl_prepare_lib_load
(
struct
skl_sst
*
skl
,
struct
skl_lib_info
*
linfo
,
int
skl_prepare_lib_load
(
struct
skl_sst
*
skl
,
struct
skl_lib_info
*
linfo
,
...
...
sound/soc/intel/skylake/skl-sst.c
浏览文件 @
460f623a
...
@@ -503,7 +503,7 @@ static void skl_clear_module_table(struct sst_dsp *ctx)
...
@@ -503,7 +503,7 @@ static void skl_clear_module_table(struct sst_dsp *ctx)
}
}
}
}
static
struct
skl_dsp_fw_ops
skl_fw_ops
=
{
static
const
struct
skl_dsp_fw_ops
skl_fw_ops
=
{
.
set_state_D0
=
skl_set_dsp_D0
,
.
set_state_D0
=
skl_set_dsp_D0
,
.
set_state_D3
=
skl_set_dsp_D3
,
.
set_state_D3
=
skl_set_dsp_D3
,
.
load_fw
=
skl_load_base_firmware
,
.
load_fw
=
skl_load_base_firmware
,
...
@@ -512,7 +512,7 @@ static struct skl_dsp_fw_ops skl_fw_ops = {
...
@@ -512,7 +512,7 @@ static struct skl_dsp_fw_ops skl_fw_ops = {
.
unload_mod
=
skl_unload_module
,
.
unload_mod
=
skl_unload_module
,
};
};
static
struct
skl_dsp_fw_ops
kbl_fw_ops
=
{
static
const
struct
skl_dsp_fw_ops
kbl_fw_ops
=
{
.
set_state_D0
=
skl_set_dsp_D0
,
.
set_state_D0
=
skl_set_dsp_D0
,
.
set_state_D3
=
skl_set_dsp_D3
,
.
set_state_D3
=
skl_set_dsp_D3
,
.
load_fw
=
skl_load_base_firmware
,
.
load_fw
=
skl_load_base_firmware
,
...
@@ -561,9 +561,13 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
...
@@ -561,9 +561,13 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
sst_dsp_mailbox_init
(
sst
,
(
SKL_ADSP_SRAM0_BASE
+
SKL_ADSP_W0_STAT_SZ
),
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
);
SKL_ADSP_W0_UP_SZ
,
SKL_ADSP_SRAM1_BASE
,
SKL_ADSP_W1_SZ
);
sst
->
fw_ops
=
skl_fw_ops
;
ret
=
skl_ipc_init
(
dev
,
skl
);
if
(
ret
)
{
skl_dsp_free
(
sst
);
return
ret
;
}
s
kl
->
cores
.
count
=
2
;
s
st
->
fw_ops
=
skl_fw_ops
;
return
0
;
return
0
;
}
}
...
...
sound/soc/intel/skylake/skl-topology.c
浏览文件 @
460f623a
此差异已折叠。
点击以展开。
sound/soc/intel/skylake/skl-topology.h
浏览文件 @
460f623a
...
@@ -44,6 +44,13 @@
...
@@ -44,6 +44,13 @@
#define SKL_DEFAULT_MIC_SEL_GAIN 0x3FF
#define SKL_DEFAULT_MIC_SEL_GAIN 0x3FF
#define SKL_MIC_SEL_SWITCH 0x3
#define SKL_MIC_SEL_SWITCH 0x3
#define SKL_OUTPUT_PIN 0
#define SKL_INPUT_PIN 1
#define SKL_MAX_PATH_CONFIGS 8
#define SKL_MAX_MODULES_IN_PIPE 8
#define SKL_MAX_MODULE_FORMATS 32
#define SKL_MAX_MODULE_RESOURCES 32
enum
skl_channel_index
{
enum
skl_channel_index
{
SKL_CHANNEL_LEFT
=
0
,
SKL_CHANNEL_LEFT
=
0
,
SKL_CHANNEL_RIGHT
=
1
,
SKL_CHANNEL_RIGHT
=
1
,
...
@@ -131,6 +138,11 @@ struct skl_cpr_cfg {
...
@@ -131,6 +138,11 @@ struct skl_cpr_cfg {
struct
skl_cpr_gtw_cfg
gtw_cfg
;
struct
skl_cpr_gtw_cfg
gtw_cfg
;
}
__packed
;
}
__packed
;
struct
skl_cpr_pin_fmt
{
u32
sink_id
;
struct
skl_audio_data_format
src_fmt
;
struct
skl_audio_data_format
dst_fmt
;
}
__packed
;
struct
skl_src_module_cfg
{
struct
skl_src_module_cfg
{
struct
skl_base_cfg
base_cfg
;
struct
skl_base_cfg
base_cfg
;
...
@@ -214,6 +226,7 @@ struct skl_kpb_params {
...
@@ -214,6 +226,7 @@ struct skl_kpb_params {
};
};
struct
skl_module_inst_id
{
struct
skl_module_inst_id
{
uuid_le
mod_uuid
;
int
module_id
;
int
module_id
;
u32
instance_id
;
u32
instance_id
;
int
pvt_id
;
int
pvt_id
;
...
@@ -266,6 +279,23 @@ struct skl_pipe_params {
...
@@ -266,6 +279,23 @@ struct skl_pipe_params {
unsigned
int
link_bps
;
unsigned
int
link_bps
;
};
};
struct
skl_pipe_fmt
{
u32
freq
;
u8
channels
;
u8
bps
;
};
struct
skl_pipe_mcfg
{
u8
res_idx
;
u8
fmt_idx
;
};
struct
skl_path_config
{
u8
mem_pages
;
struct
skl_pipe_fmt
in_fmt
;
struct
skl_pipe_fmt
out_fmt
;
};
struct
skl_pipe
{
struct
skl_pipe
{
u8
ppl_id
;
u8
ppl_id
;
u8
pipe_priority
;
u8
pipe_priority
;
...
@@ -274,6 +304,10 @@ struct skl_pipe {
...
@@ -274,6 +304,10 @@ struct skl_pipe {
u8
lp_mode
;
u8
lp_mode
;
struct
skl_pipe_params
*
p_params
;
struct
skl_pipe_params
*
p_params
;
enum
skl_pipe_state
state
;
enum
skl_pipe_state
state
;
u8
direction
;
u8
cur_config_idx
;
u8
nr_cfgs
;
struct
skl_path_config
configs
[
SKL_MAX_PATH_CONFIGS
];
struct
list_head
w_list
;
struct
list_head
w_list
;
bool
passthru
;
bool
passthru
;
};
};
...
@@ -292,9 +326,57 @@ enum d0i3_capability {
...
@@ -292,9 +326,57 @@ enum d0i3_capability {
SKL_D0I3_NON_STREAMING
=
2
,
SKL_D0I3_NON_STREAMING
=
2
,
};
};
struct
skl_module_pin_fmt
{
u8
id
;
struct
skl_module_fmt
fmt
;
};
struct
skl_module_iface
{
u8
fmt_idx
;
u8
nr_in_fmt
;
u8
nr_out_fmt
;
struct
skl_module_pin_fmt
inputs
[
MAX_IN_QUEUE
];
struct
skl_module_pin_fmt
outputs
[
MAX_OUT_QUEUE
];
};
struct
skl_module_pin_resources
{
u8
pin_index
;
u32
buf_size
;
};
struct
skl_module_res
{
u8
id
;
u32
is_pages
;
u32
cps
;
u32
ibs
;
u32
obs
;
u32
dma_buffer_size
;
u32
cpc
;
u8
nr_input_pins
;
u8
nr_output_pins
;
struct
skl_module_pin_resources
input
[
MAX_IN_QUEUE
];
struct
skl_module_pin_resources
output
[
MAX_OUT_QUEUE
];
};
struct
skl_module
{
uuid_le
uuid
;
u8
loadable
;
u8
input_pin_type
;
u8
output_pin_type
;
u8
max_input_pins
;
u8
max_output_pins
;
u8
nr_resources
;
u8
nr_interfaces
;
struct
skl_module_res
resources
[
SKL_MAX_MODULE_RESOURCES
];
struct
skl_module_iface
formats
[
SKL_MAX_MODULE_FORMATS
];
};
struct
skl_module_cfg
{
struct
skl_module_cfg
{
u8
guid
[
16
];
u8
guid
[
16
];
struct
skl_module_inst_id
id
;
struct
skl_module_inst_id
id
;
struct
skl_module
*
module
;
int
res_idx
;
int
fmt_idx
;
u8
domain
;
u8
domain
;
bool
homogenous_inputs
;
bool
homogenous_inputs
;
bool
homogenous_outputs
;
bool
homogenous_outputs
;
...
@@ -329,6 +411,7 @@ struct skl_module_cfg {
...
@@ -329,6 +411,7 @@ struct skl_module_cfg {
enum
skl_module_state
m_state
;
enum
skl_module_state
m_state
;
struct
skl_pipe
*
pipe
;
struct
skl_pipe
*
pipe
;
struct
skl_specific_cfg
formats_config
;
struct
skl_specific_cfg
formats_config
;
struct
skl_pipe_mcfg
mod_cfg
[
SKL_MAX_MODULES_IN_PIPE
];
};
};
struct
skl_algo_data
{
struct
skl_algo_data
{
...
...
sound/soc/intel/skylake/skl.c
浏览文件 @
460f623a
...
@@ -415,7 +415,7 @@ static int skl_free(struct hdac_ext_bus *ebus)
...
@@ -415,7 +415,7 @@ static int skl_free(struct hdac_ext_bus *ebus)
snd_hdac_ext_stop_streams
(
ebus
);
snd_hdac_ext_stop_streams
(
ebus
);
if
(
bus
->
irq
>=
0
)
if
(
bus
->
irq
>=
0
)
free_irq
(
bus
->
irq
,
(
void
*
)
bus
);
free_irq
(
bus
->
irq
,
(
void
*
)
e
bus
);
snd_hdac_bus_free_stream_pages
(
bus
);
snd_hdac_bus_free_stream_pages
(
bus
);
snd_hdac_stream_free_all
(
ebus
);
snd_hdac_stream_free_all
(
ebus
);
snd_hdac_link_free_all
(
ebus
);
snd_hdac_link_free_all
(
ebus
);
...
@@ -528,7 +528,7 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr)
...
@@ -528,7 +528,7 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr)
}
}
/* Codec initialization */
/* Codec initialization */
static
int
skl_codec_create
(
struct
hdac_ext_bus
*
ebus
)
static
void
skl_codec_create
(
struct
hdac_ext_bus
*
ebus
)
{
{
struct
hdac_bus
*
bus
=
ebus_to_hbus
(
ebus
);
struct
hdac_bus
*
bus
=
ebus_to_hbus
(
ebus
);
int
c
,
max_slots
;
int
c
,
max_slots
;
...
@@ -559,8 +559,6 @@ static int skl_codec_create(struct hdac_ext_bus *ebus)
...
@@ -559,8 +559,6 @@ static int skl_codec_create(struct hdac_ext_bus *ebus)
}
}
}
}
}
}
return
0
;
}
}
static
const
struct
hdac_bus_ops
bus_core_ops
=
{
static
const
struct
hdac_bus_ops
bus_core_ops
=
{
...
@@ -612,9 +610,7 @@ static void skl_probe_work(struct work_struct *work)
...
@@ -612,9 +610,7 @@ static void skl_probe_work(struct work_struct *work)
dev_info
(
bus
->
dev
,
"no hda codecs found!
\n
"
);
dev_info
(
bus
->
dev
,
"no hda codecs found!
\n
"
);
/* create codec instances */
/* create codec instances */
err
=
skl_codec_create
(
ebus
);
skl_codec_create
(
ebus
);
if
(
err
<
0
)
goto
out_err
;
if
(
IS_ENABLED
(
CONFIG_SND_SOC_HDAC_HDMI
))
{
if
(
IS_ENABLED
(
CONFIG_SND_SOC_HDAC_HDMI
))
{
err
=
snd_hdac_display_power
(
bus
,
false
);
err
=
snd_hdac_display_power
(
bus
,
false
);
...
@@ -702,6 +698,8 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
...
@@ -702,6 +698,8 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
return
-
ENXIO
;
return
-
ENXIO
;
}
}
skl_init_chip
(
bus
,
true
);
snd_hdac_bus_parse_capabilities
(
bus
);
snd_hdac_bus_parse_capabilities
(
bus
);
if
(
skl_acquire_irq
(
ebus
,
0
)
<
0
)
if
(
skl_acquire_irq
(
ebus
,
0
)
<
0
)
...
@@ -982,6 +980,11 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
...
@@ -982,6 +980,11 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
.
quirk_data
=
&
kbl_poppy_codecs
,
.
quirk_data
=
&
kbl_poppy_codecs
,
.
pdata
=
&
skl_dmic_data
.
pdata
=
&
skl_dmic_data
},
},
{
.
id
=
"10EC5663"
,
.
drv_name
=
"kbl_rt5663"
,
.
fw_filename
=
"intel/dsp_fw_kbl.bin"
,
},
{}
{}
};
};
...
@@ -995,6 +998,14 @@ static struct sst_acpi_mach sst_glk_devdata[] = {
...
@@ -995,6 +998,14 @@ static struct sst_acpi_mach sst_glk_devdata[] = {
{}
{}
};
};
static
const
struct
sst_acpi_mach
sst_cnl_devdata
[]
=
{
{
.
id
=
"INT34C2"
,
.
drv_name
=
"cnl_rt274"
,
.
fw_filename
=
"intel/dsp_fw_cnl.bin"
,
},
};
/* PCI IDs */
/* PCI IDs */
static
const
struct
pci_device_id
skl_ids
[]
=
{
static
const
struct
pci_device_id
skl_ids
[]
=
{
/* Sunrise Point-LP */
/* Sunrise Point-LP */
...
@@ -1009,6 +1020,9 @@ static const struct pci_device_id skl_ids[] = {
...
@@ -1009,6 +1020,9 @@ static const struct pci_device_id skl_ids[] = {
/* GLK */
/* GLK */
{
PCI_DEVICE
(
0x8086
,
0x3198
),
{
PCI_DEVICE
(
0x8086
,
0x3198
),
.
driver_data
=
(
unsigned
long
)
&
sst_glk_devdata
},
.
driver_data
=
(
unsigned
long
)
&
sst_glk_devdata
},
/* CNL */
{
PCI_DEVICE
(
0x8086
,
0x9dc8
),
.
driver_data
=
(
unsigned
long
)
&
sst_cnl_devdata
},
{
0
,
}
{
0
,
}
};
};
MODULE_DEVICE_TABLE
(
pci
,
skl_ids
);
MODULE_DEVICE_TABLE
(
pci
,
skl_ids
);
...
...
sound/soc/intel/skylake/skl.h
浏览文件 @
460f623a
...
@@ -71,6 +71,8 @@ struct skl {
...
@@ -71,6 +71,8 @@ struct skl {
struct
work_struct
probe_work
;
struct
work_struct
probe_work
;
struct
skl_debug
*
debugfs
;
struct
skl_debug
*
debugfs
;
u8
nr_modules
;
struct
skl_module
**
modules
;
};
};
#define skl_to_ebus(s) (&(s)->ebus)
#define skl_to_ebus(s) (&(s)->ebus)
...
@@ -90,6 +92,7 @@ struct skl_machine_pdata {
...
@@ -90,6 +92,7 @@ struct skl_machine_pdata {
struct
skl_dsp_ops
{
struct
skl_dsp_ops
{
int
id
;
int
id
;
unsigned
int
num_cores
;
struct
skl_dsp_loader_ops
(
*
loader_ops
)(
void
);
struct
skl_dsp_loader_ops
(
*
loader_ops
)(
void
);
int
(
*
init
)(
struct
device
*
dev
,
void
__iomem
*
mmio_base
,
int
(
*
init
)(
struct
device
*
dev
,
void
__iomem
*
mmio_base
,
int
irq
,
const
char
*
fw_name
,
int
irq
,
const
char
*
fw_name
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录