#include <linux/err.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/hwmon.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/gpio/consumer.h>
        return 0;
 }
 
+static int tas2764_read_die_temp(struct tas2764_priv *tas2764, long *result)
+{
+       int ret, reg;
+
+       ret = regmap_read(tas2764->regmap, TAS2764_TEMP, ®);
+       if (ret)
+               return ret;
+       /*
+        * 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.
+        */
+       *result = (reg - 93) * 1000;
+       return 0;
+}
+
+static umode_t tas2764_hwmon_is_visible(const void *data,
+                                       enum hwmon_sensor_types type, u32 attr,
+                                       int channel)
+{
+       if (type != hwmon_temp)
+               return 0;
+
+       switch (attr) {
+       case hwmon_temp_input:
+               return 0444;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int tas2764_hwmon_read(struct device *dev,
+                             enum hwmon_sensor_types type,
+                             u32 attr, int channel, long *val)
+{
+       struct tas2764_priv *tas2764 = dev_get_drvdata(dev);
+       int ret;
+
+       switch (attr) {
+       case hwmon_temp_input:
+               ret = tas2764_read_die_temp(tas2764, val);
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+               break;
+       }
+
+       return ret;
+}
+
+static const struct hwmon_channel_info *const tas2764_hwmon_info[] = {
+       HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+       NULL
+};
+
+static const struct hwmon_ops tas2764_hwmon_ops = {
+       .is_visible     = tas2764_hwmon_is_visible,
+       .read           = tas2764_hwmon_read,
+};
+
+static const struct hwmon_chip_info tas2764_hwmon_chip_info = {
+       .ops    = &tas2764_hwmon_ops,
+       .info   = tas2764_hwmon_info,
+};
+
 static int tas2764_codec_probe(struct snd_soc_component *component)
 {
        struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
                }
        }
 
+       if (IS_REACHABLE(CONFIG_HWMON)) {
+               struct device *hwmon;
+
+               hwmon = devm_hwmon_device_register_with_info(&client->dev, "tas2764",
+                                                       tas2764,
+                                                       &tas2764_hwmon_chip_info,
+                                                       NULL);
+               if (IS_ERR(hwmon)) {
+                       return dev_err_probe(&client->dev, PTR_ERR(hwmon),
+                                            "Failed to register temp sensor\n");
+               }
+       }
+
+
        return devm_snd_soc_register_component(tas2764->dev,
                                               &soc_component_driver_tas2764,
                                               tas2764_dai_driver,