Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 1 | The Linux Hardware Monitoring kernel API |
| 2 | ======================================== |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 3 | |
| 4 | Guenter Roeck |
| 5 | |
| 6 | Introduction |
| 7 | ------------ |
| 8 | |
| 9 | This document describes the API that can be used by hardware monitoring |
| 10 | drivers that want to use the hardware monitoring framework. |
| 11 | |
| 12 | This document does not describe what a hardware monitoring (hwmon) Driver or |
| 13 | Device is. It also does not describe the API which can be used by user space |
| 14 | to communicate with a hardware monitoring device. If you want to know this |
Mauro Carvalho Chehab | 7ebd8b66 | 2019-04-17 06:46:29 -0300 | [diff] [blame] | 15 | then please read the following file: Documentation/hwmon/sysfs-interface.rst. |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 16 | |
| 17 | For additional guidelines on how to write and improve hwmon drivers, please |
Mauro Carvalho Chehab | 7ebd8b66 | 2019-04-17 06:46:29 -0300 | [diff] [blame] | 18 | also read Documentation/hwmon/submitting-patches.rst. |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 19 | |
| 20 | The API |
| 21 | ------- |
| 22 | Each hardware monitoring driver must #include <linux/hwmon.h> and, in most |
| 23 | cases, <linux/hwmon-sysfs.h>. linux/hwmon.h declares the following |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 24 | register/unregister functions:: |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 25 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 26 | struct device * |
| 27 | hwmon_device_register_with_groups(struct device *dev, const char *name, |
| 28 | void *drvdata, |
| 29 | const struct attribute_group **groups); |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 30 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 31 | struct device * |
| 32 | devm_hwmon_device_register_with_groups(struct device *dev, |
| 33 | const char *name, void *drvdata, |
| 34 | const struct attribute_group **groups); |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 35 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 36 | struct device * |
| 37 | hwmon_device_register_with_info(struct device *dev, |
| 38 | const char *name, void *drvdata, |
| 39 | const struct hwmon_chip_info *info, |
| 40 | const struct attribute_group **extra_groups); |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 41 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 42 | struct device * |
| 43 | devm_hwmon_device_register_with_info(struct device *dev, |
| 44 | const char *name, |
| 45 | void *drvdata, |
| 46 | const struct hwmon_chip_info *info, |
| 47 | const struct attribute_group **extra_groups); |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 48 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 49 | void hwmon_device_unregister(struct device *dev); |
| 50 | |
| 51 | void devm_hwmon_device_unregister(struct device *dev); |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 52 | |
Guenter Roeck | af1bd36 | 2016-10-16 11:31:08 -0700 | [diff] [blame] | 53 | hwmon_device_register_with_groups registers a hardware monitoring device. |
| 54 | The first parameter of this function is a pointer to the parent device. |
| 55 | The name parameter is a pointer to the hwmon device name. The registration |
| 56 | function wil create a name sysfs attribute pointing to this name. |
| 57 | The drvdata parameter is the pointer to the local driver data. |
| 58 | hwmon_device_register_with_groups will attach this pointer to the newly |
| 59 | allocated hwmon device. The pointer can be retrieved by the driver using |
| 60 | dev_get_drvdata() on the hwmon device pointer. The groups parameter is |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 61 | a pointer to a list of sysfs attribute groups. The list must be NULL terminated. |
| 62 | hwmon_device_register_with_groups creates the hwmon device with name attribute |
| 63 | as well as all sysfs attributes attached to the hwmon device. |
Guenter Roeck | af1bd36 | 2016-10-16 11:31:08 -0700 | [diff] [blame] | 64 | This function returns a pointer to the newly created hardware monitoring device |
| 65 | or PTR_ERR for failure. |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 66 | |
| 67 | devm_hwmon_device_register_with_groups is similar to |
| 68 | hwmon_device_register_with_groups. However, it is device managed, meaning the |
| 69 | hwmon device does not have to be removed explicitly by the removal function. |
| 70 | |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 71 | hwmon_device_register_with_info is the most comprehensive and preferred means |
| 72 | to register a hardware monitoring device. It creates the standard sysfs |
| 73 | attributes in the hardware monitoring core, letting the driver focus on reading |
| 74 | from and writing to the chip instead of having to bother with sysfs attributes. |
Lucas Magasweran | 59df4f4 | 2018-05-08 04:43:33 -0700 | [diff] [blame] | 75 | The parent device parameter cannot be NULL with non-NULL chip info. Its |
| 76 | parameters are described in more detail below. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 77 | |
| 78 | devm_hwmon_device_register_with_info is similar to |
| 79 | hwmon_device_register_with_info. However, it is device managed, meaning the |
| 80 | hwmon device does not have to be removed explicitly by the removal function. |
| 81 | |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 82 | hwmon_device_unregister deregisters a registered hardware monitoring device. |
| 83 | The parameter of this function is the pointer to the registered hardware |
| 84 | monitoring device structure. This function must be called from the driver |
| 85 | remove function if the hardware monitoring device was registered with |
Guenter Roeck | af1bd36 | 2016-10-16 11:31:08 -0700 | [diff] [blame] | 86 | hwmon_device_register_with_groups or hwmon_device_register_with_info. |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 87 | |
| 88 | devm_hwmon_device_unregister does not normally have to be called. It is only |
| 89 | needed for error handling, and only needed if the driver probe fails after |
Guenter Roeck | af1bd36 | 2016-10-16 11:31:08 -0700 | [diff] [blame] | 90 | the call to devm_hwmon_device_register_with_groups or |
| 91 | hwmon_device_register_with_info and if the automatic (device managed) |
| 92 | removal would be too late. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 93 | |
Guenter Roeck | f172841 | 2017-01-24 20:24:36 -0800 | [diff] [blame] | 94 | All supported hwmon device registration functions only accept valid device |
| 95 | names. Device names including invalid characters (whitespace, '*', or '-') |
| 96 | will be rejected. The 'name' parameter is mandatory. |
| 97 | |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 98 | Using devm_hwmon_device_register_with_info() |
| 99 | -------------------------------------------- |
| 100 | |
| 101 | hwmon_device_register_with_info() registers a hardware monitoring device. |
| 102 | The parameters to this function are |
| 103 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 104 | =============================================== =============================================== |
| 105 | `struct device *dev` Pointer to parent device |
| 106 | `const char *name` Device name |
| 107 | `void *drvdata` Driver private data |
| 108 | `const struct hwmon_chip_info *info` Pointer to chip description. |
| 109 | `const struct attribute_group **extra_groups` Null-terminated list of additional non-standard |
| 110 | sysfs attribute groups. |
| 111 | =============================================== =============================================== |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 112 | |
| 113 | This function returns a pointer to the created hardware monitoring device |
| 114 | on success and a negative error code for failure. |
| 115 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 116 | The hwmon_chip_info structure looks as follows:: |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 117 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 118 | struct hwmon_chip_info { |
| 119 | const struct hwmon_ops *ops; |
| 120 | const struct hwmon_channel_info **info; |
| 121 | }; |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 122 | |
| 123 | It contains the following fields: |
| 124 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 125 | * ops: |
| 126 | Pointer to device operations. |
| 127 | * info: |
| 128 | NULL-terminated list of device channel descriptors. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 129 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 130 | The list of hwmon operations is defined as:: |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 131 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 132 | struct hwmon_ops { |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 133 | umode_t (*is_visible)(const void *, enum hwmon_sensor_types type, |
| 134 | u32 attr, int); |
| 135 | int (*read)(struct device *, enum hwmon_sensor_types type, |
| 136 | u32 attr, int, long *); |
| 137 | int (*write)(struct device *, enum hwmon_sensor_types type, |
| 138 | u32 attr, int, long); |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 139 | }; |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 140 | |
| 141 | It defines the following operations. |
| 142 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 143 | * is_visible: |
| 144 | Pointer to a function to return the file mode for each supported |
| 145 | attribute. This function is mandatory. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 146 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 147 | * read: |
| 148 | Pointer to a function for reading a value from the chip. This function |
| 149 | is optional, but must be provided if any readable attributes exist. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 150 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 151 | * write: |
| 152 | Pointer to a function for writing a value to the chip. This function is |
| 153 | optional, but must be provided if any writeable attributes exist. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 154 | |
| 155 | Each sensor channel is described with struct hwmon_channel_info, which is |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 156 | defined as follows:: |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 157 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 158 | struct hwmon_channel_info { |
| 159 | enum hwmon_sensor_types type; |
| 160 | u32 *config; |
| 161 | }; |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 162 | |
| 163 | It contains following fields: |
| 164 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 165 | * type: |
| 166 | The hardware monitoring sensor type. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 167 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 168 | Supported sensor types are |
| 169 | |
| 170 | ================== ================================================== |
| 171 | hwmon_chip A virtual sensor type, used to describe attributes |
| 172 | which are not bound to a specific input or output |
| 173 | hwmon_temp Temperature sensor |
| 174 | hwmon_in Voltage sensor |
| 175 | hwmon_curr Current sensor |
| 176 | hwmon_power Power sensor |
| 177 | hwmon_energy Energy sensor |
| 178 | hwmon_humidity Humidity sensor |
| 179 | hwmon_fan Fan speed sensor |
| 180 | hwmon_pwm PWM control |
| 181 | ================== ================================================== |
| 182 | |
| 183 | * config: |
| 184 | Pointer to a 0-terminated list of configuration values for each |
| 185 | sensor of the given type. Each value is a combination of bit values |
| 186 | describing the attributes supposed by a single sensor. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 187 | |
| 188 | As an example, here is the complete description file for a LM75 compatible |
| 189 | sensor chip. The chip has a single temperature sensor. The driver wants to |
| 190 | register with the thermal subsystem (HWMON_C_REGISTER_TZ), and it supports |
| 191 | the update_interval attribute (HWMON_C_UPDATE_INTERVAL). The chip supports |
| 192 | reading the temperature (HWMON_T_INPUT), it has a maximum temperature |
| 193 | register (HWMON_T_MAX) as well as a maximum temperature hysteresis register |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 194 | (HWMON_T_MAX_HYST):: |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 195 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 196 | static const u32 lm75_chip_config[] = { |
| 197 | HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL, |
| 198 | 0 |
| 199 | }; |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 200 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 201 | static const struct hwmon_channel_info lm75_chip = { |
| 202 | .type = hwmon_chip, |
| 203 | .config = lm75_chip_config, |
| 204 | }; |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 205 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 206 | static const u32 lm75_temp_config[] = { |
| 207 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST, |
| 208 | 0 |
| 209 | }; |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 210 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 211 | static const struct hwmon_channel_info lm75_temp = { |
| 212 | .type = hwmon_temp, |
| 213 | .config = lm75_temp_config, |
| 214 | }; |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 215 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 216 | static const struct hwmon_channel_info *lm75_info[] = { |
| 217 | &lm75_chip, |
| 218 | &lm75_temp, |
| 219 | NULL |
| 220 | }; |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 221 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 222 | The HWMON_CHANNEL_INFO() macro can and should be used when possible. |
| 223 | With this macro, the above example can be simplified to |
Guenter Roeck | 6bf2db4 | 2019-03-31 10:22:24 -0700 | [diff] [blame] | 224 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 225 | static const struct hwmon_channel_info *lm75_info[] = { |
| 226 | HWMON_CHANNEL_INFO(chip, |
| 227 | HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL), |
| 228 | HWMON_CHANNEL_INFO(temp, |
| 229 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST), |
| 230 | NULL |
| 231 | }; |
Guenter Roeck | 6bf2db4 | 2019-03-31 10:22:24 -0700 | [diff] [blame] | 232 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 233 | The remaining declarations are as follows. |
Guenter Roeck | 6bf2db4 | 2019-03-31 10:22:24 -0700 | [diff] [blame] | 234 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 235 | static const struct hwmon_ops lm75_hwmon_ops = { |
| 236 | .is_visible = lm75_is_visible, |
| 237 | .read = lm75_read, |
| 238 | .write = lm75_write, |
| 239 | }; |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 240 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 241 | static const struct hwmon_chip_info lm75_chip_info = { |
| 242 | .ops = &lm75_hwmon_ops, |
| 243 | .info = lm75_info, |
| 244 | }; |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 245 | |
| 246 | A complete list of bit values indicating individual attribute support |
| 247 | is defined in include/linux/hwmon.h. Definition prefixes are as follows. |
| 248 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 249 | =============== ================================================= |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 250 | HWMON_C_xxxx Chip attributes, for use with hwmon_chip. |
| 251 | HWMON_T_xxxx Temperature attributes, for use with hwmon_temp. |
| 252 | HWMON_I_xxxx Voltage attributes, for use with hwmon_in. |
| 253 | HWMON_C_xxxx Current attributes, for use with hwmon_curr. |
| 254 | Notice the prefix overlap with chip attributes. |
| 255 | HWMON_P_xxxx Power attributes, for use with hwmon_power. |
| 256 | HWMON_E_xxxx Energy attributes, for use with hwmon_energy. |
| 257 | HWMON_H_xxxx Humidity attributes, for use with hwmon_humidity. |
| 258 | HWMON_F_xxxx Fan speed attributes, for use with hwmon_fan. |
Guenter Roeck | f9f7bb3 | 2016-06-26 12:20:46 -0700 | [diff] [blame] | 259 | HWMON_PWM_xxxx PWM control attributes, for use with hwmon_pwm. |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 260 | =============== ================================================= |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 261 | |
| 262 | Driver callback functions |
| 263 | ------------------------- |
| 264 | |
| 265 | Each driver provides is_visible, read, and write functions. Parameters |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 266 | and return values for those functions are as follows:: |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 267 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 268 | umode_t is_visible_func(const void *data, enum hwmon_sensor_types type, |
| 269 | u32 attr, int channel) |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 270 | |
| 271 | Parameters: |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 272 | data: |
| 273 | Pointer to device private data structure. |
| 274 | type: |
| 275 | The sensor type. |
| 276 | attr: |
| 277 | Attribute identifier associated with a specific attribute. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 278 | For example, the attribute value for HWMON_T_INPUT would be |
| 279 | hwmon_temp_input. For complete mappings of bit fields to |
| 280 | attribute values please see include/linux/hwmon.h. |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 281 | channel: |
| 282 | The sensor channel number. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 283 | |
| 284 | Return value: |
| 285 | The file mode for this attribute. Typically, this will be 0 (the |
| 286 | attribute will not be created), S_IRUGO, or 'S_IRUGO | S_IWUSR'. |
| 287 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 288 | :: |
| 289 | |
| 290 | int read_func(struct device *dev, enum hwmon_sensor_types type, |
| 291 | u32 attr, int channel, long *val) |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 292 | |
| 293 | Parameters: |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 294 | dev: |
| 295 | Pointer to the hardware monitoring device. |
| 296 | type: |
| 297 | The sensor type. |
| 298 | attr: |
| 299 | Attribute identifier associated with a specific attribute. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 300 | For example, the attribute value for HWMON_T_INPUT would be |
| 301 | hwmon_temp_input. For complete mappings please see |
| 302 | include/linux/hwmon.h. |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 303 | channel: |
| 304 | The sensor channel number. |
| 305 | val: |
| 306 | Pointer to attribute value. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 307 | |
| 308 | Return value: |
| 309 | 0 on success, a negative error number otherwise. |
| 310 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 311 | :: |
| 312 | |
| 313 | int write_func(struct device *dev, enum hwmon_sensor_types type, |
| 314 | u32 attr, int channel, long val) |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 315 | |
| 316 | Parameters: |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 317 | dev: |
| 318 | Pointer to the hardware monitoring device. |
| 319 | type: |
| 320 | The sensor type. |
| 321 | attr: |
| 322 | Attribute identifier associated with a specific attribute. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 323 | For example, the attribute value for HWMON_T_INPUT would be |
| 324 | hwmon_temp_input. For complete mappings please see |
| 325 | include/linux/hwmon.h. |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 326 | channel: |
| 327 | The sensor channel number. |
| 328 | val: |
| 329 | The value to write to the chip. |
Guenter Roeck | bf7153f | 2016-06-23 18:57:03 -0700 | [diff] [blame] | 330 | |
| 331 | Return value: |
| 332 | 0 on success, a negative error number otherwise. |
| 333 | |
| 334 | |
| 335 | Driver-provided sysfs attributes |
| 336 | -------------------------------- |
| 337 | |
| 338 | If the hardware monitoring device is registered with |
| 339 | hwmon_device_register_with_info or devm_hwmon_device_register_with_info, |
Guenter Roeck | 848ba0a | 2016-10-16 17:20:43 -0700 | [diff] [blame] | 340 | it is most likely not necessary to provide sysfs attributes. Only additional |
| 341 | non-standard sysfs attributes need to be provided when one of those registration |
| 342 | functions is used. |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 343 | |
| 344 | The header file linux/hwmon-sysfs.h provides a number of useful macros to |
| 345 | declare and use hardware monitoring sysfs attributes. |
| 346 | |
Guenter Roeck | a5c47c0 | 2016-12-27 15:28:19 -0800 | [diff] [blame] | 347 | In many cases, you can use the exsting define DEVICE_ATTR or its variants |
| 348 | DEVICE_ATTR_{RW,RO,WO} to declare such attributes. This is feasible if an |
| 349 | attribute has no additional context. However, in many cases there will be |
| 350 | additional information such as a sensor index which will need to be passed |
| 351 | to the sysfs attribute handling function. |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 352 | |
| 353 | SENSOR_DEVICE_ATTR and SENSOR_DEVICE_ATTR_2 can be used to define attributes |
| 354 | which need such additional context information. SENSOR_DEVICE_ATTR requires |
| 355 | one additional argument, SENSOR_DEVICE_ATTR_2 requires two. |
| 356 | |
Guenter Roeck | a5c47c0 | 2016-12-27 15:28:19 -0800 | [diff] [blame] | 357 | Simplified variants of SENSOR_DEVICE_ATTR and SENSOR_DEVICE_ATTR_2 are available |
| 358 | and should be used if standard attribute permissions and function names are |
| 359 | feasible. Standard permissions are 0644 for SENSOR_DEVICE_ATTR[_2]_RW, |
| 360 | 0444 for SENSOR_DEVICE_ATTR[_2]_RO, and 0200 for SENSOR_DEVICE_ATTR[_2]_WO. |
| 361 | Standard functions, similar to DEVICE_ATTR_{RW,RO,WO}, have _show and _store |
| 362 | appended to the provided function name. |
| 363 | |
| 364 | SENSOR_DEVICE_ATTR and its variants define a struct sensor_device_attribute |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 365 | variable. This structure has the following fields:: |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 366 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 367 | struct sensor_device_attribute { |
| 368 | struct device_attribute dev_attr; |
| 369 | int index; |
| 370 | }; |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 371 | |
| 372 | You can use to_sensor_dev_attr to get the pointer to this structure from the |
| 373 | attribute read or write function. Its parameter is the device to which the |
| 374 | attribute is attached. |
| 375 | |
Guenter Roeck | a5c47c0 | 2016-12-27 15:28:19 -0800 | [diff] [blame] | 376 | SENSOR_DEVICE_ATTR_2 and its variants define a struct sensor_device_attribute_2 |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 377 | variable, which is defined as follows:: |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 378 | |
Mauro Carvalho Chehab | b04f2f7 | 2019-04-17 06:46:28 -0300 | [diff] [blame] | 379 | struct sensor_device_attribute_2 { |
| 380 | struct device_attribute dev_attr; |
| 381 | u8 index; |
| 382 | u8 nr; |
| 383 | }; |
Guenter Roeck | a962266 | 2014-05-10 09:56:15 -0700 | [diff] [blame] | 384 | |
| 385 | Use to_sensor_dev_attr_2 to get the pointer to this structure. Its parameter |
| 386 | is the device to which the attribute is attached. |