OSDN Git Service

ASoC: sta32x: Convert to direct regmap API usage.
authorThomas Niederprüm <niederp@physik.uni-kl.de>
Wed, 21 Jan 2015 23:01:53 +0000 (00:01 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 27 Jan 2015 17:13:21 +0000 (17:13 +0000)
use the regmap API directly rather than relying on the snd_soc_read/write
functions as this seems to be in accordance with common practice.

Signed-off-by: Thomas Niederprüm <niederp@physik.uni-kl.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/Kconfig
sound/soc/codecs/sta32x.c

index 8349f98..27e1e3b 100644 (file)
@@ -581,6 +581,7 @@ config SND_SOC_SSM4567
 
 config SND_SOC_STA32X
        tristate
+       select REGMAP_I2C
 
 config SND_SOC_STA350
        tristate "STA350 speaker amplifier"
index 7e18200..4517453 100644 (file)
@@ -102,6 +102,35 @@ static const struct reg_default sta32x_regs[] = {
        { 0x2c, 0x0c },
 };
 
+static const struct regmap_range sta32x_write_regs_range[] = {
+       regmap_reg_range(STA32X_CONFA,  STA32X_AUTO2),
+       regmap_reg_range(STA32X_C1CFG,  STA32X_FDRC2),
+};
+
+static const struct regmap_range sta32x_read_regs_range[] = {
+       regmap_reg_range(STA32X_CONFA,  STA32X_AUTO2),
+       regmap_reg_range(STA32X_C1CFG,  STA32X_FDRC2),
+};
+
+static const struct regmap_range sta32x_volatile_regs_range[] = {
+       regmap_reg_range(STA32X_CFADDR2, STA32X_CFUD),
+};
+
+static const struct regmap_access_table sta32x_write_regs = {
+       .yes_ranges =   sta32x_write_regs_range,
+       .n_yes_ranges = ARRAY_SIZE(sta32x_write_regs_range),
+};
+
+static const struct regmap_access_table sta32x_read_regs = {
+       .yes_ranges =   sta32x_read_regs_range,
+       .n_yes_ranges = ARRAY_SIZE(sta32x_read_regs_range),
+};
+
+static const struct regmap_access_table sta32x_volatile_regs = {
+       .yes_ranges =   sta32x_volatile_regs_range,
+       .n_yes_ranges = ARRAY_SIZE(sta32x_volatile_regs_range),
+};
+
 /* regulator power supply names */
 static const char *sta32x_supply_names[] = {
        "Vdda", /* analog supply, 3.3VV */
@@ -122,6 +151,7 @@ struct sta32x_priv {
        u32 coef_shadow[STA32X_COEF_COUNT];
        struct delayed_work watchdog_work;
        int shutdown;
+       struct mutex coeff_lock;
 };
 
 static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);
@@ -244,29 +274,42 @@ static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
        int numcoef = kcontrol->private_value >> 16;
        int index = kcontrol->private_value & 0xffff;
-       unsigned int cfud;
-       int i;
+       unsigned int cfud, val;
+       int i, ret = 0;
+
+       mutex_lock(&sta32x->coeff_lock);
 
        /* preserve reserved bits in STA32X_CFUD */
-       cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
-       /* chip documentation does not say if the bits are self clearing,
-        * so do it explicitly */
-       snd_soc_write(codec, STA32X_CFUD, cfud);
+       regmap_read(sta32x->regmap, STA32X_CFUD, &cfud);
+       cfud &= 0xf0;
+       /*
+        * chip documentation does not say if the bits are self clearing,
+        * so do it explicitly
+        */
+       regmap_write(sta32x->regmap, STA32X_CFUD, cfud);
 
-       snd_soc_write(codec, STA32X_CFADDR2, index);
-       if (numcoef == 1)
-               snd_soc_write(codec, STA32X_CFUD, cfud | 0x04);
-       else if (numcoef == 5)
-               snd_soc_write(codec, STA32X_CFUD, cfud | 0x08);
-       else
-               return -EINVAL;
-       for (i = 0; i < 3 * numcoef; i++)
-               ucontrol->value.bytes.data[i] =
-                       snd_soc_read(codec, STA32X_B1CF1 + i);
+       regmap_write(sta32x->regmap, STA32X_CFADDR2, index);
+       if (numcoef == 1) {
+               regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x04);
+       } else if (numcoef == 5) {
+               regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x08);
+       } else {
+               ret = -EINVAL;
+               goto exit_unlock;
+       }
 
-       return 0;
+       for (i = 0; i < 3 * numcoef; i++) {
+               regmap_read(sta32x->regmap, STA32X_B1CF1 + i, &val);
+               ucontrol->value.bytes.data[i] = val;
+       }
+
+exit_unlock:
+       mutex_unlock(&sta32x->coeff_lock);
+
+       return ret;
 }
 
 static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
@@ -280,24 +323,27 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
        int i;
 
        /* preserve reserved bits in STA32X_CFUD */
-       cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
-       /* chip documentation does not say if the bits are self clearing,
-        * so do it explicitly */
-       snd_soc_write(codec, STA32X_CFUD, cfud);
+       regmap_read(sta32x->regmap, STA32X_CFUD, &cfud);
+       cfud &= 0xf0;
+       /*
+        * chip documentation does not say if the bits are self clearing,
+        * so do it explicitly
+        */
+       regmap_write(sta32x->regmap, STA32X_CFUD, cfud);
 
-       snd_soc_write(codec, STA32X_CFADDR2, index);
+       regmap_write(sta32x->regmap, STA32X_CFADDR2, index);
        for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++)
                sta32x->coef_shadow[index + i] =
                          (ucontrol->value.bytes.data[3 * i] << 16)
                        | (ucontrol->value.bytes.data[3 * i + 1] << 8)
                        | (ucontrol->value.bytes.data[3 * i + 2]);
        for (i = 0; i < 3 * numcoef; i++)
-               snd_soc_write(codec, STA32X_B1CF1 + i,
-                             ucontrol->value.bytes.data[i]);
+               regmap_write(sta32x->regmap, STA32X_B1CF1 + i,
+                            ucontrol->value.bytes.data[i]);
        if (numcoef == 1)
-               snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
+               regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x01);
        else if (numcoef == 5)
-               snd_soc_write(codec, STA32X_CFUD, cfud | 0x02);
+               regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x02);
        else
                return -EINVAL;
 
@@ -311,20 +357,23 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
        int i;
 
        /* preserve reserved bits in STA32X_CFUD */
-       cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
+       regmap_read(sta32x->regmap, STA32X_CFUD, &cfud);
+       cfud &= 0xf0;
 
        for (i = 0; i < STA32X_COEF_COUNT; i++) {
-               snd_soc_write(codec, STA32X_CFADDR2, i);
-               snd_soc_write(codec, STA32X_B1CF1,
-                             (sta32x->coef_shadow[i] >> 16) & 0xff);
-               snd_soc_write(codec, STA32X_B1CF2,
-                             (sta32x->coef_shadow[i] >> 8) & 0xff);
-               snd_soc_write(codec, STA32X_B1CF3,
-                             (sta32x->coef_shadow[i]) & 0xff);
-               /* chip documentation does not say if the bits are
-                * self-clearing, so do it explicitly */
-               snd_soc_write(codec, STA32X_CFUD, cfud);
-               snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
+               regmap_write(sta32x->regmap, STA32X_CFADDR2, i);
+               regmap_write(sta32x->regmap, STA32X_B1CF1,
+                            (sta32x->coef_shadow[i] >> 16) & 0xff);
+               regmap_write(sta32x->regmap, STA32X_B1CF2,
+                            (sta32x->coef_shadow[i] >> 8) & 0xff);
+               regmap_write(sta32x->regmap, STA32X_B1CF3,
+                            (sta32x->coef_shadow[i]) & 0xff);
+               /*
+                * chip documentation does not say if the bits are
+                * self-clearing, so do it explicitly
+                */
+               regmap_write(sta32x->regmap, STA32X_CFUD, cfud);
+               regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x01);
        }
        return 0;
 }
@@ -336,11 +385,11 @@ static int sta32x_cache_sync(struct snd_soc_codec *codec)
        int rc;
 
        /* mute during register sync */
-       mute = snd_soc_read(codec, STA32X_MMUTE);
-       snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
+       regmap_read(sta32x->regmap, STA32X_MMUTE, &mute);
+       regmap_write(sta32x->regmap, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
        sta32x_sync_coef_shadow(codec);
        rc = regcache_sync(sta32x->regmap);
-       snd_soc_write(codec, STA32X_MMUTE, mute);
+       regmap_write(sta32x->regmap, STA32X_MMUTE, mute);
        return rc;
 }
 
@@ -599,10 +648,7 @@ static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 {
        struct snd_soc_codec *codec = codec_dai->codec;
        struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
-       u8 confb = snd_soc_read(codec, STA32X_CONFB);
-
-       pr_debug("\n");
-       confb &= ~(STA32X_CONFB_C1IM | STA32X_CONFB_C2IM);
+       u8 confb = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
@@ -632,8 +678,8 @@ static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, STA32X_CONFB, confb);
-       return 0;
+       return regmap_update_bits(sta32x->regmap, STA32X_CONFB,
+                                 STA32X_CONFB_C1IM | STA32X_CONFB_C2IM, confb);
 }
 
 /**
@@ -653,7 +699,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
        struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
        unsigned int rate;
        int i, mcs = -1, ir = -1;
-       u8 confa, confb;
+       unsigned int confa, confb;
 
        rate = params_rate(params);
        pr_debug("rate: %u\n", rate);
@@ -672,12 +718,10 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
        if (mcs < 0)
                return -EINVAL;
 
-       confa = snd_soc_read(codec, STA32X_CONFA);
-       confa &= ~(STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK);
-       confa |= (ir << STA32X_CONFA_IR_SHIFT) | (mcs << STA32X_CONFA_MCS_SHIFT);
+       confa = (ir << STA32X_CONFA_IR_SHIFT) |
+               (mcs << STA32X_CONFA_MCS_SHIFT);
+       confb = 0;
 
-       confb = snd_soc_read(codec, STA32X_CONFB);
-       confb &= ~(STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB);
        switch (params_width(params)) {
        case 24:
                pr_debug("24bit\n");
@@ -746,8 +790,20 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, STA32X_CONFA, confa);
-       snd_soc_write(codec, STA32X_CONFB, confb);
+       ret = regmap_update_bits(sta32x->regmap, STA32X_CONFA,
+                                STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK,
+                                confa);
+       if (ret < 0)
+               return ret;
+
+       ret = regmap_update_bits(sta32x->regmap, STA32X_CONFB,
+                                STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB,
+                                confb);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
        return 0;
 }
 
@@ -773,7 +829,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_PREPARE:
                /* Full power on */
-               snd_soc_update_bits(codec, STA32X_CONFF,
+               regmap_update_bits(sta32x->regmap, STA32X_CONFF,
                                    STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
                                    STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);
                break;
@@ -792,19 +848,17 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
                        sta32x_watchdog_start(sta32x);
                }
 
-               /* Power up to mute */
-               /* FIXME */
-               snd_soc_update_bits(codec, STA32X_CONFF,
-                                   STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
-                                   STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);
+               /* Power down */
+               regmap_update_bits(sta32x->regmap, STA32X_CONFF,
+                                  STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
+                                  0);
 
                break;
 
        case SND_SOC_BIAS_OFF:
                /* The chip runs through the power down sequence for us. */
-               snd_soc_update_bits(codec, STA32X_CONFF,
-                                   STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
-                                   STA32X_CONFF_PWDN);
+               regmap_update_bits(sta32x->regmap, STA32X_CONFF,
+                                  STA32X_CONFF_PWDN | STA32X_CONFF_EAPD, 0);
                msleep(300);
                sta32x_watchdog_stop(sta32x);
                regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies),
@@ -836,11 +890,8 @@ static struct snd_soc_dai_driver sta32x_dai = {
 static int sta32x_probe(struct snd_soc_codec *codec)
 {
        struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct sta32x_platform_data *pdata = sta32x->pdata;
        int i, ret = 0, thermal = 0;
-
-       sta32x->codec = codec;
-       sta32x->pdata = dev_get_platdata(codec->dev);
-
        ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
                                    sta32x->supplies);
        if (ret != 0) {
@@ -848,50 +899,34 @@ static int sta32x_probe(struct snd_soc_codec *codec)
                return ret;
        }
 
-       /* Chip documentation explicitly requires that the reset values
-        * of reserved register bits are left untouched.
-        * Write the register default value to cache for reserved registers,
-        * so the write to the these registers are suppressed by the cache
-        * restore code when it skips writes of default registers.
-        */
-       regcache_cache_only(sta32x->regmap, true);
-       snd_soc_write(codec, STA32X_CONFC, 0xc2);
-       snd_soc_write(codec, STA32X_CONFE, 0xc2);
-       snd_soc_write(codec, STA32X_CONFF, 0x5c);
-       snd_soc_write(codec, STA32X_MMUTE, 0x10);
-       snd_soc_write(codec, STA32X_AUTO1, 0x60);
-       snd_soc_write(codec, STA32X_AUTO3, 0x00);
-       snd_soc_write(codec, STA32X_C3CFG, 0x40);
-       regcache_cache_only(sta32x->regmap, false);
-
        /* set thermal warning adjustment and recovery */
-       if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE))
+       if (!pdata->thermal_warning_recovery)
                thermal |= STA32X_CONFA_TWAB;
-       if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_RECOVERY_ENABLE))
+       if (!pdata->thermal_warning_adjustment)
                thermal |= STA32X_CONFA_TWRB;
-       snd_soc_update_bits(codec, STA32X_CONFA,
-                           STA32X_CONFA_TWAB | STA32X_CONFA_TWRB,
-                           thermal);
+       regmap_update_bits(sta32x->regmap, STA32X_CONFA,
+                          STA32X_CONFA_TWAB | STA32X_CONFA_TWRB,
+                          thermal);
 
        /* select output configuration  */
-       snd_soc_update_bits(codec, STA32X_CONFF,
-                           STA32X_CONFF_OCFG_MASK,
-                           sta32x->pdata->output_conf
-                           << STA32X_CONFF_OCFG_SHIFT);
+       regmap_update_bits(sta32x->regmap, STA32X_CONFF,
+                          STA32X_CONFF_OCFG_MASK,
+                          pdata->output_conf
+                               << STA32X_CONFF_OCFG_SHIFT);
 
        /* channel to output mapping */
-       snd_soc_update_bits(codec, STA32X_C1CFG,
-                           STA32X_CxCFG_OM_MASK,
-                           sta32x->pdata->ch1_output_mapping
-                           << STA32X_CxCFG_OM_SHIFT);
-       snd_soc_update_bits(codec, STA32X_C2CFG,
-                           STA32X_CxCFG_OM_MASK,
-                           sta32x->pdata->ch2_output_mapping
-                           << STA32X_CxCFG_OM_SHIFT);
-       snd_soc_update_bits(codec, STA32X_C3CFG,
-                           STA32X_CxCFG_OM_MASK,
-                           sta32x->pdata->ch3_output_mapping
-                           << STA32X_CxCFG_OM_SHIFT);
+       regmap_update_bits(sta32x->regmap, STA32X_C1CFG,
+                          STA32X_CxCFG_OM_MASK,
+                          pdata->ch1_output_mapping
+                               << STA32X_CxCFG_OM_SHIFT);
+       regmap_update_bits(sta32x->regmap, STA32X_C2CFG,
+                          STA32X_CxCFG_OM_MASK,
+                          pdata->ch2_output_mapping
+                               << STA32X_CxCFG_OM_SHIFT);
+       regmap_update_bits(sta32x->regmap, STA32X_C3CFG,
+                          STA32X_CxCFG_OM_MASK,
+                          pdata->ch3_output_mapping
+                               << STA32X_CxCFG_OM_SHIFT);
 
        /* initialize coefficient shadow RAM with reset values */
        for (i = 4; i <= 49; i += 5)
@@ -924,16 +959,6 @@ static int sta32x_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-static bool sta32x_reg_is_volatile(struct device *dev, unsigned int reg)
-{
-       switch (reg) {
-       case STA32X_CONFA ... STA32X_L2ATRT:
-       case STA32X_MPCC1 ... STA32X_FDRC2:
-               return 0;
-       }
-       return 1;
-}
-
 static const struct snd_soc_codec_driver sta32x_codec = {
        .probe =                sta32x_probe,
        .remove =               sta32x_remove,
@@ -954,12 +979,16 @@ static const struct regmap_config sta32x_regmap = {
        .reg_defaults =         sta32x_regs,
        .num_reg_defaults =     ARRAY_SIZE(sta32x_regs),
        .cache_type =           REGCACHE_RBTREE,
-       .volatile_reg =         sta32x_reg_is_volatile,
+       .wr_table =             &sta32x_write_regs,
+       .rd_table =             &sta32x_read_regs,
+       .volatile_table =       &sta32x_volatile_regs,
+};
 };
 
 static int sta32x_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
+       struct device *dev = &i2c->dev;
        struct sta32x_priv *sta32x;
        int ret, i;
 
@@ -968,6 +997,8 @@ static int sta32x_i2c_probe(struct i2c_client *i2c,
        if (!sta32x)
                return -ENOMEM;
 
+       mutex_init(&sta32x->coeff_lock);
+       sta32x->pdata = dev_get_platdata(dev);
        /* regulators */
        for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
                sta32x->supplies[i].supply = sta32x_supply_names[i];
@@ -982,15 +1013,15 @@ static int sta32x_i2c_probe(struct i2c_client *i2c,
        sta32x->regmap = devm_regmap_init_i2c(i2c, &sta32x_regmap);
        if (IS_ERR(sta32x->regmap)) {
                ret = PTR_ERR(sta32x->regmap);
-               dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
+               dev_err(dev, "Failed to init regmap: %d\n", ret);
                return ret;
        }
 
        i2c_set_clientdata(i2c, sta32x);
 
-       ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
-       if (ret != 0)
-               dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
+       ret = snd_soc_register_codec(dev, &sta32x_codec, &sta32x_dai, 1);
+       if (ret < 0)
+               dev_err(dev, "Failed to register codec (%d)\n", ret);
 
        return ret;
 }