2023-07-27 03:38:05

by Chancel Liu

[permalink] [raw]
Subject: [PATCH 0/3] Update the register list of MICFIL

MICFIL IP is upgraded on i.MX93 platform. Add new registers and new bit
definition.

Chancel Liu (3):
ASoC: fsl_micfil: Add new registers and new bit definition
ASoC: fsl_micfil: Add fsl_micfil_check_version function
ASoC: fsl_micfil: Use SET_SYSTEM_SLEEP_PM_OPS to simplify PM

sound/soc/fsl/fsl_micfil.c | 100 ++++++++++++++++++++++++++++++-------
sound/soc/fsl/fsl_micfil.h | 64 ++++++++++++++++++++++++
2 files changed, 146 insertions(+), 18 deletions(-)

--
2.25.1



2023-07-27 03:55:38

by Chancel Liu

[permalink] [raw]
Subject: [PATCH 2/3] ASoC: fsl_micfil: Add fsl_micfil_check_version function

fsl_micfil_check_version can help to parse the version info in VERID
and PARAM registers. Since the two registers are added only on i.MX93
platform, a member flag called check_version is introduced to soc data
structure which indicates need to check version.

Signed-off-by: Chancel Liu <[email protected]>
---
sound/soc/fsl/fsl_micfil.c | 76 +++++++++++++++++++++++++++++++++++++-
sound/soc/fsl/fsl_micfil.h | 36 ++++++++++++++++++
2 files changed, 110 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
index b15febf19c02..46eda6e8c4b6 100644
--- a/sound/soc/fsl/fsl_micfil.c
+++ b/sound/soc/fsl/fsl_micfil.c
@@ -56,6 +56,8 @@ struct fsl_micfil {
int vad_init_mode;
int vad_enabled;
int vad_detected;
+ struct fsl_micfil_verid verid;
+ struct fsl_micfil_param param;
};

struct fsl_micfil_soc_data {
@@ -64,6 +66,7 @@ struct fsl_micfil_soc_data {
unsigned int dataline;
bool imx;
bool use_edma;
+ bool check_version;
u64 formats;
};

@@ -90,6 +93,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx93 = {
.dataline = 0xf,
.formats = SNDRV_PCM_FMTBIT_S32_LE,
.use_edma = true,
+ .check_version = true,
};

static const struct of_device_id fsl_micfil_dt_ids[] = {
@@ -356,6 +360,49 @@ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
SOC_SINGLE_BOOL_EXT("VAD Detected", 0, hwvad_detected, NULL),
};

+static int fsl_micfil_check_version(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ unsigned int val;
+ int ret;
+
+ if (!micfil->soc->check_version)
+ return 0;
+
+ ret = regmap_read(micfil->regmap, REG_MICFIL_VERID, &val);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(dev, "VERID: 0x%016X\n", val);
+
+ micfil->verid.version = val &
+ (MICFIL_VERID_MAJOR_MASK | MICFIL_VERID_MINOR_MASK);
+ micfil->verid.version >>= MICFIL_VERID_MINOR_SHIFT;
+ micfil->verid.feature = val & MICFIL_VERID_FEATURE_MASK;
+
+ ret = regmap_read(micfil->regmap, REG_MICFIL_PARAM, &val);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(dev, "PARAM: 0x%016X\n", val);
+
+ micfil->param.hwvad_num = (val & MICFIL_PARAM_NUM_HWVAD_MASK) >>
+ MICFIL_PARAM_NUM_HWVAD_SHIFT;
+ micfil->param.hwvad_zcd = val & MICFIL_PARAM_HWVAD_ZCD;
+ micfil->param.hwvad_energy_mode = val & MICFIL_PARAM_HWVAD_ENERGY_MODE;
+ micfil->param.hwvad = val & MICFIL_PARAM_HWVAD;
+ micfil->param.dc_out_bypass = val & MICFIL_PARAM_DC_OUT_BYPASS;
+ micfil->param.dc_in_bypass = val & MICFIL_PARAM_DC_IN_BYPASS;
+ micfil->param.low_power = val & MICFIL_PARAM_LOW_POWER;
+ micfil->param.fil_out_width = val & MICFIL_PARAM_FIL_OUT_WIDTH;
+ micfil->param.fifo_ptrwid = (val & MICFIL_PARAM_FIFO_PTRWID_MASK) >>
+ MICFIL_PARAM_FIFO_PTRWID_SHIFT;
+ micfil->param.npair = (val & MICFIL_PARAM_NPAIR_MASK) >>
+ MICFIL_PARAM_NPAIR_SHIFT;
+
+ return 0;
+}
+
/* The SRES is a self-negated bit which provides the CPU with the
* capability to initialize the PDM Interface module through the
* slave-bus interface. This bit always reads as zero, and this
@@ -1037,6 +1084,9 @@ static irqreturn_t hwvad_err_isr(int irq, void *devid)
return IRQ_HANDLED;
}

+static int fsl_micfil_runtime_suspend(struct device *dev);
+static int fsl_micfil_runtime_resume(struct device *dev);
+
static int fsl_micfil_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -1156,6 +1206,25 @@ static int fsl_micfil_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, micfil);

pm_runtime_enable(&pdev->dev);
+ if (!pm_runtime_enabled(&pdev->dev)) {
+ ret = fsl_micfil_runtime_resume(&pdev->dev);
+ if (ret)
+ goto err_pm_disable;
+ }
+
+ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret < 0)
+ goto err_pm_get_sync;
+
+ /* Get micfil version */
+ ret = fsl_micfil_check_version(&pdev->dev);
+ if (ret < 0)
+ dev_warn(&pdev->dev, "Error reading MICFIL version: %d\n", ret);
+
+ ret = pm_runtime_put_sync(&pdev->dev);
+ if (ret < 0 && ret != -ENOSYS)
+ goto err_pm_get_sync;
+
regcache_cache_only(micfil->regmap, true);

/*
@@ -1180,6 +1249,9 @@ static int fsl_micfil_probe(struct platform_device *pdev)

return ret;

+err_pm_get_sync:
+ if (!pm_runtime_status_suspended(&pdev->dev))
+ fsl_micfil_runtime_suspend(&pdev->dev);
err_pm_disable:
pm_runtime_disable(&pdev->dev);

@@ -1191,7 +1263,7 @@ static void fsl_micfil_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
}

-static int __maybe_unused fsl_micfil_runtime_suspend(struct device *dev)
+static int fsl_micfil_runtime_suspend(struct device *dev)
{
struct fsl_micfil *micfil = dev_get_drvdata(dev);

@@ -1203,7 +1275,7 @@ static int __maybe_unused fsl_micfil_runtime_suspend(struct device *dev)
return 0;
}

-static int __maybe_unused fsl_micfil_runtime_resume(struct device *dev)
+static int fsl_micfil_runtime_resume(struct device *dev)
{
struct fsl_micfil *micfil = dev_get_drvdata(dev);
int ret;
diff --git a/sound/soc/fsl/fsl_micfil.h b/sound/soc/fsl/fsl_micfil.h
index b3c392ef5daf..231a52aff024 100644
--- a/sound/soc/fsl/fsl_micfil.h
+++ b/sound/soc/fsl/fsl_micfil.h
@@ -174,4 +174,40 @@
#define MICFIL_HWVAD_ENVELOPE_MODE 0
#define MICFIL_HWVAD_ENERGY_MODE 1

+/**
+ * struct fsl_micfil_verid - version id data
+ * @version: version number
+ * @feature: feature specification number
+ */
+struct fsl_micfil_verid {
+ u32 version;
+ u32 feature;
+};
+
+/**
+ * struct fsl_micfil_param - parameter data
+ * @hwvad_num: the number of HWVADs
+ * @hwvad_zcd: HWVAD zero-cross detector is active
+ * @hwvad_energy_mode: HWVAD energy mode is active
+ * @hwvad: HWVAD is active
+ * @dc_out_bypass: points out if the output DC remover is disabled
+ * @dc_in_bypass: points out if the input DC remover is disabled
+ * @low_power: low power decimation filter
+ * @fil_out_width: filter output width
+ * @fifo_ptrwid: FIFO pointer width
+ * @npair: number of microphone pairs
+ */
+struct fsl_micfil_param {
+ u32 hwvad_num;
+ bool hwvad_zcd;
+ bool hwvad_energy_mode;
+ bool hwvad;
+ bool dc_out_bypass;
+ bool dc_in_bypass;
+ bool low_power;
+ bool fil_out_width;
+ u32 fifo_ptrwid;
+ u32 npair;
+};
+
#endif /* _FSL_MICFIL_H */
--
2.25.1


2023-07-27 03:57:49

by Chancel Liu

[permalink] [raw]
Subject: [PATCH 1/3] ASoC: fsl_micfil: Add new registers and new bit definition

MICFIL IP is upgraded on i.MX93 platform. These new registers and new
bit definition are added to complete the register list.

Signed-off-by: Chancel Liu <[email protected]>
---
sound/soc/fsl/fsl_micfil.c | 6 ++++++
sound/soc/fsl/fsl_micfil.h | 28 ++++++++++++++++++++++++++++
2 files changed, 34 insertions(+)

diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
index 3f08082a55be..b15febf19c02 100644
--- a/sound/soc/fsl/fsl_micfil.c
+++ b/sound/soc/fsl/fsl_micfil.c
@@ -825,6 +825,9 @@ static bool fsl_micfil_readable_reg(struct device *dev, unsigned int reg)
case REG_MICFIL_DC_CTRL:
case REG_MICFIL_OUT_CTRL:
case REG_MICFIL_OUT_STAT:
+ case REG_MICFIL_FSYNC_CTRL:
+ case REG_MICFIL_VERID:
+ case REG_MICFIL_PARAM:
case REG_MICFIL_VAD0_CTRL1:
case REG_MICFIL_VAD0_CTRL2:
case REG_MICFIL_VAD0_STAT:
@@ -849,6 +852,7 @@ static bool fsl_micfil_writeable_reg(struct device *dev, unsigned int reg)
case REG_MICFIL_DC_CTRL:
case REG_MICFIL_OUT_CTRL:
case REG_MICFIL_OUT_STAT: /* Write 1 to Clear */
+ case REG_MICFIL_FSYNC_CTRL:
case REG_MICFIL_VAD0_CTRL1:
case REG_MICFIL_VAD0_CTRL2:
case REG_MICFIL_VAD0_STAT: /* Write 1 to Clear */
@@ -873,6 +877,8 @@ static bool fsl_micfil_volatile_reg(struct device *dev, unsigned int reg)
case REG_MICFIL_DATACH5:
case REG_MICFIL_DATACH6:
case REG_MICFIL_DATACH7:
+ case REG_MICFIL_VERID:
+ case REG_MICFIL_PARAM:
case REG_MICFIL_VAD0_STAT:
case REG_MICFIL_VAD0_NDATA:
return true;
diff --git a/sound/soc/fsl/fsl_micfil.h b/sound/soc/fsl/fsl_micfil.h
index 9237a1c4cb8f..b3c392ef5daf 100644
--- a/sound/soc/fsl/fsl_micfil.h
+++ b/sound/soc/fsl/fsl_micfil.h
@@ -24,6 +24,9 @@
#define REG_MICFIL_DC_CTRL 0x64
#define REG_MICFIL_OUT_CTRL 0x74
#define REG_MICFIL_OUT_STAT 0x7C
+#define REG_MICFIL_FSYNC_CTRL 0x80
+#define REG_MICFIL_VERID 0x84
+#define REG_MICFIL_PARAM 0x88
#define REG_MICFIL_VAD0_CTRL1 0x90
#define REG_MICFIL_VAD0_CTRL2 0x94
#define REG_MICFIL_VAD0_STAT 0x98
@@ -39,6 +42,8 @@
#define MICFIL_CTRL1_DBG BIT(28)
#define MICFIL_CTRL1_SRES BIT(27)
#define MICFIL_CTRL1_DBGE BIT(26)
+#define MICFIL_CTRL1_DECFILS BIT(20)
+#define MICFIL_CTRL1_FSYNCEN BIT(16)

#define MICFIL_CTRL1_DISEL_DISABLE 0
#define MICFIL_CTRL1_DISEL_DMA 1
@@ -82,6 +87,29 @@
#define MICFIL_DC_CUTOFF_152Hz 2
#define MICFIL_DC_BYPASS 3

+/* MICFIL VERID Register -- REG_MICFIL_VERID */
+#define MICFIL_VERID_MAJOR_SHIFT 24
+#define MICFIL_VERID_MAJOR_MASK GENMASK(31, 24)
+#define MICFIL_VERID_MINOR_SHIFT 16
+#define MICFIL_VERID_MINOR_MASK GENMASK(23, 16)
+#define MICFIL_VERID_FEATURE_SHIFT 0
+#define MICFIL_VERID_FEATURE_MASK GENMASK(15, 0)
+
+/* MICFIL PARAM Register -- REG_MICFIL_PARAM */
+#define MICFIL_PARAM_NUM_HWVAD_SHIFT 24
+#define MICFIL_PARAM_NUM_HWVAD_MASK GENMASK(27, 24)
+#define MICFIL_PARAM_HWVAD_ZCD BIT(19)
+#define MICFIL_PARAM_HWVAD_ENERGY_MODE BIT(17)
+#define MICFIL_PARAM_HWVAD BIT(16)
+#define MICFIL_PARAM_DC_OUT_BYPASS BIT(11)
+#define MICFIL_PARAM_DC_IN_BYPASS BIT(10)
+#define MICFIL_PARAM_LOW_POWER BIT(9)
+#define MICFIL_PARAM_FIL_OUT_WIDTH BIT(8)
+#define MICFIL_PARAM_FIFO_PTRWID_SHIFT 4
+#define MICFIL_PARAM_FIFO_PTRWID_MASK GENMASK(7, 4)
+#define MICFIL_PARAM_NPAIR_SHIFT 0
+#define MICFIL_PARAM_NPAIR_MASK GENMASK(3, 0)
+
/* MICFIL HWVAD0 Control 1 Register -- REG_MICFIL_VAD0_CTRL1*/
#define MICFIL_VAD0_CTRL1_CHSEL GENMASK(26, 24)
#define MICFIL_VAD0_CTRL1_CICOSR GENMASK(19, 16)
--
2.25.1


2023-07-27 04:34:12

by Chancel Liu

[permalink] [raw]
Subject: [PATCH 3/3] ASoC: fsl_micfil: Use SET_SYSTEM_SLEEP_PM_OPS to simplify PM

Use SET_SYSTEM_SLEEP_PM_OPS to simplify suspend and resume function.
fsl_micfil_suspend() and fsl_micfil_resume() can be deleted.

Signed-off-by: Chancel Liu <[email protected]>
---
sound/soc/fsl/fsl_micfil.c | 18 ++----------------
1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
index 46eda6e8c4b6..6f5f8a886764 100644
--- a/sound/soc/fsl/fsl_micfil.c
+++ b/sound/soc/fsl/fsl_micfil.c
@@ -1297,26 +1297,12 @@ static int fsl_micfil_runtime_resume(struct device *dev)
return 0;
}

-static int __maybe_unused fsl_micfil_suspend(struct device *dev)
-{
- pm_runtime_force_suspend(dev);
-
- return 0;
-}
-
-static int __maybe_unused fsl_micfil_resume(struct device *dev)
-{
- pm_runtime_force_resume(dev);
-
- return 0;
-}
-
static const struct dev_pm_ops fsl_micfil_pm_ops = {
SET_RUNTIME_PM_OPS(fsl_micfil_runtime_suspend,
fsl_micfil_runtime_resume,
NULL)
- SET_SYSTEM_SLEEP_PM_OPS(fsl_micfil_suspend,
- fsl_micfil_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
};

static struct platform_driver fsl_micfil_driver = {
--
2.25.1