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