xref: /illumos-gate/usr/src/uts/common/sys/sensors.h (revision 8119dad84d6416f13557b0ba8e2aaf9064cbcfd3)
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