This source file includes following definitions.
- m41t93_set_reg
- m41t93_set_time
- m41t93_get_time
- m41t93_probe
1
2
3
4
5
6
7
8
9 #include <linux/bcd.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/rtc.h>
14 #include <linux/spi/spi.h>
15
16 #define M41T93_REG_SSEC 0
17 #define M41T93_REG_ST_SEC 1
18 #define M41T93_REG_MIN 2
19 #define M41T93_REG_CENT_HOUR 3
20 #define M41T93_REG_WDAY 4
21 #define M41T93_REG_DAY 5
22 #define M41T93_REG_MON 6
23 #define M41T93_REG_YEAR 7
24
25
26 #define M41T93_REG_ALM_HOUR_HT 0xc
27 #define M41T93_REG_FLAGS 0xf
28
29 #define M41T93_FLAG_ST (1 << 7)
30 #define M41T93_FLAG_OF (1 << 2)
31 #define M41T93_FLAG_BL (1 << 4)
32 #define M41T93_FLAG_HT (1 << 6)
33
34 static inline int m41t93_set_reg(struct spi_device *spi, u8 addr, u8 data)
35 {
36 u8 buf[2];
37
38
39 buf[0] = addr | 0x80;
40 buf[1] = data;
41
42 return spi_write(spi, buf, sizeof(buf));
43 }
44
45 static int m41t93_set_time(struct device *dev, struct rtc_time *tm)
46 {
47 struct spi_device *spi = to_spi_device(dev);
48 int tmp;
49 u8 buf[9] = {0x80};
50 u8 * const data = &buf[1];
51
52 dev_dbg(dev, "%s secs=%d, mins=%d, "
53 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
54 "write", tm->tm_sec, tm->tm_min,
55 tm->tm_hour, tm->tm_mday,
56 tm->tm_mon, tm->tm_year, tm->tm_wday);
57
58 if (tm->tm_year < 100) {
59 dev_warn(&spi->dev, "unsupported date (before 2000-01-01).\n");
60 return -EINVAL;
61 }
62
63 tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
64 if (tmp < 0)
65 return tmp;
66
67 if (tmp & M41T93_FLAG_OF) {
68 dev_warn(&spi->dev, "OF bit is set, resetting.\n");
69 m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF);
70
71 tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
72 if (tmp < 0) {
73 return tmp;
74 } else if (tmp & M41T93_FLAG_OF) {
75
76
77 u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST;
78
79 dev_warn(&spi->dev,
80 "OF bit is still set, kickstarting clock.\n");
81 m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
82 reset_osc &= ~M41T93_FLAG_ST;
83 m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
84 }
85 }
86
87 data[M41T93_REG_SSEC] = 0;
88 data[M41T93_REG_ST_SEC] = bin2bcd(tm->tm_sec);
89 data[M41T93_REG_MIN] = bin2bcd(tm->tm_min);
90 data[M41T93_REG_CENT_HOUR] = bin2bcd(tm->tm_hour) |
91 ((tm->tm_year/100-1) << 6);
92 data[M41T93_REG_DAY] = bin2bcd(tm->tm_mday);
93 data[M41T93_REG_WDAY] = bin2bcd(tm->tm_wday + 1);
94 data[M41T93_REG_MON] = bin2bcd(tm->tm_mon + 1);
95 data[M41T93_REG_YEAR] = bin2bcd(tm->tm_year % 100);
96
97 return spi_write(spi, buf, sizeof(buf));
98 }
99
100
101 static int m41t93_get_time(struct device *dev, struct rtc_time *tm)
102 {
103 struct spi_device *spi = to_spi_device(dev);
104 const u8 start_addr = 0;
105 u8 buf[8];
106 int century_after_1900;
107 int tmp;
108 int ret = 0;
109
110
111
112
113
114
115
116 tmp = spi_w8r8(spi, M41T93_REG_ALM_HOUR_HT);
117 if (tmp < 0)
118 return tmp;
119
120 if (tmp & M41T93_FLAG_HT) {
121 dev_dbg(&spi->dev, "HT bit is set, reenable clock update.\n");
122 m41t93_set_reg(spi, M41T93_REG_ALM_HOUR_HT,
123 tmp & ~M41T93_FLAG_HT);
124 }
125
126 tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
127 if (tmp < 0)
128 return tmp;
129
130 if (tmp & M41T93_FLAG_OF) {
131 ret = -EINVAL;
132 dev_warn(&spi->dev, "OF bit is set, write time to restart.\n");
133 }
134
135 if (tmp & M41T93_FLAG_BL)
136 dev_warn(&spi->dev, "BL bit is set, replace battery.\n");
137
138
139 tmp = spi_write_then_read(spi, &start_addr, 1, buf, sizeof(buf));
140 if (tmp < 0)
141 return tmp;
142
143 tm->tm_sec = bcd2bin(buf[M41T93_REG_ST_SEC]);
144 tm->tm_min = bcd2bin(buf[M41T93_REG_MIN]);
145 tm->tm_hour = bcd2bin(buf[M41T93_REG_CENT_HOUR] & 0x3f);
146 tm->tm_mday = bcd2bin(buf[M41T93_REG_DAY]);
147 tm->tm_mon = bcd2bin(buf[M41T93_REG_MON]) - 1;
148 tm->tm_wday = bcd2bin(buf[M41T93_REG_WDAY] & 0x0f) - 1;
149
150 century_after_1900 = (buf[M41T93_REG_CENT_HOUR] >> 6) + 1;
151 tm->tm_year = bcd2bin(buf[M41T93_REG_YEAR]) + century_after_1900 * 100;
152
153 dev_dbg(dev, "%s secs=%d, mins=%d, "
154 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
155 "read", tm->tm_sec, tm->tm_min,
156 tm->tm_hour, tm->tm_mday,
157 tm->tm_mon, tm->tm_year, tm->tm_wday);
158
159 return ret;
160 }
161
162
163 static const struct rtc_class_ops m41t93_rtc_ops = {
164 .read_time = m41t93_get_time,
165 .set_time = m41t93_set_time,
166 };
167
168 static struct spi_driver m41t93_driver;
169
170 static int m41t93_probe(struct spi_device *spi)
171 {
172 struct rtc_device *rtc;
173 int res;
174
175 spi->bits_per_word = 8;
176 spi_setup(spi);
177
178 res = spi_w8r8(spi, M41T93_REG_WDAY);
179 if (res < 0 || (res & 0xf8) != 0) {
180 dev_err(&spi->dev, "not found 0x%x.\n", res);
181 return -ENODEV;
182 }
183
184 rtc = devm_rtc_device_register(&spi->dev, m41t93_driver.driver.name,
185 &m41t93_rtc_ops, THIS_MODULE);
186 if (IS_ERR(rtc))
187 return PTR_ERR(rtc);
188
189 spi_set_drvdata(spi, rtc);
190
191 return 0;
192 }
193
194 static struct spi_driver m41t93_driver = {
195 .driver = {
196 .name = "rtc-m41t93",
197 },
198 .probe = m41t93_probe,
199 };
200
201 module_spi_driver(m41t93_driver);
202
203 MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>");
204 MODULE_DESCRIPTION("Driver for ST M41T93 SPI RTC");
205 MODULE_LICENSE("GPL");
206 MODULE_ALIAS("spi:rtc-m41t93");