Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
authorMark Brown <broonie@kernel.org>
Fri, 10 Nov 2017 21:30:53 +0000 (21:30 +0000)
committerMark Brown <broonie@kernel.org>
Fri, 10 Nov 2017 21:30:53 +0000 (21:30 +0000)
41 files changed:
include/sound/soc-acpi-intel-match.h [new file with mode: 0644]
include/sound/soc-acpi.h [new file with mode: 0644]
include/sound/soc.h
sound/soc/Kconfig
sound/soc/Makefile
sound/soc/codecs/hdac_hdmi.c
sound/soc/intel/Kconfig
sound/soc/intel/Makefile
sound/soc/intel/atom/sst-mfld-platform-compress.c
sound/soc/intel/atom/sst-mfld-platform.h
sound/soc/intel/atom/sst/sst_acpi.c
sound/soc/intel/atom/sst/sst_loader.c
sound/soc/intel/atom/sst/sst_stream.c
sound/soc/intel/boards/Kconfig [new file with mode: 0644]
sound/soc/intel/boards/bxt_da7219_max98357a.c
sound/soc/intel/boards/bytcht_da7213.c
sound/soc/intel/boards/bytcht_es8316.c
sound/soc/intel/boards/bytcht_nocodec.c
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/intel/boards/bytcr_rt5651.c
sound/soc/intel/boards/cht_bsw_max98090_ti.c
sound/soc/intel/boards/cht_bsw_rt5645.c
sound/soc/intel/boards/cht_bsw_rt5672.c
sound/soc/intel/boards/kbl_rt5663_max98927.c
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
sound/soc/intel/boards/skl_nau88l25_max98357a.c
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
sound/soc/intel/common/Makefile
sound/soc/intel/common/soc-acpi-intel-byt-match.c [new file with mode: 0644]
sound/soc/intel/common/soc-acpi-intel-cht-match.c [new file with mode: 0644]
sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c [new file with mode: 0644]
sound/soc/intel/common/sst-acpi.c
sound/soc/intel/common/sst-acpi.h [deleted file]
sound/soc/intel/common/sst-firmware.c
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl-topology.h
sound/soc/intel/skylake/skl.c
sound/soc/intel/skylake/skl.h
sound/soc/soc-acpi.c [moved from sound/soc/intel/common/sst-match-acpi.c with 63% similarity]

diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h
new file mode 100644 (file)
index 0000000..1a9191c
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * Copyright (C) 2017, Intel Corporation. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __LINUX_SND_SOC_ACPI_INTEL_MATCH_H
+#define __LINUX_SND_SOC_ACPI_INTEL_MATCH_H
+
+#include <linux/stddef.h>
+#include <linux/acpi.h>
+
+/*
+ * these tables are not constants, some fields can be used for
+ * pdata or machine ops
+ */
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_haswell_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_legacy_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[];
+
+#endif
diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h
new file mode 100644 (file)
index 0000000..a7d8d33
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2013-15, Intel Corporation. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __LINUX_SND_SOC_ACPI_H
+#define __LINUX_SND_SOC_ACPI_H
+
+#include <linux/stddef.h>
+#include <linux/acpi.h>
+
+struct snd_soc_acpi_package_context {
+       char *name;           /* package name */
+       int length;           /* number of elements */
+       struct acpi_buffer *format;
+       struct acpi_buffer *state;
+       bool data_valid;
+};
+
+#if IS_ENABLED(CONFIG_ACPI)
+/* translation fron HID to I2C name, needed for DAI codec_name */
+const char *snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]);
+bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
+                                   struct snd_soc_acpi_package_context *ctx);
+#else
+static inline const char *
+snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
+{
+       return NULL;
+}
+static inline bool
+snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
+                                  struct snd_soc_acpi_package_context *ctx)
+{
+       return false;
+}
+#endif
+
+/* acpi match */
+struct snd_soc_acpi_mach *
+snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines);
+
+/* acpi check hid */
+bool snd_soc_acpi_check_hid(const u8 hid[ACPI_ID_LEN]);
+
+/**
+ * snd_soc_acpi_mach: ACPI-based machine descriptor. Most of the fields are
+ * related to the hardware, except for the firmware and topology file names.
+ * A platform supported by legacy and Sound Open Firmware (SOF) would expose
+ * all firmware/topology related fields.
+ *
+ * @id: ACPI ID (usually the codec's) used to find a matching machine driver.
+ * @drv_name: machine driver name
+ * @fw_filename: firmware file name. Used when SOF is not enabled.
+ * @board: board name
+ * @machine_quirk: pointer to quirk, usually based on DMI information when
+ * ACPI ID alone is not sufficient, wrong or misleading
+ * @quirk_data: data used to uniquely identify a machine, usually a list of
+ * audio codecs whose presence if checked with ACPI
+ * @pdata: intended for platform data or machine specific-ops. This structure
+ *  is not constant since this field may be updated at run-time
+ * @sof_fw_filename: Sound Open Firmware file name, if enabled
+ * @sof_tplg_filename: Sound Open Firmware topology file name, if enabled
+ * @asoc_plat_name: ASoC platform name, used for binding machine drivers
+ * if non NULL
+ * @new_mach_data: machine driver private data fixup
+ */
+/* Descriptor for SST ASoC machine driver */
+struct snd_soc_acpi_mach {
+       const u8 id[ACPI_ID_LEN];
+       const char *drv_name;
+       const char *fw_filename;
+       const char *board;
+       struct snd_soc_acpi_mach * (*machine_quirk)(void *arg);
+       const void *quirk_data;
+       void *pdata;
+       const char *sof_fw_filename;
+       const char *sof_tplg_filename;
+       const char *asoc_plat_name;
+       struct platform_device * (*new_mach_data)(void *pdata);
+};
+
+#define SND_SOC_ACPI_MAX_CODECS 3
+
+/**
+ * struct snd_soc_acpi_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 snd_soc_acpi_codecs {
+       int num_codecs;
+       u8 codecs[SND_SOC_ACPI_MAX_CODECS][ACPI_ID_LEN];
+};
+
+/* check all codecs */
+struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg);
+
+#endif
index 0668cbd9f0b525b3b7654775621a14b7e83a916d..1a7323238c495d7d51313f6ccd8780291ff3e9e5 100644 (file)
@@ -1821,6 +1821,20 @@ struct snd_soc_dai *snd_soc_find_dai(
 
 #include <sound/soc-dai.h>
 
+static inline
+struct snd_soc_dai *snd_soc_card_get_codec_dai(struct snd_soc_card *card,
+                                              const char *dai_name)
+{
+       struct snd_soc_pcm_runtime *rtd;
+
+       list_for_each_entry(rtd, &card->rtd_list, list) {
+               if (!strcmp(rtd->codec_dai->name, dai_name))
+                       return rtd->codec_dai;
+       }
+
+       return NULL;
+}
+
 #ifdef CONFIG_DEBUG_FS
 extern struct dentry *snd_soc_debugfs_root;
 #endif
index c0abad2067e14a07feb3eee54209a3467517040c..d22758165496c966e7797e5ac2a2b446cd21d972 100644 (file)
@@ -36,6 +36,9 @@ config SND_SOC_COMPRESS
 config SND_SOC_TOPOLOGY
        bool
 
+config SND_SOC_ACPI
+       tristate
+
 # All the supported SoCs
 source "sound/soc/adi/Kconfig"
 source "sound/soc/amd/Kconfig"
index bf8c1e2ce0bfd9c294a8f622da99dcdc49cf1e8d..5327f4d6c668b6e6180849cd60e5d7de969089e1 100644 (file)
@@ -15,6 +15,12 @@ ifneq ($(CONFIG_SND_SOC_AC97_BUS),)
 snd-soc-core-objs += soc-ac97.o
 endif
 
+ifneq ($(CONFIG_SND_SOC_ACPI),)
+snd-soc-acpi-objs := soc-acpi.o
+endif
+
+obj-$(CONFIG_SND_SOC_ACPI) += snd-soc-acpi.o
+
 obj-$(CONFIG_SND_SOC)  += snd-soc-core.o
 obj-$(CONFIG_SND_SOC)  += codecs/
 obj-$(CONFIG_SND_SOC)  += generic/
index e824d47cc22b0fd3cc2cfe8de4491530cd182bd5..f3b4f4dfae6ad29cd9e7b34b38b54580ddea43b6 100644 (file)
@@ -942,7 +942,8 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev,
        if (!se)
                return -ENOMEM;
 
-       sprintf(kc_name, "Pin %d port %d Input", pin->nid, port->id);
+       snprintf(kc_name, NAME_SIZE, "Pin %d port %d Input",
+                                               pin->nid, port->id);
        kc->name = devm_kstrdup(&edev->hdac.dev, kc_name, GFP_KERNEL);
        if (!kc->name)
                return -ENOMEM;
@@ -1452,6 +1453,8 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
        int i, num_nodes;
        struct hdac_device *hdac = &edev->hdac;
        struct hdac_hdmi_priv *hdmi = edev->private_data;
+       struct hdac_hdmi_cvt *temp_cvt, *cvt_next;
+       struct hdac_hdmi_pin *temp_pin, *pin_next;
        int ret;
 
        hdac_hdmi_skl_enable_all_pins(hdac);
@@ -1481,32 +1484,54 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
                case AC_WID_AUD_OUT:
                        ret = hdac_hdmi_add_cvt(edev, nid);
                        if (ret < 0)
-                               return ret;
+                               goto free_widgets;
                        break;
 
                case AC_WID_PIN:
                        ret = hdac_hdmi_add_pin(edev, nid);
                        if (ret < 0)
-                               return ret;
+                               goto free_widgets;
                        break;
                }
        }
 
        hdac->end_nid = nid;
 
-       if (!hdmi->num_pin || !hdmi->num_cvt)
-               return -EIO;
+       if (!hdmi->num_pin || !hdmi->num_cvt) {
+               ret = -EIO;
+               goto free_widgets;
+       }
 
        ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt);
        if (ret) {
                dev_err(&hdac->dev, "Failed to create dais with err: %d\n",
                                                        ret);
-               return ret;
+               goto free_widgets;
        }
 
        *num_dais = hdmi->num_cvt;
+       ret = hdac_hdmi_init_dai_map(edev);
+       if (ret < 0)
+               goto free_widgets;
+
+       return ret;
+
+free_widgets:
+       list_for_each_entry_safe(temp_cvt, cvt_next, &hdmi->cvt_list, head) {
+               list_del(&temp_cvt->head);
+               kfree(temp_cvt->name);
+               kfree(temp_cvt);
+       }
+
+       list_for_each_entry_safe(temp_pin, pin_next, &hdmi->pin_list, head) {
+               for (i = 0; i < temp_pin->num_ports; i++)
+                       temp_pin->ports[i].pin = NULL;
+               kfree(temp_pin->ports);
+               list_del(&temp_pin->head);
+               kfree(temp_pin);
+       }
 
-       return hdac_hdmi_init_dai_map(edev);
+       return ret;
 }
 
 static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
@@ -1894,6 +1919,9 @@ static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
        struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
        struct hdac_hdmi_port *port;
 
+       if (!pcm)
+               return;
+
        if (list_empty(&pcm->port_list))
                return;
 
@@ -1912,6 +1940,9 @@ static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
        struct hdac_hdmi_priv *hdmi = edev->private_data;
        struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
 
+       if (!pcm)
+               return false;
+
        if (list_empty(&pcm->port_list))
                return false;
 
@@ -1925,6 +1956,9 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
        struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
        struct hdac_hdmi_port *port;
 
+       if (!pcm)
+               return 0;
+
        if (list_empty(&pcm->port_list))
                return 0;
 
@@ -1978,6 +2012,9 @@ 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.get_spk_alloc = hdac_hdmi_get_spk_alloc;
 
+       if (!hdac_id)
+               return -ENODEV;
+
        if (hdac_id->driver_data)
                hdmi_priv->drv_data =
                        (struct hdac_hdmi_drv_data *)hdac_id->driver_data;
index b3c7f554ec30efb4b66603e17b714777ededc215..bb8be10b843701f3ad8ea5bf22b194b40dbe24c8 100644 (file)
@@ -1,19 +1,3 @@
-config SND_MFLD_MACHINE
-       tristate "SOC Machine Audio driver for Intel Medfield MID platform"
-       depends on INTEL_SCU_IPC
-       select SND_SOC_SN95031
-       select SND_SST_ATOM_HIFI2_PLATFORM
-       select SND_SST_IPC_PCI
-       help
-          This adds support for ASoC machine driver for Intel(R) MID Medfield platform
-          used as alsa device in audio substem in Intel(R) MID devices
-          Say Y if you have such a device.
-          If unsure select "N".
-
-config SND_SST_ATOM_HIFI2_PLATFORM
-       tristate
-       select SND_SOC_COMPRESS
-
 config SND_SST_IPC
        tristate
 
@@ -27,10 +11,12 @@ config SND_SST_IPC_ACPI
        select SND_SOC_INTEL_SST
        select IOSF_MBI
 
+config SND_SOC_INTEL_COMMON
+       tristate
+
 config SND_SOC_INTEL_SST
        tristate
        select SND_SOC_INTEL_SST_ACPI if ACPI
-       select SND_SOC_INTEL_SST_MATCH if ACPI
 
 config SND_SOC_INTEL_SST_FIRMWARE
        tristate
@@ -39,280 +25,42 @@ config SND_SOC_INTEL_SST_FIRMWARE
 config SND_SOC_INTEL_SST_ACPI
        tristate
 
-config SND_SOC_INTEL_SST_MATCH
+config SND_SOC_ACPI_INTEL_MATCH
        tristate
+       select SND_SOC_ACPI if ACPI
+
+config SND_SOC_INTEL_SST_TOPLEVEL
+       tristate "Intel ASoC SST drivers"
+       depends on X86 || COMPILE_TEST
+       select SND_SOC_INTEL_MACH
+       select SND_SOC_INTEL_COMMON
 
 config SND_SOC_INTEL_HASWELL
-       tristate
+       tristate "Intel ASoC SST driver for Haswell/Broadwell"
+       depends on SND_SOC_INTEL_SST_TOPLEVEL && SND_DMA_SGBUF
+       depends on DMADEVICES
        select SND_SOC_INTEL_SST
        select SND_SOC_INTEL_SST_FIRMWARE
 
 config SND_SOC_INTEL_BAYTRAIL
-       tristate
-       select SND_SOC_INTEL_SST
-       select SND_SOC_INTEL_SST_FIRMWARE
-
-config SND_SOC_INTEL_HASWELL_MACH
-       tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
-       depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
-       depends on DMADEVICES
-       select SND_SOC_INTEL_HASWELL
-       select SND_SOC_RT5640
-       help
-         This adds support for the Lynxpoint Audio DSP on Intel(R) Haswell
-         Ultrabook platforms.
-         Say Y if you have such a device.
-         If unsure select "N".
-
-config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
-       tristate "ASoC Audio driver for Broxton with DA7219 and MAX98357A in I2S Mode"
-       depends on X86 && ACPI && I2C
-       select SND_SOC_INTEL_SKYLAKE
-       select SND_SOC_DA7219
-       select SND_SOC_MAX98357A
-       select SND_SOC_DMIC
-       select SND_SOC_HDAC_HDMI
-       select SND_HDA_DSP_LOADER
-       help
-          This adds support for ASoC machine driver for Broxton-P platforms
-          with DA7219 + MAX98357A I2S audio codec.
-          Say Y if you have such a device.
-          If unsure select "N".
-
-config SND_SOC_INTEL_BXT_RT298_MACH
-       tristate "ASoC Audio driver for Broxton with RT298 I2S mode"
-       depends on X86 && ACPI && I2C
-       select SND_SOC_INTEL_SKYLAKE
-       select SND_SOC_RT298
-       select SND_SOC_DMIC
-       select SND_SOC_HDAC_HDMI
-       select SND_HDA_DSP_LOADER
-       help
-          This adds support for ASoC machine driver for Broxton platforms
-          with RT286 I2S audio codec.
-          Say Y if you have such a device.
-          If unsure select "N".
-
-config SND_SOC_INTEL_BYT_RT5640_MACH
-       tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
-       depends on X86_INTEL_LPSS && I2C
+       tristate "Intel ASoC SST driver for Baytrail (legacy)"
+       depends on SND_SOC_INTEL_SST_TOPLEVEL
        depends on DMADEVICES
-       depends on SND_SST_IPC_ACPI = n
-       select SND_SOC_INTEL_BAYTRAIL
-       select SND_SOC_RT5640
-       help
-         This adds audio driver for Intel Baytrail platform based boards
-         with the RT5640 audio codec. This driver is deprecated, use
-         SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality.
-
-config SND_SOC_INTEL_BYT_MAX98090_MACH
-       tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec"
-       depends on X86_INTEL_LPSS && I2C
-       depends on DMADEVICES
-       depends on SND_SST_IPC_ACPI = n
-       select SND_SOC_INTEL_BAYTRAIL
-       select SND_SOC_MAX98090
-       help
-         This adds audio driver for Intel Baytrail platform based boards
-         with the MAX98090 audio codec.
-
-config SND_SOC_INTEL_BDW_RT5677_MACH
-       tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec"
-       depends on X86_INTEL_LPSS && GPIOLIB && I2C
-       depends on DMADEVICES
-       select SND_SOC_INTEL_HASWELL
-       select SND_SOC_RT5677
-       help
-         This adds support for Intel Broadwell platform based boards with
-         the RT5677 audio codec.
-
-config SND_SOC_INTEL_BROADWELL_MACH
-       tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
-       depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
-       depends on DMADEVICES
-       select SND_SOC_INTEL_HASWELL
-       select SND_SOC_RT286
-       help
-         This adds support for the Wilcatpoint Audio DSP on Intel(R) Broadwell
-         Ultrabook platforms.
-         Say Y if you have such a device.
-         If unsure select "N".
-
-config SND_SOC_INTEL_BYTCR_RT5640_MACH
-        tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5640 codec"
-       depends on X86 && I2C && ACPI
-       select SND_SOC_RT5640
-       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 and Baytrail-CR
-          platforms with RT5640 audio codec.
-          Say Y if you have such a device.
-          If unsure select "N".
-
-config SND_SOC_INTEL_BYTCR_RT5651_MACH
-        tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5651 codec"
-       depends on X86 && I2C && ACPI
-       select SND_SOC_RT5651
-       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 and Baytrail-CR
-          platforms with RT5651 audio codec.
-          Say Y if you have such a device.
-          If unsure select "N".
-
-config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
-        tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec"
-        depends on X86_INTEL_LPSS && I2C && ACPI
-        select SND_SOC_RT5670
-        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) Cherrytrail & Braswell
-          platforms with RT5672 audio codec.
-          Say Y if you have such a device.
-          If unsure select "N".
-
-config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
-       tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec"
-       depends on X86_INTEL_LPSS && I2C && ACPI
-       select SND_SOC_RT5645
-       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) Cherrytrail & Braswell
-         platforms with RT5645/5650 audio codec.
-         If unsure select "N".
-
-config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
-       tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec"
-       depends on X86_INTEL_LPSS && I2C && ACPI
-       select SND_SOC_MAX98090
-       select SND_SOC_TS3A227E
-       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) Cherrytrail & Braswell
-         platforms with MAX98090 audio codec it also can support TI jack chip as aux device.
-         If unsure select "N".
-
-config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
-       tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with DA7212/7213 codec"
-       depends on X86_INTEL_LPSS && I2C && ACPI
-       select SND_SOC_DA7213
-       select SND_SST_ATOM_HIFI2_PLATFORM
-       select SND_SST_IPC_ACPI
-       select SND_SOC_INTEL_SST_MATCH if ACPI
-       help
-         This adds support for ASoC machine driver for Intel(R) Baytrail & CherryTrail
-         platforms with DA7212/7213 audio codec.
-         If unsure select "N".
-
-config SND_SOC_INTEL_BYT_CHT_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
-       select SND_SST_ATOM_HIFI2_PLATFORM
-       select SND_SST_IPC_ACPI
-       select SND_SOC_INTEL_SST_MATCH if ACPI
-       help
-         This adds support for ASoC machine driver for the MinnowBoard Max or
-         Up boards and provides access to I2S signals on the Low-Speed
-         connector
-         If unsure select "N".
-
-config SND_SOC_INTEL_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".
+       select SND_SOC_INTEL_SST_FIRMWARE
 
-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 && SPI
-        select SND_SOC_INTEL_SST
-        select SND_SOC_INTEL_SKYLAKE
-        select SND_SOC_RT5663
-        select SND_SOC_RT5514
-        select SND_SOC_RT5514_SPI
-        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_SST_ATOM_HIFI2_PLATFORM
+       tristate "Intel ASoC SST driver for HiFi2 platforms (*field, *trail)"
+       depends on SND_SOC_INTEL_SST_TOPLEVEL && X86
+       select SND_SOC_COMPRESS
 
 config SND_SOC_INTEL_SKYLAKE
-       tristate
+       tristate "Intel ASoC SST driver for SKL/BXT/KBL/GLK/CNL"
+       depends on SND_SOC_INTEL_SST_TOPLEVEL && PCI && ACPI
        select SND_HDA_EXT_CORE
        select SND_HDA_DSP_LOADER
        select SND_SOC_TOPOLOGY
        select SND_SOC_INTEL_SST
 
-config SND_SOC_INTEL_SKL_RT286_MACH
-       tristate "ASoC Audio driver for SKL with RT286 I2S mode"
-       depends on X86 && ACPI && I2C
-       select SND_SOC_INTEL_SKYLAKE
-       select SND_SOC_RT286
-       select SND_SOC_DMIC
-       select SND_SOC_HDAC_HDMI
-       help
-          This adds support for ASoC machine driver for Skylake platforms
-          with RT286 I2S audio codec.
-          Say Y if you have such a device.
-          If unsure select "N".
-
-config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
-       tristate "ASoC Audio driver for SKL with NAU88L25 and SSM4567 in I2S Mode"
-       depends on X86_INTEL_LPSS && I2C
-       select SND_SOC_INTEL_SKYLAKE
-       select SND_SOC_NAU8825
-       select SND_SOC_SSM4567
-       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 NAU88L25 + SSM4567.
-         Say Y if you have such a device.
-         If unsure select "N".
-
-config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
-       tristate "ASoC Audio driver for SKL with NAU88L25 and MAX98357A in I2S Mode"
-       depends on X86_INTEL_LPSS && I2C
-       select SND_SOC_INTEL_SKYLAKE
-       select SND_SOC_NAU8825
-       select SND_SOC_MAX98357A
-       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 NAU88L25 + MAX98357A.
-         Say Y if you have such a device.
-         If unsure select "N".
+# ASoC codec drivers
+source "sound/soc/intel/boards/Kconfig"
index 62f37ffffdf00c95ad4f92f584ed85239abae4d0..b973d457e834a7719ed47fd737d5b216ab4285dd 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 # Core support
-obj-$(CONFIG_SND_SOC_INTEL_SST) += common/
+obj-$(CONFIG_SND_SOC_INTEL_COMMON) += common/
 
 # Platform Support
 obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += haswell/
index 1bead81bb5106b590259780d4bcdef86dba5fc03..1dbcab5a6ff0bf1fdf509a837f5e23125abc86bd 100644 (file)
@@ -259,7 +259,7 @@ static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream,
        return stream->compr_ops->set_metadata(sst->dev, stream->id, metadata);
 }
 
-struct snd_compr_ops sst_platform_compr_ops = {
+const struct snd_compr_ops sst_platform_compr_ops = {
 
        .open = sst_platform_compr_open,
        .free = sst_platform_compr_free,
index cb32cc7e5ec1f17484dc94f73a0a72cae38d9903..31a58c25472cb51be10c83143a0fac237fec9293 100644 (file)
@@ -25,7 +25,7 @@
 #include "sst-atom-controls.h"
 
 extern struct sst_device *sst;
-extern struct snd_compr_ops sst_platform_compr_ops;
+extern const struct snd_compr_ops sst_platform_compr_ops;
 
 #define SST_MONO               1
 #define SST_STEREO             2
index 0e928d54305dad366586c6d2ec56829e5bb75ed2..32d6e02e21049719feb32691ee0ded359b5a4572 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/io.h>
-#include <linux/miscdevice.h>
 #include <linux/platform_device.h>
 #include <linux/firmware.h>
 #include <linux/pm_runtime.h>
 #include <acpi/acpi_bus.h>
 #include <asm/cpu_device_id.h>
 #include <asm/iosf_mbi.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
 #include "../sst-mfld-platform.h"
 #include "../../common/sst-dsp.h"
-#include "../../common/sst-acpi.h"
 #include "sst.h"
 
 /* LPE viewpoint addresses */
@@ -239,19 +239,26 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
        return 0;
 }
 
+static int is_byt(void)
+{
+       bool status = false;
+       static const struct x86_cpu_id cpu_ids[] = {
+               { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
+               {}
+       };
+       if (x86_match_cpu(cpu_ids))
+               status = true;
+       return status;
+}
 
 static int is_byt_cr(struct device *dev, bool *bytcr)
 {
        int status = 0;
 
        if (IS_ENABLED(CONFIG_IOSF_MBI)) {
-               static const struct x86_cpu_id cpu_ids[] = {
-                       { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
-                       {}
-               };
                u32 bios_status;
 
-               if (!x86_match_cpu(cpu_ids) || !iosf_mbi_available()) {
+               if (!is_byt() || !iosf_mbi_available()) {
                        /* bail silently */
                        return status;
                }
@@ -285,7 +292,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
        int ret = 0;
        struct intel_sst_drv *ctx;
        const struct acpi_device_id *id;
-       struct sst_acpi_mach *mach;
+       struct snd_soc_acpi_mach *mach;
        struct platform_device *mdev;
        struct platform_device *plat_dev;
        struct sst_platform_info *pdata;
@@ -297,13 +304,17 @@ static int sst_acpi_probe(struct platform_device *pdev)
                return -ENODEV;
        dev_dbg(dev, "for %s\n", id->id);
 
-       mach = (struct sst_acpi_mach *)id->driver_data;
-       mach = sst_acpi_find_machine(mach);
+       mach = (struct snd_soc_acpi_mach *)id->driver_data;
+       mach = snd_soc_acpi_find_machine(mach);
        if (mach == NULL) {
                dev_err(dev, "No matching machine driver found\n");
                return -ENODEV;
        }
 
+       if (is_byt())
+               mach->pdata = &byt_rvp_platform_data;
+       else
+               mach->pdata = &chv_platform_data;
        pdata = mach->pdata;
 
        ret = kstrtouint(id->id, 16, &dev_id);
@@ -381,286 +392,9 @@ static int sst_acpi_remove(struct platform_device *pdev)
        return 0;
 }
 
-static unsigned long cht_machine_id;
-
-#define CHT_SURFACE_MACH 1
-#define BYT_THINKPAD_10  2
-
-static int cht_surface_quirk_cb(const struct dmi_system_id *id)
-{
-       cht_machine_id = CHT_SURFACE_MACH;
-       return 1;
-}
-
-static int byt_thinkpad10_quirk_cb(const struct dmi_system_id *id)
-{
-       cht_machine_id = BYT_THINKPAD_10;
-       return 1;
-}
-
-
-static const struct dmi_system_id byt_table[] = {
-       {
-               .callback = byt_thinkpad10_quirk_cb,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
-               },
-       },
-       {
-               .callback = byt_thinkpad10_quirk_cb,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
-               },
-       },
-       {
-               .callback = byt_thinkpad10_quirk_cb,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
-               },
-       },
-       { }
-};
-
-static const struct dmi_system_id cht_table[] = {
-       {
-               .callback = cht_surface_quirk_cb,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
-               },
-       },
-       { }
-};
-
-
-static struct sst_acpi_mach cht_surface_mach = {
-       .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 = {
-       .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)
-{
-       struct sst_acpi_mach *mach = arg;
-
-       dmi_check_system(cht_table);
-
-       if (cht_machine_id == CHT_SURFACE_MACH)
-               return &cht_surface_mach;
-       else
-               return mach;
-}
-
-static struct sst_acpi_mach *byt_quirk(void *arg)
-{
-       struct sst_acpi_mach *mach = arg;
-
-       dmi_check_system(byt_table);
-
-       if (cht_machine_id == BYT_THINKPAD_10)
-               return &byt_thinkpad_10;
-       else
-               return mach;
-}
-
-
-static struct sst_acpi_mach sst_acpi_bytcr[] = {
-       {
-               .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 */
-       {
-               .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
-        */
-       {
-               .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[] = {
-       {
-               .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 */
-       {
-               .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 */
-       {
-               .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
-        */
-       {
-               .id = "808622A8",
-               .drv_name = "bytcht_nocodec",
-               .fw_filename = "intel/fw_sst_22a8.bin",
-               .board = "bytcht_nocodec",
-               .pdata = &chv_platform_data
-       },
-#endif
-       {},
-};
-
 static const struct acpi_device_id sst_acpi_ids[] = {
-       { "80860F28", (unsigned long)&sst_acpi_bytcr},
-       { "808622A8", (unsigned long) &sst_acpi_chv},
+       { "80860F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
+       { "808622A8", (unsigned long)&snd_soc_acpi_intel_cherrytrail_machines},
        { },
 };
 
index 33917146d9c445d9919c3dacad2bf904f04b1d9a..a686eef2cf7f7a1a4a7f7f23a00808122734a850 100644 (file)
@@ -415,7 +415,6 @@ int sst_load_fw(struct intel_sst_drv *sst_drv_ctx)
                        return ret_val;
        }
 
-       BUG_ON(!sst_drv_ctx->fw_in_mem);
        block = sst_create_block(sst_drv_ctx, 0, FW_DWNL_ID);
        if (block == NULL)
                return -ENOMEM;
index 83d8dda152331054650f6fca0d5d09d160d73108..65e257b17a7efe69ecf8810622db647f373b820a 100644 (file)
@@ -45,7 +45,6 @@ int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
        void *data = NULL;
 
        dev_dbg(sst_drv_ctx->dev, "Enter\n");
-       BUG_ON(!params);
 
        str_params = (struct snd_sst_params *)params;
        memset(&alloc_param, 0, sizeof(alloc_param));
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
new file mode 100644 (file)
index 0000000..6f75470
--- /dev/null
@@ -0,0 +1,265 @@
+config SND_SOC_INTEL_MACH
+       tristate "Intel Audio machine drivers"
+       depends on SND_SOC_INTEL_SST_TOPLEVEL
+       select SND_SOC_ACPI_INTEL_MATCH if ACPI
+
+if SND_SOC_INTEL_MACH
+
+config SND_MFLD_MACHINE
+       tristate "SOC Machine Audio driver for Intel Medfield MID platform"
+       depends on INTEL_SCU_IPC
+       select SND_SOC_SN95031
+       depends on SND_SST_ATOM_HIFI2_PLATFORM
+       select SND_SST_IPC_PCI
+       help
+          This adds support for ASoC machine driver for Intel(R) MID Medfield platform
+          used as alsa device in audio substem in Intel(R) MID devices
+          Say Y if you have such a device.
+          If unsure select "N".
+
+config SND_SOC_INTEL_HASWELL_MACH
+       tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
+       depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
+       depends on SND_SOC_INTEL_HASWELL
+       select SND_SOC_RT5640
+       help
+         This adds support for the Lynxpoint Audio DSP on Intel(R) Haswell
+         Ultrabook platforms.
+         Say Y if you have such a device.
+         If unsure select "N".
+
+config SND_SOC_INTEL_BDW_RT5677_MACH
+       tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec"
+       depends on X86_INTEL_LPSS && GPIOLIB && I2C
+       depends on SND_SOC_INTEL_HASWELL
+       select SND_SOC_RT5677
+       help
+         This adds support for Intel Broadwell platform based boards with
+         the RT5677 audio codec.
+
+config SND_SOC_INTEL_BROADWELL_MACH
+       tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
+       depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
+       depends on SND_SOC_INTEL_HASWELL
+       select SND_SOC_RT286
+       help
+         This adds support for the Wilcatpoint Audio DSP on Intel(R) Broadwell
+         Ultrabook platforms.
+         Say Y if you have such a device.
+         If unsure select "N".
+
+config SND_SOC_INTEL_BYT_MAX98090_MACH
+       tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec"
+       depends on X86_INTEL_LPSS && I2C
+       depends on SND_SST_IPC_ACPI = n
+       depends on SND_SOC_INTEL_BAYTRAIL
+       select SND_SOC_MAX98090
+       help
+         This adds audio driver for Intel Baytrail platform based boards
+         with the MAX98090 audio codec.
+
+config SND_SOC_INTEL_BYT_RT5640_MACH
+       tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
+       depends on X86_INTEL_LPSS && I2C
+       depends on SND_SST_IPC_ACPI = n
+       depends on SND_SOC_INTEL_BAYTRAIL
+       select SND_SOC_RT5640
+       help
+         This adds audio driver for Intel Baytrail platform based boards
+         with the RT5640 audio codec. This driver is deprecated, use
+         SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality.
+
+config SND_SOC_INTEL_BYTCR_RT5640_MACH
+        tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5640 codec"
+       depends on X86 && I2C && ACPI
+       select SND_SOC_RT5640
+       depends on SND_SST_ATOM_HIFI2_PLATFORM
+       select SND_SST_IPC_ACPI
+       help
+          This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
+          platforms with RT5640 audio codec.
+          Say Y if you have such a device.
+          If unsure select "N".
+
+config SND_SOC_INTEL_BYTCR_RT5651_MACH
+        tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5651 codec"
+       depends on X86 && I2C && ACPI
+       select SND_SOC_RT5651
+       depends on SND_SST_ATOM_HIFI2_PLATFORM
+       select SND_SST_IPC_ACPI
+       help
+          This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
+          platforms with RT5651 audio codec.
+          Say Y if you have such a device.
+          If unsure select "N".
+
+config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
+        tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec"
+       depends on X86_INTEL_LPSS && I2C && ACPI
+        select SND_SOC_RT5670
+        depends on SND_SST_ATOM_HIFI2_PLATFORM
+        select SND_SST_IPC_ACPI
+        help
+          This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
+          platforms with RT5672 audio codec.
+          Say Y if you have such a device.
+          If unsure select "N".
+
+config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
+       tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec"
+       depends on X86_INTEL_LPSS && I2C && ACPI
+       select SND_SOC_RT5645
+       depends on SND_SST_ATOM_HIFI2_PLATFORM
+       select SND_SST_IPC_ACPI
+       help
+         This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
+         platforms with RT5645/5650 audio codec.
+         If unsure select "N".
+
+config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
+       tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec"
+       depends on X86_INTEL_LPSS && I2C && ACPI
+       select SND_SOC_MAX98090
+       select SND_SOC_TS3A227E
+       depends on SND_SST_ATOM_HIFI2_PLATFORM
+       select SND_SST_IPC_ACPI
+       help
+         This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
+         platforms with MAX98090 audio codec it also can support TI jack chip as aux device.
+         If unsure select "N".
+
+config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
+       tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with DA7212/7213 codec"
+       depends on X86_INTEL_LPSS && I2C && ACPI
+       select SND_SOC_DA7213
+       depends on SND_SST_ATOM_HIFI2_PLATFORM
+       select SND_SST_IPC_ACPI
+       help
+         This adds support for ASoC machine driver for Intel(R) Baytrail & CherryTrail
+         platforms with DA7212/7213 audio codec.
+         If unsure select "N".
+
+config SND_SOC_INTEL_BYT_CHT_ES8316_MACH
+       tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with ES8316 codec"
+       depends on X86_INTEL_LPSS && I2C && ACPI
+       select SND_SOC_ES8316
+       depends on SND_SST_ATOM_HIFI2_PLATFORM
+       select SND_SST_IPC_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
+       depends on SND_SST_ATOM_HIFI2_PLATFORM
+       select SND_SST_IPC_ACPI
+       help
+         This adds support for ASoC machine driver for the MinnowBoard Max or
+         Up boards and provides access to I2S signals on the Low-Speed
+         connector
+         If unsure select "N".
+
+config SND_SOC_INTEL_SKL_RT286_MACH
+       tristate "ASoC Audio driver for SKL with RT286 I2S mode"
+       depends on X86 && ACPI && I2C
+       depends on SND_SOC_INTEL_SKYLAKE
+       select SND_SOC_RT286
+       select SND_SOC_DMIC
+       select SND_SOC_HDAC_HDMI
+       help
+          This adds support for ASoC machine driver for Skylake platforms
+          with RT286 I2S audio codec.
+          Say Y if you have such a device.
+          If unsure select "N".
+
+config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
+       tristate "ASoC Audio driver for SKL with NAU88L25 and SSM4567 in I2S Mode"
+       depends on X86_INTEL_LPSS && I2C
+       depends on SND_SOC_INTEL_SKYLAKE
+       select SND_SOC_NAU8825
+       select SND_SOC_SSM4567
+       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 NAU88L25 + SSM4567.
+         Say Y if you have such a device.
+         If unsure select "N".
+
+config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
+       tristate "ASoC Audio driver for SKL with NAU88L25 and MAX98357A in I2S Mode"
+       depends on X86_INTEL_LPSS && I2C
+       depends on SND_SOC_INTEL_SKYLAKE
+       select SND_SOC_NAU8825
+       select SND_SOC_MAX98357A
+       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 NAU88L25 + MAX98357A.
+         Say Y if you have such a device.
+         If unsure select "N".
+
+config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
+       tristate "ASoC Audio driver for Broxton with DA7219 and MAX98357A in I2S Mode"
+       depends on X86 && ACPI && I2C
+       depends on SND_SOC_INTEL_SKYLAKE
+       select SND_SOC_DA7219
+       select SND_SOC_MAX98357A
+       select SND_SOC_DMIC
+       select SND_SOC_HDAC_HDMI
+       select SND_HDA_DSP_LOADER
+       help
+          This adds support for ASoC machine driver for Broxton-P platforms
+          with DA7219 + MAX98357A I2S audio codec.
+          Say Y if you have such a device.
+          If unsure select "N".
+
+config SND_SOC_INTEL_BXT_RT298_MACH
+       tristate "ASoC Audio driver for Broxton with RT298 I2S mode"
+       depends on X86 && ACPI && I2C
+       depends on SND_SOC_INTEL_SKYLAKE
+       select SND_SOC_RT298
+       select SND_SOC_DMIC
+       select SND_SOC_HDAC_HDMI
+       select SND_HDA_DSP_LOADER
+       help
+          This adds support for ASoC machine driver for Broxton platforms
+          with RT286 I2S audio codec.
+          Say Y if you have such a device.
+          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
+       depends on 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 && SPI
+        select SND_SOC_INTEL_SST
+        depends on SND_SOC_INTEL_SKYLAKE
+        select SND_SOC_RT5663
+        select SND_SOC_RT5514
+        select SND_SOC_RT5514_SPI
+        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".
+
+endif
index ce35ec7884d1e59873e184d3dd8f5bf0711806a6..f8a91a6f2a17af51c68e69ec88b907e718e72952 100644 (file)
@@ -55,20 +55,6 @@ enum {
        BXT_DPCM_AUDIO_HDMI3_PB,
 };
 
-static inline struct snd_soc_dai *bxt_get_codec_dai(struct snd_soc_card *card)
-{
-       struct snd_soc_pcm_runtime *rtd;
-
-       list_for_each_entry(rtd, &card->rtd_list, list) {
-
-               if (!strncmp(rtd->codec_dai->name, BXT_DIALOG_CODEC_DAI,
-                            strlen(BXT_DIALOG_CODEC_DAI)))
-                       return rtd->codec_dai;
-       }
-
-       return NULL;
-}
-
 static int platform_clock_control(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *k, int  event)
 {
@@ -77,7 +63,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
        struct snd_soc_card *card = dapm->card;
        struct snd_soc_dai *codec_dai;
 
-       codec_dai = bxt_get_codec_dai(card);
+       codec_dai = snd_soc_card_get_codec_dai(card, BXT_DIALOG_CODEC_DAI);
        if (!codec_dai) {
                dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
                return -EIO;
index 18873e23f404b1aec4f5ef05a8483887529fc309..c4d82ad41bd70b432ee82b327f6ce5ccd76024e5 100644 (file)
@@ -27,9 +27,9 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include <sound/soc-acpi.h>
 #include "../../codecs/da7213.h"
 #include "../atom/sst-atom-controls.h"
-#include "../common/sst-acpi.h"
 
 static const struct snd_kcontrol_new controls[] = {
        SOC_DAPM_PIN_SWITCH("Headphone Jack"),
@@ -185,19 +185,11 @@ static struct snd_soc_dai_link dailink[] = {
                .dpcm_playback = 1,
                .ops = &aif1_ops,
        },
-       [MERR_DPCM_COMPR] = {
-               .name = "Compressed Port",
-               .stream_name = "Compress",
-               .cpu_dai_name = "compress-cpu-dai",
-               .codec_dai_name = "snd-soc-dummy-dai",
-               .codec_name = "snd-soc-dummy",
-               .platform_name = "sst-mfld-platform",
-       },
        /* CODEC<->CODEC link */
        /* back ends */
        {
                .name = "SSP2-Codec",
-               .id = 1,
+               .id = 0,
                .cpu_dai_name = "ssp2-port",
                .platform_name = "sst-mfld-platform",
                .no_pcm = 1,
@@ -231,19 +223,18 @@ static char codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
 
 static int bytcht_da7213_probe(struct platform_device *pdev)
 {
-       int ret_val = 0;
-       int i;
        struct snd_soc_card *card;
-       struct sst_acpi_mach *mach;
+       struct snd_soc_acpi_mach *mach;
        const char *i2c_name = NULL;
        int dai_index = 0;
+       int ret_val = 0;
+       int i;
 
        mach = (&pdev->dev)->platform_data;
        card = &bytcht_da7213_card;
        card->dev = &pdev->dev;
 
        /* fix index of codec dai */
-       dai_index = MERR_DPCM_COMPR + 1;
        for (i = 0; i < ARRAY_SIZE(dailink); i++) {
                if (!strcmp(dailink[i].codec_name, "i2c-DLGS7213:00")) {
                        dai_index = i;
@@ -252,8 +243,8 @@ static int bytcht_da7213_probe(struct platform_device *pdev)
        }
 
        /* fixup codec name based on HID */
-       i2c_name = sst_acpi_find_name_from_hid(mach->id);
-       if (i2c_name != NULL) {
+       i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
+       if (i2c_name) {
                snprintf(codec_name, sizeof(codec_name),
                        "%s%s", "i2c-", i2c_name);
                dailink[dai_index].codec_name = codec_name;
index 52635462dac63ec3dbb1f61bf6d0d33ee14b0d0e..8088396717e35b1133306bc6f4a95feac2b3aa7e 100644 (file)
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include <sound/soc-acpi.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),
 
@@ -208,22 +194,13 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
                .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,
+               .id = 0,
                .cpu_dai_name = "ssp2-port",
                .platform_name = "sst-mfld-platform",
                .no_pcm = 1,
index 1dd9441806fa31d02c7d3808a35d2d3e8fd304f1..b80ec027a0e82b5d33411d7398dcd7cdeb9da7fa 100644 (file)
@@ -133,19 +133,11 @@ static struct snd_soc_dai_link dais[] = {
                .dpcm_playback = 1,
                .ops = &aif1_ops,
        },
-       [MERR_DPCM_COMPR] = {
-               .name = "Compressed Port",
-               .stream_name = "Compress",
-               .cpu_dai_name = "compress-cpu-dai",
-               .codec_dai_name = "snd-soc-dummy-dai",
-               .codec_name = "snd-soc-dummy",
-               .platform_name = "sst-mfld-platform",
-       },
        /* CODEC<->CODEC link */
        /* back ends */
        {
                .name = "SSP2-LowSpeed Connector",
-               .id = 1,
+               .id = 0,
                .cpu_dai_name = "ssp2-port",
                .platform_name = "sst-mfld-platform",
                .no_pcm = 1,
index 4a76b099a508954c4cd3e6b3a3bfdfda1755b0fe..f2c0fc415e52fccfb138597f0ff5c3ef6f6136ef 100644 (file)
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
+#include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
 #include <asm/cpu_device_id.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 <sound/jack.h>
+#include <sound/soc-acpi.h>
 #include "../../codecs/rt5640.h"
 #include "../atom/sst-atom-controls.h"
-#include "../common/sst-acpi.h"
 #include "../common/sst-dsp.h"
 
 enum {
@@ -44,13 +44,13 @@ enum {
        BYT_RT5640_IN3_MAP,
 };
 
-#define BYT_RT5640_MAP(quirk)  ((quirk) & 0xff)
+#define BYT_RT5640_MAP(quirk)  ((quirk) &  GENMASK(7, 0))
 #define BYT_RT5640_DMIC_EN     BIT(16)
 #define BYT_RT5640_MONO_SPEAKER BIT(17)
 #define BYT_RT5640_DIFF_MIC     BIT(18) /* defaut is single-ended */
-#define BYT_RT5640_SSP2_AIF2     BIT(19) /* default is using AIF1  */
-#define BYT_RT5640_SSP0_AIF1     BIT(20)
-#define BYT_RT5640_SSP0_AIF2     BIT(21)
+#define BYT_RT5640_SSP2_AIF2    BIT(19) /* default is using AIF1  */
+#define BYT_RT5640_SSP0_AIF1    BIT(20)
+#define BYT_RT5640_SSP0_AIF2    BIT(21)
 #define BYT_RT5640_MCLK_EN     BIT(22)
 #define BYT_RT5640_MCLK_25MHZ  BIT(23)
 
@@ -145,22 +145,6 @@ static void log_quirks(struct device *dev)
 #define BYT_CODEC_DAI1 "rt5640-aif1"
 #define BYT_CODEC_DAI2 "rt5640-aif2"
 
-static inline struct snd_soc_dai *byt_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, BYT_CODEC_DAI1,
-                            strlen(BYT_CODEC_DAI1)))
-                       return rtd->codec_dai;
-               if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI2,
-                               strlen(BYT_CODEC_DAI2)))
-                       return rtd->codec_dai;
-
-       }
-       return NULL;
-}
-
 static int platform_clock_control(struct snd_soc_dapm_widget *w,
                                  struct snd_kcontrol *k, int  event)
 {
@@ -170,7 +154,10 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
        struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
        int ret;
 
-       codec_dai = byt_get_codec_dai(card);
+       codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
+       if (!codec_dai)
+               codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
+
        if (!codec_dai) {
                dev_err(card->dev,
                        "Codec dai not found; Unable to set platform clock\n");
@@ -178,7 +165,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
        }
 
        if (SND_SOC_DAPM_EVENT_ON(event)) {
-               if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) {
+               if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
                        ret = clk_prepare_enable(priv->mclk);
                        if (ret < 0) {
                                dev_err(card->dev,
@@ -199,7 +186,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
                                             48000 * 512,
                                             SND_SOC_CLOCK_IN);
                if (!ret) {
-                       if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk)
+                       if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
                                clk_disable_unprepare(priv->mclk);
                }
        }
@@ -376,8 +363,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
                },
-               .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
-                                                BYT_RT5640_MCLK_EN),
+               .driver_data = (void *)(BYT_RT5640_IN1_MAP |
+                                       BYT_RT5640_MCLK_EN),
        },
        {
                .callback = byt_rt5640_quirk_cb,
@@ -385,12 +372,11 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
                },
-               .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
-                                                BYT_RT5640_MONO_SPEAKER |
-                                                BYT_RT5640_DIFF_MIC |
-                                                BYT_RT5640_SSP0_AIF2 |
-                                                BYT_RT5640_MCLK_EN
-                                                ),
+               .driver_data = (void *)(BYT_RT5640_IN1_MAP |
+                                       BYT_RT5640_MONO_SPEAKER |
+                                       BYT_RT5640_DIFF_MIC |
+                                       BYT_RT5640_SSP0_AIF2 |
+                                       BYT_RT5640_MCLK_EN),
        },
        {
                .callback = byt_rt5640_quirk_cb,
@@ -398,9 +384,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."),
                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
                },
-               .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP |
-                                                BYT_RT5640_DMIC_EN |
-                                                BYT_RT5640_MCLK_EN),
+               .driver_data = (void *)(BYT_RT5640_DMIC2_MAP |
+                                       BYT_RT5640_DMIC_EN |
+                                       BYT_RT5640_MCLK_EN),
        },
        {
                .callback = byt_rt5640_quirk_cb,
@@ -408,8 +394,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
                },
-               .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
-                                                BYT_RT5640_MCLK_EN),
+               .driver_data = (void *)(BYT_RT5640_IN1_MAP |
+                                       BYT_RT5640_MCLK_EN),
        },
        {
                .callback = byt_rt5640_quirk_cb,
@@ -417,8 +403,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
                },
-               .driver_data = (unsigned long *)(BYT_RT5640_DMIC1_MAP |
-                                                BYT_RT5640_DMIC_EN),
+               .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+                                       BYT_RT5640_DMIC_EN),
        },
        {
                .callback = byt_rt5640_quirk_cb,
@@ -426,9 +412,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
                        DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
                },
-               .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP |
-                                               BYT_RT5640_MCLK_EN |
-                                               BYT_RT5640_SSP0_AIF1),
+               .driver_data = (void *)(BYT_RT5640_IN3_MAP |
+                                       BYT_RT5640_MCLK_EN |
+                                       BYT_RT5640_SSP0_AIF1),
        },
        {
                .callback = byt_rt5640_quirk_cb,
@@ -436,7 +422,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
                },
-               .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
+               .driver_data = (void *)(BYT_RT5640_IN1_MAP |
                                                 BYT_RT5640_MCLK_EN |
                                                 BYT_RT5640_SSP0_AIF1),
 
@@ -446,9 +432,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
                },
-               .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP |
-                                                BYT_RT5640_MCLK_EN |
-                                                BYT_RT5640_SSP0_AIF1),
+               .driver_data = (void *)(BYT_RT5640_IN3_MAP |
+                                       BYT_RT5640_MCLK_EN |
+                                       BYT_RT5640_SSP0_AIF1),
 
        },
        {}
@@ -456,12 +442,12 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 
 static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 {
-       int ret;
-       struct snd_soc_codec *codec = runtime->codec;
        struct snd_soc_card *card = runtime->card;
-       const struct snd_soc_dapm_route *custom_map;
        struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
+       struct snd_soc_codec *codec = runtime->codec;
+       const struct snd_soc_dapm_route *custom_map;
        int num_routes;
+       int ret;
 
        card->dapm.idle_bias_off = true;
 
@@ -549,7 +535,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
        snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
        snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
 
-       if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) {
+       if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
                /*
                 * The firmware might enable the clock at
                 * boot (this information may or may not
@@ -692,19 +678,11 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
                .dynamic = 1,
                .dpcm_playback = 1,
                .ops = &byt_rt5640_aif1_ops,
-       },
-       [MERR_DPCM_COMPR] = {
-               .name = "Baytrail Compressed Port",
-               .stream_name = "Baytrail 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 */
        {
                .name = "SSP2-Codec",
-               .id = 1,
+               .id = 0,
                .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */
                .platform_name = "sst-mfld-platform",
                .no_pcm = 1,
@@ -758,12 +736,12 @@ struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
 
 static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 {
-       int ret_val = 0;
-       struct sst_acpi_mach *mach;
+       struct byt_rt5640_private *priv;
+       struct snd_soc_acpi_mach *mach;
        const char *i2c_name = NULL;
+       int ret_val = 0;
+       int dai_index = 0;
        int i;
-       int dai_index;
-       struct byt_rt5640_private *priv;
 
        is_bytcr = false;
        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
@@ -776,7 +754,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
        snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
 
        /* fix index of codec dai */
-       dai_index = MERR_DPCM_COMPR + 1;
        for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
                if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) {
                        dai_index = i;
@@ -785,8 +762,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
        }
 
        /* fixup codec name based on HID */
-       i2c_name = sst_acpi_find_name_from_hid(mach->id);
-       if (i2c_name != NULL) {
+       i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
+       if (i2c_name) {
                snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
                        "%s%s", "i2c-", i2c_name);
 
@@ -819,7 +796,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
                /* format specified: 2 64-bit integers */
                struct acpi_buffer format = {sizeof("NN"), "NN"};
                struct acpi_buffer state = {0, NULL};
-               struct sst_acpi_package_context pkg_ctx;
+               struct snd_soc_acpi_package_context pkg_ctx;
                bool pkg_found = false;
 
                state.length = sizeof(chan_package);
@@ -831,7 +808,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
                pkg_ctx.state = &state;
                pkg_ctx.data_valid = false;
 
-               pkg_found = sst_acpi_find_package_from_hid(mach->id, &pkg_ctx);
+               pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
+                                                              &pkg_ctx);
                if (pkg_found) {
                        if (chan_package.aif_value == 1) {
                                dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
@@ -891,7 +869,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
                        byt_rt5640_cpu_dai_name;
        }
 
-       if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) {
+       if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
                priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
                if (IS_ERR(priv->mclk)) {
                        ret_val = PTR_ERR(priv->mclk);
index 4a3516b38c2c9727f7138054cee367ab5ede1205..d955836c6870a8ad7d6cbe4939fbc3c457738c77 100644 (file)
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
+#include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <asm/platform_sst_audio.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/jack.h>
+#include <sound/soc-acpi.h>
 #include "../../codecs/rt5651.h"
 #include "../atom/sst-atom-controls.h"
 
+enum {
+       BYT_RT5651_DMIC_MAP,
+       BYT_RT5651_IN1_MAP,
+       BYT_RT5651_IN2_MAP,
+};
+
+#define BYT_RT5651_MAP(quirk)  ((quirk) & GENMASK(7, 0))
+#define BYT_RT5651_DMIC_EN     BIT(16)
+#define BYT_RT5651_MCLK_EN     BIT(17)
+#define BYT_RT5651_MCLK_25MHZ  BIT(18)
+
+struct byt_rt5651_private {
+       struct clk *mclk;
+       struct snd_soc_jack jack;
+};
+
+static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC_MAP |
+                                       BYT_RT5651_DMIC_EN |
+                                       BYT_RT5651_MCLK_EN;
+
+static void log_quirks(struct device *dev)
+{
+       if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_DMIC_MAP)
+               dev_info(dev, "quirk DMIC_MAP enabled");
+       if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_MAP)
+               dev_info(dev, "quirk IN1_MAP enabled");
+       if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP)
+               dev_info(dev, "quirk IN2_MAP enabled");
+       if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
+               dev_info(dev, "quirk DMIC enabled");
+       if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
+               dev_info(dev, "quirk MCLK_EN enabled");
+       if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
+               dev_info(dev, "quirk MCLK_25MHZ enabled");
+}
+
+#define BYT_CODEC_DAI1 "rt5651-aif1"
+
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
+                                 struct snd_kcontrol *k, int  event)
+{
+       struct snd_soc_dapm_context *dapm = w->dapm;
+       struct snd_soc_card *card = dapm->card;
+       struct snd_soc_dai *codec_dai;
+       struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
+       int ret;
+
+       codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
+       if (!codec_dai) {
+               dev_err(card->dev,
+                       "Codec dai not found; Unable to set platform clock\n");
+               return -EIO;
+       }
+
+       if (SND_SOC_DAPM_EVENT_ON(event)) {
+               if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
+                       ret = clk_prepare_enable(priv->mclk);
+                       if (ret < 0) {
+                               dev_err(card->dev,
+                                       "could not configure MCLK state");
+                               return ret;
+                       }
+               }
+               ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
+                                            48000 * 512,
+                                            SND_SOC_CLOCK_IN);
+       } else {
+               /*
+                * Set codec clock source to internal clock before
+                * turning off the platform clock. Codec needs clock
+                * for Jack detection and button press
+                */
+               ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_RCCLK,
+                                            48000 * 512,
+                                            SND_SOC_CLOCK_IN);
+               if (!ret)
+                       if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
+                               clk_disable_unprepare(priv->mclk);
+       }
+
+       if (ret < 0) {
+               dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
 static const struct snd_soc_dapm_widget byt_rt5651_widgets[] = {
        SND_SOC_DAPM_HP("Headphone", NULL),
        SND_SOC_DAPM_MIC("Headset Mic", NULL),
        SND_SOC_DAPM_MIC("Internal Mic", NULL),
        SND_SOC_DAPM_SPK("Speaker", NULL),
+       SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+                           platform_clock_control, SND_SOC_DAPM_PRE_PMU |
+                           SND_SOC_DAPM_POST_PMD),
+
 };
 
 static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
+       {"Headphone", NULL, "Platform Clock"},
+       {"Headset Mic", NULL, "Platform Clock"},
+       {"Internal Mic", NULL, "Platform Clock"},
+       {"Speaker", NULL, "Platform Clock"},
+
        {"AIF1 Playback", NULL, "ssp2 Tx"},
        {"ssp2 Tx", NULL, "codec_out0"},
        {"ssp2 Tx", NULL, "codec_out1"},
@@ -47,38 +147,30 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
        {"ssp2 Rx", NULL, "AIF1 Capture"},
 
        {"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */
-       {"IN2P", NULL, "Headset Mic"},
        {"Headphone", NULL, "HPOL"},
        {"Headphone", NULL, "HPOR"},
        {"Speaker", NULL, "LOUTL"},
        {"Speaker", NULL, "LOUTR"},
 };
 
-static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic1_map[] = {
-       {"DMIC1", NULL, "Internal Mic"},
-};
-
-static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic2_map[] = {
-       {"DMIC2", NULL, "Internal Mic"},
+static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = {
+       {"IN2P", NULL, "Headset Mic"},
+       {"DMIC L1", NULL, "Internal Mic"},
+       {"DMIC R1", NULL, "Internal Mic"},
 };
 
 static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = {
        {"Internal Mic", NULL, "micbias1"},
+       {"IN2P", NULL, "Headset Mic"},
        {"IN1P", NULL, "Internal Mic"},
 };
 
-enum {
-       BYT_RT5651_DMIC1_MAP,
-       BYT_RT5651_DMIC2_MAP,
-       BYT_RT5651_IN1_MAP,
+static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map[] = {
+       {"Internal Mic", NULL, "micbias1"},
+       {"IN1P", NULL, "Headset Mic"},
+       {"IN2P", NULL, "Internal Mic"},
 };
 
-#define BYT_RT5651_MAP(quirk)  ((quirk) & 0xff)
-#define BYT_RT5651_DMIC_EN     BIT(16)
-
-static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC1_MAP |
-                                       BYT_RT5651_DMIC_EN;
-
 static const struct snd_kcontrol_new byt_rt5651_controls[] = {
        SOC_DAPM_PIN_SWITCH("Headphone"),
        SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -86,6 +178,17 @@ static const struct snd_kcontrol_new byt_rt5651_controls[] = {
        SOC_DAPM_PIN_SWITCH("Speaker"),
 };
 
+static struct snd_soc_jack_pin bytcr_jack_pins[] = {
+       {
+               .pin    = "Headphone",
+               .mask   = SND_JACK_HEADPHONE,
+       },
+       {
+               .pin    = "Headset Mic",
+               .mask   = SND_JACK_MICROPHONE,
+       },
+};
+
 static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
                                        struct snd_pcm_hw_params *params)
 {
@@ -103,9 +206,26 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
                return ret;
        }
 
-       ret = snd_soc_dai_set_pll(codec_dai, 0, RT5651_PLL1_S_BCLK1,
-                                 params_rate(params) * 50,
-                                 params_rate(params) * 512);
+       if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) {
+               /* 2x25 bit slots on SSP2 */
+               ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                       RT5651_PLL1_S_BCLK1,
+                                       params_rate(params) * 50,
+                                       params_rate(params) * 512);
+       } else {
+               if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ) {
+                       ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                               RT5651_PLL1_S_MCLK,
+                                               25000000,
+                                               params_rate(params) * 512);
+               } else {
+                       ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                               RT5651_PLL1_S_MCLK,
+                                               19200000,
+                                               params_rate(params) * 512);
+               }
+       }
+
        if (ret < 0) {
                dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
                return ret;
@@ -114,33 +234,60 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
+static int byt_rt5651_quirk_cb(const struct dmi_system_id *id)
+{
+       byt_rt5651_quirk = (unsigned long)id->driver_data;
+       return 1;
+}
+
 static const struct dmi_system_id byt_rt5651_quirk_table[] = {
+       {
+               .callback = byt_rt5651_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
+               },
+               .driver_data = (void *)(BYT_RT5651_DMIC_MAP |
+                                       BYT_RT5651_DMIC_EN),
+       },
+       {
+               .callback = byt_rt5651_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "KIANO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
+               },
+               .driver_data = (void *)(BYT_RT5651_IN2_MAP),
+       },
        {}
 };
 
 static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
 {
-       int ret;
        struct snd_soc_card *card = runtime->card;
+       struct snd_soc_codec *codec = runtime->codec;
+       struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
        const struct snd_soc_dapm_route *custom_map;
        int num_routes;
+       int ret;
 
        card->dapm.idle_bias_off = true;
 
-       dmi_check_system(byt_rt5651_quirk_table);
        switch (BYT_RT5651_MAP(byt_rt5651_quirk)) {
        case BYT_RT5651_IN1_MAP:
                custom_map = byt_rt5651_intmic_in1_map;
                num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_map);
                break;
-       case BYT_RT5651_DMIC2_MAP:
-               custom_map = byt_rt5651_intmic_dmic2_map;
-               num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic2_map);
+       case BYT_RT5651_IN2_MAP:
+               custom_map = byt_rt5651_intmic_in2_map;
+               num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_map);
                break;
        default:
-               custom_map = byt_rt5651_intmic_dmic1_map;
-               num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic1_map);
+               custom_map = byt_rt5651_intmic_dmic_map;
+               num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic_map);
        }
+       ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
+       if (ret)
+               return ret;
 
        ret = snd_soc_add_card_controls(card, byt_rt5651_controls,
                                        ARRAY_SIZE(byt_rt5651_controls));
@@ -151,6 +298,40 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
        snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
        snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
 
+       if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
+               /*
+                * 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);
+
+               if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
+                       ret = clk_set_rate(priv->mclk, 25000000);
+               else
+                       ret = clk_set_rate(priv->mclk, 19200000);
+
+               if (ret)
+                       dev_err(card->dev, "unable to set MCLK rate\n");
+       }
+
+       ret = snd_soc_card_jack_new(runtime->card, "Headset",
+                                   SND_JACK_HEADSET, &priv->jack,
+                                   bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins));
+       if (ret) {
+               dev_err(runtime->dev, "Headset jack creation failed %d\n", ret);
+               return ret;
+       }
+
+       rt5651_set_jack_detect(codec, &priv->jack);
+
        return ret;
 }
 
@@ -253,19 +434,11 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
                .dpcm_playback = 1,
                .ops = &byt_rt5651_aif1_ops,
        },
-       [MERR_DPCM_COMPR] = {
-               .name = "Compressed Port",
-               .stream_name = "Compress",
-               .cpu_dai_name = "compress-cpu-dai",
-               .codec_dai_name = "snd-soc-dummy-dai",
-               .codec_name = "snd-soc-dummy",
-               .platform_name = "sst-mfld-platform",
-       },
        /* CODEC<->CODEC link */
        /* back ends */
        {
                .name = "SSP2-Codec",
-               .id = 1,
+               .id = 0,
                .cpu_dai_name = "ssp2-port",
                .platform_name = "sst-mfld-platform",
                .no_pcm = 1,
@@ -296,13 +469,65 @@ static struct snd_soc_card byt_rt5651_card = {
        .fully_routed = true,
 };
 
+static char byt_rt5651_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
+
 static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
 {
+       struct byt_rt5651_private *priv;
+       struct snd_soc_acpi_mach *mach;
+       const char *i2c_name = NULL;
        int ret_val = 0;
+       int dai_index = 0;
+       int i;
+
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
+       if (!priv)
+               return -ENOMEM;
 
        /* register the soc card */
        byt_rt5651_card.dev = &pdev->dev;
 
+       mach = byt_rt5651_card.dev->platform_data;
+       snd_soc_card_set_drvdata(&byt_rt5651_card, priv);
+
+       /* fix index of codec dai */
+       for (i = 0; i < ARRAY_SIZE(byt_rt5651_dais); i++) {
+               if (!strcmp(byt_rt5651_dais[i].codec_name, "i2c-10EC5651:00")) {
+                       dai_index = i;
+                       break;
+               }
+       }
+
+       /* fixup codec name based on HID */
+       i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
+       if (i2c_name) {
+               snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
+                       "%s%s", "i2c-", i2c_name);
+
+               byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
+       }
+
+       /* check quirks before creating card */
+       dmi_check_system(byt_rt5651_quirk_table);
+       log_quirks(&pdev->dev);
+
+       if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
+               priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
+               if (IS_ERR(priv->mclk)) {
+                       dev_err(&pdev->dev,
+                               "Failed to get MCLK from pmc_plt_clk_3: %ld\n",
+                               PTR_ERR(priv->mclk));
+                       /*
+                        * Fall back to bit clock usage for -ENOENT (clock not
+                        * available likely due to missing dependencies), bail
+                        * for all other errors, including -EPROBE_DEFER
+                        */
+                       if (ret_val != -ENOENT)
+                               return ret_val;
+                       byt_rt5651_quirk &= ~BYT_RT5651_MCLK_EN;
+               }
+       }
+
        ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card);
 
        if (ret_val) {
index 455a55af7ad2d1949edebd4191a6cfa90f59900d..d3e1c7e12004dded46fd24ac9345758cea556233 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
+#include <linux/clk.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #define CHT_CODEC_DAI  "HiFi"
 
 struct cht_mc_private {
+       struct clk *mclk;
        struct snd_soc_jack jack;
        bool ts3a227e_present;
 };
 
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
+                                         struct snd_kcontrol *k, int  event)
+{
+       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 = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI);
+       if (!codec_dai) {
+               dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
+               return -EIO;
+       }
+
+       if (SND_SOC_DAPM_EVENT_ON(event)) {
+               ret = clk_prepare_enable(ctx->mclk);
+               if (ret < 0) {
+                       dev_err(card->dev,
+                               "could not configure MCLK state");
+                       return ret;
+               }
+       } else {
+               clk_disable_unprepare(ctx->mclk);
+       }
+
+       return 0;
+}
+
 static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
        SND_SOC_DAPM_HP("Headphone", NULL),
        SND_SOC_DAPM_MIC("Headset Mic", NULL),
        SND_SOC_DAPM_MIC("Int Mic", NULL),
        SND_SOC_DAPM_SPK("Ext Spk", NULL),
+       SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+                           platform_clock_control, SND_SOC_DAPM_PRE_PMU |
+                           SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_route cht_audio_map[] = {
@@ -60,6 +94,10 @@ static const struct snd_soc_dapm_route cht_audio_map[] = {
        {"codec_in0", NULL, "ssp2 Rx" },
        {"codec_in1", NULL, "ssp2 Rx" },
        {"ssp2 Rx", NULL, "HiFi Capture"},
+       {"Headphone", NULL, "Platform Clock"},
+       {"Headset Mic", NULL, "Platform Clock"},
+       {"Int Mic", NULL, "Platform Clock"},
+       {"Ext Spk", NULL, "Platform Clock"},
 };
 
 static const struct snd_kcontrol_new cht_mc_controls[] = {
@@ -109,6 +147,40 @@ static struct notifier_block cht_jack_nb = {
        .notifier_call = cht_ti_jack_event,
 };
 
+static struct snd_soc_jack_pin hs_jack_pins[] = {
+       {
+               .pin    = "Headphone",
+               .mask   = SND_JACK_HEADPHONE,
+       },
+       {
+               .pin    = "Headset Mic",
+               .mask   = SND_JACK_MICROPHONE,
+       },
+};
+
+static struct snd_soc_jack_gpio hs_jack_gpios[] = {
+       {
+               .name           = "hp",
+               .report         = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
+               .debounce_time  = 200,
+       },
+       {
+               .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_max98090_gpios[] = {
+       { "hp-gpios", &hp_gpios, 1 },
+       { "mic-gpios", &mic_gpios, 1 },
+       {},
+};
+
 static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
 {
        int ret;
@@ -116,30 +188,55 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
        struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
        struct snd_soc_jack *jack = &ctx->jack;
 
-       /**
-       * TI supports 4 butons headset detection
-       * KEY_MEDIA
-       * KEY_VOICECOMMAND
-       * KEY_VOLUMEUP
-       * KEY_VOLUMEDOWN
-       */
-       if (ctx->ts3a227e_present)
-               jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
-                                       SND_JACK_BTN_0 | SND_JACK_BTN_1 |
-                                       SND_JACK_BTN_2 | SND_JACK_BTN_3;
-       else
-               jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE;
+       if (ctx->ts3a227e_present) {
+               /*
+                * The jack has already been created in the
+                * cht_max98090_headset_init() function.
+                */
+               snd_soc_jack_notifier_register(jack, &cht_jack_nb);
+               return 0;
+       }
 
-       ret = snd_soc_card_jack_new(runtime->card, "Headset Jack",
-                                       jack_type, jack, NULL, 0);
+       jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE;
 
+       ret = snd_soc_card_jack_new(runtime->card, "Headset Jack",
+                                   jack_type, jack,
+                                   hs_jack_pins, ARRAY_SIZE(hs_jack_pins));
        if (ret) {
                dev_err(runtime->dev, "Headset Jack creation failed %d\n", ret);
                return ret;
        }
 
-       if (ctx->ts3a227e_present)
-               snd_soc_jack_notifier_register(jack, &cht_jack_nb);
+       ret = snd_soc_jack_add_gpiods(runtime->card->dev->parent, jack,
+                                     ARRAY_SIZE(hs_jack_gpios),
+                                     hs_jack_gpios);
+       if (ret) {
+               /*
+                * flag error but don't bail if jack detect is broken
+                * due to platform issues or bad BIOS/configuration
+                */
+               dev_err(runtime->dev,
+                       "jack detection gpios not added, error %d\n", ret);
+       }
+
+       /*
+        * 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;
 }
@@ -188,8 +285,29 @@ static int cht_max98090_headset_init(struct snd_soc_component *component)
 {
        struct snd_soc_card *card = component->card;
        struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
+       struct snd_soc_jack *jack = &ctx->jack;
+       int jack_type;
+       int ret;
 
-       return ts3a227e_enable_jack_detect(component, &ctx->jack);
+       /*
+        * TI supports 4 butons headset detection
+        * KEY_MEDIA
+        * KEY_VOICECOMMAND
+        * KEY_VOLUMEUP
+        * KEY_VOLUMEDOWN
+        */
+       jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
+                   SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+                   SND_JACK_BTN_2 | SND_JACK_BTN_3;
+
+       ret = snd_soc_card_jack_new(card, "Headset Jack", jack_type,
+                                   jack, NULL, 0);
+       if (ret) {
+               dev_err(card->dev, "Headset Jack creation failed %d\n", ret);
+               return ret;
+       }
+
+       return ts3a227e_enable_jack_detect(component, jack);
 }
 
 static const struct snd_soc_ops cht_aif1_ops = {
@@ -232,18 +350,10 @@ static struct snd_soc_dai_link cht_dailink[] = {
                .dpcm_playback = 1,
                .ops = &cht_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 */
        {
                .name = "SSP2-Codec",
-               .id = 1,
+               .id = 0,
                .cpu_dai_name = "ssp2-port",
                .platform_name = "sst-mfld-platform",
                .no_pcm = 1,
@@ -277,6 +387,7 @@ static struct snd_soc_card snd_soc_card_cht = {
 
 static int snd_cht_mc_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
        int ret_val = 0;
        struct cht_mc_private *drv;
 
@@ -289,11 +400,25 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
                /* no need probe TI jack detection chip */
                snd_soc_card_cht.aux_dev = NULL;
                snd_soc_card_cht.num_aux_devs = 0;
+
+               ret_val = devm_acpi_dev_add_driver_gpios(dev->parent,
+                                                        acpi_max98090_gpios);
+               if (ret_val)
+                       dev_dbg(dev, "Unable to add GPIO mapping table\n");
        }
 
        /* register the soc card */
        snd_soc_card_cht.dev = &pdev->dev;
        snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
+
+       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);
+       }
+
        ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht);
        if (ret_val) {
                dev_err(&pdev->dev,
index 5bcde01d15e68d31dd6292ba9a7a8deedf7f0161..18d129caa974f7c905930d6381f7673820b0323f 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/acpi.h>
 #include <linux/platform_device.h>
+#include <linux/acpi.h>
+#include <linux/clk.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
 #include <asm/cpu_device_id.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 <sound/jack.h>
+#include <sound/soc-acpi.h>
 #include "../../codecs/rt5645.h"
 #include "../atom/sst-atom-controls.h"
-#include "../common/sst-acpi.h"
 
 #define CHT_PLAT_CLK_3_HZ      19200000
 #define CHT_CODEC_DAI1 "rt5645-aif1"
@@ -53,7 +53,7 @@ struct cht_mc_private {
        struct clk *mclk;
 };
 
-#define CHT_RT5645_MAP(quirk)  ((quirk) & 0xff)
+#define CHT_RT5645_MAP(quirk)  ((quirk) & GENMASK(7, 0))
 #define CHT_RT5645_SSP2_AIF2     BIT(16) /* default is using AIF1  */
 #define CHT_RT5645_SSP0_AIF1     BIT(17)
 #define CHT_RT5645_SSP0_AIF2     BIT(18)
@@ -70,21 +70,6 @@ static void log_quirks(struct device *dev)
                dev_info(dev, "quirk SSP0_AIF2 enabled");
 }
 
-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_DAI1,
-                            strlen(CHT_CODEC_DAI1)))
-                       return rtd->codec_dai;
-               if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI2,
-                            strlen(CHT_CODEC_DAI2)))
-                       return rtd->codec_dai;
-       }
-       return NULL;
-}
-
 static int platform_clock_control(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *k, int  event)
 {
@@ -94,20 +79,21 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
        struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
        int ret;
 
-       codec_dai = cht_get_codec_dai(card);
+       codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI1);
+       if (!codec_dai)
+               codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI2);
+
        if (!codec_dai) {
                dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
                return -EIO;
        }
 
        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;
-                       }
+               ret = clk_prepare_enable(ctx->mclk);
+               if (ret < 0) {
+                       dev_err(card->dev,
+                               "could not configure MCLK state");
+                       return ret;
                }
        } else {
                /* Set codec sysclk source to its internal clock because codec PLL will
@@ -122,8 +108,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
                        return ret;
                }
 
-               if (ctx->mclk)
-                       clk_disable_unprepare(ctx->mclk);
+               clk_disable_unprepare(ctx->mclk);
        }
 
        return 0;
@@ -258,11 +243,11 @@ static const struct dmi_system_id cht_rt5645_quirk_table[] = {
 
 static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
 {
-       int ret;
-       int jack_type;
-       struct snd_soc_codec *codec = runtime->codec;
        struct snd_soc_card *card = runtime->card;
        struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
+       struct snd_soc_codec *codec = runtime->codec;
+       int jack_type;
+       int ret;
 
        if ((cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) ||
            (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) {
@@ -320,26 +305,26 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
 
        rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack);
 
-       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);
+       /*
+        * 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");
 
-               if (ret)
-                       dev_err(runtime->dev, "unable to set MCLK rate\n");
-       }
        return ret;
 }
 
@@ -460,19 +445,11 @@ static struct snd_soc_dai_link cht_dailink[] = {
                .dpcm_playback = 1,
                .ops = &cht_aif1_ops,
        },
-       [MERR_DPCM_COMPR] = {
-               .name = "Compressed Port",
-               .stream_name = "Compress",
-               .cpu_dai_name = "compress-cpu-dai",
-               .codec_dai_name = "snd-soc-dummy-dai",
-               .codec_name = "snd-soc-dummy",
-               .platform_name = "sst-mfld-platform",
-       },
        /* CODEC<->CODEC link */
        /* back ends */
        {
                .name = "SSP2-Codec",
-               .id = 1,
+               .id = 0,
                .cpu_dai_name = "ssp2-port",
                .platform_name = "sst-mfld-platform",
                .no_pcm = 1,
@@ -545,15 +522,15 @@ struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
 
 static int snd_cht_mc_probe(struct platform_device *pdev)
 {
-       int ret_val = 0;
-       int i;
-       struct cht_mc_private *drv;
        struct snd_soc_card *card = snd_soc_cards[0].soc_card;
-       struct sst_acpi_mach *mach;
+       struct snd_soc_acpi_mach *mach;
+       struct cht_mc_private *drv;
        const char *i2c_name = NULL;
-       int dai_index = 0;
        bool found = false;
        bool is_bytcr = false;
+       int dai_index = 0;
+       int ret_val = 0;
+       int i;
 
        drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
        if (!drv)
@@ -589,8 +566,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
                }
 
        /* fixup codec name based on HID */
-       i2c_name = sst_acpi_find_name_from_hid(mach->id);
-       if (i2c_name != NULL) {
+       i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
+       if (i2c_name) {
                snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name),
                        "%s%s", "i2c-", i2c_name);
                cht_dailink[dai_index].codec_name = cht_rt5645_codec_name;
@@ -622,7 +599,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
                /* format specified: 2 64-bit integers */
                struct acpi_buffer format = {sizeof("NN"), "NN"};
                struct acpi_buffer state = {0, NULL};
-               struct sst_acpi_package_context pkg_ctx;
+               struct snd_soc_acpi_package_context pkg_ctx;
                bool pkg_found = false;
 
                state.length = sizeof(chan_package);
@@ -634,7 +611,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
                pkg_ctx.state = &state;
                pkg_ctx.data_valid = false;
 
-               pkg_found = sst_acpi_find_package_from_hid(mach->id, &pkg_ctx);
+               pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
+                                                              &pkg_ctx);
                if (pkg_found) {
                        if (chan_package.aif_value == 1) {
                                dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
@@ -682,14 +660,12 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
                        cht_rt5645_cpu_dai_name;
        }
 
-       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);
-               }
+       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(card, drv);
index f597d558222388e0b52302395ecfbf22a5a127d7..f8f21eee9b2d373e4d8c60e8d696286e598e0ad0 100644 (file)
 #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>
 #include <sound/jack.h>
+#include <sound/soc-acpi.h>
 #include "../../codecs/rt5670.h"
 #include "../atom/sst-atom-controls.h"
-#include "../common/sst-acpi.h"
+
 
 /* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */
 #define CHT_PLAT_CLK_3_HZ      19200000
@@ -51,18 +51,6 @@ static struct snd_soc_jack_pin cht_bsw_headset_pins[] = {
        },
 };
 
-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 int platform_clock_control(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *k, int  event)
 {
@@ -72,7 +60,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
        struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
        int ret;
 
-       codec_dai = cht_get_codec_dai(card);
+       codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI);
        if (!codec_dai) {
                dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
                return -EIO;
@@ -315,20 +303,12 @@ static struct snd_soc_dai_link cht_dailink[] = {
                .dpcm_playback = 1,
                .ops = &cht_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 End DAI links */
        {
                /* SSP2 - Codec */
                .name = "SSP2-Codec",
-               .id = 1,
+               .id = 0,
                .cpu_dai_name = "ssp2-port",
                .platform_name = "sst-mfld-platform",
                .no_pcm = 1,
@@ -348,9 +328,11 @@ static struct snd_soc_dai_link cht_dailink[] = {
 static int cht_suspend_pre(struct snd_soc_card *card)
 {
        struct snd_soc_component *component;
+       struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
 
        list_for_each_entry(component, &card->component_dev_list, card_list) {
-               if (!strcmp(component->name, "i2c-10EC5670:00")) {
+               if (!strncmp(component->name,
+                            ctx->codec_name, sizeof(ctx->codec_name))) {
                        struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
                        dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
@@ -364,9 +346,11 @@ static int cht_suspend_pre(struct snd_soc_card *card)
 static int cht_resume_post(struct snd_soc_card *card)
 {
        struct snd_soc_component *component;
+       struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
 
        list_for_each_entry(component, &card->component_dev_list, card_list) {
-               if (!strcmp(component->name, "i2c-10EC5670:00")) {
+               if (!strncmp(component->name,
+                            ctx->codec_name, sizeof(ctx->codec_name))) {
                        struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
                        dev_dbg(codec->dev, "enabling jack detect for resume.\n");
@@ -380,7 +364,7 @@ static int cht_resume_post(struct snd_soc_card *card)
 
 /* SoC card */
 static struct snd_soc_card snd_soc_card_cht = {
-       .name = "cherrytrailcraudio",
+       .name = "cht-bsw-rt5672",
        .owner = THIS_MODULE,
        .dai_link = cht_dailink,
        .num_links = ARRAY_SIZE(cht_dailink),
@@ -394,25 +378,13 @@ 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;
+       struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
        const char *i2c_name;
        int i;
 
@@ -424,7 +396,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
 
        /* fixup codec name based on HID */
        if (mach) {
-               i2c_name = sst_acpi_find_name_from_hid(mach->id);
+               i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
                if (i2c_name) {
                        snprintf(drv->codec_name, sizeof(drv->codec_name),
                                 "i2c-%s", i2c_name);
@@ -439,14 +411,12 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
                }
        }
 
-       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);
-               }
+       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);
 
index 7f76074207063a5da6ad8c9874002646d42c88c1..6f9a8bcf20f3ebb4407a2452eed8870a11b40c02 100644 (file)
@@ -17,6 +17,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/input.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <sound/core.h>
@@ -208,6 +209,7 @@ 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;
+       struct snd_soc_jack *jack;
 
        /*
         * Headset buttons map to the google Reference headset.
@@ -221,6 +223,13 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
                dev_err(rtd->dev, "Headset Jack creation failed %d\n", 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);
        return ret;
 }
@@ -341,13 +350,28 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
        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 */
-       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);
+       /*
+        * 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 Headset Playback") ||
+           !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);
+       }
+       /*
+        * 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;
 }
@@ -390,6 +414,43 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
        return 0;
 }
 
+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, MAXIM_DEV0_NAME)) {
+                       /*
+                        * Use channel 4 and 5 for the first amp
+                        */
+                       ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16);
+                       if (ret < 0) {
+                               dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
+                               return ret;
+                       }
+               }
+               if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) {
+                       /*
+                        * Use channel 6 and 7 for the second amp
+                        */
+                       ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 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 unsigned int channels_dmic[] = {
        2, 4,
 };
@@ -593,12 +654,13 @@ static struct snd_soc_dai_link kabylake_dais[] = {
                .no_pcm = 1,
                .codecs = max98927_codec_components,
                .num_codecs = ARRAY_SIZE(max98927_codec_components),
-               .dai_fmt = SND_SOC_DAIFMT_I2S |
+               .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,
+               .ops = &kabylake_ssp0_ops,
        },
        {
                /* SSP1 - Codec */
index 69ab559564921c4a5670bb519a4c9d80058d418b..6072164f2d43db7c7f8f50000892f6e61e80d79c 100644 (file)
@@ -302,6 +302,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
         * 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 Headset Playback") ||
            !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
                rate->min = rate->max = 48000;
                channels->min = channels->max = 2;
index 5ed0aa27b467d0e4807a6fefecfb216334d49daf..1b5a689dc99bb4810194a0bd068fea8f75c99426 100644 (file)
@@ -54,20 +54,6 @@ enum {
        SKL_DPCM_AUDIO_HDMI3_PB,
 };
 
-static inline struct snd_soc_dai *skl_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, SKL_NUVOTON_CODEC_DAI,
-                            strlen(SKL_NUVOTON_CODEC_DAI)))
-                       return rtd->codec_dai;
-       }
-
-       return NULL;
-}
-
 static int platform_clock_control(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *k, int  event)
 {
@@ -76,7 +62,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
        struct snd_soc_dai *codec_dai;
        int ret;
 
-       codec_dai = skl_get_codec_dai(card);
+       codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI);
        if (!codec_dai) {
                dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
                return -EIO;
index 01b8b140bb0874af87fa3ef98a4213bf7f6c74a5..7bea4bc774815a83e7d4f9490398fda08d4a48d8 100644 (file)
@@ -57,20 +57,6 @@ enum {
        SKL_DPCM_AUDIO_HDMI3_PB,
 };
 
-static inline struct snd_soc_dai *skl_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, SKL_NUVOTON_CODEC_DAI,
-                            strlen(SKL_NUVOTON_CODEC_DAI)))
-                       return rtd->codec_dai;
-       }
-
-       return NULL;
-}
-
 static const struct snd_kcontrol_new skylake_controls[] = {
        SOC_DAPM_PIN_SWITCH("Headphone Jack"),
        SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -86,7 +72,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
        struct snd_soc_dai *codec_dai;
        int ret;
 
-       codec_dai = skl_get_codec_dai(card);
+       codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI);
        if (!codec_dai) {
                dev_err(card->dev, "Codec dai not found\n");
                return -EIO;
index 0e029f354f6bcfe72fbf7f9c627a2a7b3d842425..7379d8830c391e422ec89d0c15f0e0d1fcc94ff4 100644 (file)
@@ -1,11 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0
 snd-soc-sst-dsp-objs := sst-dsp.o
 snd-soc-sst-acpi-objs := sst-acpi.o
-snd-soc-sst-match-objs := sst-match-acpi.o
 snd-soc-sst-ipc-objs := sst-ipc.o
 snd-soc-sst-firmware-objs := sst-firmware.o
+snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-match.o soc-acpi-intel-hsw-bdw-match.o
 
 obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
 obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
-obj-$(CONFIG_SND_SOC_INTEL_SST_MATCH) += snd-soc-sst-match.o
 obj-$(CONFIG_SND_SOC_INTEL_SST_FIRMWARE) += snd-soc-sst-firmware.o
+obj-$(CONFIG_SND_SOC_ACPI_INTEL_MATCH) += snd-soc-acpi-intel-match.o
diff --git a/sound/soc/intel/common/soc-acpi-intel-byt-match.c b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
new file mode 100644 (file)
index 0000000..bfe1ca6
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * soc-apci-intel-byt-match.c - tables and support for BYT ACPI enumeration.
+ *
+ * Copyright (c) 2017, Intel Corporation.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/dmi.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+
+static unsigned long byt_machine_id;
+
+#define BYT_THINKPAD_10  1
+
+static int byt_thinkpad10_quirk_cb(const struct dmi_system_id *id)
+{
+       byt_machine_id = BYT_THINKPAD_10;
+       return 1;
+}
+
+
+static const struct dmi_system_id byt_table[] = {
+       {
+               .callback = byt_thinkpad10_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
+               },
+       },
+       {
+               .callback = byt_thinkpad10_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
+               },
+       },
+       {
+               .callback = byt_thinkpad10_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
+               },
+       },
+       { }
+};
+
+static struct snd_soc_acpi_mach byt_thinkpad_10 = {
+       .id = "10EC5640",
+       .drv_name = "cht-bsw-rt5672",
+       .fw_filename = "intel/fw_sst_0f28.bin",
+       .board = "cht-bsw",
+       .sof_fw_filename = "intel/reef-byt.ri",
+       .sof_tplg_filename = "intel/reef-byt-rt5670.tplg",
+       .asoc_plat_name = "sst-mfld-platform",
+};
+
+static struct snd_soc_acpi_mach *byt_quirk(void *arg)
+{
+       struct snd_soc_acpi_mach *mach = arg;
+
+       dmi_check_system(byt_table);
+
+       if (byt_machine_id == BYT_THINKPAD_10)
+               return &byt_thinkpad_10;
+       else
+               return mach;
+}
+
+struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_legacy_machines[] = {
+       {
+               .id = "10EC5640",
+               .drv_name = "byt-rt5640",
+               .fw_filename = "intel/fw_sst_0f28.bin-48kHz_i2s_master",
+       },
+       {
+               .id = "193C9890",
+               .drv_name = "byt-max98090",
+               .fw_filename = "intel/fw_sst_0f28.bin-48kHz_i2s_master",
+       },
+       {}
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_baytrail_legacy_machines);
+
+struct snd_soc_acpi_mach  snd_soc_acpi_intel_baytrail_machines[] = {
+       {
+               .id = "10EC5640",
+               .drv_name = "bytcr_rt5640",
+               .fw_filename = "intel/fw_sst_0f28.bin",
+               .board = "bytcr_rt5640",
+               .machine_quirk = byt_quirk,
+               .sof_fw_filename = "intel/reef-byt.ri",
+               .sof_tplg_filename = "intel/reef-byt-rt5640.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "10EC5642",
+               .drv_name = "bytcr_rt5640",
+               .fw_filename = "intel/fw_sst_0f28.bin",
+               .board = "bytcr_rt5640",
+               .sof_fw_filename = "intel/reef-byt.ri",
+               .sof_tplg_filename = "intel/reef-byt-rt5640.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "INTCCFFD",
+               .drv_name = "bytcr_rt5640",
+               .fw_filename = "intel/fw_sst_0f28.bin",
+               .board = "bytcr_rt5640",
+               .sof_fw_filename = "intel/reef-byt.ri",
+               .sof_tplg_filename = "intel/reef-byt-rt5640.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "10EC5651",
+               .drv_name = "bytcr_rt5651",
+               .fw_filename = "intel/fw_sst_0f28.bin",
+               .board = "bytcr_rt5651",
+               .sof_fw_filename = "intel/reef-byt.ri",
+               .sof_tplg_filename = "intel/reef-byt-rt5651.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "DLGS7212",
+               .drv_name = "bytcht_da7213",
+               .fw_filename = "intel/fw_sst_0f28.bin",
+               .board = "bytcht_da7213",
+               .sof_fw_filename = "intel/reef-byt.ri",
+               .sof_tplg_filename = "intel/reef-byt-da7213.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "DLGS7213",
+               .drv_name = "bytcht_da7213",
+               .fw_filename = "intel/fw_sst_0f28.bin",
+               .board = "bytcht_da7213",
+               .sof_fw_filename = "intel/reef-byt.ri",
+               .sof_tplg_filename = "intel/reef-byt-da7213.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       /* some Baytrail platforms rely on RT5645, use CHT machine driver */
+       {
+               .id = "10EC5645",
+               .drv_name = "cht-bsw-rt5645",
+               .fw_filename = "intel/fw_sst_0f28.bin",
+               .board = "cht-bsw",
+               .sof_fw_filename = "intel/reef-byt.ri",
+               .sof_tplg_filename = "intel/reef-byt-rt5645.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "10EC5648",
+               .drv_name = "cht-bsw-rt5645",
+               .fw_filename = "intel/fw_sst_0f28.bin",
+               .board = "cht-bsw",
+               .sof_fw_filename = "intel/reef-byt.ri",
+               .sof_tplg_filename = "intel/reef-byt-rt5645.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       /* use CHT driver to Baytrail Chromebooks */
+       {
+               .id = "193C9890",
+               .drv_name = "cht-bsw-max98090",
+               .fw_filename = "intel/fw_sst_0f28.bin",
+               .board = "cht-bsw",
+               .sof_fw_filename = "intel/reef-byt.ri",
+               .sof_tplg_filename = "intel/reef-byt-max98090.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+#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
+        */
+       {
+               .id = "80860F28",
+               .drv_name = "bytcht_nocodec",
+               .fw_filename = "intel/fw_sst_0f28.bin",
+               .board = "bytcht_nocodec",
+       },
+#endif
+       {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_baytrail_machines);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c
new file mode 100644 (file)
index 0000000..b50a0d5
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * soc-apci-intel-cht-match.c - tables and support for CHT ACPI enumeration.
+ *
+ * Copyright (c) 2017, Intel Corporation.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/dmi.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+
+static unsigned long cht_machine_id;
+
+#define CHT_SURFACE_MACH 1
+
+static int cht_surface_quirk_cb(const struct dmi_system_id *id)
+{
+       cht_machine_id = CHT_SURFACE_MACH;
+       return 1;
+}
+
+static const struct dmi_system_id cht_table[] = {
+       {
+               .callback = cht_surface_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
+               },
+       },
+       { }
+};
+
+static struct snd_soc_acpi_mach cht_surface_mach = {
+       .id = "10EC5640",
+       .drv_name = "cht-bsw-rt5645",
+       .fw_filename = "intel/fw_sst_22a8.bin",
+       .board = "cht-bsw",
+       .sof_fw_filename = "intel/reef-cht.ri",
+       .sof_tplg_filename = "intel/reef-cht-rt5645.tplg",
+       .asoc_plat_name = "sst-mfld-platform",
+};
+
+static struct snd_soc_acpi_mach *cht_quirk(void *arg)
+{
+       struct snd_soc_acpi_mach *mach = arg;
+
+       dmi_check_system(cht_table);
+
+       if (cht_machine_id == CHT_SURFACE_MACH)
+               return &cht_surface_mach;
+       else
+               return mach;
+}
+
+/* Cherryview-based platforms: CherryTrail and Braswell */
+struct snd_soc_acpi_mach  snd_soc_acpi_intel_cherrytrail_machines[] = {
+       {
+               .id = "10EC5670",
+               .drv_name = "cht-bsw-rt5672",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "cht-bsw",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-rt5670.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "10EC5672",
+               .drv_name = "cht-bsw-rt5672",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "cht-bsw",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-rt5670.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "10EC5645",
+               .drv_name = "cht-bsw-rt5645",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "cht-bsw",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-rt5645.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "10EC5650",
+               .drv_name = "cht-bsw-rt5645",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "cht-bsw",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-rt5645.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "10EC3270",
+               .drv_name = "cht-bsw-rt5645",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "cht-bsw",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-rt5645.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "193C9890",
+               .drv_name = "cht-bsw-max98090",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "cht-bsw",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-max98090.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "DLGS7212",
+               .drv_name = "bytcht_da7213",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "bytcht_da7213",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-da7213.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "DLGS7213",
+               .drv_name = "bytcht_da7213",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "bytcht_da7213",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-da7213.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "ESSX8316",
+               .drv_name = "bytcht_es8316",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "bytcht_es8316",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-es8316.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       /* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
+       {
+               .id = "10EC5640",
+               .drv_name = "bytcr_rt5640",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "bytcr_rt5640",
+               .machine_quirk = cht_quirk,
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-rt5640.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       {
+               .id = "10EC3276",
+               .drv_name = "bytcr_rt5640",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "bytcr_rt5640",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-rt5640.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+       /* some CHT-T platforms rely on RT5651, use Baytrail machine driver */
+       {
+               .id = "10EC5651",
+               .drv_name = "bytcr_rt5651",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "bytcr_rt5651",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-rt5651.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
+#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
+        */
+       {
+               .id = "808622A8",
+               .drv_name = "bytcht_nocodec",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "bytcht_nocodec",
+       },
+#endif
+       {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cherrytrail_machines);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c b/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c
new file mode 100644 (file)
index 0000000..e0e8c8c
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * soc-apci-intel-hsw-bdw-match.c - tables and support for ACPI enumeration.
+ *
+ * Copyright (c) 2017, Intel Corporation.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/dmi.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+
+struct snd_soc_acpi_mach snd_soc_acpi_intel_haswell_machines[] = {
+       {
+               .id = "INT33CA",
+               .drv_name = "haswell-audio",
+               .fw_filename = "intel/IntcSST1.bin",
+               .sof_fw_filename = "intel/reef-hsw.ri",
+               .sof_tplg_filename = "intel/reef-hsw.tplg",
+               .asoc_plat_name = "haswell-pcm-audio",
+       },
+       {}
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_haswell_machines);
+
+struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[] = {
+       {
+               .id = "INT343A",
+               .drv_name = "broadwell-audio",
+               .fw_filename =  "intel/IntcSST2.bin",
+               .sof_fw_filename = "intel/reef-bdw.ri",
+               .sof_tplg_filename = "intel/reef-bdw-rt286.tplg",
+               .asoc_plat_name = "haswell-pcm-audio",
+       },
+       {
+               .id = "RT5677CE",
+               .drv_name = "bdw-rt5677",
+               .fw_filename =  "intel/IntcSST2.bin",
+               .sof_fw_filename = "intel/reef-bdw.ri",
+               .sof_tplg_filename = "intel/reef-bdw-rt286.tplg",
+               .asoc_plat_name = "haswell-pcm-audio",
+       },
+       {
+               .id = "INT33CA",
+               .drv_name = "haswell-audio",
+               .fw_filename = "intel/IntcSST2.bin",
+               .sof_fw_filename = "intel/reef-bdw.ri",
+               .sof_tplg_filename = "intel/reef-bdw-rt5640.tplg",
+               .asoc_plat_name = "haswell-pcm-audio",
+       },
+       {}
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_broadwell_machines);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel Common ACPI Match module");
index 1285cc597b6b36b3959ca715f978fa0faca97d0c..cf6fbbd4e3786623808308d0a28d3f54658dfbe4 100644 (file)
@@ -21,7 +21,8 @@
 #include <linux/platform_device.h>
 
 #include "sst-dsp.h"
-#include "sst-acpi.h"
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
 
 #define SST_LPT_DSP_DMA_ADDR_OFFSET    0x0F0000
 #define SST_WPT_DSP_DMA_ADDR_OFFSET    0x0FE000
@@ -30,7 +31,7 @@
 /* Descriptor for setting up SST platform data */
 struct sst_acpi_desc {
        const char *drv_name;
-       struct sst_acpi_mach *machines;
+       struct snd_soc_acpi_mach *machines;
        /* Platform resource indexes. Must set to -1 if not used */
        int resindex_lpe_base;
        int resindex_pcicfg_base;
@@ -49,7 +50,7 @@ struct sst_acpi_priv {
        struct platform_device *pdev_pcm;
        struct sst_pdata sst_pdata;
        struct sst_acpi_desc *desc;
-       struct sst_acpi_mach *mach;
+       struct snd_soc_acpi_mach *mach;
 };
 
 static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
@@ -59,7 +60,7 @@ static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
        struct sst_acpi_priv *sst_acpi = platform_get_drvdata(pdev);
        struct sst_pdata *sst_pdata = &sst_acpi->sst_pdata;
        struct sst_acpi_desc *desc = sst_acpi->desc;
-       struct sst_acpi_mach *mach = sst_acpi->mach;
+       struct snd_soc_acpi_mach *mach = sst_acpi->mach;
 
        sst_pdata->fw = fw;
        if (!fw) {
@@ -85,7 +86,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct sst_acpi_priv *sst_acpi;
        struct sst_pdata *sst_pdata;
-       struct sst_acpi_mach *mach;
+       struct snd_soc_acpi_mach *mach;
        struct sst_acpi_desc *desc;
        struct resource *mmio;
        int ret = 0;
@@ -99,7 +100,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
                return -ENODEV;
 
        desc = (struct sst_acpi_desc *)id->driver_data;
-       mach = sst_acpi_find_machine(desc->machines);
+       mach = snd_soc_acpi_find_machine(desc->machines);
        if (mach == NULL) {
                dev_err(dev, "No matching ASoC machine driver found\n");
                return -ENODEV;
@@ -179,14 +180,9 @@ static int sst_acpi_remove(struct platform_device *pdev)
        return 0;
 }
 
-static struct sst_acpi_mach haswell_machines[] = {
-       { "INT33CA", "haswell-audio", "intel/IntcSST1.bin", NULL, NULL, NULL },
-       {}
-};
-
 static struct sst_acpi_desc sst_acpi_haswell_desc = {
        .drv_name = "haswell-pcm-audio",
-       .machines = haswell_machines,
+       .machines = snd_soc_acpi_intel_haswell_machines,
        .resindex_lpe_base = 0,
        .resindex_pcicfg_base = 1,
        .resindex_fw_base = -1,
@@ -197,15 +193,9 @@ static struct sst_acpi_desc sst_acpi_haswell_desc = {
        .dma_size = SST_LPT_DSP_DMA_SIZE,
 };
 
-static struct sst_acpi_mach broadwell_machines[] = {
-       { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL },
-       { "RT5677CE", "bdw-rt5677", "intel/IntcSST2.bin", NULL, NULL, NULL },
-       {}
-};
-
 static struct sst_acpi_desc sst_acpi_broadwell_desc = {
        .drv_name = "haswell-pcm-audio",
-       .machines = broadwell_machines,
+       .machines = snd_soc_acpi_intel_broadwell_machines,
        .resindex_lpe_base = 0,
        .resindex_pcicfg_base = 1,
        .resindex_fw_base = -1,
@@ -217,15 +207,9 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = {
 };
 
 #if !IS_ENABLED(CONFIG_SND_SST_IPC_ACPI)
-static struct sst_acpi_mach baytrail_machines[] = {
-       { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL },
-       { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL },
-       {}
-};
-
 static struct sst_acpi_desc sst_acpi_baytrail_desc = {
        .drv_name = "baytrail-pcm-audio",
-       .machines = baytrail_machines,
+       .machines = snd_soc_acpi_intel_baytrail_legacy_machines,
        .resindex_lpe_base = 0,
        .resindex_pcicfg_base = 1,
        .resindex_fw_base = 2,
diff --git a/sound/soc/intel/common/sst-acpi.h b/sound/soc/intel/common/sst-acpi.h
deleted file mode 100644 (file)
index afe9b87..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2013-15, Intel Corporation. All rights reserved.
- *
- * 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/stddef.h>
-#include <linux/acpi.h>
-
-struct sst_acpi_package_context {
-       char *name;           /* package name */
-       int length;           /* number of elements */
-       struct acpi_buffer *format;
-       struct acpi_buffer *state;
-       bool data_valid;
-};
-
-#if IS_ENABLED(CONFIG_ACPI)
-/* translation fron HID to I2C name, needed for DAI codec_name */
-const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]);
-bool sst_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
-                                   struct sst_acpi_package_context *ctx);
-#else
-static inline const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
-{
-       return NULL;
-}
-static inline bool sst_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
-                                          struct sst_acpi_package_context *ctx)
-{
-       return false;
-}
-#endif
-
-/* 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 */
-       const u8 id[ACPI_ID_LEN];
-       /* machine driver name */
-       const char *drv_name;
-       /* firmware file name */
-       const char *fw_filename;
-
-       /* 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);
index a086c35f91bb94bfe879ebc743fc81177e787118..657afc02f1c47813b55cffa4bd2f53465539f0b8 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <linux/firmware.h>
 #include <linux/export.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
@@ -274,7 +275,6 @@ int sst_dma_new(struct sst_dsp *sst)
        struct sst_pdata *sst_pdata = sst->pdata;
        struct sst_dma *dma;
        struct resource mem;
-       const char *dma_dev_name;
        int ret = 0;
 
        if (sst->pdata->resindex_dma_base == -1)
@@ -285,7 +285,6 @@ int sst_dma_new(struct sst_dsp *sst)
        * is attached to the ADSP IP. */
        switch (sst->pdata->dma_engine) {
        case SST_DMA_TYPE_DW:
-               dma_dev_name = "dw_dmac";
                break;
        default:
                dev_err(sst->dev, "error: invalid DMA engine %d\n",
index b9c205c8bb735e6311f53515bf038d3b1f9630f9..61b5bfa79d1325b5a42e69119ccb1e39c20c0b6c 100644 (file)
@@ -613,8 +613,10 @@ skip_buf_size_calc:
 }
 
 #define DMA_CONTROL_ID 5
+#define DMA_I2S_BLOB_SIZE 21
 
-int skl_dsp_set_dma_control(struct skl_sst *ctx, struct skl_module_cfg *mconfig)
+int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
+                               u32 caps_size, u32 node_id)
 {
        struct skl_dma_control *dma_ctrl;
        struct skl_ipc_large_config_msg msg = {0};
@@ -624,24 +626,27 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, struct skl_module_cfg *mconfig)
        /*
         * if blob size zero, then return
         */
-       if (mconfig->formats_config.caps_size == 0)
+       if (caps_size == 0)
                return 0;
 
        msg.large_param_id = DMA_CONTROL_ID;
-       msg.param_data_size = sizeof(struct skl_dma_control) +
-                               mconfig->formats_config.caps_size;
+       msg.param_data_size = sizeof(struct skl_dma_control) + caps_size;
 
        dma_ctrl = kzalloc(msg.param_data_size, GFP_KERNEL);
        if (dma_ctrl == NULL)
                return -ENOMEM;
 
-       dma_ctrl->node_id = skl_get_node_id(ctx, mconfig);
+       dma_ctrl->node_id = node_id;
 
-       /* size in dwords */
-       dma_ctrl->config_length = mconfig->formats_config.caps_size / 4;
+       /*
+        * NHLT blob may contain additional configs along with i2s blob.
+        * firmware expects only the i2s blob size as the config_length.
+        * So fix to i2s blob size.
+        * size in dwords.
+        */
+       dma_ctrl->config_length = DMA_I2S_BLOB_SIZE;
 
-       memcpy(dma_ctrl->config_data, mconfig->formats_config.caps,
-                               mconfig->formats_config.caps_size);
+       memcpy(dma_ctrl->config_data, caps, caps_size);
 
        err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl);
 
index a3cb204e9640fa36052bb2caf685ac465e051262..1dd97479e0c014bf1f814f16dd419268529454e0 100644 (file)
@@ -653,7 +653,7 @@ static const struct snd_soc_dai_ops skl_link_dai_ops = {
        .trigger = skl_link_pcm_trigger,
 };
 
-static struct snd_soc_dai_driver skl_platform_dai[] = {
+static struct snd_soc_dai_driver skl_fe_dai[] = {
 {
        .name = "System Pin",
        .ops = &skl_pcm_dai_ops,
@@ -797,8 +797,10 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
                .sig_bits = 32,
        },
 },
+};
 
 /* BE CPU  Dais */
+static struct snd_soc_dai_driver skl_platform_dai[] = {
 {
        .name = "SSP0 Pin",
        .ops = &skl_be_ssp_dai_ops,
@@ -976,6 +978,14 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
 },
 };
 
+int skl_dai_load(struct snd_soc_component *cmp,
+                struct snd_soc_dai_driver *pcm_dai)
+{
+       pcm_dai->ops = &skl_pcm_dai_ops;
+
+       return 0;
+}
+
 static int skl_platform_open(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -1363,6 +1373,8 @@ int skl_platform_register(struct device *dev)
        int ret;
        struct hdac_ext_bus *ebus = dev_get_drvdata(dev);
        struct skl *skl = ebus_to_skl(ebus);
+       struct snd_soc_dai_driver *dais;
+       int num_dais = ARRAY_SIZE(skl_platform_dai);
 
        INIT_LIST_HEAD(&skl->ppl_list);
        INIT_LIST_HEAD(&skl->bind_list);
@@ -1372,14 +1384,38 @@ int skl_platform_register(struct device *dev)
                dev_err(dev, "soc platform registration failed %d\n", ret);
                return ret;
        }
+
+       skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai),
+                           GFP_KERNEL);
+       if (!skl->dais) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       if (!skl->use_tplg_pcm) {
+               dais = krealloc(skl->dais, sizeof(skl_fe_dai) +
+                               sizeof(skl_platform_dai), GFP_KERNEL);
+               if (!dais) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               skl->dais = dais;
+               memcpy(&skl->dais[ARRAY_SIZE(skl_platform_dai)], skl_fe_dai,
+                      sizeof(skl_fe_dai));
+               num_dais += ARRAY_SIZE(skl_fe_dai);
+       }
+
        ret = snd_soc_register_component(dev, &skl_component,
-                               skl_platform_dai,
-                               ARRAY_SIZE(skl_platform_dai));
+                                        skl->dais, num_dais);
        if (ret) {
                dev_err(dev, "soc component registration failed %d\n", ret);
-               snd_soc_unregister_platform(dev);
+               goto err;
        }
 
+       return 0;
+err:
+       snd_soc_unregister_platform(dev);
        return ret;
 
 }
@@ -1399,5 +1435,7 @@ int skl_platform_unregister(struct device *dev)
 
        snd_soc_unregister_component(dev);
        snd_soc_unregister_platform(dev);
+       kfree(skl->dais);
+
        return 0;
 }
index 27bcb62568fbc70c6291c34f377c48c9fe36f448..a072bcf209d2aa4c9c72503466e027e6867cd9bb 100644 (file)
@@ -2036,21 +2036,45 @@ static int skl_tplg_add_pipe(struct device *dev,
        return 0;
 }
 
-static int skl_tplg_fill_pin(struct device *dev, u32 tkn,
+static int skl_tplg_get_uuid(struct device *dev, u8 *guid,
+             struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
+{
+       if (uuid_tkn->token == SKL_TKN_UUID) {
+               memcpy(guid, &uuid_tkn->uuid, 16);
+               return 0;
+       }
+
+       dev_err(dev, "Not an UUID token %d\n", uuid_tkn->token);
+
+       return -EINVAL;
+}
+
+static int skl_tplg_fill_pin(struct device *dev,
+                       struct snd_soc_tplg_vendor_value_elem *tkn_elem,
                        struct skl_module_pin *m_pin,
-                       int pin_index, u32 value)
+                       int pin_index)
 {
-       switch (tkn) {
+       int ret;
+
+       switch (tkn_elem->token) {
        case SKL_TKN_U32_PIN_MOD_ID:
-               m_pin[pin_index].id.module_id = value;
+               m_pin[pin_index].id.module_id = tkn_elem->value;
                break;
 
        case SKL_TKN_U32_PIN_INST_ID:
-               m_pin[pin_index].id.instance_id = value;
+               m_pin[pin_index].id.instance_id = tkn_elem->value;
+               break;
+
+       case SKL_TKN_UUID:
+               ret = skl_tplg_get_uuid(dev, m_pin[pin_index].id.mod_uuid.b,
+                       (struct snd_soc_tplg_vendor_uuid_elem *)tkn_elem);
+               if (ret < 0)
+                       return ret;
+
                break;
 
        default:
-               dev_err(dev, "%d Not a pin token\n", value);
+               dev_err(dev, "%d Not a pin token\n", tkn_elem->token);
                return -EINVAL;
        }
 
@@ -2083,9 +2107,7 @@ static int skl_tplg_fill_pins_info(struct device *dev,
                return -EINVAL;
        }
 
-       ret = skl_tplg_fill_pin(dev, tkn_elem->token,
-                       m_pin, pin_count, tkn_elem->value);
-
+       ret = skl_tplg_fill_pin(dev, tkn_elem, m_pin, pin_count);
        if (ret < 0)
                return ret;
 
@@ -2170,19 +2192,6 @@ static int skl_tplg_widget_fill_fmt(struct device *dev,
        return skl_tplg_fill_fmt(dev, dst_fmt, tkn, val);
 }
 
-static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig,
-             struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
-{
-       if (uuid_tkn->token == SKL_TKN_UUID)
-               memcpy(&mconfig->guid, &uuid_tkn->uuid, 16);
-       else {
-               dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
 static void skl_tplg_fill_pin_dynamic_val(
                struct skl_module_pin *mpin, u32 pin_count, u32 value)
 {
@@ -2488,6 +2497,7 @@ static int skl_tplg_get_token(struct device *dev,
 
        case SKL_TKN_U32_PIN_MOD_ID:
        case SKL_TKN_U32_PIN_INST_ID:
+       case SKL_TKN_UUID:
                ret = skl_tplg_fill_pins_info(dev,
                                mconfig, tkn_elem, dir,
                                pin_index);
@@ -2550,6 +2560,7 @@ static int skl_tplg_get_tokens(struct device *dev,
        struct snd_soc_tplg_vendor_value_elem *tkn_elem;
        int tkn_count = 0, ret;
        int off = 0, tuple_size = 0;
+       bool is_module_guid = true;
 
        if (block_size <= 0)
                return -EINVAL;
@@ -2565,7 +2576,15 @@ static int skl_tplg_get_tokens(struct device *dev,
                        continue;
 
                case SND_SOC_TPLG_TUPLE_TYPE_UUID:
-                       ret = skl_tplg_get_uuid(dev, mconfig, array->uuid);
+                       if (is_module_guid) {
+                               ret = skl_tplg_get_uuid(dev, mconfig->guid,
+                                                       array->uuid);
+                               is_module_guid = false;
+                       } else {
+                               ret = skl_tplg_get_token(dev, array->value, skl,
+                                                        mconfig);
+                       }
+
                        if (ret < 0)
                                return ret;
 
@@ -3331,6 +3350,7 @@ static struct snd_soc_tplg_ops skl_tplg_ops  = {
        .io_ops = skl_tplg_kcontrol_ops,
        .io_ops_count = ARRAY_SIZE(skl_tplg_kcontrol_ops),
        .manifest = skl_manifest_load,
+       .dai_load = skl_dai_load,
 };
 
 /*
@@ -3404,7 +3424,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
 
        ret = request_firmware(&fw, skl->tplg_name, bus->dev);
        if (ret < 0) {
-               dev_err(bus->dev, "tplg fw %s load failed with %d\n",
+               dev_info(bus->dev, "tplg fw %s load failed with %d, falling back to dfw_sst.bin",
                                skl->tplg_name, ret);
                ret = request_firmware(&fw, "dfw_sst.bin", bus->dev);
                if (ret < 0) {
index bc3c29161ed0062b55a83598de4159c2de499fd2..b6496513fe555d476c6796f9cc5e40f2e29f4caf 100644 (file)
@@ -456,8 +456,8 @@ static inline struct skl *get_skl_ctx(struct device *dev)
 
 int skl_tplg_be_update_params(struct snd_soc_dai *dai,
        struct skl_pipe_params *params);
-int skl_dsp_set_dma_control(struct skl_sst *ctx,
-               struct skl_module_cfg *mconfig);
+int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
+                       u32 caps_size, u32 node_id);
 void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
        struct skl_pipe_params *params, int stream);
 int skl_tplg_init(struct snd_soc_platform *platform,
@@ -502,4 +502,7 @@ int skl_pcm_host_dma_prepare(struct device *dev,
                        struct skl_pipe_params *params);
 int skl_pcm_link_dma_prepare(struct device *dev,
                        struct skl_pipe_params *params);
+
+int skl_dai_load(struct snd_soc_component *cmp,
+                struct snd_soc_dai_driver *pcm_dai);
 #endif
index f94b484abb992e92c156e10f9144b1368d93d969..31d8634e8aa1c4f71e7f089bd1da0545e1345ab0 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/firmware.h>
 #include <linux/delay.h>
 #include <sound/pcm.h>
-#include "../common/sst-acpi.h"
+#include <sound/soc-acpi.h>
 #include <sound/hda_register.h>
 #include <sound/hdaudio.h>
 #include <sound/hda_i915.h>
@@ -439,10 +439,10 @@ static int skl_machine_device_register(struct skl *skl, void *driver_data)
 {
        struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
        struct platform_device *pdev;
-       struct sst_acpi_mach *mach = driver_data;
+       struct snd_soc_acpi_mach *mach = driver_data;
        int ret;
 
-       mach = sst_acpi_find_machine(mach);
+       mach = snd_soc_acpi_find_machine(mach);
        if (mach == NULL) {
                dev_err(bus->dev, "No matching machine driver found\n");
                return -ENODEV;
@@ -462,8 +462,11 @@ static int skl_machine_device_register(struct skl *skl, void *driver_data)
                return -EIO;
        }
 
-       if (mach->pdata)
+       if (mach->pdata) {
+               skl->use_tplg_pcm =
+                       ((struct skl_machine_pdata *)mach->pdata)->use_tplg_pcm;
                dev_set_drvdata(&pdev->dev, mach->pdata);
+       }
 
        skl->i2s_dev = pdev;
 
@@ -875,33 +878,36 @@ static void skl_remove(struct pci_dev *pci)
        dev_set_drvdata(&pci->dev, NULL);
 }
 
-static struct sst_codecs skl_codecs = {
+static struct snd_soc_acpi_codecs skl_codecs = {
        .num_codecs = 1,
        .codecs = {"10508825"}
 };
 
-static struct sst_codecs kbl_codecs = {
+static struct snd_soc_acpi_codecs kbl_codecs = {
        .num_codecs = 1,
        .codecs = {"10508825"}
 };
 
-static struct sst_codecs bxt_codecs = {
+static struct snd_soc_acpi_codecs bxt_codecs = {
        .num_codecs = 1,
        .codecs = {"MX98357A"}
 };
 
-static struct sst_codecs kbl_poppy_codecs = {
+static struct snd_soc_acpi_codecs kbl_poppy_codecs = {
        .num_codecs = 1,
        .codecs = {"10EC5663"}
 };
 
-static struct sst_codecs kbl_5663_5514_codecs = {
+static struct snd_soc_acpi_codecs kbl_5663_5514_codecs = {
        .num_codecs = 2,
        .codecs = {"10EC5663", "10EC5514"}
 };
 
+static struct skl_machine_pdata cnl_pdata = {
+       .use_tplg_pcm = true,
+};
 
-static struct sst_acpi_mach sst_skl_devdata[] = {
+static struct snd_soc_acpi_mach sst_skl_devdata[] = {
        {
                .id = "INT343A",
                .drv_name = "skl_alc286s_i2s",
@@ -911,7 +917,7 @@ static struct sst_acpi_mach sst_skl_devdata[] = {
                .id = "INT343B",
                .drv_name = "skl_n88l25_s4567",
                .fw_filename = "intel/dsp_fw_release.bin",
-               .machine_quirk = sst_acpi_codec_list,
+               .machine_quirk = snd_soc_acpi_codec_list,
                .quirk_data = &skl_codecs,
                .pdata = &skl_dmic_data
        },
@@ -919,14 +925,14 @@ static struct sst_acpi_mach sst_skl_devdata[] = {
                .id = "MX98357A",
                .drv_name = "skl_n88l25_m98357a",
                .fw_filename = "intel/dsp_fw_release.bin",
-               .machine_quirk = sst_acpi_codec_list,
+               .machine_quirk = snd_soc_acpi_codec_list,
                .quirk_data = &skl_codecs,
                .pdata = &skl_dmic_data
        },
        {}
 };
 
-static struct sst_acpi_mach sst_bxtp_devdata[] = {
+static struct snd_soc_acpi_mach sst_bxtp_devdata[] = {
        {
                .id = "INT343A",
                .drv_name = "bxt_alc298s_i2s",
@@ -936,13 +942,13 @@ static struct sst_acpi_mach sst_bxtp_devdata[] = {
                .id = "DLGS7219",
                .drv_name = "bxt_da7219_max98357a_i2s",
                .fw_filename = "intel/dsp_fw_bxtn.bin",
-               .machine_quirk = sst_acpi_codec_list,
+               .machine_quirk = snd_soc_acpi_codec_list,
                .quirk_data = &bxt_codecs,
        },
        {}
 };
 
-static struct sst_acpi_mach sst_kbl_devdata[] = {
+static struct snd_soc_acpi_mach sst_kbl_devdata[] = {
        {
                .id = "INT343A",
                .drv_name = "kbl_alc286s_i2s",
@@ -952,7 +958,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
                .id = "INT343B",
                .drv_name = "kbl_n88l25_s4567",
                .fw_filename = "intel/dsp_fw_kbl.bin",
-               .machine_quirk = sst_acpi_codec_list,
+               .machine_quirk = snd_soc_acpi_codec_list,
                .quirk_data = &kbl_codecs,
                .pdata = &skl_dmic_data
        },
@@ -960,7 +966,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
                .id = "MX98357A",
                .drv_name = "kbl_n88l25_m98357a",
                .fw_filename = "intel/dsp_fw_kbl.bin",
-               .machine_quirk = sst_acpi_codec_list,
+               .machine_quirk = snd_soc_acpi_codec_list,
                .quirk_data = &kbl_codecs,
                .pdata = &skl_dmic_data
        },
@@ -968,7 +974,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
                .id = "MX98927",
                .drv_name = "kbl_r5514_5663_max",
                .fw_filename = "intel/dsp_fw_kbl.bin",
-               .machine_quirk = sst_acpi_codec_list,
+               .machine_quirk = snd_soc_acpi_codec_list,
                .quirk_data = &kbl_5663_5514_codecs,
                .pdata = &skl_dmic_data
        },
@@ -976,7 +982,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
                .id = "MX98927",
                .drv_name = "kbl_rt5663_m98927",
                .fw_filename = "intel/dsp_fw_kbl.bin",
-               .machine_quirk = sst_acpi_codec_list,
+               .machine_quirk = snd_soc_acpi_codec_list,
                .quirk_data = &kbl_poppy_codecs,
                .pdata = &skl_dmic_data
        },
@@ -989,7 +995,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
        {}
 };
 
-static struct sst_acpi_mach sst_glk_devdata[] = {
+static struct snd_soc_acpi_mach sst_glk_devdata[] = {
        {
                .id = "INT343A",
                .drv_name = "glk_alc298s_i2s",
@@ -998,12 +1004,14 @@ static struct sst_acpi_mach sst_glk_devdata[] = {
        {}
 };
 
-static const struct sst_acpi_mach sst_cnl_devdata[] = {
+static const struct snd_soc_acpi_mach sst_cnl_devdata[] = {
        {
                .id = "INT34C2",
                .drv_name = "cnl_rt274",
                .fw_filename = "intel/dsp_fw_cnl.bin",
+               .pdata = &cnl_pdata,
        },
+       {}
 };
 
 /* PCI IDs */
index 8d9d6899f761b2a55991ebea505a0e9f9a964fd8..e00cde8200ddd186cea76aeec8442891ad4107a9 100644 (file)
@@ -53,6 +53,7 @@ struct skl {
        struct platform_device *dmic_dev;
        struct platform_device *i2s_dev;
        struct snd_soc_platform *platform;
+       struct snd_soc_dai_driver *dais;
 
        struct nhlt_acpi_table *nhlt; /* nhlt ptr */
        struct skl_sst *skl_sst; /* sst skl ctx */
@@ -73,6 +74,7 @@ struct skl {
        struct skl_debug *debugfs;
        u8 nr_modules;
        struct skl_module **modules;
+       bool use_tplg_pcm;
 };
 
 #define skl_to_ebus(s) (&(s)->ebus)
@@ -85,9 +87,9 @@ struct skl_dma_params {
        u8 stream_tag;
 };
 
-/* to pass dmic data */
 struct skl_machine_pdata {
        u32 dmic_num;
+       bool use_tplg_pcm; /* use dais and dai links from topology */
 };
 
 struct skl_dsp_ops {
similarity index 63%
rename from sound/soc/intel/common/sst-match-acpi.c
rename to sound/soc/soc-acpi.c
index 56d26f36a3cba16f25217b465cfe4704c674e3c9..f21df28bc28e24eafc744fb8b524c26e9cbbd844 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sst_match_apci.c - SST (LPE) match for ACPI enumeration.
+ * soc-apci.c - support for ACPI enumeration.
  *
  * Copyright (c) 2013-15, Intel Corporation.
  *
@@ -14,9 +14,9 @@
  * more details.
  */
 
-#include "sst-acpi.h"
+#include <sound/soc-acpi.h>
 
-static acpi_status sst_acpi_find_name(acpi_handle handle, u32 level,
+static acpi_status snd_soc_acpi_find_name(acpi_handle handle, u32 level,
                                      void *context, void **ret)
 {
        struct acpi_device *adev;
@@ -34,12 +34,12 @@ static acpi_status sst_acpi_find_name(acpi_handle handle, u32 level,
        return AE_OK;
 }
 
-const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
+const char *snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
 {
        const char *name = NULL;
        acpi_status status;
 
-       status = acpi_get_devices(hid, sst_acpi_find_name, NULL,
+       status = acpi_get_devices(hid, snd_soc_acpi_find_name, NULL,
                                  (void **)&name);
 
        if (ACPI_FAILURE(status) || name[0] == '\0')
@@ -47,9 +47,9 @@ const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
 
        return name;
 }
-EXPORT_SYMBOL_GPL(sst_acpi_find_name_from_hid);
+EXPORT_SYMBOL_GPL(snd_soc_acpi_find_name_from_hid);
 
-static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
+static acpi_status snd_soc_acpi_mach_match(acpi_handle handle, u32 level,
                                       void *context, void **ret)
 {
        unsigned long long sta;
@@ -63,26 +63,27 @@ 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])
+bool snd_soc_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);
+       status = acpi_get_devices(hid, snd_soc_acpi_mach_match, &found, NULL);
 
        if (ACPI_FAILURE(status))
                return false;
 
        return found;
 }
-EXPORT_SYMBOL_GPL(sst_acpi_check_hid);
+EXPORT_SYMBOL_GPL(snd_soc_acpi_check_hid);
 
-struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines)
+struct snd_soc_acpi_mach *
+snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines)
 {
-       struct sst_acpi_mach *mach;
+       struct snd_soc_acpi_mach *mach;
 
        for (mach = machines; mach->id[0]; mach++) {
-               if (sst_acpi_check_hid(mach->id) == true) {
+               if (snd_soc_acpi_check_hid(mach->id) == true) {
                        if (mach->machine_quirk == NULL)
                                return mach;
 
@@ -92,14 +93,14 @@ struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines)
        }
        return NULL;
 }
-EXPORT_SYMBOL_GPL(sst_acpi_find_machine);
+EXPORT_SYMBOL_GPL(snd_soc_acpi_find_machine);
 
-static acpi_status sst_acpi_find_package(acpi_handle handle, u32 level,
-                                       void *context, void **ret)
+static acpi_status snd_soc_acpi_find_package(acpi_handle handle, u32 level,
+                                            void *context, void **ret)
 {
        struct acpi_device *adev;
        acpi_status status = AE_OK;
-       struct sst_acpi_package_context *pkg_ctx = context;
+       struct snd_soc_acpi_package_context *pkg_ctx = context;
 
        pkg_ctx->data_valid = false;
 
@@ -137,37 +138,38 @@ static acpi_status sst_acpi_find_package(acpi_handle handle, u32 level,
        return AE_OK;
 }
 
-bool sst_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
-                               struct sst_acpi_package_context *ctx)
+bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
+                               struct snd_soc_acpi_package_context *ctx)
 {
        acpi_status status;
 
-       status = acpi_get_devices(hid, sst_acpi_find_package, ctx, NULL);
+       status = acpi_get_devices(hid, snd_soc_acpi_find_package, ctx, NULL);
 
        if (ACPI_FAILURE(status) || !ctx->data_valid)
                return false;
 
        return true;
 }
-EXPORT_SYMBOL_GPL(sst_acpi_find_package_from_hid);
+EXPORT_SYMBOL_GPL(snd_soc_acpi_find_package_from_hid);
 
-struct sst_acpi_mach *sst_acpi_codec_list(void *arg)
+struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
 {
-       struct sst_acpi_mach *mach = arg;
-       struct sst_codecs *codec_list = (struct sst_codecs *) mach->quirk_data;
+       struct snd_soc_acpi_mach *mach = arg;
+       struct snd_soc_acpi_codecs *codec_list =
+               (struct snd_soc_acpi_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)
+               if (snd_soc_acpi_check_hid(codec_list->codecs[i]) != true)
                        return NULL;
        }
 
        return mach;
 }
-EXPORT_SYMBOL_GPL(sst_acpi_codec_list);
+EXPORT_SYMBOL_GPL(snd_soc_acpi_codec_list);
 
 MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Intel Common ACPI Match module");
+MODULE_DESCRIPTION("ALSA SoC ACPI module");