• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 and
6  * only version 2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  */
14 
15 #include <linux/platform_device.h>
16 #include "tsens.h"
17 
18 /* eeprom layout data for 8974 */
19 #define BASE1_MASK		0xff
20 #define S0_P1_MASK		0x3f00
21 #define S1_P1_MASK		0xfc000
22 #define S2_P1_MASK		0x3f00000
23 #define S3_P1_MASK		0xfc000000
24 #define S4_P1_MASK		0x3f
25 #define S5_P1_MASK		0xfc0
26 #define S6_P1_MASK		0x3f000
27 #define S7_P1_MASK		0xfc0000
28 #define S8_P1_MASK		0x3f000000
29 #define S8_P1_MASK_BKP		0x3f
30 #define S9_P1_MASK		0x3f
31 #define S9_P1_MASK_BKP		0xfc0
32 #define S10_P1_MASK		0xfc0
33 #define S10_P1_MASK_BKP		0x3f000
34 #define CAL_SEL_0_1		0xc0000000
35 #define CAL_SEL_2		0x40000000
36 #define CAL_SEL_SHIFT		30
37 #define CAL_SEL_SHIFT_2		28
38 
39 #define S0_P1_SHIFT		8
40 #define S1_P1_SHIFT		14
41 #define S2_P1_SHIFT		20
42 #define S3_P1_SHIFT		26
43 #define S5_P1_SHIFT		6
44 #define S6_P1_SHIFT		12
45 #define S7_P1_SHIFT		18
46 #define S8_P1_SHIFT		24
47 #define S9_P1_BKP_SHIFT		6
48 #define S10_P1_SHIFT		6
49 #define S10_P1_BKP_SHIFT	12
50 
51 #define BASE2_SHIFT		12
52 #define BASE2_BKP_SHIFT		18
53 #define S0_P2_SHIFT		20
54 #define S0_P2_BKP_SHIFT		26
55 #define S1_P2_SHIFT		26
56 #define S2_P2_BKP_SHIFT		6
57 #define S3_P2_SHIFT		6
58 #define S3_P2_BKP_SHIFT		12
59 #define S4_P2_SHIFT		12
60 #define S4_P2_BKP_SHIFT		18
61 #define S5_P2_SHIFT		18
62 #define S5_P2_BKP_SHIFT		24
63 #define S6_P2_SHIFT		24
64 #define S7_P2_BKP_SHIFT		6
65 #define S8_P2_SHIFT		6
66 #define S8_P2_BKP_SHIFT		12
67 #define S9_P2_SHIFT		12
68 #define S9_P2_BKP_SHIFT		18
69 #define S10_P2_SHIFT		18
70 #define S10_P2_BKP_SHIFT	24
71 
72 #define BASE2_MASK		0xff000
73 #define BASE2_BKP_MASK		0xfc0000
74 #define S0_P2_MASK		0x3f00000
75 #define S0_P2_BKP_MASK		0xfc000000
76 #define S1_P2_MASK		0xfc000000
77 #define S1_P2_BKP_MASK		0x3f
78 #define S2_P2_MASK		0x3f
79 #define S2_P2_BKP_MASK		0xfc0
80 #define S3_P2_MASK		0xfc0
81 #define S3_P2_BKP_MASK		0x3f000
82 #define S4_P2_MASK		0x3f000
83 #define S4_P2_BKP_MASK		0xfc0000
84 #define S5_P2_MASK		0xfc0000
85 #define S5_P2_BKP_MASK		0x3f000000
86 #define S6_P2_MASK		0x3f000000
87 #define S6_P2_BKP_MASK		0x3f
88 #define S7_P2_MASK		0x3f
89 #define S7_P2_BKP_MASK		0xfc0
90 #define S8_P2_MASK		0xfc0
91 #define S8_P2_BKP_MASK		0x3f000
92 #define S9_P2_MASK		0x3f000
93 #define S9_P2_BKP_MASK		0xfc0000
94 #define S10_P2_MASK		0xfc0000
95 #define S10_P2_BKP_MASK		0x3f000000
96 
97 #define BKP_SEL			0x3
98 #define BKP_REDUN_SEL		0xe0000000
99 #define BKP_REDUN_SHIFT		29
100 
101 #define BIT_APPEND		0x3
102 
calibrate_8974(struct tsens_device * tmdev)103 static int calibrate_8974(struct tsens_device *tmdev)
104 {
105 	int base1 = 0, base2 = 0, i;
106 	u32 p1[11], p2[11];
107 	int mode = 0;
108 	u32 *calib, *bkp;
109 	u32 calib_redun_sel;
110 
111 	calib = (u32 *)qfprom_read(tmdev->dev, "calib");
112 	if (IS_ERR(calib))
113 		return PTR_ERR(calib);
114 
115 	bkp = (u32 *)qfprom_read(tmdev->dev, "calib_backup");
116 	if (IS_ERR(bkp))
117 		return PTR_ERR(bkp);
118 
119 	calib_redun_sel =  bkp[1] & BKP_REDUN_SEL;
120 	calib_redun_sel >>= BKP_REDUN_SHIFT;
121 
122 	if (calib_redun_sel == BKP_SEL) {
123 		mode = (calib[4] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
124 		mode |= (calib[5] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
125 
126 		switch (mode) {
127 		case TWO_PT_CALIB:
128 			base2 = (bkp[2] & BASE2_BKP_MASK) >> BASE2_BKP_SHIFT;
129 			p2[0] = (bkp[2] & S0_P2_BKP_MASK) >> S0_P2_BKP_SHIFT;
130 			p2[1] = (bkp[3] & S1_P2_BKP_MASK);
131 			p2[2] = (bkp[3] & S2_P2_BKP_MASK) >> S2_P2_BKP_SHIFT;
132 			p2[3] = (bkp[3] & S3_P2_BKP_MASK) >> S3_P2_BKP_SHIFT;
133 			p2[4] = (bkp[3] & S4_P2_BKP_MASK) >> S4_P2_BKP_SHIFT;
134 			p2[5] = (calib[4] & S5_P2_BKP_MASK) >> S5_P2_BKP_SHIFT;
135 			p2[6] = (calib[5] & S6_P2_BKP_MASK);
136 			p2[7] = (calib[5] & S7_P2_BKP_MASK) >> S7_P2_BKP_SHIFT;
137 			p2[8] = (calib[5] & S8_P2_BKP_MASK) >> S8_P2_BKP_SHIFT;
138 			p2[9] = (calib[5] & S9_P2_BKP_MASK) >> S9_P2_BKP_SHIFT;
139 			p2[10] = (calib[5] & S10_P2_BKP_MASK) >> S10_P2_BKP_SHIFT;
140 			/* Fall through */
141 		case ONE_PT_CALIB:
142 		case ONE_PT_CALIB2:
143 			base1 = bkp[0] & BASE1_MASK;
144 			p1[0] = (bkp[0] & S0_P1_MASK) >> S0_P1_SHIFT;
145 			p1[1] = (bkp[0] & S1_P1_MASK) >> S1_P1_SHIFT;
146 			p1[2] = (bkp[0] & S2_P1_MASK) >> S2_P1_SHIFT;
147 			p1[3] = (bkp[0] & S3_P1_MASK) >> S3_P1_SHIFT;
148 			p1[4] = (bkp[1] & S4_P1_MASK);
149 			p1[5] = (bkp[1] & S5_P1_MASK) >> S5_P1_SHIFT;
150 			p1[6] = (bkp[1] & S6_P1_MASK) >> S6_P1_SHIFT;
151 			p1[7] = (bkp[1] & S7_P1_MASK) >> S7_P1_SHIFT;
152 			p1[8] = (bkp[2] & S8_P1_MASK_BKP) >> S8_P1_SHIFT;
153 			p1[9] = (bkp[2] & S9_P1_MASK_BKP) >> S9_P1_BKP_SHIFT;
154 			p1[10] = (bkp[2] & S10_P1_MASK_BKP) >> S10_P1_BKP_SHIFT;
155 			break;
156 		}
157 	} else {
158 		mode = (calib[1] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
159 		mode |= (calib[3] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
160 
161 		switch (mode) {
162 		case TWO_PT_CALIB:
163 			base2 = (calib[2] & BASE2_MASK) >> BASE2_SHIFT;
164 			p2[0] = (calib[2] & S0_P2_MASK) >> S0_P2_SHIFT;
165 			p2[1] = (calib[2] & S1_P2_MASK) >> S1_P2_SHIFT;
166 			p2[2] = (calib[3] & S2_P2_MASK);
167 			p2[3] = (calib[3] & S3_P2_MASK) >> S3_P2_SHIFT;
168 			p2[4] = (calib[3] & S4_P2_MASK) >> S4_P2_SHIFT;
169 			p2[5] = (calib[3] & S5_P2_MASK) >> S5_P2_SHIFT;
170 			p2[6] = (calib[3] & S6_P2_MASK) >> S6_P2_SHIFT;
171 			p2[7] = (calib[4] & S7_P2_MASK);
172 			p2[8] = (calib[4] & S8_P2_MASK) >> S8_P2_SHIFT;
173 			p2[9] = (calib[4] & S9_P2_MASK) >> S9_P2_SHIFT;
174 			p2[10] = (calib[4] & S10_P2_MASK) >> S10_P2_SHIFT;
175 			/* Fall through */
176 		case ONE_PT_CALIB:
177 		case ONE_PT_CALIB2:
178 			base1 = calib[0] & BASE1_MASK;
179 			p1[0] = (calib[0] & S0_P1_MASK) >> S0_P1_SHIFT;
180 			p1[1] = (calib[0] & S1_P1_MASK) >> S1_P1_SHIFT;
181 			p1[2] = (calib[0] & S2_P1_MASK) >> S2_P1_SHIFT;
182 			p1[3] = (calib[0] & S3_P1_MASK) >> S3_P1_SHIFT;
183 			p1[4] = (calib[1] & S4_P1_MASK);
184 			p1[5] = (calib[1] & S5_P1_MASK) >> S5_P1_SHIFT;
185 			p1[6] = (calib[1] & S6_P1_MASK) >> S6_P1_SHIFT;
186 			p1[7] = (calib[1] & S7_P1_MASK) >> S7_P1_SHIFT;
187 			p1[8] = (calib[1] & S8_P1_MASK) >> S8_P1_SHIFT;
188 			p1[9] = (calib[2] & S9_P1_MASK);
189 			p1[10] = (calib[2] & S10_P1_MASK) >> S10_P1_SHIFT;
190 			break;
191 		}
192 	}
193 
194 	switch (mode) {
195 	case ONE_PT_CALIB:
196 		for (i = 0; i < tmdev->num_sensors; i++)
197 			p1[i] += (base1 << 2) | BIT_APPEND;
198 		break;
199 	case TWO_PT_CALIB:
200 		for (i = 0; i < tmdev->num_sensors; i++) {
201 			p2[i] += base2;
202 			p2[i] <<= 2;
203 			p2[i] |= BIT_APPEND;
204 		}
205 		/* Fall through */
206 	case ONE_PT_CALIB2:
207 		for (i = 0; i < tmdev->num_sensors; i++) {
208 			p1[i] += base1;
209 			p1[i] <<= 2;
210 			p1[i] |= BIT_APPEND;
211 		}
212 		break;
213 	default:
214 		for (i = 0; i < tmdev->num_sensors; i++)
215 			p2[i] = 780;
216 		p1[0] = 502;
217 		p1[1] = 509;
218 		p1[2] = 503;
219 		p1[3] = 509;
220 		p1[4] = 505;
221 		p1[5] = 509;
222 		p1[6] = 507;
223 		p1[7] = 510;
224 		p1[8] = 508;
225 		p1[9] = 509;
226 		p1[10] = 508;
227 		break;
228 	}
229 
230 	compute_intercept_slope(tmdev, p1, p2, mode);
231 
232 	return 0;
233 }
234 
235 static const struct tsens_ops ops_8974 = {
236 	.init		= init_common,
237 	.calibrate	= calibrate_8974,
238 	.get_temp	= get_temp_common,
239 };
240 
241 const struct tsens_data data_8974 = {
242 	.num_sensors	= 11,
243 	.ops		= &ops_8974,
244 };
245