1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_UNITS_H 3 #define _LINUX_UNITS_H 4 5 #include <linux/bits.h> 6 #include <linux/math.h> 7 8 /* Metric prefixes in accordance with Système international (d'unités) */ 9 #define PETA 1000000000000000ULL 10 #define TERA 1000000000000ULL 11 #define GIGA 1000000000UL 12 #define MEGA 1000000UL 13 #define KILO 1000UL 14 #define HECTO 100UL 15 #define DECA 10UL 16 #define DECI 10UL 17 #define CENTI 100UL 18 #define MILLI 1000UL 19 #define MICRO 1000000UL 20 #define NANO 1000000000UL 21 #define PICO 1000000000000ULL 22 #define FEMTO 1000000000000000ULL 23 24 /* 25 * Percentage and related scaling units 26 * 27 * These macros define scaling factors used to convert between ratio and 28 * percentage-based representations with different decimal resolutions. 29 * They are used for precise fractional calculations in engineering, finance, 30 * and measurement applications. 31 * 32 * Examples: 33 * 1% = 0.01 = 1 / PERCENT 34 * 0.1% = 0.001 = 1 / PERMILLE 35 * 0.01% = 0.0001 = 1 / PERMYRIAD (1 basis point) 36 * 0.001% = 0.00001 = 1 / PERCENTMILLE 37 */ 38 #define PERCENT 100 39 #define PERMILLE 1000 40 #define PERMYRIAD 10000 41 #define PERCENTMILLE 100000 42 43 #define NANOHZ_PER_HZ 1000000000UL 44 #define MICROHZ_PER_HZ 1000000UL 45 #define MILLIHZ_PER_HZ 1000UL 46 47 /* Hz based multipliers */ 48 #define HZ_PER_KHZ 1000UL 49 #define HZ_PER_MHZ 1000000UL 50 #define HZ_PER_GHZ 1000000000UL 51 52 /* kHz based multipliers */ 53 #define KHZ_PER_MHZ 1000UL 54 #define KHZ_PER_GHZ 1000000UL 55 56 #define MILLIWATT_PER_WATT 1000UL 57 #define MICROWATT_PER_MILLIWATT 1000UL 58 #define MICROWATT_PER_WATT 1000000UL 59 60 #define BYTES_PER_KBIT (KILO / BITS_PER_BYTE) 61 #define BYTES_PER_MBIT (MEGA / BITS_PER_BYTE) 62 #define BYTES_PER_GBIT (GIGA / BITS_PER_BYTE) 63 64 #define ABSOLUTE_ZERO_MILLICELSIUS -273150 65 66 static inline long milli_kelvin_to_millicelsius(long t) 67 { 68 return t + ABSOLUTE_ZERO_MILLICELSIUS; 69 } 70 71 static inline long millicelsius_to_milli_kelvin(long t) 72 { 73 return t - ABSOLUTE_ZERO_MILLICELSIUS; 74 } 75 76 #define MILLIDEGREE_PER_DEGREE 1000 77 #define MILLIDEGREE_PER_DECIDEGREE 100 78 79 static inline long kelvin_to_millicelsius(long t) 80 { 81 return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DEGREE); 82 } 83 84 static inline long millicelsius_to_kelvin(long t) 85 { 86 t = millicelsius_to_milli_kelvin(t); 87 88 return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE); 89 } 90 91 static inline long deci_kelvin_to_celsius(long t) 92 { 93 t = milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE); 94 95 return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE); 96 } 97 98 static inline long celsius_to_deci_kelvin(long t) 99 { 100 t = millicelsius_to_milli_kelvin(t * MILLIDEGREE_PER_DEGREE); 101 102 return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE); 103 } 104 105 /** 106 * deci_kelvin_to_millicelsius_with_offset - convert Kelvin to Celsius 107 * @t: temperature value in decidegrees Kelvin 108 * @offset: difference between Kelvin and Celsius in millidegrees 109 * 110 * Return: temperature value in millidegrees Celsius 111 */ 112 static inline long deci_kelvin_to_millicelsius_with_offset(long t, long offset) 113 { 114 return t * MILLIDEGREE_PER_DECIDEGREE - offset; 115 } 116 117 static inline long deci_kelvin_to_millicelsius(long t) 118 { 119 return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE); 120 } 121 122 static inline long millicelsius_to_deci_kelvin(long t) 123 { 124 t = millicelsius_to_milli_kelvin(t); 125 126 return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE); 127 } 128 129 static inline long kelvin_to_celsius(long t) 130 { 131 return t + DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS, 132 MILLIDEGREE_PER_DEGREE); 133 } 134 135 static inline long celsius_to_kelvin(long t) 136 { 137 return t - DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS, 138 MILLIDEGREE_PER_DEGREE); 139 } 140 141 #endif /* _LINUX_UNITS_H */ 142