blob: 04dd5c50079f8edc4f4584d9ea90c06c0d5dc402 [file] [log] [blame]
Chinkit Kumar,Kirti Kumar Parmar253de882018-06-06 00:11:56 +05301/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/platform_device.h>
15#include "tsens.h"
16
17/* eeprom layout data for 8937 */
18#define BASE0_MASK_8937 0x000000ff
19#define BASE1_MASK_8937 0xff000000
20#define BASE1_SHIFT_8937 24
21
22#define S0_P1_MASK_8937 0x000001f8
23#define S1_P1_MASK_8937 0x001f8000
24#define S2_P1_MASK_0_4_8937 0xf8000000
25#define S2_P1_MASK_5_8937 0x00000001
26#define S3_P1_MASK_8937 0x00001f80
27#define S4_P1_MASK_8937 0x01f80000
28#define S5_P1_MASK_8937 0x00003f00
29#define S6_P1_MASK_8937 0x03f00000
30#define S7_P1_MASK_8937 0x0000003f
31#define S8_P1_MASK_8937 0x0003f000
32#define S9_P1_MASK_8937 0x0000003f
33#define S10_P1_MASK_8937 0x0003f000
34
35#define S0_P2_MASK_8937 0x00007e00
36#define S1_P2_MASK_8937 0x07e00000
37#define S2_P2_MASK_8937 0x0000007e
38#define S3_P2_MASK_8937 0x0007e000
39#define S4_P2_MASK_8937 0x7e000000
40#define S5_P2_MASK_8937 0x000fc000
41#define S6_P2_MASK_8937 0xfc000000
42#define S7_P2_MASK_8937 0x00000fc0
43#define S8_P2_MASK_8937 0x00fc0000
44#define S9_P2_MASK_8937 0x00000fc0
45#define S10_P2_MASK_8937 0x00fc0000
46
47#define S0_P1_SHIFT_8937 3
48#define S1_P1_SHIFT_8937 15
49#define S2_P1_SHIFT_0_4_8937 27
50#define S2_P1_SHIFT_5_8937 5
51#define S3_P1_SHIFT_8937 7
52#define S4_P1_SHIFT_8937 19
53#define S5_P1_SHIFT_8937 8
54#define S6_P1_SHIFT_8937 20
55#define S8_P1_SHIFT_8937 12
56#define S10_P1_SHIFT_8937 12
57
58#define S0_P2_SHIFT_8937 9
59#define S1_P2_SHIFT_8937 21
60#define S2_P2_SHIFT_8937 1
61#define S3_P2_SHIFT_8937 13
62#define S4_P2_SHIFT_8937 25
63#define S5_P2_SHIFT_8937 14
64#define S6_P2_SHIFT_8937 26
65#define S7_P2_SHIFT_8937 6
66#define S8_P2_SHIFT_8937 18
67#define S9_P2_SHIFT_8937 6
68#define S10_P2_SHIFT_8937 18
69
70#define CAL_SEL_MASK_8937 0x00000007
71
72/* eeprom layout for 8909 */
73#define TSENS_EEPROM(n) ((n) + 0xa0)
74#define BASE0_MASK_8909 0x000000ff
75#define BASE1_MASK_8909 0x0000ff00
76
77#define S0_P1_MASK_8909 0x0000003f
78#define S1_P1_MASK_8909 0x0003f000
79#define S2_P1_MASK_8909 0x3f000000
80#define S3_P1_MASK_8909 0x000003f0
81#define S4_P1_MASK_8909 0x003f0000
82
83#define S0_P2_MASK_8909 0x00000fc0
84#define S1_P2_MASK_8909 0x00fc0000
85#define S2_P2_MASK_0_1_8909 0xc0000000
86#define S2_P2_MASK_2_5_8909 0x0000000f
87#define S3_P2_MASK_8909 0x0000fc00
88#define S4_P2_MASK_8909 0x0fc00000
89
90#define TSENS_CAL_SEL_8909 0x00070000
91#define CAL_SEL_SHIFT_8909 16
92#define BASE1_SHIFT_8909 8
93
94#define S1_P1_SHIFT_8909 12
95#define S2_P1_SHIFT_8909 24
96#define S3_P1_SHIFT_8909 4
97#define S4_P1_SHIFT_8909 16
98
99#define S0_P2_SHIFT_8909 6
100#define S1_P2_SHIFT_8909 18
101#define S2_P2_SHIFT_0_1_8909 30
102#define S2_P2_SHIFT_2_5_8909 2
103#define S3_P2_SHIFT_8909 10
104#define S4_P2_SHIFT_8909 22
105
106#define CAL_DEGC_PT1 30
107#define CAL_DEGC_PT2 120
108/*
109 * Use this function on devices where slope and offset calculations
110 * depend on calibration data read from qfprom. On others the slope
111 * and offset values are derived from tz->tzp->slope and tz->tzp->offset
112 * resp.
113 */
114static void compute_intercept_slope(struct tsens_device *tmdev, u32 *p1,
115 u32 *p2, u32 mode)
116{
117 int i;
118 int num, den;
119
120 for (i = 0; i < tmdev->ctrl_data->num_sensors; i++) {
121 pr_debug(
122 "sensor%d - data_point1:%#x data_point2:%#x\n",
123 i, p1[i], p2[i]);
124
125 tmdev->sensor[i].slope = SLOPE_DEFAULT;
126 if (mode == TWO_PT_CALIB) {
127 /*
128 * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
129 * temp_120_degc - temp_30_degc (x2 - x1)
130 */
131 num = p2[i] - p1[i];
132 num *= SLOPE_FACTOR;
133 den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
134 tmdev->sensor[i].slope = num / den;
135 }
136
137 tmdev->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
138 (CAL_DEGC_PT1 *
139 tmdev->sensor[i].slope);
140 pr_debug("offset:%d\n", tmdev->sensor[i].offset);
141 }
142}
143
144int calibrate_8937(struct tsens_device *tmdev)
145{
146 int base0 = 0, base1 = 0, i;
147 u32 p1[TSENS_NUM_SENSORS_8937], p2[TSENS_NUM_SENSORS_8937];
148 int mode = 0, tmp = 0;
149 u32 qfprom_cdata[5] = {0, 0, 0, 0, 0};
150
151 qfprom_cdata[0] = readl_relaxed(tmdev->tsens_calib_addr + 0x1D8);
152 qfprom_cdata[1] = readl_relaxed(tmdev->tsens_calib_addr + 0x1DC);
153 qfprom_cdata[2] = readl_relaxed(tmdev->tsens_calib_addr + 0x210);
154 qfprom_cdata[3] = readl_relaxed(tmdev->tsens_calib_addr + 0x214);
155 qfprom_cdata[4] = readl_relaxed(tmdev->tsens_calib_addr + 0x230);
156
157 mode = (qfprom_cdata[2] & CAL_SEL_MASK_8937);
158 pr_debug("calibration mode is %d\n", mode);
159
160 switch (mode) {
161 case TWO_PT_CALIB:
162 base1 = (qfprom_cdata[1] &
163 BASE1_MASK_8937) >> BASE1_SHIFT_8937;
164 p2[0] = (qfprom_cdata[2] &
165 S0_P2_MASK_8937) >> S0_P2_SHIFT_8937;
166 p2[1] = (qfprom_cdata[2] &
167 S1_P2_MASK_8937) >> S1_P2_SHIFT_8937;
168 p2[2] = (qfprom_cdata[3] &
169 S2_P2_MASK_8937) >> S2_P2_SHIFT_8937;
170 p2[3] = (qfprom_cdata[3] &
171 S3_P2_MASK_8937) >> S3_P2_SHIFT_8937;
172 p2[4] = (qfprom_cdata[3] &
173 S4_P2_MASK_8937) >> S4_P2_SHIFT_8937;
174 p2[5] = (qfprom_cdata[0] &
175 S5_P2_MASK_8937) >> S5_P2_SHIFT_8937;
176 p2[6] = (qfprom_cdata[0] &
177 S6_P2_MASK_8937) >> S6_P2_SHIFT_8937;
178 p2[7] = (qfprom_cdata[1] &
179 S7_P2_MASK_8937) >> S7_P2_SHIFT_8937;
180 p2[8] = (qfprom_cdata[1] &
181 S8_P2_MASK_8937) >> S8_P2_SHIFT_8937;
182 p2[9] = (qfprom_cdata[4] &
183 S9_P2_MASK_8937) >> S9_P2_SHIFT_8937;
184 p2[10] = (qfprom_cdata[4] &
185 S10_P2_MASK_8937) >> S10_P2_SHIFT_8937;
186
187 for (i = 0; i < TSENS_NUM_SENSORS_8937; i++)
188 p2[i] = ((base1 + p2[i]) << 2);
189 /* Fall through */
190 case ONE_PT_CALIB2:
191 base0 = (qfprom_cdata[0] & BASE0_MASK_8937);
192 p1[0] = (qfprom_cdata[2] &
193 S0_P1_MASK_8937) >> S0_P1_SHIFT_8937;
194 p1[1] = (qfprom_cdata[2] &
195 S1_P1_MASK_8937) >> S1_P1_SHIFT_8937;
196 p1[2] = (qfprom_cdata[2] &
197 S2_P1_MASK_0_4_8937) >> S2_P1_SHIFT_0_4_8937;
198 tmp = (qfprom_cdata[3] &
199 S2_P1_MASK_5_8937) << S2_P1_SHIFT_5_8937;
200 p1[2] |= tmp;
201 p1[3] = (qfprom_cdata[3] &
202 S3_P1_MASK_8937) >> S3_P1_SHIFT_8937;
203 p1[4] = (qfprom_cdata[3] &
204 S4_P1_MASK_8937) >> S4_P1_SHIFT_8937;
205 p1[5] = (qfprom_cdata[0] &
206 S5_P1_MASK_8937) >> S5_P1_SHIFT_8937;
207 p1[6] = (qfprom_cdata[0] &
208 S6_P1_MASK_8937) >> S6_P1_SHIFT_8937;
209 p1[7] = (qfprom_cdata[1] & S7_P1_MASK_8937);
210 p1[8] = (qfprom_cdata[1] &
211 S8_P1_MASK_8937) >> S8_P1_SHIFT_8937;
212 p1[9] = (qfprom_cdata[4] & S9_P1_MASK_8937);
213 p1[10] = (qfprom_cdata[4] &
214 S10_P1_MASK_8937) >> S10_P1_SHIFT_8937;
215
216 for (i = 0; i < TSENS_NUM_SENSORS_8937; i++)
217 p1[i] = (((base0) + p1[i]) << 2);
218 break;
219 default:
220 for (i = 0; i < TSENS_NUM_SENSORS_8937; i++) {
221 p1[i] = 500;
222 p2[i] = 780;
223 }
224 break;
225 }
226
227 compute_intercept_slope(tmdev, p1, p2, mode);
228
229 return 0;
230}
231
232int calibrate_8909(struct tsens_device *tmdev)
233{
234 int i, base0 = 0, base1 = 0;
235 u32 p1[TSENS_NUM_SENSORS_8909], p2[TSENS_NUM_SENSORS_8909];
236 int mode = 0, temp = 0;
237 uint32_t calib_data[3] = {0, 0, 0};
238
239 calib_data[0] = readl_relaxed(
240 TSENS_EEPROM(tmdev->tsens_calib_addr));
241 calib_data[1] = readl_relaxed(
242 (TSENS_EEPROM(tmdev->tsens_calib_addr) + 0x4));
243 calib_data[2] = readl_relaxed(
244 (TSENS_EEPROM(tmdev->tsens_calib_addr) + 0x3c));
245 mode = (calib_data[2] & TSENS_CAL_SEL_8909) >> CAL_SEL_SHIFT_8909;
246
247 pr_debug("calib mode is %d\n", mode);
248
249 switch (mode) {
250 case TWO_PT_CALIB:
251 base1 = (calib_data[2] & BASE1_MASK_8909) >> BASE1_SHIFT_8909;
252 p2[0] = (calib_data[0] & S0_P2_MASK_8909) >> S0_P2_SHIFT_8909;
253 p2[1] = (calib_data[0] & S1_P2_MASK_8909) >> S1_P2_SHIFT_8909;
254 p2[2] = (calib_data[0] &
255 S2_P2_MASK_0_1_8909) >> S2_P2_SHIFT_0_1_8909;
256 temp = (calib_data[1] &
257 S2_P2_MASK_2_5_8909) << S2_P2_SHIFT_2_5_8909;
258 p2[2] |= temp;
259 p2[3] = (calib_data[1] & S3_P2_MASK_8909) >> S3_P2_SHIFT_8909;
260 p2[4] = (calib_data[1] & S4_P2_MASK_8909) >> S4_P2_SHIFT_8909;
261
262 for (i = 0; i < TSENS_NUM_SENSORS_8909; i++)
263 p2[i] = ((base1 + p2[i]) << 2);
264 /* Fall through */
265 case ONE_PT_CALIB2:
266 base0 = (calib_data[2] & BASE0_MASK_8909);
267 p1[0] = (calib_data[0] & S0_P1_MASK_8909);
268 p1[1] = (calib_data[0] & S1_P1_MASK_8909) >> S1_P1_SHIFT_8909;
269 p1[2] = (calib_data[0] & S2_P1_MASK_8909) >> S2_P1_SHIFT_8909;
270 p1[3] = (calib_data[1] & S3_P1_MASK_8909) >> S3_P1_SHIFT_8909;
271 p1[4] = (calib_data[1] & S4_P1_MASK_8909) >> S4_P1_SHIFT_8909;
272 for (i = 0; i < TSENS_NUM_SENSORS_8909; i++)
273 p1[i] = (((base0) + p1[i]) << 2);
274 break;
275 default:
276 for (i = 0; i < TSENS_NUM_SENSORS_8909; i++) {
277 p1[i] = 500;
278 p2[i] = 780;
279 }
280 break;
281 }
282
283 compute_intercept_slope(tmdev, p1, p2, mode);
284 return 0;
285}