1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Author: Lars Randers <lranders@mail.dk> 4 */ 5 6 #include <linux/bitfield.h> 7 #include <linux/err.h> 8 #include <linux/freezer.h> 9 #include <linux/hwmon.h> 10 #include <linux/io.h> 11 #include <linux/kthread.h> 12 #include <linux/math.h> 13 #include <linux/mfd/syscon.h> 14 #include <linux/minmax.h> 15 #include <linux/module.h> 16 #include <linux/of_address.h> 17 #include <linux/platform_device.h> 18 #include <linux/regmap.h> 19 20 #define MPFS_TVS_CTRL 0x08 21 #define MPFS_TVS_OUTPUT0 0x24 22 #define MPFS_TVS_OUTPUT1 0x28 23 24 #define MPFS_TVS_CTRL_TEMP_VALID BIT(19) 25 #define MPFS_TVS_CTRL_V2P5_VALID BIT(18) 26 #define MPFS_TVS_CTRL_V1P8_VALID BIT(17) 27 #define MPFS_TVS_CTRL_V1P05_VALID BIT(16) 28 29 #define MPFS_TVS_CTRL_TEMP_ENABLE BIT(3) 30 #define MPFS_TVS_CTRL_V2P5_ENABLE BIT(2) 31 #define MPFS_TVS_CTRL_V1P8_ENABLE BIT(1) 32 #define MPFS_TVS_CTRL_V1P05_ENABLE BIT(0) 33 #define MPFS_TVS_CTRL_ENABLE_ALL GENMASK(3, 0) 34 35 /* 36 * For all of these the value in millivolts is stored in 16 bits, with an upper 37 * sign bit and a lower 3 bits of decimal. These masks discard the sign bit and 38 * decimal places, because if Linux is running these voltages cannot be negative 39 * and so avoid having to convert to two's complement. 40 */ 41 #define MPFS_OUTPUT0_V1P8_MASK GENMASK(30, 19) 42 #define MPFS_OUTPUT0_V1P05_MASK GENMASK(14, 3) 43 #define MPFS_OUTPUT1_V2P5_MASK GENMASK(14, 3) 44 45 /* 46 * The register map claims that the temperature is stored in bits 31:16, but 47 * application note "AN4682: PolarFire FPGA Temperature and Voltage Sensor" 48 * says that 31 is reserved. Temperature is in kelvin, so what's probably a 49 * sign bit has no value anyway. 50 */ 51 #define MPFS_OUTPUT1_TEMP_MASK GENMASK(30, 16) 52 53 #define MPFS_TVS_INTERVAL_MASK GENMASK(15, 8) 54 #define MPFS_TVS_INTERVAL_OFFSET 8 55 /* The interval register is in increments of 32 us */ 56 #define MPFS_TVS_INTERVAL_SCALE 32 57 /* with 254 usable increments of 32 us available, 8 ms is the integer limit */ 58 #define MPFS_TVS_INTERVAL_MAX_MS 8 59 60 /* 273.1875 in 11.4 fixed-point notation */ 61 #define MPFS_TVS_K_TO_C 0x1113 62 63 enum mpfs_tvs_sensors { 64 SENSOR_V1P05 = 0, 65 SENSOR_V1P8, 66 SENSOR_V2P5, 67 }; 68 69 static const char * const mpfs_tvs_voltage_labels[] = { "1P05", "1P8", "2P5" }; 70 71 struct mpfs_tvs { 72 struct regmap *regmap; 73 }; 74 75 static int mpfs_tvs_voltage_read(struct mpfs_tvs *data, u32 attr, 76 int channel, long *val) 77 { 78 u32 tmp, control; 79 80 if (attr != hwmon_in_input && attr != hwmon_in_enable) 81 return -EOPNOTSUPP; 82 83 regmap_read(data->regmap, MPFS_TVS_CTRL, &control); 84 85 switch (channel) { 86 case SENSOR_V2P5: 87 if (attr == hwmon_in_enable) { 88 *val = FIELD_GET(MPFS_TVS_CTRL_V2P5_ENABLE, control); 89 break; 90 } 91 92 if (!(control & MPFS_TVS_CTRL_V2P5_VALID)) 93 return -ENODATA; 94 95 regmap_read(data->regmap, MPFS_TVS_OUTPUT1, &tmp); 96 *val = FIELD_GET(MPFS_OUTPUT1_V2P5_MASK, tmp); 97 break; 98 case SENSOR_V1P8: 99 if (attr == hwmon_in_enable) { 100 *val = FIELD_GET(MPFS_TVS_CTRL_V1P8_ENABLE, control); 101 break; 102 } 103 104 if (!(control & MPFS_TVS_CTRL_V1P8_VALID)) 105 return -ENODATA; 106 107 regmap_read(data->regmap, MPFS_TVS_OUTPUT0, &tmp); 108 *val = FIELD_GET(MPFS_OUTPUT0_V1P8_MASK, tmp); 109 break; 110 case SENSOR_V1P05: 111 if (attr == hwmon_in_enable) { 112 *val = FIELD_GET(MPFS_TVS_CTRL_V1P05_ENABLE, control); 113 break; 114 } 115 116 if (!(control & MPFS_TVS_CTRL_V1P05_VALID)) 117 return -ENODATA; 118 119 regmap_read(data->regmap, MPFS_TVS_OUTPUT0, &tmp); 120 *val = FIELD_GET(MPFS_OUTPUT0_V1P05_MASK, tmp); 121 break; 122 default: 123 return -EOPNOTSUPP; 124 } 125 126 return 0; 127 } 128 129 static int mpfs_tvs_voltage_write(struct mpfs_tvs *data, u32 attr, 130 int channel, long val) 131 { 132 u32 tmp; 133 134 if (attr != hwmon_in_enable) 135 return -EOPNOTSUPP; 136 137 if (val > 1 || val < 0) 138 return -EINVAL; 139 140 switch (channel) { 141 case SENSOR_V2P5: 142 tmp = FIELD_PREP(MPFS_TVS_CTRL_V2P5_ENABLE, val); 143 regmap_update_bits(data->regmap, MPFS_TVS_CTRL, 144 MPFS_TVS_CTRL_V2P5_ENABLE, tmp); 145 break; 146 case SENSOR_V1P8: 147 tmp = FIELD_PREP(MPFS_TVS_CTRL_V1P8_ENABLE, val); 148 regmap_update_bits(data->regmap, MPFS_TVS_CTRL, 149 MPFS_TVS_CTRL_V1P8_ENABLE, tmp); 150 break; 151 case SENSOR_V1P05: 152 tmp = FIELD_PREP(MPFS_TVS_CTRL_V1P05_ENABLE, val); 153 regmap_update_bits(data->regmap, MPFS_TVS_CTRL, 154 MPFS_TVS_CTRL_V1P05_ENABLE, tmp); 155 break; 156 default: 157 return -EOPNOTSUPP; 158 } 159 160 return 0; 161 } 162 163 static int mpfs_tvs_temp_read(struct mpfs_tvs *data, u32 attr, long *val) 164 { 165 u32 tmp, control; 166 167 if (attr != hwmon_temp_input && attr != hwmon_temp_enable) 168 return -EOPNOTSUPP; 169 170 regmap_read(data->regmap, MPFS_TVS_CTRL, &control); 171 172 if (attr == hwmon_temp_enable) { 173 *val = FIELD_GET(MPFS_TVS_CTRL_TEMP_ENABLE, control); 174 return 0; 175 } 176 177 if (!(control & MPFS_TVS_CTRL_TEMP_VALID)) 178 return -ENODATA; 179 180 regmap_read(data->regmap, MPFS_TVS_OUTPUT1, &tmp); 181 *val = FIELD_GET(MPFS_OUTPUT1_TEMP_MASK, tmp); 182 *val -= MPFS_TVS_K_TO_C; 183 *val = (1000 * *val) >> 4; /* fixed point (11.4) to millidegrees */ 184 185 return 0; 186 } 187 188 static int mpfs_tvs_temp_write(struct mpfs_tvs *data, u32 attr, long val) 189 { 190 u32 tmp; 191 192 if (attr != hwmon_temp_enable) 193 return -EOPNOTSUPP; 194 195 if (val > 1 || val < 0) 196 return -EINVAL; 197 198 tmp = FIELD_PREP(MPFS_TVS_CTRL_TEMP_ENABLE, val); 199 regmap_update_bits(data->regmap, MPFS_TVS_CTRL, 200 MPFS_TVS_CTRL_TEMP_ENABLE, tmp); 201 202 return 0; 203 } 204 205 static int mpfs_tvs_interval_read(struct mpfs_tvs *data, u32 attr, long *val) 206 { 207 u32 tmp; 208 209 if (attr != hwmon_chip_update_interval) 210 return -EOPNOTSUPP; 211 212 regmap_read(data->regmap, MPFS_TVS_CTRL, &tmp); 213 *val = FIELD_GET(MPFS_TVS_INTERVAL_MASK, tmp); 214 *val *= MPFS_TVS_INTERVAL_SCALE; 215 *val = roundup(*val, 1000); 216 *val /= 1000; 217 218 return 0; 219 } 220 221 static int mpfs_tvs_interval_write(struct mpfs_tvs *data, u32 attr, long val) 222 { 223 long temp = val; 224 225 if (attr != hwmon_chip_update_interval) 226 return -EOPNOTSUPP; 227 228 temp = clamp(temp, 0, MPFS_TVS_INTERVAL_MAX_MS); 229 230 temp *= 1000; 231 temp /= MPFS_TVS_INTERVAL_SCALE; 232 233 temp <<= MPFS_TVS_INTERVAL_OFFSET; 234 regmap_update_bits(data->regmap, MPFS_TVS_CTRL, 235 MPFS_TVS_INTERVAL_MASK, temp); 236 237 return 0; 238 } 239 240 static umode_t mpfs_tvs_is_visible(const void *data, 241 enum hwmon_sensor_types type, 242 u32 attr, int channel) 243 { 244 if (type == hwmon_chip && attr == hwmon_chip_update_interval) 245 return 0644; 246 247 if (type == hwmon_temp) { 248 switch (attr) { 249 case hwmon_temp_enable: 250 return 0644; 251 case hwmon_temp_input: 252 case hwmon_temp_label: 253 return 0444; 254 default: 255 return 0; 256 } 257 } 258 259 if (type == hwmon_in) { 260 switch (attr) { 261 case hwmon_in_enable: 262 return 0644; 263 case hwmon_in_input: 264 case hwmon_in_label: 265 return 0444; 266 default: 267 return 0; 268 } 269 } 270 271 return 0; 272 } 273 274 static int mpfs_tvs_read(struct device *dev, enum hwmon_sensor_types type, 275 u32 attr, int channel, long *val) 276 { 277 struct mpfs_tvs *data = dev_get_drvdata(dev); 278 279 switch (type) { 280 case hwmon_temp: 281 return mpfs_tvs_temp_read(data, attr, val); 282 case hwmon_in: 283 return mpfs_tvs_voltage_read(data, attr, channel, val); 284 case hwmon_chip: 285 return mpfs_tvs_interval_read(data, attr, val); 286 default: 287 return -EOPNOTSUPP; 288 } 289 } 290 291 static int mpfs_tvs_write(struct device *dev, enum hwmon_sensor_types type, 292 u32 attr, int channel, long val) 293 { 294 struct mpfs_tvs *data = dev_get_drvdata(dev); 295 296 switch (type) { 297 case hwmon_temp: 298 return mpfs_tvs_temp_write(data, attr, val); 299 case hwmon_in: 300 return mpfs_tvs_voltage_write(data, attr, channel, val); 301 case hwmon_chip: 302 return mpfs_tvs_interval_write(data, attr, val); 303 default: 304 return -EOPNOTSUPP; 305 } 306 } 307 308 static int mpfs_tvs_read_labels(struct device *dev, 309 enum hwmon_sensor_types type, 310 u32 attr, int channel, 311 const char **str) 312 { 313 switch (type) { 314 case hwmon_temp: 315 *str = "Die Temp"; 316 return 0; 317 case hwmon_in: 318 *str = mpfs_tvs_voltage_labels[channel]; 319 return 0; 320 default: 321 return -EOPNOTSUPP; 322 } 323 } 324 325 static const struct hwmon_ops mpfs_tvs_ops = { 326 .is_visible = mpfs_tvs_is_visible, 327 .read_string = mpfs_tvs_read_labels, 328 .read = mpfs_tvs_read, 329 .write = mpfs_tvs_write, 330 }; 331 332 static const struct hwmon_channel_info *mpfs_tvs_info[] = { 333 HWMON_CHANNEL_INFO(chip, 334 HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL), 335 HWMON_CHANNEL_INFO(temp, 336 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_ENABLE), 337 HWMON_CHANNEL_INFO(in, 338 HWMON_I_INPUT | HWMON_I_LABEL | HWMON_I_ENABLE, 339 HWMON_I_INPUT | HWMON_I_LABEL | HWMON_I_ENABLE, 340 HWMON_I_INPUT | HWMON_I_LABEL | HWMON_I_ENABLE), 341 NULL 342 }; 343 344 static const struct hwmon_chip_info mpfs_tvs_chip_info = { 345 .ops = &mpfs_tvs_ops, 346 .info = mpfs_tvs_info, 347 }; 348 349 static int mpfs_tvs_probe(struct platform_device *pdev) 350 { 351 struct device *hwmon_dev; 352 struct mpfs_tvs *data; 353 354 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 355 if (!data) 356 return -ENOMEM; 357 358 data->regmap = device_node_to_regmap(pdev->dev.parent->of_node); 359 if (IS_ERR(data->regmap)) 360 return dev_err_probe(&pdev->dev, PTR_ERR(data->regmap), 361 "Failed to find syscon regmap\n"); 362 363 /* 364 * It's an MMIO regmap with no resources, there's nothing that can fail 365 * and return an error 366 */ 367 regmap_write(data->regmap, MPFS_TVS_CTRL, MPFS_TVS_CTRL_ENABLE_ALL); 368 369 hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, "mpfs_tvs", 370 data, 371 &mpfs_tvs_chip_info, 372 NULL); 373 if (IS_ERR(hwmon_dev)) 374 return dev_err_probe(&pdev->dev, PTR_ERR(hwmon_dev), 375 "hwmon device registration failed.\n"); 376 377 return 0; 378 } 379 380 static struct platform_driver mpfs_tvs_driver = { 381 .probe = mpfs_tvs_probe, 382 .driver = { 383 .name = "mpfs-tvs", 384 }, 385 }; 386 module_platform_driver(mpfs_tvs_driver); 387 388 MODULE_AUTHOR("Lars Randers <lranders@mail.dk>"); 389 MODULE_DESCRIPTION("PolarFire SoC temperature & voltage sensor driver"); 390 MODULE_LICENSE("GPL"); 391