diff options
Diffstat (limited to 'sound/soc/fsl/fsl_easrc.c')
| -rw-r--r-- | sound/soc/fsl/fsl_easrc.c | 132 |
1 files changed, 97 insertions, 35 deletions
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index f404a39009e1..114a6c0b6b73 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -52,10 +52,16 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value; unsigned int regval = ucontrol->value.integer.value[0]; + int ret; + + if (regval < EASRC_WIDTH_16_BIT || regval > EASRC_WIDTH_24_BIT) + return -EINVAL; + + ret = (easrc_priv->bps_iec958[mc->regbase] != regval); easrc_priv->bps_iec958[mc->regbase] = regval; - return 0; + return ret; } static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, @@ -67,22 +73,52 @@ static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value; - ucontrol->value.enumerated.item[0] = easrc_priv->bps_iec958[mc->regbase]; + ucontrol->value.integer.value[0] = easrc_priv->bps_iec958[mc->regbase]; return 0; } +static int fsl_easrc_iec958_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; + uinfo->count = 1; + return 0; +} + static int fsl_easrc_get_reg(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value; - unsigned int regval; + struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component); + unsigned int *regval = (unsigned int *)ucontrol->value.iec958.status; + int ret; + + ret = regmap_read(easrc->regmap, REG_EASRC_CS0(mc->regbase), ®val[0]); + if (ret) + return ret; + + ret = regmap_read(easrc->regmap, REG_EASRC_CS1(mc->regbase), ®val[1]); + if (ret) + return ret; - regval = snd_soc_component_read(component, mc->regbase); + ret = regmap_read(easrc->regmap, REG_EASRC_CS2(mc->regbase), ®val[2]); + if (ret) + return ret; - ucontrol->value.integer.value[0] = regval; + ret = regmap_read(easrc->regmap, REG_EASRC_CS3(mc->regbase), ®val[3]); + if (ret) + return ret; + + ret = regmap_read(easrc->regmap, REG_EASRC_CS4(mc->regbase), ®val[4]); + if (ret) + return ret; + + ret = regmap_read(easrc->regmap, REG_EASRC_CS5(mc->regbase), ®val[5]); + if (ret) + return ret; return 0; } @@ -93,20 +129,63 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value; - unsigned int regval = ucontrol->value.integer.value[0]; + struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component); + unsigned int *regval = (unsigned int *)ucontrol->value.iec958.status; + bool changed, changed_all = false; int ret; - ret = snd_soc_component_write(component, mc->regbase, regval); - if (ret < 0) + ret = pm_runtime_resume_and_get(component->dev); + if (ret) return ret; - return 0; + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS0(mc->regbase), + GENMASK(31, 0), regval[0], &changed); + if (ret != 0) + goto err; + changed_all |= changed; + + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS1(mc->regbase), + GENMASK(31, 0), regval[1], &changed); + if (ret != 0) + goto err; + changed_all |= changed; + + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS2(mc->regbase), + GENMASK(31, 0), regval[2], &changed); + if (ret != 0) + goto err; + changed_all |= changed; + + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS3(mc->regbase), + GENMASK(31, 0), regval[3], &changed); + if (ret != 0) + goto err; + changed_all |= changed; + + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS4(mc->regbase), + GENMASK(31, 0), regval[4], &changed); + if (ret != 0) + goto err; + changed_all |= changed; + + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS5(mc->regbase), + GENMASK(31, 0), regval[5], &changed); + if (ret != 0) + goto err; + changed_all |= changed; +err: + pm_runtime_put_autosuspend(component->dev); + + if (ret != 0) + return ret; + else + return changed_all; } #define SOC_SINGLE_REG_RW(xname, xreg) \ { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = (xname), \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ - .info = snd_soc_info_xr_sx, .get = fsl_easrc_get_reg, \ + .info = fsl_easrc_iec958_info, .get = fsl_easrc_get_reg, \ .put = fsl_easrc_set_reg, \ .private_value = (unsigned long)&(struct soc_mreg_control) \ { .regbase = xreg, .regcount = 1, .nbits = 32, \ @@ -137,30 +216,10 @@ static const struct snd_kcontrol_new fsl_easrc_snd_controls[] = { SOC_SINGLE_VAL_RW("Context 2 IEC958 Bits Per Sample", 2), SOC_SINGLE_VAL_RW("Context 3 IEC958 Bits Per Sample", 3), - SOC_SINGLE_REG_RW("Context 0 IEC958 CS0", REG_EASRC_CS0(0)), - SOC_SINGLE_REG_RW("Context 1 IEC958 CS0", REG_EASRC_CS0(1)), - SOC_SINGLE_REG_RW("Context 2 IEC958 CS0", REG_EASRC_CS0(2)), - SOC_SINGLE_REG_RW("Context 3 IEC958 CS0", REG_EASRC_CS0(3)), - SOC_SINGLE_REG_RW("Context 0 IEC958 CS1", REG_EASRC_CS1(0)), - SOC_SINGLE_REG_RW("Context 1 IEC958 CS1", REG_EASRC_CS1(1)), - SOC_SINGLE_REG_RW("Context 2 IEC958 CS1", REG_EASRC_CS1(2)), - SOC_SINGLE_REG_RW("Context 3 IEC958 CS1", REG_EASRC_CS1(3)), - SOC_SINGLE_REG_RW("Context 0 IEC958 CS2", REG_EASRC_CS2(0)), - SOC_SINGLE_REG_RW("Context 1 IEC958 CS2", REG_EASRC_CS2(1)), - SOC_SINGLE_REG_RW("Context 2 IEC958 CS2", REG_EASRC_CS2(2)), - SOC_SINGLE_REG_RW("Context 3 IEC958 CS2", REG_EASRC_CS2(3)), - SOC_SINGLE_REG_RW("Context 0 IEC958 CS3", REG_EASRC_CS3(0)), - SOC_SINGLE_REG_RW("Context 1 IEC958 CS3", REG_EASRC_CS3(1)), - SOC_SINGLE_REG_RW("Context 2 IEC958 CS3", REG_EASRC_CS3(2)), - SOC_SINGLE_REG_RW("Context 3 IEC958 CS3", REG_EASRC_CS3(3)), - SOC_SINGLE_REG_RW("Context 0 IEC958 CS4", REG_EASRC_CS4(0)), - SOC_SINGLE_REG_RW("Context 1 IEC958 CS4", REG_EASRC_CS4(1)), - SOC_SINGLE_REG_RW("Context 2 IEC958 CS4", REG_EASRC_CS4(2)), - SOC_SINGLE_REG_RW("Context 3 IEC958 CS4", REG_EASRC_CS4(3)), - SOC_SINGLE_REG_RW("Context 0 IEC958 CS5", REG_EASRC_CS5(0)), - SOC_SINGLE_REG_RW("Context 1 IEC958 CS5", REG_EASRC_CS5(1)), - SOC_SINGLE_REG_RW("Context 2 IEC958 CS5", REG_EASRC_CS5(2)), - SOC_SINGLE_REG_RW("Context 3 IEC958 CS5", REG_EASRC_CS5(3)), + SOC_SINGLE_REG_RW("Context 0 IEC958 CS", 0), + SOC_SINGLE_REG_RW("Context 1 IEC958 CS", 1), + SOC_SINGLE_REG_RW("Context 2 IEC958 CS", 2), + SOC_SINGLE_REG_RW("Context 3 IEC958 CS", 3), }; /* @@ -1280,7 +1339,7 @@ static int fsl_easrc_request_context(int channels, struct fsl_asrc_pair *ctx) /* * Release the context * - * This funciton is mainly doing the revert thing in request context + * This function is mainly doing the revert thing in request context */ static void fsl_easrc_release_context(struct fsl_asrc_pair *ctx) { @@ -1577,6 +1636,9 @@ static const struct snd_soc_component_driver fsl_easrc_component = { .controls = fsl_easrc_snd_controls, .num_controls = ARRAY_SIZE(fsl_easrc_snd_controls), .legacy_dai_naming = 1, +#ifdef CONFIG_DEBUG_FS + .debugfs_prefix = "easrc", +#endif }; static const struct reg_default fsl_easrc_reg_defaults[] = { |
