Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Real Time Clock driver for Conexant Digicolor
0004  *
0005  * Copyright (C) 2015 Paradox Innovation Ltd.
0006  *
0007  * Author: Baruch Siach <baruch@tkos.co.il>
0008  */
0009 
0010 #include <linux/io.h>
0011 #include <linux/iopoll.h>
0012 #include <linux/delay.h>
0013 #include <linux/module.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/rtc.h>
0016 #include <linux/of.h>
0017 
0018 #define DC_RTC_CONTROL      0x0
0019 #define DC_RTC_TIME     0x8
0020 #define DC_RTC_REFERENCE    0xc
0021 #define DC_RTC_ALARM        0x10
0022 #define DC_RTC_INTFLAG_CLEAR    0x14
0023 #define DC_RTC_INTENABLE    0x16
0024 
0025 #define DC_RTC_CMD_MASK     0xf
0026 #define DC_RTC_GO_BUSY      BIT(7)
0027 
0028 #define CMD_NOP         0
0029 #define CMD_RESET       1
0030 #define CMD_WRITE       3
0031 #define CMD_READ        4
0032 
0033 #define CMD_DELAY_US        (10*1000)
0034 #define CMD_TIMEOUT_US      (500*CMD_DELAY_US)
0035 
0036 struct dc_rtc {
0037     struct rtc_device   *rtc_dev;
0038     void __iomem        *regs;
0039 };
0040 
0041 static int dc_rtc_cmds(struct dc_rtc *rtc, const u8 *cmds, int len)
0042 {
0043     u8 val;
0044     int i, ret;
0045 
0046     for (i = 0; i < len; i++) {
0047         writeb_relaxed((cmds[i] & DC_RTC_CMD_MASK) | DC_RTC_GO_BUSY,
0048                    rtc->regs + DC_RTC_CONTROL);
0049         ret = readb_relaxed_poll_timeout(
0050             rtc->regs + DC_RTC_CONTROL, val,
0051             !(val & DC_RTC_GO_BUSY), CMD_DELAY_US, CMD_TIMEOUT_US);
0052         if (ret < 0)
0053             return ret;
0054     }
0055 
0056     return 0;
0057 }
0058 
0059 static int dc_rtc_read(struct dc_rtc *rtc, unsigned long *val)
0060 {
0061     static const u8 read_cmds[] = {CMD_READ, CMD_NOP};
0062     u32 reference, time1, time2;
0063     int ret;
0064 
0065     ret = dc_rtc_cmds(rtc, read_cmds, ARRAY_SIZE(read_cmds));
0066     if (ret < 0)
0067         return ret;
0068 
0069     reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE);
0070     time1 = readl_relaxed(rtc->regs + DC_RTC_TIME);
0071     /* Read twice to ensure consistency */
0072     while (1) {
0073         time2 = readl_relaxed(rtc->regs + DC_RTC_TIME);
0074         if (time1 == time2)
0075             break;
0076         time1 = time2;
0077     }
0078 
0079     *val = reference + time1;
0080     return 0;
0081 }
0082 
0083 static int dc_rtc_write(struct dc_rtc *rtc, u32 val)
0084 {
0085     static const u8 write_cmds[] = {CMD_WRITE, CMD_NOP, CMD_RESET, CMD_NOP};
0086 
0087     writel_relaxed(val, rtc->regs + DC_RTC_REFERENCE);
0088     return dc_rtc_cmds(rtc, write_cmds, ARRAY_SIZE(write_cmds));
0089 }
0090 
0091 static int dc_rtc_read_time(struct device *dev, struct rtc_time *tm)
0092 {
0093     struct dc_rtc *rtc = dev_get_drvdata(dev);
0094     unsigned long now;
0095     int ret;
0096 
0097     ret = dc_rtc_read(rtc, &now);
0098     if (ret < 0)
0099         return ret;
0100     rtc_time64_to_tm(now, tm);
0101 
0102     return 0;
0103 }
0104 
0105 static int dc_rtc_set_time(struct device *dev, struct rtc_time *tm)
0106 {
0107     struct dc_rtc *rtc = dev_get_drvdata(dev);
0108 
0109     return dc_rtc_write(rtc, rtc_tm_to_time64(tm));
0110 }
0111 
0112 static int dc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0113 {
0114     struct dc_rtc *rtc = dev_get_drvdata(dev);
0115     u32 alarm_reg, reference;
0116     unsigned long now;
0117     int ret;
0118 
0119     alarm_reg = readl_relaxed(rtc->regs + DC_RTC_ALARM);
0120     reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE);
0121     rtc_time64_to_tm(reference + alarm_reg, &alarm->time);
0122 
0123     ret = dc_rtc_read(rtc, &now);
0124     if (ret < 0)
0125         return ret;
0126 
0127     alarm->pending = alarm_reg + reference > now;
0128     alarm->enabled = readl_relaxed(rtc->regs + DC_RTC_INTENABLE);
0129 
0130     return 0;
0131 }
0132 
0133 static int dc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0134 {
0135     struct dc_rtc *rtc = dev_get_drvdata(dev);
0136     time64_t alarm_time;
0137     u32 reference;
0138 
0139     alarm_time = rtc_tm_to_time64(&alarm->time);
0140 
0141     reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE);
0142     writel_relaxed(alarm_time - reference, rtc->regs + DC_RTC_ALARM);
0143 
0144     writeb_relaxed(!!alarm->enabled, rtc->regs + DC_RTC_INTENABLE);
0145 
0146     return 0;
0147 }
0148 
0149 static int dc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
0150 {
0151     struct dc_rtc *rtc = dev_get_drvdata(dev);
0152 
0153     writeb_relaxed(!!enabled, rtc->regs + DC_RTC_INTENABLE);
0154 
0155     return 0;
0156 }
0157 
0158 static const struct rtc_class_ops dc_rtc_ops = {
0159     .read_time      = dc_rtc_read_time,
0160     .set_time       = dc_rtc_set_time,
0161     .read_alarm     = dc_rtc_read_alarm,
0162     .set_alarm      = dc_rtc_set_alarm,
0163     .alarm_irq_enable   = dc_rtc_alarm_irq_enable,
0164 };
0165 
0166 static irqreturn_t dc_rtc_irq(int irq, void *dev_id)
0167 {
0168     struct dc_rtc *rtc = dev_id;
0169 
0170     writeb_relaxed(1, rtc->regs + DC_RTC_INTFLAG_CLEAR);
0171     rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
0172 
0173     return IRQ_HANDLED;
0174 }
0175 
0176 static int __init dc_rtc_probe(struct platform_device *pdev)
0177 {
0178     struct dc_rtc *rtc;
0179     int irq, ret;
0180 
0181     rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
0182     if (!rtc)
0183         return -ENOMEM;
0184 
0185     rtc->regs = devm_platform_ioremap_resource(pdev, 0);
0186     if (IS_ERR(rtc->regs))
0187         return PTR_ERR(rtc->regs);
0188 
0189     rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
0190     if (IS_ERR(rtc->rtc_dev))
0191         return PTR_ERR(rtc->rtc_dev);
0192 
0193     irq = platform_get_irq(pdev, 0);
0194     if (irq < 0)
0195         return irq;
0196     ret = devm_request_irq(&pdev->dev, irq, dc_rtc_irq, 0, pdev->name, rtc);
0197     if (ret < 0)
0198         return ret;
0199 
0200     platform_set_drvdata(pdev, rtc);
0201 
0202     rtc->rtc_dev->ops = &dc_rtc_ops;
0203     rtc->rtc_dev->range_max = U32_MAX;
0204 
0205     return devm_rtc_register_device(rtc->rtc_dev);
0206 }
0207 
0208 static const __maybe_unused struct of_device_id dc_dt_ids[] = {
0209     { .compatible = "cnxt,cx92755-rtc" },
0210     { /* sentinel */ }
0211 };
0212 MODULE_DEVICE_TABLE(of, dc_dt_ids);
0213 
0214 static struct platform_driver dc_rtc_driver = {
0215     .driver = {
0216         .name = "digicolor_rtc",
0217         .of_match_table = of_match_ptr(dc_dt_ids),
0218     },
0219 };
0220 module_platform_driver_probe(dc_rtc_driver, dc_rtc_probe);
0221 
0222 MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
0223 MODULE_DESCRIPTION("Conexant Digicolor Realtime Clock Driver (RTC)");
0224 MODULE_LICENSE("GPL");