Commit | Line | Data |
---|---|---|
87976ce2 SS |
1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* | |
3 | * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC | |
4 | * | |
5 | * Baikal-T1 Process, Voltage, Temperature sensor driver | |
6 | */ | |
7 | #ifndef __HWMON_BT1_PVT_H__ | |
8 | #define __HWMON_BT1_PVT_H__ | |
9 | ||
10 | #include <linux/completion.h> | |
11 | #include <linux/hwmon.h> | |
12 | #include <linux/kernel.h> | |
0015503e | 13 | #include <linux/ktime.h> |
87976ce2 SS |
14 | #include <linux/mutex.h> |
15 | #include <linux/seqlock.h> | |
16 | ||
17 | /* Baikal-T1 PVT registers and their bitfields */ | |
18 | #define PVT_CTRL 0x00 | |
19 | #define PVT_CTRL_EN BIT(0) | |
20 | #define PVT_CTRL_MODE_FLD 1 | |
21 | #define PVT_CTRL_MODE_MASK GENMASK(3, PVT_CTRL_MODE_FLD) | |
22 | #define PVT_CTRL_MODE_TEMP 0x0 | |
23 | #define PVT_CTRL_MODE_VOLT 0x1 | |
24 | #define PVT_CTRL_MODE_LVT 0x2 | |
25 | #define PVT_CTRL_MODE_HVT 0x4 | |
26 | #define PVT_CTRL_MODE_SVT 0x6 | |
27 | #define PVT_CTRL_TRIM_FLD 4 | |
28 | #define PVT_CTRL_TRIM_MASK GENMASK(8, PVT_CTRL_TRIM_FLD) | |
29 | #define PVT_DATA 0x04 | |
30 | #define PVT_DATA_VALID BIT(10) | |
31 | #define PVT_DATA_DATA_FLD 0 | |
32 | #define PVT_DATA_DATA_MASK GENMASK(9, PVT_DATA_DATA_FLD) | |
33 | #define PVT_TTHRES 0x08 | |
34 | #define PVT_VTHRES 0x0C | |
35 | #define PVT_LTHRES 0x10 | |
36 | #define PVT_HTHRES 0x14 | |
37 | #define PVT_STHRES 0x18 | |
38 | #define PVT_THRES_LO_FLD 0 | |
39 | #define PVT_THRES_LO_MASK GENMASK(9, PVT_THRES_LO_FLD) | |
40 | #define PVT_THRES_HI_FLD 10 | |
41 | #define PVT_THRES_HI_MASK GENMASK(19, PVT_THRES_HI_FLD) | |
42 | #define PVT_TTIMEOUT 0x1C | |
43 | #define PVT_INTR_STAT 0x20 | |
44 | #define PVT_INTR_MASK 0x24 | |
45 | #define PVT_RAW_INTR_STAT 0x28 | |
46 | #define PVT_INTR_DVALID BIT(0) | |
47 | #define PVT_INTR_TTHRES_LO BIT(1) | |
48 | #define PVT_INTR_TTHRES_HI BIT(2) | |
49 | #define PVT_INTR_VTHRES_LO BIT(3) | |
50 | #define PVT_INTR_VTHRES_HI BIT(4) | |
51 | #define PVT_INTR_LTHRES_LO BIT(5) | |
52 | #define PVT_INTR_LTHRES_HI BIT(6) | |
53 | #define PVT_INTR_HTHRES_LO BIT(7) | |
54 | #define PVT_INTR_HTHRES_HI BIT(8) | |
55 | #define PVT_INTR_STHRES_LO BIT(9) | |
56 | #define PVT_INTR_STHRES_HI BIT(10) | |
57 | #define PVT_INTR_ALL GENMASK(10, 0) | |
58 | #define PVT_CLR_INTR 0x2C | |
59 | ||
60 | /* | |
61 | * PVT sensors-related limits and default values | |
62 | * @PVT_TEMP_MIN: Minimal temperature in millidegrees of Celsius. | |
63 | * @PVT_TEMP_MAX: Maximal temperature in millidegrees of Celsius. | |
64 | * @PVT_TEMP_CHS: Number of temperature hwmon channels. | |
65 | * @PVT_VOLT_MIN: Minimal voltage in mV. | |
66 | * @PVT_VOLT_MAX: Maximal voltage in mV. | |
67 | * @PVT_VOLT_CHS: Number of voltage hwmon channels. | |
68 | * @PVT_DATA_MIN: Minimal PVT raw data value. | |
69 | * @PVT_DATA_MAX: Maximal PVT raw data value. | |
70 | * @PVT_TRIM_MIN: Minimal temperature sensor trim value. | |
71 | * @PVT_TRIM_MAX: Maximal temperature sensor trim value. | |
72 | * @PVT_TRIM_DEF: Default temperature sensor trim value (set a proper value | |
73 | * when one is determined for Baikal-T1 SoC). | |
74 | * @PVT_TRIM_TEMP: Maximum temperature encoded by the trim factor. | |
75 | * @PVT_TRIM_STEP: Temperature stride corresponding to the trim value. | |
76 | * @PVT_TOUT_MIN: Minimal timeout between samples in nanoseconds. | |
77 | * @PVT_TOUT_DEF: Default data measurements timeout. In case if alarms are | |
78 | * activated the PVT IRQ is enabled to be raised after each | |
79 | * conversion in order to have the thresholds checked and the | |
80 | * converted value cached. Too frequent conversions may cause | |
81 | * the system CPU overload. Lets set the 50ms delay between | |
82 | * them by default to prevent this. | |
83 | */ | |
84 | #define PVT_TEMP_MIN -48380L | |
85 | #define PVT_TEMP_MAX 147438L | |
86 | #define PVT_TEMP_CHS 1 | |
87 | #define PVT_VOLT_MIN 620L | |
88 | #define PVT_VOLT_MAX 1168L | |
89 | #define PVT_VOLT_CHS 4 | |
90 | #define PVT_DATA_MIN 0 | |
91 | #define PVT_DATA_MAX (PVT_DATA_DATA_MASK >> PVT_DATA_DATA_FLD) | |
92 | #define PVT_TRIM_MIN 0 | |
93 | #define PVT_TRIM_MAX (PVT_CTRL_TRIM_MASK >> PVT_CTRL_TRIM_FLD) | |
94 | #define PVT_TRIM_TEMP 7130 | |
95 | #define PVT_TRIM_STEP (PVT_TRIM_TEMP / PVT_TRIM_MAX) | |
96 | #define PVT_TRIM_DEF 0 | |
97 | #define PVT_TOUT_MIN (NSEC_PER_SEC / 3000) | |
98 | #if defined(CONFIG_SENSORS_BT1_PVT_ALARMS) | |
99 | # define PVT_TOUT_DEF 60000 | |
100 | #else | |
101 | # define PVT_TOUT_DEF 0 | |
102 | #endif | |
103 | ||
104 | /* | |
105 | * enum pvt_sensor_type - Baikal-T1 PVT sensor types (correspond to each PVT | |
106 | * sampling mode) | |
107 | * @PVT_SENSOR*: helpers to traverse the sensors in loops. | |
108 | * @PVT_TEMP: PVT Temperature sensor. | |
109 | * @PVT_VOLT: PVT Voltage sensor. | |
110 | * @PVT_LVT: PVT Low-Voltage threshold sensor. | |
111 | * @PVT_HVT: PVT High-Voltage threshold sensor. | |
112 | * @PVT_SVT: PVT Standard-Voltage threshold sensor. | |
113 | */ | |
114 | enum pvt_sensor_type { | |
115 | PVT_SENSOR_FIRST, | |
116 | PVT_TEMP = PVT_SENSOR_FIRST, | |
117 | PVT_VOLT, | |
118 | PVT_LVT, | |
119 | PVT_HVT, | |
120 | PVT_SVT, | |
121 | PVT_SENSOR_LAST = PVT_SVT, | |
122 | PVT_SENSORS_NUM | |
123 | }; | |
124 | ||
125 | /* | |
126 | * enum pvt_clock_type - Baikal-T1 PVT clocks. | |
127 | * @PVT_CLOCK_APB: APB clock. | |
128 | * @PVT_CLOCK_REF: PVT reference clock. | |
129 | */ | |
130 | enum pvt_clock_type { | |
131 | PVT_CLOCK_APB, | |
132 | PVT_CLOCK_REF, | |
133 | PVT_CLOCK_NUM | |
134 | }; | |
135 | ||
136 | /* | |
137 | * struct pvt_sensor_info - Baikal-T1 PVT sensor informational structure | |
138 | * @channel: Sensor channel ID. | |
139 | * @label: hwmon sensor label. | |
140 | * @mode: PVT mode corresponding to the channel. | |
141 | * @thres_base: upper and lower threshold values of the sensor. | |
142 | * @thres_sts_lo: low threshold status bitfield. | |
143 | * @thres_sts_hi: high threshold status bitfield. | |
144 | * @type: Sensor type. | |
145 | * @attr_min_alarm: Min alarm attribute ID. | |
146 | * @attr_min_alarm: Max alarm attribute ID. | |
147 | */ | |
148 | struct pvt_sensor_info { | |
149 | int channel; | |
150 | const char *label; | |
151 | u32 mode; | |
152 | unsigned long thres_base; | |
153 | u32 thres_sts_lo; | |
154 | u32 thres_sts_hi; | |
155 | enum hwmon_sensor_types type; | |
156 | u32 attr_min_alarm; | |
157 | u32 attr_max_alarm; | |
158 | }; | |
159 | ||
160 | #define PVT_SENSOR_INFO(_ch, _label, _type, _mode, _thres) \ | |
161 | { \ | |
162 | .channel = _ch, \ | |
163 | .label = _label, \ | |
164 | .mode = PVT_CTRL_MODE_ ##_mode, \ | |
165 | .thres_base = PVT_ ##_thres, \ | |
166 | .thres_sts_lo = PVT_INTR_ ##_thres## _LO, \ | |
167 | .thres_sts_hi = PVT_INTR_ ##_thres## _HI, \ | |
168 | .type = _type, \ | |
169 | .attr_min_alarm = _type## _min, \ | |
170 | .attr_max_alarm = _type## _max, \ | |
171 | } | |
172 | ||
173 | /* | |
174 | * struct pvt_cache - PVT sensors data cache | |
175 | * @data: data cache in raw format. | |
176 | * @thres_sts_lo: low threshold status saved on the previous data conversion. | |
177 | * @thres_sts_hi: high threshold status saved on the previous data conversion. | |
178 | * @data_seqlock: cached data seq-lock. | |
179 | * @conversion: data conversion completion. | |
180 | */ | |
181 | struct pvt_cache { | |
182 | u32 data; | |
183 | #if defined(CONFIG_SENSORS_BT1_PVT_ALARMS) | |
184 | seqlock_t data_seqlock; | |
185 | u32 thres_sts_lo; | |
186 | u32 thres_sts_hi; | |
187 | #else | |
188 | struct completion conversion; | |
189 | #endif | |
190 | }; | |
191 | ||
192 | /* | |
193 | * struct pvt_hwmon - Baikal-T1 PVT private data | |
194 | * @dev: device structure of the PVT platform device. | |
195 | * @hwmon: hwmon device structure. | |
196 | * @regs: pointer to the Baikal-T1 PVT registers region. | |
197 | * @irq: PVT events IRQ number. | |
198 | * @clks: Array of the PVT clocks descriptor (APB/ref clocks). | |
199 | * @ref_clk: Pointer to the reference clocks descriptor. | |
200 | * @iface_mtx: Generic interface mutex (used to lock the alarm registers | |
201 | * when the alarms enabled, or the data conversion interface | |
202 | * if alarms are disabled). | |
203 | * @sensor: current PVT sensor the data conversion is being performed for. | |
204 | * @cache: data cache descriptor. | |
0015503e | 205 | * @timeout: conversion timeout cache. |
87976ce2 SS |
206 | */ |
207 | struct pvt_hwmon { | |
208 | struct device *dev; | |
209 | struct device *hwmon; | |
210 | ||
211 | void __iomem *regs; | |
212 | int irq; | |
213 | ||
214 | struct clk_bulk_data clks[PVT_CLOCK_NUM]; | |
215 | ||
216 | struct mutex iface_mtx; | |
217 | enum pvt_sensor_type sensor; | |
218 | struct pvt_cache cache[PVT_SENSORS_NUM]; | |
0015503e | 219 | ktime_t timeout; |
87976ce2 SS |
220 | }; |
221 | ||
222 | /* | |
223 | * struct pvt_poly_term - a term descriptor of the PVT data translation | |
224 | * polynomial | |
225 | * @deg: degree of the term. | |
226 | * @coef: multiplication factor of the term. | |
227 | * @divider: distributed divider per each degree. | |
228 | * @divider_leftover: divider leftover, which couldn't be redistributed. | |
229 | */ | |
230 | struct pvt_poly_term { | |
231 | unsigned int deg; | |
232 | long coef; | |
233 | long divider; | |
234 | long divider_leftover; | |
235 | }; | |
236 | ||
237 | /* | |
238 | * struct pvt_poly - PVT data translation polynomial descriptor | |
239 | * @total_divider: total data divider. | |
240 | * @terms: polynomial terms up to a free one. | |
241 | */ | |
242 | struct pvt_poly { | |
243 | long total_divider; | |
244 | struct pvt_poly_term terms[]; | |
245 | }; | |
246 | ||
247 | #endif /* __HWMON_BT1_PVT_H__ */ |