xref: /OK3568_Linux_fs/u-boot/drivers/rtc/rk8xx_rtc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 #include <power/pmic.h>
10 #include <power/rk8xx_pmic.h>
11 #include <irq-generic.h>
12 #include <asm/arch/periph.h>
13 #include <dm/pinctrl.h>
14 #include <rtc.h>
15 
16 #define	RK817_INT_STS_REG0	0xf8
17 #define	RK817_INT_MSK_REG0	0xf9
18 
19 #define	RK816_INT_STS_REG2	0x4c
20 #define	RK816_INT_MSK_REG2	0x4d
21 
22 #define	RK808_INT_STS_REG1	0x4c
23 #define	RK808_INT_MSK_REG1	0x4d
24 
25 #define	RK805_INT_STS_REG	0x4c
26 #define	RK805_INT_MSK_REG	0x4d
27 
28 #define RK808_RTC_CTRL_REG	0x10
29 #define RK808_RTC_STATUS_REG	0x11
30 #define RK808_RTC_INT_REG	0x12
31 
32 #define RK817_RTC_CTRL_REG	0x0d
33 #define RK817_RTC_STATUS_REG	0x0e
34 #define RK817_RTC_INT_REG	0x0f
35 
36 #define RTC_ALARM_EN		5
37 #define RTC_ALARM_STATUS	BIT(6)
38 
39 struct rk8xx_rtc_priv {
40 	u8 rtc_int_sts_reg;
41 	u8 rtc_int_msk_reg;
42 	u8 int_sts_reg;
43 	u8 int_msk_reg;
44 	int rtc_alarm_trigger;
45 	int irq_is_busy;
46 };
47 
rtc_irq_handler(int irq,void * data)48 static void rtc_irq_handler(int irq, void *data)
49 {
50 	struct udevice *dev = data;
51 	struct rk8xx_rtc_priv *priv = dev_get_priv(dev);
52 	int ret, val;
53 
54 	debug("%s: irq = %d\n", __func__, irq);
55 
56 	if (priv->rtc_int_sts_reg) {
57 		val = pmic_reg_read(dev->parent, priv->rtc_int_sts_reg);
58 		if (val < 0) {
59 			printf("%s: i2c read reg 0x%x failed, ret=%d\n",
60 			       __func__, priv->rtc_int_sts_reg, val);
61 			return;
62 		}
63 
64 		if (val & RTC_ALARM_STATUS) {
65 			priv->rtc_alarm_trigger = 1;
66 			printf("RTC: alarm interrupt\n");
67 		}
68 
69 		ret = pmic_reg_write(dev->parent,
70 				     priv->rtc_int_sts_reg, 0xfe);
71 		if (ret < 0) {
72 			printf("%s: i2c write reg 0x%x failed, ret=%d\n",
73 			       __func__, priv->rtc_int_sts_reg, ret);
74 			return;
75 		}
76 	}
77 
78 	ret = pmic_reg_write(dev->parent,
79 			     priv->int_sts_reg, 0xff);
80 	if (ret < 0) {
81 		printf("%s: i2c write reg 0x%x failed, ret=%d\n",
82 		       __func__, priv->int_sts_reg, ret);
83 		return;
84 	}
85 	debug("%s: reg[0x%x] = 0x%x\n", __func__, priv->int_sts_reg,
86 	      pmic_reg_read(dev->parent, priv->int_sts_reg));
87 }
88 
rtc_interrupt_init(struct udevice * dev)89 static int rtc_interrupt_init(struct udevice *dev)
90 {
91 	struct rk8xx_rtc_priv *priv = dev_get_priv(dev);
92 	u32 interrupt[2], phandle;
93 	int irq, ret;
94 
95 	phandle = dev_read_u32_default(dev->parent, "interrupt-parent", -1);
96 	if (phandle < 0) {
97 		printf("failed get 'interrupt-parent', ret=%d\n", phandle);
98 		return phandle;
99 	}
100 
101 	ret = dev_read_u32_array(dev->parent, "interrupts", interrupt, 2);
102 	if (ret) {
103 		printf("failed get 'interrupt', ret=%d\n", ret);
104 		return ret;
105 	}
106 
107 	irq = phandle_gpio_to_irq(phandle, interrupt[0]);
108 	if (irq < 0) {
109 		if (irq == -EBUSY) {
110 			priv->irq_is_busy = 1;
111 			return 0;
112 		}
113 		return irq;
114 	}
115 	irq_install_handler(irq, rtc_irq_handler, dev);
116 	irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
117 	irq_handler_enable(irq);
118 
119 	return 0;
120 }
121 
rk8xx_rtc_alarm_trigger(struct udevice * dev)122 static int rk8xx_rtc_alarm_trigger(struct udevice *dev)
123 {
124 	struct rk8xx_rtc_priv *priv = dev_get_priv(dev);
125 	int val, ret, alarm_trigger = 0;
126 
127 	if (priv->irq_is_busy) {
128 		val = pmic_reg_read(dev->parent, priv->rtc_int_sts_reg);
129 		if (val < 0) {
130 			printf("%s: i2c read reg 0x%x failed, ret=%d\n",
131 			       __func__, priv->rtc_int_sts_reg, val);
132 			return val;
133 		}
134 		if (val & RTC_ALARM_STATUS) {
135 			alarm_trigger = 1;
136 			printf("rtc alarm interrupt\n");
137 		}
138 		ret = pmic_reg_write(dev->parent,
139 				     priv->rtc_int_sts_reg, 0xfe);
140 		if (ret < 0) {
141 			printf("%s: i2c write reg 0x%x failed, ret=%d\n",
142 			       __func__, priv->rtc_int_sts_reg, ret);
143 			return ret;
144 		}
145 		return alarm_trigger;
146 	} else {
147 		return priv->rtc_alarm_trigger;
148 	}
149 }
150 
151 static struct rtc_ops rk8xx_rtc_ops = {
152 	.alarm_trigger = rk8xx_rtc_alarm_trigger,
153 };
154 
rk8xx_rtc_probe(struct udevice * dev)155 static int rk8xx_rtc_probe(struct udevice *dev)
156 {
157 	struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent);
158 	struct rk8xx_rtc_priv *priv = dev_get_priv(dev);
159 	int ret, val;
160 
161 	priv->rtc_int_sts_reg = RK808_RTC_STATUS_REG;
162 	priv->rtc_int_msk_reg = RK808_RTC_INT_REG;
163 	switch (rk8xx->variant) {
164 	case RK808_ID:
165 	case RK818_ID:
166 		priv->int_msk_reg = RK808_INT_MSK_REG1;
167 		priv->int_sts_reg = RK808_INT_STS_REG1;
168 		break;
169 	case RK805_ID:
170 		priv->int_msk_reg = RK805_INT_MSK_REG;
171 		priv->int_sts_reg = RK805_INT_STS_REG;
172 		break;
173 	case RK816_ID:
174 		priv->int_msk_reg = RK816_INT_MSK_REG2;
175 		priv->int_sts_reg = RK816_INT_STS_REG2;
176 		break;
177 	case RK809_ID:
178 	case RK817_ID:
179 		priv->rtc_int_sts_reg = RK817_RTC_STATUS_REG;
180 		priv->rtc_int_msk_reg = RK817_RTC_INT_REG;
181 		priv->int_msk_reg = RK817_INT_MSK_REG0;
182 		priv->int_sts_reg = RK817_INT_STS_REG0;
183 		break;
184 	default:
185 		return -EINVAL;
186 	}
187 
188 	priv->rtc_alarm_trigger = 0;
189 	priv->irq_is_busy = 0;
190 	/* mask and clear interrupt */
191 	val = pmic_reg_read(dev->parent, priv->int_msk_reg);
192 	if (val < 0) {
193 		printf("%s: i2c read reg 0x%x failed, ret=%d\n",
194 		       __func__, priv->int_msk_reg, val);
195 		return val;
196 	}
197 	ret = pmic_reg_write(dev->parent,
198 			     priv->int_msk_reg, val | 0xc1);
199 	if (ret < 0) {
200 		printf("%s: i2c write reg 0x%x failed, ret=%d\n",
201 		       __func__, priv->int_msk_reg, ret);
202 		return ret;
203 	}
204 	val = pmic_reg_read(dev->parent, priv->int_sts_reg);
205 	if (val < 0) {
206 		printf("%s: i2c read reg 0x%x failed, ret=%d\n",
207 		       __func__, priv->int_sts_reg, val);
208 		return val;
209 	}
210 	ret = pmic_reg_write(dev->parent,
211 			     priv->int_sts_reg,
212 			     val | (1 << RTC_ALARM_EN));
213 	if (ret < 0) {
214 		printf("%s: i2c write reg 0x%x failed, ret=%d\n",
215 		       __func__, priv->int_sts_reg, ret);
216 		return ret;
217 	}
218 	debug("%s: reg[0x%x] = 0x%x\n", __func__, priv->int_msk_reg,
219 	      pmic_reg_read(dev->parent, priv->int_msk_reg));
220 	debug("%s: reg[0x%x] = 0x%x\n", __func__, priv->int_sts_reg,
221 	      pmic_reg_read(dev->parent, priv->int_sts_reg));
222 
223 	return rtc_interrupt_init(dev);
224 }
225 
226 U_BOOT_DRIVER(rk8xx_rtc) = {
227 	.name   = "rk8xx_rtc",
228 	.id     = UCLASS_RTC,
229 	.probe  = rk8xx_rtc_probe,
230 	.ops	= &rk8xx_rtc_ops,
231 	.priv_auto_alloc_size = sizeof(struct rk8xx_rtc_priv),
232 };
233