1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
6 #ifndef __QCOM_TSENS_H__
7 #define __QCOM_TSENS_H__
9 #define NO_PT_CALIB 0x0
10 #define ONE_PT_CALIB 0x1
11 #define ONE_PT_CALIB2 0x2
12 #define TWO_PT_CALIB 0x3
13 #define CAL_DEGC_PT1 30
14 #define CAL_DEGC_PT2 120
15 #define SLOPE_FACTOR 1000
16 #define SLOPE_DEFAULT 3200
17 #define TIMEOUT_US 100
18 #define THRESHOLD_MAX_ADC_CODE 0x3ff
19 #define THRESHOLD_MIN_ADC_CODE 0x0
21 #define MAX_SENSORS 16
23 #include <linux/interrupt.h>
24 #include <linux/thermal.h>
25 #include <linux/regmap.h>
26 #include <linux/slab.h>
30 /* IP version numbers in ascending order */
45 * struct tsens_sensor - data for each sensor connected to the tsens device
46 * @priv: tsens device instance that this sensor is connected to
47 * @tzd: pointer to the thermal zone that this sensor is in
48 * @offset: offset of temperature adjustment curve
49 * @hw_id: HW ID can be used in case of platform-specific IDs
50 * @slope: slope of temperature adjustment curve
51 * @status: 8960-specific variable to track 8960 and 8660 status register offset
54 struct tsens_priv *priv;
55 struct thermal_zone_device *tzd;
63 * struct tsens_ops - operations as supported by the tsens device
64 * @init: Function to initialize the tsens device
65 * @calibrate: Function to calibrate the tsens device
66 * @get_temp: Function which returns the temp in millidegC
67 * @enable: Function to enable (clocks/power) tsens device
68 * @disable: Function to disable the tsens device
69 * @suspend: Function to suspend the tsens device
70 * @resume: Function to resume the tsens device
73 /* mandatory callbacks */
74 int (*init)(struct tsens_priv *priv);
75 int (*calibrate)(struct tsens_priv *priv);
76 int (*get_temp)(const struct tsens_sensor *s, int *temp);
77 /* optional callbacks */
78 int (*enable)(struct tsens_priv *priv, int i);
79 void (*disable)(struct tsens_priv *priv);
80 int (*suspend)(struct tsens_priv *priv);
81 int (*resume)(struct tsens_priv *priv);
84 #define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \
85 [_name##_##0] = REG_FIELD(_offset, _startbit, _stopbit), \
86 [_name##_##1] = REG_FIELD(_offset + 4, _startbit, _stopbit), \
87 [_name##_##2] = REG_FIELD(_offset + 8, _startbit, _stopbit), \
88 [_name##_##3] = REG_FIELD(_offset + 12, _startbit, _stopbit), \
89 [_name##_##4] = REG_FIELD(_offset + 16, _startbit, _stopbit), \
90 [_name##_##5] = REG_FIELD(_offset + 20, _startbit, _stopbit), \
91 [_name##_##6] = REG_FIELD(_offset + 24, _startbit, _stopbit), \
92 [_name##_##7] = REG_FIELD(_offset + 28, _startbit, _stopbit), \
93 [_name##_##8] = REG_FIELD(_offset + 32, _startbit, _stopbit), \
94 [_name##_##9] = REG_FIELD(_offset + 36, _startbit, _stopbit), \
95 [_name##_##10] = REG_FIELD(_offset + 40, _startbit, _stopbit)
97 #define REG_FIELD_FOR_EACH_SENSOR16(_name, _offset, _startbit, _stopbit) \
98 [_name##_##0] = REG_FIELD(_offset, _startbit, _stopbit), \
99 [_name##_##1] = REG_FIELD(_offset + 4, _startbit, _stopbit), \
100 [_name##_##2] = REG_FIELD(_offset + 8, _startbit, _stopbit), \
101 [_name##_##3] = REG_FIELD(_offset + 12, _startbit, _stopbit), \
102 [_name##_##4] = REG_FIELD(_offset + 16, _startbit, _stopbit), \
103 [_name##_##5] = REG_FIELD(_offset + 20, _startbit, _stopbit), \
104 [_name##_##6] = REG_FIELD(_offset + 24, _startbit, _stopbit), \
105 [_name##_##7] = REG_FIELD(_offset + 28, _startbit, _stopbit), \
106 [_name##_##8] = REG_FIELD(_offset + 32, _startbit, _stopbit), \
107 [_name##_##9] = REG_FIELD(_offset + 36, _startbit, _stopbit), \
108 [_name##_##10] = REG_FIELD(_offset + 40, _startbit, _stopbit), \
109 [_name##_##11] = REG_FIELD(_offset + 44, _startbit, _stopbit), \
110 [_name##_##12] = REG_FIELD(_offset + 48, _startbit, _stopbit), \
111 [_name##_##13] = REG_FIELD(_offset + 52, _startbit, _stopbit), \
112 [_name##_##14] = REG_FIELD(_offset + 56, _startbit, _stopbit), \
113 [_name##_##15] = REG_FIELD(_offset + 60, _startbit, _stopbit)
115 #define REG_FIELD_SPLIT_BITS_0_15(_name, _offset) \
116 [_name##_##0] = REG_FIELD(_offset, 0, 0), \
117 [_name##_##1] = REG_FIELD(_offset, 1, 1), \
118 [_name##_##2] = REG_FIELD(_offset, 2, 2), \
119 [_name##_##3] = REG_FIELD(_offset, 3, 3), \
120 [_name##_##4] = REG_FIELD(_offset, 4, 4), \
121 [_name##_##5] = REG_FIELD(_offset, 5, 5), \
122 [_name##_##6] = REG_FIELD(_offset, 6, 6), \
123 [_name##_##7] = REG_FIELD(_offset, 7, 7), \
124 [_name##_##8] = REG_FIELD(_offset, 8, 8), \
125 [_name##_##9] = REG_FIELD(_offset, 9, 9), \
126 [_name##_##10] = REG_FIELD(_offset, 10, 10), \
127 [_name##_##11] = REG_FIELD(_offset, 11, 11), \
128 [_name##_##12] = REG_FIELD(_offset, 12, 12), \
129 [_name##_##13] = REG_FIELD(_offset, 13, 13), \
130 [_name##_##14] = REG_FIELD(_offset, 14, 14), \
131 [_name##_##15] = REG_FIELD(_offset, 15, 15)
133 #define REG_FIELD_SPLIT_BITS_16_31(_name, _offset) \
134 [_name##_##0] = REG_FIELD(_offset, 16, 16), \
135 [_name##_##1] = REG_FIELD(_offset, 17, 17), \
136 [_name##_##2] = REG_FIELD(_offset, 18, 18), \
137 [_name##_##3] = REG_FIELD(_offset, 19, 19), \
138 [_name##_##4] = REG_FIELD(_offset, 20, 20), \
139 [_name##_##5] = REG_FIELD(_offset, 21, 21), \
140 [_name##_##6] = REG_FIELD(_offset, 22, 22), \
141 [_name##_##7] = REG_FIELD(_offset, 23, 23), \
142 [_name##_##8] = REG_FIELD(_offset, 24, 24), \
143 [_name##_##9] = REG_FIELD(_offset, 25, 25), \
144 [_name##_##10] = REG_FIELD(_offset, 26, 26), \
145 [_name##_##11] = REG_FIELD(_offset, 27, 27), \
146 [_name##_##12] = REG_FIELD(_offset, 28, 28), \
147 [_name##_##13] = REG_FIELD(_offset, 29, 29), \
148 [_name##_##14] = REG_FIELD(_offset, 30, 30), \
149 [_name##_##15] = REG_FIELD(_offset, 31, 31)
152 * reg_field IDs to use as an index into an array
153 * If you change the order of the entries, check the devm_regmap_field_alloc()
154 * calls in init_common()
157 /* ----- SROT ------ */
168 /* ----- TM ------ */
171 /* INTERRUPT ENABLE */
172 INT_EN, /* v2+ has separate enables for crit, upper and lower irq */
174 LAST_TEMP_0, /* Last temperature reading */
190 VALID_0, /* VALID reading or not */
206 LOWER_STATUS_0, /* LOWER threshold violated */
222 LOW_INT_STATUS_0, /* LOWER interrupt status */
238 LOW_INT_CLEAR_0, /* LOWER interrupt clear */
254 LOW_INT_MASK_0, /* LOWER interrupt mask */
270 LOW_THRESH_0, /* LOWER threshold values */
286 UPPER_STATUS_0, /* UPPER threshold violated */
302 UP_INT_STATUS_0, /* UPPER interrupt status */
318 UP_INT_CLEAR_0, /* UPPER interrupt clear */
334 UP_INT_MASK_0, /* UPPER interrupt mask */
350 UP_THRESH_0, /* UPPER threshold values */
366 CRITICAL_STATUS_0, /* CRITICAL threshold violated */
382 CRIT_INT_STATUS_0, /* CRITICAL interrupt status */
398 CRIT_INT_CLEAR_0, /* CRITICAL interrupt clear */
414 CRIT_INT_MASK_0, /* CRITICAL interrupt mask */
430 CRIT_THRESH_0, /* CRITICAL threshold values */
453 /* CYCLE COMPLETION MONITOR */
458 MIN_STATUS_0, /* MIN threshold violated */
474 MAX_STATUS_0, /* MAX threshold violated */
496 * struct tsens_features - Features supported by the IP
497 * @ver_major: Major number of IP version
498 * @crit_int: does the IP support critical interrupts?
499 * @combo_int: does the IP use one IRQ for up, low and critical thresholds?
500 * @adc: do the sensors only output adc code (instead of temperature)?
501 * @srot_split: does the IP neatly splits the register space into SROT and TM,
502 * with SROT only being available to secure boot firmware?
503 * @has_watchdog: does this IP support watchdog functionality?
504 * @max_sensors: maximum sensors supported by this version of the IP
505 * @trip_min_temp: minimum trip temperature supported by this version of the IP
506 * @trip_max_temp: maximum trip temperature supported by this version of the IP
508 struct tsens_features {
509 unsigned int ver_major;
510 unsigned int crit_int:1;
511 unsigned int combo_int:1;
513 unsigned int srot_split:1;
514 unsigned int has_watchdog:1;
515 unsigned int max_sensors;
521 * struct tsens_plat_data - tsens compile-time platform data
522 * @num_sensors: Number of sensors supported by platform
523 * @ops: operations the tsens instance supports
524 * @hw_ids: Subset of sensors ids supported by platform, if not the first n
525 * @feat: features of the IP
526 * @fields: bitfield locations
528 struct tsens_plat_data {
529 const u32 num_sensors;
530 const struct tsens_ops *ops;
531 unsigned int *hw_ids;
532 struct tsens_features *feat;
533 const struct reg_field *fields;
537 * struct tsens_context - Registers to be saved/restored across a context loss
538 * @threshold: Threshold register value
539 * @control: Control register value
541 struct tsens_context {
547 * struct tsens_priv - private data for each instance of the tsens IP
548 * @dev: pointer to struct device
549 * @num_sensors: number of sensors enabled on this device
550 * @tm_map: pointer to TM register address space
551 * @srot_map: pointer to SROT register address space
552 * @tm_offset: deal with old device trees that don't address TM and SROT
553 * address space separately
554 * @ul_lock: lock while processing upper/lower threshold interrupts
555 * @crit_lock: lock while processing critical threshold interrupts
556 * @rf: array of regmap_fields used to store value of the field
557 * @ctx: registers to be saved and restored during suspend/resume
558 * @feat: features of the IP
559 * @fields: bitfield locations
560 * @ops: pointer to list of callbacks supported by this device
561 * @debug_root: pointer to debugfs dentry for all tsens
562 * @debug: pointer to debugfs dentry for tsens controller
563 * @sensor: list of sensors attached to this device
568 struct regmap *tm_map;
569 struct regmap *srot_map;
572 /* lock for upper/lower threshold interrupts */
575 struct regmap_field *rf[MAX_REGFIELDS];
576 struct tsens_context ctx;
577 struct tsens_features *feat;
578 const struct reg_field *fields;
579 const struct tsens_ops *ops;
581 struct dentry *debug_root;
582 struct dentry *debug;
584 struct tsens_sensor sensor[];
588 * struct tsens_single_value - internal representation of a single field inside nvmem calibration data
589 * @idx: index into the u32 data array
590 * @shift: the shift of the first bit in the value
591 * @blob: index of the data blob to use for this cell
593 struct tsens_single_value {
600 * struct tsens_legacy_calibration_format - description of calibration data used when parsing the legacy nvmem blob
601 * @base_len: the length of the base fields inside calibration data
602 * @base_shift: the shift to be applied to base data
603 * @sp_len: the length of the sN_pM fields inside calibration data
604 * @mode: descriptor of the calibration mode field
605 * @invalid: descriptor of the calibration mode invalid field
606 * @base: descriptors of the base0 and base1 fields
607 * @sp: descriptors of the sN_pM fields
609 struct tsens_legacy_calibration_format {
610 unsigned int base_len;
611 unsigned int base_shift;
614 struct tsens_single_value mode;
615 /* on all platforms except 8974 invalid is the third bit of what downstream calls 'mode' */
616 struct tsens_single_value invalid;
617 struct tsens_single_value base[2];
618 struct tsens_single_value sp[][2];
621 char *qfprom_read(struct device *dev, const char *cname);
622 int tsens_read_calibration_legacy(struct tsens_priv *priv,
623 const struct tsens_legacy_calibration_format *format,
625 u32 *cdata, u32 *csel);
626 int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, bool backup);
627 int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift);
628 int tsens_calibrate_common(struct tsens_priv *priv);
629 void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode);
630 int init_common(struct tsens_priv *priv);
631 int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp);
632 int get_temp_common(const struct tsens_sensor *s, int *temp);
635 extern struct tsens_plat_data data_8960;
637 /* TSENS v0.1 targets */
638 extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607;
640 /* TSENS v1 targets */
641 extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956;
643 /* TSENS v2 targets */
644 extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2;
646 #endif /* __QCOM_TSENS_H__ */