Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
51fa6a8f
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看板
提交
51fa6a8f
编写于
7月 03, 2017
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
上级
9a532f05
bdd0384a
变更
38
隐藏空白更改
内联
并排
Showing
38 changed file
with
2817 addition
and
264 deletion
+2817
-264
include/uapi/sound/snd_sst_tokens.h
include/uapi/sound/snd_sst_tokens.h
+6
-2
sound/soc/codecs/rt5670.c
sound/soc/codecs/rt5670.c
+9
-0
sound/soc/codecs/rt5677.c
sound/soc/codecs/rt5677.c
+7
-25
sound/soc/intel/Kconfig
sound/soc/intel/Kconfig
+42
-0
sound/soc/intel/atom/sst-mfld-platform-pcm.c
sound/soc/intel/atom/sst-mfld-platform-pcm.c
+1
-1
sound/soc/intel/atom/sst/sst.c
sound/soc/intel/atom/sst/sst.c
+12
-47
sound/soc/intel/atom/sst/sst.h
sound/soc/intel/atom/sst/sst.h
+4
-26
sound/soc/intel/atom/sst/sst_acpi.c
sound/soc/intel/atom/sst/sst_acpi.c
+169
-63
sound/soc/intel/boards/Makefile
sound/soc/intel/boards/Makefile
+6
-0
sound/soc/intel/boards/bdw-rt5677.c
sound/soc/intel/boards/bdw-rt5677.c
+26
-0
sound/soc/intel/boards/bxt_da7219_max98357a.c
sound/soc/intel/boards/bxt_da7219_max98357a.c
+6
-6
sound/soc/intel/boards/bxt_rt298.c
sound/soc/intel/boards/bxt_rt298.c
+8
-11
sound/soc/intel/boards/byt-max98090.c
sound/soc/intel/boards/byt-max98090.c
+18
-6
sound/soc/intel/boards/bytcht_es8316.c
sound/soc/intel/boards/bytcht_es8316.c
+300
-0
sound/soc/intel/boards/bytcht_nocodec.c
sound/soc/intel/boards/bytcht_nocodec.c
+2
-2
sound/soc/intel/boards/bytcr_rt5651.c
sound/soc/intel/boards/bytcr_rt5651.c
+2
-2
sound/soc/intel/boards/cht_bsw_max98090_ti.c
sound/soc/intel/boards/cht_bsw_max98090_ti.c
+0
-12
sound/soc/intel/boards/cht_bsw_rt5672.c
sound/soc/intel/boards/cht_bsw_rt5672.c
+80
-9
sound/soc/intel/boards/kbl_rt5663_max98927.c
sound/soc/intel/boards/kbl_rt5663_max98927.c
+687
-0
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+640
-0
sound/soc/intel/boards/skl_nau88l25_max98357a.c
sound/soc/intel/boards/skl_nau88l25_max98357a.c
+8
-8
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+8
-8
sound/soc/intel/boards/skl_rt286.c
sound/soc/intel/boards/skl_rt286.c
+24
-6
sound/soc/intel/common/sst-acpi.h
sound/soc/intel/common/sst-acpi.h
+23
-0
sound/soc/intel/common/sst-dsp-priv.h
sound/soc/intel/common/sst-dsp-priv.h
+4
-0
sound/soc/intel/common/sst-match-acpi.c
sound/soc/intel/common/sst-match-acpi.c
+41
-6
sound/soc/intel/skylake/Makefile
sound/soc/intel/skylake/Makefile
+4
-0
sound/soc/intel/skylake/bxt-sst.c
sound/soc/intel/skylake/bxt-sst.c
+4
-0
sound/soc/intel/skylake/skl-debug.c
sound/soc/intel/skylake/skl-debug.c
+268
-0
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl-messages.c
+27
-4
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-pcm.c
+5
-1
sound/soc/intel/skylake/skl-sst.c
sound/soc/intel/skylake/skl-sst.c
+5
-0
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl-topology.c
+183
-4
sound/soc/intel/skylake/skl-topology.h
sound/soc/intel/skylake/skl-topology.h
+21
-0
sound/soc/intel/skylake/skl-tplg-interface.h
sound/soc/intel/skylake/skl-tplg-interface.h
+2
-0
sound/soc/intel/skylake/skl.c
sound/soc/intel/skylake/skl.c
+104
-11
sound/soc/intel/skylake/skl.h
sound/soc/intel/skylake/skl.h
+26
-0
sound/soc/soc-core.c
sound/soc/soc-core.c
+35
-4
未找到文件。
include/uapi/sound/snd_sst_tokens.h
浏览文件 @
51fa6a8f
...
...
@@ -161,6 +161,8 @@
*
* %SKL_TKL_U32_D0I3_CAPS: Specifies the D0i3 capability for module
*
* %SKL_TKN_U32_DMA_BUF_SIZE: DMA buffer size in millisec
*
* module_id and loadable flags dont have tokens as these values will be
* read from the DSP FW manifest
*/
...
...
@@ -213,8 +215,10 @@ enum SKL_TKNS {
SKL_TKN_U32_LIB_COUNT
,
SKL_TKN_STR_LIB_NAME
,
SKL_TKN_U32_PMODE
,
SKL_TKL_U32_D0I3_CAPS
,
SKL_TKN_MAX
=
SKL_TKL_U32_D0I3_CAPS
,
SKL_TKL_U32_D0I3_CAPS
,
/* Typo added at v4.10 */
SKL_TKN_U32_D0I3_CAPS
=
SKL_TKL_U32_D0I3_CAPS
,
SKL_TKN_U32_DMA_BUF_SIZE
,
SKL_TKN_MAX
=
SKL_TKN_U32_DMA_BUF_SIZE
,
};
#endif
sound/soc/codecs/rt5670.c
浏览文件 @
51fa6a8f
...
...
@@ -2848,6 +2848,10 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
DMI_MATCH
(
DMI_PRODUCT_VERSION
,
"ThinkPad Tablet B"
),
},
},
{}
};
static
const
struct
dmi_system_id
dmi_platform_intel_bytcht_jdmode2
[]
=
{
{
.
ident
=
"Lenovo Thinkpad Tablet 10"
,
.
matches
=
{
...
...
@@ -2882,6 +2886,11 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
rt5670
->
pdata
.
dmic1_data_pin
=
RT5670_DMIC_DATA_IN2P
;
rt5670
->
pdata
.
dev_gpio
=
true
;
rt5670
->
pdata
.
jd_mode
=
1
;
}
else
if
(
dmi_check_system
(
dmi_platform_intel_bytcht_jdmode2
))
{
rt5670
->
pdata
.
dmic_en
=
true
;
rt5670
->
pdata
.
dmic1_data_pin
=
RT5670_DMIC_DATA_IN2P
;
rt5670
->
pdata
.
dev_gpio
=
true
;
rt5670
->
pdata
.
jd_mode
=
2
;
}
rt5670
->
regmap
=
devm_regmap_init_i2c
(
i2c
,
&
rt5670_regmap
);
...
...
sound/soc/codecs/rt5677.c
浏览文件 @
51fa6a8f
...
...
@@ -41,15 +41,6 @@
#define RT5677_PR_BASE (RT5677_PR_RANGE_BASE + (0 * RT5677_PR_SPACING))
/* GPIO indexes defined by ACPI */
enum
{
RT5677_GPIO_PLUG_DET
=
0
,
RT5677_GPIO_MIC_PRESENT_L
=
1
,
RT5677_GPIO_HOTWORD_DET_L
=
2
,
RT5677_GPIO_DSP_INT
=
3
,
RT5677_GPIO_HP_AMP_SHDN_L
=
4
,
};
static
const
struct
regmap_range_cfg
rt5677_ranges
[]
=
{
{
.
name
=
"PR"
,
...
...
@@ -5030,7 +5021,6 @@ static const struct regmap_config rt5677_regmap = {
static
const
struct
i2c_device_id
rt5677_i2c_id
[]
=
{
{
"rt5677"
,
RT5677
},
{
"rt5676"
,
RT5676
},
{
"RT5677CE:00"
,
RT5677
},
{
}
};
MODULE_DEVICE_TABLE
(
i2c
,
rt5677_i2c_id
);
...
...
@@ -5041,28 +5031,19 @@ static const struct of_device_id rt5677_of_match[] = {
};
MODULE_DEVICE_TABLE
(
of
,
rt5677_of_match
);
static
const
struct
acpi_gpio_params
plug_det_gpio
=
{
RT5677_GPIO_PLUG_DET
,
0
,
false
};
static
const
struct
acpi_gpio_params
mic_present_gpio
=
{
RT5677_GPIO_MIC_PRESENT_L
,
0
,
false
};
static
const
struct
acpi_gpio_params
headphone_enable_gpio
=
{
RT5677_GPIO_HP_AMP_SHDN_L
,
0
,
false
};
static
const
struct
acpi_gpio_mapping
bdw_rt5677_gpios
[]
=
{
{
"plug-det-gpios"
,
&
plug_det_gpio
,
1
},
{
"mic-present-gpios"
,
&
mic_present_gpio
,
1
},
{
"headphone-enable-gpios"
,
&
headphone_enable_gpio
,
1
},
{
NULL
},
#ifdef CONFIG_ACPI
static
const
struct
acpi_device_id
rt5677_acpi_match
[]
=
{
{
"RT5677CE"
,
RT5677
},
{
}
};
MODULE_DEVICE_TABLE
(
acpi
,
rt5677_acpi_match
);
#endif
static
void
rt5677_read_acpi_properties
(
struct
rt5677_priv
*
rt5677
,
struct
device
*
dev
)
{
int
ret
;
u32
val
;
ret
=
acpi_dev_add_driver_gpios
(
ACPI_COMPANION
(
dev
),
bdw_rt5677_gpios
);
if
(
ret
)
dev_warn
(
dev
,
"Failed to add driver gpios
\n
"
);
if
(
!
device_property_read_u32
(
dev
,
"DCLK"
,
&
val
))
rt5677
->
pdata
.
dmic2_clk_pin
=
val
;
...
...
@@ -5301,6 +5282,7 @@ static struct i2c_driver rt5677_i2c_driver = {
.
driver
=
{
.
name
=
"rt5677"
,
.
of_match_table
=
rt5677_of_match
,
.
acpi_match_table
=
ACPI_PTR
(
rt5677_acpi_match
),
},
.
probe
=
rt5677_i2c_probe
,
.
remove
=
rt5677_i2c_remove
,
...
...
sound/soc/intel/Kconfig
浏览文件 @
51fa6a8f
...
...
@@ -214,6 +214,18 @@ config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
platforms with DA7212/7213 audio codec.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_ES8316_MACH
tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with ES8316 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SOC_ES8316
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help
This adds support for ASoC machine driver for Intel(R) Baytrail &
Cherrytrail platforms with ES8316 audio codec.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH
tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail platform with no codec (MinnowBoard MAX, Up)"
depends on X86_INTEL_LPSS && I2C && ACPI
...
...
@@ -226,6 +238,36 @@ config SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH
connector
If unsure select "N".
config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH
tristate "ASoC Audio driver for KBL with RT5663 and MAX98927 in I2S Mode"
depends on X86_INTEL_LPSS && I2C
select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SKYLAKE
select SND_SOC_RT5663
select SND_SOC_MAX98927
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for RT5663 + MAX98927.
Say Y if you have such a device.
If unsure select "N".
config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH
tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode"
depends on X86_INTEL_LPSS && I2C
select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SKYLAKE
select SND_SOC_RT5663
select SND_SOC_RT5514
select SND_SOC_MAX98927
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for RT5663 + RT5514 + MAX98927.
Say Y if you have such a device.
If unsure select "N".
config SND_SOC_INTEL_SKYLAKE
tristate
select SND_HDA_EXT_CORE
...
...
sound/soc/intel/atom/sst-mfld-platform-pcm.c
浏览文件 @
51fa6a8f
...
...
@@ -690,7 +690,7 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
snd_dma_continuous_data
(
GFP_DMA
),
SST_MIN_BUFFER
,
SST_MAX_BUFFER
);
if
(
retval
)
{
dev_err
(
rtd
->
dev
,
"dma buffer allocation
f fail
\n
"
);
dev_err
(
rtd
->
dev
,
"dma buffer allocation
failure
\n
"
);
return
retval
;
}
}
...
...
sound/soc/intel/atom/sst/sst.c
浏览文件 @
51fa6a8f
...
...
@@ -258,7 +258,7 @@ static ssize_t firmware_version_show(struct device *dev,
}
DEVICE_ATTR_RO
(
firmware_version
);
static
DEVICE_ATTR_RO
(
firmware_version
);
static
const
struct
attribute
*
sst_fw_version_attrs
[]
=
{
&
dev_attr_firmware_version
.
attr
,
...
...
@@ -382,37 +382,6 @@ void sst_context_cleanup(struct intel_sst_drv *ctx)
}
EXPORT_SYMBOL_GPL
(
sst_context_cleanup
);
static
inline
void
sst_save_shim64
(
struct
intel_sst_drv
*
ctx
,
void
__iomem
*
shim
,
struct
sst_shim_regs64
*
shim_regs
)
{
unsigned
long
irq_flags
;
spin_lock_irqsave
(
&
ctx
->
ipc_spin_lock
,
irq_flags
);
shim_regs
->
imrx
=
sst_shim_read64
(
shim
,
SST_IMRX
);
shim_regs
->
csr
=
sst_shim_read64
(
shim
,
SST_CSR
);
spin_unlock_irqrestore
(
&
ctx
->
ipc_spin_lock
,
irq_flags
);
}
static
inline
void
sst_restore_shim64
(
struct
intel_sst_drv
*
ctx
,
void
__iomem
*
shim
,
struct
sst_shim_regs64
*
shim_regs
)
{
unsigned
long
irq_flags
;
/*
* we only need to restore IMRX for this case, rest will be
* initialize by FW or driver when firmware is loaded
*/
spin_lock_irqsave
(
&
ctx
->
ipc_spin_lock
,
irq_flags
);
sst_shim_write64
(
shim
,
SST_IMRX
,
shim_regs
->
imrx
);
sst_shim_write64
(
shim
,
SST_CSR
,
shim_regs
->
csr
);
spin_unlock_irqrestore
(
&
ctx
->
ipc_spin_lock
,
irq_flags
);
}
void
sst_configure_runtime_pm
(
struct
intel_sst_drv
*
ctx
)
{
pm_runtime_set_autosuspend_delay
(
ctx
->
dev
,
SST_SUSPEND_DELAY
);
...
...
@@ -432,8 +401,6 @@ void sst_configure_runtime_pm(struct intel_sst_drv *ctx)
pm_runtime_set_active
(
ctx
->
dev
);
else
pm_runtime_put_noidle
(
ctx
->
dev
);
sst_save_shim64
(
ctx
,
ctx
->
shim
,
ctx
->
shim_regs64
);
}
EXPORT_SYMBOL_GPL
(
sst_configure_runtime_pm
);
...
...
@@ -457,8 +424,6 @@ static int intel_sst_runtime_suspend(struct device *dev)
flush_workqueue
(
ctx
->
post_msg_wq
);
ctx
->
ops
->
reset
(
ctx
);
/* save the shim registers because PMC doesn't save state */
sst_save_shim64
(
ctx
,
ctx
->
shim
,
ctx
->
shim_regs64
);
return
ret
;
}
...
...
@@ -499,23 +464,23 @@ static int intel_sst_suspend(struct device *dev)
fw_save
=
kzalloc
(
sizeof
(
*
fw_save
),
GFP_KERNEL
);
if
(
!
fw_save
)
return
-
ENOMEM
;
fw_save
->
iram
=
kzalloc
(
ctx
->
iram_end
-
ctx
->
iram_base
,
GFP_KERNEL
);
fw_save
->
iram
=
k
v
zalloc
(
ctx
->
iram_end
-
ctx
->
iram_base
,
GFP_KERNEL
);
if
(
!
fw_save
->
iram
)
{
ret
=
-
ENOMEM
;
goto
iram
;
}
fw_save
->
dram
=
kzalloc
(
ctx
->
dram_end
-
ctx
->
dram_base
,
GFP_KERNEL
);
fw_save
->
dram
=
k
v
zalloc
(
ctx
->
dram_end
-
ctx
->
dram_base
,
GFP_KERNEL
);
if
(
!
fw_save
->
dram
)
{
ret
=
-
ENOMEM
;
goto
dram
;
}
fw_save
->
sram
=
kzalloc
(
SST_MAILBOX_SIZE
,
GFP_KERNEL
);
fw_save
->
sram
=
k
v
zalloc
(
SST_MAILBOX_SIZE
,
GFP_KERNEL
);
if
(
!
fw_save
->
sram
)
{
ret
=
-
ENOMEM
;
goto
sram
;
}
fw_save
->
ddr
=
kzalloc
(
ctx
->
ddr_end
-
ctx
->
ddr_base
,
GFP_KERNEL
);
fw_save
->
ddr
=
k
v
zalloc
(
ctx
->
ddr_end
-
ctx
->
ddr_base
,
GFP_KERNEL
);
if
(
!
fw_save
->
ddr
)
{
ret
=
-
ENOMEM
;
goto
ddr
;
...
...
@@ -530,11 +495,11 @@ static int intel_sst_suspend(struct device *dev)
ctx
->
ops
->
reset
(
ctx
);
return
0
;
ddr:
kfree
(
fw_save
->
sram
);
k
v
free
(
fw_save
->
sram
);
sram:
kfree
(
fw_save
->
dram
);
k
v
free
(
fw_save
->
dram
);
dram:
kfree
(
fw_save
->
iram
);
k
v
free
(
fw_save
->
iram
);
iram:
kfree
(
fw_save
);
return
ret
;
...
...
@@ -562,10 +527,10 @@ static int intel_sst_resume(struct device *dev)
memcpy32_toio
(
ctx
->
mailbox
,
fw_save
->
sram
,
SST_MAILBOX_SIZE
);
memcpy32_toio
(
ctx
->
ddr
,
fw_save
->
ddr
,
ctx
->
ddr_end
-
ctx
->
ddr_base
);
kfree
(
fw_save
->
sram
);
kfree
(
fw_save
->
dram
);
kfree
(
fw_save
->
iram
);
kfree
(
fw_save
->
ddr
);
k
v
free
(
fw_save
->
sram
);
k
v
free
(
fw_save
->
dram
);
k
v
free
(
fw_save
->
iram
);
k
v
free
(
fw_save
->
ddr
);
kfree
(
fw_save
);
block
=
sst_create_block
(
ctx
,
0
,
FW_DWNL_ID
);
...
...
sound/soc/intel/atom/sst/sst.h
浏览文件 @
51fa6a8f
...
...
@@ -317,31 +317,11 @@ struct sst_ipc_reg {
int
ipcd
;
};
struct
sst_shim_regs64
{
u64
csr
;
u64
pisr
;
u64
pimr
;
u64
isrx
;
u64
isrd
;
u64
imrx
;
u64
imrd
;
u64
ipcx
;
u64
ipcd
;
u64
isrsc
;
u64
isrlpesc
;
u64
imrsc
;
u64
imrlpesc
;
u64
ipcsc
;
u64
ipclpesc
;
u64
clkctl
;
u64
csr2
;
};
struct
sst_fw_save
{
void
*
iram
;
void
*
dram
;
void
*
sram
;
void
*
ddr
;
void
*
iram
;
/* allocated via kvmalloc() */
void
*
dram
;
/* allocated via kvmalloc() */
void
*
sram
;
/* allocated via kvmalloc() */
void
*
ddr
;
/* allocated via kvmalloc() */
};
/**
...
...
@@ -356,7 +336,6 @@ struct sst_fw_save {
* @dram : SST DRAM pointer
* @pdata : SST info passed as a part of pci platform data
* @shim_phy_add : SST shim phy addr
* @shim_regs64: Struct to save shim registers
* @ipc_dispatch_list : ipc messages dispatched
* @rx_list : to copy the process_reply/process_msg from DSP
* @ipc_post_msg_wq : wq to post IPC messages context
...
...
@@ -398,7 +377,6 @@ struct intel_sst_drv {
unsigned
int
ddr_end
;
unsigned
int
ddr_base
;
unsigned
int
mailbox_recv_offset
;
struct
sst_shim_regs64
*
shim_regs64
;
struct
list_head
block_list
;
struct
list_head
ipc_dispatch_list
;
struct
sst_platform_info
*
pdata
;
...
...
sound/soc/intel/atom/sst/sst_acpi.c
浏览文件 @
51fa6a8f
...
...
@@ -303,8 +303,6 @@ static int sst_acpi_probe(struct platform_device *pdev)
dev_err
(
dev
,
"No matching machine driver found
\n
"
);
return
-
ENODEV
;
}
if
(
mach
->
machine_quirk
)
mach
=
mach
->
machine_quirk
(
mach
);
pdata
=
mach
->
pdata
;
...
...
@@ -360,23 +358,9 @@ static int sst_acpi_probe(struct platform_device *pdev)
if
(
ret
<
0
)
return
ret
;
/* need to save shim registers in BYT */
ctx
->
shim_regs64
=
devm_kzalloc
(
ctx
->
dev
,
sizeof
(
*
ctx
->
shim_regs64
),
GFP_KERNEL
);
if
(
!
ctx
->
shim_regs64
)
{
ret
=
-
ENOMEM
;
goto
do_sst_cleanup
;
}
sst_configure_runtime_pm
(
ctx
);
platform_set_drvdata
(
pdev
,
ctx
);
return
ret
;
do_sst_cleanup:
sst_context_cleanup
(
ctx
);
platform_set_drvdata
(
pdev
,
NULL
);
dev_err
(
ctx
->
dev
,
"failed with %d
\n
"
,
ret
);
return
ret
;
}
/**
...
...
@@ -453,12 +437,20 @@ static const struct dmi_system_id cht_table[] = {
static
struct
sst_acpi_mach
cht_surface_mach
=
{
"10EC5640"
,
"cht-bsw-rt5645"
,
"intel/fw_sst_22a8.bin"
,
"cht-bsw"
,
NULL
,
&
chv_platform_data
};
.
id
=
"10EC5640"
,
.
drv_name
=
"cht-bsw-rt5645"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"cht-bsw"
,
.
pdata
=
&
chv_platform_data
,
};
static
struct
sst_acpi_mach
byt_thinkpad_10
=
{
"10EC5640"
,
"cht-bsw-rt5672"
,
"intel/fw_sst_0f28.bin"
,
"cht-bsw"
,
NULL
,
&
byt_rvp_platform_data
};
.
id
=
"10EC5640"
,
.
drv_name
=
"cht-bsw-rt5672"
,
.
fw_filename
=
"intel/fw_sst_0f28.bin"
,
.
board
=
"cht-bsw"
,
.
pdata
=
&
byt_rvp_platform_data
,
};
static
struct
sst_acpi_mach
*
cht_quirk
(
void
*
arg
)
{
...
...
@@ -486,68 +478,182 @@ static struct sst_acpi_mach *byt_quirk(void *arg)
static
struct
sst_acpi_mach
sst_acpi_bytcr
[]
=
{
{
"10EC5640"
,
"bytcr_rt5640"
,
"intel/fw_sst_0f28.bin"
,
"bytcr_rt5640"
,
byt_quirk
,
&
byt_rvp_platform_data
},
{
"10EC5642"
,
"bytcr_rt5640"
,
"intel/fw_sst_0f28.bin"
,
"bytcr_rt5640"
,
NULL
,
&
byt_rvp_platform_data
},
{
"INTCCFFD"
,
"bytcr_rt5640"
,
"intel/fw_sst_0f28.bin"
,
"bytcr_rt5640"
,
NULL
,
&
byt_rvp_platform_data
},
{
"10EC5651"
,
"bytcr_rt5651"
,
"intel/fw_sst_0f28.bin"
,
"bytcr_rt5651"
,
NULL
,
&
byt_rvp_platform_data
},
{
"DLGS7212"
,
"bytcht_da7213"
,
"intel/fw_sst_0f28.bin"
,
"bytcht_da7213"
,
NULL
,
&
byt_rvp_platform_data
},
{
"DLGS7213"
,
"bytcht_da7213"
,
"intel/fw_sst_0f28.bin"
,
"bytcht_da7213"
,
NULL
,
&
byt_rvp_platform_data
},
{
.
id
=
"10EC5640"
,
.
drv_name
=
"bytcr_rt5640"
,
.
fw_filename
=
"intel/fw_sst_0f28.bin"
,
.
board
=
"bytcr_rt5640"
,
.
machine_quirk
=
byt_quirk
,
.
pdata
=
&
byt_rvp_platform_data
,
},
{
.
id
=
"10EC5642"
,
.
drv_name
=
"bytcr_rt5640"
,
.
fw_filename
=
"intel/fw_sst_0f28.bin"
,
.
board
=
"bytcr_rt5640"
,
.
pdata
=
&
byt_rvp_platform_data
},
{
.
id
=
"INTCCFFD"
,
.
drv_name
=
"bytcr_rt5640"
,
.
fw_filename
=
"intel/fw_sst_0f28.bin"
,
.
board
=
"bytcr_rt5640"
,
.
pdata
=
&
byt_rvp_platform_data
},
{
.
id
=
"10EC5651"
,
.
drv_name
=
"bytcr_rt5651"
,
.
fw_filename
=
"intel/fw_sst_0f28.bin"
,
.
board
=
"bytcr_rt5651"
,
.
pdata
=
&
byt_rvp_platform_data
},
{
.
id
=
"DLGS7212"
,
.
drv_name
=
"bytcht_da7213"
,
.
fw_filename
=
"intel/fw_sst_0f28.bin"
,
.
board
=
"bytcht_da7213"
,
.
pdata
=
&
byt_rvp_platform_data
},
{
.
id
=
"DLGS7213"
,
.
drv_name
=
"bytcht_da7213"
,
.
fw_filename
=
"intel/fw_sst_0f28.bin"
,
.
board
=
"bytcht_da7213"
,
.
pdata
=
&
byt_rvp_platform_data
},
/* some Baytrail platforms rely on RT5645, use CHT machine driver */
{
"10EC5645"
,
"cht-bsw-rt5645"
,
"intel/fw_sst_0f28.bin"
,
"cht-bsw"
,
NULL
,
&
byt_rvp_platform_data
},
{
"10EC5648"
,
"cht-bsw-rt5645"
,
"intel/fw_sst_0f28.bin"
,
"cht-bsw"
,
NULL
,
&
byt_rvp_platform_data
},
{
.
id
=
"10EC5645"
,
.
drv_name
=
"cht-bsw-rt5645"
,
.
fw_filename
=
"intel/fw_sst_0f28.bin"
,
.
board
=
"cht-bsw"
,
.
pdata
=
&
byt_rvp_platform_data
},
{
.
id
=
"10EC5648"
,
.
drv_name
=
"cht-bsw-rt5645"
,
.
fw_filename
=
"intel/fw_sst_0f28.bin"
,
.
board
=
"cht-bsw"
,
.
pdata
=
&
byt_rvp_platform_data
},
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
/*
* This is always last in the table so that it is selected only when
* enabled explicitly and there is no codec-related information in SSDT
*/
{
"80860F28"
,
"bytcht_nocodec"
,
"intel/fw_sst_0f28.bin"
,
"bytcht_nocodec"
,
NULL
,
&
byt_rvp_platform_data
},
{
.
id
=
"80860F28"
,
.
drv_name
=
"bytcht_nocodec"
,
.
fw_filename
=
"intel/fw_sst_0f28.bin"
,
.
board
=
"bytcht_nocodec"
,
.
pdata
=
&
byt_rvp_platform_data
},
#endif
{},
};
/* Cherryview-based platforms: CherryTrail and Braswell */
static
struct
sst_acpi_mach
sst_acpi_chv
[]
=
{
{
"10EC5670"
,
"cht-bsw-rt5672"
,
"intel/fw_sst_22a8.bin"
,
"cht-bsw"
,
NULL
,
&
chv_platform_data
},
{
"10EC5672"
,
"cht-bsw-rt5672"
,
"intel/fw_sst_22a8.bin"
,
"cht-bsw"
,
NULL
,
&
chv_platform_data
},
{
"10EC5645"
,
"cht-bsw-rt5645"
,
"intel/fw_sst_22a8.bin"
,
"cht-bsw"
,
NULL
,
&
chv_platform_data
},
{
"10EC5650"
,
"cht-bsw-rt5645"
,
"intel/fw_sst_22a8.bin"
,
"cht-bsw"
,
NULL
,
&
chv_platform_data
},
{
"10EC3270"
,
"cht-bsw-rt5645"
,
"intel/fw_sst_22a8.bin"
,
"cht-bsw"
,
NULL
,
&
chv_platform_data
},
{
"193C9890"
,
"cht-bsw-max98090"
,
"intel/fw_sst_22a8.bin"
,
"cht-bsw"
,
NULL
,
&
chv_platform_data
},
{
"DLGS7212"
,
"bytcht_da7213"
,
"intel/fw_sst_22a8.bin"
,
"bytcht_da7213"
,
NULL
,
&
chv_platform_data
},
{
"DLGS7213"
,
"bytcht_da7213"
,
"intel/fw_sst_22a8.bin"
,
"bytcht_da7213"
,
NULL
,
&
chv_platform_data
},
{
.
id
=
"10EC5670"
,
.
drv_name
=
"cht-bsw-rt5672"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"cht-bsw"
,
.
pdata
=
&
chv_platform_data
},
{
.
id
=
"10EC5672"
,
.
drv_name
=
"cht-bsw-rt5672"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"cht-bsw"
,
.
pdata
=
&
chv_platform_data
},
{
.
id
=
"10EC5645"
,
.
drv_name
=
"cht-bsw-rt5645"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"cht-bsw"
,
.
pdata
=
&
chv_platform_data
},
{
.
id
=
"10EC5650"
,
.
drv_name
=
"cht-bsw-rt5645"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"cht-bsw"
,
.
pdata
=
&
chv_platform_data
},
{
.
id
=
"10EC3270"
,
.
drv_name
=
"cht-bsw-rt5645"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"cht-bsw"
,
.
pdata
=
&
chv_platform_data
},
{
.
id
=
"193C9890"
,
.
drv_name
=
"cht-bsw-max98090"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"cht-bsw"
,
.
pdata
=
&
chv_platform_data
},
{
.
id
=
"DLGS7212"
,
.
drv_name
=
"bytcht_da7213"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"bytcht_da7213"
,
.
pdata
=
&
chv_platform_data
},
{
.
id
=
"DLGS7213"
,
.
drv_name
=
"bytcht_da7213"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"bytcht_da7213"
,
.
pdata
=
&
chv_platform_data
},
{
.
id
=
"ESSX8316"
,
.
drv_name
=
"bytcht_es8316"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"bytcht_es8316"
,
.
pdata
=
&
chv_platform_data
},
/* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
{
"10EC5640"
,
"bytcr_rt5640"
,
"intel/fw_sst_22a8.bin"
,
"bytcr_rt5640"
,
cht_quirk
,
&
chv_platform_data
},
{
"10EC3276"
,
"bytcr_rt5640"
,
"intel/fw_sst_22a8.bin"
,
"bytcr_rt5640"
,
NULL
,
&
chv_platform_data
},
{
.
id
=
"10EC5640"
,
.
drv_name
=
"bytcr_rt5640"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"bytcr_rt5640"
,
.
machine_quirk
=
cht_quirk
,
.
pdata
=
&
chv_platform_data
},
{
.
id
=
"10EC3276"
,
.
drv_name
=
"bytcr_rt5640"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"bytcr_rt5640"
,
.
pdata
=
&
chv_platform_data
},
/* some CHT-T platforms rely on RT5651, use Baytrail machine driver */
{
"10EC5651"
,
"bytcr_rt5651"
,
"intel/fw_sst_22a8.bin"
,
"bytcr_rt5651"
,
NULL
,
&
chv_platform_data
},
{
.
id
=
"10EC5651"
,
.
drv_name
=
"bytcr_rt5651"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"bytcr_rt5651"
,
.
pdata
=
&
chv_platform_data
},
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
/*
* This is always last in the table so that it is selected only when
* enabled explicitly and there is no codec-related information in SSDT
*/
{
"808622A8"
,
"bytcht_nocodec"
,
"intel/fw_sst_22a8.bin"
,
"bytcht_nocodec"
,
NULL
,
&
chv_platform_data
},
{
.
id
=
"808622A8"
,
.
drv_name
=
"bytcht_nocodec"
,
.
fw_filename
=
"intel/fw_sst_22a8.bin"
,
.
board
=
"bytcht_nocodec"
,
.
pdata
=
&
chv_platform_data
},
#endif
{},
};
...
...
sound/soc/intel/boards/Makefile
浏览文件 @
51fa6a8f
...
...
@@ -11,7 +11,10 @@ snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
snd-soc-sst-cht-bsw-rt5645-objs
:=
cht_bsw_rt5645.o
snd-soc-sst-cht-bsw-max98090_ti-objs
:=
cht_bsw_max98090_ti.o
snd-soc-sst-byt-cht-da7213-objs
:=
bytcht_da7213.o
snd-soc-sst-byt-cht-es8316-objs
:=
bytcht_es8316.o
snd-soc-sst-byt-cht-nocodec-objs
:=
bytcht_nocodec.o
snd-soc-kbl_rt5663_max98927-objs
:=
kbl_rt5663_max98927.o
snd-soc-kbl_rt5663_rt5514_max98927-objs
:=
kbl_rt5663_rt5514_max98927.o
snd-soc-skl_rt286-objs
:=
skl_rt286.o
snd-skl_nau88l25_max98357a-objs
:=
skl_nau88l25_max98357a.o
snd-soc-skl_nau88l25_ssm4567-objs
:=
skl_nau88l25_ssm4567.o
...
...
@@ -29,7 +32,10 @@ obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH)
+=
snd-soc-sst-cht-bsw-rt5645.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH)
+=
snd-soc-sst-cht-bsw-max98090_ti.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH)
+=
snd-soc-sst-byt-cht-da7213.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH)
+=
snd-soc-sst-byt-cht-es8316.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
+=
snd-soc-sst-byt-cht-nocodec.o
obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH)
+=
snd-soc-kbl_rt5663_max98927.o
obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH)
+=
snd-soc-kbl_rt5663_rt5514_max98927.o
obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH)
+=
snd-soc-skl_rt286.o
obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH)
+=
snd-skl_nau88l25_max98357a.o
obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH)
+=
snd-soc-skl_nau88l25_ssm4567.o
sound/soc/intel/boards/bdw-rt5677.c
浏览文件 @
51fa6a8f
...
...
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
...
...
@@ -120,6 +121,26 @@ static struct snd_soc_jack_gpio mic_jack_gpio = {
.
invert
=
1
,
};
/* GPIO indexes defined by ACPI */
enum
{
RT5677_GPIO_PLUG_DET
=
0
,
RT5677_GPIO_MIC_PRESENT_L
=
1
,
RT5677_GPIO_HOTWORD_DET_L
=
2
,
RT5677_GPIO_DSP_INT
=
3
,
RT5677_GPIO_HP_AMP_SHDN_L
=
4
,
};
static
const
struct
acpi_gpio_params
plug_det_gpio
=
{
RT5677_GPIO_PLUG_DET
,
0
,
false
};
static
const
struct
acpi_gpio_params
mic_present_gpio
=
{
RT5677_GPIO_MIC_PRESENT_L
,
0
,
false
};
static
const
struct
acpi_gpio_params
headphone_enable_gpio
=
{
RT5677_GPIO_HP_AMP_SHDN_L
,
0
,
false
};
static
const
struct
acpi_gpio_mapping
bdw_rt5677_gpios
[]
=
{
{
"plug-det-gpios"
,
&
plug_det_gpio
,
1
},
{
"mic-present-gpios"
,
&
mic_present_gpio
,
1
},
{
"headphone-enable-gpios"
,
&
headphone_enable_gpio
,
1
},
{
NULL
},
};
static
int
broadwell_ssp0_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
struct
snd_pcm_hw_params
*
params
)
{
...
...
@@ -184,6 +205,11 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_dapm_context
*
dapm
=
snd_soc_codec_get_dapm
(
codec
);
int
ret
;
ret
=
devm_acpi_dev_add_driver_gpios
(
codec
->
dev
,
bdw_rt5677_gpios
);
if
(
ret
)
dev_warn
(
codec
->
dev
,
"Failed to add driver gpios
\n
"
);
/* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1.
* The ASRC clock source is clk_i2s1_asrc.
...
...
sound/soc/intel/boards/bxt_da7219_max98357a.c
浏览文件 @
51fa6a8f
...
...
@@ -242,31 +242,31 @@ static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd)
return
0
;
}
static
unsigned
int
rates
[]
=
{
static
const
unsigned
int
rates
[]
=
{
48000
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
.
count
=
ARRAY_SIZE
(
rates
),
.
list
=
rates
,
.
mask
=
0
,
};
static
unsigned
int
channels
[]
=
{
static
const
unsigned
int
channels
[]
=
{
DUAL_CHANNEL
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
.
count
=
ARRAY_SIZE
(
channels
),
.
list
=
channels
,
.
mask
=
0
,
};
static
unsigned
int
channels_quad
[]
=
{
static
const
unsigned
int
channels_quad
[]
=
{
QUAD_CHANNEL
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_channels_quad
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_channels_quad
=
{
.
count
=
ARRAY_SIZE
(
channels_quad
),
.
list
=
channels_quad
,
.
mask
=
0
,
...
...
sound/soc/intel/boards/bxt_rt298.c
浏览文件 @
51fa6a8f
...
...
@@ -207,11 +207,11 @@ static const struct snd_soc_ops broxton_rt298_ops = {
.
hw_params
=
broxton_rt298_hw_params
,
};
static
unsigned
int
rates
[]
=
{
static
const
unsigned
int
rates
[]
=
{
48000
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
.
count
=
ARRAY_SIZE
(
rates
),
.
list
=
rates
,
.
mask
=
0
,
...
...
@@ -222,19 +222,16 @@ static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct
snd_interval
*
channels
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_CHANNELS
);
if
(
params_channels
(
params
)
==
2
)
channels
->
min
=
channels
->
max
=
2
;
else
channels
->
min
=
channels
->
max
=
4
;
channels
->
min
=
channels
->
max
=
4
;
return
0
;
}
static
unsigned
int
channels_dmic
[]
=
{
2
,
4
,
static
const
unsigned
int
channels_dmic
[]
=
{
1
,
2
,
3
,
4
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_dmic_channels
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_dmic_channels
=
{
.
count
=
ARRAY_SIZE
(
channels_dmic
),
.
list
=
channels_dmic
,
.
mask
=
0
,
...
...
@@ -256,11 +253,11 @@ static const struct snd_soc_ops broxton_dmic_ops = {
.
startup
=
broxton_dmic_startup
,
};
static
unsigned
int
channels
[]
=
{
static
const
unsigned
int
channels
[]
=
{
2
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
.
count
=
ARRAY_SIZE
(
channels
),
.
list
=
channels
,
.
mask
=
0
,
...
...
sound/soc/intel/boards/byt-max98090.c
浏览文件 @
51fa6a8f
...
...
@@ -67,20 +67,27 @@ static struct snd_soc_jack_pin hs_jack_pins[] = {
static
struct
snd_soc_jack_gpio
hs_jack_gpios
[]
=
{
{
.
name
=
"hp-gpio"
,
.
idx
=
0
,
.
name
=
"hp"
,
.
report
=
SND_JACK_HEADPHONE
|
SND_JACK_LINEOUT
,
.
debounce_time
=
200
,
},
{
.
name
=
"mic-gpio"
,
.
idx
=
1
,
.
name
=
"mic"
,
.
invert
=
1
,
.
report
=
SND_JACK_MICROPHONE
,
.
debounce_time
=
200
,
},
};
static
const
struct
acpi_gpio_params
hp_gpios
=
{
0
,
0
,
false
};
static
const
struct
acpi_gpio_params
mic_gpios
=
{
1
,
0
,
false
};
static
const
struct
acpi_gpio_mapping
acpi_byt_max98090_gpios
[]
=
{
{
"hp-gpios"
,
&
hp_gpios
,
1
},
{
"mic-gpios"
,
&
mic_gpios
,
1
},
{},
};
static
int
byt_max98090_init
(
struct
snd_soc_pcm_runtime
*
runtime
)
{
int
ret
;
...
...
@@ -140,8 +147,9 @@ static struct snd_soc_card byt_max98090_card = {
static
int
byt_max98090_probe
(
struct
platform_device
*
pdev
)
{
int
ret_val
=
0
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
byt_max98090_private
*
priv
;
int
ret_val
;
priv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
priv
),
GFP_ATOMIC
);
if
(
!
priv
)
{
...
...
@@ -149,6 +157,10 @@ static int byt_max98090_probe(struct platform_device *pdev)
return
-
ENOMEM
;
}
ret_val
=
devm_acpi_dev_add_driver_gpios
(
dev
->
parent
,
acpi_byt_max98090_gpios
);
if
(
ret_val
)
dev_dbg
(
dev
,
"Unable to add GPIO mapping table
\n
"
);
byt_max98090_card
.
dev
=
&
pdev
->
dev
;
snd_soc_card_set_drvdata
(
&
byt_max98090_card
,
priv
);
ret_val
=
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
byt_max98090_card
);
...
...
@@ -158,7 +170,7 @@ static int byt_max98090_probe(struct platform_device *pdev)
return
ret_val
;
}
return
ret_val
;
return
0
;
}
static
int
byt_max98090_remove
(
struct
platform_device
*
pdev
)
...
...
sound/soc/intel/boards/bytcht_es8316.c
0 → 100644
浏览文件 @
51fa6a8f
/*
* bytcht_es8316.c - ASoc Machine driver for Intel Baytrail/Cherrytrail
* platforms with Everest ES8316 SoC
*
* Copyright (C) 2017 Endless Mobile, Inc.
* Authors: David Yang <yangxiaohua@everest-semi.com>,
* Daniel Drake <drake@endlessm.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <asm/platform_sst_audio.h>
#include <linux/clk.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "../atom/sst-atom-controls.h"
#include "../common/sst-acpi.h"
#include "../common/sst-dsp.h"
struct
byt_cht_es8316_private
{
struct
clk
*
mclk
;
};
#define CODEC_DAI1 "ES8316 HiFi"
static
inline
struct
snd_soc_dai
*
get_codec_dai
(
struct
snd_soc_card
*
card
)
{
struct
snd_soc_pcm_runtime
*
rtd
;
list_for_each_entry
(
rtd
,
&
card
->
rtd_list
,
list
)
{
if
(
!
strncmp
(
rtd
->
codec_dai
->
name
,
CODEC_DAI1
,
strlen
(
CODEC_DAI1
)))
return
rtd
->
codec_dai
;
}
return
NULL
;
}
static
const
struct
snd_soc_dapm_widget
byt_cht_es8316_widgets
[]
=
{
SND_SOC_DAPM_HP
(
"Headphone"
,
NULL
),
/*
* The codec supports two analog microphone inputs. I have only
* tested MIC1. A DMIC route could also potentially be added
* if such functionality is found on another platform.
*/
SND_SOC_DAPM_MIC
(
"Microphone 1"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Microphone 2"
,
NULL
),
};
static
const
struct
snd_soc_dapm_route
byt_cht_es8316_audio_map
[]
=
{
{
"MIC1"
,
NULL
,
"Microphone 1"
},
{
"MIC2"
,
NULL
,
"Microphone 2"
},
{
"Headphone"
,
NULL
,
"HPOL"
},
{
"Headphone"
,
NULL
,
"HPOR"
},
{
"Playback"
,
NULL
,
"ssp2 Tx"
},
{
"ssp2 Tx"
,
NULL
,
"codec_out0"
},
{
"ssp2 Tx"
,
NULL
,
"codec_out1"
},
{
"codec_in0"
,
NULL
,
"ssp2 Rx"
},
{
"codec_in1"
,
NULL
,
"ssp2 Rx"
},
{
"ssp2 Rx"
,
NULL
,
"Capture"
},
};
static
const
struct
snd_kcontrol_new
byt_cht_es8316_controls
[]
=
{
SOC_DAPM_PIN_SWITCH
(
"Headphone"
),
SOC_DAPM_PIN_SWITCH
(
"Microphone 1"
),
SOC_DAPM_PIN_SWITCH
(
"Microphone 2"
),
};
static
int
byt_cht_es8316_init
(
struct
snd_soc_pcm_runtime
*
runtime
)
{
struct
snd_soc_card
*
card
=
runtime
->
card
;
struct
byt_cht_es8316_private
*
priv
=
snd_soc_card_get_drvdata
(
card
);
int
ret
;
card
->
dapm
.
idle_bias_off
=
true
;
/*
* The firmware might enable the clock at boot (this information
* may or may not be reflected in the enable clock register).
* To change the rate we must disable the clock first to cover these
* cases. Due to common clock framework restrictions that do not allow
* to disable a clock that has not been enabled, we need to enable
* the clock first.
*/
ret
=
clk_prepare_enable
(
priv
->
mclk
);
if
(
!
ret
)
clk_disable_unprepare
(
priv
->
mclk
);
ret
=
clk_set_rate
(
priv
->
mclk
,
19200000
);
if
(
ret
)
dev_err
(
card
->
dev
,
"unable to set MCLK rate
\n
"
);
ret
=
clk_prepare_enable
(
priv
->
mclk
);
if
(
ret
)
dev_err
(
card
->
dev
,
"unable to enable MCLK
\n
"
);
ret
=
snd_soc_dai_set_sysclk
(
runtime
->
codec_dai
,
0
,
19200000
,
SND_SOC_CLOCK_IN
);
if
(
ret
<
0
)
{
dev_err
(
card
->
dev
,
"can't set codec clock %d
\n
"
,
ret
);
return
ret
;
}
return
0
;
}
static
const
struct
snd_soc_pcm_stream
byt_cht_es8316_dai_params
=
{
.
formats
=
SNDRV_PCM_FMTBIT_S24_LE
,
.
rate_min
=
48000
,
.
rate_max
=
48000
,
.
channels_min
=
2
,
.
channels_max
=
2
,
};
static
int
byt_cht_es8316_codec_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_interval
*
rate
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_RATE
);
struct
snd_interval
*
channels
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_CHANNELS
);
int
ret
;
/* The DSP will covert the FE rate to 48k, stereo */
rate
->
min
=
rate
->
max
=
48000
;
channels
->
min
=
channels
->
max
=
2
;
/* set SSP2 to 24-bit */
params_set_format
(
params
,
SNDRV_PCM_FORMAT_S24_LE
);
/*
* Default mode for SSP configuration is TDM 4 slot, override config
* with explicit setting to I2S 2ch 24-bit. The word length is set with
* dai_set_tdm_slot() since there is no other API exposed
*/
ret
=
snd_soc_dai_set_fmt
(
rtd
->
cpu_dai
,
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBS_CFS
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"can't set format to I2S, err %d
\n
"
,
ret
);
return
ret
;
}
ret
=
snd_soc_dai_set_tdm_slot
(
rtd
->
cpu_dai
,
0x3
,
0x3
,
2
,
24
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"can't set I2S config, err %d
\n
"
,
ret
);
return
ret
;
}
return
0
;
}
static
int
byt_cht_es8316_aif1_startup
(
struct
snd_pcm_substream
*
substream
)
{
return
snd_pcm_hw_constraint_single
(
substream
->
runtime
,
SNDRV_PCM_HW_PARAM_RATE
,
48000
);
}
static
const
struct
snd_soc_ops
byt_cht_es8316_aif1_ops
=
{
.
startup
=
byt_cht_es8316_aif1_startup
,
};
static
struct
snd_soc_dai_link
byt_cht_es8316_dais
[]
=
{
[
MERR_DPCM_AUDIO
]
=
{
.
name
=
"Audio Port"
,
.
stream_name
=
"Audio"
,
.
cpu_dai_name
=
"media-cpu-dai"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
codec_name
=
"snd-soc-dummy"
,
.
platform_name
=
"sst-mfld-platform"
,
.
nonatomic
=
true
,
.
dynamic
=
1
,
.
dpcm_playback
=
1
,
.
dpcm_capture
=
1
,
.
ops
=
&
byt_cht_es8316_aif1_ops
,
},
[
MERR_DPCM_DEEP_BUFFER
]
=
{
.
name
=
"Deep-Buffer Audio Port"
,
.
stream_name
=
"Deep-Buffer Audio"
,
.
cpu_dai_name
=
"deepbuffer-cpu-dai"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
codec_name
=
"snd-soc-dummy"
,
.
platform_name
=
"sst-mfld-platform"
,
.
nonatomic
=
true
,
.
dynamic
=
1
,
.
dpcm_playback
=
1
,
.
ops
=
&
byt_cht_es8316_aif1_ops
,
},
[
MERR_DPCM_COMPR
]
=
{
.
name
=
"Compressed Port"
,
.
stream_name
=
"Compress"
,
.
cpu_dai_name
=
"compress-cpu-dai"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
codec_name
=
"snd-soc-dummy"
,
.
platform_name
=
"sst-mfld-platform"
,
},
/* back ends */
{
/* Only SSP2 has been tested here, so BYT-CR platforms that
* require SSP0 will not work.
*/
.
name
=
"SSP2-Codec"
,
.
id
=
1
,
.
cpu_dai_name
=
"ssp2-port"
,
.
platform_name
=
"sst-mfld-platform"
,
.
no_pcm
=
1
,
.
codec_dai_name
=
"ES8316 HiFi"
,
.
codec_name
=
"i2c-ESSX8316:00"
,
.
dai_fmt
=
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBS_CFS
,
.
be_hw_params_fixup
=
byt_cht_es8316_codec_fixup
,
.
nonatomic
=
true
,
.
dpcm_playback
=
1
,
.
dpcm_capture
=
1
,
.
init
=
byt_cht_es8316_init
,
},
};
/* SoC card */
static
struct
snd_soc_card
byt_cht_es8316_card
=
{
.
name
=
"bytcht-es8316"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
byt_cht_es8316_dais
,
.
num_links
=
ARRAY_SIZE
(
byt_cht_es8316_dais
),
.
dapm_widgets
=
byt_cht_es8316_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
byt_cht_es8316_widgets
),
.
dapm_routes
=
byt_cht_es8316_audio_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
byt_cht_es8316_audio_map
),
.
controls
=
byt_cht_es8316_controls
,
.
num_controls
=
ARRAY_SIZE
(
byt_cht_es8316_controls
),
.
fully_routed
=
true
,
};
static
int
snd_byt_cht_es8316_mc_probe
(
struct
platform_device
*
pdev
)
{
int
ret
=
0
;
struct
byt_cht_es8316_private
*
priv
;
priv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
priv
),
GFP_ATOMIC
);
if
(
!
priv
)
return
-
ENOMEM
;
/* register the soc card */
byt_cht_es8316_card
.
dev
=
&
pdev
->
dev
;
snd_soc_card_set_drvdata
(
&
byt_cht_es8316_card
,
priv
);
priv
->
mclk
=
devm_clk_get
(
&
pdev
->
dev
,
"pmc_plt_clk_3"
);
if
(
IS_ERR
(
priv
->
mclk
))
{
ret
=
PTR_ERR
(
priv
->
mclk
);
dev_err
(
&
pdev
->
dev
,
"Failed to get MCLK from pmc_plt_clk_3: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
byt_cht_es8316_card
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"snd_soc_register_card failed %d
\n
"
,
ret
);
return
ret
;
}
platform_set_drvdata
(
pdev
,
&
byt_cht_es8316_card
);
return
ret
;
}
static
struct
platform_driver
snd_byt_cht_es8316_mc_driver
=
{
.
driver
=
{
.
name
=
"bytcht_es8316"
,
},
.
probe
=
snd_byt_cht_es8316_mc_probe
,
};
module_platform_driver
(
snd_byt_cht_es8316_mc_driver
);
MODULE_DESCRIPTION
(
"ASoC Intel(R) Baytrail/Cherrytrail Machine driver"
);
MODULE_AUTHOR
(
"David Yang <yangxiaohua@everest-semi.com>"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_ALIAS
(
"platform:bytcht_es8316"
);
sound/soc/intel/boards/bytcht_nocodec.c
浏览文件 @
51fa6a8f
...
...
@@ -85,11 +85,11 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd,
return
0
;
}
static
unsigned
int
rates_48000
[]
=
{
static
const
unsigned
int
rates_48000
[]
=
{
48000
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_48000
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_48000
=
{
.
count
=
ARRAY_SIZE
(
rates_48000
),
.
list
=
rates_48000
,
};
...
...
sound/soc/intel/boards/bytcr_rt5651.c
浏览文件 @
51fa6a8f
...
...
@@ -203,11 +203,11 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
return
0
;
}
static
unsigned
int
rates_48000
[]
=
{
static
const
unsigned
int
rates_48000
[]
=
{
48000
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_48000
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_48000
=
{
.
count
=
ARRAY_SIZE
(
rates_48000
),
.
list
=
rates_48000
,
};
...
...
sound/soc/intel/boards/cht_bsw_max98090_ti.c
浏览文件 @
51fa6a8f
...
...
@@ -39,18 +39,6 @@ struct cht_mc_private {
bool
ts3a227e_present
;
};
static
inline
struct
snd_soc_dai
*
cht_get_codec_dai
(
struct
snd_soc_card
*
card
)
{
struct
snd_soc_pcm_runtime
*
rtd
;
list_for_each_entry
(
rtd
,
&
card
->
rtd_list
,
list
)
{
if
(
!
strncmp
(
rtd
->
codec_dai
->
name
,
CHT_CODEC_DAI
,
strlen
(
CHT_CODEC_DAI
)))
return
rtd
->
codec_dai
;
}
return
NULL
;
}
static
const
struct
snd_soc_dapm_widget
cht_dapm_widgets
[]
=
{
SND_SOC_DAPM_HP
(
"Headphone"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Headset Mic"
,
NULL
),
...
...
sound/soc/intel/boards/cht_bsw_rt5672.c
浏览文件 @
51fa6a8f
...
...
@@ -19,6 +19,8 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <asm/cpu_device_id.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
...
...
@@ -31,8 +33,11 @@
#define CHT_PLAT_CLK_3_HZ 19200000
#define CHT_CODEC_DAI "rt5670-aif1"
static
struct
snd_soc_jack
cht_bsw_headset
;
static
char
cht_bsw_codec_name
[
16
];
struct
cht_mc_private
{
struct
snd_soc_jack
headset
;
char
codec_name
[
16
];
struct
clk
*
mclk
;
};
/* Headset jack detection DAPM pins */
static
struct
snd_soc_jack_pin
cht_bsw_headset_pins
[]
=
{
...
...
@@ -64,6 +69,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct
snd_soc_dapm_context
*
dapm
=
w
->
dapm
;
struct
snd_soc_card
*
card
=
dapm
->
card
;
struct
snd_soc_dai
*
codec_dai
;
struct
cht_mc_private
*
ctx
=
snd_soc_card_get_drvdata
(
card
);
int
ret
;
codec_dai
=
cht_get_codec_dai
(
card
);
...
...
@@ -73,6 +79,15 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
}
if
(
SND_SOC_DAPM_EVENT_ON
(
event
))
{
if
(
ctx
->
mclk
)
{
ret
=
clk_prepare_enable
(
ctx
->
mclk
);
if
(
ret
<
0
)
{
dev_err
(
card
->
dev
,
"could not configure MCLK state"
);
return
ret
;
}
}
/* set codec PLL source to the 19.2MHz platform clock (MCLK) */
ret
=
snd_soc_dai_set_pll
(
codec_dai
,
0
,
RT5670_PLL1_S_MCLK
,
CHT_PLAT_CLK_3_HZ
,
48000
*
512
);
...
...
@@ -96,6 +111,9 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
*/
snd_soc_dai_set_sysclk
(
codec_dai
,
RT5670_SCLK_S_RCCLK
,
48000
*
512
,
SND_SOC_CLOCK_IN
);
if
(
ctx
->
mclk
)
clk_disable_unprepare
(
ctx
->
mclk
);
}
return
0
;
}
...
...
@@ -171,6 +189,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
int
ret
;
struct
snd_soc_dai
*
codec_dai
=
runtime
->
codec_dai
;
struct
snd_soc_codec
*
codec
=
codec_dai
->
codec
;
struct
cht_mc_private
*
ctx
=
snd_soc_card_get_drvdata
(
runtime
->
card
);
/* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
ret
=
snd_soc_dai_set_tdm_slot
(
codec_dai
,
0xF
,
0xF
,
4
,
24
);
...
...
@@ -194,13 +213,37 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
RT5670_CLK_SEL_I2S1_ASRC
);
ret
=
snd_soc_card_jack_new
(
runtime
->
card
,
"Headset"
,
SND_JACK_HEADSET
|
SND_JACK_BTN_0
|
SND_JACK_BTN_1
|
SND_JACK_BTN_2
,
&
cht_bsw_headset
,
cht_bsw_headset_pins
,
ARRAY_SIZE
(
cht_bsw_headset_pins
));
SND_JACK_HEADSET
|
SND_JACK_BTN_0
|
SND_JACK_BTN_1
|
SND_JACK_BTN_2
,
&
ctx
->
headset
,
cht_bsw_headset_pins
,
ARRAY_SIZE
(
cht_bsw_headset_pins
));
if
(
ret
)
return
ret
;
rt5670_set_jack_detect
(
codec
,
&
cht_bsw_headset
);
rt5670_set_jack_detect
(
codec
,
&
ctx
->
headset
);
if
(
ctx
->
mclk
)
{
/*
* The firmware might enable the clock at
* boot (this information may or may not
* be reflected in the enable clock register).
* To change the rate we must disable the clock
* first to cover these cases. Due to common
* clock framework restrictions that do not allow
* to disable a clock that has not been enabled,
* we need to enable the clock first.
*/
ret
=
clk_prepare_enable
(
ctx
->
mclk
);
if
(
!
ret
)
clk_disable_unprepare
(
ctx
->
mclk
);
ret
=
clk_set_rate
(
ctx
->
mclk
,
CHT_PLAT_CLK_3_HZ
);
if
(
ret
)
{
dev_err
(
runtime
->
dev
,
"unable to set MCLK rate
\n
"
);
return
ret
;
}
}
return
0
;
}
...
...
@@ -341,34 +384,62 @@ static struct snd_soc_card snd_soc_card_cht = {
.
resume_post
=
cht_resume_post
,
};
static
bool
is_valleyview
(
void
)
{
static
const
struct
x86_cpu_id
cpu_ids
[]
=
{
{
X86_VENDOR_INTEL
,
6
,
55
},
/* Valleyview, Bay Trail */
{}
};
if
(
!
x86_match_cpu
(
cpu_ids
))
return
false
;
return
true
;
}
#define RT5672_I2C_DEFAULT "i2c-10EC5670:00"
static
int
snd_cht_mc_probe
(
struct
platform_device
*
pdev
)
{
int
ret_val
=
0
;
struct
cht_mc_private
*
drv
;
struct
sst_acpi_mach
*
mach
=
pdev
->
dev
.
platform_data
;
const
char
*
i2c_name
;
int
i
;
strcpy
(
cht_bsw_codec_name
,
RT5672_I2C_DEFAULT
);
drv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
drv
),
GFP_ATOMIC
);
if
(
!
drv
)
return
-
ENOMEM
;
strcpy
(
drv
->
codec_name
,
RT5672_I2C_DEFAULT
);
/* fixup codec name based on HID */
if
(
mach
)
{
i2c_name
=
sst_acpi_find_name_from_hid
(
mach
->
id
);
if
(
i2c_name
)
{
snprintf
(
cht_bsw_codec_name
,
sizeof
(
cht_bsw_
codec_name
),
snprintf
(
drv
->
codec_name
,
sizeof
(
drv
->
codec_name
),
"i2c-%s"
,
i2c_name
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cht_dailink
);
i
++
)
{
if
(
!
strcmp
(
cht_dailink
[
i
].
codec_name
,
RT5672_I2C_DEFAULT
))
{
cht_dailink
[
i
].
codec_name
=
cht_bsw_
codec_name
;
drv
->
codec_name
;
break
;
}
}
}
}
if
(
is_valleyview
())
{
drv
->
mclk
=
devm_clk_get
(
&
pdev
->
dev
,
"pmc_plt_clk_3"
);
if
(
IS_ERR
(
drv
->
mclk
))
{
dev_err
(
&
pdev
->
dev
,
"Failed to get MCLK from pmc_plt_clk_3: %ld
\n
"
,
PTR_ERR
(
drv
->
mclk
));
return
PTR_ERR
(
drv
->
mclk
);
}
}
snd_soc_card_set_drvdata
(
&
snd_soc_card_cht
,
drv
);
/* register the soc card */
snd_soc_card_cht
.
dev
=
&
pdev
->
dev
;
ret_val
=
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
snd_soc_card_cht
);
...
...
sound/soc/intel/boards/kbl_rt5663_max98927.c
0 → 100644
浏览文件 @
51fa6a8f
/*
* Intel Kabylake I2S Machine Driver with MAXIM98927
* and RT5663 Codecs
*
* Copyright (C) 2017, Intel Corporation. All rights reserved.
*
* Modified from:
* Intel Skylake I2S Machine driver
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License 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/platform_device.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "../../codecs/rt5663.h"
#include "../../codecs/hdac_hdmi.h"
#include "../skylake/skl.h"
#define KBL_REALTEK_CODEC_DAI "rt5663-aif"
#define KBL_MAXIM_CODEC_DAI "max98927-aif1"
#define DMIC_CH(p) p->list[p->count-1]
#define MAXIM_DEV0_NAME "i2c-MX98927:00"
#define MAXIM_DEV1_NAME "i2c-MX98927:01"
static
struct
snd_soc_card
kabylake_audio_card
;
static
const
struct
snd_pcm_hw_constraint_list
*
dmic_constraints
;
static
struct
snd_soc_jack
skylake_hdmi
[
3
];
struct
kbl_hdmi_pcm
{
struct
list_head
head
;
struct
snd_soc_dai
*
codec_dai
;
int
device
;
};
struct
kbl_rt5663_private
{
struct
snd_soc_jack
kabylake_headset
;
struct
list_head
hdmi_pcm_list
;
};
enum
{
KBL_DPCM_AUDIO_PB
=
0
,
KBL_DPCM_AUDIO_CP
,
KBL_DPCM_AUDIO_REF_CP
,
KBL_DPCM_AUDIO_DMIC_CP
,
KBL_DPCM_AUDIO_HDMI1_PB
,
KBL_DPCM_AUDIO_HDMI2_PB
,
KBL_DPCM_AUDIO_HDMI3_PB
,
};
static
const
struct
snd_kcontrol_new
kabylake_controls
[]
=
{
SOC_DAPM_PIN_SWITCH
(
"Headphone Jack"
),
SOC_DAPM_PIN_SWITCH
(
"Headset Mic"
),
SOC_DAPM_PIN_SWITCH
(
"Left Spk"
),
SOC_DAPM_PIN_SWITCH
(
"Right Spk"
),
};
static
const
struct
snd_soc_dapm_widget
kabylake_widgets
[]
=
{
SND_SOC_DAPM_HP
(
"Headphone Jack"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Headset Mic"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Left Spk"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Right Spk"
,
NULL
),
SND_SOC_DAPM_MIC
(
"SoC DMIC"
,
NULL
),
SND_SOC_DAPM_SPK
(
"DP"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI"
,
NULL
),
};
static
const
struct
snd_soc_dapm_route
kabylake_map
[]
=
{
/* HP jack connectors - unknown if we have jack detection */
{
"Headphone Jack"
,
NULL
,
"HPOL"
},
{
"Headphone Jack"
,
NULL
,
"HPOR"
},
/* speaker */
{
"Left Spk"
,
NULL
,
"Left BE_OUT"
},
{
"Right Spk"
,
NULL
,
"Right BE_OUT"
},
/* other jacks */
{
"IN1P"
,
NULL
,
"Headset Mic"
},
{
"IN1N"
,
NULL
,
"Headset Mic"
},
{
"DMic"
,
NULL
,
"SoC DMIC"
},
{
"HDMI"
,
NULL
,
"hif5 Output"
},
{
"DP"
,
NULL
,
"hif6 Output"
},
/* CODEC BE connections */
{
"Left HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"Right HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"ssp0 Tx"
,
NULL
,
"codec0_out"
},
{
"AIF Playback"
,
NULL
,
"ssp1 Tx"
},
{
"ssp1 Tx"
,
NULL
,
"codec1_out"
},
{
"codec0_in"
,
NULL
,
"ssp1 Rx"
},
{
"ssp1 Rx"
,
NULL
,
"AIF Capture"
},
/* DMIC */
{
"dmic01_hifi"
,
NULL
,
"DMIC01 Rx"
},
{
"DMIC01 Rx"
,
NULL
,
"DMIC AIF"
},
{
"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
struct
snd_soc_codec_conf
max98927_codec_conf
[]
=
{
{
.
dev_name
=
MAXIM_DEV0_NAME
,
.
name_prefix
=
"Right"
,
},
{
.
dev_name
=
MAXIM_DEV1_NAME
,
.
name_prefix
=
"Left"
,
},
};
static
struct
snd_soc_dai_link_component
max98927_codec_components
[]
=
{
{
/* Left */
.
name
=
MAXIM_DEV0_NAME
,
.
dai_name
=
KBL_MAXIM_CODEC_DAI
,
},
{
/* Right */
.
name
=
MAXIM_DEV1_NAME
,
.
dai_name
=
KBL_MAXIM_CODEC_DAI
,
},
};
static
int
kabylake_rt5663_fe_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
int
ret
;
struct
snd_soc_dapm_context
*
dapm
;
struct
snd_soc_component
*
component
=
rtd
->
cpu_dai
->
component
;
dapm
=
snd_soc_component_get_dapm
(
component
);
ret
=
snd_soc_dapm_ignore_suspend
(
dapm
,
"Reference Capture"
);
if
(
ret
)
{
dev_err
(
rtd
->
dev
,
"Ref Cap ignore suspend failed %d
\n
"
,
ret
);
return
ret
;
}
return
ret
;
}
static
int
kabylake_rt5663_codec_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
int
ret
;
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
/*
* Headset buttons map to the google Reference headset.
* These can be configured by userspace.
*/
ret
=
snd_soc_card_jack_new
(
&
kabylake_audio_card
,
"Headset Jack"
,
SND_JACK_HEADSET
|
SND_JACK_BTN_0
|
SND_JACK_BTN_1
|
SND_JACK_BTN_2
|
SND_JACK_BTN_3
,
&
ctx
->
kabylake_headset
,
NULL
,
0
);
if
(
ret
)
{
dev_err
(
rtd
->
dev
,
"Headset Jack creation failed %d
\n
"
,
ret
);
return
ret
;
}
rt5663_set_jack_detect
(
codec
,
&
ctx
->
kabylake_headset
);
ret
=
snd_soc_dapm_ignore_suspend
(
&
rtd
->
card
->
dapm
,
"SoC DMIC"
);
if
(
ret
)
{
dev_err
(
rtd
->
dev
,
"SoC DMIC ignore suspend failed %d
\n
"
,
ret
);
return
ret
;
}
return
ret
;
}
static
int
kabylake_hdmi1_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
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_HDMI1_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
)
{
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
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_hdmi3_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
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
);
return
0
;
}
static
unsigned
int
rates
[]
=
{
48000
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
.
count
=
ARRAY_SIZE
(
rates
),
.
list
=
rates
,
.
mask
=
0
,
};
static
unsigned
int
channels
[]
=
{
2
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
.
count
=
ARRAY_SIZE
(
channels
),
.
list
=
channels
,
.
mask
=
0
,
};
static
int
kbl_fe_startup
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
/*
* On this platform for PCM device we support,
* 48Khz
* stereo
* 16 bit audio
*/
runtime
->
hw
.
channels_max
=
2
;
snd_pcm_hw_constraint_list
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
&
constraints_channels
);
runtime
->
hw
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
;
snd_pcm_hw_constraint_msbits
(
runtime
,
0
,
16
,
16
);
snd_pcm_hw_constraint_list
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_RATE
,
&
constraints_rates
);
return
0
;
}
static
const
struct
snd_soc_ops
kabylake_rt5663_fe_ops
=
{
.
startup
=
kbl_fe_startup
,
};
static
int
kabylake_ssp_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_interval
*
rate
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_RATE
);
struct
snd_interval
*
channels
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_CHANNELS
);
struct
snd_mask
*
fmt
=
hw_param_mask
(
params
,
SNDRV_PCM_HW_PARAM_FORMAT
);
/* The ADSP will convert the FE rate to 48k, stereo */
rate
->
min
=
rate
->
max
=
48000
;
channels
->
min
=
channels
->
max
=
2
;
/* set SSP1 to 24 bit */
snd_mask_none
(
fmt
);
snd_mask_set
(
fmt
,
SNDRV_PCM_FORMAT_S24_LE
);
return
0
;
}
static
int
kabylake_rt5663_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
;
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
RT5663_SCLK_S_MCLK
,
24576000
,
SND_SOC_CLOCK_IN
);
/* 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
);
if
(
ret
<
0
)
dev_err
(
rtd
->
dev
,
"snd_soc_dai_set_sysclk err = %d
\n
"
,
ret
);
return
ret
;
}
static
struct
snd_soc_ops
kabylake_rt5663_ops
=
{
.
hw_params
=
kabylake_rt5663_hw_params
,
};
static
int
kabylake_dmic_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_interval
*
channels
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_CHANNELS
);
if
(
params_channels
(
params
)
==
2
||
DMIC_CH
(
dmic_constraints
)
==
2
)
channels
->
min
=
channels
->
max
=
2
;
else
channels
->
min
=
channels
->
max
=
4
;
return
0
;
}
static
unsigned
int
channels_dmic
[]
=
{
2
,
4
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_dmic_channels
=
{
.
count
=
ARRAY_SIZE
(
channels_dmic
),
.
list
=
channels_dmic
,
.
mask
=
0
,
};
static
const
unsigned
int
dmic_2ch
[]
=
{
2
,
};
static
const
struct
snd_pcm_hw_constraint_list
constraints_dmic_2ch
=
{
.
count
=
ARRAY_SIZE
(
dmic_2ch
),
.
list
=
dmic_2ch
,
.
mask
=
0
,
};
static
int
kabylake_dmic_startup
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
runtime
->
hw
.
channels_max
=
DMIC_CH
(
dmic_constraints
);
snd_pcm_hw_constraint_list
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
dmic_constraints
);
return
snd_pcm_hw_constraint_list
(
substream
->
runtime
,
0
,
SNDRV_PCM_HW_PARAM_RATE
,
&
constraints_rates
);
}
static
struct
snd_soc_ops
kabylake_dmic_ops
=
{
.
startup
=
kabylake_dmic_startup
,
};
static
unsigned
int
rates_16000
[]
=
{
16000
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_16000
=
{
.
count
=
ARRAY_SIZE
(
rates_16000
),
.
list
=
rates_16000
,
};
static
const
unsigned
int
ch_mono
[]
=
{
1
,
};
static
const
struct
snd_pcm_hw_constraint_list
constraints_refcap
=
{
.
count
=
ARRAY_SIZE
(
ch_mono
),
.
list
=
ch_mono
,
};
static
int
kabylake_refcap_startup
(
struct
snd_pcm_substream
*
substream
)
{
substream
->
runtime
->
hw
.
channels_max
=
1
;
snd_pcm_hw_constraint_list
(
substream
->
runtime
,
0
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
&
constraints_refcap
);
return
snd_pcm_hw_constraint_list
(
substream
->
runtime
,
0
,
SNDRV_PCM_HW_PARAM_RATE
,
&
constraints_16000
);
}
static
struct
snd_soc_ops
skylaye_refcap_ops
=
{
.
startup
=
kabylake_refcap_startup
,
};
/* kabylake digital audio interface glue - connects codec <--> CPU */
static
struct
snd_soc_dai_link
kabylake_dais
[]
=
{
/* Front End DAI links */
[
KBL_DPCM_AUDIO_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
,
.
init
=
kabylake_rt5663_fe_init
,
.
trigger
=
{
SND_SOC_DPCM_TRIGGER_POST
,
SND_SOC_DPCM_TRIGGER_POST
},
.
dpcm_playback
=
1
,
.
ops
=
&
kabylake_rt5663_fe_ops
,
},
[
KBL_DPCM_AUDIO_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_REF_CP
]
=
{
.
name
=
"Kbl Audio Reference cap"
,
.
stream_name
=
"Wake on Voice"
,
.
cpu_dai_name
=
"Reference Pin"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
platform_name
=
"0000:00:1f.3"
,
.
init
=
NULL
,
.
dpcm_capture
=
1
,
.
nonatomic
=
1
,
.
dynamic
=
1
,
.
ops
=
&
skylaye_refcap_ops
,
},
[
KBL_DPCM_AUDIO_DMIC_CP
]
=
{
.
name
=
"Kbl Audio DMIC cap"
,
.
stream_name
=
"dmiccap"
,
.
cpu_dai_name
=
"DMIC Pin"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
platform_name
=
"0000:00:1f.3"
,
.
init
=
NULL
,
.
dpcm_capture
=
1
,
.
nonatomic
=
1
,
.
dynamic
=
1
,
.
ops
=
&
kabylake_dmic_ops
,
},
[
KBL_DPCM_AUDIO_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_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
,
},
[
KBL_DPCM_AUDIO_HDMI3_PB
]
=
{
.
name
=
"Kbl HDMI Port3"
,
.
stream_name
=
"Hdmi3"
,
.
cpu_dai_name
=
"HDMI3 Pin"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
platform_name
=
"0000:00:1f.3"
,
.
trigger
=
{
SND_SOC_DPCM_TRIGGER_POST
,
SND_SOC_DPCM_TRIGGER_POST
},
.
dpcm_playback
=
1
,
.
init
=
NULL
,
.
nonatomic
=
1
,
.
dynamic
=
1
,
},
/* Back End DAI links */
{
/* SSP0 - Codec */
.
name
=
"SSP0-Codec"
,
.
id
=
0
,
.
cpu_dai_name
=
"SSP0 Pin"
,
.
platform_name
=
"0000:00:1f.3"
,
.
no_pcm
=
1
,
.
codecs
=
max98927_codec_components
,
.
num_codecs
=
ARRAY_SIZE
(
max98927_codec_components
),
.
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
,
.
dpcm_playback
=
1
,
},
{
/* SSP1 - Codec */
.
name
=
"SSP1-Codec"
,
.
id
=
1
,
.
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
=
"dmic01"
,
.
id
=
2
,
.
cpu_dai_name
=
"DMIC01 Pin"
,
.
codec_name
=
"dmic-codec"
,
.
codec_dai_name
=
"dmic-hifi"
,
.
platform_name
=
"0000:00:1f.3"
,
.
be_hw_params_fixup
=
kabylake_dmic_fixup
,
.
ignore_suspend
=
1
,
.
dpcm_capture
=
1
,
.
no_pcm
=
1
,
},
{
.
name
=
"iDisp1"
,
.
id
=
3
,
.
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_hdmi1_init
,
.
no_pcm
=
1
,
},
{
.
name
=
"iDisp2"
,
.
id
=
4
,
.
cpu_dai_name
=
"iDisp2 Pin"
,
.
codec_name
=
"ehdaudio0D2"
,
.
codec_dai_name
=
"intel-hdmi-hifi2"
,
.
platform_name
=
"0000:00:1f.3"
,
.
init
=
kabylake_hdmi2_init
,
.
dpcm_playback
=
1
,
.
no_pcm
=
1
,
},
{
.
name
=
"iDisp3"
,
.
id
=
5
,
.
cpu_dai_name
=
"iDisp3 Pin"
,
.
codec_name
=
"ehdaudio0D2"
,
.
codec_dai_name
=
"intel-hdmi-hifi3"
,
.
platform_name
=
"0000:00:1f.3"
,
.
init
=
kabylake_hdmi3_init
,
.
dpcm_playback
=
1
,
.
no_pcm
=
1
,
},
};
#define NAME_SIZE 32
static
int
kabylake_card_late_probe
(
struct
snd_soc_card
*
card
)
{
struct
kbl_rt5663_private
*
ctx
=
snd_soc_card_get_drvdata
(
card
);
struct
kbl_hdmi_pcm
*
pcm
;
int
err
,
i
=
0
;
char
jack_name
[
NAME_SIZE
];
list_for_each_entry
(
pcm
,
&
ctx
->
hdmi_pcm_list
,
head
)
{
snprintf
(
jack_name
,
sizeof
(
jack_name
),
"HDMI/DP, pcm=%d Jack"
,
pcm
->
device
);
err
=
snd_soc_card_jack_new
(
card
,
jack_name
,
SND_JACK_AVOUT
,
&
skylake_hdmi
[
i
],
NULL
,
0
);
if
(
err
)
return
err
;
err
=
hdac_hdmi_jack_init
(
pcm
->
codec_dai
,
pcm
->
device
,
&
skylake_hdmi
[
i
]);
if
(
err
<
0
)
return
err
;
i
++
;
}
return
0
;
}
/* kabylake audio machine driver for SPT + RT5663 */
static
struct
snd_soc_card
kabylake_audio_card
=
{
.
name
=
"kblrt5663max"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
kabylake_dais
,
.
num_links
=
ARRAY_SIZE
(
kabylake_dais
),
.
controls
=
kabylake_controls
,
.
num_controls
=
ARRAY_SIZE
(
kabylake_controls
),
.
dapm_widgets
=
kabylake_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
kabylake_widgets
),
.
dapm_routes
=
kabylake_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
kabylake_map
),
.
codec_conf
=
max98927_codec_conf
,
.
num_configs
=
ARRAY_SIZE
(
max98927_codec_conf
),
.
fully_routed
=
true
,
.
late_probe
=
kabylake_card_late_probe
,
};
static
int
kabylake_audio_probe
(
struct
platform_device
*
pdev
)
{
struct
kbl_rt5663_private
*
ctx
;
struct
skl_machine_pdata
*
pdata
;
ctx
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
ctx
),
GFP_ATOMIC
);
if
(
!
ctx
)
return
-
ENOMEM
;
INIT_LIST_HEAD
(
&
ctx
->
hdmi_pcm_list
);
kabylake_audio_card
.
dev
=
&
pdev
->
dev
;
snd_soc_card_set_drvdata
(
&
kabylake_audio_card
,
ctx
);
pdata
=
dev_get_drvdata
(
&
pdev
->
dev
);
if
(
pdata
)
dmic_constraints
=
pdata
->
dmic_num
==
2
?
&
constraints_dmic_2ch
:
&
constraints_dmic_channels
;
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
kabylake_audio_card
);
}
static
const
struct
platform_device_id
kbl_board_ids
[]
=
{
{
.
name
=
"kbl_rt5663_m98927"
},
{
}
};
static
struct
platform_driver
kabylake_audio
=
{
.
probe
=
kabylake_audio_probe
,
.
driver
=
{
.
name
=
"kbl_rt5663_m98927"
,
.
pm
=
&
snd_soc_pm_ops
,
},
.
id_table
=
kbl_board_ids
,
};
module_platform_driver
(
kabylake_audio
)
/* Module information */
MODULE_DESCRIPTION
(
"Audio Machine driver-RT5663 & MAX98927 in I2S mode"
);
MODULE_AUTHOR
(
"Naveen M <naveen.m@intel.com>"
);
MODULE_AUTHOR
(
"Harsha Priya <harshapriya.n@intel.com>"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_ALIAS
(
"platform:kbl_rt5663_m98927"
);
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
0 → 100644
浏览文件 @
51fa6a8f
/*
* Intel Kabylake I2S Machine Driver with MAXIM98927
* RT5514 and RT5663 Codecs
*
* Copyright (C) 2017, Intel Corporation. All rights reserved.
*
* Modified from:
* Intel Kabylake I2S Machine driver supporting MAXIM98927 and
* RT5663 codecs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License 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/platform_device.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "../../codecs/rt5514.h"
#include "../../codecs/rt5663.h"
#include "../../codecs/hdac_hdmi.h"
#include "../skylake/skl.h"
#define KBL_REALTEK_CODEC_DAI "rt5663-aif"
#define KBL_REALTEK_DMIC_CODEC_DAI "rt5514-aif1"
#define KBL_MAXIM_CODEC_DAI "max98927-aif1"
#define MAXIM_DEV0_NAME "i2c-MX98927:00"
#define MAXIM_DEV1_NAME "i2c-MX98927:01"
#define RT5514_DEV_NAME "i2c-10EC5514:00"
#define RT5663_DEV_NAME "i2c-10EC5663:00"
#define RT5514_AIF1_BCLK_FREQ (48000 * 8 * 16)
#define RT5514_AIF1_SYSCLK_FREQ 12288000
#define NAME_SIZE 32
#define DMIC_CH(p) p->list[p->count-1]
static
struct
snd_soc_card
kabylake_audio_card
;
static
const
struct
snd_pcm_hw_constraint_list
*
dmic_constraints
;
struct
kbl_hdmi_pcm
{
struct
list_head
head
;
struct
snd_soc_dai
*
codec_dai
;
int
device
;
};
struct
kbl_codec_private
{
struct
snd_soc_jack
kabylake_headset
;
struct
list_head
hdmi_pcm_list
;
struct
snd_soc_jack
kabylake_hdmi
[
2
];
};
enum
{
KBL_DPCM_AUDIO_PB
=
0
,
KBL_DPCM_AUDIO_CP
,
KBL_DPCM_AUDIO_DMIC_CP
,
KBL_DPCM_AUDIO_HDMI1_PB
,
KBL_DPCM_AUDIO_HDMI2_PB
,
};
static
const
struct
snd_kcontrol_new
kabylake_controls
[]
=
{
SOC_DAPM_PIN_SWITCH
(
"Headphone Jack"
),
SOC_DAPM_PIN_SWITCH
(
"Headset Mic"
),
SOC_DAPM_PIN_SWITCH
(
"Left Spk"
),
SOC_DAPM_PIN_SWITCH
(
"Right Spk"
),
SOC_DAPM_PIN_SWITCH
(
"DMIC"
),
};
static
const
struct
snd_soc_dapm_widget
kabylake_widgets
[]
=
{
SND_SOC_DAPM_HP
(
"Headphone Jack"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Headset Mic"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Left Spk"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Right Spk"
,
NULL
),
SND_SOC_DAPM_MIC
(
"DMIC"
,
NULL
),
SND_SOC_DAPM_SPK
(
"DP"
,
NULL
),
SND_SOC_DAPM_SPK
(
"HDMI"
,
NULL
),
};
static
const
struct
snd_soc_dapm_route
kabylake_map
[]
=
{
/* Headphones */
{
"Headphone Jack"
,
NULL
,
"HPOL"
},
{
"Headphone Jack"
,
NULL
,
"HPOR"
},
/* speaker */
{
"Left Spk"
,
NULL
,
"Left BE_OUT"
},
{
"Right Spk"
,
NULL
,
"Right BE_OUT"
},
/* other jacks */
{
"IN1P"
,
NULL
,
"Headset Mic"
},
{
"IN1N"
,
NULL
,
"Headset Mic"
},
{
"HDMI"
,
NULL
,
"hif5 Output"
},
{
"DP"
,
NULL
,
"hif6 Output"
},
/* CODEC BE connections */
{
"Left HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"Right HiFi Playback"
,
NULL
,
"ssp0 Tx"
},
{
"ssp0 Tx"
,
NULL
,
"codec0_out"
},
{
"AIF Playback"
,
NULL
,
"ssp1 Tx"
},
{
"ssp1 Tx"
,
NULL
,
"codec1_out"
},
{
"codec0_in"
,
NULL
,
"ssp1 Rx"
},
{
"ssp1 Rx"
,
NULL
,
"AIF Capture"
},
{
"codec1_in"
,
NULL
,
"ssp0 Rx"
},
{
"ssp0 Rx"
,
NULL
,
"AIF1 Capture"
},
/* DMIC */
{
"DMIC1L"
,
NULL
,
"DMIC"
},
{
"DMIC1R"
,
NULL
,
"DMIC"
},
{
"DMIC2L"
,
NULL
,
"DMIC"
},
{
"DMIC2R"
,
NULL
,
"DMIC"
},
{
"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
[]
=
{
{
.
dev_name
=
MAXIM_DEV0_NAME
,
.
name_prefix
=
"Right"
,
},
{
.
dev_name
=
MAXIM_DEV1_NAME
,
.
name_prefix
=
"Left"
,
},
};
static
struct
snd_soc_dai_link_component
ssp0_codec_components
[]
=
{
{
/* Left */
.
name
=
MAXIM_DEV0_NAME
,
.
dai_name
=
KBL_MAXIM_CODEC_DAI
,
},
{
/* Right */
.
name
=
MAXIM_DEV1_NAME
,
.
dai_name
=
KBL_MAXIM_CODEC_DAI
,
},
{
/*dmic */
.
name
=
RT5514_DEV_NAME
,
.
dai_name
=
KBL_REALTEK_DMIC_CODEC_DAI
,
},
};
static
int
kabylake_rt5663_fe_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
snd_soc_dapm_context
*
dapm
;
struct
snd_soc_component
*
component
=
rtd
->
cpu_dai
->
component
;
int
ret
;
dapm
=
snd_soc_component_get_dapm
(
component
);
ret
=
snd_soc_dapm_ignore_suspend
(
dapm
,
"Reference Capture"
);
if
(
ret
)
dev_err
(
rtd
->
dev
,
"Ref Cap -Ignore suspend failed = %d
\n
"
,
ret
);
return
ret
;
}
static
int
kabylake_rt5663_codec_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
int
ret
;
struct
kbl_codec_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
/*
* Headset buttons map to the google Reference headset.
* These can be configured by userspace.
*/
ret
=
snd_soc_card_jack_new
(
&
kabylake_audio_card
,
"Headset Jack"
,
SND_JACK_HEADSET
|
SND_JACK_BTN_0
|
SND_JACK_BTN_1
|
SND_JACK_BTN_2
|
SND_JACK_BTN_3
,
&
ctx
->
kabylake_headset
,
NULL
,
0
);
if
(
ret
)
{
dev_err
(
rtd
->
dev
,
"Headset Jack creation failed %d
\n
"
,
ret
);
return
ret
;
}
rt5663_set_jack_detect
(
codec
,
&
ctx
->
kabylake_headset
);
ret
=
snd_soc_dapm_ignore_suspend
(
&
rtd
->
card
->
dapm
,
"DMIC"
);
if
(
ret
)
dev_err
(
rtd
->
dev
,
"DMIC - Ignore suspend failed = %d
\n
"
,
ret
);
return
ret
;
}
static
int
kabylake_hdmi_init
(
struct
snd_soc_pcm_runtime
*
rtd
,
int
device
)
{
struct
kbl_codec_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
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
=
device
;
pcm
->
codec_dai
=
dai
;
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
return
0
;
}
static
int
kabylake_hdmi1_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
return
kabylake_hdmi_init
(
rtd
,
KBL_DPCM_AUDIO_HDMI1_PB
);
}
static
int
kabylake_hdmi2_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
return
kabylake_hdmi_init
(
rtd
,
KBL_DPCM_AUDIO_HDMI2_PB
);
}
static
const
unsigned
int
rates
[]
=
{
48000
,
};
static
const
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
.
count
=
ARRAY_SIZE
(
rates
),
.
list
=
rates
,
.
mask
=
0
,
};
static
const
unsigned
int
channels
[]
=
{
2
,
};
static
const
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
.
count
=
ARRAY_SIZE
(
channels
),
.
list
=
channels
,
.
mask
=
0
,
};
static
int
kbl_fe_startup
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
/*
* On this platform for PCM device we support,
* 48Khz
* stereo
* 16 bit audio
*/
runtime
->
hw
.
channels_max
=
2
;
snd_pcm_hw_constraint_list
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
&
constraints_channels
);
runtime
->
hw
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
;
snd_pcm_hw_constraint_msbits
(
runtime
,
0
,
16
,
16
);
snd_pcm_hw_constraint_list
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_RATE
,
&
constraints_rates
);
return
0
;
}
static
const
struct
snd_soc_ops
kabylake_rt5663_fe_ops
=
{
.
startup
=
kbl_fe_startup
,
};
static
int
kabylake_ssp_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_interval
*
rate
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_RATE
);
struct
snd_interval
*
channels
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_CHANNELS
);
struct
snd_mask
*
fmt
=
hw_param_mask
(
params
,
SNDRV_PCM_HW_PARAM_FORMAT
);
struct
snd_soc_dpcm
*
dpcm
=
container_of
(
params
,
struct
snd_soc_dpcm
,
hw_params
);
struct
snd_soc_dai_link
*
fe_dai_link
=
dpcm
->
fe
->
dai_link
;
struct
snd_soc_dai_link
*
be_dai_link
=
dpcm
->
be
->
dai_link
;
/*
* The ADSP will convert the FE rate to 48k, stereo, 24 bit
*/
if
(
!
strcmp
(
fe_dai_link
->
name
,
"Kbl Audio Port"
)
||
!
strcmp
(
fe_dai_link
->
name
,
"Kbl Audio Capture Port"
))
{
rate
->
min
=
rate
->
max
=
48000
;
channels
->
min
=
channels
->
max
=
2
;
snd_mask_none
(
fmt
);
snd_mask_set
(
fmt
,
SNDRV_PCM_FORMAT_S24_LE
);
}
else
if
(
!
strcmp
(
fe_dai_link
->
name
,
"Kbl Audio DMIC cap"
))
{
if
(
params_channels
(
params
)
==
2
||
DMIC_CH
(
dmic_constraints
)
==
2
)
channels
->
min
=
channels
->
max
=
2
;
else
channels
->
min
=
channels
->
max
=
4
;
}
/*
* The speaker on the SSP0 supports S16_LE and not S24_LE.
* thus changing the mask here
*/
if
(
!
strcmp
(
be_dai_link
->
name
,
"SSP0-Codec"
))
snd_mask_set
(
fmt
,
SNDRV_PCM_FORMAT_S16_LE
);
return
0
;
}
static
int
kabylake_rt5663_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
;
/* 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
);
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
RT5663_SCLK_S_MCLK
,
24576000
,
SND_SOC_CLOCK_IN
);
if
(
ret
<
0
)
dev_err
(
rtd
->
dev
,
"snd_soc_dai_set_sysclk err = %d
\n
"
,
ret
);
return
ret
;
}
static
struct
snd_soc_ops
kabylake_rt5663_ops
=
{
.
hw_params
=
kabylake_rt5663_hw_params
,
};
static
int
kabylake_ssp0_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
int
ret
=
0
,
j
;
for
(
j
=
0
;
j
<
rtd
->
num_codecs
;
j
++
)
{
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dais
[
j
];
if
(
!
strcmp
(
codec_dai
->
component
->
name
,
RT5514_DEV_NAME
))
{
ret
=
snd_soc_dai_set_tdm_slot
(
codec_dai
,
0xF
,
0
,
8
,
16
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"set TDM slot err:%d
\n
"
,
ret
);
return
ret
;
}
ret
=
snd_soc_dai_set_pll
(
codec_dai
,
0
,
RT5514_PLL1_S_BCLK
,
RT5514_AIF1_BCLK_FREQ
,
RT5514_AIF1_SYSCLK_FREQ
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"set bclk err: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
RT5514_SCLK_S_PLL1
,
RT5514_AIF1_SYSCLK_FREQ
,
SND_SOC_CLOCK_IN
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"set sclk err: %d
\n
"
,
ret
);
return
ret
;
}
}
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
,
0xF0
,
3
,
8
,
16
);
if
(
ret
<
0
)
{
dev_err
(
rtd
->
dev
,
"set TDM slot err:%d
\n
"
,
ret
);
return
ret
;
}
}
}
return
ret
;
}
static
struct
snd_soc_ops
kabylake_ssp0_ops
=
{
.
hw_params
=
kabylake_ssp0_hw_params
,
};
static
const
unsigned
int
channels_dmic
[]
=
{
4
,
};
static
const
struct
snd_pcm_hw_constraint_list
constraints_dmic_channels
=
{
.
count
=
ARRAY_SIZE
(
channels_dmic
),
.
list
=
channels_dmic
,
.
mask
=
0
,
};
static
const
unsigned
int
dmic_2ch
[]
=
{
4
,
};
static
const
struct
snd_pcm_hw_constraint_list
constraints_dmic_2ch
=
{
.
count
=
ARRAY_SIZE
(
dmic_2ch
),
.
list
=
dmic_2ch
,
.
mask
=
0
,
};
static
int
kabylake_dmic_startup
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
runtime
->
hw
.
channels_max
=
DMIC_CH
(
dmic_constraints
);
snd_pcm_hw_constraint_list
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
dmic_constraints
);
return
snd_pcm_hw_constraint_list
(
substream
->
runtime
,
0
,
SNDRV_PCM_HW_PARAM_RATE
,
&
constraints_rates
);
}
static
struct
snd_soc_ops
kabylake_dmic_ops
=
{
.
startup
=
kabylake_dmic_startup
,
};
/* kabylake digital audio interface glue - connects codec <--> CPU */
static
struct
snd_soc_dai_link
kabylake_dais
[]
=
{
/* Front End DAI links */
[
KBL_DPCM_AUDIO_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
,
.
init
=
kabylake_rt5663_fe_init
,
.
trigger
=
{
SND_SOC_DPCM_TRIGGER_POST
,
SND_SOC_DPCM_TRIGGER_POST
},
.
dpcm_playback
=
1
,
.
ops
=
&
kabylake_rt5663_fe_ops
,
},
[
KBL_DPCM_AUDIO_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_DMIC_CP
]
=
{
.
name
=
"Kbl Audio DMIC cap"
,
.
stream_name
=
"dmiccap"
,
.
cpu_dai_name
=
"DMIC Pin"
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
platform_name
=
"0000:00:1f.3"
,
.
init
=
NULL
,
.
dpcm_capture
=
1
,
.
nonatomic
=
1
,
.
dynamic
=
1
,
.
ops
=
&
kabylake_dmic_ops
,
},
[
KBL_DPCM_AUDIO_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_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 */
/* single Back end dai for both max speakers and dmic */
{
/* SSP0 - Codec */
.
name
=
"SSP0-Codec"
,
.
id
=
0
,
.
cpu_dai_name
=
"SSP0 Pin"
,
.
platform_name
=
"0000:00:1f.3"
,
.
no_pcm
=
1
,
.
codecs
=
ssp0_codec_components
,
.
num_codecs
=
ARRAY_SIZE
(
ssp0_codec_components
),
.
dai_fmt
=
SND_SOC_DAIFMT_DSP_B
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBS_CFS
,
.
ignore_pmdown_time
=
1
,
.
be_hw_params_fixup
=
kabylake_ssp_fixup
,
.
dpcm_playback
=
1
,
.
dpcm_capture
=
1
,
.
ops
=
&
kabylake_ssp0_ops
,
},
{
.
name
=
"SSP1-Codec"
,
.
id
=
1
,
.
cpu_dai_name
=
"SSP1 Pin"
,
.
platform_name
=
"0000:00:1f.3"
,
.
no_pcm
=
1
,
.
codec_name
=
RT5663_DEV_NAME
,
.
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
=
3
,
.
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_hdmi1_init
,
.
no_pcm
=
1
,
},
{
.
name
=
"iDisp2"
,
.
id
=
4
,
.
cpu_dai_name
=
"iDisp2 Pin"
,
.
codec_name
=
"ehdaudio0D2"
,
.
codec_dai_name
=
"intel-hdmi-hifi2"
,
.
platform_name
=
"0000:00:1f.3"
,
.
init
=
kabylake_hdmi2_init
,
.
dpcm_playback
=
1
,
.
no_pcm
=
1
,
},
};
static
int
kabylake_card_late_probe
(
struct
snd_soc_card
*
card
)
{
struct
kbl_codec_private
*
ctx
=
snd_soc_card_get_drvdata
(
card
);
struct
kbl_hdmi_pcm
*
pcm
;
int
err
,
i
=
0
;
char
jack_name
[
NAME_SIZE
];
list_for_each_entry
(
pcm
,
&
ctx
->
hdmi_pcm_list
,
head
)
{
err
=
snd_soc_card_jack_new
(
card
,
jack_name
,
SND_JACK_AVOUT
,
&
ctx
->
kabylake_hdmi
[
i
],
NULL
,
0
);
if
(
err
)
return
err
;
err
=
hdac_hdmi_jack_init
(
pcm
->
codec_dai
,
pcm
->
device
,
&
ctx
->
kabylake_hdmi
[
i
]);
if
(
err
<
0
)
return
err
;
i
++
;
}
return
0
;
}
/*
* kabylake audio machine driver for MAX98927 + RT5514 + RT5663
*/
static
struct
snd_soc_card
kabylake_audio_card
=
{
.
name
=
"kbl_r5514_5663_max"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
kabylake_dais
,
.
num_links
=
ARRAY_SIZE
(
kabylake_dais
),
.
controls
=
kabylake_controls
,
.
num_controls
=
ARRAY_SIZE
(
kabylake_controls
),
.
dapm_widgets
=
kabylake_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
kabylake_widgets
),
.
dapm_routes
=
kabylake_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
kabylake_map
),
.
codec_conf
=
max98927_codec_conf
,
.
num_configs
=
ARRAY_SIZE
(
max98927_codec_conf
),
.
fully_routed
=
true
,
.
late_probe
=
kabylake_card_late_probe
,
};
static
int
kabylake_audio_probe
(
struct
platform_device
*
pdev
)
{
struct
kbl_codec_private
*
ctx
;
struct
skl_machine_pdata
*
pdata
;
ctx
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
ctx
),
GFP_ATOMIC
);
if
(
!
ctx
)
return
-
ENOMEM
;
INIT_LIST_HEAD
(
&
ctx
->
hdmi_pcm_list
);
kabylake_audio_card
.
dev
=
&
pdev
->
dev
;
snd_soc_card_set_drvdata
(
&
kabylake_audio_card
,
ctx
);
pdata
=
dev_get_drvdata
(
&
pdev
->
dev
);
if
(
pdata
)
dmic_constraints
=
pdata
->
dmic_num
==
2
?
&
constraints_dmic_2ch
:
&
constraints_dmic_channels
;
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
kabylake_audio_card
);
}
static
const
struct
platform_device_id
kbl_board_ids
[]
=
{
{
.
name
=
"kbl_r5514_5663_max"
},
{
}
};
static
struct
platform_driver
kabylake_audio
=
{
.
probe
=
kabylake_audio_probe
,
.
driver
=
{
.
name
=
"kbl_r5514_5663_max"
,
.
pm
=
&
snd_soc_pm_ops
,
},
.
id_table
=
kbl_board_ids
,
};
module_platform_driver
(
kabylake_audio
)
/* Module information */
MODULE_DESCRIPTION
(
"Audio Machine driver-RT5663 RT5514 & MAX98927"
);
MODULE_AUTHOR
(
"Harsha Priya <harshapriya.n@intel.com>"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_ALIAS
(
"platform:kbl_r5514_5663_max"
);
sound/soc/intel/boards/skl_nau88l25_max98357a.c
浏览文件 @
51fa6a8f
...
...
@@ -266,21 +266,21 @@ static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
return
0
;
}
static
unsigned
int
rates
[]
=
{
static
const
unsigned
int
rates
[]
=
{
48000
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
.
count
=
ARRAY_SIZE
(
rates
),
.
list
=
rates
,
.
mask
=
0
,
};
static
unsigned
int
channels
[]
=
{
static
const
unsigned
int
channels
[]
=
{
2
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
.
count
=
ARRAY_SIZE
(
channels
),
.
list
=
channels
,
.
mask
=
0
,
...
...
@@ -348,11 +348,11 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
return
0
;
}
static
unsigned
int
channels_dmic
[]
=
{
static
const
unsigned
int
channels_dmic
[]
=
{
2
,
4
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_dmic_channels
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_dmic_channels
=
{
.
count
=
ARRAY_SIZE
(
channels_dmic
),
.
list
=
channels_dmic
,
.
mask
=
0
,
...
...
@@ -384,11 +384,11 @@ static const struct snd_soc_ops skylake_dmic_ops = {
.
startup
=
skylake_dmic_startup
,
};
static
unsigned
int
rates_16000
[]
=
{
static
const
unsigned
int
rates_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
),
.
list
=
rates_16000
,
};
...
...
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
浏览文件 @
51fa6a8f
...
...
@@ -297,21 +297,21 @@ static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
return
0
;
}
static
unsigned
int
rates
[]
=
{
static
const
unsigned
int
rates
[]
=
{
48000
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
.
count
=
ARRAY_SIZE
(
rates
),
.
list
=
rates
,
.
mask
=
0
,
};
static
unsigned
int
channels
[]
=
{
static
const
unsigned
int
channels
[]
=
{
2
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
.
count
=
ARRAY_SIZE
(
channels
),
.
list
=
channels
,
.
mask
=
0
,
...
...
@@ -397,11 +397,11 @@ static const struct snd_soc_ops skylake_nau8825_ops = {
.
hw_params
=
skylake_nau8825_hw_params
,
};
static
unsigned
int
channels_dmic
[]
=
{
static
const
unsigned
int
channels_dmic
[]
=
{
2
,
4
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_dmic_channels
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_dmic_channels
=
{
.
count
=
ARRAY_SIZE
(
channels_dmic
),
.
list
=
channels_dmic
,
.
mask
=
0
,
...
...
@@ -433,11 +433,11 @@ static const struct snd_soc_ops skylake_dmic_ops = {
.
startup
=
skylake_dmic_startup
,
};
static
unsigned
int
rates_16000
[]
=
{
static
const
unsigned
int
rates_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
),
.
list
=
rates_16000
,
};
...
...
sound/soc/intel/boards/skl_rt286.c
浏览文件 @
51fa6a8f
...
...
@@ -43,6 +43,7 @@ struct skl_rt286_private {
enum
{
SKL_DPCM_AUDIO_PB
=
0
,
SKL_DPCM_AUDIO_DB_PB
,
SKL_DPCM_AUDIO_CP
,
SKL_DPCM_AUDIO_REF_CP
,
SKL_DPCM_AUDIO_DMIC_CP
,
...
...
@@ -165,21 +166,21 @@ static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd)
return
0
;
}
static
unsigned
int
rates
[]
=
{
static
const
unsigned
int
rates
[]
=
{
48000
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_rates
=
{
.
count
=
ARRAY_SIZE
(
rates
),
.
list
=
rates
,
.
mask
=
0
,
};
static
unsigned
int
channels
[]
=
{
static
const
unsigned
int
channels
[]
=
{
2
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_channels
=
{
.
count
=
ARRAY_SIZE
(
channels
),
.
list
=
channels
,
.
mask
=
0
,
...
...
@@ -264,11 +265,11 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
return
0
;
}
static
unsigned
int
channels_dmic
[]
=
{
static
const
unsigned
int
channels_dmic
[]
=
{
2
,
4
,
};
static
struct
snd_pcm_hw_constraint_list
constraints_dmic_channels
=
{
static
const
struct
snd_pcm_hw_constraint_list
constraints_dmic_channels
=
{
.
count
=
ARRAY_SIZE
(
channels_dmic
),
.
list
=
channels_dmic
,
.
mask
=
0
,
...
...
@@ -310,6 +311,23 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
.
dpcm_playback
=
1
,
.
ops
=
&
skylake_rt286_fe_ops
,
},
[
SKL_DPCM_AUDIO_DB_PB
]
=
{
.
name
=
"Skl Deepbuffer Port"
,
.
stream_name
=
"Deep Buffer Audio"
,
.
cpu_dai_name
=
"Deepbuffer Pin"
,
.
platform_name
=
"0000:00:1f.3"
,
.
nonatomic
=
1
,
.
dynamic
=
1
,
.
codec_name
=
"snd-soc-dummy"
,
.
codec_dai_name
=
"snd-soc-dummy-dai"
,
.
trigger
=
{
SND_SOC_DPCM_TRIGGER_POST
,
SND_SOC_DPCM_TRIGGER_POST
},
.
dpcm_playback
=
1
,
.
ops
=
&
skylake_rt286_fe_ops
,
},
[
SKL_DPCM_AUDIO_CP
]
=
{
.
name
=
"Skl Audio Capture Port"
,
.
stream_name
=
"Audio Record"
,
...
...
sound/soc/intel/common/sst-acpi.h
浏览文件 @
51fa6a8f
...
...
@@ -43,6 +43,9 @@ static inline bool sst_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
/* acpi match */
struct
sst_acpi_mach
*
sst_acpi_find_machine
(
struct
sst_acpi_mach
*
machines
);
/* acpi check hid */
bool
sst_acpi_check_hid
(
const
u8
hid
[
ACPI_ID_LEN
]);
/* Descriptor for SST ASoC machine driver */
struct
sst_acpi_mach
{
/* ACPI ID for the matching machine driver. Audio codec for instance */
...
...
@@ -55,5 +58,25 @@ struct sst_acpi_mach {
/* board name */
const
char
*
board
;
struct
sst_acpi_mach
*
(
*
machine_quirk
)(
void
*
arg
);
const
void
*
quirk_data
;
void
*
pdata
;
};
#define SST_ACPI_MAX_CODECS 3
/**
* struct sst_codecs: Structure to hold secondary codec information apart from
* the matched one, this data will be passed to the quirk function to match
* with the ACPI detected devices
*
* @num_codecs: number of secondary codecs used in the platform
* @codecs: holds the codec IDs
*
*/
struct
sst_codecs
{
int
num_codecs
;
u8
codecs
[
SST_ACPI_MAX_CODECS
][
ACPI_ID_LEN
];
};
/* check all codecs */
struct
sst_acpi_mach
*
sst_acpi_codec_list
(
void
*
arg
);
sound/soc/intel/common/sst-dsp-priv.h
浏览文件 @
51fa6a8f
...
...
@@ -77,6 +77,10 @@ struct sst_addr {
u32
dram_offset
;
u32
dsp_iram_offset
;
u32
dsp_dram_offset
;
u32
sram0_base
;
u32
sram1_base
;
u32
w0_stat_sz
;
u32
w0_up_sz
;
void
__iomem
*
lpe
;
void
__iomem
*
shim
;
void
__iomem
*
pci_cfg
;
...
...
sound/soc/intel/common/sst-match-acpi.c
浏览文件 @
51fa6a8f
...
...
@@ -63,16 +63,33 @@ static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
return
AE_OK
;
}
bool
sst_acpi_check_hid
(
const
u8
hid
[
ACPI_ID_LEN
])
{
acpi_status
status
;
bool
found
=
false
;
status
=
acpi_get_devices
(
hid
,
sst_acpi_mach_match
,
&
found
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
return
false
;
return
found
;
}
EXPORT_SYMBOL_GPL
(
sst_acpi_check_hid
);
struct
sst_acpi_mach
*
sst_acpi_find_machine
(
struct
sst_acpi_mach
*
machines
)
{
struct
sst_acpi_mach
*
mach
;
bool
found
=
false
;
for
(
mach
=
machines
;
mach
->
id
[
0
];
mach
++
)
if
(
ACPI_SUCCESS
(
acpi_get_devices
(
mach
->
id
,
sst_acpi_mach_match
,
&
found
,
NULL
))
&&
found
)
return
mach
;
for
(
mach
=
machines
;
mach
->
id
[
0
];
mach
++
)
{
if
(
sst_acpi_check_hid
(
mach
->
id
)
==
true
)
{
if
(
mach
->
machine_quirk
==
NULL
)
return
mach
;
if
(
mach
->
machine_quirk
(
mach
)
!=
NULL
)
return
mach
;
}
}
return
NULL
;
}
EXPORT_SYMBOL_GPL
(
sst_acpi_find_machine
);
...
...
@@ -134,5 +151,23 @@ bool sst_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
}
EXPORT_SYMBOL_GPL
(
sst_acpi_find_package_from_hid
);
struct
sst_acpi_mach
*
sst_acpi_codec_list
(
void
*
arg
)
{
struct
sst_acpi_mach
*
mach
=
arg
;
struct
sst_codecs
*
codec_list
=
(
struct
sst_codecs
*
)
mach
->
quirk_data
;
int
i
;
if
(
mach
->
quirk_data
==
NULL
)
return
mach
;
for
(
i
=
0
;
i
<
codec_list
->
num_codecs
;
i
++
)
{
if
(
sst_acpi_check_hid
(
codec_list
->
codecs
[
i
])
!=
true
)
return
NULL
;
}
return
mach
;
}
EXPORT_SYMBOL_GPL
(
sst_acpi_codec_list
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_DESCRIPTION
(
"Intel Common ACPI Match module"
);
sound/soc/intel/skylake/Makefile
浏览文件 @
51fa6a8f
snd-soc-skl-objs
:=
skl.o skl-pcm.o skl-nhlt.o skl-messages.o
\
skl-topology.o
ifdef
CONFIG_DEBUG_FS
snd-soc-skl-objs
+=
skl-debug.o
endif
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE)
+=
snd-soc-skl.o
# Skylake IPC Support
...
...
sound/soc/intel/skylake/bxt-sst.c
浏览文件 @
51fa6a8f
...
...
@@ -573,6 +573,10 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
sst
->
fw_ops
=
bxt_fw_ops
;
sst
->
addr
.
lpe
=
mmio_base
;
sst
->
addr
.
shim
=
mmio_base
;
sst
->
addr
.
sram0_base
=
BXT_ADSP_SRAM0_BASE
;
sst
->
addr
.
sram1_base
=
BXT_ADSP_SRAM1_BASE
;
sst
->
addr
.
w0_stat_sz
=
SKL_ADSP_W0_STAT_SZ
;
sst
->
addr
.
w0_up_sz
=
SKL_ADSP_W0_UP_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
);
...
...
sound/soc/intel/skylake/skl-debug.c
0 → 100644
浏览文件 @
51fa6a8f
/*
* skl-debug.c - Debugfs for skl driver
*
* Copyright (C) 2016-17 Intel Corp
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/pci.h>
#include <linux/debugfs.h>
#include "skl.h"
#include "skl-sst-dsp.h"
#include "skl-sst-ipc.h"
#include "skl-tplg-interface.h"
#include "skl-topology.h"
#include "../common/sst-dsp-priv.h"
#define MOD_BUF PAGE_SIZE
#define FW_REG_BUF PAGE_SIZE
#define FW_REG_SIZE 0x60
struct
skl_debug
{
struct
skl
*
skl
;
struct
device
*
dev
;
struct
dentry
*
fs
;
struct
dentry
*
modules
;
u8
fw_read_buff
[
FW_REG_BUF
];
};
static
ssize_t
skl_print_pins
(
struct
skl_module_pin
*
m_pin
,
char
*
buf
,
int
max_pin
,
ssize_t
size
,
bool
direction
)
{
int
i
;
ssize_t
ret
=
0
;
for
(
i
=
0
;
i
<
max_pin
;
i
++
)
ret
+=
snprintf
(
buf
+
size
,
MOD_BUF
-
size
,
"%s %d
\n\t
Module %d
\n\t
Instance %d
\n\t
"
"In-used %s
\n\t
Type %s
\n
"
"
\t
State %d
\n\t
Index %d
\n
"
,
direction
?
"Input Pin:"
:
"Output Pin:"
,
i
,
m_pin
[
i
].
id
.
module_id
,
m_pin
[
i
].
id
.
instance_id
,
m_pin
[
i
].
in_use
?
"Used"
:
"Unused"
,
m_pin
[
i
].
is_dynamic
?
"Dynamic"
:
"Static"
,
m_pin
[
i
].
pin_state
,
i
);
return
ret
;
}
static
ssize_t
skl_print_fmt
(
struct
skl_module_fmt
*
fmt
,
char
*
buf
,
ssize_t
size
,
bool
direction
)
{
return
snprintf
(
buf
+
size
,
MOD_BUF
-
size
,
"%s
\n\t
Ch %d
\n\t
Freq %d
\n\t
Bit depth %d
\n\t
"
"Valid bit depth %d
\n\t
Ch config %#x
\n\t
Interleaving %d
\n\t
"
"Sample Type %d
\n\t
Ch Map %#x
\n
"
,
direction
?
"Input Format:"
:
"Output Format:"
,
fmt
->
channels
,
fmt
->
s_freq
,
fmt
->
bit_depth
,
fmt
->
valid_bit_depth
,
fmt
->
ch_cfg
,
fmt
->
interleaving_style
,
fmt
->
sample_type
,
fmt
->
ch_map
);
}
static
ssize_t
module_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
skl_module_cfg
*
mconfig
=
file
->
private_data
;
char
*
buf
;
ssize_t
ret
;
buf
=
kzalloc
(
MOD_BUF
,
GFP_KERNEL
);
if
(
!
buf
)
return
-
ENOMEM
;
ret
=
snprintf
(
buf
,
MOD_BUF
,
"Module:
\n\t
UUID %pUL
\n\t
Module id %d
\n
"
"
\t
Instance id %d
\n\t
Pvt_id %d
\n
"
,
mconfig
->
guid
,
mconfig
->
id
.
module_id
,
mconfig
->
id
.
instance_id
,
mconfig
->
id
.
pvt_id
);
ret
+=
snprintf
(
buf
+
ret
,
MOD_BUF
-
ret
,
"Resources:
\n\t
MCPS %#x
\n\t
IBS %#x
\n\t
OBS %#x
\t\n
"
,
mconfig
->
mcps
,
mconfig
->
ibs
,
mconfig
->
obs
);
ret
+=
snprintf
(
buf
+
ret
,
MOD_BUF
-
ret
,
"Module data:
\n\t
Core %d
\n\t
In queue %d
\n\t
"
"Out queue %d
\n\t
Type %s
\n
"
,
mconfig
->
core_id
,
mconfig
->
max_in_queue
,
mconfig
->
max_out_queue
,
mconfig
->
is_loadable
?
"loadable"
:
"inbuilt"
);
ret
+=
skl_print_fmt
(
mconfig
->
in_fmt
,
buf
,
ret
,
true
);
ret
+=
skl_print_fmt
(
mconfig
->
out_fmt
,
buf
,
ret
,
false
);
ret
+=
snprintf
(
buf
+
ret
,
MOD_BUF
-
ret
,
"Fixup:
\n\t
Params %#x
\n\t
Converter %#x
\n
"
,
mconfig
->
params_fixup
,
mconfig
->
converter
);
ret
+=
snprintf
(
buf
+
ret
,
MOD_BUF
-
ret
,
"Module Gateway:
\n\t
Type %#x
\n\t
Vbus %#x
\n\t
HW conn %#x
\n\t
Slot %#x
\n
"
,
mconfig
->
dev_type
,
mconfig
->
vbus_id
,
mconfig
->
hw_conn_type
,
mconfig
->
time_slot
);
ret
+=
snprintf
(
buf
+
ret
,
MOD_BUF
-
ret
,
"Pipeline:
\n\t
ID %d
\n\t
Priority %d
\n\t
Conn Type %d
\n\t
"
"Pages %#x
\n
"
,
mconfig
->
pipe
->
ppl_id
,
mconfig
->
pipe
->
pipe_priority
,
mconfig
->
pipe
->
conn_type
,
mconfig
->
pipe
->
memory_pages
);
ret
+=
snprintf
(
buf
+
ret
,
MOD_BUF
-
ret
,
"
\t
Params:
\n\t\t
Host DMA %d
\n\t\t
Link DMA %d
\n
"
,
mconfig
->
pipe
->
p_params
->
host_dma_id
,
mconfig
->
pipe
->
p_params
->
link_dma_id
);
ret
+=
snprintf
(
buf
+
ret
,
MOD_BUF
-
ret
,
"
\t
PCM params:
\n\t\t
Ch %d
\n\t\t
Freq %d
\n\t\t
Format %d
\n
"
,
mconfig
->
pipe
->
p_params
->
ch
,
mconfig
->
pipe
->
p_params
->
s_freq
,
mconfig
->
pipe
->
p_params
->
s_fmt
);
ret
+=
snprintf
(
buf
+
ret
,
MOD_BUF
-
ret
,
"
\t
Link %#x
\n\t
Stream %#x
\n
"
,
mconfig
->
pipe
->
p_params
->
linktype
,
mconfig
->
pipe
->
p_params
->
stream
);
ret
+=
snprintf
(
buf
+
ret
,
MOD_BUF
-
ret
,
"
\t
State %d
\n\t
Passthru %s
\n
"
,
mconfig
->
pipe
->
state
,
mconfig
->
pipe
->
passthru
?
"true"
:
"false"
);
ret
+=
skl_print_pins
(
mconfig
->
m_in_pin
,
buf
,
mconfig
->
max_in_queue
,
ret
,
true
);
ret
+=
skl_print_pins
(
mconfig
->
m_out_pin
,
buf
,
mconfig
->
max_out_queue
,
ret
,
false
);
ret
+=
snprintf
(
buf
+
ret
,
MOD_BUF
-
ret
,
"Other:
\n\t
Domain %d
\n\t
Homogenous Input %s
\n\t
"
"Homogenous Output %s
\n\t
In Queue Mask %d
\n\t
"
"Out Queue Mask %d
\n\t
DMA ID %d
\n\t
Mem Pages %d
\n\t
"
"Module Type %d
\n\t
Module State %d
\n
"
,
mconfig
->
domain
,
mconfig
->
homogenous_inputs
?
"true"
:
"false"
,
mconfig
->
homogenous_outputs
?
"true"
:
"false"
,
mconfig
->
in_queue_mask
,
mconfig
->
out_queue_mask
,
mconfig
->
dma_id
,
mconfig
->
mem_pages
,
mconfig
->
m_state
,
mconfig
->
m_type
);
ret
=
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
ret
);
kfree
(
buf
);
return
ret
;
}
static
const
struct
file_operations
mcfg_fops
=
{
.
open
=
simple_open
,
.
read
=
module_read
,
.
llseek
=
default_llseek
,
};
void
skl_debug_init_module
(
struct
skl_debug
*
d
,
struct
snd_soc_dapm_widget
*
w
,
struct
skl_module_cfg
*
mconfig
)
{
if
(
!
debugfs_create_file
(
w
->
name
,
0444
,
d
->
modules
,
mconfig
,
&
mcfg_fops
))
dev_err
(
d
->
dev
,
"%s: module debugfs init failed
\n
"
,
w
->
name
);
}
static
ssize_t
fw_softreg_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
skl_debug
*
d
=
file
->
private_data
;
struct
sst_dsp
*
sst
=
d
->
skl
->
skl_sst
->
dsp
;
size_t
w0_stat_sz
=
sst
->
addr
.
w0_stat_sz
;
void
__iomem
*
in_base
=
sst
->
mailbox
.
in_base
;
void
__iomem
*
fw_reg_addr
;
unsigned
int
offset
;
char
*
tmp
;
ssize_t
ret
=
0
;
tmp
=
kzalloc
(
FW_REG_BUF
,
GFP_KERNEL
);
if
(
!
tmp
)
return
-
ENOMEM
;
fw_reg_addr
=
in_base
-
w0_stat_sz
;
memset
(
d
->
fw_read_buff
,
0
,
FW_REG_BUF
);
if
(
w0_stat_sz
>
0
)
__iowrite32_copy
(
d
->
fw_read_buff
,
fw_reg_addr
,
w0_stat_sz
>>
2
);
for
(
offset
=
0
;
offset
<
FW_REG_SIZE
;
offset
+=
16
)
{
ret
+=
snprintf
(
tmp
+
ret
,
FW_REG_BUF
-
ret
,
"%#.4x: "
,
offset
);
hex_dump_to_buffer
(
d
->
fw_read_buff
+
offset
,
16
,
16
,
4
,
tmp
+
ret
,
FW_REG_BUF
-
ret
,
0
);
ret
+=
strlen
(
tmp
+
ret
);
/* print newline for each offset */
if
(
FW_REG_BUF
-
ret
>
0
)
tmp
[
ret
++
]
=
'\n'
;
}
ret
=
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
tmp
,
ret
);
kfree
(
tmp
);
return
ret
;
}
static
const
struct
file_operations
soft_regs_ctrl_fops
=
{
.
open
=
simple_open
,
.
read
=
fw_softreg_read
,
.
llseek
=
default_llseek
,
};
struct
skl_debug
*
skl_debugfs_init
(
struct
skl
*
skl
)
{
struct
skl_debug
*
d
;
d
=
devm_kzalloc
(
&
skl
->
pci
->
dev
,
sizeof
(
*
d
),
GFP_KERNEL
);
if
(
!
d
)
return
NULL
;
/* create the debugfs dir with platform component's debugfs as parent */
d
->
fs
=
debugfs_create_dir
(
"dsp"
,
skl
->
platform
->
component
.
debugfs_root
);
if
(
IS_ERR
(
d
->
fs
)
||
!
d
->
fs
)
{
dev_err
(
&
skl
->
pci
->
dev
,
"debugfs root creation failed
\n
"
);
return
NULL
;
}
d
->
skl
=
skl
;
d
->
dev
=
&
skl
->
pci
->
dev
;
/* now create the module dir */
d
->
modules
=
debugfs_create_dir
(
"modules"
,
d
->
fs
);
if
(
IS_ERR
(
d
->
modules
)
||
!
d
->
modules
)
{
dev_err
(
&
skl
->
pci
->
dev
,
"modules debugfs create failed
\n
"
);
goto
err
;
}
if
(
!
debugfs_create_file
(
"fw_soft_regs_rd"
,
0444
,
d
->
fs
,
d
,
&
soft_regs_ctrl_fops
))
{
dev_err
(
d
->
dev
,
"fw soft regs control debugfs init failed
\n
"
);
goto
err
;
}
return
d
;
err:
debugfs_remove_recursive
(
d
->
fs
);
return
NULL
;
}
void
skl_debugfs_exit
(
struct
skl_debug
*
d
)
{
debugfs_remove_recursive
(
d
->
fs
);
kfree
(
d
);
}
sound/soc/intel/skylake/skl-messages.c
浏览文件 @
51fa6a8f
...
...
@@ -507,6 +507,8 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
struct
skl_module_cfg
*
mconfig
,
struct
skl_cpr_cfg
*
cpr_mconfig
)
{
u32
dma_io_buf
;
cpr_mconfig
->
gtw_cfg
.
node_id
=
skl_get_node_id
(
ctx
,
mconfig
);
if
(
cpr_mconfig
->
gtw_cfg
.
node_id
==
SKL_NON_GATEWAY_CPR_NODE_ID
)
{
...
...
@@ -514,10 +516,29 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
return
;
}
if
(
SKL_CONN_SOURCE
==
mconfig
->
hw_conn_type
)
cpr_mconfig
->
gtw_cfg
.
dma_buffer_size
=
2
*
mconfig
->
obs
;
else
cpr_mconfig
->
gtw_cfg
.
dma_buffer_size
=
2
*
mconfig
->
ibs
;
switch
(
mconfig
->
hw_conn_type
)
{
case
SKL_CONN_SOURCE
:
if
(
mconfig
->
dev_type
==
SKL_DEVICE_HDAHOST
)
dma_io_buf
=
mconfig
->
ibs
;
else
dma_io_buf
=
mconfig
->
obs
;
break
;
case
SKL_CONN_SINK
:
if
(
mconfig
->
dev_type
==
SKL_DEVICE_HDAHOST
)
dma_io_buf
=
mconfig
->
obs
;
else
dma_io_buf
=
mconfig
->
ibs
;
break
;
default:
dev_warn
(
ctx
->
dev
,
"wrong connection type: %d
\n
"
,
mconfig
->
hw_conn_type
);
return
;
}
cpr_mconfig
->
gtw_cfg
.
dma_buffer_size
=
mconfig
->
dma_buffer_size
*
dma_io_buf
;
cpr_mconfig
->
cpr_feature_mask
=
0
;
cpr_mconfig
->
gtw_cfg
.
config_length
=
0
;
...
...
@@ -707,6 +728,7 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx,
return
param_size
;
case
SKL_MODULE_TYPE_BASE_OUTFMT
:
case
SKL_MODULE_TYPE_MIC_SELECT
:
case
SKL_MODULE_TYPE_KPB
:
return
sizeof
(
struct
skl_base_outfmt_cfg
);
...
...
@@ -761,6 +783,7 @@ static int skl_set_module_format(struct skl_sst *ctx,
break
;
case
SKL_MODULE_TYPE_BASE_OUTFMT
:
case
SKL_MODULE_TYPE_MIC_SELECT
:
case
SKL_MODULE_TYPE_KPB
:
skl_set_base_outfmt_format
(
ctx
,
module_config
,
*
param_data
);
break
;
...
...
sound/soc/intel/skylake/skl-pcm.c
浏览文件 @
51fa6a8f
...
...
@@ -1249,12 +1249,16 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
pm_runtime_get_sync
(
platform
->
dev
);
if
((
ebus_to_hbus
(
ebus
))
->
ppcap
)
{
skl
->
platform
=
platform
;
/* init debugfs */
skl
->
debugfs
=
skl_debugfs_init
(
skl
);
ret
=
skl_tplg_init
(
platform
,
ebus
);
if
(
ret
<
0
)
{
dev_err
(
platform
->
dev
,
"Failed to init topology!
\n
"
);
return
ret
;
}
skl
->
platform
=
platform
;
/* load the firmwares, since all is set */
ops
=
skl_get_dsp_ops
(
skl
->
pci
->
device
);
...
...
sound/soc/intel/skylake/skl-sst.c
浏览文件 @
51fa6a8f
...
...
@@ -553,6 +553,11 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
sst
=
skl
->
dsp
;
sst
->
addr
.
lpe
=
mmio_base
;
sst
->
addr
.
shim
=
mmio_base
;
sst
->
addr
.
sram0_base
=
SKL_ADSP_SRAM0_BASE
;
sst
->
addr
.
sram1_base
=
SKL_ADSP_SRAM1_BASE
;
sst
->
addr
.
w0_stat_sz
=
SKL_ADSP_W0_STAT_SZ
;
sst
->
addr
.
w0_up_sz
=
SKL_ADSP_W0_UP_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
);
...
...
sound/soc/intel/skylake/skl-topology.c
浏览文件 @
51fa6a8f
...
...
@@ -36,6 +36,19 @@
#define SKL_IN_DIR_BIT_MASK BIT(0)
#define SKL_PIN_COUNT_MASK GENMASK(7, 4)
static
const
int
mic_mono_list
[]
=
{
0
,
1
,
2
,
3
,
};
static
const
int
mic_stereo_list
[][
SKL_CH_STEREO
]
=
{
{
0
,
1
},
{
0
,
2
},
{
0
,
3
},
{
1
,
2
},
{
1
,
3
},
{
2
,
3
},
};
static
const
int
mic_trio_list
[][
SKL_CH_TRIO
]
=
{
{
0
,
1
,
2
},
{
0
,
1
,
3
},
{
0
,
2
,
3
},
{
1
,
2
,
3
},
};
static
const
int
mic_quatro_list
[][
SKL_CH_QUATRO
]
=
{
{
0
,
1
,
2
,
3
},
};
void
skl_tplg_d0i3_get
(
struct
skl
*
skl
,
enum
d0i3_capability
caps
)
{
struct
skl_d0i3_data
*
d0i3
=
&
skl
->
skl_sst
->
d0i3
;
...
...
@@ -1314,6 +1327,111 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
return
0
;
}
static
int
skl_tplg_mic_control_get
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_soc_dapm_widget
*
w
=
snd_soc_dapm_kcontrol_widget
(
kcontrol
);
struct
skl_module_cfg
*
mconfig
=
w
->
priv
;
struct
soc_enum
*
ec
=
(
struct
soc_enum
*
)
kcontrol
->
private_value
;
u32
ch_type
=
*
((
u32
*
)
ec
->
dobj
.
private
);
if
(
mconfig
->
dmic_ch_type
==
ch_type
)
ucontrol
->
value
.
enumerated
.
item
[
0
]
=
mconfig
->
dmic_ch_combo_index
;
else
ucontrol
->
value
.
enumerated
.
item
[
0
]
=
0
;
return
0
;
}
static
int
skl_fill_mic_sel_params
(
struct
skl_module_cfg
*
mconfig
,
struct
skl_mic_sel_config
*
mic_cfg
,
struct
device
*
dev
)
{
struct
skl_specific_cfg
*
sp_cfg
=
&
mconfig
->
formats_config
;
sp_cfg
->
caps_size
=
sizeof
(
struct
skl_mic_sel_config
);
sp_cfg
->
set_params
=
SKL_PARAM_SET
;
sp_cfg
->
param_id
=
0x00
;
if
(
!
sp_cfg
->
caps
)
{
sp_cfg
->
caps
=
devm_kzalloc
(
dev
,
sp_cfg
->
caps_size
,
GFP_KERNEL
);
if
(
!
sp_cfg
->
caps
)
return
-
ENOMEM
;
}
mic_cfg
->
mic_switch
=
SKL_MIC_SEL_SWITCH
;
mic_cfg
->
flags
=
0
;
memcpy
(
sp_cfg
->
caps
,
mic_cfg
,
sp_cfg
->
caps_size
);
return
0
;
}
static
int
skl_tplg_mic_control_set
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_soc_dapm_widget
*
w
=
snd_soc_dapm_kcontrol_widget
(
kcontrol
);
struct
skl_module_cfg
*
mconfig
=
w
->
priv
;
struct
skl_mic_sel_config
mic_cfg
=
{
0
};
struct
soc_enum
*
ec
=
(
struct
soc_enum
*
)
kcontrol
->
private_value
;
u32
ch_type
=
*
((
u32
*
)
ec
->
dobj
.
private
);
const
int
*
list
;
u8
in_ch
,
out_ch
,
index
;
mconfig
->
dmic_ch_type
=
ch_type
;
mconfig
->
dmic_ch_combo_index
=
ucontrol
->
value
.
enumerated
.
item
[
0
];
/* enum control index 0 is INVALID, so no channels to be set */
if
(
mconfig
->
dmic_ch_combo_index
==
0
)
return
0
;
/* No valid channel selection map for index 0, so offset by 1 */
index
=
mconfig
->
dmic_ch_combo_index
-
1
;
switch
(
ch_type
)
{
case
SKL_CH_MONO
:
if
(
mconfig
->
dmic_ch_combo_index
>
ARRAY_SIZE
(
mic_mono_list
))
return
-
EINVAL
;
list
=
&
mic_mono_list
[
index
];
break
;
case
SKL_CH_STEREO
:
if
(
mconfig
->
dmic_ch_combo_index
>
ARRAY_SIZE
(
mic_stereo_list
))
return
-
EINVAL
;
list
=
mic_stereo_list
[
index
];
break
;
case
SKL_CH_TRIO
:
if
(
mconfig
->
dmic_ch_combo_index
>
ARRAY_SIZE
(
mic_trio_list
))
return
-
EINVAL
;
list
=
mic_trio_list
[
index
];
break
;
case
SKL_CH_QUATRO
:
if
(
mconfig
->
dmic_ch_combo_index
>
ARRAY_SIZE
(
mic_quatro_list
))
return
-
EINVAL
;
list
=
mic_quatro_list
[
index
];
break
;
default:
dev_err
(
w
->
dapm
->
dev
,
"Invalid channel %d for mic_select module
\n
"
,
ch_type
);
return
-
EINVAL
;
}
/* channel type enum map to number of chanels for that type */
for
(
out_ch
=
0
;
out_ch
<
ch_type
;
out_ch
++
)
{
in_ch
=
list
[
out_ch
];
mic_cfg
.
blob
[
out_ch
][
in_ch
]
=
SKL_DEFAULT_MIC_SEL_GAIN
;
}
return
skl_fill_mic_sel_params
(
mconfig
,
&
mic_cfg
,
w
->
dapm
->
dev
);
}
/*
* Fill the dma id for host and link. In case of passthrough
* pipeline, this will both host and link in the same
...
...
@@ -1666,6 +1784,14 @@ static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
skl_tplg_tlv_control_set
},
};
static
const
struct
snd_soc_tplg_kcontrol_ops
skl_tplg_kcontrol_ops
[]
=
{
{
.
id
=
SKL_CONTROL_TYPE_MIC_SELECT
,
.
get
=
skl_tplg_mic_control_get
,
.
put
=
skl_tplg_mic_control_set
,
},
};
static
int
skl_tplg_fill_pipe_tkn
(
struct
device
*
dev
,
struct
skl_pipe
*
pipe
,
u32
tkn
,
u32
tkn_val
)
...
...
@@ -1995,7 +2121,7 @@ static int skl_tplg_get_token(struct device *dev,
mconfig
->
converter
=
tkn_elem
->
value
;
break
;
case
SKL_TK
L
_U32_D0I3_CAPS
:
case
SKL_TK
N
_U32_D0I3_CAPS
:
mconfig
->
d0i3_caps
=
tkn_elem
->
value
;
break
;
...
...
@@ -2070,12 +2196,26 @@ static int skl_tplg_get_token(struct device *dev,
break
;
case
SKL_TKN_U32_CAPS_SET_PARAMS
:
mconfig
->
formats_config
.
set_params
=
tkn_elem
->
value
;
break
;
case
SKL_TKN_U32_CAPS_PARAMS_ID
:
mconfig
->
formats_config
.
param_id
=
tkn_elem
->
value
;
break
;
case
SKL_TKN_U32_PROC_DOMAIN
:
mconfig
->
domain
=
tkn_elem
->
value
;
break
;
case
SKL_TKN_U32_DMA_BUF_SIZE
:
mconfig
->
dma_buffer_size
=
tkn_elem
->
value
;
break
;
case
SKL_TKN_U8_IN_PIN_TYPE
:
case
SKL_TKN_U8_OUT_PIN_TYPE
:
case
SKL_TKN_U8_CONN_TYPE
:
...
...
@@ -2147,7 +2287,7 @@ static int skl_tplg_get_tokens(struct device *dev,
tuple_size
+=
tkn_count
*
sizeof
(
*
tkn_elem
);
}
return
0
;
return
off
;
}
/*
...
...
@@ -2198,10 +2338,11 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
num_blocks
=
ret
;
off
+=
array
->
size
;
array
=
(
struct
snd_soc_tplg_vendor_array
*
)(
tplg_w
->
priv
.
data
+
off
);
/* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
while
(
num_blocks
>
0
)
{
array
=
(
struct
snd_soc_tplg_vendor_array
*
)
(
tplg_w
->
priv
.
data
+
off
);
ret
=
skl_tplg_get_desc_blocks
(
dev
,
array
);
if
(
ret
<
0
)
...
...
@@ -2237,7 +2378,9 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
memcpy
(
mconfig
->
formats_config
.
caps
,
data
,
mconfig
->
formats_config
.
caps_size
);
--
num_blocks
;
ret
=
mconfig
->
formats_config
.
caps_size
;
}
off
+=
ret
;
}
return
0
;
...
...
@@ -2329,6 +2472,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
ret
=
skl_tplg_get_pvt_data
(
tplg_w
,
skl
,
bus
->
dev
,
mconfig
);
if
(
ret
<
0
)
return
ret
;
skl_debug_init_module
(
skl
->
debugfs
,
w
,
mconfig
);
bind_event:
if
(
tplg_w
->
event_type
==
0
)
{
dev_dbg
(
bus
->
dev
,
"ASoC: No event handler required
\n
"
);
...
...
@@ -2377,14 +2523,34 @@ static int skl_init_algo_data(struct device *dev, struct soc_bytes_ext *be,
return
0
;
}
static
int
skl_init_enum_data
(
struct
device
*
dev
,
struct
soc_enum
*
se
,
struct
snd_soc_tplg_enum_control
*
ec
)
{
void
*
data
;
if
(
ec
->
priv
.
size
)
{
data
=
devm_kzalloc
(
dev
,
sizeof
(
ec
->
priv
.
size
),
GFP_KERNEL
);
if
(
!
data
)
return
-
ENOMEM
;
memcpy
(
data
,
ec
->
priv
.
data
,
ec
->
priv
.
size
);
se
->
dobj
.
private
=
data
;
}
return
0
;
}
static
int
skl_tplg_control_load
(
struct
snd_soc_component
*
cmpnt
,
struct
snd_kcontrol_new
*
kctl
,
struct
snd_soc_tplg_ctl_hdr
*
hdr
)
{
struct
soc_bytes_ext
*
sb
;
struct
snd_soc_tplg_bytes_control
*
tplg_bc
;
struct
snd_soc_tplg_enum_control
*
tplg_ec
;
struct
hdac_ext_bus
*
ebus
=
snd_soc_component_get_drvdata
(
cmpnt
);
struct
hdac_bus
*
bus
=
ebus_to_hbus
(
ebus
);
struct
soc_enum
*
se
;
switch
(
hdr
->
ops
.
info
)
{
case
SND_SOC_TPLG_CTL_BYTES
:
...
...
@@ -2398,6 +2564,17 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
}
break
;
case
SND_SOC_TPLG_CTL_ENUM
:
tplg_ec
=
container_of
(
hdr
,
struct
snd_soc_tplg_enum_control
,
hdr
);
if
(
kctl
->
access
&
SNDRV_CTL_ELEM_ACCESS_READWRITE
)
{
se
=
(
struct
soc_enum
*
)
kctl
->
private_value
;
if
(
tplg_ec
->
priv
.
size
)
return
skl_init_enum_data
(
bus
->
dev
,
se
,
tplg_ec
);
}
break
;
default:
dev_warn
(
bus
->
dev
,
"Control load not supported %d:%d:%d
\n
"
,
hdr
->
ops
.
get
,
hdr
->
ops
.
put
,
hdr
->
ops
.
info
);
...
...
@@ -2626,6 +2803,8 @@ static struct snd_soc_tplg_ops skl_tplg_ops = {
.
control_load
=
skl_tplg_control_load
,
.
bytes_ext_ops
=
skl_tlv_ops
,
.
bytes_ext_ops_count
=
ARRAY_SIZE
(
skl_tlv_ops
),
.
io_ops
=
skl_tplg_kcontrol_ops
,
.
io_ops_count
=
ARRAY_SIZE
(
skl_tplg_kcontrol_ops
),
.
manifest
=
skl_manifest_load
,
};
...
...
sound/soc/intel/skylake/skl-topology.h
浏览文件 @
51fa6a8f
...
...
@@ -39,6 +39,11 @@
#define MODULE_MAX_IN_PINS 8
#define MODULE_MAX_OUT_PINS 8
#define SKL_MIC_CH_SUPPORT 4
#define SKL_MIC_MAX_CH_SUPPORT 8
#define SKL_DEFAULT_MIC_SEL_GAIN 0x3FF
#define SKL_MIC_SEL_SWITCH 0x3
enum
skl_channel_index
{
SKL_CHANNEL_LEFT
=
0
,
SKL_CHANNEL_RIGHT
=
1
,
...
...
@@ -309,11 +314,14 @@ struct skl_module_cfg {
u8
dev_type
;
u8
dma_id
;
u8
time_slot
;
u8
dmic_ch_combo_index
;
u32
dmic_ch_type
;
u32
params_fixup
;
u32
converter
;
u32
vbus_id
;
u32
mem_pages
;
enum
d0i3_capability
d0i3_caps
;
u32
dma_buffer_size
;
/* in milli seconds */
struct
skl_module_pin
*
m_in_pin
;
struct
skl_module_pin
*
m_out_pin
;
enum
skl_module_type
m_type
;
...
...
@@ -342,6 +350,19 @@ struct skl_module_deferred_bind {
struct
list_head
node
;
};
struct
skl_mic_sel_config
{
u16
mic_switch
;
u16
flags
;
u16
blob
[
SKL_MIC_MAX_CH_SUPPORT
][
SKL_MIC_MAX_CH_SUPPORT
];
}
__packed
;
enum
skl_channel
{
SKL_CH_MONO
=
1
,
SKL_CH_STEREO
=
2
,
SKL_CH_TRIO
=
3
,
SKL_CH_QUATRO
=
4
,
};
static
inline
struct
skl
*
get_skl_ctx
(
struct
device
*
dev
)
{
struct
hdac_ext_bus
*
ebus
=
dev_get_drvdata
(
dev
);
...
...
sound/soc/intel/skylake/skl-tplg-interface.h
浏览文件 @
51fa6a8f
...
...
@@ -24,6 +24,7 @@
* SST types start at higher to avoid any overlapping in future
*/
#define SKL_CONTROL_TYPE_BYTE_TLV 0x100
#define SKL_CONTROL_TYPE_MIC_SELECT 0x102
#define HDA_SST_CFG_MAX 900
/* size of copier cfg*/
#define MAX_IN_QUEUE 8
...
...
@@ -82,6 +83,7 @@ enum skl_module_type {
SKL_MODULE_TYPE_ALGO
,
SKL_MODULE_TYPE_BASE_OUTFMT
,
SKL_MODULE_TYPE_KPB
,
SKL_MODULE_TYPE_MIC_SELECT
,
};
enum
skl_core_affinity
{
...
...
sound/soc/intel/skylake/skl.c
浏览文件 @
51fa6a8f
...
...
@@ -866,6 +866,8 @@ static void skl_remove(struct pci_dev *pci)
/* codec removal, invoke bus_device_remove */
snd_hdac_ext_bus_device_remove
(
ebus
);
skl_debugfs_exit
(
skl
->
debugfs
);
skl
->
debugfs
=
NULL
;
skl_platform_unregister
(
&
pci
->
dev
);
skl_free_dsp
(
skl
);
skl_machine_device_unregister
(
skl
);
...
...
@@ -876,29 +878,120 @@ static void skl_remove(struct pci_dev *pci)
dev_set_drvdata
(
&
pci
->
dev
,
NULL
);
}
static
struct
sst_codecs
skl_codecs
=
{
.
num_codecs
=
1
,
.
codecs
=
{
"NAU88L25"
}
};
static
struct
sst_codecs
kbl_codecs
=
{
.
num_codecs
=
1
,
.
codecs
=
{
"NAU88L25"
}
};
static
struct
sst_codecs
bxt_codecs
=
{
.
num_codecs
=
1
,
.
codecs
=
{
"MX98357A"
}
};
static
struct
sst_codecs
kbl_poppy_codecs
=
{
.
num_codecs
=
1
,
.
codecs
=
{
"10EC5663"
}
};
static
struct
sst_codecs
kbl_5663_5514_codecs
=
{
.
num_codecs
=
2
,
.
codecs
=
{
"10EC5663"
,
"10EC5514"
}
};
static
struct
sst_acpi_mach
sst_skl_devdata
[]
=
{
{
"INT343A"
,
"skl_alc286s_i2s"
,
"intel/dsp_fw_release.bin"
,
NULL
,
NULL
,
NULL
},
{
"INT343B"
,
"skl_n88l25_s4567"
,
"intel/dsp_fw_release.bin"
,
NULL
,
NULL
,
&
skl_dmic_data
},
{
"MX98357A"
,
"skl_n88l25_m98357a"
,
"intel/dsp_fw_release.bin"
,
NULL
,
NULL
,
&
skl_dmic_data
},
{
.
id
=
"INT343A"
,
.
drv_name
=
"skl_alc286s_i2s"
,
.
fw_filename
=
"intel/dsp_fw_release.bin"
,
},
{
.
id
=
"INT343B"
,
.
drv_name
=
"skl_n88l25_s4567"
,
.
fw_filename
=
"intel/dsp_fw_release.bin"
,
.
machine_quirk
=
sst_acpi_codec_list
,
.
quirk_data
=
&
skl_codecs
,
.
pdata
=
&
skl_dmic_data
},
{
.
id
=
"MX98357A"
,
.
drv_name
=
"skl_n88l25_m98357a"
,
.
fw_filename
=
"intel/dsp_fw_release.bin"
,
.
machine_quirk
=
sst_acpi_codec_list
,
.
quirk_data
=
&
skl_codecs
,
.
pdata
=
&
skl_dmic_data
},
{}
};
static
struct
sst_acpi_mach
sst_bxtp_devdata
[]
=
{
{
"INT343A"
,
"bxt_alc298s_i2s"
,
"intel/dsp_fw_bxtn.bin"
,
NULL
,
NULL
,
NULL
},
{
"DLGS7219"
,
"bxt_da7219_max98357a_i2s"
,
"intel/dsp_fw_bxtn.bin"
,
NULL
,
NULL
,
NULL
},
{
.
id
=
"INT343A"
,
.
drv_name
=
"bxt_alc298s_i2s"
,
.
fw_filename
=
"intel/dsp_fw_bxtn.bin"
,
},
{
.
id
=
"DLGS7219"
,
.
drv_name
=
"bxt_da7219_max98357a_i2s"
,
.
fw_filename
=
"intel/dsp_fw_bxtn.bin"
,
.
machine_quirk
=
sst_acpi_codec_list
,
.
quirk_data
=
&
bxt_codecs
,
},
};
static
struct
sst_acpi_mach
sst_kbl_devdata
[]
=
{
{
"INT343A"
,
"kbl_alc286s_i2s"
,
"intel/dsp_fw_kbl.bin"
,
NULL
,
NULL
,
NULL
},
{
"INT343B"
,
"kbl_n88l25_s4567"
,
"intel/dsp_fw_kbl.bin"
,
NULL
,
NULL
,
&
skl_dmic_data
},
{
"MX98357A"
,
"kbl_n88l25_m98357a"
,
"intel/dsp_fw_kbl.bin"
,
NULL
,
NULL
,
&
skl_dmic_data
},
{
.
id
=
"INT343A"
,
.
drv_name
=
"kbl_alc286s_i2s"
,
.
fw_filename
=
"intel/dsp_fw_kbl.bin"
,
},
{
.
id
=
"INT343B"
,
.
drv_name
=
"kbl_n88l25_s4567"
,
.
fw_filename
=
"intel/dsp_fw_kbl.bin"
,
.
machine_quirk
=
sst_acpi_codec_list
,
.
quirk_data
=
&
kbl_codecs
,
.
pdata
=
&
skl_dmic_data
},
{
.
id
=
"MX98357A"
,
.
drv_name
=
"kbl_n88l25_m98357a"
,
.
fw_filename
=
"intel/dsp_fw_kbl.bin"
,
.
machine_quirk
=
sst_acpi_codec_list
,
.
quirk_data
=
&
kbl_codecs
,
.
pdata
=
&
skl_dmic_data
},
{
.
id
=
"MX98927"
,
.
drv_name
=
"kbl_r5514_5663_max"
,
.
fw_filename
=
"intel/dsp_fw_kbl.bin"
,
.
machine_quirk
=
sst_acpi_codec_list
,
.
quirk_data
=
&
kbl_5663_5514_codecs
,
.
pdata
=
&
skl_dmic_data
},
{
.
id
=
"MX98927"
,
.
drv_name
=
"kbl_rt5663_m98927"
,
.
fw_filename
=
"intel/dsp_fw_kbl.bin"
,
.
machine_quirk
=
sst_acpi_codec_list
,
.
quirk_data
=
&
kbl_poppy_codecs
,
.
pdata
=
&
skl_dmic_data
},
{}
};
static
struct
sst_acpi_mach
sst_glk_devdata
[]
=
{
{
"INT343A"
,
"glk_alc298s_i2s"
,
"intel/dsp_fw_glk.bin"
,
NULL
,
NULL
,
NULL
},
{
.
id
=
"INT343A"
,
.
drv_name
=
"glk_alc298s_i2s"
,
.
fw_filename
=
"intel/dsp_fw_glk.bin"
,
},
};
/* PCI IDs */
...
...
sound/soc/intel/skylake/skl.h
浏览文件 @
51fa6a8f
...
...
@@ -23,6 +23,7 @@
#include <sound/hda_register.h>
#include <sound/hdaudio_ext.h>
#include <sound/soc.h>
#include "skl-nhlt.h"
#define SKL_SUSPEND_DELAY 2000
...
...
@@ -42,6 +43,8 @@ struct skl_dsp_resource {
u32
mem
;
};
struct
skl_debug
;
struct
skl
{
struct
hdac_ext_bus
ebus
;
struct
pci_dev
*
pci
;
...
...
@@ -66,6 +69,8 @@ struct skl {
int
supend_active
;
struct
work_struct
probe_work
;
struct
skl_debug
*
debugfs
;
};
#define skl_to_ebus(s) (&(s)->ebus)
...
...
@@ -116,4 +121,25 @@ void skl_update_d0i3c(struct device *dev, bool enable);
int
skl_nhlt_create_sysfs
(
struct
skl
*
skl
);
void
skl_nhlt_remove_sysfs
(
struct
skl
*
skl
);
struct
skl_module_cfg
;
#ifdef CONFIG_DEBUG_FS
struct
skl_debug
*
skl_debugfs_init
(
struct
skl
*
skl
);
void
skl_debugfs_exit
(
struct
skl_debug
*
d
);
void
skl_debug_init_module
(
struct
skl_debug
*
d
,
struct
snd_soc_dapm_widget
*
w
,
struct
skl_module_cfg
*
mconfig
);
#else
static
inline
struct
skl_debug
*
skl_debugfs_init
(
struct
skl
*
skl
)
{
return
NULL
;
}
static
inline
void
skl_debugfs_exit
(
struct
skl_debug
*
d
)
{}
static
inline
void
skl_debug_init_module
(
struct
skl_debug
*
d
,
struct
snd_soc_dapm_widget
*
w
,
struct
skl_module_cfg
*
mconfig
)
{}
#endif
#endif
/* __SOUND_SOC_SKL_H */
sound/soc/soc-core.c
浏览文件 @
51fa6a8f
...
...
@@ -68,6 +68,20 @@ static int pmdown_time = 5000;
module_param
(
pmdown_time
,
int
,
0
);
MODULE_PARM_DESC
(
pmdown_time
,
"DAPM stream powerdown time (msecs)"
);
/* If a DMI filed contain strings in this blacklist (e.g.
* "Type2 - Board Manufacturer" or "Type1 - TBD by OEM"), it will be taken
* as invalid and dropped when setting the card long name from DMI info.
*/
static
const
char
*
const
dmi_blacklist
[]
=
{
"To be filled by OEM"
,
"TBD by OEM"
,
"Default String"
,
"Board Manufacturer"
,
"Board Vendor Name"
,
"Board Product Name"
,
NULL
,
/* terminator */
};
/* returns the minimum number of bytes needed to represent
* a particular given value */
static
int
min_bytes_needed
(
unsigned
long
val
)
...
...
@@ -1933,6 +1947,22 @@ static void cleanup_dmi_name(char *name)
name
[
j
]
=
'\0'
;
}
/* Check if a DMI field is valid, i.e. not containing any string
* in the black list.
*/
static
int
is_dmi_valid
(
const
char
*
field
)
{
int
i
=
0
;
while
(
dmi_blacklist
[
i
])
{
if
(
strstr
(
field
,
dmi_blacklist
[
i
]))
return
0
;
i
++
;
}
return
1
;
}
/**
* snd_soc_set_dmi_name() - Register DMI names to card
* @card: The card to register DMI names
...
...
@@ -1975,17 +2005,18 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
/* make up dmi long name as: vendor.product.version.board */
vendor
=
dmi_get_system_info
(
DMI_BOARD_VENDOR
);
if
(
!
vendor
)
{
if
(
!
vendor
||
!
is_dmi_valid
(
vendor
)
)
{
dev_warn
(
card
->
dev
,
"ASoC: no DMI vendor name!
\n
"
);
return
0
;
}
snprintf
(
card
->
dmi_longname
,
sizeof
(
card
->
snd_card
->
longname
),
"%s"
,
vendor
);
cleanup_dmi_name
(
card
->
dmi_longname
);
product
=
dmi_get_system_info
(
DMI_PRODUCT_NAME
);
if
(
product
)
{
if
(
product
&&
is_dmi_valid
(
product
)
)
{
len
=
strlen
(
card
->
dmi_longname
);
snprintf
(
card
->
dmi_longname
+
len
,
longname_buf_size
-
len
,
...
...
@@ -1999,7 +2030,7 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
* name in the product version field
*/
product_version
=
dmi_get_system_info
(
DMI_PRODUCT_VERSION
);
if
(
product_version
)
{
if
(
product_version
&&
is_dmi_valid
(
product_version
)
)
{
len
=
strlen
(
card
->
dmi_longname
);
snprintf
(
card
->
dmi_longname
+
len
,
longname_buf_size
-
len
,
...
...
@@ -2012,7 +2043,7 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
}
board
=
dmi_get_system_info
(
DMI_BOARD_NAME
);
if
(
board
)
{
if
(
board
&&
is_dmi_valid
(
board
)
)
{
len
=
strlen
(
card
->
dmi_longname
);
snprintf
(
card
->
dmi_longname
+
len
,
longname_buf_size
-
len
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录