xref: /OK3568_Linux_fs/kernel/drivers/hwmon/bt1-pvt.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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