1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
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>
13 #define CAL_MDEGC 30000
15 #define CONFIG_ADDR 0x3640
16 #define CONFIG_ADDR_8660 0x3620
17 /* CONFIG_ADDR bitmasks */
19 #define CONFIG_MASK 0xf
21 #define CONFIG_SHIFT_8660 28
22 #define CONFIG_MASK_8660 (3 << CONFIG_SHIFT_8660)
24 #define STATUS_CNTL_ADDR_8064 0x3660
25 #define CNTL_ADDR 0x3620
26 /* CNTL_ADDR bitmasks */
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
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)
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
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
54 #define S0_STATUS_ADDR 0x3628
55 #define INT_STATUS_ADDR 0x363c
56 #define TRDY_MASK BIT(7)
57 #define TIMEOUT_US 100
59 static int suspend_8960(struct tsens_priv
*priv
)
63 struct regmap
*map
= priv
->tm_map
;
65 ret
= regmap_read(map
, THRESHOLD_ADDR
, &priv
->ctx
.threshold
);
69 ret
= regmap_read(map
, CNTL_ADDR
, &priv
->ctx
.control
);
73 if (priv
->num_sensors
> 1)
74 mask
= SLP_CLK_ENA
| EN
;
76 mask
= SLP_CLK_ENA_8660
| EN
;
78 ret
= regmap_update_bits(map
, CNTL_ADDR
, mask
, 0);
85 static int resume_8960(struct tsens_priv
*priv
)
88 struct regmap
*map
= priv
->tm_map
;
90 ret
= regmap_update_bits(map
, CNTL_ADDR
, SW_RST
, SW_RST
);
95 * Separate CONFIG restore is not needed only for 8660 as
96 * config is part of CTRL Addr and its restored as such
98 if (priv
->num_sensors
> 1) {
99 ret
= regmap_update_bits(map
, CONFIG_ADDR
, CONFIG_MASK
, CONFIG
);
104 ret
= regmap_write(map
, THRESHOLD_ADDR
, priv
->ctx
.threshold
);
108 ret
= regmap_write(map
, CNTL_ADDR
, priv
->ctx
.control
);
115 static int enable_8960(struct tsens_priv
*priv
, int id
)
120 ret
= regmap_read(priv
->tm_map
, CNTL_ADDR
, ®
);
124 mask
= BIT(id
+ SENSOR0_SHIFT
);
125 ret
= regmap_write(priv
->tm_map
, CNTL_ADDR
, reg
| SW_RST
);
129 if (priv
->num_sensors
> 1)
130 reg
|= mask
| SLP_CLK_ENA
| EN
;
132 reg
|= mask
| SLP_CLK_ENA_8660
| EN
;
134 ret
= regmap_write(priv
->tm_map
, CNTL_ADDR
, reg
);
141 static void disable_8960(struct tsens_priv
*priv
)
147 mask
= GENMASK(priv
->num_sensors
- 1, 0);
148 mask
<<= SENSOR0_SHIFT
;
151 ret
= regmap_read(priv
->tm_map
, CNTL_ADDR
, ®_cntl
);
157 if (priv
->num_sensors
> 1)
158 reg_cntl
&= ~SLP_CLK_ENA
;
160 reg_cntl
&= ~SLP_CLK_ENA_8660
;
162 regmap_write(priv
->tm_map
, CNTL_ADDR
, reg_cntl
);
165 static int init_8960(struct tsens_priv
*priv
)
170 priv
->tm_map
= dev_get_regmap(priv
->dev
, NULL
);
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.
180 for (i
= 0; i
< priv
->num_sensors
; i
++) {
182 priv
->sensor
[i
].status
= S0_STATUS_ADDR
+ 40;
183 priv
->sensor
[i
].status
+= i
* 4;
187 ret
= regmap_update_bits(priv
->tm_map
, CNTL_ADDR
, SW_RST
, reg_cntl
);
191 if (priv
->num_sensors
> 1) {
192 reg_cntl
|= SLP_CLK_ENA
| (MEASURE_PERIOD
<< 18);
194 ret
= regmap_update_bits(priv
->tm_map
, CONFIG_ADDR
,
195 CONFIG_MASK
, CONFIG
);
197 reg_cntl
|= SLP_CLK_ENA_8660
| (MEASURE_PERIOD
<< 16);
198 reg_cntl
&= ~CONFIG_MASK_8660
;
199 reg_cntl
|= CONFIG_8660
<< CONFIG_SHIFT_8660
;
202 reg_cntl
|= GENMASK(priv
->num_sensors
- 1, 0) << SENSOR0_SHIFT
;
203 ret
= regmap_write(priv
->tm_map
, CNTL_ADDR
, reg_cntl
);
208 ret
= regmap_write(priv
->tm_map
, CNTL_ADDR
, reg_cntl
);
215 static int calibrate_8960(struct tsens_priv
*priv
)
220 ssize_t num_read
= priv
->num_sensors
;
221 struct tsens_sensor
*s
= priv
->sensor
;
223 data
= qfprom_read(priv
->dev
, "calib");
225 data
= qfprom_read(priv
->dev
, "calib_backup");
227 return PTR_ERR(data
);
229 for (i
= 0; i
< num_read
; i
++, s
++)
237 /* Temperature on y axis and ADC-code on x-axis */
238 static inline int code_to_mdegC(u32 adc_code
, const struct tsens_sensor
*s
)
242 slope
= thermal_zone_get_slope(s
->tzd
);
243 offset
= CAL_MDEGC
- slope
* s
->offset
;
245 return adc_code
* slope
+ offset
;
248 static int get_temp_8960(struct tsens_sensor
*s
, int *temp
)
252 struct tsens_priv
*priv
= s
->priv
;
253 unsigned long timeout
;
255 timeout
= jiffies
+ usecs_to_jiffies(TIMEOUT_US
);
257 ret
= regmap_read(priv
->tm_map
, INT_STATUS_ADDR
, &trdy
);
260 if (!(trdy
& TRDY_MASK
))
262 ret
= regmap_read(priv
->tm_map
, s
->status
, &code
);
265 *temp
= code_to_mdegC(code
, s
);
267 } while (time_before(jiffies
, timeout
));
272 static const struct tsens_ops ops_8960
= {
274 .calibrate
= calibrate_8960
,
275 .get_temp
= get_temp_8960
,
276 .enable
= enable_8960
,
277 .disable
= disable_8960
,
278 .suspend
= suspend_8960
,
279 .resume
= resume_8960
,
282 const struct tsens_plat_data data_8960
= {