1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * rtc-cv1800.c: RTC driver for Sophgo cv1800 RTC 4 * 5 * Author: Jingbao Qiu <qiujingbao.dlmu@gmail.com> 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/irq.h> 10 #include <linux/kernel.h> 11 #include <linux/mfd/syscon.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/platform_device.h> 15 #include <linux/regmap.h> 16 #include <linux/rtc.h> 17 18 #define SEC_PULSE_GEN 0x1004 19 #define ALARM_TIME 0x1008 20 #define ALARM_ENABLE 0x100C 21 #define SET_SEC_CNTR_VAL 0x1010 22 #define SET_SEC_CNTR_TRIG 0x1014 23 #define SEC_CNTR_VAL 0x1018 24 25 /* 26 * When in VDDBKUP domain, this MACRO register 27 * does not power down 28 */ 29 #define MACRO_RO_T 0x14A8 30 #define MACRO_RG_SET_T 0x1498 31 32 #define ALARM_ENABLE_MASK BIT(0) 33 #define SEL_SEC_PULSE BIT(31) 34 35 struct cv1800_rtc_priv { 36 struct rtc_device *rtc_dev; 37 struct regmap *rtc_map; 38 struct clk *clk; 39 int irq; 40 }; 41 42 static bool cv1800_rtc_enabled(struct device *dev) 43 { 44 struct cv1800_rtc_priv *info = dev_get_drvdata(dev); 45 u32 reg; 46 47 regmap_read(info->rtc_map, SEC_PULSE_GEN, ®); 48 49 return (reg & SEL_SEC_PULSE) == 0; 50 } 51 52 static void cv1800_rtc_enable(struct device *dev) 53 { 54 struct cv1800_rtc_priv *info = dev_get_drvdata(dev); 55 56 /* Sec pulse generated internally */ 57 regmap_update_bits(info->rtc_map, SEC_PULSE_GEN, SEL_SEC_PULSE, 0); 58 } 59 60 static int cv1800_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 61 { 62 struct cv1800_rtc_priv *info = dev_get_drvdata(dev); 63 64 regmap_write(info->rtc_map, ALARM_ENABLE, enabled); 65 66 return 0; 67 } 68 69 static int cv1800_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 70 { 71 struct cv1800_rtc_priv *info = dev_get_drvdata(dev); 72 unsigned long alarm_time; 73 74 alarm_time = rtc_tm_to_time64(&alrm->time); 75 76 cv1800_rtc_alarm_irq_enable(dev, 0); 77 78 regmap_write(info->rtc_map, ALARM_TIME, alarm_time); 79 80 cv1800_rtc_alarm_irq_enable(dev, alrm->enabled); 81 82 return 0; 83 } 84 85 static int cv1800_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) 86 { 87 struct cv1800_rtc_priv *info = dev_get_drvdata(dev); 88 u32 enabled; 89 u32 time; 90 91 if (!cv1800_rtc_enabled(dev)) { 92 alarm->enabled = 0; 93 return 0; 94 } 95 96 regmap_read(info->rtc_map, ALARM_ENABLE, &enabled); 97 98 alarm->enabled = enabled & ALARM_ENABLE_MASK; 99 100 regmap_read(info->rtc_map, ALARM_TIME, &time); 101 102 rtc_time64_to_tm(time, &alarm->time); 103 104 return 0; 105 } 106 107 static int cv1800_rtc_read_time(struct device *dev, struct rtc_time *tm) 108 { 109 struct cv1800_rtc_priv *info = dev_get_drvdata(dev); 110 u32 sec; 111 112 if (!cv1800_rtc_enabled(dev)) 113 return -EINVAL; 114 115 regmap_read(info->rtc_map, SEC_CNTR_VAL, &sec); 116 117 rtc_time64_to_tm(sec, tm); 118 119 return 0; 120 } 121 122 static int cv1800_rtc_set_time(struct device *dev, struct rtc_time *tm) 123 { 124 struct cv1800_rtc_priv *info = dev_get_drvdata(dev); 125 unsigned long sec; 126 127 sec = rtc_tm_to_time64(tm); 128 129 regmap_write(info->rtc_map, SET_SEC_CNTR_VAL, sec); 130 regmap_write(info->rtc_map, SET_SEC_CNTR_TRIG, 1); 131 132 regmap_write(info->rtc_map, MACRO_RG_SET_T, sec); 133 134 cv1800_rtc_enable(dev); 135 136 return 0; 137 } 138 139 static irqreturn_t cv1800_rtc_irq_handler(int irq, void *dev_id) 140 { 141 struct cv1800_rtc_priv *info = dev_id; 142 143 rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); 144 145 regmap_write(info->rtc_map, ALARM_ENABLE, 0); 146 147 return IRQ_HANDLED; 148 } 149 150 static const struct rtc_class_ops cv1800_rtc_ops = { 151 .read_time = cv1800_rtc_read_time, 152 .set_time = cv1800_rtc_set_time, 153 .read_alarm = cv1800_rtc_read_alarm, 154 .set_alarm = cv1800_rtc_set_alarm, 155 .alarm_irq_enable = cv1800_rtc_alarm_irq_enable, 156 }; 157 158 static int cv1800_rtc_probe(struct platform_device *pdev) 159 { 160 struct cv1800_rtc_priv *rtc; 161 int ret; 162 163 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); 164 if (!rtc) 165 return -ENOMEM; 166 167 rtc->rtc_map = device_node_to_regmap(pdev->dev.parent->of_node); 168 if (IS_ERR(rtc->rtc_map)) 169 return dev_err_probe(&pdev->dev, PTR_ERR(rtc->rtc_map), 170 "cannot get parent regmap\n"); 171 172 rtc->irq = platform_get_irq(pdev, 0); 173 if (rtc->irq < 0) 174 return rtc->irq; 175 176 rtc->clk = devm_clk_get_enabled(pdev->dev.parent, "rtc"); 177 if (IS_ERR(rtc->clk)) 178 return dev_err_probe(&pdev->dev, PTR_ERR(rtc->clk), 179 "rtc clk not found\n"); 180 181 platform_set_drvdata(pdev, rtc); 182 183 device_init_wakeup(&pdev->dev, 1); 184 185 rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); 186 if (IS_ERR(rtc->rtc_dev)) 187 return PTR_ERR(rtc->rtc_dev); 188 189 rtc->rtc_dev->ops = &cv1800_rtc_ops; 190 rtc->rtc_dev->range_max = U32_MAX; 191 192 ret = devm_request_irq(&pdev->dev, rtc->irq, cv1800_rtc_irq_handler, 193 IRQF_TRIGGER_HIGH, "rtc alarm", rtc); 194 if (ret) 195 return dev_err_probe(&pdev->dev, ret, 196 "cannot register interrupt handler\n"); 197 198 return devm_rtc_register_device(rtc->rtc_dev); 199 } 200 201 static const struct platform_device_id cv1800_rtc_id[] = { 202 { .name = "cv1800b-rtc" }, 203 { /* sentinel */ }, 204 }; 205 MODULE_DEVICE_TABLE(platform, cv1800_rtc_id); 206 207 static struct platform_driver cv1800_rtc_driver = { 208 .driver = { 209 .name = "sophgo-cv1800-rtc", 210 }, 211 .probe = cv1800_rtc_probe, 212 .id_table = cv1800_rtc_id, 213 }; 214 215 module_platform_driver(cv1800_rtc_driver); 216 MODULE_AUTHOR("Jingbao Qiu"); 217 MODULE_DESCRIPTION("Sophgo cv1800 RTC Driver"); 218 MODULE_LICENSE("GPL"); 219