1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2019, Linaro Limited
6 #include <linux/bitops.h>
7 #include <linux/regmap.h>
8 #include <linux/delay.h>
9 #include <linux/slab.h>
12 /* ----- SROT ------ */
13 #define SROT_HW_VER_OFF 0x0000
14 #define SROT_CTRL_OFF 0x0004
17 #define TM_INT_EN_OFF 0x0000
18 #define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF 0x0004
19 #define TM_Sn_STATUS_OFF 0x0044
20 #define TM_TRDY_OFF 0x0084
21 #define TM_HIGH_LOW_INT_STATUS_OFF 0x0088
22 #define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090
24 /* eeprom layout data for msm8956/76 (v1) */
25 #define MSM8976_BASE0_MASK 0xff
26 #define MSM8976_BASE1_MASK 0xff
27 #define MSM8976_BASE1_SHIFT 8
29 #define MSM8976_S0_P1_MASK 0x3f00
30 #define MSM8976_S1_P1_MASK 0x3f00000
31 #define MSM8976_S2_P1_MASK 0x3f
32 #define MSM8976_S3_P1_MASK 0x3f000
33 #define MSM8976_S4_P1_MASK 0x3f00
34 #define MSM8976_S5_P1_MASK 0x3f00000
35 #define MSM8976_S6_P1_MASK 0x3f
36 #define MSM8976_S7_P1_MASK 0x3f000
37 #define MSM8976_S8_P1_MASK 0x1f8
38 #define MSM8976_S9_P1_MASK 0x1f8000
39 #define MSM8976_S10_P1_MASK 0xf8000000
40 #define MSM8976_S10_P1_MASK_1 0x1
42 #define MSM8976_S0_P2_MASK 0xfc000
43 #define MSM8976_S1_P2_MASK 0xfc000000
44 #define MSM8976_S2_P2_MASK 0xfc0
45 #define MSM8976_S3_P2_MASK 0xfc0000
46 #define MSM8976_S4_P2_MASK 0xfc000
47 #define MSM8976_S5_P2_MASK 0xfc000000
48 #define MSM8976_S6_P2_MASK 0xfc0
49 #define MSM8976_S7_P2_MASK 0xfc0000
50 #define MSM8976_S8_P2_MASK 0x7e00
51 #define MSM8976_S9_P2_MASK 0x7e00000
52 #define MSM8976_S10_P2_MASK 0x7e
54 #define MSM8976_S0_P1_SHIFT 8
55 #define MSM8976_S1_P1_SHIFT 20
56 #define MSM8976_S2_P1_SHIFT 0
57 #define MSM8976_S3_P1_SHIFT 12
58 #define MSM8976_S4_P1_SHIFT 8
59 #define MSM8976_S5_P1_SHIFT 20
60 #define MSM8976_S6_P1_SHIFT 0
61 #define MSM8976_S7_P1_SHIFT 12
62 #define MSM8976_S8_P1_SHIFT 3
63 #define MSM8976_S9_P1_SHIFT 15
64 #define MSM8976_S10_P1_SHIFT 27
65 #define MSM8976_S10_P1_SHIFT_1 0
67 #define MSM8976_S0_P2_SHIFT 14
68 #define MSM8976_S1_P2_SHIFT 26
69 #define MSM8976_S2_P2_SHIFT 6
70 #define MSM8976_S3_P2_SHIFT 18
71 #define MSM8976_S4_P2_SHIFT 14
72 #define MSM8976_S5_P2_SHIFT 26
73 #define MSM8976_S6_P2_SHIFT 6
74 #define MSM8976_S7_P2_SHIFT 18
75 #define MSM8976_S8_P2_SHIFT 9
76 #define MSM8976_S9_P2_SHIFT 21
77 #define MSM8976_S10_P2_SHIFT 1
79 #define MSM8976_CAL_SEL_MASK 0x3
81 #define MSM8976_CAL_DEGC_PT1 30
82 #define MSM8976_CAL_DEGC_PT2 120
83 #define MSM8976_SLOPE_FACTOR 1000
84 #define MSM8976_SLOPE_DEFAULT 3200
86 /* eeprom layout data for qcs404/405 (v1) */
87 #define BASE0_MASK 0x000007f8
88 #define BASE1_MASK 0x0007f800
90 #define BASE1_SHIFT 11
92 #define S0_P1_MASK 0x0000003f
93 #define S1_P1_MASK 0x0003f000
94 #define S2_P1_MASK 0x3f000000
95 #define S3_P1_MASK 0x000003f0
96 #define S4_P1_MASK 0x003f0000
97 #define S5_P1_MASK 0x0000003f
98 #define S6_P1_MASK 0x0003f000
99 #define S7_P1_MASK 0x3f000000
100 #define S8_P1_MASK 0x000003f0
101 #define S9_P1_MASK 0x003f0000
103 #define S0_P2_MASK 0x00000fc0
104 #define S1_P2_MASK 0x00fc0000
105 #define S2_P2_MASK_1_0 0xc0000000
106 #define S2_P2_MASK_5_2 0x0000000f
107 #define S3_P2_MASK 0x0000fc00
108 #define S4_P2_MASK 0x0fc00000
109 #define S5_P2_MASK 0x00000fc0
110 #define S6_P2_MASK 0x00fc0000
111 #define S7_P2_MASK_1_0 0xc0000000
112 #define S7_P2_MASK_5_2 0x0000000f
113 #define S8_P2_MASK 0x0000fc00
114 #define S9_P2_MASK 0x0fc00000
116 #define S0_P1_SHIFT 0
117 #define S0_P2_SHIFT 6
118 #define S1_P1_SHIFT 12
119 #define S1_P2_SHIFT 18
120 #define S2_P1_SHIFT 24
121 #define S2_P2_SHIFT_1_0 30
123 #define S2_P2_SHIFT_5_2 0
124 #define S3_P1_SHIFT 4
125 #define S3_P2_SHIFT 10
126 #define S4_P1_SHIFT 16
127 #define S4_P2_SHIFT 22
129 #define S5_P1_SHIFT 0
130 #define S5_P2_SHIFT 6
131 #define S6_P1_SHIFT 12
132 #define S6_P2_SHIFT 18
133 #define S7_P1_SHIFT 24
134 #define S7_P2_SHIFT_1_0 30
136 #define S7_P2_SHIFT_5_2 0
137 #define S8_P1_SHIFT 4
138 #define S8_P2_SHIFT 10
139 #define S9_P1_SHIFT 16
140 #define S9_P2_SHIFT 22
142 #define CAL_SEL_MASK 7
143 #define CAL_SEL_SHIFT 0
145 static void compute_intercept_slope_8976(struct tsens_priv
*priv
,
146 u32
*p1
, u32
*p2
, u32 mode
)
150 priv
->sensor
[0].slope
= 3313;
151 priv
->sensor
[1].slope
= 3275;
152 priv
->sensor
[2].slope
= 3320;
153 priv
->sensor
[3].slope
= 3246;
154 priv
->sensor
[4].slope
= 3279;
155 priv
->sensor
[5].slope
= 3257;
156 priv
->sensor
[6].slope
= 3234;
157 priv
->sensor
[7].slope
= 3269;
158 priv
->sensor
[8].slope
= 3255;
159 priv
->sensor
[9].slope
= 3239;
160 priv
->sensor
[10].slope
= 3286;
162 for (i
= 0; i
< priv
->num_sensors
; i
++) {
163 priv
->sensor
[i
].offset
= (p1
[i
] * MSM8976_SLOPE_FACTOR
) -
164 (MSM8976_CAL_DEGC_PT1
*
165 priv
->sensor
[i
].slope
);
169 static int calibrate_v1(struct tsens_priv
*priv
)
171 u32 base0
= 0, base1
= 0;
173 u32 mode
= 0, lsb
= 0, msb
= 0;
177 qfprom_cdata
= (u32
*)qfprom_read(priv
->dev
, "calib");
178 if (IS_ERR(qfprom_cdata
))
179 return PTR_ERR(qfprom_cdata
);
181 mode
= (qfprom_cdata
[4] & CAL_SEL_MASK
) >> CAL_SEL_SHIFT
;
182 dev_dbg(priv
->dev
, "calibration mode is %d\n", mode
);
186 base1
= (qfprom_cdata
[4] & BASE1_MASK
) >> BASE1_SHIFT
;
187 p2
[0] = (qfprom_cdata
[0] & S0_P2_MASK
) >> S0_P2_SHIFT
;
188 p2
[1] = (qfprom_cdata
[0] & S1_P2_MASK
) >> S1_P2_SHIFT
;
189 /* This value is split over two registers, 2 bits and 4 bits */
190 lsb
= (qfprom_cdata
[0] & S2_P2_MASK_1_0
) >> S2_P2_SHIFT_1_0
;
191 msb
= (qfprom_cdata
[1] & S2_P2_MASK_5_2
) >> S2_P2_SHIFT_5_2
;
192 p2
[2] = msb
<< 2 | lsb
;
193 p2
[3] = (qfprom_cdata
[1] & S3_P2_MASK
) >> S3_P2_SHIFT
;
194 p2
[4] = (qfprom_cdata
[1] & S4_P2_MASK
) >> S4_P2_SHIFT
;
195 p2
[5] = (qfprom_cdata
[2] & S5_P2_MASK
) >> S5_P2_SHIFT
;
196 p2
[6] = (qfprom_cdata
[2] & S6_P2_MASK
) >> S6_P2_SHIFT
;
197 /* This value is split over two registers, 2 bits and 4 bits */
198 lsb
= (qfprom_cdata
[2] & S7_P2_MASK_1_0
) >> S7_P2_SHIFT_1_0
;
199 msb
= (qfprom_cdata
[3] & S7_P2_MASK_5_2
) >> S7_P2_SHIFT_5_2
;
200 p2
[7] = msb
<< 2 | lsb
;
201 p2
[8] = (qfprom_cdata
[3] & S8_P2_MASK
) >> S8_P2_SHIFT
;
202 p2
[9] = (qfprom_cdata
[3] & S9_P2_MASK
) >> S9_P2_SHIFT
;
203 for (i
= 0; i
< priv
->num_sensors
; i
++)
204 p2
[i
] = ((base1
+ p2
[i
]) << 2);
207 base0
= (qfprom_cdata
[4] & BASE0_MASK
) >> BASE0_SHIFT
;
208 p1
[0] = (qfprom_cdata
[0] & S0_P1_MASK
) >> S0_P1_SHIFT
;
209 p1
[1] = (qfprom_cdata
[0] & S1_P1_MASK
) >> S1_P1_SHIFT
;
210 p1
[2] = (qfprom_cdata
[0] & S2_P1_MASK
) >> S2_P1_SHIFT
;
211 p1
[3] = (qfprom_cdata
[1] & S3_P1_MASK
) >> S3_P1_SHIFT
;
212 p1
[4] = (qfprom_cdata
[1] & S4_P1_MASK
) >> S4_P1_SHIFT
;
213 p1
[5] = (qfprom_cdata
[2] & S5_P1_MASK
) >> S5_P1_SHIFT
;
214 p1
[6] = (qfprom_cdata
[2] & S6_P1_MASK
) >> S6_P1_SHIFT
;
215 p1
[7] = (qfprom_cdata
[2] & S7_P1_MASK
) >> S7_P1_SHIFT
;
216 p1
[8] = (qfprom_cdata
[3] & S8_P1_MASK
) >> S8_P1_SHIFT
;
217 p1
[9] = (qfprom_cdata
[3] & S9_P1_MASK
) >> S9_P1_SHIFT
;
218 for (i
= 0; i
< priv
->num_sensors
; i
++)
219 p1
[i
] = (((base0
) + p1
[i
]) << 2);
222 for (i
= 0; i
< priv
->num_sensors
; i
++) {
229 compute_intercept_slope(priv
, p1
, p2
, mode
);
235 static int calibrate_8976(struct tsens_priv
*priv
)
237 int base0
= 0, base1
= 0, i
;
239 int mode
= 0, tmp
= 0;
242 qfprom_cdata
= (u32
*)qfprom_read(priv
->dev
, "calib");
243 if (IS_ERR(qfprom_cdata
))
244 return PTR_ERR(qfprom_cdata
);
246 mode
= (qfprom_cdata
[4] & MSM8976_CAL_SEL_MASK
);
247 dev_dbg(priv
->dev
, "calibration mode is %d\n", mode
);
251 base1
= (qfprom_cdata
[2] & MSM8976_BASE1_MASK
) >> MSM8976_BASE1_SHIFT
;
252 p2
[0] = (qfprom_cdata
[0] & MSM8976_S0_P2_MASK
) >> MSM8976_S0_P2_SHIFT
;
253 p2
[1] = (qfprom_cdata
[0] & MSM8976_S1_P2_MASK
) >> MSM8976_S1_P2_SHIFT
;
254 p2
[2] = (qfprom_cdata
[1] & MSM8976_S2_P2_MASK
) >> MSM8976_S2_P2_SHIFT
;
255 p2
[3] = (qfprom_cdata
[1] & MSM8976_S3_P2_MASK
) >> MSM8976_S3_P2_SHIFT
;
256 p2
[4] = (qfprom_cdata
[2] & MSM8976_S4_P2_MASK
) >> MSM8976_S4_P2_SHIFT
;
257 p2
[5] = (qfprom_cdata
[2] & MSM8976_S5_P2_MASK
) >> MSM8976_S5_P2_SHIFT
;
258 p2
[6] = (qfprom_cdata
[3] & MSM8976_S6_P2_MASK
) >> MSM8976_S6_P2_SHIFT
;
259 p2
[7] = (qfprom_cdata
[3] & MSM8976_S7_P2_MASK
) >> MSM8976_S7_P2_SHIFT
;
260 p2
[8] = (qfprom_cdata
[4] & MSM8976_S8_P2_MASK
) >> MSM8976_S8_P2_SHIFT
;
261 p2
[9] = (qfprom_cdata
[4] & MSM8976_S9_P2_MASK
) >> MSM8976_S9_P2_SHIFT
;
262 p2
[10] = (qfprom_cdata
[5] & MSM8976_S10_P2_MASK
) >> MSM8976_S10_P2_SHIFT
;
264 for (i
= 0; i
< priv
->num_sensors
; i
++)
265 p2
[i
] = ((base1
+ p2
[i
]) << 2);
268 base0
= qfprom_cdata
[0] & MSM8976_BASE0_MASK
;
269 p1
[0] = (qfprom_cdata
[0] & MSM8976_S0_P1_MASK
) >> MSM8976_S0_P1_SHIFT
;
270 p1
[1] = (qfprom_cdata
[0] & MSM8976_S1_P1_MASK
) >> MSM8976_S1_P1_SHIFT
;
271 p1
[2] = (qfprom_cdata
[1] & MSM8976_S2_P1_MASK
) >> MSM8976_S2_P1_SHIFT
;
272 p1
[3] = (qfprom_cdata
[1] & MSM8976_S3_P1_MASK
) >> MSM8976_S3_P1_SHIFT
;
273 p1
[4] = (qfprom_cdata
[2] & MSM8976_S4_P1_MASK
) >> MSM8976_S4_P1_SHIFT
;
274 p1
[5] = (qfprom_cdata
[2] & MSM8976_S5_P1_MASK
) >> MSM8976_S5_P1_SHIFT
;
275 p1
[6] = (qfprom_cdata
[3] & MSM8976_S6_P1_MASK
) >> MSM8976_S6_P1_SHIFT
;
276 p1
[7] = (qfprom_cdata
[3] & MSM8976_S7_P1_MASK
) >> MSM8976_S7_P1_SHIFT
;
277 p1
[8] = (qfprom_cdata
[4] & MSM8976_S8_P1_MASK
) >> MSM8976_S8_P1_SHIFT
;
278 p1
[9] = (qfprom_cdata
[4] & MSM8976_S9_P1_MASK
) >> MSM8976_S9_P1_SHIFT
;
279 p1
[10] = (qfprom_cdata
[4] & MSM8976_S10_P1_MASK
) >> MSM8976_S10_P1_SHIFT
;
280 tmp
= (qfprom_cdata
[5] & MSM8976_S10_P1_MASK_1
) << MSM8976_S10_P1_SHIFT_1
;
283 for (i
= 0; i
< priv
->num_sensors
; i
++)
284 p1
[i
] = (((base0
) + p1
[i
]) << 2);
287 for (i
= 0; i
< priv
->num_sensors
; i
++) {
294 compute_intercept_slope_8976(priv
, p1
, p2
, mode
);
300 /* v1.x: msm8956,8976,qcs404,405 */
302 static const struct tsens_features tsens_v1_feat
= {
303 .ver_major
= VER_1_X
,
310 static const struct reg_field tsens_v1_regfields
[MAX_REGFIELDS
] = {
311 /* ----- SROT ------ */
313 [VER_MAJOR
] = REG_FIELD(SROT_HW_VER_OFF
, 28, 31),
314 [VER_MINOR
] = REG_FIELD(SROT_HW_VER_OFF
, 16, 27),
315 [VER_STEP
] = REG_FIELD(SROT_HW_VER_OFF
, 0, 15),
317 [TSENS_EN
] = REG_FIELD(SROT_CTRL_OFF
, 0, 0),
318 [TSENS_SW_RST
] = REG_FIELD(SROT_CTRL_OFF
, 1, 1),
319 [SENSOR_EN
] = REG_FIELD(SROT_CTRL_OFF
, 3, 13),
321 /* ----- TM ------ */
322 /* INTERRUPT ENABLE */
323 [INT_EN
] = REG_FIELD(TM_INT_EN_OFF
, 0, 0),
325 /* UPPER/LOWER TEMPERATURE THRESHOLDS */
326 REG_FIELD_FOR_EACH_SENSOR11(LOW_THRESH
, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF
, 0, 9),
327 REG_FIELD_FOR_EACH_SENSOR11(UP_THRESH
, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF
, 10, 19),
329 /* UPPER/LOWER INTERRUPTS [CLEAR/STATUS] */
330 REG_FIELD_FOR_EACH_SENSOR11(LOW_INT_CLEAR
, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF
, 20, 20),
331 REG_FIELD_FOR_EACH_SENSOR11(UP_INT_CLEAR
, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF
, 21, 21),
332 [LOW_INT_STATUS_0
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 0, 0),
333 [LOW_INT_STATUS_1
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 1, 1),
334 [LOW_INT_STATUS_2
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 2, 2),
335 [LOW_INT_STATUS_3
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 3, 3),
336 [LOW_INT_STATUS_4
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 4, 4),
337 [LOW_INT_STATUS_5
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 5, 5),
338 [LOW_INT_STATUS_6
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 6, 6),
339 [LOW_INT_STATUS_7
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 7, 7),
340 [UP_INT_STATUS_0
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 8, 8),
341 [UP_INT_STATUS_1
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 9, 9),
342 [UP_INT_STATUS_2
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 10, 10),
343 [UP_INT_STATUS_3
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 11, 11),
344 [UP_INT_STATUS_4
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 12, 12),
345 [UP_INT_STATUS_5
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 13, 13),
346 [UP_INT_STATUS_6
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 14, 14),
347 [UP_INT_STATUS_7
] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF
, 15, 15),
349 /* NO CRITICAL INTERRUPT SUPPORT on v1 */
352 REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP
, TM_Sn_STATUS_OFF
, 0, 9),
353 REG_FIELD_FOR_EACH_SENSOR11(VALID
, TM_Sn_STATUS_OFF
, 14, 14),
354 /* xxx_STATUS bits: 1 == threshold violated */
355 REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS
, TM_Sn_STATUS_OFF
, 10, 10),
356 REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS
, TM_Sn_STATUS_OFF
, 11, 11),
357 REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS
, TM_Sn_STATUS_OFF
, 12, 12),
358 /* No CRITICAL field on v1.x */
359 REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS
, TM_Sn_STATUS_OFF
, 13, 13),
361 /* TRDY: 1=ready, 0=in progress */
362 [TRDY
] = REG_FIELD(TM_TRDY_OFF
, 0, 0),
365 static const struct tsens_ops ops_generic_v1
= {
367 .calibrate
= calibrate_v1
,
368 .get_temp
= get_temp_tsens_valid
,
371 const struct tsens_plat_data data_tsens_v1
= {
372 .ops
= &ops_generic_v1
,
373 .feat
= &tsens_v1_feat
,
374 .fields
= tsens_v1_regfields
,
377 static const struct tsens_ops ops_8976
= {
379 .calibrate
= calibrate_8976
,
380 .get_temp
= get_temp_tsens_valid
,
383 /* Valid for both MSM8956 and MSM8976. Sensor ID 3 is unused. */
384 const struct tsens_plat_data data_8976
= {
387 .hw_ids
= (unsigned int[]){0, 1, 2, 4, 5, 6, 7, 8, 9, 10},
388 .feat
= &tsens_v1_feat
,
389 .fields
= tsens_v1_regfields
,