0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/init.h>
0009 #include <linux/rtc.h>
0010 #include <linux/platform_device.h>
0011
0012 #include <linux/mfd/dm355evm_msp.h>
0013 #include <linux/module.h>
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 union evm_time {
0029 u8 bytes[4];
0030 u32 value;
0031 };
0032
0033 static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm)
0034 {
0035 union evm_time time;
0036 int status;
0037 int tries = 0;
0038
0039 do {
0040
0041
0042
0043
0044
0045 status = dm355evm_msp_read(DM355EVM_MSP_RTC_0);
0046 if (status < 0)
0047 return status;
0048 if (tries && time.bytes[0] == status)
0049 break;
0050 time.bytes[0] = status;
0051
0052 status = dm355evm_msp_read(DM355EVM_MSP_RTC_1);
0053 if (status < 0)
0054 return status;
0055 if (tries && time.bytes[1] == status)
0056 break;
0057 time.bytes[1] = status;
0058
0059 status = dm355evm_msp_read(DM355EVM_MSP_RTC_2);
0060 if (status < 0)
0061 return status;
0062 if (tries && time.bytes[2] == status)
0063 break;
0064 time.bytes[2] = status;
0065
0066 status = dm355evm_msp_read(DM355EVM_MSP_RTC_3);
0067 if (status < 0)
0068 return status;
0069 if (tries && time.bytes[3] == status)
0070 break;
0071 time.bytes[3] = status;
0072
0073 } while (++tries < 5);
0074
0075 dev_dbg(dev, "read timestamp %08x\n", time.value);
0076
0077 rtc_time64_to_tm(le32_to_cpu(time.value), tm);
0078 return 0;
0079 }
0080
0081 static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm)
0082 {
0083 union evm_time time;
0084 unsigned long value;
0085 int status;
0086
0087 value = rtc_tm_to_time64(tm);
0088 time.value = cpu_to_le32(value);
0089
0090 dev_dbg(dev, "write timestamp %08x\n", time.value);
0091
0092
0093
0094
0095
0096 status = dm355evm_msp_write(time.bytes[0], DM355EVM_MSP_RTC_0);
0097 if (status < 0)
0098 return status;
0099
0100 status = dm355evm_msp_write(time.bytes[1], DM355EVM_MSP_RTC_1);
0101 if (status < 0)
0102 return status;
0103
0104 status = dm355evm_msp_write(time.bytes[2], DM355EVM_MSP_RTC_2);
0105 if (status < 0)
0106 return status;
0107
0108 status = dm355evm_msp_write(time.bytes[3], DM355EVM_MSP_RTC_3);
0109 if (status < 0)
0110 return status;
0111
0112 return 0;
0113 }
0114
0115 static const struct rtc_class_ops dm355evm_rtc_ops = {
0116 .read_time = dm355evm_rtc_read_time,
0117 .set_time = dm355evm_rtc_set_time,
0118 };
0119
0120
0121
0122 static int dm355evm_rtc_probe(struct platform_device *pdev)
0123 {
0124 struct rtc_device *rtc;
0125
0126 rtc = devm_rtc_allocate_device(&pdev->dev);
0127 if (IS_ERR(rtc))
0128 return PTR_ERR(rtc);
0129
0130 platform_set_drvdata(pdev, rtc);
0131
0132 rtc->ops = &dm355evm_rtc_ops;
0133 rtc->range_max = U32_MAX;
0134
0135 return devm_rtc_register_device(rtc);
0136 }
0137
0138
0139
0140
0141
0142 static struct platform_driver rtc_dm355evm_driver = {
0143 .probe = dm355evm_rtc_probe,
0144 .driver = {
0145 .name = "rtc-dm355evm",
0146 },
0147 };
0148
0149 module_platform_driver(rtc_dm355evm_driver);
0150
0151 MODULE_LICENSE("GPL");