]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ASoC: tas2764: Deal with bogus initial temperature register value
authorJames Calligeros <jcalligeros99@gmail.com>
Sun, 3 May 2026 12:23:23 +0000 (22:23 +1000)
committerMark Brown <broonie@kernel.org>
Tue, 5 May 2026 01:49:20 +0000 (10:49 +0900)
The TAS2764 datasheet specifies that the chip initialises the
temperature register such that the temperature reading is 2.6 *C,
ostensibly to prevent tripping the chip's protection circuitry.
The chip is not capable of representing 2.6 *C however, and the
register is actually initialised to 0. The ADC does not start
sampling until the chip is powered up, and the last sampled
temperature persists in the register during software shutdown.
Therefore, any reading returning 0 is almost certain to be
from before the ADC has actually started sampling, meaning that
it is invalid.

Return -ENODATA early if the temperature has not yet been sampled
by the chip, and indicate a fault condition using HWMON_T_FAULT.

Fixes: 186dfc85f9a8 ("ASoC: tas2764: expose die temp to hwmon")
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/tas2764.c

index 6aab6d2b741910d60efb9b28ec0887c5570604f2..55211266927d1ad719c488525512a7a18f867d6c 100644 (file)
@@ -684,18 +684,33 @@ static int tas2764_read_die_temp(struct tas2764_priv *tas2764, long *result)
         * As per datasheet, subtract 93 from raw value to get degrees
         * Celsius. hwmon wants millidegrees.
         *
-        * NOTE: The chip will initialise the TAS2764_TEMP register to
-        * 2.6 *C to avoid triggering temperature protection. Since the
-        * ADC is powered down during software shutdown, this value will
-        * persist until the chip is fully powered up (e.g. the PCM it's
-        * attached to is opened). The ADC will power down again when
-        * the chip is put back into software shutdown, with the last
-        * value sampled persisting in the ADC's register.
+        * NOTE: The TAS2764 datasheet mentions initialising TAS2764_TEMP
+        * such that the temperature is 2.6 *C, however the register
+        * is actually initialised to 0. The ADC is also powered down during
+        * software shutdown. The last sampled temperature will persist
+        * in the register while the amp is in this power state.
         */
+       if (reg == 0)
+               return -ENODATA;
+
        *result = (reg - 93) * 1000;
        return 0;
 }
 
+static int tas2764_hwmon_is_fault(struct tas2764_priv *tas2764, long *result)
+{
+       int ret;
+       long temp;
+
+       ret = tas2764_read_die_temp(tas2764, &temp);
+       if (ret == -ENODATA) {
+               *result = true;
+               return 0;
+       }
+
+       return ret;
+}
+
 static umode_t tas2764_hwmon_is_visible(const void *data,
                                        enum hwmon_sensor_types type, u32 attr,
                                        int channel)
@@ -705,6 +720,7 @@ static umode_t tas2764_hwmon_is_visible(const void *data,
 
        switch (attr) {
        case hwmon_temp_input:
+       case hwmon_temp_fault:
                return 0444;
        default:
                break;
@@ -724,6 +740,9 @@ static int tas2764_hwmon_read(struct device *dev,
        case hwmon_temp_input:
                ret = tas2764_read_die_temp(tas2764, val);
                break;
+       case hwmon_temp_fault:
+               ret = tas2764_hwmon_is_fault(tas2764, val);
+               break;
        default:
                ret = -EOPNOTSUPP;
                break;
@@ -733,7 +752,7 @@ static int tas2764_hwmon_read(struct device *dev,
 }
 
 static const struct hwmon_channel_info *const tas2764_hwmon_info[] = {
-       HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+       HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_FAULT),
        NULL
 };