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