1
2
3
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
13#define SROT_HW_VER_OFF 0x0000
14#define SROT_CTRL_OFF 0x0004
15
16
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
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
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
145static 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
169static 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
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
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
235static 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
301
302static 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
310static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
311
312
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
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
322
323 [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0),
324
325
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
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
350
351
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
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
359 REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS, TM_Sn_STATUS_OFF, 13, 13),
360
361
362 [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
363};
364
365static const struct tsens_ops ops_generic_v1 = {
366 .init = init_common,
367 .calibrate = calibrate_v1,
368 .get_temp = get_temp_tsens_valid,
369};
370
371struct tsens_plat_data data_tsens_v1 = {
372 .ops = &ops_generic_v1,
373 .feat = &tsens_v1_feat,
374 .fields = tsens_v1_regfields,
375};
376
377static const struct tsens_ops ops_8976 = {
378 .init = init_common,
379 .calibrate = calibrate_8976,
380 .get_temp = get_temp_tsens_valid,
381};
382
383
384struct tsens_plat_data data_8976 = {
385 .num_sensors = 11,
386 .ops = &ops_8976,
387 .hw_ids = (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
388 .feat = &tsens_v1_feat,
389 .fields = tsens_v1_regfields,
390};
391