diff options
author | Mark A. Greer <mgreer@mvista.com> | 2006-04-25 07:04:54 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-22 14:10:32 -0400 |
commit | 5e9f4f2e5a02bb6908278a819952aa31fffefaa2 (patch) | |
tree | 6f000080ee15597f9523de0e6d31b192bdb0aaec | |
parent | e931b8d8a428f87e6ea488d2fd80007bb66b3ea8 (diff) |
[PATCH] I2C: m41t00: Add support for the ST M41T81 and M41T85
This patch adds support for the ST m41t81 and m41t85 i2c rtc chips
to the existing m41t00 driver.
Since there is no way to reliably determine what type of rtc chip
is in use, the chip type is passed in via platform_data. The i2c
address and square wave frequency are passed in via platform_data
as well. To accommodate the use of platform_data, a new header
file include/linux/m41t00.h has been added.
The m41t81 and m41t85 chips halt the updating of their time registers
while they are being accessed. They resume when a stop condition
exists on the i2c bus or when non-time related regs are accessed.
To make the best use of that facility and to make more efficient
use of the i2c bus, this patch replaces multiple i2c_smbus_xxx calls
with a single i2c_transfer call.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/i2c/chips/m41t00.c | 313 | ||||
-rw-r--r-- | include/linux/m41t00.h | 50 |
2 files changed, 291 insertions, 72 deletions
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index eb2be3e4416c..2dd0a34d9472 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * I2C client/driver for the ST M41T00 Real-Time Clock chip. | 2 | * I2C client/driver for the ST M41T00 family of i2c rtc chips. |
3 | * | 3 | * |
4 | * Author: Mark A. Greer <mgreer@mvista.com> | 4 | * Author: Mark A. Greer <mgreer@mvista.com> |
5 | * | 5 | * |
6 | * 2005 (c) MontaVista Software, Inc. This file is licensed under | 6 | * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under |
7 | * the terms of the GNU General Public License version 2. This program | 7 | * the terms of the GNU General Public License version 2. This program |
8 | * is licensed "as is" without any warranty of any kind, whether express | 8 | * is licensed "as is" without any warranty of any kind, whether express |
9 | * or implied. | 9 | * or implied. |
@@ -19,21 +19,17 @@ | |||
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/rtc.h> | 20 | #include <linux/rtc.h> |
21 | #include <linux/bcd.h> | 21 | #include <linux/bcd.h> |
22 | #include <linux/mutex.h> | ||
23 | #include <linux/workqueue.h> | 22 | #include <linux/workqueue.h> |
24 | 23 | #include <linux/platform_device.h> | |
24 | #include <linux/m41t00.h> | ||
25 | #include <asm/time.h> | 25 | #include <asm/time.h> |
26 | #include <asm/rtc.h> | 26 | #include <asm/rtc.h> |
27 | 27 | ||
28 | #define M41T00_DRV_NAME "m41t00" | ||
29 | |||
30 | static DEFINE_MUTEX(m41t00_mutex); | ||
31 | |||
32 | static struct i2c_driver m41t00_driver; | 28 | static struct i2c_driver m41t00_driver; |
33 | static struct i2c_client *save_client; | 29 | static struct i2c_client *save_client; |
34 | 30 | ||
35 | static unsigned short ignore[] = { I2C_CLIENT_END }; | 31 | static unsigned short ignore[] = { I2C_CLIENT_END }; |
36 | static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END }; | 32 | static unsigned short normal_addr[] = { I2C_CLIENT_END, I2C_CLIENT_END }; |
37 | 33 | ||
38 | static struct i2c_client_address_data addr_data = { | 34 | static struct i2c_client_address_data addr_data = { |
39 | .normal_i2c = normal_addr, | 35 | .normal_i2c = normal_addr, |
@@ -41,34 +37,92 @@ static struct i2c_client_address_data addr_data = { | |||
41 | .ignore = ignore, | 37 | .ignore = ignore, |
42 | }; | 38 | }; |
43 | 39 | ||
40 | struct m41t00_chip_info { | ||
41 | u8 type; | ||
42 | char *name; | ||
43 | u8 read_limit; | ||
44 | u8 sec; /* Offsets for chip regs */ | ||
45 | u8 min; | ||
46 | u8 hour; | ||
47 | u8 day; | ||
48 | u8 mon; | ||
49 | u8 year; | ||
50 | u8 alarm_mon; | ||
51 | u8 alarm_hour; | ||
52 | u8 sqw; | ||
53 | u8 sqw_freq; | ||
54 | }; | ||
55 | |||
56 | static struct m41t00_chip_info m41t00_chip_info_tbl[] = { | ||
57 | { | ||
58 | .type = M41T00_TYPE_M41T00, | ||
59 | .name = "m41t00", | ||
60 | .read_limit = 5, | ||
61 | .sec = 0, | ||
62 | .min = 1, | ||
63 | .hour = 2, | ||
64 | .day = 4, | ||
65 | .mon = 5, | ||
66 | .year = 6, | ||
67 | }, | ||
68 | { | ||
69 | .type = M41T00_TYPE_M41T81, | ||
70 | .name = "m41t81", | ||
71 | .read_limit = 1, | ||
72 | .sec = 1, | ||
73 | .min = 2, | ||
74 | .hour = 3, | ||
75 | .day = 5, | ||
76 | .mon = 6, | ||
77 | .year = 7, | ||
78 | .alarm_mon = 0xa, | ||
79 | .alarm_hour = 0xc, | ||
80 | .sqw = 0x13, | ||
81 | }, | ||
82 | { | ||
83 | .type = M41T00_TYPE_M41T85, | ||
84 | .name = "m41t85", | ||
85 | .read_limit = 1, | ||
86 | .sec = 1, | ||
87 | .min = 2, | ||
88 | .hour = 3, | ||
89 | .day = 5, | ||
90 | .mon = 6, | ||
91 | .year = 7, | ||
92 | .alarm_mon = 0xa, | ||
93 | .alarm_hour = 0xc, | ||
94 | .sqw = 0x13, | ||
95 | }, | ||
96 | }; | ||
97 | static struct m41t00_chip_info *m41t00_chip; | ||
98 | |||
44 | ulong | 99 | ulong |
45 | m41t00_get_rtc_time(void) | 100 | m41t00_get_rtc_time(void) |
46 | { | 101 | { |
47 | s32 sec, min, hour, day, mon, year; | 102 | s32 sec, min, hour, day, mon, year; |
48 | s32 sec1, min1, hour1, day1, mon1, year1; | 103 | s32 sec1, min1, hour1, day1, mon1, year1; |
49 | ulong limit = 10; | 104 | u8 reads = 0; |
105 | u8 buf[8], msgbuf[1] = { 0 }; /* offset into rtc's regs */ | ||
106 | struct i2c_msg msgs[] = { | ||
107 | { | ||
108 | .addr = save_client->addr, | ||
109 | .flags = 0, | ||
110 | .len = 1, | ||
111 | .buf = msgbuf, | ||
112 | }, | ||
113 | { | ||
114 | .addr = save_client->addr, | ||
115 | .flags = I2C_M_RD, | ||
116 | .len = 8, | ||
117 | .buf = buf, | ||
118 | }, | ||
119 | }; | ||
50 | 120 | ||
51 | sec = min = hour = day = mon = year = 0; | 121 | sec = min = hour = day = mon = year = 0; |
52 | sec1 = min1 = hour1 = day1 = mon1 = year1 = 0; | ||
53 | 122 | ||
54 | mutex_lock(&m41t00_mutex); | ||
55 | do { | 123 | do { |
56 | if (((sec = i2c_smbus_read_byte_data(save_client, 0)) >= 0) | 124 | if (i2c_transfer(save_client->adapter, msgs, 2) < 0) |
57 | && ((min = i2c_smbus_read_byte_data(save_client, 1)) | 125 | goto read_err; |
58 | >= 0) | ||
59 | && ((hour = i2c_smbus_read_byte_data(save_client, 2)) | ||
60 | >= 0) | ||
61 | && ((day = i2c_smbus_read_byte_data(save_client, 4)) | ||
62 | >= 0) | ||
63 | && ((mon = i2c_smbus_read_byte_data(save_client, 5)) | ||
64 | >= 0) | ||
65 | && ((year = i2c_smbus_read_byte_data(save_client, 6)) | ||
66 | >= 0) | ||
67 | && ((sec == sec1) && (min == min1) && (hour == hour1) | ||
68 | && (day == day1) && (mon == mon1) | ||
69 | && (year == year1))) | ||
70 | |||
71 | break; | ||
72 | 126 | ||
73 | sec1 = sec; | 127 | sec1 = sec; |
74 | min1 = min; | 128 | min1 = min; |
@@ -76,21 +130,21 @@ m41t00_get_rtc_time(void) | |||
76 | day1 = day; | 130 | day1 = day; |
77 | mon1 = mon; | 131 | mon1 = mon; |
78 | year1 = year; | 132 | year1 = year; |
79 | } while (--limit > 0); | ||
80 | mutex_unlock(&m41t00_mutex); | ||
81 | |||
82 | if (limit == 0) { | ||
83 | dev_warn(&save_client->dev, | ||
84 | "m41t00: can't read rtc chip\n"); | ||
85 | sec = min = hour = day = mon = year = 0; | ||
86 | } | ||
87 | 133 | ||
88 | sec &= 0x7f; | 134 | sec = buf[m41t00_chip->sec] & 0x7f; |
89 | min &= 0x7f; | 135 | min = buf[m41t00_chip->min] & 0x7f; |
90 | hour &= 0x3f; | 136 | hour = buf[m41t00_chip->hour] & 0x3f; |
91 | day &= 0x3f; | 137 | day = buf[m41t00_chip->day] & 0x3f; |
92 | mon &= 0x1f; | 138 | mon = buf[m41t00_chip->mon] & 0x1f; |
93 | year &= 0xff; | 139 | year = buf[m41t00_chip->year]; |
140 | } while ((++reads < m41t00_chip->read_limit) && ((sec != sec1) | ||
141 | || (min != min1) || (hour != hour1) || (day != day1) | ||
142 | || (mon != mon1) || (year != year1))); | ||
143 | |||
144 | if ((m41t00_chip->read_limit > 1) && ((sec != sec1) || (min != min1) | ||
145 | || (hour != hour1) || (day != day1) || (mon != mon1) | ||
146 | || (year != year1))) | ||
147 | goto read_err; | ||
94 | 148 | ||
95 | sec = BCD2BIN(sec); | 149 | sec = BCD2BIN(sec); |
96 | min = BCD2BIN(min); | 150 | min = BCD2BIN(min); |
@@ -104,40 +158,60 @@ m41t00_get_rtc_time(void) | |||
104 | year += 100; | 158 | year += 100; |
105 | 159 | ||
106 | return mktime(year, mon, day, hour, min, sec); | 160 | return mktime(year, mon, day, hour, min, sec); |
161 | |||
162 | read_err: | ||
163 | dev_err(&save_client->dev, "m41t00_get_rtc_time: Read error\n"); | ||
164 | return 0; | ||
107 | } | 165 | } |
166 | EXPORT_SYMBOL_GPL(m41t00_get_rtc_time); | ||
108 | 167 | ||
109 | static void | 168 | static void |
110 | m41t00_set(void *arg) | 169 | m41t00_set(void *arg) |
111 | { | 170 | { |
112 | struct rtc_time tm; | 171 | struct rtc_time tm; |
113 | ulong nowtime = *(ulong *)arg; | 172 | int nowtime = *(int *)arg; |
173 | s32 sec, min, hour, day, mon, year; | ||
174 | u8 wbuf[9], *buf = &wbuf[1], msgbuf[1] = { 0 }; | ||
175 | struct i2c_msg msgs[] = { | ||
176 | { | ||
177 | .addr = save_client->addr, | ||
178 | .flags = 0, | ||
179 | .len = 1, | ||
180 | .buf = msgbuf, | ||
181 | }, | ||
182 | { | ||
183 | .addr = save_client->addr, | ||
184 | .flags = I2C_M_RD, | ||
185 | .len = 8, | ||
186 | .buf = buf, | ||
187 | }, | ||
188 | }; | ||
114 | 189 | ||
115 | to_tm(nowtime, &tm); | 190 | to_tm(nowtime, &tm); |
116 | tm.tm_year = (tm.tm_year - 1900) % 100; | 191 | tm.tm_year = (tm.tm_year - 1900) % 100; |
117 | 192 | ||
118 | tm.tm_sec = BIN2BCD(tm.tm_sec); | 193 | sec = BIN2BCD(tm.tm_sec); |
119 | tm.tm_min = BIN2BCD(tm.tm_min); | 194 | min = BIN2BCD(tm.tm_min); |
120 | tm.tm_hour = BIN2BCD(tm.tm_hour); | 195 | hour = BIN2BCD(tm.tm_hour); |
121 | tm.tm_mon = BIN2BCD(tm.tm_mon); | 196 | day = BIN2BCD(tm.tm_mday); |
122 | tm.tm_mday = BIN2BCD(tm.tm_mday); | 197 | mon = BIN2BCD(tm.tm_mon); |
123 | tm.tm_year = BIN2BCD(tm.tm_year); | 198 | year = BIN2BCD(tm.tm_year); |
124 | 199 | ||
125 | mutex_lock(&m41t00_mutex); | 200 | /* Read reg values into buf[0..7]/wbuf[1..8] */ |
126 | if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) | 201 | if (i2c_transfer(save_client->adapter, msgs, 2) < 0) { |
127 | || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) | 202 | dev_err(&save_client->dev, "m41t00_set: Read error\n"); |
128 | < 0) | 203 | return; |
129 | || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x3f) | 204 | } |
130 | < 0) | 205 | |
131 | || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x3f) | 206 | wbuf[0] = 0; /* offset into rtc's regs */ |
132 | < 0) | 207 | buf[m41t00_chip->sec] = (buf[m41t00_chip->sec] & ~0x7f) | (sec & 0x7f); |
133 | || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x1f) | 208 | buf[m41t00_chip->min] = (buf[m41t00_chip->min] & ~0x7f) | (min & 0x7f); |
134 | < 0) | 209 | buf[m41t00_chip->hour] = (buf[m41t00_chip->hour] & ~0x3f) | (hour& 0x3f); |
135 | || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0xff) | 210 | buf[m41t00_chip->day] = (buf[m41t00_chip->day] & ~0x3f) | (day & 0x3f); |
136 | < 0)) | 211 | buf[m41t00_chip->mon] = (buf[m41t00_chip->mon] & ~0x1f) | (mon & 0x1f); |
137 | 212 | ||
138 | dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); | 213 | if (i2c_master_send(save_client, wbuf, 9) < 0) |
139 | 214 | dev_err(&save_client->dev, "m41t00_set: Write error\n"); | |
140 | mutex_unlock(&m41t00_mutex); | ||
141 | } | 215 | } |
142 | 216 | ||
143 | static ulong new_time; | 217 | static ulong new_time; |
@@ -156,6 +230,48 @@ m41t00_set_rtc_time(ulong nowtime) | |||
156 | 230 | ||
157 | return 0; | 231 | return 0; |
158 | } | 232 | } |
233 | EXPORT_SYMBOL_GPL(m41t00_set_rtc_time); | ||
234 | |||
235 | /* | ||
236 | ***************************************************************************** | ||
237 | * | ||
238 | * platform_data Driver Interface | ||
239 | * | ||
240 | ***************************************************************************** | ||
241 | */ | ||
242 | static int __init | ||
243 | m41t00_platform_probe(struct platform_device *pdev) | ||
244 | { | ||
245 | struct m41t00_platform_data *pdata; | ||
246 | int i; | ||
247 | |||
248 | if (pdev && (pdata = pdev->dev.platform_data)) { | ||
249 | normal_addr[0] = pdata->i2c_addr; | ||
250 | |||
251 | for (i=0; i<ARRAY_SIZE(m41t00_chip_info_tbl); i++) | ||
252 | if (m41t00_chip_info_tbl[i].type == pdata->type) { | ||
253 | m41t00_chip = &m41t00_chip_info_tbl[i]; | ||
254 | m41t00_chip->sqw_freq = pdata->sqw_freq; | ||
255 | return 0; | ||
256 | } | ||
257 | } | ||
258 | return -ENODEV; | ||
259 | } | ||
260 | |||
261 | static int __exit | ||
262 | m41t00_platform_remove(struct platform_device *pdev) | ||
263 | { | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static struct platform_driver m41t00_platform_driver = { | ||
268 | .probe = m41t00_platform_probe, | ||
269 | .remove = m41t00_platform_remove, | ||
270 | .driver = { | ||
271 | .owner = THIS_MODULE, | ||
272 | .name = M41T00_DRV_NAME, | ||
273 | }, | ||
274 | }; | ||
159 | 275 | ||
160 | /* | 276 | /* |
161 | ***************************************************************************** | 277 | ***************************************************************************** |
@@ -170,23 +286,71 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind) | |||
170 | struct i2c_client *client; | 286 | struct i2c_client *client; |
171 | int rc; | 287 | int rc; |
172 | 288 | ||
289 | if (!i2c_check_functionality(adap, I2C_FUNC_I2C | ||
290 | | I2C_FUNC_SMBUS_BYTE_DATA)) | ||
291 | return 0; | ||
292 | |||
173 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 293 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); |
174 | if (!client) | 294 | if (!client) |
175 | return -ENOMEM; | 295 | return -ENOMEM; |
176 | 296 | ||
177 | strlcpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE); | 297 | strlcpy(client->name, m41t00_chip->name, I2C_NAME_SIZE); |
178 | client->addr = addr; | 298 | client->addr = addr; |
179 | client->adapter = adap; | 299 | client->adapter = adap; |
180 | client->driver = &m41t00_driver; | 300 | client->driver = &m41t00_driver; |
181 | 301 | ||
182 | if ((rc = i2c_attach_client(client)) != 0) { | 302 | if ((rc = i2c_attach_client(client))) |
183 | kfree(client); | 303 | goto attach_err; |
184 | return rc; | 304 | |
305 | if (m41t00_chip->type != M41T00_TYPE_M41T00) { | ||
306 | /* If asked, disable SQW, set SQW frequency & re-enable */ | ||
307 | if (m41t00_chip->sqw_freq) | ||
308 | if (((rc = i2c_smbus_read_byte_data(client, | ||
309 | m41t00_chip->alarm_mon)) < 0) | ||
310 | || ((rc = i2c_smbus_write_byte_data(client, | ||
311 | m41t00_chip->alarm_mon, rc & ~0x40)) <0) | ||
312 | || ((rc = i2c_smbus_write_byte_data(client, | ||
313 | m41t00_chip->sqw, | ||
314 | m41t00_chip->sqw_freq)) < 0) | ||
315 | || ((rc = i2c_smbus_write_byte_data(client, | ||
316 | m41t00_chip->alarm_mon, rc | 0x40)) <0)) | ||
317 | goto sqw_err; | ||
318 | |||
319 | /* Make sure HT (Halt Update) bit is cleared */ | ||
320 | if ((rc = i2c_smbus_read_byte_data(client, | ||
321 | m41t00_chip->alarm_hour)) < 0) | ||
322 | goto ht_err; | ||
323 | |||
324 | if (rc & 0x40) | ||
325 | if ((rc = i2c_smbus_write_byte_data(client, | ||
326 | m41t00_chip->alarm_hour, rc & ~0x40))<0) | ||
327 | goto ht_err; | ||
185 | } | 328 | } |
186 | 329 | ||
187 | m41t00_wq = create_singlethread_workqueue("m41t00"); | 330 | /* Make sure ST (stop) bit is cleared */ |
331 | if ((rc = i2c_smbus_read_byte_data(client, m41t00_chip->sec)) < 0) | ||
332 | goto st_err; | ||
333 | |||
334 | if (rc & 0x80) | ||
335 | if ((rc = i2c_smbus_write_byte_data(client, m41t00_chip->sec, | ||
336 | rc & ~0x80)) < 0) | ||
337 | goto st_err; | ||
338 | |||
339 | m41t00_wq = create_singlethread_workqueue(m41t00_chip->name); | ||
188 | save_client = client; | 340 | save_client = client; |
189 | return 0; | 341 | return 0; |
342 | |||
343 | st_err: | ||
344 | dev_err(&client->dev, "m41t00_probe: Can't clear ST bit\n"); | ||
345 | goto attach_err; | ||
346 | ht_err: | ||
347 | dev_err(&client->dev, "m41t00_probe: Can't clear HT bit\n"); | ||
348 | goto attach_err; | ||
349 | sqw_err: | ||
350 | dev_err(&client->dev, "m41t00_probe: Can't set SQW Frequency\n"); | ||
351 | attach_err: | ||
352 | kfree(client); | ||
353 | return rc; | ||
190 | } | 354 | } |
191 | 355 | ||
192 | static int | 356 | static int |
@@ -219,13 +383,18 @@ static struct i2c_driver m41t00_driver = { | |||
219 | static int __init | 383 | static int __init |
220 | m41t00_init(void) | 384 | m41t00_init(void) |
221 | { | 385 | { |
222 | return i2c_add_driver(&m41t00_driver); | 386 | int rc; |
387 | |||
388 | if (!(rc = platform_driver_register(&m41t00_platform_driver))) | ||
389 | rc = i2c_add_driver(&m41t00_driver); | ||
390 | return rc; | ||
223 | } | 391 | } |
224 | 392 | ||
225 | static void __exit | 393 | static void __exit |
226 | m41t00_exit(void) | 394 | m41t00_exit(void) |
227 | { | 395 | { |
228 | i2c_del_driver(&m41t00_driver); | 396 | i2c_del_driver(&m41t00_driver); |
397 | platform_driver_unregister(&m41t00_platform_driver); | ||
229 | } | 398 | } |
230 | 399 | ||
231 | module_init(m41t00_init); | 400 | module_init(m41t00_init); |
diff --git a/include/linux/m41t00.h b/include/linux/m41t00.h new file mode 100644 index 000000000000..b423360ca38e --- /dev/null +++ b/include/linux/m41t00.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * Definitions for the ST M41T00 family of i2c rtc chips. | ||
3 | * | ||
4 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
5 | * | ||
6 | * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | |||
12 | #ifndef _M41T00_H | ||
13 | #define _M41T00_H | ||
14 | |||
15 | #define M41T00_DRV_NAME "m41t00" | ||
16 | #define M41T00_I2C_ADDR 0x68 | ||
17 | |||
18 | #define M41T00_TYPE_M41T00 0 | ||
19 | #define M41T00_TYPE_M41T81 81 | ||
20 | #define M41T00_TYPE_M41T85 85 | ||
21 | |||
22 | struct m41t00_platform_data { | ||
23 | u8 type; | ||
24 | u8 i2c_addr; | ||
25 | u8 sqw_freq; | ||
26 | }; | ||
27 | |||
28 | /* SQW output disabled, this is default value by power on */ | ||
29 | #define M41T00_SQW_DISABLE (0) | ||
30 | |||
31 | #define M41T00_SQW_32KHZ (1<<4) /* 32.768 KHz */ | ||
32 | #define M41T00_SQW_8KHZ (2<<4) /* 8.192 KHz */ | ||
33 | #define M41T00_SQW_4KHZ (3<<4) /* 4.096 KHz */ | ||
34 | #define M41T00_SQW_2KHZ (4<<4) /* 2.048 KHz */ | ||
35 | #define M41T00_SQW_1KHZ (5<<4) /* 1.024 KHz */ | ||
36 | #define M41T00_SQW_512HZ (6<<4) /* 512 Hz */ | ||
37 | #define M41T00_SQW_256HZ (7<<4) /* 256 Hz */ | ||
38 | #define M41T00_SQW_128HZ (8<<4) /* 128 Hz */ | ||
39 | #define M41T00_SQW_64HZ (9<<4) /* 64 Hz */ | ||
40 | #define M41T00_SQW_32HZ (10<<4) /* 32 Hz */ | ||
41 | #define M41T00_SQW_16HZ (11<<4) /* 16 Hz */ | ||
42 | #define M41T00_SQW_8HZ (12<<4) /* 8 Hz */ | ||
43 | #define M41T00_SQW_4HZ (13<<4) /* 4 Hz */ | ||
44 | #define M41T00_SQW_2HZ (14<<4) /* 2 Hz */ | ||
45 | #define M41T00_SQW_1HZ (15<<4) /* 1 Hz */ | ||
46 | |||
47 | extern ulong m41t00_get_rtc_time(void); | ||
48 | extern int m41t00_set_rtc_time(ulong nowtime); | ||
49 | |||
50 | #endif /* _M41T00_H */ | ||