| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 599235bd9d22c8cad90b0a7621b46d70cca94d31 Mon Sep 17 00:00:00 2001 |
| 2 | From: Viorel Suman <viorel.suman@nxp.com> |
| 3 | Date: Wed, 5 Jun 2019 13:46:32 +0000 |
| 4 | Subject: [PATCH] MLK-21957-3: ASoC: fsl_sai: add bitcount and timestamp |
| 5 | controls |
| 6 | |
| 7 | Bitcount and timestamp support added in SAI IP recently. |
| 8 | Add the related controls in SAI driver. |
| 9 | |
| 10 | Signed-off-by: Viorel Suman <viorel.suman@nxp.com> |
| 11 | --- |
| 12 | sound/soc/fsl/fsl_sai.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++- |
| 13 | sound/soc/fsl/fsl_sai.h | 6 +++ |
| 14 | 2 files changed, 102 insertions(+), 1 deletion(-) |
| 15 | |
| 16 | --- a/sound/soc/fsl/fsl_sai.c |
| 17 | +++ b/sound/soc/fsl/fsl_sai.c |
| 18 | @@ -992,6 +992,90 @@ static const struct snd_soc_dai_ops fsl_ |
| 19 | .shutdown = fsl_sai_shutdown, |
| 20 | }; |
| 21 | |
| 22 | +static const char |
| 23 | + *en_sl[] = { "Disabled", "Enabled", }, |
| 24 | + *inc_sl[] = { "On enabled and bitcount increment", "On enabled", }; |
| 25 | + |
| 26 | +static const struct soc_enum tstmp_enum[] = { |
| 27 | +SOC_ENUM_SINGLE(FSL_SAI_TTCTL, 0, ARRAY_SIZE(en_sl), en_sl), |
| 28 | +SOC_ENUM_SINGLE(FSL_SAI_RTCTL, 0, ARRAY_SIZE(en_sl), en_sl), |
| 29 | +SOC_ENUM_SINGLE(FSL_SAI_TTCTL, 1, ARRAY_SIZE(inc_sl), inc_sl), |
| 30 | +SOC_ENUM_SINGLE(FSL_SAI_RTCTL, 1, ARRAY_SIZE(inc_sl), inc_sl), |
| 31 | +}; |
| 32 | + |
| 33 | +int fsl_sai_get_reg(struct snd_kcontrol *kcontrol, |
| 34 | + struct snd_ctl_elem_value *ucontrol) |
| 35 | +{ |
| 36 | + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
| 37 | + struct soc_mreg_control *mc = |
| 38 | + (struct soc_mreg_control *)kcontrol->private_value; |
| 39 | + bool pm_active = pm_runtime_active(component->dev); |
| 40 | + unsigned int regval; |
| 41 | + int ret; |
| 42 | + |
| 43 | + if (pm_active) |
| 44 | + regcache_cache_bypass(component->regmap, true); |
| 45 | + |
| 46 | + ret = snd_soc_component_read(component, mc->regbase, ®val); |
| 47 | + |
| 48 | + if (pm_active) |
| 49 | + regcache_cache_bypass(component->regmap, false); |
| 50 | + |
| 51 | + if (ret < 0) |
| 52 | + return ret; |
| 53 | + |
| 54 | + ucontrol->value.integer.value[0] = regval; |
| 55 | + |
| 56 | + return 0; |
| 57 | +} |
| 58 | + |
| 59 | +#define SOC_SINGLE_REG_RO(xname, xreg) \ |
| 60 | +{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = (xname), \ |
| 61 | + .access = SNDRV_CTL_ELEM_ACCESS_READ | \ |
| 62 | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| 63 | + .info = snd_soc_info_xr_sx, .get = fsl_sai_get_reg, \ |
| 64 | + .private_value = (unsigned long)&(struct soc_mreg_control) \ |
| 65 | + { .regbase = xreg, .regcount = 1, .nbits = 32, \ |
| 66 | + .invert = 0, .min = 0, .max = 0xffffffff, } } |
| 67 | + |
| 68 | +static const struct snd_kcontrol_new fsl_sai_pb_ctrls[] = { |
| 69 | + SOC_ENUM("Playback Timestamp Control", tstmp_enum[0]), |
| 70 | + SOC_ENUM("Playback Timestamp Increment", tstmp_enum[2]), |
| 71 | + SOC_SINGLE("Playback Timestamp Reset", FSL_SAI_TTCTL, 8, 1, 0), |
| 72 | + SOC_SINGLE("Playback Bit Counter Reset", FSL_SAI_TTCTL, 9, 1, 0), |
| 73 | + SOC_SINGLE_REG_RO("Playback Timestamp Counter", FSL_SAI_TTCTN), |
| 74 | + SOC_SINGLE_REG_RO("Playback Bit Counter", FSL_SAI_TBCTN), |
| 75 | + SOC_SINGLE_REG_RO("Playback Latched Timestamp Counter", FSL_SAI_TTCAP), |
| 76 | +}; |
| 77 | + |
| 78 | +static const struct snd_kcontrol_new fsl_sai_cp_ctrls[] = { |
| 79 | + SOC_ENUM("Capture Timestamp Control", tstmp_enum[1]), |
| 80 | + SOC_ENUM("Capture Timestamp Increment", tstmp_enum[3]), |
| 81 | + SOC_SINGLE("Capture Timestamp Reset", FSL_SAI_RTCTL, 8, 1, 0), |
| 82 | + SOC_SINGLE("Capture Bit Counter Reset", FSL_SAI_RTCTL, 9, 1, 0), |
| 83 | + SOC_SINGLE_REG_RO("Capture Timestamp Counter", FSL_SAI_RTCTN), |
| 84 | + SOC_SINGLE_REG_RO("Capture Bit Counter", FSL_SAI_RBCTN), |
| 85 | + SOC_SINGLE_REG_RO("Capture Latched Timestamp Counter", FSL_SAI_RTCAP), |
| 86 | +}; |
| 87 | + |
| 88 | +static int fsl_sai_pcm_new(struct snd_soc_pcm_runtime *rtd, |
| 89 | + struct snd_soc_dai *dai) |
| 90 | +{ |
| 91 | + struct fsl_sai *sai = dev_get_drvdata(dai->dev); |
| 92 | + struct snd_pcm *pcm = rtd->pcm; |
| 93 | + bool ts_enabled = sai->verid.timestamp_en; |
| 94 | + struct snd_soc_component *comp = dai->component; |
| 95 | + |
| 96 | + if (ts_enabled && pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) |
| 97 | + snd_soc_add_component_controls(comp, fsl_sai_pb_ctrls, |
| 98 | + ARRAY_SIZE(fsl_sai_pb_ctrls)); |
| 99 | + |
| 100 | + if (ts_enabled && pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) |
| 101 | + snd_soc_add_component_controls(comp, fsl_sai_cp_ctrls, |
| 102 | + ARRAY_SIZE(fsl_sai_cp_ctrls)); |
| 103 | + return 0; |
| 104 | +} |
| 105 | + |
| 106 | static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) |
| 107 | { |
| 108 | struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); |
| 109 | @@ -1030,6 +1114,7 @@ static int fsl_sai_dai_resume(struct snd |
| 110 | } |
| 111 | |
| 112 | static struct snd_soc_dai_driver fsl_sai_dai_template = { |
| 113 | + .pcm_new = fsl_sai_pcm_new, |
| 114 | .probe = fsl_sai_dai_probe, |
| 115 | .playback = { |
| 116 | .stream_name = "CPU-Playback", |
| 117 | @@ -1054,7 +1139,7 @@ static struct snd_soc_dai_driver fsl_sai |
| 118 | }; |
| 119 | |
| 120 | static const struct snd_soc_component_driver fsl_component = { |
| 121 | - .name = "fsl-sai", |
| 122 | + .name = "fsl-sai", |
| 123 | }; |
| 124 | |
| 125 | static struct reg_default fsl_sai_v2_reg_defaults[] = { |
| 126 | @@ -1141,6 +1226,14 @@ static bool fsl_sai_readable_reg(struct |
| 127 | case FSL_SAI_MDIV: |
| 128 | case FSL_SAI_VERID: |
| 129 | case FSL_SAI_PARAM: |
| 130 | + case FSL_SAI_TTCTN: |
| 131 | + case FSL_SAI_RTCTN: |
| 132 | + case FSL_SAI_TTCTL: |
| 133 | + case FSL_SAI_TBCTN: |
| 134 | + case FSL_SAI_TTCAP: |
| 135 | + case FSL_SAI_RTCTL: |
| 136 | + case FSL_SAI_RBCTN: |
| 137 | + case FSL_SAI_RTCAP: |
| 138 | return true; |
| 139 | default: |
| 140 | return false; |
| 141 | @@ -1214,6 +1307,8 @@ static bool fsl_sai_writeable_reg(struct |
| 142 | case FSL_SAI_RMR: |
| 143 | case FSL_SAI_MCTL: |
| 144 | case FSL_SAI_MDIV: |
| 145 | + case FSL_SAI_TTCTL: |
| 146 | + case FSL_SAI_RTCTL: |
| 147 | return true; |
| 148 | default: |
| 149 | return false; |
| 150 | --- a/sound/soc/fsl/fsl_sai.h |
| 151 | +++ b/sound/soc/fsl/fsl_sai.h |
| 152 | @@ -210,6 +210,12 @@ |
| 153 | |
| 154 | #define SAI_FLAG_PMQOS BIT(0) |
| 155 | |
| 156 | +/* SAI timestamp and bitcounter */ |
| 157 | +#define FSL_SAI_xTCTL_TSEN BIT(0) |
| 158 | +#define FSL_SAI_xTCTL_TSINC BIT(1) |
| 159 | +#define FSL_SAI_xTCTL_RTSC BIT(8) |
| 160 | +#define FSL_SAI_xTCTL_RBC BIT(9) |
| 161 | + |
| 162 | struct fsl_sai_soc_data { |
| 163 | unsigned int fifo_depth; |
| 164 | unsigned int fifos; |