1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4  */
5 
6 #include <linux/platform_device.h>
7 #include <linux/delay.h>
8 #include <linux/bitops.h>
9 #include <linux/regmap.h>
10 #include <linux/thermal.h>
11 #include "tsens.h"
12 
13 #define CAL_MDEGC		30000
14 
15 #define CONFIG_ADDR		0x3640
16 #define CONFIG_ADDR_8660	0x3620
17 /* CONFIG_ADDR bitmasks */
18 #define CONFIG			0x9b
19 #define CONFIG_MASK		0xf
20 #define CONFIG_8660		1
21 #define CONFIG_SHIFT_8660	28
22 #define CONFIG_MASK_8660	(3 << CONFIG_SHIFT_8660)
23 
24 #define STATUS_CNTL_ADDR_8064	0x3660
25 #define CNTL_ADDR		0x3620
26 /* CNTL_ADDR bitmasks */
27 #define EN			BIT(0)
28 #define SW_RST			BIT(1)
29 #define SENSOR0_EN		BIT(3)
30 #define SLP_CLK_ENA		BIT(26)
31 #define SLP_CLK_ENA_8660	BIT(24)
32 #define MEASURE_PERIOD		1
33 #define SENSOR0_SHIFT		3
34 
35 /* INT_STATUS_ADDR bitmasks */
36 #define MIN_STATUS_MASK		BIT(0)
37 #define LOWER_STATUS_CLR	BIT(1)
38 #define UPPER_STATUS_CLR	BIT(2)
39 #define MAX_STATUS_MASK		BIT(3)
40 
41 #define THRESHOLD_ADDR		0x3624
42 /* THRESHOLD_ADDR bitmasks */
43 #define THRESHOLD_MAX_LIMIT_SHIFT	24
44 #define THRESHOLD_MIN_LIMIT_SHIFT	16
45 #define THRESHOLD_UPPER_LIMIT_SHIFT	8
46 #define THRESHOLD_LOWER_LIMIT_SHIFT	0
47 
48 /* Initial temperature threshold values */
49 #define LOWER_LIMIT_TH		0x50
50 #define UPPER_LIMIT_TH		0xdf
51 #define MIN_LIMIT_TH		0x0
52 #define MAX_LIMIT_TH		0xff
53 
54 #define S0_STATUS_ADDR		0x3628
55 #define INT_STATUS_ADDR		0x363c
56 #define TRDY_MASK		BIT(7)
57 #define TIMEOUT_US		100
58 
59 static int suspend_8960(struct tsens_device *tmdev)
60 {
61 	int ret;
62 	unsigned int mask;
63 	struct regmap *map = tmdev->tm_map;
64 
65 	ret = regmap_read(map, THRESHOLD_ADDR, &tmdev->ctx.threshold);
66 	if (ret)
67 		return ret;
68 
69 	ret = regmap_read(map, CNTL_ADDR, &tmdev->ctx.control);
70 	if (ret)
71 		return ret;
72 
73 	if (tmdev->num_sensors > 1)
74 		mask = SLP_CLK_ENA | EN;
75 	else
76 		mask = SLP_CLK_ENA_8660 | EN;
77 
78 	ret = regmap_update_bits(map, CNTL_ADDR, mask, 0);
79 	if (ret)
80 		return ret;
81 
82 	return 0;
83 }
84 
85 static int resume_8960(struct tsens_device *tmdev)
86 {
87 	int ret;
88 	struct regmap *map = tmdev->tm_map;
89 
90 	ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
91 	if (ret)
92 		return ret;
93 
94 	/*
95 	 * Separate CONFIG restore is not needed only for 8660 as
96 	 * config is part of CTRL Addr and its restored as such
97 	 */
98 	if (tmdev->num_sensors > 1) {
99 		ret = regmap_update_bits(map, CONFIG_ADDR, CONFIG_MASK, CONFIG);
100 		if (ret)
101 			return ret;
102 	}
103 
104 	ret = regmap_write(map, THRESHOLD_ADDR, tmdev->ctx.threshold);
105 	if (ret)
106 		return ret;
107 
108 	ret = regmap_write(map, CNTL_ADDR, tmdev->ctx.control);
109 	if (ret)
110 		return ret;
111 
112 	return 0;
113 }
114 
115 static int enable_8960(struct tsens_device *tmdev, int id)
116 {
117 	int ret;
118 	u32 reg, mask;
119 
120 	ret = regmap_read(tmdev->tm_map, CNTL_ADDR, &reg);
121 	if (ret)
122 		return ret;
123 
124 	mask = BIT(id + SENSOR0_SHIFT);
125 	ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg | SW_RST);
126 	if (ret)
127 		return ret;
128 
129 	if (tmdev->num_sensors > 1)
130 		reg |= mask | SLP_CLK_ENA | EN;
131 	else
132 		reg |= mask | SLP_CLK_ENA_8660 | EN;
133 
134 	ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg);
135 	if (ret)
136 		return ret;
137 
138 	return 0;
139 }
140 
141 static void disable_8960(struct tsens_device *tmdev)
142 {
143 	int ret;
144 	u32 reg_cntl;
145 	u32 mask;
146 
147 	mask = GENMASK(tmdev->num_sensors - 1, 0);
148 	mask <<= SENSOR0_SHIFT;
149 	mask |= EN;
150 
151 	ret = regmap_read(tmdev->tm_map, CNTL_ADDR, &reg_cntl);
152 	if (ret)
153 		return;
154 
155 	reg_cntl &= ~mask;
156 
157 	if (tmdev->num_sensors > 1)
158 		reg_cntl &= ~SLP_CLK_ENA;
159 	else
160 		reg_cntl &= ~SLP_CLK_ENA_8660;
161 
162 	regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl);
163 }
164 
165 static int init_8960(struct tsens_device *tmdev)
166 {
167 	int ret, i;
168 	u32 reg_cntl;
169 
170 	tmdev->tm_map = dev_get_regmap(tmdev->dev, NULL);
171 	if (!tmdev->tm_map)
172 		return -ENODEV;
173 
174 	/*
175 	 * The status registers for each sensor are discontiguous
176 	 * because some SoCs have 5 sensors while others have more
177 	 * but the control registers stay in the same place, i.e
178 	 * directly after the first 5 status registers.
179 	 */
180 	for (i = 0; i < tmdev->num_sensors; i++) {
181 		if (i >= 5)
182 			tmdev->sensor[i].status = S0_STATUS_ADDR + 40;
183 		tmdev->sensor[i].status += i * 4;
184 	}
185 
186 	reg_cntl = SW_RST;
187 	ret = regmap_update_bits(tmdev->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
188 	if (ret)
189 		return ret;
190 
191 	if (tmdev->num_sensors > 1) {
192 		reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
193 		reg_cntl &= ~SW_RST;
194 		ret = regmap_update_bits(tmdev->tm_map, CONFIG_ADDR,
195 					 CONFIG_MASK, CONFIG);
196 	} else {
197 		reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16);
198 		reg_cntl &= ~CONFIG_MASK_8660;
199 		reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660;
200 	}
201 
202 	reg_cntl |= GENMASK(tmdev->num_sensors - 1, 0) << SENSOR0_SHIFT;
203 	ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl);
204 	if (ret)
205 		return ret;
206 
207 	reg_cntl |= EN;
208 	ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl);
209 	if (ret)
210 		return ret;
211 
212 	return 0;
213 }
214 
215 static int calibrate_8960(struct tsens_device *tmdev)
216 {
217 	int i;
218 	char *data;
219 
220 	ssize_t num_read = tmdev->num_sensors;
221 	struct tsens_sensor *s = tmdev->sensor;
222 
223 	data = qfprom_read(tmdev->dev, "calib");
224 	if (IS_ERR(data))
225 		data = qfprom_read(tmdev->dev, "calib_backup");
226 	if (IS_ERR(data))
227 		return PTR_ERR(data);
228 
229 	for (i = 0; i < num_read; i++, s++)
230 		s->offset = data[i];
231 
232 	return 0;
233 }
234 
235 /* Temperature on y axis and ADC-code on x-axis */
236 static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
237 {
238 	int slope, offset;
239 
240 	slope = thermal_zone_get_slope(s->tzd);
241 	offset = CAL_MDEGC - slope * s->offset;
242 
243 	return adc_code * slope + offset;
244 }
245 
246 static int get_temp_8960(struct tsens_device *tmdev, int id, int *temp)
247 {
248 	int ret;
249 	u32 code, trdy;
250 	const struct tsens_sensor *s = &tmdev->sensor[id];
251 	unsigned long timeout;
252 
253 	timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
254 	do {
255 		ret = regmap_read(tmdev->tm_map, INT_STATUS_ADDR, &trdy);
256 		if (ret)
257 			return ret;
258 		if (!(trdy & TRDY_MASK))
259 			continue;
260 		ret = regmap_read(tmdev->tm_map, s->status, &code);
261 		if (ret)
262 			return ret;
263 		*temp = code_to_mdegC(code, s);
264 		return 0;
265 	} while (time_before(jiffies, timeout));
266 
267 	return -ETIMEDOUT;
268 }
269 
270 static const struct tsens_ops ops_8960 = {
271 	.init		= init_8960,
272 	.calibrate	= calibrate_8960,
273 	.get_temp	= get_temp_8960,
274 	.enable		= enable_8960,
275 	.disable	= disable_8960,
276 	.suspend	= suspend_8960,
277 	.resume		= resume_8960,
278 };
279 
280 const struct tsens_data data_8960 = {
281 	.num_sensors	= 11,
282 	.ops		= &ops_8960,
283 };
284