nvmem: rockchip-efuse: Fix dependencies
[firefly-linux-kernel-4.4.55.git] / drivers / rtc / rtc-s35392a.c
1 /*drivers/rtc/rtc-s35392a.h - driver for s35392a\r
2  *\r
3  * Copyright (C) 2010 ROCKCHIP, Inc.\r
4  *\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
8  *\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
13  */\r
14 \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
25 \r
26 #define RTC_RATE        100 * 1000\r
27 #define S35392_TEST 0\r
28 \r
29 #if 0\r
30 #define DBG(x...)   printk(x)\r
31 #else\r
32 #define DBG(x...)\r
33 #endif\r
34 \r
35 struct s35392a {\r
36         struct i2c_client *client;\r
37         struct rtc_device *rtc;\r
38         int twentyfourhour;\r
39         struct work_struct work;\r
40 };\r
41 \r
42 \r
43 \r
44 static int s35392a_set_reg(struct s35392a *s35392a, const char reg, char *buf, int len)\r
45 {\r
46         struct i2c_client *client = s35392a->client;\r
47         struct i2c_msg msg;\r
48         int ret;\r
49         int i;\r
50         char *buff = buf;\r
51         msg.addr = client->addr | reg;\r
52         msg.flags = client->flags;\r
53         msg.len = len;\r
54         msg.buf = buff;\r
55         msg.scl_rate = RTC_RATE;\r
56         \r
57         ret = i2c_transfer(client->adapter,&msg,1);\r
58         for(i=0;i<len;i++)\r
59                 DBG("buf[%d]=0x%x\n",i,buf[i]);\r
60         return ret;     \r
61         \r
62 }\r
63 \r
64 static int s35392a_get_reg(struct s35392a *s35392a, const char reg, char *buf, int len)\r
65 {\r
66         struct i2c_client *client = s35392a->client;\r
67         struct i2c_msg msg;\r
68         int ret;\r
69 \r
70         msg.addr = client->addr | reg;\r
71         msg.flags = client->flags | I2C_M_RD;\r
72         msg.len = len;\r
73         msg.buf = buf;\r
74         msg.scl_rate = RTC_RATE;\r
75 \r
76         ret = i2c_transfer(client->adapter,&msg,1);\r
77         return ret;\r
78         \r
79 }\r
80 \r
81 #if S35392_TEST\r
82 static int s35392_set_reg(struct s35392a *s35392a, const char reg, char *buf, int len,unsigned char head)\r
83 {\r
84         struct i2c_client *client = s35392a->client;\r
85         struct i2c_msg msg;\r
86         int ret;\r
87         \r
88         char *buff = buf;\r
89         msg.addr = client->addr | reg | (head << 3);\r
90         msg.flags = client->flags;\r
91         msg.len = len;\r
92         msg.buf = buff;\r
93         msg.scl_rate = RTC_RATE;        \r
94         ret = i2c_transfer(client->adapter,&msg,1);\r
95         return ret;     \r
96         \r
97 }\r
98 \r
99 static int s35392_get_reg(struct s35392a *s35392a, const char reg, char *buf, int len,unsigned char head)\r
100 {\r
101         struct i2c_client *client = s35392a->client;\r
102         struct i2c_msg msg;\r
103         int ret;\r
104 \r
105         msg.addr = client->addr | reg |(head << 3);\r
106         msg.flags = client->flags | I2C_M_RD;\r
107         msg.len = len;\r
108         msg.buf = buf;\r
109         msg.scl_rate = RTC_RATE;\r
110 \r
111         ret = i2c_transfer(client->adapter,&msg,1);\r
112         return ret;\r
113         \r
114 }\r
115 static int s35392a_test(struct s35392a *s35392a)\r
116 {\r
117         char buf[1];\r
118         char i;\r
119         \r
120         i = 50;\r
121         while(i--)\r
122         {\r
123         if (s35392_get_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf),6) < 0)\r
124                 return -EIO;    \r
125         if (!(buf[0] & (S35392A_FLAG_POC | S35392A_FLAG_BLD)))\r
126                 return 0;\r
127         \r
128         buf[0] |= (S35392A_FLAG_RESET | S35392A_FLAG_24H);\r
129         buf[0] &= 0xf0;\r
130         s35392_set_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf),6);\r
131         \r
132         buf[0] = 0;\r
133         s35392_get_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf),6);\r
134         mdelay(10);     \r
135         }\r
136         return 0;\r
137 }\r
138 #endif\r
139 static int s35392a_init(struct s35392a *s35392a)\r
140 {\r
141         char buf[1];\r
142 \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
149         \r
150         buf[0] |= (S35392A_FLAG_RESET | S35392A_FLAG_24H);\r
151         buf[0] &= 0xf0;\r
152         return s35392a_set_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf));\r
153 \r
154 }\r
155 \r
156 \r
157 static char s35392a_hr2reg(struct s35392a *s35392a, int hour)\r
158 {\r
159         if (s35392a->twentyfourhour)\r
160                 return bin2bcd(hour);\r
161 \r
162         if (hour < 12)\r
163                 return bin2bcd(hour);\r
164 \r
165         return 0x40 | bin2bcd(hour - 12);\r
166 }\r
167 \r
168 static int s35392a_reg2hr(struct s35392a *s35392a, char reg)\r
169 {\r
170         unsigned hour;\r
171 \r
172         if (s35392a->twentyfourhour)\r
173                 return bcd2bin(reg & 0x3f);\r
174 \r
175         hour = bcd2bin(reg & 0x3f);\r
176         if (reg & 0x40)\r
177                 hour += 12;\r
178 \r
179         return hour;\r
180 }\r
181 \r
182 static char s35392a_hour2reg(struct s35392a *s35392a, int hour)\r
183 {\r
184         if (s35392a->twentyfourhour)\r
185         {\r
186                 if(hour<12)\r
187                         return 0x80 | bin2bcd(hour) ;\r
188                 else\r
189                         return 0xc0| bin2bcd(hour) ;\r
190         }               \r
191         else\r
192         {\r
193                 if(hour<12)\r
194                         return 0x80 | bin2bcd(hour) ;\r
195                 else\r
196                         return 0xc0 | bin2bcd(hour - 12);\r
197         }\r
198                 \r
199 }\r
200 \r
201 static int s35392a_set_datetime(struct i2c_client *client, struct rtc_time *tm)\r
202 {\r
203         struct s35392a  *s35392a = i2c_get_clientdata(client);\r
204         int i, err;\r
205         char buf[7];\r
206 \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
210                 tm->tm_wday);\r
211 \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
219 \r
220         /* This chip expects the bits of each byte to be in reverse order */\r
221         for(i=0;i<7;i++)\r
222                 DBG("buf[%d]=0x%x\n",i,buf[i]);\r
223         for (i = 0; i < 7; ++i)\r
224                 buf[i] = bitrev8(buf[i]);\r
225         for(i=0;i<7;i++)\r
226                 DBG("buf[%d]=0x%x\n",i,buf[i]);\r
227         err = s35392a_set_reg(s35392a, S35392A_CMD_TIME1, buf, sizeof(buf));\r
228 \r
229         return err;\r
230 }\r
231 \r
232 static int s35392a_get_datetime(struct i2c_client *client, struct rtc_time *tm)\r
233 {\r
234         struct s35392a *s35392a = i2c_get_clientdata(client);\r
235         char buf[7];\r
236         int i, err;\r
237 \r
238         err = s35392a_get_reg(s35392a, S35392A_CMD_TIME1, buf, sizeof(buf));\r
239         if (err < 0)\r
240                 return err;\r
241         for(i=0;i<7;i++)\r
242                 DBG("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
246         for(i=0;i<7;i++)\r
247                 DBG("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
256 \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
260                 tm->tm_wday);\r
261 \r
262         return rtc_valid_tm(tm);\r
263 }\r
264 static int s35392a_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm  *tm)\r
265 {\r
266         struct s35392a  *s35392a = i2c_get_clientdata(client);\r
267         char buf[3];\r
268         int i,err;\r
269         char data;\r
270         DBG("%s:%d\n",__FUNCTION__,__LINE__);   \r
271         err = s35392a_get_reg(s35392a, S35392A_CMD_INT2, buf, sizeof(buf));\r
272         if(err < 0)\r
273                 return err;\r
274         for(i=0;i<3;i++)\r
275                 DBG("buf[%d]=0x%x\n",i,buf[i]);\r
276          for(i = 0;i < 3;++i)\r
277          buf[i] = bitrev8(buf[i]);\r
278         for(i=0;i<3;i++)\r
279                 DBG("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
283 \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
286         \r
287         if(buf[S35392A_ALARM_HOURS] & S35392A_ALARM_ENABLE)\r
288                 tm->time.tm_hour = s35392a_reg2hr(s35392a, buf[S35392A_ALARM_HOURS]);\r
289         \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
292         \r
293 \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
299         \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
303                 tm->time.tm_wday);\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
308         \r
309         DBG("%s:%d\n",__FUNCTION__,__LINE__);\r
310         return data;\r
311 }\r
312 \r
313 static int s35392a_i2c_set_alarm(struct i2c_client *client, struct rtc_wkalrm  *tm)\r
314 {\r
315         struct s35392a  *s35392a = i2c_get_clientdata(client);\r
316         char buf[3];\r
317         char data;\r
318         int i,err;\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
323                 tm->time.tm_wday);\r
324         \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
332         for(i=0;i<3;i++)\r
333                 DBG("buf[%d]=0x%x\n",i,buf[i]);\r
334          for(i = 0;i < 3;++i)\r
335          buf[i] = bitrev8(buf[i]);\r
336         for(i=0;i<3;i++)\r
337                 DBG("buf[%d]=0x%x\n",i,buf[i]);\r
338          if(tm->enabled)\r
339          {\r
340                 data = 0x00;\r
341                  s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);       \r
342                 s35392a_set_reg(s35392a, S35392A_CMD_INT2, &data, 1);\r
343 \r
344                 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);\r
345                 //data =  (data |S35392A_FLAG_INT2AE) & 0x2;\r
346                 data = 0x02;\r
347                 s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);                \r
348                 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);\r
349                 DBG("data = 0x%x\n",data);\r
350                 err = s35392a_set_reg(s35392a, S35392A_CMD_INT2, buf, sizeof(buf));\r
351                 return err;\r
352          }\r
353          else\r
354          {\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
358          }\r
359          return -1;     \r
360         \r
361 }\r
362 static int s35392a_i2c_read_alarm0(struct i2c_client *client, struct rtc_wkalrm  *tm)\r
363 {\r
364         struct s35392a  *s35392a = i2c_get_clientdata(client);\r
365         char buf[3];\r
366         int i,err;\r
367         char data;\r
368         DBG("%s:%d\n",__FUNCTION__,__LINE__);   \r
369         err = s35392a_get_reg(s35392a, S35392A_CMD_INT1, buf, sizeof(buf));\r
370         if(err < 0)\r
371                 return err;\r
372         for(i=0;i<3;i++)\r
373                 DBG("buf[%d]=0x%x\n",i,buf[i]);\r
374          for(i = 0;i < 3;++i)\r
375          buf[i] = bitrev8(buf[i]);\r
376         for(i=0;i<3;i++)\r
377                 DBG("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
381 \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
384         \r
385         if(buf[S35392A_ALARM_HOURS] & S35392A_ALARM_ENABLE)\r
386                 tm->time.tm_hour = s35392a_reg2hr(s35392a, buf[S35392A_ALARM_HOURS]);\r
387         \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
390         \r
391 \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
397         \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
401                 tm->time.tm_wday);\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
406         \r
407         DBG("%s:%d\n",__FUNCTION__,__LINE__);\r
408         return data;\r
409 }\r
410 \r
411 static int s35392a_i2c_set_alarm0(struct i2c_client *client, struct rtc_wkalrm  *tm)\r
412 {\r
413         struct s35392a  *s35392a = i2c_get_clientdata(client);\r
414         char buf[3];\r
415         char data;\r
416         int i,err;\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
421                 tm->time.tm_wday);\r
422         \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
430         for(i=0;i<3;i++)\r
431                 DBG("buf[%d]=0x%x\n",i,buf[i]);\r
432          for(i = 0;i < 3;++i)\r
433          buf[i] = bitrev8(buf[i]);\r
434         for(i=0;i<3;i++)\r
435                 DBG("buf[%d]=0x%x\n",i,buf[i]);\r
436          if(tm->enabled)\r
437          {\r
438                 data = 0x00;\r
439                  s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);       \r
440                 s35392a_set_reg(s35392a, S35392A_CMD_INT2, &data, 1);\r
441 \r
442                 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);\r
443                 //ta =  (data |S35392A_FLAG_INT1AE) & 0x20;\r
444                 data = 0x02;\r
445                 s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);                \r
446                 s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);\r
447                 DBG("data = 0x%x\n",data);\r
448                 err = s35392a_set_reg(s35392a, S35392A_CMD_INT1, buf, sizeof(buf));\r
449                 return err;\r
450          }\r
451          else\r
452          {\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
456          }\r
457          return -1;     \r
458         \r
459 }\r
460 static void s35392a_alarm_test(struct i2c_client *client ,struct rtc_time rtc_alarm_rtc_time)\r
461 {\r
462         struct rtc_wkalrm rtc_alarm,tm; \r
463         char data;\r
464         struct s35392a  *s35392a = i2c_get_clientdata(client);\r
465         DBG("%s:%d\n",__FUNCTION__,__LINE__);   \r
466         \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
471         else    \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
491         \r
492         DBG("------------------first-------------------------0x%0x, 0x%0x\n",data, data&S35392A_FLAG_INT2);\r
493         do\r
494         {         \r
495                 msleep(10000);\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
501         \r
502     msleep(20000);\r
503     s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);\r
504     DBG("--------------------last-------------------------0x%0x\n",data);\r
505     data=0x00;\r
506     s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);\r
507     s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);\r
508 }\r
509 \r
510 static void s35392a_alarm_test0(struct i2c_client *client ,struct rtc_time rtc_alarm_rtc_time)\r
511 {\r
512         struct rtc_wkalrm rtc_alarm,tm; \r
513         char data;\r
514         struct s35392a  *s35392a = i2c_get_clientdata(client);\r
515         DBG("%s:%d\n",__FUNCTION__,__LINE__);   \r
516         \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
521         else    \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
541         \r
542         DBG("------------------first-------------------------0x%0x, 0x%0x\n",data, data&S35392A_FLAG_INT1);\r
543         do\r
544         {         \r
545                 msleep(10000);\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
550                 \r
551     }while((data & S35392A_FLAG_INT1) == 0);\r
552      msleep(10000);\r
553     s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);\r
554     DBG("--------------------last-------------------------0x%0x\n",data);\r
555     data=0x00;\r
556     s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);\r
557     s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, &data, 1);\r
558   \r
559 }\r
560 \r
561 static int s35392a_set_init_time(struct s35392a *s35392a)\r
562 {       \r
563         struct rtc_time *tm;\r
564         struct i2c_client *client = s35392a->client;\r
565         tm->tm_year = 110;\r
566         tm->tm_mon      = 8;\r
567         tm->tm_mday = 8;\r
568         tm->tm_wday      = 0;\r
569         tm->tm_hour = 8;\r
570         tm->tm_min = 8;\r
571         tm->tm_sec = 8; \r
572         s35392a_set_datetime(client, tm);\r
573         return 0;\r
574 }\r
575 static int s35392a_reset(struct s35392a *s35392a)\r
576 {\r
577         char buf[1];\r
578         \r
579         if (s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf)) < 0)\r
580                 return -EIO;    \r
581         if (!(buf[0] & (S35392A_FLAG_POC | S35392A_FLAG_BLD))) {\r
582         buf[0] = 0x00;\r
583         s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, buf, 1);   \r
584         s35392a_set_reg(s35392a, S35392A_CMD_INT2, buf, 1);\r
585                 return 0;\r
586         }\r
587 \r
588         buf[0] |= (S35392A_FLAG_RESET | S35392A_FLAG_24H);\r
589         buf[0] &= 0xf0;\r
590         s35392a_set_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf));\r
591         \r
592         //s35392a_set_init_time( s35392a);      \r
593         return 0;               \r
594 }\r
595 \r
596 static int s35392a_disable_test_mode(struct s35392a *s35392a)\r
597 {\r
598         char buf[1];\r
599 \r
600         if (s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, buf, sizeof(buf)) < 0)\r
601                 return -EIO;\r
602 \r
603         if (!(buf[0] & S35392A_FLAG_TEST))\r
604                 return 0;\r
605 \r
606         buf[0] &= ~S35392A_FLAG_TEST;\r
607         return s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, buf, sizeof(buf));\r
608 }\r
609 static int s35392a_rtc_read_time(struct device *dev, struct rtc_time *tm)\r
610 {\r
611         return s35392a_get_datetime(to_i2c_client(dev), tm);\r
612 }\r
613 \r
614 static int s35392a_rtc_set_time(struct device *dev, struct rtc_time *tm)\r
615 {\r
616         return s35392a_set_datetime(to_i2c_client(dev), tm);\r
617 }\r
618 static int s35392a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)\r
619 {\r
620         return s35392a_i2c_read_alarm(to_i2c_client(dev),tm);\r
621 }\r
622 static int s35392a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)\r
623 {       \r
624         return s35392a_i2c_set_alarm(to_i2c_client(dev),tm);    \r
625 }\r
626 \r
627 static int s35392a_i2c_open_alarm(struct i2c_client *client )   \r
628 {\r
629         u8 data;\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
636         return 0;\r
637 }\r
638 static int s35392a_i2c_close_alarm(struct i2c_client *client )\r
639 {\r
640         u8 data;\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
647         return 0;\r
648 }\r
649 \r
650 static int s35392a_rtc_ioctl(struct device *dev,unsigned int cmd,unsigned long arg)\r
651 {\r
652         struct i2c_client *client = to_i2c_client(dev);\r
653         DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);\r
654         switch(cmd)\r
655         {\r
656                 case RTC_AIE_OFF:\r
657                         if(s35392a_i2c_close_alarm(client) < 0)\r
658                                 goto err;\r
659                         break;\r
660                 case RTC_AIE_ON:\r
661                         if(s35392a_i2c_open_alarm(client) < 0)\r
662                                 goto err;\r
663                         break;\r
664                 default:\r
665                         return -ENOIOCTLCMD;\r
666         }\r
667         return 0;\r
668 err:\r
669         return -EIO;\r
670 }\r
671 static int  s35392a_rtc_proc(struct device *dev, unsigned int cmd, unsigned long arg)\r
672 {\r
673         return 0;\r
674 }\r
675 \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
683 };\r
684 \r
685 \r
686 \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
690 {\r
691         DBG("\n@@@@@@@@@@@s35392a_sysfs_show_flags@@@@@@@@@@@@@\n");\r
692         \r
693                 return -EIO;\r
694 \r
695 }\r
696 static DEVICE_ATTR(flags, S_IRUGO,  s35392a_sysfs_show_flags, NULL);\r
697 \r
698 static ssize_t  s35392a_sysfs_show_sqwfreq(struct device *dev,\r
699                                 struct device_attribute *attr, char *buf)\r
700 {\r
701         DBG("\n@@@@@@@@@@@ s35392a_sysfs_show_sqwfreq@@@@@@@@@@@@@\n");\r
702         struct i2c_client *client = to_i2c_client(dev);\r
703         return 0;\r
704 }\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
708 {\r
709         DBG("\n@@@@@@@@@@@s35392a_sysfs_set_sqwfreq@@@@@@@@@@@@@\n");\r
710         \r
711         return count;\r
712 }\r
713 static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR,\r
714                    s35392a_sysfs_show_sqwfreq, s35392a_sysfs_set_sqwfreq);\r
715 \r
716 static struct attribute *attrs[] = {\r
717         &dev_attr_flags.attr,\r
718         &dev_attr_sqwfreq.attr,\r
719         NULL,\r
720 };\r
721 static struct attribute_group attr_group = {\r
722         .attrs = attrs,\r
723 };\r
724 static int  s35392a_sysfs_register(struct device *dev)\r
725 {\r
726         DBG("\n@@@@@@@@@@@s35392a_sysfs_register@@@@@@@@@@@@@\n");\r
727         return sysfs_create_group(&dev->kobj, &attr_group);\r
728         \r
729 }\r
730 #else\r
731 static int  s35392a_sysfs_register(struct device *dev)\r
732 {\r
733         DBG("\n@@@@@@@@@@@s35392a_sysfs_register@@@@@@@@@@@@@\n");\r
734         return 0;\r
735         \r
736 }\r
737 #endif  \r
738 \r
739 static struct i2c_driver s35392a_driver;\r
740 \r
741 static void s35392a_work_func(struct work_struct *work)\r
742 {\r
743         struct s35392a *s35392a = container_of(work, struct s35392a, work);\r
744         struct i2c_client *client = s35392a->client;\r
745     \r
746         DBG("\n@@@@@@@@@@@rtc_wakeup_irq@@@@@@@@@@@@@\n");\r
747         \r
748         char data = 0x00;\r
749     s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);\r
750     data = 0x00;\r
751     s35392a_set_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);\r
752     s35392a_get_reg(s35392a, S35392A_CMD_STATUS2, &data, 1);\r
753     \r
754         DBG("\n@@@@@@@@@@@rtc_wakeup_irq@@@@@@@@@@@@@\n");      \r
755                 \r
756         enable_irq(client->irq);                \r
757 }\r
758 \r
759 static void s35392a_wakeup_irq(int irq, void *dev_id)\r
760 {       \r
761         struct s35392a *s35392a = (struct s35392a *)dev_id;\r
762 \r
763     disable_irq_nosync(irq);\r
764     schedule_work(&s35392a->work);\r
765 }\r
766 \r
767 static int s35392a_probe(struct i2c_client *client,\r
768                          const struct i2c_device_id *id)\r
769 {\r
770         struct rk2818_rtc_platform_data *pdata = client->dev.platform_data;\r
771         int err;\r
772         unsigned int i;\r
773         struct s35392a *s35392a;\r
774         struct rtc_time tm;\r
775         char buf[1];\r
776         \r
777         DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);\r
778         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {\r
779                 err = -ENODEV;\r
780                 goto exit;\r
781         }\r
782 \r
783         s35392a = kzalloc(sizeof(struct s35392a), GFP_KERNEL);\r
784         if (!s35392a) {\r
785                 err = -ENOMEM;\r
786                 goto exit;\r
787         }\r
788 \r
789         s35392a->client = client;\r
790         i2c_set_clientdata(client, s35392a);\r
791         //mdelay(500);\r
792         //s35392a_init(s35392a);\r
793         err = s35392a_reset(s35392a);   \r
794         if (err < 0) {\r
795                 dev_err(&client->dev, "error resetting chip\n");\r
796                 goto exit_dummy;\r
797         }\r
798         \r
799         err = s35392a_disable_test_mode(s35392a);\r
800         if (err < 0) {\r
801                 dev_err(&client->dev, "error disabling test mode\n");\r
802                 goto exit_dummy;\r
803         }\r
804 \r
805         err = s35392a_get_reg(s35392a, S35392A_CMD_STATUS1, buf, sizeof(buf));\r
806         if (err < 0) {\r
807                 dev_err(&client->dev, "error checking 12/24 hour mode\n");\r
808                 goto exit_dummy;\r
809         }\r
810         if (buf[0] & S35392A_FLAG_24H)\r
811                 s35392a->twentyfourhour = 1;\r
812         else\r
813                 s35392a->twentyfourhour = 0;\r
814 \r
815         if (s35392a_get_datetime(client, &tm) < 0)\r
816                 dev_warn(&client->dev, "clock needs to be set\n");\r
817                 \r
818         s35392a->rtc = rtc_device_register(s35392a_driver.driver.name,\r
819                                 &client->dev, &s35392a_rtc_ops, THIS_MODULE);\r
820         \r
821         if (IS_ERR(s35392a->rtc)) {\r
822                 err = PTR_ERR(s35392a->rtc);\r
823                 goto exit_dummy;\r
824         }\r
825         err = s35392a_sysfs_register(&client->dev);\r
826         if(err)\r
827         {\r
828                 dev_err(&client->dev, "error sysfs register\n");\r
829                 goto exit_dummy;\r
830         }\r
831         \r
832         if(err = gpio_request(client->irq, "rtc gpio"))\r
833         {\r
834                 dev_err(&client->dev, "gpio request fail\n");\r
835                 gpio_free(client->irq);\r
836                 goto exit_dummy;\r
837         }\r
838 \r
839         if (pdata && (pdata->irq_type == GPIO_LOW)) {\r
840                 gpio_pull_updown(client->irq,GPIOPullUp);\r
841 \r
842                 client->irq = gpio_to_irq(client->irq);\r
843 \r
844                 if(err = request_irq(client->irq, s35392a_wakeup_irq,IRQF_TRIGGER_LOW,NULL,s35392a) <0) \r
845                 {\r
846                         DBG("unable to request rtc irq\n");\r
847                         goto exit_dummy;\r
848                 }       \r
849         }\r
850         else {\r
851                 gpio_pull_updown(client->irq,GPIOPullDown);\r
852 \r
853                 client->irq = gpio_to_irq(client->irq);\r
854 \r
855                 if(err = request_irq(client->irq, s35392a_wakeup_irq,IRQF_TRIGGER_HIGH,NULL,s35392a) <0)        \r
856                 {\r
857                         DBG("unable to request rtc irq\n");\r
858                         goto exit_dummy;\r
859                 }       \r
860         }\r
861         \r
862         INIT_WORK(&s35392a->work, s35392a_work_func);\r
863         \r
864 #if 0 //S35392_TEST\r
865         //i=2;\r
866         while(1)\r
867         {\r
868                 s35392a_get_datetime(client, &tm);\r
869                 s35392a_alarm_test(client, tm);\r
870                 //sleep(200);\r
871         }\r
872 #endif\r
873         \r
874         DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);\r
875         return 0;\r
876 \r
877 exit_dummy:\r
878         rtc_device_unregister(s35392a->rtc);\r
879         kfree(s35392a);\r
880         i2c_set_clientdata(client, NULL);\r
881 \r
882 exit:\r
883         return err;\r
884 }\r
885 \r
886 static int s35392a_remove(struct i2c_client *client)\r
887 {\r
888         unsigned int i;\r
889 \r
890         struct s35392a *s35392a = i2c_get_clientdata(client);\r
891 \r
892                 if (s35392a->client)\r
893                         i2c_unregister_device(s35392a->client);\r
894 \r
895         rtc_device_unregister(s35392a->rtc);\r
896         kfree(s35392a);\r
897         i2c_set_clientdata(client, NULL);\r
898 \r
899         return 0;\r
900 }\r
901 \r
902 static const struct i2c_device_id s35392a_id[] = {\r
903         { "rtc-s35392a", 0 },\r
904         { }\r
905 };\r
906 MODULE_DEVICE_TABLE(i2c, s35392a_id);\r
907 \r
908 static struct i2c_driver s35392a_driver = {\r
909         .driver         = {\r
910                 .name   = "rtc-s35392a",\r
911         },\r
912         .probe          = s35392a_probe,\r
913         .remove         = s35392a_remove,\r
914         .id_table       = s35392a_id,\r
915 };\r
916 \r
917 static int __init s35392a_rtc_init(void)\r
918 {\r
919         DBG("@@@@@%s:%d@@@@@\n",__FUNCTION__,__LINE__);\r
920         return i2c_add_driver(&s35392a_driver);\r
921 }\r
922 \r
923 static void __exit s35392a_rtc_exit(void)\r
924 {\r
925         i2c_del_driver(&s35392a_driver);\r
926 }\r
927 \r
928 MODULE_AUTHOR("swj@rock-chips.com>");\r
929 MODULE_DESCRIPTION("S35392A RTC driver");\r
930 MODULE_LICENSE("GPL");\r
931 \r
932 module_init(s35392a_rtc_init);\r
933 module_exit(s35392a_rtc_exit);\r
934 \r