Linux 硬體監控核心 API¶
Guenter Roeck
簡介¶
本文件介紹了希望使用硬體監控框架的硬體監控驅動程式可以使用的 API。
本文件不描述什麼是硬體監控 (hwmon) 驅動程式或裝置。它也不描述使用者空間可以用來與硬體監控裝置通訊的 API。如果您想了解這一點,請閱讀以下檔案:sysfs 檔案的命名和資料格式標準。
有關如何編寫和改進 hwmon 驅動程式的更多指南,請閱讀如何使您的補丁被 Hwmon 子系統接受。
API¶
每個硬體監控驅動程式必須 #include <linux/hwmon.h>,在某些情況下,還必須 #include <linux/hwmon-sysfs.h>。 linux/hwmon.h 聲明瞭以下注冊/登出函式
struct device *
hwmon_device_register_with_info(struct device *dev,
const char *name, void *drvdata,
const struct hwmon_chip_info *info,
const struct attribute_group **extra_groups);
struct device *
devm_hwmon_device_register_with_info(struct device *dev,
const char *name,
void *drvdata,
const struct hwmon_chip_info *info,
const struct attribute_group **extra_groups);
void hwmon_device_unregister(struct device *dev);
char *hwmon_sanitize_name(const char *name);
char *devm_hwmon_sanitize_name(struct device *dev, const char *name);
hwmon_device_register_with_info 註冊一個硬體監控裝置。它在硬體監控核心中建立標準的 sysfs 屬性,使驅動程式能夠專注於從晶片讀取和寫入,而不必為 sysfs 屬性而煩惱。父裝置引數以及晶片引數不得為 NULL。其引數在下面有更詳細的描述。
devm_hwmon_device_register_with_info 類似於 hwmon_device_register_with_info。但是,它是裝置管理的,這意味著 hwmon 裝置不必透過移除函式顯式移除。
所有其他硬體監控設備註冊功能都已棄用,不得在新驅動程式中使用。
hwmon_device_unregister 登出已註冊的硬體監控裝置。此函式的引數是指向已註冊的硬體監控裝置結構的指標。如果硬體監控裝置是透過 hwmon_device_register_with_info 註冊的,則必須從驅動程式移除函式中呼叫此函式。
所有受支援的 hwmon 設備註冊函式只接受有效的裝置名稱。包含無效字元(空格、“*”或“-”)的裝置名稱將被拒絕。如果將 NULL 作為 name 引數傳遞,硬體監控裝置名稱將從父裝置名稱派生。
如果驅動程式不使用靜態裝置名稱(例如,它使用 dev_name()),因此無法確保名稱僅包含有效字元,則可以使用 hwmon_sanitize_name。此便利函式將複製字串並將任何無效字元替換為下劃線。它將為新字串分配記憶體,呼叫者有責任在移除裝置時釋放記憶體。
devm_hwmon_sanitize_name 是 hwmon_sanitize_name 的資源管理版本;記憶體將在裝置移除時自動釋放。
使用 devm_hwmon_device_register_with_info()¶
hwmon_device_register_with_info() 註冊一個硬體監控裝置。此函式的引數是
|
指向父裝置的指標 |
const char *name |
裝置名稱 |
void *drvdata |
驅動程式私有資料 |
const struct hwmon_chip_info *info |
指向晶片描述的指標。 |
const struct attribute_group **extra_groups |
附加的非標準 sysfs 屬性組的以 null 結尾的列表。 |
此函式成功時返回指向已建立的硬體監控裝置的指標,失敗時返回負錯誤程式碼。
hwmon_chip_info 結構如下所示
struct hwmon_chip_info {
const struct hwmon_ops *ops;
const struct hwmon_channel_info * const *info;
};
它包含以下欄位
- ops
指向裝置操作的指標。
- info
以 NULL 結尾的裝置通道描述符列表。
hwmon 操作列表定義為
struct hwmon_ops {
umode_t (*is_visible)(const void *, enum hwmon_sensor_types type,
u32 attr, int);
int (*read)(struct device *, enum hwmon_sensor_types type,
u32 attr, int, long *);
int (*write)(struct device *, enum hwmon_sensor_types type,
u32 attr, int, long);
};
它定義了以下操作。
- is_visible
指向為每個受支援的屬性返回檔案模式的函式的指標。此函式是強制性的。
- read
指向從晶片讀取值的函式的指標。此函式是可選的,但如果存在任何可讀屬性,則必須提供。
- write
指向將值寫入晶片的函式的指標。此函式是可選的,但如果存在任何可寫屬性,則必須提供。
每個感測器通道都使用 struct hwmon_channel_info 描述,其定義如下
struct hwmon_channel_info {
enum hwmon_sensor_types type;
u32 *config;
};
它包含以下欄位
- type
硬體監控感測器型別。
支援的感測器型別有
hwmon_chip
一種虛擬感測器型別,用於描述未繫結到特定輸入或輸出的屬性
hwmon_temp
溫度感測器
hwmon_in
電壓感測器
hwmon_curr
電流感測器
hwmon_power
功率感測器
hwmon_energy
能量感測器
hwmon_humidity
溼度感測器
hwmon_fan
風扇速度感測器
hwmon_pwm
PWM 控制
- config
指向給定型別的每個感測器的配置值的以 0 結尾的列表的指標。每個值都是描述單個感測器支援的屬性的位值的組合。
例如,這是 LM75 相容感測器晶片的完整描述檔案。該晶片只有一個溫度感測器。驅動程式希望在熱子系統 (HWMON_C_REGISTER_TZ) 中註冊,它支援 update_interval 屬性 (HWMON_C_UPDATE_INTERVAL)。該晶片支援讀取溫度 (HWMON_T_INPUT),它具有最高溫度暫存器 (HWMON_T_MAX) 以及最高溫度滯後暫存器 (HWMON_T_MAX_HYST)
static const u32 lm75_chip_config[] = {
HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL,
0
};
static const struct hwmon_channel_info lm75_chip = {
.type = hwmon_chip,
.config = lm75_chip_config,
};
static const u32 lm75_temp_config[] = {
HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST,
0
};
static const struct hwmon_channel_info lm75_temp = {
.type = hwmon_temp,
.config = lm75_temp_config,
};
static const struct hwmon_channel_info * const lm75_info[] = {
&lm75_chip,
&lm75_temp,
NULL
};
The HWMON_CHANNEL_INFO() macro can and should be used when possible.
With this macro, the above example can be simplified to
static const struct hwmon_channel_info * const lm75_info[] = {
HWMON_CHANNEL_INFO(chip,
HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL),
HWMON_CHANNEL_INFO(temp,
HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST),
NULL
};
The remaining declarations are as follows.
static const struct hwmon_ops lm75_hwmon_ops = {
.is_visible = lm75_is_visible,
.read = lm75_read,
.write = lm75_write,
};
static const struct hwmon_chip_info lm75_chip_info = {
.ops = &lm75_hwmon_ops,
.info = lm75_info,
};
指示各個屬性支援的位值的完整列表在 include/linux/hwmon.h 中定義。定義字首如下。
HWMON_C_xxxx |
晶片屬性,用於 hwmon_chip。 |
HWMON_T_xxxx |
溫度屬性,用於 hwmon_temp。 |
HWMON_I_xxxx |
電壓屬性,用於 hwmon_in。 |
HWMON_C_xxxx |
電流屬性,用於 hwmon_curr。請注意與晶片屬性的字首重疊。 |
HWMON_P_xxxx |
功率屬性,用於 hwmon_power。 |
HWMON_E_xxxx |
能量屬性,用於 hwmon_energy。 |
HWMON_H_xxxx |
溼度屬性,用於 hwmon_humidity。 |
HWMON_F_xxxx |
風扇速度屬性,用於 hwmon_fan。 |
HWMON_PWM_xxxx |
PWM 控制屬性,用於 hwmon_pwm。 |
驅動程式回撥函式¶
每個驅動程式都提供 is_visible、read 和 write 函式。這些函式的引數和返回值如下
umode_t is_visible_func(const void *data, enum hwmon_sensor_types type,
u32 attr, int channel)
- 引數
- data
指向裝置私有資料結構的指標。
- type
感測器型別。
- attr
與特定屬性關聯的屬性識別符號。例如,HWMON_T_INPUT 的屬性值將為 hwmon_temp_input。有關位欄位到屬性值的完整對映,請參見 include/linux/hwmon.h。
- channel
感測器通道號。
- 返回值
此屬性的檔案模式。通常,這將為 0(不會建立該屬性)、0444 或 0644。
int read_func(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
- 引數
- dev
指向硬體監控裝置的指標。
- type
感測器型別。
- attr
與特定屬性關聯的屬性識別符號。例如,HWMON_T_INPUT 的屬性值將為 hwmon_temp_input。有關完整對映,請參見 include/linux/hwmon.h。
- channel
感測器通道號。
- val
指向屬性值的指標。
- 返回值
成功時為 0,否則為負錯誤號。
int write_func(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
- 引數
- dev
指向硬體監控裝置的指標。
- type
感測器型別。
- attr
與特定屬性關聯的屬性識別符號。例如,HWMON_T_INPUT 的屬性值將為 hwmon_temp_input。有關完整對映,請參見 include/linux/hwmon.h。
- channel
感測器通道號。
- val
要寫入晶片的值。
- 返回值
成功時為 0,否則為負錯誤號。
驅動程式提供的 sysfs 屬性¶
在大多數情況下,驅動程式無需提供 sysfs 屬性,因為硬體監控核心會在內部建立這些屬性。只需要提供額外的非標準 sysfs 屬性。
標頭檔案 linux/hwmon-sysfs.h 提供了許多有用的宏來宣告和使用硬體監控 sysfs 屬性。
在許多情況下,您可以使用現有的 define DEVICE_ATTR 或其變體 DEVICE_ATTR_{RW,RO,WO} 來宣告此類屬性。如果屬性沒有其他上下文,這是可行的。但是,在許多情況下,會有其他資訊,例如感測器索引,需要傳遞給 sysfs 屬性處理函式。
SENSOR_DEVICE_ATTR 和 SENSOR_DEVICE_ATTR_2 可用於定義需要此類額外上下文資訊的屬性。 SENSOR_DEVICE_ATTR 需要一個額外的引數,SENSOR_DEVICE_ATTR_2 需要兩個。
SENSOR_DEVICE_ATTR 的簡化變體和 SENSOR_DEVICE_ATTR_2 可用,如果標準屬性許可權和函式名稱可行,則應使用。標準許可權對於 SENSOR_DEVICE_ATTR[_2]_RW 為 0644,對於 SENSOR_DEVICE_ATTR[_2]_RO 為 0444,對於 SENSOR_DEVICE_ATTR[_2]_WO 為 0200。標準函式類似於 DEVICE_ATTR_{RW,RO,WO},在提供的函式名稱後附加 _show 和 _store。
SENSOR_DEVICE_ATTR 及其變體定義了一個 struct sensor_device_attribute 變數。此結構具有以下欄位
struct sensor_device_attribute {
struct device_attribute dev_attr;
int index;
};
您可以使用 to_sensor_dev_attr 從屬性讀取或寫入函式中獲取指向此結構的指標。它的引數是附加了屬性的裝置。
SENSOR_DEVICE_ATTR_2 及其變體定義了一個 struct sensor_device_attribute_2 變數,其定義如下
struct sensor_device_attribute_2 {
struct device_attribute dev_attr;
u8 index;
u8 nr;
};
使用 to_sensor_dev_attr_2 獲取指向此結構的指標。它的引數是附加了屬性的裝置。