1 /* 2 * Freescale STMP37XX/STMP378X Real Time Clock driver 3 * 4 * Copyright (c) 2007 Sigmatel, Inc. 5 * Peter Hartley, <peter.hartley@sigmatel.com> 6 * 7 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. 8 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. 9 * Copyright 2011 Wolfram Sang, Pengutronix e.K. 10 */ 11 12 /* 13 * The code contained herein is licensed under the GNU General Public 14 * License. You may obtain a copy of the GNU General Public License 15 * Version 2 or later at the following locations: 16 * 17 * http://www.opensource.org/licenses/gpl-license.html 18 * http://www.gnu.org/copyleft/gpl.html 19 */ 20 #include <linux/kernel.h> 21 #include <linux/module.h> 22 #include <linux/io.h> 23 #include <linux/init.h> 24 #include <linux/platform_device.h> 25 #include <linux/interrupt.h> 26 #include <linux/rtc.h> 27 #include <linux/slab.h> 28 #include <linux/of_device.h> 29 30 #include <mach/common.h> 31 32 #define STMP3XXX_RTC_CTRL 0x0 33 #define STMP3XXX_RTC_CTRL_SET 0x4 34 #define STMP3XXX_RTC_CTRL_CLR 0x8 35 #define STMP3XXX_RTC_CTRL_ALARM_IRQ_EN 0x00000001 36 #define STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN 0x00000002 37 #define STMP3XXX_RTC_CTRL_ALARM_IRQ 0x00000004 38 39 #define STMP3XXX_RTC_STAT 0x10 40 #define STMP3XXX_RTC_STAT_STALE_SHIFT 16 41 #define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000 42 43 #define STMP3XXX_RTC_SECONDS 0x30 44 45 #define STMP3XXX_RTC_ALARM 0x40 46 47 #define STMP3XXX_RTC_PERSISTENT0 0x60 48 #define STMP3XXX_RTC_PERSISTENT0_SET 0x64 49 #define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 50 #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN 0x00000002 51 #define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 52 #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 53 54 struct stmp3xxx_rtc_data { 55 struct rtc_device *rtc; 56 void __iomem *io; 57 int irq_alarm; 58 }; 59 60 static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) 61 { 62 /* 63 * The datasheet doesn't say which way round the 64 * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0, 65 * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS 66 */ 67 while (readl(rtc_data->io + STMP3XXX_RTC_STAT) & 68 (0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)) 69 cpu_relax(); 70 } 71 72 /* Time read/write */ 73 static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) 74 { 75 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 76 77 stmp3xxx_wait_time(rtc_data); 78 rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); 79 return 0; 80 } 81 82 static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) 83 { 84 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 85 86 writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); 87 stmp3xxx_wait_time(rtc_data); 88 return 0; 89 } 90 91 /* interrupt(s) handler */ 92 static irqreturn_t stmp3xxx_rtc_interrupt(int irq, void *dev_id) 93 { 94 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev_id); 95 u32 status = readl(rtc_data->io + STMP3XXX_RTC_CTRL); 96 97 if (status & STMP3XXX_RTC_CTRL_ALARM_IRQ) { 98 writel(STMP3XXX_RTC_CTRL_ALARM_IRQ, 99 rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 100 rtc_update_irq(rtc_data->rtc, 1, RTC_AF | RTC_IRQF); 101 return IRQ_HANDLED; 102 } 103 104 return IRQ_NONE; 105 } 106 107 static int stmp3xxx_alarm_irq_enable(struct device *dev, unsigned int enabled) 108 { 109 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 110 111 if (enabled) { 112 writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 113 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN, 114 rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET); 115 writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 116 rtc_data->io + STMP3XXX_RTC_CTRL_SET); 117 } else { 118 writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 119 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN, 120 rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 121 writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 122 rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 123 } 124 return 0; 125 } 126 127 static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 128 { 129 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 130 131 rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_ALARM), &alm->time); 132 return 0; 133 } 134 135 static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 136 { 137 unsigned long t; 138 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 139 140 rtc_tm_to_time(&alm->time, &t); 141 writel(t, rtc_data->io + STMP3XXX_RTC_ALARM); 142 143 stmp3xxx_alarm_irq_enable(dev, alm->enabled); 144 145 return 0; 146 } 147 148 static struct rtc_class_ops stmp3xxx_rtc_ops = { 149 .alarm_irq_enable = 150 stmp3xxx_alarm_irq_enable, 151 .read_time = stmp3xxx_rtc_gettime, 152 .set_mmss = stmp3xxx_rtc_set_mmss, 153 .read_alarm = stmp3xxx_rtc_read_alarm, 154 .set_alarm = stmp3xxx_rtc_set_alarm, 155 }; 156 157 static int stmp3xxx_rtc_remove(struct platform_device *pdev) 158 { 159 struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(pdev); 160 161 if (!rtc_data) 162 return 0; 163 164 writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 165 rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 166 free_irq(rtc_data->irq_alarm, &pdev->dev); 167 rtc_device_unregister(rtc_data->rtc); 168 platform_set_drvdata(pdev, NULL); 169 iounmap(rtc_data->io); 170 kfree(rtc_data); 171 172 return 0; 173 } 174 175 static int stmp3xxx_rtc_probe(struct platform_device *pdev) 176 { 177 struct stmp3xxx_rtc_data *rtc_data; 178 struct resource *r; 179 int err; 180 181 rtc_data = kzalloc(sizeof *rtc_data, GFP_KERNEL); 182 if (!rtc_data) 183 return -ENOMEM; 184 185 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 186 if (!r) { 187 dev_err(&pdev->dev, "failed to get resource\n"); 188 err = -ENXIO; 189 goto out_free; 190 } 191 192 rtc_data->io = ioremap(r->start, resource_size(r)); 193 if (!rtc_data->io) { 194 dev_err(&pdev->dev, "ioremap failed\n"); 195 err = -EIO; 196 goto out_free; 197 } 198 199 rtc_data->irq_alarm = platform_get_irq(pdev, 0); 200 201 if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) & 202 STMP3XXX_RTC_STAT_RTC_PRESENT)) { 203 dev_err(&pdev->dev, "no device onboard\n"); 204 err = -ENODEV; 205 goto out_remap; 206 } 207 208 platform_set_drvdata(pdev, rtc_data); 209 210 mxs_reset_block(rtc_data->io); 211 writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 212 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | 213 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, 214 rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 215 216 writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN | 217 STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 218 rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 219 220 rtc_data->rtc = rtc_device_register(pdev->name, &pdev->dev, 221 &stmp3xxx_rtc_ops, THIS_MODULE); 222 if (IS_ERR(rtc_data->rtc)) { 223 err = PTR_ERR(rtc_data->rtc); 224 goto out_remap; 225 } 226 227 err = request_irq(rtc_data->irq_alarm, stmp3xxx_rtc_interrupt, 0, 228 "RTC alarm", &pdev->dev); 229 if (err) { 230 dev_err(&pdev->dev, "Cannot claim IRQ%d\n", 231 rtc_data->irq_alarm); 232 goto out_irq_alarm; 233 } 234 235 return 0; 236 237 out_irq_alarm: 238 rtc_device_unregister(rtc_data->rtc); 239 out_remap: 240 platform_set_drvdata(pdev, NULL); 241 iounmap(rtc_data->io); 242 out_free: 243 kfree(rtc_data); 244 return err; 245 } 246 247 #ifdef CONFIG_PM 248 static int stmp3xxx_rtc_suspend(struct platform_device *dev, pm_message_t state) 249 { 250 return 0; 251 } 252 253 static int stmp3xxx_rtc_resume(struct platform_device *dev) 254 { 255 struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(dev); 256 257 mxs_reset_block(rtc_data->io); 258 writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 259 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | 260 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, 261 rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 262 return 0; 263 } 264 #else 265 #define stmp3xxx_rtc_suspend NULL 266 #define stmp3xxx_rtc_resume NULL 267 #endif 268 269 static const struct of_device_id rtc_dt_ids[] = { 270 { .compatible = "fsl,stmp3xxx-rtc", }, 271 { /* sentinel */ } 272 }; 273 MODULE_DEVICE_TABLE(of, rtc_dt_ids); 274 275 static struct platform_driver stmp3xxx_rtcdrv = { 276 .probe = stmp3xxx_rtc_probe, 277 .remove = stmp3xxx_rtc_remove, 278 .suspend = stmp3xxx_rtc_suspend, 279 .resume = stmp3xxx_rtc_resume, 280 .driver = { 281 .name = "stmp3xxx-rtc", 282 .owner = THIS_MODULE, 283 .of_match_table = rtc_dt_ids, 284 }, 285 }; 286 287 module_platform_driver(stmp3xxx_rtcdrv); 288 289 MODULE_DESCRIPTION("STMP3xxx RTC Driver"); 290 MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and " 291 "Wolfram Sang <w.sang@pengutronix.de>"); 292 MODULE_LICENSE("GPL"); 293