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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [rtc/] [rtc-max6900.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * rtc class driver for the Maxim MAX6900 chip
3
 *
4
 * Author: Dale Farnsworth <dale@farnsworth.org>
5
 *
6
 * based on previously existing rtc class drivers
7
 *
8
 * 2007 (c) MontaVista, Software, Inc.  This file is licensed under
9
 * the terms of the GNU General Public License version 2.  This program
10
 * is licensed "as is" without any warranty of any kind, whether express
11
 * or implied.
12
 */
13
 
14
#include <linux/module.h>
15
#include <linux/i2c.h>
16
#include <linux/bcd.h>
17
#include <linux/rtc.h>
18
#include <linux/delay.h>
19
 
20
#define DRV_NAME "max6900"
21
#define DRV_VERSION "0.1"
22
 
23
/*
24
 * register indices
25
 */
26
#define MAX6900_REG_SC                  0        /* seconds      00-59 */
27
#define MAX6900_REG_MN                  1       /* minutes      00-59 */
28
#define MAX6900_REG_HR                  2       /* hours        00-23 */
29
#define MAX6900_REG_DT                  3       /* day of month 00-31 */
30
#define MAX6900_REG_MO                  4       /* month        01-12 */
31
#define MAX6900_REG_DW                  5       /* day of week   1-7  */
32
#define MAX6900_REG_YR                  6       /* year         00-99 */
33
#define MAX6900_REG_CT                  7       /* control */
34
                                                /* register 8 is undocumented */
35
#define MAX6900_REG_CENTURY             9       /* century */
36
#define MAX6900_REG_LEN                 10
37
 
38
#define MAX6900_BURST_LEN               8       /* can burst r/w first 8 regs */
39
 
40
#define MAX6900_REG_CT_WP               (1 << 7)        /* Write Protect */
41
 
42
 
43
/*
44
 * register read/write commands
45
 */
46
#define MAX6900_REG_CONTROL_WRITE       0x8e
47
#define MAX6900_REG_CENTURY_WRITE       0x92
48
#define MAX6900_REG_CENTURY_READ        0x93
49
#define MAX6900_REG_RESERVED_READ       0x96
50
#define MAX6900_REG_BURST_WRITE         0xbe
51
#define MAX6900_REG_BURST_READ          0xbf
52
 
53
#define MAX6900_IDLE_TIME_AFTER_WRITE   3       /* specification says 2.5 mS */
54
 
55
#define MAX6900_I2C_ADDR                0xa0
56
 
57
static unsigned short normal_i2c[] = {
58
        MAX6900_I2C_ADDR >> 1,
59
        I2C_CLIENT_END
60
};
61
 
62
I2C_CLIENT_INSMOD;                      /* defines addr_data */
63
 
64
static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind);
65
 
66
static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
67
{
68
        u8 reg_burst_read[1] = { MAX6900_REG_BURST_READ };
69
        u8 reg_century_read[1] = { MAX6900_REG_CENTURY_READ };
70
        struct i2c_msg msgs[4] = {
71
                {
72
                        .addr   = client->addr,
73
                        .flags  = 0, /* write */
74
                        .len    = sizeof(reg_burst_read),
75
                        .buf    = reg_burst_read
76
                },
77
                {
78
                        .addr   = client->addr,
79
                        .flags  = I2C_M_RD,
80
                        .len    = MAX6900_BURST_LEN,
81
                        .buf    = buf
82
                },
83
                {
84
                        .addr   = client->addr,
85
                        .flags  = 0, /* write */
86
                        .len    = sizeof(reg_century_read),
87
                        .buf    = reg_century_read
88
                },
89
                {
90
                        .addr   = client->addr,
91
                        .flags  = I2C_M_RD,
92
                        .len    = sizeof(buf[MAX6900_REG_CENTURY]),
93
                        .buf    = &buf[MAX6900_REG_CENTURY]
94
                }
95
        };
96
        int rc;
97
 
98
        rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
99
        if (rc != ARRAY_SIZE(msgs)) {
100
                dev_err(&client->dev, "%s: register read failed\n",
101
                        __FUNCTION__);
102
                return -EIO;
103
        }
104
        return 0;
105
}
106
 
107
static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
108
{
109
        u8 i2c_century_buf[1 + 1] = { MAX6900_REG_CENTURY_WRITE };
110
        struct i2c_msg century_msgs[1] = {
111
                {
112
                        .addr   = client->addr,
113
                        .flags  = 0, /* write */
114
                        .len    = sizeof(i2c_century_buf),
115
                        .buf    = i2c_century_buf
116
                }
117
        };
118
        u8 i2c_burst_buf[MAX6900_BURST_LEN + 1] = { MAX6900_REG_BURST_WRITE };
119
        struct i2c_msg burst_msgs[1] = {
120
                {
121
                        .addr   = client->addr,
122
                        .flags  = 0, /* write */
123
                        .len    = sizeof(i2c_burst_buf),
124
                        .buf    = i2c_burst_buf
125
                }
126
        };
127
        int rc;
128
 
129
        /*
130
         * We have to make separate calls to i2c_transfer because of
131
         * the need to delay after each write to the chip.  Also,
132
         * we write the century byte first, since we set the write-protect
133
         * bit as part of the burst write.
134
         */
135
        i2c_century_buf[1] = buf[MAX6900_REG_CENTURY];
136
        rc = i2c_transfer(client->adapter, century_msgs,
137
                          ARRAY_SIZE(century_msgs));
138
        if (rc != ARRAY_SIZE(century_msgs))
139
                goto write_failed;
140
        msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
141
 
142
        memcpy(&i2c_burst_buf[1], buf, MAX6900_BURST_LEN);
143
 
144
        rc = i2c_transfer(client->adapter, burst_msgs, ARRAY_SIZE(burst_msgs));
145
        if (rc != ARRAY_SIZE(burst_msgs))
146
                goto write_failed;
147
        msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
148
 
149
        return 0;
150
 
151
write_failed:
152
        dev_err(&client->dev, "%s: register write failed\n",
153
                __FUNCTION__);
154
        return -EIO;
155
}
156
 
157
static int max6900_i2c_validate_client(struct i2c_client *client)
158
{
159
        u8 regs[MAX6900_REG_LEN];
160
        u8 zero_mask[] = {
161
                0x80,   /* seconds */
162
                0x80,   /* minutes */
163
                0x40,   /* hours */
164
                0xc0,   /* day of month */
165
                0xe0,   /* month */
166
                0xf8,   /* day of week */
167
                0x00,   /* year */
168
                0x7f,   /* control */
169
        };
170
        int i;
171
        int rc;
172
        int reserved;
173
 
174
        reserved = i2c_smbus_read_byte_data(client, MAX6900_REG_RESERVED_READ);
175
        if (reserved != 0x07)
176
                return -ENODEV;
177
 
178
        rc = max6900_i2c_read_regs(client, regs);
179
        if (rc < 0)
180
                return rc;
181
 
182
        for (i = 0; i < ARRAY_SIZE(zero_mask); ++i) {
183
                if (regs[i] & zero_mask[i])
184
                        return -ENODEV;
185
        }
186
 
187
        return 0;
188
}
189
 
190
static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
191
{
192
        int rc;
193
        u8 regs[MAX6900_REG_LEN];
194
 
195
        rc = max6900_i2c_read_regs(client, regs);
196
        if (rc < 0)
197
                return rc;
198
 
199
        tm->tm_sec = BCD2BIN(regs[MAX6900_REG_SC]);
200
        tm->tm_min = BCD2BIN(regs[MAX6900_REG_MN]);
201
        tm->tm_hour = BCD2BIN(regs[MAX6900_REG_HR] & 0x3f);
202
        tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]);
203
        tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1;
204
        tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) +
205
                      BCD2BIN(regs[MAX6900_REG_CENTURY]) * 100 - 1900;
206
        tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]);
207
 
208
        return 0;
209
}
210
 
211
static int max6900_i2c_clear_write_protect(struct i2c_client *client)
212
{
213
        int rc;
214
        rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0);
215
        if (rc < 0) {
216
                dev_err(&client->dev, "%s: control register write failed\n",
217
                        __FUNCTION__);
218
                return -EIO;
219
        }
220
        return 0;
221
}
222
 
223
static int max6900_i2c_set_time(struct i2c_client *client,
224
                                struct rtc_time const *tm)
225
{
226
        u8 regs[MAX6900_REG_LEN];
227
        int rc;
228
 
229
        rc = max6900_i2c_clear_write_protect(client);
230
        if (rc < 0)
231
                return rc;
232
 
233
        regs[MAX6900_REG_SC] = BIN2BCD(tm->tm_sec);
234
        regs[MAX6900_REG_MN] = BIN2BCD(tm->tm_min);
235
        regs[MAX6900_REG_HR] = BIN2BCD(tm->tm_hour);
236
        regs[MAX6900_REG_DT] = BIN2BCD(tm->tm_mday);
237
        regs[MAX6900_REG_MO] = BIN2BCD(tm->tm_mon + 1);
238
        regs[MAX6900_REG_DW] = BIN2BCD(tm->tm_wday);
239
        regs[MAX6900_REG_YR] = BIN2BCD(tm->tm_year % 100);
240
        regs[MAX6900_REG_CENTURY] = BIN2BCD((tm->tm_year + 1900) / 100);
241
        /* set write protect */
242
        regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP;
243
 
244
        rc = max6900_i2c_write_regs(client, regs);
245
        if (rc < 0)
246
                return rc;
247
 
248
        return 0;
249
}
250
 
251
static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm)
252
{
253
        return max6900_i2c_read_time(to_i2c_client(dev), tm);
254
}
255
 
256
static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
257
{
258
        return max6900_i2c_set_time(to_i2c_client(dev), tm);
259
}
260
 
261
static int max6900_attach_adapter(struct i2c_adapter *adapter)
262
{
263
        return i2c_probe(adapter, &addr_data, max6900_probe);
264
}
265
 
266
static int max6900_detach_client(struct i2c_client *client)
267
{
268
        struct rtc_device *const rtc = i2c_get_clientdata(client);
269
 
270
        if (rtc)
271
                rtc_device_unregister(rtc);
272
 
273
        return i2c_detach_client(client);
274
}
275
 
276
static struct i2c_driver max6900_driver = {
277
        .driver         = {
278
                .name   = DRV_NAME,
279
        },
280
        .id             = I2C_DRIVERID_MAX6900,
281
        .attach_adapter = max6900_attach_adapter,
282
        .detach_client  = max6900_detach_client,
283
};
284
 
285
static const struct rtc_class_ops max6900_rtc_ops = {
286
        .read_time      = max6900_rtc_read_time,
287
        .set_time       = max6900_rtc_set_time,
288
};
289
 
290
static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind)
291
{
292
        int rc = 0;
293
        struct i2c_client *client = NULL;
294
        struct rtc_device *rtc = NULL;
295
 
296
        if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
297
                rc = -ENODEV;
298
                goto failout;
299
        }
300
 
301
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
302
        if (client == NULL) {
303
                rc = -ENOMEM;
304
                goto failout;
305
        }
306
 
307
        client->addr = addr;
308
        client->adapter = adapter;
309
        client->driver = &max6900_driver;
310
        strlcpy(client->name, DRV_NAME, I2C_NAME_SIZE);
311
 
312
        if (kind < 0) {
313
                rc = max6900_i2c_validate_client(client);
314
                if (rc < 0)
315
                        goto failout;
316
        }
317
 
318
        rc = i2c_attach_client(client);
319
        if (rc < 0)
320
                goto failout;
321
 
322
        dev_info(&client->dev,
323
                 "chip found, driver version " DRV_VERSION "\n");
324
 
325
        rtc = rtc_device_register(max6900_driver.driver.name,
326
                                  &client->dev,
327
                                  &max6900_rtc_ops, THIS_MODULE);
328
        if (IS_ERR(rtc)) {
329
                rc = PTR_ERR(rtc);
330
                goto failout_detach;
331
        }
332
 
333
        i2c_set_clientdata(client, rtc);
334
 
335
        return 0;
336
 
337
failout_detach:
338
        i2c_detach_client(client);
339
failout:
340
        kfree(client);
341
        return rc;
342
}
343
 
344
static int __init max6900_init(void)
345
{
346
        return i2c_add_driver(&max6900_driver);
347
}
348
 
349
static void __exit max6900_exit(void)
350
{
351
        i2c_del_driver(&max6900_driver);
352
}
353
 
354
MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
355
MODULE_LICENSE("GPL");
356
MODULE_VERSION(DRV_VERSION);
357
 
358
module_init(max6900_init);
359
module_exit(max6900_exit);

powered by: WebSVN 2.1.0

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