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 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 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 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 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