1 /* drivers/rtc/rtc-HYM8563.c - driver for HYM8563
3 * Copyright (C) 2010 ROCKCHIP, Inc.
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #define pr_fmt(fmt) "rtc: %s: " fmt, __func__
18 #include <linux/module.h>
19 #include <linux/i2c.h>
20 #include <linux/bcd.h>
21 #include <linux/rtc.h>
22 #include <linux/delay.h>
23 #include <linux/wakelock.h>
24 #include <linux/slab.h>
25 #include "rtc-HYM8563.h"
26 #include <linux/of_gpio.h>
27 #include <linux/irqdomain.h>
28 #define RTC_SPEED 200 * 1000
32 struct i2c_client *client;
34 struct rtc_device *rtc;
35 struct rtc_wkalrm alarm;
36 struct wake_lock wake_lock;
38 static struct i2c_client *gClient = NULL;
40 static int i2c_master_reg8_send(const struct i2c_client *client, const char reg, const char *buf, int count, int scl_rate)
42 struct i2c_adapter *adap=client->adapter;
45 char *tx_buf = (char *)kzalloc(count + 1, GFP_KERNEL);
49 memcpy(tx_buf+1, buf, count);
51 msg.addr = client->addr;
52 msg.flags = client->flags;
54 msg.buf = (char *)tx_buf;
55 msg.scl_rate = scl_rate;
57 ret = i2c_transfer(adap, &msg, 1);
59 return (ret == 1) ? count : ret;
63 static int i2c_master_reg8_recv(const struct i2c_client *client, const char reg, char *buf, int count, int scl_rate)
65 struct i2c_adapter *adap=client->adapter;
66 struct i2c_msg msgs[2];
70 msgs[0].addr = client->addr;
71 msgs[0].flags = client->flags;
73 msgs[0].buf = ®_buf;
74 msgs[0].scl_rate = scl_rate;
76 msgs[1].addr = client->addr;
77 msgs[1].flags = client->flags | I2C_M_RD;
79 msgs[1].buf = (char *)buf;
80 msgs[1].scl_rate = scl_rate;
82 ret = i2c_transfer(adap, msgs, 2);
84 return (ret == 2)? count : ret;
89 static int hym8563_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
92 ret = i2c_master_reg8_recv(client, reg, buf, len, RTC_SPEED);
96 static int hym8563_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], __u16 len)
99 ret = i2c_master_reg8_send(client, reg, buf, (int)len, RTC_SPEED);
104 int hym8563_enable_count(struct i2c_client *client, int en)
106 struct hym8563 *hym8563 = i2c_get_clientdata(client);
113 hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);
115 hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);
117 regs[0] |= (TE | TD1);
118 hym8563_i2c_set_regs(client, RTC_T_CTL, regs, 1);
121 hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);
123 hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);
125 regs[0] |= (TD0 | TD1);
126 hym8563_i2c_set_regs(client, RTC_T_CTL, regs, 1);
132 int hym8563_set_count(struct i2c_client *client, int sec)
134 struct hym8563 *hym8563 = i2c_get_clientdata(client);
147 hym8563_i2c_set_regs(client, RTC_T_COUNT, regs, 1);
153 /*the init of the hym8563 at first time */
154 static int hym8563_init_device(struct i2c_client *client)
156 struct hym8563 *hym8563 = i2c_get_clientdata(client);
160 mutex_lock(&hym8563->mutex);
162 sr = hym8563_i2c_set_regs(client, RTC_CTL1, regs, 1);
168 sr = hym8563_i2c_set_regs(client, RTC_CLKOUT, regs, 1);
172 /*enable alarm && count interrupt*/
173 sr = hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);
177 regs[0] |= (AIE | TIE);
178 sr = hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);
181 sr = hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);
185 sr = hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);
187 pr_err("read CTL2 err\n");
191 if(regs[0] & (AF|TF))
194 sr = hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);
198 mutex_unlock(&hym8563->mutex);
203 static int hym8563_read_datetime(struct i2c_client *client, struct rtc_time *tm)
205 struct hym8563 *hym8563 = i2c_get_clientdata(client);
206 u8 regs[HYM8563_RTC_SECTION_LEN] = { 0, };
207 mutex_lock(&hym8563->mutex);
208 // for (i = 0; i < HYM8563_RTC_SECTION_LEN; i++) {
209 // hym8563_i2c_read_regs(client, RTC_SEC+i, ®s[i], 1);
211 hym8563_i2c_read_regs(client, RTC_SEC, regs, HYM8563_RTC_SECTION_LEN);
213 mutex_unlock(&hym8563->mutex);
215 tm->tm_sec = bcd2bin(regs[0x00] & 0x7F);
216 tm->tm_min = bcd2bin(regs[0x01] & 0x7F);
217 tm->tm_hour = bcd2bin(regs[0x02] & 0x3F);
218 tm->tm_mday = bcd2bin(regs[0x03] & 0x3F);
219 tm->tm_wday = bcd2bin(regs[0x04] & 0x07);
221 tm->tm_mon = bcd2bin(regs[0x05] & 0x1F) ;
222 tm->tm_mon -= 1; //inorder to cooperate the systerm time
224 tm->tm_year = bcd2bin(regs[0x06] & 0xFF);
230 tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
231 tm->tm_year -= 1900; //inorder to cooperate the systerm time
236 pr_debug("%4d-%02d-%02d(%d) %02d:%02d:%02d\n",
237 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,
238 tm->tm_hour, tm->tm_min, tm->tm_sec);
243 static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
245 return hym8563_read_datetime(to_i2c_client(dev), tm);
248 static int hym8563_set_time(struct i2c_client *client, struct rtc_time *tm)
250 struct hym8563 *hym8563 = i2c_get_clientdata(client);
251 u8 regs[HYM8563_RTC_SECTION_LEN] = { 0, };
255 pr_debug("%4d-%02d-%02d(%d) %02d:%02d:%02d\n",
256 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,
257 tm->tm_hour, tm->tm_min, tm->tm_sec);
259 mon_day = rtc_month_days((tm->tm_mon), tm->tm_year + 1900);
261 if(tm->tm_sec >= 60 || tm->tm_sec < 0 ) //set sec
262 regs[0x00] = bin2bcd(0x00);
264 regs[0x00] = bin2bcd(tm->tm_sec);
266 if(tm->tm_min >= 60 || tm->tm_min < 0 ) //set min
267 regs[0x01] = bin2bcd(0x00);
269 regs[0x01] = bin2bcd(tm->tm_min);
271 if(tm->tm_hour >= 24 || tm->tm_hour < 0 ) //set hour
272 regs[0x02] = bin2bcd(0x00);
274 regs[0x02] = bin2bcd(tm->tm_hour);
276 if((tm->tm_mday) > mon_day) //if the input month day is bigger than the biggest day of this month, set the biggest day
277 regs[0x03] = bin2bcd(mon_day);
278 else if((tm->tm_mday) > 0)
279 regs[0x03] = bin2bcd(tm->tm_mday);
280 else if((tm->tm_mday) <= 0)
281 regs[0x03] = bin2bcd(0x01);
283 if( tm->tm_year >= 200) // year >= 2100
284 regs[0x06] = bin2bcd(99); //year = 2099
285 else if(tm->tm_year >= 100) // 2000 <= year < 2100
286 regs[0x06] = bin2bcd(tm->tm_year - 100);
287 else if(tm->tm_year >= 0){ // 1900 <= year < 2000
288 regs[0x06] = bin2bcd(tm->tm_year);
290 }else{ // year < 1900
291 regs[0x06] = bin2bcd(0); //year = 1900
294 regs[0x04] = bin2bcd(tm->tm_wday); //set the weekday
295 regs[0x05] = (regs[0x05] & 0x80)| (bin2bcd(tm->tm_mon + 1) & 0x7F); //set the month
297 mutex_lock(&hym8563->mutex);
298 // for(i=0;i<HYM8563_RTC_SECTION_LEN;i++){
299 // ret = hym8563_i2c_set_regs(client, RTC_SEC+i, ®s[i], 1);
301 hym8563_i2c_set_regs(client, RTC_SEC, regs, HYM8563_RTC_SECTION_LEN);
303 mutex_unlock(&hym8563->mutex);
308 static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
310 return hym8563_set_time(to_i2c_client(dev), tm);
313 static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
315 struct i2c_client *client = to_i2c_client(dev);
316 struct hym8563 *hym8563 = i2c_get_clientdata(client);
320 mutex_lock(&hym8563->mutex);
321 hym8563_i2c_read_regs(client, RTC_A_MIN, regs, 4);
324 hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);
325 mutex_unlock(&hym8563->mutex);
329 static int hym8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
331 struct i2c_client *client = to_i2c_client(dev);
332 struct hym8563 *hym8563 = i2c_get_clientdata(client);
333 struct rtc_time now, *tm = &alarm->time;
336 unsigned long alarm_sec, now_sec;
339 pr_debug("%4d-%02d-%02d(%d) %02d:%02d:%02d enabled %d\n",
340 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,
341 tm->tm_hour, tm->tm_min, tm->tm_sec, alarm->enabled);
344 hym8563_read_datetime(client, &now);
347 mutex_lock(&hym8563->mutex);
348 rtc_tm_to_time(tm, &alarm_sec);
349 rtc_tm_to_time(&now, &now_sec);
351 diff_sec = alarm_sec - now_sec;
353 if((diff_sec > 0) && (diff_sec < 256))
355 printk("%s:diff_sec= %ds , use time\n",__func__, diff_sec);
357 if (alarm->enabled == 1)
359 hym8563_set_count(client, diff_sec);
360 hym8563_enable_count(client, 1);
365 hym8563_enable_count(client, 0);
371 printk("%s:diff_sec= %ds , use alarm\n",__func__, diff_sec);
372 hym8563_enable_count(client, 0);
376 rtc_tm_to_time(tm, &alarm_sec);
377 rtc_time_to_tm(alarm_sec, tm);
380 hym8563->alarm = *alarm;
383 hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);
384 mon_day = rtc_month_days(tm->tm_mon, tm->tm_year + 1900);
385 hym8563_i2c_read_regs(client, RTC_A_MIN, regs, 4);
387 if (tm->tm_min >= 60 || tm->tm_min < 0) //set min
388 regs[0x00] = bin2bcd(0x00) & 0x7f;
390 regs[0x00] = bin2bcd(tm->tm_min) & 0x7f;
391 if (tm->tm_hour >= 24 || tm->tm_hour < 0) //set hour
392 regs[0x01] = bin2bcd(0x00) & 0x7f;
394 regs[0x01] = bin2bcd(tm->tm_hour) & 0x7f;
395 regs[0x03] = bin2bcd (tm->tm_wday) & 0x7f;
397 /* if the input month day is bigger than the biggest day of this month, set the biggest day */
398 if (tm->tm_mday > mon_day)
399 regs[0x02] = bin2bcd(mon_day) & 0x7f;
400 else if (tm->tm_mday > 0)
401 regs[0x02] = bin2bcd(tm->tm_mday) & 0x7f;
402 else if (tm->tm_mday <= 0)
403 regs[0x02] = bin2bcd(0x01) & 0x7f;
405 hym8563_i2c_set_regs(client, RTC_A_MIN, regs, 4);
406 hym8563_i2c_read_regs(client, RTC_A_MIN, regs, 4);
407 hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);
408 if (alarm->enabled == 1)
412 hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);
413 hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);
417 pr_info("alarm sec <= now sec\n");
422 mutex_unlock(&hym8563->mutex);
426 #ifdef CONFIG_HDMI_SAVE_DATA
427 int hdmi_get_data(void)
431 hym8563_i2c_read_regs(gClient, RTC_T_COUNT, ®s, 1);
434 printk("%s rtc has no init\n",__func__);
437 if(regs==0 || regs==0xff){
438 printk("%s rtc has no hdmi data\n",__func__);
444 int hdmi_set_data(int data)
446 u8 regs = (data+1)&0xff;
448 hym8563_i2c_set_regs(gClient, RTC_T_COUNT, ®s, 1);
451 printk("%s rtc has no init\n",__func__);
457 EXPORT_SYMBOL(hdmi_get_data);
458 EXPORT_SYMBOL(hdmi_set_data);
460 #if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
461 static int hym8563_i2c_open_alarm(struct i2c_client *client)
464 hym8563_i2c_read_regs(client, RTC_CTL2, &data, 1);
466 hym8563_i2c_set_regs(client, RTC_CTL2, &data, 1);
471 static int hym8563_i2c_close_alarm(struct i2c_client *client)
474 hym8563_i2c_read_regs(client, RTC_CTL2, &data, 1);
476 hym8563_i2c_set_regs(client, RTC_CTL2, &data, 1);
481 static int hym8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
483 struct i2c_client *client = to_i2c_client(dev);
487 if(hym8563_i2c_close_alarm(client) < 0)
491 if(hym8563_i2c_open_alarm(client))
502 #define hym8563_rtc_ioctl NULL
505 #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
506 static int hym8563_rtc_proc(struct device *dev, struct seq_file *seq)
511 #define hym8563_rtc_proc NULL
514 static irqreturn_t hym8563_wakeup_irq(int irq, void *data)
516 struct hym8563 *hym8563 = data;
517 struct i2c_client *client = hym8563->client;
520 mutex_lock(&hym8563->mutex);
521 hym8563_i2c_read_regs(client, RTC_CTL2, &value, 1);
523 hym8563_i2c_set_regs(client, RTC_CTL2, &value, 1);
524 mutex_unlock(&hym8563->mutex);
526 rtc_update_irq(hym8563->rtc, 1, RTC_IRQF | RTC_AF | RTC_UF);
528 //printk("%s:irq=%d\n",__func__,irq);
532 static const struct rtc_class_ops hym8563_rtc_ops = {
533 .read_time = hym8563_rtc_read_time,
534 .set_time = hym8563_rtc_set_time,
535 .read_alarm = hym8563_rtc_read_alarm,
536 .set_alarm = hym8563_rtc_set_alarm,
537 .ioctl = hym8563_rtc_ioctl,
538 .proc = hym8563_rtc_proc
541 static int hym8563_probe(struct i2c_client *client, const struct i2c_device_id *id)
545 struct hym8563 *hym8563;
546 struct rtc_device *rtc = NULL;
547 struct rtc_time tm_read, tm = {
557 struct device_node *np = client->dev.of_node;
558 unsigned long irq_flags;
561 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
564 hym8563 = devm_kzalloc(&client->dev,sizeof(*hym8563), GFP_KERNEL);
570 hym8563->client = client;
571 hym8563->alarm.enabled = 0;
573 mutex_init(&hym8563->mutex);
574 wake_lock_init(&hym8563->wake_lock, WAKE_LOCK_SUSPEND, "rtc_hym8563");
575 i2c_set_clientdata(client, hym8563);
577 hym8563_init_device(client);
578 hym8563_enable_count(client, 0);
581 hym8563_i2c_read_regs(client,RTC_SEC,®,1);
583 dev_info(&client->dev, "clock/calendar information is no longer guaranteed\n");
584 hym8563_set_time(client, &tm);
587 hym8563_read_datetime(client, &tm_read); //read time from hym8563
589 if(((tm_read.tm_year < 70) | (tm_read.tm_year > 137 )) | (tm_read.tm_mon == -1) | (rtc_valid_tm(&tm_read) != 0)) //if the hym8563 haven't initialized
591 hym8563_set_time(client, &tm); //initialize the hym8563
594 client->irq = of_get_named_gpio_flags(np, "irq_gpio", 0,(enum of_gpio_flags *)&irq_flags);
597 hym8563->irq = gpio_to_irq(client->irq);
598 result = devm_request_threaded_irq(&client->dev, hym8563->irq, NULL, hym8563_wakeup_irq, irq_flags | IRQF_ONESHOT, client->dev.driver->name,hym8563 );
600 printk(KERN_ERR "%s:fail to request irq = %d, ret = 0x%x\n",__func__, hym8563->irq, result);
603 enable_irq_wake(hym8563->irq);
604 device_init_wakeup(&client->dev, 1);
606 rtc = devm_rtc_device_register(&client->dev,
608 &hym8563_rtc_ops, THIS_MODULE);
620 wake_lock_destroy(&hym8563->wake_lock);
625 static int hym8563_remove(struct i2c_client *client)
627 struct hym8563 *hym8563 = i2c_get_clientdata(client);
629 wake_lock_destroy(&hym8563->wake_lock);
635 void hym8563_shutdown(struct i2c_client * client)
640 ret=hym8563_i2c_set_regs(client, RTC_CLKOUT, regs, 1);
642 printk("rtc shutdown is error\n");
647 static const struct i2c_device_id hym8563_id[] = {
648 { "rtc_hym8563", 0 },
651 MODULE_DEVICE_TABLE(i2c, hym8563_id);
653 static struct of_device_id rtc_dt_ids[] = {
654 { .compatible = "rtc,hym8563" },
658 struct i2c_driver hym8563_driver = {
660 .name = "rtc_hym8563",
661 .owner = THIS_MODULE,
662 .of_match_table = of_match_ptr(rtc_dt_ids),
664 .probe = hym8563_probe,
665 .remove = hym8563_remove,
666 //.shutdown=hym8563_shutdown,
667 .id_table = hym8563_id,
670 static int __init hym8563_init(void)
672 return i2c_add_driver(&hym8563_driver);
675 static void __exit hym8563_exit(void)
677 i2c_del_driver(&hym8563_driver);
680 MODULE_AUTHOR("lhh lhh@rock-chips.com");
681 MODULE_DESCRIPTION("HYM8563 RTC driver");
682 MODULE_LICENSE("GPL");
684 module_init(hym8563_init);
685 module_exit(hym8563_exit);