Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux...
[muen/linux.git] / drivers / thermal / qcom / tsens-8960.c
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
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
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
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
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
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
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 */
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
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 };