1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2014-2016, Fuzhou Rockchip Electronics Co., Ltd
4*4882a593Smuzhiyun * Caesar Wang <wxt@rock-chips.com>
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <linux/clk.h>
8*4882a593Smuzhiyun #include <linux/delay.h>
9*4882a593Smuzhiyun #include <linux/interrupt.h>
10*4882a593Smuzhiyun #include <linux/io.h>
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <linux/of.h>
13*4882a593Smuzhiyun #include <linux/of_address.h>
14*4882a593Smuzhiyun #include <linux/of_irq.h>
15*4882a593Smuzhiyun #include <linux/platform_device.h>
16*4882a593Smuzhiyun #include <linux/regmap.h>
17*4882a593Smuzhiyun #include <linux/reset.h>
18*4882a593Smuzhiyun #include <linux/rockchip/cpu.h>
19*4882a593Smuzhiyun #include <linux/thermal.h>
20*4882a593Smuzhiyun #include <linux/mfd/syscon.h>
21*4882a593Smuzhiyun #include <linux/pinctrl/consumer.h>
22*4882a593Smuzhiyun #include <linux/nvmem-consumer.h>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun /*
25*4882a593Smuzhiyun * If the temperature over a period of time High,
26*4882a593Smuzhiyun * the resulting TSHUT gave CRU module,let it reset the entire chip,
27*4882a593Smuzhiyun * or via GPIO give PMIC.
28*4882a593Smuzhiyun */
29*4882a593Smuzhiyun enum tshut_mode {
30*4882a593Smuzhiyun TSHUT_MODE_CRU = 0,
31*4882a593Smuzhiyun TSHUT_MODE_OTP,
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /*
35*4882a593Smuzhiyun * The system Temperature Sensors tshut(tshut) polarity
36*4882a593Smuzhiyun * the bit 8 is tshut polarity.
37*4882a593Smuzhiyun * 0: low active, 1: high active
38*4882a593Smuzhiyun */
39*4882a593Smuzhiyun enum tshut_polarity {
40*4882a593Smuzhiyun TSHUT_LOW_ACTIVE = 0,
41*4882a593Smuzhiyun TSHUT_HIGH_ACTIVE,
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /*
45*4882a593Smuzhiyun * The system has two Temperature Sensors.
46*4882a593Smuzhiyun * sensor0 is for CPU, and sensor1 is for GPU.
47*4882a593Smuzhiyun */
48*4882a593Smuzhiyun enum sensor_id {
49*4882a593Smuzhiyun SENSOR_CPU = 0,
50*4882a593Smuzhiyun SENSOR_GPU,
51*4882a593Smuzhiyun };
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun * The conversion table has the adc value and temperature.
55*4882a593Smuzhiyun * ADC_DECREMENT: the adc value is of diminishing.(e.g. rk3288_code_table)
56*4882a593Smuzhiyun * ADC_INCREMENT: the adc value is incremental.(e.g. rk3368_code_table)
57*4882a593Smuzhiyun */
58*4882a593Smuzhiyun enum adc_sort_mode {
59*4882a593Smuzhiyun ADC_DECREMENT = 0,
60*4882a593Smuzhiyun ADC_INCREMENT,
61*4882a593Smuzhiyun };
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun #include "thermal_hwmon.h"
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /**
66*4882a593Smuzhiyun * The max sensors is seven in rockchip SoCs.
67*4882a593Smuzhiyun */
68*4882a593Smuzhiyun #define SOC_MAX_SENSORS 7
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /**
71*4882a593Smuzhiyun * struct chip_tsadc_table - hold information about chip-specific differences
72*4882a593Smuzhiyun * @id: conversion table
73*4882a593Smuzhiyun * @length: size of conversion table
74*4882a593Smuzhiyun * @data_mask: mask to apply on data inputs
75*4882a593Smuzhiyun * @kNum: linear parameter k
76*4882a593Smuzhiyun * @bNum: linear parameter b
77*4882a593Smuzhiyun * @mode: sort mode of this adc variant (incrementing or decrementing)
78*4882a593Smuzhiyun */
79*4882a593Smuzhiyun struct chip_tsadc_table {
80*4882a593Smuzhiyun const struct tsadc_table *id;
81*4882a593Smuzhiyun unsigned int length;
82*4882a593Smuzhiyun u32 data_mask;
83*4882a593Smuzhiyun /* Tsadc is linear, using linear parameters */
84*4882a593Smuzhiyun int kNum;
85*4882a593Smuzhiyun int bNum;
86*4882a593Smuzhiyun enum adc_sort_mode mode;
87*4882a593Smuzhiyun };
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /**
90*4882a593Smuzhiyun * struct rockchip_tsadc_chip - hold the private data of tsadc chip
91*4882a593Smuzhiyun * @chn_id: array of sensor ids of chip corresponding to the channel
92*4882a593Smuzhiyun * @chn_num: the channel number of tsadc chip
93*4882a593Smuzhiyun * @conversion_time: the conversion time of tsadc
94*4882a593Smuzhiyun * @trim_slope: use to conversion trim code to trim temp
95*4882a593Smuzhiyun * @tshut_temp: the hardware-controlled shutdown temperature value
96*4882a593Smuzhiyun * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO)
97*4882a593Smuzhiyun * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
98*4882a593Smuzhiyun * @initialize: SoC special initialize tsadc controller method
99*4882a593Smuzhiyun * @irq_ack: clear the interrupt
100*4882a593Smuzhiyun * @control: enable/disable method for the tsadc controller
101*4882a593Smuzhiyun * @get_temp: get the temperature
102*4882a593Smuzhiyun * @set_alarm_temp: set the high temperature interrupt
103*4882a593Smuzhiyun * @set_tshut_temp: set the hardware-controlled shutdown temperature
104*4882a593Smuzhiyun * @set_tshut_mode: set the hardware-controlled shutdown mode
105*4882a593Smuzhiyun * @get_trim_code: get the trim code by otp value
106*4882a593Smuzhiyun * @set_clk_rate: set clock rate
107*4882a593Smuzhiyun * @table: the chip-specific conversion table
108*4882a593Smuzhiyun */
109*4882a593Smuzhiyun struct rockchip_tsadc_chip {
110*4882a593Smuzhiyun /* The sensor id of chip correspond to the ADC channel */
111*4882a593Smuzhiyun int chn_id[SOC_MAX_SENSORS];
112*4882a593Smuzhiyun int chn_num;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun /* The sensor electrical characteristics */
115*4882a593Smuzhiyun int conversion_time;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun /* Use to conversion trim code to trim temp */
118*4882a593Smuzhiyun int trim_slope;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun /* The hardware-controlled tshut property */
121*4882a593Smuzhiyun int tshut_temp;
122*4882a593Smuzhiyun enum tshut_mode tshut_mode;
123*4882a593Smuzhiyun enum tshut_polarity tshut_polarity;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun /* Chip-wide methods */
126*4882a593Smuzhiyun void (*initialize)(struct regmap *grf,
127*4882a593Smuzhiyun void __iomem *reg, enum tshut_polarity p);
128*4882a593Smuzhiyun void (*irq_ack)(void __iomem *reg);
129*4882a593Smuzhiyun void (*control)(void __iomem *reg, bool on);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun /* Per-sensor methods */
132*4882a593Smuzhiyun int (*get_temp)(const struct chip_tsadc_table *table,
133*4882a593Smuzhiyun int chn, void __iomem *reg, int *temp);
134*4882a593Smuzhiyun int (*set_alarm_temp)(const struct chip_tsadc_table *table,
135*4882a593Smuzhiyun int chn, void __iomem *reg, int temp);
136*4882a593Smuzhiyun int (*set_tshut_temp)(const struct chip_tsadc_table *table,
137*4882a593Smuzhiyun int chn, void __iomem *reg, int temp);
138*4882a593Smuzhiyun void (*set_tshut_mode)(struct regmap *grf, int chn,
139*4882a593Smuzhiyun void __iomem *reg, enum tshut_mode m);
140*4882a593Smuzhiyun int (*get_trim_code)(const struct chip_tsadc_table *table,
141*4882a593Smuzhiyun int code, int trim_base, int trim_base_frac);
142*4882a593Smuzhiyun int (*set_clk_rate)(struct platform_device *pdev);
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun /* Per-table methods */
145*4882a593Smuzhiyun struct chip_tsadc_table table;
146*4882a593Smuzhiyun };
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun /**
149*4882a593Smuzhiyun * struct rockchip_thermal_sensor - hold the information of thermal sensor
150*4882a593Smuzhiyun * @thermal: pointer to the platform/configuration data
151*4882a593Smuzhiyun * @tzd: pointer to a thermal zone
152*4882a593Smuzhiyun * @id: identifier of the thermal sensor
153*4882a593Smuzhiyun * @trim_temp: the trim temp of the thermal sensor
154*4882a593Smuzhiyun * @tshut_temp: the hardware-controlled shutdown temperature value
155*4882a593Smuzhiyun */
156*4882a593Smuzhiyun struct rockchip_thermal_sensor {
157*4882a593Smuzhiyun struct rockchip_thermal_data *thermal;
158*4882a593Smuzhiyun struct thermal_zone_device *tzd;
159*4882a593Smuzhiyun int id;
160*4882a593Smuzhiyun int trim_temp;
161*4882a593Smuzhiyun int tshut_temp;
162*4882a593Smuzhiyun };
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /**
165*4882a593Smuzhiyun * struct rockchip_thermal_data - hold the private data of thermal driver
166*4882a593Smuzhiyun * @chip: pointer to the platform/configuration data
167*4882a593Smuzhiyun * @pdev: platform device of thermal
168*4882a593Smuzhiyun * @reset: the reset controller of tsadc
169*4882a593Smuzhiyun * @sensors: array of thermal sensors
170*4882a593Smuzhiyun * @clk: the bulk clk of tsadc, include controller clock and peripherals bus clock
171*4882a593Smuzhiyun * @num_clks: the number of tsadc clks
172*4882a593Smuzhiyun * @grf: the general register file will be used to do static set by software
173*4882a593Smuzhiyun * @regs: the base address of tsadc controller
174*4882a593Smuzhiyun * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO)
175*4882a593Smuzhiyun * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
176*4882a593Smuzhiyun * @pinctrl: the pinctrl of tsadc
177*4882a593Smuzhiyun * @gpio_state: pinctrl select gpio function
178*4882a593Smuzhiyun * @otp_state: pinctrl select otp out function
179*4882a593Smuzhiyun * @panic_nb: panic notifier block
180*4882a593Smuzhiyun */
181*4882a593Smuzhiyun struct rockchip_thermal_data {
182*4882a593Smuzhiyun const struct rockchip_tsadc_chip *chip;
183*4882a593Smuzhiyun struct platform_device *pdev;
184*4882a593Smuzhiyun struct reset_control *reset;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun struct rockchip_thermal_sensor sensors[SOC_MAX_SENSORS];
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun struct clk_bulk_data *clks;
189*4882a593Smuzhiyun int num_clks;
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun struct regmap *grf;
192*4882a593Smuzhiyun void __iomem *regs;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun enum tshut_mode tshut_mode;
195*4882a593Smuzhiyun enum tshut_polarity tshut_polarity;
196*4882a593Smuzhiyun struct pinctrl *pinctrl;
197*4882a593Smuzhiyun struct pinctrl_state *gpio_state;
198*4882a593Smuzhiyun struct pinctrl_state *otp_state;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun struct notifier_block panic_nb;
201*4882a593Smuzhiyun };
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun /**
204*4882a593Smuzhiyun * TSADC Sensor Register description:
205*4882a593Smuzhiyun *
206*4882a593Smuzhiyun * TSADCV2_* are used for RK3288 SoCs, the other chips can reuse it.
207*4882a593Smuzhiyun * TSADCV3_* are used for newer SoCs than RK3288. (e.g: RK3228, RK3399)
208*4882a593Smuzhiyun *
209*4882a593Smuzhiyun */
210*4882a593Smuzhiyun #define TSADCV2_USER_CON 0x00
211*4882a593Smuzhiyun #define TSADCV2_AUTO_CON 0x04
212*4882a593Smuzhiyun #define TSADCV2_INT_EN 0x08
213*4882a593Smuzhiyun #define TSADCV2_INT_PD 0x0c
214*4882a593Smuzhiyun #define TSADCV3_AUTO_SRC_CON 0x0c
215*4882a593Smuzhiyun #define TSADCV3_HT_INT_EN 0x14
216*4882a593Smuzhiyun #define TSADCV3_HSHUT_GPIO_INT_EN 0x18
217*4882a593Smuzhiyun #define TSADCV3_HSHUT_CRU_INT_EN 0x1c
218*4882a593Smuzhiyun #define TSADCV3_INT_PD 0x24
219*4882a593Smuzhiyun #define TSADCV3_HSHUT_PD 0x28
220*4882a593Smuzhiyun #define TSADCV2_DATA(chn) (0x20 + (chn) * 0x04)
221*4882a593Smuzhiyun #define TSADCV2_COMP_INT(chn) (0x30 + (chn) * 0x04)
222*4882a593Smuzhiyun #define TSADCV2_COMP_SHUT(chn) (0x40 + (chn) * 0x04)
223*4882a593Smuzhiyun #define TSADCV3_DATA(chn) (0x2c + (chn) * 0x04)
224*4882a593Smuzhiyun #define TSADCV3_COMP_INT(chn) (0x6c + (chn) * 0x04)
225*4882a593Smuzhiyun #define TSADCV3_COMP_SHUT(chn) (0x10c + (chn) * 0x04)
226*4882a593Smuzhiyun #define TSADCV2_HIGHT_INT_DEBOUNCE 0x60
227*4882a593Smuzhiyun #define TSADCV2_HIGHT_TSHUT_DEBOUNCE 0x64
228*4882a593Smuzhiyun #define TSADCV3_HIGHT_INT_DEBOUNCE 0x14c
229*4882a593Smuzhiyun #define TSADCV3_HIGHT_TSHUT_DEBOUNCE 0x150
230*4882a593Smuzhiyun #define TSADCV2_AUTO_PERIOD 0x68
231*4882a593Smuzhiyun #define TSADCV2_AUTO_PERIOD_HT 0x6c
232*4882a593Smuzhiyun #define TSADCV3_AUTO_PERIOD 0x154
233*4882a593Smuzhiyun #define TSADCV3_AUTO_PERIOD_HT 0x158
234*4882a593Smuzhiyun #define TSADCV9_Q_MAX 0x210
235*4882a593Smuzhiyun #define TSADCV9_FLOW_CON 0x218
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun #define TSADCV2_AUTO_EN BIT(0)
238*4882a593Smuzhiyun #define TSADCV2_AUTO_EN_MASK BIT(16)
239*4882a593Smuzhiyun #define TSADCV2_AUTO_SRC_EN(chn) BIT(4 + (chn))
240*4882a593Smuzhiyun #define TSADCV3_AUTO_SRC_EN(chn) BIT(chn)
241*4882a593Smuzhiyun #define TSADCV3_AUTO_SRC_EN_MASK(chn) BIT(16 + chn)
242*4882a593Smuzhiyun #define TSADCV2_AUTO_TSHUT_POLARITY_HIGH BIT(8)
243*4882a593Smuzhiyun #define TSADCV2_AUTO_TSHUT_POLARITY_MASK BIT(24)
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun #define TSADCV3_AUTO_Q_SEL_EN BIT(1)
246*4882a593Smuzhiyun #define TSADCV3_AUTO_Q_SEL_EN_MASK BIT(17)
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun #define TSADCV2_INT_SRC_EN(chn) BIT(chn)
249*4882a593Smuzhiyun #define TSADCV2_INT_SRC_EN_MASK(chn) BIT(16 + (chn))
250*4882a593Smuzhiyun #define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn))
251*4882a593Smuzhiyun #define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn))
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun #define TSADCV2_INT_PD_CLEAR_MASK ~BIT(8)
254*4882a593Smuzhiyun #define TSADCV3_INT_PD_CLEAR_MASK ~BIT(16)
255*4882a593Smuzhiyun #define TSADCV4_INT_PD_CLEAR_MASK 0xffffffff
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun #define TSADCV2_DATA_MASK 0xfff
258*4882a593Smuzhiyun #define TSADCV3_DATA_MASK 0x3ff
259*4882a593Smuzhiyun #define TSADCV4_DATA_MASK 0x1ff
260*4882a593Smuzhiyun #define TSADCV5_DATA_MASK 0x7ff
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4
263*4882a593Smuzhiyun #define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4
264*4882a593Smuzhiyun #define TSADCV2_AUTO_PERIOD_TIME 250 /* 250ms */
265*4882a593Smuzhiyun #define TSADCV2_AUTO_PERIOD_HT_TIME 50 /* 50ms */
266*4882a593Smuzhiyun #define TSADCV3_AUTO_PERIOD_TIME 1875 /* 2.5ms */
267*4882a593Smuzhiyun #define TSADCV3_AUTO_PERIOD_HT_TIME 1875 /* 2.5ms */
268*4882a593Smuzhiyun #define TSADCV5_AUTO_PERIOD_TIME 1622 /* 2.5ms */
269*4882a593Smuzhiyun #define TSADCV5_AUTO_PERIOD_HT_TIME 1622 /* 2.5ms */
270*4882a593Smuzhiyun #define TSADCV6_AUTO_PERIOD_TIME 5000 /* 2.5ms */
271*4882a593Smuzhiyun #define TSADCV6_AUTO_PERIOD_HT_TIME 5000 /* 2.5ms */
272*4882a593Smuzhiyun #define TSADCV7_AUTO_PERIOD_TIME 3000 /* 2.5ms */
273*4882a593Smuzhiyun #define TSADCV7_AUTO_PERIOD_HT_TIME 3000 /* 2.5ms */
274*4882a593Smuzhiyun #define TSADCV12_AUTO_PERIOD_TIME 3000 /* 2.5ms */
275*4882a593Smuzhiyun #define TSADCV12_AUTO_PERIOD_HT_TIME 3000 /* 2.5ms */
276*4882a593Smuzhiyun #define TSADCV3_Q_MAX_VAL 0x7ff /* 11bit 2047 */
277*4882a593Smuzhiyun #define TSADCV12_Q_MAX_VAL 0xfff /* 12bit 4095 */
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun #define TSADCV2_USER_INTER_PD_SOC 0x340 /* 13 clocks */
280*4882a593Smuzhiyun #define TSADCV5_USER_INTER_PD_SOC 0xfc0 /* 97us, at least 90us */
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun #define TSADCV9_AUTO_SRC (0x10001 << 0)
283*4882a593Smuzhiyun #define TSADCV9_PD_MODE (0x10001 << 4)
284*4882a593Smuzhiyun #define TSADCV9_Q_MAX_VAL (0xffff0400 << 0)
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun #define GRF_SARADC_TESTBIT 0x0e644
287*4882a593Smuzhiyun #define GRF_TSADC_TESTBIT_L 0x0e648
288*4882a593Smuzhiyun #define GRF_TSADC_TESTBIT_H 0x0e64c
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun #define PX30_GRF_SOC_CON0 0x0400
291*4882a593Smuzhiyun #define PX30_GRF_SOC_CON2 0x0408
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun #define RK1808_BUS_GRF_SOC_CON0 0x0400
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun #define RK3528_GRF_TSADC_CON 0x40030
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun #define RK3562_GRF_TSADC_CON 0x0580
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun #define RK3568_GRF_TSADC_CON 0x0600
300*4882a593Smuzhiyun #define RK3568_GRF_TSADC_ANA_REG0 (0x10001 << 0)
301*4882a593Smuzhiyun #define RK3568_GRF_TSADC_ANA_REG1 (0x10001 << 1)
302*4882a593Smuzhiyun #define RK3568_GRF_TSADC_ANA_REG2 (0x10001 << 2)
303*4882a593Smuzhiyun #define RK3568_GRF_TSADC_TSEN (0x10001 << 8)
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun #define RV1106_VOGRF_TSADC_CON 0x6000C
306*4882a593Smuzhiyun #define RV1106_VOGRF_TSADC_TSEN (0x10001 << 8)
307*4882a593Smuzhiyun #define RV1106_VOGRF_TSADC_ANA (0xff0007 << 0)
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun #define RV1126_GRF0_TSADC_CON 0x0100
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun #define RV1126_GRF0_TSADC_TRM (0xff0077 << 0)
312*4882a593Smuzhiyun #define RV1126_GRF0_TSADC_SHUT_2CRU (0x30003 << 10)
313*4882a593Smuzhiyun #define RV1126_GRF0_TSADC_SHUT_2GPIO (0x70007 << 12)
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun #define GRF_SARADC_TESTBIT_ON (0x10001 << 2)
316*4882a593Smuzhiyun #define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2)
317*4882a593Smuzhiyun #define GRF_TSADC_BANDGAP_CHOPPER_EN (0x10001 << 2)
318*4882a593Smuzhiyun #define GRF_TSADC_VCM_EN_L (0x10001 << 7)
319*4882a593Smuzhiyun #define GRF_TSADC_VCM_EN_H (0x10001 << 7)
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun #define GRF_CON_TSADC_CH_INV (0x10001 << 1)
322*4882a593Smuzhiyun #define PX30S_TSADC_TDC_MODE (0x10001 << 4)
323*4882a593Smuzhiyun #define PX30S_TSADC_TRIM (0xf0007 << 0)
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun /* -40 to 125 is reliable, outside the range existed unreliability */
327*4882a593Smuzhiyun #define MIN_TEMP (-60000)
328*4882a593Smuzhiyun #define MAX_TEMP (180000)
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun /**
331*4882a593Smuzhiyun * struct tsadc_table - code to temperature conversion table
332*4882a593Smuzhiyun * @code: the value of adc channel
333*4882a593Smuzhiyun * @temp: the temperature
334*4882a593Smuzhiyun * Note:
335*4882a593Smuzhiyun * code to temperature mapping of the temperature sensor is a piece wise linear
336*4882a593Smuzhiyun * curve.Any temperature, code faling between to 2 give temperatures can be
337*4882a593Smuzhiyun * linearly interpolated.
338*4882a593Smuzhiyun * Code to Temperature mapping should be updated based on manufacturer results.
339*4882a593Smuzhiyun */
340*4882a593Smuzhiyun struct tsadc_table {
341*4882a593Smuzhiyun u32 code;
342*4882a593Smuzhiyun int temp;
343*4882a593Smuzhiyun };
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun static const struct tsadc_table rv1106_code_table[] = {
346*4882a593Smuzhiyun {0, MIN_TEMP},
347*4882a593Smuzhiyun {363, MIN_TEMP},
348*4882a593Smuzhiyun {396, -40000},
349*4882a593Smuzhiyun {504, 25000},
350*4882a593Smuzhiyun {605, 85000},
351*4882a593Smuzhiyun {673, 125000},
352*4882a593Smuzhiyun {758, MAX_TEMP},
353*4882a593Smuzhiyun {TSADCV2_DATA_MASK, MAX_TEMP},
354*4882a593Smuzhiyun };
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun static const struct tsadc_table rv1108_table[] = {
357*4882a593Smuzhiyun {0, MIN_TEMP},
358*4882a593Smuzhiyun {342, MIN_TEMP},
359*4882a593Smuzhiyun {374, -40000},
360*4882a593Smuzhiyun {382, -35000},
361*4882a593Smuzhiyun {389, -30000},
362*4882a593Smuzhiyun {397, -25000},
363*4882a593Smuzhiyun {405, -20000},
364*4882a593Smuzhiyun {413, -15000},
365*4882a593Smuzhiyun {421, -10000},
366*4882a593Smuzhiyun {429, -5000},
367*4882a593Smuzhiyun {436, 0},
368*4882a593Smuzhiyun {444, 5000},
369*4882a593Smuzhiyun {452, 10000},
370*4882a593Smuzhiyun {460, 15000},
371*4882a593Smuzhiyun {468, 20000},
372*4882a593Smuzhiyun {476, 25000},
373*4882a593Smuzhiyun {483, 30000},
374*4882a593Smuzhiyun {491, 35000},
375*4882a593Smuzhiyun {499, 40000},
376*4882a593Smuzhiyun {507, 45000},
377*4882a593Smuzhiyun {515, 50000},
378*4882a593Smuzhiyun {523, 55000},
379*4882a593Smuzhiyun {531, 60000},
380*4882a593Smuzhiyun {539, 65000},
381*4882a593Smuzhiyun {547, 70000},
382*4882a593Smuzhiyun {555, 75000},
383*4882a593Smuzhiyun {562, 80000},
384*4882a593Smuzhiyun {570, 85000},
385*4882a593Smuzhiyun {578, 90000},
386*4882a593Smuzhiyun {586, 95000},
387*4882a593Smuzhiyun {594, 100000},
388*4882a593Smuzhiyun {602, 105000},
389*4882a593Smuzhiyun {610, 110000},
390*4882a593Smuzhiyun {618, 115000},
391*4882a593Smuzhiyun {626, 120000},
392*4882a593Smuzhiyun {634, 125000},
393*4882a593Smuzhiyun {722, MAX_TEMP},
394*4882a593Smuzhiyun {TSADCV2_DATA_MASK, MAX_TEMP},
395*4882a593Smuzhiyun };
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun static const struct tsadc_table rk1808_code_table[] = {
398*4882a593Smuzhiyun {0, MIN_TEMP},
399*4882a593Smuzhiyun {3423, MIN_TEMP},
400*4882a593Smuzhiyun {3455, -40000},
401*4882a593Smuzhiyun {3463, -35000},
402*4882a593Smuzhiyun {3471, -30000},
403*4882a593Smuzhiyun {3479, -25000},
404*4882a593Smuzhiyun {3487, -20000},
405*4882a593Smuzhiyun {3495, -15000},
406*4882a593Smuzhiyun {3503, -10000},
407*4882a593Smuzhiyun {3511, -5000},
408*4882a593Smuzhiyun {3519, 0},
409*4882a593Smuzhiyun {3527, 5000},
410*4882a593Smuzhiyun {3535, 10000},
411*4882a593Smuzhiyun {3543, 15000},
412*4882a593Smuzhiyun {3551, 20000},
413*4882a593Smuzhiyun {3559, 25000},
414*4882a593Smuzhiyun {3567, 30000},
415*4882a593Smuzhiyun {3576, 35000},
416*4882a593Smuzhiyun {3584, 40000},
417*4882a593Smuzhiyun {3592, 45000},
418*4882a593Smuzhiyun {3600, 50000},
419*4882a593Smuzhiyun {3609, 55000},
420*4882a593Smuzhiyun {3617, 60000},
421*4882a593Smuzhiyun {3625, 65000},
422*4882a593Smuzhiyun {3633, 70000},
423*4882a593Smuzhiyun {3642, 75000},
424*4882a593Smuzhiyun {3650, 80000},
425*4882a593Smuzhiyun {3659, 85000},
426*4882a593Smuzhiyun {3667, 90000},
427*4882a593Smuzhiyun {3675, 95000},
428*4882a593Smuzhiyun {3684, 100000},
429*4882a593Smuzhiyun {3692, 105000},
430*4882a593Smuzhiyun {3701, 110000},
431*4882a593Smuzhiyun {3709, 115000},
432*4882a593Smuzhiyun {3718, 120000},
433*4882a593Smuzhiyun {3726, 125000},
434*4882a593Smuzhiyun {3820, MAX_TEMP},
435*4882a593Smuzhiyun {TSADCV2_DATA_MASK, MAX_TEMP},
436*4882a593Smuzhiyun };
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun static const struct tsadc_table rk3228_code_table[] = {
439*4882a593Smuzhiyun {0, MIN_TEMP},
440*4882a593Smuzhiyun {568, MIN_TEMP},
441*4882a593Smuzhiyun {588, -40000},
442*4882a593Smuzhiyun {593, -35000},
443*4882a593Smuzhiyun {598, -30000},
444*4882a593Smuzhiyun {603, -25000},
445*4882a593Smuzhiyun {608, -20000},
446*4882a593Smuzhiyun {613, -15000},
447*4882a593Smuzhiyun {618, -10000},
448*4882a593Smuzhiyun {623, -5000},
449*4882a593Smuzhiyun {629, 0},
450*4882a593Smuzhiyun {634, 5000},
451*4882a593Smuzhiyun {639, 10000},
452*4882a593Smuzhiyun {644, 15000},
453*4882a593Smuzhiyun {649, 20000},
454*4882a593Smuzhiyun {654, 25000},
455*4882a593Smuzhiyun {660, 30000},
456*4882a593Smuzhiyun {665, 35000},
457*4882a593Smuzhiyun {670, 40000},
458*4882a593Smuzhiyun {675, 45000},
459*4882a593Smuzhiyun {681, 50000},
460*4882a593Smuzhiyun {686, 55000},
461*4882a593Smuzhiyun {691, 60000},
462*4882a593Smuzhiyun {696, 65000},
463*4882a593Smuzhiyun {702, 70000},
464*4882a593Smuzhiyun {707, 75000},
465*4882a593Smuzhiyun {712, 80000},
466*4882a593Smuzhiyun {717, 85000},
467*4882a593Smuzhiyun {723, 90000},
468*4882a593Smuzhiyun {728, 95000},
469*4882a593Smuzhiyun {733, 100000},
470*4882a593Smuzhiyun {738, 105000},
471*4882a593Smuzhiyun {744, 110000},
472*4882a593Smuzhiyun {749, 115000},
473*4882a593Smuzhiyun {754, 120000},
474*4882a593Smuzhiyun {760, 125000},
475*4882a593Smuzhiyun {821, MAX_TEMP},
476*4882a593Smuzhiyun {TSADCV2_DATA_MASK, MAX_TEMP},
477*4882a593Smuzhiyun };
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun static const struct tsadc_table rk3288_code_table[] = {
480*4882a593Smuzhiyun {TSADCV2_DATA_MASK, MIN_TEMP},
481*4882a593Smuzhiyun {3833, MIN_TEMP},
482*4882a593Smuzhiyun {3800, -40000},
483*4882a593Smuzhiyun {3792, -35000},
484*4882a593Smuzhiyun {3783, -30000},
485*4882a593Smuzhiyun {3774, -25000},
486*4882a593Smuzhiyun {3765, -20000},
487*4882a593Smuzhiyun {3756, -15000},
488*4882a593Smuzhiyun {3747, -10000},
489*4882a593Smuzhiyun {3737, -5000},
490*4882a593Smuzhiyun {3728, 0},
491*4882a593Smuzhiyun {3718, 5000},
492*4882a593Smuzhiyun {3708, 10000},
493*4882a593Smuzhiyun {3698, 15000},
494*4882a593Smuzhiyun {3688, 20000},
495*4882a593Smuzhiyun {3678, 25000},
496*4882a593Smuzhiyun {3667, 30000},
497*4882a593Smuzhiyun {3656, 35000},
498*4882a593Smuzhiyun {3645, 40000},
499*4882a593Smuzhiyun {3634, 45000},
500*4882a593Smuzhiyun {3623, 50000},
501*4882a593Smuzhiyun {3611, 55000},
502*4882a593Smuzhiyun {3600, 60000},
503*4882a593Smuzhiyun {3588, 65000},
504*4882a593Smuzhiyun {3575, 70000},
505*4882a593Smuzhiyun {3563, 75000},
506*4882a593Smuzhiyun {3550, 80000},
507*4882a593Smuzhiyun {3537, 85000},
508*4882a593Smuzhiyun {3524, 90000},
509*4882a593Smuzhiyun {3510, 95000},
510*4882a593Smuzhiyun {3496, 100000},
511*4882a593Smuzhiyun {3482, 105000},
512*4882a593Smuzhiyun {3467, 110000},
513*4882a593Smuzhiyun {3452, 115000},
514*4882a593Smuzhiyun {3437, 120000},
515*4882a593Smuzhiyun {3421, 125000},
516*4882a593Smuzhiyun {3350, 145000},
517*4882a593Smuzhiyun {3270, 165000},
518*4882a593Smuzhiyun {3195, MAX_TEMP},
519*4882a593Smuzhiyun {0, MAX_TEMP},
520*4882a593Smuzhiyun };
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun static const struct tsadc_table rk3328_code_table[] = {
523*4882a593Smuzhiyun {0, MIN_TEMP},
524*4882a593Smuzhiyun {261, MIN_TEMP},
525*4882a593Smuzhiyun {296, -40000},
526*4882a593Smuzhiyun {304, -35000},
527*4882a593Smuzhiyun {313, -30000},
528*4882a593Smuzhiyun {331, -20000},
529*4882a593Smuzhiyun {340, -15000},
530*4882a593Smuzhiyun {349, -10000},
531*4882a593Smuzhiyun {359, -5000},
532*4882a593Smuzhiyun {368, 0},
533*4882a593Smuzhiyun {378, 5000},
534*4882a593Smuzhiyun {388, 10000},
535*4882a593Smuzhiyun {398, 15000},
536*4882a593Smuzhiyun {408, 20000},
537*4882a593Smuzhiyun {418, 25000},
538*4882a593Smuzhiyun {429, 30000},
539*4882a593Smuzhiyun {440, 35000},
540*4882a593Smuzhiyun {451, 40000},
541*4882a593Smuzhiyun {462, 45000},
542*4882a593Smuzhiyun {473, 50000},
543*4882a593Smuzhiyun {485, 55000},
544*4882a593Smuzhiyun {496, 60000},
545*4882a593Smuzhiyun {508, 65000},
546*4882a593Smuzhiyun {521, 70000},
547*4882a593Smuzhiyun {533, 75000},
548*4882a593Smuzhiyun {546, 80000},
549*4882a593Smuzhiyun {559, 85000},
550*4882a593Smuzhiyun {572, 90000},
551*4882a593Smuzhiyun {586, 95000},
552*4882a593Smuzhiyun {600, 100000},
553*4882a593Smuzhiyun {614, 105000},
554*4882a593Smuzhiyun {629, 110000},
555*4882a593Smuzhiyun {644, 115000},
556*4882a593Smuzhiyun {659, 120000},
557*4882a593Smuzhiyun {675, 125000},
558*4882a593Smuzhiyun {745, 145000},
559*4882a593Smuzhiyun {825, 165000},
560*4882a593Smuzhiyun {900, MAX_TEMP},
561*4882a593Smuzhiyun {TSADCV2_DATA_MASK, MAX_TEMP},
562*4882a593Smuzhiyun };
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun static const struct tsadc_table rk3368_code_table[] = {
565*4882a593Smuzhiyun {0, MIN_TEMP},
566*4882a593Smuzhiyun {98, MIN_TEMP},
567*4882a593Smuzhiyun {106, -40000},
568*4882a593Smuzhiyun {108, -35000},
569*4882a593Smuzhiyun {110, -30000},
570*4882a593Smuzhiyun {112, -25000},
571*4882a593Smuzhiyun {114, -20000},
572*4882a593Smuzhiyun {116, -15000},
573*4882a593Smuzhiyun {118, -10000},
574*4882a593Smuzhiyun {120, -5000},
575*4882a593Smuzhiyun {122, 0},
576*4882a593Smuzhiyun {124, 5000},
577*4882a593Smuzhiyun {126, 10000},
578*4882a593Smuzhiyun {128, 15000},
579*4882a593Smuzhiyun {130, 20000},
580*4882a593Smuzhiyun {132, 25000},
581*4882a593Smuzhiyun {134, 30000},
582*4882a593Smuzhiyun {136, 35000},
583*4882a593Smuzhiyun {138, 40000},
584*4882a593Smuzhiyun {140, 45000},
585*4882a593Smuzhiyun {142, 50000},
586*4882a593Smuzhiyun {144, 55000},
587*4882a593Smuzhiyun {146, 60000},
588*4882a593Smuzhiyun {148, 65000},
589*4882a593Smuzhiyun {150, 70000},
590*4882a593Smuzhiyun {152, 75000},
591*4882a593Smuzhiyun {154, 80000},
592*4882a593Smuzhiyun {156, 85000},
593*4882a593Smuzhiyun {158, 90000},
594*4882a593Smuzhiyun {160, 95000},
595*4882a593Smuzhiyun {162, 100000},
596*4882a593Smuzhiyun {163, 105000},
597*4882a593Smuzhiyun {165, 110000},
598*4882a593Smuzhiyun {167, 115000},
599*4882a593Smuzhiyun {169, 120000},
600*4882a593Smuzhiyun {171, 125000},
601*4882a593Smuzhiyun {193, MAX_TEMP},
602*4882a593Smuzhiyun {TSADCV3_DATA_MASK, MAX_TEMP},
603*4882a593Smuzhiyun };
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun static const struct tsadc_table rk3399_code_table[] = {
606*4882a593Smuzhiyun {0, MIN_TEMP},
607*4882a593Smuzhiyun {368, MIN_TEMP},
608*4882a593Smuzhiyun {402, -40000},
609*4882a593Smuzhiyun {410, -35000},
610*4882a593Smuzhiyun {419, -30000},
611*4882a593Smuzhiyun {427, -25000},
612*4882a593Smuzhiyun {436, -20000},
613*4882a593Smuzhiyun {444, -15000},
614*4882a593Smuzhiyun {453, -10000},
615*4882a593Smuzhiyun {461, -5000},
616*4882a593Smuzhiyun {470, 0},
617*4882a593Smuzhiyun {478, 5000},
618*4882a593Smuzhiyun {487, 10000},
619*4882a593Smuzhiyun {496, 15000},
620*4882a593Smuzhiyun {504, 20000},
621*4882a593Smuzhiyun {513, 25000},
622*4882a593Smuzhiyun {521, 30000},
623*4882a593Smuzhiyun {530, 35000},
624*4882a593Smuzhiyun {538, 40000},
625*4882a593Smuzhiyun {547, 45000},
626*4882a593Smuzhiyun {555, 50000},
627*4882a593Smuzhiyun {564, 55000},
628*4882a593Smuzhiyun {573, 60000},
629*4882a593Smuzhiyun {581, 65000},
630*4882a593Smuzhiyun {590, 70000},
631*4882a593Smuzhiyun {599, 75000},
632*4882a593Smuzhiyun {607, 80000},
633*4882a593Smuzhiyun {616, 85000},
634*4882a593Smuzhiyun {624, 90000},
635*4882a593Smuzhiyun {633, 95000},
636*4882a593Smuzhiyun {642, 100000},
637*4882a593Smuzhiyun {650, 105000},
638*4882a593Smuzhiyun {659, 110000},
639*4882a593Smuzhiyun {668, 115000},
640*4882a593Smuzhiyun {677, 120000},
641*4882a593Smuzhiyun {685, 125000},
642*4882a593Smuzhiyun {782, MAX_TEMP},
643*4882a593Smuzhiyun {TSADCV3_DATA_MASK, MAX_TEMP},
644*4882a593Smuzhiyun };
645*4882a593Smuzhiyun
646*4882a593Smuzhiyun static const struct tsadc_table rk3528_code_table[] = {
647*4882a593Smuzhiyun {0, MIN_TEMP},
648*4882a593Smuzhiyun {1386, MIN_TEMP},
649*4882a593Smuzhiyun {1419, -40000},
650*4882a593Smuzhiyun {1427, -35000},
651*4882a593Smuzhiyun {1435, -30000},
652*4882a593Smuzhiyun {1443, -25000},
653*4882a593Smuzhiyun {1452, -20000},
654*4882a593Smuzhiyun {1460, -15000},
655*4882a593Smuzhiyun {1468, -10000},
656*4882a593Smuzhiyun {1477, -5000},
657*4882a593Smuzhiyun {1486, 0},
658*4882a593Smuzhiyun {1494, 5000},
659*4882a593Smuzhiyun {1502, 10000},
660*4882a593Smuzhiyun {1510, 15000},
661*4882a593Smuzhiyun {1519, 20000},
662*4882a593Smuzhiyun {1527, 25000},
663*4882a593Smuzhiyun {1535, 30000},
664*4882a593Smuzhiyun {1544, 35000},
665*4882a593Smuzhiyun {1552, 40000},
666*4882a593Smuzhiyun {1561, 45000},
667*4882a593Smuzhiyun {1569, 50000},
668*4882a593Smuzhiyun {1578, 55000},
669*4882a593Smuzhiyun {1586, 60000},
670*4882a593Smuzhiyun {1594, 65000},
671*4882a593Smuzhiyun {1603, 70000},
672*4882a593Smuzhiyun {1612, 75000},
673*4882a593Smuzhiyun {1620, 80000},
674*4882a593Smuzhiyun {1628, 85000},
675*4882a593Smuzhiyun {1637, 90000},
676*4882a593Smuzhiyun {1646, 95000},
677*4882a593Smuzhiyun {1654, 100000},
678*4882a593Smuzhiyun {1662, 105000},
679*4882a593Smuzhiyun {1671, 110000},
680*4882a593Smuzhiyun {1679, 115000},
681*4882a593Smuzhiyun {1688, 120000},
682*4882a593Smuzhiyun {1696, 125000},
683*4882a593Smuzhiyun {1790, MAX_TEMP},
684*4882a593Smuzhiyun {TSADCV5_DATA_MASK, MAX_TEMP},
685*4882a593Smuzhiyun };
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun static const struct tsadc_table rk3562_code_table[] = {
688*4882a593Smuzhiyun {0, MIN_TEMP},
689*4882a593Smuzhiyun {1385, MIN_TEMP},
690*4882a593Smuzhiyun {1419, -40000},
691*4882a593Smuzhiyun {1428, -35000},
692*4882a593Smuzhiyun {1436, -30000},
693*4882a593Smuzhiyun {1445, -25000},
694*4882a593Smuzhiyun {1453, -20000},
695*4882a593Smuzhiyun {1462, -15000},
696*4882a593Smuzhiyun {1470, -10000},
697*4882a593Smuzhiyun {1479, -5000},
698*4882a593Smuzhiyun {1487, 0},
699*4882a593Smuzhiyun {1496, 5000},
700*4882a593Smuzhiyun {1504, 10000},
701*4882a593Smuzhiyun {1512, 15000},
702*4882a593Smuzhiyun {1521, 20000},
703*4882a593Smuzhiyun {1529, 25000},
704*4882a593Smuzhiyun {1538, 30000},
705*4882a593Smuzhiyun {1546, 35000},
706*4882a593Smuzhiyun {1555, 40000},
707*4882a593Smuzhiyun {1563, 45000},
708*4882a593Smuzhiyun {1572, 50000},
709*4882a593Smuzhiyun {1580, 55000},
710*4882a593Smuzhiyun {1589, 60000},
711*4882a593Smuzhiyun {1598, 65000},
712*4882a593Smuzhiyun {1606, 70000},
713*4882a593Smuzhiyun {1615, 75000},
714*4882a593Smuzhiyun {1623, 80000},
715*4882a593Smuzhiyun {1632, 85000},
716*4882a593Smuzhiyun {1640, 90000},
717*4882a593Smuzhiyun {1648, 95000},
718*4882a593Smuzhiyun {1657, 100000},
719*4882a593Smuzhiyun {1666, 105000},
720*4882a593Smuzhiyun {1674, 110000},
721*4882a593Smuzhiyun {1682, 115000},
722*4882a593Smuzhiyun {1691, 120000},
723*4882a593Smuzhiyun {1699, 125000},
724*4882a593Smuzhiyun {1793, MAX_TEMP},
725*4882a593Smuzhiyun {TSADCV2_DATA_MASK, MAX_TEMP},
726*4882a593Smuzhiyun };
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun static const struct tsadc_table rk3568_code_table[] = {
729*4882a593Smuzhiyun {0, MIN_TEMP},
730*4882a593Smuzhiyun {1448, MIN_TEMP},
731*4882a593Smuzhiyun {1584, -40000},
732*4882a593Smuzhiyun {1620, -35000},
733*4882a593Smuzhiyun {1652, -30000},
734*4882a593Smuzhiyun {1688, -25000},
735*4882a593Smuzhiyun {1720, -20000},
736*4882a593Smuzhiyun {1756, -15000},
737*4882a593Smuzhiyun {1788, -10000},
738*4882a593Smuzhiyun {1824, -5000},
739*4882a593Smuzhiyun {1856, 0},
740*4882a593Smuzhiyun {1892, 5000},
741*4882a593Smuzhiyun {1924, 10000},
742*4882a593Smuzhiyun {1956, 15000},
743*4882a593Smuzhiyun {1992, 20000},
744*4882a593Smuzhiyun {2024, 25000},
745*4882a593Smuzhiyun {2060, 30000},
746*4882a593Smuzhiyun {2092, 35000},
747*4882a593Smuzhiyun {2128, 40000},
748*4882a593Smuzhiyun {2160, 45000},
749*4882a593Smuzhiyun {2196, 50000},
750*4882a593Smuzhiyun {2228, 55000},
751*4882a593Smuzhiyun {2264, 60000},
752*4882a593Smuzhiyun {2300, 65000},
753*4882a593Smuzhiyun {2332, 70000},
754*4882a593Smuzhiyun {2368, 75000},
755*4882a593Smuzhiyun {2400, 80000},
756*4882a593Smuzhiyun {2436, 85000},
757*4882a593Smuzhiyun {2468, 90000},
758*4882a593Smuzhiyun {2500, 95000},
759*4882a593Smuzhiyun {2536, 100000},
760*4882a593Smuzhiyun {2572, 105000},
761*4882a593Smuzhiyun {2604, 110000},
762*4882a593Smuzhiyun {2636, 115000},
763*4882a593Smuzhiyun {2672, 120000},
764*4882a593Smuzhiyun {2704, 125000},
765*4882a593Smuzhiyun {3076, MAX_TEMP},
766*4882a593Smuzhiyun {TSADCV2_DATA_MASK, MAX_TEMP},
767*4882a593Smuzhiyun };
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun static const struct tsadc_table rk3588_code_table[] = {
770*4882a593Smuzhiyun {0, MIN_TEMP},
771*4882a593Smuzhiyun {194, MIN_TEMP},
772*4882a593Smuzhiyun {215, -40000},
773*4882a593Smuzhiyun {285, 25000},
774*4882a593Smuzhiyun {350, 85000},
775*4882a593Smuzhiyun {395, 125000},
776*4882a593Smuzhiyun {455, MAX_TEMP},
777*4882a593Smuzhiyun {TSADCV4_DATA_MASK, MAX_TEMP},
778*4882a593Smuzhiyun };
779*4882a593Smuzhiyun
rk_tsadcv2_temp_to_code(const struct chip_tsadc_table * table,int temp)780*4882a593Smuzhiyun static u32 rk_tsadcv2_temp_to_code(const struct chip_tsadc_table *table,
781*4882a593Smuzhiyun int temp)
782*4882a593Smuzhiyun {
783*4882a593Smuzhiyun int high, low, mid;
784*4882a593Smuzhiyun unsigned long num;
785*4882a593Smuzhiyun unsigned int denom;
786*4882a593Smuzhiyun u32 error = table->data_mask;
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun if (table->kNum)
789*4882a593Smuzhiyun return (((temp / 1000) * table->kNum) / 1000 + table->bNum);
790*4882a593Smuzhiyun
791*4882a593Smuzhiyun low = 0;
792*4882a593Smuzhiyun high = (table->length - 1) - 1; /* ignore the last check for table */
793*4882a593Smuzhiyun mid = (high + low) / 2;
794*4882a593Smuzhiyun
795*4882a593Smuzhiyun /* Return mask code data when the temp is over table range */
796*4882a593Smuzhiyun if (temp < table->id[low].temp || temp > table->id[high].temp)
797*4882a593Smuzhiyun goto exit;
798*4882a593Smuzhiyun
799*4882a593Smuzhiyun while (low <= high) {
800*4882a593Smuzhiyun if (temp == table->id[mid].temp)
801*4882a593Smuzhiyun return table->id[mid].code;
802*4882a593Smuzhiyun else if (temp < table->id[mid].temp)
803*4882a593Smuzhiyun high = mid - 1;
804*4882a593Smuzhiyun else
805*4882a593Smuzhiyun low = mid + 1;
806*4882a593Smuzhiyun mid = (low + high) / 2;
807*4882a593Smuzhiyun }
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun /*
810*4882a593Smuzhiyun * The conversion code granularity provided by the table. Let's
811*4882a593Smuzhiyun * assume that the relationship between temperature and
812*4882a593Smuzhiyun * analog value between 2 table entries is linear and interpolate
813*4882a593Smuzhiyun * to produce less granular result.
814*4882a593Smuzhiyun */
815*4882a593Smuzhiyun num = abs(table->id[mid + 1].code - table->id[mid].code);
816*4882a593Smuzhiyun num *= temp - table->id[mid].temp;
817*4882a593Smuzhiyun denom = table->id[mid + 1].temp - table->id[mid].temp;
818*4882a593Smuzhiyun
819*4882a593Smuzhiyun switch (table->mode) {
820*4882a593Smuzhiyun case ADC_DECREMENT:
821*4882a593Smuzhiyun return table->id[mid].code - (num / denom);
822*4882a593Smuzhiyun case ADC_INCREMENT:
823*4882a593Smuzhiyun return table->id[mid].code + (num / denom);
824*4882a593Smuzhiyun default:
825*4882a593Smuzhiyun pr_err("%s: unknown table mode: %d\n", __func__, table->mode);
826*4882a593Smuzhiyun return error;
827*4882a593Smuzhiyun }
828*4882a593Smuzhiyun
829*4882a593Smuzhiyun exit:
830*4882a593Smuzhiyun pr_err("%s: invalid temperature, temp=%d error=%d\n",
831*4882a593Smuzhiyun __func__, temp, error);
832*4882a593Smuzhiyun return error;
833*4882a593Smuzhiyun }
834*4882a593Smuzhiyun
rk_tsadcv2_code_to_temp(const struct chip_tsadc_table * table,u32 code,int * temp)835*4882a593Smuzhiyun static int rk_tsadcv2_code_to_temp(const struct chip_tsadc_table *table,
836*4882a593Smuzhiyun u32 code, int *temp)
837*4882a593Smuzhiyun {
838*4882a593Smuzhiyun unsigned int low = 1;
839*4882a593Smuzhiyun unsigned int high = table->length - 1;
840*4882a593Smuzhiyun unsigned int mid = (low + high) / 2;
841*4882a593Smuzhiyun unsigned int num;
842*4882a593Smuzhiyun unsigned long denom;
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun if (table->kNum) {
845*4882a593Smuzhiyun *temp = (((int)code - table->bNum) * 10000 / table->kNum) * 100;
846*4882a593Smuzhiyun if (*temp < MIN_TEMP || *temp > MAX_TEMP)
847*4882a593Smuzhiyun return -EAGAIN;
848*4882a593Smuzhiyun return 0;
849*4882a593Smuzhiyun }
850*4882a593Smuzhiyun
851*4882a593Smuzhiyun WARN_ON(table->length < 2);
852*4882a593Smuzhiyun
853*4882a593Smuzhiyun switch (table->mode) {
854*4882a593Smuzhiyun case ADC_DECREMENT:
855*4882a593Smuzhiyun code &= table->data_mask;
856*4882a593Smuzhiyun if (code <= table->id[high].code)
857*4882a593Smuzhiyun return -EAGAIN; /* Incorrect reading */
858*4882a593Smuzhiyun
859*4882a593Smuzhiyun while (low <= high) {
860*4882a593Smuzhiyun if (code >= table->id[mid].code &&
861*4882a593Smuzhiyun code < table->id[mid - 1].code)
862*4882a593Smuzhiyun break;
863*4882a593Smuzhiyun else if (code < table->id[mid].code)
864*4882a593Smuzhiyun low = mid + 1;
865*4882a593Smuzhiyun else
866*4882a593Smuzhiyun high = mid - 1;
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun mid = (low + high) / 2;
869*4882a593Smuzhiyun }
870*4882a593Smuzhiyun break;
871*4882a593Smuzhiyun case ADC_INCREMENT:
872*4882a593Smuzhiyun code &= table->data_mask;
873*4882a593Smuzhiyun if (code < table->id[low].code)
874*4882a593Smuzhiyun return -EAGAIN; /* Incorrect reading */
875*4882a593Smuzhiyun
876*4882a593Smuzhiyun while (low <= high) {
877*4882a593Smuzhiyun if (code <= table->id[mid].code &&
878*4882a593Smuzhiyun code > table->id[mid - 1].code)
879*4882a593Smuzhiyun break;
880*4882a593Smuzhiyun else if (code > table->id[mid].code)
881*4882a593Smuzhiyun low = mid + 1;
882*4882a593Smuzhiyun else
883*4882a593Smuzhiyun high = mid - 1;
884*4882a593Smuzhiyun
885*4882a593Smuzhiyun mid = (low + high) / 2;
886*4882a593Smuzhiyun }
887*4882a593Smuzhiyun break;
888*4882a593Smuzhiyun default:
889*4882a593Smuzhiyun pr_err("%s: unknown table mode: %d\n", __func__, table->mode);
890*4882a593Smuzhiyun return -EINVAL;
891*4882a593Smuzhiyun }
892*4882a593Smuzhiyun
893*4882a593Smuzhiyun /*
894*4882a593Smuzhiyun * The 5C granularity provided by the table is too much. Let's
895*4882a593Smuzhiyun * assume that the relationship between sensor readings and
896*4882a593Smuzhiyun * temperature between 2 table entries is linear and interpolate
897*4882a593Smuzhiyun * to produce less granular result.
898*4882a593Smuzhiyun */
899*4882a593Smuzhiyun num = table->id[mid].temp - table->id[mid - 1].temp;
900*4882a593Smuzhiyun num *= abs(table->id[mid - 1].code - code);
901*4882a593Smuzhiyun denom = abs(table->id[mid - 1].code - table->id[mid].code);
902*4882a593Smuzhiyun *temp = table->id[mid - 1].temp + (num / denom);
903*4882a593Smuzhiyun
904*4882a593Smuzhiyun return 0;
905*4882a593Smuzhiyun }
906*4882a593Smuzhiyun
907*4882a593Smuzhiyun /**
908*4882a593Smuzhiyun * rk_tsadcv2_initialize - initialize TASDC Controller.
909*4882a593Smuzhiyun * @grf: the general register file will be used to do static set by software
910*4882a593Smuzhiyun * @regs: the base address of tsadc controller
911*4882a593Smuzhiyun * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
912*4882a593Smuzhiyun *
913*4882a593Smuzhiyun * (1) Set TSADC_V2_AUTO_PERIOD:
914*4882a593Smuzhiyun * Configure the interleave between every two accessing of
915*4882a593Smuzhiyun * TSADC in normal operation.
916*4882a593Smuzhiyun *
917*4882a593Smuzhiyun * (2) Set TSADCV2_AUTO_PERIOD_HT:
918*4882a593Smuzhiyun * Configure the interleave between every two accessing of
919*4882a593Smuzhiyun * TSADC after the temperature is higher than COM_SHUT or COM_INT.
920*4882a593Smuzhiyun *
921*4882a593Smuzhiyun * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE:
922*4882a593Smuzhiyun * If the temperature is higher than COMP_INT or COMP_SHUT for
923*4882a593Smuzhiyun * "debounce" times, TSADC controller will generate interrupt or TSHUT.
924*4882a593Smuzhiyun */
rk_tsadcv2_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)925*4882a593Smuzhiyun static void rk_tsadcv2_initialize(struct regmap *grf, void __iomem *regs,
926*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
927*4882a593Smuzhiyun {
928*4882a593Smuzhiyun if (tshut_polarity == TSHUT_HIGH_ACTIVE)
929*4882a593Smuzhiyun writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
930*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
931*4882a593Smuzhiyun else
932*4882a593Smuzhiyun writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
933*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
934*4882a593Smuzhiyun
935*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD);
936*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,
937*4882a593Smuzhiyun regs + TSADCV2_HIGHT_INT_DEBOUNCE);
938*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_PERIOD_HT_TIME,
939*4882a593Smuzhiyun regs + TSADCV2_AUTO_PERIOD_HT);
940*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,
941*4882a593Smuzhiyun regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);
942*4882a593Smuzhiyun }
943*4882a593Smuzhiyun
944*4882a593Smuzhiyun /**
945*4882a593Smuzhiyun * rk_tsadcv3_initialize - initialize TASDC Controller.
946*4882a593Smuzhiyun * @grf: the general register file will be used to do static set by software
947*4882a593Smuzhiyun * @regs: the base address of tsadc controller
948*4882a593Smuzhiyun * @tshut_polarity: the hardware-controlled active polarity (0:LOW 1:HIGH)
949*4882a593Smuzhiyun *
950*4882a593Smuzhiyun * (1) The tsadc control power sequence.
951*4882a593Smuzhiyun *
952*4882a593Smuzhiyun * (2) Set TSADC_V2_AUTO_PERIOD:
953*4882a593Smuzhiyun * Configure the interleave between every two accessing of
954*4882a593Smuzhiyun * TSADC in normal operation.
955*4882a593Smuzhiyun *
956*4882a593Smuzhiyun * (2) Set TSADCV2_AUTO_PERIOD_HT:
957*4882a593Smuzhiyun * Configure the interleave between every two accessing of
958*4882a593Smuzhiyun * TSADC after the temperature is higher than COM_SHUT or COM_INT.
959*4882a593Smuzhiyun *
960*4882a593Smuzhiyun * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE:
961*4882a593Smuzhiyun * If the temperature is higher than COMP_INT or COMP_SHUT for
962*4882a593Smuzhiyun * "debounce" times, TSADC controller will generate interrupt or TSHUT.
963*4882a593Smuzhiyun */
rk_tsadcv3_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)964*4882a593Smuzhiyun static void rk_tsadcv3_initialize(struct regmap *grf, void __iomem *regs,
965*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
966*4882a593Smuzhiyun {
967*4882a593Smuzhiyun /* The tsadc control power sequence */
968*4882a593Smuzhiyun if (IS_ERR(grf)) {
969*4882a593Smuzhiyun /* Set interleave value to workround ic time sync issue */
970*4882a593Smuzhiyun writel_relaxed(TSADCV2_USER_INTER_PD_SOC, regs +
971*4882a593Smuzhiyun TSADCV2_USER_CON);
972*4882a593Smuzhiyun
973*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_PERIOD_TIME,
974*4882a593Smuzhiyun regs + TSADCV2_AUTO_PERIOD);
975*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,
976*4882a593Smuzhiyun regs + TSADCV2_HIGHT_INT_DEBOUNCE);
977*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_PERIOD_HT_TIME,
978*4882a593Smuzhiyun regs + TSADCV2_AUTO_PERIOD_HT);
979*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,
980*4882a593Smuzhiyun regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);
981*4882a593Smuzhiyun
982*4882a593Smuzhiyun } else {
983*4882a593Smuzhiyun /* Enable the voltage common mode feature */
984*4882a593Smuzhiyun regmap_write(grf, GRF_TSADC_TESTBIT_L, GRF_TSADC_VCM_EN_L);
985*4882a593Smuzhiyun regmap_write(grf, GRF_TSADC_TESTBIT_H, GRF_TSADC_VCM_EN_H);
986*4882a593Smuzhiyun
987*4882a593Smuzhiyun usleep_range(15, 100); /* The spec note says at least 15 us */
988*4882a593Smuzhiyun regmap_write(grf, GRF_SARADC_TESTBIT, GRF_SARADC_TESTBIT_ON);
989*4882a593Smuzhiyun regmap_write(grf, GRF_TSADC_TESTBIT_H, GRF_TSADC_TESTBIT_H_ON);
990*4882a593Smuzhiyun usleep_range(90, 200); /* The spec note says at least 90 us */
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun writel_relaxed(TSADCV3_AUTO_PERIOD_TIME,
993*4882a593Smuzhiyun regs + TSADCV2_AUTO_PERIOD);
994*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,
995*4882a593Smuzhiyun regs + TSADCV2_HIGHT_INT_DEBOUNCE);
996*4882a593Smuzhiyun writel_relaxed(TSADCV3_AUTO_PERIOD_HT_TIME,
997*4882a593Smuzhiyun regs + TSADCV2_AUTO_PERIOD_HT);
998*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,
999*4882a593Smuzhiyun regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);
1000*4882a593Smuzhiyun }
1001*4882a593Smuzhiyun
1002*4882a593Smuzhiyun if (tshut_polarity == TSHUT_HIGH_ACTIVE)
1003*4882a593Smuzhiyun writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
1004*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1005*4882a593Smuzhiyun else
1006*4882a593Smuzhiyun writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
1007*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1008*4882a593Smuzhiyun }
1009*4882a593Smuzhiyun
rk_tsadcv4_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)1010*4882a593Smuzhiyun static void rk_tsadcv4_initialize(struct regmap *grf, void __iomem *regs,
1011*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
1012*4882a593Smuzhiyun {
1013*4882a593Smuzhiyun rk_tsadcv2_initialize(grf, regs, tshut_polarity);
1014*4882a593Smuzhiyun regmap_write(grf, PX30_GRF_SOC_CON2, GRF_CON_TSADC_CH_INV);
1015*4882a593Smuzhiyun }
1016*4882a593Smuzhiyun
rk_tsadcv5_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)1017*4882a593Smuzhiyun static void rk_tsadcv5_initialize(struct regmap *grf, void __iomem *regs,
1018*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
1019*4882a593Smuzhiyun {
1020*4882a593Smuzhiyun if (tshut_polarity == TSHUT_HIGH_ACTIVE)
1021*4882a593Smuzhiyun writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
1022*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1023*4882a593Smuzhiyun else
1024*4882a593Smuzhiyun writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
1025*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1026*4882a593Smuzhiyun
1027*4882a593Smuzhiyun writel_relaxed(TSADCV5_USER_INTER_PD_SOC, regs + TSADCV2_USER_CON);
1028*4882a593Smuzhiyun
1029*4882a593Smuzhiyun writel_relaxed(TSADCV5_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD);
1030*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,
1031*4882a593Smuzhiyun regs + TSADCV2_HIGHT_INT_DEBOUNCE);
1032*4882a593Smuzhiyun writel_relaxed(TSADCV5_AUTO_PERIOD_HT_TIME,
1033*4882a593Smuzhiyun regs + TSADCV2_AUTO_PERIOD_HT);
1034*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,
1035*4882a593Smuzhiyun regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun if (!IS_ERR(grf))
1038*4882a593Smuzhiyun regmap_write(grf, RK1808_BUS_GRF_SOC_CON0,
1039*4882a593Smuzhiyun GRF_TSADC_BANDGAP_CHOPPER_EN);
1040*4882a593Smuzhiyun }
1041*4882a593Smuzhiyun
rk_tsadcv6_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)1042*4882a593Smuzhiyun static void rk_tsadcv6_initialize(struct regmap *grf, void __iomem *regs,
1043*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
1044*4882a593Smuzhiyun {
1045*4882a593Smuzhiyun rk_tsadcv2_initialize(grf, regs, tshut_polarity);
1046*4882a593Smuzhiyun
1047*4882a593Smuzhiyun if (!IS_ERR(grf))
1048*4882a593Smuzhiyun regmap_write(grf, RV1126_GRF0_TSADC_CON,
1049*4882a593Smuzhiyun RV1126_GRF0_TSADC_TRM);
1050*4882a593Smuzhiyun }
1051*4882a593Smuzhiyun
rk_tsadcv7_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)1052*4882a593Smuzhiyun static void rk_tsadcv7_initialize(struct regmap *grf, void __iomem *regs,
1053*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
1054*4882a593Smuzhiyun {
1055*4882a593Smuzhiyun writel_relaxed(TSADCV5_USER_INTER_PD_SOC, regs + TSADCV2_USER_CON);
1056*4882a593Smuzhiyun writel_relaxed(TSADCV5_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD);
1057*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,
1058*4882a593Smuzhiyun regs + TSADCV2_HIGHT_INT_DEBOUNCE);
1059*4882a593Smuzhiyun writel_relaxed(TSADCV5_AUTO_PERIOD_HT_TIME,
1060*4882a593Smuzhiyun regs + TSADCV2_AUTO_PERIOD_HT);
1061*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,
1062*4882a593Smuzhiyun regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);
1063*4882a593Smuzhiyun
1064*4882a593Smuzhiyun if (tshut_polarity == TSHUT_HIGH_ACTIVE)
1065*4882a593Smuzhiyun writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
1066*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1067*4882a593Smuzhiyun else
1068*4882a593Smuzhiyun writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
1069*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1070*4882a593Smuzhiyun
1071*4882a593Smuzhiyun /*
1072*4882a593Smuzhiyun * The general register file will is optional
1073*4882a593Smuzhiyun * and might not be available.
1074*4882a593Smuzhiyun */
1075*4882a593Smuzhiyun if (!IS_ERR(grf)) {
1076*4882a593Smuzhiyun regmap_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_TSEN);
1077*4882a593Smuzhiyun /*
1078*4882a593Smuzhiyun * RK3568 TRM, section 18.5. requires a delay no less
1079*4882a593Smuzhiyun * than 10us between the rising edge of tsadc_tsen_en
1080*4882a593Smuzhiyun * and the rising edge of tsadc_ana_reg_0/1/2.
1081*4882a593Smuzhiyun */
1082*4882a593Smuzhiyun udelay(15);
1083*4882a593Smuzhiyun regmap_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG0);
1084*4882a593Smuzhiyun regmap_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG1);
1085*4882a593Smuzhiyun regmap_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG2);
1086*4882a593Smuzhiyun
1087*4882a593Smuzhiyun /*
1088*4882a593Smuzhiyun * RK3568 TRM, section 18.5. requires a delay no less
1089*4882a593Smuzhiyun * than 90us after the rising edge of tsadc_ana_reg_0/1/2.
1090*4882a593Smuzhiyun */
1091*4882a593Smuzhiyun usleep_range(100, 200);
1092*4882a593Smuzhiyun }
1093*4882a593Smuzhiyun }
1094*4882a593Smuzhiyun
rk_tsadcv8_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)1095*4882a593Smuzhiyun static void rk_tsadcv8_initialize(struct regmap *grf, void __iomem *regs,
1096*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
1097*4882a593Smuzhiyun {
1098*4882a593Smuzhiyun writel_relaxed(TSADCV6_AUTO_PERIOD_TIME, regs + TSADCV3_AUTO_PERIOD);
1099*4882a593Smuzhiyun writel_relaxed(TSADCV6_AUTO_PERIOD_HT_TIME,
1100*4882a593Smuzhiyun regs + TSADCV3_AUTO_PERIOD_HT);
1101*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,
1102*4882a593Smuzhiyun regs + TSADCV3_HIGHT_INT_DEBOUNCE);
1103*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,
1104*4882a593Smuzhiyun regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE);
1105*4882a593Smuzhiyun if (tshut_polarity == TSHUT_HIGH_ACTIVE)
1106*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_HIGH |
1107*4882a593Smuzhiyun TSADCV2_AUTO_TSHUT_POLARITY_MASK,
1108*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1109*4882a593Smuzhiyun else
1110*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_MASK,
1111*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1112*4882a593Smuzhiyun }
1113*4882a593Smuzhiyun
rk_tsadcv9_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)1114*4882a593Smuzhiyun static void rk_tsadcv9_initialize(struct regmap *grf, void __iomem *regs,
1115*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
1116*4882a593Smuzhiyun {
1117*4882a593Smuzhiyun regmap_write(grf, RV1106_VOGRF_TSADC_CON, RV1106_VOGRF_TSADC_TSEN);
1118*4882a593Smuzhiyun udelay(10);
1119*4882a593Smuzhiyun regmap_write(grf, RV1106_VOGRF_TSADC_CON, RV1106_VOGRF_TSADC_ANA);
1120*4882a593Smuzhiyun udelay(100);
1121*4882a593Smuzhiyun
1122*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_PERIOD_TIME, regs + TSADCV3_AUTO_PERIOD);
1123*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_PERIOD_TIME,
1124*4882a593Smuzhiyun regs + TSADCV3_AUTO_PERIOD_HT);
1125*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,
1126*4882a593Smuzhiyun regs + TSADCV3_HIGHT_INT_DEBOUNCE);
1127*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,
1128*4882a593Smuzhiyun regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE);
1129*4882a593Smuzhiyun writel_relaxed(TSADCV9_AUTO_SRC, regs + TSADCV2_INT_PD);
1130*4882a593Smuzhiyun writel_relaxed(TSADCV9_PD_MODE, regs + TSADCV9_FLOW_CON);
1131*4882a593Smuzhiyun writel_relaxed(TSADCV9_Q_MAX_VAL, regs + TSADCV9_Q_MAX);
1132*4882a593Smuzhiyun if (tshut_polarity == TSHUT_HIGH_ACTIVE)
1133*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_HIGH |
1134*4882a593Smuzhiyun TSADCV2_AUTO_TSHUT_POLARITY_MASK,
1135*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1136*4882a593Smuzhiyun else
1137*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_MASK,
1138*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1139*4882a593Smuzhiyun writel_relaxed(TSADCV3_AUTO_Q_SEL_EN | (TSADCV3_AUTO_Q_SEL_EN << 16),
1140*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1141*4882a593Smuzhiyun }
1142*4882a593Smuzhiyun
rk_tsadcv10_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)1143*4882a593Smuzhiyun static void rk_tsadcv10_initialize(struct regmap *grf, void __iomem *regs,
1144*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
1145*4882a593Smuzhiyun {
1146*4882a593Smuzhiyun rk_tsadcv2_initialize(grf, regs, tshut_polarity);
1147*4882a593Smuzhiyun if (!IS_ERR(grf)) {
1148*4882a593Smuzhiyun regmap_write(grf, PX30_GRF_SOC_CON0, PX30S_TSADC_TDC_MODE);
1149*4882a593Smuzhiyun regmap_write(grf, PX30_GRF_SOC_CON0, PX30S_TSADC_TRIM);
1150*4882a593Smuzhiyun }
1151*4882a593Smuzhiyun }
1152*4882a593Smuzhiyun
rk_tsadcv11_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)1153*4882a593Smuzhiyun static void rk_tsadcv11_initialize(struct regmap *grf, void __iomem *regs,
1154*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
1155*4882a593Smuzhiyun {
1156*4882a593Smuzhiyun writel_relaxed(TSADCV7_AUTO_PERIOD_TIME, regs + TSADCV3_AUTO_PERIOD);
1157*4882a593Smuzhiyun writel_relaxed(TSADCV7_AUTO_PERIOD_HT_TIME,
1158*4882a593Smuzhiyun regs + TSADCV3_AUTO_PERIOD_HT);
1159*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,
1160*4882a593Smuzhiyun regs + TSADCV3_HIGHT_INT_DEBOUNCE);
1161*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,
1162*4882a593Smuzhiyun regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE);
1163*4882a593Smuzhiyun writel_relaxed(TSADCV3_Q_MAX_VAL, regs + TSADCV9_Q_MAX);
1164*4882a593Smuzhiyun writel_relaxed(TSADCV3_AUTO_Q_SEL_EN | TSADCV3_AUTO_Q_SEL_EN_MASK,
1165*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1166*4882a593Smuzhiyun if (tshut_polarity == TSHUT_HIGH_ACTIVE)
1167*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_HIGH |
1168*4882a593Smuzhiyun TSADCV2_AUTO_TSHUT_POLARITY_MASK,
1169*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1170*4882a593Smuzhiyun else
1171*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_MASK,
1172*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1173*4882a593Smuzhiyun
1174*4882a593Smuzhiyun if (!IS_ERR(grf)) {
1175*4882a593Smuzhiyun regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_TSEN);
1176*4882a593Smuzhiyun udelay(15);
1177*4882a593Smuzhiyun regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG0);
1178*4882a593Smuzhiyun regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG1);
1179*4882a593Smuzhiyun regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG2);
1180*4882a593Smuzhiyun usleep_range(100, 200);
1181*4882a593Smuzhiyun }
1182*4882a593Smuzhiyun }
1183*4882a593Smuzhiyun
rk_tsadcv12_initialize(struct regmap * grf,void __iomem * regs,enum tshut_polarity tshut_polarity)1184*4882a593Smuzhiyun static void rk_tsadcv12_initialize(struct regmap *grf, void __iomem *regs,
1185*4882a593Smuzhiyun enum tshut_polarity tshut_polarity)
1186*4882a593Smuzhiyun {
1187*4882a593Smuzhiyun writel_relaxed(TSADCV12_AUTO_PERIOD_TIME, regs + TSADCV3_AUTO_PERIOD);
1188*4882a593Smuzhiyun writel_relaxed(TSADCV12_AUTO_PERIOD_HT_TIME,
1189*4882a593Smuzhiyun regs + TSADCV3_AUTO_PERIOD_HT);
1190*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT,
1191*4882a593Smuzhiyun regs + TSADCV3_HIGHT_INT_DEBOUNCE);
1192*4882a593Smuzhiyun writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,
1193*4882a593Smuzhiyun regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE);
1194*4882a593Smuzhiyun writel_relaxed(TSADCV12_Q_MAX_VAL, regs + TSADCV9_Q_MAX);
1195*4882a593Smuzhiyun writel_relaxed(TSADCV3_AUTO_Q_SEL_EN | TSADCV3_AUTO_Q_SEL_EN_MASK,
1196*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1197*4882a593Smuzhiyun if (tshut_polarity == TSHUT_HIGH_ACTIVE)
1198*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_HIGH |
1199*4882a593Smuzhiyun TSADCV2_AUTO_TSHUT_POLARITY_MASK,
1200*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1201*4882a593Smuzhiyun else
1202*4882a593Smuzhiyun writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_MASK,
1203*4882a593Smuzhiyun regs + TSADCV2_AUTO_CON);
1204*4882a593Smuzhiyun
1205*4882a593Smuzhiyun if (!IS_ERR(grf)) {
1206*4882a593Smuzhiyun regmap_write(grf, RK3562_GRF_TSADC_CON, RK3568_GRF_TSADC_TSEN);
1207*4882a593Smuzhiyun udelay(15);
1208*4882a593Smuzhiyun regmap_write(grf, RK3562_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG0);
1209*4882a593Smuzhiyun regmap_write(grf, RK3562_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG1);
1210*4882a593Smuzhiyun regmap_write(grf, RK3562_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG2);
1211*4882a593Smuzhiyun usleep_range(100, 200);
1212*4882a593Smuzhiyun }
1213*4882a593Smuzhiyun }
1214*4882a593Smuzhiyun
rk_tsadcv2_irq_ack(void __iomem * regs)1215*4882a593Smuzhiyun static void rk_tsadcv2_irq_ack(void __iomem *regs)
1216*4882a593Smuzhiyun {
1217*4882a593Smuzhiyun u32 val;
1218*4882a593Smuzhiyun
1219*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV2_INT_PD);
1220*4882a593Smuzhiyun writel_relaxed(val & TSADCV2_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD);
1221*4882a593Smuzhiyun }
1222*4882a593Smuzhiyun
rk_tsadcv3_irq_ack(void __iomem * regs)1223*4882a593Smuzhiyun static void rk_tsadcv3_irq_ack(void __iomem *regs)
1224*4882a593Smuzhiyun {
1225*4882a593Smuzhiyun u32 val;
1226*4882a593Smuzhiyun
1227*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV2_INT_PD);
1228*4882a593Smuzhiyun writel_relaxed(val & TSADCV3_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD);
1229*4882a593Smuzhiyun }
1230*4882a593Smuzhiyun
rk_tsadcv4_irq_ack(void __iomem * regs)1231*4882a593Smuzhiyun static void rk_tsadcv4_irq_ack(void __iomem *regs)
1232*4882a593Smuzhiyun {
1233*4882a593Smuzhiyun u32 val;
1234*4882a593Smuzhiyun
1235*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV3_INT_PD);
1236*4882a593Smuzhiyun writel_relaxed(val & TSADCV4_INT_PD_CLEAR_MASK, regs + TSADCV3_INT_PD);
1237*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV3_HSHUT_PD);
1238*4882a593Smuzhiyun writel_relaxed(val & TSADCV3_INT_PD_CLEAR_MASK,
1239*4882a593Smuzhiyun regs + TSADCV3_HSHUT_PD);
1240*4882a593Smuzhiyun }
1241*4882a593Smuzhiyun
rk_tsadcv2_control(void __iomem * regs,bool enable)1242*4882a593Smuzhiyun static void rk_tsadcv2_control(void __iomem *regs, bool enable)
1243*4882a593Smuzhiyun {
1244*4882a593Smuzhiyun u32 val;
1245*4882a593Smuzhiyun
1246*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV2_AUTO_CON);
1247*4882a593Smuzhiyun if (enable)
1248*4882a593Smuzhiyun val |= TSADCV2_AUTO_EN;
1249*4882a593Smuzhiyun else
1250*4882a593Smuzhiyun val &= ~TSADCV2_AUTO_EN;
1251*4882a593Smuzhiyun
1252*4882a593Smuzhiyun writel_relaxed(val, regs + TSADCV2_AUTO_CON);
1253*4882a593Smuzhiyun }
1254*4882a593Smuzhiyun
1255*4882a593Smuzhiyun /**
1256*4882a593Smuzhiyun * rk_tsadcv3_control - the tsadc controller is enabled or disabled.
1257*4882a593Smuzhiyun * @regs: the base address of tsadc controller
1258*4882a593Smuzhiyun * @enable: boolean flag to enable the controller
1259*4882a593Smuzhiyun *
1260*4882a593Smuzhiyun * NOTE: TSADC controller works at auto mode, and some SoCs need set the
1261*4882a593Smuzhiyun * tsadc_q_sel bit on TSADCV2_AUTO_CON[1]. The (1024 - tsadc_q) as output
1262*4882a593Smuzhiyun * adc value if setting this bit to enable.
1263*4882a593Smuzhiyun */
rk_tsadcv3_control(void __iomem * regs,bool enable)1264*4882a593Smuzhiyun static void rk_tsadcv3_control(void __iomem *regs, bool enable)
1265*4882a593Smuzhiyun {
1266*4882a593Smuzhiyun u32 val;
1267*4882a593Smuzhiyun
1268*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV2_AUTO_CON);
1269*4882a593Smuzhiyun if (enable)
1270*4882a593Smuzhiyun val |= TSADCV2_AUTO_EN | TSADCV3_AUTO_Q_SEL_EN;
1271*4882a593Smuzhiyun else
1272*4882a593Smuzhiyun val &= ~TSADCV2_AUTO_EN;
1273*4882a593Smuzhiyun
1274*4882a593Smuzhiyun writel_relaxed(val, regs + TSADCV2_AUTO_CON);
1275*4882a593Smuzhiyun }
1276*4882a593Smuzhiyun
rk_tsadcv4_control(void __iomem * regs,bool enable)1277*4882a593Smuzhiyun static void rk_tsadcv4_control(void __iomem *regs, bool enable)
1278*4882a593Smuzhiyun {
1279*4882a593Smuzhiyun u32 val;
1280*4882a593Smuzhiyun
1281*4882a593Smuzhiyun if (enable)
1282*4882a593Smuzhiyun val = TSADCV2_AUTO_EN | TSADCV2_AUTO_EN_MASK;
1283*4882a593Smuzhiyun else
1284*4882a593Smuzhiyun val = TSADCV2_AUTO_EN_MASK;
1285*4882a593Smuzhiyun
1286*4882a593Smuzhiyun writel_relaxed(val, regs + TSADCV2_AUTO_CON);
1287*4882a593Smuzhiyun }
1288*4882a593Smuzhiyun
rk_tsadcv2_get_temp(const struct chip_tsadc_table * table,int chn,void __iomem * regs,int * temp)1289*4882a593Smuzhiyun static int rk_tsadcv2_get_temp(const struct chip_tsadc_table *table,
1290*4882a593Smuzhiyun int chn, void __iomem *regs, int *temp)
1291*4882a593Smuzhiyun {
1292*4882a593Smuzhiyun u32 val;
1293*4882a593Smuzhiyun
1294*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV2_DATA(chn));
1295*4882a593Smuzhiyun
1296*4882a593Smuzhiyun return rk_tsadcv2_code_to_temp(table, val, temp);
1297*4882a593Smuzhiyun }
1298*4882a593Smuzhiyun
rk_tsadcv4_get_temp(const struct chip_tsadc_table * table,int chn,void __iomem * regs,int * temp)1299*4882a593Smuzhiyun static int rk_tsadcv4_get_temp(const struct chip_tsadc_table *table,
1300*4882a593Smuzhiyun int chn, void __iomem *regs, int *temp)
1301*4882a593Smuzhiyun {
1302*4882a593Smuzhiyun u32 val;
1303*4882a593Smuzhiyun
1304*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV3_DATA(chn));
1305*4882a593Smuzhiyun
1306*4882a593Smuzhiyun return rk_tsadcv2_code_to_temp(table, val, temp);
1307*4882a593Smuzhiyun }
1308*4882a593Smuzhiyun
rk_tsadcv2_alarm_temp(const struct chip_tsadc_table * table,int chn,void __iomem * regs,int temp)1309*4882a593Smuzhiyun static int rk_tsadcv2_alarm_temp(const struct chip_tsadc_table *table,
1310*4882a593Smuzhiyun int chn, void __iomem *regs, int temp)
1311*4882a593Smuzhiyun {
1312*4882a593Smuzhiyun u32 alarm_value;
1313*4882a593Smuzhiyun u32 int_en, int_clr;
1314*4882a593Smuzhiyun
1315*4882a593Smuzhiyun /*
1316*4882a593Smuzhiyun * In some cases, some sensors didn't need the trip points, the
1317*4882a593Smuzhiyun * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm
1318*4882a593Smuzhiyun * in the end, ignore this case and disable the high temperature
1319*4882a593Smuzhiyun * interrupt.
1320*4882a593Smuzhiyun */
1321*4882a593Smuzhiyun if (temp == INT_MAX) {
1322*4882a593Smuzhiyun int_clr = readl_relaxed(regs + TSADCV2_INT_EN);
1323*4882a593Smuzhiyun int_clr &= ~TSADCV2_INT_SRC_EN(chn);
1324*4882a593Smuzhiyun writel_relaxed(int_clr, regs + TSADCV2_INT_EN);
1325*4882a593Smuzhiyun return 0;
1326*4882a593Smuzhiyun }
1327*4882a593Smuzhiyun
1328*4882a593Smuzhiyun /* Make sure the value is valid */
1329*4882a593Smuzhiyun alarm_value = rk_tsadcv2_temp_to_code(table, temp);
1330*4882a593Smuzhiyun if (alarm_value == table->data_mask)
1331*4882a593Smuzhiyun return -ERANGE;
1332*4882a593Smuzhiyun
1333*4882a593Smuzhiyun writel_relaxed(alarm_value & table->data_mask,
1334*4882a593Smuzhiyun regs + TSADCV2_COMP_INT(chn));
1335*4882a593Smuzhiyun
1336*4882a593Smuzhiyun int_en = readl_relaxed(regs + TSADCV2_INT_EN);
1337*4882a593Smuzhiyun int_en |= TSADCV2_INT_SRC_EN(chn);
1338*4882a593Smuzhiyun writel_relaxed(int_en, regs + TSADCV2_INT_EN);
1339*4882a593Smuzhiyun
1340*4882a593Smuzhiyun return 0;
1341*4882a593Smuzhiyun }
1342*4882a593Smuzhiyun
rk_tsadcv3_alarm_temp(const struct chip_tsadc_table * table,int chn,void __iomem * regs,int temp)1343*4882a593Smuzhiyun static int rk_tsadcv3_alarm_temp(const struct chip_tsadc_table *table,
1344*4882a593Smuzhiyun int chn, void __iomem *regs, int temp)
1345*4882a593Smuzhiyun {
1346*4882a593Smuzhiyun u32 alarm_value;
1347*4882a593Smuzhiyun
1348*4882a593Smuzhiyun /*
1349*4882a593Smuzhiyun * In some cases, some sensors didn't need the trip points, the
1350*4882a593Smuzhiyun * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm
1351*4882a593Smuzhiyun * in the end, ignore this case and disable the high temperature
1352*4882a593Smuzhiyun * interrupt.
1353*4882a593Smuzhiyun */
1354*4882a593Smuzhiyun if (temp == INT_MAX) {
1355*4882a593Smuzhiyun writel_relaxed(TSADCV2_INT_SRC_EN_MASK(chn),
1356*4882a593Smuzhiyun regs + TSADCV3_HT_INT_EN);
1357*4882a593Smuzhiyun return 0;
1358*4882a593Smuzhiyun }
1359*4882a593Smuzhiyun /* Make sure the value is valid */
1360*4882a593Smuzhiyun alarm_value = rk_tsadcv2_temp_to_code(table, temp);
1361*4882a593Smuzhiyun if (alarm_value == table->data_mask)
1362*4882a593Smuzhiyun return -ERANGE;
1363*4882a593Smuzhiyun writel_relaxed(alarm_value & table->data_mask,
1364*4882a593Smuzhiyun regs + TSADCV3_COMP_INT(chn));
1365*4882a593Smuzhiyun writel_relaxed(TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn),
1366*4882a593Smuzhiyun regs + TSADCV3_HT_INT_EN);
1367*4882a593Smuzhiyun return 0;
1368*4882a593Smuzhiyun }
1369*4882a593Smuzhiyun
rk_tsadcv2_tshut_temp(const struct chip_tsadc_table * table,int chn,void __iomem * regs,int temp)1370*4882a593Smuzhiyun static int rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table,
1371*4882a593Smuzhiyun int chn, void __iomem *regs, int temp)
1372*4882a593Smuzhiyun {
1373*4882a593Smuzhiyun u32 tshut_value, val;
1374*4882a593Smuzhiyun
1375*4882a593Smuzhiyun /* Make sure the value is valid */
1376*4882a593Smuzhiyun tshut_value = rk_tsadcv2_temp_to_code(table, temp);
1377*4882a593Smuzhiyun if (tshut_value == table->data_mask)
1378*4882a593Smuzhiyun return -ERANGE;
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn));
1381*4882a593Smuzhiyun
1382*4882a593Smuzhiyun /* TSHUT will be valid */
1383*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV2_AUTO_CON);
1384*4882a593Smuzhiyun writel_relaxed(val | TSADCV2_AUTO_SRC_EN(chn), regs + TSADCV2_AUTO_CON);
1385*4882a593Smuzhiyun
1386*4882a593Smuzhiyun return 0;
1387*4882a593Smuzhiyun }
1388*4882a593Smuzhiyun
rk_tsadcv3_tshut_temp(const struct chip_tsadc_table * table,int chn,void __iomem * regs,int temp)1389*4882a593Smuzhiyun static int rk_tsadcv3_tshut_temp(const struct chip_tsadc_table *table,
1390*4882a593Smuzhiyun int chn, void __iomem *regs, int temp)
1391*4882a593Smuzhiyun {
1392*4882a593Smuzhiyun u32 tshut_value;
1393*4882a593Smuzhiyun
1394*4882a593Smuzhiyun /* Make sure the value is valid */
1395*4882a593Smuzhiyun tshut_value = rk_tsadcv2_temp_to_code(table, temp);
1396*4882a593Smuzhiyun if (tshut_value == table->data_mask)
1397*4882a593Smuzhiyun return -ERANGE;
1398*4882a593Smuzhiyun
1399*4882a593Smuzhiyun writel_relaxed(tshut_value, regs + TSADCV3_COMP_SHUT(chn));
1400*4882a593Smuzhiyun
1401*4882a593Smuzhiyun /* TSHUT will be valid */
1402*4882a593Smuzhiyun writel_relaxed(TSADCV3_AUTO_SRC_EN(chn) | TSADCV3_AUTO_SRC_EN_MASK(chn),
1403*4882a593Smuzhiyun regs + TSADCV3_AUTO_SRC_CON);
1404*4882a593Smuzhiyun
1405*4882a593Smuzhiyun return 0;
1406*4882a593Smuzhiyun }
1407*4882a593Smuzhiyun
rk_tsadcv2_tshut_mode(struct regmap * grf,int chn,void __iomem * regs,enum tshut_mode mode)1408*4882a593Smuzhiyun static void rk_tsadcv2_tshut_mode(struct regmap *grf, int chn,
1409*4882a593Smuzhiyun void __iomem *regs,
1410*4882a593Smuzhiyun enum tshut_mode mode)
1411*4882a593Smuzhiyun {
1412*4882a593Smuzhiyun u32 val;
1413*4882a593Smuzhiyun
1414*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV2_INT_EN);
1415*4882a593Smuzhiyun if (mode == TSHUT_MODE_OTP) {
1416*4882a593Smuzhiyun val &= ~TSADCV2_SHUT_2CRU_SRC_EN(chn);
1417*4882a593Smuzhiyun val |= TSADCV2_SHUT_2GPIO_SRC_EN(chn);
1418*4882a593Smuzhiyun } else {
1419*4882a593Smuzhiyun val &= ~TSADCV2_SHUT_2GPIO_SRC_EN(chn);
1420*4882a593Smuzhiyun val |= TSADCV2_SHUT_2CRU_SRC_EN(chn);
1421*4882a593Smuzhiyun }
1422*4882a593Smuzhiyun
1423*4882a593Smuzhiyun writel_relaxed(val, regs + TSADCV2_INT_EN);
1424*4882a593Smuzhiyun }
1425*4882a593Smuzhiyun
rk_tsadcv3_tshut_mode(struct regmap * grf,int chn,void __iomem * regs,enum tshut_mode mode)1426*4882a593Smuzhiyun static void rk_tsadcv3_tshut_mode(struct regmap *grf, int chn,
1427*4882a593Smuzhiyun void __iomem *regs,
1428*4882a593Smuzhiyun enum tshut_mode mode)
1429*4882a593Smuzhiyun {
1430*4882a593Smuzhiyun u32 val;
1431*4882a593Smuzhiyun
1432*4882a593Smuzhiyun val = readl_relaxed(regs + TSADCV2_INT_EN);
1433*4882a593Smuzhiyun if (mode == TSHUT_MODE_OTP) {
1434*4882a593Smuzhiyun val &= ~TSADCV2_SHUT_2CRU_SRC_EN(chn);
1435*4882a593Smuzhiyun val |= TSADCV2_SHUT_2GPIO_SRC_EN(chn);
1436*4882a593Smuzhiyun if (!IS_ERR(grf))
1437*4882a593Smuzhiyun regmap_write(grf, RV1126_GRF0_TSADC_CON,
1438*4882a593Smuzhiyun RV1126_GRF0_TSADC_SHUT_2GPIO);
1439*4882a593Smuzhiyun } else {
1440*4882a593Smuzhiyun val &= ~TSADCV2_SHUT_2GPIO_SRC_EN(chn);
1441*4882a593Smuzhiyun val |= TSADCV2_SHUT_2CRU_SRC_EN(chn);
1442*4882a593Smuzhiyun if (!IS_ERR(grf))
1443*4882a593Smuzhiyun regmap_write(grf, RV1126_GRF0_TSADC_CON,
1444*4882a593Smuzhiyun RV1126_GRF0_TSADC_SHUT_2CRU);
1445*4882a593Smuzhiyun }
1446*4882a593Smuzhiyun
1447*4882a593Smuzhiyun writel_relaxed(val, regs + TSADCV2_INT_EN);
1448*4882a593Smuzhiyun }
1449*4882a593Smuzhiyun
rk_tsadcv4_tshut_mode(struct regmap * grf,int chn,void __iomem * regs,enum tshut_mode mode)1450*4882a593Smuzhiyun static void rk_tsadcv4_tshut_mode(struct regmap *grf, int chn,
1451*4882a593Smuzhiyun void __iomem *regs,
1452*4882a593Smuzhiyun enum tshut_mode mode)
1453*4882a593Smuzhiyun {
1454*4882a593Smuzhiyun u32 val_gpio, val_cru;
1455*4882a593Smuzhiyun
1456*4882a593Smuzhiyun if (mode == TSHUT_MODE_OTP) {
1457*4882a593Smuzhiyun val_gpio = TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn);
1458*4882a593Smuzhiyun val_cru = TSADCV2_INT_SRC_EN_MASK(chn);
1459*4882a593Smuzhiyun } else {
1460*4882a593Smuzhiyun val_cru = TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn);
1461*4882a593Smuzhiyun val_gpio = TSADCV2_INT_SRC_EN_MASK(chn);
1462*4882a593Smuzhiyun }
1463*4882a593Smuzhiyun writel_relaxed(val_gpio, regs + TSADCV3_HSHUT_GPIO_INT_EN);
1464*4882a593Smuzhiyun writel_relaxed(val_cru, regs + TSADCV3_HSHUT_CRU_INT_EN);
1465*4882a593Smuzhiyun }
1466*4882a593Smuzhiyun
rk_tsadcv1_get_trim_code(const struct chip_tsadc_table * table,int code,int trim_base,int trim_base_frac)1467*4882a593Smuzhiyun static int rk_tsadcv1_get_trim_code(const struct chip_tsadc_table *table,
1468*4882a593Smuzhiyun int code, int trim_base, int trim_base_frac)
1469*4882a593Smuzhiyun {
1470*4882a593Smuzhiyun u32 base_code = (trim_base * table->kNum +
1471*4882a593Smuzhiyun trim_base_frac * table->kNum / 10) / 1000 + table->bNum;
1472*4882a593Smuzhiyun
1473*4882a593Smuzhiyun return code - base_code;
1474*4882a593Smuzhiyun }
1475*4882a593Smuzhiyun
rk_tsadcv2_get_trim_code(const struct chip_tsadc_table * table,int code,int trim_base,int trim_base_frac)1476*4882a593Smuzhiyun static int rk_tsadcv2_get_trim_code(const struct chip_tsadc_table *table,
1477*4882a593Smuzhiyun int code, int trim_base, int trim_base_frac)
1478*4882a593Smuzhiyun {
1479*4882a593Smuzhiyun int temp = trim_base * 1000 + trim_base_frac * 100;
1480*4882a593Smuzhiyun u32 base_code = rk_tsadcv2_temp_to_code(table, temp);
1481*4882a593Smuzhiyun
1482*4882a593Smuzhiyun return code - base_code;
1483*4882a593Smuzhiyun }
1484*4882a593Smuzhiyun
rk_tsadcv3_get_trim_code(const struct chip_tsadc_table * table,int code,int trim_base,int trim_base_frac)1485*4882a593Smuzhiyun static int rk_tsadcv3_get_trim_code(const struct chip_tsadc_table *table,
1486*4882a593Smuzhiyun int code, int trim_base, int trim_base_frac)
1487*4882a593Smuzhiyun {
1488*4882a593Smuzhiyun int temp = trim_base * 1000 + trim_base_frac * 100;
1489*4882a593Smuzhiyun u32 base_code = rk_tsadcv2_temp_to_code(table, temp);
1490*4882a593Smuzhiyun
1491*4882a593Smuzhiyun rk_tsadcv2_temp_to_code(table, temp);
1492*4882a593Smuzhiyun
1493*4882a593Smuzhiyun return (TSADCV3_Q_MAX_VAL - code) - base_code;
1494*4882a593Smuzhiyun }
1495*4882a593Smuzhiyun
rk_tsadcv1_set_clk_rate(struct platform_device * pdev)1496*4882a593Smuzhiyun static int rk_tsadcv1_set_clk_rate(struct platform_device *pdev)
1497*4882a593Smuzhiyun {
1498*4882a593Smuzhiyun struct clk *clk;
1499*4882a593Smuzhiyun int error;
1500*4882a593Smuzhiyun
1501*4882a593Smuzhiyun clk = devm_clk_get(&pdev->dev, "tsadc");
1502*4882a593Smuzhiyun if (IS_ERR(clk)) {
1503*4882a593Smuzhiyun error = PTR_ERR(clk);
1504*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to get tsadc clock\n");
1505*4882a593Smuzhiyun return error;
1506*4882a593Smuzhiyun }
1507*4882a593Smuzhiyun error = clk_set_rate(clk, 4000000);
1508*4882a593Smuzhiyun if (error < 0) {
1509*4882a593Smuzhiyun devm_clk_put(&pdev->dev, clk);
1510*4882a593Smuzhiyun dev_err(&pdev->dev,
1511*4882a593Smuzhiyun "failed to set tsadc clk rate to 4000000Hz\n");
1512*4882a593Smuzhiyun return error;
1513*4882a593Smuzhiyun }
1514*4882a593Smuzhiyun devm_clk_put(&pdev->dev, clk);
1515*4882a593Smuzhiyun
1516*4882a593Smuzhiyun return 0;
1517*4882a593Smuzhiyun }
1518*4882a593Smuzhiyun
1519*4882a593Smuzhiyun static const struct rockchip_tsadc_chip px30_tsadc_data = {
1520*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1521*4882a593Smuzhiyun .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
1522*4882a593Smuzhiyun .chn_num = 2, /* 2 channels for tsadc */
1523*4882a593Smuzhiyun
1524*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */
1525*4882a593Smuzhiyun .tshut_temp = 95000,
1526*4882a593Smuzhiyun
1527*4882a593Smuzhiyun .initialize = rk_tsadcv4_initialize,
1528*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1529*4882a593Smuzhiyun .control = rk_tsadcv3_control,
1530*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1531*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1532*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1533*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1534*4882a593Smuzhiyun
1535*4882a593Smuzhiyun .table = {
1536*4882a593Smuzhiyun .id = rk3328_code_table,
1537*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3328_code_table),
1538*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1539*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1540*4882a593Smuzhiyun },
1541*4882a593Smuzhiyun };
1542*4882a593Smuzhiyun
1543*4882a593Smuzhiyun static const struct rockchip_tsadc_chip px30s_tsadc_data = {
1544*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1545*4882a593Smuzhiyun .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
1546*4882a593Smuzhiyun .chn_num = 2, /* 1 channels for tsadc */
1547*4882a593Smuzhiyun .conversion_time = 2100, /* us */
1548*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */
1549*4882a593Smuzhiyun .tshut_temp = 95000,
1550*4882a593Smuzhiyun .initialize = rk_tsadcv10_initialize,
1551*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1552*4882a593Smuzhiyun .control = rk_tsadcv2_control,
1553*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1554*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1555*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1556*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1557*4882a593Smuzhiyun .set_clk_rate = rk_tsadcv1_set_clk_rate,
1558*4882a593Smuzhiyun .table = {
1559*4882a593Smuzhiyun .kNum = 2699,
1560*4882a593Smuzhiyun .bNum = 2796,
1561*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1562*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1563*4882a593Smuzhiyun },
1564*4882a593Smuzhiyun };
1565*4882a593Smuzhiyun
1566*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rv1106_tsadc_data = {
1567*4882a593Smuzhiyun /* top, big_core0, big_core1, little_core, center, gpu, npu */
1568*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1569*4882a593Smuzhiyun .chn_num = 1, /* seven channels for tsadc */
1570*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */
1571*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1572*4882a593Smuzhiyun .tshut_temp = 95000,
1573*4882a593Smuzhiyun .initialize = rk_tsadcv9_initialize,
1574*4882a593Smuzhiyun .irq_ack = rk_tsadcv4_irq_ack,
1575*4882a593Smuzhiyun .control = rk_tsadcv4_control,
1576*4882a593Smuzhiyun .get_temp = rk_tsadcv4_get_temp,
1577*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv3_alarm_temp,
1578*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv3_tshut_temp,
1579*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv4_tshut_mode,
1580*4882a593Smuzhiyun .table = {
1581*4882a593Smuzhiyun .id = rv1106_code_table,
1582*4882a593Smuzhiyun .length = ARRAY_SIZE(rv1106_code_table),
1583*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1584*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1585*4882a593Smuzhiyun },
1586*4882a593Smuzhiyun };
1587*4882a593Smuzhiyun
1588*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rv1108_tsadc_data = {
1589*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1590*4882a593Smuzhiyun .chn_num = 1, /* one channel for tsadc */
1591*4882a593Smuzhiyun
1592*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1593*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1594*4882a593Smuzhiyun .tshut_temp = 95000,
1595*4882a593Smuzhiyun
1596*4882a593Smuzhiyun .initialize = rk_tsadcv2_initialize,
1597*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1598*4882a593Smuzhiyun .control = rk_tsadcv3_control,
1599*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1600*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1601*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1602*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1603*4882a593Smuzhiyun
1604*4882a593Smuzhiyun .table = {
1605*4882a593Smuzhiyun .id = rv1108_table,
1606*4882a593Smuzhiyun .length = ARRAY_SIZE(rv1108_table),
1607*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1608*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1609*4882a593Smuzhiyun },
1610*4882a593Smuzhiyun };
1611*4882a593Smuzhiyun
1612*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rv1126_tsadc_data = {
1613*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1614*4882a593Smuzhiyun .chn_num = 1, /* one channel for tsadc */
1615*4882a593Smuzhiyun
1616*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */
1617*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1618*4882a593Smuzhiyun .tshut_temp = 95000,
1619*4882a593Smuzhiyun
1620*4882a593Smuzhiyun .initialize = rk_tsadcv6_initialize,
1621*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1622*4882a593Smuzhiyun .control = rk_tsadcv2_control,
1623*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1624*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1625*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1626*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv3_tshut_mode,
1627*4882a593Smuzhiyun .get_trim_code = rk_tsadcv1_get_trim_code,
1628*4882a593Smuzhiyun .trim_slope = 500,
1629*4882a593Smuzhiyun
1630*4882a593Smuzhiyun .table = {
1631*4882a593Smuzhiyun .kNum = 2263,
1632*4882a593Smuzhiyun .bNum = 2704,
1633*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1634*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1635*4882a593Smuzhiyun },
1636*4882a593Smuzhiyun };
1637*4882a593Smuzhiyun
1638*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk1808_tsadc_data = {
1639*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1640*4882a593Smuzhiyun .chn_num = 1, /* one channel for tsadc */
1641*4882a593Smuzhiyun
1642*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1643*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1644*4882a593Smuzhiyun .tshut_temp = 95000,
1645*4882a593Smuzhiyun
1646*4882a593Smuzhiyun .initialize = rk_tsadcv5_initialize,
1647*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1648*4882a593Smuzhiyun .control = rk_tsadcv3_control,
1649*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1650*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1651*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1652*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1653*4882a593Smuzhiyun
1654*4882a593Smuzhiyun .table = {
1655*4882a593Smuzhiyun .id = rk1808_code_table,
1656*4882a593Smuzhiyun .length = ARRAY_SIZE(rk1808_code_table),
1657*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1658*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1659*4882a593Smuzhiyun },
1660*4882a593Smuzhiyun };
1661*4882a593Smuzhiyun
1662*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3228_tsadc_data = {
1663*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1664*4882a593Smuzhiyun .chn_num = 1, /* one channel for tsadc */
1665*4882a593Smuzhiyun
1666*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1667*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1668*4882a593Smuzhiyun .tshut_temp = 95000,
1669*4882a593Smuzhiyun
1670*4882a593Smuzhiyun .initialize = rk_tsadcv2_initialize,
1671*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1672*4882a593Smuzhiyun .control = rk_tsadcv3_control,
1673*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1674*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1675*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1676*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1677*4882a593Smuzhiyun
1678*4882a593Smuzhiyun .table = {
1679*4882a593Smuzhiyun .id = rk3228_code_table,
1680*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3228_code_table),
1681*4882a593Smuzhiyun .data_mask = TSADCV3_DATA_MASK,
1682*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1683*4882a593Smuzhiyun },
1684*4882a593Smuzhiyun };
1685*4882a593Smuzhiyun
1686*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3288_tsadc_data = {
1687*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 1, /* cpu sensor is channel 1 */
1688*4882a593Smuzhiyun .chn_id[SENSOR_GPU] = 2, /* gpu sensor is channel 2 */
1689*4882a593Smuzhiyun .chn_num = 2, /* two channels for tsadc */
1690*4882a593Smuzhiyun
1691*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1692*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1693*4882a593Smuzhiyun .tshut_temp = 95000,
1694*4882a593Smuzhiyun
1695*4882a593Smuzhiyun .initialize = rk_tsadcv2_initialize,
1696*4882a593Smuzhiyun .irq_ack = rk_tsadcv2_irq_ack,
1697*4882a593Smuzhiyun .control = rk_tsadcv2_control,
1698*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1699*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1700*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1701*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1702*4882a593Smuzhiyun
1703*4882a593Smuzhiyun .table = {
1704*4882a593Smuzhiyun .id = rk3288_code_table,
1705*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3288_code_table),
1706*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1707*4882a593Smuzhiyun .mode = ADC_DECREMENT,
1708*4882a593Smuzhiyun },
1709*4882a593Smuzhiyun };
1710*4882a593Smuzhiyun
1711*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3308_tsadc_data = {
1712*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1713*4882a593Smuzhiyun .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
1714*4882a593Smuzhiyun .chn_num = 2, /* 2 channels for tsadc */
1715*4882a593Smuzhiyun
1716*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */
1717*4882a593Smuzhiyun .tshut_temp = 95000,
1718*4882a593Smuzhiyun
1719*4882a593Smuzhiyun .initialize = rk_tsadcv2_initialize,
1720*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1721*4882a593Smuzhiyun .control = rk_tsadcv3_control,
1722*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1723*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1724*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1725*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1726*4882a593Smuzhiyun
1727*4882a593Smuzhiyun .table = {
1728*4882a593Smuzhiyun .id = rk3328_code_table,
1729*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3328_code_table),
1730*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1731*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1732*4882a593Smuzhiyun },
1733*4882a593Smuzhiyun };
1734*4882a593Smuzhiyun
1735*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3308bs_tsadc_data = {
1736*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1737*4882a593Smuzhiyun .chn_num = 1, /* 1 channels for tsadc */
1738*4882a593Smuzhiyun
1739*4882a593Smuzhiyun .conversion_time = 2100, /* us */
1740*4882a593Smuzhiyun
1741*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */
1742*4882a593Smuzhiyun .tshut_temp = 95000,
1743*4882a593Smuzhiyun
1744*4882a593Smuzhiyun .initialize = rk_tsadcv2_initialize,
1745*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1746*4882a593Smuzhiyun .control = rk_tsadcv2_control,
1747*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1748*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1749*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1750*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1751*4882a593Smuzhiyun .set_clk_rate = rk_tsadcv1_set_clk_rate,
1752*4882a593Smuzhiyun
1753*4882a593Smuzhiyun .table = {
1754*4882a593Smuzhiyun .kNum = 2699,
1755*4882a593Smuzhiyun .bNum = 2796,
1756*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1757*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1758*4882a593Smuzhiyun },
1759*4882a593Smuzhiyun };
1760*4882a593Smuzhiyun
1761*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3328_tsadc_data = {
1762*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1763*4882a593Smuzhiyun .chn_num = 1, /* one channels for tsadc */
1764*4882a593Smuzhiyun
1765*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */
1766*4882a593Smuzhiyun .tshut_temp = 95000,
1767*4882a593Smuzhiyun
1768*4882a593Smuzhiyun .initialize = rk_tsadcv2_initialize,
1769*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1770*4882a593Smuzhiyun .control = rk_tsadcv3_control,
1771*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1772*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1773*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1774*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1775*4882a593Smuzhiyun
1776*4882a593Smuzhiyun .table = {
1777*4882a593Smuzhiyun .id = rk3328_code_table,
1778*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3328_code_table),
1779*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1780*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1781*4882a593Smuzhiyun },
1782*4882a593Smuzhiyun };
1783*4882a593Smuzhiyun
1784*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3366_tsadc_data = {
1785*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1786*4882a593Smuzhiyun .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
1787*4882a593Smuzhiyun .chn_num = 2, /* two channels for tsadc */
1788*4882a593Smuzhiyun
1789*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1790*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1791*4882a593Smuzhiyun .tshut_temp = 95000,
1792*4882a593Smuzhiyun
1793*4882a593Smuzhiyun .initialize = rk_tsadcv3_initialize,
1794*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1795*4882a593Smuzhiyun .control = rk_tsadcv3_control,
1796*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1797*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1798*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1799*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1800*4882a593Smuzhiyun
1801*4882a593Smuzhiyun .table = {
1802*4882a593Smuzhiyun .id = rk3228_code_table,
1803*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3228_code_table),
1804*4882a593Smuzhiyun .data_mask = TSADCV3_DATA_MASK,
1805*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1806*4882a593Smuzhiyun },
1807*4882a593Smuzhiyun };
1808*4882a593Smuzhiyun
1809*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3368_tsadc_data = {
1810*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1811*4882a593Smuzhiyun .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
1812*4882a593Smuzhiyun .chn_num = 2, /* two channels for tsadc */
1813*4882a593Smuzhiyun
1814*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1815*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1816*4882a593Smuzhiyun .tshut_temp = 95000,
1817*4882a593Smuzhiyun
1818*4882a593Smuzhiyun .initialize = rk_tsadcv2_initialize,
1819*4882a593Smuzhiyun .irq_ack = rk_tsadcv2_irq_ack,
1820*4882a593Smuzhiyun .control = rk_tsadcv2_control,
1821*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1822*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1823*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1824*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1825*4882a593Smuzhiyun
1826*4882a593Smuzhiyun .table = {
1827*4882a593Smuzhiyun .id = rk3368_code_table,
1828*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3368_code_table),
1829*4882a593Smuzhiyun .data_mask = TSADCV3_DATA_MASK,
1830*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1831*4882a593Smuzhiyun },
1832*4882a593Smuzhiyun };
1833*4882a593Smuzhiyun
1834*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3399_tsadc_data = {
1835*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1836*4882a593Smuzhiyun .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
1837*4882a593Smuzhiyun .chn_num = 2, /* two channels for tsadc */
1838*4882a593Smuzhiyun
1839*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1840*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1841*4882a593Smuzhiyun .tshut_temp = 95000,
1842*4882a593Smuzhiyun
1843*4882a593Smuzhiyun .initialize = rk_tsadcv3_initialize,
1844*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1845*4882a593Smuzhiyun .control = rk_tsadcv3_control,
1846*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1847*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1848*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1849*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1850*4882a593Smuzhiyun
1851*4882a593Smuzhiyun .table = {
1852*4882a593Smuzhiyun .id = rk3399_code_table,
1853*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3399_code_table),
1854*4882a593Smuzhiyun .data_mask = TSADCV3_DATA_MASK,
1855*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1856*4882a593Smuzhiyun },
1857*4882a593Smuzhiyun };
1858*4882a593Smuzhiyun
1859*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3528_tsadc_data = {
1860*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1861*4882a593Smuzhiyun .chn_num = 1, /* one channels for tsadc */
1862*4882a593Smuzhiyun
1863*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1864*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1865*4882a593Smuzhiyun .tshut_temp = 95000,
1866*4882a593Smuzhiyun
1867*4882a593Smuzhiyun .initialize = rk_tsadcv11_initialize,
1868*4882a593Smuzhiyun .irq_ack = rk_tsadcv4_irq_ack,
1869*4882a593Smuzhiyun .control = rk_tsadcv4_control,
1870*4882a593Smuzhiyun .get_temp = rk_tsadcv4_get_temp,
1871*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv3_alarm_temp,
1872*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv3_tshut_temp,
1873*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv4_tshut_mode,
1874*4882a593Smuzhiyun
1875*4882a593Smuzhiyun .table = {
1876*4882a593Smuzhiyun .id = rk3528_code_table,
1877*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3528_code_table),
1878*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1879*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1880*4882a593Smuzhiyun },
1881*4882a593Smuzhiyun };
1882*4882a593Smuzhiyun
1883*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3562_tsadc_data = {
1884*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1885*4882a593Smuzhiyun .chn_num = 1, /* one channels for tsadc */
1886*4882a593Smuzhiyun
1887*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1888*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1889*4882a593Smuzhiyun .tshut_temp = 95000,
1890*4882a593Smuzhiyun
1891*4882a593Smuzhiyun .initialize = rk_tsadcv12_initialize,
1892*4882a593Smuzhiyun .irq_ack = rk_tsadcv4_irq_ack,
1893*4882a593Smuzhiyun .control = rk_tsadcv4_control,
1894*4882a593Smuzhiyun .get_temp = rk_tsadcv4_get_temp,
1895*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv3_alarm_temp,
1896*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv3_tshut_temp,
1897*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv4_tshut_mode,
1898*4882a593Smuzhiyun .get_trim_code = rk_tsadcv3_get_trim_code,
1899*4882a593Smuzhiyun .trim_slope = 588,
1900*4882a593Smuzhiyun
1901*4882a593Smuzhiyun .table = {
1902*4882a593Smuzhiyun .id = rk3562_code_table,
1903*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3562_code_table),
1904*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1905*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1906*4882a593Smuzhiyun },
1907*4882a593Smuzhiyun };
1908*4882a593Smuzhiyun
1909*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3568_tsadc_data = {
1910*4882a593Smuzhiyun .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
1911*4882a593Smuzhiyun .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
1912*4882a593Smuzhiyun .chn_num = 2, /* two channels for tsadc */
1913*4882a593Smuzhiyun
1914*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1915*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1916*4882a593Smuzhiyun .tshut_temp = 95000,
1917*4882a593Smuzhiyun
1918*4882a593Smuzhiyun .initialize = rk_tsadcv7_initialize,
1919*4882a593Smuzhiyun .irq_ack = rk_tsadcv3_irq_ack,
1920*4882a593Smuzhiyun .control = rk_tsadcv3_control,
1921*4882a593Smuzhiyun .get_temp = rk_tsadcv2_get_temp,
1922*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv2_alarm_temp,
1923*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv2_tshut_temp,
1924*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv2_tshut_mode,
1925*4882a593Smuzhiyun .get_trim_code = rk_tsadcv2_get_trim_code,
1926*4882a593Smuzhiyun .trim_slope = 147,
1927*4882a593Smuzhiyun
1928*4882a593Smuzhiyun .table = {
1929*4882a593Smuzhiyun .id = rk3568_code_table,
1930*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3568_code_table),
1931*4882a593Smuzhiyun .data_mask = TSADCV2_DATA_MASK,
1932*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1933*4882a593Smuzhiyun },
1934*4882a593Smuzhiyun };
1935*4882a593Smuzhiyun
1936*4882a593Smuzhiyun static const struct rockchip_tsadc_chip rk3588_tsadc_data = {
1937*4882a593Smuzhiyun /* top, big_core0, big_core1, little_core, center, gpu, npu */
1938*4882a593Smuzhiyun .chn_id = {0, 1, 2, 3, 4, 5, 6},
1939*4882a593Smuzhiyun .chn_num = 7, /* seven channels for tsadc */
1940*4882a593Smuzhiyun .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */
1941*4882a593Smuzhiyun .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
1942*4882a593Smuzhiyun .tshut_temp = 95000,
1943*4882a593Smuzhiyun .initialize = rk_tsadcv8_initialize,
1944*4882a593Smuzhiyun .irq_ack = rk_tsadcv4_irq_ack,
1945*4882a593Smuzhiyun .control = rk_tsadcv4_control,
1946*4882a593Smuzhiyun .get_temp = rk_tsadcv4_get_temp,
1947*4882a593Smuzhiyun .set_alarm_temp = rk_tsadcv3_alarm_temp,
1948*4882a593Smuzhiyun .set_tshut_temp = rk_tsadcv3_tshut_temp,
1949*4882a593Smuzhiyun .set_tshut_mode = rk_tsadcv4_tshut_mode,
1950*4882a593Smuzhiyun .table = {
1951*4882a593Smuzhiyun .id = rk3588_code_table,
1952*4882a593Smuzhiyun .length = ARRAY_SIZE(rk3588_code_table),
1953*4882a593Smuzhiyun .data_mask = TSADCV4_DATA_MASK,
1954*4882a593Smuzhiyun .mode = ADC_INCREMENT,
1955*4882a593Smuzhiyun },
1956*4882a593Smuzhiyun };
1957*4882a593Smuzhiyun
1958*4882a593Smuzhiyun static const struct of_device_id of_rockchip_thermal_match[] = {
1959*4882a593Smuzhiyun #ifdef CONFIG_CPU_PX30
1960*4882a593Smuzhiyun { .compatible = "rockchip,px30-tsadc",
1961*4882a593Smuzhiyun .data = (void *)&px30_tsadc_data,
1962*4882a593Smuzhiyun },
1963*4882a593Smuzhiyun { .compatible = "rockchip,px30s-tsadc",
1964*4882a593Smuzhiyun .data = (void *)&px30s_tsadc_data,
1965*4882a593Smuzhiyun },
1966*4882a593Smuzhiyun #endif
1967*4882a593Smuzhiyun #ifdef CONFIG_CPU_RV1106
1968*4882a593Smuzhiyun {
1969*4882a593Smuzhiyun .compatible = "rockchip,rv1106-tsadc",
1970*4882a593Smuzhiyun .data = (void *)&rv1106_tsadc_data,
1971*4882a593Smuzhiyun },
1972*4882a593Smuzhiyun #endif
1973*4882a593Smuzhiyun #ifdef CONFIG_CPU_RV1108
1974*4882a593Smuzhiyun {
1975*4882a593Smuzhiyun .compatible = "rockchip,rv1108-tsadc",
1976*4882a593Smuzhiyun .data = (void *)&rv1108_tsadc_data,
1977*4882a593Smuzhiyun },
1978*4882a593Smuzhiyun #endif
1979*4882a593Smuzhiyun #ifdef CONFIG_CPU_RV1126
1980*4882a593Smuzhiyun {
1981*4882a593Smuzhiyun .compatible = "rockchip,rv1126-tsadc",
1982*4882a593Smuzhiyun .data = (void *)&rv1126_tsadc_data,
1983*4882a593Smuzhiyun },
1984*4882a593Smuzhiyun #endif
1985*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK1808
1986*4882a593Smuzhiyun {
1987*4882a593Smuzhiyun .compatible = "rockchip,rk1808-tsadc",
1988*4882a593Smuzhiyun .data = (void *)&rk1808_tsadc_data,
1989*4882a593Smuzhiyun },
1990*4882a593Smuzhiyun #endif
1991*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK322X
1992*4882a593Smuzhiyun {
1993*4882a593Smuzhiyun .compatible = "rockchip,rk3228-tsadc",
1994*4882a593Smuzhiyun .data = (void *)&rk3228_tsadc_data,
1995*4882a593Smuzhiyun },
1996*4882a593Smuzhiyun #endif
1997*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK3288
1998*4882a593Smuzhiyun {
1999*4882a593Smuzhiyun .compatible = "rockchip,rk3288-tsadc",
2000*4882a593Smuzhiyun .data = (void *)&rk3288_tsadc_data,
2001*4882a593Smuzhiyun },
2002*4882a593Smuzhiyun #endif
2003*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK3308
2004*4882a593Smuzhiyun {
2005*4882a593Smuzhiyun .compatible = "rockchip,rk3308-tsadc",
2006*4882a593Smuzhiyun .data = (void *)&rk3308_tsadc_data,
2007*4882a593Smuzhiyun },
2008*4882a593Smuzhiyun {
2009*4882a593Smuzhiyun .compatible = "rockchip,rk3308bs-tsadc",
2010*4882a593Smuzhiyun .data = (void *)&rk3308bs_tsadc_data,
2011*4882a593Smuzhiyun },
2012*4882a593Smuzhiyun #endif
2013*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK3328
2014*4882a593Smuzhiyun {
2015*4882a593Smuzhiyun .compatible = "rockchip,rk3328-tsadc",
2016*4882a593Smuzhiyun .data = (void *)&rk3328_tsadc_data,
2017*4882a593Smuzhiyun },
2018*4882a593Smuzhiyun #endif
2019*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK3366
2020*4882a593Smuzhiyun {
2021*4882a593Smuzhiyun .compatible = "rockchip,rk3366-tsadc",
2022*4882a593Smuzhiyun .data = (void *)&rk3366_tsadc_data,
2023*4882a593Smuzhiyun },
2024*4882a593Smuzhiyun #endif
2025*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK3368
2026*4882a593Smuzhiyun {
2027*4882a593Smuzhiyun .compatible = "rockchip,rk3368-tsadc",
2028*4882a593Smuzhiyun .data = (void *)&rk3368_tsadc_data,
2029*4882a593Smuzhiyun },
2030*4882a593Smuzhiyun #endif
2031*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK3399
2032*4882a593Smuzhiyun {
2033*4882a593Smuzhiyun .compatible = "rockchip,rk3399-tsadc",
2034*4882a593Smuzhiyun .data = (void *)&rk3399_tsadc_data,
2035*4882a593Smuzhiyun },
2036*4882a593Smuzhiyun #endif
2037*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK3528
2038*4882a593Smuzhiyun {
2039*4882a593Smuzhiyun .compatible = "rockchip,rk3528-tsadc",
2040*4882a593Smuzhiyun .data = (void *)&rk3528_tsadc_data,
2041*4882a593Smuzhiyun },
2042*4882a593Smuzhiyun #endif
2043*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK3562
2044*4882a593Smuzhiyun {
2045*4882a593Smuzhiyun .compatible = "rockchip,rk3562-tsadc",
2046*4882a593Smuzhiyun .data = (void *)&rk3562_tsadc_data,
2047*4882a593Smuzhiyun },
2048*4882a593Smuzhiyun #endif
2049*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK3568
2050*4882a593Smuzhiyun {
2051*4882a593Smuzhiyun .compatible = "rockchip,rk3568-tsadc",
2052*4882a593Smuzhiyun .data = (void *)&rk3568_tsadc_data,
2053*4882a593Smuzhiyun },
2054*4882a593Smuzhiyun #endif
2055*4882a593Smuzhiyun #ifdef CONFIG_CPU_RK3588
2056*4882a593Smuzhiyun {
2057*4882a593Smuzhiyun .compatible = "rockchip,rk3588-tsadc",
2058*4882a593Smuzhiyun .data = (void *)&rk3588_tsadc_data,
2059*4882a593Smuzhiyun },
2060*4882a593Smuzhiyun #endif
2061*4882a593Smuzhiyun { /* end */ },
2062*4882a593Smuzhiyun };
2063*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match);
2064*4882a593Smuzhiyun
2065*4882a593Smuzhiyun static void
rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor * sensor,bool on)2066*4882a593Smuzhiyun rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on)
2067*4882a593Smuzhiyun {
2068*4882a593Smuzhiyun struct thermal_zone_device *tzd = sensor->tzd;
2069*4882a593Smuzhiyun
2070*4882a593Smuzhiyun if (on)
2071*4882a593Smuzhiyun thermal_zone_device_enable(tzd);
2072*4882a593Smuzhiyun else
2073*4882a593Smuzhiyun thermal_zone_device_disable(tzd);
2074*4882a593Smuzhiyun }
2075*4882a593Smuzhiyun
rockchip_thermal_alarm_irq_thread(int irq,void * dev)2076*4882a593Smuzhiyun static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev)
2077*4882a593Smuzhiyun {
2078*4882a593Smuzhiyun struct rockchip_thermal_data *thermal = dev;
2079*4882a593Smuzhiyun int i;
2080*4882a593Smuzhiyun
2081*4882a593Smuzhiyun dev_dbg(&thermal->pdev->dev, "thermal alarm\n");
2082*4882a593Smuzhiyun
2083*4882a593Smuzhiyun thermal->chip->irq_ack(thermal->regs);
2084*4882a593Smuzhiyun
2085*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++)
2086*4882a593Smuzhiyun thermal_zone_device_update(thermal->sensors[i].tzd,
2087*4882a593Smuzhiyun THERMAL_EVENT_UNSPECIFIED);
2088*4882a593Smuzhiyun
2089*4882a593Smuzhiyun return IRQ_HANDLED;
2090*4882a593Smuzhiyun }
2091*4882a593Smuzhiyun
rockchip_thermal_set_trips(void * _sensor,int low,int high)2092*4882a593Smuzhiyun static int rockchip_thermal_set_trips(void *_sensor, int low, int high)
2093*4882a593Smuzhiyun {
2094*4882a593Smuzhiyun struct rockchip_thermal_sensor *sensor = _sensor;
2095*4882a593Smuzhiyun struct rockchip_thermal_data *thermal = sensor->thermal;
2096*4882a593Smuzhiyun const struct rockchip_tsadc_chip *tsadc = thermal->chip;
2097*4882a593Smuzhiyun
2098*4882a593Smuzhiyun dev_dbg(&thermal->pdev->dev, "%s: sensor %d: low: %d, high %d\n",
2099*4882a593Smuzhiyun __func__, sensor->id, low, high);
2100*4882a593Smuzhiyun
2101*4882a593Smuzhiyun high += sensor->trim_temp;
2102*4882a593Smuzhiyun
2103*4882a593Smuzhiyun return tsadc->set_alarm_temp(&tsadc->table,
2104*4882a593Smuzhiyun sensor->id, thermal->regs, high);
2105*4882a593Smuzhiyun }
2106*4882a593Smuzhiyun
rockchip_thermal_get_temp(void * _sensor,int * out_temp)2107*4882a593Smuzhiyun static int rockchip_thermal_get_temp(void *_sensor, int *out_temp)
2108*4882a593Smuzhiyun {
2109*4882a593Smuzhiyun struct rockchip_thermal_sensor *sensor = _sensor;
2110*4882a593Smuzhiyun struct rockchip_thermal_data *thermal = sensor->thermal;
2111*4882a593Smuzhiyun const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip;
2112*4882a593Smuzhiyun int retval;
2113*4882a593Smuzhiyun
2114*4882a593Smuzhiyun retval = tsadc->get_temp(&tsadc->table,
2115*4882a593Smuzhiyun sensor->id, thermal->regs, out_temp);
2116*4882a593Smuzhiyun *out_temp -= sensor->trim_temp;
2117*4882a593Smuzhiyun dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n",
2118*4882a593Smuzhiyun sensor->id, *out_temp, retval);
2119*4882a593Smuzhiyun
2120*4882a593Smuzhiyun return retval;
2121*4882a593Smuzhiyun }
2122*4882a593Smuzhiyun
2123*4882a593Smuzhiyun static const struct thermal_zone_of_device_ops rockchip_of_thermal_ops = {
2124*4882a593Smuzhiyun .get_temp = rockchip_thermal_get_temp,
2125*4882a593Smuzhiyun .set_trips = rockchip_thermal_set_trips,
2126*4882a593Smuzhiyun };
2127*4882a593Smuzhiyun
thermal_pinctrl_select_otp(struct rockchip_thermal_data * thermal)2128*4882a593Smuzhiyun static void thermal_pinctrl_select_otp(struct rockchip_thermal_data *thermal)
2129*4882a593Smuzhiyun {
2130*4882a593Smuzhiyun if (!IS_ERR(thermal->pinctrl) && !IS_ERR_OR_NULL(thermal->otp_state))
2131*4882a593Smuzhiyun pinctrl_select_state(thermal->pinctrl,
2132*4882a593Smuzhiyun thermal->otp_state);
2133*4882a593Smuzhiyun }
2134*4882a593Smuzhiyun
thermal_pinctrl_select_gpio(struct rockchip_thermal_data * thermal)2135*4882a593Smuzhiyun static void thermal_pinctrl_select_gpio(struct rockchip_thermal_data *thermal)
2136*4882a593Smuzhiyun {
2137*4882a593Smuzhiyun if (!IS_ERR(thermal->pinctrl) && !IS_ERR_OR_NULL(thermal->gpio_state))
2138*4882a593Smuzhiyun pinctrl_select_state(thermal->pinctrl,
2139*4882a593Smuzhiyun thermal->gpio_state);
2140*4882a593Smuzhiyun }
2141*4882a593Smuzhiyun
rockchip_get_efuse_value(struct device_node * np,char * porp_name,int * value)2142*4882a593Smuzhiyun static int rockchip_get_efuse_value(struct device_node *np, char *porp_name,
2143*4882a593Smuzhiyun int *value)
2144*4882a593Smuzhiyun {
2145*4882a593Smuzhiyun struct nvmem_cell *cell;
2146*4882a593Smuzhiyun unsigned char *buf;
2147*4882a593Smuzhiyun size_t len;
2148*4882a593Smuzhiyun
2149*4882a593Smuzhiyun cell = of_nvmem_cell_get(np, porp_name);
2150*4882a593Smuzhiyun if (IS_ERR(cell))
2151*4882a593Smuzhiyun return PTR_ERR(cell);
2152*4882a593Smuzhiyun
2153*4882a593Smuzhiyun buf = (unsigned char *)nvmem_cell_read(cell, &len);
2154*4882a593Smuzhiyun
2155*4882a593Smuzhiyun nvmem_cell_put(cell);
2156*4882a593Smuzhiyun
2157*4882a593Smuzhiyun if (IS_ERR(buf))
2158*4882a593Smuzhiyun return PTR_ERR(buf);
2159*4882a593Smuzhiyun
2160*4882a593Smuzhiyun *value = buf[0];
2161*4882a593Smuzhiyun
2162*4882a593Smuzhiyun kfree(buf);
2163*4882a593Smuzhiyun
2164*4882a593Smuzhiyun return 0;
2165*4882a593Smuzhiyun }
2166*4882a593Smuzhiyun
rockchip_get_trim_configure(struct device * dev,struct device_node * np,struct rockchip_thermal_data * thermal)2167*4882a593Smuzhiyun static int rockchip_get_trim_configure(struct device *dev,
2168*4882a593Smuzhiyun struct device_node *np,
2169*4882a593Smuzhiyun struct rockchip_thermal_data *thermal)
2170*4882a593Smuzhiyun {
2171*4882a593Smuzhiyun const struct rockchip_tsadc_chip *tsadc = thermal->chip;
2172*4882a593Smuzhiyun struct device_node *node;
2173*4882a593Smuzhiyun int trim_base = 0, trim_base_frac = 0, trim_l = 0, trim_h = 0;
2174*4882a593Smuzhiyun int trim_temp, trim_code;
2175*4882a593Smuzhiyun int i, id;
2176*4882a593Smuzhiyun
2177*4882a593Smuzhiyun if (!tsadc->get_trim_code)
2178*4882a593Smuzhiyun return 0;
2179*4882a593Smuzhiyun /*
2180*4882a593Smuzhiyun * The tsadc won't to handle the error in here
2181*4882a593Smuzhiyun * since some SoCs didn't need this property.
2182*4882a593Smuzhiyun */
2183*4882a593Smuzhiyun rockchip_get_efuse_value(np, "trim_base", &trim_base);
2184*4882a593Smuzhiyun if (!trim_base)
2185*4882a593Smuzhiyun trim_base = 30;
2186*4882a593Smuzhiyun rockchip_get_efuse_value(np, "trim_base_frac", &trim_base_frac);
2187*4882a593Smuzhiyun /*
2188*4882a593Smuzhiyun * If the tsadc node contains trim_h and trim_l property,
2189*4882a593Smuzhiyun * all channels use the common trim configure, otherwise,
2190*4882a593Smuzhiyun * get trim configure from child nodes.
2191*4882a593Smuzhiyun */
2192*4882a593Smuzhiyun if (!rockchip_get_efuse_value(np, "trim_l", &trim_l) &&
2193*4882a593Smuzhiyun !rockchip_get_efuse_value(np, "trim_h", &trim_h)) {
2194*4882a593Smuzhiyun if (!trim_l && !trim_h)
2195*4882a593Smuzhiyun return 0;
2196*4882a593Smuzhiyun trim_code = tsadc->get_trim_code(&tsadc->table,
2197*4882a593Smuzhiyun (trim_h << 8) | trim_l,
2198*4882a593Smuzhiyun trim_base, trim_base_frac);
2199*4882a593Smuzhiyun trim_temp = thermal->chip->trim_slope * trim_code;
2200*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++) {
2201*4882a593Smuzhiyun thermal->sensors[i].trim_temp = trim_temp;
2202*4882a593Smuzhiyun thermal->sensors[i].tshut_temp += trim_temp;
2203*4882a593Smuzhiyun if (thermal->sensors[i].tshut_temp > MAX_TEMP)
2204*4882a593Smuzhiyun thermal->sensors[i].tshut_temp = MAX_TEMP;
2205*4882a593Smuzhiyun }
2206*4882a593Smuzhiyun } else {
2207*4882a593Smuzhiyun for_each_available_child_of_node(np, node) {
2208*4882a593Smuzhiyun if (of_property_read_u32(node, "reg", &id)) {
2209*4882a593Smuzhiyun dev_info(dev, "Missing tsadc id property\n");
2210*4882a593Smuzhiyun continue;
2211*4882a593Smuzhiyun }
2212*4882a593Smuzhiyun if (id >= SOC_MAX_SENSORS)
2213*4882a593Smuzhiyun continue;
2214*4882a593Smuzhiyun if (rockchip_get_efuse_value(node, "trim_l", &trim_l)) {
2215*4882a593Smuzhiyun dev_info(dev, "ch%d Missing trim_l property\n",
2216*4882a593Smuzhiyun id);
2217*4882a593Smuzhiyun continue;
2218*4882a593Smuzhiyun }
2219*4882a593Smuzhiyun if (rockchip_get_efuse_value(node, "trim_h", &trim_h)) {
2220*4882a593Smuzhiyun dev_info(dev, "ch%d Missing trim_h property\n",
2221*4882a593Smuzhiyun id);
2222*4882a593Smuzhiyun continue;
2223*4882a593Smuzhiyun }
2224*4882a593Smuzhiyun if (!trim_l && !trim_h)
2225*4882a593Smuzhiyun continue;
2226*4882a593Smuzhiyun trim_code = tsadc->get_trim_code(&tsadc->table,
2227*4882a593Smuzhiyun (trim_h << 8) | trim_l,
2228*4882a593Smuzhiyun trim_base,
2229*4882a593Smuzhiyun trim_base_frac);
2230*4882a593Smuzhiyun trim_temp = thermal->chip->trim_slope * trim_code;
2231*4882a593Smuzhiyun thermal->sensors[id].trim_temp = trim_temp;
2232*4882a593Smuzhiyun thermal->sensors[id].tshut_temp += trim_temp;
2233*4882a593Smuzhiyun if (thermal->sensors[id].tshut_temp > MAX_TEMP)
2234*4882a593Smuzhiyun thermal->sensors[id].tshut_temp = MAX_TEMP;
2235*4882a593Smuzhiyun }
2236*4882a593Smuzhiyun }
2237*4882a593Smuzhiyun
2238*4882a593Smuzhiyun return 0;
2239*4882a593Smuzhiyun }
2240*4882a593Smuzhiyun
rockchip_configure_from_dt(struct device * dev,struct device_node * np,struct rockchip_thermal_data * thermal)2241*4882a593Smuzhiyun static int rockchip_configure_from_dt(struct device *dev,
2242*4882a593Smuzhiyun struct device_node *np,
2243*4882a593Smuzhiyun struct rockchip_thermal_data *thermal)
2244*4882a593Smuzhiyun {
2245*4882a593Smuzhiyun u32 shut_temp, tshut_mode, tshut_polarity;
2246*4882a593Smuzhiyun int i;
2247*4882a593Smuzhiyun
2248*4882a593Smuzhiyun if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) {
2249*4882a593Smuzhiyun dev_warn(dev,
2250*4882a593Smuzhiyun "Missing tshut temp property, using default %d\n",
2251*4882a593Smuzhiyun thermal->chip->tshut_temp);
2252*4882a593Smuzhiyun shut_temp = thermal->chip->tshut_temp;
2253*4882a593Smuzhiyun }
2254*4882a593Smuzhiyun if (shut_temp > INT_MAX) {
2255*4882a593Smuzhiyun dev_err(dev, "Invalid tshut temperature specified: %d\n",
2256*4882a593Smuzhiyun shut_temp);
2257*4882a593Smuzhiyun return -ERANGE;
2258*4882a593Smuzhiyun }
2259*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++)
2260*4882a593Smuzhiyun thermal->sensors[i].tshut_temp = shut_temp;
2261*4882a593Smuzhiyun
2262*4882a593Smuzhiyun if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) {
2263*4882a593Smuzhiyun dev_warn(dev,
2264*4882a593Smuzhiyun "Missing tshut mode property, using default (%s)\n",
2265*4882a593Smuzhiyun thermal->chip->tshut_mode == TSHUT_MODE_OTP ?
2266*4882a593Smuzhiyun "gpio" : "cru");
2267*4882a593Smuzhiyun thermal->tshut_mode = thermal->chip->tshut_mode;
2268*4882a593Smuzhiyun } else {
2269*4882a593Smuzhiyun thermal->tshut_mode = tshut_mode;
2270*4882a593Smuzhiyun }
2271*4882a593Smuzhiyun
2272*4882a593Smuzhiyun if (thermal->tshut_mode > 1) {
2273*4882a593Smuzhiyun dev_err(dev, "Invalid tshut mode specified: %d\n",
2274*4882a593Smuzhiyun thermal->tshut_mode);
2275*4882a593Smuzhiyun return -EINVAL;
2276*4882a593Smuzhiyun }
2277*4882a593Smuzhiyun
2278*4882a593Smuzhiyun if (of_property_read_u32(np, "rockchip,hw-tshut-polarity",
2279*4882a593Smuzhiyun &tshut_polarity)) {
2280*4882a593Smuzhiyun dev_warn(dev,
2281*4882a593Smuzhiyun "Missing tshut-polarity property, using default (%s)\n",
2282*4882a593Smuzhiyun thermal->chip->tshut_polarity == TSHUT_LOW_ACTIVE ?
2283*4882a593Smuzhiyun "low" : "high");
2284*4882a593Smuzhiyun thermal->tshut_polarity = thermal->chip->tshut_polarity;
2285*4882a593Smuzhiyun } else {
2286*4882a593Smuzhiyun thermal->tshut_polarity = tshut_polarity;
2287*4882a593Smuzhiyun }
2288*4882a593Smuzhiyun
2289*4882a593Smuzhiyun if (thermal->tshut_polarity > 1) {
2290*4882a593Smuzhiyun dev_err(dev, "Invalid tshut-polarity specified: %d\n",
2291*4882a593Smuzhiyun thermal->tshut_polarity);
2292*4882a593Smuzhiyun return -EINVAL;
2293*4882a593Smuzhiyun }
2294*4882a593Smuzhiyun
2295*4882a593Smuzhiyun /* The tsadc wont to handle the error in here since some SoCs didn't
2296*4882a593Smuzhiyun * need this property.
2297*4882a593Smuzhiyun */
2298*4882a593Smuzhiyun thermal->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
2299*4882a593Smuzhiyun if (IS_ERR(thermal->grf))
2300*4882a593Smuzhiyun dev_warn(dev, "Missing rockchip,grf property\n");
2301*4882a593Smuzhiyun
2302*4882a593Smuzhiyun rockchip_get_trim_configure(dev, np, thermal);
2303*4882a593Smuzhiyun
2304*4882a593Smuzhiyun return 0;
2305*4882a593Smuzhiyun }
2306*4882a593Smuzhiyun
2307*4882a593Smuzhiyun static int
rockchip_thermal_register_sensor(struct platform_device * pdev,struct rockchip_thermal_data * thermal,struct rockchip_thermal_sensor * sensor,int id)2308*4882a593Smuzhiyun rockchip_thermal_register_sensor(struct platform_device *pdev,
2309*4882a593Smuzhiyun struct rockchip_thermal_data *thermal,
2310*4882a593Smuzhiyun struct rockchip_thermal_sensor *sensor,
2311*4882a593Smuzhiyun int id)
2312*4882a593Smuzhiyun {
2313*4882a593Smuzhiyun const struct rockchip_tsadc_chip *tsadc = thermal->chip;
2314*4882a593Smuzhiyun int error;
2315*4882a593Smuzhiyun
2316*4882a593Smuzhiyun tsadc->set_tshut_mode(thermal->grf, id, thermal->regs,
2317*4882a593Smuzhiyun thermal->tshut_mode);
2318*4882a593Smuzhiyun
2319*4882a593Smuzhiyun error = tsadc->set_tshut_temp(&tsadc->table, id, thermal->regs,
2320*4882a593Smuzhiyun sensor->tshut_temp);
2321*4882a593Smuzhiyun if (error)
2322*4882a593Smuzhiyun dev_err(&pdev->dev, "%s: invalid tshut=%d, error=%d\n",
2323*4882a593Smuzhiyun __func__, sensor->tshut_temp, error);
2324*4882a593Smuzhiyun
2325*4882a593Smuzhiyun sensor->thermal = thermal;
2326*4882a593Smuzhiyun sensor->id = id;
2327*4882a593Smuzhiyun sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, id,
2328*4882a593Smuzhiyun sensor, &rockchip_of_thermal_ops);
2329*4882a593Smuzhiyun if (IS_ERR(sensor->tzd)) {
2330*4882a593Smuzhiyun error = PTR_ERR(sensor->tzd);
2331*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to register sensor %d: %d\n",
2332*4882a593Smuzhiyun id, error);
2333*4882a593Smuzhiyun return error;
2334*4882a593Smuzhiyun }
2335*4882a593Smuzhiyun
2336*4882a593Smuzhiyun return 0;
2337*4882a593Smuzhiyun }
2338*4882a593Smuzhiyun
2339*4882a593Smuzhiyun /**
2340*4882a593Smuzhiyun * Reset TSADC Controller, reset all tsadc registers.
2341*4882a593Smuzhiyun * @reset: the reset controller of tsadc
2342*4882a593Smuzhiyun */
rockchip_thermal_reset_controller(struct reset_control * reset)2343*4882a593Smuzhiyun static void rockchip_thermal_reset_controller(struct reset_control *reset)
2344*4882a593Smuzhiyun {
2345*4882a593Smuzhiyun reset_control_assert(reset);
2346*4882a593Smuzhiyun usleep_range(10, 20);
2347*4882a593Smuzhiyun reset_control_deassert(reset);
2348*4882a593Smuzhiyun }
2349*4882a593Smuzhiyun
rockchip_dump_temperature(struct rockchip_thermal_data * thermal)2350*4882a593Smuzhiyun static void rockchip_dump_temperature(struct rockchip_thermal_data *thermal)
2351*4882a593Smuzhiyun {
2352*4882a593Smuzhiyun struct platform_device *pdev;
2353*4882a593Smuzhiyun int i;
2354*4882a593Smuzhiyun
2355*4882a593Smuzhiyun if (!thermal)
2356*4882a593Smuzhiyun return;
2357*4882a593Smuzhiyun
2358*4882a593Smuzhiyun pdev = thermal->pdev;
2359*4882a593Smuzhiyun
2360*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++) {
2361*4882a593Smuzhiyun struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];
2362*4882a593Smuzhiyun struct thermal_zone_device *tz = sensor->tzd;
2363*4882a593Smuzhiyun
2364*4882a593Smuzhiyun if (tz->temperature != THERMAL_TEMP_INVALID)
2365*4882a593Smuzhiyun dev_warn(&pdev->dev, "channal %d: temperature(%d C)\n",
2366*4882a593Smuzhiyun i, tz->temperature / 1000);
2367*4882a593Smuzhiyun }
2368*4882a593Smuzhiyun
2369*4882a593Smuzhiyun if (thermal->regs) {
2370*4882a593Smuzhiyun pr_warn("THERMAL REGS:\n");
2371*4882a593Smuzhiyun print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET,
2372*4882a593Smuzhiyun 32, 4, thermal->regs, 0x88, false);
2373*4882a593Smuzhiyun }
2374*4882a593Smuzhiyun }
2375*4882a593Smuzhiyun
rockchip_thermal_panic(struct notifier_block * this,unsigned long ev,void * ptr)2376*4882a593Smuzhiyun static int rockchip_thermal_panic(struct notifier_block *this,
2377*4882a593Smuzhiyun unsigned long ev, void *ptr)
2378*4882a593Smuzhiyun {
2379*4882a593Smuzhiyun struct rockchip_thermal_data *thermal;
2380*4882a593Smuzhiyun
2381*4882a593Smuzhiyun thermal = container_of(this, struct rockchip_thermal_data, panic_nb);
2382*4882a593Smuzhiyun rockchip_dump_temperature(thermal);
2383*4882a593Smuzhiyun
2384*4882a593Smuzhiyun return NOTIFY_DONE;
2385*4882a593Smuzhiyun }
2386*4882a593Smuzhiyun
rockchip_thermal_probe(struct platform_device * pdev)2387*4882a593Smuzhiyun static int rockchip_thermal_probe(struct platform_device *pdev)
2388*4882a593Smuzhiyun {
2389*4882a593Smuzhiyun struct device_node *np = pdev->dev.of_node;
2390*4882a593Smuzhiyun struct rockchip_thermal_data *thermal;
2391*4882a593Smuzhiyun const struct of_device_id *match;
2392*4882a593Smuzhiyun struct resource *res;
2393*4882a593Smuzhiyun int irq;
2394*4882a593Smuzhiyun int i;
2395*4882a593Smuzhiyun int error;
2396*4882a593Smuzhiyun
2397*4882a593Smuzhiyun match = of_match_node(of_rockchip_thermal_match, np);
2398*4882a593Smuzhiyun if (!match)
2399*4882a593Smuzhiyun return -ENXIO;
2400*4882a593Smuzhiyun
2401*4882a593Smuzhiyun irq = platform_get_irq(pdev, 0);
2402*4882a593Smuzhiyun if (irq < 0)
2403*4882a593Smuzhiyun return -EINVAL;
2404*4882a593Smuzhiyun
2405*4882a593Smuzhiyun thermal = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_thermal_data),
2406*4882a593Smuzhiyun GFP_KERNEL);
2407*4882a593Smuzhiyun if (!thermal)
2408*4882a593Smuzhiyun return -ENOMEM;
2409*4882a593Smuzhiyun
2410*4882a593Smuzhiyun thermal->pdev = pdev;
2411*4882a593Smuzhiyun
2412*4882a593Smuzhiyun thermal->chip = (const struct rockchip_tsadc_chip *)match->data;
2413*4882a593Smuzhiyun if (!thermal->chip)
2414*4882a593Smuzhiyun return -EINVAL;
2415*4882a593Smuzhiyun if (soc_is_px30s())
2416*4882a593Smuzhiyun thermal->chip = &px30s_tsadc_data;
2417*4882a593Smuzhiyun if (soc_is_rk3308bs())
2418*4882a593Smuzhiyun thermal->chip = &rk3308bs_tsadc_data;
2419*4882a593Smuzhiyun
2420*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2421*4882a593Smuzhiyun thermal->regs = devm_ioremap_resource(&pdev->dev, res);
2422*4882a593Smuzhiyun if (IS_ERR(thermal->regs))
2423*4882a593Smuzhiyun return PTR_ERR(thermal->regs);
2424*4882a593Smuzhiyun
2425*4882a593Smuzhiyun thermal->reset = devm_reset_control_array_get(&pdev->dev, false, false);
2426*4882a593Smuzhiyun if (IS_ERR(thermal->reset)) {
2427*4882a593Smuzhiyun if (PTR_ERR(thermal->reset) != -EPROBE_DEFER)
2428*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to get tsadc reset lines\n");
2429*4882a593Smuzhiyun return PTR_ERR(thermal->reset);
2430*4882a593Smuzhiyun }
2431*4882a593Smuzhiyun
2432*4882a593Smuzhiyun thermal->num_clks = devm_clk_bulk_get_all(&pdev->dev, &thermal->clks);
2433*4882a593Smuzhiyun if (thermal->num_clks < 1)
2434*4882a593Smuzhiyun return -ENODEV;
2435*4882a593Smuzhiyun
2436*4882a593Smuzhiyun error = clk_bulk_prepare_enable(thermal->num_clks, thermal->clks);
2437*4882a593Smuzhiyun if (error) {
2438*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to prepare enable tsadc bulk clks: %d\n",
2439*4882a593Smuzhiyun error);
2440*4882a593Smuzhiyun return error;
2441*4882a593Smuzhiyun }
2442*4882a593Smuzhiyun platform_set_drvdata(pdev, thermal);
2443*4882a593Smuzhiyun
2444*4882a593Smuzhiyun if (thermal->chip->set_clk_rate)
2445*4882a593Smuzhiyun thermal->chip->set_clk_rate(pdev);
2446*4882a593Smuzhiyun
2447*4882a593Smuzhiyun thermal->chip->control(thermal->regs, false);
2448*4882a593Smuzhiyun
2449*4882a593Smuzhiyun rockchip_thermal_reset_controller(thermal->reset);
2450*4882a593Smuzhiyun
2451*4882a593Smuzhiyun error = rockchip_configure_from_dt(&pdev->dev, np, thermal);
2452*4882a593Smuzhiyun if (error) {
2453*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to parse device tree data: %d\n",
2454*4882a593Smuzhiyun error);
2455*4882a593Smuzhiyun goto err_disable_clocks;
2456*4882a593Smuzhiyun }
2457*4882a593Smuzhiyun
2458*4882a593Smuzhiyun thermal->chip->initialize(thermal->grf, thermal->regs,
2459*4882a593Smuzhiyun thermal->tshut_polarity);
2460*4882a593Smuzhiyun
2461*4882a593Smuzhiyun if (thermal->tshut_mode == TSHUT_MODE_OTP) {
2462*4882a593Smuzhiyun thermal->pinctrl = devm_pinctrl_get(&pdev->dev);
2463*4882a593Smuzhiyun if (IS_ERR(thermal->pinctrl))
2464*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to find thermal pinctrl\n");
2465*4882a593Smuzhiyun
2466*4882a593Smuzhiyun thermal->gpio_state = pinctrl_lookup_state(thermal->pinctrl,
2467*4882a593Smuzhiyun "gpio");
2468*4882a593Smuzhiyun if (IS_ERR_OR_NULL(thermal->gpio_state))
2469*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to find thermal gpio state\n");
2470*4882a593Smuzhiyun
2471*4882a593Smuzhiyun thermal->otp_state = pinctrl_lookup_state(thermal->pinctrl,
2472*4882a593Smuzhiyun "otpout");
2473*4882a593Smuzhiyun if (IS_ERR_OR_NULL(thermal->otp_state))
2474*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to find thermal otpout state\n");
2475*4882a593Smuzhiyun
2476*4882a593Smuzhiyun thermal_pinctrl_select_otp(thermal);
2477*4882a593Smuzhiyun }
2478*4882a593Smuzhiyun
2479*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++) {
2480*4882a593Smuzhiyun error = rockchip_thermal_register_sensor(pdev, thermal,
2481*4882a593Smuzhiyun &thermal->sensors[i],
2482*4882a593Smuzhiyun thermal->chip->chn_id[i]);
2483*4882a593Smuzhiyun if (error) {
2484*4882a593Smuzhiyun dev_err(&pdev->dev,
2485*4882a593Smuzhiyun "failed to register sensor[%d] : error = %d\n",
2486*4882a593Smuzhiyun i, error);
2487*4882a593Smuzhiyun goto err_disable_clocks;
2488*4882a593Smuzhiyun }
2489*4882a593Smuzhiyun }
2490*4882a593Smuzhiyun
2491*4882a593Smuzhiyun error = devm_request_threaded_irq(&pdev->dev, irq, NULL,
2492*4882a593Smuzhiyun &rockchip_thermal_alarm_irq_thread,
2493*4882a593Smuzhiyun IRQF_ONESHOT,
2494*4882a593Smuzhiyun "rockchip_thermal", thermal);
2495*4882a593Smuzhiyun if (error) {
2496*4882a593Smuzhiyun dev_err(&pdev->dev,
2497*4882a593Smuzhiyun "failed to request tsadc irq: %d\n", error);
2498*4882a593Smuzhiyun goto err_disable_clocks;
2499*4882a593Smuzhiyun }
2500*4882a593Smuzhiyun
2501*4882a593Smuzhiyun thermal->chip->control(thermal->regs, true);
2502*4882a593Smuzhiyun if (thermal->chip->conversion_time)
2503*4882a593Smuzhiyun usleep_range(thermal->chip->conversion_time,
2504*4882a593Smuzhiyun thermal->chip->conversion_time + 50);
2505*4882a593Smuzhiyun
2506*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++) {
2507*4882a593Smuzhiyun rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
2508*4882a593Smuzhiyun thermal->sensors[i].tzd->tzp->no_hwmon = false;
2509*4882a593Smuzhiyun error = thermal_add_hwmon_sysfs(thermal->sensors[i].tzd);
2510*4882a593Smuzhiyun if (error)
2511*4882a593Smuzhiyun dev_warn(&pdev->dev,
2512*4882a593Smuzhiyun "failed to register sensor %d with hwmon: %d\n",
2513*4882a593Smuzhiyun i, error);
2514*4882a593Smuzhiyun }
2515*4882a593Smuzhiyun
2516*4882a593Smuzhiyun thermal->panic_nb.notifier_call = rockchip_thermal_panic;
2517*4882a593Smuzhiyun atomic_notifier_chain_register(&panic_notifier_list,
2518*4882a593Smuzhiyun &thermal->panic_nb);
2519*4882a593Smuzhiyun
2520*4882a593Smuzhiyun dev_info(&pdev->dev, "tsadc is probed successfully!\n");
2521*4882a593Smuzhiyun
2522*4882a593Smuzhiyun return 0;
2523*4882a593Smuzhiyun
2524*4882a593Smuzhiyun err_disable_clocks:
2525*4882a593Smuzhiyun clk_bulk_disable_unprepare(thermal->num_clks, thermal->clks);
2526*4882a593Smuzhiyun
2527*4882a593Smuzhiyun return error;
2528*4882a593Smuzhiyun }
2529*4882a593Smuzhiyun
rockchip_thermal_remove(struct platform_device * pdev)2530*4882a593Smuzhiyun static int rockchip_thermal_remove(struct platform_device *pdev)
2531*4882a593Smuzhiyun {
2532*4882a593Smuzhiyun struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
2533*4882a593Smuzhiyun int i;
2534*4882a593Smuzhiyun
2535*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++) {
2536*4882a593Smuzhiyun struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];
2537*4882a593Smuzhiyun
2538*4882a593Smuzhiyun thermal_remove_hwmon_sysfs(sensor->tzd);
2539*4882a593Smuzhiyun rockchip_thermal_toggle_sensor(sensor, false);
2540*4882a593Smuzhiyun }
2541*4882a593Smuzhiyun
2542*4882a593Smuzhiyun thermal->chip->control(thermal->regs, false);
2543*4882a593Smuzhiyun
2544*4882a593Smuzhiyun clk_bulk_disable_unprepare(thermal->num_clks, thermal->clks);
2545*4882a593Smuzhiyun
2546*4882a593Smuzhiyun return 0;
2547*4882a593Smuzhiyun }
2548*4882a593Smuzhiyun
rockchip_thermal_shutdown(struct platform_device * pdev)2549*4882a593Smuzhiyun static void rockchip_thermal_shutdown(struct platform_device *pdev)
2550*4882a593Smuzhiyun {
2551*4882a593Smuzhiyun struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
2552*4882a593Smuzhiyun int i;
2553*4882a593Smuzhiyun
2554*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++) {
2555*4882a593Smuzhiyun int id = thermal->sensors[i].id;
2556*4882a593Smuzhiyun
2557*4882a593Smuzhiyun if (thermal->tshut_mode != TSHUT_MODE_CRU)
2558*4882a593Smuzhiyun thermal->chip->set_tshut_mode(thermal->grf, id,
2559*4882a593Smuzhiyun thermal->regs,
2560*4882a593Smuzhiyun TSHUT_MODE_CRU);
2561*4882a593Smuzhiyun }
2562*4882a593Smuzhiyun if (thermal->tshut_mode == TSHUT_MODE_OTP)
2563*4882a593Smuzhiyun thermal_pinctrl_select_gpio(thermal);
2564*4882a593Smuzhiyun }
2565*4882a593Smuzhiyun
rockchip_thermal_suspend(struct device * dev)2566*4882a593Smuzhiyun static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
2567*4882a593Smuzhiyun {
2568*4882a593Smuzhiyun struct rockchip_thermal_data *thermal = dev_get_drvdata(dev);
2569*4882a593Smuzhiyun int i;
2570*4882a593Smuzhiyun
2571*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++)
2572*4882a593Smuzhiyun rockchip_thermal_toggle_sensor(&thermal->sensors[i], false);
2573*4882a593Smuzhiyun
2574*4882a593Smuzhiyun thermal->chip->control(thermal->regs, false);
2575*4882a593Smuzhiyun
2576*4882a593Smuzhiyun clk_bulk_disable(thermal->num_clks, thermal->clks);
2577*4882a593Smuzhiyun
2578*4882a593Smuzhiyun if (thermal->tshut_mode == TSHUT_MODE_OTP)
2579*4882a593Smuzhiyun thermal_pinctrl_select_gpio(thermal);
2580*4882a593Smuzhiyun
2581*4882a593Smuzhiyun return 0;
2582*4882a593Smuzhiyun }
2583*4882a593Smuzhiyun
rockchip_thermal_resume(struct device * dev)2584*4882a593Smuzhiyun static int __maybe_unused rockchip_thermal_resume(struct device *dev)
2585*4882a593Smuzhiyun {
2586*4882a593Smuzhiyun struct rockchip_thermal_data *thermal = dev_get_drvdata(dev);
2587*4882a593Smuzhiyun int i;
2588*4882a593Smuzhiyun int error;
2589*4882a593Smuzhiyun
2590*4882a593Smuzhiyun error = clk_bulk_enable(thermal->num_clks, thermal->clks);
2591*4882a593Smuzhiyun if (error) {
2592*4882a593Smuzhiyun dev_err(dev, "failed to enable tsadc bulk clks: %d\n",
2593*4882a593Smuzhiyun error);
2594*4882a593Smuzhiyun return error;
2595*4882a593Smuzhiyun }
2596*4882a593Smuzhiyun
2597*4882a593Smuzhiyun rockchip_thermal_reset_controller(thermal->reset);
2598*4882a593Smuzhiyun
2599*4882a593Smuzhiyun thermal->chip->initialize(thermal->grf, thermal->regs,
2600*4882a593Smuzhiyun thermal->tshut_polarity);
2601*4882a593Smuzhiyun
2602*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++) {
2603*4882a593Smuzhiyun int id = thermal->sensors[i].id;
2604*4882a593Smuzhiyun int tshut_temp = thermal->sensors[i].tshut_temp;
2605*4882a593Smuzhiyun
2606*4882a593Smuzhiyun thermal->chip->set_tshut_mode(thermal->grf, id, thermal->regs,
2607*4882a593Smuzhiyun thermal->tshut_mode);
2608*4882a593Smuzhiyun
2609*4882a593Smuzhiyun error = thermal->chip->set_tshut_temp(&thermal->chip->table,
2610*4882a593Smuzhiyun id, thermal->regs,
2611*4882a593Smuzhiyun tshut_temp);
2612*4882a593Smuzhiyun if (error)
2613*4882a593Smuzhiyun dev_err(dev, "%s: invalid tshut=%d, error=%d\n",
2614*4882a593Smuzhiyun __func__, tshut_temp, error);
2615*4882a593Smuzhiyun }
2616*4882a593Smuzhiyun
2617*4882a593Smuzhiyun thermal->chip->control(thermal->regs, true);
2618*4882a593Smuzhiyun if (thermal->chip->conversion_time)
2619*4882a593Smuzhiyun usleep_range(thermal->chip->conversion_time,
2620*4882a593Smuzhiyun thermal->chip->conversion_time + 50);
2621*4882a593Smuzhiyun
2622*4882a593Smuzhiyun for (i = 0; i < thermal->chip->chn_num; i++)
2623*4882a593Smuzhiyun rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
2624*4882a593Smuzhiyun
2625*4882a593Smuzhiyun if (thermal->tshut_mode == TSHUT_MODE_OTP)
2626*4882a593Smuzhiyun thermal_pinctrl_select_otp(thermal);
2627*4882a593Smuzhiyun
2628*4882a593Smuzhiyun return 0;
2629*4882a593Smuzhiyun }
2630*4882a593Smuzhiyun
2631*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(rockchip_thermal_pm_ops,
2632*4882a593Smuzhiyun rockchip_thermal_suspend, rockchip_thermal_resume);
2633*4882a593Smuzhiyun
2634*4882a593Smuzhiyun static struct platform_driver rockchip_thermal_driver = {
2635*4882a593Smuzhiyun .driver = {
2636*4882a593Smuzhiyun .name = "rockchip-thermal",
2637*4882a593Smuzhiyun .pm = &rockchip_thermal_pm_ops,
2638*4882a593Smuzhiyun .of_match_table = of_rockchip_thermal_match,
2639*4882a593Smuzhiyun },
2640*4882a593Smuzhiyun .probe = rockchip_thermal_probe,
2641*4882a593Smuzhiyun .remove = rockchip_thermal_remove,
2642*4882a593Smuzhiyun .shutdown = rockchip_thermal_shutdown,
2643*4882a593Smuzhiyun };
2644*4882a593Smuzhiyun
rockchip_thermal_driver_init(void)2645*4882a593Smuzhiyun static int __init rockchip_thermal_driver_init(void)
2646*4882a593Smuzhiyun {
2647*4882a593Smuzhiyun return platform_driver_register(&rockchip_thermal_driver);
2648*4882a593Smuzhiyun }
2649*4882a593Smuzhiyun rootfs_initcall(rockchip_thermal_driver_init);
2650*4882a593Smuzhiyun
rockchip_thermal_driver_exit(void)2651*4882a593Smuzhiyun static void __exit rockchip_thermal_driver_exit(void)
2652*4882a593Smuzhiyun {
2653*4882a593Smuzhiyun platform_driver_unregister(&rockchip_thermal_driver);
2654*4882a593Smuzhiyun }
2655*4882a593Smuzhiyun module_exit(rockchip_thermal_driver_exit);
2656*4882a593Smuzhiyun
2657*4882a593Smuzhiyun MODULE_DESCRIPTION("ROCKCHIP THERMAL Driver");
2658*4882a593Smuzhiyun MODULE_AUTHOR("Rockchip, Inc.");
2659*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
2660*4882a593Smuzhiyun MODULE_ALIAS("platform:rockchip-thermal");
2661