Merge series "ASoC: cppcheck fixes of the week" from Pierre-Louis Bossart <pierre...
authorMark Brown <broonie@kernel.org>
Tue, 11 May 2021 08:06:00 +0000 (09:06 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 11 May 2021 08:06:00 +0000 (09:06 +0100)
While running some checks on a rebased branch, I realized I missed a
couple of trivial cases on newer code.

Pierre-Louis Bossart (4):
  ASoC: codecs: mt6359-accdet: remove useless initialization
  ASoc: codecs: mt6359: remove useless initializations
  ASoC: codecs: rt1019: clarify expression
  ASoC: fsl: imx-pcm-rpmsg: remove useless initialization

 sound/soc/codecs/mt6359-accdet.c | 2 +-
 sound/soc/codecs/mt6359.c        | 2 +-
 sound/soc/codecs/rt1019.c        | 4 ++--
 sound/soc/fsl/imx-pcm-rpmsg.c    | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

--
2.25.1

52 files changed:
sound/soc/amd/renoir/acp3x-pdm-dma.c
sound/soc/codecs/cs42l42.c
sound/soc/codecs/cs42l42.h
sound/soc/codecs/lpass-rx-macro.c
sound/soc/codecs/lpass-wsa-macro.c
sound/soc/codecs/rt1019.c
sound/soc/codecs/rt286.c
sound/soc/codecs/rt5682-i2c.c
sound/soc/fsl/fsl_spdif.c
sound/soc/fsl/fsl_spdif.h
sound/soc/fsl/fsl_xcvr.c
sound/soc/fsl/imx-pcm-rpmsg.c
sound/soc/fsl/imx-pcm-rpmsg.h
sound/soc/intel/boards/Kconfig
sound/soc/intel/boards/Makefile
sound/soc/intel/boards/bxt_da7219_max98357a.c
sound/soc/intel/boards/bxt_rt298.c
sound/soc/intel/boards/bytcht_cx2072x.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/bytcr_wm5102.c
sound/soc/intel/boards/cht_bsw_rt5645.c
sound/soc/intel/boards/cht_bsw_rt5672.c
sound/soc/intel/boards/cml_rt1011_rt5682.c
sound/soc/intel/boards/ehl_rt5660.c
sound/soc/intel/boards/glk_rt5682_max98357a.c
sound/soc/intel/boards/hda_dsp_common.c
sound/soc/intel/boards/skl_hda_dsp_generic.c
sound/soc/intel/boards/sof_cs42l42.c [new file with mode: 0644]
sound/soc/intel/boards/sof_da7219_max98373.c
sound/soc/intel/boards/sof_maxim_common.c
sound/soc/intel/boards/sof_maxim_common.h
sound/soc/intel/boards/sof_pcm512x.c
sound/soc/intel/boards/sof_rt5682.c
sound/soc/intel/boards/sof_sdw.c
sound/soc/intel/boards/sof_sdw_common.h
sound/soc/intel/boards/sof_sdw_max98373.c
sound/soc/intel/boards/sof_wm8804.c
sound/soc/intel/common/soc-acpi-intel-adl-match.c
sound/soc/intel/common/soc-acpi-intel-glk-match.c
sound/soc/jz4740/jz4740-i2s.c
sound/soc/jz4740/jz4740-i2s.h
sound/soc/mediatek/mt8192/mt8192-dai-adda.c
sound/soc/qcom/qdsp6/q6afe.c
sound/soc/sof/intel/Makefile
sound/soc/sof/intel/atom.c [new file with mode: 0644]
sound/soc/sof/intel/atom.h [new file with mode: 0644]
sound/soc/sof/intel/byt.c
sound/soc/sof/intel/pci-tng.c

index 4c2810e..bd20622 100644 (file)
@@ -77,7 +77,6 @@ static void enable_pdm_clock(void __iomem *acp_base)
        u32 pdm_clk_enable, pdm_ctrl;
 
        pdm_clk_enable = ACP_PDM_CLK_FREQ_MASK;
-       pdm_ctrl = 0x00;
 
        rn_writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
        pdm_ctrl = rn_readl(acp_base + ACP_WOV_MISC_CTRL);
@@ -144,9 +143,6 @@ static int stop_pdm_dma(void __iomem *acp_base)
        u32 pdm_enable, pdm_dma_enable;
        int timeout;
 
-       pdm_enable = 0x00;
-       pdm_dma_enable  = 0x00;
-
        pdm_enable = rn_readl(acp_base + ACP_WOV_PDM_ENABLE);
        pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
        if (pdm_dma_enable & 0x01) {
index bf982e1..d9f8da7 100644 (file)
 #include <linux/gpio.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
+#include <linux/acpi.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/regulator/consumer.h>
 #include <linux/gpio/consumer.h>
-#include <linux/of.h>
-#include <linux/of_gpio.h>
 #include <linux/of_device.h>
 #include <linux/pm_runtime.h>
 #include <sound/core.h>
@@ -518,26 +518,33 @@ static const struct snd_soc_dapm_route cs42l42_audio_map[] = {
        { "SDOUT2", NULL, "ASP TX EN" },
 };
 
+static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_jack *jk, void *d)
+{
+       struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
+
+       cs42l42->jack = jk;
+
+       regmap_update_bits(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK,
+                          CS42L42_RS_PLUG_MASK | CS42L42_RS_UNPLUG_MASK |
+                          CS42L42_TS_PLUG_MASK | CS42L42_TS_UNPLUG_MASK,
+                          (1 << CS42L42_RS_PLUG_SHIFT) | (1 << CS42L42_RS_UNPLUG_SHIFT) |
+                          (0 << CS42L42_TS_PLUG_SHIFT) | (0 << CS42L42_TS_UNPLUG_SHIFT));
+
+       return 0;
+}
+
 static int cs42l42_component_probe(struct snd_soc_component *component)
 {
-       struct cs42l42_private *cs42l42 =
-               (struct cs42l42_private *)snd_soc_component_get_drvdata(component);
-       struct snd_soc_card *crd = component->card;
-       int ret = 0;
+       struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
 
        cs42l42->component = component;
 
-       ret = snd_soc_card_jack_new(crd, "CS42L42 Headset", SND_JACK_HEADSET | SND_JACK_BTN_0 |
-                                   SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3,
-                                   &cs42l42->jack, NULL, 0);
-       if (ret < 0)
-               dev_err(component->dev, "Cannot create CS42L42 Headset: %d\n", ret);
-
-       return ret;
+       return 0;
 }
 
 static const struct snd_soc_component_driver soc_component_dev_cs42l42 = {
        .probe                  = cs42l42_component_probe,
+       .set_jack               = cs42l42_set_jack,
        .dapm_widgets           = cs42l42_dapm_widgets,
        .num_dapm_widgets       = ARRAY_SIZE(cs42l42_dapm_widgets),
        .dapm_routes            = cs42l42_audio_map,
@@ -1410,11 +1417,11 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
                        switch(cs42l42->hs_type){
                        case CS42L42_PLUG_CTIA:
                        case CS42L42_PLUG_OMTP:
-                               snd_soc_jack_report(&cs42l42->jack, SND_JACK_HEADSET,
+                               snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADSET,
                                                    SND_JACK_HEADSET);
                                break;
                        case CS42L42_PLUG_HEADPHONE:
-                               snd_soc_jack_report(&cs42l42->jack, SND_JACK_HEADPHONE,
+                               snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADPHONE,
                                                    SND_JACK_HEADPHONE);
                                break;
                        default:
@@ -1442,10 +1449,10 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
                                switch(cs42l42->hs_type){
                                case CS42L42_PLUG_CTIA:
                                case CS42L42_PLUG_OMTP:
-                                       snd_soc_jack_report(&cs42l42->jack, 0, SND_JACK_HEADSET);
+                                       snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADSET);
                                        break;
                                case CS42L42_PLUG_HEADPHONE:
-                                       snd_soc_jack_report(&cs42l42->jack, 0, SND_JACK_HEADPHONE);
+                                       snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADPHONE);
                                        break;
                                default:
                                        break;
@@ -1472,7 +1479,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
                                report = cs42l42_handle_button_press(cs42l42);
 
                        }
-                       snd_soc_jack_report(&cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+                       snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
                                                                   SND_JACK_BTN_2 | SND_JACK_BTN_3);
                }
        }
@@ -1579,8 +1586,8 @@ static void cs42l42_set_interrupt_masks(struct cs42l42_private *cs42l42)
                        CS42L42_TS_UNPLUG_MASK,
                        (1 << CS42L42_RS_PLUG_SHIFT) |
                        (1 << CS42L42_RS_UNPLUG_SHIFT) |
-                       (0 << CS42L42_TS_PLUG_SHIFT) |
-                       (0 << CS42L42_TS_UNPLUG_SHIFT));
+                       (1 << CS42L42_TS_PLUG_SHIFT) |
+                       (1 << CS42L42_TS_UNPLUG_SHIFT));
 }
 
 static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42)
@@ -1630,17 +1637,15 @@ static const unsigned int threshold_defaults[] = {
        CS42L42_HS_DET_LEVEL_1
 };
 
-static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
+static int cs42l42_handle_device_data(struct device *dev,
                                        struct cs42l42_private *cs42l42)
 {
-       struct device_node *np = i2c_client->dev.of_node;
        unsigned int val;
-       unsigned int thresholds[CS42L42_NUM_BIASES];
+       u32 thresholds[CS42L42_NUM_BIASES];
        int ret;
        int i;
 
-       ret = of_property_read_u32(np, "cirrus,ts-inv", &val);
-
+       ret = device_property_read_u32(dev, "cirrus,ts-inv", &val);
        if (!ret) {
                switch (val) {
                case CS42L42_TS_INV_EN:
@@ -1648,7 +1653,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
                        cs42l42->ts_inv = val;
                        break;
                default:
-                       dev_err(&i2c_client->dev,
+                       dev_err(dev,
                                "Wrong cirrus,ts-inv DT value %d\n",
                                val);
                        cs42l42->ts_inv = CS42L42_TS_INV_DIS;
@@ -1661,8 +1666,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
                        CS42L42_TS_INV_MASK,
                        (cs42l42->ts_inv << CS42L42_TS_INV_SHIFT));
 
-       ret = of_property_read_u32(np, "cirrus,ts-dbnc-rise", &val);
-
+       ret = device_property_read_u32(dev, "cirrus,ts-dbnc-rise", &val);
        if (!ret) {
                switch (val) {
                case CS42L42_TS_DBNCE_0:
@@ -1676,7 +1680,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
                        cs42l42->ts_dbnc_rise = val;
                        break;
                default:
-                       dev_err(&i2c_client->dev,
+                       dev_err(dev,
                                "Wrong cirrus,ts-dbnc-rise DT value %d\n",
                                val);
                        cs42l42->ts_dbnc_rise = CS42L42_TS_DBNCE_1000;
@@ -1690,8 +1694,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
                        (cs42l42->ts_dbnc_rise <<
                        CS42L42_TS_RISE_DBNCE_TIME_SHIFT));
 
-       ret = of_property_read_u32(np, "cirrus,ts-dbnc-fall", &val);
-
+       ret = device_property_read_u32(dev, "cirrus,ts-dbnc-fall", &val);
        if (!ret) {
                switch (val) {
                case CS42L42_TS_DBNCE_0:
@@ -1705,7 +1708,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
                        cs42l42->ts_dbnc_fall = val;
                        break;
                default:
-                       dev_err(&i2c_client->dev,
+                       dev_err(dev,
                                "Wrong cirrus,ts-dbnc-fall DT value %d\n",
                                val);
                        cs42l42->ts_dbnc_fall = CS42L42_TS_DBNCE_0;
@@ -1719,13 +1722,12 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
                        (cs42l42->ts_dbnc_fall <<
                        CS42L42_TS_FALL_DBNCE_TIME_SHIFT));
 
-       ret = of_property_read_u32(np, "cirrus,btn-det-init-dbnce", &val);
-
+       ret = device_property_read_u32(dev, "cirrus,btn-det-init-dbnce", &val);
        if (!ret) {
                if (val <= CS42L42_BTN_DET_INIT_DBNCE_MAX)
                        cs42l42->btn_det_init_dbnce = val;
                else {
-                       dev_err(&i2c_client->dev,
+                       dev_err(dev,
                                "Wrong cirrus,btn-det-init-dbnce DT value %d\n",
                                val);
                        cs42l42->btn_det_init_dbnce =
@@ -1736,14 +1738,13 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
                        CS42L42_BTN_DET_INIT_DBNCE_DEFAULT;
        }
 
-       ret = of_property_read_u32(np, "cirrus,btn-det-event-dbnce", &val);
-
+       ret = device_property_read_u32(dev, "cirrus,btn-det-event-dbnce", &val);
        if (!ret) {
                if (val <= CS42L42_BTN_DET_EVENT_DBNCE_MAX)
                        cs42l42->btn_det_event_dbnce = val;
                else {
-                       dev_err(&i2c_client->dev,
-                       "Wrong cirrus,btn-det-event-dbnce DT value %d\n", val);
+                       dev_err(dev,
+                               "Wrong cirrus,btn-det-event-dbnce DT value %d\n", val);
                        cs42l42->btn_det_event_dbnce =
                                CS42L42_BTN_DET_EVENT_DBNCE_DEFAULT;
                }
@@ -1752,19 +1753,17 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
                        CS42L42_BTN_DET_EVENT_DBNCE_DEFAULT;
        }
 
-       ret = of_property_read_u32_array(np, "cirrus,bias-lvls",
-                                  (u32 *)thresholds, CS42L42_NUM_BIASES);
-
+       ret = device_property_read_u32_array(dev, "cirrus,bias-lvls",
+                                            thresholds, ARRAY_SIZE(thresholds));
        if (!ret) {
                for (i = 0; i < CS42L42_NUM_BIASES; i++) {
                        if (thresholds[i] <= CS42L42_HS_DET_LEVEL_MAX)
                                cs42l42->bias_thresholds[i] = thresholds[i];
                        else {
-                               dev_err(&i2c_client->dev,
-                               "Wrong cirrus,bias-lvls[%d] DT value %d\n", i,
+                               dev_err(dev,
+                                       "Wrong cirrus,bias-lvls[%d] DT value %d\n", i,
                                        thresholds[i]);
-                               cs42l42->bias_thresholds[i] =
-                                       threshold_defaults[i];
+                               cs42l42->bias_thresholds[i] = threshold_defaults[i];
                        }
                }
        } else {
@@ -1772,8 +1771,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
                        cs42l42->bias_thresholds[i] = threshold_defaults[i];
        }
 
-       ret = of_property_read_u32(np, "cirrus,hs-bias-ramp-rate", &val);
-
+       ret = device_property_read_u32(dev, "cirrus,hs-bias-ramp-rate", &val);
        if (!ret) {
                switch (val) {
                case CS42L42_HSBIAS_RAMP_FAST_RISE_SLOW_FALL:
@@ -1793,7 +1791,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
                        cs42l42->hs_bias_ramp_time = CS42L42_HSBIAS_RAMP_TIME3;
                        break;
                default:
-                       dev_err(&i2c_client->dev,
+                       dev_err(dev,
                                "Wrong cirrus,hs-bias-ramp-rate DT value %d\n",
                                val);
                        cs42l42->hs_bias_ramp_rate = CS42L42_HSBIAS_RAMP_SLOW;
@@ -1923,11 +1921,9 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client,
                        (1 << CS42L42_ADC_PDN_SHIFT) |
                        (0 << CS42L42_PDN_ALL_SHIFT));
 
-       if (i2c_client->dev.of_node) {
-               ret = cs42l42_handle_device_data(i2c_client, cs42l42);
-               if (ret != 0)
-                       goto err_disable;
-       }
+       ret = cs42l42_handle_device_data(&i2c_client->dev, cs42l42);
+       if (ret != 0)
+               goto err_disable;
 
        /* Setup headset detection */
        cs42l42_setup_hs_type_detect(cs42l42);
@@ -2006,12 +2002,21 @@ static const struct dev_pm_ops cs42l42_runtime_pm = {
                           NULL)
 };
 
+#ifdef CONFIG_OF
 static const struct of_device_id cs42l42_of_match[] = {
        { .compatible = "cirrus,cs42l42", },
-       {},
+       {}
 };
 MODULE_DEVICE_TABLE(of, cs42l42_of_match);
+#endif
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id cs42l42_acpi_match[] = {
+       {"10134242", 0,},
+       {}
+};
+MODULE_DEVICE_TABLE(acpi, cs42l42_acpi_match);
+#endif
 
 static const struct i2c_device_id cs42l42_id[] = {
        {"cs42l42", 0},
@@ -2024,7 +2029,8 @@ static struct i2c_driver cs42l42_i2c_driver = {
        .driver = {
                .name = "cs42l42",
                .pm = &cs42l42_runtime_pm,
-               .of_match_table = cs42l42_of_match,
+               .of_match_table = of_match_ptr(cs42l42_of_match),
+               .acpi_match_table = ACPI_PTR(cs42l42_acpi_match),
                },
        .id_table = cs42l42_id,
        .probe = cs42l42_i2c_probe,
index 36b763f..2e0d383 100644 (file)
@@ -773,7 +773,7 @@ struct  cs42l42_private {
        struct regulator_bulk_data supplies[CS42L42_NUM_SUPPLIES];
        struct gpio_desc *reset_gpio;
        struct completion pdn_done;
-       struct snd_soc_jack jack;
+       struct snd_soc_jack *jack;
        int bclk;
        u32 sclk;
        u32 srate;
index b0ebfc8..8dff72f 100644 (file)
@@ -2628,7 +2628,7 @@ static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w,
                break;
        default:
                break;
-       };
+       }
        return 0;
 }
 
index 1a7fa54..d3ac318 100644 (file)
@@ -1727,6 +1727,10 @@ static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
                val = val & CDC_WSA_RX_MIX_TX1_SEL_MASK;
                ec_tx = (val >> CDC_WSA_RX_MIX_TX1_SEL_SHFT) - 1;
                break;
+       default:
+               dev_err(component->dev, "%s: Invalid shift %u\n",
+                       __func__, w->shift);
+               return -EINVAL;
        }
 
        if (wsa->ec_hq[ec_tx]) {
index 1ed85ec..8c0b002 100644 (file)
@@ -522,6 +522,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt1019 = {
        .num_dapm_widgets       = ARRAY_SIZE(rt1019_dapm_widgets),
        .dapm_routes            = rt1019_dapm_routes,
        .num_dapm_routes        = ARRAY_SIZE(rt1019_dapm_routes),
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt1019_regmap = {
index 802f485..caa7208 100644 (file)
@@ -725,7 +725,6 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       d_len_code = 0;
        switch (params_width(params)) {
        /* bit 6:4 Bits per Sample */
        case 16:
index 8ea9f1d..4a56a52 100644 (file)
@@ -273,12 +273,23 @@ static void rt5682_i2c_shutdown(struct i2c_client *client)
 {
        struct rt5682_priv *rt5682 = i2c_get_clientdata(client);
 
+       disable_irq(client->irq);
        cancel_delayed_work_sync(&rt5682->jack_detect_work);
        cancel_delayed_work_sync(&rt5682->jd_check_work);
 
        rt5682_reset(rt5682);
 }
 
+static int rt5682_i2c_remove(struct i2c_client *client)
+{
+       struct rt5682_priv *rt5682 = i2c_get_clientdata(client);
+
+       rt5682_i2c_shutdown(client);
+       regulator_bulk_disable(ARRAY_SIZE(rt5682->supplies), rt5682->supplies);
+
+       return 0;
+}
+
 static const struct of_device_id rt5682_of_match[] = {
        {.compatible = "realtek,rt5682i"},
        {},
@@ -305,6 +316,7 @@ static struct i2c_driver rt5682_i2c_driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
        .probe = rt5682_i2c_probe,
+       .remove = rt5682_i2c_remove,
        .shutdown = rt5682_i2c_shutdown,
        .id_table = rt5682_i2c_id,
 };
index c631de3..2a76714 100644 (file)
@@ -49,6 +49,7 @@ static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0xa, 0xb };
  * @imx: for imx platform
  * @shared_root_clock: flag of sharing a clock source with others;
  *                     so the driver shouldn't set root clock rate
+ * @raw_capture_mode: if raw capture mode support
  * @interrupts: interrupt number
  * @tx_burst: tx maxburst size
  * @rx_burst: rx maxburst size
@@ -57,6 +58,7 @@ static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0xa, 0xb };
 struct fsl_spdif_soc_data {
        bool imx;
        bool shared_root_clock;
+       bool raw_capture_mode;
        u32 interrupts;
        u32 tx_burst;
        u32 rx_burst;
@@ -136,6 +138,7 @@ struct fsl_spdif_priv {
 static struct fsl_spdif_soc_data fsl_spdif_vf610 = {
        .imx = false,
        .shared_root_clock = false,
+       .raw_capture_mode = false,
        .interrupts = 1,
        .tx_burst = FSL_SPDIF_TXFIFO_WML,
        .rx_burst = FSL_SPDIF_RXFIFO_WML,
@@ -145,6 +148,7 @@ static struct fsl_spdif_soc_data fsl_spdif_vf610 = {
 static struct fsl_spdif_soc_data fsl_spdif_imx35 = {
        .imx = true,
        .shared_root_clock = false,
+       .raw_capture_mode = false,
        .interrupts = 1,
        .tx_burst = FSL_SPDIF_TXFIFO_WML,
        .rx_burst = FSL_SPDIF_RXFIFO_WML,
@@ -154,6 +158,7 @@ static struct fsl_spdif_soc_data fsl_spdif_imx35 = {
 static struct fsl_spdif_soc_data fsl_spdif_imx6sx = {
        .imx = true,
        .shared_root_clock = true,
+       .raw_capture_mode = false,
        .interrupts = 1,
        .tx_burst = FSL_SPDIF_TXFIFO_WML,
        .rx_burst = FSL_SPDIF_RXFIFO_WML,
@@ -164,12 +169,23 @@ static struct fsl_spdif_soc_data fsl_spdif_imx6sx = {
 static struct fsl_spdif_soc_data fsl_spdif_imx8qm = {
        .imx = true,
        .shared_root_clock = true,
+       .raw_capture_mode = false,
        .interrupts = 2,
        .tx_burst = 2,          /* Applied for EDMA */
        .rx_burst = 2,          /* Applied for EDMA */
        .tx_formats = SNDRV_PCM_FMTBIT_S24_LE,  /* Applied for EDMA */
 };
 
+static struct fsl_spdif_soc_data fsl_spdif_imx8mm = {
+       .imx = true,
+       .shared_root_clock = false,
+       .raw_capture_mode = true,
+       .interrupts = 1,
+       .tx_burst = FSL_SPDIF_TXFIFO_WML,
+       .rx_burst = FSL_SPDIF_RXFIFO_WML,
+       .tx_formats = FSL_SPDIF_FORMATS_PLAYBACK,
+};
+
 /* Check if clk is a root clock that does not share clock source with others */
 static inline bool fsl_spdif_can_set_clk_rate(struct fsl_spdif_priv *spdif, int clk)
 {
@@ -846,6 +862,39 @@ static int fsl_spdif_tx_vbit_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+static int fsl_spdif_rx_rcm_get(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+       struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
+       struct regmap *regmap = spdif_priv->regmap;
+       u32 val;
+
+       regmap_read(regmap, REG_SPDIF_SCR, &val);
+       val = (val & SCR_RAW_CAPTURE_MODE) ? 1 : 0;
+       ucontrol->value.integer.value[0] = val;
+
+       return 0;
+}
+
+static int fsl_spdif_rx_rcm_put(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+       struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
+       struct regmap *regmap = spdif_priv->regmap;
+       u32 val = (ucontrol->value.integer.value[0] ? SCR_RAW_CAPTURE_MODE : 0);
+
+       if (val)
+               cpu_dai->driver->capture.formats |= SNDRV_PCM_FMTBIT_S32_LE;
+       else
+               cpu_dai->driver->capture.formats &= ~SNDRV_PCM_FMTBIT_S32_LE;
+
+       regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_RAW_CAPTURE_MODE, val);
+
+       return 0;
+}
+
 /* DPLL lock information */
 static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_info *uinfo)
@@ -1029,6 +1078,19 @@ static struct snd_kcontrol_new fsl_spdif_ctrls[] = {
        },
 };
 
+static struct snd_kcontrol_new fsl_spdif_ctrls_rcm[] = {
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+               .name = "IEC958 Raw Capture Mode",
+               .access = SNDRV_CTL_ELEM_ACCESS_READ |
+                       SNDRV_CTL_ELEM_ACCESS_WRITE |
+                       SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+               .info = snd_ctl_boolean_mono_info,
+               .get = fsl_spdif_rx_rcm_get,
+               .put = fsl_spdif_rx_rcm_put,
+       },
+};
+
 static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
 {
        struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai);
@@ -1038,6 +1100,10 @@ static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
 
        snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls));
 
+       if (spdif_private->soc->raw_capture_mode)
+               snd_soc_add_dai_controls(dai, fsl_spdif_ctrls_rcm,
+                                        ARRAY_SIZE(fsl_spdif_ctrls_rcm));
+
        /*Clear the val bit for Tx*/
        regmap_update_bits(spdif_private->regmap, REG_SPDIF_SCR,
                           SCR_VAL_MASK, SCR_VAL_CLEAR);
@@ -1476,6 +1542,7 @@ static const struct of_device_id fsl_spdif_dt_ids[] = {
        { .compatible = "fsl,vf610-spdif", .data = &fsl_spdif_vf610, },
        { .compatible = "fsl,imx6sx-spdif", .data = &fsl_spdif_imx6sx, },
        { .compatible = "fsl,imx8qm-spdif", .data = &fsl_spdif_imx8qm, },
+       { .compatible = "fsl,imx8mm-spdif", .data = &fsl_spdif_imx8mm, },
        {}
 };
 MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);
index d5f1dfd..bff8290 100644 (file)
@@ -63,6 +63,7 @@
 #define SCR_TXFIFO_FSEL_IF4            (0x1 << SCR_TXFIFO_FSEL_OFFSET)
 #define SCR_TXFIFO_FSEL_IF8            (0x2 << SCR_TXFIFO_FSEL_OFFSET)
 #define SCR_TXFIFO_FSEL_IF12           (0x3 << SCR_TXFIFO_FSEL_OFFSET)
+#define SCR_RAW_CAPTURE_MODE           BIT(14)
 #define SCR_LOW_POWER                  (1 << 13)
 #define SCR_SOFT_RESET                 (1 << 12)
 #define SCR_TXFIFO_CTRL_OFFSET         10
index 6cb5581..df7c189 100644 (file)
@@ -736,7 +736,7 @@ static int fsl_xcvr_load_firmware(struct fsl_xcvr *xcvr)
                        /* clean current page, including data memory */
                        memset_io(xcvr->ram_addr, 0, size);
                }
-       };
+       }
 
 err_firmware:
        release_firmware(fw);
index 6d883a1..6d6c44c 100644 (file)
@@ -161,10 +161,10 @@ static int imx_rpmsg_pcm_hw_params(struct snd_soc_component *component,
                msg->s_msg.param.format   = RPMSG_S24_LE;
                break;
        case SNDRV_PCM_FORMAT_DSD_U16_LE:
-               msg->s_msg.param.format   = SNDRV_PCM_FORMAT_DSD_U16_LE;
+               msg->s_msg.param.format   = RPMSG_DSD_U16_LE;
                break;
        case SNDRV_PCM_FORMAT_DSD_U32_LE:
-               msg->s_msg.param.format   = SNDRV_PCM_FORMAT_DSD_U32_LE;
+               msg->s_msg.param.format   = RPMSG_DSD_U32_LE;
                break;
        default:
                msg->s_msg.param.format   = RPMSG_S32_LE;
index 308d153..8286b55 100644 (file)
 #define        RPMSG_S16_LE            0x0
 #define        RPMSG_S24_LE            0x1
 #define        RPMSG_S32_LE            0x2
-#define        RPMSG_DSD_U16_LE        0x3
+#define        RPMSG_DSD_U16_LE        49  /* SNDRV_PCM_FORMAT_DSD_U16_LE */
 #define        RPMSG_DSD_U24_LE        0x4
-#define        RPMSG_DSD_U32_LE        0x5
+#define        RPMSG_DSD_U32_LE        50  /* SNDRV_PCM_FORMAT_DSD_U32_LE */
 
 #define        RPMSG_CH_LEFT           0x0
 #define        RPMSG_CH_RIGHT          0x1
index 5837939..eef5f4a 100644 (file)
@@ -26,6 +26,12 @@ config SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES
          interface.
          If unsure select N.
 
+config SND_SOC_INTEL_HDA_DSP_COMMON
+       tristate
+
+config SND_SOC_INTEL_SOF_MAXIM_COMMON
+       tristate
+
 if SND_SOC_INTEL_CATPT
 
 config SND_SOC_INTEL_HASWELL_MACH
@@ -278,6 +284,7 @@ config SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
        select SND_SOC_MAX98390
        select SND_SOC_DMIC
        select SND_SOC_HDAC_HDMI
+       select SND_SOC_INTEL_HDA_DSP_COMMON
 
 config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
        tristate
@@ -304,6 +311,7 @@ config SND_SOC_INTEL_BXT_RT298_MACH
        select SND_SOC_RT298
        select SND_SOC_DMIC
        select SND_SOC_HDAC_HDMI
+       select SND_SOC_INTEL_HDA_DSP_COMMON
        help
           This adds support for ASoC machine driver for Broxton platforms
           with RT286 I2S audio codec.
@@ -422,6 +430,7 @@ config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH
        select SND_SOC_MAX98357A
        select SND_SOC_DMIC
        select SND_SOC_HDAC_HDMI
+       select SND_SOC_INTEL_HDA_DSP_COMMON
        help
           This adds support for ASoC machine driver for Geminilake platforms
           with RT5682 + MAX98357A I2S audio codec.
@@ -437,6 +446,7 @@ config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH
        depends on SND_HDA_CODEC_HDMI
        depends on GPIOLIB
        select SND_SOC_HDAC_HDMI
+       select SND_SOC_INTEL_HDA_DSP_COMMON
        select SND_SOC_DMIC
        # SND_SOC_HDAC_HDA is already selected
        help
@@ -461,18 +471,38 @@ config SND_SOC_INTEL_SOF_RT5682_MACH
        select SND_SOC_RT5682_I2C
        select SND_SOC_DMIC
        select SND_SOC_HDAC_HDMI
+       select SND_SOC_INTEL_HDA_DSP_COMMON
+       select SND_SOC_INTEL_SOF_MAXIM_COMMON
        help
           This adds support for ASoC machine driver for SOF platforms
           with rt5682 codec.
           Say Y if you have such a device.
           If unsure select "N".
 
+config SND_SOC_INTEL_SOF_CS42L42_MACH
+       tristate "SOF with cs42l42 codec in I2S Mode"
+       depends on I2C && ACPI
+       depends on ((SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC) &&\
+                   (MFD_INTEL_LPSS || COMPILE_TEST))
+       select SND_SOC_CS42L42
+       select SND_SOC_MAX98357A
+       select SND_SOC_DMIC
+       select SND_SOC_HDAC_HDMI
+       select SND_SOC_INTEL_HDA_DSP_COMMON
+       select SND_SOC_INTEL_SOF_MAXIM_COMMON
+       help
+          This adds support for ASoC machine driver for SOF platforms
+          with cs42l42 codec.
+          Say Y if you have such a device.
+          If unsure select "N".
+
 config SND_SOC_INTEL_SOF_PCM512x_MACH
        tristate "SOF with TI PCM512x codec"
        depends on I2C && ACPI
        depends on (SND_SOC_SOF_HDA_AUDIO_CODEC && (MFD_INTEL_LPSS || COMPILE_TEST)) ||\
                   (SND_SOC_SOF_BAYTRAIL && (X86_INTEL_LPSS || COMPILE_TEST))
        depends on SND_HDA_CODEC_HDMI
+       select SND_SOC_INTEL_HDA_DSP_COMMON
        select SND_SOC_PCM512x_I2C
        help
          This adds support for ASoC machine driver for SOF platforms
@@ -504,6 +534,7 @@ config SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH
        select SND_SOC_RT5682_I2C
        select SND_SOC_DMIC
        select SND_SOC_HDAC_HDMI
+       select SND_SOC_INTEL_HDA_DSP_COMMON
        help
          This adds support for ASoC machine driver for SOF platform with
          RT1011 + RT5682 I2S codec.
@@ -519,6 +550,7 @@ config SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH
        depends on I2C && ACPI && GPIOLIB
        depends on MFD_INTEL_LPSS || COMPILE_TEST
        depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC
+       select SND_SOC_INTEL_HDA_DSP_COMMON
        select SND_SOC_DA7219
        select SND_SOC_MAX98373_I2C
        select SND_SOC_DMIC
@@ -539,6 +571,7 @@ config SND_SOC_INTEL_EHL_RT5660_MACH
        depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC
        select SND_SOC_RT5660
        select SND_SOC_DMIC
+       select SND_SOC_INTEL_HDA_DSP_COMMON
        help
          This adds support for ASoC machine driver for Elkhart Lake
          platform with RT5660 I2S audio codec.
@@ -566,6 +599,8 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
        select SND_SOC_RT715_SDCA_SDW
        select SND_SOC_RT5682_SDW
        select SND_SOC_DMIC
+       select SND_SOC_INTEL_HDA_DSP_COMMON
+       select SND_SOC_INTEL_SOF_MAXIM_COMMON
        help
          Add support for Intel SoundWire-based platforms connected to
          MAX98373, RT700, RT711, RT1308 and RT715
@@ -573,5 +608,4 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
 
 endif
 
-
 endif ## SND_SOC_INTEL_MACH
index 616c5fb..ed21b82 100644 (file)
@@ -3,11 +3,11 @@ snd-soc-sst-haswell-objs := haswell.o
 snd-soc-sst-bdw-rt5650-mach-objs := bdw-rt5650.o
 snd-soc-sst-bdw-rt5677-mach-objs := bdw-rt5677.o
 snd-soc-sst-broadwell-objs := broadwell.o
-snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o hda_dsp_common.o
-snd-soc-sst-bxt-rt298-objs := bxt_rt298.o hda_dsp_common.o
-snd-soc-sst-sof-pcm512x-objs := sof_pcm512x.o hda_dsp_common.o
+snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o
+snd-soc-sst-bxt-rt298-objs := bxt_rt298.o
+snd-soc-sst-sof-pcm512x-objs := sof_pcm512x.o
 snd-soc-sst-sof-wm8804-objs := sof_wm8804.o
-snd-soc-sst-glk-rt5682_max98357a-objs := glk_rt5682_max98357a.o hda_dsp_common.o
+snd-soc-sst-glk-rt5682_max98357a-objs := glk_rt5682_max98357a.o
 snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o
 snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o
 snd-soc-sst-bytcr-wm5102-objs := bytcr_wm5102.o
@@ -19,28 +19,29 @@ snd-soc-sst-byt-cht-cx2072x-objs := bytcht_cx2072x.o
 snd-soc-sst-byt-cht-da7213-objs := bytcht_da7213.o
 snd-soc-sst-byt-cht-es8316-objs := bytcht_es8316.o
 snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.o
-snd-soc-sof_rt5682-objs := sof_rt5682.o hda_dsp_common.o sof_maxim_common.o sof_realtek_common.o
-snd-soc-cml_rt1011_rt5682-objs := cml_rt1011_rt5682.o hda_dsp_common.o
+snd-soc-sof_rt5682-objs := sof_rt5682.o sof_realtek_common.o
+snd-soc-sof_cs42l42-objs := sof_cs42l42.o
+snd-soc-cml_rt1011_rt5682-objs := cml_rt1011_rt5682.o
 snd-soc-kbl_da7219_max98357a-objs := kbl_da7219_max98357a.o
 snd-soc-kbl_da7219_max98927-objs := kbl_da7219_max98927.o
 snd-soc-kbl_rt5663_max98927-objs := kbl_rt5663_max98927.o
 snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o
 snd-soc-kbl_rt5660-objs := kbl_rt5660.o
 snd-soc-skl_rt286-objs := skl_rt286.o
-snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o hda_dsp_common.o
+snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o
 snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o
 snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o
-snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o hda_dsp_common.o
-snd-soc-ehl-rt5660-objs := ehl_rt5660.o hda_dsp_common.o
+snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o
+snd-soc-ehl-rt5660-objs := ehl_rt5660.o
 snd-soc-sof-sdw-objs += sof_sdw.o                              \
                        sof_sdw_max98373.o                      \
                        sof_sdw_rt1308.o sof_sdw_rt1316.o       \
                        sof_sdw_rt5682.o sof_sdw_rt700.o        \
                        sof_sdw_rt711.o sof_sdw_rt711_sdca.o    \
                        sof_sdw_rt715.o sof_sdw_rt715_sdca.o    \
-                       sof_maxim_common.o                      \
-                       sof_sdw_dmic.o sof_sdw_hdmi.o hda_dsp_common.o
+                       sof_sdw_dmic.o sof_sdw_hdmi.o
 obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o
+obj-$(CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH) += snd-soc-sof_cs42l42.o
 obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
 obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON) += snd-soc-sst-bxt-da7219_max98357a.o
 obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o
@@ -74,3 +75,10 @@ obj-$(CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH) += snd-soc-skl_hda_dsp.o
 obj-$(CONFIG_SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH) += snd-soc-sof_da7219_max98373.o
 obj-$(CONFIG_SND_SOC_INTEL_EHL_RT5660_MACH) += snd-soc-ehl-rt5660.o
 obj-$(CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH) += snd-soc-sof-sdw.o
+
+# common modules
+snd-soc-intel-hda-dsp-common-objs := hda_dsp_common.o
+obj-$(CONFIG_SND_SOC_INTEL_HDA_DSP_COMMON) += snd-soc-intel-hda-dsp-common.o
+
+snd-soc-intel-sof-maxim-common-objs += sof_maxim_common.o
+obj-$(CONFIG_SND_SOC_INTEL_SOF_MAXIM_COMMON) += snd-soc-intel-sof-maxim-common.o
index 9ffef39..07ae950 100644 (file)
@@ -869,3 +869,4 @@ MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:bxt_da7219_max98357a");
 MODULE_ALIAS("platform:glk_da7219_max98357a");
 MODULE_ALIAS("platform:cml_da7219_max98357a");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
index 0f3157d..32a776f 100644 (file)
@@ -667,3 +667,4 @@ MODULE_DESCRIPTION("Intel SST Audio for Broxton");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:bxt_alc298s_i2s");
 MODULE_ALIAS("platform:glk_alc298s_i2s");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
index 2bfe3e4..a9e51bb 100644 (file)
@@ -198,7 +198,6 @@ static struct snd_soc_dai_link byt_cht_cx2072x_dais[] = {
                                              | SND_SOC_DAIFMT_CBS_CFS,
                .init = byt_cht_cx2072x_init,
                .be_hw_params_fixup = byt_cht_cx2072x_fixup,
-               .nonatomic = true,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                SND_SOC_DAILINK_REG(ssp2, cx2072x, platform),
index cfeba27..a28773f 100644 (file)
@@ -197,7 +197,6 @@ static struct snd_soc_dai_link dailink[] = {
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
                                                | SND_SOC_DAIFMT_CBS_CFS,
                .be_hw_params_fixup = codec_fixup,
-               .nonatomic = true,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                .ops = &ssp2_ops,
index 06df2d4..a0af915 100644 (file)
@@ -337,7 +337,6 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
                                                | SND_SOC_DAIFMT_CBS_CFS,
                .be_hw_params_fixup = byt_cht_es8316_codec_fixup,
-               .nonatomic = true,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                .init = byt_cht_es8316_init,
index 8c0dab1..9b48fe7 100644 (file)
@@ -144,7 +144,6 @@ static struct snd_soc_dai_link dais[] = {
                                                | SND_SOC_DAIFMT_CBS_CFS,
                .be_hw_params_fixup = codec_fixup,
                .ignore_suspend = 1,
-               .nonatomic = true,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                SND_SOC_DAILINK_REG(ssp2_port, dummy, platform),
index df2f5d5..240cb43 100644 (file)
@@ -1180,7 +1180,6 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
                                                | SND_SOC_DAIFMT_CBS_CFS,
                .be_hw_params_fixup = byt_rt5640_codec_fixup,
-               .nonatomic = true,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                .init = byt_rt5640_init,
index 148b7b1..e13c0c6 100644 (file)
@@ -786,7 +786,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
                                                | SND_SOC_DAIFMT_CBS_CFS,
                .be_hw_params_fixup = byt_rt5651_codec_fixup,
-               .nonatomic = true,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                .init = byt_rt5651_init,
index 8d8ab9b..580d5fd 100644 (file)
@@ -351,7 +351,6 @@ static struct snd_soc_dai_link byt_wm5102_dais[] = {
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
                                                | SND_SOC_DAIFMT_CBS_CFS,
                .be_hw_params_fixup = byt_wm5102_codec_fixup,
-               .nonatomic = true,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                .init = byt_wm5102_init,
index 6fea554..804dbc7 100644 (file)
@@ -471,7 +471,6 @@ static struct snd_soc_dai_link cht_dailink[] = {
                .no_pcm = 1,
                .init = cht_codec_init,
                .be_hw_params_fixup = cht_codec_fixup,
-               .nonatomic = true,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                .ops = &cht_be_ssp2_ops,
index e358632..9509b6e 100644 (file)
@@ -375,7 +375,6 @@ static struct snd_soc_dai_link cht_dailink[] = {
                .name = "SSP2-Codec",
                .id = 0,
                .no_pcm = 1,
-               .nonatomic = true,
                .init = cht_codec_init,
                .be_hw_params_fixup = cht_codec_fixup,
                .dpcm_playback = 1,
index 14813be..27615ac 100644 (file)
@@ -594,3 +594,4 @@ MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:cml_rt1011_rt5682");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
index 7c0d4e9..00773d1 100644 (file)
@@ -181,7 +181,6 @@ static struct snd_soc_dai_link ehl_rt5660_dailink[] = {
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                .ops = &rt5660_ops,
-               .nonatomic = true,
                SND_SOC_DAILINK_REG(ssp0_pin, rt5660_codec, platform),
        },
        {
@@ -321,3 +320,4 @@ MODULE_DESCRIPTION("ASoC Intel(R) Elkhartlake + rt5660 Machine driver");
 MODULE_AUTHOR("libin.yang@intel.com");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:ehl_rt5660");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
index 62cca51..19e2ff9 100644 (file)
@@ -642,3 +642,4 @@ MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
 MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:glk_rt5682_max98357a");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
index 91ad2a0..efdc4bc 100644 (file)
@@ -2,6 +2,7 @@
 //
 // Copyright(c) 2019 Intel Corporation. All rights reserved.
 
+#include <linux/module.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <sound/hda_codec.h>
@@ -82,5 +83,9 @@ int hda_dsp_hdmi_build_controls(struct snd_soc_card *card,
 
        return err;
 }
+EXPORT_SYMBOL_NS(hda_dsp_hdmi_build_controls, SND_SOC_INTEL_HDA_DSP_COMMON);
 
 #endif
+
+MODULE_DESCRIPTION("ASoC Intel HDMI helpers");
+MODULE_LICENSE("GPL");
index bc50eda..f4b4eec 100644 (file)
@@ -258,3 +258,4 @@ MODULE_DESCRIPTION("SKL/KBL/BXT/APL HDA Generic Machine driver");
 MODULE_AUTHOR("Rakesh Ughreja <rakesh.a.ughreja@intel.com>");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:skl_hda_dsp_generic");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c
new file mode 100644 (file)
index 0000000..1b46ff4
--- /dev/null
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2021 Intel Corporation.
+
+/*
+ * Intel SOF Machine Driver with Cirrus Logic CS42L42 Codec
+ * and speaker codec MAX98357A
+ */
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/dmi.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+#include <dt-bindings/sound/cs42l42.h>
+#include "../../codecs/hdac_hdmi.h"
+#include "../common/soc-intel-quirks.h"
+#include "hda_dsp_common.h"
+#include "sof_maxim_common.h"
+
+#define NAME_SIZE 32
+
+#define SOF_CS42L42_SSP_CODEC(quirk)           ((quirk) & GENMASK(2, 0))
+#define SOF_CS42L42_SSP_CODEC_MASK             (GENMASK(2, 0))
+#define SOF_SPEAKER_AMP_PRESENT                        BIT(3)
+#define SOF_CS42L42_SSP_AMP_SHIFT              4
+#define SOF_CS42L42_SSP_AMP_MASK               (GENMASK(6, 4))
+#define SOF_CS42L42_SSP_AMP(quirk)     \
+       (((quirk) << SOF_CS42L42_SSP_AMP_SHIFT) & SOF_CS42L42_SSP_AMP_MASK)
+#define SOF_CS42L42_NUM_HDMIDEV_SHIFT          7
+#define SOF_CS42L42_NUM_HDMIDEV_MASK           (GENMASK(9, 7))
+#define SOF_CS42L42_NUM_HDMIDEV(quirk) \
+       (((quirk) << SOF_CS42L42_NUM_HDMIDEV_SHIFT) & SOF_CS42L42_NUM_HDMIDEV_MASK)
+#define SOF_MAX98357A_SPEAKER_AMP_PRESENT      BIT(10)
+
+/* Default: SSP2 */
+static unsigned long sof_cs42l42_quirk = SOF_CS42L42_SSP_CODEC(2);
+
+struct sof_hdmi_pcm {
+       struct list_head head;
+       struct snd_soc_dai *codec_dai;
+       struct snd_soc_jack hdmi_jack;
+       int device;
+};
+
+struct sof_card_private {
+       struct snd_soc_jack headset_jack;
+       struct list_head hdmi_pcm_list;
+       bool common_hdmi_codec_drv;
+};
+
+static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+       struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
+       struct sof_hdmi_pcm *pcm;
+
+       pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
+       if (!pcm)
+               return -ENOMEM;
+
+       /* dai_link id is 1:1 mapped to the PCM device */
+       pcm->device = rtd->dai_link->id;
+       pcm->codec_dai = dai;
+
+       list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
+
+       return 0;
+}
+
+static int sof_cs42l42_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+       struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+       struct snd_soc_jack *jack = &ctx->headset_jack;
+       int ret;
+
+       /*
+        * Headset buttons map to the google Reference headset.
+        * These can be configured by userspace.
+        */
+       ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
+                                   SND_JACK_HEADSET | SND_JACK_BTN_0 |
+                                   SND_JACK_BTN_1 | SND_JACK_BTN_2 |
+                                   SND_JACK_BTN_3,
+                                   jack, NULL, 0);
+       if (ret) {
+               dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
+               return ret;
+       }
+
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
+
+       ret = snd_soc_component_set_jack(component, jack, NULL);
+       if (ret) {
+               dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
+               return ret;
+       }
+
+       return ret;
+};
+
+static void sof_cs42l42_exit(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+
+       snd_soc_component_set_jack(component, NULL, NULL);
+}
+
+static int sof_cs42l42_hw_params(struct snd_pcm_substream *substream,
+                                struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+       struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+       int clk_freq, ret;
+
+       clk_freq = 3072000; /* BCLK freq */
+
+       /* Configure sysclk for codec */
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+                                    clk_freq, SND_SOC_CLOCK_IN);
+       if (ret < 0)
+               dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
+
+       return ret;
+}
+
+static const struct snd_soc_ops sof_cs42l42_ops = {
+       .hw_params = sof_cs42l42_hw_params,
+};
+
+static struct snd_soc_dai_link_component platform_component[] = {
+       {
+               /* name might be overridden during probe */
+               .name = "0000:00:1f.3"
+       }
+};
+
+static int sof_card_late_probe(struct snd_soc_card *card)
+{
+       struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
+       struct snd_soc_component *component = NULL;
+       char jack_name[NAME_SIZE];
+       struct sof_hdmi_pcm *pcm;
+       int err;
+
+       if (list_empty(&ctx->hdmi_pcm_list))
+               return -EINVAL;
+
+       if (ctx->common_hdmi_codec_drv) {
+               pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
+                                      head);
+               component = pcm->codec_dai->component;
+               return hda_dsp_hdmi_build_controls(card, component);
+       }
+
+       list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
+               component = pcm->codec_dai->component;
+               snprintf(jack_name, sizeof(jack_name),
+                        "HDMI/DP, pcm=%d Jack", pcm->device);
+               err = snd_soc_card_jack_new(card, jack_name,
+                                           SND_JACK_AVOUT, &pcm->hdmi_jack,
+                                           NULL, 0);
+
+               if (err)
+                       return err;
+
+               err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
+                                         &pcm->hdmi_jack);
+               if (err < 0)
+                       return err;
+       }
+
+       return hdac_hdmi_jack_port_init(component, &card->dapm);
+}
+
+static const struct snd_kcontrol_new sof_controls[] = {
+       SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+       SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static const struct snd_soc_dapm_widget sof_widgets[] = {
+       SND_SOC_DAPM_HP("Headphone Jack", NULL),
+       SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_soc_dapm_widget dmic_widgets[] = {
+       SND_SOC_DAPM_MIC("SoC DMIC", NULL),
+};
+
+static const struct snd_soc_dapm_route sof_map[] = {
+       /* HP jack connectors - unknown if we have jack detection */
+       {"Headphone Jack", NULL, "HP"},
+
+       /* other jacks */
+       {"HS", NULL, "Headset Mic"},
+};
+
+static const struct snd_soc_dapm_route dmic_map[] = {
+       /* digital mics */
+       {"DMic", NULL, "SoC DMIC"},
+};
+
+static int dmic_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_card *card = rtd->card;
+       int ret;
+
+       ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
+                                       ARRAY_SIZE(dmic_widgets));
+       if (ret) {
+               dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
+               /* Don't need to add routes if widget addition failed */
+               return ret;
+       }
+
+       ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
+                                     ARRAY_SIZE(dmic_map));
+
+       if (ret)
+               dev_err(card->dev, "DMic map addition failed: %d\n", ret);
+
+       return ret;
+}
+
+/* sof audio machine driver for cs42l42 codec */
+static struct snd_soc_card sof_audio_card_cs42l42 = {
+       .name = "cs42l42", /* the sof- prefix is added by the core */
+       .owner = THIS_MODULE,
+       .controls = sof_controls,
+       .num_controls = ARRAY_SIZE(sof_controls),
+       .dapm_widgets = sof_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(sof_widgets),
+       .dapm_routes = sof_map,
+       .num_dapm_routes = ARRAY_SIZE(sof_map),
+       .fully_routed = true,
+       .late_probe = sof_card_late_probe,
+};
+
+static struct snd_soc_dai_link_component cs42l42_component[] = {
+       {
+               .name = "i2c-10134242:00",
+               .dai_name = "cs42l42",
+       }
+};
+
+static struct snd_soc_dai_link_component dmic_component[] = {
+       {
+               .name = "dmic-codec",
+               .dai_name = "dmic-hifi",
+       }
+};
+
+static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
+                                                         int ssp_codec,
+                                                         int ssp_amp,
+                                                         int dmic_be_num,
+                                                         int hdmi_num)
+{
+       struct snd_soc_dai_link_component *idisp_components;
+       struct snd_soc_dai_link_component *cpus;
+       struct snd_soc_dai_link *links;
+       int i, id = 0;
+
+       links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
+                            sof_audio_card_cs42l42.num_links, GFP_KERNEL);
+       cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) *
+                            sof_audio_card_cs42l42.num_links, GFP_KERNEL);
+       if (!links || !cpus)
+               goto devm_err;
+
+       /* speaker amp */
+       if (sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT) {
+               links[id].name = devm_kasprintf(dev, GFP_KERNEL,
+                                               "SSP%d-Codec", ssp_amp);
+               if (!links[id].name)
+                       goto devm_err;
+
+               links[id].id = id;
+
+               if (sof_cs42l42_quirk & SOF_MAX98357A_SPEAKER_AMP_PRESENT) {
+                       max_98357a_dai_link(&links[id]);
+               } else {
+                       dev_err(dev, "no amp defined\n");
+                       goto devm_err;
+               }
+
+               links[id].platforms = platform_component;
+               links[id].num_platforms = ARRAY_SIZE(platform_component);
+               links[id].dpcm_playback = 1;
+               links[id].no_pcm = 1;
+               links[id].cpus = &cpus[id];
+               links[id].num_cpus = 1;
+
+               links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+                                                         "SSP%d Pin",
+                                                         ssp_amp);
+               if (!links[id].cpus->dai_name)
+                       goto devm_err;
+
+               id++;
+       }
+
+       /* codec SSP */
+       links[id].name = devm_kasprintf(dev, GFP_KERNEL,
+                                       "SSP%d-Codec", ssp_codec);
+       if (!links[id].name)
+               goto devm_err;
+
+       links[id].id = id;
+       links[id].codecs = cs42l42_component;
+       links[id].num_codecs = ARRAY_SIZE(cs42l42_component);
+       links[id].platforms = platform_component;
+       links[id].num_platforms = ARRAY_SIZE(platform_component);
+       links[id].init = sof_cs42l42_init;
+       links[id].exit = sof_cs42l42_exit;
+       links[id].ops = &sof_cs42l42_ops;
+       links[id].dpcm_playback = 1;
+       links[id].dpcm_capture = 1;
+       links[id].no_pcm = 1;
+       links[id].cpus = &cpus[id];
+       links[id].num_cpus = 1;
+
+       links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+                                                 "SSP%d Pin",
+                                                 ssp_codec);
+       if (!links[id].cpus->dai_name)
+               goto devm_err;
+
+       id++;
+
+       /* dmic */
+       if (dmic_be_num > 0) {
+               /* at least we have dmic01 */
+               links[id].name = "dmic01";
+               links[id].cpus = &cpus[id];
+               links[id].cpus->dai_name = "DMIC01 Pin";
+               links[id].init = dmic_init;
+               if (dmic_be_num > 1) {
+                       /* set up 2 BE links at most */
+                       links[id + 1].name = "dmic16k";
+                       links[id + 1].cpus = &cpus[id + 1];
+                       links[id + 1].cpus->dai_name = "DMIC16k Pin";
+                       dmic_be_num = 2;
+               }
+       }
+
+       for (i = 0; i < dmic_be_num; i++) {
+               links[id].id = id;
+               links[id].num_cpus = 1;
+               links[id].codecs = dmic_component;
+               links[id].num_codecs = ARRAY_SIZE(dmic_component);
+               links[id].platforms = platform_component;
+               links[id].num_platforms = ARRAY_SIZE(platform_component);
+               links[id].ignore_suspend = 1;
+               links[id].dpcm_capture = 1;
+               links[id].no_pcm = 1;
+               id++;
+       }
+
+       /* HDMI */
+       if (hdmi_num > 0) {
+               idisp_components = devm_kzalloc(dev,
+                                               sizeof(struct snd_soc_dai_link_component) *
+                                               hdmi_num, GFP_KERNEL);
+               if (!idisp_components)
+                       goto devm_err;
+       }
+       for (i = 1; i <= hdmi_num; i++) {
+               links[id].name = devm_kasprintf(dev, GFP_KERNEL,
+                                               "iDisp%d", i);
+               if (!links[id].name)
+                       goto devm_err;
+
+               links[id].id = id;
+               links[id].cpus = &cpus[id];
+               links[id].num_cpus = 1;
+               links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+                                                         "iDisp%d Pin", i);
+               if (!links[id].cpus->dai_name)
+                       goto devm_err;
+
+               idisp_components[i - 1].name = "ehdaudio0D2";
+               idisp_components[i - 1].dai_name = devm_kasprintf(dev,
+                                                                 GFP_KERNEL,
+                                                                 "intel-hdmi-hifi%d",
+                                                                 i);
+               if (!idisp_components[i - 1].dai_name)
+                       goto devm_err;
+
+               links[id].codecs = &idisp_components[i - 1];
+               links[id].num_codecs = 1;
+               links[id].platforms = platform_component;
+               links[id].num_platforms = ARRAY_SIZE(platform_component);
+               links[id].init = sof_hdmi_init;
+               links[id].dpcm_playback = 1;
+               links[id].no_pcm = 1;
+               id++;
+       }
+
+       return links;
+devm_err:
+       return NULL;
+}
+
+static int sof_audio_probe(struct platform_device *pdev)
+{
+       struct snd_soc_dai_link *dai_links;
+       struct snd_soc_acpi_mach *mach;
+       struct sof_card_private *ctx;
+       int dmic_be_num, hdmi_num;
+       int ret, ssp_amp, ssp_codec;
+
+       ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+
+       if (pdev->id_entry && pdev->id_entry->driver_data)
+               sof_cs42l42_quirk = (unsigned long)pdev->id_entry->driver_data;
+
+       mach = pdev->dev.platform_data;
+
+       if (soc_intel_is_glk()) {
+               dmic_be_num = 1;
+               hdmi_num = 3;
+       } else {
+               dmic_be_num = 2;
+               hdmi_num = (sof_cs42l42_quirk & SOF_CS42L42_NUM_HDMIDEV_MASK) >>
+                        SOF_CS42L42_NUM_HDMIDEV_SHIFT;
+               /* default number of HDMI DAI's */
+               if (!hdmi_num)
+                       hdmi_num = 3;
+       }
+
+       dev_dbg(&pdev->dev, "sof_cs42l42_quirk = %lx\n", sof_cs42l42_quirk);
+
+       ssp_amp = (sof_cs42l42_quirk & SOF_CS42L42_SSP_AMP_MASK) >>
+                       SOF_CS42L42_SSP_AMP_SHIFT;
+
+       ssp_codec = sof_cs42l42_quirk & SOF_CS42L42_SSP_CODEC_MASK;
+
+       /* compute number of dai links */
+       sof_audio_card_cs42l42.num_links = 1 + dmic_be_num + hdmi_num;
+
+       if (sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT)
+               sof_audio_card_cs42l42.num_links++;
+
+       dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
+                                             dmic_be_num, hdmi_num);
+       if (!dai_links)
+               return -ENOMEM;
+
+       sof_audio_card_cs42l42.dai_link = dai_links;
+
+       INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
+
+       sof_audio_card_cs42l42.dev = &pdev->dev;
+
+       /* set platform name for each dailink */
+       ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_cs42l42,
+                                                   mach->mach_params.platform);
+       if (ret)
+               return ret;
+
+       ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
+
+       snd_soc_card_set_drvdata(&sof_audio_card_cs42l42, ctx);
+
+       return devm_snd_soc_register_card(&pdev->dev,
+                                         &sof_audio_card_cs42l42);
+}
+
+static const struct platform_device_id board_ids[] = {
+       {
+               .name = "glk_cs4242_max98357a",
+               .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(2) |
+                                       SOF_SPEAKER_AMP_PRESENT |
+                                       SOF_MAX98357A_SPEAKER_AMP_PRESENT |
+                                       SOF_CS42L42_SSP_AMP(1)),
+       },
+       { }
+};
+
+static struct platform_driver sof_audio = {
+       .probe = sof_audio_probe,
+       .driver = {
+               .name = "sof_cs42l42",
+               .pm = &snd_soc_pm_ops,
+       },
+       .id_table = board_ids,
+};
+module_platform_driver(sof_audio)
+
+/* Module information */
+MODULE_DESCRIPTION("SOF Audio Machine driver for CS42L42");
+MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sof_cs42l42");
+MODULE_ALIAS("platform:glk_cs4242_max98357a");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
+MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
index f3cb077..0604d25 100644 (file)
@@ -457,3 +457,4 @@ MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:sof_da7219_max98360a");
 MODULE_ALIAS("platform:sof_da7219_max98373");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
index 437d205..e9c52f8 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 //
 // Copyright(c) 2020 Intel Corporation. All rights reserved.
+#include <linux/module.h>
 #include <linux/string.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
@@ -16,6 +17,7 @@ const struct snd_soc_dapm_route max_98373_dapm_routes[] = {
        { "Left Spk", NULL, "Left BE_OUT" },
        { "Right Spk", NULL, "Right BE_OUT" },
 };
+EXPORT_SYMBOL_NS(max_98373_dapm_routes, SND_SOC_INTEL_SOF_MAXIM_COMMON);
 
 static struct snd_soc_codec_conf max_98373_codec_conf[] = {
        {
@@ -38,9 +40,10 @@ struct snd_soc_dai_link_component max_98373_components[] = {
                .dai_name = MAX_98373_CODEC_DAI,
        },
 };
+EXPORT_SYMBOL_NS(max_98373_components, SND_SOC_INTEL_SOF_MAXIM_COMMON);
 
-static int max98373_hw_params(struct snd_pcm_substream *substream,
-                             struct snd_pcm_hw_params *params)
+static int max_98373_hw_params(struct snd_pcm_substream *substream,
+                              struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
        struct snd_soc_dai *codec_dai;
@@ -59,7 +62,7 @@ static int max98373_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-int max98373_trigger(struct snd_pcm_substream *substream, int cmd)
+int max_98373_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
        struct snd_soc_dai *codec_dai;
@@ -102,13 +105,15 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd)
 
        return ret;
 }
+EXPORT_SYMBOL_NS(max_98373_trigger, SND_SOC_INTEL_SOF_MAXIM_COMMON);
 
 struct snd_soc_ops max_98373_ops = {
-       .hw_params = max98373_hw_params,
-       .trigger = max98373_trigger,
+       .hw_params = max_98373_hw_params,
+       .trigger = max_98373_trigger,
 };
+EXPORT_SYMBOL_NS(max_98373_ops, SND_SOC_INTEL_SOF_MAXIM_COMMON);
 
-int max98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd)
+int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_card *card = rtd->card;
        int ret;
@@ -119,9 +124,74 @@ int max98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd)
                dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
        return ret;
 }
+EXPORT_SYMBOL_NS(max_98373_spk_codec_init, SND_SOC_INTEL_SOF_MAXIM_COMMON);
 
-void sof_max98373_codec_conf(struct snd_soc_card *card)
+void max_98373_set_codec_conf(struct snd_soc_card *card)
 {
        card->codec_conf = max_98373_codec_conf;
        card->num_configs = ARRAY_SIZE(max_98373_codec_conf);
 }
+EXPORT_SYMBOL_NS(max_98373_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON);
+
+/*
+ * Maxim MAX98357A
+ */
+static const struct snd_kcontrol_new max_98357a_kcontrols[] = {
+       SOC_DAPM_PIN_SWITCH("Spk"),
+};
+
+static const struct snd_soc_dapm_widget max_98357a_dapm_widgets[] = {
+       SND_SOC_DAPM_SPK("Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route max_98357a_dapm_routes[] = {
+       /* speaker */
+       {"Spk", NULL, "Speaker"},
+};
+
+static struct snd_soc_dai_link_component max_98357a_components[] = {
+       {
+               .name = MAX_98357A_DEV0_NAME,
+               .dai_name = MAX_98357A_CODEC_DAI,
+       }
+};
+
+static int max_98357a_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_card *card = rtd->card;
+       int ret;
+
+       ret = snd_soc_dapm_new_controls(&card->dapm, max_98357a_dapm_widgets,
+                                       ARRAY_SIZE(max_98357a_dapm_widgets));
+       if (ret) {
+               dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret);
+               /* Don't need to add routes if widget addition failed */
+               return ret;
+       }
+
+       ret = snd_soc_add_card_controls(card, max_98357a_kcontrols,
+                                       ARRAY_SIZE(max_98357a_kcontrols));
+       if (ret) {
+               dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_dapm_add_routes(&card->dapm, max_98357a_dapm_routes,
+                                     ARRAY_SIZE(max_98357a_dapm_routes));
+
+       if (ret)
+               dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret);
+
+       return ret;
+}
+
+void max_98357a_dai_link(struct snd_soc_dai_link *link)
+{
+       link->codecs = max_98357a_components;
+       link->num_codecs = ARRAY_SIZE(max_98357a_components);
+       link->init = max_98357a_init;
+}
+EXPORT_SYMBOL_NS(max_98357a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON);
+
+MODULE_DESCRIPTION("ASoC Intel SOF Maxim helpers");
+MODULE_LICENSE("GPL");
index 5240b1c..2674f1e 100644 (file)
@@ -20,8 +20,16 @@ extern struct snd_soc_dai_link_component max_98373_components[2];
 extern struct snd_soc_ops max_98373_ops;
 extern const struct snd_soc_dapm_route max_98373_dapm_routes[];
 
-int max98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd);
-void sof_max98373_codec_conf(struct snd_soc_card *card);
-int max98373_trigger(struct snd_pcm_substream *substream, int cmd);
+int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd);
+void max_98373_set_codec_conf(struct snd_soc_card *card);
+int max_98373_trigger(struct snd_pcm_substream *substream, int cmd);
+
+/*
+ * Maxim MAX98357A
+ */
+#define MAX_98357A_CODEC_DAI   "HiFi"
+#define MAX_98357A_DEV0_NAME   "MX98357A:00"
+
+void max_98357a_dai_link(struct snd_soc_dai_link *link);
 
 #endif /* __SOF_MAXIM_COMMON_H */
index d2b0456..2ec9c62 100644 (file)
@@ -241,7 +241,6 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
        links[id].num_platforms = ARRAY_SIZE(platform_component);
        links[id].init = sof_pcm512x_codec_init;
        links[id].ops = &sof_pcm512x_ops;
-       links[id].nonatomic = true;
        links[id].dpcm_playback = 1;
        /*
         * capture only supported with specific versions of the Hifiberry DAC+
@@ -437,3 +436,4 @@ MODULE_DESCRIPTION("ASoC Intel(R) SOF + PCM512x Machine driver");
 MODULE_AUTHOR("Pierre-Louis Bossart");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:sof_pcm512x");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
index 58548ea..f3d3705 100644 (file)
 #define SOF_MAX98373_SPEAKER_AMP_PRESENT       BIT(17)
 #define SOF_MAX98360A_SPEAKER_AMP_PRESENT      BIT(18)
 
+/* BT audio offload: reserve 3 bits for future */
+#define SOF_BT_OFFLOAD_SSP_SHIFT               19
+#define SOF_BT_OFFLOAD_SSP_MASK                (GENMASK(21, 19))
+#define SOF_BT_OFFLOAD_SSP(quirk)      \
+       (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
+#define SOF_SSP_BT_OFFLOAD_PRESENT             BIT(22)
+
 /* Default: MCLK on, MCLK 19.2M, SSP0  */
 static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
                                        SOF_RT5682_SSP_CODEC(0);
@@ -444,20 +451,26 @@ static int sof_card_late_probe(struct snd_soc_card *card)
 static const struct snd_kcontrol_new sof_controls[] = {
        SOC_DAPM_PIN_SWITCH("Headphone Jack"),
        SOC_DAPM_PIN_SWITCH("Headset Mic"),
-       SOC_DAPM_PIN_SWITCH("Spk"),
        SOC_DAPM_PIN_SWITCH("Left Spk"),
        SOC_DAPM_PIN_SWITCH("Right Spk"),
 
 };
 
+static const struct snd_kcontrol_new speaker_controls[] = {
+       SOC_DAPM_PIN_SWITCH("Spk"),
+};
+
 static const struct snd_soc_dapm_widget sof_widgets[] = {
        SND_SOC_DAPM_HP("Headphone Jack", NULL),
        SND_SOC_DAPM_MIC("Headset Mic", NULL),
-       SND_SOC_DAPM_SPK("Spk", NULL),
        SND_SOC_DAPM_SPK("Left Spk", NULL),
        SND_SOC_DAPM_SPK("Right Spk", NULL),
 };
 
+static const struct snd_soc_dapm_widget speaker_widgets[] = {
+       SND_SOC_DAPM_SPK("Spk", NULL),
+};
+
 static const struct snd_soc_dapm_widget dmic_widgets[] = {
        SND_SOC_DAPM_MIC("SoC DMIC", NULL),
 };
@@ -497,6 +510,21 @@ static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd)
        struct snd_soc_card *card = rtd->card;
        int ret;
 
+       ret = snd_soc_dapm_new_controls(&card->dapm, speaker_widgets,
+                                       ARRAY_SIZE(speaker_widgets));
+       if (ret) {
+               dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret);
+               /* Don't need to add routes if widget addition failed */
+               return ret;
+       }
+
+       ret = snd_soc_add_card_controls(card, speaker_controls,
+                                       ARRAY_SIZE(speaker_controls));
+       if (ret) {
+               dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
+               return ret;
+       }
+
        ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map,
                                      ARRAY_SIZE(speaker_map));
 
@@ -566,13 +594,6 @@ static struct snd_soc_dai_link_component dmic_component[] = {
        }
 };
 
-static struct snd_soc_dai_link_component max98357a_component[] = {
-       {
-               .name = "MX98357A:00",
-               .dai_name = "HiFi",
-       }
-};
-
 static struct snd_soc_dai_link_component max98360a_component[] = {
        {
                .name = "MX98360A:00",
@@ -591,6 +612,13 @@ static struct snd_soc_dai_link_component rt1015_components[] = {
        },
 };
 
+static struct snd_soc_dai_link_component dummy_component[] = {
+       {
+               .name = "snd-soc-dummy",
+               .dai_name = "snd-soc-dummy-dai",
+       }
+};
+
 static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
                                                          int ssp_codec,
                                                          int ssp_amp,
@@ -623,7 +651,6 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
        links[id].init = sof_rt5682_codec_init;
        links[id].exit = sof_rt5682_codec_exit;
        links[id].ops = &sof_rt5682_ops;
-       links[id].nonatomic = true;
        links[id].dpcm_playback = 1;
        links[id].dpcm_capture = 1;
        links[id].no_pcm = 1;
@@ -742,7 +769,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
                                SOF_MAX98373_SPEAKER_AMP_PRESENT) {
                        links[id].codecs = max_98373_components;
                        links[id].num_codecs = ARRAY_SIZE(max_98373_components);
-                       links[id].init = max98373_spk_codec_init;
+                       links[id].init = max_98373_spk_codec_init;
                        links[id].ops = &max_98373_ops;
                        /* feedback stream */
                        links[id].dpcm_capture = 1;
@@ -755,13 +782,10 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
                                SOF_RT1011_SPEAKER_AMP_PRESENT) {
                        sof_rt1011_dai_link(&links[id]);
                } else {
-                       links[id].codecs = max98357a_component;
-                       links[id].num_codecs = ARRAY_SIZE(max98357a_component);
-                       links[id].init = speaker_codec_init;
+                       max_98357a_dai_link(&links[id]);
                }
                links[id].platforms = platform_component;
                links[id].num_platforms = ARRAY_SIZE(platform_component);
-               links[id].nonatomic = true;
                links[id].dpcm_playback = 1;
                links[id].no_pcm = 1;
                links[id].cpus = &cpus[id];
@@ -780,6 +804,31 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
                        if (!links[id].cpus->dai_name)
                                goto devm_err;
                }
+               id++;
+       }
+
+       /* BT audio offload */
+       if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
+               int port = (sof_rt5682_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
+                               SOF_BT_OFFLOAD_SSP_SHIFT;
+
+               links[id].id = id;
+               links[id].cpus = &cpus[id];
+               links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+                                                         "SSP%d Pin", port);
+               if (!links[id].cpus->dai_name)
+                       goto devm_err;
+               links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
+               if (!links[id].name)
+                       goto devm_err;
+               links[id].codecs = dummy_component;
+               links[id].num_codecs = ARRAY_SIZE(dummy_component);
+               links[id].platforms = platform_component;
+               links[id].num_platforms = ARRAY_SIZE(platform_component);
+               links[id].dpcm_playback = 1;
+               links[id].dpcm_capture = 1;
+               links[id].no_pcm = 1;
+               links[id].num_cpus = 1;
        }
 
        return links;
@@ -863,12 +912,15 @@ static int sof_audio_probe(struct platform_device *pdev)
                sof_audio_card_rt5682.num_links++;
 
        if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT)
-               sof_max98373_codec_conf(&sof_audio_card_rt5682);
+               max_98373_set_codec_conf(&sof_audio_card_rt5682);
        else if (sof_rt5682_quirk & SOF_RT1011_SPEAKER_AMP_PRESENT)
                sof_rt1011_codec_conf(&sof_audio_card_rt5682);
        else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT)
                sof_rt1015p_codec_conf(&sof_audio_card_rt5682);
 
+       if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
+               sof_audio_card_rt5682.num_links++;
+
        dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
                                              dmic_be_num, hdmi_num);
        if (!dai_links)
@@ -909,7 +961,9 @@ static const struct platform_device_id board_ids[] = {
                                        SOF_RT5682_SSP_CODEC(0) |
                                        SOF_SPEAKER_AMP_PRESENT |
                                        SOF_RT5682_SSP_AMP(1) |
-                                       SOF_RT5682_NUM_HDMIDEV(4)),
+                                       SOF_RT5682_NUM_HDMIDEV(4) |
+                                       SOF_BT_OFFLOAD_SSP(2) |
+                                       SOF_SSP_BT_OFFLOAD_PRESENT),
        },
        {
                .name = "jsl_rt5682_rt1015",
@@ -927,7 +981,9 @@ static const struct platform_device_id board_ids[] = {
                                        SOF_SPEAKER_AMP_PRESENT |
                                        SOF_MAX98373_SPEAKER_AMP_PRESENT |
                                        SOF_RT5682_SSP_AMP(1) |
-                                       SOF_RT5682_NUM_HDMIDEV(4)),
+                                       SOF_RT5682_NUM_HDMIDEV(4) |
+                                       SOF_BT_OFFLOAD_SSP(2) |
+                                       SOF_SSP_BT_OFFLOAD_PRESENT),
        },
        {
                .name = "jsl_rt5682_max98360a",
@@ -955,7 +1011,9 @@ static const struct platform_device_id board_ids[] = {
                                        SOF_SPEAKER_AMP_PRESENT |
                                        SOF_RT1011_SPEAKER_AMP_PRESENT |
                                        SOF_RT5682_SSP_AMP(1) |
-                                       SOF_RT5682_NUM_HDMIDEV(4)),
+                                       SOF_RT5682_NUM_HDMIDEV(4) |
+                                       SOF_BT_OFFLOAD_SSP(2) |
+                                       SOF_SSP_BT_OFFLOAD_PRESENT),
        },
        {
                .name = "jsl_rt5682_rt1015p",
@@ -966,6 +1024,25 @@ static const struct platform_device_id board_ids[] = {
                                        SOF_RT1015P_SPEAKER_AMP_PRESENT |
                                        SOF_RT5682_SSP_AMP(1)),
        },
+       {
+               .name = "adl_max98373_rt5682",
+               .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
+                                       SOF_RT5682_SSP_CODEC(0) |
+                                       SOF_SPEAKER_AMP_PRESENT |
+                                       SOF_MAX98373_SPEAKER_AMP_PRESENT |
+                                       SOF_RT5682_SSP_AMP(1) |
+                                       SOF_RT5682_NUM_HDMIDEV(4) |
+                                       SOF_BT_OFFLOAD_SSP(2) |
+                                       SOF_SSP_BT_OFFLOAD_PRESENT),
+       },
+       {
+               .name = "adl_max98357a_rt5682",
+               .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
+                                       SOF_RT5682_SSP_CODEC(0) |
+                                       SOF_SPEAKER_AMP_PRESENT |
+                                       SOF_RT5682_SSP_AMP(2) |
+                                       SOF_RT5682_NUM_HDMIDEV(4)),
+       },
        { }
 };
 
@@ -993,3 +1070,7 @@ MODULE_ALIAS("platform:jsl_rt5682_max98360a");
 MODULE_ALIAS("platform:cml_rt1015_rt5682");
 MODULE_ALIAS("platform:tgl_rt1011_rt5682");
 MODULE_ALIAS("platform:jsl_rt5682_rt1015p");
+MODULE_ALIAS("platform:adl_max98373_rt5682");
+MODULE_ALIAS("platform:adl_max98357a_rt5682");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
+MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
index ecd3f90..0f1ad9e 100644 (file)
@@ -147,7 +147,9 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
                },
                .driver_data = (void *)(SOF_SDW_TGL_HDMI |
                                        SOF_SDW_PCH_DMIC |
-                                       SOF_SDW_FOUR_SPK),
+                                       SOF_SDW_FOUR_SPK |
+                                       SOF_BT_OFFLOAD_SSP(2) |
+                                       SOF_SSP_BT_OFFLOAD_PRESENT),
        },
        {
                .callback = sof_sdw_quirk_cb,
@@ -196,6 +198,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
                },
                .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 |
                                        SOF_SDW_TGL_HDMI |
+                                       SOF_RT715_DAI_ID_FIX |
                                        SOF_SDW_PCH_DMIC),
        },
        {}
@@ -353,6 +356,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
                .part_id = 0x714,
                .version_id = 3,
                .direction = {false, true},
+               .ignore_pch_dmic = true,
                .dai_name = "rt715-aif2",
                .init = sof_sdw_rt715_sdca_init,
        },
@@ -360,6 +364,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
                .part_id = 0x715,
                .version_id = 3,
                .direction = {false, true},
+               .ignore_pch_dmic = true,
                .dai_name = "rt715-aif2",
                .init = sof_sdw_rt715_sdca_init,
        },
@@ -367,6 +372,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
                .part_id = 0x714,
                .version_id = 2,
                .direction = {false, true},
+               .ignore_pch_dmic = true,
                .dai_name = "rt715-aif2",
                .init = sof_sdw_rt715_init,
        },
@@ -374,6 +380,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
                .part_id = 0x715,
                .version_id = 2,
                .direction = {false, true},
+               .ignore_pch_dmic = true,
                .dai_name = "rt715-aif2",
                .init = sof_sdw_rt715_init,
        },
@@ -499,7 +506,6 @@ static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links
        dai_links->name = name;
        dai_links->platforms = platform_component;
        dai_links->num_platforms = ARRAY_SIZE(platform_component);
-       dai_links->nonatomic = true;
        dai_links->no_pcm = 1;
        dai_links->cpus = cpus;
        dai_links->num_cpus = cpus_num;
@@ -729,7 +735,8 @@ static int create_sdw_dailink(struct device *dev, int *be_index,
                              int *cpu_id, bool *group_generated,
                              struct snd_soc_codec_conf *codec_conf,
                              int codec_count,
-                             int *codec_conf_index)
+                             int *codec_conf_index,
+                             bool *ignore_pch_dmic)
 {
        const struct snd_soc_acpi_link_adr *link_next;
        struct snd_soc_dai_link_component *codecs;
@@ -782,6 +789,9 @@ static int create_sdw_dailink(struct device *dev, int *be_index,
        if (codec_index < 0)
                return codec_index;
 
+       if (codec_info_list[codec_index].ignore_pch_dmic)
+               *ignore_pch_dmic = true;
+
        cpu_dai_index = *cpu_id;
        for_each_pcm_streams(stream) {
                char *name, *cpu_name;
@@ -913,6 +923,7 @@ static int sof_card_dai_links_create(struct device *dev,
        const struct snd_soc_acpi_link_adr *adr_link;
        struct snd_soc_dai_link_component *cpus;
        struct snd_soc_codec_conf *codec_conf;
+       bool ignore_pch_dmic = false;
        int codec_conf_count;
        int codec_conf_index = 0;
        bool group_generated[SDW_MAX_GROUPS];
@@ -968,6 +979,9 @@ static int sof_card_dai_links_create(struct device *dev,
        dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) ? 2 : 0;
        comp_num += dmic_num;
 
+       if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
+               comp_num++;
+
        dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num,
                dmic_num, ctx->idisp_codec ? hdmi_num : 0);
 
@@ -1019,7 +1033,8 @@ static int sof_card_dai_links_create(struct device *dev,
                                         sdw_cpu_dai_num, cpus, adr_link,
                                         &cpu_id, group_generated,
                                         codec_conf, codec_conf_count,
-                                        &codec_conf_index);
+                                        &codec_conf_index,
+                                        &ignore_pch_dmic);
                if (ret < 0) {
                        dev_err(dev, "failed to create dai link %d", be_id);
                        return -ENOMEM;
@@ -1087,6 +1102,10 @@ SSP:
 DMIC:
        /* dmic */
        if (dmic_num > 0) {
+               if (ignore_pch_dmic) {
+                       dev_warn(dev, "Ignoring PCH DMIC\n");
+                       goto HDMI;
+               }
                cpus[cpu_id].dai_name = "DMIC01 Pin";
                init_dai_link(dev, links + link_id, be_id, "dmic01",
                              0, 1, // DMIC only supports capture
@@ -1105,6 +1124,7 @@ DMIC:
                INC_ID(be_id, cpu_id, link_id);
        }
 
+HDMI:
        /* HDMI */
        if (hdmi_num > 0) {
                idisp_components = devm_kcalloc(dev, hdmi_num,
@@ -1147,6 +1167,31 @@ DMIC:
                INC_ID(be_id, cpu_id, link_id);
        }
 
+       if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
+               int port = (sof_sdw_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
+                               SOF_BT_OFFLOAD_SSP_SHIFT;
+
+               name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
+               if (!name)
+                       return -ENOMEM;
+
+               ssp_components = devm_kzalloc(dev, sizeof(*ssp_components),
+                                               GFP_KERNEL);
+               if (!ssp_components)
+                       return -ENOMEM;
+
+               ssp_components->name = "snd-soc-dummy";
+               ssp_components->dai_name = "snd-soc-dummy-dai";
+
+               cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port);
+               if (!cpu_name)
+                       return -ENOMEM;
+
+               cpus[cpu_id].dai_name = cpu_name;
+               init_dai_link(dev, links + link_id, be_id, name, 1, 1,
+                               cpus + cpu_id, 1, ssp_components, 1, NULL, NULL);
+       }
+
        card->dai_link = links;
        card->num_links = num_links;
 
@@ -1302,3 +1347,5 @@ MODULE_AUTHOR("Rander Wang <rander.wang@linux.intel.com>");
 MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:sof_sdw");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
+MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
index f3cb679..37ae3a1 100644 (file)
@@ -50,12 +50,20 @@ enum {
 #define SOF_RT715_DAI_ID_FIX           BIT(11)
 #define SOF_SDW_NO_AGGREGATION         BIT(12)
 
+/* BT audio offload: reserve 3 bits for future */
+#define SOF_BT_OFFLOAD_SSP_SHIFT       13
+#define SOF_BT_OFFLOAD_SSP_MASK        (GENMASK(15, 13))
+#define SOF_BT_OFFLOAD_SSP(quirk)      \
+       (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
+#define SOF_SSP_BT_OFFLOAD_PRESENT     BIT(16)
+
 struct sof_sdw_codec_info {
        const int part_id;
        const int version_id;
        int amp_num;
        const u8 acpi_id[ACPI_ID_LEN];
        const bool direction[2]; // playback & capture support
+       const bool ignore_pch_dmic;
        const char *dai_name;
        const struct snd_soc_ops *ops;
 
index cfdf970..0e7ed90 100644 (file)
@@ -64,7 +64,7 @@ static int max98373_sdw_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                /* enable max98373 first */
-               ret = max98373_trigger(substream, cmd);
+               ret = max_98373_trigger(substream, cmd);
                if (ret < 0)
                        break;
 
@@ -77,7 +77,7 @@ static int max98373_sdw_trigger(struct snd_pcm_substream *substream, int cmd)
                if (ret < 0)
                        break;
 
-               ret = max98373_trigger(substream, cmd);
+               ret = max_98373_trigger(substream, cmd);
                break;
        default:
                ret = -EINVAL;
index 6a181e4..54395e2 100644 (file)
@@ -167,7 +167,6 @@ static struct snd_soc_dai_link dailink[] = {
                .name = "SSP5-Codec",
                .id = 0,
                .no_pcm = 1,
-               .nonatomic = true,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                .ops = &sof_wm8804_ops,
index 692c4c4..39ac6d5 100644 (file)
@@ -232,7 +232,33 @@ static const struct snd_soc_acpi_link_adr adl_rvp[] = {
        {}
 };
 
+static const struct snd_soc_acpi_codecs adl_max98373_amp = {
+       .num_codecs = 1,
+       .codecs = {"MX98373"}
+};
+
+static const struct snd_soc_acpi_codecs adl_max98357a_amp = {
+       .num_codecs = 1,
+       .codecs = {"MX98357A"}
+};
+
 struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
+       {
+               .id = "10EC5682",
+               .drv_name = "adl_max98373_rt5682",
+               .machine_quirk = snd_soc_acpi_codec_list,
+               .quirk_data = &adl_max98373_amp,
+               .sof_fw_filename = "sof-adl.ri",
+               .sof_tplg_filename = "sof-adl-max98373-rt5682.tplg",
+       },
+       {
+               .id = "10EC5682",
+               .drv_name = "adl_max98357a_rt5682",
+               .machine_quirk = snd_soc_acpi_codec_list,
+               .quirk_data = &adl_max98357a_amp,
+               .sof_fw_filename = "sof-adl.ri",
+               .sof_tplg_filename = "sof-adl-max98357a-rt5682.tplg",
+       },
        {},
 };
 EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_machines);
index 6ceaab1..20ef855 100644 (file)
@@ -40,6 +40,16 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[] = {
                .sof_fw_filename = "sof-glk.ri",
                .sof_tplg_filename = "sof-glk-rt5682.tplg",
        },
+       {
+               .id = "10134242",
+               .drv_name = "glk_cs4242_max98357a",
+               .fw_filename = "intel/dsp_fw_glk.bin",
+               .machine_quirk = snd_soc_acpi_codec_list,
+               .quirk_data = &glk_codecs,
+               .sof_fw_filename = "sof-glk.ri",
+               .sof_tplg_filename = "sof-glk-cs42l42.tplg",
+       },
+
        {},
 };
 EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_glk_machines);
index 52ba0e3..65d0bf9 100644 (file)
@@ -371,7 +371,7 @@ static int jz4740_i2s_resume(struct snd_soc_component *component)
        return 0;
 }
 
-static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
+static void jz4740_i2s_init_pcm_config(struct jz4740_i2s *i2s)
 {
        struct snd_dmaengine_dai_dma_data *dma_data;
 
@@ -396,7 +396,7 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
        if (ret)
                return ret;
 
-       jz4740_i2c_init_pcm_config(i2s);
+       jz4740_i2s_init_pcm_config(i2s);
        snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
                &i2s->capture_dma_data);
 
index 44f1201..4da14ea 100644 (file)
@@ -7,6 +7,4 @@
 #define JZ4740_I2S_CLKSRC_EXT 0
 #define JZ4740_I2S_CLKSRC_PLL 1
 
-#define JZ4740_I2S_BIT_CLK             0
-
 #endif
index f040dce..f8c73e8 100644 (file)
@@ -413,8 +413,6 @@ static int mtk_adda_pad_top_event(struct snd_soc_dapm_widget *w,
        case SND_SOC_DAPM_PRE_PMU:
                if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2)
                        regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x38);
-               else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2)
-                       regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x30);
                else
                        regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x30);
                break;
index 729d27d..c5c1818 100644 (file)
@@ -1183,7 +1183,7 @@ int q6afe_port_stop(struct q6afe_port *port)
        struct afe_port_cmd_device_stop *stop;
        struct q6afe *afe = port->afe;
        struct apr_pkt *pkt;
-       int port_id = port->id;
+       int port_id;
        int ret = 0;
        int index, pkt_size;
        void *p;
index f3d6f70..feae487 100644 (file)
@@ -13,7 +13,10 @@ snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-compress.o
 
 snd-sof-intel-hda-objs := hda-codec.o
 
-obj-$(CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP) += snd-sof-acpi-intel-byt.o
+snd-sof-intel-atom-objs := atom.o
+
+obj-$(CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP) += snd-sof-intel-atom.o
+obj-$(CONFIG_SND_SOC_SOF_BAYTRAIL) += snd-sof-acpi-intel-byt.o
 obj-$(CONFIG_SND_SOC_SOF_BROADWELL) += snd-sof-acpi-intel-bdw.o
 obj-$(CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC) += snd-sof-intel-ipc.o
 obj-$(CONFIG_SND_SOC_SOF_HDA_COMMON) += snd-sof-intel-hda-common.o
diff --git a/sound/soc/sof/intel/atom.c b/sound/soc/sof/intel/atom.c
new file mode 100644 (file)
index 0000000..d8804ef
--- /dev/null
@@ -0,0 +1,463 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license.  When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2018-2021 Intel Corporation. All rights reserved.
+//
+// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
+//
+
+/*
+ * Hardware interface for audio DSP on Atom devices
+ */
+
+#include <linux/module.h>
+#include <sound/sof.h>
+#include <sound/sof/xtensa.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+#include <sound/intel-dsp-config.h>
+#include "../ops.h"
+#include "shim.h"
+#include "atom.h"
+#include "../sof-acpi-dev.h"
+#include "../sof-audio.h"
+#include "../../intel/common/soc-intel-quirks.h"
+
+static void atom_host_done(struct snd_sof_dev *sdev);
+static void atom_dsp_done(struct snd_sof_dev *sdev);
+static void atom_get_reply(struct snd_sof_dev *sdev);
+
+/*
+ * Debug
+ */
+
+static void atom_get_registers(struct snd_sof_dev *sdev,
+                              struct sof_ipc_dsp_oops_xtensa *xoops,
+                              struct sof_ipc_panic_info *panic_info,
+                              u32 *stack, size_t stack_words)
+{
+       u32 offset = sdev->dsp_oops_offset;
+
+       /* first read regsisters */
+       sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
+
+       /* note: variable AR register array is not read */
+
+       /* then get panic info */
+       if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
+               dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
+                       xoops->arch_hdr.totalsize);
+               return;
+       }
+       offset += xoops->arch_hdr.totalsize;
+       sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
+
+       /* then get the stack */
+       offset += sizeof(*panic_info);
+       sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
+}
+
+void atom_dump(struct snd_sof_dev *sdev, u32 flags)
+{
+       struct sof_ipc_dsp_oops_xtensa xoops;
+       struct sof_ipc_panic_info panic_info;
+       u32 stack[STACK_DUMP_SIZE];
+       u64 status, panic, imrd, imrx;
+
+       /* now try generic SOF status messages */
+       status = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCD);
+       panic = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCX);
+       atom_get_registers(sdev, &xoops, &panic_info, stack,
+                          STACK_DUMP_SIZE);
+       snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack,
+                          STACK_DUMP_SIZE);
+
+       /* provide some context for firmware debug */
+       imrx = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IMRX);
+       imrd = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IMRD);
+       dev_err(sdev->dev,
+               "error: ipc host -> DSP: pending %s complete %s raw 0x%llx\n",
+               (panic & SHIM_IPCX_BUSY) ? "yes" : "no",
+               (panic & SHIM_IPCX_DONE) ? "yes" : "no", panic);
+       dev_err(sdev->dev,
+               "error: mask host: pending %s complete %s raw 0x%llx\n",
+               (imrx & SHIM_IMRX_BUSY) ? "yes" : "no",
+               (imrx & SHIM_IMRX_DONE) ? "yes" : "no", imrx);
+       dev_err(sdev->dev,
+               "error: ipc DSP -> host: pending %s complete %s raw 0x%llx\n",
+               (status & SHIM_IPCD_BUSY) ? "yes" : "no",
+               (status & SHIM_IPCD_DONE) ? "yes" : "no", status);
+       dev_err(sdev->dev,
+               "error: mask DSP: pending %s complete %s raw 0x%llx\n",
+               (imrd & SHIM_IMRD_BUSY) ? "yes" : "no",
+               (imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd);
+
+}
+EXPORT_SYMBOL_NS(atom_dump, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+/*
+ * IPC Doorbell IRQ handler and thread.
+ */
+
+irqreturn_t atom_irq_handler(int irq, void *context)
+{
+       struct snd_sof_dev *sdev = context;
+       u64 ipcx, ipcd;
+       int ret = IRQ_NONE;
+
+       ipcx = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCX);
+       ipcd = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCD);
+
+       if (ipcx & SHIM_BYT_IPCX_DONE) {
+
+               /* reply message from DSP, Mask Done interrupt first */
+               snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR,
+                                                  SHIM_IMRX,
+                                                  SHIM_IMRX_DONE,
+                                                  SHIM_IMRX_DONE);
+               ret = IRQ_WAKE_THREAD;
+       }
+
+       if (ipcd & SHIM_BYT_IPCD_BUSY) {
+
+               /* new message from DSP, Mask Busy interrupt first */
+               snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR,
+                                                  SHIM_IMRX,
+                                                  SHIM_IMRX_BUSY,
+                                                  SHIM_IMRX_BUSY);
+               ret = IRQ_WAKE_THREAD;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_NS(atom_irq_handler, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+irqreturn_t atom_irq_thread(int irq, void *context)
+{
+       struct snd_sof_dev *sdev = context;
+       u64 ipcx, ipcd;
+
+       ipcx = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCX);
+       ipcd = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCD);
+
+       /* reply message from DSP */
+       if (ipcx & SHIM_BYT_IPCX_DONE) {
+
+               spin_lock_irq(&sdev->ipc_lock);
+
+               /*
+                * handle immediate reply from DSP core. If the msg is
+                * found, set done bit in cmd_done which is called at the
+                * end of message processing function, else set it here
+                * because the done bit can't be set in cmd_done function
+                * which is triggered by msg
+                */
+               atom_get_reply(sdev);
+               snd_sof_ipc_reply(sdev, ipcx);
+
+               atom_dsp_done(sdev);
+
+               spin_unlock_irq(&sdev->ipc_lock);
+       }
+
+       /* new message from DSP */
+       if (ipcd & SHIM_BYT_IPCD_BUSY) {
+
+               /* Handle messages from DSP Core */
+               if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
+                       snd_sof_dsp_panic(sdev, PANIC_OFFSET(ipcd) +
+                                         MBOX_OFFSET);
+               } else {
+                       snd_sof_ipc_msgs_rx(sdev);
+               }
+
+               atom_host_done(sdev);
+       }
+
+       return IRQ_HANDLED;
+}
+EXPORT_SYMBOL_NS(atom_irq_thread, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+int atom_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
+{
+       /* unmask and prepare to receive Done interrupt */
+       snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IMRX,
+                                          SHIM_IMRX_DONE, 0);
+
+       /* send the message */
+       sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
+                         msg->msg_size);
+       snd_sof_dsp_write64(sdev, DSP_BAR, SHIM_IPCX, SHIM_BYT_IPCX_BUSY);
+
+       return 0;
+}
+EXPORT_SYMBOL_NS(atom_send_msg, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+static void atom_get_reply(struct snd_sof_dev *sdev)
+{
+       struct snd_sof_ipc_msg *msg = sdev->msg;
+       struct sof_ipc_reply reply;
+       int ret = 0;
+
+       /*
+        * Sometimes, there is unexpected reply ipc arriving. The reply
+        * ipc belongs to none of the ipcs sent from driver.
+        * In this case, the driver must ignore the ipc.
+        */
+       if (!msg) {
+               dev_warn(sdev->dev, "unexpected ipc interrupt raised!\n");
+               return;
+       }
+
+       /* get reply */
+       sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
+
+       if (reply.error < 0) {
+               memcpy(msg->reply_data, &reply, sizeof(reply));
+               ret = reply.error;
+       } else {
+               /* reply correct size ? */
+               if (reply.hdr.size != msg->reply_size) {
+                       dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
+                               msg->reply_size, reply.hdr.size);
+                       ret = -EINVAL;
+               }
+
+               /* read the message */
+               if (msg->reply_size > 0)
+                       sof_mailbox_read(sdev, sdev->host_box.offset,
+                                        msg->reply_data, msg->reply_size);
+       }
+
+       msg->reply_error = ret;
+}
+
+int atom_get_mailbox_offset(struct snd_sof_dev *sdev)
+{
+       return MBOX_OFFSET;
+}
+EXPORT_SYMBOL_NS(atom_get_mailbox_offset, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+int atom_get_window_offset(struct snd_sof_dev *sdev, u32 id)
+{
+       return MBOX_OFFSET;
+}
+EXPORT_SYMBOL_NS(atom_get_window_offset, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+static void atom_host_done(struct snd_sof_dev *sdev)
+{
+       /* clear BUSY bit and set DONE bit - accept new messages */
+       snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IPCD,
+                                          SHIM_BYT_IPCD_BUSY |
+                                          SHIM_BYT_IPCD_DONE,
+                                          SHIM_BYT_IPCD_DONE);
+
+       /* unmask and prepare to receive next new message */
+       snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IMRX,
+                                          SHIM_IMRX_BUSY, 0);
+}
+
+static void atom_dsp_done(struct snd_sof_dev *sdev)
+{
+       /* clear DONE bit - tell DSP we have completed */
+       snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IPCX,
+                                          SHIM_BYT_IPCX_DONE, 0);
+}
+
+/*
+ * DSP control.
+ */
+
+int atom_run(struct snd_sof_dev *sdev)
+{
+       int tries = 10;
+
+       /* release stall and wait to unstall */
+       snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR,
+                                 SHIM_BYT_CSR_STALL, 0x0);
+       while (tries--) {
+               if (!(snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_CSR) &
+                     SHIM_BYT_CSR_PWAITMODE))
+                       break;
+               msleep(100);
+       }
+       if (tries < 0) {
+               dev_err(sdev->dev, "error:  unable to run DSP firmware\n");
+               atom_dump(sdev, SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX);
+               return -ENODEV;
+       }
+
+       /* return init core mask */
+       return 1;
+}
+EXPORT_SYMBOL_NS(atom_run, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+int atom_reset(struct snd_sof_dev *sdev)
+{
+       /* put DSP into reset, set reset vector and stall */
+       snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR,
+                                 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL |
+                                 SHIM_BYT_CSR_STALL,
+                                 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL |
+                                 SHIM_BYT_CSR_STALL);
+
+       usleep_range(10, 15);
+
+       /* take DSP out of reset and keep stalled for FW loading */
+       snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR,
+                                 SHIM_BYT_CSR_RST, 0);
+
+       return 0;
+}
+EXPORT_SYMBOL_NS(atom_reset, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
+                                  const char *sof_tplg_filename,
+                                  const char *ssp_str)
+{
+       const char *tplg_filename = NULL;
+       char *filename;
+       char *split_ext;
+
+       filename = devm_kstrdup(sdev->dev, sof_tplg_filename, GFP_KERNEL);
+       if (!filename)
+               return NULL;
+
+       /* this assumes a .tplg extension */
+       split_ext = strsep(&filename, ".");
+       if (split_ext) {
+               tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
+                                              "%s-%s.tplg",
+                                              split_ext, ssp_str);
+               if (!tplg_filename)
+                       return NULL;
+       }
+       return tplg_filename;
+}
+
+void atom_machine_select(struct snd_sof_dev *sdev)
+{
+       struct snd_sof_pdata *sof_pdata = sdev->pdata;
+       const struct sof_dev_desc *desc = sof_pdata->desc;
+       struct snd_soc_acpi_mach *mach;
+       struct platform_device *pdev;
+       const char *tplg_filename;
+
+       mach = snd_soc_acpi_find_machine(desc->machines);
+       if (!mach) {
+               dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
+               return;
+       }
+
+       pdev = to_platform_device(sdev->dev);
+       if (soc_intel_is_byt_cr(pdev)) {
+               dev_dbg(sdev->dev,
+                       "BYT-CR detected, SSP0 used instead of SSP2\n");
+
+               tplg_filename = fixup_tplg_name(sdev,
+                                               mach->sof_tplg_filename,
+                                               "ssp0");
+       } else {
+               tplg_filename = mach->sof_tplg_filename;
+       }
+
+       if (!tplg_filename) {
+               dev_dbg(sdev->dev,
+                       "error: no topology filename\n");
+               return;
+       }
+
+       sof_pdata->tplg_filename = tplg_filename;
+       mach->mach_params.acpi_ipc_irq_index = desc->irqindex_host_ipc;
+       sof_pdata->machine = mach;
+}
+EXPORT_SYMBOL_NS(atom_machine_select, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+/* Atom DAIs */
+struct snd_soc_dai_driver atom_dai[] = {
+{
+       .name = "ssp0-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+},
+{
+       .name = "ssp1-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+},
+{
+       .name = "ssp2-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       }
+},
+{
+       .name = "ssp3-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+},
+{
+       .name = "ssp4-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+},
+{
+       .name = "ssp5-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+},
+};
+EXPORT_SYMBOL_NS(atom_dai, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+void atom_set_mach_params(const struct snd_soc_acpi_mach *mach,
+                         struct snd_sof_dev *sdev)
+{
+       struct snd_sof_pdata *pdata = sdev->pdata;
+       const struct sof_dev_desc *desc = pdata->desc;
+       struct snd_soc_acpi_mach_params *mach_params;
+
+       mach_params = (struct snd_soc_acpi_mach_params *)&mach->mach_params;
+       mach_params->platform = dev_name(sdev->dev);
+       mach_params->num_dai_drivers = desc->ops->num_drv;
+       mach_params->dai_drivers = desc->ops->drv;
+}
+EXPORT_SYMBOL_NS(atom_set_mach_params, SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/sof/intel/atom.h b/sound/soc/sof/intel/atom.h
new file mode 100644 (file)
index 0000000..96a462c
--- /dev/null
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Copyright(c) 2017-2021 Intel Corporation. All rights reserved.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
+ */
+
+#ifndef __SOF_INTEL_ATOM_H
+#define __SOF_INTEL_ATOM_H
+
+/* DSP memories */
+#define IRAM_OFFSET            0x0C0000
+#define IRAM_SIZE              (80 * 1024)
+#define DRAM_OFFSET            0x100000
+#define DRAM_SIZE              (160 * 1024)
+#define SHIM_OFFSET            0x140000
+#define SHIM_SIZE_BYT          0x100
+#define SHIM_SIZE_CHT          0x118
+#define MBOX_OFFSET            0x144000
+#define MBOX_SIZE              0x1000
+#define EXCEPT_OFFSET          0x800
+#define EXCEPT_MAX_HDR_SIZE    0x400
+
+/* DSP peripherals */
+#define DMAC0_OFFSET           0x098000
+#define DMAC1_OFFSET           0x09c000
+#define DMAC2_OFFSET           0x094000
+#define DMAC_SIZE              0x420
+#define SSP0_OFFSET            0x0a0000
+#define SSP1_OFFSET            0x0a1000
+#define SSP2_OFFSET            0x0a2000
+#define SSP3_OFFSET            0x0a4000
+#define SSP4_OFFSET            0x0a5000
+#define SSP5_OFFSET            0x0a6000
+#define SSP_SIZE               0x100
+
+#define STACK_DUMP_SIZE                32
+
+#define PCI_BAR_SIZE           0x200000
+
+#define PANIC_OFFSET(x)        (((x) & GENMASK_ULL(47, 32)) >> 32)
+
+/*
+ * Debug
+ */
+
+#define MBOX_DUMP_SIZE 0x30
+
+/* BARs */
+#define DSP_BAR                0
+#define PCI_BAR                1
+#define IMR_BAR                2
+
+irqreturn_t atom_irq_handler(int irq, void *context);
+irqreturn_t atom_irq_thread(int irq, void *context);
+
+int atom_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg);
+int atom_get_mailbox_offset(struct snd_sof_dev *sdev);
+int atom_get_window_offset(struct snd_sof_dev *sdev, u32 id);
+
+int atom_run(struct snd_sof_dev *sdev);
+int atom_reset(struct snd_sof_dev *sdev);
+void atom_dump(struct snd_sof_dev *sdev, u32 flags);
+
+void atom_machine_select(struct snd_sof_dev *sdev);
+void atom_set_mach_params(const struct snd_soc_acpi_mach *mach,
+                         struct snd_sof_dev *sdev);
+
+extern struct snd_soc_dai_driver atom_dai[];
+
+#endif
index d9803e2..8edaf6f 100644 (file)
 #include <sound/soc-acpi-intel-match.h>
 #include <sound/intel-dsp-config.h>
 #include "../ops.h"
+#include "atom.h"
 #include "shim.h"
 #include "../sof-acpi-dev.h"
 #include "../sof-audio.h"
 #include "../../intel/common/soc-intel-quirks.h"
 
-/* DSP memories */
-#define IRAM_OFFSET            0x0C0000
-#define IRAM_SIZE              (80 * 1024)
-#define DRAM_OFFSET            0x100000
-#define DRAM_SIZE              (160 * 1024)
-#define SHIM_OFFSET            0x140000
-#define SHIM_SIZE_BYT          0x100
-#define SHIM_SIZE_CHT          0x118
-#define MBOX_OFFSET            0x144000
-#define MBOX_SIZE              0x1000
-#define EXCEPT_OFFSET          0x800
-#define EXCEPT_MAX_HDR_SIZE    0x400
-
-/* DSP peripherals */
-#define DMAC0_OFFSET           0x098000
-#define DMAC1_OFFSET           0x09c000
-#define DMAC2_OFFSET           0x094000
-#define DMAC_SIZE              0x420
-#define SSP0_OFFSET            0x0a0000
-#define SSP1_OFFSET            0x0a1000
-#define SSP2_OFFSET            0x0a2000
-#define SSP3_OFFSET            0x0a4000
-#define SSP4_OFFSET            0x0a5000
-#define SSP5_OFFSET            0x0a6000
-#define SSP_SIZE               0x100
-
-#define BYT_STACK_DUMP_SIZE    32
-
-#define BYT_PCI_BAR_SIZE       0x200000
-
-#define BYT_PANIC_OFFSET(x)    (((x) & GENMASK_ULL(47, 32)) >> 32)
-
-/*
- * Debug
- */
-
-#define MBOX_DUMP_SIZE 0x30
-
-/* BARs */
-#define BYT_DSP_BAR            0
-#define BYT_PCI_BAR            1
-#define BYT_IMR_BAR            2
-
 static const struct snd_sof_debugfs_map byt_debugfs[] = {
-       {"dmac0", BYT_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
+       {"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
         SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"dmac1", BYT_DSP_BAR,  DMAC1_OFFSET, DMAC_SIZE,
+       {"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
         SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"ssp0",  BYT_DSP_BAR, SSP0_OFFSET, SSP_SIZE,
+       {"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE,
         SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"ssp1", BYT_DSP_BAR, SSP1_OFFSET, SSP_SIZE,
+       {"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE,
         SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"ssp2", BYT_DSP_BAR, SSP2_OFFSET, SSP_SIZE,
+       {"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE,
         SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"iram", BYT_DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
+       {"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
         SOF_DEBUGFS_ACCESS_D0_ONLY},
-       {"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
+       {"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
         SOF_DEBUGFS_ACCESS_D0_ONLY},
-       {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT,
+       {"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT,
         SOF_DEBUGFS_ACCESS_ALWAYS},
 };
 
-static void byt_host_done(struct snd_sof_dev *sdev);
-static void byt_dsp_done(struct snd_sof_dev *sdev);
-static void byt_get_reply(struct snd_sof_dev *sdev);
-
-/*
- * Debug
- */
-
-static void byt_get_registers(struct snd_sof_dev *sdev,
-                             struct sof_ipc_dsp_oops_xtensa *xoops,
-                             struct sof_ipc_panic_info *panic_info,
-                             u32 *stack, size_t stack_words)
-{
-       u32 offset = sdev->dsp_oops_offset;
-
-       /* first read regsisters */
-       sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
-
-       /* note: variable AR register array is not read */
-
-       /* then get panic info */
-       if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
-               dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
-                       xoops->arch_hdr.totalsize);
-               return;
-       }
-       offset += xoops->arch_hdr.totalsize;
-       sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
-
-       /* then get the stack */
-       offset += sizeof(*panic_info);
-       sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
-}
-
-static void byt_dump(struct snd_sof_dev *sdev, u32 flags)
-{
-       struct sof_ipc_dsp_oops_xtensa xoops;
-       struct sof_ipc_panic_info panic_info;
-       u32 stack[BYT_STACK_DUMP_SIZE];
-       u64 status, panic, imrd, imrx;
-
-       /* now try generic SOF status messages */
-       status = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD);
-       panic = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX);
-       byt_get_registers(sdev, &xoops, &panic_info, stack,
-                         BYT_STACK_DUMP_SIZE);
-       snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack,
-                          BYT_STACK_DUMP_SIZE);
-
-       /* provide some context for firmware debug */
-       imrx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRX);
-       imrd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRD);
-       dev_err(sdev->dev,
-               "error: ipc host -> DSP: pending %s complete %s raw 0x%llx\n",
-               (panic & SHIM_IPCX_BUSY) ? "yes" : "no",
-               (panic & SHIM_IPCX_DONE) ? "yes" : "no", panic);
-       dev_err(sdev->dev,
-               "error: mask host: pending %s complete %s raw 0x%llx\n",
-               (imrx & SHIM_IMRX_BUSY) ? "yes" : "no",
-               (imrx & SHIM_IMRX_DONE) ? "yes" : "no", imrx);
-       dev_err(sdev->dev,
-               "error: ipc DSP -> host: pending %s complete %s raw 0x%llx\n",
-               (status & SHIM_IPCD_BUSY) ? "yes" : "no",
-               (status & SHIM_IPCD_DONE) ? "yes" : "no", status);
-       dev_err(sdev->dev,
-               "error: mask DSP: pending %s complete %s raw 0x%llx\n",
-               (imrd & SHIM_IMRD_BUSY) ? "yes" : "no",
-               (imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd);
-
-}
-
-/*
- * IPC Doorbell IRQ handler and thread.
- */
-
-static irqreturn_t byt_irq_handler(int irq, void *context)
-{
-       struct snd_sof_dev *sdev = context;
-       u64 ipcx, ipcd;
-       int ret = IRQ_NONE;
-
-       ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX);
-       ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD);
-
-       if (ipcx & SHIM_BYT_IPCX_DONE) {
-
-               /* reply message from DSP, Mask Done interrupt first */
-               snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR,
-                                                  SHIM_IMRX,
-                                                  SHIM_IMRX_DONE,
-                                                  SHIM_IMRX_DONE);
-               ret = IRQ_WAKE_THREAD;
-       }
-
-       if (ipcd & SHIM_BYT_IPCD_BUSY) {
-
-               /* new message from DSP, Mask Busy interrupt first */
-               snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR,
-                                                  SHIM_IMRX,
-                                                  SHIM_IMRX_BUSY,
-                                                  SHIM_IMRX_BUSY);
-               ret = IRQ_WAKE_THREAD;
-       }
-
-       return ret;
-}
-
-static irqreturn_t byt_irq_thread(int irq, void *context)
-{
-       struct snd_sof_dev *sdev = context;
-       u64 ipcx, ipcd;
-
-       ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX);
-       ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD);
-
-       /* reply message from DSP */
-       if (ipcx & SHIM_BYT_IPCX_DONE) {
-
-               spin_lock_irq(&sdev->ipc_lock);
-
-               /*
-                * handle immediate reply from DSP core. If the msg is
-                * found, set done bit in cmd_done which is called at the
-                * end of message processing function, else set it here
-                * because the done bit can't be set in cmd_done function
-                * which is triggered by msg
-                */
-               byt_get_reply(sdev);
-               snd_sof_ipc_reply(sdev, ipcx);
-
-               byt_dsp_done(sdev);
-
-               spin_unlock_irq(&sdev->ipc_lock);
-       }
-
-       /* new message from DSP */
-       if (ipcd & SHIM_BYT_IPCD_BUSY) {
-
-               /* Handle messages from DSP Core */
-               if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
-                       snd_sof_dsp_panic(sdev, BYT_PANIC_OFFSET(ipcd) +
-                                         MBOX_OFFSET);
-               } else {
-                       snd_sof_ipc_msgs_rx(sdev);
-               }
-
-               byt_host_done(sdev);
-       }
-
-       return IRQ_HANDLED;
-}
-
-static int byt_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
-{
-       /* unmask and prepare to receive Done interrupt */
-       snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX,
-                                          SHIM_IMRX_DONE, 0);
-
-       /* send the message */
-       sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
-                         msg->msg_size);
-       snd_sof_dsp_write64(sdev, BYT_DSP_BAR, SHIM_IPCX, SHIM_BYT_IPCX_BUSY);
-
-       return 0;
-}
-
-static void byt_get_reply(struct snd_sof_dev *sdev)
-{
-       struct snd_sof_ipc_msg *msg = sdev->msg;
-       struct sof_ipc_reply reply;
-       int ret = 0;
-
-       /*
-        * Sometimes, there is unexpected reply ipc arriving. The reply
-        * ipc belongs to none of the ipcs sent from driver.
-        * In this case, the driver must ignore the ipc.
-        */
-       if (!msg) {
-               dev_warn(sdev->dev, "unexpected ipc interrupt raised!\n");
-               return;
-       }
-
-       /* get reply */
-       sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
-
-       if (reply.error < 0) {
-               memcpy(msg->reply_data, &reply, sizeof(reply));
-               ret = reply.error;
-       } else {
-               /* reply correct size ? */
-               if (reply.hdr.size != msg->reply_size) {
-                       dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
-                               msg->reply_size, reply.hdr.size);
-                       ret = -EINVAL;
-               }
-
-               /* read the message */
-               if (msg->reply_size > 0)
-                       sof_mailbox_read(sdev, sdev->host_box.offset,
-                                        msg->reply_data, msg->reply_size);
-       }
-
-       msg->reply_error = ret;
-}
-
-static int byt_get_mailbox_offset(struct snd_sof_dev *sdev)
-{
-       return MBOX_OFFSET;
-}
-
-static int byt_get_window_offset(struct snd_sof_dev *sdev, u32 id)
-{
-       return MBOX_OFFSET;
-}
-
-static void byt_host_done(struct snd_sof_dev *sdev)
-{
-       /* clear BUSY bit and set DONE bit - accept new messages */
-       snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCD,
-                                          SHIM_BYT_IPCD_BUSY |
-                                          SHIM_BYT_IPCD_DONE,
-                                          SHIM_BYT_IPCD_DONE);
-
-       /* unmask and prepare to receive next new message */
-       snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX,
-                                          SHIM_IMRX_BUSY, 0);
-}
-
-static void byt_dsp_done(struct snd_sof_dev *sdev)
-{
-       /* clear DONE bit - tell DSP we have completed */
-       snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCX,
-                                          SHIM_BYT_IPCX_DONE, 0);
-}
-
-/*
- * DSP control.
- */
-
-static int byt_run(struct snd_sof_dev *sdev)
-{
-       int tries = 10;
-
-       /* release stall and wait to unstall */
-       snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR,
-                                 SHIM_BYT_CSR_STALL, 0x0);
-       while (tries--) {
-               if (!(snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_CSR) &
-                     SHIM_BYT_CSR_PWAITMODE))
-                       break;
-               msleep(100);
-       }
-       if (tries < 0) {
-               dev_err(sdev->dev, "error:  unable to run DSP firmware\n");
-               byt_dump(sdev, SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX);
-               return -ENODEV;
-       }
-
-       /* return init core mask */
-       return 1;
-}
-
-static int byt_reset(struct snd_sof_dev *sdev)
-{
-       /* put DSP into reset, set reset vector and stall */
-       snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR,
-                                 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL |
-                                 SHIM_BYT_CSR_STALL,
-                                 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL |
-                                 SHIM_BYT_CSR_STALL);
-
-       usleep_range(10, 15);
-
-       /* take DSP out of reset and keep stalled for FW loading */
-       snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR,
-                                 SHIM_BYT_CSR_RST, 0);
-
-       return 0;
-}
-
-static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
-                                  const char *sof_tplg_filename,
-                                  const char *ssp_str)
-{
-       const char *tplg_filename = NULL;
-       char *filename;
-       char *split_ext;
-
-       filename = devm_kstrdup(sdev->dev, sof_tplg_filename, GFP_KERNEL);
-       if (!filename)
-               return NULL;
-
-       /* this assumes a .tplg extension */
-       split_ext = strsep(&filename, ".");
-       if (split_ext) {
-               tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
-                                              "%s-%s.tplg",
-                                              split_ext, ssp_str);
-               if (!tplg_filename)
-                       return NULL;
-       }
-       return tplg_filename;
-}
-
-static void byt_machine_select(struct snd_sof_dev *sdev)
-{
-       struct snd_sof_pdata *sof_pdata = sdev->pdata;
-       const struct sof_dev_desc *desc = sof_pdata->desc;
-       struct snd_soc_acpi_mach *mach;
-       struct platform_device *pdev;
-       const char *tplg_filename;
-
-       mach = snd_soc_acpi_find_machine(desc->machines);
-       if (!mach) {
-               dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
-               return;
-       }
-
-       pdev = to_platform_device(sdev->dev);
-       if (soc_intel_is_byt_cr(pdev)) {
-               dev_dbg(sdev->dev,
-                       "BYT-CR detected, SSP0 used instead of SSP2\n");
-
-               tplg_filename = fixup_tplg_name(sdev,
-                                               mach->sof_tplg_filename,
-                                               "ssp0");
-       } else {
-               tplg_filename = mach->sof_tplg_filename;
-       }
-
-       if (!tplg_filename) {
-               dev_dbg(sdev->dev,
-                       "error: no topology filename\n");
-               return;
-       }
-
-       sof_pdata->tplg_filename = tplg_filename;
-       mach->mach_params.acpi_ipc_irq_index = desc->irqindex_host_ipc;
-       sof_pdata->machine = mach;
-}
-
-/* Baytrail DAIs */
-static struct snd_soc_dai_driver byt_dai[] = {
-{
-       .name = "ssp0-port",
-       .playback = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-       .capture = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-},
-{
-       .name = "ssp1-port",
-       .playback = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-       .capture = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-},
-{
-       .name = "ssp2-port",
-       .playback = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-       .capture = {
-               .channels_min = 1,
-               .channels_max = 8,
-       }
-},
-{
-       .name = "ssp3-port",
-       .playback = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-       .capture = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-},
-{
-       .name = "ssp4-port",
-       .playback = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-       .capture = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-},
-{
-       .name = "ssp5-port",
-       .playback = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-       .capture = {
-               .channels_min = 1,
-               .channels_max = 8,
-       },
-},
-};
-
-static void byt_set_mach_params(const struct snd_soc_acpi_mach *mach,
-                               struct snd_sof_dev *sdev)
-{
-       struct snd_sof_pdata *pdata = sdev->pdata;
-       const struct sof_dev_desc *desc = pdata->desc;
-       struct snd_soc_acpi_mach_params *mach_params;
-
-       mach_params = (struct snd_soc_acpi_mach_params *)&mach->mach_params;
-       mach_params->platform = dev_name(sdev->dev);
-       mach_params->num_dai_drivers = desc->ops->num_drv;
-       mach_params->dai_drivers = desc->ops->drv;
-}
-
-/*
- * Probe and remove.
- */
-
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
-
-static int tangier_pci_probe(struct snd_sof_dev *sdev)
-{
-       struct snd_sof_pdata *pdata = sdev->pdata;
-       const struct sof_dev_desc *desc = pdata->desc;
-       struct pci_dev *pci = to_pci_dev(sdev->dev);
-       u32 base, size;
-       int ret;
-
-       /* DSP DMA can only access low 31 bits of host memory */
-       ret = dma_coerce_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31));
-       if (ret < 0) {
-               dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
-               return ret;
-       }
-
-       /* LPE base */
-       base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET;
-       size = BYT_PCI_BAR_SIZE;
-
-       dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
-       sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
-       if (!sdev->bar[BYT_DSP_BAR]) {
-               dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
-                       base, size);
-               return -ENODEV;
-       }
-       dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]);
-
-       /* IMR base - optional */
-       if (desc->resindex_imr_base == -1)
-               goto irq;
-
-       base = pci_resource_start(pci, desc->resindex_imr_base);
-       size = pci_resource_len(pci, desc->resindex_imr_base);
-
-       /* some BIOSes don't map IMR */
-       if (base == 0x55aa55aa || base == 0x0) {
-               dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
-               goto irq;
-       }
-
-       dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
-       sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size);
-       if (!sdev->bar[BYT_IMR_BAR]) {
-               dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
-                       base, size);
-               return -ENODEV;
-       }
-       dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]);
-
-irq:
-       /* register our IRQ */
-       sdev->ipc_irq = pci->irq;
-       dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
-       ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
-                                       byt_irq_handler, byt_irq_thread,
-                                       0, "AudioDSP", sdev);
-       if (ret < 0) {
-               dev_err(sdev->dev, "error: failed to register IRQ %d\n",
-                       sdev->ipc_irq);
-               return ret;
-       }
-
-       /* enable BUSY and disable DONE Interrupt by default */
-       snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX,
-                                 SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
-                                 SHIM_IMRX_DONE);
-
-       /* set default mailbox offset for FW ready message */
-       sdev->dsp_box.offset = MBOX_OFFSET;
-
-       return ret;
-}
-
-const struct snd_sof_dsp_ops sof_tng_ops = {
-       /* device init */
-       .probe          = tangier_pci_probe,
-
-       /* DSP core boot / reset */
-       .run            = byt_run,
-       .reset          = byt_reset,
-
-       /* Register IO */
-       .write          = sof_io_write,
-       .read           = sof_io_read,
-       .write64        = sof_io_write64,
-       .read64         = sof_io_read64,
-
-       /* Block IO */
-       .block_read     = sof_block_read,
-       .block_write    = sof_block_write,
-
-       /* doorbell */
-       .irq_handler    = byt_irq_handler,
-       .irq_thread     = byt_irq_thread,
-
-       /* ipc */
-       .send_msg       = byt_send_msg,
-       .fw_ready       = sof_fw_ready,
-       .get_mailbox_offset = byt_get_mailbox_offset,
-       .get_window_offset = byt_get_window_offset,
-
-       .ipc_msg_data   = intel_ipc_msg_data,
-       .ipc_pcm_params = intel_ipc_pcm_params,
-
-       /* machine driver */
-       .machine_select = byt_machine_select,
-       .machine_register = sof_machine_register,
-       .machine_unregister = sof_machine_unregister,
-       .set_mach_params = byt_set_mach_params,
-
-       /* debug */
-       .debug_map      = byt_debugfs,
-       .debug_map_count        = ARRAY_SIZE(byt_debugfs),
-       .dbg_dump       = byt_dump,
-
-       /* stream callbacks */
-       .pcm_open       = intel_pcm_open,
-       .pcm_close      = intel_pcm_close,
-
-       /* module loading */
-       .load_module    = snd_sof_parse_module_memcpy,
-
-       /*Firmware loading */
-       .load_firmware  = snd_sof_load_firmware_memcpy,
-
-       /* DAI drivers */
-       .drv = byt_dai,
-       .num_drv = 3, /* we have only 3 SSPs on byt*/
-
-       /* ALSA HW info flags */
-       .hw_info =      SNDRV_PCM_INFO_MMAP |
-                       SNDRV_PCM_INFO_MMAP_VALID |
-                       SNDRV_PCM_INFO_INTERLEAVED |
-                       SNDRV_PCM_INFO_PAUSE |
-                       SNDRV_PCM_INFO_BATCH,
-
-       .arch_ops = &sof_xtensa_arch_ops,
-};
-EXPORT_SYMBOL_NS(sof_tng_ops, SND_SOC_SOF_MERRIFIELD);
-
-const struct sof_intel_dsp_desc tng_chip_info = {
-       .cores_num = 1,
-       .host_managed_cores_mask = 1,
+static const struct snd_sof_debugfs_map cht_debugfs[] = {
+       {"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"dmac2", DSP_BAR, DMAC2_OFFSET, DMAC_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"ssp3", DSP_BAR, SSP3_OFFSET, SSP_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"ssp4", DSP_BAR, SSP4_OFFSET, SSP_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"ssp5", DSP_BAR, SSP5_OFFSET, SSP_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
+        SOF_DEBUGFS_ACCESS_D0_ONLY},
+       {"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
+        SOF_DEBUGFS_ACCESS_D0_ONLY},
+       {"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_CHT,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
 };
-EXPORT_SYMBOL_NS(tng_chip_info, SND_SOC_SOF_MERRIFIELD);
-
-#endif /* CONFIG_SND_SOC_SOF_MERRIFIELD */
-
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
 
 static void byt_reset_dsp_disable_int(struct snd_sof_dev *sdev)
 {
        /* Disable Interrupt from both sides */
-       snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x3);
-       snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x3);
+       snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX, 0x3, 0x3);
+       snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRD, 0x3, 0x3);
 
        /* Put DSP into reset, set reset vector */
-       snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR,
+       snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR,
                                  SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL,
                                  SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL);
 }
@@ -689,7 +93,7 @@ static int byt_suspend(struct snd_sof_dev *sdev, u32 target_state)
 static int byt_resume(struct snd_sof_dev *sdev)
 {
        /* enable BUSY and disable DONE Interrupt by default */
-       snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX,
+       snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX,
                                  SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
                                  SHIM_IMRX_DONE);
 
@@ -703,33 +107,6 @@ static int byt_remove(struct snd_sof_dev *sdev)
        return 0;
 }
 
-static const struct snd_sof_debugfs_map cht_debugfs[] = {
-       {"dmac0", BYT_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
-        SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"dmac1", BYT_DSP_BAR,  DMAC1_OFFSET, DMAC_SIZE,
-        SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"dmac2", BYT_DSP_BAR,  DMAC2_OFFSET, DMAC_SIZE,
-        SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"ssp0",  BYT_DSP_BAR, SSP0_OFFSET, SSP_SIZE,
-        SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"ssp1", BYT_DSP_BAR, SSP1_OFFSET, SSP_SIZE,
-        SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"ssp2", BYT_DSP_BAR, SSP2_OFFSET, SSP_SIZE,
-        SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"ssp3", BYT_DSP_BAR, SSP3_OFFSET, SSP_SIZE,
-        SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"ssp4", BYT_DSP_BAR, SSP4_OFFSET, SSP_SIZE,
-        SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"ssp5", BYT_DSP_BAR, SSP5_OFFSET, SSP_SIZE,
-        SOF_DEBUGFS_ACCESS_ALWAYS},
-       {"iram", BYT_DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
-        SOF_DEBUGFS_ACCESS_D0_ONLY},
-       {"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
-        SOF_DEBUGFS_ACCESS_D0_ONLY},
-       {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE_CHT,
-        SOF_DEBUGFS_ACCESS_ALWAYS},
-};
-
 static int byt_acpi_probe(struct snd_sof_dev *sdev)
 {
        struct snd_sof_pdata *pdata = sdev->pdata;
@@ -760,17 +137,17 @@ static int byt_acpi_probe(struct snd_sof_dev *sdev)
        }
 
        dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
-       sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
-       if (!sdev->bar[BYT_DSP_BAR]) {
+       sdev->bar[DSP_BAR] = devm_ioremap(sdev->dev, base, size);
+       if (!sdev->bar[DSP_BAR]) {
                dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
                        base, size);
                return -ENODEV;
        }
-       dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]);
+       dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[DSP_BAR]);
 
        /* TODO: add offsets */
-       sdev->mmio_bar = BYT_DSP_BAR;
-       sdev->mailbox_bar = BYT_DSP_BAR;
+       sdev->mmio_bar = DSP_BAR;
+       sdev->mailbox_bar = DSP_BAR;
 
        /* IMR base - optional */
        if (desc->resindex_imr_base == -1)
@@ -794,13 +171,13 @@ static int byt_acpi_probe(struct snd_sof_dev *sdev)
        }
 
        dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
-       sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size);
-       if (!sdev->bar[BYT_IMR_BAR]) {
+       sdev->bar[IMR_BAR] = devm_ioremap(sdev->dev, base, size);
+       if (!sdev->bar[IMR_BAR]) {
                dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
                        base, size);
                return -ENODEV;
        }
-       dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]);
+       dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[IMR_BAR]);
 
 irq:
        /* register our IRQ */
@@ -810,7 +187,7 @@ irq:
 
        dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
        ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
-                                       byt_irq_handler, byt_irq_thread,
+                                       atom_irq_handler, atom_irq_thread,
                                        IRQF_SHARED, "AudioDSP", sdev);
        if (ret < 0) {
                dev_err(sdev->dev, "error: failed to register IRQ %d\n",
@@ -819,7 +196,7 @@ irq:
        }
 
        /* enable BUSY and disable DONE Interrupt by default */
-       snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX,
+       snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX,
                                  SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
                                  SHIM_IMRX_DONE);
 
@@ -836,8 +213,8 @@ static const struct snd_sof_dsp_ops sof_byt_ops = {
        .remove         = byt_remove,
 
        /* DSP core boot / reset */
-       .run            = byt_run,
-       .reset          = byt_reset,
+       .run            = atom_run,
+       .reset          = atom_reset,
 
        /* Register IO */
        .write          = sof_io_write,
@@ -850,28 +227,28 @@ static const struct snd_sof_dsp_ops sof_byt_ops = {
        .block_write    = sof_block_write,
 
        /* doorbell */
-       .irq_handler    = byt_irq_handler,
-       .irq_thread     = byt_irq_thread,
+       .irq_handler    = atom_irq_handler,
+       .irq_thread     = atom_irq_thread,
 
        /* ipc */
-       .send_msg       = byt_send_msg,
+       .send_msg       = atom_send_msg,
        .fw_ready       = sof_fw_ready,
-       .get_mailbox_offset = byt_get_mailbox_offset,
-       .get_window_offset = byt_get_window_offset,
+       .get_mailbox_offset = atom_get_mailbox_offset,
+       .get_window_offset = atom_get_window_offset,
 
        .ipc_msg_data   = intel_ipc_msg_data,
        .ipc_pcm_params = intel_ipc_pcm_params,
 
        /* machine driver */
-       .machine_select = byt_machine_select,
+       .machine_select = atom_machine_select,
        .machine_register = sof_machine_register,
        .machine_unregister = sof_machine_unregister,
-       .set_mach_params = byt_set_mach_params,
+       .set_mach_params = atom_set_mach_params,
 
        /* debug */
        .debug_map      = byt_debugfs,
        .debug_map_count        = ARRAY_SIZE(byt_debugfs),
-       .dbg_dump       = byt_dump,
+       .dbg_dump       = atom_dump,
 
        /* stream callbacks */
        .pcm_open       = intel_pcm_open,
@@ -888,7 +265,7 @@ static const struct snd_sof_dsp_ops sof_byt_ops = {
        .resume = byt_resume,
 
        /* DAI drivers */
-       .drv = byt_dai,
+       .drv = atom_dai,
        .num_drv = 3, /* we have only 3 SSPs on byt*/
 
        /* ALSA HW info flags */
@@ -913,8 +290,8 @@ static const struct snd_sof_dsp_ops sof_cht_ops = {
        .remove         = byt_remove,
 
        /* DSP core boot / reset */
-       .run            = byt_run,
-       .reset          = byt_reset,
+       .run            = atom_run,
+       .reset          = atom_reset,
 
        /* Register IO */
        .write          = sof_io_write,
@@ -927,28 +304,28 @@ static const struct snd_sof_dsp_ops sof_cht_ops = {
        .block_write    = sof_block_write,
 
        /* doorbell */
-       .irq_handler    = byt_irq_handler,
-       .irq_thread     = byt_irq_thread,
+       .irq_handler    = atom_irq_handler,
+       .irq_thread     = atom_irq_thread,
 
        /* ipc */
-       .send_msg       = byt_send_msg,
+       .send_msg       = atom_send_msg,
        .fw_ready       = sof_fw_ready,
-       .get_mailbox_offset = byt_get_mailbox_offset,
-       .get_window_offset = byt_get_window_offset,
+       .get_mailbox_offset = atom_get_mailbox_offset,
+       .get_window_offset = atom_get_window_offset,
 
        .ipc_msg_data   = intel_ipc_msg_data,
        .ipc_pcm_params = intel_ipc_pcm_params,
 
        /* machine driver */
-       .machine_select = byt_machine_select,
+       .machine_select = atom_machine_select,
        .machine_register = sof_machine_register,
        .machine_unregister = sof_machine_unregister,
-       .set_mach_params = byt_set_mach_params,
+       .set_mach_params = atom_set_mach_params,
 
        /* debug */
        .debug_map      = cht_debugfs,
        .debug_map_count        = ARRAY_SIZE(cht_debugfs),
-       .dbg_dump       = byt_dump,
+       .dbg_dump       = atom_dump,
 
        /* stream callbacks */
        .pcm_open       = intel_pcm_open,
@@ -965,9 +342,9 @@ static const struct snd_sof_dsp_ops sof_cht_ops = {
        .resume = byt_resume,
 
        /* DAI drivers */
-       .drv = byt_dai,
+       .drv = atom_dai,
        /* all 6 SSPs may be available for cherrytrail */
-       .num_drv = ARRAY_SIZE(byt_dai),
+       .num_drv = 6,
 
        /* ALSA HW info flags */
        .hw_info =      SNDRV_PCM_INFO_MMAP |
@@ -1073,9 +450,8 @@ static struct platform_driver snd_sof_acpi_intel_byt_driver = {
 };
 module_platform_driver(snd_sof_acpi_intel_byt_driver);
 
-#endif /* CONFIG_SND_SOC_SOF_BAYTRAIL */
-
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC);
 MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
 MODULE_IMPORT_NS(SND_SOC_SOF_ACPI_DEV);
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
index 94b9704..4ee1da3 100644 (file)
 #include <sound/soc-acpi-intel-match.h>
 #include <sound/sof.h>
 #include "../ops.h"
+#include "atom.h"
+#include "shim.h"
 #include "../sof-pci-dev.h"
+#include "../sof-audio.h"
 
 /* platform specific devices */
 #include "shim.h"
@@ -29,6 +32,170 @@ static struct snd_soc_acpi_mach sof_tng_machines[] = {
        {}
 };
 
+static const struct snd_sof_debugfs_map tng_debugfs[] = {
+       {"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+       {"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
+        SOF_DEBUGFS_ACCESS_D0_ONLY},
+       {"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
+        SOF_DEBUGFS_ACCESS_D0_ONLY},
+       {"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT,
+        SOF_DEBUGFS_ACCESS_ALWAYS},
+};
+
+static int tangier_pci_probe(struct snd_sof_dev *sdev)
+{
+       struct snd_sof_pdata *pdata = sdev->pdata;
+       const struct sof_dev_desc *desc = pdata->desc;
+       struct pci_dev *pci = to_pci_dev(sdev->dev);
+       u32 base, size;
+       int ret;
+
+       /* DSP DMA can only access low 31 bits of host memory */
+       ret = dma_coerce_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31));
+       if (ret < 0) {
+               dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
+               return ret;
+       }
+
+       /* LPE base */
+       base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET;
+       size = PCI_BAR_SIZE;
+
+       dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
+       sdev->bar[DSP_BAR] = devm_ioremap(sdev->dev, base, size);
+       if (!sdev->bar[DSP_BAR]) {
+               dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
+                       base, size);
+               return -ENODEV;
+       }
+       dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[DSP_BAR]);
+
+       /* IMR base - optional */
+       if (desc->resindex_imr_base == -1)
+               goto irq;
+
+       base = pci_resource_start(pci, desc->resindex_imr_base);
+       size = pci_resource_len(pci, desc->resindex_imr_base);
+
+       /* some BIOSes don't map IMR */
+       if (base == 0x55aa55aa || base == 0x0) {
+               dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
+               goto irq;
+       }
+
+       dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
+       sdev->bar[IMR_BAR] = devm_ioremap(sdev->dev, base, size);
+       if (!sdev->bar[IMR_BAR]) {
+               dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
+                       base, size);
+               return -ENODEV;
+       }
+       dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[IMR_BAR]);
+
+irq:
+       /* register our IRQ */
+       sdev->ipc_irq = pci->irq;
+       dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
+       ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
+                                       atom_irq_handler, atom_irq_thread,
+                                       0, "AudioDSP", sdev);
+       if (ret < 0) {
+               dev_err(sdev->dev, "error: failed to register IRQ %d\n",
+                       sdev->ipc_irq);
+               return ret;
+       }
+
+       /* enable BUSY and disable DONE Interrupt by default */
+       snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX,
+                                 SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
+                                 SHIM_IMRX_DONE);
+
+       /* set default mailbox offset for FW ready message */
+       sdev->dsp_box.offset = MBOX_OFFSET;
+
+       return ret;
+}
+
+const struct snd_sof_dsp_ops sof_tng_ops = {
+       /* device init */
+       .probe          = tangier_pci_probe,
+
+       /* DSP core boot / reset */
+       .run            = atom_run,
+       .reset          = atom_reset,
+
+       /* Register IO */
+       .write          = sof_io_write,
+       .read           = sof_io_read,
+       .write64        = sof_io_write64,
+       .read64         = sof_io_read64,
+
+       /* Block IO */
+       .block_read     = sof_block_read,
+       .block_write    = sof_block_write,
+
+       /* doorbell */
+       .irq_handler    = atom_irq_handler,
+       .irq_thread     = atom_irq_thread,
+
+       /* ipc */
+       .send_msg       = atom_send_msg,
+       .fw_ready       = sof_fw_ready,
+       .get_mailbox_offset = atom_get_mailbox_offset,
+       .get_window_offset = atom_get_window_offset,
+
+       .ipc_msg_data   = intel_ipc_msg_data,
+       .ipc_pcm_params = intel_ipc_pcm_params,
+
+       /* machine driver */
+       .machine_select = atom_machine_select,
+       .machine_register = sof_machine_register,
+       .machine_unregister = sof_machine_unregister,
+       .set_mach_params = atom_set_mach_params,
+
+       /* debug */
+       .debug_map      = tng_debugfs,
+       .debug_map_count        = ARRAY_SIZE(tng_debugfs),
+       .dbg_dump       = atom_dump,
+
+       /* stream callbacks */
+       .pcm_open       = intel_pcm_open,
+       .pcm_close      = intel_pcm_close,
+
+       /* module loading */
+       .load_module    = snd_sof_parse_module_memcpy,
+
+       /*Firmware loading */
+       .load_firmware  = snd_sof_load_firmware_memcpy,
+
+       /* DAI drivers */
+       .drv = atom_dai,
+       .num_drv = 3, /* we have only 3 SSPs on byt*/
+
+       /* ALSA HW info flags */
+       .hw_info =      SNDRV_PCM_INFO_MMAP |
+                       SNDRV_PCM_INFO_MMAP_VALID |
+                       SNDRV_PCM_INFO_INTERLEAVED |
+                       SNDRV_PCM_INFO_PAUSE |
+                       SNDRV_PCM_INFO_BATCH,
+
+       .arch_ops = &sof_xtensa_arch_ops,
+};
+
+const struct sof_intel_dsp_desc tng_chip_info = {
+       .cores_num = 1,
+       .host_managed_cores_mask = 1,
+};
+
 static const struct sof_dev_desc tng_desc = {
        .machines               = sof_tng_machines,
        .resindex_lpe_base      = 3,    /* IRAM, but subtract IRAM offset */
@@ -66,5 +233,7 @@ static struct pci_driver snd_sof_pci_intel_tng_driver = {
 module_pci_driver(snd_sof_pci_intel_tng_driver);
 
 MODULE_LICENSE("Dual BSD/GPL");
-MODULE_IMPORT_NS(SND_SOC_SOF_MERRIFIELD);
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC);
+MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
 MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV);
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_ATOM_HIFI_EP);