ASoC: TWL4030: Add functionalty to reset the registers
[deliverable/linux.git] / drivers / rtc / rtc-fm3130.c
CommitLineData
c6d8f400
SL
1/*
2 * rtc-fm3130.c - RTC driver for Ramtron FM3130 I2C chip.
3 *
4 * Copyright (C) 2008 Sergey Lapin
5 * Based on ds1307 driver by James Chapman and David Brownell
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/i2c.h>
14#include <linux/rtc.h>
15#include <linux/bcd.h>
16
17#define FM3130_RTC_CONTROL (0x0)
18#define FM3130_CAL_CONTROL (0x1)
19#define FM3130_RTC_SECONDS (0x2)
20#define FM3130_RTC_MINUTES (0x3)
21#define FM3130_RTC_HOURS (0x4)
22#define FM3130_RTC_DAY (0x5)
23#define FM3130_RTC_DATE (0x6)
24#define FM3130_RTC_MONTHS (0x7)
25#define FM3130_RTC_YEARS (0x8)
26
27#define FM3130_ALARM_SECONDS (0x9)
28#define FM3130_ALARM_MINUTES (0xa)
29#define FM3130_ALARM_HOURS (0xb)
30#define FM3130_ALARM_DATE (0xc)
31#define FM3130_ALARM_MONTHS (0xd)
32#define FM3130_ALARM_WP_CONTROL (0xe)
33
34#define FM3130_CAL_CONTROL_BIT_nOSCEN (1 << 7) /* Osciallator enabled */
35#define FM3130_RTC_CONTROL_BIT_LB (1 << 7) /* Low battery */
36#define FM3130_RTC_CONTROL_BIT_AF (1 << 6) /* Alarm flag */
37#define FM3130_RTC_CONTROL_BIT_CF (1 << 5) /* Century overflow */
38#define FM3130_RTC_CONTROL_BIT_POR (1 << 4) /* Power on reset */
39#define FM3130_RTC_CONTROL_BIT_AEN (1 << 3) /* Alarm enable */
40#define FM3130_RTC_CONTROL_BIT_CAL (1 << 2) /* Calibration mode */
41#define FM3130_RTC_CONTROL_BIT_WRITE (1 << 1) /* W=1 -> write mode W=0 normal */
42#define FM3130_RTC_CONTROL_BIT_READ (1 << 0) /* R=1 -> read mode R=0 normal */
43
44#define FM3130_CLOCK_REGS 7
45#define FM3130_ALARM_REGS 5
46
47struct fm3130 {
48 u8 reg_addr_time;
49 u8 reg_addr_alarm;
50 u8 regs[15];
51 struct i2c_msg msg[4];
52 struct i2c_client *client;
53 struct rtc_device *rtc;
54 int data_valid;
55 int alarm;
56};
57static const struct i2c_device_id fm3130_id[] = {
876550aa 58 { "fm3130", 0 },
c6d8f400
SL
59 { }
60};
61MODULE_DEVICE_TABLE(i2c, fm3130_id);
62
63#define FM3130_MODE_NORMAL 0
64#define FM3130_MODE_WRITE 1
65#define FM3130_MODE_READ 2
66
67static void fm3130_rtc_mode(struct device *dev, int mode)
68{
69 struct fm3130 *fm3130 = dev_get_drvdata(dev);
70
71 fm3130->regs[FM3130_RTC_CONTROL] =
72 i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL);
73 switch (mode) {
74 case FM3130_MODE_NORMAL:
75 fm3130->regs[FM3130_RTC_CONTROL] &=
76 ~(FM3130_RTC_CONTROL_BIT_WRITE |
77 FM3130_RTC_CONTROL_BIT_READ);
78 break;
79 case FM3130_MODE_WRITE:
80 fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_WRITE;
81 break;
82 case FM3130_MODE_READ:
83 fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_READ;
84 break;
85 default:
86 dev_dbg(dev, "invalid mode %d\n", mode);
87 break;
88 }
89 /* Checking for alarm */
90 if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) {
91 fm3130->alarm = 1;
92 fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF;
93 }
94 i2c_smbus_write_byte_data(fm3130->client,
95 FM3130_RTC_CONTROL, fm3130->regs[FM3130_RTC_CONTROL]);
96}
97
98static int fm3130_get_time(struct device *dev, struct rtc_time *t)
99{
100 struct fm3130 *fm3130 = dev_get_drvdata(dev);
101 int tmp;
102
103 if (!fm3130->data_valid) {
104 /* We have invalid data in RTC, probably due
105 to battery faults or other problems. Return EIO
106 for now, it will allow us to set data later insted
107 of error during probing which disables device */
108 return -EIO;
109 }
110 fm3130_rtc_mode(dev, FM3130_MODE_READ);
111
112 /* read the RTC date and time registers all at once */
113 tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent),
114 fm3130->msg, 2);
115 if (tmp != 2) {
116 dev_err(dev, "%s error %d\n", "read", tmp);
117 return -EIO;
118 }
119
120 fm3130_rtc_mode(dev, FM3130_MODE_NORMAL);
121
122 dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x"
123 "%02x %02x %02x %02x %02x %02x %02x\n",
124 "read",
125 fm3130->regs[0], fm3130->regs[1],
126 fm3130->regs[2], fm3130->regs[3],
127 fm3130->regs[4], fm3130->regs[5],
128 fm3130->regs[6], fm3130->regs[7],
129 fm3130->regs[8], fm3130->regs[9],
130 fm3130->regs[0xa], fm3130->regs[0xb],
131 fm3130->regs[0xc], fm3130->regs[0xd],
132 fm3130->regs[0xe]);
133
fe20ba70
AB
134 t->tm_sec = bcd2bin(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f);
135 t->tm_min = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f);
c6d8f400 136 tmp = fm3130->regs[FM3130_RTC_HOURS] & 0x3f;
fe20ba70
AB
137 t->tm_hour = bcd2bin(tmp);
138 t->tm_wday = bcd2bin(fm3130->regs[FM3130_RTC_DAY] & 0x07) - 1;
139 t->tm_mday = bcd2bin(fm3130->regs[FM3130_RTC_DATE] & 0x3f);
c6d8f400 140 tmp = fm3130->regs[FM3130_RTC_MONTHS] & 0x1f;
fe20ba70 141 t->tm_mon = bcd2bin(tmp) - 1;
c6d8f400
SL
142
143 /* assume 20YY not 19YY, and ignore CF bit */
fe20ba70 144 t->tm_year = bcd2bin(fm3130->regs[FM3130_RTC_YEARS]) + 100;
c6d8f400
SL
145
146 dev_dbg(dev, "%s secs=%d, mins=%d, "
147 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
148 "read", t->tm_sec, t->tm_min,
149 t->tm_hour, t->tm_mday,
150 t->tm_mon, t->tm_year, t->tm_wday);
151
152 /* initial clock setting can be undefined */
153 return rtc_valid_tm(t);
154}
155
156
157static int fm3130_set_time(struct device *dev, struct rtc_time *t)
158{
159 struct fm3130 *fm3130 = dev_get_drvdata(dev);
160 int tmp, i;
161 u8 *buf = fm3130->regs;
162
163 dev_dbg(dev, "%s secs=%d, mins=%d, "
164 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
165 "write", t->tm_sec, t->tm_min,
166 t->tm_hour, t->tm_mday,
167 t->tm_mon, t->tm_year, t->tm_wday);
168
169 /* first register addr */
fe20ba70
AB
170 buf[FM3130_RTC_SECONDS] = bin2bcd(t->tm_sec);
171 buf[FM3130_RTC_MINUTES] = bin2bcd(t->tm_min);
172 buf[FM3130_RTC_HOURS] = bin2bcd(t->tm_hour);
173 buf[FM3130_RTC_DAY] = bin2bcd(t->tm_wday + 1);
174 buf[FM3130_RTC_DATE] = bin2bcd(t->tm_mday);
175 buf[FM3130_RTC_MONTHS] = bin2bcd(t->tm_mon + 1);
c6d8f400
SL
176
177 /* assume 20YY not 19YY */
178 tmp = t->tm_year - 100;
fe20ba70 179 buf[FM3130_RTC_YEARS] = bin2bcd(tmp);
c6d8f400
SL
180
181 dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x"
182 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
183 "write", buf[0], buf[1], buf[2], buf[3],
184 buf[4], buf[5], buf[6], buf[7],
185 buf[8], buf[9], buf[0xa], buf[0xb],
186 buf[0xc], buf[0xd], buf[0xe]);
187
188 fm3130_rtc_mode(dev, FM3130_MODE_WRITE);
189
190 /* Writing time registers, we don't support multibyte transfers */
191 for (i = 0; i < FM3130_CLOCK_REGS; i++) {
192 i2c_smbus_write_byte_data(fm3130->client,
193 FM3130_RTC_SECONDS + i,
194 fm3130->regs[FM3130_RTC_SECONDS + i]);
195 }
196
197 fm3130_rtc_mode(dev, FM3130_MODE_NORMAL);
198
199 /* We assume here that data are valid once written */
200 if (!fm3130->data_valid)
201 fm3130->data_valid = 1;
202 return 0;
203}
204
205static int fm3130_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
206{
207 struct fm3130 *fm3130 = dev_get_drvdata(dev);
208 int tmp;
209 struct rtc_time *tm = &alrm->time;
210 /* read the RTC alarm registers all at once */
211 tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent),
212 &fm3130->msg[2], 2);
213 if (tmp != 2) {
214 dev_err(dev, "%s error %d\n", "read", tmp);
215 return -EIO;
216 }
217 dev_dbg(dev, "alarm read %02x %02x %02x %02x %02x\n",
218 fm3130->regs[FM3130_ALARM_SECONDS],
219 fm3130->regs[FM3130_ALARM_MINUTES],
220 fm3130->regs[FM3130_ALARM_HOURS],
221 fm3130->regs[FM3130_ALARM_DATE],
222 fm3130->regs[FM3130_ALARM_MONTHS]);
223
224
fe20ba70
AB
225 tm->tm_sec = bcd2bin(fm3130->regs[FM3130_ALARM_SECONDS] & 0x7F);
226 tm->tm_min = bcd2bin(fm3130->regs[FM3130_ALARM_MINUTES] & 0x7F);
227 tm->tm_hour = bcd2bin(fm3130->regs[FM3130_ALARM_HOURS] & 0x3F);
228 tm->tm_mday = bcd2bin(fm3130->regs[FM3130_ALARM_DATE] & 0x3F);
229 tm->tm_mon = bcd2bin(fm3130->regs[FM3130_ALARM_MONTHS] & 0x1F);
c6d8f400
SL
230 if (tm->tm_mon > 0)
231 tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */
232 dev_dbg(dev, "%s secs=%d, mins=%d, "
233 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
234 "read alarm", tm->tm_sec, tm->tm_min,
235 tm->tm_hour, tm->tm_mday,
236 tm->tm_mon, tm->tm_year, tm->tm_wday);
237
238 return 0;
239}
240
241static int fm3130_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
242{
243 struct fm3130 *fm3130 = dev_get_drvdata(dev);
244 struct rtc_time *tm = &alrm->time;
245 int i;
246
247 dev_dbg(dev, "%s secs=%d, mins=%d, "
248 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
249 "write alarm", tm->tm_sec, tm->tm_min,
250 tm->tm_hour, tm->tm_mday,
251 tm->tm_mon, tm->tm_year, tm->tm_wday);
252
253 if (tm->tm_sec != -1)
254 fm3130->regs[FM3130_ALARM_SECONDS] =
fe20ba70 255 bin2bcd(tm->tm_sec) | 0x80;
c6d8f400
SL
256
257 if (tm->tm_min != -1)
258 fm3130->regs[FM3130_ALARM_MINUTES] =
fe20ba70 259 bin2bcd(tm->tm_min) | 0x80;
c6d8f400
SL
260
261 if (tm->tm_hour != -1)
262 fm3130->regs[FM3130_ALARM_HOURS] =
fe20ba70 263 bin2bcd(tm->tm_hour) | 0x80;
c6d8f400
SL
264
265 if (tm->tm_mday != -1)
266 fm3130->regs[FM3130_ALARM_DATE] =
fe20ba70 267 bin2bcd(tm->tm_mday) | 0x80;
c6d8f400
SL
268
269 if (tm->tm_mon != -1)
270 fm3130->regs[FM3130_ALARM_MONTHS] =
fe20ba70 271 bin2bcd(tm->tm_mon + 1) | 0x80;
c6d8f400
SL
272
273 dev_dbg(dev, "alarm write %02x %02x %02x %02x %02x\n",
274 fm3130->regs[FM3130_ALARM_SECONDS],
275 fm3130->regs[FM3130_ALARM_MINUTES],
276 fm3130->regs[FM3130_ALARM_HOURS],
277 fm3130->regs[FM3130_ALARM_DATE],
278 fm3130->regs[FM3130_ALARM_MONTHS]);
279 /* Writing time registers, we don't support multibyte transfers */
280 for (i = 0; i < FM3130_ALARM_REGS; i++) {
281 i2c_smbus_write_byte_data(fm3130->client,
282 FM3130_ALARM_SECONDS + i,
283 fm3130->regs[FM3130_ALARM_SECONDS + i]);
284 }
285 fm3130->regs[FM3130_RTC_CONTROL] =
286 i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL);
287 /* Checking for alarm */
288 if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) {
289 fm3130->alarm = 1;
290 fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF;
291 }
292 if (alrm->enabled) {
293 i2c_smbus_write_byte_data(fm3130->client, FM3130_RTC_CONTROL,
294 (fm3130->regs[FM3130_RTC_CONTROL] &
295 ~(FM3130_RTC_CONTROL_BIT_CAL)) |
296 FM3130_RTC_CONTROL_BIT_AEN);
297 } else {
298 i2c_smbus_write_byte_data(fm3130->client, FM3130_RTC_CONTROL,
299 fm3130->regs[FM3130_RTC_CONTROL] &
300 ~(FM3130_RTC_CONTROL_BIT_AEN));
301 }
302 return 0;
303}
304
305static const struct rtc_class_ops fm3130_rtc_ops = {
306 .read_time = fm3130_get_time,
307 .set_time = fm3130_set_time,
308 .read_alarm = fm3130_read_alarm,
309 .set_alarm = fm3130_set_alarm,
310};
311
312static struct i2c_driver fm3130_driver;
313
314static int __devinit fm3130_probe(struct i2c_client *client,
315 const struct i2c_device_id *id)
316{
317 struct fm3130 *fm3130;
318 int err = -ENODEV;
319 int tmp;
320 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
321
322 if (!i2c_check_functionality(adapter,
323 I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
324 return -EIO;
325
326 fm3130 = kzalloc(sizeof(struct fm3130), GFP_KERNEL);
327
328 if (!fm3130)
329 return -ENOMEM;
330
331 fm3130->client = client;
332 i2c_set_clientdata(client, fm3130);
333 fm3130->reg_addr_time = FM3130_RTC_SECONDS;
334 fm3130->reg_addr_alarm = FM3130_ALARM_SECONDS;
335
336 /* Messages to read time */
337 fm3130->msg[0].addr = client->addr;
338 fm3130->msg[0].flags = 0;
339 fm3130->msg[0].len = 1;
340 fm3130->msg[0].buf = &fm3130->reg_addr_time;
341
342 fm3130->msg[1].addr = client->addr;
343 fm3130->msg[1].flags = I2C_M_RD;
344 fm3130->msg[1].len = FM3130_CLOCK_REGS;
345 fm3130->msg[1].buf = &fm3130->regs[FM3130_RTC_SECONDS];
346
347 /* Messages to read alarm */
348 fm3130->msg[2].addr = client->addr;
349 fm3130->msg[2].flags = 0;
350 fm3130->msg[2].len = 1;
351 fm3130->msg[2].buf = &fm3130->reg_addr_alarm;
352
353 fm3130->msg[3].addr = client->addr;
354 fm3130->msg[3].flags = I2C_M_RD;
355 fm3130->msg[3].len = FM3130_ALARM_REGS;
356 fm3130->msg[3].buf = &fm3130->regs[FM3130_ALARM_SECONDS];
357
358 fm3130->data_valid = 0;
359
360 tmp = i2c_transfer(adapter, fm3130->msg, 4);
361 if (tmp != 4) {
362 pr_debug("read error %d\n", tmp);
363 err = -EIO;
364 goto exit_free;
365 }
366
367 fm3130->regs[FM3130_RTC_CONTROL] =
368 i2c_smbus_read_byte_data(client, FM3130_RTC_CONTROL);
369 fm3130->regs[FM3130_CAL_CONTROL] =
370 i2c_smbus_read_byte_data(client, FM3130_CAL_CONTROL);
371
372 /* Checking for alarm */
373 if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) {
374 fm3130->alarm = 1;
375 fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF;
376 }
377
378 /* Disabling calibration mode */
f4b51628 379 if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_CAL) {
c6d8f400
SL
380 i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL,
381 fm3130->regs[FM3130_RTC_CONTROL] &
382 ~(FM3130_RTC_CONTROL_BIT_CAL));
383 dev_warn(&client->dev, "Disabling calibration mode!\n");
f4b51628 384 }
c6d8f400
SL
385
386 /* Disabling read and write modes */
387 if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_WRITE ||
f4b51628 388 fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_READ) {
c6d8f400
SL
389 i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL,
390 fm3130->regs[FM3130_RTC_CONTROL] &
391 ~(FM3130_RTC_CONTROL_BIT_READ |
392 FM3130_RTC_CONTROL_BIT_WRITE));
393 dev_warn(&client->dev, "Disabling READ or WRITE mode!\n");
f4b51628 394 }
c6d8f400
SL
395
396 /* oscillator off? turn it on, so clock can tick. */
397 if (fm3130->regs[FM3130_CAL_CONTROL] & FM3130_CAL_CONTROL_BIT_nOSCEN)
398 i2c_smbus_write_byte_data(client, FM3130_CAL_CONTROL,
399 fm3130->regs[FM3130_CAL_CONTROL] &
400 ~(FM3130_CAL_CONTROL_BIT_nOSCEN));
401
402 /* oscillator fault? clear flag, and warn */
403 if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_LB)
404 dev_warn(&client->dev, "Low battery!\n");
405
406 /* oscillator fault? clear flag, and warn */
407 if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_POR) {
408 i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL,
409 fm3130->regs[FM3130_RTC_CONTROL] &
410 ~FM3130_RTC_CONTROL_BIT_POR);
411 dev_warn(&client->dev, "SET TIME!\n");
412 }
413 /* ACS is controlled by alarm */
414 i2c_smbus_write_byte_data(client, FM3130_ALARM_WP_CONTROL, 0x80);
415
416 /* TODO */
417 /* TODO need to sanity check alarm */
418 tmp = fm3130->regs[FM3130_RTC_SECONDS];
fe20ba70 419 tmp = bcd2bin(tmp & 0x7f);
c6d8f400
SL
420 if (tmp > 60)
421 goto exit_bad;
fe20ba70 422 tmp = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f);
c6d8f400
SL
423 if (tmp > 60)
424 goto exit_bad;
425
fe20ba70 426 tmp = bcd2bin(fm3130->regs[FM3130_RTC_DATE] & 0x3f);
c6d8f400
SL
427 if (tmp == 0 || tmp > 31)
428 goto exit_bad;
429
fe20ba70 430 tmp = bcd2bin(fm3130->regs[FM3130_RTC_MONTHS] & 0x1f);
c6d8f400
SL
431 if (tmp == 0 || tmp > 12)
432 goto exit_bad;
433
434 tmp = fm3130->regs[FM3130_RTC_HOURS];
435
436 fm3130->data_valid = 1;
437
438exit_bad:
439 if (!fm3130->data_valid)
440 dev_dbg(&client->dev,
441 "%s: %02x %02x %02x %02x %02x %02x %02x %02x"
442 "%02x %02x %02x %02x %02x %02x %02x\n",
443 "bogus registers",
444 fm3130->regs[0], fm3130->regs[1],
445 fm3130->regs[2], fm3130->regs[3],
446 fm3130->regs[4], fm3130->regs[5],
447 fm3130->regs[6], fm3130->regs[7],
448 fm3130->regs[8], fm3130->regs[9],
449 fm3130->regs[0xa], fm3130->regs[0xb],
450 fm3130->regs[0xc], fm3130->regs[0xd],
451 fm3130->regs[0xe]);
452
453 /* We won't bail out here because we just got invalid data.
454 Time setting from u-boot doesn't work anyway */
455 fm3130->rtc = rtc_device_register(client->name, &client->dev,
456 &fm3130_rtc_ops, THIS_MODULE);
457 if (IS_ERR(fm3130->rtc)) {
458 err = PTR_ERR(fm3130->rtc);
459 dev_err(&client->dev,
460 "unable to register the class device\n");
461 goto exit_free;
462 }
463 return 0;
464exit_free:
465 kfree(fm3130);
466 return err;
467}
468
469static int __devexit fm3130_remove(struct i2c_client *client)
470{
471 struct fm3130 *fm3130 = i2c_get_clientdata(client);
472
473 rtc_device_unregister(fm3130->rtc);
474 kfree(fm3130);
475 return 0;
476}
477
478static struct i2c_driver fm3130_driver = {
479 .driver = {
480 .name = "rtc-fm3130",
481 .owner = THIS_MODULE,
482 },
483 .probe = fm3130_probe,
484 .remove = __devexit_p(fm3130_remove),
485 .id_table = fm3130_id,
486};
487
488static int __init fm3130_init(void)
489{
490 return i2c_add_driver(&fm3130_driver);
491}
492module_init(fm3130_init);
493
494static void __exit fm3130_exit(void)
495{
496 i2c_del_driver(&fm3130_driver);
497}
498module_exit(fm3130_exit);
499
500MODULE_DESCRIPTION("RTC driver for FM3130");
501MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>");
502MODULE_LICENSE("GPL");
503
This page took 0.198962 seconds and 5 git commands to generate.