123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- The Linux Hardware Monitoring kernel API
- ========================================
- Guenter Roeck
- Introduction
- ------------
- This document describes the API that can be used by hardware monitoring
- drivers that want to use the hardware monitoring framework.
- This document does not describe what a hardware monitoring (hwmon) Driver or
- Device is. It also does not describe the API which can be used by user space
- to communicate with a hardware monitoring device. If you want to know this
- then please read the following file: Documentation/hwmon/sysfs-interface.rst.
- For additional guidelines on how to write and improve hwmon drivers, please
- also read Documentation/hwmon/submitting-patches.rst.
- The API
- -------
- Each hardware monitoring driver must #include <linux/hwmon.h> and, in most
- cases, <linux/hwmon-sysfs.h>. linux/hwmon.h declares the following
- register/unregister functions::
- struct device *
- hwmon_device_register_with_groups(struct device *dev, const char *name,
- void *drvdata,
- const struct attribute_group **groups);
- struct device *
- devm_hwmon_device_register_with_groups(struct device *dev,
- const char *name, void *drvdata,
- const struct attribute_group **groups);
- 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);
- void devm_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_groups registers a hardware monitoring device.
- The first parameter of this function is a pointer to the parent device.
- The name parameter is a pointer to the hwmon device name. The registration
- function wil create a name sysfs attribute pointing to this name.
- The drvdata parameter is the pointer to the local driver data.
- hwmon_device_register_with_groups will attach this pointer to the newly
- allocated hwmon device. The pointer can be retrieved by the driver using
- dev_get_drvdata() on the hwmon device pointer. The groups parameter is
- a pointer to a list of sysfs attribute groups. The list must be NULL terminated.
- hwmon_device_register_with_groups creates the hwmon device with name attribute
- as well as all sysfs attributes attached to the hwmon device.
- This function returns a pointer to the newly created hardware monitoring device
- or PTR_ERR for failure.
- devm_hwmon_device_register_with_groups is similar to
- hwmon_device_register_with_groups. However, it is device managed, meaning the
- hwmon device does not have to be removed explicitly by the removal function.
- hwmon_device_register_with_info is the most comprehensive and preferred means
- to register a hardware monitoring device. It creates the standard sysfs
- attributes in the hardware monitoring core, letting the driver focus on reading
- from and writing to the chip instead of having to bother with sysfs attributes.
- The parent device parameter as well as the chip parameter must not be NULL. Its
- parameters are described in more detail below.
- devm_hwmon_device_register_with_info is similar to
- hwmon_device_register_with_info. However, it is device managed, meaning the
- hwmon device does not have to be removed explicitly by the removal function.
- hwmon_device_unregister deregisters a registered hardware monitoring device.
- The parameter of this function is the pointer to the registered hardware
- monitoring device structure. This function must be called from the driver
- remove function if the hardware monitoring device was registered with
- hwmon_device_register_with_groups or hwmon_device_register_with_info.
- devm_hwmon_device_unregister does not normally have to be called. It is only
- needed for error handling, and only needed if the driver probe fails after
- the call to devm_hwmon_device_register_with_groups or
- hwmon_device_register_with_info and if the automatic (device managed)
- removal would be too late.
- All supported hwmon device registration functions only accept valid device
- names. Device names including invalid characters (whitespace, '*', or '-')
- will be rejected. The 'name' parameter is mandatory.
- If the driver doesn't use a static device name (for example it uses
- dev_name()), and therefore cannot make sure the name only contains valid
- characters, hwmon_sanitize_name can be used. This convenience function
- will duplicate the string and replace any invalid characters with an
- underscore. It will allocate memory for the new string and it is the
- responsibility of the caller to release the memory when the device is
- removed.
- devm_hwmon_sanitize_name is the resource managed version of
- hwmon_sanitize_name; the memory will be freed automatically on device
- removal.
- Using devm_hwmon_device_register_with_info()
- --------------------------------------------
- hwmon_device_register_with_info() registers a hardware monitoring device.
- The parameters to this function are
- =============================================== ===============================================
- `struct device *dev` Pointer to parent device
- `const char *name` Device name
- `void *drvdata` Driver private data
- `const struct hwmon_chip_info *info` Pointer to chip description.
- `const struct attribute_group **extra_groups` Null-terminated list of additional non-standard
- sysfs attribute groups.
- =============================================== ===============================================
- This function returns a pointer to the created hardware monitoring device
- on success and a negative error code for failure.
- The hwmon_chip_info structure looks as follows::
- struct hwmon_chip_info {
- const struct hwmon_ops *ops;
- const struct hwmon_channel_info **info;
- };
- It contains the following fields:
- * ops:
- Pointer to device operations.
- * info:
- NULL-terminated list of device channel descriptors.
- The list of hwmon operations is defined as::
- 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);
- };
- It defines the following operations.
- * is_visible:
- Pointer to a function to return the file mode for each supported
- attribute. This function is mandatory.
- * read:
- Pointer to a function for reading a value from the chip. This function
- is optional, but must be provided if any readable attributes exist.
- * write:
- Pointer to a function for writing a value to the chip. This function is
- optional, but must be provided if any writeable attributes exist.
- Each sensor channel is described with struct hwmon_channel_info, which is
- defined as follows::
- struct hwmon_channel_info {
- enum hwmon_sensor_types type;
- u32 *config;
- };
- It contains following fields:
- * type:
- The hardware monitoring sensor type.
- Supported sensor types are
- ================== ==================================================
- hwmon_chip A virtual sensor type, used to describe attributes
- which are not bound to a specific input or output
- hwmon_temp Temperature sensor
- hwmon_in Voltage sensor
- hwmon_curr Current sensor
- hwmon_power Power sensor
- hwmon_energy Energy sensor
- hwmon_humidity Humidity sensor
- hwmon_fan Fan speed sensor
- hwmon_pwm PWM control
- ================== ==================================================
- * config:
- Pointer to a 0-terminated list of configuration values for each
- sensor of the given type. Each value is a combination of bit values
- describing the attributes supposed by a single sensor.
- As an example, here is the complete description file for a LM75 compatible
- sensor chip. The chip has a single temperature sensor. The driver wants to
- register with the thermal subsystem (HWMON_C_REGISTER_TZ), and it supports
- the update_interval attribute (HWMON_C_UPDATE_INTERVAL). The chip supports
- reading the temperature (HWMON_T_INPUT), it has a maximum temperature
- register (HWMON_T_MAX) as well as a maximum temperature hysteresis register
- (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 *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 *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,
- };
- A complete list of bit values indicating individual attribute support
- is defined in include/linux/hwmon.h. Definition prefixes are as follows.
- =============== =================================================
- HWMON_C_xxxx Chip attributes, for use with hwmon_chip.
- HWMON_T_xxxx Temperature attributes, for use with hwmon_temp.
- HWMON_I_xxxx Voltage attributes, for use with hwmon_in.
- HWMON_C_xxxx Current attributes, for use with hwmon_curr.
- Notice the prefix overlap with chip attributes.
- HWMON_P_xxxx Power attributes, for use with hwmon_power.
- HWMON_E_xxxx Energy attributes, for use with hwmon_energy.
- HWMON_H_xxxx Humidity attributes, for use with hwmon_humidity.
- HWMON_F_xxxx Fan speed attributes, for use with hwmon_fan.
- HWMON_PWM_xxxx PWM control attributes, for use with hwmon_pwm.
- =============== =================================================
- Driver callback functions
- -------------------------
- Each driver provides is_visible, read, and write functions. Parameters
- and return values for those functions are as follows::
- umode_t is_visible_func(const void *data, enum hwmon_sensor_types type,
- u32 attr, int channel)
- Parameters:
- data:
- Pointer to device private data structure.
- type:
- The sensor type.
- attr:
- Attribute identifier associated with a specific attribute.
- For example, the attribute value for HWMON_T_INPUT would be
- hwmon_temp_input. For complete mappings of bit fields to
- attribute values please see include/linux/hwmon.h.
- channel:
- The sensor channel number.
- Return value:
- The file mode for this attribute. Typically, this will be 0 (the
- attribute will not be created), S_IRUGO, or 'S_IRUGO | S_IWUSR'.
- ::
- int read_func(struct device *dev, enum hwmon_sensor_types type,
- u32 attr, int channel, long *val)
- Parameters:
- dev:
- Pointer to the hardware monitoring device.
- type:
- The sensor type.
- attr:
- Attribute identifier associated with a specific attribute.
- For example, the attribute value for HWMON_T_INPUT would be
- hwmon_temp_input. For complete mappings please see
- include/linux/hwmon.h.
- channel:
- The sensor channel number.
- val:
- Pointer to attribute value.
- Return value:
- 0 on success, a negative error number otherwise.
- ::
- int write_func(struct device *dev, enum hwmon_sensor_types type,
- u32 attr, int channel, long val)
- Parameters:
- dev:
- Pointer to the hardware monitoring device.
- type:
- The sensor type.
- attr:
- Attribute identifier associated with a specific attribute.
- For example, the attribute value for HWMON_T_INPUT would be
- hwmon_temp_input. For complete mappings please see
- include/linux/hwmon.h.
- channel:
- The sensor channel number.
- val:
- The value to write to the chip.
- Return value:
- 0 on success, a negative error number otherwise.
- Driver-provided sysfs attributes
- --------------------------------
- If the hardware monitoring device is registered with
- hwmon_device_register_with_info or devm_hwmon_device_register_with_info,
- it is most likely not necessary to provide sysfs attributes. Only additional
- non-standard sysfs attributes need to be provided when one of those registration
- functions is used.
- The header file linux/hwmon-sysfs.h provides a number of useful macros to
- declare and use hardware monitoring sysfs attributes.
- In many cases, you can use the exsting define DEVICE_ATTR or its variants
- DEVICE_ATTR_{RW,RO,WO} to declare such attributes. This is feasible if an
- attribute has no additional context. However, in many cases there will be
- additional information such as a sensor index which will need to be passed
- to the sysfs attribute handling function.
- SENSOR_DEVICE_ATTR and SENSOR_DEVICE_ATTR_2 can be used to define attributes
- which need such additional context information. SENSOR_DEVICE_ATTR requires
- one additional argument, SENSOR_DEVICE_ATTR_2 requires two.
- Simplified variants of SENSOR_DEVICE_ATTR and SENSOR_DEVICE_ATTR_2 are available
- and should be used if standard attribute permissions and function names are
- feasible. Standard permissions are 0644 for SENSOR_DEVICE_ATTR[_2]_RW,
- 0444 for SENSOR_DEVICE_ATTR[_2]_RO, and 0200 for SENSOR_DEVICE_ATTR[_2]_WO.
- Standard functions, similar to DEVICE_ATTR_{RW,RO,WO}, have _show and _store
- appended to the provided function name.
- SENSOR_DEVICE_ATTR and its variants define a struct sensor_device_attribute
- variable. This structure has the following fields::
- struct sensor_device_attribute {
- struct device_attribute dev_attr;
- int index;
- };
- You can use to_sensor_dev_attr to get the pointer to this structure from the
- attribute read or write function. Its parameter is the device to which the
- attribute is attached.
- SENSOR_DEVICE_ATTR_2 and its variants define a struct sensor_device_attribute_2
- variable, which is defined as follows::
- struct sensor_device_attribute_2 {
- struct device_attribute dev_attr;
- u8 index;
- u8 nr;
- };
- Use to_sensor_dev_attr_2 to get the pointer to this structure. Its parameter
- is the device to which the attribute is attached.
|