1*c89ac918SYiting Deng // SPDX-License-Identifier: (GPL-2.0-only OR MIT) 2*c89ac918SYiting Deng /* 3*c89ac918SYiting Deng * Copyright (C) 2024 Amlogic, Inc. All rights reserved 4*c89ac918SYiting Deng * Author: Yiting Deng <yiting.deng@amlogic.com> 5*c89ac918SYiting Deng */ 6*c89ac918SYiting Deng 7*c89ac918SYiting Deng #include <linux/bitfield.h> 8*c89ac918SYiting Deng #include <linux/clk.h> 9*c89ac918SYiting Deng #include <linux/clk-provider.h> 10*c89ac918SYiting Deng #include <linux/delay.h> 11*c89ac918SYiting Deng #include <linux/module.h> 12*c89ac918SYiting Deng #include <linux/platform_device.h> 13*c89ac918SYiting Deng #include <linux/regmap.h> 14*c89ac918SYiting Deng #include <linux/rtc.h> 15*c89ac918SYiting Deng #include <linux/time64.h> 16*c89ac918SYiting Deng 17*c89ac918SYiting Deng /* rtc oscillator rate */ 18*c89ac918SYiting Deng #define OSC_32K 32768 19*c89ac918SYiting Deng #define OSC_24M 24000000 20*c89ac918SYiting Deng 21*c89ac918SYiting Deng #define RTC_CTRL (0x0 << 2) /* Control RTC */ 22*c89ac918SYiting Deng #define RTC_ALRM0_EN BIT(0) 23*c89ac918SYiting Deng #define RTC_OSC_SEL BIT(8) 24*c89ac918SYiting Deng #define RTC_ENABLE BIT(12) 25*c89ac918SYiting Deng 26*c89ac918SYiting Deng #define RTC_COUNTER_REG (0x1 << 2) /* Program RTC counter initial value */ 27*c89ac918SYiting Deng 28*c89ac918SYiting Deng #define RTC_ALARM0_REG (0x2 << 2) /* Program RTC alarm0 value */ 29*c89ac918SYiting Deng 30*c89ac918SYiting Deng #define RTC_SEC_ADJUST_REG (0x6 << 2) /* Control second-based timing adjustment */ 31*c89ac918SYiting Deng #define RTC_MATCH_COUNTER GENMASK(18, 0) 32*c89ac918SYiting Deng #define RTC_SEC_ADJUST_CTRL GENMASK(20, 19) 33*c89ac918SYiting Deng #define RTC_ADJ_VALID BIT(23) 34*c89ac918SYiting Deng 35*c89ac918SYiting Deng #define RTC_INT_MASK (0x8 << 2) /* RTC interrupt mask */ 36*c89ac918SYiting Deng #define RTC_ALRM0_IRQ_MSK BIT(0) 37*c89ac918SYiting Deng 38*c89ac918SYiting Deng #define RTC_INT_CLR (0x9 << 2) /* Clear RTC interrupt */ 39*c89ac918SYiting Deng #define RTC_ALRM0_IRQ_CLR BIT(0) 40*c89ac918SYiting Deng 41*c89ac918SYiting Deng #define RTC_OSCIN_CTRL0 (0xa << 2) /* Control RTC clk from 24M */ 42*c89ac918SYiting Deng #define RTC_OSCIN_CTRL1 (0xb << 2) /* Control RTC clk from 24M */ 43*c89ac918SYiting Deng #define RTC_OSCIN_IN_EN BIT(31) 44*c89ac918SYiting Deng #define RTC_OSCIN_OUT_CFG GENMASK(29, 28) 45*c89ac918SYiting Deng #define RTC_OSCIN_OUT_N0M0 GENMASK(11, 0) 46*c89ac918SYiting Deng #define RTC_OSCIN_OUT_N1M1 GENMASK(23, 12) 47*c89ac918SYiting Deng 48*c89ac918SYiting Deng #define RTC_INT_STATUS (0xc << 2) /* RTC interrupt status */ 49*c89ac918SYiting Deng #define RTC_ALRM0_IRQ_STATUS BIT(0) 50*c89ac918SYiting Deng 51*c89ac918SYiting Deng #define RTC_REAL_TIME (0xd << 2) /* RTC time value */ 52*c89ac918SYiting Deng 53*c89ac918SYiting Deng #define RTC_OSCIN_OUT_32K_N0 0x2dc 54*c89ac918SYiting Deng #define RTC_OSCIN_OUT_32K_N1 0x2db 55*c89ac918SYiting Deng #define RTC_OSCIN_OUT_32K_M0 0x1 56*c89ac918SYiting Deng #define RTC_OSCIN_OUT_32K_M1 0x2 57*c89ac918SYiting Deng 58*c89ac918SYiting Deng #define RTC_SWALLOW_SECOND 0x2 59*c89ac918SYiting Deng #define RTC_INSERT_SECOND 0x3 60*c89ac918SYiting Deng 61*c89ac918SYiting Deng struct aml_rtc_config { 62*c89ac918SYiting Deng bool gray_stored; 63*c89ac918SYiting Deng }; 64*c89ac918SYiting Deng 65*c89ac918SYiting Deng struct aml_rtc_data { 66*c89ac918SYiting Deng struct regmap *map; 67*c89ac918SYiting Deng struct rtc_device *rtc_dev; 68*c89ac918SYiting Deng int irq; 69*c89ac918SYiting Deng struct clk *rtc_clk; 70*c89ac918SYiting Deng struct clk *sys_clk; 71*c89ac918SYiting Deng int rtc_enabled; 72*c89ac918SYiting Deng const struct aml_rtc_config *config; 73*c89ac918SYiting Deng }; 74*c89ac918SYiting Deng 75*c89ac918SYiting Deng static const struct regmap_config aml_rtc_regmap_config = { 76*c89ac918SYiting Deng .reg_bits = 32, 77*c89ac918SYiting Deng .val_bits = 32, 78*c89ac918SYiting Deng .reg_stride = 4, 79*c89ac918SYiting Deng .max_register = RTC_REAL_TIME, 80*c89ac918SYiting Deng }; 81*c89ac918SYiting Deng 82*c89ac918SYiting Deng static inline u32 gray_to_binary(u32 gray) 83*c89ac918SYiting Deng { 84*c89ac918SYiting Deng u32 bcd = gray; 85*c89ac918SYiting Deng int size = sizeof(bcd) * 8; 86*c89ac918SYiting Deng int i; 87*c89ac918SYiting Deng 88*c89ac918SYiting Deng for (i = 0; (1 << i) < size; i++) 89*c89ac918SYiting Deng bcd ^= bcd >> (1 << i); 90*c89ac918SYiting Deng 91*c89ac918SYiting Deng return bcd; 92*c89ac918SYiting Deng } 93*c89ac918SYiting Deng 94*c89ac918SYiting Deng static inline u32 binary_to_gray(u32 bcd) 95*c89ac918SYiting Deng { 96*c89ac918SYiting Deng return bcd ^ (bcd >> 1); 97*c89ac918SYiting Deng } 98*c89ac918SYiting Deng 99*c89ac918SYiting Deng static int aml_rtc_read_time(struct device *dev, struct rtc_time *tm) 100*c89ac918SYiting Deng { 101*c89ac918SYiting Deng struct aml_rtc_data *rtc = dev_get_drvdata(dev); 102*c89ac918SYiting Deng u32 time_sec; 103*c89ac918SYiting Deng 104*c89ac918SYiting Deng /* if RTC disabled, read time failed */ 105*c89ac918SYiting Deng if (!rtc->rtc_enabled) { 106*c89ac918SYiting Deng dev_err(dev, "RTC disabled, read time failed\n"); 107*c89ac918SYiting Deng return -EINVAL; 108*c89ac918SYiting Deng } 109*c89ac918SYiting Deng 110*c89ac918SYiting Deng regmap_read(rtc->map, RTC_REAL_TIME, &time_sec); 111*c89ac918SYiting Deng if (rtc->config->gray_stored) 112*c89ac918SYiting Deng time_sec = gray_to_binary(time_sec); 113*c89ac918SYiting Deng rtc_time64_to_tm(time_sec, tm); 114*c89ac918SYiting Deng dev_dbg(dev, "%s: read time = %us\n", __func__, time_sec); 115*c89ac918SYiting Deng 116*c89ac918SYiting Deng return 0; 117*c89ac918SYiting Deng } 118*c89ac918SYiting Deng 119*c89ac918SYiting Deng static int aml_rtc_set_time(struct device *dev, struct rtc_time *tm) 120*c89ac918SYiting Deng { 121*c89ac918SYiting Deng struct aml_rtc_data *rtc = dev_get_drvdata(dev); 122*c89ac918SYiting Deng u32 time_sec; 123*c89ac918SYiting Deng 124*c89ac918SYiting Deng /* if RTC disabled, first enable it */ 125*c89ac918SYiting Deng if (!rtc->rtc_enabled) { 126*c89ac918SYiting Deng regmap_write_bits(rtc->map, RTC_CTRL, RTC_ENABLE, RTC_ENABLE); 127*c89ac918SYiting Deng usleep_range(100, 200); 128*c89ac918SYiting Deng rtc->rtc_enabled = regmap_test_bits(rtc->map, RTC_CTRL, RTC_ENABLE); 129*c89ac918SYiting Deng if (!rtc->rtc_enabled) 130*c89ac918SYiting Deng return -EINVAL; 131*c89ac918SYiting Deng } 132*c89ac918SYiting Deng 133*c89ac918SYiting Deng time_sec = rtc_tm_to_time64(tm); 134*c89ac918SYiting Deng if (rtc->config->gray_stored) 135*c89ac918SYiting Deng time_sec = binary_to_gray(time_sec); 136*c89ac918SYiting Deng regmap_write(rtc->map, RTC_COUNTER_REG, time_sec); 137*c89ac918SYiting Deng dev_dbg(dev, "%s: set time = %us\n", __func__, time_sec); 138*c89ac918SYiting Deng 139*c89ac918SYiting Deng return 0; 140*c89ac918SYiting Deng } 141*c89ac918SYiting Deng 142*c89ac918SYiting Deng static int aml_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) 143*c89ac918SYiting Deng { 144*c89ac918SYiting Deng struct aml_rtc_data *rtc = dev_get_drvdata(dev); 145*c89ac918SYiting Deng time64_t alarm_sec; 146*c89ac918SYiting Deng 147*c89ac918SYiting Deng /* if RTC disabled, set alarm failed */ 148*c89ac918SYiting Deng if (!rtc->rtc_enabled) { 149*c89ac918SYiting Deng dev_err(dev, "RTC disabled, set alarm failed\n"); 150*c89ac918SYiting Deng return -EINVAL; 151*c89ac918SYiting Deng } 152*c89ac918SYiting Deng 153*c89ac918SYiting Deng regmap_update_bits(rtc->map, RTC_CTRL, 154*c89ac918SYiting Deng RTC_ALRM0_EN, RTC_ALRM0_EN); 155*c89ac918SYiting Deng regmap_update_bits(rtc->map, RTC_INT_MASK, 156*c89ac918SYiting Deng RTC_ALRM0_IRQ_MSK, 0); 157*c89ac918SYiting Deng 158*c89ac918SYiting Deng alarm_sec = rtc_tm_to_time64(&alarm->time); 159*c89ac918SYiting Deng if (rtc->config->gray_stored) 160*c89ac918SYiting Deng alarm_sec = binary_to_gray(alarm_sec); 161*c89ac918SYiting Deng regmap_write(rtc->map, RTC_ALARM0_REG, alarm_sec); 162*c89ac918SYiting Deng 163*c89ac918SYiting Deng dev_dbg(dev, "%s: alarm->enabled=%d alarm_set=%llds\n", __func__, 164*c89ac918SYiting Deng alarm->enabled, alarm_sec); 165*c89ac918SYiting Deng 166*c89ac918SYiting Deng return 0; 167*c89ac918SYiting Deng } 168*c89ac918SYiting Deng 169*c89ac918SYiting Deng static int aml_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) 170*c89ac918SYiting Deng { 171*c89ac918SYiting Deng struct aml_rtc_data *rtc = dev_get_drvdata(dev); 172*c89ac918SYiting Deng u32 alarm_sec; 173*c89ac918SYiting Deng int alarm_enable; 174*c89ac918SYiting Deng int alarm_mask; 175*c89ac918SYiting Deng 176*c89ac918SYiting Deng /* if RTC disabled, read alarm failed */ 177*c89ac918SYiting Deng if (!rtc->rtc_enabled) { 178*c89ac918SYiting Deng dev_err(dev, "RTC disabled, read alarm failed\n"); 179*c89ac918SYiting Deng return -EINVAL; 180*c89ac918SYiting Deng } 181*c89ac918SYiting Deng 182*c89ac918SYiting Deng regmap_read(rtc->map, RTC_ALARM0_REG, &alarm_sec); 183*c89ac918SYiting Deng if (rtc->config->gray_stored) 184*c89ac918SYiting Deng alarm_sec = gray_to_binary(alarm_sec); 185*c89ac918SYiting Deng rtc_time64_to_tm(alarm_sec, &alarm->time); 186*c89ac918SYiting Deng 187*c89ac918SYiting Deng alarm_enable = regmap_test_bits(rtc->map, RTC_CTRL, RTC_ALRM0_EN); 188*c89ac918SYiting Deng alarm_mask = regmap_test_bits(rtc->map, RTC_INT_MASK, RTC_ALRM0_IRQ_MSK); 189*c89ac918SYiting Deng alarm->enabled = (alarm_enable && !alarm_mask) ? 1 : 0; 190*c89ac918SYiting Deng dev_dbg(dev, "%s: alarm->enabled=%d alarm=%us\n", __func__, 191*c89ac918SYiting Deng alarm->enabled, alarm_sec); 192*c89ac918SYiting Deng 193*c89ac918SYiting Deng return 0; 194*c89ac918SYiting Deng } 195*c89ac918SYiting Deng 196*c89ac918SYiting Deng static int aml_rtc_read_offset(struct device *dev, long *offset) 197*c89ac918SYiting Deng { 198*c89ac918SYiting Deng struct aml_rtc_data *rtc = dev_get_drvdata(dev); 199*c89ac918SYiting Deng u32 reg_val; 200*c89ac918SYiting Deng long val; 201*c89ac918SYiting Deng int sign, match_counter, enable; 202*c89ac918SYiting Deng 203*c89ac918SYiting Deng /* if RTC disabled, read offset failed */ 204*c89ac918SYiting Deng if (!rtc->rtc_enabled) { 205*c89ac918SYiting Deng dev_err(dev, "RTC disabled, read offset failed\n"); 206*c89ac918SYiting Deng return -EINVAL; 207*c89ac918SYiting Deng } 208*c89ac918SYiting Deng 209*c89ac918SYiting Deng regmap_read(rtc->map, RTC_SEC_ADJUST_REG, ®_val); 210*c89ac918SYiting Deng enable = FIELD_GET(RTC_ADJ_VALID, reg_val); 211*c89ac918SYiting Deng if (!enable) { 212*c89ac918SYiting Deng val = 0; 213*c89ac918SYiting Deng } else { 214*c89ac918SYiting Deng sign = FIELD_GET(RTC_SEC_ADJUST_CTRL, reg_val); 215*c89ac918SYiting Deng match_counter = FIELD_GET(RTC_MATCH_COUNTER, reg_val); 216*c89ac918SYiting Deng val = 1000000000 / (match_counter + 1); 217*c89ac918SYiting Deng if (sign == RTC_SWALLOW_SECOND) 218*c89ac918SYiting Deng val = -val; 219*c89ac918SYiting Deng } 220*c89ac918SYiting Deng *offset = val; 221*c89ac918SYiting Deng 222*c89ac918SYiting Deng return 0; 223*c89ac918SYiting Deng } 224*c89ac918SYiting Deng 225*c89ac918SYiting Deng static int aml_rtc_set_offset(struct device *dev, long offset) 226*c89ac918SYiting Deng { 227*c89ac918SYiting Deng struct aml_rtc_data *rtc = dev_get_drvdata(dev); 228*c89ac918SYiting Deng int sign = 0; 229*c89ac918SYiting Deng int match_counter = 0; 230*c89ac918SYiting Deng int enable = 0; 231*c89ac918SYiting Deng u32 reg_val; 232*c89ac918SYiting Deng 233*c89ac918SYiting Deng /* if RTC disabled, set offset failed */ 234*c89ac918SYiting Deng if (!rtc->rtc_enabled) { 235*c89ac918SYiting Deng dev_err(dev, "RTC disabled, set offset failed\n"); 236*c89ac918SYiting Deng return -EINVAL; 237*c89ac918SYiting Deng } 238*c89ac918SYiting Deng 239*c89ac918SYiting Deng if (offset) { 240*c89ac918SYiting Deng enable = 1; 241*c89ac918SYiting Deng sign = offset < 0 ? RTC_SWALLOW_SECOND : RTC_INSERT_SECOND; 242*c89ac918SYiting Deng match_counter = 1000000000 / abs(offset) - 1; 243*c89ac918SYiting Deng if (match_counter < 0 || match_counter > RTC_MATCH_COUNTER) 244*c89ac918SYiting Deng return -EINVAL; 245*c89ac918SYiting Deng } 246*c89ac918SYiting Deng 247*c89ac918SYiting Deng reg_val = FIELD_PREP(RTC_ADJ_VALID, enable) | 248*c89ac918SYiting Deng FIELD_PREP(RTC_SEC_ADJUST_CTRL, sign) | 249*c89ac918SYiting Deng FIELD_PREP(RTC_MATCH_COUNTER, match_counter); 250*c89ac918SYiting Deng regmap_write(rtc->map, RTC_SEC_ADJUST_REG, reg_val); 251*c89ac918SYiting Deng 252*c89ac918SYiting Deng return 0; 253*c89ac918SYiting Deng } 254*c89ac918SYiting Deng 255*c89ac918SYiting Deng static int aml_rtc_alarm_enable(struct device *dev, unsigned int enabled) 256*c89ac918SYiting Deng { 257*c89ac918SYiting Deng struct aml_rtc_data *rtc = dev_get_drvdata(dev); 258*c89ac918SYiting Deng 259*c89ac918SYiting Deng if (enabled) { 260*c89ac918SYiting Deng regmap_update_bits(rtc->map, RTC_CTRL, 261*c89ac918SYiting Deng RTC_ALRM0_EN, RTC_ALRM0_EN); 262*c89ac918SYiting Deng regmap_update_bits(rtc->map, RTC_INT_MASK, 263*c89ac918SYiting Deng RTC_ALRM0_IRQ_MSK, 0); 264*c89ac918SYiting Deng } else { 265*c89ac918SYiting Deng regmap_update_bits(rtc->map, RTC_INT_MASK, 266*c89ac918SYiting Deng RTC_ALRM0_IRQ_MSK, RTC_ALRM0_IRQ_MSK); 267*c89ac918SYiting Deng regmap_update_bits(rtc->map, RTC_CTRL, 268*c89ac918SYiting Deng RTC_ALRM0_EN, 0); 269*c89ac918SYiting Deng } 270*c89ac918SYiting Deng 271*c89ac918SYiting Deng return 0; 272*c89ac918SYiting Deng } 273*c89ac918SYiting Deng 274*c89ac918SYiting Deng static const struct rtc_class_ops aml_rtc_ops = { 275*c89ac918SYiting Deng .read_time = aml_rtc_read_time, 276*c89ac918SYiting Deng .set_time = aml_rtc_set_time, 277*c89ac918SYiting Deng .read_alarm = aml_rtc_read_alarm, 278*c89ac918SYiting Deng .set_alarm = aml_rtc_set_alarm, 279*c89ac918SYiting Deng .alarm_irq_enable = aml_rtc_alarm_enable, 280*c89ac918SYiting Deng .read_offset = aml_rtc_read_offset, 281*c89ac918SYiting Deng .set_offset = aml_rtc_set_offset, 282*c89ac918SYiting Deng }; 283*c89ac918SYiting Deng 284*c89ac918SYiting Deng static irqreturn_t aml_rtc_handler(int irq, void *data) 285*c89ac918SYiting Deng { 286*c89ac918SYiting Deng struct aml_rtc_data *rtc = (struct aml_rtc_data *)data; 287*c89ac918SYiting Deng 288*c89ac918SYiting Deng regmap_write(rtc->map, RTC_ALARM0_REG, 0); 289*c89ac918SYiting Deng regmap_write(rtc->map, RTC_INT_CLR, RTC_ALRM0_IRQ_STATUS); 290*c89ac918SYiting Deng 291*c89ac918SYiting Deng rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); 292*c89ac918SYiting Deng 293*c89ac918SYiting Deng return IRQ_HANDLED; 294*c89ac918SYiting Deng } 295*c89ac918SYiting Deng 296*c89ac918SYiting Deng static void aml_rtc_init(struct aml_rtc_data *rtc) 297*c89ac918SYiting Deng { 298*c89ac918SYiting Deng u32 reg_val = 0; 299*c89ac918SYiting Deng 300*c89ac918SYiting Deng rtc->rtc_enabled = regmap_test_bits(rtc->map, RTC_CTRL, RTC_ENABLE); 301*c89ac918SYiting Deng if (!rtc->rtc_enabled) { 302*c89ac918SYiting Deng if (clk_get_rate(rtc->rtc_clk) == OSC_24M) { 303*c89ac918SYiting Deng /* select 24M oscillator */ 304*c89ac918SYiting Deng regmap_write_bits(rtc->map, RTC_CTRL, RTC_OSC_SEL, RTC_OSC_SEL); 305*c89ac918SYiting Deng 306*c89ac918SYiting Deng /* 307*c89ac918SYiting Deng * Set RTC oscillator to freq_out to freq_in/((N0*M0+N1*M1)/(M0+M1)) 308*c89ac918SYiting Deng * Enable clock_in gate of oscillator 24MHz 309*c89ac918SYiting Deng * Set N0 to 733, N1 to 732 310*c89ac918SYiting Deng */ 311*c89ac918SYiting Deng reg_val = FIELD_PREP(RTC_OSCIN_IN_EN, 1) 312*c89ac918SYiting Deng | FIELD_PREP(RTC_OSCIN_OUT_CFG, 1) 313*c89ac918SYiting Deng | FIELD_PREP(RTC_OSCIN_OUT_N0M0, RTC_OSCIN_OUT_32K_N0) 314*c89ac918SYiting Deng | FIELD_PREP(RTC_OSCIN_OUT_N1M1, RTC_OSCIN_OUT_32K_N1); 315*c89ac918SYiting Deng regmap_write_bits(rtc->map, RTC_OSCIN_CTRL0, RTC_OSCIN_IN_EN 316*c89ac918SYiting Deng | RTC_OSCIN_OUT_CFG | RTC_OSCIN_OUT_N0M0 317*c89ac918SYiting Deng | RTC_OSCIN_OUT_N1M1, reg_val); 318*c89ac918SYiting Deng 319*c89ac918SYiting Deng /* Set M0 to 2, M1 to 3, so freq_out = 32768 Hz*/ 320*c89ac918SYiting Deng reg_val = FIELD_PREP(RTC_OSCIN_OUT_N0M0, RTC_OSCIN_OUT_32K_M0) 321*c89ac918SYiting Deng | FIELD_PREP(RTC_OSCIN_OUT_N1M1, RTC_OSCIN_OUT_32K_M1); 322*c89ac918SYiting Deng regmap_write_bits(rtc->map, RTC_OSCIN_CTRL1, RTC_OSCIN_OUT_N0M0 323*c89ac918SYiting Deng | RTC_OSCIN_OUT_N1M1, reg_val); 324*c89ac918SYiting Deng } else { 325*c89ac918SYiting Deng /* select 32K oscillator */ 326*c89ac918SYiting Deng regmap_write_bits(rtc->map, RTC_CTRL, RTC_OSC_SEL, 0); 327*c89ac918SYiting Deng } 328*c89ac918SYiting Deng } 329*c89ac918SYiting Deng regmap_write_bits(rtc->map, RTC_INT_MASK, 330*c89ac918SYiting Deng RTC_ALRM0_IRQ_MSK, RTC_ALRM0_IRQ_MSK); 331*c89ac918SYiting Deng regmap_write_bits(rtc->map, RTC_CTRL, RTC_ALRM0_EN, 0); 332*c89ac918SYiting Deng } 333*c89ac918SYiting Deng 334*c89ac918SYiting Deng static int aml_rtc_probe(struct platform_device *pdev) 335*c89ac918SYiting Deng { 336*c89ac918SYiting Deng struct device *dev = &pdev->dev; 337*c89ac918SYiting Deng struct aml_rtc_data *rtc; 338*c89ac918SYiting Deng void __iomem *base; 339*c89ac918SYiting Deng int ret = 0; 340*c89ac918SYiting Deng 341*c89ac918SYiting Deng rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL); 342*c89ac918SYiting Deng if (!rtc) 343*c89ac918SYiting Deng return -ENOMEM; 344*c89ac918SYiting Deng 345*c89ac918SYiting Deng rtc->config = of_device_get_match_data(dev); 346*c89ac918SYiting Deng if (!rtc->config) 347*c89ac918SYiting Deng return -ENODEV; 348*c89ac918SYiting Deng 349*c89ac918SYiting Deng base = devm_platform_ioremap_resource(pdev, 0); 350*c89ac918SYiting Deng if (IS_ERR(base)) 351*c89ac918SYiting Deng return dev_err_probe(dev, PTR_ERR(base), "resource ioremap failed\n"); 352*c89ac918SYiting Deng 353*c89ac918SYiting Deng rtc->map = devm_regmap_init_mmio(dev, base, &aml_rtc_regmap_config); 354*c89ac918SYiting Deng if (IS_ERR(rtc->map)) 355*c89ac918SYiting Deng return dev_err_probe(dev, PTR_ERR(rtc->map), "regmap init failed\n"); 356*c89ac918SYiting Deng 357*c89ac918SYiting Deng rtc->irq = platform_get_irq(pdev, 0); 358*c89ac918SYiting Deng if (rtc->irq < 0) 359*c89ac918SYiting Deng return rtc->irq; 360*c89ac918SYiting Deng 361*c89ac918SYiting Deng rtc->rtc_clk = devm_clk_get(dev, "osc"); 362*c89ac918SYiting Deng if (IS_ERR(rtc->rtc_clk)) 363*c89ac918SYiting Deng return dev_err_probe(dev, PTR_ERR(rtc->rtc_clk), 364*c89ac918SYiting Deng "failed to find rtc clock\n"); 365*c89ac918SYiting Deng if (clk_get_rate(rtc->rtc_clk) != OSC_32K && clk_get_rate(rtc->rtc_clk) != OSC_24M) 366*c89ac918SYiting Deng return dev_err_probe(dev, -EINVAL, "Invalid clock configuration\n"); 367*c89ac918SYiting Deng 368*c89ac918SYiting Deng rtc->sys_clk = devm_clk_get_enabled(dev, "sys"); 369*c89ac918SYiting Deng if (IS_ERR(rtc->sys_clk)) 370*c89ac918SYiting Deng return dev_err_probe(dev, PTR_ERR(rtc->sys_clk), 371*c89ac918SYiting Deng "failed to get_enable rtc sys clk\n"); 372*c89ac918SYiting Deng aml_rtc_init(rtc); 373*c89ac918SYiting Deng 374*c89ac918SYiting Deng device_init_wakeup(dev, 1); 375*c89ac918SYiting Deng platform_set_drvdata(pdev, rtc); 376*c89ac918SYiting Deng 377*c89ac918SYiting Deng rtc->rtc_dev = devm_rtc_allocate_device(dev); 378*c89ac918SYiting Deng if (IS_ERR(rtc->rtc_dev)) { 379*c89ac918SYiting Deng ret = PTR_ERR(rtc->rtc_dev); 380*c89ac918SYiting Deng goto err_clk; 381*c89ac918SYiting Deng } 382*c89ac918SYiting Deng 383*c89ac918SYiting Deng ret = devm_request_irq(dev, rtc->irq, aml_rtc_handler, 384*c89ac918SYiting Deng IRQF_ONESHOT, "aml-rtc alarm", rtc); 385*c89ac918SYiting Deng if (ret) { 386*c89ac918SYiting Deng dev_err_probe(dev, ret, "IRQ%d request failed, ret = %d\n", 387*c89ac918SYiting Deng rtc->irq, ret); 388*c89ac918SYiting Deng goto err_clk; 389*c89ac918SYiting Deng } 390*c89ac918SYiting Deng 391*c89ac918SYiting Deng rtc->rtc_dev->ops = &aml_rtc_ops; 392*c89ac918SYiting Deng rtc->rtc_dev->range_min = 0; 393*c89ac918SYiting Deng rtc->rtc_dev->range_max = U32_MAX; 394*c89ac918SYiting Deng 395*c89ac918SYiting Deng ret = devm_rtc_register_device(rtc->rtc_dev); 396*c89ac918SYiting Deng if (ret) { 397*c89ac918SYiting Deng dev_err_probe(&pdev->dev, ret, "Failed to register RTC device: %d\n", ret); 398*c89ac918SYiting Deng goto err_clk; 399*c89ac918SYiting Deng } 400*c89ac918SYiting Deng 401*c89ac918SYiting Deng return 0; 402*c89ac918SYiting Deng err_clk: 403*c89ac918SYiting Deng clk_disable_unprepare(rtc->sys_clk); 404*c89ac918SYiting Deng device_init_wakeup(dev, 0); 405*c89ac918SYiting Deng 406*c89ac918SYiting Deng return ret; 407*c89ac918SYiting Deng } 408*c89ac918SYiting Deng 409*c89ac918SYiting Deng #ifdef CONFIG_PM_SLEEP 410*c89ac918SYiting Deng static int aml_rtc_suspend(struct device *dev) 411*c89ac918SYiting Deng { 412*c89ac918SYiting Deng struct aml_rtc_data *rtc = dev_get_drvdata(dev); 413*c89ac918SYiting Deng 414*c89ac918SYiting Deng if (device_may_wakeup(dev)) 415*c89ac918SYiting Deng enable_irq_wake(rtc->irq); 416*c89ac918SYiting Deng 417*c89ac918SYiting Deng return 0; 418*c89ac918SYiting Deng } 419*c89ac918SYiting Deng 420*c89ac918SYiting Deng static int aml_rtc_resume(struct device *dev) 421*c89ac918SYiting Deng { 422*c89ac918SYiting Deng struct aml_rtc_data *rtc = dev_get_drvdata(dev); 423*c89ac918SYiting Deng 424*c89ac918SYiting Deng if (device_may_wakeup(dev)) 425*c89ac918SYiting Deng disable_irq_wake(rtc->irq); 426*c89ac918SYiting Deng 427*c89ac918SYiting Deng return 0; 428*c89ac918SYiting Deng } 429*c89ac918SYiting Deng #endif 430*c89ac918SYiting Deng 431*c89ac918SYiting Deng static SIMPLE_DEV_PM_OPS(aml_rtc_pm_ops, 432*c89ac918SYiting Deng aml_rtc_suspend, aml_rtc_resume); 433*c89ac918SYiting Deng 434*c89ac918SYiting Deng static void aml_rtc_remove(struct platform_device *pdev) 435*c89ac918SYiting Deng { 436*c89ac918SYiting Deng struct aml_rtc_data *rtc = dev_get_drvdata(&pdev->dev); 437*c89ac918SYiting Deng 438*c89ac918SYiting Deng clk_disable_unprepare(rtc->sys_clk); 439*c89ac918SYiting Deng device_init_wakeup(&pdev->dev, 0); 440*c89ac918SYiting Deng } 441*c89ac918SYiting Deng 442*c89ac918SYiting Deng static const struct aml_rtc_config a5_rtc_config = { 443*c89ac918SYiting Deng }; 444*c89ac918SYiting Deng 445*c89ac918SYiting Deng static const struct aml_rtc_config a4_rtc_config = { 446*c89ac918SYiting Deng .gray_stored = true, 447*c89ac918SYiting Deng }; 448*c89ac918SYiting Deng 449*c89ac918SYiting Deng static const struct of_device_id aml_rtc_device_id[] = { 450*c89ac918SYiting Deng { 451*c89ac918SYiting Deng .compatible = "amlogic,a4-rtc", 452*c89ac918SYiting Deng .data = &a4_rtc_config, 453*c89ac918SYiting Deng }, 454*c89ac918SYiting Deng { 455*c89ac918SYiting Deng .compatible = "amlogic,a5-rtc", 456*c89ac918SYiting Deng .data = &a5_rtc_config, 457*c89ac918SYiting Deng }, 458*c89ac918SYiting Deng }; 459*c89ac918SYiting Deng MODULE_DEVICE_TABLE(of, aml_rtc_device_id); 460*c89ac918SYiting Deng 461*c89ac918SYiting Deng static struct platform_driver aml_rtc_driver = { 462*c89ac918SYiting Deng .probe = aml_rtc_probe, 463*c89ac918SYiting Deng .remove = aml_rtc_remove, 464*c89ac918SYiting Deng .driver = { 465*c89ac918SYiting Deng .name = "aml-rtc", 466*c89ac918SYiting Deng .pm = &aml_rtc_pm_ops, 467*c89ac918SYiting Deng .of_match_table = aml_rtc_device_id, 468*c89ac918SYiting Deng }, 469*c89ac918SYiting Deng }; 470*c89ac918SYiting Deng 471*c89ac918SYiting Deng module_platform_driver(aml_rtc_driver); 472*c89ac918SYiting Deng MODULE_DESCRIPTION("Amlogic RTC driver"); 473*c89ac918SYiting Deng MODULE_AUTHOR("Yiting Deng <yiting.deng@amlogic.com>"); 474*c89ac918SYiting Deng MODULE_LICENSE("GPL"); 475