Expose the codec die temperature to the hwmon interface Signed-off-by: James Calligeros <jcalligeros99@xxxxxxxxx> --- sound/soc/codecs/tas2764.c | 70 +++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index b0d016f85f7fd57bec36b33db5e8c2bd242b5b94..670c59e57997a7988af837bd58da695ad773ae14 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -8,6 +8,7 @@ #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> @@ -605,6 +606,61 @@ static struct attribute *tas2764_sysfs_attrs[] = { }; ATTRIBUTE_GROUPS(tas2764_sysfs); +#if defined(CONFIG_HWMON) +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 = i2c_get_clientdata(to_i2c_client(dev)); + int ret; + + switch (attr) { + case hwmon_temp_input: + ret = tas2764_read_die_temp(tas2764, (int *)val); + if (!ret) + *val *= 1000; + 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, +}; +#endif + static int tas2764_codec_probe(struct snd_soc_component *component) { struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); @@ -882,6 +938,20 @@ static int tas2764_i2c_probe(struct i2c_client *client) } } + 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, -- 2.48.1