Merge remote-tracking branch 'asoc/topic/ab8500' into asoc-next
authorMark Brown <broonie@linaro.org>
Fri, 8 Nov 2013 10:43:20 +0000 (10:43 +0000)
committerMark Brown <broonie@linaro.org>
Fri, 8 Nov 2013 10:43:20 +0000 (10:43 +0000)
1  2 
sound/soc/codecs/ab8500-codec.c

index 80555d7551e68018d5e66485eea1507b10c35b92,3ef481551740dba7df6aa9f405a8ce7f83bf0ddc..21ae8d4fdbfb3a0242502197386577232048d509
@@@ -126,6 -126,8 +126,8 @@@ struct ab8500_codec_drvdata_dbg 
  
  /* Private data for AB8500 device-driver */
  struct ab8500_codec_drvdata {
+       struct regmap *regmap;
        /* Sidetone */
        long *sid_fir_values;
        enum sid_state sid_status;
@@@ -166,49 -168,35 +168,35 @@@ static inline const char *amic_type_str
   */
  
  /* Read a register from the audio-bank of AB8500 */
- static unsigned int ab8500_codec_read_reg(struct snd_soc_codec *codec,
-                                       unsigned int reg)
+ static int ab8500_codec_read_reg(void *context, unsigned int reg,
+                                unsigned int *value)
  {
+       struct device *dev = context;
        int status;
-       unsigned int value = 0;
  
        u8 value8;
-       status = abx500_get_register_interruptible(codec->dev, AB8500_AUDIO,
-                                               reg, &value8);
-       if (status < 0) {
-               dev_err(codec->dev,
-                       "%s: ERROR: Register (0x%02x:0x%02x) read failed (%d).\n",
-                       __func__, (u8)AB8500_AUDIO, (u8)reg, status);
-       } else {
-               dev_dbg(codec->dev,
-                       "%s: Read 0x%02x from register 0x%02x:0x%02x\n",
-                       __func__, value8, (u8)AB8500_AUDIO, (u8)reg);
-               value = (unsigned int)value8;
-       }
+       status = abx500_get_register_interruptible(dev, AB8500_AUDIO,
+                                                  reg, &value8);
+       *value = (unsigned int)value8;
  
-       return value;
+       return status;
  }
  
  /* Write to a register in the audio-bank of AB8500 */
- static int ab8500_codec_write_reg(struct snd_soc_codec *codec,
-                               unsigned int reg, unsigned int value)
+ static int ab8500_codec_write_reg(void *context, unsigned int reg,
+                                 unsigned int value)
  {
-       int status;
-       status = abx500_set_register_interruptible(codec->dev, AB8500_AUDIO,
-                                               reg, value);
-       if (status < 0)
-               dev_err(codec->dev,
-                       "%s: ERROR: Register (%02x:%02x) write failed (%d).\n",
-                       __func__, (u8)AB8500_AUDIO, (u8)reg, status);
-       else
-               dev_dbg(codec->dev,
-                       "%s: Wrote 0x%02x into register %02x:%02x\n",
-                       __func__, (u8)value, (u8)AB8500_AUDIO, (u8)reg);
+       struct device *dev = context;
  
-       return status;
+       return abx500_set_register_interruptible(dev, AB8500_AUDIO,
+                                                reg, value);
  }
  
+ static const struct regmap_config ab8500_codec_regmap = {
+       .reg_read = ab8500_codec_read_reg,
+       .reg_write = ab8500_codec_write_reg,
+ };
  /*
   * Controls - DAPM
   */
@@@ -1225,18 -1213,13 +1213,18 @@@ static int anc_status_control_put(struc
        struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
        struct device *dev = codec->dev;
        bool apply_fir, apply_iir;
 -      int req, status;
 +      unsigned int req;
 +      int status;
  
        dev_dbg(dev, "%s: Enter.\n", __func__);
  
        mutex_lock(&drvdata->anc_lock);
  
        req = ucontrol->value.integer.value[0];
 +      if (req >= ARRAY_SIZE(enum_anc_state)) {
 +              status = -EINVAL;
 +              goto cleanup;
 +      }
        if (req != ANC_APPLY_FIR_IIR && req != ANC_APPLY_FIR &&
                req != ANC_APPLY_IIR) {
                dev_err(dev, "%s: ERROR: Unsupported status to set '%s'!\n",
@@@ -2312,17 -2295,17 +2300,17 @@@ static int ab8500_codec_set_dai_tdm_slo
        case 0:
                break;
        case 1:
-               slot = find_first_bit((unsigned long *)&tx_mask, 32);
+               slot = ffs(tx_mask);
                snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot);
                snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot);
                snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot);
                snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot);
                break;
        case 2:
-               slot = find_first_bit((unsigned long *)&tx_mask, 32);
+               slot = ffs(tx_mask);
                snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot);
                snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot);
-               slot = find_next_bit((unsigned long *)&tx_mask, 32, slot + 1);
+               slot = fls(tx_mask);
                snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot);
                snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot);
                break;
        case 0:
                break;
        case 1:
-               slot = find_first_bit((unsigned long *)&rx_mask, 32);
+               slot = ffs(rx_mask);
                snd_soc_update_bits(codec, AB8500_ADSLOTSEL(slot),
                                AB8500_MASK_SLOT(slot),
                                AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
                break;
        case 2:
-               slot = find_first_bit((unsigned long *)&rx_mask, 32);
+               slot = ffs(rx_mask);
                snd_soc_update_bits(codec,
                                AB8500_ADSLOTSEL(slot),
                                AB8500_MASK_SLOT(slot),
                                AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
-               slot = find_next_bit((unsigned long *)&rx_mask, 32, slot + 1);
+               slot = fls(rx_mask);
                snd_soc_update_bits(codec,
                                AB8500_ADSLOTSEL(slot),
                                AB8500_MASK_SLOT(slot),
@@@ -2485,9 -2468,13 +2473,13 @@@ static int ab8500_codec_probe(struct sn
  
        dev_dbg(dev, "%s: Enter.\n", __func__);
  
+       snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
        /* Setup AB8500 according to board-settings */
        pdata = dev_get_platdata(dev->parent);
  
+       codec->control_data = drvdata->regmap;
        if (np) {
                if (!pdata)
                        pdata = devm_kzalloc(dev,
        }
  
        /* Override HW-defaults */
-       ab8500_codec_write_reg(codec,
-                               AB8500_ANACONF5,
-                               BIT(AB8500_ANACONF5_HSAUTOEN));
-       ab8500_codec_write_reg(codec,
-                               AB8500_SHORTCIRCONF,
-                               BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
+       snd_soc_write(codec, AB8500_ANACONF5,
+                     BIT(AB8500_ANACONF5_HSAUTOEN));
+       snd_soc_write(codec, AB8500_SHORTCIRCONF,
+                     BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
  
        /* Add filter controls */
        status = snd_soc_add_codec_controls(codec, ab8500_filter_controls,
  
  static struct snd_soc_codec_driver ab8500_codec_driver = {
        .probe =                ab8500_codec_probe,
-       .read =                 ab8500_codec_read_reg,
-       .write =                ab8500_codec_write_reg,
-       .reg_word_size =        sizeof(u8),
        .controls =             ab8500_ctrls,
        .num_controls =         ARRAY_SIZE(ab8500_ctrls),
        .dapm_widgets =         ab8500_dapm_widgets,
@@@ -2588,10 -2570,21 +2575,21 @@@ static int ab8500_codec_driver_probe(st
        /* Create driver private-data struct */
        drvdata = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_codec_drvdata),
                        GFP_KERNEL);
+       if (!drvdata)
+               return -ENOMEM;
        drvdata->sid_status = SID_UNCONFIGURED;
        drvdata->anc_status = ANC_UNCONFIGURED;
        dev_set_drvdata(&pdev->dev, drvdata);
  
+       drvdata->regmap = devm_regmap_init(&pdev->dev, NULL, &pdev->dev,
+                                          &ab8500_codec_regmap);
+       if (IS_ERR(drvdata->regmap)) {
+               status = PTR_ERR(drvdata->regmap);
+               dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n",
+                       __func__, status);
+               return status;
+       }
        dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__);
        status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver,
                                ab8500_codec_dai,
  
  static int ab8500_codec_driver_remove(struct platform_device *pdev)
  {
-       dev_info(&pdev->dev, "%s Enter.\n", __func__);
+       dev_dbg(&pdev->dev, "%s Enter.\n", __func__);
  
        snd_soc_unregister_codec(&pdev->dev);