OSDN Git Service

ASoC: max98396: Make data monitor features configurable
authorDaniel Mack <daniel@zonque.org>
Fri, 26 Aug 2022 08:59:27 +0000 (10:59 +0200)
committerMark Brown <broonie@kernel.org>
Wed, 31 Aug 2022 11:13:07 +0000 (12:13 +0100)
Allow the data monitor features to be enabled explicitly, and enable control
over their details.

Signed-off-by: Daniel Mack <daniel@zonque.org>
Link: https://lore.kernel.org/r/20220826085927.2336224-2-daniel@zonque.org
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/max98396.c
sound/soc/codecs/max98396.h

index 364b4b7..a7b6a23 100644 (file)
@@ -1483,6 +1483,87 @@ static int max98396_probe(struct snd_soc_component *component)
                           MAX98396_CLK_MON_AUTO_RESTART_MASK,
                           MAX98396_CLK_MON_AUTO_RESTART_MASK);
 
+       regmap_update_bits(max98396->regmap,
+                          MAX98396_R203F_ENABLE_CTRLS,
+                          MAX98396_CTRL_DMON_STUCK_EN_MASK,
+                          max98396->dmon_stuck_enable ?
+                               MAX98396_CTRL_DMON_STUCK_EN_MASK : 0);
+
+       regmap_update_bits(max98396->regmap,
+                          MAX98396_R203F_ENABLE_CTRLS,
+                          MAX98396_CTRL_DMON_MAG_EN_MASK,
+                          max98396->dmon_mag_enable ?
+                               MAX98396_CTRL_DMON_MAG_EN_MASK : 0);
+
+       switch (max98396->dmon_duration) {
+       case 64:
+               regmap_update_bits(max98396->regmap,
+                                  MAX98396_R2039_DATA_MON_CTRL,
+                                  MAX98396_DMON_DURATION_MASK, 0);
+               break;
+       case 256:
+               regmap_update_bits(max98396->regmap,
+                                  MAX98396_R2039_DATA_MON_CTRL,
+                                  MAX98396_DMON_DURATION_MASK, 1);
+               break;
+       case 1024:
+               regmap_update_bits(max98396->regmap,
+                                  MAX98396_R2039_DATA_MON_CTRL,
+                                  MAX98396_DMON_DURATION_MASK, 2);
+               break;
+       case 4096:
+               regmap_update_bits(max98396->regmap,
+                                  MAX98396_R2039_DATA_MON_CTRL,
+                                  MAX98396_DMON_DURATION_MASK, 3);
+               break;
+       default:
+               dev_err(component->dev, "Invalid DMON duration %d\n",
+                       max98396->dmon_duration);
+       }
+
+       switch (max98396->dmon_stuck_threshold) {
+       case 15:
+               regmap_update_bits(max98396->regmap,
+                                  MAX98396_R2039_DATA_MON_CTRL,
+                                  MAX98396_DMON_STUCK_THRESH_MASK,
+                                  0 << MAX98396_DMON_STUCK_THRESH_SHIFT);
+               break;
+       case 13:
+               regmap_update_bits(max98396->regmap,
+                                  MAX98396_R2039_DATA_MON_CTRL,
+                                  MAX98396_DMON_STUCK_THRESH_MASK,
+                                  1 << MAX98396_DMON_STUCK_THRESH_SHIFT);
+               break;
+       case 22:
+               regmap_update_bits(max98396->regmap,
+                                  MAX98396_R2039_DATA_MON_CTRL,
+                                  MAX98396_DMON_STUCK_THRESH_MASK,
+                                  2 << MAX98396_DMON_STUCK_THRESH_SHIFT);
+               break;
+       case 9:
+               regmap_update_bits(max98396->regmap,
+                                  MAX98396_R2039_DATA_MON_CTRL,
+                                  MAX98396_DMON_STUCK_THRESH_MASK,
+                                  3 << MAX98396_DMON_STUCK_THRESH_SHIFT);
+               break;
+       default:
+               dev_err(component->dev, "Invalid DMON stuck threshold %d\n",
+                       max98396->dmon_stuck_threshold);
+       }
+
+       switch (max98396->dmon_mag_threshold) {
+       case 2 ... 5:
+               regmap_update_bits(max98396->regmap,
+                                  MAX98396_R2039_DATA_MON_CTRL,
+                                  MAX98396_DMON_STUCK_THRESH_MASK,
+                                  (5 - max98396->dmon_mag_threshold)
+                                       << MAX98396_DMON_MAG_THRESH_SHIFT);
+               break;
+       default:
+               dev_err(component->dev, "Invalid DMON magnitude threshold %d\n",
+                       max98396->dmon_mag_threshold);
+       }
+
        /* Speaker Amplifier PCM RX Enable by default */
        regmap_update_bits(max98396->regmap,
                           MAX98396_R205E_PCM_RX_EN,
@@ -1614,6 +1695,27 @@ static void max98396_read_device_property(struct device *dev,
                max98396->bypass_slot = value & 0xF;
        else
                max98396->bypass_slot = 0;
+
+       max98396->dmon_stuck_enable =
+               device_property_read_bool(dev, "adi,dmon-stuck-enable");
+
+       if (!device_property_read_u32(dev, "adi,dmon-stuck-threshold-bits", &value))
+               max98396->dmon_stuck_threshold = value;
+       else
+               max98396->dmon_stuck_threshold = 15;
+
+       max98396->dmon_mag_enable =
+               device_property_read_bool(dev, "adi,dmon-magnitude-enable");
+
+       if (!device_property_read_u32(dev, "adi,dmon-magnitude-threshold-bits", &value))
+               max98396->dmon_mag_threshold = value;
+       else
+               max98396->dmon_mag_threshold = 5;
+
+       if (!device_property_read_u32(dev, "adi,dmon-duration-ms", &value))
+               max98396->dmon_duration = value;
+       else
+               max98396->dmon_duration = 64;
 }
 
 static void max98396_core_supplies_disable(void *priv)
index 7278c77..d396aa3 100644 (file)
 #define MAX98396_CLK_MON_AUTO_RESTART_MASK     (0x1 << 0)
 #define MAX98396_CLK_MON_AUTO_RESTART_SHIFT    (0)
 
+/* MAX98396_R2039_DATA_MON_CTRL */
+#define MAX98396_DMON_MAG_THRESH_SHIFT         (4)
+#define MAX98396_DMON_MAG_THRESH_MASK          (0x3 << MAX98396_DMON_MAG_THRESH_SHIFT)
+#define MAX98396_DMON_STUCK_THRESH_SHIFT       (2)
+#define MAX98396_DMON_STUCK_THRESH_MASK                (0x3 << MAX98396_DMON_STUCK_THRESH_SHIFT)
+#define MAX98396_DMON_DURATION_MASK            (0x3)
+
 /* MAX98396_R203F_ENABLE_CTRLS */
 #define MAX98396_CTRL_CMON_EN_SHIFT            (0)
+#define MAX98396_CTRL_DMON_STUCK_EN_MASK       (0x1 << 1)
+#define MAX98396_CTRL_DMON_MAG_EN_MASK         (0x1 << 2)
 
 /* MAX98396_R2041_PCM_MODE_CFG */
 #define MAX98396_PCM_MODE_CFG_FORMAT_MASK      (0x7 << 3)
@@ -305,6 +314,11 @@ struct max98396_priv {
        unsigned int i_slot;
        unsigned int spkfb_slot;
        unsigned int bypass_slot;
+       bool dmon_stuck_enable;
+       unsigned int dmon_stuck_threshold;
+       bool dmon_mag_enable;
+       unsigned int dmon_mag_threshold;
+       unsigned int dmon_duration;
        bool interleave_mode;
        bool tdm_mode;
        int tdm_max_samplerate;