Merge remote-tracking branch 'asoc/topic/component' into asoc-next
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 12 Apr 2013 12:56:56 +0000 (13:56 +0100)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 12 Apr 2013 12:56:56 +0000 (13:56 +0100)
1  2 
sound/soc/atmel/atmel_ssc_dai.c
sound/soc/fsl/imx-ssi.c
sound/soc/soc-core.c

index 94da62345a276bd2e8e482b73dd7ee4ee027088a,1435f3067d16a7fb69987c29e4514954ddbdc4da..f3fdfa07fcb9fafa76d913b64be070b54d31486e
@@@ -533,49 -533,6 +533,49 @@@ static int atmel_ssc_hw_params(struct s
                break;
  
        case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
 +              /*
 +               * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks.
 +               *
 +               * The SSC transmit clock is obtained from the BCLK signal on
 +               * on the TK line, and the SSC receive clock is
 +               * generated from the transmit clock.
 +               *
 +               * Data is transferred on first BCLK after LRC pulse rising
 +               * edge.If stereo, the right channel data is contiguous with
 +               * the left channel data.
 +               */
 +              rcmr =    SSC_BF(RCMR_PERIOD, 0)
 +                      | SSC_BF(RCMR_STTDLY, START_DELAY)
 +                      | SSC_BF(RCMR_START, SSC_START_RISING_RF)
 +                      | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
 +                      | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
 +                      | SSC_BF(RCMR_CKS, SSC_CKS_PIN);
 +
 +              rfmr =    SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
 +                      | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
 +                      | SSC_BF(RFMR_FSLEN, 0)
 +                      | SSC_BF(RFMR_DATNB, (channels - 1))
 +                      | SSC_BIT(RFMR_MSBF)
 +                      | SSC_BF(RFMR_LOOP, 0)
 +                      | SSC_BF(RFMR_DATLEN, (bits - 1));
 +
 +              tcmr =    SSC_BF(TCMR_PERIOD, 0)
 +                      | SSC_BF(TCMR_STTDLY, START_DELAY)
 +                      | SSC_BF(TCMR_START, SSC_START_RISING_RF)
 +                      | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
 +                      | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
 +                      | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
 +
 +              tfmr =    SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
 +                      | SSC_BF(TFMR_FSDEN, 0)
 +                      | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
 +                      | SSC_BF(TFMR_FSLEN, 0)
 +                      | SSC_BF(TFMR_DATNB, (channels - 1))
 +                      | SSC_BIT(TFMR_MSBF)
 +                      | SSC_BF(TFMR_DATDEF, 0)
 +                      | SSC_BF(TFMR_DATLEN, (bits - 1));
 +              break;
 +
        default:
                printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",
                        ssc_p->daifmt);
@@@ -750,13 -707,18 +750,18 @@@ static struct snd_soc_dai_driver atmel_
                .ops = &atmel_ssc_dai_ops,
  };
  
+ static const struct snd_soc_component_driver atmel_ssc_component = {
+       .name           = "atmel-ssc",
+ };
  static int asoc_ssc_init(struct device *dev)
  {
        struct platform_device *pdev = to_platform_device(dev);
        struct ssc_device *ssc = platform_get_drvdata(pdev);
        int ret;
  
-       ret = snd_soc_register_dai(dev, &atmel_ssc_dai);
+       ret = snd_soc_register_component(dev, &atmel_ssc_component,
+                                        &atmel_ssc_dai, 1);
        if (ret) {
                dev_err(dev, "Could not register DAI: %d\n", ret);
                goto err;
        return 0;
  
  err_unregister_dai:
-       snd_soc_unregister_dai(dev);
+       snd_soc_unregister_component(dev);
  err:
        return ret;
  }
@@@ -790,7 -752,7 +795,7 @@@ static void asoc_ssc_exit(struct devic
        else
                atmel_pcm_pdc_platform_unregister(dev);
  
-       snd_soc_unregister_dai(dev);
+       snd_soc_unregister_component(dev);
  }
  
  /**
diff --combined sound/soc/fsl/imx-ssi.c
index 810c7eeb7b03998d39a69dde175f21a9c8fcee1c,90110ada270d39b4b4e3024c060e3ae3ab875920..4a26d88d723667d2b71e856a78c8c71a74344814
@@@ -413,6 -413,10 +413,10 @@@ static struct snd_soc_dai_driver imx_ac
        .ops = &imx_ssi_pcm_dai_ops,
  };
  
+ static const struct snd_soc_component_driver imx_component = {
+       .name           = DRV_NAME,
+ };
  static void setup_channel_to_ac97(struct imx_ssi *imx_ssi)
  {
        void __iomem *base = imx_ssi->base;
@@@ -496,8 -500,6 +500,8 @@@ static void imx_ssi_ac97_reset(struct s
  
        if (imx_ssi->ac97_reset)
                imx_ssi->ac97_reset(ac97);
 +      /* First read sometimes fails, do a dummy read */
 +      imx_ssi_ac97_read(ac97, 0);
  }
  
  static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
  
        if (imx_ssi->ac97_warm_reset)
                imx_ssi->ac97_warm_reset(ac97);
 +
 +      /* First read sometimes fails, do a dummy read */
 +      imx_ssi_ac97_read(ac97, 0);
  }
  
  struct snd_ac97_bus_ops soc_ac97_ops = {
@@@ -591,7 -590,8 +595,8 @@@ static int imx_ssi_probe(struct platfor
  
        platform_set_drvdata(pdev, ssi);
  
-       ret = snd_soc_register_dai(&pdev->dev, dai);
+       ret = snd_soc_register_component(&pdev->dev, &imx_component,
+                                        dai, 1);
        if (ret) {
                dev_err(&pdev->dev, "register DAI failed\n");
                goto failed_register;
@@@ -632,7 -632,7 +637,7 @@@ failed_pdev_alloc
  failed_pdev_fiq_add:
        platform_device_put(ssi->soc_platform_pdev_fiq);
  failed_pdev_fiq_alloc:
-       snd_soc_unregister_dai(&pdev->dev);
+       snd_soc_unregister_component(&pdev->dev);
  failed_register:
        release_mem_region(res->start, resource_size(res));
  failed_get_resource:
@@@ -650,7 -650,7 +655,7 @@@ static int imx_ssi_remove(struct platfo
        platform_device_unregister(ssi->soc_platform_pdev);
        platform_device_unregister(ssi->soc_platform_pdev_fiq);
  
-       snd_soc_unregister_dai(&pdev->dev);
+       snd_soc_unregister_component(&pdev->dev);
  
        if (ssi->flags & IMX_SSI_USE_AC97)
                ac97_ssi = NULL;
diff --combined sound/soc/soc-core.c
index ff4b45a5d796f0f16dcd09b7611ad6dc3bda5bb0,fb50e00a71e45ad56395b1217dee4837e7a22f19..45aa1d3a4a52f628a7b13c6a8a3ae2206772dbcd
@@@ -58,6 -58,7 +58,7 @@@ static DEFINE_MUTEX(client_mutex)
  static LIST_HEAD(dai_list);
  static LIST_HEAD(platform_list);
  static LIST_HEAD(codec_list);
+ static LIST_HEAD(component_list);
  
  /*
   * This is a timeout to do a DAPM powerdown after a stream is closed().
@@@ -2963,7 -2964,7 +2964,7 @@@ int snd_soc_put_volsw_range(struct snd_
        val = val << shift;
  
        ret = snd_soc_update_bits_locked(codec, reg, val_mask, val);
 -      if (ret != 0)
 +      if (ret < 0)
                return ret;
  
        if (snd_soc_volsw_is_stereo(mc)) {
@@@ -3140,7 -3141,7 +3141,7 @@@ int snd_soc_bytes_put(struct snd_kcontr
        if (params->mask) {
                ret = regmap_read(codec->control_data, params->base, &val);
                if (ret != 0)
 -                      return ret;
 +                      goto out;
  
                val &= params->mask;
  
                        ((u32 *)data)[0] |= cpu_to_be32(val);
                        break;
                default:
 -                      return -EINVAL;
 +                      ret = -EINVAL;
 +                      goto out;
                }
        }
  
        ret = regmap_raw_write(codec->control_data, params->base,
                               data, len);
  
 +out:
        kfree(data);
  
        return ret;
@@@ -3740,7 -3739,7 +3741,7 @@@ static inline char *fmt_multiple_name(s
   *
   * @dai: DAI to register
   */
- int snd_soc_register_dai(struct device *dev,
static int snd_soc_register_dai(struct device *dev,
                struct snd_soc_dai_driver *dai_drv)
  {
        struct snd_soc_codec *codec;
  
        return 0;
  }
- EXPORT_SYMBOL_GPL(snd_soc_register_dai);
  
  /**
   * snd_soc_unregister_dai - Unregister a DAI from the ASoC core
   *
   * @dai: DAI to unregister
   */
- void snd_soc_unregister_dai(struct device *dev)
static void snd_soc_unregister_dai(struct device *dev)
  {
        struct snd_soc_dai *dai;
  
@@@ -3813,7 -3811,6 +3813,6 @@@ found
        kfree(dai->name);
        kfree(dai);
  }
- EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
  
  /**
   * snd_soc_register_dais - Register multiple DAIs with the ASoC core
   * @dai: Array of DAIs to register
   * @count: Number of DAIs
   */
- int snd_soc_register_dais(struct device *dev,
static int snd_soc_register_dais(struct device *dev,
                struct snd_soc_dai_driver *dai_drv, size_t count)
  {
        struct snd_soc_codec *codec;
@@@ -3885,7 -3882,6 +3884,6 @@@ err
  
        return ret;
  }
- EXPORT_SYMBOL_GPL(snd_soc_register_dais);
  
  /**
   * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
   * @dai: Array of DAIs to unregister
   * @count: Number of DAIs
   */
- void snd_soc_unregister_dais(struct device *dev, size_t count)
static void snd_soc_unregister_dais(struct device *dev, size_t count)
  {
        int i;
  
        for (i = 0; i < count; i++)
                snd_soc_unregister_dai(dev);
  }
- EXPORT_SYMBOL_GPL(snd_soc_unregister_dais);
  
  /**
   * snd_soc_register_platform - Register a platform with the ASoC core
@@@ -4139,6 -4134,92 +4136,92 @@@ found
  }
  EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
  
+ /**
+  * snd_soc_register_component - Register a component with the ASoC core
+  *
+  */
+ int snd_soc_register_component(struct device *dev,
+                        const struct snd_soc_component_driver *cmpnt_drv,
+                        struct snd_soc_dai_driver *dai_drv,
+                        int num_dai)
+ {
+       struct snd_soc_component *cmpnt;
+       int ret;
+       dev_dbg(dev, "component register %s\n", dev_name(dev));
+       cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
+       if (!cmpnt) {
+               dev_err(dev, "ASoC: Failed to allocate memory\n");
+               return -ENOMEM;
+       }
+       cmpnt->name = fmt_single_name(dev, &cmpnt->id);
+       if (!cmpnt->name) {
+               dev_err(dev, "ASoC: Failed to simplifying name\n");
+               return -ENOMEM;
+       }
+       cmpnt->dev      = dev;
+       cmpnt->driver   = cmpnt_drv;
+       cmpnt->num_dai  = num_dai;
+       /*
+        * snd_soc_register_dai()  uses fmt_single_name(), and
+        * snd_soc_register_dais() uses fmt_multiple_name()
+        * for dai->name which is used for name based matching
+        */
+       if (1 == num_dai)
+               ret = snd_soc_register_dai(dev, dai_drv);
+       else
+               ret = snd_soc_register_dais(dev, dai_drv, num_dai);
+       if (ret < 0) {
+               dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
+               goto error_component_name;
+       }
+       mutex_lock(&client_mutex);
+       list_add(&cmpnt->list, &component_list);
+       mutex_unlock(&client_mutex);
+       dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
+       return ret;
+ error_component_name:
+       kfree(cmpnt->name);
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_register_component);
+ /**
+  * snd_soc_unregister_component - Unregister a component from the ASoC core
+  *
+  */
+ void snd_soc_unregister_component(struct device *dev)
+ {
+       struct snd_soc_component *cmpnt;
+       list_for_each_entry(cmpnt, &component_list, list) {
+               if (dev == cmpnt->dev)
+                       goto found;
+       }
+       return;
+ found:
+       snd_soc_unregister_dais(dev, cmpnt->num_dai);
+       mutex_lock(&client_mutex);
+       list_del(&cmpnt->list);
+       mutex_unlock(&client_mutex);
+       dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
+       kfree(cmpnt->name);
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
  /* Retrieve a card's name from device tree */
  int snd_soc_of_parse_card_name(struct snd_soc_card *card,
                               const char *propname)
@@@ -4199,6 -4280,7 +4282,6 @@@ int snd_soc_of_parse_audio_routing(stru
                        dev_err(card->dev,
                                "ASoC: Property '%s' index %d could not be read: %d\n",
                                propname, 2 * i, ret);
 -                      kfree(routes);
                        return -EINVAL;
                }
                ret = of_property_read_string_index(np, propname,
                        dev_err(card->dev,
                                "ASoC: Property '%s' index %d could not be read: %d\n",
                                propname, (2 * i) + 1, ret);
 -                      kfree(routes);
                        return -EINVAL;
                }
        }