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