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