Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a1be4cea authored by Thomas Niederprüm's avatar Thomas Niederprüm Committed by Mark Brown
Browse files

ASoC: sta32x: Convert to direct regmap API usage.



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: default avatarThomas Niederprüm <niederp@physik.uni-kl.de>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 97bf6af1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -581,6 +581,7 @@ config SND_SOC_SSM4567

config SND_SOC_STA32X
	tristate
	select REGMAP_I2C

config SND_SOC_STA350
	tristate "STA350 speaker amplifier"
+151 −120
Original line number Diff line number Diff line
@@ -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,
		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,
		regmap_write(sta32x->regmap, STA32X_CFADDR2, i);
		regmap_write(sta32x->regmap, STA32X_B1CF1,
			     (sta32x->coef_shadow[i] >> 16) & 0xff);
		snd_soc_write(codec, STA32X_B1CF2,
		regmap_write(sta32x->regmap, STA32X_B1CF2,
			     (sta32x->coef_shadow[i] >> 8) & 0xff);
		snd_soc_write(codec, STA32X_B1CF3,
		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 */
		snd_soc_write(codec, STA32X_CFUD, cfud);
		snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
		/*
		 * 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,
		/* Power down */
		regmap_update_bits(sta32x->regmap, STA32X_CONFF,
				   STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
				    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,49 +899,33 @@ 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,
	regmap_update_bits(sta32x->regmap, STA32X_CONFA,
			   STA32X_CONFA_TWAB | STA32X_CONFA_TWRB,
			   thermal);

	/* select output configuration  */
	snd_soc_update_bits(codec, STA32X_CONFF,
	regmap_update_bits(sta32x->regmap, STA32X_CONFF,
			   STA32X_CONFF_OCFG_MASK,
			    sta32x->pdata->output_conf
			   pdata->output_conf
				<< STA32X_CONFF_OCFG_SHIFT);

	/* channel to output mapping */
	snd_soc_update_bits(codec, STA32X_C1CFG,
	regmap_update_bits(sta32x->regmap, STA32X_C1CFG,
			   STA32X_CxCFG_OM_MASK,
			    sta32x->pdata->ch1_output_mapping
			   pdata->ch1_output_mapping
				<< STA32X_CxCFG_OM_SHIFT);
	snd_soc_update_bits(codec, STA32X_C2CFG,
	regmap_update_bits(sta32x->regmap, STA32X_C2CFG,
			   STA32X_CxCFG_OM_MASK,
			    sta32x->pdata->ch2_output_mapping
			   pdata->ch2_output_mapping
				<< STA32X_CxCFG_OM_SHIFT);
	snd_soc_update_bits(codec, STA32X_C3CFG,
	regmap_update_bits(sta32x->regmap, STA32X_C3CFG,
			   STA32X_CxCFG_OM_MASK,
			    sta32x->pdata->ch3_output_mapping
			   pdata->ch3_output_mapping
				<< STA32X_CxCFG_OM_SHIFT);

	/* initialize coefficient shadow RAM with reset values */
@@ -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;
}