0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/rtc.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/io.h>
0013 #include <linux/gfp.h>
0014
0015 #define EP93XX_RTC_DATA 0x000
0016 #define EP93XX_RTC_MATCH 0x004
0017 #define EP93XX_RTC_STATUS 0x008
0018 #define EP93XX_RTC_STATUS_INTR BIT(0)
0019 #define EP93XX_RTC_LOAD 0x00C
0020 #define EP93XX_RTC_CONTROL 0x010
0021 #define EP93XX_RTC_CONTROL_MIE BIT(0)
0022 #define EP93XX_RTC_SWCOMP 0x108
0023 #define EP93XX_RTC_SWCOMP_DEL_MASK 0x001f0000
0024 #define EP93XX_RTC_SWCOMP_DEL_SHIFT 16
0025 #define EP93XX_RTC_SWCOMP_INT_MASK 0x0000ffff
0026 #define EP93XX_RTC_SWCOMP_INT_SHIFT 0
0027
0028 struct ep93xx_rtc {
0029 void __iomem *mmio_base;
0030 struct rtc_device *rtc;
0031 };
0032
0033 static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
0034 unsigned short *delete)
0035 {
0036 struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev);
0037 unsigned long comp;
0038
0039 comp = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_SWCOMP);
0040
0041 if (preload)
0042 *preload = (comp & EP93XX_RTC_SWCOMP_INT_MASK)
0043 >> EP93XX_RTC_SWCOMP_INT_SHIFT;
0044
0045 if (delete)
0046 *delete = (comp & EP93XX_RTC_SWCOMP_DEL_MASK)
0047 >> EP93XX_RTC_SWCOMP_DEL_SHIFT;
0048
0049 return 0;
0050 }
0051
0052 static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
0053 {
0054 struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev);
0055 unsigned long time;
0056
0057 time = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA);
0058
0059 rtc_time64_to_tm(time, tm);
0060 return 0;
0061 }
0062
0063 static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm)
0064 {
0065 struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev);
0066 unsigned long secs = rtc_tm_to_time64(tm);
0067
0068 writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD);
0069 return 0;
0070 }
0071
0072 static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq)
0073 {
0074 unsigned short preload, delete;
0075
0076 ep93xx_rtc_get_swcomp(dev, &preload, &delete);
0077
0078 seq_printf(seq, "preload\t\t: %d\n", preload);
0079 seq_printf(seq, "delete\t\t: %d\n", delete);
0080
0081 return 0;
0082 }
0083
0084 static const struct rtc_class_ops ep93xx_rtc_ops = {
0085 .read_time = ep93xx_rtc_read_time,
0086 .set_time = ep93xx_rtc_set_time,
0087 .proc = ep93xx_rtc_proc,
0088 };
0089
0090 static ssize_t comp_preload_show(struct device *dev,
0091 struct device_attribute *attr, char *buf)
0092 {
0093 unsigned short preload;
0094
0095 ep93xx_rtc_get_swcomp(dev->parent, &preload, NULL);
0096
0097 return sprintf(buf, "%d\n", preload);
0098 }
0099 static DEVICE_ATTR_RO(comp_preload);
0100
0101 static ssize_t comp_delete_show(struct device *dev,
0102 struct device_attribute *attr, char *buf)
0103 {
0104 unsigned short delete;
0105
0106 ep93xx_rtc_get_swcomp(dev->parent, NULL, &delete);
0107
0108 return sprintf(buf, "%d\n", delete);
0109 }
0110 static DEVICE_ATTR_RO(comp_delete);
0111
0112 static struct attribute *ep93xx_rtc_attrs[] = {
0113 &dev_attr_comp_preload.attr,
0114 &dev_attr_comp_delete.attr,
0115 NULL
0116 };
0117
0118 static const struct attribute_group ep93xx_rtc_sysfs_files = {
0119 .attrs = ep93xx_rtc_attrs,
0120 };
0121
0122 static int ep93xx_rtc_probe(struct platform_device *pdev)
0123 {
0124 struct ep93xx_rtc *ep93xx_rtc;
0125 int err;
0126
0127 ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL);
0128 if (!ep93xx_rtc)
0129 return -ENOMEM;
0130
0131 ep93xx_rtc->mmio_base = devm_platform_ioremap_resource(pdev, 0);
0132 if (IS_ERR(ep93xx_rtc->mmio_base))
0133 return PTR_ERR(ep93xx_rtc->mmio_base);
0134
0135 platform_set_drvdata(pdev, ep93xx_rtc);
0136
0137 ep93xx_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
0138 if (IS_ERR(ep93xx_rtc->rtc))
0139 return PTR_ERR(ep93xx_rtc->rtc);
0140
0141 ep93xx_rtc->rtc->ops = &ep93xx_rtc_ops;
0142 ep93xx_rtc->rtc->range_max = U32_MAX;
0143
0144 err = rtc_add_group(ep93xx_rtc->rtc, &ep93xx_rtc_sysfs_files);
0145 if (err)
0146 return err;
0147
0148 return devm_rtc_register_device(ep93xx_rtc->rtc);
0149 }
0150
0151 static struct platform_driver ep93xx_rtc_driver = {
0152 .driver = {
0153 .name = "ep93xx-rtc",
0154 },
0155 .probe = ep93xx_rtc_probe,
0156 };
0157
0158 module_platform_driver(ep93xx_rtc_driver);
0159
0160 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
0161 MODULE_DESCRIPTION("EP93XX RTC driver");
0162 MODULE_LICENSE("GPL");
0163 MODULE_ALIAS("platform:ep93xx-rtc");