On 28-03-2022 21:14, Mark Brown wrote:
On Mon, Mar 28, 2022 at 11:35:22AM +0530, Sameer Pujar wrote:
- regcache_cache_only(asrc->regmap, false);
- regcache_sync(asrc->regmap);
- /* Setup global registers */
- regmap_write(asrc->regmap, TEGRA186_ASRC_GLOBAL_SOFT_RESET, 0x1);
- regmap_write(asrc->regmap, TEGRA186_ASRC_GLOBAL_SCRATCH_ADDR,
TEGRA186_ASRC_ARAM_START_ADDR);
- regmap_write(asrc->regmap, TEGRA186_ASRC_GLOBAL_INT_MASK, 0x01);
- regmap_write(asrc->regmap, TEGRA186_ASRC_GLOBAL_ENB,
TEGRA186_ASRC_GLOBAL_EN);
- regmap_write(asrc->regmap, TEGRA186_ASRC_GLOBAL_INT_CLEAR, 0x01);
This seems weird - we resync the cache, then do a soft reset (which presumably desyncs the cache) and then explicitly restore a bunch of things (hopefully everything that was in the cached state?). This is certainly very much not idiomatic and looks worrying. Are you sure that the device is getting anything out of the register cache?
Let me recheck this part. It may not be required to setup these registers for every RPM resume. Thanks for pointing this.
+static int tegra186_asrc_put_ratio_source(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
+{
- struct soc_enum *asrc_private =
(struct soc_enum *)kcontrol->private_value;
- struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
- struct tegra186_asrc *asrc = snd_soc_component_get_drvdata(cmpnt);
- unsigned int id = asrc_private->reg / TEGRA186_ASRC_STREAM_STRIDE;
- asrc->lane[id].ratio_source = ucontrol->value.enumerated.item[0];
- regmap_update_bits(asrc->regmap, asrc_private->reg,
TEGRA186_ASRC_STREAM_RATIO_TYPE_MASK,
asrc->lane[id].ratio_source);
- return 1;
+}
This should only return 1 if the value actually changed, you can use regmap_update_bits_check() to detect the change. Current mixer-test ought to spot this.
Will fix this.
+static const struct snd_kcontrol_new tegra186_asrc_controls[] = {
- /* Controls for integer part of ratio */
- SOC_SINGLE_EXT("Ratio1 Integer Part",
ASRC_STREAM_REG(TEGRA186_ASRC_RATIO_INT_PART, 0),
0, TEGRA186_ASRC_STREAM_RATIO_INT_PART_MASK, 0,
tegra186_asrc_get_ratio_int,
tegra186_asrc_put_ratio_int),
Can't the driver work out the ratios based on...
- /* Source of ratio provider */
- SOC_ENUM_EXT("Ratio1 Source", src_select1,
tegra186_asrc_get_ratio_source,
tegra186_asrc_put_ratio_source),
...the sources? Or does it need to be configured before either side is ready in which case this might be the best we can do for now.
The ratio needs to be updated before start of the stream and this programming via controls is required only when the ratio source is SW. When ratio detector module is used (support is not yet added), the ratio is automatically updated by HW.