1 /*drivers/rtc/rtc-s35392a.h - driver for s35392a
\r
3 * Copyright (C) 2010 ROCKCHIP, Inc.
\r
5 * This software is licensed under the terms of the GNU General Public
\r
6 * License version 2, as published by the Free Software Foundation, and
\r
7 * may be copied, distributed, and modified under those terms.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
15 #include <linux/module.h>
\r
16 #include <linux/rtc.h>
\r
17 #include <linux/i2c.h>
\r
18 #include <linux/bitrev.h>
\r
19 #include <linux/bcd.h>
\r
20 #include <linux/slab.h>
\r
21 #include <linux/delay.h>
\r
22 #include <mach/gpio.h>
\r
23 #include <mach/board.h>
\r
24 #include "rtc-s35392a.h"
\r
26 #define RTC_RATE 100 * 1000
\r
27 #define S35392_TEST 0
\r
30 #define DBG(x...) printk(x)
\r
36 struct i2c_client *client;
\r
37 struct rtc_device *rtc;
\r
39 struct work_struct work;
\r
44 static int s35392a_set_reg(struct s35392a *s35392a, const char reg, char *buf, int len)
\r
46 struct i2c_client *client = s35392a->client;
\r
51 msg.addr = client->addr | reg;
\r
52 msg.flags = client->flags;
\r
55 msg.scl_rate = RTC_RATE;
\r
57 ret = i2c_transfer(client->adapter,&msg,1);
\r
59 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
64 static int s35392a_get_reg(struct s35392a *s35392a, const char reg, char *buf, int len)
\r
66 struct i2c_client *client = s35392a->client;
\r
70 msg.addr = client->addr | reg;
\r
71 msg.flags = client->flags | I2C_M_RD;
\r
74 msg.scl_rate = RTC_RATE;
\r
76 ret = i2c_transfer(client->adapter,&msg,1);
\r
82 static int s35392_set_reg(struct s35392a *s35392a, const char reg, char *buf, int len,unsigned char head)
\r
84 struct i2c_client *client = s35392a->client;
\r
89 msg.addr = client->addr | reg | (head << 3);
\r
90 msg.flags = client->flags;
\r
93 msg.scl_rate = RTC_RATE;
\r
94 ret = i2c_transfer(client->adapter,&msg,1);
\r
99 static int s35392_get_reg(struct s35392a *s35392a, const char reg, char *buf, int len,unsigned char head)
\r
101 struct i2c_client *client = s35392a->client;
\r
102 struct i2c_msg msg;
\r
105 msg.addr = client->addr | reg |(head << 3);
\r
106 msg.flags = client->flags | I2C_M_RD;
\r
109 msg.scl_rate = RTC_RATE;
\r
111 ret = i2c_transfer(client->adapter,&msg,1);
\r
115 static int s35392a_test(struct s35392a *s35392a)
\r
123 if (s35392_get_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf),6) < 0)
\r
125 if (!(buf[0] & (S35392A_FLAG_POC | S35392A_FLAG_BLD)))
\r
128 buf[0] |= (S35392A_FLAG_RESET | S35392A_FLAG_24H);
\r
130 s35392_set_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf),6);
\r
133 s35392_get_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf),6);
\r
139 static int s35392a_init(struct s35392a *s35392a)
\r
143 s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf));
\r
144 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, buf, sizeof(buf));
\r
145 s35392a_get_reg(s35392a, S35392A_CMD_INT1, buf, sizeof(buf));
\r
146 s35392a_get_reg(s35392a, S35392A_CMD_INT2, buf, sizeof(buf));
\r
147 s35392a_get_reg(s35392a, S35392A_CMD_CHECK, buf, sizeof(buf));
\r
148 s35392a_get_reg(s35392a, S35392A_CMD_FREE, buf, sizeof(buf));
\r
150 buf[0] |= (S35392A_FLAG_RESET | S35392A_FLAG_24H);
\r
152 return s35392a_set_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf));
\r
157 static char s35392a_hr2reg(struct s35392a *s35392a, int hour)
\r
159 if (s35392a->twentyfourhour)
\r
160 return bin2bcd(hour);
\r
163 return bin2bcd(hour);
\r
165 return 0x40 | bin2bcd(hour - 12);
\r
168 static int s35392a_reg2hr(struct s35392a *s35392a, char reg)
\r
172 if (s35392a->twentyfourhour)
\r
173 return bcd2bin(reg & 0x3f);
\r
175 hour = bcd2bin(reg & 0x3f);
\r
182 static char s35392a_hour2reg(struct s35392a *s35392a, int hour)
\r
184 if (s35392a->twentyfourhour)
\r
187 return 0x80 | bin2bcd(hour) ;
\r
189 return 0xc0| bin2bcd(hour) ;
\r
194 return 0x80 | bin2bcd(hour) ;
\r
196 return 0xc0 | bin2bcd(hour - 12);
\r
201 static int s35392a_set_datetime(struct i2c_client *client, struct rtc_time *tm)
\r
203 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
207 DBG("%s: tm is secs=%d, mins=%d, hours=%d mday=%d, "
\r
208 "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec,
\r
209 tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year,
\r
212 buf[S35392A_BYTE_YEAR] = bin2bcd(tm->tm_year - 100);
\r
213 buf[S35392A_BYTE_MONTH] = bin2bcd(tm->tm_mon + 1);
\r
214 buf[S35392A_BYTE_DAY] = bin2bcd(tm->tm_mday);
\r
215 buf[S35392A_BYTE_WDAY] = bin2bcd(tm->tm_wday);
\r
216 buf[S35392A_BYTE_HOURS] = s35392a_hr2reg(s35392a, tm->tm_hour);
\r
217 buf[S35392A_BYTE_MINS] = bin2bcd(tm->tm_min);
\r
218 buf[S35392A_BYTE_SECS] = bin2bcd(tm->tm_sec);
\r
220 /* This chip expects the bits of each byte to be in reverse order */
\r
222 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
223 for (i = 0; i < 7; ++i)
\r
224 buf[i] = bitrev8(buf[i]);
\r
226 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
227 err = s35392a_set_reg(s35392a, S35392A_CMD_TIME1, buf, sizeof(buf));
\r
232 static int s35392a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
\r
234 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
238 err = s35392a_get_reg(s35392a, S35392A_CMD_TIME1, buf, sizeof(buf));
\r
242 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
243 /* This chip returns the bits of each byte in reverse order */
\r
244 for (i = 0; i < 7; ++i)
\r
245 buf[i] = bitrev8(buf[i]);
\r
247 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
248 tm->tm_sec = bcd2bin(buf[S35392A_BYTE_SECS]);
\r
249 tm->tm_min = bcd2bin(buf[S35392A_BYTE_MINS]);
\r
250 tm->tm_hour = s35392a_reg2hr(s35392a, buf[S35392A_BYTE_HOURS]);
\r
251 tm->tm_wday = bcd2bin(buf[S35392A_BYTE_WDAY]);
\r
252 tm->tm_mday = bcd2bin(buf[S35392A_BYTE_DAY]);
\r
253 tm->tm_mon = bcd2bin(buf[S35392A_BYTE_MONTH]) - 1;
\r
254 tm->tm_year = bcd2bin(buf[S35392A_BYTE_YEAR]) + 100;
\r
255 //tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
\r
257 DBG( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, "
\r
258 "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec,
\r
259 tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year,
\r
262 return rtc_valid_tm(tm);
\r
264 static int s35392a_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *tm)
\r
266 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
270 DBG("%s:%d\n",__FUNCTION__,__LINE__);
\r
271 err = s35392a_get_reg(s35392a, S35392A_CMD_INT2, buf, sizeof(buf));
\r
275 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
276 for(i = 0;i < 3;++i)
\r
277 buf[i] = bitrev8(buf[i]);
\r
279 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
280 tm->time.tm_wday = -1;
\r
281 tm->time.tm_hour = -1;
\r
282 tm->time.tm_min = -1;
\r
284 if(buf[S35392A_ALARM_WDAYS] & S35392A_ALARM_ENABLE )
\r
285 tm->time.tm_wday = bcd2bin(buf[S35392A_ALARM_WDAYS] & S35392A_ALARM_DISABLE) ;
\r
287 if(buf[S35392A_ALARM_HOURS] & S35392A_ALARM_ENABLE)
\r
288 tm->time.tm_hour = s35392a_reg2hr(s35392a, buf[S35392A_ALARM_HOURS]);
\r
290 if(buf[S35392A_ALARM_MINS] & S35392A_ALARM_ENABLE)
\r
291 tm->time.tm_min = bcd2bin(buf[S35392A_ALARM_MINS] & S35392A_ALARM_DISABLE) ;
\r
294 tm->time.tm_year = -1;
\r
295 tm->time.tm_mon = -1;
\r
296 tm->time.tm_mday = -1;
\r
297 tm->time.tm_yday = -1;
\r
298 tm->time.tm_sec = -1;
\r
300 DBG( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, "
\r
301 "mon=%d, year=%d, wday=%d\n", __func__, tm->time.tm_sec,
\r
302 tm->time.tm_min, tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_mon, tm->time.tm_year,
\r
304 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
305 tm->enabled = ((data & S35392A_MASK_INT2) == S35392A_INT2_ENABLE);
\r
306 s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);
\r
307 tm->pending = !!(data & S35392A_FLAG_INT2);
\r
309 DBG("%s:%d\n",__FUNCTION__,__LINE__);
\r
313 static int s35392a_i2c_set_alarm(struct i2c_client *client, struct rtc_wkalrm *tm)
\r
315 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
319 DBG("%s:%d\n",__FUNCTION__,__LINE__);
\r
320 DBG( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, "
\r
321 "mon=%d, year=%d, wday=%d\n", __func__, tm->time.tm_sec,
\r
322 tm->time.tm_min, tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_mon, tm->time.tm_year,
\r
325 buf[S35392A_ALARM_WDAYS] = tm->time.tm_wday>= 0 ?
\r
326 (bin2bcd(tm->time.tm_wday) |S35392A_ALARM_ENABLE) : 0;
\r
327 buf[S35392A_ALARM_WDAYS]=0;
\r
328 buf[S35392A_ALARM_HOURS] = tm->time.tm_hour >=0 ?
\r
329 s35392a_hour2reg(s35392a, tm->time.tm_hour) : 0;
\r
330 buf[S35392A_ALARM_MINS] = tm->time.tm_min >= 0?
\r
331 bin2bcd(tm->time.tm_min) | S35392A_ALARM_ENABLE:0;
\r
333 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
334 for(i = 0;i < 3;++i)
\r
335 buf[i] = bitrev8(buf[i]);
\r
337 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
341 s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
342 s35392a_set_reg(s35392a, S35392A_CMD_INT2, &data, 1);
\r
344 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
345 //data = (data |S35392A_FLAG_INT2AE) & 0x2;
\r
347 s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
348 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
349 printk("data = 0x%x\n",data);
\r
350 err = s35392a_set_reg(s35392a, S35392A_CMD_INT2, buf, sizeof(buf));
\r
355 //s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
356 //data &= ~S35392A_FLAG_INT1AE;
\r
357 //s35392a_set_reg( s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
362 static int s35392a_i2c_read_alarm0(struct i2c_client *client, struct rtc_wkalrm *tm)
\r
364 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
368 DBG("%s:%d\n",__FUNCTION__,__LINE__);
\r
369 err = s35392a_get_reg(s35392a, S35392A_CMD_INT1, buf, sizeof(buf));
\r
373 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
374 for(i = 0;i < 3;++i)
\r
375 buf[i] = bitrev8(buf[i]);
\r
377 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
378 tm->time.tm_wday = -1;
\r
379 tm->time.tm_hour = -1;
\r
380 tm->time.tm_min = -1;
\r
382 if(buf[S35392A_ALARM_WDAYS] & S35392A_ALARM_ENABLE )
\r
383 tm->time.tm_wday = bcd2bin(buf[S35392A_ALARM_WDAYS] & S35392A_ALARM_DISABLE) ;
\r
385 if(buf[S35392A_ALARM_HOURS] & S35392A_ALARM_ENABLE)
\r
386 tm->time.tm_hour = s35392a_reg2hr(s35392a, buf[S35392A_ALARM_HOURS]);
\r
388 if(buf[S35392A_ALARM_MINS] & S35392A_ALARM_ENABLE)
\r
389 tm->time.tm_min = bcd2bin(buf[S35392A_ALARM_MINS] & S35392A_ALARM_DISABLE) ;
\r
392 tm->time.tm_year = -1;
\r
393 tm->time.tm_mon = -1;
\r
394 tm->time.tm_mday = -1;
\r
395 tm->time.tm_yday = -1;
\r
396 tm->time.tm_sec = -1;
\r
398 DBG( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, "
\r
399 "mon=%d, year=%d, wday=%d\n", __func__, tm->time.tm_sec,
\r
400 tm->time.tm_min, tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_mon, tm->time.tm_year,
\r
402 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
403 tm->enabled = ((data & S35392A_MASK_INT1) == S35392A_INT1_ENABLE);
\r
404 s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);
\r
405 tm->pending = !!(data & S35392A_FLAG_INT1);
\r
407 DBG("%s:%d\n",__FUNCTION__,__LINE__);
\r
411 static int s35392a_i2c_set_alarm0(struct i2c_client *client, struct rtc_wkalrm *tm)
\r
413 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
417 DBG("%s:%d\n",__FUNCTION__,__LINE__);
\r
418 DBG( "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, "
\r
419 "mon=%d, year=%d, wday=%d\n", __func__, tm->time.tm_sec,
\r
420 tm->time.tm_min, tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_mon, tm->time.tm_year,
\r
423 //buf[S35392A_ALARM_WDAYS] = tm->time.tm_wday>= 0 ?
\r
424 // (bin2bcd(tm->time.tm_wday) |S35392A_ALARM_ENABLE) : 0;
\r
425 buf[S35392A_ALARM_WDAYS]=0;
\r
426 buf[S35392A_ALARM_HOURS] = tm->time.tm_hour >=0 ?
\r
427 s35392a_hour2reg(s35392a, tm->time.tm_hour) : 0;
\r
428 buf[S35392A_ALARM_MINS] = tm->time.tm_min >= 0?
\r
429 bin2bcd(tm->time.tm_min) | S35392A_ALARM_ENABLE:0;
\r
431 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
432 for(i = 0;i < 3;++i)
\r
433 buf[i] = bitrev8(buf[i]);
\r
435 printk("buf[%d]=0x%x\n",i,buf[i]);
\r
439 s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
440 s35392a_set_reg(s35392a, S35392A_CMD_INT2, &data, 1);
\r
442 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
443 //ta = (data |S35392A_FLAG_INT1AE) & 0x20;
\r
445 s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
446 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
447 printk("data = 0x%x\n",data);
\r
448 err = s35392a_set_reg(s35392a, S35392A_CMD_INT1, buf, sizeof(buf));
\r
453 //s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
454 //data &= ~S35392A_FLAG_INT1AE;
\r
455 //s35392a_set_reg( s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
460 static void s35392a_alarm_test(struct i2c_client *client ,struct rtc_time rtc_alarm_rtc_time)
\r
462 struct rtc_wkalrm rtc_alarm,tm;
\r
464 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
465 DBG("%s:%d\n",__FUNCTION__,__LINE__);
\r
467 rtc_alarm.time.tm_sec = rtc_alarm_rtc_time.tm_sec;
\r
468 rtc_alarm.time.tm_min = (rtc_alarm_rtc_time.tm_min + 1) % 60;
\r
469 if((rtc_alarm.time.tm_min + 2)/60 > 0)
\r
470 rtc_alarm.time.tm_hour = rtc_alarm_rtc_time.tm_hour+1;
\r
472 rtc_alarm.time.tm_hour = rtc_alarm_rtc_time.tm_hour;
\r
473 if(rtc_alarm.time.tm_hour >24)
\r
474 rtc_alarm.time.tm_hour =24;
\r
475 rtc_alarm.time.tm_mday = rtc_alarm_rtc_time.tm_mday;
\r
476 rtc_alarm.time.tm_mon = rtc_alarm_rtc_time.tm_mon;
\r
477 rtc_alarm.time.tm_year = rtc_alarm_rtc_time.tm_year;
\r
478 rtc_alarm.time.tm_wday = rtc_alarm_rtc_time.tm_wday;
\r
479 rtc_alarm.time.tm_yday = rtc_alarm_rtc_time.tm_yday;
\r
480 rtc_alarm.enabled = 1;
\r
481 DBG("set alarm - rtc %02d:%02d:%02d %02d/%02d/%04d week=%02d\n",
\r
482 rtc_alarm.time.tm_hour, rtc_alarm.time.tm_min,
\r
483 rtc_alarm.time.tm_sec, rtc_alarm.time.tm_mon + 1,
\r
484 rtc_alarm.time.tm_mday, rtc_alarm.time.tm_year + 1900,rtc_alarm.time.tm_wday);
\r
485 s35392a_i2c_set_alarm(client,&rtc_alarm);
\r
486 data = s35392a_i2c_read_alarm(client,&tm);
\r
487 DBG("set alarm - rtc %02d:%02d:%02d %02d/%02d/%04d week=%02d\n",
\r
488 tm.time.tm_hour, tm.time.tm_min,
\r
489 tm.time.tm_sec, tm.time.tm_mon + 1,
\r
490 tm.time.tm_mday, tm.time.tm_year + 1900,tm.time.tm_wday);
\r
492 DBG("------------------first-------------------------0x%0x, 0x%0x\n",data, data&S35392A_FLAG_INT2);
\r
496 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
497 DBG("-----------------------------------------------0x%0x\n",data);
\r
498 s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);
\r
499 DBG("-----------------------------------------------0x%0x\n",data);
\r
500 }while((data & S35392A_FLAG_INT2) == 0);
\r
503 s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);
\r
504 DBG("--------------------last-------------------------0x%0x\n",data);
\r
506 s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
507 s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);
\r
510 static void s35392a_alarm_test0(struct i2c_client *client ,struct rtc_time rtc_alarm_rtc_time)
\r
512 struct rtc_wkalrm rtc_alarm,tm;
\r
514 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
515 DBG("%s:%d\n",__FUNCTION__,__LINE__);
\r
517 rtc_alarm.time.tm_sec = rtc_alarm_rtc_time.tm_sec;
\r
518 rtc_alarm.time.tm_min = (rtc_alarm_rtc_time.tm_min + 3) % 60;
\r
519 if((rtc_alarm.time.tm_min + 3)/60 > 0)
\r
520 rtc_alarm.time.tm_hour = rtc_alarm_rtc_time.tm_hour+1;
\r
522 rtc_alarm.time.tm_hour = rtc_alarm_rtc_time.tm_hour;
\r
523 if(rtc_alarm.time.tm_hour >24)
\r
524 rtc_alarm.time.tm_hour =24;
\r
525 rtc_alarm.time.tm_mday = rtc_alarm_rtc_time.tm_mday;
\r
526 rtc_alarm.time.tm_mon = rtc_alarm_rtc_time.tm_mon;
\r
527 rtc_alarm.time.tm_year = rtc_alarm_rtc_time.tm_year;
\r
528 rtc_alarm.time.tm_wday = rtc_alarm_rtc_time.tm_wday;
\r
529 rtc_alarm.time.tm_yday = rtc_alarm_rtc_time.tm_yday;
\r
530 rtc_alarm.enabled = 1;
\r
531 DBG("set alarm - rtc %02d:%02d:%02d %02d/%02d/%04d week=%02d\n",
\r
532 rtc_alarm.time.tm_hour, rtc_alarm.time.tm_min,
\r
533 rtc_alarm.time.tm_sec, rtc_alarm.time.tm_mon + 1,
\r
534 rtc_alarm.time.tm_mday, rtc_alarm.time.tm_year + 1900,rtc_alarm.time.tm_wday);
\r
535 s35392a_i2c_set_alarm0(client,&rtc_alarm);
\r
536 data = s35392a_i2c_read_alarm0(client,&tm);
\r
537 DBG("set alarm - rtc %02d:%02d:%02d %02d/%02d/%04d week=%02d\n",
\r
538 tm.time.tm_hour, tm.time.tm_min,
\r
539 tm.time.tm_sec, tm.time.tm_mon + 1,
\r
540 tm.time.tm_mday, tm.time.tm_year + 1900,tm.time.tm_wday);
\r
542 DBG("------------------first-------------------------0x%0x, 0x%0x\n",data, data&S35392A_FLAG_INT1);
\r
546 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
547 DBG("-----------------------------------------------0x%0x\n",data);
\r
548 s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);
\r
549 DBG("-----------------------------------------------0x%0x\n",data);
\r
551 }while((data & S35392A_FLAG_INT1) == 0);
\r
553 s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);
\r
554 DBG("--------------------last-------------------------0x%0x\n",data);
\r
556 s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
557 s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);
\r
561 static int s35392a_set_init_time(struct s35392a *s35392a)
\r
563 struct rtc_time *tm;
\r
564 struct i2c_client *client = s35392a->client;
\r
572 s35392a_set_datetime(client, tm);
\r
575 static int s35392a_reset(struct s35392a *s35392a)
\r
579 if (s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf)) < 0)
\r
581 if (!(buf[0] & (S35392A_FLAG_POC | S35392A_FLAG_BLD))) {
\r
583 s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, buf, 1);
\r
584 s35392a_set_reg(s35392a, S35392A_CMD_INT2, buf, 1);
\r
588 buf[0] |= (S35392A_FLAG_RESET | S35392A_FLAG_24H);
\r
590 s35392a_set_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf));
\r
592 //s35392a_set_init_time( s35392a);
\r
596 static int s35392a_disable_test_mode(struct s35392a *s35392a)
\r
600 if (s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, buf, sizeof(buf)) < 0)
\r
603 if (!(buf[0] & S35392A_FLAG_TEST))
\r
606 buf[0] &= ~S35392A_FLAG_TEST;
\r
607 return s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, buf, sizeof(buf));
\r
609 static int s35392a_rtc_read_time(struct device *dev, struct rtc_time *tm)
\r
611 return s35392a_get_datetime(to_i2c_client(dev), tm);
\r
614 static int s35392a_rtc_set_time(struct device *dev, struct rtc_time *tm)
\r
616 return s35392a_set_datetime(to_i2c_client(dev), tm);
\r
618 static int s35392a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
\r
620 return s35392a_i2c_read_alarm(to_i2c_client(dev),tm);
\r
622 static int s35392a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
\r
624 return s35392a_i2c_set_alarm(to_i2c_client(dev),tm);
\r
627 static int s35392a_i2c_open_alarm(struct i2c_client *client )
\r
630 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
631 DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
\r
632 s35392a_get_reg( s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
633 data = (data |S35392A_FLAG_INT2AE) & 0x02;
\r
634 s35392a_set_reg( s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
635 DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
\r
638 static int s35392a_i2c_close_alarm(struct i2c_client *client )
\r
641 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
642 DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
\r
643 s35392a_get_reg( s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
644 data &= ~S35392A_FLAG_INT2AE;
\r
645 s35392a_set_reg( s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
646 DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
\r
650 static int s35392a_rtc_ioctl(struct device *dev,unsigned int cmd,unsigned long arg)
\r
652 struct i2c_client *client = to_i2c_client(dev);
\r
653 DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
\r
657 if(s35392a_i2c_close_alarm(client) < 0)
\r
661 if(s35392a_i2c_open_alarm(client) < 0)
\r
665 return -ENOIOCTLCMD;
\r
671 static int s35392a_rtc_proc(struct device *dev, unsigned int cmd, unsigned long arg)
\r
676 static const struct rtc_class_ops s35392a_rtc_ops = {
\r
677 .read_time = s35392a_rtc_read_time,
\r
678 .set_time = s35392a_rtc_set_time,
\r
679 .read_alarm = s35392a_rtc_read_alarm,
\r
680 .set_alarm = s35392a_rtc_set_alarm,
\r
681 .ioctl = s35392a_rtc_ioctl,
\r
682 .proc = s35392a_rtc_proc
\r
687 #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
\r
688 static ssize_t s35392a_sysfs_show_flags(struct device *dev,
\r
689 struct device_attribute *attr, char *buf)
\r
691 DBG("\n@@@@@@@@@@@s35392a_sysfs_show_flags@@@@@@@@@@@@@\n");
\r
696 static DEVICE_ATTR(flags, S_IRUGO, s35392a_sysfs_show_flags, NULL);
\r
698 static ssize_t s35392a_sysfs_show_sqwfreq(struct device *dev,
\r
699 struct device_attribute *attr, char *buf)
\r
701 DBG("\n@@@@@@@@@@@ s35392a_sysfs_show_sqwfreq@@@@@@@@@@@@@\n");
\r
702 struct i2c_client *client = to_i2c_client(dev);
\r
705 static ssize_t s35392a_sysfs_set_sqwfreq(struct device *dev,
\r
706 struct device_attribute *attr,
\r
707 const char *buf, size_t count)
\r
709 DBG("\n@@@@@@@@@@@s35392a_sysfs_set_sqwfreq@@@@@@@@@@@@@\n");
\r
713 static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR,
\r
714 s35392a_sysfs_show_sqwfreq, s35392a_sysfs_set_sqwfreq);
\r
716 static struct attribute *attrs[] = {
\r
717 &dev_attr_flags.attr,
\r
718 &dev_attr_sqwfreq.attr,
\r
721 static struct attribute_group attr_group = {
\r
724 static int s35392a_sysfs_register(struct device *dev)
\r
726 DBG("\n@@@@@@@@@@@s35392a_sysfs_register@@@@@@@@@@@@@\n");
\r
727 return sysfs_create_group(&dev->kobj, &attr_group);
\r
731 static int s35392a_sysfs_register(struct device *dev)
\r
733 DBG("\n@@@@@@@@@@@s35392a_sysfs_register@@@@@@@@@@@@@\n");
\r
739 static struct i2c_driver s35392a_driver;
\r
741 static void s35392a_work_func(struct work_struct *work)
\r
743 struct s35392a *s35392a = container_of(work, struct s35392a, work);
\r
744 struct i2c_client *client = s35392a->client;
\r
746 printk("\n@@@@@@@@@@@rtc_wakeup_irq@@@@@@@@@@@@@\n");
\r
749 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
751 s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
752 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);
\r
754 printk("\n@@@@@@@@@@@rtc_wakeup_irq@@@@@@@@@@@@@\n");
\r
756 enable_irq(client->irq);
\r
759 static void s35392a_wakeup_irq(int irq, void *dev_id)
\r
761 struct s35392a *s35392a = (struct s35392a *)dev_id;
\r
763 disable_irq_nosync(irq);
\r
764 schedule_work(&s35392a->work);
\r
767 static int s35392a_probe(struct i2c_client *client,
\r
768 const struct i2c_device_id *id)
\r
770 struct rk2818_rtc_platform_data *pdata = client->dev.platform_data;
\r
773 struct s35392a *s35392a;
\r
774 struct rtc_time tm;
\r
777 printk("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
\r
778 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
\r
783 s35392a = kzalloc(sizeof(struct s35392a), GFP_KERNEL);
\r
789 s35392a->client = client;
\r
790 i2c_set_clientdata(client, s35392a);
\r
792 //s35392a_init(s35392a);
\r
793 err = s35392a_reset(s35392a);
\r
795 dev_err(&client->dev, "error resetting chip\n");
\r
799 err = s35392a_disable_test_mode(s35392a);
\r
801 dev_err(&client->dev, "error disabling test mode\n");
\r
805 err = s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf));
\r
807 dev_err(&client->dev, "error checking 12/24 hour mode\n");
\r
810 if (buf[0] & S35392A_FLAG_24H)
\r
811 s35392a->twentyfourhour = 1;
\r
813 s35392a->twentyfourhour = 0;
\r
815 if (s35392a_get_datetime(client, &tm) < 0)
\r
816 dev_warn(&client->dev, "clock needs to be set\n");
\r
818 s35392a->rtc = rtc_device_register(s35392a_driver.driver.name,
\r
819 &client->dev, &s35392a_rtc_ops, THIS_MODULE);
\r
821 if (IS_ERR(s35392a->rtc)) {
\r
822 err = PTR_ERR(s35392a->rtc);
\r
825 err = s35392a_sysfs_register(&client->dev);
\r
828 dev_err(&client->dev, "error sysfs register\n");
\r
832 if(err = gpio_request(client->irq, "rtc gpio"))
\r
834 dev_err(&client->dev, "gpio request fail\n");
\r
835 gpio_free(client->irq);
\r
839 if (pdata && (pdata->irq_type == GPIO_LOW)) {
\r
840 gpio_pull_updown(client->irq,GPIOPullUp);
\r
842 client->irq = gpio_to_irq(client->irq);
\r
844 if(err = request_irq(client->irq, s35392a_wakeup_irq,IRQF_TRIGGER_LOW,NULL,s35392a) <0)
\r
846 printk("unable to request rtc irq\n");
\r
851 gpio_pull_updown(client->irq,GPIOPullDown);
\r
853 client->irq = gpio_to_irq(client->irq);
\r
855 if(err = request_irq(client->irq, s35392a_wakeup_irq,IRQF_TRIGGER_HIGH,NULL,s35392a) <0)
\r
857 printk("unable to request rtc irq\n");
\r
862 INIT_WORK(&s35392a->work, s35392a_work_func);
\r
864 #if 0 //S35392_TEST
\r
868 s35392a_get_datetime(client, &tm);
\r
869 s35392a_alarm_test(client, tm);
\r
874 printk("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
\r
878 rtc_device_unregister(s35392a->rtc);
\r
880 i2c_set_clientdata(client, NULL);
\r
886 static int s35392a_remove(struct i2c_client *client)
\r
890 struct s35392a *s35392a = i2c_get_clientdata(client);
\r
892 if (s35392a->client)
\r
893 i2c_unregister_device(s35392a->client);
\r
895 rtc_device_unregister(s35392a->rtc);
\r
897 i2c_set_clientdata(client, NULL);
\r
902 static const struct i2c_device_id s35392a_id[] = {
\r
903 { "rtc-s35392a", 0 },
\r
906 MODULE_DEVICE_TABLE(i2c, s35392a_id);
\r
908 static struct i2c_driver s35392a_driver = {
\r
910 .name = "rtc-s35392a",
\r
912 .probe = s35392a_probe,
\r
913 .remove = s35392a_remove,
\r
914 .id_table = s35392a_id,
\r
917 static int __init s35392a_rtc_init(void)
\r
919 printk("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);
\r
920 return i2c_add_driver(&s35392a_driver);
\r
923 static void __exit s35392a_rtc_exit(void)
\r
925 i2c_del_driver(&s35392a_driver);
\r
928 MODULE_AUTHOR("swj@rock-chips.com>");
\r
929 MODULE_DESCRIPTION("S35392A RTC driver");
\r
930 MODULE_LICENSE("GPL");
\r
932 module_init(s35392a_rtc_init);
\r
933 module_exit(s35392a_rtc_exit);
\r