^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Maxim Kaurkin <maxim.kaurkin@baikalelectronics.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Serge Semin <Sergey.Semin@baikalelectronics.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Baikal-T1 Process, Voltage, Temperature sensor driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/seqlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "bt1-pvt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * For the sake of the code simplification we created the sensors info table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * with the sensor names, activation modes, threshold registers base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * and the thresholds bit fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static const struct pvt_sensor_info pvt_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) PVT_SENSOR_INFO(0, "CPU Core Temperature", hwmon_temp, TEMP, TTHRES),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) PVT_SENSOR_INFO(0, "CPU Core Voltage", hwmon_in, VOLT, VTHRES),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) PVT_SENSOR_INFO(1, "CPU Core Low-Vt", hwmon_in, LVT, LTHRES),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) PVT_SENSOR_INFO(2, "CPU Core High-Vt", hwmon_in, HVT, HTHRES),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) PVT_SENSOR_INFO(3, "CPU Core Standard-Vt", hwmon_in, SVT, STHRES),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * The original translation formulae of the temperature (in degrees of Celsius)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * to PVT data and vice-versa are following:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * N = 1.8322e-8*(T^4) + 2.343e-5*(T^3) + 8.7018e-3*(T^2) + 3.9269*(T^1) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * 1.7204e2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * T = -1.6743e-11*(N^4) + 8.1542e-8*(N^3) + -1.8201e-4*(N^2) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * 3.1020e-1*(N^1) - 4.838e1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * where T = [-48.380, 147.438]C and N = [0, 1023].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * They must be accordingly altered to be suitable for the integer arithmetics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * The technique is called 'factor redistribution', which just makes sure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * multiplications and divisions are made so to have a result of the operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * within the integer numbers limit. In addition we need to translate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * formulae to accept millidegrees of Celsius. Here what they look like after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * the alterations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * N = (18322e-20*(T^4) + 2343e-13*(T^3) + 87018e-9*(T^2) + 39269e-3*T +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * 17204e2) / 1e4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * T = -16743e-12*(D^4) + 81542e-9*(D^3) - 182010e-6*(D^2) + 310200e-3*D -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * 48380,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * where T = [-48380, 147438] mC and N = [0, 1023].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static const struct pvt_poly __maybe_unused poly_temp_to_N = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .total_divider = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .terms = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {4, 18322, 10000, 10000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {3, 2343, 10000, 10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {2, 87018, 10000, 10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {1, 39269, 1000, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {0, 1720400, 1, 1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static const struct pvt_poly poly_N_to_temp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .total_divider = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .terms = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {4, -16743, 1000, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {3, 81542, 1000, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {2, -182010, 1000, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {1, 310200, 1000, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {0, -48380, 1, 1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * Similar alterations are performed for the voltage conversion equations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * The original formulae are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * N = 1.8658e3*V - 1.1572e3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * V = (N + 1.1572e3) / 1.8658e3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * where V = [0.620, 1.168] V and N = [0, 1023].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * After the optimization they looks as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * N = (18658e-3*V - 11572) / 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * V = N * 10^5 / 18658 + 11572 * 10^4 / 18658.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static const struct pvt_poly __maybe_unused poly_volt_to_N = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .total_divider = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .terms = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {1, 18658, 1000, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {0, -11572, 1, 1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static const struct pvt_poly poly_N_to_volt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .total_divider = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .terms = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {1, 100000, 18658, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {0, 115720000, 1, 18658}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Here is the polynomial calculation function, which performs the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * redistributed terms calculations. It's pretty straightforward. We walk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * over each degree term up to the free one, and perform the redistributed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * multiplication of the term coefficient, its divider (as for the rationale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * fraction representation), data power and the rational fraction divider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * leftover. Then all of this is collected in a total sum variable, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * value is normalized by the total divider before being returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static long pvt_calc_poly(const struct pvt_poly *poly, long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) const struct pvt_poly_term *term = poly->terms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) long tmp, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int deg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) tmp = term->coef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) for (deg = 0; deg < term->deg; ++deg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) tmp = mult_frac(tmp, data, term->divider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ret += tmp / term->divider_leftover;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) } while ((term++)->deg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return ret / poly->total_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static inline u32 pvt_update(void __iomem *reg, u32 mask, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) old = readl_relaxed(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) writel((old & ~mask) | (data & mask), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return old & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * Baikal-T1 PVT mode can be updated only when the controller is disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * So first we disable it, then set the new mode together with the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * getting back enabled. The same concerns the temperature trim and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * measurements timeout. If it is necessary the interface mutex is supposed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * to be locked at the time the operations are performed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static inline void pvt_set_mode(struct pvt_hwmon *pvt, u32 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u32 old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) mode = FIELD_PREP(PVT_CTRL_MODE_MASK, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) old = pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_MODE_MASK | PVT_CTRL_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) mode | old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static inline u32 pvt_calc_trim(long temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) temp = clamp_val(temp, 0, PVT_TRIM_TEMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return DIV_ROUND_UP(temp, PVT_TRIM_STEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static inline void pvt_set_trim(struct pvt_hwmon *pvt, u32 trim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u32 old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) trim = FIELD_PREP(PVT_CTRL_TRIM_MASK, trim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) old = pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_TRIM_MASK | PVT_CTRL_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) trim | old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static inline void pvt_set_tout(struct pvt_hwmon *pvt, u32 tout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) u32 old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) old = pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) writel(tout, pvt->regs + PVT_TTIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * This driver can optionally provide the hwmon alarms for each sensor the PVT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * controller supports. The alarms functionality is made compile-time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * configurable due to the hardware interface implementation peculiarity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * described further in this comment. So in case if alarms are unnecessary in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * your system design it's recommended to have them disabled to prevent the PVT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * IRQs being periodically raised to get the data cache/alarms status up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * date.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * Baikal-T1 PVT embedded controller is based on the Analog Bits PVT sensor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * but is equipped with a dedicated control wrapper. It exposes the PVT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * sub-block registers space via the APB3 bus. In addition the wrapper provides
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * a common interrupt vector of the sensors conversion completion events and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * threshold value alarms. Alas the wrapper interface hasn't been fully thought
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * through. There is only one sensor can be activated at a time, for which the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * thresholds comparator is enabled right after the data conversion is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * completed. Due to this if alarms need to be implemented for all available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * sensors we can't just set the thresholds and enable the interrupts. We need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * to enable the sensors one after another and let the controller to detect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * the alarms by itself at each conversion. This also makes pointless to handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * the alarms interrupts, since in occasion they happen synchronously with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * data conversion completion. The best driver design would be to have the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * completion interrupts enabled only and keep the converted value in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * driver data cache. This solution is implemented if hwmon alarms are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * in this driver. In case if the alarms are disabled, the conversion is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * performed on demand at the time a sensors input file is read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #if defined(CONFIG_SENSORS_BT1_PVT_ALARMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define pvt_hard_isr NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static irqreturn_t pvt_soft_isr(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) const struct pvt_sensor_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct pvt_hwmon *pvt = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct pvt_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u32 val, thres_sts, old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * DVALID bit will be cleared by reading the data. We need to save the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * status before the next conversion happens. Threshold events will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * handled a bit later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) thres_sts = readl(pvt->regs + PVT_RAW_INTR_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * Then lets recharge the PVT interface with the next sampling mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * Lock the interface mutex to serialize trim, timeouts and alarm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * thresholds settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) cache = &pvt->cache[pvt->sensor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) info = &pvt_info[pvt->sensor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) pvt->sensor = (pvt->sensor == PVT_SENSOR_LAST) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) PVT_SENSOR_FIRST : (pvt->sensor + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * For some reason we have to mask the interrupt before changing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * mode, otherwise sometimes the temperature mode doesn't get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * activated even though the actual mode in the ctrl register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * corresponds to one. Then we read the data. By doing so we also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * recharge the data conversion. After this the mode corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * to the next sensor in the row is set. Finally we enable the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * interrupts back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) mutex_lock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) old = pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) PVT_INTR_DVALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) val = readl(pvt->regs + PVT_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) pvt_set_mode(pvt, pvt_info[pvt->sensor].mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) mutex_unlock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * We can now update the data cache with data just retrieved from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * sensor. Lock write-seqlock to make sure the reader has a coherent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) write_seqlock(&cache->data_seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) cache->data = FIELD_GET(PVT_DATA_DATA_MASK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) write_sequnlock(&cache->data_seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * While PVT core is doing the next mode data conversion, we'll check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * whether the alarms were triggered for the current sensor. Note that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * according to the documentation only one threshold IRQ status can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * set at a time, that's why if-else statement is utilized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if ((thres_sts & info->thres_sts_lo) ^ cache->thres_sts_lo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) WRITE_ONCE(cache->thres_sts_lo, thres_sts & info->thres_sts_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) hwmon_notify_event(pvt->hwmon, info->type, info->attr_min_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) info->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) } else if ((thres_sts & info->thres_sts_hi) ^ cache->thres_sts_hi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) WRITE_ONCE(cache->thres_sts_hi, thres_sts & info->thres_sts_hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) hwmon_notify_event(pvt->hwmon, info->type, info->attr_max_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) info->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static inline umode_t pvt_limit_is_visible(enum pvt_sensor_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return 0644;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static inline umode_t pvt_alarm_is_visible(enum pvt_sensor_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct pvt_cache *cache = &pvt->cache[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned int seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) seq = read_seqbegin(&cache->data_seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) data = cache->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) } while (read_seqretry(&cache->data_seqlock, seq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (type == PVT_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *val = pvt_calc_poly(&poly_N_to_temp, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) *val = pvt_calc_poly(&poly_N_to_volt, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static int pvt_read_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) bool is_low, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* No need in serialization, since it is just read from MMIO. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) data = readl(pvt->regs + pvt_info[type].thres_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (is_low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) data = FIELD_GET(PVT_THRES_LO_MASK, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) data = FIELD_GET(PVT_THRES_HI_MASK, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (type == PVT_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) *val = pvt_calc_poly(&poly_N_to_temp, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) *val = pvt_calc_poly(&poly_N_to_volt, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static int pvt_write_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) bool is_low, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) u32 data, limit, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (type == PVT_TEMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) val = clamp(val, PVT_TEMP_MIN, PVT_TEMP_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) data = pvt_calc_poly(&poly_temp_to_N, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) val = clamp(val, PVT_VOLT_MIN, PVT_VOLT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) data = pvt_calc_poly(&poly_volt_to_N, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* Serialize limit update, since a part of the register is changed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ret = mutex_lock_interruptible(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* Make sure the upper and lower ranges don't intersect. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) limit = readl(pvt->regs + pvt_info[type].thres_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (is_low) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) limit = FIELD_GET(PVT_THRES_HI_MASK, limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) data = clamp_val(data, PVT_DATA_MIN, limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) data = FIELD_PREP(PVT_THRES_LO_MASK, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) mask = PVT_THRES_LO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) limit = FIELD_GET(PVT_THRES_LO_MASK, limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) data = clamp_val(data, limit, PVT_DATA_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) data = FIELD_PREP(PVT_THRES_HI_MASK, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) mask = PVT_THRES_HI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) pvt_update(pvt->regs + pvt_info[type].thres_base, mask, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) mutex_unlock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static int pvt_read_alarm(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) bool is_low, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (is_low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *val = !!READ_ONCE(pvt->cache[type].thres_sts_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) *val = !!READ_ONCE(pvt->cache[type].thres_sts_hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static const struct hwmon_channel_info *pvt_channel_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) HWMON_CHANNEL_INFO(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) HWMON_CHANNEL_INFO(temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) HWMON_T_INPUT | HWMON_T_TYPE | HWMON_T_LABEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) HWMON_T_MIN | HWMON_T_MIN_ALARM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) HWMON_T_MAX | HWMON_T_MAX_ALARM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) HWMON_T_OFFSET),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) HWMON_CHANNEL_INFO(in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) HWMON_I_INPUT | HWMON_I_LABEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) HWMON_I_MIN | HWMON_I_MIN_ALARM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) HWMON_I_MAX | HWMON_I_MAX_ALARM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) HWMON_I_INPUT | HWMON_I_LABEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) HWMON_I_MIN | HWMON_I_MIN_ALARM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) HWMON_I_MAX | HWMON_I_MAX_ALARM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) HWMON_I_INPUT | HWMON_I_LABEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) HWMON_I_MIN | HWMON_I_MIN_ALARM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) HWMON_I_MAX | HWMON_I_MAX_ALARM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) HWMON_I_INPUT | HWMON_I_LABEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) HWMON_I_MIN | HWMON_I_MIN_ALARM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) HWMON_I_MAX | HWMON_I_MAX_ALARM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) #else /* !CONFIG_SENSORS_BT1_PVT_ALARMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static irqreturn_t pvt_hard_isr(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct pvt_hwmon *pvt = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct pvt_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * Mask the DVALID interrupt so after exiting from the handler a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * repeated conversion wouldn't happen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) PVT_INTR_DVALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * Nothing special for alarm-less driver. Just read the data, update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * the cache and notify a waiter of this event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) val = readl(pvt->regs + PVT_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!(val & PVT_DATA_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dev_err(pvt->dev, "Got IRQ when data isn't valid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) cache = &pvt->cache[pvt->sensor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) WRITE_ONCE(cache->data, FIELD_GET(PVT_DATA_DATA_MASK, val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) complete(&cache->conversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #define pvt_soft_isr NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static inline umode_t pvt_limit_is_visible(enum pvt_sensor_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static inline umode_t pvt_alarm_is_visible(enum pvt_sensor_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static int pvt_read_data(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct pvt_cache *cache = &pvt->cache[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * Lock PVT conversion interface until data cache is updated. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * data read procedure is following: set the requested PVT sensor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * mode, enable IRQ and conversion, wait until conversion is finished,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * then disable conversion and IRQ, and read the cached data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ret = mutex_lock_interruptible(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) pvt->sensor = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) pvt_set_mode(pvt, pvt_info[type].mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * Unmask the DVALID interrupt and enable the sensors conversions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * Do the reverse procedure when conversion is done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * Wait with timeout since in case if the sensor is suddenly powered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * down the request won't be completed and the caller will hang up on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * this procedure until the power is back up again. Multiply the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * timeout by the factor of two to prevent a false timeout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) timeout = 2 * usecs_to_jiffies(ktime_to_us(pvt->timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ret = wait_for_completion_timeout(&cache->conversion, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) PVT_INTR_DVALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) data = READ_ONCE(cache->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) mutex_unlock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (type == PVT_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) *val = pvt_calc_poly(&poly_N_to_temp, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) *val = pvt_calc_poly(&poly_N_to_volt, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static int pvt_read_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) bool is_low, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static int pvt_write_limit(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) bool is_low, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static int pvt_read_alarm(struct pvt_hwmon *pvt, enum pvt_sensor_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) bool is_low, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static const struct hwmon_channel_info *pvt_channel_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) HWMON_CHANNEL_INFO(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) HWMON_CHANNEL_INFO(temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) HWMON_T_INPUT | HWMON_T_TYPE | HWMON_T_LABEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) HWMON_T_OFFSET),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) HWMON_CHANNEL_INFO(in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) HWMON_I_INPUT | HWMON_I_LABEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) HWMON_I_INPUT | HWMON_I_LABEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) HWMON_I_INPUT | HWMON_I_LABEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) HWMON_I_INPUT | HWMON_I_LABEL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) #endif /* !CONFIG_SENSORS_BT1_PVT_ALARMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static inline bool pvt_hwmon_channel_is_valid(enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) case hwmon_temp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (ch < 0 || ch >= PVT_TEMP_CHS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) case hwmon_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (ch < 0 || ch >= PVT_VOLT_CHS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* The rest of the types are independent from the channel number. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static umode_t pvt_hwmon_is_visible(const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) u32 attr, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (!pvt_hwmon_channel_is_valid(type, ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) case hwmon_chip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) case hwmon_chip_update_interval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return 0644;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) case hwmon_temp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) case hwmon_temp_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) case hwmon_temp_type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) case hwmon_temp_label:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) case hwmon_temp_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) case hwmon_temp_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return pvt_limit_is_visible(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) case hwmon_temp_min_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) case hwmon_temp_max_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return pvt_alarm_is_visible(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) case hwmon_temp_offset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return 0644;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) case hwmon_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) case hwmon_in_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) case hwmon_in_label:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) case hwmon_in_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) case hwmon_in_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return pvt_limit_is_visible(PVT_VOLT + ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case hwmon_in_min_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) case hwmon_in_max_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return pvt_alarm_is_visible(PVT_VOLT + ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static int pvt_read_trim(struct pvt_hwmon *pvt, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) data = readl(pvt->regs + PVT_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) *val = FIELD_GET(PVT_CTRL_TRIM_MASK, data) * PVT_TRIM_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static int pvt_write_trim(struct pvt_hwmon *pvt, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) u32 trim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * Serialize trim update, since a part of the register is changed and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * the controller is supposed to be disabled during this operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ret = mutex_lock_interruptible(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) trim = pvt_calc_trim(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) pvt_set_trim(pvt, trim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) mutex_unlock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static int pvt_read_timeout(struct pvt_hwmon *pvt, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ret = mutex_lock_interruptible(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /* Return the result in msec as hwmon sysfs interface requires. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) *val = ktime_to_ms(pvt->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) mutex_unlock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static int pvt_write_timeout(struct pvt_hwmon *pvt, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) ktime_t kt, cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) rate = clk_get_rate(pvt->clks[PVT_CLOCK_REF].clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * If alarms are enabled, the requested timeout must be divided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * between all available sensors to have the requested delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * applicable to each individual sensor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) cache = kt = ms_to_ktime(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) #if defined(CONFIG_SENSORS_BT1_PVT_ALARMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) kt = ktime_divns(kt, PVT_SENSORS_NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * Subtract a constant lag, which always persists due to the limited
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * PVT sampling rate. Make sure the timeout is not negative.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) kt = ktime_sub_ns(kt, PVT_TOUT_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (ktime_to_ns(kt) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) kt = ktime_set(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * Finally recalculate the timeout in terms of the reference clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * period.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) data = ktime_divns(kt * rate, NSEC_PER_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * Update the measurements delay, but lock the interface first, since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * we have to disable PVT in order to have the new delay actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ret = mutex_lock_interruptible(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) pvt_set_tout(pvt, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) pvt->timeout = cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) mutex_unlock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static int pvt_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) u32 attr, int ch, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct pvt_hwmon *pvt = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (!pvt_hwmon_channel_is_valid(type, ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) case hwmon_chip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) case hwmon_chip_update_interval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return pvt_read_timeout(pvt, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) case hwmon_temp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case hwmon_temp_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return pvt_read_data(pvt, ch, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) case hwmon_temp_type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) *val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) case hwmon_temp_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return pvt_read_limit(pvt, ch, true, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) case hwmon_temp_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return pvt_read_limit(pvt, ch, false, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) case hwmon_temp_min_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return pvt_read_alarm(pvt, ch, true, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) case hwmon_temp_max_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return pvt_read_alarm(pvt, ch, false, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) case hwmon_temp_offset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return pvt_read_trim(pvt, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) case hwmon_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) case hwmon_in_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return pvt_read_data(pvt, PVT_VOLT + ch, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) case hwmon_in_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return pvt_read_limit(pvt, PVT_VOLT + ch, true, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) case hwmon_in_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return pvt_read_limit(pvt, PVT_VOLT + ch, false, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) case hwmon_in_min_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return pvt_read_alarm(pvt, PVT_VOLT + ch, true, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) case hwmon_in_max_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return pvt_read_alarm(pvt, PVT_VOLT + ch, false, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static int pvt_hwmon_read_string(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) u32 attr, int ch, const char **str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (!pvt_hwmon_channel_is_valid(type, ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) case hwmon_temp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) case hwmon_temp_label:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) *str = pvt_info[ch].label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) case hwmon_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) case hwmon_in_label:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) *str = pvt_info[PVT_VOLT + ch].label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) static int pvt_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) u32 attr, int ch, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct pvt_hwmon *pvt = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (!pvt_hwmon_channel_is_valid(type, ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) case hwmon_chip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) case hwmon_chip_update_interval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return pvt_write_timeout(pvt, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) case hwmon_temp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) case hwmon_temp_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return pvt_write_limit(pvt, ch, true, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) case hwmon_temp_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return pvt_write_limit(pvt, ch, false, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) case hwmon_temp_offset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return pvt_write_trim(pvt, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) case hwmon_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case hwmon_in_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return pvt_write_limit(pvt, PVT_VOLT + ch, true, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) case hwmon_in_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return pvt_write_limit(pvt, PVT_VOLT + ch, false, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static const struct hwmon_ops pvt_hwmon_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) .is_visible = pvt_hwmon_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) .read = pvt_hwmon_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) .read_string = pvt_hwmon_read_string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) .write = pvt_hwmon_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static const struct hwmon_chip_info pvt_hwmon_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .ops = &pvt_hwmon_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) .info = pvt_channel_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static void pvt_clear_data(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct pvt_hwmon *pvt = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) #if !defined(CONFIG_SENSORS_BT1_PVT_ALARMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) for (idx = 0; idx < PVT_SENSORS_NUM; ++idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) complete_all(&pvt->cache[idx].conversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) mutex_destroy(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static struct pvt_hwmon *pvt_create_data(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct pvt_hwmon *pvt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) int ret, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) pvt = devm_kzalloc(dev, sizeof(*pvt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (!pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) ret = devm_add_action(dev, pvt_clear_data, pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) dev_err(dev, "Can't add PVT data clear action\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) pvt->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) pvt->sensor = PVT_SENSOR_FIRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) mutex_init(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) #if defined(CONFIG_SENSORS_BT1_PVT_ALARMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) for (idx = 0; idx < PVT_SENSORS_NUM; ++idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) seqlock_init(&pvt->cache[idx].data_seqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) for (idx = 0; idx < PVT_SENSORS_NUM; ++idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) init_completion(&pvt->cache[idx].conversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return pvt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static int pvt_request_regs(struct pvt_hwmon *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct platform_device *pdev = to_platform_device(pvt->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) dev_err(pvt->dev, "Couldn't find PVT memresource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) pvt->regs = devm_ioremap_resource(pvt->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (IS_ERR(pvt->regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) dev_err(pvt->dev, "Couldn't map PVT registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return PTR_ERR(pvt->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) static void pvt_disable_clks(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct pvt_hwmon *pvt = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) clk_bulk_disable_unprepare(PVT_CLOCK_NUM, pvt->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) static int pvt_request_clks(struct pvt_hwmon *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) pvt->clks[PVT_CLOCK_APB].id = "pclk";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) pvt->clks[PVT_CLOCK_REF].id = "ref";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ret = devm_clk_bulk_get(pvt->dev, PVT_CLOCK_NUM, pvt->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) dev_err(pvt->dev, "Couldn't get PVT clocks descriptors\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) ret = clk_bulk_prepare_enable(PVT_CLOCK_NUM, pvt->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) dev_err(pvt->dev, "Couldn't enable the PVT clocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) ret = devm_add_action_or_reset(pvt->dev, pvt_disable_clks, pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) dev_err(pvt->dev, "Can't add PVT clocks disable action\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static int pvt_check_pwr(struct pvt_hwmon *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) unsigned long tout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * Test out the sensor conversion functionality. If it is not done on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * time then the domain must have been unpowered and we won't be able
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) * to use the device later in this driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * Note If the power source is lost during the normal driver work the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * data read procedure will either return -ETIMEDOUT (for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) * alarm-less driver configuration) or just stop the repeated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * conversion. In the later case alas we won't be able to detect the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * problem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_ALL, PVT_INTR_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) pvt_set_tout(pvt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) readl(pvt->regs + PVT_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) tout = PVT_TOUT_MIN / NSEC_PER_USEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) usleep_range(tout, 2 * tout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) data = readl(pvt->regs + PVT_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (!(data & PVT_DATA_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) dev_err(pvt->dev, "Sensor is powered down\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static int pvt_init_iface(struct pvt_hwmon *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) u32 trim, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) rate = clk_get_rate(pvt->clks[PVT_CLOCK_REF].clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) dev_err(pvt->dev, "Invalid reference clock rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * Make sure all interrupts and controller are disabled so not to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * accidentally have ISR executed before the driver data is fully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) * initialized. Clear the IRQ status as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_ALL, PVT_INTR_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) readl(pvt->regs + PVT_CLR_INTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) readl(pvt->regs + PVT_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* Setup default sensor mode, timeout and temperature trim. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) pvt_set_mode(pvt, pvt_info[pvt->sensor].mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) pvt_set_tout(pvt, PVT_TOUT_DEF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * Preserve the current ref-clock based delay (Ttotal) between the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * sensors data samples in the driver data so not to recalculate it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * each time on the data requests and timeout reads. It consists of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * delay introduced by the internal ref-clock timer (N / Fclk) and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * constant timeout caused by each conversion latency (Tmin):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * Ttotal = N / Fclk + Tmin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * If alarms are enabled the sensors are polled one after another and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * in order to get the next measurement of a particular sensor the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * caller will have to wait for at most until all the others are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * polled. In that case the formulae will look a bit different:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * Ttotal = 5 * (N / Fclk + Tmin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) #if defined(CONFIG_SENSORS_BT1_PVT_ALARMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) pvt->timeout = ktime_set(PVT_SENSORS_NUM * PVT_TOUT_DEF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) pvt->timeout = ktime_divns(pvt->timeout, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) pvt->timeout = ktime_add_ns(pvt->timeout, PVT_SENSORS_NUM * PVT_TOUT_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) pvt->timeout = ktime_set(PVT_TOUT_DEF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) pvt->timeout = ktime_divns(pvt->timeout, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) pvt->timeout = ktime_add_ns(pvt->timeout, PVT_TOUT_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) trim = PVT_TRIM_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (!of_property_read_u32(pvt->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) "baikal,pvt-temp-offset-millicelsius", &temp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) trim = pvt_calc_trim(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) pvt_set_trim(pvt, trim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static int pvt_request_irq(struct pvt_hwmon *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct platform_device *pdev = to_platform_device(pvt->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) pvt->irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (pvt->irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) return pvt->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) ret = devm_request_threaded_irq(pvt->dev, pvt->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) pvt_hard_isr, pvt_soft_isr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) #if defined(CONFIG_SENSORS_BT1_PVT_ALARMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) IRQF_SHARED | IRQF_TRIGGER_HIGH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) IRQF_SHARED | IRQF_TRIGGER_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) "pvt", pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) dev_err(pvt->dev, "Couldn't request PVT IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) static int pvt_create_hwmon(struct pvt_hwmon *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) pvt->hwmon = devm_hwmon_device_register_with_info(pvt->dev, "pvt", pvt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) &pvt_hwmon_info, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (IS_ERR(pvt->hwmon)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) dev_err(pvt->dev, "Couldn't create hwmon device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return PTR_ERR(pvt->hwmon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) #if defined(CONFIG_SENSORS_BT1_PVT_ALARMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) static void pvt_disable_iface(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct pvt_hwmon *pvt = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) mutex_lock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) PVT_INTR_DVALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) mutex_unlock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) static int pvt_enable_iface(struct pvt_hwmon *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ret = devm_add_action(pvt->dev, pvt_disable_iface, pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) dev_err(pvt->dev, "Can't add PVT disable interface action\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * Enable sensors data conversion and IRQ. We need to lock the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * interface mutex since hwmon has just been created and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * corresponding sysfs files are accessible from user-space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * which theoretically may cause races.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) mutex_lock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_DVALID, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) mutex_unlock(&pvt->iface_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) #else /* !CONFIG_SENSORS_BT1_PVT_ALARMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) static int pvt_enable_iface(struct pvt_hwmon *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) #endif /* !CONFIG_SENSORS_BT1_PVT_ALARMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) static int pvt_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct pvt_hwmon *pvt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) pvt = pvt_create_data(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (IS_ERR(pvt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return PTR_ERR(pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) ret = pvt_request_regs(pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ret = pvt_request_clks(pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) ret = pvt_check_pwr(pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) ret = pvt_init_iface(pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) ret = pvt_request_irq(pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) ret = pvt_create_hwmon(pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ret = pvt_enable_iface(pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) static const struct of_device_id pvt_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) { .compatible = "baikal,bt1-pvt" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) MODULE_DEVICE_TABLE(of, pvt_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static struct platform_driver pvt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) .probe = pvt_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) .name = "bt1-pvt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) .of_match_table = pvt_of_match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) module_platform_driver(pvt_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) MODULE_AUTHOR("Maxim Kaurkin <maxim.kaurkin@baikalelectronics.ru>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) MODULE_DESCRIPTION("Baikal-T1 PVT driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) MODULE_LICENSE("GPL v2");