1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 4 */ 5 6 #ifndef __QCOM_TSENS_H__ 7 #define __QCOM_TSENS_H__ 8 9 #define ONE_PT_CALIB 0x1 10 #define ONE_PT_CALIB2 0x2 11 #define TWO_PT_CALIB 0x3 12 #define CAL_DEGC_PT1 30 13 #define CAL_DEGC_PT2 120 14 #define SLOPE_FACTOR 1000 15 #define SLOPE_DEFAULT 3200 16 17 18 #include <linux/thermal.h> 19 #include <linux/regmap.h> 20 #include <linux/slab.h> 21 22 struct tsens_priv; 23 24 enum tsens_ver { 25 VER_0_1 = 0, 26 VER_1_X, 27 VER_2_X, 28 }; 29 30 /** 31 * struct tsens_sensor - data for each sensor connected to the tsens device 32 * @priv: tsens device instance that this sensor is connected to 33 * @tzd: pointer to the thermal zone that this sensor is in 34 * @offset: offset of temperature adjustment curve 35 * @id: Sensor ID 36 * @hw_id: HW ID can be used in case of platform-specific IDs 37 * @slope: slope of temperature adjustment curve 38 * @status: 8960-specific variable to track 8960 and 8660 status register offset 39 */ 40 struct tsens_sensor { 41 struct tsens_priv *priv; 42 struct thermal_zone_device *tzd; 43 int offset; 44 unsigned int id; 45 unsigned int hw_id; 46 int slope; 47 u32 status; 48 }; 49 50 /** 51 * struct tsens_ops - operations as supported by the tsens device 52 * @init: Function to initialize the tsens device 53 * @calibrate: Function to calibrate the tsens device 54 * @get_temp: Function which returns the temp in millidegC 55 * @enable: Function to enable (clocks/power) tsens device 56 * @disable: Function to disable the tsens device 57 * @suspend: Function to suspend the tsens device 58 * @resume: Function to resume the tsens device 59 * @get_trend: Function to get the thermal/temp trend 60 */ 61 struct tsens_ops { 62 /* mandatory callbacks */ 63 int (*init)(struct tsens_priv *priv); 64 int (*calibrate)(struct tsens_priv *priv); 65 int (*get_temp)(struct tsens_priv *priv, int i, int *temp); 66 /* optional callbacks */ 67 int (*enable)(struct tsens_priv *priv, int i); 68 void (*disable)(struct tsens_priv *priv); 69 int (*suspend)(struct tsens_priv *priv); 70 int (*resume)(struct tsens_priv *priv); 71 int (*get_trend)(struct tsens_priv *priv, int i, enum thermal_trend *trend); 72 }; 73 74 #define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \ 75 [_name##_##0] = REG_FIELD(_offset, _startbit, _stopbit), \ 76 [_name##_##1] = REG_FIELD(_offset + 4, _startbit, _stopbit), \ 77 [_name##_##2] = REG_FIELD(_offset + 8, _startbit, _stopbit), \ 78 [_name##_##3] = REG_FIELD(_offset + 12, _startbit, _stopbit), \ 79 [_name##_##4] = REG_FIELD(_offset + 16, _startbit, _stopbit), \ 80 [_name##_##5] = REG_FIELD(_offset + 20, _startbit, _stopbit), \ 81 [_name##_##6] = REG_FIELD(_offset + 24, _startbit, _stopbit), \ 82 [_name##_##7] = REG_FIELD(_offset + 28, _startbit, _stopbit), \ 83 [_name##_##8] = REG_FIELD(_offset + 32, _startbit, _stopbit), \ 84 [_name##_##9] = REG_FIELD(_offset + 36, _startbit, _stopbit), \ 85 [_name##_##10] = REG_FIELD(_offset + 40, _startbit, _stopbit) 86 87 #define REG_FIELD_FOR_EACH_SENSOR16(_name, _offset, _startbit, _stopbit) \ 88 [_name##_##0] = REG_FIELD(_offset, _startbit, _stopbit), \ 89 [_name##_##1] = REG_FIELD(_offset + 4, _startbit, _stopbit), \ 90 [_name##_##2] = REG_FIELD(_offset + 8, _startbit, _stopbit), \ 91 [_name##_##3] = REG_FIELD(_offset + 12, _startbit, _stopbit), \ 92 [_name##_##4] = REG_FIELD(_offset + 16, _startbit, _stopbit), \ 93 [_name##_##5] = REG_FIELD(_offset + 20, _startbit, _stopbit), \ 94 [_name##_##6] = REG_FIELD(_offset + 24, _startbit, _stopbit), \ 95 [_name##_##7] = REG_FIELD(_offset + 28, _startbit, _stopbit), \ 96 [_name##_##8] = REG_FIELD(_offset + 32, _startbit, _stopbit), \ 97 [_name##_##9] = REG_FIELD(_offset + 36, _startbit, _stopbit), \ 98 [_name##_##10] = REG_FIELD(_offset + 40, _startbit, _stopbit), \ 99 [_name##_##11] = REG_FIELD(_offset + 44, _startbit, _stopbit), \ 100 [_name##_##12] = REG_FIELD(_offset + 48, _startbit, _stopbit), \ 101 [_name##_##13] = REG_FIELD(_offset + 52, _startbit, _stopbit), \ 102 [_name##_##14] = REG_FIELD(_offset + 56, _startbit, _stopbit), \ 103 [_name##_##15] = REG_FIELD(_offset + 60, _startbit, _stopbit) 104 105 /* reg_field IDs to use as an index into an array */ 106 enum regfield_ids { 107 /* ----- SROT ------ */ 108 /* HW_VER */ 109 VER_MAJOR = 0, 110 VER_MINOR, 111 VER_STEP, 112 /* CTRL_OFFSET */ 113 TSENS_EN = 3, 114 TSENS_SW_RST, 115 SENSOR_EN, 116 CODE_OR_TEMP, 117 118 /* ----- TM ------ */ 119 /* STATUS */ 120 LAST_TEMP_0 = 7, /* Last temperature reading */ 121 LAST_TEMP_1, 122 LAST_TEMP_2, 123 LAST_TEMP_3, 124 LAST_TEMP_4, 125 LAST_TEMP_5, 126 LAST_TEMP_6, 127 LAST_TEMP_7, 128 LAST_TEMP_8, 129 LAST_TEMP_9, 130 LAST_TEMP_10, 131 LAST_TEMP_11, 132 LAST_TEMP_12, 133 LAST_TEMP_13, 134 LAST_TEMP_14, 135 LAST_TEMP_15, 136 VALID_0 = 23, /* VALID reading or not */ 137 VALID_1, 138 VALID_2, 139 VALID_3, 140 VALID_4, 141 VALID_5, 142 VALID_6, 143 VALID_7, 144 VALID_8, 145 VALID_9, 146 VALID_10, 147 VALID_11, 148 VALID_12, 149 VALID_13, 150 VALID_14, 151 VALID_15, 152 MIN_STATUS_0, /* MIN threshold violated */ 153 MIN_STATUS_1, 154 MIN_STATUS_2, 155 MIN_STATUS_3, 156 MIN_STATUS_4, 157 MIN_STATUS_5, 158 MIN_STATUS_6, 159 MIN_STATUS_7, 160 MIN_STATUS_8, 161 MIN_STATUS_9, 162 MIN_STATUS_10, 163 MIN_STATUS_11, 164 MIN_STATUS_12, 165 MIN_STATUS_13, 166 MIN_STATUS_14, 167 MIN_STATUS_15, 168 MAX_STATUS_0, /* MAX threshold violated */ 169 MAX_STATUS_1, 170 MAX_STATUS_2, 171 MAX_STATUS_3, 172 MAX_STATUS_4, 173 MAX_STATUS_5, 174 MAX_STATUS_6, 175 MAX_STATUS_7, 176 MAX_STATUS_8, 177 MAX_STATUS_9, 178 MAX_STATUS_10, 179 MAX_STATUS_11, 180 MAX_STATUS_12, 181 MAX_STATUS_13, 182 MAX_STATUS_14, 183 MAX_STATUS_15, 184 LOWER_STATUS_0, /* LOWER threshold violated */ 185 LOWER_STATUS_1, 186 LOWER_STATUS_2, 187 LOWER_STATUS_3, 188 LOWER_STATUS_4, 189 LOWER_STATUS_5, 190 LOWER_STATUS_6, 191 LOWER_STATUS_7, 192 LOWER_STATUS_8, 193 LOWER_STATUS_9, 194 LOWER_STATUS_10, 195 LOWER_STATUS_11, 196 LOWER_STATUS_12, 197 LOWER_STATUS_13, 198 LOWER_STATUS_14, 199 LOWER_STATUS_15, 200 UPPER_STATUS_0, /* UPPER threshold violated */ 201 UPPER_STATUS_1, 202 UPPER_STATUS_2, 203 UPPER_STATUS_3, 204 UPPER_STATUS_4, 205 UPPER_STATUS_5, 206 UPPER_STATUS_6, 207 UPPER_STATUS_7, 208 UPPER_STATUS_8, 209 UPPER_STATUS_9, 210 UPPER_STATUS_10, 211 UPPER_STATUS_11, 212 UPPER_STATUS_12, 213 UPPER_STATUS_13, 214 UPPER_STATUS_14, 215 UPPER_STATUS_15, 216 CRITICAL_STATUS_0, /* CRITICAL threshold violated */ 217 CRITICAL_STATUS_1, 218 CRITICAL_STATUS_2, 219 CRITICAL_STATUS_3, 220 CRITICAL_STATUS_4, 221 CRITICAL_STATUS_5, 222 CRITICAL_STATUS_6, 223 CRITICAL_STATUS_7, 224 CRITICAL_STATUS_8, 225 CRITICAL_STATUS_9, 226 CRITICAL_STATUS_10, 227 CRITICAL_STATUS_11, 228 CRITICAL_STATUS_12, 229 CRITICAL_STATUS_13, 230 CRITICAL_STATUS_14, 231 CRITICAL_STATUS_15, 232 /* TRDY */ 233 TRDY, 234 /* INTERRUPT ENABLE */ 235 INT_EN, /* Pre-V1, V1.x */ 236 LOW_INT_EN, /* V2.x */ 237 UP_INT_EN, /* V2.x */ 238 CRIT_INT_EN, /* V2.x */ 239 240 /* Keep last */ 241 MAX_REGFIELDS 242 }; 243 244 /** 245 * struct tsens_features - Features supported by the IP 246 * @ver_major: Major number of IP version 247 * @crit_int: does the IP support critical interrupts? 248 * @adc: do the sensors only output adc code (instead of temperature)? 249 * @srot_split: does the IP neatly splits the register space into SROT and TM, 250 * with SROT only being available to secure boot firmware? 251 * @max_sensors: maximum sensors supported by this version of the IP 252 */ 253 struct tsens_features { 254 unsigned int ver_major; 255 unsigned int crit_int:1; 256 unsigned int adc:1; 257 unsigned int srot_split:1; 258 unsigned int max_sensors; 259 }; 260 261 /** 262 * struct tsens_plat_data - tsens compile-time platform data 263 * @num_sensors: Number of sensors supported by platform 264 * @ops: operations the tsens instance supports 265 * @hw_ids: Subset of sensors ids supported by platform, if not the first n 266 * @feat: features of the IP 267 * @fields: bitfield locations 268 */ 269 struct tsens_plat_data { 270 const u32 num_sensors; 271 const struct tsens_ops *ops; 272 unsigned int *hw_ids; 273 const struct tsens_features *feat; 274 const struct reg_field *fields; 275 }; 276 277 /** 278 * struct tsens_context - Registers to be saved/restored across a context loss 279 */ 280 struct tsens_context { 281 int threshold; 282 int control; 283 }; 284 285 /** 286 * struct tsens_priv - private data for each instance of the tsens IP 287 * @dev: pointer to struct device 288 * @num_sensors: number of sensors enabled on this device 289 * @tm_map: pointer to TM register address space 290 * @srot_map: pointer to SROT register address space 291 * @tm_offset: deal with old device trees that don't address TM and SROT 292 * address space separately 293 * @rf: array of regmap_fields used to store value of the field 294 * @ctx: registers to be saved and restored during suspend/resume 295 * @feat: features of the IP 296 * @fields: bitfield locations 297 * @ops: pointer to list of callbacks supported by this device 298 * @sensor: list of sensors attached to this device 299 */ 300 struct tsens_priv { 301 struct device *dev; 302 u32 num_sensors; 303 struct regmap *tm_map; 304 struct regmap *srot_map; 305 u32 tm_offset; 306 struct regmap_field *rf[MAX_REGFIELDS]; 307 struct tsens_context ctx; 308 const struct tsens_features *feat; 309 const struct reg_field *fields; 310 const struct tsens_ops *ops; 311 struct tsens_sensor sensor[0]; 312 }; 313 314 char *qfprom_read(struct device *dev, const char *cname); 315 void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode); 316 int init_common(struct tsens_priv *priv); 317 int get_temp_tsens_valid(struct tsens_priv *priv, int i, int *temp); 318 int get_temp_common(struct tsens_priv *priv, int i, int *temp); 319 320 /* TSENS target */ 321 extern const struct tsens_plat_data data_8960; 322 323 /* TSENS v0.1 targets */ 324 extern const struct tsens_plat_data data_8916, data_8974; 325 326 /* TSENS v1 targets */ 327 extern const struct tsens_plat_data data_tsens_v1; 328 329 /* TSENS v2 targets */ 330 extern const struct tsens_plat_data data_8996, data_tsens_v2; 331 332 #endif /* __QCOM_TSENS_H__ */ 333