1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Baikal-T1 Process, Voltage, Temperature sensor driver 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun #ifndef __HWMON_BT1_PVT_H__ 8*4882a593Smuzhiyun #define __HWMON_BT1_PVT_H__ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #include <linux/completion.h> 11*4882a593Smuzhiyun #include <linux/hwmon.h> 12*4882a593Smuzhiyun #include <linux/kernel.h> 13*4882a593Smuzhiyun #include <linux/ktime.h> 14*4882a593Smuzhiyun #include <linux/mutex.h> 15*4882a593Smuzhiyun #include <linux/seqlock.h> 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun /* Baikal-T1 PVT registers and their bitfields */ 18*4882a593Smuzhiyun #define PVT_CTRL 0x00 19*4882a593Smuzhiyun #define PVT_CTRL_EN BIT(0) 20*4882a593Smuzhiyun #define PVT_CTRL_MODE_FLD 1 21*4882a593Smuzhiyun #define PVT_CTRL_MODE_MASK GENMASK(3, PVT_CTRL_MODE_FLD) 22*4882a593Smuzhiyun #define PVT_CTRL_MODE_TEMP 0x0 23*4882a593Smuzhiyun #define PVT_CTRL_MODE_VOLT 0x1 24*4882a593Smuzhiyun #define PVT_CTRL_MODE_LVT 0x2 25*4882a593Smuzhiyun #define PVT_CTRL_MODE_HVT 0x4 26*4882a593Smuzhiyun #define PVT_CTRL_MODE_SVT 0x6 27*4882a593Smuzhiyun #define PVT_CTRL_TRIM_FLD 4 28*4882a593Smuzhiyun #define PVT_CTRL_TRIM_MASK GENMASK(8, PVT_CTRL_TRIM_FLD) 29*4882a593Smuzhiyun #define PVT_DATA 0x04 30*4882a593Smuzhiyun #define PVT_DATA_VALID BIT(10) 31*4882a593Smuzhiyun #define PVT_DATA_DATA_FLD 0 32*4882a593Smuzhiyun #define PVT_DATA_DATA_MASK GENMASK(9, PVT_DATA_DATA_FLD) 33*4882a593Smuzhiyun #define PVT_TTHRES 0x08 34*4882a593Smuzhiyun #define PVT_VTHRES 0x0C 35*4882a593Smuzhiyun #define PVT_LTHRES 0x10 36*4882a593Smuzhiyun #define PVT_HTHRES 0x14 37*4882a593Smuzhiyun #define PVT_STHRES 0x18 38*4882a593Smuzhiyun #define PVT_THRES_LO_FLD 0 39*4882a593Smuzhiyun #define PVT_THRES_LO_MASK GENMASK(9, PVT_THRES_LO_FLD) 40*4882a593Smuzhiyun #define PVT_THRES_HI_FLD 10 41*4882a593Smuzhiyun #define PVT_THRES_HI_MASK GENMASK(19, PVT_THRES_HI_FLD) 42*4882a593Smuzhiyun #define PVT_TTIMEOUT 0x1C 43*4882a593Smuzhiyun #define PVT_INTR_STAT 0x20 44*4882a593Smuzhiyun #define PVT_INTR_MASK 0x24 45*4882a593Smuzhiyun #define PVT_RAW_INTR_STAT 0x28 46*4882a593Smuzhiyun #define PVT_INTR_DVALID BIT(0) 47*4882a593Smuzhiyun #define PVT_INTR_TTHRES_LO BIT(1) 48*4882a593Smuzhiyun #define PVT_INTR_TTHRES_HI BIT(2) 49*4882a593Smuzhiyun #define PVT_INTR_VTHRES_LO BIT(3) 50*4882a593Smuzhiyun #define PVT_INTR_VTHRES_HI BIT(4) 51*4882a593Smuzhiyun #define PVT_INTR_LTHRES_LO BIT(5) 52*4882a593Smuzhiyun #define PVT_INTR_LTHRES_HI BIT(6) 53*4882a593Smuzhiyun #define PVT_INTR_HTHRES_LO BIT(7) 54*4882a593Smuzhiyun #define PVT_INTR_HTHRES_HI BIT(8) 55*4882a593Smuzhiyun #define PVT_INTR_STHRES_LO BIT(9) 56*4882a593Smuzhiyun #define PVT_INTR_STHRES_HI BIT(10) 57*4882a593Smuzhiyun #define PVT_INTR_ALL GENMASK(10, 0) 58*4882a593Smuzhiyun #define PVT_CLR_INTR 0x2C 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun /* 61*4882a593Smuzhiyun * PVT sensors-related limits and default values 62*4882a593Smuzhiyun * @PVT_TEMP_MIN: Minimal temperature in millidegrees of Celsius. 63*4882a593Smuzhiyun * @PVT_TEMP_MAX: Maximal temperature in millidegrees of Celsius. 64*4882a593Smuzhiyun * @PVT_TEMP_CHS: Number of temperature hwmon channels. 65*4882a593Smuzhiyun * @PVT_VOLT_MIN: Minimal voltage in mV. 66*4882a593Smuzhiyun * @PVT_VOLT_MAX: Maximal voltage in mV. 67*4882a593Smuzhiyun * @PVT_VOLT_CHS: Number of voltage hwmon channels. 68*4882a593Smuzhiyun * @PVT_DATA_MIN: Minimal PVT raw data value. 69*4882a593Smuzhiyun * @PVT_DATA_MAX: Maximal PVT raw data value. 70*4882a593Smuzhiyun * @PVT_TRIM_MIN: Minimal temperature sensor trim value. 71*4882a593Smuzhiyun * @PVT_TRIM_MAX: Maximal temperature sensor trim value. 72*4882a593Smuzhiyun * @PVT_TRIM_DEF: Default temperature sensor trim value (set a proper value 73*4882a593Smuzhiyun * when one is determined for Baikal-T1 SoC). 74*4882a593Smuzhiyun * @PVT_TRIM_TEMP: Maximum temperature encoded by the trim factor. 75*4882a593Smuzhiyun * @PVT_TRIM_STEP: Temperature stride corresponding to the trim value. 76*4882a593Smuzhiyun * @PVT_TOUT_MIN: Minimal timeout between samples in nanoseconds. 77*4882a593Smuzhiyun * @PVT_TOUT_DEF: Default data measurements timeout. In case if alarms are 78*4882a593Smuzhiyun * activated the PVT IRQ is enabled to be raised after each 79*4882a593Smuzhiyun * conversion in order to have the thresholds checked and the 80*4882a593Smuzhiyun * converted value cached. Too frequent conversions may cause 81*4882a593Smuzhiyun * the system CPU overload. Lets set the 50ms delay between 82*4882a593Smuzhiyun * them by default to prevent this. 83*4882a593Smuzhiyun */ 84*4882a593Smuzhiyun #define PVT_TEMP_MIN -48380L 85*4882a593Smuzhiyun #define PVT_TEMP_MAX 147438L 86*4882a593Smuzhiyun #define PVT_TEMP_CHS 1 87*4882a593Smuzhiyun #define PVT_VOLT_MIN 620L 88*4882a593Smuzhiyun #define PVT_VOLT_MAX 1168L 89*4882a593Smuzhiyun #define PVT_VOLT_CHS 4 90*4882a593Smuzhiyun #define PVT_DATA_MIN 0 91*4882a593Smuzhiyun #define PVT_DATA_MAX (PVT_DATA_DATA_MASK >> PVT_DATA_DATA_FLD) 92*4882a593Smuzhiyun #define PVT_TRIM_MIN 0 93*4882a593Smuzhiyun #define PVT_TRIM_MAX (PVT_CTRL_TRIM_MASK >> PVT_CTRL_TRIM_FLD) 94*4882a593Smuzhiyun #define PVT_TRIM_TEMP 7130 95*4882a593Smuzhiyun #define PVT_TRIM_STEP (PVT_TRIM_TEMP / PVT_TRIM_MAX) 96*4882a593Smuzhiyun #define PVT_TRIM_DEF 0 97*4882a593Smuzhiyun #define PVT_TOUT_MIN (NSEC_PER_SEC / 3000) 98*4882a593Smuzhiyun #if defined(CONFIG_SENSORS_BT1_PVT_ALARMS) 99*4882a593Smuzhiyun # define PVT_TOUT_DEF 60000 100*4882a593Smuzhiyun #else 101*4882a593Smuzhiyun # define PVT_TOUT_DEF 0 102*4882a593Smuzhiyun #endif 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun /* 105*4882a593Smuzhiyun * enum pvt_sensor_type - Baikal-T1 PVT sensor types (correspond to each PVT 106*4882a593Smuzhiyun * sampling mode) 107*4882a593Smuzhiyun * @PVT_SENSOR*: helpers to traverse the sensors in loops. 108*4882a593Smuzhiyun * @PVT_TEMP: PVT Temperature sensor. 109*4882a593Smuzhiyun * @PVT_VOLT: PVT Voltage sensor. 110*4882a593Smuzhiyun * @PVT_LVT: PVT Low-Voltage threshold sensor. 111*4882a593Smuzhiyun * @PVT_HVT: PVT High-Voltage threshold sensor. 112*4882a593Smuzhiyun * @PVT_SVT: PVT Standard-Voltage threshold sensor. 113*4882a593Smuzhiyun */ 114*4882a593Smuzhiyun enum pvt_sensor_type { 115*4882a593Smuzhiyun PVT_SENSOR_FIRST, 116*4882a593Smuzhiyun PVT_TEMP = PVT_SENSOR_FIRST, 117*4882a593Smuzhiyun PVT_VOLT, 118*4882a593Smuzhiyun PVT_LVT, 119*4882a593Smuzhiyun PVT_HVT, 120*4882a593Smuzhiyun PVT_SVT, 121*4882a593Smuzhiyun PVT_SENSOR_LAST = PVT_SVT, 122*4882a593Smuzhiyun PVT_SENSORS_NUM 123*4882a593Smuzhiyun }; 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun /* 126*4882a593Smuzhiyun * enum pvt_clock_type - Baikal-T1 PVT clocks. 127*4882a593Smuzhiyun * @PVT_CLOCK_APB: APB clock. 128*4882a593Smuzhiyun * @PVT_CLOCK_REF: PVT reference clock. 129*4882a593Smuzhiyun */ 130*4882a593Smuzhiyun enum pvt_clock_type { 131*4882a593Smuzhiyun PVT_CLOCK_APB, 132*4882a593Smuzhiyun PVT_CLOCK_REF, 133*4882a593Smuzhiyun PVT_CLOCK_NUM 134*4882a593Smuzhiyun }; 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun /* 137*4882a593Smuzhiyun * struct pvt_sensor_info - Baikal-T1 PVT sensor informational structure 138*4882a593Smuzhiyun * @channel: Sensor channel ID. 139*4882a593Smuzhiyun * @label: hwmon sensor label. 140*4882a593Smuzhiyun * @mode: PVT mode corresponding to the channel. 141*4882a593Smuzhiyun * @thres_base: upper and lower threshold values of the sensor. 142*4882a593Smuzhiyun * @thres_sts_lo: low threshold status bitfield. 143*4882a593Smuzhiyun * @thres_sts_hi: high threshold status bitfield. 144*4882a593Smuzhiyun * @type: Sensor type. 145*4882a593Smuzhiyun * @attr_min_alarm: Min alarm attribute ID. 146*4882a593Smuzhiyun * @attr_min_alarm: Max alarm attribute ID. 147*4882a593Smuzhiyun */ 148*4882a593Smuzhiyun struct pvt_sensor_info { 149*4882a593Smuzhiyun int channel; 150*4882a593Smuzhiyun const char *label; 151*4882a593Smuzhiyun u32 mode; 152*4882a593Smuzhiyun unsigned long thres_base; 153*4882a593Smuzhiyun u32 thres_sts_lo; 154*4882a593Smuzhiyun u32 thres_sts_hi; 155*4882a593Smuzhiyun enum hwmon_sensor_types type; 156*4882a593Smuzhiyun u32 attr_min_alarm; 157*4882a593Smuzhiyun u32 attr_max_alarm; 158*4882a593Smuzhiyun }; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun #define PVT_SENSOR_INFO(_ch, _label, _type, _mode, _thres) \ 161*4882a593Smuzhiyun { \ 162*4882a593Smuzhiyun .channel = _ch, \ 163*4882a593Smuzhiyun .label = _label, \ 164*4882a593Smuzhiyun .mode = PVT_CTRL_MODE_ ##_mode, \ 165*4882a593Smuzhiyun .thres_base = PVT_ ##_thres, \ 166*4882a593Smuzhiyun .thres_sts_lo = PVT_INTR_ ##_thres## _LO, \ 167*4882a593Smuzhiyun .thres_sts_hi = PVT_INTR_ ##_thres## _HI, \ 168*4882a593Smuzhiyun .type = _type, \ 169*4882a593Smuzhiyun .attr_min_alarm = _type## _min, \ 170*4882a593Smuzhiyun .attr_max_alarm = _type## _max, \ 171*4882a593Smuzhiyun } 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun /* 174*4882a593Smuzhiyun * struct pvt_cache - PVT sensors data cache 175*4882a593Smuzhiyun * @data: data cache in raw format. 176*4882a593Smuzhiyun * @thres_sts_lo: low threshold status saved on the previous data conversion. 177*4882a593Smuzhiyun * @thres_sts_hi: high threshold status saved on the previous data conversion. 178*4882a593Smuzhiyun * @data_seqlock: cached data seq-lock. 179*4882a593Smuzhiyun * @conversion: data conversion completion. 180*4882a593Smuzhiyun */ 181*4882a593Smuzhiyun struct pvt_cache { 182*4882a593Smuzhiyun u32 data; 183*4882a593Smuzhiyun #if defined(CONFIG_SENSORS_BT1_PVT_ALARMS) 184*4882a593Smuzhiyun seqlock_t data_seqlock; 185*4882a593Smuzhiyun u32 thres_sts_lo; 186*4882a593Smuzhiyun u32 thres_sts_hi; 187*4882a593Smuzhiyun #else 188*4882a593Smuzhiyun struct completion conversion; 189*4882a593Smuzhiyun #endif 190*4882a593Smuzhiyun }; 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun /* 193*4882a593Smuzhiyun * struct pvt_hwmon - Baikal-T1 PVT private data 194*4882a593Smuzhiyun * @dev: device structure of the PVT platform device. 195*4882a593Smuzhiyun * @hwmon: hwmon device structure. 196*4882a593Smuzhiyun * @regs: pointer to the Baikal-T1 PVT registers region. 197*4882a593Smuzhiyun * @irq: PVT events IRQ number. 198*4882a593Smuzhiyun * @clks: Array of the PVT clocks descriptor (APB/ref clocks). 199*4882a593Smuzhiyun * @ref_clk: Pointer to the reference clocks descriptor. 200*4882a593Smuzhiyun * @iface_mtx: Generic interface mutex (used to lock the alarm registers 201*4882a593Smuzhiyun * when the alarms enabled, or the data conversion interface 202*4882a593Smuzhiyun * if alarms are disabled). 203*4882a593Smuzhiyun * @sensor: current PVT sensor the data conversion is being performed for. 204*4882a593Smuzhiyun * @cache: data cache descriptor. 205*4882a593Smuzhiyun * @timeout: conversion timeout cache. 206*4882a593Smuzhiyun */ 207*4882a593Smuzhiyun struct pvt_hwmon { 208*4882a593Smuzhiyun struct device *dev; 209*4882a593Smuzhiyun struct device *hwmon; 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun void __iomem *regs; 212*4882a593Smuzhiyun int irq; 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun struct clk_bulk_data clks[PVT_CLOCK_NUM]; 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun struct mutex iface_mtx; 217*4882a593Smuzhiyun enum pvt_sensor_type sensor; 218*4882a593Smuzhiyun struct pvt_cache cache[PVT_SENSORS_NUM]; 219*4882a593Smuzhiyun ktime_t timeout; 220*4882a593Smuzhiyun }; 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun /* 223*4882a593Smuzhiyun * struct pvt_poly_term - a term descriptor of the PVT data translation 224*4882a593Smuzhiyun * polynomial 225*4882a593Smuzhiyun * @deg: degree of the term. 226*4882a593Smuzhiyun * @coef: multiplication factor of the term. 227*4882a593Smuzhiyun * @divider: distributed divider per each degree. 228*4882a593Smuzhiyun * @divider_leftover: divider leftover, which couldn't be redistributed. 229*4882a593Smuzhiyun */ 230*4882a593Smuzhiyun struct pvt_poly_term { 231*4882a593Smuzhiyun unsigned int deg; 232*4882a593Smuzhiyun long coef; 233*4882a593Smuzhiyun long divider; 234*4882a593Smuzhiyun long divider_leftover; 235*4882a593Smuzhiyun }; 236*4882a593Smuzhiyun 237*4882a593Smuzhiyun /* 238*4882a593Smuzhiyun * struct pvt_poly - PVT data translation polynomial descriptor 239*4882a593Smuzhiyun * @total_divider: total data divider. 240*4882a593Smuzhiyun * @terms: polynomial terms up to a free one. 241*4882a593Smuzhiyun */ 242*4882a593Smuzhiyun struct pvt_poly { 243*4882a593Smuzhiyun long total_divider; 244*4882a593Smuzhiyun struct pvt_poly_term terms[]; 245*4882a593Smuzhiyun }; 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun #endif /* __HWMON_BT1_PVT_H__ */ 248