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, ®); 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, ®_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 }; 293