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_priv *priv) 60 { 61 int ret; 62 unsigned int mask; 63 struct regmap *map = priv->tm_map; 64 65 ret = regmap_read(map, THRESHOLD_ADDR, &priv->ctx.threshold); 66 if (ret) 67 return ret; 68 69 ret = regmap_read(map, CNTL_ADDR, &priv->ctx.control); 70 if (ret) 71 return ret; 72 73 if (priv->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_priv *priv) 86 { 87 int ret; 88 struct regmap *map = priv->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 (priv->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, priv->ctx.threshold); 105 if (ret) 106 return ret; 107 108 ret = regmap_write(map, CNTL_ADDR, priv->ctx.control); 109 if (ret) 110 return ret; 111 112 return 0; 113 } 114 115 static int enable_8960(struct tsens_priv *priv, int id) 116 { 117 int ret; 118 u32 reg, mask; 119 120 ret = regmap_read(priv->tm_map, CNTL_ADDR, ®); 121 if (ret) 122 return ret; 123 124 mask = BIT(id + SENSOR0_SHIFT); 125 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST); 126 if (ret) 127 return ret; 128 129 if (priv->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(priv->tm_map, CNTL_ADDR, reg); 135 if (ret) 136 return ret; 137 138 return 0; 139 } 140 141 static void disable_8960(struct tsens_priv *priv) 142 { 143 int ret; 144 u32 reg_cntl; 145 u32 mask; 146 147 mask = GENMASK(priv->num_sensors - 1, 0); 148 mask <<= SENSOR0_SHIFT; 149 mask |= EN; 150 151 ret = regmap_read(priv->tm_map, CNTL_ADDR, ®_cntl); 152 if (ret) 153 return; 154 155 reg_cntl &= ~mask; 156 157 if (priv->num_sensors > 1) 158 reg_cntl &= ~SLP_CLK_ENA; 159 else 160 reg_cntl &= ~SLP_CLK_ENA_8660; 161 162 regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); 163 } 164 165 static int init_8960(struct tsens_priv *priv) 166 { 167 int ret, i; 168 u32 reg_cntl; 169 170 priv->tm_map = dev_get_regmap(priv->dev, NULL); 171 if (!priv->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 < priv->num_sensors; i++) { 181 if (i >= 5) 182 priv->sensor[i].status = S0_STATUS_ADDR + 40; 183 priv->sensor[i].status += i * 4; 184 } 185 186 reg_cntl = SW_RST; 187 ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl); 188 if (ret) 189 return ret; 190 191 if (priv->num_sensors > 1) { 192 reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18); 193 reg_cntl &= ~SW_RST; 194 ret = regmap_update_bits(priv->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(priv->num_sensors - 1, 0) << SENSOR0_SHIFT; 203 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); 204 if (ret) 205 return ret; 206 207 reg_cntl |= EN; 208 ret = regmap_write(priv->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_priv *priv) 216 { 217 int i; 218 char *data; 219 220 ssize_t num_read = priv->num_sensors; 221 struct tsens_sensor *s = priv->sensor; 222 223 data = qfprom_read(priv->dev, "calib"); 224 if (IS_ERR(data)) 225 data = qfprom_read(priv->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 kfree(data); 233 234 return 0; 235 } 236 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) 239 { 240 int slope, offset; 241 242 slope = thermal_zone_get_slope(s->tzd); 243 offset = CAL_MDEGC - slope * s->offset; 244 245 return adc_code * slope + offset; 246 } 247 248 static int get_temp_8960(const struct tsens_sensor *s, int *temp) 249 { 250 int ret; 251 u32 code, trdy; 252 struct tsens_priv *priv = s->priv; 253 unsigned long timeout; 254 255 timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); 256 do { 257 ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy); 258 if (ret) 259 return ret; 260 if (!(trdy & TRDY_MASK)) 261 continue; 262 ret = regmap_read(priv->tm_map, s->status, &code); 263 if (ret) 264 return ret; 265 *temp = code_to_mdegC(code, s); 266 return 0; 267 } while (time_before(jiffies, timeout)); 268 269 return -ETIMEDOUT; 270 } 271 272 static const struct tsens_ops ops_8960 = { 273 .init = init_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, 280 }; 281 282 struct tsens_plat_data data_8960 = { 283 .num_sensors = 11, 284 .ops = &ops_8960, 285 }; 286