blob: 76a26426855984519ae86b44d6902e1cfc7fa81e [file] [log] [blame]
Angel Ponsbbc99cf2020-04-04 18:51:23 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Shunqian Zhengf4181ce2016-05-06 16:50:48 +08002
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
Shunqian Zhengf4181ce2016-05-06 16:50:48 +08004#include <delay.h>
5#include <soc/clock.h>
6#include <soc/grf.h>
7#include <soc/tsadc.h>
8#include <stdint.h>
Shunqian Zhengf4181ce2016-05-06 16:50:48 +08009
10struct rk3399_tsadc_regs {
11 u32 user_con;
12 u32 auto_con;
13 u32 int_en;
14 u32 int_pd;
15 u32 reserved0[(0x20 - 0x10) / 4];
16 u32 data0;
17 u32 data1;
18 u32 data2;
19 u32 data3;
20 u32 comp0_int;
21 u32 comp1_int;
22 u32 comp2_int;
23 u32 comp3_int;
24 u32 comp0_shut;
25 u32 comp1_shut;
26 u32 comp2_shut;
27 u32 comp3_shut;
28 u32 reserved1[(0x60 - 0x50) / 4];
29 u32 hight_int_debounce;
30 u32 hight_tshut_debounce;
31 u32 auto_period;
32 u32 auto_period_ht;
33};
34check_member(rk3399_tsadc_regs, auto_period_ht, 0x6c);
35
36/* user_con */
37#define ADC_POWER_CTRL (1 << 3)
38#define START_MODE (1 << 4)
39#define START_SHIFT 5
40#define START_MASK 1
41#define INTER_PD_SHIFT 6
42#define INTER_PD_MASK 0x3f
43
44/* auto_con */
45#define LAST_TSHUT (1 << 24)
46#define SRC3_EN (1 << 7)
47#define SRC2_EN (1 << 6)
48#define SRC1_EN (1 << 5)
49#define SRC0_EN (1 << 4)
50#define Q_SEL (1 << 1)
51#define AUTO_EN (1 << 0)
52
53/* int_en */
54#define TSHUT_CRU_EN_SRC3 (1 << 11)
55#define TSHUT_CRU_EN_SRC2 (1 << 10)
56#define TSHUT_CRU_EN_SRC1 (1 << 9)
57#define TSHUT_CRU_EN_SRC0 (1 << 8)
58#define TSHUT_GPIO_EN_SRC3 (1 << 7)
59#define TSHUT_GPIO_EN_SRC2 (1 << 6)
60#define TSHUT_GPIO_EN_SRC1 (1 << 5)
61#define TSHUT_GPIO_EN_SRC0 (1 << 4)
62
63#define AUTO_PERIOD 187500 /* 250ms */
64#define AUTO_DEBOUNCE 4
65#define AUTO_PERIOD_HT 37500 /* 50ms */
66#define AUTO_DEBOUNCE_HT 4
67#define TSADC_CLOCK_HZ (750 * KHz)
68
69/* AD value, correspond to 120 degrees Celsius,
70 * Please refer shut value table in:
71 * https://patchwork.kernel.org/patch/8908411/
72 * A quick ref:
73 * {573, 60000}, {599, 75000}, {616, 85000}, {633, 95000},
74 * {642, 100000}, {659, 110000}, {677, 120000}, {685, 125000}
75 */
76#define TSADC_SHUT_VALUE 677
77
78#define GRF_TSADC_TSEN_PD0_ON RK_SETBITS(0)
79#define GRF_TSADC_TSEN_PD0_OFF RK_CLRBITS(0)
80#define GRF_SARADC_TSEN_ON RK_SETBITS(0)
81
82struct rk3399_tsadc_regs *rk3399_tsadc = (void *)TSADC_BASE;
83
84void tsadc_init(uint32_t polarity)
85{
86 rkclk_configure_tsadc(TSADC_CLOCK_HZ);
87
88 /* tsadc power sequence */
Julius Werner55009af2019-12-02 22:03:27 -080089 clrbits32(&rk3399_tsadc->user_con, ADC_POWER_CTRL);
Shunqian Zhengf4181ce2016-05-06 16:50:48 +080090 write32(&rk3399_grf->tsadc_testbit_l, GRF_TSADC_TSEN_PD0_ON);
91 udelay(50);
92 write32(&rk3399_grf->tsadc_testbit_l, GRF_TSADC_TSEN_PD0_OFF);
93 udelay(20);
94 write32(&rk3399_grf->saradc_testbit, GRF_SARADC_TSEN_ON);
95 udelay(100);
96
97 /* set the tshut polarity */
98 write32(&rk3399_tsadc->auto_con, polarity);
99
100 /* setup the automatic mode:
101 * AUTO_PERIOD: interleave between every two accessing of TSADC
Elyes HAOUAS8d1b0f12020-02-20 18:20:57 +0100102 * AUTO_DEBOUNCE: only generate interrupt or TSHUT when temperature
Shunqian Zhengf4181ce2016-05-06 16:50:48 +0800103 * is higher than COMP_INT for "debounce" times
104 * AUTO_PERIOD_HT: the interleave between every two accessing after the
105 * temperature is higher than COMP_SHUT or COMP_INT
106 * AUTO_DEBOUNCE_HT: only generate interrupt or TSHUT when temperature
107 * is higher than COMP_SHUT for "debounce" times.
108 */
109 write32(&rk3399_tsadc->auto_period, AUTO_PERIOD);
110 write32(&rk3399_tsadc->hight_int_debounce, AUTO_DEBOUNCE);
111 write32(&rk3399_tsadc->auto_period_ht, AUTO_PERIOD_HT);
112 write32(&rk3399_tsadc->hight_tshut_debounce, AUTO_DEBOUNCE_HT);
Elyes HAOUAS8d1b0f12020-02-20 18:20:57 +0100113 /* Enable the src0, negative temperature coefficient */
Julius Werner55009af2019-12-02 22:03:27 -0800114 setbits32(&rk3399_tsadc->auto_con, Q_SEL | SRC0_EN);
Shunqian Zhengf4181ce2016-05-06 16:50:48 +0800115 udelay(100);
Julius Werner55009af2019-12-02 22:03:27 -0800116 setbits32(&rk3399_tsadc->auto_con, AUTO_EN);
Shunqian Zhengf4181ce2016-05-06 16:50:48 +0800117
118 write32(&rk3399_tsadc->comp0_shut, TSADC_SHUT_VALUE);
119 write32(&rk3399_tsadc->int_en, TSHUT_CRU_EN_SRC0 | TSHUT_GPIO_EN_SRC0);
120
121 /* Set the tsadc_int pinmux */
122 write32(&rk3399_pmugrf->tsadc_int, IOMUX_TSADC_INT);
123}