Commit 460f623a authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/topic/intel' into asoc-next

parents 39e0a0ae 38a77085
...@@ -163,8 +163,71 @@ ...@@ -163,8 +163,71 @@
* *
* %SKL_TKN_U32_DMA_BUF_SIZE: DMA buffer size in millisec * %SKL_TKN_U32_DMA_BUF_SIZE: DMA buffer size in millisec
* *
* %SKL_TKN_U32_PIPE_DIR: Specifies pipe direction. Can be
* playback/capture.
*
* %SKL_TKN_U32_NUM_CONFIGS: Number of pipe configs
*
* %SKL_TKN_U32_PATH_MEM_PGS: Size of memory (in pages) required for pipeline
* and its data
*
* %SKL_TKN_U32_PIPE_CONFIG_ID: Config id for the modules in the pipe
* and PCM params supported by that pipe
* config. This is used as index to fill
* up the pipe config and module config
* structure.
*
* %SKL_TKN_U32_CFG_FREQ:
* %SKL_TKN_U8_CFG_CHAN:
* %SKL_TKN_U8_CFG_BPS: PCM params (freq, channels, bits per sample)
* supported for each of the pipe configs.
*
* %SKL_TKN_CFG_MOD_RES_ID: Module's resource index for each of the
* pipe config
*
* %SKL_TKN_CFG_MOD_FMT_ID: Module's interface index for each of the
* pipe config
*
* %SKL_TKN_U8_NUM_MOD: Number of modules in the manifest
*
* %SKL_TKN_MM_U8_MOD_IDX: Current index of the module in the manifest
*
* %SKL_TKN_MM_U8_NUM_RES: Number of resources for the module
*
* %SKL_TKN_MM_U8_NUM_INTF: Number of interfaces for the module
*
* %SKL_TKN_MM_U32_RES_ID: Resource index for the resource info to
* be filled into.
* A module can support multiple resource
* configuration and is represnted as a
* resource table. This index is used to
* fill information into appropriate index.
*
* %SKL_TKN_MM_U32_CPS: DSP cycles per second
*
* %SKL_TKN_MM_U32_DMA_SIZE: Allocated buffer size for gateway DMA
*
* %SKL_TKN_MM_U32_CPC: DSP cycles allocated per frame
*
* %SKL_TKN_MM_U32_RES_PIN_ID: Resource pin index in the module
*
* %SKL_TKN_MM_U32_INTF_PIN_ID: Interface index in the module
*
* %SKL_TKN_MM_U32_PIN_BUF: Buffer size of the module pin
*
* %SKL_TKN_MM_U32_FMT_ID: Format index for each of the interface/
* format information to be filled into.
*
* %SKL_TKN_MM_U32_NUM_IN_FMT: Number of input formats
* %SKL_TKN_MM_U32_NUM_OUT_FMT: Number of output formats
*
* module_id and loadable flags dont have tokens as these values will be * module_id and loadable flags dont have tokens as these values will be
* read from the DSP FW manifest * read from the DSP FW manifest
*
* Tokens defined can be used either in the manifest or widget private data.
*
* SKL_TKN_MM is used as a suffix for all tokens that represent
* module data in the manifest.
*/ */
enum SKL_TKNS { enum SKL_TKNS {
SKL_TKN_UUID = 1, SKL_TKN_UUID = 1,
...@@ -218,7 +281,34 @@ enum SKL_TKNS { ...@@ -218,7 +281,34 @@ enum SKL_TKNS {
SKL_TKL_U32_D0I3_CAPS, /* Typo added at v4.10 */ SKL_TKL_U32_D0I3_CAPS, /* Typo added at v4.10 */
SKL_TKN_U32_D0I3_CAPS = SKL_TKL_U32_D0I3_CAPS, SKL_TKN_U32_D0I3_CAPS = SKL_TKL_U32_D0I3_CAPS,
SKL_TKN_U32_DMA_BUF_SIZE, SKL_TKN_U32_DMA_BUF_SIZE,
SKL_TKN_MAX = SKL_TKN_U32_DMA_BUF_SIZE,
SKL_TKN_U32_PIPE_DIRECTION,
SKL_TKN_U32_PIPE_CONFIG_ID,
SKL_TKN_U32_NUM_CONFIGS,
SKL_TKN_U32_PATH_MEM_PGS,
SKL_TKN_U32_CFG_FREQ,
SKL_TKN_U8_CFG_CHAN,
SKL_TKN_U8_CFG_BPS,
SKL_TKN_CFG_MOD_RES_ID,
SKL_TKN_CFG_MOD_FMT_ID,
SKL_TKN_U8_NUM_MOD,
SKL_TKN_MM_U8_MOD_IDX,
SKL_TKN_MM_U8_NUM_RES,
SKL_TKN_MM_U8_NUM_INTF,
SKL_TKN_MM_U32_RES_ID,
SKL_TKN_MM_U32_CPS,
SKL_TKN_MM_U32_DMA_SIZE,
SKL_TKN_MM_U32_CPC,
SKL_TKN_MM_U32_RES_PIN_ID,
SKL_TKN_MM_U32_INTF_PIN_ID,
SKL_TKN_MM_U32_PIN_BUF,
SKL_TKN_MM_U32_FMT_ID,
SKL_TKN_MM_U32_NUM_IN_FMT,
SKL_TKN_MM_U32_NUM_OUT_FMT,
SKL_TKN_MAX = SKL_TKN_MM_U32_NUM_OUT_FMT,
}; };
#endif #endif
...@@ -321,6 +321,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o ...@@ -321,6 +321,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o
obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
obj-$(CONFIG_SND_SOC_MAX98371) += snd-soc-max98371.o
obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o
obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
......
...@@ -121,6 +121,10 @@ struct hdac_hdmi_dai_port_map { ...@@ -121,6 +121,10 @@ struct hdac_hdmi_dai_port_map {
struct hdac_hdmi_cvt *cvt; struct hdac_hdmi_cvt *cvt;
}; };
struct hdac_hdmi_drv_data {
unsigned int vendor_nid;
};
struct hdac_hdmi_priv { struct hdac_hdmi_priv {
struct hdac_hdmi_dai_port_map dai_map[HDA_MAX_CVTS]; struct hdac_hdmi_dai_port_map dai_map[HDA_MAX_CVTS];
struct list_head pin_list; struct list_head pin_list;
...@@ -131,6 +135,7 @@ struct hdac_hdmi_priv { ...@@ -131,6 +135,7 @@ struct hdac_hdmi_priv {
int num_ports; int num_ports;
struct mutex pin_mutex; struct mutex pin_mutex;
struct hdac_chmap chmap; struct hdac_chmap chmap;
struct hdac_hdmi_drv_data *drv_data;
}; };
static struct hdac_hdmi_pcm * static struct hdac_hdmi_pcm *
...@@ -1321,6 +1326,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) ...@@ -1321,6 +1326,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
} }
#define INTEL_VENDOR_NID 0x08 #define INTEL_VENDOR_NID 0x08
#define INTEL_GLK_VENDOR_NID 0x0b
#define INTEL_GET_VENDOR_VERB 0xf81 #define INTEL_GET_VENDOR_VERB 0xf81
#define INTEL_SET_VENDOR_VERB 0x781 #define INTEL_SET_VENDOR_VERB 0x781
#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */ #define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
...@@ -1329,14 +1335,17 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) ...@@ -1329,14 +1335,17 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac) static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
{ {
unsigned int vendor_param; unsigned int vendor_param;
struct hdac_ext_device *edev = to_ehdac_device(hdac);
struct hdac_hdmi_priv *hdmi = edev->private_data;
unsigned int vendor_nid = hdmi->drv_data->vendor_nid;
vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
INTEL_GET_VENDOR_VERB, 0); INTEL_GET_VENDOR_VERB, 0);
if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS) if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
return; return;
vendor_param |= INTEL_EN_ALL_PIN_CVTS; vendor_param |= INTEL_EN_ALL_PIN_CVTS;
vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
INTEL_SET_VENDOR_VERB, vendor_param); INTEL_SET_VENDOR_VERB, vendor_param);
if (vendor_param == -1) if (vendor_param == -1)
return; return;
...@@ -1345,15 +1354,18 @@ static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac) ...@@ -1345,15 +1354,18 @@ static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac) static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac)
{ {
unsigned int vendor_param; unsigned int vendor_param;
struct hdac_ext_device *edev = to_ehdac_device(hdac);
struct hdac_hdmi_priv *hdmi = edev->private_data;
unsigned int vendor_nid = hdmi->drv_data->vendor_nid;
vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
INTEL_GET_VENDOR_VERB, 0); INTEL_GET_VENDOR_VERB, 0);
if (vendor_param == -1 || vendor_param & INTEL_EN_DP12) if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
return; return;
/* enable DP1.2 mode */ /* enable DP1.2 mode */
vendor_param |= INTEL_EN_DP12; vendor_param |= INTEL_EN_DP12;
vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
INTEL_SET_VENDOR_VERB, vendor_param); INTEL_SET_VENDOR_VERB, vendor_param);
if (vendor_param == -1) if (vendor_param == -1)
return; return;
...@@ -1927,6 +1939,14 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx) ...@@ -1927,6 +1939,14 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
return port->eld.info.spk_alloc; return port->eld.info.spk_alloc;
} }
static struct hdac_hdmi_drv_data intel_glk_drv_data = {
.vendor_nid = INTEL_GLK_VENDOR_NID,
};
static struct hdac_hdmi_drv_data intel_drv_data = {
.vendor_nid = INTEL_VENDOR_NID,
};
static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
{ {
struct hdac_device *codec = &edev->hdac; struct hdac_device *codec = &edev->hdac;
...@@ -1935,6 +1955,8 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) ...@@ -1935,6 +1955,8 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
struct hdac_ext_link *hlink = NULL; struct hdac_ext_link *hlink = NULL;
int num_dais = 0; int num_dais = 0;
int ret = 0; int ret = 0;
struct hdac_driver *hdrv = drv_to_hdac_driver(codec->dev.driver);
const struct hda_device_id *hdac_id = hdac_get_device_id(codec, hdrv);
/* hold the ref while we probe */ /* hold the ref while we probe */
hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev)); hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev));
...@@ -1956,6 +1978,12 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) ...@@ -1956,6 +1978,12 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached; hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached;
hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc; hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc;
if (hdac_id->driver_data)
hdmi_priv->drv_data =
(struct hdac_hdmi_drv_data *)hdac_id->driver_data;
else
hdmi_priv->drv_data = &intel_drv_data;
dev_set_drvdata(&codec->dev, edev); dev_set_drvdata(&codec->dev, edev);
INIT_LIST_HEAD(&hdmi_priv->pin_list); INIT_LIST_HEAD(&hdmi_priv->pin_list);
...@@ -2127,7 +2155,8 @@ static const struct hda_device_id hdmi_list[] = { ...@@ -2127,7 +2155,8 @@ static const struct hda_device_id hdmi_list[] = {
HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0), HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0), HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0),
HDA_CODEC_EXT_ENTRY(0x8086280b, 0x100000, "Kabylake HDMI", 0), HDA_CODEC_EXT_ENTRY(0x8086280b, 0x100000, "Kabylake HDMI", 0),
HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI", 0), HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI",
&intel_glk_drv_data),
{} {}
}; };
......
...@@ -349,12 +349,14 @@ static struct snd_soc_dai_driver max98371_dai[] = { ...@@ -349,12 +349,14 @@ static struct snd_soc_dai_driver max98371_dai[] = {
}; };
static const struct snd_soc_codec_driver max98371_codec = { static const struct snd_soc_codec_driver max98371_codec = {
.controls = max98371_snd_controls, .component_driver = {
.num_controls = ARRAY_SIZE(max98371_snd_controls), .controls = max98371_snd_controls,
.dapm_routes = max98371_audio_map, .num_controls = ARRAY_SIZE(max98371_snd_controls),
.num_dapm_routes = ARRAY_SIZE(max98371_audio_map), .dapm_routes = max98371_audio_map,
.dapm_widgets = max98371_dapm_widgets, .num_dapm_routes = ARRAY_SIZE(max98371_audio_map),
.num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets), .dapm_widgets = max98371_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets),
},
}; };
static const struct regmap_config max98371_regmap = { static const struct regmap_config max98371_regmap = {
......
...@@ -255,11 +255,12 @@ config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH ...@@ -255,11 +255,12 @@ config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH
config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH
tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode" tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode"
depends on X86_INTEL_LPSS && I2C depends on X86_INTEL_LPSS && I2C && SPI
select SND_SOC_INTEL_SST select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SKYLAKE select SND_SOC_INTEL_SKYLAKE
select SND_SOC_RT5663 select SND_SOC_RT5663
select SND_SOC_RT5514 select SND_SOC_RT5514
select SND_SOC_RT5514_SPI
select SND_SOC_MAX98927 select SND_SOC_MAX98927
select SND_SOC_HDAC_HDMI select SND_SOC_HDAC_HDMI
help help
......
...@@ -76,7 +76,7 @@ int sst_unregister_dsp(struct sst_device *dev) ...@@ -76,7 +76,7 @@ int sst_unregister_dsp(struct sst_device *dev)
} }
EXPORT_SYMBOL_GPL(sst_unregister_dsp); EXPORT_SYMBOL_GPL(sst_unregister_dsp);
static struct snd_pcm_hardware sst_platform_pcm_hw = { static const struct snd_pcm_hardware sst_platform_pcm_hw = {
.info = (SNDRV_PCM_INFO_INTERLEAVED | .info = (SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_DOUBLE | SNDRV_PCM_INFO_DOUBLE |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_PAUSE |
...@@ -471,7 +471,7 @@ static void sst_disable_ssp(struct snd_pcm_substream *substream, ...@@ -471,7 +471,7 @@ static void sst_disable_ssp(struct snd_pcm_substream *substream,
} }
} }
static struct snd_soc_dai_ops sst_media_dai_ops = { static const struct snd_soc_dai_ops sst_media_dai_ops = {
.startup = sst_media_open, .startup = sst_media_open,
.shutdown = sst_media_close, .shutdown = sst_media_close,
.prepare = sst_media_prepare, .prepare = sst_media_prepare,
...@@ -480,11 +480,11 @@ static struct snd_soc_dai_ops sst_media_dai_ops = { ...@@ -480,11 +480,11 @@ static struct snd_soc_dai_ops sst_media_dai_ops = {
.mute_stream = sst_media_digital_mute, .mute_stream = sst_media_digital_mute,
}; };
static struct snd_soc_dai_ops sst_compr_dai_ops = { static const struct snd_soc_dai_ops sst_compr_dai_ops = {
.mute_stream = sst_media_digital_mute, .mute_stream = sst_media_digital_mute,
}; };
static struct snd_soc_dai_ops sst_be_dai_ops = { static const struct snd_soc_dai_ops sst_be_dai_ops = {
.startup = sst_enable_ssp, .startup = sst_enable_ssp,
.hw_params = sst_be_hw_params, .hw_params = sst_be_hw_params,
.set_fmt = sst_set_format, .set_fmt = sst_set_format,
...@@ -705,7 +705,7 @@ static int sst_soc_probe(struct snd_soc_platform *platform) ...@@ -705,7 +705,7 @@ static int sst_soc_probe(struct snd_soc_platform *platform)
return sst_dsp_init_v2_dpcm(platform); return sst_dsp_init_v2_dpcm(platform);
} }
static struct snd_soc_platform_driver sst_soc_platform_drv = { static const struct snd_soc_platform_driver sst_soc_platform_drv = {
.probe = sst_soc_probe, .probe = sst_soc_probe,
.ops = &sst_platform_ops, .ops = &sst_platform_ops,
.compr_ops = &sst_platform_compr_ops, .compr_ops = &sst_platform_compr_ops,
......
...@@ -407,7 +407,7 @@ static int sst_cdev_caps(struct snd_compr_caps *caps) ...@@ -407,7 +407,7 @@ static int sst_cdev_caps(struct snd_compr_caps *caps)
return 0; return 0;
} }
static struct snd_compr_codec_caps caps_mp3 = { static const struct snd_compr_codec_caps caps_mp3 = {
.num_descriptors = 1, .num_descriptors = 1,
.descriptor[0].max_ch = 2, .descriptor[0].max_ch = 2,
.descriptor[0].sample_rates[0] = 48000, .descriptor[0].sample_rates[0] = 48000,
...@@ -424,7 +424,7 @@ static struct snd_compr_codec_caps caps_mp3 = { ...@@ -424,7 +424,7 @@ static struct snd_compr_codec_caps caps_mp3 = {
.descriptor[0].formats = 0, .descriptor[0].formats = 0,
}; };
static struct snd_compr_codec_caps caps_aac = { static const struct snd_compr_codec_caps caps_aac = {
.num_descriptors = 2, .num_descriptors = 2,
.descriptor[1].max_ch = 2, .descriptor[1].max_ch = 2,
.descriptor[0].sample_rates[0] = 48000, .descriptor[0].sample_rates[0] = 48000,
......
...@@ -181,7 +181,7 @@ static void intel_sst_remove(struct pci_dev *pci) ...@@ -181,7 +181,7 @@ static void intel_sst_remove(struct pci_dev *pci)
} }
/* PCI Routines */ /* PCI Routines */
static struct pci_device_id intel_sst_ids[] = { static const struct pci_device_id intel_sst_ids[] = {
{ PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0}, { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0},
{ 0, } { 0, }
}; };
......
...@@ -309,7 +309,7 @@ static int sst_byt_pcm_mmap(struct snd_pcm_substream *substream, ...@@ -309,7 +309,7 @@ static int sst_byt_pcm_mmap(struct snd_pcm_substream *substream,
return snd_pcm_lib_default_mmap(substream, vma); return snd_pcm_lib_default_mmap(substream, vma);
} }
static struct snd_pcm_ops sst_byt_pcm_ops = { static const struct snd_pcm_ops sst_byt_pcm_ops = {
.open = sst_byt_pcm_open, .open = sst_byt_pcm_open,
.close = sst_byt_pcm_close, .close = sst_byt_pcm_close,
.ioctl = snd_pcm_lib_ioctl, .ioctl = snd_pcm_lib_ioctl,
...@@ -395,7 +395,7 @@ static int sst_byt_pcm_remove(struct snd_soc_platform *platform) ...@@ -395,7 +395,7 @@ static int sst_byt_pcm_remove(struct snd_soc_platform *platform)
return 0; return 0;
} }
static struct snd_soc_platform_driver byt_soc_platform = { static const struct snd_soc_platform_driver byt_soc_platform = {
.probe = sst_byt_pcm_probe, .probe = sst_byt_pcm_probe,
.remove = sst_byt_pcm_remove, .remove = sst_byt_pcm_remove,
.ops = &sst_byt_pcm_ops, .ops = &sst_byt_pcm_ops,
......
...@@ -114,7 +114,44 @@ static const struct snd_soc_dapm_route broxton_rt298_map[] = { ...@@ -114,7 +114,44 @@ static const struct snd_soc_dapm_route broxton_rt298_map[] = {
{ "iDisp2 Tx", NULL, "iDisp2_out"}, { "iDisp2 Tx", NULL, "iDisp2_out"},
{ "hifi1", NULL, "iDisp1 Tx"}, { "hifi1", NULL, "iDisp1 Tx"},
{ "iDisp1 Tx", NULL, "iDisp1_out"}, { "iDisp1 Tx", NULL, "iDisp1_out"},
};
static const struct snd_soc_dapm_route geminilake_rt298_map[] = {
/* speaker */
{"Speaker", NULL, "SPOR"},
{"Speaker", NULL, "SPOL"},
/* HP jack connectors - unknown if we have jack detect */
{"Headphone Jack", NULL, "HPO Pin"},
/* other jacks */
{"MIC1", NULL, "Mic Jack"},
/* digital mics */
{"DMIC1 Pin", NULL, "DMIC2"},
{"DMic", NULL, "SoC DMIC"},
{"HDMI1", NULL, "hif5-0 Output"},
{"HDMI2", NULL, "hif6-0 Output"},
{"HDMI2", NULL, "hif7-0 Output"},
/* CODEC BE connections */
{ "AIF1 Playback", NULL, "ssp2 Tx"},
{ "ssp2 Tx", NULL, "codec0_out"},
{ "ssp2 Tx", NULL, "codec1_out"},
{ "codec0_in", NULL, "ssp2 Rx" },
{ "ssp2 Rx", NULL, "AIF1 Capture" },
{ "dmic01_hifi", NULL, "DMIC01 Rx" },
{ "DMIC01 Rx", NULL, "Capture" },
{ "hifi3", NULL, "iDisp3 Tx"},
{ "iDisp3 Tx", NULL, "iDisp3_out"},
{ "hifi2", NULL, "iDisp2 Tx"},
{ "iDisp2 Tx", NULL, "iDisp2_out"},
{ "hifi1", NULL, "iDisp1 Tx"},
{ "iDisp1 Tx", NULL, "iDisp1_out"},
}; };
static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd) static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd)
...@@ -492,7 +529,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card) ...@@ -492,7 +529,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
/* broxton audio machine driver for SPT + RT298S */ /* broxton audio machine driver for SPT + RT298S */
static struct snd_soc_card broxton_rt298 = { static struct snd_soc_card broxton_rt298 = {
.name = "broxton-rt298", .name = "broxton-rt298",
.owner = THIS_MODULE,
.dai_link = broxton_rt298_dais, .dai_link = broxton_rt298_dais,
.num_links = ARRAY_SIZE(broxton_rt298_dais), .num_links = ARRAY_SIZE(broxton_rt298_dais),
.controls = broxton_controls, .controls = broxton_controls,
...@@ -506,9 +542,41 @@ static struct snd_soc_card broxton_rt298 = { ...@@ -506,9 +542,41 @@ static struct snd_soc_card broxton_rt298 = {
}; };
static struct snd_soc_card geminilake_rt298 = {
.name = "geminilake-rt298",
.dai_link = broxton_rt298_dais,
.num_links = ARRAY_SIZE(broxton_rt298_dais),
.controls = broxton_controls,
.num_controls = ARRAY_SIZE(broxton_controls),
.dapm_widgets = broxton_widgets,
.num_dapm_widgets = ARRAY_SIZE(broxton_widgets),
.dapm_routes = geminilake_rt298_map,
.num_dapm_routes = ARRAY_SIZE(geminilake_rt298_map),
.fully_routed = true,
.late_probe = bxt_card_late_probe,
};
static int broxton_audio_probe(struct platform_device *pdev) static int broxton_audio_probe(struct platform_device *pdev)
{ {
struct bxt_rt286_private *ctx; struct bxt_rt286_private *ctx;
struct snd_soc_card *card =
(struct snd_soc_card *)pdev->id_entry->driver_data;
int i;
for (i = 0; i < ARRAY_SIZE(broxton_rt298_dais); i++) {
if (!strncmp(card->dai_link[i].codec_name, "i2c-INT343A:00",
I2C_NAME_SIZE)) {
if (!strncmp(card->name, "broxton-rt298",
PLATFORM_NAME_SIZE)) {
card->dai_link[i].name = "SSP5-Codec";
card->dai_link[i].cpu_dai_name = "SSP5 Pin";
} else if (!strncmp(card->name, "geminilake-rt298",
PLATFORM_NAME_SIZE)) {
card->dai_link[i].name = "SSP2-Codec";
card->dai_link[i].cpu_dai_name = "SSP2 Pin";
}
}
}
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
if (!ctx) if (!ctx)
...@@ -516,18 +584,27 @@ static int broxton_audio_probe(struct platform_device *pdev) ...@@ -516,18 +584,27 @@ static int broxton_audio_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&ctx->hdmi_pcm_list); INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
broxton_rt298.dev = &pdev->dev; card->dev = &pdev->dev;
snd_soc_card_set_drvdata(&broxton_rt298, ctx); snd_soc_card_set_drvdata(card, ctx);
return devm_snd_soc_register_card(&pdev->dev, &broxton_rt298); return devm_snd_soc_register_card(&pdev->dev, card);
} }
static const struct platform_device_id bxt_board_ids[] = {
{ .name = "bxt_alc298s_i2s", .driver_data =
(unsigned long)&broxton_rt298 },
{ .name = "glk_alc298s_i2s", .driver_data =
(unsigned long)&geminilake_rt298 },
{}
};
static struct platform_driver broxton_audio = { static struct platform_driver broxton_audio = {
.probe = broxton_audio_probe, .probe = broxton_audio_probe,
.driver = { .driver = {
.name = "bxt_alc298s_i2s", .name = "bxt_alc298s_i2s",
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.id_table = bxt_board_ids,
}; };
module_platform_driver(broxton_audio) module_platform_driver(broxton_audio)
...@@ -537,3 +614,4 @@ MODULE_AUTHOR("Senthilnathan Veppur <senthilnathanx.veppur@intel.com>"); ...@@ -537,3 +614,4 @@ MODULE_AUTHOR("Senthilnathan Veppur <senthilnathanx.veppur@intel.com>");
MODULE_DESCRIPTION("Intel SST Audio for Broxton"); MODULE_DESCRIPTION("Intel SST Audio for Broxton");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:bxt_alc298s_i2s"); MODULE_ALIAS("platform:bxt_alc298s_i2s");
MODULE_ALIAS("platform:glk_alc298s_i2s");
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include <linux/input.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <sound/core.h> #include <sound/core.h>
...@@ -62,7 +63,10 @@ struct kbl_codec_private { ...@@ -62,7 +63,10 @@ struct kbl_codec_private {
enum { enum {
KBL_DPCM_AUDIO_PB = 0, KBL_DPCM_AUDIO_PB = 0,
KBL_DPCM_AUDIO_CP, KBL_DPCM_AUDIO_CP,
KBL_DPCM_AUDIO_HS_PB,
KBL_DPCM_AUDIO_ECHO_REF_CP,
KBL_DPCM_AUDIO_DMIC_CP, KBL_DPCM_AUDIO_DMIC_CP,
KBL_DPCM_AUDIO_RT5514_DSP,
KBL_DPCM_AUDIO_HDMI1_PB, KBL_DPCM_AUDIO_HDMI1_PB,
KBL_DPCM_AUDIO_HDMI2_PB, KBL_DPCM_AUDIO_HDMI2_PB,
}; };
...@@ -81,8 +85,8 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = { ...@@ -81,8 +85,8 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = {
SND_SOC_DAPM_SPK("Left Spk", NULL), SND_SOC_DAPM_SPK("Left Spk", NULL),
SND_SOC_DAPM_SPK("Right Spk", NULL), SND_SOC_DAPM_SPK("Right Spk", NULL),
SND_SOC_DAPM_MIC("DMIC", NULL), SND_SOC_DAPM_MIC("DMIC", NULL),
SND_SOC_DAPM_SPK("DP", NULL), SND_SOC_DAPM_SPK("HDMI1", NULL),
SND_SOC_DAPM_SPK("HDMI", NULL), SND_SOC_DAPM_SPK("HDMI2", NULL),
}; };
...@@ -99,23 +103,25 @@ static const struct snd_soc_dapm_route kabylake_map[] = { ...@@ -99,23 +103,25 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
{ "IN1P", NULL, "Headset Mic" }, { "IN1P", NULL, "Headset Mic" },
{ "IN1N", NULL, "Headset Mic" }, { "IN1N", NULL, "Headset Mic" },
{ "HDMI", NULL, "hif5 Output" },
{ "DP", NULL, "hif6 Output" },
/* CODEC BE connections */ /* CODEC BE connections */
{ "Left HiFi Playback", NULL, "ssp0 Tx" }, { "Left HiFi Playback", NULL, "ssp0 Tx" },
{ "Right HiFi Playback", NULL, "ssp0 Tx" }, { "Right HiFi Playback", NULL, "ssp0 Tx" },
{ "ssp0 Tx", NULL, "codec0_out" }, { "ssp0 Tx", NULL, "spk_out" },
{ "AIF Playback", NULL, "ssp1 Tx" }, { "AIF Playback", NULL, "ssp1 Tx" },
{ "ssp1 Tx", NULL, "codec1_out" }, { "ssp1 Tx", NULL, "hs_out" },
{ "codec0_in", NULL, "ssp1 Rx" }, { "hs_in", NULL, "ssp1 Rx" },
{ "ssp1 Rx", NULL, "AIF Capture" }, { "ssp1 Rx", NULL, "AIF Capture" },
{ "codec1_in", NULL, "ssp0 Rx" }, { "codec1_in", NULL, "ssp0 Rx" },
{ "ssp0 Rx", NULL, "AIF1 Capture" }, { "ssp0 Rx", NULL, "AIF1 Capture" },
/* IV feedback path */
{ "codec0_fb_in", NULL, "ssp0 Rx"},
{ "ssp0 Rx", NULL, "Left HiFi Capture" },
{ "ssp0 Rx", NULL, "Right HiFi Capture" },
/* DMIC */ /* DMIC */
{ "DMIC1L", NULL, "DMIC" }, { "DMIC1L", NULL, "DMIC" },
{ "DMIC1R", NULL, "DMIC" }, { "DMIC1R", NULL, "DMIC" },
...@@ -173,6 +179,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) ...@@ -173,6 +179,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
int ret; int ret;
struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_codec *codec = rtd->codec; struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_jack *jack;
/* /*
* Headset buttons map to the google Reference headset. * Headset buttons map to the google Reference headset.
...@@ -187,6 +194,12 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) ...@@ -187,6 +194,12 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
return ret; return ret;
} }
jack = &ctx->kabylake_headset;
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
rt5663_set_jack_detect(codec, &ctx->kabylake_headset); rt5663_set_jack_detect(codec, &ctx->kabylake_headset);
ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC"); ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC");
...@@ -358,11 +371,18 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, ...@@ -358,11 +371,18 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
} }
} }
if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME) || if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) {
!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16);
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF0, 3, 8, 16);
if (ret < 0) { if (ret < 0) {
dev_err(rtd->dev, "set TDM slot err:%d\n", ret); dev_err(rtd->dev, "DEV0 TDM slot err:%d\n", ret);
return ret;
}
}
if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) {
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16);
if (ret < 0) {
dev_err(rtd->dev, "DEV1 TDM slot err:%d\n", ret);
return ret; return ret;
} }
} }
...@@ -442,6 +462,36 @@ static struct snd_soc_dai_link kabylake_dais[] = { ...@@ -442,6 +462,36 @@ static struct snd_soc_dai_link kabylake_dais[] = {
.dpcm_capture = 1, .dpcm_capture = 1,
.ops = &kabylake_rt5663_fe_ops, .ops = &kabylake_rt5663_fe_ops,
}, },
[KBL_DPCM_AUDIO_HS_PB] = {
.name = "Kbl Audio Headset Playback",
.stream_name = "Headset Audio",
.cpu_dai_name = "System Pin2",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:1f.3",
.dpcm_playback = 1,
.nonatomic = 1,
.dynamic = 1,
},
[KBL_DPCM_AUDIO_ECHO_REF_CP] = {
.name = "Kbl Audio Echo Reference cap",
.stream_name = "Echoreference Capture",
.cpu_dai_name = "Echoref Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:1f.3",
.init = NULL,
.capture_only = 1,
.nonatomic = 1,
},
[KBL_DPCM_AUDIO_RT5514_DSP] = {
.name = "rt5514 dsp",
.stream_name = "Wake on Voice",
.cpu_dai_name = "spi-PRP0001:00",
.platform_name = "spi-PRP0001:00",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
},
[KBL_DPCM_AUDIO_DMIC_CP] = { [KBL_DPCM_AUDIO_DMIC_CP] = {
.name = "Kbl Audio DMIC cap", .name = "Kbl Audio DMIC cap",
.stream_name = "dmiccap", .stream_name = "dmiccap",
...@@ -548,10 +598,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) ...@@ -548,10 +598,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
{ {
struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card); struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
struct kbl_hdmi_pcm *pcm; struct kbl_hdmi_pcm *pcm;
struct snd_soc_codec *codec = NULL;
int err, i = 0; int err, i = 0;
char jack_name[NAME_SIZE]; char jack_name[NAME_SIZE];
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
codec = pcm->codec_dai->codec;
err = snd_soc_card_jack_new(card, jack_name, err = snd_soc_card_jack_new(card, jack_name,
SND_JACK_AVOUT, &ctx->kabylake_hdmi[i], SND_JACK_AVOUT, &ctx->kabylake_hdmi[i],
NULL, 0); NULL, 0);
...@@ -565,7 +617,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) ...@@ -565,7 +617,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
i++; i++;
} }
return 0; if (!codec)
return -EINVAL;
return hdac_hdmi_jack_port_init(codec, &card->dapm);
} }
/* /*
......
...@@ -376,10 +376,8 @@ static int snd_mfld_mc_probe(struct platform_device *pdev) ...@@ -376,10 +376,8 @@ static int snd_mfld_mc_probe(struct platform_device *pdev)
/* audio interrupt base of SRAM location where /* audio interrupt base of SRAM location where
* interrupts are stored by System FW */ * interrupts are stored by System FW */
mc_drv_ctx = devm_kzalloc(&pdev->dev, sizeof(*mc_drv_ctx), GFP_ATOMIC); mc_drv_ctx = devm_kzalloc(&pdev->dev, sizeof(*mc_drv_ctx), GFP_ATOMIC);
if (!mc_drv_ctx) { if (!mc_drv_ctx)
pr_err("allocation failed\n");
return -ENOMEM; return -ENOMEM;
}
irq_mem = platform_get_resource_byname( irq_mem = platform_get_resource_byname(
pdev, IORESOURCE_MEM, "IRQ_BASE"); pdev, IORESOURCE_MEM, "IRQ_BASE");
......
...@@ -1135,7 +1135,7 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform) ...@@ -1135,7 +1135,7 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform)
return 0; return 0;
} }
static struct snd_soc_platform_driver hsw_soc_platform = { static const struct snd_soc_platform_driver hsw_soc_platform = {
.probe = hsw_pcm_probe, .probe = hsw_pcm_probe,
.remove = hsw_pcm_remove, .remove = hsw_pcm_remove,
.ops = &hsw_pcm_ops, .ops = &hsw_pcm_ops,
......
...@@ -8,7 +8,8 @@ endif ...@@ -8,7 +8,8 @@ endif
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o
# Skylake IPC Support # Skylake IPC Support
snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o skl-sst-cldma.o \ snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o \
skl-sst.o bxt-sst.o skl-sst-utils.o skl-sst-cldma.o skl-sst.o bxt-sst.o cnl-sst.o \
skl-sst-utils.o
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o
...@@ -530,7 +530,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) ...@@ -530,7 +530,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
return 0; return 0;
} }
static struct skl_dsp_fw_ops bxt_fw_ops = { static const struct skl_dsp_fw_ops bxt_fw_ops = {
.set_state_D0 = bxt_set_dsp_D0, .set_state_D0 = bxt_set_dsp_D0,
.set_state_D3 = bxt_set_dsp_D3, .set_state_D3 = bxt_set_dsp_D3,
.set_state_D0i3 = bxt_schedule_dsp_D0i3, .set_state_D0i3 = bxt_schedule_dsp_D0i3,
...@@ -581,10 +581,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, ...@@ -581,10 +581,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
ret = skl_ipc_init(dev, skl);
if (ret) {
skl_dsp_free(sst);
return ret;
}
/* set the D0i3 check */ /* set the D0i3 check */
skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0; skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0;
skl->cores.count = 2;
skl->boot_complete = false; skl->boot_complete = false;
init_waitqueue_head(&skl->boot_wait); init_waitqueue_head(&skl->boot_wait);
INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3); INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3);
...@@ -629,11 +634,6 @@ void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) ...@@ -629,11 +634,6 @@ void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
release_firmware(ctx->dsp->fw); release_firmware(ctx->dsp->fw);
skl_freeup_uuid_list(ctx); skl_freeup_uuid_list(ctx);
skl_ipc_free(&ctx->ipc); skl_ipc_free(&ctx->ipc);
ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp);
if (ctx->dsp->addr.lpe)
iounmap(ctx->dsp->addr.lpe);
ctx->dsp->ops->free(ctx->dsp); ctx->dsp->ops->free(ctx->dsp);
} }
EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup); EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup);
......
/*
* cnl-sst-dsp.c - CNL SST library generic function
*
* Copyright (C) 2016-17, Intel Corporation.
* Author: Guneshwor Singh <guneshwor.o.singh@intel.com>
*
* Modified from:
* SKL SST library generic function
* Copyright (C) 2014-15, Intel Corporation.
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <linux/device.h>
#include "../common/sst-dsp.h"
#include "../common/sst-ipc.h"
#include "../common/sst-dsp-priv.h"
#include "cnl-sst-dsp.h"
/* various timeout values */
#define CNL_DSP_PU_TO 50
#define CNL_DSP_PD_TO 50
#define CNL_DSP_RESET_TO 50
static int
cnl_dsp_core_set_reset_state(struct sst_dsp *ctx, unsigned int core_mask)
{
/* update bits */
sst_dsp_shim_update_bits_unlocked(ctx,
CNL_ADSP_REG_ADSPCS, CNL_ADSPCS_CRST(core_mask),
CNL_ADSPCS_CRST(core_mask));
/* poll with timeout to check if operation successful */
return sst_dsp_register_poll(ctx,
CNL_ADSP_REG_ADSPCS,
CNL_ADSPCS_CRST(core_mask),
CNL_ADSPCS_CRST(core_mask),
CNL_DSP_RESET_TO,
"Set reset");
}
static int
cnl_dsp_core_unset_reset_state(struct sst_dsp *ctx, unsigned int core_mask)
{
/* update bits */
sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS,
CNL_ADSPCS_CRST(core_mask), 0);
/* poll with timeout to check if operation successful */
return sst_dsp_register_poll(ctx,
CNL_ADSP_REG_ADSPCS,
CNL_ADSPCS_CRST(core_mask),
0,
CNL_DSP_RESET_TO,
"Unset reset");
}
static bool is_cnl_dsp_core_enable(struct sst_dsp *ctx, unsigned int core_mask)
{
int val;
bool is_enable;
val = sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPCS);
is_enable = (val & CNL_ADSPCS_CPA(core_mask)) &&
(val & CNL_ADSPCS_SPA(core_mask)) &&
!(val & CNL_ADSPCS_CRST(core_mask)) &&
!(val & CNL_ADSPCS_CSTALL(core_mask));
dev_dbg(ctx->dev, "DSP core(s) enabled? %d: core_mask %#x\n",
is_enable, core_mask);
return is_enable;
}
static int cnl_dsp_reset_core(struct sst_dsp *ctx, unsigned int core_mask)
{
/* stall core */
sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS,
CNL_ADSPCS_CSTALL(core_mask),
CNL_ADSPCS_CSTALL(core_mask));
/* set reset state */
return cnl_dsp_core_set_reset_state(ctx, core_mask);
}
static int cnl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask)
{
int ret;
/* unset reset state */
ret = cnl_dsp_core_unset_reset_state(ctx, core_mask);
if (ret < 0)
return ret;
/* run core */
sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS,
CNL_ADSPCS_CSTALL(core_mask), 0);
if (!is_cnl_dsp_core_enable(ctx, core_mask)) {
cnl_dsp_reset_core(ctx, core_mask);
dev_err(ctx->dev, "DSP core mask %#x enable failed\n",
core_mask);
ret = -EIO;
}
return ret;
}
static int cnl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask)
{
/* update bits */
sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS,
CNL_ADSPCS_SPA(core_mask),
CNL_ADSPCS_SPA(core_mask));
/* poll with timeout to check if operation successful */
return sst_dsp_register_poll(ctx, CNL_ADSP_REG_ADSPCS,
CNL_ADSPCS_CPA(core_mask),
CNL_ADSPCS_CPA(core_mask),
CNL_DSP_PU_TO,
"Power up");
}
static int cnl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask)
{
/* update bits */
sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS,
CNL_ADSPCS_SPA(core_mask), 0);
/* poll with timeout to check if operation successful */
return sst_dsp_register_poll(ctx,
CNL_ADSP_REG_ADSPCS,
CNL_ADSPCS_CPA(core_mask),
0,
CNL_DSP_PD_TO,
"Power down");
}
int cnl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask)
{
int ret;
/* power up */
ret = cnl_dsp_core_power_up(ctx, core_mask);
if (ret < 0) {
dev_dbg(ctx->dev, "DSP core mask %#x power up failed",
core_mask);
return ret;
}
return cnl_dsp_start_core(ctx, core_mask);
}
int cnl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask)
{
int ret;
ret = cnl_dsp_reset_core(ctx, core_mask);
if (ret < 0) {
dev_err(ctx->dev, "DSP core mask %#x reset failed\n",
core_mask);
return ret;
}
/* power down core*/
ret = cnl_dsp_core_power_down(ctx, core_mask);
if (ret < 0) {
dev_err(ctx->dev, "DSP core mask %#x power down failed\n",
core_mask);
return ret;
}
if (is_cnl_dsp_core_enable(ctx, core_mask)) {
dev_err(ctx->dev, "DSP core mask %#x disable failed\n",
core_mask);
ret = -EIO;
}
return ret;
}
irqreturn_t cnl_dsp_sst_interrupt(int irq, void *dev_id)
{
struct sst_dsp *ctx = dev_id;
u32 val;
irqreturn_t ret = IRQ_NONE;
spin_lock(&ctx->spinlock);
val = sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPIS);
ctx->intr_status = val;
if (val == 0xffffffff) {
spin_unlock(&ctx->spinlock);
return IRQ_NONE;
}
if (val & CNL_ADSPIS_IPC) {
cnl_ipc_int_disable(ctx);
ret = IRQ_WAKE_THREAD;
}
spin_unlock(&ctx->spinlock);
return ret;
}
void cnl_dsp_free(struct sst_dsp *dsp)
{
cnl_ipc_int_disable(dsp);
free_irq(dsp->irq, dsp);
cnl_ipc_op_int_disable(dsp);
cnl_dsp_disable_core(dsp, SKL_DSP_CORE0_MASK);
}
EXPORT_SYMBOL_GPL(cnl_dsp_free);
void cnl_ipc_int_enable(struct sst_dsp *ctx)
{
sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_ADSPIC,
CNL_ADSPIC_IPC, CNL_ADSPIC_IPC);
}
void cnl_ipc_int_disable(struct sst_dsp *ctx)
{
sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPIC,
CNL_ADSPIC_IPC, 0);
}
void cnl_ipc_op_int_enable(struct sst_dsp *ctx)
{
/* enable IPC DONE interrupt */
sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL,
CNL_ADSP_REG_HIPCCTL_DONE,
CNL_ADSP_REG_HIPCCTL_DONE);
/* enable IPC BUSY interrupt */
sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL,
CNL_ADSP_REG_HIPCCTL_BUSY,
CNL_ADSP_REG_HIPCCTL_BUSY);
}
void cnl_ipc_op_int_disable(struct sst_dsp *ctx)
{
/* disable IPC DONE interrupt */
sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL,
CNL_ADSP_REG_HIPCCTL_DONE, 0);
/* disable IPC BUSY interrupt */
sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL,
CNL_ADSP_REG_HIPCCTL_BUSY, 0);
}
bool cnl_ipc_int_status(struct sst_dsp *ctx)
{
return sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPIS) &
CNL_ADSPIS_IPC;
}
void cnl_ipc_free(struct sst_generic_ipc *ipc)
{
cnl_ipc_op_int_disable(ipc->dsp);
sst_ipc_fini(ipc);
}
/*
* Cannonlake SST DSP Support
*
* Copyright (C) 2016-17, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#ifndef __CNL_SST_DSP_H__
#define __CNL_SST_DSP_H__
struct sst_dsp;
struct skl_sst;
struct sst_dsp_device;
struct sst_generic_ipc;
/* Intel HD Audio General DSP Registers */
#define CNL_ADSP_GEN_BASE 0x0
#define CNL_ADSP_REG_ADSPCS (CNL_ADSP_GEN_BASE + 0x04)
#define CNL_ADSP_REG_ADSPIC (CNL_ADSP_GEN_BASE + 0x08)
#define CNL_ADSP_REG_ADSPIS (CNL_ADSP_GEN_BASE + 0x0c)
/* Intel HD Audio Inter-Processor Communication Registers */
#define CNL_ADSP_IPC_BASE 0xc0
#define CNL_ADSP_REG_HIPCTDR (CNL_ADSP_IPC_BASE + 0x00)
#define CNL_ADSP_REG_HIPCTDA (CNL_ADSP_IPC_BASE + 0x04)
#define CNL_ADSP_REG_HIPCTDD (CNL_ADSP_IPC_BASE + 0x08)
#define CNL_ADSP_REG_HIPCIDR (CNL_ADSP_IPC_BASE + 0x10)
#define CNL_ADSP_REG_HIPCIDA (CNL_ADSP_IPC_BASE + 0x14)
#define CNL_ADSP_REG_HIPCIDD (CNL_ADSP_IPC_BASE + 0x18)
#define CNL_ADSP_REG_HIPCCTL (CNL_ADSP_IPC_BASE + 0x28)
/* HIPCTDR */
#define CNL_ADSP_REG_HIPCTDR_BUSY BIT(31)
/* HIPCTDA */
#define CNL_ADSP_REG_HIPCTDA_DONE BIT(31)
/* HIPCIDR */
#define CNL_ADSP_REG_HIPCIDR_BUSY BIT(31)
/* HIPCIDA */
#define CNL_ADSP_REG_HIPCIDA_DONE BIT(31)
/* CNL HIPCCTL */
#define CNL_ADSP_REG_HIPCCTL_DONE BIT(1)
#define CNL_ADSP_REG_HIPCCTL_BUSY BIT(0)
/* CNL HIPCT */
#define CNL_ADSP_REG_HIPCT_BUSY BIT(31)
/* Intel HD Audio SRAM Window 1 */
#define CNL_ADSP_SRAM1_BASE 0xa0000
#define CNL_ADSP_MMIO_LEN 0x10000
#define CNL_ADSP_W0_STAT_SZ 0x1000
#define CNL_ADSP_W0_UP_SZ 0x1000
#define CNL_ADSP_W1_SZ 0x1000
#define CNL_FW_STS_MASK 0xf
#define CNL_ADSPIC_IPC 0x1
#define CNL_ADSPIS_IPC 0x1
#define CNL_DSP_CORES 4
#define CNL_DSP_CORES_MASK ((1 << CNL_DSP_CORES) - 1)
/* core reset - asserted high */
#define CNL_ADSPCS_CRST_SHIFT 0
#define CNL_ADSPCS_CRST(x) (x << CNL_ADSPCS_CRST_SHIFT)
/* core run/stall - when set to 1 core is stalled */
#define CNL_ADSPCS_CSTALL_SHIFT 8
#define CNL_ADSPCS_CSTALL(x) (x << CNL_ADSPCS_CSTALL_SHIFT)
/* set power active - when set to 1 turn core on */
#define CNL_ADSPCS_SPA_SHIFT 16
#define CNL_ADSPCS_SPA(x) (x << CNL_ADSPCS_SPA_SHIFT)
/* current power active - power status of cores, set by hardware */
#define CNL_ADSPCS_CPA_SHIFT 24
#define CNL_ADSPCS_CPA(x) (x << CNL_ADSPCS_CPA_SHIFT)
int cnl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core);
int cnl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core);
irqreturn_t cnl_dsp_sst_interrupt(int irq, void *dev_id);
void cnl_dsp_free(struct sst_dsp *dsp);
void cnl_ipc_int_enable(struct sst_dsp *ctx);
void cnl_ipc_int_disable(struct sst_dsp *ctx);
void cnl_ipc_op_int_enable(struct sst_dsp *ctx);
void cnl_ipc_op_int_disable(struct sst_dsp *ctx);
bool cnl_ipc_int_status(struct sst_dsp *ctx);
void cnl_ipc_free(struct sst_generic_ipc *ipc);
int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
struct skl_sst **dsp);
int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx);
void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
#endif /*__CNL_SST_DSP_H__*/
This diff is collapsed.
This diff is collapsed.
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#define HDA_STEREO 2 #define HDA_STEREO 2
#define HDA_QUAD 4 #define HDA_QUAD 4
static struct snd_pcm_hardware azx_pcm_hw = { static const struct snd_pcm_hardware azx_pcm_hw = {
.info = (SNDRV_PCM_INFO_MMAP | .info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_BLOCK_TRANSFER |
...@@ -628,7 +628,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, ...@@ -628,7 +628,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static struct snd_soc_dai_ops skl_pcm_dai_ops = { static const struct snd_soc_dai_ops skl_pcm_dai_ops = {
.startup = skl_pcm_open, .startup = skl_pcm_open,
.shutdown = skl_pcm_close, .shutdown = skl_pcm_close,
.prepare = skl_pcm_prepare, .prepare = skl_pcm_prepare,
...@@ -637,15 +637,15 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = { ...@@ -637,15 +637,15 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = {
.trigger = skl_pcm_trigger, .trigger = skl_pcm_trigger,
}; };
static struct snd_soc_dai_ops skl_dmic_dai_ops = { static const struct snd_soc_dai_ops skl_dmic_dai_ops = {
.hw_params = skl_be_hw_params, .hw_params = skl_be_hw_params,
}; };
static struct snd_soc_dai_ops skl_be_ssp_dai_ops = { static const struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
.hw_params = skl_be_hw_params, .hw_params = skl_be_hw_params,
}; };
static struct snd_soc_dai_ops skl_link_dai_ops = { static const struct snd_soc_dai_ops skl_link_dai_ops = {
.prepare = skl_link_pcm_prepare, .prepare = skl_link_pcm_prepare,
.hw_params = skl_link_hw_params, .hw_params = skl_link_hw_params,
.hw_free = skl_link_hw_free, .hw_free = skl_link_hw_free,
...@@ -674,6 +674,32 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { ...@@ -674,6 +674,32 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.sig_bits = 32, .sig_bits = 32,
}, },
}, },
{
.name = "System Pin2",
.ops = &skl_pcm_dai_ops,
.playback = {
.stream_name = "Headset Playback",
.channels_min = HDA_MONO,
.channels_max = HDA_STEREO,
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 |
SNDRV_PCM_RATE_8000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
},
},
{
.name = "Echoref Pin",
.ops = &skl_pcm_dai_ops,
.capture = {
.stream_name = "Echoreference Capture",
.channels_min = HDA_STEREO,
.channels_max = HDA_STEREO,
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 |
SNDRV_PCM_RATE_8000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
},
},
{ {
.name = "Reference Pin", .name = "Reference Pin",
.ops = &skl_pcm_dai_ops, .ops = &skl_pcm_dai_ops,
...@@ -1194,8 +1220,11 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) ...@@ -1194,8 +1220,11 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
{ {
struct skl_sst *ctx = skl->skl_sst; struct skl_sst *ctx = skl->skl_sst;
struct skl_module_inst_id *pin_id;
uuid_le *uuid_mod, *uuid_tplg;
struct skl_module *skl_module;
struct uuid_module *module; struct uuid_module *module;
uuid_le *uuid_mod; int i, ret = -EIO;
uuid_mod = (uuid_le *)mconfig->guid; uuid_mod = (uuid_le *)mconfig->guid;
...@@ -1207,12 +1236,45 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) ...@@ -1207,12 +1236,45 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
list_for_each_entry(module, &ctx->uuid_list, list) { list_for_each_entry(module, &ctx->uuid_list, list) {
if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
mconfig->id.module_id = module->id; mconfig->id.module_id = module->id;
mconfig->is_loadable = module->is_loadable; if (mconfig->module)
return 0; mconfig->module->loadable = module->is_loadable;
ret = 0;
break;
}
}
if (ret)
return ret;
uuid_mod = &module->uuid;
ret = -EIO;
for (i = 0; i < skl->nr_modules; i++) {
skl_module = skl->modules[i];
uuid_tplg = &skl_module->uuid;
if (!uuid_le_cmp(*uuid_mod, *uuid_tplg)) {
mconfig->module = skl_module;
ret = 0;
break;
} }
} }
if (skl->nr_modules && ret)
return ret;
return -EIO; list_for_each_entry(module, &ctx->uuid_list, list) {
for (i = 0; i < MAX_IN_QUEUE; i++) {
pin_id = &mconfig->m_in_pin[i].id;
if (!uuid_le_cmp(pin_id->mod_uuid, module->uuid))
pin_id->module_id = module->id;
}
for (i = 0; i < MAX_OUT_QUEUE; i++) {
pin_id = &mconfig->m_out_pin[i].id;
if (!uuid_le_cmp(pin_id->mod_uuid, module->uuid))
pin_id->module_id = module->id;
}
}
return 0;
} }
static int skl_populate_modules(struct skl *skl) static int skl_populate_modules(struct skl *skl)
...@@ -1284,7 +1346,7 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform) ...@@ -1284,7 +1346,7 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
return 0; return 0;
} }
static struct snd_soc_platform_driver skl_platform_drv = { static const struct snd_soc_platform_driver skl_platform_drv = {
.probe = skl_platform_soc_probe, .probe = skl_platform_soc_probe,
.ops = &skl_platform_ops, .ops = &skl_platform_ops,
.pcm_new = skl_pcm_new, .pcm_new = skl_pcm_new,
......
...@@ -47,7 +47,7 @@ void skl_dsp_init_core_state(struct sst_dsp *ctx) ...@@ -47,7 +47,7 @@ void skl_dsp_init_core_state(struct sst_dsp *ctx)
skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING; skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING;
skl->cores.usage_count[SKL_DSP_CORE0_ID] = 1; skl->cores.usage_count[SKL_DSP_CORE0_ID] = 1;
for (i = SKL_DSP_CORE0_ID + 1; i < SKL_DSP_CORES_MAX; i++) { for (i = SKL_DSP_CORE0_ID + 1; i < skl->cores.count; i++) {
skl->cores.state[i] = SKL_DSP_RESET; skl->cores.state[i] = SKL_DSP_RESET;
skl->cores.usage_count[i] = 0; skl->cores.usage_count[i] = 0;
} }
...@@ -351,6 +351,8 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id) ...@@ -351,6 +351,8 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
return -EINVAL; return -EINVAL;
} }
skl->cores.usage_count[core_id]++;
if (skl->cores.state[core_id] == SKL_DSP_RESET) { if (skl->cores.state[core_id] == SKL_DSP_RESET) {
ret = ctx->fw_ops.set_state_D0(ctx, core_id); ret = ctx->fw_ops.set_state_D0(ctx, core_id);
if (ret < 0) { if (ret < 0) {
...@@ -359,8 +361,6 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id) ...@@ -359,8 +361,6 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
} }
} }
skl->cores.usage_count[core_id]++;
out: out:
dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n", dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n",
core_id, skl->cores.state[core_id], core_id, skl->cores.state[core_id],
......
...@@ -283,7 +283,7 @@ enum skl_ipc_module_msg { ...@@ -283,7 +283,7 @@ enum skl_ipc_module_msg {
IPC_MOD_SET_D0IX = 8 IPC_MOD_SET_D0IX = 8
}; };
static void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data, void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data,
size_t tx_size) size_t tx_size)
{ {
if (tx_size) if (tx_size)
...@@ -347,7 +347,7 @@ static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc, ...@@ -347,7 +347,7 @@ static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc,
} }
static int skl_ipc_process_notification(struct sst_generic_ipc *ipc, int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
struct skl_ipc_header header) struct skl_ipc_header header)
{ {
struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);
...@@ -406,7 +406,7 @@ static int skl_ipc_set_reply_error_code(u32 reply) ...@@ -406,7 +406,7 @@ static int skl_ipc_set_reply_error_code(u32 reply)
} }
} }
static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
struct skl_ipc_header header) struct skl_ipc_header header)
{ {
struct ipc_message *msg; struct ipc_message *msg;
......
...@@ -44,12 +44,10 @@ struct skl_ipc_header { ...@@ -44,12 +44,10 @@ struct skl_ipc_header {
u32 extension; u32 extension;
}; };
#define SKL_DSP_CORES_MAX 2
struct skl_dsp_cores { struct skl_dsp_cores {
unsigned int count; unsigned int count;
enum skl_dsp_states state[SKL_DSP_CORES_MAX]; enum skl_dsp_states *state;
int usage_count[SKL_DSP_CORES_MAX]; int *usage_count;
}; };
/** /**
...@@ -214,4 +212,10 @@ void skl_ipc_free(struct sst_generic_ipc *ipc); ...@@ -214,4 +212,10 @@ void skl_ipc_free(struct sst_generic_ipc *ipc);
int skl_ipc_init(struct device *dev, struct skl_sst *skl); int skl_ipc_init(struct device *dev, struct skl_sst *skl);
void skl_clear_module_cnt(struct sst_dsp *ctx); void skl_clear_module_cnt(struct sst_dsp *ctx);
void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
struct skl_ipc_header header);
int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
struct skl_ipc_header header);
void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data,
size_t tx_size);
#endif /* __SKL_IPC_H */ #endif /* __SKL_IPC_H */
...@@ -368,7 +368,6 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, ...@@ -368,7 +368,6 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
{ {
struct skl_sst *skl; struct skl_sst *skl;
struct sst_dsp *sst; struct sst_dsp *sst;
int ret;
skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL);
if (skl == NULL) if (skl == NULL)
...@@ -388,15 +387,12 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, ...@@ -388,15 +387,12 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
sst->dsp_ops = dsp_ops; sst->dsp_ops = dsp_ops;
init_waitqueue_head(&skl->mod_load_wait); init_waitqueue_head(&skl->mod_load_wait);
INIT_LIST_HEAD(&sst->module_list); INIT_LIST_HEAD(&sst->module_list);
ret = skl_ipc_init(dev, skl);
if (ret)
return ret;
skl->is_first_boot = true; skl->is_first_boot = true;
if (dsp) if (dsp)
*dsp = skl; *dsp = skl;
return ret; return 0;
} }
int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo,
......
...@@ -503,7 +503,7 @@ static void skl_clear_module_table(struct sst_dsp *ctx) ...@@ -503,7 +503,7 @@ static void skl_clear_module_table(struct sst_dsp *ctx)
} }
} }
static struct skl_dsp_fw_ops skl_fw_ops = { static const struct skl_dsp_fw_ops skl_fw_ops = {
.set_state_D0 = skl_set_dsp_D0, .set_state_D0 = skl_set_dsp_D0,
.set_state_D3 = skl_set_dsp_D3, .set_state_D3 = skl_set_dsp_D3,
.load_fw = skl_load_base_firmware, .load_fw = skl_load_base_firmware,
...@@ -512,7 +512,7 @@ static struct skl_dsp_fw_ops skl_fw_ops = { ...@@ -512,7 +512,7 @@ static struct skl_dsp_fw_ops skl_fw_ops = {
.unload_mod = skl_unload_module, .unload_mod = skl_unload_module,
}; };
static struct skl_dsp_fw_ops kbl_fw_ops = { static const struct skl_dsp_fw_ops kbl_fw_ops = {
.set_state_D0 = skl_set_dsp_D0, .set_state_D0 = skl_set_dsp_D0,
.set_state_D3 = skl_set_dsp_D3, .set_state_D3 = skl_set_dsp_D3,
.load_fw = skl_load_base_firmware, .load_fw = skl_load_base_firmware,
...@@ -561,9 +561,13 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, ...@@ -561,9 +561,13 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
sst->fw_ops = skl_fw_ops; ret = skl_ipc_init(dev, skl);
if (ret) {
skl_dsp_free(sst);
return ret;
}
skl->cores.count = 2; sst->fw_ops = skl_fw_ops;
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -44,6 +44,13 @@ ...@@ -44,6 +44,13 @@
#define SKL_DEFAULT_MIC_SEL_GAIN 0x3FF #define SKL_DEFAULT_MIC_SEL_GAIN 0x3FF
#define SKL_MIC_SEL_SWITCH 0x3 #define SKL_MIC_SEL_SWITCH 0x3
#define SKL_OUTPUT_PIN 0
#define SKL_INPUT_PIN 1
#define SKL_MAX_PATH_CONFIGS 8
#define SKL_MAX_MODULES_IN_PIPE 8
#define SKL_MAX_MODULE_FORMATS 32
#define SKL_MAX_MODULE_RESOURCES 32
enum skl_channel_index { enum skl_channel_index {
SKL_CHANNEL_LEFT = 0, SKL_CHANNEL_LEFT = 0,
SKL_CHANNEL_RIGHT = 1, SKL_CHANNEL_RIGHT = 1,
...@@ -131,6 +138,11 @@ struct skl_cpr_cfg { ...@@ -131,6 +138,11 @@ struct skl_cpr_cfg {
struct skl_cpr_gtw_cfg gtw_cfg; struct skl_cpr_gtw_cfg gtw_cfg;
} __packed; } __packed;
struct skl_cpr_pin_fmt {
u32 sink_id;
struct skl_audio_data_format src_fmt;
struct skl_audio_data_format dst_fmt;
} __packed;
struct skl_src_module_cfg { struct skl_src_module_cfg {
struct skl_base_cfg base_cfg; struct skl_base_cfg base_cfg;
...@@ -214,6 +226,7 @@ struct skl_kpb_params { ...@@ -214,6 +226,7 @@ struct skl_kpb_params {
}; };
struct skl_module_inst_id { struct skl_module_inst_id {
uuid_le mod_uuid;
int module_id; int module_id;
u32 instance_id; u32 instance_id;
int pvt_id; int pvt_id;
...@@ -266,6 +279,23 @@ struct skl_pipe_params { ...@@ -266,6 +279,23 @@ struct skl_pipe_params {
unsigned int link_bps; unsigned int link_bps;
}; };
struct skl_pipe_fmt {
u32 freq;
u8 channels;
u8 bps;
};
struct skl_pipe_mcfg {
u8 res_idx;
u8 fmt_idx;
};
struct skl_path_config {
u8 mem_pages;
struct skl_pipe_fmt in_fmt;
struct skl_pipe_fmt out_fmt;
};
struct skl_pipe { struct skl_pipe {
u8 ppl_id; u8 ppl_id;
u8 pipe_priority; u8 pipe_priority;
...@@ -274,6 +304,10 @@ struct skl_pipe { ...@@ -274,6 +304,10 @@ struct skl_pipe {
u8 lp_mode; u8 lp_mode;
struct skl_pipe_params *p_params; struct skl_pipe_params *p_params;
enum skl_pipe_state state; enum skl_pipe_state state;
u8 direction;
u8 cur_config_idx;
u8 nr_cfgs;
struct skl_path_config configs[SKL_MAX_PATH_CONFIGS];
struct list_head w_list; struct list_head w_list;
bool passthru; bool passthru;
}; };
...@@ -292,9 +326,57 @@ enum d0i3_capability { ...@@ -292,9 +326,57 @@ enum d0i3_capability {
SKL_D0I3_NON_STREAMING = 2, SKL_D0I3_NON_STREAMING = 2,
}; };
struct skl_module_pin_fmt {
u8 id;
struct skl_module_fmt fmt;
};
struct skl_module_iface {
u8 fmt_idx;
u8 nr_in_fmt;
u8 nr_out_fmt;
struct skl_module_pin_fmt inputs[MAX_IN_QUEUE];
struct skl_module_pin_fmt outputs[MAX_OUT_QUEUE];
};
struct skl_module_pin_resources {
u8 pin_index;
u32 buf_size;
};
struct skl_module_res {
u8 id;
u32 is_pages;
u32 cps;
u32 ibs;
u32 obs;
u32 dma_buffer_size;
u32 cpc;
u8 nr_input_pins;
u8 nr_output_pins;
struct skl_module_pin_resources input[MAX_IN_QUEUE];
struct skl_module_pin_resources output[MAX_OUT_QUEUE];
};
struct skl_module {
uuid_le uuid;
u8 loadable;
u8 input_pin_type;
u8 output_pin_type;
u8 max_input_pins;
u8 max_output_pins;
u8 nr_resources;
u8 nr_interfaces;
struct skl_module_res resources[SKL_MAX_MODULE_RESOURCES];
struct skl_module_iface formats[SKL_MAX_MODULE_FORMATS];
};
struct skl_module_cfg { struct skl_module_cfg {
u8 guid[16]; u8 guid[16];
struct skl_module_inst_id id; struct skl_module_inst_id id;
struct skl_module *module;
int res_idx;
int fmt_idx;
u8 domain; u8 domain;
bool homogenous_inputs; bool homogenous_inputs;
bool homogenous_outputs; bool homogenous_outputs;
...@@ -329,6 +411,7 @@ struct skl_module_cfg { ...@@ -329,6 +411,7 @@ struct skl_module_cfg {
enum skl_module_state m_state; enum skl_module_state m_state;
struct skl_pipe *pipe; struct skl_pipe *pipe;
struct skl_specific_cfg formats_config; struct skl_specific_cfg formats_config;
struct skl_pipe_mcfg mod_cfg[SKL_MAX_MODULES_IN_PIPE];
}; };
struct skl_algo_data { struct skl_algo_data {
......
...@@ -415,7 +415,7 @@ static int skl_free(struct hdac_ext_bus *ebus) ...@@ -415,7 +415,7 @@ static int skl_free(struct hdac_ext_bus *ebus)
snd_hdac_ext_stop_streams(ebus); snd_hdac_ext_stop_streams(ebus);
if (bus->irq >= 0) if (bus->irq >= 0)
free_irq(bus->irq, (void *)bus); free_irq(bus->irq, (void *)ebus);
snd_hdac_bus_free_stream_pages(bus); snd_hdac_bus_free_stream_pages(bus);
snd_hdac_stream_free_all(ebus); snd_hdac_stream_free_all(ebus);
snd_hdac_link_free_all(ebus); snd_hdac_link_free_all(ebus);
...@@ -528,7 +528,7 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr) ...@@ -528,7 +528,7 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr)
} }
/* Codec initialization */ /* Codec initialization */
static int skl_codec_create(struct hdac_ext_bus *ebus) static void skl_codec_create(struct hdac_ext_bus *ebus)
{ {
struct hdac_bus *bus = ebus_to_hbus(ebus); struct hdac_bus *bus = ebus_to_hbus(ebus);
int c, max_slots; int c, max_slots;
...@@ -559,8 +559,6 @@ static int skl_codec_create(struct hdac_ext_bus *ebus) ...@@ -559,8 +559,6 @@ static int skl_codec_create(struct hdac_ext_bus *ebus)
} }
} }
} }
return 0;
} }
static const struct hdac_bus_ops bus_core_ops = { static const struct hdac_bus_ops bus_core_ops = {
...@@ -612,9 +610,7 @@ static void skl_probe_work(struct work_struct *work) ...@@ -612,9 +610,7 @@ static void skl_probe_work(struct work_struct *work)
dev_info(bus->dev, "no hda codecs found!\n"); dev_info(bus->dev, "no hda codecs found!\n");
/* create codec instances */ /* create codec instances */
err = skl_codec_create(ebus); skl_codec_create(ebus);
if (err < 0)
goto out_err;
if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
err = snd_hdac_display_power(bus, false); err = snd_hdac_display_power(bus, false);
...@@ -702,6 +698,8 @@ static int skl_first_init(struct hdac_ext_bus *ebus) ...@@ -702,6 +698,8 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
return -ENXIO; return -ENXIO;
} }
skl_init_chip(bus, true);
snd_hdac_bus_parse_capabilities(bus); snd_hdac_bus_parse_capabilities(bus);
if (skl_acquire_irq(ebus, 0) < 0) if (skl_acquire_irq(ebus, 0) < 0)
...@@ -982,6 +980,11 @@ static struct sst_acpi_mach sst_kbl_devdata[] = { ...@@ -982,6 +980,11 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
.quirk_data = &kbl_poppy_codecs, .quirk_data = &kbl_poppy_codecs,
.pdata = &skl_dmic_data .pdata = &skl_dmic_data
}, },
{
.id = "10EC5663",
.drv_name = "kbl_rt5663",
.fw_filename = "intel/dsp_fw_kbl.bin",
},
{} {}
}; };
...@@ -995,6 +998,14 @@ static struct sst_acpi_mach sst_glk_devdata[] = { ...@@ -995,6 +998,14 @@ static struct sst_acpi_mach sst_glk_devdata[] = {
{} {}
}; };
static const struct sst_acpi_mach sst_cnl_devdata[] = {
{
.id = "INT34C2",
.drv_name = "cnl_rt274",
.fw_filename = "intel/dsp_fw_cnl.bin",
},
};
/* PCI IDs */ /* PCI IDs */
static const struct pci_device_id skl_ids[] = { static const struct pci_device_id skl_ids[] = {
/* Sunrise Point-LP */ /* Sunrise Point-LP */
...@@ -1009,6 +1020,9 @@ static const struct pci_device_id skl_ids[] = { ...@@ -1009,6 +1020,9 @@ static const struct pci_device_id skl_ids[] = {
/* GLK */ /* GLK */
{ PCI_DEVICE(0x8086, 0x3198), { PCI_DEVICE(0x8086, 0x3198),
.driver_data = (unsigned long)&sst_glk_devdata}, .driver_data = (unsigned long)&sst_glk_devdata},
/* CNL */
{ PCI_DEVICE(0x8086, 0x9dc8),
.driver_data = (unsigned long)&sst_cnl_devdata},
{ 0, } { 0, }
}; };
MODULE_DEVICE_TABLE(pci, skl_ids); MODULE_DEVICE_TABLE(pci, skl_ids);
......
...@@ -71,6 +71,8 @@ struct skl { ...@@ -71,6 +71,8 @@ struct skl {
struct work_struct probe_work; struct work_struct probe_work;
struct skl_debug *debugfs; struct skl_debug *debugfs;
u8 nr_modules;
struct skl_module **modules;
}; };
#define skl_to_ebus(s) (&(s)->ebus) #define skl_to_ebus(s) (&(s)->ebus)
...@@ -90,6 +92,7 @@ struct skl_machine_pdata { ...@@ -90,6 +92,7 @@ struct skl_machine_pdata {
struct skl_dsp_ops { struct skl_dsp_ops {
int id; int id;
unsigned int num_cores;
struct skl_dsp_loader_ops (*loader_ops)(void); struct skl_dsp_loader_ops (*loader_ops)(void);
int (*init)(struct device *dev, void __iomem *mmio_base, int (*init)(struct device *dev, void __iomem *mmio_base,
int irq, const char *fw_name, int irq, const char *fw_name,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment