summaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl/fsl_micfil.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-08-30 13:45:05 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-08-30 13:45:05 -0700
commit4fb0dacb78c6a041bbd38ddd998df806af5c2c69 (patch)
treef175caac9bc11c78632959a954a6b618fbf8f5c1 /sound/soc/fsl/fsl_micfil.c
parent461f35f014466c4e26dca6be0f431f57297df3f2 (diff)
parent358040e3807754944dbddf948a23c6d914297ed7 (diff)
downloadlinux-stable-4fb0dacb78c6a041bbd38ddd998df806af5c2c69.tar.gz
linux-stable-4fb0dacb78c6a041bbd38ddd998df806af5c2c69.tar.bz2
linux-stable-4fb0dacb78c6a041bbd38ddd998df806af5c2c69.zip
Merge tag 'sound-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "We've received a fairly wide range of changes at this time, including for ALSA and ASoC core, but all of them are rather small changes. Here are some highlights: ALSA / ASoC Core: - Fixes of inconsistent locking around control API helpers - A few new control API functions and cleanups - Workarounds for potential UAFs by delayed kobj releases - Unified PCM copy ops with iov_iter - Continued efforts for ASoC API cleanups ASoC: - An adaptor to allow use of IIO DACs and ADCs in ASoC which pulls in some IIO changes - Create a library function for intlog10() and use it in the NAU8825 driver - Convert drivers to use the more modern maple tree register cache - Lots of work on the SOF framework, AMD and Intel drivers, including a lot of cleanup and new device support - Standardization of the presentation of jacks from drivers - Provision of some generic sound card DT properties - Support for AMD Van Gogh, AMD machines with MAX98388 and NAU8821, AWInic AW88261, Cirrus Logic CS35L36 and CS42L43, various Intel platforms including AVS machines with ES8336 and RT5663, Mediatek MT7986, NXP i.MX93, RealTek RT1017 and StarFive JH7110 Others: - New test coverage including ASoC and topology tests in KUnit; this also involves enabling UML builds of ALSA since that's the default KUnit test environment which pulls in the addition of some stubs to the driver - More enhancement of pcmtest driver - A few fixes / enhancements of MIDI 2.0 UMP core - Using PCI definitions in allover HD-audio code - Support for Cirrus CS35L56 and TI TAS2781 HD-audio sub-codecs - CS35L41 HD-audio sub-codec improvements - Continued emu10k1 improvements" * tag 'sound-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (693 commits) ALSA: pcm: Fix missing fixup call in compat hw_refine ioctl ASoC: dwc: i2s: Fix unused functions ALSA: usb-audio: Don't try to submit URBs after disconnection ALSA: emu10k1: add separate documentation for E-MU cards ALSA: emu10k1: more documentation updates ALSA: emu10k1: de-duplicate audigy-mixer.rst vs. sb-live-mixer.rst ALSA: ump: Fix -Wformat-truncation warnings ALSA: hda: Add missing dependency on CONFIG_EFI for Cirrus/TI sub-codecs ALSA: doc: Fix missing backquote in midi-2.0.rst ALSA: hda/realtek: Add quirk for mute LEDs on HP ENVY x360 15-eu0xxx ALSA: hda/tas2781: Switch back to use struct i2c_driver's .probe() ASoC: soc-core.c: Do not error if a DAI link component is not found ASoC: codecs: Fix error code in aw88261_i2c_probe() ASoC: audio-graph-card.c: move audio_graph_parse_of() ASoC: cs42l43: Use new-style PM runtime macros ALSA: documentation: Add description for USB MIDI 2.0 gadget driver ALSA: ump: Don't create unused substreams for static blocks ALSA: ump: Fill group names for legacy rawmidi substreams ALSA: usb-audio: Attach legacy rawmidi after probing all UMP EPs ALSA: ac97: Fix possible error value of *rac97 ...
Diffstat (limited to 'sound/soc/fsl/fsl_micfil.c')
-rw-r--r--sound/soc/fsl/fsl_micfil.c116
1 files changed, 90 insertions, 26 deletions
diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
index 9d01225dedd9..0d37edb70261 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 use_verid;
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,
+ .use_verid = 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_use_verid(struct device *dev)
+{
+ struct fsl_micfil *micfil = dev_get_drvdata(dev);
+ unsigned int val;
+ int ret;
+
+ if (!micfil->soc->use_verid)
+ 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
@@ -717,12 +764,6 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static const struct snd_soc_dai_ops fsl_micfil_dai_ops = {
- .startup = fsl_micfil_startup,
- .trigger = fsl_micfil_trigger,
- .hw_params = fsl_micfil_hw_params,
-};
-
static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
{
struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev);
@@ -760,8 +801,14 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
return 0;
}
+static const struct snd_soc_dai_ops fsl_micfil_dai_ops = {
+ .probe = fsl_micfil_dai_probe,
+ .startup = fsl_micfil_startup,
+ .trigger = fsl_micfil_trigger,
+ .hw_params = fsl_micfil_hw_params,
+};
+
static struct snd_soc_dai_driver fsl_micfil_dai = {
- .probe = fsl_micfil_dai_probe,
.capture = {
.stream_name = "CPU-Capture",
.channels_min = 1,
@@ -825,6 +872,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 +899,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 +924,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;
@@ -1031,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;
@@ -1044,7 +1100,7 @@ static int fsl_micfil_probe(struct platform_device *pdev)
return -ENOMEM;
micfil->pdev = pdev;
- strncpy(micfil->name, np->name, sizeof(micfil->name) - 1);
+ strscpy(micfil->name, np->name, sizeof(micfil->name));
micfil->soc = of_device_get_match_data(&pdev->dev);
@@ -1150,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_use_verid(&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);
/*
@@ -1174,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);
@@ -1185,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);
@@ -1197,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;
@@ -1219,26 +1297,12 @@ static int __maybe_unused 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 = {