Merge branch 'topic/component' of git://git.kernel.org/pub/scm/linux/kernel/git/broon...
authorMark Brown <broonie@kernel.org>
Tue, 10 Oct 2017 09:23:08 +0000 (10:23 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 10 Oct 2017 09:23:08 +0000 (10:23 +0100)
1  2 
include/sound/soc.h
sound/soc/soc-core.c

diff --combined include/sound/soc.h
index 11ca867033bd7d906056c581343f97070bdd4689,580da1e4f1418908098c0e1a46b571f5f7ea0324..eea3007a28f1a4592a1a482d48fc33bc137a0098
@@@ -468,6 -468,11 +468,11 @@@ int snd_soc_register_codec(struct devic
                const struct snd_soc_codec_driver *codec_drv,
                struct snd_soc_dai_driver *dai_drv, int num_dai);
  void snd_soc_unregister_codec(struct device *dev);
+ int snd_soc_add_component(struct device *dev,
+               struct snd_soc_component *component,
+               const struct snd_soc_component_driver *component_driver,
+               struct snd_soc_dai_driver *dai_drv,
+               int num_dai);
  int snd_soc_register_component(struct device *dev,
                         const struct snd_soc_component_driver *component_driver,
                         struct snd_soc_dai_driver *dai_drv, int num_dai);
@@@ -475,8 -480,6 +480,8 @@@ int devm_snd_soc_register_component(str
                         const struct snd_soc_component_driver *component_driver,
                         struct snd_soc_dai_driver *dai_drv, int num_dai);
  void snd_soc_unregister_component(struct device *dev);
 +struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
 +                                                 const char *driver_name);
  int snd_soc_cache_init(struct snd_soc_codec *codec);
  int snd_soc_cache_exit(struct snd_soc_codec *codec);
  
@@@ -797,10 -800,6 +802,10 @@@ struct snd_soc_component_driver 
        int (*suspend)(struct snd_soc_component *);
        int (*resume)(struct snd_soc_component *);
  
 +      /* pcm creation and destruction */
 +      int (*pcm_new)(struct snd_soc_pcm_runtime *);
 +      void (*pcm_free)(struct snd_pcm *);
 +
        /* component wide operations */
        int (*set_sysclk)(struct snd_soc_component *component,
                          int clk_id, int source, unsigned int freq, int dir);
        void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
                int subseq);
        int (*stream_event)(struct snd_soc_component *, int event);
 +      int (*set_bias_level)(struct snd_soc_component *component,
 +                            enum snd_soc_bias_level level);
  
        /* probe ordering - for components with runtime dependencies */
        int probe_order;
        int remove_order;
 +
 +      /* bits */
 +      unsigned int idle_bias_on:1;
 +      unsigned int suspend_bias_off:1;
  };
  
  struct snd_soc_component {
        void (*remove)(struct snd_soc_component *);
        int (*suspend)(struct snd_soc_component *);
        int (*resume)(struct snd_soc_component *);
 +      int (*pcm_new)(struct snd_soc_component *, struct snd_soc_pcm_runtime *);
 +      void (*pcm_free)(struct snd_soc_component *, struct snd_pcm *);
  
        int (*set_sysclk)(struct snd_soc_component *component,
                          int clk_id, int source, unsigned int freq, int dir);
                       int source, unsigned int freq_in, unsigned int freq_out);
        int (*set_jack)(struct snd_soc_component *component,
                        struct snd_soc_jack *jack,  void *data);
 +      int (*set_bias_level)(struct snd_soc_component *component,
 +                            enum snd_soc_bias_level level);
  
        /* machine specific init */
        int (*init)(struct snd_soc_component *component);
diff --combined sound/soc/soc-core.c
index 6ec127346e9c457df78ba125cb274029ca895fdf,3a1c3b44de5e0f0d77372d989786d8d816bd1649..166b6d218fe5c1f0da73c9a69b6d0e574c35df52
@@@ -614,8 -614,6 +614,8 @@@ struct snd_pcm_substream *snd_soc_get_d
  }
  EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream);
  
 +static const struct snd_soc_ops null_snd_soc_ops;
 +
  static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
        struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
  {
        INIT_LIST_HEAD(&rtd->component_list);
        rtd->card = card;
        rtd->dai_link = dai_link;
 +      if (!rtd->dai_link->ops)
 +              rtd->dai_link->ops = &null_snd_soc_ops;
 +
        rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) *
                                        dai_link->num_codecs,
                                        GFP_KERNEL);
  
  static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
  {
 -      if (rtd && rtd->codec_dais)
 -              kfree(rtd->codec_dais);
 +      kfree(rtd->codec_dais);
        snd_soc_rtdcom_del_all(rtd);
        kfree(rtd);
  }
@@@ -2636,7 -2632,7 +2636,7 @@@ EXPORT_SYMBOL_GPL(snd_soc_add_dai_contr
  int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
        unsigned int freq, int dir)
  {
 -      if (dai->driver && dai->driver->ops->set_sysclk)
 +      if (dai->driver->ops->set_sysclk)
                return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
  
        return snd_soc_component_set_sysclk(dai->component, clk_id, 0,
@@@ -2704,7 -2700,7 +2704,7 @@@ EXPORT_SYMBOL_GPL(snd_soc_component_set
  int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
        int div_id, int div)
  {
 -      if (dai->driver && dai->driver->ops->set_clkdiv)
 +      if (dai->driver->ops->set_clkdiv)
                return dai->driver->ops->set_clkdiv(dai, div_id, div);
        else
                return -EINVAL;
@@@ -2724,7 -2720,7 +2724,7 @@@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdi
  int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
        unsigned int freq_in, unsigned int freq_out)
  {
 -      if (dai->driver && dai->driver->ops->set_pll)
 +      if (dai->driver->ops->set_pll)
                return dai->driver->ops->set_pll(dai, pll_id, source,
                                         freq_in, freq_out);
  
@@@ -2790,7 -2786,7 +2790,7 @@@ EXPORT_SYMBOL_GPL(snd_soc_component_set
   */
  int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
  {
 -      if (dai->driver && dai->driver->ops->set_bclk_ratio)
 +      if (dai->driver->ops->set_bclk_ratio)
                return dai->driver->ops->set_bclk_ratio(dai, ratio);
        else
                return -EINVAL;
@@@ -2864,7 -2860,7 +2864,7 @@@ static int snd_soc_xlate_tdm_slot_mask(
  int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
        unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
  {
 -      if (dai->driver && dai->driver->ops->xlate_tdm_slot_mask)
 +      if (dai->driver->ops->xlate_tdm_slot_mask)
                dai->driver->ops->xlate_tdm_slot_mask(slots,
                                                &tx_mask, &rx_mask);
        else
        dai->tx_mask = tx_mask;
        dai->rx_mask = rx_mask;
  
 -      if (dai->driver && dai->driver->ops->set_tdm_slot)
 +      if (dai->driver->ops->set_tdm_slot)
                return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
                                slots, slot_width);
        else
@@@ -2897,7 -2893,7 +2897,7 @@@ int snd_soc_dai_set_channel_map(struct 
        unsigned int tx_num, unsigned int *tx_slot,
        unsigned int rx_num, unsigned int *rx_slot)
  {
 -      if (dai->driver && dai->driver->ops->set_channel_map)
 +      if (dai->driver->ops->set_channel_map)
                return dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
                        rx_num, rx_slot);
        else
@@@ -2914,7 -2910,7 +2914,7 @@@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_chann
   */
  int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
  {
 -      if (dai->driver && dai->driver->ops->set_tristate)
 +      if (dai->driver->ops->set_tristate)
                return dai->driver->ops->set_tristate(dai, tristate);
        else
                return -EINVAL;
@@@ -3254,30 -3250,6 +3254,30 @@@ static int snd_soc_component_stream_eve
        return component->driver->stream_event(component, event);
  }
  
 +static int snd_soc_component_drv_pcm_new(struct snd_soc_component *component,
 +                                      struct snd_soc_pcm_runtime *rtd)
 +{
 +      if (component->driver->pcm_new)
 +              return component->driver->pcm_new(rtd);
 +
 +      return 0;
 +}
 +
 +static void snd_soc_component_drv_pcm_free(struct snd_soc_component *component,
 +                                        struct snd_pcm *pcm)
 +{
 +      if (component->driver->pcm_free)
 +              component->driver->pcm_free(pcm);
 +}
 +
 +static int snd_soc_component_set_bias_level(struct snd_soc_dapm_context *dapm,
 +                                      enum snd_soc_bias_level level)
 +{
 +      struct snd_soc_component *component = dapm->component;
 +
 +      return component->driver->set_bias_level(component, level);
 +}
 +
  static int snd_soc_component_initialize(struct snd_soc_component *component,
        const struct snd_soc_component_driver *driver, struct device *dev)
  {
        component->set_sysclk = component->driver->set_sysclk;
        component->set_pll = component->driver->set_pll;
        component->set_jack = component->driver->set_jack;
 +      component->pcm_new = snd_soc_component_drv_pcm_new;
 +      component->pcm_free = snd_soc_component_drv_pcm_free;
  
        dapm = snd_soc_component_get_dapm(component);
        dapm->dev = dev;
        dapm->component = component;
        dapm->bias_level = SND_SOC_BIAS_OFF;
 -      dapm->idle_bias_off = true;
 +      dapm->idle_bias_off = !driver->idle_bias_on;
 +      dapm->suspend_bias_off = driver->suspend_bias_off;
        if (driver->seq_notifier)
                dapm->seq_notifier = snd_soc_component_seq_notifier;
        if (driver->stream_event)
                dapm->stream_event = snd_soc_component_stream_event;
 +      if (driver->set_bias_level)
 +              dapm->set_bias_level = snd_soc_component_set_bias_level;
  
        INIT_LIST_HEAD(&component->dai_list);
        mutex_init(&component->io_mutex);
@@@ -3404,20 -3371,14 +3404,14 @@@ static void snd_soc_component_del_unloc
        list_del(&component->list);
  }
  
- int snd_soc_register_component(struct device *dev,
-                              const struct snd_soc_component_driver *component_driver,
-                              struct snd_soc_dai_driver *dai_drv,
-                              int num_dai)
+ int snd_soc_add_component(struct device *dev,
+                       struct snd_soc_component *component,
+                       const struct snd_soc_component_driver *component_driver,
+                       struct snd_soc_dai_driver *dai_drv,
+                       int num_dai)
  {
-       struct snd_soc_component *component;
        int ret;
  
-       component = kzalloc(sizeof(*component), GFP_KERNEL);
-       if (!component) {
-               dev_err(dev, "ASoC: Failed to allocate memory\n");
-               return -ENOMEM;
-       }
        ret = snd_soc_component_initialize(component, component_driver, dev);
        if (ret)
                goto err_free;
@@@ -3441,6 -3402,24 +3435,24 @@@ err_free
        kfree(component);
        return ret;
  }
+ EXPORT_SYMBOL_GPL(snd_soc_add_component);
+ int snd_soc_register_component(struct device *dev,
+                       const struct snd_soc_component_driver *component_driver,
+                       struct snd_soc_dai_driver *dai_drv,
+                       int num_dai)
+ {
+       struct snd_soc_component *component;
+       component = kzalloc(sizeof(*component), GFP_KERNEL);
+       if (!component) {
+               dev_err(dev, "ASoC: Failed to allocate memory\n");
+               return -ENOMEM;
+       }
+       return snd_soc_add_component(dev, component, component_driver,
+                                    dai_drv, num_dai);
+ }
  EXPORT_SYMBOL_GPL(snd_soc_register_component);
  
  /**
@@@ -3481,32 -3460,6 +3493,32 @@@ void snd_soc_unregister_component(struc
  }
  EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
  
 +struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
 +                                                 const char *driver_name)
 +{
 +      struct snd_soc_component *component;
 +      struct snd_soc_component *ret;
 +
 +      ret = NULL;
 +      mutex_lock(&client_mutex);
 +      list_for_each_entry(component, &component_list, list) {
 +              if (dev != component->dev)
 +                      continue;
 +
 +              if (driver_name &&
 +                  (driver_name != component->driver->name) &&
 +                  (strcmp(component->driver->name, driver_name) != 0))
 +                      continue;
 +
 +              ret = component;
 +              break;
 +      }
 +      mutex_unlock(&client_mutex);
 +
 +      return ret;
 +}
 +EXPORT_SYMBOL_GPL(snd_soc_lookup_component);
 +
  static int snd_soc_platform_drv_probe(struct snd_soc_component *component)
  {
        struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
@@@ -3521,26 -3474,6 +3533,26 @@@ static void snd_soc_platform_drv_remove
        platform->driver->remove(platform);
  }
  
 +static int snd_soc_platform_drv_pcm_new(struct snd_soc_component *component,
 +                                      struct snd_soc_pcm_runtime *rtd)
 +{
 +      struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
 +
 +      if (platform->driver->pcm_new)
 +              return platform->driver->pcm_new(rtd);
 +
 +      return 0;
 +}
 +
 +static void snd_soc_platform_drv_pcm_free(struct snd_soc_component *component,
 +                                        struct snd_pcm *pcm)
 +{
 +      struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
 +
 +      if (platform->driver->pcm_free)
 +              platform->driver->pcm_free(pcm);
 +}
 +
  /**
   * snd_soc_add_platform - Add a platform to the ASoC core
   * @dev: The parent device for the platform
@@@ -3564,10 -3497,6 +3576,10 @@@ int snd_soc_add_platform(struct device 
                platform->component.probe = snd_soc_platform_drv_probe;
        if (platform_drv->remove)
                platform->component.remove = snd_soc_platform_drv_remove;
 +      if (platform_drv->pcm_new)
 +              platform->component.pcm_new = snd_soc_platform_drv_pcm_new;
 +      if (platform_drv->pcm_free)
 +              platform->component.pcm_free = snd_soc_platform_drv_pcm_free;
  
  #ifdef CONFIG_DEBUG_FS
        platform->component.debugfs_prefix = "platform";