2 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
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.
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.
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>
22 #define CAL_MDEGC 30000
24 #define CONFIG_ADDR 0x3640
25 #define CONFIG_ADDR_8660 0x3620
26 /* CONFIG_ADDR bitmasks */
28 #define CONFIG_MASK 0xf
30 #define CONFIG_SHIFT_8660 28
31 #define CONFIG_MASK_8660 (3 << CONFIG_SHIFT_8660)
33 #define STATUS_CNTL_ADDR_8064 0x3660
34 #define CNTL_ADDR 0x3620
35 /* CNTL_ADDR bitmasks */
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
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)
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
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
63 #define S0_STATUS_ADDR 0x3628
64 #define INT_STATUS_ADDR 0x363c
65 #define TRDY_MASK BIT(7)
66 #define TIMEOUT_US 100
68 static int suspend_8960(struct tsens_device
*tmdev
)
72 struct regmap
*map
= tmdev
->map
;
74 ret
= regmap_read(map
, THRESHOLD_ADDR
, &tmdev
->ctx
.threshold
);
78 ret
= regmap_read(map
, CNTL_ADDR
, &tmdev
->ctx
.control
);
82 if (tmdev
->num_sensors
> 1)
83 mask
= SLP_CLK_ENA
| EN
;
85 mask
= SLP_CLK_ENA_8660
| EN
;
87 ret
= regmap_update_bits(map
, CNTL_ADDR
, mask
, 0);
94 static int resume_8960(struct tsens_device
*tmdev
)
97 struct regmap
*map
= tmdev
->map
;
99 ret
= regmap_update_bits(map
, CNTL_ADDR
, SW_RST
, SW_RST
);
104 * Separate CONFIG restore is not needed only for 8660 as
105 * config is part of CTRL Addr and its restored as such
107 if (tmdev
->num_sensors
> 1) {
108 ret
= regmap_update_bits(map
, CONFIG_ADDR
, CONFIG_MASK
, CONFIG
);
113 ret
= regmap_write(map
, THRESHOLD_ADDR
, tmdev
->ctx
.threshold
);
117 ret
= regmap_write(map
, CNTL_ADDR
, tmdev
->ctx
.control
);
124 static int enable_8960(struct tsens_device
*tmdev
, int id
)
129 ret
= regmap_read(tmdev
->map
, CNTL_ADDR
, ®
);
133 mask
= BIT(id
+ SENSOR0_SHIFT
);
134 ret
= regmap_write(tmdev
->map
, CNTL_ADDR
, reg
| SW_RST
);
138 if (tmdev
->num_sensors
> 1)
139 reg
|= mask
| SLP_CLK_ENA
| EN
;
141 reg
|= mask
| SLP_CLK_ENA_8660
| EN
;
143 ret
= regmap_write(tmdev
->map
, CNTL_ADDR
, reg
);
150 static void disable_8960(struct tsens_device
*tmdev
)
156 mask
= GENMASK(tmdev
->num_sensors
- 1, 0);
157 mask
<<= SENSOR0_SHIFT
;
160 ret
= regmap_read(tmdev
->map
, CNTL_ADDR
, ®_cntl
);
166 if (tmdev
->num_sensors
> 1)
167 reg_cntl
&= ~SLP_CLK_ENA
;
169 reg_cntl
&= ~SLP_CLK_ENA_8660
;
171 regmap_write(tmdev
->map
, CNTL_ADDR
, reg_cntl
);
174 static int init_8960(struct tsens_device
*tmdev
)
179 tmdev
->map
= dev_get_regmap(tmdev
->dev
, NULL
);
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.
189 for (i
= 0; i
< tmdev
->num_sensors
; i
++) {
191 tmdev
->sensor
[i
].status
= S0_STATUS_ADDR
+ 40;
192 tmdev
->sensor
[i
].status
+= i
* 4;
196 ret
= regmap_update_bits(tmdev
->map
, CNTL_ADDR
, SW_RST
, reg_cntl
);
200 if (tmdev
->num_sensors
> 1) {
201 reg_cntl
|= SLP_CLK_ENA
| (MEASURE_PERIOD
<< 18);
203 ret
= regmap_update_bits(tmdev
->map
, CONFIG_ADDR
,
204 CONFIG_MASK
, CONFIG
);
206 reg_cntl
|= SLP_CLK_ENA_8660
| (MEASURE_PERIOD
<< 16);
207 reg_cntl
&= ~CONFIG_MASK_8660
;
208 reg_cntl
|= CONFIG_8660
<< CONFIG_SHIFT_8660
;
211 reg_cntl
|= GENMASK(tmdev
->num_sensors
- 1, 0) << SENSOR0_SHIFT
;
212 ret
= regmap_write(tmdev
->map
, CNTL_ADDR
, reg_cntl
);
217 ret
= regmap_write(tmdev
->map
, CNTL_ADDR
, reg_cntl
);
224 static int calibrate_8960(struct tsens_device
*tmdev
)
229 ssize_t num_read
= tmdev
->num_sensors
;
230 struct tsens_sensor
*s
= tmdev
->sensor
;
232 data
= qfprom_read(tmdev
->dev
, "calib");
234 data
= qfprom_read(tmdev
->dev
, "calib_backup");
236 return PTR_ERR(data
);
238 for (i
= 0; i
< num_read
; i
++, s
++)
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
)
249 slope
= thermal_zone_get_slope(s
->tzd
);
250 offset
= CAL_MDEGC
- slope
* s
->offset
;
252 return adc_code
* slope
+ offset
;
255 static int get_temp_8960(struct tsens_device
*tmdev
, int id
, int *temp
)
259 const struct tsens_sensor
*s
= &tmdev
->sensor
[id
];
260 unsigned long timeout
;
262 timeout
= jiffies
+ usecs_to_jiffies(TIMEOUT_US
);
264 ret
= regmap_read(tmdev
->map
, INT_STATUS_ADDR
, &trdy
);
267 if (!(trdy
& TRDY_MASK
))
269 ret
= regmap_read(tmdev
->map
, s
->status
, &code
);
272 *temp
= code_to_mdegC(code
, s
);
274 } while (time_before(jiffies
, timeout
));
279 static const struct tsens_ops ops_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
,
289 const struct tsens_data data_8960
= {