1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2019, Linaro Limited
4 */
5
6 #include <linux/bitops.h>
7 #include <linux/regmap.h>
8 #include <linux/delay.h>
9 #include <linux/slab.h>
10 #include "tsens.h"
11
12 /* ----- SROT ------ */
13 #define SROT_HW_VER_OFF 0x0000
14 #define SROT_CTRL_OFF 0x0004
15
16 /* ----- TM ------ */
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
23
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
28
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
41
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
53
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
66
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
78
79 #define MSM8976_CAL_SEL_MASK 0x3
80
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
85
86 /* eeprom layout data for qcs404/405 (v1) */
87 #define BASE0_MASK 0x000007f8
88 #define BASE1_MASK 0x0007f800
89 #define BASE0_SHIFT 3
90 #define BASE1_SHIFT 11
91
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
102
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
115
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
122
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
128
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
135
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
141
142 #define CAL_SEL_MASK 7
143 #define CAL_SEL_SHIFT 0
144
compute_intercept_slope_8976(struct tsens_priv * priv,u32 * p1,u32 * p2,u32 mode)145 static void compute_intercept_slope_8976(struct tsens_priv *priv,
146 u32 *p1, u32 *p2, u32 mode)
147 {
148 int i;
149
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;
161
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);
166 }
167 }
168
calibrate_v1(struct tsens_priv * priv)169 static int calibrate_v1(struct tsens_priv *priv)
170 {
171 u32 base0 = 0, base1 = 0;
172 u32 p1[10], p2[10];
173 u32 mode = 0, lsb = 0, msb = 0;
174 u32 *qfprom_cdata;
175 int i;
176
177 qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
178 if (IS_ERR(qfprom_cdata))
179 return PTR_ERR(qfprom_cdata);
180
181 mode = (qfprom_cdata[4] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
182 dev_dbg(priv->dev, "calibration mode is %d\n", mode);
183
184 switch (mode) {
185 case TWO_PT_CALIB:
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);
205 fallthrough;
206 case ONE_PT_CALIB2:
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);
220 break;
221 default:
222 for (i = 0; i < priv->num_sensors; i++) {
223 p1[i] = 500;
224 p2[i] = 780;
225 }
226 break;
227 }
228
229 compute_intercept_slope(priv, p1, p2, mode);
230 kfree(qfprom_cdata);
231
232 return 0;
233 }
234
calibrate_8976(struct tsens_priv * priv)235 static int calibrate_8976(struct tsens_priv *priv)
236 {
237 int base0 = 0, base1 = 0, i;
238 u32 p1[11], p2[11];
239 int mode = 0, tmp = 0;
240 u32 *qfprom_cdata;
241
242 qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
243 if (IS_ERR(qfprom_cdata))
244 return PTR_ERR(qfprom_cdata);
245
246 mode = (qfprom_cdata[4] & MSM8976_CAL_SEL_MASK);
247 dev_dbg(priv->dev, "calibration mode is %d\n", mode);
248
249 switch (mode) {
250 case TWO_PT_CALIB:
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;
263
264 for (i = 0; i < priv->num_sensors; i++)
265 p2[i] = ((base1 + p2[i]) << 2);
266 fallthrough;
267 case ONE_PT_CALIB2:
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;
281 p1[10] |= tmp;
282
283 for (i = 0; i < priv->num_sensors; i++)
284 p1[i] = (((base0) + p1[i]) << 2);
285 break;
286 default:
287 for (i = 0; i < priv->num_sensors; i++) {
288 p1[i] = 500;
289 p2[i] = 780;
290 }
291 break;
292 }
293
294 compute_intercept_slope_8976(priv, p1, p2, mode);
295 kfree(qfprom_cdata);
296
297 return 0;
298 }
299
300 /* v1.x: msm8956,8976,qcs404,405 */
301
302 static struct tsens_features tsens_v1_feat = {
303 .ver_major = VER_1_X,
304 .crit_int = 0,
305 .adc = 1,
306 .srot_split = 1,
307 .max_sensors = 11,
308 };
309
310 static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
311 /* ----- SROT ------ */
312 /* VERSION */
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),
316 /* CTRL_OFFSET */
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),
320
321 /* ----- TM ------ */
322 /* INTERRUPT ENABLE */
323 [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0),
324
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),
328
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),
348
349 /* NO CRITICAL INTERRUPT SUPPORT on v1 */
350
351 /* Sn_STATUS */
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),
360
361 /* TRDY: 1=ready, 0=in progress */
362 [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
363 };
364
365 static const struct tsens_ops ops_generic_v1 = {
366 .init = init_common,
367 .calibrate = calibrate_v1,
368 .get_temp = get_temp_tsens_valid,
369 };
370
371 struct tsens_plat_data data_tsens_v1 = {
372 .ops = &ops_generic_v1,
373 .feat = &tsens_v1_feat,
374 .fields = tsens_v1_regfields,
375 };
376
377 static const struct tsens_ops ops_8976 = {
378 .init = init_common,
379 .calibrate = calibrate_8976,
380 .get_temp = get_temp_tsens_valid,
381 };
382
383 /* Valid for both MSM8956 and MSM8976. Sensor ID 3 is unused. */
384 struct tsens_plat_data data_8976 = {
385 .num_sensors = 11,
386 .ops = &ops_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,
390 };
391