aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@codeaurora.org>2016-05-05 04:51:41 -0400
committerZhang Rui <rui.zhang@intel.com>2016-09-27 02:02:16 -0400
commit5e6703bd2d83548998848865cb9a9a795f31a311 (patch)
tree4e2e27016d27464e69c2c9da0ec1315a0eb30b22
parent840a5bd3ed3fdd62456d4d26c3128ec10496555b (diff)
thermal: qcom: tsens-8974: Add support for 8974 family of SoCs
Add .calibrate support for 8974 family as part of tsens_ops. Based on the original code by Siddartha Mohanadoss and Stephen Boyd. Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Eduardo Valentin <edubezval@gmail.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
-rw-r--r--drivers/thermal/qcom/Makefile2
-rw-r--r--drivers/thermal/qcom/tsens-8974.c244
-rw-r--r--drivers/thermal/qcom/tsens.c1
-rw-r--r--drivers/thermal/qcom/tsens.h2
4 files changed, 247 insertions, 2 deletions
diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
index 05c98e4b73a3..a471100ac5f6 100644
--- a/drivers/thermal/qcom/Makefile
+++ b/drivers/thermal/qcom/Makefile
@@ -1,2 +1,2 @@
1obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o 1obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
2qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o 2qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o
diff --git a/drivers/thermal/qcom/tsens-8974.c b/drivers/thermal/qcom/tsens-8974.c
new file mode 100644
index 000000000000..da3ca4c18999
--- /dev/null
+++ b/drivers/thermal/qcom/tsens-8974.c
@@ -0,0 +1,244 @@
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
103static 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
235const struct tsens_ops ops_8974 = {
236 .init = init_common,
237 .calibrate = calibrate_8974,
238 .get_temp = get_temp_common,
239};
240
241const struct tsens_data data_8974 = {
242 .num_sensors = 11,
243 .ops = &ops_8974,
244};
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 7f3dfa1d6757..5f206e3c9198 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -68,6 +68,7 @@ static const struct of_device_id tsens_table[] = {
68 .data = &data_8916, 68 .data = &data_8916,
69 }, { 69 }, {
70 .compatible = "qcom,msm8974-tsens", 70 .compatible = "qcom,msm8974-tsens",
71 .data = &data_8974,
71 }, 72 },
72 {} 73 {}
73}; 74};
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index e767ad566340..8ab99971a1a7 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -87,6 +87,6 @@ void compute_intercept_slope(struct tsens_device *, u32 *, u32 *, u32);
87int init_common(struct tsens_device *); 87int init_common(struct tsens_device *);
88int get_temp_common(struct tsens_device *, int, int *); 88int get_temp_common(struct tsens_device *, int, int *);
89 89
90extern const struct tsens_data data_8916; 90extern const struct tsens_data data_8916, data_8974;
91 91
92#endif /* __QCOM_TSENS_H__ */ 92#endif /* __QCOM_TSENS_H__ */