OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [rtc/] [rtc-pcf8563.c] - Blame information for rev 67

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * An I2C driver for the Philips PCF8563 RTC
3
 * Copyright 2005-06 Tower Technologies
4
 *
5
 * Author: Alessandro Zummo <a.zummo@towertech.it>
6
 * Maintainers: http://www.nslu2-linux.org/
7
 *
8
 * based on the other drivers in this same directory.
9
 *
10
 * http://www.semiconductors.philips.com/acrobat/datasheets/PCF8563-04.pdf
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License version 2 as
14
 * published by the Free Software Foundation.
15
 */
16
 
17
#include <linux/i2c.h>
18
#include <linux/bcd.h>
19
#include <linux/rtc.h>
20
 
21
#define DRV_VERSION "0.4.2"
22
 
23
/* Addresses to scan: none
24
 * This chip cannot be reliably autodetected. An empty eeprom
25
 * located at 0x51 will pass the validation routine due to
26
 * the way the registers are implemented.
27
 */
28
static unsigned short normal_i2c[] = { I2C_CLIENT_END };
29
 
30
/* Module parameters */
31
I2C_CLIENT_INSMOD;
32
 
33
#define PCF8563_REG_ST1         0x00 /* status */
34
#define PCF8563_REG_ST2         0x01
35
 
36
#define PCF8563_REG_SC          0x02 /* datetime */
37
#define PCF8563_REG_MN          0x03
38
#define PCF8563_REG_HR          0x04
39
#define PCF8563_REG_DM          0x05
40
#define PCF8563_REG_DW          0x06
41
#define PCF8563_REG_MO          0x07
42
#define PCF8563_REG_YR          0x08
43
 
44
#define PCF8563_REG_AMN         0x09 /* alarm */
45
#define PCF8563_REG_AHR         0x0A
46
#define PCF8563_REG_ADM         0x0B
47
#define PCF8563_REG_ADW         0x0C
48
 
49
#define PCF8563_REG_CLKO        0x0D /* clock out */
50
#define PCF8563_REG_TMRC        0x0E /* timer control */
51
#define PCF8563_REG_TMR         0x0F /* timer */
52
 
53
#define PCF8563_SC_LV           0x80 /* low voltage */
54
#define PCF8563_MO_C            0x80 /* century */
55
 
56
struct pcf8563 {
57
        struct i2c_client client;
58
        /*
59
         * The meaning of MO_C bit varies by the chip type.
60
         * From PCF8563 datasheet: this bit is toggled when the years
61
         * register overflows from 99 to 00
62
         *   0 indicates the century is 20xx
63
         *   1 indicates the century is 19xx
64
         * From RTC8564 datasheet: this bit indicates change of
65
         * century. When the year digit data overflows from 99 to 00,
66
         * this bit is set. By presetting it to 0 while still in the
67
         * 20th century, it will be set in year 2000, ...
68
         * There seems no reliable way to know how the system use this
69
         * bit.  So let's do it heuristically, assuming we are live in
70
         * 1970...2069.
71
         */
72
        int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
73
};
74
 
75
static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
76
static int pcf8563_detach(struct i2c_client *client);
77
 
78
/*
79
 * In the routines that deal directly with the pcf8563 hardware, we use
80
 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
81
 */
82
static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
83
{
84
        struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
85
        unsigned char buf[13] = { PCF8563_REG_ST1 };
86
 
87
        struct i2c_msg msgs[] = {
88
                { client->addr, 0, 1, buf },     /* setup read ptr */
89
                { client->addr, I2C_M_RD, 13, buf },    /* read status + date */
90
        };
91
 
92
        /* read registers */
93
        if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
94
                dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
95
                return -EIO;
96
        }
97
 
98
        if (buf[PCF8563_REG_SC] & PCF8563_SC_LV)
99
                dev_info(&client->dev,
100
                        "low voltage detected, date/time is not reliable.\n");
101
 
102
        dev_dbg(&client->dev,
103
                "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, "
104
                "mday=%02x, wday=%02x, mon=%02x, year=%02x\n",
105
                __FUNCTION__,
106
                buf[0], buf[1], buf[2], buf[3],
107
                buf[4], buf[5], buf[6], buf[7],
108
                buf[8]);
109
 
110
 
111
        tm->tm_sec = BCD2BIN(buf[PCF8563_REG_SC] & 0x7F);
112
        tm->tm_min = BCD2BIN(buf[PCF8563_REG_MN] & 0x7F);
113
        tm->tm_hour = BCD2BIN(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */
114
        tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F);
115
        tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
116
        tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
117
        tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR]);
118
        if (tm->tm_year < 70)
119
                tm->tm_year += 100;     /* assume we are in 1970...2069 */
120
        /* detect the polarity heuristically. see note above. */
121
        pcf8563->c_polarity = (buf[PCF8563_REG_MO] & PCF8563_MO_C) ?
122
                (tm->tm_year >= 100) : (tm->tm_year < 100);
123
 
124
        dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
125
                "mday=%d, mon=%d, year=%d, wday=%d\n",
126
                __FUNCTION__,
127
                tm->tm_sec, tm->tm_min, tm->tm_hour,
128
                tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
129
 
130
        /* the clock can give out invalid datetime, but we cannot return
131
         * -EINVAL otherwise hwclock will refuse to set the time on bootup.
132
         */
133
        if (rtc_valid_tm(tm) < 0)
134
                dev_err(&client->dev, "retrieved date/time is not valid.\n");
135
 
136
        return 0;
137
}
138
 
139
static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
140
{
141
        struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
142
        int i, err;
143
        unsigned char buf[9];
144
 
145
        dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
146
                "mday=%d, mon=%d, year=%d, wday=%d\n",
147
                __FUNCTION__,
148
                tm->tm_sec, tm->tm_min, tm->tm_hour,
149
                tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
150
 
151
        /* hours, minutes and seconds */
152
        buf[PCF8563_REG_SC] = BIN2BCD(tm->tm_sec);
153
        buf[PCF8563_REG_MN] = BIN2BCD(tm->tm_min);
154
        buf[PCF8563_REG_HR] = BIN2BCD(tm->tm_hour);
155
 
156
        buf[PCF8563_REG_DM] = BIN2BCD(tm->tm_mday);
157
 
158
        /* month, 1 - 12 */
159
        buf[PCF8563_REG_MO] = BIN2BCD(tm->tm_mon + 1);
160
 
161
        /* year and century */
162
        buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
163
        if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100))
164
                buf[PCF8563_REG_MO] |= PCF8563_MO_C;
165
 
166
        buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
167
 
168
        /* write register's data */
169
        for (i = 0; i < 7; i++) {
170
                unsigned char data[2] = { PCF8563_REG_SC + i,
171
                                                buf[PCF8563_REG_SC + i] };
172
 
173
                err = i2c_master_send(client, data, sizeof(data));
174
                if (err != sizeof(data)) {
175
                        dev_err(&client->dev,
176
                                "%s: err=%d addr=%02x, data=%02x\n",
177
                                __FUNCTION__, err, data[0], data[1]);
178
                        return -EIO;
179
                }
180
        };
181
 
182
        return 0;
183
}
184
 
185
struct pcf8563_limit
186
{
187
        unsigned char reg;
188
        unsigned char mask;
189
        unsigned char min;
190
        unsigned char max;
191
};
192
 
193
static int pcf8563_validate_client(struct i2c_client *client)
194
{
195
        int i;
196
 
197
        static const struct pcf8563_limit pattern[] = {
198
                /* register, mask, min, max */
199
                { PCF8563_REG_SC,       0x7F,   0,       59      },
200
                { PCF8563_REG_MN,       0x7F,   0,       59      },
201
                { PCF8563_REG_HR,       0x3F,   0,       23      },
202
                { PCF8563_REG_DM,       0x3F,   0,       31      },
203
                { PCF8563_REG_MO,       0x1F,   0,       12      },
204
        };
205
 
206
        /* check limits (only registers with bcd values) */
207
        for (i = 0; i < ARRAY_SIZE(pattern); i++) {
208
                int xfer;
209
                unsigned char value;
210
                unsigned char buf = pattern[i].reg;
211
 
212
                struct i2c_msg msgs[] = {
213
                        { client->addr, 0, 1, &buf },
214
                        { client->addr, I2C_M_RD, 1, &buf },
215
                };
216
 
217
                xfer = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
218
 
219
                if (xfer != ARRAY_SIZE(msgs)) {
220
                        dev_err(&client->dev,
221
                                "%s: could not read register 0x%02X\n",
222
                                __FUNCTION__, pattern[i].reg);
223
 
224
                        return -EIO;
225
                }
226
 
227
                value = BCD2BIN(buf & pattern[i].mask);
228
 
229
                if (value > pattern[i].max ||
230
                        value < pattern[i].min) {
231
                        dev_dbg(&client->dev,
232
                                "%s: pattern=%d, reg=%x, mask=0x%02x, min=%d, "
233
                                "max=%d, value=%d, raw=0x%02X\n",
234
                                __FUNCTION__, i, pattern[i].reg, pattern[i].mask,
235
                                pattern[i].min, pattern[i].max,
236
                                value, buf);
237
 
238
                        return -ENODEV;
239
                }
240
        }
241
 
242
        return 0;
243
}
244
 
245
static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
246
{
247
        return pcf8563_get_datetime(to_i2c_client(dev), tm);
248
}
249
 
250
static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
251
{
252
        return pcf8563_set_datetime(to_i2c_client(dev), tm);
253
}
254
 
255
static const struct rtc_class_ops pcf8563_rtc_ops = {
256
        .read_time      = pcf8563_rtc_read_time,
257
        .set_time       = pcf8563_rtc_set_time,
258
};
259
 
260
static int pcf8563_attach(struct i2c_adapter *adapter)
261
{
262
        return i2c_probe(adapter, &addr_data, pcf8563_probe);
263
}
264
 
265
static struct i2c_driver pcf8563_driver = {
266
        .driver         = {
267
                .name   = "pcf8563",
268
        },
269
        .id             = I2C_DRIVERID_PCF8563,
270
        .attach_adapter = &pcf8563_attach,
271
        .detach_client  = &pcf8563_detach,
272
};
273
 
274
static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
275
{
276
        struct pcf8563 *pcf8563;
277
        struct i2c_client *client;
278
        struct rtc_device *rtc;
279
 
280
        int err = 0;
281
 
282
        dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
283
 
284
        if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
285
                err = -ENODEV;
286
                goto exit;
287
        }
288
 
289
        if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) {
290
                err = -ENOMEM;
291
                goto exit;
292
        }
293
 
294
        client = &pcf8563->client;
295
        client->addr = address;
296
        client->driver = &pcf8563_driver;
297
        client->adapter = adapter;
298
 
299
        strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE);
300
 
301
        /* Verify the chip is really an PCF8563 */
302
        if (kind < 0) {
303
                if (pcf8563_validate_client(client) < 0) {
304
                        err = -ENODEV;
305
                        goto exit_kfree;
306
                }
307
        }
308
 
309
        /* Inform the i2c layer */
310
        if ((err = i2c_attach_client(client)))
311
                goto exit_kfree;
312
 
313
        dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
314
 
315
        rtc = rtc_device_register(pcf8563_driver.driver.name, &client->dev,
316
                                &pcf8563_rtc_ops, THIS_MODULE);
317
 
318
        if (IS_ERR(rtc)) {
319
                err = PTR_ERR(rtc);
320
                goto exit_detach;
321
        }
322
 
323
        i2c_set_clientdata(client, rtc);
324
 
325
        return 0;
326
 
327
exit_detach:
328
        i2c_detach_client(client);
329
 
330
exit_kfree:
331
        kfree(pcf8563);
332
 
333
exit:
334
        return err;
335
}
336
 
337
static int pcf8563_detach(struct i2c_client *client)
338
{
339
        struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
340
        int err;
341
        struct rtc_device *rtc = i2c_get_clientdata(client);
342
 
343
        if (rtc)
344
                rtc_device_unregister(rtc);
345
 
346
        if ((err = i2c_detach_client(client)))
347
                return err;
348
 
349
        kfree(pcf8563);
350
 
351
        return 0;
352
}
353
 
354
static int __init pcf8563_init(void)
355
{
356
        return i2c_add_driver(&pcf8563_driver);
357
}
358
 
359
static void __exit pcf8563_exit(void)
360
{
361
        i2c_del_driver(&pcf8563_driver);
362
}
363
 
364
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
365
MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
366
MODULE_LICENSE("GPL");
367
MODULE_VERSION(DRV_VERSION);
368
 
369
module_init(pcf8563_init);
370
module_exit(pcf8563_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.