|
2 | 2 | /* Copyright (C) 2020 MediaTek Inc. */
|
3 | 3 |
|
4 | 4 | #include <linux/etherdevice.h>
|
| 5 | +#include <linux/hwmon.h> |
| 6 | +#include <linux/hwmon-sysfs.h> |
| 7 | +#include <linux/thermal.h> |
5 | 8 | #include <linux/firmware.h>
|
6 | 9 | #include "mt7921.h"
|
7 | 10 | #include "../mt76_connac2_mac.h"
|
@@ -51,6 +54,57 @@ static const struct ieee80211_iface_combination if_comb_chanctx[] = {
|
51 | 54 | }
|
52 | 55 | };
|
53 | 56 |
|
| 57 | +static ssize_t mt7921_thermal_temp_show(struct device *dev, |
| 58 | + struct device_attribute *attr, |
| 59 | + char *buf) |
| 60 | +{ |
| 61 | + switch (to_sensor_dev_attr(attr)->index) { |
| 62 | + case 0: { |
| 63 | + struct mt7921_phy *phy = dev_get_drvdata(dev); |
| 64 | + struct mt7921_dev *mdev = phy->dev; |
| 65 | + int temperature; |
| 66 | + |
| 67 | + mt7921_mutex_acquire(mdev); |
| 68 | + temperature = mt7921_mcu_get_temperature(phy); |
| 69 | + mt7921_mutex_release(mdev); |
| 70 | + |
| 71 | + if (temperature < 0) |
| 72 | + return temperature; |
| 73 | + /* display in millidegree Celsius */ |
| 74 | + return sprintf(buf, "%u\n", temperature * 1000); |
| 75 | + } |
| 76 | + default: |
| 77 | + return -EINVAL; |
| 78 | + } |
| 79 | +} |
| 80 | +static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7921_thermal_temp, 0); |
| 81 | + |
| 82 | +static struct attribute *mt7921_hwmon_attrs[] = { |
| 83 | + &sensor_dev_attr_temp1_input.dev_attr.attr, |
| 84 | + NULL, |
| 85 | +}; |
| 86 | +ATTRIBUTE_GROUPS(mt7921_hwmon); |
| 87 | + |
| 88 | +static int mt7921_thermal_init(struct mt7921_phy *phy) |
| 89 | +{ |
| 90 | + struct wiphy *wiphy = phy->mt76->hw->wiphy; |
| 91 | + struct device *hwmon; |
| 92 | + const char *name; |
| 93 | + |
| 94 | + if (!IS_REACHABLE(CONFIG_HWMON)) |
| 95 | + return 0; |
| 96 | + |
| 97 | + name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7921_%s", |
| 98 | + wiphy_name(wiphy)); |
| 99 | + |
| 100 | + hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy, |
| 101 | + mt7921_hwmon_groups); |
| 102 | + if (IS_ERR(hwmon)) |
| 103 | + return PTR_ERR(hwmon); |
| 104 | + |
| 105 | + return 0; |
| 106 | +} |
| 107 | + |
54 | 108 | static void
|
55 | 109 | mt7921_regd_notifier(struct wiphy *wiphy,
|
56 | 110 | struct regulatory_request *request)
|
@@ -363,6 +417,12 @@ static void mt7921_init_work(struct work_struct *work)
|
363 | 417 | return;
|
364 | 418 | }
|
365 | 419 |
|
| 420 | + ret = mt7921_thermal_init(&dev->phy); |
| 421 | + if (ret) { |
| 422 | + dev_err(dev->mt76.dev, "thermal init failed\n"); |
| 423 | + return; |
| 424 | + } |
| 425 | + |
366 | 426 | /* we support chip reset now */
|
367 | 427 | dev->hw_init_done = true;
|
368 | 428 |
|
|
0 commit comments