Merge branch 'fix/intel' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorMark Brown <broonie@kernel.org>
Mon, 8 Jan 2018 15:54:50 +0000 (15:54 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 8 Jan 2018 15:54:50 +0000 (15:54 +0000)
1  2 
include/uapi/sound/snd_sst_tokens.h
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl-nhlt.c
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-sst-utils.c
sound/soc/intel/skylake/skl-topology.c

index 9e38fea11b2b951df5bd822a8d212cd84a05bc8c,326054a72bc7e9ca240a39128be9585531c025cc..8ba0112e533688a26cb3012be334fbc35c9c4e67
@@@ -1,3 -1,4 +1,4 @@@
+ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
  /*
   * snd_sst_tokens.h - Intel SST tokens definition
   *
   * %SKL_TKN_MM_U32_NUM_IN_FMT:  Number of input formats
   * %SKL_TKN_MM_U32_NUM_OUT_FMT: Number of output formats
   *
 + * %SKL_TKN_U32_ASTATE_IDX:     Table Index for the A-State entry to be filled
 + *                              with kcps and clock source
 + *
 + * %SKL_TKN_U32_ASTATE_COUNT:   Number of valid entries in A-State table
 + *
 + * %SKL_TKN_U32_ASTATE_KCPS:    Specifies the core load threshold (in kilo
 + *                              cycles per second) below which DSP is clocked
 + *                              from source specified by clock source.
 + *
 + * %SKL_TKN_U32_ASTATE_CLK_SRC: Clock source for A-State entry
 + *
   * module_id and loadable flags dont have tokens as these values will be
   * read from the DSP FW manifest
   *
@@@ -319,11 -309,7 +320,11 @@@ enum SKL_TKNS 
        SKL_TKN_MM_U32_NUM_IN_FMT,
        SKL_TKN_MM_U32_NUM_OUT_FMT,
  
 -      SKL_TKN_MAX = SKL_TKN_MM_U32_NUM_OUT_FMT,
 +      SKL_TKN_U32_ASTATE_IDX,
 +      SKL_TKN_U32_ASTATE_COUNT,
 +      SKL_TKN_U32_ASTATE_KCPS,
 +      SKL_TKN_U32_ASTATE_CLK_SRC,
 +      SKL_TKN_MAX = SKL_TKN_U32_ASTATE_CLK_SRC,
  };
  
  #endif
index 38512f0d1a731fd44d29c4703ecda897adf8cc41,6072164f2d43db7c7f8f50000892f6e61e80d79c..5ae0459d59c2bacb5fae0953f621930ceafbccaf
@@@ -195,7 -195,7 +195,7 @@@ static int kabylake_rt5663_codec_init(s
        }
  
        jack = &ctx->kabylake_headset;
 -      snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
 +      snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
        snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
        snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
        snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
@@@ -605,6 -605,8 +605,8 @@@ static int kabylake_card_late_probe(str
  
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
                codec = pcm->codec_dai->codec;
+               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, &ctx->kabylake_hdmi[i],
                                NULL, 0);
index 933c1fbb222ff96eac9ba03427cb2c1cbb764732,61b5bfa79d1325b5a42e69119ccb1e39c20c0b6c..8cbf080c38b3ef1acfcecb8f869bfbcee59eb732
@@@ -55,19 -55,6 +55,19 @@@ static int skl_free_dma_buf(struct devi
        return 0;
  }
  
 +#define SKL_ASTATE_PARAM_ID   4
 +
 +void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data)
 +{
 +      struct skl_ipc_large_config_msg msg = {0};
 +
 +      msg.large_param_id = SKL_ASTATE_PARAM_ID;
 +      msg.param_data_size = (cnt * sizeof(struct skl_astate_param) +
 +                              sizeof(cnt));
 +
 +      skl_ipc_set_large_config(&ctx->ipc, &msg, data);
 +}
 +
  #define NOTIFICATION_PARAM_ID 3
  #define NOTIFICATION_MASK 0xf
  
@@@ -417,20 -404,11 +417,20 @@@ int skl_resume_dsp(struct skl *skl
        if (skl->skl_sst->is_first_boot == true)
                return 0;
  
 +      /* disable dynamic clock gating during fw and lib download */
 +      ctx->enable_miscbdcge(ctx->dev, false);
 +
        ret = skl_dsp_wake(ctx->dsp);
 +      ctx->enable_miscbdcge(ctx->dev, true);
        if (ret < 0)
                return ret;
  
        skl_dsp_enable_notification(skl->skl_sst, false);
 +
 +      if (skl->cfg.astate_cfg != NULL) {
 +              skl_dsp_set_astate_cfg(skl->skl_sst, skl->cfg.astate_cfg->count,
 +                                      skl->cfg.astate_cfg);
 +      }
        return ret;
  }
  
@@@ -729,18 -707,11 +729,11 @@@ static void skl_set_updown_mixer_format
        struct skl_module *module = mconfig->module;
        struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx];
        struct skl_module_fmt *fmt = &iface->outputs[0].fmt;
-       int i = 0;
  
        skl_set_base_module_format(ctx, mconfig,
                (struct skl_base_cfg *)mixer_mconfig);
        mixer_mconfig->out_ch_cfg = fmt->ch_cfg;
-       /* Select F/W default coefficient */
-       mixer_mconfig->coeff_sel = 0x0;
-       /* User coeff, don't care since we are selecting F/W defaults */
-       for (i = 0; i < UP_DOWN_MIXER_MAX_COEFF; i++)
-               mixer_mconfig->coeff[i] = 0xDEADBEEF;
+       mixer_mconfig->ch_map = fmt->ch_map;
  }
  
  /*
index bde7f40f29f5c61da3c2794d10a5ace90f69a03a,1ce414d86d8a422969719aa755692a8c20ca11b4..d9b3dc89a1dc49cefbe7d5d89907b72c261a9ba9
   */
  #include <linux/pci.h>
  #include "skl.h"
 +#include "skl-i2s.h"
  
+ #define NHLT_ACPI_HEADER_SIG  "NHLT"
  /* Unique identification for getting NHLT blobs */
  static guid_t osc_guid =
        GUID_INIT(0xA69F886E, 0x6CEB, 0x4594,
@@@ -42,10 -43,18 +44,18 @@@ struct nhlt_acpi_table *skl_nhlt_init(s
        obj = acpi_evaluate_dsm(handle, &osc_guid, 1, 1, NULL);
        if (obj && obj->type == ACPI_TYPE_BUFFER) {
                nhlt_ptr = (struct nhlt_resource_desc  *)obj->buffer.pointer;
-               nhlt_table = (struct nhlt_acpi_table *)
+               if (nhlt_ptr->length)
+                       nhlt_table = (struct nhlt_acpi_table *)
                                memremap(nhlt_ptr->min_addr, nhlt_ptr->length,
                                MEMREMAP_WB);
                ACPI_FREE(obj);
+               if (nhlt_table && (strncmp(nhlt_table->header.signature,
+                                       NHLT_ACPI_HEADER_SIG,
+                                       strlen(NHLT_ACPI_HEADER_SIG)) != 0)) {
+                       memunmap(nhlt_table);
+                       dev_err(dev, "NHLT ACPI header signature incorrect\n");
+                       return NULL;
+               }
                return nhlt_table;
        }
  
@@@ -263,157 -272,3 +273,157 @@@ void skl_nhlt_remove_sysfs(struct skl *
  
        sysfs_remove_file(&dev->kobj, &dev_attr_platform_id.attr);
  }
 +
 +/*
 + * Queries NHLT for all the fmt configuration for a particular endpoint and
 + * stores all possible rates supported in a rate table for the corresponding
 + * sclk/sclkfs.
 + */
 +static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
 +                              struct nhlt_fmt *fmt, u8 id)
 +{
 +      struct skl_i2s_config_blob_legacy *i2s_config;
 +      struct skl_clk_parent_src *parent;
 +      struct skl_ssp_clk *sclk, *sclkfs;
 +      struct nhlt_fmt_cfg *fmt_cfg;
 +      struct wav_fmt_ext *wav_fmt;
 +      unsigned long rate = 0;
 +      bool present = false;
 +      int rate_index = 0;
 +      u16 channels, bps;
 +      u8 clk_src;
 +      int i, j;
 +      u32 fs;
 +
 +      sclk = &ssp_clks[SKL_SCLK_OFS];
 +      sclkfs = &ssp_clks[SKL_SCLKFS_OFS];
 +
 +      if (fmt->fmt_count == 0)
 +              return;
 +
 +      for (i = 0; i < fmt->fmt_count; i++) {
 +              fmt_cfg = &fmt->fmt_config[i];
 +              wav_fmt = &fmt_cfg->fmt_ext;
 +
 +              channels = wav_fmt->fmt.channels;
 +              bps = wav_fmt->fmt.bits_per_sample;
 +              fs = wav_fmt->fmt.samples_per_sec;
 +
 +              /*
 +               * In case of TDM configuration on a ssp, there can
 +               * be more than one blob in which channel masks are
 +               * different for each usecase for a specific rate and bps.
 +               * But the sclk rate will be generated for the total
 +               * number of channels used for that endpoint.
 +               *
 +               * So for the given fs and bps, choose blob which has
 +               * the superset of all channels for that endpoint and
 +               * derive the rate.
 +               */
 +              for (j = i; j < fmt->fmt_count; j++) {
 +                      fmt_cfg = &fmt->fmt_config[j];
 +                      wav_fmt = &fmt_cfg->fmt_ext;
 +                      if ((fs == wav_fmt->fmt.samples_per_sec) &&
 +                         (bps == wav_fmt->fmt.bits_per_sample))
 +                              channels = max_t(u16, channels,
 +                                              wav_fmt->fmt.channels);
 +              }
 +
 +              rate = channels * bps * fs;
 +
 +              /* check if the rate is added already to the given SSP's sclk */
 +              for (j = 0; (j < SKL_MAX_CLK_RATES) &&
 +                          (sclk[id].rate_cfg[j].rate != 0); j++) {
 +                      if (sclk[id].rate_cfg[j].rate == rate) {
 +                              present = true;
 +                              break;
 +                      }
 +              }
 +
 +              /* Fill rate and parent for sclk/sclkfs */
 +              if (!present) {
 +                      /* MCLK Divider Source Select */
 +                      i2s_config = (struct skl_i2s_config_blob_legacy *)
 +                                              fmt->fmt_config[0].config.caps;
 +                      clk_src = ((i2s_config->mclk.mdivctrl)
 +                                      & SKL_MNDSS_DIV_CLK_SRC_MASK) >>
 +                                      SKL_SHIFT(SKL_MNDSS_DIV_CLK_SRC_MASK);
 +
 +                      parent = skl_get_parent_clk(clk_src);
 +
 +                      /*
 +                       * Do not copy the config data if there is no parent
 +                       * clock available for this clock source select
 +                       */
 +                      if (!parent)
 +                              continue;
 +
 +                      sclk[id].rate_cfg[rate_index].rate = rate;
 +                      sclk[id].rate_cfg[rate_index].config = fmt_cfg;
 +                      sclkfs[id].rate_cfg[rate_index].rate = rate;
 +                      sclkfs[id].rate_cfg[rate_index].config = fmt_cfg;
 +                      sclk[id].parent_name = parent->name;
 +                      sclkfs[id].parent_name = parent->name;
 +
 +                      rate_index++;
 +              }
 +      }
 +}
 +
 +static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk,
 +                              struct nhlt_fmt *fmt, u8 id)
 +{
 +      struct skl_i2s_config_blob_legacy *i2s_config;
 +      struct nhlt_specific_cfg *fmt_cfg;
 +      struct skl_clk_parent_src *parent;
 +      u32 clkdiv, div_ratio;
 +      u8 clk_src;
 +
 +      fmt_cfg = &fmt->fmt_config[0].config;
 +      i2s_config = (struct skl_i2s_config_blob_legacy *)fmt_cfg->caps;
 +
 +      /* MCLK Divider Source Select */
 +      clk_src = ((i2s_config->mclk.mdivctrl) & SKL_MCLK_DIV_CLK_SRC_MASK) >>
 +                                      SKL_SHIFT(SKL_MCLK_DIV_CLK_SRC_MASK);
 +
 +      clkdiv = i2s_config->mclk.mdivr & SKL_MCLK_DIV_RATIO_MASK;
 +
 +      /* bypass divider */
 +      div_ratio = 1;
 +
 +      if (clkdiv != SKL_MCLK_DIV_RATIO_MASK)
 +              /* Divider is 2 + clkdiv */
 +              div_ratio = clkdiv + 2;
 +
 +      /* Calculate MCLK rate from source using div value */
 +      parent = skl_get_parent_clk(clk_src);
 +      if (!parent)
 +              return;
 +
 +      mclk[id].rate_cfg[0].rate = parent->rate/div_ratio;
 +      mclk[id].rate_cfg[0].config = &fmt->fmt_config[0];
 +      mclk[id].parent_name = parent->name;
 +}
 +
 +void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks)
 +{
 +      struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
 +      struct nhlt_endpoint *epnt;
 +      struct nhlt_fmt *fmt;
 +      int i;
 +      u8 id;
 +
 +      epnt = (struct nhlt_endpoint *)nhlt->desc;
 +      for (i = 0; i < nhlt->endpoint_count; i++) {
 +              if (epnt->linktype == NHLT_LINK_SSP) {
 +                      id = epnt->virtual_bus_id;
 +
 +                      fmt = (struct nhlt_fmt *)(epnt->config.caps
 +                                      + epnt->config.size);
 +
 +                      skl_get_ssp_clks(skl, ssp_clks, fmt, id);
 +                      skl_get_mclk(skl, ssp_clks, fmt, id);
 +              }
 +              epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
 +      }
 +}
index b45a9cd5f058818ac5a54495606613438d66d870,1dd97479e0c014bf1f814f16dd419268529454e0..e4682853382614d83d73bf27a8e5a7ee3810bbca
@@@ -355,7 -355,8 +355,8 @@@ static void skl_pcm_close(struct snd_pc
        }
  
        mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
-       skl_tplg_d0i3_put(skl, mconfig->d0i3_caps);
+       if (mconfig)
+               skl_tplg_d0i3_put(skl, mconfig->d0i3_caps);
  
        kfree(dma_params);
  }
@@@ -536,7 -537,7 +537,7 @@@ static int skl_link_hw_params(struct sn
  
        snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
  
 -      link = snd_hdac_ext_bus_get_link(ebus, rtd->codec->component.name);
 +      link = snd_hdac_ext_bus_get_link(ebus, codec_dai->component->name);
        if (!link)
                return -EINVAL;
  
@@@ -619,7 -620,7 +620,7 @@@ static int skl_link_hw_free(struct snd_
  
        link_dev->link_prepared = 0;
  
 -      link = snd_hdac_ext_bus_get_link(ebus, rtd->codec->component.name);
 +      link = snd_hdac_ext_bus_get_link(ebus, rtd->codec_dai->component->name);
        if (!link)
                return -EINVAL;
  
@@@ -1342,11 -1343,7 +1343,11 @@@ static int skl_platform_soc_probe(struc
                        return -EIO;
                }
  
 +              /* disable dynamic clock gating during fw and lib download */
 +              skl->skl_sst->enable_miscbdcge(platform->dev, false);
 +
                ret = ops->init_fw(platform->dev, skl->skl_sst);
 +              skl->skl_sst->enable_miscbdcge(platform->dev, true);
                if (ret < 0) {
                        dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
                        return ret;
                skl_populate_modules(skl);
                skl->skl_sst->update_d0i3c = skl_update_d0i3c;
                skl_dsp_enable_notification(skl->skl_sst, false);
 +
 +              if (skl->cfg.astate_cfg != NULL) {
 +                      skl_dsp_set_astate_cfg(skl->skl_sst,
 +                                      skl->cfg.astate_cfg->count,
 +                                      skl->cfg.astate_cfg);
 +              }
        }
        pm_runtime_mark_last_busy(platform->dev);
        pm_runtime_put_autosuspend(platform->dev);
index 746df24bfd821d7b175795ad7ae1d474b02025e1,8ff89280d9fd44f11e34121f1dddd7647004c688..2ae405617876281749525db63dad5fffd0e8305d
@@@ -178,8 -178,7 +178,8 @@@ static inline int skl_pvtid_128(struct 
   * skl_get_pvt_id: generate a private id for use as module id
   *
   * @ctx: driver context
 - * @mconfig: module configuration data
 + * @uuid_mod: module's uuid
 + * @instance_id: module's instance id
   *
   * This generates a 128 bit private unique id for a module TYPE so that
   * module instance is unique
@@@ -209,8 -208,7 +209,8 @@@ EXPORT_SYMBOL_GPL(skl_get_pvt_id)
   * skl_put_pvt_id: free up the private id allocated
   *
   * @ctx: driver context
 - * @mconfig: module configuration data
 + * @uuid_mod: module's uuid
 + * @pvt_id: module pvt id
   *
   * This frees a 128 bit private unique id previously generated
   */
@@@ -253,6 -251,7 +253,7 @@@ int snd_skl_parse_uuids(struct sst_dsp 
        struct uuid_module *module;
        struct firmware stripped_fw;
        unsigned int safe_file;
+       int ret = 0;
  
        /* Get the FW pointer to derive ADSP header */
        stripped_fw.data = fw->data;
  
        for (i = 0; i < num_entry; i++, mod_entry++) {
                module = kzalloc(sizeof(*module), GFP_KERNEL);
-               if (!module)
-                       return -ENOMEM;
+               if (!module) {
+                       ret = -ENOMEM;
+                       goto free_uuid_list;
+               }
  
                uuid_bin = (uuid_le *)mod_entry->uuid.id;
                memcpy(&module->uuid, uuid_bin, sizeof(module->uuid));
                size = sizeof(int) * mod_entry->instance_max_count;
                module->instance_id = devm_kzalloc(ctx->dev, size, GFP_KERNEL);
                if (!module->instance_id) {
-                       kfree(module);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto free_uuid_list;
                }
  
                list_add_tail(&module->list, &skl->uuid_list);
        }
  
        return 0;
+ free_uuid_list:
+       skl_freeup_uuid_list(skl);
+       return ret;
  }
  
  void skl_freeup_uuid_list(struct skl_sst *ctx)
index d8d110b3be0122a7c518775dd0f8e6530df4bb81,a072bcf209d2aa4c9c72503466e027e6867cd9bb..6a5f8462c3804070f19ece3bf7e5e66e7602df38
@@@ -2036,21 -2036,45 +2036,45 @@@ static int skl_tplg_add_pipe(struct dev
        return 0;
  }
  
- static int skl_tplg_fill_pin(struct device *dev, u32 tkn,
+ static int skl_tplg_get_uuid(struct device *dev, u8 *guid,
+             struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
+ {
+       if (uuid_tkn->token == SKL_TKN_UUID) {
+               memcpy(guid, &uuid_tkn->uuid, 16);
+               return 0;
+       }
+       dev_err(dev, "Not an UUID token %d\n", uuid_tkn->token);
+       return -EINVAL;
+ }
+ static int skl_tplg_fill_pin(struct device *dev,
+                       struct snd_soc_tplg_vendor_value_elem *tkn_elem,
                        struct skl_module_pin *m_pin,
-                       int pin_index, u32 value)
+                       int pin_index)
  {
-       switch (tkn) {
+       int ret;
+       switch (tkn_elem->token) {
        case SKL_TKN_U32_PIN_MOD_ID:
-               m_pin[pin_index].id.module_id = value;
+               m_pin[pin_index].id.module_id = tkn_elem->value;
                break;
  
        case SKL_TKN_U32_PIN_INST_ID:
-               m_pin[pin_index].id.instance_id = value;
+               m_pin[pin_index].id.instance_id = tkn_elem->value;
+               break;
+       case SKL_TKN_UUID:
+               ret = skl_tplg_get_uuid(dev, m_pin[pin_index].id.mod_uuid.b,
+                       (struct snd_soc_tplg_vendor_uuid_elem *)tkn_elem);
+               if (ret < 0)
+                       return ret;
                break;
  
        default:
-               dev_err(dev, "%d Not a pin token\n", value);
+               dev_err(dev, "%d Not a pin token\n", tkn_elem->token);
                return -EINVAL;
        }
  
@@@ -2083,9 -2107,7 +2107,7 @@@ static int skl_tplg_fill_pins_info(stru
                return -EINVAL;
        }
  
-       ret = skl_tplg_fill_pin(dev, tkn_elem->token,
-                       m_pin, pin_count, tkn_elem->value);
+       ret = skl_tplg_fill_pin(dev, tkn_elem, m_pin, pin_count);
        if (ret < 0)
                return ret;
  
@@@ -2170,19 -2192,6 +2192,6 @@@ static int skl_tplg_widget_fill_fmt(str
        return skl_tplg_fill_fmt(dev, dst_fmt, tkn, val);
  }
  
- static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig,
-             struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
- {
-       if (uuid_tkn->token == SKL_TKN_UUID)
-               memcpy(&mconfig->guid, &uuid_tkn->uuid, 16);
-       else {
-               dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token);
-               return -EINVAL;
-       }
-       return 0;
- }
  static void skl_tplg_fill_pin_dynamic_val(
                struct skl_module_pin *mpin, u32 pin_count, u32 value)
  {
@@@ -2382,7 -2391,7 +2391,7 @@@ static int skl_tplg_get_token(struct de
        case SKL_TKN_U32_MAX_MCPS:
        case SKL_TKN_U32_OBS:
        case SKL_TKN_U32_IBS:
-               ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, dir, pin_index);
+               ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, pin_index, dir);
                if (ret < 0)
                        return ret;
  
  
        case SKL_TKN_U32_PIN_MOD_ID:
        case SKL_TKN_U32_PIN_INST_ID:
+       case SKL_TKN_UUID:
                ret = skl_tplg_fill_pins_info(dev,
                                mconfig, tkn_elem, dir,
                                pin_index);
@@@ -2550,6 -2560,7 +2560,7 @@@ static int skl_tplg_get_tokens(struct d
        struct snd_soc_tplg_vendor_value_elem *tkn_elem;
        int tkn_count = 0, ret;
        int off = 0, tuple_size = 0;
+       bool is_module_guid = true;
  
        if (block_size <= 0)
                return -EINVAL;
                        continue;
  
                case SND_SOC_TPLG_TUPLE_TYPE_UUID:
-                       ret = skl_tplg_get_uuid(dev, mconfig, array->uuid);
+                       if (is_module_guid) {
+                               ret = skl_tplg_get_uuid(dev, mconfig->guid,
+                                                       array->uuid);
+                               is_module_guid = false;
+                       } else {
+                               ret = skl_tplg_get_token(dev, array->value, skl,
+                                                        mconfig);
+                       }
                        if (ret < 0)
                                return ret;
  
@@@ -3037,13 -3056,11 +3056,13 @@@ static int skl_tplg_get_int_tkn(struct 
                struct snd_soc_tplg_vendor_value_elem *tkn_elem,
                struct skl *skl)
  {
 -      int tkn_count = 0, ret;
 +      int tkn_count = 0, ret, size;
        static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx;
        struct skl_module_res *res = NULL;
        struct skl_module_iface *fmt = NULL;
        struct skl_module *mod = NULL;
 +      static struct skl_astate_param *astate_table;
 +      static int astate_cfg_idx, count;
        int i;
  
        if (skl->modules) {
                mod_idx = tkn_elem->value;
                break;
  
 +      case SKL_TKN_U32_ASTATE_COUNT:
 +              if (astate_table != NULL) {
 +                      dev_err(dev, "More than one entry for A-State count");
 +                      return -EINVAL;
 +              }
 +
 +              if (tkn_elem->value > SKL_MAX_ASTATE_CFG) {
 +                      dev_err(dev, "Invalid A-State count %d\n",
 +                              tkn_elem->value);
 +                      return -EINVAL;
 +              }
 +
 +              size = tkn_elem->value * sizeof(struct skl_astate_param) +
 +                              sizeof(count);
 +              skl->cfg.astate_cfg = devm_kzalloc(dev, size, GFP_KERNEL);
 +              if (!skl->cfg.astate_cfg)
 +                      return -ENOMEM;
 +
 +              astate_table = skl->cfg.astate_cfg->astate_table;
 +              count = skl->cfg.astate_cfg->count = tkn_elem->value;
 +              break;
 +
 +      case SKL_TKN_U32_ASTATE_IDX:
 +              if (tkn_elem->value >= count) {
 +                      dev_err(dev, "Invalid A-State index %d\n",
 +                              tkn_elem->value);
 +                      return -EINVAL;
 +              }
 +
 +              astate_cfg_idx = tkn_elem->value;
 +              break;
 +
 +      case SKL_TKN_U32_ASTATE_KCPS:
 +              astate_table[astate_cfg_idx].kcps = tkn_elem->value;
 +              break;
 +
 +      case SKL_TKN_U32_ASTATE_CLK_SRC:
 +              astate_table[astate_cfg_idx].clk_src = tkn_elem->value;
 +              break;
 +
        case SKL_TKN_U8_IN_PIN_TYPE:
        case SKL_TKN_U8_OUT_PIN_TYPE:
        case SKL_TKN_U8_IN_QUEUE_COUNT: