MLK-21957-3: ASoC: fsl_sai: add bitcount and timestamp controls
Bitcount and timestamp support added in SAI IP recently. Add the related controls in SAI driver. Signed-off-by: Viorel Suman <viorel.suman@nxp.com>5.4-rM2-2.2.x-imx-squashed
parent
4c4b7df6f9
commit
d9a6fd7eb7
|
@ -992,6 +992,90 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
|
|||
.shutdown = fsl_sai_shutdown,
|
||||
};
|
||||
|
||||
static const char
|
||||
*en_sl[] = { "Disabled", "Enabled", },
|
||||
*inc_sl[] = { "On enabled and bitcount increment", "On enabled", };
|
||||
|
||||
static const struct soc_enum tstmp_enum[] = {
|
||||
SOC_ENUM_SINGLE(FSL_SAI_TTCTL, 0, ARRAY_SIZE(en_sl), en_sl),
|
||||
SOC_ENUM_SINGLE(FSL_SAI_RTCTL, 0, ARRAY_SIZE(en_sl), en_sl),
|
||||
SOC_ENUM_SINGLE(FSL_SAI_TTCTL, 1, ARRAY_SIZE(inc_sl), inc_sl),
|
||||
SOC_ENUM_SINGLE(FSL_SAI_RTCTL, 1, ARRAY_SIZE(inc_sl), inc_sl),
|
||||
};
|
||||
|
||||
int fsl_sai_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;
|
||||
bool pm_active = pm_runtime_active(component->dev);
|
||||
unsigned int regval;
|
||||
int ret;
|
||||
|
||||
if (pm_active)
|
||||
regcache_cache_bypass(component->regmap, true);
|
||||
|
||||
ret = snd_soc_component_read(component, mc->regbase, ®val);
|
||||
|
||||
if (pm_active)
|
||||
regcache_cache_bypass(component->regmap, false);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ucontrol->value.integer.value[0] = regval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SOC_SINGLE_REG_RO(xname, xreg) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = (xname), \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ | \
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
|
||||
.info = snd_soc_info_xr_sx, .get = fsl_sai_get_reg, \
|
||||
.private_value = (unsigned long)&(struct soc_mreg_control) \
|
||||
{ .regbase = xreg, .regcount = 1, .nbits = 32, \
|
||||
.invert = 0, .min = 0, .max = 0xffffffff, } }
|
||||
|
||||
static const struct snd_kcontrol_new fsl_sai_pb_ctrls[] = {
|
||||
SOC_ENUM("Playback Timestamp Control", tstmp_enum[0]),
|
||||
SOC_ENUM("Playback Timestamp Increment", tstmp_enum[2]),
|
||||
SOC_SINGLE("Playback Timestamp Reset", FSL_SAI_TTCTL, 8, 1, 0),
|
||||
SOC_SINGLE("Playback Bit Counter Reset", FSL_SAI_TTCTL, 9, 1, 0),
|
||||
SOC_SINGLE_REG_RO("Playback Timestamp Counter", FSL_SAI_TTCTN),
|
||||
SOC_SINGLE_REG_RO("Playback Bit Counter", FSL_SAI_TBCTN),
|
||||
SOC_SINGLE_REG_RO("Playback Latched Timestamp Counter", FSL_SAI_TTCAP),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new fsl_sai_cp_ctrls[] = {
|
||||
SOC_ENUM("Capture Timestamp Control", tstmp_enum[1]),
|
||||
SOC_ENUM("Capture Timestamp Increment", tstmp_enum[3]),
|
||||
SOC_SINGLE("Capture Timestamp Reset", FSL_SAI_RTCTL, 8, 1, 0),
|
||||
SOC_SINGLE("Capture Bit Counter Reset", FSL_SAI_RTCTL, 9, 1, 0),
|
||||
SOC_SINGLE_REG_RO("Capture Timestamp Counter", FSL_SAI_RTCTN),
|
||||
SOC_SINGLE_REG_RO("Capture Bit Counter", FSL_SAI_RBCTN),
|
||||
SOC_SINGLE_REG_RO("Capture Latched Timestamp Counter", FSL_SAI_RTCAP),
|
||||
};
|
||||
|
||||
static int fsl_sai_pcm_new(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct fsl_sai *sai = dev_get_drvdata(dai->dev);
|
||||
struct snd_pcm *pcm = rtd->pcm;
|
||||
bool ts_enabled = sai->verid.timestamp_en;
|
||||
struct snd_soc_component *comp = dai->component;
|
||||
|
||||
if (ts_enabled && pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
|
||||
snd_soc_add_component_controls(comp, fsl_sai_pb_ctrls,
|
||||
ARRAY_SIZE(fsl_sai_pb_ctrls));
|
||||
|
||||
if (ts_enabled && pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
|
||||
snd_soc_add_component_controls(comp, fsl_sai_cp_ctrls,
|
||||
ARRAY_SIZE(fsl_sai_cp_ctrls));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
|
||||
|
@ -1030,6 +1114,7 @@ static int fsl_sai_dai_resume(struct snd_soc_dai *cpu_dai)
|
|||
}
|
||||
|
||||
static struct snd_soc_dai_driver fsl_sai_dai = {
|
||||
.pcm_new = fsl_sai_pcm_new,
|
||||
.probe = fsl_sai_dai_probe,
|
||||
.playback = {
|
||||
.stream_name = "CPU-Playback",
|
||||
|
@ -1054,7 +1139,7 @@ static struct snd_soc_dai_driver fsl_sai_dai = {
|
|||
};
|
||||
|
||||
static const struct snd_soc_component_driver fsl_component = {
|
||||
.name = "fsl-sai",
|
||||
.name = "fsl-sai",
|
||||
};
|
||||
|
||||
static struct reg_default fsl_sai_v2_reg_defaults[] = {
|
||||
|
@ -1141,6 +1226,14 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
|
|||
case FSL_SAI_MDIV:
|
||||
case FSL_SAI_VERID:
|
||||
case FSL_SAI_PARAM:
|
||||
case FSL_SAI_TTCTN:
|
||||
case FSL_SAI_RTCTN:
|
||||
case FSL_SAI_TTCTL:
|
||||
case FSL_SAI_TBCTN:
|
||||
case FSL_SAI_TTCAP:
|
||||
case FSL_SAI_RTCTL:
|
||||
case FSL_SAI_RBCTN:
|
||||
case FSL_SAI_RTCAP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -1214,6 +1307,8 @@ static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
|
|||
case FSL_SAI_RMR:
|
||||
case FSL_SAI_MCTL:
|
||||
case FSL_SAI_MDIV:
|
||||
case FSL_SAI_TTCTL:
|
||||
case FSL_SAI_RTCTL:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -210,6 +210,12 @@
|
|||
|
||||
#define SAI_FLAG_PMQOS BIT(0)
|
||||
|
||||
/* SAI timestamp and bitcounter */
|
||||
#define FSL_SAI_xTCTL_TSEN BIT(0)
|
||||
#define FSL_SAI_xTCTL_TSINC BIT(1)
|
||||
#define FSL_SAI_xTCTL_RTSC BIT(8)
|
||||
#define FSL_SAI_xTCTL_RBC BIT(9)
|
||||
|
||||
struct fsl_sai_soc_data {
|
||||
unsigned int fifo_depth;
|
||||
unsigned int fifos;
|
||||
|
|
Loading…
Reference in New Issue