18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Baikal-T1 Process, Voltage, Temperature sensor driver 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#ifndef __HWMON_BT1_PVT_H__ 88c2ecf20Sopenharmony_ci#define __HWMON_BT1_PVT_H__ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/completion.h> 118c2ecf20Sopenharmony_ci#include <linux/hwmon.h> 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/ktime.h> 148c2ecf20Sopenharmony_ci#include <linux/mutex.h> 158c2ecf20Sopenharmony_ci#include <linux/seqlock.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* Baikal-T1 PVT registers and their bitfields */ 188c2ecf20Sopenharmony_ci#define PVT_CTRL 0x00 198c2ecf20Sopenharmony_ci#define PVT_CTRL_EN BIT(0) 208c2ecf20Sopenharmony_ci#define PVT_CTRL_MODE_FLD 1 218c2ecf20Sopenharmony_ci#define PVT_CTRL_MODE_MASK GENMASK(3, PVT_CTRL_MODE_FLD) 228c2ecf20Sopenharmony_ci#define PVT_CTRL_MODE_TEMP 0x0 238c2ecf20Sopenharmony_ci#define PVT_CTRL_MODE_VOLT 0x1 248c2ecf20Sopenharmony_ci#define PVT_CTRL_MODE_LVT 0x2 258c2ecf20Sopenharmony_ci#define PVT_CTRL_MODE_HVT 0x4 268c2ecf20Sopenharmony_ci#define PVT_CTRL_MODE_SVT 0x6 278c2ecf20Sopenharmony_ci#define PVT_CTRL_TRIM_FLD 4 288c2ecf20Sopenharmony_ci#define PVT_CTRL_TRIM_MASK GENMASK(8, PVT_CTRL_TRIM_FLD) 298c2ecf20Sopenharmony_ci#define PVT_DATA 0x04 308c2ecf20Sopenharmony_ci#define PVT_DATA_VALID BIT(10) 318c2ecf20Sopenharmony_ci#define PVT_DATA_DATA_FLD 0 328c2ecf20Sopenharmony_ci#define PVT_DATA_DATA_MASK GENMASK(9, PVT_DATA_DATA_FLD) 338c2ecf20Sopenharmony_ci#define PVT_TTHRES 0x08 348c2ecf20Sopenharmony_ci#define PVT_VTHRES 0x0C 358c2ecf20Sopenharmony_ci#define PVT_LTHRES 0x10 368c2ecf20Sopenharmony_ci#define PVT_HTHRES 0x14 378c2ecf20Sopenharmony_ci#define PVT_STHRES 0x18 388c2ecf20Sopenharmony_ci#define PVT_THRES_LO_FLD 0 398c2ecf20Sopenharmony_ci#define PVT_THRES_LO_MASK GENMASK(9, PVT_THRES_LO_FLD) 408c2ecf20Sopenharmony_ci#define PVT_THRES_HI_FLD 10 418c2ecf20Sopenharmony_ci#define PVT_THRES_HI_MASK GENMASK(19, PVT_THRES_HI_FLD) 428c2ecf20Sopenharmony_ci#define PVT_TTIMEOUT 0x1C 438c2ecf20Sopenharmony_ci#define PVT_INTR_STAT 0x20 448c2ecf20Sopenharmony_ci#define PVT_INTR_MASK 0x24 458c2ecf20Sopenharmony_ci#define PVT_RAW_INTR_STAT 0x28 468c2ecf20Sopenharmony_ci#define PVT_INTR_DVALID BIT(0) 478c2ecf20Sopenharmony_ci#define PVT_INTR_TTHRES_LO BIT(1) 488c2ecf20Sopenharmony_ci#define PVT_INTR_TTHRES_HI BIT(2) 498c2ecf20Sopenharmony_ci#define PVT_INTR_VTHRES_LO BIT(3) 508c2ecf20Sopenharmony_ci#define PVT_INTR_VTHRES_HI BIT(4) 518c2ecf20Sopenharmony_ci#define PVT_INTR_LTHRES_LO BIT(5) 528c2ecf20Sopenharmony_ci#define PVT_INTR_LTHRES_HI BIT(6) 538c2ecf20Sopenharmony_ci#define PVT_INTR_HTHRES_LO BIT(7) 548c2ecf20Sopenharmony_ci#define PVT_INTR_HTHRES_HI BIT(8) 558c2ecf20Sopenharmony_ci#define PVT_INTR_STHRES_LO BIT(9) 568c2ecf20Sopenharmony_ci#define PVT_INTR_STHRES_HI BIT(10) 578c2ecf20Sopenharmony_ci#define PVT_INTR_ALL GENMASK(10, 0) 588c2ecf20Sopenharmony_ci#define PVT_CLR_INTR 0x2C 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci/* 618c2ecf20Sopenharmony_ci * PVT sensors-related limits and default values 628c2ecf20Sopenharmony_ci * @PVT_TEMP_MIN: Minimal temperature in millidegrees of Celsius. 638c2ecf20Sopenharmony_ci * @PVT_TEMP_MAX: Maximal temperature in millidegrees of Celsius. 648c2ecf20Sopenharmony_ci * @PVT_TEMP_CHS: Number of temperature hwmon channels. 658c2ecf20Sopenharmony_ci * @PVT_VOLT_MIN: Minimal voltage in mV. 668c2ecf20Sopenharmony_ci * @PVT_VOLT_MAX: Maximal voltage in mV. 678c2ecf20Sopenharmony_ci * @PVT_VOLT_CHS: Number of voltage hwmon channels. 688c2ecf20Sopenharmony_ci * @PVT_DATA_MIN: Minimal PVT raw data value. 698c2ecf20Sopenharmony_ci * @PVT_DATA_MAX: Maximal PVT raw data value. 708c2ecf20Sopenharmony_ci * @PVT_TRIM_MIN: Minimal temperature sensor trim value. 718c2ecf20Sopenharmony_ci * @PVT_TRIM_MAX: Maximal temperature sensor trim value. 728c2ecf20Sopenharmony_ci * @PVT_TRIM_DEF: Default temperature sensor trim value (set a proper value 738c2ecf20Sopenharmony_ci * when one is determined for Baikal-T1 SoC). 748c2ecf20Sopenharmony_ci * @PVT_TRIM_TEMP: Maximum temperature encoded by the trim factor. 758c2ecf20Sopenharmony_ci * @PVT_TRIM_STEP: Temperature stride corresponding to the trim value. 768c2ecf20Sopenharmony_ci * @PVT_TOUT_MIN: Minimal timeout between samples in nanoseconds. 778c2ecf20Sopenharmony_ci * @PVT_TOUT_DEF: Default data measurements timeout. In case if alarms are 788c2ecf20Sopenharmony_ci * activated the PVT IRQ is enabled to be raised after each 798c2ecf20Sopenharmony_ci * conversion in order to have the thresholds checked and the 808c2ecf20Sopenharmony_ci * converted value cached. Too frequent conversions may cause 818c2ecf20Sopenharmony_ci * the system CPU overload. Lets set the 50ms delay between 828c2ecf20Sopenharmony_ci * them by default to prevent this. 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci#define PVT_TEMP_MIN -48380L 858c2ecf20Sopenharmony_ci#define PVT_TEMP_MAX 147438L 868c2ecf20Sopenharmony_ci#define PVT_TEMP_CHS 1 878c2ecf20Sopenharmony_ci#define PVT_VOLT_MIN 620L 888c2ecf20Sopenharmony_ci#define PVT_VOLT_MAX 1168L 898c2ecf20Sopenharmony_ci#define PVT_VOLT_CHS 4 908c2ecf20Sopenharmony_ci#define PVT_DATA_MIN 0 918c2ecf20Sopenharmony_ci#define PVT_DATA_MAX (PVT_DATA_DATA_MASK >> PVT_DATA_DATA_FLD) 928c2ecf20Sopenharmony_ci#define PVT_TRIM_MIN 0 938c2ecf20Sopenharmony_ci#define PVT_TRIM_MAX (PVT_CTRL_TRIM_MASK >> PVT_CTRL_TRIM_FLD) 948c2ecf20Sopenharmony_ci#define PVT_TRIM_TEMP 7130 958c2ecf20Sopenharmony_ci#define PVT_TRIM_STEP (PVT_TRIM_TEMP / PVT_TRIM_MAX) 968c2ecf20Sopenharmony_ci#define PVT_TRIM_DEF 0 978c2ecf20Sopenharmony_ci#define PVT_TOUT_MIN (NSEC_PER_SEC / 3000) 988c2ecf20Sopenharmony_ci#if defined(CONFIG_SENSORS_BT1_PVT_ALARMS) 998c2ecf20Sopenharmony_ci# define PVT_TOUT_DEF 60000 1008c2ecf20Sopenharmony_ci#else 1018c2ecf20Sopenharmony_ci# define PVT_TOUT_DEF 0 1028c2ecf20Sopenharmony_ci#endif 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci/* 1058c2ecf20Sopenharmony_ci * enum pvt_sensor_type - Baikal-T1 PVT sensor types (correspond to each PVT 1068c2ecf20Sopenharmony_ci * sampling mode) 1078c2ecf20Sopenharmony_ci * @PVT_SENSOR*: helpers to traverse the sensors in loops. 1088c2ecf20Sopenharmony_ci * @PVT_TEMP: PVT Temperature sensor. 1098c2ecf20Sopenharmony_ci * @PVT_VOLT: PVT Voltage sensor. 1108c2ecf20Sopenharmony_ci * @PVT_LVT: PVT Low-Voltage threshold sensor. 1118c2ecf20Sopenharmony_ci * @PVT_HVT: PVT High-Voltage threshold sensor. 1128c2ecf20Sopenharmony_ci * @PVT_SVT: PVT Standard-Voltage threshold sensor. 1138c2ecf20Sopenharmony_ci */ 1148c2ecf20Sopenharmony_cienum pvt_sensor_type { 1158c2ecf20Sopenharmony_ci PVT_SENSOR_FIRST, 1168c2ecf20Sopenharmony_ci PVT_TEMP = PVT_SENSOR_FIRST, 1178c2ecf20Sopenharmony_ci PVT_VOLT, 1188c2ecf20Sopenharmony_ci PVT_LVT, 1198c2ecf20Sopenharmony_ci PVT_HVT, 1208c2ecf20Sopenharmony_ci PVT_SVT, 1218c2ecf20Sopenharmony_ci PVT_SENSOR_LAST = PVT_SVT, 1228c2ecf20Sopenharmony_ci PVT_SENSORS_NUM 1238c2ecf20Sopenharmony_ci}; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci/* 1268c2ecf20Sopenharmony_ci * enum pvt_clock_type - Baikal-T1 PVT clocks. 1278c2ecf20Sopenharmony_ci * @PVT_CLOCK_APB: APB clock. 1288c2ecf20Sopenharmony_ci * @PVT_CLOCK_REF: PVT reference clock. 1298c2ecf20Sopenharmony_ci */ 1308c2ecf20Sopenharmony_cienum pvt_clock_type { 1318c2ecf20Sopenharmony_ci PVT_CLOCK_APB, 1328c2ecf20Sopenharmony_ci PVT_CLOCK_REF, 1338c2ecf20Sopenharmony_ci PVT_CLOCK_NUM 1348c2ecf20Sopenharmony_ci}; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci/* 1378c2ecf20Sopenharmony_ci * struct pvt_sensor_info - Baikal-T1 PVT sensor informational structure 1388c2ecf20Sopenharmony_ci * @channel: Sensor channel ID. 1398c2ecf20Sopenharmony_ci * @label: hwmon sensor label. 1408c2ecf20Sopenharmony_ci * @mode: PVT mode corresponding to the channel. 1418c2ecf20Sopenharmony_ci * @thres_base: upper and lower threshold values of the sensor. 1428c2ecf20Sopenharmony_ci * @thres_sts_lo: low threshold status bitfield. 1438c2ecf20Sopenharmony_ci * @thres_sts_hi: high threshold status bitfield. 1448c2ecf20Sopenharmony_ci * @type: Sensor type. 1458c2ecf20Sopenharmony_ci * @attr_min_alarm: Min alarm attribute ID. 1468c2ecf20Sopenharmony_ci * @attr_min_alarm: Max alarm attribute ID. 1478c2ecf20Sopenharmony_ci */ 1488c2ecf20Sopenharmony_cistruct pvt_sensor_info { 1498c2ecf20Sopenharmony_ci int channel; 1508c2ecf20Sopenharmony_ci const char *label; 1518c2ecf20Sopenharmony_ci u32 mode; 1528c2ecf20Sopenharmony_ci unsigned long thres_base; 1538c2ecf20Sopenharmony_ci u32 thres_sts_lo; 1548c2ecf20Sopenharmony_ci u32 thres_sts_hi; 1558c2ecf20Sopenharmony_ci enum hwmon_sensor_types type; 1568c2ecf20Sopenharmony_ci u32 attr_min_alarm; 1578c2ecf20Sopenharmony_ci u32 attr_max_alarm; 1588c2ecf20Sopenharmony_ci}; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci#define PVT_SENSOR_INFO(_ch, _label, _type, _mode, _thres) \ 1618c2ecf20Sopenharmony_ci { \ 1628c2ecf20Sopenharmony_ci .channel = _ch, \ 1638c2ecf20Sopenharmony_ci .label = _label, \ 1648c2ecf20Sopenharmony_ci .mode = PVT_CTRL_MODE_ ##_mode, \ 1658c2ecf20Sopenharmony_ci .thres_base = PVT_ ##_thres, \ 1668c2ecf20Sopenharmony_ci .thres_sts_lo = PVT_INTR_ ##_thres## _LO, \ 1678c2ecf20Sopenharmony_ci .thres_sts_hi = PVT_INTR_ ##_thres## _HI, \ 1688c2ecf20Sopenharmony_ci .type = _type, \ 1698c2ecf20Sopenharmony_ci .attr_min_alarm = _type## _min, \ 1708c2ecf20Sopenharmony_ci .attr_max_alarm = _type## _max, \ 1718c2ecf20Sopenharmony_ci } 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci/* 1748c2ecf20Sopenharmony_ci * struct pvt_cache - PVT sensors data cache 1758c2ecf20Sopenharmony_ci * @data: data cache in raw format. 1768c2ecf20Sopenharmony_ci * @thres_sts_lo: low threshold status saved on the previous data conversion. 1778c2ecf20Sopenharmony_ci * @thres_sts_hi: high threshold status saved on the previous data conversion. 1788c2ecf20Sopenharmony_ci * @data_seqlock: cached data seq-lock. 1798c2ecf20Sopenharmony_ci * @conversion: data conversion completion. 1808c2ecf20Sopenharmony_ci */ 1818c2ecf20Sopenharmony_cistruct pvt_cache { 1828c2ecf20Sopenharmony_ci u32 data; 1838c2ecf20Sopenharmony_ci#if defined(CONFIG_SENSORS_BT1_PVT_ALARMS) 1848c2ecf20Sopenharmony_ci seqlock_t data_seqlock; 1858c2ecf20Sopenharmony_ci u32 thres_sts_lo; 1868c2ecf20Sopenharmony_ci u32 thres_sts_hi; 1878c2ecf20Sopenharmony_ci#else 1888c2ecf20Sopenharmony_ci struct completion conversion; 1898c2ecf20Sopenharmony_ci#endif 1908c2ecf20Sopenharmony_ci}; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci/* 1938c2ecf20Sopenharmony_ci * struct pvt_hwmon - Baikal-T1 PVT private data 1948c2ecf20Sopenharmony_ci * @dev: device structure of the PVT platform device. 1958c2ecf20Sopenharmony_ci * @hwmon: hwmon device structure. 1968c2ecf20Sopenharmony_ci * @regs: pointer to the Baikal-T1 PVT registers region. 1978c2ecf20Sopenharmony_ci * @irq: PVT events IRQ number. 1988c2ecf20Sopenharmony_ci * @clks: Array of the PVT clocks descriptor (APB/ref clocks). 1998c2ecf20Sopenharmony_ci * @ref_clk: Pointer to the reference clocks descriptor. 2008c2ecf20Sopenharmony_ci * @iface_mtx: Generic interface mutex (used to lock the alarm registers 2018c2ecf20Sopenharmony_ci * when the alarms enabled, or the data conversion interface 2028c2ecf20Sopenharmony_ci * if alarms are disabled). 2038c2ecf20Sopenharmony_ci * @sensor: current PVT sensor the data conversion is being performed for. 2048c2ecf20Sopenharmony_ci * @cache: data cache descriptor. 2058c2ecf20Sopenharmony_ci * @timeout: conversion timeout cache. 2068c2ecf20Sopenharmony_ci */ 2078c2ecf20Sopenharmony_cistruct pvt_hwmon { 2088c2ecf20Sopenharmony_ci struct device *dev; 2098c2ecf20Sopenharmony_ci struct device *hwmon; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci void __iomem *regs; 2128c2ecf20Sopenharmony_ci int irq; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci struct clk_bulk_data clks[PVT_CLOCK_NUM]; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci struct mutex iface_mtx; 2178c2ecf20Sopenharmony_ci enum pvt_sensor_type sensor; 2188c2ecf20Sopenharmony_ci struct pvt_cache cache[PVT_SENSORS_NUM]; 2198c2ecf20Sopenharmony_ci ktime_t timeout; 2208c2ecf20Sopenharmony_ci}; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci/* 2238c2ecf20Sopenharmony_ci * struct pvt_poly_term - a term descriptor of the PVT data translation 2248c2ecf20Sopenharmony_ci * polynomial 2258c2ecf20Sopenharmony_ci * @deg: degree of the term. 2268c2ecf20Sopenharmony_ci * @coef: multiplication factor of the term. 2278c2ecf20Sopenharmony_ci * @divider: distributed divider per each degree. 2288c2ecf20Sopenharmony_ci * @divider_leftover: divider leftover, which couldn't be redistributed. 2298c2ecf20Sopenharmony_ci */ 2308c2ecf20Sopenharmony_cistruct pvt_poly_term { 2318c2ecf20Sopenharmony_ci unsigned int deg; 2328c2ecf20Sopenharmony_ci long coef; 2338c2ecf20Sopenharmony_ci long divider; 2348c2ecf20Sopenharmony_ci long divider_leftover; 2358c2ecf20Sopenharmony_ci}; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci/* 2388c2ecf20Sopenharmony_ci * struct pvt_poly - PVT data translation polynomial descriptor 2398c2ecf20Sopenharmony_ci * @total_divider: total data divider. 2408c2ecf20Sopenharmony_ci * @terms: polynomial terms up to a free one. 2418c2ecf20Sopenharmony_ci */ 2428c2ecf20Sopenharmony_cistruct pvt_poly { 2438c2ecf20Sopenharmony_ci long total_divider; 2448c2ecf20Sopenharmony_ci struct pvt_poly_term terms[]; 2458c2ecf20Sopenharmony_ci}; 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci#endif /* __HWMON_BT1_PVT_H__ */ 248