1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2019, Joyent, Inc. 14 * Copyright 2024 Oxide Computer Company 15 */ 16 17 #ifndef _SYS_SENSORS_H 18 #define _SYS_SENSORS_H 19 20 /* 21 * Consolidated sensor ioctls for various parts of the operating system. These 22 * interfaces should not be relied on at all. They are evolving and will change 23 * as we add more to the system for this. This may eventually become a larger 24 * framework, though it's more likely we'll consolidate that in userland. 25 */ 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 /* 32 * List of different possible kinds of sensors. 33 */ 34 #define SENSOR_KIND_UNKNOWN 0x00 35 #define SENSOR_KIND_TEMPERATURE 0x01 36 #define SENSOR_KIND_VOLTAGE 0x02 37 #define SENSOR_KIND_CURRENT 0x03 38 #define SENSOR_KIND_SYNTHETIC 0x04 39 40 /* 41 * Lists of units that sensors may have. The none type is intended for unitless 42 * sensors such as general control sensors. These sensors are generally derived 43 * from a secondary unit. A prime example is AMD's CPU control temperature, 44 * which is a unitless measure that is derived from temperature. 45 */ 46 #define SENSOR_UNIT_UNKNOWN 0x00 47 #define SENSOR_UNIT_CELSIUS 0x01 48 #define SENSOR_UNIT_FAHRENHEIT 0x02 49 #define SENSOR_UNIT_KELVIN 0x03 50 #define SENSOR_UNIT_VOLTS 0x04 51 #define SENSOR_UNIT_AMPS 0x05 52 #define SENSOR_UNIT_NONE 0x06 53 54 #define SENSOR_IOCTL (('s' << 24) | ('e' << 16) | ('n' << 8)) 55 56 /* 57 * Ask the sensor what kind of sensor it is. 58 */ 59 #define SENSOR_IOCTL_KIND (SENSOR_IOCTL | 0x01) 60 61 typedef struct sensor_ioctl_kind { 62 uint64_t sik_kind; 63 uint64_t sik_derive; 64 } sensor_ioctl_kind_t; 65 66 /* 67 * Ask the sensor for a scalar measurement. The sensor is responsible for 68 * returning the units it's in. A scalar measurement is broken down into a 69 * signed value and a notion of its granularity. The sit_gran member indicates 70 * the granularity: the number of increments per unit in the measurement (the 71 * sit_value member). sit_gran is signed and the sign indicates whether one 72 * needs to multiply or divide the granularity. The sit_prec member describes a 73 * +/- value (taking sit_gran into account) that describes the precision of the 74 * sensor. 75 * 76 * For example, consider a temperature sensor that set sit_gran to 10. This 77 * would mean that the value in sit_value was in 10ths of a degree and that to 78 * get the actual value in degrees, one would divide by 10. On the other hand, a 79 * negative value means that we effectively have to multiply to get there. For 80 * example, a value of -2 would indicate that each value in sit_value indicated 81 * two degrees and to get the temperature in degrees you would multiply 82 * sit_value * by two. 83 */ 84 #define SENSOR_IOCTL_SCALAR (SENSOR_IOCTL | 0x02) 85 86 typedef struct sensor_ioctl_scalar { 87 uint32_t sis_unit; 88 int32_t sis_gran; 89 uint32_t sis_prec; 90 uint32_t sis_pad; 91 int64_t sis_value; 92 } sensor_ioctl_scalar_t; 93 94 #ifdef _KERNEL 95 typedef int (*ksensor_kind_f)(void *, sensor_ioctl_kind_t *); 96 typedef int (*ksensor_scalar_f)(void *, sensor_ioctl_scalar_t *); 97 98 typedef struct { 99 ksensor_kind_f kso_kind; 100 ksensor_scalar_f kso_scalar; 101 } ksensor_ops_t; 102 103 extern int ksensor_kind_temperature(void *, sensor_ioctl_kind_t *); 104 extern int ksensor_kind_voltage(void *, sensor_ioctl_kind_t *); 105 extern int ksensor_kind_current(void *, sensor_ioctl_kind_t *); 106 107 /* 108 * Create a sensor where the class and name is supplied. 109 */ 110 extern int ksensor_create(dev_info_t *, const ksensor_ops_t *, void *, 111 const char *, const char *, id_t *); 112 113 /* 114 * Create a scalar sensor for a PCI device. If this is not a device-wide 115 * (e.g. per-function) sensor, this should not be used. 116 */ 117 extern int ksensor_create_scalar_pcidev(dev_info_t *, uint64_t, 118 const ksensor_ops_t *, void *, const char *, id_t *); 119 120 /* 121 * Remove a named or all sensors from this driver. 122 */ 123 #define KSENSOR_ALL_IDS INT_MIN 124 extern int ksensor_remove(dev_info_t *, id_t); 125 126 #endif 127 128 #ifdef __cplusplus 129 } 130 #endif 131 132 #endif /* _SYS_SENSORS_H */ 133